Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Tuesday, January 26, 2021

As a young programmer, I think it was probably around 2.4 or 2.2 that I started to use Python. Today it remains one of my favorite languages.

I remember thinking quite highly of the Zen of Python at the time. Much time as gone on since then, and to be frank, I think it even more beautiful and dead on balls accurate today than I did then. The older I get as a programmer the more accurately it reflects the reality.

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Wednesday, June 26, 2019

Solving the wrong problem?

Programming language Python's 'existential threat' is app distribution: Is this the answer?

I kind of can't help but wonder if this is really about solving the wrong problem.

In dealing with the developer side of things: pip and venv really aren't that bad compared to some of the squirrelly means of distributing software the world has known. But much beyond 'type pip install xxx and cross your fingers', I wouldn't really call it a user oriented system. It works well enough for Python developers but is not catered to Joe Average User or twelve year olds who just want to blow stuff up.

To make things ease on end users of course: you have to solve the actual problem. Linux has a good rule about not breaking userspace--but userspace doesn't care about you! Personally I think that is the real pickle.

Over in NT land it's pretty simple. You build some shit and the system ABI is probably the same across a bunch of Windows versions if you're not too crazy, and most of the baggage is the problem of your install creation process. Whether that's some fancy tool or some rules in your Makefile. It's impressive when you load up a video game that's old as hell and it just works, despite being almost old enough to buy a beer. It wasn't made to be efficient: it evolved to become stable. It grew up in a world where people shipped binaries and pushing changes to users was costly.

Now by the time you have an actual Linux desktop distribution: all bets are pretty much off. A decent one will usually maintain a viable ABI for a major release number but that doesn't mean everything will be compatible forever, nor does it mean the binary dependencies you require will remain in xyz package repo for the next fifty years. Some of this lands on distributions and how they deal with package management to squeeze binaries into nixie norms of hierarchy. Some of this also lands on developers, who may or may not know what an ABI is from a hole in the ground because they're used to recompiling to APIs and configuring ten thousand build time knobs and don't care that changing something impacts binary compatibility between their library and the works of others.

There are reasons why things like AppImage and Flatpak exist. Many of these I think owe to the source centric nature of unix systems. Different communities have different norms of sharing and reuse.

When I began learning unix systems, I chose a source centric flavour that would let me learn how things worked under the hood. The kind where you waited three and a half days because a new version of KDE or GNOME landed and many a dependency in the food chain needed to be rebuilt. The kind where you learned to diagnose linker problems and grumble knowing that changes to library X meant recompiling half your environment if you wanted to be sure your applications didn't combust quietly in a corner just waiting for the day you actually needed to launch them again, or curse at some major framework linking to some piddly library that triggered same.

In the end my times with that system were dominated by two things: stability and compile times. But I didn't chose that in order to have an easy one click and done system. I had chosen it because I wanted to learn how computers worked and develop the means of figuring out why the fuck programs broke. Today if you use that flavour of unix, you can pretty much live a purely binary world that wasn't so easy when I was a padawan.

By contrast an acquaintance of mine back then, ironically a Python programmer, had chosen a more widely known distribution that focused on having the latest binaries available without having to compile all the things. One that's still quite popular about ~15 years later. Let's just say the usability of binary focused distributions has improved with time despite the warts that is binary distribution in *nix land. Or to summarize it thusly:

When it came time for a major version upgrade: I spent a few days compiling before getting back to work. He spent a few days cursing and then reformatted, lol.

Friday, June 21, 2019

While lunch is rather late at least my experiment in making an RSS -> Diaspora bot is going well.

Friday, August 20, 2010

The STAMAN Project: Phase IV,

Having thought of tasks and storage formats, it's now time to figure out an implementation language, i.e. what programming langauge am I going to write the task manager in.

O.K. based on what we've got so far, it is easy to infer the following is worth having:
  • Portable between systems—a must for me ;)
  • Easy access to SQLite—usually trivial.
  • Better tools than gmtime().
That means this page is rather useful, for what languages can be ruled out. In my rĂ©pertoire this means Go (aww), Scheme, AWK, and shell languages can be skipped. Reason being the portability of Scheme bindings in general, and the others lacking sufficient portability (for my taste) at this time. That still leaves about 13 languages, lol. PHP, Java, Lua, JavaScript, and X86 assembly are easy for me to rule out. Reasons for that can all be easily guessed; at least if you remember how much I enjoy Suns Java tools. JS/Lua are great choices but I don't want to screw with the bindings and stuff.

I'm not very interested in compiling SQLite in C/C++ on Windows, or the CLI binding everywhere. So this effectively makes the choice Perl, Python, or Ruby. Out of those three, none is perfect either: perl doesn't come with the required database code, it just has the definitive interface for databases everybody mimics. Python and Ruby on the other hand, come with SQLite bindings—which many distributions separate out into separate packages. It's just a lose, lose situation when you think about dependencies, but it does beat writing your own everything for every program. Sometimes. Setup with these three dynamic languages would be easy though, in so far as we've gotten with the above.

Time handling is another issue. Perl has fairly minimalist handling of time built in, but on the upside, if you need it, it's probably three abreast on CPAN. Time::Format and the core Time::Piece module each come to mind. What isn't built into Perl, often comes with it or can be added to it. Ruby provides a simple but effective Time class, that makes for more natural code than you may expect. More complex operations will require Googling for a Ruby gem, or hand coding it on demand. Python on the other hand provides a comprehensive datetime module, and supporting time and calendar modules, all out of the box! I would say Python takes the lead here.

Rule one of getting work done: know how to leverage libraries.


In terms of programming languages, Perl, Ruby, and Python are generally equal enough for most tasks, so long as you don't shoot yourself in the foot. Some subtle differences that personally irk me:

  • Perls autovivification can be almost as much a miss-feature as it can be a convenience. You've just got to learn the damn language :-P.
  • Ruby functions are not first class objects! Some things can also be weird if you're not used to Ruby.
  • Python doesn't always stand up well to typos, especially if they involve indentation \o/.

Because of how many lines of code I've done in Python over the years, I am more familiar with it's set of "Irks" than Ruby's, like wise I know Sh, C, and Perl more intimately than other languages, so I really know their irks. For perl, it's mostly thin things that get in inconvenient when combing the warnings pragmata with the nature of perl syntax. They spiritually conflict at times. Under Ruby, I mostly find gripes that have a bigger place in programmer culture. My issues with Python generally have to do with trade-offs that I disagree with as a matter of my convenience, even if it usually results in a Good Thing overall. It comes from a C-oriented background meshed with a love for the Perl programming language.

This is a fact: you will always be irked by your programming language, if you use it enough. What can I say, nothing is perfect. Shoot!


For this particular application, there's some things worth noting also: language portability. If the machine doesn't run perl, it's not a real computer. Most systems you're likely to care about will run Ruby and Python, and there's probably a crusty old version of Python for those you don't (nor directly should). In contrast however, Perl is often a lower level of "Cross platform" behaviour than Ruby/Python. You'll find this highlighted well in the Camel book. One reason I use Python frequently, it always behaves as expected without so many subtle hiccups.


How much this pertains to the current matter, i.e. implementing STAMAN. Perl is the most universally available language, and I'm more prone to need such a feature than most people. A plus over Ruby is no crappy 1.8.x/1.9.x porting issues...! Of course however, I have a camel to ask about minor details, hehe. In my experience the Python 2k/3k thing is less issue than Ruby's for writing code yourself, more of an issue in leveraging existing code.


So I reckon, that means Perl or Ruby is best called for here. I exclude Python, because I just use the frick'n thing to often.

Thursday, April 22, 2010

My dumbest python moment ever....

In cleaning up tmk's cache related code for a fresh commit, I wrote an expand2str() method that encapsulates the issue of dealing with expand() returning a list of expansions, and a properly converted string being desired anyway.

Suddenly I noticed this backtrace:


Traceback (most recent call last):
  File "tmk.py", line 929, in 
    process_recipe(recipe)
  File "tmk.py", line 742, in process_recipe
    recipe.parse()
  File "tmk.py", line 276, in parse
    if not self.eval_pproc_directive(p):
AttributeError: Recipe instance has no attribute 'eval_pproc_directive'



Which is totally ridiculous, because eval_pproc_directive and parse are both methods of the same class. While the former is defined after the latter, by the time the instance (self) exists, the class is fully defined. Making a short test case, proved that the act of one in a billion hadn't changed Pythons rules about this stuff.

In poking around to see what changed introduced during this commit, may have popped the magic cork, I noticed removing the reference caused the same type of error, successively on methods defined after they were invoked.


Then I saw it!

I had accidentally indented the expand2str() method one short, there by making it a function rather then a class method, and there by doing like wise and making them nested methods inside expand2str().

Sometimes Python really irks the typoist in me!

Friday, October 31, 2008

This is so recursive, it hurts


# this is so recursive, it hurts
for topdir in args:
    for root, dirs, files in os.walk(topdir):
        for file in files:
            for regexp in patterns:
                if re.search(regexp, file):
                    file = os.path.join(root, file)
                    if verbose:
                        sys.stdout.write("file name: %s\t" % file)
                        p = os.stat(file)
                        a, m, t = (
                             time.strftime("%Y-%m-%dT%H:%M:%S",
                                        time.gmtime(p.st_atime)), 
                             time.strftime("%Y-%m-%dT%H:%M:%S", 
                                        time.gmtime(p.st_mtime)), 
                             time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime()), )
                        sys.stdout.write( "atime: %s\tmtime: %s\tnow: %s\n" %
                             (a,m,t))
                    else:
                        print file
What a huge, ugly, monster, I'm glad the finished code doesn't look like that lol.

Wednesday, September 24, 2008

Slithering around an aging question

Hmm, it seems if I can sort a suitable SQL-interface (beyond the standard issue sqlite3 module) that Python will become my primary language.


It seems, no matter how much I try to circumvent it, Python is the best choice all around :\ And I've tried to knock it down to size lool.


