Wie sieht es mit Deinen Java-Kenntnissen aus? Möchtest Du vordefinierte Formeln eingeben oder maximale Flexibilität wie bei einem richtigen Taschenrechner haben? Soll es eine graphische Oberfläche (GUI) geben oder soll es eine Konsolenanwendung sein?

Nehmen wir mal die Formel



Im Code fragst Du über einen Scanner (oder auch über eine graphische Oberfläche) die drei Variablen ab und führst die Rechnung aus:

try (Scanner scanner = new Scanner(System.in)) {
  System.out.print("a = ");
  double a = scanner.nextDouble();

  System.out.print("b = ");
  double b = scanner.nextDouble();

  System.out.print("c = ");
  double c = scanner.nextDouble();

  double result = a * Math.sqrt(b + Math.pow(c, 2));
  System.out.println("Ergebnis: " + result);
} catch(InputMismatchException e) {
  System.out.println("Fehler: Ungültige Zahl! Punkt statt Komma verwenden!");
}

Wie du siehst, ist das total unflexibel und ein wirklicher Taschenrechner wird das nicht. Besser wäre ein echter Taschenrechner, auf welchem Du Tasten betätigen kannst und somit beliebige Rechnungen möglich sind. Dafür benötigst Du einen Parser. Hier findest Du solch einen fertigen Parser.

Du kannst aber auch einen eigenen Parser implementieren, falls Du dir das zutraust. Schau Dir dazu Folgendes an:

  • Infixnotation: https://de.wikipedia.org/wiki/Infixnotation
  • Reverse Polish Notation: https://en.wikipedia.org/wiki/Reverse_Polish_notation
  • Shunting-yard-Algorithmus: https://de.wikipedia.org/wiki/Shunting-yard-Algorithmus
  • Stack: https://de.wikipedia.org/wiki/Stapelspeicher

Ziel ist, einen Term in Infixnotation in einen Term in RPN-Notation umzuwandeln. Diesen kann man nämlich ziemlich einfach in Java parsen. Dies ist erforderlich, weil verschiedene Operatoren unterschiedliche Rangfolgen haben und somit nicht alles von links nach rechts gerechnet werden kann. Bei der RPN-Notation ist alles direkt so geordnet, wie es auch abgearbeitet werden soll.

Melde Dich gerne bei weiteren Fragen ;-)

...zur Antwort

Inwiefern ist eine ROM für Gaming geeignet oder nicht? Was genau soll die ROM denn bieten? Wenn du einfach nur nach einer schlanken und performanten Custom-ROM suchst, bist du mit LineageOS bestens beraten.

Ansonsten hat der Kernel weitaus größere Auswirkungen auf die Performance. Durch einen Custom-Kernel können beispielsweise CPU-Governor und Overclocking eingestellt werden. Um einen passenden Kernel empfehlen zu können, müsste das Gerätemodell bekannt sein. Generell ist ohne weitere Informationen nicht klar, ob ein Custom-Kernel für dich überhaupt sinnvoll ist.

...zur Antwort
Python 3: Ich habe Fragen zur Implementation des Huffman-Code. Könnt ihr mir helfen?

Hallo Leute,

ich hoffe, dass ich hiermit nicht den Shitstorm of Doom heraufbeschwöre, aber ich komme seit fünf Tagen partout nicht weiter.

1) (2 Punkte) Gegeben sei folgende Nachricht: ”Mississippi River in Ontario isn’t Mississippi River in Mississippi!”

Zeichne den zugehörigen Huffman-Baum und stelle die Codetabelle auf, wie sie es in der Vorlesung gelernt haben. Geben Sie alle erforderlichen Werte an! Wie lautet die oben angegebene Nachricht in ihrer codierten Form?

2) (2 Punkte) Schreibe ein Python 3.7.x Programm, welches die in der Aufgabe 11.1 aufgestellte Codetabelle beinhaltet. Das Programm soll Befehle encode und decode verstehen und die darauffolgende Eingabe codieren oder decodieren können. Falsche Eingaben sind mit einer Warnung in der Konsole zu quittieren. Geben jeweils 5 Testfälle für Codierung und Decodierung an. Zusätzlich gebe an, wie Deine Implementierung die Nachricht

3) (4 Punkte) Schreibe ein in Python 3.7.x Programm, welches eine Eingabe (Nachricht) über die Konsole entgegennimmt, sie analysiert und basierend darauf eine Codetabelle aufbaut.

  • Gebe diese Codetabelle in der Konsole aus.
  • Gebe die codierte Eingabe in der Konsole aus.
  • Implementiere eine Funktion zur Decodierung und gebe die decodierte Nachricht zur Verifikation in der Konsole aus.

Setze die Befehle newbase und showtable um. Ermögliche damit eine neue Eingabe und lasse für diese eine neue Codetabelle berechnen und gegebenenfalls ausgeben. Setze weiterhin Befehle encode und decode um, wie Du es in der Aufgabe 11.2 gemacht hast.

Hinweise:

Zur Lösung dieser Aufgabe dürfen built-in Sortiermethoden verwendet werden. Denke daran, dass nicht alle Datentypen geordnet sind. Dennoch können hier auch solche Datentypen sehr hilfreich sein.

Nicht lauffähige Programme werden nicht bewertet, dabei gilt als Maßstab NUR die Ausführbarkeit in der Konsole!

Aufgabe 1 hab ich noch lösen können,

Ich weiß, im Netz gibt es gefühlt 3000 Huffman Code-Tutorials, aber die sind alle auf fortgeschrittenen Niveau und erklären auch nicht, wie ich diese Code-Tabelle implementieren soll. Zur Erklärung:

  • Spalte 1: Die relative Häufigkeit, wie oft ein Zeichen allgemein im String vorkommt.
  • Spalte 2: Der Logarithmus dualis:



  • Spalte 3: Blockcode der Reihe nach aufgeschrieben
  • Spalte 4: Der Huffman Code (auf den 0 und 1 in der Grafik basierend)
  • Spalte 5: Gewichtete Codelänge (Anzahl der Bits im Huffman-Code * Relative Häufigkeit)

Wie kann ich das in Python berechnen lassen und zusätzlich noch in so einer Tabellenform ausgeben? Dazu müsste man doch alle Werte von diesem Baum manuell eintragen, oder nicht?

Kann ich bei Aufgabe 2) nicht einfach die Variablen neu definieren, z.B. "M == 000" oder ist das geschummelt?

...zur Frage

Aufgabe 3 beinhaltet Aufgabe 2. Daher hier meine Lösung für Aufgabe 3 auf die Schnelle:

import math
from texttable import Texttable

class Tree:
  def __init__(self, chars = None, freq = None):
    self.left = None
    self.right = None
    self.chars = chars
    self.freq = freq

sum1 = 0
sum2 = 0
table = None
text = None

def newbase():
  global sum1, sum2, table, text

  text = input("Eingabe: ")
  table = {}

  for c in text:
    if (not c in table):
      table[c] = [1 / len(text)]
    else:
      table[c][0] += 1 / len(text)

  trees = []
  for r in table:
    trees.append(Tree(r, table[r][0]))

  while (len(trees) > 1):
    trees.sort(key=lambda x: x.freq)

    newTree = Tree(trees[0].chars + trees[1].chars, \
        trees[0].freq + trees[1].freq)
    newTree.left = trees[0]
    newTree.right = trees[1]
    trees.append(newTree)
    trees.pop(0)
    trees.pop(0)

  tree = trees[0]

  for i, c in enumerate(table):
    l = table[c]
    
    s1 = -((math.log(l[0])) / math.log(2)) * l[0]
    sum1 += s1
    l.append(s1)

    form = "{0:0" + str(math.ceil(math.log(len(table), 2))) + "b}"
    l.append(form.format(i))

    huffman = ""
    t = tree
    while (t != None):
      if (t.left != None and c in t.left.chars):
        huffman += "0"
        t = t.left
      elif (t.right != None and c in t.right.chars):
        huffman += "1"
        t = t.right
      else:
        t = None
    
    l.append(huffman)

    s2 = len(huffman) * l[0]
    sum2 += s2
    l.append(s2)

  return table

def showtable():
  t = Texttable()
  t.add_row(["A", "Relative Häufigkeit", "-p(A) ld p(A)", "Blockcode", \
      "Huffmann", "Gewichtete Codelänge"])
  for k, v in table.items():
    t.add_row([k] + v)
  t.add_row(["Summe", 1, str(sum1) + " bit", \
      str(math.ceil(math.log(len(table), 2))) + " bit", "", str(sum2) + " bit"])
  print(t.draw())

def encode():
  encoded = ""

  for c in text:
    encoded += table[c][3]
  
  return encoded

def decode(encoded):
  decoded = ""

  i = 0
  while i < len(encoded):
    j = i + 1
    c = None
    while (c == None):
      s = encoded[i:j]
      for k, v in table.items():
        if (v[3] == s):
          c = k
      j += 1
    
    decoded += c
    i = j-1

  return decoded

table = newbase()
showtable()

encoded = encode()
print (encoded)

decoded = decode(encoded)
print(decoded)

Live-Test: https://repl.it/@tavkomann/Huffman

Im Endeffekt habe ich mich für ein Dictionary entschieden, welches jedem Buchstaben eine Liste mit den restlichen Tabellenspalten zuordnet. Außerdem habe ich einen ganz grundlegenden Baum implementiert.

Schau dir das einfach mal an und versuche es nachzuvollziehen. Das könnte dich für deine eigene Lösung inspirieren. Solltest du konkrete Fragen zu meinem Code haben, frage einfach nach ;-)

...zur Antwort

Um welche Programmiersprache geht es denn?

In Java kannst Du beispielsweise folgendermaßen eine ganzzahlige Zufallszahl zwischen min und max erzeugen:

Random rand = new Random();
int n = rand.nextInt(max - min + 1) + min;

Dies ist eine schnelle Methode zur Erzeugung von Zufallszahlen. So ganz zufällig sind sie jedoch nicht. Daher gibt es für besondere Fälle (beispielsweise Kryptographie), in denen die Zufallszahlen noch zufälliger sein müssen, folgende Methode:

Random rand = new SecureRandom()
int n = random.nextInt(max - min + 1) + min;
Kongruenzgeneratoren

Obige Zufallsgeneratoren sind ziemlich gut. Wenn du jedoch verstehen möchtest, wie sie generell funktionieren, kannst du dir mal die Kongruenzgeneratoren anschauen. Es gibt verschiedene Arten. Ein linearer Kongruenzgenerator, damit können Pseudozufallszahlen erzeugt werden, sieht beispielsweise so aus:



a ist ein Faktor, mit dem der vorherige Zufallswert multipliziert wird. Das Ergebnis wird um c, das Inkrement, erhöht. Außerdem sorgt m dafür, dass sich der Zufallswert innerhalb eines bestimmten Bereiches befindet, sodass sich Zahlen auch wiederholen können. Der Zufallswert ist immer größer null und kleiner m. Der Zufallsgenerator beginnt immer mit einem bestimmten Startwert, welcher beispielsweise aus der aktuellen Zeit bestimmt werden kann.

Eine ganz einfache Java-Implementierung könnte beispielsweise so aussehen:

class SimpleRandom {
  private int max, rand;

  public SimpleRandom(int max) {
    this.max = max;
    rand = (int)(System.currentTimeMillis() % max);
  }

  public int nextInt() {
    rand = (35537 * rand + 7) % 35543;
    return rand % max;
  }
}

Nun können beispielsweise 20 Zufallszahlen im Bereich von 1-100 (ebenfalls nach der Formel ganz oben in meiner Antwort) erzeugt werden:

SimpleRandom rand = new SimpleRandom(100 - 1 + 1);

for (int i = 0; i < 20; ++i) {
  int n = rand.nextInt() + 1;
  System.out.println(n);
}

Die erzeugten Zufallszahlen sind nicht so schlecht, aber für die Praxis eher unbrauchbar. Hier ein Live-Beispiel: https://repl.it/repls/WorthwhileRoughApplication

...zur Antwort
Was ist Arch Linux?

Bei Arch Linux handelt es sich um eine flexible und leichtgewichtige GNU/Linux-Distribution für erfahrene Anwender. Die Besonderheit ist, dass nach der Installation lediglich ein Grundsystem vorliegt, welches optimal nach den Bedürfnissen des Nutzers gestaltet werden kann.

Außerdem handelt es sich um ein sogenanntes Rolling-Release-System, das heißt, dass es keinerlei Betriebssystem-Versionen gibt, bei welchen eine große Menge an Software auf einmal aktualisiert und neue Funktionalität eingebaut wird. Stattdessen werden die einzelnen Pakete kontinuierlich aktualisiert, sodass das System brandaktuell ist. Neuinstallationen sind nie erforderlich.

Ist es ein Betriebssystem?

Ja, es ist ein GNU/Linux-Betriebssystem. Es wird also der Linux-Kernel verwendet und eine große Menge an GNU-Tools eingesetzt. Das System ist unixähnlich.

Was ist daran besser?

Im Vergleich wozu? Zu Windows habe ich bereits hier und hier einen sehr ausführlichen Vergleich vorgenommen. Einen ausführlichen Vergleich zu anderen Distributionen findest du hier.

Was macht Arch aus?

  • Anpassbarkeit: Arch lässt sich extrem stark an deine eigenen Bedürfnisse anpassen. Das System enthält nur das, was du wirklich brauchst und keinen redundanten Schnickschnack. Du nimmst das System nicht einfach so hin wie es ist, sondern du gestaltest es aktiv nach deinen Wünschen. Deshalb sieht ein Arch-System bei jedem Nutzer wahrscheinlich vollkommen anders aus. Der Nachteil ist natürlich, dass zu Beginn nicht alles fertig und direkt nutzbar ist, sondern du erst einmal vieles einrichten musst, bevor du anfangen kannst.
  • Software: Es gibt sehr viele Software-Pakete für Arch. Arch bietet zusätzlich zum Paketmanager pacman das sogenannte AUR an, welches von Nutzern gepflegt wird. Für Debian/Ubuntu soll es zwar insgesamt mehr Pakete geben, jedoch habe ich genau die gegenteilige Erfahrung gemacht ;-)
  • Software direkt vom Entwickler: Während andere Distributionen beispielsweise Desktop-Oberflächen leicht modifizieren, bekommst du bei Arch direkt das Produkt, welches der Entwickler herausgegeben hat.
  • Aktualität: Arch ist durch das Rolling-Release-Modell immer sehr aktuell und Arch-User erhalten so oftmals als erste die neuesten Versionen von Programmen und somit den Zugang zu neuen Features. Dies hat jedoch zur Folge, dass die Updates nicht immer ganz glatt laufen und danach möglicherweise bestimmte Funktionalitäten beeinträchtigt werden. Du musst damit rechnen, hin und wieder mal Hand anlegen zu müssen, um Fehler zu beseitigen. Daher solltest du dich gut mit der Arbeit mit Log-Dateien auskennen, um die Probleme auch selbstständig lösen zu können.
  • Arch-Wiki: Das Arch-Wiki ist das beste Linux-Wiki, welches mir bekannt ist.
Ist es kompliziert?

Es ist kompliziert, wenn man bislang zu wenig GNU/Linux-Erfahrung besitzt. Arch richtet sich wirklich nur an erfahrene Anwender, weil du damit rechnen musst, dass du dir nicht alle Einstellungen zusammenklicken kannst, sondern auch sehr viel mit der CLI arbeiten musst. Daher musst du die grundlegenden Befehle beherrschen und zudem ein gutes Wissen über einzelne Hintergründe besitzen.

Für Einsteiger ist dagegen das auf Arch basierende System Manjaro sehr empfehlenswert. Damit bekommst du natürlich bei weitem nicht alle Vorteile von Arch zu spüren – Manjaro betont stets, dass es nicht Arch ist –, jedoch ist es ebenfalls ein ganz gutes System für Einsteiger, siehe auch: https://wiki.manjaro.org/index.php?title=Manjaro:_A_Different_Kind_of_Beast

Geht es auch gut auf dem Laptop?

Natürlich! Es spielt keine Rolle, ob PC oder Laptop: Solange die notwendigen Treiber für die Hardware vorhanden sind, sollte alles problemlos funktionieren.

...zur Antwort

Das sind sehr viele komplexe Fragen. Hoffentlich liest du das alles, was ich jetzt schreibe. Eigentlich wird das meiste davon sogar schon an Gymnasien im Informatik-Unterricht gelehrt und entspricht einem ganzen Semester...

Logikgatter
Ich weiß dass eine CPU aus unzählig vielen Transistoren besteht. Somit ein Binärsystem besitzt (1;0).

Allein mit dem Prinzip der Transistoren kommt man nicht weiter, das ist zu nah an der wirklichen Hardware. Um etwas Komplexes wie einen Computer zu entwickeln, ist stets Abstraktion erforderlich. Die erste Abstraktionsebene stellen dabei die sogenannten Logikgatter dar. Diese basieren auf dem EVA-Prinzip: Binäre Eingaben werden durch eine Schaltung (bestehend aus Transistoren) in binäre Ausgaben umgewandelt. Dabei existieren drei Grundgatter:

Bild zum Beitrag

Es gibt AND-, OR- und NOT-Gatter. Hier findest du zugehörige Symbole und Tabellen detailliert erklärt.

Das UND-Gatter liefert am Ausgang nur eine 1, sofern beide Eingaben 1 sind. Das ODER-Gatter liefert am Ausgang eine 1, sofern mindestens eine der beiden Eingaben 1 ist. Das NICHT-Gatter liefert am Ausgang eine 1, sofern die Eingabe 0 ist, ansonsten liefert es eine 0. Diese Gatter basieren auf bestimmten elektrischen Schaltungen, welche aber im weiteren Verlauf nicht mehr relevant sind. Es ist wichtig, dass man das Prinzip der Gatter verinnerlicht hat, bevor man sich Gedanken über eine CPU machen kann.

In der Praxis werden zwar die drei Grundgatter oft alle durch NAND-Gatter umgesetzt, aber das vernachlässigen wir der Einfachheit halber mal.

Zum Ausprobieren eignet sich das Programm LogicSIM.

JKMS-Flip-Flop

Die Grundgatter lassen sich zu komplexeren Schaltungen zusammenschließen, sodass wir beispielsweise sogar Daten speichern können. Wichtig sind noch die sogenannten JK-Flip-Flops sowie Multiplexer. Ein JKMS-Flip-Flop sieht so aus:

Bild zum Beitrag

Der mittlere Eingang dient für ein Taktsignal, d. h. eine regelmäßige Abfolge von Einsen und Nullen:

Bild zum Beitrag

Bei einer steigenden Taktflanke werden die Eingaben eingelesen, bei der nächsten fallenden Taktflanke ausgegeben. Sofern der obere Eingang beim Einlesen gesetzt ist, wird eine 1 gespeichert. Ist dagegen der untere Eingang beim Einlesen gesetzt, wird eine 0 gespeichert. Der gespeicherte Wert liegt am Ausgang an. Der untere Ausgang ist dasselbe, nur negiert. Ein JKMS-Flip-Flop ist eigentlich eine Zusammensetzung aus zwei JK-Flip-Flops. Ein JK-Flip-Flop wiederum ist aus einem RS-Flip-Flop zusammengesetzt. Dieses sieht mit den Grundgattern so aus, damit du dir vorstellen kannst, wie das überhaupt funktionieren kann:

Bild zum Beitrag

Geschickt, oder? Jedenfalls werde ich jetzt nicht erklären, wie man davon zum JK-Flip-Flop und letztendlich zum JSMS-Flip-Flop kommt. Das ist auch gar nicht so relevant. Baue das mal in LogicSIM nach und spiele ein bisschen herum, schaue dir an, wie das reagiert.

Multiplexer

Ein Multiplexer wählt aus einer Reihe von Eingaben eine aus und schaltet diese an den Ausgang durch. Hier die Schaltung für einen 1-MUX:

Bild zum Beitrag

s ist quasi ein Schalter. Ist s 0, so wird der obere Ausgang durchgeschaltet, ansonsten der untere. Ebenso gibt es auch einen 2-MUX, welcher zwei Schalteingänge besitzt und somit vier verschiedene Eingaben durchschalten kann.

Das reicht erst einmal an Grundlagen. Das waren nur mal ein paar Beispiele. Die weiteren Grundlagen musst du für ein tieferes Verständnis recherchieren und dir erarbeiten.

Von-Neumann-Architektur

Die Von-Neumann-Architektur bildet die Grundlage für den Aufbau heutiger Computer:

Bild zum Beitrag

Quelle: Lukas Grossar, Von-Neumann Architektur, CC0, Wikimedia Commons

Die CPU ist dabei aus Rechenwerk (ALU) und Steuerwerk zusammengesetzt. Über ein Bus-System können diese mit dem Ein-/Ausgabewerk sowie dem Speicherwerk kommunizieren. Nur in diesem Verbund ergeben die einzelnen Komponenten überhaupt Sinn. Wenn du die Funktionsweise einer CPU klären möchtest, musst du immer alle weiteren Komponenten in die Überlegungen hinzuziehen.

Ein Modellrechner

Der Aufbau heutiger Prozessoren ist sehr komplex. Daher ist es fast unmöglich, anhand der Struktur einen Einblick in Aufbau und Funktionsweise eines Computers zu bekommen. Aus diesem Grund wird oftmals ein Modellrechner zur Rate gezogen, dessen Struktur vereinfacht ist. Der grobe Aufbau des im Folgenden betrachteten Modellrechners ist in der folgenden Abbildung dargestellt:

Bild zum Beitrag

Wie aus der Abbildung hervorgeht, ist ein Computer modular aufgebaut. Deshalb ist es sinnvoll, die Funktion jeder Komponente im Einzelnen zu beschreiben:

  1. Der Taktgeber: Aus einem Dauertaktsignal werden fünf Taktimpulse generiert: Die ersten vier Takte dienen der Rechnung, der fünfte Takt dient der Erhöhung des Befehlszählers um eins und dem Übertragen des aktuellen Befehls aus dem RAM in das Befehlsregister.
  2. Der Befehlszähler: Legt fest, welcher Befehl aus dem RAM ausgelesen wird, indem er die jeweilige Speicherzelle adressiert.
  3. Der RAM: Hier werden alle Befehle gespeichert.
  4. Das Befehlsregister: Das Befehlsregister erhält aus dem RAM mithilfe der Adressierung durch den Befehlszähler den aktuell durchzuführenden Befehl und speichert diesen.
  5. Das Steuerwerk: Das Steuerwerk gibt je nach Belegung des Befehlsregisters unterschiedliche Signale an die Bauteile ab.
  6. Das Eingaberegister: Das Eingaberegister speichert eine Zahl, welche beim nächsten Taktsignal an das Rechenwerk übergeben wird.
  7. Das Rechenwerk (ALU): Hier wird die Zahl aus dem Eingaberegister mit der Zahl aus dem Akkumulator verrechnet. Das Ergebnis wird wiederum im Akkumulator gespeichert, sodass damit weiter gerechnet werden kann.
  8. Ausgaberegister: Bei einem bestimmten Befehlscode wird der Wert des Akkumulators in das Ausgaberegister geschoben und dort als Ausgabe zwischengespeichert.

Eine solche Schaltung kann konkret folgendermaßen realisiert werden:

Bild zum Beitrag

Programmierung des Modellrechners

Damit kannst du beispielsweise 2+2 rechnen. Der obige Rechner ist wenig flexibel – du musst alles von Hand machen. Daher verlinke ich einfach mal eine 4-Bit-CPU:

https://simulator.io/board/AWZpw7Fy3I/2

Das ist letztendlich die praktische Umsetzung obiger Überlegungen. Der Befehlssatz der CPU ist dort ebenfalls aufgeführt:

https://imgur.com/a/zuRd1ZP

Nehmen wir als Beispiel mal kein Videospiel sondern eine Matheaufgabe: Wenn ich 2+2 rechnen will, wird dann einfach ein Code aus mehreren 1 und 0 abgerufen oder wie darf ich das verstehen?

Um also zwei Zahlen zu addieren, würde sich folgendes Programm eignen:

IN
SWP
IN
ADD
OUT

Binär:

0000
0011
0000
0100
0001

Das kannst du auf der Website direkt oben links im ROM per Edit eintragen und die Simulation per Klick auf das dritte Taktsignal starten. So sollte es aussehen:

https://imgur.com/a/UFwdGLj

Nun kannst du damit zwei Zahlen addieren. Nun probieren wir mal etwas Komplizierteres: Wir addieren zwei Zahlen und, sofern die Summe 8 ist, geben wir 5 aus. Ansonsten fragen wir wieder zwei neue Zahlen ab – so lange, bis irgendwann die Summe 8 ist. Das würde so aussehen:

IN
SWP
IN
ADD
SWP
MOV
8
SUB
JZ
12
JMP
0
MOV
5
OUT

Binär:

0000
0011
0000
0100
0011
0010
1000
0101
1011
1100
1010
0000
0010
0101
0001
Und dann zum 2. Teil der Frage: Wie arbeitet eine Programmiersprache? Wie wird es bewerkstelligt dass der PC auf die eingegebenen Zeilen reagiert?

Das geschieht genauso, wie eben beschrieben. Nun handelt es sich dabei um Maschinencode, Einsen und Nullen. Das kann man sich kaum merken, daher gibt es Programmiersprachen der zweiten Generation, sogenannte Assemblersprachen. Diese nutzen, wie man oben sieht, Symbole in Textform (z. B. IN, SWP, ADD, MOV).

...zur Antwort

Ich hoffe, ich verstehe die Frage korrekt. Zunächst einmal muss die Breite der Sanduhr in einer Variable definiert werden, wobei die Breite ungerade sein muss:

int n = 11;

if (n % 2 == 0) {
  printf("Fehler: Nur ungerade Breiten sind möglich!");
  exit(EXIT_FAILURE);
}

Nun geht es erst einmal darum, die Sanduhr ohne Sand auszugeben. Dafür benötigen wir mehrere for-Schleifen. Die äußere Schleife soll Zeile für Zeile durchlaufen. Insgesamt haben wir bei einer Breite von n eine Zeilenanzahl von n-2. Daher sollte die Schleife folgendermaßen aussehen:

for (int i = 0, j = n; i < n-2; ++i, j += (i < n/2) ? -2 : 2) {
  // ...
}

Wie du siehst, benötigen wir einen zweiten Zähler j. Dieser Zähler zählt die Breite in der jeweiligen Zeile. Diese verringert sich bis zur Mitte (n/2) um zwei und erhöht sich danach jede Zeile wieder um zwei. Die Differenz n-j gibt die Zahl der Leerzeichen an. Dabei gibt es links genauso viele Leerzeichen wie rechts. Somit können wir die linken Leerzeichen so ausgeben:

for (int k = 0; k < (n - j) / 2; ++k) {
  printf(" ");
}

Jetzt folgt die Ausgabe der eigentlichen Sanduhr, wobei wir mithilfe einer if-Abfrage dafür sorgen, dass in der ersten und letzten Zeile sowie in der ersten und letzten Spalte eine Raute, ansonsten ein Leerzeichen ausgegeben wird:

for (int k = 0; k < j; ++k) {
  if (i == 0 || i == n-3 || k == 0 || k == j - 1) {
    printf("#");
  } else {
    printf(" ");
  }
}

Bisher sieht unser Code also so aus:

int n = 11;

if (n % 2 == 0) {
  printf("Fehler: Nur ungerade Breiten sind möglich!");
  exit(EXIT_FAILURE);
}

for (int i = 0, j = n; i < n-2; ++i, j += (i < n/2) ? -2 : 2) {
  for (int k = 0; k < (n - j) / 2; ++k) {
    printf(" ");
  }

  for (int k = 0; k < j; ++k) {
    if (i == 0 || i == n-3 || k == 0 || k == j - 1) {
      printf("#");
    } else {
      printf(" ");
    }
  }
  printf("\n");
}

Diese Sanduhr müssen wir mehrmals ausgeben. Wir haben n-2 Zeilen. Darunter ist eine Zeile die Mitte, zwei Zeilen sind obere und untere Grenze. Somit gibt es ((n-2)-1-2) / 2 = (n-5)/2 Zeilen mit Sand. Die Sanduhr müssen wir daher (n-5)/2 + 1 mal ausgeben, um den ganzen Verlauf des Sandes bis ganz nach unten sehen zu können. Wir rahmen den gesamten Code daher durch eine weitere Schleife ein:

for (int x = 0; x < (n-5)/2 + 1; ++x) {
  // ...
}

Unser else teilen wir nun in ein else if und ein else, damit wir unterscheiden können, ob wir Sand oder Leerzeichen ausgeben:

if (...) {
  // ...
} else if ((i >= x+1 && i <= (n-5)/2) ||
    (i >= n-3-x && i <= n-4)) {
  printf("*");
} else {
  printf(" ");
}

Wie ergibt sich die Bedingung für den Sand? Nun, einmal müssen wir den Sand in der oberen und einmal in der unteren Hälfte betrachten. Oben muss die aktuelle Zeile zwischen der oberen Grenze (durch x definiert) und der Mitte liegen, unten zwischen der oberen Grenze (ergibt sich aus x und der Zeilenanzahl) und dem unteren Ende. Das ist auch alles rein mathematisch.

Hier ist der vollständige Code:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  int n = 11;

  if (n % 2 == 0) {
    printf("Fehler: Nur ungerade Breiten sind möglich!");
    exit(EXIT_FAILURE);
  }

  for (int x = 0; x < (n-5)/2 + 1; ++x) {
    for (int i = 0, j = n; i < n-2; ++i, j += (i < n/2) ? -2 : 2) {
      for (int k = 0; k < (n - j) / 2; ++k) {
        printf(" ");
      }

      for (int k = 0; k < j; ++k) {
        if (i == 0 || i == n-3 || k == 0 || k == j - 1) {
          printf("#");
        } else if ((i >= x+1 && i <= (n-5)/2) ||
            (i >= n-3-x && i <= n-4)) {
          printf("*");
        } else {
          printf(" ");
        }
      }
      printf("\n");
    }

    printf("\n");
  }

  return 0;
}

Die Ausgabe ist folgende:

###########
 #*******#
  #*****#
   #***#
    # #
   #   #
  #     #
 #       #
###########

###########
 #       #
  #*****#
   #***#
    # #
   #   #
  #     #
 #*******#
###########

###########
 #       #
  #     #
   #***#
    # #
   #   #
  #*****#
 #*******#
###########

###########
 #       #
  #     #
   #   #
    # #
   #***#
  #*****#
 #*******#
###########

Ich hoffe, die Erklärung ist verständlich genug. Versuche, den Code mal nachzuvollziehen. Hier ein Live-Beispiel: https://repl.it/repls/SpringgreenWelltodoCores

...zur Antwort

Statt dem Komma musst du einen Punkt verwenden. Du solltest die Anweisungen vor der while-Schleife entfernen, damit es nicht zu den Dopplungen kommt, die du angesprochen hast. Es genügt, wenn du vor der Schleife eingabe auf einen Wert ungleich 0 setzt, damit die Schleifenbedingung beim ersten Durchlauf erfüllt ist. Versuche es folgendermaßen:

eingabe = 1

while eingabe != 0:
  print("Geben Sie einen Inch-Wert ein: ")
  inchwert = input()
  eingabe = int(inchwert)

  if eingabe != 0:
    print(eingabe, " inch, sind: ", eingabe * 2.54, "cm")

  elif eingabe == 0:
    print("Eingabe darf nicht gleich 0 sein")
    break
...zur Antwort

Eine gute deutsche Seite ist diese: https://www.linuxmintusers.de/

Außerdem gibt es noch diese englische Seite: https://forums.linuxmint.com/

Ansonsten gibt es auch gute andere Linux-Communities, bei denen du Fragen zu Linux Mint stellen kannst:

  • https://forum.ubuntuusers.de/
  • https://unix.stackexchange.com/
  • Letztendlich bekommt man auch hier bei gutefrage oft gute Antworten, solange die Thematik nicht allzu komplex ist
...zur Antwort

Es existiert keine Möglichkeit mit guter Browserkompatibilität, um Bilder mit CSS zu ändern. Deshalb schlage ich vor, mit Hintergrundbildern zu arbeiten. Dazu erstellst du einen Wrapper für dein Bild:

<div class="avatar-wrapper">
  <img src=“avatar.png” alt="Avatar" class=“avatar” />
</div>

Anschließend weist du dem Wrapper ein Hintergrundbild zu, welches zunächst jedoch durch das eigentliche Bild verdeckt ist:

.avatar-wrapper {
  display: inline-block;
  background-image: url(avatar2.png);
}

Beim Hovern verbirgst du nun das vordere Bild, indem du es transparent machst:

.avatar-wrapper >.avatar:hover {
  opacity: 0;
}

Zudem ist noch folgender Fix erforderlich:

.avatar-wrapper > .avatar {
  vertical-align: top;
}

Hier ein Live-Beispiel: https://jsfiddle.net/w2x3tsz0/

...zur Antwort

Ein Soft-Brick sollte die Recovery nicht beeinflussen – sie sollte nach wie vor funktionieren. Halte zum Erzwingen eines Neustarts Leiser- und Power-Taste 20-30 Sekunden gedrückt und boote anschließend in die Recovery oder zumindest in den Bootloader (der sollte ohnehin funktionieren...).

...zur Antwort

Um die Zeichenketten zu vergleichen, kannst du jeweils jede einzelne Stelle miteinander vergleichen. Dazu kannst du eine Schleife verwenden, mit welcher du überprüfst, ob der Buchstabe der einen Zeichenkette an einer bestimmten Stelle mit dem Buchstaben der zweiten Zeichenkette an derselben Stelle übereinstimmt. Gibt es einen Unterschied, kannst du diesen mithilfe einer Counter-Variable vom Typ Ganzzahl registrieren.

public static int Diff(string a, string b) {
  int differences = 0;
  for (int i = 0; i < Math.Min(a.Length, b.Length); ++i) {
    if (a[i] != b[i]) {
      ++differences;
    }
  }

  differences += Math.Max(a.Length, b.Length)
      - Math.Min(a.Length, b.Length);
  return differences;
}

Wie du siehst, muss auch der Fall betrachtet werden, dass beide Zeichenketten verschieden lang sind. In diesem Fall kann man beispielsweise wie in obigem Code nur die Stellen vergleichen, die in beiden Zeichenketten vorhanden sind. Alle weiteren zusätzlichen Stellen kann man zu der Zahl der Unterschiede hinzuaddieren. Das ist jedoch Definitionssache.

...zur Antwort
Du kriegst die resurrection remix ROM

Nach dem Zurücksetzen wirst du nach wie vor die zuvor installierte Custom-ROM installiert haben. Um wieder die Stock-ROM zu erhalten, musst du diese über Odin oder Heimdall flashen. Samsung-Stock-ROMs findest du bei SamMobile.

...zur Antwort

Klicke im Reiter „Start“ auf „Markieren“ und dann auf „Auswahlbereich“. Dort sind alle Objekte aufgeführt und du kannst sie über das Auge ausblenden.

...zur Antwort

Die einfachste mir bekannte Möglichkeit, Ads ohne Root zu blocken, ist YouTube Vanced. Hier findest du die Installationsanleitung für nicht gerootete Geräte: https://youtubevanced.com/non-root

...zur Antwort
Wo könnten die Fragen gespeichert werden (in App oder online Datenbank)?

Am besten speicherst du die Fragen direkt in der App, damit sie auch offline verfügbar sind. Damit neue Fragen nachgeladen werden können, gibt es zwei Möglichkeiten:

  1. Die App updaten
  2. Neue Fragen aus einer Datenbank nachladen

Die zweite Variante wäre sinnvoller, da dadurch häufige vollständige Updates vermieden werden und nur die Datenmenge geladen wird, die tatsächlich auch erforderlich ist.

