Advertisement
mikhailemv

Untitled

Nov 9th, 2022
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.14 KB | None | 0 0
  1. import csv
  2. import datetime
  3. import re
  4.  
  5. from prettytable import PrettyTable, ALL
  6.  
  7.  
  8. class Vacancy:
  9.     experience_translator = \
  10.         {
  11.             'noExperience': 'Нет опыта',
  12.             "between1And3": 'От 1 года до 3 лет',
  13.             'between3And6': 'От 3 до 6 лет',
  14.             'moreThan6': 'Более 6 лет',
  15.         }
  16.  
  17.     experience_values = \
  18.         {
  19.             'Нет опыта': 0,
  20.             'От 1 года до 3 лет': 1,
  21.             'От 3 до 6 лет': 2,
  22.             'Более 6 лет': 3
  23.         }
  24.  
  25.     def __init__(self, object_vacancy) -> None:
  26.         self.name = object_vacancy['name'][0]
  27.         self.description = object_vacancy['description'][0]
  28.         self.key_skills = object_vacancy['key_skills']
  29.         self.experience_id = self.experience_translator[object_vacancy['experience_id'][0]]
  30.         self.premium = 'Да' if object_vacancy['premium'][0].lower() == 'true' else 'Нет'
  31.         self.employer_name = object_vacancy['employer_name'][0]
  32.         self.salary = Salary(object_vacancy['salary_from'][0], object_vacancy['salary_to'][0],
  33.                              object_vacancy['salary_gross'][0], object_vacancy['salary_currency'][0])
  34.         self.area_name = object_vacancy['area_name'][0]
  35.         self.published_at = datetime.datetime.strptime(object_vacancy['published_at'][0], '%Y-%m-%dT%H:%M:%S%z')
  36.  
  37.     def get_experience_for_comparing(self) -> int:
  38.         return self.experience_values[self.experience_id]
  39.  
  40.  
  41. class Salary:
  42.     salary_currency = \
  43.         {
  44.             'AZN': 'Манаты',
  45.             'BYR': 'Белорусские рубли',
  46.             'EUR': 'Евро',
  47.             'GEL': 'Грузинский лари',
  48.             'KGS': 'Киргизский сом',
  49.             'KZT': 'Тенге',
  50.             'RUR': 'Рубли',
  51.             'UAH': "Гривны",
  52.             'USD': 'Доллары',
  53.             'UZS': 'Узбекский сум'
  54.         }
  55.  
  56.     currency_ratio = \
  57.         {
  58.             'Манаты': 35.68,
  59.             'Белорусские рубли': 23.91,
  60.             'Евро': 59.90,
  61.             'Грузинский лари': 21.74,
  62.             'Киргизский сом': 0.76,
  63.             'Тенге': 0.13,
  64.             'Рубли': 1,
  65.             'Гривны': 1.64,
  66.             'Доллары': 60.66,
  67.             'Узбекский сум': 0.0055
  68.         }
  69.  
  70.     def __init__(self,
  71.                  salary_from: str,
  72.                  salary_to: str,
  73.                  salary_gross: str,
  74.                  salary_currency: str) -> None:
  75.         self.salary_from = salary_from
  76.         self.salary_to = salary_to
  77.         self.salary_gross = salary_gross
  78.         self.salary_currency = self.salary_currency[salary_currency]
  79.  
  80.     def get_value_for_comparing(self) -> float:
  81.         min_salary = int((float((''.join(self.salary_from.split())))))
  82.         max_salary = int((float((''.join(self.salary_to.split())))))
  83.         return ((min_salary + max_salary) // 2) * self.currency_ratio[self.salary_currency]
  84.  
  85.     def get_salary_string_with_right_form(self) -> str:
  86.         tax = 'Без вычета' if self.salary_gross.lower() == 'true' else 'С вычетом'
  87.         salary_from = '{0:,}'.format(int(float(self.salary_from))).replace(',', ' ')
  88.         salary_to = '{0:,}'.format(int(float(self.salary_to))).replace(',', ' ')
  89.         return f'{salary_from} - {salary_to} ({self.salary_currency}) ({tax} налогов)'
  90.  
  91.  
  92. class DataSet:
  93.     def __init__(self,
  94.                  file_name: str,
  95.                  vacancies_objects: list) -> None:
  96.         self.file_name = file_name
  97.         self.vacancies_objects = vacancies_objects
  98.  
  99.     @staticmethod
  100.     def __clean_html_tags(raw_html: str) -> str:
  101.         clean_text = re.sub(re.compile('<.*?>'), '', raw_html)
  102.         return clean_text
  103.  
  104.     def __csv_reader(self) -> tuple:
  105.         headlines, vacancies = list(), list()
  106.         with open(self.file_name, encoding='utf-8-sig') as file:
  107.             vacancies_list, counter = csv.reader(file, delimiter=','), 0
  108.             for line in vacancies_list:
  109.                 if counter == 0:
  110.                     counter += 1
  111.                     headlines = line
  112.                 else:
  113.                     if '' in line or len(line) != len(headlines):
  114.                         continue
  115.                     vacancies.append(line)
  116.         if len(headlines) == 0:
  117.             print('Пустой файл')
  118.             exit()
  119.         if len(vacancies) == 0:
  120.             print('Нет данных')
  121.             exit()
  122.         return vacancies, headlines
  123.  
  124.     def __csv_filer(self, reader: tuple, headlines: list) -> list:
  125.         vacancies_list = list()
  126.         for line in reader:
  127.             current_dictionary = dict()
  128.             for i in range(len(line)):
  129.                 current_dictionary[headlines[i]] = line[i].split('\n')
  130.                 for j in range(len(current_dictionary[headlines[i]])):
  131.                     current_dictionary[headlines[i]][j] = \
  132.                         ' '.join(self.__clean_html_tags(current_dictionary[headlines[i]][j]).split())
  133.             vacancies_list.append(Vacancy(current_dictionary))
  134.         return vacancies_list
  135.  
  136.     def put_vacancies(self) -> None:
  137.         (vacancies, headlines) = self.__csv_reader()
  138.         self.vacancies_objects = self.__csv_filer(vacancies, headlines)
  139.  
  140.  
  141. class InputConnect:
  142.     headlines_translator = \
  143.         {
  144.             '№': '№',
  145.             'name': 'Название',
  146.             'description': 'Описание',
  147.             'key_skills': 'Навыки',
  148.             'experience_id': 'Опыт работы',
  149.             'premium': 'Премиум-вакансия',
  150.             'employer_name': 'Компания',
  151.             'salary': 'Оклад',
  152.             'area_name': 'Название региона',
  153.             'published_at': 'Дата публикации вакансии',
  154.             't': 'Идентификатор валюты оклада'
  155.         }
  156.  
  157.     def __init__(self) -> None:
  158.         self.file_name = input('Введите название файла: ')
  159.         self.filter_parameter = input('Введите параметр фильтрации: ')
  160.         self.sort_parameter = input('Введите параметр сортировки: ')
  161.         self.sort_descending = input('Обратный порядок сортировки (Да / Нет): ')
  162.         self.tableRange = input('Введите диапазон вывода: ')
  163.         self.inserted_columns = input('Введите требуемые столбцы: ')
  164.         self.table = PrettyTable()
  165.         self.table.field_names = list(self.headlines_translator.values())[0:10]
  166.  
  167.     def start_checking(self) -> None:
  168.         if self.filter_parameter != '':
  169.             if ': ' not in self.filter_parameter:
  170.                 print('Формат ввода некорректен')
  171.                 exit()
  172.             if self.filter_parameter.split(': ')[0] \
  173.                     not in self.headlines_translator.values():
  174.                 print('Параметр поиска некорректен')
  175.                 exit()
  176.         if self.sort_parameter != '' and self.sort_parameter \
  177.                 not in self.headlines_translator.values():
  178.             print('Параметр сортировки некорректен')
  179.             exit()
  180.         if self.sort_descending != '' and self.sort_descending != 'Нет' and self.sort_descending != 'Да':
  181.             print('Порядок сортировки задан некорректно')
  182.             exit()
  183.  
  184.     def get_filtered_vacancies(self, vacancies_list: list) -> list:
  185.         final_list = list()
  186.         for vacancy in vacancies_list:
  187.             is_correct_vacancy = False
  188.             if self.filter_parameter == '':
  189.                 is_correct_vacancy = True
  190.             else:
  191.                 field_name = self.filter_parameter.split(': ')[0]
  192.                 value = self.filter_parameter.split(': ')[1]
  193.                 if field_name == 'Название':
  194.                     if value != vacancy.name:
  195.                         continue
  196.                     is_correct_vacancy = True
  197.                 elif field_name == 'Оклад':
  198.                     value = int(value)
  199.                     salary_from = int(''.join(vacancy.salary.salary_from.split()))
  200.                     salary_to = int(''.join(vacancy.salary.salary_to.split()))
  201.                     if value < salary_from or value > salary_to:
  202.                         continue
  203.                     is_correct_vacancy = True
  204.                 elif field_name == 'Идентификатор валюты оклада':
  205.                     if vacancy.salary.salary_currency != value:
  206.                         continue
  207.                     is_correct_vacancy = True
  208.                 elif field_name == "Дата публикации вакансии":
  209.                     if value != (".".join(
  210.                             reversed(str(vacancy.published_at.date()).split('-')))):
  211.                         continue
  212.                     is_correct_vacancy = True
  213.                 else:
  214.                     flag_by_field = False
  215.                     values = value.strip().split(', ')
  216.                     for v in values:
  217.                         field_name_translated = list(self.headlines_translator.keys())[
  218.                             list(self.headlines_translator.values()).index(field_name)]
  219.                         if v not in getattr(vacancy, field_name_translated):
  220.                             flag_by_field = True
  221.                             break
  222.                     if not flag_by_field:
  223.                         is_correct_vacancy = True
  224.             if is_correct_vacancy:
  225.                 final_list.append(vacancy)
  226.         return final_list
  227.  
  228.     def get_sorted_vacancies(self, vacancies: list) -> list:
  229.         self.sort_descending = True if self.sort_descending == 'Да' else False
  230.         if self.sort_parameter == '':
  231.             return vacancies
  232.         if self.sort_parameter == 'Навыки':
  233.             return sorted(vacancies, key=lambda x: len(x.key_skills),
  234.                           reverse=self.sort_descending)
  235.         elif self.sort_parameter == 'Оклад':
  236.             return sorted(vacancies, key=lambda x: x.salary.get_value_for_comparing(),
  237.                           reverse=self.sort_descending)
  238.         elif self.sort_parameter == 'Дата публикации вакансии':
  239.             return sorted(vacancies, key=lambda x: x.published_at,
  240.                           reverse=self.sort_descending)
  241.         elif self.sort_parameter == 'Опыт работы':
  242.             return sorted(vacancies, key=lambda x: x.get_experience_for_comparing(),
  243.                           reverse=self.sort_descending)
  244.         else:
  245.             key = list(self.headlines_translator.keys())[
  246.                 list(self.headlines_translator.values()).index(self.sort_parameter)]
  247.             return sorted(vacancies, key=lambda x: getattr(x, key),
  248.                           reverse=self.sort_descending)
  249.  
  250.     def add_vacancies_to_table(self, vacancies: list) -> None:
  251.         counter = 1
  252.         for vacancy in vacancies:
  253.             current_vacancies_list = list()
  254.             for key in list(self.headlines_translator.keys())[1:10]:
  255.                 value = getattr(vacancy, key)
  256.                 adding = value
  257.                 if type(value) == datetime.datetime:
  258.                     adding = ('.'.join(reversed(str(value.date()).split('-'))))
  259.                 elif type(value) == list:
  260.                     adding = ('\n'.join(value))
  261.                 elif type(value) == Salary:
  262.                     adding = value.get_salary_string_with_right_form()
  263.                 if type(value) != Salary and len(adding) > 100:
  264.                     adding = adding[0:100] + '...'
  265.                 current_vacancies_list.append(adding)
  266.             self.table.add_row([counter] + current_vacancies_list)
  267.             counter += 1
  268.  
  269.     def print_table(self) -> None:
  270.         range_table = self.tableRange.split()
  271.         columns_list = [line for line in self.inserted_columns.split(', ') if line.strip() != '']
  272.         columns = ['№'] + columns_list
  273.  
  274.         start_index = int(range_table[0]) - 1 if len(range_table) >= 1 else 0
  275.         end_index = int(range_table[1]) - 1 if len(range_table) > 1 else len(self.table.rows)
  276.         columns = self.table.field_names if len(columns) == 1 else columns
  277.  
  278.         self.table.max_width = 20
  279.         self.table.hrules = ALL
  280.         self.table.align = 'l'
  281.  
  282.         if len(self.table.get_string().split('\n')) > 3:
  283.             print(self.table.get_string(
  284.                 start=start_index,
  285.                 end=end_index,
  286.                 fields=columns
  287.             ))
  288.         else:
  289.             print('Ничего не найдено')
  290.  
  291.  
  292. inserted_data = InputConnect()
  293. inserted_data.start_checking()
  294. current_dataset = DataSet(inserted_data.file_name, list())
  295. current_dataset.put_vacancies()
  296. inserted_data.add_vacancies_to_table(
  297.     inserted_data.get_sorted_vacancies(
  298.         inserted_data.get_filtered_vacancies(
  299.             current_dataset.vacancies_objects)))
  300. inserted_data.print_table()
  301.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement