Kurzusok
/
Python
Python
/
Feladatok
/
Kártyajátékok
Kártyajátékok

Kártyajátékok

Tanulófeladat

Bevezetés

A list elemek sorozatából álló, módosítható gyűjtemény. A legtöbb gyűjteményhez hasonlóan (lásd a beépített tuple, dict és set típusokat), a listák bármilyen (vagy akár többféle) adattípusra tárolhatnak hivatkozást, beleértve más listákat is. Ahogy bármelyik sorozatnél, az elemek balról a 0-based index számmal, jobbról a -1-based index számmal érhetők el. A listák egészben vagy részben is másolhatók szeleteléssel vagy a <list>.copy() metódussal.

A listák a közös és a módosító sorozatműveleteket is támogatják, például a min()/max(), <list>.index(), <list>.append() és <list>.reverse() metódusokat. A listák elemein a for item in <list> szerkezettel lehet végigiterálni. A for index, item in enumerate(<list>) szerkezet akkor hasznos, ha az elem indexére és értékére is szükséged van.

A háttérben a lists dinamikus tömbökként vannak megvalósítva, hasonlóan a Java ArrayList típusához, és leggyakrabban hasonló adatok (stringek, számok, halmazok stb.) ismeretlen hosszúságú csoportjainak tárolására használják őket. A listák rendkívül rugalmas és hasznos adatszerkezetek, és a Python számos beépített metódusa és művelete listát ad eredményül.

Létrehozás

A list literálként hozható létre szögletes [] zárójelekkel és az elemek közötti vesszőkkel:

>>> no_elements = []

>>> no_elements
[]

>>> one_element = ["Guava"]

>>> one_element
['Guava']

>>> elements_separated_with_commas = ["Parrot", "Bird", 334782]

>>> elements_separated_with_commas
['Parrot', 'Bird', 334782]

Az olvashatóság érdekében sortöréseket is használhatsz, ha sok elem vagy egy list-en belül egymásba ágyazott adatszerkezet van:

>>> lots_of_entries = [
      "Rose",
      "Sunflower",
      "Poppy",
      "Pansy",
      "Tulip",
      "Fuchsia",
      "Cyclamen",
      "Lavender"
   ]
   
>>> lots_of_entries
['Rose', 'Sunflower', 'Poppy', 'Pansy', 'Tulip', 'Fuchsia', 'Cyclamen', 'Lavender']

# Each data structure is on its own line to help clarify what they are.
>>> nested_data_structures = [
      {"fish": "gold", "monkey": "brown", "parrot": "grey"},
      ("fish", "mammal", "bird"),
      ['water', 'jungle', 'sky']
   ]
   
>>> nested_data_structures
[{'fish': 'gold', 'monkey': 'brown', 'parrot': 'grey'}, ('fish', 'mammal', 'bird'), ['water', 'jungle', 'sky']]

A list() konstruktor használható üresen, vagy argumentumként egy iterálható objektummal. A konstruktor végigmegy az iterálható elemeken, és sorban hozzáadja őket a list-hez:

>>> no_elements = list()

>>> no_elements
[]

# The tuple is unpacked and each element is added.
>>> multiple_elements_from_tuple = list(("Parrot", "Bird", 334782))

>>> multiple_elements_from_tuple
['Parrot', 'Bird', 334782]

# The set is unpacked and each element is added.
>>> multiple_elements_from_set = list({2, 3, 5, 7, 11})

>>> multiple_elements_from_set
[2, 3, 5, 7, 11]

A list konstruktor string-gel vagy dict-tel való használata meglepő eredményt adhat:

# String elements (Unicode code points) are iterated through and added *individually*.
>>> multiple_elements_string = list("Timbuktu")

>>> multiple_elements_string
['T', 'i', 'm', 'b', 'u', 'k', 't', 'u']

# Unicode separators and positioning code points are also added *individually*.
>>> multiple_code_points_string = list('अभ्यास')

>>> multiple_code_points_string
['अ', 'भ', '्', 'य', 'ा', 'स']

# The iteration default for dictionaries is over the keys, so only key data is inserted into the list.
>>> source_data = {"fish": "gold", "monkey": "brown"}

>>> multiple_elements_dict_1 = list(source_data)
['fish', 'monkey']

Mivel a list konstruktor csak iterálhatókat (vagy semmit) fogad el argumentumként, a nem iterálható objektumok típushibát dobnak. Ezért sokkal egyszerűbb egy egyelemű list-et a literál szintaxissal létrehozni.

