Archiv für die Kategorie „Programmierung“

Drupal: SQL einer View manipulieren

Donnerstag, 27. Mai 2010

Manchmal sind selbst Views nicht flexibel genug. Mein konkretes Problem war, dass ich mit Organic Groups gearbeitet hatte und jede Gurppe ihre eigenen Tags (Taxonomie). Leider konnte ich es nicht so einrichten, dass ich die Tags der jeweiligen Gruppe als Block anzeigen konnte.

Ich musste den von der View erzeugten SQL nur ganz leicht abändern, damit es genau so funktioniert, wie ich mir das vorgestellt hatte. Dazu fügt man folgendes an die Datei

sites/all/modules/views/views.module

an:

function views_views_pre_execute(&$view) {
//   drupal_set_message($view->name);
   if($view->name=="Taglist") {
      $view->build_info['query']="SELECT node.nid AS nid, DISTINCT term_data.name AS term_data_name, term_data.vid AS term_data_vid, term_data.tid AS term_data_tid FROM node node  LEFT JOIN term_node term_node ON node.vid = term_node.vid LEFT JOIN term_data term_data ON term_node.tid = term_data.tid GROUP BY nid ORDER BY term_data_name ASC";
   }
}
PDF Creator    Sende Artikel als PDF an

mysql_affected_rows() analog im MySQL-Code verarbeiten

Montag, 17. Mai 2010

Beim entwerfen neuer MySQL-Proceduren komme ich immer wieder zu dem Punkt, an dem ich denke “Verdammt …. hier wären die php-mysql-Funktionen hilfreich!”

So auch heute:

Das Problem: Eine MySQL-Procedure, die beim erfolgreichen Löschen von einer bestimmten Anzahl von Einträgen einen weiteren MySQL-Befehl ausführt.

Die Lösung: ROW_COUNT() !

Hier ein Beispiel, bei dem die Einträge aus Tabelle randomOtherTable nur gelöscht werden, wenn zuvor aus Tabelle randomTable 5 Einträge entfernt wurden.

CREATE  PROCEDURE `deleteSomething`(deleteId int(11),ownerId int(11), OUT isDeleted bit(1))
BEGIN
DELETE FROM randomTable WHERE id = deleteId AND userId = ownerId LIMIT 5;
IF ROW_COUNT() = 5 THEN
BEGIN
DELETE FROM randomOtherTable WHERE other_id = deleteId;
SET isDeleted = 1;
END;
ELSE SET isDeleted = 0;
END IF;
END
PDF    Sende Artikel als PDF an

Scheme: Funktion mit internem privatem Attribut (private Variable)

Sonntag, 21. März 2010

Mit folgender Anweisung definiert man eine simple Zählfunktion in Scheme von der man beliebig viele unabhänge Zähler parallel erstellen kann.

(define (counter init)
  (local
    ((define i (- init 1)))
    (lambda ()
      (begin
        (set! i (+ i 1))
        i
      )
    )
  )
)

Wie man sieht definiert man zuerst eine Funktion namens counter die einen Parameter erwartet. Die Funktion hat intern eine lokale Variable die zu beginn auf den übergebenen Wert (vermindert um 1) gesetzt wird. Schließlich gibt die Funktion eine neue Funktion zurück die mit der eben erstellen lokalen Variable zählt. Diese interne private Variable kommt einem privaten Attribut einer Klasse einer modernen Programmiersprache nahe.
Somit ergeben folgende Anweisungen:

(define c1 (counter 0))
(define c2 (counter 1100))
(c1)
(c2)
(c2)
(c1)
(c1)
(c1)
(c2)
0
1100
1101
1
2
3
1102
PDF erstellen    Sende Artikel als PDF an

Kultspiel Plumber (Java, Open Source)

Sonntag, 21. März 2010

Dieses Spiel ist das Ergebnis eines zweiwöchigen Uni Praktikums. Es waren daran 4 Personen ca. 3h täglich beteiligt. Das Spiel ist komplett in Java geschrieben, die benötigten Librarys sind in den jeweiligen Downloads enthalten. Um das Spiel zu starten benutzen Sie bitte die plumber.bat unter Windows und die plumber.sh unter Unix.

