Code 2019-un gəlişi və tanışlığı sevməyi necə öyrəndiyim

İllik bir ənənəm olaraq dekabr ayı ərzində Advent of Code proqramlaşdırma çağırışında bir bıçaq götürdüm. İl ərzində öyrəndiklərimi sınamaq üçün ya da özümü sınamaq üçün hər zaman bir fürsət olmuşam.

Əvvəlki işimdə 2019-cu ilin bir hissəsi üçün işlədiyimiz proqramı qurmaq və yerləşdirmək üçün PowerShell yazısından istifadə etdik. Mən qoşulduqda onun bəzi funksionallığı miras qaldı, çünki indi Visual Studio-da eyni anda birdən çox layihəni işlədə bilərsiniz. Qiymətləndirmə qrupu üçün qiymətləndirmə aparmaq üçün bir instansiyaya tətbiq etdiyi bir funksionallıq və bununla əlaqədar bir məsələ ondadır ki, artıq işləyən instansiya və səhvləri qismən yazmağa çalışmasıdır. Qoşulduğumda növbələşdirmə həlli yalnız QA instansiya qovluğundakı sənədləri əl ilə silmək idi (fayllarda bir neçə dəfə istifadə olunur) və sonra yenidən cəhd etməkdir. Tövsiyə etdiyim və həyata keçirdiyim sürətli və bir az həssas bir düzəliş, skriptin o hissəsini müvəffəqiyyətlə işləyənə qədər yenidən sınamaq idi ki, bu da işimizi bir qədər asanlaşdırdı.

Bu, həqiqətən yaşamış olduğum PowerShell’in ilk ləzzəti idi. Gizli olaraq, həqiqətən çox şey etmədim; Mən yalnız bir dəyişən təqdim etdim və niyə bütün sənədlərin uğurla yayımlandığını müəyyənləşdirdim və getdim. Bununla birlikdə, mən ümumiyyətlə PowerShell haqqında çox şey bilmədiyimi və gələcəkdə daha yaxşı istifadə etməyi öyrənməli olduğumu bilirdim.

Dekabr ayına sürətli irəliləyin; 1-ci Advent Ad günü çıxdı və mən PowerShell'dən istifadə edərək mümkün qədər çox çətinlik çəkməyə çalışaraq özümü yeni bir şəkildə sınamağa və sınamağa hazır idim. İlk çətinlik kifayət qədər sadə görünürdü; Bir siyahıdakı hər bir nömrə üzərində əməliyyat aparın və hamısını əlavə edin. Bunu demək olar ki, mənasız bir şəkildə başqa bir dildə edə biləcəyimi bilirdim, amma PowerShell mənim üçün yeni olduğu üçün sıfırdan başlamalı oldum.

Əvvəlcə bir növ mühit qurmalıydım. İlk gün həqiqətən daha çox nəyə ehtiyacım olduğunu bilmirdim, buna görə kod bazam sadəcə iki skript idi; ilk günün çağırışının hər hissəsi üçün bir.

Get-Məzmunu, bir funksiyanı necə yerinə yetirəcəyimi və ən azı ekrandakı dəyəri necə əks etdirəcəyimi öyrəndiyim üçün kodum kifayət qədər sadə idi, baxmayaraq ki, sonda $ TotalMassın necə göstərildiyini ümumiyyətlə necə təsir etdiyini tam başa düşmədim. proqramın vəziyyəti. Bilirdim ki, heç olmasa ayaqlarımı PowerShell-ə ​​daldırdığım və yeni şeylər öyrənməyə davam etməyə hazır olduğum.

Vahid testini də işimə təqdim etmək istədim. Yəqin ki, əvvəlcə həddən artıq dərəcədə öldürüldü, amma hesab edirəm ki, bu testləri əvvəlcədən əlavə etməyə başlamaq qərarı, ehtimal ki, daha yaxşı oldu, çünki həqiqətən testlərə uyğun olmağı hədəfləyən həllər yaratmağıma səbəb oldu. Xoşbəxtlikdən, çətinliklərin bir çoxunda effektiv sınaqlar olan nümunələr var. Bu ilk gündə test yalnız bir neçə təcrid olunmuş sayda idi və bunların tam siyahısı deyildi, ona görə də arqumentləri skriptlə əvəz etməyə çalışdım ki, ya faylı ya da tək bir nömrəni təyin edə biləsiniz.

