Najważniejsze aspekty w metodyce nauczania programowania

advertisement
Najważniejsze aspekty w metodyce
nauczania programowania, czyli
w jaki sposób uczyć
programowania (w szkole)
Krzysztof Diks, II UW
Podsumowanie wyników z matury
2013
• Poziom podstawowy: Dla zdających
najtrudniejsze okazało się zadanie 4. z zakresu
algorytmiki i programowania.
• Poziom rozszerzony: Trudność maturzystom
sprawiły zadania 6.b i 6.c z zakresu algorytmiki
i programowania.
2
3
2005
4
2005
5
2007
6
Przyczyna
Nie wyartykułowano, co ma być celem
początkowej fazy nauki programowania.
Celami wstępnej fazy nauki programowania
nie powinny być:
•szczegółowe poznanie (składni) wybranego
języka programowania
•kształcenie umiejętności tworzenia (często
technicznych) aplikacji
•szczegółowe poznawanie środowisk
wspierających pracę programisty
7
Przyczyna
Nie zdefiniowano co to jest programowanie
dla początkujących adeptów informatyki.
KD, GJ: Programowanie, to formalny
sposób zapisywania algorytmów, a co za
tym idzie nie należy w procesie nauczania
rozdzielać algorytmiki i programowania.
8
Wady istniejących podręczników do uczenia
elementów programowania (w liceach)
• rozdzielenie nauki programowania od układania algorytmów
• duży nacisk na nauczanie składni i szczegółów
technicznych języka programowania, zamiast na uczenie rozumienia
podstawowych konstrukcji programistycznych (zapisywania algorytmów)
• brak kształcenia umiejętności projektowania poprawnych
algorytmów
• dominujące używanie schematów blokowych (listy kroków)
do zapisywania algorytmów
• nieciekawe, techniczne przykłady
• dominacja odtwórczych zadań
• wprowadzanie „klasycznych” algorytmów bez uzasadniania
dlaczego zaliczamy je do klasyki (ze względu na wagę rozwiązywanego
problemu? ze względu na wagę i ogólność użytych w nich metod?) 9
Rozdzielenie nauki programowania od układania algorytmów
…W rozdziale II (Algorytmika i programowanie - problemy
zaawansowane) poszerzamy wiadomości dotyczące wprowadzania
danych i wyprowadzania wyników, m.in. losowanie danych.
Systematyzujemy wiedzę uczniów dotyczącą typów danych
w języku Turbo Pascal. Uczniowie poznają zasady przetwarzania
rekordów i plików, w tym plików tekstowych. Zapoznają się
z cechami programowania obiektowego na przykładzie
języka Object Pascal. Dowiadują się, na czym polega programowanie
zdarzeniowe - tworzą interfejs użytkownika w systemie Delphi.
Poznają elementy analizy algorytmów. Analizują wybrane algorytmy
sortowania oraz algorytmy wykonujące operacje na liczbach
naturalnych. Poznają reprezentację danych numerycznych
w komputerze oraz wybrane algorytmy numeryczne. …
10
Duży nacisk na nauczanie składni i szczegółów technicznych języka
programowania, zamiast na uczenie rozumienia podstawowych
konstrukcji programistycznych (zapisywania algorytmów)
…Kolejną pętlą w C++ jest pętla while. Pętla ta wykonuje się kolejny raz,
gdy wyrażenie jest prawdziwe (czyli ma wartość różną od zera).
Składnia pętli while
while (wyrażenie) instrukcja;
gdzie:
wyrażenie
instrukcja
-wyrażenie przyjmujące wartość logiczną
„prawda” albo „fałsz”
- instrukcja wykonywana w pętli
Napiszmy prosty program wyświetlający na ekranie znaki podane
z klawiatury do momentu, aż podamy znak „k”.
11
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char z;
cout << ˝podaj znak ˝;
cin >> z;
while (z != ‘k’)
{
cout << ˝ Podaj kolejny znak ˝;
cin >> z;
}
cout << ˝ Podales ˝ << z << ˝ wiec koncze˝;
cin.ignore();
getchar();
return 0;
}
12
Brak kształcenia umiejętności projektowania poprawnych
algorytmów
…Metodami, jakie się w takich przypadkach stosuje zajmiemy się w przyszłym
roku. Na co dzień muszą wystarczyć poniższe zasady:
•staraj się wykorzystywać sprawdzone pewne algorytmy; mogą to być procedury,
ale też fragmenty poprzednio wykorzystywanych algorytmów; gromadź takie stałe
fragmenty gry w swojej podręcznej biblioteczce;
•na etapie tworzenia algorytmu możesz być wizjonerem, artystą, na etapie sprawdzania,
czy algorytm działa zgodnie z Twoimi zamierzeniami, powinieneś być skrupulatnym,
podejrzliwym kontrolerem, który sprawdza każdy szczegół, nie wierzy nikomu, nawet
sobie;
•ćwicz – pisz programy, podpatruj, jak inni to robią, stale szukaj nowych, lepszych
rozwiązań…
13
Dominujące używanie schematów blokowych (listy kroków)
do zapisywania algorytmów
Problem algorytmiczny: Badanie, czy podana liczba jest pierwsza
Dane wejściowe: liczba naturalna n > 1 – badana liczba
Dane wyjściowe: napis „liczba pierwsza”, gdy n jest liczbą pierwszą, lub napis
„liczba złożona”, gdy n jest liczbą złożoną
Zmienne pomocnicze: liczba naturalna i – potencjalny dzielnik; i > 1
1.
2.
3.
4.
5.
6.
Wczytaj n.
Zmiennej pomocniczej i przypisz wartość 2.
Jeśli kwadrat liczby i jest większy od liczby n, to wypisz „liczba pierwsza”
i zakończ.
Jeśli reszta z dzielenia n przez i wynosi 0, wypisz ‘liczba złożona” i zakończ.
Zwiększ o 1 wartość zmiennej pomocniczej i.
Przejdź do kroku 3.
14
Nieciekawe, techniczne przykłady
Przykład użycia instrukcji iteracyjnej while
uses CRT;
var powtórz:boolean;
procedure sprawdz(var powtorz: boolean);
var c:char;
begin
write(‘Czy powtórzyć (nacisnij t/T jeśli TAK)? ‘);
c := ReadKey; Writeln(c);
powtorz := UpCase(c)=‘T’;
writeln
end;
begin
powtorz := True;
while powtorz do begin
czytajDane(m,n); wypisz(m,n);
sprawdz(powtorz);
end
end.
15
Dominacja odtwórczych zadań
Napisz program realizujący algorytm z przykładu 5. Posłuż się
danymi generowanymi losowo. Zanotuj, ile operacji każdorazowo
wykonał program (liczba operacji będzie równa numerowi
znalezionego elementu lub n, gdy element nie zostanie znaleziony).
Oblicz średnią liczbę operacji dla wszystkich wykonań programu.
16
Wprowadzanie „klasycznych” algorytmów bez uzasadniania
dlaczego zaliczamy je do klasyki (ze względu na wagę rozwiązywanego
problemu? ze względu na wagę i ogólność użytych w nich metod?)
Z podstawy programowej:
algorytmy wyszukiwania i porządkowania (sortowania), np.:
– jednoczesne znajdowanie największego i najmniejszego elementu
w zbiorze: algorytm naiwny i optymalny,
– algorytmy sortowania ciągu liczb: bąbelkowy, przez wybór,
przez wstawianie liniowe lub binarne, przez scalanie, szybki,
kubełkowy.
17
Wstęp do programowania w ujęciu
algorytmicznym - podstawy
Sylabus:
• algorytm (specyfikacja, dziedzina algorytmiczna,
zapisywanie algorytmów)
• kodowanie algorytmów (instrukcje: warunkowa i iteracji)
•funkcja
• zmienne
• projektowanie iteracji, poprawność algorytmu
• tablice
• złożoność obliczeniowa algorytmu
18
W jaki sposób układamy i
zapisujemy algorytmy - przykłady
Zadanie 1 – pierwiastek dyskretny
Dane: nieujemna liczba całkowita n
Wyniki: nieujemna liczba całkowita
 n  p taka, że
