Tuesday, April 12, 2016

Blog and challanges summary

I started this blog to write about things that interests me. At the beginning it was a little bit about motivation and running [here]. I set some goals for myself to achieve [here] and event create a page that stores all my successes and failures [here].

Today I would like to end this part of my webpage so I will do a quick summary of how I failed hard and succeed in some of the challenges.

Challenges summary - failure part

Lets start with the bad news - in both of the running challenges, namely:

  • run half marathon in 2015
  • run marathon in 2015

I failed. Last time, that I wrote about running [here] I mentioned that I got injured. Unfortunately the recovery period was long (I tried running after 2/3/4/5 weeks and my knee was still hurting). I took some pills but it did not help. I did some exercises instead - ride a bicycle, did over 100 km while cross country skiing. The break from running made it impossible to take part in half marathon in Poznan in April. I started running in April and gradually increased the intensity (I read a book about running during while being injured). Unfortunately in July my knee started hurting again and I had to pause running again. This shattered the dreams of marathon for me.

On the bright side of things - I bought a bike and I enjoyed riding it. I did almost 1500 kms last year, while in previous years I did not ride at all. I was even able to ride over 100 km in one day which I am proud of :) All in all despite not fulfilling my plans I enjoyed the year trying different sports.

Additional note for other people that are starting running or are planning to - do not force yourself to much. I know it is nice to exhaust yourself after a long day in front of the computer but for the sake of your health run slowly. Really. Or read a book or run with somebody at pace that you can talk comfortably.

Challenges summary - I don't know what it is part

I started the blog to express myself to the world. To hone my writing skills. To share my ideas. I challenged myself to keep the blog up with regular updates. It is still alive. Maybe not exactly alive and kicking but also not on the verge of death I guess. What do you think my dear reader? Was this challenge a success or was it a failure?

Challenges summary - I did something right part

At the beginning of the year somebody showed me a program for a mobile phone that allows learning the foreign languages. I am talking about Duolingo. It is really well executed application and what is most important it is free (and can be used on both mobile phone and the PC thanks to being a webpage). I started doing the exercises and today I achieved 100 days streak (which was my goal). That means I did the necessary exercises each and every day starting from 4th of January. I finished all the lessons a while ago and now I only did repetitions and it is less interesting that new lessons.
I would like to encourage everybody to try the Duoliong and the method of learning by small but frequent exercises. On the downside there is only one level of Polish-English course and is rather simple.

TL; DR

When I started this blog I set myself a few goals (challenges). Today I revised how I fare - I described my failures and successes. Now I retire this part of the webpage - no more challenges for me (at least for now). The archived ones can be found here.

Friday, January 15, 2016

Python is Over 9000!

In my last post I asked you, my dear reader, to try and flex your programming muscles solving some tasks in C++ language. Now is the time to compare the solutions of the aforementioned exercises in both Python (written by me, please take a note that I have learnt Python in the last year) and C++ (solutions from my friends who know how to program). Big shoutouts to them, as without their work this post will not be that long. You can check their profiles on github - przemkovv and MichalNowicki).

The code

1) lets assume we have two collections and would like to print values from them in the following format:
value_0_from_first_collection, value_0_from_second_collection
value_1_from_first_collection, value_1_from_second_collection
etc.

So for the warm-up we are doing something rather easy, that in Python looks really straightforward:

for n1, n2 in zip(numbers_1, numbers_2):
    print(n1, n2)

For those not familiar with Python - you can check zip function here. In this case it is returning elements from both collections which are assigned to names n1 and n2.

In C++ it looks a little bit more cumbersome (what are this magical * sign? :P):

for (auto it = kolekcjaA.begin(), it2 = kolekcjaB.begin(); 
     it != kolekcjaA.end() && it2 != kolekcjaB.end(); ++it, ++it2) {
    std::cout << *it << " " << *it2 << std::endl;
}

Or if you use some dark magic you can get something similar to what Python is offering:

vector<tuple<char="", int="">> out_zipped;

transform(vec.begin(), vec.end(), str.begin(), back_inserter(out_zipped), [](auto x, auto y){ return make_tuple(x, y);});

for_each(out_zipped.begin(), out_zipped.end(), [](auto t) {
    cout << get<0>(t) << ", " << get<1>(t) << endl;
});

It gets the job done but I would say that Python solution is much neater.

2) lets assume we have a text and we would like to print it without the first and the last sign. In addition we would like to print the text length.

Python:
print(text[1:-1], ", " + str(len(text)))

C++:
// solution 1
std::cout << text.substr(1, text.size() - 2) << " " << text.length() << std::endl;

// solution 2
string cut_from_both_sides(str.begin() + 1, str.end() - 1);
cout << cut_from_both_sides.length() << " " << cut_from_both_sides << endl;

All of them looks similar, but look at the next task to see the advantage of Python solution!

3) we have a collection of values and we would like to print it without the first and last values. In addition we would like to print the size of the collection.

Python:
print(numbers_1[1:-1], ", " + str(len(numbers_1)))

C++:
// solution 1
for (auto it = kolekcjaA.begin() + 1; it + 1 != kolekcjaA.end(); ++it) {
    std::cout << *it << std::endl;
}

// solution 2
vector<int> vec2(begin(vec) + 1, end(vec) - 1);
cout << vec2 << endl;

As you can see the Python is still using the same way, while C++ solution 1 evolved to using iterators, while the C++ solution 2 is the same but will not work for lists (and other collections that do not offer [] operator)!

4) we have a function that has to return:
a) two values,
b) three values.
How would you implement that?

Python:
def increment_all(a, b, c):
    return a+1, b+1, c+1

x, y, z = increment_all(x, y, z)
print(x, y, z)

C++:
auto triple_return() {
    return make_tuple(5, "good", 3.5);
}

auto gotcha3 = triple_return();
cout << get<0>(gotcha3) << " " << get<1>(gotcha3) << " " << get<2>(gotcha3) << endl;

To save space I left just triple return. At first glance all the solutions look similar, but take a closer look how you print the returned values and you will appreciate Python simplicity. Also it is possible to swap values without additional buffers:

a, b = b, a

5) for collection of your choice do:
a) print all values,

Python:
for v in values:
    print(v)

C++:
for (auto value : vec3) {
    std::cout << value << std::endl;
}

Nothing extraordinary. C++ has similar construction for getting elements from collections.

b) increase each value by 10,

Python:
values = [v+10 for v in values]

C++:
// solution 1
for (auto& x : vec3) {
    x += 10;
}

// solution 2
transform(begin(vec3), end(vec3), begin(vec3), [](auto x) { return x + 10; });

This is where things start to be interesting. In Python you use thing called list comprehension, which is general and elegant way to work on containers. In C++ you can use solution similar to the last one but you have to remember to use another special C++ operator - &. Solution 2 is a way to mimic Python behaviour.

c) remove last element,

Python:
values.pop()

C++:
// solution 1
kolekcjaA.resize(kolekcjaA.size() - 1);

// solution 2
vec3.pop_back();

Nothing special, but C++ guys offered two different solutions :)

d) remove n-th element,

Python:
n = 2
values.pop(n)

C++:
// solution 1
int n = 4;
kolekcjaA.erase(kolekcjaA.begin() + n);
}
// solution 2
const int nth = 10;
vec3.erase(begin(vec3) + nth);

Once again C++ solutions does not work for lists.

e) print value alongside its index,

Python:
for i, v in enumerate(values):
    print(i, v)

C++:
// solution 1
for (int i = 0; i < kolekcjaA.size(); i++) {
     std::cout << "Index = " << i << " " << kolekcjaA[i] << std::endl;
}

// solution 2
int i=0;
for (auto it = begin(vec3); it != end(vec3); ++i, ++it) {
    cout << i << " " << *it << endl;
}
// solution 3
i=0;
for (auto x : vec3){
    cout << i << " " << x << endl;
    ++i;
}
// solution 4
for (auto p = make_pair(0, begin(vec3)) ; p.second != end(vec3); ++p.first, ++p.second) {
    cout << p.first << " " << *(p.second)  << endl;
}

In Python this is straightforward - enumerate and done! C++ offers a lot of solutions, that have some pros and cons. I prefer to have one main solution - it helps when more than one person is working on with the code.

f) check if value x is in collection,

Python:
if 27 in values:
    print("27 is in the collection")

C++:
// solution 1
bool contains_25 = find(begin(vec3), end(vec3), 25) != end(vec3);
cout << contains_25 << endl;
// solution 2
auto contains_x = [](auto C, auto x) { return find(begin(C), end(C), x) != end(C); };
cout << contains_x(vec3, 25) << endl;

Once again you can witness how elegant Python is. It is the most straightforward way and even non-programers would understand what this code do.

g) check if all values are smaller than y.

Python:
if all(v < 30 for v in values):
    print("All values are smaller than 30!")

C++:
// solution 1
int twojaWartosc = 4;
auto wart = std::find_if(kolekcjaA.begin(), kolekcjaA.end(), [&twojaWartosc](auto const &x) { return x < twojaWartosc; });
std::cout << "Wartosc : " << *wart << std::endl;

// solution 2
int y = 50;
cout << all_of(begin(vec3), end(vec3), [=](auto x) { return x < y; }) << endl;
// solution 3
auto less_y = [](auto y) { return [=](auto x) { return x < y;  }; };
cout << all_of(begin(vec3), end(vec3), less_y(20)) << endl;

Python is clean and simple. In C++ you can use different ways, but even this simple task can cause problems - solution 1 throws exception when the value is not in the collection as you try to access (dereference) an iterator that point to the end of collection.

6) having a text count how many letters are lower-case and how many are upper-case

Python:
number_of_uppercase_case = sum(1 for c in text if c.isupper())
number_of_lowercase_case = sum(1 for c in text if c.islower())

C++:
// solution 1
int male = std::count_if(podanyTekst.begin(), podanyTekst.end(), [](unsigned char x) { return islower(x); });
int duze = std::count_if(podanyTekst.begin(), podanyTekst.end(), [](unsigned char x) { return isupper(x); });

// solution 2
cout << count_if(begin(s), end(s), islower) << endl;
cout << count_if(begin(s), end(s), isupper) << endl;

All the solutions are very similar - they use built-in functions. The thing with Python is that you can use almost the same code for other things like e.g. extraction of lower-case letters:

lower_case_letters = [c for c in text if c.islower()]

7) is there any situations that you do not use indentation?

We all have agreed that apart of code golfing everybody should use indentation. So if it is obligatory lets resign from { and } brackets. Their are unneeded and deprecated. Lets use Python!

8) are you using standard arrays (static or dynamic) at all (like: int a[5] or int* b = new int[5])?

Once again we had a consensus - dynamic tables should be avoided as they can be dangerous.
When I think about them two quotes comes to my mind:

C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.

-- Bjarne Stroustrup

With great power comes great responsibility.

-- Voltaire

Other

On a side note - this is probably the longest most in my career.
If anybody is interested I used Syntax highlighter to post the code. It offers nice looking code but embedding small portions of code is cumbersome - you have to edit html code and doing it through the browser is a pain.

Summary

I hope you enjoyed this long, over 9000 signs comparison. By no mean I was trying to defame C++. I think it is an important programming language, that has its uses (C for microcontrollers, some high performance routines and libraries). Just in my opinion the new additions to C++ (C11, C14) that tries to convert it to modern programming are a failure. They change many things upside-down, make the code much different to understand for people that are not familiar with new standards while the code is still not as elegant and readable as Python. It is just my two cents, opinion that is probably heavy influenced by my experience - I did a lot of programming for embedded systems (microcontroller based).



If, by some accident, you are still not convinced about Python greatness you are not alone. Apparently some people think Python is overrated ;)

TL; DR

This post describes why I think Python is a great language, especially when you are starting learning how to program. Different simple exercises were done in both Python and C++ and the code was compared. Python rulez.

Wednesday, December 30, 2015

I became a Python zealot!

