Opublikowano Dodaj komentarz

Nic nie dzieje się bez przyczyny

Nic nie dzieje się bez przyczyny

Jak w tytule – dziś zebrało mi się na pisanie. Ostatnio spotkały mnie zdarzenia, z których wyciągam wnioski. Powoli, ale skutecznie.

Byłam ostatnio na 6 rozmowach kwalifikacyjnych, bo szukałam pracy jako alternatywy dla tej co mam. Zawsze coś można ulepszyć, trawa po drugiej stronie płota jest zawsze zieleńsza. I po doświadczeniach zdobytych podczas tych rozmów, trzeba iść do przodu, nie poddawać się. Większość ludzi, nie tylko spoza branży IT, zatrzymała się się na pracy pierwszej, drugiej po studiach. I trwa w niej, bo rodzina, bo dzieci, bo kredyt. „Trwa” a nie rozwija się, stoi w miejscu, bo dzieci będą miały lepiej. Żyją marzeniami o przyszłości. Tylko, że ja tak nie chcę! Chcę żeby moje dzieci wszystko miały, ale nie za wszelką cenę.

Wracając do rozmów kwalifikacyjnych i wniosków. Wyniki wszystkich okazały się negatywne, bo:

– może za wysoko się wyceniłam, na podstawie dotychczasowego doświadczenia i płacy

– angielski w stopniu średniozaawansowanym w piśmie i pustka w głowie jak trzeba mówić

– jestem za stara, nie poświęcę całego wolnego czasu również na pracę po godzinach i pełną dyspozycyjność.

– nie znam pełnego, prawidłowego procesu wytwarzania systemów i zarządzania zespołem programistów, ponieważ przez 10 lat sama stanowiłam jednoosobowy zespół wytwórczy (pominęłam urlopy macierzyńskie i inne zajęcia które wykonywałam po studiach)

Próbowałam też szukać zleceń za granicą, zarejestrowałam się na 3 portalach zagranicznych świadczących usługi pośrednictwa pracy między zleceniodawcami a freelancerami. I spróbowałam przejść przez rekrutację, bo nie wszystkich „z ulicy” przyjmują. I znów porażka, bo konieczny fluently English in speech – przecież trzeba gadać z klientami. Wiem, wiem… To tylko cegiełka, żeby uczyć się więcej.

Więc plany na przyszłość:

– angielski szkolić w gadaniu

– wdrażać się w Xamarin (w pracy), bo wydaje mi się, że Microsoft stawia na mobile i rozwijać to będzie w najbliższej przyszłości

– nie poddawać się, bo co mnie nie zabije to wzmocni.

A tak poza tym to postawiłam nową stronę zaprzyjaźnionego  przedszkola: http://kasztanowyzakatek.pl

w php i Joomla,  i chyba będę robić skórki do Joomla 3.x i je sprzedawać. Zawsze coś wpadnie.

Opublikowano Dodaj komentarz

Moje zgłoszenie do Piórko 2017

Ilustracje na konkurs Piórko 2017

Moje zgłoszenie do Piórko 2017

Kolejny konkurs, tym razem Biedronka zorganizowała konkurs dla ilustratorów na ilustracje do książki dla dzieci Piórko 2017. Można dużo wygrać i jest duża konkurencja. Wiadomo, że zawsze są lepsi i zawsze są gorsi. A we mnie nadal siedzi mała dziewczynka, lubię kolorowe ilustracje i jestem często łatwowierna i naiwna, bo czy zawsze trzeba stać na baczność w kontaktach z ludźmi?

Moje prace do konkursu – powyżej 🙂

Aktualizacja 2018-01-24:

W listopadzie 2017 r. pojawiła się w Biedronkach książka ilustrowana z konkursu. Piękna. Polecam, bo warto czytać dzieciom – to rozwija nas i dzieci. Pokazuje nowe horyzonty.

Opublikowano Dodaj komentarz

Moje wystąpienie na gali konkursu Daj się poznać 2017

Moje wystąpienie na gali konkursu Daj się poznać 2017

Opiszę pokrótce moje wrażenia po wystąpieniu na gali konkursu Daj się poznać 2017 zorganizowanego charytatywnie przez Maćka Aniserowicza.

Skończył się konkurs, czas wakacji i nic się nie dzieje. Wczoraj Maciej Aniserowicz opublikował wystąpienia uczestników – w tym moje. Bałam się wtedy i teraz się boję jak to przyjmą odbiorcy. Ale przecież nic złego nie powiedziałam ani nie obraziłam nikogo. Oddałam na tym wystąpieniu cząstkę siebie, pokazałam się. Dla mnie to wygrana.

Tutaj możecie obejrzeć mnie: https://www.youtube.com/watch?v=pyAD4pas0aA

I dziękuję Wam, którzy tam byli za pozytywny oddźwięk 🙂

Poniżej screeny z aplikacji TAX FREE, które pokazałam na wystąpieniu (ten sam obrazek co w Portfolio):

aplikacja TAX FREE
Opublikowano

Trochę podsumowania dotyczącego aplikacji TAX FREE

Czas konkursu się skończył. Była to dla mnie przygoda, i ciekawa jestem jaka przyszłość mnie czeka w związku z tym konkursem, bo oczekuję że wreszcie ktoś mnie zauważy, że otworzą się nowe drzwi, a może okna 🙂

Poza tym w aplikacji TAX FREE baza danych SQLLite prawie opanowana. Niesamowite, ale naprawdę polecam bazę w SQLLite, jest prosta, lekka i łatwa w obsłudze. Aplikacja zostanie dokończona zapewne do końca sierpnia 2017r. i jak zdobędę fundusze oraz uda mi się założyć swoją firmę, to zostanie opublikowana w AppStore (być może w odwrotnej kolejności, bo AppStore weryfikuje firmę przed założeniem konta developerskiego – czy na pewno to firma a nie jakiś nastolatek).

Nie lubię „lać wody”, nie chcę się nad sobą rozczulać i lubię „krótko i na temat”, dlatego ten post jest krótki. Pozdrawiam wszystkich, którzy mnie czytali. Dziękuję!

Opublikowano

17 krok w aplikacji TAX FREE – REST API cd.

Dzisiaj końcówka webserwisu – ShopRestHandler.php

Ta klasa ma kilka metod, które mogą być powszechnie stosowane we wszystkich klasach dziedziczących. Do konstruowania odpowiedzi wykorzystywana jest jedna metoda (setHttpHeaders), a inna metoda trzyma różny stan HTTP (getHttpStatusMessage). Jest to podstawa do zwrócenia odpowiedniego komunikatu w zależności od odpowiedzi serwera.

