- nowość
- W empik go
Python - zbiór zadań z rozwiązaniami - ebook
Python - zbiór zadań z rozwiązaniami - ebook
Programowanie w Pythonie przestaje być tajemnicą, gdy masz w rękach właściwy przewodnik. Ta wyjątkowa publikacja to prawdziwa skarbnica wiedzy praktycznej, która całkowicie zmienia sposób nauki programowania. W przeciwieństwie do tradycyjnych podręczników, które zasypują czytelnika suchą teorią, ta książka wprowadza innowacyjne podejście - uczenie się przez rozwiązywanie konkretnych problemów. Każde zadanie zostało starannie wyselekcjonowane, by budować Twoje umiejętności programistyczne, od podstaw po zaawansowane koncepcje. Publikacja stanowi nieocenione źródło wiedzy zarówno dla początkujących programistów, jak i dla tych, którzy chcą podnieść swoje umiejętności na wyższy poziom. Systematyczne rozwiązywanie zawartych w niej zadań gwarantuje solidne podstawy programowania i pewność siebie w tworzeniu własnych projektów. Ta książka to więcej niż zbiór zadań - to program szkoleniowy, który przekształci Cię z początkującego programisty w pewnego siebie eksperta Pythona.
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 9788368316254 |
Rozmiar pliku: | 203 KB |
FRAGMENT KSIĄŻKI
1: Wprowadzenie do języka Python
Instalacja i konfiguracja środowiska
Pierwszy program
Używanie konsoli interaktywnej
Podstawowa składnia
Style formatowania kodu (PEP 8)
2: Zmienne i typy danych
Zadanie: Konwersja między systemami liczbowymi
Zadanie: Kalkulator rat kredytu
Zadanie: Inteligentna konwersja typów
Zadanie: Analizator tekstu
Zadanie: Generator raportów
Zadanie: System reguł logicznych
3: Operatory i wyrażenia
Zadanie: Kalkulator naukowy
Zadanie: System porównywania i sortowania danych
Zadanie: System filtrowania produktów
Zadanie: Gra w zgadywanie z operatorami przypisania
Zadanie: System uprawnień z operatorami bitowymi
Zadanie: Parser wyrażeń matematycznych
Zadanie: Analizator wyrażeń algebraicznych
4: Instrukcje warunkowe
Zadanie: System oceniania wyników testów
Zadanie: System rekomendacji filmów
Zadanie: Analizator typów zdań
Zadanie: System weryfikacji hasła
Zadanie: Generator komunikatów kontekstowych
Zadanie: System rezerwacji biletów
5: Pętle i iteracje
Zadanie: Gra w zgadywanie liczby
Zadanie: Analiza ciągu Fibonacciego
Zadanie: Generator wzorów ASCII
Zadanie: Analizator tekstu
Zadanie: Optymalizator liczb pierwszych
Zadanie: Analiza danych pogodowych
Zadanie: Przetwarzanie danych z wykorzystaniem komprehensji
6: Funkcje
Zadanie: Funkcje do przetwarzania teksu
Zadanie: Generowanie raportów
Zadanie Wartości domyślne parametrów
Zadanie Argumenty pozycyjne i nazwane
Zadanie: Zwracanie wartości
Zadanie: Funkcje zagnieżdżone
Zadanie: Rekurencja
Zadanie: Dokumentowanie funkcji
7: Listy i krotki
Zadanie: Menedżer plików logów
Zadanie: Analizator logów serwera
Zadanie: System logowania zdarzeń aplikacji
Zadanie: Analizator danych sprzedażowych
Zadanie: System konfiguracji aplikacji
Zadanie: Menedżer kontekstu dla bazy SQLite
Zadanie: System synchronizacji katalogów
8: Obsługa wyjątków
Zadanie: Parser plików konfiguracyjnych z obsługą błędów
Zadanie: Walidator danych formularza rejestracyjnego
Zadanie: System obsługi konta bankowego z własnymi wyjątkami
Zadanie: Menedżer połączeń z bazą danych
Zadanie: System logowania zdarzeń z propagacją wyjątków
Zadanie: Refaktoryzacja systemu obsługi zamówień
9: Moduły i pakiety
Zadanie: Kalkulator statystyczny z różnymi metodami importu
Zadanie: Biblioteka do przetwarzania tekstu
Zadanie: System zarządzania szkołą
Zadanie: Program demonstracyjny przestrzeni nazw
Zadanie: Narzędzie do zarządzania ścieżkami modułów
Zadanie: Tworzenie i publikacja pakietu Python
Zadanie: Menedżer wirtualnych środowisk
10: Programowanie obiektowe
Zadanie: System biblioteczny
Zadanie: Menadżer połączeń do bazy danych
Zadanie: Monitor procesów
Zadanie: Konto bankowe
Zadanie: Fabryka pojazdów
Zadanie: Walidator danych
Zadanie: Talia kart
Zadanie: Menadżer konfiguracji
11: Dziedziczenie i polimorfizm
Zadanie: Walidator adresów email
Zadanie: Parser logów serwera
Zadanie: Analizator składni kodu źródłowego
Zadanie: Konwerter formatów dat
Zadanie: Narzędzie do refaktoryzacji kodu
Zadanie: Walidator formularzy
Zadanie: Parser danych strukturalnych ze stron WWW
12: Praca z datami i czasem
Zadanie: Analizator logów serwera
Zadanie: Generator raportów finansowych
Zadanie: Walidator danych osobowych
Zadanie: Parser plików konfiguracyjnych
Zadanie: Konwerter kodowania tekstu
Zadanie: Narzędzie do analizy tekstu wielojęzycznego
Zadanie: Generator dokumentów z szablonów
13: Programowanie funkcyjne
Zadanie: Funkcje lambda
Zadanie: Map, filter, reduce
Zadanie: Funkcje wyższego rzędu
Zadanie: Domknięcia
Zadanie: Currying
Zadanie: Immutability
Zadanie: Funkcje czyste
14: Generatory i iteratory
Zadanie: Implementacja systemu logowania wykonania funkcji
Zadanie: System cachowania wyników z parametrami
Zadanie: System walidacji atrybutów klasy
Zadanie: System middleware dla funkcji webowych
15: Wielowątkowość i współbieżność
Zadanie: Moduł threading
Zadanie: Tworzenie wątków
Zadanie: Synchronizacja wątków
Zadanie: Kolejki i wymiana danych
Zadanie: Procesy w Pythonie
16: Testowanie kodu
Zadanie: Kompleksowe testowanie klasy bankowej
Zadanie: Implementacja testów z wykorzystaniem pytest
Zadanie: Testowanie systemu walidacji formularza
Zadanie: Test integracji systemu zarządzania zamówieniamiInstalacja i konfiguracja środowiska
Instalacja środowiska programistycznego jest pierwszym krokiem w rozpoczęciu przygody z językiem Python. W tym podrozdziale przeprowadzimy proces instalacji niezbędnych narzędzi na najpopularniejszych systemach operacyjnych oraz skonfigurujemy nasze pierwsze środowisko programistyczne.
Instalacja Pythona
Pierwszym krokiem jest pobranie interpretera Pythona. Należy wejść na oficjalną stronę
(https://www.python.org/downloads)
i pobrać najnowszą stabilną wersję. Na stronie zostaniemy automatycznie przekierowani do wersji odpowiedniej dla naszego systemu operacyjnego.
System Windows: Po pobraniu pliku instalacyjnego uruchamiamy go z uprawnieniami administratora. Bardzo ważne jest zaznaczenie opcji "Add Python to PATH" podczas instalacji - umożliwi to później wywoływanie Pythona z poziomu wiersza poleceń. Wybieramy instalację niestandardową (Custom Installation) i upewniamy się, że zaznaczone są wszystkie komponenty, szczególnie pip (menedżer pakietów). Instalator utworzy odpowiednie katalogi i doda wymagane zmienne środowiskowe.
System macOS: Na komputerach Mac instalacja przebiega podobnie - po pobraniu pliku .pkg klikamy dwukrotnie, aby uruchomić instalator. System macOS może wymagać potwierdzenia instalacji w ustawieniach bezpieczeństwa. Python zostanie zainstalowany w katalogu /Library/Frameworks/Python.framework/Versions/3.x. Terminal automatycznie wykryje nową instalację.
System Linux: W większości dystrybucji Linux Python jest już preinstalowany. Możemy jednak potrzebować nowszej wersji. W Ubuntu i podobnych systemach używamy następujących poleceń w terminalu:
sudo apt update
sudo apt install python3
sudo apt install python3-pip
Weryfikacja instalacji: Po zakończeniu instalacji warto sprawdzić jej poprawność. Otwieramy terminal (wiersz poleceń w Windows) i wpisujemy:
python --version
pip --version
Powinniśmy zobaczyć numery zainstalowanych wersji. Jeśli polecenia nie są rozpoznawane w Windows, należy zrestartować system.
Instalacja PyCharm:
PyCharm Community Edition to darmowe, zaawansowane środowisko programistyczne (IDE). Wchodzimy na stronę (http://www.jetbrains.com/pycharm/download) i pobieramy wersję Community odpowiednią dla naszego systemu.
Windows: Uruchamiamy pobrany plik .exe i przechodzimy przez kreator instalacji, akceptując domyślne ustawienia.
macOS: Przeciągamy pobraną aplikację do folderu Applications.
Linux: Rozpakowujemy pobrany archiwum .tar.gz i uruchamiamy skrypt install.sh z katalogu bin.
Konfiguracja interpretera w PyCharm:
1. Po pierwszym uruchomieniu PyCharm wybieramy "Create New Project"
2. Wskazujemy lokalizację projektu i jego nazwę (np. "pierwszy\_projekt")
3. W sekcji "Python Interpreter" wybieramy "Previously configured interpreter"
4. Klikamy "Add Interpreter" i wskazujemy zainstalowaną wersję Pythona:
- Windows: zazwyczaj C:\\Users\\\AppData\\Local\\Programs\\Python\\Python3x\\python.exe
- macOS/Linux: /usr/local/bin/python3 lub podobna ścieżka
Pierwszy program
Rozpoczynając przygodę z programowaniem w Pythonie, stworzymy nasz pierwszy interaktywny program. Będzie on komunikował się z użytkownikiem, pobierał dane i wykonywał proste obliczenia.
Tworzenie nowego pliku programu rozpoczynamy od otwarcia PyCharm i wybrania opcji "New Python File" z menu kontekstowego prawego przycisku myszy w panelu projektu. Nazwijmy nasz plik "powitanie.py". Rozszerzenie .py jest standardowym rozszerzeniem dla plików źródłowych Pythona.
W nowo utworzonym pliku zaczniemy od najprostszej instrukcji wyświetlającej tekst na ekranie. Służy do tego funkcja print():
print("Witaj w moim pierwszym programie!")
Aby program mógł pobrać dane od użytkownika, wykorzystamy funkcję input(). Zapisuje ona wprowadzony tekst do zmiennej, którą możemy później wykorzystać:
imie = input("Jak masz na imię? ")
wiek = input("Ile masz lat? ")
Zauważmy, że funkcja input() zawsze zwraca tekst (string), nawet jeśli użytkownik wprowadzi liczbę. Aby wykonać obliczenia na wieku, musimy przekonwertować go na liczbę całkowitą za pomocą funkcji int():
wiek = int(wiek)
aktualny_rok = 2024
rok_100_lat = aktualny_rok + (100 - wiek)
Teraz możemy połączyć wszystkie elementy w kompletny program:
print("Witaj w moim pierwszym programie!")
imie = input("Jak masz na imię? ")
wiek = input("Ile masz lat? ")
wiek = int(wiek)
aktualny_rok = 2024
rok_100_lat = aktualny_rok + (100 - wiek)
print(f"Cześć {imie}! Masz {wiek} lat.")
print(f"100 lat skończysz w roku {rok_100_lat}.")
Program możemy uruchomić na dwa sposoby. Pierwszy to użycie zielonego przycisku "Run" w PyCharm (lub skrót Shift+F10). Drugi sposób to uruchomienie z terminala. W tym celu otwieramy terminal w katalogu z naszym plikiem i wpisujemy:
python powitanie.py
Podczas pisania programu mogą pojawić się błędy składni (syntax errors). PyCharm będzie je podkreślał na czerwono jeszcze przed uruchomieniem. Najczęstsze błędy to:
- Brak zamknięcia cudzysłowu w tekście
- Nieprawidłowe wcięcia kodu
- Brak nawiasów zamykających przy funkcjach
- Literówki w nazwach zmiennych
Jeśli program napotka błąd podczas działania, Python wyświetli komunikat wskazujący linię z błędem i jego typ. Na przykład, próba przekonwertowania tekstu "osiem" na liczbę wywoła ValueError. Warto uważnie czytać te komunikaty, ponieważ zawierają cenne wskazówki do rozwiązania problemu.
Używanie konsoli interaktywnej
Konsola interaktywna Pythona, znana również jako Python REPL (Read-Eval-Print Loop), to potężne narzędzie pozwalające na natychmiastowe wykonywanie i testowanie kodu. W przeciwieństwie do tradycyjnych skryptów, gdzie cały program jest wykonywany od początku do końca, konsola interaktywna wykonuje każde polecenie natychmiast po jego wprowadzeniu.
Dostęp do konsoli interaktywnej możemy uzyskać na kilka sposobów. Najprostszym jest otwarcie terminala i wpisanie polecenia "python" lub "python3". W środowisku PyCharm konsolę otwieramy za pomocą zakładki "Python Console" znajdującej się na dole ekranu. System IDLE, dostarczany wraz z Pythonem, również oferuje własną konsolę interaktywną - wystarczy uruchomić IDLE z menu start lub terminala.
Spróbujmy wykonać pierwsze obliczenia w konsoli. Po znaku zachęty ">>>" możemy wpisywać wyrażenia matematyczne:
>>> 2 + 2
4
>>> 10 * 5
50
>>> 20 / 3 # dzielenie zwraca liczbę zmiennoprzecinkową
6.666666666666667
>>> 20 // 3 # dzielenie całkowitoliczbowe
6
>>> 20 % 3 # operator modulo (reszta z dzielenia)
2
>>> 2 ** 3 # potęgowanie
8
Konsola świetnie nadaje się również do eksperymentowania z tekstem. Python oferuje wiele użytecznych operacji na ciągach znaków:
>>> "Python" + " " + "3.12" # łączenie tekstów
'Python 3.12'
>>> "Python" * 3 # powtarzanie tekstu
'PythonPythonPython'
>>> "Python" # pierwszy znak (indeksowanie od zera)
'P'
>>> "Python" # ostatni znak
'n'
>>> len("Python") # długość tekstu
6
>>> "python".upper() # zamiana na wielkie litery
'PYTHON'
Podczas pracy w konsoli interaktywnej możemy korzystać z historii wcześniej wprowadzonych poleceń. Używając strzałek góra/dół na klawiaturze, przewijamy ostatnio wykonane polecenia. Jest to szczególnie przydatne, gdy chcemy zmodyfikować poprzednie wyrażenie bez przepisywania go w całości.
Konsola zapamiętuje również wartości zmiennych w ramach jednej sesji:
>>> x = 10
>>> y = 5
>>> x + y
15
>>> x * y
50
>>> tekst = "Hello"
>>> tekst.lower()
'hello'
Warto zauważyć, że w konsoli interaktywnej wynik każdego wyrażenia jest automatycznie wyświetlany - nie trzeba używać funkcji print(). To kolejna różnica w porównaniu do tradycyjnych skryptów. W przypadku błędu składni lub wykonania, konsola natychmiast wyświetli komunikat o błędzie, pozwalając na szybką korektę:
>>> 10 / 0
Traceback (most recent call last):
File "
ZeroDivisionError: division by zero
Konsola interaktywna jest nieocenionym narzędziem podczas nauki Pythona - pozwala na szybkie testowanie pojedynczych wyrażeń, eksperymentowanie z funkcjami i natychmiastowe otrzymywanie wyników. Jest również przydatna podczas debugowania większych programów, gdy chcemy sprawdzić działanie poszczególnych fragmentów kodu w izolacji.
Podstawowa składnia
Składnia Pythona jest jedną z jego najmocniejszych stron - została zaprojektowana tak, aby kod był czytelny i elegancki. Jednocześnie początkujący programiści często popełniają charakterystyczne błędy składniowe. Przyjrzyjmy się typowym pomyłkom na przykładzie prostego programu:
Print("Witaj świecie!") # błąd: Python rozróżnia wielkość liter
liczba1 = 10
Liczba2 = 20 # niespójna konwencja nazewnictwa
wynik = liczba1 + Liczba2
if wynik > 25:
print("Wynik jest większy niż 25") # brak wcięcia
tekst = "To jest
długi tekst" # niedozwolony podział stringu
imie = 'Adam" # niespójne użycie cudzysłowów
Poprawna wersja tego kodu powinna wyglądać następująco:
print("Witaj świecie!") # funkcje zaczynają się małą literą
liczba1 = 10
liczba2 = 20 # konsekwentnie używamy małych liter
wynik = liczba1 + liczba2
if wynik > 25:
print("Wynik jest większy niż 25") # wymagane wcięcie 4 spacji
tekst = "To jest \
długi tekst" # użycie znaku kontynuacji linii
imie = 'Adam' # spójne użycie cudzysłowów
Wcięcia w Pythonie mają szczególne znaczenie - definiują bloki kodu. W przeciwieństwie do wielu innych języków programowania, które używają nawiasów klamrowych, Python wykorzystuje wcięcia do określenia, które instrukcje należą do danego bloku (np. wnętrza funkcji czy instrukcji warunkowej). Standardowo stosuje się 4 spacje dla każdego poziomu wcięcia. Mieszanie spacji i tabulatorów jest niedozwolone i prowadzi do błędów.
Python oferuje elastyczność w zakresie używania cudzysłowów. Możemy używać zarówno pojedynczych ('), jak i podwójnych (") cudzysłowów do definiowania tekstów:
tekst1 = 'Python'
tekst2 = "Python" # oba zapisy są równoważne
cytat = 'Powiedział "Cześć!"' # cudzysłowy można zagnieżdżać
długi_tekst = '''To jest
tekst wielolinijkowy''' # potrójne cudzysłowy dla wielu linii
Przy tworzeniu nazw zmiennych obowiązują następujące zasady:
- Nazwa może zawierać litery, cyfry i podkreślenia
- Musi zaczynać się od litery lub podkreślenia
- Nie może być słowem kluczowym (jak if, for, while)
- Python rozróżnia wielkość liter (zmienna1 i Zmienna1 to różne zmienne)
- Zaleca się używanie małych liter i podkreśleń (snake\_case)
Python oferuje specjalne sekwencje znaków, rozpoczynające się od backslasha (), które pozwalają na specjalne formatowanie tekstu:
print("Pierwsza linia\nDruga linia") # \n - nowa linia
print("Kolumna1\tKolumna2") # \t - tabulator
print("Ścieżka do pliku: C:\\Program Files") # \\ - backslash
print(r"Ścieżka do pliku: C:\Program Files") # r - raw string
Dobrą praktyką jest zachowanie spójności w całym kodzie. Jeśli zdecydujemy się na określony styl (np. pojedyncze cudzysłowy), powinniśmy go konsekwentnie stosować w całym programie. Python ma oficjalny przewodnik stylu (PEP 8), który zawiera szczegółowe zalecenia dotyczące formatowania kodu.
Style formatowania kodu (PEP 8)
PEP 8 (Python Enhancement Proposal 8) to oficjalny przewodnik stylu dla kodu Pythona. Przestrzeganie tych wytycznych pomaga tworzyć kod, który jest czytelny i łatwy w utrzymaniu. Zasady PEP 8 powstały na podstawie wieloletnich doświadczeń społeczności Pythona i są powszechnie akceptowane w projektach na całym świecie.
Przyjrzyjmy się przykładowi kodu, który łamie wiele zasad formatowania:
def oblicz_srednia(x,y):
return(x+y)/2
class KalkulatorOcen:
def __init__(self,oceny):self.oceny=oceny
def srednia(self):
suma=0
for ocena in self.oceny:suma+=ocena
return suma/len(self.oceny)
wynik=KalkulatorOcen()
print(wynik.srednia())Ten sam kod po zastosowaniu zasad PEP 8 wygląda następująco:
def oblicz_srednia(x, y):
return (x + y) / 2
class KalkulatorOcen:
def __init__(self, oceny):
self.oceny = oceny
def srednia(self):
suma = 0
for ocena in self.oceny:
suma += ocena
return suma / len(self.oceny)
wynik = KalkulatorOcen()
print(wynik.srednia())
Aby automatycznie formatować kod zgodnie z PEP 8, możemy wykorzystać narzędzie autopep8. Instalujemy je za pomocą menedżera pakietów pip:
pip install autopep8
Po instalacji możemy użyć autopep8 z linii poleceń:
autopep8 --in-place --aggressive --aggressive moj_plik.py
W środowisku PyCharm możemy skonfigurować automatyczne formatowanie kodu. Przechodzimy do Settings (Ctrl+Alt+S) > Editor > Code Style > Python i ustawiamy:
- Hard wrap at: 79 (maksymalna długość linii zgodnie z PEP 8)
- Use spaces instead of tabs
- Indent size: 4
PyCharm umożliwia również formatowanie kodu na żądanie za pomocą skrótu Ctrl+Alt+L (Windows/Linux) lub Cmd+Alt+L (macOS).
Kolejnym przydatnym narzędziem jest pylint, który nie tylko sprawdza formatowanie, ale także znajduje potencjalne błędy i naruszenia dobrych praktyk. Instalujemy go podobnie:
pip install pylint
Przykład użycia pylint:
pylint moj_plik.py
Pylint generuje szczegółowy raport z oceną kodu w skali 0-10 oraz listą problemów do rozwiązania. Możemy skonfigurować pylint w PyCharm, przechodząc do Settings > Tools > External Tools i dodając nowe narzędzie.
Kwestia spacji kontra tabulatory w Pythonie jest rozstrzygnięta jednoznacznie - PEP 8 zaleca używanie 4 spacji do wcięć. Chociaż tabulatory działają, mieszanie ich ze spacjami może prowadzić do trudnych do wykrycia błędów. Większość edytorów można skonfigurować tak, aby automatycznie zamieniały tabulatory na spacje.
Poprawne formatowanie kodu to nie tylko kwestia estetyki. Dobrze sformatowany kod:
- Jest łatwiejszy do czytania i zrozumienia
- Zmniejsza prawdopodobieństwo błędów
- Ułatwia współpracę z innymi programistami
- Przyspiesza debugowanie
- Jest łatwiejszy w utrzymaniu
Warto pamiętać, że chociaż narzędzia automatycznego formatowania są pomocne, nie zastąpią zrozumienia zasad PEP 8. Niektóre decyzje dotyczące formatowania wymagają ludzkiego osądu i znajomości kontekstu.
2: ZMIENNE I TYPY DANYCHZadanie: Konwersja między systemami liczbowymi
W praktyce programistycznej często zachodzi potrzeba konwersji liczb między różnymi systemami. Python dostarcza wbudowane narzędzia do obsługi liczb w systemie dwójkowym, ósemkowym i szesnastkowym. W tym zadaniu stworzymy program, który pozwoli na swobodną konwersję między tymi systemami.
Rozwiązanie:
Na początku zdefiniujmy funkcję, która będzie odpowiedzialna za konwersję liczby do wszystkich systemów:
def konwertuj_liczbe(liczba_str, system_wejsciowy):
try:
# Konwersja wejścia na liczbę całkowitą
if system_wejsciowy == 10:
liczba = int(liczba_str)
else:
liczba = int(liczba_str, system_wejsciowy)
# Konwersja do różnych systemów
bin_str = bin(liczba) # Usuwamy prefiks '0b'
oct_str = oct(liczba) # Usuwamy prefiks '0o'
hex_str = hex(liczba) # Usuwamy prefiks '0x'
dec_str = str(liczba)
return {
'dwójkowy': bin_str,
'ósemkowy': oct_str,
'dziesiętny': dec_str,
'szesnastkowy': hex_str.upper()
}
except ValueError:
return None
Teraz implementujemy główną część programu, która będzie komunikować się z użytkownikiem:
def main():
systemy = {
'dwójkowy': 2,
'ósemkowy': 8,
'dziesiętny': 10,
'szesnastkowy': 16
}
while True:
print("\nKonwerter systemów liczbowych")
print("Dostępne systemy:", ", ".join(systemy.keys()))
system = input("Podaj system wejściowy: ").lower()
if system not in systemy:
print("Nieprawidłowy system liczbowy!")
continue
liczba = input(f"Podaj liczbę w systemie {system}: ")
wynik = konwertuj_liczbe(liczba, systemy)
if wynik is None:
print("Błąd: Nieprawidłowa liczba dla wybranego systemu!")
continue
print("\nWyniki konwersji:")
for system, wartosc in wynik.items():
print(f"{system:12} : {wartosc}")
if input("\nKontynuować? (t/n): ").lower() != 't':
break
if __name__ == "__main__":
main()
Przeanalizujmy kluczowe elementy rozwiązania:
1. Funkcja `konwertuj_liczbe` przyjmuje dwa parametry: tekst reprezentujący liczbę oraz podstawę systemu wejściowego. Wykorzystuje wbudowane funkcje Pythona:
- `bin()` - konwersja do systemu dwójkowego
- `oct()` - konwersja do systemu ósemkowego
- `hex()` - konwersja do systemu szesnastkowego
2. Prefiksy systemów liczbowych (0b, 0o, 0x) są usuwane przez wycinanie pierwszych dwóch znaków za pomocą notacji slice ``.
3. Konwersja string-int z różnymi podstawami realizowana jest przez drugi parametr funkcji `int()`. Na przykład:
int("1010", 2) # konwersja z systemu dwójkowego
int("752", 8) # konwersja z systemu ósemkowego
int("A5", 16) # konwersja z systemu szesnastkowego
4. Formatowanie wyników wykorzystuje f-stringi z określoną szerokością pola (`:12`), co zapewnia czytelne wyrównanie wyników.
5. Obsługa błędów realizowana jest przez blok `try-except`, który przechwytuje `ValueError` w przypadku nieprawidłowego wejścia.
Program można dalej rozwijać, dodając na przykład:
- Walidację wejścia przed konwersją
- Możliwość zapisu wyników do pliku
- Obsługę liczb ujemnych
- Formatowanie wyników z separatorami (np. 1010 1111 dla liczb binarnych)
Zadanie: Kalkulator rat kredytu
Precyzyjne obliczenia finansowe wymagają szczególnej uwagi przy operacjach na liczbach zmiennoprzecinkowych. W tym zadaniu stworzymy kalkulator, który nie tylko prawidłowo obliczy raty kredytu, ale również pokaże, jak radzić sobie z typowymi problemami związanymi z dokładnością obliczeń.
Rozwiązanie:
Najpierw przyjrzyjmy się problemom z typem float na prostym przykładzie:
print(0.1 + 0.2) # Wyświetli 0.30000000000000004
print(0.1 * 3) # Wyświetli 0.30000000000000004
Aby uniknąć takich niedokładności, wykorzystamy moduł decimal:
from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN, getcontext
# Ustawienie precyzji dla obliczeń
getcontext().prec = 10
def oblicz_rate(kwota, oprocentowanie, liczba_rat, kapitalizacja='miesięczna'):
try:
# Konwersja parametrów na Decimal
kwota = Decimal(str(kwota))
oprocentowanie = Decimal(str(oprocentowanie)) / Decimal('100')
liczba_rat = Decimal(str(liczba_rat))
# Słownik okresów kapitalizacji
okresy = {
'roczna': Decimal('1'),
'półroczna': Decimal('2'),
'kwartalna': Decimal('4'),
'miesięczna': Decimal('12')
}
m = okresy
r = oprocentowanie / m
# Wzór na ratę: PMT = PV * (r * (1 + r)^n) / ((1 + r)^n - 1)
czynnik = (Decimal('1') + r) ** liczba_rat
rata = kwota * (r * czynnik) / (czynnik - Decimal('1'))
# Zaokrąglenie do 2 miejsc po przecinku
rata = rata.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
return rata
except ZeroDivisionError:
return "Błąd: Nieprawidłowe parametry kredytu"
except KeyError:
return "Błąd: Nieprawidłowy okres kapitalizacji"
except InvalidOperation:
return "Błąd: Nieprawidłowe dane wejściowe"
Dodajmy funkcję do formatowania wyświetlania wyników:
def formatuj_kwote(kwota, waluta="PLN"):
try:
if isinstance(kwota, str):
return kwota # Zwracamy komunikat błędu bez formatowania
kwota = Decimal(str(kwota))
kwota_str = '{:,.2f}'.format(kwota)
# Zamiana przecinka na spację dla tysięcy i kropki na przecinek dla groszy
kwota_str = kwota_str.replace(',', ' ').replace('.', ',')
return f"{kwota_str} {waluta}"
except:
return "Błąd formatowania kwoty"
def wyswietl_harmonogram(kwota, rata, oprocentowanie, liczba_rat):
pozostalo = Decimal(str(kwota))
print("\nHarmonogram spłat:")
print(f"{'Nr raty':>6} {'Rata':>15} {'Pozostało':>15}")
print("-" * 38)
for nr in range(1, int(liczba_rat) + 1):
print(f"{nr:>6} {formatuj_kwote(rata):>15} {formatuj_kwote(pozostalo):>15}")
pozostalo -= rata
# Zaokrąglenie pozostałej kwoty
pozostalo = pozostalo.quantize(Decimal('0.01'), ROUND_DOWN)
Przykład użycia kalkulatora:
def main():
try:
kwota = Decimal('100000')
oprocentowanie = Decimal('3.5')
liczba_rat = Decimal('12')
rata = oblicz_rate(kwota, oprocentowanie, liczba_rat)
print(f"Kwota kredytu: {formatuj_kwote(kwota)}")
print(f"Rata miesięczna: {formatuj_kwote(rata)}")
wyswietl_harmonogram(kwota, rata, oprocentowanie, liczba_rat)
except Exception as e:
print(f"Wystąpił nieoczekiwany błąd: {e}")
if __name__ == "__main__":
main()
Ten kod demonstruje kilka ważnych koncepcji:
1. Używamy typu Decimal zamiast float, co zapewnia dokładne obliczenia dziesiętne.
2. Metoda quantize() pozwala kontrolować zaokrąglenia, a ROUND\_HALF\_UP i ROUND\_DOWN to różne strategie zaokrąglania.
3. Formatowanie kwot używa separatorów tysięcy i prawidłowego zapisu groszy zgodnego z polską notacją.
4. Program obsługuje różne błędy, w tym dzielenie przez zero i nieprawidłowe dane wejściowe.
5. Harmonogram spłat pokazuje, jak pracować z kolejnymi obliczeniami, zachowując precyzję na każdym kroku.
Program można rozszerzyć o dodatkowe funkcje, takie jak:
- Obliczanie rzeczywistej rocznej stopy procentowej (RRSO)
- Uwzględnienie dodatkowych opłat i prowizji
- Generowanie szczegółowego harmonogramu w pliku CSV
- Obsługę różnych walut i przewalutowania
Zadanie: Inteligentna konwersja typów
W praktyce programistycznej często spotykamy się z danymi, których typ nie jest z góry określony. Może to być input od użytkownika, dane z pliku CSV czy API. W tym zadaniu stworzymy uniwersalny konwerter, który będzie potrafił automatycznie wykryć i przekształcić dane do najbardziej odpowiedniego typu.
Rozwiązanie:
Zacznijmy od implementacji głównej funkcji konwertującej:
def wykryj_i_konwertuj(wartosc):
if not isinstance(wartosc, str):
return wartosc # Jeśli wartość nie jest stringiem, zwracamy bez zmian
# Usuń białe znaki z początku i końca
wartosc = wartosc.strip()
# Sprawdź wartości logiczne
wartosci_logiczne = {
'true': True, 'false': False,
'tak': True, 'nie': False,
'1': True, '0': False,
'prawda': True, 'fałsz': False
}
if wartosc.lower() in wartosci_logiczne:
return wartosci_logiczne
# Próba konwersji na int
try:
if wartosc.isdigit() or (wartosc == '-' and wartosc.isdigit()):
return int(wartosc)
except Exception:
pass
# Próba konwersji na float
try:
return float(wartosc.replace(',', '.'))
except ValueError:
pass
# Jeśli żadna konwersja nie jest możliwa, zwróć string
return wartosc
Stwórzmy funkcję pomocniczą do identyfikacji typu:
def opisz_typ(wartosc):
typ = type(wartosc)
if isinstance(wartosc, bool):
return "bool"
elif isinstance(wartosc, int):
return "int"
elif isinstance(wartosc, float):
return "float"
elif isinstance(wartosc, str):
return "str"
else:
return str(typ.__name__)
Teraz implementacja parsera dla zestawu danych:
def przeanalizuj_dane(dane):
wyniki =
for wartosc in dane:
try:
skonwertowana = wykryj_i_konwertuj(wartosc)
wyniki.append({
'wejście': wartosc,
'wyjście': skonwertowana,
'typ_wejścia': opisz_typ(wartosc),
'typ_wyjścia': opisz_typ(skonwertowana)
})
except Exception as e:
wyniki.append({
'wejście': wartosc,
'wyjście': None,
'typ_wejścia': opisz_typ(wartosc),
'typ_wyjścia': 'błąd konwersji',
'błąd': str(e)
})
return wyniki
Przykład użycia:
def main():
przyklad_danych =
wyniki = przeanalizuj_dane(przyklad_danych)
print("Analiza konwersji typów:")
print("-" * 80)
print(f"{'Wejście':<15} {'Typ wejścia':<12} {'Wyjście':<15} {'Typ wyjścia':<12}")
print("-" * 80)
for wynik in wyniki:
print(f"{str(wynik):<15} "
f"{wynik:<12} "
f"{str(wynik):<15} "
f"{wynik:<12}")
if __name__ == "__main__":
main()
Ten kod demonstruje kilka ważnych aspektów konwersji typów w Pythonie:
1. Hierarchia konwersji jest zaimplementowana od najbardziej do najmniej specyficznego typu (bool -> int -> float -> str).
2. Program rozpoznaje różne formaty zapisu liczb, w tym notację polską z przecinkiem jako separatorem dziesiętnym.
3. Konwersja uwzględnia wartości logiczne w różnych zapisach, co jest przydatne przy pracy z danymi wejściowymi od użytkownika.
4. Każda próba konwersji jest zabezpieczona blokiem try-except, co zapewnia stabilność programu.
5. Automatyczna koercja typów jest widoczna przy operacjach na różnych typach numerycznych, na przykład przy mieszaniu int i float.
Program można rozszerzyć o:
- Obsługę dat w różnych formatach
- Konwersję wartości pieniężnych
- Obsługę list i krotek
- Wykrywanie formatów specjalnych (np. numery telefonów, kody pocztowe)
- Eksport wyników do różnych formatów
Zadanie: Analizator tekstu
W pracy z tekstem często potrzebujemy narzędzi do jego szczegółowej analizy. Stworzymy program, który pomoże nam zbadać strukturę tekstu, dostarczając statystyk i informacji o jego zawartości. Program będzie szczególnie przydatny przy analizie dokumentów, artykułów czy wypowiedzi.
Rozwiązanie:
Zacznijmy od stworzenia głównej klasy analizatora:
import re
from collections import Counter
import string
class AnalizatorTekstu:
def __init__(self, tekst):
self.tekst_surowy = tekst
self.tekst_czysty = self._wyczysc_tekst(tekst)
self.slowa = self._podziel_na_slowa()
self.zdania = self._podziel_na_zdania()
def _wyczysc_tekst(self, tekst):
# Usuń nadmiarowe białe znaki
tekst = ' '.join(tekst.split())
# Zamień wielokrotne spacje na pojedyncze
tekst = re.sub(r'\s+', ' ', tekst)
return tekst.strip()
def _podziel_na_slowa(self):
# Usuń znaki interpunkcyjne i podziel na słowa
tekst_bez_interpunkcji = self.tekst_czysty.translate(
str.maketrans('', '', string.punctuation)
)
return
def _podziel_na_zdania(self):
# Podziel tekst na zdania (zakończone . ! ?)
return +', self.tekst_czysty) if zdanie.strip()]
Dodajmy metody do analizy tekstu:
def statystyki_podstawowe(self):
return {
'liczba_znakow': len(self.tekst_surowy),
'liczba_znakow_bez_spacji': len(self.tekst_surowy.replace(' ', '')),
'liczba_slow': len(self.slowa),
'liczba_zdan': len(self.zdania),
'srednia_dlugosc_slowa': sum(len(slowo) for slowo in self.slowa) / len(self.slowa) if self.slowa else 0,
'srednia_dlugosc_zdania': sum(len(zdanie.split()) for zdanie in self.zdania) / len(self.zdania) if self.zdania else 0
}
def najczestsze_slowa(self, ilosc=10, min_dlugosc=3):
# Filtruj słowa krótsze niż min_dlugosc
dluzsze_slowa =
return Counter(dluzsze_slowa).most_common(ilosc)
def znajdz_frazy(self, fraza):
# Znajdź wszystkie wystąpienia frazy
wyniki =
indeks = 0
fraza = fraza.lower()
tekst = self.tekst_czysty.lower()
while True:
indeks = tekst.find(fraza, indeks)
if indeks == -1:
break
# Pobierz kontekst (20 znaków przed i po frazie)
start = max(0, indeks - 20)
koniec = min(len(tekst), indeks + len(fraza) + 20)
kontekst = self.tekst_czysty
wyniki.append({
'pozycja': indeks,
'kontekst': f"...{kontekst}..."
})
indeks += 1
return wyniki
Przykład użycia analizatora:
def main():
tekst_przykladowy = """
Python jest językiem programowania wysokiego poziomu. Jego składnia jest przejrzysta
i czytelna! Język Python wspiera różne paradygmaty programowania. Został stworzony przez
Guido van Rossuma i wydany w 1991 roku. Python jest dynamicznie typowany?
"""
analizator = AnalizatorTekstu(tekst_przykladowy)
# Wyświetl podstawowe statystyki
statystyki = analizator.statystyki_podstawowe()
print("Statystyki tekstu:")
for nazwa, wartosc in statystyki.items():
if isinstance(wartosc, float):
print(f"{nazwa}: {wartosc:.2f}")
else:
print(f"{nazwa}: {wartosc}")
# Wyświetl najczęściej występujące słowa
print("\nNajczęściej występujące słowa:")
for slowo, liczba in analizator.najczestsze_slowa(5):
print(f"{slowo}: {liczba} wystąpień")
# Znajdź wystąpienia frazy
fraza = "python"
print(f"\nWystąpienia frazy '{fraza}':")
for wynik in analizator.znajdz_frazy(fraza):
print(f"Pozycja {wynik}: {wynik}")
if __name__ == "__main__":
main()
Program demonstruje różne aspekty pracy z tekstem w Pythonie:
1. Wykorzystuje wbudowane metody stringów takie jak split(), strip(), replace() do podstawowej obróbki tekstu.
2. Pokazuje zaawansowane dzielenie tekstu przy użyciu wyrażeń regularnych (re.split()).
3. Demonstruje łączenie tekstów przy użyciu join() oraz konketanacji z wykorzystaniem f-stringów.
4. Implementuje wyszukiwanie w tekście za pomocą metody find() oraz wyrażeń regularnych.
5. Pokazuje różne metody czyszczenia tekstu, w tym usuwanie znaków interpunkcyjnych i nadmiarowych białych znaków.
Program można rozszerzyć o:
- Analizę sentymentu tekstu
- Wykrywanie języka
- Znajdowanie synonimów
- Generowanie chmury słów
- Eksport analizy do różnych formatów
Zadanie: Generator raportów
W praktyce biznesowej często potrzebujemy przedstawiać dane w różnych formatach, dostosowanych do konkretnych potrzeb odbiorców. Stworzymy uniwersalny generator raportów, który pozwoli na elastyczne formatowanie danych w zależności od wymagań.
Rozwiązanie:
Najpierw zdefiniujmy klasę reprezentującą pojedynczy rekord danych:
from datetime import datetime
from decimal import Decimal
class DaneSprzedazy:
def __init__(self, id_produktu, nazwa, cena, ilosc, data_sprzedazy):
self.id_produktu = id_produktu
self.nazwa = nazwa
self.cena = Decimal(str(cena))
self.ilosc = ilosc
self.data_sprzedazy = data_sprzedazy
self.wartosc = self.cena * Decimal(str(ilosc))
Teraz implementacja głównej klasy generatora raportów:
class GeneratorRaportow:
def __init__(self, dane):
self.dane = dane
def format_tabelaryczny(self):
# Definicja nagłówków i szerokości kolumn
kolumny = {
'ID': 6,
'Nazwa': 20,
'Cena': 10,
'Ilość': 8,
'Wartość': 12,
'Data': 12
}
# Tworzenie linii nagłówka
naglowek = '|'.join(f"{nazwa:^{szer}}" for nazwa, szer in kolumny.items())
separator = '-' * len(naglowek)
# Formatowanie wierszy
wiersze =
for rekord in self.dane:
wiersz = '|'.join(}}",
f"{rekord.nazwa:<{kolumny}}",
f"{rekord.cena:>{kolumny}.2f}",
f"{rekord.ilosc:^{kolumny}}",
f"{rekord.wartosc:>{kolumny}.2f}",
f"{rekord.data_sprzedazy.strftime('%Y-%m-%d'):^{kolumny}}"
])
wiersze.append(wiersz)
return f"{naglowek}\n{separator}\n" + "\n".join(wiersze)
def format_csv(self, separator=';'):
wiersze =
# Nagłówek
naglowek = separator.join()
wiersze.append(naglowek)
# Dane
for rekord in self.dane:
wiersz = separator.join()
wiersze.append(wiersz)
return '\n'.join(wiersze)
def raport_podsumowujacy(self):
suma_wartosci = sum(rekord.wartosc for rekord in self.dane)
ilosc_rekordow = len(self.dane)
return f"""
Raport podsumowujący sprzedaż
{'=' * 30}
Liczba transakcji: {ilosc_rekordow:>6}
Łączna wartość: {suma_wartosci:>10,.2f} PLN
Średnia wartość: {suma_wartosci/ilosc_rekordow:>10,.2f} PLN
Data raportu: {datetime.now():%Y-%m-%d %H:%M}
{'=' * 30}
"""
Przykład użycia generatora:
def main():
# Przykładowe dane
dane_testowe =
generator = GeneratorRaportow(dane_testowe)
print("Raport w formacie tabelarycznym:")
print(generator.format_tabelaryczny())
print("\nRaport w formacie CSV:")
print(generator.format_csv())
print("\nRaport podsumowujący:")
print(generator.raport_podsumowujacy())
if __name__ == "__main__":
main()
Ten kod pokazuje różne techniki formatowania tekstu w Pythonie:
1. F-stringi z różnymi specyfikatorami wyrównania:
- `:<` - wyrównanie do lewej
- `:>` - wyrównanie do prawej
- `:^` - wyrównanie do środka
2. Formatowanie liczb:
- `.2f` - dwa miejsca po przecinku
- `,` - separator tysięcy
- Zamiana kropki na przecinek dla formatu polskiego
3. Formatowanie dat przy użyciu strftime():
- `%Y-%m-%d` - format ISO
- `%d.%m.%Y` - format polski
- `%H:%M` - czas
4. Wyrównywanie tekstu z określoną szerokością kolumn dla czytelności
5. Różne style raportów dostosowane do potrzeb:
- Format tabelaryczny dla czytelności
- Format CSV do importu danych
- Format podsumowujący dla szybkiego przeglądu
Program można rozbudować o:
- Eksport do formatu HTML
- Kolorowanie tekstu w terminalu
- Sortowanie i filtrowanie danych
- Dodanie wykresów ASCII
- Obsługę różnych lokalizacji i formatów regionalnychZadanie: System reguł logicznych
Systemy informatyczne często wymagają implementacji złożonych reguł biznesowych, gdzie decyzje podejmowane są na podstawie wielu warunków. Stworzymy system weryfikacji uprawnień użytkownika, który będzie sprawdzał możliwość wykonania określonych operacji na podstawie różnych kryteriów.
Rozwiązanie:
Zacznijmy od zdefiniowania podstawowych struktur danych:
class Uzytkownik:
def __init__(self, nazwa, poziom_dostepu, aktywny=True, blokady=None):
self.nazwa = nazwa
self.poziom_dostepu = poziom_dostepu
self.aktywny = aktywny
self.blokady = blokady or
self.ostatnie_logowanie = None
self.liczba_prob_logowania = 0
class Zasob:
def __init__(self, nazwa, minimalny_poziom_dostepu, dostepny=True):
self.nazwa = nazwa
self.minimalny_poziom_dostepu = minimalny_poziom_dostepu
self.dostepny = dostepny
self.wymagane_uprawnienia = set()
Teraz implementacja głównej logiki weryfikacji uprawnień:
class SystemUprawnien:
def __init__(self):
self.MAX_PROB_LOGOWANIA = 3
self.WYMAGANY_POZIOM_ADMINISTRACYJNY = 5
def czy_uzytkownik_aktywny(self, uzytkownik):
# Wykorzystanie wartości truthy/falsy
return bool(uzytkownik and uzytkownik.aktywny)
def sprawdz_poziom_dostepu(self, uzytkownik, zasob):
# Operator and z wartością numeryczną
return uzytkownik.poziom_dostepu and uzytkownik.poziom_dostepu >= zasob.minimalny_poziom_dostepu
def czy_zasob_dostepny(self, zasob):
# Proste wyrażenie logiczne z negacją
return not (zasob is None or not zasob.dostepny)
def czy_ma_blokady(self, uzytkownik):
# Konwersja listy na wartość logiczną
return bool(uzytkownik.blokady)
def czy_moze_administrowac(self, uzytkownik):
# Złożone wyrażenie logiczne
warunki =
return all(warunki)
def sprawdz_dostep(self, uzytkownik, zasob):
# Skrócone obliczenia logiczne z wieloma warunkami
try:
podstawowe_warunki = (
uzytkownik and zasob and # Czy obiekty istnieją
self.czy_uzytkownik_aktywny(uzytkownik) and
self.czy_zasob_dostepny(zasob) and
not self.czy_ma_blokady(uzytkownik)
)
if not podstawowe_warunki:
return False
ma_poziom = self.sprawdz_poziom_dostepu(uzytkownik, zasob)
ma_uprawnienia = not zasob.wymagane_uprawnienia or (
set(uzytkownik.poziom_dostepu) >= zasob.wymagane_uprawnienia
)
return ma_poziom and ma_uprawnienia
except AttributeError:
return False
Przykład użycia systemu uprawnień:
def main():
system = SystemUprawnien()
# Tworzenie użytkowników z różnymi poziomami dostępu
admin = Uzytkownik("admin", 7)
user = Uzytkownik("user", 3, blokady=)
gosc = Uzytkownik("gosc", 1, aktywny=False)
# Tworzenie zasobów
zasob_poufny = Zasob("dane_poufne", 5)
zasob_publiczny = Zasob("dane_publiczne", 1)
# Demonstracja różnych scenariuszy
testy =
print("Wyniki testów uprawnień:")
for uzytkownik, zasob in testy:
wynik = system.sprawdz_dostep(uzytkownik, zasob)
szczegoly = {
"użytkownik": uzytkownik.nazwa,
"zasób": zasob.nazwa,
"dostęp": wynik,
"aktywny": system.czy_uzytkownik_aktywny(uzytkownik),
"blokady": system.czy_ma_blokady(uzytkownik),
"może_administrować": system.czy_moze_administrowac(uzytkownik)
}
print(f"\nTest dostępu dla {szczegoly} do {szczegoly}:")
for klucz, wartosc in szczegoly.items():
print(f"{klucz:20}: {wartosc}")
if __name__ == "__main__":
main()
Ten kod demonstruje różne aspekty pracy z typami logicznymi w Pythonie:
1. Wartości puste (None, puste listy, zera) są traktowane jako False, a niepuste jako True.
2. Operatory logiczne umożliwiają tworzenie złożonych warunków przy zachowaniu czytelności kodu.
3. Skrócone obliczenia zapewniają efektywność - warunki są sprawdzane tylko do momentu ustalenia wyniku.
4. Konwersja na bool może być jawna (funkcja bool()) lub niejawna (w kontekście warunkowym).
5. Złożone warunki mogą być grupowane w listy i sprawdzane za pomocą funkcji all() lub any().
Program można rozszerzyć o:
- System logowania i śledzenia dostępu
- Czasowe blokady i automatyczne odblokowywanie
- Hierarchiczne struktury uprawnień
- Grupy użytkowników i dziedziczenie uprawnień
- Audyt i raportowanie dostępuZadanie: Kalkulator naukowy
W tym zadaniu stworzymy zaawansowany kalkulator naukowy w Pythonie, który będzie obsługiwał różnorodne operacje matematyczne z zachowaniem kolejności działań. Kalkulator będzie nie tylko wykonywał podstawowe operacje arytmetyczne, ale również obsługiwał funkcje naukowe i przechowywał historię obliczeń.
import math
from typing import List, Union
class KalkulatorNaukowy:
def __init__(self):
self.historia: List =
def oblicz(self, wyrazenie: str) -> Union:
"""
Oblicza wartość wyrażenia matematycznego.
Args:
wyrazenie: String zawierający wyrażenie matematyczne
Returns:
Wynik obliczenia jako float lub int
"""
try:
wynik = eval(self._przygotuj_wyrazenie(wyrazenie))
self.historia.append(f"{wyrazenie} = {wynik}")
return wynik
except Exception as e:
raise ValueError(f"Błąd w wyrażeniu: {str(e)}")
def _przygotuj_wyrazenie(self, wyrazenie: str) -> str:
"""Przygotowuje wyrażenie do obliczenia, zastępując funkcje matematyczne."""
wyrazenie = wyrazenie.replace('^', '**') # Zamiana ^ na **
wyrazenie = wyrazenie.replace('sqrt', 'math.sqrt')
wyrazenie = wyrazenie.replace('pi', str(math.pi))
return wyrazenie
def konwertuj_na_radiany(self, stopnie: float) -> float:
"""Konwertuje stopnie na radiany."""
radiany = math.radians(stopnie)
self.historia.append(f"{stopnie}° = {radiany} rad")
return radiany
def pokaz_historie(self) -> None:
"""Wyświetla historię operacji."""
print("\nHistoria operacji:")
for operacja in self.historia: