Ответы пользователя по тегу ООП
  • Как исправить ошибку в программе на python?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    А вы пробовали читать текст ошибки?
    Вот смотрите, тут указано в какой строке и конкретно где в этой строке ошибка. А ниже написано в чем заключается ошибка.
    File "C:\Users\Никита\Documents\#программа для расчёта оценок.py", line 50, in
    a = ProgrammForTest()
    ^^^^^^^^^^^^^^^^^
    TypeError: ProgrammForTest.__init__() missing 4 required positional arguments: 'a', 'b', 'c', and 'ball'

    Вот вонкретное пояснение: "missing 4 required positional arguments: 'a', 'b', 'c', and 'ball'"

    Мне кажется вам следует взять любую книгу по питону с нуля и пееречитать ее внимательно.

    О каком ООП речь, если вы основных концепий еще не освоили?
    Просто доверьтесь хорошей книге. пусть, например это будет Луц. Но не перескакивайте главы, выполняйте упражнения и всё у вас получится.
    Сейчас же, даже если закрыть глаха на ошибки, вы написали полнейшую чушь. Бессмысленную и беспощадную.
    Ответ написан
  • Как передать значения из данной функции в основную программу?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    нио каком 'return' тут речь быть не может. Это calback.
    Если ваш "основной код" работает в том же потоке, то можете сделать глобальный обьект (синглтон), который будет "виден" на уровне модуля и в on_message и в вашем "основном коде". В него вы затягивайте сообщения, а в другом месте их вынимаете. Для этого очереди и существуют.
    Если речь идёт о разных потоках, то так не получится. Тогда оптимально будет поднять внешнюю очередь, например RabbitMQ и пользоваться ею. Но судя по вашему вопросу, знаний у вас пока не хватит на это. Подучить бы сперва питон на более простых вещах.
    Ответ написан
    1 комментарий
  • Какой паттерн нужен для того чтобы познакомить две сущности?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    А в чем. собственно, проблема?
    Планета у вас опционально имеет игрока. При присваивании планете игрока она обязана дёрнуть соответствующий метод у игрока и добавиться ему в список планет.
    В Питоне я бы использовал слабоые ссылки на планеты в списке у игрока.
    Прежде чем искать идеальную архитектуру вам стоит понять для чего вам всё это нужно и не делать лишнего.
    Ответ написан
    Комментировать
  • Полиморфизм - это обратное наследование?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Это ваше собственное определение про обратное наследование?
    Родительский класс ничего не знает о методах потомков.
    Полиморфизм нужен для организации уровня абстракции.
    У автомобиля есть абстрактный интерфейс: разгоняться, тормозить, поворачивать. Вы применяете соответствующие методы, а под капотом происходит полиморфизм в зависимости от того, на какой машине вы едете: на ДВС при ускорении отодвигается заслонка, обогащается сместь, поступает в форсунки, увеличиваются обороты; у электромобиля частотник увеличивает частоту, синусоиды, идущей на двигатели, он начинает крутиться быстрее... Потом кто-то придумал гибрид и там всё гораздо сложнее, но на уровне "предка" обо всём этом не нужно думать, благодаря полиморфизму мы имеем простые понятные методы, которые у потомков реализованы по-своему.
    Ответ написан
    Комментировать
  • Является ли это исключительной ситуацией?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    А БД у вас глобально торчит в виде синглтона? Вы даёте id конструктору пользователя, и этот конструктор сам (!) лезет в БД (какую-то), что-то оттуда подтягивает, бросает исключения в зависимости от внешнего состояния...

    У какой-то другой сущности, к примеру у приложения, должен быть фабричный метод get_user. Он по идентификатору достаёт необходимые данные (этот код можно в классовый метод юзера поместить) и создаёт на основе этих данных инстанс юзера, например передавая все основные данные в конструктор.
    Ответ написан
    3 комментария
  • Можно ли в геттерах создавать новые сущности?

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

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

    Короче, мало данных для конкретных рекомендаций. Однако менять внутреннее состояние объекта в читающем (по логике вещей) методе, а тем более в геттере свойства -- это плохая идея, она ухудшит код.
    Ответ написан
  • Как однозначно переопределить сложение?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    1. Нужно, чтобы классы A, B, C, D были потомками одного абстрактного класса Base. Абстрактный класс должен декларировать общий для них интерфейс.
    2. Нужно сделать ещё один класс G - потомок от Base. G должен содержать внутри список элементов класса Base. Кроме этого G должен реализовывать все абстрактные методы своего интерфейса путём вызова соответствующих методов вложенных в свой список объектов.
    3. Класс Base должен перекрывать метод сложения __add__. Результатом сложения возвращается экземпляр G, содержащий список из складываемых элементов.
    Ответ написан
    Комментировать
  • Какие функции должны быть методами класса, а какие должны быть функциями модуля?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Мне кажется логичным следующий вариант: если функция не имеет отношения к алгоритму шифрования (напр, chunk - разбивает массив/буфер на равные части), т.е. она может быть использована в каких-то других контекстах, а не только в моей шифрующей проге, то ее стоит вынести из класса.

    • Если функции нужен в качестве контекста выполнения объект, то разумно и логично сделать ее методом.
    • Если функции контекст объекта не нужен, но она ни для чего не годится, кроме внутренних нужд объекта, то можно сделать ее статическим методом, чтобы не засорять глобальный скоуп модуля узко специализированными фугкциями.
    • Если функция более-менее универсальна (как те, что вы описали) и может работать со стандартными типами данных, а не только с вашим объектом, то логично разместить их на уровне модуля или вынести в отдельный модуль.
    Ответ написан
    1 комментарий
  • Для чего нужен полиморфизм?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Полиморфизм - это широкое понятие.
    Идея его в том, чтобы скрыть лишние детали реализации и сделать код более универсальным.
    К примеру у вас есть абстрактный класс Фигура, у него есть абстрактный метод нарисовать(куда: Канва). Этот метод нельзя запускать, он абстрактный. Не понятно как рисовать абстрактную фигуру.
    Зато у фигуры есть потомки: Круг(Фигура) и Квадрат(Фигура). У них метод "нарисовать" перекрыт конкретной реализацией. Это виртуальный метод (есть такой термин в некоторых ЯП).
    За счет полиморфизма мы можем нарисовать любую фигуру не зная как она рисуется. Мы знаем только как с ней общаться на уровне ее интерфейса.
    Ответ написан
    4 комментария
  • Как вызвать из GUI методы?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Мне кажется вы взялись сразу за много задач и пытаетесь решить их одновременно.
    Хорошее решение было бы таким:
    1. Оформить основную бизнес-логику как отдельную библиотеку.
    2. Сделать CLI интерфейс для для вашей функциональности. Это будет отдельный скрипт. который с помощью argparse разбирает параметры командной строки, извлекает из них аргументы и запускает бизнес-логику. Возможно уже этого будет достаточно. особенно если можно вынести редко изменяемую конфигурацию в отдельный json или yaml файл и сделать на уровне операционной системы биндинг вашей утилиты в контекстное меню "Открыть с помощью". CLI утилита вполне способна сделать все необходимые преобразования, создать новый документ и открыть его экселем или что там привязано к xls.
    3. Если так уж нужна GUI, то я бы не советовал для вашей задачи делать нативное приложение с окошками и кнопочками. Можно сделать тривиальный веб-сервис на flask с одной единственной веб-формой, которая позволяет загрузить xls-файл с компа и потом скачать закэшированный результат. Также можно отобразить ошибки преобразования сверстав их в html.

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

    Ок. Давайте более по существу.
    1. Содержимое всех ваших модулей с бизнес-логикой (ParseExcelOMS.py, ParseExcelMIS.py и т.д.) выделите в отдельные функции, входными аргументами которых будут имена файлов.
    2. Импортируйте эти модули в модуле с GUI, и там, получив имена файлов, вызывайте нужные функции.

    Если не будет получаться - приходите с конкретными вопросами. А-то не понятно что именно вам не понятно. Вроде код у вас слишком сложный для непонимания автором концепции функций.
    Ответ написан
  • Куда двигаться(Python)?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Хватит "учить". Это не продуктивно. Просто делайте.
    Начните небольшой pet-project в той области, в какой лично вам интересно. Интерес нужен чисто для мотивации. Если вы супер-мотивированный человек, то и так можете делать всё что угодно.
    Вот какой-то тип рассуждает на ютубчике про то, чем заняться юным программистам. Специально не искал, просто промелькнуло на периферии и ваш вопрос напомнил. Он не про питон говорит, но это не важно.

    От себя могу порекомендовать следующее:
    1. Вести блокнотик для баззвордов. Всё, что слышите вокруг себя касательно предметной области, все непонятные слова и термины выписывайте в блокнотик и, на досуге, гуглите. Если тема и термин релевантны вашей области интересов и выбранному стеку технологий, то вникайте глубже, если не очень, то читайте поверхностно. Со временем новые слова в блокнотик станут попадать всё реже, а старые после нескольких попаданий запомнятся и тоже перестанут. Вы станете эрудированным в своей области.
    2. Читайте чужие исходники. Нет, не учите. Нет глубоко лезть не надо. Просто ищите на гитхабе для себя интересное и читайте как это сделали, думайте как сделали бы вы.
    3. освойте базовые вещи:
      • системы контроля версий в целом и git в частности;
      • концепцию TDD и какую-нибудь из стандартных библиотек для юнит-тестирования;
      • принципы unix-way; стандарты CLI; bash; концепцию пайпов (в linux и windiws);
      • освойте регулярные выражения, порешайте кроссворды.
      • соберите для себя шаблоны стандартных приложений для быстрого старта проектов: сайт с админкой и авторизацией; CLI-утилита; REST API сервис...
      • освойте концепцию docker контейнеризации;
      • освойте CI/CD...



    Где-то к середине этого списка ваш вопрос станет гарантировано не релевантен для вас.
    Ответ написан
    Комментировать