www.plusplanet.de
Schulinfos von F. Töns

Informatikkurs der Q2, Abi 2019



16.04.2019
Bitte schaut in die Mathe-LK-Kategorie. Sorry für die versehentliche falsche Zuordnung.


28.03.2019
Fehlendes Material für den Test in der kommenden Woche:
Know-How übers Silicon-Valley: 20190305_siliconvalley_zusf.pdf

Vokabeln bei der Soundprogrammierung:

Übersteuerung/Clipping:
Bei zu hoher Lautstärke kann "der y-Wert" nicht mehr dargestellt werden, und es wird zwangsweise die Auslenkung bzw. die Amplitude begrenzt.

Frequenz (Einheit: Hertz) und Unterschied Frequenz und Amplitude
Frequenz: Anzahl der Schwingungen pro Sekunde
Amplitude: Größe der Auslenkung, "Höchster y-Wert"


Die Samplerate ist die Frequenz, mit der ein Audiosignal abgetastet wird.
Falls die Frequenz des aufgenommenen Signals höher als die der Samplerate ist, wird auf jeden Fall das Signal zerstört.

Frequenzbereich, welcher vom menschlichen Gehör wahrgenommen werden kann: Etwa 50Hz bis 18000Hz (Wobei die Werte abhängig sind: sowohl vom Alter des Menschen als auch vom Schalldruck des Signals)




21.03.2019
Mini-Skript "Neuronale Netze" www.plusplanet.de/pp_files/20190311_eigenes_Skript.zip
Um die Zip-Datei zu öffnen, benötigt man ein Passwort. In diesem Fall ist es der Vorname des Namenspatrons unserer Schule (kleingeschrieben).
Beispiel: Hieße unsere Schule "Konrad-Adenauer-Grundschule Düsseldorf" so wäre das Passwort "konrad".

Ergebnisse aus dem Unterricht

UND

Neuron A  ---- Gewicht: 1 -----|
                               |
                               >---- Ausgabeneuron X
                               |     (Schwellwert: 2  )
Neuron B  ---- Gewicht: 1 -----|

(0,0) -> 0
(0,1) -> 0
(1,0) -> 0
(1,1) -> 1

NOT

Neuron A  ---- Gewicht:  -1  -----> Ausgabeneuron X
                                 (Schwellwert:  0 )
(0) -> 1
(1) -> 0



21.02.2019

Erstelle eine MindMap zum Thema "Künstliche Intelligenz"

Lade dazu eine Version von FreeMind herunter und installiere sie:
http://freemind.sourceforge.net/wiki/index.php/Download

Der Wikipedia-Artikel zur Künstlichen Intelligenz liefert einen guten Überblick über das Thema.

Speichere dein Ergebnis erstens als .mm Datei ab (FreeMind-Datenformat) und exportiere die Mindmap auch als png (damit wir eure Ergebnisse auch schnell ohne vorherige Installation begutachten können)

Ähnlich wie die Fakten zum Silicon Valley werden wir uns zunächst ein Bild über das Thema machen. Welchen Bereich wir tatsächlich programmtechnisch umsetzen werden (können), werde ich später noch entscheiden.


19.02.2019

Was man über das Silicon Valley wissen sollte:
(Bitte schreibt einen kurzen Text über die jeweiligen Euch zugewiesenen Themen. Abgabe beim nächsten Mal am besten elektronisch: Stick, Mail o.ä.)

G: (M:)
Welcher Anteil technischer Konzerne sitzt im SV?
Welche sind die größten Unternehmen dort?

M: (G:)
Warum (warum nicht) sollte ein Unternehmen ins SV gehen?
Vergleich: deutsche Startups und SV-Startups.

D:
Wie groß ist die wirtschaftliche Bedeutung des SV? BIP?

L: G:
Geographische Lage? Warum dort und nicht anderswo?

Alt: L:
Microsoft sitzt nicht im SV. Warum? Vor- und Nachteile?

D: Ali:
Welche technischen Errungenschaften sind dem SV zuzuschreiben?

Alt: Ali:
Skandale?



12.02.2019
Fragen/Positionen zum Silicon Valley:
Warum bleiben die großen Unternehmen noch dort?
Begünstigt die geographische Nähe so vieler Unternehmen nicht Kartelle?
Silicon Valley ist eine Dreckschleuder.

L: Umweltaktivist
D: Firmenchef
A: Regierungsvertreter
G: Arbeiter bei Foxconn in China
M: Kinder, die Kobalt im Kongo abbauen



07.02.2019
Download des Johnny-Simulators:
https://sourceforge.net/projects/johnnysimulator/


22.01.2019
Hausaufgabe zu Donnerstag:

Erstellt als Abschluss zu unserer Unterrichtsreihe "Theoretische Informatik und formale Sprachen" einen Text, in dem folgende Begriffe vorkommen:
reguläre Sprache
nichtreguläre Sprache
großes Sigma
kontextsensitive Sprache
kontextfreie Sprache
Grammatik
Terminal/ Nichtterminalsymbol
Automat:
.Kellerautomat
.Nichtdeterministischer A.
.Deterministischer A.
Turing-Maschine
Chomsky-Hierarchie
Syntax / Semantik


21.01.2019
Informationen zum Johnny Modellrechner von Peter Dauscher:
https://wiki.zum.de/wiki/Rechnerarchitektur_mit_Simulator_JOHNNY

10.01.2019
Turing-Maschine
http://math.hws.edu/eck/js/turing-machine/TM.html

13.12.2018
Rohbau eines Java-Programmes, welches einen einfachen Automaten darstellt:


public class Haupt {  
    
    public static void main() {
        automat("0000");
        automat("0001");
        automat("0010");
        automat("0011");
        automat("0100");
        automat("0101");
        automat("0110");
        automat("0111");
        automat("1000");
        automat("1001");
        automat("1010");
        automat("1011");
        automat("1100");
        automat("1101");
        automat("1110");
        automat("1111");
    }
    
    
    public static void automat(String eingabe) {
        // Zustand
        char z;
        char startzustand = 's';
        
        z = startzustand;
        
        for(int i = 0; i < eingabe.length(); i++) {
            char akt = eingabe.charAt(i);
            
            if(z == 's') {
                if(akt == '0') {
                    z = 's';
                } else if(akt == '1') {
                    z = 'a';
                } else {
                  z = '§'; // Fehlerzustand  
                }
            } else if (z == 'a') {
                if(akt == '0') {
                    z = 'b';
                } else if(akt == '1') {
                    z = 's';
                } else {
                  z = '§'; // Fehlerzustand  
                }
            } else if (z == 'b') {
                if(akt == '0') {
                    z = 'a';
                } else if(akt == '1') {
                    z = 'b';
                } else {
                  z = '§'; // Fehlerzustand  
                }
            }
            
        }
        
        // Aktzeptierende Zustände abprüfen:
        if(z == 's') {
            System.out.println("Wort "+eingabe+" wird akzeptiert! Endzustand: "+z);
        } else {
            System.out.println("Wort "+eingabe+" wird nicht akzeptiert! Endzustand: "+z);
        }
        
    }
}





12.12.2018
Übungsmaterial für die Klausur:
In folgendem Dokument sind Lösungen zu ausgewählten Aufgaben unseres Skriptes zusammengefasst. Vorsicht: die Lösungen sind nicht alle auf Korrektheit überprüft worden! Im überwiegenden Teil haben wird die Aufgaben aber in den Informatikstunden besprochen. Es dürften also nicht mehr massenweise Fehler auftreten.
Formale_Sprachen_Loesungen_zum_Skript_low.pdf

Erklärung, wie man einen DEA in einen NEA wandelt:
nea_in_dea_wandeln.pdf

Beispiele zur Minimierung von DEA. (Zwei der drei Beispiele beginnen mit einem NEA, der zunächst in einen DEA gewandelt wird um dann minimiert zu werden)
dea_minimieren.pdf



11.12.2018
Klausurthemen für den 18.12.18:

Oberthema: Formale Sprachen, insbesondere reguläre Sprachen
Literatur: http://www.oberstufeninformatik.de/theorie/Formale_Sprachen.pdf
Die Seiten 1 bis 34 des Skripts sind Grundlage der Klausur.

Darüberhinaus werden noch folgende zwei Themen in der Klausur abgefragt:
* Umwandlung eines NEA in einen DEA (über die Erzeugung einer neuen Tabelle für die Zustandsübergänge). Ein so erzeugter Automat kann sehr groß werden. Daher ist es sinnvoll, über Minimierung von DEAs zu reden:
* Minimierung eines DEA über die Ermittlung verschmelzbarer Zustände. (Siehe z.B. https://www.youtube.com/watch?v=KkEoqDtyMAs )

Wesentliche Zusammenhänge bezüglich regulärer Sprachen sind:
* Ein DEA ist (im Prinzip durch einfaches "Abschreiben") in eine (reguläre) Grammatik wandelbar.
* Eine reguläre Grammatik ist in einen DEA wandelbar. Ggf erhält man bei der Umwandlung der Grammatikregeln einen NEA (denn z.B. Regel S -> aA | aB | aS ist ja in einer regulären Grammatik erlaubt ) , der aber in einen DEA umgewandelt werden kann.
* Eine nichtreguläre Grammatik kann trotzdem eine reguläre Sprache erzeugen. Beispiel: "S -> aa | bS ". Diese Grammatik ist offensichtlich nicht regulär (Verständnisfrage: warum?), aber dennoch bereitet es nur wenig Mühe, einen passenden DEA zu entwerfen, der die passende Sprache erkennt (Verständnisfrage: wie sieht dieser aus?)
* Ein NEA kann in einen DEA umgewandelt werden.
* Ein DEA ist möglicherweise minimierbar, d.h. Zustände können verschmolzen werden, so dass ein Automat entsteht, der die gleiche Sprache akzeptiert, jedoch weniger Zustände benötigt.


03.12.2018
Der Download von JFLAP geht über diese Seite:
http://www.jflap.org/jflaptmp/
Falls das nicht unmittelbar funktioniert, muss man über
http://www.jflap.org/getjflap.html
gehen und erst ein paar Fragen beantworten.


27.11.2018
Hausaufgabe bis zum 29.11:
Seite 24 Nr 4.
Dazu muss man die Seiten davor in etwa verstanden haben.

22.11.2018
Hausaufgabe bis zum 27.11:
Seite 16 Aufgaben  3 und Seite 17 Aufgabe 5.

20.11.2018
Hausaufgabe bis zum 22.11:
Seite 16 Aufgaben 1 bis 3.

13.11.2018
Der erste Link auf
http://www.oberstufeninformatik.de/theorie/index.html
ist ein Skript zu theoretischer Informatik:
http://www.oberstufeninformatik.de/theorie/Formale_Sprachen.pdf

Im Unterricht wurde bereits  bearbeitet: S6 Aufgabe 1
Als Hausaufgabe soll bearbeitet werden: S10 Aufgabe 3 ("Bunny Banana")

Folgende Aufgaben sollen auf jeden Fall bearbeitet werden:
S6 A1
S10 A1, A2, A3, A4
S11 A
S16 A1, A2, A3, A4, A5



30.10.2018
Lies folgende Artikel:
https://de.wikipedia.org/wiki/Tiefensuche
https://de.wikipedia.org/wiki/Breitensuche

Mit "Suche" ist gemeint, dass in der Regel ein bestimmter Knoten gesucht wird. Dabei wird der Graph in einer bestimmten Reihenfolge durchlaufen. Wenn das gesuchte Element aber gar nicht vorhanden ist, werden alle Knoten des Graphen besucht (und erfolglos durchsucht). Diese Besuchsreihenfolge soll nun Thema sein.

Versuche dann für jedes Verfahren vorherzusagen, wie im Beispielprogramm (wird bereitgestellt) mit dem Startort "Deutschland" die Besuchsreihenfolge ist (wobei immer die Himmelsrichtung-Reihenfolge n,o,s,w eingehalten wird).

Implementiere schließlich die Tiefensuche und dann die Breitensuche.

Klausurthemen für die IF-Klausur am 6.11.2018:
* Rekursion verstehen, erklären und programmieren können
* Begriff: Baum (und dabei Knoten, Kante, Blatt, Höhe)
* Begriff: Graph (und dabei Knoten, Kante, gerichtet bzw. ungerichtet )
* Rekursiver Durchlauf (Traversierung) eines Baumes: (siehe z.B.: https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/  )
***** inorder: Links Wurzel Rechts
***** preorder: Wurzel Links Rechts
***** postorder: Links Rechts Wurzel
* Expression-Baum (also ein Baum, in welchem ein mathematischer Term gespeichert ist)
* Binärer Suchbaum (Abiturklasse benutzen können)
***** Einfüge- und Löschoperation bei binären Suchbäumen verstehen
* Tiefensuche und Breitensuche bei Graphen.

* Parsen eines Mathematischen Ausdrucks mit Hilfe eines einfachen Automaten und Übertragung der Idee in Programmcode (wir hatten zwei Zustände unterschieden - je nachdem, ob noch ein "Zahlteil" kommt oder nicht)






09.10.2018
Lade folgende Dia-Datei herunter:
20181009_binary_search_tree.dia

Gib dann eine Reihenfolge von Einfüge- und Lösch-operationen an um dann die jeweilge Baumstruktur zu zeichnen.

Programmiere später (erst in Absprache mit Herrn Töns) eine Methode "size" für die BinarySearchTree-Klasse.


25.09.2018
Lies:
https://de.wikipedia.org/wiki/Baum_(Datenstruktur)
https://de.wikipedia.org/wiki/Suchbaum
Und überfliege folgenden Artikel:
https://de.wikipedia.org/wiki/Binärer_Suchbaum


Aufgaben:
1) Teste das bereitgestellte Programm und interpretiere die Ausgabe
2) Erkläre, warum der entstehende Baum so aussieht, wie er aussieht.
3) Erzeuge einen "entarteten" Baum, der letztlich nichts anderes als eine (verkettete) Liste ist.
4) Erzeuge einen Baum so, dass die Personen nach Geburtsdatum geordnet ausgegeben werden.
5) Lies https://de.wikipedia.org/wiki/Binärbaum#Löschen
6) Lies und verstehe die Methode "remove" aus der Klasse BinarySearchTree und mache dir die Arbeitsweise an Beispielen klar.
7) Die Methode remove in der Abiturklasse benutzt die "optimierte" Version aus Fall B des Artikels aus Punkt 5). implementiere die Einfache, nicht optimale Version!





04.09.2018
Erkundige dich über ein einfaches Grafikformat:
https://de.wikipedia.org/wiki/Portable_Anymap
Lies insbesondere das Beispiel zu dem Bild mit dem Buchstaben "FEEP" (also mit dem Format-Code P2) - damit sollte man ziemlich einfach auch per Java Grafikdateien erstellen können.

Tipps für kleine Programme:

import javax.swing.JOptionPane;
public class InputDialogTest{
    public static void main(String[] bla){
        String eingabe = JOptionPane.showInputDialog(null,
            "Geben Sie Ihren Namen ein",
            "Eine Eingabeaufforderung",
            JOptionPane.PLAIN_MESSAGE);
        System.out.println("Die Eingabe war: "+eingabe);
    }
}



30.08.2018
Link zum Kurz-Lehrplan:
20180830_SiLP_IF.png

Link zum Karteikartenstapel:
http://www.plusplanet.de/flashmeister


28.06.2018

Liebe Informatiker

Leider ist zum "Schuljahressaisonendestress" und den Nachprüfungen auch noch eine Erkältung dazugekommen. D.h.: Die Noten sind immer noch nicht fertig. (Die zwei Klausuren sind aber korrigiert und liegen bei Frau Schleier)
Noch vor der Zeugniskonferenz werde ich Euch kontaktieren, um Euch Eure Noten mitzuteilen.

Für heute wären die Hacking-Challenges auf https://0xf.at eine tolle Übung gewesen - aber bei uns wird die Seite ja leider rausgefiltert. Ich habe leider keine Zeit gefunden, diese Filtereinstellung anzupassen. Aber ich würde euch gerne ein paar Tipps für die ersten Level geben, die ihr dann zuhause knacken könnt. Möglicherweise könnt ihr auch euer Handy benutzen - dann müsst ihr aber den HTML-Quelltext anzeigen können. Bei meinem Samsung-Handy geht das, indem man der normalen Adresse https://0xf.at/play/1 den Befehl view-source: voranstellt, also die Adresse view-source:https://0xf.at/play/1 aufruft.

Tipps zu ....
Level 1: einfach nur Quelltext anschauen und Javascript-Code entziffern
Level 2: Informiere dich über URL-Encoding
Level 3: Nicht veräppeln lassen!
Level 4: Java-Script-Code genau lesen - was wird als Passwort genau akzeptiert?
Level 5: Informiere Dich über ASCII-Codes

Den Rest verrate ich nicht ... es soll ja eine Herausforderung sein!




19.06.2018
Aufgabe 1: Lies in der Wikipedia die Artikel OSI-Modell und Internetprotokollfamilie.
Formuliere dann mindestens eine Frage mit richtigen und falschen Antworten, die in einem Multiple-Choice Test verwendet werden könnten. Der Test könnte im nächsten Schuljahr in diesem Kurs gestellt werden.

Aufgabe 2: Wähle einen der folgenden Computer-Attacken aus und verstehe sie so, dass du die Attacke in einem 5-Minuten-Referat erklären kannst.
Übersicht: Siehe Wikipedia Kategorie Sicherheitslücke.
Mögliche konkrete Angriffe (die wir mit unserem Wissen erklären können):
Smurf-Angriff, Ping Of Death, Phreaking, RogueDHCP, Session Hijacking, SQL-Injection, SYN-Flood, Teardrop-Attacke, Header_injection, DHCP-Starvation-Attack, ARP-Spoofing, Forkbomb, Land-Attacke


17.05.2018
Klausurthemen:

Grundlagen:
* Code auf Papier ausführen (Tabellen anlegen und Variablenwerte protokollieren)
* Programme "exakt lesen" (Methode, Eigenschaft etc. immer identifizieren können)
* Einfache Algorithmen selbst schreiben können.
* Mit Datenstruktur Array und List umgehen können.

Eigentliche Themen:
* Client-Server-Programmierung
** Kenntnis der Abiturklassen
** Teile eines Clients oder Servers programmieren können (Z.B. Teile eines Chat-Clients oder eines Additionsservers)
* Kryptografie
** Caesar-Verschlüsselung und Vigenere verstehen
** Kerckhoffsches Prinzip erläutern können
* Diffie-Hellman-Schlüsselaustausch
** durchführen können "per Hand" und mit dem GTR
** Modulo-Exponentiation auch bei größeren Zahlen durchführen können (falls es zu Überläufen kommt)
** Diffie-Hellman-Helfer-Programm verstehen (s.u.)



15.05.2018
20180517_diffie_hellman_helfer.zip


IFQ1 am 15.5.2018
-----------------
1. Caesar-Verschlüsselung: Idee, Angriff (bruteforce, Häufigkeit),
Zitat Wikipedia:
Da die Größe des Schlüsselraums nur 25 beträgt, liegt nach Ausprobieren spätestens nach dem 25. Versuch der Klartext vor. Eine erschöpfende Schlüsselsuche (Exhaustion) ist bei der Caesar-Verschlüsselung trivial realisierbar. Da dies auch ohne Computer oder Rechenmaschine mit geringem Aufwand möglich ist, bestand die Sicherheit der Caesar-Verschlüsselung schon zu ihren Anfängen nicht auf der Geheimhaltung des Schlüssels, sondern im Wesentlichen auf der Geheimhaltung des Verfahrens, und entspricht damit nicht dem im 19. Jahrhundert postulierten Prinzip von Auguste Kerckhoffs.

Begriffe:   Klartext: Die von Menschen lesbare Nachricht
            Geheimtext: Die verschlüsselte Nachricht (nicht unmittelbar menschenlesbar)
            Kryptosystem: Ein Verfahren, welches einen Klartext durch Anwendung eines Schlüssels in einen Geheimtext wandelt und auch wieder zurückwandelt
            Schlüssel: (s. Kryptosystem)
            Klartextalphabet (Alle möglichen Symbole, die im Klartext vorkommen dürfen)
            Geheimtextalphabet (Alle möglichen Symbole, die im Geheimtext vorkommen dürfen)
            Schlüsselalphabet (Alle möglichen Symbole, die im Schlüssel vorkommen dürfen)
            
Beim Kryptosystem Caesar gilt: Sowohl Klartext als auch Geheimtext sind die 26 Buchstaben des lat. Alphabets. Schlüsselalphabet sind alle ganze Zahlen im Intervall [0;25]

2. Kerckhoffsches Prinzip (1883)
Verkürzt: "Die Sicherheit eines Verschlüsselungsverfahrens beruht auf der Geheimhaltung des Schlüssels anstatt auf der Geheimhaltung des Verschlüsselungsalgorithmus."
Problematisches Gegenprinzip: "Security through obscurity": Sicherheit durch Geheimhaltung des Verschlüsselungsalgorithmus selbst.
Warum ist das Problematisch? U.a. wegen:
* Es ist viel schwieriger, einen Algorithmus geheim zu halten als einen Schlüssel.
* Es ist schwieriger, einen enttarnten Algorithmus durch einen anderen zu ersetzen als einen enttarnten Schlüssel.

3. Vigenere Verschlüsselung: Idee, Angriff durch Häufigkeitsanalyse bei kurzen(!) Schlüsseln und langen(!) Texten.
Wenn Schlüssellänge >= Klartextlänge und Schlüssel echt zufällig gewählt (nicht aus dem Wörterbuch) gilt, dann ist Vigenere tatsächlich unknackbar (da identisch mit One-Time-Pad)

Beispiel (ohne aufwändiges Vigenere-Quadrat): Klartext: "tim ist spion", Schlüssel "bagdad"
Klartext:                  t i m i s t s p i o n
Schluessel:                b a g d a d b a g d a
(Verschiebung)             1 0 6 3 0 3 1 0 6 3 0
Geheimtext:                U I S L S W T P O R N

4. Kryptosystem Digi-Vigenere: Alle Alphabete bestehen nur aus {0,1}.
Beispiel:
Klartext:         00100110
Schluessel:       01001100
Geheimtext:       01101010
(Hinweis: Dies entspricht einer XOR-Verknüpfung ("entweder-oder" - aber nicht beides) von Klartext und Schlüssel. Hier ist der Schlüssel genauso lang wie der Klartext, so dass in diesem Fall die Sicherheit eines One-Time-Pads gegeben ist)

5. Fazit: Bereits Digi-Vigenere erlaubt es uns, beliebige Daten ziemlich sicher zu Verschlüsseln. (Vorsicht: In der Praxis sind Klartexte lang und Schlüssel kurz. In diesem Fall ist Digi-Vigenere sehr unsicher. Es gibt für diese Fälle wesentlich bessere - aber auch kompliziertere Kryptosysteme).
Allgemeines Problem bleibt bislang, dass ein Schlüssel immer im Geheimen ausgetauscht werden muss.

6. Diffie-Hellman-Schlüsselaustausch
Ein Verfahren, mit dem sich zwei Kommunikationspartner (online, für alle einsehbar) auf einen Schlüssel (z.B. für Digi-Vigenere) einigen können, ohne sich im Geheimen treffen zu müssen.
Wir nennen die Kommunikationspartner Alice und Bob. Ein Angreifer namens Carlo kann die Kommunikation belauschen.

Verfahren im Kurzen:
A)  Alice schlägt zwei Zahlen vor und schickt diese an Bob:
    Eine (große) Primzahl p und eine ganze Zahl g aus dem Intervall [1;p[
    Diese beiden Zahlen kann Carlo abhören.

B)  Alice denkt sich im geheimen für sich eine Zahl a aus dem Intervall [1;p[ aus.
    Alice berechnet x = g^a mod p
    Alice schickt x (für Carlo einsehbar) an Bob
    
C)  Bob denkt sich im geheimen für sich eine Zahl b aus dem Intervall [1;p[ aus.
    Bob berechnet y = g^b mod p
    Bob schickt y (für Carlo einsehbar) an Alice

D)  Alice berechnet s = y^a mod p
    Bob berechnet s = x^b mod p
    Die berechnete Zahl s ist bei Bob und Alice identisch, aber für Carlo nicht ohne Weiteres ermittelbar (§§ Details später)
    
E)  Die Zahl s kann nun als Schlüssel für ein symmetrisches Verschlüsselungsverfahren z.B. Digi-Vigenere benutzt werden.

7. Eigenschaften der Modulo-Rechnung:
A) 4*4 mod 3 = ((4 mod 3) * (4 mod 3)) mod 3 = 1
    (hilfreich um Zwischenergebnisse klein zu halten)
    
Idee beim obigen Schlüsselaustausch:
Alice rechnet: x = g^a mod p
Bob rechnet:   y = g^b mod p
Alice rechnet: s = y^a = (g^b)^a mod p
Bob rechnet:   s = x^b = (g^a)^b mod p


B) 2^4 mod 5 zu berechnen ist einfach (hier: 2^4 mod 5 = 16 mod 5 = 1)
    Aber aus 2^d mod 5 = 1 auf den Exponenten d zu schließen ist schwierig. Im Allgemeinen muss man probieren:
    
    Wertetabelle:   d  1 2 3 4
            2^d mod 5  2 4 3 1     also muss d gleich 4 sein.
    
8. Angriffsmöglichkeiten für den Lauscher Carlo:
Beispielkommunikation:
Alice schlägt vor: p = 13 g = 8
Alice denkt sich aus: a = 5
Alice rechnet: x = (8^5) mod 13 = 8
Bob denkt sich aus: b = 12
Bob rechnet: y = (8^12) mod 13 = 1
Alice rechnet den Schlüssel aus: s = y^a mod 13 = 1^5 mod 13 = 1
Bob rechnet den Schlüssel aus: s = x^b mod 13 = 8^12 mod 13 = 1

Carlo kennt die Zahlen: p = 13, g = 8, x = 8  , y = 1
Carlo versucht nun, die Zahl a zu ermitteln, indem er versucht, folgende Gleichung zu lösen:
  8 = 8^a mod 13
Carlo MUSS die Gleichung durch probieren lösen:
Wertetabelle:
         a: 1 2  3  4  5
8^a mod 13: 8 12 5  1  8




03.05.2018

Die Klasse MeinServer soll exakt dokumentiert werden. (Hinweis: "exaktes Lesen von Programmcode" ist hier gefragt). Wir beziehen uns auf den Quellcode, der hier (siehe etwas weiter unten) zu finden ist.
http://collabedit.com/py7hv


Beschreibe Schwächen und Angriffsszenarien für das Chatprotokoll. Dabei dürfen und müssen Vorannahmen getroffen werden. Relativ einfach scheint es zu sein, einen DOS-Angriff zu beschreiben (DOS = Denial Of Service, also eine Unbenutzbarmachung des Servers z.B. durch Überlastung oder andere Maßnahmen). Besonders spannend wären Angriffe, mit denen man andere Chatteilnehmer betrügen könnte.
http://collabedit.com/5c5eu

BlueJ-Projekt:
20180426_netzklassentest3_chat_Lehrerversion7.zip
Hinweis: Will man das Projekt daheim starten, so muss man natürlich erst den Server starten. Wenn man sich dann mit einem Client im Heimnetzwerk zum Server verbinden möchte, so benötigt man die IP-Adresse des Servers. Diese bekommt man unter Linux mit dem Terminal-Befehl "ifconfig" heraus. Unter Windows öffnet man die Kommandozeile (Start-Menü, Ausführen, CMD eintippen, dann im schwarzen Fenster: "ipconfig" eingeben)


Quelltext der Datei MeinServer.java

1. public class MeinServer extends Server {
2.     List<Nick> nicknames;
3.     public MeinServer(int pPort) {
4.         super(pPort);
5.         nicknames = new List<Nick>();
6.     }
7.
8.     public  void processNewConnection(String pClientIP, int pClientPort) {
9.         System.out.println("Incoming Connection from: "+pClientIP+" on Port "+pClientPort);
10.         Nick newNick = new Nick(pClientIP,pClientPort, pClientIP);  
11.         nicknames.append(newNick);
12.     }
13.
14.     public  void processMessage(String pClientIP, int pClientPort, String pMessage) {
15.         System.out.println("Processing Message from: "+pClientIP+" on Port "+pClientPort);
16.         System.out.println(" Message is: "+pMessage);
17.
18.         if(pMessage.length() >= 5) {
19.             if(pMessage.substring(0,5).equals("NICK:")) {
20.                 String newNick = pMessage.substring(5);
21.                 String oldNick = renameNick(pClientIP, newNick);
22.                 Nick n = retrieveNick(pClientIP);
23.                 mySendToAllNonMuted(n,"User "+oldNick+" is now called "+newNick);
24.             } else if(pMessage.substring(0,5).equals("MESG:")) {
25.                 String message = pMessage.substring(5);
26.                 Nick n = retrieveNick(pClientIP);
27.                 mySendToAllNonMuted(n,n.nickname+" says: "+message);
28.             } else if(pMessage.substring(0,5).equals("MUTE:")) {
29.                 Nick n = retrieveNick(pClientIP);
30.                 n.muted = true;
31.                 mySendToAllNonMuted(n,n.nickname+" is now muted.");
32.             } else if(pMessage.substring(0,5).equals("NOIS:")) {
33.                 Nick n = retrieveNick(pClientIP);
34.                 n.muted = false;
35.                 mySendToAllNonMuted(n,n.nickname+" is now de-muted.");
36.             } else if(pMessage.substring(0,5).equals("ONLN:")) {
37.                 String nicknames = getAllNicknames();
38.                 send(pClientIP, pClientPort, "ONLN:"+nicknames);            
39.             } else if(pMessage.substring(0,5).equals("PRIV:")) {
40.                 String payload = pMessage.substring(5);
41.                 int atIdx = payload.indexOf('@');
42.                 if(atIdx > 0) {
43.                     String toNickname = payload.substring(0,atIdx);
44.                     String message = payload.substring(atIdx+1);
45.                     System.out.println(" Private Message to:"+toNickname);
46.                     System.out.println(" Private Message is:"+message);
47.                     Nick toNick = retrieveNickByNickname(toNickname);
48.                     if(toNick != null) {
49.                         Nick n = retrieveNick(pClientIP);
50.                         send(toNick.clientIP, toNick.clientPort, n.nickname+" sends you a private message: "+message);
51.                     } else {
52.                         send(pClientIP, pClientPort, "The Nickname "+toNickname+" doesn't exist");
53.                     }
54.                 } else {
55.                     send(pClientIP, pClientPort, "Error: Malformed Request!");
56.                 }
57.             } else {
58.                 send(pClientIP, pClientPort, "Invalid Message: "+pMessage);                            
59.             }
60.         } else {
61.             send(pClientIP, pClientPort, "Invalid Message: "+pMessage);            
62.         }
63.     }
64.
65.     private void mySendToAllNonMuted(Nick emitter, String msg) {
66.         nicknames.toFirst();
67.         while(nicknames.hasAccess() ) {
68.             Nick pair = nicknames.getContent();
69.             if(!pair.muted) {
70.                 send(pair.clientIP, pair.clientPort, "From "+emitter.nickname+": "+msg );
71.             } else {
72.                 send(emitter.clientIP, emitter.clientPort, "From Server: User "+pair.nickname+" is muted!" );
73.             }
74.             nicknames.next();            
75.         }
76.
77.     }
78.
79.     public  void processClosingConnection(String pClientIP, int pClientPort) {
80.         System.out.println("Connection Closed by: "+pClientIP+" on Port "+pClientPort);
81.         deleteNick(pClientIP);        
82.     }
83.
84.     public void deleteNick(String clientIP) {
85.         nicknames.toFirst();
86.         boolean found = false;
87.         while(!found && nicknames.hasAccess() ) {
88.             Nick pair = nicknames.getContent();
89.             if(pair.clientIP.equals(clientIP)) {
90.                 found = true;
91.                 nicknames.remove();
92.             } else {
93.                 nicknames.next();
94.             }
95.         }
96.     }
97.
98.     public String renameNick(String clientIP, String newNick) {
99.         nicknames.toFirst();
100.         String result = "unknown";
101.         boolean found = false;
102.         while(!found && nicknames.hasAccess() ) {
103.             Nick pair = nicknames.getContent();
104.             if(pair.clientIP.equals(clientIP)) {
105.                 found = true;
106.                 result = pair.nickname;
107.                 pair.nickname = newNick;
108.             } else {
109.                 nicknames.next();
110.             }
111.         }
112.         return result;
113.
114.     }
115.
116.     public Nick retrieveNickByNickname(String nickname) {
117.         nicknames.toFirst();
118.         Nick result = null;
119.         boolean found = false;
120.         while(!found && nicknames.hasAccess()) {
121.             Nick pair = nicknames.getContent();
122.             if(pair.nickname.equals(nickname)) {
123.                 found = true;
124.                 result = pair;
125.             } else {
126.                 nicknames.next();
127.             }
128.         }
129.         return result;        
130.     }
131.
132.     public Nick retrieveNick(String clientIP) {
133.         nicknames.toFirst();
134.         Nick result = null;
135.         boolean found = false;
136.         while(!found && nicknames.hasAccess()) {
137.             Nick pair = nicknames.getContent();
138.             if(pair.clientIP.equals(clientIP)) {
139.                 found = true;
140.                 result = pair;
141.             } else {
142.                 nicknames.next();
143.             }
144.         }
145.         return result;        
146.     }
147.
148.     public String retrieveNickname(String clientIP) {
149.         nicknames.toFirst();
150.         String result = "unknown";
151.         boolean found = false;
152.         while(!found && nicknames.hasAccess()) {
153.             Nick pair = nicknames.getContent();
154.             if(pair.clientIP.equals(clientIP)) {
155.                 found = true;
156.                 result = pair.nickname;
157.             } else {
158.                 nicknames.next();
159.             }
160.         }
161.         return result;
162.     }
163.
164.     public String getAllNicknames() {
165.         nicknames.toFirst();
166.         String result = "";
167.         while(nicknames.hasAccess()) {
168.             Nick pair = nicknames.getContent();
169.             result += pair.nickname + ",";
170.             nicknames.next();
171.         }
172.         if(result.length() > 0) {
173.             result = result.substring(0,result.length()-1);
174.         }
175.         return result;
176.     }
177.
178. }
179.












06.03.2018
Geimeinsame Vereinbarung für ein Chat-Protokoll
http://collabedit.com/cv9su

Transkript vom 02.05.2018:

Vereinbarungen für das Chat-Protokoll "GBGCHAT2018"
###################################################

Festgelegt ist folgendes:
##########################
Ein Server, der das Protokoll "GBGCHAT2018" implementiert, muss unter einer IP-Adresse auf Port 9000 Verbindungen zulassen. Dann wartet er auf Nachrichten von den Clients.

Eine Client-Nachricht beginnt immer mit einem 5 Zeichen langen Code, dessen letztes Zeichen ein Doppelpunkt ist. Darauf folgen dann die eigentlichen Daten. Sollte der Server Client-Nachrichten empfangen, die diesem Schema nicht entsprechen, so wird die Nachricht verworfen.

Code NICK:
Beispiel:
NICK:superman2000
Der Client signalisiert dem Server, dass er in Zukunft unter dem angegebenen Nickname identifiziert wereden möchte. Zur IP, unter der sich der Teilnehmer mit dem Server verbunden hat, wird auf dem Server ein Nickname gespeichert. Damit können alle späteren Nachrichten dieses Teilnehmers einem sprechenden Namen zugeordnet werden. Der Server schickt eine Rückantwort an alle verbundenen Clients, dass sich ein Nickname geändert hat.

Code MESG:
Beispiel:
MESG:Dies ist eine tolle Nachricht an alle!
Der Client signalisiert dem Server, dass die angefügte Nachricht an alle Clients gesendet werden soll.

Code MUTE: und Code NOIS:
Eine Art Ruhemodus; ist dieser aktiviert bleibt man  zwar verbunden, erhält aber keine Nachrichten mehr.
Mit dem Code "MUTE:" muss der Server für den Absender speichern, dass der Absender bis auf weiteres keine Nachrichten mehr zugestellt bekommt. Der Absender einer echten Nachricht mit "MESG:" bekommt eine Rückmeldung darüber, welche Empfänger die Nachricht aufgrund des Ruhemodus nicht empfangen konnten.
Aufhebung des Ruhemodus kann durch den Code "NOIS:" erfolgen. Absetzung von "NOIS:" ohne vorheriges "MUTE:" hat keinen Effekt.

Code ONLN:
Wenn der Client diesen Code an den Server schickt (ohne weitere Daten), so antwortet der Server mit einer kommaseparierten Liste von eingeloggten Benutzern, wobei ebenfalls "ONLN:" vom Server vorangestellt wird.
Hinweis:
Mit:
if(pMessage.substring(0,5).equals("ONLN:"))
kann überprüft werden, ob die ersten 5 Zeichen der Serverantwort diesem Code entsprechen.
Mit:
String payload = pMessage.substring(5);
bekommt man den Teil HINTER dem 5ten Zeichen des Strings. Umwandlung des kommaseparierten Teils in ein Array geschieht mit:
String[] nicknames = payload.split(',')

Code PRIV:
Syntax:
PRIV:nickname@message
Der Client sendet an den Nickname nickname die Message message.


Weitere Vorschläge für Codes:
#####################################
####################################
Beim GUI des Chats:
Eine Art "Lobby" (rechts oder links an der Seite des ChatClients), in der sich die Personen befinden, die sich schon verbunden haben.
Damit könnte man Befehle, wie zum Beispiel "flüstern" ( eine gewisse Person anschreiben), ganz einfach durch einen Rechtsklick an der gewünschten Person in der Lobby vollführen. (Beim Rechtsclick werden mehrere Befehle geöffnet, zum Beispiel "flüstern", "Gruppe einladen", etc.)

GUI des Chats:
An der linken Seiten könnten sich die Räume ( Räume sind IP )
Anmerkung: Mehrere Server sind problematisch.

-von Altin
######################################
@Altin das ganze könnte man eventeuell auch durchführen in dem man vor seine Nachricht ein @+Name setzt
-Lars

############################
- Moritz
############################
Dateien senden: eine separate Sendezeile ähnlich wie für Text nur mit den häufigsten Dateitypen kompatibel.

Benachrichtigungen: bei minimiertem Chatfenster wird der angemeldete User durch ein Pop Up bei neuen Nachrichten belästigt.
-Philipp
############################
Gesendete Nachrichten wieder löschen (wie bei WhatsApp)
-Daniel

############################
Dadurch das mit "nick" die IP einenb Benutzernamen zugeotrdnet bekommt, kann man einfach den "nick" Namen nehmen und
durch @"nick" private Nachrichten zu schicken.

-Glenn
############################
Da wir uns darauf geeinigt hatten, dass die "Codewörter" immer lediglich aus vier Buchstaben plus Doppelpunkt bestehen, muss jedem Client eine zweistellige ID zugewiesen werden (da die Nicknames teilweise zu lang sind). Diese ID wird in der Reihenfolge 01, 02, 03 usw. an die Clients die sich verbinden vergeben. Die ID des jeweiligen Clients braucht der User nicht zu wissen, da neue Buttons dort eingefügt werden, wo auch auch Nickname, "mute-Status", usw. stehen. Werden diese Buttons vom User geklickt, sendet der Client das neue Codewort plus den sich im Eingabefeld befindlichen Text an den Server. Das neue Codewort wäre beispielsweise "ID03:" und signalisiert dem Server, die angehängte Nachricht nur an den Client mit der ID "03" weiterzuleiten.

- Moritz
######################################################


06.03.2018
Verzeichnis mit der Tutorial-Datenbank:
20180308_sqlite_tut_demodb.zip



06.03.2018
Vom ER-Diagramm zum Datenbankschema:
Link zum ER-Diagramm aus dem Unterricht: 20180306_er_diagram.png
Daraus wurde mit Hilfe der Transformationsregeln folgendes Schema:
Datenbankschema für unser ER-Diagramm mit den Entitäten:
person, sportgerät und hobby und adresse

Nach den Regeln (S.160) ergibt sich:

person (pid PRIMARY KEY,
        name, vorname, gebdat,
        aid FREMDSCHLÜSSEL)

sportgerät (sid PRIMARY KEY, name, ort, anz, zustand)

hobby (hid PRIMARY KEY, name)

adresse (aid  PRIMARY KEY, str, hnr , plz, ort)

personhathobby(phid PRIMARY KEY,
        pid FREMDSCHLÜSSEL,
        hid FREMDSCHLÜSSEL)
        
personverantwortlichfuersportgerät(psid  PRIMARY KEY,
        pid FREMDSCHLÜSSEL,
        hid FREMDSCHLÜSSEL)

Daten, um eine Spieldatenbank zu erzeugen, damit man SQL-Befehle üben kann:
(Achtung: Diese Datenbank hat mit den Diagrammen oben nichts zu tun!)

CREATE TABLE person (pid INTEGER PRIMARY KEY, name TEXT, oid INTEGER);
INSERT INTO person VALUES(1,'moritz',1);
INSERT INTO person VALUES(2,'altin',1);
INSERT INTO person VALUES(3,'daniel',1);
INSERT INTO person VALUES(4,'merkel',2);
CREATE TABLE ort(oid INTEGER PRIMARY KEY, name TEXT);
INSERT INTO ort VALUES(1,'duesseldorf');
INSERT INTO ort VALUES(2,'berlin');
CREATE TABLE hobby (hid INTEGER PRIMARY KEY, name);
INSERT INTO hobby VALUES(1,'schach');
INSERT INTO hobby VALUES(2,'radeln');
INSERT INTO hobby VALUES(3,'fernsehen');
CREATE TABLE personhobby (phid INTEGER PRIMARY KEY, pid, hid);
INSERT INTO personhobby VALUES(1,1,2);
INSERT INTO personhobby VALUES(2,1,3);
INSERT INTO personhobby VALUES(3,2,3);
INSERT INTO personhobby VALUES(4,4,1);


personen und ihre hobbies rausfinden:
select person.name, hobby.name from person, personhobby, hobby where person.pid=personhobby.pid AND personhobby.hid = hobby.id;

welche personen wohnen in duesseldorf?
select person.name from person, ord where person.oid = ort.oid AND ort.name = 'duesseldorf';



06.03.2018
Klausurthemen:

Grundlagen:
* Code auf Papier ausführen (Tabellen anlegen und Variablenwerte protokollieren)
* Programme "exakt lesen" (Methode, Eigenschaft etc. immer identifizieren können)
* Einfache Algorithmen selbst schreiben können.
* Mit Datenstruktur Array und List umgehen können.

Eigentliche Themen:
* Komplexität von Algorithmen: Bei konkreten Algorithmen Befehle zählen und eine Funktion für die Anzahl in Abhängigkeit von der Eingabegröße n angeben.
* Schwierigkeiten bei der Speicherung von Daten in Textdateien
* Datenbanken:
** Theorie hinter Datenbanken kennen. Dazu die kopierten Buchseiten verstehen. Insbesondere: Entity-Relationship-Diagramme entwerfen können (Begriffe Entity, Entitymenge, Attribute, Schlüssel und Primärschlüssel, Relationship, Kardinalität (1:1 / 1:n / m:n))
** Grundidee Normalisierung. Besser als in den kopierten Buchseiten ists bei Wikipedia erklärt: https://de.wikipedia.org/wiki/Normalisierung_(Datenbank). Dabei müssen die Definitionen für die Normalformen nicht auswendig gelernt werden. Der Sinn sollte aber klar sein.
** Überführung des ER in ein relationales Modell bzw. Datenbankschema. Transformationsregeln anwenden können (nicht auswendig lernen). Begriffe: Tabelle, Attribut (Feld), Datzensatz, Primärschlüssel und Fremdschlüssel
** SQL-Befehle kennen: (Jene, die auf den englischen Zettel stehen). Damit einzelne Abfragen formulieren können. Idee hinter einem "Join" verstehen und anwenden können.




22.02.2018
Liebe Q1-Informatiker

Ich komme heute etwas später. Aber ihr könnt schonmal folgendes erledigen:
Öffnet wieder mit sqlite3 eure Datenbank. Probiert mit den Befehlen herum: Benutzt INSERT, und SELECT (insbesondere SELECT mit WHERE-Zusatz (siehe Doku)) und UPDATE und, und und.

Findet heraus, wie man alle personen findet, die das Hobby "Schach" haben. Die erste Idee wäre ja:
SELECT name FROM personen WHERE hobbies = 'Schach';
Dabei ist aber problematisch, dass ja jemand auch 'Schach, Radfahren' als Hobby haben kann und die Strings 'Schach' und 'Schach, Radfahren' eben nicht identisch sind.
Finde dafür eine Lösung, indem du folgenden Artikel überfliegst:
http://www.sqlitetutorial.net/sqlite-like/

Bis hierhin sollte ich nun wieder im Unterricht sein. Viel Erfolg!


08.02.2018

Im Unterricht haben wir die Probleme des Ansatzes "Datenbank aus Textdatei" erörtert (siehe weiter unten die Unterrichtsmitschrift).

Aufgabe:
Lies dich zunächst schlau:
https://de.wikipedia.org/wiki/Datenbank - nur den Einführungsabsatz
https://de.wikipedia.org/wiki/Relationale_Datenbank - Einführungsabsatz, Abschnitt "Grundlegende Konzepte" und "Beziehungen zwischen Tabellen"

Beantworte mit diesem Vorwissen, inwieweit ein DBMS die unten aufgeworfenen Probleme "behebt" (Beziehe Dich dabei nur auf die Fragen F4, F5, F7, F8.)


Unterrichtsmitschrift:

Fragen zur (problematischen) Implementation der Klasse "TextdateiZugriff" und zum (problematischen) Ansatz "Daten aus Textdatei" allgemein.

Probleme dieser konkreten Implementierung:
F1: Was würde passieren, wenn man einen Datensatz mit ID "nase" anfügen würde?
A: Nichts. Der Datensatz mit ID "nase" würde ohne Meckern angefuegt.

F2: Was würde passieren, wenn man einen Datensatz mit Geburtsdatum "nase" anfügen würde?
A: Nichts. Der Datensatz mit Geburtsdatum "nase" würde ohne Meckern angefuegt.

F3: Was passiert mit Leerzeichen vor oder nach Einträgen?
A: Nichts. Leerzeichen werden mit übertragen. Achtung: Probleme bei Suche (falls Leerzeichen nicht mitgesucht wird)

F4: Was passiert, wenn man aus Versehen ein Komma in den Namen einfügt?
A: Wird einfach mit übertragen. Problem: Struktur der Textdatei wird zerschossen

F5: Was passiert, wenn man eine ID doppelt vergibt?
A: Nichts. Der Benutzer kanns i.d.R nicht verursachen. Aber ein Programmierfehler kann für doppelte IDs sorgen, so dass Datensätze nicht mehr eindeutig zuordnebar sind.

F6: Mehrmals wird in dieser Klasse Arrays.copyOf benutzt. Warum? Welche Probleme ergeben sich daraus?
A: Arrays.CopyOf kopiert Teile eines Arrays in ein anderes Array. Dies wird insbesondere beim Einlesen der Textdatei genutzt, da wir gar nicht vorher wissen, wieviele Datensätze wir überhaupt einlesen. Das Kopieren erzeugt hinter den Kulissen aber Speicherplatzanforderungen, die "teuer" (im Sinne von Prozessorzeit) sind. Der momentane Ansatz würde bei einer Textdatei mit Millionen von Datensätzen zu unakzeptablen Warteizeiten führen.

Probleme mit dem Ansatz allgemein:
F7: Was passiert, wenn man nicht nur Hobbies, sondern die Quelldaten um ein oder mehrere Leibgerichte erweitern wollte?
A: Man braucht andere Zeichen um unterschiedliche Hobbies oder Leibgerichte voneinander zu trennen, um klar zu machen, wo eine "Zelle" anfängt und aufhört.

F8: Was passiert, wenn man z.B. auch die bevorzugte Smartphone-Marke mit abspeichern wollte und sicherstellen will, dass man bei "Samsung" nicht aus Versehen "Samsong" eingeben kann?
A: Sinnvollerweise benutzt man eine neue Textdatei in der man Handymarken speichert und in der eigentlichen Datenbank nur Referenzen auf Einträge in der Handymarkendatei speichert.

F9: wie vergrößert sich das o.g.(Handymarke) Problem, wenn man das auf die Hobbies übertragen würde?
A: (Im Unterricht noch keine Antwort gegeben)

F10: Angenommen man erweitert unsere Tabelle um ein Feld namens "Freund_von", in dem man die ID des Freundes abspeichert. Welche Probleme ergeben sich?
A: (Im Unterricht noch keine Antwort gegeben)





08.01.2018

Zwei Möglichkeiten zur Mittelwertberechnung:

    static double mittelwert1(int[] a) {
        int summe = 0;
        for(int i=0; i<a.length; i++) {
            summe = summe + a[i];
        }
        double mw = (double) summe/a.length;
        return mw;
    }
    
    static double mittelwert2(int[] a) {
        int summe = 0;
        for(int i=0; i<a.length; i++) {
            summe = summe + a[0]; // Element an Position 0!

            // shift array. achtung: veraendert Array!
            for(int j=1; j<a.length; j++) {
                a[j-1] = a[j];
            }
        }
        double mw = (double) summe/a.length;
        return mw;
    }




22.12.2017
Hier die Abiturklassen mit ein paar neuen implementierten Methoden. Insbesondere die Klasse List wurde erweitert.
20171207_abiturklassen_erweitert.zip


05.12.2017
Übungen zur heutigen Stunde:
Erweitere die "Abiturklassen":
Queue:
* Methode int getLength(),
* Methode String toString()
Stack:
* Methode int getLength(),
* Methode String toString()
List:
* Methode String toString(),
* Methode <ContentType> elementAt(int i),
* Methode int indexOf(<ContentType> element),
* Methode void sort(),
* Methode void sortedIndexOf(<ContentType> element),
* Methode void currentTo(int i)

Klausurthemen:
Dynamische lineare Datenstrukturen:
Queue, Stack und List
Die "Abiturklassen" (siehe auch Verlinkungen weiter unten) kennen, anwenden können, verstehen und erweitern können. Vorteile und Nachteile gegenüber Arrays. (Genauere Kenntnis von "Generics" oder "inneren Klassen" wird nicht abgefragt. Der von uns geschriebene Programmcode muss aber verstanden sein)

Mergesort auf der von uns erweiterten List-Klasse.

Exaktes Beschreiben von Programmcode
(auch "Programmausführung auf Papier" mit Verfolgung von Variableninhalten)

Kleinere Algorithmen selbst schreiben können: z.B.
* finde in einem Array das größte Element
* Berechne den Durchschnitt bei einem Zahlenarray
* sortieren mit Bubblesort

21.11.2017
Arbeiten mit Listen: Implementation von Insertion-Sort:


public class Haupt {
    public static List<Integer> insertionsort(List<Integer> input) {
        List<Integer> sortiert = new List<Integer>();      
        // .... hier fehlt einiges
        return sortiert;
    }

    public static void main() {
        List<Integer> zahlen = new List<Integer>();
        zahlen.append(6);
        zahlen.append(9);
        zahlen.append(2);
        zahlen.append(8);
        zahlen.append(4);

        ausgabe(zahlen);
        zahlen = insertionsort(zahlen);
        System.out.println("----- Und jetzt sortiert: -----");
        ausgabe(zahlen);
    }

    public static void ausgabe(List<Integer> liste) {
        liste.toFirst();
        while(liste.hasAccess()) {
            System.out.println("Zahl: "+liste.getContent());
            liste.next();
        }
    }
}




06.11.2017

"Abitur-Klassen"
Übersicht:
https://www.schulentwicklung.nrw.de/lehrplaene/lehrplannavigator-s-ii/gymnasiale-oberstufe/informatik/hinweise-und-beispiele/hinweise-und-beispiele.html
Direktlink:
https://www.schulentwicklung.nrw.de/lehrplaene/upload/klp_SII/if/MaterialZABI/2016-08-30_Implementationen_von_Klassen_fuer_das_Zentralabitur_ab_2018.zip

Betrachtung von
01 Datenstrukturklassen -> 01 linear -> Stack.java

Generics (immer dann, wenn <T> (also "spitze Klammern") in Klassen vorkommen)
Ausführlich: In "Java ist auch eine Insel" Kapitel 9
http://openbook.rheinwerk-verlag.de/javainsel/javainsel_09_001.html#dodtp1e5aa8bf-acb7-4f0f-b3cf-176e06f73845
Erinnerung: CompareTo-Methode beim Sortieren mit Arrays.sort()

Äußere und innere Klassen
Ausführlich: In "Java ist auch eine Insel" Kapitel 7 (genauer: Kapitel 7.3)
http://openbook.rheinwerk-verlag.de/javainsel/javainsel_07_003.html#dodtp57658547-2c54-47bd-851c-11e27903b66a

Übung:
Lege zwei Stacks an: roteSocke und gelbeSocke
in die rote Socke kommen mehrere "Süßigkeiten" in folgender Reihenfolge:
"Orange","Weihnachtsmann","Lebkuchen" (die Orange ist also unten in der Socke)
Fritzchen will aber die Orange zuerst essen. Daher holt er jeweils die oberen Objekte aus der rotenSocke (vom ersten Stack) und packt sie in die gelbe Socke (den zweiten Stack). Dann sollte in gelbeSocke die Orange oben liegen.
Ausprobieren können wir das, indem wir alle Objekte aus der gelbenSocke der Reihe nach herausholen.






19.10.2017
Dateien (nur Text) lesen: https://stackoverflow.com/a/3403112
Dateien (nur Text) schreiben: https://stackoverflow.com/a/2885224


12.10.2017
Infoblatt: 20171012_Referenzen_Arrays_Speicherlayout.pdf
Das auf dem Infoblatt besprochene Demoprogramm:

public class MyClass {
    public int x;
    public int y;
    
    public static void main() {
        int h = 3;

        MyClass mcObjectA = new MyClass();
        mcObjectA.x = 3;
        mcObjectA.y = 4;

        MyClass mcObjectB = new MyClass();
        mcObjectB.x = 5;
        mcObjectB.y = 6;
        
        int[] a = new int[3];
        a[0] = 10;
        a[1] = 11;
        a[2] = 12;

        MyClass[] mcArray = new MyClass[2];
        mcArray[0] = mcObjectA;
        mcArray[1] = mcObjectB;
        
        MyClass dummyA;
        int[] dummyB;
    }
}


10.10.2017
Referenz-Programm für das TSP
20170921_Pointarray_referenz.zip


Klausurthemen:
Exaktes Beschreiben von Programmcode
(auch "Programmausführung auf Papier" mit Verfolgung von Variableninhalten)

Verstehen des TSP-Programms
(ggf. Teile neu schreiben können / Fehler finden )

Kleinere Algorithmen selbst schreiben können:
z.B.
* finde in einem Array das größte Element
* Berechne den Durchschnitt bei einem Zahlenarray
* sortieren mit Bubblesort

28.09.2017
Vorschlag für das Finden einer optimaleren Tour:

double guteTourlaenge = gesamtlaenge(pointArray);
for( ... 10000 mal ) {
    probierPointArray = kopie von pointArray;
    tauscheZweiWegpunkte(probierPointArray)
    neueTourlaenge = gesamtlaenge(probierPointArray);
    if(neueTourlaenge < guteTourlaenge) {
        pointArray = probierPointArray;
        guteTourlaenge = neueTourlaenge
        Ausgabe("Bessere Lösung mit Länge: "+guteTourlaenge)
    }
}


26.09.2017
Lösung aus der Stunde von Lars, Altin und Phillip:
20170921_Pointarray_Lars_Altin_Phil.zip

26.09.2017
Lesehinweise: "Java ist auch eine Insel"

(Kapitel 3.7 wird als Vorwissen vorausgesetzt)
3.8.6 (ohne *-Teil)
3.8.7 (ohne *-Teil)
3.8.11: Nur "Zufällige Spielerpositionen erzeugen" und Listing 3.23 "übertrieben exakt" erklären können
3.8.17  Richtig verstehen

Link zum Buch: http://openbook.rheinwerk-verlag.de/javainsel/index.html



19.09.2017
Rohbau für unser Travelling-Salesman Programm:

20170921_Pointarray.zip


19.09.2017

Übertrieben exaktes Lesen von Programmcode

Beispiel:

(Wir nehmen die ganze Zeit an, dass wir uns in einer Klasse namens Haupt befinden.)

    public static void main(String[] args) {
Eine Methode mit Namen main wird als public (also von außerhalb der Klasse sichtbar) und static (also unabhängig von existierenden Objekten der Klasse aufrufbar) deklariert. Das einzige Argument der Methode ist ein String-Array mit Namen args. Die Definition der Methode folgt in den nächsten Zeilen (erkennbar an der geschweiften Klammer, die den Methodenblock einleitet).
        Point[] pointArray = generatePointArray(15);
Die Variable pointArray vom Typ "Array von Point-Objekten" wird deklariert und mit dem Ergebnis des Methodenaufrufs generatePointArray(15) definiert. Die Methode generatePointArray muss eine Methode "unserer" Klasse Haupt sein, denn andernfalls hätte man sie mit objektname.generatePointArray(15) oder Klassenname.generatePointArray(15) (im Falle einer statischen Methode) aufrufen müssen.
        Arrays.sort(pointArray);
Die statische Methode sort aus der Klasse Arrays wird aufgerufen, wobei als Argument das oben definierte pointArray angegeben wird. Die Methode sort muss statisch sein, denn Arrays ist ein Klassenname (Arrays ist eine Klasse aus dem Paket java.util, welche mit import eingebunden werden muss).
        
        for(int i = 0 ;  i < pointArray.length; i++) {
Eine for-Schleife wird eingeleitet. Die Laufvariable i durchläuft die Werte von Null bis "Länge des pointArray minus eins".
            System.out.println("Punkt: "+pointArray[i] +
            " hat den Abstand "+pointArray[i].distance(0,0)+
            " vom Ursprung");

System ist eine Klasse, die in Java immer zur Verfügung steht. Eine Klassenvariable von System ist out, ein Objekt der Klasse PrintWriter PrintStream, welche wiederum die Methode println kennt. Das Argument von println ist ein String, der in diesem Fall aus mehreren Teilen "zusammengebaut" wird. Mit pointArray i wird auf das i-te Element (also ein Point-Objekt) des Arrays pointArray zugegriffen. Weil wir das Point-Objekt in einem String-Kontext verwenden, wird automatisch die toString()-Methode des Point-Objekts aufgerufen. Mit pointArray i .distance(0,0) wird auf dem o.g. Point-Objekt die Methode distance(0,0) aufgerufen, welche die Distanz des Punktes zum Koordinatenursprung als double-Variable zurückgibt.
        }
    }

Der for-Schleifenblock und der Methodenblock werden beendet.





14.09.2017


import java.awt.Point;
import java.util.Arrays;

public class Haupt {
    
    // erzeugt ein Array von anz Point-Objekten
    public static Point[] generatePointArray(int anz) {
        Point[] pa = new Point[anz];
        for(int i = 0; i < anz; i++) {
            int px = (int) (Math.random() * 10);
            int py = (int) (Math.random() * 10);
            pa[i] = new Point(px,py);
        }
        return pa;
    }
    
    public static void main(String[] args) {
        Point[] pointArray = generatePointArray(15);

        Arrays.sort(pointArray);
        
        for(int i = 0 ;  i < pointArray.length; i++) {
            System.out.println("Punkt: "+pointArray[i] +
            " hat den Abstand "+pointArray[i].distance(0,0)+
            " vom Ursprung");
        }
    }
}

//  und klasse MyPoint:

import java.awt.Point;

public class MyPoint extends Point implements Comparable {
    
    public int compareTo(Object o) {
        Point p = (Point) o;
        // ...
    }
}







12.09.2017
Kleinere Java-Programme wirklich verstehen!

A1) Schreibe eine Java-Klasse Haupt , welche eine main-Methode und eine generatePointArray-Methode enthält:
In generatePointArray soll ein Array von Point-Objekten erstellt werden (wir starten mit 15 Point-Objekten), welche mit zufälligen Punktkoordinaten intialisiert werden. In der main-Methode sollen das erzeugte Array ausgegeben werden. (Hinweis: lies kurz die java-API zur Klasse Point)
A2) Punkte im 2D-Koordinatensystem haben zunächst keine festgelegte Ordung, nach der man sortieren könnte. Das Array aus Point-Objekten soll nach folgendem Kriterium sortiert werden: Abstand des Punktes vom Koordinatenursprung. Überlege, wie das Problem in Java umsetzbar wäre (Implementiere jedoch noch nicht! Das machen wir gemeinsam)
A3) Sinnvoll wäre, wenn man den Point-Objekten auch noch Namen geben könnte. Die String-Ausgabe eines Punktes sollte diesen Namen mit ausgeben.
A4) Schreibe die Methode wayLength, welche die Länge der Strecke errechnet, wenn man vom Koordinatenursprung zum ersten, dann zum zweiten, ... bis zum letzten Punkt des Arrays "wandert".



28.06.2017

EVA-Aufgabe zu Mittwoch, dem 28.6.2017 in den ersten beiden Stunden.

Es soll mit Java-Kara gearbeitet werden. Es soll eine (oder mehrere) der folgenden "eingebauten" Aufgaben gelöst werden:
* Bilder invertieren
* Spirale zeichnen
* Dreieck zeichnen
* oder eine der schwierigen Aufgaben.

