Rekrutacja w IT – Frontend

Od jakiegoś czasu biorę aktywny udział w rozmowach rekrutacyjnych i chciałbym się podzielić paroma spostrzeżeniami z jakimi się spotkałem. Obecnie świat frontend bardzo szybko się rozwija i nie jest bezpodstawnym by żartować sobie każdego dnia “Co tam we frontendzie, jaki nowy framework dzisiaj wyszedł.”. Tak ten świat wygląda i należy szukać sposobów by się w nim odnaleźć, ale również nadążać i mieć narzędzia śledzenia trendów. Moim zdaniem najważniejsze jest świadomość paru rzeczy:
 
Dobra znajomość znajomość podstaw JavaScript oraz zaawansowanych zagadnień w JavaScript – ta wiedza będzie nam potrzebna bez względu na to z jakim frameworkiem będziemy pracowaćJavaScript to język który ma bardzo wiele możliwości jednak nie wszystkie są rozsądne, nie wszystko co można w tym języku robić jest dobrą praktyką jak np. eval() Nie jest podstawy mówi się, że “eval is Evil”. Bardzo dobrą książką która daje dobre i szybkie wprowadzenie do JavaScript to książka “JavaScript – The Good Parts”. Dzięki niej na blisko 170 stronach możemy się zapoznać z dobrą stroną JavaScript, bardzo ładnie pokazuje to obrazek przypięty do tego postu:

Umiejętność odróżnienia ważnych aspektów “nowego” frameworku od ceteris paribus już istniejących rozwiązań Moim zdaniem nie ma sensu w chwili obecnej nawet próbować być specjalistą i znać wszystkie możliwe hacki w jednym frameworku. Ja osobiście popełniłem ten błąd ucząc się Ionic 1 https://ionicframework.com/docs/v1/, po około 9 miesiącach intensywnej nauki tego frameworku wyszła na świat nowsza wersja Ionic 2 która rozwiązywała wiele problemów (np. zacinanie się aplikacji kiedy na listę wrzuciliśmy większą ilość elementów) i okazało się, że 90% mojej nauki poszło do kosza. Nauka poszła do kosza ponieważ wersja Ionic 1 był powiązany ściśle z AngularJS 1 natomiast w Ionic 2 twórcy postanowili zaimplementować Angular 2 który jest praktycznie nowym frameworkiem, a AngularJS do Angular2 oraz Angular 4 ma się dokładnie tak samo jak Java do JavaScript…. 
http://crockford.com/javascript/
https://frontendmasters.com/books/front-end-handbook/2017/ – bardzo dobra kompleksowa książka
 
Znajomości dobrych praktyk zarówno programowania w JavaScript jak również dobrych praktyk programowania w wybranych przez nas lub firmę frameworku
Kiedy zaczynamy programować w nowym frameworku warto zadawać następujące zapytania do Google:
“angular controllers best practices”
“angular factory best practices”
“angular writing code best practices”
Jeśli akurat piszemy w Angular polecam https://github.com/johnpapa/angular-styleguide. Moim celem jest przekazanie idei “best practicies”, niestety kiedy robimy tutorial nacisk kładziony jest na szybki efekt, nikt się nie przejmuje dalszym rozwojem kodu a aby otrzymać jak najszybciej efekt zazwyczaj jak najniższym wysiłkiem energii i to jest dobre, jednak zajmując się komercyjnie programowaniem warto znać dobre praktyki.
 
Znajomość zagadnień architektury oraz umiejętność pisania kodu wraz z testami (nie jest prawdą, że każdy kod napisany np. w AngularJS jest “testowalny” – w momencie kiedy w kontrolerze mamy wstrzyknięte dużo zależności ciężko napisać testy do takiego kodu)
Mam tutaj zagadnienia które zahaczają o architekturę, na przykładzie AngularJS to: moduł, dyrektywa, programowanie modułowego kodu.
https://stackoverflow.com/questions/11171778/difference-between-service-directive-and-module
 
Efektywna umiejętność śledzenia trendów
Dla osób rozpoczynających swoją przygodę proponuję Weekly Webdev Challange https://www.facebook.com/groups/1131907053499522/ każdego tygodnia jest nowe zadanie dzięki któremu możemy szlifować nasze umiejętności web developera lub podobne inicjatywy https://medium.freecodecamp.org/the-10-most-popular-coding-challenge-websites-of-2016-fb8a5672d22f poniżej zamieszam linki dzięki którym możecie śledzić trendy, oczywiście to tylko wybrane:
https://www.reddit.com/r/Frontend/
https://medium.com/@sapegin/who-to-follow-on-twitter-if-youre-a-frontend-developer-b7873e787480
http://frontendweekly.co/
https://twitter.com/hashtag/frontend
https://medium.freecodecamp.org/modern-frontend-hacking-cheatsheets-df9c2566c72a
http://thewebplatformpodcast.com/
https://www.wykop.pl/link/3385027/jak-wyglada-nauka-javascript-w-2016-eng/
https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb
https://benmccormick.org/2017/07/19/ten-things-javascript/
http://ml-games.tomasz-rewak.com JavaScript pozwala również na Machine Learning
https://github.com/benoitvallon/computer-science-in-javascript/tree/master/data-structures-in-javascript
https://developer.mozilla.org/pl/docs/Web/JavaScript/EventLoop
https://leetcode.com/problems/median-of-two-sorted-arrays/description/
Na koniec dodam, że nie poruszałem w tym wpisie takich zagadnień jak: HTML5, CSS wraz z preprocesorami, kontrola wersji, znajomość obsługi Continuous Integration. Musimy pamiętać również, że najlepszą formą nauki to praktyka, obecnie firmy bardzo lubią kiedy kandydat posiada własne konto Github na którym można zleźć przykładowy kod. 
W razie pytań zapraszam do komentowania i zadawania pytań i/lub uwag. 

