Λύσεις των 4 Δραστηριοτήτων (κώδικας Python και ανάλυση σεναρίων) και των 7 Ερωτήσεων του κεφαλαίου 6.
Ερώτηση: Ας πειραματιστούμε γράφοντας κώδικα σε Python, ο οποίος διαβάζει το αρχείο “input_file.txt” και το ξαναγράφει στο νέο αρχείο “output_file.txt”, όπου πριν από κάθε γραμμή θα προσθέτει τον αύξοντα αριθμό της. Τα αρχεία θεωρούμε ότι βρίσκονται στον τρέχοντα κατάλογο “TxtFiles”.
Απάντηση:
for line in inputfile και γράφουμε κάθε γραμμή με μπροστά τον μετρητή (μετατροπή του αριθμού σε συμβολοσειρά με str, γιατί η write δέχεται μόνο συμβολοσειρές). Η μεταβλητή line περιέχει ήδη το \n της γραμμής, οπότε δεν προσθέτουμε άλλο. Στο τέλος κλείνουμε και τα δύο αρχεία:inputfile = open("TxtFiles/input_file.txt", "r")
outputFile = open("TxtFiles/output_file.txt", "w")
linecounter = 1
for line in inputfile:
outputFile.write(str(linecounter) + ". " + line)
linecounter = linecounter + 1
inputfile.close()
outputFile.close()
\n, ούτε η αντίστοιχη γραμμή εξόδου θα τελειώνει· αν ο φάκελος TxtFiles ή το αρχείο εισόδου δεν υπάρχουν, η open() προκαλεί σφάλμα (IOError).Σύνοψη: open εισόδου "r" και εξόδου "w" στον φάκελο TxtFiles· for line in inputfile: outputFile.write(str(linecounter) + ". " + line) και αύξηση του μετρητή· close() και στα δύο.
Κριτήρια αξιολόγησης:
Ερώτηση: Υποθέτουμε ότι έχουμε ένα πρόγραμμα σε Python που έχει αποθηκευθεί στο αρχείο με όνομα demo.py και με τον ακόλουθο κώδικα: def linecount(filename): / count = 0 / for line in open(filename): / count += 1 / return count / print linecount('demo.py'). Εκτελέστε το παραπάνω πρόγραμμα και συζητήστε το αποτέλεσμα. Υπόδειξη: Το αποτέλεσμα είναι ότι θα εμφανίσει το πλήθος των γραμμών του αρχείου.
Απάντηση:
Τι κάνει η συνάρτηση: η linecount(filename) ανοίγει το αρχείο με open(filename) (προεπιλογή «r») απευθείας μέσα στη for, διατρέχει τις γραμμές του μία-μία και αυξάνει τον μετρητή count σε κάθε γραμμή· επιστρέφει το πλήθος των γραμμών.
Τι εμφανίζει: η print linecount('demo.py') δίνει ως όρισμα το ίδιο το αρχείο του προγράμματος. Το demo.py, όπως είναι γραμμένο, έχει 6 γραμμές (def, count = 0, for, count += 1, return, print) → η εκτέλεση εμφανίζει 6. Αν προσθέσουμε κενές γραμμές ή σχόλια, ο αριθμός αλλάζει αντίστοιχα — μετρά όλες τις γραμμές, όχι μόνο τις εντολές.
Συζήτηση: ① ένα αρχείο .py είναι κι αυτό αρχείο κειμένου, άρα διαβάζεται όπως κάθε άλλο (δύο τύποι αρχείων, σελ. 91)· ② το open() μέσα στη for λειτουργεί επειδή το αντικείμενο αρχείου είναι επαναλήψιμο κατά γραμμές· ③ δεν καλείται close() — κακή πρακτική: το αρχείο μένει ανοιχτό μέχρι να το απελευθερώσει η Python· σωστότερα f = open(filename) … f.close()· ④ η συνάρτηση είναι γενική: linecount('words.txt') → 3 για το αρχείο της ενότητας 6.2.
def linecount(filename):
f = open(filename) # "r"
count = 0
for line in f:
count += 1
f.close()
return count
print linecount('demo.py') # 8 (με τη νέα διάταξη 8 γραμμών)
Σύνοψη: Εμφανίζει το πλήθος των γραμμών του demo.py (6 για τον δοσμένο κώδικα): η συνάρτηση ανοίγει το αρχείο, μετρά με for line in … και επιστρέφει τον μετρητή· το .py διαβάζεται ως αρχείο κειμένου· λείπει το close().
Κριτήρια αξιολόγησης:
Ερώτηση: Να γράψετε πρόγραμμα στη γλώσσα Python, το οποίο θα δέχεται ως είσοδο το όνομα ενός αρχείου, θα εμφανίζει τα περιεχόμενά του κατά γραμμή και στη συνέχεια θα γράφει σε ένα άλλο αρχείο, τις γραμμές του αρχείου με την αντίστροφη σειρά.
Απάντηση:
Σχέδιο: ① διαβάζουμε το όνομα με raw_input (συμβολοσειρά)· ② ανοίγουμε για ανάγνωση, εμφανίζουμε κάθε γραμμή και ταυτόχρονα την αποθηκεύουμε σε λίστα (χρειαζόμαστε όλες τις γραμμές για να τις γράψουμε ανάποδα)· ③ ανοίγουμε το δεύτερο αρχείο για εγγραφή και γράφουμε τα στοιχεία της λίστας από το τέλος προς την αρχή (range(len(lines)-1, -1, -1))· ④ κλείνουμε τα αρχεία.
# Εμφάνιση αρχείου κατά γραμμή και εγγραφή των γραμμών του αντίστροφα
name = raw_input("Δώσε το όνομα του αρχείου: ")
fin = open(name, "r")
lines = []
for line in fin:
print line, # το κόμμα αποφεύγει τη διπλή αλλαγή γραμμής (η line έχει \n)
lines.append(line)
fin.close()
fout = open("reversed_" + name, "w")
for i in range(len(lines) - 1, -1, -1):
fout.write(lines[i])
fout.close()
print "Οι γραμμές γράφτηκαν αντίστροφα στο αρχείο", "reversed_" + name
Παράδειγμα: για το words.txt («This is line 1 / This is line 2 / This is line 3») εμφανίζει τις τρεις γραμμές και το reversed_words.txt περιέχει «This is line 3 / This is line 2 / This is line 1».
Λεπτομέρειες: αν η τελευταία γραμμή του αρχείου δεν έχει \n, στο αντίστροφο αρχείο θα «κολλήσει» με την επόμενη — μπορούμε να το αποφύγουμε προσθέτοντας \n όπου λείπει (if not line.endswith('\n'): line += '\n'). Εναλλακτικά για την αντιστροφή: lines.reverse() και μετά for line in lines: fout.write(line), ή μια στοίβα (κεφ. 8). Python 3: input() αντί raw_input(), print(line, end='').
Σύνοψη: raw_input για το όνομα· open "r", for line in fin: print + append σε λίστα· open δεύτερου αρχείου "w" και write των στοιχείων της λίστας με range(len−1, −1, −1)· close().
Κριτήρια αξιολόγησης:
Ερώτηση: Τι πιστεύετε ότι θα συμβεί, όταν θα εκτελεστούν τα παρακάτω σενάρια. Τεκμηριώστε την άποψή σας. (my_list = [i**2 for i in range(1,11)] / f = open("output.txt", "w") / for item in my_list: f.write(str(item) + "\n") / f.close() / f = open("output.txt", "r") / print f.readline() / print f.read() / f.close() — σελ. 102)
Απάντηση:
Γραμμή προς γραμμή: ① my_list = [i**2 for i in range(1,11)] δημιουργεί (με «list comprehension») τη λίστα των τετραγώνων των 1…10: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]. ② open('output.txt', «w») δημιουργεί (ή αδειάζει, αν υπάρχει) το αρχείο. ③ Ο βρόχος γράφει κάθε τετράγωνο ως συμβολοσειρά (str(item), γιατί η write δεν δέχεται αριθμούς) ακολουθούμενο από αλλαγή γραμμής — το αρχείο αποκτά 10 γραμμές: 1, 4, 9, …, 100. ④ close() αποθηκεύει οριστικά τα δεδομένα.
⑤ Ανοίγουμε ξανά για ανάγνωση. ⑥ print f.readline() διαβάζει την πρώτη γραμμή «1\n» και την τυπώνει· επειδή η γραμμή περιέχει ήδη \n και η print προσθέτει δική της αλλαγή γραμμής, εμφανίζεται το 1 και μετά μία κενή γραμμή. ⑦ print f.read() διαβάζει το υπόλοιπο αρχείο από την τρέχουσα θέση (το αντικείμενο θυμάται πού έμεινε — σελ. 96) → τυπώνει τις γραμμές 4 έως 100, μία σε κάθε γραμμή, και στο τέλος πάλι μια κενή γραμμή. ⑧ close().
Έξοδος στην οθόνη:
1
4
9
16
25
36
49
64
81
100
Τεκμηρίωση: η readline και η read δεν ξεκινούν από την αρχή αλλά από τη θέση που έχει αφήσει η προηγούμενη ανάγνωση (fin.tell/seek, σελ. 96-97)· αν θέλαμε ξανά όλο το αρχείο θα καλούσαμε f.seek(0) πριν το read(). Αν το αρχείο ανοιγόταν με «a» αντί για «w» σε δεύτερη εκτέλεση, τα τετράγωνα θα προστίθεντο μετά τα παλιά (20 γραμμές).
Σύνοψη: Δημιουργείται το output.txt με 10 γραμμές (τα τετράγωνα 1…100)· η readline τυπώνει την πρώτη γραμμή «1» (+ κενή γραμμή λόγω \n) και η read το υπόλοιπο, 4 έως 100, γιατί η ανάγνωση συνεχίζει από την τρέχουσα θέση.
Κριτήρια αξιολόγησης:
Ερώτηση: Σε τι χρησιμεύει ένα αρχείο δεδομένων;
Απάντηση:
Σύνοψη: (ενδεικτική) Για μόνιμη αποθήκευση δεδομένων σε αποθηκευτικό μέσο, ώστε να μη χάνονται μετά την εκτέλεση και να μπορούν να διαβαστούν/ενημερωθούν από το πρόγραμμα (σε αντίθεση με τα προσωρινά δεδομένα της κύριας μνήμης).
Κριτήρια αξιολόγησης:
Ερώτηση: Ποιες βασικές λειτουργίες - μεθόδους υποστηρίζει η γλώσσα προγραμματισμού Python για τη διαχείριση αρχείων;
Απάντηση:
Σύνοψη: (ενδεικτική) open (r/w/a/r+), close/closed· write· read/readline/for line in· tell/seek· mode/name· os.rename, remove, mkdir, chdir, getcwd, rmdir.
Κριτήρια αξιολόγησης:
Ερώτηση: Με ποια συνάρτηση (μέθοδο) ανοίγουμε ένα αρχείο για ανάγνωση;
Απάντηση:
fin = open('words.txt', «r»). Επειδή το «r» είναι η προεπιλογή, αρκεί και fin = open('words.txt') (σελ. 91, 96).Σύνοψη: open("όνομα", "r") — ή απλώς open("όνομα"), αφού το "r" είναι προεπιλογή.
Κριτήρια αξιολόγησης:
Ερώτηση: Πώς ανοίγουμε ένα αρχείο για εγγραφή;
Απάντηση:
fin = open('words.txt', «w»). Αν το αρχείο δεν υπάρχει, δημιουργείται· αν υπάρχει, τα περιεχόμενά του διαγράφονται (σελ. 92).open('words.txt', «a») — επίσης δημιουργεί το αρχείο αν δεν υπάρχει. Με «r+» το αρχείο ανοίγει για ανάγνωση και εγγραφή. Μετά το άνοιγμα γράφουμε με write() και κλείνουμε με close().Σύνοψη: open("όνομα", "w") — δημιουργεί το αρχείο ή διαγράφει τα παλιά περιεχόμενα· open("όνομα", "a") για προσθήκη στο τέλος χωρίς διαγραφή.
Κριτήρια αξιολόγησης:
Ερώτηση: Με ποια συνάρτηση κλείνουμε ένα αρχείο;
Απάντηση:
fin.close() (σελ. 93).fin.closed → True).Σύνοψη: close() — π.χ. fin.close()· αποθηκεύει ό,τι είναι στη μνήμη και απελευθερώνει πόρους· έλεγχος με fin.closed.
Κριτήρια αξιολόγησης:
Ερώτηση: Με ποια συνάρτηση γράφουμε περιεχόμενο σε ένα αρχείο;
Απάντηση:
fin.write('This is line 4\n') (σελ. 94). Το αρχείο πρέπει να έχει ανοιχτεί με «w», «a» ή «r+».x = 52 / keimeno.write(str(x)).Σύνοψη: write(συμβολοσειρά) — π.χ. fin.write("This is line 4\n")· αριθμοί με str(), αλλαγή γραμμής με \n.
Κριτήρια αξιολόγησης:
Ερώτηση: Ποια συνάρτηση μπορούμε να χρησιμοποιήσουμε για να διαβάσουμε δεδομένα από μία γραμμή, από ένα αρχείο;
Απάντηση:
print fin.readline() → «This is line 1» (σελ. 96).for line in fin: print line. (Η read() διαβάζει χαρακτήρες — read(count) — ή όλο το υπόλοιπο, όχι κατά γραμμή.)Σύνοψη: readline() — διαβάζει ως τον χαρακτήρα νέας γραμμής και επιστρέφει τη γραμμή· η επόμενη κλήση δίνει την επόμενη γραμμή· εναλλακτικά for line in αρχείο.
Κριτήρια αξιολόγησης: