W niektórych kontekstach jestem zdezorientowany funkcjami min i max.
W jednym kontekście, gdy używasz funkcji do przyjęcia większej lub mniejszej z dwóch wartości, nie ma problemu. Na przykład,
//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);
}
Łatwo. Ale w innym kontekście jestem zdezorientowany. Jeśli próbuję ustawić maksimum lub minimum, otrzymuję je wstecz.
//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
}
Czy nie jest wskazane, aby tworzyć własne funkcje w następujący sposób?
//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)
}
Oczywiście korzystanie z wbudowanych będzie szybsze, ale wydaje mi się to niepotrzebną mikrooptymalizacją. Czy jest jakiś inny powód, dla którego byłoby to niewskazane? A co z projektem grupowym?
design
functions
readability
Devsman
źródło
źródło
std::clamp
funkcji lub coś podobnego.up_to
(dlamin
) iat_least
(dlamax
)? Myślę, że przekazują znaczenie lepiej niżminimize
itp., Chociaż może chwilę zastanowić się, dlaczego są przemienni.min
amax
takżeminimize
imaximize
są całkowicie błędnymi nazwami funkcji, które chcesz napisać. Domyślnemin
imax
mają znacznie większy sens. W rzeczywistości PRAWIE masz prawidłowe nazwy funkcji. Ta operacja nazywa się zaciskaniem lub zamykaniem i napisałeś dwie funkcje zamykania. SugerowałbymcapUpperBound
icapLowBound
. Nie muszę nikomu wyjaśniać, co robi, co jest oczywiste.Odpowiedzi:
Jak już wspomnieli inni: nie twórz funkcji o nazwie podobnej do wbudowanej biblioteki standardowej lub ogólnie używanej funkcji, ale zmień jej zachowanie. Można przyzwyczaić się do konwencji nazewnictwa, nawet jeśli na pierwszy rzut oka nie ma to większego sensu, ale nie będzie możliwe uzasadnienie działania kodu po wprowadzeniu innych funkcji, które robią to samo, ale mają ich nazwiska zamieniły się.
Zamiast „przeciążać” nazwy używane przez standardową bibliotekę, używaj nowych nazw, które dokładnie odzwierciedlają to, co masz na myśli. W twoim przypadku tak naprawdę nie interesuje Cię „minimum”. Zamiast tego chcesz ograniczyć wartość. Matematycznie jest to ta sama operacja, ale semantycznie nie do końca. Dlaczego więc nie tylko funkcja
robi to, co jest potrzebne i mówi to po nazwie. (Można również realizować
cap
w warunkachmin
jak pokazano w timster „s odpowiedzi ).Inną często używaną nazwą funkcji jest
clamp
. Pobiera trzy argumenty i „zaciska” podaną wartość w interwale określonym przez pozostałe dwie wartości.Jeśli używasz tak powszechnie znanej nazwy funkcji, każda nowa osoba dołączająca do Twojego zespołu (w tym przyszłość, którą wrócisz do kodu po chwili) szybko zrozumie, co się dzieje, zamiast przeklinać cię za pomylenie ich przez złamanie ich oczekiwania dotyczące nazw funkcji, które według nich znają.
źródło
clamp
jest szeroko stosowany we wszelkiego rodzaju przetwarzaniu sygnałów i podobnych operacjach (przetwarzanie obrazu itp.), więc zdecydowanie to też bym wybrał. Chociaż nie powiedziałbym, że wymaga górnej i dolnej granicy: widziałem to dość często tylko w jednym kierunku.clamp
. A jeśli jest napisany poprawnie, możesz po prostu użyć granicy nieskończoności / ujemnej nieskończoności, gdy chcesz, aby była związana tylko w jedną stronę. Na przykład, aby upewnić się, że liczba nie jest większa niż 255 (ale nie dolna granica), należy użyćclamp(myNumber, -Infinity, 255)
.Jeśli wykonasz taką funkcję, gdzie
minimize(4, 10)
zwraca 10 , to powiedziałbym, że jest to niewskazane, ponieważ inni programiści mogą cię udusić.(Okej, może nie dosłownie cię uduszą na śmierć, ale poważnie ... Nie rób tego.)
źródło
DO NOT
(z „NIE Wrzeciona, Nie pasuj ani nie okaleczaj”). Ktoś, kto zaimplementował coś takiego, otrzymałby kartę.Aliasowanie funkcji jest w porządku, ale nie próbuj zmieniać znaczenia istniejących terminów
Tworzenie aliasu funkcji jest w porządku - wspólne biblioteki robią to cały czas .
Jednak złym pomysłem jest używanie terminów w sposób sprzeczny z powszechnym użyciem, np. W twoim przykładzie, w którym według ciebie maksymalne i minimalne wartości powinny być odwrócone. Jest to mylące dla innych programistów, a wyrządzicie sobie krzywdę, ucząc się interpretowania tych terminów w niestandardowy sposób.
Więc w twoim przypadku porzuć żargon „minimalny / maksymalny”, który uważasz za mylący, i stwórz własny, łatwy do zrozumienia kod.
Refaktoryzacja Twojego przykładu:
Jako dodatkowy bonus za każdym razem, gdy spojrzysz na ten kod, będziesz sobie przypominał, w jaki sposób wartości minimalne i maksymalne są używane w języku programowania. W końcu będzie to miało sens w twojej głowie.
źródło
min
imax
które myli OP. To kiedymin
jest używany do ustawienia stałej górnej granicy na jakąś wartość.get_lower_value
byłoby w tej aplikacji równie sprzeczne z intuicją. Gdybym miał wybrać alternatywną nazwę dla tej operacji, nazwałbym to supremum , chociaż nie jestem pewien, ilu programistów natychmiast to zrozumie.supremum
funkcjiget_lower_value
zdefiniowanej powyżej tylko do wywołaniamin
. Powoduje, że następny programista ma dokładnie ten sam problem co wywołanie gomaximise
. Sugerowałbym to nazwaćapply_upper_bound
, ale nie jestem pewien, czy to idealne. To wciąż dziwne, ponieważ działa tak samo, niezależnie od tego, w jaki sposób umieścisz parametry, ale nazwa sugeruje, że jeden z parametrów jest „wartością”, a drugi jest „związany” i że są one w jakiś sposób różne.Uwielbiam to pytanie. Rozbijmy to jednak.
1: Czy powinieneś zawinąć pojedynczy wiersz kodu?
Tak, mogę wymyślić wiele przykładów, w których możesz to zrobić. Może wymuszasz wpisywanie parametrów lub ukrywasz konkretną implementację za interfejsem. W twoim przykładzie zasadniczo ukrywasz statyczne wywołanie metody.
Dodatkowo w dzisiejszych czasach możesz robić wiele rzeczy w jednym wierszu.
2: Czy nazwy „Min” i „Max” są mylące?
Tak! Oni są całkowicie! Czysty guru kodujący zmieniłby ich nazwy na „FunctionWhichReturnsTheLargestOfItsParameters” lub coś w tym rodzaju. Na szczęście mamy dokumentację i (jeśli masz szczęście) IntelliSense i komentarze, które nam pomogą, aby każdy, kto jest zdezorientowany nazwami, mógł przeczytać o tym, co powinien zrobić.
3: Jeśli sam zmienisz nazwę na coś innego.
Tak, idź po to. Na przykład możesz mieć:
Dodaje sens, a osoba dzwoniąca nie musi lub nie chce wiedzieć, jak obliczyć wartość.
4: Jeśli zmienisz nazwę „min” na „maksymalizuj”
Nie!! oszalałeś?! Ale tak, pytanie podkreśla, że różni ludzie odczytują różne znaczenia nazw funkcji i obiektów. To, co jedna osoba uważa za jasne i konwencjonalne, inne jest niejasne i zagmatwane. Dlatego mamy komentarze. Zamiast tego powinieneś napisać:
Potem, gdy ktoś czyta
wiedzą, że popełniłeś błąd.
źródło
FunctionWhichReturnsTheLargestOfItsParameters
są dobre, nie chcę tego brać w tym udziału.FunctionWhichReturns
na przodzie każdej funkcji (która nie rzuca wyjątku ani nie kończy). Można skończyć zgetMinimum
,getLarger
(lubgetLargest
z więcej niż 2 wejścia), choć, wykonując prawdziwe porady wzdłuż linii, które (a) czyste funkcje i / lub „pozyskiwaniu” należy użyć brodawkęget
, (b) angielskie słowa nie powinna być podana w skrócie nazwy. Oczywiście jest to zbyt szczegółowe dla tych, którzy decydują się na wywołanie takich funkcjimax
.Nie . Nie twórz funkcji o nazwach bardzo podobnych do funkcji wbudowanych, ale faktycznie robi to odwrotnie . Może się to wydawać intuicyjne, ale będzie bardzo mylące dla innych programistów, a nawet dla ciebie w przyszłości, gdy będziesz miał więcej doświadczenia.
Znaczenie
max
to „maksimum”, ale twoje „intuicyjne” rozumienie przypomina „maksimum”. Ale to po prostu złe zrozumienie funkcji, a zmiana nazwy zmax
namaximum
nie przekazuje twojej odmiennej interpretacji. Nawet jeśli mocno wierzysz, że projektanci języków popełnili błąd, nie rób czegoś takiego.Ale zmiana nazwy na tak,
cap(x, limit)
jak sugerowano, byłaby w porządku, ponieważ wyraźnie przekazuje zamiar, nawet jeśli tylko się zawijamin
.źródło
To, co może być mylące, to użycie Capped w nazwie funkcji lub zrozumienie, co oznacza wprowadzenie ograniczenia. Jest to ogranicznik i nie wymaga maksimum czegokolwiek.
Jeśli pytasz o najniższą, najmniejszą lub najwcześniejszą, czy uważasz, że Max jest odpowiednią funkcją?
Pozostaw min i maks w spokoju. Napisz testy, aby przynajmniej raz poprawić.
Jeśli musisz tak często korzystać z tych funkcji w swoim projekcie, znajdziesz jakąś wskazówkę, która pomoże ci wyjaśnić, której z nich użyć. Coś w rodzaju <lub>, szeroka część ust jest skierowana w stronę większej wartości.
źródło
max
funkcja jest bardziej odpowiednia, ale logiczniemin
rzeczą, której tak naprawdę szuka.Aby odpowiedzieć na twoje pytanie: Czy jest jakiś inny powód, dla którego byłoby to niewskazane? A co z projektem grupowym? Ma to sens, że chcesz mieć własne funkcje, co nie stanowi problemu. Upewnij się tylko, że należą do twojej klasy pomocniczej i nie są łatwe do wywołania dla innych, chyba że ją zaimportują. (Joes.Utilities.)
Ale żeby spojrzeć ponownie na twój problem, w zasadzie zamiast tego pomyślałbym:
Czujesz się zagubiony, ponieważ próbujesz zastosować logikę mózgu do tych funkcji min / maks. Zamiast tego po prostu mów po angielsku. jest inaczej .
if
input
greater than or equal to 255
then
return 255
return
input
Który jest:
Moja opinia. Idziesz do funkcji max \ min z niewłaściwych powodów, prędkość tych rzeczy jest znikoma. Rób to, co ma sens.
źródło
Rozumiem twój problem, ale niechętnie to zrobię. Lepiej po prostu wiercić w czaszce, co robią min () i max ().
Większość programistów wie, co robią funkcje min () i max () - nawet jeśli, podobnie jak ty, czasami zmagają się z intuicją, z której korzystać w danym momencie. Jeśli czytam program i widzę max (x, y), od razu wiem, co on robi. Jeśli utworzysz własną funkcję „alias”, to nikt inny czytający Twój kod nie będzie wiedział, co robi ten alias. Muszą znaleźć twoją funkcję. Niepotrzebnie przerywa przepływ czytania i zmusza czytelnika do dodatkowego myślenia, aby zrozumieć Twój program.
Jeśli masz problem z ustaleniem, którego użyć w pewnym momencie, dodam komentarz wyjaśniający to. Następnie, jeśli przyszły czytelnik jest podobnie zdezorientowany, twój komentarz powinien to wyjaśnić. Lub jeśli zrobisz to źle, ale komentarz wyjaśnia, co próbujesz zrobić, osoba próbująca go debugować będzie miała wskazówkę.
Po aliasowaniu funkcji, ponieważ nazwa koliduje z intuicją ... czy to jedyny przypadek, w którym jest to problem? A może wybierasz alias innych funkcji? Być może jesteś zdezorientowany przez „czytaj” i łatwiej ci myśleć o tym jako o „akceptuj”, zmieniasz „dopisz” na „StringTogether”, „zaokrąglasz” do „DropDecimals” itp. Przenieś to do absurdalnej skrajności a wasze programy będą niezrozumiałe.
Rzeczywiście, lata temu pracowałem z programistą, który nie lubił wszystkich znaków interpunkcyjnych w C. Więc napisał kilka makr, aby pozwolić mu napisać „TO” zamiast „{” i „END-IF” zamiast „}” i dziesiątki innych takich zamian. Więc kiedy próbowałeś czytać jego programy, nie wyglądało to już nawet na C, to było jak nauka nowego języka. Nie pamiętam teraz, czy „AND” przetłumaczone na „&” czy „&&” - i o to chodzi. Podważasz inwestycje, które ludzie włożyli w naukę języka i biblioteki.
To powiedziawszy, nie powiedziałbym, że funkcja, która nie robi nic poza wywołaniem standardowej funkcji bibliotecznej, jest koniecznie zła. Jeśli celem twojej funkcji nie jest tworzenie aliasu, ale zamknięcie zachowania, które akurat jest pojedynczą funkcją, może to być dobre i właściwe. Mam na myśli, że jeśli logicznie i nieuchronnie musisz zrobić maksimum w tym punkcie programu, to po prostu wywołaj maksimum bezpośrednio. Ale jeśli musisz wykonać jakieś obliczenia, które dzisiaj wymagają maksimum, ale które mogą zostać zmodyfikowane w przyszłości, aby zrobić coś innego, odpowiednia jest funkcja pośrednia.
źródło
Zmiana nazw wbudowanych funkcji jest w porządku, pod warunkiem, że nowe nazwy znacznie upraszczają kod i nikt go nie zrozumie. (Jeśli używasz C / C ++, nie używaj #define, ponieważ utrudnia to zobaczenie, co się dzieje.) Nazwa funkcji powinna działać jak komentarz wyjaśniający, co robi kod wywołujący i dlaczego .
Nie jesteś jedyną osobą, która miała ten problem z parametrami min i max, jednak wciąż nie widzę dobrego ogólnego rozwiązania, które działa we wszystkich domenach. Myślę, że jednym z problemów związanych z nazywaniem tych funkcji jest to, że dwa argumenty mają różne logiczne znaczenia, ale są przedstawiane w ten sam sposób.
Jeśli Twój język na to pozwala, możesz spróbować
źródło
Nie.
Nie piszesz swoich opakowań. Nazwy tych opakowań nie są bardzo znaczące.
To, co próbujesz zrobić, to miłe zaciemnienie kodu. Wymyślasz dodatkową warstwę, która służy 2 celom:
Ukrywając rzeczy, z którymi nie czujesz się komfortowo, ranisz tylko swój kod teraz i siebie w przyszłości. Nie możesz rosnąć, pozostając w strefie komfortu. Musisz nauczyć się, jak
min
imax
pracować.źródło
Używanie Min, Max do podkręcania i cofania jest w porządku i nie jest sprzeczne z intuicją. Odbywa się to również przy użyciu:
W oprogramowaniu sprzętowym sięga dalej niż MMX, który sam wyprzedza nowoczesną grafikę 3D, która opiera się na tym rozszerzeniu.
Zastąpienie funkcji standardowej branży nawet lokalnie martwi mnie, pochodna nazwa może być lepsza. Być może studenci C ++ mogą przeciążać swoją mało znaną klasę.
źródło
Jest w porządku, w niektórych przypadkach, ale nie w swoim przykładzie, ponieważ istnieje wiele lepszych sposobów wyrazu to:
saturate
,clamp
,clip
, itd.źródło
Wolałbym stworzyć ogólną funkcję o nazwie „ograniczony”
lub przy użyciu „min” i „max”
źródło
Co z wywoływaniem funkcji:
atmost(x,255)
: zwraca niższą z wartości x lub 255 co najwyżej.atleast(10,x)
: zwraca wyższą z x lub co najmniej 10.źródło
min(x+y, MAX_VALUE);
miałoby znacznie więcej znaczenia niżmyCustomFunction(x, y);
Odpowiedź brzmi TAK, jest niewskazana . Służy jedynie jako alias języka twojego mózgu.
źródło