Mükemmel ürün gamını tasarlama


10

Eğer bir dil tasarlayacak olsaydım, "mükemmel" ürün gamını nasıl tasarlayacağımı düşünüyordum. Sizin için bilmediğiniz bir ifadede 1-4 gibi bir değer aralığını temsil eden bir aralık değişmezini bilirsiniz. En çok foreach / foreach döngülerinde kullanılırlar

Göz önünde bulundurulması gereken birkaç konu var gibi görünüyor

  • Kapsayıcı ve özel aralıklar için destek, uç noktalara +1 veya -1'e yapışmak biraz çirkin ve hataya eğilimli görünüyor.

  • Adımlama desteği, böylece örneğin çift veya tek sayılar yapabilirsiniz

  • Okunabilirlik.

  • Belirsizlik, değişmez aralığın neyi tanımladığını tam olarak anlamsız olmalı

  • Varsayılan, muhtemelen kapsayıcıdan münhasır olmalıdır, çünkü çoğu durumda diziler üzerinde döngü yapmak için kullanılan şey budur.

Her neyse, gördüğüm aralık değişmezinin bir örneği, özel (sonda) aralık için 1..3 ve kapsayıcı (sonda) için 1 ... 3 şeklinde olan Ruby'dir. Ayrıca 1..10 adımını (5) da yapabilirsiniz. Dikkatle değerlendirdikten sonra bu yaklaşım hakkında hoşlanmadığım birkaç şey buldum (sınırlı yakut bilgimden)

  1. Sadece kapsayıcı ve münhasır sonu tanımlayabilirsiniz. Çoğu senaryoyu tanımlarken biraz tutarsız görünüyor.

  2. Sadece bir ek ile değişir. bir aralığın kapsayıcı veya özel olup olmadığını görmeyi zorlaştırmak için bir tarif gibi görünüyor. Seni bilmiyorum ama nokta bulanık bir şey olma eğilimindedir :)

  3. Aralıklar için gösterim gibi yöntem eklemek, değişmezlik kavramını biraz tutarsız görünen bir sınıfla karıştırır (aralıklar bir sınıfa derlenmiş olsa bile)

Her neyse, farklı alternatifleri düşündükten sonra. Bununla geldim

  • [5..1] 5,4,3,2,1
  • [1..5 [ 1,2,3,4
  • ] 1..5] 2,3,4,5
  • [ 0..5..20] 0,5,10,15,20

ve benzerleri. Seviyorum çünkü [normalde bir seti belirtir ve bu bir setin aksine sipariş edilmesine rağmen buna benzer.

Biraz yırtıldığım bir şey, özel / kapsayıcı göstergeleri zorunlu veya değil yapmaktır, yani sadece 1..5 yazarsanız, dizilerdeki en yaygın durum olduğu için varsayılan 1,2,3,4 olur. Daha kolay ve daha okunabilir, ancak daha az belirgin ve yazmak zorunda olsaydınız [1..5 [nasıl çalıştıklarını erken öğrenirsiniz.

Ne düşünüyorsun, çoğu üssü kapladım mı, bir şeyleri gözden kaçırdım mı? [] zorunlu mu yaparsınız? Aralık değişmezlerini programlama dilinizde farklı şekilde tasarlar mısınız?

Adaylar

  • köşeli ayraç stili: [0..10 [ , adımla: [0..5..20 [
  • aralık gösterimi: [0..10) , adım: [0..5..20)
  • münhasır ünlem. 0 ..! 10, adım: 0..5 ..! 20
    • farklı adımla. 0 ..! 20, 5
    • ancak bu, varsayılan * 0..10 ' dahil (herşey dahil)
  • wordy: [0'dan! 20'ye 5]

Şimdiye kadar en sevdiğim estetik olarak 0 ..! 10 ve 0..5 ..! 20 olduğunu söylemeliyim , sadece varsayılan 0..10'un kapsayıcı-özel için daha mantıklı olmasını diliyorum


2
1,5,10,15,20Boşluk 4, 5, 5, 5 ?!
Peter Taylor

ayy :) düzeltildi
Homde

Yanıtlar:


14

Neden Matematik'te zaten var olanı icat ettiniz?

Aralık Gösterimi

Bu, zaten var olan 'Belirsizlik' noktanızı kapsamalıdır.

Tek sorunun adımı atlamak olacak. Belki matematikte başka bir şey bu konuda yardımcı olabilir?


3
Merhaba, aslında aralık gösterimi hakkında. Ancak beni kullanmak istemeyen şey, hem [hem de] ile simetrik olmaması ve parantez kullanmanın yanı sıra (bahsettiğiniz gibi) adımlar atmamasıydı. Parantez kullanımı, küme ayracı eşleşmesini karıştırma potansiyeline sahip gibi görünüyor ve bunları ifadelere kaydetmeyi tercih ediyorum. ] Ve [kullanmak bir iso standardıdır ve adımların entegrasyonu ile daha iyi gidiyor gibi görünüyordu, ama bu sadece benim görüşüm.
Homde

7
@MKO: Eşsiz köşeli parantez (gibi [1..5[) kullanma fikriniz, editörleri en az standart aralık gösterimi kadar karıştırır.
David Thornley

2
Hmm, başka bir fikir, kullanmaya ne dersiniz! örneğin: 1 ..! 5 veya 0..5 ..! 20 (kademeli)
Homde

1
@MKO: !İlk veya son öğeyi hariç tutmak için kullanmak iyi olabilir.
Sinirli

8

Haskell serilerini gördün mü? Adımlar için fikirleri (ortada) ile benzerdir ancak sözdizimsel bir farkla belirtilir ( @ luqui'nin cevabından ):

[1,2..10] = [1,2,3,4,5,6,7,8,9,10]
[1,3..10] = [1,3,5,7,9]
[4,3..0]  = [4,3,2,1,0]
[0,5..]   = [0,5,10,15,20,25,30,35...  -- infinite
[1,1..]   = [1,1,1,1,1,1,1,1,1,1,1...  -- infinite

Bu gösterimi çok sezgisel buluyorum: numaralandırmaya başlıyorsunuz ve nerede bitmesi gerektiğini işaretlemek için vücuda atlıyorsunuz.

"Münhasır" davasını kapsamaz, ancak açıkçası, davranış hakkında bir kez daha açık olmayı tercih ederim (hangi sınırın kapsayıcı ve hangisinin özel olduğunu belirtin) ve sözdizimi son derece net olmadığı sürece (ve dil agnostik editörlerini karıştırmaz).


5

Onları sunan dillerde liste kavrayışları hakkında okumalısınız.

Örneğin Python, range()durumlarınızı ifade etmek için çok karmaşık vakalar için işlev ve liste kavrayışı ile oldukça güzel bir şekilde kapsar range().


2

Bence gösterimin anlamsız olmaktan çok uzak. Sezgisel olarak, [0..5..20]bana adım genişliği = 5 olan bir aralık gibi görünmüyor: Bazı köşe durumlarda bile başarısız oluyor: seti (0,2) ifade etmeye ne dersiniz - [0..2..2]ya da ortaya ne koymalıyım?

Python'un dilim gösteriminin sağlam bir yaklaşım olduğunu düşünüyorum: [start:end:step](adım isteğe bağlı olmak).

Özel ve kapsayıcı aralıklar için gerçekten desteğe ihtiyacınız varsa, bu sizin dilinizde sözdizimsel belirsizlikler getirmedikçe standart aralık gösterimini (yani (ve kullanarak [) kullanırdım .


1
"standart" gösterimde ilgili Avrupa okulları öğretmek [], [[, ]]ve ][, hiçbir parantez ... ve bizim standart elbette daha iyidir;)
Matthieu M.

@Matthieu: Aslında burada (Hollanda'da olduğu Avrupa'da), biz de standart gösterimde olduğu öğretildi.
Frits

1

Üçüncü bir artış değeri belirlediğinizde, bunu isteğe bağlı bir değer olduğu ve ortada isteğe bağlı bir 3. argüman eklemekten daha sezgisel göründüğü için, ortadan ziyade bir son eklemekten daha iyi olduğunu düşünüyorum. .

[1..5..20] yerine [1..20] [5] veya [1..20,5] gibi bir şey yapabilirsiniz.


Bu geçerli bir nokta ve belki de bir tat meselesi, bana [1..20] kullanarak "1'den 5'e kadar," 1'den 2'ye, 5'ten 5'e kadar "düşünmenin daha kolay olacağını düşündüm. [5] biraz karmaşık görünüyor ama belki de virgül yaklaşımı uygulanabilir. Bu konuda daha fazla geri bildirim almak isterim
Homde

1
  • [1..5 [1,2,3,4
  • ] 1..5] 2,3,4,5
  • ] 1..5 [2,3,4

Neden sadece [1..4], [2..5], [2..4] kullanmıyorsunuz? Aralıkları Hariç Tutmak fazla fayda sağlamaz. MIN + 1 veya MAX-1 yazmanıza gerek yok, evet, ancak yine de yasaklamıyorlar. Çok fazla varyasyon, imho. Benim tercih ettiğim dil olan scala, (1'den 3'e) ve (1'den 3'e kadar) [= (1'den 2'ye]] 'ye sahip ama başlangıçta beni karıştırdı. Şimdi her zaman 'x to y' kullanıyorum ve bu nedenle, kullanmadığım seçeneğin hariç tutma olduğunu biliyorum, ama elbette kullanmadığım bir Seçenekten yararlanmıyorum.

  • [5..1] 5,4,3,2,1

tabii ki (1'den MAX'a) (x => y = (MAX + 1) - x) ama bu çok kaynatma plakasıdır ve kullanıcı dostu değildir.

  • [0..5..20] 0,5,10,15,20

Tabii ki (0-4) (x => y = x * 5) çok fazla kazan plakası değildir. Tartışmalı.


Aralıkları hariç tutmanın ana yararı olan afaik, eleman sayısının uç noktaların farkı olmasıdır.
Justin L.

@JustinL .: 5-1 cebirimde 4, ancak sınırlar hariç 3 element içeriyor: 2, 3, 4.
kullanıcı bilinmiyor

1

Böyle bir şeye ne dersin:

  • [5..1] 5,4,3,2,1
  • [1..5] [i, e] 1,2,3,4
  • [5..1] [i, e] 5,4,3,2
  • [1..5] [e, i] 2,3,4,5
  • [1..5] [e, e] 2,3,4
  • [0..20] 5'e 0,5,10,15,20

iVe eköşeli parantez ikinci çiftinin başlaması beklenen veya aralık biten kapsayıcı veya özel olup olmadığını gösterir (veya kullanmak olabilir inclve excldaha net olmak istiyorsanız). by 5adım aralığını gösterir. İlk ve son örnek ilk ve son değeri kapsayıcıdır, bu yüzden [i,i]bir varsayılan varsayılan davranış olacağını düşünüyorum, atladım.

Varsayılan değerler [i,i], kapsayıcı / özel belirleyici ve by 1adım belirleyici için olabilir.

Normalde içeren standart notasyonu önerdi olurdu (ve [@Dan McGrath tarafından belirtildiği gibi, ancak kodda bu kafa karıştırıcı görünebilir konusunda hemfikirdir.


Aşağı oyu açıklayan var mı?
FrustratedWithFormsDesigner

Yanlışlıkla yanlış bir şey görmedim . Aşağı oyuna karşı koymak için oy verdim.
Berin Loritsch

1

Ve kazanan

Kendi çözümümü seçtiğim için üzgünüm, tüm yorumları ve geri bildirimleri gerçekten takdir ediyorum ve yanlış bir şey bulursanız lütfen bu çözümü eleştirin

Bu yüzden gitmeye karar verdim:

0..5           = 0,1,2,3,5
0..5..10       = 0,5,10
..3            = 0,1,3
!0..!5         = 1,2,3,4
3..            = 3 to infinity

segmented ranges
-
0..5,..5..20   = 0,1,2,3,4,5,10,15,20
0..3,10..5..20 = 0,1,2,3,10,15,20

Gördüğünüz gibi kapsayıcı her iki duyunun da varsayılanıdır, özellikle adım kullanırken sezgisel olarak en anlamlı olan şey budur. Kullanabilirsiniz ! bir son vermek için.

Dezavantajı, bir diziye karşı çalışırken normalde özel kullanmak istediğinizdir, ancak daha sonra, çoğu zaman muhtemelen bu durumlarda her biri için bir şey kullanmanız gerekir. Gerçekten indekse karşı çalışmanız gerekiyorsa, ayrıştırıcı sonunda hariç tutma işaretini unuttuğunuzda bir uyarı verebilir ve bir uyarı verebilir.

Ben en temiz görünüyordu ve umarım en okunabilir olduğunu çünkü virgül ya da başka bir şey kullanmak yerine adım değişkenin her iki tarafında .. kullanarak gitti.

Ayrıca, farklı bölümlerin farklı adımlara sahip olduğu aralıkları yapabilmek için virgüllerle bazı sözdizimine attım


Adımı belirtmek dışında iyi görünüyor. Bence bu [5 ile 0--10] gibi daha temiz olurdu. Bölümlenmiş aralık [0..5, ..20 x 5], vb. Olabilir. Biri de (diğer formlardan farklı olarak) sıfır adım büyüklüğüne izin verebilecek [adım adım ilk rakamları] belirtebilir.
Supercat

0

'[1..5 [' formunu, parens ve parantezleri karıştırmaktan kaçınmanızın aynı nedenlerinden biri için kullanmam - mevcut editörlerin çoğu brace eşleşmesini karıştırır. Belki parantez içinde '[1 .. | 5]' gibi bir işaretleyici kullanın.

Dikkate alınması gereken diğer bir şey, limitleri elde etmek için yöntemlerin davranışıdır. Örneğin, 'başlangıç' / 'bitiş' ile 'ilk' / 'son' ile 'min' / 'max'. Hem kapsayıcı hem de münhasır sınırlar ve adım büyüklüğüne sahip olanlar için akılcı olmaları gerekir.


0

Ruby'de gösterim ve çalışan bir Range nesnesi vardır. Temelde şöyle görünür:

1..5  # range 1,2,3,4,5

Ruby ile adım boyutu aralığın bir işlevi değil, aralık boyunca yineleme işlevidir. Yukarıda aynı aralığı kullanabilir ve eğer istersek farklı şekilde tekrarlayabiliriz:

(1..5).step(3) { |x| puts x }
(1..5).step(2) { |x| puts x }

İşte düşünmek isteyebileceğiniz şeyler:

  • Kapsayıcı / özel uç noktalar için dil desteği eklemek sorunlu olabilir. Tüm aralıklar kapsayıcıysa (Ruby'nin seçimi), geliştiriciler aralığın uç noktalarını buna göre ayarlayacaktır. Uç noktaların kapsayıcılığını veya münhasırlığını, basit bir ayrıştırıcı dilbilgisi ile hem görsel olarak açık hem de açık olacak şekilde nasıl temsil ediyorsunuz?
  • Aralığı yinelemekten daha fazlası için mi kullanıyorsunuz? Yaygın örnekler arasında aralık karşılaştırmaları, birleştirme, aralık karşılaştırmalarındaki değer sayılabilir. Eğer öyleyse, bu olasılıkları nasıl temsil ediyorsunuz? (Bu örneklerin her biri hakkında fikir edinmek için Range sınıfının bağlantısına bakın.)

BTW, Ruby'nin yaptığı gibi bir anahtar deyimine dahil edilmelerine izin verirseniz aralıklar oldukça iyidir:

switch(myval)
    when 0..33 then puts "Low"
    when 34..66 then puts "Medium"
    when 67..100 then puts "High"
end

Ruby'nin menzil nesnesinin hepsinin sonu olduğunu ve hepsi olduğunu söylemiyorum, ama bahsettiğiniz kavramın çalışan bir uygulaması. Neyi sevdiğinizi, beğenmediğinizi ve farklı bir şekilde yapacağınızı görmek için onunla oynayın.


Soruyu dikkatlice okuyun, OP zaten Ruby aralıklarının farkındadır:Anyways, one example of range literal I've seen is Ruby which is in the form of 1..3 for an exclusive (on the end) range and 1...3 for inclusive (on the end). You can also do 1..10.step(5).
FrustratedWithFormsDesigner

0

Kesinlikle dikkate alacağım bir çözüm, operatöre aşırı yüklemeyi kullanmaktır.

1+[0..3]*5

Mutlaka herkes için hemen şeffaf olmayacaktır, ancak durduklarını ve düşündüklerinde, çoğu programcının anlayacağını umuyorum ve dili düzenli olarak kullanan insanlar sadece bir deyim olarak öğreneceklerdi.

Açıklığa kavuşturmak için, sonuç [1, 6, 11, 16], çarpımı kaldırmak ve daha sonra aralık üzerinde toplama yapmak olacaktır. Python kullanıcıları için belirsiz olabileceğini fark etmemiştim; Aralıkları listeler yerine toplam siparişlerin alt kümeleri olarak düşünüyorum. ve bir seti tekrarlamak mantıklı değil.


2
Çok belirsiz. Python'da olduğu gibi " list expression * 5değeri list expression5 kez tekrarlayın" anlamına da gelebilir .
nikie

Bu çok garip görünüyor ve bunun ne olacağından emin değilim ... 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3? 1,3,6,9,12? 5,10,15? belki başka bir şey? Her iki durumda da, bu gösterimi tamamen mantıksız buluyorum. Belki de bir çeşit garip C işaretçi operasyonu gibi görünüyor ...
FrustratedWithFormsDesigner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.