C#: Sortiere die Wörter im String anhand ihrer enthaltenen Zahl

Vorgaben

  • Der String enthält verschiedene Wörter, getrennt durch ein Leerzeichen, welche richtig sortiert einen Satz ergeben
  • Jedes Wort hat an beliebiger Stelle eine Zahl, welche die Position im Satz angibt
  • Wenn der Eingabe-String leer ist, gibt die Funktion einen leeren String zurück
  • Der Eingabe-String enthält nur gültige Werte

Beispiel

EingabeAusgabe
Ap7fel h2abe Ic1h un4d Hung3er 5möchte ein6Ic1h h2abe Hung3er un4d 5möchte ein6 Ap7fel

Meine erste Lösung

public static string OrderWordsByNumber2(string words)
{
    if (string.IsNullOrWhiteSpace(words)) return string.Empty;

    return String.Join(" ", words.Split(" ")
        .Select(x => new { word = x, pos = x.First(v => Char.IsDigit(v)) })
        .OrderBy(x => x.pos)
        .Select(x => x.word));
}

Meine zweite optimierte Lösung

public static string OrderWordsByNumber(string words)
{
    if (string.IsNullOrWhiteSpace(words)) return string.Empty;
    return String.Join(" ", words.Split(" ")
        .OrderBy(x => x.ToList().First(v => Char.IsDigit(v))));        }
}

Unit-Test

[Test]
public void DuplicateCountTest()
{
    Assert.AreEqual("1Das is2t ei3ne spannend4e Aufgabe5",
        Snippets.OrderWordsByNumber("Aufgabe5 1Das ei3ne is2t spannend4e"));
    Assert.AreEqual("Ic1h h2abe Hung3er un4d 5möchte ein6 Ap7fel",
        Snippets.OrderWordsByNumber("Ap7fel h2abe Ic1h un4d Hung3er 5möchte ein6"));
    Assert.AreEqual("", Snippets.OrderWordsByNumber(""));
}

C#: String zu “Camel-Case” konvertieren

Vorgaben

  • Die Funktion entfernt “-“, “_” und ändert den darauf folgenden Buchstaben auf einen Grossbuchstaben
  • Der erste Buchstaben wird nur grossgeschrieben, wenn dieser bereits im Eingabe-String gross ist

Beispiele

calculate_total-pricecalculateTotalPrice
Get_from-weather_apiGetFromWeatherApi

Meine Lösung

public static string ToCamelCase(string str)
{
    return Regex.Replace(str, @"[-_]\w", delegate(Match matches)
        {
            return matches.ToString().Substring(1).ToUpper();
        });
}

Meine optimierte Lösung

Die Regex Anpassung mit zusätzlichen Klammern @”[-_](\w)” – Subexpression ermöglicht es, direkt auf den gesuchten Buchstaben zuzugreifen.

public static string ToCamelCase(string str)
{
    return Regex.Replace(str, @"[-_](\w)", delegate (Match matches)
    {
        return matches.Groups[1].Value.ToUpper();
    });
}

Meine zweite optimierte Lösung

Das “Delegate” kann auch mit “Lambda expressions” geschrieben werden.

Lambda expression

public static string ToCamelCase(string str)
{
    return Regex.Replace(str, @"[-_](\w)", 
        m => m.Groups[1].Value.ToUpper());
}

Unit-Test

public void ToCamelCaseTest()
{
    Assert.AreEqual("calculateTotalPrice", 
        Snippets.ToCamelCase("calculate_total-price"));
    Assert.AreEqual("GetFromWeatherApi", 
        Snippets.ToCamelCase("Get_from-weather_api"));
}

Nützliches

Tool for building and testing regular expressions on the .NET regex engine: http://regexstorm.net/tester

C#: Finde die Anzahl mehrfach vorhandenen alphanumerischer Zeichen oder Zahlen in einem String

Vorgaben

  • Gross- Kleinschreibung spielt keine Rolle
  • String enthält nur alphanumerische Zeichen oder Zahlen

Beispiele

StringRückgabe der Funktion
“abcde”0
“aacDeii”2
“Aaahjkl”1

Meine erste Lösung

public static int DuplicateCount(string str)
{
    var charAmounts = str.GroupBy(x => x.ToString(),
        StringComparer.CurrentCultureIgnoreCase)
        .Select(x => new { Character = x.Key, Count = x.Count() });

    return charAmounts.Where(x => x.Count > 1).Count();
}

Meine zweite verbesserte Lösung

public static int DuplicateCount(string str)
{
    return str.ToLower().GroupBy(x => x)
        .Where(y => y.Count() > 1).Count();
}

Unit-Test

[Test]
public void DuplicateCountTest()
{
    Assert.AreEqual(0, Snippets.DuplicateCount(""));
    Assert.AreEqual(0, Snippets.DuplicateCount("abcde"));
    Assert.AreEqual(2, Snippets.DuplicateCount("abbcdde"));
    Assert.AreEqual(2, Snippets.DuplicateCount("aabBcde"));
    Assert.AreEqual(2, Snippets.DuplicateCount("Schifffahrt"));
    Assert.AreEqual(3, Snippets.DuplicateCount("Affenbrotbaum"));
    Assert.AreEqual(1, Snippets.DuplicateCount("Nuss"));
    Assert.AreEqual(1, Snippets.DuplicateCount("2mal2"));
    Assert.AreEqual(2, Snippets.DuplicateCount("333Fragen22"));
}

C#: Finde die ungerade oder gerade Zahl in einem Array

Ausgangslage

  • Das Array enthält immer Werte
  • Die Werte können gerade oder ungerade Zahlen sein
  • Möglicher Array Aufbau:
    • x beliebige gerade Zahlen + 1 ungerade Zahl
    • x beliebige ungerade Zahlen + 1 gerade Zahl

Lösungsvorschlag

public static int FindEvenOrOddNumber(int[] numbers)
{
    var oddV = numbers.Where(x => x % 2 != 0).ToList();
    var evenV = numbers.Where(x => x % 2 == 0).ToList();

    return (oddV.Count > 1) ? evenV.First() : oddV.First();
}

Unit-Tests

[Test]
public void FindEvenOrOddNumberTest()
{
    int[] numbers = { 2, -4, 6, 
8, -10, 9, 12, -16 };
    Assert.IsTrue(9 == Snippets.FindEvenOrOddNumber(numbers));
}

[Test]
public void FindEvenOrOddNumberTest2()
{
    int[] numbers = { 222444888, 7, 19, 1979, 89, 1, 25787, 11,1979};
    Assert.IsTrue(222444888 == Snippets.FindEvenOrOddNumber(numbers));
}

C# 9: Verbessertes “Pattern Matching”

Relational Patterns

Ab C# 9 können Werte mit Relational Patterns geprüft werden:

<kleiner als
>grösser als
<=kleiner oder gleich
>=grösser oder gleich

Dazu nun ein Code Beispiel:

using System;

namespace ConsoleApp2
{
    class Program
    {
        public class Animal
        {
            public string Name { get; set; }
            public int Weight { get; set; }
            public int YearOfBirth { get; set; }
        }

        static void Main(string[] args)
        {
            var animal = new Animal()
            {
                Name = "Tiger"
                ,Weight = 300
                ,YearOfBirth = 2016
            };

            if (animal is Animal { Weight: > 200 } animalWeightMoreThen200)
            {
                Console.WriteLine($"Animal is more then 200kg! " +
                    $"Weight: {animalWeightMoreThen200.Weight}kg");
            }
        }
    }
}

Wir haben ein Objekt Animal. Bevor wir mit diesem Objekt arbeiten, prüfen wir, ob es vom Typ Animal ist. Mit einem “Relational Pattern” können wir nun auch sicherstellen, dass unser Tier mehr als 200 kg wiegt, bevor wir damit arbeiten.

Pattern Combinators

Seit C# 9 haben wir nun auch die Möglichkeit mehrere Patterns zu kombinieren. Dazu haben wir folgende Möglichkeiten:

andund
oroder
notnicht

Dazu nun ein Code Beispiel:

using System;

namespace ConsoleApp2
{
    class Program
    {
        public class Animal
        {
            public string Name { get; set; }
            public int Weight { get; set; }
            public int YearOfBirth { get; set; }
        }

        static void Main(string[] args)
        {
            var animal = new Animal()
            {
                Name = "Tiger"
                , Weight = 299
                , YearOfBirth = 2016
            };

            if (animal is Animal { Weight: > 200 and < 300, 
                Name: "Tiger" } tigerWeightBetween200And300)
            {
                Console.WriteLine($"The tiger weight is between 200kg and 300kg! " +
                    $"Weight: {tigerWeightBetween200And300.Weight}kg");
            }
        }
    }
}

Wir haben ein Objekt Animal. Bevor wir mit diesem Objekt arbeiten, prüfen wir, ob es vom Typ Animal ist. Mit den kombinierten “Relational Patterns” können wir nun auch sicherstellen, dass unser Tier mehr als 200 kg und weniger als 300 kg wiegt und der Name Tiger ist, bevor wir damit arbeiten.

Nützliche Links

Microsoft docs: Pattern matching enhancements

C# 9.0: Improved Pattern Matching

Raspberry Pi Imaging Utility: Die magische Tastenkombination ab V. 1.6

Ab der Version 1.6 des Raspberry Pi Imager kann mit der Hilfe der neuen Tastenkombination das Image für den Raspberry Pi zusätzlich konfiguriert werden.

ctrl + shift + x

Diese neue Tastenkombination erlaubt die Vorab-Konfiguration von SSH und WLAN sowie das Setzen der Spracheinstellungen und das festlegen des Hostnamen. Wird der Raspberry Pi an einem Monitor betrieben, hat man nun auch die Möglichkeit, den “Overscan” zu deaktivieren. Dadurch wird der standardmässige schwarze Rahmen um das Bild ausgeschaltet.

Nützliche Links

Raspberry Pi Imaging Utility

Raspberry Pi OS Lite installieren mit dem Raspberry Pi Imager

Ubuntu 18.04: Apache2 php Version aktualisieren auf php7.4

Da es sich um einen Ubuntu Server Version 18.04 LTS (End of Life: April 2023) handelt, muss zuerst das PPA von “ondrej/php” hinzugefügt werden. Darin sind sämtliche benötigten PHP Packages / Extensions der Version 7.4 enthalten. Zusätzlich braucht es für den Apache2 noch “ondrej/apache2”.

sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/apache2
sudo apt update

Als Nächstes kann nun php7.4 installiert werden:

sudo apt install php7.4

Nachdem wir nun PHP installiert haben, installieren wir noch die benötigten Extensions:

sudo apt install php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl -y

Jetzt können wir Apache2 konfigurieren und deaktivieren zuerst einmal die alte PHP-Version:

sudo a2dismod php7.2

Als Nächstes aktivieren wir die neue PHP-Version:

sudo a2enmod php7.4

Zum Schluss müssen wir noch einen Neustart des Webserver Apache2 durchführen, damit die neue PHP-Version auch verwendet wird:

sudo systemctl restart apache2

Nützliche Links

Upgrade PHP version to PHP 7.4 on Ubuntu

ppa:ondrej/php – the main PHP repository

Ondřej Surý – bietet Debian Packages (PHP, nginx, apache, DNS, …)

The Ubuntu lifecycle

Microsoft Learn

Mit der Webplattform Microsoft Learn bietet Microsoft viele verschiedene Module und Lernpfade (praktische Übungen), um sich mit den aktuellen Microsoft Technologien kostenlos weiterbilden zu können.

Das Einzige, was man dazu braucht, ist ein Microsoft Learn-Konto. Die Module sind versehen mit einem theoretischen und einem praktischen Teil, welcher dann mit der Hilfe einer Sandbox (Azure Shell mit allen benötigten Tools) durchgeführt werden kann.

Es gibt auch sogenannte “30 Days to Learn It-Herausforderungen”. Dabei werden mehrere Module zu einer Sammlung zusammen gefasst. Beispiel die “Cloud Skills Challenge – Azure Developer”. Sie besteht aus 35 Module, für die man laut Microsoft ca. 28 Std. und 16 Min. Zeit investieren muss. Beendet man die Herausforderung innerhalb dieser 30 Tage, erhält man eine 50% Gutschrift für ein “Microsoft Certification exam”.

Viel Spass beim Ausprobieren und Lernen! :o)

Nützliche Links

Microsoft Learn

30 Days to Learn It

Meine Badges & Trophäen

Authentisierung, Authentifizierung und Autorisierung

Was bedeuten Authentisierung, Authentifizierung und Autorisierung schon wieder?

Alle 3 Begriffe beschreiben einen unterschiedlichen Schritt bei der Überprüfung einer bestimmten Identität und dem Gewähren von Zugriffsrechten.

  1. Authentisierung – das aktive Nachweisen einer Identität
  2. Authentifizierung – die Prüfung des Nachweises auf seine Korrektheit
  3. Autorisierung – den Zugiff auf die erlaubten Ressourcen freigeben

Beispiel: Flugreise

  1. Person authentisiert sich mit ihrem Pass und Ticket am Flughafen
  2. Die Person wird anhand ihrer Dokumente am Schalter authentifiziert
  3. Durch das Ticket wird die Person autorisiert am Flug teilzunehmen

Beispiel: Anmeldung Webanwendung

  1. Person authentisiert sich mit der Eingabe ihres Benutzernamens und Passworts
  2. Server / Dienst überprüft Benutzername und Passwort Kombination und authentifiziert die Person
  3. Gleichzeitig erhält die Person ihre zugewiesenen Berechtigungen. Server / Dienst autorisiert die Person auf zugewiesene Module und Funktionen (Bsp: Benutzerverwaltung, Auflistung offener Rechnungen usw.)

Nützliche Links

Wikipedia: Authentifizierung

Wikipedia: Autorisierung

C# 9: Init only Properties / init only setters

Init only Properties sind unveränderbare Datenobjekte, die einmal initialisiert den Zustand nicht mehr ändern können. Dazu verwendet man das Schlüsselwort init anstelle von set.

// Auto property
public Guid MyId { get; init; }

// property
private Guid myId;
public Guid MyId{
  get {return myId;}
  init {myId = value;}
}

// lambda property
private Guid myId;
public Guid MyId{
  get  => myId;
  init => myId = value;
}

Wird nun die “MyId” einmal zugewiesen, kann diese nicht mehr versehentlich überschrieben werden. “MyId” kann nur bei der Objektinitialisierung oder über den Konstruktor festgelegt werden.

// object class with the secret 
public class MySecret
 {
  public MySecret()
  {
  }
  public MySecret(Guid myId)
  {
    MyId = myId;
  }
  public Guid MyId { get; init; }
}

// Example 1
// create an object with the secret
// assign with object initializer
MySecret mySecret = new MySecret()
{
  MyId = Guid.NewGuid()
};


// Example 2
// create an object with the secret
// assign in the instance constructor
MySecret mySecret2 = new MySecret(Guid.NewGuid());

Nützliche Links

docs.microsoft.com: init only setters