מפענח הצפנים - צריך עזרה עם התרגיל גפ שנה אחרי

שלום! יודע שעברו שנים מאז התרגיל, חזרתי לאחורה קצת כדי לחזור על הקורס מחדש כי התעורר בי חשק לשחק עם פייתון.
התרגיל הזה שובר אותי כל פעם מחדש.
אני יודע שבהמשך, עם לולאות והכל, הוא הופך להרבה יותר פשוט - אבל עכשיו, יש כל מיני דברים שאני פשוט לא מצליח. דברים קטנים ומעצבנים.

האם יש אפשרות להסבר מפורט ומלא לפתירת התרגיל? איזה פונקציות עליי ליצור?

יש לי פונקציה שמחזירה לי כמה מספרים נכונים.

אני חושב שמה שאני מסתבך איתו יותר מהכל זה ההבנה של איך קוראים לפונקציות בתוך פונקציות אחרות? אם אני מגדיר פונקציה מסוימת כמשהו, לדוגמה:
def func() = love

האם love קורא לפונקציה או רק מצביע על מה שהפונקציה מחזירה? אבל איך הפונקציה מחזירה משהו?
בקיצור אני שואל איך אני קורא לפונקציה ששואלת מה הסיסמא הנכונה 3 פעמים בלי לולאות וכ’ו.

תודה!

לייק 1

זה מצוין שזה לא קל, כי זה בהחלט יעזור לך לבסס את ההבנה בכל מה שקשור בפונקציות – ויהפוך את החומר שעתיד לבוא לפחות קשה.

בוא נתחיל מההתחלה :slight_smile:

  1. איך תגדיר פונקציה שמקבלת שני פרמטרים ומחזירה את הסכום שלהם?
  2. איך תקרא לה מתוך התוכנית הראשית עם הפרמטרים 2 ו¯3, כך שתחזיר 5?
  3. איך תחשב את התרגיל 1 ועוד 2 ועוד 3 בעזרת הפונקציה הזו?

רשום כאן את הפתרונות ונתקדם הלאה (:

3 לייקים
  1. def func(a,b)
    Return a+b

  2. Func(2,3)

  3. Func(2,3) + 1. (?)

זה כתוב מאוד לא מקצועי ולא אסתטי אבל זה בגדול, לא?
יכול להיות ששכחתי להמיר לint אבל זכור לי שפונקציה לא בהכרח מחזירה str כמו input

יש לך גישה למחשב? בגדול אתה צודק - אבל אשמח אם כחלק מהפינג פונג שנעשה בימים הקרובים תשקיע זמן בלבדוק את הקוד שכתבת לפני שאתה שולח אותו כאן :slight_smile:

יש לך רעיון לאיך לפתור את 3 בלי להשתמש בסימן +, כלומר, רק בעזרת func?

כן. מתנצל על מקודם, מעכשיו אענה רק מלפטופ לאחר בדיקה.

def func(a,b):
number = a + b
number = number + a + b
return number

print(func(1,2))

בטוח יש עוד המון דרכים אבל אולי אני לא מספיק מפוקס על לאיזה דרך לנסות להגיע.
עדיין יש שם + פשוט השארתי אותו בתוך הפונקציה. וגם שיניתי את הפונקציה. האם הכוונה היא להשתמש בדיוק באותה פונקציה פשוטה של a + b ואיכשהו להכניס 3 מספרים?

def func(a,b):
number = a + b
return a + b

func(func(1,2), 3)

חשבתי גם על זה

מצוין! האופציה השנייה באמת מצוינת, ומאפשרת לך לחבר 3 מספרים שונים.

יצרת ״מתכון״ פשוט שמחבר שני מספרים, ואז השתמשת בו פעמיים כדי לפתור בעיה מורכבת יותר.

  1. הגדרת פונקציה של חיבור בין שני מספרים – נקרא לה add, לדוגמה.
  2. קראת לה פעמיים כדי לבצע את ה״מתכון״ שהיא מציעה פעמיים.
  3. הדפסת את הערך שחזר מהפונקציה. (בפתרון הראשון, אבל ודאי התכוונת לעשות את זה גם בפתרון השני :slight_smile: )

עכשיו, כשאנחנו סגורים שאנחנו באותו דף לגבי הגדרת פונקציות, בוא ניגש לאזורים קרובים יותר למה ששאלת:

  1. תגדיר פונקציה אחרת, שנקראת increment. הפונקציה תקבל מספר ותחזיר אותו אחרי שהוספת לו 1. כלומר, עבור 5 היא תחזיר 6, עבור 6 היא תחזיר 7 וכך הלאה.
  2. אני בטוח שבהינתן ההצלחה שלך בתרגיל הקודם זה היה קל. בשביל התרגול – תוכל לחשוב על דרך שהמימוש של increment ישתמש במימוש של פונקציית החיבור שיצרת לפני כן (add)? כלומר; בתוך גוף הפונקציה increment לא יופיע הסימן +.

def add(a,b):
number = a + b
return number

def increment(n):
n = add(n, 1)
return n

print(increment(5))

זה מגניב

מעולה.

יצרת שתי פונקציות שונות, אחת “בסיסית” והשנייה שמסתמכת עליה.
באחת הפונקציות השתמשת בפונקציה השנייה.
זה בערך כמו שבמתכון לפסטה עשויים להפנות אותי למתכון לרוטב רוזה – רוטב הרוזה מצריך הכנה נפרדת אבל הוא חלק מהתוצאה הסופית שאליה אני רוצה להגיע (פסטה טעימה).

זה מביא אותנו לצורך לפתח את היכולת של לקחת משימה, ולחלק אותה לפונקציות (תהליכים קטנים שמרכיבים אותה).
ברגע שתסתכל על משימה (או תרגיל, במקרה שלנו) ותדע לפרק אותה לפונקציות – החיים שלך יהיו משמעותית קלים יותר.
חלוקה לפונקציות גם עושה סדר בראש, מקלה על ניהול הקוד בעתיד ומפשטת לנו את הקוד.

ניקח תרגיל לדוגמה:

במשחק קופסה פופולרי, דמות מתחילה ברמה 0 ועולה רמה כל 50 נקודות ניסיון. כשהדמות מגיעה לרמה 10 המשחק נהיה קשה יותר עבורה, והיא מתחילה לעלות רמה כל 100 נקודות ניסיון.
כלומר: כשיש לדמות 500 נקודות ניסיון היא מקודמת לרמה 10. היא תקודם לרמה 11 רק כשיהיו לה 600 נקודות ניסיון.

דוגמאות:

  1. עבור 350 נקודות ניסיון, רמת הדמות היא \dfrac{350}{50}, כלומר 7.
  2. עבור 275 נקודות ניסיון, רמת הדמות היא \dfrac{275}{50} מעוגל כלפי מטה, כלומר 5.
  3. עבור 751 נקודות ניסיון, רמת הדמות היא {\dfrac{(751 - 500)}{100}} + 10, מעוגל כלפי מטה, כלומר 12. (הנוסחה עבור מספר נקודות ניסיון מ¯500 ומעלה היא {\dfrac{(N - 500)}{100}} + 10, כש־ N הוא מספר נקודות הניסיון).

ידוע גם שכל דמות יכולה לסחוב כמות חפצים השווה לחצי מרמתה, כאשר החצי מעוגל כלפי מעלה: כלומר דמות ברמה 5 יכולה לסחוב 3 חפצים, כך גם דמות ברמה 6, אבל דמות ברמה 31 יכולה לסחוב 16 חפצים! (דמויות ברמה 0 לא יכולות לסחוב איתן חפצים, כמובן).

  1. קח דף ועט, ונסה להבין כמה חפצים יכולה לסחוב דמות עם 1337 נקודות ניסיון. (יצא לך 9?)
  2. אם היית צריך לחלק את תרגיל 1 לכמה שיותר “שלבים”, כמה “שלבים” שונים היית מגדיר? מה הם?
  3. ממש תוכנית שמקבלת כקלט מספר נקודות ניסיון, ומחזירה כמה חפצים הדמות יכולה לסחוב. נסה שהפונקציות שתיצור יקבילו לשלבים שתיארת בשאלה 2.
  4. אם תנסה ממש, תוכל לפרק את הקוד לאפילו יותר פונקציות. אחת לדוגמה היא פונקציה שמקבלת מספר ומעגלת אותו כלפי מעלה. יכול לחשוב על עוד פונקציה שתוכל להוציא מהקוד שלך?
  5. אחרי שכתבת את הפונקציה, אני אגיד לך שיש מצב מיוחד למשחק שבו אפשר לשחק ביחד כקבוצה (co-op) של שלושה אנשים. במצב כזה, כמות החפצים שאפשר לסחוב היא חצי מסכום הרמות של כולם מעוגל כלפי מעלה. האם, בהינתן הצורה שבה תיכננת את הקוד בסעיף 3/4, תוכל לכתוב קוד שמקבל את נקודות הניסיון של כל אחד מ¯3 השחקנים ומדפיס כמה חפצים הם יכולים לסחוב יחדיו?
2 לייקים
  1. אכן יצא 9
  2. ניסיתי לחלק לכמה שיותר “שלבים” אבל בגדול מה שצריך זה לחשב את הרמה, ודרך הרמה לחשב כמה חפצים יכול המשתמש לשאת.
  3. מימשתי את התוכנית בכמה שיותר פונקציות, והגעתי ל4. אכן שמחשבת את הרמה של המשתמש מתחת ל500 נקודות ניסיון, השנייה מעל 500 נקודות ניסיון. השלישית נותנת לי את הרמה בשילוב של שתיהן, זאת אומרת אני משתמש רק בה כדי לחשב את הרמה והיא פונה לאחת מהן. הרביעית היא כמה הגיבור יכול לשאת דרך חישוב הרמה. הנה התוכנית:

def level_ten(exp):
lvl = exp // 50
return lvl

def level_ten_up(exp):
lvl = ((exp - 500) // 100) + 10
return lvl

def what_level(exp):
if exp <= 500:
lvl = level_ten(exp)
elif exp > 500:
lvl = level_ten_up(exp)
return lvl

def carry(level):
if level % 2 == 1:
items = level // 2 + 1
else:
items = level // 2
return items

print(carry(what_level(1337)))

  1. כאן אני לא בטוח, האם לא הוצאתי כבר כל דבר אפשרי מהפונקציות? אני יכול לחשוב על פונקציה שאולי אומרת לי בהינתן מספר מסוים אם הוא מעל 500 או פחות מ500 למרות שזה קצת מטופש… או את האופציה לפצל את carry לשתי פונקציות שונות, אחת במקרה של מספר זוגי ואחת במקרה של מספר אי זוגי. במקרה של אי זוגי היא תחשב חלקי שניים ותעגל למעלה.

  2. אוקיי! וואו! אני חושב שהצלחתי. אני לא בטוח אם זה מה שביקשת כי כתבת “סכום הרמות של כולם מעוגל כלפי מעלה”, אבל במידה ואלו הן רק רמות זה תמיד מעוגל כלפי מעלה… לא? אז הנחתי שהתכוונת שוב שזה חצי מסכום רמתם מעוגל כלפי מעלה. במידה וזה היה סכום הרמות שלהם = כמות החפצים שהם יכולים לסחוב, אתקן. אבל בגדול זה מה שיצא לי (אחרי הפונקציות של 3.)

def co_op():
user_1 = input("EXP of first user: ")
a = what_level(int(user_1))
user_2 = input("EXP of second user: ")
b = what_level(int(user_2))
user_3 = input("EXP of third user: ")
c = what_level(int(user_3))

total_carry = carry(a + b + c)
return total_carry

print(co_op())

הכוונה הייתה לחצי מסכום הרמות של כולם מעוגל כלפי מעלה (ערכתי), אבל כן בגדול :slight_smile:
מגניב, נראה טוב! עבודה מצוינת עד עכשיו.

מצליח לדמיין איך היית פותר עכשיו את מפענח הצפנים?

אני בטוח שיש כמה דרכים לשפר את זה, ואולי לפצל לעוד כמה פונקציות… אבל בגדול - כן, אני חושב שהצלחתי.

מצוין, איזה כיף!

ראיתי את הקוד ומחקתי אותו כי אני מעדיף שלא יסתובבו פתרונות של תרגילים מהמחברת –
זה גורם לאנשים לדלג על התרגיל ולהסתכל בפתרון במקום לעשות את התהליך שעשינו עכשיו :slight_smile:

בהצלחה בהמשך

לייק 1

ים, תודה ענקית. ממש לא מובן מאליו. הקורס נגמר מזמן והייתי בספק אם מישהו בכלל יגיב לי והדרך שבה אתה מעביר את החומר היא אידאלית.

11 לייקים

@Yam
אני חוזר על החומר גם ואני פשוט נהנה לקרוא את ההדרכה שאתה מעניק.
קראתי שיש דיבור על הורדת האתר , ורציתי להציע לארח אותו על שרת שיש לי -ללא תמורה.
אשמח אם תיצור איתי קשר

בברכה
רן

2 לייקים