Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about python (old posts, page 16)

No, I don't get a dime from them

For a few months I have been us­ing an un­man­aged vir­tu­al pri­vate serv­er from Tek­ton­ic, and I love it.

What's that? Let's take it one word at a time, and then some more.

  1. It's a serv­er: which means it's a ful­l-ish lin­ux in­­stal­la­­tion. So it is ca­­pa­ble of do­ing lots of things. I can run all sorts of weird python thin­­gies in it if I wan­t. IMAPS and SSMT­P? No prob­le­­mo.

  2. It's pri­­vate: which means I am root on it. I have the shel­l. I choose what to in­­stal­l.

  3. It's vir­­tu­al: it's a Vir­­tuoz­­zo par­ti­­tion in a re­al serv­er. That means no cus­­tom ker­nel mod­­ules, and that since al­­most ev­ery­thing is shared with oth­­er in­­s­tances, 5GB of disk and 128MB of RAM go a long way.

  4. It's un­­man­aged: which means I man­age it. Which is just the way I pre­fer it, since that's my job.

  5. It's cheap. I start­ed on a 8 dol­lars a month plan (which does­n't seem to be there any­­more, the cur­rent cheap­­est is a 15 dol­lars plan).

  6. It's a throw­­away. I want to host some client as a favour? I just put it there. I could even rent an­oth­er of these servers for a while, use it, then close it. Back­­up­s? Click­­ing on a we­b­­page saves the im­age! Oth­­er than that... I back it.

  7. Fixed IP­s. All you want (for ex­­tra coin­s).

  8. A home away from home. All my stuff is there. I need it, I get it. With­­out both­­er­ing about hav­ing my own serv­er at home via no-ip or some­­such (which of course I still have too ;-)

  9. It works. It hard­­ly ev­er break­s. And hav­ing sur­­vived ex­pen­­sive, man­aged server­s, this ba­­by is work­ing just as well.

  10. It's a nice gift. Sup­­pose you have a con­nec­­tion to a free soft­­ware pro­­jec­t/LUG/­­fam­i­­ly/what­ev­er, and they need a place on the in­­ter­net. Why not spon­­sor them with some­thing like this? I of­fered one to PyAr (which did­n't take it, but it's the thought that counts ;-)

  11. The ul­ti­­mate learn­ing ex­pe­ri­ence: you can re­­s­tore the sys­tem in 2 min­utes. Want to play/learn sysad­min­ing? Do it on the re­al vir­­tu­al thing! Much cheap­­er than hos­ing your own box ;-)

  12. They of­fer a good ser­vice. So, peo­­ple should know about it. And of course... if you know a sim­i­lar, but even bet­ter deal... I'm all ears!

A different UNIX Part II: A better shell language

One of the things peo­ple study when they "learn unix" is shell script­ing and us­age. Be­cause ev­ery sys­tem has a shel­l, and if you learn to use it in­ter­ac­tive­ly, you are half way there to au­tomat­ing sys­tem tasks!

Let's con­sid­er that for a mo­men­t... what are the odds that the same lan­guage can be good for in­ter­ac­tive use and for pro­gram­ming? I say slim.

Not to men­tion that learn­ing shell as a way to learn unix is like go­ing to a school that teach­es TV pro­duc­tion, and study­ing the re­mote. While use­ful, not re­al­ly the im­por­tant tool (ok, that anal­o­gy does­n't work at al­l. But it sounds neat, does­n't it?).

The first thing is that to­day's Lin­ux dom­i­na­tion of the unix­sphere has caused a se­ri­ous mono­cul­ture in shell script­ing: ev­ery­one us­es bash. The more en­light­ened ones may check that their scripts work on some oth­er Bourne-style shel­l.

There are no im­por­tant dis­tri­bu­tions (or pro­pri­etary unix­es) that use a csh or any­thing like it. De­bian has a pol­i­cy that things should work with­out bashism­s. That's about as good as it get­s.

Writ­ing a dozen pages on how shell sucks would be triv­ial. But un­in­ter­est­ing.

So, let's think it over, and start from the top.

What should a shell script­ing lan­guage be like?

What does­n't mat­ter?

Let's tack­le these things. I in­vite any­one to add ex­tra ideas in the com­ments sec­tion.

What should a shell scripting language be like?

  • In­­ter­pret­ed (ob­vi­ous)

  • Dy­­nam­ic typ­ing (y­ou will be switch­ing ints to strs and vicev­er­sa all the time).

  • Easy in­­­cor­po­ra­­tion of oth­­er pro­­grams as func­­tion­s/meth­od­s/what­ev­er.

    That pret­­ty much is what makes it a shel­l. ls should be in­­dis­­t­in­guish­able from some­thing writ­ten us­ing the shell it­­self.

  • Pipes. This is a must. Unix has a bazil­lion tools meant to be used in com­­mand pipe­­lines. You can im­­ple­­ment a RDBMS us­ing that kind of thing (look for nosql). Lev­er­age that.

    But even here, on its strength, the shell is not per­fec­t. Why can't I eas­i­­ly pipe stderr and std­out to dif­fer­­ent pro­cess­es? Why can't I pipe the same thing to two pro­cess­es at the same time (yes, I know how to do it with a neat trick ;-)

  • Glob­bing. *.txt should give you a list of files. This is one of the ob­vi­ous things where sh is bro­ken. *.txt may be a string or a list, de­pend­ing on con­tex­t... and a list is just a se­ries of strings with blanks. That is one of the bazil­lion things that makes writ­ing shell scripts (at least good ones) hard:

    [ralsina@monty ralsina]\$ echo *out
    a.out
    [ralsina@monty ralsina]\$ echo *outa
    *outa
  • A list da­­ta type. No, writ­ing strings sep­a­rat­ed with spa­ces is not ok. Maybe a python-style dic­­tio­­nary as well?

  • Func­­tions (ob­vi­ous)

  • Li­braries (and ok, the shell source mech­a­nism seems good enough)

  • Stand­alone. It should­n't spawn sh for any rea­­son ;-)

What doesn't matter?

  • Per­­for­­mance. Ok, it mat­ters that a five-­lin­er does­n't take 50 min­utes un­­less it has to. But 1 sec­onds or two sec­ond­s? not that im­­por­­tan­t.

  • Ob­­ject ori­en­­ta­­tion. I don't see it be­ing too use­­ful. Shell scripts are old-­­fash­ioned :-)

  • Com­­pat­i­­bil­i­­ty to cur­rent shel­l­s. Come on. Why be like some­thing that suck­­s? ;-)

Now, the example

Let's con­sid­er a typ­i­cal piece of shell script and a re­write in a more rea­son­able syn­tax.

This is bash (no it does­n't work on any oth­er shel­l, I think):

DAEMONS=( syslog network cron )

# Start daemons
for daemon in "\${DAEMONS[@]}"; do
      if [ "\$daemon" = "\${daemon#!}" ]; then
              if [ "\$daemon" = "\${daemon#@}" ]; then
                      /etc/rc.d/\$daemon start
              else
                      stat_bkgd "Starting \${daemon:1}"
                      (/etc/rc.d/\${daemon:1} start) &>/dev/null &
              fi
      fi
done

And since DAE­MONS is some­thing the ad­min writes, this script lets you shoot in the foot in half a dozen ways, too.

How about this:

DAEMONS=["syslog","network","cron"]

# Start daemons
for daemon in DAEMONS {
      if ( daemon[0] != "!" ) {
              if ( daemon[0] == "@" ) {
                      stat_bkgd ("Starting "+daemon[1:])
                      /etc/rc.d/+daemon[1:] ("start") &> /dev/null &
              } else {
                      /etc/rc.d/+daemon ("start")
              }
      }
}

Of couse the syn­tax is some­thing I just made up as I was writ­ing, but is­n't it nicer al­ready?

Eating like a Python, for Python, and other stuff

I am now al­most re­cov­ered from the trip to San­ta Fe for the Jor­na­da Python and I have reached a few con­clus­sion­s.

  1. I do kin­­da miss my old city.

  2. It does take slight­­ly longer than 15 min­utes to show it ;-)

  3. This kind of events is cool

  4. I am old, and can no longer take a 6-hour bus ride and then go to work.

On more de­tail:

The city is much pret­ti­er than it was when I left 5 years ago. Lots of con­struc­tion go­ing on, ev­ery­thing is clean­er, nicer, and more or­ga­nized, it seem­s.

Man, I had for­got­ten how great you can eat there. And how cheap­ly. Re­mem­ber I men­tioned that fish-eat­ing place? Well, it's on­ly $22. That's pe­sos. So, it's about 7 dol­lars for all the de­li­cious fish you can eat, and all the cold beer you can drink.

Which in my case is quite a lot. Al­though I am get­ting slow on the beer, too.

The on­ly bad thing about it is that the guys that went on Sun­day got Pacú and we did­n't. Dammit!

Then there is the So­ciedad Ale­m­ana. The ugli­est place ev­er. The best pi­ca­da [1] ev­er. It's a club­house found­ed by a for­mer Graf Spee crew­man. If they eat like that on the ger­man navy, I would con­sid­er join­ing. And I get sea­sick.

Oh, and the lebanese restau­ran­t. I was for­get­ting that.

Of course all this eat­ing and im­bib­ing al­so meant I missed half the even­t, but the morn­ing con­fer­ences were in­tro­duc­to­ry, so I got the good bits any­way.

Spe­cial­ly: I now un­der­stand meta­class­es! and dec­o­ra­tors! Yipee!

We had a good time with Rosar­i­o, she got to know bet­ter some of my friend­s, spe­cial­ly Javier and César [a­ka Ned Flan­der­s] (and Ce­sar's fam­i­ly, Nor­ma, Flo­ren­cia and Ju­lian).

We took a ride over the costan­era (a river­walk), pep­pered with com­ments like this (all dates are wrong):

Here was the Piedras Blan­cas beach, un­til the flood of 87.

That's where the old train bridge was un­til the flood of 69, then there was a liftchair, un­til the flood of 82.

That sus­pen­sion bridge is not the orig­i­nal, which was washed off in 83 (and then stolen)

This piece of the costan­era is new, the old one was gone in 78

And so on. You see, this place is... kin­da flood­y. Ar­chi­tec­ture is not a per­ma­nent thing.

On yet an­oth­er an­gle, I am go­ing back to school next year. I don't in­tend to fin­ish my Maths de­gree, but will go for Sys­tem En­gi­neer­ing in­stead. We'll see what hap­pen­s.

1

We had the ger­man style pi­ca­da. That means plates of pota­to sal­ad, smoked ham, three dif­fer­ent sausages, lev­er­wurst, pick­les, three cheeses, and a sausage cazuela. The clas­sic San­ta Fe style pi­ca­da may in­clude any of those plus meat­ball­s, mi­lane­sa (schnitzel-­like thing), chip­s, olives, lupines (a kind of pick­led bean), small sand­wich­es, and a hun­dred oth­er things. All that in small pieces, ready to eat with fin­gers and/or tooth­pick­s. All salty. So you get ex­tra beer.

A silly entry

To­day's en­try has no pieces of neat python code, no ques­tion­s, no crit­ic of any­thing, no in­ter­est­ing link, no hint of any­thing I wrote/(­would/will)write, no fun­ny piece, no un­fun­ny piece, no noth­ing.

I am tired to­day.

So, have a nice day :-)

Python-v4l: neat!

Think­ing about Cher­ryTV and ways to turn it in­to a re­al ap­pli­ca­tion, I thought the worse piece of it was the re­liance on v4lctl, and how re­al­ly you just don't know if it works or not, and how you can't fine­tune, and what­ev­er, and run in­to Python-v4l.

It has re­mained ap­par­ent­ly un­touched by two years, but I man­aged to build it with one ed­it and to make it work by switch­ing a line to an al­ter­nate ver­sion (they are both there), and it's nice.

Here's the ex­am­ple TV view­ing ap­pli­ca­tion us­ing it:

#!/usr/bin/env python
# Sample TV viewing application for pyv4l >= 0.3 - by Michael Dove
#<pythondeveloper@optushome.com.au>
# 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 equiv­a­lent C ap­p... well... nice job here!


Contents © 2000-2020 Roberto Alsina