i'm trying to make a program that calculates simple interest and the function i made to calculate the interest returns 0 when i run it and i don't know what the problem is
`year = int(input("Enter years: "))
month = int(input("Enter months: "))
days = int(input("Enter days: "))
totalYears = float()
interest = float()
def get_time():
totalYears = round(year (month * 31 days)/365,1)
print("total time in years is",totalYears,"years")
principal = float(input("Enter principal: "))
rate = float(input("Enter rate (in %): "))
def simple_interest():
interest = round(principal * rate/100 * totalYears,2)
print("Total interest earned is $",interest)
get_time()
simple_interest()`
i tried intializing the principal and rate at the start even though i know it's unnecessary since it's intialized when i ask for the input, i assume the problem is with the variables but i can't find it if it is.
CodePudding user response:
The variable TotalYears
in the get_time
function is not the same as the variable TotalYears
referenced outside the function. When you want to assign a value to TotalYears in get_time, you need to declare "Global" to let python know that you are referencing the variable outside the scope of the get_time function.
year = int(input("Enter years: "))
month = int(input("Enter months: "))
days = int(input("Enter days: "))
totalYears = float()
interest = float()
principal = float(input("Enter principal: "))
rate = float(input("Enter rate (in %): "))
def get_time():
global totalYears
totalYears = round(year (month * 31 days)/365,1)
print("total time in years is",totalYears,"years")
def simple_interest():
interest = round(principal * (rate/100) * totalYears,2)
print("Total interest earned is $",interest)
get_time()
simple_interest()
CodePudding user response:
When you initialise totalYears
as float()
, it gets defined in the global variable scope. When you then define totalYears
by calling the function get_time()
, that version of totalYears
gets defined inside the scope of the get_time()
function call. When that function call ends, the value of totalYears
is extinguished - and never gets returned for use by any other function.
So the version of totalYears
that's available to your next function call - simple_interest
is 0.0
- the original version you initialised in the global scope, not the version you defined in the scope of get_time()
.
If you want totalYears to be defined inside get_time()
, and then be available for use by simple_interest()
, I would suggest something like this:
year = int(input("Enter years: "))
month = int(input("Enter months: "))
days = int(input("Enter days: "))
totalYears = float()
interest = float()
def get_time():
totalYears = round(year (month * 31 days)/365,1)
print("total time in years is",totalYears,"years")
return totalYears
principal = float(input("Enter principal: "))
rate = float(input("Enter rate (in %): "))
def simple_interest(totalYears):
interest = principal * rate/100 * totalYears
print(f'Total interest earned is ${round(interest, 2)}')
totalYears = get_time()
simple_interest(totalYears)
If I call run your script with 5 years, 3 months, 2 days, $1000 in principal and a rate of 2%, I get the following output:
Enter years: 5
Enter months: 3
Enter days: 2
Enter principal: 1000
Enter rate (in %): 2
total time in years is 5.3 years
Total interest earned is $106.0
That addresses your immediate question - but a couple of points to note:
First: You don't have to define totalYears and interest as empty floats. You could delete totalYears = float()
and interest = float()
from your script and make no difference to how it runs.
Second: It's a lot easier to manage/analyse/debug your code if you try to keep your functions pure - with inputs and outputs passed into and returned from those functions. An example of how your code might be refactored to reflect this approach below:
def get_inputs():
year = int(input("Enter years: "))
month = int(input("Enter months: "))
days = int(input("Enter days: "))
principal = float(input("Enter principal: "))
rate = float(input("Enter rate (in %): "))
return year, month, days, principal, rate
get_inputs
gets inputs from the user and returns these inputs as five clearly named variables. This function is not "pure" - i.e. it interacts with other things (i.e. the user).
def get_time(year, month, days):
totalYears = round(year (month * 31 days)/365,1)
return totalYears
def simple_interest(principal, rate, totalYears):
interest = principal * rate/100 * totalYears
return interest
get_time
and simple_interest
are pure - in that their behaviour depends ONLY on the inputs provided to them - they have no "side effects", they don't print anything to the screen, they don't modify anything outside the scope of the function call. Their behaviour is entirely predictable and stable.
def print_outputs(totalYears, interest):
print(f'total time in years is {totalYears} years')
print(f'Total interest earned is ${round(interest, 2)}')
print_outputs
like get_inputs
is not pure - but it IS predictable - it takes in two inputs, and the resulting behaviour is an always predictable, repeatable output to the screen. It doesn't mutate any variables not explicitly passed to it.
We then call these functions:
year, month, days, principal, rate = get_inputs()
totalYears = get_time(year, month, days)
interest = simple_interest(principal, rate, totalYears)
print_outputs(totalYears, interest)
This produces exactly the same behaviour as before, but this approach makes very clear what variables are being passed into and out of various function calls, without creating any "globally" accessible variables whose names/meanings could become ambiguous. There are of course ways to define global variables in Python, but personally, I tend to run scared of doing that if at all avoidable.
CodePudding user response:
The problem is that get_time()
is not updating the value of your global totalYears
since you're not returning it. And simple_interest()
won't update interest
for the same reason.
You can check this by printing totalYears
inside simple_interest()
:
def simple_interest():
interest = round(principal * rate/100 * totalYears,2)
#This should return 0:
print(totalYears)
print("Total interest earned is $",interest)
One easy way is just returning totalYears
and interest
:
def get_time():
totalYears = round(year (month * 31 days)/365,1)
print("total time in years is",totalYears,"years")
return totalYears
def simple_interest():
interest = round(principal * rate/100 * totalYears,2)
print("Total interest earned is $",interest)
return interest
year = int(input("Enter years: "))
month = int(input("Enter months: "))
days = int(input("Enter days: "))
principal = float(input("Enter principal: "))
rate = float(input("Enter rate (in %): "))
totalYears = get_time()
interest = simple_interest()
I hope this helps :)