В современном мире так много больших и сложных чисел, что порой голова идет кругом. Самое время подумать о том, чтобы она не шла кругом у наших клиентов.
Начнем с постановки практической задачи: Необходимо организовать удобный интерфейс для ввода диапазона числовых значений.
На практике это может потребоваться при создании «фильтров» для товарных каталогов: подвергаться фильтрации могут такие характеристики, как «диагональ телевизора», «минимальная температура в морозильной камере холодильника», «частота процессора».
В самом общем случае это могут быть положительные и отрицательные, целые и дробные числа, покрывающие некоторое недискретное пространство значений.
Очевидное и самое простое в реализации решение:
Такой интерфейс обладает рядом недостатков, среди которых выделим три наиболее важных:
пользователь вынужден обращаться к клавиатуре
пользователь может ошибиться при вводе (например, дробных значений)
пользователь не информирован о диапазоне чисел, имеющих смысл в контексте фильтра
Все эти недостатки легко устраняются применением инструмента «слайдер» из состава большого количества современных javascript фреймворков. Мы для примера возьмем один из наиболее популярных: jQuery UI Slider.
Воспользовавшись примером из документации, получаем легкое и удобное решение:
Отсюда и далее все примеры будем приводить на базе этих трех характеристик: целочисленной, целочисленной отрицательной и дробной.
Хорошо. Все три недостатка мы устранили. Но можно лучше. Избавим пользователя от необходимости «прицеливаться» ползунком, оглядываясь на значение числового индикатора. Для этого нанесем шкалу значений:
Ещё лучше. Но что-то в этих числах явно не так — это не те числа, которыми привык пользоваться человек. Это не круглые числа! На их месте так и просится что-то вроде: «500, 800, 1100, 1400, …», «-24, -22, -20, -18, …».
Википедия нам говорит о двух близких, по сути, трактовках термина «Круглые числа»: «10, 100, 1000, …» и «10, 20, 30, …». В общем виде круглое число в десятичной системе счисления имеет вид ±N×10k, где N — десятичная цифра, а k любое натуральное число. Для нашей задачи мы вынуждены будем расширить понятие круглого числа множеством чисел с отрицательными k (0.1, 0.2, …, 0.007, …), т.к. исчислять коэффициент аэродинамического сопротивления целыми числами не представляется возможным.
Итак, для построения «правильной» шкалы нам потребуется научиться вычислять такие минимальное и максимальное значения, а также величину шага, чтобы каждая метка на шкале была круглым числом.
Очевидно, что в этом случае наша шкала станет немного шире или уже, т.к. граничные значения сместятся в круглые позиции. Сужать — недопустимо: мы не можем позволить себе «выкинуть товар» из поиска. Следовательно, левую границу будем округлять до меньшего, правую границу и шаг — до большего круглого числа.
Важно также понимать, что для нашей задачи, при вычислении минимального значения, говорить о ближайшем круглом для, например, 517, — в отрыве от всего диапазона не имеет смысла. На его роль могло бы пойти число 500, будь у нас интервал от 517 до 3000 или, например, 510, будь у нас интервал от 517 до 550.
Верным решением задачи будем считать такой набор значений минимального (MINo), максимального числа (MAXo) и величины шага (STEPo), который удовлетворяет условиям:
MINo ≤ MIN // новый минимум не больше исходного
MAXo ≥ MAX // новый максимум не меньше исходного
STEPo × N = MAXo - MINo
Поиск круглого шага сводится к поиску ближайшего большего или равного круглого числа. Для этого исходный шаг необходимо разложить в экспоненциальную запись:
Затем округлить мантиссу до меньшего целого и увеличить на 1
STEPo = (floor(STEP_MANTISSA) + 1) * STEP_POWER
Минимальное значение получим, округлив исходное значение до ближайшего меньшего числа, кратного STEP_POWER. Максимально значение вычислим из минимального и шага
Левая граница и величина шага будут соответствовать условиям задачи по способу их получения. А вот правая граница нуждается в дополнительной проверке, так как в общем случае она может оказаться меньше исходного максимума.
STEP = (MAX-MIN) / N
VALID = false; // флаг «верное решение найдено»
while not VALID
begin
STEP_EXP = floor( log10(STEP) )
STEP_POWER = 10STEP_EXP
STEP_MANTISSA = STEP / STEP_POWER
STEPo = (floor(STEP_MANTISSA) + 1) * STEP_POWER
STEP = STEPo// для перехода следующему круглому числу на следующей итерации цикла
end
Применяя этот алгоритм, получаем:
Такой интерфейс уже можно назвать user friendly, но в нём возник новый недостаток, не свойственный предыдущим примерам: при некоторых значениях MIN, MAX и количества засечек может возникать ситуация, когда интервалы между несколькими последними засечками выходят за пределы [MIN: MAX].
Примером такой ситуации может служить попытка отобразить диапазон значений [0 : 110] на шкале с десятью интервалами (11 засечек): шаг по 10 не покроет весь диапазон, а шаг по 20 сделает пустыми правые интервалы. Простого решения этой проблемы нет, однако, есть способ существенно снизить вероятность появления таких отрезков за счет расширения понятия круглого числа.
В текущем решении круглыми являются только те числа, мантисса которых входит в множество натуральных чисел от 1 до 9. Т.е. круглыми считаются только числа:
1
2
3
4
5
6
7
8
9
10
20
30
40
50
60
70
80
90
100
200
300
400
500
600
700
800
900
…
…
…
…
…
…
…
…
…
А что, если расширить это множество числами, с мантиссой 1.2, 1.5 и 2.5? В тех самых случаях «пустого» отрезка мы получим более короткие значения (например, округлив 135, вместо 200 — получим 150)
1
1.2
1.5
2
2.5
3
4
5
6
7
8
9
10
12
15
20
25
30
40
50
60
70
80
90
100
120
150
200
250
300
400
500
600
700
800
900
…
…
…
…
…
…
…
…
…
…
…
…
Описывать алгоритм поиска ближайшего круглого по «новым правилам» не буду, полагая, что это не будет сложной задачей. Сразу покажу результат такого апгрейда:
Итог
Мог бы сам подвести итог под всем сказанным выше, но думаю, что своим глазам читатель верит больше, поэтому — сводный пример:
Details
Математика
Помимо привычной десятичной системы счисления, существуют и другие. Им не в меньшей степени свойственно понятие круглого числа. И, хотя это имеет малое практическое значение, всё сказанное действительно и для них. (0xF000 воспринимается проще, чем 0xA48C, да? :-) )
Язык программирования
Если в вашем языке программирования нет функции вычисления десятичного логарифма, но есть натуральный, как в javascript — не беда: на помощь придут свойства логарифмов.
logN(x) = ln(x) / ln(N)
log10(x) = ln(x) / ln(10)
Исходный код
Алгоритмы, описанные в этой статье, вы можете найти реализованными на языке javascript в прилагаемой к статье библиотеке.
Также доступен код, иллюстрирующий применение алгоритмов в связке с jQuery UI Slider: examples.js
Future
Как говорится: совершенству нет предела. Интерфейс выбора диапазона значений всё ещё можно совершенствовать:
В некоторых случаях может быть полезна экспоненциальная шкала. Не теряя наглядности, она позволит детализировать отдельные, значимые, насыщенные участки отрезка и, наоборот, сузить разреженные. Очевидный пример: товарный каталог с эксклюзивными позициями. Цены в таком каталоге будет сосредоточены чуть ниже среднего значения, тогда как верхние отрезки окажутся почти пустыми.
Для некоторых физических величин обратный порядок следования значений. Температура в морозильной камере — должна начинаться с минимального по модулю значения.
Есть над чем поработать!
P.S. Показались наши примеры неудачными? Попробуйте свои значения:
Теперь результаты поиска Google будут появляться на странице выдачи еще до завершения ввода запроса пользователем. Революционное изменение во взаимодействии с поисковыми системами, направленное на экономию времени просмотра результатов.
В последнее время фраза «оценка эффективности рекламы в интернете» приобрела очень большую популярность. Казалось бы, и раньше многие задумывались об этом и делали какие-то общие оценки, но как показывает наша практика за последний год работы, сейчас рекламодатели стали подходить к оценке эффективности гораздо тщательнее. Но мы также сталкиваемся с тем, что мало кто понимает, как это можно сделать. Поэтому мы решили рассказать о том, как провести оценку рекламной кампании с помощью Google Analytics.
Каждый день Яндексу задают миллионы запросов. Это порождает вопросы: «Что же эти люди ищут? И откуда эти люди?». Смотрим трансляцию запросов к Яндексу на карте!
Наши многоуважаемые коллеги создали интересное дополнение для Firefox, добавляющее функциональность обычной поисковой выдаче наиболее популярных поисковых систем Рунета. Инструмент расширения выдачи замечателен тем, что будет полезен не только оптимизаторам, но и обычным пользователям. А некоторым просто откроет глаза на интернет-поиск.
У вас когда-нибудь были сомнения, на какую страницу привести пользователя? Что именно он хочет увидеть в ответ на свой запрос? Не мучайтесь с выбором, задайте несколько ссылок и сделайте своё объявление более эффективным!
Компания AdLabs предлагает свои услуги по созданию и разработке сайтов любой сложности. В процессе изготовления сайта используются новейшие разработки в IT индустрии и привлекаются специалисты различных областей, для того чтобы разработать качественный сайт. К каждому заказу по разработке сайта у нас осуществляется индивидуальный подход, что исключает возможность дублирования сайта или изготовления веб-сайта по шаблону. Дизайн и стиль разрабатываемого сайта выполняется таким образом, чтобы подчеркнуть имидж компании или торговой марки, кроме этого учитываются пожелания со стороны клиента. Для качественного многофункционального сайта, необходима хорошая система управления (CMS). Наши программисты разработали CMS таким образом, что Вам не нужно будет изучать основы PHP и HTML для добавления или редактирования информации на сайте, а богатый функционал позволит с легкостью настроить сайт таким образом, как Вам будет удобно. Но мы не ограничиваемся стандартным набором функций, в случае, если клиент захочет иметь какую-то дополнительную функцию или модуль для сайта – профессиональные программисты добавят ее в CMS. Благодаря гибкой настройке и легкости в эксплуатации системы управления, поддержка созданного веб сайта не вызовет никаких проблем даже у обычного пользователя.
Регулярное отслеживание новостей в области изготовления и разработки сайтов помогают нам идти в ногу со временем и гарантировать клиентам быстрое создание современных, качественных сайтов под заказ. Мы с радостью готовы выслушать любые пожелания и предложения по разработке сайтов.