diff --git a/learning_python3.md b/learning_python3.md index 4ca8ae1..0274464 100644 --- a/learning_python3.md +++ b/learning_python3.md @@ -1706,6 +1706,115 @@ for login in my_login_list: print("\t{}: {}".format(key, login[key])) ``` +# Coding challenge - Task manager + +Can you create me a *task manager* please? +I made one that is run from the command line with different arguments to modify it's behaviour. +If this looks too challenging I can tell you that the *full code* is 64 lines long, including empty lines! +Those of you who already tried out [argparse](https://realpython.com/command-line-interfaces-python-argparse/) in the previous challenges will probably understand what's going on here. +Those who did not I urge you to have a look at the link above and don't hesitate to ask for help! + +```bash +➜ python_course_doc git:(master) ✗ python3 test.py --help +usage: test.py [-h] [--file FILE] {add,delete,show} ... + +positional arguments: + {add,delete,show} + add adds a todo item to you todo list + delete deletes an item from your todo list + show show all your tasks + +optional arguments: + -h, --help show this help message and exit + --file FILE, -f FILE path to your todo file +➜ python_course_doc git:(master) ✗ python3 test.py show +ID: 0 --- buy milk +ID: 1 --- clean house +ID: 2 --- test my code +➜ python_course_doc git:(master) ✗ python3 test.py add write some documentation +➜ python_course_doc git:(master) ✗ python3 test.py show +ID: 0 --- buy milk +ID: 1 --- clean house +ID: 2 --- test my code +ID: 3 --- write some documentation +➜ python_course_doc git:(master) ✗ python3 test.py delete 2 +➜ python_course_doc git:(master) ✗ python3 test.py show +ID: 0 --- buy milk +ID: 1 --- clean house +ID: 2 --- write some documentation +➜ python_course_doc git:(master) ✗ +``` + +
+ Spoiler warning + +```python3 +import argparse +import pathlib + + +def read_taskfile(taskfile_path): + tasks = [] + if not pathlib.Path(taskfile_path).exists(): + return tasks + with open(taskfile_path, "r") as fp: + lines = fp.readlines() + for line in lines: + task = line.strip() + tasks.append(task) + return tasks + + +def write_taskfile(taskfile_path, tasks): + with open(taskfile_path, "w") as fp: + for task in tasks: + fp.write("{}\n".format(task)) + + +def show_tasks(tasks): + counter = 0 + for task in tasks: + print("ID: {} --- {}".format(counter, task)) + counter += 1 + + +def add_task(tasks, task): + tasks.append(task) + return tasks + + +def delete_task(tasks, task_id): + tasks.pop(task_id) + return tasks + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--file", "-f", default="./todo.tasks", help="path to your todo file") + subparser = parser.add_subparsers() + add = subparser.add_parser("add", help="adds a todo item to you todo list") + add.add_argument("task", nargs="*") + delete = subparser.add_parser("delete", help="deletes an item from your todo list") + delete.add_argument("idx", type=int, nargs="*") + show = subparser.add_parser("show", help="show all your tasks") + show.add_argument("show", action="store_true") + args = parser.parse_args() + + taskfile = args.file + tasks = read_taskfile(taskfile) + + if "task" in args: + tasks = add_task(tasks, " ".join(args.task)) + write_taskfile(taskfile, tasks) + elif "idx" in args: + for idx in args.idx: + tasks = delete_task(tasks, idx) + write_taskfile(taskfile, tasks) + elif args.show: + show_tasks(tasks) +``` +
+ ## csv, JSON and yaml # Now for some useful scripting