Yuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.comYuce's Bloghttp://yuce.tekol.net/2012-11-02T22:00:00ZacrylamidReportLab on OSXtag:yuce.tekol.net,2012-11-03:/2012/reportlab-on-osx2012-11-02T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>It's easy to compile <a href="http://www.reportlab.com/">ReportLab</a> on OSX (<em>in my case, 10.8</em>). The only problem is, you'll get the following warning:</p>
<pre class="highlight"><code># installing without freetype no ttf, sorry!
# You need to install a static library version of the freetype2 software</code></pre>
<p>Don't try to <code>brew</code> it yet. OSX already has freetype2 installed on versions before 10.7. For 10.7 and later make sure you install <a href="http://xquartz.macosforge.org">XQuartz</a>. Then we just need to help ReportLab installer to help find it.</p>
<p>Download ReportLab, and insert the following lines around after line 104 (after <code># attempt to make sure we pick freetype2 over other versions</code>):</p>
<pre class="highlight"><code class="language-plain">aDir(I, "/usr/X11/include")
aDir(L, "/usr/X11/lib")</code></pre>
<p>Remove the <code>build</code> directory (<em>if it already exists</em>) and do <code>python setup.py build</code> as usual. It should work.</p>New Blogtag:yuce.tekol.net,2012-10-04:/2012/new-blog2012-10-03T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Here's my new blog, with content collected from my previous blogs.
It's running on a modified <a href="https://github.com/posativ/acrylamid">Acrylamid</a> static blog generator.
You can access the modifications on <a href="https://github.com/yuce/acrylamid">my GitHub fork</a>.</p>Prometheus - The Movietag:yuce.tekol.net,2012-06-11:/2012/prometheus-the-movie2012-06-10T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Scenario: a grocery store</p>
<p>A WOMAN approaches you as you carefully appreciate the sodium content of a can of beans.</p>
<p>WOMAN: That can of beans is going to kill Earth!</p>
<p>YOU: My God!</p>
<p>(<em>you proceed to bludgeon your forehead with the can of beans until you knock yourself unconscious.</em>)</p>
<p>— This is a parody of a scene from #Prometheus, source: IMDB comment.</p>Compiling Python Extension Modules on Mac OSX 10.6tag:yuce.tekol.net,2011-05-27:/2011/compiling-python-extension-modules-on-mac-osx-10-62011-05-26T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>If you get the following error when you are compiling a Python C extension module in Mac OSX 10.6:</p>
<pre class="highlight"><code>/gcc/darwin/ppc/as or /usr/bin/../local/libexec/gcc/darwin/ppc/as) for architecture ppc not installed
Installed assemblers are:
/usr/bin/../libexec/gcc/darwin/x86_64/as for architecture x86_64
/usr/bin/../libexec/gcc/darwin/i386/as for architecture i386
spammodule.c:63: fatal error: error writing to -: Broken pipe compilation terminated.</code></pre>
<p>Run setup.py as follows:</p>
<pre class="highlight"><code>ARCHFLAGS="-arch i386 -arch x86_64" python setup.py build</code></pre>OSX-like Window Title Buttons for GNOME 2tag:yuce.tekol.net,2010-03-22:/2010/osx-like-window-title-buttons-for-gnome-22010-03-21T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>The following works on OpenSolaris with GNOME 2.28.2</p>
<pre class="highlight"><code class="language-text">$ gconftool-2 -t string -s \
"/apps/metacity/general/button_layout" \
"close,minimize,maximize:menu"</code></pre>Installing Flash on Open Solaris snv_132tag:yuce.tekol.net,2010-02-16:/2010/installing-flash-on-open-solaris-snv-1322010-02-15T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<ol>
<li>Install <code>SUNWmlib</code> package.</li>
<li>Save <code>flash_player_10_solaris.x86.tar.gz</code> from <a href="http://get.adobe.com/flashplayer/">http://get.adobe.com/flashplayer/</a> to <code>~/Downloads</code>.</li>
<li>
<p>Open a terminal and execute the following:</p>
<pre class="highlight"><code class="language-text">cd ~/Downloads
tar xjvf flash_player_10_solaris_x86.tar.bz2
pfexec cp ~/Downloads/flash_player_10_solaris_r42_34_x86/libflashplayer.so /usr/lib/firefox/plugins</code></pre>
</li>
<li>
<p>Restart Firefox</p>
</li>
</ol>Go Sample: Link Checkertag:yuce.tekol.net,2009-11-14:/2009/go-sample-link-checker2009-11-13T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>You should have heard about <a href="http://golang.org/">Go</a>, Google's new language.
To be honest, it is one of the ugliest languages I've ever used (<em>I mean among the ones not designed to be ugly</em>); but it's interesting enough, and I decided to teach myself some.</p>
<p>Here's the result of a few hrs of reading, searching, coding, reading again and coding: an (almost) port of Josh Marshall's <a href="http://blog.joshmarshall.org/2009/11/url-checker/">Python URL Link Checker</a>.
It doesn't support checking local files, but has a nice <code>-v</code> switch which lets you see all processed URLs.
So far, programming Go felt a bit like programming C++.
Also, Go links the code statically at the moment, which results in an executable of size 1.2MB for 64bit Linux.
(<em>DISCLAIMER: the following program is a toy, don't use it for anything serious</em>)</p>
<pre class="highlight"><code class="language-text">package main
import "fmt"
import "http"
import "os"
import "bytes"
import "regexp"
import "strings"
import "container/vector"
import "flag"
// from Go tutorial
func Append(slice, data[]byte) []byte {
l := len(slice);
if l + len(data) > cap(slice) { // reallocate
// Allocate double what's needed, for future growth.
newSlice := make([]byte, (l+len(data))*2);
// Copy data (could use bytes.Copy()).
for i, c := range slice {
newSlice[i] = c
}
slice = newSlice;
}
slice = slice[0:l+len(data)];
for i, c := range data {
slice[l+i] = c
}
return slice;
}
func get_page(url string) string {
// http.Get doesn't work well without a slash at the end
url = url + "/";
var content []byte;
var buf [65535]byte;
resp, _, e := http.Get(url);
if e != nil {
fmt.Println(e);
os.Exit(1);
}
for true {
rlen, e := resp.Body.Read(buf[0:len(buf)]);
if e == os.EOF {
break;
}
else if e != nil {
fmt.Println(e);
os.Exit(2);
}
content = Append(content, buf[0:rlen]);
}
resp.Body.Close();
return bytes.NewBuffer(content).String();
}
func get_urls(page *string) []string {
link_re, _ := regexp.Compile(`http://[^ <>"'()]+`);
return link_re.AllMatchesString(*page, 0);
}
func check_url(url string) int {
url = strings.TrimSpace(url);
// using GET instead of HEAD, since Go has a Get function
// and we just need the response code
resp, _, e := http.Get(url);
if e != nil {
return 0;
}
return resp.StatusCode;
}
func main() {
// parse command line arguments
isVerbose := flag.Bool("v", false, "Display processed URLs");
flag.Parse();
if flag.NArg() < 1 {
fmt.Println("Usage: checkurls [-v] URL");
os.Exit(1);
}
checkedUrl := flag.Arg(0);
fmt.Printf("Searching for URLs [%s]\n", checkedUrl);
codes := make(map[int]*vector.StringVector);
page := get_page(checkedUrl);
urls := get_urls(&page);
fmt.Printf("Checking %d URLs...\n", len(urls));
for i := 0; i < len(urls); i++ {
code := check_url(urls[i]);
// if code wasn't seen before, create a vector for it in codes
if _, ok := codes[code]; !ok {
codes[code] = vector.NewStringVector(0);
}
codes[code].Push(urls[i]);
if *isVerbose {
fmt.Printf("[%3d] %s\n", code, urls[i]);
}
}
fmt.Println("\nResults");
fmt.Println("=======");
for code, links := range codes {
fmt.Printf("There were %d %ds.\n", links.Len(), code);
if 399 < code && code < 500 {
for i := 0; i < links.Len(); i++ {
fmt.Printf("* %s\n", links.At(i));
}
}
fmt.Println("");
}
}</code></pre>Getting the Current Module in Pythontag:yuce.tekol.net,2009-10-15:/2009/getting-the-current-module-in-python2009-10-14T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Say, you want to insert a function, class or any other object into the current module dynamically.
How can you do that? Of course, you start with getting the module name:</p>
<pre class="highlight"><code class="language-python">myName = globals()['__name__']</code></pre>
<p>Then, get the module itself:</p>
<pre class="highlight"><code class="language-python">import sys
me = sys.modules[myName]</code></pre>
<p>OK, you got the module, now insert something in it:</p>
<pre class="highlight"><code class="language-python">setattr(me, 'hello', lambda x: 'Hello %s'%x)</code></pre>
<p>We can call hello in our module from now on:</p>
<pre class="highlight"><code class="language-python">print hello('World')</code></pre>Merging PDF Files Using Ghostscripttag:yuce.tekol.net,2009-10-14:/2009/merging-pdf-files-using-ghostscript2009-10-13T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>If you have to merge PDF files, you need no other than Ghostscript (which is installed by default with many Linux distributions).
Here's the command line:</p>
<pre class="highlight"><code class="language-text">gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=firstANDsecond.pdf -dBATCH first.pdf second.pdf</code></pre>Web Application Testing with Selenium: Basics and Setuptag:yuce.tekol.net,2009-10-09:/2009/web-application-testing-with-selenium-basics-and-setup2009-10-08T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<h3>Introduction</h3>
<p>It's always hard to ensure an application works up to a specification and continue keeping up to the specs in the course of development.
Testing web applications is even harder, since they are composed of more components, and usually at least some of the components of the application are not directly controlled by the developers, such as links to other internet resources or mashups.</p>
<p>Luckily, there's a great tool for easing the pain of web application testing: <a href="http://seleniumhq.org/">Selenium</a>.
Selenium simulates a human user, by controlling a web browser using Javascript through a system called <em>Selenium Core</em>.
The simulated behaviour includes clicking on links, form and dialog buttons; filling in forms; drag&drop and others.</p>
<p>Currently there are two ways to develop and run Selenium tests, <a href="http://seleniumhq.org/docs/03_selenium_ide.html">Selenium IDE</a> which is a Firefox extension and <a href="http://seleniumhq.org/docs/05_selenium_rc.html">Selenium Remote Control</a> which consists of a Java server that controls the browser and client APIs for writing tests.</p>
<p>In this series of articles I will try to explain how to write tests for Selenium RC.</p>
<h3>Prerequisites and Install</h3>
<p>Selenium server is written in Java and requires a Java runtime environment of version 5 or up, a recent version of Python is required (<em>I've used 2.5 and 2.6</em>) for the client API (<em>other languages are also supported, including Java and PHP</em>); last of all a browser with decent Javascript is required, Firefox and Safari works great.
Internet Explorer and Opera are supported too.</p>
<p>If you are on Linux, most probably you already have Python and Firefox installed and may need to install Java; on Mac OSX Leopard and up you need to install Firefox; on Windows you need to install all prerequisites.</p>
<p>In the rest of the article, I assume you're on a UNIX-like system and familar with the command line.
If you're ready, let's roll!</p>
<ol>
<li>Download Selenium RC from: <a href="http://seleniumhq.org/download/">http://seleniumhq.org/download/</a> and extract it to somewhere convenient.
The package contains Selenium server and client APIs for several languages.</li>
<li>Create a directory for the tests, I picked <code>~/tests</code>.</li>
<li>Copy <code>selenium-server.jar</code> from <code>selenium-server</code> directory in the package to <code>~/tests</code>.</li>
<li>Copy <code>selenium.py</code> from <code>selenium-python-client-driver-1.0.1</code> directory in the package to <code>~/tests</code>.
Alternatively, you can copy it to somewhere in your Python path.</li>
<li>Selenium is installed!</li>
</ol>
<h3>Writing a Simple Test</h3>
<p>Now, let's write a simple test using Selenium client API for Python.
This test demonstrates only a small portion of Selenium's power.
Save the following code to <code>~/tests/test_wikipedia.py</code>.</p>
<p>Selenium has a nice <a href="http://wikipedia.org/wiki/selenium">Wikipedia page</a>.
Suppose we want to check whether that page is up frequently since we are fans of Selenium.
We could write a test as follows:</p>
<pre class="highlight"><code class="language-python">import time
import unittest
from selenium import selenium
# Select Firefox as the browser
# (Note that this is not Google's Chrome)
BROWSER = '*chrome'
SITE_URL = 'http://en.wikipedia.org'
class WikipediaSeleniumTest(unittest.TestCase):
def setUp(self):
self.sel = selenium('localhost', 4444,
BROWSER, SITE_URL)
self.sel.start()
def test_wikipedia(self):
sel = self.sel
sel.open('/')
# Go to selenium page
sel.type('id=searchInput', 'selenium')
sel.click('id=searchGoButton')
sel.wait_for_page_to_load(30000)
# assure we are on selenium page
assert sel.get_title().startswith('Selenium'), \
'Selenium page not reached'
# Wikipedia displays selenium element page,
# let's visit the software one
sel.click('link=Selenium (software)')
sel.wait_for_page_to_load(30000)
assert sel.get_title().startswith('Selenium (software)'), \
'Selenium (software) page not reached'
# wait a bit so we can see the last page
time.sleep(5)
def tearDown(self):
self.sel.stop()
if __name__ == '__main__':
unittest.main()</code></pre>
<p>You can get the source from here <a href="http://python.pastebin.com/f3293f2a8">http://python.pastebin.com/f3293f2a8</a>.
I will explain the code in the next article in this series, but we can run it and see how it works:</p>
<ol>
<li>Run Selenium server: <code>java -jar selenium-server.jar&</code>.</li>
<li>Run the test: <code>python test_wikipedia.py</code>.</li>
</ol>
<p>If everything goes right, you should see two Firefox windows: the one on the top contains executed Selenium commands (<em>Selenese</em>), and bottom one shows the automated Firefox window, which reflects the executed Selenese.
You can make that window larger to see "selenium" is written in the search box and visited pages change as Selenium clicks buttons and links.
If the test completes successfully, you will see something like the following in your console:</p>
<pre class="highlight"><code class="language-text">---------------------
Ran 1 test in 16.536s
OK</code></pre>
<p>The dots represents number of tests completed successfully.
Since there was only one test run, there's one dot.</p>PySWIP: Facts and Rulestag:yuce.tekol.net,2009-10-08:/2009/pyswip-facts-and-rules2009-10-07T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p><a href="http://code.google.com/p/pyswip/">PySWIP</a> is a Python module which enables accessing <a href="http://www.swi-prolog.org/">SWI-Prolog</a>'s foreign language interface using our beloved computer language.
Here's a small tutorial on adding facts and rules to prolog knowledgebase.</p>
<p>First, adding facts and rules, based on examples in a <a href="http://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/rules.html">Prolog tutorial</a>.</p>
<pre class="highlight"><code class="language-python">from pyswip import Prolog
p = Prolog()
# something is fun if it is a car and it is red.
p.assertz('(fun(X) :- red(X), car(X))')
# facts...
p.assertz('car(vw_beatle)')
p.assertz('car(ferrari)')
p.assertz('car(hyundai)')
p.assertz('bike(harley_davidson)')
p.assertz('red(ferrari)')
p.assertz('red(vw_beatle)')
p.assertz('blue(hyundai)')</code></pre>
<p>Find all cars in the knowledgebase:</p>
<pre class="highlight"><code class="language-python">print list(p.query('car(Which)'))</code></pre>
<p>Outputs:</p>
<pre class="highlight"><code class="language-python">[{'Which':'vw_beatle'}, {'Which':'ferrari'}, {'Which':'hyundai'}]</code></pre>
<p>Find all fun things:</p>
<pre class="highlight"><code class="language-python">print list(p.query('fun(What)'))</code></pre>
<p>Outputs:</p>
<pre class="highlight"><code class="language-python">[{'What':'vw_beatle'}, {'What':'ferrari'}]</code></pre>
<p>Pretty easy, huh? ;) There are more complex Prolog examples in <a href="http://code.google.com/p/pyswip/downloads/list">PySWIP source distribution</a>, including a sudoku solver.</p>Getting the Currently Playing Song Info on Amarok via DCOPtag:yuce.tekol.net,2009-08-13:/2009/getting-the-currently-playing-song-info-on-amarok-via-dcop2009-08-12T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Here's a sample application for using DCOP with Python.
Needed to install <a href="http://packages.debian.org/search?keywords=python-dcop">python-dcop</a> on Debian.
It works on KDE 3.5 with Amarok 1.4 (<em>won't work on KDE 4</em>)</p>
<pre class="highlight"><code class="language-python">import pydcop
playerService = pydcop.DCOPObject('amarok', 'player')
d = dict(
title=playerService.title(),
artist=playerService.artist(),
album=playerService.album()
)
print '%(artist)s - %(title)s (%(album)s)' % d</code></pre>
<p><strong>kdcop</strong> is a great application to discover DCOP services.</p>
<p>I've posted a slightly extended version of this entry to <a href="http://code.activestate.com/recipes/576878/">Active State Python Cookbook</a>.</p>Auto-set Filetype for Django Templates for Vimtag:yuce.tekol.net,2009-08-11:/2009/auto-set-filetype-for-django-templates-for-vim2009-08-10T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Add the following to your Django templates for automatically setting the file type to Django when you open them with Vim:</p>
<pre class="highlight"><code class="language-django">{% comment %}
# vim:ft=django
{% endcomment %}</code></pre>Ctypes Stringstag:yuce.tekol.net,2007-05-28:/2007/ctypes-strings2007-05-27T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>I've written bulk of <a href="http://code.google.com/p/pyswip/">PySWIP</a> last summer, it is based on Nathan Denny's <code>proolog.py</code>.
This is the first project that I used <a href="http://starship.python.net/crew/theller/ctypes/">ctypes</a>, a fantastic package which allows calling C functions from dynamic libraries that I use to link <code>libpl.so</code> (<em>Linux</em>) or <code>libpl.dll</code> (<em>Windows</em>) of <a href="http://www.swi-prolog.org/">SWI-Prolog</a>.
One of the difficulties I had back then was finding the corresponding ctypes code for <code>PL_get_chars</code> which is defined at <code>SWI-Prolog.h</code> as follows:</p>
<pre class="highlight"><code class="language-c">PL_EXPORT(int) PL_get_chars(term_t t,
char **s, unsigned int flags);</code></pre>
<p>I use that function in <code>queryGenerator</code>:</p>
<pre class="highlight"><code class="language-python">answer = (c_char_p*maxsubresult)()
while PL_get_list(swipl_list, swipl_head, swipl_list):
PL_get_chars(swipl_head, answer,
CVT_ALL | CVT_WRITE | BUF_RING)
bindings.append(cstr2pystr(answer))</code></pre>
<p>And, <code>cstr2pystr</code> is a home-madePython function to convert from a C-string to a Python string in an awful way ;)</p>
<p>That was until I've seen this <a href="http://www.pererikstrandberg.se/blog/index.cgi?page=PythonCansiCombo">article</a> in the <a href="http://www.pererikstrandberg.se/blog/">blog</a> of a good person called Erik Strandberg.
His article is about using ctypes, and especially using ctypes types which inspired me to write the code below (knowing that a function called <code>addressof</code> existed helped much!), thanks Erik :)</p>
<pre class="highlight"><code class="language-python">answer = c_char_p("\x00"*MAXSTR)
while PL_get_list(swipl_list, swipl_head, swipl_list):
PL_get_chars(swipl_head, addressof(answer),
CVT_ALL | CVT_WRITE | BUF_RING)
bindings.append(answer.value)</code></pre>SEND + MORE + MONEYtag:yuce.tekol.net,2007-05-27:/2007/send-+-more-+-money2007-05-26T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Finding valid and distinct integers for digits S, E, N, D, M, O, R and Y in the equation SEND + MORE = MONEY is a classical constraint programming problem.
Here's the slightly modified version of the sample program at <a href="http://en.wikipedia.org/wiki/Constraint_programming">Wikipedia constraint programming entry</a> for <a href="http://www.swi-prolog.org/">SWI-Prolog</a> using clp library:</p>
<pre class="highlight"><code class="language-prolog">:- use_module(library('clp/bounds')).
sendmore(Digits) :-
Digits = [S,E,N,D,M,O,R,Y],
Digits in 0..9,
S #\= 0,
M #\= 0,
all_different(Digits),
1000*S + 100*E + 10*N + D
+ 1000*M + 100*O + 10*R + E
#= 10000*M + 1000*O + 100*N + 10*E + Y,
label(Digits).</code></pre>
<p>Here's what happens when we load the code and run <code>sendmore</code>:</p>
<pre class="highlight"><code class="language-prolog">?- consult('money.pl').
% library(clp/clp_events) compiled into clp_events 0.00 sec, 2,948 bytes
% library(clp/bounds) compiled into bounds 0.03 sec, 90,992 bytes
% money2.pl compiled 0.03 sec, 91,812 bytes
Yes
?- sendmore(X).
X = [9, 5, 6, 7, 1, 0, 8, 2] ;
No</code></pre>
<p>So, 9567 + 1085 = 10652.
AFAI remember, there was a similar question asked to Google's candidate software engineers, which was <code>WWW + DOT = COM</code>.
Well, you now know the answer ;)
I'll include both examples for my <a href="http://code.google.com/p/pyswip/">PySWIP</a> Python package which enables to query SWI-Prolog from Python.</p>Eclipse Workspace Problemtag:yuce.tekol.net,2007-03-04:/2007/eclipse-workspace-problem2007-03-03T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Today, while commiting <a href="http://biz.berlios.de">Biz</a>, <a href="http://www.eclipse.org/">Eclipse</a> locked up,
and after that it didn't get past the slash screen in the subsequent runs.
I've wasted some time to fix it, and here is a simple solution:
Just delete <code>~/workspace/.metadata/.plugins/org.eclipse.ui.workbench</code> and you're good ((<em>assuming your workspace is <code>~/workspace</code></em>) .</p>Shameful Pasttag:yuce.tekol.net,2005-10-24:/2005/shameful-past2005-10-23T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>A few hours ago, when I was dealing with my thesis, I've come up with a Python function that constructs a tour for a given <a href="http://www.tsp.gatech.edu/">TSP</a> instance using the <a href="http://itp.nat.uni-magdeburg.de/%7Emertens/TSP/node2.html">nearest neighbor heuristic</a>:</p>
<pre class="highlight"><code class="language-python">def nearestneighbor(size, dists):
tour = [0]*size
candy = [True]*size
candy[0] = False
for i in range(1, size):
prev = tour[i - 1]
tour[i] = min([(dists[prev][c], c)
for c in range(size) if candy[c] and c != prev])[1]
candy[tour[i]] = False
return tour</code></pre>
<p>Not too bad...
Then I dig into old Python code that I wrote last year, the times when I was quitting C++ and beginning to use Python; and find this piece of code that consists of a class named <code>Nearestneighbor</code> doing (almost) the same thing as the function above:</p>
<pre class="highlight"><code class="language-python">class Nearestneighbor:
def __init__(self, dists):
self.__dists = dists
self.dimension = dists.shape[0]
def construct(self, startcity = None):
if startcity is None:
self.startcity = rnd.randint(self.dimension)
else: self.startcity = startcity
self.tour = [self.startcity]
cities = range(self.dimension)
del cities[self.startcity]
while cities:
ndist = sys.maxint # nearest :) distance
nindex = 0 # nearest city's index
pcity = self.tour[-1] # previous city
ndist = self.__dists[pcity,cities[nindex]]
for i in range(1, len(cities)):
dist = self.__dists[pcity,cities[i]]
if dist < ndist:
nindex = i
ndist = dist
self.tour.append(cities[nindex])
del cities[nindex]</code></pre>
<p>Well, this is definitely not my favorite piece of Python code ;-)</p>Freeeze for Marvin3tag:yuce.tekol.net,2005-10-17:/2005/freeeze-for-marvin32005-10-16T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Today, I added a keyword called <em>freeze</em> to Marvin3.
Basically, when called inside a routine, it pops the top element from the stack and replaces routine's code with a word that pushes that value onto the stack.
This way we can create a <em>write-once</em> routine, which is similar to C#'s <code>readonly</code> modifier (<em>value is allowed to be set once</em>).
Consider the following example:</p>
<pre class="highlight"><code class="language-text">:YOUR-NUMBER input int freeze ;
"Enter a number:" prints YOUR-NUMBER
YOUR-NUMBER " is a nice number!" cat println</code></pre>
<p>Notice that, although <code>YOUR-NUMBER</code> is a routine, when called, it just pushes the same value determined when it is first called.</p>
<p>Here is a more complex one. The following set of class and routines implement a generator that returns subsequent numbers starting from 1 (<em>then 2, 3, ...</em>):</p>
<pre class="highlight"><code class="language-text">@__generate 0 !n [%n incr ^n] dup ;
:_generate __generate freeze ;
:generate _generate call ;</code></pre>
<p>The Python equivalent is (although using generators would be better):</p>
<pre class="highlight"><code class="language-python">class _generate:
def __init__(self):
self.n = 0
def __call__(self):
self.n += 1
return self.n
generate = _generate()</code></pre>wxPython 2.6.1.0 on Ubuntu Hoary Hedgehogtag:yuce.tekol.net,2005-10-11:/2005/wxpython-2-6-1-0-on-ubuntu-hoary-hedgehog2005-10-10T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>One of the few packages I needed but couldn't find in Ubuntu repository is wxPython 2.6 (<em>the repository only supports 2.5.3.2</em>).
Following a trail at <a href="http://www.wxpython.org/download.php#sources"">wxPython download</a>, I managed to install 2.6.1.0.
Thanks to the guys at <a href="http://www.bitpim.org/developer.html">BitPim</a>[BitPim] for giving directions to convert a wxPython source RPM to deb.
I had a few more steps for Hoary, and I posted the complete instructions to <a href="http://wiki.wxpython.org/wxPython%20with%20Ubuntu">wxPython wiki</a>.</p>99 Bottles of Beer in Marvin3tag:yuce.tekol.net,2005-09-29:/2005/99-bottles-of-beer-in-marvin32005-09-28T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>How to write 99 bottles of beer in Marvin3?</p>
<pre class="highlight"><code class="language-text">:bottles dup dup 1 > [" bottles"] [" bottle"] ifte cat ;
:sing
bottles dup " of beer on the wall," cat println
" of beer. " cat println
"Take one down, pass it around." println ;
:theend "No more beer left." println ;
:beers [dup 0 >] [sing decr] while theend eat ;
# start singing
99 beers</code></pre>
<p>Also you may check <a href="/2005/99-bottles-of-beer-on-the-wall/">a previous post</a> for <em>the original</em> Marvin.
Other languages? <a href="http://www.westnet.com/mirrors/99bottles/beer.html">99 Bottles of Beer on the Wall</a> lists many.
See <a href="http://en.wikipedia.org/wiki/99_Bottles_of_Beer">99 Bottles of Beer on Wikipedia</a>.</p>Marvin3 is launchedtag:yuce.tekol.net,2005-09-27:/2005/marvin3-is-launched2005-09-26T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<blockquote>
<p>Marvin3 is a new cross-platform stack-based language developed in Python.
Marvin3 features object-oriented-programming, anonymous routines, eager lists, variables, lexical scope, combinators and support for modules.</p>
</blockquote>
<p>This is from my <a href="http://sourceforge.net/projects/marvin3/">Marvin3 project home</a>.
Marvin has evolved into Marvin3 and is becoming ready to be tried by the audience.
In order to make it better known, and because it is free software, I requested a SourceForge account yesterday, and to my surprise my request was approved in a couple of hours (<em>while I was led to believe that it would take two days!!!</em>).
Well, I am happy for that, and I released Marvin3 0.0.6 which has some way to go; but it is still somewhat usable (or triable???).</p>
<p>This release of Marvin3 includes the interpreter command-line, as well as a GUI called Mice (<em>Marvin3 Interactive Command Environment</em>).
If you want to have a look, be sure you have <a href="http://www.python.org">Python</a> 2.4.1 and <a href="http://www.wxpython.org">wxPython</a> 2.6.1 (<em>if you intend to use the Mice GUI</em>).
Mice GUI seems to work OK with WinXP (<em>with some quirks</em>) but having problems with GNOME 2.10 (on Ubuntu 5.04).
Most probably, this is because of the old version of wxPython shipped with Ubuntu 5.04.
Later I will post a Win32 binary release and try to release an Debian/Ubuntu deb.
Anyway, you can download Marvin3 0.0.6 from <a href="http://sourceforge.net/projects/marvin3/">Marvin3 project home</a>.
The zip file has a few sample Marvin3 programs (<em>but it is ridiculously few, next release will be serious about this</em>), so you can try them and even tell me your opinions.</p>
<p>That's all folks (for now)...</p>Ubuntu is Greattag:yuce.tekol.net,2005-09-14:/2005/ubuntu-is-great2005-09-13T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>Last week, I received 20 (1 install + 1 live) Ubuntu Linux 5.04 (Hoary Hedgehog) CDs <em>FOR FREE</em> (details will follow).
Of course in no time I installed it. I have to say that Hoary rocks!
I was using Warthy before, and this new release fixes the few problems Warthy had (e.g., my Kingston USB-disk is now recognized, and my computer turns off when I log out.)</p>
<p>The new version of Ubuntu, <a href="http://www.ubuntu.com/newsitems/5.10preview">Breezy Badger</a> is on its way out but let me write some of the features of Hoary:</p>
<ul>
<li><a href="http://www.python.org/2.4.1/">Python 2.4.1</a>, the latest version for now.</li>
<li><a href="http://www.gnome.org/start/2.10/">GNOME 2.10</a>, not the latest version (<em>2.12 will be included in Breezy</em>) but works perfectly.</li>
<li><a href="http://www.mozilla.org/products/firefox/">Firefox 1.02</a>, not the latest version but it is updated easily in Windows Update style.</li>
<li>Synaptic package manager that makes install/update/uninstall a snap.</li>
<li><em>much more...</em></li>
</ul>
<p>Well, after installation of the base system, I ran Synaptic and downloaded other software I frequently use, such as <a href="http://wxpython.org">wxPython</a> for GUI programming with Python (<em>2.5.3.2pre is the latest in the repository though, I hope 2.6.1.0 will be available soon</em>),
<a href="http://www.mozilla.org/products/thunderbird/">Thunderbird</a> (1.06) for reading my mail (<em>Evolution 2.2 is installed by default</em>).</p>
<p>Now the <em>FOR FREE</em> part... Most Linux distros are downloadable for free, but Ubuntu won't charge anything even sending the CDs to you in reasonable quantities.
There are people who asked for and received 100 CDs! I was not greedy that much however, so I only asked for 20.
If you are nearby <a href="http://www.emu.edu.tr">EMU</a> <a href="http://cmpe.emu.edu.tr">Department of Computer Engineering</a> room 124, you may take one free from me.
Or you may order some CDs for yourself at <a href="http://shipit.ubuntulinux.org/">Ubuntu shipit</a>.
Don't forget to read the <a href="http://www.ubuntulinux.org/support/documentation/faq/shipit/">FAQ</a> though.
(<em>Note: The CD distribution is closed until the release of Breezy, which will be releason on October.</em>)</p>The Gods Made Heavy Metal in Istanbultag:yuce.tekol.net,2005-09-13:/2005/the-gods-made-heavy-metal-in-istanbul2005-09-12T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>The eminent heavy metal band <a href="http://www.manowar.com/"">Manowar</a> was in Istanbul, Turkey on August 6th 2005.
The concert was at Yedikule (7 Towers) Dungeons, the perfect place for it.
It was also raining and thundering when the band was playing <em>Hail and Kill</em>.
The show was in one word, <strong>PERFECT!</strong>, we kept on screaming and singing the songs at the top of our voice during the concert (<em>well, I couldn't speak for two days afterwards :)</em>).</p>
<p>One of the most important events of the concert was, Joey DeMaio's announcement in which he said, "Manowar's hatred against Turks is a LIE!"; he even kissed the Turkish flag, and said, "This is the color of heavy metal" , and later, "heavy metal was born here".
Damn right! Below is a photo of DeMaio with the Turkish flag:</p>
<p><img alt="Manowar in Istanbul" src="/manowar_istanbul.jpg" /></p>
<p>The concert was the main event of the Rock the Nations 3 Open-Air Festival.
Manowar promised to come back to Turkey next year; be sure to be there!</p>
<p><strong>LONG LIVE HEAVY METAL!!!</strong></p>Generating All Strings of a Given Alphabettag:yuce.tekol.net,2005-06-10:/2005/generating-all-strings-of-a-given-alphabet2005-06-09T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>For a recent research project, I had to write a function that generates all the strings of a given alphabet.
It was (as always) very easy to figure it out in Python, only 5 minutes; below is the code (with modifications, I've polished the idea a bit):</p>
<pre class="highlight"><code class="language-python">def allstrings(alphabet, length):
"""Find the list of all strings of 'alphabet' of length 'length'"""
if length == 0: return []
c = [[a] for a in alphabet[:]]
if length == 1: return c
c = [[x,y] for x in alphabet for y in alphabet]
if length == 2: return c
for l in range(2, length):
c = [[x]+y for x in alphabet for y in c]
return c</code></pre>
<p>Then, suppose you want the possible strings of length 4 of alphabet {1,2,3}; then just write:</p>
<pre class="highlight"><code class="language-python">allstrings([1,2,3], 4)</code></pre>
<p>And here is the Haskell version:</p>
<pre class="highlight"><code class="language-haskell">allstrings alphabet n
| n == 0 = []
| n == 1 = [alphabet]
| n == 2 = [[a,b] | a<-alphabet, b<-alphabet]
| otherwise =
[[a] ++ b | a<-alphabet, b<-(allstrings alphabet (n - 1))]</code></pre>Accumulator Generatortag:yuce.tekol.net,2005-04-26:/2005/accumulator-generator2005-04-25T22:00:00ZYuce Tekolhttp://yuce.tekol.net/yucetekol@gmail.com<p>In his <a href="http://www.paulgraham.com/accgen.html">accumulator generator</a> page, Paul Graham compares several languages to solve a particular problem that is quoted below
(apparently, he has chosen this example in favor of his new Lisp-like language <a href="http://www.paulgraham.com/arc.html">Arc</a>):</p>
<blockquote>
<p>The problem: Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.</p>
<p>Note: (a) that's number, not integer, (b) that's incremented by, not plus.</p>
</blockquote>
<p>My trial with Marvin was a failure, and could not satisfy all the 5 requirements given <a href="http://www.paulgraham.com/accgensub.html"">here</a>.
But now with Marvin2 (a rewrite of the language) this can be accomplished with the following line:</p>
<pre class="highlight"><code class="language-text">@foo !n [ %n + ^n ] ;</code></pre>
<p>Nice... You can then run the sample code like this:</p>
<pre class="highlight"><code class="language-text">1 'foo new !x
5 \x
3 'foo new
2.3 \x println</code></pre>
<p>And the result is 8.3, as expected.</p>