JGU Logo JGU Logo JGU Logo JGU Logo

Institut für Informatik

Michael Wand
David Hartmann
Sommersemester 2020DIGITAL

Hello EiS

Übung 1
Einführung in die Softwareentwicklung







[1] Meine persönliche Empfehlung ist im Laufe des Studiums ein kleines Feature in ein größeres Softwareprojekt mittels Git einzupflegen (selbstverständlich tun dies im Schnitt 9 von 10 Studenten </ironie>). So viel ist sicher: Beim Lesen von Code und beim Stellen eines „Pull-Request“ lernt man Aspekte der Softwareentwicklung kennen, die kleine und abgeschlossene Übungeneinheiten wie unsere nicht vermitteln können. Damit Sie dies also selbstständig tun können, kümmern wir uns innerhalb dieser Übung also um die Basis.





Aufgabe Versionierungsverwaltungssysteme

Letzte Änderung: 19. April 2020, 18:01 Uhr
18 Punkteim Detail
Ansicht:   |  

a) Schreiben Sie in wenigen Sätzen:

b.) Beschreiben Sie nun in eigenen Worten die Funktionalität der folgenden Befehle:
Meine Empfehlung: Spielen Sie das Online-Puzzle https://learngitbranching.js.org/ durch, um ein besseres Gefühl für diese zu bekommen.1






[1] Es geht hier nicht wirklich darum, die Bearbeitung der Aufgabe zu Prüfen, sondern Sie dazu ermutigen sich früh mit Git zu beschäftigen.
Für sehr Interessierte kann ich nur das Buch „Progit“ empfehlen:






Aufgabe Heron-Verfahren in C++

Letzte Änderung: 19. April 2020, 18:01 Uhr
12 Punkteim Detail
Ansicht:   |  
In der Vorlesung wurde C++ noch gar nicht eingeführt. Für diese Aufgabe ist dies jedoch gar nicht schlimm, denn


Das folgende Programm implementiert das Heron-Verfahren mithilfe einer while-Schleife, die sie bereits aus Python kennen.


#include <iostream>
#include <iomanip>

int main() {
    double input;
    std::cout << "Gib die Zahl ein, deren Wurzel du bestimmen möchtest: ";
    std::cin >> input;

    double a = input;
    double b = 1;

    while (std::abs(a - b) > 0.00001) {
        a = input / b;
        b = (a + b) / 2;
    }

    std::cout << std::setprecision(10) << "Die Wurzel von " 
              << input << " ist " << a << std::endl;
}

Aufgaben

  1. Im Tutorium wurde demonstriert, wie man C++-Code mit der Kommandozeile kompiliert. Kompilieren Sie also das Programm unter Verwendung einer Kommandozeile Ihrer Wahl und führen Sie es aus. Beschreiben Sie, welchen Befehl Sie dazu verwenden, und geben Sie Ihr Betriebssystem mit an.
  2. Obwohl das Programm eine Fließkommazahl als Eingabe braucht, kann der Nutzer natürlich trotzdem jede beliebige Zeichenkette übergeben. Überlegen Sie sich ein Beispiel für eine unsinnige Eingabe (mit Begründung) und beschreiben Sie, wie das Programm darauf reagiert.
  3. Finden Sie experimentell heraus, welche Funktion std::setprecision hat.
  4. In bestimmten Sonderfällen kann es vorkommen, dass die Schleife nie abbricht. Damit das Programm auch in diesen Fällen terminiert, wollen wir die Anzahl der Schleifendurchläufe begrenzen. Ändern Sie das Programm so ab, dass eine weitere Zahl vom Typ int eingelesen wird, diese Zahl soll die maximale Anzahl der Durchläufe sein. Modifizieren Sie die Schleife so, dass die Maximalanzahl nie überschritten wird.
  5. Ändern Sie das Programm derartig ab, dass zusätzlich zum Ergebnis ausgegeben wird, ob die Schleife die maximale Anzahl der erlaubten Durchläufe erreicht hat.




Aufgabe Abgabe mit Git

Letzte Änderung: 23. April 2020, 12:11 Uhr
10 Punkteim Detail
Ansicht:   |  

In der ersten Woche:

  1. Suchen Sie sich als erstes eine Übungsgruppe!
  2. Loggen Sie sich im Gitlab des Landes RLP (gitlab.rlp.net) ein.
  3. Richten Sie in Microsoft Teams einen gemeinsamen Chat ein.

In den Gitlab-Gruppen (die bis Montag Nachmittag erstellt werden) werden wir automatisiert für jedes Übungsblatt ein neues Git-Repository erstellen in das Sie ihre Abgaben pushen sollten.


Noch ein kurzer Hinweis zu den von uns bereitgestellten Repositories:
Um Verwirrung zu vermeiden haben wir „force-pushes“ auf dem master-Branch für Sie ausgestellt. Der Vorteil ist der, dass ihre Repositories nicht divergieren können, was nur mit etwas mehr Erfahrung wieder lösbar ist und im schlimmsten Fall dazu führt, dass alle Forks und Clones neu initialisiert werden müssen. Der Nachteil ist, dass alle Änderungen auf dem master-Branch damit persistent sind — einmal gepush ist der Commit enthalten, kann aber durch revert wieder mittels eines neuen Commits zurückgezogen werden.


Hinweis:
Auch wenn Sie in dieser Aufgabe etwas falsch machen, können Sie stets den lokalen Ordner des Repositories auf Ihrem Rechner löschen und wieder mit Aufgabenteil 1 anfangen. Sofern Sie ihr Repository nicht gepusht haben, sind alle Änderungen nur lokal!


Nun zur Aufgabe

  1. Clonen Sie das Repository, dass nun in Ihrer Untergruppe in Gitlab erscheinen sollte.
  2. Fügen Sie die Datei heron.cpp aus der letzten Aufgabe in dieses Repository ein und pushen Sie die Änderungen auf den Server.
  3. Ein typischer Fall ist der Folgende: Sie und eine weitere Person (z.B. Ihr(e) Abgabepartner(in)) arbeiten an der selben Datei — schlimmer noch, sie arbeiten an der selben Zeile in der selben Datei.

    Sorgen Sie zuerst dafür, dass beide Personen den selben Repository-Status auf ihrem Rechner haben. (Alternativ können Sie auch in zwei verschiedenen Ordnern jeweils clonen bzw. pullen)
    1. Ersetzen Sie in beiden Repositories denselben Variablennamen durch einen jeweils unterschiedlichen Namen.
    2. Committen Sie beide die Änderung (noch nicht pushen!).
    3. Nun pusht die eine Person die Änderung.
    4. Die andere Person kann nicht pushen, da der master-Branch divergiert ist (sie können es ruhig versuchen). Lösen Sie den Konflikt durch Ausführung des Befehls git pull. (Den Ordner löschen und die Änderung auf dem neuen Commit ausführen ist nicht erlaubt! Es geht hier darum den merge-Konflikt selbst zu lösen. ;) )
  4. Etwas schwieriger, aber auch typischer Fall — diesmal bei der Zusammenarbeit mit fremden Personen, also solchen, die keinen Zugriff auf Ihr eigenes Repository haben:
    Wie Sie vielleicht bemerkt haben, sind die Repositories sog. Forks eines anderen öffentlichen Repositories (dies wird in der Weboberfläche unter dem Repository-Namen angezeigt). Bei Änderungen von vorgegebenem Code werden wir das Ursprungsrepository abändern, dass Sie dann wiederum „fetchen“ und in Ihr Repository einpflegen können. Dies ist übrigens auch die übliche Form von Kollaboration auf Github.com oder ähnlichen Anbietern von Git-Repositories.

    Wir möchten nun einen solchen Fall simulieren;
    Das Szenario ist wie folgt. Sie haben ein Repository geforkt, weil Sie das dort hinterlegte Tool interessant fanden.1 Wir nehmen an, Sie haben bereits ein Feature in das Projekt eingebaut und als Commit in Ihr Repository eingepflegt.2 Ein typisches Problem ist nun, dass das Team, das noch nichts von Ihren Änderungen weiß weiter an dem Projekt gearbeitet hat und in das offizielle Repository, zu dem Sie typischerweise keinen Zugriff haben, gepusht haben.3 In unserer Simulation befindet sich das offizielle Repository des Projektes unter http://gitlab.rlp.net/eis20/materialien/blatt01-fork.

    Nun zur eigentlichen Aufgabe:
    Fügen Sie dieses Repository lokal als weiteres „remote“-Repository ein, fetchen dessen Änderungen und mergen Sie diese Änderungen in ihr Repository ein.
    Vergessen Sie nicht zu pushen wenn sie fertig sind!

    Sie können selbst prüfen, ob Sie alles richtig gemacht haben4:
    • bei einem richtigen Merge sollte Ihr Repository nun eine Abzweigung im Verlauf haben:
      > git tree
      *       71287f0 2020-04-19 (HEAD -> master)  Merge remote-tracking branch 'fork/master' (David Hartmann)
      |\  
      | *     4a8d0ff 2019-04-17 (fork/master)  README changed (David Hartmann)
      * |     3b0e32c 2020-04-19  IHRE COMMIT MESSAGE (IHR NAME)
      |/  
      *       f07be10 2019-04-17 (origin/master, origin/HEAD)  Initial commit (David Hartmann)
      
    • So am Rande: bei einem richtigen Rebase würde die Historie wie folgt aussehen:
      > git tree
      *       f27cbbc 2020-04-19 (HEAD -> master)  IHRE COMMIT MESSAGE (IHR NAME)
      *       4a8d0ff 2019-04-17 (remote/master)  README changed (David Hartmann)
      *       f07be10 2019-04-17 (origin/master, origin/HEAD)  Initial commit (David Hartmann)
      
      Wie sie sehen gibt es keine Abzweigungen und das vor und zurückspringen ist deutlich einfacher als bei einem verzweigten Versionsbaum.
    • In beiden Fällen ist es jedoch so, dass die Commit-IDs des Forks übernommen werden.
      Mit anderen Worten: die Änderung, die Sie in Ihr eigene Repository eingepflegt haben sind die tatsächlichen Änderungen — für git sind es ein und der selbe Commit und weiteres mergen/rebasen ist ohne weiteres möglich, da die bereits eingepflegten Commits nicht mehr auf Korrektheit überprüft werden müssen. Der einzige Nachteil eines Rebases5 behsteht darin, dass es sich nicht mehr um Ihren ursprünglichen Commit, sondern eine Kopie aller Änderungen, handelt — dies ist daran zu beobachten, dass sich die Commit-Id vor und nach einem Rebase ändert.




[1] Genau wie das Lerngruppen-Repository, an dem Sie gerade arbeiten.
[2] Genau wie in Aufgabenteil 2.
[3] Sie planen noch das Team des Projektes zu bitten, Ihr Feature in den offiziellen zweig einzubinden. Dies ist aber noch nicht geschehen.
[4] Einen Befehl den ich stets vielen Empfehle ist git tree. Dieser gibt Ihnen die Versionshistorie wie oben angezeigt auf der Konsole aus. Sie erhalten diesen Befehl, wenn sie ihn einmalig als git-alias wie folgt setzen:

git config --global alias.tree 'log --graph --full-history --all --color --date=short'

[5] Ein anderer Nachteil ist die etwas etwas anderen Verwendung. Aus dem Grund soll in dieser Aufgabe lediglich das Repository gemerged werden.