function with loop and if statement help

This is the place for queries that don't fit in any of the other categories.

function with loop and if statement help

Postby Tyreejackson » Wed Jun 12, 2013 4:07 am

Hi there, I just started working with python last week in to try and learn something new and I have encountered a problem.

The program I am trying to write is as follows
- asks the user how many books they bought
- asks the user the cost of each book
- if they buy 4 or more books, they receive a 40% discount on their purchase
-if they buy 3 books, they receive a 30% discount on their purchase
-if they buy 2 books, they receive a 20% discount on their purchase
-if they buy 1 book, they receive a 10% discount on their purchase
- must write the code using functions
-must call the function in from another module (using ECLIPSE IDE with pythonviewer)

My approach was to first find the total of the books using a for loop and then using if statements, i would apply the proper discount to the total to get the grand total. I have been able to run this code, but I cannot get the right answer if 4 books are purchased (discount doesnt apply properly) OR only one book is purchased (get error: local variable 'grand_total' referenced before assignment)

Here is my code:
Code: Select all
def total_cost (numbooks):
   
    total = 0
   
   
    for numbooks in range(numbooks):
        price_each_book = int(input("price of the book?"))
        total = total + price_each_book
       
        if numbooks >= 5:
            grand_total = total - (total * 0.4)
   
   
        elif numbooks == 4:
            grand_total = total - (total * 0.4)
   
        elif numbooks ==3:
            grand_total = total - (total * 0.3)
       
        elif numbooks ==2:
            grand_total = total - (total * 0.2)
       
        elif numbooks ==1:
            grand_total = total - (total * 0.1)
       
    return grand_total


and to call and run the function from another module:

Code: Select all
import maggiespizza

numbooks = int(input("How many books are you buying?"))

s = maggiespizza.total_cost(numbooks)

print ("total: {0} " .format(s))


Any help would be appreciate, thanks for your time!
Tyreejackson
 
Posts: 7
Joined: Wed Jun 12, 2013 3:56 am

Re: function with loop and if statement help

Postby micseydel » Wed Jun 12, 2013 4:32 am

Code: Select all
for numbooks in range(numbooks):

Walk through your code one line at a time, be the interpreter, and you should be able to see what your program is doing, and compare that to what it should be doing. Especially what the line above is doing.
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1303
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: function with loop and if statement help

Postby Mekire » Wed Jun 12, 2013 4:33 am

Well a lot of that stuff doesn't belong in the for loop. Calculate your total in the loop and then calculate your grandtotal outside it.

Also your if/elif statements are fairly unnecessary.
This is a good opportunity to use the min builtin.

Consider the following:
Code: Select all
numbooks = int(input())
discount = min(numbooks*0.1,0.4)
print(discount)

Here the discount is either the number of books times 0.1 or 0.4. Whichever is lower.

-Mek

Edit: Wah... I didn't even noticed he used the name twice in the for loop header.
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: function with loop and if statement help

Postby Tyreejackson » Wed Jun 12, 2013 4:45 am

micseydel wrote:
Code: Select all
for numbooks in range(numbooks):

Walk through your code one line at a time, be the interpreter, and you should be able to see what your program is doing, and compare that to what it should be doing. Especially what the line above is doing.


Thanks for this. I switched the 'iterator' (I believe his is what it is called?) to "i" instead of numbooks, and this seemingly fixed all of my problems. The only reason that I used numbooks twice in the first place is because the IDE warned me that I had an unused variable, however, upon further reading it seems that an unused iterator is not a problem.
Tyreejackson
 
Posts: 7
Joined: Wed Jun 12, 2013 3:56 am

Re: function with loop and if statement help

Postby Tyreejackson » Wed Jun 12, 2013 4:49 am

Mekire wrote:Well a lot of that stuff doesn't belong in the for loop. Calculate your total in the loop and then calculate your grandtotal outside it.

Also your if/elif statements are fairly unnecessary.
This is a good opportunity to use the min builtin.

Consider the following:
Code: Select all
numbooks = int(input())
discount = min(numbooks*0.1,0.4)
print(discount)

Here the discount is either the number of books times 0.1 or 0.4. Whichever is lower.

-Mek

Edit: Wah... I didn't even noticed he used the name twice in the for loop header.

I will look into this further, so i can code as efficiently as possible one day!! Not quite sure how to implement it as of now, though. Thank you for broadening my knowledge!
Tyreejackson
 
Posts: 7
Joined: Wed Jun 12, 2013 3:56 am

Re: function with loop and if statement help

Postby Mekire » Wed Jun 12, 2013 5:00 am