Some time ago I started solving coding puzzles from codingame webpage. I mentioned it in a previous blog entry. I am doing all the puzzles in Python as a way to learn this language. Currently I have done all easy, all except one medium, half of hard and half of very hard. You can find solutions on my github account.

Thing that I would like to share with you today my dear reader is my findings about Python language.

Let me give you some background:

I learned some basics Pascal in a high school (using the Free Pascal IDE, yes the blue one pictured below!) and created a master mind game (you can admire this marvellous piece of work here).


Then I started my studies - Control Engineering and Robotics and learned C and C++. It was during medieval ages, harsh and dark times without vectors, list and all other shiny things kids play with these days. I prepared my own double-linked list, stack, queue through the pain and hard work.

On a second year, way before it was introduced on lectures I started working with microcontrollers and after short stint using asembler (I still have one of the programs I wrote, check it HERE) I switched to programming them in C. At that times the mighty AVR Studio 4 was considered a state of the art IDE, with no code completion and ugly looking font! All of this skewed me away from the objective C++ and made me favour C.

After the second year of studies I started additional field of studies - Computer Science. There I have learnt that C# is a great way to write programs with windows, buttons and so on. I also got to know collections, generic types and a world without pointers. On the other hand I was introduced to image processing library called OpenCV (during glory days of C api with IPLImage and manual memory managment <yay>). What is funny is that you can still found a lot of advices and code examples related to old OpenCV APIs. During that times I just coded - if there was a task, I did it, did not have any favourite language - I used what was best suited - C for micros, C++ for image processing, C# for windows apps. I did not know about unit tests, refactoring, clean code theories, version control systems (!) and other things. There were just problems that had to be solved. If the problem was small enough I was able to finish it fast, if it was rather large I was suffering because of my unawareness of  proper code management techniques. I drifted far away from the main point that I was planning to make - during all that time I did not find my go to language.

Diving into Python

Last year a friend (thanks a lot Marek!) convinced me to try Python. At the beginning I was sceptical as I thought that the same thing can be achieved with C# or C++ with heavy usage of standard library (especially with new things from C++11). Boy I was wrong! During this year I wrote some programs with Python:
and solutions for codingame puzzles:

After the last one especially I came to conclusion that Python is a great language to start your programming journey. This is somehow important to me as I am teaching programming at the Poznan University of Technology. Earlier, I was teaching students how to solve problems using C/C++ programming language and I did it with passion. Nowadays I am doubting if it is the best way and it is because of Python. I tried to convince my colleagues about Python superiority but they are stubborn so I will try to convince YOU, the reader. Try solving following problems in C++, while I will do them in Python and we will compare the solutions in the instalment of this series (I sent the questions to a few friends and if they accept I will post their solutions too). Here we go:

* you can use any collection you find appropriate for the task (vector / list / other). Same goes for strings / arrays of chars.

1) lets assume we have to collections and would like to print values in the following format:
value_0_from_first_collection, value_0_from_second_collection
value_1_from_first_collection, value_1_from_second_collection
etc

2) lets assume we have a text and we would like to print it without the first and the last sign. In addition print text length.

3) we have a collection of values and we would like to prit it without the first and the last value. In addition print collection size.

4) we have a function that has to return:
a) two values,
b) three values.
How would you implement that?

5) for collection of your choice do:
a) print all values,
b) increase each value by 10,
c) remove last element,
d) remove n-th element,
e) print value alongside its index,
f) check if value x is in collection,
g) check if all values are smaller than y.

6) having a text count how many letters are lower-case and how many are upper-case

7) is there any situation that you do not use indentation?

8) are you using standard arrays (static or dynamic) at all (like: int a[5] or int* b = new int[5])?

TL; DR

My programming history was presented. It is full of entertaining and absorbing adventures (who would contempt some asembler and pascal code!) that you should read carefully. Also Python is the thing right now. At the end I ordered you a homework that you have to do and post the solution in the comment section below!

Saturday, December 19, 2015

The Witcher 3: Wild Hunt - Hearts of Stone review

I thought that the previous blog entry about Witcher 3 was sole exception from technical oriented topics that I planned to discuss here. But the CD PROJEKT RED did it again. They created expansion that is in my opinion much better than the original game, which was a masterpiece on its own.

