Posts about programming (old posts, page 6)

2006-05-20 13:00

Python-v4l: neat!

Thinking about CherryTV and ways to turn it into a real application, I thought the worse piece of it was the reliance on v4lctl, and how really you just don't know if it works or not, and how you can't finetune, and whatever, and run into Python-v4l.

It has remained apparently untouched by two years, but I managed to build it with one edit and to make it work by switching a line to an alternate version (they are both there), and it's nice.

Here's the example TV viewing application using it:

#!/usr/bin/env python
# Sample TV viewing application for pyv4l >= 0.3 - by Michael Dove
#<[email protected]>
# Note: this does the imaging in grab mode. Performance is limited.
# I average 35 fps @ 320x240. Disabling the writes to the tk window yeilds 90+ fps.

import v4l
import Image
import ImageChops
WIDTH = 320
HEIGHT = 240
vid = v4l.video('/dev/video')
cap = vid.getCapabilities()
print "Device Name: %s" % cap[0]
print "Type: %d" % cap[1]
print "Channels: %d" % cap[2]
print "Audios: %d" % cap[3]
print "Maximum Width: %d" % cap[4]
print "Maximum Height: %d" % cap[5]
print "Minimum Width: %d" % cap[6]
print "Minimum Height: %d" % cap[7]
vid.setupImage(WIDTH, HEIGHT, v4l.VIDEO_PALETTE_YUYV)
print vid.getChannel(0) # TV
vid.setChannel(0) # set to TV
vid.setFrequency(216250)

import Tkinter
tk=Tkinter.Tk()
import ImageTk
photo = ImageTk.PhotoImage("RGB",(WIDTH,HEIGHT))
label= Tkinter.Label(tk,text="mini TV",image=photo,width=WIDTH,height=HEIGHT)
label.pack()

vid.preQueueFrames()
nextFrame = 0;
vid.setVolume(5)
vid.mute()

try:
    while 1:
        output = vid.getImage(nextFrame)
        im = Image.fromstring("RGB", (WIDTH, HEIGHT), output)
        # update Tk label
        photo.paste(im)
        tk.update()
        nextFrame = vid.queueFrame()

except Tkinter.TclError:
    print "something"
    pass
vid.mute()

If you have seen the equivalent C app... well... nice job here!

2006-05-17 08:29

Flickr Banners

If you are one of the three persons who actually see this blog on its site instead of reading it through some sort of aggregator, you may have noticed I have a banner.

This is what it looks like:

//ralsina.me/lateral/lateral.jpg//ralsina.me/lateral/opinion.jpg

Nice, ah?

It's not very original (look for "spell with flickr" to see where I stole the idea), but I wrote a script to do it. So here it is, feel free to steal it too, it's your turn.

You will need this, ImageMagick, and a Flickr API key.

To use it simply call it like this:

python banner.py something

And you will have a something.jpg with something in it.

#!/usr/bin/env python

import flickr,sys,random
from urllib import urlopen
import os

g=flickr.Group(id="[email protected]")

urls = []
for l in sys.argv[1]:
  if l=="a":
    l="aa"
  if l=="i":
    l="ii"
  photos = g.getPhotos(tags=[l], per_page=50)
  urls.append(photos[random.randrange(50)].getURL(
              size='Square', urlType='source'))


for i in range(0,len(urls)):
  f=open(str(i)+'.jpg','w')
  data=urlopen(urls[i]).read()
  f.write(data)
  f.close()

os.system ("montage -tile %dx1 -geometry +0+0 %s %s"%(
            len(urls),' '.join([ '%d.jpg'%x for x in range(0,
            len(urls)) ]), sys.argv[1]+'.jpg'))

2006-05-16 00:20

Using runit is even simpler

I have posted in the past about runit.

One of the problems people migrating to runit have is that all your services are SysV scripts.

The runit author has a collection of scripts you can use, but usually they require some adjustment to work on a specific version of Linux.

So, I wrote a lame python script that takes the SysV scripts you are currently using and turns them into runit services, including dependencies.

Suppose you usually start on runlevel 3. Then you save this script and run it like this:

mkdir services
python importinit.py 3

And you should end with a bunch of runit services inside services/

Those services will start in roughly the same order as if you were using SysV init. That's probably way too much dependencies.

The main difference is that kdm will start earlier and the ttys will start way earlier than you are used to.

I have found that my notebook boots faster using this, but I can't provide a bootchart because it simply doesn't seem to work in my computer.

