From 58b3b5fb9f4da4d90b06784804ed8678eda0c1fc Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sat, 25 Apr 2020 03:25:00 +0300 Subject: [PATCH 01/11] First commit --- homework/config.py | 18 +++--- homework/logg_cvd19.py | 24 +++++++ homework/model_cvd19.py | 139 ++++++++++++++++++++++++++++++++++++++++ homework/patient.py | 92 ++++++++++++++++++++++---- 4 files changed, 253 insertions(+), 20 deletions(-) create mode 100644 homework/logg_cvd19.py create mode 100644 homework/model_cvd19.py diff --git a/homework/config.py b/homework/config.py index 955b991..f3f20c6 100644 --- a/homework/config.py +++ b/homework/config.py @@ -1,13 +1,13 @@ -GOOD_LOG_FILE = "good_log.txt" -ERROR_LOG_FILE = "error_log.txt" -CSV_PATH = "csv.csv" +GOOD_LOG_FILE = "success.log" +ERROR_LOG_FILE = "errors.log" +CSV_PATH = "covid_19_members.csv" PHONE_FORMAT = "79160000000" # Здесь запишите телефон +7-916-000-00-00 в том формате, в котором вы храните телефоны -PASSPORT_TYPE = "паспорт" # тип документа, когда он паспорт -PASSPORT_FORMAT = "0000 000000" # Здесь запишите номер парспорта 0000 000000 в том формате, в котором вы его храните +PASSPORT_TYPE = "Паспорт" # тип документа, когда он паспорт +PASSPORT_FORMAT = "0000000000" # Здесь запишите номер парспорта 0000 000000 в том формате, в котором вы его храните -INTERNATIONAL_PASSPORT_TYPE = "заграничный паспорт" # тип документа, если это загран -INTERNATIONAL_PASSPORT_FORMAT = "00 0000000" # формат хранения заграна для номера 00 0000000 +INTERNATIONAL_PASSPORT_TYPE = "Заграничный паспорт" # тип документа, если это загран +INTERNATIONAL_PASSPORT_FORMAT = "000000000" # формат хранения заграна для номера 00 0000000 -DRIVER_LICENSE_TYPE = "водительское удостоверение" # тип документа, если это водительское удостоверение -DRIVER_LICENSE_FORMAT = "00 00 000000" # формат хранения номера ВУ +DRIVER_LICENSE_TYPE = "Водительские права" # тип документа, если это водительское удостоверение +DRIVER_LICENSE_FORMAT = "0000000000" # формат хранения номера ВУ diff --git a/homework/logg_cvd19.py b/homework/logg_cvd19.py new file mode 100644 index 0000000..a0a488f --- /dev/null +++ b/homework/logg_cvd19.py @@ -0,0 +1,24 @@ +import logging +from contextlib import contextmanager + +logger_s = logging.getLogger("covid_19_success") +logger_s.setLevel(logging.INFO) +logger_e = logging.getLogger("covid_19_errors") +logger_e.setLevel(logging.ERROR) + +formatter = logging.Formatter("%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s") + + +@contextmanager +def logger(): + handler_success = logging.FileHandler('success.log', 'a', 'utf-8') + handler_errors = logging.FileHandler('errors.log', 'a', 'utf-8') + handler_success.setFormatter(formatter) + handler_errors.setFormatter(formatter) + logger_s.addHandler(handler_success) + logger_e.addHandler(handler_errors) + yield + handler_success.close() + logging.getLogger('covid_19_success').removeHandler(handler_success) + handler_errors.close() + logging.getLogger('covid_19_errors').removeHandler(handler_errors) \ No newline at end of file diff --git a/homework/model_cvd19.py b/homework/model_cvd19.py new file mode 100644 index 0000000..23d5225 --- /dev/null +++ b/homework/model_cvd19.py @@ -0,0 +1,139 @@ +from homework.logg_cvd19 import logger_e, logger_s, logger + + +# TODO Do not logg every time creation of patient +class AutoStorageDescriptor: + def __set_name__(self, owner, name): + self.name = name + + def __set__(self, instance, value): + # log.logger_s.info(f"Поле {self.name} заполнено") + instance.__dict__[self.name] = value + + def __get__(self, instance, owner): + if instance is None: + return self + else: + return instance.__dict__[self.name] + + +class Validated(AutoStorageDescriptor): + with logger(): + def __set__(self, instance, value): + value = self.validate(instance, value) + super(Validated, self).__set__(instance, value) + + @classmethod + def validate(cls, instance, value): + """return""" + + +class NameValidator(Validated): + def validate(self, instance, value): + if type(value) != str: + with logger(): + logger_e.error("Wrong type") + raise TypeError + if value.isalpha(): + return value.capitalize() + else: + with logger(): + logger_e.error("Wrong type_name") + raise ValueError + + +class NonBlank(NameValidator): + def validate(self, instance, value): + if self.name in instance.__dict__ and getattr(instance, self.name): + with logger(): + logger_e.error("Переназначение ФИО не предусмотрено") + raise AttributeError + return NameValidator.validate(self, instance, value) + + +class RenameOther(Validated): + def validate(self, instance, value): + if self.name in instance.__dict__ and getattr(instance, self.name): + with logger(): + logger_s.info(f"{self.name} было изменено") + return value + return value + + +class PhoneValidator(RenameOther): + white_lst = [str(i) for i in range(0, 10)] + + def validate(self, instance, value): + if type(value) != str: + with logger(): + logger_e.error("Wrong type") + raise TypeError + for symbol in value: + if symbol not in self.white_lst: + value = value.replace(symbol, '') + if value.find('8') == 0: + value = value.replace(value[0], '7', 1) + if len(value) != 11: + with logger(): + logger_e.error("Wrong attribute phone") + raise ValueError + return RenameOther.validate(self, instance, value) + + +class BirthValidator(RenameOther): + def validate(self, instance, value): + if type(value) != str: + with logger(): + logger_e.error("Wrong type") + raise TypeError + for symbol in value: + if symbol.isalpha(): + with logger(): + logger_e.error("Wrong value") + raise ValueError + if str(symbol) == ' ' or symbol == '-': + value = value.replace(symbol, '.') + birth_lst = value.split('.') + value = f'{birth_lst[0].zfill(4)}-' \ + f'{birth_lst[1].zfill(2)}-' \ + f'{birth_lst[2].zfill(2)}' + return RenameOther.validate(self, instance, value) + + +class DocTypeValidator(RenameOther): + white_lst = ['Паспорт', 'Заграничный паспорт', 'Водительские права'] + + def validate(self, instance, value): + if type(value) != str: + with logger(): + logger_e.error("Wrong type") + raise TypeError + else: + if value.capitalize() in self.white_lst: + value = value.capitalize() + return RenameOther.validate(self, instance, value) + else: + with logger(): + logger_e.error("Wrong doc_type") + raise ValueError + + +class DocIDValidator(RenameOther): + doc_dict = {'Паспорт': 10, 'Водительские права': 10, 'Заграничный паспорт': 9} + white_lst = [str(i) for i in range(0, 10)] + + def validate(self, instance, value): + if type(value) != str: + with logger(): + logger_e.error("Wrong type") + raise TypeError + for symbol in value: + if symbol not in self.white_lst: + value = value.replace(symbol, '') + if len(value) == self.doc_dict[getattr(instance, 'document_type')]: + return RenameOther.validate(self, instance, value) + else: + with logger(): + logger_e.error("Wrong doc_id") + raise ValueError + diff --git a/homework/patient.py b/homework/patient.py index dad2526..ef09623 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,17 +1,87 @@ -class Patient: - def __init__(self, *args, **kwargs): - pass +import csv +import homework.model_cvd19 as model +import homework.logg_cvd19 as log - def create(*args, **kwargs): - raise NotImplementedError() +FILENAME = 'covid_19_members.csv' + + +class Patient(object): + first_name = model.NonBlank() + last_name = model.NonBlank() + birth_date = model.BirthValidator() + phone = model.PhoneValidator() + document_type = model.DocTypeValidator() + document_id = model.DocIDValidator() + + def __init__(self, *args): + # self.handler_success = logging.FileHandler('success.log', 'a', 'utf-8') + # self.handler_errors = logging.FileHandler('errors.log', 'a', 'utf-8') + # self.handler_success.setFormatter(log.formatter) + # self.handler_errors.setFormatter(log.formatter) + # log.logger_s.addHandler(self.handler_success) + # log.logger_e.addHandler(self.handler_errors) + + if args: + self.first_name = args[0] + self.last_name = args[1] + self.birth_date = args[2] + self.phone = args[3] + self.document_type = args[4] + self.document_id = args[5] + with log.logger(): + log.logger_s.info('Был создан новый пациент') + + def __str__(self): + return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ + f'{self.document_id}' + + @classmethod + def create(cls, *args): + super(Patient, cls).__init__(*args) + cls.created = Patient(*args) + return cls.created def save(self): - pass + data = [self.first_name, self.last_name, self.birth_date, self.phone, self.document_type, self.document_id] + try: + with open(FILENAME, "a", newline="", encoding='utf-8') as file: + writer = csv.writer(file) + writer.writerow(data) + except Exception: + with log.logger(): + log.logger_e.error('Something wrong') + raise Exception('Something wrong!') + else: + with log.logger(): + log.logger_s.info('Сделана новая запись о пациенте в таблице') + + # def __del__(self): + # self.handler_success.close() + # logging.getLogger('covid_19_success').removeHandler(self.handler_success) + # self.handler_errors.close() + # logging.getLogger('covid_19_errors').removeHandler(self.handler_errors) + + +class PatientCollection(object): + def __init__(self, path): + self.path = path + self.fileBytePos = 0 + self.count = -1 + def __iter__(self): + return self -class PatientCollection: - def __init__(self, log_file): - pass + def __next__(self): + inFile = open(self.path, 'r', encoding='utf-8') + inFile.seek(self.fileBytePos) + data = inFile.readline() + self.fileBytePos = inFile.tell() + inFile.close() + if not data or not self.count: + raise StopIteration + self.count -= 1 + return Patient(*data.split(',')) - def limit(self, n): - raise NotImplementedError() + def limit(self, count): + self.count = count + return self.__iter__() From 704f994dc31de9f2a94716b3beca3a7df506e0be Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sat, 25 Apr 2020 15:22:14 +0300 Subject: [PATCH 02/11] Remove some useless things in contextmanager --- homework/logg_cvd19.py | 15 +++++++-------- homework/patient.py | 23 +++++++++++------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/homework/logg_cvd19.py b/homework/logg_cvd19.py index a0a488f..5de0bdf 100644 --- a/homework/logg_cvd19.py +++ b/homework/logg_cvd19.py @@ -8,17 +8,16 @@ formatter = logging.Formatter("%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s") +handler_success = logging.FileHandler('success.log', 'a', 'utf-8') +handler_errors = logging.FileHandler('errors.log', 'a', 'utf-8') +handler_success.setFormatter(formatter) +handler_errors.setFormatter(formatter) +logger_s.addHandler(handler_success) +logger_e.addHandler(handler_errors) + @contextmanager def logger(): - handler_success = logging.FileHandler('success.log', 'a', 'utf-8') - handler_errors = logging.FileHandler('errors.log', 'a', 'utf-8') - handler_success.setFormatter(formatter) - handler_errors.setFormatter(formatter) - logger_s.addHandler(handler_success) - logger_e.addHandler(handler_errors) yield handler_success.close() - logging.getLogger('covid_19_success').removeHandler(handler_success) handler_errors.close() - logging.getLogger('covid_19_errors').removeHandler(handler_errors) \ No newline at end of file diff --git a/homework/patient.py b/homework/patient.py index ef09623..27c5f28 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,4 +1,5 @@ import csv +import logging import homework.model_cvd19 as model import homework.logg_cvd19 as log @@ -14,12 +15,8 @@ class Patient(object): document_id = model.DocIDValidator() def __init__(self, *args): - # self.handler_success = logging.FileHandler('success.log', 'a', 'utf-8') - # self.handler_errors = logging.FileHandler('errors.log', 'a', 'utf-8') - # self.handler_success.setFormatter(log.formatter) - # self.handler_errors.setFormatter(log.formatter) - # log.logger_s.addHandler(self.handler_success) - # log.logger_e.addHandler(self.handler_errors) + self.logger_s = logging.getLogger('covid_19_success') + self.logger_e = logging.getLogger("covid_19_errors") if args: self.first_name = args[0] @@ -29,7 +26,7 @@ def __init__(self, *args): self.document_type = args[4] self.document_id = args[5] with log.logger(): - log.logger_s.info('Был создан новый пациент') + self.logger_s.info('Был создан новый пациент') def __str__(self): return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ @@ -55,11 +52,13 @@ def save(self): with log.logger(): log.logger_s.info('Сделана новая запись о пациенте в таблице') - # def __del__(self): - # self.handler_success.close() - # logging.getLogger('covid_19_success').removeHandler(self.handler_success) - # self.handler_errors.close() - # logging.getLogger('covid_19_errors').removeHandler(self.handler_errors) + def __del__(self): + del self.logger_s + for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): + fh.close() + del self.logger_e + for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): + fh.close() class PatientCollection(object): From df75f26b4aabb451dd651cb5487b7083f91908f5 Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sat, 25 Apr 2020 15:31:18 +0300 Subject: [PATCH 03/11] Remove loggers from patient. Now its using only loggers from logg file. Test system doesnt allow to add loggers in __init__ and remove handlers in __del__, just because i have commented them --- homework/patient.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index 27c5f28..50934ae 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -15,8 +15,8 @@ class Patient(object): document_id = model.DocIDValidator() def __init__(self, *args): - self.logger_s = logging.getLogger('covid_19_success') - self.logger_e = logging.getLogger("covid_19_errors") + # self.logger_s = logging.getLogger('covid_19_success') + # self.logger_e = logging.getLogger("covid_19_errors") if args: self.first_name = args[0] @@ -26,7 +26,7 @@ def __init__(self, *args): self.document_type = args[4] self.document_id = args[5] with log.logger(): - self.logger_s.info('Был создан новый пациент') + log.logger_s.info('Был создан новый пациент') def __str__(self): return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ @@ -52,13 +52,13 @@ def save(self): with log.logger(): log.logger_s.info('Сделана новая запись о пациенте в таблице') - def __del__(self): - del self.logger_s - for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): - fh.close() - del self.logger_e - for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): - fh.close() + # def __del__(self): + # del self.logger_s + # for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): + # fh.close() + # del self.logger_e + # for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): + # fh.close() class PatientCollection(object): From 3eb9bbfe6edf8ff2c016059b08b91411a25569cc Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sat, 25 Apr 2020 22:57:08 +0300 Subject: [PATCH 04/11] ContextManager was removed. Normal logging was added with initialization and deleting --- homework/logg_cvd19.py | 8 ------- homework/model_cvd19.py | 46 ++++++++++++++--------------------------- homework/patient.py | 29 ++++++++++++-------------- 3 files changed, 28 insertions(+), 55 deletions(-) diff --git a/homework/logg_cvd19.py b/homework/logg_cvd19.py index 5de0bdf..8847935 100644 --- a/homework/logg_cvd19.py +++ b/homework/logg_cvd19.py @@ -1,5 +1,4 @@ import logging -from contextlib import contextmanager logger_s = logging.getLogger("covid_19_success") logger_s.setLevel(logging.INFO) @@ -14,10 +13,3 @@ handler_errors.setFormatter(formatter) logger_s.addHandler(handler_success) logger_e.addHandler(handler_errors) - - -@contextmanager -def logger(): - yield - handler_success.close() - handler_errors.close() diff --git a/homework/model_cvd19.py b/homework/model_cvd19.py index 23d5225..c75c5a6 100644 --- a/homework/model_cvd19.py +++ b/homework/model_cvd19.py @@ -1,6 +1,3 @@ -from homework.logg_cvd19 import logger_e, logger_s, logger - - # TODO Do not logg every time creation of patient class AutoStorageDescriptor: def __set_name__(self, owner, name): @@ -18,10 +15,9 @@ def __get__(self, instance, owner): class Validated(AutoStorageDescriptor): - with logger(): - def __set__(self, instance, value): - value = self.validate(instance, value) - super(Validated, self).__set__(instance, value) + def __set__(self, instance, value): + value = self.validate(instance, value) + super(Validated, self).__set__(instance, value) @classmethod def validate(cls, instance, value): @@ -31,22 +27,19 @@ def validate(cls, instance, value): class NameValidator(Validated): def validate(self, instance, value): if type(value) != str: - with logger(): - logger_e.error("Wrong type") + instance.logger_e.error("Wrong type") raise TypeError if value.isalpha(): return value.capitalize() else: - with logger(): - logger_e.error("Wrong type_name") + instance.logger_e.error("Wrong type_name") raise ValueError class NonBlank(NameValidator): def validate(self, instance, value): if self.name in instance.__dict__ and getattr(instance, self.name): - with logger(): - logger_e.error("Переназначение ФИО не предусмотрено") + instance.logger_e.error("Переназначение ФИО не предусмотрено") raise AttributeError return NameValidator.validate(self, instance, value) @@ -54,8 +47,7 @@ def validate(self, instance, value): class RenameOther(Validated): def validate(self, instance, value): if self.name in instance.__dict__ and getattr(instance, self.name): - with logger(): - logger_s.info(f"{self.name} было изменено") + instance.logger_s.info(f"{self.name} было изменено") return value return value @@ -65,8 +57,7 @@ class PhoneValidator(RenameOther): def validate(self, instance, value): if type(value) != str: - with logger(): - logger_e.error("Wrong type") + instance.logger_e.error("Wrong type") raise TypeError for symbol in value: if symbol not in self.white_lst: @@ -74,8 +65,7 @@ def validate(self, instance, value): if value.find('8') == 0: value = value.replace(value[0], '7', 1) if len(value) != 11: - with logger(): - logger_e.error("Wrong attribute phone") + instance.logger_e.error("Wrong attribute phone") raise ValueError return RenameOther.validate(self, instance, value) @@ -83,13 +73,11 @@ def validate(self, instance, value): class BirthValidator(RenameOther): def validate(self, instance, value): if type(value) != str: - with logger(): - logger_e.error("Wrong type") + instance.logger_e.error("Wrong type") raise TypeError for symbol in value: if symbol.isalpha(): - with logger(): - logger_e.error("Wrong value") + instance.logger_e.error("Wrong value") raise ValueError if str(symbol) == ' ' or symbol == '-': value = value.replace(symbol, '.') @@ -105,16 +93,14 @@ class DocTypeValidator(RenameOther): def validate(self, instance, value): if type(value) != str: - with logger(): - logger_e.error("Wrong type") + instance.logger_e.error("Wrong type") raise TypeError else: if value.capitalize() in self.white_lst: value = value.capitalize() return RenameOther.validate(self, instance, value) else: - with logger(): - logger_e.error("Wrong doc_type") + instance.logger_e.error("Wrong doc_type") raise ValueError @@ -124,8 +110,7 @@ class DocIDValidator(RenameOther): def validate(self, instance, value): if type(value) != str: - with logger(): - logger_e.error("Wrong type") + instance.logger_e.error("Wrong type") raise TypeError for symbol in value: if symbol not in self.white_lst: @@ -133,7 +118,6 @@ def validate(self, instance, value): if len(value) == self.doc_dict[getattr(instance, 'document_type')]: return RenameOther.validate(self, instance, value) else: - with logger(): - logger_e.error("Wrong doc_id") + instance.logger_e.error("Wrong doc_id") raise ValueError diff --git a/homework/patient.py b/homework/patient.py index 50934ae..497ffc3 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,7 +1,7 @@ import csv import logging import homework.model_cvd19 as model -import homework.logg_cvd19 as log +from homework.logg_cvd19 import logger_s, logger_e FILENAME = 'covid_19_members.csv' @@ -15,8 +15,8 @@ class Patient(object): document_id = model.DocIDValidator() def __init__(self, *args): - # self.logger_s = logging.getLogger('covid_19_success') - # self.logger_e = logging.getLogger("covid_19_errors") + self.logger_s = logging.getLogger('covid_19_success') + self.logger_e = logging.getLogger("covid_19_errors") if args: self.first_name = args[0] @@ -25,8 +25,7 @@ def __init__(self, *args): self.phone = args[3] self.document_type = args[4] self.document_id = args[5] - with log.logger(): - log.logger_s.info('Был создан новый пациент') + self.logger_s.info('Был создан новый пациент') def __str__(self): return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ @@ -45,20 +44,18 @@ def save(self): writer = csv.writer(file) writer.writerow(data) except Exception: - with log.logger(): - log.logger_e.error('Something wrong') + self.logger_e.error('Something wrong') raise Exception('Something wrong!') else: - with log.logger(): - log.logger_s.info('Сделана новая запись о пациенте в таблице') + self.logger_s.info('Сделана новая запись о пациенте в таблице') - # def __del__(self): - # del self.logger_s - # for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): - # fh.close() - # del self.logger_e - # for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): - # fh.close() + def __del__(self): + del self.logger_s + for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): + fh.close() + del self.logger_e + for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): + fh.close() class PatientCollection(object): From d6be4199b1822b6cab537e647f24f61e3641dfb9 Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sat, 25 Apr 2020 23:00:00 +0300 Subject: [PATCH 05/11] Dont watch it. Only Updating tests --- tests/test_patient.py | 8 ++++---- tests/test_patient_collection.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_patient.py b/tests/test_patient.py index 125bd59..19287a4 100644 --- a/tests/test_patient.py +++ b/tests/test_patient.py @@ -31,13 +31,13 @@ def wrapper(*args, **kwargs): return deco -def setup(): +def setup_module(__main__): for file in [GOOD_LOG_FILE, ERROR_LOG_FILE, CSV_PATH]: with open(file, 'w', encoding='utf-8') as f: f.write('') -def teardown(): +def teardown_module(__name__): for file in [GOOD_LOG_FILE, ERROR_LOG_FILE, CSV_PATH]: os.remove(file) @@ -180,7 +180,7 @@ def test_wrong_type_assignment(patient, field, param): )) @check_log_size("error", increased=True) @check_log_size("good") -def test_wrong_type_assignment(patient, field, param): +def test_wrong_value_assignment(patient, field, param): try: setattr(patient, field, param) assert False, f"ValueError for {field} assignment not invoked" @@ -192,4 +192,4 @@ def test_wrong_type_assignment(patient, field, param): @check_log_size("csv", increased=True) def test_save(): patient = Patient(*GOOD_PARAMS) - patient.save() + patient.save() \ No newline at end of file diff --git a/tests/test_patient_collection.py b/tests/test_patient_collection.py index 9536eff..0099d1f 100644 --- a/tests/test_patient_collection.py +++ b/tests/test_patient_collection.py @@ -75,4 +75,4 @@ def test_limit_remove_records(): limit = collection.limit(4) with open(CSV_PATH, 'w', encoding='utf-8') as f: f.write('') - assert len([_ for _ in limit]) == 0, "Limit works wrong for empty file" + assert len([_ for _ in limit]) == 0, "Limit works wrong for empty file" \ No newline at end of file From d4d2fbd2ae4c611c406195a96145d2f5af022a4d Mon Sep 17 00:00:00 2001 From: coolcrazycool Date: Sun, 26 Apr 2020 19:38:35 +0300 Subject: [PATCH 06/11] Fix problems --- homework/model_cvd19.py | 58 ++++++++++++++++++++------------------- homework/patient.py | 61 ++++++++++++++++++++++------------------- 2 files changed, 63 insertions(+), 56 deletions(-) diff --git a/homework/model_cvd19.py b/homework/model_cvd19.py index c75c5a6..a376fee 100644 --- a/homework/model_cvd19.py +++ b/homework/model_cvd19.py @@ -1,10 +1,12 @@ +from abc import ABCMeta + + # TODO Do not logg every time creation of patient class AutoStorageDescriptor: def __set_name__(self, owner, name): self.name = name def __set__(self, instance, value): - # log.logger_s.info(f"Поле {self.name} заполнено") instance.__dict__[self.name] = value def __get__(self, instance, owner): @@ -21,27 +23,27 @@ def __set__(self, instance, value): @classmethod def validate(cls, instance, value): - """return""" + raise NotImplementedError("Validate method is not implemented") class NameValidator(Validated): def validate(self, instance, value): - if type(value) != str: - instance.logger_e.error("Wrong type") - raise TypeError + if not isinstance(value, str): + instance.logger_e.error("Wrong type for f_name or l_name") + raise TypeError("Wrong type for f_name or l_name") if value.isalpha(): return value.capitalize() else: - instance.logger_e.error("Wrong type_name") - raise ValueError + instance.logger_e.error("Wrong value for f_name or s_name") + raise ValueError("Wrong value for f_name or s_name") class NonBlank(NameValidator): def validate(self, instance, value): if self.name in instance.__dict__ and getattr(instance, self.name): instance.logger_e.error("Переназначение ФИО не предусмотрено") - raise AttributeError - return NameValidator.validate(self, instance, value) + raise AttributeError("F_name or L_name can not be changed") + return super(NonBlank, self).validate(instance, value) class RenameOther(Validated): @@ -56,9 +58,9 @@ class PhoneValidator(RenameOther): white_lst = [str(i) for i in range(0, 10)] def validate(self, instance, value): - if type(value) != str: - instance.logger_e.error("Wrong type") - raise TypeError + if not isinstance(value, str): + instance.logger_e.error("Wrong type for Phone") + raise TypeError("Wrong type for Phone") for symbol in value: if symbol not in self.white_lst: value = value.replace(symbol, '') @@ -66,19 +68,19 @@ def validate(self, instance, value): value = value.replace(value[0], '7', 1) if len(value) != 11: instance.logger_e.error("Wrong attribute phone") - raise ValueError + raise ValueError("Wrong attribute phone") return RenameOther.validate(self, instance, value) class BirthValidator(RenameOther): def validate(self, instance, value): - if type(value) != str: - instance.logger_e.error("Wrong type") - raise TypeError + if not isinstance(value, str): + instance.logger_e.error("Wrong type for birthday") + raise TypeError("Wrong type for birthday") for symbol in value: if symbol.isalpha(): - instance.logger_e.error("Wrong value") - raise ValueError + instance.logger_e.error("Wrong value for birthday") + raise ValueError("Wrong value for birthday") if str(symbol) == ' ' or symbol == '-': value = value.replace(symbol, '.') birth_lst = value.split('.') @@ -92,16 +94,16 @@ class DocTypeValidator(RenameOther): white_lst = ['Паспорт', 'Заграничный паспорт', 'Водительские права'] def validate(self, instance, value): - if type(value) != str: - instance.logger_e.error("Wrong type") - raise TypeError + if not isinstance(value, str): + instance.logger_e.error("Wrong type for doc_type") + raise TypeError("Wrong type for doc_type") else: if value.capitalize() in self.white_lst: value = value.capitalize() return RenameOther.validate(self, instance, value) else: - instance.logger_e.error("Wrong doc_type") - raise ValueError + instance.logger_e.error("Wrong doc_type value") + raise ValueError("Wrong doc_type value") class DocIDValidator(RenameOther): @@ -109,15 +111,15 @@ class DocIDValidator(RenameOther): white_lst = [str(i) for i in range(0, 10)] def validate(self, instance, value): - if type(value) != str: - instance.logger_e.error("Wrong type") - raise TypeError + if not isinstance(value, str): + instance.logger_e.error("Wrong type for doc_id") + raise TypeError("Wrong type for doc_id") for symbol in value: if symbol not in self.white_lst: value = value.replace(symbol, '') if len(value) == self.doc_dict[getattr(instance, 'document_type')]: return RenameOther.validate(self, instance, value) else: - instance.logger_e.error("Wrong doc_id") - raise ValueError + instance.logger_e.error("Wrong doc_id value") + raise ValueError("Wrong doc_id value") diff --git a/homework/patient.py b/homework/patient.py index 497ffc3..bc6476d 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,7 +1,7 @@ import csv import logging import homework.model_cvd19 as model -from homework.logg_cvd19 import logger_s, logger_e +from homework.logg_cvd19 import logger_s, logger_e, handler_errors, handler_success FILENAME = 'covid_19_members.csv' @@ -14,28 +14,26 @@ class Patient(object): document_type = model.DocTypeValidator() document_id = model.DocIDValidator() - def __init__(self, *args): + def __init__(self, first_name, last_name, birth_date, phone, document_type, document_id): self.logger_s = logging.getLogger('covid_19_success') self.logger_e = logging.getLogger("covid_19_errors") - if args: - self.first_name = args[0] - self.last_name = args[1] - self.birth_date = args[2] - self.phone = args[3] - self.document_type = args[4] - self.document_id = args[5] + if first_name and last_name and birth_date and phone and document_type and document_id: + self.first_name = first_name + self.last_name = last_name + self.birth_date = birth_date + self.phone = phone + self.document_type = document_type + self.document_id = document_id self.logger_s.info('Был создан новый пациент') def __str__(self): return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ f'{self.document_id}' - @classmethod - def create(cls, *args): - super(Patient, cls).__init__(*args) - cls.created = Patient(*args) - return cls.created + @staticmethod + def create(first_name, last_name, birth_date, phone, document_type, document_id): + return Patient(first_name, last_name, birth_date, phone, document_type, document_id) def save(self): data = [self.first_name, self.last_name, self.birth_date, self.phone, self.document_type, self.document_id] @@ -43,19 +41,27 @@ def save(self): with open(FILENAME, "a", newline="", encoding='utf-8') as file: writer = csv.writer(file) writer.writerow(data) - except Exception: - self.logger_e.error('Something wrong') - raise Exception('Something wrong!') + except UnicodeError: + self.logger_e.error('Something wrong with your decoder in SAVE') + raise UnicodeError('Something wrong with your decoder in SAVE') + except IsADirectoryError: + self.logger_e.error('Cant write in directory. Problem in SAVE') + raise IsADirectoryError('Cant write in directory. Problem in SAVE') + except PermissionError: + self.logger_e.error('U cant write in this file. Problem in SAVE') + raise PermissionError('U cant write in this file. Problem in SAVE') + except OSError: + self.logger_e.error('Some System Error. Problem in SAVE') + raise OSError('Some System Error. Problem in SAVE') + except RuntimeError: + self.logger_e.error('Something unexpected. Problem in SAVE') + raise RuntimeError('Something unexpected. Problem in SAVE') else: self.logger_s.info('Сделана новая запись о пациенте в таблице') def __del__(self): - del self.logger_s - for fh in list(logging.getLogger("covid_19_success").handlers[::-1]): - fh.close() - del self.logger_e - for fh in list(logging.getLogger("covid_19_errors").handlers[::-1]): - fh.close() + handler_errors.close() + handler_success.close() class PatientCollection(object): @@ -68,11 +74,10 @@ def __iter__(self): return self def __next__(self): - inFile = open(self.path, 'r', encoding='utf-8') - inFile.seek(self.fileBytePos) - data = inFile.readline() - self.fileBytePos = inFile.tell() - inFile.close() + with open(self.path, 'r', encoding='utf-8') as inFile: + inFile.seek(self.fileBytePos) + data = inFile.readline() + self.fileBytePos = inFile.tell() if not data or not self.count: raise StopIteration self.count -= 1 From 59d32017655acf5db969ff3b185840802b5d67ff Mon Sep 17 00:00:00 2001 From: Dmitriy Razum Date: Fri, 1 May 2020 19:43:20 +0300 Subject: [PATCH 07/11] Methods are decorated --- homework/logg_cvd19.py | 42 +++++++++++++++++++++++++++++++++++++++++ homework/model_cvd19.py | 19 ++++++++----------- homework/patient.py | 31 ++++++++---------------------- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/homework/logg_cvd19.py b/homework/logg_cvd19.py index 8847935..240299d 100644 --- a/homework/logg_cvd19.py +++ b/homework/logg_cvd19.py @@ -13,3 +13,45 @@ handler_errors.setFormatter(formatter) logger_s.addHandler(handler_success) logger_e.addHandler(handler_errors) + + +def decorated_log(func): + def wrapper(*args, **kwargs): + if func.__name__ == '__init__': + key = 'init' + if func.__name__ == 'save': + key = 'save' + try: + result = func(*args, **kwargs) + if result: + return result + except AttributeError: + logger_e.error('F_name or L_name can not be changed') + raise AttributeError("F_name or L_name can not be changed") + except TypeError: + logger_e.error('Ошибка с типом данных') + raise TypeError("Ошибка с типом данных") + except UnicodeError: + logger_e.error('Something wrong with your decoder in SAVE') + raise UnicodeError('Something wrong with your decoder in SAVE') + except ValueError: + logger_e.error('Ошибка с типом данных') + raise ValueError("Ошибка с данными") + except IsADirectoryError: + logger_e.error('Cant write in directory. Problem in SAVE') + raise IsADirectoryError('Cant write in directory. Problem in SAVE') + except PermissionError: + logger_e.error('U cant write in this file. Problem in SAVE') + raise PermissionError('U cant write in this file. Problem in SAVE') + except OSError: + logger_e.error('Some System Error. Problem in SAVE') + raise OSError('Some System Error. Problem in SAVE') + except RuntimeError: + logger_e.error('Something unexpected. Problem in SAVE') + raise RuntimeError('Something unexpected. Problem in SAVE') + else: + if key == 'init': + logger_s.info('Пациент создан') + if key == 'save': + logger_s.info('Пациент сохранен') + return wrapper diff --git a/homework/model_cvd19.py b/homework/model_cvd19.py index a376fee..bcbf426 100644 --- a/homework/model_cvd19.py +++ b/homework/model_cvd19.py @@ -1,4 +1,5 @@ from abc import ABCMeta +from homework.logg_cvd19 import decorated_log # TODO Do not logg every time creation of patient @@ -27,26 +28,26 @@ def validate(cls, instance, value): class NameValidator(Validated): + @decorated_log def validate(self, instance, value): if not isinstance(value, str): - instance.logger_e.error("Wrong type for f_name or l_name") raise TypeError("Wrong type for f_name or l_name") if value.isalpha(): return value.capitalize() else: - instance.logger_e.error("Wrong value for f_name or s_name") raise ValueError("Wrong value for f_name or s_name") class NonBlank(NameValidator): + @decorated_log def validate(self, instance, value): if self.name in instance.__dict__ and getattr(instance, self.name): - instance.logger_e.error("Переназначение ФИО не предусмотрено") raise AttributeError("F_name or L_name can not be changed") return super(NonBlank, self).validate(instance, value) class RenameOther(Validated): + @decorated_log def validate(self, instance, value): if self.name in instance.__dict__ and getattr(instance, self.name): instance.logger_s.info(f"{self.name} было изменено") @@ -57,9 +58,9 @@ def validate(self, instance, value): class PhoneValidator(RenameOther): white_lst = [str(i) for i in range(0, 10)] + @decorated_log def validate(self, instance, value): if not isinstance(value, str): - instance.logger_e.error("Wrong type for Phone") raise TypeError("Wrong type for Phone") for symbol in value: if symbol not in self.white_lst: @@ -67,19 +68,17 @@ def validate(self, instance, value): if value.find('8') == 0: value = value.replace(value[0], '7', 1) if len(value) != 11: - instance.logger_e.error("Wrong attribute phone") raise ValueError("Wrong attribute phone") return RenameOther.validate(self, instance, value) class BirthValidator(RenameOther): + @decorated_log def validate(self, instance, value): if not isinstance(value, str): - instance.logger_e.error("Wrong type for birthday") raise TypeError("Wrong type for birthday") for symbol in value: if symbol.isalpha(): - instance.logger_e.error("Wrong value for birthday") raise ValueError("Wrong value for birthday") if str(symbol) == ' ' or symbol == '-': value = value.replace(symbol, '.') @@ -93,16 +92,15 @@ def validate(self, instance, value): class DocTypeValidator(RenameOther): white_lst = ['Паспорт', 'Заграничный паспорт', 'Водительские права'] + @decorated_log def validate(self, instance, value): if not isinstance(value, str): - instance.logger_e.error("Wrong type for doc_type") raise TypeError("Wrong type for doc_type") else: if value.capitalize() in self.white_lst: value = value.capitalize() return RenameOther.validate(self, instance, value) else: - instance.logger_e.error("Wrong doc_type value") raise ValueError("Wrong doc_type value") @@ -110,9 +108,9 @@ class DocIDValidator(RenameOther): doc_dict = {'Паспорт': 10, 'Водительские права': 10, 'Заграничный паспорт': 9} white_lst = [str(i) for i in range(0, 10)] + @decorated_log def validate(self, instance, value): if not isinstance(value, str): - instance.logger_e.error("Wrong type for doc_id") raise TypeError("Wrong type for doc_id") for symbol in value: if symbol not in self.white_lst: @@ -120,6 +118,5 @@ def validate(self, instance, value): if len(value) == self.doc_dict[getattr(instance, 'document_type')]: return RenameOther.validate(self, instance, value) else: - instance.logger_e.error("Wrong doc_id value") raise ValueError("Wrong doc_id value") diff --git a/homework/patient.py b/homework/patient.py index bc6476d..fc0bafc 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,7 +1,7 @@ import csv import logging import homework.model_cvd19 as model -from homework.logg_cvd19 import logger_s, logger_e, handler_errors, handler_success +from homework.logg_cvd19 import logger_s, logger_e, handler_errors, handler_success, decorated_log FILENAME = 'covid_19_members.csv' @@ -14,6 +14,7 @@ class Patient(object): document_type = model.DocTypeValidator() document_id = model.DocIDValidator() + @decorated_log def __init__(self, first_name, last_name, birth_date, phone, document_type, document_id): self.logger_s = logging.getLogger('covid_19_success') self.logger_e = logging.getLogger("covid_19_errors") @@ -25,7 +26,6 @@ def __init__(self, first_name, last_name, birth_date, phone, document_type, docu self.phone = phone self.document_type = document_type self.document_id = document_id - self.logger_s.info('Был создан новый пациент') def __str__(self): return f'{self.first_name} {self.last_name} {self.birth_date} {self.phone} {self.document_type} ' \ @@ -35,29 +35,12 @@ def __str__(self): def create(first_name, last_name, birth_date, phone, document_type, document_id): return Patient(first_name, last_name, birth_date, phone, document_type, document_id) + @decorated_log def save(self): data = [self.first_name, self.last_name, self.birth_date, self.phone, self.document_type, self.document_id] - try: - with open(FILENAME, "a", newline="", encoding='utf-8') as file: - writer = csv.writer(file) - writer.writerow(data) - except UnicodeError: - self.logger_e.error('Something wrong with your decoder in SAVE') - raise UnicodeError('Something wrong with your decoder in SAVE') - except IsADirectoryError: - self.logger_e.error('Cant write in directory. Problem in SAVE') - raise IsADirectoryError('Cant write in directory. Problem in SAVE') - except PermissionError: - self.logger_e.error('U cant write in this file. Problem in SAVE') - raise PermissionError('U cant write in this file. Problem in SAVE') - except OSError: - self.logger_e.error('Some System Error. Problem in SAVE') - raise OSError('Some System Error. Problem in SAVE') - except RuntimeError: - self.logger_e.error('Something unexpected. Problem in SAVE') - raise RuntimeError('Something unexpected. Problem in SAVE') - else: - self.logger_s.info('Сделана новая запись о пациенте в таблице') + with open(FILENAME, "a", newline="", encoding='utf-8') as file: + writer = csv.writer(file) + writer.writerow(data) def __del__(self): handler_errors.close() @@ -73,6 +56,7 @@ def __init__(self, path): def __iter__(self): return self + @decorated_log def __next__(self): with open(self.path, 'r', encoding='utf-8') as inFile: inFile.seek(self.fileBytePos) @@ -81,6 +65,7 @@ def __next__(self): if not data or not self.count: raise StopIteration self.count -= 1 + print(self.fileBytePos) return Patient(*data.split(',')) def limit(self, count): From af44712d32d1159faabf01d1faa241cc11e8ea62 Mon Sep 17 00:00:00 2001 From: Dmitriy Razum Date: Sat, 2 May 2020 13:12:58 +0300 Subject: [PATCH 08/11] Test database --- __init__.py | 0 homework/cli/__init__.py | 0 homework/cli/cli.py | 43 ++++++++++++++++++++++++++++++++++++++++ homework/patient.py | 33 +++++++++++++++++++----------- 4 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 __init__.py create mode 100644 homework/cli/__init__.py create mode 100644 homework/cli/cli.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/homework/cli/__init__.py b/homework/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/homework/cli/cli.py b/homework/cli/cli.py new file mode 100644 index 0000000..60ab24f --- /dev/null +++ b/homework/cli/cli.py @@ -0,0 +1,43 @@ +from homework.patient import Patient, PatientCollection +import click + + +@click.group() +def cli(): + pass + + +@click.command() +@click.argument('f_name') +@click.argument('s_name') +@click.option('--birth-date') +@click.option('--phone') +@click.option('--document-type') +@click.option('--document-number') +def create(f_name, s_name, birth_date, phone, document_type, document_number): + print(f_name, s_name, birth_date, phone, document_type, document_number) + patient = Patient(f_name, s_name, birth_date, phone, document_type, document_number) + patient.save() + del patient + + +@click.command() +def show(limit=10): + collection = PatientCollection('homework/covid_19_db.db') + for i in collection.limit(limit): + print(i) + + +@click.command() +def count(): + collection = PatientCollection('homework/covid_19_db.db') + for i in collection.limit(None): + print(i) + + +cli.add_command(create) +cli.add_command(show) +cli.add_command(count) + +if __name__ == '__main__': + cli() diff --git a/homework/patient.py b/homework/patient.py index fc0bafc..ce4642a 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -2,6 +2,7 @@ import logging import homework.model_cvd19 as model from homework.logg_cvd19 import logger_s, logger_e, handler_errors, handler_success, decorated_log +import sqlite3 FILENAME = 'covid_19_members.csv' @@ -37,10 +38,17 @@ def create(first_name, last_name, birth_date, phone, document_type, document_id) @decorated_log def save(self): + conn = sqlite3.connect('covid_19_db.db') + cursor = conn.cursor() + cursor.execute("""CREATE TABLE IF NOT EXISTS covid_members + (first_name char(30) not null, last_name char(30) not null, birth_date char(10) not null, + phone char(11) not null , document_type char(20) not null , document_id char(10) not null UNIQUE);""") + data = [self.first_name, self.last_name, self.birth_date, self.phone, self.document_type, self.document_id] - with open(FILENAME, "a", newline="", encoding='utf-8') as file: - writer = csv.writer(file) - writer.writerow(data) + cursor.execute('INSERT INTO covid_members VALUES(?, ?, ?, ?, ?, ?)', data) + conn.commit() + cursor.close() + conn.close() def __del__(self): handler_errors.close() @@ -51,22 +59,23 @@ class PatientCollection(object): def __init__(self, path): self.path = path self.fileBytePos = 0 - self.count = -1 + self.id = 1 + self.count = None + self.conn = sqlite3.connect(self.path) + self.cursor = self.conn.cursor() def __iter__(self): return self @decorated_log def __next__(self): - with open(self.path, 'r', encoding='utf-8') as inFile: - inFile.seek(self.fileBytePos) - data = inFile.readline() - self.fileBytePos = inFile.tell() - if not data or not self.count: + data = self.cursor.execute(f"SELECT * FROM covid_members WHERE id = {self.id}") + self.id += 1 + if not data or (self.count and self.id == self.count): + self.conn.close() + self.cursor.close() raise StopIteration - self.count -= 1 - print(self.fileBytePos) - return Patient(*data.split(',')) + return Patient(*data) def limit(self, count): self.count = count From 453b246c07274f9cf9d212565f05df675980944c Mon Sep 17 00:00:00 2001 From: Dmitriy Razum Date: Sat, 2 May 2020 23:02:14 +0300 Subject: [PATCH 09/11] Derorator. SQLite DB. Cli terminal --- __init__.py | 0 homework/cli.py | 105 +++++++++++++++++++++++++++++++++++++++ homework/cli/__init__.py | 0 homework/cli/cli.py | 43 ---------------- homework/config.py | 2 +- homework/logg_cvd19.py | 11 ++++ homework/model_cvd19.py | 2 +- homework/patient.py | 29 ++++++----- 8 files changed, 135 insertions(+), 57 deletions(-) delete mode 100644 __init__.py create mode 100644 homework/cli.py delete mode 100644 homework/cli/__init__.py delete mode 100644 homework/cli/cli.py diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/homework/cli.py b/homework/cli.py new file mode 100644 index 0000000..2ad8354 --- /dev/null +++ b/homework/cli.py @@ -0,0 +1,105 @@ +from patient import Patient, PatientCollection +import click +import sqlite3 + + +class OptionEatAll(click.Option): + + def __init__(self, *args, **kwargs): + self.save_other_options = kwargs.pop('save_other_options', True) + nargs = kwargs.pop('nargs', -1) + assert nargs == -1, 'nargs, if set, must be -1 not {}'.format(nargs) + super(OptionEatAll, self).__init__(*args, **kwargs) + self._previous_parser_process = None + self._eat_all_parser = None + + def add_to_parser(self, parser, ctx): + + def parser_process(value, state): + # method to hook to the parser.process + done = False + value = [value] + if self.save_other_options: + # grab everything up to the next option + while state.rargs and not done: + for prefix in self._eat_all_parser.prefixes: + if state.rargs[0].startswith(prefix): + done = True + if not done: + value.append(state.rargs.pop(0)) + else: + # grab everything remaining + value += state.rargs + state.rargs[:] = [] + value = tuple(value) + + # call the actual process + self._previous_parser_process(value, state) + + retval = super(OptionEatAll, self).add_to_parser(parser, ctx) + for name in self.opts: + our_parser = parser._long_opt.get(name) or parser._short_opt.get(name) + if our_parser: + self._eat_all_parser = our_parser + self._previous_parser_process = our_parser.process + our_parser.process = parser_process + break + return retval + + +@click.group() +def cli(): + pass + + +@click.command() +@click.argument('f_name') +@click.argument('s_name') +@click.option('--birth-date') +@click.option('--phone') +@click.option('--document-type') +@click.option('--document-number', cls=OptionEatAll, type=str) +def create(f_name, s_name, birth_date, phone, document_type, document_number): + document_id = '' + for current in document_number: + document_id += current + patient = Patient(f_name, s_name, birth_date, phone, document_type, document_id) + patient.save() + del patient + + +@click.command() +@click.argument('limit', default=10, type=int) +def show(limit): + collection = PatientCollection('covid_19_db.db') + for i in collection.limit(limit): + print(i) + + +@click.command() +def count(): + collection = PatientCollection('covid_19_db.db') + for i in collection.limit(None): + print(i) + + +cli.add_command(create) +cli.add_command(show) +cli.add_command(count) + +if __name__ == '__main__': + conn = sqlite3.connect('covid_19_db.db') + cursor = conn.cursor() + cursor.execute("""CREATE TABLE IF NOT EXISTS covid_members + (first_name TEXT not null, + last_name TEXT not null, + birth_date TEXT not null, + phone TEXT not null, + document_type TEXT not null, + document_id TEXT not null UNIQUE + );""") + + conn.commit() + cursor.close() + conn.close() + cli() diff --git a/homework/cli/__init__.py b/homework/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/homework/cli/cli.py b/homework/cli/cli.py deleted file mode 100644 index 60ab24f..0000000 --- a/homework/cli/cli.py +++ /dev/null @@ -1,43 +0,0 @@ -from homework.patient import Patient, PatientCollection -import click - - -@click.group() -def cli(): - pass - - -@click.command() -@click.argument('f_name') -@click.argument('s_name') -@click.option('--birth-date') -@click.option('--phone') -@click.option('--document-type') -@click.option('--document-number') -def create(f_name, s_name, birth_date, phone, document_type, document_number): - print(f_name, s_name, birth_date, phone, document_type, document_number) - patient = Patient(f_name, s_name, birth_date, phone, document_type, document_number) - patient.save() - del patient - - -@click.command() -def show(limit=10): - collection = PatientCollection('homework/covid_19_db.db') - for i in collection.limit(limit): - print(i) - - -@click.command() -def count(): - collection = PatientCollection('homework/covid_19_db.db') - for i in collection.limit(None): - print(i) - - -cli.add_command(create) -cli.add_command(show) -cli.add_command(count) - -if __name__ == '__main__': - cli() diff --git a/homework/config.py b/homework/config.py index f3f20c6..f841177 100644 --- a/homework/config.py +++ b/homework/config.py @@ -1,6 +1,6 @@ GOOD_LOG_FILE = "success.log" ERROR_LOG_FILE = "errors.log" -CSV_PATH = "covid_19_members.csv" +CSV_PATH = "covid_19_db.db" PHONE_FORMAT = "79160000000" # Здесь запишите телефон +7-916-000-00-00 в том формате, в котором вы храните телефоны PASSPORT_TYPE = "Паспорт" # тип документа, когда он паспорт diff --git a/homework/logg_cvd19.py b/homework/logg_cvd19.py index 240299d..1a87041 100644 --- a/homework/logg_cvd19.py +++ b/homework/logg_cvd19.py @@ -1,4 +1,5 @@ import logging +import sqlite3 logger_s = logging.getLogger("covid_19_success") logger_s.setLevel(logging.INFO) @@ -17,6 +18,7 @@ def decorated_log(func): def wrapper(*args, **kwargs): + key = None if func.__name__ == '__init__': key = 'init' if func.__name__ == 'save': @@ -37,6 +39,15 @@ def wrapper(*args, **kwargs): except ValueError: logger_e.error('Ошибка с типом данных') raise ValueError("Ошибка с данными") + except sqlite3.IntegrityError: + logger_e.error('Данные с таким документом уже существуют') + raise sqlite3.IntegrityError("Данные с таким документом уже существуют") + except sqlite3.OperationalError: + logger_e.error('Проблемы с подключением к базе') + raise sqlite3.OperationalError("Проблемы с подключением к базе") + except sqlite3.DatabaseError: + logger_e.error('Ошибка внутри базы') + raise sqlite3.DatabaseError("Ошибка внутри базы") except IsADirectoryError: logger_e.error('Cant write in directory. Problem in SAVE') raise IsADirectoryError('Cant write in directory. Problem in SAVE') diff --git a/homework/model_cvd19.py b/homework/model_cvd19.py index bcbf426..cd4d489 100644 --- a/homework/model_cvd19.py +++ b/homework/model_cvd19.py @@ -1,5 +1,5 @@ from abc import ABCMeta -from homework.logg_cvd19 import decorated_log +from logg_cvd19 import decorated_log # TODO Do not logg every time creation of patient diff --git a/homework/patient.py b/homework/patient.py index ce4642a..bf14fff 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,10 +1,10 @@ import csv import logging -import homework.model_cvd19 as model -from homework.logg_cvd19 import logger_s, logger_e, handler_errors, handler_success, decorated_log +import model_cvd19 as model +from logg_cvd19 import logger_s, logger_e, handler_errors, handler_success, decorated_log import sqlite3 -FILENAME = 'covid_19_members.csv' +FILENAME = 'covid_19_db.db' class Patient(object): @@ -40,12 +40,10 @@ def create(first_name, last_name, birth_date, phone, document_type, document_id) def save(self): conn = sqlite3.connect('covid_19_db.db') cursor = conn.cursor() - cursor.execute("""CREATE TABLE IF NOT EXISTS covid_members - (first_name char(30) not null, last_name char(30) not null, birth_date char(10) not null, - phone char(11) not null , document_type char(20) not null , document_id char(10) not null UNIQUE);""") data = [self.first_name, self.last_name, self.birth_date, self.phone, self.document_type, self.document_id] - cursor.execute('INSERT INTO covid_members VALUES(?, ?, ?, ?, ?, ?)', data) + cursor.execute("INSERT INTO covid_members VALUES (?, ?, ?, ?, ?, ?)", data) + conn.commit() cursor.close() conn.close() @@ -58,7 +56,6 @@ def __del__(self): class PatientCollection(object): def __init__(self, path): self.path = path - self.fileBytePos = 0 self.id = 1 self.count = None self.conn = sqlite3.connect(self.path) @@ -69,12 +66,20 @@ def __iter__(self): @decorated_log def __next__(self): - data = self.cursor.execute(f"SELECT * FROM covid_members WHERE id = {self.id}") - self.id += 1 - if not data or (self.count and self.id == self.count): - self.conn.close() + if self.count: + if self.id == self.count+1: + self.cursor.close() + self.conn.close() + raise StopIteration + read_line = self.cursor.execute(f"SELECT first_name, last_name, birth_date, phone, document_type, document_id" + f" FROM covid_members WHERE ROWID = {self.id}") + data = list(read_line) + data = list(*data) + if not data: self.cursor.close() + self.conn.close() raise StopIteration + self.id += 1 return Patient(*data) def limit(self, count): From 1a2fe44ad7144b80a5e6611e754c7bb97f0f7c1e Mon Sep 17 00:00:00 2001 From: Dmitriy Razum Date: Sun, 3 May 2020 17:43:34 +0300 Subject: [PATCH 10/11] Bug fix --- homework/cli.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/homework/cli.py b/homework/cli.py index 2ad8354..82561f7 100644 --- a/homework/cli.py +++ b/homework/cli.py @@ -55,15 +55,17 @@ def cli(): @click.command() @click.argument('f_name') @click.argument('s_name') -@click.option('--birth-date') -@click.option('--phone') -@click.option('--document-type') +@click.option('--birth-date', cls=OptionEatAll, type= str) +@click.option('--phone', cls=OptionEatAll, type=str) +@click.option('--document-type', cls=OptionEatAll, type=str) @click.option('--document-number', cls=OptionEatAll, type=str) def create(f_name, s_name, birth_date, phone, document_type, document_number): - document_id = '' - for current in document_number: - document_id += current - patient = Patient(f_name, s_name, birth_date, phone, document_type, document_id) + print(f_name, s_name, birth_date, phone, document_type, document_number) + birth_date = ''.join(birth_date) + phone = ''.join(phone) + document_type = ' '.join(document_type) + document_number = ''.join(document_number) + patient = Patient(f_name, s_name, birth_date, phone, document_type, document_number) patient.save() del patient From ffd9e3e3bd430438b9fc28bf0b6c1c0df74ed74d Mon Sep 17 00:00:00 2001 From: Dmitriy Razum Date: Sun, 3 May 2020 17:45:06 +0300 Subject: [PATCH 11/11] Bug fix_vers2 --- homework/cli.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homework/cli.py b/homework/cli.py index 82561f7..a480649 100644 --- a/homework/cli.py +++ b/homework/cli.py @@ -60,7 +60,6 @@ def cli(): @click.option('--document-type', cls=OptionEatAll, type=str) @click.option('--document-number', cls=OptionEatAll, type=str) def create(f_name, s_name, birth_date, phone, document_type, document_number): - print(f_name, s_name, birth_date, phone, document_type, document_number) birth_date = ''.join(birth_date) phone = ''.join(phone) document_type = ' '.join(document_type)