Τύποι δεδομένων στο pseudoglossa.gr

Ξεκίνησε από alkisg, 26 Ιουν 2011, 03:22:52 ΜΜ

« προηγούμενο - επόμενο »

alkisg

Στάθη, δοκίμασα το παρακάτω:

Κώδικας: Ψευδογλώσσα
Αλγόριθμος Συγκρίσεις
α ← 'Κείμενο'
Διάβασε α
Διάβασε β
Εμφάνισε α > β
Τέλος Συγκρίσεις


Και η οθόνη εισόδου/εξόδου πήγε ως εξής:
10
9
Αληθής


Γιατί το 10 είναι μεγαλύτερο από το 9; Δεν θα έπρεπε να θεωρηθούν ως αλφαριθμητικά και τα δύο;

sstergou

Το θέμα αυτό με είχε προβληματίσει πάρα πολύ.

Τότε είχα αποφασίσει ότι κατά την σύγκριση δύο τιμών πρέπει να γίνεται πρώτα έλεγχος για το αν αυτές οι τιμές ανάγονται σωστά σε αριθμούς. Αν ναι τότε γίνεται αριθμητική σύγκριση. Μου φάνηκε ότι με αυτό τον τρόπο εξασφάλιζα καλύτερη συμπεριφορά στην πλειοψηφία των προβλημάτων του ΑΕΠΠ αλλά γενικά είναι κάτι που πάνω στο οποίο θα ήθελα να ακούσω και άλλες γνώμες..

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

Λάμπρος Μπουκουβάλας

χαίρε (ξανά) Ευστάθιε τιτανομεγιστοτεράστιε!
Λάμπρος Μπουκουβάλας
MSc - MRes

http://blogs.sch.gr/lambrosbouk

Ο Θουκυδίδης  (που τον διαβάζουν οι ξένοι, αλλά όχι εμείς)  έγραφε: «Αταλαίπωρος τοις πολλοίς η ζήτησις της αληθείας, και επί τα ετοίμα μάλλον τρέπονται» (Ι, 20, 3). Οι περισσότεροι δηλαδή αναζητούν αβασάνιστα την αλήθεια και στρέφονται σε ό,τι βρίσκουν έτοιμο. Δεν προβληματίζονται...

Gnirut

#3
Παράθεση από: sstergou στις 26 Ιουν 2011, 04:57:29 ΜΜ
Το θέμα αυτό με είχε προβληματίσει πάρα πολύ.

Τότε είχα αποφασίσει ότι κατά την σύγκριση δύο τιμών πρέπει να γίνεται πρώτα έλεγχος για το αν αυτές οι τιμές ανάγονται σωστά σε αριθμούς. Αν ναι τότε γίνεται αριθμητική σύγκριση. Μου φάνηκε ότι με αυτό τον τρόπο εξασφάλιζα καλύτερη συμπεριφορά στην πλειοψηφία των προβλημάτων του ΑΕΠΠ αλλά γενικά είναι κάτι που πάνω στο οποίο θα ήθελα να ακούσω και άλλες γνώμες..

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

Προσωπική μου άποψη είναι ότι θα ήταν ορθότερο να βγάζει runtime error αν κάποιος προσπαθήσει να εκτελέσει σύγκριση ανάμεσα σε τιμές μεταβλητών με ανόμοιους (ή μη "παρόμοιους") τύπους παρά να μπλέξει το πράγμα με ελέγχους τύπων πριν την χρήση της σύγκρισης. Π.χ. τι θα έπρεπε να γίνεται εδώ:

...
(κάπου) Διάβασε a (← 'qwerty')
...
(κάπου αλλού) Διαβασε a (← 10)
...
b ← 9
Εμφάνισε a>b


Παρατήρηση: εαν γράψεις τέτοιου είδους κώδικα άλλες φορές το παιρνει, άλλες φορές χτυπάει λάθος στο δεύτερο Διάβασε, άλλες φορές χτυπάει και στο πρώτο εαν έχεις εκτελέσει ξανά το πρόγραμμα. Γενικά εμφανίζει διαφορετική εκτέλεση σε διαδοχικά Run. Δεν ξέρω αν φταίει κάτι στον browser μου ή αγνοώ κάτι εγώ.

