Zaliczeniowe zadanie programistyczne - semestr letni

Dopuszczalne, a nawet wskazane, są dyskusje z innymi studentami na temat zadania, a nawet wspólne opracowywanie algorytmu rozwiązania - lecz ostateczną implementację, testowanie i dokumentację programu należy wykonać samodzielnie.

Wykonanie zadań wiąże się m.in. z opanowaniem programowania operacji zapisu i odczytu plików tekstowych (a także operacji na stringach) w języku C. W razie kłopotów ze zrozumieniem stosownego rozdziału w K&R służę konsultacjami.

Wybór zadania

Z przedstawionych do wyboru zadań, należy wybrać jedno. Tytuł wybranego zadania należy przesłać do zatwierdzenia na adres email piotr.krzyzanowski@mimuw.edu.pl do 12. kwietnia.

Wybór zadania jest ostateczny, nie będzie można go później zmienić na inne, ani zamienić się z inną osobą - dlatego w razie wątpliwości warto wcześniej skonsultować treść zadania z prowadzącym ćwiczenia.

Projekt programu

Po zatwierdzeniu wyboru zadania, warto sporządzić na własny użytek (nie będzie oceniany ani sprawdzany!) projekt programu, aby potem móc w usystematyzowany sposób prowadzić implementację. Projekt programu jest dla zadania tym, czym konspekt dla wypracowania z języka polskiego: to plan pracy i zarys metod wykonania jej. Projekt programu powinien zawierać:

  1. Sformułowanie zadania
  2. Ogólne omówienie projektowanego rozwiązania (wybór metody, uzasadnienie, dyskusja ewentualnych alternatyw)
  3. Ogólny opis struktury logicznej programu i jego podprogramów (funkcji)
  4. Opis formatu danych i wyników, ograniczenia na dane
  5. Niezbędne testy programu (i opis metod ich weryfikacji)

Rozwiązanie zadania

Następnie należy przystąpić do realizacji zadania. W trakcie pisania programu dobrze jest go dokumentować, zamieszczając w nim (dla siebie) krótkie i treściwe komentarze przy kolejnych porcjach kodu. Gdy w trakcie implementacji zajdzie uzasadniona potrzeba odejścia od swojego pierwotnego projektu, należy to dobrze przemyśleć i ewentualnie przekonstruować projekt. W takiej chwili, porzucenie projektu i zdanie się na wielką improwizację (aby zobaczyć "co wyjdzie") jest, moim zdaniem, mało roztropne. Po opracowaniu, uruchomieniu i przetestowaniu programu, należy rozbudować dokumentujące go komentarze tak, by kod źródłowy był czytelny dla sprawdzającego. Należy pamiętać, by każdy plik kodu źródłowego miał na początku krótki komentarz dotyczący: streszczenia zawartości pliku, jego autora i daty ostatniej modyfikacji. Konieczne jest także krótkie objaśnienie zasad działania najważniejszych funkcji.

Konstruowany program powinien mieć budowę modułową, tzn. składać się z kilku dobrze przemyślanych funkcji, realizujących logicznie wyodrębione części algorytmu rozwiązania zadania.

Ocenie będzie podlegać program wraz z dokumentacją w kodzie źródłowym, na którą składają się co najmniej trzy pliki:

W/w składniki rozwiązania należy przesłać (w jednym mailu, ale każdy plik jako osobny załącznik) do dnia 25.05.09. na adres piotr.krzyzanowski@mimuw.edu.pl. Każdy rozpoczęty dzień opóźnienia obniża ocenę o 5 punktów.

Ocena

Oceniane będą: wartość merytoryczna, artystyczna i estetyczna przedstawionego rozwiązania. Maksymalnie można uzyskać 10 punktów. Program, który nie daje się uruchomić na Linuxie na students.mimuw.edu.pl (tzn. w LABie), będzie automatycznie oceniony na 0 punktów. Elementem oceny może być także rozmowa na temat programu i jego uruchomienie "na żywo" w LABie.

Zadania do wyboru

Indeksator
Program ma wczytywać zadany plik tekstowy i generować alfabetyczny indeks występujących w nim słów, ze wskazaniem w której linii tekstu to słowo wystąpiło. Jeśli wystąpiło więcej niż raz, oczywiście numeru linii nie powtarzamy. W wersji ciekawszej, program mógłby omijać nie znaczące słówka takie jak np. (w języku polskim) "a", "i", "lub", "że" (brak tej cechy nie wpłynie jednak na ocenę).

Jeśli na przykład plik litwa.txt zawiera następujący tekst:

Litwo! LiTWo ty moja! Ty jestes jak zdrowie.
Ile cie trzeba cenic, ten tylko sie dowie,
Kto cie stracil. Dzis pieknosc twa w calej ozdobie

to wywołanie programu na tym pliku


program litwa.txt

dawałoby efekt


calej 3
cenic 2
cie 2, 3
dowie 2
dzis 3
...itd...
litwo 1
moja 1
...itd...

Program ma działać na dużych tekstach. Zadaniem łatwym jest implementacja tego programu tak, by działał dobrze na tekstach anglojęzycznych, czy też na tekstach polskojęzycznych w kodowaniu Windows-1250, czy ISO-8859-2. Znacznie trudniejsze (i nie jest to obowiązkowe, zob. akapit poniżej) może okazać się zaimplementowanie algorytmu tak, by działał prawidłowo na tekstach kodowanych w UTF-8 (domyślnym w Linuxie). Wtedy można skorzystać z funkcji C działających na rozszerzonym zestawie znaków wykorzystać funkcje C iconv_open, iconv, iconv_close.

Na szczęście - jeśli nie chcemy wgłębiać się w tajniki obsługi UTF-8 - możemy ominąć tę trudność. Dowolny tekst w pliku tekst1.txt w kodowaniu XXX możemy przekodować do pliku tekst2.txt (już w kodowaniu YYY) zaklęciem iconv -f XXX -t YYY tekst1.txt > tekst2.txt, na przykład

iconv -f UTF-8 -t ISO-8859-2 litwa.txt > brzytwa.txt

spowoduje, że w pliku brzytwa.txt znajdzie się zawartość pliku litwa.txt, ale już w kodowaniu ISO-8859-2 (pod warunkiem, oczywiście, że litwa.txt faktycznie była w kodowaniu UTF-8).

Zatem sensowna sekwencja poleceń naszego programu w przypadku, gdy indeksowany plik litwa.txt jest w kodowaniu UTF-8, mogłaby wyglądać następująco:


iconv -f UTF-8 -t ISO-8859-2 litwa.txt >  brzytwa.txt
program brzytwa.txt > sitwa.txt
iconv -f ISO-8859-2 -t UTF-8 sitwa.txt >  indeks.txt

Kalkulator (trudniejsze)
Zaimplementuj czterodziałaniowy interpreter wyrażeń arytmetycznych (z nawiasami). Dla zadanego stringa (o długości nie większej niż znany parametr MAXLEN) z napisem zawierającym (być może poprawne) wyrażenie arytmetyczne, np. 3.14+5*(17.123/(-2)) funkcja ma obliczać poprawną wartość tego wyrażenia lub sygnalizować błąd gdy wyrażenie jest błędne, np. wtedy, gdy jest w nim niesparowany nawias: 3.14+5*(<17.123/(-2)). Oczywiście, mnożenie i dzielenie muszą mieć większy priorytet od dodawania i odejmowania, zatem 3.14+5*17 to to samo, co 3.14+(5*17). To zadanie jest tylko pozornie łatwe. Ale na pewno jest do zrobienia!
Dyferencjator (jeszcze trudniejsze)
Podobny jak Kalkulator, ale tym razem musi różniczkować zadane wyrażenie względem zadanej zmiennej, np. 3.14+a*x + sin(x) różniczkowane względem x powinno dać w wyniku 0+a*1+cos(x), choć oczywiście znacznie lepiej byłoby, gdyby dawało a+cos(x). Podobnie, wyjściowe wyrażenie różniczkowane względem a powinno dawać w wyniku x, a różniczkowane względem zmiennej q powinno dawać zero. Nie kryję, że to zadanie jest trudne.
Aktualizacja: 03.03.2017, 10:43:22.
© Piotr Krzyżanowski