Wie kann ich eine Webseite auf mehreren Clients gleichzeitig aktualisieren?

Hallo alle zusammen,

Ich hab Grundkentnisse in HTML/CSS/JS/PHP und würde gerne versuchen, eine Quiz-Webapp zu programmieren, die man vor Ort gemeinsam spielt.

Ich stelle es mir so vor: Alle Mitspieler rufen zunächst auf ihrem Handy eine Webseite auf, auf der aber zunächst nichts angezeigt wird. Dann wird eine Frage vorgelesen bzw. auf einem Bildschirm angezeigt, und anschließend werden bei allen Mitspielern gleichzeitig auf dem Smartphone die Antwortmöglichkeiten eingeblendet (wird natürlich vom Quizmaster über eine Webapp gesteuert), von der sie dann eine auswählen können.

Es gibt bereits ein Spiel, das genau das macht, Jackbox Party. Auch hier wählen sich die Mitspieler über eine Webseite ein, um am Spiel teilzunehmen. Allerdings will ich eben ein eigenes Quiz mit eigenen Fragen und eigenen Regeln machen.

Meine Frage ist es jetzt, wie ich es schaffe, dass auf allen Smartphones die Antwortmöglichkeiten möglichst gleichzeitig freigeschaltet werden. Der Server kann ja eigentlich den Browsern der Smartphones kein Signal geben, wenn sie nicht vorher eine Anfrage schicken. Ich kann ja aber auch wohl schlecht 10-Mal in der Sekunde eine AJAX-Anfrage an den Server schicken, ob es jetzt soweit ist, oder doch? Würde das überhaupt gehen oder brauchen die Requests da nicht schon zu lange, als dass man es so oft machen kann?

Wie würdet ihr das umsetzen?

Ich freue mich auf eure Vorschläge.

...zur Frage

Eine bidirektionale Verbindung ist mithilfe von WebSockets umsetzbar. Für PHP gibt es die Bibliothek Ratchet. Auf der verlinkten Website findest du ein gutes Tutorial.

Alle Mitspieler rufen zunächst auf ihrem Handy eine Webseite auf, auf der aber zunächst nichts angezeigt wird. Dann wird eine Frage vorgelesen bzw. auf einem Bildschirm angezeigt, und anschließend werden bei allen Mitspielern gleichzeitig auf dem Smartphone die Antwortmöglichkeiten eingeblendet (wird natürlich vom Quizmaster über eine Webapp gesteuert), von der sie dann eine auswählen können.

Letztendlich kann über Ratchet eine Nachricht mit Inhalt der Frage sowie den Antwortmöglichkeiten an die Clients gesendet werden. Mithilfe von JavaScript können diese in die Seite eingebaut werden.

...zur Antwort

Die ersten fünf Zeichen erhältst du folgendermaßen:

print(eingabe1[:5])

Die Zeichen bis zum ersten Slash erhältst du über split:

print(eingabe1.split('/')[0])
...zur Antwort

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
Naja, es geht

Die Idee finde ich generell ganz gut und die Suchergebnisse sind wirklich nicht schlecht. Aber auf Dauer fehlen mir dann doch zu viele Features. Damit meine ich v. a. die vielen netten Miniapplikationen, die bei Google direkt eingebettet sind: Ich kann mir direkt bei Google das Wetter inkl. Diagramm anschauen, einen Taschenrechner benutzen, Informationen über Personen, Filme, Bücher etc. auf einen Blick sehen, mir die Aktien anschauen, die Bundesligatabelle abrufen etc. Es gibt so vieles, was direkt integriert ist und ich bekomme wichtige Informationen ganz schnell, noch bevor ich überhaupt eine Website aus den Suchergebnissen angeklickt habe. Zudem ist die Aufbereitung der Daten und die Reduktion auf das Wesentliche meist extrem gut gelungen.

Ein weiterer großer Vorteil ist, dass Google sehr schnell und die Größe gering ist. Dadurch kann ich selbst bei gedrosselter Verbindung solche Daten relativ schnell abrufen. Das geht viel schneller, als die einzelnen Websites aufzurufen, weil diese meist deutlich langsamer und größer sind.

Diese ganzen Features fehlen mir sehr und daher habe ich für mich bisher keine praktikable Alternative zu Google gefunden. Zu DuckDuckGo würde ich direkt wechseln, sobald mehr solcher Miniapplikationen eingebaut werden. Momentan gibt es außer dem Taschenrechner und direkter Wikipedia-Einbindung kaum etwas.

...zur Antwort

Verwende blur statt focusout und überprüfe, auf welches Element der Focus übertragen wird. Ist es der Button, blendest du ihn nicht aus und überträgst den Focus nach dem Klick wieder zurück auf das Textfeld:

var target = e.relatedTarget;
if (target == null || target.id != 'tgl') {
  tgl.classList.remove('visible');
} else {
  password.focus();
}

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

...zur Antwort

Das liegt an den Standard-Styles des Browsers. Dieser legt standardmäßig bestimmte Abstände fest. Entferne die negativen Margins:

margin-top: -8px;
margin-left: -8px;
margin-right: -10px;

Schnelle Abhilfe schafft folgender Code:

* {
  margin: 0;
  padding: 0;
}

In der Praxis verwendet man eher einen CSS-Reset oder Normalize.css.

...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
Kann man mit einem Raspberry einen NAS bauen?

Ich verwende einen Raspberry Pi für eine Cloud, von daher denke ich, dass ein NAS ebenfalls kein Problem darstellen sollte. Mit Spitzengeschwindigkeiten kannst du natürlich nicht rechnen ;)

Welches Betriebssystem brauche ich [...]

Im Endeffekt könntest du jedes Betriebssystem verwenden, speziell für einen NAS gibt es jedoch OpenMediaVault, welches, ebenso wie Raspbian, auf Debian basiert. Hier findest du eine Anleitung dazu.

[...] und würde es auch über Wlan funktionieren. Und würde es über alle Ethernet-Buchsen im Haus gehen?

Der NAS funktioniert auch über das WLAN, solange das alles dasselbe Netzwerk ist. Welche Ethernet-Buchse du verwendest, spielt keine Rolle.

Welche Komponenten brauche ich?

Im Endeffekt genügt eine schnelle SDXC-Karte mit mindestens Class 10 und viel Speicherplatz. Bedenke, dass die Lebensdauer von SD-Karten nicht allzu hoch ist und du daher regelmäßig Backups erstellen solltest. Wie gut eine externe Festplatte mit dem Raspberry Pi läuft, weiß ich nicht, aber du kannst es ja mal probieren. Zwingend erforderlich ist sie nicht.

...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
werden die privaten Atribute bei einer Unterklasse von der Oberklasse geerbt?

Wirf mal einen Blick in die JLS. Dort findest du Folgendes:

Members of a class that are declared private are not inherited by subclasses of that class.
A private field of a superclass might be accessible to a subclass - for example, if both classes are members of the same class. Nevertheless, a private field is never inherited by a subclass.

Das heißt im Klartext, private Attribute werden niemals vererbt. Es ist schon so, dass im RAM die privaten Attribute im Objekt enthalten sind, dies bezeichnet man aber nicht als Vererbung im klassischen Sinne, weil private Attribute nicht sichtbar sind. Man kann auf sie aus der Subklasse heraus nicht zugreifen.

Und wie kann man Zugang zu den privaten Atributen einer Oberklasse bei einer Unterklasse durch sie (Oberklasse) haben?

Dafür gibt es sogenannte Getter und Setter. Über diese kannst du Zugriff auf private Attribute erhalten:

class A {
  private int x = 0;

  public void setX(int x) {
    this.x = x;
  }

  public int getX() {
    return x;
  }
}

class B extends A {

}

Das klappt nicht:

B b = new B();
b.x = 5;
System.out.println(b.x);

Das hingegen schon:

B b = new B();
b.setX(5);
System.out.println(b.getX());

So allein ergeben Getter und Setter meist wenig Sinn. Hier findest du detailliertere Ausführungen zu der Thematik.

...zur Antwort

Was ist denn mit deiner Leiste passiert? Du kannst mobile Daten letztendlich auch über die Einstellungen aktivieren.

...zur Antwort
Bei meiner HTML Seite will ich durch einen Knopf auf eine neue Seite kommen, die die alte seite ersetzt.

Das lässt sich mithilfe eines Links umsetzen, welchen du wie einen Button stylst:

<a href="URL" class="btn">Klick!</a>
.btn {
  text-decoration: none;
  background-color: #49a0cc;
  color: #fff;
  padding: 10px 19px;
  border-radius: 4px;
  font-weight: 500;
}

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

...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:

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:

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

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:

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:

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:

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:

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:

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

Die Höhe kannst du so nicht angeben. Korrekt wäre:

var winH = $win.height() * 0.1;

Ich jedoch denke, du meinst eher dies:

var winH = $nav.offset().top - $win.height() * 0.9;

Dabei ändert sich die Farbe, sobald das Element zu 10% sichtbar ist.

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

...zur Antwort
wenn man soweit ist "s" auszurechnen, braucht man dafür allem Anschein nach das Inverse von k.

Das ist korrekt.

Aber wie berechne ich das?

Dafür wendest du den erweiterten euklidischen Algorithmus an und bestimmst somit den ggT, welchen du allerdings schon kennst, weil k und p-1 nach Definition teilerfremd sind:

ggT(k, p-1) = 1

In dem gegebenen Beispiel also:

ggT(13, 96) = 1

Schau dir unbedingt den Algorithmus noch einmal an, falls du ihn nicht verstehst. Wir müssen trotzdem den ggT von Hand berechnen. Dies geht wie folgt:

13 = 0 * 96 + 13
96 = 7 * 13 +  5
13 = 2 *  5 +  3
 5 = 1 *  3 +  2
 3 = 1 *  2 +  1
 2 = 2 *  1 +  0

Wie man sieht, ist der ggT korrekterweise auch bei einer Berechnung von Hand 1. Diese Identität können wir nun nutzen und rückwärts auflösen, wobei wir in der vorletzten Zeile beginnen:

1 = 3 - 1*2

Das ist ja klar. Nun gehen wir immer eine weitere Zeile hoch und spezifizieren abwechselnd rechten und linken Faktor genauer, wobei wir die Klammern anschließend direkt wieder auflösen:

1 = 3 - 1*(5 - 1*3) = 3 - 1*5 + 1*3 = 2*3 - 1*5
  = 2*(13 - 2*5) - 1*5 = 2*13 - 4*5 - 1*5 = 2*13 - 5*5
  = 2*13 - 5*(96 - 7*13) = 2*13 - 5*96 + 35*13 = 37*13 - 5*96

Somit ergibt sich:

1 = 37*13 - 5*96

In Modulo-Schreibweise gilt daher:

1 = 37*13 mod 96

Wir schreiben dies nochmals mit Symbolen auf:

1 = (a * k) mod p-1

Hierbei ergibt eine Zahl mal eine andere Zahl 1. Dies ist genau die Definition der Inverse und daher kennen wir sie nun:

a = k^(-1) = 37

  

Weitere Referenzen

  • Gute Erklärung mit farbigen Markierungen: https://www.mathe-online.at/materialien/Franz.Embacher/files/RSA/Euklid.html
  • Gute Erklärung des ElGamal-Signatur-Verfahrens: https://www.mathe-online.at/materialien/Franz.Embacher/files/RSA/Euklid.html
  • Online-Rechner für die Inverse: http://public.hochschule-trier.de/~knorr/multiplikativesInverse.php
...zur Antwort

Gute Definitionen gibt es bei Wikipedia. In dieser Antwort gebrauche ich daher Erklärungen, damit es einen Mehrwert gegenüber Wikipedia gibt.

Klassen

Klassen sind letztendlich nichts Anderes als eigene Datentypen. Bisher hast du bestimmt schon Datentypen wie int (Ganzzahl), double (Kommazahl) oder char (Zeichen) kennengelernt. Mit Klassen hast du in Java die Möglichkeit, eigene Datentypen zu definieren, welche sich aus diesen primitiven Datentypen zusammensetzen. Es handelt sich um komplexe Datentypen.

Um also unnötige Wiederholungen zu vermeiden (DRY-Prinzip) und gleichzeitig dafür zu sorgen, dass niemand mehr den „Code hinter den Kulissen“ verstehen muss, hat man sich etwas ausgedacht, was ziemlich nah am echten Leben ist.

Letztendlich ist im echten Leben alles ein Objekt. Sei es beispielsweise ein Auto. Nun gibt es verschiedene Autos. Sie unterscheiden sich in den Werten bestimmter Eigenschaften wie Farbe, Größe, Form, Leistung etc. Dennoch haben sie auch gewisse Gemeinsamkeiten:

Alle Autos haben eine Farbe, eine Leistung etc. Alle Autos haben gleiche Fähigkeiten wie Beschleunigen, Bremsen, Lenken, Blinken, Hupen etc. Das unterscheidet ein Auto von einem Menschen oder einer Katze. Deshalb macht es Sinn, sich zunächst einen Bauplan für ein solches Objekt zu erstellen. Diesen Bauplan bezeichnet man als Klasse. Eine Klasse könnte so aussehen:

class Auto {
  // Eigenschaften
  public String marke;
  public String kennzeichen;
  public Color farbe;
  // ...

  // Konstruktor
  public Auto(String marke, String kennzeichen, Color farbe) {
    this.marke = marke;
    this.kennzeichen = kennzeichen;
    this.farbe = farbe;
  }

  // Weitere Methoden
  public void hupen() {
    System.out.println("Beep beep");
  }
  // ...
}

Somit ist es, wie ich ganz am Anfang erwähnt hatte, nichts Anderes als ein eigener Datentyp. Ein Objekt, das ich nach dem Bauplan eines Autos erstelle, ist keine Zahl und auch kein Zeichen, sondern ein Auto. Der Datentyp ist folglich Auto.

Ein solcher Bauplan muss festlegen, über welche Eigenschaften und Methoden ein Objekt bzw. eine Instanz der Klasse verfügt. Bei einer Instanz handelt es sich um eine konkrete Ausprägung einer Klasse. Dadurch kann man beliebig viele Objekte gleicher Ursprungsklasse erstellen, diesen jedoch unterschiedliche Werte für Eigenschaften geben.

Du kannst dir das wie einen Bauplan für einen Stuhl vorstellen. Der Bauplan legt fest, wie der Stuhl letztendlich auszusehen hat. In Java wäre dieser Bauplan die Klasse. Nun kannst du aus demselben Bauplan viele Stühle erstellen, denen du jedoch unterschiedliche Werte für Eigenschaften (Farbe, Höhe, Sitzfläche etc.) zuweist. Die Stühle, die nach diesem Bauplan erzeugt worden sind, wären in Java Objekte bzw. Instanzen.

Konstruktor

Zurück zum Auto. Eine Auto-Instanz erstellst du nun so:

Auto vw = new Auto("Volkswagen", "M XY 1234", Color.BLUE);

Oder so für ein anderes Auto:

Auto ferrari = new Auto("Ferrari", "B AB 5678", Color.RED);

Du siehst hier schön, dass die Klasse nur einen Rahmen darstellt. Beim Erzeugen einer Instanz wird der Konstruktor aufgerufen, eine besondere Methode. Hier nochmal der Konstruktor, den du auch im obigen Code findest:

public Auto(String marke, String kennzeichen, Color farbe) {
  this.marke = marke;
  this.kennzeichen = kennzeichen;
  this.farbe = farbe;
}

Im Konstruktor wird alles so eingerichtet, dass ein gültiges Objekt entsteht. Ein Auto kann nicht ohne Farbe, Marke etc. existieren. Daher sorgt der Konstruktor dafür, dass diese Werte direkt bei der Erzeugung eines Objekts gesetzt sind. Wäre dies nicht der Fall, so würde ein semantisch nicht sinnvolles Objekt existieren, bis irgendwann diese Werte gesetzt werden. Das darf jedoch nicht der Fall sein.

Bibliothek

Eine Bibliothek ist eine Sammlung fertiger Hilfsklassen für häufige Anwendungszwecke. Diese kannst du mit dem Schlüsselwort import einbinden und dann verwenden. Der Sinn ist, dass man Zeit einspart, weil man nicht immer das Rad neu erfinden muss. Ein Beispiel stellt Color dar, welches ich in obigen Beispielen verwendet habe. Color kannst du so einbinden:

import java.awt.Color;
...zur Antwort

Dein Code funktioniert bei mir ohne Probleme. Aktiviere die Anzeige von Errors:

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

Entferne das @ vor mail und entferne die Weiterleitung. Nun solltest du eine Fehlermeldung sehen können. Offenbar ist bei dir sendmail nicht korrekt konfiguriert.

...zur Antwort

Dies lässt sich mithilfe von Formularen und JavaScript umsetzen:

<form onsubmit="setURL(this, document.getElementById('part').value);">
  <input id="part" />
  <button type="submit">OK</button>
</form>
function setURL(form, part) {
  form.action = 'url/' + part;
}

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

...zur Antwort
ich habe ein Python Script geschrieben welches ich auf meiner Webseite abbilden will, wie mach ich das am besten?

Das kommt darauf an, welche Programmiersprachen dir auf dem Server zur Verfügung stehen. Mit PHP ließe sich das folgendermaßen umsetzen:

<pre> 
<?php 

echo shell_exec('python3 script.py'); 

?> 
</pre>

Du könntest dir je nach Betriebssystem natürlich auch ein Shell- bzw. Batch-Script schreiben, aber das wäre, im Gegensatz zur obigen Lösung, keine automatische Lösung mehr, weil du das Script nach jeder Änderung manuell ausführen müsstest.

...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

Das ist eine sehr gute Frage! Das Problem ist, dass du den Text zwar durchsichtig machen kannst, aber dadurch wirst du nicht den Farbverlauf, sondern nur den Hintergrund des Buttons zu sehen bekommen. Du musst dir nämlich vorstellen, dass unter dem Text der Hintergrund des Buttons weitergeht. Daher sind die vorgeschlagenen Lösungen (opacity, rgba) nicht zielführend. Die Thematik ist deutlich komplizierter. Ich empfehle für maximale Browser-Kompatibilität die Verwendung eines Bildes, am besten einer SVG-Grafik.

Das kann folgendermaßen aussehen:

<div class="overlay">
  <div id="outer">
    <svg class="transbtn" id="transbtn1">
      <defs>
        <mask id="mask" x="0" y="0" width="100%" height="100%">
          <rect id="overlay" x="0" y="0" width="100%" height="100%" />
          <text id="transtext" x="50%" y="50%">Download</text>
        </mask>
      </defs>
      <rect id="r" x="0" y="0" width="100%" height="100%" />
      <text id="text" x="50%" y="50%">Download</text>
    </svg>
  </div>
</div>
.overlay {
  background: linear-gradient(90deg, #ff0000, #ba00ff, #0005ff);
  background-size: 600% 600%;
  animation: Farbverlauf 30s ease infinite;
  height: 100vh;
  text-align: center;
}

@keyframes Farbverlauf {
  0% {
    background-position: 100% 0%;
  }
  50% {
    background-position: 0% 100%;
  }
  100% {
    background-position: 100% 0%;
  }
}

#outer {
  border: 2px solid #fff;
  display: inline-block;
  border-radius: 10px;
  width: calc(6rem + 30px);
  height: 51px;
}

.transbtn {
  width: calc(100% + 4px);
  height: calc(100% + 4px);
  border-radius: 10px;
  margin-left: -2px;
  margin-top: -2px;
}

.transbtn #border {
  fill: transparent;
  stroke: white;
  stroke-width: 2px;
}

.transbtn text {
  font-family: sans-serif;
  font-size: 16px;
  text-anchor: middle;
  text-transform: uppercase;
  dominant-baseline: middle;
}

.transbtn #text {
  fill: white;
}

.transbtn:hover #text {
  fill: transparent;
}

.transbtn #overlay {
  fill: white;
}

.transbtn #r {
  fill: transparent;
}

.transbtn:hover #r {
  fill: white;
  mask: url(#mask);
}

Hier ein funktionierendes Live-Beispiel, getestet in den aktuellen Versionen von Chromium und Firefox: https://jsfiddle.net/dz0cn3sv/

Ein SVG-Tutorial findest du hier. Ich kann jetzt nicht alles erklären, das wäre zu umfangreich. Deshalb solltest du dich entweder dort einlesen oder es einfach so hinnehmen.

Trotzdem eine kurze Erklärung, weshalb obiges Beispiel funktioniert: Beim Hovern wird der Text quasi transparent. Und zwar richtig transparent, weil der ganze Button ein Bild ist. Somit sieht man nicht den Button-Hintergrund, sondern den richtigen, sprich, den Farbverlauf. Das ist die einzige sinnvolle Lösung, welche mir zurzeit einfällt.

...zur Antwort

Es gibt keine großen Unterschiede, alle Methoden ermöglichen dir Root ohne Einschränkungen. Der einzige Unterschied ist, wie dies ermöglicht wird. Ich würde dir allerdings immer zum Rooten über die Recovery (TWRP oder CWM) raten. Insbesondere würde ich dir Magisk empfehlen. Im Link sind einige Vorteile aufgelistet. Magisk bietet dir die Möglichkeit, die Existenz der Root-Rechte für einzelne Apps zu verbergen, da diese sich sonst stur stellen würden. Außerdem hast du die Möglichkeit, Magisk-Module zu nutzen. Hier ist eine Auflistung der beliebtesten Module. Die wesentlichen Unterschiede zwischen Magisk und SuperSU sind hier zusammengestellt. Letztendlich ist Magisk quasi Root, nur mit ein paar zusätzlichen Vorteilen, welche dir die anderen Methoden nicht bieten.

...zur Antwort

Den Lade-Status des Akkus kannst du nur als Ganzzahl abfragen: https://developer.android.com/reference/android/os/BatteryManager.html#BATTERY_PROPERTY_CAPACITY

Dies funktioniert so (API 21+):

BatteryManager bm = (BatteryManager) getSystemService(BATTERY_SERVICE);
int level = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);

Genauer kannst du den Status nicht abrufen und es ist auch nicht sinnvoll, weil sich das gar nicht so genau feststellen lässt. Außerdem gibt es dafür keinen sinnvollen Anwendungsbereich.

...zur Antwort

Es ist hinsichtlich der Sicherheit überhaupt keine gute Idee, aber du könntest dafür sorgen, dass PHP mit demselben Nutzer ausgeführt wird, über den auch die GUI geöffnet wurde. Verändere dazu in der /etc/apache2/apache2.conf die Zeile, welche mit User beginnt und starte Apache neu. Solltest du einen anderen Webserver verwenden, musst du stattdessen natürlich die entsprechende Konfigurationsdatei anpassen.

Anschließend müsstest du Chromium folgendermaßen starten können:

shell_exec('DISPLAY=:0 chromium youtube.com/tv# -kiosk');

Ansonsten gibt es, falls Verzögerungen von bis zu einer Minute kein Problem darstellen, auch eine Lösung per Cronjob: https://unix.stackexchange.com/questions/78281/how-to-start-a-gui-program-with-php-from-website

...zur Antwort

Wie sollen denn Ein- und Ausgabe erfolgen? Das einfachste wäre natürlich Folgendes:

var a = prompt("a:");
var b = prompt("b:");
var c = parseInt(a) + parseInt(b);
alert(c);

Hierbei wird allerdings nicht geprüft, ob die Eingabe gültig ist. Dasselbe ist natürlich auch mit HTML-Elementen möglich:

<input type="number" id="a" />
<input type="number" id="b" />
<button onclick="add();">Addieren</button>
<p id="c"></p>
function add() {
  var a = document.getElementById('a').value;
  var b = document.getElementById('b').value;
  var c = parseInt(a) + parseInt(b);
  document.getElementById('c').innerHTML = c;
}
...zur Antwort

Ich bevorzuge durchsichtige Hüllen. Warum kauft man sich ein schönes Smartphone, um dann das eigentliche Design durch eine billige Hülle zu verdecken? Dann lohnt sich ja Glas-Optik beispielsweise gar nicht. Bei OnePlus-Geräten ist übrigens sogar eine durchsichtige Hülle kostenlos mit dabei :)

...zur Antwort

Der Entwickler Nguyen Ha Dong meinte dazu [freie Übersetzung]:

Ich denke, es wird heutzutage immer schwieriger, von Apps zu leben, aber es gibt immer noch eine Chance. Nehmen Sie mich als Beispiel. Da ich einen Tagesjob hatte und nicht viel Zeit zum Entwickeln hatte, musste ich ein Spiel entwickeln, das wirklich kurz und einfach war. Ich musste das Spiel auch sehr schwierig machen, um dessen Lebensdauer zu verlängern, weil ich nicht die Ressourcen habe, um laufende Inhalte wie die Big-Game-Unternehmen zu erstellen. Wenn meine Spiele scheitern, geht es mir immer noch gut, weil ich einen guten Tagesjob habe. Der schwierigste Teil ist, dass man etwas anderes machen muss[...]

Statt regelmäßiger Funktionsupdates wurde also auf eine hohe Schwierigkeit gesetzt. Dasselbe hat Google beim Android 5 Easter Egg auch getan.

Quelle: Epstein, Zach: Flappy Bird creator reveals why he made the game so infuriatingly difficult. BGR, 2014. Im Internet: https://bgr.com/2014/02/11/flappy-bird-interview-difficulty/ (zul. abgerufen 20.12.2018).

...zur Antwort

Versuche mal, die Config-Dateien zu entfernen:

rm -r ~/.dropbox*
...zur Antwort

Python Code Falsch?

Moin Moin, ich lerne aktuell Python und stoße auf folgendes Problem:

class Train():
  def __init__(self,route, position):
    self.route = route
    self.position = position
  def show_station(self):
    print(self.route[self.position])
  def move(self):
    if self.position == 4:
      print("Endstation! Alle aussteigen!")
    else:
      self.position = self.position +1
  def move_back(self):
    if self.position == 0:
      print("Alles einsteigen")
    else:
      self.position = self.position - 1

orientexpress = Train(["Paris", "Budapest", "Bukarest", "Istanbul"], 0)
print(orientexpress.position)
orientexpress.show_station()
orientexpress.move()
print(orientexpress.position)
orientexpress.show_station()
orientexpress.move()
orientexpress.show_station()
orientexpress.move()
orientexpress.show_station()
orientexpress.move()
orientexpress.move()
orientexpress.move_back()
print(orientexpress.position)
orientexpress.show_station()

Ich möchte, dass er mir das ausgibt:

Paris
Budapest
Bukarest
Istanbul
Endstation! Alle aussteigen!
Bukarest

Aber ich bekomme das:

0
Paris
1
Budapest
Bukarest
Istanbul
Endstation! Alle aussteigen!
3
Istanbul

Ich denke, der Code ist eigentlich relativ simpel, falls es aber noch einer weiteren Erläuterung braucht:

Es ist so, dass das Attribut self.position den richtigen wert von 3 annimmt, wenn die move_back-Funktion aufgerufen wird, aber die show:station-Funktion gibt trotzdem Istanbul aus. Ich weiß wirklich nicht, warum, die print-Befehle habe ich eingefügt, um den Wert zu überprüfen.

...zur Frage

Lasse auch mal Leerzeilen, dann siehst du vielleicht besser, was eigentlich passiert. Der Index beginnt schon bei 0, daher ist die Endstation bereits bei Position 3, nicht bei Position 4. Dementsprechend kannst du den einen move weglassen, der dazu führt, dass du quasi über die Endstation hinaus fährst (deshalb landest du, wenn du wieder zurück fährst, wieder in Istanbul). So sollte das funktionieren:

class Train():
  def __init__(self, route, position):
    self.route = route
    self.position = position
  def show_station(self):
    print(self.route[self.position])
  def move(self):
    if self.position == 3:
      print("Endstation! Alle aussteigen!")
    else:
      self.position = self.position + 1
  def move_back(self):
    if self.position == 0:
      print("Alles einsteigen")
    else:
      self.position = self.position - 1

orientexpress = Train(["Paris", "Budapest", "Bukarest", "Istanbul"], 0)

orientexpress.show_station()

orientexpress.move()
orientexpress.show_station()

orientexpress.move()
orientexpress.show_station()

orientexpress.move()
orientexpress.show_station()

orientexpress.move()
orientexpress.move_back()
orientexpress.show_station()
...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

Was ist denn die Frage? :D

  1. Startet bei 0 und läuft, solange der Zähler ungleich 10 ist: von 0 bis 9
  2. Startet bei 10 und läuft, solange der Zähler echt größer 0 ist: von 10 bis 1
  3. Startet bei 1 und läuft, solange der Zähler kleiner oder gleich 15 ist, und zwar in Dreierschritten: 1, 4, 7, 10, 13 (denn 16 ist nicht kleiner oder gleich 15)
  4. Startet bei 0 und läuft, solange der Zähler kleiner 3 ist, und zwar in 0,5er-Schritten: von 0 bis 2,5
  5. Startet bei 10 und läuft, solange der Zähler kleiner 0 ist: Kein einziger Durchlauf (denn 10 ist nicht kleiner 0)

Selbst testen kannst du hier: https://repl.it/languages/java

...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

Du kannst ein Add-On verwenden. Für Chrome gibt es beispielsweise dieses: https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk

...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

Für welches Betriebssystem denn? Für den PC habe ich selbst sehr gute Erfahrungen mit Sweet Home 3D gemacht. Damit habe ich den kompletten Grundriss meines Hauses geplant und sogar die Innenräume kann man relativ gut damit planen. Für Android gibt es von denselben Entwicklern das Pendant Renovations 3D. Damit habe ich noch keine Erfahrungen gemacht, aber es sieht auf den ersten Blick recht ähnlich zur PC-Version aus.

...zur Antwort

Probiere mal folgenden regulären Ausdruck:

((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])(\.|$)){4}

Live-Test: https://regex101.com/r/Iwwh2F/1

Erläuterung

Es gibt drei Fälle:

  • Vorne steht „25“. Dann muss eine Zahl von 0-5 folgen.
  • Vorne steht „2“. Dann muss eine Zahl von 0-4 und eine Zahl von 0-9 folgen.
  • Alle weiteren Fälle, wobei nur eine Ziffer erforderlich, die anderen beiden optional sind.

Anschließend folgt entweder ein Punkt oder das Zeilenende. Dies wiederholt sich viermal.

...zur Antwort

Dafür empfehle ich dir MediaInfo. Metadaten kannst du damit folgendermaßen auslesen:

mediainfo --fullscan video.mp4

Zum Rotieren kann ffmpeg verwendet werden:

ffmpeg -i in.mp4 -vf "transpose=1" out.mp4

Setze eine 1 für eine Drehung im Uhrzeigersinn und eine 2 für eine Drehung gegen den Uhrzeigersinn ein. ffmpeg kann auch Metadaten auslesen:

ffprobe video.mp4

Allerdings ist die Ausgabe im Vergleich zu MediaInfo nicht so übersichtlich.

...zur Antwort

Dafür gibt es verschiedenste Möglichkeiten, denn es kommt darauf an, wie dein Header konkret aussieht und in welcher Beziehung Menüpunkt und Text zueinander stehen.

1. Kindelemente

Nutze den Kindkombinator:

.link:hover > .text {
  background-color: red;
}

Live-Beispiel: http://jsfiddle.net/apkzv4u5/

2. Geschwisterelemente

Nutze die angrenzenden Geschwisterselektoren:

.link:hover + .text {
  background-color: red;
}

Live-Beispiel: http://jsfiddle.net/p3es0cL2/

3. Allgemeiner Fall

Dies wird wahrscheinlich in den meisten Fällen die passendste Methode sein. Hierbei ist JavaScript erforderlich, weil Events verarbeitet werden müssen:

for (let i = 0; i < links.length; ++i) {
  links[i].addEventListener('mouseover', function() {
  texts[i].classList.add('active');
});
  
links[i].addEventListener('mouseout', function() {
  texts[i].classList.remove('active');
  });
}

Die Klasse active kann dann im CSS-Code entsprechend so verarbeitet werden, dass eine Hervorhebung zustande kommt.

Live-Beispiel: http://jsfiddle.net/vnqp80dz/

Es könnten natürlich auch IDs eingesetzt werden.

...zur Antwort

Dieses Feature ist lediglich im kostenpflichtigen Nova Launcher Prime enthalten. Alternativ kannst du aber auch kostenlos Notifyer Unread Count verwenden. Dazu musst du die App einfach installieren, das Widget hinzufügen, dieses anklicken und dann den Anweisungen folgen.

...zur Antwort

Da du offensichtlich Nougat auf einem älteren Gerät nutzt, ist bei dir eine Custom-ROM installiert. Wenn du Google-Apps nutzen möchtest, musst du die GApps flashen: https://opengapps.org/

Wähle ARM und Android 7.1. Welches Paket du wählst, kannst du frei entscheiden (je nachdem, welche Apps du benötigst). Lade die ZIP-Datei auf das Gerät, ohne sie zu entpacken. Nun boote in die Recovery. Schalte dazu das Gerät aus und halte Home-, Ein- und Lauter-Taste gedrückt, bis du den Samsung-Bildschirm siehst. Lasse die Ein-Taste los, halte die anderen beiden Tasten aber solange gedrückt, bis die Recovery (TWRP oder CWM) startet.

In der Recovery solltest du nun die Möglichkeit haben, über „Install“ o. Ä. die ZIP-Datei auszuwählen und zu flashen. Danach kannst du das System neu starten. Der erste Start könnte etwas länger dauern. Anschließend sollten alle Apps aus dem gewählten Paket installiert sein.

...zur Antwort

Mir ist keine Galerie bekannt, welche alle von dir genannten Features enthält. Ich habe viel gesucht, aber nichts Gutes gefunden. Stattdessen empfehle ich dir, Screenshot Utility zu verwenden. Dabei kannst du die von dir gefundene Galerie weiterhin verwenden und zum Bearbeiten das Bild über die Share-Funktion an Screenshot Utility weitergeben. Zuschneiden, Freihandmarkierungen und verschiedene Formen sind in der App möglich.

...zur Antwort

Herzlich willkommen zum neuen GNOME :)

Nutze Nemo statt Nautilus, um wieder Desktop-Icons zu haben: https://martinvogel.de/blog/index.php?/archives/142-Wie-man-den-Gnome-Dateimanager-Nautilus-durch-Nemo-ersetzt.html

...zur Antwort

Du versuchst, die Größe des Hintergrunds zu definieren, hast aber gar keinen Hintergrund festgelegt. Ein Video kann nicht als Hintergrund verwendet werden, daher musst du direkt über Mindestbreite und -höhe die Maße festlegen. Außerdem solltest du einen Wrapper verwenden, damit der Rest, der über den Bildschirmrand hinaus geht, abgeschnitten werden kann:

<div class="video_wrapper">
  <video class="video_background" preload="auto" autoplay="true" loop="loop" muted="muted">
    <source src="spin.mp4" type="video/mp4">
    Video not supported
  </video>
</div>
* {
  margin: 0;
  padding: 0;
}

.video_background {
  min-width: 100%;
  min-height: 100vh;
}

.video_wrapper {
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

Live-Beispiel: http://jsfiddle.net/5er3wg6y/

Übrigens wie kann ich das video unmuten?

Das ist nicht möglich, denn autoplay wird von modernen Browsern nur noch bei gemuteten Videos unterstützt. Ansonsten wird eine Aktion des Users, z. B. ein Mausklick, erwartet, um das Video zu starten. Siehe auch https://developers.google.com/web/updates/2017/09/autoplay-policy-changes

...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

Der Text hat keine Höhe, weil du die line-height auf 0 gesetzt hast. Entferne die jeweilige Zeile oder füge Folgendes hinzu:

.intavehead {
  line-height: inherit;
}
...zur Antwort

Schau dir mal TeaVM an. Damit habe ich selbst noch keine Erfahrungen gesammelt, aber du kannst ja mal testen, ob es deinen Anforderungen entspricht.

...zur Antwort

Schau dir noch einmal an, wie das Ganze funktioniert:

Quelle: WissensDürster4Bit-2KomplementCC BY-SA 3.0

Generell erhältst du die Zweierkomplementdarstellung durch folgende Schritte:

  1. Ignoriere das Vorzeichen und rechne die Dezimalzahl ins Binärsystem um
  2. Invertiere alle Bits
  3. Addiere +1

Für die -2 ergibt sich somit:

  1. 00000010
  2. 11111101
  3. 11111110

Und hier siehst du schon, dass das Komplement davon 00000001 ist. Das liegt daran, dass die 00000000 als null und die 11111111 als -1 definiert ist. Der unäre Operator ~ invertiert daher alle Bits.

...zur Antwort

Das ist eine eigene Schriftart. Hier ein Beispiel. Das erste Symbol ist das richtige und das zweite ist dieses Zeichen: „>“. Man sieht den Unterschied sofort. Das dritte ist ein Versuch, dies direkt mit CSS nachzumachen.

...zur Antwort
ich möchte eine Art Labyrinth mit PHP programmieren. [...] Wenn ich [...]  klicke

Für dieses Vorhaben eignet sich eine serverseitige Programmiersprache nicht, weil bei jedem Klick die komplette Seite neu geladen werden müsste, was sicherlich nicht so sinnvoll ist. Daher ist die Verwendung von JavaScript empfehlenswert. HTML und CSS sind übrigens keine Scriptsprachen, sondern HTML ist eine Markup-Sprache und CSS eine Stylesheet-Sprache.

Wenn ich auf eines der unten rechts sich befindenden  Symbole klicke und dann auf ein Kästchen im Labyrinth, so soll dieses Symbol flächendeckend in diesem Kästchen eingefügt werden.

Zunächst brauchst du ein grundlegendes Markup für ein Kästchen. Du hast das Kästchen und in jedem Kästchen befinden sich grundsätzlich zwei Linien. Beide Linien treffen sich in der Mitte, sind aber entsprechend rotiert. Dieses Markup würde sich eignen:

<div class="box">
  <div class="line line-1"></div>
  <div class="line line-2"></div>
</div>

Nun zum Style. Die Box muss einen Rahmen besitzen und die Linien sollten vertikal mittig positioniert werden. Außerdem müssen beide Linien versetzt sein. Somit ergibt sich:

#grid {
  display: flex;
}

.box {
  width: 4rem;
  height: 4rem;
  border: #000 1px solid;
  position: relative;
  display: inline-block;
}

.line {
  width: 2rem;
  border-top: #000 1px solid;
  position: absolute;
  top: 50%;
  transform-origin: right center;
}

.line-2 {
  left: 50%;
  transform-origin: left center;
}

Nun kannst du verschiedene Linien folgendermaßen umsetzen:

<div class="box line-type-1">
  <div class="line line-1"></div>
  <div class="line line-2"></div>
</div>

Für jeden Typ erstellst du nun entsprechende Klassen und rotierst die Linien:

.line-type-1 > .line-2,
.line-type-2 > .line-2,
.line-type-3 > .line-2,
.line-type-4 > .line-2 {
  transform: rotate(90deg);
}

.line-type-2, .line-type-5 {
  transform: rotate(-90deg);
}

.line-type-3 {
  transform: rotate(-180deg);
}

.line-type-4 {
  transform: rotate(-270deg);
}

.line-type-none > .line {
  display: none;
}

Nun benötigst du erst einmal ein 5x5-Raster #grid, welches du mit JavaScript erzeugen kannst. Dabei musst du jeder Box einen Click-Listener hinzufügen:

var grid = document.getElementById('grid');

for (let i = 0; i <= 5; ++i) {
  let div = document.createElement('div');
  for (let j = 0; j <= 5; ++j) {
    let box = document.createElement('div');
    box.className = 'box line-type-none';
    box.innerHTML = '<div class="line line-1"></div><div class="line line-2"></div>';
    box.onclick = function() {
      boxClicked(box);
    };
    div.appendChild(box);
  }
  grid.appendChild(div);
}

Nun brauchst du eine Auswahlmöglichkeit für die Farbe bzw. zum Löschen:

<input type="radio" name="action" value="green" onclick="setColor('green');" checked> Grün<br />
<input type="radio" name="action" value="purple" onclick="setColor('purple');"> Lila<br />
<input type="radio" name="action" value="delete" onclick="setType('none');"> Löschen

Jetzt ist die Funktion zum Setzen der Farbe erforderlich (die Funktion zum Setzen des Typs folgt noch):

var color = 'green';

function setColor(c) {
  color = c;
}

Jetzt kommen die sechs verschiedenen Auswahlmöglichkeiten:

<div class="flex">
  <div class="box line-type-1" onclick="setType('1');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
  <div class="box line-type-2" onclick="setType('2');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
  <div class="box line-type-3" onclick="setType('3');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
  <div class="box line-type-4" onclick="setType('4');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
  <div class="box line-type-5" onclick="setType('5');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
  <div class="box line-type-6" onclick="setType('6');">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
  </div>
</div>

Entsprechend benötigen wir eine Funktion zum Setzen des Typs:

var type = 1

function setType(t) {
  type = t;
}

Jetzt fehlt nur noch die zentrale Funktion zum Einfügen der Symbole. Dazu müssen nur die Klassen angepasst werden:

function boxClicked(box) {
  box.className = 'box line-type-' + type + ' ' + color;
}

Die Farben können entsprechend so in CSS deklariert werden:

.green > .line {
  border-color: #4caf50;
}

.purple > .line {
  border-color: #9400d3;
}

Hier ein Live-Beispiel: http://jsfiddle.net/150unoyj/

Nun folgt deine Aufgabe: Versuche aufbauend auf diesem Grundgerüst zu überprüfen, ob alles korrekt gelöst wurde. Füge dazu einen Button ein. Ein Tipp: Du musst die Klassennamen überprüfen. Solltest du dazu noch Fragen haben, melde dich gerne per Kommentar!

...zur Antwort

Die App ist zwar schon uralt, aber es kann sein, dass sie deinen Erwartungen entspricht: https://play.google.com/store/apps/details?id=com.led.notify

Es gibt einige Nutzer, die Probleme mit der App haben, daher musst du schauen, ob sie bei dir korrekt funktioniert.

...zur Antwort

Ich besitze seit wenigen Monaten das OnePlus 6 und habe damit bislang sehr gute Erfahrungen gemacht. Der erste Eindruck beim Auspacken war schon ziemlich gut. Das Gerät sieht äußerlich sehr gut aus und ist hervorragend verarbeit. Das Ladekabel (Dash Charge) ist von sehr hoher Qualität und lädt unglaublich schnell. Zudem ist eine durchsichtige Hülle enthalten und ein Displayschutz vorappliziert. Letztendlich bin ich bei dieser Hülle geblieben, weil ich sie ausreichend finde und sie das schöne Design des Smartphones nicht beeinflusst.

Das Gerät weist eine hohe Performance auf und läuft jederzeit flüssig. Apps starten immer schnell und ohne Verzögerung. Abstürze und Lags habe ich bisher keine bemerken können. Die Software ist eine der besten, die es gibt. Bei OxygenOS handelt es sich ein sehr schlankes Android, welches sehr nah an Vanilla Android ist, aber um sehr sinnvolle Funktionen erweitert wurde. Redundante Apps (Bloatware) sind nicht vorinstalliert.

Die Kamera ist alles in allem ziemlich gut und erzeugt solide Bilder. Die Qualität ist bei Nacht jedoch nicht ganz so herausragend wie bei Samsung-Geräten. Dies hat sich durch den neuen Nightscape-Modus seit dem neuesten Update jedoch deutlich verbessert.

Der Lautsprecher ist leider nur ein Mono-Lautsprecher und bietet daher keinen sonderlich berauschenden Sound. Es ist in Ordnung, aber hervorragende Soundqualität kann man nicht erwarten. Hinzu kommt das Problem, dass man den Lautsprecher aufgrund seiner Position leicht mit dem Finger verdecken kann.

Die Akkulaufzeit des Geräts ist gut, bei durchschnittlicher Belastung hält der Akku 1,5 - 2 Tage. Benutzt man das Gerät sehr intensiv kommt man trotzdem ziemlich gut über den Tag. Dank des schnellen Ladekabels sollte man überhaupt keine Probleme damit haben.

Der Fingerabdrucksensor funktioniert zuverlässig und reagiert immer noch ohne Verzögerung. Probleme bei der Erkennung treten äußerst selten auf, es genügt dann aber jedes Mal, den Finger einfach nochmals auf den Sensor zu legen. Die Position des Sensors ist im Übrigen sehr gut gewählt, da sie bequem zu erreichen ist.

Updates sind schon einige erschienen und haben bislang keinerlei Probleme verursacht. Zudem hat man bei OnePlus-Geräten den Vorteil, dass man sie beliebig modifizieren (Root, Custom-ROM, Custom-Recovery etc.) kann, ohne dass die Garantie erlischt.

Das Display macht einen guten Eindruck und ist sehr scharf. Der Touchscreen funktioniert zuverlässig und die Bildschirmhelligkeit passt sich seit dem neuesten Update ziemlich gut an die Umgebung an. Die Notch sieht nicht nur gut aus, sondern schafft auch weiteren Platz für das Display. Anfangs war ich zwar eher skeptisch, aber ich habe sie mittlerweile zu schätzen gelernt. Das Bildschirmverhältnis ist sehr angenehm und vorteilhaft beim Lesen von Texten. Bei Videos stößt man auf keine großen Probleme, YouTube bietet sogar die Möglichkeit, Videos auf volle Bildschirmgröße zu zoomen.

Alles in allem ist es ein ziemlich solides und empfehlenswertes Gerät, welches zahlreiche Vorteile bietet, die ich gar nicht alle aufzählen kann. Bisher habe ich ausschließlich gute Erfahrungen mit dem OnePlus 6 gemacht und würde es auf jeden Fall wieder kaufen. Sind dir gute Soundqualität oder gute Nachaufnahmen wichtig, solltest du m. E. jedoch eher zu einem anderen Gerät greifen.

...zur Antwort

Wenn du von einem solchen Problem berichtest, solltest du immer den HTML- und CSS-Code, beispielsweise über JSFiddle, posten. Es ist denkbar, dass du in deinem CSS-Code beispielsweise von der Displaygröße abhängige Styles, welche nicht responsive sind, einsetzt, sodass einzelne Komponenten nicht sichtbar sind. Konkreter kann ich dies ohne Code leider nicht erläutern.

...zur Antwort

Es handelt sich um ROT-13, eine besondere Caesar-Chiffre. Dabei wird jeder Buchstabe um 13 Buchstaben rotiert (bei Verwendung von ausschließlich 26 Buchstaben) – sowohl bei der Verschlüsselung als auch bei der Entschlüsselung. In deinem Beispiel ergibt sich durch Rotation:

Qnf vfg xrva fcnz!
Das ist kein Spam!

Hier findest du ein entsprechendes Online-Tool.

...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

JavaScript Code Probleme?

Hey Leute ich habe eine Frage zu JavaScript unzwar versuche ich aktuell mein Code der in JQuery geschrieben ist in JavaScript zu konvertieren.

Ich habe es hier beispielsweise auch versucht aber es funktioniert nicht.

Wo liegt das Problem ?

JQuery Code:

`&lt;script&gt;$(document).ready(function () {</p><p>      $('#checkinput').on("input", function () {</p><p>        tmpval = $(this).val();</p><p>        if (tmpval == '') {</p><p>          $('#vm').removeClass(' do ');</p><p>          $('#vm').addClass(' donot ');</p><p>        } else {</p><p>          $('#vm').addClass(' do ');</p><p>          $('#vm').removeClass(' donot ');</p><p>        }</p><p>      });</p><p>    });&lt;/script&gt;
</p><p>JavaScript Code:
&lt;script&gt;</p><p>function onCallInput3() {tmpval = document.getElementById("checkinput").value;if (tmpval == '') {document.getElementById('vm').classList.remove('do');document.getElementById('vm').classList.add(' donot ');} else {document.getElementById('vm').classList.add('     do');document.getElementById('vm').classList.remove('  donot');}};&lt;/script&gt;
das ganze soll den button aktivieren und deaktivieren
<span style="color: rgb(131, 148, 150); font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(47, 49, 54); display: inline !important; float: none;">&lt;button id="vm" oninput="onCallInput3()" class="activatedeactivate     donot    " disabled=""&gt;abschicken&lt;/button&gt;
`

...zur Frage

Du hast vergessen, den Event-Listener zu setzen. Deshalb wird die Funktion nie aufgerufen. So sollte der Code aussehen:

function onCallInput3() {
  tmpval = document.getElementById('checkinput').value;
  if (tmpval == '') {
    document.getElementById('vm').classList.remove('do');
    document.getElementById('vm').classList.add('donot');
  } else {
    document.getElementById('vm').classList.add('do');
    document.getElementById('vm').classList.remove('donot');
  }
}

document.getElementById('checkinput').addEventListener('keyup', onCallInput3, false);

Live-Beispiel: http://jsfiddle.net/7qmys9bh/

PS: Du solltest nächstes Mal den Code richtig formatieren, damit man ihn besser lesen kann.

...zur Antwort
Gebootet ist aber eine andere mit Linux 19 als Bertriebssystem.

Linux 19 gibt es noch gar nicht. Du meinst wohl Linux Mint 19 ;)

Hallo ich möchte meine dort installierten Windows Spiele auf der zweiten Festplatte spielen.

Das ist nicht ohne Weiteres möglich. Diese Spiele sind für Windows entwickelt worden und sind daher nicht mit GNU/Linux-Systemen kompatibel. Du kannst aber recherchieren, ob es diese Spiele auch für GNU/Linux-Systeme gibt (beispielsweise über Steam). Ansonsten kannst du probieren, die Applikationen mit Wine zu starten. Das klappt meistens nicht. Als grafisches Frontend für Wine ist PlayOnLinux empfehlenswert.

Solltest du ein Spiel nicht zum Laufen bekommen, bleibt dir nur noch die Verwendung von Windows (siehe Dualboot) oder einer virtuellen Maschine (siehe VirtualBox). Bei Letzterem musst du die Spiele aber i. d. R. in der virtuellen Maschine neu installieren.

Nun hab ich Bedenken das der Start mir was am Linux zerstören könnte.

In welcher Hinsicht? Allein durch die Nutzung von Wine oder einer virtuellen Maschine sollte nicht zerstört werden.

...zur Antwort

Ich kenne Berlin nicht so gut, aber dennoch versuche ich, dir hierbei weiterzuhelfen.

Also Ich suche das Nikolai Viertel in Berlin , also der Ort wo Berlin entstanden ist - sowas suche Ich für Braunschweig.

Die ältesten Gebiete Braunschweigs finden sich in der Innenstadt, dazu zählen insbesondere die Gebiete um den Altstadtmarkt, den Kohlmarkt, den Burgplatz und das Magniviertel. Im Grunde genommen kann man man die Oker ziemlich gut als Begrenzung ansehen, wie auf folgender Karte zu sehen ist: https://www.braunschweig.de/tourismus/ueber-braunschweig/index.html

Und den Alexanderplatz, also die Shopping und Business, Hotel Center auf einem Platz wie Alexanderplatz, aber nur in Braunschweig.

Shoppen kann man ebenfalls am besten in der Innenstadt. Gute Orte sind das Schloss sowie die Gebiete um den Kohlmarkt und die Burgpassage herum. Du wirst selbst feststellen, dass sich dort die meisten Einkaufsstraßen befinden und sich verschiedenste Geschäfte nebeneinander befinden. Am besten fängst du im Schloss an und gehst dann rechts an C&A vorbei zum Kohlmarkt. Dort geht es dann entweder über die Burgpassage (die zurzeit gesperrt ist) oder an New Yorker vorbei über den Sack. Auf dem ganzen Weg gehst du an den wichtigsten Shopping-Geschäften lang.

Die Hotels sind sind an verschiedenen Orten in der Innenstadt konzentriert. Insgesamt ist das meiste sehr gut zu Fuß zu erreichen. Einkaufsläden finden sich in der gesamten Stadt, nicht nur in der Innenstadt. Es gibt keinen Ort, an den es sich lohnt, extra hinzufahren. Banken sind ebenfalls überall vorzufinden.

Dann suche Ich noch ein Platz wie der Potsdamer Platz in Berlin ( Sitz der Unternehmen usw.) nur in braunschweig.

Das kann man nicht so wirklich sagen. Im Zentrum findet man beispielsweise die Sparkasse. Ansonsten sind Gewerbegebiete an mehreren Orten verteilt, beispielsweise der Forschungsflughafen des DLRs oder die Fabrikstraße. Es kommt sehr darauf an, was du konkret suchst.

Und der kurfrürstendamm für braunschweig, aber da weiß ich nicht was typisch ist... ich glaube da sind viele Ärzte oder so.

Ein gutes Ärztezentrum findest du beispielsweise an der Elbestraße sowie im Galeria Kaufhof. Ansonsten solltest du konkrete Ärzte eher recherchieren – manchmal kann es sich auch lohnen zu einem Spezialisten (z. B. in Wolfenbüttel) zu fahren.

Also Orte wo sich viele Menschen aufhalten ( bitte mit Grunddaseinfunktion des Ortes nennen wie die Orte in Berlin) in Braunschweig auch ich.

Am belebtesten ist es sicherlich in der Innenstadt um die ganzen Läden herum – das ist aber keineswegs vergleichbar mit Berlin. Ansonsten gibt es mehrere gute Parks wie den Bürgerpark, den Prinz-Albrecht-Park oder das Gebiet um den Südsee.

Um die Innenstadt herum befinden sich mehrere Wohnsiedlungen. Insbesondere das westliche und östliche Ringgebiet sowie die Weststadt sind typische Orte für Wohnungen. Etwas ruhiger ist es dagegen in Gebieten wie Broitzem, Stöckheim oder Querum. Der Trend geht dahin, dass Neubaugebiete für Häuser weiter außen liegen, letztens sind Lamme, Leiferde sowie Bevenrode hinzugekommen. Je weiter man nach außen gelangt, desto mehr bekommt man das Gefühl, dass das alles gar nicht mehr so wirklich eine ganze Stadt ist, sondern eher einzelne Dörfer mit eigenem Zentrum. Das hängt auch damit zusammen, dass diese Gebiete früher gar nicht zu Braunschweig gehört haben.

Das zum grundsätzlichen Aufbau. Ansonsten gibt es verschiedenste Schwerpunktgebiete. So findet man beispielsweise im Nordosten viele Möbelgeschäfte und zahlreiche Geschäfte mit dem Fokus auf das Eigenheim bzw. die Wohnung. Es ist nicht unbedingt alles an einem Ort zu finden. Es wäre zu umfangreich, jetzt alle Orte genau auszuführen. Besser wäre es, wenn du konkret nachfragst, wonach du suchst. Dann kann ich dir auch genauere Empfehlungen für Orte und Geschäfte geben.

...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

Angefangen hat es bei mir im Prinzip in der Bibliothek. Wir haben hier eine sehr gute Stadtbibliothek, in welcher ich in meiner Kindheit sehr viel Zeit verbracht habe. Es gibt eine Informatik-Abteilung, welche über 300 Bücher über Programmierung enthält. Irgendwie war ich fasziniert davon und habe mir damals diese Programmierbücher für Kinder ausgeliehen. Zu dieser Zeit ging ich noch in die Grundschule.

Zudem entwickelte mein Vater eine Website für meine Mutter, welche selbstständig war (er hatte es eher angelernt und war kein richtiger Webentwickler, sondern eigentlich auf Hardware spezialisiert). So habe ich dann in der Zeit von Netscape und Composer HTML gelernt, weil ich selbst Websites entwickeln können wollte. Mich faszinierte es, dass ich mit dem Computer kommunizieren kann, dass ich einem nicht lebenden Objekt mitteilen kann, was es zu tun hat.

Mit der Zeit habe ich dann nicht mehr so viel in die Richtung gemacht, aber als ich aufs Gymnasium ging, erinnerte ich mich daran, was ich mir eigentlich mal vorgenommen habe. Also lernte ich CSS, PHP und JavaScript dazu. Damit habe ich einige Jahre verbracht, in denen ich tausendseitige Bücher und zahlreiche Online-Artikel gelesen sowie viele Projekte umgesetzt habe.

Nun waren PHP und JavaScript schon mal ein guter Einstieg in die Programmierung, aber ich wollte mehr. Damals hatte ich sehr viele Web-Apps und hybride Apps erstellt, doch ich wollte endlich „richtige“ native Apps und Programme schreiben. Also lernte ich Java. Das war auch die Lehrsprache an meiner Schule und durch meine tiefreichenden Kenntnisse war ich anderen Schülern schon deutlich voraus (außer einem, der programmierte auch in der Freizeit). Dies war mein Ausweg aus der Webentwicklung in weitere Sektoren.

Zudem hatte ich das Glück, einen der besten Informatik-Lehrer gehabt zu haben, welcher sehr viel Programmierung und Objektorientierung im Unterricht ansetzte. Im Vergleich zum Kollegen aus NRW muss ich sagen, dass hier in Niedersachsen wohl deutlich mehr Programmierung auf dem Plan steht. Los geht es meist mit Scratch und Lego Mindstorms, dann kommt irgendwann Java.

Allerdings sind ganz klar riesige Unterschiede zwischen den Lehrkräften vorhanden. Es gibt Lehrer, welche nicht einmal Informatik studiert, sondern dies nur so angelernt haben, weil in dem Bereich einfach ein großer Mangel besteht. Lehrer aus einer anderen Stadt, welche den Unterricht mal besuchten, stellten ein vergleichsweise deutlich höheres Niveau bei uns fest. Dies ist vorteilhaft für die guten Schüler, aber bedeutet natürlich auch mehr Arbeit für die etwas schwächeren Schüler. Alles hat seine Vor- und Nachteile. Für mich war es nur ein Vorteil.

Letztendlich habe ich im Unterricht und auch zu Hause sehr viele Zusatzaufgaben bearbeitet und im Grunde genommen schon fast das Studium im Bereich der Programmierung vorweg genommen: Sortieralgorithmen, Suchalgorithmen, Graphenalgorithmen, Datenstrukturen, ein GTR (Infix Evaluator), Java EE und vieles mehr habe ich in der Zeit umgesetzt.

Java war dabei die zentrale Programmiersprache, aber auch C lernte ich über Mikrocontroller aus der Freizeit (hatte damals damit einen Wettbewerb in Niedersachsen gewonnen) kennen. Auf Python stieß ich ebenfalls irgendwie und derweil hatte ich schon recht früh den Wechsel von Windows zu GNU/Linux vollzogen. Und so kamen über die Jahre immer weitere Programmiersprachen, aber auch jede Menge weitere elementare Kenntnisse, welche tatsächlich fast noch wichtiger als die Sprache selbst sind, dazu. Man kann so ein dickes Buch wunderbar in den Urlaub mitnehmen und am Strand lesen. Dann gucken die Leute auch manchmal, aber es hinterlässt eine gebildete Wirkung ;)

Fazit: Lies Bücher (von Online-Tutorials und Videos rate ich stark ab!) und nimm dir ausreichend Zeit, um genügend Erfahrung zu sammeln. Solltest du Interesse daran haben und Spaß am Programmieren empfinden, so sammelt sich das Wissen über die Jahre schon von selbst an. Es gibt immer irgendetwas zu lernen und daher hilft es, zusätzlich sehr viele Blogartikel im Internet zu lesen und auch mal Bücher auszuleihen, welche sich nicht um eine Programmiersprache, sondern um ein bestimmtes Konzept drehen.

Für den Einstieg kann ich dir jedenfalls Java empfehlen, einige empfehlen aber auch Python. Letztendlich ist es deine Entscheidung, womit du anfängst, aber allein schon aufgrund des Prinzips der Objektorientierung, welches in Java wesentlich elementarer verankert ist (v. a. in den Büchern merkt man das daran, dass in Java schon sehr früh die Objektorientierung erklärt wird, in Python erst deutlich später). Das sehe ich als entscheidenden Vorteil im Hinblick auf die Herausbildung eines guten Code-Stils an.

Solltest du noch irgendwelche Fragen haben, melde dich gerne per Kommentar ^_^

...zur Antwort

document.getElementsByTagName liefert ein HTMLCollection-Objekt zurück, denn es können schließlich mehrere Elemente mit demselben Tag im DOM existieren. Der Tag-Name ist im Gegensatz zu einer ID nicht eindeutig. Die einzelnen Elemente kannst du nach folgendem Schema ansprechen (n ist die Anzahl an Elementen mit dem jeweiligen Tag-Namen):

document.getElementsByTagName[0]
document.getElementsByTagName[1]
document.getElementsByTagName[2]
...
document.getElementsByTagName[n-1]

Um also hierbei nur den einen Footer anzusprechen, schreibe Folgendes:

document.getElementsByTagName('footer')[0].innerHTML = 'Hello World';
...zur Antwort

Das ist durchaus machbar. Für eine Drop-Down-Liste kannst du dir das OptionMenu ansehen. Wie man E-Mails versenden kann, ist in der Dokumentation beschrieben: https://docs.python.org/3.4/library/email-examples.html Schau dir auch diesen Thread an: https://stackoverflow.com/a/10147497/8292104

Alles Weitere sollte für dich nichts Neues sein.

...zur Antwort

Eine Liste durchläufst du mit:

for dict in l:
  # ...

Nun kannst du den Wert für c abfragen:

c = dict['c']

Jetzt kommt der Trick: Anstatt mit Substrings zu arbeiten, kannst du dir direkt das Trennzeichen (Komma) zu Nutze machen. Dafür gibt es die Funktion split, welche einen String an einem Trennzeichen in eine Liste aufteilt. Uns interessiert der zweite String in dieser Liste:

c.split(',')[1]

Insgesamt ergibt sich also folgender Code:

l = [{'a' : '1,x', 'b' : '2,y', 'c' : '3,z'}]

for dict in l:
  c = dict['c']
  print(c.split(',')[1])

Dieser Code gibt jedes z in der Liste l aus.

...zur Antwort

Java: Ausgabe der while-Schleife II?

Moin,

Das ist eine Folgefrage auf "Java: Ausgabe der while-Schleife ?"

Ich habe jetzt versucht mit einer Arraylist zu arbeiten.

Ich wollte die Arraylist bearbeiten und jeden einzelnen bearbeiten schritt in "alleListen" einfügen. da ich wieder schreibe - klappt es nicht :)

Mein Fehler ist wie vorher, nur das gegenteil oder? macht das sinn?^^

Werte = new ArrayList<>(); is ja quatsch

letzteZahl+=letzteZahl; erfüllt auch nicht den zweck

Die Ausgabe die ich haben wollte ist:

[[2, 3, 4, 8], [2, 3, 4, 16], [2, 3, 4, 32], [2, 3, 4, 64], [2, 3, 4, 128], [2, 3, 4, 256]]
        ArrayList<ArrayList<Integer>> alleListen = new ArrayList<>();
        ArrayList<Integer> werte = new ArrayList<>();
        
        werte.add(2);
        werte.add(3);
        werte.add(4);
        werte.add(4);
        
        int menge = 6;
        int cnt = 0;
        int letzteZahl = 0;

        while (cnt < menge) {                      letzteZahl = werte.get(3);         letzteZahl*=2;

        werte.remove(3);
        werte.add(letzteZahl);
        
        alleListen.add(werte);
        
        werte = new ArrayList<>();
        
        werte.add(alleListen.get(0).get(0));
        werte.add(alleListen.get(0).get(1));
        werte.add(alleListen.get(0).get(2));
        werte.add(alleListen.get(0).get(3));
        
        cnt++;
        
        }
        
        System.out.print(alleListen);

Ausgabe:

[[2, 3, 4, 8], [2, 3, 4, 16], [2, 3, 4, 16], [2, 3, 4, 16], [2, 3, 4, 16], [2, 3, 4, 16]]
...zur Frage
Mein Fehler ist wie vorher, nur das gegenteil oder? macht das sinn?^^

Nicht ganz. Dein Code ist fast korrekt. Diesmal ist es nur ein ganz kleiner Flüchtigkeitsfehler. Ersetze

werte.add(alleListen.get(0).get(0));
werte.add(alleListen.get(0).get(1));
werte.add(alleListen.get(0).get(2));
werte.add(alleListen.get(0).get(3));

durch

werte.add(alleListen.get(cnt).get(0));
werte.add(alleListen.get(cnt).get(1));
werte.add(alleListen.get(cnt).get(2));
werte.add(alleListen.get(cnt).get(3));

Ansonsten schaust du nämlich immer nur auf die erste Liste in alleListen, weshalb sich der Wert ab dem zweiten Durchlauf nicht mehr ändert.

Außerdem kannst du

werte.remove(3);
werte.add(letzteZahl);

verkürzen zu

werte.set(3, letzteZahl);

Auf die Effizienz dieser Methode gehe ich in dieser Antwort noch nicht ein. Am Anfang ist es erst einmal wichtig, dass man überhaupt ein Gespür dafür bekommt, wie man bestimmte Probleme lösen kann. Wenn dies selbstständig gelingt, ist das optimal. Später, wenn man etwas mehr Erfahrung hat, kann man sich darum bemühen, seinen Code zu verbessern.

PS: Duzen ist ganz gut ;)

...zur Antwort

Ich versuche mal, das Schritt für Schritt zu erklären.

Das Problem

Du hast eine Liste und fügst dieser in jedem Schleifendurchlauf eine Zahl hinzu:

ArrayList<Integer> liste = new ArrayList<Integer>();
liste.add(0);
liste.add(1);
liste.add(2);
liste.add(3);
// ...

Nichts Anderes als dies tust du. Nun gib diese Liste nach der Schleife mal aus. Du bekommst logischerweise

[0, 1, 2, 3, 4, 5]

als Ausgabe.

Jetzt fügst du diese Liste in jedem Schleifendurchlauf einer anderen Liste hinzu:

alleListen.add(liste);

Man könnte jetzt annehmen, dass die Ausgabe eigentlich so aussehen sollte:

[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]]

Und tatsächlich sieht sie so aus, wenn du die Zeile

alleListen.add(liste);

in Folgendes umwandelst:

alleListen.add(new ArrayList(liste));

Aber warum ist das so?

Es wird nicht die Liste eingefügt, sondern der Wert der Referenz (Java ist immer pass by (reference) value). Ein solcher Wert kann z. B. so aussehen:

ArrayList@7d4991ad 

Das steht eigentlich in der Gesamtliste. Das musst du dir wie eine Adresse vorstellen. Das ist eine Art Zeiger, der immer auf die Liste zeigt, welche irgendwo im RAM liegt. Die Liste existiert nicht mehrfach, das wäre doch nicht sinnvoll, sondern nur einmal im RAM. Alle Zuweisungen sind nur Verweise auf diese Liste. Veränderst du die Liste, so verändert sich natürlich auch die Gesamtliste, weil diese ja dauerhaft auf die Liste zeigt.

Stelle dir ein Regal mit Schubladen vor. Das Regal ist die Gesamtliste. Nun legst du in jede Schublade nicht ein weiteres Regal mit Schubladen (die Liste, die du zuweist), sondern du legst lediglich einen Zettel rein, auf welchem steht, wo du das andere Regal finden kannst (Referenz). Nachdem die Schleife komplett durchgelaufen ist, sieht das Regal so aus:

Regal {
  Schublade { Anderes Regal steht im Wohnzimmer },
  Schublade { Anderes Regal steht im Wohnzimmer },
  Schublade { Anderes Regal steht im Wohnzimmer },
  Schublade { Anderes Regal steht im Wohnzimmer },
  Schublade { Anderes Regal steht im Wohnzimmer },
  Schublade { Anderes Regal steht im Wohnzimmer }
}

Das andere Regal sieht so aus:

Regal2 {
  Schublade { 0 },
  Schublade { 1 },
  Schublade { 2 },
  Schublade { 3 },
  Schublade { 4 },
  Schublade { 5 }
}

Wenn du nun den Inhalt des ersten Regals ermittelst (die ArrayList ausgibst), dann wird immer beim zweiten Regal nachgeschaut und so lässt sich die von dir beobachtete Ausgabe erklären.

Die Lösung

Lege immer neue Listen an:

ArrayList<ArrayList<Integer>> alleListen = new ArrayList<>();
ArrayList<Integer> liste = new ArrayList<>();
int menge = 6;
int cnt = 0;

while (cnt < menge) {
  liste = new ArrayList<Integer>();
  liste.add(cnt);
  alleListen.add(liste);
  cnt++;
}        

System.out.print(alleListen);

Dadurch enthält die Gesamtliste nun mehrere Werte von Referenzen auf unterschiedliche Listen.

Weitere Hinweise

  • Achte darauf, die Java Conventions einzuhalten. Bezeichnungen von Variablen und Methoden beginnen mit einem kleinen Buchstaben.
  • Nutze Abkürzungen. Statt
ArrayList<Integer> liste = new ArrayList<Integer>();

kannst du auch Folgendes schreiben:

ArrayList<Integer> liste = new ArrayList<>();

Fragen?

Frage gerne per Kommentar nach ;-)

...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

Was soll ich installieren?

[...]was für Programme Brauch ich um mit java zu programmieren[...]

Zunächst benötigst du das JDK. Eine Anleitung zur vollständigen Installation findest du hier für verschiedene Betriebssysteme. Anschließend kann es auch schon los gehen. Mit einem beliebigen Editor kannst du eine .java-Datei erstellen, in die du den Programmcode schreibst. Anschließend kannst du mithilfe eines Terminals bzw. CMD kompilieren

javac Name.java

sowie ausführen

java Name

Als Editor eignet sich beispielsweise Atom. Dies ist für den Einstieg ganz gut und man sollte dies definitiv beherrschen. Ansonsten wirst du relativ schnell merken, dass dies für etwas größere Projekte nicht so komfortabel ist. Eine IDE kann Abhilfe schaffen, denn in dieser sind Editor, Debugger, Compiler und vieles mehr integriert. Für Java empfehle ich in dieser Hinsicht NetBeans, Eclipse und IntelliJ.

Eclipse ist aufgrund des Plugins WindowBuilder besonders für Swing-Applikationen geeignet. IntelliJ überzeugt dagegen mit einer hervorragenden Autovervollständigung, welche dir sehr viel Arbeit abnimmt. Es spielt keine Rolle, für welche IDE du dich letztendlich entscheidest, weil dies reine Geschmackssache ist. Teste am besten alle durch, sobald du etwas mehr Erfahrung hast. Am Anfang solltest du einfach irgendeine nehmen.

Solltest du unterwegs bzw. an einem anderen Rechner sein, ist eine Online-IDE wie repl.it übrigens eine tolle Sache.

Hello world!

[...]Und wie lässt man einen Text anzeigen (mit voller Erklärung bitte)[...]

Dies funktioniert in Java folgendermaßen:

public class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}

Es macht kaum Sinn, das jetzt alles zu erklären, weil dabei eine Erklärung des Prinzips der objektorientierten Programmierung unvermeidlich ist. Darüber habe ich hier einen groben Überblick geschrieben: https://www.gutefrage.net/frage/klassen-in-java#answer-275933262

Dennoch mal ganz grundlegend:

public class Main {

Eine öffentliche Klasse namens "Main".

public static void main(String[] args) {

Eine öffentliche, statische Methode namens "main", welche nichts zurückgibt und als Parameter ein String-Array übergeben bekommt, welches innerhalb der Methode über die Bezeichnung "args" angesprochen werden kann.

System.out.println("Hello world!");

Die Ausgabe der Zeichenkette "Hello world!" über den Standard-Output-Stream.

So, das war jetzt ganz grob und ich bin mir sicher, dass du nichts verstehst. Doch das ist nicht schlimm, denn du hast Java schließlich noch nicht gelernt.

Wie lerne ich Java?

Ich rate dir sehr dazu, ein Buch und keine Video-Reihe oder ein Online-Tutorial zu verwenden. Gründe habe ich hier zusammengefasst. Für den Einstieg würde ich aufgrund der Tatsache, dass du zuvor "nur" mit Batch programmiert hast, eher zu folgendem Buch raten:

https://www.amazon.de/Programmieren-lernen-Java-WindowBuilder-Programmieranf%C3%A4nger/dp/3836256053

Nachdem du ausreichend Erfahrung gesammelt hast (min. ein Jahr), solltest du folgendes Buch lesen:

https://www.amazon.de/Java-auch-eine-Insel-Java-Entwickler/dp/3836258692

Um schließlich alle Bereiche von Java SE theoretisch abdecken zu können, auch noch dieses:

https://www.amazon.de/Java-SE-9-Standard-Bibliothek-Handbuch-Entwickler/dp/3836258749

Weitergehen kann es beispielsweise auch mit Java EE oder Android-Development. Die vorgeschlagenen Bücher gibt es übrigens in vielen Bibliotheken, sodass du kein Geld ausgeben musst.

Was tun, wenn ich Schwierigkeiten habe?

Zum Nachschlagen eignet sich bei Java eine beliebige Suchmaschine, denn im Internet finden sich zahlreiche hilfreiche Ressourcen. Vor allem die Docs

https://docs.oracle.com/en/

und Stackoverflow

https://stackoverflow.com/

sind gute Anlaufstellen.

Also sehr viel lesen?!

Nein, auf keinen Fall! Bücher vermitteln Theorie und Theorie ist essentiell, doch man kann nicht erwarten, dass man ein Buch liest und dann Java perfekt beherrscht. Ich meine, ein Buch über Kochen oder Autofahren bringt dich auch nicht wirklich weiter, wenn du es nie probiert hast, oder?

Die primäre Lernquelle wird immer die Erfahrung sein. Über die Bücher lernst du nur die Theorie. Allgemein sollte das Motto "Learning by doing" sein, denn Theorie allein nützt einem rein gar nichts. Man kann so viel lesen, wie man will, doch es gelingt keinem Buch der Welt, das Wissen zusammenzufassen, welches ein erfahrener Java-Entwickler besitzt.

Ein paar Tipps für Projekte findest du hier. Ich möchte dabei noch einmal eine ausdrückliche Empfehlung für Java Kara aussprechen.

Was kann ich mit Java machen?

[...]und was man mit java alles machen kann[...]

Das habe ich bereits hier zusammengefasst: https://www.gutefrage.net/frage/wofuer-ist-java-denn-gut?

Solltest du weitere Fragen haben, so melde dich gerne per Kommentar :)

...zur Antwort
Ich habe mich dazu entschieden, diese Welt zu verlassen.

Ich verstehe vielleicht nicht genau, wie du dich fühlst, ich kann es aber nicht mit meinem Gewissen vereinbaren, dir Tipps zu geben, das kann ich einfach nicht. Ich will dich nicht einfach gehen lassen, sondern ich möchte, dass du deine Entscheidung überdenkst, auch wenn es dir schwer fällt. Ich werde dir nicht erzählen, dass bessere Zeiten folgen werden oder dass es nicht so schlimm ist. Genauso werde ich dir nicht sagen, wie du dich verhalten sollst.

Nein, ich will versuchen, deine Probleme zu verstehen. Ich weiß, dass nicht alles nach Plan gelaufen ist und dass du dich am Boden zerstört fühlst. Und diese außerordentlich schlechte Lage möchte ich auch nicht leugnen. Mir ist bewusst, dass deine Entscheidung keine freiwillige ist, sondern die Wahrnehmung eines Menschen, der in eine psychische Krise geraten ist, beträchtlich verändert und eingeengt ist. Die Entscheidungs- und Handlungsfreiheit ist eingeschränkt.

Ich weiß es auch überaus zu schätzen, dass du alles in deiner Macht stehende getan hast, um Hilfe zu finden. Du denkst sogar an deine Mitmenschen und dir ist klar, dass es sich um eine schwerwiegende Entscheidung handelt. Du bist ein guter Mensch!

Ich habe mich schon ein paar Personen mit meinen Problemen anvertraut. Menschen, denen ich vertraue. Die Menschen hören mir auch zu und helfen mir, doch all die Hilfe, auch Telefonsorge und Therapie, hilft nicht.

Ich verstehe. Es kann wirklich frustrierend sein, so viele Dinge auszuprobieren und trotzdem keine Lösung zu finden. Ich weiß nicht, wie wir deine Probleme lösen können und kann dich dabei leider nicht unterstützen. Ich weiß aber, dass ich mir Sorgen um die Auswirkungen mache, die diese Probleme auf dein Leben und das Leben deiner Mitmenschen haben. Ich will nicht, dass du dir etwas antust, denn du lebst nur einmal und das Leben ist wertvoll.

Du bist nicht allein, es gibt genügend Menschen, die dich lieben. Ich weiß, du glaubst mir das nicht, doch es stimmt: Jemand liebt dich und will nicht, dass du gehst, dass du diese Welt verlässt. Ich weiß, dass ich dich nicht von deiner Entscheidung abhalten kann, denn es ist deine Entscheidung und die will ich dir nicht nehmen, aber ich möchte dich bitten, nochmals alles gründlich zu überdenken. Gehe noch einmal dein ganzes Leben durch und beleuchte wirklich alle Dinge, um zu verstehen, was schief gelaufen ist und wie es dazu kommen konnte. Behalte bitte immer im Auge, dass du nur einmal leben kannst und es danach vorbei ist. Alles, was du jemals tun wolltest, kannst du nicht mehr tun.

"Viele Menschen haben sich umbringen wollen und sich zuletzt damit begnügt, ihre Photographie zu zerreißen." - Jules Renard

...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

Das ist im Flugmodus mithilfe von ADB möglich: https://www.xda-developers.com/customize-radios-airplane-mode-android/

...zur Antwort

Mehrere Dinge sind hierbei zu beachten:

  • Halte die Java Conventions ein und benenne Klassen mit einem großen Anfangsbuchstaben. Verwende zudem aussagekräftigere Bezeichnungen
  • Strings werden mithilfe der equals-Methode verglichen
  • Um statische Methoden einer anderen Klasse aufzurufen, musst du schon kennzeichnen, dass diese Methode in einer anderen Klasse deklariert ist. Dazu hängt man den Klassennamen davor an.

Folgender Code ist funktionsfähig:

// ExampleClass.java

import javax.swing.JOptionPane;

public class ExampleClass {
    public static void test() {
        JOptionPane.showMessageDialog(null, "Test", "Test-Fenster",
                JOptionPane.INFORMATION_MESSAGE);
    }
}


// Main.java

import javax.swing.JOptionPane;

public class Main {
    public static void main(String args[]) {
        String eingabe = JOptionPane.showInputDialog(null,
                "Bitte geben Sie was ein!", "Input-Box");
        if (eingabe.equals("Hallo")) {
            ExampleClass.test();
        }
    }
}
...zur Antwort

Diese Angriffsmethode nennt sich XSS (Cross-Site Scripting). Dies sollte als Schutz bei der Ausgabe von Nutzereingaben im HTML-Code genügen:

$noxss = htmlspecialchars($input);

Bei der Ausgabe in anderen Teilen, z. B. im JS-Code, sind weitere Absicherungsschritte erforderlich.

...zur Antwort
Wie sieht es aber bei gefloateten Elementen aus? Wie wirkt sich da, der negative Margin aus?

Das verhält sich etwas anders. Es gibt zwei verschiedene Fälle.

Negativer Margin in Floatrichtung

Floatest du nach links und wendest einen negativen margin-left an, so verhält sich das genauso wie bei statisch positionierten Elementen. Dasselbe gilt für float: right und margin-right. Beispiel: https://jsfiddle.net/xu7Lmuok/

Negativer Margin entgegen der Floatrichtung

Wendest du nun einen negativen Margin entgegen der Floatrichtung an, so merkst du auf den ersten Blick keinen Unterschied, egal wie stark du den Margin erhöhst. Es scheint, als hätte der negative Margin gar keine Auswirkung. Beispiel: https://jsfiddle.net/eaL223sd/

Nehmen wir an, du hast folgendes Layout: https://jsfiddle.net/2gvsrLoy/

Nun wenden wir einen negativen Margin entgegen der Floatrichtung an: https://jsfiddle.net/7t2zy4Lh/

Wie du siehst, verändert sich das Element selbst nicht, aber für andere gefloatete Elemente verhält es sich nun so, als wäre die Breite um den Betrag des negativen Margins geringer. Der von dir verlinkte Artikel versucht nun zu erklären, dass dies praktisch ist, wenn man ein Spaltenlayout hat, in dem eine Spalte eine feste Breite (hier: 200px) hat und die andere Spalte dynamisch den restlichen Platz füllen soll.

Außer einem Spaltenlayout ist z. B. auch Folgendes möglich: https://jsfiddle.net/y3dhw22d/

Dies klappt nur dank des negativen Margins und hat gegenüber dem Verringern der Breite den Vorteil, dass der Text an anderen Stellen weiterhin die volle Breite einnimmt, siehe das Gegenbeispiel ohne negativen Margins, sondern mit geringerer Breite: https://jsfiddle.net/vm6d3k0n/

Wie du siehst, ist hier die Variante mit negativen Margins viel besser, weil das Element weiterhin die volle Breite einnimmt, wenn dies möglich ist. Der negative Margin verändert also nicht zwangsläufig die Breite des Elements, schafft aber Platz für andere Elemente, der bei Bedarf auch genutzt wird.

Eine weitere gute Referenz

Hier findest du einen weiteren guten Artikel über das Thema: https://www.smashingmagazine.com/2009/07/the-definitive-guide-to-using-negative-margins/

Ich denke, der Rest deines Artikels sollte nun klar sein. Ansonsten kannst du gerne noch spezifisch nachfragen ;-)

...zur Antwort
Ich kann mir das visuell nicht vorstellen.

Deshalb habe ich dir mal eine Animation erstellt: https://jsfiddle.net/4hwjjspy/

Das Blaue ist das Elternelement. Das Rote ist der Rahmen um das Kindelement. Das Grüne ist der Content des Kindelements. Zunächst wird der Padding hinzugefügt. Dadurch wird der Content selbst nach innen verschoben. Deswegen wird er anschließend über den negativen Margin wieder an den Rahmen des Elternelements geschoben. Welchen Sinn das nun hat, hängt natürlich vom jeweiligen Sachzusammenhang ab.

...zur Antwort

ADB ist die Android Debug Bridge. Dabei handelt es sich um eine Software-Schnittstelle, mit der du mit deinem Android OS mithilfe eines Computer kommunizieren kannst. Dies geschieht i. d. R. über USB. ADB kannst du hier herunterladen: https://forum.xda-developers.com/showthread.php?t=2588979

Anschließend steht es dir als CMD-/Terminal-Befehl zur Verfügung.

...zur Antwort

Ich kenne das Problem nicht, weil ich dieses Gerät nicht besitze, aber da hier keine Antwort mehr zu erwarten ist, mal ein Tipp: Nutze doch einfach die Google Contacts-App. Dort kannst du Kontakte direkt mit deinem Google-Konto verknüpfen, sodass sie beim nächsten Umstieg direkt auf dem anderen Gerät vorhanden sind.

...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
Was braucht denn beim S9+ soviel mehr, dass ich quasi schon wieder von Anfang an an der Kapazitätsgrenze bin?

Du verstehst das nicht richtig, das ist eine Fehlvorstellung. Du bist noch nicht an der Kapazitätsgrenze, auch wenn der RAM fast voll ist. Nach und nach füllt sich der RAM mit den Apps, die du benutzt. Er wird dann automatisch vom Android-System gereinigt, damit du neue Apps starten kannst. Der RAM sollte möglichst voll sein, damit du schneller zwischen Apps wechseln kannst.

Der RAM wird zum Cachen genutzt

Ein voller RAM ist nicht schlecht, sondern unter Unix- und Linux-Systemen sogar erwünscht. Android nutzt den Linux-Kernel und dieser verfolgt die Philosophie, dass freier Speicher verschwendeter Speicher ist. Der verfügbare Speicher wird zum Cachen häufig verwendeter Dateien verwendet, um das System zu beschleunigen, weil der RAM nämlich deutlich schneller als der interne Speicher ist. Auch viele Apps, v. a. Browser, bedienen sich eines Caches, um schneller zu sein und die User Experience zu verbessern.

Gut, wir halten also fest, dass es zweifellos gut ist, den RAM als Cache zu verwenden. Nun möchtest du wohl nicht, dass dieser Cache deinen gesamten RAM einnimmt. Du möchtest, dass der freie Speicher sofort für weitere Apps, die du startest, zur Verfügung steht und siehst den Cache daher als Problem an.

Der Cache nimmt den gesamten RAM ein - ein Problem?

Das ist aber gar kein Problem, denn gecachte Daten haben eine niedrige Priorität und werden schnell verworfen, wenn mehr Speicher für etwas Anderes benötigt wird. Darum gibt es also gar keinen Nachteil, den RAM für das Cachen zu verwenden, sondern nur Vorteile.

Leerer RAM ist nämlich nutzlos. Das Beschreiben von leerem RAM ist nicht schneller als das Beschreiben von genutztem RAM. Ebenso reduziert leerer RAM den Akkuverbrauch nicht. Freier RAM ist einzig und allein eine pure Verschwendung, die keine Vorteile mit sich bringt.

Apps nicht schließen, keine Task Killer nutzen!

Das ist übrigens auch der Grund, weshalb es in Android keinen direkten Schließen-Button für Apps gibt. Man sollte Apps generell nicht über die App-Übersicht schließen, denn das verschlechtert nur die Performance. Dasselbe gilt für Task Killer - diese richten mehr Schaden als Nutzen an. Stattdessen werden Apps im RAM aufbewahrt und pausiert, sodass sie keine CPU-Zeit verbrauchen. Soll die App wieder gestartet werden, kann dies dadurch weitaus schneller geschehen, da sie sich schon im RAM befindet.

Fazit: Lasse Android sich selbst um den RAM kümmern, das System weiß schon, was es tut. Solange du keine spürbaren Performance-Probleme hast, brauchst du dir über den RAM-Verbrauch keine Gedanken machen.

...zur Antwort

Nein, eine solche App kann es nicht geben, weil die entsprechenden Funktionen direkt in die Hardware eingebaut ist. Repariere die Taste oder lasse sie reparieren, alles Andere macht keinen Sinn.

Dennoch mal eine Lösung, die etwas "von hinten durch die Brust ins Auge" ist:

  • Kaufe dir einen USB-JIG
  • Installiere den Samsung-Gerätetreiber auf dem PC: http://developer.samsung.com/galaxy/others/android-usb-driver-for-windows
  • Installiere Odin: https://odindownload.com/
  • Lade dir diese Datei herunter: http://www.mediafire.com/file/xbruaqwuryjnaua/OdinForceReboot+-+UNZIP\_ME.zip
  • Entpacke sie, es sollte eine .tar-Datei enthalten sein

Das sind die Voraussetzungen. Zum Starten des Gerätes, musst du jedes Mal Folgendes tun:

  • Schließe den USB-JIG an, dein Gerät startet in den Download-Mode
  • Entferne den USB-JIG
  • Bestätige die Warnung
  • Schließe das Gerät per USB an den PC an
  • Starte Odin
  • Wähle bei den Optionen nur F. Reset Time und Auto Reboot, sonst nichts
  • Wähle bei AP die .tar-Datei aus
  • Drücke Start und warte, bis das Samsung-Logo erscheint
  • Trenne die USB-Verbindung
  • Dein Smartphone sollte jetzt starten

Viel Erfolg :)

...zur Antwort

Du kannst zwar die APKs entpacken, doch das wird dich wahrscheinlich kaum weiter bringen. Wenn du den Source-Code einer App verändern möchtest, nutze das APK Studio dafür. Klicke auf dieser Seite oben auf "download", um den Windows-Installer herunterladen zu können: http://vaibhavpandey.com/apkstudio/

Achte darauf, keine Urheberrechtsverstöße zu begehen und nutze die manipulierten APKs nur für den privaten Gebrauch, veröffentliche sie auf keinen Fall.

...zur Antwort

Du benötigst einen Webserver wie Apache und den PHP-Interpreter.

Apache:

apt update
apt dist-upgrade
apt install apache2
chown -R pi:www-data /var/www/html/
chmod -R 770 /var/www/html/

Teste, ob die Einrichtung funktioniert hat. Du müsstest die Apache-Default-Seite sehen, wenn du die IP-Adresse des Raspberry Pis in einem Browser eingibst.

PHP:

apt install php7.0-common php7.0-fpm php7.0-curl php7.0-gd php7.0-cli php7.0-mcrypt php7.0 php7.0-opcache php7.0-mbstring php7.0-xml php7.0-zip libapache2-mod-php7.0

Teste, indem du im du im Verzeichnis /var/www/html eine PHP-Datei mit folgendem Inhalt anlegst:

<?php phpinfo(); ?>

Du solltest, wenn du die Seite im Browser aufrufst, die PHP-Infoseite sehen.

Willst du eigentlich etwas Anderes machen, musst du dies deutlicher erläutern.

...zur Antwort

Aufbau von IP-Adressen

IPv4-Adressen sind nach folgendem Schema aufgebaut:

xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Die 4 Byte = 32 Bit werden in vier Oktetts (á 8 Bit) aufgeteilt.

Generell werden die vier Binärzahlen in Dezimalzahlen umgerechnet und die dotted-decimal notation wird so gebildet. Angelehnt an die Telefonvorwahl bestimmen die ersten Stellen das Netz. Dieser Teil wird als Netzadressteil bezeichnet. Die restlichen Bits geben das Endsystem an, welches auch als Host bezeichnet wird. Dies ist der Hostadressteil.

Es gibt zwei Möglichkeiten, um die Anzahl der Binärstellen, die das Netz kennzeichnen, anzugeben:

  1. Man nutzt eine Zahlengruppe, die wie eine Netzadresse aussieht. Sie besitzt im Netzadressteil nur Einsen, im Hostadressteil nur Nullen. Diese Zahlengruppe heißt Netzmaske. Beispiel: 255.255.0.0 für Klasse B.
  2. Die moderne Schreibweise: Man hängt die binäre Stellenzahl an die IP-Adresse an. Beispiel: xxx.xxx.xxx.xxx/16 für Klasse B.

Einteilung in Netzklassen und Berechnung des theoretischen Adressbereichs

In der Anfangszeit des Internets wurden fünf Netzklassen gebildet. Ein Präfix, die sogenannten Klassen-Bits dienten zur Kennzeichnung. Die Präfixe sind für die Klassen A - E 0, 10, 110, 1110 und 1111. Diese Präfixe sind einfach so festgelegt worden. Nun kann der theoretische Adressbereich bestimmt werden.

Klasse A:

Eine Adresse sieht so aus:

0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Alles mit einem x ist variabel, der Rest fest. Nun ist der niedrigste Wert logischerweise

00000000.00000000.00000000.00000000

Der höchste Wert ist

01111111.11111111.11111111.11111111

Dies ergibt, umgerechnet in Dezimalzahlen einen theoretischen Adressbereich von 0.0.0.0 bis 127.255.255.255.

Somit sind 128 Netze und 256 * 256 * 256 - 2 = 16 777 214 Hosts möglich. Zwei Hosts müssen aufgrund der Netzadresse und der Broadcastadresse abgezogen werden. Die Netzadresse ist die niedrigste Adresse (alle Bits im Hostadressteil sind 0), die Broadcastadresse ist die höchste Adresse (alle Bits im Hostadressteil sind 1) in einem Netz.

Klasse B:

Eine Adresse sieht so aus:

10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Der niedrigste Wert ist

10000000.00000000.00000000.00000000

Der höchste Wert ist

10111111.11111111.11111111.11111111

Dies ergibt einen theoretischen Adressbereich von 128.0.0.0 bis 191.255.255.255.

Somit sind (191 - 128 + 1) * 256 = 16 384 Netze und 256 * 256 - 2 = 65 534 Hosts möglich.

Klasse C:

Eine Adresse sieht so aus:

110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Der niedrigste Wert ist

11000000.00000000.00000000.00000000

Der höhste Wert ist

11011111.11111111.11111111.11111111

Dies ergibt eine theoretischen Adressbereich von 192.0.0.0 bis 223.255.255.255.

Somit sind (223 - 192 + 1) * 256 * 256 = 2 097 152 Netze und 256 - 2 = 254 Hosts möglich.

Klasse D:

Eine Adresse sieht so aus:

1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Der niedrigste Wert ist

11100000.00000000.00000000.00000000

Der höchste Wert ist

11101111.11111111.11111111.11111111

Dies ergibt einen theoretischen Adressbereich von 224.0.0.0 bis 239.255.255.255.

Diese Adressen werden nicht wie bei den Klassen A bis C vergeben, sondern sie dienen dem Multicasting.

Klasse E:

Eine Adresse sieht so aus:

1111xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

Der niedrigste Wert ist

11110000.00000000.00000000.00000000

Der höchste Wert ist

11111111.11111111.11111111.11111111

Dies ergibt einen theoretischen Adressbereich von 240.0.0.0 bis 255.255.255.255. Dieser Bereich ist für experimentelle zukünftige Anwendungen reserviert.

Ausnahmeregelungen - reservierte Adressräume

Es handelt sich oben explizit um theoretische Adressräume. Allerdings sind einige Adressräume reserviert. Dies sind u. a.:

  • 0.0.0.0: Der Host selbst, siehe auch http://www.searchnetworking.de/antwort/Wofuer-wird-die-IP-Adresse-0000-verwendet
  • 10.x.x.x: Früher für experimentelle Zwecke, heute für private Class-A-Netze
  • 127.x.x.x: Localhost (127.0.0.1), Loopback
  • 169.254.x.x: APIPA
  • 172.16.0.0 - 172.31.255.255: private Class-B-Netze
  • 192.168.x.x: private Class-C-Netze

Aus diesem Grund sind die tatsächlich gültigen Oktettbereiche

  • für Klasse A: 0 - 126
  • für Klasse B: 128 - 191
  • für Klasse C: 192 - 223
  • für Klasse D: 224 - 239
  • für Klasse E: 240 - 255

Welchen Sinn hatten diese Netzklassen?

Die Welt war damals sehr vom Telefon geprägt. Man wollte bei den IP-Adressen alles genauso machen, wie du schon an meinem obigen Vergleich der Vorwahl mit dem Netzadressteil siehst. So dachte man sich, es gibt große Städte mit kurzen Vorwahlen und langen Teilnehmernummer. Deshalb wollte man wenige sehr große Netze, eine Mittelklasse und sehr viele ziemlich kleine Netze (Dörfer besitzen nämlich längere Vorwahlen) schaffen. Klingt sinnvoll, doch hat man zwei entscheidende Fehler gemacht:

  1. Verschwenderischer Umgang: Früher schien eine Adressgröße von 2³² für ziemlich viel und man hätte nie gedacht, dass das Internet je so stark benutzt wird. Die Netzadressbereiche sind einfach nach Anfrage zugeteilt worden, auch wenn so große Netze wie Class-A gar nicht erforderlich gewesen wären, und so belegten wenige Firmen und Organisationen schnell die Hälfte alle möglichen IP-Adressen.
  2. Inflexibilität: Heute ist eine Netzgröße von 254 Hosts meistens zu klein, 65 534 Hosts sind dagegen zu viele. Somit passen die Klassen gar nicht zum tatsächlichen Bedarf.

Lösung des Problems - CIDR und NAT gegen die IP-Adressraumverknappung

Zunächst wurde das Konzept 1985 durch Subnetting (Einteilung eines Netzes in Teilnetze) und 1992 durch Supernetting (Zusammenschluss von "unbrauchbar" kleinen Netzen) ergänzt. 1993 wurde schließlich das Classless Inter-Domain Routing (CIDR) eingeführt. CIDR hob die Längenbeschränkung der Netzmaske auf die festen Werte 8, 16 und 24 Bits und somit die Klassen A, B und C auf. Dadurch können heute die Netzgrößen besser den Anforderungen angepasst werden.

Heute werden Computer zudem nicht mehr direkt an das WAN angeschlossen wie zur Zeit, als man noch davon ausging, dass der IPv4-Adressraum für alle ausreichen würde. Aufgrund der zunehmenden IP-Adressraumverknappung und der zu langwierigen Entwicklung von Nachfolgern für IPv4 (z.B. IPv6) wurde 1994 erstmals NAT eingesetzt wurde.

Dabei lässt man pro Haushalt i.d.R. nur noch einen Internetzugang zu. Da wir aber mehr als nur einen PC nutzen, kommen an dieser Stelle die Internetrouter ins Spiel. Alle Computer werden mithilfe eines Switches, in modernen Routern bereits integriert, zu einem Heimnetzwerk, dem LAN, verbunden. Der Router ist sowohl an das LAN als auch an das WAN angeschlossen.

Sendet nun ein Computer einen Request an eine Website, so geht dieser eigentlich an den Router. Der Router übersetzt diesen Request durch Masquerading, u. a. anhand von Routing- und Forwardingtabellen, und sendet selbst den Request ab. Die Response wird schließlich wieder an den jeweiligen Rechner weitergeleitet. Durch diese Technik können mehrere Rechner mit unterschiedlichen internen IP-Adressen über eine einzige öffentliche IP-Adresse Internetzugriff erhalten, was die Anzahl der benötigten IP-Adressen nochmals deutlich reduziert und der IP-Adressraumverknappung entgegenwirkt.

Fragen?

Das dürfte fürs Erste alles Wichtige sein, was du zu diesem Thema wissen musst. Wenn du noch weitere Fragen haben solltest, kannst du dich gerne per Kommentar an mich wenden ;-)

...zur Antwort
Sonst wundert man sich hinterher, warum eine Anwendung zwischendurch so zäh reagiert, weil der Garbage Collector rumrödelt, oder etwa nicht?

Bei den meisten Anwendungen sollte das gar keine so große Bedeutung haben, weil bei einem Scanner i. d. R. auch eine Pause kommt, während der der Nutzer eine Eingabe tätigt. Ich habe mal Folgendes probiert, um zu schauen, wie der GC darauf reagiert:

public class Test {
  public static void main (String[] args) {
    Runtime r = Runtime.getRuntime();
    while (true) {
      System.out.println(r.freeMemory());
      new java.util.Scanner(System.in);
    }
  }
}

Lasse das einige Sekunden laufen und stoppe das Programm dann. Wenn du dir den Terminal-Output ansiehst, merkst du, dass der verfügbare RAM allmählich weniger wird, dann aber, wenn der GC aufgeräumt hat, sprunghaft wieder mehr RAM zur Verfügung steht. Das Programm kannst du minutenlang laufen lassen, ohne dass es zu Problemen kommt.

Der GC hat das eigentlich sehr gut im Griff. Alle unreferenzierten Objekte werden vom GC regelmäßig entfernt, wenn es Zeit wird. Dass das Programm "zäh reagiert", wie du beschreibst, kann ich mir nicht vorstellen. Dafür muss man noch viel mehr falsch machen. Wenn es natürlich um speicherkritische Anwendungen geht, kann man jedoch durchaus Probleme damit bekommen.

Generell hast du recht, dass es ein wesentlich besserer Stil ist, nur ein Scanner-Objekt zu erzeugen. Schließlich spricht nichts dagegen und man hat dadurch nur Vorteile. Wieso sollte man es also nicht gleich so tun?

...zur Antwort

Ich habe zwei Vermutungen:

  1. Eine angeschlossene Komponente ist defekt. Entferne alles, was man entfernen kann: SD-Karte, SIM-Karte etc.
  2. Die Firmware ist defekt. Flashe sie neu. Eine umfassende Anleitung dazu findest du hier.

Nach einem Defekt des Geräts selbst hört sich das für mich nicht an.

...zur Antwort
wenn man bei einer Web-App ,wie zum Beispiel „discord“, sich den Quellcode anzeigen lässt, kommt im Fall von discord erst nur grundlegendes HTML heraus und dann wird auf zwei .js Dateien verwiesen in dem der ganze Inhalt drinnen steht.

Dann wird der Inhalt dynamisch nachgeladen, was bei einer Chat-Application letztendlich auch sinnvoll ist. Dies kann auf verschiedenen Wegen erfolgen:

  • AJAX bzw. Long Polling (hierbei nicht sinnvoll)
  • SSE (hierbei nicht sinnvoll)
  • Web Socket (hierbei sinnvoll)
Stehen in diesen Dateien alles drinnen was ich dort im Browser sehe. Halt in JavaScript statt in HTML ?

Alles, was du im Browser sehen kannst, wird durch den HTML- und den CSS-Code bestimmt.

Und wenn ja, ich dachte das man mit JavaScript gar keine Benutzer Oberfläche programmieren kann.

Das kann man auch nicht, aber man kann den DOM manipulieren.

Wie funktioniert eine Web-App z.B. discord?

Eine Web-App ist eine ganz normale Website, die i. d. R. besonders gut an mobile Geräte angepasst ist.

...zur Antwort

Nun, programmieren und hacken hat erst einmal überhaupt nichts miteinander zu tun. Zunächst solltest du mit dem Programmieren beginnen, bevor du dich mit Hacking auseinandersetzt.

Womit lernen?

Ich rate von Online-Tutorials und Videos ab. Stattdessen würde ich eher ein Buch mit Übungsaufgaben empfehlen: https://www.gutefrage.net/frage/java-nach-tutorial-lernen

Welche Sprache?

Ich empfehle dir generell, auch ohne zu wissen, was du vor hast, für den Einstieg die Programmiersprache Java, die du nun auch ganz vorbildlich lernst. Heutzutage ist nämlich das Prinzip der objektorientierten Programmierung (OOP) sehr essentiell. Gerade bei größeren Programmen ist es sinnvoller, anstatt imperativ (Zeile für Zeile, alle Befehle hintereinander) oder prozedural (häufig vorkommende Prozeduren oder Funktionen auslagern, um sie mehrfach verwenden zu können, anstatt sich ständig zu wiederholen), objektorientiert zu programmieren.

Dabei werden Objekte genutzt, die den Objekten in der Realität entsprechen: Jedes Objekt hat gewisse Eigenschaften und Methoden. Diese werden in einer Klasse festgelegt, welche sozusagen ein Bauplan für Objekte darstellt. Aus diesem Bauplan können schließlich mehrere Objekte "gebaut" werden.

Das klingt zwar erst einmal sehr theoretisch, jedoch erleichtert es die Lesbarkeit größerer Projekte und ermöglicht die einfachere Wiederverwendbarkeit bereits entworfener Problemlösungen.

Diese objektorientierte Programmierung ist z.B. in Python, welches auch gerne für den Einstieg empfohlen wird, nur teilweise umgesetzt, viele wichtige Features fehlen vollkommen. Java dagegen unterstützt nur OOP (man möge mir die Ungenauigkeit an dieser Stelle verzeihen) und keinen anderen Stil. Zudem ist Java wesentlich strenger und erlaubt dir bestimmte Dinge nicht, bei denen dir Python einen gewissen Freiraum bietet. Diesen Freiraum nutzen Anfänger aufgrund von Bequemlichkeit sehr gerne und erlernen somit einen "pfuschigen"/unsauberen Programmierstil.

Um jedoch ordentlich Programmieren zu lernen und gleichzeitig das zukunftsentscheidende Prinzip der objektorientierten Programmierung kennen zu lernen, würde ich auf eine Sprache setzen, die dir diese Möglichkeiten bietet.

Java tut das und ist darüber hinaus für Einsteiger ziemlich einfach gehalten. Diese Sprache ist eine Interpreter-Sprache, also auch plattformunabhängig. Allerdings wird nicht der Java-Code interpretiert, sondern der Bytecode, in den der Programmcode zuvor kompiliert wird, was Java wesentlich schneller als viele andere Interpreter-Sprachen macht.

Zudem ist die Sprache sehr universell und kann in vielen Bereichen eingesetzt werden, z.B. GUI-Programmierung, einfache Spiele, Android-Apps, Webdevelopment, AI und Machine Learning, Minecraft Plugins, Robotik, Datenbank-Programmierung, Netzwerk-Programmierung, wissenschaftliche Programmierung, Cloud-Development, etc.

Viele Entwickler empfehlen vor Java noch eine leichte Vereinfachung: Processing. Siehe dazu diese Antwort: https://www.gutefrage.net/frage/welche-programmiersprache-sollte-ich-fuer-den-einstieg-nehmen?foundIn=list-answers-by-user#answer-261096307

Ich kann dir vor Java auch noch Scratch empfehlen. Damit kann man etwas sanfter in die Algorithmik und das logisch-strukturierte Denken einsteigen.

Wie lernen?

Für Java empfehle ich dir folgendes folgendes Buch zum Einstieg:

https://www.amazon.de/Programmieren-lernen-mit-Java-WindowBuilder/dp/3836241307/ref=sr_1_1?ie=UTF8&qid=1503873351&sr=8-1&keywords=programmieren+lernen+mit+java

Anschließend heißt es, jede Menge Erfahrung sammeln (mindestens ein Jahr). Zur Erweiterung des Wissens eignet sich dann folgendes Buch:

https://www.amazon.de/Java-auch-eine-Insel-Java-Entwickler/dp/3836241196/ref=sr_1_1?s=books&ie=UTF8&qid=1503873413&sr=1-1&keywords=java+insel

Und falls du vollends ein Java-Profi werden willst, auch noch dieses:

https://www.amazon.de/Java-auch-eine-Insel-Java-Entwickler/dp/3836241196/ref=sr_1_1?s=books&ie=UTF8&qid=1503873413&sr=1-1&keywords=java+insel

Ansonsten kann auch die App-Entwicklung (Android), die ebenfalls mit Java vonstatten geht, interessant sein:

https://www.amazon.de/Android-Praxisbuch-Entwickler-Android-Funktionen-Datenbanken/dp/3836242001/ref=sr_1_1?s=books&ie=UTF8&qid=1503873507&sr=1-1&keywords=android+7

Dies wird wohl immer stärker die Zukunft sein. Meine vorgeschlagenen Bücher gibt es übrigens in vielen Bibliotheken, sodass du kein Geld ausgeben musst.

Was tun, wenn ich Schwierigkeiten habe?

Zum Nachschlagen eignet sich bei Java wunderbar Google. Vor allem die Docs

https://docs.oracle.com/en/

und Stackoverflow

https://stackoverflow.com/

sind gute Anlaufstellen.

Und dann?

Allgemein ist es besser, wenn man mehrere Programmiersprachen beherrscht. Nachdem du Java sicher im Schlaf beherrscht, kannst und solltest du auch mit Python, C und C++ etc. weiter machen. Jede Sprache hat ihre Daseinsberechtigung und wird für verschiedene Anwendungsbereiche verstärkt genutzt. Es gibt keine "beste" Programmiersprache. Deswegen sollte man nicht nach einer aufhören, sondern besser sein Wissen erweitern.

Letztendlich sind diese Programmiersprachen aber nur das Mittel zum Zweck. Viel wichtiger sind die Konzepte und das "Drumherum", was man dabei lernt. Diese Erfahrung macht einen guten Entwickler aus. Andere Sprachen zu lernen, sollte sowieso kein großes Problem darstellen, wenn man bereits eine beherrscht. Man sollte sich schnell in unbekannte Felder einarbeiten können.

Solltest du noch Fragen haben, kannst du dich gerne melden.

Ich wünsche dir viel Spaß !

...zur Antwort