Τα πάντα για την Python

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την Python

Δημοσίευσηαπό arkanoid » 27 Ιουν 2011, 22:57

Είτε κάνεις και τις τρεις ενέργειες σε μία επανάληψη, είτε σε τρεις (μία ενέργεια σε κάθε επανάληψη) πάλι Ο(3n)=Ο(n) είναι. Η δικιά σου εκδοχή ίσως πλεονεκτεί λίγο αφού διατρέχεις τη δομή μόνο μία φορά, αλλά όχι τόσο όσο υποστηρίζεις.
Πάντως επιμένω ότι η χρήση της len() αντί για χρήση μεταβλητής μέσα στην επανάληψη είναι ορθότερη τεχνική.
Γνώσεις ⇛ Linux: Καλά ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Ubuntu 11.04 64 bit σε Dell Inspiron N5010
Intel Core i5 M480 │ 4 GB │ ATI Radeon HD 5600
arkanoid
babeTUX
babeTUX
 
Δημοσιεύσεις: 15
Εγγραφή: 30 Μάιος 2011, 01:36
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό migf1 » 27 Ιουν 2011, 23:32

Τι εννοείς όχι τόσο όσο υποστηρίζω; Εξαρχής έδωσα ακριβές νούμερο (διατρέχεις τον πίνακα 3 φορές αντί για 1, άσχετα αν από απροσεξία σε επόμενο ποστ το 3 φορές το έγραψα με notation ^3, το οποίο σωστά μου επισήμανες και διόρθωσες... ήταν στο 2ο ποστ μου όμως, όχι στο 1ο).

Όσο για το ορθότερη τεχνική, εξαρτάται. Αν π.χ. ο πίνακάς σου αποτελείται από τίποτε εκατομμύρια στοιχεία ή εκατοντάδες εκατομμυρίων, η "τεχνική" πολλαπλής προσπέλασης του ίδιου πίνακα μεταφράζεται σε εκνευριστική στην καλύτερη των περιπτώσεων, ακόμα και δραματικά επιζήμια στη χειρότερη (αν π.χ μιλάμε για επαγγελματική ή ερευνητική εφαρμογή... π.χ. τηλεπικοινωνίες) καθυστέρηση στο χρόνο εκτέλεσης.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό medigeek » 28 Ιουν 2011, 01:04

c7p έγραψε:Για προσπαθήστε να λύσετε την άσκηση http://codingbat.com/prob/p126968 να δούμε πόσες διαφορετικές λύσεις θα έχουμε :P -κατά προτίμηση χωρίς ταξινόμηση για μεγαλύτερη δυσκολία :roll: -.

Κώδικας: Επιλογή όλων
def centered_average(nums):
nums.sort()
a = len(nums)
i = a % 2
if i == 0:
z = (nums[a / 2 - 1] + nums[a / 2]) / 2
else:
z = nums[int(a / 2)]
return z


Βασικά ζητάει το median: http://math.about.com/od/statistics/a/MeanMedian.htm
Edit: Μολις κατάλαβα ότι o c7p ζήτησε συγκεκριμενα χωρίς .sort() :P
Κύπριος; Κόπιασε στο ubuntu-cy! ┃ Launchpad Debian Github
Οδηγός για νεοεισερχόμενους -- Αρχικές οδηγίες για αρχάριους χρήστες του Ubuntu

1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 12.10 quantal 3.5.0-21-generic 64bit (en_US.UTF-8, GNOME cinnamon2d), Ubuntu 3.5.0-19-generic, Windows 7
3 Intel Core2 Duo CPU E6550 2.33GHz ‖ RAM 5970 MiB ‖ MSI MS-7235
4 nVidia G73 [GeForce 7300 GT] [10de:0393] {nvidia}
5 eth0: Realtek RTL-8110SC/8169SC Gigabit Ethernet [10ec:8167] (rev 10)
Άβαταρ μέλους
medigeek
Freedom
Freedom
 
Δημοσιεύσεις: 5023
Εγγραφή: 24 Μάιος 2008, 14:49
Τοποθεσία: Σερβία/Κύπρος
Launchpad: medigeek
IRC: savvas
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό Ilias95 » 28 Ιουν 2011, 01:26

Να συνεχίσω την απορία μου απ' την προηγούμενη σελίδα καθώς βρήκα μια λύση αλλά δεν μπορώ να την χρησιμοποιήσω ακόμα. :?
Σκέφτηκα να χρησιμοποιήσω την συνάρτηση exec.
Έτσι απ' την κλάση που έδειξα και προηγουμένως:

Spoiler: show
Κώδικας: Επιλογή όλων
class Epafes:
global d
d = 1 # Με την μεταβλητή d ορίζω τον αύξων αριθμό μέσα στην __init__.
arithmos_epafwn = 0

def __init__(self, epafi):
global d
print('Εισάγεται στοιχεία της επαφής:\n')
print('Όνομα: ', end='') ; name = input()
print('Επίθετο: ', end='') ; surname = input()
print('e-mail: ', end='') ; mail = input()
print('Διέυθηνση: ', end='') ; address = input()
print('Τηλέφωνο: ', end='') ; telephone = input()
print('Κατηγορία: ', end='') ; category = input()
self.name = name
self.surname = surname
self.mail = mail
self.address = address
self.telephone = telephone
self.category = category
self.k = d # Α/Α - αύξων αριθμός
d += 1
Epafes.arithmos_epafwn += 1
epafi = d

def tell(self):

print('''
{6}. {0} {1}:

Όνομα: {0}
Επίθετο: {1}
e-mail: {2}
Διέυθηνση: {3}
Τηλέφωνο: {4}
Κατηγορία: {5}
'''.format(self.name, self.surname, self.mail, \
self.address, self.telephone, self.category, self.k))


Αν κάνω το παρακάτω και εισάγω Giannis, το πρόγραμμα θα δουλέψει άψογα:

Κώδικας: Επιλογή όλων
Giannis = Epafes(1)

print('Poia epafi theleis na deis?') ; b = input()
symvolosira = b + '.tell()'
exec(symvolosira) # Η exec μετατρέπει το αλφαριθμητικό a στο όνομα της μεταβλητής στην προκειμένη περίπτωση.


Θα εισάγω δηλαδή τα στοιχεία του Giannis και θα τα πάρω πίσω με την tell().

Αν όμως κάνω μια μικρή αλλαγή και εισάγω και στο a και στο b Giannis, θα έχω πρόβλημα:

Κώδικας: Επιλογή όλων
print('Pws na onomastei i epafi?') ; a = input()
a = Epafes(1)
print('Poia epafi theleis na deis?') ; b = input()
symvolosira = b + '.tell()'
exec(symvolosira)


Θα πάρω σφάλμα:

Spoiler: show
Κώδικας: Επιλογή όλων
Traceback (most recent call last):
File "Epafes.py", line 49, in <module>
exec(symvolosira)
File "<string>", line 1, in <module>
NameError: name 'Ilias' is not defined

(Σκέφτηκα ότι αφού το a θα το ορίσω σαν Giannis και το b πάλι σαν Γιάννης θα δουλέψει, αλλά τελικά το Epafes(1) αντιστοιχίζεται στην μεταβλητή a η οποία πριν απλά είχε την τιμή "Giannis".)

Πως θα το κάνω να καταλάβει ότι το b και το a είναι και τα δύο Giannis; :wtf:

Ευχαριστώ εκ των προτέρων για οποιαδήποτε απάντηση!
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό sv1jsb » 28 Ιουν 2011, 12:34

arkanoid έγραψε:
Κώδικας: Επιλογή όλων

def centered_average(nums):
min, max = nums[0], nums[0]
for i in nums:
if i >= max:
max = i
if i <= min:
min = i
sum = 0
for i in nums:
sum = sum + i
sum = sum - (min + max)
return (sum / (len(nums) - 2))


"Μαζεύοντας" λίγο τον κώδικα του arkanoid θα πρότεινα το εξής:
Κώδικας: Επιλογή όλων

def centered_average(nums):
min, max, sum = nums[0], nums[0], nums[0]
for i in nums[1:]:
if i >= max:
max = i
if i <= min:
min = i
sum +=i
sum = sum - (min + max)
return (sum / (len(nums) - 2))

