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

22 Mar 2013

C shared objects exported to python (ctypes)

Some C Projects need a quick extension which is not performance relevant. Sometimes I wish to use python because it is available on all modern *nix systems. Also, programming in python is very efficient.

To solve this I have created a small example project which puts the functionality into a shared object (dll in windows-speak) which can be used from python.

The library:

lib.c
This library contains a simple function which appends the string "->aaa" to an existing string. This is an interesting example since it involves dynamic memory allocation and pointers.


#include <stdlib.h>
#include <string.h>
#include "lib.h"

//int main() {return 0;}

char *append(char* str) {
 //char *n = "";
 char *b = "->aaa";
 char *n = malloc(strlen(str) + strlen(b) + 1);
 n[0] = '\0';
 strcat(n, str);
 strcat(n, b);
 return n;
}


lib.h
char *append(char* str);


test.c
used for testing the the library from C.

#include <stdio.h>
#include "lib.h"

int main(int argc, char* argv[]) {
 printf("%s\n", append(argv[1]));
 return 0;
}

Compiling
#!/usr/bin/env bash
gcc -std=c99 -Wall -c -fPIC lib.c -o lib.o
gcc -std=c99 -Wall -shared -Wl,-soname,libt.so -o libt.so lib.o
gcc -std=c99 -Wall -o test test.c -L. -lt
rm lib.o


pylibt.py
Because python uses dynamic data types we need to give some hints about data types. Also pointers need to be declared.
#!/usr/bin/env python

from ctypes import *

cdll.LoadLibrary("./libt.so")
_libt = CDLL("libt.so")

#def initpylibt():
# pass

def append(s):
 _append = _libt.append
 _append.argtypes = [c_char_p]
 _append.restype = c_char_p
 return _append(s)


test.py
let's use the python module from a script.

#!/usr/bin/env python

import pylibt

ret = pylibt.append("0123456789as dfasdf asdf asdf asdf asf asdf")
print ret


4 Feb 2013

nag-o-meter



This is our new status display of the Service Monitoring System I have built up during the last years. My cow-orkers keep forgetting to act upon warnings. I thought I could add some extra motivation for fixing errors in a timely manner (note the nice sound it makes :) ).

A little bit of python, a little bit of *nix voodoo glued together with a bash script - done.



10 Oct 2012

Analyzing mavlink packages

I am currently on the search for a simple way to graph and analyze ArduPilot Mega telemetry logs. APM uses mavlink as protocol.

Andrew Tridgel has written a nice python library for the mavlink protocol which is called (who would have guessed?) pymalink.

pymavlink comes with a couple of examples which are quiet usefull (check the pymavlink/examples folder).

mavlogdump.py will generate an ASCII representation of the binary data structs. This outpu can be easily converted with sed, grep, awk, etc. for analysis in other programs.

mavplot.py can be used to graph data from the file.

I am currently analyzing a crash of a fixed wing drone. It's far away and all I have is a telemetry log file. mavplot.py could nicely display, that the drone stalled shortly after the takeoff, still unsure why.

mavplot.py example usage:

$ pymavlink/examples/mavgraph.py --planner --mav10 sander.tlog \
  VFR_HUD.airspeed 'VFR_HUD.groundspeed' '(SERVO_OUTPUT_RAW.servo1_raw-1000)/100' \
  '(SERVO_OUTPUT_RAW.servo2_raw-1000)/100' '(SERVO_OUTPUT_RAW.servo3_raw-1000)/100' \ 
  '(SERVO_OUTPUT_RAW.servo4_raw-1000)/100' ATTITUDE.roll ATTITUDE.pitch ATTITUDE.yaw \
  'VFR_HUD.alt/10'
 

The nice thing about these tools is, that parameters can contain python expressions which means, all the values can be adjusted to a specific need.


5 Feb 2012

Python - Convert google Calendar ICS to CSV

#!/usr/bin/env python

import urllib2
from icalendar import Calendar#, Event

outfile = "output.xls"
theurl = 'https://...'
username = 'xxx'
password = 'xxx'

QUOTE='"'
DELIM_FIELD = ","
DELIM_ROW   = "\n"
DATE_FORMAT = "%d.%m.%Y"
# a great password

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
# this creates a password manager
passman.add_password(None, theurl, username, password)
# because we have put None at the start it will always
# use this username/password combination for  urls
# for which `theurl` is a super-url

authhandler = urllib2.HTTPBasicAuthHandler(passman)
# create the AuthHandler

opener = urllib2.build_opener(authhandler)

urllib2.install_opener(opener)
# All calls to urllib2.urlopen will now use our handler
# Make sure not to include the protocol in with the URL, or
# HTTPPasswordMgrWithDefaultRealm will be very confused.
# You must (of course) use it when fetching the page though.

pagehandle = urllib2.urlopen(theurl)
# authentication is now handled automatically for us

if pagehandle.code != 200:
 print "Something went wrong. HTTP response code: %s" % pagehandle.code

fp = open(outfile,'wb')
fp.write(QUOTE)
fp.write("Start")
fp.write(QUOTE)
fp.write(DELIM_FIELD)
fp.write(QUOTE)
fp.write("End")
fp.write(QUOTE)
fp.write(DELIM_FIELD)
fp.write(QUOTE)
fp.write("Days")
fp.write(QUOTE)
fp.write(DELIM_FIELD)
fp.write(QUOTE)
fp.write("Summary")
fp.write(QUOTE)
fp.write(DELIM_ROW)

