Duża Hydra – pierwszy projekt

Większość kursów programistycznych zaczyna od czegoś banalnego typu wyświetlenie komunikatu Hello World! Jednakże na potrzeby tego rozwiązania proponuję, że wykonamy coś ciekawszego. Problem jaki rozwiążemy celowo przejaskrawiam, wiem, że w ten sposób lepiej zapadnie Ci w pamięci.

Załóżmy, że wśród pracowników przyjął się zwyczaj “śmieszkowania” poprzez umieszczania w nazwie towaru w kartotece towarowej opisów zawierających nieodpowiednie słowa np. kit, dupa, lipa.
Ciężko się nie zgodzić, z faktem, że słabo będzie wyglądała pozycja na fakturze:
Farba X – dupa nie farba
Zróbmy coś z tym!

Zakasaj rękawy, będzie kodowanie!

DH start!

Ale czekaj… Skoro czytasz ten artykuł pewnie robisz to pierwszy raz?
Przygotujmy się, poniżej przedstawię jak sprawdzić czy posiadasz Dużą Hydrę w systemie oraz jakie dev narzędzia będą dla Ciebie niezbędne.

Aby praca nad dodatkiem Dużej Hydry była możliwa musisz posiadać moduł XL Hydra Plus, możesz zapytać o ten fakt swojego opiekuna Comarch lub samodzielnie sprawdzić w Menadżerze Kluczy poprzez odnalezienie pozycji XL Hydra Plus i zweryfikowanie jej aktywności.

Menedżer Kluczy ERP XL – podgląd wystąpienia DH

Posiadasz dostęp do DH? Super! Możemy instalować środowisko developerskie. Jeszcze nie masz dostępu? Skontaktuj się z swoim opiekunem w tej sprawie i wróć do artykułu.

Aby wykonać dodatek Dużej Hydry będzie potrzebował dwóch narzędzi:

  • Visual Studio – nie jest istotna wersja, chociaż zawsze zalecam Ci instalację najnowszej jeżeli tylko masz taką możliwość;
  • Comarch ERP XL;

Uruchamiamy Visual Studio i tworzymy projekt typu Class Library, w którym utworzymy nasz dodatek DH.

Tworzenie projektu DH – Class Library

Usuwamy klasę Class1 i w tworzymy klasę CheckWareNameWidget, która będzie przechowywała definicję naszego dodatku.

Dodajemy do projektu referencje do dll z “Hydrą” CdnHydra.dll, plik ten znajduje się w katalogu z instalacją XL-a, przeważnie jest to coś w stylu:
C:\Program Files (x86)\Comarch ERP XL 2018.2\CdnHydra.dll

Dodajemy

using Hydra;

następnie dziedziczymy klasę abstrakcyjną

Callback

oraz nadpisujemy metody abstrakcyjne

Init()

oraz

Cleanup()

Powinieneś mieć przed oczyma taki kod:

using Hydra;

namespace DH_CheckWareName
{

 public class CheckWareNameWidget : Callback
 {
     public override void Init()
     {
     }

     public override void Cleanup()
     {
     }
 }
}

nad słowem kluczowym namespace dodajemy definicję dodatku DH, zgodnie z poniższym schematem:

[assembly: CallbackAssemblyDescription(Name: "Kontroluj nazwę towaru",
                                       Description: "Sprawdzaj czy na kartotece towarowej nie użyto zabronionych słów.",
                                       Author: "Szymon Liszewski",
                                       Version: "1.0",
                                       SystemVersion: "2018.2",
                                       Created: "14-11-2018")]

Pamiętaj aby poświęcić chwilę na wypełnienie powyższego opisu assembly, gdyż na jego podstawie będziesz odnajdywał plik w systemie ERP. W przypadku gdy wykonasz klientowi 20 i więcej dodatków DH, niezwykle istotne jest prawidłowe ich opisanie, dzięki czemu od razu jesteś w stanie odnaleźć dodatek realizujący daną funkcjonalność jeżeli będzie istniała potrzeba jego edycji/poprawy/deaktywacji.

Kolejnym krokiem jest dodanie atrybutu z subskrypcją procedury bezpośrednio nad nazwą klasy – atrybut ten określa w jakim miejscu w programie chcemy podłączyć się z naszym dodatkiem DH. W kolejnych wpisach opiszę dokładniej na czym polega owa subskrypcja, w tej chwili zaufaj mi i wprowadź kod:

