Dev-Picayune

picayune: of little value or importance

An Odd Monday Calendar Bit of Nonsense

(now updated with some pointless Python code)

This is perfect for this little blog concerned with trivial and small things. I noticed that my Peanuts calendar on my desk is essentially a reproduction of the 1990 calendar. Obviously, they all have to be reproductions because Charles Schulz died in 2000. So looking more closely, I realized they’d chosen 1990 primarily because the dates and days of 1990 match 2007. So a quick hack with the ‘cal’ program under linux and I was off and searching for what will most likely be next year’s calendar. Since 2008 is a leap year and obviously 1991 is not, I knew that wasn’t going to work.

First I generated target calendar with:

cal 2008 > cal2008.txt

Then, I just manually (although I could have written a script) looped through a few known leap years and found that 1980 seems to match perfectly as well.

cal 1980|diff - cal2008.txt

Obviously, what we’re looking for is a diff of only the first line, the year. Side note: the selection of 1952 (also a match), would seem to be fairly unlikely.

For 2009, there are a bunch of choices including: 1953, 1959, 1970, 1981, 1987 and 1998.

Why am I posted this? I don’t know other than it was fun to use ‘cal’ and ‘diff’ to anticipate which Peanuts calendar would be next.

UPDATE

I couldn’t resist doing a Python solution to this little problem. I know this isn’t as efficient as someone else could make it, but it was entertaining for me to do it. It took about 5 or 6 minutes to write and ran correctly the first time (matching my previous results):

import sys 
import datetime
def matchCals(inputYear,minYear,maxYear):
    sDayOfWeek = datetime.date(inputYear,1,1).weekday()
    eDayOfWeek = datetime.date(inputYear,12,31).weekday()
    for testYear in range(minYear,maxYear+1):
        if (sDayOfWeek == datetime.date(testYear,1,1).weekday() and eDayOfWeek == datetime.date(testYear,12,31).weekday()):
            print "Match Found... %s = %s" % (str(testYear) , str(inputYear))
 
if __name__ == "__main__":
    matchCals(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))

Here I just check the day of the week on the first day of the year, and the last day of the year. If both of those fall on the same day, I assume the calendars for those years are the same. And since we’re dealing with a limited set of dates (valid complete Peanuts calendars running roughly 1951 to 1999, it handles a min and max year for input as well. So to run it for 2008, you just type in:

python ./caltest.py 2008 1951 1999

Of course, there is no error checking… so if you enter a string or an invalid year… that’s your own problem. I just wanted to see how quick I could do it. Obviously, I’ve waisted more of my time… and more of your time.

3 comments

Another Benefit of Multiple Python Web Frameworks

Brandon and I were exchanging emails the other day about the state of Python IDE’s and specifically about IDE support for GUI’s. My thought was that while nearly every distribution of Python has Tkinter with it, it’s just so impotent that despite being included it’s not really the standard GUI library for Python. Whether it’s wxPython, or PyGTK or something else, there’s plenty of debate on GUI frameworks and Python. That has certainly hurt the Python community a little if what you’re looking for a great editor IDE combined with a great GUI layout tool.

So what does this have to do with web frameworks? I’d say that unlike the GUI thing, we’re probably better off in a sense because Python retains it’s own identity. Unlike Ruby, where one can barely think or mention the name Ruby without also saying “Rails”. It’s like saying Marco without saying Polo. Ruby has (in my opinion) lost a fair amount of identity because of Rails. Certainly, there are plenty of projects in the Ruby community that by their nature will start to reverse that (one that immediately comes to mind is IronRuby). But just imagine for a moment if Python was just known for one web framework only. What if it was “Python turning TurboGears” or “Python on Pylons” or “Twisted Python (aka Python in a Knot)” or even “Python was his Django”. Python would lose some of its identity. So, for those who like to revel in the diversity of web solutions for Python, enjoy! And for those who wish the community would just pick one framework, they can just go to Zope.

No comments

Python, ODBC and Linux

If you’re using Linux at all and need ODBC access to data sources, you’ve basically got two choices for Python library access, mxODBC and pyodbc. And really, until recently, pyodbc wasn’t really strongly considered a Linux option. In fact, even today, it’s not very Linux friendly to get installed (or at least I didn’t think it was).

I was needing to connect to our IBM iSeries database (AS/400 for most of us who aren’t newbies) from a Linux box. I managed to download and eventually install the IBM Access Client under Ubuntu and I had configured unixODBC stuff to the point that I felt I had a valid DSN setup. It was time to try to connect from Python. Since I work for a non-profit organization, I knew that eGenix had always treated non-profits differently and allowed the mxODBC library to be used for free. But after downloading and installing the latest version of the mxODBC stuff, it was apparent that I needed a license key. Thinking that non-profits were still getting a break, I wrote to their sales department inquiring about licenses for a non-profit organization. This is what I got back:

thank you for your enquiry about mxODBC. Unfortunately mxODBC is no longer free for non-profit organisations. The new release of mxODBC continues several years’ improvements. The change in licensing was necessary because less than 0.1% of all downloads of mxODBC led to purchases and we are sure that mxOBDC is currently being used in commercial environments without a licence. Furthermore, we know that mxODBC is often in use in environments with commercial products such as Oracle. We have, therefore, unfortunately had to introduce a compulsory licensing scheme and have also reviewed our licensing policy. Because our product is extremely competitively priced we cannot afford to give away a great many licences particularly outside of Germany as we cannot offset the donation against tax. We also have to consider the administrative overhead involved in verifying non-profit status. It is for these reasons that we have decided to stop providing mxODBC for free.

Fortunately, I had already decided to hack away on getting pyodbc to run while I was waiting for eGenix to respond. Point is, if you’re willing to keep installing headers and such, you should eventually be able to get pyodbc to compile and work under Linux. The big one for me was that I found that version 2.0.35 was the only version I got get to work with my Python 2.5 installation (not sure about other versions). Doing the sudo python setup.PY install failed everytime with 2.0.36, but 2.0.35 was fine.

As for eGenix, I am sure the mxODBC is a fine product. Their mx libraries have long been a part of the overall Python landscape and I can’t help but think that if my requirements were for a trusted ODBC connection that was continuously used in a production environment, mxODBC might be the best option. But I also can’t help but think that pyodbc and the overall FOSS-spirit of the Python community might eventually do them (eGenix) in. It’s obvious that if the pyodbc project continues to mature under its current model that it will become the way to do ODBC with Python. It’s not that I have anything against folks making money. I am, after all, a capitalist. But part of the fun of a free market is watching how the software market continues to change with competition from free software.

As a side note, I think it is interesting that the IBM client access software, while not open source, is now free.

Technorati Tags: , , ,

5 comments

Sites Hijacked

Thanks to a ‘Security Breach’ at DreamHost, my 2+ sites were hijacked. Obviously have things running again, but this issue points out several things. FTP is not very secure (as if we didn’t know that). Running PHP, while convenient because everyone runs it, is also a dangerous because the bad guys just wrote a script that edited any ‘index.php’ files out there on the accounts they managed to breach. If I’d been running some funky cool django stuff, there’d have been no index.php to hijack.

No comments

Some Weird DOS String Things

I found myself needing to do a fairly complicated thing. Well, it’s not complicated, but for a DOS batch file, it seemed complicated. The problem I was facing: to insert some “official” DOS command stuff into a .bat file that is run on all computers in our entire organization. I have no idea how many machines were talking about here but I would guess the number to be in the 5,000+ range or higher. Specifically, this is our official domain login script. Yikes. I don’t like having anything to do with something that gets touched this often. One screwup in there and it’s not a good thing. The problem is that we have a special group of machines (about 130) that are not registered on the domain. Now we need them on the domain but we don’t want to run some of the programs that our “Software Taliban” uses for monitoring machines. All of these special machines have a common naming scheme which is the letter S followed by a 7-digit number. So my task was insert some DOS .bat stuff in the existing .bat file that will run without external dependencies (other than whatever is already guaranteed to be there). All I knew for sure was that the environment variable COMPUTERNAME would be filled with the name of the computer and that my special machines were running 2K or XP and that either way, the OS environment variable would be filled with “Windows_NT”.

I also wanted to make sure I didn’t catch machines that were named “Snoopy” or anything like that. So for lack of a better way, I chose the following as my DOS string substitution method:

SET CN=%COMPUTERNAME% 
SET CN=%CN:0=x% 
SET CN=%CN:1=x% 
SET CN=%CN:2=x% 
SET CN=%CN:3=x% 
SET CN=%CN:4=x% 
SET CN=%CN:5=x% 
SET CN=%CN:6=x% 
SET CN=%CN:7=x% 
SET CN=%CN:8=x% 
SET CN=%CN:9=x% 
IF /i "%CN%"=="Sxxxxxx" GOTO END

The magic here is the funky %variable:y=x% stuff. Essentially, it’s string replacement where any ‘y’ is replaced with an ‘x’. This then normalizes the name into something I can compare against. Doing it this way also guarantees that I am comparing the length as well. So while it isn’t pretty, I was pleasantly surprised to find it was possible to do in DOS. There is also a method for getting a substring using a similar syntax: %variable:~s,l% where s is the starting position (1-based) and l is the length of the sub-string. Talk about obscure. But then again, how often do you have to stick to plain old DOS .bat files?

Technorati Tags: ,

4 comments

Headed to PyCon 2007 and My Twisted BoF Announcement

Since there seems to be virtually nothing Twisted or Nevow related going on at PyCon, I thought (last minute I know) that I would at least try to organize a BoF meeting (most likely pretty informal) for folks into Twisted and Nevow. So if you are interested, please add your name to the wiki page for the Twisted BoF. If there’s at least 3 or 4 folks, I’ll try to setup a time, even if it’s a dinner or lunch or something. Or if someone else wants to suggest a time that would be great as well.

Technorati Tags: , , ,

No comments

Brandon’s Handy Komodo Hacks

If you’re running or thinking of running Komodo Edit 4.0 (or IDE), then you need to check out Brandon’s Site. In particular he’s done several different tips including:

Enjoy!

Technorati Tags: ,

No comments

Running OpenSUSE 10.2 as a VMWare Guest

I downloaded the 10.2 version (DVD image) of OpenSUSE just to see what it was like. I quickly created a blank 20GB virtual machine for it to install into. And then it all came to a halt. After a ton of searching, I discovered that the secret was to type “nomce” as the lone boot option before selecting “Install” from the menu. Once I did that, it installed without any problems.

As for OpenSUSE itself. It was interesting seeing such a different take on an install process compared to Ubuntu (now that I have done so many installs). I have only played with it for a few minutes but I found it interesting that Python 2.5 was the default version installed. I also couldn’t immediately figure out how you’re supposed to install something like wxpython on there. I’m thinking Ubuntu has me pretty spoiled. But I still think it’s appropriate to give OpenSUSE a look.

2 comments

pyodbc and mxODBC and Accessing the DB/400 AS/400 DB2 Databases

For a utility we are writing at work we needed to be able to insert and delete records from a temporary flat file/table on our AS/400. For reference, we are connecting via IBM’s iSeries Access ODBC drivers. The SELECT statements were working fine but we were getting the infamous SQL7008 errors on all DELETE and INSERT statements. I hunted frantically for a solution and everything of course explains that unjournaled files on an AS/400 won’t support transactions and that the driver should be set to an isolation level of 0. The problem is that there appears to be no way to actually set something called an “isolation level” within the IBM driver.

After some experimentation and a little logic, I discovered that the solution is rather simple. In mxODBC you need to specify the clear_auto_commit=0 as part of the connection parameters. And the solution for pyodbc is similar, you need to specify the new autocommit=True as a named parameter for the connect method. The tricky part about the pyodbc is that the new autocommit parameter didn’t exist until February 1st, 2007 (version 2.0.33). I was floundering along in version 2.0.30 and was stuck as to why the documentation didn’t seem to match the actual library. After a quick download and install of the latest version, I was in business. It’s nice to see the pyodbc project maturing and being so actively developed.

Technorati Tags: , , , , ,

1 comment

Now on wxPython 2.8.x Upgrade from 2.7.x and 2.6.x

At work, I have a couple of apps we’re about to release that use py2exe and wxPython. And like many folks, I’ve ended up seeing the zipextimporter error trying to run the final .exe on a Windows 2000 box. Windows XP was fine. I was getting this error with a wxPython 2.7.x configuration. Since 2.8.1.x is now out, I figured I’d upgrade while I was at it. Now, my previously mentioned issue with the StaticBoxSizer is fixed so that’s definitely an improvement and I no longer have to use the --dell-exclude gdiplus.dll fix (yea!) , but I was still getting the zipextimporter error on _core_. Any search on google will turn up tons of hits for this error. Each time, folks are implored to include gdiplus.dll and stuff like that. No matter what advice I followed, it didn’t seem to work. But it turns out the missing file was really MSVCP71.DLL (rather than MSVCR71.DLL). By including that .DLL (you can get it from the wx library area referenced in the output of py2exe) with my .exe I’m suddenly good to go on Window 2K boxes. Under XP, everything is fine without it because it is presumably already installed on an XP box. Since I was having trouble finding info on it, I figured I’d blog about it. Essentially, it’s one of those things where you really need to just look at the output of py2exe because the bindings and includes for wxpython are now pretty darn accurate. Overall, a big thumbs up to wxPython 2.8.x so far. Now, I’m anxious to look at other areas to see what all is new/better.

Technorati Tags: , ,

5 comments

« Previous PageNext Page »