Kashiash's Blog

o programowaniu inaczej : jak zrobić i się nie narobić

Archive for the ‘Uncategorized’ Category

Go(lang) I MS SQL

Posted by kashiash w dniu 18 grudnia, 2017

Dzisiaj połaczymy sie aplikacja w go z MS SQL.

Trzeba pobrać driver sql


go get github.com/denisenkom/go-mssqldb

przykład, który pobiera dane z tabeli:

package main
import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/denisenkom/go-mssqldb"
)
func main() {
    condb, errdb := sql.Open("mssql", "server=192.168.1.1;user id=jk;password=JakiesDzwineHaslo;database=baza1")
    if errdb != nil {
        fmt.Println(" Error open db:", errdb.Error())
    }
    var (
        id int
        NrKlienta int
        Nazwa string
    )
    rows, err := condb.Query("select ID,IDKLIENTA,NAZWA from dbo.Klienci")
    if err != nil {
        log.Fatal(err)
    }
    for rows.Next() {
        err := rows.Scan(&id, &NrKlienta, &Nazwa)
        if err != nil {
            log.Fatal(err)
        }
        log.Println(id, NrKlienta, Nazwa)
    }
    defer condb.Close()
}

powyższy kod pobiera 3 wybrane kolumny z tabeli klienci i wyświetla je na oknie konsoli.
Następnym razem wrzucimy to do excela 😉
Gdybysmy chcieli wykonać jakąś komendę nie będąca zapytaniem sql można użyć metody Exec:

   _, err = condb.Exec("update klienci set Uwagi = 'ABC' where Data is not null")

Posted in Go, SQL, Uncategorized | Leave a Comment »

Błąd 07006 czyli Naruszenie atrybutu ograniczonego typu danych podczas dostępu do rekordu dbo.Faktury

Posted by kashiash w dniu 3 marca, 2015

I z rozpędu kolejny babolik własnej produkcji:

Pojawia się wtedy gdy próbuję użyć {prop:sql} na strukturach gdzie liczba/typy/kolejność kolumn w dct różnią się od tego co jest w SQL. W tym przypadku zrobiłem małe sprzątanie w dct, a sql-owe odłożyłem sobie na ” jak będę miał większe moce przerobowe”.

Zapomniałem jednak, że kiedyś pod wpływem „eksplozji chęci bycia cool, maczo programowania itd” popełniłem taki kod:

faktury{PROP:SQL} = 'select * from faktury where ....

loop until Access:Faktury.Next()
...
...

…i dopóki dct było zgodne z SQL, to ten trik dawał ogromny zysk wydajnościowy, a jednocześnie był miną przeciw-programistyczną na którą zgodnie z prawem Murphy’ego, się nadziałem. I taką został – posprzątałem w SQL.

Posted in Uncategorized | Otagowane: , , | Leave a Comment »

Błąd (01S01) co to za błąd? Szczególnie z punktu widzenia programisty Clarion

Posted by kashiash w dniu 3 marca, 2015

Od czasu do czasu, po kolejnym grzebnięciu w kodzie pojawiają się dziwne komunikaty błędów. Praktycznie za każdym razem przypominam sobie, że miałem z czymś takim do czynienia, że znalazłem rozwiązanie, ale już nie pamiętam. Następuje proces przeszukiwania Google, który jak zwykle charakteryzuje się tym, że niby tematów podobnych jest mnóstwo, ale to tylko takie „akademickie” pitolenie, z którego niewiele wynika.
Najchętniej znalazłbym własną odpowiedź: jak sobie poradziłem poprzednim razem. I temu służy ten wpis.

Błąd (01S01) czyli SQL fractional truncation, występuje w przypadku moich programów gdy pobieram typ DATE (w dct) z SQL gdzie jest on DateTime i w cześć bitów zawierającej Time są wartości rożne od 0. Najczęściej występuje to wtedy gdy dokonam update tej daty w SQL np funkcja getdate(), bez przycięcia części związanej z czasem:
Wtedy wystarczy zwykły update:

update[RejestrZdarzen]
set data = cast(cast(data as int) as datetime)
where data <> cast(cast(data as int) as datetime)

i pozamiatane. Oczywiście można dyskutować , że skoro w SQL jest DateTime, to w DCT tez tak powinno być, ale to rozwiązanie ma też kilka wad, które irytują mnie niekiedy bardziej niz powyższe.

Okazuję się, że w przypadku samego pola typu Time w clarionie, w SQL po konwersji np FM3 to pole tez jest DateTime i tez jest mały problem bo SQL potrafi zapamiętać tam więcej niż clarion, co w konsekwencji też wywoła powyższy błąd w aplikacji clarionowej.

prostowanie polega na wycięciu części z tysiecznymi np tak:

update[RejestrZdarzen]
set czas = cast(czas as char(19))
where ...

Może się jednak przekonam na używanie grup DateTime …

Posted in Uncategorized | Otagowane: , , | Leave a Comment »

Posted by kashiash w dniu 11 lutego, 2011

Tutorial II: Vehicle Management System – Part 3: New Tables

 

 

In such a vehicle management system, an information about expenses is usually very useful.

To implement it, let’s add a FuelLog and two dictionary tables about fuel provider company and fuel type. To do so, please follow the table:

FuelLog  

 

PkFuelLog 

KEY(Ful:Id),DUP,NOCASE 

KeyVehicle 

KEY(Ful:Vehicle),DUP,NOCASE 

KeyBrand 

KEY(Ful:Brand),DUP,NOCASE 

KeyFuelType 

KEY(Ful:FuelType),DUP,NOCASE 

Columns 

 

Id  

LONG 

Vehicle 

LONG 

FillUpDate 

DATE 

Quantity  

REAL 

TotalCost  

REAL 

Notes 

STRING(100) 

StartingOdometer 

LONG 

EndingOdometer 

LONG 

OdometerChange 

LONG 

Brand 

LONG 

FuelType 

LONG 

   

Brands 

 

PkBrands

KEY(Bra:Id),DUP,NOCASE 

KeyBrand 

KEY(Bra:Brand),DUP,NOCASE 

Kolumny 

 

Id  

LONG 

Brand 

STRING(51) 

   
   

FuelTypes  

 

PkFuelTypes 

KEY(Fty:Id),DUP,NOCASE 

KeyFuelType 

KEY(Fty:FuelTypes),DUP,NOCASE 

Columns 

 

Id 

LONG 

FuelTypes 

STRING(50) 

 

In addition, define relations between the tables:

FuelTypes <->> FuelLog

Vehicles <->> FuelLog

Brands <->> FuelLog

For the newly created FuelLog table, set must be in file for the fields Vehicle, Brand i FuelType. (this should be done in the Validity Checks tabs)

Then, set for these columns UseSpinner and DSP.

 

 

 

Finally, we’ll obtain a following database structure:

 

Let’s save the application and generate code.

We have 3 new tables, so we need new icons for them. Without them, the application will not run.

We need brands.png, fuelstypes.png and fuellog.png, to be added to the res/drawables folder.

After starting the generated application we should see:

 

 

As you see, we are running out of space. Making icons smaller than 48×48 would help to some extent,. We could also stop showing all these buttons in the main menu.

But, so far, look what more came out from our efforts:

 

There is surely a problem with space, but MOBY will help us!

In File User Options set PromptsInLine(true) . After regenerating:

 

 

The same can be set for Vehicles: PromptsInLine(true).

In the current version, there are 2 posssiblities to get into the fuel log: either directly from the main menu or from the menu key in the vehicle screen.

When we set UseTabHost(true) in FileUserOptions for Vehicles, the application will generate code so, that the list will be accessible also from a separate tab in the vehicle screen.



 

In the subsequent steps, we’ll work on more lists to be displayed for vehicles and on the fuel log. So far play with the application as is.

 

 

 

 

 

 

 

 

 

Why doesn’t it compile ?

When we get a message in Eclipse that our project has errors and can’t be started, check the PROBLEMS tab.

Here an example of a message. In this case cleaning the project is sufficient to get it right.

 

We recommend to start any attempts in this way. Simply select Project/Clean and look what is displayed in the Problems tab.

In addition, it is good to know that common error in a MOBY application is caused by the lack of required icons.

Simply add the icons with required names to the res/drawables folder and the issue should be solved.

 

 

 

 

 

Posted in Uncategorized | Leave a Comment »

Wykaz Opcji użytkownika

Posted by kashiash w dniu 28 stycznia, 2011

 

 

Definiowane dla każdej z tabel: %FileUserOptions

 

User option

Typ

Opis

 

UseTabHost

boolean

Okienko Edycji danej tabeli będzie miało zakładki na których będą wyświetlane dane z tabeli podrzędnych (Child Tables)