[SubscribeProcedure(Procedures.TwrEdycja, "Edycja kartoteki towarowej")]

Tym sposobem utworzyliśmy definicję dodatku DH. Czas na to co tygryski lubią najbardziej czyli mięsko. Dodajemy zatem takiego potworka w ciele metody Init():

AddSubscription(true, 0, Events.OpenWindow, (procID, ctrlID, eveID) =>
{
    AddSubscription(true, GetWindow().Children["?Cli_Zapisz"].Id, Events.Accepted, (procedureID, controlID, eventID) =>
    {
        ClaWindow wareNameControl = GetWindow().Children["?Twr:Nazwa"];
        string wareName = wareNameControl.ScreenTextRaw;

        if (wareName.ToLower().Contains("lipa")
        || wareName.ToLower().Contains("dupa")
        || wareName.ToLower().Contains("kit"))
        {
            MessageBox.Show("Nazwa towaru zawiera niedozwoloną frazę. Niedozwolone słowa: lipa, dupa, kit.", "Blokada zapisu kartoteki", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            return false;
        }

        return true;
    });

    return true;
});

Na pierwszy rzut oka kod może wydawać się skomplikowany, jednakże jest bardziej banalny niż Ci się wydaje.
Metoda AddSubscription dodaje subskrypcję na daną kontrolkę lub okno.
Pierwsze wywołanie AddSubscription dodaje subskrypcję na okno “Karta towaru”, która jest podniesiona do trybu edycji. Następne wywołanie, zagnieżdżone, AddSubscription dodaje zdarzenie w momencie kliknięcia buttona zapisz “dyskietki” w oknie “Karty towaru”.
ClaWindow jest klasą, która reprezentuje każdy pojedynczy element GUI, zarówno główne okno GetWindow() jak również np. kontrolkę textbox z nazwą towaru GetWindow().Children[“?Twr:Nazwa”].
W przyszłości opiszę skąd możesz pobierać nazwy dzieci w oknie dla poszczególnych kontrolek, np. ?Twr:Nazwa lub ?Cli_Zapisz.
Jak również schemat działania dodatków DH. Na ten moment musi wystarczyć Ci informacja, że AddSubscription jest zdarzeniem, które oczekuje zaistnienia akcji na wybranej kontrolce, return true – oznacza, że zdarzenie zostaje wykonane, a return false – powoduje przerwanie zdarzenia.

Dysponujemy poprawnym kodem aplikacji, czas podłączyć ją w systemie, w tym celu wykonujemy builda aplikacji w trybie Release oraz w dowolnym module ERP XL wybieramy z głównego menu aplikacji System > Dodatki.

Uruchomienie okna zarządzające dodatkami DH w programie

Importujemy dodatek z za pomocą buttona Importuj – wskazujemy utworzoną przez nas bibliotekę DLL. Pojawia się na liście nowy dodatek o nazwie “Kotroluj nazwę towaru” wybieramy go oraz podnosimy do Edycji, w oknie edycji dodatku zmieniamy Stan dodatku ustawiając go na Aktywny.

Zaimportowanie dodatku oraz jego aktywowanie.

Ostatnim krokiem jest uruchomienie modułu Administrator i podpięcie dodatku pod konkretne centrum w programie. W tym celu w module Administrator wybieramy Firma > Struktura Firmy, po czym na zakładce Struktura praw podnosimy do edycji wybrane centrum (może to być główne centrum lub wybrane podcentrum). Przechodzimy do zakładki Dodatki, w której dodajemy nowo utworzony dodatek.

Od tej pory dodatek będzie działał w serwisie.
Jeżeli zdarzyłoby się, że jakiemuś operatorowi dodatek by nie działał sprawdź:

  • czy dodatek na pewno jest aktywny;
  • czy dodatek został przypisany do aktywnej struktury praw;
  • czy kod dodatku działa poprawnie;
  • spróbuj w oknie Lista dodatków wybrać opcję “Odśwież w programie”;
  • uruchom ponownie moduł ERP XL;

Tak prezentuje się działająca aplikacja, po wciśnięciu buttona zapisz na kartotece towarowej w przypadku gdy nazwa kartoteki zawiera nieodpowiedni tekst:

Zablokowanie zapisu kartoteki towarowej w chwili gdy nazwa kartoteki zawiera niestosowne słowo

Zrealizowaliśmy dodatek DH, część rzeczy nie została wyjaśniona dokładnie, chciałem abyś mógł wykonać całą aplikację jak najszybciej. Znajdziesz opisy zaawansowanych zagadnień w kolejnych wpisach.
Jeżeli potrzebujesz, poniżej znajduje się realizowane zadanie, wskaż jedynie referencje na plik CdnHydra.dll.

Gratuluję właśnie wykonałeś swój pierwszy dodatek DH!

Czym właściwie jest Duża Hydra?

Comarch ERP XL mimo wielu zalet nigdy nie będzie narzędziem dostosowanym do każdego przedsiębiorstwa w 100%. Ludzie różnią się, ich potrzeby również. Metodologia postępowania w przypadku prac budowlanych znacząco różni się od produkcji w zakładzie mleczarskim. Dlatego niezbędne jest dostosowanie produktu podczas jego wdrożenia. Często okazuje się, że nie zawsze środowisko ERP jest wystarczająco elastyczne aby w zakresie oferowanych funkcjonalności odzwierciedlić proces produkcji oraz czynności wykonywanych w firmie w sposób optymalny dla grupy odbiorców – użytkowników systemu.

W tym miejscu znajduje się luka dla programistów, dzięki Dużej Hydrze, mogą oni znacząco ułatwić pracę poprzez optymalizację procesów w firmie oraz dostosowania systemu do wymagań klienta.

Także do rzeczy: Duża Hydra jest interfejsem programistycznym, jest to komponent systemu Comarch ERP XL, który umożliwia zastosowanie w systemie tak zwanych dodatków, lub jak też mawiają starsi programiści, Callback-ów.

Dzięki DH programista jest w stanie m.in.:

  • reagować na zdarzenia (events) występujące w aplikacji, podpinać się pod nie oraz reagować na ich wystąpienie;
  • wprowadzać usprawnienia procesów (np. blokować wyskakiwanie okna zasobów podczas planowania procesu produkcyjnego) – o ile jest to zasadne, wykonać aktualizację cen względem określonego wzorca na dokumentach, dostosować dane w systemie do zapotrzebowania Klienta;
  • dodawać własne okna w systemie, przechowujące dodatkowe informacje lub oferujące dodatkowe realizacje;
  • wykonanie eksportu danych z systemu na cele innych systemów np. WinSAD, PUESC, CEPiK, etc. Dzięki czemu nie tylko oszczędzamy czas na potrzeby przygotowania danych w odpowiedniej strukturze, ale również zapewnimy ich poprawność;
  • wprowadzać procedury walidacyjne na dokumentach;
  • dostosowywać wybrane dokumenty zgodnie z wymaganym schematem (możliwe jest dodanie np. buttona, po wciśnięciu którego dokument automatycznie zostanie wypełniony zgodnie ze ustalonym schematem w firmie, np. dodany odpowiedni opis, wpisane atrybuty, ustawione odpowiednie pola typu checkbox oraz combobox);
  • Komunikację z innymi systemami np. Salesforce poprzez np. usługę RESTową;
  • Importowania danych do systemu ERP XL z innych systemów;

Przede wszystkim DH umożliwia:

  • znaczne oszczędności czasu podczas podczas korzystania z Comarch ERP XL – osobiście udało mi się przyspieszyć proces planowania produkcji w jednej z firm o 70% poprzez umożliwienie zablokowania okna listy zasobów przez wybranego operatora;
  • automatyzację zadań;

Stosowanie DH pozwala optymalizować system ERP.

Podstawowe polecenia w SQL Server

Podczas pracy z SQL Server niezbędne wg mnie są następujące polecenia:

1. Wyszukiwanie treści w bazie:

select o.name
from sys.sql_modules c
join sysobjects o on c.object_id = o.id
where [definition] like '%%'


2. Procent przebudowania indeksów w bazie:

;WITH cte AS
(
SELECT
object_id,
index_id,
partition_number,
rows,
ROW_NUMBER() OVER(PARTITION BY object_id, index_id, partition_number ORDER BY partition_id) as rn
FROM sys.partitions
)
SELECT
   object_name(cur.object_id) as TableName,
   cur.index_id,
   cur.partition_number,
   PrecentDone =
      CASE
         WHEN pre.rows = 0 THEN 0
      ELSE
         ((cur.rows * 100.0) / pre.rows)
      END,
   pre.rows - cur.rows as MissingRows
FROM cte as cur
INNER JOIN cte as pre on (cur.object_id = pre.object_id) AND (cur.index_id = pre.index_id) AND (cur.partition_number = pre.partition_number) AND (cur.rn = pre.rn +1)
ORDER BY 4


3. Aktualnie wykonujący się blok kodu w danej sesji:

select QueryText = SUBSTRING(st.text, (re.statement_start_offset/2)+1,
       ((CASE re.statement_end_offset
          WHEN -1 THEN DATALENGTH(st.text)
         ELSE re.statement_end_offset
         END - re.statement_start_offset)/2) + 1)
from sys.dm_exec_requests re with (nolock)
CROSS APPLY sys.dm_exec_sql_text(re.sql_handle) AS st
where re.session_id = 1234


4. Wypisywanie aktualnie wykonywanej operacji bez oczekiwania na zakończenie się całej procedury:

declare @Date date ='2015-01-16';
declare @DateStr varchar(100);
while(@Date < cast(getdate() as date))
begin
 set @DateStr = cast(@Date as varchar);
 Raiserror(@DateStr,0,1) with nowait
 --tutaj operacje z jakimiś datami
 set @Date = dateadd(day,1,@date);
end


5. Przykład wykorzystania ROW_NUMBER() do wyeliminowania duplikatów danych:

create table #fox_table  (ID bigint)

insert into #fox_table(ID) values (1);
insert into #fox_table(ID) values (1);
insert into #fox_table(ID) values (1);
insert into #fox_table(ID) values (1);
insert into #fox_table(ID) values (5);
insert into #fox_table(ID) values (5);
insert into #fox_table(ID) values (5);

;with duplicates as
(
 select ID, ROW_NUMBER() over (partition by ID order by ID) as RowNum
 from #fox_table with (nolock)
)
delete from duplicates where RowNum > 1;

select * from #fox_table

drop table #fox_table

6. Wyświetlenie top 25 procedur wykonujących największe ilości:
a) Logical Writes

