You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

176 lines
4.8KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. '''
  4. Data module for a Kai's Text Tools.
  5. (c) 2013 Ivan "Kai SD" Korystin
  6. License: GPLv3
  7. '''
  8. import csv, codecs
  9. class Data(object):
  10. '''
  11. Empty data class. Can be used for a subclassing or procedural data creation.
  12. '''
  13. def __init__(self, *args, **kwargs):
  14. '''
  15. Constructor
  16. '''
  17. self.keys = []
  18. self.rows = []
  19. def __getitem__(self, pair):
  20. '''
  21. Returns a value for given key and row.
  22. '''
  23. key = pair[0]
  24. row = pair[1]
  25. keys = self.keys
  26. rows = self.rows
  27. if key in keys:
  28. if len(rows) > row:
  29. return rows[row][keys.index(key)]
  30. else:
  31. raise BaseException('Row %i not found in data' % (row))
  32. else:
  33. raise BaseException('Named value %s not found in data' % (key))
  34. def __setitem__(self, pair, value):
  35. '''
  36. Sets a value for given key and row.
  37. '''
  38. key = pair[0]
  39. row = pair[1]
  40. keys = self.keys
  41. rows = self.rows
  42. if key in keys:
  43. if len(rows) > row:
  44. rows[row][keys.index(key)] = value
  45. else:
  46. raise BaseException('Row %i not found in data' % (row))
  47. else:
  48. raise BaseException('Named value %s not found in data' % (key))
  49. def __str__(self):
  50. '''
  51. Returns data as string.
  52. '''
  53. return str((self.keys, self.rows))
  54. def __repr__(self):
  55. return self.__str__()
  56. def has_key(self, key):
  57. '''
  58. Returns True if given key exists in data
  59. '''
  60. return key in self.keys
  61. def add_rows(self, n=1):
  62. '''
  63. Adds some empty rows to the data.
  64. '''
  65. keys = self.keys
  66. rows = self.rows
  67. for n in xrange(0, n):
  68. row = []
  69. for k in keys:
  70. row.append('')
  71. rows.append(row)
  72. def add_keys(self, *h):
  73. '''
  74. Adds new keys to the data.
  75. '''
  76. keys = self.keys
  77. rows = self.rows
  78. for i in h:
  79. keys.append(i)
  80. for r in rows:
  81. for i in h:
  82. r.append('')
  83. def col_by_key(self, key):
  84. cols = []
  85. keys = self.keys
  86. rows = self.rows
  87. if key in keys:
  88. idx = keys.index(key)
  89. for r in rows:
  90. cols.append(r[idx])
  91. else:
  92. raise BaseException('Named value %s not found in data' % (key))
  93. return tuple(cols)
  94. def row_by_idx(self, idx):
  95. return tuple(self.rows[idx])
  96. class CSVData(Data):
  97. '''
  98. Class for reading CSV files.
  99. '''
  100. class Reader:
  101. class Recoder:
  102. def __init__(self, f, encoding):
  103. self.reader = codecs.getreader(encoding)(f)
  104. def __iter__(self):
  105. return self
  106. def next(self):
  107. return self.reader.next().encode("utf-8")
  108. def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
  109. f = self.Recoder(f, encoding)
  110. self.reader = csv.reader(f, dialect=dialect, **kwds)
  111. def next(self):
  112. row = self.reader.next()
  113. return [unicode(s, "utf-8") for s in row]
  114. def __iter__(self):
  115. return self
  116. def __init__(self, filename, encoding='utf-8', delimiter=';', quotechar='"', **kwargs):
  117. csvfile = self.Reader(open(filename), encoding=encoding, delimiter=delimiter, quotechar=quotechar)
  118. sourceData = []
  119. sourcekeys = None
  120. if kwargs.get('transpose', False):
  121. sourcekeys = []
  122. rowData = []
  123. for i in csvfile:
  124. sourcekeys.append(i[0])
  125. for k in xrange(1, len(i)):
  126. sourceData.append([])
  127. try:
  128. i[k] = int(i[k])
  129. except:
  130. try:
  131. i[k] = float(i[k])
  132. except:
  133. i[k] = i[k]
  134. rowData.append(i[1:])
  135. sourceData = list(map(lambda *x:x, *rowData))
  136. else:
  137. for i in csvfile:
  138. if sourcekeys is None:
  139. sourcekeys = i
  140. else:
  141. for k in xrange(0, len(i)):
  142. try:
  143. i[k] = int(i[k])
  144. except:
  145. try:
  146. i[k] = float(i[k])
  147. except:
  148. i[k] = i[k]
  149. sourceData.append(i)
  150. self.keys = sourcekeys
  151. self.rows = sourceData