Posted in February 2007

Introductory Books for Beginning Programmers

I’ve recently started learning progrmming seriously and so I’ve been on the lookout for good books to learn from. So here’s a short list of books that I’ve found useful. They deal with a variety of languages and concepts and the best thing is that they’re all absolutely free. Please note that these books would probably be most useful for someone in the last two years of school, though older people shouldn’t have a problem. I’m personally using them as a sort of prep for studying Computer Science in college and so only time will tell if I’ve been successful.

How to Think Like a Computer Scientist – Python Version

Python by itself is a very good programming language for beginners (unless you’re less than ten years old in which case I would suggest Logo). Combine that with a good book and you get a winning combination. The book’s style is clear and cluttered and the chapters are fairly self-contained. It does a good job of introducing procedural programming first before moving on to object orientation (which can be quite a difficult concept for beginners). My only real gripe is that there seem to be too few exercises, which sort of leaves you on your own to find something to do.

How to Think Like a Computer Scientist – Java Version

This is the original Think Like a Computer Scientist book, and unfortunately it’s one major flaw isn’t really something that can be fixed: the choice of language. Java as a language may be very nice, but it’s certainly not too fascinating for beginners. If your learning programming on your own, like I am, I would recommend starting this book after you’ve come to grips with the object oriented matter in the Python book. That issue aside, it is a very good book and I personally like its style slightly more than I do the Python one’s. One major scoring point is that there are a number of exercises at the end of each chapter which involve both writing and reading/fixing code. This book will also come in handy if you’re studying for the American AP exam, but I’m not quite sure if it covers all the bases. I would suggest combining this with the BlueJ IDE, which’ll let you sidestep many of the practical hurdles involved in using Java as a beginning language.

How to Design Programs

This book is designed from the ground up to make you learn programming that is data-centric, i.e. the program’s very purpose for existence is the data that it manipulates. Unlike other programming books that focus on specific concepts as a path around which to structure your learning, this book focuses on data: you start by using smaller, atomic types of data and then move on to using mroe complex data structures. This book uses the functional programming language Scheme. But this books comes with its own dedicated environment: DrScheme. DrScheme helps beginners tremendously by hiding obscure syntax features until the time is right. It does this by providing not just standard Scheme, but a number of subsets containing only the features that you will need. As you progress through the book you move on to richer and richer subsets until finally you’re ready to use full-fledged Scheme. The book focusses on the ‘why’ of a program rather than the ‘how’.

Structure and Implementation of Computer Programs

Think of this as the last one’s big brother. SICP has been the textbook for MIT’s introductory Computer Science for the better part of two decades. As you can well imagine, this not for the faint of heart. However, once you set your mind to it, you’ll find that the book deserves its reputation as a computer science classic. It’s written in a simple no-nonsense style and like HtDP, it teaches you programming, not a programming language. It uses Scheme, but it makes and effort not to let your attention be drawn to what language you’re using. The book drives home the fact the computer is just a tool and your head is where you have to do the real work. That being said, there is probably no point in reading this book unless you intend to make computers your career. Also, having some amount of programming experience would help you on your way. This book is also rather intensely mathematical, and so make sureyour math skills are well polished before you embark on this journey.

Programming from the Ground Up

This book takes a different approach to programming: it’s basic premise that you can only really learn how to make a program if you understand how the computer ticks inside and what it does when it runs your program. As a result of that philosophy you are required to get up close and personal with the computer and that means assembly language. Yes the book uses assembly language (x86 assembly to be specific), but all the examples are very thoroughly explained and if you have patience in abundance, you shouldn’t have any problems. What sets it apart from SICP, is that while SICP approaches programming from a mostly theoretical aspect, this approach is decidedly practical. Again, probably not worth your time unless you plan on computer science as a career.

Personally, I think all the above are very good books. Of course there is the inevitable question of choice. I’m currently working my way through the How to Think Like A Computer Scientist books (yes, both of them). Once school is over I will try push through How to Design Programs and finally go through SICP and Programming from the Ground Up. All in all, I think all of that should keep me busy for the better part of a year. So in a year’s time, come back and check on my progress. If you’d like an IDE to go with your new book, check out the next post.

Tagged

The Ackermann Function in Java: Why Computers are Stupid

I’ve started teaching myself Java, right from the basics and as a guide I’m using the Java version of the How to Think Like a Computer Scientist book. One of the exercises at the end of the fifth chaper (called Fruitful Functions) is to implement the Ackermann Function as a recursive method. The Ackermann function is mathematically defined as:


