Artykuł Kompletne podstawy Elastic Searcha + integracja ES z Railsami pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Na początku chciałbym powiedzieć kilka słów na temat samych spotkań – jeśli Cię to nie interesuje i chcesz jedynie przeczytać o Elastic Searchu – po prostu przejdź do punktu „Elastic Search – podstawy”;-).
Łódź w ostatnim czasie pod względem spotkań (meetupów) technologicznych mocno się rozwija. Ostatnio spadł na mnie zaszczyt dołożyć do tego cegiełkę, ponieważ objąłem organizację jednego z nich. LRUGi koncentrują się wokół szeroko pojętej technologii Ruby on Rails, chociaż tak naprawdę na naszych spotkaniach można zdobyć wiedzę z szerokiego zakresu;-) Tu zawsze jest ciekawie i zawsze – przede wszystkim – do bólu praktycznie. Przychodząc na nasze spotkania możesz spodziewać się jednego: wyjdziesz z nich z wiedzą, którą następnego dnia będziesz mógł zastosować – albo przynajmniej spróbować. Przykład?Poza omawianym tutaj Elastic Searchem, jedna z prezentacji dotyczyła bazy danych, która może pomóc Ci w stworzeniu zsynchronizowanych aplikacji – mobilnej, oraz „przeglądarkowej”. Bywa też zabawnie – jak na ostatnim spotkaniu, gdy Maciek pokazał jak w najgorszy i najbardziej niepraktyczny, ale zarazem najbardziej pomysłowy sposób zamienić liczby arabskie na rzymskie. Wykorzystał do tego narzędzia, o jakich filozofom się nie śniło;-)
Ale LRUGi to nie tylko konkretna dawka wiedzy. Z pewnością będziesz zachwycony (lub zachwycona! Dziewczyny są tu bardzo mile widziane;-)) atmosferą. Tutaj każdy może porozmawiać z każdym, a prelegenci w przerwach służą swoją wiedzą. Dodatkowo czas na naszych spotkaniach umilają pizza i piwo – oczywiście w zdrowych ilościach;-).
Jeśli więc interesujesz się IT i chcesz pożytecznie spędzić czas w towarzystwie ludzi, którzy są do ciebie podobni – po prostu przyjdź:-) Wszystkie informacje zawsze na bieżąco znajdziesz na profilu fb LRUGa – o tutaj. Polubić warto go także z innej prostej przyczyny – publikujemy tu naprawdę przydatne informacje. Nie tylko techniczne! Ostatnio mogłeś przeczytać u nas jak przygotować się do Lightning Talków, a niebawem będzie trochę informacji ze świata Ruby on Rails. Zapraszam jeszcze raz – spotykajmy się co miesiąc!
No to możemy przejść do Elastic Searcha. Oficjalnie o ES mówi się, że to Full-text search engine. Czyli po prostu technologia, która pomaga bardzo szybko wyszukiwać i wstępnie przetwarzać ilości danych. Naprawdę duże ilości danych! Pozwól, że kilka rzeczy napiszę, które mam nadzieję jakoś pokażą czym Elastic jest.
Jak już Cię zachęciłem (zachęciłem, prawda?), to teraz z chęcią rozpiszę bardzo krótko budowę Elastic Searcha. Na samym początku warto wspomnieć, że ES zbudowany jest wokół nierelacyjnej bazy danych.
Cluster – na samej górze w hierarchii stoi klaster. On spaja wszystkie serwery. Ma swoją nazwę – domyślnie elasticsearch (jeśli odpalasz ES na macu, to domyślnie nazwą jest elasticsearch_twojanazwa).
Node – czyli po prostu serwer. Elasticsearch może działać na kilku serwerach, ale my wykorzystamy tylko jednego noda. Lokalnie odpalany jest standardowo na porcie 9200. Node też ma swoją nazwę i ciekawostka może być przysmakiem dla koneserów komiksów, bowiem domyślnie nazwa losowana jest ze zbioru imion… bohaterów komiksów Marvela
Index – kolekcja dokumentów. To w przybliżeniu odpowiednik tabeli w bazie relacyjnej.
Document – dokument jest najmniejszą jednostką Elastica. To odpowiednik rekordu w bazie relacyjnej. Ma swoje pola – takie jak imię, nazwa, wiek itd.
Skoro znasz już budowę, warto zabrać się za „samo gęste”. Jeśli jesteś na macu, zainstaluj Elastic Searcha przez
brew install elasticsearch.
Być może będziesz musiał doinstalować jakieś javowe rzeczy, ale nie powinno być z tym zasadniczo problemu. Jeśli korzystasz z Linuxa – w tym artykule wyjaśnione jest jak to załatwić;-)
Gdy już zainstalowałeś (sama instalacja trwa około 5-7 minut, możesz więc śmiało iść zaparzyć sobie kawę, albo przeczytać jakiś inny fajny artykuł na IT-Blogu Wolnego Człowieka;-) ), uruchamiamy za pomocą prostej komendy elasticsearch. W tym momencie ES zostanie włączony w trybie developerskim (będziesz mógł podglądać logi Noda) na porcie nr 9200. Jeśli chcesz podstawowe informacje na jego temat – wejdź po prostu w przeglądarce na http://localhost:9200.
Zanim przejdziemy do wyszukiwania, musimy mieć co wyszukiwać. W tym celu nauczymy się kilku podstawowych rzeczy – indexowania, pobierania, oraz usuwania danych w ES.
Indexowanie – to po prostu dodawanie dokumentu do indexu. Aby to zrobić, musimy uderzyć metodą PUT na następujący adres:
http://localhost:9200/index/typ/id
W tym celu użyjemy CURLa. Wejdź do swojego terminala/konsoli i wpisz następujące polecenie.
curl -XPUT "http://localhost:9200/employees/employee/1" -d' { "name": "Daria Woźnicka", "level": "Senior", "salary": 100000, "sex": "woman" }'
W tym momencie dodaliśmy dokument do bazy Elastica. Brawo! Pierwsza operacja zrobiona. Teraz jeszcze dwie, które są bliźniaczo podobne, więc napiszę tylko wzór na nie.
Pobieranie po id – żeby wyciągnąć z bazy jakiś element po prostu uderzamy na taki sam adres, z tą różnicą, że robimy to z metodą GET, oraz nie podajemi żadnych danych.
curl -XGET "http://localhost:9200/employees/employee/1"
Usuwanie dokumentu – to niemal identyczna operacja. Na powyższy adres uderzamy metodą DELETE
curl -XDELETE "http://localhost:9200/employees/employee/1"
No, nareszcie! Czas wziąć się za to co najfajniejsze, czyli za wyszukiwanie rzeczy, które chcemy znaleźć. Najpierw jednak zachęcam Cię do „zaaplikowania” dokumentów, które przygotowałem. To typowy zbiór pracowników jakiejś firmy, z kilkoma stopniami. Odpowiednie polecenia znajdziesz samym dole artykułu. Ja będę wyszukiwał właśnie na tym zbiorze.
Aby to zrobić, musimy wysłać zapytanie na endpoint _search, jako dane podajemy „query”, a następnie rodzaje query. My posłużymy się „query_string”. Na początek znajdźmy może… ludzi, którzy są juniorami?
curl -XPOST "http://localhost:9200/_search" -d' { "query":{ "query_string":{ "query": "junior" } } }'
Gratulacje! Spójrz na wynik, jaki dostałeś. Bardzo ważną rzeczą, o której chcę powiedzieć, to scores. Właściwie to jedna z najważniejszych rzeczy tutaj – Elasticsearch oblicza jak ważny jest dany dokument w aspekcie twojego wyszukania i do każdego wyniku podaje swoją punktację. No dobrze… ale w wyniku, któy dostaliśmy są przecież dwa dokumenty. I bynajmniej oba nie są juniorami!
Co dostaliśmy:
Możemy na przykład zbudować nowe query – tym razem powiemy Elasticowi, żeby patrzył tylko na pole „level” ; – )
curl -XPOST "http://localhost:9200/_search" -d' { "query":{ "query":{ "query_string": "junior", "fields": ["level"] } } }'
Prawda, że proste? Po wysłaniu takiego zapytania, nie mamy już problemu z otrzymaniem prawidłowej odpowiedzi;-)
Skoro już wiemy co i jak, przejdźmy do integracji ES z naszą aplikacją napisaną w technologii Ruby on Rails. To naprawdę prosta sprawa, tylko trzeba przejść kilka łatwych kroków. Będę do tego wykorzystywał aplikację, którą napisałem specjalnie dla każdego, kto chce się nauczyć Elastic Searcha od podstaw. Można ją pobrać z mojego githuba (o, tutaj). Aplikacja Companies Legerin ma dwie branche – master, oraz elasticsearch. Master jest zupełnie „goła” – ma jedynie model Company i oddpowiednio skonfigurowaną aplikację, aby można było łatwo zacząć naukę Elastica. Na drugiej branchy ES jest już zainstalowany – wersja dla leniwych;-)
Dodatkowo dołożyłm bazę danych. Aby ją wczytać, należy wejść w główny folder aplikacji i w konsoli (zwykłej, nie railsowej) utworzyć bazę danych ( bundle exec rails c ), a następnei wywołać komendę
sqlite3 db/development.sqlite3 < database.sql
Sprawa z integracją ma się prosto. Korzystamy z trzech gemów:
gem 'elasticsearch-model', git: 'https://github.com/elastic/elasticsearch-rails.git' gem 'elasticsearch-rails', git: 'https://github.com/elastic/elasticsearch-rails.git' gem 'elasticsearch-persistence', git: 'https://github.com/elastic/elasticsearch-rails.git'
W aplikacji będziemy musieli wskazać, które dane ES ma zapisywać. W tym celu idziemy do wybranego modelu – w naszym przypadku to model Company – i wpisujemy następujące rzeczy na początku klasy.
include Elasticsearch::Model include Elasticsearch::Model::Callbacks index_name "companies"
Dzięki pierwszym dwóm bibliotekom możemy korzystać z Elastic Searcha na tym modelu, oraz będzie on przeinddexowywał bazę danych (swoją) przy każdym callbacku – czyli jeśli zapiszemu, usuniemy, lub updatujemy nasz obiekt modelu Company. Na samym końcu dodajemy index_name i wskazujemy jak ma się nazywać nasz index.
Kolejna rzecz to dodanie metody as_index_json. Tutaj określamy jakie pola ma zapisywać w swojej bazie ES.
def as_indexed_json(options={}) self.as_json({ only: [:name, :description, :id, :income, :employee_amount, :address], }) end
Ostatnim krokiem jest uruchomienie konsoli railsowej i wrzucenie następujących dwóch poleceń:
Company.__elasticsearch__.create_index! Company.__elasticsearch__.import(force: true)
To zasadniczo tyle;-) Od teraz można korzystać z Elastic Searcha w aplikacji.
Od teraz możemy zbudować naszą pierwszą metodę, która będzie wyszukiwać. dokumenty z podaną przez nas frazą.
def self.search_by_query_string(query) __elasticsearch__.search( { query: { query_string: { query: query } } } ) end
Jako argument pozwalamy podać jakąś frazę, po której będziemy przeszukiwać. __elasticsearch__.search() to nic innego, jak właśnie uderzenie na endpoint _search – robiliśmy to wyżej, na sucho;-) Dalej jest już tylko to, co znasz.
Zrómy jakąś bardziej zaawansowaną metodę!
Pozwolimy użytkownikowi wyszukać dokumenty wykorzystując nazwę firmy, opis, oraz adres, ale opis będziemy chcieli wzmocnić. Dodatkowo – co ważne – chcemy, aby wyszukiwało dokumenty nawet, jeśli użytkownik NIE WPISZE PEŁNEJ NAZWY. I tu wchodzimy w magię ES – przyjrzyjmy się poniższej metodzie.
def self.search_by_part_of_phrase(query) __elasticsearch__.search( { query: { query_string: { query: "*#{query}*", fields: ['name', 'description^5', 'address'] } } } ) end
Teraz przejdź do konsoli i wywołaj te metody. Wywołajmy sobie ostatnią – Company.search_by_part_of_phrase(„Micro”).
Woow! Co za wynik! O co tu chodzi?! Spokojnie, na wyniku możemy zrobić kilka rzeczy, przede wszystkim dwie.
Company.search_by_part_of_phrase("Micro").results.to_a.
Company.search_by_part_of_phrase("Micro").records.to_a
To byłoby na tyle. Sądzę, że jeśli opanujesz (i zrozumiesz!) to co jest w tym artykule, to będzie to bardzo fajny wstęp do pracy z Elastic Searchem. Polecam eksperymenty, pracować możesz bez przeszkód na moim projekcie, który udostępniłem na githubie. Jeśli masz jakiekolwiek pytania – napisz śmiało do mnie na maila, na facebooku, lub w komentarzu, a ja postaram się pomóc:-) No i do zobaczenia na następnym LRUGu! Prezentację z LRUGa, oraz github znajdziesz w zasobach.
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
Piszę do Ciebie Prosto z Łodzi
Jeśli uważasz, że artykuł był pomocny, lub po prostu lubisz być kreatywnym w IT – polub mój Fanpage na Facebook’u. Zapraszam do zostawienia maila – zero spamu, 100% dobrych treści.
A to wspomniane dane. Po prostu je przekopiuj do swojej konsoli – dzięki nim będziesz mieć większe pole do przeszukiwania.
curl -XPUT "http://localhost:9200/employees/employee/1" -d' {"name": "Jessica Jones", "level": "Senior", "salary": 100000, "sex": "woman" }' curl -XPUT "http://localhost:9200/employees/employee/2" -d' {"name": "Paweł Kukiz", "level": "Beginer", "salary": 10, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/3" -d' {"name": "Ronald Reagan", "level": "Senior", "salary": 90000, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/4" -d' {"name": "Steve Jobs", "level": "Mid1", "salary": 15, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/5" -d' {"name": "Bill Clinton", "level": "Mid3", "salary": 4000, "sex": "woman" }' curl -XPUT "http://localhost:9200/employees/employee/6" -d' {"name": "Elon Musk", "level": "Senior", "salary": 24000, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/7" -d' {"name": "Marek Czuma", "level": "Beginer", "salary": 0, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/8" -d' {"name": "Hayley Williams", "level": "Senior", "salary": 0, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/9" -d' {"name": "Lana Del Rey", "level": "Mid3", "salary": 70000, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/10" -d' {"name": "Jennifer Lawrence", "level": "Mid1", "salary": 2000, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/11" -d' {"name": "Goerge Bush Junior", "level": "Senior", "salary": 2000, "sex": "man" }' curl -XPUT "http://localhost:9200/employees/employee/12" -d' {"name": "Jan Kowalski", "level": "Junior", "salary": 200, "sex": "man" }'
Artykuł Kompletne podstawy Elastic Searcha + integracja ES z Railsami pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł What is “better code” and how to write one? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Every good programmer wants to create a nice code. But what does it actually mean? And what exactly can you do? Let me show you my own list of “Top 5 actions to make your code better”.
First question we should ask ourselves is „Why are we programmers?”. Reasons may be varied: „I can create my own mechanisms!” or „I can change the world through my applications!”. For sure it can be also „I just want to earn money”. In any of this cases you have to create a working application. And quality of this app depends on your code. So it has to be good.
But what does it mean „good/nice/better” code? For me it should be readable, scalable and consistent. Now let me show you my favorite habits & tricks that make up my own list of „Top 5 actions to make code better”.
I assume, that you use repository. One of the biggest temptations is having only one branch. Let me show you why it is wrong. Here is the probable situation:
Three people work on some project. They have problems with conflicts on master branch everyday. „But we can be disciplined! And we can pull branch always when we start working, and…” – ok, yes, you can. But actually, I don’t believe that you will. I propose you a simple mechanism that will give you at least 3 great things:
The mechanism – as I said – is very simple. All you have to have is repository and some mate who can review your code (the best option would be a senior programmer, but it also can be someone with similar experience to yours). Now follow six easy steps:
That’s all! Only a few really simple steps, but you can gain as much as you can imagine.
Clean Code is a very popular topic in programmer’s environment. Lets face it – clean code is a huge thing. If you don’t use it yet, you can start with only a few simple rules.
This is my favorite way to improve my work. This is as simple as possible. Just after writing the method take a short break. After that, sit back down and write the same method once again, but better. It can take a while, but trust me, it will help you and your project. You can say „Oh, ok, but that Pull Requests and Code Review I wrote 5 minutes ago are good!”. Of course, but this trick is so fast and you don’t need second person to help, so just give it a try. You will be surprised with effects it will bring.
When you start work, you should define what you will be doing today. Write it down on some piece of paper or in an application of your choice and look at identified goals from time to time during the day. Try to complete the list before you leave the office. You will see few benefits:
Sometimes tasks are too heavy to finish them during one day. Don’t worry! Just split it into smaller subtasks.
Very important but also the most difficult from my „Top 5” (and absolutely valuable). When you finish your application, try to crash it. The better tested app, the grater is its quality. Generally you can use one or more of a several kinds of tests. Here is a few ways to test:
And that’s it! Implementing these five simple rules in your every day work will improve your code and make your life easier
Have fun & good luck!
My name is Marek Czuma, this is IT-Blog Wolnego Człowieka,
I write to you from Łódź
Artykuł What is “better code” and how to write one? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Kobiety w IT [pokłosie spotkania WIT Łódź] pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Kobieta informatyk jest jak świnka morska – ani świnka, ani morska.
Pewnie wielu moich czytelników zna ten niewybredny dowcip. Niezależnie od tego czy kogoś śmieszy, czy obrusza – nie sposób ukrywać, że temat kobiet w IT jest bardzo gorący i najczęściej prowadzony w 100% przez emocje – główny nurt dyskusji bardzo często wytycza to, czy rozmówca wyznaje poprawność polityczną, czy jest jej przeciwnikiem.
Na IT-Blogu Wolnego Człowieka oczywiście mówimy poprawności politycznej „good bye”, na jej miejsce zapraszając elementarną kulturę osobistą. Dziś pora zająć się tematem kobiet w IT – byłem niedawno na spotkaniu Women In Technology Łódź, a teraz zainspirowany wydarzeniem i rozmowami przeprowadzonymi w 6. Dzielnicy zapraszam do zapoznania się z tematem.
Jeśli czytasz ten tekst i zastanawiasz się czy zacząć programować – pozwól, że wprowadzę Cię w nasz świat bez zbędnej terminologii, żargonów i dziwnych zwyczajów. W razie jakichkolwiek pytań – pisz na mojego maila ([email protected])
Na początek spójrzmy na fakty (Badania Siemens Polska 2015).
Do studiów inżynierskich przygotowuje się aż 40-45% kobiet, które podchodzą do matury. Na studia inżynierskie aplikuje natomiast… jedynie 12% z nich! Pytanie jakie rodzi się automatycznie to „dlaczego?”. Oczywiście za pytaniem „Dlaczego do studiów inżynierskich podchodzi mniej kobiet” idzie drugie – „czemu kobiety, które myślą o IT bardzo często nie decydują się na to?”.
Blog Hakierka (autorka: Amanda) daje w odpowiedzi aż cztery powody:
Mimo, że w pierwszym punkcie Hakierka wymienia kilka wyrazistych, silnych postaci kobiecych ze świata IT, twierdzi, że „brak wzorców” jest problemem. Być może wzorce te nie są jeszcze aż tak znane, a być może po prostu jest ich mniej, ponieważ kobiet jest w tej branży po prostu mniej? Autorka artykułu wini popkulturę (m.in. popularny serial Silicon Valley), gdzie kobiet w IT jest za mało, a jeśli istnieją, to przedstawiane są jako te głupawe. O ile pierwszy argument – wybacz Hakierko – jest po prostu głupi, bo niby czemu ktoś miałby zniekształcać rzeczywistość w imię ideologicznych racji? – to z drugim się zgadzam. Chociaż w „Dolinie Krzemowej” większość kobiecych ról to postacie pozytywne i rozgarnięte, to pewnie w wielu innych miejscach kobiety są przedstawiane jako „te gorsze”.
Jeśli chodzi o seksizm – autorka nie podaje żadnych dogłębniejszych argumentów.
Daria Woźnicka, organizatorka WIT Łódź
W firmie w której pracuję seksizm właściwie nie istnieje. Obaw o wszechobecny seksizm nie potwierdzają również kobiety, z którymi rozmawiałem. Jedna z nich – Magda – zgodziła się wypowiedzieć dla IT-Bloga Wolnego Człowieka. Jej zdaniem kobiety są raczej mile widziane w zespole. Ludzie mówią po pracy, że „fajnie było”. Zdaje się to potwierdzać Somar, jedna z prelegentek, która mówi, że po ich kursach „dziewczyny z reguły nie są traktowane gorzej. Zdecydowanie pomaga zmysł artystyczny i poczucie estetyki – szczególnie we frontendzie”.
Wielokrotnie jednak słyszałem najpoważniejszy argument, który pokrywa się z ostatnim punktem wymienianym przez Hakierke i w środowiskach kobiecych powtarzany jest jak mantra – kobiety nie wierzą w siebie. Wspomniana wcześniej Magda mówi, że odbija się to na pensjach.
Kobiety mniej zarabiają, wynika to z niedocenienia ich przez siebie. Na rozmowie rekrutacyjnej często proponują mniejsze pieniądze
Magda
To samo mówi Somar, która bierze udział w organizacji kursów, na których kobiety są przygotowywane do IT. Twierdzi, że widać wyraźnie, że kobiety w siebie nie wierzą. Jak dodaje – zazwyczaj jest to kwestia utartych stereotypów, że mężczyźni lepiej radzą sobie z technologią.
Jeśli więc chcemy, aby w branży IT było więcej kobiet, musimy zastanowić się, w jaki sposób przede wszystkim zwiększyć poczucie własnej wartości u płci pięknej.
„Moim celem w prowadzeniu łódzkiej gałęzi Women In Technology nie jest walka z seksizmem, prawa kobiet czy o równouprawnienie. Chciałabym osiągnąć to, o czym mówię na początku każdego spotkania – sprawić, by kobiety poznały osobiście kobiety-inżynierów, przestały się bać, odważyły się zacząć karierę w branży IT, by było nas więcej – sami mężczyźni nie załatają dziury w zapotrzebowaniu na specjalistów”
Daria Woźnicka, organizatorka WIT Łódź
Osobiście twierdzę, że spotkania takie jak Women In Technology to jedyna sensowna forma wspierania kobiet w IT i „walki o ich prawa”. Nie, nie dostałem pieniędzy od tej organizacji. Żeby jednak naświetlić „jak to wygląda”, dosłownie w kilku krótkich punktach przedstawię o czym były poszczególne prezentacje.
Prelegentka jest humanistką, która od dziecka zajmowała się mnóstwem rzeczy. Jest muzykiem, pasjonatką zwierząt i detali ludzkiego organizmu. Animatorka dziecięca i lektorka języka angielskiego.
Obecnie inżynier IT i Junior Software Developer z rocznym doświadczeniem. Na prezentacji zachęcała kobiety, które są humanistkami, żeby – jeśli tylko chcą – uwierzyły w siebie i zaczęły swoją przygodę.
To bardzo istotne, biorąc pod uwagę jak dużo kobiet jest w branżach humanistycznych, oraz jak wiele z nich w siebie nie wierzy (w aspekcie IT – o czym pisałem wyżej).
Druga prelegentka to absolwentka informatyki z wydziału FTIMS na PŁ. Posiada doświadczenie w kierowaniu i współpracy z zespołami międzynarodowymi, więc zna się na rzeczy.
Na spotkaniu opowiadała o metodologii SCRUM i o tym jak profesjonalnie zarządzać zespołami – jakie są pułapki i jak robić to wszystko z głową.
W mojej ocenie bardzo ważny temat, poważnie przygotowujący słuchaczy do wejścia w branżę – w końcu IT to nie tylko „klepanie kodu”, ale codzienna zespołowa praca. Taka prezentacja daje poważną, konkretną wiedzę i pozwala wejść w branżę „mniej świeżym”.
Ostatnia prezentacja pokazywała jak wkręcić się w branżę. W przeciwieństwie do pierwszej była mniej „świadectwem”, a bardziej „tutorialem” z szeroką listą bardzo konkretnych narzędzi i praktyk.
To bardzo istotne, ponieważ konkretu nierzadko brakuje. To znaczy nawet jak ktoś wyjdzie natchniony z jednej czy drugiej konferencji i ma poczucie „Tak! Zrobię to!”, potem wraca do domu i myśli „ale jak…”.
Ta prezentacja tłumaczy „jak” i daje dużo konkretu.
Jak widać, poza niewątpliwie wspaniałą atmosferą, WIT to przede wszystkim realna pomoc – od kobiet, dla kobiet. I takie coś właśnie uważam za jedyną dobrą formę wsparcia. Zawsze jestem zwolennikiem pracy pozytywnej – a więc zamiast równać mężczyzn „w dół” (i na przykład ustawowo utrudniać im pracę w IT), kobiety którym się udało pomagają innym kobietom, aby te stawały się coraz lepsze. To właśnie ciągnie rynek w górę – brawo babeczki! Oby tak dalej.
[UWAGA! TUTAJ ZACZYNA SIĘ MOJA BARDZO SUBIEKTYWNA OPINIA]
Zarówno przed spotkaniem Women in Technology, jak i po nim rozmawiałem z wieloma kobietami z różnych miejsc branży (oraz takimi, które do branży dopiero się dobijają) i wniosek jest jeden – nie ma jednego twardego frontu kobiet. Są takie, które wykazują „odchył feministyczny”, jak i takie, która podchodzą do sprawy z dystansem. Najczęściej zadawałem dwa pytania – „Czy sądzisz, że kobiety w IT są traktowane nierówno?”, oraz „czy sądzisz, że powinniśmy dążyć do wyrównania liczby kobiet i mężczyzn w IT za wszelką cenę?”.
Do Polski weszła jakiś czas temu firma NetEnt ze Szwecji (a jakże), która postawiła sobie za cel zrównanie zatrudnienia kobiet i mężczyzn w każdym obszarze pracy. Osobiście twierdzę, że nie ma chyba głupszego pomysłu na cokolwiek. Na szczęście nie jestem w tym spojrzeniu odosobniony – kobiety z którymi rozmawiałem, nie chcą wyrównywania na siłę kobiet i mężczyzn (w znaczeniu ilościowym). Najbardziej chyba spodobała mi się reakcja Ani, którą poznałem właśnie na WIT.
Dla tych, którzy są „z zewnątrz” – drodzy Państwo, obecnie IT to tak gigantyczna branża, że pracę w różnych jej obszarach mogą znaleźć ludzie o różnych predyspozycjach. Nie ma co ukrywać, że z zasady kobiety i mężczyźni się różnią. Jeśli ktoś twierdzi inaczej – to znaczy, że jest ideologiem. Nie ma też co szufladkować ludzi, bo można kogoś skrzywdzić, lub czyjegoś potencjału nie wykorzystać, po prostu.
Ostatnie więc moje zdanie brzmi – może skończmy głupie ideologiczne dyskusje o tym która grupa płciowa się nadaje, a która nie, a może zacznijmy kierować się tym… kto się nadaje, a kto nie?
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
Piszę do Ciebie Prosto z Łodzi
Jeśli uważasz, że warto zająć się poważnymi rzeczami, a o sprawach trudnych rozmawiać dojrzale – polub mój Fanpage na Facebook’u i podaj artykuł dalej, w ten sposób będziemy uświadamiali i aktywizowali coraz więcej ludzi. Zapraszam do zostawienia maila – zero spamu, 100% dobrych treści.
Artykuł Kobiety w IT [pokłosie spotkania WIT Łódź] pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Umieszczanie logiki w aplikacji webowej – zrób to dobrze [serwisy w RoR] pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>6 dzielnica, Maro opowiada o tym gdzie trzymać logikę;-)
Istotą wszystkiego i pytaniem, które spowodowało powstanie prezentacji był dylemat – gdzie w aplikacjach webowych umieszczać logikę? No to do dzieła!
(Prezentacja w PDF została umieszczona w materiałach, czyli tutaj).
Jeśli tworzysz już aplikacje webowe, to pewnie wiesz co to jest MVC. Jeśli tak rzeczywiście jest, śmiało ruszaj do punktu następnego. Jeśli jednak nie jest to dla Ciebie jasne – pozwól, że w prostych, żołnierskich słowach wyjaśnię „z czym to się je”.
Model View Controller – wzorzec architektoniczny, służący do organizowania struktury aplikacji posiadających graficzne interfejsy użytkownika
Tyle jeśli chodzi o oficjalną definicję. Jeśli chodzi o praktykę, w skrócie MVC to sposób dzielenia kodu, który tworzysz między 3 warstwy – Widok (czyli View – plik, który w efekcie daje Ci stronę, którą możesz oglądać) z jednej strony. Przeciwny biegun zajmuje Model – czyli pewna reprezentacja tabeli w bazie danych, same „bebechy” aplikacji (np. klasa, która reprezentuje tabelę – w niej określamy relację z innymi tabelami, czy walidacje na konkretne pola). Łączy je Kontroler (controller), który dokonuje niezbędnych operacji (jak na przykład znalezienie jakiegoś obiektu i przekazanie go do widoku).
MVC (Model-View-controller) przedstawione na prostym schemacie
Po co taki podział? Daje nam bardzo wiele korzyści. Przede wszystkim porządkuje, wprowadza wyższy poziom bezpieczeństwa, oraz sprawia, że w kodzie można się połapać (kiedy wiesz czego gdzie szukać, rozwijać aplikację jest dużo prościej).
Podstawowe pytanie brzmi – w której z tych warstw (Modelu, Kontrolerze, czy Widoku) umieścić logikę?
Chciałbym, żebyś pomyślał nad rozwojem aplikacji, w której stosujesz logikę w modelu. Zasymulujmy jak może się rozwijać kod (na szczegóły implementacyjne nie zwracaj uwagi póki co).
Na początku model „z logiką” wygląda fajnie.
Model z jedną metodą wygląda dobrze
Po niedługim czasie, zaczynasz widzieć jak się rozrasta…
Model z kilkoma metodami powinien zapalić ostrzegawczą lampkę
No tak, to jest ten moment, do którego niewątpliwie musisz dojść. A jeśli tak się stanie, wtedy albo przyjdzie Ci zrobić refactor kodu, albo brnąć dalej w takie coś. Obie opcje są niezbyt przyjemne.
Tak więc – jak widzisz – trzymanie logiki całej aplikacji w modelach, to nie jest najlepszy pomysł. Na szczęście z odsieczą przychodzą…
Jeśli jesteś początkującym programistą, to musisz wiedzieć, że serwisy to najzwyklejsze w świecie klasy. W Ruby on Rails umieszczamy je w katalogu app/services (za pierwszym razem musisz katalog services stworzyć). To tam wrzucamy większość logiki, odciążając w ten sposób model, oraz kontroler. Ot co, cały sens serwisów streszczony w kilku słowach. Spójrzmy więc i zapamiętajmy…
Serwis tworzymy, jeśli chcemy stworzyć jakąś część logiki, odciążając w ten sposób model i kontroler. Serwis umieszczamy w folderze app/services.
Oczywiście otwartą sprawą zostaje to jak technicznie tworzyć serwisy. Ja zaprezentuję tutaj dwa sposoby pisania ich, nie określam jednak który jest lepszy – wszystko zależy od Ciebie, twoich upodobań i konkretnej sytuacji.
Ta wspaniała nazwa jest oczywiście mojego autorstwa i nie radzę się do niej przywiązywać.
Ten sposób tworzenia serwisów jest bardzo prosty i intuicyjny, powiedziałbym nawet że bardzo naturalny. Swoisty wzór na niego przedstawiam poniżej.
class SomethingService def initialize(param1, param2) @param1 = param1 @param2 = param2 end def method_first # Logic... end def method_second # Logic... end end
Jak widać sprawa ma się bardzo prosto, dla nieobeznanych wyjaśnienia wymaga jedynie metoda initialize. To ona będzie wywołana w momencie, w którym tworzymy obiekt klasy SomethingService (taki konstruktor w Ruby). Wewnątrz można stworzyć zmienne z „@” – wtedy dostępne będą w całej klasie, we wszystkich metodach.
Poniżej przedstawiam użycie takiego serwisu w dowolnym miejscu w kodzie.
service_object = SomethingService.new(1, "nazwa") first_thing = service_object.method_first second_thing = service_object.method_second
W pierwszej linijce stworzyłem obiekt ServiceName – wtedy automatycznie została wywołana metoda initialize. Następne linijki to wywołanie konkretnych metod.
Zwracam uwagę, że nazwa każdego z serwisów powinna się kończyć słówkiem „Service” (np. SkillService, StatsService itd), zaś nazwa pliku powinna kończyś się „_service” (np. skill_service, stats_service).
Nazywany potocznie „ten z call’em”. Różni się od pierwszego tym, że cały serwis pełni jedną funkcję. Jeśli nie jest to jeszcze jasne, spójrz na wzór na serwis z call’em.
class DoSomething def initialize(param1, param2) @param1 = param1 @param2 = param2 end def call # Some logic... end private def method_first # Logic... end def method_second # Logic... end end
Tutaj sprawa ma się tak, że tylko metoda call jest publiczna i tylko ją wywołujemy. Wszystkie inne metody są prywatne i służą jej, jeśli oczywiście zachodzi taka potrzeba. W przeciwieństwie do poprzedniego serwisu nie daje nam tak różnorakich możliwości, pozostaje za to bardziej klarowny i przejrzysty.
A oto jak wywołujemy serwis jak ten:
some_thing = DoSomething.new(1, "nazwa").call
Prawda, że proste? No bardzo proste. Tutaj również zwracam uwagę na nazewnictwo – ponieważ tutaj serwis odpowiada za jedną rzecz, nie musi kończyć się dopiskami „service” – niemniej pozostawiam tą kwestię twojej wygodzie.
Oczywiście do zrozumienia przyda się przykład. Posłużę się moją aplikacją, która wspiera usystematyzowane rozwijanie umiejętności. Sprawa jest niezwykle prosta – gdy zaczynamy pracować nad jakąś rzeczą (nazwaną w aplikacji Prefabem) – klikamy przycisk start. Kiedy kończymy – stop. W tym momencie tworzy nam się log_time. Chcemy wyciągnąć informacje o tym ile pracowaliśmy nad daną umiejętnością (prefab może realizować kilka umiejętności) w określonym okresie czasu, oraz z konkretnym wykresem dzień-czas. W efekcie będzie to wyglądało mniej więcej tak jak na screenie poniżej.
Warthog – statystyki umiejętności
W tym celu musimy wykonać cała masę operacji (wyciągnąć logtime’y, policzyć z nich czas, przyporządkować do dni, policzyć czas ogólnie, zamienić czas na konkretną datę… i kilka innych). Do tego stworzymy serwis SkillsStatsService – to będzie „serwis jako zbiór metod”. Ponieważ jednak w kontrolerze potrzebujemy dosłownie kilku danych, do zwrócenia ich użyjemy SkillsDataSummaryService – serwis ten będzie typowym serwisem „z call”. Będzie wykorzystywał SkillsStatsService.
module DirectData class SkillsStatsService def initialize(skill_id) @skill = Skill.find(skill_id) @generals = DirectData::GeneralStatsService.new(@skill.user.id) end def log_times_in_period(from, to) LogTime.where(prefab_id: @skill.prefabs.select(:id)).where('date_start >= ? AND date_start <=? ', from, to) end def log_times_in_general LogTime.where(prefab_id: @skill.prefabs.select(:id)) end # I inne metody... end
module DirectData class SkillsDataSummaryService def initialize(skill_id, from, to) @skill = Skill.find(skill_id) @from = from @to = to @skills_stats = DirectData::SkillsStatsService.new(@skill.id) @generals = DirectData::GeneralStatsService.new(@skill.user.id) end def call data = {} data[:time_jointly] = @generals.seconds_to_units(@skills_stats.time_in_period(@from, @to)) data[:time_per_day] = @skills_stats.time_in_period_per_day(@from, @to) data[:skill_name] = @skill.name data end end end
Dzięki połączeniu tych dwóch serwisów, bardzo ładnie możemy przekazać do kontrolera tylko niezbędne dane.
class SkillStatsController < ApplicationController def index if current_user.log_times.any? @skills = current_user.skills.pluck(:name) @range = params[:from].nil? ? { from: nil, to: nil} : { from: params[:from].to_date, to: params[:to].to_date } @skill = find_skill(params[:skill_name]) @data = DirectData::SkillsDataSummaryService.new(@skill.id, @range[:from], @range[:to]).call end end private def find_skill(name) skill = name.nil? ? current_user.skills.first : Skill.find_by(name: params[:skill_name].strip) skill = current_user.skills.first if skill == nil skill end end
To już wszystko, gdybyś miał (lub miała) jakiekolwiek pytania, to śmiało do mnie pisz ([email protected]). Zachęcam do budowania swoich aplikacji – możliwie kreatywnych, które rozwiązują twoje konkretne problemy.
Powodzenia!
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
Piszę do Ciebie Prosto z Łodzi
Jeśli uważasz, że artykuł był pomocny, lub po prostu lubisz być kreatywnym w IT – polub mój Fanpage na Facebook’u. Zapraszam do zostawienia maila – zero spamu, 100% dobrych treści.
Artykuł Umieszczanie logiki w aplikacji webowej – zrób to dobrze [serwisy w RoR] pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Jestem nauczycielką, ale chcę umieć programować – Kreatywne IT nie dla druidów cz 2 pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>W poprzednim artykule dowiedziałaś się, czym jest programowanie. Poznałaś również podstawowe składowe języka C# – zmienne oraz instrukcje if. Wiesz także, że na całość powinno się patrzeć jak na komendy wydane komputerowi oraz pewien układ logiczny. Po dzisiejszym artykule będziesz dysponowała naprawdę szerokim spektrum narzędzi dzięki którym będziesz mogła dać poszaleć swojej wyobraźni (w kwestii tworzenia programowanie oczywiście;-) ) i stworzyć coś zupełnie ” swojego”. Zabierajmy się do roboty!
Otwórz swój Visual Studio na projekcie który stworzyłaś poprzednio, nie ma sensu tworzyć nowego.
Zacznijmy nowe składowe od pętli. Na pierwszy ogień idzie pętla while. Zasadniczo konstrukcja jest bardzo podobna do konstrukcji if. Wygląda to następująco
while(warunek) { }
Wygląda znajomo? Pętla while to taki zapętlony if. To znaczy, że kiedy cały kod jaki piszesz wewnątrz tego bloku (pomiedzy nawiasami {}) dojdzie do końca ponownie sprawdzany jest warunek. Pętla wykonywana jest więc do momentu w którym warunek nie zostanie spełniony. Bardzo prosty przykład
int liczba = 1; While(liczba<10) { Console.writeLine(liczba); liczba = liczba + 1; }
Powyższa pętla przebiegnie 9 razy i za każdym wypisze aktualną wartość zmiennej liczba a następnie zwiększy tą wartość o 1.
Druga (i ostatnia dzisiaj) pętla dzisiaj to pętla for. Różni się od pętli while tym, że pozwala na z góry określoną liczbę przebiegów (np. Chcemy wykonać jakaś instrukcję 10 razy – wtedy używamy pętli for). Jej konstrukcja może Cię nieco odepchnąć, ale nie bój się! Już za chwilkę będziesz się nią posługiwała niczym czerwoną szminką przed balem…
Oto przykład najprostszej możliwej pętli for.
for (int i = 1; i < 10; i++) { Console.WriteLine(i); }
Efekt? Dokładnie taki sam jak przy omawianym while. Tworzymy ją w następujący sposób: w nawiasie () najpierw tworzymy zmienną (zwykle nazywamy ją i), następnie podajemy warunek, który musi być spełniony, żeby pętla działała. Na samym końcu podajemy operację która wykonuje się po każdym przejściu pętli for. Już tłumaczę dziwny zwrot „i++”. To tak zwana inkrementacja (wow! wow!). To znaczy, że zmienna i zwiększa swoją wartość o 1. Jeśli więc i=5 i zastosujemy i++, to efektem tego będzie i o wartości 6.
Płynnie przechodzimy do kolejnej składowej
Wcześniej (w poprzednim artykule) korzystaliśmy jedynie ze zmiennych globalnych (choć nie do końca, ale dla uproszczenia tak przyjmijmy) – czyli które są dostępne w całym programie. Teraz zetknęliśmy się ze zmienną i wewnątrz pętli for – jest to zmienna lokalna. Co to znaczy? To nadzwyczaj proste i intuicyjne – zmienna lokalna jest widoczna tylko tam, gdzie ją stworzysz. Jeśli więc stworzyliśmy wewnątrz pętli for zmienną int i, nie możemy jej użyć nigdzie indziej. Poniżej dałem przykład dobrego i złego użycia. W tym pierwszym – dla kompilatora zmienna i po prostu nie istnieje (jeśli spróbujesz odpalić program, Visual Studio Ci o tym powie. Poinformuje Cię również gdzie jest błąd)! Jeśli chcemy użyć zmiennej wewnątrz jakiegoś bloku (czy to if, for, while, czy cokolwiek innego), to musimy to zrobić na zmiennej globalnej lub lokalnej dla tego konkretnego bloku.
Po lewej nie możemy w if użyć zmiennej ‚i’, ponieważ nie zadeklarowaliśmy jej tam.
Zmienne są naprawdę bardzo przydatne – można w nich przechowywać różne wartości, dokonywać na nich obliczeń i operacji logicznych. Zastanów się jednak – co zrobić, gdy chcesz na przykład stworzyć listę nazw książek? Możesz wtedy utworzyć zmienną typu string. Albo dwie. Ewentualnie siedem… Tak naprawdę jednak nie możesz przewidzieć ile będziesz chciała książek stworzyć. Co więc począć w takim przypadku? Na szczęście nie zostajesz pozostawiona sama sobie. Z pomocą przychodzą bohaterskie… kolekcje!
Listy są pierwszym typem kolekcji – najbardziej popularnym. Pamiętasz jak mówiłem o tym, żebyś traktowała zmienne jak swoiste „pudełeczka” których „zawartość” to wartość zmiennej? Listy są po prostu połączonymi pudełeczkami. Sądzę że najłatwiej będzie sobie wyobrazić listę w postaci takich zabawkowych wagoników. Każdy wagonik, to jedna zmienna. Tworzymy więc najpierw listę, a potem możemy „doczepiać kolejne wagoniki” – czyli dodawać do niej kolejne zmienne. Mam nadzieję, że moja wysokich lotów grafika Ci w tym pomoże.
Lista to po prostu miejsce w którym są zebrane w porządku różne zmienne tego samego typu.
W C# zrobisz to samo co na grafice w następujący sposób.
List<string> tytuly = new List<string>(); string wladca = "Władca Pierścieni"; string wiedzmin = "Wiedźmin"; string ferdydurke = "Ferdydurke"; tytuly.Add(wladca); tytuly.Add(wiedzmin); tytuly.Add(ferdydurke); Console.WriteLine(tytuly[0]);
Najpierw utworzyliśmy listę. Ten dziwny zapis będzie obecny zawsze, ilekroć będziemy tworzyć zmienne jakichkolwiek bardziej zaawansowanych struktur (o tym więcej możesz przeczytać w moim artykule o programowaniu obiektowym). Następnie stworzyliśmy kolejne zmienne, które są kolejnymi tytułami książek (mam nadzieje, że załapałaś, że ostatni tytuł to żart w aspekcie moich ulubionych?).
Następna linijka pokazuje potęgę list. Tym banalnie prostym poleceniem ( .Add(zmienna) ) „doczepiliśmy wagonik” na koniec. Żeby wyświetlić któryś element listy wystarczy napisać tytuly[numerWagonika]. Musisz pamiętać, że wszelkie kolekcje w C# (i wielu innych językach) są numerowane od 0.
Zostawmy już w spokoju listy. Drugą (i ostatnią) kolekcją którą poznasz są słowniki. Nazywają się tak, ponieważ… działają jak słowniki. Aby wyszukać element w liście musieliśmy podać jego miejsce (id). Słowniki są kolekcjami, które działają na zasadzie klucz-wartość. Tym razem nie będę pokazywał Ci żadnej grafiki – wystarczy zwykła tabelka ;- )
Dictionary<string, int> wzrosty Słownik wzrosty z kluczem typu string i wartością typu int |
|
Klucz Zmiennej (typ string) | Wartość Zmiennej (typ int) |
„marek” | 185 |
„genowefa” | 165 |
„hayley” | 157 |
Twórcy C# przygotowali to dla nas oczywiście w elegancki sposób obsługę słownika, co też za chwilkę wykorzystamy.
Dictionary<string, int> wzrosty = new Dictionary<string, int>(); wzrosty.Add("marek", 185); wzrosty.Add("genowefa", 165); wzrosty.Add("hayley", 157); Console.WriteLine(wzrosty["hayley"]);
Gdy deklarujemy nasz słownik (pierwsza linijka) w nawiasie trójkątnym najpierw podajemy typ klucza, potem typ wartości (dla przypomnienia – string to typ który pozwala pisać tekst, int natomiast to zmienne całkowite). To co musimy pamiętać to fakt, że w jednym słowniku NIE MOŻE powtórzyć się element z tym samym kluczem. Proste? Proste.
Poznałaś kilka kolejnych elementów C# (które jednak są wspólne dla większości języków programowania), więc czas coś stworzyć – przecież po to tu siedzisz prawda? Jeśli jednak któregoś elementu zupełnie nie rozumiesz – spróbuj popisać przykładowy kod, poeksperymentuj. Jeśli dalej nie będziesz zupełnie rozumiała o co chodzi – nie wahaj się ani sekundy dłużej i pisz do mnie maila. Z przyjemnością wytłumaczę Ci w jedyny, niepowtarzalny, indywidualny dla Ciebie sposób! Jeśli jednak rozumiesz „trzy po trzy” – to super! To znaczy, że śmiało możesz iść dalej. Idźmy więc dalej, stwórzmy coś fajnego, tylko w praktyce można w pełni zrozumieć to co się poznawało.
Dzisiaj napiszemy… prosty program do nauki słówek w języku angielskim.
Nasz program będzie miał dwie części – w jednej będziemy wypełniali bazę słówkami, zaś w drugiej będziemy mogli się uczyć. Zacznijmy od przygotowania tego, co nam będzie potrzebne.
Tak wygląda cały kod. Poniżej jego omówienie. Oczywiście całość w funkcji main()
static void Main(string[] args) { bool kontynuujProgram = true; Dictionary<string, string> slowka = new Dictionary<string, string>(); while(kontynuujProgram) { string coDalej = ""; Console.WriteLine("Witaj! Jeśli chcesz się się uczyć, wpisz 'uczenie', jeśli chcesz dodać słówko - 'uzupelnianie': "); coDalej = Console.ReadLine(); if(coDalej == "uzupelnianie") { string angielski = ""; string polski = ""; Console.WriteLine("Wpisz słowo po polsku: "); polski = Console.ReadLine(); Console.WriteLine("Wpisz słowo po angielsku: "); angielski = Console.ReadLine(); slowka.Add(polski, angielski); }else { int liczbaSlowek = slowka.Count; for(int i=0; i< liczbaSlowek; i++) { string ang = slowka.ElementAt(i).Value; string pl = slowka.ElementAt(i).Key; string angielskiUzytkownika; Console.WriteLine(pl + " to po angielsku: "); angielskiUzytkownika = Console.ReadLine(); if(angielskiUzytkownika == ang) { Console.WriteLine("Bardzo dobrze!"); }else { Console.WriteLine("Źle. Naprawdę to " + ang); } } } } }
Na początku – po stworzeniu słownika o nazwie ‘slowka’ – stworzyliśmy pętlę while. Pozwoli ona nie kończyć programu. Wewnątrz dajemy użytkownikowi wybrać którą część chce odwiedzić (czy chce dodać słówko czy chce się pouczyć). Jeśli chce dodać słówko – pozwalamy wpisać po polsku oraz angielsku za każdym razem zapisując do odpowiednich zmiennych. Na końcu dodajemy nowy element do słownika właśnie dzięki wykorzystaniu tychże zmiennych.
W drugiej części dajemy się uczyć. Dzięki wywołaniu ‘count’ na słowniku wiemy ile ma elementów i tyle razy możemy przejechać po pętli for. Wewnątrz pętli najpierw stworzymy dwie zmienne typu string (ang i pl) i przypiszemy im odpowiednie dane (klucz i wartość) z elementu naszego słownika. Stworzymy zawczasu jeszcze jedną zmienną (angUzytkownika) do której przypiszemy odpowiedź ucznia; – ). Gdy już ją mamy – dzięki konstrukcji if..else możemy napisać użytkownikowi czy dobrze odpowiedział. Dzięki pętli for program spyta nas o kolejne słówka aż do skończenia słownika.
Tak powinien wyglądać program po skompilowaniu
To koniec! Zdaję sobie sprawę z tego, że powyżej było dużo nowości. Jestem przekonany jednak, że dasz sobie radę. Jeśli uznasz, że do tego dania sobie rady potrzebujesz pewnych wskazówek, napisz do mnie śmiało na [email protected].
Szczerze powiem, że jestem pod dużym wrażeniem, że udało Ci się tutaj dotrzeć. Znaczy to ni mniej ni więcej to, że jesteś osobą ciekawą świata, która oczekuje od życia ciut więcej niż przeciętnie. Jeśli tak faktycznie jest, zachęcam Cię do polubienia mojego profilu na facebooku – razem będziemy mogli stworzyć grupę osób które wzajemnie pomagają sobie poszerzać horyzonty (nie tylko w Kreatywnym IT! Przejrzyj bloga a dowiesz się np. jak się prowadzi w Łodzi firmę kreatywną;-) ). Możesz również dopisać się do mojego newslettera – obiecuję żadnych spamów. Jedynie raz w tygodniu (zwykle w niedziele wieczorem) dostaniesz maila z podsumowaniem tego co zrobiłem przez ostatni tydzień.
Jeszcze raz gratuluję i powodzenia w zdobywaniu nowych lądów w życiu!
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
piszę do Ciebie prosto z Łodzi
Artykuł Jestem nauczycielką, ale chcę umieć programować – Kreatywne IT nie dla druidów cz 2 pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Jestem nauczycielką, ale chcę umieć programować – Kreatywne IT nie dla druidów cz 1 pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Na początek ustalmy sobie jeszcze 3 proste zasady tego artykułu:
No to do dzieła!
Suupeeer, zabieramy się za programowanie! Ale tak właściwie, to co to w ogóle znaczy? Będziemy zwierać kabelki? Albo ustawiać w odpowiednim ciągu zera i jedynki? Mam nadzieję, że przygotowałaś już sobie piwnicę i założyłaś sweter lub bluzę… Stop! Programowanie nie przypomina już tego, co w latach 80′. Zaufaj mi – żeby zacząć, nie musisz mieć żadnej specjalistycznej wiedzy. Cóż to takiego więc, to programowanie?
Naprawdę, możesz programować zachowując kontakt ze znajomymi i resztą społeczeństwa. Serio!
Programowanie to – mówiąc krótko – napisanie komputerowi co ma robić. W tym celu potrzebujemy jakiś język programowania i kompilator. Język programowania wydaje mi się dość intuicyjny, jak normalne języki którymi się posługujemy. To po prostu zbiór reguł i zasad dzięki którym możemy z komputerem pogadać. W naszym przypadku to będzie C# (słownie –si szarp. Nie ce krzyżyk ani ce krateczka!). A kompilator? No właśnie. Zdanie wcześniej nieco skłamałem (ale nie bardzo!). Język programowania to zbiór reguł i instrukcji które wykorzystujemy żeby napisać program. A kompilator, to taki mechanizm który zamienia to co napisaliśmy na język który rozumie komputer (czyli na ciąg zer i jedynek).
My użyjemy (jak już wyżej wspomniałem) języka C# który został stworzony przez Microsoft. Użyjemy go, ponieważ jest jest wygodny w szybkim pisaniu i nie trzeba się przejmować całą masą zbędnych problemów. A co z kompilatorem? Tutaj użyjemy nie tylko kompilatora, ale i całego IDE (Integrated Development Environment) – czyli całego środowiska, którego składową jest kompilator. Zrobimy tak z dwóch powodów. Po pierwsze – korzysta się z tego w bardzo łatwy sposób (kompiluje się za kliknięciem jednego przycisku, poza tym podpowiada składnię więc nie trzeba wielu rzeczy pamiętać). Po drugie – to profesjonalne środowisko. Nasze IDE nazywa się Microsoft Visual Studio i można pobrać tutaj.
Gdy zainstalujesz możesz się nieco zdziwić ogromem wszystkiego, ale nie przerażaj się – przywykniesz, obiecuję. A może i się zaprzyjaźnisz z VS. Dam krótką instrukcję jak rozpocząć pierwszy projekt. Po odpaleniu możesz spotkać podobny widok jak ten poniżej. Zrób więc tak jak ja. Kliknij „New Project”, następnie Templates-> Visual C# i Console Application. Na dole wybierz ścieżkę docelową w której ma utworzyć projekt oraz jego nazwę (ja nazwałem ją druidzkim kalkulatorem, ale nazwij jak chcesz – całość ma sprawiać Ci przyjemność;-) ).
Visual Studio krok 1 – utwórz projekt
Wybierz odpowiednie opcje do projektu.
Gdy klikniesz „Ok” zobaczysz gotowy swój projekt z pierwszym kawałkiem kodu. Na ten moment możesz śmiało zostawić to co się stworzyło w spokoju i wrócić do artykułu.
Wspaniale! Masz już na komputerze zainstalowane środowisko programistyczne, wiesz czym jest kompilator oraz IDE oraz ogólnie czym jest programowanie. Czas zdobyć przysiąść do tego czym jest programowanie.
Na początku programowanie było wystukiwaniem zer i jedynek. Z czasem ludzie zaczęli tworzyć języki programowania, aż doszli do tego co jest teraz, jednak musisz pamiętać, że „pod spodem” końcem końców wszystko i tak zamienia się w zera i jedynki. Mało romantyczne? Być może. Na szczęście nie musisz teraz o tym myśleć. I nie będziesz musiała póki nie wejdziesz na naprawdę konkretny poziom. Chcę jednak, żebyś wypracowała sobie pewne odpowiednie spojrzenie na programowanie zanim siądziemy do konkretów.
Pamiętasz lekcje logiki na matematyce w liceum? Jeśli Ci się podobały, lub chociaż czujesz do nich mniejszą odrazę niż do reszty Królowej Nauk, to mam dobrą wiadomość – programowanie to właśnie logika. Oczywiście nie musisz teraz przypominać sobie tych wszystkich przyprawiających o zawrót głowy zadań „na 6” w których trzeba było dociec jaki jest efekt zdania logicznego (jak na załączonym obrazku).
Zdania logiczne się przydają, ale w suchej formie bywają mało atrakcyjne
Przypomnij sobie zdanie, które musiało paść z twoich ust – szczególnie w momencie w którym musiałaś robić zadania logiczne zamiast iść z koleżankami na imprezę – „Matkoo a po co mi to w ogóle w życiu? Co ja będę zdania logiczne na randce rozwiązywać?”. Nie wiem co robisz na swoich randkach, ale mogę Cię zapewnić, że programowanie to właśnie to miejsce, w którym zdanie logiczne się przydają. Co więcej! Tutaj dostają bardzo fajnej, praktycznej otoczki która sprawia że nie są one uciążliwe ani nudne.
Tak więc, podsumowując – chciałbym żebyś zawsze patrzyła na programowanie jako na zestaw instrukcji które wydajesz komputerowi. To co on zrobi zależy od tego co powiesz mu aby robił. Jest w środowisku programistów takie powiedzenie które powinnaś przyswoić sobie na trudne momenty – „Program robi to co napisałaś żeby robił, a nie to co chciałaś żeby robił”.
Po tym przydługim wstępie możemy wreszcie zacząć się uczyć programować. Przedstawię Ci poniżej kilka składowych, mechanizmów które pozwolą Ci napisać pierwszy program.
Podstawową składową każdego języka programowania są zmienne. To takie „pudełeczka”, w które możemy wrzucić jakieś dane które chcemy wykorzystać później. Na przykład damy użytkownikowi możliwość wpisania imienia. Żeby potem to imię wykorzystać wrzucamy do „pudełeczka” nazwanego na przykład „imieUzytkownika”. Gdy zechcemy je użyć, po prostu wywołujemy naszą zmieną i… już! Mamy imię użytkownika! Czy to nie proste? Oczywiście że tak.
Każda zmienna może mieć swój typ. Rozróżniamy je, ponieważ kompilator musi wiedzieć czy to co przekazujemy to liczba, napis, wartość logiczna czy coś jeszcze. Poniżej tabelka z kilkoma najbardziej podstawowymi typami zmiennych.
Typ | Rodzaj | Przykład |
int | Liczba całkowita | 5 |
float | Liczba zmiennoprzecinkowa | 5.44 |
string | Napis | „No hej, jestem stringiem” |
bool | Wartość logiczna | Zawsze jedna z dwóch: true lub false |
Żeby stworzyć w C# zmienną musimy napisać kawałek kodu według następującego wzoru:
[typ] [nazwa] = [wartość];
Przykłady:
string imie = „Kasia”;
int wiek = 25;
float wzrost = 1.65;
bool jestKobieta = true;
Cóż, jak widać nie ma tu zbyt dużej filozofii. Pamiętaj proszę zawsze, żeby po zakończeniu czegokolwiek postawić średnik. Jego brak jest najczęstszym problemem początkujących programistów.
Napiszmy pierwszy kod! Z pewnością zaciekawiło Cię to co zobaczyłaś zaraz po otwarciu strony. Pozwól że zbyt wiele teraz nie będę tłumaczył (po przejściu całego 3-artykułowego kursu będziesz wiedziała i rozumiała zdecydowanie więcej). Na ten moment jedna ważne jest, że wszystko co będziesz pisała powinno mieć miejsce wewnątrz main(), między klamerką otwierającą a domykającą. Zajmijmy się teraz bardzo prostym kodem, który będzie twoim pierwszym. Poniżej przedstawiam całość, ale postaraj się nie kopiować, a choćby przepisywać. Zobaczysz w ten sposób jak funkcjonuje Visual Studio i zapamiętasz lepiej składnię C#.
static void Main(string[] args) { string powitanie = "No czesc, jestem twoja pierwsza aplikacja"; Console.WriteLine(powitanie); Console.ReadLine(); }
Już tłumaczę. Pierwsza linijka (string powitanie) to stworzenie zmiennej o nazwie powitanie i wartości „no cześć, (blablabla)”. Dzięki temu manewrowi zapamiętaliśmy w pamięci komputera (pudełeczko, pamiętasz?) pewien tekst. Następna linijka to wyrzucenie na ekran powitania. Nie będę tutaj tłumaczył dokładnie czym jest Console ani WriteLine ponieważ nie jest to miejsce na to. Teraz przyjmij ze to pozwala na wyrzucenie na ekran tekstu. Ostatnia linijka to – przyznam – dość prymitywny wybieg mający na celu zatrzymanie programu do momentu w którym użytkownik (czyli Ty) nie postanowi kliknąć klawisza „enter”. W przeciwnym przypadku program natychmiastowo skończyłby pracę nie pokazując nam się dłużej niż ułamek sekundy.
Świetnie, twoje pierwsze starcie z kodem zaliczone! Pora zrobić coś bardziej zaawansowanego. Instrukcje warunkowe if służą do… stawiania warunków. Zasadniczo to banalna konstrukcja na zasadzie jeśli [cośtam] to [zrób coś]. Przykład:
if (jakasZmienna == 10) { Console.WriteLine("jakas zmienna jest równa dziesiec"); }
Prawda że proste? To typowa logika jaką znasz z lekcji matematyki z liceum. Wewnątrz nawiasu if() musi być zawsze wartość logiczna, czyli taka której efektem jest true lub false. Taką wartość logiczną można uzyskać właśnie dzięki operator logiczny „==” (Operatory logiczne nieco niżej).
Istnieje jeszcze if…else. To identyczna, ale nieco rozbudowana konstrukcja, która uzupełnia zwykłego if’a o „w przeciwnym wypadku”. Zróbmy to samo raz jeszcze, ale uwzględnijmy inne wypadki.
if (jakasZmienna == 10) { Console.WriteLine("jakaś zmienna jest równa dziesiec"); }else{ Console.WriteLine("Jakaś zmienna nie jest równa dziesiec") }
Prawda że proste? Możemy jeszcze zbudować konstrukcję „else if” i dać po niej nowy warunek, na przykład w taki sposób:
if (jakasZmienna == 10) { Console.WriteLine("jakaś zmienna jest równa dziesiec"); }else if(jakasZmienna == 20){ Console.WriteLine("Jakaś zmienna jest równa dwadziescia") }else if(jakasZmienna == 30){ Console.WriteLine("Jakaś zmienna jest równa trzydziesci") }else{ Console.WriteLine("Jakaś zmienna nie jest równa ani dziesiec, ani swadziescia, ani trzydziesci") }
Ta banalnie prosta instrukcja jest niezwykłym (często nadużywanym) narzędziem! Tak więc, skoro poznałaś już to co trzeba, napiszmy program z prawdziwego zdarzenia – z interakcją z użytkownikiem, wykorzystujący instrukcje warunkowe.
Zróbmy coś nietypowego jak na tego typu tutoriale. Nie będzimy pisać żadnego prostego kalkulatora (to pod koniec, w trzecim artykule), ale załóżmy sobie sytuację z życia wziętą. Zapewne masz tak czasem, że piszą do ciebie różne osoby które chcą Cię poznać. Zapewne bywa tak, że piszą gdy jesteś zajęta. Napiszmy przykładowy program który mógłby za Ciebie rozwiązać nieco problemów, który byłby swoistym filtrem i dopuszczał tylko te osoby, które faktycznie mogłabyś chcieć poznać.
Co będzie nam potrzebne?
static void Main(string[] args) { int wiek; int minimumWiekowe = 20; int maximumWiekowe = 25; string email = "[email protected]"; string powitanie = "Witaj w moim programie! Podaj swój wiek"; string odpowiedzPozytywna = "Swietnie! Takiej osoby szukalam, napisz do mnie na maila: " + email; string odpowiedzNegatywna = "Niestety, szukam osoby w nieco innym wieku, powodzenia w dalszym szukaniu!"; Console.WriteLine(powitanie); wiek = Convert.ToInt32(Console.ReadLine()); if((wiek >= minimumWiekowe) && (wiek <= maximumWiekowe)) { Console.WriteLine(odpowiedzPozytywna); }else{ Console.WriteLine(odpowiedzNegatywna); } Console.ReadLine(); }
Chyba jedyne co należy wytłumaczyć to warunek if. Wygląda groźnie, ale jest banalny. Najtrudniejsze wyrażenie tam – „&&” – to zwyczajne logiczne „i”. Tak więc jeśli wiek jest większy lub równy minimum wiekowe i jest mniejszy bądź równy maximum wiekowe, to zrób to co napisane dalej.
Jeśli chodzi o zwrot „Convert” – służy on do zamiany jednego typu zmiennej na drugi. Ponieważ WriteLine sprawia że dostajemy zmienną typu string (a my potrzebujemy zmiennej typu int), musimy zrobić Convert.ToInt32(). Po takim manewrze string staje się intem. Jeśli zrozumiałaś o co tu chodzi to świetnie! Jeśli jednak akurat ta część jeszcze do Ciebie nie dociera, nie ma problemu, obiecuję że za parę artykułów będzie dużo łatwiej.
Tym oto prostym sposobem napisałaś program, który pozwala przesiać według twoich preferencji potencjalnych rozmówców. Proste? Do następnego artykułu mam dla Ciebie zadanie – rozbuduj swoją aplikację o nowe kryteria. Daj podać mu wzrost, zainteresowania lub imię i postaraj się dzięki konstrukcjom if..else if..else wybrać najlepszego kandydata do rozmowy.
To tyle! Dziękuję Ci, że udało Ci się dojść do końca artykułu. To naprawdę niesamowite że spróbowałaś wejść w świat programowania od strony hobbystycznej. Mam nadzieję, że się nie nudziłaś. W następnym artykule poznasz kilka kolejnych składowych które dadzą właściwie nieograniczone możliwości tobie jako programistce. Zachęcam do zapisania się do newslettera (poniżej) żebyś była na bieżąco z moimi artykułami (w ramach Programowania Nie Dla Druidów jeszcze 2!), a na koniec przedstawiam tabelkę – moim subiektywnym zdaniem – najważniejszych operatorów logicznych które możesz stosować m.in. w instrukcji if. Do zobaczenia niedługo!
Operator | Znaczenie |
== | Operator porównania (czy jedna wartość równa jest drugiej?) |
>= | Większe lub równe |
<= | Mniejsze lub równe |
!= | Różne |
&& | i (warunek && warunek – oba warunki muszą być true) |
|| | Lub (warunek || warunek – jeden z nich musi być true) |
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
piszę do Ciebie prosto z Łodzi
Artykuł Jestem nauczycielką, ale chcę umieć programować – Kreatywne IT nie dla druidów cz 1 pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł C#, .NET, OOP… czyli jak programować ładnie i zgrabnie? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>[Cykl – Baza]
Cały czas pozostajemy w środowisku Visual Studio. Tym razem jednak rezygnujemy z C++ i przesiadamy się na C# – obiektowy język stworzony przez Microsoft. Nie musisz się jednak bać tej zmiany – korzystając z niego cały czas pozostajemy w rodzinie języków C, jestem przekonany że bez problemu go zrozumiesz i już za chwilę zaczniesz w pełni wykorzystywać możliwości jakie Ci daje ;). Korzystanie z C# to jednak nie koniec zmian – nieśmiało rozpoczniemy dzisiaj przygodę z .NET – technologią stworzoną przez Microsoft. Nieśmiało ponieważ dziś wykorzystamy zaledwie kilka fragmentów z przepastnych zbiorów naszych kolegów zza oceanu. Nie musisz się jednak martwić – już za niedługo (wraz z rozpoczęciem nowego cyklu!) odważniej wejdziemy w to co oferują nam Amerykanie i będziemy czerpać do woli. Zróbmy jednak krótki wstęp do C#. Zasadniczo jest to język bliźniaczo podobny do znanego Ci już doskonale C++. Jest jednak kilka istotnych zmian. Wymieńmy te elementy języka które nas będą dzisiaj interesować.
Koniec z niskopoziomowym zarządzaniem pamięcią, wskaźniki w C#… nie istnieją! A konkretnie istnieją w trybie unsafe, jednak nie są tak naprawdę niezbędne dla zaawansowanego programowania w tym języku. To dla nas dobra wiadomość, oczywiście o ile chcemy się skupić na stworzeniu złożonych aplikacji bez zastanawiania jak je niskopoziomowo optymalizować. Odpada nam jednak element sprawiający nierzadko bardzo duże problemy
Pętla foreach jest – jak można się domyśleć – rozwinięciem pętli for. Dzięki niej możemy w bardzo łatwy sposób przejść się po kolekcji (np. tablicy) nawet nie znając jej długości.
int[] array = new int[10]; foreach (int element in array) { Console.WriteLine(element); }
Na początku stworzyłem tablicę (tak się to robi w C#;) ) a potem wyświetliłem na ekranie wszystkie jej elementy za pomocą pętli foreach. Co ważne! Pętla ta jest read-only, służy tylko do odczytu i nie można napisać np. „element = 5”. W powyższym przykładzie pominąłem zupełnie wypełnienie tablicy (można zrobić to używając np. tradycyjnej pętli for w klasycznym wydaniu – nie różni się ona niczym od znanej z C++).
Pamiętasz czym są getery i setery? No! To teraz śmiało możesz zapomnieć… No dobrze, troszkę przesadziłem, jednak C# wprowadza zupełnie nowy element (poza polami i metodami) nazwany properties (właściwości). W skrócie jest to coś między metodą a polem, co w zręczny sposób zastępuje getery i setery. Co prawda zastosowań ma mnóstwo, jednak o tym przekonasz się w następnych artykułach. Na ten moment spójrzmy na następujący kod.
class Person { private string _name; public string Name { get{ return _name; } set{ _name = value; } } }
I następnie ten – napisany w funkcji main():
Person Janek = new Person(); Janek.Name = "Janek"; Console.WriteLine(Janek.Name);
Najpierw stworzyliśmy prywatną zmienną _name, a następnie właściwość Name. W bloku właściwości ustalamy zasady działania get oraz set. W tym przypadku daliśmy prostą, bez żadnych obostrzeń (moglibyśmy np. wewnątrz bloku get wstawić jakiegoś if’a i dzięki niemu dodać pewne warunki które obowiązywałyby przy próbie odczytu). Następnie (w main) widzimy jak z właściwości skorzystać. Tak! Jest to najprostsza na świecie operacja i wygląda dokładnie tak, jakbyśmy używali zwykłego pola. Oczywiście nie możemy zrobić tego z _name, ponieważ to pole prywatne. Właściwości łączą więc możliwości obostrzeń znane z metod Get() i Set() oraz prostotę użycia zwykłych pól. Fajne? Fajne.
To jednak nie koniec! W powyższym przypadku mamy bardzo prostą, zupełnie niezłożoną problematykę. W takiej sytuacji możemy jeszcze bardziej uprościć kod i wyglądałby on następująco.
class Person { public string Name{ get; set; } }
W tym przypadku nie musimy nawet tworzyć prywatnego pola – właściwość jest samowystarczalna! Jeśli np. nie chcielibyśmy dawać możliwości odczytu, dodajemy przed ‘get’ słówko ‘private’. Powodzenia w zabawie z właściwościami!
W poprzednim artykule stworzyliśmy prostą aplikację ze zbiorem produktów sklepowych i możliwościami prostych operacji na nich (np. dodawanie nowych produktów, obliczanie ogólnej ceny wszystkich itd.). Teraz również zajmiemy się stworzeniem naszego „Shop Base”, jednak wykorzystamy zdobytą przed chwilą wiedzę z zakresu C# oraz bardzo podstawowe dobrodziejstwa technologii .NET. Napiszmy tu jeszcze raz ogólną strukturę aplikacji (nieco zmienioną wobec poprzedniego artykułu).
Właściwości:
Metody:
Pola:
Właściwości:
Metody:
Zabierzmy się więc za implementację! Jestem przekonany że gdy po wszystkim spojrzysz na swoją aplikację z zeszłego tygodnia i obecną nie będziesz mógł uwierzyć. Najpierw zacznijmy od stworzenie klasy Product.
class Product { //Właściwości public int Id{ get; set; } public string Name{ get; private set; } public float Price{ get; set; } //Metody public Product(int _id, string _name, float _price) { Id = _id; Name = _name; Price = _price; } public Product() { } public void WriteProduct() { Console.WriteLine("Produkt id: " + Id + ", nazwa: " + Name + ", cena: " + Price + "\n"); } }
Tak, zgadza się – to cała klasa Product! Szybko licząc mamy… ponad 70 linijek kodu mniej! Na początku tworzymy stosowne właściwości (Ponieważ nie chcemy by produktowi zmieniać później nazwę, ‘set’ ustawiliśmy jako prywatne), następnie przechodzimy do metod. Mamy dwa konstruktory, z których jeden nie ustawia żadnych właściwości i na końcu prościutką metodę WriteProduct która wypisuje na konsole dane odnośnie produktu. Prawda że proste?
Przejdźmy do nieco bardziej zaawansowanej struktury, jaką jest klasa Base
class Base { //Pola protected List<Product> products; protected int id = 0; //Właściwości public string Name{ get; set; } //Metody: public Base(string _name) { products = new List<Product>(); Name = _name; } public void AddProduct(Product _product) { id++; Product tmpProd = new Product(); tmpProd = _product; tmpProd.Id = id; products.Add(tmpProd); } public void RemoveProduct(int _id) { foreach(Product element in products) { if (element.Id == _id) { products.Remove(element); } } } public void WriteProducts() { Console.WriteLine("Produkty w bazie " + Name + ": "); foreach(Product element in products) { element.WriteProduct(); } } public float CalculateProducts() { float tmpPrice = 0; foreach(Product element in products) { tmpPrice += element.Price; } return tmpPrice; } public Product FindProduct(int _id) { foreach(Product element in products) { if (element.Id == _id) { return element; } } return new Product(); } }
Tu znów mamy oszczędność kodu (choć nie tak dużą jak przy poprzedniej klasie). Więcej jednak miejsca muszę poświęcić na wyjaśnienie. Na początku tworzymy dwa pola zastrzeżone (pamiętasz czym się różni ‘protected’ od ‘private’? Jeśli nie, zachęcam do zerknięcia w poprzedni artykuł ). Najgroźniej wyglądającym jest „products”, które jest Listą. Nie bój się, już wyjaśniam o co chodzi. Listy to kolekcje, pewne zaawansowane zbiory danych które dostajemy w ramach .NET. Spytasz pewnie „Po co? Przecież mamy tablice!”. Zgadza się, jednak listy – w przeciwieństwie do klasycznych tablic – są dynamiczne i nie musisz z góry określać ile mają „slotów”. Po drugie, mają zaimplementowane kilka bardzo sprytnych metod których użycie bardzo ułatwia korzystanie z nich. Jak zobaczysz w kolejnych metodach, dodawanie czy usuwanie elementów listy jest o niebo prostsze niż usunięcie z tablicy. Mimo że mam nadzieję, że ten krótki opis wystarczy Ci w zrozumieniu kodu zachęcam do zgłębienia wiedzy o listach i innych kolekcjach generycznych – również ze względu na pewien brak precyzji którym niestety muszę się posługiwać w tym artykule. Przejdźmy zatem do wspomnianych metod. Poza konstruktorem pierwszą z nich jest AddProduct(), która dodaje do listy produkty. Jak widzisz nie trzeba „bawić” się z wymyślaniem dziwnych kombinacji – wystarczy dać nazwę listy a potem po kropce „Add” i w parametrze obiekt który chcemy wstawić. Czy nie jest to prostsze? W RemoveProduct() używamy pętli foreach którą opisywałem wyżej i metody Remove() którą daje nam lista. Jako że reszta metod budowana jest na podobnej zasadzie, przejdę do omówienia ostatniej. W FindProduct() znów używamy pętli foreach i zwracamy znaleziony obiekt. No tak… a co jeśli nie uda nam się znaleźć obiektu? W takiej sytuacji pętla zakończy swoje działanie (return kończy pętlę i resztę działania metody) i dojdzie do drugiego „return” zwracając tym samym zupełnie nowy obiekt (bez właściwości).
Finalny stan programu
Brawo! Stworzyłeś prostą aplikację do zarządzania produktami w elegancki sposób, korzystając z nowoczesnej technologii. Ze względu na brak miejsca nie zamieszczam tu implementacji funkcji main(). Możesz jednak zajrzeć do materiałów i pobrać cały kod programu. Jeśli masz jakieś pytania lub uwagi jestem cały czas do dyspozycji pod mailem. Pod koniec wypada mi przestrzec przed niezbyt precyzyjnymi stwierdzeniami które padły w tym artykule. Moim zadaniem jest zachęcić Cię do pogłębiania wiedzy. Robię to z przyjemnością, jednak ze względu na specyficzny charakter artykułu czasem to co piszę jest nieprecyzyjne a implementacja niezbyt elegancka. Zwracam na to twoją uwagę i nakłaniam do poszerzania wiedzy i umiejętności poprzez czytanie tutoriali, kodu innych programistów oraz – co najważniejsze – pisanie swoich aplikacji. Jeśli chciałbyś się pochwalić czymś co napisałeś – wyślij mi to na maila. Ja sprawdzę i odpiszę, a jeśli będzie naprawdę dobre – napiszę o tym na swoim blogu;)
Tym oto artykułem kończymy cykl nazwany „Cyklem-Bazą”. Poznałeś w nim podstawy programowania obiektowego i liznąłeś C# wraz z technologią .NET. Powinieneś jednak potraktować to jako rozgrzewkę przed czymś naprawdę ekscytującym! Już niedługo po czubek głowy zanurzysz się w .NET i zaczniesz tworzyć aplikację użytkową! Czy to znaczy że wszystko co napisaliśmy do tej pory będzie Bezużyteczne? Absolutnie! Cały czas będziemy siedzieć w tej samej tematyce, pomyślimy jednak jak ją rozbudować i nadać temu ładny wygląd. Do zobaczenia za tydzień!
Jeśli dotarłeś aż tutaj, to znaczy że jesteś człowiekiem innym niż większość. To znaczy, że nie wystarczają Ci skrótowce, że prawdopodobnie wymagasz od siebie nieco więcej niż przeciętnie. Pozostańmy zatem w kontakcie – zapisz się na Newsletter Wolnego Człowieka i pomóż mi tworzyć coraz lepsze treści! Jeśli zdecydujesz się wpisać – obiecuję zero spamu. Raz w tygodniu będziesz dostawał maila z podsumowaniem tego co zrobiłem na blogu.
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
piszę do Ciebie prosto z Łodzi
Artykuł C#, .NET, OOP… czyli jak programować ładnie i zgrabnie? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Programowanie Obiektowe – czyli jak programować, aby skutecznie tworzyć realny świat? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Zacznijmy od podstawowej rzeczy – co to w ogóle jest OOP i po co je stosujemy? Ujmując rzecz nieformalnie, OOP (Object Oriented Programming – programowanie zorientowane obiektowo) to pewna filozofia tworzenia oprogramowania, która – w przeciwieństwie do strukturalnego – bazuje na klasach i ich obiektach. Już się tłumaczę z tego dość zawiłego zwrotu. Załóżmy ze chcemy napisać jakiegoś RPGa, dla ułatwienia weźmy lubianego powszechnie Wiedźmina, który w końcu jest naszą narodową dumą;) Cała gra może oczywiście zostać napisana w jednym pliku, w funkcji main z milionem zmiennych na początku… Nieee, oczywiście że nie może! Jak mniemam domyślasz się, ze nie dałoby się tego zrobić ze względu na monstrualnych rozmiarów bałagan jaki by powstał. Dodatkowo – przy takiej złożoności gry jaka ma Wiedźmin – nie sposób byłoby zaprojektować od strony inżynierskiej takiego kodu. Na szczęście programiści są zaradni i stworzyli… Klasy! Klasy to pewne typy struktur danych, które programista tworzy sam. Pozwala to wejść na zupełnie inny, dużo bardziej naturalny poziom. Każda klasa składa się z pól (zmiennych) oraz metod (funkcji).
Wróćmy do przykładu Wiedźmina – nie musimy już posługiwać się milionem nic nie mówiących zmiennych. Możemy stworzyć klasę ‚postać’, która będzie miała pola: życie, wytrzymałość, szybkość, imię oraz bron. Metody jakie stworzylibyśmy dla naszej klasy to: Biegnij() oraz Zaatakuj(). Wspaniale! Zauważyłeś pewnie jednak drobną nieścisłość. Przypatrzmy się typom pól: int, float, float, string i…? No właśnie, czym miałaby być bron? Stringiem który opisuje jej nazwę? A może floatem który opisuje jej atak? Na szczęście żyjemy w świecie programowania obiektowego i nie musimy się ograniczać;) Stwórzmy zatem klasę… Bron! Sadze ze tutaj sprawa jest bardzo prosta, klasa będzie zawierać jedynie dwa pola: nazwa (string) oraz atak (float).
Wszystko bardzo fajnie, ale ‚postać’ to dosyć ogólne stwierdzenie. Wiemy przecież, że w świecie Andrzeja Sapkowskiego jest bardzo dużo rodzajów postaci i ze różnią się one od siebie dosyć znacząco. Możemy zatem uszczegółowić. W tym celu skorzystamy z pewnej relacji miedzy klasami, która nazwana została ‚dziedziczeniem’. To bardzo proste – klasa pochodna(potomek) dziedziczy wszystkie pola i metody po klasie bazowej (przodek). W tym przypadku możemy stworzyć kilka klas pochodnych: krasnolud, elf, człowiek. Każda z tych klas automatycznie będzie miała życie, wytrzymałość, szybkość oraz bron. Będzie również miała metody Biegnij() oraz Zaatakuj(). Możemy jednak każdej z nich dodać cos specyficznego dla danej rasy. Np. krasnoludowi możemy dać dodatkowa metodę RozpocznijAwanture() a elfowi dodać pole kołczan. Jakie jeszcze inne klasy i związki mogłyby wystąpić w grze autorstwa CD Projekt Red? Wymieńmy pokrótce kilka: zapewne może być bron po której dziedziczy miecz, łuk oraz topór. Potwór po którym dziedziczą utopiec, przeraza, kikimora oraz troll. Na końcu możemy oczywiście stworzyć ‚Eliksir’, który zawiera w sobie inne klasy – składniki. Gdy mamy już zbudowaną strukturę naszego programu (Gry tez są rodzajem aplikacji. W dodatku jednym z fajniejszych;)), możemy przystąpić do tworzenia obiektów. Jeśli pomyślisz o klasie jako o typie zmiennych, to obiekt jest właśnie zmienną (z resztą nie trzeba traktować tego jak metaforę. Tak naprawdę jest!). Możemy więc stworzyć całą armię robiąc 1000 elementową tablicę krasnoludów. Możemy stworzyć kilka obiektów klasy ‚Krasnolud’ oraz kilka klasy ‚Człowiek’ i umieścić ich w obiekcie klasy ‚Karczma’, który to będzie elementem obiektu klasy ‚Miasto’. Prawda ze programowanie zaczyna wyglądać bardzo naturalnie, żeby nie powiedzieć „przyjaźnie”? Jestem przekonany, że w mig przyswoiłeś sobie wszystko co napisałem na górze. Jest jednak jeszcze jedna rzecz, o której koniecznie musisz wiedzieć.
Ta rzecz to hermetyczność. Wyobraźmy sobie klasę człowiek (ale w życiu realnym, nie w grze). Może ona mieć takie pola jak: wątroba, poziom krwi, serce, nerki. Nie chcielibyśmy żeby każdy mógł nam majstrować przy nerkach prawda? Właśnie dlatego w klasach zarówno pola jak i metody maja jeden z trzech modyfikatorów dostępu. Public wskazuje, że element jest dostępny publicznie i ma do niego dostęp każdy. Private – dostęp jedynie dla metod wewnątrz klasy. Protected – podobnie jak private, jednak jest dziedziczone przez klasy potomne. No dobrze, ale pewnie chciałbyś w razie potrzeby, aby do poziomu krwi miał dostęp lekarz? Od tego są specjalne metody zwane geterami oraz seterami. Getery (lub krócej – gety) wyciągają wartość danego pola zaś setery (sety) nadają określonemu polu wartość. Daje nam to bardzo ważną możliwość kontroli tego co wpływa do naszych pól. Tak więc możemy ustawić ogranicznik w seterze przeznaczonym dla poziomu krwi i nadać granice – nie można zmienić stanu pola jeśli będzie miało ono mieć w efekcie mniej niż 2.5 oraz nie wolno jeśli mielibyśmy mieć więcej niż 6 litrow. Możemy nie stworzyć getera lub setera, wtedy ograniczany możliwości tego kto chciałby majstrować później przy obiekcie. Dla przykładu – pole może być stanem konta bankowego w danym momencie. Nie chcemy raczej żeby ktoś poza nami miał do niego dostęp, nie stworzymy więc geta. Nie damy tym samym żadnej możliwości zdobycia wiedzy o tym ile pieniążków zgromadziliśmy. Znakomicie! Poznałeś już teoretyczne podstawy programowania obiektowego, czas zabrać się za aspekt praktyczny.
Stworzymy razem prostą aplikację do przechowywania danych o produktach oraz prostych operacji na nich. Do dzieła! Na początku wypiszmy funkcjonalności jakie będzie posiadał nasz program – nazwijmy go sklepem.
Po tym krótkim wstępie projektowym pobawmy się w inżynierię oprogramowania. Zastanówmy się jakich klas będziemy potrzebować do Sklepu. Mimo mojej miłości do wszystkiego co polskie, w tym oczywiście do języka – kod budować będę w języku angielskim i Tobie też to zalecam;)
Pola:
Metody:
Pola:
Metody:
Zatem zabierzmy się za implementację! Używam do tego celu środowiska Visual Studio 2013 i Tobie też to zalecam. Po utworzeniu projektu (który nazwiemy „ShopBase”) oraz pliku „main.cpp” z funkcją main() zabierzmy się za utworzenie pierwszej klasy! Klikamy „Project->Add Class”, a następnie „Add”. W pole „Class Name” wpisujemy „Product” i klikamy „Finish”. Brawo! Twoja pierwsza klasa została właśnie stworzona! Jak widzisz środowisko wygenerowało Ci dwa pliki: jedno z rozszerzeniem „.h” i jedno z rozszerzeniem „.cpp”. Pierwszy z nich to tzw. header – plik nagłówkowy, w którym będziemy jedynie definiować pola i metody, w drugim zaś te same pola i metody będziemy implementować. Dopisz odpowiednie miejsca, aby cała klasa wyglądała następująco:
Product.h #pragma once #include <iostream> #include <string> using namespace std; class Product { private: int id; string name; float price; public: Product(int _id, string _name, float _price); Product(); int GetId(); string GetName(); float GetPrice(); void SetPrice(float _price); void SetId(int _id); void WriteProduct(); ~Product(); }; Product.cpp #include "Product.h" Product::Product(int _id, string _name, float _price) { id = _id; name = _name; price = _price; } Product::Product() { id = -1; name = "empty"; price = 0; } float Product::GetPrice() { return price; } void Product::SetPrice(float _price) { price = _price; } void Product::WriteProduct() { cout << "Produkt id: " << id << "\n nazwa: "<< name << " \n cena: " << price << "\n"; } Product::~Product() { }
Jak widzisz zaimplementowaliśmy wszystkie pola oraz metody które zaplanowaliśmy. Ale zaraz, co to za dziwne metody na początku i na końcu?! Już tłumaczę. Gdy tworzymy klasę automatycznie tworzą nam się: konstruktor oraz destruktor. Pierwszy z nich to metoda, która wywołana będzie zawsze podczas tworzenia obiektu, zaś destruktor – tak, zgadłeś! Podczas usuwania Mamy jednak dość specyficzną konstrukcję. Pierwszy z konstruktorów jako argument przyjmuje id, name oraz string – czyli nasze pola prywatne, które zaraz też wypełniamy. Gdy jednak użytkownik nie poda żadnych argumentów stosujemy konstruktor domyślny – w naszym przypadku tworzymy bardzo specyficzny obiekt o „nierealnych danych” takich jak -1 jako id. Jeśli któryś z produktów będzie miał to id będziemy go traktować jako obiekt który nie istnieje i dopiero jest „do stworzenia”. Reszta metod jak mniemam nie wymaga komentarza (Gety i Sety pisze się podobnie, więc zostawiłem jedynie po jednym dla przykładu), jednak gdybyś miał z którąkolwiek z nich problem nie wahaj się i śmiało pisz na mojego maila
Base.h #pragma once #include <iostream> #include "Product.h" using namespace std; class Base { private: int lastId; Product products[100]; string name; public: Base(); void AddProduct(Product _product); void RemoveProduct(int _id); string GetName(); void SetName(string _name); void WriteProducts(); float CalculateProducts(); Product FindProduct(int _id); ~Base(); };
Sądzę, że większość jest jasna. Jestem jednak winien komentarz w jednym z moich ruchów. Gdy spojrzysz na drugą linijkę pól prywatnych zobaczysz tablicę 100 elementową produktów. Musisz wiedzieć, że zastosowałem takie rozwiązanie TYLKO ze względu na łatwość implementacji. Trzeba jasno powiedzieć, że jest ono brzydkie i w następnym artykule przejdziemy do bardziej eleganckich i nowoczesnych rozwiązań!
Base.cpp #include "Base.h" Base::Base() { lastId = 0; } void Base::AddProduct(Product _product) { for (int i = 0; i < 100; i++) { if (products[i].GetId() == -1) { lastId++; products[i] = _product; products[i].SetId(lastId); break; } } } void Base::RemoveProduct(int _id) { for (int i = 0; i < 100; i++) { if (products[i].GetId() == _id) { products[i] = Product(); break; } } } void Base::WriteProducts() { cout << "produkty bazy " << name << ":" << endl; for (int i = 0; i < 100; i++) { if (products[i].GetId() != -1) { products[i].WriteProduct(); } } } float Base::CalculateProducts() { float price = 0; for (int i = 0; i < 100; i++) { price += products[i].GetPrice(); } return price; } Product Base::FindProduct(int _id) { Product tmpProd = Product(); for (int i = 0; i < 100; i++) { if (products[i].GetId() == _id) { tmpProd = products[i]; } } return tmpProd; }
Z powodu oszczędności miejsca usunąłem stąd get’y i set’y oraz destruktor. W konstruktorze ustawiamy „lastId” na 0 – będzie to nasz licznik dzięki któremu będziemy nadawali kolejne id. W AddProduct() przebiegamy po tablicy produktów i jeśli jest „wolne” miejsce (id == -1) to wstawiamy tam nasz produkt z id o 1 większym od ostatniego oddanego produktu. W RemoveProduct() wykorzystujemy konstruktor domyślny Product i wybrany rekord tablicy produktów czynimy „pustym”. WriteProducts() przechodzi tradycyjnie po tablicy i wypisuje kolejne elementy. Finalnie FindProduct() – wyszukujemy w tablicy produkt o podanym id i zwracamy go.
Znakomicie! Udało nam się zrobić to co najważniejsze – klasy. Teraz należy napisać tylko interfejs do nich. I tu czeka na Ciebie wyzwanie – ja wstawię „brzydki” bez komentarza, a Ty stwórz jego lepszą wersję i wyślij do mnie. Oczywiście najlepiej, gdyby była to wersja obiektowa!
Main.cpp – funkcja main() void main() { bool condition = true; Base ShopBase = Base(); Base Basket = Base(); while (condition) { cout << "Witaj w naszym sklepie! Wybierz co chcesz zrobic:" << endl; cout << "1 - Wyswietlic wszystkie produkty w bazie" << endl; cout << "2 - Dodac produkt do bazy" << endl; cout << "3 - Wyswietlic twoj koszyk" << endl; cout << "4 - Dodac produkt do koszyka" << endl; cout << "5 - usunac produkt z koszyka" << endl; cout << "6 - Obliczyc wartosc koszyka" << endl; int helpVar = 0; cin >> helpVar; switch (helpVar) { case 1: { ShopBase.WriteProducts(); cout << endl; break; } case 2: { string name; float price; cout << "Wpisz nazwe: "; cin >> name; cout << "Wpisz cene: "; cin >> price; Product tmpProduct = Product(-1, name, price); ShopBase.AddProduct(tmpProduct); break; } case 3: { Basket.WriteProducts(); cout << endl; break; } case 4: { int tmpId; cout << "Podaj id: "; cin >> tmpId; Product tmpProd = ShopBase.FindProduct(tmpId); Basket.AddProduct(tmpProd); break; } case 5: { int tmpId; cout << "Podaj id: "; cin >> tmpId; Basket.RemoveProduct(tmpId); break; } case 6: { float tmpPrice = Basket.CalculateProducts(); cout << "Wartosc koszyka to: " << tmpPrice << endl; break; } default: cout << "Wybrales zla opcje!" << endl; break; } } _getch(); }
Efekt końcowy aplikacji.
Brawo! Stworzyłeś swój pierwszy program do obsługi sklepowej bazy produktów Przy tej okazji dowiedziałeś się czym są klasy, metody, pola, hermetyzacja, konstruktory, destruktory oraz najważniejsze – po co my to wszystko stosujemy? Rozumiem oczywiście, że to dużo nowych informacji i jeszcze nie wszystko musi być jasne. Spokojnie! Jest czas, tylko heros zrozumie zawsze za pierwszym razem. Jeśli masz jakiekolwiek pytania pisz śmiało na mojego maila. Zapraszam do materiałów, gdzie znajdziesz również pełny projekt do pobrania. Zdaję sobie sprawę, że niektóre rozwiązania, które zastosowałem są „brzydkie”. Wobec tego zachęcam Cię… do poprawy ich! Popraw i przyślij mi rozwiązanie, a ja z przyjemnością je przejrzę. Miłego kodowania!
Jeśli dotarłeś aż tutaj, to znaczy że jesteś człowiekiem innym niż większość. To znaczy, że nie wystarczają Ci skrótowce, że prawdopodobnie wymagasz od siebie nieco więcej niż przeciętnie. Pozostańmy zatem w kontakcie – zapisz się na Newsletter Wolnego Człowieka i pomóż mi tworzyć coraz lepsze treści! Jeśli zdecydujesz się wpisać – obiecuję zero spamu. Raz w tygodniu będziesz dostawał maila z podsumowaniem tego co zrobiłem na blogu.
Artykuł Programowanie Obiektowe – czyli jak programować, aby skutecznie tworzyć realny świat? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Testy dla zielonych, czyli dlaczego nie warto zaczynać aplikacji bez testów pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>To zdecydowanie najważniejszy punkt mojego dzisiejszego artykułu oraz środowego LRUGa. Żebyś dobrze to zrozumiał posłużę się aplikacją którą rozwijam po godzinach. Warthog Timer ma pomóc w zmobilizowaniu się przy okazji realizowania różnych umiejętności. Sama główna funkcjonalność jest banalnie prosta. Gdy zaczynasz coś robić (na przykład pracę inżynierską, aplikację internetową czy malowanie obrazu) klikasz „START” na timerze. Gdy kończysz klikasz „STOP” – i w tym momencie tworzy się log_time – jeden obiekt w bazie. Następnie idziesz do statystyk i sprawdzasz ile udało ci się spędzić czasu nad różnymi fajnymi rzeczami. Statystyką która nas dzisiaj zajmie będzie „Najlepszy cel”. Na rysunku poniżej przedstawiam łańcuch metod jaki musi się odbyć od pozyskania danych (calculate_time_from_log_times) do obliczenia ostatecznego celu (best_target).
To co warto zauważyć to fakt, że ta metoda na samym dole obliczająca czas jest użyta aż… 8 razy. I to za każdym razem jest podobny łańcuch. Zastanówmy się więc co będzie, jeśli będziemy chcieli ją nieco zmienić, ale zamiast poprawić – zepsujemy? Oczywiście zarówno ten, jak i każdy inny łańcuch staje się kompletnie do niczego. W tym przypadku więc Warthog byłby kompletnie sparaliżowaną aplikacją. „Ok, co z tego, przecież mogę się przeklikać” ktoś powie. Pewnie – ale ile razy? I za każdym razem gdy coś zmienisz masz zamiar się przeklikiwać we wszystkich możliwych wariantach? Już to widzę…
Tutaj z pomocą przychodzą nam testy jednostkowe. Są to takie małe fragmenciki kodu, drobne instrukcje które mają sprawdzać czy przy odpowiednich parametrach wywołanie danej metody daje pożądany wynik. To rozwiązanie o wiele lepsze, niż popularne „przeklikam się”, gdyż myślimy tylko raz (przy pisaniu), a potem po prostu odpalamy testy zawsze gdy dokonamy jakiś zmian i.. już.
Ponieważ na co dzień piszę w Ruby on Rails a i prezentacja była oparta na tej technologii, to tutaj dokładnie pokażę jak od 0 zbudować sobie wygodne środowisko do pierwszych, najbardziej podstawowych testów. Potrzebne będzie nam kilka gemów. Wchodzimy w Gemfile (w głównym katalogu aplikacji) i wpisujemy kolejno:
gem ‘rspec-rails’ gem ‘factory_girl_rails’ gem ‘database_cleaner’
Gdy już to wpiszemy idziemy do terminala i wprowadzamy „bundle install”, co zainstaluje nam wszystkie wyżej wprowadzone gemy. Krótkie wytłumaczenie – Rspec to gem odpowiedzialny za obsługę testów, jest można powiedzieć „głównym filarem” który wszystko spaja. Ponieważ jednak jest to środowisko testowe a nie development, musimy stworzyć tam nasze obiekty. Do tego posłuży nam Factory Girl (Nie pytaj, nazwy tutaj naprawdę bywają dziwne…). Na koniec bardzo przydatna sprawa – Database Cleaner pomoże nam czyścić bazę przed każdym testem. Dzięki temu na każdy test popatrzymy jako osobną część i zachowamy nad nim pełną kontrolę. Skoro już zainstalowałeś gemy, wejdź ponownie w terminal i wprowadź komendę rails generate rspec:install. Po tym zabiegu powinieneś w głównym katalogu aplikacji mieć folder „spec”. Na ten moment wpisz w terminal „rspec” i… zobacz jak świetnie wykonały Ci się twoje wszystkie (0) testy. Gratuluje! Wejdź w folder spec, a następnie spec_helper.rb. tutaj wklej następujący kod który obsłuży czyszczenie bazy danych w odpowiednich momentach.
Zabierzmy się za napisanie testu. Tutaj mogę niestety jedynie pokazać Ci jak wygląda to u mnie, w Warthog’u. Testujemy omawianą wyżej metodę calculate_time_from_log_times. Wygląda ona następująco:
def calculate_time_from_log_times(log_times) time = 0 log_times.each do |log_time| time += log_time.time * 60 end time end
Ponieważ znajduje się ona w serwisie (taka klasa w której umieszczamy logikę – na przykład różne algorytmy), stworzyłem w folderze „spec” nowy katalog – „services”, zaś w nim „targets_stats_service_spec.rb” – czyli nazwę mojego serwisu z dodanym na końcu „_spec” (To kwestia konwencji, która w Ruby on Rails jest święta! Dlatego też się do niej stosuj). Wewnątrz napisałem 3 testy – widoczne pod spodem. Zwróćmy uwagę na kilka elementów:
require 'rails_helper' context 'tests for calculate_time_from_log_times' do it 'should get time 0' do user = FactoryGirl.create(:user) service = DirectData::TargetsStatsService.new(user.id) time = service.calculate_time_from_log_times(user.log_times) expect(time).to eq(0) end it 'should get time 1800 (30 min * 60 s)' do user = FactoryGirl.create(:user) prefab = FactoryGirl.create(:prefab, user: user) FactoryGirl.create(:skill, user: user) FactoryGirl.create(:log_time, user: user, prefab: prefab) service = DirectData::TargetsStatsService.new(user.id) time = service.calculate_time_from_log_times(user.log_times) expect(time).to eq(1800) end it 'should get time 4500 (30 + 30 + 15 [min] * 60 s)' do user = FactoryGirl.create(:user) prefab = FactoryGirl.create(:prefab, user: user) FactoryGirl.create(:skill, user: user) FactoryGirl.create(:log_time, user: user, prefab: prefab) FactoryGirl.create(:log_time, user: user, prefab: prefab) FactoryGirl.create(:log_time2, user: user, prefab: prefab) service = DirectData::TargetsStatsService.new(user.id) time = service.calculate_time_from_log_times(user.log_times) expect(time).to eq(4500) end end
Warto zwrócić uwagę na to FactoryGirl.create(). To właśnie stworzenie obiektu w bazie. Żeby stworzyć „matrycę” takiego obiektu najpierw utworzyłem folder „factories” wewnątrz „spec”, a następnie stworzyłem odpowiedniki modeli – np. log_time.rb, target.rb czy user.rb. Pokazuję przykładowy kod – user.rb żebyś wiedział jak tworzyć proste Factory Girl.
FactoryGirl.define do factory :user do email '[email protected]' password 'lolopolo' confirmed_at { DateTime.now } end end
Gdy już napisałeś testy, jedyne co musisz zrobić aby je odpalić to wejść do terminala i wpisać… rspec. Klikasz enter i już! Testy samoczynnie idą, zaś na koniec „wypluwają” raport. Jeśli któryś się nie powiódł to prawdopodobnie masz coś nie tak z metodą (lub z samym testem). Gdy uda Ci się doprowadzić wszystko do pozytywnego stanu możesz poklepać się po pleckach – wykonałeś(/łaś!) kawał dobrej roboty!
Na koniec chciałbym bardzo mocno zaznaczyć, że testy to gigantyczny temat który zaledwie tutaj musnęliśmy. Zachęcam Cię do eksplorowania Internetu w celu dalszego szlifowania umiejętności związanych testowaniem. Pamiętaj, że od tego zależy jakość twojej aplikacji, a przecież nie chcemy robić niczego byle jak prawda? Testy oszczędzają mnóstwo czasu i nerwów oraz dają Ci większą kontrolę nad tym co dzieje się z twoją aplikacją. Oczywiście jeśli będziesz chciał poznawać te tematy, służę pomocą – możesz napisać do mnie maila lub złapać mnie na którymś z LRUG’ów;-)
P.S.
Warthog jest w wersji pre-alfa, ale jeśli chcesz spróbować przejąć kontrolę nad czasem który poświęcasz na rzeczy które Cię budują, to zachęcam do korzystania na stronie warthogtimer.com. Przed rejestracją po prawej stronie zajrzyj w znak zapytania który podpowie Ci, jak korzystać z serwisu. A jeśli będziesz miał uwagi, pytania lub sugestie również odnośnie rozwoju aplikacji – zamieniam się w słuch : – )
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
piszę do Ciebie prosto z Łodzi
Artykuł Testy dla zielonych, czyli dlaczego nie warto zaczynać aplikacji bez testów pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Artykuł Czego potrzeba Ci jeszcze, abyś zmieniał świat? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>Pierwotnie artykuł ten ukazał się w tygodniku MojaMatura.pl
Ta branża to informatyka. Zarówno uczelnia jak i codzienna praca zawodowa nauczyły mnie bardzo jasno, ze nie ma tutaj niemal żadnych granic. A jeśli w danym momencie wydaje mi się ze są to najczęściej jest to złudzenie lub – co zdarza się bardzo rzadko – faktyczna granica, jednak istniejąca tylko po to aby została rozbita. Rozumiem jednak, ze dla osób które patrzą na IT z zewnątrz a także (a może przede wszystkim ) dla tych, którzy dziedzinę tą znają ze szkolnych zajęć informatyki może się ona wydać czymś potężnym i odległym, do czego dostęp maja jedynie „druidzi” znający tajniki tej niezwykłej magii. Zgodzę się w jednym – jest to dziedzina potężna. Stawiam jednak wielkie „veto!” wobec stwierdzenia, ze nie mogą tworzyć w niej „zwykli” ludzie. Jeśli nie miałeś wcześniej kontaktu z informatyką (poza tworzeniem prezentacji w PowerPoint;) ) to w moich artykułach postaram się wprowadzić Cię do „grona druidów”. Jeśli próbowałeś już swoich sił, to w rubryczce tej liczę że znajdziesz trochę inspiracji i pomocy odnośnie tworzenia.
Czym będziemy się zajmowali? Niemal wszystkim! Postaram się miedzy innymi pokazać jak stworzyć prosta aplikacje użytkowa (tak! To znaczy ze będziesz mógł potem z niej korzystać i że przyda ci się ona w codziennym życiu) wykorzystująca bazę danych i korzystająca z danych zamieszczonych w Internecie (brzmi groźnie? To niech przestanie, bo leży to w zasięgu twojej ręki! Poza tym dostaniesz odpowiednia pomoc, ale o tym później). Mało? Razem zrobimy prosta grę wideo w która będziesz mógł grać na swoim smartfonie czy komputerze (a może więcej niż jedną…?). No! Ale wiadomo ze nasza branża to nie tylko programowanie. Nauczysz się tez jak tworzyć grafiki – zarówno 2D jak i 3D. A teraz ekstra bonus! Dlatego, że mam głębokie przekonanie, ze artykuły nie powinny być jednostronne. Dlatego to Ty powinieneś zareagować i gdy tylko pomyślisz że jakąś tematykę chciałbyś poznać bardziej – napisz do mnie. Jeśli pomysł będzie naprawdę dobry – napisze o nim artykuł.
Wspomniałem o tym, ze nie jesteś skazany na to, żeby w pojedynkę mierzyć się z problemami podczas tworzenia i już się z tego tłumaczę. Otóż MojaMatura.pl to nie jedyne miejsce gdzie możesz mnie znaleźć. Zapraszam na mojego bloga, na którym będziesz mógł przeczytać rozwinięcie czytanych tutaj artykułów, pozyskać materiały oraz – co najważniejsze dla tego wątku – nawiązać kontakt ze mną. Tak więc ja oraz osoby które co jakiś czas będą pomagały mi w tworzeniu artykułów będziemy do twojej dyspozycji. W każdym artykule będę zachęcał Cię nie tylko do spróbowania swoich sił w konkretnej tematyce, ale przede wszystkim do tworzenia swoich dzieł i dzielenia się nimi. Zachęcam nie tylko Ciebie ale i twoich kolegów do tego, abyśmy stworzyli swoistą społeczność młodych twórców. Obiecuję również, że jeśli któryś z Twoich pomysłów spodoba mi się szczególnie – nie omieszkam o nim wspomnieć tutaj lub na swoim blogu. Również jeśli będziesz miał jakieś pytania z szeroko pojętej informatyki – napisz do mnie, a ja zadam je ludziom z branży którzy zajmują się tym na co dzień.
Tak więc ruszamy na podbój świata! Zapnij pasy, szykuj dużo ciekawości i determinacji bo będą one niezbędne. I zawsze, ale to zawsze pamiętaj – jeśli jakiekolwiek granice faktycznie istnieją, to są one do rozwiązania w Tobie. Czy to wszystko znaczy, że możesz po prostu teraz usiąść i za miesiąc zbudujesz iTunes? Oczywiście, że nie. To znaczy, że jeśli usiądziesz teraz i będziesz robił coraz to lepsze aplikacje, za miesiąc lub dwa postawisz pierwszą aplikację z której będziesz mógł korzystać w życiu codziennym, zaś za dwa lata stworzysz razem ze znajomymi taką, z której korzystać będzie cała Polska. Branża informatyki to nie świat idylliczny, żeby do czegoś dojść faktycznie trzeba być bardzo wytrwałym i zdeterminowanym, trzeba codziennie budować nowe elemenciki swojego systemu (jakby to zaśpiewała Hayley Williams – „budować dom cegła po nudnej cegle…”). Jest to jednak świat w którym to nie układy, a twój dobry pomysł i ciężka praca mogą przynieść Ci sukces. Zachęcam zatem do kreowania swoich pomysłów, wdrażania ich i dzielenia się nimi z innymi. Świat można zmienić. Trzeba tylko chcieć i wykazać więcej determinacji niż konkurencja Powodzenia!
Ja nazywam się Marek Czuma, a to jest IT-Blog Wolnego Człowieka
piszę do Ciebie prosto z Łodzi
Artykuł Czego potrzeba Ci jeszcze, abyś zmieniał świat? pochodzi z serwisu Marek Czuma - IT-Blog Wolnego Człowieka.
]]>