Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- #
- #
- 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)*'
- legal_name = re.compile(reg_val)
- if type(name) == str:
- if keyword.iskeyword(name) == True or name.isdigit() or legal_name.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}'''
- repr_template = '''
- def __repr__(self):
- return '{type_name}({str_format})'.format({self_format})'''
- template_get = '''
- def get_{field}(self):
- return self.{field}'''
- get_format = ''' \
- def get_{name}(self):
- return self.{name}'''
- #**********Change self._mutable = mutable(variable) if attempting extra credit - setattr
- getitem_template = '''\
- def __getitem__(self):
- pass
- '''
- eq_template = '''\
- def __eq__(self):
- pass
- '''
- replace_template = '''\
- def _replace(self):
- pass
- '''
- #***********EXTRA CREDIT***************
- setattr_template = '''\
- def __setattr__(self):
- pass
- '''
- 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 = field_list,
- self_mutable = False)
- class_definition += repr_template.format(
- type_name = type_name,
- 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 ))
- class_definition += "".join([template_get.format(field = field) for field 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