Python Functions: Biological Exercises in Hebrew
yuval bloch
🧬 תרגיל 5 - פוקציות
🛠️ הנחיות כלליות:
-
כדי לנסות את הפונקציות הריצו אתן אם קלטים שונים, במקרים מסוימים אני נותן לכם דוגמא לקלט, אל תספקו בה אלא הוסיפו קלטים משלכם כולל מקרי קצה (קלט לא תקין מחרוזת ריקה ואחרים)
-
יש להוסיף תיעוד באנגלית (
docstring
) בראש כל פונקציה, שמסביר בקצרה את מטרתה, הקלט והפלט. -
במקרה של קלט לא תקין, יש להדפיס הודעת שגיאה ולהחזיר ערך מתאים.
-
יש להימנע מחזרה על קוד - אם אתם מבצעים את אותה פעולה בפונקציות שונות צרו פונקציה נוספת וקיראו לה מתו הפונקציות השונות
-
שימו לב שהסעיפים המאוחרים משתמשים בפונצקיות מהסעיפים המקודמים הקפידו על עבודה מדוייקת בהתחלה אחרת זה יתנקם בכם בהמשך
שאלה 1: דינמיקה של אוכלוסיית איילים בפארק ילוסטון
עבור בעלי חיים כמו איילים, עונת הרבייה מתרחשת בעיקר באביב, בעוד שרוב התמותה קורית בחורף. מינים כאלו ניתן לתאר באמצעות מודל מבוסס אירועים:
-
אירוע רבייה (אביב) – האוכלוסייה גדלה.
-
אירוע תמותה (חורף) – האוכלוסייה קטנה.
הערות כלליות
-
הקפידו על עיגול תוצאות למספרים שלמים עיגול מתרחש כלפי מטה.
-
דאגו שתמיד גודל האוכלוסייה לא ירד מתחת ל-0. מספרים שלילים יהפכו ל0
-
הוסיפו הדפסות שמבהירות מה קורה בכל שנה (שנה, גודל אוכלוסיית איילים, גודל אוכלוסיית זאבים).
סעיף 1.1: פונקציית תמותה
כתבו פונקציה בשם death
שמקבלת שני פרמטרים:
-
N
– גודל האוכלוסייה -
death_rate
– שיעור התמותה
הפונקציה תחזיר מספר שלם וחיובי המחושב לפי הנוסחה:
N - N * death_rate
אם התוצאה שלילית – יש להחזיר 0
. יש לעגל את התוצאה למטה.
סעיף 1.2: פונקציית רבייה
כתבו פונקציה בשם birth
שמבצעת פעולה דומה, אך לפי הנוסחה:
N + N * birth_rate
גם כאן יש לעגל את התוצאה למטה.
סעיף 1.3: שלב סימולציה בודד
כתבו פונקציה בשם simulation_step
שמקבלת את הפרמטרים:
-
N
– גודל אוכלוסייה -
birth_rate
– שיעור ריבוי -
death_rate
– שיעור תמותה
הפונקציה תבצע קודם רבייה ואז תמותה, ותחזיר את גודל האוכלוסייה הסופי לאחר שני האירועים.
סעיף 1.4: ריצת סימולציה
כתבו פונקציה בשם simulation
שמקבלת את הפרמטרים:
-
N
– גודל אוכלוסייה התחלתי -
birth_rate
– שיעור ריבוי -
death_rate
– שיעור תמותה -
years
– מספר השנים להריץ
הפונקציה תריץ לולאה למשך מספר השנים, ובכל שנה:
-
תבצע שלב סימולציה אחד (
simulation_step
). -
תדפיס את השנה הנוכחית וגודל האוכלוסייה.
סעיף 1.5: חקירת התנהגות הדינמיקה
הריצו את הסימולציה מספר פעמים עם ערכים שונים של birth_rate
ו-death_rate
.
שימו לב:
-
אם קצב התמותה גבוה מקצב הריבוי – האוכלוסייה תיכחד.
-
אם קצב התמותה נמוך מקצב הריבוי – האוכלוסייה תגדל ללא גבול.
זוהי דינמיקה לא טבעית. כדי לדמות את הטבע, נוסיף השפעה של תחרות על משאבים.
שאלה 2: תחרות וטורפים
סעיף 2.1: השפעת התחרות
כתבו פונקציה בשם competition
שמקבלת:
-
N
– גודל אוכלוסייה -
K
– קיבולת נשיאה (מספר בעלי חיים שהשטח יכול להכיל) -
competition_rate
– קצב השפעת התחרות
הפונקציה תחזיר את ערך התחרות לפי הנוסחה:
competition_rate * N * (N / K)
הוסיפו את חישוב התחרות כשלב שלישי לכל צעד של הסימולציה (simulation_step
), והריצו סימולציות שונות.
שימו לב שיש לשנות גם את פונקציית הסימולציה כך שתקבל ותעביר את הפרמטרים הנוספים
חקור: מתי האוכלוסייה נכחדת? מתי היא מתייצבת? מתי היא גדלה?
סעיף 2.2: הוספת זאבים
הוסיפו לסימולציה פרמטר חדש:
N_wolf
– מספר זאבים
בכל סיבוב יש להדפיס גם את מספר הזאבים.
סעיף 2.3: תמותת זאבים
כתבו פונקציה לעדכון אוכלוסיית הזאבים במהלך החורף, לפי הנוסחה:
N - predator_death_rate * N
(כאשר N
הוא מספר הזאבים ו-predator_death_rate
הוא שיעור תמותת הזאבים).
התאימו את פונקציית הסימולציה בהתאם.
סעיף 2.4: טריפה ורביית זאבים
בעונת הציד, זאבים מתרבים רק אם טרפו. כתבו חישוב טריפה ורבייה לפי:
- כמות טריפה:
predation = predation_rate * predator_population * (N / K)
- עדכון אוכלוסיית האיילים לאחר טריפה:
N = N - predation
- עדכון אוכלוסיית הזאבים לאחר רבייה:
predator_population = predator_population + (predation / 2)
השלימו את הסימולציה כך שתכיל גם טריפה, הריצו ובחנו את הדינימקה המתקבלת למשל עבור הפרמטרים
birth_rate = 0.5
death_rate = 0.2
comptition_rate = 0.1
generations = 100
k = 100
predator_death_rate = 0.1
predetion_rate =0.1
האוכלוסיה אמורה להתייצב על 27 איילים ו29 זאבים הריצו עם פרמטרים שונים
שאלה 3 סימולציה של התרבות חיידקים על פני רצועה צרה
🧠 רקע ביולוגי:
כאשר מושבת חיידקים מתפשטת בסביבה צרה כמו צינור דק, נים של צמח, או חריץ במצע גידול, התפשטות החיידקים מתבצעת בעיקר בכיוון אחד — שמאלה וימינה — כך שניתן לתאר אותה בצורה טובה כמרחב חד-ממדי.
ההתפשטות מתרחשת על ידי כך שתאים מתחלקים לאזורים שכנים. עם זאת, כאשר קצב ההתרבות גבוה מדי או קיים עומס תאי מקומי (תחרות חזקה), מתרחשת דעיכה — תאים לא מצליחים להיקלט באזורים עמוסים מדי.
במודל זה, חיידק חדש יופיע בתא ריק אם יש לו בדיוק שכן אחד חי, אך לא אם יש שניים (תחרות) או אפס (אין מקור).
🛠️ תיאור הסימולציה:
אתחיל מלתאר את הסימולציה כולה ולאחר מכן תוכלו לעבור סעיף ולראות כיצד לייצר אותה ממספר פונקציות קצרות
-
נייצג את את הרצועה כרשימה של מחרוזות בנות ספרה אחת (
" "
או"*"
):-
"*"
— חיידק חי. -
" "
— מקום ריק.
-
-
בכל דור:
-
חיידק מתרבה לתאים סמוכים (ימין ושמאל).
-
אם שני חיידקים מנסים להתרבות לאותו מקום, התחרות נכשלת — התא נשאר ריק.
-
חיידק חי חי דור אחד בלבד, כלומר אינו שורד לדור הבא — רק צאצאיו (אם נוצרו) ממשיכים.
-
סעיף 3.1: הדפסת מצב האוכלוסייה
כתבו פונקציה שמקבלת רשימה של תאים (רווחים וכוכביות) ומדפיסה אותם כמחרוזת רציפה, ללא תווים נוספים.
דוגמה:
קלט:
["*", "*", " ", "*"]
פלט במסך:
** *
סעיף 3.2 אתחול מצב התאים
כתבו פונקציה שמקבלת מספר של גודל רצועה, ויוצרת רשימה שאורכה כמספר הנתון.
-
הרשימה תהיה מלאה ברווחים
" "
. -
במיקום האמצעי (או אחד לפני אם המספר זוגי) יתווסף חיידק חי (
"*"
).
דוגמאות:
קלט:
5
פלט:
[" ", " ", "*", " ", " "]
קלט:
4
פלט:
[" ", "*", " ", " "]
סעיף 3.3 ספירת שכנים חיים
כתבו פונקציה שמקבלת רשימה ואינדקס של תא, ומחזירה את מספר החיידקים החיים בקרבתו (ימין ושמאל בלבד).
-
אם מדובר בתא הראשון — אין שכן שמאלה (נחשב ריק).
-
אם מדובר בתא האחרון — אין שכן מימין (נחשב ריק).
דוגמאות:
array = ["*", " ", "*"]
count_live_neighbors(array, 0)
# Output: 0
count_live_neighbors(array, 1)
# Output: 2
סעיף 3.4: חישוב הדור הבא
כתבו פונקציה שמקבלת את הרשימה הנוכחית ומחזירה רשימה חדשה:
-
עוברים על כל תא ריק:
-
אם יש לו בדיוק שכן אחד חי — התא יתמלא (יהפוך ל-"*").
-
אם יש לו אפס או שני שכנים חיים — התא יתרוקן (יהפוך ל ״ ״).
-
דוגמה:
קלט:
["*", " ", "*", " "]
פלט:
[" ", " ", " ", "*"]
סעיף 3.5: הרצת הסימולציה
כתבו פונקציה שמקבלת שני מספרים:
-
גודל הרצועה (מספר התאים).
-
מספר דורות להריץ.
הפונקציה תעשה את הדברים הבאים:
-
תאתחל את הרצועה עם חיידק אחד באמצע.
-
תדפיס את המצב בתחילת הסימולציה.
-
עבור כל דור:
-
תחשב את הדור הבא לפי הכללים.
-
תדפיס את המצב החדש.
-
📚 דוגמת הרצה:
קריאה לפונקציה לדוגמה:
simulate(50, 25)
פלט:
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * *
סעיף 3.6: דוגמאות נוספות
נסו לשנות את רשימה המקורית מה יקרא למשל אם נתחיל אם שני חיידקים חיים בשני הקצוות
העשרה (לא חובה)
המודל שבניתם מבוסס על הרעיון של אוטומט תאי חד-ממדי. אוטומטים מסוג זה פועלים לפי חוקים קבועים. לדוגמה, במודל שלכם תא יתמלא בסיבוב הבא אם ורק אם בדיוק אחד מהשכנים שלו מלא בסיבוב הנוכחי. חוק זה ידוע בשם חוק 90.
עם זאת, קיימים חוקים רבים נוספים — כל אחד מגדיר דפוס אחר של התנהגות. תוכלו למצוא דוגמאות מעניינות באתר הבא: (האתר באנגלית) https://mathworld.wolfram.com/ElementaryCellularAutomaton.html
חשבו: כיצד ניתן לקודד את החוקים השונים שמופיעים שם? אילו תופעות ביולוגיות אפשר לדמות בעזרתם?
אתגר למתקדמים במיוחד
כתבו פונקציה שמקבלת כקלט:
- מערכת חוקים של אוטומט תאי חד-ממדי בתור רשימה של קונפגרציות עבורן התא יהיה מלא בסיבוב הבא למשל חוק 90 יקודד כ
[[0,0,1] , [0,1,1] ,[1,0,0] , [1,1,0]]
- מצב התחלתי של התאים
הפונקציה תריץ סימולציה בהתאם לחוקים ותציג את התוצאה.