Posts Tagged ‘Programmierung’

Freitag, 14. Dezember 2018

Video: The Computer Hack That Saved Apollo 14

Grandiose Geschichte, von welcher ich noch nie gehört hatte (kein Wunder, Apollo 11 und Apollo 13 waren leider deutlich filmreifer und stahlen diesem Vorfall die Schau).

War da viel Glück im Spiel, oder waren sich die Computer-Ingenieure auf der Erde wirklich sicher, dass man a) eine Prozedur manuell denken lassen konnte, dass sie sich bereits im „Abort-Modus“ befand und b) keine andere Computer-Routine sich auf diesen Wert abstütze und darauf basierend wiederum andere Routinen aufrief. Jedenfalls scheint es funktioniert zu haben!

Auch ganz spannend: Die Verwendung von Verben und Nomen (in Zahlencodes geschlüsselt), um den Computer umzuprogrammieren — technisch DSKY genannt. Naheliegende Analogie; die ich höchstens annäherungsweise noch von LucasArts-Adventures her kenne. Aber selbst da bereits mit Computermaus und graphischer Oberfläche.

Tags: , , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 11. April 2012

XING-Bilder grösser machen

Da ich keinen Sinn darin sehe, für eine XING Premium-Mitgliedschaft Geld auszugeben, habe ich ab und zu das Problem, dass ich erraten muss, wer mein Profil so alles besucht hat.

XING zeigt mir dabei die Besucher mit einem klitzekleinen Bildchen an, worauf ich die Person partout nicht erkennen kann. Wenn ich meine Neugier befriedigen möchte, muss ich eine XING-Mitgliedschaft kaufen.

Doch zumindest etwas Licht ins Dunkel lässt sich bringen, indem man etwas mit der Bild-URL spielt. Hier ein Beispiel:


https://www.xing.com/pubimg/users/1/6/c/2450328df.16473797,2.30x40.jpg

Hmmm! Löschen wir doch mal die Pixeldimensionen nach dem Komma. Oh:


https://www.xing.com/pubimg/users/1/6/c/2450328df.16473797,2.jpg

So sieht der Mitmensch also aus, der mein Profil besucht hat …

Mein Tipp an XING: Die verschiedenen Grössen der Bilder sollten einen variablen Bestandteil haben, der von aussenstehenden weder erraten noch hergeleitet werden kann. Beispielsweise mittels md5($imageSize . $internalUserId).

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 11. Februar 2012

Vom Nutzen einer PHP Debug-Klasse

Seit mehreren Jahren verwende ich eine Sammlung von selber entwickelten emeidi*-PHP-Klassen, um Web-Sites und -Applikationen zu entwickeln. Leider hege ich immer noch grosse Skrupel, diese Klassen via Github als Open Source Software freizugeben — einerseits weil sich im Quellcode doch der eine oder andere unschöne Bock findet, andererseits, weil die Klassen Sicherheitslücken enthalten könnten, die bei produktiven Web-Sites ausgenützt werden könnten. Hinzu kommt mein Amazon-API-Key, den ich kurzerhand in die emeidiAmazon-Klasse festkodiert habe …

Unverzichtbares Kernstück ist dabei meine emeidiDebug-Klasse, welche für die professionelle, effiziente Web-Entwicklung unabdingbar ist. Jede andere meiner Klasse instanziert beim Laden die emeidiDebug-Klasse, mit welcher ich im ganzen Programmcode nützliche Fehlermeldungen und/oder Informationen zum Programmablauf festhalte.

Auf produktiven Web-Sites gebe ich den Inhalt des Debug-Objektes natürlich nicht aus, aber auf dem Entwicklungsserver ist es eine grosse Unterstützung, wenn ich am Ende der ausgegebenen Web-Seite noch folgenden Code hinpflanze:

...
<?php print $klasse->debug->getHtml(); ?>
</body>
</html>

Im ganzen PHP-Code finden sich zur Befüllung dieses Objekts Konstrukte wie

