How to know the charging/discharging speed of your MacBook

I recently encountered this problem when the charger of my MacBook 11” was stolen in the library. I had to use a USB charger for my Samsung Galaxy to charge the laptop with a micro-USB to USB type C converter. Obviously it wasn’t quick enough so the net effect on the battery was discharging. I have a few phone chargers, and a portable battery, so I would like to know the charging/discharging speed.

After some Googling I found the system command system_profiler. It lists all the system information about your Mac. To follow the following instructions, you need to have Terminal (Launchpad-Other-Terminal) opened.

First I’ll use a MacBook Pro 15”, mid 2015 as an example of displaying the discharging speed.

The charging/discharging speed is basically indicated by the battery current. If it’s negative it means your battery is discharging and vice versa.

I fully charged the laptop and waited until the battery went to 99%. I then did

system_profiler SPPowerDataType

and saw the following information about the Battery.

Notice the Amperage (mA) and keep in mind that it might change a little based on your activities but it should always be negative if you don’t connect to a charger. You should repeat this a few times to get a rough estimation about the basic power consumption of your laptop. If you don’t want to see so much information but only the Amperage, use

system_profiler SPPowerDataType | grep -I "Amperage"

Typically there will be some delay but it doesn’t matter. See example below

Now if I connect the charger (85 W) it shows a positive Amperage indicating a fast charging

The estimated Amperage of a MacBook 11”, with minimum activities (only Chrome opened and no “significant energy usage”) of different chargers are:

  1. A Samsung Quick Charger (for Galaxy S7 edge) + nanoUSB cable + nanoUSB to USB C adapter: Roughly -200 mA. Even though you turn off the laptop, charging speed is super slow.
  2. A Samsung Quick Charger (for Galaxy S8 edge) + USB C cable: Roughly 0 mA (so if you turn off the laptop it should be charging quickly enough).
  3. A Samsung normal charger (for Galaxy S6 or earlier) + nanoUSB cable + nanoUSB to USB C adapter: Roughly -300 mA. Even slower than 1. Almost not visibly effective charging.
  4. A portable battery, marked up to 5 A: Roughly -100 mA. Slow but useful.

So, if you lost your original charger, you may use a Samsung USB C charger and its cable and shut down your computer for temporary rescuing. Or, you have to buy a good charger from Amazon…

Using Github and Gitlab (2) – Use Git online

In our first tutorial of how to use Git on a local machine, we have seen the basic operations of Git. Nevertheless, the main purpose of using Git is to store your repository online, and collaborate with others. In this tutorial we will show how to set up Github or Gitlab for your projects.

Tell git who you are

The first step is to let Git know you identity. For both Github and Gitlab this has to be done. Set up your Email and Name by:

git config --global user.name "Your Name"

git config --global user.email "Your Email"

You may use git config –list to see existing configurations at any time.

Authorize your computer for gitlab and github

Without authorization, anyone can put things into your account. Github and Gitlab use SSH to make a secure connection, so you need to give your computer a key to enter your account.

If you now think like “Uh, I need to see my public SSH key”, then you may skip to the end of this section to add the public key to your account. Otherwise, Gitlab and Github both have detailed tutorials on how to generate the SSH key. They are the same thing. Read them: Github tutorial and Gitlab tutorial. Once it is generated, copy the public key in ~/.ssh/id_rsa.pub and paste it into the key library in Github/Gitlab. They are both in the Settings menu.

start a new project online

Create an account using the email above. On both Gitlab and Github.

On Github, create a new repository:

You will see this page, but don’t do anything yet, we’ll go over this.

On Gitlab, create a new project, it’s very similar, you can even import from Github:

Here you can already notice the difference:

On Github, the default visibility is “Public“, while on Gitlab, the default is “Private“. This is probably the biggest, if any, difference of the two. Github asks you to pay for a private repository, while Gitlab is totally free for any of the visibility levels. If you want to make your codes open-source and invite as many users as possible to work on them, then I recommend Github since it has more users.

Start Using the remote repository

I do prefer the instructions given by Gitlab after a new repository is created, than those on Github. There are basically two ways of using the online repository.

Think of the online repository as a branch. You do stuff on your own branch and you may merge from the remote branch. When you are ready you can also push your contributions (discussed later).

If you have an existing repository on your local computer:

You need to push it onto the remote server. The remote setting is controlled by the command git remote. In this case, you need to add a remote destination. Each remote repository has a reference, and the default reference name is origin. Therefore, for my Gitlab repository I’ll do

git remote add origin git@gitlab.com:frankliuao/git_demo.git

Now the reference origin is taken by Gitlab, so you can’t use the same for Github anymore. I’ll use another_origin:

git remote add another_origin git@github.com:frankliuao/git_demo.git

You can check the remote settings by using git remote show [remote_ref_name]. The remote_ref_name is optional: if not provided all remote reference names will be shown:

Now you can push the same local repository to either remote server using

git push -u origin master

where -u is short for “upstream”, which sets the reference name origin. Following the reference name, a head (refer to the 1st tutorial) name is needed, and the default name is master. After this command, the HEAD of your Gitlab repository is now master with all the commits from your local repository preserved. It has to be called master, since it’s the default head name when you created the online repository:

You should be able to see files in your online repositories now.

If you do not have an existing repository on your computer:

In many cases you may just want to finish what others have already started. Under that circumstance, it is called “clone” the remote repository:

git clone THE-REMOTE-REPOSITORY-LINK

As shown, clone creates a new directory in the current folder where the command is executed. That’s why I used a new directory ~/Download/new_git_demo/ to demonstrate it. If I executed the same command in ~/Download/, it wouldn’t have worked – the ~/Download/git_demo/ already exists!

To visualize the clone, we show two examples: Upper one is a simple case where the online repository does not have branches, while the lower one has two branches and the local repository also has two branches but are marked by the origin/ to clarify. If you want to work with that branch, you need to add the branch locally by git branch –track work_progress origin/work_progress.

Keep updated with the remote repository

Let’s still use the second case (with remote branch) above as an example. After it is cloned, the remote repository has some new commits. To get updated, it’s not called clone any more. Instead, it’s called “fetch“, or “pull“. There are some differences.

fetch:

You only need a remote repository reference to do fetch. In our last case it can be just

git fetch origin

Consider our last example, the local repository will become (upper is the new remote repo):

You own heads are not affected (if you set up a branch locally named “work_progress” it will be still at a). The remote_reference/head are updated to match the remote status.

pull:

On the other hand, if you want to update your HEAD to a remote head, you need to do a git pull remote_repo_reference remote_head, so in our case it can be

git pull origin master

Git will first do a fetch for you then change your HEAD to the corresponding head. As for our example it can be visualized by

Notice: if your local repository has new commits and they do not have conflicts with the online repo, then it’s basically a merge – your local files will be updated to reflect the change. If there is a conflict, solve it using the way that was shown in the merge section, then do a new commit.

Contribute to the remote repository

Now suppose an opposite situation of the above: you made some commits but the remote didn’t. You want to contribute. Opposite of “pull“, this is a “push” situation. The command is git push remote_repo_reference remote_head_name. For our case it is

git push origin master

This pushes your current HEAD to the origin/master on the remote repository. As for your local repository the origin/master will also be changed to whatever you just committed. The remote_repo_reference and remote_head_name are optional, but specifying them will be safer and not specifying them will push every branch of your local repository to the remote.

Be sure not to leave any dangling commits when doing the push. If you have a branch (not master) that is not in the remote repository, this will cause some trouble, since it will become a dangling commit. For example, the “another” branch below becomes a dangling branch after being pushed to the remote server, so it’s not recommended:

Change remote branch

You may add a branch on the remote (assuming reference name is origin) by first checking out your local branch, and then doing

git push -u origin branch_name

You may delete a remote branch by

git push origin --delete <branch_name>

 

That should be able to get you through daily usage of git/github/gitlab!

Using Github and Gitlab (1) – About Git

Recently at work we encountered the choice between Github and Gitlab. I did some research and summarized their similarities and differences below.

First of all, both of them are based on Git. Let’s first talk about Git itself. Git is standalone from any of the Git online servers: in principle you don’t need Internet to use Git. But, nobody else can see your project then. What’s the point?

Check whether you have git first. If not, install it.

git --version

How git works

Basically, Git is used to record the changes of a project, which contains folders and files. It stores all these information in a repository in each project folder. Each time some changes are done, and you want to record the status of the project (like you wanna take a selfie for your workout progress), it’s called a commit. Each commit has a reference to it, called a head. The current head is capitalized as HEAD, and each repository can have multiple heads.

Each commit includes 1. The project files; 2. parent commit; 3. a name for this commit (a head).

initializing git and the first commit

Let’s start the demo now. I created a file “History.txt” and wrote “08/09/17 15:09: Ao Created History.txt”. I am ready for my very first commit. So, I initialize the repository by:

git init

It will say Initialized empty Git repository in /path/to/project/directory/.git/. Next you need to tell Git what files are relevant, i.e. which files you want to commit, i.e. you need to add the files to the commit list.

git add file1 file2 file3

Or if you want to commit the whole directory, do

git add .

Now you may do your first commit by:

git commit -m "Initial commit"

You will see a bunch of notifications saying your first commit was successful. Alternatively, you can also use

git commit -a -m "Initial commit"

to automatically add all the files and commit (equivalent to git add . ; git commit -m “…”)Now, let’s add another line to the file: “08/09/17 15:30: Ao Modified History.txt”. Before you do the next commit, you probably want to check which files were modified, and what are different. Use the following commands:

git status

You will see “Modified: History.txt”, indicating the file was modified since last commit. Use

git diff

to get the detailed changes between the current files and the last commit:

Go ahead and do the next commit with git commit -m “Second commit”. Now you have two commits.

Reversing commits

Now say you realized that the changes in your last commit were really stupid/unnecessary. You want to reverse it. There are basically two options: hard and soft. Before demonstrating this technique, let’s add another line in the file, and do another commit. Now you have three commits.

Let’s say you want to go back to the 1st commit and do some changes. First we try the soft way. Each commit head, as you could see, has a unique name, called SHA1 name. You need the first 7 characters to describe a head, e.g. our first commit is 5d28811, but I found you can use more than that, up to the whole SHA1 name. We want to basically “reset” to that commit. So the command is

git reset --soft 5d28811

Also, you can use the name of the head, such as master, to refer to the commit.

You will see the following Git status change:

Oh BOY! There is only one commit left. But your file stays as it was at the 3rd commit. But Wait, you then again realized all you did for the 2nd and 3rd commits make sense! You want to go back to the 3rd commit (cancelling the “reset”). What should you do?

Luckily, all these heads (references) are properly stored in Git. You just need to call another log file, reflog:

For now we ignore the meaning of HEAD@{*}. You see your third commit is still there. Now you can go back by

git reset --soft 3224034

Next, we will try the HARD way. Be very careful when using this option, as this will cause changes to both your commits and files. All right, now we are at the 3rd commit. We are sure we want to discard the 2nd and 3rd commits. Do:

git reset --hard 5d28811

As shown, each hard reset can change both your commits and files. Although you may use hard reset to recover the files, as they are still recorded in reflog, I still recommend you be cautious when using it.

Alternatively, we can use another method: git revert. Revert also changes your file, but it’s different than reset. To demonstrate it let’s again start from the 3rd commit.

git revert 3224034bf 7d9fd5cf80a7a

Each time a revert happens, there will be a notification file opened, looking like this

It is basically a commit message on the first line. The document is opened with vim, so all you have to do is keep/change the commit message (in this case default is: Revert “Second commit”), and press :wq and Enter to save and exit vim. After two reverts, the project looks like this:

As shown, the reverts have been recorded in the log. The status is “up to date” (no unstaged changes), and the file has been reverted to the 1st commit. Now you probably understand: each revert is treated as a new commit, while reset just abandons changes made since then:

 4(2) means the 4th commit = 2nd, same for 5(1)

Therefore, you may use reset when you are working on your own branch, but use revert when you are working on a shared branch.

Now, since we have introduced this term, let’s talk about branch.

Use branches to collaborate on a project

An example of why you should use branches: You have released a game to players for testing, and you are working on adding another character. You received a bug report from a player and it needs to be fixed immediately. Option 1, without branches, you commit the current version with the unfinished character (such as a hero with infinite HP or 1 HP), then you fix the problem and commit again. Now all the players will start reporting this unfinished character.

The story of Nintendo’s Pokemon Go tells us a crashing game should not be seen by the players. BTW, I still couldn’t believe they made a fortune with that app.

The solution is to have two branches, say, one named “new_character” and one named “release”. Players only see the “release” branch, and you commit to “new_character”, go back to “release”, debug, commit, go back again to “new_character”, and work on the HP issue.

To start a new branch from a certain commit head, do

git branch new-branch-name starting-head-reference

Branch is almost just another name for head. To show all branches, do either one of the following two:

git branch -a

git show-branch -a

An example is given below. I have redone the whole repository to be clear – the previous example generated too much trash information.

As shown, there are two branches, master and work_progress. Now you should be able to understand what “On branch master” means. master is the default HEAD name, also the default branch name if you create a new one. To switch to another branch, do

git checkout head-name

(remember a branch is just a head?) NOTICE: all files in your directory will be changed to that commit. 

What we just did can be visualized as follows (remember HEAD is the current head):

You can now work on the file and do another commit. Since this commit won’t be seen on the master branch, let’s call it commit 3′. The change can be shown by the following:

As shown, on master branch the entry at 08/13/17 23:00 isn’t recorded. Vice versa, on the work_progress branch the entry at 08/13/17 15:13 isn’t recorded.

Now you might wonder, Hey, the bug fix is useful for my ongoing work too, how may I add that in the master branch? That’s the idea of (very important!!) merge

Merge files from other branches

Now imagine you added a file called addon.txt to fix the bug in the work_progress branch, now you want that to appear in your master branch. First, in work_progress, you need to add the new file by git add, then you need to commit it, and switch to master

In branch master, you do not see addon.txt. Now do

git merge work_progress

Now you see addon.txt, but you also see a conflict:

The addon.txt showed up, however the History.txt became like this, since work_progress also changed it:

This is a conflict. You need to resolve it. You may keep the current content (below <<<<<< HEAD) and also contents from work_progress (below ====== and above >>>>>>). Then add it and commit. Now, from git log, you’ll realize that we have effectively combined the commits from work_progress and master.

To visualize, what was done is basically:

To delete a branch, just do

git branch -d branch_name

Be sure not to leave a dangling commit when you delete a branch. For example, if you haven’t merged the commit 3′ from work_progress to 4, then you can’t delete it, since 3′ will become a dangling commit.

Now you know most things about the local usage of Git. It’ time to check Github and Gitlab: how to use Git online.

How to migrate contacts from Network Solutions Webmail to Gmail

For a complete migration, after the emails have been migrated, you probably also want the contacts in Gmail, too. Below are some instructions on how to do so.

First, login your Webmail and click on the Address Book column:

Click on the button to the right of “Global address book” (the three strokes thingy), Choose Export.

Then, choose vCard as the format. Click on Export. A file will be automatically downloaded to your computer.

Now log in your Gmail account. To the left page you may choose “Contacts” and see all the current contacts.

Click on the “Import Contacts…”, then the following window will pop out, click on “Choose File”, and select the vCard file you just downloaded from Network Solutions. Then click Import.

Now you should have all the contacts from your Network Solution Webmail!

Migrate emails from Network Solutions Webmail to G Suite

G Suite provides very powerful email MX records hosting. It integrates with Google Drive, Calendar, Documents, and much more. We are happy we could use G Suite to host our emails.

In the following I’ll use info@beamphysics.com as an example to show you how to migrate your old emails to the new G Suite environment. Step by step.

First of all, do all of the following when you think you are getting the least amount of emails to avoid possible interruptions.

1. your administrator will set up an account for you on Google

The admin will create an account “info@beamphysics.com” on G Suite. Notice companies like Euclid Techlabs requires this account to be identical to your old email address, but you may request for aliases; in other cases you may request an account from the admin.

An email will be sent to you after account creation. Use the information to log in your new G Suite account. (Notice that this temporary password is only apparent to you, but not to the administrator).

Use this to log in. After log in you may go to Gmail and start using other Google services.

2. Preparations for migrating your old emails

Now you have two accounts with the same email info@beamphysics.com. When you log in on Google from the above link sent by Google, you see something like this:

Your emails are still being sent to and stored by Network Solutions. It is the administrator’s responsibility to ask Network Solutions to switch the MX records hosting to G Suite. You are responsible to only migrate your emails (if you chose to do it by yourself).

OK, here is the hard part. We are using the IMAP (Internet Message Access Protocol) to migrate emails. You can think of it as to “authorize Network Solutions to release your emails to another party”.

So, you should have your Network Solutions Webmail password ready.

You also need a service account credential file, in JSON format (****.json), sent by the administrator. Notice: this file contains the company’s G Suite administration information and you should only use it but not read, edit, or distribute it. After the email migration you need to delete this file completely (not by dragging it into trash can, DO empty your trash can).

3. download the Gsuitemigration tool

Download GSuiteMigration.msi from

https://tools.google.com/dlpage/exchangemigration

If your computer warns you that “This file might damage your computer” and balabala, ignore it. Don’t ignore warnings for other MSI files from the Internet though…

Run the tool as the computer’s administrator.

4. create an excel table with your information

User accounts: Create a list of the user accounts that you are migrating. The list should be a CSV file in the following format:

user1#user1password, google_apps_user1
user2#user2password, google_apps_user2

The second column “google_apps_user1” can be left blank if the desired email is the same as the Network Solutions email. In our case they are both info@beamphysics.com, so the Excel to be used looks like this:

Where the censored black doodle is the password for info@beamphysics.com on Network Solutions Webmail. Replace that with your password.

5. Start the Gsuitemigration tool

Start the GSuiteMigration program, make it look like this (You need to replace beamphysics.com to whichever domain you are migrating from):

Notice that the dropdown list is blocked by the text box. Please select “Other IMAP Server” from the dropdown list.

Click on “Next”, now you are on Step 2 of 3.

In the first text box, enter your G Suite domain name. Usually it’s your company’s main website. Notice in many cases, a company can own many websites, such as that Euclid Techlabs owns euclidtechlabs.com and beamphysics.com. So in this case, even you are migrating emails on beamphysics.com, the G Suite domain name is still the main website: euclidtechlabs.com.

Next, select the JSON file the administrator sent you. This has been mentioned before. If you don’t have it, contact the administrator. 

Then, enter the administrator’s email address. This is provided by the administrator. Your G Suite could have multiple admins but this must match the creator of the JSON file. 

See below for a screenshot.

When you are done with Step 2, click on Next. Now you are at Step 3 of 3.

First select Email messages, and All.

For the “File of accounts to migrate”, select the CSV file you created from the above instructions.

Choose “Migrate deleted emails” in “Advanced Options” if you want.

Click Next. Now you are at the summary page, double-check all the settings and now you are ready to start.

Click Next. You will then start. First it will run some diagnostics. Then you can click start to migrate.

If you encounter any problems at this stage, contact the admin.

6. Log in your G Suite account again and see the emails migrated.

In your Google account, you may see the emails have been migrated.

Notice: all your emails in the Inbox will be automatically added to Inbox, however, emails in the folders will be found in _INBOX/Folder/SubFolder/SubsubFolder/… etc. See below. If you want to move them out to the upper level, click on the triangle to the right of the folder name and select “Edit”. 

 

You are done here. Thanks for reading! If you want to also migrate your contacts, please refer to the following tutorial:http://www.frankliuao.com/blogs/how-to-migrate-contacts-from-network-solutions-webmail-to-gmail/

A tutorial for CMake – simplized, and with examples.

What is CMake? Why CMake?

CMake makes writing Makefiles much simpler, and makes your Makefiles cross-platform. It makes your life easier, especially for C/C++ programmers.

Getting started: cmake and make gives you an executable.

Suppose you have a “Hello World” C++ program (any you could find on a online C++ compiler website default page). To make an executable, you could do

g++ -o HelloWorld -Wall -std=c++11 HelloWorld.cpp

(-W is for warnings, -std

Then you read about make and Makefiles, you changed the compiling to Makefile-style. You could create a Makefile that looks like below

HelloWorld: HelloWorld.cpp
    g++ -o HelloWorld -Wall -std=c++11 HelloWorld.cpp
clean: 
    rm -f HelloWorld

Everything fine. You can do

make
make clean

to generate the executable and clean the compile. However, when you compress the folder and send it to your friend, he/she fails to make it. Then you now wonder, should I change g++ to another compiler? No. You use cmake in this case

First, create a file called “CMakeLists.txt” in the current folder. Add the following lines to it.

cmake_minimum_required(VERSION 2.8.9)
project (HelloWorld)
add_executable(HelloWorld HelloWorld.cpp)

Save it. In the same folder, run

cmake ./

You will see the following screen output

-- The C compiler identification is AppleClang 8.0.0.8000038
-- The CXX compiler identification is AppleClang 8.0.0.8000038
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to:
/Users/frankliuao/Downloads/cmake_tutorial

You will see a Makefile, and many CMake-related files. Then you can do make and make clean to compile and clean. When put on a Linux (you could see I was using a Mac above), the output will become

-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /nustorm/data1/aoliu/HelloWorld/

You could see that although the two compilers are the same on both systems, the categories they belong to are different (GNU and clang). cmake is able to detect them and automatically generate Makefile to compile.

Compile your codes in a ./build/ sub-directory

As you could see, doing cmake ./ in the main dir actually creates junks in it. That’s ugly. In practice many people choose to invoke cmake  in a ./build/ sub-directory to avoid this. Plus, your source codes usually reside in the ./src/ folder.

In this example, we will build a new project called HelloComplex. I have moved the source  HelloComplex.cpp to ./src/. I’ll also show you how to add folders to include header files in them.

Suppose we want to include a header file Complex.hpp, which is nothing fancy but a class that enables some basic complex number operations. Conventionally this file will be put into the ./include/ folder. Let’s do so. The hierarchy of the main folder now looks like the following

Now, you may’ve noticed that besides CMakeLists.txt, there is now a new file cmake_make.sh, which is a BASH script as you could tell from its extension “.sh”. This is the key part of this section.

The contents of the BASH script are as follows

#!/bin/bash
if [ $# -ge 1 ]
then
  if [ $1="clean" ] 
  then
    if [ -e ./build/Makefile ]
    then
      cd ./build/; make clean; cd - 1>/dev/null
    fi
    rm -rf build/
  else
    echo "Command not found"
    exit 1
  fi
else
  if [ ! -d ./build/ ] 
  then
    mkdir ./build/
  fi
  cd ./build/; cmake ..; make; cd - 1>/dev/null
fi

If you are familiar with BASH scripting, it’s one of the simplest scripts; if not, basically you use it like make: ./cmake_make.sh builds the program, and ./cmake_make.sh clean cleans the build. It allows you to put CMakeLists.txt in the main directory, but does the build in the ./build/ directory instead. 

The CMakeLists.txt now reads:

cmake_minimum_required(VERSION 2.8.9)
project(HelloComplex)

if(NOT EXISTS ${PROJECT_SOURCE_DIR}/bin)
  file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
endif()

if(NOT EXISTS ${PROJECT_SOURCE_DIR}/lib)
  file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
endif()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)

include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(HelloComplex
  ${PROJECT_SOURCE_DIR}/src/HelloComplex.cpp)
Here are the explanations of the syntaxes:

First of all, most of the CMake syntaxes are accepted either in UPPERCASE or lowercase, such as cmake_minimum_required(), project(), etc. However, built-in arguments or variables, such as MAKE_DIRECTORY and ${PROJECT_SOURCE_DIR}, are better off in all capitals. User defined variables should be case-consistent throughout the file.

  • cmake_minimum_required(VERSION X.X): Specify the minimum version required to run this CMake file;
  • project(NAME): Specify the project name;
  • if()…endif(): Conditional statements;
  • NOT, EXIST: boolean operation and file operation keywords;
  • ${PROJECT_SOURCE_DIR}: directory of where the project is. In this case it refers to the main directory.
  • CMAKE_RUNTIME_OUTPUT_DIRECTORY, CMAKE_ARCHIVE_OUTPUT_DIRECTORY, CMAKE_LIBRARY_OUTPUT_DIRECTORY: CMake preset variables for executable output, link output, and library output, respectively;
  • set(variable, value): sets the variable to value;
  • include_directories(): add directories to search for header files;
  • add_executable(executable_name, source_files): build the source files to excutable_name

OK. Now it should be self-explanatory. Execute the BASH script and you will find the executable in ./bin/ and the junk in ./build/!

 

Adding user defined dictionary to Eclipse to add new words to spelling check

After installation of Eclipse, Eclipse automatically starts to check spellings for you. It uses its default dictionary file and you may find many words that you use on your daily basis do not exist (yet) in the default dictionary. How to add them?

Unless you provide a user-defined dictionary for Eclipse, no new words can be added. In order to do this, you may first download a standard US-English dictionary from:

http://downloads.sourceforge.net/wordlist/hunspell-en_US-2017.01.22.zip

Unzip the package after downloading. Copy the “en_US.dic” file to some folder (one that you keep Eclipse library files, for example. One that you don’t delete easily).

Open Eclipse-Preferences-General-Editors-Text Editors-Spelling, Make sure that the “Enable spell checking” is checked. In the “dictionary-User defined dictionary” section, copy the full path of the above pasted dictionary file. For me, it is

/Users/frankliuao/Documents/Eclipse/en_US.dic

Thus the page will look like this

Click Apply or OK. Now you will be able to add new words to the dictionary.  For example:

 

Start scientific computing on a new OS X

You got your new MacBook/Mac, and (of course) you are excited. Now you want to use it for scientific computing, let me get you started.

First of all, the programming environment on an OS X system is based on an App that is distributed in the App Store. Yes, in the App Store. You need to download the newest version to enable the newest features. Its name is XCode.

Download it from App Store. You need to sign in with your Apple ID.

Now you are ready to install the next important tool called macports. Macports integrated almost all the essential and fancy packages for you to do scientific computing. Here is its official website:

https://www.macports.org/

Download macports and install. After it’s installed, open a Terminal window (which is found in Launchpad-Other), type the following command

xcode-select --install

This installs all the command line tools macports needs. Then, accept the XCode license by

xcodebuild -license

Now you are ready to install ports from macports. You may go through the available list for all the ports you can install. From my own perspective, I found the following ones particularly useful:

  • python27, py27-numpy, py27-matplotlib, py27-ipython, py27-notebook
  • inkscape
  • cmake
  • openmpi

How to work with CMake and Netbeans (8.2 or newer) on OS X

After an exhausting search for a good IDE for C++, I finally stopped at Netbeans. I appreciate its convenient zoom-in/out feature, auto-completion, user-friendly interface, etc.

The first challenge I met was to set up the project to work with CMake, as I decided to think beyond the GNU make. I use a MacBook, therefore many programmer tools have to be “manually” installed, including CMake. In this journal, I’ll demonstrate how to set up a project in Netbeans to work with CMake on Mac OS X.

Pre-requisites

You need the following softwares to work with:

  • macports (Follow the website instructions to install)
  • Netbeans (Download “All”)

Preparations

After macports is installed, install CMake and tree on the command line in a Terminal:

sudo port install cmake tree

macports will find the pre-requisites for cmake and complete the installation. You can now test CMake by:

cmake -version

This will give you the version number of your CMake. Test tree program by just typing tree in the prompt and it will give you a hierarchy of the current folder. Now you are ready to go.

Working with a small C++ project

Here we use a simple example of a C++ program that uses its own header for complex numbers (not even close to complete but enough for demonstration), called HelloComplex

Supposedly you have written the header and source files and want to start a Netbeans project. The file hierarchy starts with the following:

The contents of each file shouldn’t be of great importance. However, the bash  file cmake_make.sh in this example is greatly useful for setting up Netbeans and also for even just CMake:

What it does is to limit the build from CMake in one directory in ./build/, so the Makefile and other CMake “junk files” will be in ./build/ . When one wants to clean the build, just do

./cmake_make.sh clean

The shell script will first look for an existing ./build/Makefile and do the designated make clean process.  Thereafter, the ./build/ directory is completely removed, and an empty ./build/ is created for the new build.

Letting NetBeans know where to find cmake

Before the project is created, go to NetBeans->Preferences->C/C++->Build Host. You should be able to see GNU there, like the following window:

Click on $PATH, which tells NetBeans where to look for binaries. Note that this $PATH is not necessarily the same as that as a system environment variable. Add the directory that contains the cmake command. As an example, on my computer cmake is in  /opt/local/bin/so I added it:

 

Start a NetBeans project with the above file hierarchy

So, NetBeans can find cmake from your system, so the cmake_make.sh can be executed.  Now go to File->New Project… The window below will pop out,

Click on Next, then  choose the root folder, such as below. Choose the modified GNU Mac. Choose Custom Configuration mode.

Check the box on Pre-build step is required, and choose the root folder to run in. Use the custom command in shell to do the build. In our case, it’s just ./cmake_make.sh  Be sure to change the accessibility to make it executable.

Hit Next, and then use the root directory as the working directory. Change the Clean Command and Build Command to ./cmake_make.sh clean and ./cmake_make.sh . Check the box for clean and build after finish.

Click on Next again, choose the source file location, which is the root directory in our case.

Click on Next, and choose Automatic Configuration (No figure for this step). The final step will be automatically completed by the software. Click on Finish, then the shell script will be executed automatically, as it was specified as the command to build the program. The following workstation should now be available, and the first pre-build should be done also.

You may run the executable in the ./bin/ directory in NetBeans, the output will be shown in the window.

Summary and reminders

This blog only describes how to start the NetBeans project from existing files, but does not include the details of CMake and C++ codes being used. If you are interested, please read my other blog on CMake. You should be able to click on Run from now on. Work on the source files including headers, re-build, and run!

Comments or questions, if any

Please leave them in the comments below. I’ll try to improve my blogs. Thanks!

美高校毕业生申请OPT攻略 – 言简意赅无废话!

什么是OPT

Optional Practical Training (OPT), 就是让学生毕业后能留美工作的手续

谁能办OPT

本文主讲毕业生办OPT的流程。但在读F-1学生也可以申请pre-completion OPT,只需要在学校呆满1年即可。毕业生办post-completion OPT.

办OPT顺序

    1. 大概毕业前3,4个月的时候,跟老板确定大概哪个月份毕业。假设定5月1。注意是毕业时间不是答辩时间!答辩在毕业前,之后要交论文稿件预留时间;
    2. 跟学校international office说一下,要求开始出具OPT的证明。IO会咨询老板意见,老板confirm。IO给你一个新的I20,上面指明是给OPT申请用的。会有一个targeted graduation date;
    3. 毕业前3个月的时候(最早90天前交材料),把材料寄出:需要的材料quote如下: To complete your OPT application, please do the following:
            • Print your name, sign, and date the I-20 where indicated.
            • Make a copy of the I-20 once you’ve signed it. You will keep the original and the copy will go in your application packet.
            • Assemble the OPT packet in the following order:
              o   I-765 (top page)
              o   Page three of I-20 copy
              o   Page one of the I-20 copy
              o   Copy of your passport identity page
              o   Copy of your paper I-94 card, front and back OR print out of your electronic I-94 record
            • Staple your bagged passport photos to the upper right corner of the I-765 only.
            • Staple your check/money order to the top center of your I-765 only.
            • Staple the entire packet together in the upper left corner.
    4. 寄出材料。与此同时,准备答辩材料,开始找工作,跟公司说明5月2号之后可以工作。公司HR会明白,发offer的时候上面start date会写5月2号或者之后,但最好不要太晚,因为OPT期间失业天数有限。如果start date是5月11号,但5月1号拿到了EAD卡,这10天就是unemployed status。
    5. (难点): 假如file太晚,毕业之后还没拿到EAD卡,这段时间都算失业期,即使批准了还没到手也算;file也不能太早,90天限制。
    6. 4月某天答辩,催一催USCIS,大概5月1号或者之后拿到OPT EAD card,去公司报道。

注意

先跟老板沟通好毕业时间。毕业时间决定了答辩时间和申请OPT的时间。OPT批准时间多则2,3个月,邮寄等等都需要count在内,不可轻视。宁可早点拿到不要晚。OPT加急非常麻烦,一定要早点行动。