# Numbers are not iterable, and so attempting to create a list with a number passed to the constructor fails.
>>> one_element = list(16)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

# Tuples *are* iterable, so passing a one-element tuple to the constructor does work, but it's awkward
>>> one_element_from_iterable = list((16,))

>>> one_element_from_iterable
[16]

Elemek elérése

A listán belüli elemek (valamint más sorozattípusok, például a str és a tuple elemei) 0-based index és zárójeles jelölés segítségével érhetők el. Az indexelés történhet left --> right irányban (nullától indulva) vagy right --> left irányban (-1-től indulva).

index balról ⟹






0
👇🏾
1
👇🏾
2
👇🏾
3
👇🏾
4
👇🏾
5
👇🏾
P y t h o n
👆🏾
-6
👆🏾
-5
👆🏾
-4
👆🏾
-3
👆🏾
-2
👆🏾
-1





⟸ index jobbról
>>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"]

# Oatmeal is at index 0 or index -4.
>>> breakfast_foods[0]
'Oatmeal'

>>> breakfast_foods[-4]
'Oatmeal'

# Eggs are at index -2 or 2
>>> breakfast_foods[-2]
'Eggs'

>>> breakfast_foods[2]
'Eggs'

# Toast is at -1
>>> breakfast_foods[-1]
'Toast'

A list-en belüli elemek egy szakasza szeleteléssel (<list>[start:stop]) érhető el. Egy szelet az index pozícióban lévő elemsorozat, ahol start <= index < stop. A szeletelés a „kivágott” elemek másolatát adja vissza, és nem módosítja az eredeti list-et.

A [start:stop:step] szintaxisban egy step paraméter is használható, hogy „átugorj” vagy szűrj bizonyos list elemeket (például a step értéke 2 esetén minden második elemet választja ki a tartományban):

>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"]

# If there is no step parameter, the step is assumed to be 1.
>>> middle_colors = colors[2:6]

>>> middle_colors
['Green', 'Yellow', 'Orange', 'Pink']

# If the start or stop parameters are omitted, the slice will
# start at index zero, and will stop at the end of the list.
>>> primary_colors = colors[::3]

>>> primary_colors
['Red', 'Yellow', 'Blue']

Munka listákkal

A beépített sum() függvény egy listán a lista összes számának összegét adja vissza:

>>> number_list = [1, 2, 3, 4]
>>> sum(number_list)
10

A lista hosszát a len() függvénnyel is megkaphatod:

>>> long_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
>>> len(long_list)
10

A listák többféleképpen is összefűzhetők:

# Using the plus + operator unpacks each list and creates a new list, but it is not efficient.
>>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"]

>>> new_via_concatenate
['George', 5, 'cat', 'Tabby']

# Likewise, using the multiplication operator * is the equivalent of using + n times.
>>> first_group = ["cat", "dog", "elephant"]
>>> multiplied_group = first_group * 3

>>> multiplied_group
['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant']

A listák iterátort biztosítanak, és ugyanúgy végig lehet rajtuk iterálni, mint más sorozattípusokon.

#  Looping through the list and printing out each element.
>>> colors = ["Orange", "Green", "Grey", "Blue"]

>>> for item in colors:
...     print(item)
...
Orange
Green
Grey
Blue

A loops és iterators részletesebb magyarázatáért dolgozd fel a loops fogalmat.

Utasítások

Elyse nagyon várja, hogy a közelgő vegasi útja során pókerezhessen (és más kártyajátékokat is játsszon). Mivel nagy rajongója az „önkövetésnek”, szeretne összeállítani néhány kis függvényt, amelyek segítenek neki a követési feladatokban, és a segítségedet kérte, hogy gondoljátok át őket együtt.

1. Pókerkörök követése

Elyse különösen szereti a pókert, és szeretné követni, hogy hány kört játszik, és hogy mely körök azok. Minden körnek saját száma van, és minden asztal mutatja az éppen játszott kör számát. Elyse kiválaszt egy asztalt, és leül játszani az első körét. Három kört tervez játszani.

Valósítsd meg a get_rounds(<round_number>) függvényt, amely megkapja az aktuális kör számát, és visszaad egyetlen list-et, amelyben az a kör és a következő kettő szerepel:

>>> get_rounds(27)
[27, 28, 29]

2. Az összes kör egy helyen