Użyteczne dla tabel posiadających tabele podrzędne

NOPOPULATE

boolean

Nie zostanie utworzone odwołanie do tabeli z głównego okna aplikacji

Kod procedur jest generowany, dostęp do tych procedur jest z innych procedur np. jako tabele podrzędne w relacji lub służące do wyboru z listy

FreezeList

boolean

Wyłącza generowanie kodu procedury wyświetlającej listę rekordów

Zapobiega nadpisaniu ręcznie dokonanych zmian

FreezeEdit

boolean

Wyłącza generowanie kodu procedury Edycji rekordów

 

FreezeListLayout

boolean

Wyłącza generowanie definicji interfejsu użytkownika dla listy rekordów

 

FreezeEditLayout

boolean

Wyłącza generowanie definicji interfejsu użytkownika dla edycji rekordów

 

FreezeTabHost

boolean

Wyłącza generowanie kodu procedury wyświetlającej obsługującej wywołania z zakładek

 

ALTERNATELAYOUT

number

Generator użyje predefiniowanego wyglądu UI dla listy

Szczegóły w rozdziale dotyczącym alternatywnych UI

LeftIconField

string

Określamy jakie pole będzie użyte do określenia jaka ikonka jest wyświetlana po lewej stronie

Informacja dodatkowa dla ALTERNATELAYOUT

RightIconField

string

Określamy jakie pole będzie użyte do określenia jaka ikonka jest wyświetlana po prawej stronie

Informacja dodatkowa dla ALTERNATELAYOUT

UpTextField

string

Określamy jakie pole będzie wyświetlane w górnym tekście

Informacja dodatkowa dla ALTERNATELAYOUT

LoTextField

string

Określamy jakie pole będzie wyświetlane w dolnym tekście

Informacja dodatkowa dla ALTERNATELAYOUT

 

 

Definiowane dla każdej kolumny: %FieldUserOptions

 

LOOKUP

string

Wpisz do tego pola wynik wyrażenia po pobraniu tabel będących w relacji. (Na początku procedury oraz po każdym wybraniu rekordu z listy lub spinner’a)

PostalCodesRecord.getCity()

LOOKUPCONDITION

string

Warunek, kiedy wyrażenie ma być wywołane

Przypisanie wartości null do kontrolki wywołuje wyjątek, użyteczne aby sprawdzać czy wyliczona wartość jest poprawna

EVALUATE

string

Wpisz wynik wrażenia do tego pola

InvItemsRecord.getPrice() * InvItemsRecord.getQuantity() * ( 1 – InvItemsRecord.getDiscount()/100)

EVALUATECONDITION

string

Warunek kiedy wyrażenie z Evaluate będzie wyliczane i wpisane

InvItemsRecord.getPrice() != null && InvItemsRecord.getQuantity() != null

UseSpinner

Boolean

Jeśli po polu jest relacja (M:1)do tabeli nadrzędnej, to do wyboru rekordu użyty będzie Spinner – odpowiednik clarionowego FileDrop

To pole musi być w relacji do PK innej tabeli oraz w Validate Checks należy określić tabelę w Must be in File

DSP

string

Zamiast ID będzie wyświetlana wartość z podanego pola z tabeli nadrzędnej

Należy zdefiniować klucz w tabeli nadrzędnej zawierający pole podane w dsp

FILTERCONDITION

string

Do listy/ spinnera z rekordami tabeli nadrzędnej użyty zostanie filtr zdefiniowany w FilterExpression jeśli spełniony będzie podany tu warunek.

mCityText.getText().toString().length() !=0

FILTEREXPRESSION

string

Wyrażenie filtrujące rekordy w tabeli nadrzędnej lub spinnerze

” City LIKE \”” + mCityText.getText().toString()+”%\””

READONLY

Boolean

Pole będzie w trybie ReadOnly.

 

HINT

string

Definiuje tekst wyświetlany w kontrolce jeśli jest pusta

 
       

ActionButtonCode

 

Kod w języku JAVA wywoływany po naciśnięciu przycisku

 

ActionButton

string

Obok kontrolki dodawany jest dodatkowy przycisk pozwalający wywołać kod zdefiniowany w ActionButtonCode

Należy wpisać tekst wyświetlający się na przycisku

ActionButtonIcon

string

Nazwa ikonki wyświetlanej na przycisku.

Plik z ikonką musi być w katalogu /res/drawables

PhoneButton

Boolean

Generator

 

NOPOPULATEONEDIT

Boolean

Pole nie pojawi się na oknie Edycji

 

NOPOPULATEONLIST

Boolean

Pole nie pojawi się na oknie z lista rekordów

 

UPDATECONTROLS

Boolean

Po zmianie wartości pola zostaną wykonane przeliczenia zdefiniowane w LOOKUP oraz EVALUATE

 

SPINNABLE

Boolean

Dodaje w UI dwa przyciski pozwalające zmniejszać/zwiększać wartość pola – odpowiednik strzałek w clarionowej kontrolce spin entry

 

 

Posted in Uncategorized | Leave a Comment »

System Ewidencji pojazdów … zabawy ciąg dalszy

Posted by kashiash w dniu 28 stycznia, 2011

 

Jeśli pobawiłeś się wygenerowana aplikacja zapewne zauważyłeś, że można zrobić ciekawy wpis w bazie pojazdów np. Wybrać samochód Citroen Passat, albo Volkswagen XM. Tak źle, a tak już bluźnierstwo 😉

Trzeba przekazać informację do Spinnera wyświetlającego Modele, jaka markę ma wyświetlać. Do tego służą 2 kolejne FieldUserOption w dct:

FILTERCONDITION – opcja która pozwala nam określić kiedy filtr ma być stosowany. W naszym przypadku wtedy gdy mamy wpisanego producenta:

VehiclesRecord.getMake() !=0

Oraz wyrażenie budujące fragment klauzuli where w zapytaniu pobierającym dane z SQLLite FILTEREXPRESSION. W naszym przypadku producent modelu ma być równy producentowi wybranemu na ekranie:

„models.make = ” + VehiclesRecord.getMake()

 

 

Dodatkowo po zmianie modelu należy wywołać metodę, która załaduje na nowo rekordy do spinnera z modelami, użyjemy do tego opcji OnAccepted

A procedura ładująca dane to LoadModel_Spinner()

 

 

Zapisujemy dct ,otwieramy app – generujemy kod, który następnie kompilujemy w Eclipsie

W efekcie dostajemy :


 

Dla Ciekawskich

 

Co zmieniły nasze ustawienia ? Wpis OnAccepted spowodował doanie metody:

        Make_Spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override

            public
void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {

                VehiclesRecord.setMake(id) ;

                LoadModel_Spinner();

 

            }

 

            @Override

            public
void onNothingSelected(AdapterView<?> parentView) {

                // your code here

            }

        });

 

Zaś wpis FILTERCONDITION i FILTEREXPRESSION genruja taki kod:

 

    private
void LoadModel_Spinner() {

 

        if (Models_Cursor !=null) {

            stopManagingCursor(Models_Cursor);

            Models_Cursor.close();

        }    

 

        if (VehiclesRecord.getMake() !=0) {

            Models_Cursor = ModelsxDbAdapter.getAll(„models.make = „ + VehiclesRecord.getMake(),null);

        } else {

            Models_Cursor = ModelsxDbAdapter.getAll(null,null);

        }


Posted in Uncategorized | Leave a Comment »

System zarządzania pojazdami – Tutorial II

Posted by kashiash w dniu 25 stycznia, 2011

 

 

Tym razem zrobimy bardziej rozbudowana aplikację, gdzie spróbuję przedstawić większość możliwości MOBY I.

 

Zrobimy system ewidencji pojazdów, wydatków z nimi związanych, rejestru napraw itp. W tej części skupimy się jedynie na kartotece pojazdy i kartotekami słownikowymi związanymi z pojazdem.

 

Zakładamy nowe dct, w nim nowa tabele, która nazywamy Vehicles

Id

LONG

ModelYear

LONG

Odmoter

LONG

Make

LONG

Model

LONG

Color

LONG

PlateNo

STRING(20)

RegistrationNo

STRING(20)

Renewal

DATE

TireSize

STRING(20)

   

Oraz kilka indeksów:

PkVehicles

KEY(Veh:Id),DUP,NOCASE !By #

KeyMake

KEY(Veh:Make),DUP,NOCASE !By Make

KeyModel

KEY(Veh:Model),DUP,NOCASE !By Model

KeyColor

KEY(Veh:Color),DUP,NOCASE !By Color

 

Teraz definiujemy tabelę

Colors

Id

LONG

Color

STRING(20)

   

PkColors

KEY(Col:Id),DUP,NOCASE

KeyColor

KEY(Col:Color),DUP,NOCASE

 

Makes

Id

LONG

Make

STRING(20)

   

PkMakes

KEY(Id),DUP,NOCASE

KeyMake

KEY(Make),DUP,NOCASE !By Make Name

 

Models

Id

LONG

Make

LONG

Model

STRING(20)

   

PkModels

KEY(Mod:Id),DUP,NOCASE

KeyMake

KEY(Mod:Make),DUP,NOCASE

keyModel

KEY(Mod:Model),DUP,NOCASE

 

Teraz zdefinujemy relacje pomiędzy tabelami. Nazwy kolumn sa na tyle jednoznaczne, że nie będę się rozpisywał, tym bardziej ze wszystkie pliki źródłowe są do pobrania

 

Makes <->> Models

Models <->> Vehicles

Colors <->> Vehicles

Makes <->> Vehicles

 

Teraz w tabeli Models wchodzimy do kolumny Make na zakładke Validate Checks, zaznaczamy Must be in Table i wybieramy Makes

 

 

Teraz podobna operacje przeprowadzamy w tabeli Vehicles dla kolumn: Make Model i Color

Na obecnym etapie nasz baza danych powinna wyglądać tak:

W tym momencie przerwiemy tymczasowo definiowanie naszego dct i wygenerujemy początkową wersje naszej aplikacji:

(poniższe kroki są dokładnie opisane we wcześniejszym tutorialu, wiec nie będę ich dokładnie opisywał)

  1. Zapisujemy dct
  2. Tworzymy puste APP z wyżej utworzonym dct
  3. W app wywołujemy UTILITY Template (Ctrl-U)
  4. Wybieramy Clarion2Android, pozostawiamy ustawienia domyślne i naciskamy OK
  5. W eclipse otwieramy nowy projekt (New Android Project)
  6. Wybieramy Create project from existing source i wskazujemy na katalog wygenerowany w kroku 4 i naciskamy Finish
  7. (Jest to podkatalog o takiej samej nazwie jak plik app, w katalogu gdzie mamy app i dct)

 

Wybieramy na oknie nawigator nasz projekt, w menu eclipsa wybieramy project/clean

 

 

Operacja ta ma na celu odbudowanie przez eclipsa wszystkich potrzebnych plików w projekcie

Teraz należy do katalogu res/drawables wgrać wszystkie potrzebne ikonki:

 

Po wrzuceniu wszystkich ikonek wybieramy z menu Run as Android project i czekamy na uruchomienie emulatora (trwa nawet 2 minuty, w zależności od komputera na jakim pracujecie)

W przypadku otrzymania komunikatu, że projekt zawiera błędy sprawdzamy czy na pewno wgraliśmy wszystkie ikonki i ewentualnie wybierzmy jeszcze raz z menu project/clean/vehicles

Na ekranie emulatora powinien pojawić nam się następujący widok:

Klikamy na Vehicles, pojawi się pusta lista, naciskamy menu i Add

Pojawi się ekran wprowadzania danych o pojeździe:


Naciskamy przycisk … przy polu Make, który wywoła liste producentów – na razie pustą.

Na tej liście naciskamy Menu i Add i jesteśmy na ekranie wpisywania danych producenta.

 

 

Dopisujemy dane kilku producentów i naciskając przycisk Back wacamy do menu głównego programu

Następnie wybieramy Models

Dopisujemy model samochodu np. Golf


 

Dopieszczanie interfejsu

Jak widać na powyższym ekranie nie wygląda zbyt elegancko, zamiast ID producenta chcielibyśmy widzieć jego nazwę

Do tego służy Opcja DSP od Display (niestety słowo display jest używane prze jakies szablony SV i clarion zachowuje się przy nim niedeterministycznie )

Wracamy do DCT, do tabeli Models do kolumny Make i dodajemy w opcjach : DSP(Kolumna z nazwa producenta)

Idziemy za ciosem i w tabeli Vehicles dodajemy DSP dla pól: Make, Model i Color

 

 

Idziemy za ciosem i w tabeli Vehicles dodajemy DSP dla pól: Make, Model i Color

Ważne jest aby dla tabel słownikowych dla pól wskazanych w dsp były zdefiniowane indeksy

KeyNazwaPola (WIELKOŚĆ LITER ISTOTNA !)np. KeyMake w tabeli producentów.

 

Otwieramy app i ponownie uruchamiamy Template Clarion2Android, następnie w eclipse naciskamy F5 – wymuszając na eclipsie odświeżenie źródeł

Uruchamiamy nasz projekt i teraz jak wejdziemy na listę modeli, a następnie na edycje danych modelu, otrzymujemy taki efekt jak poniżej.


W pole make możemy teraz wpisać nazwę producenta lub jego Id a aplikacja go znajdzie, możemy go tez wybrać z listy klikając na przycisk „…”

 

Jest lepiej, ale o ile takie rozwiązanie wystarczało w clarionie, to w androidzie jest nieco staroświeckie, zamienimy pole producenta z przyciskiem wyboru na Spinner. Spinner to odpowiednik clarionowej kontrolki File Drop.

Wracamy do dct do tabeli Models i w kolumnie Make w opcja dopisujemy UseSpinner(true)

 

To samo możemy zrobić w Vehicles dla Make, Model i Color

 

Generujemy projekt na nowo, odświeżamy go w Eclipse i uruchamiamy,

Po wejściu do edycji modelu naszym pięknym oczom ukazuje się następujący ekran:

A jeśli zadaliśmy sobie trud ustawienia UseSpinner dla Vehicles to w edycji pojazdu mamy taki widoczek:

 

Wystarczy tej rozkoszy clarionowo androidowej na dzisiaj, ciąg dalszy wkrótce

Posted in Uncategorized | Leave a Comment »

Lektury, źródła wiedzy, inspiracje

Posted by kashiash w dniu 11 grudnia, 2010

Spisuje tutaj swoje przemyślenia, cześć jest faktycznie moimi pomysłami, a część to informacje zasłyszane lub przeczytane, po mniejszym lub większym przetworzeniu w mojej „makówce”. W celu uniknięcia posądzenia o wypisywanie cudzych koncepcji bez wymieniania źródła informacji,  przestawiam poniżej listę ostatnich lektur jakie mnie zajmowały i bardzo prawdopodobne że wpłynęły i wpływać będą na treść tego co wypisuję lub opowiadam.

N. Wirth Algorytmy + struktury danych = programy

J. Bentley Perelki programowania

Robert L. Baber O programowaniu inaczej

powyższe to lektury sprzed wielu lat, które wraz ze wszystkimi przygodami Pana Samochodzika, Old Surehanda i Tomka Wilmowskiego, spowodowały, że jestem kim jestem 😉

poniżej lista lektur z ostatnich kilku miesięcy

David Allen Getting Things Done

red. Kevlin Henney 97 Things Every Programmer Should Know

Neal Ford The Productive Programmer

Robert C. Martin Czysty kod podręcznik dobrego programisty

Joel Spolsky Smart and Gets Things Done: Joel Spolsky’s Concise Guide to Finding the Best Technical Talent

C & C Ta’eed How to be rockstar freelancer

Edited by Andy Oram and Greg Wilson Beautiful Code

Jason Fried Rework

i pewnie mnóstwo innych o których już nie pamiętam … jak sobie przypomnę będę dopisywał

Posted in Uncategorized | Leave a Comment »

Zasada Pareto w pracy programistycznej

Posted by kashiash w dniu 5 grudnia, 2010

Zasada Pareto w pewnym uproszczeniu mówi, że 20% obiektów jest związanych z 20% zasobów. Co to oznacza dla nas? Np to że 80% funkcjonalności nowego programu zrobimy w 20% całego czasu realizacji programu. Jednocześnie  na odwrót: 80% czasu zajmie nam tworzenie 20%   programu. I co z tego ? A np to, że warto oszacować które z procedur należą do tych 80% a które do pozostałych 20% i zrealizować 80% funkcjonalności,  po 1/5 czasu zaplanowanego na projekt  w harmonogramie dać użytkownikom program (działający w 80%). Ten program usprawni już im pracę. Widzą co powstało, maja na czym pracować ,nie marudzą kiedy będzie program, tylko ewentualnie wypominają czego w nim brakuje – a to już inna bajka (w końcu nie ukrywamy, że to nie jest nasze ostatnie słowo)! Presja pracy nad programem spada – oczywiście nie można sobie pozostałych 20% odpuścić, ale dobre poczucie, że już coś działa pozwala na bardziej komfortową pracą nad resztą.

Drugą zaletą takiego postępowania jest to, że jeśli podczas projektowania poczyniliśmy błędne założenia to większość z nich może być już na tym etapie wychwycona. Chyba lepiej dowiedzieć się, ze do zmiany mamy wynik kilku tygodni pracy, niż to co robiliśmy przez ostatnie pół roku.

Należy sobie uświadomić, że program idealny nie istnieje. Zawsze można coś zakodować lepiej:  uzyskamy bardziej efektywny kod, czytelniej czy bardziej przyjazne dla użytkownika. Tylko jeśli będziemy pracować nad tym tym idealnym programem to czas jego oddania będzie oscylował w następnym dziesięcioleciu.

Na Playstation jest taka gra Gran Turismo 5. Pisali ją kilka lat i podobno skończyli tylko dlatego ze ktoś zagroził zespołowi programistycznemu, że ich odłączy od kasy za pisanie. Ci przyjęli „propozycję nie odrzucenia” z komentarzem ze wiele rzeczy jeszcze chcieli tam zmienić tylko nie dane im było. Pewnie robiliby to jeszcze ze 4 lata. Efekt jaki uzyskali w „niedokończonej” wersji jest wybitny, niespotykany w żadnym innym symulatorze wyścigów samochodowych. Tak długo mogli trzymać klientów w niepewności i testować ich cierpliwość , bo ……………………   po 2ch latach wypuścili wersję GT5 Prologue .

Tak też należy pisać program: robimy wersje „Prologue”, dajemy użytkownikom, niech się nacieszą, niech używają, testują, a my mamy czas na cyzelowanie interfejsu użytkownika, dopieszczanie zapytańdo bazy danych czy kolejnej pętli liczącej PI z dokładnością do kilku tysięcy miejsc po przecinku 😉

Wśród ostatnich przemyśleń pojawiło się jeszcze jedno: nikt nie lubi pisać dokumentacji. Warto wtedy pamiętać o opisywanej zasadzie. Trzeba napisać 20 % dokumentacji, która opiszę 80% funkcji systemu. Zawsze można powiedzieć że 80% tego co miało być opisane, jest opisane!

Posted in Uncategorized | Leave a Comment »

Pracoholizm

Posted by kashiash w dniu 29 listopada, 2010

Niekiedy zadaje sobie pytanie, czy jestem pracoholikiem? Niestety prawdopodobnie jestem lub bardzo blisko mi do bycia nim. Żyjemy w społeczeństwie gdzie uczciwa praca ma poważanie. I całe szczęście, że tak jest. Tylko czy pracoholizm tez zasługuje na poważanie? Facet który pracuje 12 godzin dziennie, po tygodniu ma wydajność kogoś, kto pracuje 5-6 godzin. Pozostały czas spędza nad walka z presja czasu, ilości zadań i walki z frustracja wynikająca z tego ze coś  nadal nie jest skończone.
Dodatkowo ktoś taki wpływa negatywnie na morale reszty zespołu. Pozostali współpracownicy nie wiedza czy to, ze oni kończą pracę o ustalonej w umowie pracy godzinie jest ok, czy może jest źle odmianę przez szefostwo. I najgorzej jest gdy szefostwo docenia pracę po godzinach. Jednoznaczne daje nam sygnał ze nie zna się na programowaniu, ze nie ma świadomości, że ten człowiek nawet jeśli pracuje dłużej, to prawdopodobnie generuje sporo błędów i demoralizuje resztę zespołu.
Ktoś kto pozostaje po godzinach nie jest bohaterem!
Bohaterem  jest ten, kto skończył pracę normalnie, zrobił co był w stanie i poszedł  do swego domu.

Sam też dbaj o to żeby znacząca cześć twego dnia czy tygodnia zajęta było przez twoje hobby. I to nie powinna być coś związane z komputerami. Najlepiej żeby były działania znacząca dalekie np pływanie czymkolwiek,nurkowanie, jazda rowerem, sklejanie modeli, czy też hodowla jedwabników.

Jak wyczujesz ze spada ci wydajność, spakuj się i jedź, gdziekolwiek, byle jak najdalej od komputera.  Czas poświęcony na wyjazd nie był stracony, to inwestycja, która natychmiast zacznie się zwracać. Po powrocie poczujesz przypływ nowych sił i chęci do pracy.

Posted in Uncategorized | 1 Comment »