<?php
require_once(„Shop.php”);
class ShopRestHandler {

private $httpVersion = „HTTP/1.1”;
public function setHttpHeaders($contentType, $statusCode){

$statusMessage = $this -> getHttpStatusMessage($statusCode);
header($this->httpVersion. ” „. $statusCode .” „. $statusMessage);
header(„Content-Type:”. $contentType);
}

public function getHttpStatusMessage($statusCode){
$httpStatus = array(
100 => ‚Continue’,
101 => ‚Switching Protocols’,
200 => ‚OK’,
201 => ‚Created’,
202 => ‚Accepted’,
203 => ‚Non-Authoritative Information’,
204 => ‚No Content’,
205 => ‚Reset Content’,
206 => ‚Partial Content’,
300 => ‚Multiple Choices’,
301 => ‚Moved Permanently’,
302 => ‚Found’,
303 => ‚See Other’,
304 => ‚Not Modified’,
305 => ‚Use Proxy’,
306 => ‚(Unused)’,
307 => ‚Temporary Redirect’,
400 => ‚Bad Request’,
401 => ‚Unauthorized’,
402 => ‚Payment Required’,
403 => ‚Forbidden’,
404 => ‚Not Found’,
405 => ‚Method Not Allowed’,
406 => ‚Not Acceptable’,
407 => ‚Proxy Authentication Required’,
408 => ‚Request Timeout’,
409 => ‚Conflict’,
410 => ‚Gone’,
411 => ‚Length Required’,
412 => ‚Precondition Failed’,
413 => ‚Request Entity Too Large’,
414 => ‚Request-URI Too Long’,
415 => ‚Unsupported Media Type’,
416 => ‚Requested Range Not Satisfiable’,
417 => ‚Expectation Failed’,
500 => ‚Internal Server Error’,
501 => ‚Not Implemented’,
502 => ‚Bad Gateway’,
503 => ‚Service Unavailable’,
504 => ‚Gateway Timeout’,
505 => ‚HTTP Version Not Supported’);
return ($httpStatus[$statusCode]) ? $httpStatus[$statusCode] : $status[500];
}

function getAllShops() {
$shop = new Shop();
$rawData = $shop->getAllShops();

if(empty($rawData)) {
$statusCode = 404;
$rawData = array(‚error’ => ‚Brak danych’);
} else {
$statusCode = 200;
}

$requestContentType = $_SERVER[‚HTTP_ACCEPT’];
$this ->setHttpHeaders($requestContentType, $statusCode);

if(strpos($requestContentType,’application/json’) !== false){
$response = $this->encodeJson($rawData);
echo $response;
}

public function encodeJson($responseData) {
$jsonResponse = json_encode($responseData);
return $jsonResponse;
}

public function getShops($count,$longitude,$latitude) {
$shop = new Shop();
$rawData = $shop->getShops($count,$longitude,$latitude);
if(empty($rawData)) {
$statusCode = 404;
$rawData = array(‚error’ => ‚Brak danych’);
} else {
$statusCode = 200;
}
$requestContentType = $_SERVER[‚HTTP_ACCEPT’];
$this ->setHttpHeaders($requestContentType, $statusCode);
if(strpos($requestContentType,’application/json’) !== false){
$response = $this->encodeJson($rawData);
echo $response;
}
}
?>

Teraz można testować, np. za pomocą przystawki do Chrome: “Advance Rest Client”

Powyższe zacznie działać, gdy baza danych powstanie na moim serwerze. To jeszcze trochę mi zajmie.

Pozostało mi dokończyć aplikację i bazę danych uzupełnić oraz klasę Shop.php podłączyć do bazy z danymi. Pisałam na początku, że jeszcze chcę postawić serwis, w którym sprzedawcy będą mogli się dopisywać jako udostępniający sprzedaż w systemie TAX FREE. Zostało 10 dni do końca konkursu 😐 coś na pewno powstanie.

aktualizacja 2017-05-20:

Baza powstała na serwerze. Ma już 1 wpis. Oto struktura jedynej tabeli w bazie:

CREATE TABLE `melastud_shops`.`shops` ( `id` INT NOT NULL , `nazwa` VARCHAR(150) NOT NULL , `NIP` VARCHAR(35) NOT NULL , `adres` VARCHAR(500) NOT NULL , `longtitude` DECIMAL(10,8) NOT NULL , `latitude` DECIMAL(11,8) NOT NULL , `dtmod` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , `trade` VARCHAR(100) NOT NULL , `miasto` VARCHAR(100) NOT NULL ) ENGINE = MyISAM;

Klucz na id:

Podgląd tabeli shops
Podgląd tabeli shops.
Opublikowano

16 krok w aplikacji TAX FREE – REST API

Dziś w skrócie sposób na konsumpcję danych z serwisu za pomocą REST API z Swift 3 (bo jest lekki). Korzystam z framewok Foundation i zapisuję odczytane dane w sesji:

 let session = URLSession(configuration: URLSessionConfiguration.default)

let task = session.dataTask(with: URL(string: „adres webserwisu json”)!, completionHandler: { (data, response, error) in if error != nil { print(error!.localizedDescription) } else { do { if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {  print(json) } } catch { print(„błąd w JSONSerialization”) } } }) task.resume() 

Bardzo proste. Teraz czas na webserwis na serwerze udostępniający dane w php. Nie będzie korzystał z żadnych bibliotek i frameworków. Ma udostępniać dane teleadresowe sklepów obsługujących TAX FREE, tylko tyle. Potrzebne mi dane geolokacyjne, aby pokazać to na mapie, czyli tworzę klasę z takimi danymi oraz dwie metody, które mają zwracać wszystkie sklepy oraz parametryzowaną liczbę sklepów w pobliżu urządzenia:

<?php Class Shop { private $name,$NIP,$adress,$longitude,$latitude;

public function getAllShops(){}

public function getShops($count,$longitude,$latitude){} } ?>

Ciało metod do wypełnienia jak utworzę bazę danych w MySQL, bo hosting przewiduję na linuksie.  Teraz zastanawiałam się czy zostawić to tak, że dostęp do url-a oraz parametry przekazywać za pomocą GET czy zmienić na ładniejsze adresy. Wybieram oczywiście to drugie. Dlatego w /.htaccess zmieniam przekierowanie:

# Turn rewrite engine on Options +FollowSymlinks

RewriteEngine on    # map neat URL to internal URL

RewriteRule ^shops/ ShopController.php [nc,qsa]

RewriteRule ^shops/([^/]+)/([^/]+)$ ShopController.php?lon=$1&lat=$2&count=$3 [L]

Teraz ShopController.php, w którym również przechwytuję wyjątki (klasa ShopRestHandler):

<?php

require_once(„ShopRestHandler.php”);

$lon = „”;

$lat = „”;

$count = „”;

if(isset($_GET[„lon”])) $lon = $_GET[„lon”];

if(isset($_GET[„lat”])) $lon = $_GET[„lat”];

if(isset($_GET[„count”])) $count = $_GET[„count”];

$shopRestHandler = new ShopRestHandler();

if (strlen($lon)>0 && strlen($lon)>0 && strlen($id)>0) {$shopRestHandler->getAllShops();}

else $shopRestHandler->getShops($count,$lon,$lat);

 ?>

Reszta jutro.

Opublikowano

15 krok w aplikacji TAX FREE i chwila refleksji

Wreszcie wyszło. Problemy z wywołaniem funkcji innego kontrolera udało się rozwiązać rzutowaniem:

(rootViewController as? ViewController)?.showSwipeMenu()

Działa:

Brakuje ikonek w menu i dodam jeszcze przy sprzedawcy ikonę kategorii zakupionego towaru, tylko później. W menu pod „W pobliżu” będzie mapka sklepów w pobliżu jeżeli chce się udostępnić swoją lokalizację. Mapka szybko do zrobienia, natomiast naniesienie punktów wymaga skorzystania z webserwisu, który trzeba napisać i który udostępnia adresy sklepów – kolejny etap do zrobienia 🙂

Teraz podłączenie SQLLite – jestem w 1/4 drogi, bo mam klasę do utworzenia i połączenia bazy, jutro szybko dokończę oprogramowywanie tabel podrozny, rachunek, sprzedawca, ustawienia.


Moje dzisiejsze refleksje dotyczą:

  • gnuśnienia w pracy, bo nie mam się od kogo uczyć, bo albo trzymają dla siebie albo nic nie wiedzą.
  • potrzeby zmian na lepsze, w tym warunków płacy.
  • potrzeby robienia czegoś, żeby nie stać w miejscu i nie marnować czasu, malutkimi kroczkami.
  • obserwacji natury ludzkiej, tj. jestem introwertyczką, zawsze obserwuję i przetwarzam. Dziś byłam na konferencji MCE 2017 (http://2017.mceconf.com). Są tu ludzie bardzo różni, ale życzliwi. Niektórzy nastawieni na siebie, tak jak dziś widziałam jak dziewczyna w trakcie wykładu zajęta była swoim blogiem i komentarzami – nie podobało mi się, że w internecie przedstawiała siebie jako całkiem inną osobę, ładną i młodą, wystylizowaną. No cóż pewnie podejście biznesowe, każde kłamstwo przejdzie byle się sprzedać. Programistów łatwo odróżnić od designerów, bo chodzą zwykle sami i siedzą z komputerem, nie gadają z nikim, boją się odezwać. A ja kim jestem? Sama nie wiem bo ani programistą w pełni ani designerem w pełni, choć dziś jeden przypiął mi łatkę designerki, bo dziewczyna 🙂
  • chcę robić nadal to co robię ale w zespole a nie sama. ZAWSZE wartość dodana powstaje w zespole, samemu trudno. Trudno też trafić do dobrego zespołu – mam tu na myśli zatrudnienie u kogoś lub zatrudnienie kogoś. I chcę mieć z tego satysfakcję nie tylko finansową. Do tej pory już zdążyłam się przekonać, że mój sukces ma wielu ojców, tylko ja jakoś na końcu tego łańcuszka. Nie chcę już tak dalej.
  • dziś na konferencji padło między innymi taki zdanie: „bez ludzi nie ma technologii” i na płaszczyźnie praca i na płaszczyźnie klient i biznes. Padło też słowo „emocje”, że ludzie ich szukają i chcą je przeżywać używając technologii. Tak jak z pasją, że trzeba robić co się lubi, a pieniądze w końcu przyjdą. Chcę w to wierzyć że tak będzie. Tylko wtedy będę miała problem co z nimi zrobić 🙂 hehehe
Opublikowano

14 krok w aplikacji TAX FREE

Eksperymentuję z różnymi swipemenu i oto co mi wyszło 🙂 – pomieszanie z poplątaniem:

Nie chcę rezygnować z paska wyszukiwarki, dlatego modyfikuję widok początkowy wg tego bardzo prostego przykładu na swipemenu: https://www.youtube.com/watch?v=SGkYb820zr4

Zrobiłam wg powyższego przykładu i po naciśnięciu ikonki menu kolejny błąd, ponieważ z

AppSearchBarController’a wywołuję funkcję z ViewController’a zmieniającego constrainty z jego UIView (marginesy boczne

@IBOutlet weak var trailingConstraint: NSLayoutConstraint!

@IBOutlet weak var leadingConstraint: NSLayoutConstraint!) – w tym momencie cały ten viewcontroller jest nil’em, bo jeszcze nie został utworzony na stosie.

Zrzut ekranu 2017-05-03
Zrzut ekranu 2017-05-03

Pewnie dziwi, że tak mało zrobiłam do tej pory osoby, które myślą, że programowanie to klik klik i już. Ja muszę przebrnąć i zrozumieć co jest przyczyną danego błędu i muszę się wdrożyć w Swift. Za kilka miesięcy już nie będę juniorem 🙂

Cały aktualny kod oczywiście na GitHub

 

Opublikowano

13,5 krok w aplikacji TAX FREE

Żeby się tak chciało jak się nie chce … Przede mną długi weekend majowy, trzeba pracować nad aplikacją, a jestem zmęczona jak długo wcześniej nie było. W pracy ogromny stres od końca poprzedniego roku, bo nikt nic nie wie co się z nami stanie. Nie wiem czy szukać nowej pracy, czy uczyć się nowego (między innymi dlatego wzięłam udział w konkursie żeby choć trochę nie myśleć o tej sytuacji). Jeszcze pomiędzy pracą a projektem dodatkowy angielski, jeszcze rodzina, jeszcze czas z nimi, bo nie można przegapić czasu jak dzieci są małe, jak się rozwijają. Tyle narzekania 🙂 Dałam sobie ostatnie 3 dni wolne (takie wolne że robimy remont, więc wolne od pracy umysłowej, jutro ciąg dalszy remontu), ale presja czasu że trzeba rozwijać projekt nie daje spokoju. Wiem że go nie skończę do końca konkursu, ale na pewno skończę do końca roku 2017, i to cały.

Napisałam tytuł 13,5 bo mało kodowania a dużo planowania w tym poście.

Plany na następne dni:

  • Uruchomić wysuwane menu
  • Załadować dane do obiektu klasy Rachunek
  • Spróbować stworzyć i zapisać dane do lokalnej bazy danych.
Opublikowano

13 krok w aplikacji TAX FREE

Jak pewnie oglądający zauważyli, w widoku DetailView z poprzedniego wpisu brakuje paska menu. I tu rada dla siebie i innych początkujących: ZAWSZE czytać dokumentację producenta! DetailView generuje się „w standardzie” z TableView, ale nie zawiera NavigationBar, ponieważ kontroller widoku modalnego nie jest dodawany do stosu nawigacji. Oczywiście trzeba dodać go ręcznie. Reszta zmian wkrótce. Teraz przyszedł czas na bazę danych.

Jak w aplikacji jest mało danych, które trzeba zapisać to można skorzystać z prostego rozwiązania do przechowywania danych – local storage i NSCodingu – protokołu umożliwiającego szybkie archiwizowanie obiektów i innych struktur. Archiwizowane obiekty można zapisać na dysku i pobrać później.

Ja chcę pójść o krok dalej i skorzystać z lokalnej bazy danych.

W systemie iOS dwie podstawowe technologie zapisu pamięci masowej dostępne dla programistów: Core Data i SQLite. Obie technologie mają zalety i wady w zależności od ilości i typu danych, które mają być przechowywane i zarządzane.

Core Data koncentruje się na obiektach, a nie na tradycyjnych podejściach opartych na tabelach. Podczas przechowywania danych przechowuje się zawartość obiektu, gdy obiekt jest reprezentowany przez klasę.

SQLite jest otwartą, lekką, z dobrym wsparciem, wieloplatformową, relacyjną bazą danych. SQLite przechowuje dane w tabelach, w których tabela zawiera jedną lub więcej kolumn, każda kolumna zawiera dane dla określonego typu danych.

SQLite:

  • SQLite jest lekki.
  • SQLite używa mniej pamięci i przestrzeni dyskowej.
  • SQLite może być żmudny i podatny na błędy kodu.
  • SQLite jest obsługiwany na Androidzie i Microsoft Windows Phone.

Core Data:

  • Potrzeba więcej czasu żeby go zrozumieć i nauczyć się.
  • Łatwiej pracuje się z obiektami.
  • Podstawowe informacje do przechowywania są obsługiwane automatycznie dzięki iCloud.

Ponieważ chcę w przyszłości przepisać tę apkę na Android, więc wybieram SQLite. Teraz trzeba przebrnąć przez tutoriale.