Apple Watch Followup Review

July 1st, 2015

I’ve been wearing my Apple Watch for over a month now, and I must say, it’s lived up to my expectations as a fitness device and “iPhone extender.” Due to the watch’s minimalist interface, navigating through the watch’s features without consulting the user manuals is like wandering through a large, confusing mansion without a map. Thankfully, the companion iPhone app includes a library of informational and instructional videos that guide the user through tasks such as customizing the watch face, making phone calls, and using Apple Pay. In this post, I will write a followup review to my previous Apple Watch review, highlighting the features I’ve enjoyed most and elaborate a little more on how the Apple Watch has helped me establish a more active lifestyle.

Noteworthy Features

Here’s a brief summary of some of the ways my Apple Watch has made my life easier:

  1. Apple Pay. Although most stores I frequent have not yet implemented a system for accepting Apple Pay, it’s been a delight to shop at stores that do for one main reason: I’m lazy. In fact, I’m so lazy that I find it a pain to dig through my backpack every time I want to make a cashier purchase. Due to a recent car break-in/robbery, I’m extra paranoid that someone will steal my backpack if I don’t have it on me at all times. Also, I easily misplace things, so it makes sense to my lazy brain to keep my stuff in one place. Consequentially, I practically carry a suitcase on my back everywhere I go. It’s embarrassing to rummage through my bag trying to find my wallet while a line of people grows behind me at the checkout. It’s a lot less embarrassing to just hold out my wrist over the card reader until I hear the satisfying “ding” of a completed transaction.

  2. iPhone Locator. Part of my laziness is due to my brain’s lack of RAM. The human brain is said to only keep track of three or four moving balls on a screen cluttered with lots of moving balls. Likewise, my brain forgets where I put my phone a lot since I carry a lot of little to-do items in my brain’s “RAM.” Recently, I misplaced my phone (again). I was too lazy to log into iCloud to use the Find my iPhone service, which is a great service to use if you suspect your iPhone has been stolen since it tracks its GPS location. The watch does not use GPS, however. You don’t need to sign into iCloud to use it either. All you need to do is swipe up on the main screen and scroll through the various “glance” pages until you get to the screen entitled “Connected.” If you press the ping button, your iPhone will start making a loud, high-pitched sound (regardless of the volume you left it at) as long as the phone is within Bluetooth range of the watch.

  3. Workout App. I’ve used the watch’s built-in workout app a few times and found it pretty interesting. For those who want detailed information about their workouts, this app seems to be just what the doctor ordered! It creates a report of your heart rate on a moment-to-moment basis so that you can see how hard you really exercised and precisely when your heart rate peaked and valleyed. The workout app lets you choose the kind of activity you want to do and the number of calories or minutes you want to burn during your workout. It also keeps a record of your workout data. Because the Workout app has so many bells and whistles, I don’t really use it. My lazy brain much prefers my favorite feature of the app: the passive activity monitor.

  4. Activity App. Out of all the features I use, the Activity app is, by far, my favorite. This feature has literally changed my life. In the past I used to sit in one place for hours to the point where I developed back pain and carpal tunnel syndrome. Being the lazy person I am, I could use a personal assistant to remind me to get off my lazy ass every now and then. Even more motivating than the built-in “stand coach” is the progress meter for measuring cumulative minutes of exercise and active calories burned. At first, I thought the goals were too easy, but in reality, it takes some effort to walk at least half an hour per day, especially with a crammed schedule. By achieving my activity goals in a consistent manner, the Watch rewards me with little badges (similar to the icons Call of Duty players unlock for reaching certain milestones in the game). When it comes to making fitness a lifelong habit, “gamifying” is the best way to go, at least in my experience.

Buy Apple Watch now from Amazon

Categories: Reviewstechnology


Towards a Third Age of Computing

June 22nd, 2015

On Friday, Tony Hey gave a fascinating lecture at the Computer History Museum about the evolution of computing. With a background in particle physics and, later, data science, Hey coauthored The Computing Universe: A Journey Through a Revolution (2014). It’s a colorful layperson’s introduction to some of the most important ideas and historical events in computing. According to Hey, computing has gone through three significant stages in history. Each of these stages highlights an emergence of new technological breakthroughs and purposes for computing.

Age 1: The Beginning of a Revolution

The first age of computing was marked by an emergence of the Von Neumann architecture (a.k.a. stored-program computers), and following that, an explosion in the transistor density of microchips. Early electronic computers, such as the ENIAC, were basically gigantic calculators with no ability to “remember” operations. The first stored-program computer, the EDSAC, emerged in the middle of the twentieth century. It used paper tape for storing information, which was represented by the patterns of punched holes in the tape. IBM followed suit and started mass-producing mainframe computers that read in programs through punched cards. Hey called this period the “IBM Mainframe Era.”

In the 1950s and 1960s, computers were not personal household items yet. They were simply too big and expensive to justify home use. Eventually, that started to change. A phenomenon known as Moore’s Law started to emerge. Moore’s Law is a prediction about the rate of improvement in microchip technology. According to Moore’s Law, the number of transistors in computer processor chips has doubled approximately every two years. This has been the trend since 1965.

Consequentially, as these computer chips became increasingly cheap and compact, computers became smaller, more powerful, and more affordable. In 1973, the first desktop computer (the Xerox Alto) entered the market. Three years later, the Dan Bricklin invented the first spreadsheet app. As computers became more ubiquitous and versatile, a new purpose started to emerge.

Age 2: Computers for Communication

The second age of computing is defined by the emergence of computer networks and the World Wide Web. The ARPANET, which was a tiny prototype of the modern Internet, only spanned a few computers in the United States. Researchers used this network to share documents. Later, Tim Berners-Lee proposed the concept of hyperlinks, which allow people to link pages in addition to share them. With the advent of hyperlinks, the World Wide Web was born in the early 1990s.

Just as transistor density exploded during the birth of the computer revolution, the Internet and Web grew prolifically. The founders of Google pioneered an algorithm for ranking web pages in search results based on page popularity, making it easy to browse the web. Now a great deal of commerce and collaboration happens across the Internet, making it the lifeblood of modern civilization. Ideas can spread faster than ever before.

Age 3: Computers for Embodiment

Tony Hey argues that we are entering an age where computers are starting to take over tasks that once required the presence of human beings. This emergence is largely the result of improved artificial intelligence and “the Internet of things.” Smart devices such as phones, cars, and refrigerators can connect with the Internet to communicate with the outside world and respond accordingly. For example, smart cars take in map data from the Internet as well as real-time sensory data from motion-sensing to predict collisions and reduce the probability and impact of accidents.

Of course, with these advances in smarter devices, users are increasingly vulnerable to the consequences of hacking. Hey’s presentation included a videoclip of a reporter riding in a smart car that has been hijacked by a programmer. The programmer took full control over the car, causing it to run through a stop sign and barrel over traffic cones. Of course, it was just a demonstration. In real life, it would have been absolutely terrifying!

Another consequence of computers taking over human jobs is unemployment. We are entering an age where people have to compete with mere machines to stay relevant in the workforce. This has an immediate negative effect on people who lose their jobs and the relevancy of their skillsets. In the long term, however, I’m hoping that we can outsource dangerous, boring jobs to machines and enable people to do the fun, creative stuff.

Age 4: Conscious Computers

As we look into the future, we can predict that computers will probably one day possess human level intelligence. As of now, our technology still has a long way to go. Some recent breakthroughs show that computers are becoming more efficient at playing games like chess and jeopardy; but even so, these supercomputers lack awareness.

When computers do gain apparent human-level consciousness, how will we know whether they truly have human-like experiences or whether they are just imitating humans? Perhaps then, we will have the means to look inside the subjective experience of brains to see what others are experiencing; but that is a topic for another day!

Book Signing

At the end of the talk, I bought a copy of The Computing Universe and got it signed by Tony Hey, himself. I told him I wanted to give the book to my dad as a Father’s Day gift. He inquired, “You’re going to read it to, I hope?” Of course! I hope to do much more than read this book. I want to be a part of its story.


Categories: Reviewstechnology


AI in Cinema: Her

June 6th, 2015


I’ve never seen a more convincing depiction of a love affair between a person and a computer as the one shown in the movie, Her. Directed by Spike Jonze in 2013, Her is a refreshingly humanistic portrayal of artificial intelligence. The film is low on action, but it doesn’t need it. This is not another cautionary tale about a dystopian future in which technology attacks. Instead, it’s a story about how people (conscious AIs included) fall in love, grow, and change.

What I particularly enjoyed about the movie was its subtlety. The plot was mainly driven by introspection. To make these emotions tangible to the viewer, the mood of a scene was conveyed through artful shots of the environment. For example, when tensions are high in one particular scene, the screen zooms in slowly on a teapot starting to whistle; on the brink of boiling over. The movie conveys the loneliness of being in a crowded room through its montages of human faces passing by. Viewers get the sense that the world is colorful, alive, and generally peaceful. In short, H​er​ depicts the kind of future I personally hope to live in.


Categories: Artificial IntelligencephilosophyReviews


Beginners Guide to C++ (Udemy)

June 1st, 2015

With Udemy’s permission (and kind invitation), I am reposting a great article for those just getting started with C++ programming. Not only is it an excellent resource for C++ beginners (and beginning programmers in general), its a concise and well-worded overview of the things I learned during my first year of computer science studies.

What this article makes clear is that C++ is designed for building software that works closely with the low-level components of the computer. Unlike higher-level languages like Java, C++ allows the programmer to directly manipulate memory via pointers. Learning C++ is a good idea if you want to understand how computers work on a low level.

As a first language, I found C++ to be challenging, but not frustratingly difficult to master. When I was first learning the language, well-written and well-illustrated learning materials were scant on the Internet, which is what motivated me to start creating computer science tutorials on my first YouTube channel, KarBytes. The Udemy article is something I wish I had when I started my adventure as a computer science student a few years ago.

Without further ado, here is the lovely article. Thanks Tiffany!


Table of Contents

  1. Introduction
  2. Getting Started
  3. Hello World
  4. The Language
  5. An Application
  6. Conclusion

1: Introduction

C++ is a general purpose programming language. Its powerful and offers its developers a wide range of programming paradigms. The language is often favored by those who are building software that interacts with low-level resources or the hardware of a computing device; even a large number of desktop applications prefer C++ due to its light weight runtime and flexibility. The language provides facilities that many other languages simply refuse to possibly in order to keep things sane and simple. For example, with C++ it is possible to do low-level memory manipulation, which makes it an ideal choice for building hardware drivers, operating system kernels, software that runs on embedded systems, etc.

Image taken from the original Udemy article.

The wide array of features that C++ provides and the numerous ways of doing anything in C++ makes it a difficult task to put everything about this language in one post. In this article, we make an attempt to briefly touch on some aspects of the language that should let a programmer with some experience in other object oriented languages get started with C++.


2: Getting Started

Getting started with C++ is quite easy on most platforms. All you need to do is install a compiler suite of choice, and you are good to go. Unless, of course, you prefer a particular integrated development environment (IDE). In which case, you can simply download one of the popular IDEs for C++ that is available for your platform, and use it.

On Linux, you may want to use the GNU Compiler Collection (GCC) for most of your C++ needs. On most Linux distributions, installing this compiler collection usually requires a single line of command, unless the compilers are already installed on your system. For example, in Arch Linux all you have to execute in your terminal is:

sudo    pacman    -S    gcc

On OS X, a C++ compiler (variation of LLVM) is already included, which should be sufficient for this beginners tutorial.

