Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.08 KB | None | 0 0
  1. '''
  2. Stand alone class to flip a CSV into output for autofill
  3. TLDR; let people buy Glasto tickers quickly
  4.  
  5. defaults to read input.csv from csv/ dir
  6. call with --csv-file buswankers.csv to read csv/buswankers.csv
  7.  
  8. Danny Sept-19
  9. '''
  10. import argparse
  11. import pandas as pd
  12. import numpy as np
  13. from pprint import pprint
  14.  
  15. read_path: str = 'csv/' # Path to read input CSV files from.
  16. max_entries = 6
  17.  
  18. pd.set_option('display.max_rows', 500)
  19. pd.set_option('display.max_columns', 500)
  20. pd.set_option('display.width', 1000)
  21.  
  22. class BusWankers():
  23. '''
  24. general class to take none techie data and make useful
  25. '''
  26. def __init__(self, csv_file: bytes):
  27. self.input_file = '{}{}'.format(read_path, csv_file)
  28.  
  29.  
  30. def read_csv(self) -> pd.DataFrame:
  31. '''
  32. csv into pandas dataframe
  33. drop any empty rows where all cells are NAN
  34. '''
  35. df = pd.read_csv(self.input_file)
  36. df = self._tidy_the_data(df = df)
  37. df = self._rename_cols(df = df)
  38.  
  39. return df
  40.  
  41.  
  42. def _tidy_the_data(self, df: pd.DataFrame) -> pd.DataFrame:
  43. '''
  44. Try and correct the noise from input
  45. '''
  46.  
  47. # Remove any empty lines.
  48. df.dropna(how='all', inplace=True)
  49.  
  50. # Check data types, flip any float.64s to ints - think account numbers in excel as scientific notation.
  51. for _col in list(df):
  52. if (df[_col].dtypes == np.float64) or (df[_col].dtype == np.int64):
  53. df[_col] = df[_col].astype('int64')
  54. print("Corrected Data Type for {} from float64 to int64".format(_col,))
  55.  
  56. return df
  57.  
  58.  
  59. def _rename_cols(self, df: pd.DataFrame) -> pd.DataFrame:
  60. '''
  61. Try and normalise human branded column names to something consistent
  62. '''
  63. group = ['group','grp', 'g']
  64. reg = ['reg', 'registration', 'reg number', 'registration numbers', 'reg', 'number', 'num', 'rn']
  65. forename = ['f_name', 'first', 'first name', 'forname', 'f']
  66. surname = ['s_name', 'last', 'last name', 'surname', 's']
  67. postcode = ['postcode', 'post', 'p']
  68. coach = ['coach', 'coach leave from', 'from', 'depart']
  69.  
  70. list_o_lists = [group, reg, forename, surname, postcode, coach]
  71.  
  72. for _col in list(df):
  73. for _my_list in list_o_lists:
  74.  
  75. if _col.lower() in _my_list:
  76. print("Column Name {} found in {} words".format(_col, _my_list[0]))
  77. df.rename(columns={_col: _my_list[0]}, inplace=True)
  78.  
  79. return df
  80.  
  81. def letter_to_int(self, letter: str) -> int:
  82. '''
  83. A returns 1, b 2, C 3 etc
  84. '''
  85. alphabet = list('abcdefghijklmnopqrstuvwxyz')
  86. return alphabet.index(letter.lower()) + 1
  87.  
  88.  
  89. def write_head_csv(self, df, out_file: str = 'csv/autofill.csv'):
  90. '''
  91. Writes the csv for autofill
  92. '''
  93. # Todo take the output filename as an arg from cmdline
  94. f = open(out_file, "w+")
  95.  
  96. profile_head1 = '### AUTOFILL PROFILES ###,,,,,,\r\n'
  97. profile_head2 = 'Profile ID,Name,Site,Hotkey,,,\r\n'
  98. f.write(profile_head1)
  99. f.write(profile_head2)
  100.  
  101. # write groups
  102. i=0
  103. for g in df.group.unique():
  104. i=i+1
  105. f.write("{}{},{}-{},,,,,\r\n".format('c',i,"Group",g))
  106.  
  107. profile_rule1 = '### AUTOFILL RULES ###,,,,,,\r\n'
  108. profile_rule2 = 'Rule ID,Type,Name,Value,Site,Mode,Profile\r\n'
  109. f.write(profile_rule1)
  110. f.write(profile_rule2)
  111.  
  112. f.close()
  113.  
  114. return
  115.  
  116.  
  117. def write_rules_csv(self, df, out_file: str = 'csv/autofill.csv'):
  118. '''
  119. Write rules section of autofill import
  120. '''
  121. f = open(out_file, "a+")
  122.  
  123. # write rules
  124. g=0 # group counter, always be 0-5, 6
  125. r=1 # row counter - infinate
  126. last_group_code = None # for checking if finish before 6 rows,
  127.  
  128. for index, row in df.iterrows():
  129.  
  130. group_code = 'c{}'.format(self.letter_to_int(row['group']))
  131. l_code = 'c{}'.format(self.letter_to_int(row['group']) - 1)
  132.  
  133. # Handle if on a new group and not written 6 records
  134. if last_group_code:
  135. if last_group_code not in group_code and g > 0:
  136. f.write('r{},0,"registrations_{}__RegistrationId",,"",1,{}\r\n'.format(r, g, l_code))
  137. r = r + 1
  138. f.write('r{},0,"registrations_{}__PostCode",,"",1,{}\r\n'.format(r, g, l_code))
  139. r = r + 1
  140. g = 0
  141.  
  142. last_group_code = group_code
  143. f.write('r{},0,"registrations_{}__RegistrationId","{}","",1,{}\r\n'.format(r, g, row['reg'], group_code ))
  144. r = r + 1
  145. f.write('r{},0,"registrations_{}__Postcode","{}","",1,{}\r\n'.format(r, g, row['postcode'], group_code))
  146. r = r + 1
  147.  
  148. # Handle max 6 in a group
  149. if g == max_entries -1:
  150. g = 0
  151. else:
  152. g = g + 1
  153.  
  154. # handle last record from loop as not the 6th
  155. if g != 0:
  156. while g < max_entries:
  157. f.write('r{},0,"registrations_{}__RegistrationId",,"",1,{}\r\n'.format(r, g, group_code))
  158. r = r + 1
  159. f.write('r{},0,"registrations_{}__PostCode",,"",1,{}\r\n'.format(r, g, group_code))
  160. r = r + 1
  161. g = g + 1
  162.  
  163. f.close()
  164. return
  165.  
  166.  
  167. def write_footer_csv(self, df, out_file: str = 'csv/autofill.csv'):
  168. '''
  169. Write footer section of autofill import
  170. '''
  171. f = open(out_file, "a+")
  172.  
  173. f.write('### AUTOFILL OPTIONS ###,,,,,,\r\n')
  174. f.write('advanced, "[]",, , , ,\r\n')
  175. f.write('exceptions, "[]",, , , ,\r\n')
  176. f.write('textclips, "[]",, , , ,\r\n')
  177. f.write('variables, "[]",, , , ,\r\n')
  178. f.write('backup, 0, 30,, , ,\r\n')
  179. f.write('manual, 0,, , , ,\r\n')
  180. f.write('delay, 1, 1,, , ,\r\n')
  181. f.write('labelmatch, 1,, , , ,\r\n')
  182. f.write('overwrite, 1,, , , ,\r\n')
  183. f.write('vars, 1,, , , ,\r\n')
  184. f.write('sound, 0,, , , ,\r\n')
  185. f.write('voice, 0, 1,, , ,\r\n')
  186. f.write('debug, 0,, , , ,\r\n')
  187. f.write('mask, 1,, , , ,\r\n')
  188. f.write('scale, 1,, , , ,\r\n')
  189. f.write('menu, 1,, , , ,\r\n')
  190. f.write('autoimport, 0,, , , ,\r\n')
  191.  
  192. f.close()
  193.  
  194.  
  195. def check_args(parser=None) -> argparse:
  196. '''
  197. Check to override default csv file name, defaults to `input.csv`
  198. '''
  199. if parser is None:
  200. parser = argparse.ArgumentParser(description='Glastonbury buswankers!')
  201.  
  202. parser.add_argument(
  203. "--csv-file",
  204. help="This is the input file to parse from the csv/ directory. Defaults to input.csv",
  205. type=str,
  206. default="input.csv",
  207. dest="csv_file",
  208. required=False
  209. )
  210.  
  211. args = parser.parse_args()
  212. return args
  213.  
  214. def main():
  215. # use default file name or another
  216. args = check_args()
  217.  
  218. # shoot for the moon..
  219. ma = BusWankers(args.csv_file)
  220. df = ma.read_csv()
  221.  
  222. # write the csv for autofill
  223. ma.write_head_csv(df)
  224. ma.write_rules_csv(df)
  225. ma.write_footer_csv(df)
  226.  
  227. print(df)
  228.  
  229.  
  230. if __name__ == '__main__':
  231. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement