Κοινοποίησε

Αξιολόγηση Χρήστη: 5 / 5

Αστέρια ΕνεργάΑστέρια ΕνεργάΑστέρια ΕνεργάΑστέρια ΕνεργάΑστέρια Ενεργά
 

Στους τοπογράφους μηχανικούς είναι σίγουρο ότι κάποια στιγμή θα χρειαστεί η κατασκευή κώδικα αριθμητικής επεξεργασίας δεδομένων ή επίλυσης κάποιου προβλήματος. Η γλώσσα προγραμματισμού python είναι ένα από τα εργαλεία που μπορούν να χρησιμοποιηθούν. Είδαμε δύο τρόπους αριθμητικής αποσφαλμάτωσης του κώδικα. Στο παρόν άρθρο θα οργανώσουμε την αποσφαλμάτωση, με μορφή συναρτήσεων, για να αποφύγουμε την διόγκωση του κώδικα όταν έχουμε εισαγωγή πολλαπλών αριθμητικών δεδομένων.

Python σχόλια - εισαγωγή δεδομένων

Έμπνευση για το χρησιμοποιούμενο παράδειγμα στο άρθρο μας αποτελεί το πρόβλημα της οπισθοτομίας στην τοπογραφία.

Όπως φαίνεται και στο παραπάνω σχήμα, κατά την επίλυση της οπισθοτομίας, σε κάποιο στάδιό της, χρειάζονται 6 αριθμητικά δεδομένα: οι γωνίες γ1, γ2, γ3 και γΑ, γΒ, γΓ.

Σε κάποιο στάδιο υπολογισμών χρησιμοποιείται το ανωτέρω τυπολόγιο, στο οποίο συμμετέχουν οι 6 γωνίες προκειμένου να υπολογιστούν οι 3 νέες παράμετροι k1, k2 και k3.

Ας δούμε πόσα είδη και πλήθη αριθμητικών σφαλμάτων θα μπορούσαν να εμφανιστούν στο παραπάνω τυπολόγιο:

  • αναφορικά με τα σφάλματα αλφαριθμητικής καταχώρησης (πχ "1.ς" αντί για "1.2") έχουμε πλήθος σφαλμάτων έξι
  • αναφορικά με τα σφάλματα διαίρεσης με το μηδέν ή περίπου με το μηδέν:
    • έξι εφαπτόμενες στον παρονομαστή
    • τρεις αλγεβρικές παραστάσεις στον παρονομαστή

Δηλαδή 6 + 6 +3 = 15 σφάλματα συνολικά. Είναι πολλά και θα πρέπει να οργανώσουμε τον κώδικα με την σειρά.

Παράδειγμα αλφαριθμητικής αποσφαλμάτωσης (ValueError) με συνάρτηση

Ξεκινούμε με την δημιουργία της συνάρτησης αποσφαλμάτωσης getnumber. Θέτουμε τις εξής βασικές αρχές σχετικά με το πως θέλουμε να λειτουργήσει η getnumber:

  1. να λαμβάνει την τιμή που πληκτρολόγησε ο χρήστης σε αλφαριθμητική μορφή
  2. αν ο χρήστης πληκτρολόγησε μόνο Enter, τότε να ενημερώνει ότι σταματά η εκτέλεση του προγράμματος
  3. αν ο χρήστης πληκτρολόγησε τιμή με σφάλμα (πχ "1.ς" αντί για 1.2):
    1. να ενημερώνεται ο χρήστης σχετικά και
    2. να ζητείται ξανά η εισαγωγή του αριθμού
  4. τα μηνύματα του κώδικα να είναι παραμετροποιήσιμα ώστε ο χρήστης να καταλαβαίνει ποιά γωνία του ζητείται ή σε ποια γωνία συνέβει το σφάλμα

