Archive for the 'cool' Category

11
Dec
09

cool site


Visit this: http://langref.org/ !

It’s such a great website! I was amazed to see Scala is 90% covered. Surely this will help my learning experience.

14
Jul
09

hacking python at runtime:a cool way of modifying your scripts


I recently discovered the _ast module. Using it, one can process Python’s syntax trees.

I’m going to illustrate the use of this module with a simple example. Here’s the code snippet we’re going to work on :


import geo
for file in os.listdir("."):
	print file

Let’s talk a bit about this snippet.

It’s kind of obvious this script has runtime errors. On my Python installation there’s no module named geo … chances are there’s not one on your system either 🙂
Another error would be the call to os.listdir. This is not an error per-se, because if you import the os module, no exception will get thrown at runtime. We can easily notice that the os module has not been imported.

Here’s what we’ll accomplish using the _ast module :

  • remove the import of the module geo
  • add an import to the os module
  • to make things more interesting, we’ll change the “.” argument of the listdir function to the “D:\\” drive

So, how do we get the syntax tree? Pretty simple :


import _ast

source_code = """
  import geo
  for file in os.listdir("."):
    print file
"""
ast = compile(source_code,"<string>","exec",_ast.PyCF_ONLY_AST)

The compile function will build an AST object. The members of the AST can be accessed through the ast.body list. In this example, ast.body[0] will be the import statement, and ast.body[1] will be the for statement.

So, now we have an AST!

The first thing we’ll do is clone the import object. I’m doing this so that I don’t have to create an import object manually. I’m lazy, I know. If you don’t know how to clone a Python object, the following snippet illustrates it :


import copy
an_object_copy = copy.deepcopy(an_object)


With this import clone, I want to import the os module. But, since this clone still has geo as it’s argument, we need to change that. We change that with the following snippet :


os_import = copy.deepcopy(ast.body[0])
os_import.names[0].name = "os"


This object is now equivalent to the following code:


import os


This is nice, but we have to add it to the AST. I’ll take advantage of this to remove the import geo statement:


# remove the import geo statement
ast.body.remove(ast.body[0])
# we insert the import os as the first statement
ast.body.insert(0,os_import)


Right now, the code is runnable. No exceptions will be thrown. Before we run it, let’s accomplish the final task too. Let’s modify the argument of listdir from “.” to “D:\\”.We know that the for object will be the second object in the list:


for_obj = ast.body[1]
# change the argument of listdir to D:\
for_obj.iter.args[0].s = "D:\\"


This changes the argument. In case the attributes I’m setting seem magic, you can find them out using Python’s introspection system ( it’s how I found them too ). You can use this system from ipython, or even your python interpreter, by calling the dir function on any object. This call will list the name of the methods the object has.
Now that we have modified the AST, we need to transform it into runnable code. We do that by calling the compile function :


code = compile(ast,"<string>","exec")


We can run the code with the exec function :


exec code

Here’s the full code of the script:


import _ast
import copy

def fix_source(source_string):
	ast = compile(source_string,"<string>","exec",_ast.PyCF_ONLY_AST)
	# clone the import object, so we can modify it
	os_import = copy.deepcopy(ast.body[0])
	# remove the import geo statement
	ast.body.remove(ast.body[0])
	# change the import argument to os
	os_import.names[0].name = "os"
	# add the import os statement to the ast
	ast.body.insert(0,os_import)
	for_obj = ast.body[1]
	# change the argument of listdir to D:\
	for_obj.iter.args[0].s = "D:\\"
	# transform the AST into something runnable
	return compile(ast,"<string>","exec")
	
if __name__ == "__main__":
	source_code = """
import geo
for file in os.listdir("."):
	print file
"""
	code = fix_source(source_code)
	exec code

I’m sure you can put this trick to use. It’s one of the greatest “hacks” I know.

I’ll try to post a Ruby alternative as soon as time allows me.

10
Jun
09

How to use the eclipse code formatter from your code


I was wondering if I could use the Eclipse Code Formatter from inside my code … so, the logical thing to do was to ask on stackoverflow, and see if anyone knew how to do that. Thanks to VonC‘s answer, I found out about the CodeFormatter class … and 10 jars and 2 hours later, I’ve got it working.

Here’s how I did it.

CodeFormatter is an abstract class, which means you can’t instantiate it directly. So, I started to search about classes derived from it, and so I found out about DefaultCodeFormatter, which I presumed was what I was looking for. I was right.

DefaultCodeFormatter implements the method :


public abstract TextEdit format(int kind,
                                String source,
                                int offset,
                                int length,
                                int indentationLevel,
                                String lineSeparator)

Method documentation can be read  here.

I wrote the following code to test it :


... main(String[] args) {
   String code = "public class geo{public static void main(String[] args){System.out.println(\"geo\");}}";
   CodeFormatter cf = new DefaultCodeFormatter();
   TextEdit te = cf.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
   System.out.println(te);
}

I used the CodeFormatter.K_UNKNOWN constant for the formatting, because I was thinking that the CodeFormatter will “deduce” the type of code I’ve passed it. I’m not really sure what K_UNKNOWN does, but it seems to work well with the code I’ve tried.

So … the DefaultCodeFormatter returned a TextEdit object as the result of the code formatting.
I was kind of hoping that it’s toString method would give me the code. Instead, I found out it had several ReplaceEdit children nodes. I tried to iterate over each of the children and print their text using their getText, but they wouldn’t “show me the code” 🙂 . I thought “TextEdit’s apply method sounds interesting. Let’s see what it does”. Checking it’s method signature :

apply(IDocument document) 

revealed a IDocument parameter. I was hoping it would be easy to create a Document object, and that I wouldn’t need any other “eclipse objects”. Turns out it was easy. There is a Document implementation, that has a String constructor :

Document(String initialContent)

I applied the TextEdit to the document, and hoped for the best. The eclipse console printed out nicely formatted code. WIN !

Here’s the full code for the class I used to test the CodeFormatter :


import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;


public class FormatterTest {

	public static void main(String[] args)
	{
		String code = "public class geo{public static void main(String[] args){System.out.println(\"geo\");}}";
		CodeFormatter cf = new DefaultCodeFormatter();
		
		TextEdit te = cf.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
		IDocument dc = new Document(code);
		try {
			te.apply(dc);
			System.out.println(dc.get());
		} catch (MalformedTreeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadLocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}	
}

Here’s the list of jars I had to add to the classpath to get the code formatter to work :

  1. org.eclipse.jdt.core_3.4.4.v_894_R34x.jar
  2. org.eclipse.text_3.4.0.v20080605-1800.jar
  3. org.eclipse.core.runtime_3.4.0.v20080512.jar
  4. org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
  5. org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
  6. org.eclipse.core.resources_3.4.2.R34x_v20090126.jar
  7. org.eclipse.core.jobs_3.4.1.R34x_v20081128.jar
  8. org.eclipse.core.contenttype_3.3.0.v20080604-1400.jar
  9. org.eclipse.osgi.services_3.1.200.v20071203.jar
  10. org.eclipse.equinox.preferences_3.2.201.R34x_v20080709.jar

They may have different versions on your eclipse installation. They worked for my eclipse installation :


Version: 3.4.2
Build id: M20090211-1700

One of those jars isn’t needed, but I can’t remember which. Sorry for the extra classes.

Hope this helps anyone!

15
Apr
09

some blender thoughts


2 years ago I needed a cube model for an application. After googling for information I got to a site that explained how to create them using vertices/triangle strips. I suck at maths/geometry, so that looked like a complicated process to me.
I did my best to understand them, but I failed miserably. All I had was some code I copy-pasted, code I didn’t understand. So, I started to look for alternatives. I discovered that models created in tools like Maya or 3D Studio Max could be imported and used. Since I didn’t have either of those, I looked for something open-source. That’s how I found Blender. After reading some available documentation, and watching some user-contributed videos, I was able to obtain a cube that looked the way I wanted it to.
Even though I wasn’t able to finish the app, I made a note to self that I should learn Blender. I think the day has come that I should do that. I think this new set of skills would be useful for a large number of things ( think game development ), or maybe develop your creative side more.
Cool? You bet.

30
Mar
09

cartoon: duck tales


Duck Tales was/is one of my favorite cartoons of all time. You gotta love Uncle Scrooge and the nephews 🙂 . Remember this?

It brings back good memories .

19
Mar
09

I love the 90’s


Dr Alban always was one of my favorite singers. I practically grew up listening to his music. I can’t say I’ve been a big fan of Haddaway, but their “new” song is just awesome :

Superb ! GG Dr Alban & Haddaway !

19
Mar
09

nice quote


Heard this here http://www.youtube.com/watch?v=yQSVMU5FPDo :
You’ll never fulfill your great destiny until you meet your greatest challenge




Blog Stats

  • 216,805 hits