Worker or Craftsman

Yesterday morning I was contacted by an entrepreneur that needs to talk to me about his problem: He can’t find developers to make some tasks.

He says that pay is good (for every single task), I can also offer in future a part-time job (Wow – ironic).

My answer was nothing of special: the world needs developers but they are few, often also not qualified people do this job and so on (he already said that with no-code everyone can develop, I have a different idea about it, move the problem only on the next step, but it’s off-topic in this post).

In the end, I have suggested he try to find on the freelancer’s website, maybe asking some simple task to verify the quality of the developer.

Today morning, while I reading the last book of Adam Grant (Think again) I had a flash-bak, and rethink to these things, I remember his words: at the end I need workers.

Maybe I found the problem, what he thinks of the developers.

The problem is the word workers (also because honestly, there is always someone smart that want to do some little task for more money).

I respect the worker (an important job as every job) but the developer is more a craftsman than a worker, from a romantic point of view this job is science and art. Develop require focus, study, …

I think that any developers don’t want to be defined as a worker, he is a craftsman, he has relations with every software developed. So, my friend, maybe you don’t find it because you search for the wrong people. Good luck (i don’t know if I’ll advise you of the mistake, I’m a worker, not a psychologist).

The reference to the book can be casual, but if it interesting you https://amzn.to/3ciClHm

Swift in five minutes

In this post, I’ll show the fundamentals of the Swift language. It’s the first of a series where I’ll show how to build a chat app using Swift and SwiftUI.

Let’s start with the simpler things, comments, variables and constants:

// It's a line comment

/*
   This is a multiline
   comment
*/

// Variable definition:
// var varname: Type = Initial value

var name: String = "Nicola"

The variables are defined using the “var” keyword, a name, after the “:” we must write the type of the variable (String, Double, Float, Array, Set,..)

The variable can be also declared shortly, omitting the type and setting directly the value, in this case, the variable gets the type of the value.

// declaring an int variable omitting the type
var age: 10 // age is an integer

The constants are declared in the same way, apart from using the “let” keyword and that they can get only a value that can be changed.

let pi = 3.14

pi = 4 // Error can't change costant value

In Swift we can declare a variable as optional, the variable can assume every value of the type defined and the “null” value. In this way, the nulla value became a possible value for that variable. An optional variable is defined appending the “?” to the type:

var myOpt: Int?
myOpt = 3

// to get the myOpt value
if let value = myOpt { 
    print("Value \(value)")
} else {
    print("null")
}

// it's equivalent to
if myOpt != nul {
  var value = myOpt!
  print("Value \(value)")
} else {
  print("null")
}

Note the “!” after myOpt, using the “!” we force to get the value of myOpt. Use it only when you are sure that the variable is not null, otherwise you can have some crash due to null pointer exception.

About the conditional statement, you find the classic:

if condtion {
} else if condition {
} else {
}

// Locic operator
// && for a and b
// || for a or b
// == for a equal b
// != for b not equal b

In swift the “condition” not need to have enclosed in () how in other languages (i.e. C).

See other types: Array, Tuple and Set.

// Array declaration
// var name: Array<Type>

// Example
var numbers: Array<Int> // at this moment the numbers is nill

// To be able to make operation on the array we must initialize

numbers = Array<Int>() // now we have an empty array

numbers.append(3) // add the number 3
numbers.append(1) // add the number 1

To iterate the elements of the array (or other collections) we need the control flow, in this case, the for loop.

for i in 0..<numbers.count { // from zero to 1
    print("numbers[\(i)] = \(numbers[i])")
}

In the previous code we iterate the numbers vector operating on a sequence in the range 0..<numbers.count . In this case 0..<2, mean that i can assume the value 0,1.

A range can be defined in this way:

var firstTenA = 0...10 // all the number from 0 to 10
var firstTenB = 0..<11 // all the number from 0 to 10
// with the < we exclude the value on the right
// Other version of the for loop see before
for i in 0...(numbers.count - 1) { // from zero to 1
    print("numbers[\(i)] = \(numbers[i])")
}

Note if you want to iterate in reverse order, you must use the reverse method :

for i in (0..<numbers.count).reversed() { 
    print("numbers[\(i)] = \(numbers[i])")
}

It possible also iterate directly on the vector:

for elem in numbers {
    print(elem)
}

About the iteration, look at the String, we can’t iterate the string with int index but using the indices.

var name: String = "Bob"
// write every single character of the string
for i in name.indices {
    print(name[i])
}

Other controls flow: while and repeat while

var counter = 10
while counter > 0 {
    print(counter)
    counter = counter - 1
}

repeat {
    print(counter)
    counter = counter + 1
} while counter < 10


How in other programming languages the code in the while is executed until the condition is true, instead of with the repeat while, the code is executed at least one time.

Another collection type is the dictionary, it’s a list of pair key and value.

var dict: [Int: String] = [Int: String]()
dict[404] = "Not found"

for key in dict.keys {
    print(key)
}

for value in dict.values {
    print(value)
}


In the code, we see the declaration of a dictionary where the key is an Int and the value is a String. It’s possible to access the element using the key in [], instead, it’s possible to iterate the key and the values using the methods keys and values.

The next step is to see how to declare and use the functions.

func nameLastName(name a: String, lastname b: String ) {
    print("Name \(a) Lastname \(b)")
}

The function is declared using the keyword func, the parameters are passed indicating a label, a name of the parameter and the type.

You can see the label as a help for the programmer, it explains what the parameter means, instead the name is used in the body of the function. To invoke that function:

nameLastName(name: "Bob", lastname: "Rossi")

It’s possible to declare also the function without the labels:

func nameLastName(a: String, b: String ) {
    print("Name \(a) Lastname \(b)")
}

// In this case the function is called in this way
nameLastName(a: "Bob", b: "Rossi")

In the end, it’s possible to declare the function to avoid the use of the name in the call.

func nameLastName(_ a: String, b: String ) {
    print("Name \(a) Lastname \(b)")
}

// In this case the function is called in this way
nameLastName("Bob", b: "Rossi")

The function can return also a value:

// Function that returns an Int
func squareRect(width: Int, height: Int) -> Int {
    let sup = width * height
    return sup
}

print(squareRect(width: 4, height: 5))

The type returned is indicated by the symbol “->”.

In Swift the parameter are passed for value, it means that we can’t change the value of the parameters in the body of the function, to make it we have to use the keyword inout in this way:

// Swap the value of two element
func swap(a: inout Int, b: inout Int) {
    let dum = a
    a = b
    b = dum
}

var first = 3
var second = 4

// Call the functions using "&" near the parameters
swap(a: &first, b: &second)

A type a bit different from other languages is the Enum. Here an example:

enum Polar: Int {
    case north = 1
    case sud, west, est
    func description() -> String{
        switch self {
        case .north:
            return "North"
        case .est:
            return "Est"
        case .west:
            return "West"
        case .sud:
            return "Sud"
        }
    }
}

The enum can have also a type (Int in the example), it’s possible to assign a specified value at every element of the enum. The big difference in Swift is that it’s possible to declare also e function in an Enum and invoke it.

var sanFrancisco = Polar.west

print(sanFrancisco.description()) // print "West"

Now see the data structure, the first one is the struct.

struct Coordinate {
    var lat: Double
    var long: Double
    
    func xy() {
       print("Lat = \(lat) and Long = \(long)")
    }
}

How in the example the struct is a data structure that can contain properties (variables, constants) and methods (function).

Very similar is also the declaration of the class:

class ClassCoordinate {
    var lat: Double
    var lon: Double
    init(lat: Double, lon: Double) {
        self.lat = lat
        self.lon = lon
    }
    
    func invert() {
        let dum = lat
        lat = lon
        lon = dum
    }
    
    func coord() -> String {
        return ("(\(lat),\(lon))")
    }
}

The big difference between class and the structures is that the struct is a value type, so if we have two variables of the same structure type, and assign the second to one, in the first is copied the value of the second.

var coordA = Coordinate(lat: 37.3382, long: 121.8863)
var coordB = Coordinate(lat: 37.3382, long: 121.8864)
var coordC = Coordinate(lat: 37.3382, long: 121.8865)

print("Point A \(coordA) Point B \(coordB)")
coordA = coordB
print("Point A \(coordA) Point B \(coordB)")
coordB = coordC
print("Point A \(coordA) Point B \(coordB)")

/*
Produce this output
Point A Coordinate(lat: 37.3382, long: 121.8863) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8865)
*/

With the class it’s is different, the class is a reference type, so when a second class is assigned to the first class, is not copied the value but the reference, so they are the same object. If you change one, change the values of the other.

var coordClassA = ClassCoordinate(lat: 37.3382, lon: 121.8863)
var coordClassB = ClassCoordinate(lat: 37.3382, lon: 121.8864)

print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")
coordClassA = coordClassB
print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")
coordClassB.lat = 1
coordClassB.lon = 2
print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")

/*
The output is
Point A Coordinate(lat: 37.3382, long: 121.8863) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8865)
Point A (37.3382,121.8863) Point B (37.3382,121.8864)
Point A (37.3382,121.8864) Point B (37.3382,121.8864)
Point A (1.0,2.0) Point B (1.0,2.0)
*/

When to use the struct and when to use the class? When the data struct is big is better to use a class because the reference doesn’t duplicate data (and consuming memory) but the reference requires more attention.

To conclude I introduce the protocol, it’s defined in the Swift documentation as: “A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality”. If a class have to conform to a protocol it must implement the function and property request from the protocol.

protocol PrintProtocol {
    var simpleLabel: String {get}
    mutating func translate()
}

class CoordinateClass: PrintProtocol {
    var lat: Double
    var lon: Double
    var simpleLabel: String = ""
    
    init(a: Double, b: Double)
    {
        self.lat = a
        self.lon = b
    }
    func translate() {
        self.lat = self.lat * 2
        self.lon = self.lon * 2
    }
}

In this case, the PrintProtocol requires that a class that using it, have to declare a variable simpleLabel (get, it possible read the value) and implement a function translate. This function is mutating, it can modify the property of the class.

In the next post, I’ll start to talk about SwiftUI. This post is not frozen, I’ll change it to improve or add important things that I skipped for now.

Note: English is not my native language, so I’m sorry for some errors. I appreciate it if your correct me.

SwiftUI and Shake Gesture

There isn’t a way to catch the shake gesture only using SwiftUI, so it’s necessary use these frameworks: Uikit and Combine.

Combine is very helpful in this case because how is wrote in the Apple documentation: “Combine declares publishers to expose values that can change over time, and subscribers to receive those values from the publishers.”

In the example, the goal is catch the Shake gesture with the UiKit, with the Combine framework we publish this event and get the combine published info in the SwiftUI view that is a subscriber. Let’s start.

We must create a Swift file, ShakeGestureManager.swift

import Foundation
import SwiftUI
import Combine
let messagePublisher = PassthroughSubject<Void, Never>()
class ShakeViewController: UIViewController {
override func motionBegan(_ motion: UIEvent.EventSubtype,
                              with event: UIEvent?) {
        guard motion == .motionShake else { return }
        messagePublisher.send()
    }
}
struct ShakeViewRepresentable: UIViewControllerRepresentable {
    
    func makeUIViewController(context: Context) ->
        ShakeViewController {
            ShakeViewController()
    }
func updateUIViewController(_ uiViewController: ShakeViewController,
                                context: Context) {
        
    }
}



Where the PassthroughSubject is a “A subject that broadcasts elements to downstream subscribers.” (from the Apple documentation). We need it to communicate with the SwiftUI View.

The ShakeViewController is a simple UIViewController that catches the shake Gesture. Like in the case of the Map, it’s not possible to use the UIViewController in the SwiftUI so we must create a struct that implement the UIViewControllerRepresentable that we can use in the SwiftUI View.

Now see the SwiftUI view:

import SwiftUI
struct ContentView: View {
    @State var shaked = false
    
    var body: some View {
        NavigationView {
            VStack{
                ZStack {
                    ShakeViewRepresentable()
                                .allowsHitTesting(false)
                    VStack {
                        Text("Shake device to change view!")
                    }
                    
                }.onReceive(messagePublisher) { _ in
                    self.shaked = true
                }
                NavigationLink(destination: SecondView(), isActive: $shaked) {
                    EmptyView()
                }
            }
        }
    }
}



The state variable shaked it used to store the shaked event. In the navigationview there is a ZStack, where at the bottom (first element) there is the ShakeViewRepresentable that can’t get touch event from the user because allowsHitTesting is false, on the top there is a simple Text message.

When the ZStack receives the messagePublisher, the shaked variable become true and the NavigationLink become active so the view navigates to the SecondView (that you can create how you want). Note the use of the EmptyView from the NavigationLink, it used to show nothing but to have a working link.

That’s all. I hope that it can be helpful. You can get the code here.

Golang MongoDb raw pagination

I’m writing a complex query (for a beginner user) for mongodb using the golang official driver, i’d like share my code to help other user.

I’ll use an aggragate to do the complex query, we need to step the first one to count the records of the query, the second step to get the elements at the request page.

var basePipeline = mongo.Pipeline{
 {{“$lookup”, bson.D{
 {“from”, “makers”},
 {“localField”, “maker”},
 {“foreignField”, “username”},
 {“as”, “makerinfo”},
 }}}}



The first piece fo the pipeline is the lookup, a similar left-join, we want join from the collection of products the makers. With the subpipeline we specify the conditions of the query:

var countPipeline mongo.Pipeline
var productsPipeline mongo.Pipeline
subpipeline := bson.D{
 {“$match”, bson.D{{“$and”,
 bson.A{
 bson.D{{“name”, bson.M{“$regex”: “.*” + initial + “.*”, “$options”: “-i”}}},
 bson.D{{“makers”, maker}},
 }}



I use two different pipeline, the countPipeline to count of the products, the second to gets the products. To have the count we must add other pipeline:

var countPipeline mongo.Pipeline
var productsPipeline mongo.Pipeline
subpipeline := bson.D{
        {"$match", bson.D{{"$and",
            bson.A{
                bson.D{{"name", bson.M{"$regex": ".*" + initial + ".*", "$options": "-i"}}},
                bson.D{{"makers", maker}},
        }}
countPipeline = append(basePipeline, subpipeline)
countCondition := bson.D{{"$count", "numberOfProduct"}}
countPipeline = append(countPipeline, countCondition)
productsPipeline = append(basePipeline, subpipeline)
 
cur, err = GetDB().Collection("products").Aggregate(GetCtx(), countPipeline)
// number of elements
var total int
if err != nil {
  fmt.Printf("[Debug] decode error %s", err)
  panic(err)
 } else {
  for cur.Next(GetCtx()) {
   dum := bson.M{"np": 0}
   if err = cur.Decode(&dum); err != nil {
    fmt.Printf("[Debug] decode error %s", err)
   }
   total = int(dum["numberOfProduct"].(int32))
  }
 }


Verify the page is in the range of the pages

// number of page
pages := total / 10
if (total % 10) > 0 {
  pages++
}
jumpPage, conError := strconv.Atoi(page)
if pages == 0 || conError != nil || jumpPage > pages {
  finalResult := bson.M{"products": result, "productsCount": 0, "pages": 0}
  return finalResult
}



Finally to gets the elements of the page:

result := []bson.M{}
var nProducts = 0
// get elements
jumpPagePipeline := bson.D{{"$skip", jumpPage}}
limitPipeline := bson.D{{"$limit", 10}}
productsPipeline = append(productsPipeline, jumpPagePipeline)
productsPipeline = append(productsPipeline, limitPipeline)
cur, err = GetDB().Collection("products").Aggregate(GetCtx(), productsPipeline)
// number of elements
if err != nil {
  fmt.Printf("[Debug] decode error %s", err)
  panic(err)
 } else {
  for cur.Next(GetCtx()) {
   dum := bson.M{}
   //var resultDecode bson.M
   if err = cur.Decode(&dum); err != nil {
    fmt.Printf("[Debug] decode error %s", err)
   }
   result = append(result, dum)
   nProducts++
  }
 }
finalResult := bson.M{"products": result, "productsCount": nProducts}



I used jumpedPipeline to jump to the page and limit to get only 10 elemets for page.

This example is not the better way to do the pagination, but it can be helpful to understand how build complex query.


For some better code you can see:

https://github.com/gobeam/mongo-go-pagination (it’s not my code)

Elm upgrade package

I start with my conclusion: use elm-json for the elm packages. Now, my story:

Yesterday, a member of my team joined to my elm project to learn the project and help me, but…. when i started the elm make command, surprise, problem with the dependencies! The problem was this package:

"Skinney/murmur3": "2.0.8"



The author removed the source (or it moved), the simple solutions is copy my package directory and give it to my collegue, but it’s no final solution.

The accused package is used from

"rtfeldman/elm-css": "15.1.0"


The last version of elm-css (16.1.0) don’t depende from murmu3 so the solution is upgrade the elm-css.

I tryed it, removing from the elm.json and run

elm install rtfeldman/elm-css


I have always an dependecies error. So, i chat on slack with the community and they suggested me to use elm-json. With elm-json i try to uninstall

elm-json uninstall rtfeldman/elm-css


but I see an message error, there are other package stephenreddek/elm-range-slider that depends from this elm-css in version 15.1.0, so at the end there are my steps:

npm -g install elm-json
elm-json uninstall rtfeldman/elm-css
elm-json install rtfeldman/elm-css@16.1.0
elm-json uninstall stephenreddek/elm-range-slider
elm-json install rtfeldman/elm-css@16.1.0

Conclusion: use elm-json for the elm packages.