forked from stromatolith/tiny_py_oo_primer
/
process_data_oo.py
159 lines (135 loc) · 6.47 KB
/
process_data_oo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!python
"""
lese und verarbeite Daten, nun objektorientiert
"""
from os import getcwd, mkdir, listdir
from os.path import join, dirname, isdir
from numpy import amin, amax, loadtxt, zeros, mean, std
from pylab import plt, cm
from cPickle import Pickler
class MyDataAnalyser(object):
def __init__(self,targetfolder):
namelist=listdir(getcwd())
if targetfolder in namelist:
self.datapath=join(targetfolder)
if not isdir(self.datapath):
raise ValueError("I can't find any subfolder {} in my working directory".format(targetfolder))
self.plotpath=join(dirname(targetfolder),'plots')
try:
mkdir(self.plotpath)
print "plot folder didn't exist yet, I just created it"
except:
print 'plot folder seems to exist, I will write in it'
self.N=0
self.n=[]
self.data=[]
self.min=None
self.max=None
self.avg_min=None
self.avg_max=None
self.read_data()
def read_data(self):
fli=listdir(self.datapath)
if len(fli)==0:
print 'warning: no datasets present'
for i,dataset in enumerate(fli):
fname,ext=dataset.split('.')
namensbruchstuecke=fname.split('_')
self.n.append(int(float(namensbruchstuecke[2])))
self.data.append(loadtxt(join(self.datapath,dataset)))
self.N=len(fli)
def process_data(self):
self.min=zeros(self.N)
self.max=zeros(self.N)
for i,dat in enumerate(self.data):
self.min[i]=amin(dat)
self.max[i]=amax(dat)
def plot_data(self):
for i,dat in enumerate(self.data):
plt.imshow(dat, cmap=cm.jet, interpolation=None, extent=[11,22,-3,2])
txt='plot '.format(self.n[i])
txt+='\nmin {0:.2f} und max {1:.2f}'.format(self.min[i],self.max[i])
txt+='\navg. min {0:.2f} und avg. max {1:.2f}'.format(mean(self.min),mean(self.max))
plt.suptitle(txt,x=0.5,y=0.98,ha='center',va='top',fontsize=10)
plt.savefig(join(self.plotpath,'pic_oo_'+str(self.n[i])+'.png'))
plt.close() # wichtig, sonst wird in den selben Plot immer mehr reingepackt
def write_importand_characteristic_data(self,extended_output=False):
"""
Man erwischt sich oft beim Schreiben solcher Ausgabefunktionen, und spaeter
muss man dann noch eventuell Einlesefunktionen fuer viele gleiche Ausgabedateien
schreiben. Das ist oft unnoetig, denn es gibt z.B. Pickler und Unpickler.
"""
if extended_output==1:
"blablabla"
elif extended_output==2:
"blablabla" # irgendwann wurde noch eine andere Version fuer noetig gehalten - oje
else:
"blablabla"
# schlanke Ausgabeoption --> Ziel ist Uebersichtlichkeit wenn nicht alles gebraucht
# wird, ABER: Nachteil --> jetzt sind die Ausgabedateien nicht mehr standardisiert
# man muss das Einleseprogramm umschreiben, um es wieder tolerant zu machen
# Oft ist das alle unnoetiger Mumpitz, denn mit Pickler und Unpickler gehts meist auch
# und es ist immer das komplette Objekt gespeichert (sofern nicht grosse Dinger vor dem
# pickling ueber Bord geworfen werden).
raise NotImplementedError('sorry, not implemented, (aber meist besser so)')
"""
Version 1:
"""
#mda=MyDataAnalyser('data')
#mda.process_data()
## jetzt hab ich auch die Information, um Statistische Groessen in die Plots
## reinschreiben zu koennen
#minmean, maxmean = mean(mda.min),mean(mda.max)
#for i,dat in enumerate(mda.data):
# plt.imshow(dat, cmap=cm.jet, interpolation=None, extent=[11,22,-3,2])
# txt='plot '.format(mda.n[i])
# txt+='\nmin {} und max {}'.format(mda.min[i],mda.max[i])
# txt+='\navg. min {} und avg. max {}'.format(minmean,maxmean)
# plt.suptitle(txt,x=0.5,y=0.98,ha='center',va='top',fontsize=10)
# plt.savefig(join(mda.plotpath,'pic_oo_'+str(mda.n[i])+'.png'))
# plt.close() # wichtig, sonst wird in den selben Plot immer mehr reingepackt
#
## Man haette natuerlich auch in process_data.py zweimal durch die Datenbank
## gehen koennen, einmal fuer die Statistik, und das zweite Mal, um die
## Plots machen zu koennen und die statistische Info mit reinschreiben zu koennen.
## Ausserdem passiert das hier ja auch nicht anders, eine Schleife in mda.read_data(),
## eine in mda.process_data(), eine dritte zum Plotten --> Rechenzeit.
## ABER: oft wird ein prozedurales Auswerteskript lang und kompliziert, und je laenger
## und komplizierter es wird, desto groesser wird die Hemmschwelle, daran auch nur kleine
## Dinge zu aendern --> Hemmung der Kreativitaet, man probiert nichts mehr aus
##
## bei der objektorientierten Version wird der Code nicht kuerzer. In der
## Klassendefinition steht oft fast derselbe Code wie vorher im prozeduralen Prototyp.
## ABER: die prozedurale Version wird oft nicht gescheit kommentiert, rein wegen Faulheit.
## Faellt nicht auf, dass die Namen der Methoden oben (read_data, process_data, plot_data)
## genau das ist, was als Abschnittsueberschriften (Mindestkommentarmenge sozusagen)
## in der Prozeduralen Version stehen sollte?
##
## Wenn man in einem langen prozeduralen Auswerteskript Abschnitte an- oder ausschaltet,
## dann bekommt man probleme wenn man sich nicht mehr daran erinnert, wie sie voneinander
## abhangen. In der obigen Version muss man solche Probleme nicht haben, man kann ja
## uebungsweise mal in die Plotfunktion einbauen, der nachprueft ob process_data schon
## gelaufen ist, so dass es im Notfall automatisch nachgeholt wird.
"""
Version 2:
ich habe bemerkt, dass ich die Plots haeufig benutze, also rein damit in
die Klassendefinition!
"""
## man bemerke die Uebersichtlichkeit der folgenden drei Befehle,
## sie sind knapp, aber doch geht hervor was alles gemacht wird
mda=MyDataAnalyser('data')
mda.process_data()
mda.plot_data()
print 'standard deviations: ',std(mda.min),std(mda.max) # Warum nicht rein damit in die Klassendefinition?
"""
noch was:
Instanz speichern, alles, ohne Arbeit mit dem Schreiben von Ausgaberoutinen
"""
output=open('einmachglas.txt','w')
einmachglas=Pickler(output)
einmachglas.dump(mda)
output.close()
# aber: Datei wird gross, weil die ganzen Datensaetze mit drin sind
# Uebung: Klassendefinition umschreiben, dass eine Instanz nicht einen
# riesigen Speicher belegt
# Grundsatzfrage stellt sich immer: Was alles als Instanzattribute mitschleppen?