Pester'i daxil edin: bəlkə də şahidi olduğum ən sadə və təəccüblü güclü bir sınaq vasitəsidir. Bu PowerShell əsaslı test paketi, bəzi proqramın çıxışını nəticəni müqayisə edən xüsusi bir üsula kəməri ilə çəkərək çox sadə sınaq hallarını yazmağa imkan verir. Boru kəməri ilə işlədiyindən hər hansı bir dil və ya alətdən istifadə edərək effektiv yaza bilər və nəticələr çıxdıqca gözlənilən nəticəyə uyğun olduğunu müqayisə edə bilərsiniz. Mən bir neçə qurdum və CI'yi depozitlərimə effektiv şəkildə birləşdirmək üçün hamısını GitHub’un yeni Fəaliyyət xüsusiyyətinə bağladım. Yenə də bu aydan sonra işlənməyəcək bir adamın depo depozitini nəzərə alsaq, çox güman ki, gələcəkdə istifadə edə biləcəyim bəzi vasitələrlə qarşılaşmaq üçün yaxşı bir fürsət idi.

2-ci gün bir az əyri-bala olsa da, bu baytekodu şərh edən bir proqram idi (və ya texniki olaraq dəyərlər tam ədəd kimi göstərildiyi üçün intcode deyildiyi üçün). Bunun üçün, loops və seriallar ilə məşğul olmalı idim, hər ikisi bir az iffy idi. Qəfildən indi mənim başqa PowerShell kodumun üstündəki müntəzəm .NET funksiyasından istifadə etməli oldum. Məsələn, girişdə bir sətir kimi oxumalı və hər bir vergülünə bölməli idim və bunu etmənin ən sadə yolu C # -də edərkən eyni sintaksis idi.

Ancaq 3-cü gün idi ki, PowerShell koduna necə yaxınlaşdığımdan bir az narahat olmağa başladım. Bu problem üçün sizə istiqamətlərin və məsafələrin siyahısı olaraq iki telin yolları verildi və ən yaxın kəsişməni təyin etməlisiniz. Dərhal yanaşmağım, bütün kəsişmələrin harada olduğunu müəyyənləşdirən və sonra bir yol verilərək bu yolun kəsişmənin nə qədər olduğunu müəyyənləşdirən bir funksiya yaratmaq idi.

Bu anda PowerShell'un əvvəlcə düşündüyümdən çox fərqli olduğunu başa düşdüm. Hər iki yolun kəsişməsini tapmaq üçün bu metodologiyanı təkrar istifadə edəcəyimi bilirdim, buna görə də yolu keçdiyiniz bir dəlil ilə bir funksiyaya ümumiləşdirə biləcəyimi bilirdim. Dönmək istədiyim addımların tam sayı idi verilən bir nöqtəyə çatmaq lazım idi. Ancaq mənim funksiyam heç bir şey qaytarmırdı və sonradan kodun hissələri çılğınlıqla işləyə bilmədikləri üçün vahiməyə düşdü. Bu funksiyaya qayıtdım və bir neçə çap ifadəsi əlavə etdim ki, nə etdiyini bildim. Bunun əvəzinə, indi mənim funksiyam boolean-a döndü. Faydalı deyil, amma maraqlı davranış idi. Təəccüblü olan odur ki, funksiya dəyərin düzgün hesablanması üçün ortaya çıxdı, lakin onu düzgün qaytara bilmədi. Çap ifadələrini əlavə etmək funksiyanın geri qaytarılmasını dəyişdirdi. Uzun bir axtarışdan sonra problemin funksiyaların boru çəkdikləri qədər geri dönməməsi olduğunu bildim. Bu, çap ifadələrinin niyə pozduğunu izah etdi, amma dəyərimin geri dönmədiyini izah etmədi. Nə üçün istədiyimi qaytarmadığına hələ 100% əmin deyiləm, amma gündəlik problemlərlə ayaqlaşmaq istədiklərimdən ötəri bu işi davam etdirmək çox əsəbi oldu.

