• Как правильно назвать rest-функции?

    @pcdesign
    Вообще это серьезный на самом деле вопрос.
    Как правильно называть функции, как правильно называть переменные?
    Этому вопросу посвящено определенное кол-во страниц в книгах: "Совершенный код", "Чистый код: создание, анализ и рефакторинг" и т.д. Если решили подключить перфекционизм, то вам стоит изучать эти книжки, хотя бы соответствующие главы.

    Вообще, проблема с правильным именованием присуща всем языкам.

    А конкретно с оформлением, да есть определенные стандарты. Например, есть языки где принят "горб верблюда" - getUserId(), в python в основном используют нижнее подчеркивание - get_user_id. Но это, имхо, уже мелочи.
    Ответ написан
    Комментировать
  • Какие шаблоны проектирования js применяются на практике чаще всего?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    какие паттерны применяются чаще всего на практике и где

    Сразу отмечу, что все это чисто мое имхо, которое может не совпадать с мнением окружающих. В контексте фронтенда обычно все довольно просто. По моим наблюдениям в среднем сайте могут иметь смысл:
    1. Модули (делим код на независимые части)
    2. Фабрики (для компонентов интерфейса)
    3. Синглтоны (для хранилищ, точек сбора полифиллов / утилит и.т.д.)
    4. Адаптеры (для зависимостей и полифилов, которые могут измениться / выпилиться)
    5. Наблюдатели (для сбора происходящих событий в одном месте)
    6. Хранители (для сохранения действий пользователя и "Ctrl-Z")
    7. Стратегии (если действуем в зависимости от прилетевших данных)

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

    Важно понимать, что паттерны проектирования - это просто хорошие идеи по поводу того, как организовать большой объем кода в той или иной ситуации. Это не "изучи тайное знание, запомни, и делай так всегда", не "используй паттерны, потому что великие их используют", это скорее "если не уверен как организовать код, возьми готовую идею, она вроде работает". Если вы будете просто решать задачи, то через N лет практики вы сами их все "изобретете", только не будете знать, что у них есть названия. Эффективно будет организовать себе заметку о том, какие из этих идей для чего примерно применяют, а потом, в процессе работы, в нее подглядывать, если встал вопрос "как организовать этот код".
    Ответ написан
    7 комментариев
  • Как восстановить структуру БД на новой машине?

    NeiroNx
    @NeiroNx
    Программист
    Если почитать документацию то таблицы из модели можно создать так:
    >>> from yourapplication import db
    >>> db.create_all()

    возможно совместить с условием sqlalchemy_utils.database_exists()
    https://www.programcreek.com/python/example/98164/...
    Ответ написан
    Комментировать
  • Почему форма не валидна?

    @pcdesign
    if request.method == 'POST' and search_form.validate_on_submit():


    Из-за этой строки.
    Если запрос не POST, а GET то каждый раз будем получить 'form is not valid'

    Должно быть что-то вроде этого:
    if request.method == 'POST':
        if search_form.validate_on_submit():
            print('form is valid')
        else:
            print('form is not valid')


    А так же попробуйте так добавить str:
    choices=[(str(item.id), item.searcher) for item in Searcher.query.all()]
    Ответ написан
    7 комментариев
  • Как запустить парсер по крону?

    fox_12
    @fox_12 Куратор тега Python
    Расставляю биты, управляю заряженными частицами
    Используйте Flask-Script для этого.

    Проблема в том, что после запуска командой flask run парсер отрабатывает, но ...

    Это вы явно что-то не то делаете...
    Ответ написан
    Комментировать
  • Обязательно ли использовать try/else?

    Ваши варианты не ошибочны, но есть несколько моментов для осмысления.
    Судя по наличию return, у Вас функция возвращает текст. Какое поведение Вы предусмотрели
    в случае неудачного завершения операции requests.get? И на каком уровне Вы намерены
    обрабатывать ошибки. Никто не может сказать Вам, как правильно, пока не узнает контекст
    Вашей задачи. Может Вы выберите стратегию: "падать как можно раньше" и вызвав панику
    завершите приложение, запишите в лог и перейдете к следующему url или что то еще.

    Предложу Вам третьи вариант:
    try:
        html = requests.get(url, headers=self.headers)
    except Exception as e:
        print('Root page parse is failed', e)
        # Ваши инструкции для ошибочной ситуации
    return html.text

    Первый вариант плох тем, что блоке для отлова стоит return, который не может
    вызвать в данном случае исключение. Второй тем, что используете else
    без необходимости. Явное лучше неявного. Использование Else как многие
    эксперты замечают в целом вредная практика. И в добавок, если функция
    возвращает значение, то прописывайте return в основном теле, а не в
    ветвлении. В будущем откроете для себя аннотирование типов, и начнете
    использовать статические анализаторы.

    P.S. Если будет время, то виды исключении лучше обрабатывать явно, а не
    ловить их все в один блок. Так можно прописать несколько стратегии для
    разных случаев сбоя.
    Ответ написан
    5 комментариев
  • Почему не создаётся пользователь?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега PostgreSQL
    Седой и строгий
    Ключ -U указывает логин не нового создаваемого юзера, а создающего, под которым утилита подключается к СУБД.
    Ответ написан
    Комментировать
  • Почему psycopg2 ругается на python3.5?

    NeiroNx
    @NeiroNx
    Программист
    скрее всего pip ссылается на 2.7, попробуй так
    python3 -m pip install psycopg2
    Ответ написан
    Комментировать
  • Почему пользователю БД не назначаются права?

    Melkij
    @Melkij
    PostgreSQL DBA
    postgres=# CREATE DATABASE joba_finder;
    CREATE DATABASE
    postgres=# CREATE USER jf_user WITH PASSWORD 'qwerty';
    CREATE ROLE
    postgres=# \l joba_finder 
                                   Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   | Права доступа 
    -------------+----------+-----------+-------------+-------------+---------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | 
    (1 строка)
    
    postgres=# GRANT ALL PRIVILEGES ON DATABASE joba_finder to jf_user;
    GRANT
    postgres=# \l joba_finder 
                                       Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   |     Права доступа     
    -------------+----------+-----------+-------------+-------------+-----------------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | =Tc/postgres         +
                 |          |           |             |             | postgres=CTc/postgres+
                 |          |           |             |             | jf_user=CTc/postgres
    (1 строка)
    
    postgres=# select version();
                                                    version                                                 
    --------------------------------------------------------------------------------------------------------
     PostgreSQL 11.2 (Debian 11.2-2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-2) 8.3.0, 64-bit
    (1 строка)

    Just works. Настройками это не регулируется, так что проверяйте что вы делаете не так. Может быть не коммитите транзакцию с grant? Не знаю.

    Не заметил:

    joba_finder-# \l

    Внимание на -# так где должен быть =# - метка указывает, что вы начали писать запрос, но не завершили его. psql команды вроде \l при этом всё ещё обрабатываются.
    postgres=# select
    postgres-# \l joba_finder 
                                       Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   |     Права доступа     
    -------------+----------+-----------+-------------+-------------+-----------------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | =Tc/postgres         +
                 |          |           |             |             | postgres=CTc/postgres+
                 |          |           |             |             | jf_user=CTc/postgres
    (1 строка)
    
    postgres-# 1;
     ?column? 
    ----------
            1
    (1 строка)

    Как пример psql команды в середине написания select 1;
    Ответ написан
    3 комментария
  • Почему не парсится страничка?

    alternativshik
    @alternativshik
    Добавление заголовка User-Agent поможет
    Ответ написан
    2 комментария
  • Где хранятся атифакты?

    Кажется вам нужно почитать документацию https://docs.gitlab.com/ee/ci/yaml/#artifacts
    В частности - про то как сохранять артефакт и настройку длительности хранения.

    Всю страницу в т.ч. Чтобы небыло таких странных вопросов.
    Ответ написан
    Комментировать
  • Является ли список массивом?

    @CrazyElf
    Конечно же есть стандартный модуль с такими свойствами: https://docs.python.org/3/library/collections.html...

    Deques are a generalization of stacks and queues (the name is pronounced “deck” and is short for “double-ended queue”). Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction.
    Ответ написан
    3 комментария
  • Является ли список массивом?

    devalone
    @devalone
    ̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
    В питоне в списке хранятся ссылки на элементы, т.е. создание нового куска памяти не так затратно
    Ответ написан
    3 комментария
  • Возможно ли улучшить пример ISP?

    longclaps
    @longclaps
    Возможно, питон - самый неподходящий язык для всякой фигни, завязанной на инкапсуляции. Ничто не мешает сделать так
    worker.pay = 100500
    или так
    Boss.setPay(worker, 100500)
    или даже так
    worker = Worker(10)
    worker.getPay()
    worker.__class__.setPay = Boss.setPay #  мутим
    worker.setPay(100500)                 #  мутим
    del worker.__class__.setPay           #  мутим
    worker.getPay()
    worker.setPay(20)                     #  я не при делах!
    worker.getPay()

    Потуги это обойти - как шлагбаум в чистом поле )
    Ответ написан
    2 комментария
  • Возможно ли улучшить пример LSP?

    vt4a2h
    @vt4a2h
    Senior software engineer (C++/Qt/boost)
    Тут есть проблема: во втором примере оба класса наследника абсолютно одинаковые. Т.е. пример ничего не показывает.

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

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Углубляться в чистый js и учить популярные фреймворки/библиотеки.
    Ответ написан
    Комментировать
  • Нарушает ли композиция принцип единой обязанности из solid?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Нет, не нарушает. Композиция порождает зависимость, а не расширяет ответственность. Если зависимый класс соблюдает D, а класс зависимости соблюдает I и L, то всё в порядке.
    Ответ написан
    Комментировать
  • Почему интерфейсы не избыточны?

    @Andy_U
    В приведенном коде все будет работать и без абстрактных классов. Но если в конце (перед newspaper.add_news('Сообщение')) добавить строчку newspaper.register('abc'), то лишь выполнение программы закончится с ошибкой. Если код сложнее представленного, ошибка может всплыть совсем не сразу. Тот же Pycharm данную ошибку никак не сможет обнаружить.

    А вот если к коду добавить type hints:
    from typing import List
    from abc import ABC, abstractmethod
    
    
    class Observer(ABC):
        @abstractmethod
        def update(self, message: str) -> None:
            pass
    
    
    class Observable(ABC):
        @abstractmethod
        def register(self, observer: Observer) -> None:
            pass
    
        @abstractmethod
        def notify_observers(self, message: str) -> None:
            pass
    
    
    class Newspaper(Observable):
        def __init__(self) -> None:
            self.observers: List[Observer] = []
    
        def register(self, observer: Observer) -> None:
            self.observers.append(observer)
    
        def notify_observers(self, message: str) -> None:
            for observer in self.observers:
                observer.update(message)
    
        def add_news(self, news: str) -> None:
            self.notify_observers(news)
    
    
    class Citizen(Observer):
        def __init__(self, name: str) -> None:
            self.name = name
    
        def update(self, message: str) -> None:
            print('{} получил: {}'.format(self.name, message))
    
    
    if __name__ == '__main__':
    
        newspaper = Newspaper()
        newspaper.register(Citizen('Иван'))
        newspaper.register(Citizen('Василий'))
        newspaper.register('abc')
        newspaper.add_news('Сообщение')

    то при использовании Pycharm или mypy они сразу отругаются на ошибку типа:
    (VENV~1) D:\My Documents\PycharmProjects\tst>mypy --strict tst105.py
    tst105.py:49: error: Argument 1 to "register" of "Newspaper" has incompatible type "str"; expected "Observer"


    Т.е., если пишете небольшие программы исключительно для себя в notepad'е - можно и без абстрактных классов и type hints. А вот во всех иных случаях - лучше действовать профессионально.
    Ответ написан
    Комментировать
  • Как перегрузить атрибут функции?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Функция - это объект, но её объявление - это не класс.
    Ответ написан
    Комментировать