On Windows, however, installing GCC might be a little more difficult. There are many IDEs available (such as CodeBlocks with MinGW) that you can possibly download as they come bundled with a set of compilers. Or, you can install MinGW separately. Otherwise, you can always use Microsofts version of C++ by installing Visual Studio which can often be a better choice given the ease of getting started.


Hello World

What purpose does a programming language serve if it doesnt allow you to print the text Hello, world! to your terminal? The very first C++ program that we will look at is one that prints this simple text to the terminal. Create the following file and name it hello.cpp:

#include <iostream>
using namespace std;

int main()    
{
      cout << "Hello, world!" << endl;
      return 0;
}

To run this program, you must first compile it using a C++ compiler of your choice. We will be using the C++ compiler in the GNU Compiler Collection from the terminal throughout the article. If you are also using that, this is what you should be executing in your terminal to compile the program:

g++ hello.cpp

If all goes well, you should notice an executable file named a.out next to hello.cpp (on Windows, the file will be named a.exe). You may run the compiled program now from your terminal on *nix systems by issuing the following command:

./a.out

On Windows:

a.exe

This should print the following line of text on your terminal:

Hello, World!


Directives

The way C or C++ compilers work is it turns your source code into executable programs in three high-level phases (preprocess, compile, and link). The first phase involves a preprocessor that handles all the directives every line of your code beginning with a hash symbol. In this case, #include instructs the preprocessor to include the header file associated to the standard library iostream. This, in essence, enables you to import functionalities into your code from external implementations; just like the import statements in Python, Go, etc., or the require function in Node.js. The underlying behavior of the #include directive is different, a bit more simple: it merely copies the contents of the named files in the spots where these directives appear.

Namespaces

C++ provides a mechanism namespaces that allows a bunch of functions and classes to be grouped under a named scope. This helps avoid name conflicts in large projects. Everything inside the standard library of C++ is declared within the std namespace. Without declaring using namespace std; in our program, we would have to prepend references to every element of the standard library with std::. For example, instead of writing cout << …”, we would have to write “std::cout << …”.

Entry

In C++, the entry point of any program is the main function. The signature of the main function is int main(). However, int main(int, char*[]) is also acceptable which we will eventually take a look at later in this tutorial. The small bootstrap code that invokes your main function expects it to return the exit status of the program as an integer. Ideally, a program that runs and exits successfully yields an exit status of zero. Non-zero exit statuses are used to indicate different types of failure. In this program, we always return a zero.

Streams

As you might have guessed, the line of code that actually prints Hello, world! to your terminal is cout << “Hello, world!” << endl;”. The line itself may look self explanatory – you are _pushing_ (<<) a piece of text into “cout”, that somehow prints it to the terminal. In this case, “cout” is an object that represents the standard output. In C world, it corresponds to the stream stdout. Finally, “endl” is what puts a new-line character at the end of the stream and forces the content of the stream to be flushed to the destination, which, in the case of stdout, is the terminal.

The Language

C++, in terms of syntax, has some similarities to C. In many ways, C++ is a superset of what C offers. The following are some brief outlines about a few aspects of C++, which is hardly comprehensive, but should help us cover some general concepts and get used terminologies essential for the rest of the article. Unlike most other languages, C++ doesnt limit you to a single paradigm of programming. Other aspects, such as templating and exception handling, are being completely left out for some more advanced tutorials of C++.

Variables

C++, being a strongly-typed language, requires you to explicitly declare variables. A declaration typically involves indicating the name and type of a variable. An integer variable named num can be declared as follows:

int num;

To declare and initialize a variable at the same time, you can do this:

int num = 5;

C++ also allows you to declare arrays by simply appending a pair of square brackets after the variable name and putting the size of the array in between them:

int arr[10];

This declares an array by the name arr that can hold 10 integers. However, declaring arrays like this require you to know the size while you are writing the code. This is often not desirable, and that is where you need dynamic allocation of arrays. In C++, it is possible to dynamically allocate an array using the keyword new[]:

int size = 10;
int arr[] = new int[size];

You may be wondering, how is this any different from the previous method of declaring arrays? After all both, are declaring an array of size 10. The difference is that in this case, size is a variable. And size doesnt always need to have the value 10. In fact, it can be any number, as long as your system memory is large enough to contain that array.

Speaking of memory, it is important to understand that in C++ not all memory allocations are treated equal. When you are declaring an array, the C++ runtime is allocating some memory for it. However, depending on how you allocated that array (or object), the memory may not be deallocated automatically. This is where C++ is significantly different from other programming languages that are garbage collected. In languages such as Python or Go, memory is deallocated by the garbage collector when it is no longer in use. In C++ not all allocated memory is deallocated automatically.

Whenever you use the new or new[] keyword, the memory allocated for that has a dynamic lifespan. And hence, it is only deallocated through an explicit use of the delete or delete[] keyword. From the example above, the array created through invocation of the new[] keyword will only be deallocated if the following code is executed:

delete[] arr;

Types

Like most typed languages, C++ comes with a handful of primitive types: bool, char, int, long, float, double, etc. Most of these types differ from one another based on the size data type that it can hold on to.

Most of these were already available in C, but C++ takes it a step further with things like the standard string library. By including the string library, you get better ways of managing strings of characters, compared to handling arrays of characters:

#include <string>
using namespace std; 
int main() {
     string s = "an important string";
     return 0;
}

Operators

Variables are just part of a programming language, and incomplete without operators. For all primitive types in C++ there is a large number of operators available. Ranging from simple assignment operators to a plethora of arithmetic, logical, and bitwise operators. C++ even lets you define custom operator behaviors by letting you overload them. A standard library and its custom types make really good use of this feature.

  • Arithmetic operators: +, -, *, /

  • Comparison operators: ==, !=, >, <, >=, <=

  • Logical operators: !, , ||

  • Bitwise operators: , |, ^, ~, <<, ≶≶

  • Pointer operators: *, , ->

  • And more