Ξεκινάμε από το πρώτο στοιχείο του πίνακα και το βάζουμε στις μεταβλητές μας min max και sum.
To loop μας οπότε χρειάζεται να ξεκινήσει από την επόμενη (δεύτερη) θέση, γι' αυτό και το [1:] στο for.
Αφού σε κάθε loop προσθέτουμε την τιμή στο sum δεν χρειάζεται το δεύτερο loop.
(Έχω την εντύπωση ότι κάπου είχα διαβάσει ότι οι τελεστές +=,-= είναι πιο γρήγοροι από τις αντίστοιχες πράξεις, οπότε ίσως θα ήταν καλύτερα
το sum=sum-(min+max), να γίνει:
sum-=min
sum-=max
δύο εντολές δηλαδή αντί μίας)
Programming blog
Γνώσεις ⇛ Linux: Καλά ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Λειτουργικό ⇛ Ubuntu 10.04 64bit
Προδιαγραφές ⇛ Phenom II │ 8GB │ 2xATI 5670 │ HD Audio │ TFT 23"
Άβαταρ μέλους
sv1jsb
babeTUX
babeTUX
 
Δημοσιεύσεις: 88
Εγγραφή: 01 Ιουν 2011, 23:50
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό migf1 » 28 Ιουν 2011, 12:44

Αλγοριθμικά πάντως, αυτό που επισήμανα στον arkanoid υλοποιημένο είναι ως εξής (ο κώδικας είναι σε C, αλλά κατάλαβα πως οι συντακτικές διαφορές είναι ελάχιστες, οπότε υποθέτω μπορεί πολύ εύκολα κάποιος που ξέρει τη γλώσσα να το κάνει valid python code)...

Κώδικας: Επιλογή όλων

//-------------------------------------------------------------------------------------
int centered_average( int nums[], int maxlen )
{
int min, max, sum = 0;
register int i;

min = max = nums[0];
for (i=0; i < maxlen; i++)
{
if ( nums[i] < min )
min = nums[i];
else
max = nums[i];
sum += nums[i];
}

return (sum-min-max)/(i-2);
}



Το i είναι βασικά το πλήθος στοιχείων του nums, και προφανώς υπολογίζεται μέσα στο loop.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό arkanoid » 28 Ιουν 2011, 12:57

migf1 έγραψε:Αλγοριθμικά πάντως, αυτό που επισήμανα στον arkanoid υλοποιημένο είναι ως εξής (ο κώδικας είναι σε C, αλλά κατάλαβα πως οι συντακτικές διαφορές είναι ελάχιστες, οπότε υποθέτω μπορεί πολύ εύκολα κάποιος που ξέρει τη γλώσσα να το κάνει valid python code)...

Κώδικας: Επιλογή όλων

//-------------------------------------------------------------------------------------
int centered_average( int nums[], int maxlen )
{
int min, max, sum = 0, n = 0;
register int i;
int retint = 0;

min = max = nums[0];
for (i=0; i < maxlen; i++)
{
if ( nums[i] < min )
min = nums[i];
else
max = nums[i];
sum += nums[i];
}

return (sum-min-max)/(i-2);
}



Το i είναι βασικά το πλήθος στοιχείων του nums, και προφανώς υπολογίζεται μέσα στο loop.


Οπότε γλιτώνεις τη χρήση της len, γιατί ξέρεις από την αρχή το μέγεθος του πίνακα.
Αν δεν είχες το maxlen ως είσοδο τι θα έκανες; Αν ο πίνακας ήταν δηλαδή άγνωστου μεγέθους;

@sv1jsb συμφωνώ με τις διορθώσεις, και ωραία η ιδέα με την αρχικοποίηση του sum στο πρώτο στοιχείο του πίνακα.
Γνώσεις ⇛ Linux: Καλά ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Ubuntu 11.04 64 bit σε Dell Inspiron N5010
Intel Core i5 M480 │ 4 GB │ ATI Radeon HD 5600
arkanoid
babeTUX
babeTUX
 
Δημοσιεύσεις: 15
Εγγραφή: 30 Μάιος 2011, 01:36
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό sv1jsb » 28 Ιουν 2011, 13:18

Ilias95 έγραψε:Να συνεχίσω την απορία μου απ' την προηγούμενη σελίδα καθώς βρήκα μια λύση αλλά δεν μπορώ να την χρησιμοποιήσω ακόμα. :?
Σκέφτηκα να χρησιμοποιήσω την συνάρτηση exec.
Έτσι απ' την κλάση που έδειξα και προηγουμένως:

Spoiler: show
Κώδικας: Επιλογή όλων
class Epafes:
global d
d = 1 # Με την μεταβλητή d ορίζω τον αύξων αριθμό μέσα στην __init__.
arithmos_epafwn = 0