If anyone is willing and able to run the tests and quantify the difference, I am all ears.

For some reason kudzu, iptables and arptables_jf don't work with this approach, so just stick them at the bottom of /etc/runit/1

Also, please understand that these are not correct runit services. They are not managed, so if your service crashes it stays crashed.

So, you should still eventually migrate to correct scripts. This is just a way to make that simpler.

2006-05-11 08:37

If you see a russian, it's my doing

In this russian site, you can see how they got my post about the Santa Fe python event. And apparently what impressed them is the thing about the fish and the beer.

См. вас там!

2006-05-08 23:40

I Jornada Python en Santa Fe, Argentina

Bilingual entry here:

Yo nací en Santa Fe. Me gusta Python. Hay un evento de Python en Santa Fe.

Pienso asistir solamente como espectador, quedarme callado y escuchar cosas interesantes que digan los demas.

Sin embargo, si quieren experimentar un lugar donde se pueden comer 30 platos de pescado por 20 pesos (y te podes comer los 30, aunque yo conozco solamente una persona con la suficiente fortaleza estomacal), mas toda la cerveza que puedas tomar... bueno, nos vemos en Santa Fe el 3 de junio.

Mas informacion aca


I come from Santa Fe. I like Python. There is a Python event on Santa Fe.

I intend to attend in a strictly spectator fashion. I will listen to other guys telling interesting stuff, and keep quiet.

However, if you want to experience a place where you can eat 30 different fish dishes for about 7 dollars (and I mean you can eat all 30, although I know only one person of such superhuman fortitude), plus all the beer you can drink... well, I will be in Santa Fe on June 3rd.

More information here

2006-05-02 15:44

FaxWeb is done

FaxWeb, a web frontend for mgetty+sendfax is finished. It works. It's probably close to bugfree ;-)

The missing piece is a nicer reimplementation of respond (and this one will be cross-platform, too) using PyQt, which is 50% done.

I am only missing how to implement portable systray icons. On Mac they make no sense, on Linux I have it working, on Windows I have no idea.

Here's the simple interface for faxweb:

http://static.flickr.com/54/139230422_f453d38430_t.jpg http://static.flickr.com/50/139230433_0d87a2f0ae_t.jpg http://static.flickr.com/47/139230434_f91f8d0b01_t.jpg

It even has a little AJAXy "the page doesn't reload" niceties courtesy of MochiKit!

Also from MochiKit, the nicer, rounded look&feel. Compare to this older, uglier one:

http://static.flickr.com/48/137206420_07ca331974_t.jpg

I know the new one is not good, either, but I have decided that since I can't aim for awesome, I should aim for adequate, and settle for boring and harmless.

Of course, if any CSS/XHTML guru volunteers for a makeover, I'd be very happy, since I use the same CSS everywhere (even on parts of this blog ;-).

All in all, a pleasure to write this thing, thanks to CherryPy!

2006-04-22 16:07

Now I remember why I don't like C++

I have refactored IUP/Qt into a lovely object hierarchy. And I now remember why I dislike C++.

Here's the basic problem (code may be wrong, I don´t have the broken versions anymore):

I have a base class IObject, that has stub setters/getters for all the IUP attributes.

For each kind of widget, I create a class that inherits from IObject and the matching Qt widget (example: QDialog).

These have to be hooked into an Ihandle structure through the use of a void * (remember, that's C, I have that too ;-)

Now, this was my first naive approach:

Ihandle *n;
IQDialog *d=new IQDialog();
n->handle=d; //handle is a void*

That compiles ok. However, when you try to call a d member later (and I know I am using old C casts... they had worked for me until today!) ...

((IObject *)(n->handle))set_title("Title here");

Blammo, segfault. Why? Because in one of the assignments to/from void *, the pointer for some reason starts to point elsewhere.

Here´s what Gliptic at #C++ suggested, and it does work:

Ihandle *n;
IQDialog *d=new IQDialog();
n->handle=static_cast <void *>(static_cast < IObject *> (d));

Right, I have to cast it twice.

And here is how you get it back:

(static_cast < IObject * >(n->handle))->set_title ("Some title");

Isn't this just ridiculously weird for anyone coming from any other language?

Or am I missing something completely?

But the good news is, it works ok, and the Qt backend now has a decent structure to hack on.

2006-04-17 14:55

The missing language

In the last month or two I have been writing a fair bit of C code.

I really dislike C. But I have not been able to find a language to replace it with, except C++, and that's not much of an improvement for what I did.

Maybe someone can read this and help me. I don't mind learning a new language. Really, it's no problem.

The goal is writing small programs (in the hundreds of lines region), which have the following requirements:

  1. The program MUST be correct. Can never segfault or crash in some other way.

Since the code is short, I think I have managed, using bstrlib, to get this, after quite a bit of pain, by auditing and unit-testing. But I am not sure, and I will never be.

It would be awesome if the language could be garbage-collected for this reason.

  1. It MUST have a decent string handling.

The programs handle mail. So, it's strings galore.

  1. It MUST have very low overhead. The programs should run and end quickly. Very quickly, because people may be waiting for them to end.
  2. It MUST be a reasonably simple language. I am not a great programmer, and these tools will be hacked at by people with limited programming skills (sysadmins like me!)
  3. Trivial access to C libraries.

So, let's see.

C: gives 3, 4 (in a fashion), and 5

C++: 2, 3, maybe 4, and 5

D: It seems to give me all of these, along with a C-like syntax... but I can't get it to work yet (correction, I got dmd to work, so it's looking good for D!).

So, any takers?

2006-04-02 01:56

BPython Lives!!!

In January, I suggested it would be trivial to write a preprocessor that would accept a version of python which delimited blocks with braces instead of indentation.

Ok, almost, I suggested #{ and #} as delimiters.

Well, I had a few minutes free today, and here it is, a functional BPython->Python compiler, so to speak.

Here's the kind of imput it takes (notice how it's not indented at all:

def factorial(n):
#{
if n==1:
#{
return 1
#}
else:
#{
return n*factorial(n-1)
#}
#}

for x in range(1,10):
#{
print x,"!=",factorial(x)
#}

And it produces this (I am not happy with the indenting of the comments, but who cares):

def factorial(n):
  #{
  if n==1:
    #{
    return 1
  #}
  else:
    #{
    return n*factorial(n-1)
  #}
#}

for x in range(1,10):
  #{
  print x,"!=",factorial(x)
#}

As you can see, this is both a legal Python and a legal BPython program ;-)

It has some problems, like not working when you use a line like this:

#{ x=1

But hey, it is python with braces.

Here's the code. I predicted 30 lines. It's 34. And it's 99% a ripoff of Ka Ping Yee's regurgitate.py which you can find all around the web.

#!/usr/bin/env python
import tokenize, sys
program = []
lastrow, lastcol = 1, 0
lastline = ''
indlevel=0
def rebuild(type, token, (startrow, startcol), (endrow, endcol), line):
    global lastrow, lastcol, lastline, program,indlevel
    if type==52 and token.startswith ("#{"):
            type=5
            indlevel+=1
    if type==52 and token.startswith ("#}"):
            type=6
            indlevel-=1
    line="  "*indlevel+line.lstrip()
    startcol+=indlevel*2
    endcol+=indlevel*2
    # Deal with the bits between tokens.
    if lastrow == startrow == endrow:            # ordinary token
        program.append(line[lastcol:startcol])
    elif lastrow != startrow:                    # backslash continuation
        program.append(lastline[lastcol:] + line[:startcol])
    elif startrow != endrow:                     # multi-line string
        program.append(lastline[lastcol:startcol])
    # Append the token itself.
    program.append(token)
    # Save some information for the next time around.
    if token and token[-1] == '\n':
        lastrow, lastcol = endrow+1, 0           # start on next line
    else:
        lastrow, lastcol = endrow, endcol        # remember last position
    lastline = line                              # remember last line
tokenize.tokenize(sys.stdin.readline, rebuild)
for piece in program: sys.stdout.write(piece)

So, all of you who dislike python because of the lack of braces and the significant whitespace:

BPython has no significant whitespace, and braces are mandatory.

Enjoy coding!

2006-01-27 22:04

Silly idea to make Python popular

I have an idea that can kill the most frequent complain about python.

BPython.

BPython is a simple wrapper around pyhton which processes a .bpy file, produces a .py file, then compiles it into a .pyc.

What does it do? It uses braces to control flow.

Since braces are actual python syntax, you will have to use #{ and #}

As an added bonus, if you are careful, a bpython program will also be a valid python program.

Of course it has issues (like module loading) but those can be worked around.

The implementation should not be more than 30 lines of python. Or bpython ;-)

Contents © 2000-2019 Roberto Alsina