Python · Syntax · Beginner

OOP, dictionaries, algorithmic thinking

15 tasks

Python exercises on OOP, dictionaries, and algorithmic thinking: classes for data analysis, counting words and characters, working with ratings, passwords, statistics, and dictionary transformations.

Dictionaries as class state

#
When a class needs to track a variable number of items — grades for many students, scores for many players, products in an inventory — a dictionary stored on self is the right tool. A separate attribute per item would not scale. ```python class GradeBook: def __init__(self): self.grades = {} def add(self, name, grade): if name not in self.grades: self.grades[name] = [] self.grades[name].append(grade) def average(self, name): grades = self.grades.get(name, []) if not grades: return 0 return sum(grades) / len(grades) ``` self.grades is initialized as an empty dict in __init__. Methods read from and write to it. The dictionary grows as you call add() — the class does not need to know in advance how many students there will be. dict.get(key, default) returns the value for key if it exists, or default otherwise — without raising a KeyError. It is safer than direct access when the key might not be there. For classes that just count occurrences — word frequency, letter counts — a plain dictionary with integer values works well: ```python class WordCounter: def __init__(self, text): self.text = text def count(self): result = {} for word in self.text.split(): result[word] = result.get(word, 0) + 1 return result ``` result.get(word, 0) + 1 is the standard dict-counting idiom: get the current count (defaulting to 0 if absent) and add 1.

Registry, counter, and aggregator patterns

#
A registry that prevents duplicates — store registered names in a set, check before adding: ```python class UserRegistry: def __init__(self): self.users = set() def register(self, username): if username in self.users: return False self.users.add(username) return True ``` A class with a balance that enforces a rule — do not allow withdrawals below zero: ```python class BankAccount: def __init__(self): self.balance = 0 def deposit(self, amount): self.balance += amount def withdraw(self, amount): if amount > self.balance: return False self.balance -= amount return True ``` Finding the top player — iterate over the dict, track the key with the maximum value: ```python class ScoreTable: def __init__(self): self.scores = {} def add(self, name, points): self.scores[name] = self.scores.get(name, 0) + points def top_player(self): return max(self.scores, key=self.scores.get) ``` max(dict, key=dict.get) finds the key whose corresponding value is largest. This is idiomatic Python for "which key has the highest value."

Dicts, sets, and class patterns quick reference

#
**Dictionary operations** ```python d = {} # empty dict d[key] = value # set / update d[key] # get — raises KeyError if missing d.get(key) # get — returns None if missing d.get(key, default) # get — returns default if missing key in d # True if key exists del d[key] # remove key d.keys() # all keys d.values() # all values d.items() # (key, value) pairs ``` **Counting idiom** ```python # Count occurrences of each word counts = {} for word in text.split(): counts[word] = counts.get(word, 0) + 1 # Same with setdefault: counts.setdefault(word, 0) counts[word] += 1 ``` **Set operations for registries** ```python s = set() # empty set — no duplicates allowed s.add(item) # add item item in s # membership check — O(1) s.remove(item) # remove — raises KeyError if absent s.discard(item) # remove — silent if absent ``` **Class patterns using dicts** ```python # Accumulate values per key self.data.setdefault(key, []).append(value) # Count per key self.counts[key] = self.counts.get(key, 0) + 1 # Find key with highest value max(self.scores, key=self.scores.get) # Iterate over all entries for name, score in self.scores.items(): print(name, score) # Check before inserting (registry pattern) if key not in self.data: self.data[key] = initial_value ```
01

WordCounter for text.

#

Create a WordCounter class that takes a text string. Add a count method that returns a dictionary where: - key — word - value — how many times it appears in the text

class WordCounter:
    pass
Solution
class WordCounter:
    def __init__(self, text):
        self.text = text

    def count(self):
        result = {}
        words = self.text.split()
        for w in words:
            if w in result:
                result[w] += 1
            else:
                result[w] = 1
        return result
02

GradeBook grade journal.

#

Create a GradeBook class. The add(name, grade) method adds a grade for a student. The average(name) method returns the student's average grade.

class GradeBook:
    pass
Solution
class GradeBook:
    def __init__(self):
        self.data = {}

    def add(self, name, grade):
        if name not in self.data:
            self.data[name] = []
        self.data[name].append(grade)

    def average(self, name):
        grades = self.data.get(name, [])
        if not grades:
            return 0
        return sum(grades) / len(grades)
03

Counting each letter.

#

Write a function that takes a string and returns a dictionary with the count of each letter.

def letter_stats(text):
    pass
Solution
def letter_stats(text):
    result = {}
    for ch in text:
        if ch.isalpha():
            ch = ch.lower()
            if ch in result:
                result[ch] += 1
            else:
                result[ch] = 1
    return result
