Пропустить к содержанию
Руководство Varlig
Главная страница Varlig

Списки и статистика

Список объединяет несколько значений под одним именем: например, шаги за неделю, экзаменационные оценки или расходы за месяц. После этого можно найти сумму, среднее, меру разброса и выбрать нужные значения.

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

Создание списка

Поместите значения в квадратные скобки, разделенные запятыми:

calc
scores = [72, 85, 91, 64, 88] даёт [72, 85, 91, 64, 88]
scores[0] даёт 72
scores[4] даёт 88
length(scores) даёт 5

Позиция значения в списке — его индекс. Он записывается в квадратных скобках после списка. Индексы начинаются с нуля: scores[0] — первая оценка, а scores[4] — пятая. Индекс последнего элемента всегда равен length(scores) - 1. Отрицательный, дробный или слишком большой индекс вызывает ошибку; отсчёт с конца отрицательными индексами не поддерживается.

Элементами могут быть расчеты, величины с единицами или другие списки:

calc
[2 * 45, 60 + 15] даёт [90, 75]
[1.5 kg, 750 g] даёт [1.5 kg, 750 g]
[[1, 2], [3, 4]][1][0] даёт 3

При вложенных списках первый индекс выбирает внутренний список, а второй выбирает из него значение: [1] выбирает [3, 4], затем [0] выбирает 3.

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

calc
salaries = [£32,000, £41,500, £38,250] даёт [£32,000.00, £41,500.00, £38,250.00]
average(salaries) даёт £37,250.00

Несколько вещей, на которые нужно обратить внимание:

  • Без пробелов запятые разделяют значения: [8200,10400] содержит два элемента. Запись [100,200,300] может означать одно число или три, поэтому Varlig выдаёт ошибку с пояснением обоих вариантов.
  • В результатах отображаются разделители тысяч и пробелы после запятых между элементами. Поэтому [8,200, 10,400] — список из двух значений.
  • Список содержит не более 1024 значений.

Сводная статистика

calc
scores = [72, 85, 91, 64, 88]
sum(scores) даёт 400
average(scores) даёт 80
median(scores) даёт 85
min(scores) даёт 64
max(scores) даёт 91
count(scores) даёт 5

mean и avg - это другие имена для average, total для sum, stdev для stddev и count для length, поэтому привычки электронной таблицы переносятся. product умножает значения вместе. Наиболее распространенное значение, процентиль или квартиль, см. ниже.

С помощью именованного списка вы также можете написать статистику словами:

calc
scores = [72, 85, 91, 64, 88]
average of scores даёт 80
total of scores даёт 400

sum of, mean of, median of, min of, max of и count of работают одинаково. После of напишите имя или сами значения, разделенные запятыми, с круглыми скобками или без них. Для значений в квадратных скобках используйте форму функции, как в average([72, 85, 91]).

Большая часть статистики, включая sum, product, average, median, min, max, count и stddev, также принимает отдельные значения вместо списка:

calc
max(72, 85, 91) даёт 91
sum(1, 2, 3, 4) даёт 10
average of 70, 85, 91 даёт 82
mean of (1,2,3) даёт 2
average(1,200, 1,800) даёт 1,500

Сложение строк выше

Строка, содержащая только sum, total, subtotal, grand total, average, max или min, вычисляет соответствующий показатель по результатам выше. Область начинается после предыдущего итога, разделителя --- или заголовка #. Так каждая часть заметки получает свой результат по мере ввода. Это соответствует параметру Subtotal в контекстном меню строки:

calc
# Groceries
bread = £1.20
milk = £1.45
eggs = £2.30
total даёт £4.95
# Household
bin bags = £3.50
washing up liquid = £1.80
total даёт £5.30

К слову итога можно добавить подпись, присвоить ему имя, перевести результат в другую единицу или дописать комментарий — строка останется естественной частью заметки:

calc
tickets = £64
train = £41.20
Estimated total: total даёт £105.20

est = total хранит число под именем, а total // still to book добавляет рядом заметку. total in kg преобразует его перед отображением, что удобно, когда в разделе используются граммы и килограммы. Статистическое слово рядом с оператором указывает на число, которое бы отображало сама строка, поэтому £5 + subtotal добавляет пять в текущий общий итог.

calc
# Parcels
12 kg даёт 12 kg
4 kg даёт 4 kg
850 g даёт 850 g
total in kg даёт 16.85 kg
max даёт 12 kg

Если вы присвоили собственное значение имени sum или total, строка покажет именно его. Если выше нет подходящих величин, появляется Unsupported: no amounts above to add up, а не пустое место или ноль. Частая причина — заголовок, о котором вы забыли.

Каждая сумма подсчитывается один раз. Когда более поздняя строка в разделе вырабатывает что-то из названной суммы, общая сумма учитывает эту строку, а не обе, поэтому список покупок цен за единицу и количества складывается в то, что вы на самом деле заплатите:

calc
shirt = £18.50
shorts = £9
9 * shirt даёт £166.50
10 * shorts даёт £90.00
fee = £40
vat = fee * 20% даёт £8.00
total даёт £304.50

shirt и shorts засчитываются внутри двух линий, которые их используют, в то время как fee остается в общей сумме, потому что vat занимает только часть.

Это правило прослеживает цепочку имён до конца. Если сумма делится на доли, а затем доли снова складываются, учитываются и строка их сложения, и исходная сумма:

calc
pot = £900
1st = 50% of pot даёт £450.00
2nd = 30% of pot даёт £270.00
3rd = 20% of pot даёт £180.00
1st + 2nd + 3rd даёт £900.00
total даёт £900.00

Складываются только совместимые величины. Если выше есть деньги или величины с единицами, проценты, ставки и простые количества исключаются, как и строки с ошибками. Числа без валюты, вставленные столбцом, учитываются, если записаны с денежной точностью до сотых. Значения с большим числом десятичных знаков, например курс или коэффициент, исключаются. Подсказка итога перечисляет пропущенные строки, например «Пропущена строка 3 (people = 2)» или «Пропущена строка 2 (ошибка)», чтобы было видно, что вошло в сумму.

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

calc
budget = £18,000
remaining = budget - £6,388.25 даёт £11,611.75
- skip hire £250 даёт £250.00
- deep clean £120 даёт £120.00
subtotal даёт £370.00

Для суммирования несоседних строк пометьте их тегом.

Наиболее частые значения

Функция mode возвращает единственное наиболее частое значение, а modes — список всех значений, разделяющих максимальную частоту:

calc
marks = [3, 4, 4, 5, 5, 5, 6]
mode(marks) даёт 5
modes([1, 1, 2, 2, 3]) даёт [1, 2]

Функция mode даёт результат, только если одно значение встречается строго чаще остальных. Если повторов нет или несколько значений имеют одинаковую максимальную частоту, она сообщает об этом, а не выбирает одно:

calc
mode([1, 2, 3]) даёт Unsupported: No value repeats, so this list has no mode; use median or average instead

Процентили и квартили

Функция percentile(list, rank) принимает процентиль от 0 до 100 и возвращает значение в этой позиции с интерполяцией между двумя ближайшими наблюдениями. quartile(list, k) делает то же по четвертям, с k от 0 до 4: quartile(list, 1) равнозначно percentile(list, 25):

calc
scores = [72, 85, 91, 64, 88]
percentile(scores, 50) даёт 85
percentile(scores, 25) даёт 72
quartile(scores, 3) даёт 88
quartile(scores, 4) даёт 91
percentile([1, 2, 3, 4], 25) даёт 1.75
quartile([1, 2, 3, 4], 3) даёт 3.25

50-й процентиль - это медиана, а 0-й и 100-й - quartile(list, 0) и quartile(list, 4) - это наименьшие и самые большие значения, такие же, как min и max. Ранг за пределами своего диапазона - это ошибка, а не ближайшее значение, которое подойдет:

calc
percentile([1, 2, 3, 4], 101) даёт Unsupported: A percentile is between 0 and 100
quartile([1, 2, 3, 4], 5) даёт Unsupported: A quartile is 0, 1, 2, 3 or 4

Разброс: дисперсия и стандартное отклонение

calc
scores = [72, 85, 91, 64, 88]
variance(scores) даёт 132.5
stddev(scores) to 1 dp даёт 11.5

Обе функции вычисляют выборочные показатели: делят на число значений минус один (n - 1). Это обычный вариант, если данные являются выборкой из большей совокупности. Нужно как минимум два значения. Для округления добавьте после любой статистической функции to 1 dp.

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

calc
# Train delays in minutes
delays = [2, 4, 4, 4, 5, 5, 7, 9]
sample_variance(delays) даёт 4.5714285714
population_variance(delays) даёт 4
sample_stddev(delays) даёт 2.1380899353
population_stddev(delays) даёт 2
Вызов На что делится сумма квадратов отклонений Минимум значений
variance, sample_variance n - 1 Два значения
population_variance n Одно значение
stddev, stdev, sample_stddev n - 1 Два значения
population_stddev n Одно значение

Имена sample_variance и sample_stddev — полные варианты variance и stddev, явно указывающие выборочный расчёт. Короткие имена всегда означали и продолжают означать выборочные показатели.

Списки с единицами

Функции sum, average, median, mode, modes, percentile, quartile, min, max, stddev и population_stddev сохраняют единицы и переводят совместимые друг в друга. Все значения приводятся к единице первого элемента; результат возвращается в ней же:

calc
commutes = [24 min, 31 min, 27 min, 22 min]
sum(commutes) даёт 1 hour 44 min
average(commutes) даёт 26 min
median(commutes) даёт 25.5 min
percentile(commutes, 25) даёт 23.5 min
population_stddev(commutes) даёт 3.3911649916 min
sum([1 kg, 500 g]) даёт 1.5 kg
modes([1 kg, 500 g, 1 kg, 500 g]) даёт [0.5 kg, 1 kg]

Дисперсии — исключение: при возведении наблюдений в квадрат единицы здесь не сохраняются. Поэтому функции дисперсии принимают только числа без единиц измерения.

calc
sample_variance([1 kg, 2 kg]) даёт Unsupported: A variance squares its observations, so it takes plain numbers; use stddev for amounts with a unit

Функция sort тоже работает только с числами без единиц. Статистика по несовместимым величинам, например sum([1 kg, 3 m]), вызывает ошибку, а не молча пропускает значения.

Правила точности описаны в разделе Гарантии вычислительного движка.

Пустые списки

Вызов для пустого списка Результат
sum([]) 0
product([]) 1
count([]), length([]) 0
average([]), median([]), min([]), max([]) Ошибка
variance([]), stddev([]) Ошибка

Пустой список часто получается после filter, которому ничего не подошло. Поэтому average отфильтрованного списка может выдать ошибку, даже если исходный список не пуст.

Теги

Тег - это # со словом, соединенным прямо с ним, например, #food. Напишите одну в любом месте на строке, чтобы пометить эту строку. Тег не принимает участия в сумме, поэтому строка все еще показывает свой собственный ответ, и она группирует эту строку с каждой другой строкой, несущей один и тот же тег. total of #food затем добавляет эти строки:

calc
£12.50 lunch #food даёт £12.50
£8 coffee #food даёт £8.00
flights = £420 #trip даёт £420.00
total of #food даёт £20.50

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

Каждая статистика работает на теге. of не является обязательным, тег может быть до или после слова, и ответ принимает метку или собственное имя, как и любая другая строка:

calc
#food £12.50
#food £8
£420 #trip
total of #food даёт £20.50
average of #food даёт £10.25
count of #food даёт 2
min of #food даёт £8.00
max of #food даёт £12.50
#food total даёт £20.50
Food this week: sum of #food даёт £20.50
eaten = avg #food даёт £10.25

sum, total, average, avg, mean, count, min и max все читаются таким образом.

Статистика по тегу используется как обычная сумма в дальнейшем выражении. Так можно вычесть уже внесённый платёж, умножить итог или сравнить два тега:

calc
£20 shop #food даёт £20.00
£30 meal out #food даёт £30.00
total of #food - £10 даёт £40.00
2 * total of #food даёт £100.00
Cooking kit: total of #food даёт £50.00

У строки может быть несколько тегов; каждый учитывает её. Укажите два тега в одном выражении, чтобы выбрать только строки с обоими:

calc
£50 dinner #trip #food даёт £50.00
£30 taxi #trip даёт £30.00
£9 sandwich #food даёт £9.00
total of #trip даёт £80.00
total of #food даёт £59.00
total of #trip #food даёт £50.00

