0

So i'm trying to write a basic TODO list program and i'm stuck on reading the data back from my file. I managed to store the content of my list in the file but when trying to read it back i never get the result i want, i tried splitting each line, read(), readline() and then append line to my list and either i get each of my list index counted as being only index[0] or if i manage to get it working then when i add some more stuff and overwrite my file with the new list it does a completely different thing when reading the data back ..

#!/usr/bin/python3

import os
from time import sleep
import platform
import getpass
import socket
import netifaces as ni
from requests import get

toDoList = []
backup = 'TODOlist.txt'
cwd = os.getcwd()

def clean():
    if platform.system() == "Linux": 
        os.system("clear")
    else:
        os.system("cls")


def printList(givenList):

        i = 0
        for task in givenList:
            print("\n[%d]: %s" % (i, task))
            i += 1
        print('\n')



def addToList(listToAdd):
    task = str(input("\n:"))
    listToAdd.append(task)
    print('\n[*]Task [%s] has been added successfully' % (task))



def removeFromList(listToRemove):
    iterator = int(input("\nNumero of the task to remove :"))
    removed = listToRemove[iterator]
    if len(toDoList) == 1:
        listToRemove.append('')

    listToRemove.pop(iterator)
    print("[*]\nTask [%d]: %s has been removed successfully" % (iterator, removed))



def storageFile(filename, listToStore):
    overwrite = ''
    if os.path.isfile(filename):
        while overwrite != 'y' or overwrite != 'n':
            choice = str(input('\n[!]This will overwrite your already saved list, are you sure? y/n : '))
            if choice == 'y':
                with open(filename, 'w+') as f:
                    for task in listToStore:
                        f.write(task)
                print('[*]\nDone.')
                break

            else:
                break
    else:
        with open(filename, 'w') as f:
            for task in listToStore:
                f.write(task)

        print('\n[*]%s created in %s' % (filename, cwd))



def main():
    toDoList = []
    clean()


    while True:
        print("\n---------------Otions------------------")
        print("1: Print your TODO list")
        print("2: Add something") 
        print("3: Remove something")
        print("4: Number of task in your TODO list")
        print("5: Save your TODO list")
        print("6: Delete all from your TODO list")
        print("7: Delete existing backup of your TODO list")
        print("99: Exit")

        optChoice = int(input("\nChoice: "))

        if optChoice == 1:
            printList(toDoList)
        elif optChoice == 2:
            addToList(toDoList)
        elif optChoice == 3:
            removeFromList()
        elif optChoice == 4:
            print("[-]\nYour TODO list currently contains %d task(s)" % (len(toDoList)))
        elif optChoice == 5:
            storageFile(backup, toDoList)
        elif optChoice == 6:
            del toDoList[:]
            print('\n[*]Done.')
        elif optChoice == 7:
            if os.path.isfile(backup):

                os.remove(backup)
                print('\n[*]Backup file %s has been removed.' % (backup))
            else:
                print('\n[X]No backup file has been detected')

        elif optChoice == 99:
            clean()
            exit()


main()
4
  • You have no "load" function ... and you do not load anything anywhere.... Commented Dec 10, 2017 at 12:15
  • I removed it, like i said above i tried writing it in so many ways, that's why i'm posting here hoping to get some help on the correct way to do it, obviously my syntax was wrong somewhere Commented Dec 10, 2017 at 12:18
  • you can open file in write mode with 'w', it will erase every content from file; in read mode 'r' you can read content of your file and append mode 'a' to append anything at end of your file Commented Dec 10, 2017 at 12:32
  • DARN - wanted to edit my answer - not your question. Please discard my edit. Commented Dec 10, 2017 at 13:06

1 Answer 1

1

Load the file:

def load(data, myPath):
    with open(myPath, "r") as f: # use r for read
       return [x.strip() for x in f.readlines()] 

Changed your storageFile(...) to add newlines after each task:

def storageFile(filename, listToStore):
    overwrite = ''
    if os.path.isfile(filename):
        while overwrite != 'y' or overwrite != 'n':
            choice = str(input('\n[!]This will overwrite your already saved list, are you sure? y/n : '))
            if choice == 'y':
                with open(filename, 'w') as f: 
                    # user a for append, w+ is not a thing
                    # if you switch to 'a' instead you should check for duplicates bevore 
                    # saving: Search SO for "list to set" + "pyhton"
                    # else your list will double itself on saving
                    for task in listToStore:
                        f.write(task + "\n") # added a newline here
                print('[*]\nDone.')
                break

            else:
                break
    else:
        with open(filename, 'w') as f:
            for task in listToStore:
                f.write(task+ "\n")   # added a newline here

        print('\n[*]%s created in %s' % (filename, cwd))

Change the main a tidbit to include automatic loading on start if file present:

def main():
    global toDoList  # use the global one
    global backup    # use the global one

    try:
       toDoList = load(toDoList, backup)
    except: 
        toDoList = []
    clean()


    while True: 
        # the rest of your main goes here....

If you implement a "load" in your menu you might consider checking fora already changed but not yet saved toDoList first before replacing it by whatever is in the file (ie only allow call to load if toDoList is empty or not "dirty"). You can add a isDirty = False to your globals as flag and set it to True in your addToList-function and to False when you save it.


Edit:

As to why I added the global in your main:

myvar = [1,2,3]
myOtherVar = [5,6,7]

def Test():
    global myOtherVar  # so in this scope "myOtherVar" == the global one
    myvar = []         # shadows the global one with a local one of same name
    print (myvar)      # prints the local (empty) one
    print(myOtherVar)  # prints the global one

Test()
print("---")
print(myvar) # prints the global one (same scope, no longer shadowed)

You "shadowed" your global list with a local list of same name - by declaring it as global inside the scope of a function it will operate on the global one and not shadow it.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for you help, still a beginner here and this will help me a lot. Why use the global keyword in main on those variables? I thought my variables were already considered 'global' when declared outside of any functions
@Orion_2.0 Python doesn't have declarations. But yes, you created a list in the global scope named toDoList, but then by doing toDoList = [] in main you create a new empty list with that name in the local scope, and that local name "shadows" the global one. To clear the global toDoList from inside a function you can simply call its .clear method: toDoList.clear(), but that will only work if you don't shadow the global name by performing an assignment to that name anywhere inside the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.