1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Oscar

Beiträge von Oscar

  • Fuzzy-Search

    • Oscar
    • 2. Oktober 2020 um 16:26
    Zitat von Bitnugger

    Ich habe deine Dll so kompiliert: nim c -d:release -o:FuzzySearch.dll FuzzySearch.nim

    Du musst das so aufrufen: nim c -d:release --app:lib FuzzySearch.nim

  • Fuzzy-Search

    • Oscar
    • 2. Oktober 2020 um 15:57
    Zitat von Mars

    Da fühle ich mich gleich schlecht, dass ich soetwas ähnliches in der SB nachgefragt habe,

    Ich gebe zu, dass Deine Frage in der SB den Ausschlag dafür gab, aber ich finde, dass man sowas in AutoIt durchaus mal gebrauchen kann.

    Und es war eine Übung, um in Nim zu programmieren. :)

    Im Übrigen ist das Ganze wirklich schnell. Bei mir dauert die Suche (so wie im Beispiel) nur rund 280ms. Bei 207336 Wörtern ist das nicht schlecht, denke ich.

    Müsste man mal mit purem AutoIt vergleichen... ^^

  • Fuzzy-Search

    • Oscar
    • 2. Oktober 2020 um 11:07

    Wenn man in AutoIt ein Wort in einem Text sucht, nimmt man normalerweise StringInStr dafür oder bastelt etwas mit StringRegExp.

    Das ist meistens ausreichend und auch schnell genug.

    Wenn man allerdings eine "unscharfe" Suche möchte, wird es kompliziert und langsam. Die sogenannte Levenshtein-Distanz (oder in Prozent umgerechnet) gibt die Ähnlichkeit zweier Wörter zurück.

    In AutoIt ist die Funktion aber sehr zeitaufwändig und wenn man einen größeren Text durchsuchen will, dauert es sehr lange.

    Da ich die Levenshtein-Distanz bereits in Nim übersetzt habe, dachte ich mir, das kann ich dann doch auch für AutoIt zur Verfügung stellen (als DLL).

    Die Suche habe ich dann auch gleich in Nim geschrieben, so wird es noch etwas schneller.

    Edit 03.10.2020:

    Ich habe den Nim-Quellcode jetzt dahingehend geändert, dass gleich alle Fundstellen (als String) zurückgegeben werden.

    Das hat den Vorteil, dass bei sehr vielen Fundstellen nur ein DllCall von AutoIt aus erforderlich ist. Im Worstcase-Fall (Suchbegriff: ein Buchstabe und Null Prozent) würde sonst für jedes Wort ein Dll-Call nötig sein, was recht zeitaufwändig ist.

    Edit 06.10.2020:

    Die Nim-interne Funktion zur Berechnung der Levenshtein-Distance editDistanceAscii() ist deutlich effektiver, als die von mir konvertierte Funktion. Die Laufzeit des Beispiels schrumpft somit von vorher 238ms auf nunmehr 66ms.

    Ich finde, das ist eine neue Version wert. :)

    Der Nim-Sourcecode sieht so aus (zum compilieren des Codes als Dll den Compiler folgendermaßen aufrufen: nim c -d:release --app:lib FuzzySearch.nim

    Code
    import strutils, std/editdistance
    
    # Levenshtein-Distanz in Prozent berechnen
    proc lsDistancePercent*(s, t: cstring): int {.stdcall,exportc,dynlib.} =
      let n = max(s.len, t.len)
      if n == 0 or s == t: return 100
      return int(100 / n * float(n - editDistanceAscii($s, $t)))
    
    # Ein Objekt zum speichern der Woerter
    type
      FuzzySearch* = ref object of RootObj
        sSearch*: seq[string]
    
    let oFS = FuzzySearch() # Objekt erstellen
    
    # Funktion, zum erstellen der Woerter aus dem uebergebenen String
    proc load*(sData: cstring): int {.stdcall,exportc,dynlib.} =
      if sData == "": return 0
      oFS.sSearch = splitWhitespace($sData, -1)
      return 1
    
    # Funktion, um die Anzahl der Woerter zurueckzugeben
    proc getCount*(): int {.stdcall,exportc,dynlib.} =
      return oFS.sSearch.len
    
    # Funktion, um ein bestimmtes Wort zurueckzugeben
    proc getWord*(iIndex: int): cstring {.stdcall,exportc,dynlib.} =
      if iIndex < 0 or iIndex > oFS.sSearch.len - 1: return ""
      return oFS.sSearch[iIndex]
    
    # Funktion, fuer die Levenshtein-Suche
    # Parameter:
    #  t = Suchbegriff
    #  s = ab dieser Wort-Position suchen
    #  p = Prozentwert, fuer die Suche
    # Rueckgabe:
    #  Ein String mit den Positionen der gefundenen Worte (durch Kommata getrennt),
    #  oder ein Leerstring, wenn nicht gefunden, bzw. Fehler
    proc search*(t: cstring, s, p: int): cstring {.stdcall,exportc,dynlib.} =
      if oFS.sSearch.len == 0: return ""
      if s > oFS.sSearch.len - 1 or s < 0: return ""
      var
        sReturn: seq[string]
        iPercent: int = p
      if iPercent > 99: iPercent = 99
      if iPercent < 0: iPercent = 0
      for iIndex in s + 1 .. oFS.sSearch.len - 1:
        if (lsDistancePercent(oFS.sSearch[iIndex], $t) >= iPercent): sReturn.add($iIndex)
      return join(sReturn, ",")
    Alles anzeigen

    Für die, die kein Nim installiert haben, habe ich die DLL bereits compiliert mit ins ZIP-Archiv (Anhang) gepackt.

    Das AutoIt-Beispiel sieht dann so aus:

    AutoIt
    #include <Array.au3>
    
    #AutoIt3Wrapper_UseX64=y
    Global $hDll = DllOpen(@ScriptDir & '\FuzzySearch.dll')
    
    Global $sWord1, $sWord2, $aRet, $iPos, $iPercent, $sFound
    
    ; Test 1 = Levenshtein-Distanz in Prozent
    ; =======================================
    $sWord1 = 'Zuckerkuchen' ; diese beiden Woerter
    $sWord2 = 'Butterkuchen' ; sollen verglichen werden
    $aRet = DllCall($hDll, 'int', 'lsDistancePercent', 'str', $sWord1, 'str', $sWord2)
    If @error Then Exit
    ConsoleWrite('Übereinstimmung: ' & $aRet[0] & '%' & @CRLF) ; in $aRet[0] steht das Ergebnis (als Integerzahl, in Prozent)
    
    ; Test 2 = Die Fuzzy-Suche in einem grossen Textdokument
    ; ======================================================
    $sWord1 = FileRead(@ScriptDir & '\bgb.txt') ; ein Textdokument laden (BGB, > 14.000 Zeilen, 1.5 MB)
    $aRet = DllCall($hDll, 'int', 'load', 'str', $sWord1) ; und den Text an die DLL uebergeben
    If @error Then Exit
    ConsoleWrite('Load ok: ' & ($aRet[0] == 1) & @CRLF)
    
    $aRet = DllCall($hDll, 'int', 'getCount') ; Anzahl der Woerter ermitteln
    If @error Then Exit
    ConsoleWrite('Count: ' & $aRet[0] & @CRLF)
    
    $aRet = DllCall($hDll, 'str', 'getWord', 'int', 85271) ; ein bestimmtes Word aus dem Text holen
    If @error Then Exit
    ConsoleWrite('Word: ' & $aRet[0] & @CRLF)
    
    $sWord2 = 'Richtlinie' ; das Suchwort
    $iPos = 0 ; Startwert. Ab diesem *Wort* (*nicht* Buchstaben) wird gesucht.
    $iPercent = 66 ; mit welcher Genauigkeit soll gesucht werden (in Prozent)
    
    $iTimer = TimerInit()
    ; Die Rueckgabe besteht aus einem String mit den Positionen der gefundenen
    ; Woerter (durch Kommata getrennt) oder ein Leerstring, wenn nichts gefunden
    ; wurde bzw. ein Fehler aufgetreten ist.
    $aRet = DllCall($hDll, 'str', 'search', 'str', $sWord2, 'int', $iPos, 'int', $iPercent)
    If @error Then Exit ConsoleWrite('Error: ' & @error & @CRLF)
    ConsoleWrite('Timer: ' & TimerDiff($iTimer) & @CRLF)
    
    ConsoleWrite('Found on Position: ' & $aRet[0] & @CRLF)
    DllClose($hDll)
    Global $aFound = StringSplit($aRet[0], ',', 2)
    _ArrayDisplay($aFound)
    Alles anzeigen

    Wichtig ist noch, dass ihr das AutoIt-Script als 64-Bit-Version ausführt #AutoIt3Wrapper_UseX64=y, weil Nim eine 64-Bit-DLL erstellt.

    Alle Quellcodes und den Beispieltext (BGB mit 207336 Wörtern) findet ihr im ZIP-Archiv.

    Dateien

    FuzzySearch.zip 421,58 kB – 433 Downloads
  • Verzeichnisangabe bei Consolen-Programm-Ende anzeigen

    • Oscar
    • 30. September 2020 um 15:48

    Warum compilierst Du das Script nicht als CUI-Programm?

    Dann funktioniert ganz einfach ConsoleWrite:

    AutoIt
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Outfile_x64=GetWindowspos.exe
    #AutoIt3Wrapper_Change2CUI=y
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Array.au3>
    
    ConsoleWrite(@CRLF & "Please be patient until preparations are done...!" & @CRLF & @CRLF)
    
    $sName = InputBox("Eingabe Fenstername", "Bitte gib den Fenstername ein:")
    
    Local $aPos = WinGetPos($sName)
    _ArrayDisplay($aPos, $sName)
    Alles anzeigen
  • Möglich oder nicht? Zeitwert aus einem Programm im Hintergrund auslesen und in ein neues Script schreiben

    • Oscar
    • 26. September 2020 um 13:58

    Ich habe mir mal das Wireshark-Protokoll angesehen. Die Zieladresse ist wohl eher: 192.168.178.55

    Aber egal.

    Hier die Aufzeichnungen von den ersten drei Paketen:

    Code
    0000   b8 27 eb 23 28 83 d8 cb 8a ba 77 44 08 00 45 00   .'.#(.....wD..E.
    0010   00 2b 36 a6 00 00 80 11 cb 8d c0 a8 05 06 c0 a8   .+6.............
    0020   b2 37 2b 48 2b 48 00 17 24 1a 70 07 01 06 1e 14   .7+H+H..$.p.....
    0030   00 00 ff 00 03 03 54 61 67                        ......Tag
    
    0000   b8 27 eb 23 28 83 d8 cb 8a ba 77 44 08 00 45 00   .'.#(.....wD..E.
    0010   00 2b 36 a7 00 00 80 11 cb 8c c0 a8 05 06 c0 a8   .+6.............
    0020   b2 37 2b 48 2b 48 00 17 24 06 70 07 01 06 1e 28   .7+H+H..$.p....(
    0030   00 00 ff 00 03 03 54 61 67                        ......Tag
    
    0000   b8 27 eb 23 28 83 d8 cb 8a ba 77 44 08 00 45 00   .'.#(.....wD..E.
    0010   00 2b 36 a8 00 00 80 11 cb 8b c0 a8 05 06 c0 a8   .+6.............
    0020   b2 37 2b 48 2b 48 00 17 23 2e 70 07 01 06 1f 00   .7+H+H..#.p.....
    0030   00 00 ff 00 03 03 54 61 67                        ......Tag
    Alles anzeigen

    Jeweils die letzten 15 Bytes enthalten die übertragenen Daten (ab 70 07 01).

    Was diese "70 07 01" sind kann ich nicht sagen, aber danach die drei Bytes scheinen die Uhrzeit zu sein.

    Du sagtest, dass Du die Aufzeichnung um 06:30 Uhr gestartet und bis 06:40 Uhr laufen gelassen hast.

    1. Paket: Hex 06 1e 14 = 06:30:20

    2. Paket: Hex 06 1e 28 = 06:30:40

    3. Paket: Hex 06 1f 00 = 06:31:00

    und so geht es weiter bis

    n. Paket: Hex 06 28 28 = 06:40:40

  • Wie wiederhole ich einen Teil eines Programmablaufs, wenn eine nachfolgende Prüfung ein negatives Ergebnis auswirft?

    • Oscar
    • 22. September 2020 um 18:26
    Zitat von 32vroni

    Wie mache ich das am einfachsten?

    So:

    AutoIt
    Do
        $var = Ping("www.google.de")
    Until Not @error
  • ListCtrl - GridLines?

    • Oscar
    • 15. September 2020 um 19:17
    Zitat von BugFix

    Ideen?

    So:

    Code
    import wNim, winim
    
    var
      dc = MemoryDC()
      bmp = Bitmap(16, 16)
    
    dc.selectObject(bmp)
    dc.clear(Brush(wBlueBrush)) # <- Standard-Brush
    let blueIcon = Icon(bmp)
    dc.clear(Brush(color=0x000000FF)) # <- im BGR-Format
    let redIcon = Icon(bmp)
    dc.clear(Brush(wWhiteBrush)) # <- Standard-Brush
    dc.drawCheckMark(0, 0, 15, 15) # Haken zeichnen (x, y, w, h)
    let checkIcon = Icon(bmp)
    
    let
      app = App()
      frame = Frame(title="Test ImageList",size=(600,300))
      panel = frame.Panel()
      list = panel.ListCtrl(size=(560,240), pos=(10,10), style=wLcReport or wBorderDouble or wLcSingleSel)
    list.setExtendedStyle(LVS_EX_GRIDLINES) # <- Extended Style
    var il = ImageList(size=(16,16), mask=false, initialCount=0)
    il.add(blueIcon)
    il.add(redIcon)
    il.add(checkIcon)
    list.setImageList(il)
    list.appendColumn(text="Column 0", width=150)
    list.setColumnFormat(0, wListFormatLeft)
    list.appendColumn(text="Column 1", width=110, format=wListFormatRight)
    list.appendColumn(text="Column 2", width=110, format=wListFormatRight)
    list.appendColumn(text="Column 3", width=wListAutosizeUseHeader)
    var imgIndex: int
    for i in 0..10:
      imgIndex = 1
      if (i mod 2) == 0: imgIndex = 0
      if (i mod 3) == 0: imgIndex = 2
      list.appendItem([$i&"-0", $i&"-1", $i&"-2", $i&"-3"], imgIndex)
    
    frame.wIdExit do (): 
      frame.delete()
    
    frame.center()
    frame.show()
    
    app.mainLoop()
    Alles anzeigen
  • [gelöst] wListCtrl - keine Mehrspaltenanzeige bei Verwendung von ItemImage?

    • Oscar
    • 15. September 2020 um 17:04

    Als kleine Ergänzung:

    Für so einfache "Grafiken" braucht man keine externen Imagedateien. Die kann man auch direkt zeichnen:

    Code
    import wNim
    
    var
      dc = MemoryDC()
      bmp = Bitmap(16, 16)
    
    dc.selectObject(bmp)
    dc.clear(Brush(wBlueBrush)) # <- Standard-Brush
    let blueIcon = Icon(bmp)
    dc.clear(Brush(color=0x000000FF)) # <- im BGR-Format
    let redIcon = Icon(bmp)
    dc.clear(Brush(wWhiteBrush)) # <- Standard-Brush
    dc.drawCheckMark(0, 0, 15, 15) # Haken zeichnen (x, y, w, h)
    let checkIcon = Icon(bmp)
    
    let
      app = App()
      frame = Frame(title="Test ImageList",size=(600,300))
      panel = frame.Panel()
      list = panel.ListCtrl(size=(560,240), pos=(10,10), style=wLcReport or wBorderDouble or wLcSingleSel)
    var il = ImageList(size=(16,16), mask=false, initialCount=0)
    il.add(blueIcon)
    il.add(redIcon)
    il.add(checkIcon)
    list.setImageList(il)
    list.appendColumn(text="Column 0", width=150)
    list.setColumnFormat(0, wListFormatLeft)
    list.appendColumn(text="Column 1", width=110, format=wListFormatRight)
    list.appendColumn(text="Column 2", width=110, format=wListFormatRight)
    list.appendColumn(text="Column 3", width=wListAutosizeUseHeader)
    
    var imgIndex: int
    for i in 0..10:
      imgIndex = 1
      if (i mod 2) == 0: imgIndex = 0
      if (i mod 3) == 0: imgIndex = 2
      list.appendItem([$i&"-0", $i&"-1", $i&"-2", $i&"-3"], imgIndex)
    
    frame.wIdExit do (): 
      frame.delete()
    
    frame.center()
    frame.show()
    
    app.mainLoop()
    Alles anzeigen
  • [gelöst] wListCtrl - keine Mehrspaltenanzeige bei Verwendung von ItemImage?

    • Oscar
    • 15. September 2020 um 12:45
    Zitat von BugFix

    Jedoch wird bei Verwendung des Styles: wLcIcon/wLcSmallIcon dann nur die erste Spalte der Liste angezeigt.

    Den IconStyle "wLcSmallIcon" weglassen! Der ist nur für den IconView-Modus.

    Wenn Du den Mehrspaltenmodus brauchst, dann nur die Imagelist zuweisen und den ImageIndex übergeben.

  • Problem mit Übergabe Datumsfunktion

    • Oscar
    • 11. September 2020 um 17:18
    Zitat von BugFix

    Insofern kann jede Jahreszahl als valide angenommen werden. Tut keinem weh.

    Ja, ok! Das Jahr könnte man weglassen (wobei die Jahre ab 1000 wohl als "gesichert" gelten, davor gab es ja einige "Meinungsverschiedenheiten" bei den Päpsten).

    Aber den Monat solltest Du schon testen, denn getDaysInMonth prüft den nicht.

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      result = if (m in 1..12) and
        (d in 1..getDaysInMonth(cast[Month](m), y)): true else: false
    
    echo dateIsValid(2020, 2, 29)
  • [Nim] nimble Update

    • Oscar
    • 11. September 2020 um 17:01
    Zitat von Bitnugger

    habt ihr keine Idee, woran das liegen könnte? Macht mich echt kirre, dass ich Nim nicht bzw. nicht mehr richtig ans Laufen bekomme.

    Hast Du VSCodium über scoop installiert scoop install vscodium?

    Ich habe nämlich gerade ein Update gemacht scoop update vscodium und bei mir läuft das neue VSCodium (v1.49) problemlos.

  • Problem mit Übergabe Datumsfunktion

    • Oscar
    • 11. September 2020 um 16:41
    Zitat von BugFix

    Aber mir ging es darum, dass ich von meiner dateAdd-Funktion den Rückgabetyp DateTime bekomme. Da kann ich bei interner Prüfung nicht plötzlich "false" zurückgeben. Ich muss die Fehlermeldung also im erwarteten Datentyp unterbringen.

    Ich dachte an ein "Fehler-Datum" (z.B. 01.01.0001):

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      result = if (y in 1000..2999) and (m in 1..12) and
        (d in 1..getDaysInMonth(cast[Month](m), y)): true else: false
    
    proc dateAdd(datefunc: proc (x: int): TimeInterval{.inline, noSideEffect, gcsafe, locks: 0.},
                 count: int, year: int = -1, mon: int = -1, day: int = -1): 
                 DateTime =
    # [...]
      if not dateIsValid(year, mon, day):
        let dtError = initDateTime(cast[MonthdayRange](1), cast[Month](1), 1, 0, 0, 0, local())
        return dtError
    Alles anzeigen
  • Problem mit Übergabe Datumsfunktion

    • Oscar
    • 11. September 2020 um 16:31
    Zitat von BugFix

    Ja klar (geht übrigens kürzer ;) )

    Naja, Du testest ja auch nur den Tag, aber mit getDaysInMonth geht's wirklich kürzer:

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      result = if (y in 1000..2999) and (m in 1..12) and
        (d in 1..getDaysInMonth(cast[Month](m), y)): true else: false
    
    echo "Date is valid: ", dateIsValid(2020, 2, 29)
  • Bug in Nim: Wertebereich bei 32Bit Integer

    • Oscar
    • 11. September 2020 um 08:57
    Zitat von BugFix

    Nach 10 Minuten schon die Lösung - schau bitte ins Nim Forum.

    Ok, das ist schnell und es löst das Problem.

    Aber:

    Zitat


    Default literals are of int type.

    Ok, kann ich noch nachvollziehen.

    Ich denke aber, dass die Erkennung der einzelnen Datentypen dann trotzdem "fehlerhaft" ist.

    Warum kann man 0x7FFFFFFF der Variablen ohne Zusatz zuweisen und ab 0x80000000 nicht mehr?

    Bis 0xFFFFFFFF ist es doch eindeutig ein 32-Bit-Datentyp (ganz egal ob signed oder unsigned).

  • Bug in Nim: Wertebereich bei 32Bit Integer

    • Oscar
    • 10. September 2020 um 05:13

    Da läuft etwas falsch!

    Man kann einer uint32-Variablen keinen Wert größer als 0x7FFFFFFF zuweisen. Ab 0x80000000 kommt als Fehler: Error: type mismatch: got <int64> but expected 'uint32'

    Code
    var test: uint32 = 0x7FFFFFFF # <- geht noch
    test = 0x80000000 # <- geht nicht mehr Error: type mismatch: got <int64> but expected 'uint32'

    BugFix : Könntest Du mal wieder einen Bugreport schreiben?

  • Problem mit Übergabe Datumsfunktion

    • Oscar
    • 9. September 2020 um 19:20
    Zitat von BugFix

    Errorhandling ist tatsächlich etwas, wo man durch AutoIt verwöhnt ist. Es gibt kein Errormakro und somit ist das Signalisieren von Fehlern recht umständlich. Aber: Man kann nicht alles haben.

    Du könntest das Datum doch auch in einer eigenen Funktion überprüfen:

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      const aDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      if not (y in 1000..2999): return false
      if not (m in 1..12): return false
      if not (d in 1..aDays[m] + (if m == 2 and isLeapYear(y): 1 else: 0)): return false
      return true
    
    echo "Date is valid: ", dateIsValid(2021, 2, 29)

    Edit: Da war noch ein kleiner Fehler drin. Ich hatte das "+1" mit im Array-Index. Behoben!

  • ColorConvert

    • Oscar
    • 9. September 2020 um 17:29
    Zitat von UEZ

    Ich weiß nicht, ob NIM diese Datenstruktur überhaupt implementiert hat.

    Nachdem ich jetzt ausgiebig gegoogelt habe, fand ich ein Beispiel für eine Union in Nim.

    Und daraus habe ich jetzt mal ein Beispiel erstellt:

    Python
    from strutils import toHex
    
    type
      ARGB* {.union.} = object
        c*: tuple[b, g, r, a: uint8]
        argb*: uint32
    
    var color: ARGB
    color.c.a = 0xFF
    color.c.r = 0xAA
    color.c.g = 0xBB
    color.c.b = 0xCC
    
    echo color.argb.toHex
    color.argb = 0xFFE0D0C0'u32
    echo color.argb.toHex
    echo color.c.r.toHex
    Alles anzeigen

    Das ist etwas komplizierter und vom Zugriff her nicht so optimal, aber es funktioniert.

    So nebenbei habe ich dann auch mal Union verstanden. Danke, UEZ! :):thumbup:

    Edit: Code noch etwas gekürzt. So geht's auch.

    Edit2: Den Vorschlag von UEZ eingebaut. Jetzt als ARGB.

  • Problem mit Übergabe Datumsfunktion

    • Oscar
    • 9. September 2020 um 14:51
    Zitat von BugFix

    Das funktioniert soweit zufriedenstellend, nur werden die Funktionen 'weeks' und 'days' als Parameter nicht erkannt. Da habe ich keine Erklärung für.

    Das liegt daran, dass die beiden Funktionen zwei Mal vorhanden sind (einmal mit TimeInterval und einmal mit Duration).

    Du musst den Aufruf quasi zu dem TimeInterval zwingen:

    Code
    import times, tables
    
    # ------------------------------------------------------------------------------
    type
      ConditionPair[T] = object
        ifTrue, ifFalse: T
    
    # ternary operator: (cond ? if-true ! if-false)
    proc `!`*[T](a, b: T): ConditionPair[T] {.inline.} = 
      ConditionPair[T](ifTrue: a, ifFalse: b)
    
    template `?`*[T](cond: bool; p: ConditionPair[T]): T =
      (if cond: p.ifTrue else: p.ifFalse)
    # ------------------------------------------------------------------------------
    
    
    # ------------------------------------------------------------------------------
    # dateFunc: The procedure to use ('years', 'months', 'weeks', 'days')
    # count:    The count of units to add. Negative value for subtraction.
    # year:     The year for the start date. -1 (default) - the current year
    # mon:      The month for the start date. -1 (default) - the current month
    # day:      The day for the start date. -1 (default) - the current day
    # ------------------------------------------------------------------------------
    proc dateAdd(datefunc: proc (x: int): TimeInterval{.inline, noSideEffect, gcsafe, locks: 0.}, count: int, year: int = -1, 
                 mon: int = -1, day: int = -1): DateTime =
      let dtToday = now() # date Today
      let  # if default (-1) - Today-value
        y = year == -1 ? dtToday.year ! year
        m: Month = mon == -1 ? dtToday.month ! cast[Month](mon)
        d: MonthdayRange = day == -1 ? dtToday.monthday ! cast[MonthdayRange](day)
      let dtStart = initDateTime(d, m, y, 0, 0, 0, local())
      result = dtStart + (count.datefunc())
    # ------------------------------------------------------------------------------
    
    let dateFormat = initTimeFormat("dd'.'MM'.'yyyy")
    echo "Heute: ", now().format(dateFormat)
    
    var d = dateAdd(years, -2)
    echo "Heute -2 Jahre: ", d.format(dateFormat)
    
    d = dateAdd(years, 2)
    echo "Heute +2 Jahre: ", d.format(dateFormat)
    
    d = dateAdd(months, -3, 2016, 2, 28)
    echo "28.02.2016 -3 Monate: ", d.format(dateFormat)
    
    d = dateAdd(months, -5)
    echo "Heute -5 Monate: ", d.format(dateFormat)
    
    d = dateAdd(months, 5)
    echo "Heute +5 Monate: ", d.format(dateFormat)
    
    d = dateAdd(weeks, -3)
    echo "Heute -3 Wochen: ", d.format(dateFormat)
    
    d = dateAdd(weeks, 3)
    echo "Heute +3 Wochen: ", d.format(dateFormat)
    
    d = dateAdd(days, -21)
    echo "Heute -21 Tage: ", d.format(dateFormat)
    
    d = dateAdd(days, 14)
    echo "Heute +14 Tage: ", d.format(dateFormat)
    Alles anzeigen
  • ColorConvert

    • Oscar
    • 9. September 2020 um 11:16
    Zitat von UEZ

    du könntest UNION in TYPE verwenden, um r, g, b, a mit z.b. col als Int32 zu vereinen.

    Würde ich versuchen, wenn ich wüsste wie...

  • ColorConvert

    • Oscar
    • 9. September 2020 um 08:52

    Funktionen in Nim, um Farbwerte zwischen RGB und BGR und zwischen RGB und HSV umzuwandeln konnte ich nicht finden, also habe ich das mal selbst geschrieben.

    Ich habe die Funktionen überladen, sodass man sowohl einen int32 Wert übergeben kann, als auch drei Einzelwerte für RGB bzw. HSV. Außerdem gibt es noch jeweils ein Objekt für die Beiden.

    Bei RGB:

    Die Werte für R, G und B liegen jeweils zwischen 0...255 (0x00...0xFF).

    Bei HSV:

    Der Wert für H liegt zwischen 0...359. Und die Werte für S und V zwischen 0.00...100.00

    Das Modul:

    Code
    import math
    
    type
      RGB* = object
        r*, g*, b*: uint8
      HSV* = object
        h*, s*, v*: float
    
    # Farbwerte von Red, Green, Blue (RGB) nach int32 konvertieren
    proc toInt32*(r, g, b: uint8): int32 =
      result = (int32(r) shl 16) or (int32(g) shl 8) or int32(b)
    
    # toInt32 mit RGB-Object (Funktion ueberladen)
    proc toInt32*(rgb: RGB): int32 =
      result = toInt32(rgb.r, rgb.g, rgb.b)
    
    # Farbwert von Red, Green, Blue (RGB) nach Blue, Green, Red (BGR) und umgekehrt
    proc switchColor*(c: int32): int32 =
      result = ((c and 0x00FF0000) shr 16) or (c and 0x0000FF00) or ((c and 0x000000FF) shl 16)
    
    # switchColor mit drei Einzelwerten (Funktion ueberladen)
    proc switchColor*(r, g, b: uint8): int32 =
      result = switchColor(toInt32(r, g, b))
    
    # Minimumwert ermitteln aus mehreren Floats (mit Maxwert von 1.0)
    # Nur fuer modulinterne Aufgaben!
    proc myMin(f: varargs[float]): float =
      result = 1.0
      for v in f:
        if v < result: result = v
    
    # Maximumwert ermitteln aus mehreren Floats (mit Minwert von 0.0)
    # Nur fuer modulinterne Aufgaben!
    proc myMax(f: varargs[float]): float =
      result = 0.0
      for v in f:
        if v > result: result = v
    
    # Floatwert auf zwei Nachkommastellen beschraenken
    # Nur fuer modulinterne Aufgaben!
    proc myRound(x: float): float =
      result = floor(x * 100) / 100
    
    # Farbwert von Red, Green, Blue (RGB) nach Hue, Saturation, Value (HSV)
    # Das Ergebnis (HSV-Object) sind drei Floatwerte (mit max. zwei Nachkommastellen).
    proc RGBtoHSV*(c: int32): HSV =
      var r, g, b, minV, maxV, del, h: float
      r = ((c and 0x00FF0000) shr 16).toFloat  / 255
      g = ((c and 0x0000FF00) shr 8).toFloat / 255
      b = ((c and 0x000000FF)).toFloat / 255
      minV = myMin(r, g, b)
      maxV = myMax(r, g, b)
      del = maxV - minV
      result.v = myRound(maxV * 100)
      if del == 0:
          result.h = 0
          result.s = 0
      else:
        result.s = myRound((del / maxV) * 100)
        if maxV == r: h = 60 * (0 + (g - b) / del)
        if maxV == g: h = 60 * (2 + (b - r) / del)
        if maxV == b: h = 60 * (4 + (r - g) / del)
        if h < 0: h += 360
        result.h = myRound(h)
    
    # RGBtoHSV mit drei Einzelwerten (Funktion ueberladen)
    proc RGBtoHSV*(r, g, b: uint8): HSV =
      result = RGBtoHSV(toInt32(r, g, b))
    
    # RGBtoHSV mit RGB-Object (Funktion ueberladen)
    proc RGBtoHSV*(rgb: RGB): HSV =
      result = RGBtoHSV(toInt32(rgb))
    
    # Farbwert von Hue, Saturation, Value (HSV) nach Red, Green, Blue (RGB)
    # Das Ergebnis (RGB) wird als int32 ausgegeben
    proc HSVtoRGB*(hsv: HSV): int32 =
      var
        h, s, v, f: float
        iH, iV, iP, iQ, iT: uint8
        res: RGB
      h = hsv.h
      s = hsv.s / 100
      v = hsv.v / 100
      f = h / 60 - floor(h / 60)
      v *= 255
      iH = uint8(floor(h / 60) mod 6)
      iV = uint8(v)
      iP = uint8(v * (1 - s))
      iQ = uint8(v * (1 - f * s))
      iT = uint8(v * (1 - (1 - f) * s))
      case iH
      of 0: res = RGB(r: iV, g: iT, b: iP)
      of 1: res = RGB(r: iQ, g: iV, b: iP)
      of 2: res = RGB(r: iP, g: iV, b: iT)
      of 3: res = RGB(r: iP, g: iQ, b: iV)
      of 4: res = RGB(r: iT, g: iP, b: iV)
      else: res = RGB(r: iV, g: iP, b: iQ)
      result = res.toInt32
    
    # HSVtoRGB mit drei Einzelwerten (Funktion ueberladen)
    proc HSVtoRGB*(h, s, v: float): int32 =
      result = HSVtoRGB(HSV(h: h, s: s, v: v))
    Alles anzeigen

    Und das Beispiel:

    Python
    import ColorConvert
    from strutils import toHex
    
    let
      r: uint8 = 0xAA
      g: uint8 = 0xBB
      b: uint8 = 0xCC
    
    let bgrColor = toInt32(b, g, r) # die drei Einzelwerte nach int32 konvertieren
    echo "Color (BGR): 0x", bgrColor.toHex
    
    let rgbColor = bgrColor.switchColor # switch BGR <-> RGB
    echo "Color (RGB): 0x", rgbColor.toHex
    
    let hsvColor = RGBtoHSV(rgbColor) # Uebergabe als int32
    echo "Color (HSV): H = ", hsvColor.h, ", S = ", hsvColor.s, ", V = ", hsvColor.v
    
    let hsvColor2 = RGBtoHSV(0xAA, 0xBB, 0xCC) # Uebergabe mit drei Einzelwerten
    echo "Color (HSV): H = ", hsvColor2.h, ", S = ", hsvColor2.s, ", V = ", hsvColor2.v
    
    let rgbColor2 = HSVtoRGB(hsvColor) # Uebergabe mit HSV-Object
    echo "Color (RGB): 0x", rgbColor2.toHex
    
    let rgbColor3 = HSVtoRGB(210, 16.66, 80) # Uebergabe mit drei Einzelwerten
    echo "Color (RGB): 0x", rgbColor3.toHex
    Alles anzeigen

    Alles auch zum downloaden im Anhang.

    Dateien

    ColorConvert.zip 1,83 kB – 627 Downloads

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™