חוברת תרגול נלווית למצגות של יחידות 7–15. בכל יחידה השאלות מסודרות מהקל למאתגר: קודם מה יודפס? ואיתור באגים (פותרים על הנייר, עם טבלת מעקב), ואחר כך כתבו תוכנית. בסוף החוברת יש מפתח תשובות עם פתרון לדוגמה לכל משימה. כל הקוד בחוברת הורץ, והפלט במפתח הוא הפלט האמיתי.
מתחילים במעקב על הנייר: לכל לולאה בונים טבלת מעקב עם עמודה לכל משתנה ועמודה לתנאי. אחר כך כותבים לולאות בעצמכם.
for i in range(start, stop, step): ה-stop לא נכלל. range(5) נותן 0 עד 4.while תנאי: רצה כל עוד התנאי True. חייבים לשנות משהו בתוך הלולאה, אחרת היא אינסופית.total = 0 לפני הלולאה ו-total += x בתוכה. מונה: count += 1.n % 10 היא ספרת האחדות, ו-n //= 10 מוחק אותה.break יוצא מהלולאה, continue מדלג לסיבוב הבא.for i in range(1, 6): print(i * 2, end=" ")
for i in range(10, 0, -3): print(i)
i, total ו-i < 10, ואז כתבו מה יודפס.total = 0 i = 1 while i < 10: total += i i += 3 print(total, i)
count = 0 for ch in "banana": if ch == "a": count += 1 print(count)
n, d ו-s בכל סיבוב.n = 4071 s = 0 while n > 0: d = n % 10 s += d n //= 10 print(s)
continue ו-break באותה לולאה)for i in range(1, 10): if i % 3 == 0: continue if i == 8: break print(i, end=" ")
for i in range(1, 4): line = "" for j in range(i): line += str(i) print(line)
total = 0 count = 0 x = int(input("מספר: ")) while x != 0: total += x count += 1 x = int(input("מספר: ")) print(total, count)
5 , 8 , 2 , 0i = 1 steps = 0 while i <= 5: print(i) steps += 1 if steps == 20: raise RuntimeError("infinite loop") i += 1
for i in range(3, 12, 4) (ב) for i in range(5, 5) (ג) while x > 0 כש-x = -2 לפני הלולאה.בינוני1234 ⟵ 4 ספרות, סכום 10, זוגיות 2.)קל3720 ⟵ 273), בלי להפוך מחרוזת. רמז: rev = rev * 10 + d.בינוני-1. הדפיסו את הממוצע, את הציון הגבוה ואת מספר הנכשלים (מתחת ל-55). אם לא הוקלד אף ציון, הדפיסו אין ציונים.בינוני\t).בינוניand, or ו-not מחברים תנאים. האופרטורים הסיביים &, |, ^, ~, << ו->> עובדים על הביטים של מספר שלם.
and: True רק אם שני הצדדים True. or: True אם לפחות צד אחד True. not הופך.not לפני and, ו-and לפני or. בספק, שמים סוגריים.False and ... ובשורה True or ... הצד הימני לא נבדק בכלל.bin(6) ⟵ '0b110'. & (וגם), | (או), ^ (או מוציא: 1 רק כשהביטים שונים).x << 1 מכפיל ב-2, x >> 1 מחלק ב-2 (חלוקה שלמה).x = 7 print(x > 5 and x < 10) print(x < 5 or x == 7) print(not x > 5)
a = True b = False c = True print(a or b and not c) print((a or b) and not c)
x = 6 print(x > 5 and x % 2 == 1, not x < 3 or x == 0)
print(bin(12), bin(10)) print(12 & 10, 12 | 10, 12 ^ 10)
print(5 << 1, 5 << 3, 40 >> 2, 7 >> 1)
x = 0 print(x != 0 and 10 / x > 1) print(x == 0 or 10 / x > 1)
age בין 13 ל-19 כולל. (ב) ch הוא תנועה באנגלית (a, e, i, o, u). (ג) year מעוברת: מתחלקת ב-4 ולא ב-100, או מתחלקת ב-400.בינוניgrade הוא 90 או 100, אבל הוא מדפיס "מצוין" גם לציון 40. למה? (הקוד לא קורס. כדי לראות את הבאג הוספנו בדיקה.)grade = 40 if grade == 90 or 100: raise AssertionError("the condition is always True")
flags = 0b0101. מה הערך (בבינארי) אחרי כל פעולה, כשכל פעולה מתחילה מ-0b0101? (א) flags | 0b0010 (ב) flags & 0b0100 (ג) flags ^ 0b0001בינונישווה צלעות, שווה שוקיים או שונה צלעות. לפני כן בדקו שהמשולש קיים: כל שני צדדים יחד ארוכים מהשלישי. אם לא, הדפיסו אין משולש.בינוני%. רמז: הביט הימני של מספר זוגי הוא 0, ו-n & 1 מחזיר בדיוק אותו.בינוני& 1 ו->> בלבד. (13 = 1101 ⟵ 3)מאתגראינדקסים, חיתוך, פעולות על רשימה, מעבר בלולאה, איברים סמוכים ורשימת מונים. שני הנושאים האחרונים מודגשים בהנחיות לבחינה של תשפ"ז.
-1. lst[1:3] מחזיר את האיברים במקומות 1 ו-2 (3 לא נכלל).append(x) מוסיף לסוף, insert(i, x) מכניס במקום i, pop() מוחק ומחזיר את האחרון, remove(x) מוחק את המופע הראשון של x.len, sum, max, min, x in lst, lst.count(x), lst.index(x).for i in range(len(lst) - 1): ומשווים lst[i] ל-lst[i + 1].counts = [0] * 10, ובלולאה counts[value] += 1. הערך הופך לאינדקס.nums = [3, 8, 1, 9, 4] print(nums[0], nums[-1], nums[1:3], nums[:2], len(nums))
nums = [3, 8, 1, 9, 4] nums.append(nums[1] + nums[-1]) nums.pop(0) nums.insert(1, 7) print(nums)
words = ["cat", "dog", "cat", "bird"] print(words.count("cat"), words.index("dog"), "fish" in words) words.remove("cat") print(words)
a = [1, 2, 3] b = a c = a[:] b.append(4) print(a) print(c)
lst = [4, 4, 7, 2, 2, 2, 9] count = 0 for i in range(len(lst) - 1): if lst[i] == lst[i + 1]: count += 1 print(count)
digits = [3, 1, 3, 0, 9, 3, 1] counts = [0] * 10 for d in digits: counts[d] += 1 print(counts) print(counts.index(max(counts)))
lst = [5, 2, 8, 1, 9] for i in range(len(lst)): if lst[i] % 2 == 0: lst[i] = 0 print(lst)
lst = [10, 20, 30] for i in range(len(lst) + 1): print(lst[i])
for x in lst: לבין for i in range(len(lst)):? מתי חייבים את הצורה השנייה?בינוניmax.קל[1, 3, 5, 2, 4, 6, 8, 1] התשובה 4 (2, 4, 6, 8).מאתגרrandom.randint(1, 6)) וספרו ברשימת מונים כמה פעמים יצא כל מספר. הדפיסו את התוצאות. בהרצה לדוגמה קבענו random.seed(1) כדי שהתוצאה תהיה קבועה.מאתגרsort ו-sorted, ומה המחשב עושה "מתחת למכסה המנוע": החלפת שני ערכים ומיון בועות.
lst.sort() ממיין את הרשימה עצמה ומחזיר None. sorted(lst) מחזיר רשימה חדשה.reverse=True. מחרוזות ממוינות לפי ABC, ואותיות גדולות באות לפני קטנות.a, b = b, a. ברשימה: lst[i], lst[i + 1] = lst[i + 1], lst[i].a = [5, 2, 9, 1] b = sorted(a) print(a) print(b) a.sort(reverse=True) print(a)
lst = [3, 1, 2] lst = lst.sort() print(lst)
names = ["dana", "Omer", "adam", "Lina"] print(sorted(names))
lst = [5, 2, 7, 1] for p in range(len(lst) - 1): for i in range(len(lst) - 1 - p): if lst[i] > lst[i + 1]: lst[i], lst[i + 1] = lst[i + 1], lst[i] print(lst)
grades = [72, 95, 88, 60, 95] grades.sort(reverse=True) print(grades[:3]) print(grades[len(grades) // 2])
lst = [4, 1, 3] result = lst.sort() print(result[0])
sorted(lst)[-1] לבין max(lst)? איזה עדיף כשרוצים רק את הגדול ולמה?בינוניswapped). הדפיסו כמה מעברים בוצעו.בינוניsort.מאתגרהגדרה, פרמטרים, return, ערכי ברירת מחדל, משתנים מקומיים, ופונקציה שמקבלת רשימה.
def name(params): מגדירה. הקוד בפנים רץ רק כשקוראים לפונקציה.return מחזיר ערך ויוצא מהפונקציה. פונקציה בלי return מחזירה None.print מציג על המסך. return מחזיר ערך לקוד שקרא. אלה שני דברים שונים.def f(a, b=2):. אפשר לקרוא בשם: f(b=1, a=4).def greet(name): print("שלום", name) greet("דנה") greet("עומר")
def f(a, b=2): if a > b: return a - b return a * b print(f(5), f(1), f(3, 3), f(b=1, a=4))
print מול return: מה יודפס?def show(x): print(x * 2) def give(x): return x * 2 a = show(5) b = give(5) print(a, b)
def check(n): for d in range(2, n): if n % d == 0: return False return True print(check(7), check(9), check(2))
x = 10 def change(): x = 99 print("inside:", x) change() print("outside:", x)
def add_bonus(grades): for i in range(len(grades)): grades[i] += 5 my = [80, 90] add_bonus(my) print(my)
def square(x): return x * x def sum_squares(a, b): return square(a) + square(b) print(sum_squares(3, 4)) print(square(sum_squares(1, 1)))
def area(w, h): result = w * h print(area(3, 4) + 1)
def f(): return 1 print("after") print(f())
digit_sum(n) שמחזירה את סכום הספרות של n, ופונקציה is_lucky(n) שמחזירה True אם סכום הספרות מתחלק ב-7. הדפיסו את כל המספרים ה"מזליים" בין 1 ל-100.קלcount_above(lst, limit) שמחזירה כמה איברים ברשימה גדולים מ-limit. ברירת המחדל של limit היא 0.קלtop3(lst) שמחזירה רשימה של שלושת הערכים הגבוהים, מהגבוה לנמוך, בלי sort ו-sorted, ובלי לשנות את הרשימה המקורית. מה היא מחזירה כשיש פחות משלושה איברים?מאתגרmenu() שמדפיסה אפשרויות וקולטת בחירה, ופונקציות add(a, b) ו-power(a, b). הקוד הראשי ירוץ בלולאה עד שהמשתמש בוחר 0.מאתגררשימה שאי אפשר לשנות: יצירה, פריסה למשתנים, פונקציה שמחזירה כמה ערכים, ורשימה של tuple-ים כטבלה.
t = (3, 4). tuple עם איבר אחד צריך פסיק: (5,).t[0] = 9 זו שגיאה: tuple לא משתנה.t.count(x) ו-t.index(x).a, b = t. פונקציה יכולה להחזיר כמה ערכים: return low, high.for name, grade in students:.t = (4, 7, 4, 1) a, b, c, d = t print(t.count(4), t.index(7), a + d, sorted(t))
t = (10, 20, 30, 40, 50) print(t[1:4], t[-2], len(t), 30 in t)
a = (5) b = (5,) print(type(a), type(b))
def stats(lst): return min(lst), max(lst), sum(lst) / len(lst) low, high, avg = stats([4, 8, 6]) print(low, high, avg) print(stats([1, 2]))
students = [("dana", 88), ("omer", 54), ("lina", 97)] for name, grade in students: if grade >= 55: print(name) print(students[1][0], students[2][1])
a = 1 b = 2 c = 3 a, b, c = c, a, b print(a, b, c)
point = (3, 4) point[0] = 10 print(point)
a, b = (1, 2, 3)
min_max(lst) שמחזירה tuple של (הקטן, הגדול) במעבר אחד על הרשימה, בלי min ו-max. קראו לה ופרסו את התוצאה לשני משתנים.קלx * x + y * y במקום המרחק עצמו.מאתגרמפתח ⟵ ערך: יצירה, גישה, in, מעבר עם keys() ו-items(), ספירה במילון ומילון של רשימות. המילון מודגש בהנחיות לבחינה.
d = {} מילון ריק. d[key] = value מוסיף או מעדכן. d[key] קורא, ושגיאה (KeyError) אם המפתח לא קיים.key in d בודק אם מפתח קיים. d.get(key, 0) מחזיר 0 אם המפתח לא קיים, בלי שגיאה.for k in d: עובר על המפתחות. for k, v in d.items(): עובר על הזוגות.counts[w] = counts.get(w, 0) + 1.ages = {"dana": 16, "omer": 17} ages["lina"] = 15 ages["dana"] = 17 print(ages) print(len(ages), "omer" in ages, 17 in ages)
prices = {"apple": 5, "bread": 8, "milk": 6} total = 0 for item in prices: total += prices[item] print(total) for item, price in prices.items(): if price > 5: print(item)
text = "to be or not to be" counts = {} for w in text.split(): counts[w] = counts.get(w, 0) + 1 print(counts)
d = {"a": 1, "b": 2} print(d.get("a"), d.get("z"), d.get("z", 0))
word = "mississippi" counts = {} for ch in word: if ch in counts: counts[ch] += 1 else: counts[ch] = 1 best = "" for ch in counts: if best == "" or counts[ch] > counts[best]: best = ch print(counts) print(best, counts[best])
words = ["apple", "avocado", "banana", "cherry", "blueberry"] by_letter = {} for w in words: first = w[0] if first not in by_letter: by_letter[first] = [] by_letter[first].append(w) print(by_letter) print(len(by_letter["b"]))
stock = {"apple": 3, "milk": 0} print(stock["bread"])
counts = {} for w in ["hi", "bye", "hi"]: counts[w] += 1 print(counts)
1 הוספה, 2 חיפוש לפי שם, 3 הצגת כולם בסדר אלפביתי, 0 יציאה. חיפוש של שם שלא קיים מדפיס הודעה, בלי שגיאה.בינוניlower()).מאתגרפתיחה, קריאה וכתיבה של קובצי טקסט, בשתי הצורות: with open(...) ו-open / close כמו בבחינה. שורות ריקות, שורות הערה עם #, ו-split על כל שורה.
f = open("a.txt", "r") ⟵ עובדים ⟵ f.close(). או with open("a.txt") as f:, שסוגר לבד."r" קריאה, "w" כתיבה (מוחק את מה שהיה), "a" הוספה לסוף.for line in f: עובר שורה אחרי שורה. כל שורה מסתיימת ב-\n, ולכן עושים line.strip().f.read() כל הקובץ כמחרוזת אחת. f.readlines() או list(f) רשימה של שורות.f.write(text) לא מוסיף \n לבד. מספר צריך להמיר: f.write(str(n) + "\n").with open("a.txt", "w") as f: f.write("one") f.write("two\n") f.write("three\n") with open("a.txt") as f: lines = f.readlines() print(lines) print(len(lines))
"w" מול "a": מה יודפס?f = open("log.txt", "w") f.write("A\n") f.close() f = open("log.txt", "a") f.write("B\n") f.close() f = open("log.txt", "w") f.write("C\n") f.close() f = open("log.txt", "a") f.write("D\n") f.close() f = open("log.txt", "r") print(f.read()) f.close()
data.txt מכיל: 5, 12, שורה ריקה, 7.512 7
total = 0 count = 0 with open("data.txt") as f: for line in f: line = line.strip() if line != "": total += int(line) count += 1 print(total, count, total / count)
# name gradedana 88omer 54lina 97 adam 71
f = open("grades.txt", "r") lines = list(f) f.close() for line in lines: if line[0] != "#" and line.strip() != "": parts = line.split() if int(parts[1]) >= 70: print(parts[0])
the sun is upthe day is longup up and away
with open("poem.txt") as f: text = f.read() print(len(text.split("\n")) - 1, len(text.split()), text.count("up"))
f = open("nums.txt", "w") for i in range(3): f.write(i) f.close()
with open("scores.txt") as f: for line in f: print(line)
print(line) מופיעה שורה ריקה בין כל שתי שורות? איך מתקנים?קלsquares.txt את המספרים 1 עד 10 ואת הריבוע של כל אחד, שורה לכל מספר (3 9). אחר כך קראו את הקובץ והדפיסו את סכום הריבועים.קלgrades.txt (מוצג למטה) מכיל שם וציון בכל שורה, שורות הערה שמתחילות ב-# ושורות ריקות. הדפיסו את הממוצע ואת שם בעל הציון הגבוה.# name gradedana 88omer 54lina 97 adam 71
grades.txt לקובץ חדש passed.txt רק את השורות של מי שעבר (55 ומעלה), ובסוף הוסיפו שורה עם מספר העוברים.# name gradedana 88omer 54lina 97 adam 71
counter.txt מספר, הוסיפו לו 1, הדפיסו אותו ושמרו בחזרה. אם הקובץ לא קיים, התחילו מ-0 (try / except FileNotFoundError). הריצו את התוכנית כמה פעמים.מאתגרמחברים הכול: חיפוש בקובץ, ניתוח טקסט עם מילון, העתקה עם שינוי, וקובץ CSV שנטען לרשימה של tuple-ים או למילון.
name, grade = line.strip().split(",").f.readline() לפני הלולאה.word in line.split() בודק מילה שלמה. word in line מוצא גם חלק ממילה ("up" בתוך "cup").line_no += 1 בכל סיבוב של הלולאה."w" מוחק אותו מיד.the sun is upthe day is longup up and away
word = "up" line_no = 0 with open("poem.txt") as f: for line in f: line_no += 1 if word in line.split(): print(line_no, line.strip())
name,class,gradedana,a1,88omer,a2,54lina,a1,97adam,a2,71noa,a1,65
with open("scores.csv") as f: header = f.readline() rows = [] for line in f: name, cls, grade = line.strip().split(",") rows.append((name, cls, int(grade))) print(header.strip()) print(len(rows), rows[0])
name,class,gradedana,a1,88omer,a2,54lina,a1,97adam,a2,71noa,a1,65
totals = {} counts = {} with open("scores.csv") as f: f.readline() for line in f: name, cls, grade = line.strip().split(",") totals[cls] = totals.get(cls, 0) + int(grade) counts[cls] = counts.get(cls, 0) + 1 for cls in sorted(totals): print(cls, totals[cls] / counts[cls])
the sun is upthe day is longup up and away
counts = {} with open("poem.txt") as f: for line in f: for w in line.split(): counts[w] = counts.get(w, 0) + 1 best = max(counts, key=counts.get) print(best, counts[best])
the sun is upthe day is longup up and away
with open("poem.txt") as src: text = src.read() with open("poem2.txt", "w") as dst: dst.write(text.replace("up", "UP")) print(text.count("up"), "replacements")
name,class,gradedana,a1,88omer,a2,54lina,a1,97adam,a2,71noa,a1,65
total = 0 with open("scores.csv") as f: for line in f: name, cls, grade = line.strip().split(",") total += int(grade) print(total)
notes.txt ובאותו זמן פותח אותו עם open("notes.txt", "w") כדי לכתוב גרסה מתוקנת מאבד את כל התוכן. למה? מה הדרך הנכונה?בינוניfind_word(filename, word) שמחזירה רשימה של מספרי השורות שבהן המילה מופיעה. אם המילה לא נמצאה, הדפיסו הודעה מתאימה.קלpoem.txt הדפיסו: מספר שורות, מספר מילים, מספר תווים (בלי \n), והשורה הארוכה ביותר.בינוניscores.csv (שם, כיתה, ציון) כתבו קובץ report.txt: שורה לכל תלמיד בפורמט name: grade (עבר/נכשל), ממוין מהציון הגבוה לנמוך, ובסוף שורת ממוצע.name,class,gradedana,a1,88omer,a2,54lina,a1,97adam,a2,71noa,a1,65
poem.txt ובנו מילון מילה ⟵ רשימת מספרי השורות שבהן היא מופיעה (בלי כפילויות, בלי להבחין בין אותיות גדולות לקטנות). הדפיסו את המילים בסדר אלפביתי.מאתגרstock.txt (שורה: item,amount) למילון. קלטו מכירות (שם מוצר וכמות) עד שמוקלד end, עדכנו את המלאי (לא לרדת מתחת ל-0) ושמרו את המילון בחזרה לקובץ.milk,5bread,3eggs,12
נסו לפתור לבד לפני שאתם פותחים. במשימות "כתבו תוכנית" יש יותר מפתרון נכון אחד. הפתרון כאן הוא דוגמה, ולידו ההרצה שלו (הקלט שהוקלד מופיע אחרי ההודעה).
2 4 6 8 1010741
12 10מעקב: i = 1, 4, 7 נכנסים ללולאה, וכש-i = 10 התנאי False. total = 1 + 4 + 7.
312הספרות נשלפות מהסוף להתחלה: 1, 7, 0, 4.
1 2 4 5 73 ו-6 מדולגים בגלל continue, וב-8 הלולאה נעצרת לפני ההדפסה.
122333
מספר: 5מספר: 8מספר: 2מספר: 015 3
ה-0 הוא הזקיף: הוא עוצר את הלולאה ולא נספר.
RuntimeError: infinite loop
השורה i += 1 לא מוזחת, ולכן היא מחוץ ללולאה. i נשאר 1 והתנאי תמיד True. התיקון: להזיח את i += 1 לתוך גוף ה-while.
(א) 3 פעמים: 3, 7, 11. (ב) 0 פעמים: ה-range ריק כי start = stop. (ג) 0 פעמים: התנאי False כבר בבדיקה הראשונה.
פתרון לדוגמה (יש עוד דרכים נכונות):
n = int(input("מספר: ")) digits = 0 total = 0 evens = 0 while n > 0: d = n % 10 digits += 1 total += d if d % 2 == 0: evens += 1 n //= 10 print(digits, total, evens)
מספר: 12344 10 2
פתרון לדוגמה (יש עוד דרכים נכונות):
n = int(input("מספר: ")) rev = 0 while n > 0: d = n % 10 rev = rev * 10 + d n //= 10 print(rev)
מספר: 3720273
ה-0 שהיה בסוף הופך לאפס מוביל, ולכן הוא נעלם.
פתרון לדוגמה (יש עוד דרכים נכונות):
count = 0 total = 0 fails = 0 best = 0 grade = int(input("ציון: ")) while grade != -1: count += 1 total += grade if grade < 55: fails += 1 if grade > best: best = grade grade = int(input("ציון: ")) if count == 0: print("אין ציונים") else: print("ממוצע:", total / count) print("הכי גבוה:", best) print("נכשלים:", fails)
ציון: 80ציון: 45ציון: 92ציון: 50ציון: -1ממוצע: 66.75הכי גבוה: 92נכשלים: 2
פתרון לדוגמה (יש עוד דרכים נכונות):
for i in range(1, 6): for j in range(1, 6): print(i * j, end="\t") print()
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25
פתרון לדוגמה (יש עוד דרכים נכונות):
for n in range(2, 1001): total = 0 for d in range(1, n): if n % d == 0: total += d if total == n: print(n)
628496
TrueTrueFalse
TrueFalse
בשורה הראשונה and מחושב קודם: b and not c הוא False, ואז True or False הוא True.
False True0b1100 0b10108 14 6
1100 & 1010 = 1000 (8), 1100 | 1010 = 1110 (14), 1100 ^ 1010 = 0110 (6).
10 40 10 3הזזה שמאלה ב-k מכפילה ב-2 בחזקת k, והזזה ימינה מחלקת (חלוקה שלמה).
FalseTrue
בשתי השורות Python יודעת את התשובה כבר מהצד השמאלי, ולכן לא מחשבת את 10 / x.
(א) age >= 13 and age <= 19 (או 13 <= age <= 19). (ב) ch == "a" or ch == "e" or ch == "i" or ch == "o" or ch == "u" (או ch in "aeiou"). (ג) (year % 4 == 0 and year % 100 != 0) or year % 400 == 0.
AssertionError: the condition is always True
הביטוי מתפרש כ-(grade == 90) or 100. 100 הוא ערך "אמיתי" (כל מספר שאינו 0), ולכן התנאי תמיד True. התיקון: grade == 90 or grade == 100.
(א) 0b0111: הדלקת ביט 1. (ב) 0b0100: בדיקה, ביט 2 דולק. (ג) 0b0100: היפוך ביט 0, שהיה דולק ונכבה.
פתרון לדוגמה (יש עוד דרכים נכונות):
a = int(input("צלע א: ")) b = int(input("צלע ב: ")) c = int(input("צלע ג: ")) if not (a + b > c and a + c > b and b + c > a): print("אין משולש") elif a == b and b == c: print("שווה צלעות") elif a == b or b == c or a == c: print("שווה שוקיים") else: print("שונה צלעות")
צלע א: 5צלע ב: 5צלע ג: 8שווה שוקיים
פתרון לדוגמה (יש עוד דרכים נכונות):
n = int(input("מספר: ")) if n & 1 == 0: print("זוגי") else: print("אי-זוגי")
מספר: 14זוגי
פתרון לדוגמה (יש עוד דרכים נכונות):
n = int(input("מספר: ")) ones = 0 while n > 0: ones += n & 1 n >>= 1 print(ones)
מספר: 133
3 4 [8, 1] [3, 8] 5[8, 7, 1, 9, 4, 12]2 1 False['dog', 'cat', 'bird']
remove מוחק רק את המופע הראשון.
[1, 2, 3, 4][1, 2, 3]
b = a לא מעתיק: a ו-b הם אותה רשימה. a[:] יוצר עותק חדש.
3הזוגות השווים: (4,4) במקומות 0–1, ו-(2,2) פעמיים: 3–4 ו-4–5.
[1, 2, 0, 3, 0, 0, 0, 0, 0, 1]3
השורה השנייה מדפיסה את הספרה שהופיעה הכי הרבה פעמים: המיקום של הערך הגדול ברשימת המונים.
[5, 0, 0, 1, 9]IndexError: list index out of range
ברשימה של 3 איברים האינדקסים הם 0, 1, 2. range(len(lst) + 1) מגיע עד 3. התיקון: range(len(lst)).
בצורה הראשונה מקבלים את הערכים עצמם. בשנייה מקבלים את המיקומים. צריך את המיקום כשמשנים איבר ברשימה (lst[i] = ...) או כשמשווים לאיבר שלידו (lst[i + 1]).
פתרון לדוגמה (יש עוד דרכים נכונות):
nums = [] x = int(input("מספר: ")) while x != 0: nums.append(x) x = int(input("מספר: ")) if len(nums) > 0: avg = sum(nums) / len(nums) print("ממוצע:", avg) for n in nums: if n > avg: print(n)
מספר: 4מספר: 10מספר: 7מספר: 1מספר: 0ממוצע: 5.5107
פתרון לדוגמה (יש עוד דרכים נכונות):
lst = [12, 45, 7, 45, 30] best = 0 for i in range(1, len(lst)): if lst[i] > lst[best]: best = i print("הגדול:", lst[best], "במקום", best)
הגדול: 45 במקום 1השוואה עם > (ולא >=) שומרת את המופע הראשון של הגדול.
פתרון לדוגמה (יש עוד דרכים נכונות):
lst = [1, 3, 5, 2, 4, 6, 8, 1] best = 1 current = 1 for i in range(len(lst) - 1): if lst[i + 1] > lst[i]: current += 1 if current > best: best = current else: current = 1 print(best)
4פתרון לדוגמה (יש עוד דרכים נכונות):
import random random.seed(1) counts = [0] * 7 # place 0 is not used for _ in range(600): counts[random.randint(1, 6)] += 1 for face in range(1, 7): print(face, counts[face])
1 1042 1023 1034 945 1136 84
כל מספר יוצא בערך 100 פעמים. בלי seed התוצאה שונה בכל הרצה.
[5, 2, 9, 1][1, 2, 5, 9][9, 5, 2, 1]
Nonesort משנה את הרשימה ומחזיר None, וזה מה שנשמר ב-lst.
['Lina', 'Omer', 'adam', 'dana']אותיות גדולות באות לפני קטנות בסדר של Python.
[2, 5, 1, 7][2, 1, 5, 7][1, 2, 5, 7]
אחרי המעבר הראשון 7 בסוף, אחרי השני גם 5 במקומו.
[95, 95, 88]88
השורה השנייה היא החציון: האיבר האמצעי ברשימה ממוינת.
TypeError: 'NoneType' object is not subscriptable
lst.sort() מחזיר None, ואי אפשר לגשת ל-None[0]. התיקון: result = sorted(lst), או lst.sort() ואז print(lst[0]).
4 + 3 + 2 + 1 = 10 השוואות. באופן כללי (n − 1) + (n − 2) + … + 1 = n(n − 1) / 2. מספר ההשוואות לא תלוי בסדר ההתחלתי.
שניהם נותנים את הגדול. max עובר על הרשימה פעם אחת, ו-sorted ממיין את כולה ובונה רשימה חדשה. לכן max עדיף.
פתרון לדוגמה (יש עוד דרכים נכונות):
lst = [1, 2, 4, 3, 5] passes = 0 swapped = True while swapped: swapped = False passes += 1 for i in range(len(lst) - 1): if lst[i] > lst[i + 1]: lst[i], lst[i + 1] = lst[i + 1], lst[i] swapped = True print(lst, "מעברים:", passes)
[1, 2, 3, 4, 5] מעברים: 2ברשימה כמעט ממוינת מספיקים 2 מעברים: אחד שמתקן, ואחד שמוודא שאין מה להחליף.
פתרון לדוגמה (יש עוד דרכים נכונות):
lst = [29, 10, 14, 37, 13] for i in range(len(lst) - 1): small = i for j in range(i + 1, len(lst)): if lst[j] < lst[small]: small = j lst[i], lst[small] = lst[small], lst[i] print(lst)
[10, 29, 14, 37, 13][10, 13, 14, 37, 29][10, 13, 14, 37, 29][10, 13, 14, 29, 37]
פתרון לדוגמה (יש עוד דרכים נכונות):
grades = [] for i in range(6): grades.append(int(input("ציון: "))) grades.sort(reverse=True) print(grades) print("שלושת הגבוהים:", grades[:3]) middle = grades[1:-1] print("ממוצע בלי קצוות:", sum(middle) / len(middle))
ציון: 70ציון: 100ציון: 85ציון: 40ציון: 90ציון: 75[100, 90, 85, 75, 70, 40]שלושת הגבוהים: [100, 90, 85]ממוצע בלי קצוות: 80.0
שלום דנהשלום עומר
3 2 9 310None 10
show מדפיסה 10 בעצמה, אבל לא מחזירה כלום. לכן a הוא None.
True False Truereturn בתוך הלולאה יוצא מהפונקציה מיד. ל-2 ה-range ריק, ולכן מוחזר True.
inside: 99outside: 10
[85, 95]הפונקציה קיבלה את אותה רשימה, ולכן השינוי נשאר גם אחרי שהיא מסתיימת.
254
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
הפונקציה מחשבת אבל לא מחזירה, ולכן area(3, 4) הוא None, ו-None + 1 זו שגיאה. התיקון: להוסיף return result.
יודפס 1 בלבד. return יוצא מהפונקציה, ולכן השורה print("after") לא רצה אף פעם ("קוד מת").
פתרון לדוגמה (יש עוד דרכים נכונות):
def digit_sum(n): total = 0 while n > 0: total += n % 10 n //= 10 return total def is_lucky(n): return digit_sum(n) % 7 == 0 for n in range(1, 101): if is_lucky(n): print(n, end=" ")
7 16 25 34 43 52 59 61 68 70 77 86 95פתרון לדוגמה (יש עוד דרכים נכונות):
def count_above(lst, limit=0): count = 0 for x in lst: if x > limit: count += 1 return count print(count_above([3, -1, 8, 0, 5])) print(count_above([3, -1, 8, 0, 5], 4))
32
פתרון לדוגמה (יש עוד דרכים נכונות):
def top3(lst): work = lst[:] # a copy - the caller's list stays the same result = [] while len(work) > 0 and len(result) < 3: best = work[0] for x in work: if x > best: best = x result.append(best) work.remove(best) return result nums = [5, 9, 2, 7, 9] print(top3(nums)) print(nums) print(top3([4]))
[9, 9, 7][5, 9, 2, 7, 9][4]
כשיש פחות משלושה איברים הפונקציה מחזירה את מה שיש.
פתרון לדוגמה (יש עוד דרכים נכונות):
def menu(): print("1) חיבור 2) חזקה 0) יציאה") return int(input("בחירה: ")) def add(a, b): return a + b def power(a, b): result = 1 for _ in range(b): result *= a return result choice = menu() while choice != 0: a = int(input("a: ")) b = int(input("b: ")) if choice == 1: print(add(a, b)) elif choice == 2: print(power(a, b)) choice = menu()
1) חיבור 2) חזקה 0) יציאהבחירה: 1a: 3b: 471) חיבור 2) חזקה 0) יציאהבחירה: 2a: 2b: 1010241) חיבור 2) חזקה 0) יציאהבחירה: 0
2 1 5 [1, 4, 4, 7]sorted על tuple מחזירה רשימה.
(20, 30, 40) 40 5 True<class 'int'> <class 'tuple'>סוגריים לבד הם רק סוגריים. מה שיוצר tuple הוא הפסיק.
4 8 6.0(1, 2, 1.5)
danalinaomer 97
3 1 2הצד הימני מחושב כולו לפני ההצבה: (3, 1, 2).
TypeError: 'tuple' object does not support item assignment
tuple לא ניתן לשינוי. אפשר ליצור tuple חדש: point = (10, point[1]), או להשתמש ברשימה.
ValueError: too many values to unpack (expected 2)
בפריסה מספר המשתנים חייב להיות שווה למספר האיברים: כאן 2 משתנים ו-3 איברים. התיקון: a, b, c = (1, 2, 3).
tuple: נתונים קבועים שלא אמורים להשתנות, ובדרך כלל מסוגים שונים, כמו נקודה (x, y) או רשומה ("dana", 88). רשימה: אוסף שגדל, קטן או משתנה, כמו רשימת ציונים שמוסיפים לה.
פתרון לדוגמה (יש עוד דרכים נכונות):
def min_max(lst): low = lst[0] high = lst[0] for x in lst: if x < low: low = x if x > high: high = x return low, high lo, hi = min_max([7, 3, 9, 1, 5]) print(lo, hi)
1 9פתרון לדוגמה (יש עוד דרכים נכונות):
students = [("dana", 88), ("omer", 54), ("lina", 97), ("adam", 71)] flipped = [] for name, grade in students: flipped.append((grade, name)) flipped.sort(reverse=True) print("הכי גבוה:", flipped[0][1]) for grade, name in flipped: print(name, grade)
הכי גבוה: linalina 97dana 88adam 71omer 54
tuple-ים ממוינים לפי האיבר הראשון, ולכן הציון צריך להיות ראשון.
פתרון לדוגמה (יש עוד דרכים נכונות):
points = [] for i in range(3): x = int(input("x: ")) y = int(input("y: ")) points.append((x, y)) best = points[0] for x, y in points: if x * x + y * y < best[0] ** 2 + best[1] ** 2: best = (x, y) print("הכי קרובה:", best)
x: 3y: 4x: -1y: 2x: 5y: 0הכי קרובה: (-1, 2)
{'dana': 17, 'omer': 17, 'lina': 15}3 True False
in בודק מפתחות, ולכן 17 in ages הוא False, אף ש-17 הוא ערך במילון.
19breadmilk
{'to': 2, 'be': 2, 'or': 1, 'not': 1}1 None 0{'m': 1, 'i': 4, 's': 4, 'p': 2}i 4
i ו-s שתיהן 4. > שומר את מי שהגיעה ראשונה במילון (i).
{'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}2
KeyError: 'bread'
אין במילון מפתח "bread". בודקים קודם עם if "bread" in stock:, או משתמשים ב-stock.get("bread", 0).
KeyError: 'hi'
בפעם הראשונה ש-"hi" מגיעה, אין לה עדיין ערך, ולכן counts[w] += 1 נכשל. התיקון: counts[w] = counts.get(w, 0) + 1.
ברשימה ניגשים לפי מיקום (0, 1, 2…), ובמילון לפי מפתח משמעותי. רשימה מתאימה לרצף של ערכים, כמו ציונים לפי הסדר. מילון מתאים לחיפוש לפי שם, כמו ספר טלפונים: שם ⟵ מספר.
פתרון לדוגמה (יש עוד דרכים נכונות):
grades = {"dana": 88, "omer": 54, "lina": 97, "adam": 71} avg = sum(grades.values()) / len(grades) print("ממוצע:", avg) best = "" for name in grades: if best == "" or grades[name] > grades[best]: best = name print("הכי גבוה:", best) for name, g in grades.items(): if g > avg: print(name)
ממוצע: 77.5הכי גבוה: linadanalina
פתרון לדוגמה (יש עוד דרכים נכונות):
book = {} choice = input("בחירה (1/2/3/0): ") while choice != "0": if choice == "1": name = input("שם: ") book[name] = input("טלפון: ") elif choice == "2": name = input("שם: ") if name in book: print(book[name]) else: print("לא נמצא") elif choice == "3": for name in sorted(book): print(name, book[name]) choice = input("בחירה (1/2/3/0): ")
בחירה (1/2/3/0): 1שם: omerטלפון: 050-1111111בחירה (1/2/3/0): 1שם: danaטלפון: 052-2222222בחירה (1/2/3/0): 2שם: linaלא נמצאבחירה (1/2/3/0): 3dana 052-2222222omer 050-1111111בחירה (1/2/3/0): 0
פתרון לדוגמה (יש עוד דרכים נכונות):
records = [("dana", "math", 90), ("omer", "math", 60), ("dana", "english", 80), ("omer", "english", 75), ("lina", "math", 100)] by_student = {} for name, subject, grade in records: if name not in by_student: by_student[name] = [] by_student[name].append(grade) for name, grades in by_student.items(): print(name, sum(grades) / len(grades))
dana 85.0omer 67.5lina 100.0
פתרון לדוגמה (יש עוד דרכים נכונות):
sentence = input("משפט: ") counts = {} for w in sentence.lower().split(): counts[w] = counts.get(w, 0) + 1 pairs = [] for w, c in counts.items(): pairs.append((c, w)) pairs.sort(reverse=True) for c, w in pairs: print(w, c)
משפט: The cat and the hat and THE batthe 3and 2hat 1cat 1bat 1
מיון של (מספר, מילה) מהגדול לקטן. כשהמספרים שווים, המילים ממוינות בסדר הפוך (z לפני a).
['onetwo\n', 'three\n']2
write לא מוסיף ירידת שורה, ולכן one ו-two באותה שורה.
onetwothree
CD
CD
24 3 8.0בלי הבדיקה, int("") היה זורק ValueError על השורה הריקה.
danalinaadam
שורה שמתחילה ב-# היא הערה, ומדלגים עליה. split() מחלק לפי רווחים.
3 12 3המספר הראשון הוא מספר השורות (הקובץ מסתיים ב-\n, ולכן יש חלק ריק בסוף), השני מספר המילים, והשלישי כמה פעמים מופיע הרצף "up".
TypeError: write() argument must be str, not int
write מקבל רק מחרוזת. התיקון: f.write(str(i) + "\n"), כי צריך גם ירידת שורה.
FileNotFoundError: [Errno 2] No such file or directory: 'scores.txt'
אין קובץ בשם scores.txt בתיקייה שבה התוכנית רצה. בודקים את שם הקובץ ואת המיקום, או תופסים את השגיאה עם try / except FileNotFoundError.
כל שורה בקובץ כבר מסתיימת ב-\n, ו-print מוסיף עוד אחת. מתקנים עם print(line.strip()) (או print(line, end="")).
פתרון לדוגמה (יש עוד דרכים נכונות):
f = open("squares.txt", "w") for n in range(1, 11): f.write(str(n) + " " + str(n * n) + "\n") f.close() total = 0 f = open("squares.txt", "r") for line in f: parts = line.split() total += int(parts[1]) f.close() print(total)
3851 12 43 94 165 256 367 498 649 8110 100
פתרון לדוגמה (יש עוד דרכים נכונות):
count = 0 total = 0 best_name = "" best = -1 f = open("grades.txt", "r") for line in f: line = line.strip() if line == "" or line[0] == "#": continue parts = line.split() grade = int(parts[1]) total += grade count += 1 if grade > best: best = grade best_name = parts[0] f.close() print("ממוצע:", total / count) print("הכי גבוה:", best_name)
ממוצע: 77.5הכי גבוה: lina
פתרון לדוגמה (יש עוד דרכים נכונות):
src = open("grades.txt", "r") dst = open("passed.txt", "w") passed = 0 for line in src: parts = line.split() if len(parts) == 2 and parts[0][0] != "#" and int(parts[1]) >= 55: dst.write(line) passed += 1 dst.write("passed: " + str(passed) + "\n") src.close() dst.close() print("נכתבו", passed, "שורות")
נכתבו 3 שורותdana 88lina 97adam 71passed: 3
len(parts) == 2 מדלג גם על השורה הריקה (שם parts ריק).
פתרון לדוגמה (יש עוד דרכים נכונות):
try: f = open("counter.txt", "r") count = int(f.read()) f.close() except FileNotFoundError: count = 0 count += 1 print("התוכנית רצה", count, "פעמים") f = open("counter.txt", "w") f.write(str(count)) f.close()
4התוכנית רצה 5 פעמיםבהרצה לדוגמה הקובץ כבר הכיל 4, כאילו התוכנית רצה 4 פעמים קודם.
1 the sun is up3 up up and away
name,class,grade5 ('dana', 'a1', 88)
a1 83.33333333333333a2 62.5
up 3max(d, key=d.get) מחזיר את המפתח שהערך שלו הכי גדול.
3 replacementsthe sun is UPthe day is longUP UP and away
ValueError: invalid literal for int() with base 10: 'grade'
השורה הראשונה היא שורת הכותרות, ו-int("grade") נכשל. התיקון: f.readline() לפני הלולאה, כדי לדלג על הכותרות.
פתיחה במצב "w" מרוקנת את הקובץ מיד, עוד לפני שקראנו ממנו. הדרך הנכונה: לקרוא קודם את כל התוכן לזיכרון ולסגור, ורק אז לפתוח לכתיבה. אפשרות אחרת: לכתוב לקובץ חדש.
פתרון לדוגמה (יש עוד דרכים נכונות):
def find_word(filename, word): result = [] line_no = 0 f = open(filename, "r") for line in f: line_no += 1 if word in line.split(): result.append(line_no) f.close() return result for w in ["is", "sky"]: lines = find_word("poem.txt", w) if len(lines) > 0: print(w, lines) else: print(w, "לא נמצאה")
the sun is upthe day is longup up and away
is [1, 2]sky לא נמצאה
פתרון לדוגמה (יש עוד דרכים נכונות):
lines = 0 words = 0 chars = 0 longest = "" with open("poem.txt") as f: for line in f: line = line.strip() lines += 1 words += len(line.split()) chars += len(line) if len(line) > len(longest): longest = line print(lines, words, chars) print("הארוכה:", longest)
the sun is upthe day is longup up and away
3 12 42הארוכה: the day is long
פתרון לדוגמה (יש עוד דרכים נכונות):
rows = [] with open("scores.csv") as f: f.readline() for line in f: name, cls, grade = line.strip().split(",") rows.append((int(grade), name)) rows.sort(reverse=True) total = 0 with open("report.txt", "w") as out: for grade, name in rows: if grade >= 55: status = "עבר" else: status = "נכשל" out.write(f"{name}: {grade} ({status})\n") total += grade out.write(f"ממוצע: {total / len(rows)}\n") print("נכתב report.txt")
נכתב report.txtlina: 97 (עבר)dana: 88 (עבר)adam: 71 (עבר)noa: 65 (עבר)omer: 54 (נכשל)ממוצע: 75.0
פתרון לדוגמה (יש עוד דרכים נכונות):
index = {} line_no = 0 with open("poem.txt") as f: for line in f: line_no += 1 for w in line.lower().split(): if w not in index: index[w] = [] if line_no not in index[w]: index[w].append(line_no) for w in sorted(index): print(w, index[w])
the sun is upthe day is longup up and away
and [3]away [3]day [2]is [1, 2]long [2]sun [1]the [1, 2]up [1, 3]
"up" מופיעה פעמיים בשורה 3, אבל מספר השורה נשמר פעם אחת.
פתרון לדוגמה (יש עוד דרכים נכונות):
stock = {} with open("stock.txt") as f: for line in f: item, amount = line.strip().split(",") stock[item] = int(amount) item = input("מוצר: ") while item != "end": qty = int(input("כמות: ")) if item not in stock: print("אין מוצר כזה") elif qty > stock[item]: print("אין מספיק במלאי, נשארו", stock[item]) else: stock[item] -= qty item = input("מוצר: ") with open("stock.txt", "w") as f: for item, amount in stock.items(): f.write(item + "," + str(amount) + "\n") print(stock)
מוצר: milkכמות: 2מוצר: breadכמות: 9אין מספיק במלאי, נשארו 3מוצר: colaכמות: 1אין מוצר כזהמוצר: end{'milk': 3, 'bread': 3, 'eggs': 12}