Ich erwarte, dass eure Lösungen (oder Lösungsansätze) am Stundenende auf den Share-Ordner gestellt werden. Und zwar so, dass ich die Java-Dateien zuordnen kann (also Datum in der Form 20170628 voranstellen und euren Namen in den Dateinamen einbauen).
Wenn eine Lösung nicht gelingt, so ist es unerlässlich, dass das Programm dokumentiert wird, damit man zumindest Ideen nachvollziehen kann.

Beste Grüße!


27.06.2017
Mini-Referate

Die Referate zur "Geschichte der Informatik" müssen zu Dienstag, dem 4.7.2017 fertig sein
Die Referate von Moritz und Lars dürden eine Woche später gehalten werden

Luca  Geschichte der Informatik: Turing
Nick  Geschichte der Informatik: elektronische Rechenmaschinen
Peter  Geschichte der Informatik: Programmiersprachen
Daniel  Geschichte der Informatik: Kryptographie
Phillipp  Geschichte der Informatik: Das Internet
Moritz  Datenschutzgesetz: Fallbeispiele
Lars  Urheberrecht: Fallbeispiele

Vorgabe: Länge des Referats: Maximal 4 Minuten, Powerpoint OK (aber Vorsicht: hier gibts nur Open Office! also wenn PP, dann keine exotischen Formatierungen) - besser ist, einfach nur eine Reihe von Bilddateien.



30.05.2017
Java-Kara Download:
download

23.05.2017

Klausurthemen der Klausur am 23.05.2017

Arbeit mit Arrays
* Programmieren können: Suche nach dem größten Element, Durschnittsberechnung etc.
* Auch mit verschachtelten Schleifen (siehe auch Sortieralgorithmen) umgehen können.

Sortieralgorithmen
* Die Ideen zum Bubble-Sort und zum Selection-Sort kennen und formulieren können
* Den Programmcode (siehe Arbeitsblatt) der beiden Sortieralgorithmen verstehen und in der Klausur z.B. ergänzen oder auf Fehler überprüfen können.

In der Klausur wird von Euch verlangt
1. Kleinere Programmabschnitte selbst zu programmieren
2. Vorgegebene Programmabschnitte zu erklären / zu ergänzen / zu korrigieren.
3. Programmausführung auf dem Papier (für Fortgeschrittene - siehe Blatt). Damit muss prinzipiell jedes Programm mit abgearbeitet werden können.




17.05.2017
Projekt für die Doppelstunde am Mittwoch:
20170517_suche.zip



06.05.2017
Klausurinformationen
Liebe Informatiker beider Kurse!
(Nur zur Information: Laut Stundenplan hat der "Dienstag-Nachmittag"-Kurs die Nummer G2, der Kurs am Mittwoch und Donnerstag hat die Nummer G1)
Die eigentlich geplante Klausurtermine waren: Kurs G1 sollte ursprünglich am 10.5 schreiben, Kurs G2 am 23.5. Weil der Termin für Kurs G1 zu knapp wäre und beide Kurse sowieso ähnlich weit sind, werden beide Kurse am Dienstag, den 23.5 in der 8/9 Stunde schreiben.

Da Kurs G2 wegen des kommenden Elternsprechtages am 9.5 schon wieder ausfällt, werde ich zeitnah noch Übungsmaterial hier einstellen.

Da ich die Klausurschreiber aus Kurs G1 schon perspönlich erreicht habe, bitte ich an dieser Stelle nur die Klausurschreiber aus Kurs G2 kurz um Rückmeldung (dass diese Information gelesen worden ist) per Email an plusplanet1@plusplanet.de

Herzlichen Dank!


03.05.2017
Liebe Informatiker
Da ich heute im Mathematik-Abitur eingesetzt werde, müsst ihr ohne mich auskommen. Diesmal sollt ihr nicht programmieren, sondern ein Mini-Referat für morgen vorbereiten!

Aufgabe: Bereitet ein 4-minütiges Referat zu den unten angegebenen Themen vor. Die Mini-Referate sollen am Donnerstag gehalten werden können. Beschränkt euch auf das Wesentliche, verliert Euch aber bitte nicht in unwichtigen Einzelheiten. Die Stichpunkte in den Klammern sind nur Anregungen und keine Pflicht.

Samer: Viren (was sind Computerviren? Funktionsweise, Sinn und Unsinn von Virenscannern)
Vincent: Hacken (Begriffsabgrenzung, mögliche Verfahren)
Marvin: Email (Geschichte, Vor- und Nachteile zu anderen Verfahren)
Sophie: Datenschutz (Warum? Rechtslage in Deutschland etc.)
Paul: Videoformate (Grundlegende Ideen von z.B. mpg, avi, mkv ... )
Niusha: Betriebssysteme (Aufgabe, Unterschiede von Windows, Linux, Android...)
Alexander: Das mp3-Format (Geschichte, Eigenschaften, Funktionsweise)
Loc: Speichermedien und ihre Eigenschaften (Disketten, Festplatten, SSD, CD, DVD ...)



02.05.2017
Bilder verändern...
20170502_MatheBilder.zip


27.04.2017
Sortieralgorithmen
20170427_selsort_Step.zip


09.02.2017
Ein Gerüst für ein Raster-spiel UPDATE!:
20170212_gbglogic_game_v1_fuer_sus.zip
(Hinweis an den Vormittags-Kurs: die Klasse SpielfeldLayer wurde geändert: Es enthält nun ein Array von "RasterObjekt"-Objekten, statt wie zuvor ein Array von "Malbar"-Objekten.)

09.02.2017
Ein Gerüst für ein Raster-spiel:
20170208_gbglogic_game_v0.zip

08.02.2017
Eine Roboterklasse für den Ameisenhaufen...

import java.awt.*;
import javax.swing.*;

public class Roboter implements MalbarBeweglich {
    Point p = new Point();
    Point d = new Point();
    boolean markiert;
    
    public Roboter() {
        p.x = (int) (Math.random() * 300);
        p.y = (int) (Math.random() * 300);
        d.x = p.x;
        d.y = p.y;
        markiert = false;
    }
  
    public void mouseClickAt(Point m) {
        if (markiert) {
            setDestination(m);
            markiert = false;
        } else {
            if((m.x > p.x) && (m.x<(p.x+20)) && (m.y > p.y) && (m.y<(p.y+20)) ) {
                markiert = true;
            }
        }
    }
    
    public void setDestination(Point d) {
        this.d = d;
    }
    
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        g.setColor(Color.yellow);
        g.fillRect(p.x,p.y,20,20);
        if(markiert) {
            g.setColor(Color.white);
        } else {
            g.setColor(Color.black);
        }
        g.fillRect(p.x+2,p.y+2,16,16);
    }
    
    public void bewegung() {
        if((d.x - p.x) > 0) {
            p.x = p.x +1;
        }
        if((d.x - p.x) < 0) {
            p.x = p.x  - 1;
        }
        if((d.y - p.y) > 0) {
            p.y = p.y +1;
        }
        if((d.y - p.y) < 0) {
            p.y = p.y  - 1;
        }
    }

}



07.02.2017
Hilfreiche Formulierungen / Vokabeln bei der Beschreibung von Programmtexten:


Klasse *** / Objekt *** (vom Typ ***) / Methode *** / Eigenschaft *** /
Variable *** / atomarer Datentyp *** / Array *** (vom Typ ***) (an Indexposition ***)
- wird angelegt bzw. erzeugt
- wird aufgerufen
- wird deklariert
- Übergabeparameter bzw. Argument
- Ergebnis (vom Typ ***)
- wird *** zugewiesen



25.01.2017
Projekt für die heutige Stunde:
20170125_grafik_Interface_Malbar.zip

12.01.2017
Projekt für die heutige Stunde:
20170112_grafik_mousemotion.zip


10.01.2017
Projekt für die heutige Stunde:
20170110_grafik.zip


20.12.2016
Projekt für die heutige Stunde:
20161220_grafik.zip


13.12.2016
Projekt für die heutige Stunde:
20161212_vierGewinnt.zip


06.12.2016
Projekt für die heutige Stunde:
20161206_LichtAnAus.zip


23.11.2016

Klausurthemen
Einführung in die Informatik
* Computer allgemein: Zettel "Von-Neumann-Architektur, EVA-Prinzip, Was ist überhaut ein Computer"
* Protokolle: Zettel "Protokoll Getränkeautomat"
* Zählen im Binärformat.

Programmiersprache Java
* Die verteilten Zettel: "Struktur eines einfachen Java-Programms", "Grundlegende Kontrollstrukturen in Java", "Variablen in Java", "Klassen und Objekte", "Eigene Klassen, eigene Methoden", "Sichtbarkeit von Variablen", "Konstruktoren new und null"
* Unterschied "Referenztyp" und atomarer Datentyp, Speichermodell (siehe PDF-Datei vom 9.11)
* Die Funktionsweise von einfachen Programmen muss man verstehen. Diesbezüglich hilft es, die hier auf www.plusplanet.de stehenden Programmbeispiele nocheinmal Zeile für Zeile durchzugehen und nachzuvollziehen. Insbesondere das untenstehende Programm zur "Klausurvorbereitung" dient dazu!

In der Klausur wird von Euch verlangt
1. Kleinere Programmabschnitte selbst zu programmieren
2. Vorgegebene Programmabschnitte zu erklären / zu ergänzen / zu korrigieren.


Programmgerüst für eine einfache Cäsar-Verschlüsselung:

public class Starter {
    // Aufgaben
    // 1. Quelltext verstehen
    // 2. Schreibe Methoden
    //          String verschluessle(String klartext, int key)
    //          String entschluessle(String geheimtext, int key)
    // 3. Schreibe eine Vigenere-Verschluesselung:
    //          String verschluessleVigenere(String klartext, String key)
    //          String entschluessleVigenere(String klartext, String key)
    // 4. Bette alle Methoden in eine GUI ein
    public static void main(String args[]) {
        String klartext = "hallo allerseits";
        System.out.println("Klartext: "+klartext);

        String abc = "abcdefghijklmnopqrstuvwxyz";
        
        int klarlaenge = klartext.length();
        
        // Buchstabenpositionen in klararray speichern
        int[] posarray = new int[klarlaenge];
        for(int i = 0; i<klarlaenge; i++) {
            char b = klartext.charAt(i); // -1 falls nicht gefunden
            int idx = abc.indexOf(b);
            posarray[i] = idx;
        }
        
        // posarray "verschluesseln"
        for(int i = 0; i<klarlaenge; i++) {
            if(posarray[i] >= 0) {  // ungueltige Zeichen sind -1
                posarray[i] = (posarray[i] + 1) % 26;
            }
        }

        // geheimtext erzeugen
        String geheimtext = "";
        for(int i = 0; i<klarlaenge; i++) {
            if( posarray[i] >= 0) {
                geheimtext = geheimtext + abc.charAt(posarray[i]);
            } else {
                geheimtext = geheimtext + "_"; // Dummyzeichen
            }
        }
        
        System.out.println("Geheimtext: "+geheimtext);
    }
}


09.11.2016
(nicht für den Dienstag-Nachmittagskurs!)
20151207_Referenztypen2.pdf


08.11.2016
Klausurthemen
Einführung in die Informatik
* Computer allgemein: Zettel "Von-Neumann-Architektur, EVA-Prinzip, Was ist überhaut ein Computer"
* Protokolle: Zettel "Protokoll Getränkeautomat"
* Zählen im Binärformat.

Programmiersprache Java
* Die verteilten Zettel: "Struktur eines einfachen Java-Programms", "Grundlegende Kontrollstrukturen in Java", "Variablen in Java", "Klassen und Objekte"
* Die Funktionsweise von einfachen Programmen muss man verstehen. Diesbezüglich hilft es, die hier auf www.plusplanet.de stehenden Programmbeispiele nocheinmal Zeile für Zeile durchzugehen und nachzuvollziehen. Insbesondere das untenstehende Programm zur "Klausurvorbereitung" dient dazu!

In der Klausur wird von Euch verlangt
1. Kleinere Programmabschnitte selbst zu programmieren
2. Vorgegebene Programmabschnitte zu erklären / zu ergänzen / zu korrigieren.



Klausurvorbereitung

public class MeineKlasse {
    public static void main(String[] args) {
        MeineKlasse mk = new MeineKlasse();

        // Gib an, welche Ausgaben methode1 macht!
        mk.methode1();
        
        // Gib an, welches Ergebnis methode2 hier liefert!
        // methode2 erledigt eine sinnvolle mathematische
        //     Operation. Welche?
        int a,b;
        b = 85;
        a = mk.methode2(b);
        System.out.println("Methode2(85) ist "+a);
    }
    
    public void methode1() {
        for(int i = 0; i<4; i++) {
            if(i>2) {
                System.out.println("Zahl x: "+(i*i));
            } else {
                System.out.println("Zahl y: "+(i+i));
            }
        }
    }
    
    public int methode2(int x) {
        int erg = 0;
        if(x<0) {
            x = x * (-1);
        }
        for(int i = 0; i < x; i++) {
            if(i*i < x) {
                erg = i;
            }
        }
        return erg;
    }
}



02.11.2016
Programmgerüst für die GUI eines Mini-Adventures

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.Random;

/*
* GUI (Graphical User Interface), mit einem eigenen Layout
*/
public class Startklasse implements ActionListener{
    JButton but1, but2,but3,but4,but5;
    JFrame frame;
    JTextArea textArea;

    public void zeigeFenster() {
        frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setTitle("Null Layout");
        frame.setLayout(null);

        but1 = new JButton("Norden");
        but1.setBounds(10,10,90,30);
        but1.addActionListener(this);
        frame.add( but1 );

        but2 = new JButton("Süden");
        but2.setBounds(100,10,100,30);
        but2.addActionListener(this);
        frame.add( but2 );

        but3 = new JButton("Westen");
        but3.setBounds(200,10,100,30);
        but3.addActionListener(this);
        frame.add( but3 );

        but4 = new JButton("Osten");
        but4.setBounds(300,10,100,30);
        but4.addActionListener(this);
        frame.add( but4 );

        but5 = new JButton("Tausche");
        but5.setBounds(400,10,100,30);
        but5.addActionListener(this);
        frame.add( but5 );

        textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        textArea.setEditable(true);
        scrollPane.setBounds(10,50,490,200);
        frame.add(scrollPane);
        
        frame.pack();
        frame.setSize(510,350);
        frame.setResizable(false);
        frame.setVisible( true );
    }
    
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == but1) {
            textArea.setText("");
            textArea.append("Button Norden gedrueckt!\n");
        }
        if(e.getSource() == but2) {
            textArea.setText("");
            textArea.append("Button Süden gedrueckt!\n");
        }
    }

    public static void main() {
        (new Startklasse()).zeigeFenster();
    }
}



05.10.2016
Programmgerüst für ein Mini-Adventure.
Kopiere dieses Gerüst in ein eigenes BlueJ-Projekt und starte das Programm mit der start()-Methode. Versuche dann den Programmtext zu verstehen und ergänze die Story so, dass ein komplizierteres Adventure-Game herauskommt. Am Donnerstag möchte ich eure Spiele sehen!


import javax.swing.*;

public class MeineKlasse {
    static String raum, wunschraum;
    
    public static void start() {
        System.out.println("+++ Abenteuerspiel im Hotel +++");

        raum = "Rezeption";

        while(!raum.equals("Ausgang")) {
            gibRaumbeschreibung(raum);
            wunschraum = frage("Wohin willst du jetzt?\n(Lobby, Rezeption oder Ausgang?)");
            // TODO: Kontrolle: ist wunschraum OK?
            raum = wunschraum;
        }
        gibRaumbeschreibung("Ausgang");
    }
    
    public static void gibRaumbeschreibung(String r) {
        if(r.equals("Rezeption")) {
            System.out.println("Du bist an der Rezeption.");
            System.out.println("Das Gästebuch ist geöffnet. LadyGaga scheint auch hier zu sein...");
        } else if(r.equals("Lobby")) {
            System.out.println("In der Lobby. Du siehst...");            
            System.out.println("... einen Kellner");            
            System.out.println("... und LadyGaga am Tisch.");            
        } else if(r.equals("Ausgang")) {
            System.out.println("Du hast das Hotel verlassen. Das Spiel ist beendet.");
        } else {
            System.out.println("Den Ort '"+r+"' kenne ich nicht! (Groß-/Kleinschreibung beachten!)");
        }
    }

    public static String frage(String fragesatz) {
        String s = (String)
            JOptionPane.showInputDialog(null,
                fragesatz,"Titel",
                JOptionPane.PLAIN_MESSAGE,
                null,null,"");
        return s;
    }
}




27.09.2016
Programmgerüst für ein GUI-Programm


import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.Random;

/*
* GUI (Graphical User Interface), mit einem eigenen Layout
*/
public class Startklasse implements ActionListener{
    JButton but1, but2;
    JTextField eingabezeile1;
    JLabel lab1;
    JFrame frame;
    JTextArea textArea;

    public void zeigeFenster() {
        frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setTitle("Null Layout");
        frame.setLayout(null);

        but1 = new JButton("Klick mich!");
        but1.setBounds(10,10,200,30);
        but1.addActionListener(this);
        frame.add( but1 );

        eingabezeile1 = new JTextField("Hier kann man schreiben...");
        eingabezeile1.setBounds(220,10,200,30);
        frame.add( eingabezeile1 );

        textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        textArea.setEditable(true);
        scrollPane.setBounds(10,50,410,200);
        frame.add(scrollPane);

        but2 = new JButton("TextArea loeschen");
        but2.setBounds(210,260,200,30);
        frame.add( but2 );
        
        lab1 = new JLabel("Informatik macht Spaß.");
        lab1.setBounds(10,260,190,30);
        frame.add(lab1);
        
        frame.pack();
        frame.setSize(430,350);
        frame.setResizable(false);
        frame.setVisible( true );
    }
    
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == but1) {
            textArea.append("Button eins gedrueckt!\n");
        }
    }

    public static void main() {
        (new Startklasse()).zeigeFenster();
    }
}



25.08.2016

Light-Bot

Das LightBot-Spiel: www.plusplanet.de/pp_lightbot/lightbot.html

Selbstprogrammierter Light-Bot-Simulator mit "Level-Designer":
http://www.plusplanet.de/lightbotsimulator/index.php


Speichere folgenden Text als Textdatei (mit Namen test.pbm) auf den Desktop:

P4 144 16
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
zzzzzzzzOOOOOOOO
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz
OOOOOOOOzzzzzzzz



Daten im Zahlenformat anzeigen

Dafür gibt es z.B. einen Dienst im Internet: https://hexed.it/

Daten hörbar machen:

Download von Audacity, einem Audioeditor:
http://downloads.sourceforge.net/portableapps/AudacityPortable_2.1.1.paf.exe?download
Beliebige Daten können damit "hörbar" gemacht werden, indem man folgendes tut:
Datei->Importieren...->Raw-Audio
Dann erscheint ein Fenster mit Einstellungen (am Besten die Voreinstellungen unverändert lassen).

Daten sichtbar machen

Mit dem Programm IrfanView kann man Daten als Grafik interpretieren lassen, wenn man folgende Schritte befolgt:
Zunächst muss fügt man am Anfang der Textdatei folgende Zeile ein:
P4 200 150
(Dies ist notwendig, damit IrfanView die Datei als Grafikdatei im PBM-Format erkennt. Dabei bedeuten die Zahlen 200 und 150, dass das Bild 200 Pixel breit und 150 Pixel hoch ist)
Als nächstes muss man die Dateinamenserweiterung von .txt in .pbm umbenennen. Schließlich kann man diese Datei dann in IrfanView hineinladen.


























Addendum zu Bäumen:

Löschen eines Knotens in Binärbäumen (siehe Wikipedia):

Fall A: Zu löschender Knoten hat höchstens ein Kind.

Ist der Knoten ein Blatt (Knoten ohne Kinder), dann wird beim Löschen einfach der Knoten entfernt. Hat der zu löschende Knoten genau ein Kind, wird dieses an die Stelle des zu löschenden Knotens gesetzt.

Fall B: Zu löschender Knoten hat zwei Kinder.

In diesem Fall kann die Löschung sowohl über den linken wie über den rechten Teilbaum vollzogen werden. Um die in-order-Reihenfolge aufrechtzuerhalten, ist aber ein Abstieg bis zu einem Halbblatt unvermeidlich.

Eine Möglichkeit ist, den linken Teilbaum an die Position zu setzen, an der der zu löschende Knoten war, und den rechten Teilbaum an den linken an dessen rechtester Stelle anzuhängen.