How to solve the weekday function problem Python - python

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.

Related

Trying to use Zeller’s formula to return days of the week using python

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

List Comprehension

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

Select dates in index

i have start date and end date and dataframe with daily observations. The problem is that i can't find a way, which will enable me select dates with periodicity of 3 months
for example:
2003-01-03 + 3 months = 2003-04-03 and so on
output should consist of 20 rows because 5 years with 3 months periodicity, including start and end dates
EDIT: Old solution didn't work for all cases. Therefore a new one:
start, end = returns.index[0], returns.index[-1]
length = (end.year - start.year) * 12 + (end.month - start.month)
if length % 3 == 0 and end.day >= start.day:
length += 3
new_index = []
for m in range(3, length, 3):
ydelta, month = divmod(start.month + m, 12)
day = pd.Timestamp(year=start.year + ydelta, month=month, day=1)
day += pd.Timedelta(f'{min(start.day, day.days_in_month) - 1}d')
new_index.append(day)
new_index = pd.DatetimeIndex(new_index)
returns = returns.loc[new_index]
Another version which has some slight inaccuracies around the month ends but is more compact:
add_3_months = pd.tseries.offsets.DateOffset(months=3)
new_index = pd.date_range(returns.index[0] + add_3_months,
returns.index[-1],
freq=add_3_months)
returns = returns.loc[new_index]

Making a time adding function in python

I'm trying to build a function that recieves a date and adds days, updating everything in case it changes, so far i've come up with this:
def addnewDate(date, numberOfDays):
date = date.split(":")
day = int(date[0])
month = int(date[1])
year = int(date[2])
new_days = 0
l = 0
l1 = 28
l2 = 30
l3 = 31
#l's are the accordingly days of the month
while numberOfDays > l:
numberOfDays = numberOfDays - l
if month != 12:
month += 1
else:
month = 1
year += 1
if month in [1, 3, 5, 7, 8, 10, 12]:
l = l3
elif month in [4, 6, 9, 11]:
l = l2
else:
l = l1
return str(day) + ':' + str(month) + ':' + str(year) #i'll deal
#with fact that it doesn't put the 0's in the < 10 digits later
Desired output:
addnewDate('29:12:2016', 5):
'03:01:2017'
I think the problem is with either the variables, or the position i'm using them in, kinda lost though..
Thanks in advance!
p.s I can't use python build in functions :)
Since you cannot use standard library, here's my attempt. I hope I did not forget anything.
define a table for month lengths
tweak it if leap year detected (every 4 year, but special cases)
work on zero-indexed days & months, much easier
add the number of days. If lesser that current month number of days, end, else, substract current month number of days and retry (while loop)
when last month reached, increase year
add 1 to day and month in the end
code:
def addnewDate(date, numberOfDays):
month_days = [31,28,31,30,31,30,31,31,30,31,30,31]
date = date.split(":")
day = int(date[0])-1
month = int(date[1])-1
year = int(date[2])
if year%4==0 and year%400!=0:
month_days[1]+=1
new_days = 0
#l's are the accordingly days of the month
day += numberOfDays
nb_days_month = month_days[month]
done = False # since you don't want to use break, let's create a flag
while not done:
nb_days_month = month_days[month]
if day < nb_days_month:
done = True
else:
day -= nb_days_month
month += 1
if month==12:
year += 1
month = 0
return "{:02}:{:02}:{:04}".format(day+1,month+1,year)
test (may be not exhaustive):
for i in ("28:02:2000","28:02:2004","28:02:2005","31:12:2012","03:02:2015"):
print(addnewDate(i,2))
print(addnewDate(i,31))
result:
02:03:2000
31:03:2000
01:03:2004
30:03:2004
02:03:2005
31:03:2005
02:01:2013
31:01:2013
05:02:2015
06:03:2015
of course, this is just for fun. Else use time or datetime modules!

How to generate random time series data including February with 29 days?

I have used the following codes to generate a random rainfall data from 1950 to 2009 with known probability, mean and standard deviations. But, I have been suffering from iterating the days of February as 29 days in the leap years. And, also I was trying to save the output in a text file, but it gives an error message like
TypeError: float argument required, not numpy.string_
Can anyone please help me out?
My code:
import numpy as np
import random
import itertools
import datetime
dry =[0.33,0.27,0.32,0.41,0.42,0.45,0.57,0.52,0.45,0.39,0.37,0.37]
wet = [0.66,0.72,0.67,0.58,0.57,0.54,0.42,0.47,0.54,0.60,0.62,0.62]
d2d_tran = [0.56,0.50,0.58,0.62,0.63,0.67,0.73,0.66,0.60,0.56,0.57,0.62]
w2w_tran = [0.78,0.80,0.79,0.73,0.72,0.72,0.63,0.64,0.66,0.71,0.74,0.76]
mu = [3.71, 4.46, 4.11, 2.94, 3.00, 2.87, 2.31, 2.44, 2.56, 3.45, 4.32, 4.12]
sigma = [6.72,7.92,7.49,6.57,6.09,5.53,4.38,4.69,4.31,5.71,7.64,7.54]
days = [31,28,31,30,31,30,31,31,30,31,30,31]
rain = []
for y in xrange(0,60):
for m in xrange(0,12):
random_num = np.random.rand(days[m])
if random.random() <= dry[m]:
random_num[0] = 0
else:
r = abs(random.gauss(mu[m],sigma[m]))
random_num[0] = r
for i in xrange(1,days[m]):
if random_num[i-1] == 0:
if random_num[i] <= d2d_tran[m]:
random_num[i] = 0
else:
r = abs(random.gauss(mu[m],sigma[m]))
random_num[i] = r
else:
if random_num[i] <= w2w_tran[m]:
r = abs(random.gauss(mu[m],sigma[m]))
random_num[i] = r
else:
random_num[i] = 0
rain.append(random_num)
rain_series = []
for j in itertools.chain.from_iterable(rain):
rain_series.append(j)
y = np.array(rain_series).reshape(-1, 1)
date_series = []
def generate_dates(start_date, end_date):
return (start_date + datetime.timedelta(days=d) for d in xrange((end_date - start_date).days + 1))
start_date = datetime.date(1950, 1, 1)
end_date = datetime.date(2009, 12, 16)
for current_date in generate_dates(start_date, end_date):
f = current_date.strftime('%Y-%m-%d')
date_series.append(f)
z = np.array(date_series).reshape(-1, 1)
#### Here I have 365x60 = 21900 rainfall values, that is why I had to
####set the end_date upto (2009,12,16). If
#### the February days for leap years can be set as 29 in days[] of
####rain_series than this problem would be solved.
data = np.concatenate((z,y), axis=1)
print data
data1 = data.reshape((21900,2))
np.savetxt('Random Rainfall Data.txt', data1)
#### I want to shape data in two columns like dates and rainfall.
#### And than, save it into a text file. But, it provides an error!!!
Use the calendar.monthrange() to get the number of days of a month.
for year in xrange(1950,2020):
for month in xrange(1,13):
day_num = calendar.monthrange(year, month)[1]
random_num = np.random.rand(day_num)
...
Regarding the data writing problem, you must add a third argument. It depends on your specific problem:
np.savetxt('test.txt', a, '%s') # Example
See documentation for more formatting info.

Categories

Resources