Что входит в сумму по тегу

Выражение с тегом просматривает те же строки, что и обычный total, и следует тем же правилам:

  • Оно охватывает свой раздел до предыдущего итога, разделителя --- или заголовка #.
  • Складываются только совместимые величины. Проценты, ставки, простые количества и строки с ошибками исключаются. Подсказка перечисляет их, например «Пропущена строка 2 (people = 2)».
  • Каждая сумма подсчитывается один раз, поэтому помеченная цена, которую позже умножает помеченная строка, учитывается в этой строке, а не в обеих.

Таким образом, заголовок - это все, что нужно, чтобы сохранить одну неделю #food отдельно от следующей:

calc
# Week 1
£20 lunch #food даёт £20.00
total of #food даёт £20.00
# Week 2
£30 lunch #food даёт £30.00
total of #food даёт £30.00

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

calc
£12.50 lunch #food даёт £12.50
total of #drinks даёт Unsupported: no lines tagged #drinks above
ring the plumber #jobs
total of #jobs даёт Unsupported: no amounts tagged #jobs above

Запись имён тегов

Имя тега может содержать буквы, цифры, _, - и /, поэтому #q1-2026 и #trip/lisbon являются каждым именем. Заглавные буквы не имеют значения:

calc
£20 flight #trip/lisbon даёт £20.00
£35 hotel #Trip/Lisbon даёт £35.00
total of #trip/lisbon даёт £55.00

#, который не соединен со словом, сохраняет свой старый смысл, поэтому ничего из того, что вы уже написали, не меняется:

Что вы пишете Что это такое
# Weekly shop Комментарий: после решётки стоит пробел
5 + 5 # comment То же самое: всё после решётки игнорируется
C#4 in Hz Музыкальный диез: решётка примыкает к обозначению ноты
#1, Invoice #123 Число, а не тег: имя тега не может начинаться с цифры
#ff0000, #fff Цветовой код
varlig.app/docs#tags Веб-адрес с фрагментом

Имя тега должно начинаться с буквы. Последовательность из трёх, четырёх, шести или восьми шестнадцатеричных цифр после решётки читается как цвет: поэтому #fee — цвет, а #fees — тег.

Теги в заметке и теги в блоке

Теги для организации заметок в боковой панели описаны в разделе Теги, ссылки и обратные ссылки. Они не распространяются внутрь блоков вычислений. Запись #food в блоке помечает строку для подсчёта и не появляется в боковой панели. Запись #food в обычном тексте организует заметку, не влияя на вычисления. Для обеих задач добавьте тег в обоих местах. Есть и различие в синтаксисе: тег заметки может содержать пробелы, если закрыть его вторым #, а тег в блоке вычислений заканчивается при первом пробеле.

Справочник функций списков

Вызов Действие
range(start,end) Целые числа от start до end включительно
range(start,end,step) Последовательность с шагом step; шаг может быть отрицательным или дробным, но не нулевым
length(list), count(list) Количество значений
sort(list) По возрастанию; только числа без единиц
reverse(list) Те же значения в обратном порядке; допускаются любые значения
unique(list) Оставить первое вхождение каждого значения
slice(list,start,end) Значения от индекса start до, но не включая индекс end
map(expression,variable,list) Вычислить выражение для каждого значения
filter(condition,variable,list) Оставить значения, для которых условие равно true
calc
range(1, 5) даёт [1, 2, 3, 4, 5]
range(0, 100, 25) даёт [0, 25, 50, 75, 100]
range(10, 0, -2) даёт [10, 8, 6, 4, 2, 0]
scores = [72, 85, 91, 64, 88]
sort(scores) даёт [64, 72, 85, 88, 91]
reverse(sort(scores)) даёт [91, 88, 85, 72, 64]
slice(sort(scores), 0, 3) даёт [64, 72, 85]
unique([4, 2, 4, 6, 2]) даёт [4, 2, 6]

reverse(sort(…)) возвращает наибольшее сначала, а slice(sort(…), 0, 3) выбирает три самых низких.

Границы среза должны удовлетворять 0 <= start <= end <= length. Одинаковые start и end дают пустой список. Сокращение scores[0:2] не поддерживается; пишите slice(scores, 0, 2).

Функция unique сравнивает сохранённые значения точно. Поэтому 1 kg и 1000 g считаются разными, а результаты, различающиеся в десятом знаке после запятой, не объединяются.

Преобразование и фильтрация: map и filter

Функция map вычисляет выражение для каждого элемента списка. filter оставляет элементы, удовлетворяющие условию. В обоих случаях сначала идёт выражение, затем имя текущего элемента, затем список:

calc
scores = [72, 85, 91, 64, 88]
map(s + 5, s, scores) даёт [77, 90, 96, 69, 93]
filter(s >= 80, s, scores) даёт [85, 91, 88]
count(filter(s >= 80, s, scores)) даёт 3
average(filter(s >= 80, s, scores)) даёт 88

Прочитайте filter(s >= 80, s, scores) как "значения s в scores, где s >= 80". Оба работают с единицами и деньгами:

calc
map(p * 1.2, p, [£10, £25, £40]) даёт [£12.00, £30.00, £48.00]
spend = [£42.50, £18.20, £65.00, £23.30]
filter(x > £30, x, spend) даёт [£42.50, £65.00]
sum(filter(x > £30, x, spend)) даёт £107.50

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

calc
x = 10
map(x * 2, x, [1, 2, 3]) даёт [2, 4, 6]
x даёт 10

Условие в filter должно быть сравнением или другим логическим значением true/false. Обычное число не превращается в true, поэтому filter(x, x, [0, 1, 2]) вызывает ошибку. Применение map или filter к пустому списку возвращает пустой список.

Арифметика со списками

Вы можете умножить или разделить каждое значение на одно число, а также добавить или вычесть два списка одинаковой длины по значению:

calc
[30, 36, 22] / 40 * 100 даёт [75, 90, 55]
2 * [3, 1, 4] даёт [6, 2, 8]
-[5, -3] даёт [-5, 3]
mocks = [62, 70, 60]
finals = [72, 78, 69]
finals - mocks даёт [10, 8, 9]
average(finals - mocks) даёт 9
[1 kg, 2 kg] + [500 g, 500 g] даёт [1.5 kg, 2.5 kg]
[72, 85] == [72, 85] даёт true

Первая строка переводит баллы из 40 в проценты. Строка finals - mocks соединяет тестовый балл каждого студента с его финальным баллом.

Некоторые операции не поддерживаются в списках:

  • Прибавление одного числа ко всему списку, как в scores + 5. Вместо этого используйте map(s + 5, s, scores).
  • Сложение списков разной длины. Значения не повторяются автоматически для выравнивания размеров.
  • Умножение двух плоских списков через *. Для суммы попарных произведений используйте dot: dot([2, 3, 1], [4, 5, 10]) даёт 33, например за два кофе по 4, три чая по 5 и один торт за 10. Для списков строк * выполняет матричное умножение; см. Векторы и матрицы.

Списки строк

Список строк работает как маленькая таблица. average и sum работают вниз по столбцам, а map может работать по строкам:

calc
# Each row is one student: [mock, final]
results = [[62, 72], [70, 78], [60, 69]]
average(results) даёт [64, 73]
sum(results) даёт [192, 219]
map(average(r), r, results) даёт [67, 74, 64.5]

median, min, max и stddev не принимают списки строк. Используйте map над строками, как в последней строке, или вытащите столбцы в отдельный список.

Точные правила для всех этих операций находятся в справке по продвинутой математике.

Всё вместе

Вот неделя подсчета шагов с часов, с ежедневной целью:

calc
# Steps, Monday to Sunday
steps = [8200, 10400, 6300, 12000, 9100, 7400, 9600]
goal = 9000
sum(steps) даёт 63,000
average(steps) даёт 9,000
median(steps) даёт 9,100
Days on target: count(filter(s >= goal, s, steps)) даёт 4
Spread: max(steps) - min(steps) даёт 5,700
# Roughly 0.75 m per step
walked = sum(steps) * 0.75 m
walked in km даёт 47.25 km

Среднее точно совпало с целью, но достичь её удалось лишь в четыре дня. Разница между лучшим и худшим днями — 5700 шагов. Измените goal или вставьте данные следующей недели, и все строки обновятся.