Wunderschönes Comic - gezeichnet und gesprochen von Meistern.
Eine schräge Mischung aus japanischem Samurai-Gemetzel mit western Einflüssen plus Handies und Roboter...
Wunderschönes Comic - gezeichnet und gesprochen von Meistern.
Eine schräge Mischung aus japanischem Samurai-Gemetzel mit western Einflüssen plus Handies und Roboter...
... auf die Shell zu ziehen und ins Highlighting zu ziehen. :) (Sorry, ich muss dringend mal wieder Herr der Ringe anschauen)
Mir geht es um grep
, der Urgroßvater aller Projektweiten Suchmöglichkeiten. Das kann viel - aber nicht alles.
Zum Beispiel ist es nicht besonders einfach in einem Projekt zu suchen dass SVN für die Versionskontrolle einsetzt. Grep besteht nämlich darauf dass es unbedingt bei -r auch in .svn
Verzeichnissen suchen will. Und das beste: es gibt zwar eine Option --exclude
- die funktioniert aber nur auf File-Basis. Das heiĂźt man kann damit keine Verzeichnisse (wie z.B. .svn
) ausschlieĂźen.
Doh.
Die Entwickler sagen dazu dass man doch lieber find . mumbojumbomagic | grep muster
 benutzen soll. Tja.
Enter Ack. Die Lösung aller Probleme. :)
-r
angeben.--python
oder --objc
nur in Dateien dieses Typs suchen.~/.ackrc
konfigurieren.Hier meine .ackrc:
$ cat ~./ackrc
--type-set=nib=.nib
--type-add=objc=.mm
--ignore-dir=build
Schick ne?
Was ich als SpaĂź alles verpasst habe, weil ich sowas noch nicht gesehen habe.
Damit ist sogar endlich geklärt wie es Jesus geschafft hat über das Wasser zu gehen.
:-)
Ach ja, die Erklärung (Wikipedia) und mehr details (Wikipedia) und eine Anleitung zum Selber herstellen.
Have phun!
Heute hatte ich das witzige Erlebnis dass wir in ein Parkhaus gefahren sind - und einfach keinen Parkplatz gefunden haben.
Ok, soweit wars noch nicht spannend - aber was ich hoch-interessant fand, ist dass wir dann beim Rausfahren nicht zur Kasse gebeten wurden. Das macht Sinn, denn wer keinen Parkplatz findet, ist natürlich Dreifach angepisst wenn er dann dafür auch noch Zahlen muss. (Und vielleicht während dessen auch noch den Ausgang versperrt.. :)
Ich halte es fĂĽr sehr wahrscheinlich, dass jedes Parkhaus so funktioniert. Cool. Denn das bedeutet, dass man prinzipiell jedes Parkhaus umsonst benutzen kann - man muss sich nur unmittelbar vor dem herausfahren eine neue Marke besorgen.
:)
(Ok, das mag nicht soo leicht sein, aber im Prinzip...)
--- zumindest scheint es so.
Das hier zum Beispiel:
#!/usr/bin/env python # encoding: utf-8 def counter_generator(): current_value = 0 def counter(): current_value += 1 return current_value return counter import unittest class ClosureTest(unittest.TestCase): def test_counter(self): self.assertEquals(1, counter_generator()()) if __name__ == '__main__': unittest.main()
Wenn man das ausführt dann kriegt man den wenig aussagekräftigen Fehler UnboundLocalError: local variable 'current_value' referenced before assignment. Oder mit anderen Worten: "Wiebidde?"
Kommentiert man current_value += 1 aus, funktioniert das ganze (ok, bis auf den dann fehlschlagenden Testcase).
Immerhin kommt man dem Problem dann auf die Spur (ich und Felix haben das leider erst herausgefunden nachdem wir auf #python nachgefragt haben...) Python kann nämlich seine Scopes nicht vernünftig. Das heißt, man kriegt keinen schreibenden Zugriff auf die Variablen eine Funktion weiter draußen - nur lesend. Nur dass die Fehlermeldung natürlich total mist ist.
Grah.
Interessanterweise geht diese Lösung auch nicht
#!/usr/bin/env python # encoding: utf-8 def counter_generator(): workaround = object() workaround.current_value = 0 def counter(): workaround.current_value += 1 return workaround.current_value return counter import unittest class ClosureTest(unittest.TestCase): def test_counter(self): self.assertEquals(1, counter_generator()()) if __name__ == '__main__': unittest.main()
FĂĽr hinweise wieso bin ich dankbar.
Vielleicht kriegt Python dass ja irgendwann mal hin. In der Zwischenzeit hilft dieser Workaround:
#!/usr/bin/env python # encoding: utf-8 class AttributableDict(dict): def __getattr__(self, attribute_name): return self[attribute_name] def __setattr__(self, attribute_name, value): self[attribute_name] = value def counter_generator(): workaround = AttributableDict() workaround.current_value = 0 def counter(): workaround.current_value += 1 return workaround.current_value return counter import unittest class ClosureTest(unittest.TestCase): def test_counter(self): self.assertEquals(1, counter_generator()()) if __name__ == '__main__': unittest.main()
iCal - ein Programm das man lieben und hassen kann.
Einerseits, es funktioniert gut, ist ordentlich ins System integriert - aber andererseits sowas:
Wenn man einen Termin bearbeitet, dann doppelklickt man ihn. Danach öffnet sich dieser in einem neuen Fenster, in dem man dann noch einmal auf Bearbeiten klicken muss damit man ihn tatsächlich verändern kann.
Das tolle daran: Wenn man dann irgendwann mit seinen Änderungen zufrieden ist und ihn bestätigen möchte, dann stellt man fest das der "Bestätigen" Knopf auf keinen sinnvollen Keyboard Shortcut reagiert. Enter, Return, Controll-Return, Command-Return, Alt-Return - alles voll daneben.
Bisher dachte ich nur: "Naja, voll nervig" aber heute ist mir aufgefallen dass sie es sogar geschafft haben dem noch die Spitze aufzusetzen: Es gibt nämlich doch eine Tastenkombination um die gemachten Änderungen zu akzeptieren:
ESCAPE
!!!!1111!!!!(elf)!!!
Ich bin Sprachlos.
(With many thanks to Dan Levin for his help)
This is what I arrived at [blog:2008/08/19/19.49 last week] as an authentication GUI:
This GUI Design has several good and bad points - first the good ones:
The bad ones though weigh very heavy:
The most pressing problem however is in the library support from OTR. It simply does not know what a question is.
This is a problem, because it makes it almost impossible to have the Question as a special entitiy in the GUI - and also that none of the synchronisation problems that this brings are adressed in the GUI. So what to do if both users start typing their own question? The other User wouldn't know - then how does the programm tell the user that his question was just overruled be the other persons and that he should provide the answer to that as the secret word?
There is more of course - but this is what I consider the most important.
Well, this is our current approach at solving these problems:
This is what I like about this:
Especially this is the most simple GUI of all the approaches that I tried.
I don't have finished mockups of the other aproaches (most is pen'n'paper work) but I did try having the question and answer thing inline like so:
I especially like the fact that this gives lots of practical information to the user - even if it is still very wordy and does not solve the race condition of who will actually ask the question.
Therefore we decided to go with the first aproach pictured above.
There is of course more to this GUI than just the pretty pictures shown above. A few more things come to mind, that we think are very important:
One unsolved problem is, that when the authentication fails multiple times, we need to find a good compromise between teaching the user about ways to prevent errors and making him aware of the possibility that there may be a man in the middle attack taking place.
Of course, just as the last time: Feedback welcome.
Stimmt einfach. :)
Und zwar gewaltig.
Heute hab ich eine Menge Zeit darauf verbrannt unserem Online-Update-System auf den Zahn zu fühlen. Das arbeitet nämlich ganz hervorragend mit Sparkle um für unsere Applikation via Appcast herunter zu laden, wenn eine neue Version ansteht. Und damit das auch schön sicher ist, nutzen wir ein kleines öffentlich/privates Schlüsselpärchen um das abzusichern.
Nun ja, bis heute mittag - da hat es nämlich auf einmal aufgehört und konnte die heruntergeladenen Dateien nicht mehr validieren.
Jetzt hatte ich natĂĽrlich das Problem, das ich an sich recht wenig von Crypto verstehe und erst recht wie man das von der shell aus einsetzt. Das wiederum hatte zur Folge, dass ich das nicht sofort auf der Shell nachvollziehen konnte und wir schon anfingen zu fĂĽrchten das vielleicht unsere SchlĂĽssel abgelaufen sind.
Gott sei dank war es aber doch was anderes - denn unser Proxy hatte fieser weise einfach eine alte Version des Appcasts gespeichert und stattdessen immer die ausgeliefert - was natĂĽrlich nicht funktionierte... Grumpf.
Note to self: Nächstes mal gleich den ganzen Vorgang von Hand reproduzieren um zu sehen wo es schief läuft - und zwar angefangen von da wo das Programm anfängt. (Auch wenn in diesem Fall die Fehlermeldung wirklich eher auf einen OpenSSL Fehler hindeutete).
Debuggen ist eben schwieriger als den Code zu schreiben. Ich vermute, weil man ihn dafür wirklich verstehen muss - inklusive aller Fehler die man in seinem eigenen Verständnis hat.
P.S.: So Signiert und Validiert man ein File mit OpenSSL von der Kommandozeile:
# base 64 encoding to ease textual transmission openssl dgst -dss1 -sign dsa_private_key.pem Important.rtf | openssl enc -base64 > signature.sig # and decode again openssl enc -base64 -d < signature.sig > decoded.signature.sig # and verify openssl dgst -dss1 -verify dsa_public_key.pem -signature decoded.signature.sig Important.rtf
Einige Fallstricke: -dss1 und -sha1 erzeugen offenbar die gleichen Checksummen (man könnte also meinen das es der gleiche Algorithmus ist) die beiden digest modi werden aber in openssl offenbar unterschiedlich behandelt. Beim Signieren löst das verwenden von -sha1 auch schön eine Fehlermeldung aus - wenn man beim Überprüfen aber -sha1 zu verwenden versucht, dann erhält man nur den Hinweis dass die Verifikation gescheitert ist - an einem falschen public key. Seeehr hilfreich liebe Entwickler.
Wie man ein SchlĂĽsselpaar erzeugt und vieles mehr gibts hier.
Apple hat sich da ja einen richtigen Kracher geleistet mit ihrem App-Store. Vor allem ist das Update-System absolut grandios gelöst.
Man geht einfach im iPhone auf den App-Store, dort in den Updates-Reiter und.... sieht nichts. Weil, da sind zwar die Updates. Aber eben nicht alle.
Ein Programm das ich mir gekauft hatte (Things, weil die UI einfach sehr, sehr gut ist) tauchte dort nämlich nicht auf - obwohl ich es sehnsüchtig erwartete. Und das, obwohl der iTunes Store das Programm schon längst als upgedatet aufgelistet hat.
Tja, was tun? Letztlich habe ich mich dann dafür entschieden, dass ich für 8 € auch das Programm einfach noch einmal herunterladen kann. Wenigstens kann ich dann die neue Version nutzen. Und kann so mal Probieren ob der App-Store nicht vielleicht einen Bug hat und mir den Preis nur fälschlicherweise anzeigt.
Gesagt getan - da kommt dann erst eine Warnung dass der Betrag jetzt direkt von meiner Kreditkarte abgezogen wird (gut, Kreditkarte hab ich nicht, aber das ist halt ne Amerikanische Firma) und dann... dann kommt der Dialog der mir erklärt das ich das Produkt ja schon gekauft hätte und das Update daher kostenlos sei.
Pfffff. Wenn ich ein Update lade, dann will ich vorher wissen ob mich das Geld kostet! Vorher, nicht hinterher. Vielleicht.
Ganz groĂźe Klasse.