Posts mit dem Label Code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Code werden angezeigt. Alle Posts anzeigen

13. März 2019

A Coders Take on BREXIT: The Lupus Solution

Usually I avoid politics and that's what I also do in this post. No opinion, I am actually 50:50 anyway. I am enjoying the show. This is purely technical.

In short: EU article 50 is a timer. It can be cancelled and restarted any time. Just like the programming timers we know. So, the solution is exactly what we do in programming: cancel and restart.

On 4 December 2018, the responsible Advocate General to the ECJ published his preliminary opinion that "a country could unilaterally cancel its withdrawal from the EU should it wish to do so, by simple notice, prior to actual departure".

Meaning, that the UK can cancel Brexit any time. But the UK can also restart Brexit at any time again. There are no time limits, no grace periods, no rate limiting on article 50 cancelling and triggering.

That makes the solution obvious: send two letters to the EU back to back.
  • the first with the cancellation of the article 50 process,
  • the second with a new trigger of article 50. 
(In practice you would play it safe and leave one day between cancel and reset.)

The result would be (almost) the same as the already planned 2 year  transition period. The March 2019 date is only the legal departure date. for all practical purposes, the UK leaves 2 years later after the transition period (December 2020). Let's get rid of the transition period and call it a second article 50 process, another two years. Practical separation would then be March 2021, only 3 months later than already planned.

Just make a law in parliament to cancel article 50 AND trigger it immediately again. 

Gives you time for a referendum or a general election or just a good transition period. Anything you want. Gives you time and changes nothing. The move just gets rid of the threatening no-deal timer.

Bonus: an extension of article 50 requires the agreement of all EU members. But the cancel/restart-move can be done by the UK alone.

Bonus Bonus: 2 years transition is what the Brits wanted, but the EU wanted a clean end of year date. So they settled for 21 months. A simple timer reset makes that 24 months again. Owned!

The ECJ handed this solution to the UK. They know what they do. This was not an accident. They mean it. That's the way out. Just do what every programmer does with timers: reset.

_happy_resetting()

PS: it's clearly an exploit and a bit shady. But it's legal. The contract is not meant to be used this way. But many contracts are "stretched". What happened to "no bailout" in the Euro zone? Giving Greece money to be (maybe) payed back in 50 years, is a stretch. What happened to the "prohibition of monetary financing"? Ah, yes, The ECB buys government bonds not directly from he governments, but from the "secondary markets". The ECB so much that the "intermediate" banks are actually straw men, being paid to circumvent Article 123. Another stretch. So, contracts are stretched, if deemed necessary. All we have, unfortunately, is the written word. The written words allow it AND it's necessary.

PPS: If people ever wanted to make exploit proof contracts and laws, then they could ask the gaming industry for advice. They have thousands of specialists who make a living by preventing the exploitation of coded rules. If computer games as an example are too low for you, then ask IT security experts or turn to academics in the field of game theory, the study of mathematical models of strategic interaction between rational decision-makers.

PPPS: In the long run: if you can do it twice, then think n+1. We can do this every other year. Maybe the UK and EU get used to it. Gives the UK a feeling of independence. And that's what it's all about, anyway. Every two years, UK activates article 50 and cancels it two years later. In practice: every other year, Brussels receives a briefcase with 2 letters from London. Could be a nice tradition in the long run. A typically British exception from EU rules.

28. Februar 2019

Agile mit Super Powers

Superboys: Edict-Abhilekh on Pixabay
tl;dr Scrum Rollen superpowern: Es gibt viel zu tun. Deshalb muss man Fähigkeiten zusammenlegen: Scrum-Master coacht auch agile Technologien, Product Owner macht UX-Design, Visual-Designer kann Frontend-Programmierung, Entwicklungsleiter ist Technik-Coach für Product Owner.

In der realen Welt haben wir mehr Rollen, als die bekannten Scrum-Rollen: Scrum Master, Product Owner und Entwicklerin.

Außerdem gibt's da noch:
  • Tester, die Test-Ingenieure sein sollten, nicht Durchklicker, sondern Integration-Test-Entwickler und Test-System Managerinnen,  
  • Admins, früher Operator, jetzt Devops, also Devs mit Leidenschaft für Betrieb, 
  • Systemarchitektinnen, die sich oft aus den Entwicklern rekrutieren und auf jeden Fall aktiv in den Entwicklungsteam sein sollten, vielleicht organisiert in Communities of Practice, aka Chapters, 
  • UX-Designer, ständig ein bisschen gebraucht, denn bei jedem Feature mit Business-Value für Benutzerinnen ist UX wichtig, 
  • Visual-Designer, soll ja auch gut aussehen, oft zwischen mehreren Teams geteilt oder sogar extern bei einer Agentur oder beim Auftraggeber. Burst-artige Arbeitslast und deshalb immer in der Gefahr, die Entwicklung aufzuhalten. 
  • Produkt Managerin, die auch gewillt ist mit dem Agile-Team ins Eingemachte zu gehen und zusammen was umzusetzen. Phantastisch, wenn sie nicht aufhört bei Marktpotential/Marktbeobachtung und Anforderungen, sondern selbst die User Stories scheibt. 
  • Marketing, Vertrieb, Controlling, Management… sind auch nötig, damit was geht, schon klar.
Von den Entwicklerinnen verlangt man heute viele Fähigkeiten:
  • Frontend und Backend, jeweils mit ihren aktuellen (und schnell wechselnden) Frameworks, 
  • Unit Tests ohne Zeit-Overhead während des Codings "einfließen" zu lassen, 
  • Integration-Tests und GUI-Tests aufzusetzen und up-to date zu halten während sich UX Workflows ändern, 
  • Beherrschung von Continuous Integration/Deployment Systemen, 
  • Container und Orchestrierung, 
  • Virtuose Bedienung von Code Repositories für Quellcode, Pakete, Container (Stichworte: GitFlow, nuget/PEAR, Dockerhub). Nicht nur benutzen, sondern auch bereitstellen, intern und extern. 
  • Code Reviews und Refactoring
  • Code-Metriken
  • Kenntnis und Benutzung von Monitoring-Systemen für Alarm, Dashboard und KPIs, 
  • Clean Code, Design Patterns, Entwicklungsumgebungen und deren Extensions, 
  • Security (in Code, Libraries aus Repos?, Operating), 
  • Reliability-Engineering, 
  • Skalierung (Up and Out)
  • Konfiguration der APIs und GUIs diverser Cloud-Anbieter und Meta-Cloud-Services, 
usw.

Unter den Entwicklern gibt es Spezialisten für das alles. Aber nehmen wir ein Team von 7, (UX-) Designer, Tester, Admin (ähm, Devops), Frontendler, Backenderin. Eigentlich sollen alle alles können, aber nicht jede, die Microservices containerisiert ist gleichzeitig ein CSS3-Wizard. Dann wird es langsam eng mit den oben genannten Spezialfertigkeiten. Coden sollen sie ja auch noch. 

Warum machen wir das alles?

Damit Features entstehen. Features, die User glücklich machen. Features entstehen durch Coding. Ohne Coding keine Features. Viel Coding - viele Features, wenn sonst alles stimmt.

Fragt man in der Retro "was hat dich in diesem Sprint vom Coden abgehalten?" - typische Antwort: "Meetings", aber auch immer öfter "Infrastruktur" und vor allem: Infrastruktur aneignen, neu lernen und verstehen. 

Ganz viel dieser Infrastruktur macht uns agil bzw. ist nötig für agile Arbeitsweise über Scrum/Kanban hinaus:  Continuous-*, Container, Cloud, Clean Code, Frameworks, Repositories…

Die Infrastruktur hat gemeinsam: Sie ist aufwändig für jede einzeln zu lernen, aber notwendig, und wenn erstmal gelernt, dann völlig OK. Aber bis dahin dauert es.

Man kann das nicht alles den Entwicklern aufbürden, deshalb verteilen wir das:

Superpower #1: Agile-Coach mit agiler Technologie

Es könnte/sollte/müsste die Aufgabe des Scrum-Masters sein, agile Technologien in das Team zu tragen, so wie auch agile Arbeitsweisen in das Team getragen werden. Natürlich soll die Scrum-Masterin nicht dauerhaft den Build-Server betreuen (obwohl sie das kann, wenn sie mehrere Hüte aufhaben will/kann/soll). Es geht darum, dass der Agile-Coach das Wissen in das Team trägt, damit nicht immer wieder wertvolle Entwicklerzeit darauf verwendet wird, zu lernen, wie man einen KPI-gesteuerten Continuous Deploment Prozess konfiguriert. Und wenn wir schon dabei sind: Es ist auch die Aufgabe des Agile-Coaches, die Beschäftigung mit Clean-Code und Design-Patterns zu stimulieren, vielleicht sogar selbst zu schulen, zumindest aber die Seniors dazu zu bringen, dass sie ihr Wissen teilen. Aber dazu muss man wissen, was es zu teilen gibt. Sorry, liebe SMs aus dem Persönlichkeitscoaching, eine agil-technische Scrum Masterin macht das Team nicht nur glücklicher, sondern auch schneller, viel schneller. Und mit "schnell" kommt dann auch "glücklich": Superpowered Scrum-Master.

Superpower #2: Product Owner mit UX-Design

Bei allen Features mit Business-Value für Endbenutzer ist UX wichtig. Coding ist dafür da, dass die Funktion funktioniert. Aber "glücklich" werden Benutzer durch gutes UX-Design, nicht nur schöne GUIs, sondern vor allem gute Workflows. Ein Product Owner gießt die Stakeholder-Anforderungen in User Stories. Bei fast jeder Story ist UX-Design nötig, zumindest Grundkenntnisse, besser umfassende. Eine gute UX-Designerin kann lernen, wie man User Stories schreibt und vielleicht sogar wie man mit Stakeholdern redet. Aber ob ein Product Owner UX lernt? UX-Design ist ein Beruf und gottgleiches User-Story Schreiben eine Berufung. Erst die klassische Ausbildung: gute Anwendungen entwerfen, dann die agile Spezialfähigkeit: User Stories und Kommunikation: Superpowered Product Owner.

...und weil wir schon dabei sind. Das wäre auch toll:

Superpower #3: Visual-Designer mit Frontend-Programmierung

Wenn die Visual-Designerin gut ist, wird die Anwendung schön. Wenn sie das, was designed wurde, auch umsetzen kann, ist es toll für alle. Denn dann muss sie das Design nicht an den Entwickler übergeben. Es gibt keine Rückfragen, keine Verzögerung, keinen Mind-Bruch. Sie kann beim Design gleich die technischen Randbedingungen berücksichtigen. Keiner muss der CSS-Sklave für die Designerin sein. Die Arbeitslast ist viel ausgeglichener, so dass man kann sich eine ganze Designerin exklusiv pro Team leisten jund nicht mehr UX-Designer zwischen Teams teilen muss: Superpowered Designer.

Superpower #4: Entwicklungsleiter mit Technik-Coach für Product Owner

Viele Product Owner kommen nicht aus dem technischen Bereich. Das ist gut so, um die Entwicklung mit dem Produktmanagement zu verzahnen. Auf der anderen Seite ist es von Vorteil, wenn die User Stories so geschrieben werden, dass sie 1. in die Gesamtarchitektur passen und 2. die Entwickler verstehen und machen, was gemeint war. Für beide Fälle ist es gut, wenn jemand aus der Technik den Product Owner bei der Formulierung der User Stories berät. Eigentlich sind die Entwicklerinnen die technischen Berater des Product Owners. Aber das kostet Entwicklerzeit, oft von allen. Deshalb bürden wir das lieber der Entwicklungsleiterin auf. Die Entwicklungsleiterin kennt die Gesamtarchitektur, die IT-Strategie und sie versteht wie Entwickler denken. Sie schreibt nicht die Stories um. Nur der PO schreibt User Stories. Aber eine Entwicklungsleiterin kann durch Fragen den Product Owner dazu bringen, die Stories so zu schreiben, dass die Entwickler die Stories verstehen und dass sie in das Gesamtkonzept passen. Eine Stunde pro Woche und Team reicht, um die technische Qualität der User Stories deutlich zu verbessern. Die Entwicklungsleiterin kann so wissen was passiert und gleichzeitig etwas steuern. Die Stunde pro Woche mit dem PO ist das effizienteste Steuerungswerkzeug der agilen Entwicklungsleiterin, ohne den agilen Prozess zu verletzen. 

Heute sind viel mehr Fertigkeiten nötig. Man muss Fähigkeiten zusammenlegen. Nicht nur bei den Entwicklern, denn die sollen entwickeln. Alle müssen mehr machen und mehr können als bisher. 

Niemand hat gesagt, dass Superkräfte einfach sind.

#SuperPoweredAgile

_happy_powering()

19. Mai 2017

CSS Customize Visual Studio Online Task Board - Remove Columns And Make it Denser

I use Visual Studio Online task board a lot for Scrum projects. But I do not like how much screen space it takes primarily because of lots of empty space.

So, I remove the empty space:

  • I do not need the "To be tested" and "Testing" columns.
  • The cards could be smaller with less margins and paddings
That's it.

I use Tampermonkey to inject CSS into the page.

Just install the Tampermonkey Chrome/Firefox extension and use this script:

Before/After:



More info, less white (grey) space.

_happy_tampering()

PS: Once you have Tampermonkey you will see lots of opportunities to change the layout of web sites. You don't have to live with it. You can change it.

For example: a script which make visual studio build colors more pronounced to counter my red-green-color weakness:

5. Dezember 2016

JsonPath

Any time a piece of my software receives a JSON message it must dive into the JSON and extract parameters. Sometimes the JSON is deeply nested and parameters are buried inside arrays of objects of arrays.

I want to access these parameters quickly without dissecting the JSON by looping and if-ing through the layers. In other words: I want single line expressions to dive into JSON and extract values.

You can call it XPath for JSON, but in a language integrated and compiled way, which is much faster, than XPath and supported by Intellisense (autocomplete).

GitHub project: https://github.com/wolfspelz/JsonPath
NuGet package: https://www.nuget.org/packages/JsonPath

Example: extract the 42 from:

var data = "[ '1st', '2nd', { 'aString': 'Hello World', 'aNumber': 42 } ]"

... parse it:

var json = new Node(data);

... extract it:

int fourtytwo = json[2]["aNumber"];

Invalid keys do not throw exceptions. They return 0 (zero), "" (empty string), or empty list:

int zero = json[1000]["noNumber"];

Of course, you can foreach a dictionary (aka JS object):

foreach (var pair in json[2]) {}

And iterate over a list (aka JS array):

for (int i = 0; i < json.Count; i++) {
    string value = json[i];
}

You can even LINQ it:

json[2].Where(pair => pair.Key == "aNumber").First().Value

and:

(from x in json[2] where x.Key == "aNumber" select x.Value).First()

Now get me the 50 from this JSON:

var data = "[ { 
        aInt: 41, 
        bLong: 42000000000, 
        cBool: true, 
        dString: '43', 
        eFloat: 3.14159265358979323 
    }, { 
        fInt: 44, 
        gLong: 45000000000, 
        hString: "46"
    }, { 
        iList: [ 
            { jInt: 47, kString: '48' }, 
            { lInt: 49, mString: '50' }
        ], 
    }
]";

I can do it in a single line, no foreach no if:

var fifty = json[2]["iList"][1]["mString"];

Other people had the same idea years ago: http://goessner.net/articles/JsonPath/. But there does not seem to be a C#/.NET implementation yet. So here it is: GitHub, nuget.

_happy_jsoning()


25. Januar 2016

Compile on Save for Typescript in Visual Studio with Gulp

The standard way to develop with Typescript in Visual Studio 2015 (ASP.NET 5, MVC6) is to create a so called "virtual project" in a folder. That's a Typescript project inside a Web-C# project. This embedded Typescript project automatically compiles Typescript files on build.

Javascript files can be changed and reloaded while a project is running (debugging). But new Typescript code will not be available until the project is restarted.

The better way is to let gulp do the compilation. But let's start with the standard way (the few steps you do here are required later anyway).

Setup the virtual Typescript project:

  • Add a folder for Typescript scripts to the Web project, e.g. "./Scripts"

  • Put a tsconfig.json file into the folder (it contains "outFile": "../wwwroot/js/ts/scripts.js") which bundles all generated Javascript in a single file scripts.js in the "wwwroot/js/ts" folder.

  • Add a folder "ts" in "wwwroot/js". This is the Typescript compiler destination folder. Compiling into a sub folder of "wwwroot/js" has the advantage that generated Javascript will be minimized like all other Javascript inside "wwwroot/js" by the the Visual Studio build step. This is nice for Release builds. For our debug session we use the non-minimized "wwwroot/js/ts/scripts.js" in the HTML.

  • Add your *.ts files to the "./Scripts" folder

  • A Visual Studio build will generate "scripts.js" and "scripts.js.map" (.map for debugging Typescript source code in IE or at least watching Typescript in Chrome).

  • Add a reference to "scripts.js" in your HTML like this: <script src="/js/ts/scripts.js"></script>.
But:

The *.ts files are only compiled and bundled when the project is built. No edit/save/reload-browser cycle. The debug session must be stopped to make new Typescript code available for browser reload.

There is a solution.

Let gulp do the Typescript compilation and trigger the compilation with a gulp file watcher.

Here is the code: https://gist.github.com/wolfspelz/d494bd8a1ba56ff81c91

Here are the steps:
  • Add a Scripts folder for Typescript files (as before for the virtual project).

  • Add a file "_tsconfig.json" to the Scripts folder (can be any name, but the name appears in "gulpfile.js"). I just renamed my existing "tsconfig.json" to "_tsconfig.json" to hide it from Visual Studio and re-use it with gulp-typescript.

  • Add gulp modules by editing "package.json". Visual Studio should download lots of node packages.



  • Add gulp tasks by editing "gulpfile.js" in three places:
  • 1. Add gulp requires at the top.

  • 2. Add the Typescript source path further down.

  • 3. Add two tasks.

  • Saving "gulpfile.js" should show two new tasks in the Task Runner Explorer: "compile-ts" and "watch".

  • Check that the "compile-ts" task works. Double click "compile-ts" in the Task Runner Explorer. It should compile and combine all Typescript into "scripts.js" in the same place as before with the virtual project.

  • Once "compile-ts" works, we can automate the Typescript compilation with the new "watch" task. In the Task Runner Explorer, bind the "watch" task to the "Project Open" event. Right-click "watch"  => Bindings => Project Open. Result:

  • You might check if the "watch"/"compile-ts" workflow works by starting "watch" and editing/saving a Typescript file in the Scripts folder.
  • Close/Open the project/solution or just stop/start Visual Studio. The "watch" task should be running after starting Visual Studio settles down.

  • Delete the "scripts.js" file from earlier "compile-ts" runs.

  • Edit/save a Typescript file. The "watch" task should start "compile-ts":

  • Check if the "scripts.js" is generated along with it's "scripts.js.map".

  • Start a debug session. 
  • Change Typescript code. Reload browser.
  • Voilà
  • The default behavior of Visual Studio for Typescript without a virtual project (and a proper "tsconfig.json") seems to be compile-on-save.It generates a Javascript for each Typescript in the "Scripts" folder. We can just ignore them. Maybe nice to check the generated Javascript code.

_happy_gulping()

PS: There could be a clean-ts task

Thanks to

21. September 2015

Feature Flags

(Image: bytearrays.com)
In one of my projects I just stumbled across the topic "Feature Flags".

Feature flags (aka Feature Toggle, aka Feature Switch) let you enable program/web site features selectively. This is especially important in continuous delivery environments where code is always committed and deployed even if a feature is not ready for prime time. It can be useful if you have a large user base and want to introduce the feature incrementally by enabling the feature for sub-sets of users. Feature flags are useful in anything beyond toy apps.

Feature flags are not new. They are widely known since Martin Fowler blogged about the pattern. He did not invent them. Many good developers have been using feature flags or alike for a long time. But Martin Fowler recognized feature flags as a remarkable pattern. Writing about feature flags was a good idea, because other developers who are not aware of the pattern can learn from it. That was 2010.

Guess what, in 2006 a lonely Weblin programmer added feature flags to the Weblin portal. Weblin has been using feature flags from the start.

_happy_flagging()

15. September 2015

ZEIT online Relaunch - Undo

ZEIT online hat gerelauncht. Jetzt irgendwie dunkel und schmaler als vorher. Gefällt nicht. Kann man aber fixen. 

Links: ZEIT nach Relaunch, 
Rechts: gefixt: wieder weiß, ohne Rand 


Wie?

Mit Tampermonkey, eine Chrome Erweiterung. Tampermonkey führt auf jeder Webseite Javascript aus.

Bei ZEIT online muss man nur ein paar CSS Anweisungen verändern: den Hintergrund vom <body>-Tag wieder in weiß und der Rahmen vom Content-<div> weg:

body { background-color: #ffffff !important; } 
.page__content { box-shadow: none; }

Man braucht noch etwas Javascript, um das CSS einzufügen. Hier das ganze Tampermonkey-Script für ZEIT online:

// ==UserScript==
// @name        ZEIT
// @namespace   http://wolfspelz.de/
// @version     0.1
// @description Restore white background
// @match       http://www.zeit.de/*
// @copyright   2015+, wolfspelz
// ==/UserScript==

function addGlobalStyle(css) {
    var head, style;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}

addGlobalStyle('body { background-color: #ffffff !important; } .page__content { box-shadow: none; }');

_happy_tampering()

Für Firefox: Greasemonkey

6. August 2015

Minimalinvasiver Bootstrap Bestätigungsdialog (Confirm Modal Dialog)

Ab und zu braucht man bei Webanwendungen einen Bestätigungsdialog, bevor die Benutzerin eine Aktion auslöst, zum Beispiel "Do you really want to delete …"


Das geht mit Bootstrap sehr schlank und fast ohne Änderungen am Code. Kein Umstellen eines Links auf Button mit click-Aktion, kein Aufruf einer Javascript Dialog-Klasse, keine extra Funktionen als Callbacks, die auf Dialog-Button-OK oder –Abbrechen reagieren, sondern…

…etwas HTML (für den Dialog) und 2 Zeilen JavaScript zum Verdrahten.

Der Trick: Angenommen es gibt einen Link, dem der Confirm-Dialog vorgeschaltet werden soll. Das href-Attribut des Links wird zum "OK"-Button des Dialogs weitergereicht und der Link stattdessen zum Öffnen des Dialogs benutzt.

Ein Klick auf:

Delete

<a href="/Offer/Delete">Delete</a>

würde das Angebot (Offer) sofort löschen. Das soll durch einen Bestätigungsdialog abgesichert werden:

Dafür muss man 3 Dinge tun:

1. Dem Link sagen, dass er den Dialog aufrufen soll

<!—data-target und data-toggle aktivieren den Dialog beim Klick-->
<a href="/User/Delete" data-target="#ConfirmDialog" data-toggle="modal" id="DeleteButton">Delete</a>

2. Den Dialog definieren (irgendwo im Body)

<!-- Modal dialog -->
<div class="modal fade" id="DeleteDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">Echt jetzt?</h4>
            </div>
            <div class="modal-body">Willst du das Angebot wirklich löschen?</div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary btn-ok">OK</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">Abbrechen</button>
            </div>
        </div>
    </div>
</div>

3. Alles verdrahten:

// Beim ursprünglichen Link:
$('#DeleteButton').each(function () { $(this)
  // Link als data-href sichern
  .data('href', $(this).attr('href'))
  // Link durch # entschärfen
  .attr('href', '#');
});
// Beim Öffnen des Dialogs:
$('#DeleteDialog').on('show.bs.modal', function (e) { $(this).find('.btn-ok')
    // …das gesicherte href-Attribut zum OK-Button weiterreichen 
  .attr('href', $(e.relatedTarget).data('href'))
    // Beim OK-Klick zum href navigieren
  .click(function () { location.href = $(this).attr('href'); });
});

Das sieht viel aus, aber in der Praxis schreibt sich das so:

$('#DeleteButton').each(function () { $(this) .data('href', $(this).attr('href')) .attr('href', '#'); });
$('#DeleteDialog').on('show.bs.modal', function (e) { $(this).find('.btn-ok') .attr('href', $(e.relatedTarget).data('href')) .click(function () { location.href = $(this).attr('href'); }); });

_happy_confirming()

PS: Nur eins der vielen kleinen Themen, die so ein Web-Projekt aufwirft: www.essenbeifreunden.com

7. Februar 2015

How to Make Your Site Responsive and Mobile Friendly in Minutes

Assumed you have a web site for years. It has a traditional layout with a header, a menu sidebar, and a content area. The menu sidebar and also the header do not fit very well on a smartphone screen.

We need a scrolling friendly vertical design. It should appear automatically whenever the screen width is the size of a smartphone. We need an overlay menu instead of the menu sidebar.

And we need it quickly without a complete redesign. 

This is what I just did for my old web site http://www.galactic-developments.de

(Because it went so smooth and easy, I'll report what I did. Maybe it helps someone. Paying back to the Web.)


Starting with a typical nice static, not responsive, not smartphone compatible design:




We will turn it into a responsive design with popup menu:




...in 10 minutes.

The Basic Principle:

HTML5/CSS3 offers a simple mechanism to switch designs based on device properties: media queries. A media query applies the enclosed CSS only if the query condition is met. 

I insert this into the HTML of the page template of my CMS (I could also add it to my CSS file):

@media screen and (max-width:700px) {
  // here will be CSS
}

Media Queries override general CSS-styles. Inside the curly braces I will now redefine some of the styles. By redefining I can make elements disappear, change sizes, and change the layout.

The above CSS means, that the styles will be applied to screens (not when printed) and which are smaller than 700 pixels.

Things to do:

1. Remove Header, Footer, and Frame

The frame in the background must disappear. The background consists of three <div>s with a background image each. Top and bottom <div>s also contain other graphics and buttons. They will all disappear. The center <div> also has my text and the menu. The center <div> will stay. But it will loose it's background. Luckily these three <div>s already have IDs. So I can add these lines inside the media query:

  #bgtop { display: none; }
  #bgcenter { background: none; }
  #bgbottom { display: none; }

... which makes my new media query CSS look like:

@media screen and (max-width:700px) {
  #bgtop { display: none; }
  #bgcenter { background: none; }
  #bgbottom { display: none; }
}

See, how the header and the vertical frame disappeared:


2. Menu

The menu should not be statically on the left side. It should be invisible at start and accessible from a menu button. If I press the menu button, then the menu should appear.

I decided, that the menu button should be in the top right corner of the screen and the menu will appear on the right side. Reason: the button in the top right corner will cover less of the text. There is free space at the top right while the top left always has text. I move the menu from the left side, which is also left of the text, to right side and above the text. My menu <div> has the ID "menu":

#menu {
  position:fixed; right:0px; top:0px; 
  background-color:#ffffff; padding:4px; 
}

The position will to be fixed even if the page is scrolled. There is a 4 pixel padding which is filled by a white background color for a small distance between the content below and the menu:


If you make the window wide, then it has still the original design.

3. Menu Button

This will be my menu button:


I insert the button <div> into the HTML (I put it just before the header <div>):

<div id="menubutton"></div>

Add CSS for the menu button:

#menubutton {
  display: block; position:fixed;
  right:4px; top:4px; width:24px; height: 24px;
  background:url(img/menubutton.png);
}

Shift the the menu down to make room for the menu button:

  #menu { margin-top:28px; }

Add a small JavaScript section to the HTML to toggle the visibility of the menu, when the menu button is pressed (jquery would be overkill, could use jquery for fade/slide animations, though):

<script>
 
document.getElementById('menubutton').onclick = function()
  {     
    var m = document.getElementById('menu'); 
    m.style.display = (m.style.display == 'block' ? 'none' : 'block');
  };
</script>

    When the page loads, then the menu should not be visible (it will be shown by the menu button):

      #menu { display: none; }


    4. Device Scaling:

    Pixel densities on mobile devices are usually higher than on desktop/laptop screens. And they differ. But all devices should show about the same amount of text. This means, that a scaling factor must be applied, which scales the page depending on the DPI of the device. The command for that comes as a meta tag. Add it to the HTML <head> section (of the web site template):

    <meta name="viewport" 
      content="width=device-width,initial-scale=1,user-scalable=no"
    />

    That's basically it:

    5. Additional Tweaks:

    Pixel densities on mobile devices are usually higher than on desktop/laptop screens. So I changed the baseline font size from 12px to 14px (this might be more effort depending on your existing CSS). In my case:

    * { font-size:14px; }

    On small smartphone screens, like old iPhones, the menu is too long. I remove some menu entries, which are not really important. I do this by assigning IDs to menu entries like. I changed:

    <li><a href="stuff.html">Wallpapers</a></a>

    to:

    <li id="menuWallpapers"><a href="stuff.html">Wallpapers</a></a>

    ...and add this to the CSS:

      #menuWallpapers { display: none; }

    As you see in the screen shot, my text is too wide. The reason is, that in my original design I assigned a fixed width to the content area, so that the text does not flow outside the border. Now, the text width should adjust to the device width. In my case, there are two <div>s to be fixed:

      #bgcenter, #main { width: auto; }

    I want to remove the page URL from the top. I don't think it's very useful, especially on a mobile screen. The page URL is only on the start page. It is a page content, not in the template of all pages. Still, I can hide it with a CSS in the same place as the other CSS tweaks.

    In other words: a style which is only used by a single page is configured globally by the media query CSS section. No problem. Since the link is inside a <div class="link">:

      .link { display: none; }


    A small shadow for the menu is no mistake:

      #menu {
        -webkit-box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 1);
        -moz-box-shadow:    0px 0px 8px 0px rgba(0, 0, 0, 1);
        box-shadow:         0px 0px 8px 0px rgba(0, 0, 0, 1);

      }

    Result:




    Summary:

    The complete CSS:

    @media screen and (max-width:700px) {
      #bgtop { display: none; }
      #bgcenter { background:none; }
      #bgbottom { display: none; }
      #menu { margin-left: 0px; }
      #menu { 
        position:fixed; right:0px; top:0px; 
        background-color:#ffffff; padding:4px; 
      }
      #menubutton {
        display: block; position:fixed;
        right:4px; top:4px; width:24px; height: 24px;
        background:url(img/menubutton.png);
      }
      #menu { margin-top:28px; }
      #menu { display: none; }
      * { font-size:14px; }
      #menuWallpapers { display: none; }
      #bgcenter, #main { width: auto; }
      .link { display: none; }
      #menu {
        -webkit-box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 1);
        -moz-box-shadow:    0px 0px 8px 0px rgba(0, 0, 0, 1);
        box-shadow:         0px 0px 8px 0px rgba(0, 0, 0, 1);

      }
    }

    A bit HTML and JavaScript for the menu button:

    <div id="menubutton"></div><script>
      document.getElementById('menubutton').onclick = function()
      {     
        var m = document.getElementById('menu'); 
        m.style.display = (m.style.display == 'block' ? 'none' : 'block');
      };
    </script>
    A meta tag in the HTML <head>:

    <meta name="viewport" 
      content="width=device-width,initial-scale=1,user-scalable=no"
    />

    _happy_scaling();

    Of course, there are other ways to make a responsive web site. You could use a mobile friendly CSS package, like bootstrap. But that probably means, that you will redesign your site, which won't be done in an hour.

    Of course, there are more modern ways to program the menu button. You could use jquery and this JavaScript:

      $('#menubutton').click(function() { $('#menu').fadeToggle(); });

    But you have to include 100 kB jquery library:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

    14. Dezember 2014

    ConfigSharp - Scripting Configuration in C#

    ConfigSharp (github, nuget)

    Config files are C# source files, managed by Visual Studio like any other code file: intellisensed, refactorable, resharpered, syntax checked, compiled, type safe.

    Write real code with control structures and classes in config files. Include other local or remote (HTTP) config files.

    No more key-value lists of string based app settings in XML. These settings are typed properties of CLR objects, even aggregated types. No more workarounds for complex settings, which do not fit properly in strings.

    Devops friendly, because admins can program their config files. Developers can document settings with examples in their own code, which also is the admins's config file.

    BTW: this is what everyone (PHP, Python, RoR) does. Configuration in your main language.

    Example: 

    Program.cs
    static void Main(string[] args)
    {
        var config = new MyConfig();
        config.Include("ConfigFile.cs");
        ...
        var prop1 = config.SomeProperty;
        // or
        var prop2 = Config.Global.SomeProperty;
        var prop3 = App.Settings.SomeProperty;
        var prop4 = AppSettings.Get("SomeProperty", "default");
    }
    
    public class MyConfig : ConfigSharp.Container
    {
        public string SomeProperty { get; set; }
        public int OrAsMemberVariable = 41;
        public DateTime PlainOldCLRTypes;
        public NLog.Config ComplexAggregatedTypes;
    }
    ConfigFile.cs
    namespace MyProgram.Configuration // any namespace
    {
        class ConfigFile : MyProgram.MyConfig // Derived from your config class
        {
            public void Load()
            {
                SomeProperty = "42";
                Include("OtherConfigFile.cs");
            }
        }
    }
    

    More on github and nuget.

    _happy_configuring();

    Tags: Config, Roslyn, C#, Script, Scripting, CLR, Configuration, File, HTTP, Remote, C# Script, Devops

    Rant: XML config files. Static, unreadable XML hell. What where they thinking? Anyone is configuring their app in the native project language. Only poor high level language coders use XML or ini files. Even worse: generating XML config files for different environments with XSLT transformations from master XML config files. Are they out of their mind? Web.config Transformation Syntax for Web Application Project Deployment. <add... xdt:Transform="Replace" xdt:Locator="Condition(@name='oldname' or @providerName='oldprovider')"> --- Condition(), or, @, What? There is already a proven syntax: it is called C#. There is already a good transformation: it is called compiler. This must end now, once and for all.

    29. Oktober 2014

    Microservices bei Weblin

    Und wieder einmal bekommt ein Prinzip, das wir bei Weblin entwickelt und benutzt haben, einen Namen: Microservices.

    "Microservices is a software architecture design pattern, in which complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs"

    Wir haben es natürlich nicht erfunden. Viele andere gute Softwareingenieure haben zur gleichen Zeit das gleiche gemacht und inzwischen ist das Prinzip (=architecture design pattern) im Mainstream angekommen und hat einen Namen und es gibt viele Artikel und Vorträge.

    Es geht darum, dass man nicht eine fette Anwendung macht, sondern mehrere (viele) von einander logisch getrennte Web-Services, die jeweils eine Funktionalität des Gesamtsystems bereitstellen und untereinander kommunizieren. Das betrifft sowohl Client/Server Kommunikation, als auch Server-Frontend/Backend und innerhalb vom Backend. Microservices können in verschiedenen Sprachen geschrieben sein und haben typischerweise jeweils eigene Datenbanken (wenn auch oft auf dem gleichen Datenbankserver). Microservices können horizontal oder vertikal skalieren,d.h. alle können auf der gleichen Server Farm laufen oder man ordnet einzelnen Microservices dedizierte Server zu.

    Welches Web-Service Protokoll man wählt spielt eine untergeordnete Rolle. Eigentlich kann man Transportprotokoll und Datenformat beliebig kombinieren. REST/JSON ist dafür momentan das Mittel der Wahl. Aber SOAP geht auch. XMLRPC war mal sehr verbreitet. Bei Weblin hatten wir oft Key/Value/LF als Datenformat (auch liebevoll SRPC genannt), weil das meistens völlig ausreicht. Es geht aber auch anspruchsvoller, z.B. mit Protocol Buffers als Datenformat. Als Transportprotokoll bietet sich HTTP an. Aber es geht auch plain TCP oder ein Message-Bus.

    Bei Weblin hatten wir Microservices für:

    • Userdaten (Identity), vom Frontend bespielt, vom Client benutzt
    • User created content upload (der berühmte File-Service: files.zweitgeist.com)
    • Download-Server
    • Wallet-Service und Punktekonto
    • Topsites-Service
    • XMPP-Server Management Service
    • Unit-Test (System-Runtime-Test) als Web-Service
    • GeoIP Auflösung als Web-Service
    • Kontaktlistenverwaltung
    • Wuscheln, Publisher (alles, was der Client wollte, ich sage nur "srpc.php")
    • VPI-Server
    • Compute-Service (Avatar-Generator)
    • Locatr
    • Ad-Server
    _happy_eigenlobing()

    25. September 2014

    Simple Token Authentication for .NET Web API

    A simple way to use tokens in HTTP requests for authentication in Web API with [Authorize] attribute including Identity, Principal and Roles. 

    Sample code: https://gist.github.com/wolfspelz/a080601bbd3988782701


    Valid tokens are stored statically in Azure-CloudConfigurationManager. This can be changed easily to check a real database of tokens.

    _happy_authenticating()

    30. Mai 2014

    Software ist so ein Weichei

    (Symbolbild)
    Da arbeitet man Monate an einem Stück Software. Tausende Zeilen Code, hunderte Klassen und Objekte, zig trickreiche Stellen und ein paar geniale Kniffe, ohne die es nicht geklappt hätte. Alles ist fertig, fast alles ist solide, das meiste sogar robust. Jetzt wird released.

    Deployment, Pressemitteilung, Traffic kommt, User auch. Das Leben ist eine Party.

    Plötzlich: bei der Presseagentur geht's nicht. Ein Geschäftspartner hat einen Absturz. Ein Kollege hatte das auch mal auch, hat aber nichts gesagt, weil Neustarten geholfen hat. Ein paar User sind genervt, aber man kann es ja nie allen Recht machen. Der Vertrieb sagt es geht überhaupt nicht, naja, die übertreiben immer. Das kennt man ja.

    OK, selbst probieren: es stimmt, da ist ein Problem. Nicht groß, aber es nervt genug, dass man es eigentlich nicht lange benutzen will. Und man erinnert sich an so einen nervigen Fehler, der manchmal während der Entwicklung aufgetreten ist. Aber F5 hat immer geholfen.

    Eigentlich geht's ja, zumindest 99,9 %. Die verdammte Software ist so undankbar. Die User auch. Man könnte es ja auch richtig benutzen. Endlos viel Arbeit und alle reden nur über den einen kleinen Fehler. Dabei ist der Rest so toll.

    Merke: ein Fehler der selten auftritt ist auch ein Fehler. Er will gefunden werden, sonst ist er beleidigt und ärgert uns später.

    Merke: das eine Prozent vom Code mit den problematischen Stellen ist das wichtigste. Das darf es nicht geben. Sonst war alles umsonst.

    _happy_debugging()

    21. Mai 2014

    JsonTree Library and Nuget Package for Quick and Easy JSON Parsing


    Any time a piece of my software receives a JSON message it must dive into the JSON and extract parameters. Sometimes the JSON is deeply nested and parameters are buried inside arrays of objects of arrays.

    I want to access these parameters quickly without dissecting the JSON by looping and if-ing through the layers. In other words: I want single line expressions to dive into JSON and extract values.

    You can call it XPath for JSON, but a language integrated compiled way, which his much faster, than XPath and supported by IntelliSense (autocomplete).

    Example JSON: 

    [ "first", { "aString": "HelloWorld", "aNumber": 42 } ]
    Extract the value 42:
    var fourtytwo = json.List[1].Dictionary["aNumber"].Int;
    The JsonTree library basically maps JavaScript Arrays to C# Lists and a JavaScript Objects to C# Dictionaries. It is then very easy to enumerate lists of dictionaries of lists, etc as single line expressions to extract values. Also, if looping is required, it is done on well known container classes List<...> and Dictionary<string,...>.

    A more complex example:
    var data = "[ { aInt: 41, bBool: true, bLong: 42000000000, cString: "43", dFloat: 3.14159265358979323 }, { aInt: 44, bLong: 45000000000, cString: "46" }, { aList: [ { aInt: 47, bString: "48" }, { aInt: 49, bString: "50" } ], bMap: { aInt: 51, bString: "52" } } ]";
    Extracting the 50 as integer number. The 50 is a string value in a JS object (of key "bString") in a JS array (as second element) in a JS object (with key "aList") in a JS array (as third element).
    var fifty = new JsonTree.Node(data).Array[2].Object["aList"].Array[1].Object["bString"].Int;
    JsonTree uses either JavaScript notation with Array and Object as keywords or C# notation with List and Dictionary as keywords. Choose whatever you like more. 

    The same as above in C# notation:
    var fifty = new JsonTree.Node(data).List[2].Dictionary["aList"].List[1].Dictionary["bString"].Int;
    Other examples:
    var pi = new JsonTree.Node("{a:3.1415927}").Dictionary.First().Value.Float;

    var pi = new JsonTree.Node("{a:3.1415927}").Dictionary["a"].Float;
    You can use JsonTree as nuget package: https://www.nuget.org/packages/JsonTree/

    Or check out the source code on Google code: https://code.google.com/p/json-tree/

    JsonTree also includes a flexible JSON serializer which is used to create a easy to read debug view of the JSON structure. Browsing the JSON in debug mode is a real highlight. 



    The serializer can also be used to add elements to a deserialized JSON node and re-serialize.

    _happy_parsing()

    PS: I know that I could use NewtonSoft JSON with C# dynamic and JObject
    PS: I know that I could use LINQ

    I like this way, because it relies only on plain old CLR objects, List and Dictionary.

    25. Februar 2014

    Visual Studio 2010 Projects Always Out of Date Solved by Changing the File Date

    If your Developer Studio suddenly tells you, that your project is "out of date". If it keeps telling you, even though you rebuild all. If a simple F5 always pops the annoying "These projects are out of date" dialog box, then ...

    ... you probably ran into a bug that lets Visual Studio think, that a totally unrelated file on your disk is a dependency of your project(s). This file probably has been added to your disk recently and for unknown reasons Visual Studio regards it as dependency.

    In my case its "C:\PROGRAMDATA\NVIDIA CORPORATION\DRS\NVDRSDB0.BIN" from a newly installed Nvidia driver. Other files have also been reported like "C:\PROGRAMDATA\SOPHOS\SOPHOS ANTI-VIRUS\CONFIG\CONFIG.BOPS".

    There might be other reasons for this behavior, like missing header files. These can be resolved easily, by adding the missing file or removing it from the solution.

    This article is about solving the case of "Visual Studio Project Out Of Date Because of Weird Dependency".

    The standard way to solve this is to
    1. find out which file claims to be newer than your project.
    2. Exclude the offending file.

    Step 1:
    Enable Visual Studio debugging and check the log. Basically:
    in
    %ProgramFiles(x86)%\Microsoft Visual Studio\10.0\Common7\IDE\
    after
    </configSections>
    insert

    <system.diagnostics>
      <switches>
        <add name="CPS" value="4" />
      </switches>
    </system.diagnostics>
    Then use DgbView to get the log output.

    Step 2:
    There seem to be ways to exclude the file or folder from the list of dependencies. This can be done for each project or system wide (which is probably what you want).

    I am not a fan of changing details in large XML config files with weak documentation and multiple possible insertion points of which only one works and the others make things worse, and which affects all projects.

    But I still tried.

    Unfortunately, I do not get these solutions to work. My project still wants to rebuild every time.

    There is another solution: 

    Just change the "modified" file date of the offending file.

    I am using Attribute Changer to date the file back by 2 years (or whatever). Simple and works.

    For the record: I download tools like Attribute Changer only from trusted software repositories. You should too. Do not download from the "homepage" of the program. Anyone can make a homepage and send you anything.

    _happy_attributing()