Wpis z serii „Matura z Informatyki w języku python”. W tym materiale pokażemy rozwiązania do zadań z matury z roku 2021. Przeanalizujemy treść zadania 5 oraz rozwiązania krok po kroku.
Poprzednie matura z informatyki python zadanie 4 można znaleźć tutaj
Wstęp do zadań z matury z Informatyki 2021 w języku Python
Zadania z matury z Informatyki z 2021 roku można znaleźć pod tym linkiem. Będzie to część 2 matury, która skupia się na części programistycznej.
Poprzednie matura z informatyki python zadanie 4 można znaleźć tutaj
Zadanie 5 – Wodociągi
Wodociągi miejskie zamierzają wykonać analizę zużycia wody. W tym celu zgromadziły dane
o poborze wody przez wszystkich swoich klientów za rok 2019. Dane są zapisane w pliku
wodociagi.txt. Pierwszy wiersz pliku jest wierszem nagłówkowym, a dane rozdzielono
średnikami. W każdym wierszu zapisano informacje dotyczące gospodarstwa domowego
jednego klienta: dziesięcioznakowy kod klienta oraz 12 liczb całkowitych oznaczających ilości
zużytej wody w m3 przez kolejnych 12 miesięcy (od stycznia do grudnia). Kod klienta składa
się z pięciocyfrowego numeru klienta, dwucyfrowej liczby oznaczającej liczbę osób
pozostających we wspólnym gospodarstwie domowym oraz trzyliterowego kodu dzielnicy
miasta. Każdy kod jest unikatowy.
Fragment pliku wodociagi.txt:
KodKlienta;I;II;III;IV;V;VI;VII;VIII;IX;X;XI;XII
0000103WIL;6;6;6;9;6;15;12;12;12;6;9;6
0000403BEM;6;3;9;9;12;15;15;15;9;6;3;9
Korzystając z powyższych danych oraz dostępnych narzędzi informatycznych, wykonaj
podane zadania. Wyniki zapisz w pliku tekstowym wyniki5.txt. Odpowiedź do każdego
zadania poprzedź numerem tego zadania.
Zadanie 5.1
Utwórz zestawienie zawierające pięciocyfrowe numery 10 klientów, którzy w ciągu roku
zużyli w swoim gospodarstwie domowym średnio najwięcej wody na jedną osobę, oraz ich
średnie zużycie wody na jedną osobę. Średnioroczne zużycie wody na jedną osobę zaokrąglij
do dwóch miejsc po przecinku.
Zestawienie, zawierające numery klientów i średnie zużycie wody na jedną osobę, uporządkuj
nierosnąco według średniej.
Rozwiązania
Z opisu zadania widzimy, że będziemy tutaj dużo operować na danych oraz ich wzajemnych zależnościach, jedną z lepszych bibliotek w tej kwestii w języku python jest biblioteka PANDAS (o której szeroko można się zapoznać korzystając z darmowego na naszej stronie PANDAS Tutorial.
import pandas as pd data = pd.read_csv('2021_Dane_PR2/wodociagi.txt',sep=';',header='infer') data.head()
Wczytując dane bezpośrednio do dataframe otrzymamy taki widok tabeli:
KodKlienta | I | II | III | IV | V | VI | VII | VIII | IX | X | XI | XII | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0000104WIL | 10 | 10 | 5 | 8 | 14 | 18 | 21 | 17 | 10 | 9 | 4 | 10 |
1 | 0000201ZOL | 2 | 2 | 1 | 3 | 3 | 4 | 4 | 4 | 2 | 2 | 2 | 2 |
2 | 0000302MOK | 4 | 4 | 2 | 6 | 5 | 7 | 10 | 8 | 4 | 6 | 3 | 3 |
3 | 0000402MOK | 3 | 3 | 3 | 5 | 4 | 7 | 9 | 7 | 4 | 6 | 2 | 2 |
4 | 0000503BIE | 7 | 3 | 7 | 8 | 7 | 10 | 13 | 10 | 6 | 9 | 7 | 7 |
Widać, że brakuje nam kilku danych oczekiwanych przez zadanie, które wynikają z Kodu Klienta, dodajmy je kolejnymi instrukcjami, rozdzielając dane z kolumny KodKlienta za pomocą funkcji .str oraz indeksowanie kolejnych części tekstu. Pierwsze 5 znaków to numer klienta, kolejne 2 to ilość osób, a kolejne 3 to dzielnica.
data['numer_klienta']=data['KodKlienta'].str[:5] data['ilosc_osob']=data['KodKlienta'].str[5:7].astype('int') data['dzielnica']=data['KodKlienta'].str[7:10] data.head()
Dzięki czemu mamy już widoczne wszystkie dane oczekiwane przez zadanie na początku (funkcja head() , pokaże nam pierwsze 5 rekordów)
KodKlienta | I | II | III | IV | V | VI | VII | VIII | IX | X | XI | XII | numer_klienta | ilosc_osob | dzielnica | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0000104WIL | 10 | 10 | 5 | 8 | 14 | 18 | 21 | 17 | 10 | 9 | 4 | 10 | 00001 | 4 | WIL |
1 | 0000201ZOL | 2 | 2 | 1 | 3 | 3 | 4 | 4 | 4 | 2 | 2 | 2 | 2 | 00002 | 1 | ZOL |
2 | 0000302MOK | 4 | 4 | 2 | 6 | 5 | 7 | 10 | 8 | 4 | 6 | 3 | 3 | 00003 | 2 | MOK |
3 | 0000402MOK | 3 | 3 | 3 | 5 | 4 | 7 | 9 | 7 | 4 | 6 | 2 | 2 | 00004 | 2 | MOK |
4 | 0000503BIE | 7 | 3 | 7 | 8 | 7 | 10 | 13 | 10 | 6 | 9 | 7 | 7 | 00005 | 3 | BIE |
Przystępując do sedna zadania, musimy policzyć średnie zużycie roczne na osobę. W takim razie będziemy potrzebować informację o tym jakie było roczne zużycie czyli sumę wartości z każdego miesiąca dla każdego klienta podzieloną przez wartość w kolumnie ilość osób. Dodamy sobie kolumnę 'roczne_zuzycie’ które będzie przechowywać sumę wszystkich miesięcy oraz dodamy kolumnę 'srednie_na_osobe’ która będzie przechowywać wartości potrzebne do rozwiązania tego zadania. Na końcu przefiltrujemy po tej kolumnie i wyświetlimy pierwsze 10 wierszy które jest naszą odpowiedzią.
data['roczne_zuzycie'] = data.I + data.II + data.III + data.IV + data.V + data.VI+data.VII+data.VIII+data.IX+data.X+data.XI+data.XII data['srednie_na_osobe']=data['roczne_zuzycie']/data['ilosc_osob'] data['srednie_na_osobe']=data.srednie_na_osobe.round(2) data_5_1 = data.sort_values(by='srednie_na_osobe', ascending=False) data_5_1[:10]
KodKlienta | I | II | III | IV | V | VI | VII | VIII | IX | X | XI | XII | numer_klienta | ilosc_osob | dzielnica | roczne_zuzycie | srednie_na_osobe | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
7934 | 0793503REM | 7 | 7 | 9 | 12 | 12 | 15 | 19 | 13 | 8 | 8 | 5 | 9 | 07935 | 3 | REM | 124 | 41.33 |
5079 | 0508003URU | 7 | 8 | 7 | 8 | 11 | 14 | 19 | 13 | 9 | 8 | 7 | 9 | 05080 | 3 | URU | 120 | 40.00 |
644 | 0064504WIL | 9 | 9 | 11 | 14 | 12 | 19 | 24 | 17 | 12 | 13 | 10 | 9 | 00645 | 4 | WIL | 159 | 39.75 |
8089 | 0809004PRA | 10 | 9 | 9 | 14 | 15 | 19 | 22 | 15 | 12 | 13 | 11 | 9 | 08090 | 4 | PRA | 158 | 39.50 |
5737 | 0573803WLO | 7 | 6 | 7 | 12 | 12 | 13 | 16 | 13 | 10 | 9 | 6 | 7 | 05738 | 3 | WLO | 118 | 39.33 |
8348 | 0834905WES | 12 | 12 | 12 | 15 | 17 | 25 | 29 | 19 | 17 | 14 | 11 | 13 | 08349 | 5 | WES | 196 | 39.20 |
8849 | 0885004BIA | 8 | 8 | 9 | 14 | 15 | 18 | 22 | 16 | 14 | 13 | 9 | 10 | 08850 | 4 | BIA | 156 | 39.00 |
2201 | 0220204REM | 9 | 10 | 11 | 14 | 12 | 19 | 19 | 18 | 14 | 11 | 7 | 9 | 02202 | 4 | REM | 153 | 38.25 |
9467 | 0946804PRA | 10 | 7 | 4 | 10 | 15 | 16 | 24 | 17 | 14 | 14 | 10 | 10 | 09468 | 4 | PRA | 151 | 37.75 |
6865 | 0686604REM | 5 | 8 | 9 | 13 | 13 | 18 | 19 | 17 | 14 | 14 | 9 | 8 | 06866 | 4 | REM | 147 | 36.75 |
Zadanie 5.2
Rozwiązanie
Dzięki pracy wykonanej przy organizacji danych w zadaniu 5.1, zadanie 5.2 będzie banalnie proste. Będzie polegać jedynie na sumie, pogrupowanychdanych po kolumnie 'dzielnica’
data_5_2 = data.groupby(['dzielnica']).sum() data_5_2['roczne_zuzycie']
Której wynikiem jest wyświetlenie wartości rocznego zużycia dla każdej z dzielnic
dzielnica BEM 54080 BIA 61614 BIE 56368 MOK 55889 OCH 59273 PRA 57241 REM 58971 SRO 58124 TAR 60234 URU 59597 URY 50116 WAW 57674 WES 60372 WIL 55476 WLO 66372 WOL 60523 ZOL 62312 Name: roczne_zuzycie, dtype: int64
Zadanie 5.3
Rozwiązanie
W kolejnym zadaniu również skorzystamy z sumy i grupowania na kolumnie 'dzielnica’, a dodatkowo wyciągniemy wartość maksymalną dla każdej kolumny z miesiącem i dodamy nową kolumnę w której przechowamy największą wartość która jest odpowiedzią.
data_5_3 = data.groupby(['dzielnica']).sum() data_5_3['max_zuzycie'] = data_5_3[['I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII']].max(axis=1) data_5_3['max_zuzycie']
Ostatecznie rozwiązaniem są wartości w kolumnie 'max_zuzycie’ dla każdej z dzielnicy
dzielnica BEM 8108 BIA 9274 BIE 8475 MOK 8452 OCH 8861 PRA 8575 REM 8873 SRO 8776 TAR 9120 URU 8960 URY 7519 WAW 8699 WES 9050 WIL 8284 WLO 9966 WOL 9117 ZOL 9417 Name: max_zuzycie, dtype: int64
Zadanie 5.4
Rozwiązanie
W tym zadaniu będziemy jedynie potrzebować sumy dla każdego miesiąca, aby otrzymać wartości dla roku 2019 jako wejście do naszej analizy. Zrobimy to sumując całą Tabele data, po czym usuniemy wszystkie nie interesujące nasz kolumny ( wszystkie oprócz miesięcy). Na końcu dodamy pomocniczą kolumnę z rokiem.
data_5_4 = data.sum()
data_5_4 = data_5_4.to_frame().transpose().drop(['KodKlienta','numer_klienta','ilosc_osob','dzielnica','roczne_zuzycie','srednie_na_osobe'],axis=1)
data_5_4['rok'] = 2019
data_5_4
Wynikiem będzie tabela z jednym wierszem od którego rozpoczniemy liczenie.
I | II | III | IV | V | VI | VII | VIII | IX | X | XI | XII | rok | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 53545 | 53274 | 53195 | 85745 | 85627 | 117552 | 149526 | 117497 | 85623 | 85530 | 53516 | 53606 | 2019 |
Zbudujemy pętlę, która dla każdego kolejnego roku od 2019 do 2030 przemnoży wartość z poprzedniego roku każdego miesiąca o 1.01 co da nam wartość powiększoną o 1% w roku kolejnym. Dzięki czemu otrzymamy tabelę z wieloma danymi, możemy w niej poszukać pierwszej wartości większej od 160000 natomiast łatwiej będzie nam ją po filtrować. Widzimy, że największe zużycie wody występuję w miesiącu 'VII’ stąd wiemy, że w tym miesiącu limit zostanie przekroczony jako pierwszy.
rok = 2019
for item in range(1,12):
data_5_4.loc[item] = data_5_4.iloc[item-1]*1.01
data_5_4['rok'].loc[item]=int(rok+item)
data_5_4.where(data_5_4['VII']>160000)
I | II | III | IV | V | VI | VII | rok | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
2 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
5 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
6 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |||||
7 | 57407.487429 | 57116.938748 | 57032.240055 | 91930.245766 | 91803.733795 | 126031.654911 | 160312.110659 | 2026.0 | |||||
8 | 57981.562303 | 57688.108136 | 57602.562456 | 92849.548224 | 92721.771133 | 127291.97146 | 161915.231766 | 2027.0 | |||||
9 | 58561.377926 | 58264.989217 | 58178.58808 | 93778.043706 | 93648.988844 | 128564.891175 | 163534.384083 | 2028.0 | |||||
10 | 59146.991705 | 58847.639109 | 58760.373961 | 94715.824143 | 94585.478733 | 129850.540086 | 165169.727924 | 2029.0 | |||||
11 | 59738.461622 | 59436.1155 | 59347.977701 | 95662.982385 | 95531.33352 | 131149.045487 | 166821.425203 | 2030.0 |
W tabeli widzimy, że pierwszy rok w którym wystąpiło przekroczenie to rok 2026 a miesiąc to oczywiście 'VII’ lipiec.
Kolejnym podpunktem jest narysowanie wykresu dla roku 2030, zrobimy to filtrując naszą tabele po kolumnie 'rok’, odwrócimy nasze dane tak, aby na osi X mieć miesiące(transpose()) i skorzystamy z funkcji plot, aby narysować nasz wykres wraz z opisami.
data_wykres = data_5_4[data_5_4.rok==2030.0] data_wykres = data_wykres.transpose().drop(['rok']) import matplotlib.pyplot as plt plt.title('przewidywane zuycie rok 2030') plt.xlabel('miesiac') plt.ylabel('zuzycie wody w m3') plt.grid(True) plt.plot(data_wykres)
Zadanie 5.5
Rozwiązanie
W tym zadaniu musimy rozwinąć naszą pętle z zadania 5.4, dodając zwiększanie się limitu oraz rozszerzając zakres lat do analizy. Wiemy, już że pierwszym miesiącem przekraczającym limit będzie miesiąc 'VII’ stąd możemy dodać prosty warunek, który zatrzyma nam dodawanie kolejnych wierszy ze zwiększającym się zużyciem kiedy zostanie on przekroczony.
rok = 2019 limit = 160000 for item in range(1,22): if item > 1 : limit +=1000 data_5_5.loc[item] = data_5_5.iloc[item-1]*1.01 data_5_5['rok'].loc[item]=int(rok+item) if data_5_5['VII'].loc[item] > limit: print (data_5_5.loc[item]) break print(limit)
W wyniku otrzymamy informację, że pierwszym rokiem po inwestycji będzie rok 2035, a przekroczy on limit 175000 m3.
Podsumowanie
Wyniki każdego z zadań na maturze należy podać w postaci pliku wynik5.txt który ostatecznie powinien wyglądać tak, dodatkowo należy dodać obrazek z wykresem do zadania 5.4:
1 tabela z zadania 5.1 2 tabela z zadania 5.2 3 tabela z zadania 5.3 4 lipiec 2026
5
lipiec 2035