I am trying to use list comprehension and the power of the nested function to return a list of all Dates being Friday 13 within a given year in the form (dd/mm/yyyy). I am however having very little luck with nested loops, I would appreciate any assistance I could get with resolving this issue.
The previously created function to be used is seen as:
def day_of_week11(d, m, y):
# Write your code here
day_names =['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
if m < 3:
y -= 1
m += 12
m -= 2
yd = y % 100
yc = y // 100
day = (d + ((13*m-1)//5) + yd + yd//4 + yc//4 - 2*yc) % 7
day=(math.ceil(day))
if 2>day>=1:
return day_names[0]
elif 3>day>=2:
return day_names[1]
elif 4>day>=3:
return day_names[2]
elif 5>day>=4:
return day_names[3]
elif 6>day>=5:
return day_names[4]
elif 7>day>=6:
return day_names[5]
else:
return day_names[6]
#The function I am attempting to write now is:
def not_lucky (yr):
def day_of_week11(d, m, y):
# Write your code here
i=(d, m, y)
return len([i for i in range(12) if day_of_week11(d, m, y)(yr,i+1,13)==4])
from datetime import timedelta, date
given_year=2021
start_date = date(given_year, 1, 1)
end_date = date(given_year+1, 1, 1)
list_of_friday_the_thirteenth=[single_date.strftime("%d/%m/%Y") for single_date in (start_date + timedelta(n) for n in range((end_date-start_date).days)) if single_date.weekday()==4 and single_date.day==13 ]
print(list_of_friday_the_thirteenth)
List comprehension would be too complicated in this case.
Possible solution is following:
from datetime import date, timedelta
def thirteenth_fridays(year):
d = date(year, 1, 1)
if d.weekday() <= 4:
days = 4 - d.weekday()
else:
days = 11 - d.weekday()
d += timedelta(days)
while d.year == year:
if d.day == 13:
yield d.strftime("%d/%m/%Y")
d += timedelta(days = 7)
for d in thirteenth_fridays(2024):
print(d)
Prints
13/09/2024
13/12/2024
Related
I see java codes but can't fully compare them with python. I am trying to use the Zeller’s Congruence to find the day of the week for any date.
Zeller’s formula assumes that for each computation within the formula where there is a
quotient (or a division of two numbers), the integer value of that computation is used. If the month is January or February then 12 is added to the month and 1
subtracted from year before calculating day.
day = (((13*m+3) / 5 + d + y + (y / 4) - (y / 100) + (y / 400)) %7).
day_names =[('Monday'),'Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
for example day_names[0] = 'Monday' and day_names[6] = 'Sunday'
The below does not seem to ever give me the correct dates, is there anyone who might be able to tell what I am doing wrong if not everything?
def day_of_week1(d, m, y):
d=1<=d<=31
m=1<=m<=12
y=1<=y<=10**5
if m in range (1,2):
m=m+12
y=y-1
day_names =[('Monday'),'Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
day =(((13*m+3) / 5 + d + y + (y / 4) - (y / 100) + (y / 400)) %7)
day=(math.ceil(day))
if 2>day>=1:
return day_names[0]
elif 3>day>=2:
return day_names[1]
elif 4>day>=3:
return day_names[2]
elif 5>day>=4:
return day_names[3]
elif 6>day>=5:
return day_names[4]
elif 7>day>=6:
return day_names[5]
elif 8>day>=7:
return day_names[6]
Use the day names from the calendar module. Also, the adjustment for the month is not compliant with Zeller's Rule. Try this:
import calendar
def day_of_week(d, m, y):
if m < 3:
y -= 1
m += 10
else:
m -= 2
yc, yd = divmod(y, 100)
r = d + (13 * m - 1) // 5 + yd + yd // 4 + yc // 4 - 2 * yc
return calendar.day_name[r % 7 - 1]
print(day_of_week(9, 11, 1951))
Output:
Friday
I am very new to Python and we were told to write the weekday function without any modules like e.g. daytime etc.
But it doesn't work and i am not sure where is a problem
def weekDay (day,month,year):
global y0
global m0
global x
y0 = 0
m0 = 0
day,month,year = int(input("Enter a day: "))
month = int(input("Enter a month: "))
year = int(input("Enter a year:"))
a = (day + x + (31 * m0) // 12) % 7
for m0 in a:
m0 = month + 12 * ((14 - month) // 12) - 2
for x in a:
x = y0 + y0 // 4 - y0 // 100 + y0 // 400
for y0 in x:
y0 = year - ((14 - month) // 12)
if a == 0:
print("Sunday")
elif a == 1:
print("Monday")
elif a == 2:
print("Tuesday")
elif a == 3:
print("Wednesday")
elif a == 4:
print("Thursday")
elif a == 5:
print("Friday")
else:
print("Error")
return weekDay(a)
'''
here is the formula we were given:
[![formula][1]][1]
[1]: https://i.stack.imgur.com/iBv30.png
This should help:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.strftime('%A')
'Friday'
>>>
Global variables not defined anywhere and I am not able to understand the logic you are trying to write. So written a function based on a aptitude trick.
def weekday(day,month,year):
"""
This function is written based upon aptitude trick
to obtain day from given a date.
Input date example : 15-5-2020
Link for logic : https://www.youtube.com/watch?v=rJ0_GWDTdD4
"""
# for different months we are assigning specific number to that month
months = {1:1, 2:4, 3:4, 4:0, 5:2, 6:5, 7:0, 8:3, 9:6, 10:1, 11:4, 12:6}
# assigning days to a number
day_name = {1:'Sunday', 2:'Monday', 3:'Tuesday', 4:'Wednesday', 5:'Thursday',
6:'Friday', 0:'Saturday'}
# to get the year in between 1600 and 2000. since we are assiging values
# for the years also
while year not in range(1600,2000):
if year>2000:
year-=400
if year<1600:
year+=400
# assigning values to years
if year in range(1600,1700):
yr = 6
if year in range(1700,1800):
yr = 4
if year in range(1800,1900):
yr = 2
if year in range(1900,2000):
yr = 0
# assigning last two numbers of year to last
first = year//100
last = year - (first * 100)
# obtaining remainder
res = (day + months[month] + yr + last + (last//4))%7
#returning the day_name
return day_name[res]
day,month,year = list(map(int,input("Enter date in format dd-mm-yyyy : ").split('-')))
print(weekday(day,month,year))
Hope, you are satisfied with logic.
My goal with this code was to write a code that measures the degree measure of the sun having that at 6:00 the angle is 0 and at 18:00 the angle is 180 degrees. I tried to make the time input a string and then loop through its characters and pick out the integers and put it into the list that way I could avoid the colon. It seems that this is still a problem. Can someone explain to me what's wrong with this code? Why do I keep getting an "unsupported operand type error"?
def sun_angle(time):
lis = []
time = str(time)
for i in time:
if i.isdigit():
lis.append(i)
else:
continue
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
b = a - 6
if b < 6 or b > 18:
return "I can't see the sun!"
else:
return b * 15
print(sun_angle("12:12"))
Michael's answer is a great explanation for why what you're doing isn't working (need to convert string to int before manipulating with * and +).
However, there are a lot of ways to parse the time that will be easier to work with than what you're doing here. I'd consider splitting and then parsing the two parts, or you could use the datetime library for more complexity:
# option 1
def parse_time_as_hour(time_str):
hour_str, min_str = time_str.split(':')
return int(hour_str) + int(min_str) / 60.0
# option 2
import datetime
def parse_time_as_hour(time_str):
parsed = datetime.datetime.strptime(time_str, '%H:%M')
return parsed.hour + parsed.minute / 60.0
def sun_angle(time):
fractional_hour = parse_time_as_hour(time)
if fractional_hour < 6 or fractional_hour >= 18:
return "I can't see the sun!"
else:
return (fractional_hour - 6) * 15
If you change the above similar line to:
a = int(lis[0]) * 10 + int(lis[1]) + ((int(lis[2]) + int(lis[3]))/60)
then you get a result. The problem on that line is that you're mixing int and str types. And since you're already passing in a string you can change time = str(time) to time = time. Casting time to a string is redundant.
Your error line is:
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
since time is a string type
def sun_angle(time):
lis = []
time = str(time)
for i in time:
if i.isdigit():
lis.append(int(i)) #cast it to type int
else:
continue
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
b = a - 6
if b < 0 or b >= 12:
return "I can't see the sun!"
else:
return b * 15
print(sun_angle("12:12"))
output: 90
You need to cast lis[i] to integer when you're calculating the value of a. 07:00 means sun is up, your logic fails and 18:01 means sun is down.
def sun_angle(time_):
lis = []
time_ = str(time_)
for i in time_:
if i.isdigit():
lis.append(i)
else:
continue
a = int(lis[0])*10
a += int(lis[1])
bb = (int(lis[2])*10 + int(lis[3]))
#print a
#print bb
#b = a - 6
if (a < 6 or a > 18) or (a == 18 and bb > 0):
return "I can't see the sun!"
else:
return (float(a)-6.0) * 15.0 + (15.0*float(bb))/60.0
I want to adapt the code here: Given a date range how can we break it up into N contiguous sub-intervals? to split a range of dates as follows:
Starting date is '2015-03-20' and end date is '2017-03-12'. I want to split it into 3 parts. One for each of the 3 years, so that I get a list like this:
[['2015-03-20', '2015-12-31'], ['2016-01-01', '2016-12-31'], ['2017-01-01', '2017-03-12']]
Any pythonic way to do this?
If I don't misunderstand your meaning, you can just get the middle years and append it to the string like -12-31 or -01-01.
start_date = '2015-03-20'
end_date = '2018-03-12'
def split_date(s,e):
return [[s,s[:4]+"-12-31"]]+ [['%s-01-01'%(str(i)), '%s-12-31'%(str(i))] for i in range(int(s[:4])+1,int(e[:4]))]+[[e[:4] + "-01-01", e]]
print(split_date(start_date,end_date))
Result:
[['2015-03-20', '2015-12-31'], ['2016-01-01', '2016-12-31'], ['2017-01-01', '2017-12-31'], ['2018-01-01', '2018-03-12']]
Modifying the original code that you linked:
from datetime import datetime, timedelta
def date_range(start, end, interval):
start = datetime.strptime(start, "%Y%m%d")
end = datetime.strptime(end, "%Y%m%d")
diff = (end - start) / interval
for i in range(interval):
if i == 0:
date_additive = 0
else:
date_additive = 1
yield ["{0}-{1}-{2}".format(str(((start + diff * i) + timedelta(days=date_additive)).strftime("%Y").zfill(2)),
str(((start + diff * i) + timedelta(days=date_additive)).strftime("%m").zfill(2)),
str(((start + diff * i) + timedelta(days=date_additive)).strftime("%d").zfill(2))),
"{0}-{1}-{2}".format(str((start + diff * (i + 1)).strftime("%Y").zfill(2)),
str((start + diff * (i + 1)).strftime("%m").zfill(2)),
str((start + diff * (i + 1)).strftime("%d").zfill(2)))]
Input example:
def main():
begin = "20150320"
end = "20170312"
interval = 3
print(list(date_range(begin, end, interval)))
main()
Results:
[['2015-03-20', '2015-11-16'], ['2015-11-17', '2016-07-14'], ['2016-07-15', '2017-03-12']]
So to figure out the day of the week from any date since 15 of october you can use a simple piece of arithmetic my problem is that i have read from a file the date (for e.g. 2009-06-12) and i have put the equation in:
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
The dates are in the format yyyy-mm-dd and my code looks like this:
count = 5
f = open('/Users/student/Desktop/Harry.txt').readlines()[count]
Y = f[2:4]
C = f[:2]
m = f[5:7]
d = f[8:10]
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
if w == 0:
print (f, "is a Sunday")
elif w == 1:
print (f, "is a Monday")
elif w == 2:
print (f, "is a Tuesday")
elif w == 3:
print (f, "is a Wednesday")
elif w == 4:
print (f, "is a Thursday")
elif w == 5:
print (f, "is a Friday")
elif w == 6:
print (f, "is a Saturday")
to clarify:
w = day of the week counting from Sunday = 0 Monday = 1
d = the day of the month (for e.g. 28th 13th)
m = month number where March = 1 etc.
Y = last 2 digits of year
C = first 2 digits of year
Yet i get this error
Traceback (most recent call last):
File "/Users/student/Documents/workspace/Tutorial Challenges/src/Day_Of_The_Week.py", line 7, in <module>
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
TypeError: can't multiply sequence by non-int of type 'float'
Help would be greatly appreciated.
Y, C, m, and d are all strings. You want to convert them into ints first:
Y = int(f[2:4])
C = int(f[:2])
...
Are you sure that equation even works, though? It looks like it'd produce a lot of non-integer weekdays. You might've miscopied it. Also, brackets aren't a grouping operator in Python; they're the list construction syntax. You'll want to replace those brackets with parentheses in the expression for w. (Or were those brackets supposed to be the floor operator? If so, you'll want math.floor, from the math module, or just int if truncation is fine.)
As the above user has said, you want to convert from string to int. However, this is the ideal place to use the datetime module. You can use this to specify that your datetime is of the format: yyyy-mm-dd, and use the module to load up the info as datetime.
http://docs.python.org/2/library/datetime.html