Οι παραπάνω απαιτήσεις καθορίζουν και την δομή που θα έχει ο κώδικας για την συνάρτηση getnumber, δηλαδή:

  1. η απαίτηση 1 υλοποιείται με την εντολή input και η εισαχθείσα τιμή αποθηκεύεται στην παράμετρο x
  2. η απαίτηση 2 υλοποιείται ελέγχοντας, με ένα μπλοκ if εάν η παράμετρος x είναι κενή περιεχομένου
  3. η απαίτηση 3 (το πρώτο μέρος της) υλοποιείται χρησιμοποιώντας ένα μπλοκ try except μέσα στο οποίο τοποθετούνται τα μπλοκ των input και if
  4. η απαίτηση 4 υλοποιείται θέτοντας 2 ορίσματα στην συνάρτηση getnumber, το msginp και το msgerr
    1. το msginp περιέχει το μήνυμα που διαβάζει ο χρήστης όταν του ζητείται να δώσει μια γωνία
    2. το msgerr περιέχει το μήνυμα που διαβάζει ο χρήστης όταν ενημερώνεται για ποια γωνία υπάρχει σφάλμα
  5. η απαίτηση 3 (το δεύτερο μέρος της) υλοποιείται με το μπλοκ της εντολής while και την βοηθητική παράμετρο verr, όλες οι προηγούμενες εντολές εκτελούνται κάτω από την επαναληπτική εντολή while για όσο η verr ισούται με True, δηλαδή για κάθε φορά που ο χρήστης πληκτρολόγησε λάθος τιμή, όταν ο χρήστης δώσει σωστή τιμή η επανάληψη σταματά και ο κώδικας επιστρέφει στην παράμετρο g1 αυτή την τιμή με μορφή κινητής υποδιαστολής.
import math as mt # Εισαγωγή βιβλιοθήκης μαθηματικών συναρτήσεων
#Έναρξη συνάρτησης αλφαριθμητικής αποσφαλμάτωσης
def getnumber(msginp,msgerr):
 verr=True #Αρχικοποίησε την βοθητική παράμετρο αναγνώρισης σφάλματος
 while (verr==True):
  try: #Έναρξη μπλοκ try except
   x=input(msginp) #Αποθήκευση εισαχθείσας τιμής σε αλφαριθμητική μορφή
   if (x==""): #Έλεγχος για το αν ο χρήστης επέλεξε να βγει έξω από το πρόγραμμα πατώντας μόνο Enter
    print("Πάτησες μόνο Enter, βγαίνω από το πρόγραμμα")
    exit()
   x=float(x) #Εδώ ενεργεί η εντολή float για μετατροπή της αλφαριθμητικής σε αριθμητική τιμή
   verr=False #Αφού έφτασα μέχρι εδώ δεν υπάρχει σφάλμα και συνεπώς...
   return x #Επιστροφή στην συνάρτηση της τιμής ως αριθμός κινητής υποδιαστολής 
  except ValueError: #Αν η μετατροπή σε float απέτυχε τότε...
   print(msgerr) #Ενημέρωσε χρήστη με μήνυμα
   verr=True #Θέσε την βοηθητική παράμετρο verr σε κατάσταση σφάλματος ώστε να ξαναεκτελεστεί το μπλοκ της while
#Λήξη συνάρτησης αλφαριθμητικής αποσφαλμάτωσης

#Χρήση της συνάρτησης getnumber για την γωνία γ1
g1=getnumber("Δώσε την γωνία γ1 σε grad:","Η γωνία γ1 δεν είναι αποδεκτός αριθμός!")
#Μήνυμα του κώδικα ότι έφτασε στο τέλος του
print("Έφτασα στο τέλος του κώδικα. Έξοδος από το πρόγραμμα.")

Αντίγραψε τον κώδικα και κλικ εδώ για να τον εκτελέσεις και δεις το αποτέλεσμα.

Παράδειγμα αποσφαλμάτωσης διαίρεσης με το μηδέν με συνάρτηση

Συνεχίζουμε έχοντας ως γνώμωνα ότι θα πρέπει να υπολογίσουμε, ας πούμε, τουλάχιστον την τιμή k1. Για να υπολογίσουμε την τιμή k1, χρειαζόμαστε τις γωνίες γ1 και γΑ. Έχοντας θωρακίσει τον χρήστη από σφάλματα αλφαριθμητικά για μια τυχαία γωνία, μπορούμε με ασφάλεια πλέον να χρησιμοποιήσουμε την συνάρτηση getnumber, μία φορά για την γωνία γ1 και μία φορά για την γωνία γΑ.

Μέχρι εδώ όλα καλά, ξέρουμε όμως ότι αν κάποια από τις γωνίες είναι μηδέν ο διερμηνέας θα διακόψει την ροή λόγω σφάλματος διαίρεσης με το μηδέν. Ξέρουμε επίσης ότι πρέπει να αποφεύγουμε γωνίες κοντά στο μηδέν ή κοντά σε πολλαπλάσια του 100g ή του 200g διότι μειώνουν την υπολογιστική ακρίβεια των ενδιάμεσων παραμέτρων. Άρα θα πρέπει να προστατέψουμε τον χρήστη του κώδικα με ανάλογους ελέγχους και ενημερωτικά μηνύματα. Το ίδιο θα πρέπει να κάνουμε και στην περίπτωση που οι γωνίες γ1 και γΑ είναι ίσες ή πολύ κοντινές.