Wie könnte zufällig eine noch nicht beantwortete Frage gestellt werden?

Alle noch nicht beantworteten Fragen kannst du in einer Datenstruktur speichern (bzw. Verweise auf die Fragen, die an einer anderen Stelle gespeichert werden), sodass du jede Frage mit einem bestimmten Index ansprechen kannst. Du musst also lediglich eine Zufallszahl generieren: https://stackoverflow.com/questions/363681/how-to-generate-random-integers-within-a-specific-range-in-java

Wie bringt man Sprachenauswahl in's Konzept?

Dafür hat Android schon ein praktisches Konzept mit an Bord: https://stackoverflow.com/questions/11794944/why-to-use-strings-xml

Jeder Text befindet sich also in einer einzigen Datei, die du übersetzen oder übersetzen lassen kannst.

Wie lässt man Anzeigen, wie viele hier Ja oder Nein gedrückt haben (Wie macht man sowas mit Cloud Firestore/Firebase Database)?

Jede Frage sollte eine numerische ID besitzen. In einer Datenbanktabelle kannst du dann zu jeder ID die zugehörige Anzahl der beiden Antwortmöglichkeiten jeweils in einer Spalte speichern. Bei jeder Antwort baust du eine Verbindung zur Datenbank auf und erhöhst den jeweiligen Wert.

...zur Antwort

Ich weiß nicht, ob es eine sauberere Lösung gibt, aber mir ist spontan dieser Workaround mit recht guter Browser-Unterstützung eingefallen:

Du verwendest ein Textfeld...

<input type="text" id="val" value="4" />

..., welches du jedoch unsichtbar machst – aber so, dass das System den Text noch auswählen kann:

#val {
  opacity: 0;
  position: absolute;
  pointer-events: none;
}

Anschließend wird die Zahl ausgewählt und in die Zwischenablage kopiert:

document.getElementById('val').select();
document.execCommand('Copy');

Live-Beispiel: https://jsfiddle.net/s0bn1zn0/

...zur Antwort

Nein, er ist eher sparsamer als die meisten vorinstallierten Launcher, habe ich das Gefühl. Zudem ist er sehr gut konfigurierbar und deshalb sehr empfehlenswert. Der Nova Launcher ist bei mir nicht einmal unter den Anwendungen aufgelistet, die am meisten Akku verbrauchen.

...zur Antwort

Silberfische sind nachtaktiv und verstecken sich tagsüber in allen möglichen Ritzen, Fußleisten, hinter Tapeten, in Kartons, unter Gegenständen, etc. Die Eier werden ebenfalls in Fugen und Spalten abgelegt. Die Tierchen ernähren sich u. a. von Papier, Pappe, Haaren, Hautschuppen, Hausstaubmilben und Kleber. Sie selbst werden wiederum z. B. von Spinnen verzehrt. Besonders ist, dass Silberfische fast ein Jahr lang ohne Nahrung auskommen können. Deswegen genügt es nicht, die Lebensbedingungen für sie zu verschlechtern, sondern bei einem bereits bestehenden Befall musst du aktiv bekämpfen.

Du solltest deshalb darauf achten, regelmäßig und richtig zu lüften. Recherchiere dies im Internet, es wird oft falsch gemacht. Zudem solltest du Staub saugen und den Boden wischen. Achte besonders auf Ritzen und Ecken. Entferne alle herumstehen Kartons, alte Zeitung, Papier und Pappe. Dichte offene Ritzen ab, entferne Schimmel, denn Silberfische können ein Indikator für ein Feuchtigkeitsproblem sein.

Stelle Klebefallen und Köderdosen auf, die du z. B. im Baumarkt erwerben kannst. Verwende aber auch selbst gemachte Fallen wie mit Honig bestrichene Papp- oder Zeitungsstreifen oder eine halbierte Kartoffel, die du morgens einfach zerdrückst. Etwas brutaler ist mit Zucker vermengtes Backpulver, denn dieses bläht sich im Magen der Silberfische auf und tötet diese. Lavendelspray ist ebenfalls ein sehr wirksames Mittel. Grundsätzlich solltest du jeden Silberfisch, den du zu Gesicht bekommst, sofort mit einem Papiertuch töten.

Wendest du diese Tipps an, solltest du den Befall schnell loswerden können, spätestens nach drei Monaten. Voraussetzung ist natürlich, dass du hartnäckig bleibst und nicht nachgibst. Du schaffst das! Ein einzelnes Mittel hat bei mir nicht geholfen, doch durch die Kombination mehrerer Tipps konnte ich den Befall bei mir bekämpfen.

...zur Antwort

Ich habe viele Simulatoren durchprobiert und kann dir sagen, dass die besten Simulatoren meiner Meinung nach von Ovidiu Pop sind. Dazu gehören z. B.:

  • Bus Simulator 3D
  • Bus Driving 2015
  • Bus Simulator 17
  • Coach Bus Simulator

Auch Duty Driver Bus LITE ist nicht schlecht. Allerdings muss ich dazu sagen, dass ich lange Zeit keine neuen Apps mehr getestet habe. Es kann durchaus sein, dass es inzwischen noch bessere Simulatoren gibt. Teste sie doch einfach, wenn du Zeit hast ;)

...zur Antwort