An die Mathematiker

  • Hallo zusammen,

    ich habe mir eine Abfrage zusammengeschrieben, die soweit auch erstmal funzt. Jedoch ist der Code ziemlich lang, und ich denke da ist noch potenziel.

    Beim durchlaufen einer For - Next Schleife würde ich gern durch eine Formel folgende Zähler umsetzen

    Durchlauf von $i von 1 bis 120,
    dann als Zweiten Zähler immer 1 bis 4
    und als dritten Zähler nach jeder 4 Gruppe eins weiter

    Fürs Verständnis eine kleines Zahlenbeispiel
    1 | 1 | 2
    2 | 2 | 2
    3 | 3 | 2
    4 | 4 | 2
    5 | 1 | 3
    6 | 2 | 3
    7 | 3 | 3
    8 | 4 | 3
    9 | 1 | 4
    10 | 2 | 4
    11 | 3 | 4
    12 | 4 | 4
    13 | 1 | 5
    14 | 2 | 5
    15 | 3 | 5
    16 | 4 | 5

    so sieht der Code bis jetzt aus

    Spoiler anzeigen


    ich hatte zwar schon mal eine entsprechende Formel hier im Forum gesehen, kann sie leider aber nicht mehr finden und das beim selbst zusammenbauen bin ich bis jetzt leider kläglich gescheitert.

    Wie kann man eine solche Anforderung am besten umsetzen?
    Für Denkanstöße wäre ich sehr dankbar.

    Viele Grüße Jens

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • So müsste es hinhauen:

    AutoIt
    For $x = 1 To 120
    	ConsoleWrite($x & " | " & ((Mod($x, 4) = 0) ? 4 : Mod($x, 4)) & " | " & Ceiling($x / 4)+1 & @CRLF)
    Next


    Yaerox: Dein Code gibt nicht einmal die Tabelle oben aus - die erste Spalte stimmt bei dir nicht ;)

    Spoiler anzeigen

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

    Einmal editiert, zuletzt von Runa (4. April 2016 um 13:04)

  • Passiert uns allen mal: Ich selbst habe gerade wieder Mal meine Migräne und code dafür deutlich schneller ohne das die Qualität merklich leidet. Hat auch was.

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • Hey danke, das funzt.

    Jedoch verstehe ich es noch nicht ganz.

    Und zwar der mittlere Teil erschließt sich mir noch nicht ganz.
    Das Mod ist eine Division, soweit klar. Aber was ist mit dem Fragezeichen und dann nochmal Mod wieso???
    Ich würde das gern nachvolziehen können um etwas dazuzulernen, und beim nächsten mal nicht wieder fragen zu müssen.

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Nehmen wir es auseinander:

    Teil 1:
    $x dürfte klar sein: Zählt einfach nur nach 120 hoch von 1 aus.

    Teil 2:
    ((Mod($x, 4) = 0) ? 4 : Mod($x, 4)) - das ist ein konditioneller Operator. In den Klammern wird - abhängig von einer Bedingung - ein Wert eingesetzt.

    Bedingung: Mod($x, 4) = 0

    Falls ja: Gib 4 aus
    Falls nein: Gib Mod($x, 4) aus

    Hintergrund des Ganzen: Die Zahlenreihe gibt uns als Modular für jede Zahl genau vier Werte: 1, 2, 3 und 0. Du wolltest allerdings 1, 2, 3 und 4. Demnach muss die 0 durch eine 4 ersetzt werden. Genau das macht dieser konditionelle Operator. Kennst du vielleicht aus Excel, Access oder dergleichen. =WENN(Bedingung;Dann;Sonst) - das ist das gleiche Prinzip.

    Teil3:
    Ceiling($x / 4)+1 - Wir teilen X durch 4, runden das auf, und rechnen eins drauf.

    Hintergrund: Wir möchten nur alle 4 Schritte um eines hoch zählen. Bedeutet, jeder Schritt muss um 0,25 erhöhen, während der Wert stabil bleibt. Dazu lassen wir immer aufrunden.

    Dadurch ergibt sich für die ersten vier Schritte (0.25, 0.50, 0.75 und 1.00) immer 1. Da du dort mit einer zwei beginnen wolltest, wird noch einmal eins draufgerechnet.


    Ich hoffe, meine Erklärungen sind verständlich, ansonsten nochmal nachfragen :)

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • @Andy da hebn wir übrigens deinen Liebling, den ternären Operator, mal im Einsatz.
    Du musst doch zugeben: Der Code wächst nicht groß vertikal und ist trotzdem lesbar :D

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Und zwar der mittlere Teil erschließt sich mir noch nicht ganz.
    Das Mod ist eine Division, soweit klar. Aber was ist mit dem Fragezeichen und dann nochmal Mod wieso???

    @Xorinator, das war ja wohl ein klassisches Eigentor....
    Viel schlimmer kann man es nicht machen :thumbdown:

    Der TE fragt nach einer MATHEMATISCHEN Lösung, bekommst stattdessen einige kryptische Zeilen hingeworfen, um auf Nachfrage innerhalb einer halben Seite Text die Erklärung einer simplen IF-Abfrage (etwas anderes ist das "Fragezeichen" nämlich nicht) erklärt zu bekommen. Thema verfehlt, 6, setzen....

    Und jetzt verstehst du hoffentlich, wieso ich dieses "Gedöns" zumindest bei Anfängern ablehne! Der Lerneffekt ist nämlich gleich null, gerade im Gegenteil, beim nächsten Problem in 6 Wochen ist entweder alles vergessen. mal abgesehen davon, dass der "mathematische" Ansatz wesentlich einfacher ist und ohne Vergleich auskommt.

    Denn wie man die "mathematische" Lösung entwickelt, ist eingängig! Listen and learn:

    MOD($i,4) ergibt eine Reihe:
    $i MOD
    1 1
    2 2
    3 3
    4 0
    5 1
    6 2
    7 3
    8 0
    9 1 soweit klar?!
    dann ist lediglich die 0 durch eine 4 zu ersetzen.
    Wenn m=0, dann 4....schreibt man mathematisch (m=0)*4 , ausgeschrieben (mod($i,4)=0)*4

    Code
    For $i = 1 To 15
        ConsoleWrite($i & "    " & Mod($i, 4) + 4 * (Mod($i, 4) = 0) & @CRLF)
    Next

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (6. April 2016 um 15:26)

  • Ich schaute mir die Lösung von ihr nicht näher an, daher wollte ich darüber keine Aussage treffen.
    Von der Warte der Erklärung her hast du absolut Recht, ich bin allerdings nach wie vor überzeugt davon, dass man das als Nicht-Anfänger sehr sinnvoll verwenden kann :)

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Zitat von Xorianator

    Von der Warte der Erklärung her hast du absolut Recht, ich bin allerdings nach wie vor überzeugt davon, dass man das als Nicht-Anfänger sehr sinnvoll verwenden kann

    Ich wiederhole an dieser Stelle:
    Eines der älteren Mitglieder (Mitglied seit: Mai 2008) dieses Forums als Anfänger zu betiteln, oder ihm dies zu unterstellen ist wohl das "Eigentor" von dem Andy schreibt... ich tue dies nicht. Wie an anderer Stelle bereits erwähnt betrachte ich kurz das Profil des Nutzers, auf dessen Thread ich antworte. Eine Sache, die zu weniger herablassendem Verhalten gegenüber Altmitgliedern führt.

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • 8 Jahre schon hier, alter Schwede. Ne aber mal im Ernst, Leute - nicht so aufschäumen. Ein netter Umgangston hat noch keiner Diskussion geschadet.

    Erstmal, mir ist super geholfen wurden, wie immer! Durch den Denkanstoß konnte ich meinen Code anpassen, so dass er jetzt das macht was ich wollte.

    Es liegt doch in der Natur der Dinge, dass es nicht nur einen Weg nach Rom gibt, also auch hier.

    Für den Lerneffekt ist es doch gut weitere Ansätze zu bekommen, außerdem kommt man dann sogar noch tiefer in das Thema.

    Warum habe ich mich an die Mathematiker gewannt, weil es meiner Meinung nach eine Mathematische Formel ist, die zur Lösung meines Problems von Nöten war.
    Und wenn ich jetzt in der Hilfe lese Modulo-Rechnung, Dividend und Divisor dann sind das doch Mathematische Aspekte, oder?

    Also zu Abschluss, danke für die Hilfe von allen!

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Ich wiederhole an dieser Stelle:
    Eines der älteren Mitglieder (Mitglied seit: Mai 2008) dieses Forums als Anfänger zu betiteln, oder ihm dies zu unterstellen ist wohl das "Eigentor" von dem Andy schreibt... ich tue dies nicht. Wie an anderer Stelle bereits erwähnt betrachte ich kurz das Profil des Nutzers, auf dessen Thread ich antworte. Eine Sache, die zu weniger herablassendem Verhalten gegenüber Altmitgliedern führt.

    Naja, viel dümmer konnte es für dich ja nicht kommen...Ins Nutzerprofil geguckt und nicht festgestellt, dass der übrigens von mir ob seiner Ausdrucks- und Frageweise sehr geschätzte Nutzer im letzten Jahr nichtmal eine Handvoll Posts erstellt hat, übrigens einer davon behandelte genau DEIN Thema, Pfad-Funktion mit Struktur
    Das "Fragezeichen" wurde damals schon nicht verstanden....soviel zu "herablassend"...ich hatte den damaligen Thread nämlich noch im Hinterkopf, bin zwar alt, aber (hoffentlich) noch nicht senil :rolleyes:
    Und überleg dir mal zum Thema "herablassend" wie man es nennt, im Wissen um die programmiertechnischen Fähigkeiten des Fragestellers einen Code zu posten nur um diesen dann auf Nachfrage "erklären zu müssen". Würde man dich nicht so gut kennen könnte man davon ausgehen, dass du dieses in voller Absicht gemacht hast, um in einem weiteren Post dein überragendes KnowHow zur Schau zu stellen. Gib bei google mal "Profilneurose" ein....

    Und btw., "Anfänger" werden in deinem Freizeitbereich (Ballerspiele) verunglimpft, genau wie in deiner Botter-Community. Aber wir befinden uns nicht dort, auch nicht auf diesem Niveau. Ein "Anfänger" wird hier genauso höflich und zuvorkommend behandelt, wie er sich uns gegenüber benimmt. Interessant dazu deine Wortwahl, ich würde den TE "als Anfänger betiteln, oder ihm dies zu unterstellen". Ausdrücke und Vergleiche, die ich jetzt auch mal dem Ballerspiele-Niveau zuordne.....
    Entgegen deinem Empfinden ist ein Anfänger kein Abschaum der Menschheit! Auch wenn das in deiner Ballerspiel+Botter-Community ganz anders gesehen und auch betitelt wird.
    Ein Anfänger ist für mich völlig wertfrei jemand, der sich mit der Materie nicht vollumfänglich auskennt. Im Gegensatz zum Profi, von dem ich professionelles Verhalten einfach erwarte und voraussetze. Und den ich dementsprechend angehen kann! Aber darüber brauchst du dir keinerlei Gedanken zu machen, ich halte dich nicht für einen Profi, nicht mal ansatzweise. Siehe meine ersten Sätze in diesem Post, einem Profi wäre so etwas definitiv nicht passiert! Und selbst wenn, hätte er es spätestens bei der Themennachlese gemerkt, den Post gelöscht mit der Begründung "selfowned :o)" . Thema erledigt, vom Establishment akzeptiert, basta! Separates the boys from the men.

    Du musst hier im Forum auch nicht den Progamer und AutoIt-Spezialisten raushängen lassen, die Poweruser wissen sowieso, aus welcher Ecke du hierher ins Forum gekommen bist. Von den profilneurotischen Namens- und Account-Spielchen mal ganz abgesehen.

    Übrigens war der Aufhänger für mich, überhaupt hier im Thread zu posten der Beitrag von Xorinator und somit auch der Bezug zum "Eigentor", den du infolge völliger Unwissenheit auch nicht verstanden hast aber auf den du infolge Profilneurose anspringen musstest. Xorinator und ich hatten uns genau zum Thema ? (Fragezeichen) bei einem gemütlichen Beisammensein am Grill sehr intensiv ausgetauscht. Ich denke für uns beide war das trotz gegenteiliger Standpunkte sehr positiv! Teil des Gesprächs war übrigens auch das "Verständnis" von gerade diesem Operator. Und dabei ging es nicht um das Nutzen davon an sich, denn derjenige "Programmierer" (Anfänger oder nicht), der diesen Operator nutzt, hat ja verstanden was er tut. Es geht darum, einem Nichtbenutzer klar zu machen, welche Vorteile er dadurch hat. Und dann wird es schwer, denn einen "Vorteil" im Sinne von besserer Lesbarkeit/Verständnis des Codes hat der Anwender definitiv nicht! Ich zitiere dazu mal


    Dieser Operator kann immer durch eine if-Anweisung vermieden werden, kann aber in vereinzelten Situationen klarer sein. Da er anderenfalls eine der zahlreichen Möglichkeiten in C/C++ ist, seine Programme für andere erfolgreich unlesbar zu gestalten, sollte man ihn sparsam einsetzen.

    Wenn schon der Lehrstuhl für die zukünftige Elite der Programmiererzunft empfiehlt, diesen Operator "sparsam" aus o.g. Gründen einzusetzen, dann sollte einem Unkundigen dieses Stück "Technik" besser erspart bleiben.

    Für mich schließt sich hier der Kreis, deine Profilneurose mit Pseudoprofessionalität ergänzen zu wollen. Ein Ternärer Operator ist kein Mittel, einem User weiterhelfen zu wollen! Und "helfen" bezieht sich nicht auf die von dir gewöhnte C&P-Mentalität! Professionell wäre gewesen, ein sauberes

    AutoIt
    $a = Mod($i, 4)          ;ganzzahliger Rest von $i/4
    If $a = 0 Then $a = 4    ; wenn der Rest 0 ist, soll $a=4 sein

    anzubieten und dann wegen mir noch die "ternäre" Version als "ich kenne auch die Kurzversion für Codeobfuscatoren!" mit dem 8o - Smilie!
    Wobei du dann auch erklären müsstest, dass ein ternärer Operator ganz und gar nichts "mathematisches" ist, sondern nur ein simples IF...THEN...ELSE.
    IF...THEN...ELSE ist Basic-like 40 Jahre alter Programmieroldie-Krampf, aber lesbar. Von jedem Programmierer.
    Und zu allem Überfluss löst der Parser das auch noch zum gleichen Code auf wie den ternären Operator.....qed :Face:

  • Ich gebe zu: Ich habe nicht alle seine Threads und Posts vollständig durchgelesen. Dass er diesen Operator bereits erklärt bekommen hat und wieder vergessen hat, war mir somit nicht bewusst.

    Der Rest deines Beitrags sind erbärmliche Beleidigungen, denen ich keine weitere Beachtung schenke. Weder bin ich in der Botter-Community - mal abgesehen davon, dass weder ich noch sie selbst mich in ihrem Forum wollen - noch wirklich in der "Ballerspiele"-Community; an dieser Stelle ignorieren wir mal vollkommen, dass deine Ansichten hierzu wieder weitere Beleidigungen sind.

    Kleine Randbemerkung, wie ich hier her kam, damit auch du es kapierst: Einmal aus besagter Botter-Community, wo ich seit über 3 Jahren nicht einmal mehr einen Account habe, wobei ich hierbei den Account durch einen Admin löschen lies. Danach war ich ausschließlich im Entwicklerforum unterwegs, wo ich es immer noch bin.

    Abschließend: Kein Parser der Welt löst eine Abfrage mit 9 Rechenoperationen und eine Abfrage mit 6 Rechenoperationen zu dem gleichen Code auf - das ist absoluter Unfug.

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • Hier kann das gerne jemand Testen, falls ihr euch streiten wollt.
    Bioshades Methode ist tatsächlich schneller (oh wie überraschend, in AutoIt nicht wirklich).

    Allerdings muss ich dir soweit erstmal widersprechen, was das folgende angeht:

    Kein Parser der Welt löst eine Abfrage mit 9 Rechenoperationen und eine Abfrage mit 6 Rechenoperationen zu dem gleichen Code auf - das ist absoluter Unfug.

    Das Einzige was daran Unfug ist, ist anzunehmen, dass das nicht möglich ist. Das kommt auf den Parser an sich an. Ein guter Parser würde erkennen, dass es sich dabei um ein und die gleichen Befehle / Operationen handelt, und würde entsprechend anpassen. Analog dazu Compiler, welche den Code zu ein und dem Gleichen zusammen fassen würden.

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

    Einmal editiert, zuletzt von Xorianator (9. April 2016 um 09:25)

    • Offizieller Beitrag

    Wenn schon der Lehrstuhl für die zukünftige Elite der Programmiererzunft empfiehlt, diesen Operator "sparsam" aus o.g. Gründen einzusetzen, dann sollte einem Unkundigen dieses Stück "Technik" besser erspart bleiben.

    Das sehe ich etwas differenzierter.
    Was macht einen großen Teil des Programmierens aus? - Das Finden von sich wiederholenden Programmstrukturen und zur Vereinfachung des Codes, das Auslagern dieser Strukturen in Funktionen.
    Nun schaue ich in ein Skript und entdecke 10...20 mal:

    AutoIt
    Local $variable
    If 'Bedingung' Then
    	$variable = 'Wert-WAHR'
    Else
    	$variable = 'Wert-FALSCH'
    EndIf

    Also sage ich mir, pack das in eine Funktion. Gesagt - getan:

    AutoIt
    Func _If_Then_Else($_condition, $_result_true, $_result_false)
    	If $_condition Then
    		Return $_result_true
    	Else
    		Return $_result_false
    	EndIf
    EndFunc

    Und nun sieht der gleiche Programmteil schon viel ansprechender aus und ist nach wie vor gut lesbar:

    AutoIt
    Local $variable = _If_Then_Else('Bedingung', 'Wert-WAHR', 'Wert-FALSCH')


    Und dann kam AutoIt v3.10.x.x mit dem Ternären Operator.

    AutoIt
    Local $variable = 'Bedingung' ? 'Wert-WAHR' : 'Wert-FALSCH'

    Und He! - der tut genau das, was meine Funktion bisher tat! D.h. es ist nicht nur "syntactic sugar", sondern auch das Abbilden einer bisher von Usern selbst erstellten Funktion in einer neuen Syntax.
    Für mich stellen sich beim Verwenden von Funktionen oder Syntax-Elementen in erster Linie folgende Fragen:
    - Kann ich Code damit schlanker gestalten?
    - Ist die Lesbarkeit des Codes gewährleistet?
    Beides kann kann ich hier absolut bejahen. Selbst das Kapseln mehrer Ternärer Operatoren muß nicht die Lesbarkeit beeinträchtigen, wenn man den Code etwas aufteilt.

    Bsp.

    Abschließend noch etwas zur bisherigen Threadführung:
    Meinungsstreit? - Unbedingt: JA!
    Aber: Bitte vermeidet das Abgleiten auf eine persönliche Ebene. Das dient weder der Problemlösung, noch macht es das Lesen des Threads angenehm.

  • Ich würde ganz auf den ternären Operator verzichten und grundsätzlich eins auf result von Mod zählen, ich bin mir noch nicht einmal sicher was schneller abgearbeitet wird, lesbarer ist es für Ungeübte aber auf jeden Fall und schlanker auch:

    Code
    For $x = 1 To 120
    	ConsoleWrite($x & " | " & Mod($x, 4)+1 & " | " & Ceiling($x / 4)+1 & @CRLF)
    Next

    das Ergebnis ist nachweislich identisch, 120 mal die Auswertung des ternären Operators und 90 mal die 2. Mod Auswertung gespart, dafür 120 zusätzlich Additionen.

    [OT]Die Perversion im Schreiben von Einzeilern habe ich auf dem C64 gesehen, die komplette Osterformel mit Datum vom Ostersonntag als Ausgabe. Bin mir aber nicht sicher ob die Simon's Basic Erweiterung Voraussetzung war[/OT]Damals hatte ich noch gute Augen, aber lesbarer Code ist etwas anderes.

    3 Mal editiert, zuletzt von autoBert (9. April 2016 um 10:57)

  • autoBert:

    Deine Lösung kommt nicht nachweislich zum selben Ergebnis.

    Deine zweite Spalte weicht durchweg vom Soll ab:

    Code
    1 | 2 | 2
    2 | 3 | 2
    3 | 4 | 2
    4 | 1 | 2
    5 | 2 | 3
    6 | 3 | 3
    7 | 4 | 3
    8 | 1 | 3
    9 | 2 | 4

    Soll - vgl. Eingangspost:

    Code
    1 | 1 | 2
    2 | 2 | 2
    3 | 3 | 2
    4 | 4 | 2
    5 | 1 | 3
    6 | 2 | 3
    7 | 3 | 3
    8 | 4 | 3
    9 | 1 | 4

    Ansonsten wäre mir deine Lösung auch lieber gewesen. ;)

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • Ups, erwischt ich hab doch glatt das falsche Skript gestartet. Aber im 2. Anlauf:

    Code
    For $x = 1 To 120
    	ConsoleWrite($x & " | " & Mod($x-1, 4)+1 & " | " & Ceiling($x / 4)+1 & @CRLF)
    Next

    immer noch für Ungeübte lesbarer, schlanker? Aber jetzt mit hoher Warscheinlichkeit langsamer.

  • Nette Idee autoBert - auf die kam ich noch gar nicht :)

    Lesbarer ist es definitiv für ungeübtere ... danke für die Idee :)

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.