Regarding summation with a for loop - python

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

Related

when i run it through a VPL it passes 13/16 tests

year=int(input("Year: "))
while year<1583 or year>9999:
print("Out of allowed range 1583 to 9999")
year=int(input("Year: "))
leap_year=year%4==0 and (year%100 !=0 or year%400==0)
month=[1,12]
month=int(input("Month: "))
while month<1 or month >12:
print ("Out of allowed range 1 to 12")
month=int(input("Month: "))
day=int(input("Day: "))
if month==1 or month==2:
month+=12
year-=1
if month in [1,3,5,7,8,10,12]:
while day<1 or day> 31:
print("Out of allowed range 1 to 31")
day=int(input("Day: "))
if month in [4,6,9,11]:
while day<1 or day >30:
print("Out of allowed range 1 to 30")
day=int(input("Day: "))
if month==2:
if leap_year:
while day<1 or day>29:
print("Out of allowed range 1 to 29")
day=int(input("Day: "))
weekday = ( day + 13*(month+1)// 5 + year + year// 4- year//100+year// 400)% 7
if weekday==0:
print("It is a Saturday.")
elif weekday==1:
print("It is a Sunday.")
elif weekday==2:
print("It is a Monday.")
elif weekday==3:
print("It is a Tuesday.")
elif weekday==4:
print("It is a Wednesday.")
elif weekday==5:
print("It is a Thursday.")
elif weekday==6:
print("It is a Friday.")`
This is the code I wrote and when i run it through a VPL it passes 13/16 tests. The ones it does not pass is :
year: 1900 month:2 day: 29
year: 2018 month:1 day: 32
year: 2018 month:2 day: 32
I've been trying different things but I dont know what is wrong ie. how to correct it. Excuse the low skill level, I've been learning for a week only.
First problem is this code:
if month==1 or month==2:
month+=12
year-=1
If month is 1 or 2 then month becomes 13 or 14, then the next validation tests fail to detect the bad day of the month.
And next problem, this fails to check for condition day < 1 or day > 28 if leap_year = False as in case of 1900, month=2, day=29.
if month==2:
if leap_year:
while day<1 or day>29:
...
Can rewrite like this:
if month==2:
if leap_year:
max_day = 29
else:
max_day = 28
while day < 1 or day > max_day:
print(f"Out of allowed range 1 to {max_day}")
day=int(input("Day: "))

leap year python script

I am trying to write a code that will accept any of the months of the year and output the month entered plus a list of the days in the month. But if February is entered it should ask for the birth year and check if that is a leap year and output February plus the days in February.
Where did I go wrong?
month = input("Enter any month of the year: ")
for n in month:
if (n == "January" or
n == "March" or
n == "April" or
n == "May" or
n == "June" or
n == "July" or
n == "August" or
n == "September" or
n == "October" or
n == "November" or
n == "December"):
print (n + range(1, 32))
elif n == "February" :
year = input("Enter a year")
for i in year:
if i % 4 == 0:
print (year + range(1,29))
I will advise you to simply use the built-in calendar module
# Program to display calendar of the given month and year
# importing calendar module
import calendar
yy = 2014 # year
mm = 11 # month
# To take month and year input from the user
# yy = int(input("Enter year: "))
# mm = int(input("Enter month: "))
# display the calendar
print(calendar.month(yy, mm))
# output
# November 2014
#Mo Tu We Th Fr Sa Su
# 1 2
# 3 4 5 6 7 8 9
#10 11 12 13 14 15 16
#17 18 19 20 21 22 23
#24 25 26 27 28 29 30
Assuming your intent is to learn how to program (such as for a educational assignment), the following should help. If it's just to do the job, you should probably use some of the built-in Python modules (like datetime or calendar) since they'll do a lot of the hard work for you.
First, input returns a string and, when you iterate over a string (for n in month), you'll get one character at a time. So iterating over "May" will give you "M", "a", and "y", none of which are equal to "May". Don't iterate, just compare the entire string:
if month == "January" ...
Second, not all those months have 31 days, you'll need to distinguish those that have 30:
if month == "February":
doFebStuff()
elif month in ['September', 'April', 'June', 'November']:
do30DayStuff()
else:
do31DayStuff()
Third, you can't concatenate a string and a range, you'll need to do something like:
print(month, end='')
for i in range(1, 32):
print(f" {i}", end='')
print()
Fourth, again for the year, input gives you a string and you don't want to iterate over it. You also want to make it an integer if you're going to do mathematical calculations on it, something like:
year = int(input("Enter a year: "))
Fifth, the rules for leap years are slightly more complex than every four years, specifically:
if it's a multiple of 400, it's a leap year; else
if it's a multiple of 100, it's not; else
if it's a multiple of 4, it is; else
it's not.
Taking all that into account, here's one way to do it, with added checks for validity (month name and year):
Days30 = ["September", "April", "June", "November"]
Days31 = ["January", "March", "May", "July", "August", "October", "December"]
lastDay = None
month = input("Enter any month of the year: ")
if month == "February":
lastDay = 28
year = -1
while year < 0:
try:
year = int(input("Enter the year: "))
except:
year = -1
if year % 400 == 0 or (year % 100 != 0 and year % 4 == 0):
lastDay = 29
elif month in Days30:
lastDay = 30
elif month in Days31:
lastDay = 31
if lastDay is None:
print(f"I don't know the month {month}")
else:
print(f"{month}:", end="")
for day in range(1, lastDay + 1):
print(f" {day}", end="")
print()
I wouldn't try to pass that off as your own work (you'll almost certainly be pinged for plagiarism) but it's a good bit of code for getting some ideas.
If you are asking where did you go wrong, there are some places:
Your if and elif are not indented properly, they do not align.
When you write for n in month:, n takes value of every letter in the month inputed. e.g. if you entered "July", n would be iterating as "J", "u", "l", and "y". So comparing n to full names of months will always evaluate to False. Just compare the month instead of iterating over it.
When taking input, python stores the value entered by user as string (year = input("Enter a year")). So when you are iterating over the variable year (for i in year) you are iterating over a string of numbers and not the number. Furthermore, modulus operator won't work for strings (i % 4) as i in this case is a string. Just do year = int(input("Enter a year")) to convert year to ineger and do not iterate over it, check for remainder with 4 directly.
You can refer to the code by paxdiablo to get a working code.

Using max() and min() unsuccessfully in Python array

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()

Day of the week using Zeller's Congruence - Python 3

I just started studying Computer Science and I'm very new to python 3 and coding in general. Our first assignment is to calculate the day of the week using Zellers Congruence, and I have a few questions regarding the code that I have written.
year = int(input("Year: "))
while not int(year) in range(1583, 10000):
year = input("Out of allowed range 1583 - 9999. Please enter a valid
number: ")
month = int(input("Month: "))
while not int(month) in range(1, 13):
month = input("Out of allowed range 1 - 12. Please enter a valid number: ")
if month == 1 or month == 2:
month += 12
year -= 1
day = int(input("Day: "))
while not int(day) in range(1, 32):
day = input("Out of allowed range 1 - 31. Please enter a valid
number: ")
result = ( day + 13 * (month+1) // 5 + year + year // 4
- year// 100 + year // 400 ) % 7
weekday = {0: "Saturday",1: "Sunday", 2: "Monday",3: "Tuesday",4:
"Wednesday",5: "Thursday",6: "Friday"}
print("The day is " + weekday[int(result)] + ".")
First off, I'm supposed to make sure that the day range is related to the correct months. For example when the month input is 1, 3, 5, 7, 8, 10 or 12, the day interval should be 1 - 31. If the month input is 4, 6, 9, or 11 the day interval should be 1-30. And lastly I have to take leap years into account aswell. And I cant figure out how to write these requirements.
Also, all critique is welcome. I know that this is far from decent, so please let me know what I could do better!
Zeller's congruence handles the leap years correctly. If your problem is making sure the input date is a valid one, I believe the simplest approach will be creating a python datetime.date object using the user input.
import datetime
... # get user inputs
date = datetime.date(year, month, day)
If there is any invalid input, python will raise a meaningful exception. You don't need to do any validation yourself, just reading them as integers will be enough.

Python Rainfall Calculator

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

Categories