Most elements (graphics, control system) of the game are the same. You can find details in my previous review. Treat this as an incremental review - I will only mention elements, which are improved:

!!! WARNING - spoilers incoming !!!

Plot

Original story was good. That is all, just good. Here on the other hand the writing is the best part. The main story of the expansion is well written with some twists and a lot of connections to the real world. It is loosely based on polish legend about Pan Twardowski and some characters are looking and acting as they are polish szlachta (difficult to explain - check wiki). The best quest is in my opinion the one where you go to the wedding with your old friend Shani to party hard while sharing your body with ghost. A-W-S-O-M-N-E-S-S to the limits. This part has a lot of cut-scenes and dialogues so it is not your typical action RPG, but rather point and click adventure, but it is fabulous. I could be a little bit biased as I have re-read all the books about Geralt prior to playing Heart of Stone and just enjoyed every second it this universe. Even just riding around, sightseeing on my trustworthy roach was enjoyable. Of course in comparison to mentioned epic wedding quest some others can look bleak, but the overall writing level is much better than the original Witcher. On a side note - there are some some really funny jokes, which in polish version are somehow specific to Poland like joke delivered by typical Janusz or an offer to take a lone in foreign currency.

Characters

Some characters were great in original game (best pal Zoltan), while some were not up to that level (especially the antagonists - they were just meh). Here we have great and even greater characters. Olgierd von Everec, the immortal nobleman, Gaunter O'Dimm, the devious mystery man, Vlodimir - the crazy wraith, oh-so cute Shani and Iris von Everec - Olgierds wife that you met in other dimension - all of them are convincing and you can sympathize with them. I really considered my words when talking with them and was really engaged in what I was doing. It should be noted that the game is well balancing the serious moments and characters with funny ones. On a side note - after I finish the game I eagerly checked who was Gaunter O'Dimm, what other players found out and more. I spent some additional time reading about other choices, and getting better info about characters.

Sound

The voicing of polish version is great, especially Gaunter O'Dimm and a song that village children sing about him. You can check even better (played during the final, more psychodelic one) version here:


Music and actors made me curious how it fares in different language. As I enjoyed how dwarfs (english Zoltan is better than polish one!) and Novigrads villans sounded in original game (even if it was difficult for me to understand them fully), the expansion characters are much better in polish in my opinion.

Fighting

Minor thing, but surely an improvement. The fights in Witcher are solid and just good. The combat is responsive, but the bosses and minibosses are not posing a challenge, does not have special powers that makes you fight accordingly. That changes in the expansion. Even though the focus is on story, the combat was much more rewarding. Learning how to fight the caretaker was fun and killing him without taking any damage felt great!

Time required to finish

I have to mention it - the expansion was advertised as offering 10 additional hours of playing, but it took me much more than that. Maybe it is because I was doing everything really slowly and enjoying every bit of it.

TL; DR

Hearts of Stone expansion is an improvement over original game in almost every aspect it was lacking. I can give it only one rating:

Over 9000! Kappa

Thursday, November 19, 2015

Programming quotes

I have few posts written, all filled with ideas and a lot of raw text. I wanted to post each of them a long time ago, but I always postpone it for later, to finish it, than get new idea, start working on it and never finish the old ones. Today I decided to start and finish post to convince myself that I am able to do it!

As you know I am doing puzzles from codingame webpage (this post describes it). I am doing my best, but still did not cracked top 100 (I am ranked at 132). While solving some problems I found that I am often reinventing the wheel - due to my poor knowledge of algorithms I am wasting a lot of time discovering simple things (e.g. graph algorithms...). I decided that even though they say you can not teach old dogs new tricks I will read Algorithms in a Nutshell book to raise my skills to the next level! There is interesting quote in the introduction that I quickly inserted into my collection of programming quotes. Then I decided to share my little collection, maybe it will be helpful to somebody. So here we go:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
-- Brian W. Kernighan


premature optimization is the root of all evil
-- Donald Knuth


