Open In App

How to make a Todo List CLI application using Python ?

Last Updated : 17 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we see how to make a Command Line application todo list in python. Todo list is a basic application in which users can add items.  It’s a list of tasks you need to complete or things that you want to do.  In to-do, list tasks are organized in order of priority.   One of the most important reasons you should use a to-do list is that it will help you stay organized. 

In this article we make a to-do list using the command line. By Using a to-do list as a command-line application we can organize our to-do list through a command prompt, and we do not need to run any script or program explicitly.

Basic Functions of todo list are:

  • Add a new todo
  • Delete a todo
  • Complete a todo
  • Show remaining todos
  • Show statistics of todo

Example

Note: In Windows Command Prompt to run the application → type todo or.\todo

In shell or git bash  -->     type ./todo
  • To create todo list application we have to follow these steps:
  • Create a folder named todolist
  • Create a file todo.py in the created folder
  • If you are a window user then Create another file todo.bat file. This is a batch file. And it is used to run the python script
  • If you are Linux user then create  a file named as todo.sh. This is used to run the python script.

                                                                                         

                                

todo.bat:

@echo off
python3 todo.py %1 %2

todo.sh:

python todo.py "$@"

Create a symbolic link to the executable file:

In Windows (In command prompt or Powershell)

To create a symbolic link on Windows, you’ll need to run either the Windows Command Prompt or Windows Powershell **with administrator privileges**. To do so, right-click on the icon for Command Prompt, or Powershell, and choose the _”Run as Administrator”_ option.

mklink todo todo.bat

In Linux or in the shell(as git bash)

$ ln -s todo.sh todo

Now we have to code the functions of our to-do list.

So we write the code in todo.py

Python3




# module required
import sys
import datetime


Help function: The help function is used to provide the way how a user can use the todo list.  And Help function is like the documentation of todo application. 

Python3




# help function
def help():
    sa = """Usage :-
$ ./todo add "todo item"  # Add a new todo
$ ./todo ls               # Show remaining todos
$ ./todo del NUMBER       # Delete a todo
$ ./todo done NUMBER      # Complete a todo
$ ./todo help             # Show usage
$ ./todo report           # Statistics"""
    sys.stdout.buffer.write(sa.encode('utf8'))


Function to add items in todo list: Add function is used to add new items to todo list

Python3




# function to add item in todo list
def add(s):
   
    f = open('todo.txt', 'a')
    f.write(s)
    f.write("\n")
    f.close()
    s = '"'+s+'"'
    print(f"Added todo: {s}")


The function to print the todo list function is used to print the items that are present in our todo list. Todo items are printed in ascending order.

Python3




# Function to print the todo list items
def ls():
   
    try:
 
        nec()
        l = len(d)
        k = l
 
        for i in d:
            sys.stdout.buffer.write(f"[{l}] {d[l]}".encode('utf8'))
            sys.stdout.buffer.write("\n".encode('utf8'))
            l = l-1
 
    except Exception as e:
        raise e


Function to Complete a todo: Function defines the completed task and this completed task is added in done.txt. 

Python3




# Function to Complete a todo
def done(no):
    try:
 
        nec()
        no = int(no)
        f = open('done.txt', 'a')
        st = 'x '+str(datetime.datetime.today()).split()[0]+' '+d[no]
         
        f.write(st)
        f.write("\n")
        f.close()
        print(f"Marked todo #{no} as done.")
         
        with open("todo.txt", "r+") as f:
            lines = f.readlines()
            f.seek(0)
             
            for i in lines:
                if i.strip('\n') != d[no]:
                    f.write(i)
            f.truncate()
    except:
        print(f"Error: todo #{no} does not exist.")


Function to show the statistics of todolist: The “report” function is used to show the complete statistics. It prints total no of the completed task and total no of the pending task.

Python3




# Function to show report/statistics of todo list
def report():
    nec()
    try:
 
        nf = open('done.txt', 'r')
        c = 1
         
        for line in nf:
            line = line.strip('\n')
            don.update({c: line})
            c = c+1
        print(
            f'{str(datetime.datetime.today()).split()[0]} Pending : {len(d)} Completed : {len(don)}')
     
    except:
        print(
            f'{str(datetime.datetime.today()).split()[0]} Pending : {len(d)} Completed : {len(don)}')


Function to delete an item from todo list: deL function is used to delete an item from todo list. It deletes todo item based on the item number

Python3




# code
def deL(no):
    try:
        no = int(no)
        nec()
 
        # utility function defined in main
        with open("todo.txt", "r+") as f:
            lines = f.readlines()
            f.seek(0)
             
            for i in lines:
                if i.strip('\n') != d[no]:
                    f.write(i)
            f.truncate()
        print(f"Deleted todo #{no}")
 
    except Exception as e:
       
        print(f"Error: todo #{no} does not exist. Nothing deleted.")


Main function and utility function

Python3




