Discussion:
Generelt klasse-design-problem - implementation i Python
(for gammel til at besvare)
Bertel Lund Hansen
2008-10-28 15:31:47 UTC
Permalink
Hej alle

Til mit statistikprogram benytter jeg nogle klasser. En
basisklasse hedder Counter og en afledt dertil hedder
Percentagecounter.

class Counter:
def __init__ (self,nam,msgs=0,usrs=0):
self.name=nam
self.messages=msgs
self.users=usrs
def gns ():
return self.messages/self.users

class PercentageCounter (Counter):
def msg_pct ():
return self.messages/total.messages*100
def pers_pct ():
return self.users/total.users*100

Under databehandlingen opsamles data for hvert indlæg og gemmes i
forskellige arrays af tællerklasser. Der er f.eks. ét der
opsamler newsreadere. Jeg kan godt lave det med simple arrays
(lister i Python), men jeg ville gerne have en inkludér-metode
knyttet sammen med disse arrays. Den skal enten appende et nyt
element eller også finde et gammelt og opdatere dets datatællere.
Derfor laver jeg klassen StatArray (her delvis pseudokodet):

class StatArray ():
unit_array=[]
def is_member (name):
return index hvor -1 = falsk
def include (name):
n=self.is_member(name)
if n>=0: opdater tællere
else: self.unit_array.append(Counter(nam,1,1))

Problemet er nu at nogle arrays skal indeholde elementer af typen
Counter mens andre skal indeholde elementer af typen
PercentageCounter.

Det kan løses ved at jeg kun laver klassen PercentageCounter, men
det vil betyde at dem som egentlig kan nøjes med Counter, vil
slæbe rundt på to overflødige metoder.

Det kan naturligvis også løses ved at jeg laver to forskellige
wrapperklasser til mine arrays. Det er også muligt at medsende et
flag i parameterlisten, men det er jo ikke særlig kønt.

Findes der en elegant løsning?
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Klaus Alexander Seistrup
2008-10-28 16:12:25 UTC
Permalink
Post by Bertel Lund Hansen
Findes der en elegant løsning?
Til at tælle ting med navn, ville jeg foretrække at benytte et dict-
objekt fremfor en liste (osse selv om listen er pakket ind i en klasse),
fx noget i retning af:

# -*- coding: iso-8859-1 -*-

# Et hypotetisk objekt, som blot har en label
class myObj:
def __init__(self, label=None):
self._label = label
# end def __init__
def __str__(self):
return self._label
# end def __str__
# end class myObj

theStats = {}

# En tællefunktion, der kan tælle alle objekter der
# har et "unikt" navn (i betydningen "der ikke skifter
# fra gang til gang). Put den evt. i en klasse for at
# undgå at gøre theStats global.
def addObj(obj):
global theStats
name = str(obj) # Her udnyttes __str__-funktionen fra myObj
theStats[name] = theStats.get(name, 0) + 1
# end def addObj

# eof

Mht. tæller og procenttæller, ku' man måske være lidt fræk og nøjes
med at have én tælleklasse, hvor __int__ eller __long__ returnerer
antallet af genstande, og hvor __float__ returnerer procentsatsen
(fx i intervallet [0; 1]), så kan man få forskellige resultater fra
den samme klasse afhængigt af om man benytter int()/long() eller
float() -- og så ville jeg blæse på om nogle objekter skulle have
en overflødig metode eller ej (se fx "dir('')" for at se hvor mange
metoder en simpel streng bærer rundt på), men det er selvfølgelig
smag og behag.

Mvh,
--
Klaus Alexander Seistrup
http://klaus.seistrup.dk/
Anders J. Munch
2008-10-28 17:45:54 UTC
Permalink
Post by Klaus Alexander Seistrup
theStats[name] = theStats.get(name, 0) + 1
I moderne Python bruger man defaultdict til den slags.
Post by Klaus Alexander Seistrup
from collections import defaultdict
dd = defaultdict(int)
... dd[c] += 1
...
... print k, "set", dd[k], "gange"
...
a set 4 gange
set 4 gange
v set 1 gange
e set 5 gange
d set 3 gange
g set 1 gange
H set 1 gange
J set 1 gange
o set 1 gange
n set 5 gange
s set 2 gange
b set 1 gange
h set 1 gange
x set 0 gange
r set 1 gange

mvh. Anders
Klaus Alexander Seistrup
2008-10-28 18:47:21 UTC
Permalink
Post by Anders J. Munch
I moderne Python bruger man defaultdict til den slags.
Nåja, nogle gange kan det være svært at skjule at man har brugt python
siden v1.2, eller deromkring.
Post by Anders J. Munch
x set 0 gange
Mon dog!

Mvh,
--
Klaus Alexander Seistrup
http://klaus.seistrup.dk/
Bertel Lund Hansen
2008-10-28 19:40:17 UTC
Permalink
Post by Klaus Alexander Seistrup
Post by Anders J. Munch
x set 0 gange
Mon dog!
Hvor i denne sætning finder du et x?

Jens Hansen havde en bondegaard
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Anders J. Munch
2008-10-28 22:19:51 UTC
Permalink
Post by Klaus Alexander Seistrup
Post by Anders J. Munch
x set 0 gange
Mon dog!
Jamen det er da korrekt: x optræder 0 gange i teksten <g>.
Jeg må vist have redigeret en linie ud fra den interaktive session, der gik
Post by Klaus Alexander Seistrup
Post by Anders J. Munch
print dd['x']
- Anders
Bertel Lund Hansen
2008-10-28 19:39:42 UTC
Permalink
Post by Anders J. Munch
I moderne Python bruger man defaultdict til den slags.
Der skal tælles to værdier ved Counter-elementerne.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Anders J. Munch
2008-10-28 22:47:39 UTC
Permalink
Post by Bertel Lund Hansen
Post by Anders J. Munch
I moderne Python bruger man defaultdict til den slags.
Der skal tælles to værdier ved Counter-elementerne.
Jeg illustrerede bare datastrukturen. Jeg har ikke sat mig ind i dit
designproblem, men det virker ret givet at der skal bruges dicts eller
defaultdicts et eller andet sted.

mvh. Anders

Loading...