Björn Lindner: dokumentiertes umständliches Script

Hi,

also nochmal, das Script, welches unter www.ascota.de/anzeige.txt zu finden ist, soll aus einer txt datei mit haendlern, und einer txt datei mit allen postleitzahlen und deren geometrischen koordinaten die 10 haendler raussuchen, die am nächsten zu einer eingegeben plz sind.
für weitere anfragen stehe ich ab morgen früh 7.30 uhr zur verfügung.

mfg björn lindner, der erstmal feierabend macht

  1. Hallo, Björn,
    ehe du jetzt gleich ganz fürchterlich Haue kriegst (von den Forumspuristen :-)
    1. Hättest Du das eigentlich an den alten Thread anhängen sollen.
    2. hier der Link zum anklicken: http://www.ascota.de/anzeige.txt
    3.

    für weitere anfragen stehe ich ab morgen früh 7.30 uhr zur verfügung.

    Und derweile legen sich die andern hier krumm um eine Lösung zu finden? HmmmPhmmm! Naja.

    Aber sonst war in Deinem Posting alles richtig! *g*

    Gruß und schönen Feierabend
    Eckard.

    1. Hi,

      Aber sonst war in Deinem Posting alles richtig! *g*

      nicht wirklich: <img src="/images/03.gif" alt="">

      Ich sehe eigentlich nirgendwo eine Frage...

      Cheatah

      1. Ich sehe eigentlich nirgendwo eine Frage...

        Sorry, Cheatah,
        hab doch glatt vergessen ein Link zum ursprünglichen Thread zu setzen http://www.teamone.de/selfaktuell/forum/messages/109088.html
        was ich hiermit nachhole.
        Gruß Eckard.

        1. Hi Eck,

          thx für die Hilfe.
          Vielleicht kann mir ja jemand sagen, ob es zeitlich etwas ausmacht, ob ich auf eine txt Datei zugreife oder auf eine MySQL Datenbank?
          Ursprünglich war das Script für ein Web ohne Datenbank, jetzt hat der Kunde aber zu einem größeren gewechselt und die Probs lösen sich vielleicht schon, wenn ich es nur auf die Datenbank umbaue.

          MFG Björn

          1. Hallo Björn,

            Die Textdateien sind _nicht_ dein Problem, sondern die ineffizient Umsetzung.
            Wie gross sind die Datensätze eigentlich? Welchen Aufbau haben sie?

            So auf Anhieb sehen tue ich nur:

            »»  $entf[$b][0]=bcsqrt((bcpow($dx,2,10)+bcpow($dy,2,10)),10);

            besser:
               $entf[$b][0]=Sqrt($dx*$dx + $dy*$dy);

            Für mehr müsstest du Variablennamen vergeben die irgendeinen Sinn machen,
            so ist das Script ungefähr so lesbar wie disassemblierter Compileroutput.

            Tip:
            $plz -> $haendler
            $i -> $anzahlHaendler
            $j -> $anzahlKoord  (zumindest da, wo das zutrifft)

            Alle Schleifen, die über das gleiche Array zählen bekommen die gleiche
            Zählervariable. (z.b. $h für alle Schleifen übers Händler Feld.)

            Wech mit den temp1 bis temp5, statt:

            »»   $temp5=$koord[$z][0];
            »»   if($temp5==$postleitzahl)

            muss da  if($koord[$z][0]==$postleitzahl) stehen.

            Was merken sich $merke1 und $merke2 ?

            Offensichtlich kommen bestimmte Codeteile mehrfach vor. Sowas gehört dann in
            eine Funktion.

            Arrays fangen -so wie du sie benutzt- bei Null an und gehen bis
            count($Feld)-1. Schleife mit Abbruchbedingung $z<=count($Feld) ist also falsch.
            Und Schleifen über for($z=ArrayGroesse;$z>=0;$z--) greifen ebenso einmal hinters
            Array.

            Sortieren macht man nicht selber, sondern mit den eingabauten Sortierfunktionen.
            (Und mit usort() kann man auch beliebige (mehrdimensionale) Arrays nach
            beliebigen Kriterien sortieren (->Archiv))

            Gruss,
            Carsten

            1. Hi Carsten,

              auch Dir erstmal Danke.
              Das sind mal wieder Tips, die einem echt nützen und wo man Programmiertechnisch etwas dazu lernt.
              Nur nachstehenden Absatz raff ich einfach net.

              Arrays fangen -so wie du sie benutzt- bei Null an und gehen bis
              count($Feld)-1. Schleife mit Abbruchbedingung $z<=count($Feld) ist also falsch.
              Und Schleifen über for($z=ArrayGroesse;$z>=0;$z--) greifen ebenso einmal hinters
              Array.

              Bis zu count($Feld) komm ich noch mit, aber dann is Sense.
              Was willst Du mir damit sagen?

              Ich hab mal die überarbeitete Version bereitgestellt.
              http://www.ascota.de/anzeige.txt

              Ich hab das nun schon von 5 auf 4 kByte kürzen können, aber dem ausklinken bei Schlund hat es noch nicht entgegen gewirkt.
              Die Rechenoperationen kann ich leider nicht zusammen fassen, da sie unterschiedlich beginnen. Bei dem einen muß ich für die AusgangsPLZ noch die Koordinaten suchen, die ich beim 2. schon hab und mir somit sparen kann.
              Vielleicht hast Du oder wer anders noch eine Idee.

              MFG Björn

              1. Hi Björn,

                Bis zu count($Feld) komm ich noch mit, aber dann is Sense.
                Was willst Du mir damit sagen?

                ok, kurzes Beispiel:

                $feld=array("erdbeere","banane","kirsche","kiwi","himbeere");

                dann ist count($feld)==5; und
                $feld[0]=="erdbeere"
                $feld[1]=="banane"
                $feld[2]=="kirsche"
                $feld[3]=="kiwi"
                $feld[4]=="himbeere"
                und feld[5] ist undefiniert. PHP macht da im allgemeinen möglichst keinen
                Aufstand von, du bekommst also 0 oder einen Leerstring.
                Also $feld[$count($feld)] hat keinen sinvollen Inhalt.
                Und wenn du
                for($z=count($feld);$z>=0;$z--)
                  echo "Feld nr. $z enhält $feld[$z]. <br>";
                ausprobierst erhälst du Zeile mit Feld nr. 5 enthält.

                Ich hab mal die überarbeitete Version bereitgestellt.
                http://www.ascota.de/anzeige.txt

                hey, $i heisst ja immer noch nicht $anzahlHaendler ;-)

                Ein Bug haste in die Sortierfunktion reingebaut, wenn
                $vergleich1==vergleich2 ist (unwahrscheinlich bei Fließkommazahlen,
                aber möglich) wird nix zurückgeben. (Z.B.: > durch >= ersetzen).

                Ich hab das nun schon von 5 auf 4 kByte kürzen können

                Die Grösse des Scripts sagt _nichts_ über sein Laufzeitverhalten aus.

                aber dem
                ausklinken bei Schlund hat es noch nicht entgegen gewirkt.

                Wie liegt das ganze denn so im Timing? Du hast es doch bestimmt auf eigenem
                Server getestet. Wie ist die aktuelle Version im Vergleich zur vorherigen ?
                Handstoppen sollte reichen, der Schlund-Server lässt dich immerhin 6 sec.
                rechnen.

                Dazu noch mal die Frage: Wie gross sind die Datensätze ?
                Also wieviele Elemente enthält die koord Tabelle und wieviele die
                haendler-Tabelle?

                Die Rechenoperationen kann ich leider nicht zusammen fassen, da sie
                unterschiedlich beginnen. Bei dem einen muß ich für die
                AusgangsPLZ noch die Koordinaten suchen, die ich beim 2. schon hab und mir
                somit sparen kann.

                Dann such sie doch für die erste Version vorher raus, dann kann der Rest mit
                einer Routine erledigt werden.

                also
                if ($zaehler < 10) // es fehlen noch haendler
                {
                  if ($zaehler==0) // noch gar keiner ->Ausgangskoordinaten fehlen noch
                  {
                     // Koordinaten zum eingegebenen Ort suchen
                     for($z=0;$z<=$j;$z++)
                     {
                        if($postleitzahl==koord[$z][0]
                        {
                           // speichern der Koordinaten der gesuchten PLZ
                          $merke1=$haendler[$a][1];
                          $merke2=$haendler[$a][2];  
                          break; // Schleife abbrechen wenn gefunden
                        }
                     }
                   }
                   // hier sind jetzt die koordinaten auf jeden Fall verfügbar und
                   // du brauchst nur noch eine Version der Entfernungsberechnung
                  
                   //Entfernungsberechnung für alle Händler zur eingegeben PLZ
                   // .....

                }

                Vielleicht hast Du oder wer anders noch eine Idee.

                habe ich:
                Was soll das mit dem 'Entfernen der Doppelungen'? Erstmal verstehe ich
                den Sinn des ganzen überhaupt nicht. Wieso sollen Händler mit Entfernung
                0 zur eingegebene PLZ nicht angezeigt werden? (Bisher angezeigt hast du
                ja nur welche mit identischer PLZ, es könnte ja sein das zwei verschiedene
                PLZ die gleichen Koordinaten haben) und wieso soll nur ein Haendler mit
                gleicher Entfernung zum eingegebenen Ort angezeigt werden?
                Ich vermute mal, das diese beiden Fälle einfach nie eintreten und dieser
                Routinenteil deswegen nichts tut ausser (viel) Rechenzeit zu verbraten.
                Ausserdem: Da du nur (höchstens) die ersten Zehn brauchst, könntest du (beide)
                Schleifen abbrechen wenn w>9 ( for($e=$i;$e>=0 && w<9;$e--).

                Gruss,
                Carsten