Question

I am coding in python and I cannot seem to figure out why when the amount of tickets sold is entered it does not calculate the full price of the tickets that were sold. Any help is appreciated, Thanks.

aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0

def Main():
    getTickets(aLimit)
    sectionIncome=calcIncome(ticketSold,aPrice)
    sectionIncome+=totalIncome
    print("The theater generated this much money from section A "+
          str(sectionIncome))

    getTickets(bLimit)
    sectionIncome=calcIncome(ticketSold,bPrice)
    sectionIncome+=totalIncome
    print("The theater generated this much money from section B "+
          str(sectionIncome))

    getTickets(cLimit)
    sectionIncome=calcIncome(ticketSold,cPrice)
    sectionIncome+=totalIncome
    print("The theater generated this much money from section C "+
          str(sectionIncome))
    print("The Theater generated "+str(totalIncome)+" total in ticket sales.")

def getTickets(limit):
    ticketSold=int(input("How many tickets were sold? "))
    if (ticketsValid(ticketSold,limit)==True):
        return ticketSold
    else:
        getTickets(limit)

def ticketsValid(Sold,limit):
    while (Sold>limit or Sold<0):
        print("ERROR: There must be tickets less than "+
              str(limit)+" and more than 0")
        return False
    return True

def calcIncome(ticketSold,price):
    return ticketSold*price

Main()
Was it helpful?

Solution

How to debug your (small) program

Okay so let's start from the top and go line-by-line. There's a lot of issues here.

aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0

These are all globals since you defined them in the module scope. That's a Bad Thing. Don't do it. If they're constants, use CAPS to mention that, but they should still not be global.

def Main(): # I mentioned in my comment, but Capitals are classes
            # by convention, use def main() instead
    getTickets(aLimit)

Let's stop and look at getTickets() so we can follow execution

def getTickets(limit): # camelCase is not advised per PEP8, but it's still around
                       # so I wouldn't worry about this one so much as Capitalized
    ticketSold=int(input("How many tickets were sold? "))
    # perfect implementation, though be prepared for users who
    # will type forty instead of 40!
    if (ticketsValid(ticketSold,limit)==True):
        return ticketSold
    # so any time you write `if ___ == True`, stop and realize that the compare
    # is unnecessary. if ticketsValid(ticketSold,limit) works just as well!
    else:
        getTickets(limit)
    # wha-? If the tickets aren't valid, we're RECURSING??! This is an infinite loop.
    # are you doing this to prompt for more input if tickets aren't valid? That's Bad

Okay so you invoked ticketsValid in there, so let's look there now...

def ticketsValid(Sold,limit): # another Capital here!
    while Sold > limit or Sold < 0: # this should be an if??
        print ("...")
        return False
    return True
# Since you have a set amount, this is MUCH easier written as:
## def ticketsValid(sold,limit):
##     return 0 < sold < limit
# but should this be <=?

Alright, back to main--ahem--Main....

def Main():
    ...
    sectionIncome = calcIncome(ticketSold,aPrice)

And hop back to calcIncome

def calcIncome(ticketSold,price):
    return ticketSold*price # why not just substitute this???

Main again

def Main():
    ...
    sectionIncome += totalIncome
    # this sets sectionIncome equal to the current value of sectionIncome
    # plus the current value of totalIncome, which is currently zero.

Then basically the whole thing gets repeated down the function. There's your issue, the += adds zero to sectionIncome instead of adding sectionIncome to totalIncome!

The better way to do this!

Here's the problem. You're trying to use functional programming to do object-oriented tasks. Most of these kind of issues are when new programmers who are interested in video games think that the best task to learn programming is a text adventure. Unfortunately, the best languages for text adventures (those that easily implement a Finite State Machine) are not usually those that beginners start with, so it's hard to implement WELL!

In your case, you should be creating objects to do the workload for you. Python does this elegantly, but it's rarely in beginning tutorials. As an example, I wrote out a bit that does exactly what you did (defines three sections of seating in a theater and sells one ticket per section)

