NewFiveFour | Blog | Portfolio


Linux: Connect to open and closed networks from the command line with a single command.

You can easily connect to an open network though

iwconfig wlan0 essid "THE NETWORK NAME"

Closed networks work with wpa_supplicant. You normally send a configuration file with that but you can simulate the file with a named pipe:

wpa_supplicant -iwlan0 -c <(echo -e 'network={\n ssid="THE NETWORK NAME" \n psk="THE PASSWORD" \n}') -B

wlan0 is your network interface name. -B means go into the background. The \ns in the configuration file is needed sadly and so we pass -e to echo to interpret them.

iwconfig should show your new connection but prehaps only after a second.

After this dhclient wlan0 will get you a dhcp address and you’ll be ready to go. You may want to kill any prior instances of dhclient.

unix wifi

Git: Subtree tutorial

Git submodules are a pain to deal with. Git subtrees are much nicer.

Let’s start with your parent repo, and another repo, currently completely separate. The latter of these will be the subtree repo.

1) Let’s add the repo like a normal repo: git remote add my-subtree git@github.com:your_username/your_repo.git.

2) Add the other repo as a subtree: git subtree add --prefix=the_folder/ my-subtree master.

That is, git subtree add and then the name of the folder it will live in and finally the repo name and branch.

3) Make a change to the files in the_folder and commit. Your parent repo, along with the files in the subtree, will be updated. But the subtree will not.

When you want update the files in the subtree repo run git subtree push --prefix=the_folder my-subtree master. And the same command but with pull to pull any new changes.

There are more things to learn, like whether you could squash commits and how all this relates to rebasing, but that’s the basics.

git

Git: Alias for multiple Github accounts in SSH

Say you have two github accounts. So you have different SSH keys. Github won’t know which key relates to which account.

However, in your ~/.ssh/config file you can setup an alias that uses the correct IndentityFile to send to github.

In that file, put this:

Host new_alias
        Hostname github.com
        User git
        IdentityFile ~/.ssh/id_rsa_new_identity

Now you can use git remote origin git@new_alias:your_username/therepo.git Note the : after the alias name. And the fact you’re putting git@ at the start.

git

A simple and naive Virtual DOM implementation, part 5

In the last part, we gave our javascript structure creator function to ability to give each node a hashcode.

We did this so the comparison function can compare a node’s children, to rearrage them rather than obliterate them.

The first thing we’ll do is get the hashcodes before we look at the node’s children. v and v1 equate to the two virtual dom trees we’re comparing.

var v_hashes = v.children.map(c => c.hashcode )
var v1_hashes = v1.children.map(c => c.hashcode )

Next we’ll make an array of the positions of the v1 hashes and whether they exist in the v hashes using indexOf().

Given the v hash array [1111, 2222] and the v1 hash array [3333, 1111, 2222] we’ll get [-1, 0, 1].

indexOf() is telling us: the zeroth item in v1 doesn’t exist in v but the first is the zeroth element, and the second is the first element.

We’re also grabbing v1’s hash in the returning array for later reference.

var positions = v1_hashes.map((h, i) => v_hashes.indexOf(h) )

With this new structure we will loop over it. It will tell us if there’s a new item in the v1 virtual dom that’s not in the v virtual dom, i.e. we find a -1 value.

positions.forEach((index_in_v, v1_pos) => {
  if(index_in_v != -1) return
  console.log("insert " + v1_hashes[v1_pos] + " into " + v1_pos + " at " + path)
  v.children.splice(v1_pos, 0, JSON.parse(JSON.stringify(v1.children[v1_pos])))
})

So we look for that -1, and then rearrange the original v array. This means, later, when we compare the two tree branches our compare function will see they’re the same.

Of course, our compare function must output the fact – here indicated initially as the console.log – that the DOM manipulation function must actually do this rearragement of the DOM.

Although there is much more to do with this function, we can now fix our previous problem with the algorithm:

The v virtual DOM tree was:

[{
    "type": "node",
    "name": "DIV",
    "attrs": [],
    "children": [{
        "type": "node",
        "name": "P",
        "attrs": [],
        "children": [{
            "type": "text",
            "value": "original",
            "children": [],
            "hashcode": -68148979
        }],
        "hashcode": -1072170396
    }],
    "hashcode": -154850033
}]

And v1 was:

[{
    "type": "node",
    "name": "DIV",
    "attrs": [],
    "children": [{
        "type": "node",
        "name": "P",
        "attrs": [],
        "children": [{
            "type": "text",
            "value": "new",
            "children": [],
            "hashcode": 1156737192
        }],
        "hashcode": -1348153726
    }, {
        "type": "node",
        "name": "P",
        "attrs": [],
        "children": [{
            "type": "text",
            "value": "original",
            "children": [],
            "hashcode": -68148979
        }],
        "hashcode": -1072170396
    }],
    "hashcode": 1511584547
}]

In other words, v1 had a new P node (hashcode: -1348153726) above the old one.

And this function:

compare = function(v, v1, path) {
    var v_hashes = v.children.map(c => c.hashcode )
    var v1_hashes = v1.children.map(c => c.hashcode )
    var positions = v1_hashes.map((h, i) => v_hashes.indexOf(h) )
    positions.forEach((index_in_v, v1_pos) => {
      if(index_in_v != -1) return
      console.log("insert " + v1_hashes[v1_pos] + " into " + v1_pos + " at " + path)
      v.children.splice(v1_pos, 0, JSON.parse(JSON.stringify(v1.children[v1_pos])))
    })
    v.children.forEach((_, i) => compare(v.children[i], v1.children[i], path + "" + i) )
}; 
compare(JSON.parse(JSON.stringify(vd[0])), JSON.parse(JSON.stringify(vd1[0])), "")

Will output only.

insert -1348153726 into 0

Next up, we’ll look at how we can remove nodes.

javascript virtual-dom

A simple and naive Virtual DOM implementation, part 4

In part 3, we found a problem with our comparison function:

If we insert a new DOM node above the existing ones the function won’t know the child nodes have been reorganised.

We use our eyes to know this. We quickly look at the node and its children. Then we know this isn’t a new node, but it’s an existing node in a new position.

The algorithm doesn’t have eyes. But we can still allow it to look. We could use JSON.stringify() to compare the nodes in the two virtual dom trees.

We could do this, but this would make our comparison function larger. And we could instead do the work in the function that creates our javascript representation of the DOM.

We can use a “hash code” of the node attributes and its children. This would allow us to compare our nodes based on this value. Here’s stackoverflow’s recommended way of creating a hash code from a string:

String.prototype.hashCode = function() {
  var hash = 0, i, chr;
  if (this.length === 0) return hash;
  for (i = 0; i < this.length; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};

Let’s alter our traverse function to use this on a aggregation of all the values of the node plus a JSON.stringify representation of the children:

function traverse(v, ele) {
  var nu = {}
  v.push(nu)
  if (ele.nodeType == 1) {
    nu.type = "node"
    nu.name = ele.nodeName
    nu.attrs = []
    for (var i = 0; i < ele.attributes.length; i++) {
      var attr = {}
      attr[ele.attributes[i].name] = ele.attributes[i].value;
      nu.attrs.push(attr)
    }
  } else if (ele.nodeType = 3) {
    nu.type = "text"
    nu.value = ele.nodeValue
  }
  nu.children = []
  for(var i = 0; i < ele.childNodes.length; i++) {
    traverse(nu.children, ele.childNodes[i])
  }
  nu.hashcode = ((""+nu.type+nu.name+JSON.stringify(nu.attrs)+nu.type+nu.value)+JSON.stringify(nu.children)).hashCode()
}; traverse(vd, document.documentElement); JSON.stringify(vd, null, 2);

The last line is the only one that has changed. It will output something like:

...
{
  "type": "node",
  "name": "DIV",
  "attrs": [{
    "id": "hi"
  }],
  "children": [{
    "type": "text",
    "value": "hi there",
    "children": [],
    "hashcode": 634735809
  }],
  "hashcode": 2015122423
}
...

We can then use the hashcodes so our comparison function can recognise identical nodes in different positions.

And we will in the next part of this series.

javascript virtual-dom

Page 1 of 84
Next