Επομένως οι βασικές αρχές που πρέπει να προστεθούν είναι, ο κώδικας:

  1. να αποτρέπει τιμές γωνίας που δίνουν εφαπτόμενη ίση με μηδέν ή πολύ κοντά στο μηδέν, να ενημερώνει για αυτό και να κόβει την ροή του προγράμματος
  2. να αποτρέπει τιμές για τις γωνίες γ1 και γΑ είτε ίσες είτε πολύ κοντινές που μπορεί να δώσουν τιμή στον παρονομαστή του k1 κοντά στο μηδέν.

Η υλοποίηση των πρόσθετων απαιτήσεων γίνεται με τροποποίηση του παραπάνω κώδικα ως εξής:

  1. μετατρέπουμε την εντολή return x (μέσα στην συνάρτηση getnumber) σε σχόλιο βάζοντας μπροστά το καγκελάκι #, με αυτό τον τρόπο, εφόσον η γωνία έγινε διασφαλισμένα αποδεκτή ως αριθμός, η ροή προχωράει έξω από το μπλοκ της εντολής while και εισέρχεται στο νέο προστιθέμενο μπλοκ if else, και εδώ εφόσον η γωνία δίνει εφαπτόμενη κατά απόλυτη τιμή πάνω από ένα όριο, η γωνία γίνεται αποδεκτή και η συνάρτηση getnumber επιστρέφει την τιμή της στην αντίστοιχη παράμετρο g1 ή gA, ειδάλλως διακόπτεται η ροή και εμφανίζεται σχετικό μήνυμα ότι παράγεται εφαπτόμενη με τιμή κοντά στο μηδέν
  2. δημιουργούμε μία νέα συνάρτηση, την kappa, την οποία τροφοδοτούμε με τις διασφαλισμένες τιμές των γ1 και γΑ, υπολογίζουμε τον παρονομαστή της παραμέτρου k1 και ελέγχουμε εαν κατά απόλυτη τιμή είναι μεγαλύτερος από το όριο που θέσαμε, εφόσον είναι υπολογίζεται η τιμή της παραμέτρου και επιστρέφεται στην παράμετρο k1, αν όμως δεν είναι διακόπτεται η ροή και εμφανίζεται σχετικό μήνυμα ότι παράγεται παρονομαστής με τιμή κοντά στο μηδέν (αυτό μπορεί να συμβεί μόνο αν οι γωνίες γ1 και γΑ είναι ίσες ή πολύ κοντινές)
import math as mt # Εισαγωγή βιβλιοθήκης μαθηματικών συναρτήσεων
#Έναρξη συνάρτησης αλφαριθμητικής αποσφαλμάτωσης
def getnumber(msginp,msgerr,msgdvzerr,limit):
 verr=True #Αρχικοποίησε την βοθητική παράμετρο αναγνώρισης σφάλματος
 while (verr==True):
  try: #Έναρξη μπλοκ try except
   x=input(msginp) #Αποθήκευση εισαχθείσας τιμής σε αλφαριθμητική μορφή
   if (x==""): #Έλεγχος για το αν ο χρήστης επέλεξε να βγει έξω από το πρόγραμμα πατώντας μόνο Enter
    print("Πάτησες μόνο Enter, βγαίνω από το πρόγραμμα")
    exit()
   x=float(x) #Εδώ ενεργεί η εντολή float για μετατροπή της αλφαριθμητικής σε αριθμητική τιμή
   verr=False #Αφού έφτασα μέχρι εδώ δεν υπάρχει σφάλμα και συνεπώς...
   #return x #Επιστροφή στην συνάρτηση της τιμής ως αριθμός κινητής υποδιαστολής 
  except ValueError: #Αν η μετατροπή σε float απέτυχε τότε...
   print(msgerr) #Ενημέρωσε χρήστη με μήνυμα
   verr=True #Θέσε την βοηθητική παράμετρο verr σε κατάσταση σφάλματος ώστε να ξαναεκτελεστεί το μπλοκ της while
 pi=mt.pi #Ανάκτηση τιμής του π μέσα από την βιβλιοθήκη
 if (abs(mt.tan(x/200.0*pi))>limit):
  return x
 else:
  print(msgdvzerr)
  exit()
#Λήξη συνάρτησης αλφαριθμητικής αποσφαλμάτωσης και ελέγχου διαίρεσης με χαμηλές τιμές

