Thursday, January 26, 2017

Practice For Funsies (Basically, a compilation of my notes.)

I've got this GitHub repository that I am maintaining to hold all a bunch of my notes from CS books, online tutorials, and implementations of various data structures and algorithms. You can check it out here.

So far, I'm working on compiling a bunch of notes for:

  • Vim Script
  • Haskell
  • Books that I have exercises completed for in the repo.
I'm planning on also adding notes for various APIs that I end up having to use. Sooner or later, I'd like to add some for the Google Sheets and GroupMe APIs. 

Hope some of you guys can find it useful. I suppose it's not really a project- just a fun way to make it easy for me to get what the implementations that I want whenever I need without scavenging from the net.




Tuesday, January 17, 2017

Building Linux From Scratch on an Ubuntu Host System

So you want to build a Linux system from source? Maybe make your own distro (I don't mean tweaking an existing on- I mean from straight scratch)? Linux From Scratch is for you! Basically, it's a book tutorial on exactly that.

There are a couple things that can go awry on Ubuntu when you're compiling the tools you need to build the base system. I'm in the middle of compiling those tools right now, and here is a public gist that I am maintaining, detailing what issues I come across on my way to the end of the book.

If you decide to try, make sure you at the very least know your basic command line and a number of tools that the book uses to help you build your system. Otherwise, you'll be totally clueless as to what's going on. I would recommend messing with Ubuntu or Fedora, and once you've gotten more experienced, go with Arch Linux or Gentoo, then finally moving onto LFS.

Monday, January 9, 2017

Basic C for Uninitiated, Part 1

To start off the day, there's nothing better than review.

For those of you unfamiliar with C reading this, this is for you- think of it as that one thingamajig that you've got to read before you get to do the cool stuff. Want to play with micro-controllers like the Arduino or some of its counterparts? Maybe you'll find this useful. This is what you'll need to learn first- the basics of C programming.

NOTE: If you have a good understanding of Java, the only section you'll really need to read is the one on pointers, further down the page. The rest is syntax or just knowing the basics of programming.

Here's a famous tidbit of C that those of us familiar to the language will know right off the bat:

1
2
3
4
5
#include <stdio.h>

int main() {
    printf("Hello, world!");
}

Let's dissect this, piece by piece.

1. This first line is what's called including a header file. By including a header file, we are able to make use of what is basically more tools to play around with, and this particular header file gives us the ability to use the function printf() (and much more).
3. This is the entry point of our program. int is an integer- it always has to be next to the main() call, and it simply means that main() returns some integer value. When we compile our program (meaning we're shifting it from a text file into an executable, something that our CPU can work with) and execute/run it, the first thing we'll get is...
4. ... a "Hello, world!" statement. printf() here takes one argument- a string of characters that is "Hello, world!"- and prints it to our terminal/console/wherever STDOUT is.
5. And we end out program with a closing bracket, to signal the end of the code block for the main() function.

I would now take this and make sure you understand exactly what this does before continuing. Don't worry too much about what's happening 'under the hood' of printf()- for now, just know what it's supposed to do.

Now, let's try something just a tad more complicated:

1
2
3
4
5
6
7
8
#include <stdio.h>

int main() {
    int a = 5;
    int b = 6;

    printf("%d", a + b);
}

Now for the same process, but without what we've already gone over:

4. & 5. Our first variables, a and b. Here, we assign a and b to numbers 5 and 6 respectively using the '=' operator. C is a statically typed programming language- meaning we need to specify exactly what type of value 5 and 6 are: int for integer.
7. printf() looks a bit different now- instead of taking one argument, it's taking two. Not only that, but I've added a placeholder into the string. Essentially, all this will do is replace what is in '%d' with the value of a + b.

The way printf() takes arguments is really interesting. At first, one might think that printf() is able to take in a variable number of arguments. The way of looking at this isn't wrong, but isn't quite right either. It decides how many arguments there are by taking a look at the first argument- the number of arguments printf() will have received will always be the number of formatting characters + the first string argument. I would take a look at this for more details.

Of course, there are different types of variables:
  • We have char for character, floats and doubles for decimals.
  • Strings, on the other hand, are a slightly different case. In languages like Java, strings are considered objects. Here, in C, there's less of an abstraction in that strings are not actual 'things'. They are actually just arrays of characters, and can be initialized like so:
    1
    char *hello_world = "Hello, world!";
    
    or, an alternative:
    1
    char hello_world[] = "Hello, world!";
    
You may not be familiar with the two ways of initializing character arrays here. The asterisk '*' next to a variable denotes a pointer, so in this case, char* is a pointer to a character. Similarly, int* would be a pointer to an integer, and so on. Think of it as allocating a chunk of memory that holds an address to some value. In this case, that would look a little something like this:
Courtesy of Google Images, from tenouk.com
Now, what's the difference between the two ways of initializing strings? Well, in the first example, something like:

1
hello_world[0] = 'J';

would not work. This is because using pointers, the string "Hello, world!" is put into read-only memory (meaning parts of memory that we cannot 'write' into), and thus we cannot edit it. However, using the char array form, this is a valid statement- the string "Hello, world!" is put into read-only memory, and then copied into the array so that we are given the freedom to modify its characters.

Of course, we can also make integer pointers (int*), float/double pointers, etc. Note that pointers simply hold an address to the actual value. To get the address of that value:

1
char* p = &hello_world; //some hex number here signifying an address in memory.

and to get the actual value,


1
char c = *hello_world; //the first character in the character array, 'H'

Note that the asterisk denotes the first character in the string- this is because the pointer will always be initialized to the address of the first character of the string.

We'll stop here for now. From this review, you should've come away with some knowledge of pointers, variables, and very, very basic C. To continue on, I would work on finding out how basic flow control structures work.

Feel free to mess with those programs as you wish. Try, for instance:
  • What happens if you make give main() a different return type? Or if you try to use printf() to print a variable you haven't yet initialized?
  • How do you add more placeholders into printf(), e.g for strings, floats, etc? How does it react if you give it too few arguments or too many? Can you make a nicely formatted output with it? (Hint: YES.)
  • Use characters, strings, integers, floats, etc and see how printf() reacts.
  • How would I find the length of a string programmatically in C? 
  • Use the flow control structures to understand how they work and what they do. 


Sunday, January 8, 2017

Wading through C and Linux

Hey, how's it going folks!

So, this is going to be my first blog post. Exciting stuff. The sole purpose of this blog is to get myself to learn something new everyday, and maybe by extension share some cool stuff with you, the reader, as well.

Let's get started with today's subject: The association between C and Linux programming.

For the newbies, C is a low-level programming language, meaning that C exposes much more of what the computer is actually doing than something like Java. For instance, in C, there's no such thing as a string- those are actually just arrays of characters that Java has created an object for, an abstraction for those who don't really want to deal with it. It also supports manual memory management through malloc() and free(). C lacks the abstractions that Java has. But we'll get back to that in a moment.

Let's discuss the relationship between C and Linux programming. For those who don't already know, Linux is an open-source operating system created by the one and only Linus Torvalds (You can see the kernel here).

NOTE: For those who are interested, the history surrounding UNIX and Linux is pretty interesting. See this article by the Linux Documentation Project for more details.

Linux programming is so associated with C programming because, well, it was all written in C. The kernel itself was written in C, as are most of its basic utilities (ls, pwd, cd, you name it!) were. The Bourne Again Shell that many new users will usually first encounter is again, written in C. The point here is that Linux is the optimal system to do your C programming shenanigans, whatever they might be, because the system itself was built in C.

For those of you that are just beginning programming, I would argue that you would be one big step ahead if you did yourself a favor and started with Linux right now. Not only is it the most diverse kind of the operating system due its open-source nature (there are many different 'flavors' of it), it is the optimal system to do all kinds of development on (unless you're doing Win32 programming or really, really enjoy Visual Studio. In which case, good job!) I would start with Ubuntu or Fedora, and replace Windows. Hear me out- there's a good reason for it.

The thing is, if you were to install either of these systems as a virtual machine or onto a computer you don't really use, you're probably never going to use them. You'll have to boot up the system, wait a bit, figure out how to use the terminal, never mind how the package system works. Maybe something breaks and you won't be too inclined to fix it since you'll just be inclined to run off back to Windows again. We can't have that.

Here's the thing: You won't learn anything that way. Trust me.

The first thing I learned about programming was that to figure out how a program works, you have to get down and dirty with it to make it do something cool. We can't just sit there and poke it with the longest stick we can find- how would you know how it does the cool thing otherwise? If you want to learn something, you gotta get close to it. I'm not talking just 'glimpsing' it. Commit to it, or get nothing instead.

Venturing into Linux is much of the same. Once you figure out the basics, maybe you'll write a shell script to make things easier; write a welcome script to pop up onto your terminal every time you start it, or swap out your desktop environment for a nifty window manager like bspwm or i3 and customize your system even more! The possibilities are endless!

For those that take my advice:
A good command line tutorial by William Shotts.

Welcome to the wonderful world of Linux.

Arch Linux, with BSPWM and the polybar.
For those interested, the Bash script doesn't really do what it's supposed to do just yet. It's supposed to use lynx, a headless web browser, to scrape a quote from a website. The sed command doesn't do what I want to do.