Συζήτηση
Γεια χαρά, Επισκέπτης
Όνομα χρήστη: Κωδικός: Να με θυμάσαι

ΘΕΜΑ: Τόσα χρόνια στην Python και δεν το γνώριζα αυτό!

Τόσα χρόνια στην Python και δεν το γνώριζα αυτό! 6 Χρόνια 11 Μήνες πριν #4381

  • babaliaris1
  • Το Άβαταρ του/της babaliaris1
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 445
  • Ληφθείσες Ευχαριστίες 75
Ας γίνει μάθημα αυτό το θέμα και για όσους δεν το γνωρίζουν :)

Έχω να κάνω μια εργασία για την σχολή μου στην οποία χρειάζεται να υλοποιήσεις κάποιες δομές
δεδομένων. Τέλος πάντων, σήμερα όλη μέρα (κυριολεκτικά) έφτιαχναν ένα B tree και για καμιά 10 ώρες περίπου δεν μπορούσα να λύσω ένα bug. Η κλάση μου ήταν ορισμένη κάπως έτσι:
import struct
 
class BNode:
 
    children          = []
    word              = []
    index             = []
    parent            = -1
    page              = -1
    totalAmountOfKeys = 0
    maxChildren       = 0
    uselessBytes      = 0
    bufferSize        = 0
 
 
    #-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-Constructor-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-#
    def __init__(self, bufferSize):
        '''Initialize the node.'''
 
        #Lets say, k = keys and k+1 = Order of Btree.
        #How many keys can i have? (page+parent = 8).
 
        # k*16 + (k+1)*4 + 8 <= bufferSize
        # k*16 + 4*k + 4 + 8 <= bufferSize
        # 20*k + 12 <= bufferSize
        # k <= (bufferSize - 12) / 20
 
        self.totalAmountOfKeys = k = (bufferSize - 12) // 20
        self.maxChildren       = c = self.totalAmountOfKeys + 1
        self.uselessBytes      = bufferSize - (k*16 + c*4 + 8)
        self.bufferSize        = bufferSize
 
 
        #Initialize the children array.
        for i in range(self.maxChildren):
            self.children.append(-1)
            pass
 
        #Initialize the key pairs.
        for i in range(self.totalAmountOfKeys):
            self.word.append("123456789ASD")
            self.index.append(-1)
            pass
 
        return
    #-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-Constructor-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-#
 
 
 
 
    #==================================Write==================================#
    def write(self, file, page):
 
        #Seek into the file.
        file.seek(self.bufferSize * page)
 
        #Create the buffer.
        buffer = bytes()
 
        #----------Add to the buffer all the pairs of (word, index)----------#
        for i in range( len(self.word) ):
            buffer += str.encode(self.word[i]) + struct.pack("i", self.index[i])
            pass
        #----------Add to the buffer all the pairs of (word, index)----------#
 
 
        #-------------------Add to the buffer the children-------------------#
        for child in self.children:
            buffer += struct.pack("i", child)
            pass
        #-------------------Add to the buffer the children-------------------#
 
        #Add the page.
        buffer += struct.pack("i", self.page)
 
        #Add the parent.
        buffer += struct.pack("i", self.parent)
 
        #Fill the remaining space with spaces.
        for i in range( self.uselessBytes ):
            buffer += str.encode(" ")
            pass
 
        #Write the buffer and return the
        #number of bytes written.
        return file.write(buffer)
    #==================================Write==================================#
 
 
 
 
    #==================================Read===================================#
    def read(self, file, page):
 
        #Seek into the file.
        file.seek(self.bufferSize * page)
 
        #Create the buffer.
        buffer   = file.read(self.bufferSize)
 
 
        #----------Get the (word, index) pairs----------#
        counter  = 0
        for i in range(0, self.totalAmountOfKeys * 16, 16):
            self.word [counter] = bytes.decode( buffer[i:i+12] )
            self.index[counter] = struct.unpack("i", buffer[i+12:i+16] ) [0]
            counter += 1
            pass
        #----------Get the (word, index) pairs----------#
 
 
 
        #----------------Get the children---------------#
        counter    = 0
        start      = self.totalAmountOfKeys * 16
        end        = start + self.maxChildren * 4
        for i in range(start, end, 4):
            self.children[counter] = struct.unpack("i", buffer[i:i+4] )[0]
            counter += 1
            pass
        #----------------Get the children---------------#
 
 
        #Get page and parent.
        self.page   = struct.unpack("i", buffer[end:end+4])[0]
        self.parent = struct.unpack("i", buffer[end+4:end+8])[0]
 
        #Return the amount of readen bytes.
        return len(buffer)
    #==================================Read===================================#
 
 
 
 
 
    #=================================Is Leaf=================================#
    def isLeaf(self):
        '''Returns True, if the node is a leaf.'''
 
        for child in self.children:
            if child != -1 : return False
 
        return True
    #=================================Is Leaf=================================#
 
 
 
 
    #=================================Is Full=================================#
    def isFull(self):
        '''Returns True, if the node is full of children.'''
 
        for child in self.children:
            if child == -1 : return False
 
        return True
    #=================================Is Full=================================#
 
 
 
 
    #==================================Print==================================#
    def print(self):
        '''This method is for debugging.'''
 
        print("Is Leaf\t\t:",self.isLeaf())
        print("Is Full\t\t:",self.isFull())
        print("Page\t\t:",self.page)
        print("Parent\t\t:",self.parent)
        print("Keys\t\t:",self.totalAmountOfKeys)
        print("Max Children\t:",self.maxChildren)
        print("Useless Bytes\t:",self.uselessBytes)
 
        print()
        for i in range( self.totalAmountOfKeys ):
            print("Word["+str(i)+"]:",self.word[i],", Index["+str(i)+"]:",self.index[i])
            pass
 
        print()
        for i in range( self.maxChildren ):
            print("Child["+str(i)+"]:",self.children[i])
            pass
 
        return
    #==================================Print==================================#

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

