Saya bingung tentang fungsi min dan maks, dalam konteks tertentu.
Dalam satu konteks, saat Anda menggunakan fungsi untuk mengambil dua nilai yang lebih besar atau lebih kecil, tidak ada masalah. Sebagai contoh,
//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);
}
Mudah. Tetapi dalam konteks lain, saya bingung. Jika saya mencoba menetapkan maksimum atau minimum, saya mendapatkannya mundur.
//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
}
Apakah tidak disarankan untuk membuat fungsi saya sendiri sebagai berikut?
//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)
}
Jelas, menggunakan builtin akan lebih cepat tetapi ini sepertinya mikro optimasi yang tidak perlu bagi saya. Apakah ada alasan lain mengapa hal ini tidak disarankan? Bagaimana dengan proyek kelompok?
design
functions
readability
Devsman
sumber
sumber
std::clamp
fungsi atau sesuatu yang serupa.up_to
(untukmin
) danat_least
(untukmax
)? Saya pikir mereka menyampaikan maknanya lebih baik daripadaminimize
, dll. Meskipun mungkin perlu beberapa saat untuk menyadari mengapa mereka berubah-ubah.min
danmax
dan jugaminimize
danmaximize
sama sekali nama yang salah untuk fungsi yang ingin Anda tulis. Defaultmin
danmax
lebih masuk akal. Anda sebenarnya HAMPIR memiliki nama fungsi yang tepat. Operasi ini disebut penjepitan atau pembatasan dan Anda telah menulis dua fungsi pembatasan. Saya sarankancapUpperBound
dancapLowBound
. Saya tidak perlu menjelaskan kepada siapa pun yang melakukan itu, sudah jelas.Jawaban:
Seperti yang telah disebutkan orang lain: jangan membuat fungsi dengan nama yang mirip dengan yang dibangun, perpustakaan standar atau fungsi yang banyak digunakan tetapi mengubah perilakunya. Dimungkinkan untuk membiasakan diri dengan konvensi penamaan bahkan jika itu tidak masuk akal bagi Anda pada pandangan pertama tetapi tidak mungkin untuk alasan tentang fungsi kode Anda setelah Anda memperkenalkan fungsi-fungsi lain yang melakukan hal yang sama tetapi memiliki nama mereka bertukar.
Alih-alih "membebani" nama-nama yang digunakan oleh perpustakaan standar, gunakan nama baru yang menyampaikan dengan tepat apa yang Anda maksud. Dalam kasus Anda, Anda tidak benar-benar tertarik pada "minimum". Sebaliknya, Anda ingin membatasi nilai. Secara matematis, ini adalah operasi yang sama tetapi secara semantik tidak cukup. Jadi mengapa bukan sekadar fungsi
yang melakukan apa yang dibutuhkan dan mengatakannya dari namanya. (Anda juga bisa menerapkan
cap
dalam halmin
seperti yang ditunjukkan pada timster 's jawaban ).Nama fungsi lain yang sering digunakan adalah
clamp
. Dibutuhkan tiga argumen dan "klem" nilai yang disediakan ke dalam interval yang ditentukan oleh dua nilai lainnya.Jika Anda menggunakan nama fungsi yang dikenal secara umum, setiap orang baru yang bergabung dengan tim Anda (termasuk masa depan Anda kembali ke kode setelah beberapa saat) akan dengan cepat memahami apa yang sedang terjadi alih-alih mengutuk Anda karena telah membingungkan mereka dengan melanggar mereka harapan tentang nama fungsi yang mereka pikir tahu.
sumber
clamp
digunakan secara luas dalam semua jenis pemrosesan sinyal dan operasi serupa (pemrosesan gambar, dll), jadi itulah yang akan saya lakukan juga. Meskipun saya tidak akan mengatakan itu membutuhkan batas atas dan bawah: Saya sudah sering melihatnya hanya untuk satu arah juga.clamp
juga. Dan jika itu ditulis dengan benar, Anda bisa menggunakan batas infinity / infinity negatif ketika Anda hanya ingin itu terikat pada satu arah. Misalnya, untuk memastikan bahwa angka tidak lebih besar dari 255 (tetapi tidak ada batas bawah), Anda akan menggunakanclamp(myNumber, -Infinity, 255)
.Jika Anda membuat fungsi seperti itu di mana
minimize(4, 10)
mengembalikan 10 , maka saya akan mengatakan bahwa tidak disarankan karena sesama programmer Anda dapat mencekik Anda.(Oke, mungkin mereka tidak akan benar-benar mencekikmu sampai mati, tapi serius ... Jangan lakukan itu.)
sumber
DO NOT
(dari "JANGAN Spindle, Lipat, atau Mutilate"). Seseorang yang menerapkan sesuatu seperti ini akan menerima kartu.Mengasingkan suatu fungsi baik-baik saja, tetapi jangan mencoba mengubah arti dari istilah yang ada
Tidak apa-apa untuk membuat alias fungsi - perpustakaan umum melakukan itu sepanjang waktu .
Namun, itu ide yang buruk untuk menggunakan istilah dengan cara yang bertentangan dengan penggunaan umum, seperti contoh Anda di mana untuk pikiran Anda max dan min harus dibalik. Ini membingungkan bagi programmer lain, dan Anda akan merugikan diri sendiri dengan melatih diri Anda untuk terus menafsirkan istilah-istilah ini dengan cara yang tidak standar.
Jadi dalam kasus Anda, tinggalkan bahasa "mininum / maksimum" yang Anda anggap membingungkan dan buat kode Anda sendiri, mudah dimengerti.
Refactoring contoh Anda:
Sebagai bonus tambahan, setiap kali Anda melihat kode ini, Anda akan mengingatkan diri sendiri bagaimana min dan max digunakan dalam bahasa pemrograman Anda. Akhirnya, akan masuk akal di kepala Anda.
sumber
min
danmax
yang membingungkan OP. Ini saatmin
digunakan untuk menetapkan batas atas tetap pada beberapa nilai.get_lower_value
akan sama berlawanan dengan intuisi dalam aplikasi ini. Jika saya memilih nama alternatif untuk operasi ini, saya akan menyebutnya supremum , meskipun saya tidak yakin berapa banyak programmer yang akan segera memahaminya.supremum
untuk fungsiget_lower_value
yang didefinisikan di atas hanya untuk memanggilmin
. Itu menyebabkan programmer berikutnya persis masalah yang sama seperti memanggilnyamaximise
. Saya sarankan menyebutnyaapply_upper_bound
, tapi saya tidak yakin itu sempurna. Ini masih aneh karena ia bekerja sama di mana saja di sekitar Anda meletakkan parameter, tetapi namanya menyiratkan bahwa salah satu parameter adalah "nilai" dan yang lainnya adalah "terikat", dan bahwa mereka entah bagaimana berbeda.Saya suka pertanyaan ini. Mari kita jatuhkan itu.
1: Haruskah Anda membungkus satu baris kode?
Ya, saya bisa memikirkan banyak contoh di mana Anda mungkin melakukan ini. Mungkin Anda menerapkan parameter yang diketik atau menyembunyikan implementasi konkret di belakang sebuah antarmuka. Dalam contoh Anda, Anda pada dasarnya menyembunyikan panggilan metode statis.
Selain itu Anda dapat melakukan banyak hal dalam satu baris hari ini.
2: Apakah nama 'Min' dan 'Max' membingungkan
Iya nih! Mereka benar-benar! Seorang guru pengkodean yang bersih akan menamainya dengan nama "FunctionWhichReturnsTheLargestOfItsParameters" atau sesuatu. Untungnya kami memiliki dokumentasi dan (jika Anda beruntung) IntelliSense dan komentar untuk membantu kami agar siapa pun yang bingung dengan namanya dapat membaca tentang apa yang seharusnya mereka lakukan.
3: Jika Anda sendiri mengubah nama mereka menjadi sesuatu yang lain.
Yup, lakukanlah. Misalnya, Anda dapat memiliki:
Itu menambah makna, dan penelepon tidak harus atau ingin tahu bagaimana menghitung nilai.
4: Jika Anda mengganti nama "min" menjadi "memaksimalkan"
Tidak!! kamu gila?! Tapi ya, pertanyaan tersebut menggarisbawahi poin bahwa orang yang berbeda membaca makna yang berbeda menjadi nama fungsi dan objek. Apa yang satu orang temukan jelas dan konvensional yang lain menemukan buram dan membingungkan. Itu sebabnya kami punya komentar. Anda sebaiknya menulis:
Lalu ketika seseorang membaca
mereka tahu Anda membuat kesalahan.
sumber
FunctionWhichReturnsTheLargestOfItsParameters
adalah hal yang baik, saya tidak ingin bagian dari itu.FunctionWhichReturns
di depan setiap fungsi (yang tidak membuang pengecualian atau mengakhiri). Anda bisa berakhir dengangetMinimum
,getLarger
(ataugetLargest
dengan lebih dari 2 input), dengan mengikuti saran nyata di sepanjang baris bahwa (a) fungsi murni dan / atau "pengambil" harus menggunakan kutilget
, (b) kata bahasa Inggris tidak boleh disingkat menjadi nama. Jelas itu terlalu bertele-tele bagi mereka yang memutuskan untuk memanggil fungsi-fungsi tersebutmax
.Tidak ada . Jangan membuat fungsi dengan nama sangat mirip dengan fungsi built-in, tetapi yang sebenarnya sebaliknya . Ini mungkin tampak intuitif bagi Anda, tetapi akan sangat membingungkan bagi pengembang lain, dan bahkan bagi diri Anda sendiri suatu saat nanti ketika Anda memiliki lebih banyak pengalaman.
Arti dari
max
"maksimum", tetapi pemahaman "intuitif" Anda adalah sesuatu seperti "maksimum". Tapi ini hanyalah pemahaman yang salah tentang fungsi, dan mengubah nama darimax
menjadimaximum
tidak mengkomunikasikan interpretasi Anda yang berbeda. Bahkan jika Anda sangat percaya bahwa perancang bahasa membuat kesalahan, jangan lakukan hal seperti ini.Tetapi mengubah nama menjadi
cap(x, limit)
seperti yang disarankan akan baik-baik saja, karena itu jelas mengomunikasikan niat, bahkan jika itu hanya membungkusmin
.sumber
Apa yang mungkin membingungkan Anda adalah menggunakan Capped dalam nama fungsi Anda atau pemahaman Anda tentang apa arti menempatkan topi. Ini adalah pembatas dan tidak memerlukan banyak hal.
Jika Anda ditanya yang terendah, terkecil, atau paling awal, apakah Anda merasa Max adalah fungsi yang tepat?
Biarkan minimal dan maks sendiri. Tulis tes sehingga setidaknya Anda akan memperbaikinya untuk kedua kalinya.
Jika Anda diharuskan untuk menggunakan fungsi-fungsi ini begitu banyak dalam proyek Anda, Anda akan menemukan semacam petunjuk untuk membantu Anda mengklarifikasi mana yang akan digunakan. Seperti <atau>, bagian mulut yang lebar menghadapi nilai yang lebih besar.
sumber
max
fungsinya lebih tepat, tetapi secara logika bijaksanamin
adalah hal yang sebenarnya dia cari.Untuk menjawab pertanyaan Anda: Apakah ada alasan lain mengapa hal ini tidak disarankan? Bagaimana dengan proyek kelompok? Masuk akal jika Anda menginginkan fungsi Anda sendiri, yang tidak masalah. Pastikan mereka berada di kelas pembantu Anda sendiri dan tidak mudah dipanggil untuk orang lain kecuali mereka mengimpornya. (Joes.Utilities.)
Tetapi untuk melihat kembali masalah Anda, pada dasarnya saya malah berpikir:
Anda menjadi bingung karena Anda mencoba menerapkan logika otak Anda ke fungsi-fungsi min / max ini. Alih-alih hanya berbicara dalam bahasa Inggris.
if
yanginput
adalahgreater than or equal to 255
then
return 255
sebaliknyareturn
yanginput
.Yang mana:
Pendapat saya. Anda menggunakan fungsi max \ min untuk alasan yang salah, kecepatan hal-hal ini dapat diabaikan. Lakukan apa yang masuk akal.
sumber
Sementara saya mengerti masalah Anda, saya akan enggan melakukan ini. Akan lebih baik untuk mengebor ke dalam tengkorak Anda apa yang dilakukan min () dan max ().
Kebanyakan programmer tahu apa fungsi min () dan max () - bahkan jika, seperti Anda, mereka kadang-kadang kesulitan dengan intuisi mereka untuk digunakan pada waktu tertentu. Jika saya membaca program dan melihat maks (x, y), saya langsung tahu apa fungsinya. Jika Anda membuat fungsi "alias" Anda sendiri, maka orang lain yang membaca kode Anda tidak akan tahu apa yang dilakukan alias ini. Mereka harus menemukan fungsi Anda. Itu tidak perlu mematahkan aliran membaca dan memaksa pembaca untuk melakukan pemikiran ekstra untuk memahami program Anda.
Jika Anda kesulitan menentukan yang akan digunakan pada titik tertentu, saya katakan, tambahkan komentar yang menjelaskannya. Kemudian jika pembaca yang akan datang juga sama bingungnya, komentar Anda harus jelas. Atau jika Anda salah tetapi komentar menjelaskan apa yang Anda coba lakukan, orang yang mencoba men-debug itu akan memiliki petunjuk.
Setelah Anda alias fungsi karena nama bentrok dengan intuisi Anda ... apakah ini satu-satunya kasus di mana itu masalah? Atau apakah Anda akan alias fungsi lain? Mungkin Anda bingung dengan "membaca" dan merasa lebih mudah untuk menganggapnya sebagai "menerima", Anda mengubah "tambahkan" menjadi "StringTogether", "bulat" menjadi "DropDecimals", dll, dll. Bawa ini ke ekstrem konyol dan program Anda tidak akan bisa dipahami.
Memang, bertahun-tahun yang lalu saya bekerja dengan seorang programmer yang tidak suka semua tanda baca dalam C. Jadi dia menulis banyak makro untuk membuatnya menulis "THEN" bukannya "{" dan "END-IF" bukannya "}" dan lusinan pergantian lainnya. Jadi ketika Anda mencoba membaca programnya, itu bahkan tidak terlihat seperti C lagi, rasanya seperti harus mempelajari bahasa yang sama sekali baru. Saya tidak ingat sekarang apakah "AND" diterjemahkan ke "&" atau "&&" - dan itu intinya. Anda merusak investasi yang dilakukan orang dalam mempelajari bahasa dan perpustakaan.
Yang mengatakan, saya tidak akan mengatakan bahwa fungsi yang tidak melakukan apa-apa selain memanggil fungsi perpustakaan standar tentu buruk. Jika titik fungsi Anda bukan untuk membuat alias, tetapi untuk merangkum perilaku yang kebetulan merupakan fungsi tunggal, ini bisa menjadi baik dan tepat. Maksud saya, jika secara logis dan tak terhindarkan Anda harus melakukan maks pada saat ini dalam program, maka panggil saja max secara langsung. Tetapi jika Anda harus melakukan beberapa perhitungan yang hari ini membutuhkan max, tetapi yang mungkin dimodifikasi di masa depan untuk melakukan sesuatu yang lain, maka fungsi perantara sesuai.
sumber
Tidak apa-apa untuk mengganti nama fungsi bawaan asalkan nama baru membuat kode Anda jauh lebih jelas dan tidak akan ketinggalan dipahami oleh siapa pun. (Jika Anda menggunakan C / C ++ jangan gunakan #define karena membuat sulit untuk melihat apa yang sedang terjadi.) Nama fungsi harus bertindak seperti komentar yang menjelaskan apa yang dilakukan kode panggilan dan mengapa itu dilakukan untuk .
Anda bukan satu-satunya orang yang memiliki masalah ini dengan min dan max, namun saya belum melihat solusi umum yang bagus yang bekerja di semua domain. Saya pikir satu masalah dengan penamaan fungsi-fungsi ini adalah bahwa kedua argumen memiliki makna logis yang berbeda, tetapi disajikan sebagai maknanya sama.
Jika bahasa Anda memungkinkan, Anda bisa mencoba
sumber
Tidak.
Anda tidak menulis pembungkus Anda. Nama-nama pembungkus itu tidak terlalu signifikan.
Apa yang Anda coba lakukan adalah kode kebingungan. Anda menciptakan lapisan tambahan yang melayani 2 tujuan:
Dengan menyembunyikan hal-hal yang membuat Anda tidak nyaman, Anda hanya menyakiti kode Anda sekarang dan diri Anda sendiri di masa depan. Anda tidak dapat tumbuh dengan tinggal di zona nyaman Anda. Yang Anda butuhkan adalah belajar bagaimana
min
danmax
bekerja.sumber
Tidak apa-apa, dan tidak terlalu berlawanan dengan intuisi untuk menggunakan Min, Max untuk mengendalikan lebih dan undershoot. Ini juga dilakukan dengan menggunakan:
Dalam firmware tanggal kembali lebih jauh dari MMX, yang itu sendiri sebelum grafis 3D modern yang bergantung pada extensivley ini.
Mengganti fungsi standar industri bahkan secara lokal akan membuat saya khawatir, nama turunannya mungkin lebih baik. Siswa C ++ mungkin kelebihan beban karena kelasnya yang tidak jelas.
sumber
Tidak apa-apa dalam beberapa kasus, tetapi tidak dalam contoh Anda, karena ada cara yang lebih baik untuk kata itu:
saturate
,clamp
,clip
, dllsumber
Saya lebih suka membuat fungsi generik bernama 'terikat'
atau dengan penggunaan 'min' dan 'max'
sumber
Bagaimana dengan memanggil fungsi Anda:
atmost(x,255)
: kembalikan paling rendah dari x atau 255 paling banyak.atleast(10,x)
: kembalikan yang lebih tinggi dari x atau setidaknya 10.sumber
min(x+y, MAX_VALUE);
akan membawa makna lebih darimyCustomFunction(x, y);
Jadi jawabannya adalah YA, itu tidak disarankan . Ini hanya berfungsi sebagai alias untuk bahasa otak Anda.
sumber