Throw to taki inny return…

April 15th, 2015

Przynajmniej w Javie. Jak już mamy Javę 8 to możemy pokusić się o takie podejście pod pewnymi warunkami.

Przypadek

Klient ma Sonara i nie zawahał się go użyć. Rzecz w tym, że ocenie podlega tylko kod z zewnątrz organizacji, czyli nasz, a ten wewnętrzny może być chujowy. My przejęliśmy ten chujowy kod i teraz naprawiamy…
Jednym z elementów jest maszynka do zamiany jsonów na obiekty i na odwrót. W niej jest kawałek kodu do pracy z datami. Wygląda on mniej więcej tak

Listing 1. Konwerter dat

public class DateConverting {

	public static void main(String[] args) {
		String dateJson = "1"; // 1-1-1970 :D

		Date date = convertStringToDate(dateJson);
		System.out.println(date.toString());
	}

	private static Date convertStringToDate(String s) {
		if (s == null || s.trim().isEmpty()) return null;
		try {
			return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS").parse(s);
		} catch (ParseException e) {
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss").parse(s);
		} catch (ParseException e) {
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm").parse(s);
		} catch (ParseException e) {
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(s);
		} catch (ParseException e) {
		}
		return new Date(Long.valueOf(s));
	}
}

Mamy cztery formaty daty i jeżeli String nie pasuje do żadnego z nich to traktujemy jak zwykły long. Jeżeli jest pusty albo jest nullem to zwracamy null. Straszna paskuda. Sonar też to stwierdził i strasznie czerwony raport. Klient kręci germańską główką i szwargocze… Jak to można naprawić.

Wersja prosta

Na razie rzecz prosta i bez udziwnień. Generalnie mamy sobie dopuszczone formaty, robimy z nich listę iterujemy i jak na listingu 2

Listing 2. Konwerter dat pierwsza poprawka

private static Date convertStringToDate(String s) {                           
	if (s == null || s.trim().isEmpty()) return null;                         
	ArrayList<String> patterns = Lists.newArrayList(YYYY_MM_DD_T_HH_MM_SS_SSS,
			YYYY_MM_DD_T_HH_MM_SS                                             
			, YYYY_MM_DD_T_HH_MM                                              
			, YYYY_MM_DD);                                                    
	for (String pattern : patterns) {                                         
		try {                                                                 
			return new SimpleDateFormat(pattern).parse(s);                    
		} catch (ParseException e) {                                          
		}                                                                     
	}                                                                         
	return new Date(Long.valueOf(s));                                         
}

Generalnie to rozwiązanie jest takie samo jak poprzednie. Różnica jest na poziomie “zamiast stu zmiennych zrób tablicę”.
My oczekujemy czegoś innego. Teraz będzie dużo kodu i magii javy 8 oraz trochę programowania prawie funkcyjnego ;) Da się to rozwiązanie zaimplementować też z użyciem np. Guavy, ale to jak musicie mieć javę 7.

Użyjmy javy 8

Koncepcja tej refaktoryzacji opera się o stwierdzenie, że rzucenie wyjątku jest tak na prawdę rodzajem instrukcji powrotu. Nasza metoda ma w takim przypadku dwa możliwe typu na wyjściu. Jeden ten zadeklarowany i drugi dla wyjątku.

Interfejs opakowujący

Na początek zdefiniujmy sobie interfejs opakowujący ParseTask. Pozwoli on na ujednolicenie różnych mechanizmów parsowania.

Listing 3. Interfejs ParseTask

interface ParseTask<R>{
	R parse() throws ParseException;
}

Implementacja będzie realizować zadanie parsowania. Może zwrócić coś R albo wyrzucić wyjątek ParseException.

Rezultat parsowania

Potrzebujemy też klasę, która będzie reprezentować rezultat parsowania. Nie chcę używać Optional ponieważ jest zbyt ogólny, a jeżeli chcemy gdzieś zachować informacje o błędzie to musimy mieć klasę specjalizowaną.

Listing 4. Klasa ParseResult

abstract class ParseResult<R> {

	static class Valid<R> extends ParseResult<R>{
		final R r;

		Valid(R r) {
			this.r = r;
		}

		@Override
		public boolean isValid() {
			return true;
		}

		@Override
		public R result() {
			return r;
		}
	}

	static class Failed<R> extends ParseResult<R>{
		final ParseException e;

		Failed(ParseException e) {
			this.e = e;
		}

		@Override
		public boolean isValid() {
			return false;
		}

		@Override
		public R result() {
			throw new NoSuchElementException("No value present");
		}
	}

	public abstract boolean isValid();
	public abstract R result();
}
Maszynka do uruchamiania

Czyli klasa Parser, której zadaniem jest uruchamianie poszczególnych zadań parsowania i tworzenie odpowiednich wyników

Listing 5. Klasa Parsersamp>

class Parser<R> implements Function<ParseTask<R>, ParseResult<R>> {

	@Override
	public ParseResult<R> apply(ParseTask<R> parseTask) {
		try {
			return new ParseResult.Valid(parseTask.parse());
		} catch (ParseException e) {
			return new ParseResult.Failed(e);
		}
	}
}

Uruchamiamy

Finalnie nasza metoda konwertująca może wyglądać w następujący sposób:

Listing 5. Klasa Parser

private static Date convertStringToDate(String s) {
		if (s == null || s.trim().isEmpty()) return null;
		ArrayList<String> patterns = Lists.newArrayList(YYYY_MM_DD_T_HH_MM_SS_SSS,
				YYYY_MM_DD_T_HH_MM_SS
				, YYYY_MM_DD_T_HH_MM
				, YYYY_MM_DD);

		return patterns.stream()
				.map(p -> (ParseTask<Date>) () -> new SimpleDateFormat(p).parse(s))
				.map(new Parser<>())
				.filter(ParseResult::isValid)
				.map(ParseResult::result)
				.findFirst().orElseGet(() -> new Date(Long.valueOf(s)));

	}

Najpierw tworzymy sobie listę zdań parsowania. Następnie odpalamy parser (feralna nazwa), sprawdzamy czy wynik jest poprawny i pierwszy poprawny wynik zwracamy. Jeżeli nie będzie żadnego poprawnego wyniku to dokonujemy domyślnej konwersji.

Podsumowanie

Czy kod wynikowy jest lepszy? Jeżeli ta operacja konwersji i parsowania była by tylko w jednym miejscu w całym systemie to można takie rozwiązanie potraktować jako ciekawostkę. Jeżeli mamy jednak wiele różnych praserów i konwersji to można wprowadzić prostą klasę narzędziową, która ułatwi nam życie:

Listing 6. Klasa ParserMatcher

class ParserMatcher<R>{

	public R findParserAndParse(Collection<ParseTask<R>> pt, Supplier<R> defVal){
		return pt.stream()
				.map(new Parser<>())
				.filter(ParseResult::isValid)
				.map(ParseResult::result)
				.findFirst().orElseGet(defVal);
	}
}

i pozwoli zredukować kod do kilku prostych regułek.

Cały “myk” w tym rozwiązaniu opiera się na dwóch rzeczach. Pierwsza to redukcja efektu ubocznego jakim jest wyjątek do poziomu opcjonalnego wyjścia. Efekt nie opuszcza miejsca, w którym się pojawił. Zostaje opakowany i zwrócony jako rezultat. Druga to rozgraniczenie sposobu przetwarzania, czyli parsowania od danych, czyli w tym przypadku parserów. W pewnym sensie tworzymy tu bardzo prymitywną gramatykę i efektywnie język obróbki informacji.

Podatki kochane… kiedy ja z was zwrot dostanę…

April 12th, 2015

…no to nie ma kuja we wsi. Zgodnie z obietnicą wpis o podatkach i moich pomysłach na ten fragment Polski. W poprzednim poście z tej serii pisałem, że rzeczywista kwota wolna od podatku w Polsce wynosi około 9tyś PLN. W pierwszym wpisie pokusiłem się o wyliczenie ile płacę składek i podatków.

Dziś kilka słów o tym ile podatków płacę efektywnie za 2014 rok. Na początek ważna informacja dostałem zwrot. I to taki naprawdę solidny (powyżej średniej krajowej brutto). Rozliczam się sam (mamy rozdzielność majątkową) i jedyną ulga jaką mam to ulga na dziecko. W 2014 byłem zatrudniony przez 6 miesięcy na UoP więc efektywnie płaciłem dość “normalny” ZUS. Z DG płacę “duży” ZUS.

Normalny ZUS oznacza, że wysokość składki jest proporcjonalna do wynagrodzenia.
Duży ZUS z DG oznacza, że nie jestem już na okresie ulgowym.

I na koniec ostatnia stała z DG odprowadzam liniowy PIT 19%.

Kwot z oczywistych powodów kwoty dochodu nie mogę podać dlatego będziemy bawić się na procentach. Powiem tylko, że jest to znacząco powyżej 100tys rocznie.

Podatek obliczony

Czyli to co trafia do pozycji 115 w PIT37 i pozycji 39 w PIT 36L. W sumie (z obu pitów podzielone przez dochód z obu pitów) daje zawrotne 11% podatku jakie oddałem państwu. Dodajmy do tego jeszcze składki na ubezpieczenie społeczne (bo na zdrowotne odliczasz od podatku) gdyż zdaniem niektórych, słusznie zresztą, są to podatki (celowe, ale podatki). W takim wypadku podatek efektywnie wynosi… 19,5%. LOL… No normalnie zabójcza stawka.

Podatek zapłacony

Samo obliczenie podatku należnego to pikuś. Są koszty, są ulgi. Jeżeli weźmiemy pod uwagę te czynniki i od dochodu odejmiemy koszty, a następnie porównamy to z kwotami odprowadzonych zaliczek to otrzymamy… 13,3%… o kurwa… w tym przypadku nie musimy już robić zabaw z ZUSem, bo ta kwota pomniejsza dochód i tym samym podstawę opodatkowania. Dla ciekawskich jeżeli doliczymy zapłacone składki to otrzymamy 26% podatku.

Efektywna stopa opodatkowania

Czyli to ile w rzeczywistości zapłaciłem podatku. Kwota zaliczek pomniejszona o kwotę zwrotu w stosunku do podstawy opodatkowania… 7,1%, ze składkami ZUS to 19,8%. W stosunku do całości dochodu… 4,8%, a dodając składki ZUS to 12,8%. I niech mi tu kurwa ktoś powie, że w Polsce mamy wysokie podatki…

Jak naprawić ten system

System jest skonstruowany by dobrze robić osobom zamożnym. Osoba biedna nie wrzuci sobie w koszty księgowej, paliwa czy elektroniki. Nie wrzuci sobie w koszty rachunków za komórkę, prąd, internet czy części rachunków za mieszkanie. Tu nie ma rat leasingowych, kredytów obrotowych czy opłat bankowych.
Inaczej mówiąc sama zabawa z kwota wolną nic nie da. Co więcej osoby biedne nie zyskają zbyt dużo (kilkadziesiąt PLN miesięcznie), a ze względu na cięcia wydatków socjalnych z powodu spadku dochodów państwa stracą część z otrzymywanej pomocy. I będzie to strata znacznie większa niż to co oszczędzą na podatkach.

Skala podatkowa

Progresywna z wieloma progami. Kwota wolna bez większych zmian. Jej coroczna waloryzacja jest wystarczająca. Następnie progi podatkowe 18 (do około 60tys), 30 (100-120tys), 40(300-350tys), 55(500tys), 80(powyżej 1 mln). Ulgi i odliczenia ograniczone do minimum. Pamiętajcie, że skala progresywna oznacza, że dany podatek płacimy od zarobków powyżej danej kwoty.

Warunkowe opodatkowanie DG podatkiem liniowym