def __init__(self, epafi):
global d
print('Εισάγεται στοιχεία της επαφής:\n')
print('Όνομα: ', end='') ; name = input()
print('Επίθετο: ', end='') ; surname = input()
print('e-mail: ', end='') ; mail = input()
print('Διέυθηνση: ', end='') ; address = input()
print('Τηλέφωνο: ', end='') ; telephone = input()
print('Κατηγορία: ', end='') ; category = input()
self.name = name
self.surname = surname
self.mail = mail
self.address = address
self.telephone = telephone
self.category = category
self.k = d # Α/Α - αύξων αριθμός
d += 1
Epafes.arithmos_epafwn += 1
epafi = d

def tell(self):

print('''
{6}. {0} {1}:

Όνομα: {0}
Επίθετο: {1}
e-mail: {2}
Διέυθηνση: {3}
Τηλέφωνο: {4}
Κατηγορία: {5}
'''.format(self.name, self.surname, self.mail, \
self.address, self.telephone, self.category, self.k))


Αν κάνω το παρακάτω και εισάγω Giannis, το πρόγραμμα θα δουλέψει άψογα:

Κώδικας: Επιλογή όλων
Giannis = Epafes(1)

print('Poia epafi theleis na deis?') ; b = input()
symvolosira = b + '.tell()'
exec(symvolosira) # Η exec μετατρέπει το αλφαριθμητικό a στο όνομα της μεταβλητής στην προκειμένη περίπτωση.


Θα εισάγω δηλαδή τα στοιχεία του Giannis και θα τα πάρω πίσω με την tell().

Αν όμως κάνω μια μικρή αλλαγή και εισάγω και στο a και στο b Giannis, θα έχω πρόβλημα:

Κώδικας: Επιλογή όλων
print('Pws na onomastei i epafi?') ; a = input()
a = Epafes(1)
print('Poia epafi theleis na deis?') ; b = input()
symvolosira = b + '.tell()'
exec(symvolosira)


Θα πάρω σφάλμα:

Spoiler: show
Κώδικας: Επιλογή όλων
Traceback (most recent call last):
File "Epafes.py", line 49, in <module>
exec(symvolosira)
File "<string>", line 1, in <module>
NameError: name 'Ilias' is not defined

(Σκέφτηκα ότι αφού το a θα το ορίσω σαν Giannis και το b πάλι σαν Γιάννης θα δουλέψει, αλλά τελικά το Epafes(1) αντιστοιχίζεται στην μεταβλητή a η οποία πριν απλά είχε την τιμή "Giannis".)

Πως θα το κάνω να καταλάβει ότι το b και το a είναι και τα δύο Giannis; :wtf:

Ευχαριστώ εκ των προτέρων για οποιαδήποτε απάντηση!


Έχεις λίγο μπερδεμένη έννοια για τα αντικείμενα και της κλάσεις.
Σε μία κλάση περιγράφεις τα όλα τα στοιχεία που προσδιορίζουν ένα αντικείμενο και διάφορες μεθόδους για τον χειρισμό αυτών των στοιχείων.
Στην προκειμένη περίπτωση θέλεις να φτιάξεις μια κλάση που να φτιάχνει αντικείμενα "επαφών". Στην κλάση πρέπει να ορίσεις τι πληροφορίες θέλεις να έχει μια επαφή. Το πως θα εμφανίσεις ή θα καταχωρίσεις νέο αντικείμενο δεν είναι υπόθεση της κλάσης αλλά του προγράμματος.
Δηλαδή:
Κώδικας: Επιλογή όλων

class epafes(object):
def __init__(self, name=None, address=None, tel=None):
self.name=name
self.address=address
self.tel=tel

Δίνοντας τώρα:
Κώδικας: Επιλογή όλων

a=epafes("ilias","kapou 35 ellada","768768686")
print a.name, a.address, a.tel

αν γράψεις print a παίρνεις το παρακάτω σαν αποτέλεμα:
Κώδικας: Επιλογή όλων

print a
<__main__.epafes object at 0xb77fcc8c>

Αυτό αν θέλεις μπορείς να το αλλάξεις αν αλλάξεις την __str__ ή την __repr__ μέθοδο του αντικειμένου.
Στην παραπάνω κλάση προσθεσε την εξής μέθοδο:
Κώδικας: Επιλογή όλων

