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

אני מקווה שאני מתקרב לכוונה שלך…

""" The function calculate the
tens digit"""

def tens_digit(*nums):
    return sum([tens_digit_of(x) for x in nums])
        

def tens_digit_of(num):
    char = ''
    num_list = []
    char = str(num)
    num_list = [x for x  in char]
    if len(num_list) > 1:

        return int(num_list[-2]) 
    



#print 12
print tens_digit(20,180,220,1)

רק שעכשיו זה לא עובד ולא הבנתי למה

זו הודעת השגיאה שקיבלתי

C:\Python\function_5>python tens_digit.py
Traceback (most recent call last):
  File "tens_digit.py", line 21, in <module>
    print tens_digit(20,180,220,1)
  File "tens_digit.py", line 5, in tens_digit
    return sum([tens_digit_of(x) for x in nums])
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

תרגיל 4 פונקציות

""" This program printing only the words
greater than the 1st argoment """

def long_from(x,*args):
    return [i for i in args if len(i) > x]

print long_from(3,'hit','me','baby','one','more','time')

תרגיל 5 פונקציות

def groupby(f,*words):
	dic = {}
	for i in words:
		if f(i) in dic:
			
			dic[f(i)].append(i)
		else:
			word_list = []
			word_list.append(i)
			dic[f(i)] = word_list
	print dic

groupby(lambda(s):s[0],'hello','hi','help','bye','here')

לגבי התרגיל עם ה tens_digit נסה לחשוב-
מה מחזירה הקריאה:

tens_digit_of(1)

?

והאם זה משהו שאפשר לסכום אותו?


בשתי האחרות הפיתרון טוב.

נקודה קטנה לגבי groupie-
אתה מחשב את:

f(i)

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

לייק 1

תרגיל 1 ביטויים רגולריים

import sys
import re

path = sys.argv[1]
key = sys.argv[2] 

with open(path,"r") as file:
    for line in file:
        m = re.search(r'(\w+)\s*=\s*(\w+)',line)
        if m is not None and m.group(1) == key:
            print m.group(2)
לייק 1

תרגיל 2 ביטויים רגולריים

import re
import sys

def camelCase(text):
    text = re.sub(r'\_',' ',text)
    text = re.sub(r'\b([a-z])',lambda m: m.group(1).upper(),text)
    text = re.sub(r'\s','',text)
    text = text[0].lower() + text[1:]


    #if re.search(r'\^[A-Z]',text):
        #text = re.sub(r'\^([A-Z])',lambda m: m.group(1).upper(),text)
    return text


while True:
    line = sys.stdin.readline()
    if line == '':break
    print camelCase(line)

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

יש את האתר הזה:
https://regex101.com

אתה יכול להכניס שם ביטוי רגולרי וטקסט ולראות אם מתאים,
ואם כן לראות בדיוק מה הקבוצות

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

לא כ"כ הבנתי איך להשתמש באתר הזה.
אני מכניס בשורה למעלה את הביטוי הרגולרי ובשורה למטה טקסט מסויים ובודק התאמה?
כשאני עושה זאת , גם בביטויים שעובדים התוצאה היא:

Your regular expression does not match the subject string.

תרגיל 2 (ביטויים רגולריים) - התוכנית שעושה את הפעולה הההפוכה

import re
import sys

def camelCase(text):
    text = re.sub(r"(\w)([A-Z])",r"\1 \2",text)
    text = re.sub(r'\b([A-Z])',lambda m: m.group(1).lower(),text)
    text = re.sub(r'\s','_',text)
    text = text.rstrip('_')
    text = text.lstrip('_')
    return text




while True:
    line = sys.stdin.readline()
    if line == '':break
    print camelCase(line)
לייק 1

תרגיל 3 ביטויים רגולריים

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

import csv
import sys
import re





