Kontakt:

mail:
www: http://www.ii.uni.wroc.pl/~prz/

Konsultacje:

  • po ostatnich zajęciach w każdym dniu w którym prowadzę laboratorium
  • proszę wcześniej uzgodnić dokładny termin konsultacji drogą mailową

Semestr zimowy w roku akademickim 2010/11

Adres:

Instytut Informatyki
Uniwersytetu Wrocławskiego
ul. Joliot-Curie 15
50-383 Wrocław
OGŁOSZENIA

2 lutego 2011 r.

Zaliczenie 4 z przedmiotu:

Ostatnią (!) w tym semestrze poprawkę testu zrobię w sobotę 5 lutego 2011 w godzinach 9:00-10:00 w sali 11 (rozpoczęcie o 9:15). Testy będę sprawdzał na bieżąco przy studentach (powtórzcie wiadomości o klasach, dziedziczeniu i polimorfizmie). Potem w pokoju 31 (pokój nauczycieli) dopytam resztę studentów i odbiorę zadania dodatkowe (tylko na notebookach) - konsultacje potrwają do godziny 11:00.

26 stycznia 2011 r.

Zaliczenie 3 z przedmiotu:

Dodatkową poprawkę testu zrobię w sobotę 29 stycznia 2011 w godzinach 8:00-8:30 w sali 13 (rozpoczęcie o 8:15) - powtórz wiadomości o instrukcjach sterujących i wyjątkach. Potem w pokoju 31 (pokój nauczycieli) posprawdzam testy, dopytam rokujące osoby i odbiorę zadania dodatkowe (tylko na notebookach) - konsultacje potrwają do godziny 11:00.

20 stycznia 2011 r.

Wyniki z pierwszego testu poprawkowego:

Do tabeli z punktami dopisałem już punkty z pierwszego testu poprawkowego.

17 stycznia 2011 r.

Zadania dodatkowe:

Zrobiłem listę zadań dodatkowych dla studentów, którym zabrakło minimalnej ilości punktów z ćwiczeń do zaliczenia przedmiotu. Studenci z brakami punktowymi (oni więdzą o kogo chodzi) mogą sobie wybrać z tej listy do dwóch zadań, zrobić je i zaprezentować w czasie najbliższego spotkania.

17 stycznia 2011 r.

Zaliczenie 2 z przedmiotu:

Poprawka testu, dopytka ustna, oddanie zadań dodatkowych zrobię w niedzielę 23 stycznia 2011 w godzinach 9:00-13:00 w sali 25. Poprawka testu rozpocznie się o 9:20; potem na bieżąco posprawdzam testy. Szacuję, że około 11:00 rozpocznę dopytkę ustną i sprawdzanie programów dodatkowych.
Wyniki pierwszego testu poprawkowego wkrótce dopiszę do tabeli z punktami.

14 stycznia 2011 r.

Wyniki z testu:

Właśnie uzupełniam niektóre odpowiedzi częściowymi punktami (bowiem wyniki testu okazały się gorsze od oczekiwanych). Ostateczną punktację uzupełnię dziś około 20.
Wszystkie zadania są już ostatecznie ocenione. Teraz sumuję punkty.
Punkty już są podliczone. Teraz będę je wpisywać do tabeli. Szacując grubość obu stosów kartek z pracami zaliczonymi i niezaliczonymi, to wynik jest mniej-więcej 1:1. Wyników na stronie proszę się spodziewać około 22.
Właśnie wrzuciłem wyniki na serwer! Oto krótki komentarz. Z testu można było dostać 8 punktów. Zaliczenie egzaminu było od 4 punktów, dopytka od 3, pozostali studenci będą pisać test poprawkowy. Pytania na teście poprawkowym w większości będą inne niż na ostatnim sprawdzianie. Termin najbliższej poprawki to niedziela 16 stycznia 2011 o godzinie 11:10 w sali 11.

11 stycznia 2011 r.

Zaliczenie 1 z przedmiotu:

Ustne dokończenie egzaminu (tylko dla tych, którym się nie powiodło na teście - ale jest to większość zdających) i wpisy do indeksu będę robić w niedzielę 16 stycznia 2011 w godzinach 10:30-13:00 w sali 11.
Wyniki testu wkrótce dopiszę do tabeli z punktami.

29 października 2010 r.

Zadanie domowe z listy 3:

Bilet na zadanie domowe z listy 3 mają wszyscy studenci, który w kolumnie ZAD.3.D w pliku ze statystyką mają wpisane 0. Proszę o sprawdzenie tych informacji, szczególnie studentów z grupy 3ZB. Zadanie domowe z listy 3 będę sprawdać na początku najbliższych zajęć (w sobotę 13 listopada 2010).

29 października 2010 r.

Zadanie 3 z listy 1:

Zadanie 3 z listy 1 będzie można zrobić w domu i zaprezentować je na początku najbliższych zajęć (w sobotę 6 listopada 2010).

14 października 2010 r.

Punkt informacyjny:

To właśnie w tym miejscu będą się pojawiać ważne ogłoszenia dotyczące organizacji zajęć związanych z tym przedmiotem. Proszę zaglądać do tych ogłoszń, szczególnie przed laboratorium.

Java to współczesny obiektowy język programowania stworzony przez Jamesa Goslinga z firmy Sun Microsystems. Od momentu powstania w połowie lat 90-tych XX wieku przeżył on dynamiczny rozwój a zainteresowanie nim stale rośnie. Język Java przyciągnął do dziś prawie 7 milionów programistów. Znajduje zastosowanie w każdej ważniejszej gałęzi przemysłu informatycznego i jest obecny w różnego rodzaju urządzeniach, komputerach i sieciach. Popularność Javy wynika przede wszystkim z przenośności programów i niezależności od konkretnej platwormy sprzętowej, a co za tym idzie, ma zastosowanie w Internecie oraz ogólnie w aplikacjach sieciowych. Jego podstawowe koncepcje zostały przejęte z języka Smalltalk (maszyna wirtualna, odśmiecanie pamięci) oraz z języka C++ (znaczna część składni i słów kluczowych).

Celem tych zajęć jest nauczenie Was programowania w języku Java oraz zapoznanie z kilkoma ważnymi technologiami wykorzystywanymi we współczesnym programowaniu w Javie.

Wymagane przygotowanie

  • Umiejętność programowania w języku C/C++ (podstawowe konstrukcje językowe i obiekty na elementarnym poziomie).
  • Znajomość podstawowych struktur danych (tablice, listy, drzewa, grafy).

Literatura

Literatura papierowa polskojęzyczna:

  • Ken Arnold, James Gosling: Java. WNT, Warszawa 1999.
  • Krzysztof Barteczko: Java. Od podstaw do technologii. Tom 1 i 2. Wydawnictwo MIKOM, Warszawa 2004.
  • Herbert Schildt: Java. Kompendium programisty. Wydawnictwo HELION, Gliwice 2005.
  • Bruce Eckel: Thinking in Java. Wydanie 4. Edycja polska. Wydawnictwo HELION, Gliwice 2006.

Literatura papierowa anglojęzyczna:

  • Ken Arnold, James Gosling, David Holmes: The Java Programming Language. Fourth Edition. Prentice Hall PTR, 2005.
  • James Gosling, Bill Joy, Guy Steele, Gilad Bracha: The Java Language Specification. Third Edition. Prentice Hall PTR, 2005.
  • Tim Lindholm, Frank Yellin: The Java Virtual Machine Specification. Second Edition. Prentice Hall PTR, 1999.

Literatura elektroniczna anglojęzyczna:

Terminarz

  • wykład: Zofia Kruczkiewicz
    • niedziela, 23 stycznia 2011 r, godzina 14-16: egzamin.
    • sobota, 29 stycznia 2011 r, godzina 12-14: egzamin poprawkowy 1.
    • sobota, 5 lutego 2011 r, godzina 12-14: egzamin poprawkowy 2.
  • laboratorium: Paweł Rzechonek
    1. sobota, 23 października 2010 r: zapoznaie ze środowiskiem NetBeans; podstawy języka Java; standardowe wejście/wyjście.
    2. sobota, 6 listopada 2010 r: klasy i obiekty; pola i metody.
    3. niedziela, 7 listopada 2010 r: składowe statyczne; wyjątki.
    4. sobota, 13 listopada 2010 r: interfejsy; typy sparametryzowane.
    5. niedziela, 14 listopada 2010 r: dziedziczenie i polimorfizm.
    6. niedziela, 12 grudnia 2010 r: strumienie i serializacja.
    7. sobota, 8 stycznia 2011 r: kolekcje standardowe; test zaliczeniowy.
    • niedziela, 16 stycznia 2011 r, godzina 10-14: poprawka testu; wpisywanie ocen do indeksów.
    • niedziela, 23 stycznia 2011 r, godzina 9-13: poprawka testu; wpisywanie ocen do indeksów.

Laboratorium

Zasady zaliczenia przedmiotu

Ogólnie:
Program studiów w trybie zaocznym przewiduje 7 ćwiczeń laboratoryjnych po dwie godziny lekcyjne. Na każdych zajęciach trzeba będzie napisać i uruchomić zadane programy. Na ostatnich ćwiczeniach będzie jeszcze przeprowadzony test zaliczeniowy połączony z odpowiedzią ustną.
Terminy:
Zadania do zaprogramowania będą ogłaszane w tygodniu poprzedzającym termin ich realizacji (za wyjątkiem pierwszych ćwiczeń), co najmniej 3 dni przed zajęciami. Zadania należy oddawać w zaplanowanym terminie na zajęciach laboratoryjnych. Spóźnienia nie będą tolerowane, za wyjątkiem uzasadnionych sytuacji życiowych: choroba, wezwanie do Sądu, prestiżowe zawody sportowe, ważne wydarzenie rodzinne, itp.
Obecność:
Obecność na zajęciach jest obowiązkowa. Jeśli z pewnych uzasadnionych powodów, o których pisałem w poprzednim punkcie, student nie będzie obecny na zajęciach, to powinien wysłać mi pocztą elektroniczną zaległy program w ciągu 3 dni od daty jego realizacji na ćwiczeniach, a na początku najbliższych zajęć zaprezentować jego działanie i opowiedzieć jak jest zbudowany. Warunkiem koniecznym zaliczenia laboratorium jest obecność na co najmniej 4 ćwiczeniach.
Zadania laboratoryjne:
Do napisania programu należy się dobrze przygotować, gdyż czasu na laboratorium jest mało. Programy należy skończyć w trakcie ćwiczeń i zaprezentować ich działanie. Będą one oceniane za zgodność z treścią, efektywność zastosowanych algorytmów, strukturę kodu (podział programu na pakiety, klasy, podprogamy) oraz za styl i czytelność kodu (komentarze, sensowne nazwy zmiennych, wcięcia). Każdy plik z kodem źródłowym powinien zawierać na początku komentarz z danymi autora (imię, nazwisko, numer indeksu) i nazwą/numerem zadania. Warunkiem koniecznym zaliczenia laboratorium jest samodzielne napisanie co najmniej 4 programów działających zgodnie ze specyfikacją.
Zadania domowe:
Dodatkowo będą zadawane zadania domowe, sprawdzane na początku następnych zajęć. Zadania domowe będą przydzielane tylko najlepszym studentom na poszczególnych zajęciach. Przepustkę do zadania domowego może dostać tylko student obecny na zajęciach, który uzyskał co najmniej 8 punktów z bieżącego zadania. Przepustki do zadań domowych będę rozdzielał osobiście pod koniec każdych ćwiczeń; na każdych zajęciach rozdam co najwyżej 5 przepustek. Punkty z zadań domowych będą uwzględniane przy wystawianiu oceny końcowej tylko w przypadku, gdy student uzyska zaliczenie z tego przedmiotu w pierwszym terminie.
Prezentacje:
Programy należy prezentować osobiście w czasie laboratorium (proszę nie wysyłać programów pocztą elektroniczną, ani nie przekazywać ich poprzez kolegów czy koleżanki). W trakcie prezentacji programu trzeba się liczyć z pytamiami dotyczącymi zadania: metoda rozwiązania, zastosowane konstrukcje językowe, wykorzystane technologie, itp. Student może też zostać poproszony o dokonanie prostych zmian w swoim programie, które powinien umieć szybko wprowadzić.
Punkty:
Na każdych ćwiczeniach można dostać do 10 punktów za napisany program; w semestrze będzie ogłoszonych 7 zestawów zadań programistycznych, więc łącznie będzie można zdobyć 70 punktów za te zadania. Na ostatnich ćwiczeniach będzie przeprowadzony egzamin ustny za 10 punktów. Maksymalnie będzie więc można zdobyć 80 punktów (plus punkty za zadania domowe doliczane do punktacji po zaliczeniu przedmiotu na warunkach podstawowych).
Oceny:
Aby zaliczyć laboratorium na ocenę dostateczną trzeba do końca semestru zgromadzić co najmniej 28 punktów za napisane programy i zdać test na minimum 4 punkty (łącznie 32 punkty); na ocenę bardzo dobrą należy zgromadzić łącznie 64 punkty; oceny pośrednie pozostają w liniowej zależności od przedstawionych wymagań granicznych. Warunkiem koniecznym zaliczenia laboratorium jest zdanie egzaminu ustnego.

Lista zadań laboratoryjnych

Przy każdym zadaniu laboratoryjnym jest/będzie napisana data, która odnosi się do dnia kiedy to zadanie będzie robione i oceniane na ćwiczeniach.

Labolatorium 1 (23.10.2010) Labolatorium 2 (6.11.2010) Labolatorium 3 (7.11.2010) Labolatorium 4 (13.11.2010)
Labolatorium 5 (14.11.2010) Labolatorium 6 (12.12.2010) Labolatorium 7 (8.01.2011) Zadania dodatkowe
Labolatorium 1 (23.10.2010): standardowe wejście/wyjście (formatowanie napisów)

Zadanie 1 (2 punkty)

Napisz program, który będzie wypisywał na standardowe wyjście informacje o jakiejś osobie. Dane na temat tej osoby (imię, nazwisko, rok urodzenia, wzrost, waga) zdefiniuj w postaci stałych pól statycznych w głównej klasie. Do wypisania tych informacji użyj metody print(), println() albo format() na obiekcie System.out.

Zadanie 2 (5 punktów)

Napisz program, który przekształci wszystkie argumenty wywołania programu na liczby rzeczywiste (o ile będzie to możliwe) i umieści je w tablicy double[]. Program ma policzyć sumę i iloczyn tych liczb i wypisać wyniki na standardowe wyjście System.out. Jeśli przekształcenie któregoś z argumentów nie będzie możliwe, to należy wypisać komunikat o błędzie na standardowe wyjście dla błędów System.err i natychmiast zakończyć działanie programu.

Zadanie 3 (3 punkty)

Stwórz obiekt klasy Date zawierający bieżącą datę i godzinę. Następnie wypisz ją na standardowym wyjściu System.out, estetycznie formatując wydruk. W metodzie format() umieść tylko dwa parametry: wzorzec ze znacznikami i referencję do obiektu z datą.

Zadanie domowe (5 punktów)

Napisz program, który wczyta ze standardowego wejścia System.in liczbę całkowitą, a następnie wypisze ją na standardowym wyjściu System.out w postaci binarnej. Zabezpiecz swój program przed podaniem nieprawidłowych danych a ewentualne komunikaty o błędach wyślij na standardowe wyjście dla błędów System.err. Do wypisania liczby w postaci binarnej wykorzystaj zdefiniowaną przez siebie rekurencyjną metodę bin(), która będzie zwracała łańcuch znaków String reprezentujący w postaci binarnej zadaną liczbę całkowitą typu long i która będzie prawidłowo działać nie tylko dla liczb dodatnich ale również dla zera i liczb ujemnych.

Do odczytania danych ze standardowego wejścia wykorzystaj klasę BufferedReader z pakietu java.io: BufferedReader we = new BufferedReader(new InputStreamReader(System.in)); Wywołując na obiekcie we metodę readLine() odczytasz cały wiersz z danymi wpisanymi z klawiatury.

 

Labolatorium 2 (6.11.2010): klasy i obiekty (geometria płaska)

Zadanie (10 punktów)

Rozważmy prostą geometrię 2-wymiarową w kartezjańskim układzie współrzędnych (prostoliniowy układ współrzędnych o parach prostopadłych osi OX i OY z punktem przecięcia O zwanym początkiem układu współrzędnych). Elementarnymi obiektami w takiej geometrii niech będą trzy figury: punkt (klasa Punkt, w której główną składową będzie punkt na płaszczyźnie typu Point2D.Double), odcinek (klasa Odcinek) jednoznacznie wyznaczony przez parę punktów oraz trójkąt (klasa Trojkat) wyznaczony jednoznacznie przez trzy punkty. Figury te mają mieć wspólną abstrakcyjną klasę bazową Figura (klasa ta powinna posiadać atrybut kolor typu Color).

W naszym programie istotną rolę będzie odgrywała klasa Rysunek, która powinna być zbiorem figur. Taki zbiór figur będzie się składał na większe dzieło zwane rysunkiem. Klasa Rysunek powinna być więc kontenerem - może ona dziedziczyć na przykład po kontenerze z biblioteki standardowej ArrayList<Figura>.

I ostatnia, najbardziej efektowna rzecz, to metody drukujące figury w formacie PostScript. Każdą z figur zaopatrz w metodę toString(), która wygeneruje opis tej figury we wspomnianym formacie. Na przykład klasa Punkt może wyglądać następująco: class Punkt extends Figura
{
  protected Point2D.Double punkt1;

  public Punkt (Color kol, double x1, double y1)
  {
    super(kol);
    punkt1 = new Point2D.Double(x1,y1);
  }
  public double x1 () { return punkt1.getX(); }
  public double y1 () { return punkt1.getY(); }

  public String toString ()
  {
    return
      "newpath\n"+
      String.format("%.3f %.3f %.3f setrgbcolor\n",kolor.getRed()/255.0,kolor.getGreen()/255.0,kolor.getBlue()/255.0)+
      String.format("%.1f %.1f 1 0 360 arc\n",x1()+dx,y1()+dy)+
      "fill";
  }
}
W klasie Rysunek powinna się znaleźć metoda wypisująca zawartość całej kolekcji na standardowe wyjście: public void drukuj ()
{
  System.out.format("%%!PS\n");
  System.out.format("%%%%Orientation: Portrait\n");
  System.out.format("%%%%BoundingBox: 0 0 595 842\n");
  System.out.format("%%%%DocumentPaperSizes: a4\n");
  for (Figura f: this) System.out.println(f.toString());
  System.out.format("showpage\n");
  System.out.format("%%%%Trailer\n");
  System.out.format("%%EOF\n");
}
Metoda drukuj() oprócz wypisania wszystkich figur musi również wypisać prolog i epilog całego dokumentu postscriptowego.

PostcSript jest systemem, w którym wyrażenia są zapisywane postfiksowo - tak jak w Odwrotnej Notacji Polskiej. Więcej szczegółów technicznych możesz przeczytać w opracowaniu PostScript Language Tutorial & Cookbook.

No i na koniec napisz program, który wygeneruje rysunek kolorowej choinki. Wypisz go na standardowe wyjście, przechwyć strumień i zapisz go do pliku (użyj wiersza poleceń), a na koniec oglądnij swój rysunek:

  • użyj jakiejś popularnej przeglądarki plików graficznych, która umie czytać pliki w formacie .ps;
  • skorzystaj z serwisu internetowego, który może wyświetlić załączony plik .ps, na przykład http://view.samurajdata.se;
  • skorzystaj z serwisu internetowego, który umie przekonwertować plik z fornatu .ps do innego popularniejszego formatu (może to być .pdf), na przykład http://ps2pdf.com.

 

Labolatorium 3 (7.11.2010): składowe statyczne (liczby pierwsze i sito Eratostenesa)

Zadanie (10 punktów)

Napisz program, który wypisze na standardowym wyjściu System.out rozkład zadanych (poprzez argumenty wywołania) liczb całkowitych na czynniki pierwsze. Rozkład każdej z nich ma być wypisany w osobnym wierszu: najpierw liczba, potem znak = i dalej czynniki pierwsze poodzielane znakiem *.

Parametry wywołania programu powinny być liczbami całkowitymi. Odstępstwo od tego wymogu ma skutkować wypisaniem stosownego komunikatu o błędzie do standardowego strumienia dla błędów System.err. Jeśli program wywołano bez żadnego parametru, to należy wypisać na standardowym strumieniu dla błędów instrukcję obsługi programu.

Programując to zadanie zdefiniuj w pakiecie narzedzia klasę usługową LiczbyPierwsze. Klasa ta powinna posiadać tylko dwie metody statyczne: czyPierwsza() testująca pierwszość liczby (funkcja ma zwracać wartość true albo false) oraz naCzynnikiPierwsze() tworząca rozkład liczby na czynniki pierwsze (czynniki te umieść w tablicy). Wykorzystaj do tego celu sito Eratostenesa, modyfikując je w ten sposób, że dla każdej liczby pamiętaj jej najmniejszy podzielnik pierwszy (będzie to trik pomocny przy wyliczaniu rozkładu liczby na czynniki pierwsze). Sito Eratostenesa zaprogramuj jako tablicę statyczną zainicjalizowaną w statycznym bloku inicjalizacyjnym.

Wspomniane wcześniej metody statyczne powinny udzielać poprawnych odpowiedzi dla wszystkich liczb typu long (weź pod uwagę, że nie możesz utworzyć tak dużego sita, więc zastanów się jak ten problem obejść algorytmicznie). Kasa LiczbyPierwsze powinna być tak zdefiniowana, aby nie można było stworzyć jej instancji. public class LiczbyPierwsze
{
  protected final ststic int POTEGA2 = 21 ;
  protected final static long[] SITO = new long[1<<POTEGA2] ;
  // ... potrzebny jest blok inicjalizacyjny dla sita ...

  public static boolean czyPierwsza (long x)
  { /* ... */ }

  public static long[] naCzynnikiPierwsze (long x)
  { /* ... */ }
}
Liczby pierwsze to liczby całkowite większe od 1, które są podzielne tylko przez siebie i przez jedynkę. Oto kilka początkowych liczb pierwszych: 2, 3, 5, 7, 11, 13, 17, 19... Wykorzystaj w swoim programie fakt, że liczba złożona x po rozkładzie na czynniki pierwsze posiada co najmniej jeden czynnik ≤sqrt(x).

Zadanie domowe (5 punktów)

Do klasy LiczbyPierwsze dopisz jeszcze dwie metody statyczne: nwd() wyliczającą największy wspólny dzielnik liczb całkowitych oraz nww() wyliczającą najmniejszą wspólna wielokrotność; argumentami tych funkcji powinny być co najmniej dwie liczby typu long (zaprogramuj metody ze zmienną liczbą argumentów). Do wyliczenia największego wspólnego dzielnika wykorzystaj algorytm Eulkidesa. Napisz także prosty program, który będzie testować działanie obu tych metod.

 

Labolatorium 4 (13.11.2010): interfejsy (drzewo binarnych poszukiwań)

Zadanie (10 punktów)

Zdefiniuj publiczny interfejs Słownik, który będzie zawierał zestaw najważniejszych operacji słownikowych do zarządzania dynamicznym zbiorem danych (elementy takiego zbioru musimy umieć porównywać, więc niech będą one typu Comparable): wstawianie elementu do zbioru (metoda wstaw), usuwanie elementu minimalnego, maksymalnego albo zadanego (metody usuńMinimum, usuńMaksimum i usuń) oraz wyszukiwanie elementu minimalnego, maksymalnego albo zadanego (metody szukajMinimum, szukajMaksimum i szukaj). public interface Słownik<TYP extends Comparable<TYP>>
{
  public TYP wstaw (TYP x);
  public TYP usuńMinimum ();
  public TYP usuńMaksimum ();
  // ...
}

Następnie zdefiniuj klasę publiczną DrzewoBST dla drzewa binarnych poszukiwań, gdzie w węzłach drzewa przechowywane będą elementy porównywalne typu Comparable. Klasa ta ma implementować interfejs Słownik. Klasa Drzewo ma być klasą opakowująca homogeniczną strukturę drzewa BST zbudowaną z węzłów. Pojedynczy węzeł natomiast, czyli klasa Węzeł, powinien być klasą wewnętrzną w klasie Drzewo. W~klasie wewnętrznej Węzeł zaimplementuj rekurencyjne metody do wstawiania, usuwania, wyszukiwania danych oraz do ich wypisywania w porządku inorder. public class DrzewoBST<TYP extends Comparable<TYP>>
implements Słownik<TYP>
{
  protected class Węzeł
  {
    protected Węzeł lewy, prawy;
    protected TYP dane;
    // ...
  }

  protected Węzeł korzeń; // referencja na korzeń drzewa
  protected int ile; // licznik elementów w drzewie
  // ...
}
Dość trudnym zadaniem w klasie Węzeł jest zaprogramowanie metod usuwających dane ze struktury, dlatego ich przykładową implementację podaję poniżej: private TYP kopiuj (Węzeł w)
  { TYP d = dane; dane = w.dane; lewy = w.lewy; prawy = w.prawy; return d; }
private Węzeł wklej (TYP d)
  { dane = d; lewy = prawy = null; return this; }
private Węzeł zamień (Węzeł w)
  { TYP d = dane; dane = w.dane; w.dane = d; return w; }

public Węzeł usuńMinimum ()
{
  if (lewy!=null)
  {
    Węzeł w = lewy.usuńMinimum();
    if (w==lewy) lewy = null;
    return w;
  }
  else if (prawy!=null) return prawy.wklej(kopiuj(prawy));
  else return this;
}
public Węzeł usuńMaksimum ()
{
  if (prawy!=null)
  {
    Węzeł w = prawy.usuńMaksimum();
    if (w==prawy) prawy = null;
    return w;
  }
  else if (lewy!=null) return lewy.wklej(kopiuj(lewy));
  else return this;
}
public Węzeł usuń (TYP x)
{
  int r = dane.compareTo(x);
  if (r<0)
    if (lewy==null) return null;
    else
    {
      Węzeł w = lewy.usuń(x);
      if (w==lewy) lewy = null;
      return w;
    }
  if (r>0)
    if (prawy==null) return null;
    else
    {
      Węzeł w = prawy.usuń(x);
      if (w==prawy) prawy = null;
      return w;
    }
  if (lewy!=null)
  {
    Węzeł w = lewy.usuńMaksimum();
    if (w==lewy) lewy = null;
    return zamień(w);
  }
  if (prawy!=null)
  {
    Węzeł w = prawy.usuńMinimum();
    if (w==prawy) prawy = null;
    return zamień(w);
  }
  return this;
}
Analogiczne metody w klasie DrzewoBST są dużo prostsze: public TYP usuńMinimum ()
{
  if (korzeń==null) return null;
  --ile;
  Węzeł w = korzeń.usuńMinimum();
  if (w==korzeń) korzeń = null;
  return w.dane();
}
public TYP usuńMaksimum ()
{
  if (korzeń==null) return null;
  --ile;
  Węzeł w = korzeń.usuńMaksimum();
  if (w==korzeń) korzeń = null;
  return w.dane();
}
public TYP usuń (TYP x)
{
  if (korzeń==null) return null;
  Węzeł w = korzeń.usuń(x);
  if (w==null) return null;
  --ile;
  if (w==korzeń) korzeń = null;
  return w.dane();
}

Dalej, zdefiniuj publiczną klasę Para, która będzie przechowywać pary klucz-wartość (w programie testowym będziemy używać par, w których klucz będzie typu String a wartość typu Double). Klucz powinien być polem publicznym ale niemodyfikowalnym a wartość polem ukrytym, do którego dostęp jest tylko za pomocą gettera (odczyt wartości) i settera (zapis nowej wartości). Zdefiniowana przez Ciebie klasa ma implementować interfejs Comparable<Para> (porównanie względem kluczy). public class Para<KLUCZ extends Comparable<KLUCZ>, WARTOŚĆ>
implements Comparable<Para<KLUCZ, WARTOŚĆ>>
{
  private final KLUCZ klucz;
  private WARTOŚĆ wartość;
  // ...
}

Na koniec przetestuj swoje drzewo BST programem MainBST.java, w którym pamiętane elementy to pary typu Para<String,Double> (napis jest kluczem a wartością liczba rzeczywista).

 

Labolatorium 5 (14.11.2010): dziedziczenie i polimorfizm (drzewa wyrażeń)

Zadanie (10 punktów)

Zdefiniuj abstrakcyjną klasę bazową Wyrazenie, reprezentującą całkowitoliczbowe wyrażenie arytmetyczne. W klasie tej umieść deklarację abstrakcyjnej metody oblicz(), której zadaniem w klasach potomnych będzie obliczanie wyrażenia i przekazywanie wyniku jako wartości typu Long.

Następnie zdefiniuj klasy dziedziczące po klasie Wyrazenie, które będą reprezentowały kolejno liczbę, zmienną (zmienne pamiętaj w statycznej kolekcji TreeMap<String,Long>), operacje arytmetyczne (dwuargumentowe dodawanie, odejmowanie, mnożenie, dzielenie i modulo oraz jednoargumentowa operacja zmiany znaku), porównania (wynikiem porównania ma być jak w języku C liczba 0 albo 1 odpowiadająca wartościom logicznym false albo true), operacje logiczne (negacja, alternatywa i koniunkcja) i inne.

Klasy te powinny być tak zaprojektowane, aby można z nich było zbudować drzewo wyrażenia: obiekty klas Liczba lub Zmienna to liście, a operatory to węzły wewnętrzne w takim drzewie. W klasach potomnych zdefiniuj metody oblicz() oraz toString().

Na koniec napisz krótki program testowy, sprawdzający działanie obiektów tych klas. W swoim programie skonstruuj drzewa obliczeń, wypisz je metodą toString() a potem oblicz i wypisz ich wartość dla następujących wyrażeń:

  • 7*11+2
  • 13-x
  • (x-3)/(x+3)
  • ((x+1)*x)/2
  • 2*x+1<0
  • x%4==0&&x%100!=0||x%400==0
  • !(|x-17|>=0)

Na przykład wyrażenie (7-x)*2 należy zdefiniować następująco: Wyrazenie w =
  new Mnozenie(
    new Odejmowanie(
      new Liczba(7),
      new Zmienna("x")
    ),
    new Liczba(2)
  );
Ustaw na początku programu testowego zmienną x na wartość –3. Pamiętaj też, aby złapać wyjątek przy próbie dzielenia przez 0.

Zadanie domowe (10 punktów)

Zdefiniuj abstrakcyjną klasę bazową Instrukcja, reprezentującą instrukcję w programie. W klasie tej umieść deklarację abstrakcyjnej metody wykonaj(), której zadaniem w klasach potomnych będzie wykonanie odpowiednich obliczeń.

Następnie zdefiniuj klasy dziedziczące po klasie Instrukcja, które będą reprezentowały kolejno deklarację zmiennej (zmienne zapamiętuj na stosie par klucz--wartość), instrukcję przypisania wartości wyrażenia do zmiennej, instrukcje warunkowe (takie jak instrukcje if oraz if-else w języku C), instrukcje pętli (takie jak instrukcje while i do-while w języku C), instrukcję czytania ze standardowego wejścia, pisania na standardowe wyjście oraz instrukcję blokową (złożenie dwóch lub więcej instrukcji). Zakładamy, że warunki w instrukcjach sterujących są wyrażeniami (warunek jest prawdziwy tylko wtedy, gdy wartość wyrażenia jest !=0). Ponadto, zmienne utworzone wewnątrz instrukcji blokowej należy usunąć na końcu bloku (można tworzyć zmienne o takich samych nazwach, ale wtedy następuje zjawisko przesłaniania zmiennych).

Klasy te powinny być tak zaprojektowane, aby można z nich było zbudować drzewo sterujące sekwencją obliczeń. W klasach potomnych zdefiniuj metody wykonaj() oraz toString().

Na koniec napisz krótki program testowy, sprawdzający działanie obiektów tych klas. W swoim programie skonstruuj drzewo obliczeń dla programu obliczającego silnię: var silnia;
silnia = 1;
var n;
read n;
if (n>1)
{
  var i;
  i = 2;
  while (i<=n)
  {
    silnia = silnia*i;
    i = i+1;
  }
}
write silnia;
Najpierw wydrukuj swój program metodą toString() a potem wykonaj go.

 

Labolatorium 6 (12.12.2010): strumienie i serializacja (kopiowanie plików, filtrowanie danych)

Zadanie 1 (6 punktów)

Napisz aplikację okienkową w technologii Swing, która będzie kopiowała zadany plik do określonego katalogu. public class Plikokopiarka extends JFrame
{
  protected File plik, katalog;
  // ...
}
Oba parametry (plik i katalog) wskaż za pomocą obiektu JFileChooser.

W swoim programie zdefiniuj ogólną funkcję kopiującą strumienie bajtowe: public static void kopiuj (InputStream we, OutputStream wy) throws IOException
{
  // ...
}
Nie zapomnij też o łapaniu ewentualnych wyjątków zgłaszanych podczas operacji czytania z lub pisania do strumienia IOException.

Zadanie 2 (4 punkty)

Zdefiniuj strumień filtrujący, który czytając linię tekstu będzie z niej usuwał białe znaki (spacje i tabulacje) na początku i na końcu oraz będzie kompresował wewnętrzne ciągi białych znaków zastępując je pojedynczą spacją. Twój strumień ma dziedziczyć po klasie BufferedReader i nadpisywać metodę readLine().

Następnie napisz aplikację okienkową w technologii Swing, która będzie wyświetlała zawartość wskazanego pliku tekstowego w obiekcie JTextArea. Do wskazania pliku użyj obiektu JFileChooser. Do odczytu danych z pliku wykorzystaj zdefiniowany przez ciebie strumień filtrujący.

Zadanie domowe (10 punktów)

Napisz aplikację okienkową w technologii Swing, która będzie zarządzać dynamicznym zbiorem danych jakim jest książka teleadresowa. Pojedyńczy wpis do książki teleadresowej to para dwóch napisów: nazwa (przeważnie imię i nazwisko, ale może to być na przykład miejsce pracy, bank, lotniski, itp) i adres (adres zamieszkania, adres mailowy, ale także numer telefonu, itp). class Wpis implements Serializable, Comparable<Wpis>
{
  public final String nazwa, adres;
  // ...
}
Wszystkie wpisy należy przechowywać w kolekcji typu Vector<Wpis>.

Aplikacja powinna zarządzać książką teleadresową poprzez dodawanie do niej nowych wpisów, usuwanie starych, modyfikację nieaktualnych oraz wyświetlanie wybranych informacji. Wybór informacji do pokazania użytkownikowi powinien być dokonany na podstawie nazwy albo adresu - można podać dowolny fragment nazwy albo adresu i jeśli dane pole zawiera taki fragment to wpis jest kwalifikowany do pokazania. Do zarządzania zbiorem wpisów (obiektem typu Vector<Wpis>) zdefiniuj własna klasę Kolekcja: class Kolekcja
{
  private Vector<Wpis> zbiór;
  // ...
  public void wstawNowy (Wpis nowy) {/*...*/}
  public void usuńStary (Wpis stary) {/*...*/}
  public void modyfikuj (Wpis stary, Wpis nowy) {/*...*/}
  public Vector<Wpis> wybierz (String naz, String adr) {/*...*/}
}
Przed wstawieniem nowego wpisu do swojej kolecji należy sprawdzić, czy taki sam wpis już istnieje (wtedy nie wstawiamy). Przy usuwaniu i modyfikacji wpisów należy najpierw odszukać zadany wpis w kolecji. We szystkich wymmienionych przypadkach wykorzystaj metodę compareTo() zdefiniowaną w interfejsie Comparable i zaimplementowaną w klasie Wpis.

Najważniejszym mechanizmem w tym programie ma być jednak wczytanie całej książki teleadresowej z pliku umieszczonego w lokalnym systemie (nazwę tego pliku przekaż do programu poprzez argumenty wywołania) przed uruchomieniem aplikacji oraz zapis książki teleadresowej do pliku przed jej zamknięciem. Przy zapisywaniu danych i ich odczytywaniu wykorzystaj technologię serializacji (należy zapisać albo odczytać cały zbiór danych typu Vector<Wpis>).

 

Labolatorium 7 (8.01.2011): grafika (śledzenie kursora myszy)

Zadanie 1 (4 punkty)

Napisz aplikację okienkową w technologii Swing, która będzie wypisywać współrzędne kursora myszy, o ile znajduje się on na powierzchi roboczej okna. Zdefiniuj w tym celu swój własny panel, który będzie reagować na zdarzenia myszy i który będzie wypisywał informację o jej bieżącym położeniu. class MójPanel extends JPanel
{
  private int mx, my; // współrzędne myszy
  private boolean wewn; // czy kursor jest na panelu

  private MouseAdapter mysz = new MouseAdapter()
  {
    public void mouseMoved (MouseEvent ev)
    {
      wewn = true;
      mouseDragged(ev);
    }
    public void mouseDragged (MouseEvent ev)
    {
      mx = ev.getX(); my = ev.getY();
      MójPanel.this.repaint();
    }
    public void mouseEntered (MouseEvent ev)
    {
      wewn = true;
      mx = ev.getX(); my = ev.getY();
    }
    public void mouseExited (MouseEvent ev)
    {
      wewn = false;
      MójPanel.this.repaint();
    }
  };
  public void paintComponent (Graphics gr)
  {
    super.paintComponent(gr);
    /*...*/
  }
  public MójPanel ()
  {
    addMouseListener(mysz);
    addMouseMotionListener(mysz);
  }
}
Metoda paintComponent() jest odpowiedzialna za narysowanie obiektu w oknie. Neleży ją więc uzupełnić o wypisywanie informacji o położeniu myszy na panelu albo o fakcie przebywania myszy poza panelem.

Zadanie 2 (6 punktów)

Napisz aplikację okienkową w technologii Swing, która będzie zawierała panel z oczami patrzącymi w stronę kursora myszy, o ile znajduje się on na powierzchi roboczej okna. Jeśli kursor wyjedzie poza powierzchnię panelu to oczy mają się pozamykać. Tłem panelu niech będzie obraz (w formacie gif albo jpg) o odpowiednio dużych rozmiarach.

Ważnym elementem tej aplikacji będzie oko, czyli odpowiednio sparametryzowana klasa Oko. W wersji minimalnej każdy obiekt takiej klasy powinien posiadać współrzędne środka oka, jego promień i kolor tęczówki. class Oko
{
  private int x, y, r; // współrzędne oka i jego promień
  private Color tęczówka; // kolor tęczówki

  public Oko (int x, int y, int r, Color t)
  {
    if (t==null||r<4) throw new NullPointerException();
    this.x = x; this.y = y; this.r = r&-2;
    tęczówka = t;
  }
  public void maluj (Graphics gr, int mx, int my, boolean otwarte)
  {
    if (otwarte)
    {
      int dx = mx-x, dy = my-y, zx = mx, zy = my;
      double dr = Math.sqrt(dx*dx+dy*dy);
      if (dr>r/2) { zx = (int)(x+(r/2)*(dx/dr)+0.5); zy = (int)(y+(r/2)*(dy/dr)+0.5); }
      gr.setColor(Color.WHITE);
      gr.fillOval(x-r,y-r,2*r-1,2*r-1);
      gr.setColor(tęczówka);
      gr.fillOval(zx-r/2,zy-r/2,r-1,r-1);
      gr.setColor(Color.BLACK);
      gr.drawOval(zx-r/2,zy-r/2,r-1,r-1);
      gr.drawOval(x-r,y-r,2*r-1,2*r-1);
    }
    else
    {
      gr.setColor(Color.WHITE);
      gr.drawLine(x-r,y,x+r,y);
      gr.setColor(Color.BLACK);
      gr.drawLine(x-r,y-1,x+r,y-1);
      gr.drawLine(x-r,y+1,x+r,y+1);
    }
  }
}
W swoim programie utwórz kilka parz oczu i umieść je na panelu w takich miejscach, aby pasowały do tła. W tym celu wygodnie będzie wyświetlać położenie kursora myszy na panelu. Przykład takiej aplikacji jest pokazany poniżej.

Oczy i obraz tła niech będa składowymi panelu, na którym będą rysowane. class MójPanel extends JPanel
{
  private int mx, my; // współrzędne myszy
  private boolean wewn; // czy kursor jest na panelu
  private ImageIcon obraz; // obiekt z obrazem odczytanym z pliku
  private Vector zbiór = new Vector(); // kolekcja oczu

  public void dodajOko (Oko oko) {/*...*/}
  public void usuńOczy () {/*...*/}
  private MouseAdapter mysz = new MouseAdapter() {/*...*/}
  public void paintComponent (Graphics gr)
  {
    obraz.paintIcon(this,gr,0,0);
    for (Oko oko: zbiór) oko.maluj(gr,mx,my,wewn);
    /*...*/
  }
  public MójPanel (ImageIcon ii)
  {
    obraz = ii;
    addMouseListener(mysz);
    addMouseMotionListener(mysz);
  }
}
Przy tworzeniu obiektu ImageIcon należy podać nazwę pliku z obrazkiem.

Egzamin ustny (10 punktów)

 

Zadania dodatkowe (16/23.01.2011): Java (różne programy)

Zadanie 1 (3 punkty)

Napisz program konsolowy, który dla zadanych poprzez argumenty wywołania liczb naturalnych n i k wyliczy i wypisze wartość symbolu Newtona (nk), przy czym n≥k≥0.

Do wyliczenia symbolu Newtona zdefiniuj metodę rekurencyjną zgodnie ze wzorem:
    (n0) = (nn) = 1 dla n≥0
    (nk) = (n-1k-1) + (n-1k) dla 0<k<n
W przypadku podania niewłaściwych co do wartości argumentów (któraś liczba jest ujemna albo n<k albo n jest zbyt duże - wartość krytyczną wyznacz eksperymentalnie) metoda ma zgłosić wyjątek IllegalArgumentException.

Zadanie 2 (4 punkty)

Napisz program konsolowy, który będzie przekształcał liczby zapisane w postaci arabskiej na liczby w zapisie rzymskim i na odwrót.

Program powinien wejść w nieskończoną pętlę, wczytując ze standardowego wejścia kolejne liczby, rozpoznawać w jakim systemie są zapisane (rzymskim czy arabskim) i wypisywać je w drugim systemie liczbowym. Gdy użytkownik wpisze pustą linię, to program powinien zakończyć działanie.

Twój program powinien korzystać z napisanej przez ciebie klasy usługowej RzymArab: public final class RzymArab
{
  private static String[] liczby =
    {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
  public static int rzym2arab (String rzym) throws NumberFormatException
    {/*...*/}
  public static String arab2rzym (int arab) throws IllegalArgumentException
    {/*...*/}
}
Ewentualne błędy formatu bądź wartości argumentów sygnalizuj za pomocą wyjątków.

Zadanie 3 (5 punktów)

Napisz program konsolowy, który liczby całkowite zadane poprzez argumenty wywołania programu wypisze na standadowym wyjściu w postaci słownej w języku polskim (można zastąpić polskie znaki diakrytyczne literami z alfabetu angielskiego).

Wykorzystaj w swoim programie statyczne tablice napisów z liczebnikami: String[] jednosci = {"", "jeden", "dwa", ..., "dziewietnascie"};
String[] dziesiatki = {"", "dziesiec", "dwadziescia", ..., "dziewiecdziesiat"};
String[] setki = {"", "sto", "dwiescie", ..., "dziewiecset"};
Argumenty, które nie dadzą się przekształcić do liczb całkowitych należy zignorować.

Zadanie 4 (6 punktów)

Napisz program konsolowy, który porówna ze sobą zawartości dwóch plików tekstowych z dokładnością do białych znaków w obrębie niepustych linii (linie puste należy ignorować).

Nazwy plików mają zostać przekazane do programu poprzez argumenty wywołania. Po napotkaniu pierwszej różnicy program powinien wypisać numer wiersza i numer pozycji w wierszu (dla obu plików), w którym wykrył różnicę, po czym przerwać dalsze przetwarzanie.

Zadanie 5 (7 punktów)

Napisz aplikację okienkową w technologii Swing, która będzie przeliczała zadaną długość na różne jednostki. W twojej aplikacji powinno się znajdować pole tekstowe JTextField do wpisania długości oraz listę JList do wyboru jednostek.

Działanie aplikacji powinno przebiegać według następującego scenarisza: użytkownik wybiera jednostkę długości; następnie wpisuje liczbę rzeczywistą do pola tekstowego; wreszcie zmienia jednostę długości, w wyniku czego poprzednio wpisana wartość zostaje przeliczona na nowe jednostki (w taki sposób aby zadana na początku długość nie uległa zmianie). Zaprogramuj w swojej aplikacji zdarzenie związane ze zmianą zaznaczenia na liście ListSelectionEvent.

Lista z jednostakim długości powinna obejmować co najmniej 12 różnych miar. Obowiązkowo mają się na niej znaleźć milimety, mety, kilomety, mile, jardy i cale. Inspiracją do wyboru jednostek może być wikipedia: pozaukładowe jednostki miary.

Egzamin

Na ostatnich zajęciach będzie przeprowadzony egzamin w postaci testu, ewentualnie uzupełniony o odpowiedź ustną. Na teście będzie 8 pytań; w trakcie odpowiedzi ustnej student dostanie co najmniej 3 pytania - w sumie będzie można dostać do 10 punktów z egzaminu. Egzamin uznam za zdany, gdy student dostanie w sumie co najmniej 4 punkty za swoje odpowiedzi. Oto lista zagadnień, które będą obowiązywały na egzaminie:

  1. Struktura programu; funkcja main().
  2. Pakiety; importowanie pakietów.
  3. Typy pierwotne i referencje.
  4. Rzutowanie; operator instanceof.
  5. Instrukcje sterujące (instrukcja blokowa, warunkowa, wyboru,instrukcje pętli, kontynuacja, przerwanie, powrót z funkcji).
  6. Tablice; tablice wielowymiarowe.
  7. Łańcuchy znakowe String; standardowe operacje na ciągach znakowych.
  8. Zmienne; zasięg zmiennych; inicjalizacja zmiennych; stałe.
  9. Definicja klasy; składowe w klasie.
  10. Tworzenie obiektów; konstuktory; odśmiecanie.
  11. Składowe statyczne; inicjalizacja pól statycznych; dostęp do metod statycznych.
  12. Dziedziczenie; polimorfizm.
  13. Interfejsy; klasy abstrakcyjne.
  14. Wyjątki; Hierarchia wyjątków; zgłaszanie wyjątków; łapanie wyjątków.
  15. Strumienie; serializacja; operacje na plikach.
  16. Kolekcje standardowe.
  17. Graficzny interfejs użytkownika Swing.
  18. Obsługa zadarzeń GUI.

Ranking

Hasło to: statystyka

Instytut Informatyki