count the number of days between two dates - python

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]

Related

Return a new instance from a class method

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)

Need assistance solving this issue in a function

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)

Python returns ints when one of variable inside function is active

The main idea is:
searchindex() - repeat binary search algorithm over the list of random data with looking back and with fix.(variable counter1 should save number of occurences)
occur() - just assumning total number of occurences.
Please help to find a problem.
I always get counter1 = 0 after running a code.
def searchindex(searchlist, secs, x):
ts = calendar.timegm(time.gmtime())
delta_minute_ts = (ts - (ts % 60)) - secs
last_minute = datetime.datetime.fromtimestamp(delta_minute_ts).strftime('%Y-%m-%d %H:%M')
start = 0
end = len(searchlist) - 1
counter1 = 0
while (start <= end):
mid = (start + end) // 2
if (searchlist[mid] == last_minute):
counter1 = int(mid)
if x == 1:
end = mid - 1
else:
start = mid + 1
elif (last_minute < searchlist[mid]):
end = mid - 1
else:
start = mid + 1
return counter1
def occur():
start_result = searchindex(new1, 60, 1)
end_result = searchindex(new1, 60, 2)
if start_result is None:
return 'no results'
else:
end_result - start_result + 1

Not defined method [duplicate]

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.

Fetch and validate date by reading char by char in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How do I read a date in MM-DD-YY format and validate as a real date?
I know it would be easier and more robust to handle it with the datetime module - but that's not what I want, so any solutions around using the the following code is appreciated:
dataType = MM-DD-YY
actualResult = 12-31-13
rIndex: counter variable for actualResult
rLen: length of actualResult
def compareDate (dataType, actualResult, rIndex, rLen):
dateString = ""
bhCount , result , count = 0 , 0 , 0
while (rIndex < rLen):
ch = actualResult[rIndex]
print ("Char %c" % ch)
dateString += str(ch)
if(ch >='0' and ch <= '9'):
count += 1
if(count == 2):
count = 0
bHyphen = False
elif(count > 2):
result = -1
break
elif(ch == "-"):
bhCount += 1
if((count == 0) and (bHyphen == False)):
bHyphen = True
else:
break
else:
break
rIndex += 1
#print dateString
return (result, rIndex)
What I am doing wrong? Any help will be appreciated.
class ValidationError(BaseException):
pass
class MyDate(object):
mounth = int()
day = int()
year = int()
_correct_mounth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def validate(self, day, mounth, year):
if not 1 <= mounth <= 12:
raise ValidationError, 'Invalid mounth!'
if year < 1:
raise ValidationError, 'Invalid year!'
if mounth == 2 and not year % 4:
if not 1 <= day <= 29:
raise ValidationError, 'Invalid day!'
else:
if not 1 <= day <= self._correct_mounth[mounth-1]:
raise ValidationError, 'Invalid day!'
return True
def __init__(self, date):
if not isinstance(date, basestring):
raise ValidationError, 'Not a string!'
date_parts = date.split('-')
if not isinstance(date_parts, list) or not len(date_parts) == 3:
raise ValidationError, 'Can`t change to list with 3 elements!'
for i in date_parts:
try:
int(i)
except TypeError:
raise ValidationError, 'Cannot convert to int!'
mounth = int(date_parts[0])
day = int(date_parts[1])
year = int(date_parts[2])
if self.validate(day, mounth, year):
self.mounth, self.day, self.year = mounth, day, year
dates = '12-31-13|08-23-12|10-10-13'
unchecked_dates = dates.split('|')
checked_dates = list()
for d in unchecked_dates:
try:
new_date = MyDate(d)
except ValidationError, e:
print '{0} is invalid date! {1}'.format(d, e)
else:
checked_dates.append(new_date)
if len(unchecked_dates) == len(checked_dates):
print 'All dates are correct.'
else:
print 'Correct dates: {0}'.format(checked_dates)
ANSWER
def compareDate (dataType, actualResult, rIndex, rLen):
hyphenCount , result , count = 0 , 0 , 0
dateString = ""
while (rIndex < rLen):
ch = actualResult[rIndex]
if (ch == '.'):
break
if(ch >= '0' and ch <= '9'):
hyphenCount = 0
count += 1
if(count > 2):
result = -1
print " d = "
break;
dateString += str(ch)
if(ch == '-'):
count = 0
hyphenCount += 1
if(hyphenCount > 1):
print " h = "
result = -1
break
#print ("Char %c" % ch)
rIndex += 1
print "dateString is = %s" % dateString
if result != -1:
msg = ""
mt = dateString[0] + dateString[1]
dt = dateString[2] + dateString[3]
yr = dateString[4] + dateString[5]
leap = '20'+yr
print mt, dt, yr
mt = int(mt)
dt = int(dt)
yr = int (yr)
leap = int(yr)
#create and call function which verify date
result,msg = verifyDate(mt,dt,yr,leap)
print msg
return (result, rIndex)
def verifyDate(mt,dt,yr,leap):
res = 0
msg = ""
leapyr = checkForLeapYear(leap)
if(yr >= 00 and yr <= 99):
if(leapyr): # for leap year
if(mt == 2):
if(dt >= 01 and dt <= 29):
res = 0
else:
msg = "should not exceed 29"
elif(mt == 1 or mt == 3 or mt == 5 or mt == 7 or mt == 8 or mt == 10 or mt == 12):
if(dt >= 01 and dt <= 31):
res = 0
else:
msg = "should not exceed 31"
res = -1
elif(mt == 4 or mt == 6 or mt == 9 or mt == 11):
if(dt >= 01 and dt <= 30):
res = 0
else:
msg = "should not exceed 30"
res = -1
else:
msg = "month should in btwn 01 to 12"
res = -1
# for leap year ...Ends Here
else:
if((mt >= 1) and (mt <= 12)):
if(mt == 2):
if(dt >= 01 and dt <= 28):
res = 0
else:
msg = "should not exceed 28"
res = -1
elif(mt == 1 or mt == 3 or mt == 5 or mt == 7 or mt == 8 or mt == 10 or mt == 12):
if(dt >= 01 and dt <= 31):
res = 0
else:
msg = "should not exceed 31"
res = -1
elif(mt == 4 or mt == 6 or mt == 9 or mt == 11):
if(dt >= 01 and dt <= 30):
res = 0
else:
msg = "should not exceed 30"
res = -1
else:
msg = "month should in btwn 01 to 12"
res = -1
else:
msg = "year should in btwn 00 to 99"
res = -1
return (res,msg)
def checkForLeapYear(yr):
if((yr %100) == 0 and (yr % 400 == 0 )):
return True
elif(yr%4 == 0):
return True
else:
return False
What else i can do with code to improve complexity and reduce lines of code.
Please answer with examples..

Categories