Thursday, June 11, 2015

თავი 3 (3,7 - 3,8)



3.7 Catching exceptions using try and except
3.7 გამონაკლის დაჭერა "ცდის" და "გამონაკლისის" გამოყენებით

ადრე ვნახეთ კოდის ნაწილი სადაც გამოვიყენეთ raw_input და int ფუნქციები, რომ წაეკითხა და გაესწორებინა მომხმარებლის მიერ შეყვანილი მთელი რიცხვები. ასევე ვნახეთ რაოდენ მუხანათური შეიძლება ეს იყოს:

>>> speed = raw_input(prompt)
What...is the airspeed velocity of an unladen swallow?
What do you mean, an African or a European swallow?
>>> int(speed)
ValueError: invalid literal for int()
>>> 

როცა ამ ანგარიშს ვახორციელებთ პითონის ინტერპრეტერში, გამოაქვს შეცდომის წერილი და შემდეგ  შევრონის პრომპტი.  ამ კოდს თუ ჩავსვამთ პითონის სკრიპტში და ეს შეცდომა მოხდება, სკრიპტი მაშინვე გაჩერდება in its tracks with a traceback.

აქაა ფარენჰაიტის  ცელსიუსში გადასაკონვერტირებელი მარტივი პროგრამა:

inp = raw_input('Enter Fahrenheit Temperature:')
fahr = float(inp)
cel = (fahr - 32.0) * 5.0 / 9.0
print cel

ამ კოდს თუ გავუშვებთ და შევიტანთ არამართებულ მონაცემს,  გამოიტანს  არამეგობრულ მესიჯს:

python fahren.py
Enter Fahrenheit Temperature:72
22.2222222222
python fahren.py
Enter Fahrenheit Temperature:fred
Traceback (most recent call last):
File "fahren.py", line 2, in <module>
fahr = float(inp)
ValueError: invalid literal for float(): fred

აქ არის პირობითი კავშირის განხორციელების სტრუქტურა (“try / except”) ჩაშენებული პითონში რომ „დაიჭიროს" ამ ტიპის მოსალოდნელი და მოულოდნელი შეცდომები. try და except -ის იდეა იმაშია, რომ იცი ზოგიერთ ინსტრუქციას შეიძლება ჰქონდეს პრობლემა და გინდა დაამატო სხვა პირობებიც იმ შემთხვევისთვის თუ შეცდომა მოხდება.  ეს დამატებითი პირობები დაიგნორდება შეცდომა თუ არ მოხდება.  try და except -ზე შეგიძლია იფიქრო როგორც "დაზღვევის პოლისზე”.
ტემპერატურის კონვერტერი შეგვიძლია დავწეროთ ასეც:

inp = raw_input('Enter Fahrenheit Temperature:')
try:
      fahr = float(inp)
      cel = (fahr - 32.0) * 5.0 / 9.0
      print cel
except:
      print 'Please enter a number'

პითონი იწყებს try ბლოკის ბრძანებების განხორციელებას. ყველაფერი თუ კარგა წავა, except ბლოკს გამოტოვებს. გამონაკლის თუ მოხდა try ბლოკში, პითონი გამოტოვებს ამ ბლოკს და განახორციელებს except ბლოკის ბრძანებებს.

python fahren2.py
Enter Fahrenheit Temperature:72
22.2222222222

python fahren2.py
Enter Fahrenheit Temperature:fred
Please enter a number

ამას ეძახიან გამონაკლისის დაჭერას try ბრძანების დახმარებით. ამ მაგალითში except ხაზი ბეჭდავს შეცდომის წერილს. საერთო ჯამში გამონაკლისის დაჭერა გაძლევს პრობლემის მოგვარების ან კიდევ ერთხელ ცდის, ანდაც პროგრამის ელეგანტურად დასრულების შანსს.

3.8 Short circuit evaluation of logical expressions

პითონი როცა ამუშავებს ლოგიკურ გამოსახულებას, როგორიცაა x >= 2 and (x/y) > 2, ანგარიშობს მარცხნიდან მარჯვნივ, and - ის განსაზღვრებიდან გამომდინარე თუ x ნაკლებია ორზე, გამოსახულება x >= 2 არის მცდარი ( False) ასე რომ მთლიანი გამოსახულებაც არის False მიუხედავად იმისა (x/y) > 2 მართალი იქნება თუ მცდარი (True თუ False.).
პითონი როცა აღმოაჩენს, რომ არაფერია სასარგებლო ლოგიკური გამოსახულების დანარჩენი ნაწილის გამოანგარიშებაში, ჩერდება და როცა ჩერდება, მაშინ გამოსახულების საბოლოო მნიშვნელობა უკვე ცნობილია. ამას ეძახიან short-circuiting (მოკლე ჩართვა). While this may seem like a fine point, the short circuit behavior leads to a clever technique called the guardian pattern.
განვიხილოთ შემდეგი კოდი:

>>> x = 6
>>> y = 2
>>> x >= 2 and (x/y) > 2
True
>>> x = 1
>>> y = 0
>>> x >= 2 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and (x/y) > 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> 


მესამე გამოთვლა მცდარია, იმიტომ რომ პითონი ანგარიშობდა (x / y) სადაც  y არის ნული, რამაც გამოიწვია შეცდომა შესრულებისას(runtime error). მაგრამ მეორე გამოთვლაში შეცდომას არ გვაჩვენებს, იმიტომ რომ  გამოსახულების პირველი ნაწილი მცდარია x >= 2 ამიტომ (x/y)  მოკლე ჩართვის წესის გამო არც დაუთვლია და შეცდომაც არ ამოაგდო.
შეგვიძლია ავაგოთ ლოგიკური გამოსახულება სტრატეგიულ ადგილას  (დაცვითი გამოთვლით)- სანამ გამოთვლაში შეცდომა მოხდება-როგორც აქ ხდება :

>>> x = 1
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x >= 2 and (x/y) > 2 and y != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> 

პირველ ლოგიკურ გამოსახულებაში x >= 2 არის მცდარი, ამიტომ გამოთვლა გაჩერდა and-თან. მეორე ლოგიკურ გამოსახულებაში x >= 2 არის  True , მაგრამ y != 0 is False ამიტომ (x/y) - დე გამოთვლა არ მიდის.
მესამე ლოგიკურ გამოსახულებაში y != 0 არის (x/y) - ის შემდეგ, ამიტომ გამოსახულება სრულდება შეცდომით.
მეორე გამოსახულებაში ვამბობთ  რომ y != 0 რაც მოქმედებს როგორც დაცვა, რათა დაზღვეული ვიყოთ, რომ შესრულდეს მარტო (x/y) თუ y არ არის ნული.