Congratulations on finding the solution. Switching the iterator will indeed solve your problem, but as I said you don't need to calculate the grand total inside the loop. You calculate the grand total for every single book but only actually need to do it after all books are input. It is a waste. Also as I said previously you really shouldn't be using if/elifs for every single option to figure out the discount rate. There is a much easier way.

As you have already solved your problem I will show you:
Code: Select all
def total_cost(numbooks):
    total = 0
    for i in range(numbooks):
        price_each_book = float(input("price of the book?"))
        total += price_each_book
    discount = min(numbooks*0.1,0.4)
    return total*(1-discount)

Also you might want to consider putting some error checking on your inputs. As it stands the program will crash on a bad input.

-Mek
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: function with loop and if statement help

Postby Tyreejackson » Wed Jun 12, 2013 6:07 am

Mekire wrote:Congratulations on finding the solution. Switching the iterator will indeed solve your problem, but as I said you don't need to calculate the grand total inside the loop. You calculate the grand total for every single book but only actually need to do it after all books are input. It is a waste. Also as I said previously you really shouldn't be using if/elifs for every single option to figure out the discount rate. There is a much easier way.

As you have already solved your problem I will show you:
Code: Select all
def total_cost(numbooks):
    total = 0
    for i in range(numbooks):
        price_each_book = float(input("price of the book?"))
        total += price_each_book
    discount = min(numbooks*0.1,0.4)
    return total*(1-discount)

Also you might want to consider putting some error checking on your inputs. As it stands the program will crash on a bad input.

-Mek


Wow this is really elegant / efficient. It does all the work my program did but with half the code. I do have a question or two though if you don't mind...

The "+=" does what exactly? my guess would be is that it sums up the price_each_book variable at each stage of the loop? This is a lot more simple than writing total = total + price_each_book

From what I've read, the min() function returns the smallest item entered into the numbooks variable? I don't understand what the * 0.1,0.4 really does, although i do recognize them as the discount percentages. If you could shed any light on how i should be using this function it would be much appreciated! I will check back into this thread tomorrow!
Tyreejackson
 
Posts: 7
Joined: Wed Jun 12, 2013 3:56 am

Re: function with loop and if statement help

Postby Mekire » Wed Jun 12, 2013 6:25 am

Your discount is equal to the number of books times 0.1.
However the max discount is 0.4 so after you have 4 books it stays at 0.4.

The minimum builtin, min, returns the lowest of the values passed to it as arguments.
I pass it the arguments numbooks*0.1 and 0.4.
If numbooks*0.1 is lower than 0.4 it will return that value.
If numbooks*0.1 is greater than 0.4 it will return 0.4.

There is a builtin for finding maximums as well called max.

As for +=, I was just talking about this in another thread so I will direct you there.
http://python-forum.org/viewtopic.php?f=6&t=4075#p4992

-Mek

Edit:
Just to be clear, there are two ways to pass arguments to min. You can pass it multiple arguments in which case it will return the lowest one; as in the following:
Code: Select all
>>> min(3,4,6,2,7,0.25,200)
0.25
>>>
Or you can pass it one argument which is a sequence (including generators); as in the following:
Code: Select all
>>> mylist = [3,4,6,2,7,0.25,200]
>>> min(mylist)
0.25
>>>
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: function with loop and if statement help

Postby Tyreejackson » Wed Jun 12, 2013 6:39 pm

Mekire wrote:Your discount is equal to the number of books times 0.1.
However the max discount is 0.4 so after you have 4 books it stays at 0.4.

The minimum builtin, min, returns the lowest of the values passed to it as arguments.
I pass it the arguments numbooks*0.1 and 0.4.
If numbooks*0.1 is lower than 0.4 it will return that value.
If numbooks*0.1 is greater than 0.4 it will return 0.4.

There is a builtin for finding maximums as well called max.

As for +=, I was just talking about this in another thread so I will direct you there.
http://python-forum.org/viewtopic.php?f=6&t=4075#p4992

-Mek

Edit:
Just to be clear, there are two ways to pass arguments to min. You can pass it multiple arguments in which case it will return the lowest one; as in the following:
Code: Select all
>>> min(3,4,6,2,7,0.25,200)
0.25
>>>
Or you can pass it one argument which is a sequence (including generators); as in the following:
Code: Select all
>>> mylist = [3,4,6,2,7,0.25,200]
>>> min(mylist)
0.25
>>>

Thanks Mekire. Your explanation is extremely helpful. I will try to use the min builtin next time when the opportunity arises!
Tyreejackson
 
Posts: 7
Joined: Wed Jun 12, 2013 3:56 am


Return to General Coding Help

Who is online

Users browsing this forum: Google [Bot] and 3 guests