100 times over

December 15, 2014

IMPORTANT NOTE: Do not try any of the following unless you have fully backed-up your files and after you have created Recovery Media on DVDs (i.e. a Windows 7 Installation DVD and a HP Drivers and Tools DVD) using the instructions provided by HP.NOTE: This guide is for people who already know how to install Windows and Ubuntu/Linux. It focuses on specific issues pertinent to this specific laptop. For general installation instructions you must find another source.DISCLAIMER: Installing an operating system that is not supplied by the hardware vendor may cause your computer to malfunction and/or void its warranty. The decision to perform such an installation is wholly your's (the reader's). The author holds no responsibility in case of damages due to reading and/or following the procedures described in this post.
I spent so much time trying to dual-boot Ubuntu 14.04 (64bit) and Windows 7 (64bit) on a HP ProBook 450 G2 laptop, that I figured I should share the knowledge with others who may try to do the exact same thing.

First of all: It is practically impossible to install a second operating system, on this laptop, without deleting at least ONE of the two partitions that contain system recovery files an tools. Yes, I am referring to the partitions named HP_TOOLS and HP_RECOVERY. Some say that you can do without HP_TOOLS (so you may choose to delete this one with no problem) and keep only HP_RECOVERY. I have not explored this option which could be useful, if you ever want to perform a "factory reset" and end up with the same setup that makes it impossible to install a second OS! If you are unsure, or if you already know that you will want to perform a factory reset in the future, then you must not perform any of the steps proposed below.

Why it is impossible to keep both of these partitions? Because the disk is partitioned with MBR, and so allows for only 4 partitions (and perhaps many logical drives inside the forth partition). The minute you resize one of the four existing partitions and try to create a fifth one (for Ubuntu), Windows presents you with a message that, to create the fifth partition, you have to convert the disk to a -so called- "dynamic" disk. DO NOT DO THIS if you plan to install Ubuntu under any circumstances. I did, thinking that a dynamic disk is perhaps Microsoft's term for a GPT disk, and later found out that no operating system, other than Microsoft's own, can use partitions on a dynamic disk. :(

To cut a long story short, after a lot of experimentation and unfortunate surprises*, I "chose" to partition my disk from scratch (thus deleting both HP_TOOLS and HP_RECOVERY), using MBR partitioning. This means that I created an "msdos" partition table, in GParted terms. I did the partitioning using the Ubuntu live USB stick, but you may do it during Windows 7 installation. However, it may be better to do it in Ubuntu, because this way you can be 100% sure that the partitions will be found by the Ubuntu installation program, which you will run AFTER the Windows 7 installation is completed (and this takes some time).

So, the steps that led to a successful installation are:

From your functioning Windows installation -if you haven't done so previously- create the Windows 7 Installation DVD and the HP Drivers and Tools DVD using the instructions provided by HP.

In the BIOS, make sure that in the Boot options the "Legacy" mode is selected (not UEFI hybrid, nor UEFI native). This was already selected in my laptop, but I played A LOT with the other options and eventually had to return to choosing the Legacy mode.

If you have experimented with GPT partitioning, or if you have converted your basic disk to a dynamic disk, you have to delete all partitions and partition your disk from scratch using MBR (msdos) partitioning. If you have useful files on your computer, you must absolutely back them up before you re-partition your disk. My computer was brand new so I did not have any files of my own on it yet and I could skip the backing-up step.

Install Windows 7 normally from the DVD. Be sure you select an appropriate size for the Windows partition and leave free space for Ubuntu. For me 100-150Gb is quite enough for Windows, because I do not install a lot of programs and I keep my personal files elsewhere (i.e. on another partition which is shared by both operating systems).

Install Ubuntu normally, on a partition different than the one where you just installed Windows on. Usually during this step, I also create a separate NTFS or FAT32 partition for my personal files, and I make this partition available to both Windows and Ubuntu.

In Ubuntu, you may have to disable the "gfxmode" of GRUB 2. I had to, because it messed up the Windows 7 boot screen. While Windows 7 did in fact boot ok after selecting its entry in the GRUB menu, the screen shown during Windows startup was corrupt (garbled). This made me think that I had a Windows boot problem, which was not the case. The OS was loading ok, only the splash screen failed to display correctly. This problem went away by setting GRUB 2 to use a text mode, not a graphical/hi-res mode.**

That's all!

If you ever try it, let me know if you had a different -hopefully better- experience along the way.-
UPDATE: January 27, 2015

Unfortunately, after all this trouble, I found out that the WiFi works very unreliably in Ubuntu. I am now using Windows most of the time and only boot into Ubuntu occasionally, to install any updates and check to see if the problem has been solved.* I tried A LOT to create a UEFI configuration, by partitioning my disk with GPT and changing the BIOS boot options and then trying to install Windows 7. Unfortunately, the Windows 7 setup program does not accept the use of GPT partitions for Windows installation. I am not sure if this is specific to my copy of Windows 7, but if you are working with the same one (the one created by HP recovery tools), by all means DO NOT waste time with UEFI and GPT partitioning!

** To disable the graphical GRUB 2 menu, enable the line GRUB_TERMINAL=console in /etc/default/grub, and perform a "sudo update-grub".

October 8, 2012

The problem of string transformation and manipulation is so common that every programming language offers either special features about it or, at the very least, a standard library with basic solutions.

In Java there's both regular expression matching /replacement via its standard library, and various “replace” operations that may be directly called on a String object. The replace operations return a new String, as in Java there can be no in-place replacement of String contents; String objects are immutable.

One problem that is common enough, in my opinion, to justify the development of a special method to handle it is this: replacing multiple characters in a String at once (in one go).

There are three kinds of replacements that we want to handle:

Replacing a character with another single character. This kind of replacement does not affect the length of the original string.

Replacing a single character with a sequence of characters (a string). This kind of replacement will increase the length of the original string.

Replacing a character with “nothing” i.e. removing the character from the string. This kind of operation will reduce the length of the original string.

We will use a Map<Character,Object> to associate the characters that are going to be replaced (keys in the Map) with the respective replacements. The replacement objects (values in the Map) will be Character objects for case number 1, non empty strings for case number two, and the empty string for case number 3.

The implementation takes care not to duplicate the original string, if there are no characters to be converted. Also, when there are characters to be converted, it will avoid copying characters one-by-one; i.e. the ones that do not need conversion will be copied in chunks as large as possible.

This is the fastest implementation that I could come up with. It may be optimised a bit further, if we only need to cover case 1: replacing characters with single characters (not with strings, and no removal of characters). In this case, we could achieve even better performance using this implementation:

In this last implementation "replaceAll()" performed at least 20% faster, in my tests, than the version in the more general StringConvertor class (using the same test data). I was also surprised to find out that -in converting upper case English text to lower case- it was a bit slower but comparable to the the built-in "toLowerCase()" method.

September 30, 2012

An example application of the Observer design pattern using Java

In one of my recent pet projects I needed objects that should be "aware" that one or more of their properties had changed. The obvious way to do it of course is to write code inside the "setter method" of each property and call whatever code must be executed in the event of a change. Something like that:

But what I really wanted was to attach an "on change" event to some of the object's properties and handle this event in a systematic way. I thought this was a valid opportunity to use the Observer design pattern and have the properties of the object notify their owner that they had changed.

We can assume that each property is not any more a simple object of a given type T, but an instance of an "observable object" that contains a value of type T:

The above solution, although valid, seems a little spartan. The PropertyObserver may be notified by calls to its notify() method, but it receives no information whatsoever about which property has changed or how it has changed. We should create a more interesting IPropertyObserver interface:

With this new implementation, the property observer object can be notified that a property has changed and also it may receive information about which property changed (the “sender” argument) and what was the value of the property before the change (the “previousValue” argument).

To cooperate with IPropertyObserver, the implementation of the ObservableProperty generic class must now change to something like this:

This new implementation also checks to see that the internal value of the property has in fact changed, before calling onPropertyChanged().

To try out this simple solution, let's create a simple Contact object; an object to hold the name and contact information of a person:

class Contact implements IPropertyObserver {
public final ObservableProperty<String> name = new ObservableProperty<String>(this);
public final ObservableProperty<Date> birthDate = new ObservableProperty<Date>(this);
public final ObservableProperty<String> mobile = new ObservableProperty<String>(this);
public final ObservableProperty<String> email = new ObservableProperty<String>(this);
public void onPropertyChanged(ObservableProperty<?> sender, Object previousValue) {
}
}

The Contact class, above, has four properties (name, birthDate, email, mobile) that are instances of ObservableProperty. Also, it implements the interface IPropertyObserver, so that it may be notified every time one of its observable properties has changed.

We now have a central place, where we can handle the event of a change in the values of the observable properties. The following code, for instance, will reflect on the object to find the property's name and then display an informative message reporting both the new and the old value of the property:

September 27, 2012

An example using the Scala programming language

I am currently learning Scala and I became quite intrigued by the compiler's ability to optimize tail-recursive calls.

For those unfamiliar with the concept, a tail-recursive method can be optimized to be executed in constant stack space. This practically means that the recursion is not really necessary and that the method in question could be implemented as a simple iterative process! Nevertheless, it is nice to have the compiler do the trick of converting the recursion into a loop and let the programmers express their ideas using recursion.

As an exercise, I set out to convert the renown Quicksort algorithm into tail-recursive form. But first, why would this algorithm need any conversion whatsoever?

Let us see an implementation of the algorithm written in Scala. I am using the following piece of code as it appears in “Scala By Example” by Martin Odersky (draft of May 24, 2011). It is a straightforward implementation of Quicksort for arrays of integers:

The recursive method sort1() may call itself up to two times at the end of each execution. This is the reason why the method is not tail-recursive. Indeed, if we use the @tailrec annotation in the definition of sort1(), the compiler will complain with this error:

could not optimize @tailrec annotated method sort1: it contains a recursive call not in tail position

The message refers to the line if (l < j) sort1(l, j).

To enable the optimization, we need to make sure that the recursive call may happen at most once at the end of the execution of sort1().

First, let's rewrite the algorithm so that the “sorting” part of it is factored out of the recursion. This is the part where elements are being compared against each other and swapped inside the array, so that the pivot element gets its “correct” position in the array (for an explanation of Quicksort you may read this Wikipedia article). We introduce a new method sortRange(), which will take a lower and upper bound and perform the “sorting work” on this segment of the array:

This new method does the sorting and then returns the values of “i” and “j” as a tuple, because these are needed to continue the process. The sort1() method still takes the same arguments as before and is in fact, again, not at all tail-recursive! Perhaps annoyingly, it does not even make use of Scala's idiomatic syntax for tuples, so we rewrite it to this more natural Scala form:

So, up to this point, we have broken down the initial implementation into a method “sortRange()” that can “do the sorting work” on segments of the array, and a recursive method “sort1()” that calls itself up to two times in every execution, using as arguments new segments of the array.

The recursive method sort1() takes as arguments the lower and upper limits of the array where it is going to work on. We are going to replace this method with one that takes as its only argument “a list of array segments” that remain to be sorted. Or, more precisely, a list of tuples containing the lower and upper bounds of the array segments that need to be sorted:

Conclusion

It was not so hard to convert the classic implementation of Quicksort into a from that is eligible for tail-recursion optimization using the Scala language. We could go ahead and convert this form into an iterative process even -but why not let the compiler do this step?

The question that arises naturally is: Is this implementation more efficient or better in any way than the classic implementation? I would answer yes AND no.

In the process of removing the second recursive call from the original code (from method sort1()), we introduced a method that needs an argument that is a list of things, while in the original form we had simple arguments of constant size. This list expands in size over time, using space in the heap. So, in effect, we traded heap space for stack space.

Arguably this is a good thing; as far as I know most machines (and this includes the Java virtual machine on its default settings) have a more limited stack space compared to their (sometimes virtually unlimited) heap space. With this in mind I believe that -under normal circumstances- the tail-recursive implementation would be able to operate on larger arrays than the classic method, without being prone to a stack overflow error.

Blog Archive

About Me

I am an Electrical Engineer and holder of a master's degree in e-Business. I have been doing object-oriented development for years (mostly Java, some C++) and I am currently employed in Athens, Greece.

I have always enjoyed learning new languages -and reinventing the wheel in the process- and I am very impressed with Ruby and Scala.

I started this blog to show my favourite ideas to fellow programmers. These are samples that I created over the years "for fun" or as part of one of my pet projects or while learning a new language. I hope you find them interesting and useful -at least for learning purposes- but I am not claiming that they represent optimal solutions in every case.

Our world is huge and I can't make sure that no one else has published something like that before. I will be glad to give credit to others as soon as I find out about it.