• Что за хэш добавляется в конце названия файла при его загрузке на сервер?

    Скорее всего это сервер делает для уникальности.
    Если сервер ваш, то вам надо просто переписать код, чтобы он так не делал.
    Если нет, то ничего поделать увы нельзя
    Ответ написан
    Комментировать
  • Как поступить с заказчиком?

    alexgp13
    @alexgp13
    Руководитель ИТ-проектов
    С точки зрения проекта в целом - Вы заключили договор о выполнении работы "под ключ", оценив ее в определенную сумму денег. Ошибка неверной оценки в данном случае скорее Ваша.
    Сложно говорить, не видя договора и ТЗ, но вообще в таких ситуациях есть три пути:
    1. Доделать проект себе в убыток, доведя до сведения заказчика причину срыва сроков. К слову, хороший заказчик может и предложить пересмотреть условия.
    2. Обговорить с заказчиком, что в сумму входили определенные работы, сейчас по факту выяснилось что работ больше, поэтому предложить заказчику выбрать, что из работ выкинуть из проекта.
    3. В продолжение п.2 предложить пересмотреть условия (доплатить), чтобы сделать все необходимое.

    С точки зрения заказчика ситуация в любом случае получается некрасивая, потому что проект не сделан, сроки сорваны, а исполнитель еще и требует еще денег, угрожая кинуть проект в состоянии, в котором проще заново работы начать, чем разобраться.
    Ответ написан
    Комментировать
  • Как поступить с заказчиком?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Я думаю - ситуация нередкая. Заказчик - как типичный бизнес может всего тоже не знать. Он может не знать деталей которые сам получает чуть позже. Так наш мир устроен. Scrum/Agile и никакого ватерфола.

    Если проанализировать историю то было 2 события.

    Первое
    Я с проектом ознакомился в общем, глянул макеты, оценил сервисную часть в общих чертах с слов заказчика


    Второе
    По итогу сервисная часть оказалась жутко сложной и объемной


    Вот что случилось между 1 и 2 событием? Почему так получилось что не было понято с самого начала? Я вобщем-то автора понимаю. Я - тоже интраверт и тоже люблю начинать код писать без лишних разговоров. А в этом как раз и ошибка.

    Что делать? Во первых не нужно врать заказчику. Бизнес любит честность в отношениях. Скажи что твой косяк. Недооценил. Недооценка сложности - частая ситуация. Как выйти из этого.

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

    2) Предложить альтернативный план который потребует больше денег и времени. Поищи сам себе консультантов которые помогут.

    Бросать эту разработку я считаю не надо. Это малодушие. Если выгораешь и работаешь по 12 часов - тоже сообщай заказчику. Это тоже честная и понятная позиция.
    Ответ написан
    3 комментария
  • Как поступить с заказчиком?

    SeaInside
    @SeaInside
    15 лет пилю все эти штуки
    Вы ведь сами понимаете, что это ваш косяк, а не заказчика? А чего ему за него платить?

    Мне прям вспомнилась ситуация, когда я пришёл к стоматологу вылечить кариес (пусть будет 2 000 рублей), мне рассверлили весь зуб и заявляют "батюшки, да тут же пульпит!" (12 000 рублей).
    Помогите Маше найти фразу для стоматолога, которая позволила бы сохранить хорошие отношения.

    И вот вы сейчас, по прошествии 2 месяцев, оставите заказчика один на один с незавершённым проектом, в котором никто не разберётся (то есть по сути ни с чем) - то вы поступаете как чудак. Я же вижу по тексту, что понимаете.
    А сюда вы за индульгенцией пришли? :)

    Хотите "сохранить отношения" - доделывайте как есть, в будущем будете мудрее.

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

    Два совета на будущее:
    1) Перезакладывать стоимость и время разработки;
    2) Если понимаешь, что всё идёт не по плану/пропал интерес / слишком сложно / некомфортно / whatever - сказать об этом сразу и отказаться от проекта, так всегда получается честнее

    Опыт всегда стоит дорого, а 53 000 рублей - ну не самая большая цена его получения :)
    Ответ написан
    8 комментариев
  • Как правильно разбить текст по переносам строк?

    seven5674
    @seven5674
    Старый я уже что бы что-то в себе менять
    Как то так
    s = """
    Название (1строка)
    Описание(несколько строк)
    Описание(несколько строк)
    Описание(несколько строк)
    Описание(несколько строк)
    Описание(несколько строк)
    Стоймость (1 строка)
    """
    
    l = s.strip().split("\n")
    
    name = l[0]
    price = l[-1]
    desc = ' '.join(l[1:-1])
    Ответ написан
    1 комментарий
  • Поиск вне зависимости от позиции?

    seven5674
    @seven5674
    Старый я уже что бы что-то в себе менять
    Если пря очень надо на регулярке
    import re
    
    ss = [
        "как дела",
        "дела как",
        "как у тебя дела",
        "как чё",
        "как вообще",
        "как проити",
        "дела хорошо"
    ]
    
    for s in ss:
        if re.findall(r"(как)", s) and re.findall(r"(дела)", s):
            print("{} - Ok".format(s))
        else:
            print("{} - Err".format(s))

    и...
    как дела - Ok
    дела как - Ok
    как у тебя дела - Ok
    как чё - Err
    как вообще - Err
    как проити - Err
    дела хорошо - Err
    Ответ написан
    Комментировать
  • Как правильно стыковать данные по датам из нескольких массивов?

    seven5674
    @seven5674
    Старый я уже что бы что-то в себе менять
    Как это учесть? Если дней в месяцах бывает не всегда 30

    spoiler

    import datetime
    import calendar
    
    summa = 1000
    
    d1 = '2022-02-01'
    d2 = '2022-02-05'
    
    d1 = datetime.datetime.strptime(d1, "%Y-%m-%d")
    d2 = datetime.datetime.strptime(d2, "%Y-%m-%d")
    
    year = d1.year
    month = d1.month
    
    days_diff = d2 - d1
    month_days = calendar.monthrange(year, month)[1]
    summa_news = (month_days - days_diff.days) * summa / month_days
    
    print("Полная сумма {}".format(summa))
    print("Сумма с учетом дней {:.0f}".format(summa_news))

    и...
    Полная сумма 1000
    Сумма с учетом дней 857



    Ведь сравнивать по дате нельзя - дни могут не сойтись, а сойтись должно именно по месяцам.

    ну значит не сравнивай дни а сравнивай только по году и месяцу
    spoiler

    import datetime
    
    d1 = '2022-02-01'
    d2 = '2022-02-05'
    
    d1 = datetime.datetime.strptime(d1, "%Y-%m-%d")
    d2 = datetime.datetime.strptime(d2, "%Y-%m-%d")
    
    # v1 - как строки
    if d1.strftime("%Y-%m") == d2.strftime("%Y-%m"):
        print("Ok")
    else:
        print("No")
    
    # v2 - как обьекты
    if d1.year == d2.year and d1.month == d2.month:
        print("Ok")
    else:
        print("No")


    проверить принадлежность даты периоду можно еще так
    spoiler

    import datetime
    
    d1 = '2022-02-01'
    d2 = '2022-02-05'
    d3 = '2022-05-05'
    
    d1 = datetime.datetime.strptime(d1, "%Y-%m-%d").timestamp()
    d2 = datetime.datetime.strptime(d2, "%Y-%m-%d").timestamp()
    d3 = datetime.datetime.strptime(d3, "%Y-%m-%d").timestamp()
    
    if d1 <= d2 <= d3:
        print("Ok")
    else:
        print("No")


    В чем хранить все эти данные

    ну для тестового примере храни в sqlite - сгенерировать fake data не особо сложная задача
    как и в целом в данной задаче я не вижу больших проблем - тут только работа с датами

    в сухом остатке БД у тебя будет содержать две таблицы
    1. Таблица с платежами - id, payer_id, period, summa
    2. Таблица с информацией по плательщикам - id, payer_id, fio
    По payer_id ты легко можешь их связать. Выборку из БД делаешь по диапазону дат.
    В основном скрипте проверяешь и суммируешь - как вариант промежуточного хранилища используй словарь
    spoiler

    credits = {
        "Иванов" : {
            "credit_1" : {
                '2021-01': 21221,
                .
                .
                .
                '2021-11': 234234
            }
        }
    }



    Значительно упросить задачу можно правильной выборкой данных
    Вот пример (в твоем случае category_sub_name - это заемщик, category_cur_name - это кредит)
    spoiler

    SELECT category_cur_name, category_cur_name, SUM(summa) AS summa FROM (
    	SELECT category_sub_name, category_cur_name, SUM(view_count) AS summa, 
           strftime("%Y-%m", created_at) AS 'period' 
           FROM orders WHERE period >= '2021-01' AND period <= '2021-12'
    	   GROUP BY category_sub_name, category_cur_name, period) 
       GROUP BY category_cur_name ORDER BY summa DESC

    62983194ca346600365564.png

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

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

    Вот пример для расчета сезонности
    6298333332598997344560.png
    Ответ написан
    Комментировать
  • В чем заключаются архитектурные ошибки моего кода?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    class Calculation():
    
      def __init__(self, calculation):
        #init
        self.calculation = calculation

    Вы сделали класс `Вычисления`, чтобы проводить вычисления, пока проводятся вычисления вычислений над вычислениями, которые вычисляются как аргумент вычислений для вычисления состояния вычислений.

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

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

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

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

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

    Вот тут у вас, очевидно, можно написать проще и без лишних повторений, провоцирующих ошибки:
    if i % self.inflation_indexation_period==0 and i != 0:
            if i not in range(0, self.inflation_indexation_period):
              init_indexation_inflation *= self.sales_init.inflation_indexation
            else:
              init_indexation_inflation = 1
            inflation_indexations.append(round(init_indexation_inflation, 5))
          else:
            inflation_indexations.append(round(init_indexation_inflation, 5))

    Лучше так:
    if i % self.inflation_indexation_period==0 and i != 0:
            if i in range(self.inflation_indexation_period):
              init_indexation_inflation = 1
            else:
              init_indexation_inflation *= self.sales_init.inflation_indexation
    
          inflation_indexations.append(round(init_indexation_inflation, 5))

    Функция get_inflation_indexations у вас имеет опасный побочный эффект. Она имеет префикс get_ но модифицирует контекст объекта. Это кэширование? Чем обусловлено такое поведение? Если такое делается "на всякий случай". то это плохая практика неявного внедрения побочного эффекта. Если нарочно, то такое надо документировать и корректно называть и описывать метод в докстринге.

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

    Перестаньте использовать i в качестве переменной для итерирования нетривиальных сущностей, отличных от протсого счетчика. i - это индекс. Используйте человеко-понятное название переменной для этого!

    Используйте декоратор итераторов enumerate. Это сделает код более прозрачным и читабельным, чем код с параллельными счетчиками. Увидев enumerate читатель кода сразу поймёт, что это простой счетчик итерируемых сущностей, что не нужно ожидать скачков этого счетчика и каких-то сложных корреляций.

    А вот здесь вообще всё плохо:
    count = 0
        revenue_list = []
        for i in total_price:
          revenue = i*total_value[count]
          revenue_list.append(revenue)
          count+=1

    count - это "количество", а вы его используете как "индекс" и никак иначе!
    i - это индекс, а вы туда суёте фактически цену!
    У вас total_price и total_value параллельные одноразмерные списки, их нужно состегнуть с помощью zip и пронумеровать с помощью enumerate (если надо, а здесь не надо!).
    Весь этот кусок понятнее, проще, короче и более питоничнее записать в такой форме:
    revenue_list = [price * value for price, value in zip(total_prices, total_values)]


    Итого вся вот эта громоздкая плохо читабельная функция:
    def get_revenue(self):
        '''Получить итоговую выручку'''
        total_price = []
        for i in self.get_inflation_indexations():
          price = self.sales_init.price*i
          total_price.append(price)
    
        total_value = []
        for i in self.get_value_indexations():
          value = self.sales_init.sales_volume*i
          total_value.append(value)
    
        count = 0
        revenue_list = []
        for i in total_price:
          revenue = i*total_value[count]
          revenue_list.append(revenue)
          count+=1
    
        return revenue_list

    Легко и читабельно для питониста заменяется на вот такую:
    def get_revenue(self):
        '''Получить итоговую выручку'''
        indexations = self.get_inflation_indexations()
    
        init_price = self.sales_init.price
        total_prices = [init_price * x for x in indexations]
    
        init_volume = self.sales_init.volume
        total_values = [init_volume * x for x in indexations]
    
        return [price * value for price, value in zip(total_prices, total_values)]


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

    Что это за ерунда:
    def get_interest_expenses(self):
        '''процентные расходы'''
        interest_expenses_list = []
        return interest_expenses_list


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

    Вот такое вообще жесть: self.get_revenue()[count]
    Отчего не сохранить в промежуточную переменную?!

    В общем, всё плохо.
    Если у вас есть функция, вычисляющая какой-то список, то зачем её вычислять каждый раз, когда вам нужен только один очередной элеиент этого списка, а вы перебираете его целиком?!
    И так много раз везде!
    Тут не архитектура хромает, тут основы алгоритмизации плачут. Тренируйтесь на кошках, сударь, больше решайте алгоритмических задачек. Структурируйте, декомпозируйте.

    Удачи.
    Ответ написан
    3 комментария
  • Как создать периодическую модель(таблицу)?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    И в чём проблема? Таблица пользователей, таблица аукционов и таблица ставок. В последней два внешних ключа на пользователей и ацкционы, поле с меткой времени и поле со значением. Элементарно.
    Ответ написан
    Комментировать
  • Как изменить класс определенного объекта из массива?

    один из вариантов — сделать эту разметку внутри самостоятельным компонентом. В который через пропсы передаётся объект статьи. Самостоятельно компонент обрабатывает клик по нему и меняет класс где-то внутри себя.

    другой вариант – признак «кликнутости» статьи (по умолчанию false) тоже держать в объекте artice. И при отрисовке учитывать его значение. По клику с индексом менять в исходных данных признак на true (разметка перерисуется).
    Ответ написан
    Комментировать
  • Как открыть сервер, принимать json и обрабатывать данные?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Изучил возможности пайтона

    Судя по тексту дальше - нет, не изучили.
    отправлять json данные и как их принимать

    Куда отправлять и откуда принимать?
    как сделать так, чтобы сервер не принимал всё подряд?

    Фильтровать.
    Ответ написан
    Комментировать
  • Как правильно настроить static в django?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Ну вы же сами указали УРЛ.
    STATIC_URL = '/static/'
    С другой стороны - пока Вы используете дев-сервер (manage.py runserver), в корневом урле нужно прописать.
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

    P.S.
    После команды "python manage.py collectstatic" файл favicon.svg копируется в:

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

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Никак.
    Стандартные методы Django не знают и не могут знать о том, какими ресурсами оперируют сторонние модули (по крайней мере, без костылей).
    Решение здесь одно - не изобретать велосипед и использовать готовые решения из DRF.
    Если уж так хочется использовать "стандартные" представления - то используйте Function Based Views
    Ответ написан
    1 комментарий
  • Как работают приложения реального времени?

    ketovv
    @ketovv
    Питонист
    Для каждой такой задачи есть своё решение.
    Если у вас лента новостей, то подойдут и переодичные запросы к серверу (главное, чтобы они не были слишком частыми и не вызывали у серверной части приложения затруднения в ответе). Если же у вас чат, то решением станут вебсокеты, которые позволяют серверной части отправлять данные на клиентскую.
    Ответ написан
    Комментировать
  • Как работают приложения реального времени?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Инициатива не на той стороне:
    не клиент должен запрашивать снова и снова «есть чё?»,
    а сервер, когда что-то происходит-появляется, в этом же событии пусть толкает сообщение заинтересованным получателям.

    Один из вариантов решения — упомянутые в других ответах веб-сокеты.

    Приложения реального времени используют «событийную» архитектуру. В обе стороны.
    На сервере: появилась новость – это событие, есть его обработчики (вызвалась функция), где это сообщение рассылают тем, кто сейчас на связи (установлено WebSocket соединение), и подписывался на события такого типа.
    На клиенте: нажали вдруг кнопку лайк! – слушатель-обработчик этого события (функция) отправил сообщение на сервер, мол под таким-то постом юзер Ю поставил лайк.
    Ответ написан
    Комментировать
  • Шум и щелчки в колонках на Ubuntu, как исправить?

    @stasrusnak
    Причина, отключение звуковой карты из-за режима энергосбережения
    На Ubuntu 19.04 решается так.

    sudo su root -c "echo 0 > /sys/module/snd_hda_intel/parameters/power_save"
    Ответ написан
    6 комментариев
  • Как обновлять объекты на странице по их появлению?

    @alekcena
    Нелинейный наставник
    Темы:
    1) Как работает интернет.
    2) GET/POST
    3) AJAX
    4) JS(DOM API или работа с dom)
    Этого вполне достаточно что-бы написать что-то простое.
    А Самое легкое загуглить библиотеки для работы с чатами. Думаю там это уже реализовано и реализовано более правильно чем вы сможете на текущем уровне сделать. Нужно прочитать только как использовать.
    Ответ написан
    Комментировать
  • Как можно упростить код для понимания?

    lxstvayne
    @lxstvayne
    Люблю Python
    Такие сложные вложенные конструкции лучше никогда не использовать, их очень трудно читать. К слову, list comprehensions здесь никакой производительности не добавит. Лучше сделать код более читабельным:
    n = int(input())
    w = []
    count = int(input())
    for _ in range(count):
        w.append(input())
    
    for i in w:
        if 1 <= n <= len(i):
            print(i[n - 1], end='')
    Ответ написан
    1 комментарий
  • Как получить количество студентов всех курсов текущего преподавателя?

    @albert-gaynullin
    Попробуй этот код для подсчета количества студентов преподавателя
    teacher_student_count = User. courses.all().aggregate(Count('students')
    Ответ написан
    2 комментария
  • Как использовать оператор or в функции filter?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    from django.db.models import Q
    q1 = Q(sender=request.user)
    q2 = Q(reciever=request.user)
    D = Dialogue.objects.filter(q1|q2)
    Ответ написан
    Комментировать