Spiel:
plumber.tar.gz
plumber.zip

Source (mit Librarys und Dokumentation):
plumber-src.tar.gz

PDF erstellen    Sende Artikel als PDF an

Quicksort in Scheme

Mittwoch, 17. März 2010
(define (my-quicksort l)
  (if (empty? l)
      empty
      (append
       (my-quicksort (filter (lambda (x) (<= x (first l))) (rest l)))
       (list (first l))
       (my-quicksort (filter (lambda (x) (> x (first l))) (rest l)))
      )
  )
)

Aufruf z.B. mit

(my-quicksort '(8 7 5 -4 2 22 9 4 -4 4 11 1 0))

produziert

(list -4 -4 0 1 2 4 4 5 7 8 9 11 22)
PDF    Sende Artikel als PDF an

Berechnung der Determinante einer NxN Matrix in MIPS Assembler

Samstag, 6. Februar 2010

Dieser Assemblercode kann die Determinante einer NxN Matrix berechnen. Dabei wird die NxN-Matrix mit Hilfe des Laplaceschen Entwicklungssatzes in N N-1xN-1-Matrixen zerlegt (eine 4×4-Matrix wird in 4 3×4-Matrixen zerlegt, usw).

Das Programm funktioniert leider nicht für “große” Matrixen (z.B. 10×10), weil das Programm dann aus dem Heap raus schreibt. Aber für Matrixen bis 5×5 funktioniert es definitiv, eventuell auch für Größere, das habe ich aber nicht getestet.

.data

dim:
#.word 2
#.word 3
#.word 4
.word 5
#.word 10

matrix:
#2x2-Martrix; solution = -2
#.word 3, 4, 5, 6
#3x3-Matrixx; solution = 4
#.word 3, 4, 5, 9, 4, 9, 1, 2, 2
#4x4-Matrix; solution = -19
#.word 3, 4, 5, 9, 4, 9, 1, 2, 2, 1, 3, 5, 7, 9, 3, 5
#solution = 0
.word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
#.word -2, 1, 1, -2, -1, -1, -1, 3, -2, -3, 0, -1, -1, -4, -5, -5, 3, 2, -4, 1, 1, 1, 0, 3, 2, 0, 3, 3, 2, 0, 2, -3, 0, -1, 4, -1, -2, -3, 0, -1, 2, -3, -3, -5, -3, -5, -3, -1, -5, 3, 0, -5, 0, -5, -5, -1,  2,  1, -4, -1, -5, -4,  1,  1, -4,  2,  3,  4, -3, -1, 1, -2,  0, -3,  1, -5,  4,  3, -1, -4, -5,  2, -5, -2, -3, -3,  3, -2,  1, -3, 1, -1, -3,  2,  0, -5,  3,  2,  3, -5

det:    .asciiz "Die Determinante ist: "
###############################################################################

.text

main:
###################################
###################################
#Hier soll das Programm stehen
#Das Ergebnis muss am Ende in $s6 stehen.

    addi    $s7, $0, 0x10040000 # initialize default heap pointer
 
    la      $a0, matrix
    lw      $a1, dim
    jal     calcDet
    addi    $s6, $v0, 0

    j       ende

###################################
# Calculates the determinante of a NxN matrix.
# expects:  adress of array with N^2 elements in $a0
#           dimension of matrix in $a1
# returns det. of given matrix in $v0
###################################
# Documentation
# $a0   -> matrix
# $a1   -> dim
# ----------------
# $s0   -> sum of det. of matrixes
calcDet:
    # if
    slti    $t0, $a1, 2         # if $a1(=dim) < 2
    beq     $0, $t0, calcDetIf  # jump to the if part
                                # if $t0 == $t1(=1) or
                                # if 2 < dim
    # else
    lw      $v0, 0($a0)
    jr      $ra                 # jump back to caller

calcDetIf:                      # The if part
    # reduce maxtrix and call recursive for each
    # reduced matrix
    addi    $sp, $sp, -4        # get some space on stack
    sw      $ra, 0($sp)         # store return adress in stack
   
    addi    $s0, $0, 0          # initialize $s0 (sum) with 0
    addi    $t0, $0, 0          # initialize $t0 (i) with 0
   
calcDetLoop:                    # loop over all sub-matrixes
    beq     $t0, $a1, calcDetLoopDone
                                # while $t0(=i) != $a1(=dim)

    addi    $sp, $sp, -16       # get some space on stack
    sw      $s0, 0($sp)         # store sum
    sw      $t0, 4($sp)         # store $t0 (i)
    sw      $a0, 8($sp)         # store $a0
    sw      $a1, 12($sp)        # store $a1

                                # dont need to copy any adress
                                # in $a0 because its already there
                                # dont need to copy any dimension
                                # of matrix in $a1 because its already there
    addi    $a2, $t0, 0         # copy i into $a2
    jal     reduceMatrix        # jump to reduceMatrix
   
    addi    $a0, $v0, 0         # copy result adress of reduceMatrix
                                # into argument register for recursive call
    sub     $a1, $a1, 1         # $a1 = dim - 1
    jal     calcDet             # call myself recursively
   
    lw      $a1, 12($sp)        # load $a1
    lw      $a0, 8($sp)         # load $a0
    lw      $t0, 4($sp)         # load $t0 (i)
    lw      $s0, 0($sp)         # load sum
    addi    $sp, $sp, 16        # clean up the stack

    addi    $t2, $0, 1          # initialise pow(er) with 1
    and     $t1, $t0, 1         # $t1 = $t0 & 0x00000001
    beq     $t1, $0, calcDetLoopJump
                                # skip one line, if $t0 % 2 = 1
    addi    $t2, $0, -1         # set power to -1
calcDetLoopJump:               

    addi    $t1, $0, 4          # $t1 = 4 (because one word = 4 bytes)
    mult    $t0, $t1            # i * $t1(=4)
    mflo    $t3                 # get result in $t3
    add     $t3, $a0, $t3       # add calulated offset to start adress of matrix
    lw      $t3, 0($t3)         # load value at calulated adress

    mult    $t2, $t3            # power * (i-th element in matrx (always in first row))
    mflo    $t4                 # get result in $t4
    mult    $t4, $v0            # multiply calcDet-result with calculated stuff
    mflo    $t4                 # get result in $t4
    add     $s0, $s0, $t4       # add to sum

    addi    $t0, $t0, 1         # $t0++ or i++

    j       calcDetLoop


calcDetLoopDone:                # loop finished, calculated all matrixes
    addi    $v0, $s0, 0         # copy sum into return register

    lw      $ra, 0($sp)         # load return adress from stack
    addi    $sp, $sp, 4         # get some space on stack

    jr      $ra
###################################


###################################
# Extracts _one_ (N-1) matrix from a
# NxN matrix. The argument
# $a2 says which (N-1) matrix should
# be returned.
# expects:  adress of array with N^2 elements in $a0
#           dimension of matrix in $a1
#           index of the smaller matrix (0-based) in $a2
# returns adress of (N-1) matrix in $v0
###################################
# Documentation
# $a0   -> matrix
# $a1   -> dim
# $a2   -> index of matrix that should be returned
# ----------------
# $s0   -> dim - 1
# $s1   -> counter for the current position in the SOURCE matrix
# $s2   -> counter for the current position in the TARGET matrix
reduceMatrix:
    addi    $s0, $a1, -1        # $s0 = dim - 1
    mult    $s0, $s0            # $s0*$s0 or
                                # (N-1)^2 or (dim-1)^2
                                # is also the size of the
                                # new matrix
    mflo    $t1                 # get result into $t1
                                # $t1 contains now the number of words required
    addi    $s1, $a0, 0         # copy start adress of source matrix in $s1
    addi    $s2, $s7, 0         # save current position of heap pointer in $s2
    addi    $v0, $s7, 0         # copy target array adress in return register
    addi    $t0, $0, 4          # set $t0 = 4
    mult    $t1, $t0            # multiply $t0(=4) * $t1(=(dim-1)^2)
                                # -> amount of necessary bytes
    mflo    $t0                 # copy result in $t0
    add     $s7, $s7, $t0       # get (N-1)^2 space of heap

    addi    $t0, $0, 4          # set $t0 = 4
    mult    $a1, $t0            # $a1(=dim)*$t0(=4)
                                # number of bytes that must be skipped to
                                # skip the first row of source matrix
    mflo    $t0
    add     $s1, $s1, $t0       # skip dim-elements or
                                # skip the first row of source matrix
    addi    $t0, $s0, 0         # initialize counter for loop 1; used as i
    add     $t2, $t0, $a2       # $t2 = $t0 + $a2 or
                                # $t2 = i + index
reduceMatrixLoop1:              # loop 1
    beq     $t2, $t0, reduceMatrixLoop1Done
                                # while index != i

    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4

    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ (i++)
    j       reduceMatrixLoop1   # jump up to the beginning of the loop
reduceMatrixLoop1Done:          # endloop 1
reduceMatrixLoop2:              # loop 2
    mult    $a1, $a1
    mflo    $t1
    beq     $t0, $t1, reduceMatrixLoop2Done
                                # while i < dim^2

    addi    $s1, $s1, 4         # skip one element in SOURCE matrix
    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
   
    mult    $a1, $a1            # $a1^2 or dim^2
    mflo    $t2                 # get the result in $t2
    sub     $t2, $t2, 1         # sub 1 from $t2, because I want to compare
                                # it with $t0 (0-based) or
                                # (dim^2)-1
    sub     $t2, $t2, $t0       # $t2-$t0 or (dim^2)-1-i
    # if
    slt     $t3, $t2, $s0       # (dim^2)-1-i < dim-1 or
                                # if $t3 == 1, you reached the last
                                # row and already skipped
    beq     $t3, $0, reduceMatrixLoop2Else
                                # jumps, if (dim-1)^2 - i < dim - 1 is false
                                # in human words: if the programm
                                # is NOT in the last row of the source matrix
    # if case
    # copy the last elements of source into target and exit function! :)
    mult    $a1, $a1            # dim^2
    mflo    $t2                 # get result in $t2
reduceMatrixLoop2Loop1:
    beq     $t2, $t0, reduceMatrixLoop2Done
                                # jump if dim^2-1 == i or jump if
                                # end of source matrix is reached
   
    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4

    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2Loop1
                                # jump up again, because its a loop!

    j       reduceMatrixLoop2Endif
                                # leave if case
                                # never used because if loop is finished
                                # it will jump to the end of the function

reduceMatrixLoop2Else:          # else case
    # copy dim - 1 elements
    add     $t2, $t0, $s0       # $t2 = $t0(=i) + $s0(=dim-1)
reduceMatrixLoop2ElseLoop:
    beq     $t2, $t0, reduceMatrixLoop2
                                # if $t2 = $t0 jump to main loop

    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4
   
    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2ElseLoop
                                # jump up to the beginning of the loop

reduceMatrixLoop2Endif:         # endif


    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2   # jump up to the beginning of the loop
reduceMatrixLoop2Done:          # endloop 2
    jr      $ra                 # jump to caller function
                                # return value ($v0) is set at beginning
                                # of this function
###################################

###################################
###################################

ende:
#Ausgabe

la $a0 det
li $v0 4
syscall

move $a0, $s6
li $v0, 1
syscall

###################################
#Ende
li $v0, 10
syscall

PDF erstellen    Sende Artikel als PDF an

Ubuntu: Eclipse Buttons nicht klickbar

Freitag, 4. Dezember 2009

Ich habe heute versucht auf meinem Ubuntu 9.04 mit einem frischem Eclipse ein Projekt mittels CVS in meinen workspace zu laden. Leider war es nicht möglich auf den next Button im CVS Dialog zu klicken. Auch der back Button war “kaputt”, der cancel Button funktionierte aber dummerweise!

Wenn man, bevor man Eclipse startet, folgende Umgebungsvariable setzt funktioniert es wieder:

export GDK_NATIVE_WINDOWS=true
PDF erstellen    Sende Artikel als PDF an

Wichtige Scheme Funktionen

Samstag, 28. November 2009

foldr und foldl

Die Funktion fold wendet eine Funktion auf jedes Element einer Liste an, speichert das Ergebnis in einer neuen Liste und gibt diese zurück.
foldr liest die Liste von links nach rechts ein. foldl von rechts nach links, also falsch herum. Daraus ergibt sich auch gleich eine sehr hilfreiche Anwendung von foldl:

> (foldl cons empty (list 1 2 3 4 5))
(list 5 4 3 2 1)

Es invertiert also einfach die übergebene Liste.

Ein anderes Beispiel (bei dem es keinen Unterschied macht, ob man foldr oder foldl nutzt):

> (foldr + 0 (list 1 2 3 4 5))
15

map

map wendet eine Funktion auf alle Elemente einer Liste an, und gibt die jeweiligen Ergebnisse als neue Liste zurück.

> (map (lambda (x) (* x x)) (list 1 2 3 4 5))
(list 1 4 9 16 25)

filter

filter filtert eine Liste. Dazu übergibt man eine Funktion die entweder true zurückgibt, wenn das gerade getestete Element in die neue Liste soll, oder eben false, wenn es nicht in die neue Liste soll.

> (filter even? (list 1 2 3 4 5))
(list 2 4)
PDF Download    Sende Artikel als PDF an

Scheme Kurs – Teil 7: IO

Samstag, 28. November 2009

Bis jetzt habe ich noch nichts zur Ein- und Ausgabe von Daten in Scheme gesagt. Simple Ausgaben kann man realisieren indem man einfach die Variable hinschreibt, ohne sie auf eine Funktion anzuwenden.

(define hallo-welt "Hallo Welt!")
hallo-welt

Es gibt aber auch eine Menge Funktionen mit denen man Ausgaben bewältigen kann. Darunter ist das aus C/C++ bekannte printf.
Ich möchte nicht näher auf die Ausgabefunktionen eingehen, da sie keine große Schwierigkeit darstellen. Alle nötigen Informationen dazu findet man unter:
http://download.plt-scheme.org/doc/html/reference/Writing.html

Das gleiche gilt für die Eingabe von Daten. Alle nötigen Informationen findet man hier:
http://download.plt-scheme.org/doc/html/reference/Reading.html

Ein kleines Beispiel zum Abschluss:

(printf "Bitte geben Sie Ihren Name ein: ")
(define name (read))
(printf "Hallo ~v" name)
PDF Drucker    Sende Artikel als PDF an

Scheme Kurs – Teil 6: set!

Samstag, 28. November 2009

Bis jetzt haben wir in Scheme nur mit Konstanten gearbeitet, die man einmal mit einem Wert belegen kann.
Mit set! kann man aber den Wert einer Variable ändern. Davor muss man die Variable aber wie eine Konstante mit define erstellen, dass heißt, wir haben bis jetzt auch schon mit Variablen gearbeitet, nur konnten wir deren Wert noch nicht ändern.

(define i 0)
(set! i 1)
(set! i (+ i 1))

Die Variable i hat nach der ersten Zeile den Wert 0, da sie mit define mit dem Wert 0 definiert wird.
Nach Zeile 2 ist der Wert von i 1, da wir es explizit mit set! festlegen.
In Zeile 3 nutzen brechnen wir den neuen Wert von i mit dem alten (oder bisherigem) Wert von i. i ist also nach dieser Zeile 2.

Das Ausrufezeichen ist eine Scheme Konvention. Man muss sich nicht daran halten, aber es ist extrem sinnvoll. Denn so kann jeder sofort erkennen dass eine Funktion eine oder mehrere Zuweisungen vornimmt.
Wenn man also eine Funktion schreibt, die einen Parameter verändert, dann sollte man an den Funktionsname ein Ausrufezeichen anhängen.

PDF Download    Sende Artikel als PDF an