Tu będzie cały “myk”. Obecnie podatek liniowy jest opcją dla “przedsiębiorcy”. Jego próg opłacalności jest gdzieś w okolicach 96tys rocznego dochodu (z założeniem dużego ZUSu). Inaczej mówiąc jeżeli nie zarabiasz co najmniej 96 tys to nie opłaca się płacić liniowego.
Moim zdaniem prawo do płacenia liniowego powinni mieć tylko ci co zatrudniają na UoP, czyli prowadzą rzeczywiste przedsiębiorstwa. Istota indywidualnej DG polega na tym, że na rynku istnieje pewna grupa usług, których świadczenie jest mocno ograniczone czasowo w stosunku do innych podmiotów. Upraszczając są pewne zawody i prace gdzie zatrudnienie na stałe nie ma sensu. Przykładowo projektant wnętrz nie będzie pracować na stałe w firmie robiącej srajtaśmę. Ma do wykonania pewne zadanie. Może je rozliczyć na umowie o dzieło (umowa rezultatu) albo jako przedsiębiorca (umowa rezultatu z ograniczeniami czasowo przestrzennymi). Nie powinno się to różnic od normalnej pracy w zakresie podatków czy składek. Po prostu masz specyficzną robotę, ale nadal jest to normalna praca.

Zasada 20/80

20% mojego podatku zabiera budżet centralny. 80% samorząd. Do tego zmiana mechanizmu “janosikowego” tak by uwzględniał dochody z bieżącego okresu rozliczeniowego, a nie lat poprzednich. Pozwoli to uniknąć sytuacji gdzie kryzys wali dwa razy w silne ośrodki. Raz obniżając bieżące dochody i dwa ciągnąc kasę z poprzednich lat. Technicznie oznaczało by to, że beneficjenci tego systemu dostawali by pieniądze za kwiecień w maju. Nie tak jak obecnie kasę za 2013 w 2015.

Naliczać wszystko od tzw. “Supergross”

Obecnie w systemie funkcjonują pojęcia “część pracownika” i “część pracodawcy”. Przeniesienie tego drugiego elementu bezpośrednio do umów oraz (ustawowo) aneksowanie umów tak by kwota na umowie była kwotą wszystkich kosztów jakie ponosi pracodawca pozwoli na uproszenie systemu.

Zapraszam do dyskusji…

JSR-354 oraz Moneta na DevCrowd 2015

April 10th, 2015

Dawno nie pisałem. Będzie tekst o podatkach, bo dostałem PIT i to takiego jakiego podsumowanie podesłał mi Paweł Szulc

Generalnie #wódka #dziwki #lasery.

Ale nie o tym dziś, choć nadal o pieniądzach.

Już za tydzień będziecie mogli posłuchać dwóch moich prezentacji na DevCrowd w Szczecinie. Jedna będzie machana rękoma o architekturze i infrastrukturze (to ta nudniejsza i poobiednia). Druga będzie poświęcona temu jak w Javie bezpiecznie liczyć pieniądze. Wczoraj siadłem do składania slajdów do tej prezentacji i jak zajrzałem do skrzynki to zobaczyłem dwa fajne maile.

Wczoraj oficjalnie pojawiła się wersja 1.0 specyfikacji JSR-354, czyli Java Money. Można ją pobrać tutaj. Całość jest skompilowana pod Javę 8, ale można sobie zrobić forka i jak ktoś potrzebuje mieć to w javie 1.5… (nekrofil).
Wraz ze specyfikacją pojawiła się też implementacja referencyjna, czyli Moneta (do pobrania tutaj).

Zatem mogę już oficjalnie powiedzieć, że na DevCrowd będzie świeże mięcho :D

Naprawiamy Kontomierz

March 16th, 2015

