I'm trying to solve a problem but I've been working on it for so long and have tried so many things but I'm really new to python and don't know how to get the input I'm after.
The calculator needs to be in a format of a nested loop. First it should ask for the number of weeks for which rainfall should be calculated. The outer loop will iterate once for each week. The inner loop will iterate seven times, once for each day of the week. Each itteration of the inner loop should ask the user to enter number of mm of rain for that day. Followed by calculations for total rainfall, average for each week and average per day.
The main trouble I'm having is getting the input of how many weeks there are and the days of the week to iterate in the program eg:
Enter the amount of rain (in mm) for Friday of week 1: 5
Enter the amount of rain (in mm) for Saturday of week 1: 6
Enter the amount of rain (in mm) for Sunday of week 1: 7
Enter the amount of rain (in mm) for Monday of week 2: 7
Enter the amount of rain (in mm) for Tuesday of week 2: 6
This is the type out output I want but so far I have no idea how to get it to do what I want. I think I need to use a dictionary but I'm not sure how to do that. This is my code thus far:
ALL_DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
total_rainfall = 0
total_weeks = 0
rainfall = {}
# Get the number of weeks.
while True:
try:
total_weeks = int(input("Enter the number of weeks for which rainfall should be calculated: "))
except ValueError:
print("Number of weeks must be an integer.")
continue
if total_weeks < 1:
print("Number of weeks must be at least 1")
continue
else:
# age was successfully parsed and we're happy with its value.
# we're ready to exit the loop!
break
for total_rainfall in range(total_weeks):
for mm in ALL_DAYS:
mm = int(input("Enter the amount of rain (in mm) for ", ALL_DAYS, "of week ", range(total_weeks), ": "))
if mm != int():
print("Amount of rain must be an integer")
elif mm < 0 :
print("Amount of rain must be non-negative")
# Calculate totals.
total_rainfall =+ mm
average_weekly = total_rainfall / total_weeks
average_daily = total_rainfall / (total_weeks*7)
# Display results.
print ("Total rainfall: ", total_rainfall, " mm ")
print("Average rainfall per week: ", average_weekly, " mm ")
print("Average rainfall per week: ", average_daily, " mm ")
if __name__=="__main__":
__main__()
If you can steer me in the right direction I will be so appreciative!
Recommendation: Break the problem into smaller pieces. Best way to do that would be with individual functions.
For example, getting the number of weeks
def get_weeks():
total_weeks = 0
while True:
try:
total_weeks = int(input("Enter the number of weeks for which rainfall should be calculated: "))
if total_weeks < 1:
print("Number of weeks must be at least 1")
else:
break
except ValueError:
print("Number of weeks must be an integer.")
return total_weeks
Then, getting the mm input for a certain week number and day. (Here is where your expected output exists)
def get_mm(week_num, day):
mm = 0
while True:
try:
mm = int(input("Enter the amount of rain (in mm) for {0} of week {1}: ".format(day, week_num)))
if mm < 0:
print("Amount of rain must be non-negative")
else:
break
except ValueError:
print("Amount of rain must be an integer")
return mm
Two functions to calculate the average. First for a list, the second for a list of lists.
# Accepts one week of rainfall
def avg_weekly_rainfall(weekly_rainfall):
if len(weekly_rainfall) == 0:
return 0
return sum(weekly_rainfall) / len(weekly_rainfall)
# Accepts several weeks of rainfall: [[1, 2, 3], [4, 5, 6], ...]
def avg_total_rainfall(weeks):
avgs = [ avg_weekly_rainfall(w) for w in weeks ]
return avg_weekly_rainfall( avgs )
Using those, you can build your weeks of rainfall into their own list.
# Build several weeks of rainfall
def get_weekly_rainfall():
total_weeks = get_weeks()
total_rainfall = []
for week_num in range(total_weeks):
weekly_rainfall = [0]*7
total_rainfall.append(weekly_rainfall)
for i, day in enumerate(ALL_DAYS):
weekly_rainfall[i] += get_mm(week_num+1, day)
return total_rainfall
Then, you can write a function that accepts that "master list", and prints out some results.
# Print the output of weeks of rainfall
def print_results(total_rainfall):
total_weeks = len(total_rainfall)
print("Weeks of rainfall", total_rainfall)
for week_num in range(total_weeks):
avg = avg_weekly_rainfall( total_rainfall[week_num] )
print("Average rainfall for week {0}: {1}".format(week_num+1, avg))
print("Total average rainfall:", avg_total_rainfall(total_rainfall))
And, finally, just two lines to run the full script.
weekly_rainfall = get_weekly_rainfall()
print_results(weekly_rainfall)
I use a list to store average rallfall for each week.
and my loop is:
1.while loop ---> week (using i to count)
2.in while loop: initialize week_sum=0, then use for loop to ask rainfall of 7 days.
3.Exit for loop ,average the rainfall, and append to the list weekaverage.
4.add week_sum to the total rainfall, and i+=1 to next week
weekaverage=[]
i = 0 #use to count week
while i<total_weeks:
week_sum = 0.
print "---------------------------------------------------------------------"
for x in ALL_DAYS:
string = "Enter the amount of rain (in mm) for %s of week #%i : " %(x,i+1)
mm = float(input(string))
week_sum += mm
weekaverage.append(weeksum/7.)
total_rainfall+=week_sum
print "---------------------------------------------------------------------"
i+=1
print "Total rainfall: %.3f" %(total_rainfall)
print "Day average is %.3f mm" %(total_rainfall/total_weeks/7.)
a = 0
for x in weekaverage:
print "Average for week %s is %.3f mm" %(a,x)
a+=1
Related
I have to be able to calculate the revenu per month depending on the number of goats sold per month knowing that every month I sell 20% of the goats I had initially in January. When I try to calculate it through my price_list I can only get 400$ and not the 300$ for the corresponding months.
The variable d is there to know whether or not the month starts with a vowel. If it does d= "d'" and if not d="de".
I have been going at it for a week and can't seem to find a solution for neither of my two problems.
Help would be really appreciated !!!
goats=int(input("Enter the number of goats at the beginning of january :"))
year= ["january","february","march","april","may","june","july","august","september","october","november","december"]
vowels = "aeiouy"
price_list = [400,400,400,400,300,300,300,300,300,300,400,400]
d=""
if goats >0:
for month in range(len(year)):
goats_left = int(goats*0.8)
goats_sold = goats - goats_left
goats = goats_left
print("At the of the month of {0} {1} , we will have {2} goats left, monthly revenu: {3} $".format(d,year[month],goats,price_list[i]))
else:
print("The number entered is not valid {0}.format(goats))
goats=int(input("Enter the number of goats at the beginning of january :"))
print("\n")
print("ANNUAL REVENUE ........................................................ :".format())
print(goats_sold_list)
My first suggestion would be to use enumerate as a more pythonic way to iterate over your list and get it's index. I also don't understand your use of d anywhere so perhaps clarify how you intended it to be used.
Finally, l don't see i or goats_sold_list declared anywhere.
This should be a starting point for improvement:
goats = int(input("Enter the number of goats at the beginning of january :"))
year = ["january","february","march","april","may","june","july","august","september","october","november","december"]
vowels = "aeiou"
price_list = [400,400,400,400,300,300,300,300,300,300,400,400]
d=""
goats_sold_list = []
if goats >0:
for index, month in enumerate(year):
#int() always rounds down, i.e 0.8 goes to 0
goats_left = int(goats*0.8)
goats_sold = goats - goats_left
goats = goats_left
goats_sold_list.append(goats_sold)
print("At the of the month of {0} {1} , we will have {2} goats left, monthly revenu: {3} $".format(d,month,goats,price_list[index]))
else:
print("The number entered is not valid {0}.format(goats)")
goats=int(input("Enter the number of goats at the beginning of january :"))
print("\n")
print("ANNUAL REVENUE ........................................................ :".format())
print(goats_sold_list)
I don't see a definition for [i] in price_list[i], barring some outside definition, I think that should be price_list[month].
I don't see d being set at any point, you might need to have some line of code setting d to some value based on the first letter of the month.
I am trying to make a sales calculator that shows different things such as what was the maximum sale for the week and which day was it, what was the minimum sale for the week and which day was it, what is the total amount of sales of all days added together, average sales for the week, and a sales commission of 0$ for less than 100$ made, 25$ for sales between $100 and 250$, 30$ for sales between $250 and $500, and 40$ for sales over 500$.
I've tried different ways of calculating the average but can't get it to work and i'm not sure how to work in the sales commission as well as linking the min and max to the day of the week they occur on.
This is what I currently:
print ("Sales Calculator Program")
print ('\n')
expenses = []
for day_number in range (1, 5 + 1):
while True:
user_input = float(input(f"Enter sales for day {day_number}\n> "))
if user_input >= 0:
expenses.append(user_input)
break
else:
print(f"Amount may not be negative. Try again:")
print ('\n')
average = average(expenses)
finalExpenses = sum(expenses)
print ("Total weekly sales were $" +str(finalExpenses))
print ("Average of the sales is $" +str(average))
This is what i'm trying to get it to look like:
Enter sales for day 1: 10.22 (User input)
Enter sales for day 2: 4.12 (User input)
Enter sales for day 3: 3.78 (User input)
Enter sales for day 4: 6.82 (User input)
Enter sales for day 5: 22.45 (User input)
Maximum sales was on Friday which is $22.45
Minimum sales was on Wednesday which is $3.78
Total weekly sales were $47.39
Average of the sales is $9.48
Sales too low for commission must earn more than $100
Thank you!
print ("Sales Calculator Program")
print ('\n')
expenses = []
for day_number in range (1, 5 + 1):
while True:
user_input = float(input(f"Enter sales for day {day_number}\n> "))
if user_input >= 0:
expenses.append((day_number,user_input))
break
else:
print(f"Amount may not be negative. Try again:")
print ('\n')
max = max(expenses, key=lambda x: x[1])
min = min(expenses, key=lambda x: x[1])
total = sum(map(lambda x: int(x[1]), expenses))
average = total/len(expenses)
for item in expenses :
if item[0] == 1:
Monday ...
For the rest you should try urself now you can use max min sum etc ... try to know more about some builtin functions before you ask here :))
You can do it like this.
print ("Sales Calculator Program")
print ('\n')
expenses = []
for day in range(1, 6):
while True:
sales = float(input(f"Enter sales for day {day}\n> "))
if sales >= 0:
expenses.append((sales, day))
break
else:
print(f"Amount may not be negative. Try again:")
print ('\n')
days = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
maxval = max(expenses, key=lambda x: x[0]) # could also use operator.itemgetter
minval = min(expenses, key=lambda x: x[0])
total = sum(e[0] for e in expenses)
average = total / len(expenses)
print('Maximum sales was on %s which is $%.2f' % (days[maxval[1]], maxval[0]))
print('Minimum sales was on %s which is $%.2f' % (days[minval[1]], minval[0]))
print ("Total weekly sales were $%.2f" % total)
print ("Average of the sales is $%.2f" % (average))
if total < 100.0:
print('Sales too low for commission must earn more than $100')
Store the daily value with the day index in a tuple. You can then use max or min with a key function to pick out element 0 as the one to use in the calculation of max/min. When you come to print it the second element in the tuple can be used to index into the days array to get the day name.
The calculation of the mean average should be pretty self explanatory.
Note that floating point numbers are not suitable for storing monetary values in any application that needs to be correct. Instead store values in cent/pence or use decimal.
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()
I am trying to write a program that uses nested loops to collect data and calculate the average rainfall over a period of years. The program should ask the number of years. The outer loop will iterate once for each year. The inner loop will iterate twelve times, once for each month. Each iteration of the inner loop will ask the user for the number of inches of rainfall for that month.
After all iterations, the program should display the nubmer of months, the total inches of rainfall and the average rainfall per month for the entire period.
years = int(input('How many years do you want to track? '))
months = 12
for years_rain in range(years):
total= 0.0
print('\nYear number', years_rain + 1)
print('------------------------------')
for month in range(months):
print('How many inches for month ', month + 1, end='')
rain = int(input(' did it rain? '))
total += rain
number_months = years * months
average = total / number_months
print('The total inches of rain was ', format(total, '.2f'),'.')
print('The number of months measured was', number_months)
print('The average rainfall was', format(average, '.2f'), 'inches')
The logic for this program is off. It is basing the average rainfall off the last year's total rainfall, not all of the years' rainfall totals.
Where am I going wrong in the logic of this program?
With properly formatted code, you'll notice that you do:
for years_rain in range(years):
total= 0.0
print('\nYear number', years_rain + 1)
...
Which resets the total to zero each iteration of your year loop. Change it instead to:
total = 0.0
for years_rain in range(years):
print('\nYear number', years_rain + 1)
...
Your total value is being reset so you need a way to keep track of the grandTotal. Here's one way to do this:
years = int(input('How many years do you want to track? '))
months = 12
grandTotal = 0.0 // will store TOTAL rainfall
for years_rain in range(years):
total= 0.0
print('\nYear number', years_rain + 1)
print('------------------------------')
for month in range(months):
print('How many inches for month ', month + 1, end='')
rain = int(input(' did it rain? '))
total += rain
grandTotal += total // add total to the grandTotal
number_months = years * months
average = grandTotal / number_months
print('The total inches of rain was ', format(average, '.2f'),'.')
print('The number of months measured was', number_months)
print('The average rainfall was', format(average, '.2f'), 'inches')
I'm trying to get the user to input a birth date and then add the individual ints in those numbers. Also, if a sum of any of these digits is greater than or equal to 10, the loop repeats and the process runs again for the value. Here's my code so far
if (sumYear >= 10):
sumYear2=0
for num in str(sumYear):
sumYear2 += int(num)
print(sumYear2)
This works however I think it would be better done as a loop. And if there's some way I won't have to use something like sumYear2 that would be great. Note, I don't think I can use the sum() function.
Thanks guys for the help. I'm having an issue though. I'm not sure why this code isn't being evaluated when I provide the month as 02 and the day as 30
while True:
year=input("Please enter the year you were born: ")
month=input("Please enter the month you were born: ")
day=input("Please enter the day you were born: ")
if(int(month)==2 and int(day)<=29):
break
elif(int(month)==1 or 3 or 5 or 7 or 8 or 10 or 12 and int(day)<=31 ):
break
elif(int(month)==4 or 6 or 9 or 11 and int(day)<=30):
break
else:
print("Please enter a valid input")
Too much work.
singledigitsum = (int(inputvalue) - 1) % 9 + 1
Note that this will fail for numbers less than 1.
#Ignacio Vazquez-Abrams's answer provides the formula. But if there were none then your code as a loop without using sumYear2 could look like:
while sumYear >= 10:
sumYear = sum(map(int, str(sumYear)))
If you're not allowed to use sum (a homework) then:
while sumYear >= 10:
s = 0
for d in str(sumYear):
s += int(d)
sumYear = s
For the second question assuming Python 3:
while True:
try:
year = int(input("Please enter the year you were born: "))
month = int(input("Please enter the month you were born: "))
day = int(input("Please enter the day you were born: "))
birthday = datetime.date(year, month, day)
except ValueError as e:
print("error: %s" % (e,))
else:
break
If you are not allowed to use try/except then:
year = get_int("Please enter the year you were born: ",
datetime.MINYEAR, datetime.MAXYEAR)
month = get_int("Please enter the month you were born: ",
1, 12)
day = get_int("Please enter the day you were born: ",
1, number_of_days_in_month(year, month))
birthday = datetime.date(year, month, day)
Where get_int():
def get_int(prompt, minvalue, maxvalue):
"""Get an integer from user."""
while True:
s = input(prompt)
if s.strip().isdigit():
v = int(s)
if minvalue <= v <= maxvalue:
return v
print("error: the input is not an integer in range [%d, %d]" % (
minvalue, maxvalue))
And number_of_days_in_month():
# number of days in a month disregarding leap years
ndays = [0]*13
ndays[1::2] = [31]*len(ndays[1::2]) # odd months
ndays[::2] = [30]*len(ndays[::2]) # even months
ndays[2] = 28 # February
ndays[8] = 31 # August
# fill other months here ...
def number_of_days_in_month(year, month):
return ndays[month] + (month == 2 and isleap(year))
You can do this
>>> d=123456
>>> sum(int(c) for c in str(d))
21