Commit ef5254e8 authored by Anton Pershin's avatar Anton Pershin

Added abstract class StandardisedNaming in module comaux and added find_*…

Added abstract class StandardisedNaming in module comaux and added find_* functions to work with standardised names
parent 616a7d69
from functools import reduce
from functools import reduce, partial
import os
import re
import collections
from copy import deepcopy
import importlib
from abc import ABC, abstractmethod
from typing import Optional, List, Tuple, Type, Any
import numpy as np
ArrayItemGetter = collections.namedtuple('ArrayItemGetter', ['key_path_to_array', 'i'])
class StandardisedNaming(ABC):
"""
Class StandardisedNaming is an abstract class used to represent standardised names of files and directories in a
general sense. To make use of its features, one needs to derive one's own class and implement methods
regexp_with_substitutions and make_name. The former should return a group-named regular expression (with or
without substitution) which can be used to recognise whether a concrete name corresponds to the standardised name
or not. The latter should create a concrete standardised name based on its attributes.
"""
@classmethod
def regexp(cls) -> str:
"""
Returns a full group-named regular expression which can be used to determine whether a certain name follows the
standardised naming.
:return: regular expression as a string
"""
return cls.regexp_with_substitutions()
@classmethod
def parse(cls, name: str) -> Optional[dict]:
"""
Checks whether a given name follows the standardised naming and, if yes, parses the name and returns a
dictionary of its attributes.
:param name: name to be parsed
:return: either dictionary of the name attributes or None if a given name does not follow the standardised
naming
"""
return parse_by_named_regexp(cls.regexp(), name)
@classmethod
@abstractmethod
def regexp_with_substitutions(cls, **kwargs) -> str:
"""
Returns a group-named regular expression (if kwargs are given, they will substituted to the regular expression
according to the names) which can be used to recognise whether a concrete name follows the standardised naming
or not.
:param kwargs: name attributes
:return: regular expression as a string
"""
raise NotImplementedError('Must be implemented. It must return the regular expression with substitutions based '
'on kwargs arguments. Being invoked with no arguments, it must return the full '
'regular expression')
@classmethod
@abstractmethod
def make_name(cls, **kwargs) -> str:
"""
Returns name based on the standardised naming and attributes passed via kwargs.
TODO: must be implemented (or joint with regexp_with_substitutions) such that regexp_with_substitutions is
used inside it
:param kwargs: name attributes
:return: name as a string
"""
raise NotImplementedError('Must be implemented. It must return the name using kwards arguments as '
'substitutions')
class ProxyDict(object):
'''
Class allowing to access a dict via a proxy mapping using the same interface as dict does.
......@@ -188,6 +253,8 @@ def find_dir_by_named_regexp(regexp, where):
'''
Search for dir in where which satisfies regexp. If successful, parses the dir according to named regexp.
Returns a tuple (found_dir, params_from_named_regexp) or None if not found.
TODO: depricated (see find_dir_by_standardised_name)
'''
dirnames = next(os.walk(where))[1]
for dir_ in dirnames:
......@@ -200,6 +267,8 @@ def find_all_dirs_by_named_regexp(regexp, where):
'''
Search for dirs in where which satisfies regexp. If successful, parses them according to named regexp.
Returns a list of tuples (found_dir, params_from_named_regexp).
TODO: depricated (see find_all_dirs_by_standardised_name)
'''
dirnames = next(os.walk(where))[1]
datas = []
......@@ -213,6 +282,8 @@ def find_all_files_by_named_regexp(regexp, where):
'''
Search for files in where which satisfies regexp. If successful, parses them according to named regexp.
Returns a list of tuples (found_dir, params_from_named_regexp).
TODO: depricated (see find_all_files_by_standardised_name)
'''
filenames = next(os.walk(where))[2]
datas = []
......@@ -222,6 +293,44 @@ def find_all_files_by_named_regexp(regexp, where):
datas.append((file_, parsing_params))
return datas
def find_dir_by_standardised_naming(naming: Type[StandardisedNaming], where: str) -> Optional[Tuple[str, dict]]:
'''
Search for dir in where which satisfies regexp. If successful, parses the dir according to named regexp.
Returns a tuple (found_dir, params_from_named_regexp) or None if not found.
'''
dirnames = next(os.walk(where))[1]
for dir_ in dirnames:
parsing_params = naming.parse(dir_)
if parsing_params is not None:
return dir_, parsing_params
return None
def find_all_dirs_by_standardised_naming(naming: Type[StandardisedNaming], where: str) -> List[Tuple[str, dict]]:
'''
Search for dirs in where which satisfies regexp. If successful, parses them according to named regexp.
Returns a list of tuples (found_dir, params_from_named_regexp).
'''
dirnames = next(os.walk(where))[1]
datas = []
for dir_ in dirnames:
parsing_params = naming.parse(dir_)
if parsing_params is not None:
datas.append((dir_, parsing_params))
return datas
def find_all_files_by_standardised_naming(naming: Type[StandardisedNaming], where: str) -> List[Tuple[str, dict]]:
'''
Search for files in where which satisfies regexp. If successful, parses them according to named regexp.
Returns a list of tuples (found_dir, params_from_named_regexp).
'''
filenames = next(os.walk(where))[2]
datas = []
for file_ in filenames:
parsing_params = naming.parse(file_)
if parsing_params is not None:
datas.append((file_, parsing_params))
return datas
def parse_by_named_regexp(regexp, val):
'''
Parses val according to named regexp. Return a dictionary of params.
......@@ -308,3 +417,20 @@ def load_function_from_module(full_function_name):
def print_pretty_dict(d):
for k, v in d.items():
print('{}: {}'.format(k ,v))
def raise_exception_if_arguments_not_in_keywords_or_none(argument_names, kwargs) -> None:
for arg in argument_names:
if arg not in kwargs:
raise ValueError('Keywords "{} = ..." must be set'.format(arg))
else:
if kwargs[arg] is None:
raise ValueError('Keywords "{}" must not be None'.format(arg))
def take_value_if_not_none(value, default=None, transform=str) -> Any:
if value is None:
if default is None:
raise ValueError('Value must not be None or default must be set')
else:
return default
else:
return transform(value)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment