Mittwoch, 6. Januar 2016

Warum selbst Seminare anbieten?

Hallo Leute...

Heute möchte ich mal erzählen, wie es dazu gekommen ist, dass ich jetzt meine eigenen Seminare anbiete. 2012 bin ich nach einigen Irrwegen darauf gekommen als freiberuflicher Dozent und IT-Trainer zu unterrichten. Dabei haben mir vor allem die Firmenschulungen sehr viel Spaß gemacht, weil die Teilnehmer hier einfach sehr motiviert und wissbegierig sind. Schließlich geht es darum in dem Job, den sie sicher schon eine Weile ausüben, noch besser zu werden.

Eine Sache hat mich jedoch immer gestört... Ich wurde von Bildungsträgern beauftragt um für eine Hand voll Teilnehmer einen Kurs zu halten. Dabei hatte ich meistens gar keine Gelegenheit die Teilnehmer vorher kennenzulernen, um zu erfahren, was sie eigentlich genau lernen wollen. Das hat die Vorbereitung des Kurses relativ schwierig gemacht. Ich kannte ja den Fokus der Teilnehmer überhaupt nicht und Aufgaben ausdenken und Lernkonzepte zu erstellen, ist eine zu umfangreiche Sache um dann alles wieder umzuwerfen, wenn die Teilnehmer dann am ersten Tag sagen, dass sie eigentlich was ganz anderes wollen, als ich erwartet habe.

Deshalb biete ich jetzt meine eigenen Seminare an und mache es mir zu Aufgabe mit jedem Teilnehmer schon vor dem Kurs zu telefonieren, um den Fokus auf die richtigen Themen setzen können. Und um zu vermeiden, dass Teilnehmer mit deutlich unterschiedlichem Fokus in einem Kurs sitzen. Sowas wird bei meinen Seminaren nicht passieren. Statt dessen mache ich lieber einen zweiten Termin auf.

Wer also Interesse hat ein Seminar bei mir zu buchen, der findet meine Homepage unter www.fluxparticle.de.

Mittwoch, 11. Juni 2014

Erweitertes Any-Pattern

Hallo Leute!

Das letzte mal ist schon etwas her. Damals hatte ich euch das All- und Any-Pattern gezeigt. Heute geht es um eine Variante des Any-Patterns. Ihr erinnert euch. Zur Erinnerung... Das Any Pattern sah z.B. so aus:


int[] werte = new int[] { 4, 2, 7, 3, 5, 1, 8 };

boolean erfuellt = false;
for (int i = 0; i < werte.length; i++) {
  if (werte[i] > 5) {
    erfuellt = true;
    break;
  }
}
if (erfuellt) {
  System.out.println("Mindestens ein Wert ist größer als 5.");
}

Es dient dazu herauszufinden, ob irgendein ("Any") Element in einem Array eine bestimmte Bedingung erfüllt. In diesem Fall ob es größer als 5 ist.


Nun möchte man aber vielleicht auch noch wissen welches Element das ist, was diese Bedingung erfüllt. Auch diese Information kann man erhalten, indem man das Pattern leicht abwandelt. Der boolean erfuellt wird dabei einfach durch eine Variable ersetzt, die sich die Position merkt, an der das gefundene Element steht. Das sieht dann für das obige Beispiel so aus:

int[] werte = new int[] { 4, 2, 7, 3, 5, 1, 8 };

int found = -1;
for (int i = 0; i < werte.length; i++) {
  if (werte[i] > 5) {
    found = i;
    break;
  }
}
if (found >= 0) {
  System.out.println("Mindestens ein Wert ist größer als 5.");
  System.out.println("Einer davon steht an Position " + found + ".");
}

Wie wir sehen, dass die Variable
found mit -1 initialisiert wird. Das ist hier das equivalent zu false für den Fall, dass kein Element in dem Array die Bedingung erfüllt. Da in Java, C++ und vielen anderen Sprachen alle Arrays mit dem Element 0 beginnen, ist -1 ein guter Wert, von dem weiß, dass diese Position im Array nicht vorkommt. Mit if (found >= 0) prüft man später also einfach ob die Variable found eine gültige Position im Array definiert und weiß dadurch gleich ob und welches Element in einem Array die Bedingung erfüllt.

Hier das ganze auch nochmal als allgemeines Pattern:

int found = -1;
for (int i = 0; i < array.length; i++) {
  if (/* Bedingung prüfen */) {
    /* Aktion für Elemente ausführen, die Bedingung erfüllen */
    found = i;
    break; // Falls keine Aktion durchgeführt werden soll
    // und man nur an den ersten passenden Element interessiert ist.
  }
}
if (found >= 0) {
  // Aktion ausführen falls ein Element die Bedingung erfüllt
}

Jetzt sollten wir uns nochmal kurz über den Fall Gedanken machen, dass mehrere Elemente in dem Array die Bedingung erfüllen. Ist man nur an irgendeinem passenden Element interessiert, und möchte keine Aktion für alle passenden Elemente durchführen, kann man die Schleife einfach mit break beenden, sobald man ein Element gefunden und sich dessen Position gemerkt hat. In dem Fall wird found am Ende die Position des ersten passenden Elements beinhalten. Lässt man aber das break weg, weil man z.B. eine Aktion für alle passenden Elemente durchführen möchte, dann wird found am Ende die Position des letzten passenden Elements beinhalten.

Samstag, 29. März 2014

All- und Any-Pattern

Gerade als Programmieranfänger muss man häufig noch über Aufgaben nachdenken, die für fortgeschrittene Programmierer schon selbstverständlich sind. Hier möchte ich nun ein paar Muster vorstellen, die immer wieder auftauchen und bei denen man sich das nachdenken sparen kann.

Ist es z.B. erforderlich zu prüfen, ob in einem Array ein Element vorkommt, dass eine bestimmte Bedingung erfüllt so, kann man das mit dem Any-Pattern testen. ich schreibe das jetzt mal in Java Syntax, obwohl es genauso gut auch für jede andere Programmiersprache funktioniert, die Arrays unterstützt. Hier ein Beispiel, bei dem festgestellt werden soll, ob ein Array eine Zahl enthält, die größer als 5 ist.

int[] werte = new int[] { 4, 2, 7, 3, 5, 1, 8 };

boolean erfuellt = false;
for (int i = 0; i < werte.length; i++) {
  if (werte[i] > 5) {
    erfuellt = true;
    break;
  }
}
if (erfuellt) {
  System.out.println("Mindestens ein Wert ist größer als 5.");
}

Hieraus lässt sich ein Muster ableiten, dass immer funktioniert, wenn man eine derartige Aufgabe vor sich hat. Man beginnt damit eine boolesche Variable auf false zu setzen. Durchläuft dann das gesamte Array und prüft jedes Mal die Bedingung, die einen interessiert. In diesem Fall, ob der Wert größer als 5 ist. Ist diese Bedingung erfüllt wird die boolesche Variable auf true gesetzt, ansonsten nicht verändert. (Das ist wichtig.) Nach Durchlaufen der Schleife kann man einfach die boolesche Variable abfragen und dann etwas tun, was für den Fall passieren soll, falls wenigstens ein Element in dem Array die Bedingung erfüllt.

Gelegentlich kann es auch vorkommen, dass man mit allen gefunden Elementen etwas tun will, dass kann man dann natürlich in dem if-Block tun. Dann sollte man allerdings auf das break verzichten, da die Aktion sonst nur für das erste gefundene Elemente ausgeführt wird.

Hier nochmal als Muster:

boolean erfuellt = false;
for (/* for-Schleife über das gesamte Array */) {
  if (/* Bedingung prüfen */) {
    /* Aktion für Elemente ausführen, die Bedingung erfüllen */
    erfuellt = true;
    break; // Falls keine Aktion durchgeführt werden soll.
  }
}
if (erfuellt) {
  // Aktion ausführen falls ein Element die Bedingung erfüllt
}

Das gleiche gibt es auch noch für den Fall, dass alle Elemente in dem Array eine Bedingung erfüllen sollen:

boolean alle = true;
for (/* for-Schleife über das gesamte Array */) {
  if (/* Bedingung prüfen */) {
    // Aktion für Elemente ausführen, die Bedingung erfüllen
  } else {
    alle = false;
    break// Falls keine Aktion durchgeführt werden soll.
  }
}
if (alle) {
  // Aktion ausführen falls alle Elemente die Bedingung erfüllen
}

Hier wird die boolesche Variable zuerst mit true initialisiert und für den Fall, dass ein Element die Bedingung nicht erfüllt auf false gesetzt.

Freitag, 25. November 2011

Duck-Typing


Durch das sogenannte Duck-Typing ist es in Python möglich beliebige Methoden auf Objekten aufzurufen. Ob eine Methode tatsächlich existiert und richtig aufgerufen wird, wird erst zur Laufzeit geprüft. Dadurch ist das folgende Beispiel-Programm aber auch sehr kompakt.

class Bird:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.__class__.__name__+' '+self.name

class Duck(Bird):
    def quak(self):
        print str(self)+': quak'

class Frog:
    def quak(self):
        print str(self)+': quak' 

ducks = [Bird('Gustav'), Duck('Donald'), object(), Frog()]

for duck in ducks:
    if hasattr(duck, 'quak'):
        duck.quak()
    else:
        print 'Keine Ente:', duck

In Java muss man das Interface CanQuak zu Hilfe nehmen. Dadurch kann der Compiler aber schon zur Compile-Zeit prüfen, dass die Methode quak() existiert und richtig aufgerufen wird.

public class Ducks
{
  public static void main(String[] args)
  {
    Object[] ducks = new Object[] {new Bird("Gustav"), new Duck("Donald"), new Object(), new Frog()};
    for (Object duck : ducks)
    {
      if (duck instanceof CanQuak)
      {
        ((CanQuak) duck).quak();
      }
      else
      {
        System.out.println("Keine Ente: " + duck);
      }
    }
  }
}

interface CanQuak
{
  public void quak();
}

class Bird
{
  private final String name;

  public Bird(String name)
  {
    this.name = name;
  }

  public String toString()
  {
    return getClass().getName() + " " + name;
  }
}

class Duck extends Bird implements CanQuak
{
  public Duck(String name)
  {
    super(name);
  }

  public void quak()
  {
    System.out.println(this + ": quak");
  }
}

class Frog implements CanQuak
{
  public void quak()
  {
    System.out.println(this + ": quak");
  }
}

Die Sprache Go verwendet ein Konzept bei dem ein Interface automatisch von Klassen implementiert wird, wenn diese Klasse die Methoden implementiert, die von dem Interface gefordert werden. Auch damit kann man das Duck-Typing-Beispiel nachbauen. Genau wie in Java kann in Go auch bereits zur Compile-Zeit sichergestellt werden, dass die Mehtode Quak() existiert und richtig aufgerufen wird.

package main

import (
  "fmt"
)

type Object struct {
}

type Bird struct {
  name string
}

type Duck struct {
  Bird
}

type Frog struct {
}

type Quaker interface {
  Quak()
}

func (b Bird) String() string { return b.name }
func (d Duck) Quak() { fmt.Printf("%s: quak\n", d) }
func (f Frog) Quak() { fmt.Printf("%s: quak\n", f) }

func main() {
  ducks := []interface{}{&Bird{"Gustav"}, &Duck{Bird{"Donald"}}, &Object{}, &Frog{}}
  for _, duck := range ducks {
    if quaker, ok := duck.(Quaker); ok {
      quaker.Quak()
    } else {
      fmt.Printf("Keine Ente: %s\n", duck)
    }
  }
}