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

All together now - The project

TICKET_PRICE = 20
tickets_remaining = 100

def total_cost(tickets):
    if tickets <= 0:
        raise ValueError("You must atleast buy 1 ticket you cheap bas...!")
    elif tickets > tickets_remaining:
        raise ValueError("Sorry but we just have {} tickets left".format(tickets_remaining))
    return tickets * 20

name = input("Hello and welcome to Monty Pythons ticket purchase shop, what is your name?  ")
print(f"Hi there {name}! This is the only place where you can get tickets to the Monty Python show!")

while tickets_remaining > 0:
    print(f"there are currently {tickets_remaining} tickets remaining")
    try:
        ticket_amount = int(input("How many tickets would you like to purchase?"))
        confirm_purchase = input(f"The total cost is {total_cost(ticket_amount)}\nWould you like to continue with the purchase? Y/N  ").upper()
    except ValueError as err:
        print("That is not a valid amount")
        print(err)
    else:
        if confirm_purchase == "Y" or confirm_purchase == "YES":
            tickets_remaining -= ticket_amount
        else:
            print("Transaction was cancelled")

print("We are all sold out and there are no more tickets to buy!")

Hello!

I challenged myself to make the program without looking at the video tutorial Craig made for making the console application - 'The Project' in Python basics. I would like to get some feedback and tips what I could improve or if I am doing something that's bad practice etc. Anyhow, would love to see some response to this one :)

3 Answers

Hi Isak!

Your solution looks pretty good.

Here is a version of my solution (which goes beyond the challenge) with error handling:

TICKET_PRICE = 10

tickets_remaining = 100  

while tickets_remaining >= 1:
    if tickets_remaining > 1:
        verb = "are"
        remaining_s = "s"
    else:
        verb = "is"
        remaining_s = ""
    print("There {} {} ticket{} remaning (at $10.00 per ticket).".format(verb, tickets_remaining, remaining_s))
    valid = False
    while valid != True:
        client_name = input("What is your name? ")
        if (len(client_name) == 0):
            print("*** INVALID SELECTION ***")
        else:
            try:
                val = int(client_name) ###  IF THIS FAILS, client_name is a string - the desired value type  ###
            except ValueError: ###  BACKWORDS LOGIC HERE  ###
                valid = True
            else:
                print("*** INVALID SELECTION ***")
    valid = False
    while valid != True:
        num_ticket = input("{}, how many tickets do you want to purchase? ".format(client_name))
        try:
            val = int(num_ticket)
        except ValueError:
            print("*** INVALID SELECTION ***")
            continue
        if val <= tickets_remaining:
            valid = True
        else:
            print("*** ERROR ***: There {} only {} ticket{} remaining. Try again.".format(verb, tickets_remaining, remaining_s))
    num_ticket = int(num_ticket)
    if num_ticket > 1:
        num_s = "s"
    else:
        num_s = ""
    amount_due = num_ticket * TICKET_PRICE
    print("The total amout due is ${}.00 for {} ticket{}.".format(amount_due, num_ticket, num_s))
    user_info = input("Do you want to procced Y/N? ").lower()
    if user_info == "y":
        print("SOLD!!!")
        tickets_remaining -= num_ticket
    else :
        print("Thanks anyways, {}".format(client_name))
print("Tickets soldout! :( ")

If you notice, in one section I sort of use ValueError backwards, but it makes it work. - I try to cast clientName to an int, and when it errors, I know it's a string (and therefore valid when it errors!?!) Again, kind of backwards logic, but sometimes you have to think outside-the-box!?! LOL

From this thread:

https://teamtreehouse.com/community/can-someone-help-me-with-this-python-script

You can test it here:

https://www.katacoda.com/courses/python/playground

II hope that helps.

Stay safe and happy coding!

Thanks for the answer!

Any reason for the backward logic or just for the sake of it?

Good idea with diffrent verb conjugation aswell. I appreciate the answer and the alternate version of the code.

Hi Isak!

The reason for the backwards logic was, for me, the easiest way to validate that the value was a string.

If you try to cast it to int, if it errors, then you know it's not a number (therefore a likely valid name string).

There are probably better ways to do string validation - but that was a workable quick-n-dirty approach to just get the job done and move on.

Also, that way also used try/except/else logic (albeit backwards), instead of if/else logic.

Part of the reason for doing it that way is because input returns a string value, even if you input 123.

So this:

name = input("Name: ")

print( isinstance(name, str) )

If you input 123, it will still return True because, technically input will return '123' not 123.

(In other word, you are really trying to rule out number strings.)

So val = int(client_name) is a better test, because it will NOT fail whether you pass it '123' or 123.

And if it does FAIL, then it must NOT be a number string.

Does that make sense?

As for the verb conjugation, yea I HATE seeing stuff like:

You have 1 tickets remaining.

I pay attention to those kinds of details - it makes for a much better user experience!

I hope that helps.

Stay safe and happy coding!

Hello!

My new and updated code, have a look!

TICKET_PRICE = 10

tickets_remaining = 100

def total(ticket_amount):
    if ticket_amount <= 0:
        raise ValueError("Purchase requirement, atleast one ticket")
    elif tickets_remaining < ticket_amount:
        raise ValueError(f"You tried to purchase {ticket_amount} ticket{noun_ending}, there {verb_1} only {tickets_remaining} ticket{noun_ending} available")
    return ticket_amount * TICKET_PRICE 

user_name = input("What's your name?  ")

while tickets_remaining > 0:
    if tickets_remaining > 1:
        verb_1 = "are"
        noun_ending = "s"
    else:
        verb_1 = "is"
        noun_ending = ""
    print(f"Hello {user_name}! There {verb_1} {tickets_remaining} ticket{noun_ending} remaining.")
    try:
        ticket_amount = int(input("How many tickets would you like to purchase?  "))
        total_cost = total(ticket_amount)
    except ValueError as err:
        print("Thas' an invalid value, please try again")
        print(err)
    else:
        print("Total cost for the tickets ${}".format(total_cost))
        confirm_purchase = input("Do you want to continue with the purchase, Y/N?  ").upper()

        if confirm_purchase == "Y" or confirm_purchase == "YES":
            print("SOLD!")
            tickets_remaining -= ticket_amount
        else:
            print("Okay {}, Thanks anyway!".format(user_name))

print("We are all out of tickets! See you next time!")

Hello again. Very interesting with the way you rule out it's not a numerical string with a try block that if it fails you are sure it's a string. Thanks for the help and the inspiration :)