Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python

Chase Frankenfeld
Chase Frankenfeld
6,137 Points

Saving to a text file on separate lines and then reading the lines back for the shopping list?

Hi. I have been playing around with the extra credit for the shopping list, and adding what I have learnt in the later lessons to it. I have worked out how to save to a list to a txt file, however, cannot work out how to save each list item to separate lines in the text file, or how to relay it back.

Also, for formatting for asking questions. I'm not sure how to make sure all the code is in code formatting, and not with some of it in text form? Apologies in advance :)

Here is my code:

import os

import sys

shopping_list = []

# functions
def show_help():
    # print out instructions on how to use the app
    print("What should we pick up at the store?")
    print("""
Enter 'done' to stop adding items.
Enter 'show' to show items in shopping list.
Enter 'help' to show instructions.
Enter 'save' to save the list.
    """)

def clear():
    if os.name == 'nt':
        os.system('cls')
    else:
        os.system('clear')    

def show_list():
    # print out the list
    print("Here is your list:")

    with open('shop/shopping_list', 'r') as f:        
        for line in f:
            print(line)

def add_to_list(new_item):
    # add new items to our list
    # make a list that will hold onto our items
    shopping_list.append(new_item)
    print("Added {}. List now has {} items.".format(new_item, len(shopping_list)))

def save_list():

    with open("shop/shopping_list.txt", "w") as f:
        f.writelines(shopping_list)

    print("Your shopping list has been saved.")    

# Exit message
def exit():
    print ('Hope you have enjoyd making a shopping list.')
    start = input("Please press enter/return to continue to play again, or Q to exit  ")
    if start.lower() == 'q':
        print("Bye! Have a good day :)")
        sys.exit()
    else:
        main()

def main():     
    clear()
    show_help()

    while True:
        # ask for new items

        new_item = input("> ")
        clear()

        # be able to quit the app
        if new_item.lower() == 'done':
            exit()
        elif new_item.lower() == 'help':
            clear()
            show_help()
            continue
        elif new_item.lower() == 'show':
            clear()
            show_list()
            continue
        elif new_item.lower() == 'save':
            clear()
            save_list()
            continue
        add_to_list(new_item)

    if len(shopping_list) > 0:  
        show_list()

main()

[MOD: added ``` python markdown formatting -cf]

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 67,989 Points

I was able to get basic I/O working with these changes:

def show_list():
    # print out the list
    print("Here is your list:")

    # FIXED: add try block to catch if file not found
    try:
        # FIXED: changed file name to 'shopping_list.txt'
        with open('shop/shopping_list.txt', 'r') as f:
            for line in f:
                # strip EOL character, since 'print' adds one
                print(line.strip())
    except FileNotFoundError:
        print("No saved shopping list")


def save_list():
    with open("shop/shopping_list.txt", "w") as f:
        # FIXED: print each item to own line
        for item in shopping_list:
            # save each item with EOL character
            f.write("{}\n".format(item))

    print("Your shopping list has been saved.")
Chase Frankenfeld
Chase Frankenfeld
6,137 Points

Thank you. Not that I see how it is done. And adding in stuff that we do all the time in some of the later courses. It actually doesn't seem to complex. Also, I have googled what strip does, and tested the code without it. But, I don't understand why print adds the line in between the items when you print the list, requiring us to use strip to remove the space?

Chris Freeman
Chris Freeman
Treehouse Moderator 67,989 Points

It comes down to the default behavior for each I/O function. A end-of-line (EOL) is needed in the file on disk to separate the lines. The built-in print() function adds an EOL character by default to whatever it prints. When reading the lines back into the program, the EOL line character is going to be present in the line data. So we have three choices:

  • Leave the EOL from the file and stop the print from added another EOL using the end='' argument
  • Use strip() on the line data to strip the file EOL and let the print add a new EOL. You can also trim the EOL off using a slice: print(line[:-1])
  • Do nothing special and see the EOL from the file and the EOL from the print