PythonPython · Chapterبەش 12 · Lectureوانە 12.2
Project: A Word-Scramble Gameپڕۆژیلە: یاریی پیتە تێکەڵەکان
Build a complete word game, Mixed Letters, step by step: word lists, random.shuffle(), functions that return values, input validation, a play-again loop, a clean quit with Ctrl+C, and tests with a fixed random seed.
یارییەکی وشەی تەواو، پیتە تێکەڵەکان، هەنگاو بە هەنگاو دروست بکە: وشە، random.shuffle()، دەگەڕێننەوە، ، بۆ دووبارە یاریکردن، وەستانی ئارام بە Ctrl+C و تاقیکردنەوە بە جێگیر.
What you will learnچی فێر دەبیت
- Plan a program with a scenario, a flowchart and a list of functions before writing code.
- Scramble a word with list(), random.shuffle() and join(), and avoid the two usual shuffle mistakes.
- Validate the player's input with loops and small checking functions.
- Join functions, return values (including None and tuples) and loops into one complete program.
- Test a program that uses random numbers with a fixed seed and assert.
- پێش نووسینی کۆد، بە ، و لیستی پلانی دابنێیت.
- وشەیەک بە list()، random.shuffle() و join() تێکەڵ بکەیت و خۆت لە دوو هەڵە باوەکەی تێکەڵکردن بپارێزیت.
- یاریزان بە و پشکنین پشتڕاست بکەیتەوە.
- ، (لەوانە None و ) و لە یەک تەواودا کۆ بکەیتەوە.
- کە بەکار دەهێنێت بە جێگیر و assert تاقی بکەیتەوە.
The project: Mixed Lettersپڕۆژیلەکە: پیتە تێکەڵەکان
You now know the main building blocks of Python: strings, loops, functions, lists and dictionaries. In this project you put them together in one complete program: a word game called Mixed Letters.
ئێستا بەردە سەرەکییەکانی دەناسیت: ، ، ، و . لەم هەموویان لە یەک تەواودا کۆ دەکەیتەوە: یارییەکی وشە بە ناوی Mixed Letters (پیتە تێکەڵەکان).
- The computer picks a word and shows its letters in a mixed order, for example
o y h n t p. - You have 3 tries to type the real word (
python). - Right on the first try: 3 points; second try: 2 points; third try: 1 point.
- After a wrong try you get a hint: the first letters of the word.
- A guess with the wrong length or with other letters is not counted as a try.
- One game has 5 different words. Then the game asks: play again?
- Type
quitat any time to stop.
- وشەیەک هەڵدەبژێرێت و پیتەکانی بە ڕیزێکی تێکەڵ پیشان دەدات، بۆ نموونە
o y h n t p. - 3 هەوڵت هەیە بۆ نووسینی وشە ڕاستەقینەکە (
python). - ڕاست لە هەوڵی یەکەمدا: 3 خاڵ؛ هەوڵی دووەم: 2 خاڵ؛ هەوڵی سێیەم: 1 خاڵ.
- دوای هەوڵێکی هەڵە سەرەداوێک وەردەگریت: پیتە سەرەتاییەکانی وشەکە.
- وەڵامێک کە درێژییەکەی هەڵە بێت یان پیتی تری تێدا بێت وەک هەوڵ ناژمێردرێت.
- هەر یارییەک 5 وشەی جیاوازی هەیە. پاشان یارییەکە دەپرسێت: دووبارە یاری دەکەیتەوە؟
- هەر کاتێک
quitبنووسە بۆ وەستان.
Letters: o o p l Your guess: pool Not this one. Hint: it starts with l Tries left: 2 Your guess: loop Correct! +2 points
We build the game in small steps. Each step is a short program that you can run and test before you go on.
یارییەکە بە هەنگاوی بچووک دروست دەکەین. هەر هەنگاوێک کورتە کە دەتوانیت پێش ئەوەی بڕۆیتە پێشەوە جێبەجێی بکەیت و تاقی بکەیتەوە.
The project: Mixed Lettersپڕۆژیلەکە: پیتە تێکەڵەکان
Anagrams and scrambled wordsanagram و وشەی تێکەڵکراو
An anagram is a word made by putting the letters of another word in a new order: listen → silent, loop → pool. Word games with letter tiles are built on this idea: you move the same letters around until a word appears.
anagram وشەیەکە کە بە ڕیزکردنەوەی پیتەکانی وشەیەکی تر دروست دەبێت: listen ← silent، loop ← pool. یارییە وشەییەکانی تەختەی پیت لەسەر ئەم بیرۆکەیە دروست کراون: هەمان پیتەکان دەجووڵێنیت تا وشەیەک دەردەکەوێت.
Our game does the opposite. It scrambles a word: it mixes the letters at random, so the result is usually not a real word (oyhntp). Your job is to find the original word again.
یارییەکەی ئێمە پێچەوانەکەی دەکات. وشەیەک تێکەڵ دەکات: پیتەکانی بە هەڵکەوت تێکەڵ دەکات، بۆیە ئەنجامەکە زۆرجار وشەیەکی ڕاستەقینە نییە (oyhntp). کاری تۆ ئەوەیە وشە بنەڕەتییەکە بدۆزیتەوە.
What the project practisesپڕۆژیلەکە ڕاهێنان لەسەر چی دەکات
A small game uses almost everything you learned in this course. The table shows which tool does which job; each link goes back to the lesson that teaches it.
یارییەکی بچووک نزیکەی هەموو ئەو شتانە بەکار دەهێنێت کە لەم کۆرسەدا فێری بوویت. خشتەکە پیشان دەدات کام ئامراز کام کار دەکات؛ هەر دەتباتەوە بۆ ئەو وانەیەی فێری دەکات.
| Job in the gameکار لە یارییەکەدا | Python toolئامرازی Python | Learn it inفێربوون لە |
|---|---|---|
| Choose words at randomهەڵبژاردنی وشە بە هەڵکەوت | random.sample() | Lesson: Modulesوانەی مۆدیوڵەکان |
| Keep the wordsهەڵگرتنی وشەکان | a list of strings | Lesson: Listsوانەی لیستەکان |
| Mix letters, read guessesتێکەڵکردنی پیت، خوێندنەوەی وەڵام | list(), .join(), .strip(), .lower() | Lesson: Stringsوانەی زنجیرەنووسەکان |
| Repeat tries and gamesدووبارەکردنەوەی هەوڵ و یاری | while, for, continue, break | Lesson: whileوانەی خولی while |
| Split the work into partsدابەشکردنی کار بۆ بەشەکان | def, return, None | Lesson: Functionsوانەی کردارەکان |
| Accept only good inputوەرگرتنی تەنها دروست | while True + return | Lesson: Validationوانەی پشتڕاستکردنەوە |
| Menu choices, two resultsهەڵبژاردنەکانی ، دوو ئەنجام | dict, tuple | Lesson: Dictionariesوانەی فەرهەنگەکان |
| Stop cleanly on Ctrl+Cوەستانی ئارام بە Ctrl+C | try / except | Lesson: Exceptionsوانەی هەڵاوێردەکان |
Plan before you codeپێش کۆدنووسین پلان دابنێ
Good projects start on paper. The planning method from Algorithms and flowcharts works here too: first a short scenario (the story of the program), then a flowchart, then the list of functions, and only then code.
لەسەر کاغەز دەست پێ دەکەن. ڕێگای پلاندانانی وانەی ئەلگۆریزمەکان و هێڵکارییەکانی ڕەوت لێرەشدا کار دەکات: سەرەتا کورت (چیرۆکی )، پاشان ، پاشان لیستی و ئینجا کۆد.
Plan before you codeپێش کۆدنووسین پلان دابنێ
A flowchart of one roundهێڵکارییەکی ڕەوت بۆ یەک گەڕ
The flowchart shows one round: one word, up to 3 tries. It uses the standard symbols: an oval for start and end, a rectangle for a step, a parallelogram for input and output, and a diamond for a yes/no question.
یەک گەڕ پیشان دەدات: یەک وشە، تا 3 هەوڵ. بەکار دەهێنێت: هێلکەیی بۆ دەستپێک و کۆتایی، لاکێشە بۆ هەنگاوێک، لاکێشەی لار بۆ و ، ئەڵماسی بۆ پرسیارێکی بەڵێ/نەخێر.
Look at the two arrows that go back up: they are the loop. The unfair-guess path goes back without changing tries, so it costs nothing. Every path that leaves the loop ends in a return: 0, None or the points.
سەیری ئەو دوو تیرە بکە کە بۆ سەرەوە دەگەڕێنەوە: ئەوان . ڕێگای وەڵامی ناڕەوا بەبێ گۆڕینی tries دەگەڕێتەوە، بۆیە هیچی تێ ناچێت. هەموو ڕێگایەک کە لە دەردەچێت بە returnـێک کۆتایی دێت: 0، None یان خاڵەکان.
Plan before you codeپێش کۆدنووسین پلان دابنێ
Split the game into functionsدابەشکردنی یارییەکە بۆ کردارەکان
Next, list the jobs and give each job its own function. A function that does one job is easy to read, to test and to change.
دواتر کارەکان بنووسە و هەر کارێک خۆی بدەرێ. کە یەک کار دەکات خوێندنەوە، تاقیکردنەوە و گۆڕینی ئاسانە.
Information travels through parameters and return values, never through global variables. play_round() returns its points and play_game() adds them up in its own local variable score. This keeps each function independent: you can test play_round() alone.
زانیاری لە ڕێگەی و دەگوازرێتەوە، هەرگیز لە ڕێگەی نا. play_round() خاڵەکانی دەگەڕێنێتەوە و play_game() لە خۆیدا بە ناوی score کۆیان دەکاتەوە. ئەمە هەر سەربەخۆ دەهێڵێتەوە: دەتوانیت play_round() بە تەنها تاقی بکەیتەوە.
Step 1: the word listsهەنگاوی 1: لیستەکانی وشە
The words live in two lists of strings. Their names are written in CAPITALS: in Python this tells other programmers that the value is a constant — set once at the top and never changed. The Kurdish words show that Python strings hold any Unicode letter.
وشەکان لە دوو دەژین. ناوەکانیان بە پیتی گەورە نووسراون: لە Pythonـدا ئەمە بە تر دەڵێت کە : یەک جار لە سەرەوە دادەنرێت و هەرگیز ناگۆڕێت. وشە کوردییەکان پیشان دەدەن کە هەر پیتێکی هەڵدەگرن.
import random
PROGRAMMING_WORDS = ["python", "variable", "function", "string", "loop",
"list", "index", "random", "integer", "keyboard"]
KURDISH_WORDS = ["کتێب", "قوتابخانە", "چایخانە", "بازاڕ", "باران",
"پاسکیل", "مامۆستا", "خوێندکار", "زستان", "کۆمپیوتەر"]
print(len(PROGRAMMING_WORDS), "programming words")
print(len(KURDISH_WORDS), "Kurdish words")
print(list("کتێب"), len("کتێب"))
print("One random word:", random.choice(PROGRAMMING_WORDS))
print("Three different words:", random.sample(PROGRAMMING_WORDS, 3))10 programming words 10 Kurdish words ['ک', 'ت', 'ێ', 'ب'] 4 One random word: integer Three different words: ['list', 'index', 'keyboard']
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-6
Two constants. A long list may continue on the next line inside the brackets.
دوو . درێژ دەتوانێت لە ناو کەوانەکاندا لە دێڕی داهاتوودا بەردەوام بێت.
- Lineدێڕی 10
list("کتێب")splits a Kurdish word into its 4 letters. Each Sorani letter is one character.list("کتێب")وشەیەکی کوردی دەکات بە 4 پیتەکەی. هەر پیتێکی سۆرانی یەک .- Lineدێڕی 11
random.choice()returns one item.random.choice()یەک دەگەڕێنێتەوە.- Lineدێڕی 12
random.sample(list, 3)returns 3 different items in a new list.random.sample(list, 3)3 جیاواز لە نوێدا دەگەڕێنێتەوە.
Why sample() and not choice() five times? choice() can pick the same word twice in one game; sample() never does.
بۆچی sample() و نەک پێنج جار choice()؟ choice() دەتوانێت لە یەک یاریدا هەمان وشە دوو جار هەڵبژێرێت؛ sample() هەرگیز وا ناکات.
Step 2: shuffling lettersهەنگاوی 2: تێکەڵکردنی پیتەکان
A string cannot be changed (it is immutable), so we cannot mix its letters in place. The trick has three moves: turn the word into a list of letters, shuffle the list, then join the letters back into a new string.
ناگۆڕدرێت ()، بۆیە ناتوانین پیتەکانی لە شوێنی خۆیدا تێکەڵ بکەین. فێڵەکە سێ جووڵەیە: وشەکە بکە بە لە پیت، تێکەڵ بکە، پاشان پیتەکان بلکێنەوە بە نوێ.


import random
word = "python"
letters = list(word) # a list of one-letter strings
print(letters)
random.shuffle(letters) # mixes the list itself, in place
print(letters)
mixed = "".join(letters) # glue the letters back into one string
print(mixed)
print(word) # the original string is unchanged['p', 'y', 't', 'h', 'o', 'n'] ['o', 'h', 't', 'y', 'p', 'n'] ohtypn python
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4
list(word)makes a new list with one letter in each place.list(word)نوێ دروست دەکات کە لە هەر شوێنێکدا پیتێکی تێدایە.- Lineدێڕی 6
shuffle()changes the list itself and returnsNone.shuffle()خودی دەگۆڕێت وNoneدەگەڕێنێتەوە.- Lineدێڕی 8
"".join(letters)glues the letters with nothing ("") between them."".join(letters)پیتەکان بە هیچ ("") لە نێوانیاندا پێکەوە دەلکێنێت.
A name painted on the classroom wall cannot be rearranged — like a string. To mix the letters, the teacher writes each letter on its own card (a list), shuffles the cards on the desk, then copies them in their new order onto a fresh sheet (a new string).
ناوێک کە لەسەر دیواری پۆل بۆیاخ کراوە ناتوانرێت ڕیزی بگۆڕدرێت؛ وەک . بۆ تێکەڵکردنی پیتەکان، مامۆستا هەر پیتێک لەسەر کارتێکی جیا دەنووسێت ()، کارتەکان لەسەر مێزەکە تێکەڵ دەکات، پاشان بە ڕیزە نوێکەیان لەسەر پەڕەیەکی نوێ دەینووسێتەوە ( نوێ).
Where the analogy stops workingسنووری ئەم نموونەیە
Real cards can get lost; shuffle() always keeps exactly the same letters, only their order changes.
کارتی ڕاستەقینە لەوانەیە ون ببن؛ shuffle() هەمیشە ڕێک هەمان پیتەکان دەهێڵێتەوە، تەنها ڕیزەکەیان دەگۆڕێت.
The random module's main tools: random(), randint(), choice() and shuffle(), shown with dice, rock-paper-scissors and a deck of cards.
ئامرازە سەرەکییەکانی random: random()، randint()، choice() و shuffle()، بە نموونەی بەردەزار، بەرد-کاغەز-مقەست و دەستەیەک کارتی یاری.
Watch 3:32–4:32: random.shuffle() mixes a list of cards in place, as the game mixes a list of letters.
لە 3:32 تا 4:32 سەیر بکە: random.shuffle() کارت لە شوێنی خۆیدا تێکەڵ دەکات، وەک چۆن یارییەکە پیت تێکەڵ دەکات.
Step 2: shuffling lettersهەنگاوی 2: تێکەڵکردنی پیتەکان
Two shuffle mistakesدوو هەڵەی تێکەڵکردن
Mistake 1: keeping the return value. shuffle() returns None. If you write letters = random.shuffle(letters), the list is shuffled and then thrown away, and letters becomes None.
هەڵەی 1: هەڵگرتنی . shuffle() None دەگەڕێنێتەوە. ئەگەر بنووسیت letters = random.shuffle(letters)، تێکەڵ دەکرێت و پاشان فڕێ دەدرێت و letters دەبێت بە None.
import random
letters = list("python")
letters = random.shuffle(letters) # WRONG: shuffle() returns None
print(letters)
print("".join(letters))None
Traceback (most recent call last):
File "/Users/aram/python/mistake_none.py", line 6, in <module>
print("".join(letters))
^^^^^^^^^^^^^^^^
TypeError: can only join an iterableMistake 2: shuffling the string. shuffle() needs something it can change. A string is immutable, so Python stops with a TypeError.
هەڵەی 2: تێکەڵکردنی . shuffle() پێویستی بە شتێکە بتوانێت بیگۆڕێت. ، بۆیە بە TypeError دەوەستێت.
import random
random.shuffle("python") # WRONG: a string cannot be changedTraceback (most recent call last):
File "/Users/aram/python/mistake_str.py", line 3, in <module>
random.shuffle("python") # WRONG: a string cannot be changed
^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.12/random.py", line 357, in shuffle
x[i], x[j] = x[j], x[i]
~^^^
TypeError: 'str' object does not support item assignmentStep 3: the scramble() functionهەنگاوی 3: کرداری scramble()
Now wrap the three moves in a function. One detail matters: a shuffle can, by chance, give the original order back. Showing loop as the puzzle for loop would spoil the round, so the function shuffles again until the result is different.
ئێستا سێ جووڵەکە لە ناو دابنێ. وردەکارییەک گرنگە: تێکەڵکردن دەتوانێت بە هەڵکەوت ڕیزە بنەڕەتییەکە بگەڕێنێتەوە. پیشاندانی loop وەک مەتەڵ بۆ loop گەڕەکە تێک دەدات، بۆیە دووبارە تێکەڵ دەکات تا ئەنجامەکە جیاواز دەبێت.
import random
def scramble(word):
"""Return the letters of word in a new random order."""
if len(set(word)) < 2: # "aa" can never look different
return word
letters = list(word)
while True:
random.shuffle(letters)
mixed = "".join(letters)
if mixed != word: # never show the answer itself
return mixed
for word in ["loop", "loop", "loop", "کتێب", "aa"]:
print(word, "->", scramble(word))loop -> polo loop -> lpoo loop -> oopl کتێب -> بکتێ aa -> aa
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6-7
Guard:
set(word)keeps each letter once. A word likeaahas only one different letter and can never look different, so the loop below would run for ever.پاسەوان:
set(word)هەر پیتێک یەک جار دەهێڵێتەوە. وشەیەکی وەکaaتەنها یەک پیتی جیاوازی هەیە و هەرگیز جیاواز دەرناکەوێت، بۆیە خوارەوە بۆ هەمیشە کار دەکات.- Lineدێڕی 9-13
Shuffle, join, test.
returnleaves the loop and the function together.تێکەڵکردن، لکاندن، پشکنین.
returnلە و پێکەوە دەردەچێت.- Lineدێڕی 16
Five test calls. Each call gives its own random order.
پێنج بانگکردنی تاقیکردنەوە. هەر بانگکردنێک ڕیزی هەڵکەوتیی خۆی دەدات.
The three calls with loop gave three different mixes, none of them loop itself. Two calls may give the same mix by chance: we only promise that the mix is never the word.
سێ بانگکردنەکەی loop سێ تێکەڵی جیاوازیان دا و هیچیان خودی loop نییە. دەشێت دوو بانگکردن بە هەڵکەوت هەمان تێکەڵ بدەن: تەنها بەڵێن دەدەین کە تێکەڵەکە هەرگیز خودی وشەکە نەبێت.
Step 4: checking a guessهەنگاوی 4: پشکنینی وەڵامێک
Players make typing mistakes. Before we count a guess as a try, we check that it is fair: the right length and exactly the letters shown. This is input validation: never trust input until you have checked it.
یاریزانان هەڵەی تایپکردن دەکەن. پێش ئەوەی وەڵامێک وەک هەوڵ بژمێرین، دەپشکنین کە ڕەوایە: درێژیی دروست و ڕێک ئەو پیتانەی پیشان دراون. ئەمە ـە: هەرگیز متمانە بە مەکە تا نەیپشکنیت.
def guess_problem(guess, word):
"""Return why guess is not a fair try, or "" if it is fine."""
if len(guess) != len(word):
return f"Please type exactly {len(word)} letters."
if sorted(guess) != sorted(word):
return "Please use only the letters shown."
return ""
word = "loop"
for guess in ["lop", "loops", "lope", "pool", "loop"]:
problem = guess_problem(guess, word)
if problem: # a non-empty string counts as True
print(guess, "->", problem)
else:
print(guess, "-> a fair try")
print(sorted("pool"), sorted("loop"))lop -> Please type exactly 4 letters. loops -> Please type exactly 4 letters. lope -> Please use only the letters shown. pool -> a fair try loop -> a fair try ['l', 'o', 'o', 'p'] ['l', 'o', 'o', 'p']
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-4
Wrong length: return a message that says how many letters are needed.
درێژیی هەڵە: پەیامێک بگەڕێنەرەوە کە دەڵێت چەند پیت پێویستە.
- Lineدێڕی 5-6
sorted()puts the letters of a string in order in a new list. Two words use the same letters exactly when their sorted lists are equal.sorted()پیتەکانی لە نوێدا ڕیز دەکات. دوو وشە ڕێک هەمان پیتەکانیان هەیە کاتێک یەکسانن.- Lineدێڕی 7
An empty string means “no problem”.
بەتاڵ واتە «هیچ کێشەیەک نییە».
- Lineدێڕی 13
In an
if, a non-empty string counts as true and""as false.لە
ifـدا نابەتاڵ وەک ڕاست و""وەک هەڵە دەژمێردرێت.
pool is a fair try for loop (same letters), even though it is the wrong word. lope is not fair: it has an e that was never shown.
pool بۆ loop هەوڵێکی ڕەوایە (هەمان پیت)، هەرچەندە وشە هەڵەکەیە. lope ڕەوا نییە: eـی تێدایە کە هەرگیز پیشان نەدراوە.
Step 5: one roundهەنگاوی 5: یەک گەڕ
play_round() follows the flowchart. Put it below scramble() and guess_problem() and add two test calls at the bottom.
play_round() شوێنی دەکەوێت. لە خوار scramble() و guess_problem() دایبنێ و دوو بانگکردنی تاقیکردنەوە لە خوارەوە زیاد بکە.
MAX_TRIES = 3 # tries for each word
def play_round(word):
"""Play one word. Return the points (0-3), or None to quit."""
print("\nLetters:", " ".join(scramble(word)))
tries = 0
while tries < MAX_TRIES:
guess = input("Your guess: ").strip().lower()
if guess == "quit":
return None
problem = guess_problem(guess, word)
if problem:
print(problem) # an unfair guess costs no try
continue
tries += 1
if guess == word:
points = MAX_TRIES + 1 - tries
print(f"Correct! +{points} points")
return points
if tries < MAX_TRIES:
print(f"Not this one. Hint: it starts with {word[:tries]}")
print(f"Tries left: {MAX_TRIES - tries}")
print(f"Out of tries. The word was {word}.")
return 0
print("Points:", play_round("string"))
print("Points:", play_round("loop"))Letters: r i t n g s Your guess: strings Please type exactly 6 letters. Your guess: rtsing Not this one. Hint: it starts with s Tries left: 2 Your guess: STRING Correct! +2 points Points: 2 Letters: p l o o Your guess: pool Not this one. Hint: it starts with l Tries left: 2 Your guess: quit Points: None
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
One constant for the number of tries. Change it here and the whole round follows.
یەک بۆ ژمارەی هەوڵەکان. لێرە بیگۆڕە و هەموو گەڕەکە شوێنی دەکەوێت.
- Lineدێڕی 9
Clean the guess at once: no spaces at the ends, small letters only.
یەکسەر وەڵامەکە پاک بکەرەوە: بێ لە سەرەکاندا، تەنها پیتی بچووک.
- Lineدێڕی 10-11
quitends the round withNone, a value that means “no points: stop”.quitگەڕەکە بەNoneکۆتایی پێ دەهێنێت، بە واتای «هیچ خاڵێک نییە: بوەستە».- Lineدێڕی 13-15
An unfair guess: explain and
continue— back to the loop test without counting a try.وەڵامێکی ناڕەوا: ڕوونی بکەرەوە و
continue— گەڕانەوە بۆ پشکنینی بەبێ ژماردنی هەوڵ.- Lineدێڕی 17-20
Points: 3 on try 1, 2 on try 2, 1 on try 3.
خاڵ: 3 لە هەوڵی 1، 2 لە هەوڵی 2، 1 لە هەوڵی 3.
- Lineدێڕی 22
word[:tries]is a slice: 1 letter after the first wrong try, 2 letters after the second.word[:tries]: دوای یەکەم هەوڵی هەڵە 1 پیت، دوای دووەم 2 پیت.- Lineدێڕی 24-25
The loop ended because all tries are used: show the word and give 0 points.
کۆتایی هات چونکە هەموو هەوڵەکان بەکار هاتوون: وشەکە پیشان بدە و 0 خاڵ بدە.
Step 5: one roundهەنگاوی 5: یەک گەڕ
Returning None to say “quit”گەڕاندنەوەی None بۆ وتنی «وەستان»
A function can return only one thing, but that thing can carry meaning. play_round() returns a number of points (0 to 3) or None. None cannot be confused with a real score, while 0 could: 0 points is a normal result after three wrong tries.
تەنها دەتوانێت یەک شت بگەڕێنێتەوە، بەڵام ئەو شتە دەتوانێت واتای هەبێت. play_round() ژمارەیەک خاڵ (0 تا 3) یان None دەگەڕێنێتەوە. None لەگەڵ خاڵێکی ڕاستەقینە تێکەڵ نابێت، بەڵام 0 تێکەڵ دەبێت: 0 خاڵ دوای سێ هەوڵی هەڵە ئەنجامێکی ئاساییە.
The caller checks it with is None: if points is None:. You met None in Return values.
بە is None دەیپشکنێت: if points is None:. پێشتر Noneـت لە نرخە گەڕاوەکان بینی.
Step 6: a whole gameهەنگاوی 6: یارییەکی تەواو
A game is 5 rounds with 5 different words. play_game() adds up the points in a local variable and gives back two results: the score, and whether the player typed quit.
یارییەک 5 گەڕە بە 5 وشەی جیاواز. play_game() خاڵەکان لە کۆ دەکاتەوە و دوو ئەنجام دەگەڕێنێتەوە: خاڵەکان و ئەوەی ئایا یاریزان quitـی نووسیوە.
def play_game(words):
"""Play ROUNDS different words. Return (score, player_quit)."""
score = 0
for word in random.sample(words, ROUNDS): # no word twice
points = play_round(word)
if points is None:
return score, True
score += points
return score, FalseExplain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4
random.sample()picksROUNDSdifferent words, so no word comes twice.random.sample()ROUNDSوشەی جیاواز هەڵدەبژێرێت، بۆیە هیچ وشەیەک دوو جار نایەت.- Lineدێڕی 6-7
The player quit: stop at once and report it.
یاریزان وەستا: یەکسەر بوەستە و ڕاپۆرتی بکە.
- Lineدێڕی 8
An accumulator: each round's points are added to
score.: خاڵی هەر گەڕێک دەخرێتە سەر
score.- Lineدێڕی 9
return score, Falsereturns a tuple of two values.return score, Falseلە دوو دەگەڕێنێتەوە.
The caller unpacks the tuple into two names: score, player_quit = play_game(words). Tuples and unpacking are explained in Tuples, sets and dictionaries.
دەکاتەوە بۆ دوو ناو: score, player_quit = play_game(words). و کردنەوەیان لە تاپڵەکان، کۆمەڵەکان و فەرهەنگەکان ڕوون کراونەتەوە.
Step 8: main() and playing againهەنگاوی 8: main() و دووبارە یاریکردن
main() connects everything. One pass of its while True loop is one game. The best score lives in main(), so it survives from game to game.
main() هەموو شتێک پێکەوە دەبەستێت. هەر while Trueـەکەی یەک یارییە. باشترین خاڵ لە main()ـدا دەژی، بۆیە لە یارییەکەوە بۆ یارییەکی تر دەمێنێتەوە.
def main():
print("=== Mixed Letters ===")
print(f"Unmix {ROUNDS} words. You have {MAX_TRIES} tries for each word.")
print("Type quit at any time to stop.")
best = 0
while True: # one pass of this loop = one game
words = choose_word_list()
score, player_quit = play_game(words)
print(f"\nScore: {score} out of {ROUNDS * MAX_TRIES}")
if score > best:
best = score
print("New best score today!")
if player_quit or not ask_yes_no("Play again? (y/n): "):
break
print(f"Best score: {best}. Goodbye!")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt: # the player pressed Ctrl+C
print("\nGame stopped. Goodbye!")Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6-8
One game: choose a list, play it, unpack the two results.
یەک یاری: هەڵبژێرە، یاری پێ بکە، دوو ئەنجامەکە بکەرەوە.
- Lineدێڕی 10-12
Keep the highest score so far.
بەرزترین خاڵ تا ئێستا هەڵبگرە.
- Lineدێڕی 13-14
Stop if the player typed
quit, or answered no. Thanks toor, the question is not asked afterquit.ئەگەر یاریزان
quitـی نووسی یان وەڵامی نەخێری دایەوە بوەستە. بە هۆیor، دوایquitپرسیارەکە ناکرێت.- Lineدێڕی 18
Run
main()only when this file is run, not when another file imports it (the tests below need that).main()تەنها کاتێک جێبەجێ بکە کە ئەم جێبەجێ دەکرێت، نەک کاتێک ترimportـی دەکات (تاقیکردنەوەکانی خوارەوە ئەمەیان پێویستە).- Lineدێڕی 19-22
Ctrl+C raises
KeyboardInterrupt. We catch it and say goodbye instead of showing a traceback.Ctrl+C
KeyboardInterruptدروست دەکات. دەیگرین و لە جیاتی پیشاندانی ماڵئاوایی دەکەین.
When the player presses Ctrl+C, the terminal shows ^C and our except block prints the goodbye line:
کاتێک یاریزان Ctrl+C دادەگرێت، ^C پیشان دەدات و بلۆکی exceptـەکەمان دێڕی ماڵئاوایی چاپ دەکات:
=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming words, 2 = Kurdish words: ^C Game stopped. Goodbye!
The complete programبەرنامە تەواوەکە
Here is the whole game in one file, mixed_letters.py (110 lines). Read it from the bottom up: main() calls the others, and each helper does one job.
ئەمە هەموو یارییەکەیە لە یەک ، mixed_letters.py (110 دێڕ). لە خوارەوە بۆ سەرەوە بیخوێنەرەوە: main() بانگی ئەوانی تر دەکات و هەر یاریدەدەرێک یەک کار دەکات.
import random
MAX_TRIES = 3 # tries for each word
ROUNDS = 5 # words in one game
PROGRAMMING_WORDS = ["python", "variable", "function", "string", "loop",
"list", "index", "random", "integer", "keyboard"]
KURDISH_WORDS = ["کتێب", "قوتابخانە", "چایخانە", "بازاڕ", "باران",
"پاسکیل", "مامۆستا", "خوێندکار", "زستان", "کۆمپیوتەر"]
WORD_LISTS = {"1": PROGRAMMING_WORDS, "2": KURDISH_WORDS}
def scramble(word):
"""Return the letters of word in a new random order."""
if len(set(word)) < 2: # "aa" can never look different
return word
letters = list(word)
while True:
random.shuffle(letters) # mixes the list in place
mixed = "".join(letters)
if mixed != word: # never show the answer itself
return mixed
def guess_problem(guess, word):
"""Return why guess is not a fair try, or "" if it is fine."""
if len(guess) != len(word):
return f"Please type exactly {len(word)} letters."
if sorted(guess) != sorted(word):
return "Please use only the letters shown."
return ""
def play_round(word):
"""Play one word. Return the points (0-3), or None to quit."""
print("\nLetters:", " ".join(scramble(word)))
tries = 0
while tries < MAX_TRIES:
guess = input("Your guess: ").strip().lower()
if guess == "quit":
return None
problem = guess_problem(guess, word)
if problem:
print(problem) # an unfair guess costs no try
continue
tries += 1
if guess == word:
points = MAX_TRIES + 1 - tries
print(f"Correct! +{points} points")
return points
if tries < MAX_TRIES:
print(f"Not this one. Hint: it starts with {word[:tries]}")
print(f"Tries left: {MAX_TRIES - tries}")
print(f"Out of tries. The word was {word}.")
return 0
def play_game(words):
"""Play ROUNDS different words. Return (score, player_quit)."""
score = 0
for word in random.sample(words, ROUNDS): # no word twice
points = play_round(word)
if points is None:
return score, True
score += points
return score, False
def choose_word_list():
"""Ask until the player types 1 or 2; return that word list."""
while True:
choice = input("1 = programming words, 2 = Kurdish words: ").strip()
if choice in WORD_LISTS:
return WORD_LISTS[choice]
print("Please type 1 or 2.")
def ask_yes_no(question):
"""Ask until the answer is yes or no; return True for yes."""
while True:
answer = input(question).strip().lower()
if answer in ("y", "yes"):
return True
if answer in ("n", "no"):
return False
print("Please answer y or n.")
def main():
print("=== Mixed Letters ===")
print(f"Unmix {ROUNDS} words. You have {MAX_TRIES} tries for each word.")
print("Type quit at any time to stop.")
best = 0
while True: # one pass of this loop = one game
words = choose_word_list()
score, player_quit = play_game(words)
print(f"\nScore: {score} out of {ROUNDS * MAX_TRIES}")
if score > best:
best = score
print("New best score today!")
if player_quit or not ask_yes_no("Play again? (y/n): "):
break
print(f"Best score: {best}. Goodbye!")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt: # the player pressed Ctrl+C
print("\nGame stopped. Goodbye!")=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming words, 2 = Kurdish words: 3 Please type 1 or 2. 1 = programming words, 2 = Kurdish words: 1 Letters: n r g s t i Your guess: string Correct! +3 points Letters: o o p l Your guess: pool Not this one. Hint: it starts with l Tries left: 2 Your guess: loop Correct! +2 points Letters: b i e r v a l a Your guess: varible Please type exactly 8 letters. Your guess: variable Correct! +3 points Letters: t l i s Your guess: slit Not this one. Hint: it starts with l Tries left: 2 Your guess: silt Not this one. Hint: it starts with li Tries left: 1 Your guess: lits Out of tries. The word was list. Letters: b e o k a r d y Your guess: keybaord Not this one. Hint: it starts with k Tries left: 2 Your guess: keyboard Correct! +2 points Score: 10 out of 15 New best score today! Play again? (y/n): maybe Please answer y or n. Play again? (y/n): n Best score: 10. Goodbye!
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-10
Settings and word lists: constants, written in capitals.
و وشە: ، بە پیتی گەورە نووسراون.
- Lineدێڕی 13-31
Two small helpers that never talk to the player: easy to test.
دوو یاریدەدەری بچووک کە هەرگیز قسە لەگەڵ یاریزان ناکەن: تاقیکردنەوەیان ئاسانە.
- Lineدێڕی 34-66
One round and one game.
یەک گەڕ و یەک یاری.
- Lineدێڕی 69-86
Two validation loops.
دوو .
- Lineدێڕی 89-110
The main loop, the
__main__guard and the Ctrl+C exit.، پاسەوانی
__main__و دەرچوون بە Ctrl+C.
In this run you can follow every rule: the menu rejects 3; pool costs a try and gives the hint l; varible (7 letters) costs nothing; list is lost after three fair tries; the score is ; and maybe is not accepted as an answer.
لەم جێبەجێکردنەدا دەتوانیت هەموو یاساکان ببینیت: هەڵبژاردنەکە 3 ڕەت دەکاتەوە؛ pool هەوڵێک دەسووتێنێت و سەرەداوی l دەدات؛ varible (7 پیت) هیچی تێ ناچێت؛ list دوای سێ هەوڵی ڕەوا دەدۆڕێت؛ کۆی خاڵەکان: ؛ و maybe وەک وەڵام قبووڵ ناکرێت.
The complete programبەرنامە تەواوەکە
Playing with Kurdish wordsیاریکردن بە وشەی کوردی
Choose list 2 and the same code plays with Kurdish words. Nothing in the program is English-only: list(), shuffle(), sorted() and len() work on any Unicode letters.
2 هەڵبژێرە و هەمان کۆد بە وشەی کوردی یاری دەکات. هیچ شتێک لە تەنها بۆ ئینگلیزی نییە: list()، shuffle()، sorted() و len() لەسەر هەر پیتێکی کار دەکەن.
=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming words, 2 = Kurdish words: 2 Letters: ا ز ا ڕ ب Your guess: بازار Please use only the letters shown. Your guess: بازاڕ Correct! +3 points Letters: ل پ س ک ا ی Your guess: quit Score: 3 out of 15 New best score today! Best score: 3. Goodbye!
The first guess was refused: بازار was typed with ر instead of ڕ. For Python these are two different characters (code points 1585 and 1685), so the guess does not use the letters shown. Careful spelling matters to a computer! See Kurdish letters in comparisons.
یەکەم وەڵام ڕەت کرایەوە: بازار بە ر لە جیاتی ڕ نووسرا. بۆ ئەمانە دوو جیاوازن ( 1585 و 1685)، بۆیە وەڵامەکە ئەو پیتانە بەکار ناهێنێت کە پیشان دراون. ڕێنووسی ورد بۆ گرنگە! بڕوانە پیتە کوردییەکان لە بەراوردکردندا.
Testing a program that uses randomتاقیکردنەوەی بەرنامەیەک کە هەڵکەوت بەکار دەهێنێت
How do you test a program whose output changes every run? Two tools help. First, random.seed() fixes the starting point of the random-number generator: with the same seed, the same “random” results come again. Second, assert checks a fact and stops the program if it is false.
چۆن تاقی دەکەیتەوە کە لە هەر جێبەجێکردنێکدا دەگۆڕێت؟ دوو ئامراز یارمەتی دەدەن. یەکەم، random.seed() خاڵی دەستپێکی دروستکەری جێگیر دەکات: بە هەمان ، هەمان ئەنجامە «هەڵکەوتییەکان» دووبارە دێنەوە. دووەم، assert ڕاستییەک دەپشکنێت و ئەگەر هەڵە بوو دەوەستێنێت.
import random
from mixed_letters import guess_problem, scramble
random.seed(2026) # fix the "random" numbers
print(scramble("python"), scramble("python"))
random.seed(2026) # same seed again ...
print(scramble("python"), scramble("python")) # ... same letters again
for word in ["python", "loop", "کتێب"]:
mixed = scramble(word)
assert mixed != word # never the answer itself
assert sorted(mixed) == sorted(word) # the same letters
assert guess_problem("pool", "loop") == ""
assert guess_problem("lop", "loop") != ""
assert guess_problem("lope", "loop") != ""
print("All tests passed.")oyhntp pythno oyhntp pythno All tests passed.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
Save this file next to
mixed_letters.py. Importing works becausemain()is guarded byif __name__ == "__main__":— the game does not start.ئەم لە تەنیشت
mixed_letters.pyهەڵبگرە.importکار دەکات چونکەmain()بەif __name__ == "__main__":پارێزراوە — یارییەکە دەست پێ ناکات.- Lineدێڕی 5-8
Same seed, same results: both lines print the same two mixes.
هەمان ، هەمان ئەنجام: هەردوو دێڕ هەمان دوو تێکەڵ چاپ دەکەن.
- Lineدێڕی 10-13
Facts that must be true for any word: never the word itself, always the same letters.
ڕاستییەک کە دەبێت بۆ هەموو وشەیەک ڕاست بێت: هەرگیز خودی وشەکە نا، هەمیشە هەمان پیتەکان.
If a fact is false, assert raises an AssertionError and shows the line. Here a wrong claim is tested on purpose:
ئەگەر ڕاستییەک هەڵە بێت، assert AssertionError دروست دەکات و دێڕەکە پیشان دەدات. لێرەدا بە ئەنقەست بانگەشەیەکی هەڵە تاقی دەکرێتەوە:
from mixed_letters import guess_problem
assert guess_problem("lope", "loop") == "" # this claim is false
print("All tests passed.")Traceback (most recent call last):
File "/Users/aram/python/test_fail.py", line 3, in <module>
assert guess_problem("lope", "loop") == "" # this claim is false
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionErrorWhat random.seed() does: the same seed gives the same 'random' numbers every run, which makes programs easy to test.
random.seed() چی دەکات: هەمان لە هەموو جێبەجێکردنێکدا هەمان دەدات، ئەمەش ئاسان دەکات.
Whole video (2:44): what random.seed() does and why the same seed gives the same results.
هەموو ڤیدیۆکە (2:44): random.seed() چی دەکات و بۆچی هەمان هەمان ئەنجام دەدات.
Common mistakesهەڵە باوەکان
| Mistakeهەڵە | What happensچی ڕوودەدات | Fixچارەسەر |
|---|---|---|
letters = random.shuffle(letters) | letters becomes Noneletters دەبێت بە None | random.shuffle(letters) |
random.shuffle(word) | TypeError: a string cannot changeTypeError: ناگۆڕدرێت | letters = list(word) firstسەرەتا letters = list(word) |
| Shuffle once, show the resultیەک جار تێکەڵکردن، پیشاندانی ئەنجام | Sometimes the answer itself is shownهەندێک جار خودی وەڵامەکە پیشان دەدرێت | Shuffle again until differentدووبارە تێکەڵ بکە تا جیاواز دەبێت |
Retry loop for a word like aa دووبارە بۆ وشەیەکی وەک aa | Infinite loop | Guard with len(set(word)) < 2پاسەوان بە len(set(word)) < 2 |
random.choice() for each roundrandom.choice() بۆ هەر گەڕێک | The same word can come twiceهەمان وشە دەتوانێت دوو جار بێت | random.sample(words, 5) |
No .strip().lower()بێ .strip().lower() | Python or python is judged wrongPython یان python بە هەڵە دادەنرێت | input(...).strip().lower() |
| Counting every guess as a tryژماردنی هەموو وەڵامێک وەک هەوڵ | A typo costs the player a tryهەڵەیەکی تایپکردن هەوڵێک لە یاریزان دەسووتێنێت | Validate first, then tries += 1سەرەتا بپشکنە، پاشان tries += 1 |
main() calls main() to play againmain() بانگی main() دەکات بۆ دووبارە یاری | The call stack grows; RecursionError after ~1000 games گەورە دەبێت؛ دوای ~1000 یاری RecursionError | A while True loop with break while True لەگەڵ break |
| Score in a global variableخاڵ لە | Hard to test; any function can change itتاقیکردنەوەی قورسە؛ هەر دەتوانێت بیگۆڕێت | Return values and add them up بگەڕێنەرەوە و کۆیان بکەرەوە |
random.seed() left in the gamerandom.seed() لە یارییەکەدا جێهێڵراوە | Every game is the sameهەموو یارییەک وەک یەکە | Seed only in tests تەنها لە تاقیکردنەوەدا |
Exercisesڕاهێنانەکان
Without running it: the word is loop and the player types lop, pool, LOOP. Write every line that play_round() prints, and its return value.
بەبێ جێبەجێکردن: وشەکە loopـە و یاریزان lop، pool، LOOP دەنووسێت. هەموو ئەو دێڕانە بنووسە کە play_round() چاپیان دەکات و .
Hintئاماژە
Remember that .lower() runs before the comparison.
لەبیرت بێت .lower() پێش بەراوردکردن جێبەجێ دەبێت.
Show answerوەڵامەکە پیشان بدە
lop has the wrong length (no try used). pool is fair but wrong: hint l, 2 tries left. LOOP becomes loop: correct on try 2, so 2 points.
lop درێژییەکەی هەڵەیە (هیچ هەوڵێک بەکار نایەت). pool ڕەوایە بەڵام هەڵەیە: سەرەداوی l، 2 هەوڵی تر دەمێنێتەوە. LOOP دەبێت بە loop: لە هەوڵی 2دا ڕاستە، بۆیە 2 خاڵ.
print("Points:", play_round("loop"))Letters: p l o o Your guess: lop Please type exactly 4 letters. Your guess: pool Not this one. Hint: it starts with l Tries left: 2 Your guess: LOOP Correct! +2 points Points: 2
Add a command skip: the player gives up the current word, sees the answer, gets 0 points and goes on to the next word. Update the welcome text too.
skip زیاد بکە: یاریزان دەستبەرداری وشەی ئێستا دەبێت، وەڵامەکە دەبینێت، 0 خاڵ وەردەگرێت و دەچێتە سەر وشەی داهاتوو. دەقی بەخێرهاتنیش نوێ بکەرەوە.
Hintئاماژە
Put the new test right after the quit test, before the guess is validated.
پشکنینە نوێیەکە ڕاستەوخۆ دوای پشکنینی quit دابنێ، پێش پشکنینی وەڵامەکە.
Show answerوەڵامەکە پیشان بدە
if guess == "quit":
return None
if guess == "skip":
print(f"Skipped. The word was {word}.")
return 0And in main(): print("Type skip to pass a word, or quit to stop."). Test run:
و لە main()ـدا: print("Type skip to pass a word, or quit to stop."). جێبەجێکردنی تاقیکردنەوە:
=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type skip to pass a word, or quit to stop. 1 = programming words, 2 = Kurdish words: 1 Letters: o y a d e b r k Your guess: skip Skipped. The word was keyboard. Letters: p l o o Your guess: quit Score: 0 out of 15 Best score: 0. Goodbye!
Add a list of animals (horse, camel, eagle, tiger, zebra, rabbit) as choice 3. Which lines must change?
ئاژەڵ (horse، camel، eagle، tiger، zebra، rabbit) وەک هەڵبژاردنی 3 زیاد بکە. کام دێڕانە دەبێت بگۆڕدرێن؟
Show answerوەڵامەکە پیشان بدە
ANIMAL_WORDS = ["horse", "camel", "eagle", "tiger", "zebra", "rabbit"]
WORD_LISTS = {"1": PROGRAMMING_WORDS, "2": KURDISH_WORDS, "3": ANIMAL_WORDS}In choose_word_list() only the two texts change: the prompt "1 = programming, 2 = Kurdish, 3 = animals: " and the message "Please type 1, 2 or 3.". The test choice in WORD_LISTS already accepts "3". The list must have at least 5 words (see exercise 4).
لە choose_word_list()ـدا تەنها دوو دەقەکە دەگۆڕێن: پرسیاری "1 = programming, 2 = Kurdish, 3 = animals: " و پەیامی "Please type 1, 2 or 3.". پشکنینی choice in WORD_LISTS خۆی "3" قبووڵ دەکات. دەبێت لانیکەم 5 وشەی هەبێت (بڕوانە ڕاهێنانی 4).
=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming, 2 = Kurdish, 3 = animals: 4 Please type 1, 2 or 3. 1 = programming, 2 = Kurdish, 3 = animals: 3 Letters: a z b e r Your guess: quit Score: 0 out of 15 Best score: 0. Goodbye!
Change ROUNDS = 5 to ROUNDS = 20 and choose list 1. What happens, and why? How would you fix it?
ROUNDS = 5 بگۆڕە بۆ ROUNDS = 20 و 1 هەڵبژێرە. چی ڕوودەدات و بۆچی؟ چۆن چاکی دەکەیتەوە؟
Hintئاماژە
Read the last line of the traceback.
دوا دێڕی بخوێنەرەوە.
Show answerوەڵامەکە پیشان بدە
The program stops with ValueError: Sample larger than population or is negative: random.sample() cannot pick 20 different words from a list of 10.
بە ValueError: Sample larger than population or is negative دەوەستێت: random.sample() ناتوانێت 20 وشەی جیاواز لە 10 وشەییدا هەڵبژێرێت.
=== Mixed Letters ===
Unmix 20 words. You have 3 tries for each word.
Type quit at any time to stop.
1 = programming words, 2 = Kurdish words: 1
Traceback (most recent call last):
File "/Users/aram/python/mixed_letters.py", line 108, in <module>
main()
File "/Users/aram/python/mixed_letters.py", line 96, in main
score, player_quit = play_game(words)
^^^^^^^^^^^^^^^^
File "/Users/aram/python/mixed_letters.py", line 61, in play_game
for word in random.sample(words, ROUNDS): # no word twice
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.12/random.py", line 430, in sample
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negativeThe simplest fix is a rule: ROUNDS must not be larger than the shortest word list (or add more words). random.sample(words, min(ROUNDS, len(words))) stops the crash, but then the welcome line and “out of 60” are wrong, so those messages would need the real number too.
سادەترین چارەسەر یاسایەکە: ROUNDS نابێت لە کورتترین وشە گەورەتر بێت (یان وشەی زیاتر زیاد بکە). random.sample(words, min(ROUNDS, len(words))) وەستانەکە نایەڵێت، بەڵام پاشان دێڕی بەخێرهاتن و «out of 60» هەڵەن، بۆیە ئەو پەیامانەش پێویستیان بە ژمارە ڕاستەکە دەبێت.
A student removes the while True loop from main() and writes if ask_yes_no("Play again? (y/n): "): main() at the end instead. The game seems to work. Give two reasons why the loop version is better.
خوێندکارێک while True لە main() لادەبات و لە جیاتی ئەوە لە کۆتاییدا دەنووسێت if ask_yes_no("Play again? (y/n): "): main(). یارییەکە وا دیارە کار دەکات. دوو هۆکار بڵێ بۆچی وەشانی باشترە.
Show answerوەڵامەکە پیشان بدە
- Each new game is a call inside the previous call. The call stack grows with every game, and after about 1000 games Python stops with
RecursionError. - Each call of
main()has its ownbest = 0, so the best score is forgotten when a new game starts; and when the player finally says no, all the waiting calls finish one by one, each printing its own goodbye line.
- هەر یارییەکی نوێ بانگکردنێکە لە ناو بانگکردنی پێشوودا. لەگەڵ هەر یارییەک گەورە دەبێت و دوای نزیکەی 1000 یاری بە
RecursionErrorدەوەستێت. - هەر بانگکردنێکی
main()best = 0ـی خۆی هەیە، بۆیە کاتێک یارییەکی نوێ دەست پێ دەکات باشترین خاڵ لەبیر دەچێت؛ و کاتێک یاریزان لە کۆتاییدا دەڵێت نەخێر، هەموو بانگکردنە چاوەڕوانەکان یەک لە دوای یەک تەواو دەبن و هەر یەکەیان دێڕی ماڵئاوایی خۆی چاپ دەکات.
Exercisesڕاهێنانەکان
One more: remember the best scoreیەکێکی تر: باشترین خاڵ لەبیر بێت
The game says “New best score today!” because best is a variable: it is lost when the program ends. Keep the best score in a file best_score.txt instead. Write load_best() (the saved number, or 0 when there is no file yet) and save_best(best), and use them in main().
یارییەکە دەڵێت «New best score today!» چونکە best : کاتێک کۆتایی دێت ون دەبێت. لە جیاتی ئەوە باشترین خاڵ لە best_score.txtـدا هەڵبگرە. load_best() (ژمارە هەڵگیراوەکە، یان 0 کاتێک هێشتا نییە) و save_best(best) بنووسە و لە main()ـدا بەکاریان بهێنە.
Hintئاماژە
Copy the pattern of A counter that remembers: read inside try, start from 0 on FileNotFoundError, write with mode "w".
شێوازی ژمێرەرێک کە لەبیری ناچێت کۆپی بکە: لە ناو try بیخوێنەرەوە، لە FileNotFoundErrorـدا لە 0ـەوە دەست پێ بکە و بە دۆخی "w" بینووسە.
Show answerوەڵامەکە پیشان بدە
BEST_FILE = "best_score.txt"
def load_best():
"""Return the saved best score, or 0 if there is none yet."""
try:
with open(BEST_FILE, encoding="utf-8") as f:
return int(f.read())
except (FileNotFoundError, ValueError): # no file yet, or no number in it
return 0
def save_best(best):
"""Write the best score into BEST_FILE for the next run."""
with open(BEST_FILE, "w", encoding="utf-8") as f:
f.write(str(best))In main(), best = 0 becomes best = load_best(), and right after best = score add save_best(best); the message can now say “New best score!”. ValueError is caught too, so a file that holds no number starts from 0 instead of crashing (Catching file errors). Two runs, one after the other:
لە main()ـدا best = 0 دەبێت بە best = load_best() و ڕاستەوخۆ دوای best = score بنووسە save_best(best)؛ ئێستا پەیامەکە دەتوانێت بڵێت «New best score!». ValueErrorـیش دەگیرێت، بۆیە کە ژمارەی تێدا نییە لە 0ـەوە دەست پێ دەکات لە جیاتی ئەوەی بوەستێت (گرتنی هەڵەکانی فایل). دوو جێبەجێکردن، یەک لە دوای یەک:
=== Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming words, 2 = Kurdish words: 1 Letters: p o l o Your guess: loop Correct! +3 points Letters: d n i x e Your guess: quit Score: 3 out of 15 New best score! Best score: 3. Goodbye! === Mixed Letters === Unmix 5 words. You have 3 tries for each word. Type quit at any time to stop. 1 = programming words, 2 = Kurdish words: 1 Letters: t s i l Your guess: slit Not this one. Hint: it starts with l Tries left: 2 Your guess: list Correct! +2 points Letters: y t h o n p Your guess: quit Score: 2 out of 15 Best score: 3. Goodbye!
The second run scored only 2, but it still knows the best score 3 from the first run: the file kept it.
جێبەجێکردنی دووەم تەنها 2 خاڵی هێنا، بەڵام هێشتا باشترین خاڵی 3ـی جێبەجێکردنی یەکەم دەزانێت: هەڵیگرتبوو.
Summaryپوختە
- Plan first: a scenario, a flowchart with standard symbols, then one function per job.
- Scramble a word with
list(word),random.shuffle(letters)(in place, returnsNone) and"".join(letters); shuffle again until the mix differs. random.sample()gives different items;random.choice()may repeat.- Validate input before you use it: clean it with
.strip().lower(), check it, explain the problem and ask again. - Pass results with return values: points,
Nonefor “quit”, a tuple for two results. - Repeat games with a loop, not by calling
main()again; catchKeyboardInterruptfor a clean Ctrl+C. - Test random code with
random.seed()andassert— and keep the seed out of the real game.
- سەرەتا پلان: ، بە ، پاشان بۆ هەر کارێک .
- وشەیەک بە
list(word)،random.shuffle(letters)(لە شوێنی خۆیدا،Noneدەگەڕێنێتەوە) و"".join(letters)تێکەڵ بکە؛ دووبارە تێکەڵ بکە تا جیاواز دەبێت. random.sample()جیاواز دەدات؛random.choice()دەشێت دووبارە بکاتەوە.- پێش بەکارهێنان بپشکنە: بە
.strip().lower()پاکی بکەرەوە، بیپشکنە، کێشەکە ڕوون بکەرەوە و دووبارە بپرسە. - ئەنجامەکان بە بگوازەرەوە: خاڵ،
Noneبۆ «وەستان»، بۆ دوو ئەنجام. - یارییەکان بە دووبارە بکەرەوە، نەک بە دووبارە بانگکردنی
main()؛KeyboardInterruptبگرە بۆ Ctrl+Cـێکی ئارام. - کۆدی هەڵکەوتی بە
random.seed()وassertتاقی بکەرەوە — و لە یارییە ڕاستەقینەکەدا دامەنێ.
Why do we turn the word into a list before shuffling?بۆچی پێش تێکەڵکردن وشەکە دەکەین بە لیست؟
Strings are immutable and shuffle() changes its argument in place; a list can be changed.
و shuffle() لە شوێنی خۆیدا دەگۆڕێت؛ دەگۆڕدرێت.
How does guess_problem() know that two words use the same letters?guess_problem() چۆن دەزانێت دوو وشە هەمان پیتەکانیان هەیە؟
It compares sorted(guess) with sorted(word): equal sorted lists mean the same letters. (How sorting works: Sorting algorithms.)
sorted(guess) لەگەڵ sorted(word) بەراورد دەکات: ڕیزکراوی یەکسان واتە هەمان پیت. (چۆنیەتیی : ئەلگۆریزمەکانی ڕیزکردن.)
What does play_round() return?play_round() چی دەگەڕێنێتەوە؟
The points (3, 2, 1 or 0), or None if the player typed quit.
خاڵەکان (3، 2، 1 یان 0)، یان None ئەگەر یاریزان quitـی نووسیبێت.
Why is if __name__ == "__main__": useful here?بۆچی if __name__ == "__main__": لێرەدا بەسوودە؟
The test file can import scramble() and guess_problem() without starting the game.
تاقیکردنەوە دەتوانێت scramble() و guess_problem() import بکات بەبێ دەستپێکردنی یارییەکە.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Python Next to JavaPython لە تەنیشت Javaـەوە
Related lecturesوانە پەیوەندیدارەکان
- Algorithms, Pseudocode and Flowchartsئەلگۆریزمەکان، نیمچەکۆد و هێڵکارییەکانی ڕەوت
- Controlling Loops: break and continueکۆنترۆڵکردنی خولەکان:
breakوcontinue - Modules and importمۆدیوڵەکان و import
- Handling Errors with try and exceptمامەڵەکردن لەگەڵ هەڵاوێردە بە try و except
- Project: Binary to Decimal Converterپڕۆژیلە: گۆڕینی دووانی بۆ دەیی
- Python Next to JavaPython لە تەنیشت Javaـەوە
- Reading and Writing Filesخوێندنەوە و نووسینی فایلەکان
- Bubble Sort, Insertion Sort and How Fast Sorting Isڕیزکردنی بڵقی، ڕیزکردن بە تێخستن و خێرایی ڕیزکردن
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- Python documentation: random — Generate pseudo-random numbers
- Harvard CS50's Introduction to Programming with Python, Lecture 2: Loops (lists, validation loops)
- Python documentation: Built-in functions (sorted, input)
- Python documentation: Built-in types (str.join, truth value testing)
- Python tutorial: Errors and exceptions (KeyboardInterrupt)
- Python tutorial: Modules (executing modules as scripts, __name__)
- Python language reference: the assert statement
- Python documentation: sys.getrecursionlimit()
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.