Wednesday, February 22, 2012

Biarri Applied Mathematics conference a success!

The first Biarri Applied Mathematics conference, or BAM, was hosted by the School of Mathematics and Physics at the University of Queensland on Monday (Feb 22). The conference was a big success, with around 65 people attending, including industry representatives, academics and students.

Dr Simon Dunstall from CSIRO won the prize for the best talk of the day, however all the talks (given by Operations Research practioners from both Biarri and from industry) were informative and interesting and generated discussion and questions. In particular it seemed that Network Flow techniques were very much alive and well, as they came up in several different modelling contexts throughout the day.

Biarri once again thanks those who attended as well as those behind the scenes who helped make the event a success.

Wednesday, January 25, 2012

An efficient and effective research environment (on linux, with vim, jabref and more)

So, I would like to share the environment that I have created for the purposes of doing research. Specifically it is an environment that allows me to:

  • Gather research papers,
  • Comment on them in various ways, and review these comments at large,
  • Store this information in source control for the purposes of sharing between my machines, and
  • Write up and deal with ideas in a systematic fashion.

So, the perhaps the first component of this system is, what operating system? Happily, it doesn't exactly matter. I use Ubuntu, but I also use Windows 7. The great thing about this scheme is that it is adaptable to any environment that runs the tools (well, obviously) and the tools all have multi-platform support.

I personally find editing in vim nicer on Ubuntu, and there is one or two arguably minor things that linux has that Windows does not (XMonad, for example), but I will elaborate on these later.

The general scheme

This approach is, obviously, tailored specifically for me, and given that I have a significant programming background, I am happy to solve some problems with actual programming. I also quite enjoy "systematic" approaches; i.e. things that may not neccessarily be the most user friendly or easy, but ones that follow a specific and clear pattern that makes logical sense.

This approach may not suit everyone, but hopefully there are at least interesting and useful ideas here that you could adapt to your own situation.

The beginning - reference management

So, of course in order to gather research papers it is neccessary to store them in a useful way. JabRef is free, and is a very nice option for this. I've described my custom JabRef set up on my own personal blog a few months ago, please read that for how to do this.

One thing on using JabRef is that sometimes you need to correct the format that bibtex exports give you. For example, one thing I am often changing is lists of authors like: "Billy Smith, Joey Anderson" to "Billy Smith and Joey Anderson"

It's not immediately clear to me why the bibtex are generated the wrong way from some of these sites, but nevertheless. This simple correction is neccessary for the data to be stored properly, and the authors to be picked up correctly, etc.

Okay, now that you've read that, you understand that I save all my PDFs to a specific location, a folder like ".../research/reference library". Where is this folder? It's in the research repository.

The "research" repository

I keep all my research, on any topic, in one generic folder, called "research". This is a private git repository hosted on BitBucket.org. I chose bitbucket over github because bitbucket has free unlimited-space private repositories, while githubs cost money. It is neccessary for the research repository to be private for two reasons, one obvious one is that it contains paywall-restricted PDFs, and the other is that it's just not appropriate to have in-progress research notes be viewable by anyone.

So, the general structure of my research repository is as follows:

~/research
    /articles
    /conferences
    /diary
    /jabref
    /reference library
    /projects
        /semigroups
        /...
    /quantum-lunch
    /...

The contents of these folders are as follows:

~/research/articles - Articles

This contains folders that map directly to papers that I'm trying to write (or more correctly at the moment, scholarships that I'm applying for, and misc notes). These are all, unsurprisingly, LaTeX documents that I edit with Vim.

When I complete an article, I created a "submitted" folder under the specific article, and put the generated PDF in there, but up until that time I only add the non-generated files to source control (this is the generally correct practice for using any kind of source control; only "source" files are included, anything that is generated from the source files is not).

~/research/conferences - Notes on conferences

In here I have folders that map to the short conference name, for example "ACC" for Australian Control Conference. Under that, I have the year, and within that I have my notes, and also any agenda's that I may have needed, to see what lectures I would attend. The notes should be in vimwiki format (I will describe this later) for easy/nice reading and editing.

~/research/dairy - Research diary and general ideas area

This is the main place I work on day-to-day. It contains all my notes, and minutes from various meetings and lectures I attend. It contains a somewhat-daily research diary, and a list of current research ideas, past research ideas (that were bad, and reasons why) and so on.

My preferred note taking form is vimwiki (to be described below), so in here are purely vimwiki files.

It's not essential that you also use vim (and hence vimwiki), but it is appropriate that whatever mechanism you use, it is a format that is ameneable to source control (i.e. allows nice text-based diffs). Emacs or any plain-text editor will be sufficient here.

~/research/jabref - Bibtex files

This is perhaps not the most appropriately named folder, but nevertheless. It contains all my .bib databases. I actually only have 3. One is very inappropriately called "2010.bib", with the view that I would store research by the year I gathered it. I'm not following this approach and I actually just keep all my research related to quantum computing (and more general subjects) in here.

I have two other bib files, one is related to a secondary field of that I am interested in researching. That is to suggest, in 2010.bib I have only documents related to quantum computing, theoretical physics and some theoretical computer science. I have a different .bib for research in completely seperate fields, say investment. The other is "lectures.bib", and it is obvious what that contains.

It's worth noting that I actually have two systems for storing lectures. One is the above, where the lecture set fits into a nice single PDF. The other is when the lecture series is split over several PDFs. These I store under a generic "University" repository that I use for my current studies (including assignments and so on). This component of my current setup needs work, and I'm open to suggestions here.

~/research/reference library - All the PDFs

Every PDF releated to my research is stored in here, prefixed with the bibtex key. So, for example I have "Datta2005, 0505213v1.pdf". JabRef associates this with the relevant item in the .bib file by the prefix, and virtue of this link in the .bib I have a trivial way to programmatically (if I'm so inclined) get this PDF.

I don't ever browse this folder directly, and currently it contains ~600 PDFs and is about 1 gig in size. Storing this much data in a git repository may offend some people, but essentially they are wrong to be offended. It is okay to store binary files as long as they are not constantly changing, and they are considered a key component of the repository; which in this case they are.

There are some downsides to this, though, and I think it's plausible to consider alternative arrangements.

The viable alternatives are:

  • Dropbox for PDFs,
  • Secondary git repository for PDFs only, and include as submodule, or
  • Some other non-local storage (say, the one offered by Zotero).

I dislike all of them because for me I prefer to have everything together. I could see dropbox being suitable, because technically it's not neccessary to have verioned PDFs.

If you have any comments on this, please share them.

~/research/projects - Specific Projects

You'll notice I have one folder here, "semigroups". This relates directly to a research scholarship I completed at RMIT. This actually involved a python program, which I have in this directory, as well as some miscellaneous files. It may be appropriate to have nicer codenames for projects, or somehow related them directly to the scholarship details. I think the best approach here is to have a codename, which is detailed in the "diary" folder, and then there is no risk on confusion or duplicate names. The scholarship details could be held seperately in the folder, because perhaps the work could be continued across scholarships.

Anyway, it's probably not neccessary to overwork this structure. It can always be changed, and it shouldn't be prohibitively difficult.

~/research/quantum-lunch - Files related to my reading group

This folder is indicative of the other types of folders you may find in this directory. In here, I have some misc python scripts related to this group. There are no notes in here, they are kept in the "diary" folder.

Technically this should be a transition area, where scripts and programs that reach an appropriate level of maturity/usefulness are either published publically (in a different repository), or moved to an appropriate folder under project, but I've not yet gotten to that stage.

It's worth noting that I do have a public github profile: silky, underwhich I will, and do, publish and tools that are worthwhile being public. If one of these projects reaches that stage, I'd essentially move it out of here (delete it) and continue it in that area.

The tools

So, with the repository layout described, let me know discuss the tools I use. We've already covered JabRef, for reference management, so we have:

  • JabRef (as mentioned), for reference management,
  • Vim + Vimwiki plugin, for taking notes, keeping ideas, and writing LaTeX,
  • Okular, for reading PDFs, and annotating them [linux],
  • Python, for programming small scripts,
  • XMonad, for window management [linux], and
  • pdflatex and bibtex, for compiling latex (from the TeXLive distribution).

So, almost all of these are available on any platform. Okular is worth commenting on, because it has an important feature that I make use of - it stores annotations not in the PDF but in a seperate file, that can then be programmatically investigated. If you can't use okular, then you may find that your annotations to PDFs are written back into the PDF itself, and it will be difficult to extract this. You can decide whether or not this bothers you when I describe how I use my annotations.

I will now describe the usage pattern for the various tools, starting in order for easiest to hardest.

Tools - Okular

So, install okular via your favourite method, say "sudo apt-get install okoular", and then open it. You will want to make it your default PDF editor, and I also choose to have it be very minimal in it's display; setting the toolbar to text only, hiding the menu, and hiding the list of pages on the left. I also configured a shortcut for exiting, namely pressing "qq".

For me this is indicative of an important principle - make small customisations that improve your life. It's worth thinking about, as they can often be trivial, but provide a nice noticable benefit.

You will also want to enable the 'Review' toolbar. This allows you to highlight lines of interest, and also add comments. Your comments are saved in a location like:

~/.kde/share/apps/okular/docdata/[number].[pdf-name].xml

This is where it gets fun. I've written a program to capture these comments, as well as comments in the 'Review' field of the .bib file. This tool is available on my github: get-notes.

You may need to adjust the 'main.conf' to suit your needs, or even change the source in some fashion. The code is pretty trivial, but requires some python libraries that you can install with easy_install.

This file products vimwiki output (you can trivially change this however you like, if you program in python). I then symbolically link this generated file ("AutoGeneratedNotes.wiki") to my "~/research/diary". Of course, following the general strategy of not including generated files in the source code, I do not break this rule for this file. There is one perhaps obvious downside to this: The output might be different on different machines, because the ~/.kde/... folder is not under source control. I consider this acceptable, because this file is a "transitional" file, in that it is not supposed to be for long-term storage of ideas and comments.

The contents of this file should be reviewed, occasionally, and then moved into either a PDF of comments, or into the research diary for an idea to investiage, or removed because you've dealt with it.

For example, I have a comment in the "Review" field of the file "Arora2002". It says: "Has a section on the Fourier Transform that might be interesting". This should, eventually, be transitioned into a minor topic to investigate further, or a small writeup in a private "Comments on things" LaTeX document, where you write up, slightly more formally, and with maths, your thoughts on things you've learned. I have this document under my "articles" folder.

With this in mind, it is then not an issue that the generated output is different bewteen machines, because ideally there will be no output on any machine, one it has been sufficiently transitioned.

Tools - LaTeX

As indicated, I use LaTeX to write up maths and more detailed notes, proposals, applications, etc. You may wish to use some front-end for LaTeX authoring, for example LyX, but as I already do a lot of work in vim, I prefer to also do LaTeX in here. If I were to switch to another editor, it would probably be Emacs.

Tools - Python

As mentioned in the above comment, I use python to write small scripts. Because they're in python, they are essentially directly runnable on any system (provided the associated packages can be installed).

I also like python because it provides various packages that are actually useful for my research (like, for example, numpy). You can get similar funcionality from free Math environments, though, such as Octave.

Tools - XMonad

XMonad is not particularly neccessary for this workflow, but I include it because I find it's ease of use aids in efficient reading and editing. I don't want to go into significant detail of XMonad configuration (but it's a fun way to spend your time), you may simply review my XMonad configuration on github.

What I like about it is the concept of focus. You can simply and easily make a PDF full screen, for distraction-free reading, and then switch things around to have vim side-by-side for commenting with context.

Feel free to disregard this, if you are using Windows, as it's equally possible to do fullscreen and side-by-side editing in Windows 7. XMonad also offers other benefits for general programming, which is the main reason I have it.

Tools - Vim + Vimwiki + LaTeX Box

Essentially the last item in my setup is Vim. It's hard to express the level of obsession one has for Vim, after a while of using it. It is highly customisable, and includes and inbuilt help system, which I used all the time, when initially learning it.

Most people will find Vim initially difficult to use (I did, when I first learned it when starting work here), but if you dedicate a few days to using it correctly, and you make significant use of the ":help [topic]" command, you will get the hang of it.

You aren't truly using Vim correctly (or, indeed, living a full life), if you don't get various plugins. The neccessary ones for LaTeX + note taking are: Vimwiki and LaTeX Box or Vim-LaTeX.

You can find the current state of my Vim configuration, again on my github - .vim

I actually currently use Vim-LaTeX, but I am planning on changing to LaTeX Box because it is more lightweight, so I would recommend starting with LaTeX Box.

The nice thing about using okular is that you can recompile your LaTeX document with the PDF open, and it will refresh it, keeping the current page open. This is very useful when typing long formulas, and reviewing your work.

I have configured Vimwiki to open with "rw", so I can type this at any time, in Vim, and be looking at the index to all my research notes. In this I have links to all my diaries, my storage spots for old search ideas, and a big list of topics to look into. I also make "TODO" notes in here, and review them with one of my other tools, "find-todo" (on the aforemention github, under /utils). This gives me a list inside Vim, and I can easily navigate to the appropriate file. Again, the TODO's are items that should be transitioned.

Review

I have documented my reseach environment, as it stands currently. It allows me to make notes easily, transition them in an appropriate workflow, and access all my documents at any time, from any computer.

The proof of a good research environment obviously in the blogging, it's in the producing of legitimately good research output, and of course that's yet to be delivered (by myself personally), so it's not possible to objectively rate this strategy for it's actual effectiveness. Nevertheless, I do feel comfortable with this layout; I feel like I can take the appropriate amount of notes; I feel my notes are always tracked, and I feel that I have a nice and readable history of what I've done. I like that I can track bad ideas; I like that I can make comments "anywhere" (i.e. in Okular or in JabRef) and have them captured automatically for later review, and I like the feeling of having everything organised.

I hope this description has been useful, and I would love to hear about any adjustments you'd propose, or just your own research strategies.

-- Noon

Thursday, December 15, 2011

Vim (and Emacs)

Biarri now has a few dedicated vim users with their configuration files available online: Myself (Loki) and Noon.

My configuration file is based on Sontek's with a few changes and additions. His description at http://sontek.net/turning-vim-into-a-modern-python-ide is worth a read.

You'll notice that I have disabled my arrow keys. Despite liking the Cure and The Smiths this isn't to hurt myself. It's not ever so I keep my hands on the home row and use hjkl. Instead it's to force me out of insert mode. I now stay in normal mode as much as possible. Since disabling my arrows I've found the combination of traditional vim motions (especially f/F) combined with Easy Motion is fantastic. I usually use f for short jumps and Easy Motion for longer movements.

Easy Motion is really best explained by watching the demo video closely, or just using it. It's quite wonderful and works well with visual mode. I'm also enjoying Command-T, PyFlakes, snipmate and ack. I'm still confused about what the best autocomplete solution is. Supertab doesn't seem to work right for me and ACP, which I was using for a while is useful but somewhat annoying. I would like it to show call signatures and if requested, docstrings in a non-annoying way too. Command-T is the greatest thing imaginable for opening files, buffers and tags.

I've also installed vimwiki but i'm so far unsure about it. I used it to store my ideas and todos in a more organised manner. I suspect it's a bit like a less awesome org mode. Speaking of which we now also have an Emacs user: https://bitbucket.org/tobyodavies/shared/src If anyone knows a good python autocomplete solution I'd love to hear about it.

Loki

Friday, December 9, 2011

Subscription payments

Selling things on the internet is quite easy and there are plenty of way to process credit cards and accept online payments. However subscriptions / recurring payments aren't easy. They aren't easy at all. Subscription changes, card failures, multiple subscriptions for a single user (different workbench products in our case) and multiple currency billing make it hard. Dealing with banks 80's style systems makes it even harder.

When we were first working out how to cope with online payments we found lots of good looking options, all of which were only available to American companies or via paypal. (RecurlyCheddarGetterSpreedly) Eventually we found RBS Worldpay.Worldpay turned out to be too inflexible and far to much effort to set up. The time required was also insane. From the start of our application to ready to get our payments up took 7 months and significant amounts of cash. We gave up on Worldpay when we were trying (hard) to integrate it. Their system for recurring payments is so ill documented and inflexible to be useless. Users appear to require a separate login and password for Worldpay. This is unacceptable. Currently we're looking into Saasy, from fastspring. They respond fantastically quickly to support request and got our testing site up and approved us in a day. So far it looks great, flexible and easy but I'll post another blog when we've got it all live. I'll also put some code for the server side part in python using cherrypy up on github, when it's a bit more polished.

Loki

Tuesday, November 1, 2011

Selecting a cell in an HTML table with jQuery

I wanted to get (and set) a cell value in a table using jQuery, selecting it by row and column index (its x and y position in the table, if you like). Frustratingly, I couldn't find a simple one-liner to do it: I could find code that gets all the cells, or get them by ID (but I don't want to have to make explicit IDs for each cell of my table), or get all the values in a given column (close, and did lead me in the right direction).

So here's two similar ways to select a given cell, where row and col are my x, y positions, and my_table is the ID of the table:

$('#my_table tr:eq('+row+') td').eq(col)


and


$('#my_table tbody tr:eq('+row+') td:eq('+col+')')




Tuesday, October 18, 2011

PostgreSQL Tricks

Over the last year or so I've gathered a little trick bag of PostgreSQL recipes. Here are some of the best.

These all work in PostgreSQL version 8.4.7 and probably most other versions. The "--" below are PostgreSQL comments.

To see your PostgreSQL version, use:

select version();

It's sometimes useful to be able to discover the tables in a schema automatically. To do this you can use the following command:

>>> \dt my_schema.* -- here the * is a wildcard

Or this command, which uses the PostgreSQL internal tables pg_class and pg_namespace:

>>> select n.nspname, c.relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where n.nspname='my_schema';

Where "my_schema" is a schema name. Once you've found the table you're interested in, \d table_name gives you the columns and their types.

To discover the columns in a table (that is in a schema):

>>> select a.attname from pg_class as c, pg_namespace as n, pg_attribute as a where n.oid=c.relnamespace and n.nspname='my_schema' and c.relname='my_table' and a.attrelid=c.oid;

Where "my_table" is the table name in your schema. This uses the PostgreSQL internal tables pg_class, pg_namespace and pg_attribute.

To discover the type of a column in a table (that is in a schema)

>>> select a.attname, t.typname, a.atttypid from pg_class as c, pg_namespace as n, pg_attribute as a, pg_type as t where n.oid=c.relnamespace and n.nspname='my_schema' and c.relname='my_table' and a.attrelid=c.oid and a.attname='my_column' and t.oid=a.atttypid;

Where "my_column" is the column name in the table. This is similar to the previous command, but also uses internal table pg_type.

If you have some duplicate rows in your table, you can delete them using the hidden ctid column, e.g.:

>>> select ctid, * from my_table; -- show me the repeats

>>> delete from my_table where CAST("ctid" as text) like '%3%'; -- kill some according to some wildcard pattern

A more automatic way is:

>>> delete form my_table where ctid not in (select max(dup.ctid) from my_table as dup group by dup.x, dup.y, dup.z); -- substitute appropriate column names for x, y, z

Allowable formats for dates are controlled by the PostgreSQL setting 'datestyle'. To see it, type:

show datestyle;


To change the datestyle you can use (for example):

set datestyle to 'iso, dmy';

But note that this change is not a permanent change (it only applies to this session/cursor).

Lastly, I sometimes use this command:

table my_table;

as a shorthand for select * from my_table.

Friday, October 14, 2011

Debugging Internet Traffic

Below are some tools and thoughts that may be useful to people who are having difficulties trying to debug issues related to internet traffic.
There are a number of other tools (e.g. Firebug, Wireshark/ethereal, etc) that are not mentioned below. However I thought a quick one pager on some of the tools that I have used and found useful might be useful to someone else.

Tamper (Firefox plug-in)

https://addons.mozilla.org/en-US/firefox/addon/tamper-data/
This is a Firefox plugin which allows users to view the exact data they're sending out through their browser. It's useful for debugging traffic, as well as those times when your browser has remembered your password and you've forgotten your password (as you can see the password that is being sent). It also gives you the opportunity to intercept this data and change it which can also be useful for debugging purposes. The disadvantage with this tool though is that it will only work on data sent through Firefox. Fiddler2 (below) can be used to intecept traffic from a wider range of sources (e.g. iexplorer, firefox, wget, curl, ... and other applications).

wget and curl

http://www.gnu.org/s/wget/
http://curl.haxx.se
These tools are very similar and are useful for sending web requests via command line. They both work in Linux and Windows (and other OSes). I was using this to help debug an issue we were having at a client site that was not allowing our newt traffic to be sent to our servers. It means you can easily change things like proxy settings, username/passwords, URLs, the posted data - without having to recompile an exe and copy it onto the client machine. I personally found curl worked better than wget. I couldn't get the username/password information to be sent correctly with wget. There was plenty of help on the net, but it just didn't seem to work for me for some reason. A typical example of the types of curl requests I was sending looked like this:
curl -L -x proxy_details:proxy_port --user username:password --output outuptfile.html http://website.com/method --data "user_info=stuffhere%3Bmorestuffhere%3Bextra_info=morestuffhere"
These command line tools can of course called via scripts as well if required.

Filddler 2

http://www.fiddler2.com/fiddler2/
I found this tool paricularly useful when diagnosing firewall/proxy issues as I could see exactly why various requests from curl/wget were, or were not, working.

I'm certainly not an expert on Fiddler2, and I'm not abou to try and tell you all the ins and outs of how to use this tool: firstly because I don't know all of them, secondly because a quick Google search will help you there.
However, some of the useful features that I have found useful are:
  • It can monitor traffic from differnt sources. The "Process" column in the left pane in the above image shows that curl and firefox traffic has been detected.
  • The upper pane on the right shows the request details of the selected item in the left pane:
    • Headers
    • TextView
    • WebForms
    • HexView
    • Auth (useful if want to see how usernames and passwords are being handled)
    • Raw
    • XML
    • JSON
  • The lower pane on the right gives the response details of the selected item in the left pane:
    • Auth
    • Caching
    • Privacy
    • Raw
    • XML
    • JSON
  • Another one of the cool features of fiddler2 is that it can be used to debug encrypted traffic. It does this by installig a security certificate on your computer. Ideally you would only install this security certificate on a machine for debuggnig purposes and one that was not passing sensitive information over the internet as it poses a security risk. It should be removed from the computer once you have finished debugging (it's easy enough to put another back in the future if requred).


Wednesday, September 28, 2011

Pre-emptive optimisation; or, how to be deliberately wasteful of server resources

For one of our long-standing clients we have been running vehicle routing optimisations on a daily basis. A file of daily orders is uploaded into our Workbench system, and is split up into several regions, each of which needs to be separately optimised. A planner works through each region, going through a series of data checks (e.g. location geocode checking), before hitting an “Optimise” button.

All of the heavy lifting is done on a server (the planner accesses it through a web app via a browser), so it’s possible that the server could silently start up the required optimisations without the planner’s involvement, and in the (fairly common) case where the region does not require any data corrections, when the planner is up to the optimisation stage, the result could be immediately available (as it has already been run, or is in the process of being run). This idea now been implemented and took only a short amount of Python code.

Furthermore, it runs in parallel as each optimisation is itself split into a separate child process (running a C++ exe) which Linux distributes across the 8 cores of our server machine.
The pre-emptive optimisations are kicked off using Python’s multiprocessing package, as follows:

from multiprocessing import Process

...

p = Process(target=start_preemptive_optimisations, args=(...))

p.start()


Control is returned to the user at this point while the optimisations run in the background. Results are stored in a folder whose name is stored in a database table; when the planner then comes to press Optimise, the system checks if there have been any data corrections – if so, it runs the optimisation from scratch as usual (the pre-emptive result for that region is thus never referenced); however, if there are no corrections, the system simply uses the stored result from the folder.

The end result for the user is that in many cases the optimisations appear to run almost instantaneously. There are really no downsides as we do not pay for our servers on a CPU cycle basis, so we can easily be wasteful of our server CPU time and run these optimisations even if their results are sometimes not needed.

One “wrinkle” we discovered with this is that we had to make our process checking more robust. There is Javascript in our browser front end that polls for certain events, such as an optimisation finishing, which is indicated by a process ceasing to exist. The Python for this is shown below, where “pid” is a process ID. The function returns True if the given process has finished or not.


def check_pid_and_return_whether_process_has_finished(pid):
        if pid and pid > 0:
            multiprocessing.active_children()   # reap all zombie children first; this also seems to pick up non-children processes
            try:
                os.waitpid(pid, os.WNOHANG)       # this reaps zombies that are child processes, as it gives these processes a chance to output their final return value to the OS.
            except OSError as e:
                if int(e.errno) <> 10:  # the 10 indicates pid is not a child process; in this case we want to do nothing and let os.kill be the function to throw an exception and return True (indicating process is finished).
                    return True
            try:
                os.kill(pid, 0)   # doesn't actually kill the process, but raises an OSError if the process pid does not exist; this indicates the process is finished.  Applies to all processes, not just children.
            except OSError as e:
                return True
        else:
            return True
        return False


Note the “reaping” of zombie processes here, and the complication that arises if a process is not a direct child of the calling Python process (it might be a “child of a child”). In this case we use a call to the (in this case rather mis-named) function os.kill.