Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

How can I improve this shopping_list? Does it make sense to improve my shopping_list with Object-Oriented Python?

Hi everyone! I've just finished the Object-Oriented Python course, which was a big step for me. I realized that using classes and methods can improve the readability of my code. But I'm still getting confused when the time to apply this comes. So here's my question. I wrote a personal shopping list that compares objects with what I saved in my list from my previous shopping sessions.

It works fine, but it seems really long and difficult to read. How can I improve it? Would it be reasonable to implement some classes and methods?

Kenneth Love I kindly ask you an opinion about it :) P.S. thank you so much for the great courses!

import os

shopping_list_ie = [{"apples": [0.30, "Tesco Metro", "Victoria Centre"]},
                         {"mushrooms": [1.80, "Tesco Express", "Upper Parliament Street"]}]

# import list
try:
    with open('shopping_list_2.txt', 'r') as b:
        shopping_list = b.read().splitlines()
    for item in shopping_list:
        shopping_list[shopping_list.index(item)] = shopping_list[shopping_list.index(item)].split(", ")
    for item in shopping_list:
        shopping_list[shopping_list.index(item)] = {item[0]: [float(item[1]), item[2], item[3]]}
except FileNotFoundError:
    # if there's no saved list
    shopping_list = shopping_list_ie
except IndexError:
    shopping_list = shopping_list_ie

# help
def show_help():
    print("""
    allowed keys:
        help
        save
        show (all or single object)
        quit
    """)


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

# show list or single objects
def show_list():
    all_single = input("[A]ll or a [S]ingle object? > ").lower()
    if all_single == "a":
        for item in shopping_list:
            print(item)
    elif all_single == "s":
        quale = input("object name > ")
        for item in shopping_list:
            if quale in item.keys():
                print(item)

# save list
def extract(item):
    for key, value in item.items():
        oggetto = [key, value]
        return oggetto

def save_list():
    with open('shopping_list_2.txt', 'w') as a:
        for items in shopping_list:
            items = str(items)
            items = items.replace("[", "")
            items = items.replace("]", "")
            items = items.replace("'", "")
            a.write(items + "\n")

# ask for place and address
def luogo():
    market_name = input("Where did you do shopping today? Enter market name > ").lower()
    luogo = input("Enter market address > ").lower()
    return [market_name, luogo]


dove = luogo()
show_help()

while True:
    print("")
    # ask for object
    oggetto = input("Enter object [es. apples] > ").lower()

    if oggetto == "show":
        clear_screen()
        show_list()
        continue
    elif oggetto == "help":
        clear_screen()
        show_help()
        continue
    elif oggetto == "quit":
        fake_list = []
        for item in shopping_list:
            fake_list += [extract(item)]
            shopping_list = fake_list
        save_list()
        clear_screen()
        print("saved! See you")
        break
    elif oggetto == "save":
        fake_list = []
        for item in shopping_list:
            fake_list += [extract(item)]
            shopping_list = fake_list
        save_list()
        print("saved")
        continue

    # ask for price
    prize = float(input("Enter prize [es. 1.00] > "))

    oggetti = []
    for item in shopping_list:
        oggetti += item.keys()

    for item in oggetti:
        if item.lower() == oggetto:
            # if more expensive, show object and ask for replace
            selezione_dict = shopping_list[oggetti.index(item)]
            if selezione_dict[item][0] < prize: 
                print(shopping_list[oggetti.index(item)])
                rimpiazzo = input("More expensive, replace anyway? [Y/n] > ").lower()
                if rimpiazzo == "n":
                    print("listed object unchanged!")
                    continue
                elif rimpiazzo == "y":
                    market, luogo = dove
                    shopping_list[oggetti.index(item)] = {oggetto : [prize, market, luogo]}
                    print("Replaced!")
                    continue
            else:
                # if cheaper show object and ask for replace
                print(shopping_list[oggetti.index(item)])
                rimpiazzo = input("Cheaper! Replace? [Y/n] > ").lower()
                if rimpiazzo == "n":
                    print("listed object unchanged!")
                    continue
                elif rimpiazzo == "y":
                    market, luogo = dove
                    shopping_list[oggetti.index(item)] = {oggetto : [prize, market, luogo]}
                    print("Replaced!")
                    continue
    # if object not listed, add to the list with place and address
    if oggetto not in oggetti:
        aggiungo = input("Not listed item! Add? [Y/n] > ").lower()
        if aggiungo == "n":
            print("object not added")
            continue
        elif aggiungo == "y":
            market, luogo = dove
            shopping_list.append({oggetto : [prize, market, luogo]}); 

1 Answer

Kenneth Love
STAFF
Kenneth Love
Treehouse Guest Teacher

The way I always think of it is that you put related lines of code into functions and related functions into classes. So start with that. Do you have functions that are all related around the same kind of data?

I would think you'd have a class to represent an item on your shopping list. What kinds of methods would that have? Maybe something to change the quantity? Or the order?

Would the list be an object? Maybe! It would make sense to have a method that allowed you to add items to it (which would, in turn, create new ListItem objects (or whatever you called them)).

I'm actually working on refreshing Object-Oriented Python right now, so feel free to email me (or comment here) with things you'd like to see updated, included, explored, etc.

Thank you very much Kenneth for you answer, I've started to make my shopping_list app a little bit more readable. For the moment I've created a class that imports or saves the list, and another main one that compares, adds and replaces objects. I'm not sure if I'm doing what you suggested me but now the app seems less messy.

https://github.com/francescocabiddu/shopping_list

Many thanks! ;)