Numerische Variablen aufsteigend sortiern

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

AGmac
Beiträge: 16
Registriert: 20.12.2022, 11:18
System: CCU
Hat sich bedankt: 2 Mal

Numerische Variablen aufsteigend sortiern

Beitrag von AGmac » 05.02.2023, 09:30

Ich habe drei Variablen x, y, z, die mit beliebigen Real-Werten gefüllt werden.

z.B.

real x = 2,345
real y = 8,783
real z = 1,034


Diese sollen aber in aufsteigender Reihenfolge in die Variablen a, b, c ausgegeben werden:

real a = z (1,034)
real b = x (2,345)
real c = y (8,783)

Wie kann ich das bewerkstelligen?

Herzlichen Dank für Euren Input und ein schönes / erholsames Wochenende!

Tyfys
Beiträge: 531
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 26 Mal
Danksagung erhalten: 121 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von Tyfys » 05.02.2023, 10:08

Hier ein Beispiel:

Code: Alles auswählen

real x = 2.345;
real y = 8.783;
real z = 1.034;

object arr = x#";"#y#";"#z;
string av;
string an;
integer len = web.webGetValueListCount(arr).ToInteger() - 1;
boolean swapped = true;
boolean revers = true;
WriteLine( "unsortiert:");
WriteLine(arr);
while (swapped)
{
    integer i = 1;
    swapped = false;
    while (i <= len)
    {
        if ((web.webGetValueFromList(arr, i).ToFloat()) < (web.webGetValueFromList(arr, i - 1).ToFloat()))
        {
            av = web.webGetValueFromList(arr, i - 1) # ";" # web.webGetValueFromList(arr, i);
            an = web.webGetValueFromList(arr, i) # ";" # web.webGetValueFromList(arr, i - 1);
            arr = arr.Replace(av, an);
            swapped = true;
        }
        i = i + 1;
    }
}
WriteLine( "sortiert:");
WriteLine( "aufsteigend:");
WriteLine(arr);

if (revers)
{
    object arr2="";
    string elem;
    foreach(elem, arr.Split(";"))
    {
        arr2 = elem # ";" # arr2;
    }
}
WriteLine( "absteigend:");
WriteLine(arr2.RTrim(";"));

real a= web.webGetValueFromList(arr, 0);
real b= web.webGetValueFromList(arr, 1);
real c= web.webGetValueFromList(arr, 2);
WriteLine("a = "#a);
WriteLine("b = "#b);
WriteLine("c = "#c);
zu beachten:
Dezimalzeichen ist ein Punkt.
Gruß
Harry

AGmac
Beiträge: 16
Registriert: 20.12.2022, 11:18
System: CCU
Hat sich bedankt: 2 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von AGmac » 05.02.2023, 13:02

Moin Harry,

danke für Deine blitzschnelle Antwort - und dann auch noch perfekt! :-)

Eine Frage habe ich noch:

Wenn NUR Werte größer "0" berücksichtigt werden sollen, wie muss ich diese "Bedingung" in Dein Script integrieren?

Tyfys
Beiträge: 531
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 26 Mal
Danksagung erhalten: 121 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von Tyfys » 05.02.2023, 13:23

ich würde es durch ersetzen dieser Zeile :

Code: Alles auswählen

object arr = x#";"#y#";"#z;
durch diese Zeilen:

Code: Alles auswählen

object arr = "";
if (x>0.0) {arr= arr#";"#x;}
if (y>0.0) {arr= arr#";"#y;}
if (z>0.0) {arr= arr#";"#z;}
arr= arr.LTrim(";");
machen.

Kommt aber auch drauf an, was du genau willst.
Gruß
Harry

AGmac
Beiträge: 16
Registriert: 20.12.2022, 11:18
System: CCU
Hat sich bedankt: 2 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von AGmac » 05.02.2023, 13:44

Perfekt - wo kann ich mal selber schlau machen, damit ich sowas demnächst auch selbst hinbekomme?

Oder: wie funktioniert das mit Arrays?

Benutzeravatar
HM-Villa
Beiträge: 488
Registriert: 24.01.2022, 10:13
System: CCU
Hat sich bedankt: 28 Mal
Danksagung erhalten: 113 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von HM-Villa » 05.02.2023, 14:15

Ganz einfach, Du musst die "0" mit dazu nehmen, in dem Du nicht auf ">0.0" sondern auf ">=0" prüfst.

Code: Alles auswählen

if (x>=0.0) {arr= arr#";"#x;}
if (y>=0.0) {arr= arr#";"#y;}
if (z>=0.0) {arr= arr#";"#z;}
______________________________________________________
950 Kanäle in 201 Geräten und 39 CUxD-Kanäle in 5 CUxD-Geräten

AGmac
Beiträge: 16
Registriert: 20.12.2022, 11:18
System: CCU
Hat sich bedankt: 2 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von AGmac » 05.02.2023, 14:21

Ja, :-) das hatte ich schon gemacht - es klappt alles so wie es beabsichtigt war, - DANK Deiner Hilfe.

Wie genau "funktioniert" das Skript bzgl. des Arrays?

Ich habe verstanden, dass anfangs die Variablen in das Array gepackt werden.

Wo mein Verstehen aber aufhört ist die Vorgehensweise in

if ((web.webGetValueFromList(arr, i).ToFloat()) < (web.webGetValueFromList(arr, i - 1).ToFloat()))
{
av = web.webGetValueFromList(arr, i - 1) # ";" # web.webGetValueFromList(arr, i);
an = web.webGetValueFromList(arr, i) # ";" # web.webGetValueFromList(arr, i - 1);
arr = arr.Replace(av, an);
swapped = true;
}

u.a. auch was das "swapped" bewirkt, sowie die Nomenklatur als solche "web.webGetValueFromList". Ist das ein feststehender Ausdruck und wo sind solche für Lernende nachlesbar?

Tyfys
Beiträge: 531
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 26 Mal
Danksagung erhalten: 121 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von Tyfys » 05.02.2023, 16:48

Wenn du etwas mehr in die Skriptprogrammierung einsteigen willst findest du hier mehr Information:
https://www.eq-3.de/downloads/download/ ... g_V2.3.pdf
Leider sicnd dort nicht alle Befehle dokumentiert.
Daher findest du hier noch mehr, die von Foristen entdeckt/dokumentiert wurden:
viewtopic.php?f=31&t=59101#p585248

Leider gibt es in HM-Skript keine bekannten Array / -Funktionen.

Etwas ähnliches wird Werteliste genannt.
Es handelt sich im Prinzip um eine Zeichenkette (oder String), wo die einzelnen Elemente durch Semikolon getrennt sind.

Da können dann die einzelnen Elemente z.B. durch web.webGetValueFromList(String ,Index) ausgelesen werden können.
Möglich wäre auch String.StrValueByIndex(";", Index)wobei das Trennzeichen (hier Semikolon) auch beliebig sein kann.
In jedem Fall geht der Index von 0 bis n, wobei 0 umgangssprachlich das erste Element ist.

Im Beispiel vergleiche ich ein Element mit dem Nachbarn und tausche diese, falls die Bedingung stimmt.
Danach geht es dann mit dem nächsten Element weiter. usw..
ToFloat() wandelt dabei die Zeichenkette zum Vergleich in eine Zahl mit Nachkommastellen.
Sonst wäre z.B. die Zahl 10.123 als String kleiner als die Zahl 2.456 als String.


swapped dient dabei als Schalter ( an/aus bzw true/false etc) , ob etwas in dem Durchgang getauscht wurde.
Wenn nichts mehr getauscht wurde ist die Sortierung beendet.
Damit die while-Schleife mindestens einmal abgearbeitet wird, muss die Variable swapped erstmal auf true gesetzt werden.

Damit du die einzelnen Schritte besser nachvollziehen kannst, füge einfach
WriteLine() - Statements ein. - z.B. WriteLine(an) nach den entsprechenden Statements ein.

Viel Spaß beim experimentieren.
Gruß
Harry

Benutzeravatar
HM-Villa
Beiträge: 488
Registriert: 24.01.2022, 10:13
System: CCU
Hat sich bedankt: 28 Mal
Danksagung erhalten: 113 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von HM-Villa » 05.02.2023, 17:11

Hallo AGmac,

web.webGetValueFromList ermöglicht den Zugriff auf einzelne Listenelemente.

Code: Alles auswählen

if ((web.webGetValueFromList(arr, i).ToFloat()) < (web.webGetValueFromList(arr, i - 1).ToFloat()))
Der Index (hier i) einer Liste beginnt mit 0, i ist = 1. Also wird hier z. B. beim ersten Durchlauf das 2. Element der Liste mit dem 1. Element (i-1=0) verglichen. Ist das 2. Element kleiner muß es "aufsteigen", was im Folgenden passiert.

Code: Alles auswählen

av = web.webGetValueFromList(arr, i - 1) # ";" # web.webGetValueFromList(arr, i);
Um für arr ein Suchkriterium zu haben (was muss geändert werden?), wird hier der Suchstring zusammengebaut, das "v" am "a" heißt bestimmt "vorher". Inhalt von av sind die verglichenen Werte in der alten Reihenfolge (1. Element (i-1), 2. Element (i)).

Code: Alles auswählen

an = web.webGetValueFromList(arr, i) # ";" # web.webGetValueFromList(arr, i - 1);
Nun braucht man noch was, mit dem av ersetzt werden kann. Die Reihenfolge muss getauscht werden. "n" soll bestimmt "nachher" sein. Also braucht an jetzt die Werte in umgekehrter Reihenfolge (2. Element (i), 1. Element (i-1)).

Code: Alles auswählen

arr = arr.Replace(av, an);
Jetzt wird in arr "av" durch "an" ersetzt. Damit ist der zweite Wert, wenn er denn kleiner war, als der erste, eine Position aufgestiegen. Die Assoziation zu "Aufsteigen" gibt dieser Art der Sortierung auch ihren Namen. Suche mal im Web nach "bubble sort". :!:

Code: Alles auswählen

swapped = true;
Falls nun im aktuellen Schleifendurchlauf etwas getauscht werden musste, wird swapped auf true gesetzt, damit es einen weiteren Schleifendurchlauf gibt. Andersrum betrachtet ist swapped das Abbruchkriterium für die while-Schleife. Denn wenn es bei einem Durchlauf nichts mehr zu sortieren gab, stimmt die Reihenfolge und man kann aufhören. Hier ist das nicht so entscheidend, bei sehr vielen Elementen kann man aber 'ne Menge Zeit sparen, wenn man so'n Abbruchkriterium hat.

Einsteigerhilfen gibt es im Thread "Tipps für Anfänger", Punkt E6) ist schon mal ganz gut.

EDIT: @Tyfys war schneller, ist ja auch sein Script, aber doppelt hält besser. :wink: Ansonsten: Lesen, lesen, lesen... und ausprobieren. Wenn etwas partout nicht gehen will - fragen.
______________________________________________________
950 Kanäle in 201 Geräten und 39 CUxD-Kanäle in 5 CUxD-Geräten

Tyfys
Beiträge: 531
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 26 Mal
Danksagung erhalten: 121 Mal

Re: Numerische Variablen aufsteigend sortiern

Beitrag von Tyfys » 05.02.2023, 17:32

@HM-Villa
Vielen Dank für die Unterstützung bei der Erklärung. Sehr gut analysiert.
(Kenne auch Leute, die nur ihrer eigenen Skripte/Programme verstehen).

Da man ja manchmal tippfaul ist:
mit av meinte ich arrayelementvon
und mit an meinte ich arrayelementnach

Nebenbei: .Replace() tauscht dann ja auch andere zufällig gleiche Nachbarn, so dass dann Steps eingespart werden.
Gruß
Harry

Antworten

Zurück zu „HomeMatic allgemein“