Friday, October 31, 2014

The post immediately prior to this one was an attempt to reproduce Windows.Forms Calendar controls in Gtk for cross platform (Windows/*nix) effective rendering.

This time I am attempting to get familiar with gtk-sharp/Gtk's version of a grid view - the Gtk.TreeView object. Some of the gtk-sharp documentation suggests the NodeView object would be easier to use. I had some trouble instantiating the objects associated with the NodeView and went with the TreeView instead in the hopes of getting more control.

The Windows.Forms GridView I did years ago is here. It became apparent to me shortly after embarking on this journey that I would be hard pressed to recreate all the functionality of that script in a timely manner. I settled for a tabular view of drillhole data (fabricated, mock data) with some custom formatting.

Aside: this is typically how mineral exploration drillhole data (core, reverse circulation drilling) is presented in tabular format - a series of from-to intervals with assay values. Assuming the assays are all separate elements, the reported weight percents should not sum more than 100%, and never do unless someone fat fingers a decimal place. I've projected a couple screaming hot polymetallic drill holes that end near surface (lack of funding for drilling), but show enough promise that the new mining town of Trachteville (the drill hole name CBT-BNZA stands for CBT-Bonanza) will spring up there at any moment . . . one can dream.

The data store object for the grid view Gtk.ListStore object would not instantiate in IronPython. I was not the only person to have experienced this problem (I cannot locate the link to the mailing list thread or forum reference, but like the big fish that got away, I swear I saw it). I didn't want to drop the effort just because of that, so I hacked and compiled some C# code:

Those are my file paths; locations depend on where you install things like mono and IronPython.

Anyway, I got my dll and I was off to the races. Getting to know the Gtk and gtk-sharp object model proved challenging for me. I'm glad I got some familiarity with it, but it would take me longer to do something in Gtk than it did with Windows.Forms. The most fun and gratifying part of the project was getting the custom formatting to work with a Gtk.TreeCellDataFunc. I used a function that yielded specific functions for each column - something that's really easy to do in Python.

Anyway, here are a couple screenshots and the IronPython code:

The OpenBSD one below turned out pretty good, but the Windows one had a little double line underneath the first row - it looked as though it was still trying to select that row when I told it specifically not to. I'm not a design perfectionist Steve Jobs type, but niggling nits like that drive me batty. For now, though it's best I publish the code and move on.

#!/usr/local/bin/mono /home/carl/IronPython-2.7.4/ipy64.exe

import clr

GTKSHARP = 'gtk-sharp'PANGO = 'pango-sharp'

# Mock store C#STOREX = 'storex'

clr.AddReference(GTKSHARP)clr.AddReference(PANGO)

# C# module compiled for this project.# Problems with Gtk.ListStore in IronPython.clr.AddReference(STOREX)

# XXX - not very generic, but better than doing them one by one. # from, to columns. for x in xrange(1, 3): self.columns[FIELDS[x]].SetCellDataFunc(self.cellrenderers[FIELDS[x]], genericfloatformat(FP1FMT, x)) # assay<x> columns. for x in xrange(3, 7): self.columns[FIELDS[x]].SetCellDataFunc(self.cellrenderers[FIELDS[x]], genericfloatformat(FP2FMT, x))

def usemarkup(self): """ Refreshes UseMarkup property on widgets (labels) so that they display properly and without markup text. """ # Have to refresh this property each time. self.frame.LabelWidget.UseMarkup = True

def prettyup(self): """ Get Gtk objects looking the way we intended. """ # Try to get Courier New on treeview. self.tree.ModifyFont(self.fdregular) # Get rid of line. self.frame.Shadow = Gtk.ShadowType.None self.usemarkup()

Thursday, October 30, 2014

A number of years ago I did a post on the IronPython Cookbook site about the Windows.Forms Calendar control. I could never get the thing to render nicely on *nix operating systems (BSD family). It sounds as though Windows.Forms development for mono (and in general) is kind of dead, so there is not much hope that solution/example will ever render nicely on *nix. Recently I've been playing with mono and decided to give gtk-sharp a shot with IronPython.

Quick disclaimers:

1) I suspect from the examples I've seen on the internet that PyGtk is a little easier to deal with than gtk-sharp. That's OK; I wanted to use IronPython and have the rest of the mono/dotNet framework available, so I went through the extra trouble to forego CPython and PyGtk and go with IronPython and gtk-sharp instead.

2) The desktop is not the most cutting edge or sexy platform in 2014. Nonetheless, where I work it is alive and well. When I no longer see engineers hacking solutions in Excel and VBA, I'll consider the possibility of outliving the desktop. Right now I'm not hopeful :-\

The results aren't bad, at least as far as rendering goes. I couldn't get the Courier font to take on OpenBSD, but the Gtk Calendar control looks acceptable. All in all, I was OK with the results on both Windows and OpenBSD. I've heard Gtk doesn't do quite as well on Apple products, but I don't own a Mac to test with. Here are a couple screenshots:

I run the cwm window manager on OpenBSD and have it set up to cut out borders on windows, hence the more minimalist look to the control there.

IronPython output on *nix has always come out in yellow or white - it doesn't show up on a white background, which I prefer. In order to get around this, I run an xterm with a black background:

Monday, October 20, 2014

Each month I redo 3D block model interpolations for a series of open pits at a distant mine. Those of you who follow my twitter feed often see me tweet, "The 3D geologic block model interpolation chuggeth . . ." What's going on is that I've got all the processing power maxed out dealing with millions of model blocks and thousands of data points. The machine heats up and with the fan sounds like a DC-9 warming up before flight.

All that said, running everything roughly in parallel is more efficient time-wise than running it sequentially. An hour of chugging is better than four. The way I've been doing this is using the Python (2.7) subprocess module's Popen method, running my five interpolated values in parallel. Our Python programmer Lori originally wrote this to run in sequence for a different set of problems. I bastardized it for my own.

The subprocess part of the code is relatively straightforward. Function startprocess() in my code covers that.

What makes this problem a little more challenging:

1) it's a vendor supplied executable we're dealing with . . . without an API or source . . . that's interactive (you can't feed it the config file path; it asks for it). This results in a number of time.sleep() and <process>.stdin.write() calls that can be brittle.

2) getting the processes started, as I just mentioned, is easy. Finding out when to stop, or kill them, requires knowledge of the app and how it generates output. I've gone for an ugly, but effective check of report file contents.

3) while waiting for the processes to finish their work, I need to know things are working and what's going on. I've accomplished this by reporting the data files' sizes in MB.

4) the executable isn't designed for a centralized code base (typically all scripts are kept in a folder for the specific project or pit), so it only allows about 100 character columns in the file paths sent to it. I've omitted this from my sanitized version of the code, but it made things even messier than they are below. Also, I don't know if all Windows programs do this, but the paths need to be inside quotes - the path kept breaking on the colon (:) when not quoted.

Basically, this is a fairly ugly problem and a script that requires babysitting while it runs. That's OK; it beats the alternative (running it sequentially while watching each run). I've tried to adhere to DRY (don't repeat yourself) as much as possible, but I suspect this could be improved upon.

The reason why I blog it is that I suspect there are other people out there who have to do the same sort of thing with their data. It doesn't have to be a mining problem. It can be anything that requires intensive computation across voluminous data with an executable not designed with a Python API.

Notes:

1) I've omitted the file multirunparameters.py that's in an import statement. It has a bunch of paths and names that are relevant to my project, but not to the reader's programming needs.

2) python 2.7 is listed at the top of the file as "mpython." This is the Python that our mine planning vendor ships that ties into their quite capable Python API. The executable I call with subprocess.Popen() is a Windows executable provided by a consultant independent of the mine planning vendor. It just makes sense to package this interpolation inside the mine planning vendor's multirun (~ batch file) framework as part of an overall working of the 3D geologic block model. The script exits as soon as this part of the batch is complete. I've inserted a 10 second pause at the end just to allow a quick look before it disappears.

Sunday, October 12, 2014

A mining bud Jen wrote a blog post lamenting the difficulty of learning a foreign language as an adult in a far off land. This inspired me to clean up my "download the Foreign Service Institute" French "tapes" (mp3's, actually) script I wrote for myself and publish it.

I'm not very astute on web programming. This script came out of necessity. There may be other, more efficient ways to do this. If you have a slow connection a piecemeal approach will probably be required. It took about 20 minutes to get all these files over a decent Verizon MIFI unit connection (I, unfortunately, don't have speed metrics available).

Notes about the downloaded product: the US State Department's language tapes and lessons were mostly written and produced 30 to 50 years ago. It's not Rosetta Stone, but I have found them to have value when it comes to practicing pronunciation, including cadence and rhythm of the foreign language - things you just can't get from printed or displayed text.

My late wife gifted me some Spanish tapes prior to the internet age that helped me out. I am by no means fluent in Spanish, but I can say Hacemos lo que podemoshasta que nosboten (this may not be entirely grammatically correct) to the Spanish speaking mining engineers and get a laugh.

The original names of the mp3's are unnecessarily long and have the appearance of having been created by the Department of Redundancy Department. It's a government thing, but it does not reflect on the quality of the product. While the tapes at times are socialogically and technologically dated in their subject matter, the foreign languages haven't changed all that much.

The script: I used Python 3.4 with the urllib module's request method. The main challenge was getting the url's of the mp3's right. The names are not entirely consistent. For help with this (I am using Firefox 24.3.0 on OpenBSD 5.4), I right clicked on the mp3's link and selected Inspect Element from the drop down menu:

The lower left window has the href and the link to the mp3 - if your script is not able to find the file, this is a convenient place to look.

print('Everything appears to have downloaded.')print('Check the directory with the files to be sure.')

As for my French efforts, I've had better luck downloading this stuff than I have learning it. Nonetheless, a quick message to Guido van Rossum and the other core devs: transmettez-leur mon meilleur souvenir.

Monday, October 6, 2014

I managed to squeeze in a 4 day stop in Johannesburg on a recent trip that happily coincided with pycon.za. I love pycon.us and all the other big conferences, but for value, these smaller localized cons can't be beat.

Venue: The Campus, Bryanston

Not your average office park. It's nicely landscaped and has a huge center beach or pitch or lawn (depending where you're from). The buildings are all named after famous sports venues like Lemans. The nod to us Yanks (NOT New York Yankees) in Wrigley Field was a nice touch.

Best of all 100MB/day of internet for all who enter. That's not ideal if you're wanting to watch Youtube videos, but plenty if you just want to check a speaker bio or do con-related stuff. I thought the organizers did a great job of keeping the con inexpensive but valuable.

The catered food and drinks were really good, by my standards at least.

Apart from an unfortunate plumbing problem in the men's bathroom the second day that was quickly repaired, everything went off without a hitch.

Astronomy is wickedly cool and based on instrumentation, precision, and data paucity and, ironically, an overabundance of data (on average about 10GB/day, up to 50GB/day). Crawford mentioned more than once the desperate need to "catch as many photons as possible because there are so few coming in." Yeah, photons, like particles of light, just wow.

Python is used for everything where it is appropriate to use it. There are plenty of problems that don't require you to be a genius rocket scientist like Crawford. sysadmin, data, and, perhaps most importantly, web. They're using MySQL and a web frontend to distribute data throughout the world on a daily basis to other astronomers who need it. I'm always biased toward raw data myself; it is critical, but if you can't distribute it, it's not worth much.

Good talk for me to attend.

Albert Nel - Using Python in Blender Nel is a total joker (in a respectful, entertaining, good way), but not enough of a joker to bely a serious love and enthusiasm for both Python and Blender.

My own experience with rendering 3D stuff is a little dinking around with POV-ray. Blender is different in that it's big on animations and honoring the laws of physics. Writing Python to automate Blender is similar to, for lack of a better analogy, writing or recording VBA macros in Excel.

Nel did a lotto ball live demo and a Lego movie ocean demo (aside: I *LOVE* live demos, even when they go wrong - it's one of the best parts of Open Source conferences versus say, a godawful boring company Powerpoint presentation - thank you to the Nelster for accomodating us).

My takeaways:

Blender is fun.Allison Randal The Earth is not Flat (and Other Heresies) Keynote - a lot of times I don't relate a lot to keynotes because it's about super high level programmer craft stuff (disclaimer: I've worked as a dev, but I'm a geologist by trade) that I can't really control or understand.

So my mind wandered as Randal gracefully moved about the stage in her pixie frame and calmly laid down her knowledge. As I much younger man I would have been thinking, "She's so smart . . . and a very attractive individual to boot . . ." As a curmudgeony old fart my thoughts go more towards the "Damn - she's in perfect shape, speaks well, and knows what the hell she's talking about. I'm SOOO jealous; why can't I be like that?" In all seriousness, what always blows me away when I see Randal talk is the calm, matter of fact way she just presents facts and opinions without any malice or belligerence.

At one point she responded to a question by saying essentially, "Don't use AWS; use OpenStack <if you want to accomplish X>." Amazon was one of the three top corporate sponsors of the event, but it wasn't a SPEAK TRUTH TO POWER/VIVE LA REVOLUCION kind of thing, just a "this is what I think based on what I know."

I'm glad she's with "us" (the open source community) instead of selling her soul to the commercial world (which she could do at great profit).

They say "kill your heroes." Until I drop 40 lbs. and learn to express my ideas in a less conflict ridden manner, I am not ready to kill anything. Sorry, Ms. Randal. I hope this isn't too creepy, but you're going to remain the queen on my hero pedestal for a while :-\

(Aside: it's none of my business, but I think Ms. Khan is Muslim - she wore this really cool black-red combination outfit with a red head scarf - I borked my picture with my point and shoot camera, but I think a video of the talk is online. Anyway, for a diversity-oriented talk, the outfit was not only cool and classy, but perfect for a South African con).

Ridhwana's talk was well structured with some humor interjected. She started out with the most important point - that she loves coding and wants to do this for a career. There were a number of valid points and ideas put forward - it's worth checking it out online.

My main takeaway: IIRC not once did Ridhwana mention a Code of Conduct policy nor did she dwell on personal experiences with harassment. Essentially, she has had a pretty good experience with colleagues thus far. After a year with an all male crew (her excepted), she learned that prior to her arrival, firm rules had been established regarding off-color humor (basically banned) and such. For me, this is a pretty good example of how some firm (but not excessively draconian) rules can help make programmer-land a women friendly place. Ridhwana's point was that (at least in South African society) this is typically how relationships go anyway. You meet someone, then after some time you get to know them better, and at that time, you can loosen up a bit more as appropriate.

Hallway track: there were fewer than 150 people at this con IIRC, so if you wanted to talk to anyone, there was time. People involved with the new kilometer array telescope project, people involved with the older telescopes northeast of Cape Town, speakers, Dr. Mertz, Allison Randal, a PhD in computational mathematics who specializes in computer vision, South African devs, the organizers of the conference - where else could a grunt open pit mine geologist like me have access to such luminosity? pycon.za is pretty sweet.