Dein Programm muss selbst die Map, bzw. die un-/begehbaren Bereiche kennen. Immer wenn sich deine Figur bewegen soll, muss geprüft werden, ob sie sich auf eine unbegehbare Fläche bewegt oder nicht. Wenn ja, müsste es eine Gegenmaßnahme geben (Reduzierung der Spielergeschwindigkeit auf 0 o.ä.).

In Java könnte man sich ein zweidimensionales Array anlegen, welches die Karte (in Form eines Rasters) abbildet (= Tilemap). Jedes Element im Array entspricht also einem Feld im Raster.

Beispiel:

boolean[][] map = {
 { false, true, true },
 { true, true, false },
 { false, false, false },
};

In dieser einfachen Form würde false für ein unbegehbares Feld und true für ein begehbares Feld stehen.

Bestenfalls wird dieses Array nun nicht nur zur Prüfung bei Spielerbewegungen herangezogen, sondern ebenso an den Zeichenprozess gekoppelt.

Beispiel bei einer Ausgabe auf der Konsole:

for (int y = 0; y < map.length; ++y) {
  for (int x = 0; x < map[y].length; ++x) {
    System.out.print(map[y][x] ? " " : "#");
  }

  System.out.println();
}

Für komplexere Maps könnte man statt mit boolschen Werten entweder Zahlen nutzen, die jeweils verschiedene Feldtypen kennzeichnen (z.B. 0 für Blöcke, 1 für Gras, 2 für Schnee, ...) oder eine eigene Feldklasse anlegen.

enum FieldType { GRASS, SNOW, WALL, /* ... */ }

class Field {
  private final FieldType fieldType;

  public Field(final FieldType fieldType) {
    this.fieldType = fieldType;
  }

  /* ... */
}

// map:
Field[][] map = {
  { new Field(FieldType.WALL), new Field(FieldType.GRASS), new Field(FieldType.GRASS) },
  { new Field(FieldType.GRASS), new Field(FieldType.GRASS), new Field(FieldType.WALL) },
  { new Field(FieldType.WALL), new Field(FieldType.WALL), new Field(FieldType.WALL) }
};

Alternativ zu einem Array (bzw. einer Tilemap) könnte man ein Spielfeld ebenso mit einem Quadtree abbilden, dem man entweder nur die Koordinaten der begehbaren oder andersherum, nur der unbegehbaren Bereiche mitteilt.

Für Programmieranfänger ist die Arraylösung allerdings wesentlich einfacher.

...zur Antwort

Die Fehlermeldung selbst macht darauf aufmerksam, dass im Code eine schließende Klammer fehlt. Es lohnt sich nun, sich den Code in einem Code-Editor korrekt eingerückt und mit Syntax Highlighting anzuschauen.

In Zeile 28 führst du den Kopf einer neuen Klasse an. Ihr Klassenkörper wird von dir jedoch nicht geschlossen. Vermutlich ist die komplette Zeile überflüssig.

...zur Antwort
Tkinter Fehler?

Ich programmiere mit Tkinter einen Taschenrechner zusammen mit einem Video.

Es kommt die ganze zeit die Fehlermeldung "nontype has no attribute get".

Mein code:

import tkinter as tk

calculator = ()

root = tk.Tk()
root.geometry("75x100")
root.title("Taschenrechner")
root.resizable(True, True)

entry_ziv = tk.Entry(root).grid(row=0, column=0)

def add_ziv(ziv):
    entry_ziv.insert(0, ziv)

def show_result():
    result = eval(entry_ziv.get())
    entry.delete(0, tk.END)
    entry_ziv.insert(0, str(result))

button_seven = tk.Button(root, text="7", command=lambda: add_ziv("7")).grid(row=1, column=0)
button_eight = tk.Button(root, text="8",command=lambda: add_ziv("8")).grid(row=1, column=1)
button_nine = tk.Button(root, text="9", command=lambda: add_ziv("9")).grid(row=1, column=2)
button_div = tk.Button(root, text=":", command=lambda: add_ziv(":")).grid(row=1, column=3)

button_four = tk.Button(root, text="4", command=lambda: add_ziv("4").grid(row=2, column=0))
button_five = tk.Button(root, text="5", command=lambda: add_ziv("5")).grid(row=2, column=1)
button_six = tk.Button(root, text="6", command=lambda: add_ziv("6")).grid(row=2, column=2)
button_multiply = tk.Button(root, text="x", command=lambda: add_ziv("x")).grid(row=2, column=3)

tton_one = tk.Button(root, text="1", command=lambda: add_ziv("1")).grid(row=3, column=0)
button_two = tk.Button(root, text="2", command=lambda: add_ziv("2")).grid(row=3, column=1)
button_tree = tk.Button(root, text="3", command=lambda: add_ziv("3")).grid(row=3, column=2)
button_minus = tk.Button(root, text="-", command=lambda: add_ziv("-")).grid(row=3, column=3)

button_execute = tk.Button(root, text="=", command=show_result()).grid(row=4, column=2)
button_plus = tk.Button(root, text="+", command=lambda: add_ziv("+")).grid(row=4, column=3)

root.mainloop()
...zur Frage

Das Problem liegt in dieser Zeile:

entry_ziv = tk.Entry(root).grid(row=0, column=0)

Die grid-Methode liefert den Wert None zurück. Auf den verweist entry_ziv dann auch.

Spalte die Zeile daher in zwei separate Anweisungen auf:

entry_ziv = tk.Entry(root)
entry_ziv.grid(row=0, column=0)
...zur Antwort
Delete/Insert/Update/Search, altmodisch gelöst? Verbesserungsvorschläge?

Mehrere Formularfunktionen in PHP:

Delete:

  if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["kunden_id"])) {
    $kunden_id = $_POST["kunden_id"];
    $sql = "DELETE FROM kunden WHERE kunden_id=$kunden_id";

    if ($conn->query($sql) === TRUE) {
      echo "Record deleted successfully";
    }
    else {
      echo "Error deleting record: " . $conn->error;
    }
  }

  $conn->close();
?>

Insert:

  if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $vname = $conn->real_escape_string($_POST['vname']);
    $nname = $conn->real_escape_string($_POST['nname']);
    $age = $conn->real_escape_string($_POST['age']);
    $sql = "INSERT INTO kunden (vname, nname, age) VALUES ('$vname', '$nname', '$age')";

    if ($conn->query($sql) === TRUE) {
      echo "Neuer Kunde erfolgreich hinzugefügt";
    }
    else {
      echo "Fehler: " . $sql . "<br>" . $conn->error;
    }
  }

  $conn->close();
?>

Update:

  if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["kunden_id"]) && isset($_POST["vname"]) && isset($_POST["nname"]) && isset($_POST["age"])) {
    // Kunden-ID und neue Daten aus dem Formular abrufen
    $kunden_id = $_POST["kunden_id"];
    $vname = $_POST["vname"];
    $nname = $_POST["nname"];
    $age = $_POST["age"];

    // SQL-Update-Statement vorbereiten
    $sql = "UPDATE kunden SET vname='$vname', nname='$nname', age='$age' WHERE kunden_id=$kunden_id";

    if ($conn->query($sql) === TRUE) {
      echo "Record updated successfully";
    }
    else {
      echo "Error updating record: " . $conn->error;
    }
  }

  $conn->close();
?>

Search:

  if (isset($_POST['search'])) {
    $search = $_POST['search'];
    $sql = "SELECT kunden_id, vname, nname, age FROM kunden WHERE nname LIKE '%$search%' ORDER BY kunden_id";
  }
  else {
    $sql = "SELECT kunden_id, vname, nname, age FROM kunden ORDER BY kunden_id";
  }

  $result = $conn->query($sql);

  if ($result->num_rows > 0) {
    echo "<table border='1'>
      <tr>
        <th>Kunden ID</th>
        <th>Vorname</th>
        <th>Nachname</th>
        <th>Alter</th>
      </tr>";

    while ($row = $result->fetch_assoc()) {
      echo "<tr>
        <td>" . $row["kunden_id"]. "</td>
        <td>" . $row["vname"]. " </td>
        <td>" . $row["nname"]. "</td>
        <td>" . $row["age"]. "</td>
      </tr>";
    }

    echo "</table>";
  }
  else {
    echo "0 Ergebnisse";
  }

  $conn->close();
?>
<form method="post">
  <input type="text" name="search" placeholder="Nachname eingeben...">
  <button type="submit">Suchen</button>
</form>
...zur Frage

1) Die Prüfung der Request-Methode ist redundant, wenn du eh die Existenz des kunden_id-Parameters prüfst.

2) Du brauchst die Datenbankverbindung nicht explizit schließen. Das passiert nach Beendigung des PHP-Skripts sowieso.

3) Berücksichtige auch hier die Punkte (1, 3, 4, 5, 8, 9), die ich dir bereits in diesem Beitrag schrieb. Die real_escape_string-Methode is dann auch redundant. Ich würde stets ein Prepared Statement vorziehen, da das all das, was notwendig ist, schon von sich aus tut.

4) Das Ergebnis einer Aktion würde ich unter dem Formular ausgeben lassen, nicht darüber. Immerhin wäre das die Erwartungshaltung eines Nutzers.

5) Ordne dem Eingabefeld ein Label zu. Das placeholder-Attribut nimmt diese Rolle nicht ein.

HTML:

<label for="searchword">Nachname:</label>
<input id="searchword" name="search" placeholder="Nachname eingeben...">

Wenn das Label visuell unbedingt versteckt sein soll, kannst du eine CSS-Regel ergänzen:

.visually-hidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}
...zur Antwort
Sort/Tabellen/QR-Code altmodisch gelöst? Verbesserungsvorschläge?

Mehrere Formularfunktionen in PHP:

Sort:

  $sort_by = "kunden_id";
  $order = "ASC";

  if (isset($_GET['sort'])) {
    // Überprüfen, ob die Sortierparameter gültig sind
    if ($_GET['sort'] == 'kunden_id' || $_GET['sort'] == 'vname' || $_GET['sort'] == 'nname' || $_GET['sort'] == 'age') {
      $sort_by = $_GET['sort'];
      $order = ($_GET['order'] == 'asc') ? 'ASC' : 'DESC';
    }
  }

  $sql = "SELECT kunden_id, vname, nname, age FROM kunden ORDER BY $sort_by $order";
  $result = $conn->query($sql);

  if ($result->num_rows > 0) {
    echo "<table border='1'>
      <tr>
        <th><a href='?sort=kunden_id&order=". ($sort_by == 'kunden_id' && $order == 'ASC' ? 'desc' : 'asc') ."'>Kunden ID</a></th>
        <th><a href='?sort=vname&order=". ($sort_by == 'vname' && $order == 'ASC' ? 'desc' : 'asc') ."'>Vorname</a></th>
        <th><a href='?sort=nname&order=". ($sort_by == 'nname' && $order == 'ASC' ? 'desc' : 'asc') ."'>Nachname</a></th>
        <th><a href='?sort=age&order=". ($sort_by == 'age' && $order == 'ASC' ? 'desc' : 'asc') ."'>Alter</a></th>
      </tr>";

    while($row = $result->fetch_assoc()) {
      echo "<tr>
        <td>" . $row["kunden_id"]. "</td>
        <td>" . $row["vname"]. " </td>
        <td>" . $row["nname"]. "</td>
        <td>" . $row["age"]. "</td>
      </tr>";
    }

    echo "</table>";
  }
  else {
    echo "0 Ergebnisse";
  }

  $conn->close();
?>

Tabellen anzeigen lassen:

<?php
  $servername = "localhost";
  $username = "root";
  $password = "";
  $dbname = "lap";

  // Create connection
  $conn = new mysqli($servername, $username, $password, $dbname);
  // Check connection
  if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
  }

  $sql = "SELECT kunden_id, vname, nname, age FROM kunden Order by kunden_id";
  $result = $conn->query($sql);

  if ($result->num_rows > 0) {
    echo "<table border='1'>
      <tr>
        <th>Kunden ID</th>
        <th>Vorname</th>
        <th>Nachname</th>
        <th>Alter</th>
      </tr>";

    // output data of each row
    while($row = $result->fetch_assoc()) {
      echo "<tr>
        <td>" . $row["kunden_id"]. "</td>
        <td>" . $row["vname"]. " </td>
        <td>" . $row["nname"]. "</td>
        <td>" . $row["age"]. "</td>
      </tr>";
    }

    echo "</table>";
  }
  else {
    echo "0 results";
  }

  $conn->close();
?>

QR-Code:

<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>QR-Code Generator</title>
  <script src="https://cdn.jsdelivr.net/npm/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      margin-top: 50px;
    }

    #qrcode {
      margin-top: 20px;
    }
    button {
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <h1>QR-Code Generator</h1>
  <form id="qrForm">
    <label for="url">Gib eine URL ein:</label>
    <input type="text" id="url" name="url" required>
    <button type="submit">Generiere QR-Code</button>
  </form>
  <div id="qrcode"></div>
  <button id="downloadBtn" style="display:none;">QR-Code herunterladen</button>
  <script>
    const qrCode = new QRCodeStyling({
      width: 300,
      height: 300,
      type: "png",
      data: "",
      image: "",
      dotsOptions: {
        color: "#000",
        type: "rounded"
      },
      backgroundOptions: {
        color: "#fff",
      }
    });
    document.getElementById("qrForm").addEventListener("submit", function(event) {
      event.preventDefault();
      const url = document.getElementById("url").value;
      qrCode.update({
        data: url
      });
      document.getElementById("qrcode").innerHTML = "";
      qrCode.append(document.getElementById("qrcode"));
      document.getElementById("downloadBtn").style.display = "block";
    });
    document.getElementById("downloadBtn").addEventListener("click", function() {
      qrCode.download({ name: "qrcode", extension: "png" });
    });
  </script>
</body>
</html>
...zur Frage

Das Sortieren von Listen/Tabellen (nach dem ersten Laden der Seite) würde ich heutzutage eher mittels JavaScript lösen. Es geht so schneller, als jedes Mal die komplette Seite neu anfordern zu müssen.

Eine Beispielimplemenation für so etwas findet man auch leicht: APG: Sortable Table Example.

Dein PHP-Code kann natürlich trotzdem bleiben, um bei expliziten Aufrufen der Seite die Daten vorsortiert zu laden.

Ansonsten gilt bezüglich deines Codes dasselbe, was ich dir in den Punkten 1, 3 und 8 dieses Beitrags schon schrieb.

Was den QR-Code-Generator angeht:

  • Die von dir genutzte Bibliothek kannst du selbst überprüfen.
  • Das type-Attribut auf dem Submit-Button ist redundant.
  • Dem Download-Button hingegen würde ich ein type-Attribut geben, welches ihn als einfachen Klickbutton ausweist (type="button").
  • Es wäre praktisch, die inhaltliche Änderung des QR-Code-Containers entsprechend zu kommunizieren. Zeichne das Element als Live-Region aus:
<div aria-live="polite" id="qrcode"></div>
  • Den Downloadbutton würde ich folglich mit in den Container packen.
  • Um CSS und JavaScript stärker voneinander zu trennen, wäre es schöner, dem Downloadbutton je nach Status nur eine Klasse hinzuzufügen oder zu entziehen. Eine CSS-Regel kann die Sichtbarkeit regeln.

CSS:

.hidden { display: none }

HTML:

<button class="hidden" id="downloadBtn">QR-Code herunterladen</button>

JavaScript:

document.getElementById("qrForm").addEventListener("submit", function(event) {
  /* ... */
  const downloadButton = document.getElementById("downloadBtn");
  downloadButton.classList.remove("hidden");
});
...zur Antwort
Alle Tabellen bei phpMyAdmin anzeigen?

Hallo, geht es vielleicht einfacher? Mit weniger Code?

<?php
  $servername = "localhost";
  $username = "root";
  $password = "";

  // Funktion um Verbindung zu prüfen und eine Nachricht auszugeben
  function checkConnection($conn) {
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }
  }

  // Verbindung herstellen
  $conn = new mysqli($servername, $username, $password);
  checkConnection($conn);

  // Alle Datenbanken abrufen
  $sql = "SHOW DATABASES";
  $result = $conn->query($sql);
  echo "<h1>Datenbanken</h1>";

  if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
      $dbname = $row['Database'];
      echo "<a href='?database=$dbname'>$dbname</a><br>";
    }
  }
  else {
    echo "Keine Datenbanken gefunden.";
  }

  $conn->close();

  // Tabellen in der gewählten Datenbank anzeigen
  if (isset($_GET['database'])) {
    $dbname = $_GET['database'];
    $conn = new mysqli($servername, $username, $password, $dbname);
    checkConnection($conn);
    $sql = "SHOW TABLES";
    $result = $conn->query($sql);
    echo "<h1>Tabellen in $dbname</h1>";

    if ($result->num_rows > 0) {
      while ($row = $result->fetch_assoc()) {
        $tablename = $row["Tables_in_$dbname"];
        echo "<a href='?database=$dbname&table=$tablename'>$tablename</a><br>";
      }
    }
    else {
      echo "Keine Tabellen gefunden.";
    }

    $conn->close();
  }

  // Einträge in der gewählten Tabelle anzeigen und Eingabefelder generieren
  if (isset($_GET['database']) && isset($_GET['table'])) {
    $dbname = $_GET['database'];
    $tablename = $_GET['table'];
    $conn = new mysqli($servername, $username, $password, $dbname);
    checkConnection($conn);
    $sql = "SELECT * FROM $tablename";
    $result = $conn->query($sql);
    echo "<h1>Einträge in $tablename bearbeiten</h1>";

    if ($result->num_rows > 0) {
      echo "<form method='POST' action='save_changes.php'>";
      echo "<table border='1'><tr>";

      // Spaltenüberschriften
      $fieldinfo = $result->fetch_fields();

      foreach ($fieldinfo as $val) {
        echo "<th>{$val->name}</th>";
      }

      echo "</tr>";

      // Daten
      while ($row = $result->fetch_assoc()) {
        echo "<tr>";

        foreach ($row as $key => $data) {
          echo "<td><input type='text' name='{$key}[]' value='$data'></td>";
        }

        echo "</tr>";
      }

      // Leeres Eingabefeld für neue Einträge hinzufügen
      echo "<tr>";

      foreach ($fieldinfo as $val) {
        echo "<td><input type='text' name='{$val->name}[]' value=''></td>";
      }

      echo "</tr>";
      echo "</table>";
      echo "<input type='hidden' name='database' value='$dbname'>";
      echo "<input type='hidden' name='table' value='$tablename'>";
      echo "<input type='submit' value='Änderungen speichern'>";
      echo "</form>";
    }
    else {
      echo "Keine Einträge gefunden.";

      // Leere Tabelle mit Eingabefeldern für neuen Eintrag anzeigen
      echo "<form method='POST' action='save_changes.php'>";
      echo "<table border='1'><tr>";

      foreach ($fieldinfo as $val) {
        echo "<th>{$val->name}</th>";
      }

      echo "</tr><tr>";

      foreach ($fieldinfo as $val) {
        echo "<td><input type='text' name='{$val->name}[]' value=''></td>";
      }

      echo "</tr></table>";
      echo "<input type='hidden' name='database' value='$dbname'>";
      echo "<input type='hidden' name='table' value='$tablename'>";
      echo "<input type='submit' value='Änderungen speichern'>";
      echo "</form>";
    }

    $conn->close();
  }
?>
...zur Frage

1) Es wäre besser, PHP und HTML stärker voneinander zu trennen.

Ein Weg wäre die alternative Syntax für Kontrollstrukturen:

<?php
  /* build connection ... */
  $result = $connection->query('SHOW DATABASES');
  $databaseEntries = $result->fetch_all(MYSQLI_ASSOC);
  $connection->close();

  /* etc. ... */
?>
<!doctype html>
<head>
  <title>Datenbanken</title>
  <meta charset="utf-8">
</head>
<body>
  <h1>Datenbanken</h1>
  <?php if (count($databaseEntries) > 0): ?>
    <ul>
    <?php foreach ($databaseEntries as $databaseEntry): ?>
      <?php $databaseName = databaseEntry['Database']; ?>
      <li><a href="?database=<?= $databaseName ?>"><?= $databaseName ?></a>
    <?php endforeach; ?>
    </ul>
  <?php else: ?>
    <p>Keine Datenbanken gefunden.
  <?php endif; ?>

  <!-- etc. ... -->
</body>

2) Die Links halte ich in einer Auflistung für besser aufgehoben. Man könnte stattdessen aber auch eine Auswahlliste oder eine Gruppe an Radioboxen anbieten. Den Fallbacktext würde ich in ein eigenes Element (p/span/o.ä.) packen, damit man ihn später leichter stylen kann.

3) Dein Skript soll als grafische Schnittstelle dienen, über die eine explizite Auswahl an Aktionen durchgeführt werden darf. Demzufolge wäre es auch in diesem Fall klüger, mit Prepared Statements zu arbeiten, um zu verhindern, dass ein Nutzer eigene Anweisungen an die Datenbank verschicken kann, die von der Oberfläche nicht angeboten werden.

4) Texteingabefelder brauchen kein explizites type- oder value-Attribut. Auch bei den form-Elementen kannst du das action-Attribut weglassen, wenn es doch eh auf diesselbe URL verweist.

5) Da du wohl auch Daten zum Speichern an die Datenbank schicken möchtest, würde ich empfehlen, für die Datenbankverbindung explizit die Zeichenkodierung vorzugeben.

6) Statt einer Funktion checkConnection wäre eine Funktion getConnection sinnvoll, die eine Verbindung kreiert und zurückgibt.

7) Wenn der URL Querystring neben einem Datenbanknamen auch einen Tabellennamen beinhaltet, brauchst du die zuvor hergestellte Datenbankverbindung doch nicht kappen. Immerhin befragst du doch in beiden Fällen die gleiche Datenbank.

8) Das border-Attribut auf dem table-Element ist obsolet. Nutze CSS stattdessen.

9) Im Übrigen fehlen in deinem geposteten Code Doctype und title. Falls sie dem HTML-Dokument tatsächlich fehlen, sollten sie noch ergänzt werden.

...zur Antwort
Nicht gelungen

Die Seite wirkt bereits im ersten Viewport überladen.

Überall bewegt sich etwas, in verschiedenen Ecken sind irgendwelche Schaltflächen platziert (die im direkten Vergleich nicht einmal im selben Raster liegen). Da die einzelnen Sektionen zu wenig Abstand zueinander haben, wirkt deren Inhalt (vor allem die Bilder) oftmals wie hineingedrängt. An anderen Stellen wird unnötigerweise eine Platznot kreiert. Bei dem Hauptmenü beispielsweise könnte man sicherlich eine einzeilige Lösung finden. Der Link "Startseite" ist schon einmal redundant, da das Logo bereits auf die Startseite verweist.

Andere redundante Elemente sind die mehrmaligen Aufführungen der Kontaktdaten. Allein auf der Kontaktseite findet man dreimal die Telefonnummer und zweimal die Anschrift mitsamt Öffnungszeiten. Es kommt der Eindruck auf, dass es sich hier lediglich um Streckung handelt, weil man nicht wusste, wie man die Seite sonst mit Inhalten befüllen sollte.

Zusätzlich gibt es Designentscheidungen, die m.E. nicht nachvollziehbar sind. Die Buttons bekommen zum Beispiel nur einen Rahmen an den vertikalen Seiten. Auf den ersten Blick hätte ich das als Fehler in der Umsetzung bewertet. Bei den Boxen auf der Kontaktseite (Öffnungszeiten, Telefon, Adresse), die nur halbseitig grau hinterlegt sind, handelt es sich vermutlich wirklich um ein ungewolltes Verhalten. Bei den Eingabefeldern, deren Umrandung erst bei Fokussierung angezeigt wird, wäre ich mir nicht ganz sicher.

Bezüglich des Footers wäre es vorteilhaft, eine andere Lösung hinsichtlich der Farbverteilung zu finden. Die Vordergrundfarbe der Links hebt sich nicht ausreichend zum Hintergrund ab und das blaue Kaiserlogo erzeugt aufgrund des scharfen Kontrasts für ein Flimmern (der Logotext ist deswegen kaum lesbar).

Wenn man sich die Seite nun noch ein wenig auf technischer Ebene anschaut, fallen schnell verschiedene Fehler auf (z.B. im Markup: ein div-Element im head, fehlerhafte Verlinkungen, u.ä.).

Ein positiver Aspekt ist die Wahl der Schriftart und -farbe im Hauptinhaltsbereich.

...zur Antwort

Zu 1.1.2: Verbinde die Tabellen betreiber und lifte mit Hilfe eines JOIN. Dann kannst du mittels einer WHERE-Klausel leicht nach den gesuchten Einträgen filtern.

Zu 1.1.4: Erneut müssen zwei Tabellen via JOIN verbunden werden. Zusätzlich solltest du dir SUM und GROUP BY anschauen.

Zu 1.1.5: Du sollst ein SELECT-Statement formulieren, welches nach irgendetwas filtert. Da du so etwas in den anderen Aufgaben auch schon tust, sollte diese Aufgabe auch nicht schwer sein.

Zu 1.1.7: Schau nach, welche Abhängigkeiten es in der Datenbank bezogen auf die Pisten gibt. Wenn eine Piste entfernt wird, müssen schließlich auch alle Einträge, die sich auf diese Piste beziehen, zuvor aktualisiert werden. Andernfalls würden sie nach Entfernen der Piste auf nicht mehr vorhandene Daten zeigen.

...zur Antwort

Die Elemente deines Fensters werden sich nicht responsive verhalten, gerade da du sie mit einem AnchorPane (bzw. fixen Größen und Koordinaten) anordnest.

Für ein adaptives/responsive Design wäre Folgendes zu beachten:

1) Verwende zur Anordnung Layout Panes wie BorderPane, GridPane, FlowPane, HBox, TilePane, VBox

2) Verzichte auf fixe Größen. Setze stattdessen eher nur Größenbereiche (z.B. Mindest-/Maximalbreite). Die präferierte Größe sollte sich an dem Inhalt ausrichten (Region.USE_COMPUTED_SIZE).

Du kannst über Constraints (siehe bspw. ColumnConstraints des GridPane) auch prozentuale Werte vorgeben oder im FXML die Werte entsprechend berechnen.

Beispiel:

<VBox fx:id="root" prefHeight="${screen.visualBounds.height}" prefWidth="${screen.visualBounds.width}">
  <fx:define>
    <Screen fx:factory="getPrimary" fx:id="screen" />
  </fx:define>
  <Label prefWidth="${root.width * 0.5}" />
</VBox>

Über die fx:factory wird die primäre Stage bezogen. Somit ist es möglich, die aktuelle Fenstergröße (visualBounds) zu ermitteln und auf dessen Grundlage die gewünschten Größen zu berechnen.

3) Was man aber auch berücksichtigen sollte: Es ist nicht unbedingt praktikabel, Elemente bei Skalierung der Fenstergröße automatisch größer/kleiner werden zu lassen. Wie bei responsive Webseiten sollte man stattdessen schauen, wie die Elemente je nach verfügbaren Platz am besten angeordnet werden.

Insofern könnte man sich auch ein eigenes Grid Layout bauen, welches bei verschiedenen Breakpoints Umbrüche erzeugt. In diesem Artikel wird die Implementation eines solchen Layout Managers gezeigt.

...zur Antwort
Kann mir jemand bei der Erstellung eines ausklappbaren Seitenmenüs mit Hamburger-Button helfen?

Hoffentlich kann mir hier jemand weiterhelfen.

Ich möchte ein ausfahrbares Seitenmenü mit einem Hamburger-Button (Font Awesome) konstruieren.

Im unteren Bild sieht man meinen momentanen Stand. Ich möchte aber, das von seitlich rechts das Menü hineinschwebt.

Zur Zeit habe ich Folgendes:

<nav role="main-navigation" aria-label="site" id="main-navigate" class="main-navi">
  <button aria-expanded="undefined"></button>
  <ul id="navlinks">
    <li class="sub-menue">
      <a class="a-link" href="/test/public/Testseite2-2.html">Blog Max Mustermann</a>
      <button aria-expanded="undefined"></button>
      <div class="nav-group">
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 1-A</a>
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 1-B</a>
      </div>
    </li>
    <li class="sub-menue">
      <a class="a-link" href="/test/public/Testseite2-2.html">Blog Erika Mustermann</a>
      <button aria-expanded="undefined"></button>
      <div class="nav-group">
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 2-A</a>
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 2-B</a>
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 2-C</a>
      </div>
    </li>
    <li class="sub-menue">
      <a class="a-link" href="/test/public/Testseite2-2.html">Website Erika Mustermann</a>
      <button aria-expanded="undefined"></button>
      <div class="nav-group">
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 3-A</a>
      </div>
    </li>
    <li class="sub-menue">
      <a class="a-link" href="/test/public/Testseite2-2.html">Impressum / Datenschutz</a>
      <button aria-expanded="undefined"></button>
      <div class="nav-group">
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 4-A</a>
        <a class="a-sublink" href="/test/public/Testseite2-2.html">UNTERMENUE 4-B</a>
      </div>
    </li>
  </ul>
</nav>

Da mein Post zu lang wird, hier ein Downloadlink des JS, CSS und HTML: http://misanthrop.bplaced.net/downloads/seitliches_menue.txt

Könnte bitte jemand mir dabei helfen, dies zu entwickeln? Ein rudimentäres CodePen-Beispiel würde mir helfen.

...zur Frage

Auf W3Schools findest du praktische Beispiele, an denen du dich orientieren kannst:

  • How To: Side Navigation
  • W3.CSS Sidebar

Und noch ein paar Hinweise zu deinen Buttons:

  • Sie geben mit aria-expanded zwar einen Ausklappzustand an, allerdings nicht für welches Element das nun gilt. Ergänze ein aria-controls-Attribut, welches auf die ID des jeweiligen Elements verweist.
  • Statt den Zustand von aria-expanded erst beim Laden zu setzen, könntest du das auch gleich im initialen Markup tun. Es bedeutet weniger Code, weniger benötigte Rechenleistung (Suchen und Ändern im DOM) und einen klaren initialen Status.
  • Den Buttons fehlt eine Beschriftung. Pseudoelemente können das nicht sicher gewährleisten. Sie sollten vorzugsweise nur für dekorativen Inhalt benutzt werden.
...zur Antwort

Dictionaries haben ein Keys-Property. Schau dafür in die Dokumentation. Bei ToArray handelt es sich wiederum um eine Linq-Erweiterungsmethode. Das heißt, du musst dafür noch den entsprechenden Namespace inkludieren.

Beispiel:

using System;
using System.Collections.Generic;
using System.Linq;

var someDictionary = new Dictionary<string, string>();
var someArray = someDictionary.Keys.ToArray();
...zur Antwort

Die Reviews API gehört zur Google Business Profile API. Alles, was du brauchst, um sie zu nutzen, ist ein Google My Business Account mit einem Unternehmensprofil (lies hier und hier). Das Anlegen von Account und Profil ist kostenlos.

Bezüglich der von dir erwähnten 200$ beziehst du dich wohl auf die Google Maps API, daher gilt alles Folgende von mir nur noch für diese. Ihre verfügbaren Sub-APIs werden in der Produktübersicht aufgeführt.

Nutzer der Google Maps Platform erhalten ein Guthaben von 200 $ pro Monat für Maps, Routes und Places (siehe Guthaben für Rechnungskonten). Damit können manche Kunden ihre Anwendungsfälle ohne Kosten abdecken. Ihnen werden erst Gebühren in Rechnung gestellt, wenn die Nutzung 200 $ in einem Monat überschreitet.
Für Maps Embed API, Maps SDK for Android und Maps SDK for iOS gibt es aktuell keine Nutzungsbeschränkungen und Kosten. Die Verwendung der API oder der SDKs wird nicht auf Ihr monatliches Guthaben von 200 $ angerechnet.

Quelle (FAQ: 1. Tab)

Für einen begrenzten Testzeitraum kann man sogar ein Guthaben von 300$ pro Monat erhalten.

(...) und muss ich eine Kreditkarte hinterlegen?

Nein, es gibt noch weitere Optionen (lies hier). PayPal wird allerdings nicht mehr unterstützt.

(...) Von mir aus kann es nach dem Guthaben aufhören zu funktionieren (...)

Du kannst Request-Limits setzen (siehe: API-Nutzung deckeln) und zusätzlich deinen Verbrauch überwachen (siehe: API-Nutzung überwachen und Budgets und Budgetbenachrichtigungen erstellen, bearbeiten oder löschen).

Wie viel Geld/Cents kostet so ein Request bzw. wie viele sind möglich mit diesen $200?

Das hängt von der jeweiligen Sub-API ab, die du aufrufst. Schau in die Preisübersicht. Die Freibeträge kannst du dir mittels Dreisatz ausrechnen.

(...) die ich von WordPress auf Next.js wegen Performance/Speed-Problemen nachbauen möchte und weil es der Kunde nicht wie gedacht als CMS nutzt (...)

Google ist es egal, ob du deine Anfragen via JavaScript oder PHP verschickst.

Bezüglich deines Vorhabens berücksichtigst du hoffentlich, dass du damit einen Kostenaufwand aufrufst, der so nicht im Interesse des Kunden liegen dürfte, sofern das noch nicht abgesprochen wurde. Für eine Performanceoptimierung würde ich erst einmal schauen, ob die derzeitige Lösung nicht entsprechend modifiziert werden kann (und wo überhaupt die Ursachen liegen).

Von einem CMS würde ich des Weiteren nicht abkehren, für Node.js gibt es ja auch einige Optionen (Apostrophe, Keystone, Strapi, ...).

Wenn es dich zudem so stört, dass dein Kunde die Texte nicht selbst pflegt, musst du das mit ihm abklären. Entweder löst man das Vertragsverhältnis oder ändert die darin verhandelten Aufgabenbereiche.

...zur Antwort
Hallo, ich hatte die Idee meinen Lebenslauf zusätzlich noch als Website zu erstellen.

Für die schlichte Aufführung eines Lebenslaufs kannst du auch LinkedIn oder Xing nutzen. Beides sind Plattformen, die gezielt auf das Knüpfen beruflicher Kontakte fokussiert sind.

Lediglich Daten wie die private Telefonnummer oder E-Mail-Adresse würde ich dort nicht ohne Weiteres einstellen, um dreiste Headhunter-Manöver zu vermeiden.

Jedoch würde ich ungerne persönliche Informationen ins Internet stellen.

Dann mache es nicht.

Was denkt ihr, wie wahrscheinlich ist es dass meine Lebenslauf Website von Leuten entdeckt wird?

Sobald die Seite einmal von einer Suchmaschine indiziert wurde, wird es zumindest einfacher. Auf welches Ranking (zu welchen Suchbegriffen) deine Webseite springen würde oder wie viele Personen gezielt nach dir suchen, lässt sich kaum beantworten.

Was könnte man machen damit nur Leute mit dem Link auf meine Website zugreifen könnten?

Du kannst ein Authentifizierungsverfahren (Basic Auth o.ä. Loginverfahren) davor setzen. Wenn du solche Dienste wie Google Sites nutzt, könntest du die Seite auch via Link mit nur bestimmten Personen teilen.

...zur Antwort

Vorausgesetzt, das du oder jemand in der Firma genügend Kenntnisse mitbringt, um einfache Office-Anwendungen (wie MS Word) zu bedienen, wäre Google Sites eine einfache und kostenlose Option, die für den Anfang vollkommen ausreichen sollte.

...zur Antwort

Man könnte die Objekte in einen Graph übertragen.

Ein Graph besteht aus Knoten, die jeweils eines deiner Objekte beinhalten. Mittels Kanten/Pfaden sind sie mit einem (leeren) Wurzelknoten verbunden, wobei jeder Pfad den Wahrscheinlichkeitswert für den Knoten beinhaltet, auf den er zeigt. Die Anzahl eines Objekts sollte ebenso außerhalb des Objekts selbst gelagert werden, bspw. im Knoten.

Das Modell einmal grob in Java angedeutet:

class Graph {
  private Node root;

  /* ... */
}

class Node {
  private ArrayList<Edge> nextEdges;
  private Edge previousEdge;
  private Object someObject;
  private int numberOfSomeObject;

  /* ... */
}

class Edge {
  private double probabilityValue;
  private Node startNode;
  private Node endNode;

  /* ... */
}  

Wenn die Häufigkeit eines bestimmten Objekts geändert werden soll, muss das also über eine Methode des Graph erfolgen. Die könnte in diesem Zug auch über alle Kanten des Vorgängerknotens iterieren, um die Wahrscheinlichkeitswerte zu aktualisieren.

...zur Antwort

Für Ketten, die stets denselben Rechenoperator nutzen, könnte man die Eingabe ganz einfach anhand des Operators in Substrings auftrennen (siehe Split-Methode).

Die einzelnen Substrings könntest du im Anschluss in Werte numerischen Typs umwandeln und via Schleife miteinander verrechnen.

Für komplexere Aufgaben, die unterschiedliche Operatoren einsetzen, wäre der Aufbau eines Expression Tree eine geeignete Wahl, was allerdings keine Übung für einen Anfänger ist.

Andernfalls kann man eine mathematische Aufgabe ebenso von der Compute-Methode einer DataTable verarbeiten lassen.

...zur Antwort
(...) wenn ich jetzt z.b. ein kleines grafisches Programm,schrieben will (...)

So lange du mit einfachen Grundbausteinen (Listen, Kontrollstrukturen, OOP) noch nicht vertraut bist, wäre es besser, sich erst einmal darauf zu fokussieren, statt bereits mit fortgeschritteneren Themen agieren zu wollen.

Mit einsteigerfreundlichen Modulen wie turtle oder Processing.py gelangt man ebenso zu visuellen Erfolgserlebnissen.

(...) woher weiß ich dann das ich erst was importieren muss (...)

Plane im Voraus. Du musst erst erfassen, was dein Programm tun/können soll und im Anschluss kannst du schauen, welcher Teilschritte es dafür zu lösen bedarf. Ich habe erst gestern mehr in diesem Beitrag dazu geschrieben.

Wenn du dabei merkst, dass du z.B. eine Netzwerkverbindung herstellen musst, wäre es gut, nach einem Modul zu suchen, welches dich dabei unterstützt, da du so etwas kaum selbst von neu aufbauen möchtest. Erste Anlaufstellen wären die Dokumentation (in der alle Module der Standardbibliothek aufgelistet werden) oder ein Package-Repository wie PyPi, welches externe Bibliotheken führt.

Für genauere Informationen zu einem Modul (was es beinhaltet, wie man es nutzen kann, etc.) solltest du immer in die entsprechende Dokumentation schauen. Bei externen Bibliotheken auf PyPi solltest du dir die jeweilige Moduldetailseite durchlesen, denn sie beinhaltet auch Links zu den offiziellen Manuals o.ä. oder manchmal sogar Kurzanleitungen).

...zur Antwort

JetBrains IntelliJ ist in erster Linie eine Java-IDE. Den Support für Python müsstest du dir erst einmal einrichten. Empfehlenswerter wäre es allerdings, sich stattdessen JetBrains PyCharm zu holen, denn das ist eine direkt auf Python-fokussierte IDE.

Die Paketverwaltung wird in deren Dokumentation beschrieben. Über diesen Weg kannst du dir auch den Discord-Wrapper für Python von PyPi herunterladen und ihn anschließend in deinem Projekt einbinden.

...zur Antwort