Commit 5cd783dc by Patryk Czarnik

Rozwiązania zadań sklep i logs

parent 3fe4731d
# Tylko na rozgrzewkę obliczenie dla jednego wybranego usera.
# Operujemy tutaj na "zwykłych zmiennych", bez słowników.
poczatek_sesji = 0
suma_czasow = 0
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
fields = line.strip().split(';')
username = fields[0]
action = fields[1]
time = int(fields[2])
if username == 'Adam':
if action == 'LOGIN':
poczatek_sesji = time
elif action == 'LOGOUT':
koniec_sesji = time
czas_sesji = koniec_sesji - poczatek_sesji
print(f'sesja user-1: {czas_sesji}')
suma_czasow += czas_sesji
print('a kuku, plik jest zamknięty')
print(f'Suma user-1: {suma_czasow}')
# Ta wersja na przykładzie dwóch userów ma wytłumaczyć, na czym będzie polegało zapisywanie danych poszczególnych userów w słowniku.
# W tej wersji używam dwóch par zmiennych, a za chwilę w wersji 2 będę miał zamiast tego dwa słowniki i w nich dane poszczególnych userów.
poczatek_sesji_user_1 = 0
suma_czasow_user_1 = 0
poczatek_sesji_user_2 = 0
suma_czasow_user_2 = 0
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
fields = line.strip().split(';')
username = fields[0]
action = fields[1]
time = int(fields[2])
if username == 'Adam':
if action == 'LOGIN':
poczatek_sesji_user_1 = time
elif action == 'LOGOUT':
koniec_sesji = time
czas_sesji = koniec_sesji - poczatek_sesji_user_1
print(f'sesja Adama: {czas_sesji}')
suma_czasow_user_1 += czas_sesji
if username == 'Bartek':
if action == 'LOGIN':
poczatek_sesji_user_2 = time
elif action == 'LOGOUT':
koniec_sesji = time
czas_sesji = koniec_sesji - poczatek_sesji_user_2
print(f'sesja Bartka: {czas_sesji}')
suma_czasow_user_2 += czas_sesji
print(f'Suma user-1: {suma_czasow_user_1}')
print(f'Suma user-2: {suma_czasow_user_2}')
# Ta wersja liczy już czasy dla wszystkich userów, używając dla każdego "algorytmu" podanego we wcześniejszych wersjach:
# - gdy widzimy początek sesji (LOGIN), zapisujemy czas początku sesji w słowniku poczatek_sesji
# - gdy widzimy koniec sesji (LOGOUT), to od bieżącego czasu odejmujemy zapamiętany wcześniej czas początku i mamy obliczony czas sesji. Dodajemy go do sumy.
poczatek_sesji = {}
suma_czasow = {}
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
fields = line.strip().split(';')
username = fields[0]
action = fields[1]
time = int(fields[2])
if action == 'LOGIN':
poczatek_sesji[username] = time
elif action == 'LOGOUT':
czas_sesji = time - poczatek_sesji[username]
print(f'koniec sesji {username:8}, czas sesji: {czas_sesji:5}')
if username not in suma_czasow:
suma_czasow[username] = 0
suma_czasow[username] += czas_sesji
for k, v in suma_czasow.items():
print(f'Suma sesji {k:8}: {v:6} s')
# Uproszczenie: wystarczy użyć jednego słownika i dla każdego usera pamiętać tylko jedną liczbę – od razu sumę.
# Korzystając z niniejszego matematycznego przekształcenia, możemy dojść do wniosku,
# że wystarczy początki sesji wpisywać ze znakiem ujemnym, a wszystko ładnie się zsumuje.
# suma = (kon1 - pocz1) + (kon2 - pocz2)
# suma = (-pocz1 + kon1) + (-pocz2 + kon2)
# suma = -pocz1 + kon1 + -pocz2 + kon2
# Jeśli użyjemy default_dict, będzie jeszcze mniej pisania
from collections import defaultdict
suma_czasow = defaultdict(int)
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
username, action, time_txt = line.strip().split(';')
time = int(time_txt)
if action == 'LOGIN':
suma_czasow[username] -= time
elif action == 'LOGOUT':
suma_czasow[username] += time
for k, v in sorted(suma_czasow.items()):
print(f'Suma sesji {k:8}: {v:6} s')
# Wersja podobna do v3, ale używająca wyrażeń regularnych do analizy linii pliku.
from collections import defaultdict
import re
pattern_login = re.compile(r'(.+);LOGIN;(\d+)')
pattern_logout = re.compile(r'(.+);LOGOUT;(\d+)')
suma_czasow = defaultdict(int)
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
match_login = pattern_login.match(line)
match_logout = pattern_logout.match(line)
if match_login:
username = match_login[1]
time = int(match_login[2])
print(f'LOGIN kto: {username} , czas: {time}')
suma_czasow[username] -= time
elif match_logout:
username = match_logout[1]
time = int(match_logout[2])
print(f'LOGOUT kto: {username} , czas: {time}')
suma_czasow[username] += time
print()
for k, v in suma_czasow.items():
print(f'Suma sesji {k:8}: {v:6} s')
# Jeszcze jedna wersja, aby pokazać względnie nową możliwość Pythona: przypisanie := , działające jako wyrażenie, do użycia w if lub while.
# ("assignment expression" / "named expression" / "walrus operator")
# Tak działa każde przypisanie w językach C, C++, Java, C# i od dawna toczyła się dyskusja, czy w Pythonie przypisanie też tak powinno działać.
# Ostatecznie w Pythonie 3.8 to wprowadzono, ale jako nowy operator, a działanie zwykłego = pozostało bez zmian.
from collections import defaultdict
import re
pattern_login = re.compile(r'(.+);LOGIN;(\d+)')
pattern_logout = re.compile(r'(.+);LOGOUT;(\d+)')
suma_czasow = defaultdict(int)
with open('logs.txt', mode='r', encoding='utf-8') as plik:
for line in plik:
if match_login := pattern_login.match(line):
username = match_login[1]
time = int(match_login[2])
print(f'LOGIN kto: {username} , czas: {time}')
suma_czasow[username] -= time
elif match_logout := pattern_logout.match(line):
username = match_logout[1]
time = int(match_logout[2])
print(f'LOGOUT kto: {username} , czas: {time}')
suma_czasow[username] += time
print()
for k, v in suma_czasow.items():
print(f'Suma sesji {k:8}: {v:6} s')
Adam;LOGIN;122
Halina;LOGIN;122
Ewa;LOGIN;206
Celina;LOGIN;308
Franek;LOGIN;367
Halina;LOGOUT;374
Franek;LOGOUT;432
Ewa;LOGOUT;540
Adam;LOGOUT;583
Adam;LOGIN;594
Grzegorz;LOGIN;638
Ewa;LOGIN;654
Ewa;LOGOUT;704
Adam;LOGOUT;766
Halina;LOGIN;783
Celina;LOGOUT;861
Ewa;LOGIN;971
Ewa;LOGOUT;1050
Janusz;LOGIN;1126
Dorota;LOGIN;1145
Bartek;LOGIN;1187
Bartek;LOGOUT;1258
Franek;LOGIN;1345
Bartek;LOGIN;1415
Adam;LOGIN;1508
Ewa;LOGIN;1610
Celina;LOGIN;1671
Grzegorz;LOGOUT;1688
Ewa;LOGOUT;1713
Grzegorz;LOGIN;1810
Adam;LOGOUT;1845
Halina;LOGOUT;1943
Grzegorz;LOGOUT;2063
Iza;LOGIN;2170
Janusz;LOGOUT;2255
Grzegorz;LOGIN;2289
Grzegorz;LOGOUT;2381
Adam;LOGIN;2454
Grzegorz;LOGIN;2527
Ewa;LOGIN;2539
Franek;LOGOUT;2573
Franek;LOGIN;2623
Franek;LOGOUT;2735
Bartek;LOGOUT;2796
Franek;LOGIN;2826
Grzegorz;LOGOUT;2836
Halina;LOGIN;2864
Ewa;LOGOUT;2954
Celina;LOGOUT;3024
Dorota;LOGOUT;3130
Bartek;LOGIN;3159
Janusz;LOGIN;3252
Grzegorz;LOGIN;3329
Bartek;LOGOUT;3339
Dorota;LOGIN;3359
Grzegorz;LOGOUT;3426
Iza;LOGOUT;3537
Ewa;LOGIN;3563
Ewa;LOGOUT;3585
Celina;LOGIN;3639
Bartek;LOGIN;3704
Janusz;LOGOUT;3785
Adam;LOGOUT;3827
Halina;LOGOUT;3900
Halina;LOGIN;3995
Adam;LOGIN;4018
Bartek;LOGOUT;4135
Dorota;LOGOUT;4195
Bartek;LOGIN;4256
Iza;LOGIN;4369
Celina;LOGOUT;4424
Adam;LOGOUT;4477
Iza;LOGOUT;4570
Celina;LOGIN;4628
Celina;LOGOUT;4738
Janusz;LOGIN;4846
Halina;LOGOUT;4940
Iza;LOGIN;5018
Grzegorz;LOGIN;5065
Halina;LOGIN;5124
Adam;LOGIN;5211
Dorota;LOGIN;5255
Ewa;LOGIN;5346
Celina;LOGIN;5349
Iza;LOGOUT;5443
Iza;LOGIN;5482
Grzegorz;LOGOUT;5519
Janusz;LOGOUT;5623
Iza;LOGOUT;5651
Celina;LOGOUT;5723
Bartek;LOGOUT;5800
Iza;LOGIN;5876
Janusz;LOGIN;5949
Janusz;LOGOUT;6042
Grzegorz;LOGIN;6118
Halina;LOGOUT;6194
Iza;LOGOUT;6291
Celina;LOGIN;6345
Franek;LOGOUT;6360
Franek;LOGIN;6370
Adam;LOGOUT;6441
Ewa;LOGOUT;6485
Celina;LOGOUT;6518
Franek;LOGOUT;6540
Grzegorz;LOGOUT;6643
Dorota;LOGOUT;6683
# Względem wersji 2:
# + menu z wyborem operacji
# + przechowywanie stanów magazynowych
# + operacje zmieniające dane w słowniku
# zwn sposób przechowywania danych w słowniku, zdecydowałem się rozdzielić operacje C i N (w treści zadania sugerowałem jedną wspólną operację)
menu = '''
Q - zakończ program
P - wypisz dostępne towary
K - wykonaj zakupy
N - zdefiniuj nowy towar
U - usuń towar z cennika
C - zmień cenę towaru
D - dostawa towaru'''
BELKA = '=' * 36
# Struktura słownika:
# nazwa: [cena, ilość]
towary = {
'pralka': [2200, 5],
'czajnik': [300, 10],
'odkurzacz': [420, 1],
'kabelek': [15, 100],
}
print('Witamy w naszym sklepie')
while True:
print(menu)
akcja = input('Wybierz polecenie: ').strip().upper()
if akcja == 'Q':
break
elif akcja == 'P':
print('Dostępne produkty:')
print(f'|{" nazwa":20}|{" cena":6}|{" ilość":6}|')
print(BELKA)
for nazwa, (cena, ilosc) in towary.items():
print(f'| {nazwa:19}|{cena:6}|{ilosc:6}|')
print(BELKA)
elif akcja == 'K':
suma = 0
while True:
nazwa = input('Podaj nazwę towaru lub naciśnij Enter, aby zakończyć: ')
if not nazwa:
break
if nazwa not in towary:
print(f'Nieznany towar {nazwa}')
continue
sztuki = int(input('Ile sztuk? '))
if sztuki > towary[nazwa][1]:
print(f'Nie ma tylu sztuk towaru. Jest tylko {towary[nazwa][1]}.')
continue
do_zaplaty = towary[nazwa][0] * sztuki
towary[nazwa][1] -= sztuki
print(f'Za {sztuki} sztuk towaru {nazwa} do zapłaty będzie {do_zaplaty}')
suma += do_zaplaty
print(f'Łącznie za cały koszyk do zapłaty: {suma}')
elif akcja == 'N':
nazwa = input('Podaj nazwę nowego towaru: ')
if nazwa in towary:
print('Taki towar już istnieje, przerywam')
continue
cena = int(input('Podaj cenę towaru: '))
towary[nazwa] = [cena, 0]
elif akcja == 'C':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
print(f'Obecna cena: {towary[nazwa][0]}')
cena = int(input('Podaj nową cenę towaru: '))
towary[nazwa][0] = cena
elif akcja == 'U':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
del towary[nazwa]
print('Towar usunięty')
elif akcja == 'D':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
print(f'Obecny stan magazynowy: {towary[nazwa][1]}')
zmiana = int(input('Podaj liczbę sztuk w dostawie: '))
towary[nazwa][1] += zmiana
else:
print('Nieznane polecenie')
print('Do widzenia')
# Względem wersji 3:
# * przechowywanie danych w pliku
# + operacje odczytu i zapisu pliku
menu = '''
Q - zakończ program
P - wypisz dostępne towary
R - wczytaj dane z pliku
W - zapisz dane do pliku
K - wykonaj zakupy
N - zdefiniuj nowy towar
U - usuń towar z cennika
C - zmień cenę towaru
D - dostawa towaru'''
SEP = ';'
PLIK = 'towary.csv'
towary = {}
print('Witamy w naszym sklepie')
while True:
print(menu)
akcja = input('Wybierz polecenie: ').strip().upper()
if akcja == 'Q':
break
elif akcja == 'P':
print('Dostępne produkty:')
print(f'| {"nazwa":19}|{" cena":6} |{" ilość":6} |')
print('=' * 38)
for nazwa, (cena, ilosc) in towary.items():
print(f'| {nazwa:19}|{cena:6} |{ilosc:6} |')
elif akcja == 'R':
with open(PLIK, 'r') as plik:
towary = {}
ile = 0
for linia in plik:
nazwa, cena, ilosc = linia.strip().split(SEP)
towary[nazwa] = [int(cena), int(ilosc)]
ile += 1
print(f'Wczytano dane {ile} towarów')
elif akcja == 'W':
with open(PLIK, 'w') as plik:
ile = 0
for nazwa, (cena, ilosc) in towary.items():
print(nazwa, cena, ilosc, sep=SEP, file=plik)
ile += 1
print(f'Zapisano dane {ile} towarów')
elif akcja == 'K':
suma = 0
while True:
nazwa = input('Podaj nazwę towaru lub naciśnij Enter, aby zakończyć: ')
if not nazwa:
break
if nazwa not in towary:
print(f'Nieznany towar {nazwa}')
continue
sztuki = int(input('Ile sztuk? '))
if sztuki > towary[nazwa][1]:
print(f'Nie ma tylu sztuk towaru. Jest tylko {towary[nazwa][1]}.')
continue
do_zaplaty = towary[nazwa][0] * sztuki
towary[nazwa][1] -= sztuki
print(f'Za {sztuki} sztuk towaru {nazwa} do zapłaty będzie {do_zaplaty}')
suma += do_zaplaty
print(f'Łącznie za cały koszyk do zapłaty: {suma}')
elif akcja == 'N':
nazwa = input('Podaj nazwę nowego towaru: ')
if nazwa in towary:
print('Taki towar już istnieje, przerywam')
continue
cena = int(input('Podaj cenę towaru: '))
towary[nazwa] = [cena, 0]
elif akcja == 'C':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
print(f'Obecna cena: {towary[nazwa][0]}')
cena = int(input('Podaj nową cenę towaru: '))
towary[nazwa][0] = cena
elif akcja == 'U':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
del towary[nazwa]
print('Towar usunięty')
elif akcja == 'D':
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
continue
print(f'Obecny stan magazynowy: {towary[nazwa][1]}')
zmiana = int(input('Podaj liczbę sztuk w dostawie: '))
towary[nazwa][1] += zmiana
else:
print('Nieznane polecenie')
print('Do widzenia')
# Względem wersji 4:
# * podział kodu na oddzielne funkcje
# * szerokość kolumny z nazwą dopasowana do max długości
# * możliwość podania alternatywnej nazwy pliku
menu = '''
Q - zakończ program
P - wypisz dostępne towary
R - wczytaj dane z pliku
W - zapisz dane do pliku
K - wykonaj zakupy
N - zdefiniuj nowy towar
U - usuń towar z cennika
C - zmień cenę towaru
D - dostawa towaru'''
SEP = ';'
PLIK = 'towary.csv'
def wybor_z_menu():
print(menu)
return input('Wybierz polecenie: ').strip().upper()
def wypisz_towary(towary):
width = max(len(nazwa) for nazwa in towary.keys()) if towary else 6
print('Dostępne produkty:')
print(f'| {"nazwa":{width}}|{" cena":6} |{" ilość":6} |')
print('=' * (width + 18))
for nazwa, (cena, ilosc) in towary.items():
print(f'| {nazwa:{width}}|{cena:6} |{ilosc:6} |')
def wczytaj_plik():
sciezka = zapytaj_o_plik()
with open(sciezka, 'r') as plik:
towary = {}
ile = 0
for linia in plik:
nazwa, cena, ilosc = linia.strip().split(SEP)
towary[nazwa] = [int(cena), int(ilosc)]
ile += 1
print(f'Wczytano dane {ile} towarów')
return towary
def zapisz_plik(towary):
sciezka = zapytaj_o_plik()
with open(sciezka, 'w') as plik:
ile = 0
for nazwa, (cena, ilosc) in towary.items():
print(nazwa, cena, ilosc, sep=SEP, file=plik)
ile += 1
print(f'Zapisano dane {ile} towarów')
def zapytaj_o_plik():
sciezka = PLIK
s = input(f'Podaj nazwę pliku lub naciśnij enter aby zatwierdzić domyślną ({sciezka}):')
if s:
sciezka = s
return sciezka
def nowy_towar(towary):
nazwa = input('Podaj nazwę nowego towaru: ')
if nazwa in towary:
print('Taki towar już istnieje, przerywam')
else:
cena = int(input('Podaj cenę towaru: '))
towary[nazwa] = [cena, 0]
def usun_towar(towary):
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
else:
del towary[nazwa]
print('Towar usunięty')
def zmien_cene_towaru(towary):
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
else:
print(f'Obecna cena: {towary[nazwa][0]}')
cena = int(input('Podaj nową cenę towaru: '))
towary[nazwa][0] = cena
def zakupy(towary):
suma = 0
while True:
nazwa = input('Podaj nazwę towaru lub naciśnij Enter, aby zakończyć: ')
if not nazwa:
break
if nazwa not in towary:
print(f'Nieznany towar {nazwa}')
continue
sztuki = int(input('Ile sztuk? '))
if sztuki > towary[nazwa][1]:
print(f'Nie ma tylu sztuk towaru. Jest tylko {towary[nazwa][1]}.')
continue
do_zaplaty = towary[nazwa][0] * sztuki
towary[nazwa][1] -= sztuki
print(f'Za {sztuki} sztuk towaru {nazwa} do zapłaty będzie {do_zaplaty}')
suma += do_zaplaty
print(f'Łącznie za cały koszyk do zapłaty: {suma}')
def dostawa(towary):
nazwa = input('Podaj nazwę istniejącego towaru: ')
if nazwa not in towary:
print('Taki towar nie istnieje, przerywam')
else:
print(f'Obecny stan magazynowy: {towary[nazwa][1]}')
zmiana = int(input('Podaj liczbę sztuk w dostawie: '))
towary[nazwa][1] += zmiana
def main():
print('Witamy w naszym sklepie')
towary = {}
while True:
akcja = wybor_z_menu()
if akcja == 'Q':
break
elif akcja == 'P':
wypisz_towary(towary)
elif akcja == 'R':
towary = wczytaj_plik()
elif akcja == 'W':
zapisz_plik(towary)
elif akcja == 'K':
zakupy(towary)
elif akcja == 'N':
nowy_towar(towary)
elif akcja == 'C':
zmien_cene_towaru(towary)
elif akcja == 'U':
usun_towar(towary)
elif akcja == 'D':
dostawa(towary)
else:
print('Nieznane polecenie')
print('Do widzenia')
if __name__ == '__main__':
main()
pralka;2500;5
odkurzacz;444;1
suszarka;350;3
bateria AA;4;100
czajnik;200;15
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment