Her bilgisayar bilimi öğrencisine hangi programlama dilleri öğretilmelidir?


13

Her bilgisayar bilimi öğrencisi size göre üniversitede hangi dilleri (veya programlama dillerinin sınıflarını (paradigmalarda olduğu gibi) ve bu sınıfın tavsiye edilen dilini) öğretmelidir? Cevaplarınızı motive edin; neden bu dil? Bundan ne faydası olacak? Hangi kavramları öğretiyor (X dilinden daha iyi)?

Not / açıklama : Bu soru, saf bilgisayar bilimi değil, yazılım mühendisliğine yoğun bir şekilde odaklanan bilgisayar bilimi ile ilgilidir. Odak noktası olan yazılım mühendisliği eğitimi değil, hala bilgisayar bilimleri eğitimi.


13
Psuedo kodu CS için yeterli olmalıdır.
Jé Queue

12
@ Xepoch - katılmıyorum. Sahte kod kullanarak istekli ve tembel değerlendirme anlambilimi, tür imzalarında kovaryans / karşıtlık, kategori teorisi vb. İfade etmek özellikle doğal değildir. Sahte kod, algoritmaları ve veri yapılarını tanımlamak için mükemmeldir, ancak CS'de bundan çok daha fazlası vardır.
Aidan Cully

6
Ayrıca, CS öğrencilerinin büyük çoğunluğu mezun olduktan sonra akademik olmayan bir iş bulmayı umuyor. Sözde kod, rekabetçi bir iş piyasasında çok değerli olmayacaktır. Bir CS derecesinin öncelikle iş eğitimi olması gerektiğini düşünmüyorum, ancak bu yönde bir miktar konaklama yapmak zorunda.
Adam Crossland

2
TÜMÜ . Zaman sınırlıysa, alfabenin harflerine başlayın. A +, B, C, C #, D, E, F #, J, K, Q, R, T ... Aslında kötü bir liste değil aslında.
Jesse Millikan

6
"Hangi Dil?" İn başka bir sürümünü keşfettiğiniz için tebrikler soru. Tüm fikirleri okumak için sabırsızlanıyorum. SICP referansını unutmayın. Oh bekle, işte burada.
Corbin Mart

Yanıtlar:


21

Bir liste vereceğim:

  • Meclisi (nispeten basit bir lehçesi): En az bir anlamak önemlidir az şey temellerinin
  • C: Prosedürel dil, birçok yerde kullanılır. Yeni öğrencilere aynı anda OOD gibi yepyeni konseptlerle yük bindirmez.
  • Java / C # / Eiffel / C ++: Nesneye Yönelik Bir Şey İyi, Bunlardan herhangi biri öğrencilere OOD öğretme amacına ulaşacak ve bu dillerden birini anladıklarında, diğerlerini de öğrenebilmeleri gerekir. iyi diller, Eiffel'i listeledim çünkü tasarım-sözleşme ile de var.
  • LISP ve Prolog: Öğrencilere, "gerçek dünyada" bunlardan hiçbirini kullanmasalar bile, önemsiz olan yeni bir düşünme yöntemi öğretir.
  • SQL ve XML: Verileri, verileri nasıl alacağınızı ve yöneteceğinizi düşünmenin yeni yollarını sunar.

Öğrenciler maruz edilmelidir bütün bunların paradigmaların en azından. Sadece bir ya da iki değil.

Birçok insanın Python'a prosedürel stili, OOP tarzını ve belki de başkalarını kapsamasını önereceğini düşünüyorum, ancak Python ile güvenle önerebilmem için yeterli kişisel deneyimim yok.


Keşke okulumun XML ve SQL üzerinde daha ayrıntılı bir şekilde ele almasını dilerdim, ikisine de giren bir dersimiz vardı ve bu terribaddı.

Lua, Python, Javascript, vb.Gibi modern dinamik diller eklerdim
Javier

4
ah, ayrıca bazı hardcore fonksiyonel, haskell ve erlang gibi çok eğitici
Javier

1
SQL listelemek için +1. En azından ilişkisel cebiri düşünüyorsun.
Jé Queue

1
Ben de yönetilmeyen OO, C ++ ve Java yönetilen ayrı . Malloc, yığın ve yığın hakkında bilgi almadan uni'den beri C ++ kullanmamış olsam da, OO'yu asla iyi anlamayacaksınız.
markmnl

45

Kişisel olarak fonksiyonel dillerin eskiden olduğu gibi öğretilmemeleri üzücü. En azından comp sci öğrencilerinin tüm önemli paradigmalardan bir dile maruz kalmaları gerektiğini düşünüyorum: prosedürel, nesne yönelimli, fonksiyonel ve dinamik.


2
+1 Programlama dilleri sınıfım kolayca aldığım en değerli sınıftı.
HappyCodeMonkey

1
Bir BT öğrencisi olarak kesinlikle katılıyorum. Genç bir web uygulaması geliştiricisi olarak okula giderken gerçek dünyada tam zamanlı çalışma avantajım var, ancak tam teşekküllü bir CS derecesi ile gitmiş olsam bile, farklı bir çok kapsama sahip olmayacağım gibi hissediyorum paradigmalar.
Ken

1
Biraz ilgili: youtube.com/watch?v=Ps8jOj7diA0 Stanford, YouTube'da Programlama Paradigmaları 2008 derslerini tamamladı.
Inaimathi

4
Listeye bildirici ekleyin (Prolog). Ayrıca bazı diller açıkça paraleldir (Occam). Öğrencilere paralelliğin nasıl işe yarayacağını öğretmek (kimse doğru yapamaz)
Martin York

1
@Martin York: Prolog , bir tür bildirim dili olan bir mantık programlama dilidir. (Bunu işlevsel programlama dilleri de genel olarak ifade
edicidir

33

İyi dengelenmiş bir CS öğrencisine 4 programlama dili türünün her birinde bir dil öğretilmesi gerektiğini düşünüyorum:

Fonksiyonel - Lisp / Haskell / PostScript. Haskell ile pek tecrübem yok, ama bu konuda öfkeli olan diğer programcıları duydum. Fonksiyonel programlamanın yapılarını ve neden birçok durumda yararlı olduklarını anlamak, bir programcının diğer dillerdeki algoritmaları düzenlemede daha iyi olmasına yardımcı olacaktır.

Nesneye Yönelik - Seçiminizi yapın. C # / Java / Python / Ruby / yadda yadda yadda. Bu tipin öğretilmesi gerekir, çünkü modern işletmelerin istediği budur.

Emir Kipi - C / Fortran / Pascal. Bunlar bugünlerde daha az yaygındır, ancak yine de pratik / tarihsel bir bakış açısıyla öğrenilmelidir. Kullandıkları yöntemler hala pratikliğe sahiptir, çünkü her dilde hepsi bir talimata dayanır. Ve zorunlu diller, talimatları listeleme ve takip etme konusunda çok iyidir.

Mantıksal - ProLog. Bu dillerden hiçbiri için iyi bir pratik kullanım bulamadım, ancak mantıksal dillerin arkasındaki bazı kavramları daha nesne odaklı dillerde nasıl yazacağımı anlamaya çalışırken kullanışlı buldum. Üniversite yıllarım boyunca mantıklı dillere uzun süre odaklanamadım ve sanırım o zaman daha güçlü bir odaklanma bana iyi gelebilirdi.


6
Bu listeye prototip eklemek isteyebilirsiniz - örneğin, JavaScript.
stusmith

@stusmith - Prototipik söz etmeye değer, ancak gerçekten nesne yönelimli dillerin bir alt kümesidir ve javascript en iyi ihtimalle sınırlı bir örnektir. Belki de programlama dilleri dersinde ödev vermeyi düşünürdüm, ama odak değil.
Joel Etherton

1
Prolog için +1. Pratik kullanımını gördüm ve algoritmaları prototiplemek için düzenli olarak kullanıyorum.
Fred Foo

@larsmans - Bunu kullanımınızı duymak isterim. Birkaç yıldır dokunmadım, bu yüzden iyi pratik uygulamalar üzerinde bulanıkım. Teknik incelemelere veya benzer makalelere bağlantılarınız var mı?
Joel Etherton

Birkaç büyük Avrupa şirketi tarafından endüstriyel olarak kullanılan açık kaynaklı bir Prolog lehçesi olan ECLiPSe'ye ( eclipseclp.org ) göz atın ( ao Fransız demiryolu şirketi SNCF, doğru hatırlarsam; bir referans bulmaya çalışacağım).
Fred Foo

6

Mezun olan her CS mezununun bilmesi gereken 1 numaralı dil, harika bir işe girme potansiyellerini en üst düzeye çıkaran dildir. Bu zamanla değişecek, bireyin harika iş tanımına bağlı olarak değişecek ve coğrafi bölgeye göre değişecek.

Şimdilik, İngilizcenin her CS majörünün bilmesi gereken # 1 dil olduğunu söyleyeceğim (bu elbette bölgeye göre değişir.)


Harika bir iş, CS derecesinin bir yan etkisidir. Bir CS derecesi tam da bunun için, hesaplama teorisi bilgisidir. Tüm bu yıllar boyunca matematik ve CS'de kafamı kırmak yerine mesleki eğitimde daha iyi bir iş bulabilirdim.
Jé Queue

2
İngilizce için +1. Bilgisayar dilleri uygulama detaylarıdır.
Wyatt Barnett

+1. Birisi İngilizce'yi iyi öğrenebiliyorsa, kılavuzları iyi öğrenebilir. İngilizceyi iyi biliyordum. Herhangi bir dili öğrenmekte sorun yaşamadım.
Shiplu Mokaddim

4

Zamanla değiştiğini düşünüyorum, ama ideal olarak - 3 farklı bakış açısıyla 3 dil. Benim günümde prosedürel, OO ve işlevseldi - Pascal, C ++ ve LISP. Özellikle bu üçte çok satılmadım. Ama röportaj yaptığımda şunu ararım:

  • Bellek yönetimine dikkat etmeniz gereken bir dille ilgili bir miktar deneyim (C / C ++ ve diğerleri)
  • API kullanımına ilişkin beklentiler ve mevcut çeşitli soyutlamalarla (C ++ / Java) nesne yönelimli bir dille biraz deneyim
  • Bir "streç" dil - garip, zor ve zorlayıcı bir şey. Birisi LISP, meclis veya başka bir zorlu dil biliyor çünkü işe almayacağım, ama mühendisin ciddi problem çözme ve bolca "bu da ne?" anlar.

Başka bir ticaret olarak - CS programlarının öğrencileri pazarda öne çıkan diller konusunda eğitmeleri gerektiğini düşünüyorum. Herhangi bir zamanda, 2-3 dilin işlerin çoğunluğu için ciddi bir öneme sahip olduğunu düşünüyorum. Bence bir okul öğrencilere borçludur ve bu dilden 3'ünden 2'sini en az birinde eğitim derinliği ile öğrenme fırsatı sunmaktadır.


4

Bir CS öğrencisi için, tartışılan CS kavramlarıyla yakından eşleşen programlama dillerini arayın. Şunu öneririm:

  • Şema, lambda hesabını daha iyi anlamak için
  • Erlang, oyuncu modelini anlamak
  • Yüklem mantığı ve ispat sistemleri için Prolog
  • Haskell, tip / kategori teorisi için ve tembel değerlendirme dilde tam olarak ifade edildiğinden
  • en az bir montaj dili - bu başlık altında saymak isterseniz, Java veya CLR bayt kodları ve LLVM IR gibi bir bayt kodu dili de atarım
  • muhtemelen Verilog veya VHDL gibi bir donanım tanımlama dili
  • Derleyici yapı sınıfı için bizon
  • dinamik tip sistemli bir şey (Ruby akla geliyor) ...

Liste bu şekilde devam edebilir, ancak temel fikir oldukça basittir: Öğrencilere, kavramları öğretmek istediğiniz şekilde en uygun programlama dilini öğretin.


3

yacc

hangi programlama dilini kullanırsanız kullanın, perde arkasında neler olup bittiğine dair bir fikir edinmek için. ölü kod gibi temel kavramları ve (iyi) bir derleyicinin sizin için yapabileceği çeşitli optimizasyon türlerini kavramaya yardımcı olur.


2

Lisp (OOP için CLOS ile) ve Haskell. Bu soru öğrencilerle sınırlı değildir. Yeni süslü programlama dilleri bu ikisinden birçok özellik ödünç aldı (kopyalandı, çalındı ​​mı? ... hayır, fena değil). Kendinizi geleceğe hazırlayabilirsiniz. Fonksiyonel programlama (stil) bugün daha önemlidir ve C # (LINQ) veya C ++ (lambda) gibi zorunlu programlama dillerinde tanıtılmaktadır. Bazı öğrencilerin sadece Java öğrenmesi çok kötü.


1
Her ikisine de katılıyorum, ancak bazı gerekçeler koymak isteyebilirsiniz (bunları tek diliniz olarak bilmenin özellikle yararlı olmayacağını da unutmayın).
Inaimathi

2

Bence dil insanların inandığı kadar önemli değil.

Evet, vb.'nin nasıl programlanacağını bilmeniz gerekir, ancak birçok büyük programcı, gelişirken onlara yardımcı olan gerçek dünya deneyimlerini kendi kendine öğrenir.

Öğrenciler sadece kitap yöntemlerini değil, gerçek dünyada nasıl programlama yapılacağına dair bazı derslerle yapabilirler, bu onları daha "yuvarlak" hale getirir ve benim tercihimde daha iyi geliştiriciler / mezunlar olur.

Üniversiteden ayrılıp çalışmaya başladıktan sonra programlama ve yazılım geliştirme hakkında daha fazla şey öğrendim!


2

GERÇEKTEN ÖNEMLİ Mİ ?

Genellikle bu sorunun ardındaki kaşıntı, "Bana en kazançlı / ilginç / zorlayıcı / kolay işleri sağlayacak olan özgeçmişimi koyabilir miyim?" Her ne kadar sorunun en özgeçmişi olsa da, ilk önce aradıklarını anlamayan İK insanlar tarafından taranıyor. ama çok sığ, kapıları geçtikten sonra malları teslim etmeniz gerekiyor.

Sizi iyi veya kötü bir programcı yapan hangi dilleri bildiğiniz değil, onu nasıl kullanabileceğinizdir. Bunun için temel olarak iki programcı kategorisi vardır:

  1. Özünde bir dil öğrenmeye yoğunlaşanlar. En önemlisi dil ve nasıl kullanılacağıdır. Aşırı uçlarda, her küçük kod parçasını süper optimize etme eğilimindedirler ve genellikle yapabildikleri için genellikle belirsiz özellikler kullanırlar.

  2. Sonra teknikler ve paradigmalar hakkında bilgi edinmek isteyenler var. Kullandıkları dil, zihinsel resimlerini zarif bir şekilde ifade edebildikleri sürece önemli değildir. Aşırı uçlarda bunlar, başkalarının kodlama işini yapmasını umarak UML veya diğer sistemleri kullanma eğilimindedir.

Bence ikisine de ihtiyacınız var. # 1 kısa vadeli beceriler sağlayacaktır ve akıllıca seçildiğinde İK kapıları boyunca sizi kolaylaştıracaktır, ancak # 2 sizinle tüm kariyerinizde kalacaktır ve sizi programcı olarak tanımlayacaktır.

# 2 rehberlik sağlayacak ve elinizdeki soruna çalışan bir çözüme yönelik düşünce treninizi düzenleyecektir, ancak 1 olmadan bu fikir bir fikir olmaya devam edecektir, sonsuza dek buharlı cennetin limbolarında yüzen (veya nereden baktığınıza bağlı olarak cehennem).

# 1, size gerçek çalışma sistemlerine fikir uygulama araçları verecektir, ancak 2 olmadan sistemleriniz kanserli şekilsiz canavarlara yönelecektir.


Evet, önemli. Öğrendiğiniz ilk dil, gelecekteki dillere nasıl bakacağınız konusunda beyninizi şekillendirir.

1

Sorunuzu kısmen kendiniz cevapladığınıza inanıyorum.

Asıl önemli olan, öğrencilere birkaç paradigma ile temas kurma fırsatı vermektir, gerçek diller önemli olmamalıdır.

Tabii ki, öncelikle en fazla iş fırsatı veren paradigmaları öğretmek önemlidir (muhtemelen şu anda OOP). Buna göre, bu paradigma için yaygın olarak kullanılan bir dili öğretmek de daha iyidir, çünkü bu muhtemelen hiç kullanmayacağınız bir şey öğrenmekten daha yararlıdır. Bu yüzden sınavlarıma sahte kod yazmaktan da nefret ettim. Pseudocode, 'sabit' bir sözdizimine sahip olmadığı sürece iyidir. Sadece kavramları bir araya getirebilmelisiniz.

Somut olarak:

OOP: .NET veya Java

Öğrencinin diğer yaklaşımlardan haberdar olmasını sağlamak için en az 1 ek programlama paradigması.

Fonksiyonel: Lisp?


fonksiyonel, hayır, lütfen, LISP değil. yerine: haskell.
mariotomo

1

Montaj dili ve mikrokod. Bir CS öğrencisi, mantıksal durum makineleri ile en son üst düzey fonksiyonel / OOP / vb. Arasındaki soyutlamanın tüm temel katmanlarını anlamalıdır. programlama dili paradigması.

Temel veya Logo veya Gıcırtı (et.al.), eğer küçük çocuklara bilgisayar okuryazarlığı öğretmeyi nasıl anlayabileceklerini anlarlar.

Fortran, Cobol ve Lisp, programlama dillerinin tarihini ve modern uygulamaların düzelttiği asıl sorunların ne olduğunu anlamak istiyorlarsa.


Ve C, böylece çalışabileceğiniz tüm açık kaynak kodunun% 90'ını anlıyorsunuz.
11:12

1

Farklı paradigmalardan 3 veya daha fazla dil seçmek o kadar da zor değil, birçok iyi cevap verildi. Ama sadece bir dil seçmek zorunda olsaydım, Scala'ya giderdim, çünkü hem işlevsel hem de nesne odaklı. Aynı dilde farklı yaklaşımları açıklayabilir ve karşılaştırabilirsiniz.


1

Yığın yönelimli / birleştirici dilleri unutmayın! Gerçek zihin bükücüler olabilirler. Küçük, anlaşılması kolay ilkelleri kullanarak karmaşıklık oluşturmayı vurgularlar. Onları çok temiz hisseden noktasız (veya zımni) kod yazmak için kullanabilirsiniz .

Klasik dil Forth , ama bu günlere gittiğim Faktör . Ayrıca görülmeye değer Joy ve Cat . Birleştirici dil wikisini kaçırmayın . Çekiç dolu bir çantadan daha eğlenceli!


0

İşlevsel bir şey, Haskell veya Lisp benim ilk tercihim olurdu, ama belki Erlang. İşlevsel diller gerçekten nasıl soyutlamalar yapılacağını çok güçlü bir şekilde öğretir.


Ancak öğrenciler tek bir paradigma ile mi sınırlı olmalıdır? Scala gibi fonksiyonel OOP dilleri ne olacak?
Anto

1
Hayır, tabii ki hayır, ben başkalarının bunlara katılacağını sanıyordum!
Zachary K

0

Ana akım olmamasına rağmen, D'nin, özellikle sürüm 2'nin, başka bir yerde kolayca öğrenilemeyen bazı ilginç dersler verdiğini görüyorum. Birbiriyle iyi oynaması ve çok düşük bir seviyede (işaretçiler, manuel bellek yönetimi, satır içi) programlamaya izin vermek için zorunlu / prosedürel, nesne yönelimli ve fonksiyonel programlama almayı düşünebildiğim diğer tüm dillerden daha ciddi bir girişimde bulunur. montaj dili) ve aynı dilde çok yüksek düzeyde (genel ve üretken programlama).

Bu değerlidir çünkü paradigmaları farklı evrenlerde varmış gibi tek başına görmek yerine, ormanı ağaçların arasından görürsünüz. Her paradigmanın güçlü ve zayıf yanlarını programlarınıza harmanlarken ince taneli bir düzeyde görürsünüz. Paradigmaların önemli yönlerinin alt düzey kod açısından kütüphanelerde nasıl uygulanabileceğini göreceksiniz. Standart kütüphane modülü std.algorithm, önemli fonksiyonel programlama ilkelerini uygular, ancak sihir olmadan düz, basit D kodudur. Benzer şekilde, std.rangetembel değerlendirme uygular, ancak yine oldukça basit bir D kodudur. Her paradigmanın ilkellerinde yer alan maliyetleri anlayacaksınız, çünkü D'nin metale yakın özellikleri, kaputun altında gerçekte olup bitenleri nispeten şeffaf hale getiriyor. Hatta C'ye benzeyen düşük seviyeli bir şey yazabilir ve daha sonra, aynı dilde, sihirli tutkal katmanları engellemeden güzel, yüksek seviyeli bir arayüz oluşturabilirsiniz.


0

Pseudocode.

Alandaki insanlar fikirlerini çerçeveye veya sözdizimine özgü jargon olmadan tutarlı, yapılandırılmış bir şekilde açıklayabilmelidir. Algoritmanızı anlamak için köşeli parantezleriniz ve parantezleriniz arasındaki farkı bilmek zorunda olmamalıyım. Anahtarların ne ??anlama geldiğini veya ne olduğunu bilmeme gerek yok grep.

Düz dilde yazın, ancak kod gibi yapılandırın ve biçimlendirin. Daha sonra herkes istediği dilde uygulayabilir.

edit: Bu cevap kısmen bazı programcıların sözde kod yazma yetersizliği tarafından motive edilir.

"Algoritmayı sahte kodda yaz"

"Bu da ne?"

Sahte kodun faydaları, programlama dışı paydaşların anlayabilmesidir. BA'ların ve kullanıcıların kodunuzu prova etmesini istediğinizi önermiyorum, ancak programcı olmayan bir algoritma gerekli algoritmayı anladığında yardımcı olabilir. Psuedocode, açıklama ihtiyacını for (int i = 0; i < j; i++)ve temel olarak ne olduğunu anlamını kaldırır jargon.


Birçok programlama dili, gerçek kod ile sözde kod arasında çok az fark olacak kadar güçlüdür. Gerçek programlama dillerinin hangi sözdizimi öğelerine itiraz ediyorsunuz?
kevin cline

@kevin cline - Bildiğim sözdizimi unsurları konusunda rahatım - itiraz edebileceğim şeyleri bilmiyorum . Tabii ki onları deşifre edebiliyorum, ama asıl nokta sahte kodun bu sorunlara sahip olmaması gerektiğidir (henüz sahte kod gibi görünen bir programlama dili göremiyorum)
Kirk Broadhurst

0

C.

  • Her şeyden önce, sadece çekirdekler için değil, hala yaygın olarak kullanılmaktadır! Şu anda C ile kodlanmış bir iş uygulamasını sürdürüyorum. Böylece, saf ve basit C ile bile, hala bir iş bulabilirsin. Büyük şirketlerde, endüstride, hemen hemen her yerde (ancak web geliştirmede).
  • Unix / Linux ortamında çalışacaksanız, en az C'yi bilmemek, alışverişe gitmek ve etiketlerdeki fiyatları okuyamamak gibidir.
  • İşaretçiler! Herkes işaretçileri anlamalıdır ( çapraz başvuru Joel Spolsky ). Ayrıca, malloc konseptini aldıktan sonra, dikkatsizce bir OOP diline "yeni" yazdığınızda tam olarak ne tür şeyler olduğunu bilirsiniz.
  • Çoğu "popüler dil" sözdizimi C'den türetilir.
  • Evet, her zaman net değil. Evet, öğrenmesi zor. Evet, dizeler yeni başlayanlar için bir kabus. Ancak programlama her zaman net değildir ve öğrenmesi zordur ve C'yi inceledikten sonra C ++ 'yı denediğinizde std :: string'i keşfettiğinizde OOP hakkında neyin harika olduğunu anlayacaksınız.

Tabii ki, sadece eski bir prosedür dili değil, birden fazla dil bilmelidir. Ama tek bir derleyici ile ıssız bir adaya gitmek zorunda olsaydım, eski iyi gcc'imle giderdim. Düşük seviyeli programlamayı biliyorsanız yüksek seviyeli programlamayı anlayabilirsiniz. Bence tam tersi doğru değil.


0

Genel problem çözme becerileri kazanmak için uygulanan programlama dillerinden bazıları ve programlama kavramları Logo ve Karel'dir, C / C ++ / Java / Lisp / PERL / Assembly / herhangi bir programlama paradigması öncesinde öğretilmelidir.

Öğrenciler programlamaya çok pratik bir giriş yaparlar.


-1

Nesnelerle her şey. Sadece iyi öğrendiklerinden emin ol.

Ben her zaman c # için büyük bir java programcı işe olurdu, ama gerçek kod yazmamış birini işe şüpheler çok olurdu

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.