Εγώ τόσο καιρό νόμιζα ότι αν δηλώσεις μια μεταβλητή απευθείας στην κλάση:
class Test:
    petros = ""

Είναι το ίδιο σαν να κάνεις:
class Test:
    pass
 
obj = Test()
obj.petros = ""

Αλλά τελικά λειτουργούν σαν στατικές μεταβλητές.

Πως γίνεται να μην το γνώριζα αυτό, 7 χρόνια στην python lol!!!
Τελικά όσο ζεις μαθαίνεις.

Παρεμπιπτόντως, οι δομές δεδομένων μου έχουν τινάξει τα μυαλά στον αέρα.
Πιστεύω την περισσότερη σπαζοκεφαλιά, έτσι την περνάνε οι προγραμματιστές.

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

Δεν ξέρω αν το έχει πάθει κανείς άλλος αυτό :p
Τελευταία διόρθωση: 6 Χρόνια 11 Μήνες πριν από babaliaris1.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Τόσα χρόνια στην Python και δεν το γνώριζα αυτό! 6 Χρόνια 11 Μήνες πριν #4382

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
babaliaris1 έγραψε:
Το πρόβλημα τελικά ήταν ότι πήγα και δήλωσα τις μεταβλητές έξω από τον Κατασκευαστή
και από' τι κατάλαβα οι μεταβλητές που είναι δηλωμένες απευθείας στην κλάση και δεν
βρίσκονται μέσα σε μεθόδους λειτουργούν σαν στατικές μεταβλητές και είναι όλες ίδιες
για κάθε αντικείμενο!!!

Εγώ τόσο καιρό νόμιζα ότι αν δηλώσεις μια μεταβλητή απευθείας στην κλάση:
class Test:
    petros = ""

Είναι το ίδιο σαν να κάνεις:
class Test:
    pass
 
obj = Test()
obj.petros = ""

Αλλά τελικά λειτουργούν σαν στατικές μεταβλητές.

Δεν πολυκατάλαβα τι ακριβώς εννοείς με τον όρο στατικές (static)
Όταν ένα attribute δηλώνεται στην class το έχουν όλα τα instances
www.python-course.eu/python3_class_and_instance_attributes.php
Δεν περιλαμβάνεται στο __dict__ τους, μπορούν όμως να το αλλάξουν
>>> class A:
	class_att=4
 
 
>>> c=A()
>>> c.class_att
4
>>> c.__dict__
{}
>>> c.class_att=4
>>> c.__dict__
{'class_att': 4}
Τελευταία διόρθωση: 6 Χρόνια 11 Μήνες πριν από Theo.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Τόσα χρόνια στην Python και δεν το γνώριζα αυτό! 6 Χρόνια 11 Μήνες πριν #4383

  • babaliaris1
  • Το Άβαταρ του/της babaliaris1
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 445
  • Ληφθείσες Ευχαριστίες 75
Theo έγραψε:
Δεν πολυκατάλαβα τι ακριβώς εννοείς με τον όρο στατικές (static)
Όταν ένα attribute δηλώνεται στην class το έχουν όλα τα instances
www.python-course.eu/python3_class_and_instance_attributes.php
Δεν περιλαμβάνεται στο __dict__ τους, μπορούν όμως να το αλλάξουν
>>> class A:
	class_att=4
 
 
>>> c=A()
>>> c.class_att
4
>>> c.__dict__
{}
>>> c.class_att=4
>>> c.__dict__
{'class_att': 4}

Ακριβώς αυτό που είπες είναι μια στατική μεταβλητή. Στην java το λέμε έτσι.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Τόσα χρόνια στην Python και δεν το γνώριζα αυτό! 6 Χρόνια 11 Μήνες πριν #4384

  • Αποστόλης
  • Το Άβαταρ του/της Αποστόλης
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 148
  • Ληφθείσες Ευχαριστίες 24
Είναι περίπου έτσι όπως το λες.
Η δήλωση της μεταβλητής με αυτό τον τρόπο σημαίνει οτι είναι global. Δηλαδή είναι διαθέσιμη σε οποιοδήποτε σημείο της class κι όχι μόνο μέσα σε μια function.

Μη σε μπερδεύει η δήλωση της Java.
Και αυτή είναι μια global μεταβλητή χωρίς να είναι static:
private int i=5;
Ειδικά στην Java static δηλώνονται και οι functions, όχι μόνο οι μεταβλητές.

Στις σύγχρονες programming/scripting languages (python, php, ruby κ.λ.π.) δεν είναι απαραίτητο να δηλωθούν οι μεταβλητές ως static, final, global κ.λ.π.
Στις παλαιότερες (C, Java, Visual Basic κ.λ.π.) είναι.
Τελευταία διόρθωση: 6 Χρόνια 11 Μήνες πριν από Αποστόλης.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Τόσα χρόνια στην Python και δεν το γνώριζα αυτό! 6 Χρόνια 11 Μήνες πριν #4385

  • babaliaris1
  • Το Άβαταρ του/της babaliaris1
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 445
  • Ληφθείσες Ευχαριστίες 75
Αποστόλης έγραψε:
Είναι περίπου έτσι όπως το λες.
Η δήλωση της μεταβλητής με αυτό τον τρόπο σημαίνει οτι είναι global. Δηλαδή είναι διαθέσιμη σε οποιοδήποτε σημείο της class κι όχι μόνο μέσα σε μια function.

Μη σε μπερδεύει η δήλωση της Java.
Και αυτή είναι μια global μεταβλητή χωρίς να είναι static:
private int i=5;
Ειδικά στην Java static δηλώνονται και οι functions, όχι μόνο οι μεταβλητές.

Στις σύγχρονες programming/scripting languages (python, php, ruby κ.λ.π.) δεν είναι απαραίτητο να δηλωθούν οι μεταβλητές ως static, final, global κ.λ.π.
Στις παλαιότερες (C, Java, Visual Basic κ.λ.π.) είναι.

Ναι το γνωρίζω αυτό. Για την ακρίβεια η python είναι μια Dynamic programming language
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.
Συντονιστές: pmav99
Χρόνος δημιουργίας σελίδας: 0.436 δευτερόλεπτα

Μοιράσου το!

Powered by CoalaWeb

Λίστα Ταχυδρομείου