Michael Scott Perkins
Michael Scott Perkins

Reputation: 345

Python - How to exclude Sat. and Sun. from weeks

I was hoping that someone could give me some examples of ways in which I can return calendar data that does the following.


  1. Returns the number of days in any given month (past/present/future), but after excluding Saturdays and Sundays.

Example:

input('Year: ') — 2018

input('Month: ') — 7

End Result: The number of weekdays in (July) of (2018) is (22).


  1. Assign an iterator to each weekday after excluding Sat. and Sun.

Example:

input('Year: ') — 2018

input('Month: ') — 7

input('date: ') — 20

End Result: The (20) is a (Friday) and is the (15) weekday of (July), (2018).

This is the code that I've been able to create so far...

import calendar

year = float(input('Year: '))
month = float(input('Month: '))
input_year = []
input_month = []

if year >= 1000 and year <=3000:
    input_year.append(year)
if month >= 1 and month <=12:
    input_month.append(month)

cal_format = calendar.TextCalendar(calendar.MONDAY)
result_cal = cal_format.formatmonth(int(input_year[0]), int(input_month[0]))
print(result_cal)

THE END RESULT IS...

Year: 1978
Month: 3
     March 1978
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

This only prints out a Text Calendar with Sat. and Sun at the end of each week, so I can at least visually exclude them. But I would really like to be able to programmatically exclude them and be able to input the above variables to calculate weekdays in a month, and which weekday each day is within that month.

Upvotes: 4

Views: 1692

Answers (4)

Billy Timimi
Billy Timimi

Reputation: 61

I made a simple solution in around 10 minutes. My approach relies heavily on list comprehensions and string methods such as join and split, so I recommend you look those up if your not familiar with them already. First split the result into lines, the tittle needs to be recentred, and the other lines needed the last characters removing.

Recenter the first line by using the strip() method to removing the whitespace at the begging of the line, then adding two space beforehand.

Take of the weekends by only including the first 15 characters of each line using list comprehensions.

The last part was the hardest. The idea was to count how many day numbers there were in my formatted calendar. First put all the lines with day numbers into one big line, then split the line by spaces to get a list of all day numbers, and finally use the size of the list.

import calendar

year = float(input('Year: '))
month = float(input('Month: '))
input_year = []
input_month = []

if year >= 1000 and year <=3000:
    input_year.append(year)
if month >= 1 and month <=12:
    input_month.append(month)

cal_format = calendar.TextCalendar(calendar.MONDAY)
result_cal = cal_format.formatmonth(int(input_year[0]), int(input_month[0]))

lines = result_cal.split("\n") # Split result_cal into a list of lines
title_line = lines[0] # Save first line, we want to edit this differently
title_line = "  " + title_line.strip() # Change the indentation of the title line


lines = lines[1:] # Now select lines below the first 
lines = [line[:3*5] for line in lines] # Only Keep first 15 characters or each
                                       # line to exclude weekends. (5 weekdays *
                                       # 3 chars per day)

lines = [line for line in lines if len(line.strip())] # Don't include empty lines
                                                      # happens if month starts
                                                      # on a weekend.

# prints out the result
print(title_line)
for line in lines:
    print(line)

# Next work out how many working days in month.
nums = "".join(lines[1:]).split(" ") # Three parts: first lines[1:] means this
                                     # only looks at the portion of the calendar
                                     # with numbers written on then. 2nd "".join()
                                     # joins the lines into a single string on 1 line
                                     # 3rd the .split(" ") splits the string based on spaces
                                     # unfortunatly 2 consecutive spaces result in an empty
                                     # string.

nums = [num for num in nums if len(num)] # Filters the empty string.
print(f"There are {len(nums)} working days in the month you selected") # Prints result
#(uses f-string, you may want to look them up, I find them to be very useful)

Upvotes: 0

EasonL
EasonL

Reputation: 863

One way to check the weekday of a date is to use the date object's weekday() method. It is in python standard library datetime module.

date.weekday()

Return the day of the week as an integer, where Monday is 0 and Sunday is 6. For example, date(2002, 12, 4).weekday() == 2, a Wednesday. See also isoweekday().

import datetime

num_of_weekdays = 0
weekday_list = []

start_date = datetime.date(int(input_year[0]), int(input_month[0]), 1)
cur_date = start_date
while cur_date.month == start_date.month:
    if 0 <= cur_date.weekday() <= 4:  # if it is a weekday
        num_of_weekdays += 1
        weekday_list.append(cur_date.day)
    cur_date += datetime.timedelta(days=1)

print("The number of weekdays in ({}) of ({}) is ({}).".format(
    input_month[0], input_year[0], num_of_weekdays))

date_ = datetime.date(int(input_year[0]), int(input_month[0]), int(input_date[0]))
index = weekday_list.index(int(input_date[0])) + 1
print("The ({}) is a ({}) and is the ({}) weekday of ({}), ({}).".format(
    date_.day, date_.strftime('%A'), index, date_.month, date_.year)

Upvotes: 0

Ellburrito
Ellburrito

Reputation: 137

Here's one way to find the number of previous weekdays:

Note that the type conversions for year, month, day are int.

import calendar

year = int(input('Year: '))
month = int(input('Month: '))
day = int(input('Day: '))

full_wks = day / 7
extra_days = day % 7

first_day = calendar.weekday(year, month, 1)
if first_day >= 5:              # if month begins on a weekend
    weekend = 7 - first_day     # yields 1 if Sunday, 2 if Saturday
    extra_days -= weekend

weekdays = full_wks * 5 + extra_days

ordinal = lambda n: "{}{}".format(n, 'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4])

print "{}/{} is the {} weekday in the month.".format(month, day, ordinal(weekdays))

Output:

Year: 2018
Month: 7
Day: 20
7/20 is the 15th weekday in the month.

Ordinal number conversion from xsot on Code Golf.

Upvotes: 1

erickque
erickque

Reputation: 126

To get the number of weekdays in a month:

import calendar

weekdays = 0
cal = calendar.Calendar()

for week in cal.monthdayscalendar(2018, 7):
    for i, day in enumerate(week):
        # Check if is a weekday and the day is from this month
        if i < 5 and day != 0:
            weekdays += 1

print weekdays

To get the weekday number of a specific day, you can modify the above code to return the weekday count when the input day is reached.

Upvotes: 1

Related Questions