# code
def nec():
 
  # utility function used in done and report function
    try:
        f = open('todo.txt', 'r')
        c = 1
        for line in f:
            line = line.strip('\n')
            d.update({c: line})
            c = c+1
    except:
        sys.stdout.buffer.write("There are no pending todos!".encode('utf8'))
 
 
# Main program
if __name__ == '__main__':
    try:
        d = {}
        don = {}
        args = sys.argv
         
        if(args[1] == 'del'):
            args[1] = 'deL'
             
        if(args[1] == 'add' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing todo string. Nothing added!".encode('utf8'))
 
        elif(args[1] == 'done' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing NUMBER for marking todo as done.".encode('utf8'))
 
        elif(args[1] == 'deL' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing NUMBER for deleting todo.".encode('utf8'))
        else:
            globals()[args[1]](*args[2:])
 
    except Exception as e:
 
        s = """Usage :-
$ ./todo add "todo item"  # Add a new todo
$ ./todo ls               # Show remaining todos
$ ./todo del NUMBER       # Delete a todo
$ ./todo done NUMBER      # Complete a todo
$ ./todo help             # Show usage
$ ./todo report           # Statistics"""
        sys.stdout.buffer.write(s.encode('utf8'))


Below is the implementation:

Python3




# Complete code
import sys
import datetime
 
 
def help():
    sa = """Usage :-
$ ./todo add "todo item"  # Add a new todo
$ ./todo ls               # Show remaining todos
$ ./todo del NUMBER       # Delete a todo
$ ./todo done NUMBER      # Complete a todo
$ ./todo help             # Show usage
$ ./todo report           # Statistics"""
    sys.stdout.buffer.write(sa.encode('utf8'))
 
 
def add(s):
    f = open('todo.txt', 'a')
    f.write(s)
    f.write("\n")
    f.close()
    s = '"'+s+'"'
    print(f"Added todo: {s}")
 
 
def ls():
    try:
 
        nec()
        l = len(d)
        k = l
 
        for i in d:
            sys.stdout.buffer.write(f"[{l}] {d[l]}".encode('utf8'))
            sys.stdout.buffer.write("\n".encode('utf8'))
            l = l-1
 
    except Exception as e:
        raise e
 
 
def deL(no):
    try:
        no = int(no)
        nec()
        with open("todo.txt", "r+") as f:
            lines = f.readlines()
            f.seek(0)
            for i in lines:
                if i.strip('\n') != d[no]:
                    f.write(i)
            f.truncate()
        print(f"Deleted todo #{no}")
 
    except Exception as e:
        print(f"Error: todo #{no} does not exist. Nothing deleted.")
 
 
def done(no):
    try:
 
        nec()
        no = int(no)
        f = open('done.txt', 'a')
        st = 'x '+str(datetime.datetime.today()).split()[0]+' '+d[no]
        f.write(st)
        f.write("\n")
        f.close()
        print(f"Marked todo #{no} as done.")
         
        with open("todo.txt", "r+") as f:
            lines = f.readlines()
            f.seek(0)
            for i in lines:
                if i.strip('\n') != d[no]:
                    f.write(i)
            f.truncate()
    except:
        print(f"Error: todo #{no} does not exist.")
 
 
def report():
    nec()
    try:
 
        nf = open('done.txt', 'r')
        c = 1
        for line in nf:
            line = line.strip('\n')
            don.update({c: line})
            c = c+1
        print(
            f'{str(datetime.datetime.today()).split()[0]} Pending : {len(d)} Completed : {len(don)}')
    except:
        print(
            f'{str(datetime.datetime.today()).split()[0]} Pending : {len(d)} Completed : {len(don)}')
 
 
def nec():
    try:
        f = open('todo.txt', 'r')
        c = 1
        for line in f:
            line = line.strip('\n')
            d.update({c: line})
            c = c+1
    except:
        sys.stdout.buffer.write("There are no pending todos!".encode('utf8'))
 
 
if __name__ == '__main__':
    try:
        d = {}
        don = {}
        args = sys.argv
        if(args[1] == 'del'):
            args[1] = 'deL'
        if(args[1] == 'add' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing todo string. Nothing added!".encode('utf8'))
 
        elif(args[1] == 'done' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing NUMBER for marking todo as done.".encode('utf8'))
 
        elif(args[1] == 'deL' and len(args[2:]) == 0):
            sys.stdout.buffer.write(
                "Error: Missing NUMBER for deleting todo.".encode('utf8'))
        else:
            globals()[args[1]](*args[2:])
 
    except Exception as e:
 
        s = """Usage :-
$ ./todo add "todo item"  # Add a new todo
$ ./todo ls               # Show remaining todos
$ ./todo del NUMBER       # Delete a todo
$ ./todo done NUMBER      # Complete a todo
$ ./todo help             # Show usage
$ ./todo report           # Statistics"""
        sys.stdout.buffer.write(s.encode('utf8'))


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads