From d3688ca0b4b14c0aa36e809a8574fc300bfac771 Mon Sep 17 00:00:00 2001 From: Yam Mesicka Date: Mon, 25 Nov 2019 06:40:24 +0200 Subject: [PATCH] Add unpacking notebook, fix index of builtins --- week4/4_Unpacking.ipynb | 929 +++++++++++++++++++ week4/{6_Builtins.ipynb => 5_Builtins.ipynb} | 72 ++ week4/images/unpacking.svg | 3 + 3 files changed, 1004 insertions(+) create mode 100644 week4/4_Unpacking.ipynb rename week4/{6_Builtins.ipynb => 5_Builtins.ipynb} (96%) create mode 100644 week4/images/unpacking.svg diff --git a/week4/4_Unpacking.ipynb b/week4/4_Unpacking.ipynb new file mode 100644 index 0000000..f5ea802 --- /dev/null +++ b/week4/4_Unpacking.ipynb @@ -0,0 +1,929 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"לוגו" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Unpacking" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## הקדמה" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " הנה שורה שתראה לנו קצת שונה תחבירית מכל מה שהכרנו עד עכשיו:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "country, population = ('Israel', 8712000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " בצד ימין יש tuple שמכיל שני איברים, ואנחנו מבצעים השמה לשני משתנים ששמותיהם country ו־population.
\n", + " אמנם לא הייתי נותן לפיסת הקוד הזו את תואר פיסת הקוד הנאה בעולם, אבל נראה שפייתון יודע להריץ אותה:
\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(f\"There are {population} people living in {country}.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " חזינו כאן במעין השמה כפולה שפייתון מאפשרת לנו לבצע:
\n", + " את האיבר הראשון בצד ימין היא הכניסה לאיבר הראשון בצד שמאל, ואת האיבר השני בצד ימין היא הכניסה לאיבר השני בצד שמאל.
\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"ארבע" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " התחביר שמאפשר לפייתון לפרק מבנה ולבצע השמה של האיברים שבו לכמה שמות משתנים במקביל, קיבל את השם unpacking.\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unpacking לתוך משתנים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### המקרה הקלאסי" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " מתכנתים רבים מנצלים את הנוחות שב־unpacking, מה שגורם לו להופיע בקוד שתמצאו \"בעולם האמיתי\" פעמים רבות.
\n", + " ניתן לבצע השמה לכמה משתנים שנרצה במקביל:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b, c, d, e = (1, 2, 3, 4, 5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " הטכניקה הזו עובדת גם עבור טיפוסים אחרים שמוגדרים כ־iterable:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b = [1, 2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " ואפילו בלי סוגריים (זה לא קסם – בצד ימין נוצר בפועל tuple):\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b = 1, 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " או כ\"חילוץ איברים\" מתוך משתנה קיים לתוך כמה משתנים נפרדים:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "point_on_map = (36.672011, 65.807761)\n", + "x, y = point_on_map\n", + "print(f\"The treasure should be in ({x}, {y}).\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " בדוגמה האחרונה יצרנו בשורה הראשונה משתנה שמצביע ל־tuple. ב־tuple ישנם שני מספרים מסוג float.
\n", + " בשורה השנייה פירקנו את ה־tuple – הערך הראשון שלו הוכנס לתוך המשתנה x והערך השני שלו הוכנס לתוך המשתנה y. \n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### unpacking בלולאות for" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " שימוש מקובל מאוד ל־unpacking אותו כבר הספקתם לראות בעבר, מתרחש בלולאות for.
\n", + " ניצור רשימה של tuple־ים, בה כל tuple ייצג מדינה ואת כמות האנשים החיים בה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "countries_with_population = [\n", + " ('Cyprus', 1198575),\n", + " ('Eswatini', 1148130),\n", + " ('Djibouti', 973560),\n", + " ('Fiji', 889953),\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + "בעולם ללא unpacking, היינו צריכים לכתוב את הקוד הבא:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for item in countries_with_population:\n", + " country = item[0]\n", + " population = item[1]\n", + " print(f\"There are {population:9,} people in {country}.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אבל כיוון שאנחנו חיים בעולם טוב יותר, פייתון מאפשרת לנו לעשות את הטריק הבא:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for country, population in countries_with_population:\n", + " print(f\"There are {population:9,} people in {country}.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
תצוגה על המשתנה countries_with_population ועל צורת הפירוק שלו
0123
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01
\"Cyprus\"1198575
-2-1
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01
\"Eswatini\"1148130
-2-1
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01
\"Djibouti\"973560
-2-1
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01
\"Fiji\"889953
-2-1
\n", + "
-4-3-2-1
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " באיור למעלה, התאים האדומים מפורקים לתוך המשתנה country והתאים הירוקים לתוך המשתנה population.
\n", + " כל איטרציה של הלולאה תגרום לפירוק של צמד אחד מתוך הרשימה, והשמתם בהתאמה לתוך צמד המשתנים שבראש לולאת ה־for.\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### במילונים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " הרעיון של unpacking הופך להיות שימושי מאוד כשאנחנו רוצים לעבור על המפתח והערך של מילון בו זמנית.
\n", + " כל שנצטרך לעשות כדי לקבל את המפתח לצד הערך בכל איטרציה, זה להשתמש בפעולה items על המילון:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "countries_with_population = {\n", + " 'Cyprus': 1198575,\n", + " 'Eswatini': 1148130,\n", + " 'Djibouti': 973560,\n", + " 'Fiji': 889953,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for country, population in countries_with_population.items():\n", + " print(f\"There are {population:9,} people in {country}.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### unpacking לערכי חזרה מפונקציה" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " המקרה הזה לא שונה מהמקרים הקודמים שראינו, אבל חשבתי שיהיה נחמד לראות אותו במפורש.
\n", + " הפעם נקח פונקציה שמחזירה tuple, ונשתמש ב־unpacking כדי לפרק את הערכים שהיא מחזירה למשתנים.
\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def division_and_modulo(number, divisor):\n", + " division = number // divisor\n", + " modulo = number % divisor\n", + " return (division, modulo) # אפשר גם בלי הסוגריים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " נשתמש בפונקציה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "division_and_modulo(5, 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " והרי שאם מוחזר לנו tuple, אפשר לעשות לו unpacking:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "div, mod = division_and_modulo(5, 2)\n", + "print(f\"division: {div}, modulo: {mod}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unpacking לארגומנטים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " נבחן את הקוד הפשוט הבא:
\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "treasure_location = (36.671111, 65.808056)\n", + "print_treasure_location(treasure_location[0], treasure_location[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " הגדרנו פונקציה שמדפיסה לנו יפה מיקומים לפי x ו־y שהיא מקבלת.
\n", + " המימוש הגיוני, אבל אוי א בראך! השימוש מאוד לא נוח!
\n", + " כל פעם אנחנו צריכים לפרק את ה־tuple שמכיל את המיקום ל־2 איברים, ולשלוח כל אחד מהם בנפרד.\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### unpacking לארגומנטים לפי מיקום" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " כפתרון למצב, פייתון מאפשרת לנו לעשות את הקסם הנפלא הבא:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "treasure_location = (36.671111, 65.808056)\n", + "print_treasure_location(*treasure_location)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " נראה מוזר? זו לא טעות, זהו באמת תחביר שמעולם לא ראינו עדיין!
\n", + " הכוכבית מפרקת את ה־tuple שהגדרנו, treasure_location, ושולחת לארגומנט x את הערך הראשון ולארגומנט y את הערך השני.\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אם היו לנו ערכים רבים, היינו יכולים להשתמש באותו טריק בלולאה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "treasure_locations = [\n", + " (36.671111, 65.808056),\n", + " (53.759748, -2.648121),\n", + " (52.333333, 1.183333),\n", + " (52.655278, -1.906667),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "for treasure_location in treasure_locations:\n", + " print_treasure_location(*treasure_location)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אבל נזכור שאנחנו יכולים להשתמש גם בתעלול שלמדנו על unpacking בתוך for:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "for treasure_x, treasure_y in treasure_locations:\n", + " print_treasure_location(treasure_x, treasure_y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### unpacking לארגומנטים לפי שם הארגומנט" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " מצוידים בפונקציה להדפסת המיקום, אנחנו מקבלים את רשימת המילונים הבאה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "treasure_maps = [\n", + " {'x': 36.671111, 'y': 65.808056},\n", + " {'x': 53.759748, 'y': -2.648121},\n", + " {'x': 52.333333, 'y': 1.183333},\n", + " {'x': 52.655278, 'y': -1.906667}\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אין מנוס, דנו אותנו לחיי עבדות של פירוק מילונים ושליחת ערכיהם לפונקציות! 😢\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "for location in treasure_maps:\n", + " print_treasure_location(location.get('x'), location.get('y'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " או שאולי לא?\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " במקרה המאוד מיוחד של מילון, ניתן לשלוח לפונקציה את הפרמטרים בעזרת unpacking עם שתי כוכביות.
\n", + " המפתחות של המילון צריכים לציין את שם הפרמטרים של הפונקציה, והערכים במילון יהיו הערך שיועבר לאותם פרמטרים:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "treasure_maps = [\n", + " {'x': 36.671111, 'y': 65.808056},\n", + " {'x': 53.759748, 'y': -2.648121},\n", + " {'x': 52.333333, 'y': 1.183333},\n", + " {'x': 52.655278, 'y': -1.906667}\n", + "]\n", + "\n", + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "for location in treasure_maps:\n", + " print_treasure_location(**location)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " מה קרה פה?
\n", + " באיטרציה הראשונה location היה {'x': 36.671111, 'y': 65.808056}.
\n", + " הפונקציה print_treasure_locations מחכה שיעבירו לה ערך לפרמטר x ולפרמטר y.
\n", + " ה־unpacking שעשינו בעזרת שתי הכוכביות העביר את הערך של המפתח 'x' במילון לפרמטר x, ואת הערך שהיה תחת המפתח 'y' במילון לפרמטר y.\n", + "

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " נראה דוגמה נוספת לפונקציה שמקבלת שנה, חודש ויום ומחזירה לנו תאריך כמחרוזת:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def stringify_date(year, month, day):\n", + " return f'{year}-{month}-{day}'\n", + "\n", + "date = {'year': 1815, 'month': 12, 'day': 10}\n", + "print(stringify_date(**date))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## שגיאות" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אנחנו רגילים שפייתון די מתירני, אבל על unpacking תקין הוא לא מוותר.
\n", + " בדוגמה הבאה אנחנו מנסים לחלץ שני איברים לתוך שלושה משתנים, וזה לא נגמר טוב:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b, c = (1, 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " נקבל שגיאה דומה אך שונה כשננסה לחלץ מספר לא נכון של ארגומנטים לתוך פונקציה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_treasure_location(x, y):\n", + " print(f\"{x}°N, {y}°E\")\n", + "\n", + "location_3d = (36.671111, 65.808056, 63.124592)\n", + "print_treasure_location(*location_3d)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " אם ננסה לעשות unpacking לאיבר שאינו iterable, תתקבל השגיאה הבאה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b = 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## קוד לדוגמה" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + "סדרת פיבונאצ'י היא סדרה שמתחילה באיברים 1 ו־1, וכל איבר בה הוא סכום שני האיברים הקודמים לו.
\n", + "האיברים הראשונים בסדרה, הם (מימין לשמאל) 1, 1, 2, 3, 5, 8, וכך הסדרה ממשיכה.
\n", + "במימוש פונקציה שמקבלת מספר ומחזירה את סכום כל איברי הסדרה עד אותו מספר, נוכל להשתמש ב־unpacking כדי לשפר את הקריאות של הפונקציה:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def fibonacci_no_unpacking(number):\n", + " # הפונקציה בלי unpacking\n", + " a = 1\n", + " b = 1\n", + " total = 0\n", + " while a <= number:\n", + " total = total + a\n", + " temp = a\n", + " a = b\n", + " b = temp + b\n", + " return total\n", + "\n", + "\n", + "def fibonacci_sum(number):\n", + " # הפונקציה עם unpacking\n", + " a, b = 1, 1\n", + " total = 0\n", + " while a <= number:\n", + " total = total + a\n", + " a, b = b, a + b\n", + " return total\n", + "\n", + "fibonacci_sum(8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## תרגילים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### אליבי לרוצחים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " לפניכם tuple המכיל מספר מילונים, כאשר כל מילון מייצג דמות חשודה ברצח.
\n", + " בתוך כל אחד מהמילונים, תחת המפתח evidences, ישנו tuple שבו שני איברים.
\n", + " האיבר הראשון הוא הנשק שנתפס על ידי המשטרה, והאיבר השני הוא המיקום המרכזי בו הדמות הייתה באותו יום.
\n", + " בהנתן שהרצח בוצע על ידי אקדח דרינגר (derringer) ב־Petersen House, הדפיסו רק את שמות האנשים שעדיין חשודים ברצח.
\n", + " השתדלו להשתמש ב־unpacking לפחות פעמיים.\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "students = (\n", + " {'name': 'Anne', 'evidences': ('derringer', 'Caesarea')},\n", + " {'name': 'Taotao', 'evidences': ('derringer', 'Petersen House')},\n", + " {'name': 'Pilpelet', 'evidences': ('Master Sword', 'Hyrule')},\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " לנוחיותכם, הנה פונקציה שמקבלת כלי נשק ומיקום, ובודקת האם הראיות תואמות:\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": 189, + "metadata": {}, + "outputs": [], + "source": [ + "def check_evidences(weapon, location):\n", + " return weapon.lower() == 'derringer' and location.lower() == 'petersen house'" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/week4/6_Builtins.ipynb b/week4/5_Builtins.ipynb similarity index 96% rename from week4/6_Builtins.ipynb rename to week4/5_Builtins.ipynb index 99e608a..50a2c1d 100644 --- a/week4/6_Builtins.ipynb +++ b/week4/5_Builtins.ipynb @@ -1790,6 +1790,77 @@ " print(f\"The sum until {number} is {current_sum}\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ממוצע ציונים" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

\n", + " קבלו רשימת תלמידים, ואז עבור כל תלמיד את רשימת הציונים שלו.
\n", + " הדפיסו את התלמיד שממוצע הציונים שלו היה הגבוה ביותר לצד הציונים שלו.\n", + "

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_grades(student_name):\n", + " grades = []\n", + " grade = input(f'Please enter a grade for {student_name}: ')\n", + "\n", + " while grade.isdecimal():\n", + " grades.append(int(grade))\n", + " grade = input(f'Please enter another grade for {student_name}: ')\n", + "\n", + " return grades\n", + "\n", + "\n", + "def get_students():\n", + " students = []\n", + " student = input('Please enter a student: ')\n", + "\n", + " while student != '':\n", + " students.append(student)\n", + " student = input('Please enter another student: ')\n", + "\n", + " return students\n", + "\n", + "\n", + "def get_students_and_grades():\n", + " grades = []\n", + " students = get_students()\n", + " for student in students:\n", + " student_grades = get_grades(student)\n", + " grades.append(student_grades)\n", + "\n", + " return zip(students, grades)\n", + "\n", + "\n", + "def get_average_grade(student_and_his_grades):\n", + " grades = student_and_his_grades[1]\n", + " if len(grades) == 0:\n", + " return 0\n", + "\n", + " return sum(grades) / len(grades)\n", + "\n", + "\n", + "students_and_grades = get_students_and_grades()\n", + "students_sorted_by_grades = sorted( # מפצלים שורה כדי שלא יהיו שורות ארוכות מדי\n", + " students_and_grades, key=get_average_grade, reverse=True\n", + ")\n", + "best_student_name, best_grade = students_sorted_by_grades[0]\n", + "print(f\"The best student is {best_student_name} with the grades: {best_grade}\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1874,6 +1945,7 @@ "source": [ "

\n", " מצאו את עשר המילים הנפוצות ביותר בספר \"מלחמה ושלום\", והדפיסו אותן למסך מהמילה הנפוצה ביותר למילה הכי פחות נפוצה.
\n", + " ליד כל מילה הדפיסו את כמות הפעמים שהופיע בספר.
\n", " הספר נמצא בקובץ war-and-peace.txt בתוך התיקייה resources.\n", "

" ] diff --git a/week4/images/unpacking.svg b/week4/images/unpacking.svg new file mode 100644 index 0000000..7a23afd --- /dev/null +++ b/week4/images/unpacking.svg @@ -0,0 +1,3 @@ + + +
population
population
country
country
Israel
Israel
8712000
8712000
,
[Not supported by viewer]
,
[Not supported by viewer]
\ No newline at end of file