Continue Reading

Lekarz programistą – dokąd zmierza ten świat?

Od paru lat obserwuję sytuację medycyny w Polsce i młodych lekarzy, ostatnimi czasy spotkałem się z pytaniami “Czy młody lekarz może dorabiać sobie programując” jako osoba która która ma doświadczenie programując jednocześnie widząc każdego dnia ile młody lekarz (a wcześniej student) musi się uczyć postanowiłem napisać parę zdań na ten temat i co ja na ten temat myślę.
Praca dzieli się na dwa typy: wyrobnictwo i praca kreatywna. Podobnie jak medycyny jak i programowania nie można się nauczyć w dwa wieczory a w obu zawodach najcenniejsze jest doświadczenie które zdobywa się długie lata. Na początku studiów (ok. 10 lat temu) przeczytałem książkę “Wędrujący Świat” Grzegorza Kołodko i jedną z rzeczy jaką zapamiętałem z niej to to, że czasy w jakich ja będę żyć to zupełnie inne realia w jakich żyli nasi rodzice. Chodzi o to jak wygląda praca, czym jest praca i gdzie warto być zawodowo. Wcześniej bycie lekarzem było super, bycie prawnikiem było super. Czasy się zmieniły diametralnie i obecnie zawodowo warto być w punkcie styku:

Synergia dziedzin

mówię o tej części wspólnej. Osobiście nazywam to “synergią dziedzin”. Przez wiele lat moim hobby było handlowanie na giełdzie walutami można to robić manualnie, ale zatrudnienie do tego komputera daje dużo lepsze wyniki. Wspaniałym połączeniem jest również programowanie z medycyną (dedykowane apki dla lekarzy, automatyczna analiza danych itp itd) i teraz do sedna. Moim zdaniem dziedziny powinny się uzupełniać i współpracować (to jest słowo klucz, a my Polacy niestety nie jesteśmy uczeni współpracy a wręcz przeciwnie) dlatego lekarz powinien szukać możliwości współpracy z koderem w celu stworzenia produktu które spełni i ułatwi życie danej grupie ludzi. 
Jako osoba która w branży siedzi blisko 10 lat wiem, że nie ma czegoś takiego jak “programista”, “programować” bo co to właściwie znaczy? Jest tyle technologii, języków, że zanim osoba odnajdzie siebie w tym samemu to minie parę lat, zanim zacznie się uczyć minie sporo czasu a zanim zacznie być dobra w danej działce minie jeszcze parę lat. Tak samo nie ma czegoś takiego jak “lekarz”, jest wiele specjalizacji i sami drodzy lekarze przestudiowaliście już tyle czasu i nadal nie wiecie kim chcecie zostać. Z programowaniem jest tak samo a bym rzekł nawet, że bardziej skomplikowanie bo technologia która rok temu była na topie dzisiaj jest już przeżytkiem – to są realia w świecie JS/Frontend. 
Bycie lekarzem to wielka odpowiedzialność i zawód który wymaga ogromnej wiedzy i kręgosłupa moralnego i pewności tego co się robi. Dlatego ja osobiście nie radzę młodym lekarzom nauki strice kodowania bo to jest ogrom pracy (chyba, że znacie kogoś kto ma projekt i jest Wam w stanie powiedzieć czego się nauczyć i szybko wrzuci Was w projekt to tak można – ale ilość warunków żebyście mieli na coś takiego jest duża i ciężko w realnym świecie spełnić je wszystkie) to do czego zachęcam to:

  1. samorozwój merytoryczny w dziedzinie w której chcemy być specjalistami
  2. prowadzenie badań, doktorat i ewentualna nauka programowania ale wiedząc CO chce się OSIĄGNĄĆ poprzez programowanie czyli: przetwarzanie dużej ilości badań, statystyka, R – język do statystyki
  3. nauka medycyny: cutting edge technologies, bycie na bieżąco z trendami na świecie
  4. zagraniczne staże – im więcej tym lepiej, uczenie się od swoich szefów zachowań, gestów, podejścia do człowieka
  5. szukanie pomysłu na produkt i jeśli się coś znajdzie to uderzajcie chociażby do osoby takiej jak ja lub innych funduszy Venture Capital z pomysłem – tam spotkacie ludzi którzy Was poprowadzą
  6. szukanie i nauka od ludzi którzy osiągnęli coś w życiu i są chętni do przekazania swojego doświadczenia dla których zapłatą jest jedna rzecz – patrzenie jak WY rośniecie
  7. ucinanie toksycznych znajomości
  8. nauka efektywnego odpoczynku i odpuszczania niektórych tematów (zrozumienie, że jesteśmy tylko ludźmi) Letting GO – http://www.buddhanet.net/4noble14.htm

Jeśli podejmujecie jakąś pracę zawsze dążcie do tego aby na pytanie: Co robisz dzisiaj, by stać się mistrzem? Móc sobie bez problemu odpowiedzieć nauczyłem się tego i tego w swojej dziedzinie. Bo chyba zgodzimy się, że zrobienie 100 bułek w McDonald nie przybliża Was do bycia specjalistami w medycynie – za to przybliża ogromny koncern McDoland bo bycia jeszcze większym a cena czasu młodych lekarzy jest bardzo cenna. Z własnego doświadczenia wiem, że czas po studiach jest krytyczny, i Wasza głowa wtedy jest jeszcze chłonna i wykorzystajcie ten czas na rozwój a nie na robienie pracy tylko dla pieniędzy. Zakończę cytatem:
 

“Przeciętni zarabiają wykonując pracę, której nie kochają.”

 
Myślcie o swoim życiu z perspektywy całego życia a nie wycinków. Jeśli nauczycie się czegoś unikalnego przez 5 lat to po tym czasie będziecie mogli odpowiednio się cenić. Współpracujcie razem ze sobą! Jak macie pytania i uwagi zapraszam do dyskusji.

Continue Reading

TRANSMISJA KONCERTU NOSPR ONLINE.

Tradycyjnie na początku Nowego Roku, w NOSPRodbędzie się Poranek noworoczny.
To historyczny moment w działalności orkiestry – NOSPR dołączy do grona najlepszych zespołów, których koncerty melomani mogą oglądać na żywo w internecie. Poranek transmitowany będzie online za pośrednictwem oficjalnego kanału NOSPRna YouTube! 
Streaming dostępny będzie na stronie internetowej NOSPR oraz stronie Programu 2 Polskiego Radia 8 stycznia 2017 r. o godz. 12.00.
Publiczność będzie miała okazję wysłuchać znanych i lubianych utworów znakomitych twórców wiedeńskich. Tym razem w programie koncertu znajdą się uwertury, arie i duety z operetek Franza Lehára i Imre Kálmána – wielkich kompozytorów operetki wiedeńskiej węgierskiego pochodzenia.
W tym roku gośćmi orkiestry będą sopranistka Karina Skrzeszewska, tenor Adam Sobierajski i baryton Stanisław Kuflyuk. Za pulpitem dyrygenckim stanie lubiany przez melomanów José Maria Florêncio.
 
Koncert rozpocznie się 8 stycznia 2017 o godz. 12.00 w siedzibie NOSPR (Katowice, pl. W. Kilara 1) i na prośbę melomanów zostanie powtórzony o godz. 18.00. Transmisja online dotyczy tylko koncertu o godz. 12.00.

Continue Reading

Integrationstests mit Spring

Integrationstests testen im Gegensatz zu Unittests nicht einzelne Methoden, sondern das Zusammenspiel verschiedener Methoden, die von einander abhängig sind. Das Framework Spring bietet hierfür viele verschiedene Funktionalitäten. Voraussetzung ist eine korrekte Injizierung der einzelnen Klassen in einer Webanwendung, wie ich es im Kapitel Dependency Injection for Beginners beschrieben habe. Außerdem benötigen wir eine separate applicationContextTest.xml wie sie im Kapitel Konfiguration in Spring mit der applicationContext.xml zu finden ist.
Für den Fall, dass Sie noch nicht die Testbibliothek von Spring zu Ihren Maven-Dependencies hinzugefügt haben, holen wir dies jetzt nach:

<dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>   
</dependency>

Da das Testen auf dem JUnit-Framework basiert, benötigen wir auch diese Dependency:

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.5</version>
            <scope>test</scope>
</dependency>

Wie kann man in Spring Tests verwenden? Man braucht einen Hinweis auf den SpringJUnit4ClassRunner und auf die Konfigurationsdatei. Die Klasse, die Tests enthält, muss wie folgt annotiert werden:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContextTest.xml" })

Im Folgenden möchte ich Tests durchführen, die Testdaten nur für die Zeit, während der Test läuft, einlesen. Am Ende werden die Inserts wieder zurückgerollt. Sprich die Testdaten werden nicht dauerhaft in der Datenbank gespeichert. Um einen Rollback am Ende eines Tests realisieren zu können, benötigen wir die unten stehenden Annotations für die Klasse:

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional

Außerdem muss jeder einzelne Test noch zusätzlich annotiert werden:

@Test
@Rollback(true)

Tests auf Service-Ebene

Lassen Sie uns mit unseren Datenbank- und Integrationstests auf Ebene der Service-Klasse beginnen. Hier unsere ersten zwei Tests:

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContextTest.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class FreigabeVerguetungServiceImplTest extends FreigabeVerguetungTest {
    @Test
    @Rollback(true)
    public void testFreigabeVergutungSetNextProcess(){
        freigabeVerguetungService.save(setFreigabeVerguetungWithOutF("BO", "VWBO00"));
        FreigabeVerguetungBODB2 freigabeAusDatenbank
                         = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        freigabeAusDatenbank.setNextProcess("F");
        freigabeVerguetungService.update(freigabeAusDatenbank);
        FreigabeVerguetungBODB2 freigabeAusDatenbankMitNextProcess
                         = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        assertEquals("F", freigabeAusDatenbankMitNextProcess.getNextProcess());
    }
    @Test
    @Rollback(true)
    public void testFreigabeVergutungRemoveNextProcess(){
        freigabeVerguetungService.save(setFreigabeVerguetungWithF("BO", "VWBO00"));
        FreigabeVerguetungBODB2 freigabeAusDatenbank
                           = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        freigabeAusDatenbank.setNextProcess(" ");
        freigabeVerguetungService.update(freigabeAusDatenbank);
        FreigabeVerguetungBODB2 freigabeAusDatenbankOhneNextProcess
                           = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        assertEquals(" ", freigabeAusDatenbankOhneNextProcess.getNextProcess());
    }
 }