path = "C:\\Python\\files_3\\"
path_csv = path + sys.argv[1]
with open(path_csv,"rb") as file:
    reader = csv.reader(file)
    rows = [exchange(row[0],row[1]) for row in reader]
    print rows

def exchange(word1,word2):
    item1 = re.sub(word1,word2,reader)
    item2 = re.sub(word2, word1, reader)
    
    return item1
    return item2

הי,

  1. יכול לשים דוגמא לביטוי שאתה חושב שצריך לעבוד אבל באתר כותב לך שהוא לא מתאים?

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

rows = [...]

תמצא משהו אחר לכתוב בסוגריים המרובעים

תרגיל 1 מחלקות ואובייקטים

class Summer(object):
    def __init__(self):
        self.total = 0

    def add(self,x=0,y=0):
        self.total += x+y

    def total(self):
        return self.total

s = Summer()
t = Summer()
s.add(10,20)
t.add(50)
s.add(30)
print s.total
print t.total

לגבי סעיף 1 (בהודעה הקודמת לגבי REGEX) ,
אני מנסה למשל להכניס לשורה העליונה את הקוד:

text = re.sub(r'\_',' ',text)

ואת הטקסט הבא

 text = aaa_bbb_ccc

אך מקבל את הודעת השגיאה שכתבתי לעיל

תרגיל 2 מחלקות ואובייקטים

class MyCounter(object):
        count = 0

        @classmethod
        def __init__(cls):
            MyCounter.count += 1


for _ in range(10):
    c1 = MyCounter()

print MyCounter.count

הפתרון הנ"ל אינו שלי ! לא הצלחתי לפתור בעצמי וראיתי אותו אצל יוני.
אני מנסה להבין -
אני רואה שהמשתנה c1 שולח כל פעם (כל עוד זה בתחום 10) למחלקה MyCounter
אני מבין ש count הוא משתנה מחלקה (לא הבנתי למה חייבים פה משתנה מחלקה)
ואני רואה שמוגדרת פונקציית מחלקה אבל ההגדרה שלה לא כמו שהראית בטקסט אלא ע"י init וגם אין שם פרמטר מלבד cls
גם הפעולה שהפונקציה הזו עושה היא MyCounter.count += 1 כלומר עדכון של המשתנה count במחלקה MyCounter
אבל אין שום החזרה (אין פעולת return). לא מובן למה.
בקיצור לא הבנתי את זה במאה אחוז וגם לא הבנתי איך אני אמור להבין מהתרגיל שאני צריך להשתמש במשתנה מחלקה ובפונקצית מחלקה.

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