Some of these operators can be combined with the assignment operator to form much more concise expressions in some cases. For example:

a += b // equivalent to a = a + b

Flow Control

C++, just like C, comes with a bunch of conditional and loop constructs. It includes, but are not limited to, if-else statements, for and while loops, and more. Most of these behave almost exactly as you would expect them to, except in some cases.

if (month == 0) { 
    cout << "January"; 
} else if(month == 1) { 
    cout << "February"; 
// ... 
} else if(month == 11) { 
    cout << "December"; 
} else { 
    cout << "not a month"; 
}

The construct above can be replaced with a switch statement.

switch(month) { 
     case 0: 
         cout << "January"; 
         break; 
     case 1: 
         cout << "February"; 
         break; 
     // ... 
     default: 
         cout << "not a month"; 
}

However, switch statements are only limited to integer (int, long long int, etc.) and character (char) values and variables, and will not quite work with strings, which you may have seen being possible in languages like Go and JavaScript.

In C++ you have multiple ways of writing a loop statement. There is while, do-while, and for.

while(n > 0) { 
     // ... 
}

The code inside these curly braces will be executed repeatedly, as long as the condition (in this case n > 0) evaluates to true.

Functions

Functions in C++ have two parts: the signature and the body. As you would expect in any strongly-typed language, the arguments and the return type of the function must be explicitly mentioned. The following is the signature of a function that takes two int arguments and returns an int:

int add(int a, int b);

The implementation of this function can look something like this:

int add(int a, int b) { 
     return a+b; 
}

It is important to remember that the order in which these functions appear in a source code file is very important. If you want to use a function, it must be declared before it is called. For example, the following program will simply refuse to be compiled:

int sub(int a, int b) { 
     return add(a, -b); 
} 
int add(int a, int b) { 
     return a+b; 
}

One thing that we can do to fix this is to move the function add above the function sub. However, that may not work in situations where there is a circular dependency. What if add depended on sub, and somehow sub depended on add? In most cases, the way we fix this is through declaring the functions first and then implementing them later on. In C++ you can declare a function just by stating its signature, and later on complete the implementation by defining its body:

int add(int a, int b); // Prototype of function add 
int sub(int a, int b) { 
     return add(a, -b); 
} 
int add(int a, int b) { 
     return a+b; 
}

Classes

Classes in C++, are meant to give data structure within your application. It is similar to struct used in C, with the added benefit of being able to define methods on them, as well as polymorphism. In fact, a minimal class looks very much like a struct in C:

class Fruit { 
public: 
     bool isCitric; 
     double weight; 
private: 
     bool isEaten; 
};

Here, the name of the class is Fruit, and it has two public attributes (isCitric and weight) and one private attribute (isEaten). Adding methods to the class is a two step process. The method signature is declared inside the class definition, and their implementation is added afterwards.

class Fruit { 
public: 
     // ... 
     void eat(); 
     // ... 
}; 
void Fruit::eat() { 
     this->isEaten = true; 
}

Notice how this is similar to declaring function signatures and implementing their behavior later on. We can instantiate an object of this class by simply declaring a variable of this type:

Fruit f;

Here f is a variable of type Fruit. To access an attribute or a method of this object, we can use the structure reference operator:

f.isCitric; 
f.eat();

When it comes to C++, these are separated into two files, usually for every class. A .h file which contains the class definition and method signatures and a .cpp file which contains the implementation of the methods. For example, for our Fruit class we could create two files named fruit.h and fruit.cpp. The first file fruit.h would contain the definition of the Fruit class. The second file fruit.cpp would contain the implementation of the Fruit::eat method. Classes in C++, as you would expect from any polymorphic programming language, can extend other classes through a simple syntax:

class Orange : public Fruit {};

Classes can also have one or more constructors and a destructor. These elements of a class are defined and declared in ways similar to that of methods, with some minor differences:

class Orange : public Fruit { 
     Orange(); // Constructor 
     ~Orange(); // Destructor 
}; 
Orange::Orange() { 
     this -≶ isCitric = true; 
     // ... 
} 
Orange::~Orange() { 
     // No-op 
}

In this snippet of code above, what we are doing is declaring a class that extends the class Fruit with a constructor and a destructor. Constructors are declared in a way that is similar to declaring methods, except that they do not have any return type and have the same name as the class itself. Destructors are also declared similarly, with the additional tilde symbol appearing before the name.

If you are already familiar with some other object oriented programming language, picking up on classes and inheritance in C++ should be simple. But that should not be a reason to underestimate the power of polymorphism in C++. There are a number of relevant features that are not often seen in other languages (such as friend classes, operator overloading etc.), which when used properly, can result in very elegantly coded programs. However, what is essential for us to realize is that these flexibilities, when used irresponsibly result in mistakes that are both hard to find and understand.

The purpose of this section was to show a simple example of classes and inheritance, and not an absolute guide to polymorphism in C++, as that itself must be built on solid understanding of what exactly polymorphism is, which is too large to currently explain.


4: Pointers

Pointers are a whole new world. They are special kind of values that let you access and manipulate memory in a completely different way. Typically, a variable is a way for us to address a certain portion of the computers memory. However, you do not have much control over what portion of the computers memory you are referring to.

Image taken from the original Udemy article.

There are two pointer related operators that we must know about at the very least if we want to use pointers in C++: and *.

The ampersand is an address of operator. Lets say you have an integer variable named x. Any time you write x, it evaluates a pointer to variable x what it means is that it evaluates to the address of the memory location where the variable x stores its value. The asterisk, on the other hand, has two uses (apart from its role as an arithmetic operator multiplication). When you declare a variable, putting an asterisk in front of the name makes it a pointer variable.

int *ptrToX;

If you were to initialize this pointer variable with an address, for example:

int x = 5; 
int *ptrToX = &x;

and if you tried to inspect the value of p, what you would see is a number that represents the address of the memory location where x stored the value 5. This, would be of much use if you could not retrieve the actual value via a pointer. This is where the second use of the asterisk operator comes in: indirection. If you were to inspect the result of the expression *ptrToX, instead of just ptrToX you would actually get the value 5. When it comes to pointers to objects, especially accessing attributes and methods of objects, using pointers can lead to messy code. We may have a pointer to an instance of our Fruit class, and we want to access the method eat of that instance. To do that, we can use the indirection operator to first obtain the value, and then use the structure reference operator to access a member or method of the object:

Fruit f; 
Fruit *ptrToF = &f; 
(*ptrToF).isCitric; 
(*ptrToF).eat();

Or, we can use a special operator known as the structure dereference operator to do the same:

ptrToF -> isCitric; 
ptrToF -> eat();


5: An Application

To provide a more hands on learning experience, we will implement a small todo application in C++. The objective is to walk through the code of this application, and understanding how the language and the standard library play their parts in the implementation. A number of robust user interface toolkits are available that work really well with C++. Qt is such a toolkit that is cross-platform, and in fact one of the most well built. However, to keep things simple we will build our todo application to only work through a command line interface.

We will begin with an empty directory for our project. Next we create our first .cpp file ytodo.cpp. Let us create the file and populate it with an noop, but valid, C++ program:

int main() { 
     return 0; 
}

Let us build the application by executing the following command in the terminal:

g++ *.cpp

and run the compiled program:

./a.out

Remember, on Windows it will be a.exe instead of ./a.out. You will notice the program has been compiled and that running it produced no output in the terminal which is expected, given the program is empty.

Since we are building a todo application, we should at least define a simple class that would represent each individual task, including the tasks title and done state. Let us create another file, name it task.h and populate it with:

#include <string> 
using namespace std; 
class Task { 
public: 
    string title; 
    bool done; 
};

As you already know, .h files are where declarations reside. Since our Task class does not have any method yet, we can skip creating a .cpp file for it now.

Next, we need to be able to handle command line arguments. If you can recall, the entry function main has variant where its signature accepts an integer and an array of character arrays. These parameters of the main function will allow us to determine what command line flags or arguments were included when the command was run. This means our main function should now have the following signature:

int main(int argc, char* argv[])

Here, argc is an integer indicating the number of arguments (elements) to expect in the array argv. Each element in argv is an individual argument from the command line. For example, running the built program as:

./a.out add "Learn C++"

Will set argc to 3, and argv to an array of 3 elements: ./a.out, add and Learn C++. Initially we want to implement three subcommands for our todo application.

  • ls/list: list all tasks

  • dd: add a new task

  • mark: mark a task as done

But before we can do that, we must add a few lines of code to help us parse these command line arguments easily:

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

using namespace std; 

int main(int argc, char *argv[]) { 
     map <string, int> scmds; 
     scmds[""] = 1; 
     scmds["ls"] = 1; 
     scmds["list"] = 1; 
     scmds["add"] = 2; 
     scmds["mark"] = 3; 
     string arg1 = ""; 
     if(argc > 1) { 
         arg1 = string(argv[1]); 
     } 
     if(scmds.find(arg1) == scmds.end()) { 
         cout << "Invalid: " << arg1 << endl; 
         return 0; 
     } 
     switch(scmds[arg1]) { 
         case 1: 
             cout << "Unimplemented: ls" << endl; 
             break; 
         case 2: 
             cout << "Unimplemented: add" << endl; 
             break; 
         case 3: 
             cout << "Unimplemented: mark" << endl; 
             break; 
     } 
     return 0; 
}

There are a few things worth mentioning regarding this code. First of all, the standard library headers included. The first one, iostream, is something we are already familiar with from our Hello World example. The second and third headers are what provides us with a map data structure (similar to a dictionary or hash in other languages) and string implementation.

Inside the main function, the very first thing we are doing is creating a map named scmds. The map has string keys and int values. The purpose of this is to create a mapping of subcommand names (strings) to unique integers representing the action to perform. Notice how we assign the same number for ls and list, making them aliases to each other. Then, we determine if we have at least two arguments. If yes, we take the second element from the argv array and store it as a string in arg1. Otherwise, we set it to ls, making it the default action when a subcommand is not included. Next we determine if a valid subcommand was issued by checking our map for the keys existence. When you make an attempt to find a key that doesnt exist in the map, as per specifications, the map returns an iterator value equivalent to the one returned by the end method of the map.

Finally, we switch based on the numeric value obtained from the map for the specific subcommand name and perform a task for now we just indicate that the actions are not yet implemented.

You can compile and run the application by executing:

g++ *.cpp 
./a.out

Adding Tasks: Files and Vectors

Let us now implement the add action. To do this, we need to accomplish three things:

  • when the user tries to add something to the todo list, store it in a in-memory data structure

  • when the application exits, store the contents of that data structure in a file

  • when the application starts, read the contents of the file to restore the state of the data structure.

here is how we can do it:

#include <fstream>
#include <iostream>
#include <map>
#include <string> 
#include <vector>
#include "task.h" 

using namespace std; 

vector <Task> tasks; 
void load() { 
     ifstream ifs("tasks.ytd"); 
     string l; 
     while(getline(ifs, l)) { 
         Task t; 
         t.done = l[0] == '1'; 
         t.title = l.substr(2); 
         tasks.push_back(t); 
     } 
     ifs.close(); 
} 

void save() { 
     ofstream ofs("tasks.ytd"); 
     for(vector <Task&lgt;::iterator it = tasks.begin(); it != tasks.end(); ++it) { 
         ofs << (it -> done ? 1 : 0) << " " << it -> title << endl; 
     } 
     ofs.close(); 
} 

string clean(string s) { 
     string r = ""; 
     for(int i = 0, l = s.length(); i < l; ++i) { 
         if(s[i] == '\r' || s[i] == '\n') { 
             r += ' '; 
         } else { 
             r += s[i]; 
         } 
     } 
     return r; 
} 

int main(int argc, char *argv[]) { 
     load(); 

     map <string, int> scmds; 
     scmds[""] = 1; 
     scmds["ls"] = 1; 
     scmds["list"] = 1; 
     scmds["add"] = 2; 
     scmds["mark"] = 3; 

     string arg1 = ""; 
     if(argc >= 2) { 
         arg1 = string(argv[1]); 
     } 

     if(scmds.find(arg1) == scmds.end()) { 
         cout << "Invalid: " << arg1 << endl; 
         return 0; 
     } 

     switch(scmds[arg1]) { 
        case 1: 
             cout << "Unimplemented: ls" << endl; 
             break; 
         case 2: 
             if(argc != 3) { 
                   cout << "Missing task title" << endl; 
                   return 0; 
             } else { 
                   string arg2 = string(argv[2]); 
                   Task t; 
                   t.title = clean(arg2); 
                   tasks.push_back(t); 
             } 
             break; 
         case 3: 
             cout << "Unimplemented: mark" << endl; 
             break; 
     } 

     save(); 
     return 0; 
}

From a quick look, we can tell that three new functions have been added and some changes have been made to the second case of the switch statement in the main function. But at the same time, a couple of new headers have been included as well. Let us walk through the changes. First of all, the new standard library headers, namely fstream and vector provide the application with file reading/writing capabilities and a dynamic array-like data structure.

The fstream standard library header is similar to iostream, but instead of providing convenient stream access to the standard input/output, fstream provides similar ways of handling files. This time, we have included another header that belongs to our own project ./task.h. This is how we include the declaration of Task class in our application.

Just below the using namespace declaration, you can see a new variable declaration. Here, we have declared a vector named tasks. The vector will only store task objects, indicated by the mention of the class name within the angle brackets. So, a vector < int > type would actually be a vector of integers, just like vector < Task > is a vector of our class Task. Next, out of the three new functions, the third one is the simplest: it takes a string, replaces all the newline and carriage return characters with ordinary space, and returns the new string. This is something we will use to clean up the task title that we get as an argument.

In our load function, we instantiate an ifstream (input file stream) and point it to the file named tasks.ytd. We then use the standard getline function to fetch one line at a time from the file. We assume that each line is an individual task where the first character is either a 0 or a 1 (indicating not done and done), and the rest of the line after a space is the tasks title. If the file doesnt exist, getline will immediately return a value that will cause the while-loop to not run at all. For every line that we process, we create a task object, set the title and done state, and push it to the tasks vector.

The save function, as you would expect, does the reverse of the load function. It loops over every task stored in the tasks vector, and puts them in the tasks.ytd file. By default, ofstream (output file stream) opens the file and replaces its contents with what you write to it. The for-loop is a bit of a handful. First of all, the type of the value we iterate on looks a little alien. This is because, when looping over a vector, it is actually convenient to use an iterator object provided by the vector. The way it works is you call the vectors begin method to get an iterator pointed at the very beginning of the vector. At every step, you increment the iterator to move it to the next element. The iterator itself behaves like a pointer, so you need to dereference it to access the actual value. You continue the loop until the iterator reaches the end. You treat ofs as you would treat cout, by streaming data into it. Once all the data has been passed to ofs, you close the file.

Finally, in the second case that handles the add subcommand, we check if we have sufficient number of arguments. If yes, we create a task object and push the tasks vector. The load and save function invocation at the beginning and end of the main function handles the synchronization of the in-memory and file-based data storage for this application. You can now compile the application:

g++ *.cpp

and try adding a task by executing:

./bin/ytodo add "Learn C++"

You will notice that a file named tasks.ytd has been created. Opening it with your favorite text editor should show the task you have just added:

0 Learn C++

Listing Tasks

At this point, implementing the ls subcommand should be a simple feat:

int main(int argc, char *argv[]) { 
     // ... 
     switch() { 
         case 1: 
             for(int i = 0, l = tasks.size(); i < l; ++i) { 
                 Task t = tasks[i]; 
                 cout << (i+1) << ". " << t.title << " [" << 
                 (t.done ? "X" : " ") << "]" << endl; 
             } 
             break; 
         // ... 
     } 
     // ... 
}

Here, we loop from 0 to l, where l is the size of the vector tasks, and we print one line for every task. First we print a serial number, then the task’s title, and finally a pair of square brackets that would have an X in-between them for tasks that have been marked as done. You can now compile and run the program to print all the tasks that you have added to the list:

Image taken from the original Udemy article.

g++ *.cpp 
./a.out ls

The idea behind printing these serial number is to provide the user with an easy way to reference the tasks. For example, next we would like to implement the “mark” subcommand which will mark tasks as done. With these serial numbers, the user should be able to mark the tasks as done by referring to these numbers. To mark the second task from the list, the user can execute:

./a.out mark 2

Marking Tasks as Done

Implementing this “mark” subcommand may be easier than you think:

int main(int argc, char *argv[]) { 
     // ... 
     switch() { 
         // ... 
         case 3: 
             if(argc < 3) { 
                 cout << "Missing task number" << endl; 
                 return 0; 

             } else { 
                 string arg2 = string(argv[2]); 
                 int no = stoi(arg2); 
                 if(no < 1 || no > tasks.size()) { 
                     cout << "Invalid task number" << endl; 
                     return 0; 
                 } 
                 Task t = tasks[no-1]; 
                 t.done = true; 
             } 
             break; 
     } 
     // ... 
}

Just like “add”, for this subcommand we determine if the third argument is present or not. We extract the third argument as a string, convert it using the standard stoi function, and check if the number is within a valid range. We then find the appropriate task object in the vector and set its done attribute to true.

There is one small detail worth pointing out here. Notice the “&” symbol before the variable name “t”? That makes this variable a reference to the element of the vector, instead of making the program copy the element of the vector into a new memory location. References work in a way similar to that of pointers, except that they have a little more restrictions imposed on what you can do with them. Without this symbol, any changes made to “t” wouldn’t have any effect on the actual task element inside the vector. If “t” wasn’t a reference to the element, it would have been a copy, and changes made to the copy of an object wouldn’t have any effect on the original object.

Sorting Tasks: Overridden Operators and STL Algorithms

As you can see, we can now add small nifty features to this tool with small, incremental updates. Let us add another feature that would sort each task based on its status. This will let us move all the completed task to the bottom of the list. For this, we will use the “sort” algorithm that comes with the standard library.

Before we use the “sort” function, we need to modify our Task class a little for it to work with the function. There are many ways of using the function, one of which involves defining a custom less than operator for your custom data type or class in this case. Overriding an operator involves defining a method-like element for the class:

// task.h 
// ... 
class Task { 
     // ... 
     public operator < (const Task &b;) const; 
};

And we will provide the implementation of this overriden operator in our “task.cpp” file:

#include "task.h" 

bool Task::operator < (const Task &b;) const { 
     return !this -> done && b.done; 
}

This allows you to compare two task objects with the less than operator. Given two tasks a and b, a is less than b only if a is not done, but b is done. The const keywords before the argument type and after the function’s signature is there to assure the compiler that the object b passed as the argument will not be modified by the function and the function will also not modify the object at “this”.

Finally, we need modify our “ytodo.cpp” file to use the sort algorithm:

#include <algorithm>
// ... 
int main(int argc, char *argv[]) { 
     // ... 
     scmds["sort"] = 4; 
     // ... 
     switch(scmds[arg1]) { 
         // ... 
         case 4: 
             sort(tasks.begin(), tasks.end()); 
             break; 
     } 
     // ... 
}

And that is it. All you have to do to sort the vector of tasks is to:

  1. Define a less than operator for the class.

  2. Include the algorithm’s standard library.

  3. Invoke the sort function with the beginning and the ending iterators of the vector.

You can now compile and run the “sort” subcommand to organize the list by moving all the tasks that have been marked as done to the bottom.

g++ *.cpp 
./a.out sort


6: Conclusion

Learning C++ is usually quite a different experience from learning any other modern programming language. This is probably attributed to the age of the language, or may even be its less-than-high-level nature – even though C++ is in fact a high level language. C++ may not be the best choice for building your next web application server, but it is certainly a powerful language that can cover a lot of ground. With its performance characteristics and versatility, C++ is often a great language for building software that is closer to your bare machine (such as hardware drivers and operating systems), or software that would like to make the use of every bit of performance that the hardware can provide – such as games, real-time applications, embedded systems, missile thrust vector control systems, and more. Just like with any other language, mastering C++ is a matter of patience and practice. This article may have barely scratched the surface, but we hope it has given you an insight into what you can expect from C++ and a starting point from where you can continue to play with the language and continue to learn more about it.

This tutorial was made in collaboration with Toptal.


Categories: Reviewssciencetutorials


AI in Cinema: Ex Machina

May 22nd, 2015

Ex Machina ​is one of the most intense and thought­-provoking movies I’ve ever seen. More of a psychological thriller than an action flick, Ex Machina is a chilling exploration of the boundaries between man and machine. The movie looks at artificial intelligence in a critical, unromantic light. It examines the realistic implications of computers someday outsmarting humans.

AI would be the biggest event in history. Unfortunately, it might also be the last.
Elon Musk

The idea that we humans are just a momentary step in the ongoing chain of evolution is undeniably frightening, even for the most avid technophiles. One of the official trailers to Ex Machina plays on this fear by quoting prominent leaders in technology such as Elon Musk and Bill Gates. Only after seeing the movie and watching the trailer a second time did the message really sink in. With the pulsating music and ponderous quotes, I wondered if Ex Machina is a cautionary tale, and if so, what kind of cautionary tale.

Summary (Spoiler Alert)

The opening scene takes place inside the offices of BlueBook, a search engine company vaguely reminiscent of Google. Caleb, a 26­-year old programmer, wins the company-­wide raffle to visit the CEO in person and learn about his latest undertaking.

Conclusion

What I understood right away after seeing the film is the lack of a moral imperative. The movie is descriptive rather than prescriptive. Intelligent machines are on the horizon, and there’s no reason why they should live to serve us, their inferior predecessors. This doesn’t mean that human beings will be obliterated by machines. What it does mean that we will have to get off our laurels as a species and realize that our place at the top of the food chain is a precarious one. In order for our species to survive and to coevolve with machines, we must stay relevant.

Ex Machina is devastatingly indifferent to the romantic ideals and over-hyped fears surrounding the future of technology. It neither glorifies nor demonizes technological progress. That’s what I love about the movie; the fact that it breaks away from the usual human­-centric tropes of science fiction and fantasy. The universe does not exist for our benefit and neither does our technology. Some day, our technology may very well beat us in the Darwinian competition for survival. While this thought chills me to the bone, it excites me and gives me an odd sense of transcendent hope. I actually look forward to something better than humans coming along.

Easter Eggs

While searching online for more information on the movie, I came across some interesting results. One of them was an “Easter egg” found within one of the snapshots of the computer code used in the movie. The actual code is written in Python and, when executed, will output the ISBN number for Embodiment and the inner life: Cognition and Consciousness ​by Murray Shanahan (2010). A low­-resolution screenshot and code snippet can be seen below.

Heres the python code

 #BlueBook code decryption

   import sys
   def sieve(n):
       x = [1] * n
       x[1] = 0
       for i in range(2,n/2):
               j = 2 * i
               while j < n:
                       x[j]=0
                       j = j+i
       return x    def prime(n,x):
       i = 1
       j = 1
       while j <= n:
               if x[i] == 1:
                       j = j + 1
               i = i + 1
       return i - 1
   x=sieve(10000)
   code = [1206,301,384,5]
   key =[1,1,2,2,]    sys.stdout.write(“”.join(chr(i) for i in [73,83,66,78,32,61,32]))
   for i in range (0,4):
       sys.stdout.write(str(prime(code[i],x)-key[i]))    

print

References


Categories: Artificial IntelligenceReviews


Tech Review: Apple Watch

May 16th, 2015


Ever since I started wearing my new Apple Watch Sport band, I’ve noticed that practically everyone I encounter has something to say about it. With its smooth edges, pistachio-­green band, and a watch face that looks like a glowing gem, my Apple Watch has been an object of intrigue, bewilderment, and quite possibly envy. The most common question people have asked me is, “Why would anyone need one of these?” In this post, I hope to enlighten people on why I am the proud owner of one of these high-­tech baubles.

The Activity App

By itself, the Activity app makes the Apple Watch worthwhile. Throughout the day, the Activity App assesses the user’s cumulative physical activity using the watch’s built-­in gyroscope, accelerometer, and an LED heart rate detector. The app communicates with the user through gentle “taps” and messages, reminding the user to stand up and move around after sitting for a while and congratulating any efforts made towards meeting physical activity goals.

Because of the Activity app, exercise feels like something I can easily and effortlessly insert into my day, whether I’m walking from the parking lot to grocery store or doing a workout at the gym. What I love about the Activity app is that it makes exercise seem a lot more doable and a lot less overwhelming. Rather than making exercise an “all or nothing” affair, the Activity app encourages a balanced lifestyle and flexible approach to fitness.

What makes the Activity app particularly user-­friendly is its beautiful and simple interface. The Activity app can be located on the home screen of the watch as an icon resembling a target. At a glance, the three circles inside the icon fill up as the user exercises throughout the day. This is a handy snapshot that can give users a quick overview of their activity levels. For a more detailed assessment, simply tap on the icon to open up the Activity app’s full interface.

The full interface consists of three circular “tracks” that fill up in a clockwise direction. At the start of each day, the tracks start off as empty. Throughout the day, users are encouraged to make these tracks fill up. One revolution around a track can be used to represent daily movement goals. It’s also possible to make multiple revolutions and earn special achievements for going the extra mile.

The outermost pink tack represents calories burned during physical activity. Caloric output is based on the wearer’s height, weight, age, and sex. The green track in the middle keeps track of time spent exercising. Finally, the innermost blue track represents the number of hours in which the user stood up and moved around for at least one minute.

LED Heart Rate Sensor

One of the most ingenious aspects of the Apple Watch is the heart rate sensor. Using LEDs (light­-emitting diodes), the watch sends light beams into the user’s skin, creating a profile of subcutaneous blood flow. The watch is able to compute the user’s heartbeats per minute in just a few seconds.

The watch takes a reading of the user’s heartbeat at frequent intervals throughout the day. Whenever the Apple Watch connects with the iPhone, it automatically transmits all the heart rate and activity data to the phone. This data is then recorded into the Health app on the iPhone. Without any effort on my part, my watch and phone have created a comprehensive profile of my heart rate and exercise stats over time!

At any time, I can check my heart rate using the Heart Rate Glance feature of the watch. I’ve found the Heart Rate Glance feature especially useful in learning how to maintain a target heart rate during workouts. As I walk or run, I can easily get objective feedback about how hard my body is working so that I can make adjustments as needed.

For friends that also own Apple Watches, it can be fun and cute to send each other heartbeats. On the Digital Touch screen, I can scroll through my (literal) circle of friends and send any one of them finger doodles, or if I press the screen in just the right way, I can send heartbeats. The heartbeats are visually represented as glowing, pulsating blobs with the distinctive “thump thump” patterns of the actual organ. I can also feel the heartbeats actually thumping through haptic feedback!

Since heartbeats are personal and often used to symbolize love, sharing heartbeats across space and time can be quite romantic! Although nothing (yet) compares to an actual hug, sending heartbeats is one of the most intimate things I’ve ever done through a gadget!

Apple Pay

For those who own the iPhone 6, Apple Pay has revolutionized the way cash register transactions take place. Without swiping a credit card, users can pay by card indirectly using their phones. Like PayPal, Apple Pay acts as the middleman between buyer and seller, allowing the buyer to keep things like credit card numbers private. With the Apple Watch, Apple Pay is now more convenient than ever since now the user has less to do. I’ve tried out the Apple Pay watch feature a few times already, intriguing the cashiers. Although it takes a little practice to get the hang of Apple Pay, I can now pay for things faster than ever before.

Messaging and Notifications

Lastly, but not least, the Apple Watch has helped me stay up to date on all of my notifications. Every time I get a phone call, iMessage, Facebook message, or Mint alert, it shows up on my watch. (If I would rather not be disturbed, I can always silence the audio and haptic feedback).

While it’s not possible to have a normal back-­and­-forth text message conversation through the watch, it does come in handy for quick replies. I personally find the default responses too robotic for my taste. Thankfully, there’s a way to customize those defaults and make them feel more personal.

Conclusion

For those that have the money and the desire, an Apple Watch augments the iPhone experience. In particular, it gives users an honest window into their own day­-to-­day habits and heartbeats and it encourages healthy living. It makes Apple Pay even more convenient than ever. Finally, it has many little features that have the potential to make life easier for some and more cluttered for others. For those looking for a high­-quality fitness monitor, I would wholeheartedly recommend the Apple Watch.

Buy Apple Watch now from Amazon

Categories: Reviewstechnology