השוואת פיתרונות קורס Python

מה ערך ה index? וכמה איברים יש ברשימה?

כמו שכתבתי ,
יש 8 אברים שאמורים להיכנס לרשימה (בפועל נכנסים רק 7)
האינדקס האחרון (כלומר אינדקס 7 המכיל את המס’ 6-) לא נכנס
התכנית מפסיקה ונזרקת הודעת השגיאה דלעיל

בלי קשר , בעקבות ההערה שלך כתבתי את התכנית הבאה ע"י שימוש ב sys.stdin

import sys
import math

while True:
    number = sys.stdin.readline()
    if number == "":break
    try:
        print math.sqrt(float(number))
    except ValueError as e:
        print "Please enter numbers > 0 only"
        print e.message```

רק לא הבנתי למה התנאי הזה לא מתקיים אף פעם  

 if number == "":break

תרגיל 2 חריגים

import sys

path = r"C:\Python\files_3\\" + sys.argv[1]

try:
    with open (path,"r") as readline:
        count = [line for line in readline]
        print len(count)
except IOError as e:
    print "Sorry, the file %s is not exist" %(sys.argv[1])
    print e.message

אבל למה זה לא מדפיס את ה e.message ?

הי,

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

לגבי התנאי - הוא לא מתקיים כי שורה שקראת מ stdin היא אף פעם לא ריקה. היא תמיד מכילה תו מיוחד שנקרא ״תו ירידת שורה״ שמציין שהשורה הסתיימה וממשיכים לשורה הבאה.

לגבי השאלה האחרונה ב IOError אין שדה message ולכן צריך להדפיס את e עצמו:

import sys

path = r"C:\Python\files_3\\" + sys.argv[1]

try:
    with open (path,"r") as readline:
        count = [line for line in readline]
        print len(count)
except IOError as e:
    print "Sorry, the file %s is not exist" %(sys.argv[1])
    print e

תרגיל 3 חריגים

אני לא יודע אם אני בכלל בכיוון אבל אחרי שיטוטים וחיפושים עצמיים החלטתי לכתוב “משהו” ולראות איך להתקדם משם:
מה שאני מבין מהקוד שכתבת הוא שיש אובייקט img שמקבל שם תקין של קובץ ואמור לפתוח קובץ אא"כ הוא מקבל שם לא תקין ואז מופעלת הפונקציה InvalidImageExt שמפעילה את הפונקציה test_bad_ext שמייצרת assert ומסיימת את התוכנית.
הקיצר , התבלבלתי לגמרי :confused:

import unittest

class TestImageFile(unittest.TestCase):
    def __init__(self,name):
        self.name = r"C:\Python\Object_Oriented_7" + name
    def test_good_ext(self):
        try:
            img = ImageFile("file.png")
            open(self.name,"a")
        except InvalidImageExt:
            self.fail("png should be a valid file extension")

    def test_bad_ext(self):
        with self.assertRaises(InvalidImageExt):
            img = ImageFile("file.mp3")

    def InvalidImageExt(self):
        self.test_bad_ext()


if __name__ == '__main__':
    unittest.main()

באמת כדאי לקחת צעד אחורה.

כשאני מקליד את התרגיל המקורי ומפעיל אני מקבל את התוצאה:

======================================================================
ERROR: test_bad_ext (__main__.TestImageFile)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "b.py", line 11, in test_bad_ext
    with self.assertRaises(InvalidImageExt):
NameError: global name 'InvalidImageExt' is not defined

======================================================================
ERROR: test_good_ext (__main__.TestImageFile)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "b.py", line 7, in test_good_ext
    except InvalidImageExt:
NameError: global name 'InvalidImageExt' is not defined

----------------------------------------------------------------------
Ran 2 tests in 0.000s

הודעת השגיאה הרלוונטית מתוך כל הפלט הזה היא:

NameError: global name 'InvalidImageExt' is not defined

אז תתחיל משם- איפה משתמשים בשם InvalidImageExt? מה זה אומר לגביו?

  • מה שנראה לי הוא שמשתמשים בו כאשר שם הקובץ אינו תקין.
    מצד אחד כיון שהוא מתחיל באות גדולה הוא נראה לי כמו מחלקה נוספת המטפלת במצב חריג אך מצד שני קח למשל את השורה:
with self.assertRaises(InvalidImageExt):

זה נראה כמו קריאה לפונקציה ולא למחלקה

  • גם לא הבנתי את

("img = ImageFile("file.png

זה נראה כמו יצירת אוביקט בשם img אבל לאן בדיוק הארגומנט file.png הולך?
אין פה שום פונקציית __init__ שתקבל את הארגומנט הזה כמו שעשינו בתרגילים קודמים ?

  • האמת היא שאני לא רואה קריאה לאף פונקציה אז איך בכלל התוכנית עובדת?
    אבל זה כנראה טמון בשורה ()unittest.main

תבנית ההפעלה והקריאה לפונקציות כאן שונה מהרגיל (לפחות ממה שהכרתי עד עכשיו) ולכן מבלבלת

אני חושב שיותר נכון להגיד שזו מחלקה שעוברת בתור פרמטר לפונקציה sefl.assertRaises. בוא ננסה להסתכל על עוד קטע:

    def test_good_ext(self):
        try:
            img = ImageFile("file.png")
        except InvalidImageExt:
            self.fail("png should be a valid file extension")

כאן כבר ממש ברור מהשימוש אחרי המילה except שאכן יש לך עסק עם מחלקה שמייצגת Exception.

תמשיך מכאן ותתחיל לבנות את המחלקה הזו. מה הקוד המלא של מחלקה שאפשר לכתוב אחרי except כלומר מחלקה שמייצגת Exception?


אחרי זה באמת אפשר להמשיך לשורה השניה שלא הבנת:

img = ImageFile("file.png")

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

טוב, אז נתחיל מהשורה :except InvalidImageExt ונגדיר מחלקה בשם InvalidImageExt אשר תחזיר Exception למי שקרא לה כלומר ל except בפונקציה test_good_ext

class InvalidImageExt(error):
    self.error = error
    raise Exception("invalid image {}".format(self.error))

אבל עדיין לא ברור לי הפורמט.
מי בדיוק קורא לפונקציות בתוך המחלקה ImageFile?
אני לא רואה כאן שום קוד כזה…
ואותו דבר ביחס לפונקציה test_bad_ext גם לה אף אחד לא קורא ולא ברור לי מתי היא מתופעלת.
מישהו אמר לי שפורמט unittest הוא בכלל פורמט לבדיקת הקוד שלי והקוד נמצא במקום אחר. האם זה נכון? לא הבנתי את זה מהתרגיל !

טוב התחלתי מלבנות את המחלקות Imagefile ו InvalidImageExt (אשר ייעשה בה שימוש בבדיקות יחידה)
למה זה לא עובד לי ???
למה לא נפתח קובץ תמונה ??

import os

class Imagefile(object):
    def __init__(self, type):
        self.types = ["jpg", "png", "tif", "gif"]
        self.type = type
        self.file = ''
        self.path = r'C:\Python\Object_Oriented_7' + '\n' + self.type
        for self.suffix in self.types:
            if self.type.endswith(self.suffix):
                self.file = open(self.path,"r")
            else:
                raise InvalidImageExt(self.type)


class InvalidImageExt(Exception):

    def __init__(self, error):
        super(InvalidImageExt, self).__init__()
        self.error = error
        pass
      

img = Imagefile("file.jpg")

הי,

יש פה כמה בעיות, אבל לפני שאפשר יהיה להגיע אליהן כדאי לשפר את המבנה:

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

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

טוב , ניסיתי לשפר.
עד השורה return True זה עובד טוב (למרות שכשכתבתי להדפיס משהו במקום return True זה לא הדפיס אז אולי אני רק חושב שזה עובד טוב) ובכל מקרה לא קיבלתי errors כשהרצתי.
על כל פנים כשמגיעים לשורה אח"כ שאמורה לטפל בחריגים זה לא עובד.
תוכל להחכימני?

import os

class Imagefile(object):
    def __init__(self, type):
        self.types = ["jpg", "png", "tif", "gif"]
        self.type = type
        self.suffix = os.path.splitext(self.type[1])
        if self.suffix in self.types:
            return True
        else:
            raise InvalidImageExt("Wrong type{}".format(self.type))


class InvalidImageExt(Exception):
    def __init__(self, error):
        super(InvalidImageExt, self).__init__()
        self.error = error
        pass



img = Imagefile("file.jpg")

אני חושב שהקוד שלך לחישוב הסיומת שגוי. נסה להוסיף הודעות הדפסה כדי לראות מה שם הקובץ המלא שעובר ומה הסיומת שאתה מוצא (במשתנה self.suffix) ותראה שהסיומת שאתה מוצא היא לא הסיומת האמיתית של הקובץ.

אחרי זה תראה איך אתה מוצא את הסיומת הנכונה ותמשיך משם.

תלמידה שאלה לגבי הקוד הבא - מדוע מדי פעם הוא ״נעצר״ ומחכה לקלט פעם שניה לפני שמדפיס פידבק למשתמש:

"""
random anumber between 1-100, u have to guess the num
"""
import random
while True:
    print("do u wanna play?")
    if not input()=="YES":
        break
    print("Let's Go!")
    print("guess a number between 1-100")
    game=random.randrange(1,100)
    finGame=True
    while finGame==True:
        if int(input())>game:
            print ("ouch! the guess is too big, try again")
        else:
            if int(input())<game:
                print ("ouch! the guess is too small, try again")
            else:
                print("nice try!!!!!!!! this guess was hwosome!",game)
                finGame=False

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

אחרי שהבנת מתי זה קורה נסי לעקוב אחר המסלול בקוד שגורם לבעיה ולבחון מה קורה שם - איזה רצף של פקודות מופעל ולמה רצף זה גורם לבעיה?

אתה מתכוון למשהו כזה?
ואז הקוד שאתה כתבת בתרגיל בודק את הקוד הזה ע"י unittest?



class ImageFile(object):
    def __init__(self, type):
        self.types = ["jpg", "png", "tif", "gif"]
        self.type = type
        self.suffix = self.type.split('.')[1]
        if self.suffix in self.types:
            print self.suffix
        else:
             raise InvalidImageExt("Wrong type{}".format(self.type))


class InvalidImageExt(Exception):
    def __init__(self, error):
        super(InvalidImageExt, self).__init__()
        self.error = error


img = ImageFile("file.gif")
לייק 1

מדויק! (ובדרך כלל אני לא משאיר הודעות קצרות כאלה אבל הפעם זה התבקש.)

הי ינון,
הקוד הבא מבצע חישוב של שורש של מספרים משורת הפקודה
הכנסתי את הנתונים הבאים בשורת הפקודה:
10
9-
p
81
(10 ראשון , 81 אחרון)

משום מה כשהוא מגיע ל 81 הוא זורק לי IndexError: list index out of range
לא מבין למה


import sys
import math

def sqrt(x):
    return math.sqrt(x)


a = []
for index,number  in enumerate(sys.argv[1:]):
    print 'number {} in place {} the root is:'.format(number,index)
    try:
        a.append(float(number))
        print sqrt(a[index])
    except ValueError as e:
        print "Please enter numbers > 0 only"
        print e.message

הבנתי מה הבעיה ותיקנתי

import sys
import math

def sqrt(x):
    return math.sqrt(x)


a = []
for number  in (sys.argv[1:]):
    try:
        a.append(float(number))
        print 'number {} in place {} the root is:'.format(number,len(a)-1)
        print sqrt(a[-1])
    except ValueError as e:
        print "Please enter numbers > 0 only"
        print e.message













לייק 1