זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/python/lessons/datastructures-lab
זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/python/lessons/datastructures-lab
תרגול מבני נתונים תרגיל 1
"""
answer 17-1
"""
import sys
table={"apple":"red","lettuce":"green","lemon":"yellow","orange":"orange"}
user_name=sys.argv[1]
password=sys.argv[2]
t=table.get(user_name)
if t is None or t!=password:
print "INTRUDER ALERT"
else:
print "Welcome Master"
תשובה לתרגול מבנה נתונים שאלה 2
"""
answer 17-2
"""
import sys
if len(sys.argv)!=21:
print "you must set 20 scores"
sys.exit()
total=0
count_scores=len(sys.argv)-1
for num in sys.argv[1:]:
total+=int(num)
avg=total/count_scores
print "Avege is {}".format(avg)
for num in sys.argv[1:]:
if int(num)>avg:print num,
הי,
לגבי פיענוח sys.argv אני הייתי כותב כך:
_, user_name, password = sys.argv
ונהוג גם להשאיר רווחים מסביב לאופרטורים למשל:
total += int(num)
והצעה אחרונה לגבי הסכום (לא בטוח שהופיע בקורס אבל בכל מקרה יהיה מעניין לספר). אני אוהב להשתמש בפונקציה sum כדי לסכום. הבעיה כאן שאתה סוכם מחרוזות וצריך להמיר למספרים לפני. שתי דרכים לעשות את זה:
l = sys.argv[1:]
# Option 1 with map
sum(map(int, l))
# Option 2 with list comprehensions
sum([int(x) for x in l])
תשובה לשאלה 3 תרגול מבנה נתונים פייתון
"""
Answer 17-3
"""
import sys
map_ip={}
with open("hosts.txt","r") as f:
for line in f:
k,v = line.split("=")
if v[-1] == "\n" : v = v[:-1]
map_ip.setdefault(k,v)
for m in sys.argv[1:]:
ip=map_ip.get(m)
if ip is None:
print "The Mechine {} not exits in the list".format(m)
else:
print "The mechine {} IP is {}".format(m,ip)
הי יוני,
לגבי השורה שמוחקת את תווי סוף השורה עדיף להשתמש בפונקציה strip של פייתון ולכתוב:
line.strip()
שאלה- למה אתה משתמש ב setdefault
ולא בהשמה רגילה למילון?
תשובה לשאלה 4 מתרגול מבנה נתונים
"""
answer 17-4
"""
from collections import Counter
map={}
with open("word.txt","r") as f:
for w in f:
w=w.strip("\n")
c=Counter(w)
#get the key
total=0
for x in c:
total += (ord(x)-ord('a')+1)*c.get(x)
#get the value
words=[]
words=map.setdefault(total,words)
words.append(w)
for v in map.values():
print v
הי יוני,
-
אין צורך להעביר פרמטר ל strip - ירידת שורה היא ברירת המחדל שם
-
החישוב שלך של המפתח במילון לא נכון. לדוגמא המחרוזת aa והמחרוזת b מייצרות את אותו ערך במשתנה total. נסה לחשוב על דרך אחרת לבדוק אם שתי מילים הן אנאגרמות
"""
answer 17-1
"""
import sys
table={"apple":"red","lettuce":"green","lemon":"yellow","orange":"orange"}
_, user_name, password = sys.argv
t=table.get(user_name)
if t is None or t!=password:
print "INTRUDER ALERT"
else:
print "Welcome Master"
הפתרון שלי לתרגיל 1:
import sys
data = {'apple':'red',
'lettuce':'green',
'lemon':'yellow',
'orange':'orange'
}
(key,value) = sys.argv[1:3]
if(key in data.keys() and value in data.values()):
print "Welcome Master"
else:
print "INTRUDER ALERT"
השורה:
if(key in data.keys() and value in data.values()):
לא מומלצת. בפייתון יש הבדל בזמן החיפוש בין מבנה הנתונים Dictionary ל List: זמן החיפוש ב Dictionary הוא מיידי, בעצם פייתון לא צריך לעבור על כל האיברים במילון כדי לחפש איבר מסוים אלא הוא ממילא שומר אותם באמצעות אינדקס שמתאים לאיבר. אפשר לקרוא על המנגנון בויקיפדיה כאן:
כשאתה כותב data.keys אתה הופך את המילון לרשימה וכך מאט את החיפוש. מומלץ יותר לבדוק קיום מפתח במילון באמצעות in ושליפת ערך באמצעות גישה ישירה לערך, כלומר שורה טובה יותר תהיה:
if key in data and data[key] == value:
נקודה נוספת - הקוד שלך בודק רק ש key ו value נמצאים במילון אבל לא שהם מתאימים לכן אפשר יהיה להתחבר עם שם משתמש וסיסמא קיימים אך לא מתאימים.
היי ינון תודה על ההערה ,הפנמתי את העניין שעבודה עם מבנה נתונים של מילון כמו json בגאווה סקריפט היא מהירה יותר בשליפת נתונים מאשר רשימה
תיקון מה שכתבתי לשאלה 1:
import sys
data = {'apple':'red',
'lettuce':'green',
'lemon':'yellow',
'orange':'orange'
}
(key,value) = sys.argv[1:3]
if(data.get(key)==value):
print "Welcome Master"
else:
print "INTRUDER ALERT"
פתרון לתרגיל 2:
import sys
import numbers
if len(sys.argv)!=3 or not sys.argv[1].isdigit() or not sys.argv[2].isdigit() :
print "Usage %s <type int> <type int>" % (sys.argv[0])
sys.exit(1)
(_,num1,num2)=sys.argv
print "{} + {} = {}".format(num1,num2,int(num1)+int(num2))
פתרון לתרגיל 3:
import sys,os
computer_name=sys.argv[1:]
file_dic ={}
with open("hosts.txt","r") as fin:
for line in fin:
line = line.split("=")
host= line[1]
host=host.rstrip()
file_dic[line[0]]=host
for host in computer_name:
try:
if file_dic[host]:
print file_dic.get(host)
except:
print "the given host {} not exsist.....".format(host)
לגבי תרגיל 4 ניסתי לעשות משהו, הוא היה מסוברבל מבחינתי ואני חושב שיש הרבה בדיקות לא נחוצות אבל זה מה שיכלותי להגיע בידע הנוכחי שלי והכלים שלמדתי עד עכשיו בקורס…
הוא לא עובד… אבל אשמח לדעת למה ולראות פתרון שעובד
import sys,os
from collections import Counter
#word1="abc"
#word2="cbaab"
words=[]
path=sys.argv[1]
with open(path,"r") as fin:
for word in fin:
words.append(word.splitlines())
strings = []
for word in words:
strings.append(str(word))
anagrma = []
flag=False
for word in strings:
for nextword in strings[1::]:
dict1= Counter(word)
dict2= Counter(nextword)
if len(dict1)!= len(dict2):
break
else:
for x in dict1:
for y in dict2:
if x in y:
flag=True
continue
else:
flag = False
break
if(flag):
anagrma.append(word,nextword)
print set(anagrma)
בשביל לזהות ששתי מילים הן אנאגרמה אחת של השניה נרצה למיין את האותיות שלהן (למשל לפי סדר מילוני).
הנה כמה דוגמאות:
>>> sorted('add')
['a', 'd', 'd']
>>> sorted('dad')
['a', 'd', 'd']
>>> sorted('dad') == sorted('dad')
True
>>> sorted('foo')
['f', 'o', 'o']
>>> sorted('bar')
['a', 'b', 'r']
>>> sorted('foo') == sorted('bar')
False
רק זה לבד יכול להספיק כדי לפתור את התרגיל. אבל אפשר לשפר: כי אם נשמור גם Dictionary של המילים שראינו נוכל לזהות יותר מהר אם מילה מסוימת היא אנאגרמה של משהו שכבר ראינו (בלי שנצטרך להשוות אותה אל מול כל המילים מחדש).