CSCI 150 - Lab 7 - Todo Manager

CSCI 150 Lab 7: Todo Manager


Overview

In this lab, you will practice using lists and strings in Python by implementing a very simple todo manager, which helps you keep track of a list of things to do (or a list of anything at all). Here's an example of what your program might look like by the end of the lab:
Welcome to the todo list manager!
Enter the name of the file with your todos: todo.txt
Warning, file todo.txt does not exist.
------------------------------
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 0
Enter the new todo: Finish writing todo manager lab
------------------------------
0) Finish writing todo manager lab
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 0
Enter the new todo: Revise paper
------------------------------
0) Finish writing todo manager lab
1) Revise paper
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 0
Enter the new todo: Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Finish writing todo manager lab
1) Revise paper
2) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 2
0) Finish writing todo manager lab
1) Revise paper
2) Beat all MK8 Deluxe tracks on 200cc mode
Which todo do you want to replace? 1
Enter the new todo: Revise paper for JFP
------------------------------
0) Finish writing todo manager lab
1) Revise paper for JFP
2) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 3
Enter the search string: z
No todos found matching 'z'.
------------------------------
0) Finish writing todo manager lab
1) Revise paper for JFP
2) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 3
Enter the search string: t
Todos matching 't':
0) Finish writing todo manager lab
1) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Finish writing todo manager lab
1) Revise paper for JFP
2) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 1
0) Finish writing todo manager lab
1) Revise paper
2) Beat all MK8 Deluxe tracks on 200cc mode
Which todo do you want to remove? 0
------------------------------
0) Revise paper for JFP
1) Beat all MK8 Deluxe tracks on 200cc mode
------------------------------
0) Add a new todo
1) Remove a todo
2) Replace a todo
3) Search
4) Quit
Your choice? 4

Step 1: Bits and Pieces

Create a new Python file called todo_manager.py, and put your name, date, copyright notice, etc. at the top. Also, don't forget to include the line
from typing import *
at the top of your file, which you will need in order to write types involving lists. Start by defining the following functions:

Step 2: Loading and Saving

A todo list manager isn't much good without being able to load and save lists of todos! You wouldn't want to have to type in all your todos every time you run the program.

I have provided functions you can use to open and save text files. Later in the semester we will learn more about how they work. For now, you can just copy and paste these functions into your program.

# Open the file with the given name and return its contents as a list
# of strings, one per line; OR print a warning and return the empty
# list if there is an error opening the file (e.g. if the file does
# not exist).
def open_file(filename: str) -> List[str]:
    try:
        f = open(filename, 'r')
        lines = [l.rstrip() for l in f.readlines()]
        f.close()
        return lines
    except:
        print("Warning, file " + filename + " does not exist.")
        return []

# Write the given string to the file with the given name.
def save_file(filename: str, contents: str):
    try:
        f = open(filename, 'w')
        f.write(contents)
        f.close()
    except:
        print("Something went wrong saving " + filename + "!")
Now define a function main() which does the following: Again, you should be sure to test your main() function. (You can use whatever file name you want for your todo list; if it doesn't already exist, it will be created by save_file.) You should be able to tell if the loading and saving is working since after running main() your todo file should have one more line at the end. Menu choices in a loop. quit.

Step 3: Menu

Now modify your main() function so it lets the user repeatedly choose options from a menu. In particular: You should also get rid of the code that adds a fake todo item to the end of the list.

Step 4: Operations

Now it's time to actually implement the operations! Below are descriptions of what the different menu choices should do. You can also look at the example program output at the top of this lab for inspiration. Be sure to test that each operation works before moving on to the next!

add

If the user chooses to add a new todo item, you should prompt them for a new todo and add it to the end of the list.

remove

If the user chooses to remove a todo item, you should use get_choice to ask for the index of the item they would like to remove. If get_choice returns -1, do nothing. Otherwise, you can use the pop list function to remove the item at a particular index, for example, if your list of todos is called todos and the user's choice is stored in a variable called choice, you could write todos.pop(choice).

replace

This should work similarly to remove: ask the user which item they would like to replace; if they make a valid choice, prompt them for a new todo item, and replace the item at the index they chose.

search

You should first write a function
def find_all(term: str, items: List[str]) -> List[str]:
which takes a search term and a list of items, and returns the list of only those items from the list which contain the search term. You can check whether one string contains another string using the in operator: for example, "th" in "python" will return True, but "z" in "python" is False. Test your function in the console: for example, you should get
>>> find_all("ab", ["baby", "dog", "cat", "absolute", "table", "python"])
["baby", "absolute", "table"]
Now implement the search menu choice: prompt the user what they want to search for, use find_all to get the todos that match their search term, and display them to the user using print_numbered_list.

At this point you should be able to reproduce something similar to the example program run shown at the beginning of the lab! Note, however, that your output does not need to be identical to the example shown. Feel free to use your creativity to make it look nice or add your own extra features.

What to turn in

Grading

© Brent Yorgey, Hendrix College