alkisg

@Gnirut, σ' αυτήν την περίπτωση ο συντακτικός έλεγχος θα έπρεπε να είχε "αποφασίσει" ότι η μεταβλητή a είναι αριθμητική λόγω της σύγκρισης a > b. Έτσι, στην "Διάβασε a (← 'qwerty')" θα έπρεπε να χτυπήσει λάθος εκτέλεσης, ότι δεν μπορεί να ανατεθεί η τιμή 'qwerty' στην αριθμητική μεταβλητή a.

Για τη διαφορετική συμπεριφορά σε διαδοχικές εκτελέσεις, μάλλον ο Στάθης "θυμάται" τους περιορισμούς στους τύπους δεδομένων από τις προηγούμενες εκτελέσεις - αυτοί μάλλον θα ήταν καλύτερα να γίνονται reset στην αρχή κάθε εκτέλεσης (μόνο οι περιορισμοί που προκύπτουν κατά το runtime, όχι κατά το συντακτικό έλεγχο).

alkisg

Ένα άλλο δύσκολο θέμα σχετικά με το συντακτικό έλεγχο στην ψευδογλώσσα.
Στον παρακάτω αλγόριθμο, το β είναι αναγκαστικά ακέραιος επειδή συμμετέχει σε πράξη "div".
Από την εντολή "β ←  α" συνεπάγεται ότι και το α είναι αναγκαστικά ακέραιος.
Άρα η εντολή "α ←  3.4" θα έπρεπε να είναι συντακτικό λάθος. Σωστά;

Κώδικας: Ψευδογλώσσα
Αλγόριθμος ΣυντακτικόΛάθος
α ←  1
β ←  α
γ ←  β div 2
α ←  3.4
Εμφάνισε α, ' ', β, ' ', γ
Τέλος ΣυντακτικόΛάθος

evry

Και γιατί είναι να μην είναι λάθος η εντολή "γ ←  β div 2"  ?

Το σκεπτικό μου είναι ότι μπορούμε να παίρνουμε σαν ένδειξη για τον τύπο μιας μεταβλητής μόνο τις εκφράσεις στις οποίες λαμβάνει τιμή, άρα (στη ΓΛΩΣΣΑ) είναι στο αριστερό μέρος εκχώρησης.
Δηλαδή αυτές οι εκφράσεις έχουν μεγαλύτερη ισχύ από εκείνες στις οποίες υπολογίζεται η β.
Οι μεν πρώτες προκύπτουν άμεσα, ενώ οι δεύτερες αποτελούν "έμμεση" πληροφορία

Ένα παράδειγμα για συζήτηση.
Η παρακάτω έκφραση είναι σίγουρα λάθος. Το θέμα όμως είναι ποιο είναι το λάθος
β ←  β div 2 + 0.5

Φυσικά αυτό που λέω μπορεί να δημιουργήσει αρκετά παράδοξα, όπως για παράδειγμα να έχεις ένα πρόγραμμα 1000 γραμμών που να δουλεύει μια χαρά και στο τέλος να βάλεις μια "λάθος" εκχώρηση και να γίνει χαμός.

Πάντως για να μην μακρηγορώ, η άποψή μου είναι ότι στο παράδειγμα που δίνεις θα πρέπει η ψευδογλώσσα να μετατρέπει αμέσως το β σε ακέραιο και να κάνει την πράξη πετώντας ένα warning.

What I cannot create I do not understand -- Richard Feynman
http://evripides.mysch.gr

alkisg

Παράθεση από: evry στις 05 Ιουλ 2011, 12:50:58 ΜΜ
Και γιατί είναι να μην είναι λάθος η εντολή "γ ←  β div 2"  ?

Μου φαίνεται πιο λογικό το λάθος να αναφέρεται στο πρώτο σημείο που εντοπίζεται conflict, σαρώνοντας από πάνω προς τα κάτω, όπως κάνει (συνήθως) ένας διερμηνευτής / μεταγλωττιστής / άνθρωπος.


