"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects." (Robert A. Heinlein)

Monday, 2 February 2009

Backing-up the EEEPC with Clonezilla


I'm going to install EEEBuntu to but first I decided to back-up my current installation. I decided to use Clonezilla, the 'live' distribution, mainly because it promised to be a clean and fast tool.
I used one 1GB USB pen drive as boot device and an external 250GB USB hard drive as backup device.
I first downloaded Clonezilla, the zip format distribution, (from here) and uncompressed it to my USB pen drive. Then, following instructions from Clonezilla site,  I made my USB drive bootable using Live USB Helper.
I then started my EEEPC from the usb drive, by pressing  ESC key at boot time and choosing the pen drive from the boot menu.
I proceeced with backup operation following Clonezilla site instructions (here). No screenshots, sorry, but there is no real difference between what I did and screenshots published in Clonezilla how to pagesThe only real difference is the disk naming: on the EEEPC internal disks are usually named "sda" and "sdb" while external disk names may change (in this case it was "sdc").
Here are my selections, in the order they appeared:
  • "Clonezilla Live (Default settings, VGA 800x600)" in boot menu options
  • Language: "English" (Italian is also available)
  • Keymap: first 'qwerty' then 'italian' and 'standard'
  • "Start_Clonezilla" option
  • Mode: "device-image" to backup source diskto an image fale in destination disk
  • Mode: "local_dev" to select a local device (the usb external drive) as target device
  • Destination device: "sdc1" this is the name given to my external drive and mounted by Clonezilla as "/home/partimag"
  • Backup directory: "Top_directory_in_the_local_device"
  • Mode: "savedisk" to save the whole EEEPC disk to an image
  • Image name: "2009-02-05-23-img" the default name
  • Source disks: "sda" and "sdb"
  • Clone programs priority: "-q : ntfsclone > partimage > dd" 
  • Advanced extra parameters: none changed from default
  • Compression: "-z1 Use gzip compression"
  • Split size: "0" EEEPC (disks are small so why to split the image?)
  • Action after cloning: "true do nothing"
In conclusion I think Clonezilla is really a valuable fast and clean tool. It took only 15 minutes to backup my EEEPC disks (not very full indeed) to an image a little bigger than 3GB. Clonezilla interface may seem a little primitive but, while using it, I never felt the need of a more complex one. So I, definitely, have no escuses for not to backup my system at least before any major upgrade.



Friday, 30 January 2009

Names generators with MySQL

There are on the net several names generator. theese programs staring from an input name generate some kind of funny phrase.
Here is an example of a "nickname generator":
The algorithm behind these programs is quite simple: it's just matter of using your name as a key to select phrase components from one or more tables. Here is a simple way to do this using MySQL:
First let's create a couple of tables:
CREATE TABLE ADJECTIVES(
              TERM VARCHAR(30));

CREATE TABLE ANIMALS(
              NAME VARCHAR(30));
Then fill the tables with some value
INSERT INTO ADJECTIVES VALUES('Lazy');
INSERT INTO ADJECTIVES VALUES('Fat');
INSERT INTO ADJECTIVES VALUES('Crazy');
INSERT INTO ADJECTIVES VALUES('Ugly');

INSERT INTO ANIMALS VALUES('Bull');
INSERT INTO ANIMALS VALUES('Cow');
INSERT INTO ANIMALS VALUES('Monkey');
INSERT INTO ANIMALS VALUES('Chicken');
To implement the selection we can use MySQL RAND()  function. Rand function can generate a pseudo-random number sequence based on a seed integer passed as parameter. The same seed number ever generates the same sequence.
Another function HEX() let us easily convert our input string to a number we can use as seed.
The number generated from RAND() function can eventually be used to select a row in the table.
Let's put all together:
SELECT
(SELECT TERM FROM ADJECTIVES ORDER BY RAND(HEX('musante.i.ph')) LIMIT 1) AS Adjective,
(SELECT NAME FROM ANIMALS ORDER BY RAND(HEX(REVERSE('musante.i.ph'))) LIMIT 1) AS Animal;
(Update) since RAND() ever generates the same number sequence from the same seed number we must use a different seed for every word we need to extract. To do this we neeed to change the source string in order to obtain a different seed number. In my example I used the REVERSE() function to implement it (not the best choice indeed) but even simpler solutions, like adding a different constant to each, should work also well.
Here is the result:

Adjective Animal 
Crazy     Chicken

Does it fit with my blog? Probably no more than "Ultimate Monk"!
What makes the difference, in this kind of programs, is the database of names used. A wider database generates, of course , a less repetitive set of phrases but what really matters is a good choice of the words database.

Thursday, 15 January 2009

Experimenting with Linux: Jinzora

Because of my job I've been too busy to post anything for a while (even at my very slow posting rate) but now here I am again with another experiment on my little Linux server.
 I was interested in experimenting with video and audio streaming, after a little of Google searching I found  this how to about Jinzora installation. Jinzora is a web based media streaming and management system completely written in PHP. It gives you a graphic user interface to search, organize and view your media files simply from your web browser. What triggered me to choose Jinzora was mainly the limited requirements It has. It helped also that i had the computer almost ready with Apache2 and MySQL already installed.
 I started my installation directly from how to's part 2 by installing some missing  component:
sudo apt-get install libapache2-mod-auth-mysql
sudo apt-get install php5-gd
and then I edited my php configuration to fit Jinzora requirements by typing:
sudo pico /etc/php5/apache2/php.ini
 and adjusting some parameters
 max_execution_time = 300
memory_limit = 128M
post_max_size = 32M
file_uploads = On
upload_max_filesize = 32M 
I then downloaded Jinzora and installed it in Apache
wget http://downloads.sourceforge.net/jinzora/jz275.tar.gz
sudo tar xvzf jz275.tar.gz
sudo mv jinzora2 /var/www/jinzora2
sudo chmod -R 777 /var/www/jinzora2
 And after restarting Apache server as usual ...
sudo /etc/init.d/apache2 restart
I've been able to access to Jinzora using my browser at the server address:
http://192.168.30.100/jinzora2/
Jinzora asks you to configure some initial configuration parameters like MySQL user and password in order to complete installation. Everthing is done with the help of a simple and well explained web based user interface. After initial configuration Jinzora asks you to delete the installation directory before proceeding with normal use. This was easily done ...
sudo rm -r /var/www/jinzora2/install
After this I finally managed to enter in Jinzora.
As my first impression Jinzora works fine: video streaming is smooth, and this is what really matters, and the user interface is clean and effective (you can choose many GUI layout and skins). I installed VLC media player on my Windows client (Sempron 2400) in order to play streaming while on my Linux laptop (EEEPC with Xandros) everything worked fine using Real player (RAM) streaming mode.
 If I'm going to continue with this media server and transform it to a fully operative one I'll need some better hardware platform with a bigger hard-disk and a quieter fan. But, at the moment, it's still just another Linux experiment.

Wednesday, 24 December 2008

Merry Christmas

No code, no screenshots this time ... simply the warmest MERRY CHRISTMAS to everybody who happens to read my blog. 
(Update 31/12)
And happy new year too!

Thursday, 18 December 2008

Merry (fractal) Christmas

This is my first Christmas as a blogger and, an old coder like me couldn't help not to post some Christmas related piece of code. I spent some of my spare time, mainly while travelling by train, writing a small java program to draw a fractal tree and I finally tuned it to produce something resembling a Christmas tree.
The algorithm used is fairly simple:  just draw a branch (a segment) and then attach some others branches to it calling recursively the same branch method. Recursive calls are stopped when branch length falls below a giver value. to make the final result a little more realistic a little randomness is added and branch color is decided on the basis of branch length.
The result is far from being satisfying (and lightyears far from artistic results as in here) but I don't think I'll get something better before Christmas.
  
Here is the code of the tree drawing class while the user interface was generated by the Netbeans plugin with only minimal manual coding needed.
package ph.mm.demo.fractals;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;

/**
 *
 * @author user
 */
public class TreePainter {

    Graphics2D graphics = null;
    private double scale = 0.42;
    private double scale2 = 0.49;
    private double angle =115;
    private double minLength = 3;
    private double rangle = 0;
    private double split = 0.6;
    private double noise = 0.05;
    private long seed = 3214;
    private Random rnd=null;
    private double x0=200;
    private double y0=350;
    private double x1=200;
    private double y1=200;
    float colScale = 0;
            
        
    public TreePainter(Graphics g) {
        graphics = (Graphics2D)g;
        graphics.setBackground(Color.BLACK);
        graphics.clearRect(0, 0, 500, 500);
        rangle=Math.toRadians(angle);
        rnd = new Random(seed);
        colScale = (float)(1/(y0-y1));
    }
   
    public void paint(){
        Line2D l = new Line2D.Double(x0, y0, x1, y1);
        branch(l);
    }
    
    public void branch(Line2D l){
        Rectangle2D r = l.getBounds2D();
        double size = Math.sqrt(r.getWidth()*r.getWidth() + r.getHeight()*r.getHeight());
        graphics.setColor(getCol(size));
        graphics.draw(l);
        
        if(size>minLength){
            double cAngle=0;
            cAngle = Math.acos((l.getX2()-l.getX1())/size);
            System.out.println(size+ ", " + Math.toDegrees(cAngle));
            if(l.getY1()>l.getY2()) cAngle=-cAngle;
            
            Point2D pSplit = new Point2D.Double(l.getX1() + (l.getX2()-l.getX1())*split,
                                                l.getY1() + (l.getY2()-l.getY1())*split);
            Point2D pEnd1 =  new Point2D.Double(l.getX2() + size*scale*getNoise()*Math.cos(cAngle), 
                                                l.getY2() + size*scale*getNoise()*Math.sin(cAngle));
            Point2D pEnd2 =  new Point2D.Double(l.getX2() + size*scale*getNoise()* Math.cos(cAngle*getNoise()+rangle), 
                                                l.getY2() + size*scale*getNoise()*Math.sin(cAngle*getNoise()+rangle));
            Point2D pEnd3 =  new Point2D.Double(l.getX2() + size*scale*getNoise()* Math.cos(cAngle*getNoise()-rangle), 
                                                l.getY2() + size*scale*getNoise()*Math.sin(cAngle*getNoise()-rangle));
            Point2D pEnd4 =  new Point2D.Double(pSplit.getX() + size*scale2*getNoise()* Math.cos(cAngle*getNoise()+rangle), 
                                                pSplit.getY() + size*scale2*getNoise()*Math.sin(cAngle*getNoise()+rangle));
            Point2D pEnd5 =  new Point2D.Double(pSplit.getX() + size*scale2*getNoise()* Math.cos(cAngle*getNoise()-rangle), 
                                                pSplit.getY() + size*scale2*getNoise()*Math.sin(cAngle*getNoise()-rangle));
            branch(new Line2D.Double(l.getP2(), pEnd1));
            branch(new Line2D.Double(l.getP2(), pEnd2));
            branch(new Line2D.Double(l.getP2(), pEnd3));
            branch(new Line2D.Double(pSplit, pEnd4));
            branch(new Line2D.Double(pSplit, pEnd5));
        }
        
    }
    
    private double getNoise(){
        return (rnd.nextDouble()-0.5)*2*noise+1;
    }
    
    private Color getCol(double size){
        if(size<minLength)
            return new Color(0.05F, 0.5F, 0.2F);
        else if(size<minLength*2)
            return new Color(0.05F,0.4F, 0.1F);
        else if(size<minLength*10)
            return new Color(0.05F,0.3F, 0.3F);
        else
            return new Color(0.3F,0.3F, 0.1F);
    }
            
}