Plagiate in (Java) Quellcode finden

fadingLeider scheint bis jetzt niemand eine wirklich freie, gute und lokale Code-Plagiats-Applikation entwickelt zu haben. Ich wäre sehr gespannt, was AST-Vergleiche bringen würden. Nundenn, ein erster und unaufwändiger Vergleich von Quellcode (und bei Programmierprüfungen eventuell mit alten Lösungen) kann schon vieles zeigen. Die einfachste Variante, die ich bis jetzt gefunden habe, ist der CPD copy-paste-detector, der Teil des PMD-Packages ist.

Der CPD braucht nicht installiert zu werden: Herunterladen, entpacken und den Pfad bei den Einstellungen in Control Panel\System and Security\System\Advanced system SettingsAdvancedEnvironmentVariables setzen.

Pfad Setzen in Windows

Pfad Setzen in Windows

Danach eine Kommandozeile öffnen den Computer um Folgendes bitten:

cpd --encoding utf8 --minimum-tokens 200 --files E:\Pruefungen\IB13a\VMKN-226\files > similarities.txt

Das kann auch auf eine Sprache eigegrenzt werden:

cpd --language java --encoding utf8 --minimum-tokens 200 --files E:\Pruefungen\IB13a\VMKN-226\files > similarities.txt

Nun stehen in der Datei similarities.txt die Teile der Dateien, die gleich sind. Weitere Optionen können auf der CPD-Page gefunden werden.

Upload und Speichern von Dateien in einer DB mit einer C# ASP.NET MVC Applikation

uploadMVC mit C# macht ja grundsätzlich Spass (obwohl für einige Leute ja auch Auspeitschen angenehm ist :)). Ich habe ein paar spezielle Aufgaben zum Realisieren gefasst und gebe hier ein paar Weisheiten von mir, die wahrscheinlich allgemein bekannt sind und ich einfach nur nicht finden kann.

In diesem Beitrag wird beschrieben, wie man verschiedene Medien (Bilder, Filme, Audio) hochladen, in einer Datenbank speichern und (mit HTML 5) wieder darstellen kann. Ich gehe aus von einer frisch erstellten und herausgeputzten MVC 3 Webapplikation.

Am Schluss sollte die Liste in etwa so aussehen:

Liste der Medien

Weiterlesen

Programmierquiz: Kürzesten, nicht passenden String finden, auf dass ein RegExp nicht passt

Hier mal eine lustige Aufgabe, mit der ich vor Kurzem konfrontiert war: Gegeben sei ein Alphabet Σ mit Symbolen und eine Regular Expression, wie etwa (0*|1*)(0*|1*)(0*|1*). Nun ist dar kürzeste String mit Symbolen aus dem Alphabet gesucht, auf dass der gegebene RegExp nicht passt.

…Hier würde etwas Musik gespielt und ein Countdown eingeblendet werden, damit der interessierte Leser eine Lösung erarbeiten kann 🙂 …

Meine Lösung funktioniert, sofern die Symbole im Alphabet einem Symbol in UTF-8 entsprechen und ist trivial: Zuerst werden alle Permutationen gebildet und der RegExp daran getestet. Aus reinem Masochismus habe ich versucht, dies in Python 3.2 zu implementieren. Und nein, itertools packt das nicht!

Ein Testdurchgang könnte folgendermassen aussehen (Das Alphabet besteht aus 0 und 1):

$ python3.2 msfr.py -v '(0*|1*)(0*|1*)(0*|1*)' 0 1
Σ: {0, 1}
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with ε MATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 0 MATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 1 MATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 00 MATCH

[...]

  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 0011 MATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 0100 MATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 0101 NOMATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 0110 MATCH

[...]

  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 1010 NOMATCH
  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 1011 MATCH

[...]

  Testing: '^(0*|1*)(0*|1*)(0*|1*)$' with 1111 MATCH
Found nonmatching strings with length 4: 0101, 1010

Klappt also nicht schlecht. ε ist übrigens der leere String :).

Dies ist mein erstes Script in Python überhaupt. Für Anregungen und Verbesserungsvorschläge bin ich mehr als dankbar:

#!/usr/bin/env python
'''
Find a minimal non-matching string for a given regular expression and an alphabet.
Created on Oct 1, 2011

@author: Skaldrom Y. Sarg
'''

import argparse
import re
import sys

def allstrings(alphabet, length):
    """Find the list of all strings of 'alphabet' of length 'length'"""
   
    if length == 0:
        return [""]
    c = []
    for i in range(length): # @UnusedVariable
        c = [[x] + y for x in alphabet for y in c or [[]]]

    return c


if __name__ == '__main__':
    scriptHelp= "msfr: Find a minimal non-matching string for a given regular expression and an alphabet.\n\
\n\
Example: python3 msfr.py '(0*|1*)(0*|1*)(0*|1*)' 0 1"

   
    parser = argparse.ArgumentParser(description=scriptHelp, epilog='Written by Michael Schneider.')
    parser.add_argument('-v, --verbose', dest='verbose', action='store_true', default=False, help='output more verbose')
    parser.add_argument('-m, --maxlength', dest='maxlength', default=10, help='max number of symbols to test (default: 10)')
    parser.add_argument('regexp', type=str, nargs=1, help='the regular expression')
    parser.add_argument('alphabet', metavar='S', type=str, nargs='+', help='a symbol of the alphabet')
    args = parser.parse_args()

    # Start
    if(args.verbose):
        print('Σ: {' + ", ".join(args.alphabet)+'}')
       
    foundNonMatch = []
    for wordlength in range(0, args.maxlength):
        for string in allstrings(args.alphabet, wordlength):
            testString = "".join(string)
            testRegexp = args.regexp[0]
            if args.verbose:
                print("  Testing: '^" + testRegexp + "$' with " + (testString if len(testString) != 0 else 'ε'), end="")
            try:
                result = re.match('^' + testRegexp + '$', testString)
            except re.error as exc:
                if args.verbose:
                    print("\n")
                print("ERROR - Invalid regexp: " + str(exc))
                sys.exit(0)
                   
                   
            if(result != None):
                if args.verbose:
                    print(" MATCH")
            else:
                foundNonMatch.append(testString)
                if args.verbose:
                    print(" NOMATCH")
        if(foundNonMatch):
            break
    if not foundNonMatch:
        print("No nonmatching strings found until length " + args.maxlength + ".")
    else:
        foundStingsLength = str(len(foundNonMatch[0]))
        foundStrings = ", ".join(foundNonMatch) if len(foundNonMatch[0]) > 0 else 'ε'
        print("Found nonmatching string" + ("s" if len(foundNonMatch) else "") + " with length " + foundStingsLength +": " +foundStrings)

Dynamische Mailsignaturen in Apple 10.7 (Lion)

Dynamisches MailWie man in verschiedenen, schon geschriebenen Blogeinträgen sehen kann, ist es mir ein Anliegen, die Welt mit etwas Dynamik zu versehen, zumindest was Mailsignaturen betrifft. Ja, auch in Mac OSX ist das möglich!

Von Haus aus bringt OSX keine Möglichkeit mehr mit, dynamische Signaturen zu erstellen. Entweder, weil es so gedacht war, weil diese Funktion in die Cloud ausgelagert wurde 🙂 oder wegen eines Bugs. Ich habe so ziemlich alles durchprobiert, was dieser Artikel über fortunes und andere Websites beschrieben haben, doch leider läuft es nicht – oder nicht mehr – so.

Erkenntnisse:

  • AppleScripts möchten nicht einfach so mit Tastaturkürzeln versehen werden.
  • Das AppleScript Utility gibt es nicht mehr. Um AppleScripts zu aktivieren muss der AppleScript-Editor geöffnet werden und das Skriptmenü in den Einstellungen aktiviert werden (siehe Abbildung).

Skript-Menü im neuen AppleScript-Editor

Will man doch mittels fortune dynamische Signaturen erzeugen, muss man wie Folgt vorgehen:

  1. Zuerst braucht man fortune. Dies kann man sich beispielsweise per MacPorts beschaffen. Damit MacPorts läuft, muss XCode vom AppStore installiert werden.
  2. Dann sollte man sich eine Zitatsammlung bereit legen, wie im Blogeintrag zu dynamischen Signaturen beschrieben.
  3. Dann muss man den Automator starten und einen neuen Service erstellen.
  4. Grundeinstellung: „Dienst empfängt keine Eingabe in Mail.app
  5. Als Aktion AppleScript ausführen suchen und einfügen.
  6. Das AppleScript:
    on run {input, parameters}
       
        tell application "Mail"
            activate
            make new outgoing message with properties ¬
                {content:do shell script "/Users/linux/Documents/sigs/psignature-mac", visible:true}
        end tell
        return input
    end run

    Natürlich muss der Pfad angepasst werden. psignature-mac ist ein Script mit folgendem Inhalt:

    #! /bin/bash
    echo "  Viele Grüsse"
    echo "     Skaldrom"
    echo "-=-=-=-=-=-=-=-=-"
    /opt/local/bin/fortune `dirname "$0"`/quotes/shorties

    Dann alles speichern und einen Kaffee trinken oder Kekse backen gehen.

  7. Um den Tastaturkürzel festzulegen, muss die Systemeinstellungen geöffnet werden. Dort auf TastaturTastaturkurzbefehle gehen. Der Dienst sollte irgendwo erscheinen und ein Klick auf den leeren Platz rechts davon ermöglicht es, einen Tastaturkurzbefehl einzugeben.
  8. Mail öffnen, Tastaturkurzbefehl (ja, ich mag dieses Wort) drücken und sich freuen.

Es gibt auch eine Lösung für existierende Mails:

on run {input, parameters}
   
    tell application "Mail"
        activate
        get do shell script "/Users/linux/Documents/sigs/psignature-mac"
        copy return & the result ¬
            to theFortune
       
        tell application "System Events"
            tell process "Mail"
                keystroke theFortune
            end tell
        end tell
    end tell
    return input
end run

Experimentelle Analysen von PHP Code für Enthusiasten

Während ich im vorhergehenden Artikel die „Standardtools“ für die Analyse von PHP verwendet habe, möchte ich hier einen Schritt weitergehen. Wenn ich schon meine Programme analysieren lasse, dann richtig :)! Darum hier ein paar nicht-standard Analysetools für PHP, die ich als eher experimentell bezeichnen würde:

  • doxygen
  • phuml
  • php-lint
  • PHP Callgraph

Weiterlesen

PHP Code-Analyse mit Ant

Graph LeadIch mag Code. Nicht jeden natürlich, „Douchebag“ Code nervt, Code der aussieht wie ein schreiender Quasimodo oder Code der von einem Dr. Frankenstein in Ausbildung erstellt wurde sind bemitleidenswert und sehr viel Code stinkt. Code, der gefällt (wie beispielsweise der von Frigidor) ist clever ohne zu bluffen, kurz aber nicht kryptisch, tut etwas, ist lesbar und hat einige Wows drin.

Diese Bewunderung sollte in Zahlen gefasst werden: mit Statistiken, Diagrammen, Balken und Graphen. Dies dient zur Vorbereitung der „Continuous Integration“ mit Jenkins/Hudson, die in dieser Serie behandelt wird. Als Quellen haben vor allem jenkins-php und ein äusserst Lesbarer Artikel im Entwickler Magazin 01/11 gedient.

Hier wird nun gezeigt, wie mit einem Befehl:

  • Die Unittests durchführt.
  • Qualitative Softwaremetriken mit PHP Depend misst: Hierarchietiefe, Komplexität, …
  • Unschöne Teile mit PHPMD identifiziert.
  • Copy-Paste-Verbrecher aufspührt mit phpcpd.
  • Den Coding-Style prüft mit dem PHP Code Sniffer.
  • Quantitative Softwaremetriken mit phploc misst.
  • Die PHPDoc-Doku erstellt.
  • Die Resultate mit dem PHP Code Browser schön darstellt.

Weiterlesen

Programmierwettbewerbe: Zeit sollte man haben

thinkingLeider kann ich mangels Zeit beim Google AI-Contest nicht mitmachen :(. Und ich habe mich schon so gefreut. Naja, ich hoffe, es gibt einen Nächsten.

Sehr interessant ist der Verlauf des Wettbewerbs des Linux-Magazins. Alles ging gut bis zum Abgabetermin am 12. September 2010. Ab dann war der Wurm drin: Die versprochenen Bestätigungsmails an die Teilnehmer sind nie eingetroffen und der Organisator ist „abgetaucht“. Die Wettbewerbsteilnehmer haben viel Geduld gezeigt, das Wiki regelmässig von Spam gereinigt und abgewartet.

Nachdem die ersten unangenehmen Fragen aufgetaucht sind, hat sich die Organisation gemeldet und verkündet, dass ein Bericht in der Novemberausgabe des Magazins erscheinen wird. Das ist er dann auch, aber mehr ist bis jetzt nicht passiert. Der Unmut wird immer grösser, vor allem nachdem eine Teilnehmerliste veröffentlicht wurde, auf der einige Bots fehlen. Leider gibt es weiterhin nur spärlich Neuigkeiten. Eine Community ist ein Dialog: Wird er vom Organisator nicht geführt, führt ihn die Community alleine.

Wir sind hier organisatorisch mit einem ähnlichen Problem konfrontiert: Programme in vielen Programmiersprachen werden abgegeben und müssen von uns bewertet werden. Auch ein kleiner Mehraufwand pro einzelner Lösung summiert sich schlussendlich zu sehr viel Zeit. Das Einzige, das hilft, ist Denken im Voraus. Klare Richtlinien und Regeln, sonst wird der Aufwand unüberschaubar riesig. Es gibt Beispiele von erfolgreich durchgeführten Wettbewerben: Avaloqix wurde life durchgeführt mit Anwesenden, der Google AI-Contest oder die alten Codezone (Microsoft) Wettbewerbe haben ebenfalls gezeigt, wie es gehen könnte. Ich möchte den Organisatoren vom Linux-Magazin nicht in die Suppe spucken, und wenn sie die Durchführung noch hinkriegen, haben sie meinen grössten Respekt und viel gearbeitet, aber irgendwie war es ein Schnellschuss.

So ganz per Zufall habe ich noch eine nette Sache entdeckt: Das Freie Magazin führt ebenfalls einen sehr interessanten Wettbewerb durch. Tip: Das LIESMICH im Download lesen :)….

