While Schleife
-
- Beiträge: 37
- Registriert: So 31. Mai 2020, 21:13
While Schleife
Hallo,
ich habe eine Schleife gebaut, die erste IF ELSE Bedingung in der Schleife wird auch erfolgreich durchgeführt, aber das Programm friert ein. Programm läuft auf 30 % CPU
ich geh mal davon aus, dass meine Abbruchbedingung nicht greift: die schleife soll von einem Preis x hochgehen bis <= stringPrice oder bis stringPrüfpunkt auf 1 (also bei 1 soll die Schleife nicht mehr durchgeführt werden). Ich habe das Programm mit verschiedenen Werten getestet und irgendwie hatte ich das gefühl, dass variablePrice := variablePrice + '2';
nicht hochzählt. Das würde aber im Widerspruch stehen mit meinen vorherigen Sätzen.
müssen noch zwei IF Else Bedingungen eingebaut werden,.
Wenn keine der drei Bedingungen greifen, dann soll der stringPrüfpunkt auf 1 (zur Begin ist der Wert 0) gesetzt werden. Vorher soll die Schleife alle variablePrice durchlaufen (wird immer aus der DB geholt).
Könnt ihr mal bitte rüberschauen??
unten ist der verbesserte Code.
ich habe eine Schleife gebaut, die erste IF ELSE Bedingung in der Schleife wird auch erfolgreich durchgeführt, aber das Programm friert ein. Programm läuft auf 30 % CPU
ich geh mal davon aus, dass meine Abbruchbedingung nicht greift: die schleife soll von einem Preis x hochgehen bis <= stringPrice oder bis stringPrüfpunkt auf 1 (also bei 1 soll die Schleife nicht mehr durchgeführt werden). Ich habe das Programm mit verschiedenen Werten getestet und irgendwie hatte ich das gefühl, dass variablePrice := variablePrice + '2';
nicht hochzählt. Das würde aber im Widerspruch stehen mit meinen vorherigen Sätzen.
müssen noch zwei IF Else Bedingungen eingebaut werden,.
Wenn keine der drei Bedingungen greifen, dann soll der stringPrüfpunkt auf 1 (zur Begin ist der Wert 0) gesetzt werden. Vorher soll die Schleife alle variablePrice durchlaufen (wird immer aus der DB geholt).
Könnt ihr mal bitte rüberschauen??
unten ist der verbesserte Code.
Zuletzt geändert von Daniel_Berlin am Do 11. Jun 2020, 17:18, insgesamt 5-mal geändert.
-
- Beiträge: 37
- Registriert: So 31. Mai 2020, 21:13
Re: While Schleife
Noch eine Anmerkung:
Wenn die erste Bedingung auf <= setze und einen höheren wert für stringPrice einsetze als variablePrice , dann wird die IF Else bedingung nicht durchgeführt. Das ist ja aber eigentlich falsch wenn ich <= einsetze.
IF ((variablePrice <= stringPrice) AND (p = '0') AND (stringNachname = tabelle2Nachname) AND (stringName= variableNachname))
THEN
BEGIN
Form2.SQLQuery1.SQL.Text := 'INSERT INTO tabelle3 (....) values (...)
P:= '1';
Form2.closeDB;
END
Wenn die erste Bedingung auf <= setze und einen höheren wert für stringPrice einsetze als variablePrice , dann wird die IF Else bedingung nicht durchgeführt. Das ist ja aber eigentlich falsch wenn ich <= einsetze.
IF ((variablePrice <= stringPrice) AND (p = '0') AND (stringNachname = tabelle2Nachname) AND (stringName= variableNachname))
THEN
BEGIN
Form2.SQLQuery1.SQL.Text := 'INSERT INTO tabelle3 (....) values (...)
P:= '1';
Form2.closeDB;
END
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: While Schleife
Kann es sein, dass du versuchst mit string zu rechnen?
var
variableprice: real;
variableprice := Form2.SQLQuery1.FieldByName('price').AsFloat;
OffTopic:
Generell würde ich die DB-Zugriffe und die Übergab der DB-Werte über eine Klasse (je Tabelle) definieren.
Dann brauchst du im Programm nur noch mit den Objekten hantieren und machst dir das Leben einfacher.
Die Änderungsprüfung etc. kann dann auch deutlich vereinfacht werden und taucht nicht in der Programmlogik auf.
Dein
könnte dann z.B. so aussehen:
var
variableprice: real;
variableprice := Form2.SQLQuery1.FieldByName('price').AsFloat;
OffTopic:
Generell würde ich die DB-Zugriffe und die Übergab der DB-Werte über eine Klasse (je Tabelle) definieren.
Dann brauchst du im Programm nur noch mit den Objekten hantieren und machst dir das Leben einfacher.
Die Änderungsprüfung etc. kann dann auch deutlich vereinfacht werden und taucht nicht in der Programmlogik auf.
Dein
Code: Alles auswählen
IF ((variablePrice <= stringPrice) AND (p = '0') AND (stringNachname = tabelle2Nachname) AND (stringName= variableNachname))
THEN
BEGIN
Form2.SQLQuery1.SQL.Text := 'INSERT INTO tabelle3 (....) values (...)
P:= '1';
Form2.closeDB;
END
Code: Alles auswählen
Table3.WriteData;
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
-
- Beiträge: 37
- Registriert: So 31. Mai 2020, 21:13
Re: While Schleife
Ich bin jetzt schon etwas weitergekommen.
Ich rechne jetzt mit double. Irgendwie ist das Programm in einer Endlosschleife, da das Programm einfriert und der Prozess bei 30% liegt. Die Bedingungen in den IF Else habe ich erfolgreich durchgetestet. Das Verhalten in der IF Elese wird durchgeführt, wenn die Bedingungen stimmen. Jedoch nicht bei einen etwas höheren Preis. Aber da würde es theoretisch auch greifen, da der niedriste Preis ( unter stringCheck = '1') hat und ich das ja ausschließe mit (stringCheck = '0'). Also irgendwie geht zählt die Schleife ggf nicht hoch?!
Zudem habe ich festgestellt, dass ich nicht den richtigen Rückgabewert bekomme. ich bekomme nicht den niedrigsten Preis zurück. Hab das in mysql getestet.
SELECT * FROM sell WHERE price= (SELECT min(price) FROM sell);
Die Berechnung in der IF ELSE liefert irgendwie 0 zurück obwohl es mehr sein müssen.
floatTempVolume := floatBuyVolume - floatSellVolume;
Anbei der verbesserte Code:
Ich rechne jetzt mit double. Irgendwie ist das Programm in einer Endlosschleife, da das Programm einfriert und der Prozess bei 30% liegt. Die Bedingungen in den IF Else habe ich erfolgreich durchgetestet. Das Verhalten in der IF Elese wird durchgeführt, wenn die Bedingungen stimmen. Jedoch nicht bei einen etwas höheren Preis. Aber da würde es theoretisch auch greifen, da der niedriste Preis ( unter stringCheck = '1') hat und ich das ja ausschließe mit (stringCheck = '0'). Also irgendwie geht zählt die Schleife ggf nicht hoch?!
Zudem habe ich festgestellt, dass ich nicht den richtigen Rückgabewert bekomme. ich bekomme nicht den niedrigsten Preis zurück. Hab das in mysql getestet.
SELECT * FROM sell WHERE price= (SELECT min(price) FROM sell);
Die Berechnung in der IF ELSE liefert irgendwie 0 zurück obwohl es mehr sein müssen.
floatTempVolume := floatBuyVolume - floatSellVolume;
Anbei der verbesserte Code:
Code: Alles auswählen
procedure TForm3.ButtonStartClick(Sender: TObject);
var
start : TDateTime;
stringCheck :string;
stringBuyPrice : string;
stringBuyVolume :: string;
buy_id : string;
sold : string;
sell_id : string;
name : string;
SellPrice : string;
floatBuyPrice : double;
floatSellPrice : double;
//for the calculation of the restvolume
floatBuyVolume : double;
floatSellVolume: double;
floatTempVolume : double;
stringTempVolume : string;
sellVolume : string;
begin
stringCheck := '0';
buy_id := EditBuy_ID.Text;
stringBuyPrice := Edit2_ID.Text;
stringBuyVolume := Edit3_ID.Text;
// here is an insert which enters every value for buy data
// now i am looking for the lowest sell price
Form2.SQLQuery3.SQL.Text := 'SELECT price, start FROM sell WHERE price = (SELECT min(price) FROM sell)';
Form2.SQLQuery3.Open;
SellPrice := Form2.SQLQuery3.FieldByName('price').AsString;
floatSellPrice :=StrToFloat(SellPrice);
floatBuyPrice := StrToFloat(stringBuyPrice);
floatBuyVolume:= StrToFloat(stringBuyVolume);
// Start := Form2.SQLQuery1.FieldByName('start').AsString;
// as long as Sell Price reaches Buy Price, can be the same
While ((floatSellPrice <= floatBuyPrice ) OR (stringCheck < '1'))
DO
BEGIN
// I collect the data which belongs to the lowest price, i have to do this every loop again, because the price is getting higher 0.1 after every loop
Form2.SQLQuery1.SQL.Text := 'SELECT * from sell WHERE price ='''+SellPrice+''';';
Form2.SQLQuery1.Open;
SellPrice := Form2.SQLQuery1.FieldByName('price').AsString;
floatSellPrice :=StrToFloat(SellPrice);
sell_id := Form2.SQLQuery1.FieldByName('id').AsString;
name := Form2.SQLQuery1.FieldByName('name').AsString;
sellVolume := Form2.SQLQuery1.FieldByName('volume').AsString;
floatSellVolume:= StrToFloat(sellVolume);
sold := Form2.SQLQuery1.FieldByName('sold').AsString;
// Buyprice is higher or the same than sell price and buy volume is higher than sell volume; sold a checkpoint for the sells, it has to be unequal 1
IF ((floatSellPrice <= floatBuyPrice) AND (stringCheck = '0') AND (floatBuyVolume > floatSellVolume) (sold <>1))
THEN
BEGIN
floatTempVolume := floatBuyVolume - floatSellVolume;
stringTempVolume :=FloatToStr(floatTempVolume);
Form2.SQLQuery1.SQL.Text := 'INSERT INTO table 2 (id, price,volume) VALUE ('''+sell_id+''','''+name+''','''+stringTempVolume+''');';
Form2.SQLQuery2.SQL.Text := 'Update buy SET check = "1", date = current_timestamp WHERE buy_id ='''+buy_ID+''';';
Form2.SQLQuery3.SQL.Text := 'Update sell SET sold ="1", date = current_timestamp WHERE id = '''+sell_id+''';';
stringCheck:= '1';
Form2.SQLQuery1.ExecSQL;
Form2.SQLQuery2.ExecSQL;
Form2.SQLQuery3.ExecSQL;
Form2.SQLTransaction1.Commit;
END
ELSE
BEGIN
floatSellPrice := floatSellPrice + 0.1;
SellPrice:=FloatToStr(floatSellPrice)
END
end;
Form2.SQLQuery2.SQL.Text := 'Update buy SET check = "1" WHERE buy_id ='''buy_id+''';';
stringCheck:= '1';
Form2.SQLQuery2.ExecSQL;
Form2.SQLTransaction1.Commit;
Form2.SQLQuery1.Close;
Form2.SQLQuery2.Close;
Form2.SQLQuery3.Close;
end
end;
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: While Schleife
Vermutlich macht das Programm genau das, was du ihm sagst. 
Versuche doch generell KEIN string für die Preis-Variablen zu verwenden!
Wie sind eigentlich die Preis-Felder in der Datenbank definiert?
Des weiteren: wie ist die Datenbank kodiert? Passt dies zur Einstellung in deinem Programm (Dezimalkomma etc)?
Mir erschließt sich nicht wirklich, was du da machen möchtest.
Wäre das nicht auch mit SQL ohne Programm schon möglich ...

Versuche doch generell KEIN string für die Preis-Variablen zu verwenden!
Wie sind eigentlich die Preis-Felder in der Datenbank definiert?
Des weiteren: wie ist die Datenbank kodiert? Passt dies zur Einstellung in deinem Programm (Dezimalkomma etc)?
Mir erschließt sich nicht wirklich, was du da machen möchtest.
Wäre das nicht auch mit SQL ohne Programm schon möglich ...
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
-
- Beiträge: 37
- Registriert: So 31. Mai 2020, 21:13
Re: While Schleife
in der DB und in meinem programm sind die Preise jetzt double.
Zuletzt geändert von Daniel_Berlin am Sa 13. Jun 2020, 17:49, insgesamt 1-mal geändert.
- h-elsner
- Lazarusforum e. V.
- Beiträge: 281
- Registriert: Di 24. Jul 2012, 15:42
- OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
- CPU-Target: X86-64; arm 32bit
- Wohnort: Illertissen
- Kontaktdaten:
Re: While Schleife
In deinem Codebeispiel oben ist irgendwie ein 'end' zuviel drin. Ich verstehe nicht, wie das kompliliert werden kann. Wenn doch fehlt in einer anderen prozedur ein 'end' und die ganze Funktionalität wird kaputt gemacht.
Für StringCheck würde ich eine boolean Variable nehmen und nicht einen string. Das aber nur am Rande.
Am Ende wird StringCheck auf '1' gesetzt. Wozu? Es kann nie wieder benutzt werden, weil es eine lokale Variable ist. Wenn du den Zustand irgendwie weiter verwenden willst, geht das nicht.
Gruß HE
Für StringCheck würde ich eine boolean Variable nehmen und nicht einen string. Das aber nur am Rande.
Am Ende wird StringCheck auf '1' gesetzt. Wozu? Es kann nie wieder benutzt werden, weil es eine lokale Variable ist. Wenn du den Zustand irgendwie weiter verwenden willst, geht das nicht.
Gruß HE
-
- Beiträge: 37
- Registriert: So 31. Mai 2020, 21:13
Re: While Schleife
stringCheck will ich nicht weiterverwenden, das war nur als zweite Abbruchbedingung gedacht, aber an dieser eigentlich nicht mehr notwendig, da stringCHeck erst nach Ende der Schleife, wenn keine IF Else greifen auf 1 gesetzt wird.
-
- Lazarusforum e. V.
- Beiträge: 559
- Registriert: So 10. Sep 2006, 23:24
- OS, Lazarus, FPC: Linux Mint 22; Lazarus 3.4 FPC 3.2.2; RaspiOS
- CPU-Target: AMD 64, ARM 64
- Wohnort: nr Stuttgart
Re: While Schleife
Mich beisst der doppelte Doppelpunkt:
Code: Alles auswählen
stringBuyVolume :: string;
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS
-
- Beiträge: 475
- Registriert: Do 15. Nov 2007, 16:58
- OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
- CPU-Target: i386, x64
- Wohnort: Gera
Re: While Schleife
Hi,
wenn ich das richtig sehe, sind in dem Codbeispiel sogar 3 end zu viel. Bei einigen fehlt ein ";". Um so etwas zu finden empfiehlt es sich, sich strickt an die korrekte Einrückung zu halten. Nicht böse gemeint, sondern als Tipp.
Und statt der 3 Hochkommas würde ich QuotedStr() benutzen.
In der While-Schleife müssten die Bedingungen mit and statt or verbunden werden oder denke ich gerade falsch? Aber die 2.Bedingung wolltest du ja eh rausnehmen...
wenn ich das richtig sehe, sind in dem Codbeispiel sogar 3 end zu viel. Bei einigen fehlt ein ";". Um so etwas zu finden empfiehlt es sich, sich strickt an die korrekte Einrückung zu halten. Nicht böse gemeint, sondern als Tipp.
Und statt der 3 Hochkommas würde ich QuotedStr() benutzen.
Code: Alles auswählen
Form2.SQLQuery2.SQL.Text := 'Update buy SET check = "1" WHERE buy_id =' + QuotedStr(buy_id) + ';';
mfg Ingo