средние расходы в день - модель Джанго

В Lisp есть списки, например: (mary выбрасывает мяч).

В некоторых списках описывается вычисление, например: (* pi (+ rr))

а второй - выражение, подходящее для того, чтобы оценщик мог пережевывать.

Но нам нужен способ включения данных в выражения. Итак, несколько десятилетий назад был введен специальный оператор, который позволил бы это сделать, например: (count-существительные (цитата (mary бросила мяч)))

Прошло время, и разработчикам надоело писать (цитата ... ), поэтому они изобрели короткую нотную запись: (count-существительные (mary бросили мяч)).

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

Вы заметите, что если вы введете: (quote bob) в свой запрос lisp, вы вернетесь: 'bob. Принтер хорошо осведомлен о соглашении, которое (quote bob) имеет сокращенную форму. Если вы когда-нибудь решите написать свои собственные макросы читателей, вы можете научить принтер, как играть.

Макросы, как v.s. читайте макросы, позвольте вам представить свои собственные специальные операторы. И это позволяет вам встраивать пользовательские языки, специфичные для домена, в ваш код. Итак - вид макроса позволяет расширять семантику и макросы чтения, чтобы вы могли расширить синтаксис. Макросы влияют на поведение компилятора и оценщика.

0
задан Philipp Chapkovski 5 March 2019 в 17:36
поделиться

2 ответа

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

class Date(Func):
    function = 'DATE'

class MySQLDateDiff(Func):
    function = 'DATEDIFF'

    def __init__(self, *expressions, **extra):
        expressions = [Date(exp) for exp in expressions]
        extra['output_field'] = extra.get('output_field', IntegerField())
        super().__init__(*expressions, **extra)

class PgDateDiff(Func):
    template = "%(expressions)s"
    arg_joiner = ' - '

    def __init__(self, *expressions, **extra):
        expressions = [Date(exp) for exp in expressions]
        extra['output_field'] = extra.get('output_field', IntegerField())
        super().__init__(*expressions, **extra)

agg = {
    avg_spend: ExpressionWrapper(
        Sum('amount') / (PgDateDiff(Max('timestamp'), Min('timestamp')) + Value(1)),
        output_field=DecimalField())
}
avg_spend = Payment.objects.aggregate(**agg)

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

0
ответ дан Brad Martsberger 5 March 2019 в 17:36
поделиться

Вы можете агрегировать минимальную и максимальную временную отметку и сумму суммы:

from django.db.models import Min, Max, Sum

def average_spending_per_day():
    aggregate = Payment.objects.aggregate(Min('timestamp'), Max('timestamp'), Sum('amount'))
    min_datetime = aggregate.get('timestamp__min')
    if min_datetime is not None:
        min_date = min_datetime.date()
        max_date = aggregate.get('timestamp__max').date()
        total_amount = aggregate.get('amount__sum')
        days = (max_date - min_date).days + 1
        return total_amount / days
    return 0

Если есть min_datetime, то в таблице БД есть некоторые данные, а также есть максимальная дата и общее количество. сумма, в противном случае мы возвращаем 0 или что вы хотите.

0
ответ дан Ivan 5 March 2019 в 17:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: