Leap-year program in Python - python

I'm having a very hard time troubleshooting my code. All I'm trying to do is have the user enter in a starting and an ending year, and then be able to calculate all the leap years in between. I'm still very new to Python, and just can't figure out why my while loop isn't doing what I want it to do.
starting = int(raw_input('Enter starting year: '))
ending = int(raw_input('Enter ending year: '))
print 'Leap years between', starting, 'and', ending
while starting <= ending:
if starting % 4 == 0 and starting % 100 != 0:
print starting
if starting % 100 == 0 and starting % 400 == 0:
print starting
starting = starting + 1
That is what I have right now. I really would prefer not to have the answer just given to me, but if I could get a little hint as to why my while loop isn't working I would really appreciate it.
This is the output I see in my IDE:

The code is working just fine. This was the following session:
Enter starting year: 2008
Enter ending year: 2032
Leap years between 2008 and 2032
2008
2012
2016
2020
2024
2028
2032
That corresponds perfectly with the information give here.
Console session:
>>> from leapyear import leap
>>> leap()
Enter starting year: >? 2008
Enter ending year: >? 2032
Leap years between 2008 and 2032
2008
2012
2016
2020
2024
2028
2032
leapyear.py
def leap():
starting = int(raw_input('Enter starting year: '))
ending = int(raw_input('Enter ending year: '))
print 'Leap years between', starting, 'and', ending
while starting <= ending:
if starting % 4 == 0 and starting % 100 != 0:
print(starting)
if starting % 100 == 0 and starting % 400 == 0:
print(starting)
starting += 1
You can also do this function using list comprehensions:
def new_leap(start, end):
return [x for x in xrange(start, end + 1)
if (x % 400 == 0) or (x % 4 == 0 and not x % 100 == 0)]
Console session:
>>> from leapyear import new_leap
>>> new_leap(2008, 2032)
[2008, 2012, 2016, 2020, 2024, 2028, 2032]

I think this will contain all the Test Case
We have added all the invalid cases in value=c
and just matched and removed the value from b
def is_leap(year):
leap = False
leap1=True
b=[]
for a in range(1800,year+200,4):
b.append(a)
c=[1800,1900,2100,2200,2300,2500,2600,2700,2800,2900]
for d in range(len(c)):
e=c[d]
if e in b:
b.remove(e)
if year in b:
return leap1
else:
return leap
year = int(input())
print(is_leap(year))

def is_leap(year):
leap = False
if year%4 ==0 :
leap = True
elif year%100 ==0:
leap = False
elif year%400 ==0:
leap = True
return leap
year = int(raw_input())
print is_leap(year)

startingYear = eval(input("Enter starting year:")
endingYear = eval(input("Enter ending year:")
for year in range(startingYear, endingYear + 1):
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
print(year)

Related

How to make a loop that validates the user-input dates based on the functions created?

I am not using any datetime module. I created my own functions to calculate the day, month, and year. I want to calculate the refunds based on the date. If the date is invalid, it should ask the user to try again until a date is true.
year = 0
month = 0
day = 0
money_owed = 0
def if_leap_year(year):
if (year % 400 == 0): return 366
elif (year % 100 == 0): return 365
elif (year % 4 == 0): return 366
else:
return 365
#print(if_leap_year(year))
def days_in_month(month, year):
if month in {1, 3, 5, 7, 8, 10, 12}:
return 31
if month == 2:
if if_leap_year(year):
return 29
return 28
return 30
#print(days_in_month(month, year))
def is_valid_date(year, month, day):
if days_in_month(month, year)<day:#checks if the given day is possible
given the month
return False
else:
return True
def days_left_in_year(month, day, year):
daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]
daysLeft = (if_leap_year(year) if month < 3 else 365) -
sum(daysInMonth[:month - 1]) - day
return daysLeft
def refund_period():
month = int(input("Enter the month of the year: "))
day = int(input("Enter the day of the year: "))
year = int(input("Enter the year to determine the number of days: "))
if is_valid_date(year , month , day):
money_owed = (days_left_in_year(month, day, year) /
if_leap_year(year)) * 278
return round(money_owed, 2)
else:
print("Your date is invalid, try again.")
while is_valid_date(year, month, day):
print('you will be refunded','$', + refund_period())
break
else:
print("Your date is invalid, try again.")
I am getting:
you will be refunded $ -8.38
even though the calculation shouldn't be performed since the date is invalid
You are setting year =0 , month =0, day = 0 in first loop.
Also the while is not clear. All your functions return an int so never validate if the date is correct.
Maybe you can create a function to validate the date something like this :
def is_valid_date(year , month , day):
if month <1 or month >12: #Validate a allowed month
return False
if day <1 or day > days_in_month(month, year): # validate an allowed day for the month
return False
return True
and you can change this function :
def refund_period():
month = int(input("Enter the month of the year: "))
day = int(input("Enter the day of the year: "))
year = int(input("Enter the year to determine the number of days: "))
if is_valid_date(year , month , day):
money_owed = (days_left_in_year(month, day, year) / if_leap_year(year)) * 278
return round(money_owed, 2)
else :
print("Your date is invalid, try again.")
Just a couple of comments:
You are getting the year, month, and day using input() so you don't need to create global variables for that.
you don't need to ask if if_leap_year(year) == 365 or 366 because this function returns 365 or 366 so you can use it directly when you calculate the money_owned, as I do.
Also you can use if_leap_year(year) instead
(if_leap_year(year) if month < 3 else 365) . That functions return 366 or 365, you dont need to validate again.
And you can use list comprehension for you daysInMonth variable inside days_left_in_year function :
daysInMonth = [days_in_month(m, year) for m in range(1,13)]
Your while loop is not comparing the function value but just checking if the object exists. Instead of conditions like while days_left_in_year(month, day, year), use conditions like while days_left_in_year(month, day, year)<30 (assuming you wanted to deny refunds on orders older than 30 days.
To validate dates, add the following function under your comment #print(days_in_month(month, year)):
def is_valid_date(year, month, day)
if days_in_month(month, year)<day:#checks if the given day is possible given the month
return False
else:
return True
then your condition should look something like this:
if ((is_valid_date(year, month, day) == True) and (month<13)):
print('you will be refunded','$', + refund_period())
else:
print("Your date is invalid, try again.")

why my If statment dont work with or in my Case -python date validation from automate the boringstuff with python [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 1 year ago.
import re
ausgabe =[]
Datum = re.compile(r"([0-2][1-9]|[3][0|1])(\/)([0-1][0-9])(\/)([0-2][0-9]{3})") #filter
Daten =(" 31/12/2000 blub 31.02.2000 und 32/01/2099 blub 28/02/2000 29/09/2009 29/39/2009 ") #Datenstr
ausgabe =Datum.findall(Daten) #durchsuchen
month = None
day = None
year = None
for Datum in ausgabe:
allright = True
day = int(Datum[0])
month =int(Datum[2])
year = int(Datum[4])
# print(day + "/" + month + "/" + year + "\n", end="")
if month == 4 or 6 or 11: #if the month is 4, 6,11
print(month)
if day > 30: #check the days of the month
allright= False
elif month == 2:
if day > 28:
print("feb hat nur 28 tage")
allright = False
elif day > 31:
print("größer als 31")
allright = False
if allright == True:
print(str(day) + "/" + str(month) + "/" + str(year) + "\n", end="")
Problem is in the following line.
The month is 12 and it jumps into the next if statement inside and checks this
but also if isnt 4 6 and 11. This is out of automate the boring stuff with python.
i just started coding some weeks ago so maybee its super easy to see...
i rewatched some videos and thougth about it but i dont understand this
if month == 4 or 6 or 11: #if the month is 4, 6,11
print(month)
if day > 30: #check the days of the month
allright= False
Instead of
if month == 4 or 6 or 11: #if the month is 4, 6,11
you should use
if month == 4 or month == 6 or month == 11: #if the month is 4, 6,11
The
if month == 4 or 6 or 11:
Is interpreted by Python as
if (month == 4) or (6) or (11):
while 6 and 11 are positive integers interpreted by Python as True
As described here

How to change the index,without giving wrong output?

So im trying to change the index and output the values as numbers.
this is my code:
import datetime
year = int(input('Enter the year (4 digits):\n'))
month = int(input('Enter the month (1-12)')
DayL = ['Mon','Tues','Wednes','Thurs','Fri','Satur','Sun']
date = DayL[datetime.date(year,month,1).weekday()] + 'day'
print(date)
Sample Output:
Enter the year (4 digits):
> 2020
Enter the month (1 - 12):
> 1
Wednesday
Im trying to get the output as a index, and it should start at Sunday (Sunday = 0), but still give the correct answer. How do i go about this ?
The output i want:
Enter the year (4 digits):
> 2020
Enter the month (1 - 12):
> 1
3
There’s no reason to use DayL.
The date.weekday function already gives you the numeric weekday using Monday=0.
To map that to a Sunday=0 system, just add 1 mod 7:
weekday = (datetime.date(year,month,1).weekday() + 1) % 7
Try to use this:
>>> (datetime.datetime( 2020, 1, 1).weekday() + 1) % 7
3
>>>

How can I more effectively find the (n)th monthly occurrence of a given weekday?

For example if I want Saturday, starting with Oct 01, 2019, I need the result to return the monthly occurrence of the last Saturday (09/28/2019); in this case, 4.
This code gives me the desired result but I'd like to find a cleaner way (preferably only using datetime module):
def seq_of_sat():
newday = today
#gets the last Saturday
while newday.weekday() !=5:
newday -= timedelta(days=1)
if (newday.day > 28):
return 5
elif (newday.day > 21):
return 4
elif (newday.day > 14):
return 3
elif (newday.day > 7):
return 2
else: return 1
Edit:Solution
shift = (newday.weekday() + 2) % 7
newday -= timedelta(days=shift)
return (int(newday.day) + 6) // 7

Python: logic error in calculating a year (leap)

So I this code which is suppose to return a list with the closest leap year of a list of years.
For example: calling the function with [1995 1750 2018] should return
1996 1748 2016
Which it does for that set of numbers.
The problem I am having is that when a leap year is in the input for example 2008 it does not give me back the closest leap year to 2008. I get back 2008.
Any suggestions as to how I can modify the code to make it work?
code
def is_leap(year):
leap = False
if year % 4 == 0:
if year % 100 != 0 or year % 400 == 0:
leap = True
return leap
major_b = []
major_f = []
newLst = []
def year_forward(yearBounds):
for item in yearBounds:
counter = 0
while not is_leap(item):
item = item + 1
counter += 1
major_f.append([item, counter])
return major_f
def year_backward(yearBounds):
for item in yearBounds:
counter = 0
while not is_leap(item):
item = item - 1
counter -= 1
major_b.append([item,counter])
return major_b
def findLastLeapYears(yearBounds):
forward = year_forward(yearBounds)
backward = year_backward(yearBounds)
counter = 0
for item in forward:
if abs(item[1]) < abs(backward[counter][1]):
newLst.append (str(item[0]))
counter+=1
elif abs(item[1]) == abs(backward[counter][1]):
if item[0] < backward[counter][0]:
newLst.append (str(item[0]))
counter += 1
else:
newLst.append (str(backward[counter][0]))
counter += 1
else:
newLst.append (str(backward[counter][0]))
counter+=1
return newLst
I'd avoid trying to roll your own leap year detection code. Use calendar.isleap to determine whether a year is a leap year or not.
Then go in a loop, like this:
import calendar
def find_nearest_leap(year):
offset = 1
while True:
if calendar.isleap(year - offset):
return year - offset
if calendar.isleap(year + offset):
return year + offset
offset += 1
To find the list of nearest leap years for a list of values, do this:
nearest_leap_years = [find_nearest_leap(year) for year in years]
Where years is the list of years you are interested in.
I'm also assuming the nearest leap year isn't the year itself, which seems to be a constraint of the problem...

Categories

Resources