Advertisement
aribahaz

Untitled

Feb 20th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. # Submitter: dcpeng (Peng, Deone)
  2. # Partner : hazaria (Hazari, Areba)
  3. # We certify that we worked cooperatively on this programming
  4. # assignment, according to the rules for pair programming
  5.  
  6. import re, traceback, keyword
  7.  
  8. def pnamedtuple(type_name, field_names, mutable=False):
  9. def show_listing(s):
  10. for aline,its_text in enumerate(s.split('\n'), 1):
  11. print(f' {aline: >3} {its_text.rstrip()}')
  12.  
  13. # put your code here
  14. # bind class_definition (used below) to the string constructed for the class
  15.  
  16. def valid_name(name):
  17. reg_val = '([a-zA-Z])+(\w)*'
  18. valid_reg = re.compile(reg_val)
  19. if type(name) == str:
  20. if keyword.iskeyword(name) == True or name.isdigit() or valid_reg.match(name) == None:
  21. return False
  22. return True
  23.  
  24. if not valid_name(str(type_name)):
  25. raise SyntaxError
  26.  
  27. field_list = []
  28.  
  29. if type(field_names) == list:
  30. for field in field_names:
  31. if not valid_name(field):
  32. raise SyntaxError
  33. elif field not in field_list:
  34. field_list.append(field)
  35.  
  36. elif type(field_names) == str:
  37. fields = re.sub('\,', '', field_names).split()
  38. for val in fields:
  39. if not valid_name(val):
  40. raise SyntaxError
  41. elif len(val) > 0 and val not in field_list:
  42. field_list.append(val)
  43. else:
  44. raise SyntaxError
  45.  
  46. class_template = '''\
  47. class {type_name}:
  48. def __init__(self, {list_names}):
  49. self._fields = [{field_list}]
  50. self._mutable = {self_mutable}
  51. {args}
  52.  
  53. def __getitem__(self, index):
  54. if index in self._fields:
  55. return self.__dict__[index]
  56. elif (type(index) == int) and (0 <= index < len(self._fields)):
  57. string = 'self.get_' + self._fields[index] + '()'
  58. return eval(string)
  59. else:
  60. raise IndexError
  61.  
  62. def __repr__(self):
  63. return '{type_name}({str_format})'.format({self_format})
  64.  
  65. def __eq__(self, rhs):
  66. if type(rhs) == {type_name}:
  67. for field in self._fields:
  68. if self[field] != rhs[field]:
  69. return False
  70. return True
  71. else:
  72. return False
  73.  
  74. def _replace(self, **kargs):
  75. if self._mutable:
  76. for k in kargs:
  77. self.__dict__[k] = kargs[k]
  78. else:
  79. for f in self._fields:
  80. if f not in kargs:
  81. kargs[f] = self.__dict__[f]
  82. return {type_name}(**kargs)'''
  83.  
  84. get_template = '''
  85. def get_{field}(self):
  86. return self.{field}
  87. '''
  88.  
  89. #***********EXTRA CREDIT***************
  90. setattr_template = '''
  91. def __setattr__(self, name, value):
  92. if ('_mutable' not in self.__dict__ or self._mutable) and name in [{fields},'_fields','_mutable']:
  93. self.__dict__[name] = value
  94. else:
  95. raise AttributeError
  96. '''
  97.  
  98. class_definition = class_template.format(
  99. type_name = type_name,
  100. list_names = ','.join(field for field in field_list),
  101. args = ('\n' + 8 * ' ').join('self.{name}={name}'.format(name = field) for field in field_list),
  102. field_list = ','.join("'" + name + "'" for name in field_list),
  103. self_mutable = str(mutable),
  104. str_format = ','.join('{name}={{{name}}}'.format(name = field) for field in field_list),
  105. self_format = ','.join('{name}=self.{name}'.format(name = field) for field in field_list)) \
  106. + "".join([get_template.format(field = field) for field in field_list]) \
  107. #+ setattr_template.format(
  108. # fields = ','.join("'" + name + "'" for name in field_list))
  109.  
  110.  
  111. # For initial debugging, remove comment to show the source code for the class
  112. show_listing(class_definition)
  113.  
  114. # Execute the class_definition string in a local name space; later, bind the
  115. # source_code name in its dictionary to the class_defintion; return the
  116. # class object created; if there is a syntax error, list the class and
  117. # also show the error
  118. name_space = dict(__name__ = f'pnamedtuple_{type_name}')
  119. try:
  120. exec(class_definition,name_space)
  121. name_space[type_name].source_code = class_definition
  122. except [TypeError, SyntaxError]:
  123. show_listing(class_definition)
  124. traceback.print_exc()
  125. return name_space[type_name]
  126.  
  127.  
  128.  
  129. if __name__ == '__main__':
  130. # Test pnamedtuple in script below using Point = pnamedtuple('Point', 'x y')
  131.  
  132. #driver tests
  133. import driver
  134. driver.default_file_name = 'bscp3W18.txt'
  135. # driver.default_show_exception= True
  136. # driver.default_show_exception_message= True
  137. # driver.default_show_traceback= True
  138. driver.driver()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement