Kurzusok
/
Python
Python
/
Feladatok
/
Mecha-nassolás menedzsment
Mecha-nassolás menedzsment

Mecha-nassolás menedzsment

Tanulófeladat

Bevezetés

A Python dict osztálya számos hasznos metódust kínál a szótárakkal való munkához. Néhányat már bemutattunk a dicts fogalomban. Itt még néhányat átveszünk, valamint néhány technikát a szótárak bejárásához és módosításához.

A setdefault() használata a hibamentes beszúráshoz

A szótár fogalomban korábban már szó volt róla, hogy a .get(key, <default value>) visszaadja a meglévő value-t, vagy a default value-t, ha egy key nem található a szótárban, így elkerülve a KeyError-t. Ez jól működik olyan helyzetekben, amikor nem szeretnél külön hibakezelést, de nem bízhatsz abban, hogy a keresett key jelen lesz.

Hasonlóan „biztonságos” (KeyError nélküli) beszúráshoz használhatod a .setdefault(key, <default value>) metódust. A setdefault(key, <default value>) visszaadja a value-t, ha a key megtalálható a szótárban. Ha a kulcs nincs meg, akkor beszúrja a (key, default value) párt, és visszaadja a default value-t használatra.

>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}

# Looking for the value associated with key "Rock Brown".
# The key does not exist, so it is added with the default value, and the value is returned.
>>> palette_I.setdefault('Rock Brown', '#694605')
'#694605'

# The (key, default value) pair has now been added to the dictionary.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}

A fromkeys() használata szótár feltöltéséhez egy iterálható objektumból

Ha gyorsan fel akarsz tölteni egy szótárt különféle keys-ekkel és alapértelmezett értékekkel, a osztálymetódus fromkeys(iterable, <default value>) végigmegy a keys egy iterálható halmazán, és létrehoz egy új dict-et. Minden values a megadott default value-ra lesz állítva:

>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')

{'Grassy Green': 'fill in hex color here',
 'Purple Mountains Majesty': 'fill in hex color here',
 'Misty Mountain Pink': 'fill in hex color here'}

Szótári bejegyzések bejárása nézeteken keresztül

A .keys(), .values() és .items() metódusok a szótár iterálható nézeteit adják vissza.

Ezekkel a nézetekkel könnyedén végigmehetsz a bejegyzéseken anélkül, hogy módosítanád őket. A nézetek emellett dinamikusak: amikor a mögöttes szótári adatok megváltoznak, a kapcsolódó view object tükrözni fogja a változást:

>>> palette_I = {'Grassy Green': '#9bc400',
                 'Purple Mountains Majesty': '#8076a3',
                  'Misty Mountain Pink': '#f9c5bd'}

# Using .keys() returns a list of keys.
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])

# Using .values() returns a list of values.
>>> palette_I.values()
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])

# Using .items() returns a list of (key, value) tuples.
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])

# Views are dynamic.  Changing values in the dict changes all of the associated views.
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
>>> palette_I['Deep Red'] = '#932432'

>>> palette_I.values()
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])

>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])

>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])

Bővebben a .keys(), .values() és .items() metódusokról

A Python 3.7+ verzióiban a dicts megőrzik a bejegyzések beszúrási sorrendjét, ami First-in, First-out (FIFO) bejárást tesz lehetővé a .keys(), .values() vagy .items() használatakor.

A Python 3.8+ verzióiban a nézetek megfordíthatók is. Ez lehetővé teszi, hogy a kulcsokat, értékeket vagy (key, value) párokat Last-in, First-out (LIFO) sorrendben járjuk be a reversed(<dict>.keys()), reversed(<dict>.values()) vagy reversed(<dict>.items()) segítségével:

>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}

# Iterating in insertion order (First in, first out)
>>> for item in palette_II.items():
...     print(item)
...
('Factory Stone Purple', '#7c677f')
('Green Treeline', '#478559')
('Purple baseline', '#161748')


# Iterating in the reverse direction. (Last in, first out)
>>> for item in reversed(palette_II.items()):
...    print (item)
...
('Purple baseline', '#161748')
('Green Treeline', '#478559')
('Factory Stone Purple', '#7c677f')

Szótár rendezése

A szótáraknak nincs beépített rendezési metódusuk. Viszont egy dict nézet rendezhető a beépített sorted() függvénnyel és a dict.items() metódussal. A rendezett nézet ezután felhasználható egy új szótár létrehozásához. A bejáráshoz hasonlóan az alapértelmezett rendezés a szótár keys szerint történik.

# Default ordering for a dictionary is insertion order (First in, first out).
>>> color_palette = {'Grassy Green': '#9bc400', 
                    'Purple Mountains Majesty': '#8076a3', 
                    'Misty Mountain Pink': '#f9c5bd', 
                    'Factory Stone Purple': '#7c677f', 
                    'Green Treeline': '#478559', 
                    'Purple baseline': '#161748'}
 
 
# The default sort order for a dictionary uses the keys.
>>> sorted_palette = dict(sorted(color_palette.items()))
>>> sorted_palette
{'Factory Stone Purple': '#7c677f',
 'Grassy Green': '#9bc400',
 'Green Treeline': '#478559',
 'Misty Mountain Pink': '#f9c5bd',
 'Purple Mountains Majesty': '#8076a3',
 'Purple baseline': '#161748'}

Szótárak összefésülése a .update() metódussal

A <dict_one>.update(<dict_two>) két szótár összefésülésére használható. Ez a metódus veszi a <dict_two> (key,value) párjait, és beírja őket a <dict_one>-ba:

>>> palette_I = {'Grassy Green': '#9bc400',
                 'Purple Mountains Majesty': '#8076a3',
                  'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
                  'Green Treeline': '#478559',
                  'Purple Baseline': '#161748'}

>>> palette_I.update(palette_II)

# Note that new items from palette_II are added.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}

Ahol a két szótár kulcsai átfedésben vannak, a dict_one value-ját felülírja a dict_two megfelelő value-ja:

>>> palette_I =   {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 
                   'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
>>> palette_III = {'Grassy Green': (155, 196, 0), 'Purple Mountains Majesty': (128, 118, 163),
                   'Misty Mountain Pink': (249, 197, 189)}
>>> palette_I.update(palette_III)

# Overlapping values in palette_I are replaced with values from palette_III
>>> palette_I
{'Grassy Green': (155, 196, 0),
  'Purple Mountains Majesty': (128, 118, 163), 
  'Misty Mountain Pink': (249, 197, 189), 
  'Factory Stone Purple': '#7c677f', 
  'Green Treeline': '#478559', 'Purple baseline': '#161748'}

Szótárak egyesítése vagy frissítése a union (| és |=) operátorokkal

A Python 3.9 egy másik módot vezet be a dicts egyesítésére: a union operátorokat. A dict_one | dict_two egy új szótárat hoz létre, amely a dict_one és dict_two (key, value) párjaiból áll. Amikor mindkét szótár osztozik kulcsokon, a dict_two értékei élveznek elsőbbséget.

>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
>>> new_dict = palette_I | palette_II
>>> new_dict
...
{'Grassy Green': '#9bc400',
 'Purple Mountains Majesty': '#8076a3',
 'Misty Mountain Pink': '#f9c5bd',
 'Factory Stone Purple': '#7c677f',
 'Green Treeline': '#478559',
 'Purple baseline': '#161748'}

A dict_one |= other hasonlóan viselkedik, mint a <dict_one>.update(<other>), de ebben az esetben az other lehet dict vagy (key, value) párok iterálható halmaza:

>>> palette_III = {'Grassy Green': (155, 196, 0),
                   'Purple Mountains Majesty': (128, 118, 163),
                   'Misty Mountain Pink': (249, 197, 189)}
>>> new_dict |= palette_III
>>> new_dict
...
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}

A szótárak és a velük való munkához használt metódusok részletes leírásához a hivatalos útmutató és a hivatalos könyvtári referencia kiváló kiindulópont.

A Real Python és a Finxter is nagyon részletes cikkekkel rendelkezik a Python szótárakról.

Utasítások

A Mecha Munch™, egy élelmiszerbevásárlást automatizáló cég, épp most vett fel, hogy a rendelési alkalmazásukon dolgozz. A csapatod feladata, hogy elkészítsen egy MVP-t (minimálisan működőképes termék), amely a bevásárlókosár minden alapvető műveletét kezeli, így a felhasználók hozzáadhatják, eltávolíthatják és rendezhetik a bevásárlásaikat. Szerencsére a pénzzel és a fizetéssel kapcsolatos funkciókat egy másik csapat kezeli!

1. Tételek hozzáadása a felhasználó bevásárlókosarához

Az MVP tegye lehetővé, hogy a felhasználó tételeket adjon a bevásárlókosarához. Ez lehet egyetlen tétel vagy egyszerre több tétel is. Mivel ez egy MVP, a tétel mennyiségét az ismétlődések jelzik. Ha a felhasználó 2 Oranges-t szeretne hozzáadni, az 'Oranges' kétszer fog szerepelni a bemeneti iterálhatóban. Ha a felhasználó kosarában már szerepel a tétel, a kosárban lévő mennyiséget 1-gyel kell növelni. Ha a tétel új a kosárban, akkor 1-es mennyiséggel kell hozzáadni.

Hozd létre az add_item(<current_cart>, <items_to_add>) függvényt, amely argumentumként egy kosárszótárat és bármilyen lista jellegű, hozzáadandó tételekből álló iterálhatót fogad. A függvény adjon vissza egy új/frissített bevásárlókosár-szótárat a felhasználónak.

>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
              ('Apple', 'Apple', 'Orange', 'Apple', 'Banana'))
{'Banana': 4, 'Apple': 5, 'Orange': 2}

>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
              ['Banana', 'Orange', 'Blueberries', 'Banana'])
{'Banana': 5, 'Apple': 2, 'Orange': 2, 'Blueberries': 1}

2. A felhasználó jegyzetalkalmazásában felsorolt tételek beolvasása

Hoppá. Úgy tűnik, a termékcsapat funkciótúltengésbe kezdett. Extra funkciókat szeretnének hozzáadni az MVP-hez. Az alkalmazásnak mostantól úgy kell bevásárlókosarat létrehoznia, hogy beolvassa a tételeket a felhasználó jegyzetalkalmazásából. Kényelmes a felhasználóknak, de kicsit több munka a csapatnak.

Hozd létre a read_notes(<notes>) függvényt, amely argumentumként bármilyen lista jellegű iterálhatót elfogad. A függvény dolgozza fel a tételeket, és hozzon létre egy felhasználói bevásárlókosarat/szótárat. Minden tételt 1-es mennyiséggel kell hozzáadni. Ezután az új felhasználói kosarat kell visszaadni.

>>> read_notes(('Banana','Apple', 'Orange'))
{'Banana': 1, 'Apple': 1, 'Orange': 1}

>>> read_notes(['Blueberries', 'Pear', 'Orange', 'Banana', 'Apple'])
{'Blueberries' : 1, 'Pear' : 1, 'Orange' : 1, 'Banana' : 1, 'Apple' : 1}

3. A receptek „ötletek” szakaszának frissítése

Az alkalmazásnak van egy „ötletek” szakasza, amely különféle konyhákból származó elkészült receptekkel van tele. A felhasználó kiválaszthatja ezek közül bármelyiket, és annak minden hozzávalója automatikusan a bevásárlókosarába kerül. A projektmenedzser megkért, hogy hozz létre egy módot ezeknek az „ötletek” recepteknek a szerkesztésére, mivel a tartalomcsapat folyamatosan változtatja a hozzávalókat és a mennyiségeket.

Hozd létre az update_recipes(<ideas>, <recipe_updates>) függvényt, amely argumentumként egy „ötletek” szótárat és egy receptfrissítésekből álló iterálhatót fogad. A függvény adja vissza az új/frissített „ötletek” szótárat.

>>>update_recipes(
    {'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
     'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}},
    (('Banana Bread', {'Banana': 4,  'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3}),)
    )
...

{'Banana Bread': {'Banana': 4, 'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3}, 
 'Raspberry Pie': {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}}

>>> update_recipes(
    {'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
    'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1},
    'Pasta Primavera': {'Eggs': 1, 'Carrots': 1, 'Spinach': 2, 'Tomatoes': 3, 'Parmesan': 2, 'Milk': 1, 'Onion': 1}},
    [('Raspberry Pie', {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2}),
    ('Pasta Primavera', {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1}),
    ('Blueberry Crumble', {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3})]
    )
...

{'Banana Bread': {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1}, 
 'Raspberry Pie': {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2}, 
 'Pasta Primavera': {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1},
 'Blueberry Crumble': {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3}}

4. A felhasználói kosár tételeinek rendezése

Miután a felhasználó elkezdett egy kosarat, az alkalmazás lehetővé teszi számára, hogy ábécésorrendbe rendezze a tételeit. Ez megkönnyíti a dolgok megtalálását, és segít az olyan adatbeviteli hibák esetén, mint amikor 'potatoes' és 'Potato' is szerepel az adatbázisban.

Hozd létre a sort_entries(<cart>) függvényt, amely argumentumként egy bevásárlókosarat/szótárat fogad, és visszaad egy új, ábécésorrendbe rendezettet.

>>> sort_entries({'Banana': 3, 'Apple': 2, 'Orange': 1})
{'Apple': 2, 'Banana':3, 'Orange': 1}

5. A felhasználói bevásárlókosár elküldése a boltba teljesítésre

Az alkalmazásnak el kell küldenie egy adott felhasználó kosarát a boltba teljesítésre. A bolt dolgozóinak azonban tudniuk kell, hogy a tétel melyik folyosón található, és hogy szükséges-e hűtés. Tehát (meglehetősen önkényesen) a „teljesítési kosarat” fordított ábécésorrendbe kell rendezni, a tételmennyiségeket pedig a helyszínre és a hűtésre vonatkozó információval együtt kell megadni.

Hozd létre a send_to_store(<cart>, <aisle_mapping>) függvényt, amely egy felhasználói bevásárlókosarat és egy szótárat fogad, amely minden tételhez tartalmazza a bolti folyosó számát és egy True/False értéket arról, hogy szükséges-e hűtés. A függvény return-nel adjon vissza egy összevont „teljesítési kosarat”, amely minden egyes megrendelt tételhez tartalmazza a mennyiséget, a folyosót és a hűtést. A tételek fordított ábécésorrendben jelenjenek meg.

>>> send_to_store({'Banana': 3, 'Apple': 2, 'Orange': 1, 'Milk': 2},
                  {'Banana': ['Aisle 5', False], 'Apple': ['Aisle 4', False], 'Orange': ['Aisle 4', False], 'Milk': ['Aisle 2', True]})
{'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]}

6. A bolti készlet frissítése, hogy tükrözze a felhasználó rendelését

Az alkalmazás nem adhat le vég nélkül vásárlói rendeléseket. Előbb-utóbb a boltból elfogynak a különféle termékek. Ezért az MVP-alkalmazásodnak frissítenie kell a bolti készletet minden alkalommal, amikor egy felhasználó elküldi a rendelését a boltba. Különben a vásárlók olyan termékeket rendelnek, amelyek valójában nem elérhetők.

Hozd létre az update_store_inventory(<fulfillment_cart>, <store_inventory>) függvényt, amely egy „teljesítési kosarat” és egy bolti készletet fogad. A függvény csökkentse a bolti készlet mennyiségeit a „teljesítési kosárban” szereplő „megrendelt” számmal, majd adja vissza a frissített bolti készletet. Ahol egy bolti tétel darabszáma 0-ra csökken, ott a darabszámot a 'Out of Stock' üzenettel kell helyettesíteni.

>>> update_store_inventory({'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]},
{'Banana': [15, 'Aisle 5', False], 'Apple': [12, 'Aisle 4', False], 'Orange': [1, 'Aisle 4', False], 'Milk': [4, 'Aisle 2', True]})

{'Banana': [12, 'Aisle 5', False], 'Apple': [10, 'Aisle 4', False], 'Orange': ['Out of Stock', 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True]}
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Python Exercism

Készen állsz elkezdeni a(z) Mecha-nassolás menedzsment feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Python nyelvet 17 fogalom146 feladat segítségével, valódi emberi mentorálással, mindez ingyen.