I don't know how to triple the amount.
1st month's payment 1 dollar.
2nd month's payment 2 dollars. (doubled the amount)
3rd month's payment 6 dollars. (triple it every other months)
4th month's payment 12 dollars. (double the amount)
5th month's payment 36 dollars. (triple it every other month)
6th month's payment 72 dollars. (double the amount)
7th month's payment 216 dollars. (triple it every other month)
and so on ...
I'm using the for and if statements.
base = 1
payments = int(input("For how many months did they say you will receive payments? "))
for i in range(0, payments):
if i % 2 > 0:
base *= 3
else:
base *= 2
month = "Month " + str(i + 1) + ":" + str(base)
print(month)
for month 1 I get $2 and I expect to get $1
You could use modulus operator and on every odd entry, triple the amount.
base = 1
payments = 5
print("Month 1: %s" % base)
for i in range(2, payments):
if i % 2 == 1:
base *= 3
else:
base *= 2
print("Month %s: %s" % (i+1, base))
You can use a list of numbers to be multiplied for (2 and 3), while the installments are less than the input. The logic is to alternate between the two numbers of the list, while the condition is true:
base = 1
payments = input("For how many months did they say you will receive payments? ")
x = 1
multiplyList = [2, 3]
print(f'Month {x}: $ {base}')
while x <= int(payments):
i = 0
for number in multiplyList:
base = (base * multiplyList[i])
print(f'Month {x}: $ {base}')
i = i + 1
x = x + 1
# output:
# Month 1: $ 1
# Month 1: $ 2
# Month 2: $ 6
# Month 3: $ 12
# Month 4: $ 36
# Month 5: $ 72
# Month 6: $ 216
# Month 7: $ 432
# Month 8: $ 1296
# Month 9: $ 2592
# Month 10: $ 7776
EDIT: OP has edited the question to incorporate new attempts and
change the problem statement, so this is out of date.
As mentioned in other answers, your approach has a few drawbacks which make it non-ideal as a solution.
That being said, here is where the code went wrong:
Starting with a condensed version of your original:
base = 1
payments = 10
for i in range(payments):
month = "Month " + str(i + 1) + ":" + str(base)
base *= 2
if i in range(2, payments, 3):
base *= 3
print(month)
you need to end up here:
base = 1
payments = 10
for i in range(payments):
month = "Month " + str(i + 1) + ":" + str(base)
if i in range(1, payments, 3):
base *= 3
else:
base *= 2
print(month)
The changes needed are:
Using range(2, ...) instead of range(1, ...). This is because the way that you print and calculate you end up determining the new base during the previous month.
Moving *= 2 into an else: statement so you don't multiply by 6
This works:
base = 1
payments = int(input("For how many months did they say you will receive payments? "))
month = "Month " + str(1) + ":" + str(base)
print(month)
for i in range(1, payments):
if i % 2 > 0:
base *= 2
else:
base *= 3
month = "Month " + str(i + 1) + ":" + str(base)
print(month)
Because you were enetering straight into the for loop, it meant that you were doubling the first month. However if you print the first amount before the loop, start the loop at two, and swap the modulo statements around, it works.
This solution has only one print() statement to print month and amount, but it has an if == 0 in the loop
you could get rid of the if statement within the loop but had to add one more print line before the loop.
if you don't want to print intermediate results then you can start the range from 1, get ird of the if i == 0 and print the result after having left the for loop.
base = 1
payments = int(input("For how many months did they say you will receive payments? "))
print(base)
for i in range(0, payments):
if i == 0:
pass
elif i % 2 > 0:
base *= 2
else:
base *= 3
msg = "Month " + str(i + 1) + ":" + str(base)
print(msg)
Related
I have to write a program which asks the user to type in a limit. The program then calculates the sum of consecutive numbers (1 + 2 + 3 + ...) until the sum is at least equal to the limit set by the user.
In addition to the result it should also print out the calculation performed. I should do this with only a while loop, no lists or True conditionals.
limit = int(input("Limit:"))
base = 0
num = 0
calc = " "
while base < limit:
base += num
num += 1
calc += f" + {num}"
print(base)
print(f"The consecutive sum: {calc} = {base}")
So for example, if the input is 10, the output should be 10 and underneath that should be "The consecutive sum: 1 + 2 + 3 + 4 = 10." If the input is 18, the output should be 21 and underneath that should be "The consecutive sum: 1 + 2 + 3 + 4 + 5 + 6 = 21."
Right now I can get it to print the final result (base) and have gotten it to print out the calculation, but it prints out one integer too many. If the input is 10, it prints out 1 + 2 + 3 + 4 + 5 when it should stop before the 5.
I would avoid the while loop and use range instead. You can derive the value of the last term with arithmetic.
If the last term is π, then the sum will be π(π+1)/2, which must be less or equal to the input limit. Resolving this equation to π given the limit, we get that the π is ββ(1 + 8β
limit) β 1) / 2β
So then the program can be:
limit = int(input("Limit:"))
n = int(((1 + 8 * limit) ** 0.5 - 1) / 2)
formula = " + ".join(map(str, range(1, n + 1)))
total = n * (n + 1) // 2
print(f"The consecutive sum: {formula} = {total}")
One way that came to my mind is concatenating values for each iteration:
limit = int(input("Limit:"))
base = 0
num = 1
num_total = 0
calculation = 'The consecutive sum: '
while base < limit:
calculation += f"{num} + "
base += num
num += 1
print(f"{calculation[:-3]} = {base}")
print(base)
#> Limit:18
## The consecutive sum: 1 + 2 + 3 + 4 + 5 + 6 = 21
## 21
The other way is printing value on each iteration without new line in the end (but you have additional + sign in the end here):
limit = int(input("Limit:"))
base = 0
num = 1
num_total = 0
print('The consecutive sum: ', end='')
while base < limit:
print(f"{num} + ", end='')
base += num
num += 1
print(f"= {base}")
print(base)
#> Limit:18
## The consecutive sum: 1 + 2 + 3 + 4 + 5 + 6 + = 21
## 21
There's probably a more efficient way to write this but this was what came to mind...
sum = 0
long_output = []
for i in range(limit + 1):
sum += i
long_output.append(str(i))
print("The consecutive sum: {} = {}".format(' + '.join(long_output), sum))
Keep putting stuff in an list and then join them afterwards. i has to be casted to a str type since join is just for strings
NOTE: the output starts at 0 to account for limit being potentially 0 (I don't know what your constraints are, if any)
EDIT: made updates based on #Copperfield's recommendation
You are/were very close. Try rearranging the follow of execution in your while statements. I also find this assignment hard. Try moving you calc line as the first statement after your 'while'.
One other way is to add an if statement:
if base< num :
calc += f" + {num}"
Here is a example to print the calculation
limit = int(input("Limit:"))
base = 0
num = 1
num_total = 0
msg = ""
while base < limit:
msg = msg + str(num) + "+"
base += num
num += 1
msg = msg[:-1] + "=" + str(limit)
print(msg)
if limit = 21 then the output would be
1+2+3+4+5+6=21
I want to round off to the nearest half hour meaning that If I arrive at 11:15 and leave 11:50, car will still be charged for one half an hour not two. I have tried for the last couple of hours to fix it but I cant seem to know what to do (I recently started learning programming)
import math
PARKING_COST = 1.75
TAX_RATE = 1.13
startHour = eval(input('Input the hour when you entered the parking lot(in 24h time please, no leading zeroes):'))
startMinute = input('Input the minute when you entered the parking lot: ')
endHour = eval(input('Input the hour when you exited the parking lot(in 24h time please, no leading zeroes): '))
endMinute = input('Input the hour when you exited the parking lot: ')
minutesPassed = (60*endHour + int(endMinute))-(60*startHour + int(startMinute))
k=1
if minutesPassed<=(15*k):
k+=1
halfHoursPassed=math.floor(float(minutesPassed)/30)
else:
halfHoursPassed=math.ceil(float(minutesPassed)/30)
subtotal = halfHoursPassed * 1.75
total = subtotal * 1.13
print('*******')
print('Parkinglot')
print('Your time in was',str(startHour)+':'+ startMinute)
print('Your time out was',str(endHour)+':'+ endMinute)
print('You spent','%.0f' %halfHoursPassed,'half hours at our garages')
print('Your subtotal was $' + '%.2f' %subtotal)
print('Your total was $' + '%.2f' %total)
print('Thank you for your stay')
print('*******')
So with full_halves = int(minutesPassed / 30) you can get the "full" 30 minute periods. Then using modulo operator % you get the remainer: remaining = minutesPassed % 30. Now, if this remainer is greater than 15, you should add another full half, otherwise you use the full_halves as is.
The modulo operator % gives back the remainder after floor division //. That is to say that 7 // 3 == 2, 7 % 3 == 1. Indeed these two are mutually defined such that (x // k) * k + (x % k) == x.
You should consider taking the modulo of your minutesPassed and 30 to see where the partial-half-hour lies, then comparing that with 15 to judge whether or not to round up or down.
halfHoursPassed = minutesPassed // 30
if minutesPassed % 30 >= 15:
halfHoursPassed += 1
You can somewhat simplify this by using the builtin divmod, which gives both // and % at once.
halfHoursPassed, partialHalfHour = divmod(minutesPassed, 30)
if partialHalfHour >= 15:
halfHoursPassed += 1
Context: Continuing with my self-learn of Python, I recently completed a textbook exercise that asked for a program that allowed the user to define 'x' number of years and to be able to input, for every month in 'x', a value for rainfall.
Issue: Below is my code, which works 'ok', however the latest exercise demands I 'expand' my code to present the numerically largest and smallest user input rainfall value, in a print statement.
Disclosure: I have looked on S.O to try finding the solution to my question, but nothing seems to be close enough to my challenge, to help me.
What I've tried: I have tried using max() and min() however I keep getting a TypeError: 'int' object is not iterable when I type the code print(max(monthlyRainfall) or print(min(monthlyRainfall)
def yearsToTrack():
userYearsTracking = int(input("How many years do you want to track: "))
return userYearsTracking
def calculationAlgorithm(userYearsTracking):
totalMonths = 0
totalRainfall = 0
for currentYear in range (1, userYearsTracking +1):
for currentMonth in range (1, 13):
monthlyRainfall = int(input("Inches of rainfall for month " + format(currentMonth, "d",) + " | year " +
format(currentYear, "d",)+": "))
totalMonths += 1
totalRainfall += monthlyRainfall
averageRainfall = totalRainfall / totalMonths
print("Total months: " + str(totalMonths))
print("Total rain:", format(totalRainfall), "(inch)")
print("Total average rainfall:", round(averageRainfall,2), "(inch)")
def main():
userYearsTracking = yearsToTrack()
calculationAlgorithm(userYearsTracking)
main()
Is anyone able to offer some 'pointers' as to where I am going wrong?
You can use sys.maxsize and 0 to intilize variables for tracking the minimum and maximum rainfall values that realistically the user will never enter above above or below respectively.
However for the second case just to make sure you can also add a simple check to ensure the user does not enter a negative rainfall amount:
def calculationAlgorithm(userYearsTracking):
totalMonths = 0
totalRainfall = 0
maxRainfall = 0
minRainfall = sys.maxsize
for currentYear in range (1, userYearsTracking +1):
for currentMonth in range (1, 13):
monthlyRainfall = int(input("Inches of rainfall for month " + format(currentMonth, "d",) + " | year " +
format(currentYear, "d",)+": "))
if monthlyRainfall < 0:
print("Error invalid rainfall entered")
sys.exit()
if monthlyRainfall > maxRainfall:
maxRainfall = monthlyRainfall
if monthlyRainfall < minRainfall:
minRainfall = monthlyRainfall
totalMonths += 1
totalRainfall += monthlyRainfall
averageRainfall = totalRainfall / totalMonths
print("Total months: " + str(totalMonths))
print("Total rain:", format(totalRainfall), "(inch)")
print("Total average rainfall:", round(averageRainfall,2), "(inch)")
print("Largest input rainfall: " + str(maxRainfall))
print("Smallest input rainfall: " + str(minRainfall))
Try out the full program with above changes here.
Example Usage:
How many years do you want to track: 1
Inches of rainfall for month 1 | year 1: 2
Inches of rainfall for month 2 | year 1: 2
Inches of rainfall for month 3 | year 1: 2
Inches of rainfall for month 4 | year 1: 2
Inches of rainfall for month 5 | year 1: 4
Inches of rainfall for month 6 | year 1: 1
Inches of rainfall for month 7 | year 1: 2
Inches of rainfall for month 8 | year 1: 2
Inches of rainfall for month 9 | year 1: 2
Inches of rainfall for month 10 | year 1: 2
Inches of rainfall for month 11 | year 1: 2
Inches of rainfall for month 12 | year 1: 2
Total months: 12
Total rain: 25 (inch)
Total average rainfall: 2.08 (inch)
Largest input rainfall: 4
Smallest input rainfall: 1
N.B. I have only used camelCase in naming the new variables as that is the style you are using. I would recommend changing all the names of the variables in your program to snake_case as that is the convention in python.
Python's built-in min() and max() functions expect iterable object like list, set, etc. I think you are putting only one integer which is not so correct (how can you pick min or max number when only 1 number given - obviously it is bot min and max).
One way of doing this would be:
declare list var:
rainfallList = []
Then when you get monthlyRainfall, you should add this code:
rainfallList.append(monthlyRainfall)
After all for loops you can use min(rainfallList) and/or max(rainfallList)
So your final code should be:
def yearsToTrack():
userYearsTracking = int(input("How many years do you want to track: "))
return userYearsTracking
def calculationAlgorithm(userYearsTracking):
totalMonths = 0
totalRainfall = 0
rainfallList = []
for currentYear in range (1, userYearsTracking +1):
for currentMonth in range (1, 13):
monthlyRainfall = int(input("Inches of rainfall for month " + format(currentMonth, "d",) + " | year " +
format(currentYear, "d",)+": "))
totalMonths += 1
rainfallList.append(monthlyRainfall)
totalRainfall += monthlyRainfall
averageRainfall = totalRainfall / totalMonths
print("Total months: " + str(totalMonths))
print("Total rain:", format(totalRainfall), "(inch)")
print("Total average rainfall:", round(averageRainfall,2), "(inch)")
print("Min rain:", format(min(rainfallList)), "(inch)")
print("Max rain:", format(max(rainfallList)), "(inch)")
def main():
userYearsTracking = yearsToTrack()
calculationAlgorithm(userYearsTracking)
main()
Having an issue with a certain part of the code (I am new to coding and have tried looking through StackOverflow for help):
def totalRainfall (rainfall):
totalRain = 0
month = 0
while month < len(rainfall):
totalRain = rainfall[month] + totalRain
month += 1
return totalRain
TypeError: Can't convert 'int' object to str implicitly
I've tried multiple ways of changing the code to make it a string explicitly as it still giving me various issues.
I'm also having a hard time enhancing the code to sort the array in ascending order and displays the values it contains.
The full code is here:
def main ():
rainfall = rainInput ()
totalRain = totalRainfall (rainfall)
average_Rainfall = averageRainfall (totalRain)
highestMonth, highestMonthly = highestMonthNumber (rainfall)
lowestMonth, lowestMonthly = lowestMonthNumber (rainfall)
print #this is for spacing output
print ('The total rainfall for the year was: ' +str(totalRain) + ' inche(s)')
print #this is for spacing output
print ('The average rainfall for the year was: ' +str(average_Rainfall) +\
' inche(s)')
print #this is for spacing in output
print ('The highest amount of rain was', highestMonthly, 'in' , highestMonth)
print #this is for spacing in output
print ('The lowest amount of rain was', lowestMonthly, 'in' , lowestMonth)
def rainInput ():
rainfall = ['January','Febuary','March','April','May','June','July','August'\
,'September','October','November','December']
month = 0
while month < len(rainfall):
rainfall[month] = input ('Please enter the amount for month ' + str\
(month + 1) + ': ')
month += 1
return rainfall
def totalRainfall (rainfall):
totalRain = 0
month = 0
while month < len(rainfall):
totalRain = rainfall[month] + totalRain
month += 1
return totalRain
def averageRainfall (totalRain):
average_Rainfall = totalRain / 12
return average_Rainfall
def highestMonthNumber (rainfall):
month = ['January','Febuary','March','April','May','June','July','August'\
,'September','October','November','December']
highestMonthly = 0
for m, n in enumerate(rainfall):
if n > highestMonthly:
highestMonthly = n
highestMonth = m
return month[highestMonth], highestMonthly
def lowestMonthNumber (rainfall):
month = ['January','Febuary','March','April','May','June','July','August'\
,'September','October','November','December']
lowestMonthly = 0
for m, n in enumerate(rainfall):
if n < lowestMonthly:
lowestMonthly = n
lowestMonth = m
return month[lowestMonth], lowestMonthly
main()
You have stored strings in your array rainfall, you need to convert them to ints before adding.
def totalRainfall (rainfall):
totalRain = 0
month = 0
while month < len(rainfall):
totalRain = int(rainfall[month]) + totalRain
month += 1
return totalRain
If you want the total rainfall as the sum of the numbers per month, simply use sum() on the list of ints. But as your error suggests, you have a list of strings, which you explicitly have to convert.
Something along the lines of
def totalRainfall (rainfall):
return sum([int(x) for x in rainfall])
The problem with your list being strings will continue to be problematic for you, so as a quick fix, I suggest you change this line
rainfall[month] = input ('Please enter the amount for month ' + str\
(month + 1) + ': ')
to
rainfall[month] = int(input('Please enter the amount for month ' + str\
(month + 1) + ': '))
That way your list contains only numbers and all your other comparisons will work.
You should also add this initialization in your lowestMonthNumber function to avoid UnboundLocalError: local variable 'lowestMonth' referenced before assignment:
lowestMonth = 0
Notice, that by initializing lowestMonthly to 0, you will most likely never get a correct result, since it is highly unlikely that any month has less rainfall.
my problem is that the 'month' value increments once to month = 1, then stays there the whole time, causing an infinite loop. How do I get this to change every time through the loop? I know I'm probably missing something extremely simple.
def rem_bal(balance, annualInterestRate, monthlyInterestRate):
month = 0
while month <= 12:
monthly_interest = (annualInterestRate) / 12.0
minimum_monthly = (monthlyInterestRate) * balance
monthly_unpaid= (balance) - (minimum_monthly)
updated_balance = round(((monthly_unpaid) + (monthly_interest * monthly_unpaid)), 2)
month =+ 1
print("Month " + str(month) + "Remaining balance: " + str(updated_balance) + " .")
balance = updated_balance
return balance
month += 1
not
month = +1
which is just
month = 1
It needs to be month += 1 not month =+ 1; the latter is just plain assignment rather than incrementing the value of month (i.e., assigning month to +1/1).
BTW, this is not how you write a code in python.
Why parentheses around almost everything?
Why recalculate monthly_interest over and over, when it doesn't change?
Using a while loop for this isn't pythonic. You should rather use
for month in range(13):
month = month+1 - tried this works