Lubię Kontomierz. Serio. Pozwala na ogarnięcie finansów i ma przypominajkę dzięki czemu nie trzeba koniecznie pamiętać o wszystkich wydatkach. Taki manager finansowy tylko trochę bardziej estetyczny. Ma jednak kilka wad związanych ze statykami. Na przykład nie potrafi odpowiedzieć na pytanie jakiej wielkości transakcje w danej kategorii stanowią większość. Niby duperela, ale istotna, bo pozwala na wyszukiwanie “wycieków” gotówki w ramach np. zakupów spożywczych.

Kontomierz pozwala na eksport danych do pliku csv. Kodowanego w CP1250 (żenua), ale to rozwiązujemy za pomocą:

Listing 1. Zmiana kodowania pliku

$ iconf -f cp1250 -t utf8 in.csv > out.csv

Mając już taki plik możemy go sobie obrobić w javie… jest jednak mały problem, bo maksymalna wielkość eksportu to 2000 transakcji (bardzo mało tak naprawdę). Zatem trzeba łączyć pliki z danego roku (co jest trochę upierdliwe). W nagrodę dostajemy jednak możliwość zrobienia dokładniejszych statystyk dla naszych finansów.

Poniżej przykładowy program liczący kilka statystyk dla zakupów z kategorii “spożywcze”.

Listing 2. Statystyka zakupów spożywczych

public class App {

	private static Set<Range> ranges = new HashSet<>();

	static {
		ranges.add(Range.closedOpen(0., 10.));
		ranges.add(Range.closedOpen(10., 20.));
		ranges.add(Range.closedOpen(20., 50.));
		ranges.add(Range.closedOpen(50., 100.));
		ranges.add(Range.closedOpen(100., 200.));
		ranges.add(Range.closedOpen(200., 500.));
		ranges.add(Range.closedOpen(500., 1000000.));
	}

	public static void main(String[] args) throws IOException, ParseException {
		CSVReader csvReader = new CSVReader();
		TransactionFile read = csvReader.read(new File("all_2014.csv"));

		Predicate<Record> ekonto = r -> r.accountName.equalsIgnoreCase("ekonto");
		Predicate<Record> portfel = r -> r.accountName.equalsIgnoreCase("portfel");
		read.transactions.stream()
				.filter(ekonto.or(portfel).and(r-> r.category.equalsIgnoreCase("spożywcze")))
				.collect(Collectors.groupingBy(r -> r.category))
				.entrySet()
				.forEach(e -> stat(e.getKey(), e.getValue()));
	}

	private static void stat(String key, List<Record> value) {
		System.out.println("Statystyka dla " + key);
		System.out.println("Liczba transakcji " + value.size());
		OptionalDouble average = value.stream()
				.mapToDouble(r -> Math.abs(r.amount.getNumber().doubleValueExact())).average();
		System.out.println("Średnia wartość transakcji " + average.orElse(0.));
		Map<Range, List<Record>> byRange = value.stream().collect(Collectors.groupingBy(r -> inRange(r)));
		ranges.stream()
				.sorted((l, r) -> l.lowerEndpoint().compareTo(r.lowerEndpoint()))
				.forEach(rng -> {
					Optional<List<Record>> records = Optional.ofNullable(byRange.get(rng));
					System.out.println("W zakresie " + rng + ": jest " + records.orElse(Collections.emptyList()).size() + " transakcji");
				});

	}

	private static Range inRange(Record r) {
		Optional<Range> range = ranges.stream()
				.filter(rng -> rng.contains(Math.abs(r.amount.getNumber().doubleValueExact()))).findFirst();
		return range.orElse(Range.closedOpen(-1., 0.));
	}
}

Nie jest to wzór piękna, ale napisanie tego zajęło mi wraz z napisaniem parsera do plików około godzinki.

Całość może pisać do pliku by można było to wrzucić do gnuplota aby mieć ładny rysunek.

Co jeszcze można np. odpowiednio dobierając filtry można sprawdzić czy wydajemy więcej na piwo czy żona na kosmetyki. Można też śledzić zmiany wydatków dla poszczególnych kategorii na przestrzeni np. lat czy miesięcy. Generalnie ogranicza nas wyobraźnia. Kod wrzucę na githuba jak go ogarnę tak by był bardziej przyjazny w użyciu.

Jest to przykład narzędzia, które robimy gdy chcemy szybko załatać braki w funkcjonalności jakiegoś innego narzędzia. Przy czym to inne narzędzie, tu Kontomierz, musi pozwalać na eksport danych w jakiś rozsądny sposób.

Kwota wolna od podatku mit 3091PLN

March 8th, 2015

Drugi wpis z serii. Czekam na rozliczenie roku od księgowej i jak je dostanę będzie wpis o moich pomysłach na podatki w PL.

Dziś jednak trochę inny temat. Mamy oto w Polsce kwotę zmniejszającą podatek. Jet to 556,02PLN roczni i jeżeli przyjmiemy najprostszy sposób przeliczenia kwota wolna od podatku wynosi tytułowe 3091PLN…. jest tu jednak pewien haczyk.

Kwota ta to dochód, który jest uzyskany np. z wynajmu, z inwestycji finansowych itp. W praktyce jeżeli pracujemy na UoP lub innej umowie, która wymaga odprowadzania składek na ZUS i NFZ to kwota wolna rośnie do 9072PLN. Dlaczego tak się dzieje? Ano dlatego, że podatek w Polsce jest naliczany w dość specyficzny sposób. Od dochodów odejmujemy zryczałtowane koszty (111PLN bodajże) otrzymując podstawę opodatkowania. Od niej odliczamy składkę na ZUS. Teraz mamy już kwotę, od której liczymy podatek po czym od podatku odejmujemy część składki na NFZ i kwotę zmniejszającą. Po drodze są jeszcze ulgi i odliczenia, które zmniejszają podatek albo podstawę. W przypadku pracy twórczej na etacie możemy jeszcze dodatkowo mieć możliwość uzyskania 50% kosztów z praw autorskich. W efekcie kwota wolna będzie dość szybko rosła.

Teraz zastanówmy się jakiego rodzaju pracę i na jakiej umowie wykonują osoby biedne. Jeżeli pominiemy patologię związaną z zatrudnianiem na czarno to większość z nich wykonuje pracę na podstawie oskładkowanej umowy. I to ona jest głównym składnikiem ich dochodów, a nie np. inwestycje giełdowe czy wynajem mieszkania. Zatem efektywnie kwota wolna od podatku dla osób najbiedniejszych jest znacznie większa niż te 3091PLN.

Co mi się bardziej opłaca praca w UK czy w PL

March 1st, 2015

Tyle się pierdoli o kwocie wolnej od podatków… postanowiłem zatem sprawdzić kilka rzeczy i porównać średnią stawkę z PL do tej z UK.

Założenia i narzędzia

By takie porównanie miało sens należy założyć kilka rzeczy.

  • Jako podstawę wyliczeń przyjmuję stawkę godzinową senior java deva dla górnych 10% zarobków. W przypadku stawki dziennej zakładam, że jest ona proporcjonalna do 8 godzin pracy.
  • Interesuje mnie stosunek kwoty po opodatkowaniu (PIT, ZUS, NFZ + odpowiedniki z UK) do kwoty z umowy.
  • Kwota z umowy to jest średnia stawka razy 168 (godzin) albo dzienna razy 21 (dni).
  • Traktuję ta kwotę jako kwotę zarobioną na UoP ponieważ porównywanie się jako firma nie ma sensu.

Teraz czas na narzędzia. Do wyliczenia podatków w UK użyłem narzędzia Listen To Taxman. Narzędziem dla Polski będzie kalkulator płac money.pl.

Końcowy wynik otrzymam dzieląc kwotę netto (net) przez brutto (gross).

Źródła danych

Skoro wiemy już co chcemy policzyć i za pomocą czego to liczymy czas na dobranie się do danych. Dla Wielkiej Brytanii dane pobrałem z portalu It job watch.
Z Polską maiłem trochę większy problem, bo nie ma tu dobrego źródła informacji (raport SiS jest wątpliwy). Jako średnią stawkę godzinową dla senior java dev przyjąłem 85PLN bazując na ogłoszeniach z 4p i nofluffjob.

