Python Arena
Step 4 of 4

Methods and attributes

After an object's dot there can be two kinds of things: attributes and methods. A date has the attribute year, and it has the method weekday, which you used with datetime objects in part 7: it gives the day of the week as a number from 0 (Monday) to 6 (Sunday).

from datetime import date

start = date(2026, 10, 17)

print(start.year)
print(start.weekday())
Output
2026
5
  • start.year is an attribute: a value stored in the object. There are no parentheses after it.
  • start.weekday() is a method call: the method works something out from the object's data. The parentheses are what call it, even when there are no arguments.

How do you know which is which? The documentation of a class lists its attributes and its methods. For date, year, month and day are attributes, and weekday() is a method. For Fraction, numerator and denominator are attributes.

A missing pair of parentheses

Mixing the two up is a common mistake, and one way round it doesn't even stop the program. This program is meant to spot Saturdays, and October 17, 2026 is one:

from datetime import date

day = date(2026, 10, 17)
if day.weekday == 5:
    print("Saturday!")
else:
    print("Not a Saturday")
Output
Not a Saturday

Without parentheses, day.weekday isn't the 5 that the method would work out: it is the method itself. A method is never equal to a number, so the condition is always False, and Python finds nothing wrong to report. Write day.weekday() == 5.

The other way round, parentheses after an attribute, does stop the program. A fraction's denominator is a number stored in the object, and Python can't call a number:

from fractions import Fraction

half = Fraction(1, 2)
print(half.denominator())
Python stops with
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(half.denominator())
          ~~~~~~~~~~~~~~~~^^
TypeError: 'int' object is not callable

"Not callable" means there are parentheses after something that isn't a function or a method: here the int 2.

Functions that take objects

Objects are values like any others, so your own functions can take them as arguments and return them. This program has a function that names the day of the week of a date, and one that picks the dates of one month out of a list:

from datetime import date


def day_name(day):
    names = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
    return names[day.weekday()]


def in_month(days, month):
    found = []
    for day in days:
        if day.month == month:
            found.append(day)
    return found


meetings = [date(2026, 5, 11), date(2026, 6, 3), date(2026, 5, 29)]

for day in in_month(meetings, 5):
    print(day, day_name(day))
Output
2026-05-11 Monday
2026-05-29 Friday

day_name uses the method's result as an index into a list. in_month reads an attribute of each object and returns a new list with some of the same date objects in it.

Your task

Challenge 1 of 3

This program mixes up attributes and methods. Fix it, so that it prints:

Month: 3
Weekday: 6
Year: 2026

Challenge 2

Write a function day_label(day) that takes a date object and returns a short label for it: the first three letters of the day of the week, a space, then the day, the month and the year separated by dots.

This code:

print(day_label(date(2026, 10, 17)))
print(day_label(date(2026, 3, 2)))

prints

Sat 17.10.2026
Mon 2.3.2026

Challenge 3

Write a function weekend_count(days) that takes a list of date objects and returns how many of them fall on a Saturday or a Sunday.

This code:

days = [date(2026, 10, 17), date(2026, 10, 18), date(2026, 10, 19)]
print(weekend_count(days))

prints

2