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

Dieser Beitrag ist Teil 2 von 2 in der Serie Continuous Integration

    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

    Dieser Beitrag ist Teil 1 von 2 in der Serie Continuous Integration

      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

      Ich weiss (nicht mehr) ob Du im Facebook bist…

      Update 27.01.2011: *übel_fluch*! Facebook hat ein Captcha eingebaut, dass diese Detection momentan nicht mehr funktionieren lässt. Das Prinzip bleibt ok, die Realisierung brauchte nun etwas mehr Zeit.

      Big BrotherEigentlich hätte ich ja ganz Anderes zu tun, aber per Zufall bin ich über den genialen Blogartikel von Mike Cardwell gestolpert. Er hat eine Idee gehabt, wie es möglich wird herauszufinden, ob Benutzer auf Facebook und Konsorten eingeloggt sind oder nicht.

      Umgesetzt in eine kleine Library läuft es als Proof-of-Concept auf Firefox und sieht folgendermassen aus:

      Loggen Sie in Gmail, Facebook, Twitter oder Digg ein um Resultate zu sehen.
      Sind Sie nicht abgelenkt?

      Neuer Check

      Grundsätzlich wäre es ja ganz einfach: Man schaut vom Client-Browser aus, ob man Zugriff auf Bilder oder Seiten hat, die nur für Eingeloggte zur Verfügung stehen. Leider gestaltet sich dieser simple Ansatz nicht so einfach, weil mit Ajax nur zur Domain der Website verbunden werden darf und nicht an einen x-beliebigen Ort. Ein Proxy hilft auch nicht weiter, da es die Cookies des Browsers braucht, und die werden nur an Facebook, etc direkt abgeliefert.

      Wie kann man also diese Restriktion umgehen?

      Weiterlesen

      PHP Funktionstests aus Netbeans mit Selenium

      SeleniumIch hab da so ein Projekt, dass ich schon mehr als ein Jahr vor mir herschiebe: Eine Überarbeitung und Erweiterung einer bestehenden PHP-Applikation. Sie läuft eigentlich super, das Pflichtenheft ist gut und alle sind glücklich. Leider hat sich die „Erweiterung“ als Operation am Herzen herausgestellt. Der ursprüngliche Cöder hat eine ziemlich komplexe Struktur erarbeitet, in der er sich selbst ab und zu verheddert hat. Das bedeutet, dass zuerst ganz hässliche Strukturbugs als solche identifiziert und gefixt werden mussten. Im Zuge dieser Operation habe ich so ziemlich jeden Teil der Software berührt, beflucht und daran herumgewurschtelt.

      Um etwas Sicherheit und Stabilität in die Sache zu bringen hätte ich gerne Unit Tests gehabt. Bei diesem Kludge sind aber so viele Komponenten beteiligt, dass es nicht so einfach klappt. Der Hammer musste eine Nummer grösser gewählt werden: Selenium.

      Mit Selenium verbindet mich eine unerwiderte Liebe. Immer wieder versuche ich an das Tool heranzukommen, immer wieder scheitere ich irgendwie weil ich abgewiesen werde. So auch zu Beginn dieses Anlaufs: Die Funktionstests laufen (vielleicht), finden es aber unangebracht sich irgendwie zu melden. Die Doku ist gut, aber nirgends wird ein Überblick vermittelt und man muss die fragilen Einzelteile mit gutem Zureden zueinander bringen.

      Weiterlesen

      Programmierwettbewerbe: Zeit sollte man haben

      Dieser Beitrag ist Teil 2 von 3 in der Serie Linux-Magazin Wettbewerb

        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.