Coder Social home page Coder Social logo

professional_task's People

Contributors

alexblack01 avatar pan7ae avatar

Watchers

 avatar

professional_task's Issues

Стандарт оформления кода

Проблема с отступами в коде

  • К чему может привести данная проблема

    Неправильные отступы могут привести к ошибкам компиляции или неправильной интерпретации кода.

  • Из-за чего могла возникнуть данная проблема

    Проблема может быть связана с неправильным форматированием кода, несоблюдением правил оформления отступов в соответствии со стандартом PEP 8, использованием табуляции вместо пробелов и т.д. Отсутствие правильных отступов может привести к трудностям в чтении и понимании кода другими программистами

  • Пример участков кода

    • src/promotion/api/promo.py Строки: 23 – 27

      async def create_promotion(
              promo_data: PromoCreate = Depends(PromoCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          return await service.create(promo_data)

      В данном случае, отступы перед строками promo_data: PromoCreate = Depends(PromoCreate.as_form), и service: PromoService = Depends(get_promo_service) должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 31 – 34

      async def get_promotion(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)):
          return await service.get(promo_id)

      В данном случае, отступы перед строками promo_id: int, и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 38 – 42

      async def update_promotion(
              promo_id: int,
              promo_data: PromoUpdate = Depends(PromoUpdate.as_form),
              service: PromoService = Depends(get_promo_service)):
          return await service.update(promo_id, promo_data)

      В данном случае, отступы перед строками promo_id: int, promo_data: PromoUpdate = Depends(PromoUpdate.as_form) и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 46 – 49

      async def delete_promotion(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)):
          return await service.delete(promo_id)

      В данном случае, отступы перед строками promo_id: int, и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 53 – 58

      async def create_participant(
              promo_id: int,
              user_data: UserCreate = Depends(UserCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      В данном случае, отступы перед строками promo_id: int, user_data: UserCreate = Depends(UserCreate.as_form) и service: PromoService = Depends(get_promo_service) должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 62 – 66

      async def delete_participant(
              promo_id: int,
              participant_id: int,
              service: PromoService = Depends(get_promo_service)):
          pass

      В данном случае, отступы перед строками promo_id: int, uparticipant_id: int, и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 70 – 74

      async def create_prize(
              prize_data: PrizeCreate = Depends(PrizeCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      В данном случае, отступы перед строками prize_data: PrizeCreate = Depends(PrizeCreate.as_form), и service: PromoService = Depends(get_promo_service) должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 78 – 82

      async def delete_prize(
              promo_id: int,
              prize_id: int,
              service: PromoService = Depends(get_promo_service)):
          pass

      В данном случае, отступы перед строками promo_id: int,, prize_id: int, и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/api/promo.py Строки 86 – 90

      async def promotion_result(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      В данном случае, отступы перед строками promo_id: int,, и service: PromoService = Depends(get_promo_service)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/models/prize.py Строки 19 – 22

      def as_form(
              cls,
              description: str = Form(None)):
          return cls(name=description)

      В данном случае, отступы перед строками cls,, и description: str = Form(None)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/models/promotion.py Строки 29 – 33

      def as_form(
              cls,
              name: str = Form(...),
              description: Optional[str] = Form(None)):
          return cls(name=name, description=description)

      В данном случае, отступы перед строками cls,, name: str = Form(...), и description: Optional[str] = Form(None)): должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

    • src/promotion/models/user.py Строки 17 – 20

      def as_form(
              cls,
              name: str = Form(...)):
          return cls(name=name)

      В данном случае, отступы перед строками cls, и name: str = Form(...), должны состоять из 4 пробелов в соответствии со стандартом PEP 8, но здесь используется неправильное количество пробелов и табуляция.

Проблема с "висящей" скобкой, закрывающей блок параметров функции

  • К чему может привести данная проблема

    Висящая закрывающая скобка в блоке параметров функции может вызвать путаницу и затруднить чтение кода другим программистам. Это может привести к ошибкам при попытке понять и использовать функцию. (Не считаю это большой ошибкой форматирования кода, но нужно оформлять все в едином стиле)

  • Из-за чего могла возникнуть данная проблема

    Вероятно, это связано с неправильным форматированием кода при написании функции.

  • Пример участков кода

    • src/promotion/api/promo.py Строки: 23 – 27

      async def create_promotion(
              promo_data: PromoCreate = Depends(PromoCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          return await service.create(promo_data)

      Необходимо обратить внимание на строку 26. Закрывающая скобка должна быть на той же строке, что и параметры функции.

    • src/promotion/api/promo.py Строки 53 – 58

      async def create_participant(
              promo_id: int,
              user_data: UserCreate = Depends(UserCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      Необходимо обратить внимание на строку 57. Закрывающая скобка должна быть на той же строке, что и параметры функции.

    • src/promotion/api/promo.py Строки 70 – 74

      async def create_prize(
              prize_data: PrizeCreate = Depends(PrizeCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      Необходимо обратить внимание на строку 73. Закрывающая скобка должна быть на той же строке, что и параметры функции.

    • src/promotion/api/promo.py Строки 86 – 90

      async def promotion_result(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)
      ):
          pass

      Необходимо обратить внимание на строку 89. Закрывающая скобка должна быть на той же строке, что и параметры функции.

Именование (Naming)

Назначение псевдонима (alias – "алиасы") при импорте модулей/библиотек

  • К чему может привести данная проблема

    Затруднение чтения и понимания кода, а также возможность создания конфликтов имен переменных в случае использования алиасов. Это может привести к ошибкам и багам.

  • Из-за чего могла возникнуть данная проблема

    Алиасы могут быть использованы для сокращения длинных имен модулей или для предотвращения конфликтов имен переменных при импорте нескольких модулей, но их неправильное использование может привести к проблемам.

  • Пример участков кода

    src/promotion/db/prize.py Строка: 1

    import sqlalchemy as sa

    В данном участке кода проблема состоит в том, что имя библиотеки импортируется как "sa", что может быть не понятным для других программистов, которые будут читать этот код. Хорошей практикой является использование полных имен библиотек или стандартных сокращений, таких как "sqlalchemy".

Дублирование названий файлов

  • К чему может привести

    Затруднения в поиске и идентификации файлов, путаница при работе с проектом. Это может привести к ошибкам при импортировании модулей и усложнить понимание структуры проекта.

  • Из-за чего могла возникнуть данная проблема

    Проблема дублирования названий файлов могла возникнуть из-за неправильного планирования и организации структуры проекта. Возможно, разработчик не обратил внимания на существующие файлы с таким же названием или не следовал правилам именования файлов.

  • Проект имеет следующую структуру

    professional_task/
    ├── src/
        └──promotions/
            ├── api
                ├── __init__.py
                ├── depends.py
                └── promo.py
            ├── db/
                ├── __init__.py
                ├── database.py
                ├── prize.py
                ├── promotion.py
                └── user.py
            ├── models/
                ├── __init__.py
                ├── prize.py
                ├── promotion.py
                ├── result.py
                └──  user.py
            ├── services/
                ├── __init__.py
                └── promo.py
            ├── __init__.py
            ├── config.py
            └── main.py
    ├── venv/
    ├── .env
    ├── .gitignore
    ├── docker-compose.yml
    ├── Dockerfile
    ├── README.md
    └── requirements.txt
    

    Для исправления проблемы рекомендуется переименовать дублирующиеся файлы или переорганизовать структуру проекта, чтобы избежать конфликта имен файлов.

Непонятные названия методов

  • К чему может привести

    Непонятные названия методов могут затруднить понимание функциональности и назначения этих методов. Это может привести к ошибкам при использовании или поддержке кода и усложнить его чтение и понимание для других разработчиков.

  • Из-за чего могла возникнуть данная проблема

    Проблема непонятных названий методов могла возникнуть из-за недостаточного внимания к неймингу или отсутствия ясной конвенции именования методов. Возможно, разработчик не уделил достаточного внимания важности понятных и информативных названий методов.

  • Пример участков кода

    src/promotion/services/promo.py Строка: 14 – 27

    async def _get(self, promo_id: int) -> PromoWithDetails:
        query = promotions.select().where(promotions.c.id == promo_id)
        promo = await self.database.fetch_one(query=query)
    
        if not promo:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
        return PromoWithDetails.parse_obj(promo)
    
    async def get_list(self) -> List[Promo]:
        query = promotions.select()
        return await self.database.fetch_all(query=query)
    
    async def get(self, promo_id: int) -> PromoWithDetails:
        return await self._get(promo_id)

    Для исправления проблемы рекомендуется переименовать методы с более информативными и понятными названиями, отражающими их функциональность и назначение. Это поможет сделать код более читаемым и понятным для других разработчиков.

Непонятное назначение метода

  • К чему может привести

    Непонятные названия методов (create, update, delete) могут затруднить понимание того, что конкретно выполняют эти методы. Это может привести к путанице и ошибкам при использовании методов, особенно для других разработчиков, которые могут работать с этим кодом. Также это может привести к ошибкам и непредсказуемому поведению, особенно при использовании этих методов в других частях кода или при работе с API.

  • Из-за чего могла возникнуть данная проблема

    Проблема непонятных названий методов (create, update, delete) может возникнуть из-за отсутствия ясности и информативности в выборе имен методов. Разработчик, создавший эти методы, мог не уделить достаточного внимания понятности и информативности их названий, что привело к затруднениям в их использовании и понимании.

    src/promotion/services/promo.py Строка: 29 – 53

    async def create(self, promo_data: PromoCreate):
        promo = PromoCreate(**promo_data.dict())
    
        values = {**promo.dict()}
        query = promotions.insert().values(**values)
        promo_res = await self.database.execute(query=query)
        return promo_res
    
    async def update(self, promo_id: int, promo_data: PromoUpdate) -> Promo:
        promo = await self._get(promo_id)
    
        for field, value in promo_data:
            if value:
                setattr(promo, field, value)
    
        values = {**promo.dict()}
        query = promotions.update().where(promotions.c.id == promo_id).values(**values)
        await self.database.execute(query=query)
        return promo
    
    async def delete(self, promo_id: int):
        await self._get(promo_id)
    
        query = promotions.delete().where(promotions.c.id == promo_id)
        return await self.database.execute(query=query)

    Для исправления проблемы рекомендуется переименовать методы таким образом, чтобы они точно отражали свою функциональность. Например, можно использовать более информативные и понятные названия, указывающие на конкретные действия, которые выполняются. Например, вместо "create" можно использовать "create_promotion", вместо "update" – "update_promotion", а вместо "delete" – "delete_promotion". Это поможет улучшить читаемость и понимание кода другими разработчиками.

Дублирование кода

Дублирование кода

  • К чему может привести данная проблема

    • Усложнение поддержки и изменений кода из-за повторения одних и тех же определений в разных файлах;
    • Затруднение в обновлении и модификации структуры базы данных из-за необходимости изменений в нескольких местах;
    • Риск возникновения ошибок из-за несогласованности определений таблиц между файлами.
  • Из-за чего могла возникнуть данная проблема

    • Отсутствие общего модуля или класса, который бы объединял определения таблиц и предоставлял их для использования в других модулях;
    • Недостаточное понимание принципа DRY (Don't Repeat Yourself) и необходимости избегать дублирования кода.
  • Пример участков кода

    Проблема относится к файлам prize.py, promotion.py и user.py в директории src/promotion/db/, где определения таблиц повторяются:

    • src/promotion/db/prize.py Строки 4 – 9

      prizes = sa.Table(
          "prizes",
          metadata,
          sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, unique=True),
          sa.Column("description", sa.String, nullable=True)
      )
    • src/promotion/db/promotion.py Строки 4 – 12

      promotions = sa.Table(
          "promotions",
          metadata,
          sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, unique=True),
          sa.Column("name", sa.String, nullable=False),
          sa.Column("description", sa.String, nullable=True),
          sa.Column("prizes", sa.ARRAY(sa.Integer), nullable=True),
          sa.Column("participants", sa.ARRAY(sa.Integer), nullable=True)
      )
    • src/promotion/db/user.py Строки 4 – 9

      users = sa.Table(
          "users",
          metadata,
          sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, unique=True),
          sa.Column("name", sa.String, unique=True),
      )
  • Рекомендации по исправлению

    Рекомендуется вынести определения таблиц в отдельный модуль или класс, который будет общим для всех модулей и предоставлять определения таблиц для использования. Это позволит избежать дублирования кода, сделает код более согласованным и улучшит его поддержку и изменение.

Мертвый код (Dead code)

Неиспользуемая функция

  • К чему может привести данная проблема

    Неиспользуемый код не выполняет никаких полезных действий и может привести к лишней сложности в понимании кода. Это может затруднить поддержку и обновление кода в будущем. Функция не будет использоваться в коде, что может привести к ненужному расходованию ресурсов.

  • Из-за чего могла возникнуть данная проблема

    Функция была определена, но не была вызвана в коде. Также неиспользуемый код может возникнуть, если в процессе разработки были внесены изменения в функцию, и определенные части кода стали ненужными.

  • Пример участков кода

    • src/promotion/api/promo.py Строки 53 – 58

      async def create_participant(
              promo_id: int,
              user_data: UserCreate = Depends(UserCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass
    • src/promotion/api/promo.py Строки 62 – 66

      async def delete_participant(
              promo_id: int,
              participant_id: int,
              service: PromoService = Depends(get_promo_service)):
          pass
    • src/promotion/api/promo.py Строки 70 – 74

      async def create_prize(
              prize_data: PrizeCreate = Depends(PrizeCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          pass
    • src/promotion/api/promo.py Строки 78 – 82

      async def delete_prize(
              promo_id: int,
              prize_id: int,
              service: PromoService = Depends(get_promo_service)):
          pass
    • src/promotion/api/promo.py Строки 86 – 90

      async def promotion_result(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)
      ):
          pass
  • Рекомендации по исправлению

    Удалить функцию, если она не нужна в программе, или добавить вызов этой функции в нужном месте кода. Если функция была намеренно оставлена без использования для будущего использования, то необходимо добавить комментарий с указанием этой цели.

Тестирование

Отсутствие модульных тестов

  • К чему может привести данная проблема

    Отсутствие модульных тестов может привести к следующим проблемам:

    • Увеличение вероятности возникновения ошибок и дефектов в коде;
    • Затруднение обнаружения и исправления ошибок.
  • Из-за чего могла возникнуть данная проблема

    Отсутствие модульных тестов может возникнуть по следующим причинам:

    • Недостаток понимания важности и пользы модульного тестирования;
    • Отсутствие средств и инфраструктуры для написания и запуска модульных тестов;
    • Отсутствие времени или недостаток процесса включения модульного тестирования в разработку.
  • Для исправления данной проблемы рекомендуется добавить модульные тесты для каждого эндпоинта. Модульные тесты позволят проверить корректность работы каждого эндпоинта в изоляции, обнаружить ошибки и дефекты, а также обеспечить надежность и уверенность в работе кода.

Аннотация типов

Отсутствие аннотации типов

  • К чему может привести данная проблема

    Отсутствие аннотации типов может затруднить чтение и понимание кода другими разработчиками, а также привести к ошибкам типизации и неожиданным поведениям в случае передачи неправильных аргументов.
    Отсутствие аннотаций типов усложняет понимание типов данных, которые принимаются и возвращаются функцией. Это может привести к ошибкам при вызове функции с аргументами неправильного типа, а также усложнить работу с кодом в будущем.

  • Из-за чего могла возникнуть данная проблема

    Возможно, разработчик не был достаточно внимателен при написании кода или не имел достаточного опыта работы с аннотациями типов в Python – это маловероятно, т.к. в большинстве случаев она все-таки есть. Либо это старый код, написанный до введения поддержки аннотаций типов в Python, что также маловероятно.

  • Пример участков кода

    • src/promotion/api/promo.py Строки 18 – 19

      async def get_promotions(service: PromoService = Depends(get_promo_service)):
          return await service.get_list()
    • src/promotion/api/promo.py Строки: 23 – 27

      async def create_promotion(
              promo_data: PromoCreate = Depends(PromoCreate.as_form),
              service: PromoService = Depends(get_promo_service)
      ):
          return await service.create(promo_data)
    • src/promotion/api/promo.py Строки 31 – 34

      async def get_promotion(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)):
          return await service.get(promo_id)
    • src/promotion/api/promo.py Строки 38 – 42

      async def update_promotion(
              promo_id: int,
              promo_data: PromoUpdate = Depends(PromoUpdate.as_form),
              service: PromoService = Depends(get_promo_service)):
          return await service.update(promo_id, promo_data)
    • src/promotion/api/promo.py Строки 46 – 49

      async def delete_promotion(
              promo_id: int,
              service: PromoService = Depends(get_promo_service)):
          return await service.delete(promo_id)
    • src/promotion/models/prize.py Строки 18 – 22

      @classmethod
      def as_form(
              cls,
              description: str = Form(None)):
          return cls(name=description)
    • src/promotion/models/promotion.py Строки 28 – 33

      @classmethod
      def as_form(
              cls,
              name: str = Form(...),
              description: Optional[str] = Form(None)):
          return cls(name=name, description=description)
    • src/promotion/models/user.py Строки 16 – 20

      @classmethod
      def as_form(
              cls,
              name: str = Form(...)):
          return cls(name=name)
    • src/promotion/services/promo.py Строки 29 – 35

      async def create(self, promo_data: PromoCreate):
          promo = PromoCreate(**promo_data.dict())
      
          values = {**promo.dict()}
          query = promotions.insert().values(**values)
          promo_res = await self.database.execute(query=query)
          return promo_res
    • src/promotion/services/promo.py Строки 49 – 53

      async def delete(self, promo_id: int):
          await self._get(promo_id)
      
          query = promotions.delete().where(promotions.c.id == promo_id)
          return await self.database.execute(query=query)
  • Рекомендации по исправлению

    Для устранения данной проблемы следует добавить аннотации типов для параметров функции и/или возвращаемого значения.

Безопасность

Хранение захардкоженных паролей

  • К чему может привести данная проблема

    Хранение захардкоженных паролей в docker-compose.yml может привести к следующим проблемам:

    • Уязвимость безопасности: Захардкоженные пароли легко могут быть обнаружены или использованы злоумышленниками, что приводит к возможности несанкционированного доступа к системе или данным;
    • Отсутствие масштабируемости: Изменение паролей требует изменения в коде и повторной сборки контейнеров, что затрудняет управление и обновление системы;
    • Нарушение принципа разделения ответственности: Захардкоженные пароли привязаны к коду и конфигурации, что нарушает принцип разделения ответственности и усложняет конфигурирование системы.
  • Из-за чего могла возникнуть данная проблема

    Хранение захардкоженных паролей в docker-compose.yml может возникнуть по следующим причинам:

    • Недостаток понимания важности безопасного хранения паролей и общих практик безопасности;
    • Отсутствие средств для удобного и безопасного хранения конфиденциальной информации, такой как пароли;
    • Отсутствие или недостаточное применение инструментов управления конфигурацией и секретами, которые позволяют изолировать конфиденциальные данные от кода и конфигурации.
  • Пример участков кода

    docker-compose.yml Строки 11 – 14

    services:
      db_promotion:
        image: postgres:13-alpine
        # ...
        environment:
          - POSTGRES_USER=fastapi_promotion
          - POSTGRES_PASSWORD=fastapi_promotion
          - POSTGRES_DB=fastapi_promotion

    Для исправления данной проблемы рекомендуется использовать механизмы управления секретами, предоставляемые Docker или другими инструментами, например, Docker Secrets или переменные окружения. Это позволит изолировать конфиденциальные данные, такие как пароли, от кода и конфигурации, обеспечивая безопасность и гибкость в управлении секретами.

    Также создание файла docker-compose.override.yml может помочь в решении данной проблемы. Файл docker-compose.override.yml предназначен для переопределения или расширения настроек, определенных в основном файле docker-compose.yml.

    Вы можете создать файл docker-compose.override.yml и использовать его для определения конфигурации, включая конфиденциальные данные, такие как пароли. Ваш основной файл docker-compose.yml будет ссылаться на этот файл, и настройки из docker-compose.override.yml будут применяться при запуске контейнеров.

Обработка исключений

Отсутствие обработки исключений с установкой общего таймаута при запросе к базе данных

В коде отсутствует обработка исключений и установка общего таймаута для запросов к базе данных. Это может привести к блокировке приложения, если запрос к базе данных занимает слишком много времени, и нет механизма для прерывания этого запроса

  • К чему может привести данная проблема

    Отсутствие обработки исключений при выполнении запросов к базе данных может привести к следующим проблемам:

    • Блокировка приложения и его неработоспособность в случае длительного запроса к базе данных;
    • Потенциальная потеря производительности и отзывчивости приложения.
  • Из-за чего могла возникнуть данная проблема

    Отсутствие обработки таймаута может быть вызвано незнанием или непредусмотрительностью разработчика при написании кода для выполнения запросов к базе данных. Возможно, разработчик не предусмотрел случаев, когда запрос может занимать слишком много времени из-за проблем с сетью, нагрузкой на БД или других факторов.

  • Пример участков кода

    src/promotion/main.py Строки 11 – 18

    @app.on_event("startup")
    async def startup():
        await database.connect()
    
    @app.on_event("shutdown")
    async def shutdown():
        await database.disconnect()

    Для решения данной проблемы необходимо добавить обработку исключений и установить общий таймаут для запросов к базе данных. Это позволит предотвратить блокировку приложения и обеспечить его отзывчивость.
    Т.е. можно добавить обработку исключений и установить общий таймаут, например, в 60 секунд для запросов к базе данных при запуске и остановке приложения.

Принципы SOLID

Принцип единой ответственности (Single Responsibility Principle, SRP)

  • К чему может привести данная проблема

    • Усложнение поддержки и изменений кода из-за размытой ответственности класса;
    • Ухудшение читаемости и понимания кода из-за смешения различных операций в одном классе;
    • Затруднение в тестировании и отладке из-за сложности изоляции и тестирования отдельных функциональностей.
  • Из-за чего могла возникнуть данная проблема

    • Недостаточное понимание принципа SRP и его применения в проектировании;
    • Постепенное усложнение класса при добавлении новых функциональностей без переосмысления его ответственностей
  • Пример участков кода

    src/promotion/services/promo.py Строки 10 – 53

    class PromoService:
        def __init__(self, database: Database):
            self.database = database
    
        async def _get(self, promo_id: int) -> PromoWithDetails:
            query = promotions.select().where(promotions.c.id == promo_id)
            promo = await self.database.fetch_one(query=query)
    
            if not promo:
                raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
            return PromoWithDetails.parse_obj(promo)
    
        async def get_list(self) -> List[Promo]:
            query = promotions.select()
            return await self.database.fetch_all(query=query)
    
        async def get(self, promo_id: int) -> PromoWithDetails:
            return await self._get(promo_id)
    
        async def create(self, promo_data: PromoCreate):
            promo = PromoCreate(**promo_data.dict())
    
            values = {**promo.dict()}
            query = promotions.insert().values(**values)
            promo_res = await self.database.execute(query=query)
            return promo_res
    
        async def update(self, promo_id: int, promo_data: PromoUpdate) -> Promo:
            promo = await self._get(promo_id)
    
            for field, value in promo_data:
                if value:
                    setattr(promo, field, value)
    
            values = {**promo.dict()}
            query = promotions.update().where(promotions.c.id == promo_id).values(**values)
            await self.database.execute(query=query)
            return promo
    
        async def delete(self, promo_id: int):
            await self._get(promo_id)
    
            query = promotions.delete().where(promotions.c.id == promo_id)
            return await self.database.execute(query=query)
  • Рекомендации по решению:

    Рекомендуется разделить класс PromoService на отдельные классы, каждый из которых будет выполнять только одну конкретную задачу, соответствуя принципу SRP. Это улучшит понимание и поддержку кода, сделает его более гибким и легко расширяемым.

Организация файловой структуры

Разделение моделей по разным файлам

  • К чему может привести данная проблема

    Разделение моделей по разным файлам может затруднить их обнаружение и понимание структуры проекта. Это усложняет поддержку и разработку кода, особенно при работе с большими проектами. Кроме того, разбросанные модели могут привести к дублированию кода и несогласованности между моделями, что может привести к ошибкам и неоднозначности.

  • Из-за чего могла возникнуть данная проблема

    Разделение моделей по разным файлам могло возникнуть из-за неоптимальной организации кода или отсутствия ясных принципов и стандартов для структурирования моделей.

  • Пример участков кода

    professional_task/
    ├── src/
        └──promotions/
            ├── api/
            ├── db/
            ├── models/
                ├── __init__.py
                ├── prize.py
                ├── promotion.py
                ├── result.py
                └──  user.py
            ├── services/
            ├── __init__.py
            ├── config.py
            └── main.py
    ├── venv/
    ├── .env
    ├── .gitignore
    ├── docker-compose.yml
    ├── Dockerfile
    ├── README.md
    └── requirements.txt
    

    Для исправления проблемы рекомендуется объединить модели, которые имеют связь или взаимосвязь, в один файл. Например, можно создать файл models.py и поместить в него все модели. Это упростит понимание структуры данных и улучшит обслуживание кода.

Логирование

Отсутствие логов

В коде отсутствует использование механизма логирования, что затрудняет отслеживание и анализ происходящих событий и ошибок в приложении. Отсутствие логов может усложнить процесс отладки, мониторинга и выявления проблемных мест.

  • К чему может привести данная проблема

    • Отсутствие информации о происходящих событиях, ошибках и предупреждениях в приложении;
    • Затруднение в процессе отладки и выявления причин возникновения проблем;
    • Невозможность проведения аудита и анализа работы приложения.
  • Из-за чего могла возникнуть данная проблема

    • Отсутствие настройки и использования библиотеки или инструментов для логирования;
    • Недостаточное внимание к важности и необходимости логирования.
  • Пример участков кода

    Проблема относится ко всему коду приложения, где отсутствует использование механизма логирования.

  • Рекомендации по решению:

    Для решения данной проблемы необходимо добавить механизм логирования в приложение. Рекомендуется использовать специализированные библиотеки или инструменты для логирования, такие как logging в Python, которые предоставляют гибкость в настройке и уровнях логирования.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.