עכשיו לגבי מחלקות ואוביקטים:

  1. הפונקציה add שכתבת עובדת אבל תפסיק לעבוד אם יהיו יותר מ-2 פרמטרים. נסה להפוך אותה לגנרית יותר (רמז: קח השראה מפונקציית חישוב הסכום בשיעור הזה:
    https://www.tocode.co.il/bundles/python/lessons/functions)

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

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

    • הראשון הוא ההדפסה MyCounter.count. זה הכתיב שמדפיס משתנה מחלקה. בשביל להדפיס משתנה רגיל של אוביקט היית צריך ״אוביקט״ משמאל לסימן הנקודה.

    • הרמז השני הוא מה הקוד עושה: הקוד יוצר 10 אוביקטים מסוג MyCounter ובסוף שואל כמה אוביקטים נוצרו. בוא נחשוב על המידע הזה- אם יש לנו מפעל שמייצר מנורות כל מנורה יודעת אם היא דולקת או כבויה, אבל רק המפעל יודע כמה מנורות ייצר. מחלקה היא כמו מפעל לייצור אוביקטים ולכן רק משתנה מחלקה יוכל להחזיק מידע שמשותף לכל האוביקטים שנוצרו.

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

הי,
לגבי סעיף 2 , תיקנתי התוכנית:

class Summer(object):
    def __init__(self):
        self.total = 0

    def add(self,*args):
        self.total += sum(args)
        return self.total


s = Summer()
t = Summer()
s.add(20,20)
t.add(80,20,1)
s.add(30)
print s.total
print t.total

אני מעריך שהפונקציה total היתה מיותרת כי היא לא באמת עשתה משהו אלא רק החזירה את הערך של האובייקט s.

לגבי השאר -

  • אמרת שאפשר לכתוב את התוכנית גם בלי המילה classmethod. הכוונה היא שלא צריך בכלל פונקצית מחלקה לתוכנית זו?

  • לגבי הרמז השני - המחלקה היא מפעל לייצור אובייקטים רק במקרה שיש משתנה מחלקה , במקרה רגיל (עם אובייקטים) כל אובייקט משתמש במחלקה בנפרד (כמו בתרגיל 1) האם הבנתי נכון?

  • בנוסף, אתה אומר שהמחלקה מייצרת אובייקטים. אני הבנתי שהאובייקט c1 מתעדכן כל הזמן (כל עוד זה בתחום של 0-9). לפי דבריך אני מבין שזה לא שהוא מתעדכן שוב ושוב אלא שכל פעם שנשלחת קריאה למחלקה נוצר עוד אובייקט בשם c1. זו גם הסיבה שהפונקציה classmethod לא מחזירה ערך ע"י הפקודה return אלא בונה עוד אובייקט c1 אך בעל ערך שונה.

  • לסיום , למה הפונקציה classmethod מוגדרת כך

def __init__(cls):

אי אפשר היה להגדיר אותה בשם שונה ולהכניס לסוגריים משתנה נוסף (מלבד cls שאני מבין שהוא מתפקד כמו self) בשם count ועליו לעשות את הפעולה הבאה?

def counter(self,count)
self.count += 1
return self.count

תודה , עמיר

התכוונת למשהו כזה? (את העבודה זה עושה רק לא הבנתי למה זה נמצא בתרגול של ביטויים רגולריים…)

path = "C:\\Python\\files_3\\"
path_csv = path + sys.argv[1]
with open(path_csv,"rb") as file:
    reader = csv.reader(file)


    rows = [row for row in reader]
    for i in rows:
        temp = i[0]
        i[0] = i[1]
        i[1] = temp

        print i
לייק 1

מעניין שאצלי זה נותן תוצאה קצת שונה (אין רווחים בין המילים מתחת לכותרת SUBTITUTION)

לאחר נסיונות רבים הצלחתי (ללא classmethod) אבל אני לא בטוח שהבנתי עד הסוף למה זה עובד
אשמח להסבר קצר שיבהיר לי

class MyCounter(object):

    count = 0

    def __init__(self):
        MyCounter.count += 1


for _ in range(10):
    c1 = MyCounter()

print MyCounter.count

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

זה אגב הפיתרון באמצעות Regexp בלבד ללא פייתון דרך אותו אתר:

עכשיו לנושא המחלקות-

  1. הפונקציה המיוחדת __init__ מופעלת אוטומטית על ידי פייתון כל פעם שמישהו יוצר אוביקט חדש ממחלקה (כל מחלקה). לכן גם במקרה של Counter השורה:
c1 = Counter()

גורמת להפעלת הפונקציה __init__ של המחלקה Counter.

  1. משתנה מחלקה הוא משתנה שנשמר במחלקה עצמה ולכן משותף לכל האוביקטים. כמו שכתבת c1 באמת מתיחס כל פעם לאוביקט אחר והאוביקטים הישנים לא נשמרו. לעומתו משתתנה המחלקה MyCounter.count נשמר ושומר על ערכו. הערך משותף לכל האוביקטים בתוכנית.

  2. ובגלל זה זה עובד! כל פעם שיוצרים אוביקט יש הפעלה של הפונקציה __init__, זו בתורה משנה את הערך של MyCounter.count ובסוף ערך המשתנה מחזיק בדיוק את כמות האוביקטים שנוצרו.