p2 <= n < (p+1)2
Dozwolone operacje: dodawanie i odejmowanie liczb całkowitych
porównywanie liczb całkowitych
Uwaga: w języku matematyki chcemy umieć obliczać wartość funkcji
pierwiastekDyskretny(n) = [sqrt(n)].
19
Algorytm w języku naturalnym:
weź 0 na kandydata
dopóki następnik kandydata spełnia nierówność pierwiastka:
niech ten następnik będzie nowym kandydatem
aktualny kandydat to poszukiwany pierwiastek dyskretny
Python:
def pierwiastekDyskretny(n):
k=0
while (k+1)*(k+1) <= n:
k=k+1
return k
20
C++:
int pierwiastekDyskretny(int n) {
int k = 0;
while ( (k+1)*(k+1) <= n) ) {
k = k + 1;
}
return k
}
21
Przyśpieszanie algorytmu –
projektowanie pętli od środka
Spostrzeżenie 1: pierwiastek dyskretny p z n leży w przedziale
[0..n]
Spostrzeżenie 2: załóżmy, że p leży w przedziale [le..pr] i niech
k będzie liczbą całkowitą z tego przedziału, wówczas
jeśli (k+1)*(k+1) <= n, to p leży w przedziale [k+1..pr]
jeśli k*k > n, to p leży w przedziale [le..k-1]
22
Projektowanie wnętrza pętli
Asercja: le <= p <=pr, co oznacza, że le*le <= n < (pr+1)*(pr+1)
k = (le+pr)/2
if (k+1)*(k+1) <= n:
le = k+1
if k*k > n:
pr = k - 1
23
Python:
def pierwiastekDyskretny(n):
assert n >= 0
le = 0
pr = n
while True:
assert (le*le <= n) AND ((pr+1)*(pr+1) > n)
k = (le + pr) / 2
if (k+1)*(k+1) <= n:
le = k+1
continue
if k*k > n:
pr = k-1
continue
assert (k<= n) AND ((k+1)*(k+1) > n)
break
return k
24
int pierwiastekDyskretny(int n){
int le, pr, k;
assert (n >= 0);
le = 0;
pr = n;
while (True){
assert ((le*le <= n) && ((pr+1)*(pr+1) > n));
k = (le + pr) / 2;
if ((k+1)*(k+1) <= n){
le = k+1;
continue;
}
if (k*k > n){
pr = k-1;
continue;
}
assert ((k<= n) && ((k+1)*(k+1) > n));
break;
}
return k;
}
25
Download