Elyse játszott néhány kört az első asztalnál, aztán szünetet tartott, és még néhány kört játszott egy második asztalnál ... de végül minden asztalhoz külön lista tartozott! Szeretné a két listát összeilleszteni, hogy minden pókerkört egy helyen követhessen.

Valósítsd meg a concatenate_rounds(<rounds_1>, <rounds_2>) függvényt, amely két listát kap, és visszaad egyetlen list-et, amely az első list összes körét tartalmazza, majd a második list összes körét:

>>> concatenate_rounds([27, 28, 29], [35, 36])
[27, 28, 29, 35, 36]

3. Korábbi körök megkeresése

Amikor néhány korábbi pókerkörről beszélgetnek, egy másik játékos megjegyzi, hogy kettő mennyire hasonlóan zajlott le. Elyse nem biztos benne, hogy ő játszotta-e azokat a köröket.

Valósítsd meg a list_contains_round(<rounds>, <round_number>) függvényt, amely két argumentumot kap: a lejátszott körök listáját és egy körszámot. A függvény True értéket ad vissza, ha a kör szerepel a lejátszott körök listájában, és False értéket, ha nem:

>>> list_contains_round([27, 28, 29, 35, 36], 29)
True

>>> list_contains_round([27, 28, 29, 35, 36], 30)
False

4. Kártyaértékek átlagolása

Elyse ki szeretne próbálni egy új játékot, amelynek a neve Black Joe. Hasonló a Black Jack-hez, ahol az a célod, hogy a kezedben lévő kártyák összege elérjen egy célértéket, de a Black Joe-ban az a cél, hogy a kártyaértékek átlaga 7 legyen. Az átlagot úgy kapod meg, hogy összeadod az összes kártyaértéket, majd az összeget elosztod a kézben lévő kártyák számával.

Valósítsd meg a card_average(<hand>) függvényt, amely visszaadja egy Black Joe-kéz kártyaértékeinek átlagát.

>>> card_average([5, 6, 7])
6.0

5. Alternatív átlagok

A Black Joe-ban a sebesség számít. Elyse megpróbál egy gyorsabb módot találni az átlag kiszámítására.

Két módot talált ki arra, hogy egy átlaghoz hasonló számot kapjon:

  • Vedd az első és az utolsó szám átlagát a kézben.
  • Használd a kéz mediánját (a középső kártyát).

Valósítsd meg az approx_average_is_average(<hand>) függvényt, amely megkapja a hand listát, benne a kezedben lévő kártyák értékeivel.

Add vissza a True értéket, ha a fent említett stratégiák közül az egyik or mindkettő olyan számot eredményez, amely egyenlő a tényleges átlaggal.

Megjegyzés: Minden kéz hossza páratlan, hogy könnyebb legyen megtalálni a mediánt.

>>> approx_average_is_average([1, 2, 3])
True

>>> approx_average_is_average([2, 3, 4, 8, 8])
True

>>> approx_average_is_average([1, 2, 3, 5, 9])
False

6. További átlagolási technikák

Az átlagolási kísérletének eredményein felbuzdulva Elyse azon gondolkodik, hogy vajon ugyanazt az eredményt adná-e a páros pozíciókon lévő kártyák átlaga, mint a páratlan pozíciókon lévő kártyák átlaga. Itt az idő egy újabb tesztfüggvényre!

Valósítsd meg az average_even_is_average_odd(<hand>) függvényt, amely egy Boolean értéket ad vissza arról, hogy a páros indexeken lévő kártyák átlaga megegyezik-e a páratlan indexeken lévő kártyák átlagával.

>>> average_even_is_average_odd([1, 2, 3])
True

>>> average_even_is_average_odd([1, 2, 3, 4])
False

7. Bónuszkör szabályai

A Black Joe-ban minden 11. kéz bónuszkéz, amelyre bónuszszabály vonatkozik: ha az utolsó húzott kártyád egy Jack, akkor megduplázod az értékét.

Valósítsd meg a maybe_double_last(<hand>) függvényt, amely megkap egy kezet, és ellenőrzi, hogy az utolsó kártya Jack-e (11). Ha az utolsó kártya Jack (11), duplázd meg az értékét, mielőtt visszaadod a kezet.

>>> hand = [5, 9, 11]
>>> maybe_double_last(hand)
[5, 9, 22]

>>> hand = [5, 9, 10]
>>> maybe_double_last(hand)
[5, 9, 10]
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Python Exercism

Készen állsz elkezdeni a(z) Kártyajátékok 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.