11 март 2016 г.

CODE TIPS #2 - Stop "using namespace std;" (C++)

Много често виждам в програми/примери за C++ използването на именното пространство "std", което представлява стандартната библиотека от функции на C++.

Оказва се, че този код не е част от добрата практика:

BAD
  1. #include <iostream>
  2. using namespace std;    // avoid this

  3. int main() {
  4.     cout << "I like pickles." << endl;
  5.     return 0;
  6. }


Защо? Простото обяснение е, че могат да се появят конфликти когато използваме други библиотеки, които потенциално могат да имат идентични имена като тези на функциите (и не само) в стандартната библиотека.


Например нека имаме 2 библиотеки с имена MyLib и OtherLib.

Да речем в MyLib имаме функцията myFunction(), а в OtherLib функцията otherFunction(). Всичко е OK, спокойно можем да импортираме тези функции и да ги извикваме безпроблемно.

Но един ден се налага да обновим първата библиотека и сега сме с MyLib 2.0, която за нещастие сега също има функция, която се казва otherFunction(). Лошо! Сега, когато извикаме otherFunction() в кода си, не е ясно кой код точно ще се изпълни. Може да ни се размине ако функциите са с различни параметри, но наистина не си струва рискът.

Решението e много просто и има потенциал да ни спести много главоболия. Ако се върнем към първоначалния пример със "std", единствената промяна, която е нужна, е да назовем името на съответното именно пространство. Тоест:

GOOD
  1. #include <iostream>
  2. int main() {
  3.     std::cout << "I like pickles." << std::endl;
  4.     return 0;
  5. }


"Но това е толкова досадно, всеки път трябва да назовавам именното пространство!" - няма проблем, защото има и алтернатива:

ALSO GOOD
  1. #include <iostream>
  2. using std::cout;
  3. using std::endl;

  1. int main() {
  2.     cout << "I like pickles." << endl;
  3.     return 0;
  4. }

Аналогично може да приложите горния код за std::string или структури като std::vector, std::list и т.н. Изключително дребна промяна, която не коства нищо, а носи огромна полза.

9 март 2016 г.

Алгоритъм за решаване на задачи по програмиране

"Въведение в програмирането със C#" на Светлин Наков е първата книга по програмиране, която завърших. Пълна е с полезна информация и наистина я препоръчвам на всеки, който има интерес в сферата или тепърва започва (макар че смятам, че дори и напреднали програмисти ще имат какво да научат, просто защото някои неща се забравят). Напълно безплатна е, така че се залавяйте!

Въпреки всичката полезна информация представена в книгата, най-много ми хареса главата за решаване на задачи по програмиране. В нея бяха представени различни идеи, които улесняват решаването на по-сложни задачи и подобряват качеството на самото решение.



Аз извлякох тези идеи и ги подредих в малко по-синтезиран вид, наподобяващ алгоритъм, но не баш. Общо взето, това което научих е, че решението на една задача се свежда до измисляне на добра идея и имплементацията на тази идея (под формата на код, в контекста на програмирането). Ето как изглежда като цяло:

1. Идея:
  - Разбийте задачата на подзадачи
  - Генерирайте идеи
  - Тествайте идеите
  - При проблем измислете нова идея

2. Имплементация:
  - Подберете структурите от данни
  - Помислете за ефективността
  - Пишете стъпка по стъпка
  - Тествайте след всяка стъпка

BROTIPS:
- Използвайте лист и химикал!
- Търсете в Google!

Толкова прост метод, но ефективен! Не е нищо ново като информация, но се учудих колко приложим е този подход не само в програмирането, но и във всичко останало. А сега отивам да тествам...

7 март 2016 г.

CODE TIPS #1 - Контра-интуитивната индентация и скобите в LISP

OK, наскоро започнах да изучавам функционален език за програмиране (LISP) и ми направи впечатление следното нещо:

Толкова. Много. Скоби.


Credits: XKCD


Зачудих се как е възможно подобен код да е четим за когото и да било. Вече очевидно никой не се интересува от това... :(

Първото ми предположение беше да подредя кода както бих го подредил в стил "всеки друг език за програмиране":

BAD
  1. ;; Well, ain't that cute...
  2. (defun f (x)
  3.     (cond
  4.         ((= x 1337) x)
  5.         (nil)
  6.     )
  7. ) ; ... but it's WRONG.

Оказа се, че конвенцията не само е против излишните празни места, но дори редове само с по една затваряща скоба на тях се считат за лоша практика. Стига де!

Имайки това предвид, за по-удачен вариант се смята следната версия:

GOOD
  1. (defun f (x)
  2.   (cond ((= x 1337) x)
  3.         (nil)))

Основната разлика:
- по 2 интервала на нов ред
- аргументите се подреждат един под друг
- затварящите скоби не се изолират на цял ред

Индентацията добре, но скобите защо така?? Обяснението, което намерих, е че опитните Lisp програмисти не обръщат внимание на броя на скобите, а се съсредоточават върху това, което се случва между тях. И втората причина е, че просто се цели минимизирането на редове код (което според мен е по-рационалната причина).

Странно, но ще свикна...

6 март 2016 г.

КАК ДА СТАНЕМ ДОБРИ ВЪВ ВСИЧКО

Кратък отговор: не можем.
Дълъг отговор: можем, но на цената на това да не сме толкова добри в други неща.

Лично аз не съм намерил начин да съм на повече от малко над средно ниво във всичко, което опитвам, ако целта ми е балансиран живот, който включва неща като финансова стабилност, добро здраве, добри взаимоотношения с околните и т.н.

Въпреки това можем да станем приемливо добри в доста неща.

Според мен съществуват общо взето 2 стратегии за "успех":
- да станем НАЙ-ДОБРИТЕ в 1 нещо (и само 1)
- да сме "OK" в доста неща

Просто няма как Майкъл Джордан да е най-добрият баскетболист и най-добрия пианист едновременно. Няма как Моцарт да е велик композитор и едновременно спортист на световно ниво.

Енергията ни е ограничена и е наша отговорност да намерим правилния начин да я използваме (според личните ни цели и възгледи за "успех" в живота).

И двете стратегии си имат плюсове и минуси. На пръв поглед по-привлекателната идея сякаш е да сме "най-добрите", но помислете какво би ни струвало това.

Да речем че искам да стана най-добрия програмист в света. И по цял ден правя само това - програмирам, програмирам, програмирам. В резултат на това, действително ставам изключителен програмист, защото съм вложил толкова време и усилия, но в същото време съм забравил за здравето си и вече 10 лицеви опори се превръщат в предизвикателство. Освен това съм забравил всякакви приятелски връзки и се чувствам самотен. Хубавото е, че съм на световно ниво и вероятно ще се движа с лекота в сферата, в която искам да се развивам (било то програмиране или каквото и да било). Но колко неща трябваше да жертвам, за да стигна това ниво?

От друга страна, мога да съм "OK" (на средно или малко над средно ниво) в повече неща. И така, сега не съм най-добрия програмист. В най-добрия случай съм малко над посредствен програмист, който не е ходил на стотици олимпиади, няма медали от състезания или гениални постижения, но пък обича това, което прави, склонен е да се учи от грешките си и винаги търси развитие. Освен това съм в добро здраве и не съм заличил идеята за социален живот. Но пък не съм нищо специално откъм "skills"... така че и тази стратегия не е перфектна.

Както и да е, нека минем по същество...

КАК ДА СТАНЕМ ДОБРИ В НЕЩО?


Забелязах, че има "pattern" (повтарящ се модел) всеки път когато искам да стана по-добър в нещо.

Обикновено първото нещо, което се случва, е нещо лошо, което ми напомня "пич, не си добър в това и ще имаш проблеми ако не промениш сегашното си положение". Помня, че точно това се случи преди да започна да спортувам street workout по-активно. Бях на много ниско ниво (не можех да се набера нито 1 път) и ми беше много тежко отвътре като виждах как връстниците ми с лекота си правиха силови, коремни и т.н.

Второто нещо или втората "фаза" е тази, в която се вманиачавам в търсенето на информация по въпроса. Започвам да търся ресурси, истории на хора били в моето положение (хора, които са успeли въпреки това), мотивация и конкретни стъпки, които мога да следвам, за да стана по-добър.

Третата фаза е най-тежката - имплементацията. Иначе казано - да вкараш плана в действие. Обикновено в този етап имам ниско самочувствие, защото за дълъг период от време се очертава да съм МНОГО ЗЛЕ в това, което правя. Съмнения от рода на "струва ли си това", "на прав път ли съм" и т.н. постоянно циркулират из главата ми. В началото прогресът ми е минимален и много пъти искам да се откажа. Помня, че точно това се случи когато започнах да програмирам - бях отчаян и не знаех какво да правя, защото дори най-елементарните задачи ми се струваха невъзможни, не схващах логиката и бях доста изплашен.

Ако стигна до следващата фаза - нещата стават по-добре. Вече имам забележим прогрес и дори не ми прави впечатление, защото имплементацията вече е част от ежедневието ми (свикнал съм да правя нещото, в което искам да стана добър). Докато се усетя - вече съм сравнително добър в конкретното нещо. От там зависи само от мен дали желая да стана още по-добър в това нещо или просто да "поддържам" сегашното си ниво, но като цяло е значително по-лесно.

Това е процесът, който се повтаря всеки път. Ако трябва да го опиша с графика - нещо от този род е:

Credits: kratosguide.com


ЗАПОМНЕТЕ ТЕЗИ 3 НЕЩА


За да формулирам процеса в по-достъпен вид, ето какво се иска от вас, за да стигнете от точка A (хипер зле) до Б (not bad).

1. ЗАОБИКОЛЕТЕ СЕ ОТ ТОВА, В КОЕТО ИСКАТЕ ДА СТАНЕТЕ ДОБРИ

Това включва:
- намерете техническа информация ("how to conquer the world" в Google)
- четете книги / гледайте клипове, които ви информират и вдъхновяват
- намерете хора, които са минали по този път и ще ви вдъхновяват/окуражават
- ВСИЧКО друго, което просто ви напомня "това е постижимо и си струва"

2. ПРЕВЪРНЕТЕ ГО В НАВИК.

Казват, че ако вършите нещо всеки ден за около 66 дни - то се превръща в навик, т.е. се автоматизира и започвате да го правите без да се замисляте. Според мен зависи. Някои навици се формират за по-малко време от това, докато други изискват повече повторение. От вас се иска само едно нещо - упражнявайте се ВСЕКИ ден. Не е важно колко време ще отнеме. Насладата е в пътешествието, а не дестинацията (не се сдържах да използвам един cheesy цитат).

3. В НАЧАЛОТО НЕ ОЧАКВАЙТЕ РЕЗУЛТАТИ

В началото ще сте зле. Няма друг начин. От изключително значение е да нямате големи очаквания, защото това ще ви накара да се откажете. Просто действайте всеки ден и ВЯРВАЙТЕ в процеса и във факта, че ще станете по-добри с времето. Аз лично много съм патил от игнорирането на тази част. Големите очаквания ви карат да се съмнявате дали сте на прав път и дали си струва да влагате толкова усилия. Просто НЕ го правете (trust me)!

---

Това е! А сега действайте!

21 февруари 2016 г.

Какво ни мотивира да действаме? (book summary)


"Drive: The Surprising Truth About What Motivates Us" на Daniel H. Pink

Интересна книга за това какво реално ни мотивира да действаме.

Книгата представя 3 вида мотивации:
- Мотивация 1.0 - най-примитивната ни биологическа мотивация - да оцелеем
- Мотивация 2.0 - награди и наказания
- Мотивация 3.0 - вътрешна ("интринсивна") мотивация

Най-добрата мотивация е Мотивация 3.0 (вътрешната), която общо взето означава, че правим нещо просто защото ни ХАРЕСВА да го правим. Тя работи благодарение на 3 компонента:

1. Автономия
Свободни сме да свършим задачата пред нас по свои правила.
2. Майсторство
Задачата развива нашите умения и ни приближава към "майсторство" в това, което правим (ключът е в състоянието на "flow", обяснено най-отдолу).
3. Висша цел
Това, което правим, е част от нещо по-голямо от нас самите и действително си струва да се свърши, защото ще подобри света по някакъв начин.

Авторът смята, че в днешно време преобладава Мотивация 2.0 (особено на работните места) и хората работят, само за да избегнат наказания (например да бъдат уволнени) или за да получат някаква награда (например месечна заплата).

Такъв вид мотивация е предимно неефективен, защото:
- убива креативното мислене на хората (фокусът ни отива към наградата и ограничава мисленето ни)
- понижава продуктивността ни (безразличие)
- създава зависимост (ако не получим наградата - няма причина да работим)

Мисленето в стил Мотивация 3.0 не е нещо, с което се раждаме, а е нещо, което можем да развием в себе си след като знаем изграждащите го принципи.

Състояние на "flow":
- знаем КАКВО трябва да направим
- знаем КАК да го направим
- знаем дали се СПРАВЯМЕ със задачата
- задачата е ТРУДНА, но ПОСТИЖИМА
- напълно концентрирани сме в това, което правим
- губим всякаква представа за време/странични проблеми
- чувстваме вътрешна наслада