def __str__(self):
return "Contact for: %s" % self.name


Για να βάλεις τιμές στο αντικείμενο ή θα το κάνεις την στιγμή που το φτιάχνεις, (όπως παραπάνω epafes("ilias","kapou 35 ellada" .....) ή
θα φτιάξεις πρώτα ένα άδειο αντικείμενο και θα το γεμίσεις με τιμές από τον χρήστη.
Κώδικας: Επιλογή όλων

a=epafes()
a.name=raw_input("Dwse onoma: ")
a.address=raw_input("Dwse dieuthinsi: ")
a.tel=raw_input("Dwse tel: ")

Τώρα αν θέλεις να δημιουργήσεις πολλά τέτοια αντικείμενα η διαδικασία πρέπει να μπεί σε ένα loop και το κάθε αντικείμενο να σώζεται σε μία λίστα (ή στον δίσκο).
Κώδικας: Επιλογή όλων

cont='Y'
MyList=[]
while(cont<>'N'):
a=epafes()
a.name=raw_input("Dwse onoma: ")
a.address=raw_input("Dwse dieuthinsi: ")
a.tel=raw_input("Dwse tel: ")
MyList.append(a)
cont=raw_input("Na synexisw? ")

for obj in MyList:
print obj.name, obj.address, obj.tel

και με τον ίδιο τρόπο θα κάνεις την αναζήτηση, βάζοντας σε loop ένα ένα τα αντικείμενα σου και ελέγχοντας αν το όνομα που έγραψε ο χρήστης είναι ίσο με obj.name, αλλιώς στο επόμενο.

Ελπίζω να βοήθησα πάνω στην λογική του προγράμματος
Φιλικά,
Ανδρέας
Τελευταία επεξεργασία από sv1jsb και 28 Ιουν 2011, 14:15, έχει επεξεργασθεί 1 φορά/ες συνολικά
Programming blog
Γνώσεις ⇛ Linux: Καλά ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Λειτουργικό ⇛ Ubuntu 10.04 64bit
Προδιαγραφές ⇛ Phenom II │ 8GB │ 2xATI 5670 │ HD Audio │ TFT 23"
Άβαταρ μέλους
sv1jsb
babeTUX
babeTUX
 
Δημοσιεύσεις: 88
Εγγραφή: 01 Ιουν 2011, 23:50
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό migf1 » 28 Ιουν 2011, 13:51

arkanoid έγραψε:Οπότε γλιτώνεις τη χρήση της len, γιατί ξέρεις από την αρχή το μέγεθος του πίνακα.
Αν δεν είχες το maxlen ως είσοδο τι θα έκανες; Αν ο πίνακας ήταν δηλαδή άγνωστου μεγέθους;

@sv1jsb συμφωνώ με τις διορθώσεις, και ωραία η ιδέα με την αρχικοποίηση του sum στο πρώτο στοιχείο του πίνακα.

Στον κώδικά σου είδα πως στη συνθήκη του loop γράφεις:
Κώδικας: Επιλογή όλων
for i in nums:

άρα συμπεραίνω πως στην python δεν χρειάζεται να ξέρεις το μήκος του nums. Οπότε αν το i στον παραπάνω κώδικα δεν σου δίνει στο τέλος του loop το πλήθος έτσι κι αλλιώς, απλώς βάζεις μια μεταβλητή, π.χ. n=0; έξω από το loop, την κάνεις: n++ μέσα στο loop και στο τέλος του loop θα ισούται με το πλήθος στοιχείων του nums.

ΥΓ. Στη C δεν υπάρχει κάτι αντίστοιχο του for i in nums:, οπότε αναγκαστικά περνάω το maxlen για να ξέρω το πάνω όριο του nums (στην python δεν χρειάζεται καν, από ότι κατάλαβα).
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την Python

Δημοσίευσηαπό Ilias95 » 28 Ιουν 2011, 13:57

@sv1jsb:
Σε ευχαριστώ πολύ φίλε για τον κόπο σου και για την αναλυτική σου απάντηση.

Όντως τα χα μπερδέψει λιγάκι, αλλά κυρίως κολλούσα στην αυτόματη δημιουργία μεταβλητών και στο πως θα τις καλέσει αυτές ο χρήστης.
Νομίζω ότι πλέον είμαι κοντά στην υλοποίηση αυτού του σκέλους του προγράμματος.
Να 'σαι καλά!
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι