Keeping it Small and Simple

2007.06.06

Translating source code into a different language as practice

Filed under: Computer Programming, Java Programming — Lorenzo E. Danielsson @ 13:05

One of the things I encourage my programming students to do is to take open source programs and rewriting them in a different programming language, or using a different GUI toolkit. There are a number of benefits to this:

  1. The student learns to read somebody else’s code
  2. The student learns to analyze code in a language that is different from the one they are learning
  3. The student (hopefully) learns a few new programming techniques along the way
  4. It is yet another way to keep the student writing code
  5. It provides a bit of variation from the old “write a program that..”-type exercises.

It’s easy to say that this is a “passive” process, meaning the student simply just translates the code to “their own” programming language without reflecting much about what they are doing. That may be true for some people, but then again, some people go through an entire programming class without reflecting much on what they are doing.

Another thing is that a friend of mine raised the concern that programming languages sometimes differ in techniques and that if I am translating a C program into Java I might be learning “C-isms”. First of all, I don’t quite understand what is so wrong with “C-isms”. Secondly, it is your responsibility as a teacher/mentor to review their code and point out areas where they could improve the program.

Remember that at first the student’s primary concern is with getting the program running at all. It is only once they have been able to do succeed in that that they will start worrying about “making it look like a conventional Java program”. The following might be a rough sketch of this process.

  1. Translate the program straight off (leaving variable names exactly the same etc). At this stage, the students only concern is to get the program to compile (in the case of a compiled language) and run, with all the functionality of the original program intact.
  2. Next they begin to do things like renaming variables to suit the language. For example, if translating a C program to Java, you might want to rename a variable from x_axis to xAxis simply because that is a convention that most Java programmers follow.
  3. Then the student refines the code. In the case of translating from a non-object orient language to an object oriented one, this might involve moving parts of the application functionality out into classes, where that makes sense.

Translating a program from for example C to Java, or from using Qt to using Gtk is not some form of miracle solution that will turn everybody into a master programmer. But it is a way to let the people who are genuinely interested in programming to get some extra practice. That’s all. I find the exercise useful. I would love to hear what others think. Please leave your comments/experiences in the comments section.