Παράθεση από: evry στις 05 Ιουλ 2011, 12:50:58 ΜΜ
Η παρακάτω έκφραση είναι σίγουρα λάθος. Το θέμα όμως είναι ποιο είναι το λάθος
β ←  β div 2 + 0.5

Για τον ίδιο λόγο, εδώ θα "αποτιμούσα" πρώτα τον τύπο δεδομένων του δεξιού μέλους και μετά του αριστερού, άρα σαν λάθος θα έλεγα: η μεταβλητή "β" είναι ακέραια, επομένως δεν μπορεί να της ανατεθεί η πραγματική έκφραση "β div 2 + 0.5".


Παράθεση από: evry στις 05 Ιουλ 2011, 12:50:58 ΜΜ
Πάντως για να μην μακρηγορώ, η άποψή μου είναι ότι στο παράδειγμα που δίνεις θα πρέπει η ψευδογλώσσα να μετατρέπει αμέσως το β σε ακέραιο και να κάνει την πράξη πετώντας ένα warning.

Άρα να μην το θεωρήσουμε συντακτικό λάθος; Δεν πρέπει να προειδοποιήσουμε τους μαθητές να διορθώσουν το πρόγραμμα, πριν καν αρχίσουν την εκτέλεσή του; Π.χ. ο πολλαπλασιασμός αλά ρωσικά θα έστεκε και χωρίς το ακέραιο μέρος;

evry