Pythons str and list classes, I actually quite like; although I don't care much for dict (Pythons associative array class), that might change come Python 3. Most of the stuff built into Python, I like using. The regular expression support, well what can I say... I don't like any stuck on OOP or procedural interfaces, after having used Perl. The =~, s//, [m]//, and related $symbolic_vars in Perl are just to useful!!!! But Pythons 're' module is good enough for stuff, I guess. Between the built in xml.* and the third-party lxml interface to libxml2, that routes pretty much a snap. I get along well with Pythons IPC offerings about as well as I do with posix's C offerings. The zlib, gzip, bz2, zipfile, and tarfile modules are enough for the compression/archive formats I may eventually need to operate on. For network related operations, Python provides a lot of stuff plus a familiar sockets interface; I don't have no problems with sockets programming (although I rarely get a chance to use it in C), I just don't have time to say, implement FTP! For GUI toolkits, basically offered is TKinter, GTK+, WxWidgets, and Qt. And it looks like GTK+ will probably be my new default kit... The epydoc program also seems to provide the style of documentation I'm used to (Javadoc-style) with good options hehe.


Not to mention the best parts of using Python as my standard language (I and II)

Tuesday, September 23, 2008

This is how I relax.... lol.

Having taken some time to analyze the mailcap and mime.types files, which map media types to handler programs and file extensions respectively. I've decided to implement something, uhh.... more "fun" out of it, for my own usage. I'll use mailcap and mime.types to setup a suitable mime/file associations to desire, and a mixture of m4 and environment varables to make it more useful hehe. I've also setup a small wrapper around Pythons mailcap and mimetypes modules, so I'm happy !


Since I need a handler that includes a web browser, rather then creating an if x is probably running ... script, to just use $BROWSER. But since, there is a shitload of apps that don't understand it, I've created quick python script to handle it. Thus, mailcap will execute this script, which will "figure it out". Once I realized how much I could use such a quickie, I added a little more abstraction to it; making it usable with other variables. And used getopt for a simple interface to it.

#!/usr/bin/env python

import sys, os, getopt

# default values for -e and -s options
envvar = "BROWSER"
envsep = ":"
# skip executing program 
noexec = False

# accepted options, usage statement, and manual page
shortopts = "hme:s:n"
longopts = [ 'help', 'man', 'environment=', 'separator=', 'no-exec' ]
def usage():
    print """
usage: %s [options] file ...

    Parse a field delimited list of programs, executing each in turn, until the
    specified application has opened the indicated file(s).

Options:

    -h,--help    display this useless message
    -e,--environment the environment variable to look up, default to BROWSER
    -s,--separator    the field separator for -e VAR, defaults to :
    -m,--man    view this manual page
    -n,--no-exec    do not execute any programs, useful if parsing $PATH

    --long-options may be abbreviated.

Exit Status: 

    The return status of the last executed program handler. If no program was
    executed, return with a non-zero exit status.

Caveats:

    A non-zero exit status is considered a successful execution.

    Programs found by parsing the environment variable, are passed onto the
    system shell UNMODIFIED. This is not secure, but it is flexible.
""" % sys.argv[0]
    sys.exit(1);


try:
    opts, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
except getopt.GetoptError, e:
    print(str(e))
    usage()

for opt, arg in opts:
    if opt in ('-h', '--help'):
        usage()
    elif opt in ('-m', '--man'):
        # XXX works on unix, dos, winnt, osx
        os.system("%s -h | $PAGER || more" % sys.argv[0])
        sys.exit(0)
    elif opt in ('-e', '--environment'):
        envvar = arg
    elif opt in ('-s', '--separator'):
        envsep = arg
    elif opt in ('-n', '--no-exec'):
        noexec=True
    else:
        assert False,"unhandled option: %s" % opt

# exec handlers until success, abort, or exit
try:
    browser = os.environ[envvar]
    apps = browser.split(envsep)
    for handler in apps:
        # just print it, don't execute it
        if noexec:
            print handler
            continue

        ret = os.system(handler)
        if not ret == 0:
            print("Bad handler -- %s" % (str(handler) % " ".join(args)))

except KeyError:
    print("No %s set!!!" % envvar)
    sys.exit(1)
except Exception, e:
    print("Un-handled exception! -- %s" % e.message)



One of the common questions of a language, is how to parse command line options? I've tried several interfaces in differing languages, but I know one thing... The getopt(3) routine in C on unix is awesome for short options. Give something more portable and with (easy) support for long options, and I'll have a big grin on my face >_>. But if I have to wade through 20 pages of documentation for a comparable OOP-Interface, I'll be snoring before I get to writing usage().

Monday, September 8, 2008

Of languages, libraries, and tools

I have been contemplating my standard language/library issue with care, although I've yet to finish most of the tests.... Courtesy of work, laziness, and to much work on the website lol.


So far, it seems to me that language wise my best thoughts:


Python, I don't really 'like' python but I can do a tremendous amount of work in it compared to other languages, time wise. And it's fairly easy to implement and test stuff -- worst thing I can say about it is it's interpreted and the regular expression support is done via a standard library module. Although jython (compile to byte code, but compares to a smaller version of an old CPython release) and ironpython (python for .net clr) should help the former, and the api for regex ain't that bad, but sucks compared to Perl lol (like most languages seem to, that don't steal Perls syntax or likewise make it a core element of the language syntax). Python also can handle interfacing with other languages well enough between the CPython, Jython, and IronPyhon implementations.


Java, great syntax and fairly logical. The byte code is portable enough between Sun JVMs and it even has the portable Swing GUI toolkit, although I'd probably end up using SWT or the WxWidgets bindings. The bad things about Java, although you can compile to native machine code, ya need to get the GNU Compiler for Java (GCJ) working first. Regular expressions are done via it's libraries rather then syntax, and. Well the only _nice_ way of saying it, most of the tools with the JDK eventually piss me off, but I like the language aside from that. The only major con is it is as OOP-centric as I've ever seen, and it's that way by design.


C++, lower level then any of the others and offering the best level of interface to C code of any of them around ;-). I personally prefer Java's syntax over that of C++ but it still gets the job done. It's just a question of how often you want to press Shift while typing... One of the best things, the STL is quite nice and well enough supported now to be worth using. Although, in my experience when working around C interfaces, the STLs value can go out the window, but maybe that's just how long I went before using the STL. One plus, unlike Java or Python, you get a more traditional pointer, not to mention a few interesting things in the std::namespace and boost libraries. Not sure what shape exceptions support is like under various system compilers, but I don't think that I've ever seen C++ code using exceptions outside of examples or perhaps the FAQ :\.


Useful points of interest:


WxWidgets for the GUI -- portable to target platforms of most interest and in all three of the above languages (and a few more too).

libxml2 for XML -- portable to target platforms, but seems to only have C++ and Pyhon bindings easily available, libxmlj (for java) I think would need compiling and I haven't tried that under FreeBSD or Windows yet.


Semi-Native Regular Expressions -- Boost libraries for C++, Pythons own regular expression module, and ditto for Java (not that I like them).


std::string, str, and String classes -- basic string handling in C++, Python, and Java. Boost and WxWidges also provides wxString.


MySQL bindings -- database operations; quickly available for C++, Python, and Java (JDBC based). Using SQLite in C++/Python is also easy enough but I'm a bit leerly of Java-related connections for SQLite3.



As to the other stuff that was on my list:

C++ and Python provide suitable IPC systems, never have looked at Java in that light. Most of the stuff I need, is basically provided by the C libraries under POSIX systems and Windos, Python has a suitable interface to it, so I'm happy hehe.


Python has good enough built in support for common compression and archive formats. Whatever can't be done via java.util.zip hopefully could be done via JZlib, I'm not familiar with anyhing ZLib under C++, but there is always the traditional interface ^_^.


I haven't considered the network side that much. Although I sometimes find it a bit lengthly, I don't really mind working with the C-style sockets library I've used here, using the windows sockets library shouldn't be to far off from the ones used on *BSD and GNU for my needs (aside from headers/linking). Python has support for a number of protocols (and pwns Ruby on documenting the classes for most protocols IMHO), Java well enough out of the box, and both Python and Java provide usable interface to TCP/UDP. WxWidgets also has a few things as well but more limited, that might be worth looking at, since I'd rather like to use a similar interface in each language, while still leaving code that can be read.


As to the ease of use and deployment, that is always a tough question. Under FreeBSD and Debian at least, they are all 'easy enough'. Windows of course, always has to be the pain in the ass. But for total portability this is an AoR where Python excels. When it comes to deploying stuff, it gets tricker. Windows lacks a package manager and you eventually have to draw a line between what you're stuck bundling and what your stuck making a dependency. One of these days I need to look at py2exe and see how it would work out for what I've a mind to setup.



Big pluses:

Qt4 for C++ and (generally) Python is great and works on all my systems, QtJambi I've never tried on FreeBSD yet, but would be interesting if it works. The only thing I hate about Qt, the commercial license costs an arm and a leg :-(, but most of my needs fit within the (free) Open Source Editions license terms with a smile.


WxWidgets seems to be less painful then GTK+ under Windows while still supporting many languages, although GTK+ would probably be more fun to learn in my case. It also has nifty things, including string/regex classes.


MySQL and SQLite are generally portable and have bindings to other languages quick & easy enough. I've never used SQLite on a project, since I run MySQL on one of my own systems to service all my SQL-related needs ;-)



When it is all said and done, I really think Pyhon is the best choice... I dunno why or how, but it seems that way! Hmm, to re-dive into using Python for most tasks, or to get C++ crazy... Or live with using both side by side? For my own sake, I think I should sake fuck Java! But it is a great language in it's own right.


Oh well, maybe in a few months I'll have figured out which path to take. I can always make use of other languages and tools, but I very much need to find a "primary" set to work with!

think:
    switch(choice) {
        case PYTHON_ONLY:
            // Python becomes my primary language
            break;
        case CPP_ONLY:
            // C++ becomes my primary language
            break;
        case PYTHON_AND_CPP:
            // use both side by side
            break;
        default:
            goto think;
    }

Wednesday, August 27, 2008

Todo: Toolkit and Library madness

Examine for portability the following toolkits under these OSes: Windows NT, Mac OSX*, Unix-like.

*I sadly don't have a Mac, although I would really love one. So a OSX binary of some form will have to pass.



GTK+ -- C, C++, Perl, Python, Ruby, PHP, C#.NET (Java bindings also avail but seem to be gnome-centric)

Qt4 -- C++, Perl, Python, Ruby, Java (C#.NET and PHP bindings seem to be questionable and only C++/Python and possibly Java bindings can be depended on).

WxWidgets -- C++, Perl, Python, Ruby, Java, C#.NET

Swing and SWT would be considered if they were available under more languages !!!


Evaluate portable standard/add-on libraries to each language for the following capabilities:


String handling (they all do well in the language standard)
Regular Expressions (Only Perl and Ruby get this great imho)
XML Processing
Network programming -- both sockets based API and protocol support (IMAP, POP, HTTP/S, FTP)
Database handling -- must support MySQL, SQLite, and some form of flat file.
Basic compression and archive format support (e.g. tar; zip; gz; bz2; lzma)\
Inter-Process Communication (IPC) methods and related process control (e.g. fork(), exec(), signal(), kill() type routine-families).
Ease of use and deployment



Goals:

Build up a standard frame work of toolkits/libraries/etc that are portable across both my general operating environment and the various languages I use

Attempt to standardize myself on few languages rather then rubber banding between various programming languages + sh/awk/sed/friends

Ensure full development environments are available to me under FreeBSD 7 and Windows NT 5.1 (e.g. I can code from either machine and not change tools)

At least one language for scripting/prototyping and one for more efficient execution when implemented in that language (e.g. 1 interpreted + 1 compiled)




and try to stay sane along the way without writing a few libraries in the process >_>

Sunday, August 24, 2008

Something that has been on my mind of late

DRAFT POST


I very much need to start standardizing myself on a smaller set of tools. Maybe tools is not the best choice of ord, o much as it is a question of languages and libraries. It's actually kind of ironic, I really would like to learn several more languages (Ada, Fortran, C#, Erlang, and I never did wrap my head around Scheme).


C++

Pro's:

can do low level stuff

can interface well with C code and libraries

Qt is natively C++ and supports everything I need it to run on (in Qt4 OSE hehe)

Fairly portable and standardized (at least much of the 1998 standard...) with several compilers available.

Mainly toolkits and frame works available, both native and from C.


Widely used and my first language


Con's:

having to dig into lower level interfaces is very error prone when doing it with a headache the size of California.


Often not my first choice for building a prototype *quickly* but good for final implementation.


Java

Pro's:

Inheritable portable between JVMs of the same implementation (e.g. Sun JVM for Win and Sun VM for Mac can run same code).


Simpler OOP syntax then C++, imho

The Swing GUI toolkit is fairly portable and SWT sufficiently supports the platforms I want to avoid skipping.

I like the way it handles exceptions, and usually like checked exceptions -- when a class is designed appropriately.


It's well defined if not perfectly standardized and compliant implementations are fairly common enough (Sun's)

Wildly used and my third language.

Well documented (if a bit boring)


Con's:


Everything is OOP....

I prefer native code to waiting on java to load

Requires a suitable runtime


Conventions expected by some tools can occasionally be irksome (to me)


C# (C Sharp)

Pro's:

It's not Java

It's similar to Java/C++

Core elements are standardized

Less resistance to shooting oneself in the foot / doing stupid things then Java but not as much as C++.


Gtk#, the binding of GTK+ to C# is available on the platforms I care about.

Con's:

Most C# applications are probably tied to Microsoft Windows implementation via .NET or through Gnome related interfaces

Requires a runtime (e.g. .NET, Mono, or Dot GNU)

Requires just enough learning of it's differences from Java, for me to use it.


PHP5

Pro's:


Portable and interpreted


Widely used across the WWW for server side scripting.


GTK+ bindings to PHP available and portable'ish


Simple language and member of the CBF.


The OOP increasingly resembles Java syntax and is just "enough" syntax to be useful without cramming.

Well documented

Con's:

Local php.ini files can cause problems (how much can you assume?)

Needs a run time (php) of the right version (5)

php4/php5 is less common off web servers or developers systems



Python

Pro's:


Great for writing prototypes

Several toolkits available that are fairly portable

Easy to work with and quit portable (and issues of portability well noted in the docs)

Large standard library

Implementations for the Java Virtual Machine and Microsoft .NET framework are available (if not as current as CPython) as well as the standard (C)Python implementation.

Con's:

Requires a run time

I *hate* it's handling of regular expressions after being so used to Perl...

It's slower then native code

Interfacing with C /or C++ code can, uhh... Get interesting, from a portability perspective.

The program is the source


Ruby

Pro's:

Handy pure OOP language

Great handling of regular expressions within the language itself, as opposed through importing an object oriented interface (i.e. as in Python/Java/C++)

Usually very "comfortable" to write.

Large standard library

Con's:

It requires a run time and alternative compilers (e.g. xruby, ironpython) may be lacking in reliability or cause some features to be unavailable

The program is the source

Wishing Ruby 2 would come sooner....

Documentation can be irksome at times

It's slower then native code and even slower then Python (Ruby 1.8.x)

Sunday, June 15, 2008

Does Python or PyQt3 have a pox on C++?

This is illogical as I've seen Python get.

Terry@dixie$ cd code/C++/src/qsm                                           0:11
Terry@dixie$ python                                                        0:11
Python 2.5.2 (r252:60911, Apr 17 2008, 16:34:02) 
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> from qt import *
>>> QDialog
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'QDialog' is not defined
>>> 
Terry@dixie$ cd $HOME                                                      0:11
Terry@dixie$ python                                                        0:11
Python 2.5.2 (r252:60911, Apr 17 2008, 16:34:02) 
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> from qt import *
>>> QDialog
<class 'qt.QDialog'>
>>> 


Maybe there is a reason for this and I've just got to much of a headache from today to notice it, but WTF man? lol. It's almost as if Python has a pox on running a script in that directory :\




I wanted to test an idea for a dialog quickly, so I started a new python script. Only to have NameError's whenever trying to reference a member of the qt module. So i copied over one of the py-qt3 example programs that came pre-installed and tried that, same barfing results.

Then I tried interactively with python, no go -- changed directories to home and tried both, and they fucking work !!!!


I don't know whether I should laugh out loud or start hex editing maliciously lol.

Thursday, April 3, 2008

Well, I have a todo list stored away on Neo Ports Manager and one of the things on my todo was to remove the dependency on the psearch program, namely because it would be faster to update our display as we find stuff in ports rather then parsing the output.


I think I might make another page in the settings to allow one to choose what fields to search in and possibly which to display as details. I plan on embedding the code to search ports right in NPM, but if it doesn't clog things up I don't see why not to allow the ability to use an external program. The best reason being if the index file ever changes or is ax'ed and I get hit by a bus, no one has to learn Python to fix NPM lol.


A couple months ago I sat down and started trying to figure out the format of the index file in ports, it was pretty easy and I wrote a small script to search it and print out all the cells of information in each entry of the index that had a matching package-version in it.


This is a quick test script I wrote tonight that searchs for a port and displays a short info on it, being a test I wrote the port to look for in the file test rather then passing sys.argv over to save time. I plan to adopt NPM to using a variation of this for searching ports now.






     1: #!/usr/bin/env python
     2: 
     3: # This is as much of the format of /usr/ports/INDEX-* file as I have
     4: # been able to reverse engineer by looking at it and a few other things
     5: # that didn't come with a nice fat manual page: the source is the documentation!
     6: #
     7: # Each program is listed on one line with each field separated with the pipe
     8: # symbol (|), list values are delimited by a space.
     9: #
    10: # pkg-ver|                   -> as listed in pkg_info
    11: # location in ports|         -> /usr/ports/editors/vim
    12: # install prefix|            -> /usr/local
    13: # short descr|               ->
    14: # path to pkg-descr|         -> /usr/ports/editors/vim/pkg-decsr
    15: # maintainer e-mail|         -> who@foo.com
    16: # listed in categories|      -> list of cat, e.g. cat1 cat2
    17: # dependencies to build|     -> list of pkg-ver required to build this port
    18: # dependencies at run time|  -> list of pkg-ver required to run this program
    19: # website|                   -> the programs website
    20: # |                          -> unknown
    21: # |                          -> unknown
    22: # XXX: the unknowns may relate to internal port opts, e..g use zip, etc
    23: ####
    24: 
    25: 
    26: import re, os.path
    27: 
    28: INDEX="/usr/ports/INDEX-6"
    29: 
    30: # find keys 1,2,4 in index row via regex
    31: def search(pattern):
    32:     idx = open(INDEX)
    33:     for line in idx:
    34:         keys = line.split('|')
    35:         k = (keys[0],os.path.split(keys[1])[1], keys[3])
    36:         for each in k:
    37:             if re.search(pattern, each):
    38:                 print 'found'
    39:                 mypp(keys)
    40:     idx.close()
    41: 
    42: def mypp(table):
    43:     print "PORT INFORMATION FOR: %s" % table[0]
    44:     print 'location: %s' % table[1][11:]
    45:     print 'descr: %s' % table[3]
    46:     print 'category: %s' % table[6]
    47:     print 'website: %s' % table[9]
    48: 
    49: 
    50: if __name__ == "__main__":
    51:     search("linux-flock")
    52: 
    53: 



Sunday, February 17, 2008

Beware of Pythons

One sad side effect of using Python so much the past few months..

I actually had to invoke GDB's 'help' command when debugging some C code tonight :\


I know several languages but I tend to do things in "the language of the moment", if I'm working on some thing in C, most of what I do on the side will usually end up in C. Like wise if its a project in Ruby, ruby scripts start filling up lol.


Maybe my brain could use an extra 256K of memory?

Friday, January 25, 2008

Proof of Concept: Randomize a list

Well, the idea was essentially that RvS allows up to 30~32 maps or so all stored as a pair of assicated arrays loaded from the servers configuration file. One array that holds the game types (e.g. tango hunt, hostage rescue, misson et. al.) and the other the actual maps to load, i.e. GameType[0]=first maps gametype and Maps[0]=first map to load.


I took a moment the other day (before my gfx card went fuzzy) to write a small program that would generate a new configuration file with a maplist specified from another file, the prototype works fine but I didn't know how I could archive my real goal: randomly populate the maplist from that file.


Here is a proof-of-concept algorithm that takes a list of items and returns a new list containing the same values but sorted into a 'random' order.


#!/usr/bin/env python

import random

def unsort(list, index):
    "return a copy of list reordered randomly"

    new_list = []
    table = []

    while len(new_list) != index:
        r = random.randint(0, index)
        try:
            if r not in table:
                table.append(r)
                new_list.append(list[r])
            else:
                continue
        except IndexError:
            pass
    return new_list

if __name__ == "__main__":
    li = [1,2,3,4,5]
    print unsort(li, len(li))



This took me about 10 minutes of thinking at work today and about 12 or 14 hours later I've made a test script in Python since that is the language I've been using for stuff latly. Basically the problem is the only way to randomly map items from one list into another is if you access elements in the list at random. But if you access a list at a random index and push it into a new list you can get duplicates. So a table (list) is used to store random numbers we have already generated. If the current number is not referenced in the table we can assume that we have not copied the element at that index in the list into the new list, if it does exist we need to try again. One bad thing is the algorithm is designed to run until completion, which can take an arbitrary amount of time to 'unsort' any given set. In theory, it could loop forever! However it would be trivial to modify it to abort the randomization process after a given time frame (such as >N iterations or seconds, which ever comes first) and just append remaining elements onto the end of the new list.

Here is a few test runs:


Terry@Dixie$ ./unsort.py
[3, 5, 4, 1, 2]
Terry@Dixie$ ./unsort.py
[3, 5, 2, 1, 4]
Terry@Dixie$ ./unsort.py
[4, 1, 2, 3, 5]
Terry@Dixie$ ./unsort.py
[5, 4, 1, 2, 3]
Terry@Dixie$ ./unsort.py
[5, 2, 4, 1, 3]
Terry@Dixie$ ./unsort.py
[3, 2, 1, 4, 5]
Terry@Dixie$ ./unsort.py
[4, 5, 3, 2, 1]
Terry@Dixie$



Odds are the PRNG is being seeded with the system time by default or making use of /dev/random on my FreeBSD laptop and that is good enough for me. And these results are random enough for me because I dunno how to write first class pseudo random number generators hehe.

Wednesday, December 26, 2007

snoring through logging

been working on a simple logging module for npm, so far I've set it up to handle 3 different outputs, the usual STDERR for big problems, a regular log file for every thing but debugging, and a developers log file for use during debugging.


stderr
CRITICAL: critical message
ERROR: error message
WARNING: warning message
run log
2007-12-27 07:27:45,156: CRITICAL -:- critical message
2007-12-27 07:27:45,157: ERROR -:- error message
2007-12-27 07:27:45,157: WARNING -:- warning message
2007-12-27 07:27:45,158: INFO -:- info message
dev log
2007-12-27 07:27:45,156 root CRITICAL: logger.logger.py.73
         critical message
2007-12-27 07:27:45,157 root ERROR: logger.logger.py.74
         error message
2007-12-27 07:27:45,157 root WARNING: logger.logger.py.75
         warning message
2007-12-27 07:27:45,158 root INFO: logger.logger.py.76
         info message
2007-12-27 07:27:45,159 root DEBUG: logger.logger.py.77
         debug message

The formats are just a matter of what I find easy on the eyes, think the middle one could stand with a shorter date format.

I might ditch the idea of a second log file and just follow my original idea of being able to specify the level of logging to use. It'd also be less work then



Either way yee slice it, I need some freaking sleep... because I can't think no more.

:wq!

Sunday, December 16, 2007

A short look

Well, almost missed my narrow window of code time... Was passed out on the couch with a full stomach before bed until nearly 0100 xD


Between My mom, my sister, the bird, and my nephew (a louder bird)... And helping with baking there is really not much I can do during the day.. Any attempt at even thinking about seriously trying to read or write goes out the window and in comes a headache. So I have to work at night, when every one else is alseep... Until I crash or the clock reaches a point where I need to go to sleep in order to be @ work on time.


I completed the mock up of a simple dialog for simulating make config. And I've almost finished a working prototype for the module but I don't have time to handle writing the slots and associated code to deal with the check boxes right now. And I need to get that done and tested before I can incorporate the prototype unto the module it belongs.

I posted a screen shot of the mock up awhile back. I've fixed the display a bit (the leading variable name from the makefile is removed). And added an ok and cancel button with the beginnings of a more key-board friendly behavior when it comes to using the keys instead of the rat to use it hehe. I've also set the caption on the dialog to contain the ports name as category/program.


In doing this, I figured the most simple way was to just muck around with a string of our target (e.g. /usr/ports/net/samba3 and /usr/ports/www/links/ in my tests). Although now that I think of it, the same routine I wrote to get a list of options to create check boxes for. Could be used to look up the category and portname variables from the makefile instead because it's not tied to looking up any specific variable. -- TODO: compare both methods for speed
after the prototype is ready to be moved to alpha group.


In trying to figure out how to get the desired result from a string version of our working path, I remembered that most languages offer some way to obtain the basename of a file or directory and set to look for it in Pythons os module. But doing that would mean we'd have to cut off the trailing slash and refeed the path to the library routine then join them into a new thing. Not exactly my idea of fun when writing a quick helper subroutine. I was very happy that help(os.path.split) revealed a method that takes care of most of that legwork itself.

Python also has some thing called list compression and which allows the mapping of the contents from one list into another based on given criteria. I've generally avoided list compressions out of disfavor for some of the (large) examples I've seen before. But for this, I actually found it yielded both quick to write and easy to understand code.

p = name # '/usr/ports/category/program' for example
prog = os.path.split(p)
cat = os.path.split(prog[0])

path = ["%s/%s" % (c,p) for c,p in zip(cat, prog) if c and p]
return path.pop()

The above snippet splits name into two lists of two elements, each a string. Basically the 2nd line returns a list of ['/usr/ports/category', 'program']. So obviously line 3 likewise splits /usr/ports/category into a list of two elements, the last of which is category. I really love how os.path.split() speeds up reading this, it takes only a glance to read it without having to double check it.


The 5th line maps any elements of the two lists (cat and prog) into a single a list of strings, i.e. some thing like path => [ '/usr/ports/category', 'category/program' ]. The test for each element being true could be ommited in this case but I wanted to show the possibility.

Since path is a list and we want to display a string (without using str() on the result!), we just pop() the last element off path, which is exactly the element we want 'category/program'


mm, now for some sleep... It's after 5am here and I'm exhausted.

Sunday, December 2, 2007

Enter the Dragon

Well, so for work goes well for day one.

I've spent most of the day working on the configuration system, at this point it would be a lot easier to have a configuration file, so I set about to work with Pythons SafeConfigParser class and the format of the config file and options, e.t.c. There is still more to do but it is a great start, especially considering that I am not entirely comfortable with OOP under Python

I'd say greater then half the code for installing and updating the ports tree is done enough for further testing, the only issue right now is the reaction to errors sup'ing or portsnaping.

I am some what tempted to try and have a wrapper of sorts that will abstact the issue of using QT or KDE specifics but I don't think there would be any point. I need to dig deeper into the PyQT/PyKDE, QT, and KDE documentation soon so I can work more gui_error.py.

widets ? qt : kde;

It would be nice to use as many elements of the KDE bindings as possible, so it fits better with systems running KDE, yet it would also be nice to keep to the QT bindings more strongly so it is less tied to KDE.. In the end it will probably be which ever I'm more comfortable with.

My primary goals in the coming days is to finish the options and errors modules while I start work on the 'searchlet', which should handle searching through ports. Until a concreate mock-up can be made of the entire main window, I think I should keep the search stuff as far away from the rest of the program as I can.


Work on the searchlet as I call it, shouldn't be to hard to keep self-contained since I prefer to work on smaller pieces and properly prototype things when I can, I'm not a real fan of monolithic masses =\


Basically 7 tenths of that battle will be wrapping my head around working with the KListView and QListView widgets. Once I've figured that out, it'll be simple enough (I hope) to figureout how to make it work with displaying a search through ports. It's just I need to get a grip on the ListView widgets before I can do that lol.


Either way, I think I have done enough for one day... 0700 Zulu Time and it would probably be nice to have a little sleep before work tomorrow 0.o


A little horsing around before bed, not pretty but considering I don't know QT from a hole int he ground... And I'm doing this with C++ documentation for Python, I think it's a nice 'Hmm, how do you make a QListView object?" test:

#!/usr/bin/env python
# Neo Ports Manager (NPM) -- refer to the LICENSE file for terms and conditions

"""

"""
import sys, os
from qt import *


def main( argc, argv ):
    a=QApplication( argv )
    listViews=QListView()
    listViews.resize(640,480)
    listViews.setCaption("Qt Example - Listview") # Sets window title
    # Add some columns to the list view
    listViews.addColumn('Qualified name') 
    listViews.addColumn('Namespace')
    # element is how to create a new list view item for display
    element = QListViewItem(listViews, 'qName', 'namespaceURI') 
    # Now lets populate an array of items into view
    els=[ [listViews, 'dir1', 'descr1'], [listViews, 'dir2', 'descr2'],
          [listViews, 'dir3', 'descr3'] ]
    for j in els:
        QListViewItem(j[0], j[1], j[2])
    # And sort it descending by col 1
    listViews.setSorting( 1, False )


    a.setMainWidget(listViews)

    # draw & exec
    listViews.show()
    a.exec_loop()


if __name__ == "__main__":
    main(len(sys.argv), sys.argv)

I don't like that QListViewItem(j[0], j[1], j[2]) line but I was trying to translate from the C++,

for ( int i = 0 ; i < attributes.length(); i++ ) {
    new QListViewItem( element, attributes.qName(i), attributes.uri(i) );
}

And I've yet to figure out how to better cook this up, still reading the docs here...

Saturday, December 1, 2007

backlog

This one made my day :-)

[15:11] [SAS]_LCpl_DUKE: Did you know: The Navy takes now only not-swimmers.
[15:11] [SAS]_RSM_Spidey01: ?
[15:11] [SAS]_LCpl_DUKE: Yeah, they defend the war-ships longer...
[15:11] [SAS]_RSM_Spidey01: LOL
[15:12] [SAS]_LCpl_DUKE: the newest joke i got 5 minutes ago... ;-)

I've been brushing up on Python for a little projectI've got in mind, so I've been cramming like a student at finals week. Python is a nice language but one I never put to use when I originally started learning it.

The thing I love the most about Python, is the doc strings, it's such a great idea if you ask me.

--- def test(params):
...     """ Simple test
...
...         More detailed info about it"""
...
...     print params
...
--- test.__doc__
' Simple test\n\t\n\t    More detailed info about it'

A poor example yes, but in actual usage the doc strings can be very useful. I also like it because it can be used to move inline-documentation (some times aka comments) into the body of the function, rather then being above it. And they are accessible at runtime with the __doc__ special method.

One thing I do wish Ruby had, is Doc Strings for methods, b/c then in IRB I could do a simple obj.methods.sort and follow up with checking a methods docstring rather then an intermixing of playful testing in IRB with looking it up in TFM.

With Python, it's quite easy to go to interactive mode and use dir(obj) to get the methods an object responds to and any available __doc__ special methods to learn more about it, before we go RTFM hehe.