İkinci təxmin etmədən, sadəcə bir müddətdir mənim goto dilim olan C # -də bir həll yazmağı qərara aldım. Çözüm təbii olaraq mənə gəldi, çünki əvvəllər düşündüyüm şeylər tam olaraq oldu. Əslində, bir hissə üçün həllim demək olar ki, tamamilə sadə LINQ funksionallığı ilə həyata keçirildi; hər iki yolun əhatə etdiyi bütün koordinatları əldə edin, onları kəsin və minimum dəyəri tapın. Yuxarıdan çıxarmaq üçün, əvvəlki günlərdə işləməyi köçürdüm (bu, çox sadə idi) və Xunit istifadə edərək testi yenidən həyata keçirdim.

İntrospektiv şəkildə baxmaq üçün bu hərəkət özüm haqqında nə deyir? Sadəlövh bir cavab olardı ki, asan yolu tapdım və artıq özümə meydan oxumaq istəmədim, baxmayaraq ki, sonrakı günlərin bəzilərinin (xüsusən açar qapı labirenti ilə 18-ci gün) istifadə edilməsindən asılı olmayaraq çox çətin olduğunu mübahisə edə bilərdim. adət etdiyim bir dil. Düşünürəm ki, buna daha az bir ittiham yolu ilə qarşılaşdığım çətinlikin daha semantik və spesifik, daha az texniki və proqramlı olduğunu başa düşdüm. Problemi həll etmək istəmədim, hərəkətə gətirməli olduğum alətlər dəsti ilə güləşdim. Əvəzində özümü məhdudlaşdırmaq istəsəydim, hər şeyi C-yə köçürərdim, burada dinamik miqyaslı massivlər və ya hashsetlər kimi asan vasitələrə etibar edə bilmirəm.

Qəti şəkildə hiss etdim ki, C # tərəfə keçmək, sonrakı problemlərin əhatəsinə görə çox böyük bir addım idi. Bu intcode tərcüməçisi hər ikinci gün inkişaf edir və bir çox problem səmərəli bir həll tapmaq üçün işləməli olduğunuz bir proqram verərdi. Eyni zamanda birdən çox işləməyi tələb edən çətinliklər olduqca maraqlı idi, xüsusən də hər tərcüməçinin giriş və çıxışı idarə etməsi lazım olduğu üçün. Bunu iplər və lambdalar ilə həyata keçirdim, bu, 9 gündən etibarən bu intcode problemləri üçün ümumiləşdirilmiş bir sinif qurduğumu deməkdir və mənim etməyim lazım olan bütün işin necə işlədiyini idarə etmək idi. İstədiyim təqdirdə test üçün xüsusi funksiyaları asanlıqla hədəfləyə biləcəyimi ifadə etdi (problemlərin əksəriyyətinin sonradan bu qədər nümunənin olmamasına təəccübləndim).

Buna baxmayaraq PowerShell-də bir yetişmə kimi baxmaq lazım deyil; nə edə biləcəyim və edə bilməyəcəyim və bundan istifadə etməyim barədə qəti şəkildə mənə ləzzət verdi. Təkrarlanan intcod problemini şərh etmək üçün hər dəfə əllə istifadə etməkdənsə və ya hansısa ümumi bir yerə müraciət etməkdənsə, xüsusi bir sinif tapdığımdan məmnunam. Düşünürəm ki, PowerShell-in miqyasını böyütməyə ehtiyac olmayan kiçik tapşırıqlar üçün, xüsusən Python-u asanlıqla quraşdıra bilmədiyiniz Windows sistemlərində istifadə etmək çox yaxşı olardı. Pester də olduqca səliqəlidir və hər hansı bir başqa dildə qəribə şey üçün yazı testlərinin keçirilməsinə qarşı olmazdım.

Ancaq nəzəri olaraq, ehtimal ki, PowerShell-də istədiyiniz hər şeyi edə bilərsiniz. Məni əsəbiləşdirən odur ki, mən səmərəli müraciət etdim .NET kitabxanalarını təmiz PowerShell məhsulları yazmaqdan daha çox istifadə etdim. Bu ssenaridə hər ikisini qarışdırmaqdansa, yalnız gəmidən tullanmaq və yalnız bir dildə yazmaq daha təbii idi. Və nəticədə, bu ssenaridə yeni alətləri qarışdırmaqdan daha çox, yeni alqoritmlərlə çətin problemlərin necə həll olunacağını öyrənməyin daha vacib olduğunu hiss etdim.