Chapterبەش 3 · Lectureوانە 3.1
The Python You Need for the AI Labsئەو Pythonـەی بۆ تاقیگەکانی ژیریی دەستکرد پێویستە
Just the Python the AI labs use: lists as stacks and queues, tuples, sets, dictionaries and nested dictionaries, all(), grids built with list comprehensions, a Point class with __repr__, int() and str(), float('inf'), conditional expressions, and how to read user input safely without eval().
تەنها ئەو تاقیگەکانی بەکاری دەهێنن: وەک و ، ، ، و ، all()، تۆڕی خانەکان بە ، Point لەگەڵ __repr__، int() و str()، float('inf')، دەربڕینی مەرجی و چۆنیەتیی خوێندنەوەی بە سەلامەتی بەبێ eval().
What you will learnچی فێر دەبیت
- Run a Python 3 program and respect indentation.
- Use a list as a stack or a queue, and tuples and sets where they fit.
- Create, read, change and loop through dictionaries and nested dictionaries.
- Use all(), list comprehensions, float('inf') and conditional expressions as the labs do.
- Write a small class with __init__ and __repr__.
- Read user input safely with int(), try/except and a range check, never eval().
- Python 3 کار پێبکەیت و ڕێز لە بگریت.
- وەک یان بەکار بهێنیت، هەروەها و لە شوێنی گونجاودا.
- و دروست بکەیت، بیانخوێنیتەوە، بیانگۆڕیت و بەسەریاندا بکەیت.
- all()، ، float('inf') و دەربڕینی مەرجی وەک تاقیگەکان بەکار بهێنیت.
- بچووک بە __init__ و __repr__ بنووسیت.
- بە سەلامەتی بە int()، try/except و پشکنینی سنوور بخوێنیتەوە، هەرگیز بە eval() نا.
Python for the AI labsPython بۆ تاقیگەکانی ژیریی دەستکرد
All the labs of this course are written in Python 3, a free programming language with short, readable code. CêIT teaches Python in full in the Python track of Fundamentals of Programming; this lesson teaches only what the lab programs need: lists, tuples, sets, dictionaries, all(), grids, classes, a few useful tricks and safe input. Each screen points to the lab where the idea is used.
هەموو تاقیگەکانی ئەم کۆرسە بە Python 3 نووسراون، بێبەرانبەرە کە کۆدەکەی کورت و ئاسانە بۆ خوێندنەوە. CêIT بە تەواوی لە بەشی بنەماکانی بەرنامەسازی فێر دەکات؛ ئەم وانەیە تەنها ئەوە فێر دەکات کە تاقیگەکان پێویستیانە: ، ، ، ، all()، تۆڕی خانەکان، ، چەند فێڵێکی بەسوود و وەرگرتنی بە سەلامەتی. هەر لاپەڕەیەک ئاماژە بەو تاقیگەیە دەکات کە بیرۆکەکەی تێدا بەکار دێت.
- Installدابەزاندن
Install the newest Python 3 from python.org. The labs were made with Python 3.9 in the PyCharm IDE; 3.9 is no longer supported, but all the code in this course also runs on newer versions.
نوێترین وەشانی Python 3 لە python.org دابەزێنە. تاقیگەکان بە Python 3.9 لە PyCharmـدا دروست کراون، کە . وەشانی 3.9 چیتر پشتگیری ناکرێت، بەڵام هەموو کۆدەکانی ئەم کۆرسە لەسەر وەشانە نوێترەکانیش کار دەکەن.
- Writeنووسین
Save your code in a file that ends in
.py, for examplehello.py.کۆدەکەت لە فایلێکدا هەڵبگرە کە بە
.pyکۆتایی دێت، بۆ نموونەhello.py. - Runکارپێکردن
Open a terminal in the same folder (on Windows, see Open Command Prompt) and type
python3 hello.py(on Windows:python hello.py), or press Run in PyCharm.لە هەمان بوخچەدا بکەرەوە (لەسەر Windows بڕوانە کردنەوەی Command Prompt) و
python3 hello.pyبنووسە (لە Windows:python hello.py)، یان لە PyCharmـدا Run دابگرە.
print("Hello, AI lab!")
print(2 + 3)Hello, AI lab! 5
Every program in this course was run like this, and the output under each code block is the real output.
هەموو لەم کۆرسەدا بەم شێوەیە کاری پێکراوە و ئەو لە ژێر هەر کۆدێکە ڕاستەقینەیە.
Listsلیستەکان
An ordered, changeable collection of values, written in square brackets: [3, 8, 0]. Items are numbered from 0, and a list can grow or shrink. Python calls it a list; Dart has List; PHP uses an for the same job.
کۆکراوەیەکی ڕیزکراو و گۆڕاوی نرخەکانە کە لەناو کەوانەی چوارگۆشەدا دەنووسرێت: [3, 8, 0]. دانەکان لە 0ەوە ژمارە دەکرێن و لیست دەتوانێت گەورە یان بچووک ببێتەوە. Python پێی دەڵێت list و Dart List؛ PHP بۆ هەمان کار بەکار دەهێنێت.
A list keeps several values in order, inside square brackets. Each item has an index: the first item is at index 0, the second at index 1, and so on. A negative index counts from the end: -1 is the last item. append() adds an item at the end and len() gives the number of items.
چەند نرخێک بە ڕیز لە ناو کەوانەی چوارگۆشەدا هەڵدەگرێت. هەر دانەیەک هەیە: یەکەم دانە لە 0دایە، دووەم لە 1 و هتد. لە کۆتاییەوە دەژمێرێت: -1 دوایین دانەیە. append() دانەیەک دەخاتە کۆتایی و len() ژمارەی دانەکان دەدات.
cities = ["Erbil", "Duhok", "Halabja"]
print(cities[0]) # the first item has index 0
print(cities[-1]) # a negative index counts from the end
cities.append("Zakho") # add to the end
print(cities, len(cities))Erbil Halabja ['Erbil', 'Duhok', 'Halabja', 'Zakho'] 4
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Index 0 is the first item.
0 یەکەم دانەیە.
- Lineدێڕی 3
Index -1 is the last item.
-1 دوایین دانەیە.
In Kurdish: how to make a Python list, read items by index (also the negative index -1), change an item and join two lists.
بە کوردی: چۆن دروست دەکەیت، بە دەخوێنیتەوە (لەوانە نەرێنیی -1)، دەگۆڕیت و دوو پێکەوە دەلکێنیت.
Kurdish video: making a list, index 0 and -1, changing an item and joining lists with +.
بە کوردی: دروستکردنی ، 0 و -1، گۆڕینی و لکاندنی بە +.
Listsلیستەکان
A list as a stack or a queueلیست وەک ستاک یان کیوو
Search algorithms keep a frontier: the places still waiting to be explored. The labs store it in a list and take items out in one of two ways. pop() takes the last item: the list works as a stack (last in, first out), which gives depth-first search. pop(0) takes the first item: the list works as a queue (first in, first out), which gives breadth-first search.
هەڵدەگرن: ئەو شوێنانەی هێشتا چاوەڕێی پشکنینن. تاقیگەکان لە هەڵیدەگرن و بە یەکێک لە دوو ڕێگە دانەکان دەردەهێنن. pop() دوایین دانە دەبات: وەک کار دەکات (دوایین هات، یەکەم دەچێت)، کە دەدات. pop(0) یەکەم دانە دەبات: وەک کار دەکات (یەکەم هات، یەکەم دەچێت)، کە دەدات.
from collections import deque
frontier = [1, 2, 3]
print(frontier.pop()) # stack: take the LAST item
print(frontier)
frontier = [1, 2, 3]
print(frontier.pop(0)) # queue: take the FIRST item
print(frontier)
frontier = deque([1, 2, 3])
print(frontier.popleft()) # a fast queue
print(frontier)3 [1, 2] 1 [2, 3] 1 deque([2, 3])
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
deque(double-ended queue) comes with Python, in thecollectionsmodule.deque( دووسەر) لەگەڵ دێت، لەcollections.- Lineدێڕی 4
Stack: the last item comes out.
: دوایین دانە دەردەچێت.
- Lineدێڕی 8
Queue: the first item comes out.
: یەکەم دانە دەردەچێت.
- Lineدێڕی 12
Same result as
pop(0), but fast even for very long queues.هەمان ئەنجامی
pop(0)، بەڵام تەنانەت بۆ زۆر درێژیش خێرایە.
Tuples and setsتاپڵەکان و کۆمەڵەکان
A tuple is like a list that cannot be changed after it is made. It is written in round brackets: (0, 0). The labs use tuples for positions (row, column) and for heap entries such as (priority, count, item). A tuple can be split into variables in one step: x, y = start.
وەک کە دوای دروستکردنی ناگۆڕدرێت. لە ناو کەوانەی ئاساییدا دەنووسرێت: (0, 0). تاقیگەکان بۆ شوێنەکان (ڕیز، ستوون) و بۆ دانەکانی وەک (priority, count, item) بەکار دەهێنن. دەکرێت بە یەک هەنگاو دابەش بکرێت بەسەر : x, y = start.
A set keeps different values with no order and no duplicates. Asking whether a value is in a set is very fast, so search programs often keep the explored places in a set.
نرخی جیاواز بەبێ ڕیزبەندی و بەبێ دووبارەبوونەوە هەڵدەگرێت. پرسینی ئەوەی ئایا نرخێک in (لە ناو) زۆر خێرایە، بۆیە گەڕان زۆرجار شوێنە پشکنراوەکان لە هەڵدەگرن.
start = (0, 0) # a tuple: (row, column)
x, y = start # unpack it into two variables
print(x, y)
explored = set() # a set: no duplicates, very fast "in" test
explored.add((0, 0))
explored.add((0, 1))
explored.add((0, 0)) # already there: nothing changes
print(len(explored), (0, 1) in explored, (5, 5) in explored)
parent = {start: None} # tuples can be dictionary keys (lists cannot)
parent[(0, 1)] = start
print(parent)0 0
2 True False
{(0, 0): None, (0, 1): (0, 0)}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Destructuring assignment: the tuple's two values go into
xandy.: دوو نرخەکەی دەچنە ناو
xوy.- Lineدێڕی 8
Adding a value that is already there changes nothing.
زیادکردنی نرخێک کە پێشتر هەیە هیچ ناگۆڕێت.
- Lineدێڕی 11
A tuple can be a dictionary key; a list cannot, because a list can change.
دەتوانێت ببێتە ؛ ناتوانێت، چونکە دەگۆڕێت.
Dictionariesفەرهەنگەکان
A Python collection of key–value pairs written in curly braces, such as {'name': 'Aram', 'age': 20}. You look up a value by its key, like looking up a word in a dictionary.
کۆکراوەیەکی لە کە لەناو {}دا دەنووسرێت، وەک {'name': 'Aram', 'age': 20}. نرخێک بە دەدۆزیتەوە، وەک دۆزینەوەی وشەیەک لە فەرهەنگدا.
A Python dictionary is like a real-life dictionary: it stores words (the keys) and their meanings (the values). You look up a word and get its meaning; you look up a key and get its value.
لە وەک فەرهەنگێکی ژیانی ڕاستەقینەیە: وشەکان () و واتاکانیان () هەڵدەگرێت. بە دوای وشەیەکدا دەگەڕێیت و واتاکەی وەردەگریت؛ بە دوای دەگەڕێیت و وەردەگریت.
Where the analogy stops workingسنووری ئەم نموونەیە
In a paper dictionary one word can have several meanings; in a Python dictionary each key has exactly one value (which may itself be a list or another dictionary), and each key appears only once.
لە فەرهەنگێکی کاغەزیدا یەک وشە دەکرێت چەند واتایەکی هەبێت؛ لە هەر ڕێک یەک نرخی هەیە (کە دەکرێت خۆی یان تر بێت) و هەر تەنها یەک جار دەردەکەوێت.
Start with curly braces
{}.بە کەوانەی لوولی
{}دەست پێبکە.Inside, write key: value pairs. A colon
:separates the key (the word you look up) from its value (its meaning).لە ناویدا جووتی : بنووسە. دوو خاڵ
:(ئەو وشەیەی بە دوایدا دەگەڕێیت) لە (واتاکەی) جیا دەکاتەوە.Separate the pairs with commas.
جووتەکان بە فاریزە لێک جیا بکەرەوە.
my_dict = {
"name": "Aram", # "name" is the key, "Aram" is the value
"age": 25, # "age" is the key, 25 is the value
"city": "Erbil" # "city" is the key, "Erbil" is the value
}
print(my_dict["name"])Aram
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-4
Three key: value pairs. Keys are "name", "age", "city"; values are "Aram", 25, "Erbil".
سێ جووتی : . : "name"، "age"، "city"؛ : "Aram"، 25، "Erbil".
- Lineدێڕی 6
Look up a key in square brackets to get its value.
لە ناو کەوانەی چوارگۆشەدا بنووسە بۆ وەرگرتنی نرخەکەی.
Python dictionaries: key-value pairs, get() with a default, adding, changing and deleting, and looping with items().
: ، get() لەگەڵ ، زیادکردن و گۆڕین و سڕینەوە، هەروەها بە items().
Whole video: dictionaries, get(), changing values and looping with items().
هەموو ڤیدیۆکە: ، get()، گۆڕینی و بە items().
Dictionariesفەرهەنگەکان
Nested dictionariesفەرهەنگە ناوەکییەکان
A nested dictionary is a dictionary inside another dictionary. It helps to store more complex data, for example several people with several details each. To build one:
لە ناو تردا. یارمەتی دەدات ئاڵۆزتر هەڵبگیرێت، بۆ نموونە چەند کەسێک کە هەر یەکەیان چەند وردەکارییەکی هەیە. بۆ دروستکردنی:
Make an outer dictionary.
دەرەوە دروست بکە.
For a key, make an inner dictionary as its value, with its own keys and values.
بۆ ، ناوەکی وەک نرخەکەی دروست بکە، بە و نرخەکانی خۆیەوە.
Repeat for deeper levels if you need them.
ئەگەر پێویستت بوو بۆ ئاستی قووڵتر دووبارەی بکەرەوە.
people = {
"person1": {"name": "Aram", "age": 25, "city": "Erbil"},
"person2": {"name": "Shilan", "age": 30, "city": "Sulaymaniyah"}
}
print(people["person1"]["name"]) # outer key first, then inner key
print(people["person2"]["age"])Aram 30
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-3
Each outer key holds a whole inner dictionary.
هەر دەرەوە ناوەکیی تەواو هەڵدەگرێت.
- Lineدێڕی 5-6
Use the outer key first, then the inner key.
سەرەتا دەرەوە بەکار بهێنە، پاشان ناوەوە.
Dictionariesفەرهەنگەکان
Looping through a dictionaryخولانەوە بەسەر فەرهەنگێکدا
The method items() gives both the key and the value of every pair, so you can use both inside a for loop. The first loop below prints each person and their whole inner dictionary. The second loop also goes through the inner dictionary, printing one detail per line. f"{key}: {value}" is an f-string: Python puts the values of the variables in the curly braces into the text.
items() هەم و هەم ی هەموو جووتێک دەدات، بۆیە دەتوانیت هەردووکیان لە ناو بەکار بهێنیت. یەکەم خوارەوە هەر کەسێک و هەموو چاپ دەکات. دووەم بەسەر دەسووڕێتەوە و هەر وردەکارییەک لە دێڕێکدا چاپ دەکات. f"{key}: {value}" f-stringـە: نرخی ئەو لە ناو {}دان دەخاتە ناو دەقەکەوە.
people = {
"person1": {"name": "Aram", "age": 25, "city": "Erbil"},
"person2": {"name": "Shilan", "age": 30, "city": "Sulaymaniyah"}
}
# Loop through the outer dictionary
for person, details in people.items():
print(person)
print(details)
# Loop through the outer AND the inner dictionary
for person, details in people.items():
print(person)
for key, value in details.items():
print(f"{key}: {value}")
print()person1
{'name': 'Aram', 'age': 25, 'city': 'Erbil'}
person2
{'name': 'Shilan', 'age': 30, 'city': 'Sulaymaniyah'}
person1
name: Aram
age: 25
city: Erbil
person2
name: Shilan
age: 30
city: SulaymaniyahThis is exactly the output the lab notes show (with our names instead of the notes' example names).
ئەمە ڕێک ئەو کە تێبینییەکانی تاقیگە پیشانی دەدەن (بە ناوەکانی ئێمە لەبری ناوە نموونەییەکانی تێبینییەکان).
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 7-9
persongets the outer key,detailsthe inner dictionary.personدەرەوە وەردەگرێت،details.- Lineدێڕی 14-15
A nested loop over the inner dictionary.
بەسەر .
- Lineدێڕی 16
An empty
print()leaves a blank line between people.print()ی بەتاڵ دێڕێکی بەتاڵ لە نێوان کەسەکاندا دادەنێت.
Dictionariesفەرهەنگەکان
Adding, changing and safe readingزیادکردن، گۆڕین و خوێندنەوەی سەلامەت
You can add a new pair or change a value by assigning to a key. in asks whether a key exists. Reading a missing key with square brackets stops the program with a KeyError, but .get() returns None (or a default value you give) instead.
دەتوانیت جووتێکی نوێ زیاد بکەیت یان نرخێک بگۆڕیت بە بۆ . in دەپرسێت ئایا هەیە. خوێندنەوەی کە نییە بە کەوانەی چوارگۆشە بە KeyError دەوەستێنێت، بەڵام .get() لەبری ئەوە None (یان ئەو خۆت دەیدەیت) دەگەڕێنێتەوە.
grades = {"Aram": 90, "Hana": 75}
grades["Rezan"] = 82 # add a new pair
grades["Hana"] = 78 # change a value
print(grades)
print("Aram" in grades, "Dilan" in grades)
print(grades.get("Dilan")) # missing key: None instead of an error
print(grades.get("Dilan", 0)) # or a default value of your choice{'Aram': 90, 'Hana': 78, 'Rezan': 82}
True False
None
0Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-3
Assigning to a new key adds it; assigning to an existing key changes its value.
بۆ نوێ زیادی دەکات؛ بۆ هەبوو نرخەکەی دەگۆڕێت.
- Lineدێڕی 6-7
.get()never crashes on a missing key..get()لەسەر نەبوو هەرگیز تێک ناچێت.
The search labs use exactly this: parent = {start: None} remembers, for every place, the place it was reached from, and parent.get(current) walks back from the goal to the start.
تاقیگەکانی گەڕان ڕێک ئەمە بەکار دەهێنن: parent = {start: None} بۆ هەر شوێنێک ئەو شوێنەی لێیەوە پێی گەیشتراوە لە بیر دەگرێت و parent.get(current) لە ئامانجەوە بەرەو دەستپێک دەگەڕێتەوە.
Checking everything at once: all()پشکنینی هەموو شتێک بە یەکجار: all()
all() is a built-in function. Its syntax is all(iterable): you give it anything you can loop over (a list, tuple, set or dictionary). It returns True if all the elements are “truthy”, and False as soon as one element is “falsy”.
all() . all(iterable)ـە: هەر شتێکی پێ دەدەیت کە بتوانیت بەسەریدا بکەیت (، ، یان ). ئەگەر هەموو دانەکان «ڕاستئاسا» (truthy) بن True دەگەڕێنێتەوە و هەر کە یەک دانە «هەڵەئاسا» (falsy) بێت False.
| Truthy (count as true)ڕاستئاسا (truthy) | Falsy (count as false)هەڵەئاسا (falsy) |
|---|---|
non-zero numbers: 1, -3, 2.5ژمارەی جگە لە سفر: 1، -3، 2.5 | 0, 0.00، 0.0 |
non-empty strings: 'a': 'a' | the empty string '': '' |
non-empty collections: [1], {'k': 1}کۆکراوەی نابەتاڵ: [1]، {'k': 1} | empty collections: [], {}, set()کۆکراوەی بەتاڵ: []، {}، set() |
TrueTrue | False, NoneFalse، None |
print(all([1, 2, 3])) # True
print(all(['a', 'b', 'c'])) # True
print(all([1, 0, 3])) # False: 0 is falsy
print(all(['a', '', 'c'])) # False: '' is falsy
print(all([])) # True: nothing is falsy
numbers = [2, 4, 6, 8]
print(all(num > 0 for num in numbers)) # TrueTrue True False False True True
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5
An empty list gives
True: there is no falsy element in it.بەتاڵ
Trueدەدات: هیچ دانەیەکی هەڵەئاسای تێدا نییە.- Lineدێڕی 8
A generator expression:
num > 0is checked for every number.دەربڕینێکی :
num > 0بۆ هەموو ژمارەیەک دەپشکنرێت.
all() is often used with a short loop inside it, as in the tic-tac-toe win check: “are all three cells of this row 'x'?”. Its partner any() returns True if at least one element is true.
all() زۆرجار لەگەڵ کورت لە ناویدا بەکار دێت، وەک پشکنینی بردنەوە لە یاریی ئێکسوئۆدا: «ئایا هەر سێ خانەی ئەم ڕیزە 'x'ن؟». هاوڕێکەی، any()، ئەگەر لانیکەم یەک دانە ڕاست بێت True دەگەڕێنێتەوە.
row = ['x', 'x', 'x']
print(all(cell == 'x' for cell in row)) # three x in a row?
row = ['x', 'o', 'x']
print(all(cell == 'x' for cell in row))
print(any(cell == 'o' for cell in row)) # any(): True if at least one is trueTrue False True
Grids: lists inside a listتۆڕی خانەکان: لیست لە ناو لیست
The maze labs store the maze as a list of strings, one string per row. maze[x][y] is the cell in row x and column y. len(maze) is the number of rows and len(maze[0]) the number of columns. The labs also need a second grid of the same size, for example seen, which records whether each cell has been visited. The short way to build it is a list comprehension: a loop written inside square brackets.
تاقیگەکانی وەک لە هەڵدەگرن، بۆ هەر ڕیزێک یەک . maze[x][y] ئەو خانەیەیە کە لە ڕیزی x و ستوونی yدایە. len(maze) ژمارەی ڕیزەکانە و len(maze[0]) ژمارەی ستوونەکان. تاقیگەکان پێویستیان بە تۆڕێکی دووەمیش هەیە بە هەمان قەبارە، بۆ نموونە seen، کە تۆماری دەکات ئایا هەر خانەیەک سەردانی کراوە. ڕێگا کورتەکە بۆ دروستکردنی ـە: کە لە ناو کەوانەی چوارگۆشەدا نووسراوە.
maze = [
"..#",
".#.",
"...",
]
print(len(maze), len(maze[0])) # rows, columns
print(maze[1][1]) # row 1, column 1 -> a wall
# A grid of False values with the same size as the maze (list comprehension)
seen = [[False for column in row] for row in maze]
print(seen)
# The same grid with two ordinary loops
seen2 = []
for row in maze:
new_row = []
for column in row:
new_row.append(False)
seen2.append(new_row)
print(seen == seen2)
x, y = 2, 3 # is (2, 3) inside the maze?
print(0 <= x < len(maze) and 0 <= y < len(maze[0]))3 3 # [[False, False, False], [False, False, False], [False, False, False]] True False
(2, 3) is outside: the maze has only 3 columns (0, 1 and 2).
(2, 3) لە دەرەوەیە: تەنها 3 ستوونی هەیە (0، 1 و 2).
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 7
Row 1, column 1:
#is a wall.ڕیزی 1، ستوونی 1:
#دیوارە.- Lineدێڕی 10
List comprehension: for every row, a new list with one
Falseper cell.: بۆ هەر ڕیزێک، نوێ بە یەک
Falseبۆ هەر خانەیەک.- Lineدێڕی 14-19
The same grid with ordinary nested loops.
هەمان تۆڕ بە ئاسایی.
- Lineدێڕی 22-23
The bounds check the maze labs use: not above the first row, not below the last, and the same for columns.
ئەو پشکنینی سنوورەی تاقیگەکانی بەکاری دەهێنن: نە سەرووی یەکەم ڕیز، نە خوارووی دوایین ڕیز و هەمان شت بۆ ستوونەکان.
Classes: the Point of the maze labsکلاسەکان: Pointـی تاقیگەکانی لابیرینت
A class is a blueprint for objects. The maze labs define a class Point for a cell. __init__ is a special method that runs when a new object is made: it stores the values as attributes of the object (self.x, self.y). self means “this object”. A parameter can have a default value, as in parent=None.
نەخشەیەکە بۆ . تاقیگەکانی بە ناوی Point بۆ خانەیەک پێناسە دەکەن. __init__ تایبەتە کە کاتێک نوێ دروست دەکرێت کار دەکات: نرخەکان وەک هەڵدەگرێت (self.x، self.y). self واتە «ئەم ». دەتوانێت هەبێت، وەک parent=None.
class Point:
def __init__(self, x, y, parent=None):
self.x = x # row
self.y = y # column
self.parent = parent # the point we came from (None at the start)
def __repr__(self):
return f"({self.x}, {self.y})"
start = Point(0, 0)
step = Point(0, 1, start)
print(step.x, step.y)
print(step.parent)
print([start, step])0 1 (0, 0) [(0, 0), (0, 1)]
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-5
__init__stores the row, the column and the point we came from.__init__ڕیز، ستوون و ئەو خاڵەی لێیەوە هاتووین هەڵدەگرێت.- Lineدێڕی 7-8
__repr__says how a point is shown when printed.__repr__دەڵێت خاڵێک لە کاتی چاپکردندا چۆن پیشان بدرێت.- Lineدێڕی 12
The second point remembers the first as its parent.
خاڵی دووەم خاڵی یەکەم وەک باوکی خۆی لە بیر دەگرێت.
Why __repr__? Without it, Python prints the object's address in memory, which tells you nothing. The lab code says it plainly: it is there to stop the address of the object from being printed.
بۆچی __repr__؟ بەبێ ئەو، ناونیشانی لە چاپ دەکات، کە هیچت پێ ناڵێت. کۆدی تاقیگەکە بە ڕوونی دەیڵێت: بۆ ئەوەیە ناونیشانی چاپ نەکرێت.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
print([Point(0, 0), Point(0, 1)])[<__main__.Point object at 0x109b93c10>, <__main__.Point object at 0x109b93fa0>]
The hexadecimal numbers are memory addresses; yours will be different every run.
ژمارە شازدەییەکان ناونیشانی ؛ هی تۆ لە هەر کارپێکردنێکدا جیاواز دەبن.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 7
The numbers after
atare memory addresses: they are different on every computer and in every run.ژمارەکانی دوای
atناونیشانی ناو : لە هەر و لە هەر جارێکی کارپێکردندا جیاوازن.
What a class is, how __init__ and self store attributes, and how to make objects from a class.
چییە، __init__ و self چۆن هەڵدەگرن و چۆن لە دروست دەکەیت.
Watch 0:00-8:47: classes, __init__, self and attributes.
لە 0:00 تا 8:47 سەیر بکە: ، __init__، self و .
Three small toolsسێ ئامرازی بچووک
Three small things appear again and again in the labs: converting between text and numbers, infinity as a starting value, and choosing between two values in one line. Each has its own short screen.
سێ شتی بچووک لە تاقیگەکاندا دووبارە و دووبارە دەردەکەون: گۆڕین لە نێوان دەق و ژمارەدا، وەک نرخی سەرەتا و هەڵبژاردن لە نێوان دوو نرخدا لە یەک دێڕدا. هەر یەکەیان لاپەڕەیەکی کورتی خۆی هەیە.
Three small toolsسێ ئامرازی بچووک
Text to number and backدەق بۆ ژمارە و بەپێچەوانەوە
"123" (text, a string) and 123 (a number, an integer) are different things. int() turns a string into an integer, and str() turns an integer into a string. This matters because input() always gives back a string, even when the user types a number. More in Turning text into numbers.
"123" (دەق، ) و 123 (ژمارە، ) دوو شتی جیاوازن. int() دەکات بە و str() دەکات بە . ئەمە گرنگە چونکە input() هەمیشە دەگەڕێنێتەوە، تەنانەت کاتێک ژمارەیەک دەنووسێت. زیاتر لە گۆڕینی دەق بۆ ژمارە.
# String to integer
string_number = "123"
integer_number = int(string_number)
print(integer_number) # 123
print(integer_number + 1) # now it is a number: 124
# Integer to string
integer_number = 123
string_number = str(integer_number)
print(string_number) # 123
print(string_number + "4") # now it is text: 1234123 124 123 1234
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
int("123")gives the number 123.int("123")ژمارەی 123 دەدات.- Lineدێڕی 5
It really is a number now: 123 + 1 = 124.
ئێستا بەڕاستی ژمارەیە: 123 + 1 = 124.
- Lineدێڕی 9
str(123)gives the text "123".str(123)دەقی "123" دەدات.- Lineدێڕی 11
It really is text now: "123" + "4" joins them.
ئێستا بەڕاستی دەقە: "123" + "4" پێکەوەیان دەلکێنێت.
Three small toolsسێ ئامرازی بچووک
Infinity as a starting valueبێسنوور وەک نرخی سەرەتا
float('inf') is positive infinity, a special float value (from the IEEE 754 standard) that is larger than every other number. Any comparison like float('inf') > 1000000 is True. Search code uses it as a starting value that any real cost will beat; the A* lab fills a grid with it to mean “not reached yet”.
float('inf') موجەبـە، نرخێکی تایبەتی (لە ستانداردی IEEE 754) کە لە هەموو ژمارەیەکی تر گەورەترە. هەر بەراوردێکی وەک float('inf') > 1000000 Trueـە. کۆدی گەڕان وەک نرخی سەرەتایی بەکاری دەهێنێت کە هەر تێچوویەکی ڕاستەقینە لێی دەباتەوە؛ تاقیگەی A* تۆڕێکی پێ پڕ دەکاتەوە بە واتای «هێشتا پێی نەگەیشتووین».
best = float('inf') # positive infinity: larger than any number
print(best > 10 ** 100)
for cost in [7, 3, 9]:
if cost < best:
best = cost
print(best)
distance = [[float('inf') for _ in range(3)] for _ in range(2)]
distance[0][0] = 0 # the start is 0 steps away
print(distance)True 3 [[0, inf, inf], [inf, inf, inf]]
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-5
Find the smallest cost: every real cost is smaller than infinity, so the first one always wins.
بچووکترین تێچوو بدۆزەوە: هەموو تێچوویەکی ڕاستەقینە لە بچووکترە، بۆیە یەکەمیان هەمیشە دەباتەوە.
- Lineدێڕی 8-9
A grid of “not reached yet”, with 0 steps for the start.
تۆڕێکی «هێشتا پێی نەگەیشتووین»، بە 0 هەنگاو بۆ دەستپێک.
Three small toolsسێ ئامرازی بچووک
Choosing a value in one lineهەڵبژاردنی نرخێک لە یەک دێڕدا
A conditional expression picks one of two values: value_if_true if condition else value_if_false. The tic-tac-toe lab uses it to switch players: if the player is 'x' the next one is 'o', otherwise 'x'. Fundamentals of Programming has the same screen: Choosing a value in one line.
دەربڕینی مەرجی () یەکێک لە دوو نرخ هەڵدەبژێرێت: value_if_true if condition else value_if_false. تاقیگەی ئێکسوئۆ بۆ گۆڕینی یاریزان بەکاری دەهێنێت: ئەگەر یاریزانەکە 'x' بێت داهاتوو 'o'ـە، ئەگەر نا 'x'. بنەماکانی هەمان لاپەڕەی هەیە: هەڵبژاردنی نرخێک لە یەک دێڕدا.
player = 'x'
for turn in range(4):
print(turn, player)
player = 'o' if player == 'x' else 'x' # switch players0 x 1 o 2 x 3 o
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4
The whole if/else in one line.
هەموو if/elseـەکە لە یەک دێڕدا.
Reading input safelyخوێندنەوەی نێوخستە بە سەلامەتی
Several labs ask the user to type a row and a column. input() returns the whole line as one string, for example "4 8". .split() cuts it at the spaces into a list of strings, and map(int, …) applies int() to every part:
چەند تاقیگەیەک داوا لە دەکەن ڕیز و ستوونێک بنووسێت. input() هەموو دێڕەکە وەک یەک دەگەڕێنێتەوە، بۆ نموونە "4 8". .split() لە شوێنی بۆشاییەکان دەیبڕێت و دەیکات بە لە . پاشان map(int, …) int() لەسەر هەموو بەشێک جێبەجێ دەکات:
line = "4 8" # what input() would return: always a string
parts = line.split() # ['4', '8']
print(parts)
x, y = map(int, parts) # int() on every part
print(x + y)['4', '8'] 12
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
We use a fixed string here so the example runs without typing.
لێرەدا جێگیر بەکار دەهێنین بۆ ئەوەی نموونەکە بەبێ نووسین کار بکات.
- Lineدێڕی 4
Destructuring: the two converted numbers go into
xandy.: دوو ژمارە گۆڕاوەکە دەچنە ناو
xوy.
This works when the user types exactly what we expect. Users don't. The next three screens show what goes wrong in the labs and how to fix it. A reusable version is built in A safe input function: get_int().
ئەمە کار دەکات کاتێک ڕێک ئەوە دەنووسێت کە چاوەڕێی دەکەین. وا ناکەن. سێ لاپەڕەی داهاتوو پیشان دەدەن لە تاقیگەکاندا چی هەڵە دەچێت و چۆن چاک دەکرێت. وەشانێکی دووبارە بەکارهاتوو لە کردارێکی نێوخستەی سەلامەت: get_int() دروست دەکرێت.
Reading input safelyخوێندنەوەی نێوخستە بە سەلامەتی
Never use eval() on inputهەرگیز eval() لەسەر نێوخستەی بەکارهێنەر بەکار مەهێنە
One lab program reads the numbers with eval(). eval() does not just read a number: it runs whatever the user types as Python code. Here we pretend the user typed a command:
یەکێک لە تاقیگە ژمارەکان بە eval() دەخوێنێتەوە. eval() تەنها ژمارەیەک ناخوێنێتەوە: هەرچی بینووسێت وەک کۆدی جێبەجێی دەکات. لێرەدا وا دادەنێین فەرمانێکی نووسیوە:
typed = "print('This text could be any command!')" # imagine a user typed this
eval(typed) # eval() RUNS it as Python code
try:
int(typed) # int() only accepts a whole number
except ValueError as error:
print("int() refused it:", error)This text could be any command!
int() refused it: invalid literal for int() with base 10: "print('This text could be any command!')"Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
eval()ran the typed text as code.eval()دەقە نووسراوەکەی وەک کۆد جێبەجێ کرد.- Lineدێڕی 4-7
int()refuses anything that is not a whole number, and we catch the error.int()هەر شتێک کە نەبێت ڕەت دەکاتەوە و ئێمە هەڵەکە دەگرین.
Reading input safelyخوێندنەوەی نێوخستە بە سەلامەتی
The negative-index trapتەڵەی ئیندێکسی سالب
Two lab programs check the typed numbers with > only, for example x > len(maze). That misses two problems. x = len(maze) is one past the last row and crashes with IndexError. A negative number passes the check, and Python reads it as a negative index, counting from the end: -1 becomes the last row. The program then quietly uses a wrong cell. (See Negative indexes: counting from the end.)
دوو تاقیگە ژمارە نووسراوەکان تەنها بە > دەپشکنن، بۆ نموونە x > len(maze). ئەمە دوو کێشە لەدەست دەدات. x = len(maze) یەک ڕیز دوای دوایین ڕیزە و بە IndexError تێک دەچێت. تێدەپەڕێت و وەک دەیخوێنێتەوە، لە کۆتاییەوە دەژمێرێت: -1 دەبێتە دوایین ڕیز. پاشان بە بێدەنگی خانەیەکی هەڵە بەکار دەهێنێت. (بڕوانە ئیندێکسە سالبەکان: ژماردن لە کۆتاییەوە.)
maze = ["....", ".##.", "...."]
x, y = -1, -1
print(maze[x][y]) # no error: -1 means "the last one"
print(x > len(maze)) # a check with > lets -1 through
print(0 <= x < len(maze)) # the correct check rejects it. False False
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
No error: Python reads
maze[-1][-1], the bottom-right cell.هیچ هەڵەیەک نییە:
maze[-1][-1]دەخوێنێتەوە، خانەی خوارەوەی لای ڕاست.- Lineدێڕی 4
-1 > 3is False, so a>check does not reject it.-1 > 3هەڵەیە، بۆیە پشکنینی>ڕەتی ناکاتەوە.- Lineدێڕی 5
0 <= x < len(maze)rejects both negative and too-large values.0 <= x < len(maze)هەم نرخی سالب و هەم نرخی زۆر گەورە ڕەت دەکاتەوە.
Reading input safelyخوێندنەوەی نێوخستە بە سەلامەتی
A safe way to read a cellڕێگایەکی سەلامەت بۆ خوێندنەوەی خانەیەک
This function accepts only two whole numbers inside the maze. Every bad input returns None, and the ask loop simply asks again:
ئەم تەنها دوو لە ناو قبووڵ دەکات. هەموو خراپ None دەگەڕێنێتەوە و پرسیارەکە بە سادەیی دووبارە دەپرسێتەوە:
ROWS, COLS = 5, 9 # the size of the maze
def parse_cell(text):
"""Turn text like '4 8' into (4, 8); return None if it is not a valid cell."""
parts = text.split()
if len(parts) != 2:
return None
try:
x, y = int(parts[0]), int(parts[1])
except ValueError: # letters, '4.5', ...
return None
if not (0 <= x < ROWS and 0 <= y < COLS):
return None # outside the maze (also rejects negative numbers)
return (x, y)
def ask_cell(prompt):
while True: # ask again until the answer is valid
cell = parse_cell(input(prompt))
if cell is not None:
return cell
print("Invalid input. Try again.")
start = ask_cell("Start (row column): ")
print("Start is", start)Start (row column): a b Invalid input. Try again. Start (row column): -1 -1 Invalid input. Try again. Start (row column): 0 0 Start is (0, 0)
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6-8
Exactly two parts are needed.
ڕێک دوو بەش پێویستە.
- Lineدێڕی 9-12
try/except ValueError: ifint()fails (letters, decimals), return None instead of crashing.try/except ValueError: ئەگەرint()سەرنەکەوت (پیت، )، لەبری تێکچوون None بگەڕێنەوە.- Lineدێڕی 13-14
The full range check: no negative numbers, nothing past the edge.
پشکنینی تەواوی سنوور: نە ، نە شتێک لە دوای لێوارەکە.
- Lineدێڕی 18-23
Keep asking until the input is valid.
بەردەوام بپرسە تا دروست دەبێت.
Exercisesڕاهێنانەکان
Store this small (simplified) road map in a dictionary whose keys are towns and whose values are lists of neighbouring towns: Erbil–Koya, Erbil–Shaqlawa, Koya–Sulaymaniyah. Print every town with its neighbours, then check whether there is a road from Erbil to Koya.
ئەم نەخشە بچووکەی ڕێگا (سادەکراوە) لە هەڵبگرە کە شارۆچکەکانن و شارۆچکە دراوسێکانن: هەولێر–کۆیە، هەولێر–شەقڵاوە، کۆیە–سلێمانی. هەموو شارۆچکەیەک لەگەڵ دراوسێکانی چاپ بکە، پاشان بپشکنە ئایا ڕێگایەک لە هەولێرەوە بۆ کۆیە هەیە.
Hintئاماژە
Use items() to loop, and in to test a neighbour.
بۆ خولانەوە items() و بۆ تاقیکردنەوەی دراوسێیەک in بەکار بهێنە.
Show answerوەڵامەکە پیشان بدە
roads = {
"Erbil": ["Koya", "Shaqlawa"],
"Koya": ["Erbil", "Sulaymaniyah"],
"Shaqlawa": ["Erbil"],
"Sulaymaniyah": ["Koya"],
}
for town, neighbours in roads.items():
print(f"{town}: {', '.join(neighbours)}")
print("Koya" in roads["Erbil"]) # is there a road from Erbil to Koya?Erbil: Koya, Shaqlawa Koya: Erbil, Sulaymaniyah Shaqlawa: Erbil Sulaymaniyah: Koya True
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1-6
Each road appears twice, once from each end.
هەر ڕێگایەک دوو جار دەردەکەوێت، جارێک لە هەر سەرێکەوە.
- Lineدێڕی 9
', '.join(...)glues the names with a comma and a space.', '.join(...)ناوەکان بە فاریزە و بۆشاییەک پێکەوە دەلکێنێت.
Use all() to check whether every number in [4, 8, 15, 16] is even, and a list comprehension to list the ones that are not.
all() بەکار بهێنە بۆ پشکنینی ئەوەی ئایا هەموو ژمارەکانی [4, 8, 15, 16] جووتن و بۆ لیستکردنی ئەوانەی جووت نین.
Show answerوەڵامەکە پیشان بدە
numbers = [4, 8, 15, 16]
print(all(n % 2 == 0 for n in numbers)) # are all of them even?
print([n for n in numbers if n % 2 != 0]) # which ones are not?False [15]
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
n % 2 == 0is True for even numbers.n % 2 == 0بۆ ژمارە جووتەکان True دەبێت.
Build a grid of 3 rows and 4 columns filled with 0, put 5 in row 1, column 2, and print it row by row.
تۆڕێکی 3 ڕیز و 4 ستوون دروست بکە کە پڕ بێت لە 0، 5 لە ڕیزی 1، ستوونی 2 دابنێ و ڕیز بە ڕیز چاپی بکە.
Hintئاماژە
[[0 for column in range(4)] for row in range(3)]
[[0 for column in range(4)] for row in range(3)]
Show answerوەڵامەکە پیشان بدە
grid = [[0 for column in range(4)] for row in range(3)]
grid[1][2] = 5
for row in grid:
print(row)[0, 0, 0, 0] [0, 0, 5, 0] [0, 0, 0, 0]
Write is_inside(x, y, maze) that returns True only for cells inside the maze, also for negative numbers. Test it on (0, 0), (2, 3), (3, 0) and (-1, 2) with a 3 × 4 maze.
is_inside(x, y, maze) بنووسە کە تەنها بۆ خانەکانی ناو True بگەڕێنێتەوە، بۆ ژمارە سالبەکانیش. لەسەر (0, 0)، (2, 3)، (3, 0) و (-1, 2) لەگەڵ 3 × 4 تاقی بکەرەوە.
Show answerوەڵامەکە پیشان بدە
def is_inside(x, y, maze):
return 0 <= x < len(maze) and 0 <= y < len(maze[0])
maze = ["....", ".##.", "...."]
for cell in [(0, 0), (2, 3), (3, 0), (-1, 2)]:
print(cell, is_inside(cell[0], cell[1], maze))(0, 0) True (2, 3) True (3, 0) False (-1, 2) False
Write a class Student with a name and a mark, and a __repr__ that shows name: mark. Make two students, print the list, then print the second student's name.
بە ناوی Student بنووسە کە ناو و نمرەی هەبێت و __repr__ێک کە name: mark پیشان بدات. دوو قوتابی دروست بکە، چاپ بکە، پاشان ناوی قوتابیی دووەم چاپ بکە.
Show answerوەڵامەکە پیشان بدە
class Student:
def __init__(self, name, mark):
self.name = name
self.mark = mark
def __repr__(self):
return f"{self.name}: {self.mark}"
students = [Student("Rezan", 88), Student("Hana", 93)]
print(students)
print(students[1].name)[Rezan: 88, Hana: 93] Hana
Summary and reviewپوختە و پێداچوونەوە
- Lists keep items in order from index 0;
pop()uses a list as a stack (DFS),pop(0)ordeque.popleft()as a queue (BFS). - Tuples are fixed lists, good for positions and dictionary keys; sets hold unique values with a fast
in. - Dictionaries map keys to values;
items()loops over both;.get()reads safely; nested dictionaries hold complex data. all()is True when every element is truthy (and for an empty iterable).- Grids are lists of rows; build them with a list comprehension and check
0 <= x < len(maze). - A class is a blueprint;
__init__stores attributes,__repr__controls printing. int()/str()convert;float('inf')is a starting value;a if c else bchooses in one line.- Never
eval()user input: useint(),try/exceptand a full range check.
- دانەکان بە ڕیز لە 0ەوە هەڵدەگرن؛
pop()وەک بەکار دەهێنێت (DFS)،pop(0)یانdeque.popleft()وەک (BFS). - نەگۆڕن، باشن بۆ شوێن و ؛ نرخی بێدووبارە هەڵدەگرن و
inـیان خێرایە. - بە نرخەکانەوە دەبەستنەوە؛
items()بەسەر هەردووکیاندا دەخولێتەوە؛.get()بە سەلامەتی دەخوێنێتەوە؛ ئاڵۆز هەڵدەگرن. all()کاتێک هەموو دانەکان ڕاستئاسا بن True دەبێت (هەروەها بۆ بەتاڵ).- تۆڕی خانەکان لە ڕیزەکانن؛ بە دروستیان بکە و
0 <= x < len(maze)بپشکنە. - نەخشەیەکە؛
__init__هەڵدەگرێت،__repr__شێوەی چاپکردن دیاری دەکات. int()/str()دەگۆڕن؛float('inf')نرخی سەرەتایە؛a if c else bلە یەک دێڕدا هەڵدەبژێرێت.- هەرگیز
eval()لەسەر بەکار مەهێنە:int()،try/exceptو پشکنینی تەواوی سنوور بەکار بهێنە.
What is the difference between pop() and pop(0)?جیاوازیی نێوان pop() و pop(0) چییە؟
pop() removes the last item (stack, last in first out); pop(0) removes the first item (queue, first in first out).
pop() دوایین دانە لادەبات (، دوایین هات یەکەم دەچێت)؛ pop(0) یەکەم دانە لادەبات (، یەکەم هات یەکەم دەچێت).
Why can a list not be a dictionary key, but a tuple can?بۆچی لیست ناتوانێت ببێتە کلیلی فەرهەنگ، بەڵام تاپڵ دەتوانێت؟
Keys must never change. A list can change; a tuple cannot.
نابێت هەرگیز بگۆڕێن. دەگۆڕێت؛ ناگۆڕێت.
What does all([]) return, and why?all([]) چی دەگەڕێنێتەوە و بۆچی؟
True: an empty list has no falsy element.
True: بەتاڵ هیچ دانەیەکی هەڵەئاسای تێدا نییە.
Why does a class need __repr__ in the labs?بۆچی کلاسێک لە تاقیگەکاندا پێویستی بە __repr__ هەیە؟
So that printed points show their coordinates instead of a memory address.
بۆ ئەوەی خاڵە چاپکراوەکان پێگەکانیان پیشان بدەن لەبری ناونیشانێکی .
Why is eval(input()) dangerous?بۆچی eval(input()) مەترسیدارە؟
It runs whatever the user types as Python code. int() only accepts numbers.
هەرچی بینووسێت وەک کۆدی جێبەجێی دەکات. int() تەنها ژمارە قبووڵ دەکات.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Priority Queues and Heapsکیووە پێشینەییەکان و هیپەکان
Related lecturesوانە پەیوەندیدارەکان
- Priority Queues and Heapsکیووە پێشینەییەکان و هیپەکان
- Agent Programs, Pseudocode and Algorithm Analysisبەرنامەکانی ئەیجێنت، نیمچەکۆد و شیکارکردنی ئەلگۆریزم
- Depth-First and Breadth-First Searchگەڕانی قووڵایی و گەڕانی پانایی
- Solving a Maze with DFS and BFSچارەسەرکردنی لابیرینت بە DFS و BFS
- Arrays in PHPڕیزەکەکان لە PHPـدا
- Multidimensional Arraysڕیزەکە فرەڕەهەندەکان
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.