#8
ακριβώς εκεί είναι το πρόβλημα, ότι δεν μιλάμε για πρόγραμμα (ή μιλάμε και είμαι εκτός θέματος :-[)
αλλά για ψευδογλώσσα. Προφανώς σε ΓΛΩΣΣΑ θα ήταν λάθος δεν το συζητάμε, αλλά σε ψευδογλώσσα μου φαίνεται ότι το καλύτερο θα ήταν να το δεχτεί και να πετάξει ένα μήνυμα ότι υπάρχει αυτό το πρόβλημα και πιθανόν να βγει λάθος αποτέλεσμα αν δοθεί αριθμός με δεκαδικό μέρος.

Παράθεση από: alkisg στις 05 Ιουλ 2011, 01:09:17 ΜΜ
Άρα να μην το θεωρήσουμε συντακτικό λάθος; Δεν πρέπει να προειδοποιήσουμε τους μαθητές να διορθώσουν το πρόγραμμα, πριν καν αρχίσουν την εκτέλεσή του; Π.χ. ο πολλαπλασιασμός αλά ρωσικά θα έστεκε και χωρίς το ακέραιο μέρος;

Τώρα αυτό που λες με την αποτίμηση των εντολών στη σειρά που είναι, αυτό στο οποίο διαφωνώ είναι ότι όταν αποτιμάς το δεξί μέλος μιας παράστασης είναι συνηθισμένο να προκύπτει από εκεί πληροφορία για τον τύπο μιας μεταβλητής;
Αυτό δεν είναι κάποιος ποιο έμμεσο και λιγότερο ισχυρό από μια εκχώρηση στην οποία η μεταβλητή βρίσκεται στο αριστερό μέρος?

Δεν ξέρω πως λειτουργούν οι περισσότεροι compilers/interpreters. π.χ. η python που μοιάζει λίγο με την ψευδογλώσσα λειτουργεί έτσι? χρησιμοποιεί την έμμεση πληροφορία για να καθορίσει τον τύπο μιας μεταβλητής?  αυτό θα έχει ενδιαφέρον, θα το κοιτάξω
What I cannot create I do not understand -- Richard Feynman
http://evripides.mysch.gr

alkisg

#9
Ναι οκ κατά λάθος είπα "πρόγραμμα" παραπάνω, "αλγόριθμος" εννοούσα, γι' αυτό έδωσα και το παράδειγμα του πολλαπλασιασμού αλά ρωσικά.

Άλλες γλώσσες που υποστηρίζουν δυναμικούς τύπους δεδομένων συνήθως επιτρέπουν αλλαγή των τύπων κατά την εκτέλεση, αλλά αν κατάλαβα καλά από την παραπάνω συζήτηση, οι περισσότεροι καθηγητές δεν το θεωρούν αποδεκτό αυτό στην ψευδογλώσσα. Αντίθετα μάλιστα, θα περίμεναν μηνύματα λάθους από τον συντακτικό έλεγχο (όπως κι αν γίνεται αυτός, ακόμα κι από άνθρωπο).

Να ένα παράδειγμα από python, δίνοντας μερικές εντολές στον interpreter της:
$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> x="Hi"
>>> x=10
>>> x=x>10
>>> print x
False
>>> x=x+10
>>> print x
10


Υ.Γ. #1: θα θεωρούσαμε το παραπάνω αποδεκτό σε ψευδογλώσσα, έστω και με κάποια warnings κατά την εκτέλεση;
Υ.Γ. #2: σχετικά με το πώς μπορεί ένας διερμηνευτής/μεταγλωττιστής να εξάγει τον τύπο μιας μεταβλητής: http://en.wikipedia.org/wiki/Type_inference

sstergou

Παράθεση από: Gnirut στις 03 Ιουλ 2011, 01:22:25 ΠΜ
Παρατήρηση: εαν γράψεις τέτοιου είδους κώδικα άλλες φορές το παιρνει, άλλες φορές χτυπάει λάθος στο δεύτερο Διάβασε, άλλες φορές χτυπάει και στο πρώτο εαν έχεις εκτελέσει ξανά το πρόγραμμα. Γενικά εμφανίζει διαφορετική εκτέλεση σε διαδοχικά Run. Δεν ξέρω αν φταίει κάτι στον browser μου ή αγνοώ κάτι εγώ.

Μπορείς να δώσεις ένα παράδειγμα τέτοιου λάθους;

sstergou

Σχετικά με τους αριθμητικούς τύπους, η δική μου φιλοσοφία είναι η εξής :

Μία αριθμητική μεταβλητή είναι ακέραιου τύπου αν έχει ακέραια τιμή.  Ο ακέραιος τύπος είναι κάτι που "υπολογίζεται" μόνο όταν χρειάζεται, ενώ όταν δεν χρειάζεται η μεταβλητή έχει τον τύπο του αριθμού.

Έχουμε 2 περιπτώσεις όπου χρειάζεται οπωσδήποτε ακέραια έκφραση.
Αυτές είναι

  • Χρησιμοποίηση των τελεστών ακέραιας διαίρεσης
  • Δείκτης σε πίνακα

Στο pseudoglossa.gr οποτεδήποτε μία έκφραση είναι τελεστέος του div,mod ή δείκτης πίνακα τότε ελέγχεται η τιμή της και αποφασίζεται κατά την εκτέλεση αν αυτή είναι έγκυρη ή όχι.

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

Gnirut

Παράθεση από: sstergou στις 07 Ιουλ 2011, 02:24:49 ΜΜ
Μπορείς να δώσεις ένα παράδειγμα τέτοιου λάθους;

Δεν μπορώ να εντοπίσω ότι κάτι είναι λάθος.

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

Δεν ξέρω εαν αυτό είναι σφάλμα του διερμηνευτή ή σφάλμα στο συστήμα μου (browser, flash) ή ο διερμηνευτής όντως σχεδιάστηκε να αποθηκεύει κάπου τον τύπο των μεταβλητών ή κάτι αγνοώ εγώ και κάνω λάθος.

sstergou

Παράθεση από: Gnirut στις 08 Ιουλ 2011, 01:34:15 ΠΜ
Η εντύπωση που μου δίνεται είναι ότι και refresh να κάνω τη σελίδα o διερμηνευτής κρατάει τον τύπο κάποιων μεταβλητών από προηγούμενο τρέξιμο και εαν στο επόμενο τρέξιμο τον βάλεις να διαβάσει την ίδια μεταβλητή με άλλο τύπο χτυπάει λάθος. .

Κάτι τέτοιο δεν γίνεται. Κάθε φορά που δίνεται η εντολή της εκτέλεσης διαγράφονται τα δεδομένα της προηγούμενης.

Ίσως κάποιο άλλο πρόβλημα υπάρχει και δίνεται η εντύπωση της αποθήκευσης του τύπου των μεταβλητών.

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

Gnirut

Παράθεση από: sstergou στις 08 Ιουλ 2011, 10:31:49 ΠΜ
Κάτι τέτοιο δεν γίνεται. Κάθε φορά που δίνεται η εντολή της εκτέλεσης διαγράφονται τα δεδομένα της προηγούμενης.
Ίσως κάποιο άλλο πρόβλημα υπάρχει και δίνεται η εντύπωση της αποθήκευσης του τύπου των μεταβλητών.
Την επόμενη φορά που θα παρατηρήσεις κάτι τέτοιο κάνε τον κόπο αν μπορείς και στείλε μου ένα μήνυμα για να το διερευνήσω.

Βλέπω διαφορετικό type checking μεταξύ των παραδειγμάτων Α και Β και στο Γ γιατί συγκρίνει αριθμό με string;

Α.
Αλγόριθμος sdf
Διάβασε a
Διάβασε b
b ← 7
Εμφάνισε a, ' ', b, ' ', a > b
Τέλος sdf

qwerty
Η μεταβλητή έχει διαφορετικό τύπο από αυτόν με τον οποίο διαβάστηκε

44
qwerty
Η μεταβλητή έχει διαφορετικό τύπο από αυτόν με τον οποίο διαβάστηκε

43
56
43 7 Αληθής


Β.
Αλγόριθμος sdf
Διάβασε a
Διάβασε b
b ← 'qwerty'
Εμφάνισε a, ' ', b, ' ', a > b
Τέλος sdf

55
66
55 qwerty Ψευδής

55
multi
55 qwerty Ψευδής

aadvark
77
aadvark qwerty Ψευδής

zero
77
zero qwerty Αληθής

aadvark
zero
aadvark qwerty Ψευδής


Γ.
Αλγόριθμος sdf
Διάβασε a
Διάβασε b
Εμφάνισε a, ' ', b, ' ', a > b
Τέλος sdf

aadvark
zero
aadvark zero Ψευδής

5
aadvark
5 aadvark Ψευδής

aadvark
5
aadvark 5 Αληθής

sstergou

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

Στο Α :
το b ← 7 αναθέτει αριθμητικό τύπο στην b, οπότε από την στιγμή που συγκρίνεται με την a θα πρέπει και η a να είναι αριθμητική για αυτό και τα λάθη.

Στο Β :
Το b ← 'qwerty' αναθέτει αλφαριθμητικό τύπο στην b οπότε όλες οι υπόλοιπες συγκρίσεις είναι μεταξύ αλφαριθμητικών.

Στο Γ :
Όλες οι συγκρίσεις είναι μεταξύ αλφαριθμητικών

Νομίζω τα αποτελέσματα είναι προβλέψιμα. Η μόνη απρόβλεπτη συμπεριφορά (που όμως ήταν εν μέρει σκόπιμη) είναι αυτή που εντόπισε ο Άλκης μερικά μηνύματα πριν την οποία και θα διορθώσω σε επόμενη έκδοση.

Gnirut

Παράθεση από: sstergou στις 08 Ιουλ 2011, 08:47:41 ΜΜ
Νομίζω τα αποτελέσματα είναι προβλέψιμα.

Ναι τώρα που το εξήγησες τι γίνεται.
Γιατί δεν επιτρέπεται το διάβασμα λογικών μεταβλητών;

sstergou

Κατά την γνώμη μου οι λογικές σταθερές τιμές δεν είναι τιμές όπου προσφέρονται για αλληλεπίδραση με τον χρήστη.
Σε μια ενδεχόμενη ερώτηση του προγράμματος όπως η "θέλετε αύξουσα ταξινόμηση;" ο χρήστης δεν είναι υποχρεωμένος να ξέρει τις τιμές Αληθής ή Ψευδής, αντί αυτού είναι πιο σωστό να απαντήσει "Ναι" ή "Όχι" και μέσω αυτής της απάντησης να αρχικοποιηθεί η λογική μεταβλητή.