Konsultacje:
Adres:
Instytut Informatyki2 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.
Literatura papierowa polskojęzyczna:
Literatura papierowa anglojęzyczna:
Literatura elektroniczna anglojęzyczna:
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.
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.
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
W klasie Rysunek powinna się znaleźć metoda wypisująca
zawartość całej kolekcji na standardowe wyjście:
{
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";
}
}
public void drukuj ()
Metoda drukuj() oprócz wypisania wszystkich figur musi
również wypisać prolog i epilog całego dokumentu
postscriptowego.
{
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");
}
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:
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
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).
{
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)
{ /* ... */ }
}
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.
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>>
Dość trudnym zadaniem w klasie Węzeł jest
zaprogramowanie metod usuwających dane ze struktury, dlatego
ich przykładową implementację podaję poniżej:
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
// ...
}
private TYP kopiuj (Węzeł w)
Analogiczne metody w klasie DrzewoBST są dużo prostsze:
{ 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;
}
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).
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ń:
Na przykład wyrażenie (7-x)*2 należy zdefiniować
następująco:
Wyrazenie w =
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.
new Mnozenie(
new Odejmowanie(
new Liczba(7),
new Zmienna("x")
),
new Liczba(2)
);
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;
Najpierw wydrukuj swój program metodą toString()
a potem wykonaj go.
silnia = 1;
var n;
read n;
if (n>1)
{
var i;
i = 2;
while (i<=n)
{
silnia = silnia*i;
i = i+1;
}
}
write silnia;
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
Oba parametry (plik i katalog) wskaż za pomocą obiektu
JFileChooser.
{
protected File plik, katalog;
// ...
}
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>
Wszystkie wpisy należy przechowywać w kolekcji typu
Vector<Wpis>.
{
public final String nazwa, adres;
// ...
}
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
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.
{
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) {/*...*/}
}
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>).
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
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.
{
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);
}
}
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
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.
{
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);
}
}
}
Oczy i obraz tła niech będa składowymi panelu, na którym będą
rysowane.
class MójPanel extends JPanel
Przy tworzeniu obiektu ImageIcon należy podać nazwę
pliku z obrazkiem.
{
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
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);
}
}
Egzamin ustny (10 punktów)
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
Ewentualne błędy formatu bądź wartości argumentów sygnalizuj
za pomocą wyjątków.
{
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
{/*...*/}
}
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"};
Argumenty, które nie dadzą się przekształcić do liczb
całkowitych należy zignorować.
String[] dziesiatki = {"", "dziesiec", "dwadziescia", ..., "dziewiecdziesiat"};
String[] setki = {"", "sto", "dwiescie", ..., "dziewiecset"};
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.
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:
Hasło to: statystyka