Python • kurs podstawowy • lekcja 25
Przetwarzanie plików linia po linii
Plik z wynikami może mieć wiele wierszy.
Twój cel: Oddzielisz parsowanie wiersza od odczytu pliku i policzysz sumę danych.Pliki tekstowe, pętle, funkcje i słowniki.
Zbuduj model działania
for line in file pobiera je kolejno bez tworzenia przez Twój kod listy całej zawartości. Zwykle line zawiera końcowy znak nowej linii. Ostatnia linia nie musi go mieć.
Parsowanie to zamiana tekstowego zapisu na dane o ustalonym znaczeniu. strip() usuwa białe znaki z obu końców, nie tylko koniec linii. split(";") tworzy listę części rozdzielonych średnikiem. Rozpakowujemy je do dwóch nazw, a int zmienia tekst wyniku na liczbę.
Zakładamy format imię;wynik, dokładnie jeden średnik, brak pustych linii i wynik całkowity. Jeśli imię mogłoby zawierać średnik, taki prosty podział byłby niewystarczający; kolejna lekcja pokaże CSV. Zapis przygotowawczy w przykładzie tworzy mały plik testowy. W prawdziwym analizatorze istniejącego pliku pomijasz ten zapis, aby nie zastąpić danych.
Przewidź przed uruchomieniem
from pathlib import Path
Path("scores.txt").write_text("Ola;10\nJan;7\n", encoding="utf-8")
def parse_score(line):
name, score_text = line.strip().split(";")
return {"name": name, "score": int(score_text)}
total = 0
with open("scores.txt", encoding="utf-8") as file:
for line in file:
record = parse_score(line)
total = total + record["score"]
print(total)
Porównaj wynik i prześledź mechanizm
17. score_text jest napisem, np. "10". Po int pole score ma int, więc akumulator wykonuje dodawanie liczb, a nie sklejanie tekstów.
Wynik kontrolny dla danych z przykładu. Wpisane odpowiedzi użytkownika nie są tutaj powtarzane:
17
| Etap | Dane |
|---|---|
| Wiersz | Ola;10 + znak nowej linii |
| strip i split | "Ola" oraz "10" |
| int | 10 |
| Rekord | name: Ola, score: 10 |
| Akumulator | 0 → 10 → 17 |
Zmień działający program
Sprawdź samą funkcję na wierszu bez końcowego znaku nowej linii. Nie otwieraj pliku.
Pierwsza wskazówka
Zachowaj działający punkt wyjścia. Zlokalizuj konstrukcję wskazaną w poleceniu i zmień tylko ten etap. Przed uruchomieniem zapisz oczekiwany efekt.
Porównaj swoją modyfikację
def parse_score(line):
name, score_text = line.strip().split(";")
return {"name": name, "score": int(score_text)}
print(parse_score("Ola;10"))
Wynik kontrolny dla danych z przykładu. Wpisane odpowiedzi użytkownika nie są tutaj powtarzane:
{'name': 'Ola', 'score': 10}
Znajdź przyczynę problemu
Celowo błędny przykład diagnostyczny. Najpierw postaw hipotezę. Nie kopiuj tej wersji jako poprawnego rozwiązania.
Zamierzone działanie: Odczytaj rekord zgodny z formatem imię;wynik.
name, score_text = "Ola;10;bonus".split(";")
Trop do diagnozy
Porównaj zamierzony rezultat z typami, nazwami i kolejnością instrukcji. Wskaż pierwsze miejsce, w którym zachowanie odbiega od celu.
Zastosuj w nowej sytuacji
Wskazówka do rozpoczęcia
Odczyt dostarcza tekst, parser nadaje mu strukturę, a przetwarzanie używa już właściwych typów.
Zacznij od przygotowania danych. Pierwsza instrukcja przykładowego rozwiązania:
from pathlib import Path
Rozwiązanie do samodzielnej kontroli
from pathlib import Path
Path("products.txt").write_text("Sok;6\nWoda;3\n", encoding="utf-8")
def parse_price(line):
name, price_text = line.strip().split(";")
return int(price_text)
total = 0
with open("products.txt", encoding="utf-8") as file:
for line in file:
total = total + parse_price(line)
print(total)
Wynik kontrolny dla danych z przykładu. Wpisane odpowiedzi użytkownika nie są tutaj powtarzane:
9
Porównaj dane wejściowe, wynik i powód użycia konstrukcji. Inna wersja kodu jest poprawna, jeśli realizuje te same wymagania.
Co zabierasz do kolejnego programu?
Odczyt dostarcza tekst, parser nadaje mu strukturę, a przetwarzanie używa już właściwych typów.
Bez zaglądania do przykładu wyjaśnij własnymi słowami, jak główna konstrukcja prowadzi od danych do wyniku. Potem sprawdź wyjaśnienie, uruchamiając swój program.