"""
Książka kontaktowa
Naszym zadaniem jest przygotowanie działającej w terminalu aplikacji przechowującej dane kontaktowe.
Na tym etapie przyjmujemy, że nazwy kontaktu ( imie z nazwiskiem, pseudonim etc) są unikalne -
możemy więc użyć ich jako kluczy w słowniku. Sugerowana struktura danych wyglądałaby tak:
kontakty = {
"Bob" : "[email protected]",
"Ada" : "FB_id: 78934759834",
}
Podstawa
W opcji minimum powinniśmy przygotować interfejs tekstowy działający w pętli nieskończonej. W tej
postaci nie musi on jeszcze czegokolwiek innego robić - ma się jedynie poprawnie wyświetlać i dawać
użytkownikowi szansę na wpisanie wyboru.
Wersja 1
W pierwszej wersji funkcjonalnej należy dodać możliwość dodawania kontaktów i wydruk wszystkich
kontaktów.
Wersja 2
Następnym krokiem byłoby dodanie pozostałej funkcjonalności - w większości będzie ona bazowała
na tym co jest w wersji 1. Na tym etapie mamy tzw. MVP - minimum viable product.
Wersja 3
Mając bazowy produkt warto się zastanowić co może pójść w trakcie korzystania z aplikacji nie tak.
Warto obsłużyć takie sytuacje - np. gdy użytkownik spróbuje usunąć kontakt który nie istnieje należy
to sprawdzić - i jeśli faktycznie kontaktu nie ma wyświetlić odpowiedni komunikat bez podejmowania
próby usunięcia wpisu (co “wywaliłoby” nasz program).
Kosmetyka
Tu możemy się zająć tym jak wyświetlić poszczególne wybory menu w bardziej przyjazny dla odbiorcy
sposób np. wybierając opcję “Wyświetl całą książkę z kontaktami” fajnie jeśli użytkownik otrzyma nie
po prostu wydruk słownika, tylko np. nazwę, poniżej danej kontaktowe, poniżej jakieś rozdzielenie (np.
serię *), po czym następny kontakt.
kontakty = {
"Bob" : "[email protected]",
"Ada" : "FB_id: 78934759834",
}
Przechowywanie kontaktów
W naszej aplikacji do kontaktów dodajcie pozycje menu do wczytywania książki z pliku i zapisywanie
do niego.
Nie kombinujcie z trybem “a” - czyli append. Wczytujcie całą zawartość pliku w trybie “r” i z pomocą
biblioteki json zamieniajcie ją na obiekt z którego możecie korzystać w Pythonie (zakładam, że jest to
słownik).
Z kolei przy zapisie danych nadpisujcie cały plik zaktualizowaną zawartością (czyli skorzystajcie z trybu
“w”).
Pomyślcie nad dodaniem automatycznego wczytania kontaktów przy starcie aplikacji. Z kolei przy jej
zamykaniu może warto zapytać osoby z niej korzystającej czy chce zapisać zmiany?
"""
import json
import os
SCIEZKA_FOLDERU = "data"
SCIEZKA_PLIKU = os.path.join(SCIEZKA_FOLDERU, "kontakty.json")
# czy folder istnieje?
os.makedirs(SCIEZKA_FOLDERU, exist_ok=True)
# jesli plik nie istnieje tworzymy go z pustym slownikiem
if not os.path.exists(SCIEZKA_PLIKU):
with open(SCIEZKA_PLIKU, "w", encoding="utf-8") as f:
json.dump({}, f, ensure_ascii=False, indent=4)
# ladujemy dane z pliku do zmiennej 'kontakty':
with open(SCIEZKA_PLIKU, "r", encoding="utf-8") as f:
try:
kontakty = json.load(f)
except json.JSONDecodeError:
kontakty = {}
def zapisz_kontakty():
with open(SCIEZKA_PLIKU, "w", encoding="utf-8") as f:
json.dump(kontakty, f, ensure_ascii=False, indent=4)
while True:
print()
print("Wybierz operację do wykonania:")
print(" 1 - dopisanie pozycji do książki")
print(" 2 - aktualizacja pozycji książki")
print(" 3 - usunięcie pozycji książki")
print(" 4 - wydruk imion z książki")
print(" 5 - wydruk całej książki z kontaktami")
print(" 6 - koniec programu")
wybor = input("Podaj kod operacji = ")
if wybor == "6":
wybor = input("Jeśli chcesz zapisać zmiany i wyjść z programu wybierz 't': ")
if wybor == 't':
zapisz_kontakty()
print()
print("Zapisano zmiany i zamknieto program.")
break
elif wybor == "1":
nazwa_kontaktu = input("Podaj nazwę kontaktu: ").strip()
if nazwa_kontaktu in kontakty:
print("Podany kontakt już istnieje. Użyj opcji aktualizacji!")
else:
dane_kontaktu = input("Podaj dane kontaktowe, np.numer telefonu, adres email: ").strip()
kontakty[nazwa_kontaktu] = dane_kontaktu
zapisz_kontakty()
print(f"Kontakt {nazwa_kontaktu} o danych {dane_kontaktu} został dodany do listy kontaktów!")
print()
print(f"Obecnie w książce kontaktowej jest {len(kontakty)} kontaktów.")
elif wybor == "2":
print("Aktualizacja pozycji książki")
aktualizacja_pozycji = input("Jeśli chcesz zaktualizować nazwę, pod którą jest zapisany kontakt wciśnij 'n'. Jeśli chcesz zaktualizować dane kontaktu wcisnij 'd'.").strip().lower()
if aktualizacja_pozycji == "n":
print("Aktualizujemy nazwę kontaktu.")
stara_nazwa = input("Podaj nazwę kontaktu do zmiany: ").strip()
znaleziony_kontakt = None
for nazwa in kontakty:
if nazwa.lower() == stara_nazwa.lower():
znaleziony_kontakt = nazwa
break
if not znaleziony_kontakt:
print(f"Kontakt o podanej nazwie {stara_nazwa} nie istnieje!")
else:
nowa_nazwa = ''
while not nowa_nazwa:
nowa_nazwa = input("Podaj nową nazwę: ").strip()
if not nowa_nazwa:
print("Nowa nazwa nie może być pusta! Podaj nową nazwę.")
if nowa_nazwa in kontakty:
print(f"Kontakt o nazwie {nowa_nazwa} już istnije!")
else:
kontakty[nowa_nazwa] = kontakty.pop(znaleziony_kontakt)
zapisz_kontakty()
print(f"Nazwa kontaktu {znaleziony_kontakt} została zastąpiona przez {nowa_nazwa}")
elif aktualizacja_pozycji == "d":
print("Aktualizujemy dane kontaktu.")
szukany_kontakt = input("Podaj nazwę kontaktu, którego dane chcesz zaktualizować: ").strip()
znaleziony_kontakt = None
for nazwa_k in kontakty:
if nazwa_k.lower() == szukany_kontakt.lower():
znaleziony_kontakt = nazwa_k
break
if not znaleziony_kontakt:
print(f"Kontakt o podanej nazwie {szukany_kontakt} nie istnieje!")
else:
potwierdzenie_aktualizacji = input(f"Obecne dane kontaktowe: {kontakty[znaleziony_kontakt]}. Na pewno chcesz je zaktualizować? Jeśli tak wcisnij 't', jeśli nie, wciśnij 'n'.").strip().lower()
if potwierdzenie_aktualizacji == 't':
nowe_dane = ''
while not nowe_dane:
print(f"Aktualizujemy dane kontaktu: {kontakty[znaleziony_kontakt]}")
nowe_dane = input("Podaj nowe dane: ").strip()
if not nowe_dane:
print("Dane kontaktowe nie mogą być puste! Spróbuj ponownie.")
kontakty[znaleziony_kontakt] = nowe_dane
zapisz_kontakty()
print(f"Dane kontaktowe kontaktu '{znaleziony_kontakt}' zostały zaktualizowane.")
else:
print("Rezygnacja z aktualizacji danych. Powrót do menu głównego.")
else:
print("Nieprawidlowy wybór opcji. Wpisz 'n' (chcę zaktualizować nazwę kontaktu) albo 'd' (chcę zaktualizowac dane kontaktu)")
elif wybor == "3":
if not kontakty:
print("Książka kontaktowa jest pusta!")
else:
kontakt_do_usuniecia = input("Podaj nazwę kontaktu, który chcesz usunąć: ").strip()
znaleziony_kontakt = None
for nazwa in kontakty:
if nazwa.lower() == kontakt_do_usuniecia.lower():
znaleziony_kontakt = nazwa
break
if not znaleziony_kontakt:
print(f"Podany kontakt, {kontakt_do_usuniecia} nie istnieje! Upewnij się, że wpisaleś poprawną nazwę. ")
else:
potwierdzenie_usuniecia = input(f"Czy na pewno chcesz usunąć kontakt '{znaleziony_kontakt}'? (t/n): ").strip().lower()
if potwierdzenie_usuniecia == "t":
dane_do_usuniecia = kontakty.pop(znaleziony_kontakt)
zapisz_kontakty()
# del kontakty[znaleziony_kontakt] del usuwa kontakt i nie mozna juz nic z tym zrobic!
# .pop() usuwa kontakt i można go np. pokazać użytkownikowi, zapisać w logu albo przywrócić, jeśli ktoś się rozmyśli
print(f"Kontakt '{znaleziony_kontakt}': {dane_do_usuniecia} został usunięty.")
else:
print("Usunięcie anulowane. Powrót do menu głównego.")
elif wybor == "4":
print("=============== Imiona w książce kontaktowej: ==============")
if not kontakty:
print("Książka kontaktowa jest pusta!")
else:
print(f"Liczba imion w książce: {len(kontakty)}")
for i, key in enumerate(sorted(kontakty), start=1):
print(f"{i}. {key}")
elif wybor == "5":
if not kontakty:
print("Książka kontaktowa jest pusta!")
else:
print("Książka kontaktowa zawiera: ")
for nazwa_kontaktu, dane_kontaktu in kontakty.items():
print(f"Nazwa: {nazwa_kontaktu}")
print(f"Dane kontaktu: {dane_kontaktu}.")
print("*" * 30)
else:
print("Ups, coś poszlo nie tak!")