Anti-nuisance lawsuit warning: The purpose of these notes is to remind me, Zoegond, of stuff or to help me work stuff out. They may contain mistakes.

Quick

  • ($a, $b....) = unpack("A2A7...", $packed)
  • push( array, list )

Monday, November 4, 2024

Google Query empty dates

Some original research for a change! If you wish to match an empty date, eg Col4 = '' does not work.

The workaround I found was eg Col4 < date '1960-1-1' or whatever date you know is earlier than any date occurring in your data.

Tuesday, October 29, 2024

Google Query date specifications

(This is purely a rewriting of Ben Collins' excellent article so that I can grasp it easier)
  • Google Query has a keyword that introduces a date literal, date 'yyyy-mm-dd', and like other parts of GQ language it's limited and inflexible. You have to give it the format shown.
  • If your date criterion is a hard-coded date, you can just put that date in the string, eg Col2 >= date '1997-05-01'
  • But if as is more likely, your date comes from a spreadsheet cell, you have to manipulate it into yyyy-mm-dd format.
    • Spreadsheet function DATEVALUE(s) interprets s as a date in the same way that Google Sheets would if you literally typed s into a cell, ie using the locale settings you've got set for GS, and it returns a GS date number
    • Spreadsheet function TEXT(n, f) applies a format f to a number n to give a formatted string. Eg TEXT(0, "YYYY-MM-DD") = "1899-12-30"
  • So you simply apply DATEVALUE to your spreadsheet date, and TEXT( , "yyyy-mm-dd") to the result, and concatenate that into your query: "Col2 >= date '" & TEXT(DATEVALUE(thedate), "yyyy-mm-dd") & "'"
Thanks again, Ben.

Tuesday, October 8, 2024

Object oriented Autoit

Autoit3's maps and function pointers make it possible to put an OO style layer on it, in much the same way that you can with JS and Perl.

But the lack of a new keyword, and any kind of this mechanism, and namespaces, means more programmer discipline is required.

A class Doubler with a static method Doubler, and an object method DoubleMe:
https://pastebin.com/aETcFCYw

; Doubler.au3
#include-once

                                                       ;  class Doubler {
                                                       
func Doubler(byref $this, $n)                          ;  constructor(n) {
; properties
$this["n"] = $n                                        ;  this.n = n;
; methods
$this["Double"] = DoublerDouble                        ;  this.Double = DoublerDouble;
$this["DoubleMe"] = DoublerDoubleMe                    ;  this.DoubleMe = DoublerDoubleMe;
endfunc                                                ; 

func DoublerDouble(byref $this, $x)                    ;  Double(x) {
return $x*2                                            ;    return x*2;
endfunc                                                ;  }

func DoublerDoubleMe(byref $this)                      ;  DoubleMe() {
$this["n"] = $this["Double"]($this, $this["n"])        ;    this.n = this.double(this.n);
endfunc                                                ;  }

                                                       ; }
In use:
; main.au3                                             ;  let obj;
#include "Doubler.au3"

local $obj[]
$obj["constructor"] = Doubler                          ;
$obj["constructor"]($obj, 128)                         ;  obj = new Doubler(128);
MsgBox(0, "", $obj["Double"]($obj, 32))                ;  alert(obj.Double(32));
;
$obj["DoubleMe"]($obj)                                 ;  obj.DoubleMe();
MsgBox(0, "", $obj["n"])                               ;  alert(obj.n);

You don't have to use an include file btw, but it's the best way to manage code in larger projects.

As I say, discipline is required:

  • You have to prefix, with the class name, the base names of the functions that are assigned to be methods, because they're in the single namespace that Au3 has.
  • You have to supply the object's map variable as first parameter to all its methods. (Strictly speaking you needn't do that with the constructor, and static methods, but I find it easier to be consistent and always supply the map variable.)
  • The aforesaid parameter must be byref if you want the method to modify any properties. Again, it's easier to be consistent and use byref for all methods.
But if you have to use Au3 to implement something, this is a way to avoid spaghetti code and function/variable name collisions.

Map elements can be set to other maps, or arrays. So your object can 'has-a' another object. But take note that Au3 cannot do more than one layer of dereference:

; Not allowed!
; $obj["anotherObj"] = []
; $obj["anotherObj"]["constructor"] = OtherClass
; $obj["anotherObj"]["constructor"]( $obj["anotherObj"] )
;
; instead do it stepwise:
local $temp[]
$temp["constructor"] = OtherClass
$temp["constructor"]($temp)
$obj["anotherObj"] = $temp

It would be possible to write a 'Ootoit' preprocessor that translated a more sugary syntax into Au3 code that used these protocols. Rather in the style of the old RATFOR tool that put a C-style layer on top of Fortran.

Thursday, July 4, 2024

Perl rewind text file

You can rewind a text file with seek($fh, 0, 0), just as you can any other file.

But that doesn't reset $. - you do that manually with $. = 0 .

Followers

Blog Archive