Edycja konfiguracji JSON
Treść zadania
Plik konfiguracyjny w formacie JSON zawiera obiekt (w Pythonie: słownik), w którym mogą być zagnieżdżone kolejne obiekty. Wczytaj ścieżkę pliku, klucz i nową wartość. Klucz jest zapisany w notacji kropkowej: baza.port oznacza klucz port wewnątrz obiektu zapisanego pod kluczem baza.
Klucz istnieje, jeśli każda jego część poza ostatnią prowadzi do obiektu, a ostatnia część jest kluczem w tym obiekcie. Jeśli klucz istnieje:
- wypisz jego dotychczasową wartość,
- ustaw nową wartość — jako liczbę całkowitą, jeśli wczytany napis składa się z samych cyfr, ewentualnie poprzedzonych znakiem
-(np.8080,-5); w przeciwnym razie jako napis (np.3.5,true,localhost), - zapisz cały plik od nowa poleceniem
json.dump(dane, plik, indent=2, ensure_ascii=False).
Dzięki takiemu zapisowi plik ma wcięcia po 2 spacje, klucze zostają w dotychczasowej kolejności, a polskie litery nie są zamieniane na kody \u…. Sprawdzarka porównuje plik po zmianie dokładnie z tym formatem (ignoruje tylko końcowe spacje i puste wiersze).
Dane wejściowe
- 1. linia: ścieżka pliku
- 2. linia: klucz w notacji kropkowej
- 3. linia: nowa wartość
Dane wyjściowe
- Dotychczasowa wartość klucza: napis bez cudzysłowów, liczba jako liczba.
Brak klucza: K— gdzieKto wczytany klucz — jeśli klucz nie istnieje. Plik pozostaje wtedy bez zmian.Plik nie istnieje.— jeśli podana ścieżka nie wskazuje istniejącego pliku.
Ograniczenia
- Plik zawiera poprawny JSON, którego główną wartością jest obiekt.
- Wartość pod istniejącym kluczem jest napisem albo liczbą całkowitą. Pozostałe wartości w pliku mogą być dowolne (listy,
true,null…). - Części klucza nie zawierają kropek.
Uwagi
- Moduł
jsonzamienia tekst JSON na słowniki, listy, napisy i liczby Pythona i z powrotem:
import json
with open("config.json", encoding="utf-8") as plik:
dane = json.load(plik) # np. {"baza": {"port": 5432}}
dane["baza"]["port"] = 6543
with open("config.json", "w", encoding="utf-8") as plik:
json.dump(dane, plik, indent=2, ensure_ascii=False)
- Do zagnieżdżonego obiektu dojdziesz pętlą po
klucz.split("."): w każdym kroku sprawdź, czy bieżąca wartość jest słownikiem (isinstance(obiekt, dict)) i czy zawiera kolejną część klucza.
Przykłady
config.json{ "nazwa": "Sklep", "baza": { "host": "localhost", "port": 5432 }, "wersja": "1.0" }
config.json baza.port 6543
5432
config.json{ "nazwa": "Sklep", "baza": { "host": "localhost", "port": 6543 }, "wersja": "1.0" }
config.json{"nazwa": "Sklep", "baza": {"host": "localhost"}}
config.json baza.port 6543
Brak klucza: baza.port
config.json{"nazwa": "Sklep", "baza": {"host": "localhost"}}
W obiekcie baza nie ma klucza port, więc plik się nie zmienia.
Potrzebujesz teorii?
Zasady obowiązujące w rozdziale 20
Poniższe zadania polegają na wczytywaniu danych ze standardowego wejścia (stdin), wykonywaniu operacji na plikach i folderach oraz wypisywaniu wyniku na standardowe wyjście (stdout).
Każde zadanie jest osobnym, niezależnym programem.
Konwencje wspólne:
- Program działa na plikach w katalogu roboczym, czyli w folderze, w którym jest uruchamiany. Wszystkie ścieżki na wejściu są względne wobec katalogu roboczego i używają
/jako separatora, np.dane/raport.txt. Ścieżki wczytuj jako całe linie — mogą zawierać spacje. - Sprawdzarka przed każdym testem tworzy nowy katalog roboczy z plikami opisanymi w teście, uruchamia program, a potem sprawdza zarówno wypisany tekst, jak i zawartość plików.
- W przykładach Pliki przed: pokazuje zawartość katalogu roboczego przed uruchomieniem programu, a Pliki po: — stan wybranych plików po jego zakończeniu. Każda linia to ścieżka pliku, a linie zaczynające się od
|to kolejne wiersze jego treści. Ścieżka zakończona/to pusty folder,(rozmiar: N B)oznacza plik o rozmiarze N bajtów, a(usunięty)— plik, którego po zakończeniu programu ma już nie być. - Pliki tekstowe są zapisane w kodowaniu UTF-8 — otwieraj je przez
open(sciezka, encoding="utf-8"). - Rozszerzenie to końcówka nazwy pliku od ostatniej kropki (razem z nią), np.
archiwum.tar.gzma rozszerzenie.gz. Rozszerzenia porównuj bez względu na wielkość liter (.TXTto też.txt). - Listy plików wypisuj po jednym w linii, jako ścieżki względem podanego folderu z separatorem
/(np.2024/raport.txt), posortowane rosnąco tak, jak sortuje napisy funkcjasorted(). Na Windowsie ścieżki mają separator\— zamień go na/(np. metodąPath.as_posix()). - Komunikaty dla przypadków brzegowych wypisuj dokładnie w podanej postaci, np.
Folder nie istnieje.,Plik nie istnieje.,Brak plików. - Program nie wypisuje komunikatów typu „Podaj ścieżkę:”. Tekst podany w
input("…")jest ignorowany przez sprawdzarkę.
Zadanie pochodzi z otwartego zbioru Nauka-Programowania (z rozwiązaniami wzorcowymi). Zgłoś błąd w treści lub testach.
Przywrócono Twój zapisany kod.
Python uruchomi się w przeglądarce przy pierwszym teście.
Kod zapisuje się automatycznie w tej przeglądarce. Tab wstawia wcięcie; aby opuścić edytor klawiaturą, naciśnij Esc, a potem Tab.
Testy
Program dostaje „Wejście” przez input() i musi wypisać „Oczekiwane wyjście”. Liczby porównywane są z tolerancją 0,01, a tekst podany w input("…") nie jest sprawdzany.
Test 1
Nie uruchomionoserwer.json serwer.port 8080
80
serwer.json{"serwer": {"adres": "0.0.0.0", "port": 80}, "debug": true}
serwer.json{ "serwer": { "adres": "0.0.0.0", "port": 8080 }, "debug": true }
Test 2
Nie uruchomionoustawienia.json motyw jasny
ciemny
ustawienia.json{ "jezyk": "pl", "motyw": "ciemny" }
ustawienia.json{ "jezyk": "pl", "motyw": "jasny" }
Test 3
Nie uruchomionoczujnik.json temperatura.min -5
0
czujnik.json{"nazwa": "termometr", "temperatura": {"min": 0, "max": 30}}
czujnik.json{ "nazwa": "termometr", "temperatura": { "min": -5, "max": 30 } }
Test 4
Nie uruchomionoapp.json wersja 3.5
3.4
app.json{"wersja": "3.4", "autor": "Ola"}
app.json{ "wersja": "3.5", "autor": "Ola" }
Test 5
Nie uruchomionoprofil.json autor.imię Żaneta
Łukasz
profil.json{"powitanie": "Cześć", "autor": {"imię": "Łukasz", "tagi": ["a", "b"]}}
profil.json{ "powitanie": "Cześć", "autor": { "imię": "Żaneta", "tagi": [ "a", "b" ] } }
Test 6
Nie uruchomionogra.json poziomy.latwy.czas brak
120
gra.json{"poziomy": {"latwy": {"wrogowie": 3, "czas": 120}}, "dzwiek": null}
gra.json{ "poziomy": { "latwy": { "wrogowie": 3, "czas": "brak" } }, "dzwiek": null }
Test 7
Nie uruchomionoconfig.json baza.uzytkownik admin
Brak klucza: baza.uzytkownik
config.json{"baza": {"host": "localhost"}}
config.json{"baza": {"host": "localhost"}}
Test 8
Nie uruchomionoconfig.json baza.port.numer 1
Brak klucza: baza.port.numer
config.json{"baza": {"port": 5432}}
config.json{"baza": {"port": 5432}}
Test 9
Nie uruchomionoconfig.json baza 1
Plik nie istnieje.
inne.json{}
config.json