Working with Multiple Github Account on a Computer

Source control is one of a basic need for software development, especially when we work on a team. Git is one of popular distributed source control. Working with multiple github account on the same computer need a few tricky way. Let’s assume we have cloned the repository from github to local computer. The following ways are the simple ways I got on internet.

Change Remote URL to HTTPS

This way is by changing the remote URL to HTTPS with the following format.

$ git remote set-url origin https://USERNAME@github.com/USERNAME/PROJECTNAME.git

Then do normal git operation such as commit, push etc. To ensure that the commits appear as performed by USERNAME, we can configure the username and email on our working directory.

$ git config user.name USERNAME
$ git config user.email USERNAME@example.com

Multiple SSH Key

The other way is by using multiple SSH key. Here is the complete tutorial by Jeffrey Way

References

  1. http://stackoverflow.com/questions/3860112/multiple-github-accounts-on-the-same-computer
  2. https://code.tutsplus.com/tutorials/quick-tip-how-to-work-with-github-and-multiple-accounts–net-22574

C++ Set with Custom Comparator

std::set is a C++ STL container that store unique elements following a specific order. It is defined in the set header file.

Benefits and Features of std::set[3]:

  1. It’s doesn’t allow duplicate elements i.e. it only contains unique elements
  2. std::set can contain element of any specified type in template argument
  3. std::set internally store elements in balanced binary tree
  4. By default std::set uses the operator < for comparing two elements and but if user passes the external sorting criteria i.e. comparator then it uses it instead of default operator < .
  5. std::set will keep the inserted elements in sorted order based on the assigned sorting criteria i.e. either by default criteria operator < or by passed comparator (if passed).

In this post the samples only limited to std::set that use custom comparator and store complex object instead of basic data type. The complex object that we will use is reusing class Person on previous post.

Let’s create custom class that handles comparation process


#ifndef CustomCompare_h
#define CustomCompare_h

#include "Person.hpp"

struct CustomCompare
{
    bool operator()(const int& lhs, const int& rhs)
    {
        return lhs < rhs;
    }

    bool operator()(const Person& lhs, const Person& rhs)
    {
        return lhs.getAge() < rhs.getAge();
    }
};

#endif /* CustomCompare_h */

The following code is an example how to use the comparator class in std:set

void SampleSetWithCustomCompare()
{
    set<Person,CustomCompare> setOfPersons;

    setOfPersons.insert(Person("Person 1", 25));
    setOfPersons.insert(Person("Person 2", 16));
    setOfPersons.insert(Person("Person 3", 28));
    setOfPersons.insert(Person("Person 4", 9));

    for(set<Person,CustomCompare>::iterator it = setOfPersons.begin(); it!=setOfPersons.end(); ++it)
    {
        cout << it->getName() << " , age : " << it->getAge()<< endl;
    }

}

References

  1. http://www.cplusplus.com/reference/set/set/
  2. http://www.wrox.com/WileyCDA/WroxTitle/Professional-C-2nd-Edition.productCd-0470932449.html
  3. http://thispointer.com/stdset-tutorial-part-1-set-usage-details-with-default-sorting-criteria/

C++ Priority Queue with Comparator

priority_queue is categorized as a STL container adaptor. It is like a queue that keeps its element in sorted order. Instead of a strict FIFO ordering, the element at the head of the queue at any given time is the one with the highest priority.

The template class definition of priority_queue is as follow

template <
   class Type,
   class Container=vector<Type>,
   class Compare=less<typename Container::value_type> >
class priority_queue

A user-provided compare can be supplied to change the ordering, e.g. using std::greater</code> would cause the smallest element to appear as the top(). We also can create custom comparator for our need.

Many samples available on net about priority_queue with default compare parameter. In this article let’s create samples by specifying the compare parameter template.


//helper function displays sorted data
template<class T>
void printQueue(T& q)
{
    while (!q.empty())
    {
        cout << q.top() << endl;
        q.pop();
    }
}

void SamplePriorityQueue()
{
    std::priority_queue<int, std::vector<int>, std::greater<int> > q;

    for(int n : {1,8,5,6,3,4,0,9,7,2})
        q.push(n);

    printQueue(q);
}

The code above uses std::greater as a compare parameter template.

0
1
2
3
4
5
6
7
8
9

Beside the std::less or std::greater, we can create our custom comparator with lamda or custom class or struct.


void SamplePriorityQueueWithLamda()
{
    // using lambda to compare elements.
    auto compare = [](int lhs, int rhs)
                {
                    return lhs < rhs;
                };

    std::priority_queue<int, std::vector<int>, decltype(compare)> q(compare);

    for(int n : {1,8,5,6,3,4,0,9,7,2})
        q.push(n);


    printQueue(q);
}

To use the custom comparator, we just need to pass it as the third parameter of priority_queue template


struct CustomCompare
{
    bool operator()(const int& lhs, const int& rhs)
    {
        return lhs < rhs;
    }
};

void SamplePriorityQueueWithCustomComparator()
{
    priority_queue<int,vector<int>, CustomCompare > pq;

    pq.push(3);
    pq.push(5);
    pq.push(1);
    pq.push(8);

    printQueue(pq);
}

The data stored in priority_queue is not limited to basic data type. We can store object in it. Let’s create a sample of it. Let’s say we have a Person class.

//Person.hpp
#ifndef Person_hpp
#define Person_hpp

#include <stdio.h>
#include <string>

using namespace std;

class Person
{
public:
    Person();
    Person(string name, int age);
    virtual ~Person();

    string getName() const;
    int getAge() const;

    friend bool operator < (const Person& lhs, const Person& rhs);
    friend bool operator > (const Person& lhs, const Person& rhs);

private:
    string name;
    int age;
};

#endif /* Person_hpp */

//Person.cpp
#include "Person.hpp"

bool operator < (const Person& lhs, const Person& rhs)
{
    return lhs.getAge() < rhs.getAge();
}

bool operator > (const Person& lhs, const Person& rhs)
{
    return lhs.getAge() > rhs.getAge();
}

Person::Person()
{
}

Person::Person(string name, int age):name(name), age(age)
{
}

Person::~Person()
{   
}

string Person::getName() const
{
    return name;
}

int Person::getAge() const
{
    return age;
}

On the Person class, we have friend overloading methods, right angle bracket and left angle bracket. The methods act as comparation operator. The operator overloading is needed if we want to use std::less or std::greater.


void SamplePriorityQueueStoreObject()
{
    vector<Person> personVector =
    {
        Person("Person 1", 25),
        Person("Person 2", 17),
        Person("Person 3", 35),
        Person("Person 4", 7),
        Person("Person 5", 50)
    };

    cout << "======== Less Priority Queue ======= " << endl;

    priority_queue<Person, vector<Person>, less<vector<Person>::value_type>> pqueue_less;

    //fill pqueue_less
    for (auto it = personVector.cbegin(); it!=personVector.cend(); it++)
    {
        pqueue_less.push(*it);
    }

    //iterate,display and pop
    while (!pqueue_less.empty())
    {
        Person value = pqueue_less.top();
        cout << value.getName() << " : " << value.getAge() << endl;

        pqueue_less.pop();
    }


    cout << endl << endl;

    cout << "======== Greater Priority Queue ======= " << endl;

    priority_queue<Person, vector<Person>, greater<vector<Person>::value_type>> pqueue_greater;
    //fill pqueue_greater
    for (auto it = personVector.cbegin(); it!=personVector.cend(); it++)
    {
        pqueue_greater.push(*it);
    }

    //iterate,display and pop
    while (!pqueue_greater.empty())
    {
        Person value = pqueue_greater.top();
        cout << value.getName() << " : " << value.getAge() << endl;

        pqueue_greater.pop();
    }
}

References

  1. http://en.cppreference.com/w/cpp/container/priority_queue
  2. https://support.microsoft.com/en-us/kb/837697
  3. http://www.wrox.com/WileyCDA/WroxTitle/Professional-C-2nd-Edition.productCd-0470932449.html

Reset Git Credential on OS X Keychain

This post basically just a note for my self. In case I got the same condition in the next, it can help me to remember what I did in the past.

I got a condition which I have just changed my git password. Surely I cannot pull or push since my local credential was not valid anymore. When I run git config --list, I believe my git password stored on OS X Keychain. The simple way I do was running a command via terminal :

$ git config credential.helper osxkeychain

I was then prompted to input my username and password. By inputing my username and new password everything back to normal.

If you want it to apply globally just append parameter --global to the command.

$ git config --global credential.helper osxkeychain

References

  1. http://stackoverflow.com/questions/20195304/how-to-update-password-for-git

Ubuntu Server Does Not Recognize VirtualBox Adapter

As we know, VirtualBox provides several adapters that we can add and be used by OS guest. At the time of writing this post, I have an OS X (host) and Ubuntu Server 16.04.1 LTS (guest). The needs are, I want to be able to remote my Ubuntu from OS X terminal. I also want my Ubuntu guest can connect to internet. I have configured two network adapters for the guest (NAT and host-only).

When I run

$ ifconfig

The first/default adapter (NAT) enp0s3 is recognized without any problems by the guest. But not the second one (host-only). To make the second adapter visible, I have to run a command

$ sudo dhclient
$ ifconfig

Now I got both adapters enp0s3 (NAT) and enp0s8 (host-only) visible on terminal. And now I can ping and run ssh from host (OS X) to guest (Ubuntu server).

In order to make it permanent, we need to edit /etc/network/interfaces with the following lines

# The second network interface
auto enp0s8
iface enp0s8 inet dhcp

Then restart the network service by running

$ sudo /etc/init.d/networking restart

That’s my note for now and thanks for reading.