Lege dir einen Button an und binde diesen an eine Funktion, die künftig auf Klickereignisse reagiert. In dieser schaust du, welche Einträge in deiner Liste ausgewählt wurden.

Der Button:

button = Button(parent_window, text="Click me", command=print_list_selection)

Die Funktion:

def print_list_selection():
  for selection in listbox.curselection():
    print(listbox.get(selection))

Voraussetzung für mein Beispiel ist, dass die Listbox über eine globale Variable ansprechbar ist.

...zur Antwort

Du hast dich bei den Klammern vertan. Die Klammer, die den Klassenkörper öffnet, muss noch vor das Feld.

public class GameOverScreen : MonoBehaviour
{
  public Text pointsText;
...zur Antwort

Ich habe es gerade einmal mit der aktuellen Version 93.1.111 getestet. Ich habe dafür eine beliebige Seite mit Cookie Popup benutzt und für die Cache-Daten einen neuen Ordner angelegt.

var applicationPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var cachePath = Path.Combine(applicationPath, "cache");

if (!Directory.Exists(cachePath))
{
  Directory.CreateDirectory(cachePath);
}

CefSharp.Cef.Initialize(new CefSettings
{
  CachePath = cachePath,
  PersistSessionCookies = true
});

// create browser control and add to form ...

Dein Problem konnte ich damit reproduzieren, obwohl im cache-Ordner offensichtlich die Cookie-Daten abgelegt wurden.

Ich habe dem Form daraufhin noch einen Event Handler zugeordnet, der anspringt, sobald es sich schließt. In diesem habe ich die Shutdown-Methode für CefSharp aufgerufen, was du vermutlich nicht tust. Dieser Aufruf bewirkt das Speichern der Cache-Daten vor Beendigung des Browserprozesses.

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  CefSharp.Cef.Shutdown();
}

Bei einem Neustart der Anwendung erscheint der Cookie Popup daraufhin nicht mehr.

...zur Antwort

Ich denke, das Problem liegt in deiner Art, die Abfragen zusammenzubauen.

Um mir einmal eine von beiden herauszugreifen:

if (pos || posEl) {

Diese baut sich aus diesen Ausdrücken zusammen:

const pos = document.body.scrollTop < 300;
const posEl = document.documentElement.scrollTop < 300;

Allerdings wird dir document.body.scrollTop bspw. im Standardmodus des Chrome-Browsers stets 0 zurückgeben. Das heißt, pos ist immer wahr.

Besser wäre es, die Ausdrücke zusammenzufassen:

const pos = (document.documentElement.scrollTop || document.body.scrollTop) < 300;

Nun müsste meiner Meinung nach noch der Vergleichsoperator umgedreht werden, denn der Zustand, dass der Nutzer nach unten gescrollt hat, ist eher daran zu bemessen, ob er die 300er-Grenze überschritten hat oder nicht.

Da du dich wohl am Viewport orientieren möchtest, würde ich wohl nicht 300 einsetzen, sondern den Wert bereechnen lassen.

const viewportHeight = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
...zur Antwort

Du kannst ein ListView benutzen, an welches du eine ObservableCollection bindest.

Zunächst brauchst du eine Modelklasse, die die einzelnen Einträge beschreibt. Wenn jedes Item nur aus einer Zahl, einem String, o.ä. besteht, benötigst du natürlich keinen separaten Typ. Ich gehe hier aber einmal von einem benutzerdefinierten Fall aus.

public class Person
{
  public string FirstName { get; set; }

  public string LastName { get; set; }
}

Dazu wird ein ViewModel angelegt. Ein ViewModel dient der Aufbereitung der Daten für ein View. Dafür hält es hier eine ObservableCollection. Das ist ein Datencontainer, der Benachrichtigungen erstellt, sollten ihm Elemente hinzugefügt oder von ihm entfernt werden. Das ist für später nützlich, denn der Plan wäre, in der Anwendung direkt nur dieses Objekt zu verändern, um Zustandsänderungen im View zu bewirken.

public class PersonViewModel
{
  public PersonViewModel()
  {
    Persons = new ObservableCollection<Person>
    {
      new Person { FirstName = "John", LastName = "Lennon" },
      new Person { FirstName = "Ringo", LastName = "Starr" },
      new Person { FirstName = "Paul", LastName = "McCartney" },
      new Person { FirstName = "George", LastName = "Harrison" }
    };
  }

  public ObservableCollection<Person> Persons { get; set; }
}

Dafür wird die Liste (bzw. eigentlich das gesamte ViewModel) an das View gebunden.

Mein View geht davon aus, dass das Projekt Example heißt und der Standardnamespace ebenso. Es für deinen Fall anzupassen, dürfte kaum ein Problem darstellen.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:vm="clr-namespace:Example;assembly=Example"
  x:Class="Example.Persons"
  Title="Example">
  <ContentPage.BindingContext>
    <vm:PersonViewModel />
  </ContentPage.BindingContext>
  
  <StackLayout>
    <ListView ItemsSource="{Binding Persons}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout Orientation="Horizontal" Padding="5">
              <Label Text="{Binding FirstName}" TextColor="Blue" />
              <Label Text="{Binding LastName}" TextColor="Red" />
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
</ContentPage>

Wichtig ist zunächst, dass die ViewModel-Bindung via BindingContext hergestellt wird. Im Prinzip legt das Programm automatisch im Hintergrund eine neue Instanz des ViewModels an und bindet diese an die View-Instanz.

Innerhalb eines StackLayouts wird die ListView kreiert und ihre Datenquelle an das ObservableCollection-Property gebunden. Das heißt, sie kreiert automatisch die notwendigen Itemcontainer, in denen die einzelnen Elemente der Persons-Liste eingetragen werden. Sollten folgend noch Personen hinzukommen oder wieder entfernt werden, bewirken die ausgeschickten Benachrichtigungen der ObservableCollection, dass sich das View selbstständig aktualisiert.

Da die einzelnen Listenelemente von Persons komplexe Objekte sind, bedarf es noch einer genaueren Beschreibung, wie sich ein einzelnes Item aufbauen soll. Andernfalls würde die ListView einfach nur für jedes Element die ToString-Methode aufrufen und du hättest mehrere Einträge, die Example.Person lauten.

Also wird das ItemTemplate definiert. In dem liegen hier einfach nur zwei Labels, die sich jeweils an die Properties der Person-Klasse binden.

Zum Hinzufügen kann man sich einen Button mitsamt Textfeldern gleich unter der ListView erstellen.

<StackLayout Orientation="Horizontal">
  <Entry Text="{Binding NewPersonFirstName}" />
  <Entry Text="{Binding NewPersonLastName}" />
  <Button Command="{Binding AddPerson}" Text="Add" />
</StackLayout>

Die Textfelder werden an neue Properties im ViewModel gehängt und der Button an einen Command. Ein Command ist ein Objekt, welches eine Methode ausführen kann (Execute-Delegate). Zusätzlich könnte man auch noch eine Bedingung anknüpfen, ob der Command überhaupt ausführbar ist (CanExecute-Predicate).

Die neuen Elemente im ViewModel:

public PersonViewModel()
{
  AddPerson = new Command(() =>
  {
    Persons.Add(new Person
    {
      FirstName = NewPersonFirstName,
      LastName = NewPersonLastName
    }
  });

  // ...
}

public ICommand AddPerson { get; }

public string NewPersonFirstName { get; set; }

public string NewPersonLastName { get; set; }

Bezüglich des Löschens von Einträgen würdest du es dir für den Anfang leichter machen, einfach jedes Item im ListView mit einem Button auszustatten.

<Button Command="{Binding RemovePerson}" CommandParameter="{Binding}" />

Dessen Command bekommt diesmal einen Parameter mit auf den Weg, welcher das Person-Objekt selbst darstellt. Das Command-Objekt ist diesmal generisch, ich zeige nur die Definition:

RemovePerson = new Command<Person>(person => Persons.Remove(person));

Lösungen, wie man einen langen Druck abfängt, kannst du dir wiederum von hier ziehen:

  • https://www.c-sharpcorner.com/article/longpress-event-for-image/
  • https://stackoverflow.com/questions/43569515/how-to-make-long-press-gesture-in-xamarin-forms

für diese Antwort empfände ich eine eigene Erklärung zu lang.

Generell solltest du die Microsoft Dokumentation als deine erste Quelle nutzen. In ihr findest du zahlreiche Artikel und auch Beispiele zu Xamarin (sei es zu einzelnen Komponenten, Bindings, Commands, etc.). Grundkenntnisse von C# und OOP werden natürlich wie immer vorausgesetzt. Hinzu kommt, wenn du meinem Lösungsweg folgst, das MVVM-Pattern.

...zur Antwort

An sich brauchst du lediglich ein ul-Element, dem du via DOM API neue li-Elemente anhängst. Für die Texteingabe reicht ein Eingabefeld mit Button.

<ul id="todos"></ul>
<form id="todo-form">
  <input>
  <button type="button">Add</button>
</form>

Dem Button weist du einen click-Handler zu, der die Elemente an das ul-Element hängt.

const toDosList = document.getElementById("todos");
const toDoForm = document.getElementById("todo-form");
toDoForm.querySelector("button").addEventListener("click", () => {
  const toDoItem = document.createElement("li");
  toDoItem.textContent = toDoForm.querySelector("input").value;
  toDosList.appendChild(toDoItem);
});

Wenn du Elemente wieder löschen möchtest, hänge je li-Element noch einen Button an, der bei Klick sein Elternelement löscht.

const removeButton = document.createElement("button");
removeButton.textContent = "Remove";
removeButton.setAttribute("type", "button");
removeButton.onclick = function() { this.parentElement.remove(); }
toDoItem.appendChild(removeButton);

Für eine persistente Speicherung kannst du einen Cookie verwenden, in dem ein Array (bspw. im JSON-Format) gespeichert wird. Bei Aufruf der Webseite liest du den Cookie ein und parst das Array.

const serializedToDos = JSON.parse(cookieValue);

Im Anschluss läufst du einmal durch alle Einträge und hängst sie an dein ul-Element an. Zusätzlich wäre es sinnvoll, konsequent alle Einträge in ein separates Array einzufügen. Beim Speichern brauchst du es nur serialisieren und in deinen Cookie schreiben.

const toDosToStore = JSON.stringify(yourArrayOfTodos);
// write to cookie ...
...zur Antwort
Es gibt noch keinen visuellen Designer zum Generieren von XAML in Xamarin.Forms Anwendungen. Der gesamte XAML-Code muss von Hand geschrieben werden (...)

Quelle

Alternative Tools wären mir da auch nicht bekannt. Auch Blend lässt sich leider nicht vollumfänglich nutzen.

Du könntest dennoch versuchen, dir die Arbeit zu erleichtern, indem du dich nach Templates umschaust (siehe bspw. hier).

Um zumindest eine Preview von der erstellten Oberfläche zu bekommen, könntest du den Gorilla Player nehmen oder du verwendest das in der Dokumentation empfohlene Hot-Reload-Feature.

...zur Antwort

Das ist C.

Dies ist erkennbar an:

  • bekannten Makros (ifndef, define)
  • den Variablentypen (uint16_t, ...)
  • den struct-Typen
  • den inkludierten Headern der C-Bibliothek Hydrogen (sie dient zur Steuerung von Ocea Controlboards, es handelt sich also um Mikrocontrollerprogrammierung)
...zur Antwort

Mit Klassen kannst du deinen Code übersichtlicher gruppieren, Code einsparen und potenzielle Fehlerquellen verringern.

Nimm als Beispiel einen Kreis, der sich bewegen soll. Ohne OOP würdest du vermutlich so vorgehen:

circle_x = 0
circle_y = 0
circle_radius = 5
circle_direction_x = 1
circle_direction_y = 1

def move():
  global circle_x
  global circle_y
  circle_x = circle_x + circle_direction_x
  circle_y = circle_y + circle_direction_y

def draw():
  some_circle_render_function(circle_x, circle_y, circle_radius)

Und wenn es mehrere Kreise sein sollten, würdest du dir vielleicht für all diese Variablen Listen anlegen:

circle_x = [ 0, 1, 2 ]
circle_y = [ 0, 2, 4 ]
circle_radius = [ 5, 6, 7 ]
circle_direction_x = [ 1, -1, 0 ]
circle_direction_y = [ 1, 0, 1 ]

Das sorgt aber für viel Code, Variablen sind unter Umständen wilder im Skript verstreut und gerade solche Listenlösungen sind fehleranfällig, da es durchaus einmal passieren kann, dass man bei einer Liste einen Eintrag vergisst, o.ä.. Das Gleiche gilt für globale Variablen: Es ist bei ihnen öfter schwerer, ihren Werdegang nachzuverfolgen, gerade da sie von jedem und überall veränderbar sind.

Mit einer Klasse könnte man den Code kürzer und einfacher formulieren:

class Circle:
  def __init__(self):
    self.x = 0
    self.y = 0
    self.radius = 5
    self.direction_x = 1
    self.direction_y = 1

  def move(self):
    self.x = self.x + self.direction_x
    self.y = self.y + self.direction_y

  def draw(self):
    some_circle_render_function(self.x, self.y, self.radius)

Die zusammengehörigen Felder und Methoden werden unter einen Namen (einer Klasse) gruppiert. Möchte man nun mehrere Kreise kreieren, bräuchte es nur noch eine Liste:

circles = [ Circle(), Circle(), Circle(), """ ... """ ]

Du hättest nun also einen eigenen Datentyp entworfen, von dem du immer neue Ableger (Objekte) erstellen kannst.

circleA = Circle()
circleA.radius = 2

circleB = Circle()
circleB.radius = 3

Jedes Objekt kann einen eigenen Zustand haben (im obigen Beispiel gibt es z.B. zwei Kreise mit unterschiedlichem Radius).

Vorteilhaft ist ebenso, dass du dein Programm einfacher anhand Realtweltszenarien aufbauen kannst.

Dazu erneut ein Beispiel: Es soll eine Buchverwaltung für eine Bibliothek gebaut werden. Im Vorfeld analysierst du, welche Objekte es in so einem Szenario gibt (Buch, Buchregister, Kunde, ...) und welche Zustände und Verhaltensweisen sie haben (Bücher haben einen Titel, Autor, ein Erscheinungsjahr, einen Verlag; Kunden haben einen Namen, eine zuordbare Adresse; in das Buchregister können Bücher ein- und ausgetragen werden; usw.). So eine Beschreibung ist für dich logisch einfach, fassbar. Und genauso, wie du das Szenario in der realen Welt beschreibst, kannst du es auch auf dein Programm abbilden. Du entwickelst also Datentypen für Buch, Buchregister, etc. und schaffst die zuständigen Beziehungen, die sie untereinander haben.

Basierend auf objektorientierten Modellen kann man Strukturen schaffen, die dein Programm leichter wartbar und flexibel gestalten. Die obig genannten Vorteile sind nur ein Teil, doch es gibt noch weitere hilfreiche Konzepte (Kapselung, Vererbung), die es dir bspw. ermöglichen, Werte von Variablen besser zu kontrollieren oder Modelle zu abstrahieren. So könnte man die Buchverwaltung zum Beispiel weiter umgestalten, sodass es nicht nur Bücher sein müssen, die man verwalten kann, sondern ebenso Videoobjekte. Dafür würde man ein Interface erstellen, in welches die Klassen Buch und Video hineinpassen (verstehe es wie einen abstrakten Platzhalter, der vorgibt, dass nur Objekte, die ihn implementieren, für ihn angegeben werden dürfen). Danach könnte man das Register umändern, sodass es die Registrierung des Interface erlaubt, also im konkreten Fall sowie Buch als auch Video.

Das gesamte OOP-Paradigma stellt eine neue Perspektive dar, wie man an Probleme herangeht. Man beschreibt ein System dazu und teilt dieses in Objekte auf, die miteinander agieren. Diese modulare Aufteilung erlaubt es später, das Programm einfacher erweitern und verändern zu können (indem man bspw. Module austauscht). Das Testen von separaten Teilen deines Programm fällt ebenso leichter (du könntest dir für einen Test z.B. explizit einen Programmteil, also z.B. eine Klasse herauskrallen und sie separat von anderen Programmteilen testen.

...zur Antwort

Alice würde dem wohl am nächsten kommen, außerdem gibt es noch die Plattform CODE.GAME.

Ansonsten könntest du dir 3D Game Engines anschauen, die Visual Scripting unterstützen. Zum Beispiel:

  • Buildbox 3
  • CryEngine
  • Godot
  • Unity3D mit Bolt
  • Unreal

Diese knotenbasierten Systeme unterscheiden sich schon etwas von Scratch. Langfristig gesehen würde ich dir empfehlen, eine textbasierte Programmiersprache (wie C#, Lua, C++, ...) zu lernen, denn sie sind in der Regel besser dokumentiert und haben einen besseren API-Support.

...zur Antwort

PyQt5 WebEngine mehrere WebViews mit jeweils unterschiedlichen Proxys in einem Fenster funktioniert nur bei den ersten beiden Proxys?

Hallo liebe Community,

Ich wollte mit PyQt eine Oberfläche Implementieren, die mehre Websites mit unterschiedlichen Proxys pro Laufzeit aufruft, und anzeigt.

Das soll dann ungefähr so aussehen:

, nur, dass beim 2. Fenster eine andere Proxyaddresse stehen sollte. Hier ist mein Code:

import json
import random
import threading
import time
from typing import *
import requests

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import requests, re
from PyQt5.QtWebEngineWidgets import *
import PyQt5.QtNetwork
import PyQt5.QtWidgets

def refresh_browser():
    time.sleep(10)
    host, port, ct = random.choice(proxylist)
    print(host, port, ct)
    PyQt5.QtNetwork.QNetworkProxy.setApplicationProxy(
        PyQt5.QtNetwork.QNetworkProxy(PyQt5.QtNetwork.QNetworkProxy.Socks5Proxy, host, port))
    window.refresh.click()


proxylist = [(a, b, c) for a, b, c in json.load(open("proxies.txt")) if c == "DE"]
available_proxiy_protocols = {"socks5":PyQt5.QtNetwork.QNetworkProxy.Socks5Proxy, "http":PyQt5.QtNetwork.QNetworkProxy.HttpProxy}
class Browser(QMainWindow):
    def __init__(self, url, proxylist: List):
        super(Browser, self).__init__()
        self.window = QWidget()
        self.layout = QVBoxLayout()
        self.horizontal = QHBoxLayout()
        self.browsers = []
        self.c = 0

        
        self.current_url = url

        self.button = QPushButton()
        self.button.clicked.connect(lambda: self.navigate(self.current_url))

        self.refresh = PyQt5.QtWidgets.QPushButton()
        self.refresh.clicked.connect(lambda: self.refr(self.current_url))


        for proxy in proxylist:
  
    
                #HIER MUSS ETWAS GEÄNDERT WERDEN
                self.browser = QWebEngineView()
    
                self.layout.addLayout(self.horizontal)
                self.layout.addWidget(self.browser)
                self.browser.setUrl(QUrl(self.current_url))
                self.browsers.append(self.browser)
    
            self.window.setLayout(self.layout)

        self.window.show()
    
    def navigate(self, url): self.browser.setUrl(QUrl(url))
    def refr(self, url):
        for br in self.browsers:
            br.setUrl(QUrl(url))
host, port, ct = random.choice(proxylist)
print(host, port, ct)
#PyQt5.QtNetwork.QNetworkProxy.setApplicationProxy(PyQt5.QtNetwork.QNetworkProxy(PyQt5.QtNetwork.QNetworkProxy.Socks5Proxy, host, port))
app = QApplication([])


proxys = [("104.255.170.63", 60757), ("103.241.227.114", 6667)]
ip = "https://httpbin.org/ip"
PyQt5.QtNetwork.QNetworkProxy.setApplicationProxy(PyQt5.QtNetwork.QNetworkProxy(PyQt5.QtNetwork.QNetworkProxy.Socks5Proxy, proxys[0][0], proxys[0][1]))
print(proxys)
window = Browser(ip, proxys)


app.exec()

Kann mir jemand helfen, uns mir sagen, wie ich nach jederm Browserfenster, das erstellt wird, einen anderen Proxy setzen kann?

Vielen Dank Im Voraus

LG Lukas Zander

...zur Frage

Du kannnst für eine einzelne QWebPage einen bestimmten Proxy definieren, indem du ihr eine entsprechende QNetworkAccessManager-Instanz überreichst.

  1. QNetworkAccessManager-Instanz anlegen und Proxy setzen (setProxy)
  2. Instanz an QWebPage überreichen (setNetworkAccessManager)

Die aktuelle QWebPage-Instanz erhältst du über die page-Methode des QWebView.

Für QWebEngineView-Objekte funktioniert das allerdings nicht.

...zur Antwort

Wie du die Ausgabe zusammenbaust, ist dir überlassen. Auch wenn du ein Array bekommst, welches die Datensätze nach Reihe speichert.

Beispiel:

$data = [ 0 => [ 1, 2, 3 ], 1 => [ 4, 5, 6 ], 2 => [ 7, 8, 9 ] ];

if (!empty($data)) {
  for ($i = 0; $i < $numberOfColumns; ++$i) {
    for ($j = 0; $j < count($data); ++$j) {
      print $data[$j][$i]. " ";
    }

    print "<br>";
  }
}
...zur Antwort

Bemühe dich um eine logische, eindeutige Struktur. HTML hat das Ziel, seine Inhalte mit Metainformationen auszustatten, sodass sie hierarchisch einordbar sind und man ihre Bedeutung möglichst gut verstehen kann. Stell dir einfach vor, du würdest dein HTML-Dokument pur lesen und müsstest dich an den HTML-Elementen orientieren, um eine bildliche Vorstellung davon zu bekommen, wie der Inhalt präsentiert werden soll. Wenn du da bspw. eine Navigation mit einem nav-Element umklammert hast, weißt du sofort, dass es sich um eine Navigation handelt.

Für eine Navigation würde ich ein nav-Element verwenden. Da die Navigationspunkte meist hierarchisch strukturiert werden, eignen sich Aufzählungslisten (ul/ol).

Das div-Element selbst hat keine semantische Bedeutung. Das heißt, es wäre besser, erst zu schauen, ob es bessere, ausdrucksstärkere Optionen gibt, deinen Inhalt zu beschreiben (z.B. mit article, section, ...).

Welche Möglichkeiten es gibt bzw. welcher Tag für welche Zwecke geeignet ist, kannst du in der MDN-Dokumentation nachlesen. Zum Beispiel zum span-Element:

The <span> HTML element is a generic inline container for phrasing content, which does not inherently represent anything. It can be used to group elements for styling purposes (using the class or id attributes), or because they share attribute values, such as lang. It should be used only when no other semantic element is appropriate. 

Quelle

Dieses Element ist also auch ohne semantische Bedeutung, so wie ein div-Element. Allerdings dient es der Gruppierung von Inline-Elementen (z.B. wenn du ein einzelnes Wort in einem Text mit einer bestimmten Farbe auszeichnen möchtest).

Angenommen, du hättest den Anwendungsfall, dass du ein Wort in einem Text besonders hervorheben möchtest. Dann könntest du dies mit einem span-Element umsetzen:

<span style="color:red">Wort</span>

oder aber besser mit einem strong:

<strong style="color:red">Wort</strong>

Der Unterschied hierbei liegt darin, dass im zweiten Fall das Wort hierarchisch eine übergeordnete Rolle innerhalb des Textes bekommt. Im ersten Fall hingegen wird es nur visuell hervorgehoben, hat inhaltlich aber die gleiche Gewichtung wie der übrige umgebene Text.

Welches ist das beste Element mit den meisten Möglichkeiten?

Folglicherweise gibt es kein bestes Element. Du kannst zwar alles in span- und div-Elemente packen, doch ausdrucksstark wird dein Dokument dadurch nicht.

...zur Antwort

Deine Logik ist zunächst einmal falsch.

Der Wert von i ist anfangs 0. So wird diese Bedingung

A.length() <= i

nur wahr werden, wenn das Eingabearray tatsächlich leer ist.

Bei der Angabe für den Rückgabewert kann man tatsächlich rätseln. Wenn nur eine Zahl zurückgegeben werden soll, könnte man mutmaßen, das es auch einen eigenen Eingabeparameter geben soll, der entscheidet, welche Summe berechnet wird. Oder aber man löst sich von dem typstrikten Gedanken und gibt tatsächlich einfach 0 oder ein Array zurück. In einigen Programmiersprachen (auch C) wäre das schließlich ebenfalls zulässig.

Bezüglich der Form: Es wäre besser, wenn du ohne Code-Ausdrücke in den einzelnen Schritten auskommen würdest. Zumal diese, wenn man sie z.B. auf Java anwenden würde, nicht einmal korrekt wären:

int[] array A  ------->   int[] a
A.length()     ------->   a.length

Der Sinn hinter solchen Diagrammen ist es, dass sie auch ohne Programmierkenntnisse lesbar sein sollen. Für Ein- und Ausgabe gibt es (in UML 2) spezielle Knotentypen (Objektknoten, dargestellt als Rechtecke). Ich würde dir sehr empfehlen, dazu hier auf PDF-Seite 16-17 (bzw. 210-211) zu lesen.

Dein Initial- und auch der Aktivitätsendknoten sind jeweils falsch. Ersterer müsste voll schwarz ausgefüllt sein, Letzterer hingegen beinhaltet einen schwarz ausgefüllten Punkt in der Mitte.

Der Entscheidungsknoten wiederum bekommt normalerweise keinen Inhalt. Stattdessen legt man einen Kommentar / ein Notizsymbol an (ein Rechteck mit umgeknickter Ecke rechts oben) und definiert in diesem gefolgt von dem Schlüsselwort <<decisionInput>> das Entscheidungsverhalten.

Beispielinhalt:

<<decisionInput>>
Ist der Himmel blau?

Den Kommentarknoten verbindest du anschließend mit einer gestrichelten Linie mit dem Entscheidungsknoten. Ein Beispiel dafür findest du hier auf PDF-Seite 11 (bzw. 205).

Für die einzelnen Aktivitätsknoten solltest du Rechtecke mit abgerundeten Ecken nehmen (nicht runde Seitenkanten).

Zu guter Letzt wäre noch eine Beschriftung gut (der Aktivitätsname). Schau dir dafür das Beispiel von Wikipedia an. Das gesamte Diagramm ist von einem Rechteck mit runden Ecken umrandet. Der Aktivitätsname steht im linken oberen Bereich.

...zur Antwort

a) Gib deinem Canvas-Element zu Programmstart nochmal explizit den Fokus. Andernfalls wird dieser an andere Elemente weitergereicht.

MyCanvas.Focus();

b) Wenn dein Canvas-Element eh die komplette Breite des Fensters einnimmt, kannst du das KeyDown-Event genauso gut dem Window-Element zuordnen.

...zur Antwort
(...) also gibt es in HTML runde boxen?

Du kannst ein Element mit CSS entsprechend visuell verändern.

Beispiel:

<div class="circle"></div>

CSS:

.circle {
  border: 1px solid;
  border-radius: 45px;
  height: 50px;
  width: 50px;
}

Ebenso könntest du SVG in dein HTML-Dokument einbinden und dort das Path-Element verwenden, um völlig frei Formen zu erstellen.

Das spielt sich soweit alles im 2D-Raum ab.

Für 3D-Elemente wäre das Zeichnen (mit JavaScript) auf einem canvas-Element eine passende Lösung. Du kannst dabei auch WebGL einsetzen.

Zusätzlich gibt es einige Frameworks/Bibliotheken, die dir die Angelegenheit noch einmal zusätzlich vereinfachen können.

So könnten Folgende für dich interessant sein:

  • LightGL (leichtgewichtiger WebGL-Wrapper)
  • SVG 3D Builder (um aus SVG 3D-Elemente zu generieren)
  • ThreeJS (WebGL-Bibliothek)
  • Voodoo (zum Mixen von 2D-/3D-Elementen)
...zur Antwort
Bekommt ihr den auch (...)?

Nein.

Ich habe mir für einen Test lediglich das Paket (hier > Code > Download ZIP) heruntergeladen, entpackt und in einen Unterordner eines lokalen Webservers geworfen. Aber auch ohne Webserver (über file:///...) funktioniert der Effekt, wie erwartet.

Fehlermeldungen konnte ich in der Browserkonsole (nach mehrmaligem Hoch-/Herunterscrollen) nicht wahrnehmen. Das gilt für unterschiedliche Webbrowser (Chrome, Firefox, Opera, Brave, ...).

und wie kann ich diesen beheben?

Man kann nur mutmaßen, dass du den Quellcode geändert hast. Der schnellste und einfachste Lösungsweg wäre es, die Änderungen rückgängig zu machen (am besten, indem du alles einfach mit den Originaldateien überschreibst).

Ansonsten als erste Abarbeitungsliste:

  • Es muss ein HTML-Element im Dokument geben, welches ein class-Attribut besitzt, in dessen Wert home-intro enthalten ist. Im Originalcode ist das das erste section-Element.
<section class="home-intro">
  • Das Skript darf erst ausgeführt werden, sobald das HTML-Dokument geladen wurde. Daher hat der Entwickler die script-Einbindung auch erst vor dem schließenden body-Tag vorgenommen.
...zur Antwort
A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )

Quelle

Oder noch einmal von offizieller Seite: Identifiers and keywords.

Ein Workaround für freie Bezeichner/Keys wäre ein Dictionary. In diesem kann man Werte assoziativ zu einem String abspeichern.

my_dictionary = { "hello#1", True }

# get value:
print(my_dictionary["hello#1"])
...zur Antwort
Also wenn ich einfach ein Div erstelle ohne Inhalt, hat es ja erstmal ein Breite von 100%, wenn nichts eingestellt wird.

Genau. Das liegt daran, dass es sich um ein Blockelement handelt. Blockelemente nehmen typischerweise die komplette Breite ihres Elternelements ein. Das in der Hierarchie oberste Blockelement ist das body-Element, welches initial die Fensterbreite besetzt.

Aber die Kinder haben dann nur noch die Breite wie deren Kinder.

Die Kindelemente halten sich ebenfalls an das oben erwähnte Verhaltensmuster, sofern es sich um Blockelemente handelt.

Ist dem automatisch so, oder wann ist dem so, und wann nicht?

Die Orientierung an der Breite des Elternelements erfolgt automatisch. Gestört wird sie nur durch das Festlegen einer individuellen Breite, einer Typänderung der Renderingbox oder indem man das Element aus dem üblichen Textfluss herausbricht.

Das folgende Beispiel zeigt alle Fälle. Bis auf die erste Box nehmen alle anderen Boxen nicht mehr die volle Breite ihres Elternelements an.

<div class="container">
  <div class="box1">Box 1</div>
  <div class="box2">Box 2</div>
  <div class="box3">Box 3</div>
  <div class="box4">Box 4</div>
</div>

CSS:

.container {
  position: relative;
}

.box1 {
  background: red;
}

.box2 {
  background: yellow;
  width: 50px;
}

.box3 {
  background: green;
  display: inline;
}

.box4 {
  background: purple;
  position: absolute;
}
(...) weil ein Div und ein Image diesbezüglich nicht "gleichwertig" sind?

Innerhalb eines Flexboxcontainers werden alle Elemente als Flexitems gewertet. Der verfügbare Platz wird automatisch verteilt und das Item, welches am meisten Platz benötigt, bekommt auch mehr Platz. Zudem gilt eine Standardregel: Ein Item kann nicht kleiner werden als sein Inhalt auf der Hauptachse.

Das heißt, wenn du bspw. drei Elemente in deinem Container hast, bei denen zwei jeweils ein großes Bild darstellen, kann es zu einem Überlappen/Überlaufen der Box kommen. Um das zu verhindern, müsste man entweder das overflow-Property setzen oder besser, den Wert von min-width für die Bildelemente mit 0 überschreiben.

Wenn du nun das justify-content-Property auf space-between setzt, erfolgt einfach nur eine gleichmäßige Verteilung aller Elemente auf der Zeile mit ebenso gleichmäßigen Abständen untereinander (Voraussetzung dafür ist natürlich, das der Container auch genügend Platz dafür hat, andernfalls wird die Eigenschaft nicht visuell sichtbar). Die äußersten Elemente grenzen direkt an der Kante des Flexboxcontainers an.

Eine Änderung des display-Properties von Elementen in einer Flexbox ändert ihr Verhalten innerhalb der Flexbox nicht, sondern beeinflusst wenn nur den Kontext für ihre Kindelemente. Einzige Ausnahme wäre der Wert none, denn mit diesem Wert werden die Elemente schlichtweg nicht gerendert.

...zur Antwort