Angenommene Werte einer Variablen in einer For-Schleife

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von wechda.

    Angenommene Werte einer Variablen in einer For-Schleife

    Hallo Leute,

    ich bin ganz neu hier im Forum und diesbezüglich, als auch auf VB bezogen ein völliger blutiger Anfänger.
    Ich hoffe daher, dass ich nicht gleich alles falsch mache und jedes Fettnäpfchen mitnehme ^^

    Ich beginne mal direkt mit meiner Problemstellung; dafür zuerst mal den relevanten Ausschnitt vom Code:
    --------------
    For i = 0 To Form1.k
    If RadioButton1.Checked Then
    x = 50 + i * 5
    y = 350 - Form1.phi_werte(i) * 90
    ---------------
    Die Schleife läuft immer weiter und stoppt erst, wenn ich einen entsprechenden Button anklicke.
    Ich hoffe der kleine Ausschnitt genügt, um mein Problem kurz zu verdeutlichen.

    Im Rahmen der Berechnung in dieser For-Schleife nimmt die Variable y fortlaufend unterschiedlichen Werte an. Diese Werte werden halt schrittweise neu berechnet.
    Ich würde nun gern fortlaufend die aktuell letzten 5 von y angenommenen Werte "abgreifen", um diese dann aufzusummieren.

    Ist das möglich?
    Wenn ja, gibt es da einen direkten Weg? (so nach dem Motto: a = y(Schritt -1) + y(Schritt -2) + ... + y(Schritt -5) ?)
    Oder müssten dazu die angenommenen Werte in irgendeiner Weise zunächst "mitgeschrieben" werden, (z.Bsp. in einer TextBox oder der Gleichen) um diese dann irgendwie daher zu entnehmen?

    Ich habe diesbezüglich auch im Forum und allgemein im Internet gesucht, bin jedoch nicht fündig geworden. Das könnte daran liegen, dass ich gar nicht so recht weiß, was ich überhaupt als Suchbegriffe eingeben soll.. Also nehmt es mir bitte nicht übel, falls das Problem so ähnlich schon vorkam und gelöst wurde. Das war dann wirklich keine böse Absicht oder Faulheit :)

    Falls mir da jemand weiterhelfen könnte, wäre das absolut großartig! :thumbsup:
    Willkommen im Forum.

    Mach Dir eine List(Of Double) und speichere da alle y-Werte drin, indem Du mit DeineListe.Prepend(NeuerYWert) arbeitest und so immer am Anfang der List den aktuellen/neuen y-Wert hinzufügst. Dann kannst Du danach mit DeineListe.Take(5) die neuesten 5 Werte hernehmen und summieren. Alternativ normal mit DeineListe.Append(NeuerYWert) arbeiten (also die neuen y-Werte ans Ende der Liste anfügen) und dann entweder die Liste per Reverse umdrehen und wieder mit Take arbeiten oder Du nimmst DeineListe.Skip(DeineListe.Count - 5) und erhältst so die neuesten 5 y-Werte (die ja eben dank Append am Ende der Liste stehen). Das Summieren geht ebenfalls mit LINQ (Sum). Du erhältst dann also als Auswertungsfunktion DeineGewünschteSumme = DeineListe.Skip(DeineListe.Count - 5).Sum

    btw: To Form1.k und Form1.phi sind Vorboten für diese Lektüre:
    Dialoge richtig instanziieren
    Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen
    und
    bitte CodeTags verwenden
    und

    wechda schrieb:

    in irgendeiner Weise zunächst "mitgeschrieben" werden, (z.Bsp. in einer TextBox
    CEs wie eine TextBox sind zur Anzeige/Bearbeitung von Werten da, nicht zum Speichern derselbigen. Dafür gibt es Variablen (wie die o.g. List)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Zunächst mal vielen lieben Dank für diese super zeitnahe Antwort!
    Ich muss zugeben, dass ich jedoch nicht so recht weiß, wie das nun explizit als Quellcode auszusehen hat.

    Könntest du mir das vielleicht auch noch einmal "vortippen"?

    Quasi wie die Eingaben dann aussehen? Also diese Liste erstellen und deklarieren, dann umdrehen, dann take(5) usw...
    Also ich verstehe zwar, was du meinst und es klingt auch sehr logisch, aber wüsste nun leider nicht, wie ich das im Detail eingeben müsste.
    Die Befehle sind mir völlig fremd..Anfänger halt..keinen Plan, dafür aber jede Menge Ahnungslosigkeit! ?(
    ^^

    VaporiZed schrieb:

    Mach Dir eine List(Of Double)

    VB.NET-Quellcode

    1. Dim DeineListe = New List(Of Double)

    VaporiZed schrieb:

    und speichere da alle y-Werte drin, indem Du mit DeineListe.Prepend(NeuerYWert) arbeitest

    VB.NET-Quellcode

    1. For i = 0 To Form1.k
    2. If RadioButton1.Checked Then
    3. x = 50 + i * 5
    4. y = 350 - Form1.phi_werte(i) * 90
    5. DeineListe.Prepend(y)

    Den Rest kriegst Du selber hin. Schließlich sind alle Begriffe, die interne Forensuche und Internetsuchmaschinen vorhanden. Stichwort Eigenrecherche.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich hab jetzt beide Wege ausprobiert und erhalte leider stets 0 als "Summe".
    Ich habe die Liste1 im übergeordneten Sub erstellt und erhalte auch keine Fehlermeldung, daher sollte da das Problem nicht herrühren.

    VB.NET-Quellcode

    1. Dim Liste1 = New List(Of Double)


    Die folgenden Eingaben entsprechen meinem letzten, vermutlich 10. Versuch ?(

    VB.NET-Quellcode

    1. For i = 0 To Form1.k
    2. If RadioButton1.Checked Then
    3. Dim a As Decimal
    4. Dim ListenSumme As Decimal
    5. x = 50 + i * 5
    6. y = 350 - Form1.phi_werte(i) * 90
    7. Liste1.Append(y)
    8. Liste1.Skip(Liste1.Count - 5)
    9. ListenSumme = Liste1.Skip(Liste1.Count - 5).Sum
    10. TextBox2.Text = ListenSumme
    11. TextBox1.Text = y


    Die Textboxen habe ich eingefügt um die Werte visuell kontrollieren zu können,,,so schnell kann man natürlich gar nicht gucken, aber man sieht immerhin, ob überhaupt Werte kommen und wie groß diese in etwa sind,,,ob diese Schwanken usw.. Während sich die einzelnen Werte von y im hoch-stelligen Bereich bewegen, habe ich für die ListenSumme von y immer einen Wert von glatt 0, egal auf welchem Wege es nun versucht habe nach Anleitung umzusetzen. Irgendwas muss ich wohl missverstanden haben, sodass für die Liste Werte gesammelt werden, die 0 sind? oder greife ich irgendwie doch an der falschen Stelle ab?

    Der Plan ist ja, dass ich immer die aktuelle Summe der derzeitig 5 letzten Werte von y erhalte. Also so, dass die Summe zwar nicht immer weiter wächst, aber eben schon definitiv nicht 0 sein kann, wenn die einzelnen Werte bereits hoch im positiven Bereich liegen..
    Ich habe wohl etwas nicht richtig verstanden oder vergessen, aber ich komm nicht drauf..

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „wechda“ ()

    Liste.Skip() gibt eine Teilliste wieder. Zeile#9 hat bei Dir also gar keinen Effekt. Folgendes hätte einen Effekt:

    VB.NET-Quellcode

    1. DeineLetzten5Einträge = Liste1.Skip(Liste1.Count - 5)


    Diese Schleife wird doch bestimmt nicht dauerhaft aufgerufen, sondern auf Wunsch, richtig?
    Daher dürfte das hier wohl klappen:

    VB.NET-Quellcode

    1. For i = 0 To Form1.k
    2. If RadioButton1.Checked Then
    3. Dim a As Decimal
    4. Dim ListenSumme As Decimal
    5. x = 50 + i * 5
    6. y = 350 - Form1.phi_werte(i) * 90
    7. Liste1.Append(y)
    8. '...
    9. End If
    10. Next
    11. ListenSumme = Liste1.Skip(Liste1.Count - 5).Sum
    12. TextBox2.Text = ListenSumme

    In einer Schleife kannst Du nicht sinnvollerweise eine TextBox aktualisieren. Die Schleife ist 1. so schnell durch, dass Du Änderungen nicht sehen würdest. Zum anderen wie die aktualisierte Anzeige für die TextBox erst durchgeführt, wenn die Schleife durch ist, also die CPU dafür Zeit hat.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Die Schleife läuft tatsächlich dauerhaft bis ich einen entsprechend eingefügten ClickButton anklicke.

    Es wird hierbei eine reibungslose Schwingung ausgeführt. Ich könnte das Programm also starten und drei Tage später liefe es samt der gezeigten Schleife noch immer.

    Bedeutet das für diesen Fall, dass es dann so nicht funktionieren kann?
    Ich teste es jedenfalls dennoch einmal :)

    EDIT:
    Getestet, klappt leider nicht :(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „wechda“ ()

    @wechda Poste mal ein bereinigtes (ohne bin, obj u.ä. Verzerichnisse) und gezipptes Testprojekt, das Deinen Effekt reproduziert.
    Nutze die Datei-Anhangs-Funktionalität des Forums:
    Erweiterte Antwort => Dateianhänge => Hochladen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das darf ich leider nicht machen :(
    Teile des Codes stammen nicht aus meiner Feder und das Programm ist tatsächlich sehr groß und hat viele Funktionen, die teilweise nichts mit meiner Problemstellung zu schaffen haben. Soll heißen, dass das Programm in Zusammenarbeit entstanden ist und ich somit nur den Anteil zeigen kann, den ich alleine geschrieben habe und das ist eben bei weitem nicht das gesamte Programm.

    Selbst wenn ich versuchen würde den entsprechenden Teil quasi gesondert rauszupicken, würde das etliche Stunden dauern und ich wüsste nicht, ob es am Ende überhaupt funktioniert.

    Im Kern berechnet Programm Schwingungen und kann diese auch darstellen. Die Variable beschreibt den Weg der Schwingungsamplitude, bzw. Auslenkung. Je größer der Wert, den y angenommen hat, des größer ist die momentane Auslenkung. Der Wert wird also immer größer bis zur maximalen Auslenkung, dann ändert sich die Richtung, wie bei Schwingungen so üblich. (hin und her oder hoch und runter, wie ein springender Flummi)

    Ich geh nun aber mal davon aus, dass es nicht ohne Weiteres möglich ist die Summe oder besser die betragsmäßige Summe(Math.abs)
    der immer aktuell 5 letzten angenommenen Werte einer Variable in z.B. einem Label auszugeben. Zumindest wohl nicht, wenn es um eine Schleife geht, welche stetig fortlaufend ist.

    Ich möchte mich aber trotzdem nochmals für die Hilfe bedanken. Das sehe ich natürlich nicht als selbstverständlich an! :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „wechda“ ()

    @wechda Du sollst doch nicht Dein vollständiges Projekt posten, sondern "nur" ein kleines Testprojekt, das Deinen Effekt reproduziert.
    Du postest bis jetzt nur Auszüge aus Prozeduren, das ist einfach zu wenig.
    Probier einfach mal, diese Klasse zu extrahieren, und allen "Sekundärcode" rauszuschmeißen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wie häufig kommen neue Werte von außen in Deine App und wie schnell wird die For-Schleife einmal durchlaufen?
    Eine Möglichkeit wäre, das Ganze nebenläufig zu gestalten, sodass das Label eben alle 1, 5 10, whatever Sekunden nur aktualisiert wird. Denn was bringt es einem, wenn das Teil im Millisekundenabstand einen neuen Wert anzeigt?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Danke zunächst für die weiteren Rückfragen. Das Programm erstreckt sich über mehrere Forms, wobei die relevante Berechnung in einer Schleife 10 Werte je Sekunde berechnet.
    Die aktuellen letzten 5 Werte sind mir daher so wichtig, da ich beim Abklinken der Schwingung ab einem bestimmten Wert die Darstellung unter anderem verändern möchte. Hier kann ich nun jedoch nicht eingeben, dass dies bei einem bestimmten y-Werte geschehen soll.
    Z.Bsp:

    VB.NET-Quellcode

    1. If y < 10 Then
    2. ....
    3. End If


    Denn es handelt sich eben um eine Schwingung und die Variable y nimmt regelmäßig den Wert 0 an, auch ohne, dass die Schwingung kleiner wurde. Sie schwingt quasi bei jeder Schwingung über 0. Wie ein Flummi, der zu Boden fällt. Wenn er gerade unten ist, wäre die Variable y = 0 und 0.1 Sekunden Später wäre er wieder 10 cm über dem Boden und weitere 0,1 Sekunden noch weitere 9 cm höher über dem Boden. Nach einigen Sprüngen jedoch würde er nur noch minimale "Hopser" machen. Man könnte sich nun also Vorstellen, dass sich die Darstellung ändern soll, wenn sein Sprung, der anfangs 100 cm Höhe hatte anders dargestellt werden soll, wenn die Höhe keine 10 cm mehr überschreitet.

    Mein Ansatz war dabei eine bestimmte Anzahl der letzten angenommenen Werte zu betrachten.
    Wenn diese dann in der betragsmäßigen Summe < 15 cm ist, soll sich die Darstellung ändern. (Das muss nicht ganz genau sein)
    Ich schreibe also in die Berechnung am Ende z.B: "*h" :

    VB.NET-Quellcode

    1. Dim h As Decimal
    2. h = 1
    3. If AbsSummeYWerte < 15 AndAlso Check.Boxh.Checked = True Then
    4. h = 10
    5. End If
    6. If RadioButton2.Checked Then
    7. x = 50 + i * 5
    8. y = 350 - Form1.phi_werte(i) * 30 *h


    So ungefähr wäre da mein Plan. Die zusätzlich eingeführte Variable h wäre zunächst 1 und würde in der Berechnung nichts ändern. Wird die Schwingung jedoch so Schwach, dass AbsSummeYWerte unter 15 ist, so ändert sich unter anderem die Variable h in den Wert 10 und die Restschwingung wird verstärkt. Ich würde es jetzt nicht exakt so machen, sondern mich auf eine Berechnung in einer anderen Form beziehen, aber im Grunde ist das die Idee dahinter.

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „wechda“ ()

    wechda schrieb:

    die Variable y nimmt regelmäßig den Wert 0 an
    Gedämpfte periodische Schwingung oder so?
    Du musst das Maximum finden, und wenn das Maximum kleiner als yMax ist, wird die "optische Vergrößerung" (die Darstellungs-Skalierung in y-Richtung) entsprechend vergrößert.
    Dies sollte eine reine Darstellungs-Option sein, die mit Deiner Berechnung nichts zu tun haben sollte!
    Du stellst in der Berechnung das jeweils letzte Maximum bereit.
    Der Darstellungsteil wertet das aus und stellt den y-Skalierungsfaktor entsprechend ein.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jap, "gedämpfte Schwingung" ist ein sehr gutes Stichwort!

    Das klingt nach einer guten Idee, wie jedoch Werte ich das Maximum ohne die Berechnung und die angenommenen Werte von y zu betrachten?
    ?(
    Da fehlt mir leider auch das Wissen, wie das umgesetzt werden kann.. Ich arbeite erst seit Kurzem mit VB..
    Lässt sich das irgendwie auf simple Weise zeigen, so dass ich das einmal probieren kann?

    Das mit der "AbsSumme_y_Werte" ist keine so gute Idee, oder lässt sich so nicht umsetzen?
    @wechda Also:
    Start, wenn der Körper nach Reflexion die Richtung wechselt: yMax = 0.
    Vergleiche zu jedem neuen Zeitpunkt den neuen berechneten y-Wert mit yMax. Ist er größer, wird dies der neue yMax-Wert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hmm, nun springt der Flummi 100 cm hoch und y ist somit 100. yMax ist dann ebenfalls 100. Dann lässt die Energie nach und der Flummi springt beim nächsten mal noch 90cm hoch, danach nur noch 80 cm, ... , 10cm und yMax ist dann weiterhin bei 100 cm.

    yMax kann ich nun nicht einfach für y einsetzen, da jeder Punkt, der für y berechnet wird auch grafisch dargestellt wird. Würde ich das also machen, hätte ich alle Punkte der Schwingung auf der Höhe von yMax, also bei 100 und hätte damit eine Gerade und keine Schwingung mehr.

    Vielleicht habe ich das aber einfach falsch verstanden :S

    Also muss meine Frage nun vielleicht lauten, was mache ich dann mit dem yMax?
    Oder andernfalls, wie komme ich an das "jeweils letzte Maximum" von y?
    Wenn das ginge, würde es sicher klappen.


    EDIT:

    Ich habe jetzt eine Art "Drumherum-Lösung" gefunden, welche mich zunächst auch recht zufrieden stimmt. Da ich die Problemstellung hier ja eröffnet habe, will ich meine Problemlösung kurz erläutern:

    Ich habe mir einen weiteren RadioButton und eine VScrollBar aus der ToolBox geholt und eine Variable o eingeführt, welche sich abhängig vom Value der Scrollbar ändert.
    Als Quellcode sieht das dann in etwa wie folgt aus:

    VB.NET-Quellcode

    1. Dim o As Decimal
    2. For i = 0 To Form1.k
    3. ' Skalierung mittels VScrollBar:
    4. If RadioButton4.Checked Then
    5. o = VScrollBar1.Value * 0.1
    6. x = 50 + i * 5
    7. y = 350 - Form1.phi_werte(i) * 15 * o

    "powered by RQ" (Falls mein Prof das zufällig sieht, erkennt er an meinen Initialen hoffentlich, dass ich es nicht einfach abgekupfert habe ^.^)7

    Die ScrollBar hat dann in seinen Eigenschaften sinnvolle Minimal- und Maximalwerte erhalten, als auch ein sinnvolles "Startvalue".
    Wenn ich nun den RadioButton4 auswähle, kann ich mittels Scrollbar die Variable o in seiner Größe ändern. Da diese am Ende meiner Berechnung aufmultipliert wird, ändern sich so auch entsprechend die von y angenommen Werte.

    Mit dieser Lösung bin ich erstmal ganz zufrieden.
    Rein aus Interesse und für den späteren etwaigen Bedarf würde mich natürlich dennoch interessieren, wie man an eine bestimmte Anzahl von zuletzt angenommen Variablen-Werte kommt.

    Und nochmals Danke für die Hilfsbereitschaft, echt super von euch! :thumbsup:

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „wechda“ ()

    wechda schrieb:

    und yMax ist dann weiterhin bei 100 cm.
    Nö:

    RodFromGermany schrieb:

    Start, wenn der Körper nach Reflexion die Richtung wechselt: yMax = 0.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Dann würde yMax doch immer die Werte von y annehmen bis y wieder kleiner wird und auf 0 abfällt. Anschließend würde yMax wieder alle Werte von 0 an von y annehmen bis y wieder bei seiner maximalen Auslenkung wäre.
    Das bedeutet doch, das yMax immer wieder 0 wäre und dann mit y "mitwachsen" würde bis y wieder kleiner wird und jedes mal wenn y=0 erreicht würde sich das wiederholen. Also wenn y kleiner wird bleibt yMax bei der letzten maximalen Auslenkung von y und wenn y=0 wird geht das Spielchen von vorne los.
    Was würde mir das bringen und was könnte ich damit anfangen? ?(

    wechda schrieb:

    Dann würde
    Lesen bildet.

    RodFromGermany schrieb:

    Ist er größer, wird dies der neue yMax-Wert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!