class Section(object):
    def __init__(self,price,limit):
        self.price = price
        self.tickets_sold = 0
        self.limit = limit
    @property
    def sales(self):
        return self.price*self.tickets_sold
    def sell(self,qty=1):
        if not isinstance(qty,int): raise TypeError("Must sell an int of tickets")
        if qty < 1: raise ValueError("Must sell positive tickets")
        qty = min(qty,self.limit-self.tickets_sold)
        self.tickets_sold += qty
        # optional print statement for the user

class Theater(object):
    def __init__(self,sections):
        self.sections = sections
    @property
    def sales(self):
        return sum(section.sales for section in self.sections)

theater = Theater([Section(20,300),
                  Section(15,500),
                  Section(10,100)])

for section in theater.sections:
    section.sell(1)
print(theater.sales)

The big problem with this is just that you don't know how to do it. Creating an object that will stay constant, then throw several instances of it around with specific attributes is precisely the approach I would favor in this circumstance.

OTHER TIPS

read up on the += operator. totalIncome is only ever set to 0.

You need to replace sectionIncome+=totalIncome with totalIncome+=sectionIncome

Code

aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0

def Main():
    getTickets(aLimit)
    sectionIncome=calcIncome(ticketSold,aPrice)
    totalIncome=sectionIncome
    print("The theater generated this much money from section A "+str(sectionIncome))

    getTickets(bLimit)
    sectionIncome=calcIncome(ticketSold,bPrice)
    totalIncome+=sectionIncome
    print("The theater generated this much money from section B "+str(sectionIncome))

    getTickets(cLimit)
    sectionIncome=calcIncome(ticketSold,cPrice)
    totalIncome+=sectionIncome
    print("The theater generated this much money from section C "+str(sectionIncome))
    print("The Theater generated "+str(totalIncome)+" total in ticket sales.")

def getTickets(limit):
    ticketSold=int(input("How many tickets were sold? "))
    if (ticketsValid(ticketSold,limit)==True):
        return ticketSold
    else:
        getTickets(limit)

def ticketsValid(Sold,limit):
    while (Sold>limit or Sold<0):
        print ("ERROR: There must be tickets less than "+str(limit)+" and more than 0")
        return False
    return True


def calcIncome(ticketSold,price):
    return ticketSold*price


Main()

sectionIncome+=totalIncome

This is the wrong way around. To add to totalIncome the value of sectionIncome, the syntax is

totalIncome+=sectionIncome

You will allso need to add global totalIncome to the beginning of Main -- or, better yet, do away with the global variables completely, like you have often been told before.

Finally, your getTickets function returns a calculated value, but the code which calls it doesn't store that result anywhere. Instead, you simply set ticketSold=1 in the global initialization, then use that as the multiplier instead of the actual number of tickets input by the user.

As a general observation, you have a lot of repetitive code, while the functions you do have are not very useful (they do not encapsulate complex behavior, nor repeated functionality). If you are a beginner, concentrate on a straightforward flow, then factor out complex repeating operations to loops or functions. Perhaps something like this:

def income ():
    total = 0
    for ticket_type, limit, price in [('A', 300, 20),
                                      ('B', 500, 15),
                                      ('C', 100, 10)]:
        print "How many %s tickets sold? (Max %d):" % (ticket_type, limit),
        sold = -1
        while sold < 0 or sold > limit:
            if sold != -1:
                print "Sorry.  Try again:",
            sold = raw_input()
            try:
                sold = int(sold)
            except:
                pass
        total += sold*price
    print "total %d" % total

income()

Please also note the user-friendly gesture of indicating the maximum allowed for each category in the input prompt (-:

The loop driver is a bit of a wart; a slicker way to do that would be to declare a class TicketCategory and have three instances A, B, and C with methods to report back their name, price, and available amounts, but that's for later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top