string.ToFloat() mit string = "0" -> seltsames Verhalten

Fehler in Firmware und WebUI & Workarounds

Moderator: Co-Administratoren

dtp
Beiträge: 6492
Registriert: 21.09.2012, 08:09
Wohnort: Stuttgart
Hat sich bedankt: 3 Mal
Danksagung erhalten: 8 Mal

string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von dtp » 11.01.2019, 20:47

Führe ich folgendes Skript aus

Code: Alles auswählen

string wert = "";
if(!wert){WriteLine("a leer");}

string wert = "0.0";
wert = wert.ToFloat();
if(!wert){WriteLine("b leer");}
erhalte ich als Ausgabe

Code: Alles auswählen

a leer
b leer
Mache ich das gleiche mit einem Zahlenwert ~= 0

Code: Alles auswählen

string wert = "";
if(!wert){WriteLine("a leer");}

string wert = "1";
wert = wert.ToFloat();
if(!wert){WriteLine("b leer");}
erhalte ich als Ausgabe, wie erwartet, nur

Code: Alles auswählen

a leer
Wieso wird der in einen Realwert umgewandelte Wert 0 behandelt, wie ein leerer String?

Feature oder Bug?
Zuletzt geändert von dtp am 24.05.2019, 14:35, insgesamt 1-mal geändert.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container, Homebridge auf Raspberry Pi 3B+;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

Benutzeravatar
Black
Beiträge: 1803
Registriert: 12.09.2015, 22:31
Wohnort: Wegberg
Hat sich bedankt: 4 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von Black » 11.01.2019, 21:00

hmmm iegentlich ergibt das das was ich erwartet habe:

Code: Alles auswählen

string wert = "";
if(!wert){WriteLine("a leer");}

WriteLine ("leerstring To int: "#"".ToInteger () );
string wert = "0.0";
wert = wert.ToFloat();
if(!wert){WriteLine("b leer");}
if (!0) {WriteLine ("b leer");}
WriteLine (false.ToInteger () );
WriteLine (true.ToInteger () );    

ergibt

Code: Alles auswählen

------------------------------- Scriptausgabe -------------------------------
a leer
leerstring To int: 0
b leer
b leer
0
1
------------------------------ Script Variablen -----------------------------
[wert              ]: 0.000000
Ein Leerer Sring wird zahlentechnisch eine 0 (obs sinnig ist sei dahingestellt)
eine 0 ist in der Logig bei BoolExpression False
ein !0 ist dann True
von daher sind deine ausgaben schlüssig.

ok, das Wandeln eines leerstrings in Integergibt in denmir bekannten proframmiersprachen eine Exception, die man mit try abfangen mussoder man muss die wandlung mit TryStrtoInt machen und das ergebnis der Funktion auf success (true) auswerten.

Rega is halt bisschen...naja...
Die Wahrheit ist ein Chor aus Wind
Meine Seite, ok noch bisschen im Aufbau

RaspberryMatic 3.45.7.20190507 mit Groundplane Antennenmod (Mein Grundstück ist halt etwas gross)
jede Menge Sensoren und Aktoren, Logamatic 2107 Gateway zum Buderus Kessel
ioBroker unter ProxMox auf NUC als Hauptsteuersystem und Visualisierung
Script Time Scheduler V1.3
SDV 3.08.11 Scripteditor und Objektinspektor

dtp
Beiträge: 6492
Registriert: 21.09.2012, 08:09
Wohnort: Stuttgart
Hat sich bedankt: 3 Mal
Danksagung erhalten: 8 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von dtp » 12.01.2019, 10:30

Die Besonderheit, dass "sting.ToInteger()" und "string.ToFloat()" jeweils den Zahlenwert 0 statt NaN oder dergleichen ausgibt, wenn string keinen Zahlenwert enthält, hatten wir ja hier schon diskutiert. Damit kann man leben, wenn man es weiß.

Aber dass "string.ToFloat()" jeweils false ist, wenn string leer ist oder den Wert 0 annimmt, ist aus meiner Sicht unlogisch, zumal jeder Zahlenwert ungleich 0 dazu führt, dass "string.ToFloat()" true wird. Wieso wird der Zahlenwert 0 hier anders behandelt, als alle anderen Zahlenwerte?
2019-01-12_10h34_04.png
2019-01-12_10h34_04.png (8.92 KiB) 423 mal betrachtet
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container, Homebridge auf Raspberry Pi 3B+;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

Gerti
Beiträge: 1110
Registriert: 28.01.2016, 18:06
Hat sich bedankt: 2 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von Gerti » 12.01.2019, 10:40

Hi!

0 ist in der Logik doch quasi false, somit ist die Ausgabe in meinen Augen völlig normal.

Gruß
Gerti

dtp
Beiträge: 6492
Registriert: 21.09.2012, 08:09
Wohnort: Stuttgart
Hat sich bedankt: 3 Mal
Danksagung erhalten: 8 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von dtp » 12.01.2019, 11:03

Warum ist es logisch, dass für 0 der Wert false, für alle andere Werte ungleich 0 aber true gesetzt wird und damit die 0 exakt so, wie ein leerer String behandelt wird?

Ich sitze gerade an einem Skript, mit dem ich meine Rollladen zentral steuern kann. Mittels zweier Systemvariablen können verschiedene Parameter in entsprechenden WebUI-Programmen gesetzt werden. Das Setzen der beiden Systemvariablen sieht beispielsweise folgendermaßen aus:

Code: Alles auswählen

! +++++ Liste der Beschattungsgeräte, Behanghöhen bzw. Ausfahrwerte und Offset-Werte für geöffnete bzw. gekippte Fenster und Türen +++++
! Stets nach dem Muster "Beschattungsgerät|Behanghöhe|Offset(t_o_)|Auslösebedingung\t
!                        Beschattungsgerät|Behanghöhe|Offset(t_o_)|Auslösebedingung" 
! ausfüllen (trennen mit "\t")
! Auslösebedingung für den Vergleich von Ist- und Soll-Wert +++++
! ne: Ist <> Soll | gt: Ist > Soll | ge: Ist >= Soll | lt: Ist < Soll | le: Ist <= Soll
string blindsList = "DG Schlafzimmer Rollladen Terrassentür|0|t10o90|ne\t
                     OG Gästezimmer Rollladen Fenster|30|t0o50|ne\t
                     OG Zimmer Lina Rollladen Fenster groß|30|t0o50|lt\t
                     OG Zimmer Jona Rollladen Fenster|40|t0o50|lt\t
                     EG Wohnzimmer Rollladen Fenster|20|t10o50|lt\t
                     EG Wohnzimmer Rollladen Terrassentür|20|t10o100|ne\t
                     UG Büro Rollladen Fenster|0|t10o90";

! +++++ Globale Werte für Behanghöhen bzw. Ausfahrwerte und Offset-Werte für geöffnete bzw. gekippte Fenster und Türen +++++
! Wenn gesetzt, sind keine lokalen Werte in "blindsList" notwendig bzw. werden ignoriert 
! Stets nach dem Muster "Behanghöhe|Offset(t_o_)|Auslösebedingung\t
!                        Behanghöhe|Offset(t_o_)|Auslösebedingung"
! ausfüllen (trennen mit "\t")
! Auslösebedingung für den Vergleich von Ist- und Soll-Wert +++++
! ne: Ist <> Soll | gt: Ist > Soll | ge: Ist >= Soll | lt: Ist < Soll | le: Ist <= Soll
string blindsGlobalValues = ""; !"" zur Berücksichtigung der lokalen Werte in "blindsList"
Es wird nun in dem zentralen Skript abgefragt, ob z.B. die Systemvariable mit den Werten von "blindGlobalValues" leer ist oder ob sie Werte enthält. Ist sie leer, werden die einzelnen Werte gemäß der Systemvariablen mit den Werten von "blindsList" verwendet. Ist sie nicht leer, werden die Einzelwerte von "blindList" ignoriert und stattdessen die globalen Werte von "blindGlobalValues" für alle Rollläden gleichermaßen verwendet. Das funktioniert soweit auch problemlos. Wenn aber nun "blindsGlobalValues" den Wert 0 enthält, was ja einem globalen Schließen der Rollläden entspricht, dann denkt das Skript, die Variable ist leer und führt das Skript mit den Einzelwerten aus. Und genaus das will ich vermeiden. Wegen des obigen Problems geht das aber nicht so einfach, wie erhofft.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container, Homebridge auf Raspberry Pi 3B+;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

hobbyquaker
Beiträge: 3300
Registriert: 12.07.2009, 20:01
Danksagung erhalten: 18 Mal
Kontaktdaten:

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von hobbyquaker » 12.01.2019, 11:11

Völlig normales Verhalten imho. Nicht-leere Strings evaluieren zu true, leere Strings evaluieren zu false. Numerische 0 evaluiert zu false, numerische nicht-0 zu true.

Beispiele Node und Python:

Code: Alles auswählen

$ echo "console.log(Boolean(''))" | node
false
$ echo "console.log(Boolean(0))" | node
false
$ echo "console.log(Boolean(1))" | node
true
$ echo "console.log(Boolean('0'))" | node
true
$ echo "console.log(Boolean(Number('0')))" | node
false


$ echo "print bool('')" | python
False
$ echo "print bool(0)" | python
False
$ echo "print bool(1)" | python
True
$ echo "print bool('0')" | python
True
$ echo "print bool(float('0'))" | python
False


Gerti
Beiträge: 1110
Registriert: 28.01.2016, 18:06
Hat sich bedankt: 2 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von Gerti » 12.01.2019, 11:33

Hi!

Es ist ja auch kein String mehr, sondern ein Float, also Zahlenwerte.

Gruß
Gerti

dtp
Beiträge: 6492
Registriert: 21.09.2012, 08:09
Wohnort: Stuttgart
Hat sich bedankt: 3 Mal
Danksagung erhalten: 8 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von dtp » 12.01.2019, 11:40

Okay, heißt also, man kann generell nicht zwischen einer leeren Stringvariablen und einer mit dem Zahlenwert 0 unterscheiden. Schade.

Welchen Sinn macht es denn, eine Stringvariable mit dem Zahlenwert 0 auf false zu setzen? Wann braucht man das?
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container, Homebridge auf Raspberry Pi 3B+;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

dtp
Beiträge: 6492
Registriert: 21.09.2012, 08:09
Wohnort: Stuttgart
Hat sich bedankt: 3 Mal
Danksagung erhalten: 8 Mal

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von dtp » 12.01.2019, 11:41

Gerti hat geschrieben:
12.01.2019, 11:33
Es ist ja auch kein String mehr, sondern ein Float, also Zahlenwerte.
Genau. Und deshalb hätte ich erwartet, dass man zumindest nach der Konvertierung eine 0 behandelt, wie jeden anderen Zahlenwert auch. Aber das ist augenscheinlich nicht gewollt.

Wenn ich einen String mit dem Zahlenwert 0 in einen Integer- oder Real-Wert konvertiere, dann kann ich damit exakt so weiterrechnen, als wenn der String beliebige Buchstaben- und Sonderzeichen-Kombinationen enthalten würde oder leer ist. Das mag durchaus Vorteile haben, um zu vermeiden, dass ein Skript unkontrolliert aussteigt, aber so wirklich logisch ist es aus meiner Sicht nicht.

Ich habe nun den besonderen Fall, dass ich einen String mit Zahlenwerten zwischen 0 und 100 (inklusive des Wertes 0) anders behandelt möchte als einen mit Buchstaben oder Sonderzeichen. Einfach aus dem Grund, dass ich bei Fehleingabe das Skript konrolliert abbrechen möchte. Und da scheint es keine Möglichkeit zu geben, oder?
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container, Homebridge auf Raspberry Pi 3B+;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

Benutzeravatar
Black
Beiträge: 1803
Registriert: 12.09.2015, 22:31
Wohnort: Wegberg
Hat sich bedankt: 4 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: !string.ToFloat() mit string = "0" -> seltsames Verhalten

Beitrag von Black » 12.01.2019, 12:06

oder musst durch den string einmal durchiterieren ob nur ziffern (mit .) vorkommen. alternativ aufruf von tcl und dort regex.

Die scriptsprache ist da nicht sooooo das dollfelxible konstrukt

Black
Die Wahrheit ist ein Chor aus Wind
Meine Seite, ok noch bisschen im Aufbau

RaspberryMatic 3.45.7.20190507 mit Groundplane Antennenmod (Mein Grundstück ist halt etwas gross)
jede Menge Sensoren und Aktoren, Logamatic 2107 Gateway zum Buderus Kessel
ioBroker unter ProxMox auf NUC als Hauptsteuersystem und Visualisierung
Script Time Scheduler V1.3
SDV 3.08.11 Scripteditor und Objektinspektor

Antworten

Zurück zu „HomeMatic - bekannte Bugs“