public Login
alien Best Practice biblaridion biosphere bohemian rhapsody cars cat conspiracy theory Email energy efficiency Engineering Explained evolution ford raptor fun HTML Kevin Powell Mark Robbins mouse OSM postgres pyramid Python queen quote Reliability Residuality Theory Software Architecture Software Engineering sql Standardization tesla untagged window functions youtube
+ New

12 posts:

2025-01-25
https://pypi.org/project/osmnx/
2023-10-03

An Introduction to Residuality Theory

An Introduction to Residuality Theory - Barry O'Reilly - NDC Oslo 2023

2022-08-05

Custom HTML emails with an email expert

2022-05-14

Smash that like button

Design Theory : How I Re-Designed the Traditional Bass Guitar: Industrial Design Process

Smash that like button like it insulted your mother!

2021-01-24

Bohemian Cat

Hilarious Cat Memes All Cat Owners Will Be Able To Relate To

2021-01-24

Conspiracy Theory

Hilarious Cat Memes All Cat Owners Will Be Able To Relate To

2020-12-18

PostgreSQL Window Functions

A window clause consists of three optional parts, a partition clause, an order clause and a frame clause.

The partition clause is similar to a group by clause, except that it can only contain expressions, no output columns. Like the group by clause, it splits the output into parts which are processed independently.

The order clause specifies how rows within each partition are ordered.

The frame clause finally determines which rows are included in the window.

A row frame counts rows:

hjp=> select a, b, c, avg(c) over w
  from t
  window w as (
    partition by a
    order by b
    rows between 1 preceding and 1 following
  )
  limit 20;
╔═══╤════╤═══╤════════════════════╗
║ a │ b  │ c │        avg         ║
╟───┼────┼───┼────────────────────╢
║ 0 │  1 │ 7 │ 4.5000000000000000 ║ ┤ │
║ 0 │  3 │ 2 │ 4.6666666666666667 ║ │ ┤ │
║ 0 │  7 │ 5 │ 4.0000000000000000 ║   │ ┤ │
║ 0 │  7 │ 5 │ 5.3333333333333333 ║     │ ┤ │
║ 0 │  8 │ 6 │ 5.3333333333333333 ║       │ ┤ │
║ 0 │  8 │ 5 │ 4.3333333333333333 ║         │ ┤ │
║ 0 │  9 │ 2 │ 4.3333333333333333 ║           │ ┤ │
║ 0 │ 10 │ 6 │ 4.0000000000000000 ║             │ ┤
║ 1 │  1 │ 4 │ 6.5000000000000000 ║ ┤ │
║ 1 │  1 │ 9 │ 6.6666666666666667 ║ │ ┤ │
║ 1 │  3 │ 7 │ 6.6666666666666667 ║   │ ┤ │
║ 1 │  4 │ 4 │ 5.6666666666666667 ║     │ ┤ │
║ 1 │  5 │ 6 │ 6.0000000000000000 ║       │ ┤ │
║ 1 │  7 │ 8 │ 7.3333333333333333 ║         │ ┤ │
║ 1 │  8 │ 8 │ 5.6666666666666667 ║           │ ┤ │
║ 1 │  8 │ 1 │ 5.3333333333333333 ║             │ ┤
║ 1 │  9 │ 7 │ 4.0000000000000000 ║
║ 1 │ 10 │ 4 │ 5.5000000000000000 ║
║ 2 │  1 │ 5 │ 7.0000000000000000 ║ ┤ │
║ 2 │  2 │ 9 │ 6.3333333333333333 ║ │ ┤ 
╚═══╧════╧═══╧════════════════════╝
(20 rows)

Easy!

A group frame counts by groups of rows which are equivalent according to the row clause:

hjp=> select a, b, c, avg(c) over w
  from t
  window w as (
    partition by a
    order by b
    groups between 1 preceding and 1 following
  )
  limit 20;
╔═══╤════╤═══╤════════════════════╗
║ a │ b  │ c │        avg         ║
╟───┼────┼───┼────────────────────╢
║ 0 │  1 │ 7 │ 4.5000000000000000 ║ ┤ │
║ 0 │  3 │ 2 │ 4.7500000000000000 ║ │ ┤ │ │
║ 0 │  7 │ 5 │ 4.6000000000000000 ║   │ ┤ │ │ │
║ 0 │  7 │ 5 │ 4.6000000000000000 ║   │ │ ┤ │ │
║ 0 │  8 │ 6 │ 4.6000000000000000 ║     │ │ ┤ │ │
║ 0 │  8 │ 5 │ 4.6000000000000000 ║     │ │ │ ┤ │
║ 0 │  9 │ 2 │ 4.7500000000000000 ║         │ │ ┤ │
║ 0 │ 10 │ 6 │ 4.0000000000000000 ║             │ ┤
║ 1 │  1 │ 4 │ 6.6666666666666667 ║ ┤ │ │
║ 1 │  1 │ 9 │ 6.6666666666666667 ║ │ ┤ │
║ 1 │  3 │ 7 │ 6.0000000000000000 ║ │ │ ┤ │
║ 1 │  4 │ 4 │ 5.6666666666666667 ║     │ ┤ │
║ 1 │  5 │ 6 │ 6.0000000000000000 ║       │ ┤ │
║ 1 │  7 │ 8 │ 5.7500000000000000 ║         │ ┤ │ │
║ 1 │  8 │ 8 │ 6.0000000000000000 ║           │ ┤ │ │
║ 1 │  8 │ 1 │ 6.0000000000000000 ║           │ │ ┤ │
║ 1 │  9 │ 7 │ 5.0000000000000000 ║             │ │ ┤
║ 1 │ 10 │ 4 │ 5.5000000000000000 ║                 │
║ 2 │  1 │ 5 │ 6.3333333333333333 ║ ┤ │
║ 2 │  2 │ 9 │ 6.4000000000000000 ║ │ ┤
╚═══╧════╧═══╧════════════════════╝
(20 rows)

Here, lines 3 and 4 form a group (b = 7), and same for lines 5 and 6 (b = 8). So the value for line 4 is the average of lines 2 (preceding group), 3 and 4 (current group) and 5 and 6 (following group).

Finally, a range frame uses the value in the column (there can be only one) in the order clause instead of a count. So it can only be used with columns where a difference between values makes sense, such as numeric or timestamp columns.

hjp=> select a, b, c, avg(c) over w
  from t
  window w as (
    partition by a
    order by b
    range between 1 preceding and 1 following
  )
  limit 20;
╔═══╤════╤═══╤════════════════════╗
║ a │ b  │ c │        avg         ║
╟───┼────┼───┼────────────────────╢
║ 0 │  1 │ 7 │ 7.0000000000000000 ║ ┤
║ 0 │  3 │ 2 │ 2.0000000000000000 ║   ┤
║ 0 │  7 │ 5 │ 5.2500000000000000 ║     ┤ │ │ │
║ 0 │  7 │ 5 │ 5.2500000000000000 ║     │ ┤ │ │
║ 0 │  8 │ 6 │ 4.6000000000000000 ║     │ │ ┤ │ │
║ 0 │  8 │ 5 │ 4.6000000000000000 ║     │ │ │ ┤ │
║ 0 │  9 │ 2 │ 4.7500000000000000 ║         │ │ ┤ │
║ 0 │ 10 │ 6 │ 4.0000000000000000 ║             │ ┤
║ 1 │  1 │ 4 │ 6.5000000000000000 ║ ┤ │
║ 1 │  1 │ 9 │ 6.5000000000000000 ║ │ ┤
║ 1 │  3 │ 7 │ 5.5000000000000000 ║     ┤ │
║ 1 │  4 │ 4 │ 5.6666666666666667 ║     │ ┤ │
║ 1 │  5 │ 6 │ 5.0000000000000000 ║       │ ┤
║ 1 │  7 │ 8 │ 5.6666666666666667 ║           ┤ │ │
║ 1 │  8 │ 8 │ 6.0000000000000000 ║           │ ┤ │ │
║ 1 │  8 │ 1 │ 6.0000000000000000 ║           │ │ ┤ │
║ 1 │  9 │ 7 │ 5.0000000000000000 ║             │ │ ┤ │
║ 1 │ 10 │ 4 │ 5.5000000000000000 ║                 │ ┤
║ 2 │  1 │ 5 │ 6.3333333333333333 ║ ┤ │
║ 2 │  2 │ 9 │ 6.3333333333333333 ║ │ ┤
╚═══╧════╧═══╧════════════════════╝
(20 rows)

Line 2 has a value of 3 in the b column, so its window includes all rows with b between (3-1) and (3+1). That's only itself. But the next row has b = 7 and there are four rows with b between (7-1) and (7+1).


Docs

2020-10-25

Biblaridion

2020-06-25

Can You Charge A Tesla By Towing It? (With Ford Raptor)

https://www.youtube.com/watch?v=RaGVoB4Zn-Y

TLDR: Yes, and you get better mileage from first towing the tesla (using x amount of fuel) and then driving the tesla with this charge thsn from driving the raptor with the same amount of fuel, even though the fuel consumption of a raptor towing a tesla is insane.

as one commenter said:

What you’ve done is build a hybrid car.

2020-05-07

Go Debugger

The Go debugger is Delve.

The command to invoke it is dlv. In good old unix tradition, it lacks vowels :-).

You can't see the source before you started the program (actually I think I managed to do that once), but you can set a breakpoint:

(dlv) b /home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:20 Breakpoint 1 set at 0xaa54ef for wwuiserver_echo/concepts.TestGetMembersWithFilter() ./concepts/getmembers_test.go:20

And then you can run/continue the program:

``` (dlv) c INFO[0000] LoadConfig Configuration loaded from /home/hjp/wrk/wsr/wwui/wwui-backend/config.json INFO[0000] test db set up - committing
DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{109 17 26 Europa {{1 true}} [] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{110 17 27 Mitteleuropa {{2 true}} [0xc000288960 0xc000288a80] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{111 27 28 Tschechien {{10 true}} [] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{112 27 29 Slowakei {{20 true}} [] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{107 17 24 Deutschland {{0 false}} [] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{106 17 23 Österreich {{0 false}} [] false} DEBU[0000]/home/hjp/wrk/wsr/wwui/wwui-backend/concepts/getmembers_test.go:33 wwuiserver_echo/concepts.checksortOrder() checksortOrder &{108 17 25 Schweiz {{0 false}} [] false}

wwuiserver_echo/concepts.TestGetMembersWithFilter() ./concepts/getmembers_test.go:20 (hits goroutine(51):1 total:1) (PC: 0xaa54ef) 15: log.SetLevel(log.DebugLevel) 16: checksortOrder(t, response.Node) 17: } 18: 19: func TestGetMembersWithFilter(t *testing.T) { => 20: setupTestDb() 21: response, err := DB.GetMembers("wdstest", berichtsregionId, []string{"facttable_test"}) 22: assert.Equal(t, nil, err) 23: log.SetReportCaller(true) 24: log.SetLevel(log.DebugLevel) 25: checksortOrder(t, response.Node) (dlv) ```

2020-03-29

tcpdump und die Sommerzeit

Ein laufendes tcpdump bekommt einen Wechsel in die Sommerzeit nicht mit:

09:38:20.295018 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 09:38:20.352045 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 09:38:30.038081 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 09:38:30.094754 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 09:38:40.412256 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 09:38:40.412465 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 ^C 13082 packets captured 13084 packets received by filter 0 packets dropped by kernel tcpdump host 80.249.000.000 0.67s user 1.46s system 0% cpu 15:47:23.34 total fw-extern:~ 10:38 :-) 82# tcpdump host 80.249.000.000 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens1f0, link-type EN10MB (Ethernet), capture size 262144 bytes 10:39:00.325750 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 10:39:00.325944 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 10:39:10.300798 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 10:39:10.357433 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 10:39:20.073194 IP firewall.xxxx.at.openvpn > 80.249.000.000.58665: UDP, length 53 10:39:20.129962 IP 80.249.000.000.58665 > firewall.xxxx.at.openvpn: UDP, length 53 ^C 6 packets captured 7 packets received by filter 0 packets dropped by kernel

Offensichtlich verwendet es nicht localtime für jede Zeile und fragt beim Start einmal den Offset ab und rechnet dann selber weiter.

2020-03-28

Waage

Meine Personenwaage funktioniert seit ein paar Tagen nicht mehr. Sie zeigt erratische Werte and und schaltet sich nach kurzem ganz ab.

Ich dachte erst, die Batterien wären zu schwach, aber das wars nicht.

Eines der Gummifusserln ist abgebrochen und die Kraftmesser sitzen offenbar über den Fusserln. Wenn nicht alle 4 vier konsistente Werte liefern, verweigert die Waage die Anzeige.

Mit Tixo festgeklebt, funktioniert wieder.