04

Checking password strength.

#

Create a PasswordChecker class. The check method returns True if the password: - length ≥ 8 - has at least one digit

class PasswordChecker:
    pass
Solution
class PasswordChecker:
    def check(self, password):
        if len(password) < 8:
            return False

        has_digit = False
        for ch in password:
            if ch.isdigit():
                has_digit = True
                break

        return has_digit
05

Product inventory.

#

Create an Inventory class. The add_item(name, count) method adds a product. The total_items() method returns the total quantity of all products.

class Inventory:
    pass
Solution
class Inventory:
    def __init__(self):
        self.items = {}

    def add_item(self, name, count):
        if name in self.items:
            self.items[name] += count
        else:
            self.items[name] = count

    def total_items(self):
        total = 0
        for c in self.items.values():
            total += c
        return total
06

Grouping words by length.

#

Write a function that takes a list of words and returns a dictionary: - key — word length - value — how many words have that length

def length_groups(words):
    pass
Solution
def length_groups(words):
    result = {}
    for w in words:
        l = len(w)
        if l in result:
            result[l] += 1
        else:
            result[l] = 1
    return result
07

BankAccount without going negative.

#

Create a BankAccount class with methods: - deposit(amount) - withdraw(amount) — does not allow the balance to go below zero

class BankAccount:
    pass
Solution
class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount
            return True
        return False
08

Vowels and consonants.

#

Write a function that takes a string and returns a dictionary with the number of vowels and consonants.

def vowels_and_consonants(text):
    pass
Solution
def vowels_and_consonants(text):
    vowels = "aeiouy"
    result = {"vowels": 0, "consonants": 0}

    for ch in text.lower():
        if ch.isalpha():
            if ch in vowels:
                result["vowels"] += 1
            else:
                result["consonants"] += 1

    return result
09

User registration.

#

Create a UserRegistry class. The register(username) method: - returns True if the user was added - False if such a user already exists

USERS = []

class UserRegistry:
    pass
Solution
USERS = []

class UserRegistry:
    def register(self, username):
        if username in USERS:
            return False
        USERS.append(username)
        return True
10

Classification of numbers.

#

Write a function that takes a list of numbers and returns a dictionary: - "positive" - "negative" - "zero"

def number_summary(nums):
    pass
Solution
def number_summary(nums):
    result = {"positive": 0, "negative": 0, "zero": 0}

    for n in nums:
        if n > 0:
            result["positive"] += 1
        elif n < 0:
            result["negative"] += 1
        else:
            result["zero"] += 1

    return result
11

Shopping cart.

#

Create a ShoppingCart class. The add(product, price) method adds a product. The total() method returns the sum of all prices.

class ShoppingCart:
    pass
Solution
class ShoppingCart:
    def __init__(self):
        self.items = {}

    def add(self, product, price):
        self.items[product] = price

    def total(self):
        total = 0
        for p in self.items.values():
            total += p
        return total
12

Position of the first appearance of a character.

#

Write a function that takes a string and returns a dictionary where the key is a character, and the value is the position of its first appearance in the string.

def first_positions(text):
    pass
Solution
def first_positions(text):
    result = {}
    for i in range(len(text)):
        if text[i] not in result:
            result[text[i]] = i
    return result
13

Player score table.

#

Create a ScoreTable class. The add(name, points) method adds points to a player. The top_player() method returns the name of the player with the highest score.

class ScoreTable:
    pass
Solution
class ScoreTable:
    def __init__(self):
        self.scores = {}

    def add(self, name, points):
        if name in self.scores:
            self.scores[name] += points
        else:
            self.scores[name] = points

    def top_player(self):
        if not self.scores:
            return None
        top = None
        max_score = -1
        for name, score in self.scores.items():
            if score > max_score:
                max_score = score
                top = name
        return top
14

Swapping keys and values.

#

Write a function that takes a dictionary and returns a new dictionary where keys and values are swapped. It is guaranteed that the values are unique.

def swap_dict(d):
    pass
Solution
def swap_dict(d):
    result = {}
    for k, v in d.items():
        result[v] = k
    return result
15

Text analyzer.

#

Create a TextAnalyzer class. The analyze method returns a dictionary: - "chars" — number of characters - "words" — number of words - "lines" — number of lines

class TextAnalyzer:
    pass
Solution
class TextAnalyzer:
    def __init__(self, text):
        self.text = text

    def analyze(self):
        chars = len(self.text)
        lines = self.text.count("\n") + 1 if self.text else 0
        words = len(self.text.split())

        return {
            "chars": chars,
            "words": words,
            "lines": lines
        }