Wyliczanki

Jako, że matematykę robią za nas narzędzia to tylko pozwolę sobie na omówienie wyników cząstkowych bez wgłębiania się w wyliczenia.

Ile zarabiamy dziennie, miesięcznie, rocznie

W UK stawka dzienna to 625 funtów.
W PL stawka dzienna to 680 złotych.

W UK stawka miesięczna to 13125 funtów.
W PL stawka miesięczna to 14280 złotych.

W UK stawka roczna to 157500 funtów.
W PL stawka roczna to 171360 złotych.

Jak widać nie ma tu dużych różnic zakładając, że ceny podstawowych produktów i usług są na podobnym poziomie. Oczywiście założenie jest nie do końca poprawne, bo o ile spożywka w UK jest stosunkowo tania to już usługi są droższe. Można jednak przyjąć, że zarobki na tym poziomie zarówno w UK jak i PL kwalifikują nas do klasy średniej.

Czas na wyliczanki

Płaca roczna netto w UK wyniesie 94116,72 funtów.
Płaca roczna netto w PL wyniesie 117820,99 złotych.

Wygląda nieźle policzmy zatem proporcje

Stosunek płacy netto do brutto w UK wynosi 94116.72/157500=0.59756647619
Stosunek płacy netto do brutto w PL wynosi 117820,99/171360=0.68756413398

Zatem jak widać robiąc to samo w UK i korzystając z wyższej kwoty wolnej oddam państwu około 9% więcej.

Janusze na swoim

Na koniec jeszcze króciutkie wyliczenie dla Januszy na swoim, którzy łapią się już w normalny ZUS. Kwota miesięczna to kwota na FV. Podatek liniowy. Średni miesięczny koszt to 1000PLN (biuro, księgowość, paliwo, amortyzacja, zakupy książek i elektroniki). Do wyliczeń posłużę się tym kalkulatorem zysku.

Kwota netto miesięcznie po odliczeniu wszelkich kosztów to 10226.05PLN.
Kwota netto rocznie po odliczeniu wszelkich kosztów to 122712.60PLN.

Stosunek netto rocznie do brutto to 10226.05*12/171360=0.71610994397

Przy czym wyliczenie nie uwzględnia jeszcze około 2,5 tysiąca, które wynika z odliczania VAT z faktur kosztowych. Po uwzględnieniu stosunek rośnie do 0.73.

Jak zatem widać na załączonym obrazku gadka o podwyższaniu kwoty wolnej to populizm w swojej najczystszej postaci.

Wkurw – najlepszy motywator do działania

February 24th, 2015

Jak zapewne niektórzy pamiętają w zeszłym roku popełniłem tu tekst na temat tworzenia konwerterów Vaadin za pomocą lambd. Dziś na blogu Vaadin pojawił się wpis gdzie był link do dodatku, który robi coś podobnego… przy czym robi to strasznie chujowo, bo traci część funkcjonalności.

Zrobiło mi się po ludzku przykro… ja tu piszę tekst w którym wyjaśniam co i jak, a tu taka niespodzianka… no ale bywa…

Przy okazji pojawił się Vaadin w wersji 7.4 i mamy tam w końcu poprawioną tabelkę co się nazywa teraz Grid. W demówce na stronie Vaadin jest używany specyficzny renderer, który pozwala na generowanie ikon z Font Awesome. Przy czym nie ma nigdzie kodu tego renderera. No wkurwiłem się strasznie, bo potrzebuję tego na wczoraj, a sam komponent rozwiązał mi dużo problemów…

Postanowiłem więc napisać własny renderer, który jest dostępny na githubie FontAwesomeRenderer. Dużo jeszcze tam pracy, ale generalnie wszem i wobec ogłaszam kod jest kurwa mój i żadna pizda w rurkach nie podpierdoli go już. Howgh!