SELECT TOP(25) p.name AS [SP Name], qs.total_logical_writes AS [TotalLogicalWrites],
qs.total_logical_writes/qs.execution_count AS [AvgLogicalWrites], qs.execution_count,
ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) AS [Calls/Second],
qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time],
qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_logical_writes DESC OPTION (RECOMPILE);


b) Physical Reads

SELECT TOP(25) p.name AS [SP Name],qs.total_physical_reads AS [TotalPhysicalReads],
qs.total_physical_reads/qs.execution_count AS [AvgPhysicalReads], qs.execution_count,
qs.total_logical_reads,qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count
AS [avg_elapsed_time], qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
AND qs.total_physical_reads > 0
ORDER BY qs.total_physical_reads DESC, qs.total_logical_reads DESC OPTION (RECOMPILE);


c) Logical Reads

SELECT TOP(25) p.name AS [SP Name], qs.total_logical_reads AS [TotalLogicalReads],
qs.total_logical_reads/qs.execution_count AS [AvgLogicalReads],qs.execution_count,
ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) AS [Calls/Second],
qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count
AS [avg_elapsed_time], qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_logical_reads DESC OPTION (RECOMPILE);


d) CPU

SELECT TOP(25) p.name AS [SP Name], qs.total_worker_time AS [TotalWorkerTime],
qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], qs.execution_count,
ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) AS [Calls/Second],
qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count
AS [avg_elapsed_time], qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);


e) duration

SELECT TOP(25) p.name AS [SP Name], qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time],
qs.total_elapsed_time, qs.execution_count, ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time,
GETDATE()), 0) AS [Calls/Second], qs.total_worker_time/qs.execution_count AS [AvgWorkerTime],
qs.total_worker_time AS [TotalWorkerTime], qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY avg_elapsed_time DESC OPTION (RECOMPILE);

Windows Service – wprowadzenie

Usługa Windows – proces wykonywany wewnątrz środowiska systemowego Windows, przeznaczony do specjalnych funkcji i niewymagający interakcji z użytkownikiem komputera. Proces taki nazywany jest też serwisem Windows. Usługa zwykle jest uruchamiana podczas startu (ładowania) systemu operacyjnego i działa tak długo, jak długo system jest czynny.

Tyle z wiki. Warto wejść w link i przeczytać pozostałe informacje.

W dzisiejszej części wykonamy banalny serwis windowsowy.

W naszym Visual Studio wybieramy kolejno File -> New -> Project i wybieramy projekt serwisu windowsowego zgodnie z poniższym schematem:

Otrzymamy projekt z klasą Service1.cs (ja osobiście zmieniam jej nazwę bo mnie ta drażni), który zawiera w sobie m.in. dwie nadpisane metody:

OnStart (logika wykonywana po uruchomieniu serwisu) i OnStop (logika wykonana przy zamykaniu serwisu).
Naszym zadaniem jest wykonanie jakiegoś ciekawego kodu w tych miejscach i nie tylko w tych 🙂
Co możemy zrobić? Wszystko!
Wysyłać powiadomienia na Skype, mail, SMS.
Wykonywać operacje na bazie danych.
Sprawdzać dostępność jakiś usług. itp.itd…

My przykładowo w OnStart umiejścimy logikę odpowiedzialną za wysyłanie maila, oczywiście drogi czytelniku, możesz zmodyfikować kod i np. utworzyć Timer, który co określony interwał będzie odpytywał zadany adres sieci Web o jakieś dane (i dopiero po pobraniu tych danych wysyłać maila). Tutaj nie będziemy implementować jakiegoś wyszukanego problemu.

Dodajmy poniższy kod do OnStart:

MailMessage message = new MailMessage();<br>message.From = new MailAddress("Jakiś adres email", "Wyświetlana nazwa");<br>message.To.Add(new MailAddress("mail, na który zostanie wysłana wiadomość"));<br>message.Subject = "Tytuł wiadomości";<br>message.Body = "Treść wiadomości";<br>SmtpClient smtp = new SmtpClient("adres smtp naszej poczty");<br>smtp.UseDefaultCredentials = false;<br>smtp.Credentials = new NetworkCredential("email", "hasło");<br>smtp.EnableSsl = true;<br>smtp.Port = 587;<br>smtp.Send(message);<br>

Tyle wystarczy by wystartować serwis, więc dajemy! Zmieniamy z Debug na Release i wciskamy F5 i co?
I gówno… 🙂
Otrzymamy komunikat:

--------------------------- Błąd uruchomienia usługi systemu Windows --------------------------- Nie można uruchomić usługi z wiersza polecenia lub z debugera. Usługa systemu Windows musi być najpierw zainstalowana (przy użyciu pliku installutil.exe), a następnie uruchomiona za pomocą Eksploratora serwera, Narzędzi administracyjnych usług systemu Windows lub polecenia NET START. --------------------------- OK ---------------------------
Błąd uruchomienia usługi systemu windows

Otóż tak jest, iż nie uruchomimy ani nie zdebugujemy (w domyślnej konfiguracji) naszego serwisu. Debugowanie serwisu pokażę w następnym wpisie.

Teraz przejdźmy do rejestracji serwisu.

Na maszynie, na której chcemy zarejestrować nasz serwis otwieramy Wiersz polecenia (cmd) jako administrator i wpisujemy:

sc create MyFirstService binPath= "ścieżka do zbudowanego przez nas serwisu" DisplayName= "Mój pierwszy serwis" start= auto

To wszystko, mamy już gotowy serwis, który będzie uruchamiał się automatycznie. Inne możliwości konfiguracji pod linkiem.
W kolejnej części pokaże jak można debugować usługę sieciową.

Poniżej jeszcze najprzydatniejsze polecenia (uruchamianie z CMD jako admin):
sc queryex NazwaUsługi – zwraca informacje o usłudze w tym jej numer PID
taskkill /f /pid NR_PID – ubija serwis, którego nie można zatrzymać – bardzo przydatne polecenie.

“Nie rozmawiajmy o polityce”

ciii_470

Do napisania tego wpisu zmusiło mnie wiele czynników, nie jestem pewien czy będę w stanie wymienić wszystkie ale postaram się w miarę mojego prostego informatycznego umysłu przekazać ciążące mi na sercu informacje wraz z możliwie najlepszą argumentacją.
1. Nie zgadzam się z istniejącą tendencją, iż nie należy rozmawiać na tematy polityczne.
2. Rozumiem osoby ucinające rozmowę (na tematy polityczne), jak również osoby wręcz darzących dużą agresją ludzi innego poglądu na politykę.
3. Jestem przerażony łatwością manipulacji medialnej w RP.
4. Przeraża mnie również podział pomiędzy ludźmi, spadek zaufania, skłócenie się rodzin.
5. Domniemywanie obywateli, iż obecność w wyborach jest “patriotycznym obowiązkiem”.

Mógłbym dodać więcej elementów do powyższej listy, jednakże uważam, że zaznaczyłem główne fakty, które są dla mnie istotne i o których rzadko rozmawia się na forum publicznym. Chcę teraz rozwinąć te punkty, wykazać z czym nie potrafię się pogodzić.

Ad 1.
Nie zgadzam się z istniejącą tendencją, iż nie należy rozmawiać na tematy polityczne.
Uważam, iż brak rozmowy na takowe tematy prowadzi do niemożliwości sterowania swoim losem, człowiek który nie potrafi wypowiedzieć się w sferze publicznej jest ograniczony przez media, które kreują w nim, często błędne, odczucia w stosunku do sfery politycznej/gospodarczej państwa.

Ad 2.
Rozumiem osoby ucinające rozmowę (na tematy polityczne), jak również osoby wręcz darzących dużą agresją ludzi innego poglądu na politykę.
Nie wiem jak jest to w Twoim przypadku, drogi Internauto, ale u mnie w rodzinie często dochodzi do spięć gdy rozmawia się o polityce. Przeważnie spięcia są typu: wykreowany świat przez media vs świat rzeczywistyStrasznie denerwuje mnie to, gdy ktoś poogląda TV i uważa się za wielkiego znawcę polityki, rynku, gospodarki i sytuacji Polski.
Wspomniałem o agresji, więc rozwinę swoją myśl. Wielu z Was nie zdaje sobie sprawy z tego, że jest sukcesywnie okłamywana w sposób taki, iż nie potrafi pojmować prawdziwie rzeczywistości (przykładowo – artykuły na gazeta.pl w większości wymuszają postrzeganie wydarzeń politycznych na korzyść niszczącej kraj partii – takie jest moje odczucie). Także gdy człowiek codziennie styka się “lawiną kłamstwa” w końcu przyjmuje je jako prawdę i broni zgubnych wartości, gdy słyszy sprzeczną z “jego” poglądem “nieprawdę”.

Ad 3.
Jestem przerażony łatwością manipulacji medialnej w RP.
Gdy ktoś chce powiedzieć prawdę może liczyć jedynie na pamięć w internecie:

W rodzimych mediach fakty przedstawiane są po łepkach – też to moje odczucie.
Każdemu radzę porównać wiadomości przedstawiane na TVP 1, TVN, TV TRWAM, NIEZALEŻNA.TV i samemu zdecydować, które media dążą do prawdy oczywiście mam na myśli zdarzenia kluczowe – np. Smoleńsk, dług publiczny, prywatyzacja, OFE, NFZ, ZUS, itp. itd…

Ad 4.
Przeraża mnie również podział pomiędzy ludźmi, spadek zaufania, skłócenie się rodzin. Uważam, że nie potrzeba w tym miejscu mojego komentarza…

Ad 5.
Domniemywanie obywateli, iż obecność w wyborach jest “patriotycznym obowiązkiem”.
Być może wpis powinien brzmieć “wmawianie obywatelom, że ich głos jest bardzo ważny”.

A ja chciałbym zapytać się ile jest warty głos człowieka, który “głosuje na PO tylko po to by PiS nie dopchał się do władzy”?
Ile warty jest głos gówniarza, który głosuje na partie, która wydaje mu się fajna, bo wyśmiewa inne partie w programach telewizyjnych? Ile to jest warte? Chcesz dać przysługę państwu? Jeżeli nie wiesz, która partia może pomóc żyć godnie Tobie i Twoim dzieciom, po prostu NIE GŁOSUJ!
Dziwię się, że zagrożenia jakie niosą współczesne czasy i partie, dostrzega klasa, która jest uważana za “najniższą”, a nie potrafią dostrzec tego “ludzie wykształceni”.

Hello World!

Te dwa słowa są chyba pierwszymi słowami każdego, kto kiedykolwiek zaczynał zabawę z programowaniem i nie ważne czy było to C#’powe

<br />
MessageBox.Show(&quot;Hello World!&quot;);<br />

czy też inny język programowania, chyba każdy przebrnął przez te dwa słowa.