Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre programming (publicaciones antiguas, página 11)

FaxWeb is done

FaxWe­b, a web fron­tend for mget­ty+send­fax is fin­ished. It work­s. It's prob­a­bly close to bugfree ;-)

The miss­ing piece is a nicer reim­ple­men­ta­tion of re­spond (and this one will be cross-­plat­for­m, too) us­ing PyQt, which is 50% done.

I am on­ly miss­ing how to im­ple­ment por­ta­ble systray icon­s. On Mac they make no sense, on Lin­ux I have it work­ing, on Win­dows I have no idea.

Here's the sim­ple in­ter­face for faxwe­b:

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 lit­tle AJAXy "the page does­n't reload" niceties cour­tesy of MochiK­it!

Al­so from MochiK­it, the nicer, round­ed look&feel. Com­pare to this old­er, ugli­er one:

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

I know the new one is not good, ei­ther, but I have de­cid­ed that since I can't aim for awe­some, I should aim for ad­e­quate, and set­tle for bor­ing and harm­less.

Of course, if any CSS/X­HTML gu­ru vol­un­teers for a makeover, I'd be very hap­py, since I use the same CSS ev­ery­where (even on parts of this blog ;-).

All in al­l, a plea­sure to write this thing, thanks to Cher­ryPy!

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

I have refac­tored IUP/Qt in­to a love­ly ob­ject hi­er­ar­chy. And I now re­mem­ber why I dis­like C++.

Here's the ba­sic prob­lem (code may be wrong, I don´t have the bro­ken ver­sions any­more):

I have a base class IOb­jec­t, that has stub set­ter­s/get­ters for all the IUP at­tributes.

For each kind of wid­get, I cre­ate a class that in­her­its from IOb­ject and the match­ing Qt wid­get (ex­am­ple: QDi­alog).

These have to be hooked in­to an Ihan­dle struc­ture through the use of a void * (re­mem­ber, that's C, I have that too ;-)

Now, this was my first naive ap­proach:

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

That com­piles ok. How­ev­er, when you try to call a d mem­ber lat­er (and I know I am us­ing old C cast­s... they had worked for me un­til to­day!) ...

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

Blam­mo, seg­fault. Why? Be­cause in one of the as­sign­ments to/from void *, the point­er for some rea­son starts to point else­where.

Here´s what Glip­tic at #C++ sug­gest­ed, 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");

Is­n't this just ridicu­lous­ly weird for any­one com­ing from any oth­er lan­guage?

Or am I miss­ing some­thing com­plete­ly?

But the good news is, it works ok, and the Qt back­end now has a de­cent struc­ture to hack on.

The missing language

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

I re­al­ly dis­like C. But I have not been able to find a lan­guage to re­place it with, ex­cept C++, and that's not much of an im­prove­ment for what I did.

Maybe some­one can read this and help me. I don't mind learn­ing a new lan­guage. Re­al­ly, it's no prob­lem.

The goal is writ­ing small pro­grams (in the hun­dreds of lines re­gion), which have the fol­low­ing re­quire­ments:

  1. The pro­­gram MUST be cor­rec­t. Can nev­er seg­­fault or crash in some oth­­er way.

Since the code is short, I think I have man­aged, us­ing bstr­lib, to get this, af­ter quite a bit of pain, by au­dit­ing and unit-test­ing. But I am not sure, and I will nev­er be.

It would be awe­some if the lan­guage could be garbage-­col­lect­ed for this rea­son.

  1. It MUST have a de­­cent string han­dling.

The pro­grams han­dle mail. So, it's strings ga­lore.

  1. It MUST have very low over­­head. The pro­­grams should run and end quick­­­ly. Very quick­­­ly, be­­cause peo­­ple may be wait­­ing for them to end.

  2. It MUST be a rea­­son­ably sim­­ple lan­guage. I am not a great pro­­gram­mer, and these tools will be hacked at by peo­­ple with lim­it­ed pro­­gram­ming skills (sysad­mins like me!)

  3. Triv­ial ac­cess to C li­braries.

So, let's see.

C: gives 3, 4 (in a fash­ion), and 5

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

D: It seems to give me all of the­se, along with a C-­like syn­tax... but I can't get it to work yet (cor­rec­tion, I got dmd to work, so it's look­ing good for D!).

So, any tak­er­s?

BPython Lives!!!

In Jan­uary, I sug­gest­ed it would be triv­ial to write a pre­proces­sor that would ac­cept a ver­sion of python which de­lim­it­ed blocks with braces in­stead of in­den­ta­tion.

Ok, al­most, I sug­gest­ed #{ and #} as de­lim­iter­s.

Well, I had a few min­utes free to­day, and here it is, a func­tion­al BPython->Python com­pil­er, so to speak.

Here's the kind of im­put it takes (no­tice how it's not in­dent­ed at al­l:

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 pro­duces this (I am not hap­py with the in­dent­ing of the com­ments, 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 le­gal Python and a le­gal BPython pro­gram ;-)

It has some prob­lem­s, like not work­ing when you use a line like this:

#{ x=1

But hey, it is python with braces.

Here's the code. I pre­dict­ed 30 lines. It's 34. And it's 99% a ripoff of Ka Ping Yee's re­gur­gi­tate.py which you can find all around the we­b.

#!/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 dis­like python be­cause of the lack of braces and the sig­nif­i­cant whites­pace:

BPython has no sig­nif­i­cant whites­pace, and braces are manda­to­ry.

En­joy cod­ing!

Silly idea to make Python popular

I have an idea that can kill the most fre­quent com­plain about python.

BPython.

BPython is a sim­ple wrap­per around py­h­ton which pro­cess­es a .bpy file, pro­duces a .py file, then com­piles it in­to a .py­c.

What does it do? It us­es braces to con­trol flow.

Since braces are ac­tu­al python syn­tax, you will have to use #{ and #}

As an added bonus, if you are care­ful, a bpython pro­gram will al­so be a valid python pro­gram.

Of course it has is­sues (like mod­ule load­ing) but those can be worked around.

The im­ple­men­ta­tion should not be more than 30 lines of python. Or bpython ;-)


Contents © 2000-2024 Roberto Alsina