סדנאת פייתון לפיזיקאים

בקרת זרימה

שליטה בסדר ביצוע התוכנית: תנאים ולולאות

הפקולטה לפיזיקה, הטכניון. חורף 2013

מרצה: רונן אברבנאל

תנאים

if/elif/else

In [1]:
if 2**2 == 4:
    print "well, clearly"
well, clearly

זו הדוגמה הראשונה שראינו לבלוקים

כדי להראות שקוד "שייך" לקוד אחר, משתמשים בסוגריים מסלוסלים:

if (2==3-1)
{
    pritnf("it's right!")
}

בפייתון, משתמשים בהזחות ("טאב", indentation) כדי לעשות את אותו הדבר:

In [93]:
a = 10

if a == 1:
    print 1
elif a == 2:
    print 2
else:
    print 'A lot' 
A lot

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

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

כל מספר שונה של רווחים/ טאבים הוא בלוק שונה. שימו לב לא לבלבל את מספר הרווחים.

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

In [4]:
a = 30
if a%5 == 0:
    if a%2 == 0:
        print "a is divided by 10!"
    print "a is divides by 5!"
a is divided by 10!
a is divides by 5!

כאשר יש קוד עם הזחות שונות אבל בלי פתיחה של בלוק חדש (עם נקודותיים), יש צרות,

In [94]:
if 3==4:
    print "no way!"
      print "maybe yes?"
  File "<ipython-input-94-7a4f0bbf1ece>", line 3
    print "maybe yes?"
    ^
IndentationError: unexpected indent

לולאות for

ב-C, לולאות for עוברות על משתנה ומבצעות פעולה עבור כל ערך שלו:

for (int i=0; i<10; i++)
{
   printf("my i is %d" , i)
}

בפייתון, לולאות עוברות על רשימה

In [1]:
range(1,8,2)
Out[1]:
[1, 3, 5, 7]
In [7]:
for i in range(1,8,2):
    print "my i is %d" % i
my i is 1
my i is 3
my i is 5
my i is 7

הפקודה range יוצרת רשימת מספרים, מאפס ועד המספר הנדרש. לפעמים, נחמד לסרוק רשימות אחרות,

In [98]:
for word in ('cool', 'powerful', 'readable'):
    print('Python is %s' % word)
Python is cool
Python is powerful
Python is readable

לולאות while

מתבצעת עד שמתקיים תנאי מסויים

In [1]:
z = 1+1j
while abs(z) < 100:
    z = z**2 +1 
z
Out[1]:
(-134+352j)

אפשר לעצות לולאות באמצע באמצעות break

In [6]:
a = 2.1
while a < 100:
    a *= -1.1
    if a < -100: 
        print "braking"
        break
    a * 3
print a
braking
-104.548880362

או לדלג על ביצוע "מחזור" מסויים של הלולאה באמצעות continue

In [3]:
a = [1,0,2,4]
for element in a:
    if element  == 0:
        continue
    print 1. / element
1.0
0.5
0.25

הבנת רשימות

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

פייתון מציע צורה פשוטה למדי לעשות פעולות כאלו בשורה אחת, List Comprehensions:

In [9]:
L = range(10)
[item * 2 for item in L if item%2==1]
Out[9]:
[2, 6, 10, 14, 18]

כדי להבין מה הולך כאן, נחלק ל-3 חלקים שכל אחד מהם יכול לבוא בנפרד

In [10]:
[item for item in L]
Out[10]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

עבור כל אחד מהאיברים ברשימה L, החזר את האיבר כמו שהוא, לרשימה חדשה.

אבל אין צורך להחזיר אותו כמו שהוא

In [11]:
[item * 2 for item in L]
Out[11]:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
In [12]:
["a number %d" % item for item in L]
Out[12]:
['a number 0',
 'a number 1',
 'a number 2',
 'a number 3',
 'a number 4',
 'a number 5',
 'a number 6',
 'a number 7',
 'a number 8',
 'a number 9']

אפשר לבצע כל קוד פייתון (ש"יפה" להכניס למקום כל כך צר) או לקרוא לכל פונקציה שהיא עבור כל אחד מאברי הרשימה.

כמו כן, אין צורך לבצע את הפעולה על כל האיברים. ניתן לבדוק אם תנאי מסויים מתקיים, ולבצע את הפעולה רק אם הוא אכן מתקיים:

In [13]:
[item for item in L if item> 3]
Out[13]:
[4, 5, 6, 7, 8, 9]
In [15]:
[item for item in L if item%3 == 0]
Out[15]:
[0, 3, 6, 9]

וכמובן, לשלב, כמו בדוגמה הראשונה.

In [16]:
L2 = ["Physics", "Math", "EE", "ME", "Biology", "Medicin"]
["%s starts with 'M'" % elem for elem in L2 if elem.startswith("M")]
Out[16]:
["Math starts with 'M'", "ME starts with 'M'", "Medicin starts with 'M'"]

תרגילון

ניתן לבצע את התרגילים הן במפענח והן בקובץ נפרד

  1. כתבו לולאה המדפיסה את כל המספרים בין 1 ל-10
  1. צרו רשימה המכילה את כל המספרים מ-10 עד 20