From daea6ec14e509133d1a5eb9d7632cf2ebf993dc2 Mon Sep 17 00:00:00 2001 From: GelioGabal Date: Tue, 16 Jun 2026 08:10:35 +0300 Subject: [PATCH] refactor: remove duplication, replace magic indices, add helper methods --- python/funding_raised.py | 188 ++++++++++++--------------------------- 1 file changed, 56 insertions(+), 132 deletions(-) diff --git a/python/funding_raised.py b/python/funding_raised.py index 4a00ef5..4e72361 100755 --- a/python/funding_raised.py +++ b/python/funding_raised.py @@ -1,137 +1,61 @@ import csv +import os -class FundingRaised: - @staticmethod - def where(options = {}): - with open("../startup_funding.csv", "rt") as csvfile: - data = csv.reader(csvfile, delimiter=',', quotechar='"') - # skip header - next(data) - csv_data = [] - for row in data: - csv_data.append(row) - - funding = [] - if 'company_name' in options: - result = [] - for row in csv_data: - if row[1] == options['company_name']: - result.append(row) - csv_data = result - - if 'city' in options: - result = [] - for row in csv_data: - if row[4] == options['city']: - result.append(row) - csv_data = result - - if 'state' in options: - result = [] - for row in csv_data: - if row[5] == options['state']: - result.append(row) - csv_data = result - - if 'round' in options: - result = [] - for row in csv_data: - if row[9] == options['round']: - result.append(row) - csv_data = result - - output = [] - for row in csv_data: - mapped = {} - mapped['permalink'] = row[0] - mapped['company_name'] = row[1] - mapped['number_employees'] = row[2] - mapped['category'] = row[3] - mapped['city'] = row[4] - mapped['state'] = row[5] - mapped['funded_date'] = row[6] - mapped['raised_amount'] = row[7] - mapped['raised_currency'] = row[8] - mapped['round'] = row[9] - output.append(mapped) - - return output - @staticmethod - def find_by(options): - with open("../startup_funding.csv", "rt") as csvfile: - data = csv.reader(csvfile, delimiter=',', quotechar='"') - # skip header - next(data) - csv_data = [] - for row in data: - csv_data.append(row) - - if 'company_name' in options: - for row in csv_data: - if row[1] == options['company_name']: - mapped = {} - mapped['permalink'] = row[0] - mapped['company_name'] = row[1] - mapped['number_employees'] = row[2] - mapped['category'] = row[3] - mapped['city'] = row[4] - mapped['state'] = row[5] - mapped['funded_date'] = row[6] - mapped['raised_amount'] = row[7] - mapped['raised_currency'] = row[8] - mapped['round'] = row[9] - return mapped - - if 'city' in options: - for row in csv_data: - if row[4] == options['city']: - mapped = {} - mapped['permalink'] = row[0] - mapped['company_name'] = row[1] - mapped['number_employees'] = row[2] - mapped['category'] = row[3] - mapped['city'] = row[4] - mapped['state'] = row[5] - mapped['funded_date'] = row[6] - mapped['raised_amount'] = row[7] - mapped['raised_currency'] = row[8] - mapped['round'] = row[9] - return mapped - - if 'state' in options: - for row in csv_data: - if row[5] == options['state']: - mapped = {} - mapped['permalink'] = row[0] - mapped['company_name'] = row[1] - mapped['number_employees'] = row[2] - mapped['category'] = row[3] - mapped['city'] = row[4] - mapped['state'] = row[5] - mapped['funded_date'] = row[6] - mapped['raised_amount'] = row[7] - mapped['raised_currency'] = row[8] - mapped['round'] = row[9] - return mapped - - if 'round' in options: - for row in csv_data: - if row[9] == options['round']: - mapped = {} - mapped['permalink'] = row[0] - mapped['company_name'] = row[1] - mapped['number_employees'] = row[2] - mapped['category'] = row[3] - mapped['city'] = row[4] - mapped['state'] = row[5] - mapped['funded_date'] = row[6] - mapped['raised_amount'] = row[7] - mapped['raised_currency'] = row[8] - mapped['round'] = row[9] - return mapped +class RecordNotFound(Exception): + pass - raise RecordNotFound -class RecordNotFound(Exception): - pass +class FundingRaised: + # Словарь для замены магических индексов + _COLUMNS = { + 'permalink': 0, 'company_name': 1, 'number_employees': 2, + 'category': 3, 'city': 4, 'state': 5, 'funded_date': 6, + 'raised_amount': 7, 'raised_currency': 8, 'round': 9 + } + + @classmethod + def _get_csv_path(cls): + """Возвращает путь к CSV-файлу независимо от места запуска.""" + current_dir = os.path.dirname(os.path.abspath(__file__)) + return os.path.join(current_dir, 'startup_funding.csv') + + @classmethod + def _read_csv(cls): + """Читает CSV и возвращает список строк без заголовка.""" + with open(cls._get_csv_path(), 'r') as f: + reader = csv.reader(f) + next(reader) + return list(reader) + + @classmethod + def _filter_data(cls, data, filters): + """Применяет фильтры к данным.""" + result = data + for field, value in filters.items(): + if field in cls._COLUMNS: + idx = cls._COLUMNS[field] + result = [row for row in result if row[idx] == value] + return result + + @classmethod + def _row_to_dict(cls, row): + """Преобразует строку в словарь.""" + return {name: row[idx] for name, idx in cls._COLUMNS.items()} + + @classmethod + def where(cls, options=None): + """Возвращает все записи, соответствующие фильтрам.""" + if options is None: + options = {} + data = cls._read_csv() + filtered = cls._filter_data(data, options) + return [cls._row_to_dict(row) for row in filtered] + + @classmethod + def find_by(cls, options): + """Возвращает первую запись, соответствующую фильтрам.""" + results = cls.where(options) + if not results: + raise RecordNotFound + return results[0]