Thursday, April 01, 2010

Extending Python with C or C++

I'm learning how to write C++ code that can extend python.

To help myself and possibly anyone else, I'm going to write what I've learned so far.

the first thing that's required is to include the python header. On ubuntu if you haven't installed it yet, you can with this:
sudo install python-dev


Then you can start editing a cpp file with whatever your fave editor is. I choose you, vim!

$ vi knightmodule.cpp
Apparently for historical reasons the file is called XXXmodule, though if you have a "long" module name you can just use the name, like knight.cpp.

Continuing on, the first line in your file needs to be:
#include
which contains all the useful bits you need to make a good extension.


#include

extern "C"{

static PyObject * whosayni(PyObject *self, PyObject *args){
const char * knight;

if(!PyArg_ParseTuple(args, "s", &knight))
return NULL;

printf("%s is a knight who says, \"Ni!\"", knight);

Py_RETURN_NONE;
}

static PyMethodDef MyMethods[] = {
{"whosayni", whosayni, METH_VARARGS,
"Param knight: prints knight is a knight who says, \"Ni!\""},
{NULL, NULL, 0, "Testing"}
};

PyMODINIT_FUNC

initmyknights(void){
(void) Py_InitModule("Hello", MyMethods);
}

} // end extern


Then we create a python build script. It can be named anything you want, but convention dictates setup.py

$ vi setup.py


then


from distutils.core import setup, Extension

module1 = Extension('knight', sources = ['knightmodule.cpp'])

setup (name = 'Knights',
version = '1.0',
description = 'They say ni!',
ext_modules = [module1])


And fire it off with
$ python setup.py build


it will put your file in build/lib.linux-i686-2.6/knight.so - you can copy this .so file anywhere or navigate to the directory. When you're in the same dir as your knight.so


$ python
Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import knight
>>> knight.whosayni("Lancelot")
Lancelot is a knight who says, "Ni!">>>


Notice that the >>> is on the same line? That's because we didn't add a newline at the end of our print string.

So go ahead and edit that, rebuild your knight, and import again (just make sure if you copied it that you copy it again). You should get something like this:

>>> knight.whosayni('Richard')
Richard is a knight who says, "Ni!"


Now you've written your very first C++ extension for Python.

Keep looking for updates when I come back and explain what all this stuff does.

Labels: , , , ,

Wednesday, September 30, 2009

You Say Potato....

In mathematics, and more importantly (or at least pertinent, to me) there is a word:

tuple.

Say that word out loud. No really, go ahead! I'll wait

Tried it out? How did you pronounce it?

Did you pronounce it two-pull? Or more tuhple... like tupperware?

I'm very curious what your natural inclination is. I've always pronounced a "toople" sound. That's all I've ever heard until my Database System professor pronounces it a bit more like "Tadpole"

Labels: , ,

Tuesday, July 29, 2008

Gas Sucks

So... Unless you've been living in a cave, you know that gas is expensive.

Where I currently live, gas is around $3.70-3.80USD/gal. And unless you've been living under a rock, you also know that people are trying to save money, by shopping at the cheapest gas stations. I haven't played with the figures before, so for your joy and education, I'll explain several figures and numbers.

First off, let's figure out some statistics. This fall I will be traveling at least 40 miles a day, 5 days a week. I may be doing more, so lets go with 240 miles a week. My car gets about 20 mpg.

Today, I purchased gas for $3.74, instead of $3.88 at the highest station I saw. According to my calculations, (assuming 240 gallons), I would have paid $44.99, rather than $46.67, coming to a savings of a whopping $1.68. I suppose I could have bought something at the dollar store or off a dollar menu at a fast food joint for that much.

On a yearly basis (52 weeks - though I don't drive 240 each week, so this won't even be accurate), that would mean I would save a total of $87.36. If I continually managed to save $.14/gallon. That is a fairly substantial annual savings, however usually the prices are less.

What does it look like if we average $.05 per gallon savings, for a whole year, at 240 miles? That's 60₵ per week, or $31.20 a year.

So we've been looking at a weekly average of 240 miles. What if you average less, say around 100 miles per week, with a 5₵ savings in gas. That's 25₵ per week, or $13 per year. Not as substantial, although for $13 you can almost go see a movie with two people. Once a year. With your gasoline savings.

So, in some cases it makes a lot of sense to find the cheapest gas, in others, it doesn't. If you'd like to experiment with your own data, this program allows you to change the gas prices, mpg, and miles driven. It then computes monthly and annual savings.

It's written in python, if you don't have python, you'll have to download it here.

Enjoy!

1 # Wayne Werner
2 # Copyright July, 2008
3 # This code may be distributed and modified for personal or non-commercial
4 # use only.
5 # Gas Savings Calculator
6 # Used for calculating weekly, monthly, and yearly gas savings
7
8 from decimal import Decimal
9 from os import system
10 clear = system('clear') # Change 'clear' to 'cls' on a Windows machine
11
12 # Retrieves information from user, converting it to decimal type
13 gasA = Decimal(raw_input('Lower Gas Price: $'))
14 gasB = Decimal(raw_input('Higher Gas Price: $'))
15 mpg = Decimal(raw_input('Miles per gallon: '))
16 miles = Decimal(raw_input('Miles Traveled: '))
17
18
19 clear # Clears the screen
20
21 # Creates a list of miles, by 10, up to the miles traveled, to show
22 # what the savings would be for lesser miles traveled
23 24 my_range = range(10, miles, 10)
25 if my_range[-1] != miles:
26 my_range.append(int(miles))
27
28 # Prints column headers
29 print "%6s %7s %7s %11s\n" % \
30 ('Miles', 'Price A', 'Price B', 'Difference')
31
32 # Loops over the values in my_range, computing the total price for
33 # each price of gasoline.
34 for x in my_range:
35 if x == my_range[-1]: # Linebreak before the final values
36 print "\n",
37 priceA = (x/mpg) * gasA
38 priceB = (x/mpg) * gasB
39 diff = priceB - priceA
40 print "%6i $%6.2f $%6.2f $%4.2f" % (x, priceA, priceB, diff)
41
42 # Computes yearly and monthly savings, based on the difference
43 annual_savings = 52 * diff
44 monthly_savings = 4 * diff
45 print "\nAt an average weekly savings of $%.02f, your monthly savings will b
e $%.02f.\nYour annual savings will be $%.02f." \
46 % (diff, monthly_savings, annual_savings)

Labels: , , , , ,

Friday, June 27, 2008

Wine, Wonderful Wine...

So, there's a program called Wine (WINdows Emulator, IIRC). I'm working on getting it to work with my scriptures again, and OpenCanvas, with all the spiffin pressure sensitivity and... not inverting the Y-axis.

Currently, with oC, it goes severely wonky. It has pressure sensitivity fine, but it inverts the Y-axis of my tablet. So when I move down, it moves up. When I move left it moves left. When I move up it moves down. Needless to say, art would get a little confusing!

So I'm working on some fixes to that at the moment.

In addition, there's a seriously wonky problem in the LDS Scriptures CD-ROM, where the search function... works backwards? Basically it used to work fine. Then when you clicked in the search box it crashed. Then that was fixed, and now it does something creepy. Say you wanted to search for "israel". So in the box you type "israel". What is now in the box, however is " learsi". Spaces and backwards! Weirded out!! So that's next on the list of fix attempts. w00t.

s'all for now, enjoy your wine ^_^

Labels: , , ,

Thursday, August 23, 2007

Huzzah!

First day of classes? Mission: Accomplished.

Yeah, it was pretty good. I only had two classes, my writing class and my math class... it seems like they should both be some good classes.

Dr. Forssman Hill is my writing teacher, and Professor Booher is my math teacher, and they both seem like competent, nice ladies. Of course, the way I see it, that basically makes them teachers anyway, this way they simply get paid for it.

Well... I think that's about it for now... I'm rather tired - I've been up since 5AM, see... Heh... it could be fun to take a nap like I learned in the Worst Case Scenario Handbook: College Survival guide... One of the things I enjoy about college is people watching. Especially after being here for a semester... I can pretty much pick the freshmen out like nobodies business - they all seem to have this startled "deer in the headlights" look - slightly unsure and more or less worried. It's cute, really. I wonder if I looked like that my first semester... I doubt it, simply because I've done so much and I'm so easygoing that I was probably like "eh, whatever." Maybe.

Tomorrow I have math again, (bleh, I really need to get books & things) and Biology... what a horrid book. Both of those books will end out around $200 for the two classes. You know, the books should really just be included in tuition or something... about $1500 of random fees is anyway, so why not those?

I'm pretty sure that next semester I'll try to get back with the MWF classes... I just think it'll be a bit easier. Of course that also depends on everything else... like, say work schedule... wheee... so much fun.

So I'm learning myself the Python programming language. It's been a lot of fun so far, I now need to learn how to open/edit files... w00t. And then I wanna start learning how to play with PyGTK+ - it's a programming language/widget set that's pretty darn cool. That's what the GIMP and pidgin are programmed in.

Pretty sweet stuff.

Well, that's enough rambling for now, I think I'll go draft a letter I'm supposed to write for creative writing class... joi de vivre!

Labels: , , , , , , , , ,