Jetzt macht auch Google noch ein Programmierwettbewerb

Ich habe mich schon gefreut: Der Würfler zum Linux-Magazin-Wettbewerb ist fertiggestellt und eigentlich bereit zum Einsenden. Etwas enttäuscht habe ich festgestellt, dass das Problem akademisch gelöst und der optimale Spieler bekannt ist. Nun, der Thrill der noch bleibt ist, dass bei nur 100 Spielen auf 50 Punkte der Zufall eine seeeehr grosse Rolle spielt.

Doch zu früh gefreut, jetzt kommt das: Die Google AI-Challenge. Man kann nicht mal was gewinnen, aber das Spiel ist unglaublich genial: Es geht darum, Planeten zu erobern:

Es gibt jetzt schon Starter-Packages für verschiedene Sprachen und das System ist ziemlich offen (für unsere Shell-Krieger 🙂 ). Ab dem 10.09.2010 kann man sich dann offiziell eintragen und losranken.

Ein Programmierwettbewerb vom Linux Magazin

Nachtrag vom 19.08.2010: Ich wurde Opfer von „mod_security“, damit konnte ich keine Artikel mehr editieren, weil ich immer ein „404 Not Found“ präsentiert bekommen habe. DAS ist doch ein Heuler…

Nun, ich habe eine neue Version des Clients unten hingehäng: Stabiler, so dass er auch eine ganze Nacht über viele Stunden und Verbindungsprobleme hinweg weiterspielt.

WuerfelOh nein. Frisch erkältet wollte ich mich auf die Arbeiten stürzen, die eigentlich schon letztes Jahr hätten erledigt sein müssen, und nun das: Das Linux-Magazin veranstaltet einen Wettbewerb für Programmierer! Die Details sind in der Ausgabe 09/10 (auch online) beschrieben und es gibt eine Wettbewerbs-Seite dazu.

Grundsätzlich geht es darum, dass zwei Programme gegeneinander würfeln. Wer zuerst 50 Punkte oder mehr erreicht, hat gewonnen. Ist man am Zuge, so kann man entweder Würfeln oder „Save“n. Bei einem Wurf werden die Augen zu der eigenen Punktzahl hinzugezählt, ausser man würfelt eine 6, dann werden alle Punkte seit dem letzten Save wieder abgezogen. Bei einem Save werden die Punkte gespeichert und der Gegner ist am Zuge.
Weiterlesen

Zeitintervalle (Erledigungsfristen) in PHP

timeIch bin wiedereinmal am Coden und irgendwie scheine ich mit fortschreitendem Alter auf immer mehr ungelöste Probleme zu treffen. In der aktuellen Applikation geht es darum, dass Erledigungsfristen als Intervalle eingegeben werden können: Beispielsweise muss eine Aufgabe immer in 2 Monaten, 1 Woche und 4 Sekunden nach dem Erfassen erledigt sein. Daraus ergeben sich ein Strauss an Problemen (oder ein Problemkorb, wie man neuerdings zu sagen scheint. Was für eine schreckliche Vorstellung, nur FRÜCHTE-Körbe finde ich noch abschreckender):

  • Jemand muss die Aufgabe erledigen. Zum Glück ist das ein PAL (Problem anderer Leute) 🙂 .
  • „In einem Monat“ und „In einem Jahr“ kann nicht trivial in Sekunden umgerechnet werden. Irgendein Soziopath hat mal bestimmt, dass nicht alle Monate und Jahre die gleiche Anzahl Tage haben. Ganz zu schweigen von Schaltsekunden und Sommer-/Winterzeit.
  • Aus hier zu verschweigenden Gründen habe ich weder Lust noch Zeit ein GUI mit 7 Textfeldern für Jahre, Monate, Wochen, Tage, Stunden, Minuten und Sekunden aufzubauen.

Ich habe mich für ein simples Eingabefeld entschieden, in denen das Erledigungsintervall in der Form „Zahl Zeitbezeichner Zahl Zeitbezeichner …“ eingegeben werden kann. In obigem Beispiel wäre das: „2m 1w 4s„.

Weiterlesen