Finally I will give a small example. Recently, I had a Java student who said he wanted to learn how to do graphics programming. So I helped him get a hold of some programs (mostly in C) and told him to start translating them into Java. To demonstrate it I took this program by CorTeX/Optimum and wrote it as a Java applet. You can see the result below (you will obviously need to create an HTML document to load the applet in order to see it in action).

  1 /*
  2  * "Flashouillis" for Java.
  3  *
  4  * Original C program written by corTeX/Optimum.
  5  *
  6  * Author: Lorenzo E. Danielsson <danielsson.lorenzo (AT) gmail DOT com>
  7  * Date created: 2007.04.21
  8  */
  9 
 10 import java.awt.Color;
 11 import java.awt.Graphics;
 12 import java.awt.Image;
 13 import javax.swing.JApplet;
 14 
 15 import static java.lang.Math.cos;
 16 import static java.lang.Math.sin;
 17 import static java.lang.Math.random;
 18 
 19 public class JFlash extends JApplet implements Runnable {
 20     private final int WIDTH = 500;
 21     private final int HEIGHT = 500;
 22     private final int DELAY = 10;
 23     private final int FLASH_MAX = 5000;         // Number of points.
 24     private final int G_ACC = 330;              // Acceleration (g).
 25 
 26     private Thread animation = null;            // Animation thread.
 27     private Graphics buffer = null;             // Back buffer for drawing.
 28     private Image image = null;
 29     private Flash[] flash = new Flash[FLASH_MAX];
 30     private int current;
 31     private float ax = 0.0F, ay = 0.0F, az = 0.0F;
 32 
 33     public void init() {
 34         image = createImage(WIDTH, HEIGHT);
 35         buffer = image.getGraphics();
 36 
 37         for (int i = 0; i < FLASH_MAX; ++i) {
 38             flash[i] = new Flash();
 39             flash[i].state = 0.0F;
 40         }
 41 
 42         current = 0;
 43     }
 44 
 45     public void paint(Graphics g) {
 46         buffer.setColor(Color.BLACK);
 47         buffer.fillRect(0, 0, WIDTH, HEIGHT);
 48 
 49         for (int i = 0; i < FLASH_MAX; ++i) {
 50             if (flash[i].state == 0 || flash[i].state >= 1)
 51                 continue;
 52 
 53             int x = (int)(flash[i].x + flash[i].vx * flash[i].state);
 54             int y = (int)(flash[i].y + flash[i].vy * flash[i].state
 55                     + (flash[i].state * flash[i].state) * G_ACC);
 56 
 57             if (x < 0 || x > WIDTH || y < 0 || y > HEIGHT)
 58                 continue;
 59 
 60             int red = (int)(flash[i].r * (1 - flash[i].state)) << 3;
 61             int green = (int)(flash[i].g * (1 - flash[i].state)) << 2;
 62             int blue = (int)(flash[i].b * (1 - flash[i].state)) << 3;
 63 
 64             if (red > 255) flash[i].r = 255;
 65             if (green > 255) flash[i].g = 255;
 66             if (blue > 255) flash[i].b = 255;
 67 
 68             buffer.setColor(new Color(red, green, blue));
 69             buffer.drawLine(x, y, x, y);
 70 
 71             flash[i].state += 0.007F;
 72         }
 73 
 74         g.drawImage(image, 0, 0, null);
 75     }
 76 
 77     public void run() {
 78         Thread thread = Thread.currentThread();
 79         while (animation == thread) {
 80             repaint();
 81 
 82             int x = (int)(WIDTH/2 + WIDTH/4 * (cos(ax+ay) + sin(ay-az)));
 83             int y = (int)(HEIGHT/2 + HEIGHT/4 * (sin(ax-ay+2*az)
 84                         + sin(ax+ax/2)));
 85 
 86             for (int j = 0; j < 40; ++j) {
 87                 float rd = (float)(2.0 * random() * Math.PI);
 88                 float vx = (float)(cos(rd));
 89                 float vy = (float)(sin(rd));
 90                 rd = (float)(50.0 + random() * 30.0);
 91                 vx *= rd;
 92                 vy *= rd;
 93 
 94                 flash[current].x = x + ((int)(random() * Integer.MAX_VALUE)
 95                         & 3);
 96                 flash[current].y = y + ((int)(random() * Integer.MAX_VALUE)
 97                         & 3);
 98 
 99                 flash[current].vx = vx;
100                 flash[current].vy = vy;
101                 flash[current].state = 0.01F;
102 
103                 flash[current].r = (int)(10 * cos(ax*6) + 20);
104                 flash[current].g = (int)(20 * cos(ay*5) + 40);
105                 flash[current].b = (int)(10 * cos(az*7) + 20);
106 
107                 ++current;
108                 if (current == FLASH_MAX)
109                     current = 0;
110             }
111 
112             ax += 0.05F;
113             ay += 0.03F;
114             az += 0.0441F;
115 
116             try {
117                 thread.sleep(DELAY);
118             } catch (Exception e) {}
119         }
120     }
121 
122     public void start() {
123         animation = new Thread(this);
124         if (animation != null)
125             animation.start();
126     }
127 
128     public void stop() {
129         if (animation != null)
130             animation = null;
131     }
132 
133     public void update(Graphics g) {
134         g.clipRect(0, 0, WIDTH, HEIGHT);
135         paint(g);
136     }
137 }
138 
139 class Flash {
140     public int x = 0, y = 0;
141     public int r = 0, g = 0, b = 0;
142     public float state = 0.0F;
143     public float vx = 0.0F, vy = 0.0F;
144 }
145 

So this obviously does quite a few things that look familiar to a C programmer but maybe less so to a person from a Java background. But the point is that Java does support the shift operators. I’m not sure if you gain anything performance-wise in Java by using the shift operators for multiplying and dividing, but it is not illegal to do so.

Now this is just a first iteration of the program. It works, and looks like the original when run. You could easily modify it to look “better” from a Java point of view.

Advertisements

2 Comments »

  1. wow, great post. I program java but I hardly do graphics and animation stuff. Nice post.

    Well for me, when I want to a learn a new language, I normally rewrite a program I wrote in a language I’m comfortable with, with the new language I’m learning, that way it gives me firm understanding of the new language and let me experiment most features and its syntax. Translating source code from one language to another is really a good practice.

    Comment by eyedol — 2007.06.23 @ 21:58

  2. This website is Great! I will recommend you to all my friends. I found so much useful things here. Thank you.

    Comment by Claudette — 2007.09.09 @ 00:13


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: