go: Three dots/ellipses notation and variadic function; arrays vs slices

Go program example below explores arrays, slices and three dots notation. Arrays and slices are similar, arrays have static usage, slices are dynamic. Arrays are type values, fixed length sentences of items of the same type. Slices are reference types. A slice is a descriptor of an array segment. It consists of three parts: a pointer to the array, the length of the segment, and its capacity. Slice can be resized by append. If capacity would change, new slice is created with new reference descriptor!!! Example below shows, how to utilize variadic functions with slices. Variadic functions can have zero or many arguments of the same type. Variadic function can’t utilized arrays with three dots notation

Program below is also at https://play.golang.org/p/hoqXY5iRVBs

/* Three dots/ellipses notation and variadic function example
   (in go command ... means all files in the directory and subdirectories)
*/
package main

import (
	"fmt"
)

// show is a variadic function, it can have none or many arguments
func show(s ...string) {
	println()
	for i, val := range s {
		fmt.Printf("%d. %s\n", i, val)
	}
}
func main() {
	fmt.Println("Arrays are value types, fixed-length sequences of items of the same type.")
	fmt.Printf("Slices are reference types, can be resized by append.\n\n")

	seasons := []string{"Spring", "Summer", "Autumn", "Winter"} // slice
	choices := [2]string{"Good", "Bad"}
	days := [...]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}

	dsun := make([]string, 7, 7) //slice

	// Let's populate dsun with Sunday first
	for i, d := range days {
		if i == 6 {
			dsun[0] = d
		} else {
			dsun[i+1] = d
		}
	}

	fmt.Println("Length of slice seasons is", len(seasons), ", capacity is ", cap(seasons))
	fmt.Println("Length of slice dsun is", len(dsun), ", capacity is ", cap(dsun))
	fmt.Println("Length of array days is", len(days))
	fmt.Println("Length of array choices is", len(choices))

	show("a", "b")
	show(seasons...)
	// show(days...) //cannot use days (type [7]string) as type []string in argument to show
	// show(choices...) //cannot use choices (type [2]string) as type []string in argument to show
	show(dsun...)
	show("The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog")
}
Posted in golang, workday | Leave a comment

Inside of rotating acrylic globe

Did you ever see glassy spinning globe of Earth, Moon, Mars, or other planet? Did you ask question, how come, that is rotating? Orwille Wingnut was not satisfied with general answer, and he posted video, what is inside. See it inside.

 

It is actually invention of William French, who published video about his invention. He submitted his patent application in 1999, and he received US patent 6937125 for “Self rotating display spherical device”, and several follow up patents with name “Frictionless self-powered moving display”. There are two spheres inside each other. Inner sphere floats on two type of non mixable liquids, more dense at bottom. It is covered with graphics, for example map of Earth, and its semi-transparent, so solar cells inside can generate electricity. Permanent magnet keeps orientation towards to the magnetic field of Earth, and motor can rotate all inner sphere even with a little electrical energy from ambien light

Moon

If you bring magnet to upper part of globe just for 10 seconds or so, it will stop rotating. After minute it starts wobble back and forward again with very small angle. With time that angle is increasing., but even after one hour it still stops and goes a little bit back. Eventually it rotates only in one direction again.

Posted in household | Leave a comment

go: Concurrent records processing with channels

Let’s say we have list of records, which can be processed concurrently. Processing time can be different. In example below processing time depends on two parameters. There are used non buffered input and output channels. 

There are these steps:

  1. Submitting N go routines
  2. Writing N times into input channel
  3. Reading N times from output channel. This takes time of the longest go routine.
  4. Display updated records
// version 3 https://play.golang.org/p/2zU0ttZ9ZYn
// version 2 https://play.golang.org/p/qQ8bgVh-dwx (this one)
// version 1 https://play.golang.org/p/LKwVh8d44GQ
package main
import (
"fmt"
"time"
)
const timeFormat = "15:04:05"
type Record = struct {
name string
student bool
delay int //Seconds
}
type InpType = struct {
index int
nameLength int
student bool
}
type OutType = struct {
index int
duration int
}
var records = []Record{
Record{name: "Adam", student: true},
Record{name: "Bob", student: true},
Record{name: "Carl", student: false},
Record{name: "Dick", student: false},
Record{name: "Elisabeth", student: false},
}
func processName(inp <-chan InpType, out chan<- OutType) {
a := <-inp
duration := a.nameLength
if a.student {
duration += 10
}
b := OutType{index: a.index, duration: duration}
time.Sleep(time.Duration(duration) * time.Second)fmt.Printf("%s End of processing index %d\n", time.Now().Format(timeFormat), a.index)out <- b
}
func main() {
fmt.Println(Let's say we are going to process name records.Processing time(delay) in seconds depends on name length, and students take 10 s more.)
inp := make(chan InpType)
out := make(chan OutType)
for i := range records { _ = i go processName(inp, out)}var inpRec InpTypefor i, rec := range records { inpRec = InpType{index: i, nameLength: len(rec.name), student: rec.student} fmt.Printf("%s Channel input: %+v\n", time.Now().Format(timeFormat), inpRec) inp <- inpRec}
for i := range records { _ = i result := <-out records[result.index].delay = result.duration}
fmt.Printf("\nRecords after processing by go routines:\n")for i, rec := range records { fmt.Printf("%d: %+v\n", i, rec)}

}

Here is output:


Let's say we are going to process name records.
Processing time(delay) in seconds depends on name length, and students take 10 s more.

23:00:00 Channel input: {index:0 nameLength:4 student:true}
23:00:00 Channel input: {index:1 nameLength:3 student:true}
23:00:00 Channel input: {index:2 nameLength:4 student:false}
23:00:00 Channel input: {index:3 nameLength:4 student:false}
23:00:00 Channel input: {index:4 nameLength:9 student:false}
23:00:04 End of processing index 3
23:00:04 End of processing index 2
23:00:09 End of processing index 4
23:00:13 End of processing index 1
23:00:14 End of processing index 0

Records after processing by go routines:
0: {name:Adam student:true delay:14}
1: {name:Bob student:true delay:13}
2: {name:Carl student:false delay:4}
3: {name:Dick student:false delay:4}
4: {name:Elisabeth student:false delay:9}
Posted in golang, workday | Leave a comment

go: base64 decoding

Here is an example how to decode base64 encoded strings https://play.golang.org/p/iojjUKwvZvn
It uses encoding packages encoding/base64 and encoding/hex .

package main

import (
	"fmt"
	"encoding/base64"
	"encoding/hex"
)

func isAscii7printable(bytes []byte)(bool){
   for _, b := range bytes {
   	if b < 32 || b > 127 {
		return false
	}
   }
   return true
}

func main() {
	b64 := "QUJD"  //ABC
	b64  = "QUJD-" //illegal base64 data at input byte 4
	b64  = "QUIK"  //AB\n
	
	bytes, err := base64.StdEncoding.DecodeString(b64)
	if err != nil {
	   fmt.Println("Input string `", b64, "`has an error: ", err.Error())
	   return
	}
        hexBytes := make([]byte, hex.EncodedLen(len(bytes)))
	hex.Encode(hexBytes, bytes)
	
	fmt.Println("Decoding base64 encoded strings")
	fmt.Println("===============================")
	fmt.Printf("Base64: %s\n", b64)
	fmt.Printf("Length: %d bytes; %d bits\n", len(bytes), 8*len(bytes))
	fmt.Printf("Hex   : %s \n", hexBytes)	

	if isAscii7printable(bytes) {
		fmt.Println("String: "+string(bytes))
	} else {
		fmt.Println("There are non ASCII7 characters.")
	}
}

Output could be:
Decoding base64 encoded strings
===============================
Base64: QUIK
Length: 3 bytes; 24 bits
Hex : 41420a
There are non ASCII7 characters.

Or after commenting two b64 lines:
Decoding base64 encoded strings
===============================
Base64: QUJD
Length: 3 bytes; 24 bits
Hex : 414243
String: ABC

For decoding non printable characters is good to use hex.Dump, see https://play.golang.org/p/f6fQpbqeHo8

package main

import (
	"fmt"
	"encoding/base64"
	"encoding/hex"
)

func b64print(b64 string) {
	bytes, err := base64.StdEncoding.DecodeString(b64)
	fmt.Printf("Base64 : %s\n", b64)
	if err != nil {
	   fmt.Printf("Input string '%s' has an error: %s\n\n", b64, err.Error())
	   return
	}
	fmt.Printf("Decoded: length: %d bytes ~ %d bits, `hexdump -C` format:\n", len(bytes), 8*len(bytes))
	fmt.Printf("%s\n", hex.Dump(bytes))	
}

func main() {
	fmt.Println("Decoding base64 encoded strings")
	fmt.Printf("===============================\n\n")

        b64print("wrong")
	b64print("SGVsbG8gV29ybGQh")
	b64print("VGFsbCByZWQgdHJlZSBvbiB0aGUgcml2ZXIgYmFuay4=")
	b64print("QSBsYXp5IGZveCBqdW1wcyBvdmVyIHF1aWNrIGJyb3duIGRvZyEgRW1haWw6dTEwQG15LmV4YW1wbGUub3JnIA==")
}

Here is an output:
Decoding base64 encoded strings
===============================

Base64 : wrong
Input string 'wrong' has an error: illegal base64 data at input byte 4

Base64 : SGVsbG8gV29ybGQh
Decoded: length: 12 bytes ~ 96 bits, `hexdump -C` format:
00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 |Hello World!|

Base64 : VGFsbCByZWQgdHJlZSBvbiB0aGUgcml2ZXIgYmFuay4=
Decoded: length: 32 bytes ~ 256 bits, `hexdump -C` format:
00000000 54 61 6c 6c 20 72 65 64 20 74 72 65 65 20 6f 6e |Tall red tree on|
00000010 20 74 68 65 20 72 69 76 65 72 20 62 61 6e 6b 2e | the river bank.|

Base64 : QSBsYXp5IGZveCBqdW1wcyBvdmVyIHF1aWNrIGJyb3duIGRvZyEgRW1haWw6dTEwQG15LmV4YW1wbGUub3JnIA==
Decoded: length: 64 bytes ~ 512 bits, `hexdump -C` format:
00000000 41 20 6c 61 7a 79 20 66 6f 78 20 6a 75 6d 70 73 |A lazy fox jumps|
00000010 20 6f 76 65 72 20 71 75 69 63 6b 20 62 72 6f 77 | over quick brow|
00000020 6e 20 64 6f 67 21 20 45 6d 61 69 6c 3a 75 31 30 |n dog! Email:u10|
00000030 40 6d 79 2e 65 78 61 6d 70 6c 65 2e 6f 72 67 20 |@my.example.org |

Posted in golang, workday | Leave a comment

go: characters frequency

Let’s explore characters frequency in the go string. Characters in go are in the format int32 – rune, and they can have any unicode value. Here is a simple go program https://play.golang.org/p/fbg7VXetxCg .

package main

import (
	"fmt"
	"sort"
)
func runeCharsFrequency(inpStr string) string {
	m := make(map[rune]int)
	for _, runeChar := range inpStr {
		m[runeChar]++
	}
	var keys []rune
	for kRune, _ := range m {
		keys = append(keys, kRune)
	}
	sort.Slice(keys, func(i, j int) bool {
		return keys[i] < keys[j]
	})

	outStr := ""
	comma := ""
	for _, k := range keys {
		outStr += fmt.Sprint(comma, k, ":", m[k])
		comma = ", "
	}
	return outStr
}
func main() {
        s := "Hello World!!!!!"
	fmt.Println("Characters frequency in string: "+s)
	fmt.Println(runeCharsFrequency(s))
}

Characters in the output have ordinal value and count:
32:1, 33:5, 72:1, 87:1, 100:1, 101:1, 108:3, 111:2, 114:1

Posted in golang, workday | Leave a comment

go: duration loop

Here is a simple duration loop go program https://play.golang.org/p/ly9U9EUr2of

package main

import (
	"fmt"
	"time"
)

func main() {
	duration := time.Second *10
	fmt.Println("Hello, duration loop "+duration.String()+" long")
	
	t1 := time.Now()
	
	for t2:= time.Now(); t2.Sub(t1) < duration; t2 = time.Now(){
	   	fmt.Println(t2.String())
		time.Sleep(time.Second)
	
	}
}

Posted in golang, workday | Leave a comment

go: proverbs

Rob Pike at Gopherfest on November 18, 2015 mentioned several thoughtful go proverbs, as you may see on this video. Here they are:

  1. Don’t communicate by sharing memory, share memory by communicating.
  2. Concurrency is not parallelism.
  3. Channels orchestrate; mutexes serialize.
  4. The bigger the interface, the weaker the abstraction.
  5. Smaller the interface, more useful.
  6. Make the zero value useful.
  7. interface{} says nothing.
  8. Gofmt’s style is no one’s favorite, yet gofmt is everyone favorite.
  9. A little copying is better than a little dependency.
  10. Syscall must always be guarded with build tags.
  11. Cgo must always be guarded with build tags.
  12. Cgo is not Go.
  13. With the unsafe package there are no guarantees.
  14. Clear is better then clever.
  15. Reflection is never clear.
  16. Errors are values.
  17. Don’t just check errors, handle them gracefully.
  18. Design the architecture, name the components, document the details.
  19. Documentation is for users.

Many more proverbs possible, but they must be short, poetic, general, about Go more than about programming. Contradictory is OK. Life and programming are full of contradictions.

Greg Osuri made Go proverbs illustrated.

Posted in golang, workday | Leave a comment

go: printing struct & array

Printing struct https://play.golang.org/p/BvMIqF3Pmc9

package main

import "fmt"

type point struct {
    x, y int
}

func main() {
    p := point{1, 2}
    fmt.Println("Printing struct point:")
    fmt.Printf(" type          %%T: %T\n", p)
    fmt.Printf(" just values   %%v: %v\n", p)
    fmt.Printf(" +field names %%+v: %+v\n", p)
    fmt.Printf(" go syntax    %%#v: %#v\n", p)
    fmt.Println()

    ptr := &p
    fmt.Println("Printing pointer to struct point:")
    fmt.Printf(" type          %%T: %T\n", ptr)
    fmt.Printf(" just values   %%v: %v\n", ptr)
    fmt.Printf(" +field names %%+v: %+v\n", ptr)
    fmt.Printf(" go syntax    %%#v: %#v\n", ptr)
    fmt.Println()

    arrP := []point{point{1, 2},point{3, 4}}
    fmt.Println("Printing array of struct points:")
    fmt.Printf(" type          %%T: %T\n", arrP)
    fmt.Printf(" just values   %%v: %v\n", arrP)
    fmt.Printf(" +field names %%+v: %+v\n", arrP)
    fmt.Printf(" go syntax    %%#v: %#v\n", arrP)
}

Output:

Printing struct point:
 type          %T: main.point
 just values   %v: {1 2}
 +field names %+v: {x:1 y:2}
 go syntax    %#v: main.point{x:1, y:2}

Printing pointer to struct point:
 type          %T: *main.point
 just values   %v: &{1 2}
 +field names %+v: &{x:1 y:2}
 go syntax    %#v: &main.point{x:1, y:2}

Printing array of struct points:
 type          %T: []main.point
 just values   %v: [{1 2} {3 4}]
 +field names %+v: [{x:1 y:2} {x:3 y:4}]
 go syntax    %#v: []main.point{main.point{x:1, y:2}, main.point{x:3, y:4}}
Posted in golang, workday | Leave a comment

go: add elements to array

Here is one way, how to add elements to array in go language, see https://play.golang.org/p/nCLX23ymRUM

package main

import (
	"fmt"
)

type MyRecord struct {
	Name  string
	Phone string
}

var recA = MyRecord{Name: "Anna", Phone: "123"}
var recB = MyRecord{Name: "Bob", Phone: "456"}

type Records []MyRecord

func buildAppendedArrayPtr() {
	arr := make(Records, 0)
	arrPtr := &arr
	arrPtr = appendToArrayPtr(arrPtr, recA)
	arrPtr = appendToArrayPtr(arrPtr, recB)

	fmt.Printf("%v %T %d \n", arrPtr, arrPtr, len(*arrPtr))

	for i, rec := range *arrPtr {
		fmt.Printf("%d. %v\n", i, rec)
	}
}

func appendToArrayPtr(recordsPtr *Records, myRecord MyRecord) *Records {
	arr := append(*recordsPtr, myRecord)
	return &arr
}

func main() {
	buildAppendedArrayPtr()
}

Posted in golang, workday | Leave a comment

GIMP: first script-fu

GIMP is great tool for images manipulation. Even better is to automate as much as possible through scripts.
Lets say we would create file named my-first.scm and this file will be placed into sub-directory scripts. Location would depend on the operation system.
Here is example from Windows 10:
C:\Users\JoeDoe\AppData\Roaming\GIMP\2.10\scripts\my-first.scm

File could have content:

(define (ten) (+ 5 5))
(define (square x) (* x x))

In GIMP, scripts have to be refreshed: Filters/Scripts-Fu/Refresh scripts
Then we can open console Filters/Script-Fu/Console and in command line write command:
(ten)
We should see output 10.
(square 5)
We should see output 25.

At https://stackoverflow.com/questions/5811378/how-do-i-write-a-custom-auto-crop-script-using-the-gimp has been published very useful Edger Script. If you would copy and paste it into file, let’s say C:\Users\JoeDoe\AppData\Roaming\GIMP\2.10\scripts\my-edger.scm and then refresh scripts. Script takes arguments input-file, output file, top, right, bottom, left. Example executing it from the console is below:

(script-fu-wirebear-edger "I:\\Pictures\\IMG-000.png" "I:\\Pictures\\Edged-IMG-000.png" 10 20 30 40)
Posted in workday | Leave a comment