Klucz

February 23rd, 2015

Krótko i filozoficznie.

Jaki nośnik jest najtrwalszy? Papier. Przy odpowiednich warunkach przechowywania można będzie go odczytać i za tysiąc lat. Dwa warunki. Będziemy znali alfabet oraz język. Nie jest to trudne do spełnienia, bo zapewniają nam to słowniki, które starają się uwspółcześnić język.

Chciałem zagrać w LHX. Nie mam stacji dyskietek 3,5″ czytającej w standardzie HD (1.44mb). Raptem 10 lat temu miałem… i mogłem zgrać…. choć LHX-a miałem też na na 5.25″. Za 20 lat nie odczytam danych z mojego dysku, bo ext3 nie będzie wspierany…

Kluczem do przyszłości jest stworzenie mechanizmów pozwalających na odczytywanie przeszłości.

Spring Boot szybkie wprowadzenie książkowe

February 22nd, 2015
Learning Spring Boot

Tytuł: Learning Spring Boot
Autor: Greg L. Turnquist
Rok: 2014
ISBN: 978-17-843-9302-1

Oj dobra książka dobra. Szczególnie jak chcesz się nauczyć Spring Boot. Same tutoriale z sieci i dokumentacja są OK, ale czasami warto sięgnąć po coś bardziej “mięsnego”. I taka właśnie jest ta książka.

Oczywiście zanim do niej usiądziesz musisz znać co nieco Javę i przynajmniej mieć pojęcie o Springu jako takim.

Co się z niej dowiesz?
Jak zainstalować, skonfigurować i uruchomić aplikację Spring Boot… ale to oczywiste :) Jednak forma w jakiej autor przedstawił ten temat jest naprawdę warta uwagi. Nie ograniczył się tylko do typowych przypadków, ale też opisał pewne podstawowe błędy, które można popełnić. Moim zdaniem można tą książkę traktować jako coś w rodzaju “manual by example”.

I na koniec szpila. Jest kilka drobnych błędów, ale można je wyłapać o ile ogarnia się springa.

—–

Really good book. If you think that tutorials and docs in network are good but you looking for something “more” this is book for you. Before you start you should know something about Java nad Spring.

What you will know after reading?

How to setup, configure and run spring boot. It is obvious ;) But in my opinion way how author presents that is very good. It simple, logical and cover most of common cases (and wrote some words about exceptional cases). You can treat as a “manual by example”.

Finally I found some small mistakes and inconsistency in examples but as I wrote at beginning you should know about spring and then you can easily recognize this issues.

Co ja zrobiłem między tagami, czyli szybki changelog w git

February 9th, 2015

Musiałem napisać maila do klienta z wykazem zmian w aplikacji od ostatniego wdrożenia. Czyli taki zwyczajny changelog.
Pamiętać wszystko co się działo nie sposób. Jest jednak na to metoda.

Trzymam się konwencji związanej z pracą ze zgłoszeniami na bitbuckecie. Inaczej mówiąc w wiadomościach do commitów zamieszczam odpowiednie słówka sterujące tak by móc manipulować zgłoszeniami. Przykładowo umieszczenie w wiadomości fixed #666 zamknie zgłoszenie o podanym numerze. Gdy zrobimy push
To czasami lubi się wywalać (nie odpala hooka), ale generalnie działa OK.

Konwencja pozwala na zrobienie czegoś takiego:

Listing 1. Polecenie generujące changelog

git log v0.3...v0.4 --pretty=format:'%H %s' | grep 'fixed #'

i już mamy wykaz zamkniętych zgłoszeń. Bawiąc się grepem i formatem można z tego wyprodukować htmla do wstawienia na stronę. Jedynym istotnym elementem jest podanie nazw tagów (w przykładzie v0.3…v0.4) by mieć zakres. Bez tego dostaniemy wszystkie commity.

Jeżeli spodobał ci się ten wpis to podziel się nim ze znajomymi korzystając z przycisków poniżej. Do tego one służą.


Translate »