File 1:
Expand|Select|Wrap|Line Numbers
- class TallySheet:
- """Manage tallies for a collection of values.
- Values can either be from a consecutive range of integers, or a
- consecutive sequence of characters from the alphabet.
- """
- def __init__(self, minVal, maxVal):
- """Create an initially empty tally sheet.
- minVal the minimum acceptable value for later insertion
- maxVal the minimum acceptable value for later insertion
- """
- self._minV = minVal
- self._maxV = maxVal
- maxIndex = self._toIndex(maxVal)
- self._tallies = [0] * (maxIndex + 1) # a list of counters, each initially zero
- def increment(self, val):
- """Increment the tally for the respective value.
- raise a TypeError if the given value is not of the proper type
- raise a ValueError if the given value is not within proper range
- """
- ind = self._toIndex(val)
- if not 0 <= ind < len(self._tallies):
- raise ValueError('parameter '+str(val)+' out of range')
- self._tallies[ind] += 1
- def getCount(self, val):
- """Return the total number of current tallies for the given value.
- raise a TypeError if the given value is not of the proper type
- raise a ValueError if the given value is not within proper range
- """
- ind = self._toIndex(val)
- if not 0 <= ind < len(self._tallies):
- raise ValueError('parameter '+str(val)+' out of range')
- return self._tallies[ind]
- def getTotalCount(self):
- """Return the total number of current tallies."""
- return sum(self._tallies)
- def _toIndex(self, val):
- """Convert from a native value to a legitimate index.
- Return the resulting index (such that _minV is mapped to 0)
- """
- try:
- if isinstance(self._minV, str):
- i = ord(val) - ord(self._minV)
- else:
- i = int( val - self._minV )
- except TypeError:
- raise TypeError('parameter '+str(val)+' of incorrect type')
- return i
- def writeTable(self, outfile):
- """Write a comprehensive table of results.
- Report each value, the count for that value, and the percentage usage.
- outfile an already open file with write access.
- """
- outfile.write('Value Count Percent \n----- ------ -------\n')
- total = max(self.getTotalCount(), 1) # avoid division by zero
- for ind in range(len(self._tallies)):
- label = self._makeLabel(ind)
- count = self._tallies[ind]
- pct = 100.0 * count / total
- outfile.write('%s %6d %6.2f%%\n' % (label, count, pct))
- def _makeLabel(self, ind):
- """Convert index to a string in native range."""
- if isinstance(self._minV, int):
- return '%5d' % (ind + self._minV)
- else:
- return ' %s ' % chr(ind + ord(self._minV))
- def writeHistogram(self, output, source):
- '''Using the information created within writeTable,
- create a histogram that compiles the data from the source file
- into groups of consecutive values.'''
- histo = list()
- text = source.read() # read the contents of the source file which in this case is tally.txt
- text = text.split('\n') # split each line in the text
- histo.append(text[0] + '\n')
- histo.append(text[1] + '\n')
- for line in text: # if there's a blank line, or a \n at the end of the file, delete it
- if line == '':
- text.remove(line)
- numLines = len(text) # this will help set up how long the loops need to be that are upcoming
- if numLines % 2 == 1: # if the number of lines is odd then the last line needs to be duplicated
- text.append(text[numLines - 1])
- for x in range(2, numLines, 2): # this loop splits each line into individual pieces then adds the parts together
- j = text[x].split() # split the first line
- k = text[x+1].split() # split the second line
- label = j[0] + '-' + k[0] # the label is the first parts added together ie. 'a-b'
- count = int(j[1]) + int(k[1]) # add the counts together
- pct = float(j[2][:-1]) + float(k[2][:-1]) # add the percentages together
- histo.append('%5s %6d %6.2f%%\n' % (label, count, pct)) # create the lines to be written and add them to histo list
- for line in histo:
- output.write(line) # as in writeTable, write a line to the output file
- if __name__ == '__main__':
- t = TallySheet('a', 'e')
- for i in range(10):
- t.increment('a')
- if t.getCount('a') == 10:
- print 'Test1: Success'
- else:
- print 'Test1: Failure'
- for i in range(5):
- t.increment('b')
- if t.getCount('b') == 5:
- print 'Test2: Success'
- else:
- print 'Test2: Failure'
- for i in range(10):
- t.increment('c')
- if t.getCount('c') == 10:
- print 'Test3: Success'
- else:
- print 'Test3: Failure'
- for i in range(5):
- t.increment('d')
- if t.getCount('d') == 5:
- print 'Test4: Success'
- else:
- print 'Test4: Failure'
- if t.getTotalCount() == 30:
- print 'Test5: Success'
- else:
- print 'Test5: Failure'
- f = file('tally.txt', 'w')
- t.writeTable(f)
- f.close()
- print "Please open and check tally.txt."
- f2 = file('histogram.txt', 'w')
- f = file('tally.txt', 'r')
- t.writeHistogram(f2, f)
- f2.close()
- f.close()
- print "Please open and check histogram.txt."
- raw_input("Press the ENTER key to continue...")
Expand|Select|Wrap|Line Numbers
- from TallySheet import *
- class TallySheetWithHist(TallySheet):
- '''A modified TallySheet Class'''
- def writeHistogram(self, output, source):
- '''Using the information created within writeTable,
- create a histogram that compiles the data from the source file
- into groups of consecutive values.'''
- histo = list()
- text = source.read() # read the contents of the source file which in this case is tally.txt
- text = text.split('\n') # split each line in the text
- histo.append(text[0] + '\n')
- histo.append(text[1] + '\n')
- for line in text: # if there's a blank line, or a \n at the end of the file, delete it
- if line == '':
- text.remove(line)
- numLines = len(text) # this will help set up how long the loops need to be that are upcoming
- if numLines % 2 == 1: # if the number of lines is odd then the last line needs to be duplicated
- text.append(text[numLines - 1])
- for x in range(2, numLines, 2): # this loop splits each line into individual pieces then adds the parts together
- j = text[x].split() # split the first line
- k = text[x+1].split() # split the second line
- label = j[0] + '-' + k[0] # the label is the first parts added together ie. 'a-b'
- count = int(j[1]) + int(k[1]) # add the counts together
- pct = float(j[2][:-1]) + float(k[2][:-1]) # add the percentages together
- histo.append('%5s %6d %6.2f%%\n' % (label, count, pct)) # create the lines to be written and add them to histo list
- for line in histo:
- output.write(line) # as in writeTable, write a line to the output file
- if __name__ == '__main__':
- t = TallySheetWithHist('a', 'e')
- for i in range(10):
- t.increment('a')
- if t.getCount('a') == 10:
- print 'Test1: Success'
- else:
- print 'Test1: Failure'
- for i in range(5):
- t.increment('b')
- if t.getCount('b') == 5:
- print 'Test2: Success'
- else:
- print 'Test2: Failure'
- for i in range(10):
- t.increment('c')
- if t.getCount('c') == 10:
- print 'Test3: Success'
- else:
- print 'Test3: Failure'
- for i in range(5):
- t.increment('d')
- if t.getCount('d') == 5:
- print 'Test4: Success'
- else:
- print 'Test4: Failure'
- if t.getTotalCount() == 30:
- print 'Test5: Success'
- else:
- print 'Test5: Failure'
- f = file('tally.txt', 'w')
- t.writeTable(f)
- f.close()
- print "Please open and check tally.txt."
- f2 = file('histogram.txt', 'w')
- f = file('tally.txt', 'r')
- t.writeHistogram(f2, f)
- f2.close()
- f.close()
- print "Please open and check histogram.txt."
- raw_input("Press the ENTER key to continue...")