קריאה וכתיבה מקבצים#
אג’נדה#
מבוא לקבצים
פתיחה וסגירה של קבצים
קריאה מקבצים
כתיבה לקבצים
טקסט המופיע למטה בסגול מציין קטעים המופיעים בסרטון
ניתן להיעזר בו כדי לחזור על התכנים או לעיין בהם שוב.
בחלק זה נלמד כיצד לעבוד עם קבצים בפייתון, כלומר איך לקרוא מידע מקובץ קיים ולכתוב מידע חדש לקובץ חדש או קיים.
שימוש בקבצים מאפשר לנו לשמור מידע בצורה קבועה, שאינה נעלמת עם סיום הריצה של התוכנית, להחזיק כמויות גדולות של נתונים, ולשתף מידע בין תוכניות שונות או בין מחשבים שונים.
נלמד כיצד לפתוח קובץ, לקרוא את תוכנו, לעדכן או להוסיף מידע ולשמור אותו מחדש. בסיום היחידה הזו תוכלו לכתוב תוכניות ששומרות מידע טקסטאולי בקבצים במחשב שלכם.
מהו קובץ?#
קובץ במחשב הוא משאב לאחסון מידע. אפשר לחשוב עליו כ”מסמך” דיגיטלי.
קבצים יכולים להכיל מידע מסוגים שונים - יש קבצי תמונה, מוזיקה, וידאו, טקסט, טבלאות ועוד.
סיומות#
לכל קובץ יש סיומת (extension), שמסמלת איזה סוג תוכן מאוחסן בקובץ. כך המחשב יודע מה רצף הביטים שבקובץ אמור לייצג וכיצד לעבד אותו.
אם הסיומת מתאימה לקובץ שמע, המחשב ימיר את הביטים לצלילים ברמקול. אם מדובר בטקסט, הוא ימיר את הביטים לתווים (לדוגמא, לפי טבלת ASCII כפי שלמדנו).
סיומת תופיע לאחר . המופיעה בסוף שם הקובץ. לדוגמא:
txt.מסמל שמדובר בקובץ טקסט.mp3.מסמל שמדובר בקובץ מוזיקה.jpg.מסמל שמדובר בקובץ של תמונה.py.מסמל שמדובר בקובץ פייתון!
בשלב הזה אנחנו נתמקד בקבצי טקסט.
שימו לב
שם הקובץ עצמו יכול גם הוא להכיל מספר נקודות. רק לאחר הנקודה האחרונה תופיע הסיומת של הקובץ.
מערכת קבצים#
למערכת קבצים מבנה היררכי#
מערכת הקבצים של המחשב בנויה בצורה היררכית, כלומר כמו עץ:
בראש ההיררכיה נמצא השורש (root) המשותף לכל העץ.
במערכות הפעלה מסוג Windows ה-root הוא בד”כ נתיב לתחילת לכונן (C:)
בתוך ה-root יש תיקיות שיכולות להכיל קבצים ותיקיות נוספות, וכל אחת מהתיקיות הללו יכולה להכיל תיקיות נוספות בעצמה.
כך נוצר מבנה מסודר שמאפשר לנו לארגן את המידע בצורה מסודרת ולגשת אליו לפי מיקומו בהיררכיה.
להלן דוגמא של עץ היררכיית קבצים ותקיות במערכת הפעלה מסוג Windows:
במקרה זה, הקובץ analyze_data.py נמצא בתיקיית Python, אשר נמצאת בשורש - \:C.
מיקום של קובץ נקרא ניתוב. בדרך כלל נסמן את הירידה בעץ התיקיות באמצעות /.
שימו לב!
יש הבדל מהותי בין \ ל-/, עליו נרחיב בהמשך.
ניתוב מלא (absolute) ויחסי (relative)#
על מנת לפתוח קובץ מהקוד שלנו, עלינו לייצג במחרוזת את הניתוב המתאים לקובץ אליו אנו רוצים לגשת.
ניתן לעשות זאת באחת משתי דרכי הניתוב הבאות:
ניתוב אבסולוטי/מלא (Absolute path) , המתאר את הניתוב של הקובץ מהroot עד הקובץ הרצוי.
כדי לגשת לקובץ analyze_data.py בצורה הזו, נתחיל מהשורש ונרד למטה בעץ התיקיות:
כלומר נתחיל בשורש -> ניכנס לתיקייה Python -> ואז נגיע לקובץ analyze_data.py.
ניתוב רלטיבי/יחסי (Relative path), המתאר את הניתוב מהמיקום הנוכחי לקובץ הרצוי.
אבל מהו המיקום הנוכחי שלנו? נשים לב כי גם הקוד שלנו נמצא בקובץ שיש לו ניתוב משלו, וזהו למעשה המיקום הנוכחי שלנו.
כיצד נגיע מהמיקום הנוכחי לקובץ אליו אנו רוצים לגשת? בדוגמא לעיל, על מנת לגשת לקובץ income ממיקום הקוד, נמצא בתיקיית Python, “נעלה” תיקייה אחת למעלה, ניכנס לתיקייה Data, ניכנס לתיקייה 2024 ורק אז ניגש לקובץ income.
אבל כיצד “נעלה” תיקיה אחת למעלה?
ניווט בהיררכיית התיקיות באמצעות ..#
קיים סימון המיוחד בניתובי קבצים ותיקיות לייצוג “עליה של תיקייה אחת למעלה” בהיררכיה - ... לדוגמא, אם היינו רוצים להגיע ל income.txt מהמיקום של analyze_data.py, הניתוב היחסי יהיה “Data/2024/income.txt/..”.
Data/2024/income.txt/..
כדאי לדעת
ניתן גם להשתמש בנקודה בודדת - . - כדי לסמן “התיקייה שבה אנחנו נמצאים”.
לדוגמא, אם הקוד שלנו היה נמצא בתיקיית Data, הניתוב היחסי של הקובץ income יהיה “income.txt/2024/.”.
אך למעשה, אין באמת צורך להשתמש ב.: אם הקובץ נמצא בדיוק בתיקיה שבה הקוד, ניתן להמיר את “file_name.txt/.” ב”filename.txt”.
שימו לב
זכרו כי הקו אלכסוני הפוך (\) נועד כדי לייצג תווים מיוחדים (כמו \n).
לכן, יש להמנע משימוש בתו כזה במחרוזות שייצגו נתיבי קבצים. שימוש כזה יגרום ליצירת נתיב קובץ לא צפוי. לדוגמא:
print("C:\Users\Desktop\file.txt")
Cell In[2], line 1
print("C:\Users\Desktop\file.txt")
^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
במקרה הזה פייתון מנסה לחפש את התו המיוחד U\ (כחלק מUsers\), ולא מוצא. לכן הוא זורק שגיאה.
כאלטרנטיבה, ניתן לייצג את ניתוב הקבצים בצורות הבאות:
'C:/Users/Desktop/file.txt'- שימוש בקו אלכסוני רגיל.'C:\\Users\\Desktop\\file.txt'- החלפת כל קו אלכסוני הפוך בשני קווים.
print('C:\\Users\\Desktop\\file.txt')
print('C:/Users/Desktop/file.txt')
C:\Users\Desktop\file.txt
C:/Users/Desktop/file.txt
תרגול#
בשאלות הבאות נתמקד בעץ התיקיות הבא:
קבצי טקסט#
טקסט המופיע למטה בסגול מציין קטעים המופיעים בסרטון
ניתן להיעזר בו כדי לחזור על התכנים או לעיין בהם שוב.
קבצי טקסט מורכבים משורות. כל שורה היא מחרוזת, כלומר רצף תווים.
התו האחרון בכל שורה הוא התו המיוחד (escape character) ירידת שורה (n\).
תזכורת
רצף תווים (בד”כ 2) המתחילים בקו אלכסוני הפוך -\ - נקראים גם escape characters, והם נועדו לסמן תווים שלא ניתן להקיש במקלדת באופן פשוט.
בד”כ לא נראה תווים הללו זה בעורכי טקסט סטנדרטיים, אלא את התווים שהם אמורים לייצג.
מאחורי הקלעים יהיה כתוב:
This is line one\nThis is line two\nThis is linethree\nThis is line four\n
פתיחת וסגירת קבצים#
גישה לקובץ#
כדי לגשת קובץ בפייתון, משתמשים בפקודה open, שמקבלת שני פרמטרים:
filenameמחרוזת המייצגת את הניתוב של הקובץ שמעוניינים לפתוח.modeאילו פעולות ניתן לבצע על הקובץ.
open מחזירה אובייקט המשמש כחיבור לקובץ שנקרא גם handle.
ניתן לחשוב על ה-handle כ”צינור” שאפשר דרכו להעביר נתונים אל הקובץ וממנו.
שימו לב
זכרו להמנע משימוש בקו אלכסוני הפוך (\) גם בשם הקובץ
מצבי פתיחת קובץ#
'r'- קריאה בלבד.'w'- כתיבה בלבד (ימחק את הנתונים הקודמים)'a'- הוספה לקובץ (כתיבה לסוף הקובץ הקיים)
דוגמא לשימוש בopen:
שימו לב
f אינו הקובץ עצמו, אלא משמש לתקשורת עם הקובץ.
מה יקרה אם נפנה לקובץ שאינו קיים?#
במצב קריאה (r), כמובן לא נוכל לקרוא מהקובץ, ולכן נקבל שגיאה.
f = open("not_existing_file.txt", "r")
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
Cell In[9], line 1
----> 1 f = open("not_existing_file.txt", "r")
File /opt/hostedtoolcache/Python/3.11.14/x64/lib/python3.11/site-packages/IPython/core/interactiveshell.py:344, in _modified_open(file, *args, **kwargs)
337 if file in {0, 1, 2}:
338 raise ValueError(
339 f"IPython won't let you open fd={file} by default "
340 "as it is likely to crash IPython. If you know what you are doing, "
341 "you can use builtins' open."
342 )
--> 344 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'
לעומת זאת, במצבי כתיבה (w) או הוספה (a), אם הקובץ אינו קיים, יווצר קובץ חדש כל עוד הניתוב לתיקיה המכילה את הקובץ קיים.
לדוגמא, הקובץ הבא יצליח להפתח במצב כתיבה, אפילו שאינו קיים, מכיוון שאנו מחפשים אותו בתיקיה הנוכחית עליה אנו עובדים:
f = open("not_existing_file.txt", "w")
לעומת זאת, במקרה שהניתוב מוביל לתיקיה שאינה קיימת, הקריאה תכשל:
f = open("not_existing_folder/not_existing_file.txt", "w")
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
Cell In[12], line 1
----> 1 f = open("not_existing_folder/not_existing_file.txt", "w")
File ~/micromamba/lib/python3.11/site-packages/IPython/core/interactiveshell.py:326, in _modified_open(file, *args, **kwargs)
319 if file in {0, 1, 2}:
320 raise ValueError(
321 f"IPython won't let you open fd={file} by default "
322 "as it is likely to crash IPython. If you know what you are doing, "
323 "you can use builtins' open."
324 )
--> 326 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_folder/not_existing_file.txt'
לאחר שפתחנו קובץ קיים, ניתן להעזר בhandle שלו (בדוגמאות שלנו f) כדי לקרוא את התוכן השמור בקובץ.
כדי לעשות זאת נשתמש בפקודה ()f.read: מתודה זו קוראת את כל תוכן הקובץ בבת אחת ומחזירה אותו כמחרוזת אחת ארוכה.
f = open('test_file_multi_line.txt', 'r')
lines = f.read()
print(lines)
This is line 1
This is line 2
The end
בהדפסה ראינו ירידת שורה מאחר שכך פייתון מדפיס את התו n\. עם זאת, הטקסט השמור בlines הינו 'This is line 1\nThis is line 2\nThe end'.
'This is line 1\nThis is line 2\nThe end'
סגירת קובץ#
סגירה של קובץ מתבצעת על-ידי הפעלת המתודה close מה-handle של הקובץ שלנו.
בדוגמא שלנו, ה-handle שלנו הוא f, ולכן נסגור את הקובץ על-ידי:
חשוב מאוד לסגור כל קובץ שפתחנו משתי סיבות:
שחרור משאבים - כל handle הנוצר עבור קובץ פתוח תופס משאבים במערכת ההפעלה. נחזור לדוגמא בה חשבנו על handle כמו “צינור” שמאפשר להוציא ולהכניס נתונים לקבצים שלנו. מכיוון שמספר ה”צינורות” הללו מוגבל, יש לשחררם ברגע שסיימנו להשתמש בקובץ, ושחרור צינור נעשה באמצעות פקודת
close. אם לא נסגור קבצים, אנחנו עלולים לגרום לכך שהתוכנית או אפילו המחשב לא יוכלו לפתוח קבצים נוספים.שמירת מידע - אם אנחנו כותבים לקובץ, השינוי לא תמיד יתעדכן מידית. לפעמים המערכת מחכה שנבקש לכתוב מספיק תווים לפני שהיא מעדכנת את הקובץ. אם הקובץ לא נסגר, המידע עלול להישאר בזיכרון ולא להישמר בפועל, וכך נאבד נתונים.
with context manager#
כדי לא לקחת את הסיכון שנפתח קובץ ולא נסגור, ניתן להשתמש ב-with כדי להגדיר את הבלוק של הקוד, או את הקונטקסט בו קובץ יהיה זמין.
הקובץ יפתח בתחילת הבלוק, ויסגר אוטומטית בסופו.
כלומר, אם עד כה קראנו קובץ כך:
f = open('test_file_multi_line.txt', 'r')
content = f.read()
f.close()
כעת נממש את אותה לוגיקה תוך שימוש בwith.
בשורה הראשונה הקובץ נפתח, והאובייקט שמייצג אותו נשמר בשם f.
ברגע שהקוד יוצא מהבלוק של ה־with (כלומר נגמרת ההזחה), פייתון סוגר את הקובץ אוטומטית.
כלומר, פייתון יסגור את הקובץ אפילו אם בלוק הקוד לא סיים לרוץ בגלל שגיאה.
כך אנחנו לא צריכים לזכור לקרוא ל־close, ולא לוקחים סיכון שהקובץ יישאר פתוח.
with open('test_file_multi_line.txt', 'r') as f:
content = f.read()
# f.close() is automatically called after the end of the `with` block
בשורה הראשונה הקובץ נפתח, והאובייקט שמייצג אותו נשמר בשם f.
ברגע שהקוד יוצא מהבלוק של ה־with (כלומר נגמרת ההזחה), פייתון סוגר את הקובץ אוטומטית. פייתון יסגור את הקובץ אפילו אם בלוק הקוד לא סיים לרוץ בגלל שגיאה.
כך אנחנו לא צריכים לזכור לקרוא ל־close, ולא לוקחים סיכון שהקובץ יישאר פתוח.
הדוגמאות תראו בהמשך ישתמשו בשתי הדרכים, כדי שנתרגל לשתי צורות הכתיבה.
תרגול#
להלן ארבעה קטעי קוד:
## Code 1 | # Code 2 | # Code 3 | # Code 4
f = open("file.txt", "r") | f = open("file.txt", "r") | with open("file.txt", "r"): |with open("file.txt", "r"): #
print("hello") | print("hello") | while True: | print("hello" + 2) #
f.close() | | print("hello") |
דרכים נוספות לקרוא מקובץ#
()f.readline#
מתודה זו קוראת את השורה הבאה בלבד מתוך הקובץ, יחסית למיקום הנוכחי שבו אנחנו נמצאים.
שימושי כשאנחנו רוצים לעבור שורה-שורה באופן ידני.
f = open('test_file_multi_line.txt', 'r')
line1 = f.readline()
line2 = f.readline()
f.close()
print(line1)
print(line2)
This is line1
This is line 2
עצרו וחשבו: מדוע קיים רווח בין שתי השורות שהודפסו?
רווח זה נובע מתו ירידת השורה n\ שקיים בסוף כל שורה, מלבד השורה האחרונה בקובץ
שימו לב
כל פעולת קריאה מקדמת אותנו שורה בקובץ, כלומר, קריאה של שורה אחת תקדם את הסמן לשורה הבאה.
כדי לחזור לתחילת הקובץ, נצטרך לסגור ולפתוח אותו מחדש.
()f.readlines#
מתודה זו קוראת את כל השורות שנשארו בקובץ ומחזירה אותן כרשימה של מחרוזות (כל איבר ברשימה הוא שורה אחת). מדובר בפקודה נוחה ביותר אם רוצים רשימה שאפשר לעבור עליה או לעבד אותה.
f = open('test_file_multi_line.txt', 'r')
lines = f.readlines()
f.close()
print(lines)
print(lines[2])
['This is line1\n', 'This is line 2\n', 'The end']
The end
שימו לב
גם כאן, כל שורה, מלבד האחרונה, מכילה בסופה את התו n\.
לולאת for על הקובץ#
ניתן לעבור שורה-שורה באמצעות לולאת for. הדרך הזו מתאימה במיוחד לקבצים גדולים, מאחר שהיא לא שומרת בזכרון את כל הקובץ בבת אחת.
f = open('test_file_multi_line.txt', 'r')
for line in f:
print(line, end='')
f.close()
This is line1
This is line 2
The end
כתיבה לקובץ#
עד עכשיו למדנו כיצד ניתן לקרוא מקבצים. עכשיו נלמד לכתוב לקבצים בעצמנו.
ראשית, נצטרך לפתוח את הקובץ בהרשאות כתיבה מתאימות (write/append).
לאחר שהקובץ פתוח, ניתן להשתמש בפקודה f.write(string) כדי לכתוב לתוך הקובץ מחרוזת.
חשוב לשים לב שהפקודה write כותבת בדיוק את התוכן שנעביר לה, כולל רווחים ותווי ירידת שורה אם הוספנו כאלו.
בדוגמא הבאה, אנו פותחים את הקובץ test_file_3.txt עם הרשאות כתיבה.
לאחר מכן נבצע שלוש פקודות write, אחת אחרי השנייה:
בראשונה כתבנו לקובץ את המחרוזת
"This is a test"אחריה כתבנו את תו ירידת השורה
n\,לבסוף, כדי לכתוב את הטאפל לתוך הקובץ, המרנו אותו למחרוזת וכתבנו גם אותו.
# open a file (or create it if no such file exists)
f = open('test_file_3.txt', 'w')
f.write("This is a test")
# newline
f.write('\n')
# to write a non-string object, first convert to string
tpl = ('string', 40)
f.write(str(tpl))
# flush data to the file and close it, unlock file, free resources
f.close()
כעת נפתח את הקובץ במצב קריאה, ונראה מה כתבנו אליו:
f = open('test_file_3.txt', 'r')
print(f.read())
f.close()
This is a test
('string', 40)
רמז
שימו לב שירידת השורה אשר מופיעה בקובץ נובעת מכך שכתבנו n\. היא לא מתבצעת באופן אוטומטי
דוגמא: כתיבת רשימת מספרים לקובץ טקסט#
בדוגמא זו נרצה לכתוב לתוך קובץ רשימה של ריבועי המספרים 1-10, כל אחד בשורה נפרדת.
ראשית, ניצור רשימה של המספרים אותם אנחנו רוצים לרשום.
my_list=[]
for a in range(1, 11):
my_list.append(a**2)
תרגול
כיצד הייתם יכולים ליצור רישום מספרים ריבועיים בשורה אחת בלבד תוך שימוש בlist comprehension?
פתרון
my_list=[a**2 for a in range(11)]
כעת נכתוב לתוך קובץ את רשימת המספרים, תוך שימוש בפקודת write
f = open("output.txt", "w")
for item in my_list:
f.write(str(item) + "\n")
f.close()
כעת נוכל לקרוא מהקובץ ולראות מה כתבנו.
f = open('output.txt', 'r')
print(f.read())
f.close()
1
4
9
16
25
36
49
64
81
100
נסו בעצמכם
מה היה קורה אם לא היינו מכניסים את תו ירידת השורה?
נסו לשנות את הקוד כך שהמספרים יופיעו בהפרש של שני רווחים אחד מהשני, במקום בשורות נפרדות.
פונקציות שימושיות לעריכת מחרוזות בקבצים#
טקסט המופיע למטה בסגול מציין קטעים המופיעים בסרטון
ניתן להיעזר בו כדי לחזור על התכנים או לעיין בהם שוב.
כפי שראינו, כאשר אנחנו עובדים עם קבצים, אנחנו מקבלים טקסט גולמי.
הטקסט הזה לא תמיד מוכן לשימוש ישיר: לעיתים הוא כולל פסיקים, רווחים מיותרים, ירידות שורה או סימנים נוספים.
לכן חשוב להכיר כמה פונקציות בסיסיות שמאפשרות לנו לנקות, לפרק ולעבד מחרוזות, כדי שנוכל להפוך את המידע מהקובץ לנתונים שימושיים.
split#
קבצים לעיתים מכילים טקסטים ארוכים, אפילו בשורה בודדת.
באמצעות split ניתן יהיה לפרק טקסט ארוך לפי תו מפריד.
מתודה זו “תחתוך” את המחרוזת ממנה הופעלה בכל המקומות בהם יופיעו תווים מפרידים, ותחזיר רשימה המכילה כל תתי-המחרוזות שנוצרו בעקבות החיתוך.
בברירת המחדל, המחרוזת תפורק בכל תו רווח כלשהו (" ", \n, \t וכו’).
לדוגמא, במקרה הזה נפצל את המחרוזת לפי פסיקים.
s = "topeka, kansas city,wichita,,olathe"
cities = s.split(',')
print(cities)
['topeka', ' kansas city', 'wichita', '', 'olathe']
ניתן לראות כי קיבלנו מחרוזת אחת ריקה, וזאת מאחר שיש שני פסיקים ביניהם “אין כלום” - כלומר יש ביניהם מחרוזת ריקה.
strip#
ניתן לנקות תווים “מיותרים” מתחילת ומסוף המחרוזת על ידי הפונקצית strip.
כברירת מחדל, תווים מיותרים מוגדרים להיות כל תו רווח כשלהו, אך ניתן להכניס כפרמטר אילו תווים נחשבים מיותרים.
' \t\n spacious \t '.strip()
'spacious'
'www.example.com'.strip('comwz.')
'example'
שימו לב!
אף אחת מהמתודות האלו לא תוריד תווים מאמצע המחרוזת. ולכן ה”m” של example נשארה במקומה.
כדאי לדעת!
ניתן להשתמש במתודות rstrip ו-lstrip כדי להסיר תווים מיותרים רק מצד אחד שהמחרוזת - הימני או השמאלי.
rstrip – מסיר רק מהצד הימני (כלומר מסוף המחרוזת)
lines = ['this is line 1\n', 'this is line 2\n', 'the end']
for i in range(len(lines)):
lines[i] = lines[i].rstrip()
print(lines)
['this is line 1', 'this is line 2', 'the end']
נסו בעצמכם - מה עושה הפונקציה ()lstrip?
# Write your code here
join#
המתודה join בפייתון משמשת לחיבור רשימה (או iterable אחר) של מחרוזות למחרוזת אחת, עם מפריד שבוחרים מראש.
לדוגמא, בקוד שלפנינו חיברנו את המילים hello ו-world באמצעות מקף (-).
"-".join(["hello", "world"])
'hello-world'
בדוגמא זו המפריד הוא המקף המתודה מופעלת מהמפריד, והארגומנט שלה הוא רשימת המחרוזות שאנו רוצים לחבר.
```{admonition} **חשבו**
:class: tip
מה הייתה התוצאה של הפעלת מתודה `join` על מחרוזת במקום על רשימת מחרוזות?
```
תרגיל: הדפסת שכיחות מילים#
הדפיסו את המילים מהקובץ input.txt לפי שכיחות יורדת. כלומר קודם את המילה הכי נפוצה בקובץ, לאחר מכן המילה השנייה הכי נפוצה, וכן הלאה.
כדי לבדוק את הקוד שלנו, יצרנו עבורכם קובץ בשם input.txt.
עליכם לפתוח אותו, לקרוא את תוכנו, ולבצע את החישוב:
שימו לב
אל תשכחו לסגור את הקובץ באמצעות מתודה close
המלצה
נסו קודם להדפיס את תוכן הקובץ במלואו, כדי להבין כמה שורות יש בקובץ.
# Write your code here
לחצו כאן כדי לצפות בפתרון
f = open("input.txt", "r")
d = {}
for line in f:
for word in line.split():
d[word] = d.get(word, 0) + 1
f.close()
for w in sorted(d, key=d.get):
print(w + ":", d[w])
תרגול מסכם#
בחלק זה אתם תתנסו בעצמכם בקריאה ובכתיבה לקבצים.
הנחיות:
בכל פעם שאתם מקבלים מחרוזת המייצגת ניתוב לקובץ, צרו תחילה את הקובץ על מנת שתוכלו לבדוק את עצמכם.
נסו לחשוב לפני המימוש - אילו קבצים עליי לפתוח? ובאיזה מצב (
mode)?אם עליכם לקרוא מקובץ, נסו לחשוב - איזו מהדרכים שלמדנו הכי תתאים?
ודאו שכל פונקציה סוגרת את כל הקבצים שהיא פתחה.
לאחר שסיימתם לכתוב את הפונקציה, בדקו את הקוד שלכם על מגוון קבצי טקסט. אל תהססו ליצור קבצים בעצמכם כדי לוודא שהקוד עושה את הדרוש.
ממשו את הפונקציה second_word אשר מקבלת מחרוזת המייצגת ניתוב לקובץ, ומדפיסה את המילה השנייה בכל שורה בקובץ.
def second_word(path):
# Write your code here
pass
# test your code here
לחצו כאן כדי לצפות בפתרון
def second_word(path):
f = open(path, "r")
for line in f:
print(line.split()[1])
f.close()
עצרו וחשבו
התבוננו כעת בקוד המופיע בפתרון. האם קוד זה מתמודד היטב עם קובץ בעל מילה בודדת? כיצד יש לתקנו כך שיעבוד גם במקרה כזה?
ממשו את הפונקציה excited_sentences אשר מקבלת מחרוזת המייצגת ניתוב לקובץ. הפונקציה תחזיר רשימה בה כל איבר הוא משפט בקובץ אשר נמצא בתוך שורה יחידה (כלומר אין בו ירידות שורה) ונגמר בסימן קריאה.
def excited_sentences(path):
# Write your code here
pass
# test your code here
לחצו כאן כדי לצפות בפתרון
def excited_sentences(path):
excited_lines = []
with open(path, "r") as f:
lines = f.readlines()
for line in lines:
excited_lines.extend(line.split("!")[:-1])
return excited_lines
עצרו וחשבו
מדוע בחרנו לוותר על האיבר האחרון בsplit?
ממשו את הפונקציה censor_file אשר מקבלת מחרוזת המייצגת ניתוב לקובץ. הפונקציה תיצור קובץ חדש בשם “censored.txt” ותכתוב לתוכו את כל השורות מהקובץ המקורי בהן לא מופיעה האות “a”.
def censor_file(path):
# Write your code here
pass
# test your code here
לחצו כאן כדי לצפות בפתרון
def censor_file(path):
f_write = open("censored.txt", "w")
with open(path, "r") as f_read:
for line in f_read:
if "a" not in line:
f_write.write(line)
f_write.close()
def censor_file2(path):
with open(path, "r") as f_read:
lines = f_read.readlines()
with open("censored.txt", "w") as f_write:
for line in lines:
if "a" not in line:
f_write.write(line)
עצרו וחשבו
התבוננו כעת בשני המימושים המופיעים בפתרון. מה ההבדל ביניהם מבחינת פתיחת וסגירת הקבצים?