Nato: Echt jetzt?

Nato-Generalsekretär Stoltenberg ändert Rhetorik:

«Wie viel Gebiet ist die Ukraine bereit, für den Frieden zu opfern?»

blick.ch – 13.06.2022

Frage: Wieso soll man einen Aggressor auch noch belohnen? Damit er einfach weitermacht und immer mehr Gebiete an sich reist?

Anmerkung: Dass es nicht funktioniert, hat man schon bei der Krim gesehen …

Keine Literatur kann in puncto Zynismus das wirkliche Leben übertreffen.

Anton Pawlowitsch Tschechow

Wikipedia: Anton Pawlowitsch Tschechow

11.04.2022

Nachdem ich dieses Video gesehen habe, fehlen mir wirklich die Worte, um meine Gedanken zu beschreiben. Wie kann man so stark sein? Ich habe grossen Respekt vor dieser starken Persönlichkeit.

https://youtu.be/YxfbrmPUrac?t=429
Ausschnitt aus dem Video – ganzes Video

„Das sind die Starken, die unter Tränen lachen, eigene Sorgen verbergen und andere glücklich machen.“

(Franz Grillparzer)

Links

Ganzes Video

Wikipedia: Franz Grillparzer

24.02.2022

An den Frieden denken, heisst an die Kinder denken.

Wikipedia: Michail Sergejewitsch Gorbatschow

Der 24.02.2022 beweist wieder einmal mehr wie dumm der Mensch sein kann. Leider nichts aus der Geschichte gelernt.

Warum kämpft man nicht gemeinsam gegen den grössten Feind, der alle Menschen bedroht? Vielleicht wäre es sinnvoller, die Ressourcen zum Retten unseres Planeten Erde zu verwenden, anstelle sich gegenseitig abzuschlachten?

Zum Glück hat die Geschichte uns auch folgendes gelernt:

“Hochmut kommt vor dem Fall”

So long, and thanks for all the fish

Mercury/32 v4.90 released

David Harris hat am 23.10.2021 eine neue Version des Mercury/32 Mailserver veröffentlicht.

Version 4.9 is an important major release containing numerous significant changes and fixes.

https://community.pmail.com/index.php?u=/topic/11469/mercury-32-v4-90-released

Nützliche Links

http://www.pmail.com/

C#: Factory methode to create new instance

Angenommen, wir haben ein Objekt AppColor, welches uns beim Erstellen der gewünschten Farben hilft. Wir möchten die Möglichkeit besitzen, die Farben über die Parameter Red, Green, Blue und Alpha zu steuern. Weiter brauchen wir verschiedene Möglichkeiten, um das Objekt zu initialisieren – sprich zu erzeugen. Direkt mit allen Parametern RGBA, nur RGB oder den einzelnen Farben. Dies führt dazu, dass wir eine ganze Reihe an Konstruktoren im Objekt haben werden:

public AppColor(byte red = 0, byte green = 0, byte blue=0, byte alpha=0)
{
    Red = red;
    Green = green;
    Blue = blue;
    Alpha = alpha;
}
public AppColor(byte red, byte green, byte blue)
{
    Red = red;
    Green = green;
    Blue = blue;
    Alpha = 0;
}
public AppColor(byte red)
{
    Red = red;
    Green = 0;
    Blue = 0;
    Alpha = 0;
}
...

Eine viel elegantere Lösung können wir mit einer Fabrikmethode (Factory methode) erstellen. Dazu erstellen wir eine Sub-Klasse mit dem Namen Builder, welche sämtliche Parameter als einzelne Methode enthält und als Rückgabewert wieder sich selber enthält. Zusätzlich wird noch eine Methode Create benötigt, welche dann das eigentliche Objekt erstellt:

public class Builder
{
#region fields
private byte _red;
private byte _green;
private byte _blue;
private byte _alpha;

#endregion

#region methodes
public Builder Red(byte red)
{
    _red = red;
    return this;
}
public Builder Green(byte green)
{
    _green = green;
    return this;
}
public Builder Blue(byte blue)
{
    _blue = blue;
    return this;
}
public Builder Alpha(byte alpha)
{
    _alpha = alpha;
    return this;
} 

public AppColor Create()
{
    return new AppColor(_red, _green, _blue, _alpha);
}
#endregion
}

Welche Vorteile haben wir nun mit diesem Konstrukt? Jetzt haben wir die Möglichkeit, eine x-beliebige Kombination von Parameter zu verwenden, um das Objekt AppColor zu erstellen:

// Einzelne Farbe
AppColor colorRed = new AppColor.Builder().Red(255).Create();

// Gemischte Farbe
AppColor mixColor = new AppColor.Builder().Red(22).Green(25).Create();

// Gemischte Farbe
AppColor mixColor2 = new AppColor.Builder().Green(25).Blue(12).Create();

// Gemischte Farbe
AppColor mixColor3 = new AppColor.Builder().Red(255).Green(255).Blue(0).Alpha(215).Create();

...

Ganze Klasse

C#: Statements as expressions

if-Statement as expression

Normales if-Statement:

public static decimal GetPriceByStatement(decimal price, int quantity, bool isPremiumMember)
{
    decimal discountAmount = 0;

    if(quantity >= 12)
    {
        discountAmount += .1M;
    }
    if (isPremiumMember)
    {
        discountAmount += .20M;
    }

    return price * (1 - discountAmount);
}

Das if-Statement als expression:

public static decimal GetPriceByExpression(decimal price, int quantity, bool isPremiumMember)
{
    decimal discountAmount = (quantity >= 12 ? .1M : 0) 
                + (isPremiumMember ? .2M : 0);
    return price * (1 - discountAmount);
}

swtich-statements as expression

Normales switch-Statement:

public static decimal GetNumberOfAccessLevelStatement(AccessLevels accessLevels)
{
    decimal accessLevelNumber = 0;
    switch (accessLevels)
    {
        case AccessLevels.Low:
            accessLevelNumber =  100501;
            break;
        case AccessLevels.LowExtendSecurity:
            accessLevelNumber = 100511;
            break;
        case AccessLevels.Middle:
            accessLevelNumber = 100601;
            break;
        case AccessLevels.MiddleExtendSecurity:
            accessLevelNumber = 100611;
            break;
        case AccessLevels.High:
            accessLevelNumber = 100701;
            break;
        case AccessLevels.HighExtendSecurity:
            accessLevelNumber = 100711;
            break;
        default:
            accessLevelNumber = 0;
            break;
    }
    return accessLevelNumber;
}

Das switch-Statement als switch-expression:

public static decimal GetNumberOfAccessLevelExpression(AccessLevels accessLevels)
{
    decimal accessLevelNumber = accessLevels switch
    {
        AccessLevels.Low => 100501,
        AccessLevels.LowExtendSecurity => 100511,
        AccessLevels.Middle => 100601,
        AccessLevels.MiddleExtendSecurity => 100611,
        AccessLevels.High => 100701,
        AccessLevels.HighExtendSecurity => 100711,
        _ => 0,
    };
    return accessLevelNumber;
}

C#: Zeichenketten richtig vergleichen

Vergleiche die zwei Namen “ROBONAME” und inputName, aber ignoriere die Gross- und Kleinschreibung.

const string ROBONAME = "iRoby";
string inputName = "IROBY";


if (0 == string.Compare(ROBONAME, inputName, true))
{
    Console.WriteLine($"Die Namen {ROBONAME} und {inputName} sind gleich.");
}

Nützliches

C# reference: https://docs.microsoft.com/en-us/dotnet/api/system.string.compare?view=net-5.0

Best practices for comparing strings in .NET: https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings

C#: String-Interpolation

Mit dem Dollar-Zeichen definieren wir, dass es sich um einen “interpolated string” handelt.

Struktur:

{<interpolationExpression>[,<alignment>][:<formatString>]}

Beispiel: String mit einem formatierten Datum

var msg = $"Datum: {DateTime.Today:dd.MM.yyyy}";

Beispiel: String mit einem formatierten Dezimalwert:

var shortPi = $"Pi is {Math.PI:F3}";

Beispiel mit Sonderzeichen und einem “conditional operator”:

Als Ausgabe erhalten wir:

Nützliches

C# reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

C#: Null-Forgiving Operator (!)

Null-forgiving oder null-suppression operator

Wenn die Null-Prüfung des Compilers aktiviert wurde (“enabled nullable annotation context”), wird das Ausrufezeichen “!” Verwenden, um bewusst einen Nullwert zu erlauben.

Den “nullable annotation context” aktivieren oder deaktivieren

Null-Prüfung des Compilers ein- ausschalten mit Preprocessor-Direktiven:

#nullable enable
#nullable disable

Die Null-Prüfung kann auch auf der Projektebene in der Projekt-Datei eingeschaltet werden:

Nach dem Aktivieren der Null-Prüfung zeigt der Compiler eine Warnung bei möglichen Nullwerten an:

Sollte ein bestimmter Wert auch Null sein dürfen, haben wir die Möglichkeit, den “Null-Forgiving Operator” zu verwenden:

Nützliches

C# reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving

C#: Finde die grösste und kleinste Zahl in einem String

Vorgaben

  • Der String enthält nur gültige Zahlen getrennt durch ein Leerzeichen und mindestens eine Zahl
  • Ausgabe ist ein String mit der grössten und kleinsten Zahl

Beispiele

EingabeAusgabe
“1 2 3 4 5 6 7 8 9 10”“10 1”
“-100 99 45 0 1 354”“354 -100”

Meine erste Lösung

public static string HighAndLow(string numbers)
{
    var sortedList = numbers.Split(" ")
                .Select(x => Convert.ToDecimal(x))
                .OrderByDescending(o => o);
    return $"{sortedList.First()} {sortedList.Last()}";
}

Meine zweite optimierte Lösung

public static string HighAndLow(string numbers)
{
    var sortedList = numbers.Split(" ").Select(int.Parse);
    return $"{sortedList.Max()} {sortedList.Min()}";
}

Unit-Test

public void GetHighAndLowTest()
{
    Assert.AreEqual("354 -100", Snippets.HighAndLow("-100 99 45 0 1 354"));
    Assert.AreEqual("10 1", Snippets.HighAndLow("1 2 3 4 5 6 7 8 9 10"));
    Assert.AreEqual("1 1", Snippets.HighAndLow("1"));
    Assert.AreEqual("3002 -68", Snippets.HighAndLow("-68 3001 3 5 -5 " +
        "42 3002 -1 0 0 -9 4 7 4 -4"));
    Assert.AreEqual("42 -9", Snippets.HighAndLow("8 3 -5 42 -1 0 0 -9 4 " +
        "7 4 -4"));
}