4 from random import choice, randint, random
9 # teenagers are hereby declared to be between 11 and 20 years old
10 birthyears = range(1991,2000)
13 names = ['john', 'paul', 'george', 'ringo',\
14 'baby','scary','posh','ginger','madonna',\
15 'prince','robyn','beyonce','jay']
16 words =['Beatle','Spice','Backstreet','Sync','Jonas',\
17 'Lennon','McCartney','Starr','Harrison','Z',\
18 'Carrot','Broccoli','Asparagus','Beet']
20 birthmonths= range(1,13)
25 def age(self, curyr=2011, curmo=11):
26 return curyr+(1.*curmo-1.)/12. - self.birthyear - 1.*(self.birthmonth-1.)/12.
29 self.subject = choice(Person.names)+choice(Person.words)+ ('%03d' % Person.serialNum)
30 Person.serialNum = Person.serialNum + 1
32 self.birthyear = choice(Person.birthyears)
33 self.birthmonth = choice(Person.birthmonths)
35 self.sex = choice(Person.sexes)
36 age = self.age(2011,11)
37 self.CI = choice(Person.CIs)
39 # newer CIs have better volume, discrimination;
40 # range goes down with age. (say).
42 CInewness = (self.CI-1.)/(1.*max(Person.CIs))
43 # from oldest CI to newest, gain 2 volume pts:
44 self.trueVolume = randint(0,4)+randint(1,4)+round(2.*CInewness)
46 # from oldest CI to newest, gain 3 discrimination pts:
47 self.trueDiscrimination = randint(0,3)+randint(1,4)+round(3.*CInewness)
49 # 21-year-olds would lose 3 range points over 10 year olds (say)
50 self.trueRange = randint(0,4)+randint(1,6)+round((10.-(self.age()-11.))*3./10.)
52 # Most people don't repeat; those that do take the test 2-5 times
53 if (random() > Person.repeatFraction):
56 self.repeats=choice(range(2,6))
59 from numpy import polyfit, array
60 def test_peopleCorrelations():
63 for pnum in xrange(1,npeople):
64 testpeople.append(Person())
66 data = [[p.age(), p.CI, p.trueVolume, p.trueRange, p.trueDiscrimination] for p in testpeople]
67 ages, cis, vols, ranges, discs = zip(*data)
69 CIVolParam, dummy = polyfit(cis, vols, 1)
70 CIRangeParam, dummy = polyfit(cis, ranges, 1)
71 CIDiscParam, dummy = polyfit(cis, discs, 1)
73 AgeVolParam, dummy = polyfit(ages, vols, 1)
74 AgeRangeParam, dummy = polyfit(ages, ranges, 1)
75 AgeDiscParam, dummy = polyfit(ages, discs, 1)
77 assert CIVolParam > 0.75*(2./25.) and CIVolParam < 1.25*(2./25.)
78 assert CIDiscParam > 0.75*(3./25.) and CIDiscParam < 1.25*(3./25.)
79 assert AgeRangeParam < 0.75*(-3./10.) and AgeRangeParam > 1.25*(-3./10.)
82 assert abs(CIRangeParam) < zeroTol
83 assert abs(AgeVolParam) < zeroTol
84 assert abs(AgeDiscParam) < zeroTol
89 incompleteFraction = 0.05
97 month = choice(months)
98 monthname = calendar.month_abbr[month]
99 day = choice(range(1,calendar.monthrange(2011, month)[1]))
100 dayname = calendar.day_abbr[calendar.weekday(2011, month, day)]
105 datestring = '%s %s %d %02d:%02d:%02d %s' % (dayname, monthname, day, hr, min, sec, '2011')
106 return [datestring, month, day, hr, min, sec]
115 def __init__(self, p):
116 """Generate a result"""
118 self.datestring, self.month, self.day, self.hr, self.min, self.sec = self.randomDate();
120 self.serialNum = Measurement.serialNum
121 Measurement.serialNum = Measurement.serialNum + 1
123 # +/- 1 random measurement error
124 self.volume = self.person.trueVolume + choice([-1,0,0,0,+1])
125 self.range = self.person.trueRange + choice([-1,0,0,0,+1])
126 self.discrimination = self.person.trueDiscrimination + choice([-1,0,0,0,+1])
128 self.volume = self.limit(self.volume)
129 self.range = self.limit(self.range)
130 self.discrimination = self.limit(self.discrimination)
132 # before this date, things were being recorded 0..9 rather than 1..10
137 fixdate = fixmonth*10000 + fixday*100 + fixhr
138 checkdate = self.month*10000 + self.day*100 + self.hr
139 if checkdate < fixdate:
140 self.volume = self.volume - 1
141 self.range = self.range - 1
142 self.discrimination = self.discrimination - 1
144 if (random() < Measurement.incompleteFraction):
145 self.discrimination = None
150 text += "%s: %s\n" % ( 'Reported', self.datestring )
151 text += "%s: %s\n" % ( 'Subject', self.person.subject )
152 text += "%s: %4d/%02d\n" % ( 'Year/month of birth', self.person.birthyear, self.person.birthmonth )
153 text += "%s: %s\n" % ( 'Sex', self.person.sex )
154 text += "%s: %d\n" % ( 'CI type', self.person.CI )
155 text += "%s: %d\n" % ( 'Volume', self.volume )
156 text += "%s: %d\n" % ( 'Range', self.range )
157 if self.discrimination is None :
158 text += "%s: \n" % ( 'Discrimination' )
160 text += "%s: %d\n" % ( 'Discrimination', self.discrimination )
165 names = ['angela', 'JamesD', 'jamesm', 'Frank_Richard',\
166 'lab183','THOMAS','alexander','Beth','Lawrence',\
167 'Toni', 'gerdal', 'Bert', 'Ernie', 'olivia', 'Leandra',\
168 'sonya_p', 'h_jackson']
169 filenamestyles = ['data_%d','Data%04d','%d','%04d','audioresult-%05d']
170 suffixstyles = ['.dat','.txt','','','.DATA']
171 tookNotesFraction = 0.5
172 notes = ['Took data on Thursday and Friday until 4pm;\nAll day saturday.\n',\
173 'Contact Janice about new calibration for data in August.\n',\
174 'Submission of hours last week shows only 7 hours because \none was spent cleaning the lab.\n',\
175 'Had some trouble accessing data submission form on Saturday,\nso fewer submissions then.\n',\
176 'Third subject had real problems with the discrimiation test, so omitted.\n',\
177 'Discrimination test seems kind of flaky - had to skip in several cases\n',\
178 'Fuse blew midway through this weeks data taking,\nfewer results than last week.\n']
179 notefilenames = ['notes.txt','NOTES','ReadMe','misc.txt','About']
182 self.name = choice(Datataker.names)
183 Datataker.names.remove(self.name)
184 self.filenameprefix = choice(Datataker.filenamestyles)
185 self.filenamesuffix = choice(Datataker.suffixstyles)
187 self.tookNotes = False
188 if (random() < Datataker.tookNotesFraction) :
189 self.tookNotes = True
190 self.notes = choice(Datataker.notes)
191 self.noteFilename = choice(Datataker.notefilenames)
193 def addmeasurement(self,measurement):
194 self.measures.append(measurement)
201 fname = self.noteFilename
202 file = open(fname, 'w')
203 file.write(self.notes)
206 for m in self.measures:
207 fname = self.filenameprefix % m.serialNum + self.filenamesuffix
208 file = open(fname, 'w')
215 #test_peopleCorrelations()
217 npeople = 300 # should generate ~ .9*300 + 3.5*.1*300 ~ 375 files
221 for pnum in range(npeople):
222 people.append(Person())
226 for m in range(p.repeats):
227 measurements.append(Measurement(p))
231 for i in range(nexperimenters):
232 experimenters.append(Datataker())
234 for fnum in xrange(min(len(measurements), nfiles)):
235 ex = choice(experimenters)
236 ex.addmeasurement(measurements[fnum])
240 for ex in experimenters:
244 if __name__=='__main__':