Now, the Ackermann function is quite well suited to computerization, it takes little real intelligence to solve for any two numbers, and is mostly repetitive calculation (which computers are good at). It took me less than a minute to implement the function as a Java method as follows:

public static int ackerman(int ack1, int ack2){

if (ack1 == 0)

	return ack2+1;

else if (ack1 >0 && ack2 == 0)

	return ackerman(ack1-1, 1);
else if (ack1 >0 && ack2>0)

	return  ackerman(ack1-1, ackerman(ack1, ack2-1);
)

I passed it to the compiler and the compiler replied with a cheery: “missing return statement”. Since I already had three return statements, that meant that there was a possible path through the method where the method would end without a value being returned. The Ackermann function doesn’t work with negative numbers, so I had already implemented a check for negatives before the function call. I tried putting in another check for negatives in the function itself, but that didn’t work. By this point I was getting rather frustrated because the above code would catch all non-negative numbers and produce appropriate returns. I ran the code in my mind with a few small numbers and everything seemed to check out as it should, the values of ack1 and ack2 would keep on reducing until ack1 hit zero and the method would end with a proper return.

Finally on a hunch, I decided to remove the last if-else and make the last return statement free-standing. Semantically it was the same thing, because there was only one possible case if the first two conditions were not satisfied. And for some reason the compiler thought that this new version was perfectly passable. I haven’t entirely ruled out the possibility that there was really some path that would have resulted in no return. But I think that it is far more probable that the compiler for some reason couldn’t handle the multiple recursions and simply gave up. Of course, I’m not an expert in these things and if someone knows of a proper explanation please let me know. Until then I’ll stick to the knowledge that a computer is still quite some distance away from what would be common sense to a human (or at least the Java compiler is).

Tagged

Cross-platform Programming: The Details

In the last article, I took a general look at cross-platform programming. From a developer’s point of view, there are a number of ways of programming cross-platform. While maintaining separate source code trees for each platform would make your program “fit in” the most with each platform, it would be almost like maintaining a different program for each platform, a lot of work indeed. One solution is to keep the same source code and use a different compiler to create a different executable for each platform. While this reduces the amount of work you have to do, using this method means that you have to be careful not to use platform-specific methods. And the performance of your program will vary according to the quality of the compiler use.

Probably the simplest solution for a cross-platform developer would be to write in an interpreted language. The upshot is that you can (mostly) forget about dealing with the platform, because the interpreter will be the same irrespective of the platform and you can be pretty confident that your code will run the same on whichever platform you make it work. On the other hand, this method relies heavily on the proper performance of the interpreter. However, if you use one of the more common interpeted languages like Python or Perl, that is unlikely to be a problem. These interpreters have been out there for years and have been thoroughly tested on all of the more common platforms out there.

And now for the Java Virtual Machine. The JVM is just what it sounds like: a sort of pseudo-computer which conveniently lets you ignore the real computer. But there are two important things that make the Java Virtual Machine different from interpreted languages. Firstly, the JVM is independent of the actual Java language. Though Java is the primarily language, there are a number of other languages which can be translated into bytecode that can be run on the JVM. There are also implentations of Python and Ruby for the JVM, though these are considerably less complete than the actual implementations. The second reason will be more appealing to developers focussing on GUI applications: Java has it’s own GUI toolkit called Swing which can provide a consistent look-and-feel across all platforms. Your program not only functions the same across all platforms, it looks the same as well.  Most other interpreted languages require an external GUI toolkit which means that the end user has to make sure that the relevant libraries are installed (or you, as a developer have to package the libraries with your program).

Talking about GUI toolkits, there are a number of toolkits out there for you to choose from. Qt and GTK are probably the more popular ones, but wxWidgets is gaining popularity. GTK and Qt are both non-native toolkits, in that they use their own drawing engines. Qt now uses the drawing API of the platform to give a more native look-and-feel. GTK on the other hand uses a number of different engines some of which emulate the look of native widget sets. wxWidgets however uses the native drawing system of the platform itself and only provides a thin abstraction layer on top of it. This means that your apps will look like native apps because they are effectively using the same set of graphics widgets. GTK is written in C while Qt and wxWidgets are in C++, but bindings for all of them exist in many popular cross-platform languages, so you can pick and choose at will.

Though I’ve presented cross-compiling and interpreted languages as two different solutions, you can take a middle path: writing part of your program in code that will be compiled separately for each platform and part in an interpreted language. The Firefox browser uses this technique. The Gecko layout engine is written in C++, but a large part of the application is made using interpreted scripting languages like XUL, CSS and JavaScript, allowing it to be easily ported. Besides Windows, Mac and Linux,  ports are available for BeOS, SkyOS, FreeBSD and OS/2.

Ultimately it comes down to you as a developer to decide which method and technologies will make your worker easier and the end product. My personal favourite is Java/Swing for heavy projects and Python/wxWidgets for smaller personal work.

Tagged

Cross-platform Programming: A Primer

Microsoft Windows is still the most popular desktop operating system in the world, but open source alternatives (mainly Linux and BSD systems) are gaining a wider user base and the Apple Mac, with it’s undeniable cool factor, is making a decent comeback. A lot of people have a lot of different opinions about this, but for a software developer this means one thing: there are now three main platforms, each with a reasonably large number of users that you might want to devlopment software for. The question is which one do you choose?

The most obvious choice would be Windows because that way your software gets out to more people (especially important if you’re actually selling your software). However that obvious advantage is offset by the fact that there is already a large amount of Windows software and your application might just get lost in the crowd unless it’s very exceptional (or you’re a ruthless marketer). The problem with Mac is that not only is its user-base smaller, and Mac users are generally quite discerning users. Linux and BSDs (which are binary compatible) have a slew of their own problems like different GUI toolkits, different software packaging systems and a general aversion to proprietary software. The upshot is that there are plenty of early adopters and a good application can gather momentum quickly.

You could do some research, weigh the pros and cons and then take the gamble, or you could side step the issue altogether. How? By developing cross-platform. You write your program so that it will run on all of the above without the need for drastic changes. Now the problem with this idea is that all of the platforms are different from each other. A program written for Windows will not run under Linux or Mac OS, unless you use some sort of emulator or virtualization. And most users will not go to so much trouble just to run your program. However, developing cross platform can be done and without too much of a fuss. There are a number of ways to do this, but I’m going to be focussing on two ways that are most efficient for software developers.

Cross-compiling

You write your program in a compiled language like C or C++ and then just used a compiler specific to the platform you’re interested in to compile your program to a binary for that platform. This way you only have to write your source code once and only have to maintain a single source tree. This also gives you access to platforms that are more esoteric than the three common ones mentioned. The GNU compiler can compile to almost 50 different processor architectures (assuming of course that there is an operating system to actually run your program on). The downside is that you have to avoid using libraries and system calls specific to a platform. This can be something of a platform, especially regarding GUIs.

Abstraction

Here you don’t worry about compiling for different platforms. Rather you write your program in an interpreted language which will run without any change for all platforms for which an interpreter exists. You can use a full-fledged virtual machine like the Java Virtual Machine or you can use a more lightweight interpreter solution like Python or Perl. The obvious restriction with this method is that an interpeter must exist for your target platform (and your users must have the interpreter installed). Howver this shouldn’t be a problem if you stick to the three listed above.

Tomorrow I’ll take a look at ways to implement each of the above methods, explore the potential difficulties of each and take a look at solutions and workarounds.

Tagged

Why I’m sticking with Linux

The Republic of Geektronica has an article about why the author is sticking with Windows XP and won’t be ugrading to Vista. Well, I’m a Linux user and I though my parents use Windows XP, I haven’t used it for the last few months. Anyway, here are my ten reasons for sticking with Linux. They run in parallel to Geektronica’s, so go take a look at those reasons first:

  1. I have far better things to spend $300 on.
  2. All my programs not  only work now, I get free and easy upgrades pretty regularly.
  3. My RAM (512MB) is about 150 MB more than my heaviest usage. I don’t want it to be 150MB less than minimal usage.
  4. Superkaramba and gDesklets can satisfy my desire for shiny things
  5. The next computer I buy will hopefully have Linux preinstalled, so I won’t have to wipe the hard drive clean first.
  6. If I want transparent windows, I’ll use the XFCE compositor
  7. I’ve I wanted more restrictions on my media, I’d put cotton in my ears and wear a blindfold.
  8. My desktop is behind a browser for most of the time (and the browser is better than IE)
  9. I want my operating system to be up-to-date without having to reach for a credit card before hitting the download button.
  10. I like cartoonish blue and green, and earthy orange, and metallic goldish bling and black empty screens (not all at the same time though).
Follow

Get every new post delivered to your Inbox.

Join 287 other followers