Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Submitter: dcpeng (Peng, Deone)
- # Partner : hazaria (Hazari, Areba)
- # We certify that we worked cooperatively on this programming
- # assignment, according to the rules for pair programming
- import re, traceback, keyword
- def pnamedtuple(type_name, field_names, mutable=False):
- def show_listing(s):
- for aline,its_text in enumerate(s.split('\n'), 1):
- print(f' {aline: >3} {its_text.rstrip()}')
- # put your code here
- # bind class_definition (used below) to the string constructed for the class
- def valid_name(name):
- reg_val = '([a-zA-Z])+(\w)*'
- valid_reg = re.compile(reg_val)
- if type(name) == str:
- if keyword.iskeyword(name) == True or name.isdigit() or valid_reg.match(name) == None:
- return False
- return True
- if not valid_name(str(type_name)):
- raise SyntaxError
- field_list = []
- if type(field_names) == list:
- for field in field_names:
- if not valid_name(field):
- raise SyntaxError
- elif field not in field_list:
- field_list.append(field)
- elif type(field_names) == str:
- fields = re.sub('\,', '', field_names).split()
- for val in fields:
- if not valid_name(val):
- raise SyntaxError
- elif len(val) > 0 and val not in field_list:
- field_list.append(val)
- else:
- raise SyntaxError
- class_template = '''\
- class {type_name}:
- def __init__(self, {list_names}):
- self._fields = [{field_list}]
- self._mutable = {self_mutable}
- {args}
- def __getitem__(self, index):
- if index in self._fields:
- return self.__dict__[index]
- elif (type(index) == int) and (0 <= index < len(self._fields)):
- string = 'self.get_' + self._fields[index] + '()'
- return eval(string)
- else:
- raise IndexError
- def __repr__(self):
- return '{type_name}({str_format})'.format({self_format})
- def __eq__(self, rhs):
- if type(rhs) == {type_name}:
- for field in self._fields:
- if self[field] != rhs[field]:
- return False
- return True
- else:
- return False
- def _replace(self, **kargs):
- if self._mutable:
- for k in kargs:
- self.__dict__[k] = kargs[k]
- else:
- for f in self._fields:
- if f not in kargs:
- kargs[f] = self.__dict__[f]
- return {type_name}(**kargs)'''
- get_template = '''
- def get_{field}(self):
- return self.{field}
- '''
- #***********EXTRA CREDIT***************
- setattr_template = '''
- def __setattr__(self, name, value):
- if ('_mutable' not in self.__dict__ or self._mutable) and name in [{fields},'_fields','_mutable']:
- self.__dict__[name] = value
- else:
- raise AttributeError
- '''
- class_definition = class_template.format(
- type_name = type_name,
- list_names = ','.join(field for field in field_list),
- args = ('\n' + 8 * ' ').join('self.{name}={name}'.format(name = field) for field in field_list),
- field_list = ','.join("'" + name + "'" for name in field_list),
- self_mutable = str(mutable),
- str_format = ','.join('{name}={{{name}}}'.format(name = field) for field in field_list),
- self_format = ','.join('{name}=self.{name}'.format(name = field) for field in field_list)) \
- + "".join([get_template.format(field = field) for field in field_list]) \
- #+ setattr_template.format(
- # fields = ','.join("'" + name + "'" for name in field_list))
- # For initial debugging, remove comment to show the source code for the class
- show_listing(class_definition)
- # Execute the class_definition string in a local name space; later, bind the
- # source_code name in its dictionary to the class_defintion; return the
- # class object created; if there is a syntax error, list the class and
- # also show the error
- name_space = dict(__name__ = f'pnamedtuple_{type_name}')
- try:
- exec(class_definition,name_space)
- name_space[type_name].source_code = class_definition
- except [TypeError, SyntaxError]:
- show_listing(class_definition)
- traceback.print_exc()
- return name_space[type_name]
- if __name__ == '__main__':
- # Test pnamedtuple in script below using Point = pnamedtuple('Point', 'x y')
- #driver tests
- import driver
- driver.default_file_name = 'bscp3W18.txt'
- # driver.default_show_exception= True
- # driver.default_show_exception_message= True
- # driver.default_show_traceback= True
- driver.driver()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement