From 4ec80cb1906c247032192b40a473c85103c4a555 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 00:12:28 +0300 Subject: [PATCH 01/14] added dz --- homework/patient.py | 225 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 214 insertions(+), 11 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index dad2526..c50d5e2 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,17 +1,220 @@ -class Patient: - def __init__(self, *args, **kwargs): - pass +import logging +import re +import csv +import homework.log_const - def create(*args, **kwargs): - raise NotImplementedError() +def check_date(data_type, data): + # first name + if data_type == 'fname': + if data is int: + raise TypeError('Incorrect first name type') + if (re.search(r'\d', data)) is None: + if re.match(r'\w+\b', data): + return data + else: + raise ValueError('Incorrect first name value') + else: + raise ValueError('Incorrect first name value') + # second name + if data_type == 'sname': + if data is int: + raise TypeError('Incorrect second name type') + if (re.search(r'\d', data)) is None: + if re.match(r'\w+\b', data): + return data + else: + raise ValueError('Incorrect second name value') + else: + raise ValueError('Incorrect second name value') + # birth date + if data_type == 'bdate': + data = re.split('-', data) + data = ''.join(data) + if re.search(r'\D', data) is None: + data = re.findall(r'\d+', data) + data = ''.join(data) + if len(data) == 8: + return data[0:4] + '-' + data[4:6] + '-' + data[6:] + else: + raise ValueError('Incorrect birth date value') + else: + raise ValueError('Incorrect birth date value') + # phone + if data_type == 'phone': + if re.search(r'[^\d()\-+ ]', data) is None: + data = re.findall(r'\d+', data) + data = ''.join(data) + if len(data) == 11: + return '8' + data[1:] + else: + raise ValueError('Incorrect phone value') + else: + raise ValueError('Incorrect phone value') - def save(self): - pass + # document type + if data_type == 'dtype': + if data is int: + raise TypeError('Incorrect document name type') + types = ('Паспорт', 'паспорт', 'Заграничный паспорт', + 'заграничный паспорт', 'загран', + 'Водительские права', 'водительсикие права') + if (re.search(r'\d', data)) is None: + if data in types: + return data + else: + raise ValueError('Incorrect doc id value') + else: + raise ValueError('Incorrect doc id value') + # document number + if data_type == 'docid': + if re.search(r'[^\d ]]', data) is None: + data = re.findall(r'\d+', data) + data = ''.join(data) + if len(data) == 10 or len(data) == 9: + return data + else: + raise ValueError('Incorrect doc num value') + else: + raise ValueError('Incorrect doc num value') + + +def Logger(func): + def wrapper(self, *args, **kwargs): + try: + func(self, *args, *kwargs) + except TypeError: + self.ex_log.error('Incorrect input type') + raise TypeError('Incorrect Type') + except ValueError: + self.ex_log.error('Incorrect input value') + raise ValueError('Incorrect value') + else: + self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, + self.last_name, func.__name__, args[0])) + return wrapper + + +class Patient(object): + def __init__(self, first_name, second_name, birth_date, phone, document_type, document_id): + self.ex_log = logging.getLogger('Exception_Logger') + self.log = logging.getLogger('Logger') + + try: + self.__first_name = check_date('fname', first_name) + self.__last_name = check_date('sname', second_name) + self.birth_date_ = check_date('bdate', birth_date) + self.phone_ = check_date('phone', phone) + self.document_type_ = check_date('dtype', document_type) + self.document_id_ = check_date('docid', document_id) + except TypeError as error_text: + self.ex_log.error('Incorrect input value') + raise TypeError(error_text) + except ValueError as error_text: + self.ex_log.error('Incorrect input value') + raise ValueError(error_text) + else: + self.log.info('New patient.py added: %s %s, %s, %s, %s %s' % + (first_name, second_name, birth_date, phone, document_type, document_id)) + + @classmethod + def create(cls, *args): + return cls(*args) + + def save(self, path='PatientsCollection.csv'): + try: + with open(path, 'a', newline='', encoding='utf-8') as csv_file: + writer = csv.writer(csv_file, delimiter=',') + patient = [self.__first_name, self.__last_name, self.birth_date_, + self.phone_, self.document_type_, self.document_id_] + writer.writerow(patient) + except Exception: + self.ex_log.error('Saving was unsuccessful') + raise Exception('Saving was unsuccessful') + else: + self.log.info('Patient %s %s was successfuly added to file' % (self.__first_name, self.__last_name)) + + @property + def first_name(self): + return self.__first_name + + @first_name.setter + def first_name(self, value): + self.ex_log.error('Unable to rewrite FIRST_NAME') + raise AttributeError("You can't change this field") + + @property + def last_name(self): + return self.__last_name + + @last_name.setter + def last_name(self, value): + self.ex_log.error('Unable to rewrite SECOND_NAME') + raise AttributeError("You can't change this field") + + @property + def birth_date(self): + return self.birth_date_ + + @birth_date.setter + @Logger + def birth_date(self, value): + self.birth_date_ = check_date('bdate', value) + + @property + def phone(self): + return self.phone_ + + @phone.setter + @Logger + def phone(self, value): + self.phone_ = check_date('phone', value) + + @property + def document_type(self): + return self.document_type_ + + @document_type.setter + @Logger + def document_type(self, value): + self.document_type_ = check_date('dtype', value) + + @property + def document_id(self): + return self.document_id_ + + @document_id.setter + @Logger + def document_id(self, value): + self.document_id_ = check_date('docid', value) + + def __del__(self): + del self.log, self.ex_log class PatientCollection: - def __init__(self, log_file): - pass + def __init__(self, path_to_file): + self.ex_log = logging.getLogger('Exception_Logger') + self.log = logging.getLogger('Logger') + + self.path_to_file = path_to_file + + def limit(self, value): + with open(self.path_to_file, 'rb', buffering=0) as file: + line = file.readline() + i = 0 + while i < value and line: + line = re.split(',', line.decode('utf-8')) + yield Patient(*line) + line = file.readline() + i += 1 + + def __iter__(self): + with open(self.path_to_file, 'rb', buffering=0) as file: + line = file.readline() + while line: + line = re.split(',', line.decode('utf-8')) + yield Patient(*line) + line = file.readline() - def limit(self, n): - raise NotImplementedError() + def __del__(self): + del self.log, self.ex_log From b2ff039bdaa4a2f22825be1a1f04ce55420c5ea2 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 00:15:51 +0300 Subject: [PATCH 02/14] logging constants --- homework/log_const.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 homework/log_const.py diff --git a/homework/log_const.py b/homework/log_const.py new file mode 100644 index 0000000..2478ba4 --- /dev/null +++ b/homework/log_const.py @@ -0,0 +1,17 @@ +import logging + +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + +ex_log = logging.getLogger('Exception_Logger') +log = logging.getLogger('Logger') +ex_log.setLevel(logging.WARNING) +log.setLevel(logging.INFO) + + +fh1 = logging.FileHandler('ex_log.log', encoding='utf-8') +fh2 = logging.FileHandler('log.log', encoding='utf-8') +fh1.setFormatter(formatter) +fh2.setFormatter(formatter) + +ex_log.addHandler(fh1) +log.addHandler(fh2) From 4a4846f6da60c8a9d1ebc2c11450855bad80b497 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 00:17:07 +0300 Subject: [PATCH 03/14] added fh closing --- tests/test_patient.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_patient.py b/tests/test_patient.py index 125bd59..2ae2d87 100644 --- a/tests/test_patient.py +++ b/tests/test_patient.py @@ -2,6 +2,8 @@ import os from datetime import datetime import itertools +import logging +from homework.log_const import fh1, fh2 import pytest @@ -39,6 +41,8 @@ def setup(): def teardown(): for file in [GOOD_LOG_FILE, ERROR_LOG_FILE, CSV_PATH]: + fh1.close() + fh2.close() os.remove(file) From 9714395a105375e2d54b992c65b506b11e4a184c Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 15:09:34 +0300 Subject: [PATCH 04/14] back to origin --- tests/test_patient.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_patient.py b/tests/test_patient.py index 2ae2d87..27c4d64 100644 --- a/tests/test_patient.py +++ b/tests/test_patient.py @@ -41,8 +41,6 @@ def setup(): def teardown(): for file in [GOOD_LOG_FILE, ERROR_LOG_FILE, CSV_PATH]: - fh1.close() - fh2.close() os.remove(file) From 60e45d64d8965063d4976485bc26db4d4664e747 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 15:11:16 +0300 Subject: [PATCH 05/14] updated destructor --- homework/patient.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/homework/patient.py b/homework/patient.py index c50d5e2..e5788ee 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -189,6 +189,10 @@ def document_id(self, value): def __del__(self): del self.log, self.ex_log + for fh in list(logging.getLogger('Exception_Logger').handlers)[::-1]: + fh.close() + for fh in list(logging.getLogger('Logger').handlers)[::-1]: + fh.close() class PatientCollection: @@ -218,3 +222,7 @@ def __iter__(self): def __del__(self): del self.log, self.ex_log + for fh in list(logging.getLogger('Exception_Logger').handlers)[::-1]: + fh.close() + for fh in list(logging.getLogger('Logger').handlers)[::-1]: + fh.close() From 074fb4ec1cf0846d6fcc3f08e813102ad5cff935 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 25 Apr 2020 23:29:49 +0300 Subject: [PATCH 06/14] logs fix(Ivan) --- tests/test_patient.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_patient.py b/tests/test_patient.py index 27c4d64..a442599 100644 --- a/tests/test_patient.py +++ b/tests/test_patient.py @@ -2,8 +2,6 @@ import os from datetime import datetime import itertools -import logging -from homework.log_const import fh1, fh2 import pytest @@ -33,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) @@ -182,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" From 5163dee72eb8f7d1b89a25812f06e51f92954f05 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sun, 26 Apr 2020 17:38:55 +0300 Subject: [PATCH 07/14] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit проверка значений перенесена в сеттеры создана маленькая функция для логирования и выкидывания исключений --- homework/patient.py | 210 ++++++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 123 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index e5788ee..69b0ffd 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -3,122 +3,52 @@ import csv import homework.log_const -def check_date(data_type, data): - # first name - if data_type == 'fname': - if data is int: - raise TypeError('Incorrect first name type') - if (re.search(r'\d', data)) is None: - if re.match(r'\w+\b', data): - return data - else: - raise ValueError('Incorrect first name value') - else: - raise ValueError('Incorrect first name value') - # second name - if data_type == 'sname': - if data is int: - raise TypeError('Incorrect second name type') - if (re.search(r'\d', data)) is None: - if re.match(r'\w+\b', data): - return data - else: - raise ValueError('Incorrect second name value') - else: - raise ValueError('Incorrect second name value') - # birth date - if data_type == 'bdate': - data = re.split('-', data) - data = ''.join(data) - if re.search(r'\D', data) is None: - data = re.findall(r'\d+', data) - data = ''.join(data) - if len(data) == 8: - return data[0:4] + '-' + data[4:6] + '-' + data[6:] - else: - raise ValueError('Incorrect birth date value') - else: - raise ValueError('Incorrect birth date value') - # phone - if data_type == 'phone': - if re.search(r'[^\d()\-+ ]', data) is None: - data = re.findall(r'\d+', data) - data = ''.join(data) - if len(data) == 11: - return '8' + data[1:] - else: - raise ValueError('Incorrect phone value') - else: - raise ValueError('Incorrect phone value') - - # document type - if data_type == 'dtype': - if data is int: - raise TypeError('Incorrect document name type') - types = ('Паспорт', 'паспорт', 'Заграничный паспорт', - 'заграничный паспорт', 'загран', - 'Водительские права', 'водительсикие права') - if (re.search(r'\d', data)) is None: - if data in types: - return data - else: - raise ValueError('Incorrect doc id value') - else: - raise ValueError('Incorrect doc id value') - # document number - if data_type == 'docid': - if re.search(r'[^\d ]]', data) is None: - data = re.findall(r'\d+', data) - data = ''.join(data) - if len(data) == 10 or len(data) == 9: - return data - else: - raise ValueError('Incorrect doc num value') - else: - raise ValueError('Incorrect doc num value') +def check_name(data): + if not isinstance(data, str): + raise TypeError("Incorrect name type: " + str(data)) + if re.match(r'\w+\b', data) and not re.search(r'\d', data): + return data + else: + raise ValueError('Incorrect name value: ' + str(data)) -def Logger(func): - def wrapper(self, *args, **kwargs): - try: - func(self, *args, *kwargs) - except TypeError: - self.ex_log.error('Incorrect input type') - raise TypeError('Incorrect Type') - except ValueError: - self.ex_log.error('Incorrect input value') - raise ValueError('Incorrect value') - else: - self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, - self.last_name, func.__name__, args[0])) - return wrapper + +def raise_error(ex_log, er_type, data, value): + text = "{0} didn't changed to {1} because of incorrect {2}".format(data, value, er_type) + if er_type == 'value': + ex_log.error(text) + raise ValueError(text) + elif er_type == 'type': + ex_log.error(text) + raise TypeError(text) class Patient(object): def __init__(self, first_name, second_name, birth_date, phone, document_type, document_id): self.ex_log = logging.getLogger('Exception_Logger') self.log = logging.getLogger('Logger') - try: - self.__first_name = check_date('fname', first_name) - self.__last_name = check_date('sname', second_name) - self.birth_date_ = check_date('bdate', birth_date) - self.phone_ = check_date('phone', phone) - self.document_type_ = check_date('dtype', document_type) - self.document_id_ = check_date('docid', document_id) + logging.getLogger('Logger').disabled = True # костыыыыыль + self.first_name_ = check_name(first_name) + self.last_name_ = check_name(second_name) + self.birth_date = birth_date + self.phone = phone + self.document_type = document_type + self.document_id = document_id + logging.getLogger('Logger').disabled = False except TypeError as error_text: - self.ex_log.error('Incorrect input value') + self.ex_log.error(error_text) raise TypeError(error_text) except ValueError as error_text: - self.ex_log.error('Incorrect input value') + self.ex_log.error(error_text) raise ValueError(error_text) else: self.log.info('New patient.py added: %s %s, %s, %s, %s %s' % (first_name, second_name, birth_date, phone, document_type, document_id)) - @classmethod - def create(cls, *args): - return cls(*args) + @staticmethod + def create(*args): + return Patient(*args) def save(self, path='PatientsCollection.csv'): try: @@ -127,15 +57,18 @@ def save(self, path='PatientsCollection.csv'): patient = [self.__first_name, self.__last_name, self.birth_date_, self.phone_, self.document_type_, self.document_id_] writer.writerow(patient) - except Exception: - self.ex_log.error('Saving was unsuccessful') - raise Exception('Saving was unsuccessful') + except IsADirectoryError: + self.ex_log.error('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) + raise IsADirectoryError('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) + except PermissionError: + self.ex_log.error('%s %s:Saving was unsuccessful: PermissionError ' % (self.first_name, self.last_name)) + raise PermissionError('%s %s:Saving was unsuccessful: PermissionError' % (self.first_name, self.last_name)) else: - self.log.info('Patient %s %s was successfuly added to file' % (self.__first_name, self.__last_name)) + self.log.info('Patient %s %s was successfully added to file' % (self.__first_name, self.__last_name)) @property def first_name(self): - return self.__first_name + return self.first_name_ @first_name.setter def first_name(self, value): @@ -144,7 +77,7 @@ def first_name(self, value): @property def last_name(self): - return self.__last_name + return self.last_name_ @last_name.setter def last_name(self, value): @@ -156,43 +89,76 @@ def birth_date(self): return self.birth_date_ @birth_date.setter - @Logger def birth_date(self, value): - self.birth_date_ = check_date('bdate', value) + if not isinstance(value, str): + raise_error(self.ex_log, 'type', 'birth_date', value) + if re.match(r'\d{4}-\d{2}-\d{2}\b', value): + self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, + self.last_name, 'birth_date', value)) + self.birth_date_ = value + else: + raise_error(self.ex_log, 'value', 'birth_date', value) @property def phone(self): return self.phone_ @phone.setter - @Logger def phone(self, value): - self.phone_ = check_date('phone', value) + if not isinstance(value, str): + raise_error(self.ex_log, 'type', 'phone', value) + if re.search(r'[^\d()\-+ ]', value) is None: + data = re.findall(r'\d+', value) + data = ''.join(data) + if len(data) == 11: + self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, + self.last_name, 'phone', value)) + self.phone_ = '8' + data[1:] + else: + raise_error(self.ex_log, 'value', 'phone', value) + else: + raise_error(self.ex_log, 'value', 'phone', value) @property def document_type(self): return self.document_type_ @document_type.setter - @Logger def document_type(self, value): - self.document_type_ = check_date('dtype', value) + if not isinstance(value, str): + raise_error(self.ex_log, 'type', 'document_type', value) + types = ('паспорт', 'заграничный паспорт', 'водительские права') + if value in types: + self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, + self.last_name, 'document_type', value)) + self.document_type_ = value + else: + raise_error(self.ex_log, 'value', 'document_type', value) @property def document_id(self): return self.document_id_ @document_id.setter - @Logger def document_id(self, value): - self.document_id_ = check_date('docid', value) + if not isinstance(value, str): + raise_error(self.ex_log, 'type', 'document_id', value) + if re.search(r'[^\d ]]', value) is None: + value = re.findall(r'\d+', value) + value = ''.join(value) + if (len(value) == 10 and self.document_type_ != 'заграничный паспорт') or\ + (len(value) == 9 and self.document_type_ == 'заграничный паспорт'): + self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, + self.last_name, 'document_id', value)) + self.document_id_ = value + else: + raise_error(self.ex_log, 'value', 'document_id', value) + else: + raise_error(self.ex_log, 'value', 'document_id', value) def __del__(self): - del self.log, self.ex_log - for fh in list(logging.getLogger('Exception_Logger').handlers)[::-1]: - fh.close() - for fh in list(logging.getLogger('Logger').handlers)[::-1]: - fh.close() + homework.log_const.fh1.close() + homework.log_const.fh2.close() class PatientCollection: @@ -221,8 +187,6 @@ def __iter__(self): line = file.readline() def __del__(self): - del self.log, self.ex_log - for fh in list(logging.getLogger('Exception_Logger').handlers)[::-1]: - fh.close() - for fh in list(logging.getLogger('Logger').handlers)[::-1]: - fh.close() + homework.log_const.fh1.close() + homework.log_const.fh2.close() + From 31d5baa9477b29df868621ab58d8d3d58fb2f194 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sun, 26 Apr 2020 17:44:32 +0300 Subject: [PATCH 08/14] idk why --- homework/config.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/homework/config.py b/homework/config.py index 955b991..e4cfc1a 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" -PHONE_FORMAT = "79160000000" # Здесь запишите телефон +7-916-000-00-00 в том формате, в котором вы храните телефоны +GOOD_LOG_FILE = "log.log" +ERROR_LOG_FILE = "ex_log.log" +CSV_PATH = "PatientsCollection.csv" +PHONE_FORMAT = "89160000000" # Здесь запишите телефон +7-916-000-00-00 в том формате, в котором вы храните телефоны PASSPORT_TYPE = "паспорт" # тип документа, когда он паспорт -PASSPORT_FORMAT = "0000 000000" # Здесь запишите номер парспорта 0000 000000 в том формате, в котором вы его храните +PASSPORT_FORMAT = "0000000000" # Здесь запишите номер парспорта 0000 000000 в том формате, в котором вы его храните INTERNATIONAL_PASSPORT_TYPE = "заграничный паспорт" # тип документа, если это загран -INTERNATIONAL_PASSPORT_FORMAT = "00 0000000" # формат хранения заграна для номера 00 0000000 +INTERNATIONAL_PASSPORT_FORMAT = "000000000" # формат хранения заграна для номера 00 0000000 -DRIVER_LICENSE_TYPE = "водительское удостоверение" # тип документа, если это водительское удостоверение -DRIVER_LICENSE_FORMAT = "00 00 000000" # формат хранения номера ВУ +DRIVER_LICENSE_TYPE = "водительские права" # тип документа, если это водительское удостоверение +DRIVER_LICENSE_FORMAT = "0000000000" # формат хранения номера ВУ From 75f5b256cd9e4745e945e5c1b2efc9333dacfaab Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sun, 26 Apr 2020 17:47:12 +0300 Subject: [PATCH 09/14] - private --- homework/patient.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index 69b0ffd..cb5038c 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -54,7 +54,7 @@ def save(self, path='PatientsCollection.csv'): try: with open(path, 'a', newline='', encoding='utf-8') as csv_file: writer = csv.writer(csv_file, delimiter=',') - patient = [self.__first_name, self.__last_name, self.birth_date_, + patient = [self.first_name, self.last_name, self.birth_date_, self.phone_, self.document_type_, self.document_id_] writer.writerow(patient) except IsADirectoryError: @@ -64,7 +64,7 @@ def save(self, path='PatientsCollection.csv'): self.ex_log.error('%s %s:Saving was unsuccessful: PermissionError ' % (self.first_name, self.last_name)) raise PermissionError('%s %s:Saving was unsuccessful: PermissionError' % (self.first_name, self.last_name)) else: - self.log.info('Patient %s %s was successfully added to file' % (self.__first_name, self.__last_name)) + self.log.info('Patient %s %s was successfully added to file' % (self.first_name, self.last_name)) @property def first_name(self): From 4dce982a0accec26e6061d329865bb5fa6159805 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Wed, 29 Apr 2020 19:26:47 +0300 Subject: [PATCH 10/14] __- -___ -_-___- -_____ ________________----_______-_--- --- homework/patient.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index cb5038c..d9ed46e 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -29,8 +29,8 @@ def __init__(self, first_name, second_name, birth_date, phone, document_type, do self.log = logging.getLogger('Logger') try: logging.getLogger('Logger').disabled = True # костыыыыыль - self.first_name_ = check_name(first_name) - self.last_name_ = check_name(second_name) + self._first_name_ = check_name(first_name) + self._last_name_ = check_name(second_name) self.birth_date = birth_date self.phone = phone self.document_type = document_type @@ -54,8 +54,8 @@ def save(self, path='PatientsCollection.csv'): try: with open(path, 'a', newline='', encoding='utf-8') as csv_file: writer = csv.writer(csv_file, delimiter=',') - patient = [self.first_name, self.last_name, self.birth_date_, - self.phone_, self.document_type_, self.document_id_] + patient = [self.first_name, self.last_name, self.birth_date, + self.phone, self.document_type, self.document_id] writer.writerow(patient) except IsADirectoryError: self.ex_log.error('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) @@ -68,7 +68,7 @@ def save(self, path='PatientsCollection.csv'): @property def first_name(self): - return self.first_name_ + return self._first_name_ @first_name.setter def first_name(self, value): @@ -77,7 +77,7 @@ def first_name(self, value): @property def last_name(self): - return self.last_name_ + return self._last_name_ @last_name.setter def last_name(self, value): From 3de12af9ac3731cf0e4132fe05da3c54f9aa46a6 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Fri, 8 May 2020 16:03:35 +0300 Subject: [PATCH 11/14] 1 step to DZ3: logging_decarator --- homework/patient.py | 111 +++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index d9ed46e..febb98d 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -13,148 +13,164 @@ def check_name(data): raise ValueError('Incorrect name value: ' + str(data)) -def raise_error(ex_log, er_type, data, value): - text = "{0} didn't changed to {1} because of incorrect {2}".format(data, value, er_type) - if er_type == 'value': - ex_log.error(text) - raise ValueError(text) - elif er_type == 'type': - ex_log.error(text) - raise TypeError(text) +def logging_decorator(func): + def wrapper(self, *args, **kwargs): + try: + result = func(self, *args, **kwargs) + except TypeError as er_text: + # er_text = 'Patient{0} {1}: incorrect type for function {2}'\ + # .format(self.first_name, self.last_name, func.__name__) + logging.getLogger('Exception_Logger').error(er_text) + raise TypeError(er_text) + except ValueError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise ValueError(er_text) + except IsADirectoryError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise IsADirectoryError(er_text) + except PermissionError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise PermissionError(er_text) + except AttributeError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise AttributeError(er_text) + finally: + pass + logging.getLogger('Logger').info('Function {0} was successfully done for patient {1} {2}' + .format(func.__name__, self.first_name, self.last_name)) + return result + return wrapper class Patient(object): + @logging_decorator def __init__(self, first_name, second_name, birth_date, phone, document_type, document_id): - self.ex_log = logging.getLogger('Exception_Logger') - self.log = logging.getLogger('Logger') try: logging.getLogger('Logger').disabled = True # костыыыыыль - self._first_name_ = check_name(first_name) - self._last_name_ = check_name(second_name) + self.first_name_ = check_name(first_name) + self.last_name_ = check_name(second_name) self.birth_date = birth_date self.phone = phone self.document_type = document_type self.document_id = document_id logging.getLogger('Logger').disabled = False except TypeError as error_text: - self.ex_log.error(error_text) raise TypeError(error_text) except ValueError as error_text: - self.ex_log.error(error_text) raise ValueError(error_text) - else: - self.log.info('New patient.py added: %s %s, %s, %s, %s %s' % - (first_name, second_name, birth_date, phone, document_type, document_id)) @staticmethod def create(*args): return Patient(*args) + @logging_decorator def save(self, path='PatientsCollection.csv'): try: with open(path, 'a', newline='', encoding='utf-8') as csv_file: writer = csv.writer(csv_file, delimiter=',') - patient = [self.first_name, self.last_name, self.birth_date, - self.phone, self.document_type, self.document_id] + patient = [self.first_name, self.last_name, self.birth_date_, + self.phone_, self.document_type_, self.document_id_] writer.writerow(patient) except IsADirectoryError: - self.ex_log.error('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) raise IsADirectoryError('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) except PermissionError: - self.ex_log.error('%s %s:Saving was unsuccessful: PermissionError ' % (self.first_name, self.last_name)) raise PermissionError('%s %s:Saving was unsuccessful: PermissionError' % (self.first_name, self.last_name)) - else: - self.log.info('Patient %s %s was successfully added to file' % (self.first_name, self.last_name)) @property def first_name(self): - return self._first_name_ + return self.first_name_ @first_name.setter + @logging_decorator def first_name(self, value): - self.ex_log.error('Unable to rewrite FIRST_NAME') - raise AttributeError("You can't change this field") + raise AttributeError("%s %s: You can't change this field" % (self.first_name, self.last_name)) @property def last_name(self): - return self._last_name_ + return self.last_name_ @last_name.setter + @logging_decorator def last_name(self, value): - self.ex_log.error('Unable to rewrite SECOND_NAME') - raise AttributeError("You can't change this field") + raise AttributeError("%s %s: You can't change this field" % (self.first_name, self.last_name)) @property def birth_date(self): return self.birth_date_ @birth_date.setter + @logging_decorator def birth_date(self, value): if not isinstance(value, str): - raise_error(self.ex_log, 'type', 'birth_date', value) + raise TypeError("%s %s: unable to change birth date because of incorrect TYPE" + % (self.first_name, self.last_name)) if re.match(r'\d{4}-\d{2}-\d{2}\b', value): - self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, - self.last_name, 'birth_date', value)) self.birth_date_ = value else: - raise_error(self.ex_log, 'value', 'birth_date', value) + raise ValueError("%s %s: unable to change birth date because of incorrect VALUE" + % (self.first_name, self.last_name)) @property def phone(self): return self.phone_ @phone.setter + @logging_decorator def phone(self, value): if not isinstance(value, str): - raise_error(self.ex_log, 'type', 'phone', value) + raise TypeError("%s %s: unable to change phone because of incorrect TYPE" + % (self.first_name, self.last_name)) if re.search(r'[^\d()\-+ ]', value) is None: data = re.findall(r'\d+', value) data = ''.join(data) if len(data) == 11: - self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, - self.last_name, 'phone', value)) self.phone_ = '8' + data[1:] else: - raise_error(self.ex_log, 'value', 'phone', value) + raise ValueError("%s %s: unable to change phone because of incorrect VALUE" + % (self.first_name, self.last_name)) else: - raise_error(self.ex_log, 'value', 'phone', value) + raise ValueError("%s %s: unable to change phone because of incorrect VALUE" + % (self.first_name, self.last_name)) @property def document_type(self): return self.document_type_ @document_type.setter + @logging_decorator def document_type(self, value): if not isinstance(value, str): - raise_error(self.ex_log, 'type', 'document_type', value) + raise TypeError("%s %s: unable to change doc. type because of incorrect TYPE" + % (self.first_name, self.last_name)) types = ('паспорт', 'заграничный паспорт', 'водительские права') if value in types: - self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, - self.last_name, 'document_type', value)) self.document_type_ = value else: - raise_error(self.ex_log, 'value', 'document_type', value) + raise ValueError("%s %s: unable to change doc. type because of incorrect VALUE" + % (self.first_name, self.last_name)) @property def document_id(self): return self.document_id_ @document_id.setter + @logging_decorator def document_id(self, value): if not isinstance(value, str): - raise_error(self.ex_log, 'type', 'document_id', value) + raise TypeError("%s %s: unable to change doc. id because of incorrect TYPE" + % (self.first_name, self.last_name)) if re.search(r'[^\d ]]', value) is None: value = re.findall(r'\d+', value) value = ''.join(value) if (len(value) == 10 and self.document_type_ != 'заграничный паспорт') or\ (len(value) == 9 and self.document_type_ == 'заграничный паспорт'): - self.log.info('{0} {1}: {2} was successfully set to {3}'.format(self.first_name, - self.last_name, 'document_id', value)) self.document_id_ = value else: - raise_error(self.ex_log, 'value', 'document_id', value) + raise ValueError("%s %s: unable to change doc. id because of incorrect VALUE" + % (self.first_name, self.last_name)) else: - raise_error(self.ex_log, 'value', 'document_id', value) + raise ValueError("%s %s: unable to change doc. id because of incorrect VALUE" + % (self.first_name, self.last_name)) def __del__(self): homework.log_const.fh1.close() @@ -190,3 +206,4 @@ def __del__(self): homework.log_const.fh1.close() homework.log_const.fh2.close() + From a1b567c095cb24091068ba671d1aaa4ccfc379da Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Fri, 8 May 2020 21:23:11 +0300 Subject: [PATCH 12/14] STEP 2: working with SQLite3 CSV -> BD --- homework/patient.py | 81 +++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index febb98d..480bc4c 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -2,6 +2,7 @@ import re import csv import homework.log_const +import sqlite3 def check_name(data): @@ -34,10 +35,22 @@ def wrapper(self, *args, **kwargs): except AttributeError as er_text: logging.getLogger('Exception_Logger').error(er_text) raise AttributeError(er_text) - finally: - pass - logging.getLogger('Logger').info('Function {0} was successfully done for patient {1} {2}' - .format(func.__name__, self.first_name, self.last_name)) + except EOFError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise EOFError(er_text) + except sqlite3.ProgrammingError as er_text: + logging.getLogger('Exception_Logger').error(er_text) + raise sqlite3.ProgrammingError(er_text) + except Exception: + er_text = 'Unexpected exception! :(' + logging.getLogger('Exception_Logger').error(er_text) + raise Exception(er_text) + if self.__class__.__name__ == 'Patient': + logging.getLogger('Logger').info('Function {0} was successfully done for patient {1} {2}' + .format(func.__name__, self.first_name, self.last_name)) + else: + logging.getLogger('Logger').info('Function {0} was successfully done for PatientCollection class' + .format(func.__name__)) return result return wrapper @@ -64,17 +77,25 @@ def create(*args): return Patient(*args) @logging_decorator - def save(self, path='PatientsCollection.csv'): + def save(self, path='PatientsCollection.db'): try: - with open(path, 'a', newline='', encoding='utf-8') as csv_file: - writer = csv.writer(csv_file, delimiter=',') - patient = [self.first_name, self.last_name, self.birth_date_, - self.phone_, self.document_type_, self.document_id_] - writer.writerow(patient) + table = sqlite3.connect(path) + with table: + cursor = table.cursor() + cursor.executescript("""CREATE TABLE IF NOT EXISTS PatientsCollection + (first_name text, second_name text, birth_date text, + phone text, doc_type text, doc_id text); + """) + patient = (self.first_name, self.last_name, self.birth_date_, + self.phone_, self.document_type_, self.document_id_) + cursor.executemany("INSERT INTO PatientsCollection VALUES (?,?,?,?,?,?)", (patient,)) except IsADirectoryError: raise IsADirectoryError('%s %s:Saving was unsuccessful: incorrect path' % (self.first_name, self.last_name)) except PermissionError: raise PermissionError('%s %s:Saving was unsuccessful: PermissionError' % (self.first_name, self.last_name)) + except sqlite3.ProgrammingError: + raise sqlite3.ProgrammingError('%s %s:Saving was unsuccessful: PermissionError' + % (self.first_name, self.last_name)) @property def first_name(self): @@ -179,31 +200,33 @@ def __del__(self): class PatientCollection: def __init__(self, path_to_file): - self.ex_log = logging.getLogger('Exception_Logger') - self.log = logging.getLogger('Logger') - self.path_to_file = path_to_file + @logging_decorator def limit(self, value): - with open(self.path_to_file, 'rb', buffering=0) as file: - line = file.readline() - i = 0 - while i < value and line: - line = re.split(',', line.decode('utf-8')) - yield Patient(*line) - line = file.readline() - i += 1 + table = sqlite3.connect(self.path_to_file) + with table: + cursor = table.cursor() + cursor.execute("SELECT * FROM PatientsCollection") + i = value + while i > 0: + element = cursor.fetchone() + if not element: + raise EOFError('You reached end of file: {0}'.format(self.path_to_file)) + yield element + i -= 1 + @logging_decorator def __iter__(self): - with open(self.path_to_file, 'rb', buffering=0) as file: - line = file.readline() - while line: - line = re.split(',', line.decode('utf-8')) - yield Patient(*line) - line = file.readline() + table = sqlite3.connect(self.path_to_file) + with table: + cursor = table.cursor() + cursor.execute("SELECT * FROM PatientsCollection") + element = cursor.fetchone() + while element: + yield element + element = cursor.fetchone() def __del__(self): homework.log_const.fh1.close() homework.log_const.fh2.close() - - From 228aca5a506eadff5c3ff36fe3ec1b75a92382a8 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 9 May 2020 02:10:18 +0300 Subject: [PATCH 13/14] small changes --- homework/patient.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/homework/patient.py b/homework/patient.py index 480bc4c..a20c94a 100644 --- a/homework/patient.py +++ b/homework/patient.py @@ -1,7 +1,6 @@ import logging import re -import csv -import homework.log_const +import log_const import sqlite3 @@ -79,6 +78,13 @@ def create(*args): @logging_decorator def save(self, path='PatientsCollection.db'): try: + ''' + with open(path, 'a', newline='', encoding='utf-8') as csv_file: + writer = csv.writer(csv_file, delimiter=',') + patient = [self.first_name, self.last_name, self.birth_date_, + self.phone_, self.document_type_, self.document_id_] + writer.writerow(patient) + ''' table = sqlite3.connect(path) with table: cursor = table.cursor() @@ -194,12 +200,12 @@ def document_id(self, value): % (self.first_name, self.last_name)) def __del__(self): - homework.log_const.fh1.close() - homework.log_const.fh2.close() + log_const.fh1.close() + log_const.fh2.close() class PatientCollection: - def __init__(self, path_to_file): + def __init__(self, path_to_file='PatientsCollection.db'): self.path_to_file = path_to_file @logging_decorator @@ -228,5 +234,6 @@ def __iter__(self): element = cursor.fetchone() def __del__(self): - homework.log_const.fh1.close() - homework.log_const.fh2.close() + log_const.fh1.close() + log_const.fh2.close() + From 6763153fc6e7f9f79153b2bedbab938bb5c50870 Mon Sep 17 00:00:00 2001 From: obscene3190 <32190896+obscene3190@users.noreply.github.com> Date: Sat, 9 May 2020 02:12:27 +0300 Subject: [PATCH 14/14] STEP3: CLI --- homework/cli.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 homework/cli.py diff --git a/homework/cli.py b/homework/cli.py new file mode 100644 index 0000000..08e2e37 --- /dev/null +++ b/homework/cli.py @@ -0,0 +1,45 @@ +import click +import sqlite3 +from patient import Patient, PatientCollection + + +@click.group() +def cli(): + pass + + +@click.command() +@click.argument('first_name') +@click.argument('last_name') +@click.option('--birth-date', 'birth_date', required=True) +@click.option('--phone', 'phone', required=True) +@click.option('--document-type', 'doc_type', required=True) +@click.option('--document-id', 'doc_id', required=True) +def create(first_name, last_name, birth_date, phone, doc_type, doc_id): + patient = Patient(first_name, last_name, birth_date, phone, doc_type, doc_id) + patient.save() + + +@click.command() +@click.argument('value', default=10) +def show(value): + collection1 = PatientCollection() + for patient in collection1.limit(value): + print(patient) + + +@click.command() +def count(): + table = sqlite3.connect('PatientsCollection.db') + with table: + cursor = table.cursor() + cursor.execute("SELECT COUNT(*) FROM PatientsCollection") + print(cursor.fetchone()[0]) + + +cli.add_command(create) +cli.add_command(show) +cli.add_command(count) + +if __name__ == '__main__': + cli()