Statistisches Erfassen

  • Hey,
    irgendwie brauche ich grade einen Gedankenstoß :p...!

    Ich lese per FF.au3 eine Website aus, dort gibt es eine History, sobald ein neuer Name in dieser "Top 9" auftaucht, ordne ich einen TimeStamp zu...

    Ich möchte gerne zählen, wie oft dieser Name schon "NEU" in die Liste gekommen ist (irgendwo aufgetaucht, mit halt NEUEM TimeStamp)...

    Mein Lösungsansatz wäre gewesen, die Strings immer in eine .txt zu schreiben, wenn das Auslesen ergeben hat, dass der Name mit dem Datum dort noch nicht drin war und am Ende ne Count-Funktion?!...^^
    Das alles soll im Hintergrund funktionieren...

    IniWrite und IniRead sind hier ja nicht möglich!? Da ich jedem Wert einen Schlüßel zuordnen muss und ich die Werte ja immer wieder brauche, das also hintereinander eingetragen werden muss...^^


    Glaube, habe sowas schon mal gesehen, finde aber die Befehle nicht, die ich brauche :(...


    Wäre super, wenn mir ebend jemand auf die Sprünge helfen könnte!^^


    LG

    • Offizieller Beitrag

    Hier bietet sich das "Scripting.Dictionary" Objekt an.
    Ich hab mal ein Muster erstellt. Ungetestet, sollte aber laufen. ;)

    Spoiler anzeigen
    [autoit]

    ; Objekt erstellen
    Global $oDict = ObjCreate("Scripting.Dictionary")
    Global $Trenner = '|' ; kannst auch was anderes aber einmaliges nehmen

    [/autoit] [autoit][/autoit] [autoit]

    ; Aufbau ist wie in einer INI, Schlüssel und Wert
    ; Schlüssel wir der Name und Wert wird einfach eine Zeichenkette mit den Timestamps separiert durch einen Trenner deiner Wahl
    ; und als erster Eintrag im Wert erscheint ein Zähler
    ; in deinem Programm erhältst du den "Namen" in einer Variablen, z.B. $Name
    $Name = 'Blub'
    $Stamp = 'DeinTimeStamp'
    ;....
    ;....
    If Not $oDict.Exists($Name) Then ; "Name" noch nicht enthalten
    $oDict.Add($Name, '1' & $Trenner & $Stamp
    Else
    Local $val = $oDict.Item($Name) ; der/die bereits existierenden Timestamps
    Local $split = StringSplit($val, $Trenner, 2)
    Local $Anzahl = $split[0] +1 ; Zähler erhöhen
    $val = $Anzahl
    For $i = 1 To UBound($split) -1 ; Value neu erstellen mit erhöhtem Zähler und neuem Stamp
    $val &= $Trenner & $split[$i]
    Next
    $val &= $Trenner & $Stamp
    $oDict.Item($Name) = $val ; den neuen Wert eintragen
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; ======== gezielt die Anzahl abfragen, Aufrufen mit Parameter "Name" =====
    Func _GetCount($KEY)
    If Not $oDict.Exists($KEY) Then Return SetError(1,0,0)
    Local $val = $oDict.Item($KEY)
    Local $split = StringSplit($val, $Trenner, 2)
    Return $split[0] ; Rückgabe Anzahl
    EndFunc

    [/autoit]

    Wenn du die Daten auch über einen Programmstart hinaus verwalten möchtest, kannst du sie in eine INI wegschreiben und auch von dort wieder laden. Sieh dir dazu mal die Func's _IniWriteSectionFromObjDict und _IniReadSectionToObjDict aus meiner UDF zum Dictionary Object an (Klick auf meinen UDF-Link in der Signatur, dort findest du weiteres).

  • Sehr gut, danke... :D Werde es nachher gleich mal testen!

    Es muss nicht über den Programmstart erhalten bleiben :)

    Das wird ein Statistik-Programm für ein Gegenstand in einem Auktionshaus^^ Leider gibt dieses rel. wenig Informationen um eine gute Gebotsstrategie zu entwickeln... Und was man uns nicht geben will, machen wir uns halt selber, hm ;D?...

    Da die Gebote dort eh immer erst in der letzten "Minute" passieren und über einen kleinen Zeitraum, reicht es mir, wenn das Programm die Statistik nur für kurze Zeit ausgibt...^^

    Hättest du mir ne Ini-Lösung gegeben, hätte ich diese bei Programm-Ende auch direkt löschen lassen!


    Also perfekte Lösung, wenn es funktioniert^^


    Vielen Dank schon mal :D *gg*


    *edit*

    ch habe noch ne Frage zu deinem Script...
    Undzwar erstelle ich die Werte immer wieder neu in einer "For...Next"-Schleife...(bzw. verschiedenen)

    Wenn ich das jetzt richtig verstehe, ist dein Script doch für 1 Namen, der gezählt wird, wenn er auftaucht, richtig?
    Also müsste ich die Werte auch zu Arrays machen und in die Schleife einbauen?!

    Dann stellt sich mir aber die Frage, ob er dann auch erkennt, wenn ein Name auftaucht, der schon mal da war, aber nicht mehr in einem Array gespeichert ist...
    Ich weiss ja nicht, wie diese "Objekte", Informationen hinterlegen...


    Hier ist mein Script dazu:
    (wieder klappt das AutoIt-Feld bei mir nicht und er löscht die Zeilenumbrüche und es wird unlesbar -.-...)

    Spoiler anzeigen
    [autoit]

    ; Ein kleines Tool, dass das Auktionshaus Swoopo um ein paar nützliche Informationen erweitert und das Mitbieten wesentlich angenehmer gestaltet!
    ; Einen ganz besonderen Dank dabei auch an https://autoit.de/www.autoitbot.de und insbesondere an dbj29, Understood und BugFix von autoit.de!

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #include
    #include
    #include
    #include
    #include
    #include
    #Include
    #Include
    #include
    #include
    #include
    ; Start Begrüßung
    $splash = @ScriptDir & "\splash.gif"
    SplashImageOn("", $splash, 265, 95, @DesktopWidth / 2 - 132, 200, 1)
    Sleep(2000)
    SplashOff()
    ; Ende Begrüßung

    [/autoit] [autoit][/autoit] [autoit]

    _MozRepl_Detect()
    $title = "Swoop'er V 1.00"
    TraySetToolTip($title)

    [/autoit] [autoit][/autoit] [autoit]

    $UName = IniRead(@ScriptDir & "/config.ini", "LogIn", "Name", "")
    $PWord = IniRead(@ScriptDir & "/config.ini", "LogIn", "Passwort", "")

    [/autoit] [autoit][/autoit] [autoit]

    Global $varNAME
    $item = InputBox("Hier das Produkt angeben!", "Bitte die exakte Seite des Produktes eingeben, dass sie beobachten wollen!", "", " M", 250, 150)
    If @error = 1 Then _Exit()

    [/autoit] [autoit][/autoit] [autoit]

    #Region ### START Koda GUI section ###
    $Swoop_Form = GUICreate($title, 275, 323, 465, 212)
    $Aktueller_Betrag = GUICtrlCreateInput("", 24, 16, 105, 21, BitOR($ES_CENTER, $ES_AUTOHSCROLL, $ES_READONLY))
    $Aktuelle_Zeit = GUICtrlCreateInput("", 144, 16, 105, 21, BitOR($ES_CENTER, $ES_AUTOHSCROLL, $ES_READONLY))
    $z_v = GUICtrlCreateButton("Zeigen", 156, 288, 89, 25, $WS_GROUP)
    $bb = GUICtrlCreateButton("Bieten", 156, 256, 89, 25, $WS_GROUP)
    $new = GUICtrlCreateButton("New", 249, 0, 26, 17, $WS_GROUP)
    GUICtrlSetFont(-1, 8, 400, 0, "Nyala")
    $true_his = GUICtrlCreateLabel("", 48, 95, 180, 150)
    GUICtrlSetFont(-1, 9, 400, 0, "Nyala")
    $Bids = GUICtrlCreateGroup("Bids", 24, 72, 225, 170)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $Obj_Name = GUICtrlCreateInput("", 24, 48, 225, 21, BitOR($ES_CENTER, $ES_AUTOHSCROLL, $ES_READONLY))
    GUICtrlSetFont(-1, 8, 400, 0, "Segoe UI")
    $login = GUICtrlCreateButton("LogIn", 249, 16, 26, 17, $WS_GROUP)
    GUICtrlSetFont(-1, 7, 400, 0, "Nyala")
    $imp_bb = GUICtrlCreateButton("BB", 249, 32, 26, 17, $WS_GROUP)
    GUICtrlSetFont(-1, 8, 400, 0, "Nyala")
    GUISetState(@SW_SHOW)
    WinSetOnTop($title, "", 1)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    Opt("WinTitleMatchMode", 2)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $his_bieter, $Input1, $Input2, $login_save, $login_cancel, $Form2
    Dim $history[10]
    Dim $array[10][5]
    Dim $array_alt[10][5]
    $xpath_be = "//td[@id='a_current_price']" ; Aktueller Betrag
    $xpath_ze = "//div[@id='countertime']" ; Aktuelle Zeit
    $xpath_object = "//h3" ; Auktionsgegenstand
    $xpath_betrag_alt = ""

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 9 Step +1
    $array[$i][3] = "//div[@id='stats_test']/table/tbody/tr[" & ($i + 1) & "]/td" ; 1 = Gebot, 2 = Name, 3 = Art des Gebotes
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _Starting()

    [/autoit] [autoit][/autoit] [autoit]

    Func _Starting()
    _FFStart($item, "default", 2, True)
    If _FFIsConnected() = 1 Then
    $varURL = _FFXpath("//div[@id='bilder_bottom']//td[1]/a/img", "src", 9)
    $varNAME = "Object.gif"
    InetGet($varURL, $varNAME)
    GUICtrlCreatePic("Object.gif", 48, 256, 80, 60, BitOR($SS_NOTIFY, $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS))
    GUICtrlSetData($Obj_Name, _FFXpath($xpath_object))
    _LogIn()
    Else
    MsgBox(48, "Achtung!", "Es ist ein Problem aufgetaucht!")
    _Exit()
    EndIf
    EndFunc ;==>_Starting

    [/autoit] [autoit][/autoit] [autoit]

    Func _LogIn_GUI()
    $Form2 = GUICreate("LogIn", 213, 97, 825, 486)
    $Input1 = GUICtrlCreateInput($UName, 64, 16, 137, 21)
    $Input2 = GUICtrlCreateInput($PWord, 64, 40, 137, 21, BitOR($ES_PASSWORD, $ES_AUTOHSCROLL))
    $login_label = GUICtrlCreateLabel("LogIn:", 8, 18, 45, 22)
    GUICtrlSetFont(-1, 10, 800, 0, "Palatino Linotype")
    $Label1 = GUICtrlCreateLabel("PW:", 8, 42, 29, 22)
    GUICtrlSetFont(-1, 10, 800, 0, "Palatino Linotype")
    $login_save = GUICtrlCreateButton("Speichern", 16, 72, 81, 17, $WS_GROUP)
    $login_cancel = GUICtrlCreateButton("Abbrechen", 120, 72, 81, 17, $WS_GROUP)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($Input1, $UName)
    GUICtrlSetData($Input2, _StringEncrypt(0, $PWord, "sW00p"))

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)
    _History()
    EndFunc ;==>_LogIn_GUI

    [/autoit] [autoit][/autoit] [autoit]

    Func _LogIn()
    If $UName <> "" And $PWord <> "" Then
    If _FFXPath("//div[@id='bcsubtext2']//td[3]") <> $UName Then
    _FFSetValueByName("login", $UName)
    _FFSetValueByName("password", $PWord)
    _FFFormSubmit()
    _FFLoadWait()

    [/autoit] [autoit][/autoit] [autoit]

    If _FFXPath("//div[@id='bcsubtext2']//td[3]") <> $UName Then
    MsgBox(48, "Achtung!", "Das Einloggen war leider nicht erfolgreich! Prüfen sie ihre Daten!")
    EndIf
    EndIf
    EndIf
    _History()
    EndFunc ;==>_LogIn

    [/autoit] [autoit][/autoit] [autoit]

    Func _IniWrite()
    IniWrite(@ScriptDir & "/config.ini", "LogIn", "Name", GUICtrlRead($Input1))
    $PW = _StringEncrypt(1, GUICtrlRead($Input2), "sW00p")
    IniWrite(@ScriptDir & "/config.ini", "LogIn", "Passwort", $PW)
    GUISetState(@SW_HIDE, $Form2)
    _LogIn()
    EndFunc ;==>_IniWrite

    [/autoit] [autoit][/autoit] [autoit]

    Func _History()
    While 1
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUICtrlSetOnEvent($z_v, "_Showhide")
    GUICtrlSetOnEvent($bb, "_Bid")
    GUICtrlSetOnEvent($new, "_New")
    GUICtrlSetOnEvent($login, "_LogIn_GUI")
    GUICtrlSetOnEvent($login_save, "_IniWrite")

    [/autoit] [autoit][/autoit] [autoit]

    $xpath_betr = _FFXPath($xpath_be)
    $xpath_betrag = StringTrimRight($xpath_betr, 2) & " €"
    $xpath_zeit = _FFXPath($xpath_ze)
    GUICtrlSetData($Aktueller_Betrag, $xpath_betrag)
    GUICtrlSetData($Aktuelle_Zeit, $xpath_zeit)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 9 Step +1
    $bidder_1 = _FFXPath($array[$i][3], "textContent", 7)
    If $bidder_1[0] <> 0 Then
    If $bidder_1[3] = "Einzelgebot" Then $array[$i][0] = "EG"
    If $bidder_1[3] = "BietButler" Then $array[$i][0] = "BB"
    $array[$i][1] = $bidder_1[2]
    $array[$i][2] = StringTrimRight($bidder_1[1], 2) & " €"
    Else
    $array[$i][0] = "" ; Bidtype / Typus des Gebotes
    $array[$i][1] = "" ; Bidder / Bieter
    $array[$i][2] = "" ; Bid / Gebot
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    If $xpath_betrag <> $xpath_betrag_alt Then
    $label_data = ""
    For $i = 1 To 9 Step +1
    For $k = 1 To 9 Step +1
    If $array[$i][2] = $array_alt[$k][2] Then
    $array[$i][4] = $array_alt[$k][4]
    ExitLoop
    EndIf
    If $k = 9 Then
    $array[$i][4] = _NowTime(4)
    EndIf
    Next
    If $array[$i][4] = "" Then
    $array[$i][4] = _NowTime(4)
    EndIf
    $label_data &= $array[$i][4] & " - " & $array[$i][0] & " - " & $array[$i][1] & " - " & $array[$i][2] & @CRLF
    Next
    GUICtrlSetData($true_his, $label_data)
    $xpath_betrag_alt = $xpath_betrag
    $array_alt = $array
    EndIf
    WEnd
    EndFunc ;==>_History

    [/autoit] [autoit][/autoit] [autoit]

    Func _Showhide()
    $FF = WinGetTitle("[Class:MozillaUIWindowClass]") ; Sucht ein FireFox-Fenster
    If BitAND(WinGetState($FF, ""), 2) Then
    WinSetState($FF, "", @SW_HIDE)
    GUICtrlSetData($z_v, "Zeigen")
    Else
    WinSetState($FF, "", @SW_SHOW)
    WinSetState($FF, "", @SW_RESTORE)
    GUICtrlSetData($z_v, "Verbergen")
    EndIf
    EndFunc ;==>_Showhide

    [/autoit] [autoit][/autoit] [autoit]

    Func _Bid()
    _FFLinkClick("fehlermeldung", "href")
    _History()
    EndFunc ;==>_Bid

    [/autoit] [autoit][/autoit] [autoit]

    Func _New()
    WinSetState($title, "", @SW_HIDE)
    $item_2 = InputBox("Hier das Produkt angeben!", "Bitte die exakte Seite des Produktes eingeben, dass sie beobachten wollen!", "", " M", 250, 150)
    WinSetState($title, "", @SW_SHOW)
    If @error = 1 Then _History()
    If @error = 0 Then
    $item = $item_2
    _Starting()
    EndIf
    EndFunc ;==>_New

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    If FileExists($varNAME) Then FileDelete($varNAME)
    _FFQuit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    Dazu sei gesagt, dass das die aktuellste Version ist und daher momentan nicht funktioniert! -.-...
    Bastel grade an der LogIn-Funktion und irgendwie will das GuiCtrlSetOnEvent nicht hinhauen, dass er einen Usernamen/PW neu annimmt, wenn man erst einen falschen drin hatte... (also alle Button der 2. GUI)...


    LG

    Edit BugFix: Habe mal die AutoIt Tags gesetzt.
    Edit Acanis: Omg... Wie? xD...??????????... Dann liegt das wohl an GoogleChrome, nicht am Forum/mir Oo...

    8 Mal editiert, zuletzt von Acanis (11. November 2009 um 17:42)

    • Offizieller Beitrag

    Wenn ich es richtig verstanden habe, brauchst du den Timestamp gar nicht zum Speichern, sondern du zählst nur?
    Dann reicht diese Version:

    Spoiler anzeigen
    [autoit]

    ; Objekt erstellen
    Global $oDict = ObjCreate("Scripting.Dictionary")

    [/autoit] [autoit][/autoit] [autoit]

    ; Aufbau ist wie in einer INI, Schlüssel und Wert
    ; Schlüssel wir der Name und Wert wird der Zähler
    ; in deinem Programm erhältst du den "Namen" in einer Variablen, z.B. $Name
    $Name = 'Blub'

    [/autoit] [autoit][/autoit] [autoit]

    ; für alle auftauchenden "Namen" rufst du _SetKey("Name") auf, dann wird der Name entweder hinzugefügt,
    ; oder falls bereits vorhanden, der Zähler erhöht

    [/autoit] [autoit][/autoit] [autoit]

    Func _SetKey($KEY)
    If Not $oDict.Exists($KEY) Then ; "Name" noch nicht enthalten
    $oDict.Add($KEY, '1') ; erstmaliges Auftreten, also Counter = 1
    Else
    Local $count = $oDict.Item($KEY) ; die Anzahl zu diesem Key
    $oDict.Item($KEY) = $count +1 ; den Counter um 1 erhöhen und eintragen
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; die Anzahl kannst du jederzeit mit _GetCount("Name") abfragen
    Func _GetCount($KEY)
    If Not $oDict.Exists($KEY) Then Return SetError(1,0,0)
    Return $oDict.Item($KEY) ; Rückgabe Anzahl
    EndFunc

    [/autoit]
  • Naja...

    Im Code siehst du ja, dass ich mit einem Array in 10 Dimensionen arbeite...

    Dimension 1-9 (ohne 0!) stehen hierbei für die "Zeilen" der History...

    Wenn jemand neues bietet, rutscht er von oben nach! ABER es kann auch sein, dass 3 Leute gleichzeitig bieten, dann rutscht der 1. auf den 4...
    Er kommt also wieder vor, mit einem neuen Array, das vorher anders benutzt wurde...

    Irgendwie muss ich ja zuordnen, ob der Name nun schon vor kam oder nicht?! :D Da ich das mit dem TimeStamp schon funktionierend habe, wollte ich den halt als Zuordnungsgröße nehmen, die zeigt, ob der Name schon mal in einem anderen Array vor kam...


    Die Funk sieht ja so gut und leicht verständlich aus^^ Nur, wie soll ich die Zählfunktion in die Abfrage einbauen?...
    Array 1 hieße, dass bei Gleichzeitiggeboten Fehler auftauchen...
    Alle Arrays hieße "Doppelbuchung", wenn der Name nur verrutscht...

    Weisst du, was ich meine :)?


    LG


    PS: Bin kein totaler Anfänger mehr, progge aber erst seit 3 Monaten, also sorry, wenn ich mich ein bisschen doof anstellen sollte *gG*