cal = Calendar.from_string(pagehandle.read())
for component in cal.walk():
 if component.name == "VEVENT":
  fp.write(QUOTE)
  fp.write(component['dtstart'].dt.strftime(DATE_FORMAT))
  fp.write(QUOTE)
  fp.write(DELIM_FIELD)
  days = (component['dtend'].dt-component['dtstart'].dt).days
  fp.write(QUOTE)
  if (days > 1):
   fp.write(component['dtend'].dt.strftime(DATE_FORMAT))
  fp.write(QUOTE)
  fp.write(DELIM_FIELD)
  fp.write(QUOTE)
  fp.write(str(days))
  fp.write(QUOTE)
  fp.write(DELIM_FIELD)
  fp.write(QUOTE)
  fp.write(component['summary'])
  fp.write(QUOTE)
  fp.write(DELIM_ROW)

fp.close()

11 Oct 2011

Succesfull flight in Auto Mode

Finally the airspeed sensor is working, here is a plot of the last autonomous flight of the funjet (APM Auto mode):



3 Aug 2009

Mac OSX

I got this Mac Mini brought in today for testing a new screen capturing solution we might implement.

It turned out to be a very nice experience. I knew these macs are shiny but they seem to be pretty useful too! After some poking around I found out there is an X Server available, an ssh client was there too. So I could instantly launch some remote X apps.

It turned out, that these macs ship by default with Python (2.3.something) and there is a nice IDE called Xcode which is offered by Apple for free of charge.

Furthermore, what got me excited, was the fact that there are many command line tools and a bash (by default). It is possible to read out information about the system's hardware and configuration via «system_profiler» which seems similar to «wmic» on Win32 and «/proc» on linux.

My next laptop will be a mac book!

8 Jan 2009

Django Project creation check list

1) (Optional) Create new Project: django-admin.py startproject projectname
2a) Add to Apache config (replace evreything within <>):

<Location "/<location>/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE ikariam.settings

PythonDebug On # disable this on a production site!

PythonPath "['<path to project root>'] + sys.path"
</Location>
# media files
Alias /media "/usr/lib/python2.4/site-packages/django/contrib/admin/media"

2b) Optionally run the python webserver: python manage.py runserver 8080
3) settings.py: Set TIME_ZONE = 'Europe/Zurich' and LANGUAGE_CODE = 'de-CH'
4) settings.py: Set Database config
5) settings.py: Add project
INSTALLED_APPS = (
'mysite.books', # or
'mysite'
)


6) example Model:
# $Id$
#
# if not specified, primarykeys will be generated automatically. A field
# with the name `id` is added as auto increment field. So do not specifically
# declare primarykeys manually unless needed.
# http://docs.djangoproject.com/en/dev/topics/db/models/#automatic-primary-key-fields
from django.db import models

class Schedule(models.Model):
# id = models.AutoField(primary_key=True)
start = models.TimeField()
end = models.TimeField()
lastmod = models.DateTimeField(auto_now=True)
inserted = models.DateTimeField(auto_now_add=True)

def __unicode__(self):
return self.start + " - " + self.end

class Price(models.Model):
# id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
description = models.CharField(max_length=250)
lastmod = models.DateTimeField(auto_now=True)
inserted = models.DateTimeField(auto_now_add=True)

def __unicode__(self):
return self.name

class Event(models.Model):
# id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
start = models.DateField()
end = models.DateField()

schedule = models.ForeignKey(Schedule)
price = models.ForeignKey(Price)

lastmod = models.DateTimeField(auto_now=True)
inserted = models.DateTimeField(auto_now_add=True)

def __unicode__(self):
return self.name

class Meta:
# db_table = u'ana_event'
ordering = ["name"]
verbose_name = "Event"
verbose_name_plural = "Events"

class Admin:
pass
# list_display = ("name", "start", "end")
# search_fields = ('name',)
# list_filter = ('name')
# ordering = ('x', 'y')

7) Check db creation and create Database:
python manage.py validate # validate db structure
python manage.py sqlall projectname # show creation SQL
python manage.py syncdb # create Database

8) Install the admin application. Do this by adding "django.contrib.admin" to your INSTALLED_APPS setting.
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'ana'
)

9) Install url redirector
from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
# Example:
# (r'^ana/', include('ana.foo.urls')),

# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),

# Uncomment the next line to enable the admin:
# (r'admin/$', include('django.contrib.admin.urls')),
(r'^ana/admin/(.*)$', admin.site.root),
)

10) Write an aemin definition for the objects
from ana.models import Event
from django.contrib import admin

class EventAdmin(admin.ModelAdmin):
# fieldsets = [
# (None, {'fields': ['question']}),
# ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
# ]

# display these fields in the listing
list_display = ("name", "start", "end")

# add filter to the right of a listing
#list_filter = ['name']

# Let's add some search capability:
search_fields = ['name']

# Finally, because Poll objects have dates, it'd be convenient
# to be able to drill down by date. Add this line:
# date_hierarchy = 'pub_date'

# liste verkleinern
# def queryset(self, request):
# return self.model._default_manager.filter(ocean=0)

admin.site.register(Event, EventAdmin)

6 Jan 2009

Django

As everyone I became infected by Python lately. Django seems to be a nice web development framework which eases the pain of everyday tasks quiet nicely.

Luckily «The Django Book» is freely available in HTML. However, I hate going through the TOC over and over again, an RSS Feed in Firefox's Bookmark toolbar saves me 1-2 clicks for every lookup.



Here ist the TOC RSS.