This question already has answers here:
Why does this python method gives an error saying global name not defined?
(3 answers)
Closed 4 years ago.
below is my code (all the methods are indented in original), after running that code I get this error:
NameError: global name 'checkDate' is not defined
the method are defined so i don't know whats the issue here (the code was in Java and work well there I just did the modification for this to work in python)
class Date:
def __init__(self, *args):
if len(args) == 3:
self._day, self._month, self._year = args
elif len(args) == 1:
self._day = args[0]._day
self._month = args[0]._month
self._year = args[0]._year
else:
raise TypeError("wrong number of arguments to Date constructor")
# methods
# checkDate - Check if the date is valid
def checkDate (self, day, month, year):
if year > 0 and month > 0 and month < 13 and day > 0 and day < 32:
if month == 1 or 3 or 5 or 7 or 8 or 10 or 12: return True
if month == 4 or 6 or 9 or 11:
if day == 31: return False
return True
if month == 2:
if (month % 4 == 0 and (month % 100 != 0 or (month % 100 == 0 and month % 400 == 0))):
if day > 28: return False
elif day > 27: return False
return False
# calculateDate - Computes the day number since the beginning of the Christian counting of years.
def calculateDate (self, day, month, year):
if month < 3:
year -= 1
month = month + 12
return 365 * year + year/4 - year/100 + year/400 + ((month+1) * 306)/10 + (day - 62);
# getDay - Return the day
def getDay(self): return self._day
# getMonth - Return the month
def getMonth(self): return self._month
# getYear - Return the year
def getYear(self): return self._year
# setDay - Sets the day (only if date remains valid)
def setDay(self, dayToSet):
if checkDate(dayToSet,_month,_year): _day = dayToSet
# setMonth - Sets the month (only if date remains valid)
def setMonth (self, monthToSet):
if checkDate(_day,monthToSet,_year): _month = monthToSet
# setYear - sets the year (only if date remains valid)
def setYear(self, yearToSet):
if checkDate(_day,_month,yearToSet): _year = yearToSet
def main():
birthDate = Date(1,1,2000)
print(birthDate.getDay())
print(birthDate.getMonth())
print(birthDate.getYear())
birthDate.setDay(8)
birthDate.setMonth(8)
birthDate.setYear(1987)
print(birthDate.getDay())
print(birthDate.getMonth())
print(birthDate.getYear())
if __name__ == "__main__": main()
You need to do self.checkDate() since checkDate is a method of your Date class.
Additionally, in setDay(), setMonth() and setYear() the variables being assigned to (_day, _month, and _year respectively) need a self. before them as well.
Related
I've implemented a date class, which calculates the next day's date and the previous day's date.
eg. if today is 3/26/2022 (MM/DD/YYYY) then my method nextday gives 3/27/2022.
However, instead of returning a string, I am trying to return an instance but it's not working properly. It's calculating the day correctly but changes the original instance.
This is my class:
class Date:
"""
Assigning class arguments
"""
min_year = 1800
dow_jan1 = "Wednesday"
def __init__(self,month=1,day=1,year=min_year):
"""
Assigning instance arguments and checking the validity of dates.
If Not valid then an Exception is raised.
"""
self.c_month = month
self.c_day = day
self.c_year = year
if self.c_year < self.min_year:
raise Exception("Invalid Year")
elif self.c_month <1 or self.c_month > 12:
raise Exception("Invalid Month")
elif self.c_day<1 or self.c_day > 31:
raise Exception("Invalid Day")
else:
if self.c_month == 2:
if self.year_is_leap(self.c_year):
if self.c_day<1 or self.c_day > 29:
raise Exception("Invalid Day")
else:
if self.c_day<1 or self.c_day > 28:
raise Exception("Invalid Day")
else:
months_31_days = [1,3,5,7,8,10,12]
if self.c_month in months_31_days:
if self.c_day<1 or self.c_day > 31:
raise Exception("Invalid Day")
else:
if self.c_day<1 or self.c_day > 30:
raise Exception("Invalid Day")
def year_is_leap(self,year=None):
"""
Finds if a year is Leap or not
Parameters:
year : takes a year which is to be checked
however if a year is not provided then the instance argument year (self.c_year)
is set as default value
"""
if year is None:
year = self.c_year
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return True
else:
return False
else:
return True
else:
return False
def __str__(self):
"""
returns the date in suitable format
eg. 2/14/1900 => February 14, 1900
"""
months = {1:"January",2:"February",3:"March",4:"April",
5:"May",6:"June",7:"July",8:"August",9:"September",
10:"October",11:"November",12:"December"}
return "{} {}, {}".format(months[self.c_month],self.c_day,self.c_year)
def nextday(self):
"""
Returns next date in date object
"""
leap_year = self.year_is_leap(self.c_year)
#print(leap_year)
if self.c_month in (1, 3, 5, 7, 8, 10, 12):
month_length = 31
elif self.c_month == 2:
if leap_year:
month_length = 29
else:
month_length = 28
else:
month_length = 30
if self.c_day < month_length:
self.c_day += 1
else:
self.c_day = 1
if self.c_month == 12:
self.c_month = 1
self.c_year += 1
else:
self.c_month += 1
print("The next date is [mm-dd-yyyy] %d-%d-%d." % (self.c_month, self.c_day,self.c_year))
return self #Date(self.c_month,self.c_day,self.c_year) #Date #self.__class__()
```
I've tried to return `self`, `Date()`, `Date(self.c_month,self.c_day,self.c_year)` and `self.__class__()`, however none of it worked.
When I run:
firstdate = Date(1,1,Date.min_year)
print(firstdate)
print("The date after ", firstdate, "is", firstdate.nextday())
I am getting the output:
January 1, 1800
The next date is [mm-dd-yyyy] 1-2-1800.
The date after January 2, 1800 is January 2, 1800
The most straightforward solution will be creating a new instance of Date with same values as self (basically copy it) and work with it, not changing self:
class Date:
# other methods here
def nextday(self):
"""
Returns next date in date object
"""
new_date = Date(self.c_month, self.c_day, self.c_year)
is_leap_year = new_date.year_is_leap(new_date.c_year)
if new_date.c_month in {1, 3, 5, 7, 8, 10, 12}:
month_length = 31
elif new_date.c_month == 2:
month_length = 28 + is_leap_year
else:
month_length = 30
if new_date.c_day < month_length:
new_date.c_day += 1
else:
new_date.c_day = 1
if new_date.c_month == 12:
new_date.c_month = 1
new_date.c_year += 1
else:
new_date.c_month += 1
print("The next date is [mm-dd-yyyy] %d-%d-%d." % (new_date.c_month, new_date.c_day,new_date.c_year))
return new_date
You could also implement some convenience methods (e.g. .copy to copy the date or __format__ to print the date, but that's out of question scope)
The problem is that you change the object attributes. For example on nextday method, you write self.c_day += 1, you are changing the object itself.
Instead, if you want to return a new Date, you need to write c_day += 1 then return Date(c_month, c_day, c_year)
I am counting number of days between two dates.For first testcase output is wrong 10108
expected output 10109
In first test case 1 day is missing in output
from typing import*
class Solution:
def daysBetweenDates(self, date1: str, date2: str) -> int:
d1 = self.days(int(date1[:4]),int(date1[5:7]),int(date1[8:]))
d2 = self.days(int(date2[:4]),int(date2[5:7]),int(date2[8:]))
return abs(d2-d1)
def isLeap (self, N):
if N % 400 == 0:
return True
if N % 100 == 0:
return False
if N % 4 != 0:
return False
return True
def days(self, year,month,rem_days):
months_list = [31,28,31,30,31,30,31,31,30,31,30,31]
days_count = 0
for i in range(1971,2101):
if year > i:
if self.isLeap(i):
days_count += 366
else:
days_count += 365
else:
break
if self.isLeap(year) and month > 2:
days_count += 1
for j in range(1,month):
if month > j:
days_count += months_list[j]
return days_count + rem_days
vals = Solution()
print(vals.daysBetweenDates("2010-09-12","1983-01-08"))
print(vals.daysBetweenDates("2019-06-29", "2019-06-30"))
print(vals.daysBetweenDates("2020-01-15", "2019-12-31"))
The month starts at one, you get the number of days for each month from the wrong index (1 for January when the correct index is 0...). Subtract one when you look up the days for each month
for j in range(1, month):
days_count += months_list[j - 1]
I have an assignment in my computer science class and need help fixing a function but I have no clue what's wrong! The function is called 'days_left'. This function takes in three variables, Day, Month, and Year. It is supposed to output how many total days are left in that year. I have tried my best but cannot figure it out! Any help will be greatly appreciated. Here's the script:
def leap_year(year):
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return True
else:
return False
else:
return True
else:
return False
def number_of_days(month, year):
days31 = [1, 3, 5, 7, 8, 10, 12]
days30 = [4, 6, 9, 11]
if month in days31:
return 31
elif month in days30:
return 30
else:
if not leap_year(year):
return 28
else:
return 29
def days_left(month, day, year):
days = 0
for i in range(1, month):
days += number_of_days(i, year)
days += day
for x in range(year):
if leap_year(year):
return 366 - days
else:
return 365 - days
if __name__ == '__main__':
print("Please enter a date: \n")
d = int(input("Day: "))
m = int(input("Month: "))
y = int(input("Year: "))
print("\nMenu:")
print("1) Calculate the number of days in the given month.")
print("2) Calculate the number of days left in the given year.")
selection = int(input())
if selection == 1:
print(number_of_days(m, y))
elif selection == 2:
print(days_left(d, m, y))
else:
print('')
def days_left(day, month, year):
It should be 'day, month' instead 'month, day' since you are calling function with days_left(d, m, y)
This is my first question here so please forgive and educate on any formatting errors. I am new to Python and going through automate the boring stuff. Decided to expand the date detection project by using the clipboard and formatting some things also. The problem I have is in any operation taken on the year part of the REGEX.
I have commented out my last attempt to validate the year and gave up and changed the REGEX to only find dates from 1000 to 2999 and skipped code validation of the dates.
I now need to validate leap years but I'm back to having to work with the year variable, but once again no operation has any effect.
Basically the problem is I can extract the year value and display it but I cannot modify it or do checks against it.
#! python3
#! detect dates in a block of text
import pyperclip
import re
#!import numpy as np
text = str(pyperclip.paste())
def datedetection(text):
dateRegex = re.compile(
r"""(
(\d|\d\d) #! match day
(/{1}) #! match /
(\d|\d\d) #! match month
(/{1}) #! match /
([1|2][0-9][0-9][0-9]) #! match year
)""",
re.VERBOSE,
)
matches = []
for groups in dateRegex.findall(text):
day = str(groups[1])
slash1 = str(groups[2])
month = str(groups[3])
slash2 = str(groups[4])
year = str(groups[5])
month_range_30 = ["04", "06", "09", "11"]
month_range_31 = ["01", "03", "05", "07", "08", "10", "12"]
month_range_Feb = ["02"]
#!year_range = np.arange(1000, 3000, 1).tolist()
if len(day) == 1:
day = "0" + day
else:
day = day
if len(month) == 1:
month = "0" + month
else:
month = month
if month in month_range_31:
if int(day) > 31:
day = "Too many days in a month with only 31 days."
slash1 = month = slash2 = year = ""
elif month in month_range_30:
if int(day) > 30:
day = "Too many days in a month with only 30 days."
slash1 = month = slash2 = year = ""
elif month in month_range_Feb:
if int(day) > 29:
day = "Too many days in February."
slash1 = month = slash2 = year = ""
elif int(month) > 12:
day = "Found an invalid month."
slash1 = month = slash2 = year = ""
elif month in month_range_Feb:
if (
int(day) == 29
and (int(year) % 4 == 0)
and (int(year) % 400 == 0)
and (int(year) % 100 == 0)
):
day = day
elif month in month_range_Feb:
if (
int(day) == 29
and (int(year) % 4 == 0)
and (int(year) % 100 != 0)
):
day = "Found an invalid leap year."
slash1 = month = slash2 = year = ""
#!elif year not in year_range:
#!day = "Year is out of range."
#!slash1 = month = slash2 = year = ""
dates = "".join([day, slash1, month, slash2, year])
matches.append(dates)
if len(matches) > 0:
pyperclip.copy("\n".join(matches))
print("Copied to clipboard:")
print("\n".join(matches))
else:
print("No dates found.")
datedetection(text)
In my approach to this project, I considered validating the days, months, and year ranges as part of the regular expression. I then defined functions to check for the leap year, and validate the number of days according to the months.
I found that way simpler and easier to understand and follow. As below:
dateRegex = re.compile(r'([0-3][0-9])/([0-1][0-9])/([1-2][0-9]{3})')
def is_leap_year(year):
year = int(year)
if year % 4 == 0:
if year % 100 == 0:
return year % 400 == 0
else:
return True
else:
return False
def is_valid_date(day, month, year):
if month == '02':
if is_leap_year(year):
return int(day) <= 29
else:
return int(day) <= 28
elif month in ['04', '06', '09', '11']:
return int(day) <= 30
else:
return int(day) <= 31
You can find the rest of my code below.
https://gist.github.com/alialbusaidi/f56e4c9342f622434f8bff0549f94884
The problem was the operations before the year operations. The day and month operations were overwriting the year values. Not entirely sure how or why at this point, but moving the year code above the day and month code has started to fix the issue.
I cannot for the life of me solve this challenge on Hackerrank. The closest I got it was to 4/6 passes.
Rules:
In the Gregorian calendar three criteria must be taken into account to identify leap years:
The year can be evenly divided by 4, is a leap year, unless:
The year can be evenly divided by 100, it is NOT a leap year, unless:
The year is also evenly divisible by 400. Then it is a leap year.
Code:
def is_leap(year):
leap = False
# Write your logic here
if year%400==0 :
leap = True
elif year%4 == 0 and year%100 != 0:
leap = True
return leap
year = int(input())
print(is_leap(year))
You forgot the ==0 or !=0 which will help understand the conditions better. You don't have to use them, but then it can cause confusion maintaining the code.
def is_leap(year):
leap = False
if (year % 4 == 0) and (year % 100 != 0):
# Note that in your code the condition will be true if it is not..
leap = True
elif (year % 100 == 0) and (year % 400 != 0):
leap = False
elif (year % 400 == 0):
# For some reason here you had False twice
leap = True
else:
leap = False
return leap
a shorter version would be:
def is_leap(year):
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
You can try this
def is_leap():
leap = False
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
leap = True
return leap
This code might be easy for some of the people to wrap their head around
def is_leap(year):
leap = False
# Write your logic here
if year%4==0:
leap=True
if year%100==0:
leap=False
if year%400==0:
leap=True
return leap
year = int(input())
print(is_leap(year))
If we split the question point by point.
Actual question:
The year can be evenly divided by 4, is a leap year, unless:
The year can be evenly divided by 100, it is NOT a leap year, unless:
The year is also evenly divisible by 400. Then it is a leap year.
Explaining it : If a year is divided by 4, then its a leap year.
If this is divided by 100 but not 400 after being divisible by 4,
then its not a leap year.
If this is divisible by 4, 100 ,400 , then its a leap year.
Basically, nested if
if(year % 4 == 0):
if(year % 100 == 0):
if(year % 400 == 0):
leap =True
else:
leap=False
else:
leap=True
else:
leap=False
return leap
def is_leap(year):
leap=False
check =lambda year : year :year%4==0 and (year%400==0 or year%100!=0)
leap=check(year)
return leap
year =int(input())
print(is_leap(year))
def is_leap(year):
leap = False
if year%4 == 0:
if(year%100 != 0 or year%400 == 0):
leap = True
return leap
def is_leap(year):
leap = False
# Write your logic here
if year % 4 == 0 and year % 100 != 0:
leap = True
elif year % 100 == 0 and year % 400 != 0:
leap = False
elif year % 400 == 0:
leap = True
elif year % 4 != 0:
leap = False
return leap
year = int(raw_input())
print is_leap(year)
def is_leap(year):
leap = False
if(year%4==0):
#century year check
if(year%100==0):
#century leap year check
if(year%400==0):
leap=True
else:
leap=True
return leap
if year%4==0 and year%100==0 and year%400==0:
return True
elif year%4==0 and year%100!=0 and year%400!=0:
return True
else:
return False
n = [int(input("Enter a year in four digit: "))]
a = list(map(lambda x: "is a Leap year" if x%4 == 0 or ( x % 100 != 0 or x % 400 == 0) else "is not a Leap year" , n))
print(f"{n[0]} {a[0]}")
def is_leap(year):
leap = False
if year % 4 == 0 and year % 100 != 0:
leap = True
elif year % 400 == 0 and year % 100 == 0:
leap = True
return leap
I just try with this:
def is_leap(year):
leap = False
# Write your logic here
if (year%4 ==0 and year%100 !=0) or year%400 ==0:
leap = True
else:
leap = False
return leap
year = int(input())
print(is_leap(year))
if year can be evenly divided by 4 and 400 is True but if it can be evenly divided by 100 is False
#simplest solution for beginner
n = int(input('Enter year to check if it is leap year.'))
if n % 4 == 0 and n%100 != 0:
leap = 'True'
elif n % 100 == 0 and n%400==0:
leap = 'True'
else:
leap = 'False'
print('the entered year is,'+leap)
This would be my solution for the problem. We want the number to be divisible with 4 no matter what. So year % 4 will need to be true for the output to be bool True as well. Then we have to consider if the number which is divisible with 4 can be divided to 400. If the number is divisible to 100 but not 400 it should give us bool False. That is why we should check divisibility to 400 and non-divisibility to 100 together and use or statement.
def is_leap(year):
leap = False
if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
return not leap
else:
return leap
year = int(input())
print(is_leap(year))
def is_leap(year):
leap = False
# Write your logic here
if (year%4 ==0):
if (year%100 == 0) and (year%400 ==0):
leap = True
elif(year%100 == 0) and (year%400 !=0):
leap = False
else:
leap = True
else:
leap = False
return leap
year = int(input())
HackerRank Problem - An extra day is added to the calendar almost every four years as February 29, and the day is called a leap day. It corrects the calendar for the fact that our planet takes approximately 365.25 days to orbit the sun. A leap year contains a leap day.
In the Gregorian calendar, three conditions are used to identify leap years:
The year can be evenly divided by 4, is a leap year, unless:
The year can be evenly divided by 100, it is NOT a leap year, unless:
The year is also evenly divisible by 400. Then it is a leap years.
Solution is the below Python Code.
def is_leap(year):
leap = False
# Write your logic here
if (year % 4 == 0) and (year % 100 != 0):
# Note that in your code the condition will be true if it is not..
leap = True
elif (year % 100 == 0) and (year % 400 != 0):
leap = False
elif (year % 400 == 0):
# For some reason here you had False twice
leap = True
else:
leap = False
return leap
year = int(input())
print(is_leap(year))
Try this #Charles Thompson, this passed all test cases for me.
def is_leap(year):
leap = False
if year%4 == 0:
if year%100 == 0:
if year%400 == 0:
leap = True
else:
leap = False
else:
leap = True
return leap
def is_leap(year):
leap = False
if year % 4 == 0 and year % 100 == 0 and year % 400 == 0:
return True
elif year %4 == 0 and year % 100! = 0 and year % 400!= 0:
return True
else:
return False
year = int(raw_input())
print is_leap(year)
def is_leap(year):
leap = False
# Write your logic here
if year%4==0:
leap= True
if year%100 ==0 and year%400==0:
leap = True
if (year%100 == 0) and (year%400 != 0):
leap = False
return leap
year = int(input())
print(is_leap(year))
def is_leap(year):
leap = False
d4 = year%4
d100 = year%100
d400 = year%400
if d4 == 0 :
if d100 != 0 or d400 == 0 :
leap = True
else :
leap = False
return leap
year = int(input())
print(is_leap(year))