#Έναρξη συνάρτησης kappa αποσφαλμάτωσης εφαπτομένων
def kappa(g1,gA,msgdvzerr,limit):
 #Οι τιμές γ1 και γΑ διασφαλισμένα πλέον δεν δίνουν μηδέν στην εφαπτόμενη
 k=1/mt.tan(gA)-1/mt.tan(g1)
 #Έλεγχος εάν οι τιμές γ1 και γΑ είναι ίσες ή πολύ κοντά, δηλαδή αν ο παρονομαστής του k είναι κοντά στο 0
 if (abs(k)>limit):
  return 1.0/k
 else:
  print(msgdvzerr)
  exit()
#Λήξη συνάρτησης kappa αποσφαλμάτωσης εφαπτομένων

limit=0.001 #Όριο ελέγχου χαμηλών τιμών εφαπτόμενων
pi=mt.pi #Ανάκτηση τιμής του π μέσα από την βιβλιοθήκη
#Χρήση της συνάρτησης getnumber για την γωνία γ1
g1=getnumber("Δώσε την γωνία γ1 σε grad:","Η γωνία γ1 δεν είναι αποδεκτός αριθμός!","Η γωνία γ1 δίνει εφαπτόμενη κοντά στο μηδέν!",limit)/200.0*pi
#Χρήση της συνάρτησης getnumber για την γωνία γA
gA=getnumber("Δώσε την γωνία γA σε grad:","Η γωνία γA δεν είναι αποδεκτός αριθμός!","Η γωνία γΑ δίνει εφαπτόμενη κοντά στο μηδέν!",limit)/200.0*pi
#Τώρα πλέον μπορεί το k1 να υπολογιστεί ασφαλώς
k1=kappa(g1,gA,"Οι γωνίες γΑ και γ1 είναι ίσες ή πολύ κοντινές. Έξοδος από το πρόγραμμα.",0.001)
print("k1={0:5.8f}\n".format(k1))
#Μήνυμα του κώδικα ότι έφτασε στο τέλος του
print("Έφτασα στο τέλος του κώδικα. Έξοδος από το πρόγραμμα.")

Αντίγραψε τον κώδικα και κλικ εδώ για να τον εκτελέσεις και δεις το αποτέλεσμα.

Ανάλογοι πρόσθετοι έλεγχοι μπορούν να γίνουν και για γωνίες που εκτινάσουν την εφαπτομένη στο άπειρο.

.

Διάβασε επίσης:

 

Η Kemioteko Engineering δημιουργήθηκε ως απόσταγμα εμπειριών 14 ετών στην αδειοδότηση, κατασκευή και λειτουργία δημόσιων τεχνικών έργων και 8 ετών στο ελεύθερο επάγγελμα του μελετητή μηχανικού με εξειδίκευση στην αδειοδότηση και λειτουργία επιχειρήσεων. Αποστολή της Kemioteko Engineering - Χατζηλιόντος Ι. Χριστόδουλος είναι η δημιουργία πελατών, οπαδών της, βαθειά ικανοποιημένων, που θέλουν να κάνουν διαχρονικά τα σωστά πράγματα με τους κατάλληλους συνεργάτες.

 

Διπλ. Χημικός Μηχανικός ΕΜΠ - Msc Περιβαλλοντικού Σχεδιασμού
Αγρονόμος Τοπογράφος Μηχανικός ΑΠΘ - 5ο Εξάμηνο
Επιθεωρητής Ξενοδοχείων - ΕΕΔΔ - TUV Austria RCN 6035/2016
Επιθεωρητής ISO 9001 - TUV Austria RCN 6065/2016
Επιθεωρητής ISO 45001 - Alison 1412-13849119
Επιθεωρητής GDPR - Alison 1401-13849119
Ενεργειακός Επιθεωρητής - No 16109 | No 553
Μελετητής ΥΠΕΧΩΔΕ - No 26837 - 18-A & 27-A
ΑΜ ΤΕΕ - No 83488 | ΤΕΧΝΙΚΟΣ ΑΣΦΑΛΕΙΑΣ. 330512/2017
Μητρώο Αξιολογητών ΓΓΕΤ- No 14856/95711/08-06-17
Ελεγκτής Δόμησης - No 4517
τηλ +302399-022359
Βασ Πιτσούλη 1, TK 63080, Νέα Καλλικράτεια
Χαλκιδική, Ελλάδα | http://kemioteko.gr
Μελετητικές Υπηρεσίες Βιομηχανικών & Περιβαλλοντικών Εγκαταστάσεων:
Σχεδιασμός, Αδειοδότηση, Διαχείριση Ποιοτικού Ελέγχου & Κατασκευών,
Οργανολογία & Ρύθμιση, Λειτουργία & Συντήρηση
Follow us 
 facebook  twitter  linkedin  googleplus  pinterest  youtube  twitter