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 SQLAlchemy Basics Working with SQLAlchemy Update and Delete Books

Its not giving me an error message when I enter in the wrong date.

It still gives me an error when I put in the wrong price, but I'm having trouble figuring out why it doesn't give me an error for the wrong date.

here is my code:

from models import (Base, session, Book, engine)
import csv
import datetime
import time 

def menu():
    while True:
        print('''
              \nPROGRAMING BOOKS
              \r1) Add book 
              \r2) View all books
              \r3) Search for book
              \r4) Book analysis
              \r5) Exit''')
        choice = input('What would you like to do?  ')
        if choice in ['1', '2', '3', '4', '5']:
            return choice
        else:
            input('''\rPlease choose one of the options above.
                  \rA number from 1-5.
                  \rPress enter to try again''')

def submenu():
    while True:
        print('''
              \r1) Edit 
              \r2) Delete
              \r3) Return to main menu 
              ''')
        choice = input('What would you like to do?  ')
        if choice in ['1', '2', '3']:
            return choice
        else:
            input('''
                  \rPlease choose one of the options above.
                  \rA number from 1-3.
                  \rPress enter to try again.''')

#the reson while true was used was because return in return choice can stop the loop and return the choice.
#thats also why we put if choice is in a set of numbers to choose from the menu


#we need to clean the csv and make the dates and prices integers bc thats how the datetime.date() has is check fit for hints
#clean_date has to take in the dates and convert them


def clean_date(date_str):
    months = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
              'August', 'September', 'October', 'November', 'December']
    split_date = date_str.split(' ')
    try:
        month = int(months.index(split_date[0]) + 1)
        day = int(split_date[1].split(',')[0])
        year = int(split_date[2])
        return_date = datetime.date(year, month, day)
    except ValueError:
        input('''
              \n ****DATE ERROR****
              \rThe Date format should include a valid Month, Day, Year from the past
              \rEx: January 13th, 2003
              \rPress enter to try again
              \r**********************************''')
        return #we can just put return it doesnt do anything just goes back loop same as return NOone
    else:
        return return_date




def clean_price(price_str):
    try:
        price_float = float(price_str)
    except ValueError:
        input('''
              \n ****PRICE ERROR****
              \rThe Price should not be a number without a currency symbol.
              \rEx: 12.99
              \rPress enter to try again
              \r**********************************''')
    else:
        return int(price_float * 100)


def clean_id(id_str, options):
    try:
        book_id = int(id_str)
    except ValueError: 
        input('''
              \n ****ID ERROR****
              \rThe ID should not be a number.
              \rPress enter to try again
              \r**********************************''')
        return
    else:
        if book_id in options:
            return book_id
        else:
            input(f'''
              \n ****ID ERROR****
              \rOptions: {options}
              \rPress enter to try again
              \r**********************************''')

def edit_check(column_name, current_value):
    print(f'\n**** EDIT {column_name} ****')
    if column_name == 'Price':
        print(f'\rCurrent Value: {current_value/100}')
    elif column_name == 'Date':
        print(f'\rCurrent Value: {current_value.strftime("%B %d %Y")}')
    else:
        print(f'\rCurrent Value: {current_value}')


    if column_name == 'Date' or column_name == 'Price':
        while True:
            changes = input('What would you like to change the value to?  ')
            if column_name == 'Date':
                changes = clean_date(changes)
                if type(changes) == datetime.date:
                    return changes
            elif column_name == 'Price':
                changes = clean_price(changes)
                if type(changes) == int:
                    return changes

    else: 
        return input('What would you like to change the value to?  ')


def add_csv():
    with open('suggested_books.csv') as csvfile:
        data = csv.reader(csvfile)
        for row in data:
            book_in_db = session.query(Book).filter(Book.title==row[0]).one_or_none()
            if book_in_db == None:
                title = row[0]
                author = row[1]
                date = clean_date(row[2])
                price = clean_price(row[3])
                new_book = Book(title=title, author=author, published_date=date, price=price)
                session.add(new_book)
        session.commit()





