#Here is my code exercice 2, I have 2 questions:
#I dont understand why my print of average is not working with the 'f'?
#How can I print in row all the grade ( in the for loop)? Because it is not printing well in the command line of Mac.
#thanks! dvorah
import sys
print('Please enter the list of 20 grades')
list_of_grades = sys.argv[1:21]
sum_of_grades = sum(map(int, list_of_grades))
number_of_students = len(list_of_grades)
average = sum_of_grades/number_of_students
print(average)
#print(f'The Average of the grades is {average}')
grades_to_integer = [int(n) for n in list_of_grades]
for grade in grades_to_integer:
if grade > average:
print(grade)
Hi Dvora,
You can print something without the line break with:
print("hello", end="")
Or using:
sys.stdout.write('hello')
As for the f - what error message did you get? What version of python are you using?
You can find your python version by running from the command line:
python --version
פתרונות לתרגילים, ממש אשמח לתגובה. תודה רבה.
(אם לא העלתי ברור, ויש דרך לעשות את זה יותר טוב, אני אתקן.
תרגיל 1
def check_user():
dict_users = {'apple': 'red',
'lettuce': 'green',
'lemon': 'yellow',
'orange': 'orange'}
username = input('Enter username: ')
password = input('Enter password: ')
# if username in dict_users:
# if dict_users[username] == password:
if (username, password) in dict_users.items():
return ('welcome master')
return ('INTRUDER ALERT')
תרגיל 2
def higher_than_avg():
return([int(mark) for mark in sys.argv[1:] if int(mark) > sum(map(int,sys.argv[1:])) /len(sys.argv)])
תרגיל 3
def ip():
dict_ip={}
with open("ips.txt", "r") as f_ip:
for line_comp in f_ip:
dict_ip[line_comp.split("=")[0]] = line_comp.split("=")[1][:-1]
for comp in sys.argv[1:]:
try:
print(dict_ip[comp])
except KeyError:
print('No such computer ', comp)
תרגיל 4
def anagrama():
list_word = []
with open("anagrame.txt", "r") as f1:
for word in f1:
list_word.append(word[0:len(word) - 1:])
print(list_word)
index = 0
found = 0
for word1 in list_word:
for word2 in list_word[index + 1:]:
if sorted(list(word1)) == sorted(list(word2)):
print(word1, word2)
list_word.remove(word2)
found = 1
index = index + 1
if found == 0:
print(word1)
found = 0
הי @elisheva
הבעיה המרכזית שחוזרת בכל הפיתרונות נקראת זמני ריצה. שווה לקרוא את הטקסט כאן:
https://discrete.gr/complexity/?he
(ואולי גם אני אכתוב מדריך כזה יום אחד :slight_smile)
הנה אצלך-
-
בתרגיל הראשון החלק שסימנת בהערה יעבוד טוב יותר, כי חיפוש במילון הוא מהיר יותר כשמחפשים לפי מפתח מאשר בחיפוש בכל רשימת הפריטים.
-
בתרגיל השני את מחשבת שוב ושוב את הסכום ואת הממוצע, כשהיה יותר יעיל לחשב אותם פעם אחת ולהשתמש בערך שחישבת בכל הלולאה.
-
בתרגיל השלישי יצא מעולה - את שומרת את כל הערכים ואז מדפיסה את אלה ששמרת.
-
בתרגיל הרביעי את בודקת כל מילה אל מול כל המילים האחרות. הרבה יותר מהיר היה לחשב את ה
sort(list(word))
פעם אחת לכל מילה ולשמור את התוצאות במילון, ואז לרוץ מחדש על כל המילים ולבדוק אל מול הערכים שכבר שמרת.
מקווה שהיה ברור ותרגישי חופשי לפרסם גירסא מעודכנת אחרי תיקון או שאלות נוספות אם יהיו
בהצלחה
ינון
קודם כל תודה רבה.
חייבת להודות שאני עדיין לא מרגישה מספיק בטוחה בעצמי בכתיבה של פייתון בשביל לשים לב לזמני ריצה.
אבל אני אתחיל לשים לב.
מצרפת את תשובה ראשונה
אבל יש לי שאלה:
כתבת שאם מחפשים לפי מפתח החיפוש מהיר יותר.
אני מבינה שמדובר על השורה הזו - התנאי השני.
if dict_users[username] == password:
אבל מה לגבי התנאי הראשון - האם גם הוא מחפש לפי מפתח, או שאם במילא בתנאי הראשון עוברים על כל המילון, אז כבר עדיף לחפש ביחד?
תודה רבה
def check_user():
dict_users = {'apple': 'red',
'lettuce': 'green',
'lemon': 'yellow',
'orange': 'orange'}
username = input('Enter username: ')
password = input('Enter password: ')
if username in dict_users:
if dict_users[username] == password:
#if (username, password) in dict_users.items():
return ('welcome master')
return ('INTRUDER ALERT')
תשובה 2.
def higher_than_avg():
#lstHigherMarks = []
sum_marks = sum(map(int,sys.argv[1:]))
avg_marks = sum_marks /len(sys.argv)
#lstHigherMarks = [int(mark) for mark in sys.argv[1:] if int(mark) > avg_marks]
#return (lstHigherMarks)
return([int(mark) for mark in sys.argv[1:] if int(mark) > avg_marks])
הי,
בהחלט כן - בפייתון החיפוש:
if x in dict_users
הוא בדיקה לפי מפתח x בתוך המילון
גם השני הרבה יותר טוב אישית הייתי מעביר את ההמרה ל int קצת למעלה - כלומר קודם יוצר רשימה של int-ים מכל sys.argv ואז רץ על רשימה זו (וזה חוסך את ההפעלה פעמיים של int)
היי ינון
לגבי שאלה מס’ 1:
ראיתי בפתרונות שהעלו פה שהערת שריצה על כל המילון עם for לא יעילה, אבל לא הצלחתי להבין איך לייעל את הקוד. אני מניח שאם המילון היה עם אלפי שמות היינו “משלמים” על זה במשאבים או בזמן הריצה של הקוד (או שזה אותו הדבר?)
אשמח אם תוכל להסביר לי איך אני יכול לתקן את הקוד כדי שיהיה יעיל יותר, או להפנות אותי למקור כזה.
מצרף את הקוד שלי:
def check_in(u_name, u_pass):
allowed = {'apple': 'red',
'lettuce': 'green',
'lemon': 'yellow',
'orange': 'orange'
}
for key, val in allowed.items():
if key == u_name and val == u_pass:
return 1
name = input("user name: ")
password = input("password: ")
check = check_in(name, password)
if check == 1:
print('Welcome MASTER')
else:
print('INTRUDER ALERT!!')
הי @Dima
הרעיון הוא למשוך מהמילון לפי המפתח במקום לרוץ על כל התאים שבו. השליפה לפי המפתח היא מהירה יותר.
בקוד זה אומר:
if u_name in allowed and allowed[u_name] == u_pass:
return 1
אפשר לקרוא על הסיבות מאחורי הסיפור בויקיפדיה בערך על טבלאות גיבוב (כך מילון ממומש ב Python):
צרפתי את התרגילים שלי. הם כתובים בתוך פונקציות לפי סדר השאלות, אשמח לקבל הערות.
תודה
def login():
passwords = {
'apple': 'red',
'lettuce': 'green',
'lemon': 'yellow',
'orange': 'orange'
}
name = input("name")
password = input("password")
if name in passwords and passwords[name] == password:
print('Welcome Master')
else:
print('INTRUDER ALTER')
def bigMarks():
print(sys.argv)
marks = [int(m) for m in sys.argv[1:]]
big = [m for m in marks if m > sum(marks)/len(marks)]
for b in big:
print(b, end=" ")
def findIP():
arguments = sys.argv[1:]
with open('hosts.txt', 'r', encoding='UTF-8') as rf:
file = rf.read().split()
sfile = [f.split("=") for f in file]
fileDic = {f[0]: f[1] for f in sfile}
try:
for a in arguments:
print(f"{a}: {fileDic[a]}")
except KeyError:
print("the value don't appear")
def anagrama(path):
with open(path, 'r', encoding='UTF-8') as rf:
words = rf.read().split()
sort_word = {}
for w in words:
sort_arr = sorted(w)
sort = ''
for a in sort_arr:
sort += a
if sort not in sort_word:
sort_word[sort] = []
sort_word[sort].append(w)
for s in sort_word.values():
for w in s:
print(w, end=" ")
print()
הי,
פיתרונות נכונים אני רוצה לכתוב כאן כמה רעיונות לשיפור או לסדר אותם שיראו קצת יותר כמו פייתון:
-
לגבי שמות משתנים - בפייתון אנחנו משתמשים באותיות קטנות בלבד בשמות משתנים ושמות פונקציות, ובקו תחתי כדי להפריד בין מילים. לכן משתנה כמו
fileDic
ירגיש יותר בנוח עם השםfile_dic
. -
בלי קשר לפייתון אני חושב שאפשר למצוא שמות ארוכים, מפורשים וברורים יותר למשתנים. לדוגמה בתרגיל של
findIP
במקוםrf
היה עדיף לבחור שם כמוhostsfile
. -
הרבה פעמים אפשר לקבל תחביר יותר נקי אם משתמשים ב Comprehensions. עשית את זה קצת למשל בתרגיל של findIP אבל אני חושב שאפשר לקחת את זה עוד כמה צעדים. כך הייתי מארגן אחרת את הקוד של הפונקציה שכתבת:
import sys
def find_ip():
arguments = sys.argv[1:]
with open('hosts.txt', 'r', encoding='UTF-8') as hostsfile:
hosts_with_ips = [line.split("=") for line in hostsfile]
hosts_ip_dict = {
host: ip for host, ip in hosts_with_ips
}
try:
for hostname in arguments:
ip = hosts_ip_dict[hostname]
print(f"{hostname}: {ip}")
except KeyError:
print("the value don't appear")
find_ip()
-
כדאי לשים לב כשמשתמשים ב Comprehension שאלה בעצם לולאות, ואם יש לנו חישוב שהולך לתת את אותו ערך בכל איטרציה עדיף לרשום אותו מחוץ ללולאה. בדוגמה שלך זה חישוב הממוצע בסעיף
bigMarks
. עדיף היה להגדיר משתנהaverage
ולהשוות אליו במקום כל פעם לחשב את הערך מחדש. -
לגבי האנגרמות הפונקציה
join
של מחרוזת עושה דבר מאוד דומה ללולאה שכתבת, כך שאפשר היה לכתוב במקום:
sort = ''.join(sorted(w))
בנוסף הראיתי בשיעור הזה:
https://www.tocode.co.il/bundles/python/lessons/16-collections
איך לעבוד עם defaultdict. אני חושב שבתרגיל האנגרמות הוא יכול להיות תוספת נחמדה.
מקווה שעזרתי ובהצלחה
תודה
בקשר להערה האחרונה, בשיעור הובא שאם שולחים את הפונקציה int מתקבל ברירת מחדל אפס,
מה צריך לשלוח לdefaultdict כדי לאתחל ברירת מחדל במערך ריק?
האפשרות המקובלת היא הפונקציה list שמחזירה רשימה ריקה:
x = list()
# is the same as:
x = []
ובכל מקרה תמיד אפשר להשתמש ב lambda:
d = defaultdict(lambda: [])
שלום
אשמח לקבל הערות
תרגיל 4
# This is a sample Python script.
from collections import defaultdict
sorted_list = defaultdict(list)
with open('demo.txt','r',encoding='UTF-8') as demo_txt:
for line in demo_txt:
sorted_list[''.join(sorted(list(line.rstrip())))].append(''.join((list(line.rstrip()))))
for key, _ in sorted_list.items():
print(', '.join((sorted_list[key])).replace(',',' '))
נראה מעולה
שיפור קטן ששווה לחשוב עליו זה לקחת את הקטע שמחשב את ה״מפתח״ - כלומר מסדר את האותיות שבמילה לפי סדר מילוני - ולהוציא אותו לפונקציה נפרדת כדי שיהיה יותר קל להבין מה קורה כשקוראים את השורה:
sorted_list[''.join(sorted(list(line.rstrip())))].append(''.join((list(line.rstrip()))))
כלומר לחשוב על משהו כמו:
word = line.rstrip()
key = sorted_letters(word)
sorted_list[key].append(word)
זה מוסיף עוד שתי שורות לפיתרון אבל אני חושב שאם תחזרי לפיתרון הזה עוד כמה חודשים יהיה יותר קל להבין אותו
@ynonp היי ינון,
התחלתי פייתון לא מזמן ואשמח לקבל חוות דעת על איך אני יכול לשפר את הקוד משמעותית (שאלה 2).
אמנם הקוד שלי מאוד פשוט ולא כל כך יעיל אבל אשמח לקצת פירוט על איך אני יכול ליעל אותו.
לדוגמה: איך אני יכול להכניס את השאלה ללולאה במקום לשאול 20 פעמים? (ראיתי את השיעורים על הלולאות אבל לא הבנתי איך אני יכול לחזור על השאלה בדיוק 20 פעמים)
ואיך אני יכול לקבוע מהם הציונים שגדולים יותר מהממוצע, במקום if?
הערה :*אני רואה שחלק מהפתרונות פה כוללים פקודות שאני לא מכיר וזה קצת מבלבל כי אני לא יודע אם אני אמור לדעת את הפקודות או לא או אם אני יכול לפתור את השאלה מבלי להשתמש בהן.
תודה מראש
להלן הקוד:
y = int(input("Please enter your grade:"))
t = int(input("Please enter your grade:"))
r = int(input("Please enter your grade:"))
u = int(input("Please enter your grade:"))
e = int(input("Please enter your grade:"))
v = int(input("Please enter your grade:"))
c = int(input("Please enter your grade:"))
h = int(input("Please enter your grade:"))
j = int(input("Please enter your grade:"))
k = int(input("Please enter your grade:"))
p = int(input("Please enter your grade:"))
z = int(input("Please enter your grade:"))
b = int(input("Please enter your grade:"))
m = int(input("Please enter your grade:"))
n = int(input("Please enter your grade:"))
i = int(input("Please enter your grade:"))
w = int(input("Please enter your grade:"))
q = int(input("Please enter your grade:"))
a = int(input("Please enter your grade:"))
g_avg = int(((a + q + w + i + n + m + b + z + p + k + k + j + h + c + v + e + u + r + t + y + x) / 20))
if x > g_avg:
print(x)
if y > g_avg:
print(y)
if t > g_avg:
print(t)
if r > g_avg:
print(r)
if u > g_avg:
print(u)
if e > g_avg:
print(e)
if v > g_avg:
print(v)
if c > g_avg:
print(c)
if h > g_avg:
print(h)
if j > g_avg:
print(j)
if k > g_avg:
print(k)
if p > g_avg:
print(p)
if z > g_avg:
print(z)
if b > g_avg:
print(b)
if m > g_avg:
print(m)
if n > g_avg:
print(n)
if i > g_avg:
print(i)
if w > g_avg:
print(w)
if q > g_avg:
print(q)
if a > g_avg:
print(a)
הי,
בפייתון אפשר לחזור על שאלה בלולאה באמצעות פקודת for. זה נראה ככה:
for i in range(20):
grade = int(input("Please enter your grade:"))
אבל זה לא מספיק, כי אנחנו רוצים גם לסכום את כל הציונים, ולכן אני מגדיר משתנה מחוץ ללולאה וכל איטרציה אני מוסיף את הציון שקלטתי לאותו סכום:
sum_of_all_grades = 0
for i in range(20):
grade = int(input("Please enter your grade:"))
sum_of_all_grades += int(grade)
אחרי הלולאה תוכל לקחת את הסכום שחושב ״לאט״ בתוך הלולאה ולחלק אותו ב 20 כדי להגיע לממוצע
היי ינון,
לגבי תרגיל 3 -
-
איך אני יכול לקלוט מהמשתמש שמות של מחשבים (כאשר המשתמש קובע כמה ערכים הוא מכניס) וכאשר הוא לוחץ enter (ללא ערך בפנים) זה מפסיק לקלוט ערכים מהמשתמש ושומר את כל הערכים שהכניס?
-
איך אני יכול לבדוק כל ערך בנפרד ( הכוונה היא שאני מכניס אותו לרשימת תנאים ) ועל פי כך לקבוע אם הערך נמצא ברשימה או לא (אם אפשרי, ואם לא אשמח לפתרון חלופי)?
תודה
הי,
- יש בפייתון לולאת while שעוזרת בדיוק במקרים כאלה. הקוד הבא מגריל מספרים אקראיים עד שהוא מוצא מספר שגדול מ 50:
from random import randint
number = randint(0, 100)
while number <= 50:
number = randint(0, 100)
print(number)
אפשר גם להשתמש בה ״הפוך״ כדי שלא נצטרך לכתוב את התנאי פעמיים בעזרת break:
from random import randint
while True:
number = randint(0, 100)
if number > 50:
break
print(number)
במקרה שלך תצטרך בתוך ה while לקלוט שמות, ולצאת מהלולאה כשהשם שקראת הוא הטקסט הריק.
- לא הבנתי את השאלה. תוכל לפרט מה בדיוק תכננת לעשות?
היי,
הכוונה שלי בשאלה 2 היא - לאחר שקלטתי את כל הערכים מהמשתמש (לאחר שרשם את כל הערכים הרצויים ולחץ enter ללא ערך) איך אני בודק כל אחד מהערכים ברשימת תנאים?
כי כאשר אני מריץ את התוכנית המשתנה computer_name שמור ללא ערך ואז הוא תמיד יבדוק את הערך הריק ,
יש דרך לסדר את זה?
תודה
להלן הקוד (כדי שתבין למה אני מתכוון):
IP_address = {
'home' : '194.90.2.1',
'work' : '10.0.0.2',
'router' : '10.0.0.1',
'mycar' : '10.0.0.5'
}
while True:
computer_name = input("Enter your computer name:")
if computer_name == '':
break
if computer_name == 'home':
print(f"{IP_address['home']}")
if computer_name == 'work':
print(f"{IP_address['work']}")
if computer_name == 'router':
print(f"{IP_address['router']}")
if computer_name == 'mycar':
print(f"{IP_address['mycar']}")
if computer_name not in IP_address:
print("The name you entered isn't in the list")