# List:
italian_artists = ['Donatelo', 'Giotto', 'Leonardo', 'Masaccio', 'Michelangelo', 'Raphael', 'Titian']
# Tuple:
italian_artists = ('Donatelo', 'Giotto', 'Leonardo', 'Masaccio', 'Michelangelo', 'Raphael', 'Titian')

"""
Explanation: <img src="images/logo.jpg" style="display: block; margin-left: auto; margin-right: auto;" alt="לוגו של מיזם לימוד הפייתון. נחש מצויר בצבעי צהוב וכחול, הנע בין האותיות של שם הקורס: לומדים פייתון. הסלוגן המופיע מעל לשם הקורס הוא מיזם חינמי ללימוד תכנות בעברית.">
<span style="text-align: right; direction: rtl; float: right;">קבוצות</span>
<span style="text-align: right; direction: rtl; float: right; clear: both;">הגדרה</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    <dfn>קבוצה</dfn> (או <dfn>set</dfn>) בפייתון היא אוסף של איברים שמתאפיינת בתכונות הבאות:
</p>

<ul style="text-align: right; direction: rtl; float: right; clear: both;">
    <li>לאיברים באוסף אין סדר מוגדר.</li>
    <li>ערך לא יכול להופיע יותר מפעם אחת.</li>
    <li>כל איבר חייב להיות immutable.</li>
</ul>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    לדוגמה:
</p>

<ul style="text-align: right; direction: rtl; float: right; clear: both;">
    <li>כתובות הדואר האלקטרוני של כל הזכאים לתעודת סיום בקורס פייתון.</li>
    <li>המספרים הראשוניים עד 1,000.</li>
    <li>שמות כל הקבצים בתיקייה images.</li>
    <li>המילים בספר "קפקא על החוף", ללא כפילויות.</li>
</ul>

<span style="text-align: right; direction: rtl; float: right; clear: both;">שימוש</span>
<span style="text-align: right; direction: rtl; float: right; clear: both;">הבסיס</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    עד מחברת זו, לו היינו מתבקשים להגדיר מבנה נתונים שיאחסן עבורנו שמות של אומנים איטלקים ידועים, היינו משתמשים ברשימה או ב־tuple־ים:
</p>
End of explanation
"""


italian_artists = {'Donatelo', 'Giotto', 'Leonardo', 'Masaccio', 'Michelangelo', 'Raphael', 'Titian'}

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אך כיוון שמדובר באוסף איברים ללא חזרות וללא סדר מוגדר, אפשר לשמור אותם כ־set:
</p>
End of explanation
"""


invisible_pink_unicorns = set()
print(invisible_pink_unicorns)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אפשר לראות שההגדרות דומות מאוד במראה שלהן.<br>
    כדי להגדיר קבוצה, נפתח סוגריים מסולסלים (כמו במילון), ונציין את איבריה, כשהם מופרדים זה מזה בפסיקים.<br>
    אם תרצו, תוכלו לדמיין קבוצה כמילון שבו יש רק מפתחות.
</p>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    נוכל גם להגדיר קבוצה ריקה באמצעות הפונקציה <code>set</code>.<br>
    נגדיר, לדוגמה, את קבוצת כל החדי־קרן הוורודות הבלתי נראות:
</p>
End of explanation
"""


numbers = range(10)
numbers = set(numbers)
print(numbers)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    תעלול נחמד נוסף הוא המרת iterable לקבוצה, באמצעות אותה הפונקציה:
</p>
End of explanation
"""


print({1, 1, 2, 3, 5})
print(set('abccccccccccc'))

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    בהגדרה שבתחילת הפרק ציינו שקבוצה לא תכיל כמה איברים בעלי ערך זהה.<br>
    למרות ההגבלה הזו, בהגדרת הקבוצה אפשר לספק ערכים שחוזרים על עצמם.<br>
    הקבוצה "תבלע" את הכפילויות בערכים, ותשאיר רק איבר אחד מכל ערך:
</p>
End of explanation
"""


italian_artists = {'Donatelo', 'Giotto', 'Leonardo', 'Masaccio', 'Michelangelo', 'Raphael', 'Titian'}

"""
Explanation: <div class="align-center" style="display: flex; text-align: right; direction: rtl; clear: both;">
    <div style="display: flex; width: 10%; float: right; clear: both;">
        <img src="images/exercise.svg" style="height: 50px !important;" alt="תרגול"> 
    </div>
    <div style="width: 70%">
        <p style="text-align: right; direction: rtl; float: right; clear: both;">
            הגדירו קבוצה שאיבריה הם האותיות הקטנות והגדולות באנגלית.<br>
            ישנו פתרון פשוט שלא מצריך מכם לכתוב את כל הא"ב.
        </p>
    </div>
    <div style="display: flex; width: 20%; border-right: 0.1rem solid #A5A5A5; padding: 1rem 2rem;">
        <p style="text-align: center; direction: rtl; justify-content: center; align-items: center; clear: both;">
            <strong>חשוב!</strong><br>
            פתרו לפני שתמשיכו!
        </p>
    </div>
</div>

<span style="text-align: right; direction: rtl; float: right; clear: both;">פעולות בין קבוצות</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    נגדיר שוב את קבוצת האומנים האיטלקים:
</p>
End of explanation
"""


ninja_turtles_characters = {'Donatelo', 'Leonardo', 'Michelangelo', 'Raphael', 'Splinter', 'Shredder'}

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אחד מיתרונותיהן רבי־הערך של קבוצות הוא היכולת לבצע ביניהן פעולות בקלות.<br>
    נדגים את הרעיון בעזרת הגדרת קבוצה נוספת, הפעם של דמויות מחוברות הקומיקס של צבי הנינג'ה:
</p>
End of explanation
"""


ninja_turtles_characters.intersection(italian_artists)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    כעת נוכל, לדוגמה, לבחור את כל הדמויות מצבי הנינג'ה שנושאות שם של אומן איטלקי מפורסם.<br>
    הקבוצה שנוצרת מהאיברים המשותפים לשתי הקבוצות נקראת <dfn>קבוצת החיתוך</dfn>.
</p>
End of explanation
"""


italian_artists.difference(ninja_turtles_characters)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    ישנן פעולות רבות נוספות שאפשר לבצע בין קבוצות.<br>
    דרך קלה להמחיש את היחסים ההדדיים בין הקבוצות הללו היא תרשים שנקרא "<a href="https://he.wikipedia.org/wiki/%D7%93%D7%99%D7%90%D7%92%D7%A8%D7%9E%D7%AA_%D7%95%D7%9F">דיאגרמת ון</a>":
</p>

<figure>
    <img src="images/venn.svg" style="max-width: 600px; margin-right: auto; margin-left: auto; text-align: center;" alt="בתמונה מופיעים שני עיגולים: ורוד בימין, מעליו מופיע הכיתוב 'דמויות מצבי הנינג'ה', וטורקיז בשמאל, מעליו מופיע הכיתוב 'אומנים איטלקים'. בין העיגולים ישנה חפיפה קלה בצבע חום. בעיגול הוורוד שבימין יש את האיברים Splinter ו־Shredder, ובעיגול הטורקיז השמאלי את Giotto, Masacccio ו־Titian. בשטח החום שבחפיפה נמצאים האיברים Donatelo, Leonardo, Michelangelo ו־Raphael."/>
    <figcaption style="margin-top: 2rem; text-align: center; direction: rtl;">דיאגרמת ון של שתי קבוצות: דמויות מצבי הנינג'ה ואומנים איטלקים.<br>
    אפשר לראות בשטח החפיפה שבין שני העיגולים את האיברים המשותפים לשתי הקבוצות.</figcaption>
</figure>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    נוכל גם לבקש, לדוגמה, את שמות האומנים האיטלקים שאינם דמויות מצבי הנינג'ה.<br>
    נקבל בחזרה את השמות שמופיעים בתרשים בעיגול הטורקיז, אך לא בחיתוך בין שני העיגולים:
</p>
End of explanation
"""


ninja_turtles_characters.difference(italian_artists)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    באותה צורה נוכל לבקש את שמות כל הדמויות מצבי הנינג'ה שאינם אומנים איטלקים.<br>
    אלו השמות שמופיעים אך ורק בעיגול הורוד, ולא בחיתוך בין שני העיגולים:
</p>
End of explanation
"""


ninja_turtles_characters.union(italian_artists)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אפשר לבקש גם את <dfn>קבוצת האיחוד</dfn>, שמורכבת מכל הדמויות שקיימות בשתי הקבוצות.<br>
    אלו כל הדמויות שמופיעות בשרטוט:
</p>
End of explanation
"""


ninja_turtles_characters.symmetric_difference(italian_artists)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    או את כל הדמויות שלא משותפות לשתי הקבוצות.<br>
    אלו כל הדמויות שמופיעות מחוץ לחיתוך של שני העיגולים:
</p>
End of explanation
"""


ninja_turtles_characters.add("April O'Neil")
print(ninja_turtles_characters)

"""
Explanation: <div class="align-center" style="display: flex; text-align: right; direction: rtl; clear: both;">
    <div style="display: flex; width: 10%; float: right; clear: both;">
        <img src="images/exercise.svg" style="height: 50px !important;" alt="תרגול"> 
    </div>
    <div style="width: 70%">
        <p style="text-align: right; direction: rtl; float: right; clear: both;">
            צרו קבוצה שאיבריה הם 10 <a href="https://he.wikipedia.org/wiki/%D7%A1%D7%93%D7%A8%D7%AA_%D7%A4%D7%99%D7%91%D7%95%D7%A0%D7%90%D7%A6%27%D7%99">מספרי פיבונאצ'י</a> הראשונים, וקבוצה נוספת שאיבריה הם המספרים הזוגיים בין 1 ל־15.<br>
            שרטטו דיאגרמת ון של שתי הקבוצות, ובדקו שהשרטוט נאמן למציאות בעזרת הפעולות שלמדתם למעלה.
        </p>
    </div>
</div>

<span style="text-align: right; direction: rtl; float: right; clear: both;">תרגיל ביניים: נענועי חנית כנגד קוף</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    בתיקיית resources נמצאים הקבצים hamlet.txt ו־the-monkeys-paw.txt.<br>
    כמה מילים משותפות לשני החיבורים? כמה שונות?<br>
    כמה מהמילים מופיעות רק בכפת הקוף, וכמה רק בהמלט?
</p>

<span style="text-align: right; direction: rtl; float: right; clear: both;">עריכת קבוצה</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    קבוצה היא mutable – אפשר לערוך אותה מבלי ליצור קבוצה חדשה, בדומה לרשימות או למילונים.<br>
    תכונה זו מאפשרת לנו לצרף לקבוצה איברים חדשים או להסיר ממנה איברים קיימים בקלות רבה.
</p>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    נוסיף לקבוצת שמות הדמויות בצבי הנינג'ה את אפריל או'ניל באמצעות הפעולה <code>add</code>:
</p>
End of explanation
"""


ninja_turtles_characters.remove("Shredder")
print(ninja_turtles_characters)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    ונמחק מהקבוצה את שרדר הרשע באמצעות הפעולה <code>remove</code>:
</p>
End of explanation
"""


ninja_turtles_characters.remove("Krang")

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    שימו לב שניסיון למחוק ערך שלא קיים בקבוצה יכעיס את פייתון:
</p>
End of explanation
"""


ninja_turtles_characters.discard("Krang")
print(ninja_turtles_characters)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אלא אם כן נשתמש בפעולה <code>discard</code>, שמאפשרת לנו למחוק איברים מקבוצות, בלי לחשוש משגיאה:
</p>
End of explanation
"""


foot_clan_members = {'Shredder', 'Krang', 'Karai'}
ninja_turtles_characters.update(foot_clan_members)
print(ninja_turtles_characters)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    ולסיום – הדמויות הרעות תמיד חוזרות לסיבוב שני.<br>
    נרחיב את הקבוצה שלנו ונוסיף אליה את הנבלים מ"שבט הרגל" (בחיי, ככה הם תרגמו את Foot Clan!) במכה אחת, באמצעות הפעולה <code>update</code>:
</p>
End of explanation
"""


only_turtles = {'Donatelo', 'Raphael', 'Michelangelo', 'Leonardo'}

'Donatelo' in only_turtles

"""
Explanation: <div class="align-center" style="display: flex; text-align: right; direction: rtl; clear: both;">
    <div style="display: flex; width: 10%; float: right; clear: both;">
        <img src="images/exercise.svg" style="height: 50px !important;" alt="תרגול"> 
    </div>
    <div style="width: 70%">
        <p style="text-align: right; direction: rtl; float: right; clear: both;">
            צרו קבוצה של 100 המספרים הראשוניים הראשונים, וצרפו אליה את כל המספרים הזוגיים בין 1 ל־1,000.<br>
            צרו קבוצה נוספת של המספרים בין 1 ל־1,000 שסכום ספרותיהם קטן מ־4.<br>
            כמה מספרים משותפים לשתי הקבוצות שיצרתם?
        </p>
    </div>
</div>

<span style="text-align: right; direction: rtl; float: right; clear: both;">בדיקות שייכות</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    אחת התכונות המועילות ביותר של קבוצות היא שאפשר לבצע בעזרתן בדיקות שייכות במהירות רבה.<br>
    בדיוק כמו חיפוש מפתח במילון, בקבוצה אפשר למצוא ערך בתוך זמן קצר מאוד.
</p>
End of explanation
"""


print(italian_artists)

only_turtles.issubset(italian_artists)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    אפשר גם לבדוק אם כל האיברים של קבוצה אחת נמצאים בתוך קבוצה אחרת:
</p>
End of explanation
"""


italian_artists.issuperset(only_turtles)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    ולהפך – אם קבוצה מסוימת מכילה את כל איברי הקבוצה השנייה:
</p>
End of explanation
"""


italian_artists.intersection(ninja_turtles_characters)

"""
Explanation: <figure>
    <img src="images/venn2.svg" style="max-width: 400px; margin-right: auto; margin-left: auto; text-align: center;" alt="בתמונה מופיעים שני עיגולים: עיגול טורקיז גדול, מעליו מופיע הכיתוב 'אומנים איטלקים', ובתוכו עיגול חום קטן, מעליו מופיע הכיתוב 'שמות הצבים'. בעיגול החום נמצאים Donatelo, Leonardo, Michelangelo ו־Raphael, ובעיגול הטורקיז Giotto, Masacccio ו־Titian."/>
    <figcaption style="margin-top: 2rem; text-align: center; direction: rtl;">דיאגרמת ון שמדגימה ששמות צבי הנינג'ה הם תת־קבוצה של אומנים איטלקים.<br>
    אפשר לראות ששטח העיגול של הצבים "נבלע" בשטח העיגול של האומנים האיטלקים.</figcaption>
</figure>

<span style="text-align: right; direction: rtl; float: right; clear: both;">תרגיל ביניים: מהיר ואמין</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    בקובץ words.txt ישנה רשימת מילים ארוכה מאוד.<br>
</p>

<ol style="text-align: right; direction: rtl; float: right; clear: both;">
    <li>בנו רשימה בשם <var>words_list</var> מכל המילים המופיעות בקובץ.</li>
    <li>בנו קבוצה בשם <var>words_set</var> מכל המילים המופיעות בקובץ.</li>
    <li>בנו פונקציה בשם <var>average_runtime</var> למדידת ביצועים, שתעזור לכם להחליט מה מהיר יותר:
        <ol>
            <li>חפשו 1,000 פעמים את המילה zwitterion בכל אחד ממבני הנתונים שיצרתם.</li>
            <li>הפונקציה תחזיר את הזמן ההמוצע שנמשך החיפוש במבנה הנתונים.</li>
        </ol>
    </li>
</ol>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    כמה זמן בממוצע נמשך חיפוש המילה ברשימה? ובקבוצה?<br>
    רמז: <span style='background: black;'>השתמשו במודול <var>time</var>.</span>
</p>

<span style="text-align: right; direction: rtl; float: right; clear: both;">אופרטורים בין קבוצות</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    לעיתים יהיה לנו נוח יותר להשתמש באופרטורים במקום בפעולות.<br>
    לדוגמה, הפעולה של חיתוך בין שמות הדמויות בצבי הנינג'ה לשמות האומנים האיטלקים שנעשתה כך:
</p>
End of explanation
"""


italian_artists & ninja_turtles_characters

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    יכולה להיעשות גם כך:
</p>
End of explanation
"""


primes = {2, 3, 5, 7}
primes_to_add = {11, 13, 17, 19}
primes.update(primes_to_add)
print(primes)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    השימוש באופרטורים בין קבוצות יכול לקצר את הכתיבה ולשוות לה מראה נקי יותר.<br>
    ריכזנו עבורכם אופרטורים שבהם משתמשים תדיר כשעובדים עם קבוצות:
</p>

<table style="text-align: right; direction: rtl; clear: both; font-size: 1.3rem">
    <caption style="text-align: center; direction: rtl; clear: both; font-size: 2rem; padding-bottom: 2rem;">אופרטורים בין קבוצות</caption>
    <thead>
        <tr>
            <th>שם פעולה</th>
            <th>שם הפעולה בפייתון</th>
            <th>אופרטור</th>
            <th>דוגמה</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>איחוד</td>
            <td>union</td>
            <td><code>|</code></td>
            <td><code dir="ltr">{1, 3, 5} | {1, 2, 3}</code> מחזיר <code dir="ltr">{1, 2, 3, 5}</code></td>
        </tr>
        <tr>
            <td>חיתוך</td>
            <td>intersection</td>
            <td><code>&</code></td>
            <td><code dir="ltr">{1, 3, 5} & {1, 2, 3}</code> מחזיר <code dir="ltr">{1, 3}</code></td>
        </tr>
        <tr>
            <td>הפרש</td>
            <td>difference</td>
            <td><code>-</code></td>
            <td>
                <code dir="ltr">{1, 3, 5} - {1, 2, 3}</code> מחזיר <code dir="ltr">{5}</code><br>
                <code dir="ltr">{1, 2, 3} - {1, 3, 5}</code> מחזיר <code dir="ltr">{2}</code>
            </td>
        </tr>
        <tr>
            <td>הפרש סימטרי</td>
            <td>symmetric_difference</td>
            <td><code>^</code></td>
            <td><code dir="ltr">{1, 2, 3} ^ {1, 3, 5}</code> מחזיר <code dir="ltr">{2, 5}</code></td>
        </tr>
        <tr>
            <td>בדיקת שייכות/הכלה</td>
            <td>issubset/issuperset</td>
            <td><code dir="ltr">&lt;=</code></td>
            <td>
                <code dir="ltr">{1, 2, 3} &lt;= {1, 3, 5}</code> מחזיר <code>False</code><br>
                <code dir="ltr">{1, 2, 3} &lt;= {1, 2, 3, 4, 5}</code> מחזיר <code>True</code>
            </td>
        </tr>
    </tbody>
</table>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    שימו לב לכך שאופרטורים בין קבוצות לרוב יוצרים קבוצה חדשה.<br>
    במקרה שאנחנו יכולים לשנות קבוצה קיימת ולנצל את היותה של קבוצה mutable, נעדיף לבחור בדרך הפעולה הזו כדי לייעל את התוכנית שלנו.<br>
</p>

<p style="text-align: right; direction: rtl; float: right; clear: both;">
    כך, לדוגמה, הוספת איברים לקבוצה בצורה הזו:
</p>
End of explanation
"""


primes = {2, 3, 5, 7}
primes_to_add = {11, 13, 17, 19}
primes = primes | primes_to_add
print(primes)

"""
Explanation: <p style="text-align: right; direction: rtl; float: right; clear: both;">
    עדיפה על הצורה הזו:
</p>
End of explanation
"""


import os


def get_filenames(path):
    for file in os.scandir(path):
        yield file.name


def common_filenames(path1, path2):
    path1_files = set(get_filenames(path1))
    path2_files = set(get_filenames(path2))
    return path1_files & path2_files


common_filenames('images', 'resources/week05_images')

"""
Explanation: <span style="text-align: right; direction: rtl; float: right; clear: both;">תרגיל לדוגמה</span>
<p style="text-align: right; direction: rtl; float: right; clear: both;">
    כתבו פונקציה שמקבלת נתיב ל־2 תיקיות, ומחזירה שמות של קבצים שמופיעים בשתי התיקיות.
</p>
End of explanation
"""