def app():
    app_running = True
    while app_running:
            choice = menu()
            if choice == '1':
                #add book
                title = input('Title: ')
                author = input('Author: ')
                date_error = True
                while date_error:
                    date = input('Published Date: (Ex: October 25, 2017): ')
                    date = clean_date(date)
                    if type(date) == datetime.date:
                        date_error = False
                price_error = True
                while price_error:       
                    price = input('Price (Ex: 25.64): ')
                    price = clean_price(price)
                    if type(price) == int:
                        price_error = False
                new_book = Book(title=title, author=author, published_date=date, price=price)
                session.add(new_book)
                session.commit()
                print('Book Added!')
                time.sleep(2)
            elif choice == '2':
                #view books
                for book in session.query(Book):
                    print(f'{book.id} | {book.title} | {book.author}')
                input('\nPress enter to return to the main menu.')
            elif choice == '3':
                #search book
                id_options = []
                for book in session.query(Book):
                    id_options.append(book.id)
                id_error = True
                while id_error:
                    id_choice = input(f'''
                      \nId Options: {id_options}
                      \rBook id: ''')   
                    id_choice = clean_id(id_choice, id_options)
                    if type(id_choice) == int:
                        id_error = False
                the_book = session.query(Book).filter(Book.id==id_choice).first()
                print(f'''
                      \n{the_book.title} by {the_book.author}
                      \rPublished: {the_book.published_date}
                      \rPrice: ${the_book.price / 100}''')
                sub_choice = submenu()
                if sub_choice == '1':
                    #edit
                    the_book.title = edit_check('Title', the_book.title)
                    the_book.author = edit_check('Author', the_book.author)
                    the_book.published_date = edit_check('Published', the_book.published_date)
                    the_book.price = edit_check('Price', the_book.price)
                    print(session.dirty)
                elif sub_choice == '2':
                    #delete
                    pass
            elif choice == '4':
                #analysis
                pass
            else: 
                print('GOODBYE')
                app_running = False


if __name__ == '__main__':
    Base.metadata.create_all(engine)
    # app()
    add_csv()
    #we can just put app() now instead of menu() bc app() has menu() choices inside
    #we need to clean csv because we nee to change certain data types
    app()

    for book in session.query(Book):
        print(book)

Here is my terminal:

PROGRAMING BOOKS  
1) Add book       
2) View all books 
3) Search for book
4) Book analysis  
5) Exit
What would you like to do?  3


Id Options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Book id: 11


Chuck Norris Adventures by Chuck Norris
Published: 2005-01-12
Price: $10.5

1) Edit
2) Delete
3) Return to main menu

What would you like to do?  1

**** EDIT Title ****
Current Value: Chuck Norris Adventures
What would you like to change the value to?  Chuck Norris Great Adventures

**** EDIT Author ****
Current Value: Chuck Norris
What would you like to change the value to?  Chuck Norris

**** EDIT Published ****
Current Value: 2005-01-12
What would you like to change the value to?  January first, 2020

**** EDIT Price ****
Current Value: 10.5
What would you like to change the value to?  five 


 ****PRICE ERROR****
The Price should not be a number without a currency symbol.
Ex: 12.99
Press enter to try again
**********************************
What would you like to change the value to?  2.99
IdentitySet([Title: Chuck Norris Great Adventures, Author: Chuck Norris, Published: January first, 2020, Price: 299])

You can see in the terminal that its not giving me an error message even though i put the wrong date/value type

What is wrong with my code? Any help is appreciated

1 Answer

Mark Sebeck
MOD
Mark Sebeck
Treehouse Moderator 37,341 Points

Hi Joshua. So you are not getting an exception error so that mean an issue with checking the date. After taking a look at you code it appears you forgot to call edit_check for the date

if sub_choice == '1':
                    #edit
                    the_book.title = edit_check('Title', the_book.title)
                    the_book.author = edit_check('Author', the_book.author)
                    the_book.published_date = edit_check('Published', the_book.published_date)
                    the_book.price = edit_check('Price', the_book.price)
                    print(session.dirty)
                elif sub_choice == '2':

Hope this helps and fixes your issue. Good luck and keep at it!

Mark Sebeck
Mark Sebeck
Treehouse Moderator 37,341 Points

BTW nice job including the code and runtime output. That was very helpful for debugging

But I am looking at my code and I actually didnt forget to call the edit_check function..... I think something else is wrong..??

Mark Sebeck
Mark Sebeck
Treehouse Moderator 37,341 Points

Hi Joshua Faisal . Ah yes. But look at 11:07 in the video. They are passing 'Date' and you are passing 'Published' into edit_check(). Sorry for the confusion.

Oh got it now. Thanks a lot. Its pretty amazig how a small thing like that can mess up everything lol.

Mark Sebeck
Mark Sebeck
Treehouse Moderator 37,341 Points

You’re welcome. Happy to help. Yes small errors can sometimes be frustrating to find sometimes. Just have to keep practicing and it will become easier.