Wir aktualisieren jeweils das Feld nextProcess aus der Datenbank und überprüfen anschließend, ob diese Änderung auch durchgeführt worden ist. Die Funktion assertEquals() stellt fest, ob das Feld nextProcess nach dem Update dem Wert  ” ” oder “F” entspricht.
Die Methoden, die die Testdaten erstellen, habe ich in einer Superklasse ausgelagert.  Ich benötige sie auch als Testdaten für eine weitere Testklasse weiter unten.

public class FreigabeVerguetungTest {
    static Logger logger = Logger.getRootLogger();
    @Autowired
    FreigabeVerguetungService freigabeVerguetungService;
    @Autowired
    FreigabeVerguetungController freigabeVerguetungController;
    public FreigabeVerguetungBODB2 setFreigabeVerguetungWithOutF(String actionType, String action){
        FreigabeVerguetungBODB2 freigabeVerguetung = new FreigabeVerguetungBODB2();
        freigabeVerguetung.setFreigabeVerguetungId(getTimestamp());
        freigabeVerguetung.setActionType(actionType);
        freigabeVerguetung.setAction(action);
        freigabeVerguetung.setBookingDate(getDate());
        freigabeVerguetung.setVoucherFirst(100);
        freigabeVerguetung.setVoucherLast(200);
        freigabeVerguetung.setFreigabeStatus(" ");
        freigabeVerguetung.setFreigabeStatusDatum(getDate());
        freigabeVerguetung.setNextProcess(" ");
        freigabeVerguetung.setModTime(getTimestamp());
        freigabeVerguetung.setModUser("eexbre1");
        freigabeVerguetung.setModTrans("WEB");
        return freigabeVerguetung;
    }
    public FreigabeVerguetungBODB2 setFreigabeVerguetungWithF(String actionType, String action){
        FreigabeVerguetungBODB2 freigabeVerguetung = new FreigabeVerguetungBODB2();
        freigabeVerguetung.setFreigabeVerguetungId(getTimestamp());
        freigabeVerguetung.setActionType(actionType);
        freigabeVerguetung.setAction(action);
        freigabeVerguetung.setBookingDate(getDate());
        freigabeVerguetung.setVoucherFirst(100);
        freigabeVerguetung.setVoucherLast(200);
        freigabeVerguetung.setFreigabeStatus(" ");
        freigabeVerguetung.setFreigabeStatusDatum(getDate());
        freigabeVerguetung.setNextProcess("F");
        freigabeVerguetung.setModTime(getTimestamp());
        freigabeVerguetung.setModUser("eexbre1");
        freigabeVerguetung.setModTrans("WEB");
        return freigabeVerguetung;
    }
    public Timestamp getTimestamp() {
        DateTestHelper dateTestHelper = new DateTestHelper();
        Timestamp ts = dateTestHelper.getTimestamp();
        return ts;
    }
    public Date getDate() {
        DateTestHelper dateTestHelper = new DateTestHelper();
        Date date = dateTestHelper.getDate();
        return date;
    }
}

Ich erstelle 2 Testdatensätze, die sich durch den Freigabestatus unterscheiden. Das Feld, das in diesen Methoden verändert wird, ist das Feld nextProcess(). Steht in diesem Feld ein F wird eine Vergütung freigegeben. Steht dort ein Leerzeichen ist die Zahlung nicht freigegeben. Mit unseren obigen Tests überprüfen wir, ob dieser Wert mit der Methode update() gesetzt wird. Diese Tests betreffen nur eine Klasse und eine Datenbanktabelle. Als nächstes erstellen wir einen Test, der Veränderungen in mehreren Datenbanktabellen überprüft. Wir überprüfen, ob die Methode saveStatusAndFreigabeVerguetung() sowohl die Freigabe korrekt setzt als auch den Status in der Tabelle Bonus.

@Test
@Rollback(true)
public void testSaveStatusAndFreigabeVerguetungMitStatus6(){
       freigabeVerguetungService.save(setFreigabeVerguetungWithF("GS", "AUD011"));
       FreigabeVerguetungBODB2 freigabeVerguetungAusDatenbank
                         = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
       setBonusArt();
       BonusBODB2 bonus = setBonus("6");
       freigabeVerguetungService.saveStatusAndFreigabeVerguetung("7", freigabeVerguetungAusDatenbank);
       FreigabeVerguetungBODB2 freigabeVerguetungMitStatus7
                         = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
       BonusBODB2 bonusAusDatenbank
                         = freigabeVerguetungService.getBonusBODB2ById(bonus.getBonusId());
       assertEquals("F", freigabeVerguetungMitStatus7.getNextProcess());
       assertEquals("7", bonusAusDatenbank.getBonusStatus());
}

Die Klasse FreigabeVerguetungTest ergänze ich um die Methoden setBonus() und setBonusArt():

public BonusBODB2 setBonus(String bonus) {
       BonusBODB2 bonusBODB2 = new BonusBODB2();
       bonusBODB2.setBonusId(getTimestamp());
       bonusBODB2.setBonusSet("GKSTRA02");
       bonusBODB2.setBonusVariante(2);
       bonusBODB2.setBonusStatus(bonus);
       bonusBODB2.setDescription("Ina's Testbonus");
       bonusBODB2.setBonusDate(getDate());
       bonusBODB2.setDateControl("N1");
       bonusBODB2.setMonthFrom("201201");
       bonusBODB2.setMonthUntil("201212");
       bonusBODB2.setModTime(getTimestamp());
       bonusBODB2.setModUser("eexbre1");
       bonusBODB2.setModTrans("WEB");
       bonusBODB2.setSbVersion(1);
       bonusBODB2.setFinals("A");
       freigabeVerguetungService.save(bonusBODB2);
       return bonusBODB2;
   }
   public BonusArtBODB2 setBonusArt() {
       BonusArtBODB2 bonusArtBODB2 = new BonusArtBODB2();
       BonusArtBODB2Id bonusArtBODB2Id = new BonusArtBODB2Id();
       bonusArtBODB2Id.setBonusSet("GKSTRA02");
       bonusArtBODB2Id.setBonusVariante(2);
       bonusArtBODB2.setId(bonusArtBODB2Id);
       bonusArtBODB2.setActionType("GS");
       bonusArtBODB2.setAction("AUD011");
       bonusArtBODB2.setModTime(getTimestamp());
       bonusArtBODB2.setModUser("eexbre1");
       bonusArtBODB2.setModTrans("QMF");
       freigabeVerguetungService.save(bonusArtBODB2);
       return bonusArtBODB2;
   }

Tests auf Controller-Ebene

Bis hier hin war alles einfach. Jetzt haben wir mehrere Probleme, die es zu lösen gilt: Im nächsten Schritt würde ein Servlet-Container (z.B. Tomcat) benötigt werden, der den Faces-Context mit hoch lädt. Der wird aber leider an dieser Stelle nicht mit gestartet. Die Lösungsansätze hierzu scheinen im Fluß zu sein. Außerdem benötigen wir einen CustomScope.
Unser FreigabeVerguetungController ist mit der Annotation @Scope(value=”session”) versehen. Diese Annotation führt im Test zu einer Fehlermeldung. Lösung  ist ein CustomScope. Für den Dummy-CustomScope benötigen wir unten stehende Klasse, die in der applicationContextTest.xml registriert werden muss (Konfiguration in Spring mit der applicationContext.xml).

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
public class CustomScope implements Scope {
    private final Map<String , Object> beanMap = new HashMap<String , Object>();
    public Object get(String name, ObjectFactory<?> factory) {
        Object bean = beanMap.get(name);
        if (null == bean) {
            bean = factory.getObject();
            beanMap.put(name, bean);
        }
        return bean;
    }
    public String getConversationId() {
        // not needed
        return null;
    }
    public void registerDestructionCallback(String arg0, Runnable arg1) {
        // not needed
    }
    public Object remove(String obj) {
        return beanMap.remove(obj);
    }
    public Object resolveContextualObject(String arg0) {
        // not needed
        return null;
    }
}

 
Ein weiteres Problem: Im Test gibt es weder einen SessionContext noch einen FacesContext. So wirft die Methode getSessionBean() aus der Klasse BeanFassade eine NullPointerException.

public static SessionBean getSessionBean() {
       FacesContext context = FacesContext.getCurrentInstance();
       ValueBinding binding = context.getApplication().createValueBinding("#{sessionBean}");
       return (SessionBean) binding.getValue(context);
}

Diese NullPointerException müssen wir in der Klasse FreigabeVerguetungController auffangen. Wir erstellen unten stehende Methode init() und eine Methode initForTest(). Für den Test ersetzen wir die SessionBean durch eine Art Mockobjekt. Sprich wir erstellen im Test selbst ein SessionBean-Objekt, dem wir Werte nur für den Test zuweisen. Zu Testzwecken instanziieren wir einen Dummy. Aber dazu weiter unten mehr.

private SessionBean sessionBean;
@PostConstruct
public void init() {
     try {
          sessionBean = BeanFassade.getSessionBean();
     } catch (NullPointerException e) {
          getSessionBean();
     }
}
public void initForTest(SessionBean sessionBean) {
     this.sessionBean = sessionBean;
}
public SessionBean getSessionBean() {
     return sessionBean;
}

Die Annotation @PostConstruct funktioniert leider nicht immer. Wollen wir beispielsweise auf eine Properties-Datei zugreifen mit unten stehender Methode getRessourceBundle(), muss dies an jeder Stelle separat erfolgen.Wozu dient die Annotation @PostConstruct? Die Methode init() wird direkt nach dem Konstruktor aufgerufen, so müssen wir diese Methode nur einmal aufrufen und nicht an allen Stellen, an denen sie benötigt wird. Warum greifen wir nicht im Konstruktor auf die SessionBean zu? Weil eine Fehlermeldung geworfen werden würde.

public static ResourceBundle getRessourceBundle(String bundle) {      
           FacesContext ctx = FacesContext.getCurrentInstance();      
           ResourceBundle resourceBundle =           
                         ResourceBundle.getBundle(bundle, ctx.getViewRoot().getLocale());      
           return resourceBundle;  
}

Wir erstellen die folgenden Methoden in der Klasse ApplyAllowanceServiceImpl.java, die die Bezeichnung für eine Belegnummer aus einer Datei auslesen. Die Methode muss dann jedes Mal im Code aufgerufen werden, wenn sie benötigt wird.

public void initVoucherNo(){       
     try{           
          voucherNo =
             FacesUtil.getRessourceBundle(GlobalConstants.BUNDLE_MESSAGES).getString("notVoucherNo");
     }catch(NullPointerException e){           
          getVoucherNo();       
     }  
}       
public String getVoucherNo() {       
     return voucherNo;   
}   
public void setVoucherNo(String voucherNo) {       
     this.voucherNo = voucherNo;   
}

Kommen wir zu unserem Test: Die Testdaten, die in den Methoden der Klasse FreigabeVerguetungTest erzeugt werden, können wir wieder verwenden. Wir instanziieren die SessionBean, übergeben ihr einen Dealer, der eine Marke und eine ID hat, und setzen diesen Wert an die Stelle, an der die Daten des Händlers durch das Händlerportal übergeben werden würden, wäre dies eine “normale Session”.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContextTest.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class FreigabeVerguetungControllerTest extends FreigabeVerguetungTest{
    static Logger logger = Logger.getRootLogger();
    @Autowired
    FreigabeVerguetungService freigabeVerguetungService;
    @Autowired
    FreigabeVerguetungController freigabeVerguetungController;
    @Test
    @Rollback(true)
    public void testSaveActionGrossKunde(){
        //Da der FacesContext im Test nicht existiert, erstellen wir eine SessionBean
        //nur für den Test.
        SessionBean sessionBean = new SessionBean();
        Dealer dealer = new Dealer();
        dealer.setOuBrandsAsString("V");
        dealer.setUserHostID("eexbre1");
        sessionBean.setDealer(dealer);
        freigabeVerguetungController.initForTest(sessionBean);
        FreigabeVerguetungBODB2 freigabeVerguetungInDatenbank
             = setFreigabeVerguetungWithOutF("GS", "AUD011");
        freigabeVerguetungService.save(freigabeVerguetungInDatenbank);
        FreigabeVerguetungBODB2 freigabeVerguetungAusDatenbank
             = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        setBonusArt();
        BonusBODB2 bonus = setBonus("6");
        freigabeVerguetungController.saveActionGrossKunde
             (freigabeVerguetungController.
              setFromBeanToFreigabeVerguetungBO(freigabeVerguetungAusDatenbank));
        FreigabeVerguetungBODB2 freigabeVerguetungMitStatus7
             = freigabeVerguetungService.getFreigabeVerguetungBODB2ById(getTimestamp());
        BonusBODB2 bonusAusDatenbank = freigabeVerguetungService.getBonusBODB2ById(bonus.getBonusId());
        assertEquals("F", freigabeVerguetungMitStatus7.getNextProcess());
        assertEquals("7", bonusAusDatenbank.getBonusStatus());
    }
}

Oben stehende Ergänzung durch die drei Methoden init(), initForTest() und getSessionBean() verändert den Code sehr. Ziel ist es, den Code möglichst nur geringfügig zu Testzwecken anzupassen. Je mehr ein Code verändert wird, desto größer ist die Gefahr zusätzliche Fehler einzubauen. Leider habe ich in Spring keinen Weg gefunden wie dies möglich wäre. Diese Methoden werden auch im folgenden benötigt. Ich möchte trotzdem zwei weitere Wege vorstellen: Der Einsatz von Reflections und der Einsatz von Anonymen Klassen. Als Erstes überschreiben wir die Methode init() durch eine Anonyme Klasse. Was ist eine anonyme Klasse? Bei anonymen Klassen werden zwei Schritte in einem durchgeführt: Es wird eine Klasse ohne Namen definiert und gleichzeitig eine Instanz dieser Klasse erstellt. Wir setzen den Wert der SessionBean in unserem Test wie folgt:Da wir sicherlich noch mehr Tests erstellen, für die wir eine SessionBean mit Dealer benötigen, würde es sich anbieten diese Funktionalität als Methode ebenfalls in die Superklasse auszulagern.

FreigabeVerguetungController freigabe = new FreigabeVerguetungController() {
           public void init() {
               SessionBean sessionBean = new SessionBean();
               Dealer dealer = new Dealer();
               dealer.setOuBrandsAsString("V");
               dealer.setUserHostID("eexbre1");
               sessionBean.setDealer(dealer);
           }
};//Die anonyme Klasse wird durch einen Strichpunkt beendet

Ich habe den entsprechende Test der Klasse FreigabeVerguetungControllerTest.java hinzugefügt:

@Test
 @Rollback(true)
 public void testSaveActionGrossKundeMitAnonymerKlasse() {
        //Da der FacesContext im Test nicht existiert, erstellen wir eine
        //SessionBean in einer anonymen Klasse nur für den Test.
        FreigabeVerguetungController freigabe = new FreigabeVerguetungController() {
            public void init() {
                SessionBean sessionBean = new SessionBean();
                Dealer dealer = new Dealer();
                dealer.setOuBrandsAsString("V");
                dealer.setUserHostID("eexbre1");
                sessionBean.setDealer(dealer);
            }
        };
        FreigabeVerguetungBODB2 freigabeVerguetungInDatenbank = setFreigabeVerguetungWithOutF(
                "GS", "AUD011");
        freigabeVerguetungService.save(freigabeVerguetungInDatenbank);
        FreigabeVerguetungBODB2 freigabeVerguetungAusDatenbank = freigabeVerguetungService
                .getFreigabeVerguetungBODB2ById(getTimestamp());
        setBonusArt();
        BonusBODB2 bonus = setBonus("6");
        freigabeVerguetungController
                .saveActionGrossKunde(freigabeVerguetungController
                        .setFromBeanToFreigabeVerguetungBO(freigabeVerguetungAusDatenbank));
        FreigabeVerguetungBODB2 freigabeVerguetungMitStatus7 = freigabeVerguetungService
                .getFreigabeVerguetungBODB2ById(getTimestamp());
        BonusBODB2 bonusAusDatenbank = freigabeVerguetungService
                .getBonusBODB2ById(bonus.getBonusId());
        assertEquals("F", freigabeVerguetungMitStatus7.getNextProcess());
        assertEquals("7", bonusAusDatenbank.getBonusStatus());
    }
}

Als Zweites setzen wir den Wert für die SessionBean mithilfe von Reflections. Eine schöne Seite zu diesem Thema ist die folgende: http://www.itblogging.de/java/java-reflection/. Die SessionBean wird von außen gesetzt, nachdem sie ansprechbar mit setAccessible(true) gemacht wurde. Es ist das gleiche Prinzip wie Dependency Injection.

//Die entsprechende Klasse wird instanziiert:
final FreigabeVerguetungController freigabe = new FreigabeVerguetungController();
//Die Klasse wird in ein Object vom Typ Class umgewandelt:
final Class<?> clazz = freigabe.getClass();
Field sessionBeanReflection = null;
try {          
       //Mit der Methode getDeclaredField() holen wir uns das Attribut
       //SessionBean der Klasse FreigabeVerguetungController:
        sessionBeanReflection = clazz.getDeclaredField("sessionBean");
} catch (SecurityException e) {
        e.printStackTrace();
} catch (NoSuchFieldException e) {
        e.printStackTrace();
}
SessionBean sessionBean = new SessionBean();
Dealer dealer = new Dealer();
dealer.setOuBrandsAsString("V");
dealer.setUserHostID("eexbre1");
sessionBean.setDealer(dealer);
//Wir verschaffen uns Zugriff auf das Attribut SessionBean
sessionBeanReflection.setAccessible(true);
try {          
        //und setzen den Wert dieses Attributs:
        sessionBeanReflection.set(freigabe, sessionBean);
} catch (IllegalArgumentException e) {
       e.printStackTrace();
} catch (IllegalAccessException e) {
       e.printStackTrace();
}

In den beiden soeben vorgestellten Lösungen wird die SessionBean von außen verändert, ohne dass der ursprüngliche Code wesentlich verändert werden muss.

Continue Reading

Transmisja VOD „GOPLANY” – Opera Narodowa

Pogoda beznadziejna, wychodzić się nie chce, jesienna chandra… to idealny moment by wysłuchać sobie opery siedząc wygodnie w swoim fotelu!
 
Zapraszam na transmisję ze spektaklu Goplana, która odbędzie się 3 listopada o godzinie 18:50 na vod.teatrwielki.pl. Tak, Teatr Wielki udostępnia platformę VOD gdzie można obejrzeć na żywo wybrane przedstawienia.
 

 

Więcej informacji:

http://teatrwielki.pl/repertuar/kalendarium/2016-2017/goplana/
https://pl.wikipedia.org/wiki/Goplana_(opera)
 

Continue Reading

Angielski za Zakrętkę

Chciałbym poinformować o akcji w Katowicach która polega na nauce języka angielskiego w cenie…. jednej zakrętki.
 
“Zbieramy zakrętki, by pomagać koledze, by otrzymał nowy wózek a ty też możesz mu pomagać. To znaczy, że możesz uczyć się Angielskiego tylko za 1 zakrętkę i komuś pomagać! Trzeba mieć 4 tony, aby mógł dostać ten wózek! Damy radę!”
 
20161026_193348
Damy radę!

Continue Reading

Programowanie automatycznych strategii transakcyjnych – zaproszenie na bezpłatne szkolenia.

Chciałbym zaprosić na szkolenia promujące moją książkę, która po paru latach pracy, zbierania materiałów, pisania notatek jest już dostępna. Chciałbym podziękować Firmie TMS Brokers która została Opiekunem Medialnym zapewniając wsparcie przy promocji, oprawie graficznej oraz korektę. Poniżej przeklejam krótki opis szkoleń:
 
SZKOLENIE NR 1
podstawowe (otwarte)

  • Co to jest automat transakcyjny
  • Platforma MetaTrader od strony programisty
  • Wady i zalety automatów transakcyjnych
  • Wprowadzenie do MetaEditor oraz jezyka programowania – MQL
  • Sterowanie oraz konfigurowanie automatu
  • Omówienie prostego automatu transakcyjnego
  • Wysyłanie zleceń transakcyjnych oraz obliczanie poziomów Stop Loss w praktyce
  • W jakiś sposób testować nasz automat – Tester Strategii– wady i zalety
  • Struktura świeczki w języku programowania – MQL

 
SZKOLENIE NR 2
zaawansowane (tylko dla Klientów TMS)

  • Metody ustawiania zlecenia Stop Loss
  • Obliczanie poziomów zlecenia Take Profit
  • Wprowadzanie zleceń oczekujących do automatu
  • Zabezpieczenie naszego automatu transakcyjnego
  • Rodzaje programów, które możemy napisać w języku programowania (MQL)
  • Programowanie obiektowe – MQL5 różnice oraz możliwości

 
SZKOLENIE NR 3
zaawansowane (tylko dla Klientów TMS)

  • Metody ustawiania zlecenia Stop Loss
  • Obliczanie poziomów zlecenia Take Profit
  • Wprowadzanie zleceń oczekujących do automatu
  • Zabezpieczenie naszego automatu transakcyjnego
  • Rodzaje programów, które możemy napisać w języku programowania (MQL)
  • Programowanie obiektowe – MQL5 różnice oraz możliwości

 
Więcej informacji znajdziecie tutaj:
Miejsce gdzie można się zarejestrować na szkolenie: http://automaty.lp.tms.pl/lp,automaty
Daty i więcej informacji: https://www.investmentuniversity.pl/kalendarz-szkolen/szkolenie-trading-automatyczny
Profil na Facebook: https://www.facebook.com/tradingautomatyczny
 
Jako zajawkę wrzucam okładkę oraz parę przykładowych stron 😉
 
trading_automatyczny
Jest również dostępna próbka książki: https://waszczyk.com/resources/trading_automatyczny-waszczyk-probka.pdf

Continue Reading

Investment & Business Days in Frankfurt am Main

08. – 13. September. – 6 Tage Livestream:
Topthemen aus: Investment, Trading und Business. Jetzt live dabei sein.

Für Börsenneulinge und aktive Anleger auf der Suche nach Trading-Ideen undprofessionellen Handelsstrategien.

Erleben Sie hautnah die Emotionen der Trader und erfahren Sie deren Tipps und Tricks. Sechs Tage, die Sie weit voranbringen werden.

Wir schalten Sie kostenlos live an allen sechs Tagen
von 08:30 – 21:00 Uhr in die Vortragsräume.

Dank Kamerateam und Ton verfolgen Sie von Ihrem Büro oder Ihrer Couch das Event. Bequemer geht es nicht mehr.

Investment & Trading
Vier Channels. 6 Tage.

Kein Börsenspiel, keine Demokonten, beobachten Sie Vollzeit-Trader bei ihrer täglichen Arbeit. Die Trader teilen ihre Handelsstrategien, Ideen und Erfahrungen mit Ihnen.

Business
Ein Channel. 6 Tage.

Alles rund um: Zeitmanagement, Projektmanagement, Change-Management, Karriereplanung, Kommunikation, Konfliktmanagement, Verkaufsstrategien und Networking.

Kostenlose Buchung & Informationen unter ib-days.com


Sie möchten Ihre Sprachkenntnisse allgemein perfektionieren !!!

Continue Reading

Przepaść

 
Link do debaty: http://wyboryprezydenckie.tvp.pl/19876535/debata-kandydatow-wybory-prezydenckie-2015
Nie mam czasu na obserwowanie przygotowań do wyborów, kątem oka obejrzałem “debatę” i przyszły mi do głowy dwie rzeczy:
1. divide et impera – zasada stara jak świat, potrzebni idioci
2. …nazwiązanie do tytułu wpisu, patrzyłem na tych ludzi, patrząc w życiorysy są to “politycy” (czy to w ogóle zawód????), historycy, politolodzy. Wielu politologów po studiach można spotkać w UK, Szkocji, Irlandii….
 
A dlaczego przepaść, ostatnio Lee Hsien Loong pochwalił się na swojej stronie na fejsbuku programik w C++ który napisał.
 
Poniżej przeklejam wpis z fejsbuka:
I told the Founders Forum two weeks ago that the last computer program I wrote was a Sudoku solver, written in C++ several years ago (http://bit.ly/1DMK5Zk). Someone asked me for it. Here is the source code, the exe file, and a sample printout – http://bit.ly/1zfIGMc
The program is pretty basic: it runs at the command prompt, in a DOS window. Type in the data line by line (e.g. 1-3-8—6), then the solver will print out the solution (or all the solutions if there are several), the number of steps the program took searching for the solution, plus some search statistics.
For techies: the program does a backtrack search, choosing the next cell to guess which minimises the fanout.
Here’s a question for those reading the source code: if x is an (binary) integer, what does (x & -x) compute?
Hope you have fun playing with this. Please tell me if you find any bugs! – LHL
#SmartNation
===========
As several of you noted, (x & –x) returns the least significant ‘1’ bit of x, i.e. the highest power of two that divides x. This assumes two’s complement notation for negative numbers, as some of you also pointed out. e.g. if x=12 (binary 1100), then (x & -x) = 4 (binary 100). I didn’t invent this; it is an old programming trick.
 
Podsumowując debatę, (szkoda mi było czasu żeby dotrwać do końca) jestem załamany durnotą, każdy najlepszy, jeden lepszy od drugiego. Było ich 10 a nikt nie powiedział żeby młode osoby zamiast słuchać tych mądrości w telewizjach ciężko pracowali, uczyli się poprzez pracę i rozwijali się. Odnośnie prognozy (nie jestem zwolennikiem) zdziwię się jeśli nie wygra Pan K.
 
Źródło: https://www.facebook.com/leehsienloong/photos/a.344710778924968.83425.125845680811480/905828379479869/?type=1&fref=nf

Continue Reading