Velocity Reviews > (Very Newbie) Problems defining a variable

# (Very Newbie) Problems defining a variable

febaen@gmail.com
Guest
Posts: n/a

 12-12-2008
#!/usr/bin/python
#Py3k, UTF-8

bank = int(input("How much money is in your account?\n>>"))
target = int(input("How much money would you like to earn each year?
\n>>"))

interest = 0
i = 0

while interest < target:
#determine the interest rate to use
if bank >= 9999:
rate = 0.006
elif bank >= 10000 and bank <= 24999:
rate = 0.0085
elif bank >= 25000 and bank <= 49999:
rate = 0.0124
elif bank >= 50000 and bank <= 99999:
rate = 0.0149
elif bank >= 100000:
rate = 0.0173
#Now that we know what interest rate to use, apply it...
lastbank = bank #To calculate interest...
bank += (bank * rate) #Update earnings...
interest = bank - lastbank #And figure out how much interest is made!
i += 1 #So we can see which year a calculation represents
print("Year %s, at %s rate: %s paid, %s in bank." % (i, rate,
interest, bank))

I wrote this expanding off an 'interest' exercise in a tutorial, which
was fairly simple (assume %1, calculate for ten years). It's intended
to take how much the user has in the bank and determine how long it
will be until it generates a certain amount in interest each year. The
problem is that rates are not solid, and increase at certain points. I
put the rates from the basic account option at my bank in as an
example.

I'm pretty certain that that is also the problem in the code. I'm
pretty sure it's a problem with the 'if' statements', and it looks
like it's one of those mistakes that's so simple you look back on it
and laugh at yourself. If you put in a bank number <= 9999, it fails,
saying "NameError: name 'rate' is not defined". If you put in one
higher, it runs correctly, but thinks that the rate is 0.006

I tried def'ing a function for it, which didn't work any better. I'm
having a hard time figuring out exactly why it is those if statements
are wrong.

Bruno Desthuilliers
Guest
Posts: n/a

 12-12-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) a écrit :
> #!/usr/bin/python
> #Py3k, UTF-8
>
> bank = int(input("How much money is in your account?\n>>"))
> target = int(input("How much money would you like to earn each year?
> \n>>"))
>
> interest = 0
> i = 0
>
> while interest < target:
> #determine the interest rate to use
> if bank >= 9999:
> rate = 0.006
> elif bank >= 10000 and bank <= 24999:
> rate = 0.0085
> elif bank >= 25000 and bank <= 49999:
> rate = 0.0124
> elif bank >= 50000 and bank <= 99999:
> rate = 0.0149
> elif bank >= 100000:
> rate = 0.0173

(snip)

> I'm pretty certain that that is also the problem in the code. I'm
> pretty sure it's a problem with the 'if' statements', and it looks
> like it's one of those mistakes that's so simple you look back on it
> and laugh at yourself. If you put in a bank number <= 9999, it fails,
> saying "NameError: name 'rate' is not defined". If you put in one
> higher, it runs correctly, but thinks that the rate is 0.006

Indeed. That's what you asked for. If bank is >= 9999, then rate will be
set to 0.006, and the following tests will be skipped. Else - since you
just don't handle the case -, rate is not defined at all.

I guess you wanted your first test to be:

if bank <= 9999:
...

FWIW, when using if/elif that way, make sure you always end with a
"default" else clause (even if just to signal you didn't expect to be
there...)

HTH

feba
Guest
Posts: n/a

 12-12-2008
On Dec 12, 5:56*am, Bruno Desthuilliers <bruno.
(E-Mail Removed)> wrote:
> (E-Mail Removed) a écrit :
>
>
>
> > #!/usr/bin/python
> > #Py3k, UTF-8

>
> > bank = int(input("How much money is in your account?\n>>"))
> > target = int(input("How much money would you like to earn each year?
> > \n>>"))

>
> > interest = 0
> > i = 0

>
> > while interest < target:
> > #determine the interest rate to use
> > * *if bank >= 9999:
> > * * * * * *rate = 0.006
> > * *elif bank >= 10000 and bank <= 24999:
> > * * * * * *rate = 0.0085
> > * *elif bank >= 25000 and bank <= 49999:
> > * * * * * *rate = 0.0124
> > * *elif bank >= 50000 and bank <= 99999:
> > * * * * * *rate = 0.0149
> > * *elif bank >= 100000:
> > * * * * * *rate = 0.0173

>
> (snip)
>
> > I'm pretty certain that that is also the problem in the code. I'm
> > pretty sure it's a problem with the 'if' statements', and it looks
> > like it's one of those mistakes that's so simple you look back on it
> > and laugh at yourself. If you put in a bank number <= 9999, it fails,
> > saying *"NameError: name 'rate' is not defined". *If you put in one
> > higher, it runs correctly, but thinks that the rate is 0.006

>
> Indeed. That's what you asked for. If bank is >= 9999, then rate will be
> set to 0.006, and the following tests will be skipped. Else - since you
> just don't handle the case -, rate is not defined at all.
>
> I guess you wanted your first test to be:
>
> * * if bank <= 9999:
> * * * *...
>
> FWIW, when using if/elif that way, make sure you always end with a
> "default" else clause (even if just to signal you didn't expect to be
> there...)
>
> HTH

that's it, thanks! was confused with it being basically in a column of
all >= *.

I replaced it with

if bank <= 0:
print("You're in the red!")
quit()
elif bank >= 1 and bank <= 9999:
rate = 0.0060
elif bank >= 10000 and bank <= 24999:
rate = 0.0085
elif bank >= 25000 and bank <= 49999:
rate = 0.0124
elif bank >= 50000 and bank <= 99999:
rate = 0.0149
elif bank >= 100000:
rate = 0.0173
else:
print("What's this doing here?")

which also changes it to keep it from going on forever if you put in a
negative amount. Out of curiosity, would you still recommend applying
an 'else' clause in this case? I don't see how it could ever be
triggered, even if there's an error of some kind

Steven D'Aprano
Guest
Posts: n/a

 12-12-2008
On Fri, 12 Dec 2008 04:05:21 -0800, feba wrote:

> that's it, thanks! was confused with it being basically in a column of
> all >= *.
>
> I replaced it with
>
> if bank <= 0:
> print("You're in the red!")
> quit()
> elif bank >= 1 and bank <= 9999:
> rate = 0.0060

You can replace this with the simpler, easier to read and faster:

elif 1 <= bank <= 9999:
rate = 0.0060
elif 10000 <= bank <= 24999:
rate = 0.0085

....

> elif bank >= 100000:
> rate = 0.0173
> else:
> print("What's this doing here?")

Change the last two else clauses to this one:

else:
rate = 0.0173

--
Steven

Chris Rebert
Guest
Posts: n/a

 12-12-2008
On Fri, Dec 12, 2008 at 3:42 AM, <(E-Mail Removed)> wrote:
> #!/usr/bin/python
> #Py3k, UTF-8
>

<snip>
>
> #determine the interest rate to use
> if bank >= 9999:
> rate = 0.006
> elif bank >= 10000 and bank <= 24999:
> rate = 0.0085
> elif bank >= 25000 and bank <= 49999:
> rate = 0.0124
> elif bank >= 50000 and bank <= 99999:
> rate = 0.0149
> elif bank >= 100000:
> rate = 0.0173

For the love of Benji, reverse the ordering of the clauses so you
don't have to keep checking whether the number is also under the next
limit!
flipped around the wrong way was right)

if bank >= 100000:
rate = 0.0173
elif bank >= 50000:
rate = 0.0149
elif bank >= 25000:
rate = 0.0124
elif bank >= 10000:
rate = 0.0085
else:
rate = 0.006

Note how much simpler that is to read and understand. And switching
the default case to the 'else' is just idiomatic.

Cheers,
Chris

--
Follow the path of the Iguana...
http://rebertia.com

bearophileHUGS@lycos.com
Guest
Posts: n/a

 12-12-2008
feba:
> * * * * if bank <= 0:
> * * * * * * * * print("You're in the red!")
> * * * * * * * * quit()
> * * * * elif bank >= 1 and bank <= 9999:
> * * * * * * * * rate = 0.0060
> * * * * elif bank >= 10000 and bank <= 24999:
> * * * * * * * * rate = 0.0085
> * * * * elif bank >= 25000 and bank <= 49999:
> * * * * * * * * rate = 0.0124
> * * * * elif bank >= 50000 and bank <= 99999:
> * * * * * * * * rate = 0.0149
> * * * * elif bank >= 100000:
> * * * * * * * * rate = 0.0173
> * * * * else:
> * * * * * * * * print("What's this doing here?")

I think your indents are a little too much large (the soft standard is
4 spaces).

The last else can be removed.

Does bank == 0 mean being in red?

That list of if-elif seems bug-prone. In the future you will learn
ways to write that in a less bug-prone (but also probably more complex

Bye,
bearophile

Bruno Desthuilliers
Guest
Posts: n/a

 12-12-2008
feba a écrit :
> On Dec 12, 5:56 am, Bruno Desthuilliers <bruno.
> (E-Mail Removed)> wrote:

(snip)
>> I guess you wanted your first test to be:
>>
>> if bank <= 9999:
>> ...

(snip)
> that's it, thanks! was confused with it being basically in a column of
> all >= *.
>
> I replaced it with
>
> if bank <= 0:
> print("You're in the red!")
> quit()
> elif bank >= 1 and bank <= 9999:
> rate = 0.0060
> elif bank >= 10000 and bank <= 24999:
> rate = 0.0085
> elif bank >= 25000 and bank <= 49999:
> rate = 0.0124
> elif bank >= 50000 and bank <= 99999:
> rate = 0.0149
> elif bank >= 100000:
> rate = 0.0173
> else:
> print("What's this doing here?")
>
> which also changes it to keep it from going on forever if you put in a
> negative amount.

Good point.

> Out of curiosity, would you still recommend applying
> an 'else' clause in this case?

Yes, but I'd use it as a replacement for the last test:

# code here ...
elif bank >= 50000 and bank <= 99999:
rate = 0.0149
else:
rate = 0.0173

And finally, I'd simplify the whole damn thing:

if bank < 1:
print("You're in the red!")
quit()
elif bank < 10000:
rate = 0.0060
elif bank < 25000:
rate = 0.0085
elif bank < 50000:
rate = 0.0124
elif bank < 100000:
rate = 0.0149
else:
rate = 0.0173

> I don't see how it could ever be
> triggered, even if there's an error of some kind

It couldn't, indeed. Which FWIW is a clear indication that the previous
test ( elif bank >= 100000 is redundant !-)

HTH

feba
Guest
Posts: n/a

 12-12-2008
Actually, I have gedit set to four spaces per tab. I have no reason
why it's showing up that large on copy/paste, but the file itself is
fine.

Thanks for the advice Chris, Stephen, I can definitely see how those
are both far better ways of doing it. I have it as:

#!/usr/bin/python
#Py3k, UTF-8

bank = int(input("How much money is in your account?\n>>"))
if bank <=0:
print("You need a postive amount to gain interest.")
quit()
target = int(input("How much money would you like to earn each year?
\n>>"))

interest = 0
i = 0

while interest < target:
#determine the interest rate to use
if bank >= 100000:
rate = 0.0173
elif bank >= 50000:
rate = 0.0149
elif bank >= 25000:
rate = 0.0124
elif bank >= 10000:
rate = 0.0085
else:
rate = 0.0060
#Now that we know what interest rate to use, apply it...
lastbank = bank #To calculate interest...
bank += (bank * rate) #Update earnings...
interest = bank - lastbank #And figure out how much interest is made!
i += 1 #So we can see which year a calculation represents
print("Year %s, at %s rate: %s paid, %s in bank." % (i, rate,
interest, bank))

now it checks to make sure the account is positive before moving on,
efficiency in getting the rate

Marc 'BlackJack' Rintsch
Guest
Posts: n/a

 12-12-2008
On Fri, 12 Dec 2008 04:58:36 -0800, feba wrote:

> Actually, I have gedit set to four spaces per tab. I have no reason why
> it's showing up that large on copy/paste, but the file itself is fine.

The file contains one tab character per indentation level and it depends
on the software you use to look at the text how many spaces will be
displayed. Better use four real spaces to indent one level so it looks
the same everywhere.

Ciao,
Marc 'BlackJack' Rintsch

Tim Rowe
Guest
Posts: n/a

 12-12-2008
Since we all seem to be having a go, here's my take. By pulling the
rates and thresholds into a dictionary I feel I'm getting a step
closer to the real world, where these would presumably be pulled in
from a database and the number of interest bands might vary. But is
there a tidier way to get 'thresholds'? I was a bit surprised that
rates.keys() didn't give me a list directly, so although the 3.0
tutorial says "The keys() method of a dictionary object returns a list
of all the keys used in the dictionary, in arbitrary order (if you
want it sorted, just apply the sort() method to )" that's not /quite/
such a given, because "the list of keys" doesn't seem to be there for
the sorting any more.

Is there a tidy way of making rates and thresholds local to get_rate,
without recalculating each time? I suppose going object oriented is
the proper way.

#Py3k,UTF-8

rates = {0: 0.006, 10000: 0.0085, 25000: 0.0124, 50000: 0.0149, 100000: 0.0173}
thresholds = list(rates.keys())
thresholds.sort()
thresholds.reverse()

def get_rate(balance):
for threshold in thresholds:
if balance >= threshold:
return rates[threshold]
else:
return 0.0

balance = int(input("How much money is in your account?\n>>"))
target = int(input("How much money would you like to earn each year?\n>>"))

if balance <= 0:
print("You'll never make your fortune that way!\n")
else:
interest = 0
year = 0
while interest < target:
rate = get_rate(balance)
interest = balance * rate
balance += interest
year += 1
print("Year %s, at %s rate: %s paid, %s in bank." % (year,
rate, interest, balance))

--
Tim Rowe