Modern software development is not about being an ace programmers anymore. It is about being a team player that empowers co-workers with:
Elegant design.
Easy to read and commented code implementing it.

-- Fabien Sanglard, http://fabiensanglard.net/


Any code of your own that you haven't looked at for six or more months might as well have been written by someone else.
-- Eagleson's law


Projects just seem to rot when you leave them alone for long periods of time.
-- John Carmack


There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton


Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
-- Douglas Hofstadter


Later means never.
-- LeBlanc’s Law


C++11 feels like a new language.
-- Bjarne Stroustrup


Write lasagne code instead of spaghetti code.


Great Developers Know When Not To Refactor. If it ain’t broke, don’t fix it.


Perfect is the enemy of the good.


Release early, release often.


If the physics allows then it can always be solved given enough money – which just means finding a big enough market.
-- notzed comment @ CNXSoftware


TL; DR
In the post I shared my collections of programming quotes that I found somewhere on the Internet and think that they are useful.

If you have your favourite quotes please share them in the comment section below!

Saturday, October 17, 2015

Codingame - fun way to hone your programming skills

Some time ago a friend show me a webpage where you can polish you coding skills while having fun!

There are a lot of sites that offer programming tasks / exercises. Usually you get the instructions and when you have prepared the solution then you can upload it as a source file. It is then tested and at the end you are provided with the information about the results of you program (if it work as it should or if it does not work).

The main advantages of CodinGame site are:
  • number of languages accepted (23),
  • online editor with autocomplete function and three styles (e.g. Vim / Emacs),
  • well defined tasks with a lot of well-thought out test cases,
  • the ability to debug your program round by round,
  • fancy and nice looking graphics and animation (I know that it is not the most important part, but it makes solving the task more appealing, especially to begginers) alongside console output to help with the debug process,
  • achievements ;)
You can visit the site by clicking the image below:


The site offers few types of competition:
  • single player puzzles,
  • multi player,
  • optimization,
  • online clashes,
  • live contests.
Today I will focus on the first type - single player puzzles. This is the oldest feature of the site and there are 52 puzzles with different difficulty levels. On each of the level you get the task description, which states what the program has to do alongside with detailed information about  the input that is provided and the output expected. Usually some initial information is given at the beginning and then the puzzles are played in turn-by-turn way - you are given current state and have to provide the output - your action. For each task there are well defined test cases that starts with very simple ones, that can often be passed with simple, naive solution. Each test is more and more difficult and checks your program against different input data (edge cases) or tests performance of your code (so that you use something more refined than bruteforce solutions). In addition to this some of the puzzles has graphic animations of what is happening so it feels like you are playing a game and in the end you even get achievements! What is even better - it can land you a job!

 All in all I can wholeheartedly recommend the CodinGame website for both the advanced programmers and to beginners. Great way to improve coding skills while having fun!

Also you can find my solutions on my github:

https://github.com/Michal-Fularz/codingame_solutions

at the moment I have all easy puzzles done in Python (2.7.x). Some others (medium / contest /clash of code) are work in progress. Please take into account that I am learning Python language currently. If you find errors or non-pythonic code let me now. I would like to improve my Python skills as I enjoy the language a lot. 


TL; DR

CodinGame is a webpage with coding puzzles done right - they are interesting and fun to do. Also you get achievements on your way and can even get a job!

Wednesday, July 8, 2015

The Witcher 3: Wild Hunt review

I'm a gamer. I play computer games and watch esport (people competing in computer games, like in sport, but using the computer, you know) in my free time.

Some time ago a third instalment of a Witcher series was published. I bought it last year on gog.com (great, great and one more time great, site! Go and buy something there, its full of games from our youth!). This game and a busy schedule at of work are the ones to blame for lack of posts. What's funny is that despite over 70 hours I still didn't finish it! This short review is my way of getting back to regular updates!

Settings:

I'm playing the PC version using an Xbox gamepad. Most of the graphics settings are set to high with Nvidia Hairworks turned off.
Graphics:
The most talked topic about graphics of the Witcher 3 (especially on PC) is the DOWNGRADE... I don't care that much about  it cause the gameplay is the most important part IMHO, but the topic is interesting from technical point of view. Looking at some comparisons  it is clearly visible that the devs didn't take the heat for nothing. Because of low computing capabilities of current gen consoles (relatively to the mighty graphic cards available for PC) a lot of games is prepared in a way that they are playable on both the PC and consoles and does not differ too much in visual department (also why implement some sophisticated effects that works only on a smallest platform?).

For me the visuals are OK, the game looks great (I rarely play graphic intensive and new games). As always there is room for improvements, but the overall subjective (my!) opinion is that it's the best looking game I played :)

The world:

Andrzej Sapkowski (the guy that wrote books that the game is based on) created a magnificent world - it's complicated, with more shades of gray (pun not intended!) than white and blacked summed up. There's a lot of hatred, prejudice and ignorance. People are caring for themselves and and nothing more, cruelty and envy is common. I would say that the setting is rather depressive, but I love it (currently reading all the books again!).

I was a little bit afraid of the open world - I loved Witcher 2 for its closed, rather small area. I was able to search every inch in reasonable time and I like / feel the urge to explore every little corner. That's why Skyrim was too much for me, it was overwhelming. I travelled to the first city, took some quests, checked some buildings, than run somewhere, and out of nowhere some mountain giants is throwing me in the air... Decided to run in other direction, found some dungeon, searched and found out I can't kill the end boss. Had to go back the same route, run in different direction... Then I learned that I can have my house and so on... Waaaay to much for me to handle. On the other hand I liked the batman games (Arkham Asylum and City) - it was interesting main story + some additional content, which does not felt necessary to do (riddles).  Going back to the Witcher 3 - the world is huuuuuge and is filled with interesting places and quests to do. There are no: "The goblins stole my precious potato, go and get it back for the sake of my ancestors... blablabla". Most of them avoid being general fetch quests and usually offers nice story and some detective work to do. Each and every is well written and offers something - a lot of lore is hidden in those quests and you can learn new facts about the world. The main story is interesting, but I would rate Witcher 2 higher (the decisions in Witcher 2 were harder to make).

Fighting:

The fighting is responsive and fun. It consist of a few moves - dodge, roll, fast/strong sword attack, parrying, magic signs and bombs. Most are executed well  but after some time I found fights a little bit repetitive (probably because I play too much). I would rate Kingdoms of Amalur (more satisfaction), Batman (so easy to do cool things) and Sleeping Dogs (those combos) fighting systems a little bit higher, but only a little. They gave more satisfaction and were easier to execute, but the multitude of actions and the need to dodge/parry most hits (the monsters hit hard in this game) is really suitable to the Witcher settings.

RPG elements (level, items):

The skill system is original and interesting. On one hand it offers a lot of different options, but on the other hand it limits you which ones you want to use at the moment. It's not typical action RPG system (like Diablo 2), it has its own depth and I would say it is well balanced. There's also a way (pricey) to reset your skills if you went wrong way.

As skills are well designed the inventory is not. It's terrible! No storage space for you to hoard all the unique weapons and other stuff (books / crafting materials / alchemy ingredients). I quickly ended with the inventory filled up with stuff and Geralt overweighted and slowed down. WHY? I just don't understand the decision making behind it. In addition to very limited space the world is filled with items to pick up (food and drinks lying everywhere, can't resist taking it all). Fortunately the community has prepared the solution - weight mod. Go get it and don't worry about overweight any more.

Other:

The game has some minigames in it and one of them (the Gwent card game) is really fun to play. Add some more cards, better AI and it can be a standalone title!

It's very sad that this will be the last time we roll with Geralt (as developers said). There is possibility for next game in series but the lovely Geralt won't be the protagonist. So use it to the fullest and explore the wonderful grim world of Witcher 3.

TL; DR

The Witcher 3: Wild Hunt is great game with nice graphics, immersive atmosphere, interesting and full open world, great quests, good RPG elements and horrible inventory system. Despite some minor problems and great but not the best in the industry elements (fighting / skills) it's well executed and very addictive game. All in all I rate it:
10/10!
It is a must-play for any gamer.