Replace Conditional with Polymorphism

  • 0
Trying to convince my team to give up on if/then/else & case...

Let's play with some code!

First the the non Object Oriented / procedural version:

/*
 * non_oop.cpp
 *
 *  Created on: Sep 4, 2015
 *      Author: ferrazlealrm@ornl.gov
 *
 *  Non OOP example of URL:
 *  scheme:[//domain[:port]][/]path
 */

#include <iostream>
#include <string>

std::string domain = "ornl.gov";
std::string http_port = "80";
std::string https_port = "443";
std::string ftp_port = "20";

std::string build_url(const std::string &scheme,
  const std::string &domain,
  const std::string &port) {
 return scheme + "://" + domain + ":" + port;
}

int main(int argc, char* argv[]) {
 if (argc != 2) {
  std::cerr << "Use " + std::string(argv[0]) + " [http, https, ftp]"<<std::endl;
  exit(-1);
 }
 std::string scheme = argv[1];

 if (scheme == "http"){
  std::cout << build_url(scheme,domain,http_port) <<std::endl;
 }
 else if (scheme == "https"){
  std::cout << build_url(scheme,domain,https_port) <<std::endl;
 }
 else if (scheme == "ftp"){
  std::cout << build_url(scheme,domain,ftp_port) <<std::endl;
 }
 else {
  std::cerr << "Scheme not valid. Use of these: http, https, ftp"<<std::endl;
 }
 return 0;
}

And the finally the Object Oriented version:

/*
 * oop.cpp
 *
 *  Created on: Sep 4, 2015
 *      Author: ferrazlealrm@ornl.gov
 *
 *  OOP example of URL:
 *  scheme:[//domain[:port]][/]path
 */

#include <iostream>
#include <string>
#include <map>

// Abstract class: cannot be instantiated
class URL {
protected:
 std::string domain = "ornl.gov";
 std::string port;
 std::string scheme;
 std::string build_url(const std::string &scheme,
   const std::string &port) const {
  return scheme + "://" + domain + ":" + port;
 }
public:
 // Pure virtual function: i.e. must be overridden by a derived class
 virtual std::string build_url() const = 0;
 ~URL() {};
};

class Http: public URL {
public:
 Http() {port = "80"; scheme = "http";}
 std::string build_url() const {
  return URL::build_url(scheme, port);
 }
};

class Https: public URL {
public:
 Https() {port = "443"; scheme = "https";}
 std::string build_url() const {
  return URL::build_url(scheme, port);
 }
};

class Ftp: public URL {
public:
 Ftp() {port = "20"; scheme = "ftp";}
 std::string build_url() const {
  return URL::build_url(scheme, port);
 }
};

/**
 * Main function
 */
std::string build_url(const URL &url) {
 return url.build_url();
}

int main(int argc, char* argv[]) {
 if (argc != 2) {
  std::cerr << "Use " + std::string(argv[0]) + " [http, https, ftp]"
    << std::endl;
  exit(-1);
 }
 std::string scheme = argv[1];

 // UGLY!!!
 // In real world I would have here some sort of Dependency Injection (e.g. factory)
 // This just shows that we can get an object given a string
 Http http;
 Https https;
 Ftp ftp;
 std::map<std::string, URL*> choices;
 choices.insert(std::make_pair("http", &http));
 choices.insert(std::make_pair("https", &https));
 choices.insert(std::make_pair("ftp", &ftp));

 if (scheme == "http" or scheme == "https" or scheme == "ftp") {
  std::cout <<  build_url(*choices[scheme]) << std::endl;
 } else {
  std::cerr << "Scheme not valid. Use of these: http, https, ftp"
    << std::endl;
 }
 return 0;
}

I know it looks complicated, but imagine you want to add a new functionality. Let for example add a path to the HTTP url:

/**
 * Let's imagine that I want to add a path to the URL: http://ornl.gov:80/
 * I don't need to modify the code! Open/closed principle.
 * Just extend it, i.e., add new code.
 */

class HttpWithPath: public Http {
protected:
 std::string path;
public:
 HttpWithPath(std::string path) : Http(), path(path) {}
 std::string build_url() const {
  std::string default_url = URL::build_url(scheme, port);
  return default_url + "/" + path;
 }
};


It does not violate the open/closed principle, which states:
"software entities should be open for extension, but closed for modification".


Just for fun

  • 0
Running out of processing power...
64 x AMD Opteron(tm) Processor 6376
$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                64
On-line CPU(s) list:   0-63
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             4
NUMA node(s):          8
Vendor ID:             AuthenticAMD
CPU family:            21
Model:                 2
Stepping:              0
CPU MHz:               2300.114
BogoMIPS:              4599.35
Virtualization:        AMD-V
L1d cache:             16K
L1i cache:             64K
L2 cache:              2048K
L3 cache:              6144K
(...)

$ grep MemTotal /proc/meminfo
MemTotal:       529254920 kB

$ df -h
(...)
                      1.1P  552T  477T  54% /(...)
(...)


JQuery autocomplete with ranged fields

  • 0
Few weeks ago I was looking for a way to get a form field autocomplete from a remote JSON file with a single HTTP request. The solution is here.
Now I want to do the same but using ranged fields (i.e., sort of an array where commas separate items and hyphen define ranges). A valid field would be: 1-8,10,13,15-20.

Here the javascript / JQuery code:
    /* Function to populate the autocomplete from a remote json.
      For ranged fields, .e.g,: 4588-4590,465-658 */
    function split(val) {
        return val.split(/[,-]\s*/);
    }

    function extractLast(term) {
        return split(term).pop();
    }

    function set_autocomplete_ranged(selector, jsonurl) {
        $.ajax({
            url: jsonurl,
            type: 'get',
            dataType: 'json',
            async: true,
            success: function (data) {                
                $(selector).autocomplete({
                    minLength: 0,
                    source: function (request, response) {
                        response($.ui.autocomplete.filter(
                        data, extractLast(request.term) ));
                    },
                    focus: function () {
                        return false;
                    },
                    select: function (event, ui) {
                        var this_value = ui.item.value
                        var all_values = this.value
                        this.value = all_values + this_value
                        return false;
                    }
                }).bind('focus', function () {
                    if (!$(this).val().trim()) $(this).keydown();
                });
            }
        });
    }
An then just add the URL for the JSON and the id for the field you want to use the ranged autocomplete:
    /*
    Function called only once! It populates the autocomplete from a remote json.
    The filtering is made locally as the source is a local variable :)
    */
    $(function() {
        var jsonurl = "http://mysite.com/myjson.json";
        var selector = '#id_ranged_field';
        if  ($(selector).is('*')) {
            set_autocomplete_ranged(selector,jsonurl);
        }
    });

Writing Blogger posts in Markdown

  • 0
Just write your markdown post here:

http://jbt.github.io/markdown-editor/

And copy paste from the right pane :) That's all!!


I have tried a few, including the stackedit.io, and this looks the best as Blogger doesn't mess up the format...

Flavoured (i.e., github) Markdown syntax is available here:

https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet


Git: Going back in time

  • 0
  1. Testing stuff on a old commit
# This will detach the HEAD, i. e., it leaves no branch checked out:
git checkout 

# Or:

# This will create a new branch from an old commit. Ideal to play and make new commits.
git checkout -b old-state 
  1. Getting rid of everything done since a specific commit
# If no published commits exist, i. e., it all the commited changes are were not pushed yet!
git reset --hard 
  1. Undo published commits with new commits.
# Delete a commit somewhere in time (the following commits are kept!):
git revert HEAD~2

# Delete the last commit:
git revert HEAD

# Delete the last two commits:
git revert HEAD~2..HEAD

Git: Delete Branch Remote and Locally

  • 0
  1. See all branches:
git branch -a
  1. Delete the branch locally:
git branch -D 
  1. Delete the branch remotely:
git push origin --delete 
DONE!

Git Roll Back

Rolling back to a previous commit:

Only, and only, if you are working by your self!

(This is dangerous in a collaborative environment: we are rewriting history!)
git reset --hard 
git push -f origin
Note, if by any reason you want to have access to the lost commits, use:
git reflog