Я запутался в функциях min и max в определенных контекстах.
В одном контексте, когда вы используете функции для получения большего или меньшего из двух значений, это не проблема. Например,
//how many autographed CD's can I give out?
int howManyAutographs(int CDs, int Cases, int Pens)
{
//if no pens, then I cannot sign any autographs
if (Pens == 0)
return 0;
//I cannot give away a CD without a case or a case without a CD
return min(CDs, Cases);
}
Легко. Но в другом контексте я запутался. Если я пытаюсь установить максимум или минимум, я получаю это задом наперед.
//return the sum, with a maximum of 255
int cappedSumWRONG(int x, int y)
{
return max(x + y, 255); //nope, this is wrong
}
//return the sum, with a maximum of 255
int cappedSumCORRECT(int x, int y)
{
return min(x + y, 255); //much better, but counter-intuitive to my mind
}
Нецелесообразно ли выполнять свои собственные функции следующим образом?
//return x, with a maximum of max
int maximize(int x, int max)
{
return min(x, max);
}
//return x, with a minimum of min
int minimize(int x, int min)
{
return max(x, min)
}
Очевидно, что использование встроенных функций будет быстрее, но для меня это кажется ненужной микрооптимизацией. Есть ли другая причина, по которой это было бы нецелесообразно? Как насчет группового проекта?
design
functions
readability
Devsman
источник
источник
std::clamp
или что-то подобное.up_to
(дляmin
) иat_least
(дляmax
)? Я думаю, что они передают значение лучше, чемminimize
, и т. Д., Хотя может потребоваться мгновение, чтобы понять, почему они коммутативны.min
аmax
также и такжеminimize
иmaximize
совершенно неправильные названия для функций, которые вы хотите написать. По умолчаниюmin
иmax
имеет гораздо больше смысла. Вы фактически ПОЛУЧИЛИ правильные имена функций. Эта операция называется фиксацией или укупоркой, и вы написали две функции укупорки. Я бы предложилcapUpperBound
иcapLowBound
. Мне не нужно никому объяснять, что делает, это очевидно.Ответы:
Как уже упоминали другие: не создавайте функцию с именем, похожим на имя встроенной, стандартной библиотеки или широко используемой функции, но изменяйте ее поведение. Можно привыкнуть к соглашению об именах, даже если оно на первый взгляд не имеет особого смысла, но невозможно будет рассуждать о функционировании вашего кода, как только вы представите те другие функции, которые делают то же самое, но имеют их имена поменялись местами.
Вместо «перегрузки» имен, используемых стандартной библиотекой, используйте новые имена, которые точно передают то, что вы имеете в виду. В вашем случае вы не заинтересованы в «минимуме». Скорее, вы хотите ограничить стоимость. Математически это та же самая операция, но семантически это не совсем так. Так почему бы не просто функция
он делает то, что нужно, и говорит об этом по названию. (Кроме того, можно реализовать
cap
с точки зрения ,min
как показано в timster «s ответ ).Другое часто используемое имя функции
clamp
. Он принимает три аргумента и «зажимает» предоставленное значение в интервале, заданном двумя другими значениями.Если вы используете такое общеизвестное имя функции, любой новый человек, присоединившийся к вашей команде (включая будущее, к которому вы вернетесь через код через некоторое время), быстро поймет, что происходит, вместо того, чтобы проклинать вас за то, что вы запутали их, сломав их ожидания относительно имен функций, которые, как они думали, они знали.
источник
clamp
широко используется во всех видах обработки сигналов и аналогичных операциях (обработка изображений и т. д.), так что это определенно то, с чем я бы тоже столкнулся. Хотя я бы не сказал, что это требует верхних и нижних границ: я видел это довольно часто только для одного направления.clamp
тоже. И если оно написано правильно, вы можете просто использовать границу бесконечности / отрицательной бесконечности, когда хотите, чтобы она была ограничена только одним способом. Например, чтобы убедиться, что число не больше 255 (но не нижней границы), вы должны использоватьclamp(myNumber, -Infinity, 255)
.Если вы сделаете такую функцию, которая
minimize(4, 10)
возвращает 10 , то я бы сказал, что это нежелательно, потому что ваши коллеги-программисты могут вас задушить.(Хорошо, может быть, они буквально не задушат тебя до смерти, но серьезно ... Не делай этого.)
источник
DO NOT
(из "НЕ Шпинделя, Сгиба, или Сломать"). Кто-то, кто реализовал что-то подобное, получил бы карточку.Псевдоним функции - это хорошо, но не пытайтесь изменить значение существующих терминов.
Можно создать псевдоним функции - обычные библиотеки делают это постоянно .
Тем не менее, это плохая идея использовать термины, противоречащие обычному употреблению, как, например, ваш пример, где, по вашему мнению, нужно переключать max и min. Это сбивает с толку других программистов, и вы будете оказывать себе медвежью услугу, обучая себя нестандартному толкованию этих терминов.
Так что в вашем случае откажитесь от выражения «минимальный / максимальный», которое вас смущает, и создайте свой собственный, легкий для понимания код.
Рефакторинг вашего примера:
В качестве дополнительного бонуса, каждый раз, когда вы смотрите на этот код, вы будете напоминать себе, как min и max используются в вашем языке программирования. В конце концов, это обретет смысл в вашей голове.
источник
min
иmax
что сбивает с толку ОП. Это когдаmin
используется, чтобы установить фиксированную верхнюю границу для некоторого значения.get_lower_value
было бы так же нелогично в этом приложении. Если бы я выбрал альтернативное имя для этой операции, я бы назвал его супремумом , хотя я не уверен, сколько программистов сразу это поймут.supremum
для функцииget_lower_value
, определенной выше, для простого вызоваmin
. Это вызывает у следующего программиста ту же проблему, что и при его вызовеmaximise
. Я бы предложил позвонитьapply_upper_bound
, но я не уверен, что это идеально. Это все еще странно, потому что работает одинаково, независимо от того, как вы помещаете параметры, но название подразумевает, что один из параметров является «значением», а другой - «связанным», и что они как-то отличаются.Мне нравится этот вопрос. Давайте разберемся с этим хотя.
1: следует ли обернуть одну строку кода?
Да, я могу привести множество примеров, где вы можете сделать это. Возможно, вы вводите типизированные параметры или скрываете конкретную реализацию за интерфейсом. В вашем примере вы по сути скрываете статический вызов метода.
Кроме того, вы можете сделать много вещей в одну строку в эти дни.
2: Запутывают ли имена «Мин» и «Макс»
Да! Они полностью такие! Чистый гуру кодирования переименовал бы их в «FunctionWhichReturnsTheLargestOfItsParameters» или что-то в этом роде. К счастью, у нас есть документация и (если вам повезет) IntelliSense и комментарии, чтобы помочь нам, чтобы любой, кто смущен именами, мог прочитать о том, что они должны делать.
3: Должны ли вы переименовать их во что-то другое.
Да, пойти на это. Например, вы могли бы иметь:
Это добавляет смысл, и вызывающая сторона не должна или не хочет знать, как рассчитать значение.
4: Если вы переименуете «мин», чтобы «максимизировать»
Нет !! вы с ума сошли?! Но да, этот вопрос подчеркивает тот факт, что разные люди читают разные значения в именах функций и объектов. То, что один человек находит ясным и условным, другой находит непрозрачным и запутанным. Вот почему у нас есть комментарии. Вместо этого вы должны написать:
Тогда, когда кто-то читает
они знают, что вы сделали ошибку.
источник
FunctionWhichReturnsTheLargestOfItsParameters
хорошая вещь, я не хочу участвовать в этом.FunctionWhichReturns
впереди каждой функции (которая не выдает исключение и не завершает работу). Вы могли бы в конечном итоге сgetMinimum
,getLarger
(илиgetLargest
с более чем 2 входами) , хотя, следуя реальные советы вдоль линий , что (а) чистые функции и / или «добытчики» следует использовать бородавкуget
, (б) английские слова не должны быть сокращенными в имена. Понятно, что это слишком многословно для тех, кто решает вызывать такие функцииmax
.Нет . Не создавайте функции с именами, очень похожими на встроенные функции, но на самом деле это не так . Это может показаться вам интуитивно понятным, но будет очень запутанным для других разработчиков, и даже для вас самих в будущем, когда у вас будет больше опыта.
Значение
max
«максимум», но ваше «интуитивное» понимание - это что-то вроде «максимум». Но это просто неправильное понимание функции, и изменение названия сmax
наmaximum
не отражает вашу другую интерпретацию. Даже если вы твердо уверены, что разработчики языка допустили ошибку, не делайте что-то подобное.Но было бы неплохо изменить название, чтобы сказать,
cap(x, limit)
как было предложено, поскольку оно явно передает намерение, даже если оно просто завершаетmin
.источник
Что может сбить вас с толку, так это использовать Capped в названии вашей функции или ваше понимание того, что означает использование cap. Это ограничитель и не требует максимум ничего.
Если вас спрашивают о самом низком, самом маленьком или самом раннем, чувствуете ли вы, что Макс - подходящая функция?
Оставьте мин и макс в покое. Напишите тесты, чтобы, по крайней мере, вы исправили это во второй раз.
Если вам нужно так много использовать эти функции в вашем проекте, вы получите какую-то подсказку, чтобы помочь вам уточнить, какую из них использовать. Вроде как <или>, широкая часть рта обращена к большему значению.
источник
max
функция более подходящая, но логическаяmin
вещь - это то, что он на самом деле ищет.Чтобы ответить на ваш вопрос: есть ли какая-либо другая причина, по которой это было бы нежелательно? Как насчет группового проекта? Это имеет смысл, что вы хотите свои собственные функции, что не проблема. Просто убедитесь, что они находятся в вашем собственном классе помощников и не могут легко вызываться другими, если они не импортируют его. (Joes.Utilities.)
Но, чтобы снова взглянуть на вашу проблему, я бы подумал:
Вы запутались, потому что пытаетесь применить свою мозговую логику к этим минимальным / максимальным функциям. Вместо этого просто говорите по-английски. в противном случае .
if
input
greater than or equal to 255
then
return 255
return
input
Который:
Мое мнение. Вы используете функции max \ min по неправильным причинам, скорость этих вещей незначительна. Делай то, что имеет смысл.
источник
Хотя я понимаю вашу проблему, я бы не хотел этого делать. Было бы лучше просто просверлить в вашем черепе то, что делают min () и max ().
Большинство программистов знают, что делают функции min () и max () - даже если, как и вы, они иногда борются со своей интуицией, которую можно использовать в любой момент времени. Если я читаю программу и вижу max (x, y), я сразу знаю, что она делает. Если вы создадите свою собственную функцию «псевдонима», то любой, кто читает ваш код, не будет знать, что делает этот псевдоним. Они должны найти вашу функцию. Это излишне нарушает поток чтения и заставляет читателя задуматься, чтобы понять вашу программу.
Если у вас возникли проблемы с определением, какой из них использовать в какой-то момент, я бы сказал, добавьте комментарий, объясняющий это. Тогда, если будущий читатель так же запутался, ваш комментарий должен прояснить ситуацию. Или, если вы делаете это неправильно, но комментарий объясняет, что вы пытались сделать, у человека, пытающегося его отладить, будет подсказка.
Как только вы создадите псевдоним функции, потому что имя конфликтует с вашей интуицией ... это единственный случай, когда это проблема? Или вы собираетесь использовать псевдонимы для других функций? Может быть, вас смущает слово «чтение», и вам легче думать о нем как о «принять», вы меняете «добавить» на «StringTogether», «округляет» на «DropDecimals» и т. Д. И т. Д. Примите это до смешного крайности и ваши программы будут непонятны.
Действительно, много лет назад я работал с программистом, которому не нравились все знаки препинания в C. Поэтому он написал несколько макросов, чтобы позволить ему писать «THEN» вместо «{» и «END-IF» вместо «}» и десятки других таких замен. Итак, когда вы пытались читать его программы, это уже не выглядело как C, это было похоже на необходимость выучить совершенно новый язык. Я не помню, переводил ли «И» на «&» или «&&» - и в этом суть. Вы подрываете инвестиции людей в изучение языка и библиотеки.
Тем не менее, я бы не сказал, что функция, которая ничего не делает, но вызывает стандартную библиотечную функцию, обязательно плохая. Если целью вашей функции является не создание псевдонима, а инкапсуляция поведения, которое оказывается единственной функцией, это может быть хорошо и правильно. Я имею в виду, что если логически и неизбежно вам нужно выполнить max в этой точке программы, просто вызовите max напрямую. Но если вам нужно выполнить какое-то вычисление, которое сегодня требует максимума, но которое может быть изменено в будущем, чтобы сделать что-то еще, тогда уместна промежуточная функция.
источник
Можно переименовывать встроенные функции при условии, что новые имена сделают ваш код понятным и понятным для всех. (Если вы используете C / C ++, не используйте #define, так как это затрудняет понимание того, что происходит.) Имя функции должно действовать как комментарий, объясняющий, что делает вызывающий код и почему он делает с ,
Вы не единственный, у кого была эта проблема с min и max, однако я пока не вижу хорошего общего решения, которое работает во всех доменах. Я думаю, что одна проблема с именованием этих функций заключается в том, что два аргумента имеют разные логические значения, но представлены как имеющие одно и то же значение.
Если ваш язык позволяет это, вы можете попробовать
источник
Нет.
Вы не пишите свои обертки. Имена этих фантиков не очень значимы.
То, что вы пытаетесь сделать, - это некая кодировка. Вы изобретаете дополнительный слой, который служит 2 целям:
Скрывая вещи, которые вас не устраивают, вы наносите вред своему коду сейчас и себе в будущем. Вы не можете расти, оставаясь в своей зоне комфорта. Что вам нужно, это научиться
min
иmax
работать.источник
Это нормально, и на самом деле не противоинтуитивно использовать Мин, Макс, чтобы обуздать и недолить. Это также делается с помощью:
В прошивке он восходит к MMX, который сам по себе предшествует современной 3D-графике, которая опирается на этот экстенсивлей.
Меня беспокоит замена стандартной отраслевой функции даже локально, может быть лучше использовать производное имя. Возможно, студенты C ++ могут перегружать свой непонятный класс.
источник
Это хорошо в некоторых случаях, но не в вашем примере, потому что есть гораздо лучшие способы слова это:
saturate
,clamp
,clip
и т.д.источник
Я бы лучше создал универсальную функцию с именем «bounded»
или с использованием 'min' и 'max'
источник
Как насчет вызова ваших функций:
atmost(x,255)
: верните самое низкое из x или 255 самое большее.atleast(10,x)
: вернуть большее из x или хотя бы 10.источник
min(x+y, MAX_VALUE);
будет иметь гораздо больше смысла, чемmyCustomFunction(x, y);
Так что ответ ДА, это не желательно . Он служит только псевдонимом для вашего мозга.
источник