Category Archives: Allgemein

CORS (cross origin resource charing) using cherrypy

Cherrypy allows to define functions to be so called „tools“ (cherrypy docs). These helper functions might be „hooked“ at various processing points within cherrypys serving process: on_start_resource, before_request_body, before_handler, before_finalize, on_end_resource, before_error_response, after_error_response, on_end_request.

Making the tool is working straight forward. According to the working draft http://www.w3.org/TR/cors/ cross origin access allowance needs to be declared within the response header (see RFC for further information on CORS headers). The following example will add a response header to allow CORS to any („*“) client; change the ‚*‘ to an uri-scheme have provide more granular scaling.

import cherrypy

def CORS():
…cherrypy.response.headers[„Access-Control-Allow-Origin“] = „*“ #

attaching the function to a process stage hook needs to be done in the main proc:

if __name__==“__main__“:
(…)
…cherrypy.tools.CORS = cherrypy.Tool(‚before_finalize‘, CORS)

# insert tool declaration within def main() or even directly
# before cherrypy.tree.mount command to prevent Error like

If you try to declare the toll earlier an TypeError starting with:
The ‚CORS‘ Tool does not accept positional arguments … is likely to be thrown.

Like with other cherrypy tools you might use them globally by adding „cherrypy.tool.CORS.on : True“ to the general.configs or by using the decorator @cherrypy.tools.CORS right after the exposure decorator of a
page/wsgi def.

Eine Linkseite fürs „Cloud Coding“

In dieser Post werde ich kurz ein paar Links aufführen, die direkt zu verschiedenen online Umgebungen für das Bearbeiten und Testen von Code leiten.

Zuerst einmal HTML5 und Javascript:

http://jsfiddle.net/
ist eine prima javascript Umgebung zum Ausprobieren und Versuchen. Es gibt eine saubere Trennung von HTML-DOM, CSS, Javascript und zur Darstellung des verarbeiteten Resultats. Da jsFiddle als webapp im Browser läuft, ist alles möglich, was vom Browser unterstützt wird. Funzt auch mit nur wenigen Ausnahmen mit dem iPad – also wirklich eine gute Möglichkeit Javascript-Code cross zu testen.

Ist der Code dann fertig, kann man ihn unter http://jsapp.us/
mit einer nodeJS Engine auf die Eignung als browser side JS testen.

http://www.cdnjs.com/
ist eine (derzeit kostenfreie) hosting-Plattform für bekannte (und exotische) Javascript-Frameworks und -Extensions. Die Plattform verspricht hohe Performanz und Optimierung (eventuell zukünftig auch durch Kombination von Frameworks wie jQuery udn jQuery UI o.ä.)

Als besonders erwähnenswert erscheint mir unter den Exoten D3 , ein Framework zur Erzeugung dynamischer Datendarstellungen mit javascript, das zur Manipulation und Erzeugung auf CSS, DOM und SVG zugreift. (By the way: schade, dass so wenige Dev sich mit SVG auseinandersetzen – SVG sollte sich für HTML-DOM Profis eigentlich „natürlicher“ anfühlen als CANVAS, trotzdem ist es erheblich weniger im Einsatz.

Für alle, die ihren Horizont erweitern und eine neue Programmiersprache lernen wollen:
Über 20 verschiedene Programmiersprachen online coden und ausprobieren kann man bei http://ideone.com/
Da ist wirklich von den diversen C Dialekten bis zu Javascript, Ruby, Python, …. alles dabei – sogar Assembler, wer’s braucht.
Zu jeder Sprache gibt es auch ein paar Zeilen sample Code zum Vergleichen. Die Programme werden auf dem Server ausgeführt, wenn man auf den m. E. etwas unglücklich platzierten „submit“-Button klickt. Es öffnet sich eine neue Seite, auf der Code, Input und Output in textareas dargestellt sind, und auch ein weiteres Editieren möglich ist.

starmap

TaTa …
2nd Athmosphere, ein Geschicklichkeits- und Gedächnistrainings-Spiel ist fertig geworden.
Tatsächlich wird es 2nd Athmosphere als iPad-Game im iTunes-Store geben, sobald Apple es durch gewunken hat, und eine html5 Versionmit etwas eingeschränkten Features. Auf dem iPad gibt’s später noch mehr Umgebungsgrafik und eine Hall of Fame (online eventuell im Apple Game-Center).

Es fehlt noch eine abschließende Komprimierung aber im Wesentlichen steht die Demo.

Und aus 2nd Athosphere hier die Routine, die hübsche zufällige Sternenkarten auf einem canvas-Element erzeugt:



// prepare starmap in an existing HTML-DIV; Name-> starMapParentDOMElement
function starMap(){
  var width = window.innerWidth;
  var height = parseInt(window.innerHeight);
  var colr = function(){return parseInt( 255-Math.random()*70);};
  var grad = function(winkel){return (winkel * Math.PI / 180);};
  var nStars = function(){return parseInt(100 + Math.random()*500);};
  var cv = document.createElement('canvas');
  cv.setAttribute('width',width+'px');
  cv.setAttribute('height',height+'px');
  cv.style.position = "absolute";
  cv.style.top = "0px";
  cv.style.left = "0px";
  document.getElementById(starMapParentDOMElement).appendChild(cv);
  var ctxx = cv.getContext('2d');
  
  // darkblue background
  ctxx.fillStyle = "rgba(10,10,30,1.0)"; 
  ctxx.fillRect(0,0,width,height);
  ctxx.fill();
 
  for(var i=nStars();i;i-=1){
    // Stars
    ctxx.fillStyle = "rgba("+[colr(),colr(),colr()].join(',')+",0.8)";
    ctxx.beginPath();
    var x = Math.random()*width;
    var y = Math.random()*height;
    var r = 0.1+2.5*Math.random();
    ctxx.arc(x,y,((r>1.7)?r:0.5),0,grad(360),false);
    ctxx.closePath();
    ctxx.fill();
    // Nebel & Fog
    ctxx.fillStyle = "rgba("+[colr(),colr(),colr()].join(',')+",0.008)";
    ctxx.beginPath();
    x = Math.random()*width;
    y = Math.random()*height;
    r = 40 + 70* Math.random();
    ctxx.arc(x,y,r,grad(Math.random()*360),grad(180+Math.random()*180),false);
    ctxx.closePath();
    ctxx.fill();
  }
}

nStars beeinflusst die Zahl der Sterne.
In den Zeilen

var r = 0.1+2.5*Math.random();
und
ctxx.arc(x,y,((r>1.7)?r:0.5),0,grad(360),false);
wird auf das Erscheinungsbild der Sterne Einfluss genommen.
r = 40 + 70* Math.random();
ctxx.arc(x,y,r,grad(Math.random()*360),grad(180+Math.random()*180),false);

wirken auf die Nebel.

Und heraus kommen feine fenstergrosse Sternenkarten.

Die Kreise und gelben Strings sind natürlich nicht Teil der Sternenkarte sondern gehören zum Spiel.

_underscore.js

Eine interessante Javascript Utility-Sammlung für alle Arten von (seriellen) Objekten ist die _underscore.js von documentcloud (zu finden unter http://underscore.js.

Eine ganze Reihe von Funktionen für die Objekt-Manipulationen, die in anderen Sprachen zur Verfügung stehen, fehlen in Javascript. _underscore.js erweitert das Funktions-Angebot und stellt über 60 Utilities zur Verfügung.

Die Bibliothek nutzt dabei die nativen Funktionen aus ECMAScipt 5 soweit bereits verfügbar.

Weitere Funktionen können mit Hilfe der Erweiterungsfunktion _.mixin in die library zur Laufzeit hinzugeladen werden. Die folgenden Funktionen können so ’nachgeladen‘ werden:

sum: sum of numerical object elements
mean: aritmethic mean of numerical object elements
median: median (center element) of a sorted object
nrange: enhanced range function returning an array of the specified range

Um die Library zu nutzen, ist erst underscript mit <script src=“ ….. /underscript.js“ ><script> zu laden und dann das Addon mit den neuen Funktionen <script src=“ ….. /underscriptAddon.js“ ><script> darüber zu laden. die functioen stehen dann mit underscore mixin Syntax z.B. _([1,3,2,4,1]).sum() zur Verfügung.

Das mixim Plugin ist im Wiki (Stichwort mixin-Plugin catalog) gelinkt oder kann bei github herunter geladen werden: https://gist.github.com/1670507

RplotNode

speed Comparison: File IO von einfachen Objekten mit python 2.7 vs. node.js

Ich habe bisher fast alles mit Python lösen können. Dennoch konnte gerade beim Arbeiten mit Objekten, die viele Elemente beherbergen (z.B. der iExam-Fragenpool) eine hohe Performance nur mit Tricks wie multi-threading und subprocessing zum Verteilen auf die verschiedenen Prozessoren erreicht werden und selbst dann hatte ich immer den Eindruck, dass die Serialisierung mit cPickle etwas bremste.

node.js hat mich in ersten Tests mit erstaunlicher Performanz überrascht und ich habe mich gefragt, wie es sich im Umgang mit Objekten im direkten Vergleich schlagen wird.

Erst einmal mussten ein paar Zeilen Code her, um die beiden Kontrahenten fair vergleichen zu können.


#! /usr/bin/python
# python code
# start with >> python2.7 testFileIO.py
import os, sys
import random
import cPickle
import time

datapth = '/Users/usrName/Desktop/nodeWork/Testdaten'
outpth = '/Users/usrName/Desktop/nodeWork/testErgPy'

# prepare & save Testdaten 
with file(datapth,'wb') as outFle:
  print >> outFle, ''.join( map(chr, [random.randint(0,255) for i in xrange(150)]) )

ergs = dict()
for i in xrange(10000):
  ergs['%05i'%i] = '000000'

# Zeitmessung starten

sTM = int(time.time()*1000)
ssTM = sTM

for i in xrange(10000):
  r = file(datapth)
  erg = r.read()
  tm = int(time.time()*1000)
  ergs['%05i'%i] = tm-sTM
  with file(outpth,'wb') as ofle:
    cPickle.dump(ergs,ofle)
  ergs = cPickle.load(file(outpth))
  sTM = tm

print 'python needed: %s ms'%(tm-ssTM)

Durch die Vorbelegung der Dictionary-Elemente bleibt der IO-Aufwand über die Aufgabe weitgehend gleich. Da die tatsächliche Zeitdifferenz im ergs-Objekt abgelegt ist, kann das auch grafisch belegt werden.
Wie man sieht, beherbergt der Pythoncode keine Tricks (s.o) – um den direkten Vergleich mit Node.js zu erreichen, das ja bekanntlich in einer Schleife auf einem Prozessor läuft.

Unten steht die selbe Routine in coffeescript. Die intFormat(zahl, zeros) erzeugt eine Anmutung der Integerdarstellung im Formatstring bei Python ‚%05i’%i


#! /usr/local/bin/coffee
# coffeescript code auf node.js v0.6.7
# start with >> coffee testFileIO.coffee 

fs = require 'fs'

cntr = 0
fle = ''
datapth = '/Users/usrName/Desktop/nodeWork/Testdaten'
outpath = "/Users/usrName/Desktop/nodeWork/testErg"
ergs = {}

intFormat = (zahl,zeros) ->
  zahl = ''+zahl
  prefx = ''
  len = zahl.length
  for i in [0...(zeros-len)]
    prefx += "0"
  prefx+zahl
  
for i in [0...10000]
  ergs[intFormat(i,5)] = '000000'

# Zeitmessung starten

altTM = new Date()
altTM = altTM.getTime()
ssTM = altTM

for i in [0...10000]
  erg = fs.readFileSync datapth,encoding='utf-8'
  tm = new Date()
  tm = tm.getTime()
  ergs[intFormat(i,5)] = tm - altTM
  fs.writeFileSync outpath,JSON.stringify(ergs) 
  altTM = tm

console.log "node.js time gone: #{ tm-ssTM } ms"

Die Aufgabe für beide bestand also darin, in einer Schleife zehntausendmal ein dictionary Object mit 10.000 Einheiten aus einem File zu laden, ein Element zu ändern (float hineinschreiben), das dictionary zu serialisieren und wieder abzulegen.

Und hier ist das Ergebnis (gemittelt aus 10 Durchläufen):

Das File, das Python bei der Serialisierung mit cPickle anlegt (39.000 Zeichen/ 319kb), ist 3x größer als die JSON-Datei, die Node erzeugt (20.000 Zeichen/ 100kb). Das kann die unterschiedliche Performanz zum Teil erklären. Aber die Aufgabe war ja gerade, ein großes Objekt frequent zu laden und zu manipulieren – genau hier zeigte sich die V8javacript engine von node.js deutlich im Vorteil.

Fazit:
Node.js war im Mittel praktisch 5.37 mal schneller als Python (MacPro 3,1 Xeon (8x, 2.8 GHz)).

update on MacBook Pro (2.26 GHz Core2Duo): node.js 5.06 mal schneller als Python 2.7.2

var Code = hopefully_Helpfull

Moin, Moin

Diese Seite ist dafür gedacht, der „Community“ der Coder, von denen ich profitiert habe, etwas zurückzugeben: Code in verschiedenen Idiomen, der im Laufe der Zeit entstanden ist. Die Liste der Software, mit der ich arbeite wird immer länger – aber das ist ja bei Euch allen so: Python 2.x, Javascript (ECMA-Script), Obj-C 4IOS, Java, Visual Basic und ChipMunk-Basic (great for fast hacks) ferner HTML5 (SVG, CANVAS), R, LaTex.

Neu dazu kommen derzeit Coffeescript mit node.js (V8JS) – striking fast!

Bitte beachten: Ich bin überzeugt, dass mein coding style vielen von Euch aufstossen wird. Ich habe das Programmieren als Teenager gelernt, d.h. vor 30 Jahren mit mz80k- BASIC und Assembler auf Kompakt-Kassetten. Folge ist, dass ich „imperativ“ programmiere und „moderne“ Techniken, wie z.B. Abstraktion durch Objektbasierung nur einsetze, wenn ich diese Strukturen innerhalb meines Frameworks tatsächlich global verwende. Das mag die Wiederverwendbarkeit in anderer Umgebung erschweren, aber es hat sich in meinen Projekten als tragfähig erwiesen. Ähnlich ist es mit der Verwendung von Frameworks und Datenbanken. Ich arbeite mit SQLite nur dann, wenn sich eine Daten-Ablage in arrays, dictionaries, selections oder in abstrakteren serialisierbaren Objekten nicht anbietet – das heißt, erst bei vielen Tausend Datensätzen. Um (JS-) Frameworks mache ich einen weiten Bogen, und implementiere das, was ich brauche, lieber selbst. Das hält den overhead klein und macht die Software unabhängig von fremden Paradigmen- und Versionswechseln – zeitloser sozusagen. Meine Software ist auf den Zielservern (i.d.R. Apple MP DesktopsPCs mit Mac OSX auf denen Apache oder Cherrypy-SeverSW läuft – ab 2011 auch node.js) performance-optimiert und durch einen Reihe von Stresstests gegangen, bevor ich sie benutze.

Mit anderen Worten, keine Gewähr und bestenfalls für Euch, liebe Leser, eine vage Hoffnung, dass Ihr auf dieser Seite etwas Nützliches findet.

Andreas

Comment are welcome.