Poučevanje Programiranja

Hitra primerjava priljubljenih jezikov za poučevanje računalniškega programiranja

V oddelku CS, kjer trenutno poučujem, sem se pred kratkim vključil v razpravo o tem, kateri programski jezik naj bi uporabljal za poučevanje začetnikov. Java in C sta najpogosteje uporabljeni jeziki v oddelku, za številne predmete pa je to primerno, vendar ne (verjamem) za absolutne začetnike. Verjamem, da je Python veliko boljša izbira za začetnike in da se zavzemam za svoj položaj, sem opravil zelo kratek, zelo neznanstven test, opisan spodaj.

***

Preizkus

Želel sem si ogledati, kaj je bilo v pisanje zelo preprostih programov v (malih) jezikih. Jeziki, ki sem jih izbral, so bili BASIC, C, Java in Python. Uporabil sem C in Java, ker se to pogosto uporablja v oddelku (in v drugih učnih ustanovah. Python sem izbral, ker ga imam rad in mislim, da je odlična izbira za poučevanje, in izbral sem OSNOVNO, ker je bilo prav preveč enostavno….
“Hello World” se je zdelo preveč nepomembno, zato sem se odločil za razmeroma preprosto nalogo branja dveh številk od uporabnika, dodajanje skupaj in tiskanje rezultatov. Moje zanimanje je bilo

  • Kako dolgo je bilo potrebno, da napišete in odpravite napako kodo
  • Koliko stvari mora študent razumeti, da bi napisal to kodo

Čas, ki je bil napisan za pisanje kode, očitno ni mišljen kot reprezentativen glede na čas, ki ga zahteva študent, ampak verjamem, da dajejo približno točno merilo primerjave. Sem razumno usposobljen (1-5 let delovnih izkušenj) v vsakem jeziku, zato mislim, da nisem bil nerazumno pristranski.


BASIC

Na koncu I. sedmega stoletja sem se naučil programirati na ravni I TRS-80 in v sistemu delitve časa, s katerim je imela moška srednja šola priložnosten dostop. Program je nepomemben v dobrih starih BASIC:

10 INPUT A
20 INPUT B
30 C=A+B
40 PRINT C

RUN

Čas za pisanje:

15 sekund. Priznam, da nimam BASIC tolmača priročen in tega ni preizkusil, ampak vem, da deluje. (V redu, sprožil sem TRS-80 emulator in dejansko je tekel – deluje …)

Stvari za razlago:

  • Številke vrstic
  • Spremenljivke
  • INPUT
  • PRINT
  • RUN

Prednosti in slabosti

BASIC je za začetnike zelo enostaven, vendar je to stari, slabo oblikovan jezik, v skoraj vseh modernih funkcijah. Visual BASIC dodaja veliko “dobrem staremu BASIC”, vendar ni primerno (verjamem), da bi poučevala enoprostorni lastniški jezik. In še vedno ni res dober jezik ….


C

#include <stdio.h>

int main(int argc, char*argv[]) 
{
    int a,b,c;

    scanf("%d",&a);
    scanf("%d",&b);

    c = a+b;
    printf("%d\n",c);
}

%> gcc -o add add.c
%> ./add

Čas za pisanje:

približno tri minute, vključno z razhroščevanjem.

Stvari za razlago:

  • #include, funkcije (glavne), vrste vrnitve, argc, argv
  • spremenljivke, vrste (int)
  • scanf (in zelo kmalu so omejitve in kako jih obdržati)
  • printf, formatni nizi
  • kazalci (že!)
  • sestavljanje, zavore in podpičji

Prednosti in slabosti

C so izdelali vrhunski hekerji za lastno uporabo. Namenjen je pisanju operacijskih sistemov, prevajalnikov in drugih sistemskih orodij, pri tem pa je postal skoraj povsem prevladujoč.
Zagotavlja odlično zmogljivost (ob predpostavki, da je dobra izbira algoritma in dobrih znanj C) in omogoča dostop do strojne opreme na nizki ravni, vendar to običajno ni potrebno za začetnike. Uporaba kazalcev C je vir zapletov in zmede za začetnike, vendar so bistvenega pomena v celo precej trivialnih programih (na primer zgoraj, čeprav na trivialen način).

Poleg tega je ravnanje z nizom C šibko v primerjavi z mnogimi drugimi sodobnimi jeziki (zgoraj opisana funkcija scanf je problematična).

C je pomemben in zelo pomemben jezik, vsi programerji pa morajo imeti znatno izpostavljenost. Vendar je grozen jezik za poučevanje začetnikov. Obstaja preveč C, ki ga je treba pojasniti, pri čemer je manj časa za razlago programiranja.


Java

import java.io.*;
public class Addup
{
    static public void main(String args[])  {
        InputStreamReader stdin = new InputStreamReader(System.in);
        BufferedReader console = new BufferedReader(stdin);
        int i1 = 0,i2 = 0;
        String s1,s2;
        try {
            s1 = console.readLine();
            i1 = Integer.parseInt(s1);
            s2 = console.readLine();
            i2 = Integer.parseInt(s2);
        }
        catch(IOException ioex) {
            System.out.println("Input error");
            System.exit(1);
        }
        catch(NumberFormatException nfex) {
            System.out.println("\"" + nfex.getMessage() + "\" is not numeric");
            System.exit(1);
        }
        System.out.println(i1 + " + " + i2 + " = " + (i1+i2));
        System.exit(0);
    }
}
%> javac Addup.java
%> java Addup

Čas za pisanje:

19 minut! Pravzaprav sem porabil približno 15 minut, ni uspel, nato pa iskal Google za primer. Gornja koda se kopira s spletne strani, za katero sem mislila, da se začne z besedami “Mogoče bi se mislilo, da bi program, ki se bere v dveh uporabnikih, vnesel cela števila in natisne njihovo vsoto, preprost kos kode”.

Očitno je, da ta koda ni povsem enakovredna drugim programom, predstavljenim tukaj, saj izvaja pravilno preverjanje napak, vendar pa Java težko ne naredi preverjanja napak. Morate ujeti izjeme, in ko ste jih ujeli, bi lahko tudi nekaj naredili z njimi.

Pravzaprav sem nekoliko nerodno, da sem imel toliko težav s tem. Delal sem na komercialnem paketu Java dve leti, vendar zaradi tega, ker je na osnovi GUI, se redko moram ukvarjati z branjem iz konzole. Real Java programerji bodo verjetno gledali navzdol na me z mešanico sočutja in gnusa. Takšno je življenje.

Stvari za razlago

  • uvoz, razredi, podpičji in podpičji
  • public, static, void, String, main args[]
  • InputStreamReader, BufferedReader, System.in
  • spremenljivke, vrste
  • try, catch, exceptions, readLine, parseInt
  • System.out.println, zbiranje, zagon

Prednosti in slabosti

Java je uporaben jezik za razvoj navzkrižne platforme, je robustna platforma za razvoj OO in ima obsežen in zelo razvit sklop knjižnic razredov. Morda je najpomembneje, da je to najbolj priljubljen jezik in obstaja veliko delovnih mest za Java programerje.
Obsežna knjižnica razreda pa je precej zastrašujoča. Zdi se, da je razred za skoraj vse, in veliko “programiranja v Java” se zdi, da je “iskanje pravega razreda”. Tudi po dveh letih se mi zdi, da v Java ne morem storiti veliko, brez stalnega sklicevanja na dokumentacijo.

Java uveljavlja usmerjanje objektov, preverjanje izjem in strogo tipkanje – to so vse (verjetno) dobre stvari – olajšajo skupini programerjev, da robustno ustvarijo velike sisteme. Toda za majhne probleme (kot so tiste, s katerimi se soočajo uvodni programski razredi) te stvari postanejo nič več kot zapleteno, časovno sesanje breme.

Samo razlog za zaposlitev zadošča, da bi Java moral “naučiti” lanaguage, vendar verjamem, da našim učencem delamo slabe storitve, če je to najboljši jezik, ki ga pokažemo.


Python

import sys

a = sys.stdin.readline()
b = sys.stdin.readline()
c = int(a) + int(b)
print c

%> python add.py

Čas za pisanje:

približno eno minuto, vključno s testiranjem in razhroščevanjem.

Stvari za razlago

  • import
  • variables
  • sys.stdin
  • readline (bere niz)
  • int (pretvori niz v celo število)
  • print

Prednosti in slabosti

Python ima precej dobrih točk:

  • uveljavlja dober programski slog (ujemanje je smiselno)
  • OO je na voljo, vendar ni uveljavljen
  • Izjeme uporabljajo, vendar niso uveljavljene
  • ni igrača ali akademski jezik – v Pythonu je veliko stvarnega dela
  • omogoča koncentracijo na algoritmih in problemih, ne na jezikovnih značilnostih in pomanjkljivostih.
  • je navzkrižno platformo in ima močan niz knjižnic
  • je varen – ima dinamično preverjanje tipa časa in preverjanje meja na nizih
  • ima močne vgrajene tipe podatkov – slovarje, sezname, zaporedja, funkcije, množice (v 2.4)
  • ima močne vgrajene kontrolne strukture – preprosto zanko nad zaporedji, zemljevidom, generatorji, razumevanjem seznama, regularnimi izrazi…
  • zahteva manj linij kode za kateri koli problem, in je bolj berljiva – s tem večjo produktivnost.

Za poučevanje kot prvi jezik pa ima nekaj posebnih prednosti. Kot je razvidno iz zgornjih primerov (ignoriranje BASIC-a), Python zahteva manj časa, manj vrstic kode in manj konceptov, ki jih je treba naučiti, da bi dosegli določen cilj. To omogoča več časa za pomembne stvari. Poleg tega so nekatere pogoste napake študentov v Pythonu popolnoma precej:

  • konec vrstice je konec vrstice (brez pozabljenih podpičij)
  • nobenih deklaracij tipa
  • resnična struktura blokov je vedno očitna (brez manjkajoče zavore)
  • dinamično dodeljevanje pomnilnika in zbiranje smeti

Končno programiranje v Pythonu je zabavno! Zabaven in pogost uspeh je vzbudil zaupanje in zanimanje za študenta, ki je nato bolje usposobljen za nadaljevanje učenja za programiranje.

Toda Python je samo skriptni jezik

Python je pogosto zavrnjen kot “samo skriptni jezik” (Perl in Ruby tudi trpijo zaradi te neumnosti). To je preprosto napačno. To ni “samo skriptni jezik” – je poln izrazit jezik zelo visokega nivoja, ki je idealen za mnoge aplikacije, vključno z enostavnimi nalogami pri skriptiranju.
Dejstvo, da lahko v Pythonu napišete “hitre in umazane” skripte, je prednost, ne pa prikrajšanost, saj je skriptiranje pravzaprav bistveni del profesionalnega programiranja. Če učenci ne poznajo Pythona (ali Perl ali Rubyja ali….), bodo v Javi preveč časa porabili za reševanje težav s skripti.

Vendar je Python počasen

Python je tolmačen jezik, kar pomeni dodaten strošek. Dinamična preverjanja mej, dinamično tipkanje in druge pametne stvari Python še naprej upočasnjujejo. Python je lahko zaporedje velikosti počasneje od enakovredne C kode. Vendar

  • Veliko, veliko aplikacij ni obvezno izračunati. Za uporabo visoko zmogljivega jezika za njih ponazarjamo greh zgodnje optimizacije.
  • Python vmesniki do C – ogromne koristi se lahko izvedejo s kodiranjem kritičnih odsekov v C
  • Časovno shranjeno kodiranje v Pythonu in precej večja preprostost napisane kode, omogoča veliko več časa za eksperimentiranje v učinkovitejših algoritmih – pogosto veliko bolj plodno, kot pa zelo hitro vodenje slabega algoritma.

Zaključek

C in Java so pomembni jeziki – za koncepte, ki jih vsebujejo, za zaposlitvene možnosti in za reševanje težav, ki jih rešujejo. Študentom je treba v teh jezikih temeljito utemeljiti. Vendar pa ne predstavljajo zadostnega arsenala za poklicnega programerja – dober “skriptni jezik” je treba – niti niso dobri jeziki, ki bi učence lahko naučili programiranja. Imajo veliko režijskih in drugih ovir, ki imajo veliko užitka, ter otežijo delo študentov in učiteljev, kot bi moral biti.

Obstajajo ljudje, ki bi trdili, da so ovire del discipline programiranja – učenci se morajo naučiti ujeti njihove izjeme, uporabljati kazalnike, razglasiti vse svoje vrste in tako naprej. Mogoče, morda ne – vendar je čas za to kasneje. Pustimo, da učenci preprosto uživajo v majhnih uspehih, ki jih smo (tudi, “jaz”) imel, ko smo začeli. Patrick Jordan – patrick@ariel.com.au – 2004-12-14…


Postscript (Feb 2006)

Poleg zgornjih komentarjev mi je veliko članov pisalo, ko se je ta članek pojavil na dnevnem Pythonu, da bi poudaril, da je v Pythonu naredil preprostejši način:

a = input()
b = input()
c = a + b
print c

%> python add.py

(predlagani so bili tudi različni oblogi, kot so ‘print input()+input()’ in delal prav tako dobro, vendar bi rekel, da so manj koristne za učne namene). Poleg tega, ker input() sprejema kakršen koli veljaven izraz Python, ta program deluje samo za celo vrsto vhodov – ints, floats, strings (to jih bo združilo – vendar upoštevajte, da morajo biti v ponudbah drugače, bodo razlagane kot variabilna imena) ali izrazi, kot je “3.14**2″. Nadaljnji dokaz, kot bi bilo potrebno, lepote Pythona.

Original: http://www.ariel.com.au/a/teaching-programming.html