რატომ (არ) შესტკივათ ადამიანებს გული ერთმანეთზე

პოსტი პროგრამირებას არ ეხება და ახალიც არაფერი წერია შიგნით : )

გარშემო ახლა ცუდი რაღაცები ხდება. უფრო სწორად, სულ ხდება, უბრალოდ ახლა ჩვენთან ახლოს ხდება. მაგ მნიშვნელოვან თემებზე სხვები დაწერენ, ჩემი ადგილი იქ არ არის, მაგრამ მე მაგის გვერდით მოვლენაზე მინდა დავწვრილმანდე. პარიზის ტრაგედიას ყველაფერთან ერთად ერთი ტალღა მოჰყვა ხალხში, სადაც ერთმანეთს გულგრილობაში ან შერჩევით სამართლიანობაში ადანაშაულებდნენ. არ მივაქცევდი ალბათ ყურადღებას, ჩემი თავიც რომ არ შემენიშნა ‘გულგრილობაში’. პარიზი იქნება, ბეირუთი, ავღანეთი თუ აფრიკაში შიმშილით დახოცილი ბავშვები, ფაქტია, რომ არ მიგვაქვს გულთან საკმარისად. ანუ საკმარისად იმისთვის, რომ რამე შევცვალოთ. რაღა შორს წავიდე, მე თვითონ დისნეის მულტფილმებზე ცხარე ცრემლით ვიტირებ, მაგრამ ბევრი რეალური ამბავი საერთოდ არ ამაღელვებს.

ჰოდა რატომ არის ეს სიახლეები უბრალოდ სიახლეები, ან რატო არ იწვევს არანაირ თანაგრძნობას ჩვენი ისტორიის წიგნი, წინაპრების ომები, სისხლისღვრა და თავგანწირვა, რატომ არის ტიტანიკის ჩაძირვა მშრალი ფაქტი, როცა იგივე სახელის გამოგონილი ფილმი ზოგს ცრემლს მოადენს, თანაც სულ ორი ადამიანის გამო. რამდენად შორს უნდა იყოს შემთხვევა დროს ან მანძილში რომ მნიშვნელობა დაეკარგოს ჩვენთვის? მე, ცხადია, კომპეტენტური არ ვარ მაგ საკითხში, ამიტომ დავუჯერებ ნეირო მეცნიერებს.

მთავარი სიტყვა აქ არის ემპათია, იგივე თანაგრძნობა. ეს თვისება ადამიანებს ხო ევოლუციურად მოგვდევს და გვჭირდება გადარჩენისთვის (ისევე როგორც მაგის მართვა გვჭირდება კრიტიკული სიტუაციების გასამკლავებლად). თანაგრძნობისთვის კი აუცილებლია ერთი რამ – კავშირი. ერთმა ადამიანმა მეორესთან უნდა გააიგივოს თავი, კავშირი უნდა იპოვოს და იგრძნოს რასაც სხვა გრძნობს. ერთ-ერთი გზა არის დაფიქრებით, აღქმით და წარმოდგენით. ან კიდევ შეიძლება ემოციების წაკითხვით. თუ იქნება ეს კავშირი, ის იგრძნობს, რადგან ჩვენში არის შესაბამისი მექანიზმი – შეგვიძლია სხვისი ემოციების, ტკივილის ან სიხარულის ამოცნობა, არის შემთხვევები, როცა ფიზიკურადაც კი განვიცდით იგივეს (სარკული ნეირონების დამსახურებაა ეს თუ სხვა რამის, არ ვიცი, მაგრამ ხო ფაქტია რომ შეგვიძლია). თუ ვინმეს არ შეუძლია, ეს გადახრაა ან დაზიანება, და შესაბამისად ჩნდებიან სოციოპატები ან ფსიქოპატები. ამ ნაკლის გამო ისინი ვერ არჩევენ ემოციებს იმ გზით როგორც ჩვენ და არ აქვთ თანაგრძნობის უნარი – შეუძლიათ მოატყუონ, მოკლან, აწამონ და ვერ მიანიჭებენ ამას მნიშვნელობას.

გადავუხვიე ახლა. იმას ვამბობდი, რომ კავშირი არის აუცილებელი კომპონენტი. როდესაც ახლოს ხარ ტრაგედიის ადგილთან, ან ესაუბრები ადამიანს, ან ფოტოს უყურებ, ან წერილს კითხულობ მისი საყვარელი ადამიანისადმი მიწერილს, მაშინ შენც განიცდი. სამწუხაროდ თუ საბედნიეროდ ახლა მედიას აქვს მაგის ძალაუფლება, რომ ვისთანაც სურს, მასთან დაგვაკავშიროს, გულზე მჯიღი დაგვარტყმევინოს ან აგვამხედროს კიდეც ვინმეს წინააღმდეგ შესაბამისად. მწერალსაც აქვს. ფოტოგრაფსაც აქვს. რეჟისორსაც. პრინციპში დღეს სოციალური ქსელის საშუალებით თითოეულ ჩვენგანს აქვს რაღაც ოდენობით (ყველაზე ნაკლებად კი მე მგონი ამ სიტყვებს აქვს “ოდესმე შენამდეც მოვლენ და მარტო იქნები”, იმიტომ რომ არანაირ ემოციებს არ უკავშირდება).

რატომ იყო პარიზი და არა ბეირუთი? შერჩევითი სამართალი არაფერ შუაშია ჩემი აზრით, უბრალოდ ჩვენი თავები ევროპასთან უფრო გავაიგივეთ. წარმოვიდგინეთ, ერთ ჩვეულებრივ დღეს, კაფეში ან კონცერტზე ჩვენს ახლობელს რომ შეემთხვეს იგივე. მაინცდამაინც კარგად ვერ ვაკავშირებთ თავს ბეირუთთან ან სირიასთან ან თუნდაც აფრიკასთან, სადაც მუდმივად იბრძვიან ადამიანები სიცოცხლისთვის. მე მგონი ასევე დიდად ვერ ვაკავშირებთ უამრავ ქართველთან, რომლებიც ძალიან რთულ გზას გადიან ამ ქვეყანაზე. ვერ ვაკავშირებთ მთის სოფლებთან, სადაც არანაირი პირობები არ არის ცხოვრების. ვერ ვაკავშირებთ ვერც ვაკის სოფლებთან, სადაც მიწას შეჭიდებული ხელები ბერდებიან და მომავალი უკეთესი არ ხდება; ვერც ქართველ ბავშვებთან, რომლებიც ოჯახის სითბოს გარეშე იზრდებიან; ვერც იმ ბავშვებთან, ვინამდეც წიგნი და ინტერნეტი არ მისულა; ვერც მაგალითად უსინათლო ადამიანებთან, რომლებიც დამოუკიდებლად ცხოვრებას ვერ შეძლებენ ჩვენთან; ზოგჯერ ვინმე ღვთისნიერი მოიტანს ჩვენამდე მათ ემოციებს და ჩვენც ვპოულობთ კავშირს. სხვა მხრივ კი ვართ ასე გულგრილები : )

რას ვიზამთ.. არ ვიცი. შეუძლებელია ადამიანმა დაიტიოს ყველას სევდა და მაინც პროდუქტიული დარჩეს. ამიტომ ვცვლით რაც შეგვიძლია. რაც არა, იმის ტვირთად ტარება არ გამოდის..

მილიარდ დოლარიანი შეცდომა

ასეთი სახელი ჰქონდა ტონი ჰოარის პრეზენტაციას 2009 წლის კონფერენციაზე სადაც პროგრამირების ისტორიაში ცუდი გადაწყვეტილებების შესახებ იყო მოხსენებები. მე მხოლოდ შარშან ვნახე და მას შემდეგ კიდევ ბევრმა წყალმა ჩაიარა, მაგრამ პრინციპში დღესაც აქტუალურია ეს საკითხი და მე მგონი ცალსახად ეფექტური გამოსავალი ჯერ ჩამოყალიბებული არ არის.

პრეზენტაცია 1965 წელს გამოგონილი null reference-ს ეხებოდა, რომელიც მილიარდ დოლარიან შეცდომად შეაფასა მისმა შემქნელმა:

“I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.”

რეალურად, მე არ ვფიქრობ რომ თვითონ null reference-ის შექმნა იყო არასწორი, რადგან მის გარეშე ალბათ ძალიან ძნელი იქნებოდა თუნდაც OOP პროგრამირება, გაცილებით ზედმეტი ლოგიკის წერა და უარესი კომპრომისების და ბაგების მოვლა მოგვიწევდა. ამიტომ შეგვიძლია უფრო type checking სისტემებს დავაბრალოთ null-თან დაკავშირებული პრობლემები. ყოველ შემთხვევაში, ჰოარის პრეზენტაციიდანაც დაახლოებით ასეთი აზრი გამოვიტანე.

კონკრეტულად რომ ვთქვათ აი ასეთ პრობლემაზეა საუბარი (ორაკლის საიტიდან ავიღებ მაგალითს):
წარმოვიდგინოთ ჩანაწერი..

String version = computer.getSoundcard().getUSB().getVersion();

როცა ჯავაში აღვწერთ მეთოდს, მას ვუთითებთ დასაბრუნებელ ტიპს. რეალურად დასაბრუნებელი მნიშვნელობა არ არის ამ ტიპის, არამედ ერთ-ერთია სიმრავლიდან { null, ეს ტიპი }

ფაქტიურად ნებისმიერი მეთოდისგან (რომელიც ობიექტს აბრუნებს) შეიძლება null reference მივიღოთ შედეგად და სანამ ამ შედეგს გამოვიყენებთ, შემოწმება გვიწევს.
ზევით აღწერილი კოდი უსაფრთხო რომ იყოს, ასე უნდა ჩაგვეწერა:

String version = "UNKNOWN";
if(computer != null){
    Soundcard soundcard = computer.getSoundcard();
    if(soundcard != null){
        USB usb = soundcard.getUSB();
        if(usb != null){
            version = usb.getVersion();
        }
    }
}

თუმცა, როგორც წესი, უფრო ხშირად ვცდილობთ რომ ასეთი ჩანაწერი თავიდან ავირიდოთ. best practice-ების მიხედვით რეკომენდირებულია მეთოდი ისე ვწეროთ რომ მან არასდროს დააბრუნოს null, არამედ, ან რაღაცა ცარიელი ობიექტი მიიღოს შედეგად ან checked შეცდომა ისროლოს. ასე ნაწერი კოდი გაცილებით გვაზღვევს runtime-ში null pointer შეცდომებისგან.

მხოლოდ რეკომენდაციების იმედზე რომ არ ვიყოთ, ჯავას მერვე ვერსიაში შემოვიდა Optional ტიპი და ასევე @NonNull @Nullable ანოტაციები და ეს რამე რუმეები საშუალებას გვაძლევს მეტად ინფორმატიული იყოს ჩვენი კოდი და ცოტა კომპილაციის დროსაც მოგვეხმაროს. თუ ვიცით რომ რომელიმე ობიექტი შეიძლება null გახდეს, შეგვიძლია ის Optional კლასის საშუალებით შევინახოთ. და მერე გამოყენების დროს გავითვალისწინოთ ეს საშიშროება.

ჯავაში ასე გამოვიდოდა getSoundcard მეთოდის სიგნატურა:

Optional<Soundcard> getSoundcard()

მერე გამოყენებისას უნდა დავწეროთ

Optional<Soundcard> optional = getSoundcard()
if (optional.isPresent()) {
    Soundcard soundcard = optional.get();
    …..
}

ან სხვა უფრო მოსახერხებელი მეთოდების გამოყენება შეიძლება – orElse, ifElse, ifPresent.. ა.შ.

ზოგ ენაში შემოიღეს მოკლე ჩანაწერიც, მაგალითად Swift-ში შეგხვდებოდათ ასეთი რამ:

var version = computer?.soundcard?.USB?.version

ამ ჯაჭვში ერთ ერთი მაინც თუ დააბრუნებს null-ს, მომდევნო getter-ების გამოძახება აღარ გაგრძელდება და მთელი შედეგი null გამოვა.

Groove ენაში არის ელვისის ოპერატორიც :D რომელიც ასე გამოიყურება ?:

String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";

და მაგითი default მნიშვნელობა შეგვიძლია შემოვიტანოთ null-ის შემთხვევაში.

ბოლო რამდენიმე თვეა რაც Swift-ზე წერას ვცდილობ. ჯერჯერობით ენა არ არის სრულად ჩამოყალიბებული და ხშირად იცვლება. თუმცა ეს კონცეპტი ალბათ არსად წასვლას არ აპირებს. თავიდან ძალიან გამიჭირდა იმასთან შეგუება, რომ ენა გაიძულებს ცვლადის გამოცხადებისთანავე განსაზღვრო optional იქნება ის თუ არა. თუ კი, მაშინ ყველგან სადაც ამ ცვლადის გამოყენებას შეეცდებით, მისი null-ზე შემოწმება და მნიშვნელობის ე.წ. unwrap მოგიწევთ optional ტიპის ცვლადისგან. კოდი არ დაკომპილირდება სხვა შემთხვევაში.

ამ პოსტში ელდარი უნდა დავთაგო : )) ერთხელ მასთან ვიწუწუნე ამ თემაზე და იმ დღეს დამაფიქრა, შემაცვლევინა აზრი. მერე წავედი და გემრიელად დავარეფაქტორე კოდი. არც ისეთი ცუდი ყოფილა ეს optional ტიპი. რაც დრო გადის, ვხვდები, რომ კარგ საქმეს მიკეთებს და მაიძულებს არ გავახალტურო რაღაცები. ასე რომ ვნახოთ.. იქნებ ჯავაშიც გაგვილამაზონ სინტაქსი თორემ დაიკარგება კაცი ამდენ boilerplate კოდში.

CNC მანქანების დაპროგრამება

ორი დღის წინ თსუ-ში მაგისტრატურა დავამთავრე. ჩემი ბოლო სემესტრში შესრულებული კვლევა CNC მანქანებს და მათ დაპროგრამებას ეხებოდა. თემა არც ისე ახლოს არის ჩემს საქმიანობასთან, მაგრამ მაინც საინტერესო იყო ჩემთვის. განსაკუთრებით კი ექსპერიმენტები ამ მანქანების ახალი პროგრამირების ენით, რომლის შესახებაც უფრო დაწვრილებით თემაში მიწერია.

რამდენადაც ვიცი, საქართველოშიც არის პატარა საწარმოები, რომლებიც ასეთი ტიპის მანქანებს იყენებენ, თუმცა პასუხი ვერ მივიღე მათგან.

შემთხვევით ვინმეს ხომ არ ჩაგიტარებიან ექსპერიმენტები ან სახლში აგიწყვიათ მსგავის მანქანა? თემის ბლოგზე გამოქვეყნება მე მგონი შეიძლება, რადგან თსუ-ს კონფერენციის საიტზე სახალხოდ დევს. თუ დაგაინტერესებთ ჩემი მიმოხილვა, ფაილი ამ ბმულზეა :)

lcamtuf_robot1

ყალიბის გაკეთება რობოტის ნაწილებისთვის. ფოტო აღებულია lcamtuf-ის საიტიდან.

othermill

Othermill კომპანია otherfab-ისგან

jobs.ge საიტის REST კლიენტი ანდროიდზე

ალბათ გსმენიათ თბილისის GTUG-ის შესახებ – ეს არის თბილისის Google Technology User Group ქომუნითი, სადაც ჯერ ჯერობით მაინც დეველოპერები ჭარბობენ. ისინი ქმნიან და ერთმანეთს აცნობენ თავის პროდუქტებს, უყვებიან საკუთარ გამოცდილებას. ამიტომ GTUG-ის შეკრებებზე სხვადასხვა ტიპის სემინარებიც ტარდება ხოლმე. მაგალითად იყო მოხსენებები ანდროიდზე, RESTful ვებ სერვისებზე, რჩევებზე თუ როგორ შეიძლება შევქმნათ უკეთესი პროგრამული უზრუნველყოფა, Responsive web დიზაინზე, გუგლის App Engine-ზე, Cross-platform Mobile Development-ზე, Machine learning-ზე (გუგლის Prediction API), GWT-ზე, გუგლის რუკებზე, NoSQL მონაცემთა ბაზებზე, ალგორითმებზე…

როდესაც პირველი შეკრებები ტარდებოდა იქ ლაპარაკი იყო ანდროიდის აპლიკაციებზე. მეც დამაინტერესა და გადავწყვიტე ერთხელ მაინც მეცადა მობილურის აპლიკაციის დეველოპმენტი. საცდელად jobs.ge-ის კლიენტის წერა დავიწყე, რადგან ამ საიტს სახალხოდ ჰქონდა rss წყაროები. აპლიკაციის ნაწილი, რაც დავწერე, github-ზეა ხოლო მის შესახებ უფრო დეტალურად ამ დოკუმენტში წერია:

jobs.ge REST client application

ამ პოსტს იმიტომ ვწერ, რომ გადავწყვიტე მობილურის აპლიკაციები ჩემი საქმე არ არის :) და დროც არ მაქვს მის გასაგრძელებლად. მახსოვს რამდენიმემ ინტერესი გამოხატა და თუ ვინმეს სურვილი აქვს შემიძლია გადავულოცო აპლიკაცია კოდებიანად და მან დაასრულოს. არ მოგერიდოთ და კომენტარებში დატოვეთ თქვენი აზრი :) დიდი არაფერია დაწერილი – ორ კვირაში რაც გავარჩიე და დავწერე. რაც არის, დოკუმენტშია აღწერილი.

GitHub-თან კავშირი პროქსის გავლით

არ მგონია რომ ეს პოსტი ბევრისთვის სასარგებლო გამოდგეს, მაგრამ მთელი დღე დამაკარგინა და ვერ მოვითმენ რომ არ დავწერო..

GitHub.com არის პროექტების ჰოსტინგის სერვისი ვებ ინტერფეისით, რომელიც Git version control სისტემას იყენებს. მოკლედ რომ ვთქვათ, თქვენ შეგიძლიათ იქ განათავსოთ პროექტის კოდები და ფაილები. ის ცვლილებების ისტორიასაც შეინახავს. შეიძლება სხვადასხვა განშტოებების და ვერსიების გამოყოფა და გუნდური მუშაობის დროს მოსახერხებელია კოდების ასე ცენტრალიზებულად არსებობა.

ძალიან არ ჩავუღრმავდები სისტემის აღწერას – კარგი ინსტრუქციები აქვთ. მაგრამ დღეს ისეთი კომპიუტერიდან დამჭირდა ცვლილებების ატვირთვა, რომელიც proxy-ის უკან იყო და ამისთვის ვერც ისე ბევრი რესურსი ვნახე.
თან არასტანდარტული პორტებიც დაბლოკილია, ssh-ით შესვლის დროს კი 22 პორტია საჭირო.

GitHub-ი რამდენიმე შესაძლებლობას გვაძლევს შესვლისთვის: ssh, https და git read-only
https-ით ssl-ის სერტიფიკატების პრობლემის გამო რატომღაც ვერ დავუკავშირდი, ამიტომ ვუკავშირდები ssh-ით ოღონდ https-ის პორტით – 443.

ჩემთან ასეთი ნაბიჯები შევასრულე:
~/.ssh საქაღალდეში შევქმენი კონფიგურაციის ფაილი config შემდეგი შიგთავსით:

Host github.com
User <მომხმარებელი>
Hostname ssh.github.com
ProxyCommand /c/connect.exe -H <პროქსის მისამართი>:<პროქსის პორტი> %h %p
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
Port 443

ProxyCommand არის option, რომელიც OpenSSH-ში SOCKS პროტოკოლის შესაცვლელად ჩაემატა და საშუალებას იძლევა რომ სხვა პროგრამები გამოიყენოს ssh-მა პროქსისთან ურთიერთობისთვის. ერთ-ერთი ასეთი პროგრამაა connect.c

მე ვინდოუსიდან ვცდილობდი ატვირთვას ამიტომ გადმოვწერე კომპილირებული ფაილი აქედან: http://dl.dropbox.com/u/2177278/connect.exe (თავის საიტზე არ მუშაობდა ლინკი).

ასეთმა კონფიგურაციამ არ იმუშავა, მაგრამ connect.exe-ს აქვს ერთი კარგი პარამეტრი -d დებაგისთვის (მაგ: ProxyCommand /c/connect.exe -d -H <პროქსის მისამართი>:<პროქსის პორტი> %h %p) და მაგის მითითების შემდეგ უფრო დეტალურად წერს სად რა პრობლემა შეხვდა. ძალიან დიდი ალბათობით მანდვე იპოვით მიზეზს.

ჩემ შემთხვევაში პრობლემა პროქსისთან აუტენტიფიკაცია იყო. პროქსის პაროლის მითითებისთვის რამდენიმე მეთოდი არსებობს, მაგრამ environment variable-ებში ღია სახით გაწერა არ მომეწონა და არც იმუშავა ჩემთან. არც git-ის global http.proxy პარამეტრმა იმუშავა (აქაც ღია სახით იყო გაწერილი).

ბოლო ბოლო გადმოვწერე Cntlm Authentication Proxy, რომელიც მანქანაზე გასაშვები სერვისია, პროქსის და აპლიკაციებს შორის დგება და ავტორიზაციას გადის მათ მაგივრად. მისი გამოყენების მარტივი მაგალითი არსად ედოთ და მაინც წამაკითხეს მთელი დოკუმენტაცია :D ამიტომ მოკლედ დავწერ როგორ მუშაობს:

Cntlm სერვისია და ინსტალაციის შემდეგ ავტომატურად არის გაშვებული. შეგიძლიათ Control panel-ის Administrative Tools-ში შეხვიდეთ და ამოაგდოთ.
პროგრამა უსმენს კონფიგურაციაში გაწერილ მისამართს და პორტს, მაგალითად: 127.0.0.1:3128
ამიტომ ყველა იმ პროგრამის კონფიგურაციაში, რომელიც გინდათ რომ მისი გავლით პროქსის დააკავშიროთ, პროქსის მისამართის მაგივრად უნდა მიუთითოთ ეს მისამართი და პორტი.

პროქსის პაროლის შეყვანა ერთხელ არის საჭირო – თავიდან. შემდეგ დოკუმენტაციის (Configuration hints განყოფილების) მიხედვით უნდა დააგენერირებინოთ თავისი პაროლი, გადაიტანოთ კონფიგურაციის ფაილში და შემდეგ სულ იმით გაივლის ხოლმე ავტორიზაციას.

მე Git Bash-დან ვუშვებდი ბრძანებებს და კავშირს ამით ვამოწმებდი ხოლმე:
$ ssh -v git@github.com

ამ პრობლემის გადასაჭრელად ძირითადად ეს პოსტები დამეხმარა:

Using Github Through Draconian Proxies
Git SSH problem – bad file number 

ცუდი ის იყო, რომ github-დან კლონი უპრობლემოდ გაკეთდა და ფაილები წამოიღო სერვერიდან, მაგრამ push-ის დროს არაფრით ამთავრებდა ოპერაციას (არც timeout შეცდომით) და მაგის გამო კავშირის პრობლემაზე არ მიფიქრია თავიდანვე. მერე გამახსენდა, რომ კლონი IDE-დან გავაკეთე.. და push არ ჰქონდა იქ..