import os # Φορτώνει μια βιβλιοθήκη που αφορά το λειτουργικό σύστημα. # Χρησιμοποιείται μόνο για να καθαρίζουμε την οθόνη filename="mydata1.txt" # Σε αυτό το αρχείο αποθηκεύουμε το λεξικό με τη συνάρτηση save() και από αυτό το αρχείο # φορτώνουμε το λεξικό με τη συνάρτηση load() # Στη μεταβλητή Person (τύπου λεξικού) θα βρίσκεται αποθηκευμένη όλη η πληροφορία στο πρόγραμμά μας. # Με άλλα λόγια αυτή είναι η "βάση δεδομένων" μας. # Αρχικά είναι άδειο το λεξικό. # Έπειτα θα αντιστοιχεί σε κάθε άτομο μια εγγραφή στο λεξικό με κλειδί το όνομα ή ψευδώνυμο του ατόμου # (που πρέπει να είναι μοναδικό για κάθε άτομο) και με τιμή κλειδιού ένα ολόκληρο λεξικό με τα παρακάτω κλειδιά: # "firstname": η τιμή είναι ένα string με το όνομα του ατόμου # "lastname": η τιμή είναι ένα string με το επώνυμο του ατόμου # "phone": η τιμή είναι ένα string με το τηλέφωνο του ατόμου # Η μεταβλητή Person θα μπορούσε π.χ. να έχει την παρακάτω τιμή (ένα άτομο μόνο) # Person = { "Mihalis": {"firstname": "Mihalis", "lastname": "Kolountzakis", "phone": "2810393834"} } Person={} # Αυτή είναι η κύρια συνάρτηση και η μόνη συνάρτηση που καλείται από το κυρίως πρόγραμμα. def main(): load() # Φορτώνουμε τα δεδομένα που είναι αποθηκευμένα στο αρχείο και γεμίζουμε τη μεταβλητή Person while True: # Τρέχουμε συνεχώς στη συνάρτηση menu εκτός αν αυτή επιστρέψει 1 που είναι σημάδι ότι ret = menu() # ο χρήστης ζήτησε τερματισμό του προγράμματος if ret == 1: break input("Πάτα enter για να συνεχίσεις: ") # Αν αφαιρεθεί αυτή η γραμμή τότε η οθόνη καθαρίζει πολύ # γρήγορα και ο χρήστης δεν προλαβαίνει να δει τι τυπώθηκε από αυτά που ζήτησε. def donothing(): # Συνάρτηση που δεν κάνει απολύτως τίποτα return # Ανάλογη της input αλλά αν ο χρήστης πατήσει απλά Enter τότε η τιμή που επιστρέφει δεν είναι το κενό # string αλλά το όρισμα default (το οποίο υποδεικνύεται στο χρήστη μέσα σε [ .. ]) def inputd(text, default): s = input("{} [default: {}]".format(text, default)) if s=='': return default else: return s # Η συνάρτηση menu διαχειρίζεται την αλληλεπίδραση με το χρήστη σε ψηλό επίπεδο. # Ρωτάει το χρήστη τι θέλει να κάνει και καλεί τις κατάλληλες συναρτήσεις. def menu(): # Επιστρέφει 0 αν θέλουμε να συνεχίσει να καλείται # και 1 αν θέλουμε να σταματήσει να καλείται os.system("clear") # Μόνο για Linux. Για windows γράψτε "cls" αντί για "clear". print("---------------------------------------------------") print("Επιλέξτε") print() for d in fnc: # Εδώ τυπώνονται όλες οι λειτουργίες που είναι διαθέσιμες στο χρήστη print(" {}: {}".format(d["letter"], d["text"])) # με την περιγραφή τους και το γράμμα επιλογής τους print("---------------------------------------------------") print() # Η επιλογή του χρήστη υποδεικνύεται με ένα γράμμα, μοναδικό ανά εντολή. choice = input(" Η επιλογή σας: ") # Ζητάμε από το χρήστη να επιλέξει λειτουργία. for d in fnc: # Καλούμε τη συνάρτηση που αντιστοιχεί στο γράμμα που επέλεξε ο χρήστης if choice == d["letter"]: d["function"]() break if choice=="q": # Αν ο χρήστης επέλεξε τέλος τότε επιστρέφουμε 1 return 1 else: return 0 # Η συνάρτηση αυτή, που δεν καλείται από την menu, αλλα από άλλες συναρτήσεις # δείχνει απλά μαι εγγραφή της βάσης στο χρήστη def showperson(name): # Τυπώνουμε στοιχισμένα τα στοιχεία του ατόμου με κλειδί name print("*** {:10.10} --> Όνομα: [{:10.10}] Επώνυμο: [{:20.20}] Αριθμ. Τηλ. [{:15.15}]".format( name, Person[name]["firstname"], Person[name]["lastname"], Person[name]["phone"])) # Δείχνει όλες τις εγγραφές στο χρήστη (αλφαβητική σειρά κλειδιού) def show(): for p in sorted(Person.keys()): showperson(p) # Αναζήτηση κλειδιού στη βάση def search(): k = input("Δώστε το μικρό όνομα του ατόμου: ").strip() # Ο ρόλος του strip είναι να απαλλαγούμε από if k not in Person.keys(): # κενούς χαρακτήρες στο τέλος της απάντησης του χρήστη print("Δεν υπάρχει τέτοιο όνομα") return L = Person[k] # Το βρήκαμε και φέρνουμε τα στοιχεία του αό τη βάση. showperson(k) # Τα δείχνουμε # Εισαγωγή νέου ατόμου στη βάση def insert(): name = input("Δώστε το μικρό όνομα για καταχώρηση: ").strip() if name in Person.keys(): print("Υπάρχει ήδη. Sorry.") # Το όνομα που ζήτησε να εισαχθεί υπάρχει ήδη return firstname = inputd("Δώστε το όνομα: ", name) # Ειδικά για το firstname προτείνουμε στο χρήστη default τιμή το κλειδί της εγγραφής lastname = input("Δώστε το επώνυμο: ") # Νέο όνομα. Ζητάμε από το χρήστη τα στοιχεία του. phone = input("Δώστε το τηλέφωνο: ") Person[name] = { "firstname": firstname, "phone": phone, "lastname": lastname } # Νέα εγγραφή στη βάση. # Διαγραφή ατόμου def delete(): name = input("Δώστε το μικρό όνομα για διαγραφή: ").strip() if name not in Person.keys(): print("Δεν υπάρχει.") # Το όνομα που ζήτησε να διαγραφεί δεν υπάρχει return del Person[name] # Διαγραφή # Τροποποίηση στοιχείων ατόμου def edit(): name = input("Δώστε το μικρό όνομα για τροποποίηση: ").strip() if name not in Person.keys(): print("Δεν υπάρχει. Sorry.") return firstname = Person[name]["firstname"] lastname = Person[name]["lastname"] phone = Person[name]["phone"] showperson(name) # Ρωτάμε το χρήστη για τις νέες τιμές με dedault τιμές τις παλιές newfirstname = inputd("Δώστε νέο όνομα", firstname).strip() newlastname = inputd("Δώστε νέο επώνυμο", lastname).strip() newphone = inputd("Δώστε νέο τηλέφωνο", phone).strip() Person[name] = { "firstname": newfirstname, "phone": newphone, "lastname": newlastname} # Τροποποιούμε την τιμή του κλειδιού name στο λεξικό. # Αποθήκευση του λεξικού στο αρχείο με όνομα filename def save(): f = open(filename, "w") # Ανοίγουμε το αρχείο για γράψιμο N = len(Person) print(N, file=f) # Στην πρώτη γραμμή γράφουμε το πλήθος των εγγραφών (για πιο εύκολο διάβασμα) for p in Person.keys(): # Για κάθε εγγραφή στη βάση μας γράφουμε 4 διαδοχικές γραμμές στο αρχείο print(p, file=f) # Στην πρώτη το όνομα print(Person[p]["firstname"], file=f) # Στη δεύτερη το επώνυμο print(Person[p]["lastname"], file=f) # Στη δεύτερη το επώνυμο print(Person[p]["phone"], file=f) # Στην τρίτη το τηλέφωνο f.close() # Κλείνουμε το αρχείο # Γεμίζουμε το λεξικό μας από το αρχείο (που είναι γραμμένο όπως το γράφει η συνάρτηση load). def load(): global Person # Εδώ πρέπει να δηλωθεί το Person ως global μεταβλητή αλλιώς η συνάρτηση load τη θεωρεί τοπική. # Ο λόγος είναι ότι η πρώτη πρόσβαση που γίνεται στην Person είναι εγγραφή και όχι ανάγνωση. # Δε θα έβλαπτε γενικά να δηλώναμε την Person ως global μεταβλητή σε κάθε συνάρτηση σε αυτό το πρόγραμμα. try: # Δοκιμάζουμε να ανοίξουμε το αρχείο. Αν υπάρξει πρόβλημα εκτελούνται οι γραμμές του except: f = open(filename, "r") # Ανοίγουμε το αρχείο για διάβασμα. except: print("Δεν μπορώ να ανοίξω το αρχείο {}".format(filename)) input("Πατήστε enter για συνέχεια") return # ***** Ως έχει θα αποτύχει και θα παρουσιάσει σφάλμα αν το αρχείο με όνομα filename δεν υπάρχει # ***** ή, για κάποιο άλλο λόγο, δε μπορεί να ανοιχθεί.. L = [ s.strip() for s in f.readlines() ] # Διαβάζουμε όλες τις γραμμές του αρχείου στη λίστα L. # Τώρα κάθε στοιχείο της L είναι ένα string, η αντίστοιχη γραμμή του αρχείου (χωρίς newline και κενά στο τέλος). N = int(L[0]) # Από την πρώτη γραμμή διαβάζουμε το πλήθος των εγγραφών. Person = {} # Μηδενίζουμε το λεξικό. for i in range(N): # Για κάθε άτομο που είναι στο αρχείο name = L[4*i+1] # παίρνουμε τα στοιχεία του από τη λίστα L firstname = L[4*i+2] lastname = L[4*i+3] phone = L[4*i+4] Person[name] = {"phone": phone, "firstname": firstname, "lastname": lastname} # και το προσθέτουμε στο λεξικό. f.close() # κλείνουμε το αρχείο. print("Διαβάστηκαν {} εγγραφές".format(N)) # Στην λίστα fnc βρίσκονται αποθηκευμένες όλες οι λειτουργίες του προγράμματος που τυπώνονται από την menu(). # Σε κάθε στοιχείο της λίστας έχουμε ένα λεξικό που περιγράφει το κείμενο που περιγράφει τη συνάρτηση ("text"), # το γράμμα επιλογής της συνάρτησης ("letter") και τη συνάρτηση που πρέπει να κληθεί σε αυτή την περίπτωση ("function") fnc = [ {"text": "Δείξτε όλο τον τηλεφωνικό κατάλογο", "letter": "s", "function": show}, {"text": "Αναζήτηση ατόμου", "letter": "?", "function": search}, {"text": "Προσθήκη ατόμου", "letter": "i", "function": insert}, {"text": "Διαγραφή ατόμου", "letter": "d", "function": delete}, {"text": "Τροποποίηση ατόμου", "letter": "e", "function": edit}, {"text": "Σώστε τον κατάλογο στο δίσκο", "letter": ">", "function": save}, {"text": "Φορτώστε τον κατάλογο από το δίσκο", "letter": "<", "function": load}, {"text": "Κλείσιμο του προγράμματος", "letter": "q", "function": donothing}, ] main()