I am a complete beginner in Python and it is my first question on Stackoverflow. I have tried numerous tutorials on youtube + some additional google searching, but havent been really able to completely solve my task. Briefly putting it below asf:
We have a dataset of futures prices (values) for next 12-36 months. Each value corresponds to one month in future. The idea for the code is to have an input of following:
starting date in days (like 2nd of Feb 2021 or any other)
duration of given days (say 95 or 150 days or 425 days)
The code has to calculate the number of days from each given month between starting and ending date (which is starting + duration) and then to use appropriate values from corresponding month to calculate an average price for this particular duration in time.
Example:
Starting date is 2nd of Feb 2021 and duration is 95 days (end date 8th of May). Values are Feb - 7750, Mar - 9200, April - 9500, May is 10100.
I have managed to do same in Excel (which was very clumsy and too complicated to use on the daily basis) and average stands for around 8949 taking in mind all above. But I cant figure out how to code same "interval" with days per month in Python. All of the articles just simply point out to "monthrange" function, but how is that possible to apply same for this task?
Appreciate your understanding of a newbie question and sorry for the lack of knowledge to express/explain my thoughts more clear.
Looking forward to any help relative to above.
You can use dataframe.todatetime() to constuct your code. If you need further help, just click ctrl + tab within your code to see the inputs and their usage.
You can try the following code.
The input_start_date() function will input the start date, and return it when called.
After we have the start date we input the duration of days.
Then we simply add them using timedelta
For the Distribution of days in the month : SO - #wwii
import datetime
from datetime import timedelta
def input_start_date():
YEAR = int(input('Enter the year : '))
MONTH = int(input('Enter the month : '))
DAY = int(input('Enter the day : '))
DATE = datetime.date(YEAR, MONTH, DAY)
return DATE
# get the start date:
Start_date = input_start_date()
# get the Duration
Duration = int(input('Enter the duration : '))
print('Start Date : ', Start_date)
print('Duration :', Duration)
# final date.
Final_date = Start_date + timedelta(days=Duration)
print(Final_date)
# credit goes to #wwii -----------------------
one_day = datetime.timedelta(1)
start_dates = [Start_date]
end_dates = []
today = Start_date
while today <= Final_date:
tomorrow = today + one_day
if tomorrow.month != today.month:
start_dates.append(tomorrow)
end_dates.append(today)
today = tomorrow
end_dates.append(Final_date)
# -----------------------------------------------
print("Distribution : ")
for i in range(len(start_dates)):
days = int(str(end_dates[i]-start_dates[i]).split()[0]) + 1
print(start_dates[i], ' to ', end_dates[i], ' = ', days)
print(str(end_dates[0]-start_dates[0]))
'''
Distribution :
2021-02-02 to 2021-02-28 = 27
2021-03-01 to 2021-03-31 = 31
2021-04-01 to 2021-04-30 = 30
2021-05-01 to 2021-05-08 = 8
'''
Related
I'm trying to build a list of "pay days" for a given month in the future knowing only when the pay days started months ago. For example:
Starting date - When the paychecks started: 1/6/2023
Frequency is every two weeks
So if I want to know which dates are pay days in March, I have to start at the 1/6/2023 and add two weeks until I get to March to know that the first pay day in March is 3/3/2/2023.
Then I want my final list of dates to be only those March dates of:
(3/3/2023, 3/17/2023, 3/31/2023)
I know I can use pandas to do something like:
pd.date_range(starting_date, starting_date+relativedelta(months=1), freq='14d')
but it would include every date back to 1/6/2023.
The easiest thing to do here would be to just update the starting_date parameter to be the first pay day in the month you're interested in.
To do this, you can use this function that finds the first pay day in a given month by first finding the difference between your start date and the desired month.
# month is the number of the month (1-12)
def get_first_pay_day_in_month(month=datetime.datetime.now().month,
year=datetime.datetime.now().year,
start_date=datetime.datetime(2023, 1, 6),
):
diff = datetime.datetime(year, month, 1) - start_date
freq = 14
if diff.days % freq == 0:
print(f'Difference: {diff.days/freq} weeks')
return datetime.datetime(year,month,1)
else:
print(f'Difference: {diff.days} days')
print(f'Days: {diff.days % freq} extra')
return datetime.datetime(year,month,1 + 14 - (diff.days % freq))
Then you can use this function to get the first pay day of a specific month and plug it into the date_range method.
from dateutil import relativedelta
starting_date = get_first_pay_day_in_month(month=3)
pay_days = pd.date_range(starting_date, starting_date+relativedelta.relativedelta(months=1), freq='14d')
print(pay_days)
I was asked to create a program that calculates the number of Sundays inbetween 2 dates! I have been searching numerous articles and documentation but I still have a hard time understanding syntax. (2 months into my coding course with 0 technology and computer experience.)
I am having trouble understanding the logic of how to associate the calendar with the days inside the Dictionary. My current code is as follows :
def difference_between_days():
daysDict = {0 : "Monday",1: "Tuesday",2: "Wedensday",3: "Thursday",4: "Friday",5:
"Saturday",6: "Sunday"}
first_date = date(2021,7,28)
end_date = date(2022,7,28)
difference_between_dates = end_date - first_date
print(f"There are {difference_between_dates.days} days inbetween the two dates!")
d = date.weekday(first_date)
dd = daysDict[d]
print(f"The first date selected is a : {dd}")
difference_between_days()
edit: When using certain functions such as .isoweekday I run into problems printing because it returns me something like this "<built-in method isoweekday of datetime.date object at 0x000001EB956FA0F0>" and I still have not reached classes yet!
Python is not my weapon of choice, but this should do the job.
The idea is to use weekday() to move the start date to the following sunday, and the endate to the previous sunday. Then count the days in between, divide by 7 (weeks) and add 1 because both ends are Sundays.
Don't hesitate to ask if it's not clear, and accept the answer if it it.
HTH
from datetime import datetime, timedelta
def number_of_sundays(from_str, to_str):
# get date objects from the string representations in Ymd format
from_date = datetime.strptime(from_str, "%Y/%m/%d")
to_date = datetime.strptime(to_str, "%Y/%m/%d")
# move start date to the following sunday
from_date = from_date + timedelta(days=6-from_date.weekday())
# move end date to the previous sunday
to_date = to_date + timedelta(days=-to_date.weekday()-1)
# now both dates are sundays so the number is the number of weeks + 1
nb_sundays = 1 + (to_date - from_date).days / 7
return nb_sundays
print(number_of_sundays("2022/08/28", "2022/09/20"))
from datetime import datetime
x = input("first date: ")
y = input("second date: ")
a = datetime.strptime(x, "%Y/%m/%d")
b = datetime.strptime(y, "%Y/%m/%d")
result = (a-b).days
print("days: ",result)
# my first date is = 2021/2/8
# my second date is = 2021/1/24
# output = days : 15
So as you see everything is fine in this code But my teacher make a challenge for me . He said can you write a code with unusual days in months . For ex : January have 31 days but I want it to be 41 days and etc .
What should I do now ? (Please don't say : sum the output with 10 because the user inputs could be changeable and I should change all of the days in months so this will not work)
I am amatuar in coding so simple explanation would be better.
So I am looking for something like this :
# if January have 41 days instead of 31 days
# my first date is = 2021/2/8
# my second date is = 2021/1/24
# output will be = days : 15 + 10 = 25
You can make dictionary consisting of months and their custom days (For example, '1': 41 means first month consisting of 41 days). Then all you need to do is to add input date of the first month with the subtraction of total days of current month and days of input date. (Assuming first date is always greater than the second).
months = {
'1': 41,
'2': 38,
'3': 24,
...
...
'12': 45,
}
x = input("first date: ")
y = input("second date: ")
a = list(x.split('/'))
b = list(y.split('/'))
# 2021/2/8
# ['2021', '2', '8']
result = int(a[2]) + (months[b[1]] - int(b[2]))
print(result)
I think you're close the answer.
you don't want to 'sum the output with 10', but why not?
the answer to the problem is 'result + extra_days' (so sum of output + offset).
So instead of the '10' you want the offset, the offset is maxDayOfMonth +/- requestedDate
Here is a related post which gives a function to get the last day of any month:
def last_day_of_month(any_day):
# this will never fail
# get close to the end of the month for any day, and add 4 days 'over'
next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
# subtract the number of remaining 'overage' days to get last day of current month, or said programattically said, the previous day of the first of next month
return next_month - datetime.timedelta(days=next_month.day)
It always helps to find a scenario for your problem, for example:
Your teacher discoverd an alternate universe where the days in a month are variable, and he wants to use the datetime library to work. :)
The following code works but stops after 29th of Feb. The website returns "you have entered an invalid date. Please re-enter your search", which necessitate clicking on "OK". How do I get around this?
country_search("United States")
time.sleep(2)
date_select = Select(driver.find_element_by_name("dr"))
date_select.select_by_visible_text("Enter date range...") #All Dates
select_economic_news()
#btnModifySearch
for month in range(1,9):
for day in range(1,32):
try:
set_from_month(month)
set_from_date(day)
set_from_year("2020")
set_to_month(month)
set_to_date(day)
set_to_year("2020")
time.sleep(5)
#select_economic_news()
time.sleep(5)
search_now()
time.sleep(8)
export_csv()
modify_search()
time.sleep(5)
#country_remove()
except ElementClickInterceptedException:
break
logout()
If you can only use the methods featured in the initial post then I would try something like:
set_from_year('2020')
set_to_year('2020')
for month in range(1, 9):
# 1 to 9 for Jan to Aug
month_str = '0' + str(month)
set_from_month(month_str)
set_to_month(month_str)
for day in range(1, 32):
# Assuming an error is thrown for invalid days
try:
# Store data as needed
except Exception as e:
# print(e) to learn from error if needed
pass
There is a lot more that goes into this if it turns out that you're writing these methods yourself and need to loop through HTML and find a pattern for daily data.
I believe you want to dynamically obtain the number of days in a month, so that you can loop over that number to get data for each date. You can do this as follows:
from datetime import datetime
currentDay = datetime.today()
# You can set the currentDay using this if you want the data till the current date or
# whenever your scheduler runs the job.
# Now you need to get the number of days in each month from the chosen date, you can
# have the corresponding function like getStartMonth() in your program which will
# return the starting month.
from calendar import monthrange
daysPerMonth = {}
year = currentDay.year #TODO : change this to getStartYear()
startMonth = 3 # TODO : Implement getStartMonth() in your code.
for month in range(startMonth, currentDay.month+1):
# monthrange returns (weekday,number of days in that month)
daysPerMonth[month] = monthrange(year, month)[1]
for month in daysPerMonth.items():
print(month[0], '-',month[1])
This will output something like this(Number of days in a month from - March 2020 till August 2020):
3 - 31
4 - 30
5 - 31
6 - 30
7 - 31
8 - 31
And then you can run a loop for number of days while referring the range from the dict that you've obtained.
NOTE : In the function where you're running the loop to get data for each date add one if condition to check if it's the last day of the year and modify the year accordingly.
Maybe You can use these function to get count days of month:
import datetime
def get_month_days_count(year: int, month: int) -> int:
date = datetime.datetime(year, month, 1)
while (date + datetime.timedelta(days=1)).month == month:
date = date + datetime.timedelta(days=1)
return date.day
I want to design an algorithm which will calculate the week number according to the start week day set. for eg : - If I set the start day as WEDNESDAY and currently its 40 week and its TUESDAY, it should print 40 as the week number. If it is WEDNESDAY or THURSDAY, I should get 41.
Think of it like a cycle. From Wednesday till tuesday, it should be assigned a week no + 1, then when next wednesday comes, week should be incremented again.
I tried using calendar.setfirstweekday(calendar.WEDNESDAY) and then altering my system machine time, all I get is 40 as the week number everytime.
How do I design such as algorithm in python?
I have a similar problem for month, but I have designed a solution for it. Here is it.
current_date = datetime.datetime.now()
if current_date.day < gv.month_start_date:
month = current_date.month -1
if month == 0:
month = 12
else:
month = current_date.month
How can I design it for week?
I finally designed a solution for this.
if current_day >= set_week_day:
week = current_week
else:
week = current_week - 1
Works for all cases.
datetime in python has a function called isocalender to get the ISO week number (starts on Monday)
import datetime
datetime.date(2013, 9, 30).isocalendar()[1]
You can use this with a little bit of logic (this script should have the week begin on Wednesdays)
import datetime
day = 30
month = 9
year = 2013
weekcount = datetime.date(year, month, day).isocalendar()[1]
if datetime.date(year, month, day).isocalendar()[2] <= 3: # start on wednesday
weekcount -= 1
print weekcount