pyk deep learning & natural language processing

This year, I should be better at X

2015 was a great year. I have fails and learn from so much experiences. Let’s recap!

In January, I started a reading challenge on Goodreads. I have read 8 of 12 books. It seems that i’m not good at keeping a schedule.

This year, I should be better at setting an expectation.

I also wrote an opinion in Bahasa titled “Kita Bisa Memilih”. This opinion is to persuade my friends to use their time wisely. But, the way I wrote it is still messy.

This year, I should be better at writing an opinion. It should be honest and more enjoyable to read for the other.

I participated in The Gopher Gala, the world’s first Go(lang) distributed hackathon, and submitted a Wisdom. There are many code dupclication in here.

This year, I should be better at refactoring the source code.

In February, I enrolled CS50. But, I’m not finish it. I only get excited for the first two weeks or so. I have to focus on my courses in college.

This year, I should be better at making a commitment.

In March, I started creating content on {ubuntu, golang}.kertaskampus.com. Which now the domain has expired. My savings is not enough to renew the domain. It’s been a hard time for me.

In April, I started to working on Project Euler. I stuck at problem 8 because I have to focus on mid-semester exam. It’s a pitty excuse. Why I don’t continue the problem after mid-semester exam finished?

This year, I should be better at archiving a todo list.

In May, my role as Google Student Ambassador(GSA) South-East Asia at Airlangga University is done. It’s been very exciting to work with Google Student Group at Airlangga University and all GSAs from Indonesia.

Me and Riliv team (formerly Relieve) is go to Google Japan! We won a Android Indonesia #SatuMulai campaign. Awesome experiences. I met a bunch of googler and eat sushi with them.

In June, I left the Riliv team. It’s been hard decision for me. But I have to focus on my research and study in Machine Learning and Artificial Intelligence.

In July, I learn more deeply about Dynamic Programming Algorithm. I can’t recommend enough this lectures.

I planned to end the summer of 2015 as intern at Silicon Valley company. Especially Dropbox. Because I love the dropbox’s vision. Besides I’m very interested to learn and contribute to scale their distributed system.

I applied at Indo2SV, a 3-month mentorship from fellow Indonesian employees, to learn more about internship at Silicon Valley. But I mess up at technical interview selection. Maybe because this is the first time for me.

My plan to internship at Dropbox is fail. Maybe this year? hehe.

In December, the last month, it’s very exciting month for me.

I released one of my Artifical Intelligence(AI) for the first time. It’s called a “Sayoeti”, the PR’s assistant of Komisi Pemberantasan Korupsi (KPK) that powered by AI. It’s also the first AI that help Indonesian Goverment publicly.

I also got an Internship from Telkomsel, one of the biggest mobile phone network company in Indonesia. In January-February this year, I will work on AI system for their internal organization.

This year, I should be better at implementing a Machine Learning algorithm.

I can’t wait to start 2016!

Casting Allocation In C

If I allocate block of memory for the obj_t it’s look like this

obj_t *obj = (obj_t *)malloc(sizeof(obj_t));
obj_t *obj = (obj_t *)calloc(nmemb, sizeof(obj_t));

After reading this post, I’m wondering why I use cast anyway?

My thought was because malloc and friends is returning void * so I need to cast to the appropriate type.

And now if I ask myself “Why do you need to cast anyway? Is there any effect?”. My answer was “I don’t know”. So I decide to doing some research about this.

I found this StackOverflow answer which provide excellent information about the bad of using cast for malloc and friends.

This is a quick summary from that discusion

Do I cast the result of malloc?

No; you don't cast the result, since:

* It is unnecessary, as void * is automatically and safely 
promoted to any other pointer type in this case.

* It can hide an error, if you forgot to include <stdlib.h>. 
This can cause crashes (or, worse, not cause a crash until 
way later in some totally different part of the code). 
Consider what happens if pointers and integers are differently 
sized; then you're hiding a warning by casting and might 
lose bits of your returned address.

* It adds clutter to the code, casts are not very easy to 
read (especially if the pointer type is long).

* It makes you repeat yourself, which is generally bad.

It’s turnout that cast is a harmful, I should avoid them as much as possible.

Is there any effect using cast?

It's a failure to include the cast, even if you got it right. 
There are simply no benefits to doing it, but a bunch of 
potential risks, and including the cast indicates that 
you don't know about the risks.

Well, 100% Agree.

The last one

To add further, your code needlessly repeats the type information
(int) which can cause errors. It's better to dereference the 
pointer being used to store the return value, 
to "lock" the two together:

int *sieve = malloc(length * sizeof *sieve);

This also moves the length to the front for increased visibility, 
and drops the redundant parentheses with sizeof; they are only 
needed when the argument is a type name. Many people seem to 
not know (or ignore) this, which makes their code more verbose.
Remember: sizeof is not a function! :) 

“It’s better to dereference the pointer being used to store the return value”

Conclusion

I don’t cast allocation anymore and use dereference the pointer instead of type name as an argument of sizeof.

obj_t *obj = malloc(sizeof *obj);
obj_t *obj = calloc(nmemb, sizeof *obj);

The good news is it also improve my code to be more readable.

My indent(1) Profile

Manage C codebase is not easy, especially if the project is team-based. One of the common issues is about consistency of code formatting. Keeping the consistency of code format is very hard, because the heterogonous of code editor and development environment.

This is where tools like gofmt(1) and rustfmt(1) used for. For C codebase there are common alternative: clang-format(1) and indent(1). I use indent heavily. It’s from GNU which is very simple and straight forward.

This is my indent(1) profile look like:

The Rules of Buffer In C

This rules does not cover of all buffer operation yet.

Buffer or String in C is represented as an array of char terminated by null character \0.

char buff[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

/* or */
char *buff = "hello"; /* \0 implicitly appended */

/* or */
char buff[] = "hello";

Null character is not the part of buff length but it does requires a memory space.

The problem is in the function for handling a string operation like allocation malloc, copy strcpy(dest, src) and concatination strcat(dest, src) is performed in unsafe way.

malloc only allocate memory for us without initialize it which potentially have a garbage values (a values from previous operation that are not cleared). Where strcpy and strcat is assume that dest is big enough which lead us buffer overflow problem if the src is larger than dest.

This is a list of rules that I always follow when dealing with buffer

1. Allocation: Use calloc instead

char *buff = (char *)calloc(LEN, sizeof(char));

calloc will allocate LEN contiguos block of memory with size sizeof(char)bytes for each block and initialize it to zero. This will make sure that buff is not contains any garbage values or sensitive information from the previous operation.

2. Copy: Use strncpy and terminate.

char buff[6];
strncpy(buff, "helllo is extra hello", sizeof(buff) - 1);
buff[sizeof(buff) - 1] = '\0';

strncpy is copy all the first sizeof(buff) - 1 from src. This help us prevent buffer overflow and corrupting the heap.

3. Concat: Use strncat

char path[11];
char fname = "hello";
char *ext = ".txt";
strncat(path, fname, sizeof(path) - strlen(fname) - 1);
strncat(path, ext, sizeof(path) - strlen(ext) - 1);

This will make sure that the concat operation is not write to more than allocated memory for path buffer.

That’s it.

Welcome to Jekyll! (Again)

This post is intentionally left here.

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated.

To add new posts, simply add a file in the _posts directory that follows the convention YYYY-MM-DD-name-of-post.ext and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.

Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.