$this->debug->add('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld,'error');

Teilweise gebe ich auf produktiven Web-Sites wichtige Warnmeldungen auch in das PHP Error-Log aus. Während ich das früher direkt mit error_log(); gemacht habe, benutze ich heute ebenfalls meine Debug-Klasse dafür.

Der Grund dafür ist simpel: Nicht nur möchte ich das gesamte Debugging über meine Debug-Klasse laufen lassen, nein, meine Debug-Klasse ist auch geschwätziger und hilft mir im Falle meines Testservers, das fehlerhafte Script zu lokalisieren.

Vor einigen Tagen fand ich auf meinem Testserver folgende Einträge in der php.err-Datei:

[06-Feb-2012 00:07:43 UTC] Not dumping descriptions because length new 1778 is smaller than lenght old 1780

Mittlerweile habe ich das ausgebende Script (es wird täglich per Cron-Job aufgerufen) lokalisiert und die Programmierung angepasst. Alt hiess es:

error_log('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld);

Neu heisst es:

$this->debug->add('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld,'error',true);

Der letzte der Funktion übergebene Parameter true weist meine Debug-Klasse an, einen Eintrag in die php.err-Datei zu machen. Dieser schaut folgendermassen aus:

[11-Feb-2012 16:57:16 UTC] Not dumping descriptions because length new 1778 is smaller than lenght old 1780 in /var/www/apps/weather2ics/weather2ics.class.php on line 95 for URI </bern>

Anhand dieser Informationen kann ich nicht nur die Datei und die verantwortliche Zeile auf einen Blick lokalisieren, welche den Fehler ausgibt, sondern sehe auch noch gerade die URI, mit welcher die Web-App aufgerufen wurde.

Tags: , ,
Labels: Web

1 Kommentar | neuen Kommentar verfassen

Donnerstag, 9. Februar 2012

SAP Spreadsheet-Exporte parsen

… ist leider nicht so einfach.

SAP bietet die Möglichkeit, Reports zu exportieren. Zur Auswahl steht unter anderem auch ein „Spreadsheet“-Format, für welches die Endung .xls vorgeschlagen wird. Dabei handelt es sich aber nicht etwa um das Excel-Binärformat, welches heute durch OOXML abgelöst wurde, sondern um das ältere XLL-Format, was auch immer das genau sein soll. Betrachtet man die aus SAP generierte Datei in einem Text-Editor, ist offensichtlich, dass es sich hierbei nicht um ein Binär- sondern um ein Plaintext-Format mit Tabulator getrennten Spalten handelt.

Wenn diese Datei aber mit Python eingelesen wird und verarbeitet werden soll, ergeben sich Probleme. Die Zeichen sind auf der cygwin-Kommandozeile von einem Leerzeichen getrennt. Es handelt sich also nicht um eine ASCII-Ausgabe.

Ein Blick mit Notepad++ auf die Datei zeigt, dass die Encodierung der Datei UCS-2 Little Endian sein soll. Auf Stackoverflow ist erwähnt, dass diese Encodierung in Python wie UTF-16 behandelt werden kann, und zwar folgendermassen:

file = codecs.open(filenameInput,'Ur',encoding='utf-16be')

Leider führt das aber nicht zum Erfolg, was nachfolgende Fehlermeldung einem schmerzlich vor Augen führt:

Traceback (most recent call last):
  File "./<script>.py", line 140, in 
    data = file.read()
  File "C:\Python27\lib\codecs.py", line 671, in read
    return self.reader.read(size)
  File "C:\Python27\lib\codecs.py", line 477, in read
    newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf16' codec can't decode bytes in position 1082-1083: illegal encoding

Tags: , ,
Labels: Allgemein

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 9. Februar 2012

Mit openpyxl .xlsx-Dateien ausgeben

Mit dem Python-Modul openpyxl ist es möglich, Excel-Dateien im Microsoft OOXML-Format (.xlsx) zu lesen und zu schreiben.

Da das Erstellen einer solchen Datei im Netz verständlich erklärt ist und hier nicht näher beleuchtet werden soll, ist das Styling von Tabellenzeilen leider kaum dokumentiert.

Hier einige Ansatzpunkte in Form von Code-Schnipseln aus einem meiner Python-Scripts:

from openpyxl.reader.excel import load_workbook
from openpyxl.writer.excel import ExcelWriter

from openpyxl.workbook import Workbook
from openpyxl.worksheet import ColumnDimension
from openpyxl.cell import get_column_letter, column_index_from_string
from openpyxl.style import Color, Fill

# Eigenschaften von Zelle in Reihe 4 und Spalte 3
cellCoord = get_column_letter(3) + "4"

# Fettschrift
sheetResult.cell(cellCoord).style.font.bold = True

# Textausrichtung
sheetResult.cell(cellCoord).style.alignment.horizontal = 'left'
sheetResult.cell(cellCoord).style.alignment.vertical = 'top'

# Textumbruch
sheetResult.cell(cellCoord).style.alignment.wrap_text = True

# Zellfüllung
sheetResult.cell(cellCoord).style.fill.fill_type = Fill.FILL_SOLID 
sheetResult.cell(cellCoord).style.fill.start_color.index = Color.GREEN

# Für Zellfüllung verfügbare Farben
BLACK = 'FF000000'
WHITE = 'FFFFFFFF'
RED = 'FFFF0000'
DARKRED = 'FF800000'
BLUE = 'FF0000FF'
DARKBLUE = 'FF000080'
GREEN = 'FF00FF00'
DARKGREEN = 'FF008000'
YELLOW = 'FFFFFF00'
DARKYELLOW = 'FF808000'

Tags: ,
Labels: Allgemein

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 9. Februar 2012

Python-Scripts unter Windows in ausführbare .exe-Dateien umwandeln

Mit Python-Scripts kann man auch in einer Grossfirma wie meinem Arbeitgeber Arbeitsabläufe automatisieren, so beispielsweise das parsen einer Excel-Datei mit dem Modul openpyxl. Ich suche in der Excel-Datei in einer bestimmten Spalte nach Parametern und in derselben Zeile dann nach den auf dem produktiven System eingestellten Werten.

Doch was macht man nun mit dem Python-Script, wenn es als stabil empfunden und zur Distribution unter den Arbeitskollegen freigegeben wurde? Man kann nicht erwarten, dass nur ein einziger Mitarbeiter Python auf seinem Windows-Rechner installiert hat und das Script so ausführen kann.

Zum Glück gibt es eine einfache Möglichkeit, um Python-Scripts in eine .exe-Datei umzuwandeln, welche ausschliesslich aus dieser Datei bestehen und deshalb problemlos herumgereicht werden können.

Hierfür benötigt man den pyinstaller (kompatibel mit Python 2.7), welchen man folgendermassen aufruft:

python C:\Source\pyinstaller-1.5.1\pyinstaller.py C:\Source\emeidi\<script>.py -F

Der Switch -F sagt pyinstaller, dass er das Script in eine einzige, grosse .exe-Datei umwandeln und auf den sonst ebenfalls nötigen .dll-Plunder verzichtet.

Anschliessend findet sich die .exe-Datei unter C:\Source\pyinstaller-1.5.1\<script>\dist\<script>.exe, welche man beispielsweise auf den Desktop kopieren und von dort ausführen kann.

Tags: , , ,
Labels: Allgemein

1 Kommentar | neuen Kommentar verfassen

Sonntag, 19. Juni 2011

Wo man als Programmierer wirklich anheuern sollte …

People who can code in the world of technology companies are a dime a dozen and get no respect. People who can code in biology, medicine, government, sociology, physics, history, and mathematics are respected and can do amazing things to advance those disciplines.

Quelle: Advice From An Old Programmer — Learn Python The Hard Way, 2nd Edition

Tags: , ,
Labels: Arbeit, Gesellschaft

Keine Kommentare | neuen Kommentar verfassen

Samstag, 28. Mai 2011

Objekte zwischen Datenbank und Programmlogik

I’ve seen the blank stare with eyes glazed when I asked a developer why they wrote 3 nested loops to find a specific value of the child of the child of a mapped ORM entity instead of just writing a specific query for it. Or why they retrieved and iterated over all 5 million items to set the same value of of the same field instead of writing an update statement.

Quelle: ORM’s hidden cost « n0tw0rthy

Das erinnerte mich spontan an folgenden Post des Entwicklers hinter NetNewsWire, dem RSS-Feedreaders meiner Wahl unter Mac OS X (unter iOS ist es klar Reeder):

On switching away from Core Data

Aus Performance-Gründen verzichtete er auf das Core Data-Framework und sprach die SQLite-Datenbank für folgende Aufgaben lieber direkt an:

  • Unzählige Nachrichten als gelesen markieren
  • Unzählige Nachrichten löschen
  • Ersetzen bestehender Nachrichten (mittels einer externen ID)
  • Überprüfung bestehender Nachrichten (mittels einer externen ID)

Tags: , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Freitag, 25. Februar 2011

Ruby on Rails 3-Kleinigkeiten

Nachfolgend eine Sammlung von Ruby on Rails 3-Kleinigkeiten, die den Umstieg von PHP-Programmierern auf diese Programmiersprache/dieses Framework erleichtern sollen.

Kommentare

Werden mit # eingeleitet.

Helper

Um die Views schlank zu halten, empfiehlt es sich, häufig benutzte (respektive umfangreiche) Funktionen in den jeweiligen Helper auszulagern. Eine gute Einleitung in die Thematik findet sich im Artikel Using helper methods in Ruby on Rails.

return fehlt

Das besondere an Ruby-Methoden: Das Resultat der letzten Zeile einer Methode wird automatisch zurückgegeben, man muss also keine aus anderen Sprachen gewohnte return-Anweisung notieren.

Helper HTML ausgeben lassen

Um mit Ruby on Rails 3 eine Helper-Methode HTML-Code zurückgeben zu lassen, muss das Resultat als „safe“ gekennzeichnet werden (via Ruby on Rails Helper Method – HTML is displayed as plain text). Ansonsten werden „<“ „>“ im Rückgabewert automatisch in HTML-Entities umgewandelt. Konkret:

def machHtml
	html = "<h1>Titel</h1>"
	html.html_safe
end

Heredoc

Wie PHP kennt auch Ruby die Heredoc-Notation (via Heredocs – oder – Code in der 2. Dimension), mit welcher man HTML-Code zeilenübergreifend notieren und Ruby-Variablen einfügen kann:

html = <<HTML
	<tr>
		<td></td>
		<td></td>
		<td></td>
	</tr>
HTML

Das besondere ist hierbei, dass man bei der Angabe eines Bindestrichs „-“ beim Beginn des Heredocs den EOL auch einrücken kann, um den Programmcode lesbarer zu machen:

html = <<-HTML
	<tr>
		<td></td>
		<td></td>
		<td></td>
	</tr>
	HTML

Um in Heredoc Ruby-Variablen auszugeben, werden diese als #{variable} notiert.

Zahlen auf zwei Nachkommastellen gerundet ausgeben

rounded = "%.2f" % val

Seiten-Template

Das Template der Standardseite (HTML Header und Footer) ist unter ~/app/views/layouts/application.html.erb abgelegt.

Stylesheets einbinden

Sobald man ein CSS-Stylesheet in ~/public/stylesheets ablegt, wird dieses automatisch in das Template eingebunden.

Zeitzone

In ~/config/application.rb sollte man die richtige Zeitzone notieren:

...
config.time_zone = 'Bern'
...

Um den erwarteten Wert herauszufinden, bemüht man sich folgenden Befehls:

$ rake time:zones:local

locale

Um die locale auf Deutsch zu ändern, muss zuerst eine vorgefertigte locale-Datei heruntergeladen und in ~/config/locales abgelegt werden. Leider ist de-CH.yml kaputt, de.yml funktioniert hingegen:

$ cd ~/config/locales
$ wget --no-check-certificate "https://github.com/svenfuchs/rails-i18n/raw/master/rails/locale/de.yml"

Anschliessend passt man ~/config/application.rb an:

...
config.i18n.default_locale = :de
...

Deutsche Zeit ausgeben

Hierzu stellt Ruby on Rails 3 eine Locale-Funktion bereit:

l(date, :format => '%a %d.%m.%Y')

Sortierung in der index-Ansicht ändern

Im Controller der Applikation unter ~/app/controllers/stamps_controller.rb kann man nach dem Scaffolding natürlech eigene Anpassungen vornehmen:

def index
    #@stamps = Stamp.all
    @stamps = Stamp.find(:all, :order => 'date_start')

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @stamps }
    end
  end

Mit @stamps = Stamp.find(:all, :order => 'date_start') macht man im Grunde dasselbe wie mit @stamps = Stamp.all, doch sortiert die Resultate datenbankseitig (!) bereits nach einem bestimmten Feld. Die Sortierrichtung kehrt man um, indem man noch DESC an den Befehl anhängt.

Tags: , , , ,
Labels: Web

1 Kommentar | neuen Kommentar verfassen

Donnerstag, 24. Februar 2011

Das erste kleine Ruby on Rails 3-Projekt

Nachdem man Ruby on Rails 3 auf seinem Entwicklungsserver eingerichtet hat, kann man sich sofort hinter die Entwicklung einer ersten Testapplikation machen.

Meine Anleitung richtet sich an Web-Entwickler, die mit einem PHP-Hintergrund Ruby on Rails ausprobieren möchten und mit dem MVC-Paradigma vertraut sind (sprich schon mit dem Zend Framework, Symfony, CakePHP etc. produktiv gearbetiet haben).

Vorbemerkung: Versionschaos

Im Netz gibt es unzählige How-Tos und Tutorials um eine erste Rails-Applikation hinzubiegen — sehr hilfreich war für mich Enabling Rails 3 for your application. Leider beziehen sich die wenigsten Anleitungen auf Ruby on Rails 3. Leider vernachlässigen es die Autoren solcher Werke oftmals zudem, darauf hinzuweisen, auf welche Rails-Version sich die Anleitung denn eigentlich bezieht. Dies hole ich hier explizit vor — meine Version lautet:

$ rails -v
Rails 3.0.4

Notabene: Es gibt anscheinend die Möglichkeit, mit der neuesten Rails-Version auch Projekte anzulegen, welche nach einer der älteren Versionen aufgebaut sind (rails _2.3.5_ APP_NAME via How can I create previous version rails in rails 3?). Wenn aber jemand Rails lernen möchte, sollte er dies mit der aktuellsten Version tun — so meine Überzeugung.

Beispielapplikation: Arbeitsjournal

Um rasch Gemeinsamkeiten und Unterschiede zu PHP aufzuzeigen, habe ich mich hierbei entschlossen, eine bestehende PHP-Webapplikation mit Ruby on Rails nachzubauen: Das Arbeitsjournal. Mit diesem führe ich für einen meiner derzeitigen Jobs Buch, wie lange ich arbeite und welche Aufgaben ich wann erledigt habe. Das Tool zeigt mir die Gesamtarbeitszeit für einen Monat und berechnet auch gleich, ob ich die gemäss Arbeitsvertrag erforderlichen Stunden abgearbeitet habe oder nicht.

Der Projekttitel liegt auf der Hand: arbeitsjournal.

Applikations-Skelett erstellen

Ich habe mich entschieden, meine Projekte unter /var/rails abzulegen. Nachdem ich dieses Verzeichnis erstellt habe, welches alle zukünftigen Ruby-Projekte enthält, wechsle ich da hinein und erstelle mir die Projektstruktur. Dank Rails ist dies Sache eines einzigen Befehls:

# mkdir /var/rails
$ cd /var/rails
$ rails new arbeitsjournal -d mysql

Die Option -d gibt an, dass man die Modelle und Daten in einer MySQL-Datenbank abgelegt haben möchte (Standard ist sqlite3)

Datenbankverbindung herstellen

Als Datenbank habe ich MySQL gewählt. Das Vorgehen ist identisch wie bei PHP-Web-Projekten: Zuerst erstellt man sich eine Datenbank (bei mir ruby_arbeitsjournal), einen MySQL-Benutzer (ruby) mitsamt Passwort und weist ihm Schreibrechte auf die neu erstellte Datenbank zu. Nach einem FLUSH PRIVILEGES; liest die MySQL-Datenbank den neuen Benutzer ein. Ich verwende dazu als Relikt vergangener Tage das GUI phpMyAdmin, obwohl ich auf der MySQL-Kommandozeile mittlerweile viel rascher ans Ziel kommen würde.

Unter Rails gibt man die Datenbankoptionen in der Datei ~/config/database.yml an:

...
development:
  adapter: mysql
  database: ruby_arbeitsjournal
  host: localhost
  username: ruby
  password: ********
...

Modell erstellen

Nun ist es an der Zeit, das Modell zu erstellen. Da es sich um eine Applikation mit ein, zwei Datenbanktabellen handelt, welche wiederum kaum Felder beinhalten, kann man dies bequem auf der Kommandozeile machen. Als Objektbezeichnung für einen Arbeitszeiteintrag habe ich mich an die gute, alte Stempeluhr erinnert und das Objekt deshalb Stamp genannt:

$ rails generate scaffold Stamp date_start:datetime date_end:datetime description:text

Das Objekt heisst Stamp und es weist drei Felder auf: date_start, date_end und description, denen die jeweiligen Titel zugewiesen werden. Nützlich war mir hier eine Liste der für’s Scaffolding verfügbaren Feldtypen.

Dies erstellt den Controller, welcher für das Auflisten (index), Anzeigen (show), Erstellen (new), Speichern (create) Editieren (edit), Aktualisieren (update) und Löschen (destroy) zuständig ist. Natürlich ohne, dass ich als Entwickler eine einzige Zeile Code schreiben muss. Genial!

Datenbanktabelle erstellen

Zuletzt erstellen wir nun die physische Tabelle in MySQL:

$ rake db:migrate --trace

Webserver starten

Ich habe einige Zeit damit verbraten, die Applikation über Apache 2 bereitzustellen. Leider momentan noch fruchtlos, u.a. weil sich die Anleitungen auf Rails 2 beziehen, welches offenbar noch ein dispatch.fcgi mit sich brachte. Dies fehlt im DocumentRoot ~/public einer 3er-Applikation.

Die Verwendung von Apache ist dabei gar nicht zwingend nötig — für Web-Entwickler stellt Rails (natürlich!) einen eigenen rudimentären Web-Server zur Verfügung. Man startet diesen über

$ cd /var/rails/arbeitsjournal
# rails server

Aus dem Intranet kann man nun auf den Testserver zugreifen, indem man Port 3000 anspricht. In meinem Falle war dies mad4you.homeip.net:3000.

Routing einrichten

Wer obigen Link aufruft, erhält die Standard-Willkommensseite für Rails-Projekte zu gesicht, die unter ~/public/index.html abgelegt ist.

Benennt man diese Datei kurzerhand um, kriegt man eine Fehlermeldung zu Gesicht. Rails kann nämlich nicht hellsehen und weiss nicht, was der Benutzer eigentlich für eine Seite angezeigt erhalten möchte. Ein Abstecher in die Routing-Datei ~/config/routes.rb und eine klitzekleine projektbezogene Anpassung hilft weiter:

...
root :to => "stamps#index"
...

Auf Deutsch: Diese Anweisung sagt Rails, dass falls ein Request namens GET / reinkommt, dieser auf die Stamps-Objekte weitergeleitet werden soll und dort die Auflistung aller Datenbankwerte

Views und Helper anpassen

Jetzt folgt die Knochenarbeit — zum ersten Mal muss Ruby programmiert werden. Hier sollte sich jeder Web-Entwickler rasch heimisch fühlen, denn abgesehen von einer anderen Programmiersprache ist das Vorgehen nun jedem mit dem MVC-Paradigma vertrauten Entwickler bekannt: Views anpassen, Helper-Funktionen entwickeln und im Controller Kollisionsabfragen etc. implementieren.

Die Pfade zu den entsprechenden MVC-Elementen lauten in meinem Fall:

  • ~/app/models/stamb.rb
  • ~/app/views/stamps/*.html.erb
  • ~/app/controllers/stamps_controller.rb

Insbesondere in ~/app/views/stamps/index.html.erb kann man genügend rumfuhrwerken. Hier vermischen sich HTML-Code und Ruby-Code, und hier kann der Entwickler genauestens steuern, wie die erfassten Daten ausgegeben respektive ausgewertet werden sollen.

Sehr wichtig ist ~/app/helpers/stamps_helper.rb, um die View nicht mit Ruby-Code zu überladen. Dorthin lagert man sich alle nützlichen kleinen Methoden aus, die mehrmals im Code benutzt werden und es deshalb Sinn macht, Redundanzen zu vermeiden.

Fertig? Fertig!

Ab jetzt verfügt man über eine funktionierende Web-Applikation, um Arbeitsstunden zu erfassen. Rails hat die entsprechenden Controller-Aktionen automatisch bereitgestellt und ich kann sofort mit dem Einfüllen von Daten beginnen.

In einem weiteren Artikel werde ich mich um einige Finessen kümmern, die für PHP-Entwickler anders, ungewohnt, oftmals aber äusserst erleichternd sind.

Tags: , , , , ,
Labels: Web

3 Kommentare | neuen Kommentar verfassen