Zuletzt aktiv 1731423730

Lab notes on getting going thru the early parts of Tasty lab.

Änderung 620e2b55f771985ee9ef8b39af136a6da01129cb

TastyHints.md Orginalformat

Tasty Lab Hints

Hint 2

If we have thought about this a bit, we might hit on the idea that a dictionary might work well:


tasks = {}   # creates an empty dictionary

tasks['Buy Milk'] = 'not yet'

tasks['Start Lab'] = 'completed'

tasks['Finish Lab'] = 'not yet'

# now there are three tasks in the dictionary 

# how to test if a task is complete?

task_name = 'Buy Milk'

if tasks[task_name] == 'not yet':
  # task is unfinished
  pass
else:
  # task is 'complete'
  pass

# to list all the tasks

for task_name, status in tasks.items():
  print("- ", task_name, status) 

Paste this block of code into the python interpreter and observe what happens. Read the code, does it make sense how we are using the task_name as the key and the task_status as the value?

We need to think about how to put thse ideas into the class Tasty. We might...

class Tasty:
  
  def __init__(self):
    self.tasks = {}

  def add_task(self, task_name):
    """
    Add a new task to the user tasks.
    """
    if task_name not in self.tasks:
        self.tasks[task_name] = "not yet"
    else:
        print("Task already added.")


  def display_tasks(self):
    for task_name, status in self.tasks.items():
      print("- ", task_name, status)

See how those things went from just trial code to methods in the class?

Yes, and... the self variable is how you know that thing is a method and not just a function.

That's an example of how I might use the rough class here.

  def display_tasks(self):
    for task_name, status in self.tasks.items():
      print("- ", task_name, status)

Hint 3

Student Asks: I'm struggling to see where we take the user input for the task name.

If we have command = input('Tasty> ')

So the command variable will have exit or whatever, after the user types something in and taps , right?

And the new <task> command/line when entered, will actually look like new Buy Milk when user types the command to be processed by the program.

so take the string inputted and split it into a list of strings, breaking each string on the character.

txt = "command typed by user"

x = txt.split()

print(x)

# x will be a  list: ['command', 'typed', 'by', 'user']

If we want to extend this to make two new strings:

  • command (the first string, perhaps "new")
  • and rest (the rest of the split strings glued back together with spaces in between...)
txt = "new Buy Milk"
t = txt.split()
print(t) # t will be: ["new", "Buy", "Milk"]
command = t[0] # command will be "new"
rest = t[1:] # carefully: Slice the array, from t[1] to end of list
             # rest will be ["Buy", "Milk"]
rest = " ".join(rest) # now rest will be "Buy Milk"
print(command, ' - ', rest)

and after hacking a bit in the python interpreter, you may end up with

  line = input(prompt)
  #print(line)
  while not line:
    line = input(prompt) # this causes input to wait until 
                         # line is not an empty string
  words = line.split()
  #print(words)
  command = words[0]
  #print(command)
  rest = words[1:]
  rest = " ".join(rest)
  #print(rest)

and maybe the right thing to do is to change the command = input("Tasty> ") to something like command, rest = tasty.prompt_user("Tasty> ")

then all the "words" after the "new" will be what you pull together to name the task?

so prompt-user(self, prompt) becomes a method which asks for the user's input (using input(prompt))

def prompt_user(self, prompt):
  inp = input(prompt)
  # insert the stuff up there about how to 
  # split words into a list and process into two parts.

Saving/Loading to a JSON file

JSON is just a structured text format for data. Very Handy.

saving? a Hint

with open("saved_data.json", "w") as fp:
  json.dump(self.tasks,fp)

loading? a Hint

with open(filename) as json_file:
  self.tasks = json.load(json_file)

And you should embed these two ideas into a method.

When you get to the point where you are puzzling over how to save/load multiple dicts (say, tasks, trash, and important), you might consider putting all this in another dictionary and just saving that.

You still have to load the one dict and then split it into three for use by the methods. This should be done in load tasks method.

The data structure might be created by

dict_to_save = { "tasks": self.tasks, "trash": self.trash, "impt": self.important }

You can now json.dump the dict_to_save to a file.

Loading it will be the opposite, you end up with one loaded_dicts which have to be split like: self.tasks = loaded_dicts['tasks']

Easy Peasy