{"id":34615,"date":"2025-02-11T13:08:19","date_gmt":"2025-02-11T12:08:19","guid":{"rendered":"https:\/\/nearshore-it.eu\/?p=34615"},"modified":"2025-05-28T11:30:54","modified_gmt":"2025-05-28T09:30:54","slug":"python-i-ai","status":"publish","type":"post","link":"https:\/\/nearshore-it.eu\/pl\/artykuly\/python-i-ai\/","title":{"rendered":"Python i AI, Float i nie tylko \u2013 czyli jak produktywniej pracowa\u0107 z Pythonem?\u00a0"},"content":{"rendered":"\n<p>Podczas konferencji Python Summit 2024 zorganizowanej przez spo\u0142eczno\u015b\u0107 PyData i PyWaw w Warszawie w grudniu ubieg\u0142ego roku, mia\u0142em mo\u017cliwo\u015b\u0107 zapoznania si\u0119 z prelekcjami na temat generatywnej sztucznej inteligencji, uczenia maszynowego, in\u017cynierii danych, technologii webowych, cyberbezpiecze\u0144stwa, testowania, architektury system\u00f3w czy dobrych praktyk pisania czystego kodu. W pami\u0119\u0107 zapad\u0142y mi szczeg\u00f3lnie dwie prelekcje, kt\u00f3re zainspirowa\u0142y mnie do napisania tego artyku\u0142u. Pierwsza z nich dotyczy\u0142a produktywnej pracy z Pythonem (prelegent: Sebastian Buczy\u0144ski, Software Architect \/ Consultant \/ Trainer z Bottega IT Minds), natomiast druga obejmowa\u0142a temat liczb zmiennoprzecinkowych Float w Pythonie (Konrad Gawda, Cloud Evangelist z Orange Polska).<\/p>\n\n\n\n<p>Zrozumienie poruszonych aspekt\u00f3w pozwala odpowiedzie\u0107 na istotne pytania. Jakie struktury wykorzystywa\u0107, by unikn\u0105\u0107 krytycznych b\u0142\u0119d\u00f3w? Jak zwi\u0119kszy\u0107 efektywno\u015b\u0107 pracy w Pythonie i zadba\u0107 o czysty kod? Jak asystenci AI wspieraj\u0105 codzienn\u0105 prac\u0119 programist\u00f3w?<\/p>\n\n\n\n<div class=\"table-of-contents\">\n    <p class=\"title\"><\/p>\n    <ol>\n                    <li><a href=\"#przyk\u0142ady-problem\u00f3w-z-liczbami-zmiennoprzecinkowymi\">1.  Przyk\u0142ady problem\u00f3w z liczbami zmiennoprzecinkowymi<\/a><\/li>\n                    <li><a href=\"#Float-\u2013-liczby-zmiennoprzecinkowe-w-Pythonie\">2.  Float \u2013 liczby zmiennoprzecinkowe w Pythonie<\/a><\/li>\n                    <li><a href=\"#Developer-Experience-\u2013-jak-mierzy\u0107-efektywno\u015b\u0107-developera?\">3.  Developer Experience \u2013 jak mierzy\u0107 efektywno\u015b\u0107 developera?<\/a><\/li>\n                    <li><a href=\"#Narz\u0119dzia-do-efektywnej-pracy-w-Pythonie\">4.  Narz\u0119dzia do efektywnej pracy w Pythonie<\/a><\/li>\n                    <li><a href=\"#Asystenci-AI-jako-wsparcie-produktywnej-pracy\">5.  Asystenci AI jako wsparcie produktywnej pracy<\/a><\/li>\n                    <li><a href=\"#Podsumowanie\">6.  Podsumowanie<\/a><\/li>\n            <\/ol>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"przyk\u0142ady-problem\u00f3w-z-liczbami-zmiennoprzecinkowymi\">Troch\u0119 historii na pocz\u0105tek \u2013 przyk\u0142ady problem\u00f3w z liczbami zmiennoprzecinkowymi<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">B\u0142\u0105d systemu obrony przeciwrakietowej Patriot&nbsp;<\/h3>\n\n\n\n<p>Podczas wojny w Zatoce Perskiej w 1991 roku system nie zadzia\u0142a\u0142 prawid\u0142owo i nie przechwyci\u0142 rakiety Scud, kt\u00f3ra uderzy\u0142a w koszary wojskowe w Dhahran w Arabii Saudyjskiej, zabijaj\u0105c 28 os\u00f3b. Przyczyn\u0105 by\u0142 b\u0142\u0105d w obliczeniach czasu. System \u015bledzi\u0142 czas za pomoc\u0105 liczby ca\u0142kowitej reprezentuj\u0105cej liczb\u0119 takt\u00f3w zegara, przy czym ka\u017cdy takt odpowiada\u0142 za oko\u0142o 0.1 sekundy. Aby obliczy\u0107 dok\u0142adny czas, liczba ca\u0142kowita by\u0142a mno\u017cona przez 0.1, kt\u00f3ra w pami\u0119ci by\u0142a reprezentowana jako liczba przybli\u017cona ze wzgl\u0119du na ograniczenia formatu IEEE 754. Z ka\u017cdym kolejnym cyklem zegara b\u0142\u0105d si\u0119 kumulowa\u0142, przez a\u017c 100 godzin od uruchomienia systemu, ostatecznie narastaj\u0105c do oko\u0142o 0.34 sekundy. Ta r\u00f3\u017cnica spowodowa\u0142a, \u017ce system obliczy\u0142 b\u0142\u0119dne po\u0142o\u017cenie rakiety Scud i nie zadzia\u0142a\u0142 na czas. Po incydencie wprowadzono aktualizacj\u0119 oprogramowania, kt\u00f3ra resetowa\u0142a zegar systemowy cz\u0119\u015bciej, zmniejszaj\u0105c wp\u0142yw kumulacji b\u0142\u0119d\u00f3w. Ta tragiczna w skutkach historia ameryka\u0144skiego systemu obrony rakietowej Patriot to jeden z klasycznych przyk\u0142ad\u00f3w b\u0142\u0119du wynikaj\u0105cego z ogranicze\u0144 liczb zmiennoprzecinkowych. Ta historia pokazuje, \u017ce w tak istotnych obliczeniach nale\u017cy unika\u0107 stosowania przybli\u017ce\u0144 i u\u017cywa\u0107 precyzyjniejszych typ\u00f3w danych.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wybory parlamentarne w Schleswig-Holstein&nbsp;<\/h3>\n\n\n\n<p>Innym przyk\u0142adem s\u0105 wybory parlamentarne z 1992 r. w niemieckim Schleswig-Holstein. W tym, jak i w wi\u0119kszo\u015bci niemieckich land\u00f3w, obowi\u0105zuje system proporcjonalny, w kt\u00f3rym partie musz\u0105 uzyska\u0107 co najmniej 5% g\u0142os\u00f3w, aby otrzyma\u0107 mandaty w parlamencie. Wyniki wybor\u00f3w by\u0142y prezentowane w procentach, a zaokr\u0105glenia mia\u0142y miejsce na r\u00f3\u017cnych etapach oblicze\u0144. Partia Zielonych uzyska\u0142a 4.97%, ale na etapie prezentacji wynik\u00f3w warto\u015b\u0107 zosta\u0142a zaokr\u0105glona do 5%, a wi\u0119c pr\u00f3g zosta\u0142 spe\u0142niony, co ca\u0142kowicie zmieni\u0142o rozk\u0142ad mandat\u00f3w w parlamencie. Doprowadzi\u0142o to do wielu kontrowersji i publicznej debaty, jednak mimo to wyniki zosta\u0142y uznane za wi\u0105\u017c\u0105ce. W systemie nie przewidziano procedury na wypadek b\u0142\u0119du zaokr\u0105glenia.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Float-\u2013-liczby-zmiennoprzecinkowe-w-Pythonie\">Float \u2013 liczby zmiennoprzecinkowe w Pythonie<\/h2>\n\n\n\n<p>W tym kontek\u015bcie bardzo ciekaw\u0105 prelekcj\u0105 z mojej perspektywy by\u0142a ta o typie Float, czyli liczbach zmiennoprzecinkowych w Pythonie.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Liczby te mo\u017cna tworzy\u0107 na r\u00f3\u017cne sposoby, poprzez dos\u0142owne przekazanie liczby, czyli np. 1.0, u\u017cywaj\u0105c klasy tj. float(1) lub poprzez dzia\u0142ania matematyczne takie jak 1\/1.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Standard IEEE 754 binary64&nbsp;<\/h3>\n\n\n\n<p>Z dokumentacji Pythona dowiadujemy si\u0119, \u017ce we wszystkich znanych implementacjach interpretera Pythona float zdefiniowany jest jako double. Bardziej szczeg\u00f3\u0142owo typ ten jest opisany wed\u0142ug standardu IEEE 754 binary64 i wygl\u0105da to nast\u0119puj\u0105co:&nbsp;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"150\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_1.png\" alt=\"Python i AI\" class=\"wp-image-34637\" title=\"\" srcset=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_1.png 756w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_1-300x60.png 300w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_1-495x98.png 495w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><\/figure>\n<\/div>\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Patrz\u0105c po kolei od lewej:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>1 bit jest po\u015bwi\u0119cony na znak (liczba dodatnia lub ujemna).&nbsp;<\/li>\n\n\n\n<li>11 bit\u00f3w wyra\u017ca wyk\u0142adnik pot\u0119gowy.&nbsp;<\/li>\n\n\n\n<li>52 bity wyra\u017caj\u0105 u\u0142amek.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>A wszystko to mo\u017cna przedstawi\u0107 za pomoc\u0105 poni\u017cszego wzoru:&nbsp;<\/p>\n\n\n\n<p>(-1)^sign x 2^(exp-1023) x 1.fraction&nbsp;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"160\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_2.png\" alt=\"Python i AI\" class=\"wp-image-34640\" title=\"\" srcset=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_2.png 756w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_2-300x63.png 300w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_2-495x105.png 495w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><\/figure>\n<\/div>\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Wed\u0142ug om\u00f3wionego standardu poni\u017cej kilka przyk\u0142ad\u00f3w reprezentacji binarnej:&nbsp;<\/p>\n\n\n\n<p><strong>a) Liczba 0.0&nbsp;<\/strong><\/p>\n\n\n\n<p>0 (sign) 00000000000 (exponent) <\/p>\n\n\n\n<p>(0).0000000000000000000000000000000000000000000000000000 (fraction)&nbsp;<\/p>\n\n\n\n<p><strong>b) Liczba 1.0 = 1 x 1.0 = 2^0 x 1.0 = 2^(1024-1024) x 1.0&nbsp;<\/strong><\/p>\n\n\n\n<p>0 (sign) 01111111111 (exponent) <\/p>\n\n\n\n<p>(1).0000000000000000000000000000000000000000000000000000 (fraction)&nbsp;<\/p>\n\n\n\n<p><strong>c) Liczba 3.0 = 2 x 1.5 = 2^1 x 1.5 =2^(1025-1024) x 1.5&nbsp;<\/strong><\/p>\n\n\n\n<p>0 (sign) 10000000000 (exponent) <\/p>\n\n\n\n<p>(1).1000000000000000000000000000000000000000000000000000 (fraction)&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Precyzja typu Float&nbsp;<\/h3>\n\n\n\n<p>Powy\u017csze przyk\u0142ady s\u0105 do\u015b\u0107 proste z punktu widzenia reprezentacji binarnej, jednak problem pojawia si\u0119 przy liczbach nieca\u0142kowitych, poniewa\u017c nie zawsze jeste\u015bmy w stanie zapisa\u0107 je w pami\u0119ci z pe\u0142n\u0105 precyzj\u0105. Mo\u017cna to zaobserwowa\u0107, u\u017cywaj\u0105c w Pythonie metody as_integer_ratio(), aby sprawdzi\u0107, jakie liczby s\u0105 u\u017cyte do dzielenia, by uzyska\u0107 oczekiwany wynik. Jak wida\u0107 na poni\u017cszym przyk\u0142adzie, dla liczby 0.1 nie ma liczb 1 i 10, jak by\u015bmy tego oczekiwali, tylko 3602879701896397 i 36028797018963968. S\u0105 to liczby, kt\u00f3re daj\u0105 najbardziej precyzyjne przybli\u017cenie do 0.1 i mo\u017cliwe do zapisu w pami\u0119ci wed\u0142ug omawianego standardu. Natomiast to, \u017ce wywo\u0142uj\u0105c print() na obliczeniu 1\/10 otrzymujemy 0.1, wynika wy\u0142\u0105cznie z tego, \u017ce print() automatycznie zaokr\u0105gla nam do najkr\u00f3tszego zapisu dziesi\u0119tnego, kt\u00f3ry si\u0119 mie\u015bci w ramach ostatniego bitu precyzji.&nbsp;&nbsp;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"54\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_3.png\" alt=\"Python i AI\" class=\"wp-image-34644\" title=\"\" srcset=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_3.png 756w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_3-300x21.png 300w, https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/nearshore_2025.02.05_graphic_3-495x35.png 495w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><\/figure>\n<\/div>\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Inn\u0105 przydatn\u0105 metod\u0105 w Pythonie, pozwalaj\u0105c\u0105 zyska\u0107 wi\u0119cej informacji na temat float\u00f3w, jest <strong>sys.float_info. <\/strong>Dzi\u0119ki niej mo\u017cemy si\u0119 dowiedzie\u0107, \u017ce float pozwala na przechowywanie do 15 cyfr znacz\u0105cych (dodatkowo ewentualnie znak plus-minus i\/lub przecinek).&nbsp;&nbsp;<\/p>\n\n\n\n<p>To wszystko mo\u017ce sprawi\u0107, \u017ce zaczniemy si\u0119 zastanawia\u0107 nad tym, jak du\u017co ucieka nam precyzji podczas u\u017cywania typu float. Do tego przydatna jest metoda <strong>math.ulp() <\/strong>(czyli Unit in the Last Place), co w praktyce zwraca nam r\u00f3\u017cnic\u0119 pomi\u0119dzy podan\u0105 liczb\u0105 a nast\u0119pn\u0105, kt\u00f3r\u0105 jeste\u015bmy w stanie zapisa\u0107 w tym formacie w pami\u0119ci. W przypadku ma\u0142ych liczb te r\u00f3\u017cnice s\u0105 bardzo marginalne, jednak przy takiej liczbie jak 2^52 ta r\u00f3\u017cnica wynosi ju\u017c r\u00f3wno 1.0. Oznacza to, \u017ce w\u0142a\u015bciwie od tej liczby wzwy\u017c ca\u0142kowicie tracimy cz\u0119\u015bci u\u0142amkowe. Id\u0105c dalej, przy 2^53 r\u00f3\u017cnica ta wynosi ju\u017c 2.0. Zatem wa\u017cnym wnioskiem jest, by tak du\u017cych liczb, nawet ca\u0142kowitych, nie przechowywa\u0107 jako float, poniewa\u017c tylko liczby parzyste w tym przypadku zachowa\u0142yby swoj\u0105 precyzj\u0119.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Symbole specjalne&nbsp;<\/h3>\n\n\n\n<p>W standardzie IEEE 754 przewidziano r\u00f3wnie\u017c miejsce dla specjalnych symboli. Je\u015bli 11-bitowa cz\u0119\u015b\u0107 exponent jest ca\u0142a wype\u0142niona jedynkami, a 52-bitowa cz\u0119\u015b\u0107 wyra\u017caj\u0105ca u\u0142amek wype\u0142niona zerami, to mamy do czynienia z reprezentacj\u0105 binarn\u0105 niesko\u0144czono\u015bci. Zape\u0142niaj\u0105c zerem bit odpowiedzialny za znak otrzymujemy plus niesko\u0144czono\u015b\u0107, a jedynk\u0105 minus niesko\u0144czono\u015b\u0107.&nbsp;<\/p>\n\n\n\n<p>Z kolei maj\u0105c r\u00f3wnie\u017c 11-bitow\u0105 cz\u0119\u015b\u0107 exponent wype\u0142nion\u0105 jedynkami, ale tak\u017ce cz\u0119\u015b\u0107 wyra\u017caj\u0105c\u0105 u\u0142amek wype\u0142nion\u0105 jedynkami, otrzymujemy symbol NaN (Not a Number). Wszelkie operacje por\u00f3wnuj\u0105ce takie jak =, &gt;, &lt; z udzia\u0142em NaN zwracaj\u0105 False, co mo\u017ce by\u0107 problematyczne w r\u00f3\u017cnych okoliczno\u015bciach. Zw\u0142aszcza kiedy u\u017cytkownik ma braki w danych i s\u0105dzi, \u017ce por\u00f3wnywana jest faktyczna liczba, a nie pusta reprezentacja w postaci NaN.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Zaokr\u0105glenia&nbsp;<\/h3>\n\n\n\n<p>Co jednak, je\u015bli nie jest potrzebna nam a\u017c taka dok\u0142adno\u015b\u0107 i chcemy upro\u015bci\u0107 jakie\u015b obliczenia? Odpowiedzi\u0105 s\u0105 zaokr\u0105glenia i nale\u017cy wiedzie\u0107, \u017ce uzyska\u0107 je mo\u017cna na r\u00f3\u017cne sposoby. Co istotne, nie r\u00f3\u017cni\u0105 si\u0119 jedynie nazwy funkcji, ale ich implementacje maj\u0105 odr\u0119bne podej\u015bcia. W prezentacji podczas Python Summit 2024 przedstawiono nast\u0119puj\u0105ce metody:&nbsp;<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Funkcja round() <\/strong>\u2013 zaokr\u0105gla zadan\u0105 liczb\u0119 do najbli\u017cszej liczby z okre\u015blon\u0105 liczb\u0105 miejsc po przecinku, domy\u015blnie do liczby ca\u0142kowitej. Natomiast szczeg\u00f3lnym przypadkiem jest sytuacja, gdy liczba jest r\u00f3wno w po\u0142owie i w obie strony jest taka sama odleg\u0142o\u015b\u0107. Wtedy najmniej znacz\u0105ca cyfra zaokr\u0105glana jest do liczby parzystej, co wed\u0142ug statystyk\u00f3w minimalizuje skumulowany b\u0142\u0105d podczas wykonywania wielu operacji zaokr\u0105glania. Czyli przyk\u0142adowo zar\u00f3wno 1.5, jak i 2.5 zostan\u0105 zaokr\u0105glone do 2, je\u015bli interesuje nas liczba ca\u0142kowita. Co ciekawe, w przypadku takich liczb jak 1.15 i 1.25 r\u00f3wnie\u017c obie powinny zosta\u0107 zaokr\u0105glone do 1.2, gdyby chcie\u0107 zachowa\u0107 dok\u0142adno\u015b\u0107 do jednego miejsca po przecinku. Jednak tylko 1.25 zwr\u00f3ci poprawnie 1.2, a dla 1.15 zostanie zwr\u00f3cone 1.1. Wynika to w\u0142a\u015bnie z tego, \u017ce liczby 1.15 nie da si\u0119 precyzyjnie przechowa\u0107 w pami\u0119ci wed\u0142ug standardu IEEE 754, a b\u0119dzie to 1.1499999999999999. Czyli nie jest to de facto r\u00f3wno w po\u0142owie, a wi\u0119c zaokr\u0105gli w d\u00f3\u0142 do 1.1.&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>int() lub math.trunc()<\/strong> \u2013 co prawda nie s\u0105 to funkcje zaokr\u0105glaj\u0105ce, tylko obcinaj\u0105ce liczb\u0119, ale ich efekt dzia\u0142a tak, jakby\u015bmy zaokr\u0105glali liczb\u0119 w kierunku 0. Czyli przyk\u0142adowo 1.9 zostanie uci\u0119te (zaokr\u0105glone) do 1, natomiast -1.9 zostanie sprowadzone do -1.&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>math.floor() lub x \/\/ 1<\/strong> \u2013 pierwsza z nich po prostu zaokr\u0105gla w d\u00f3\u0142, w kierunku \u2013niesko\u0144czono\u015bci. Natomiast druga to dzielenie bez reszty, przy czym dziel\u0105c przez jeden, uzyskamy ten sam efekt co w przypadku pierwszej funkcji. Przyk\u0142adowo dla obu z nich -1.9 zostanie zaokr\u0105glone do -2, a 1.9 do 1.&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>math.ceil() <\/strong>\u2013 zaokr\u0105glanie w g\u00f3r\u0119, w kierunku + niesko\u0144czono\u015bci. U\u017cywaj\u0105c tego samego przyk\u0142adu -1.9 zostanie zaokr\u0105glone do -1, natomiast 1.9 zaokr\u0105gli do 2.&nbsp;<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Developer-Experience-\u2013-jak-mierzy\u0107-efektywno\u015b\u0107-developera?\">Developer Experience \u2013 jak mierzy\u0107 efektywno\u015b\u0107 developera?<\/h2>\n\n\n\n<p>W przesz\u0142o\u015bci na r\u00f3\u017cne sposoby pr\u00f3bowano mierzy\u0107 efektywno\u015b\u0107 developer\u00f3w. Jedn\u0105 z bardziej popularnych, a zarazem nietrafionych metod, by\u0142o mierzenie efektywno\u015bci poprzez liczb\u0119 napisanych linii kodu. Podczas drugiej z wspomnianych prezentacji przytoczono koncepcj\u0119, kt\u00f3ra nie tyle pozwala na mierzenie produktywno\u015bci, co pomaga zadba\u0107 o efektywne \u015brodowisko pracy. Mowa tutaj o DevEX (Developer Experience), kt\u00f3re wyr\u00f3\u017cnia 3 filary:&nbsp;<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Stan przep\u0142ywu (Flow state)<\/strong> \u2013 z punktu widzenia developera jest to stan g\u0142\u0119bokiego skupienia, w kt\u00f3rym jeste\u015bmy w stanie spokojnie pracowa\u0107. Je\u015bli cele nie s\u0105 jasno doprecyzowane, mo\u017ce wyst\u0105pi\u0107 konieczno\u015b\u0107 przerwania zadania, by ustali\u0107 nie\u015bcis\u0142o\u015bci.&nbsp;<\/li>\n\n\n\n<li><strong>P\u0119tle zwrotne (Feedback loops) <\/strong>\u2013 oznacza, ile czasu mija, zanim developer si\u0119 dowie, \u017ce kod nie dzia\u0142a. W przypadku test\u00f3w jednostkowych ten feedback jest bardzo szybki, ale w przypadku code review na feedback trzeba zaczeka\u0107 d\u0142u\u017cej.&nbsp;<\/li>\n\n\n\n<li><strong>\u0141adunek kognitywny (Cognitive load)<\/strong> \u2013 oznacza wysi\u0142ek umys\u0142owy wymagany do skutecznego pisania kodu. Je\u015bli programista spotyka si\u0119 z projektem o innej strukturze ni\u017c zwykle albo nie ma do dyspozycji dokumentacji, do kt\u00f3rej zawsze mia\u0142 dost\u0119p, ten \u0142adunek b\u0119dzie wy\u017cszy.&nbsp;<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Narz\u0119dzia-do-efektywnej-pracy-w-Pythonie\">Narz\u0119dzia do efektywnej pracy w Pythonie<\/h2>\n\n\n\n<p>Wielu programist\u00f3w rozpoczyna przygod\u0119 z Pythonem, gdy\u017c zach\u0119ca ich intuicyjna sk\u0142adnia i wszechstronno\u015b\u0107 zastosowa\u0144 tego j\u0119zyka w analizie danych. W miar\u0119 rozwoju umiej\u0119tno\u015bci w naturalny spos\u00f3b poszukujemy narz\u0119dzi pozwalaj\u0105cych zwi\u0119kszy\u0107 efektywno\u015b\u0107 pracy i u\u0142atwiaj\u0105cych \u017cycie. Podczas kolejnej prezentacji, w kt\u00f3rej mia\u0142em okazj\u0119 bra\u0107 udzia\u0142 w trakcie Python Summit 2024, zosta\u0142y om\u00f3wione takie narz\u0119dzia:&nbsp;<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Formatery&nbsp;<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Formatowanie kodu to bardzo istotny aspekt, poniewa\u017c to od tego g\u0142\u00f3wnie b\u0119dzie zale\u017ca\u0142o, czy programi\u015bcie wygodnie si\u0119 czyta oraz pisze kod. Jednak ka\u017cdy z nas mo\u017ce mie\u0107 nieco inne preferencje, przyzwyczajenia, dlatego najlepiej, aby zosta\u0142 przyj\u0119ty jeden \u015bci\u015ble okre\u015blony spos\u00f3b formatowania. Zaleca si\u0119 korzystanie ze standardu PEP 8. Jest to do\u015b\u0107 d\u0142ugi dokument, dlatego dbanie samodzielnie o ka\u017cdy szczeg\u00f3\u0142 mog\u0142oby by\u0107 bardzo czasoch\u0142onne \u2013 \u0142adunek kognitywny ro\u015bnie. Dodatkowo podczas code review to by\u0142aby rzecz, na kt\u00f3r\u0105 trzeba zwraca\u0107 uwag\u0119, zatem przek\u0142ada si\u0119 to na dodatkowy czas po\u015bwi\u0119cony po stronie zespo\u0142u, a i p\u0119tla zwrotna si\u0119 wyd\u0142u\u017ca. I tutaj z pomoc\u0105 przychodz\u0105 formatery kodu, kt\u00f3re mog\u0105 wykona\u0107 ca\u0142\u0105 prac\u0119 za nas. Przyk\u0142adowe formatery kodu w Pythonie to:<strong> black, isort, ruff, yapf.<\/strong>&nbsp;<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Lintery<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>S\u0105 to narz\u0119dzia do statycznej analizy kodu, dzi\u0119ki kt\u00f3rym mo\u017cemy dowiedzie\u0107 si\u0119 o niekt\u00f3rych b\u0142\u0119dach jeszcze przed uruchomieniem kodu. Ponadto lintery s\u0105 w stanie naprawia\u0107 za nas takie b\u0142\u0119dy jak np. liter\u00f3wki powsta\u0142e poprzez u\u017cycie nieistniej\u0105cej zmiennej. Inne kwestie, kt\u00f3re mog\u0105 by\u0107 sprawdzane automatycznie, to ilo\u015b\u0107 znak\u00f3w w ka\u017cdej linii, d\u0142ugo\u015b\u0107 nazw funkcji, zmiennych, ilo\u015b\u0107 argument\u00f3w do funkcji itp. Przyk\u0142ady linter\u00f3w w Pythonie to: <strong>pylint, flake8, ruff.<\/strong>&nbsp;<br>&nbsp;<\/p>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>Adnotacje typ\u00f3w i type checkery<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>W kwestii typ\u00f3w zmiennych Python jest bardzo liberalny, poniewa\u017c mamy tu do czynienia z typowaniem dynamicznym. Mimo to okre\u015blanie typ\u00f3w, jakie przewidujemy dla danych zmiennych, jest postrzegane jako dobra praktyka w Pythonie. Jest to funkcja, kt\u00f3ra zosta\u0142a wprowadzona od wersji Pythona 3.5. Nale\u017cy mie\u0107 na uwadze, \u017ce adnotacje typ\u00f3w s\u0105 jedynie komentarzem i nie s\u0105 uwzgl\u0119dniane przez program, o ile nie ma zewn\u0119trznej biblioteki, kt\u00f3ra by je interpretowa\u0142a. U\u017cywaj\u0105c jednak PyCharma, jednego z najpopularniejszych IDE dla Pythona, mo\u017cemy odnie\u015b\u0107 korzy\u015bci z adnotacji typ\u00f3w natychmiastowo. PyCharm posiada wbudowany type checker, dzi\u0119ki czemu b\u0119dziemy widzie\u0107 r\u00f3\u017cne podpowiedzi dotycz\u0105ce typ\u00f3w. Inne popularne zewn\u0119trzne type checkery to: <strong>mypy, pyright <\/strong>czy te\u017c<strong> pyre.<\/strong>&nbsp;<\/p>\n\n\n\n<p>Rekomendacja dotycz\u0105ca om\u00f3wionych narz\u0119dzi bardzo przypad\u0142a mi do gustu. Wed\u0142ug prelegent\u00f3w Python Summit 2024 dobrym wyborem b\u0119dzie <strong>ruff<\/strong>, poniewa\u017c \u015bwietnie sprawdza si\u0119 zar\u00f3wno jako formater, jak i linter. Zast\u0119puje inne narz\u0119dzia oraz jest bardzo szybki. Dodatkowym argumentem, by si\u0119 bli\u017cej przyjrze\u0107 tej bibliotece, jest to, \u017ce w planach jest rozszerzenie jej funkcjonalno\u015bci r\u00f3wnie\u017c o type checker. Jednak na ten moment nale\u017cy korzysta\u0107 ze sprawdzonych i popularnych narz\u0119dzi do sprawdzania typ\u00f3w, takich jak <strong>mypy <\/strong>oraz <strong>pyright.&nbsp;<\/strong>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Asystenci-AI-jako-wsparcie-produktywnej-pracy\">Asystenci AI jako wsparcie produktywnej pracy<\/h2>\n\n\n\n<p>Na koniec temat, bez kt\u00f3rego trudno obecnie wyobrazi\u0107 sobie przysz\u0142o\u015b\u0107 programowania \u2013 mianowicie narz\u0119dzia sztucznej inteligencji. Poza wspomnianymi tradycyjnymi narz\u0119dziami do usprawniania pracy w Pythonie podczas konferencji w prezentacjach osobn\u0105 cz\u0119\u015b\u0107 po\u015bwi\u0119cono nowoczesnym podej\u015bciom do tworzenia oprogramowania wykorzystuj\u0105cym asystent\u00f3w AI.&nbsp;&nbsp;<\/p>\n\n\n\n<p>O ile obecnie raczej nie ma co liczy\u0107 na to, \u017ce napisz\u0105 za nas ca\u0142y program, o tyle mog\u0105 \u015bwietnie si\u0119 sprawdzi\u0107 jako usprawnienie pracy. Zainstalowanie takiej wtyczki jak chocia\u017cby Copilot mo\u017ce przyspieszy\u0107 proste operacje czy te\u017c tworzenie komentarzy dzi\u0119ki trafnym podpowiedziom.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Je\u015bli nie pami\u0119tamy sk\u0142adni, argument\u00f3w biblioteki etc., sprawdzanie dokumentacji mo\u017ce okaza\u0107 si\u0119 ju\u017c zb\u0119dne. Asystenci AI mog\u0105 r\u00f3wnie\u017c przyspieszy\u0107 pisanie prostych test\u00f3w jednostkowych. Warto jednak najpierw napisa\u0107 kilka z nich samodzielnie, by asystent m\u00f3g\u0142 lepiej rozpozna\u0107 poprawny wz\u00f3r.&nbsp;<\/p>\n\n\n\n<p>Poni\u017cej kilka przyk\u0142ad\u00f3w najbardziej popularnych narz\u0119dzi programistycznych.&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GitHub Copilot<\/strong> \u2013 narz\u0119dzie analizuje kontekst kodu i pozwala zautomatyzowa\u0107, a tym samym przyspieszy\u0107 uzupe\u0142nianie fragment\u00f3w kodu. Przydatny w tworzeniu i przegl\u0105dzie dokumentacji oraz wyszukiwaniu konkretnych rozwi\u0105za\u0144.&nbsp;<\/li>\n\n\n\n<li><strong>Supermaven<\/strong> \u2013 sugeruje zale\u017cno\u015bci i poprawki w kodzie, eliminuj\u0105c b\u0142\u0119dy i optymalizuj\u0105c wydajno\u015b\u0107 aplikacji. Narz\u0119dzie mo\u017ce zasugerowa\u0107 u\u017cycie najlepszej biblioteki pod k\u0105tem danego projektu, co skraca czas analizy i przyspiesza proces wdra\u017cania nowych rozwi\u0105za\u0144.&nbsp;<\/li>\n\n\n\n<li><strong>Cursor AI<\/strong> \u2013 usprawnia prac\u0119 programist\u00f3w Python dzi\u0119ki inteligentnemu autouzupe\u0142nianiu, generowaniu kodu na podstawie j\u0119zyka naturalnego oraz mo\u017cliwo\u015bci szybkiego refactoringu.&nbsp;<\/li>\n\n\n\n<li><strong>Tabnine <\/strong>\u2013 pozwala uzupe\u0142nia\u0107 kod w czasie rzeczywistym, co zwi\u0119ksza produktywno\u015b\u0107 i pomaga unika\u0107 b\u0142\u0119d\u00f3w sk\u0142adniowych, a tak\u017ce eliminuje powtarzalno\u015b\u0107 zada\u0144 zwi\u0105zanych z pisaniem kodu.&nbsp;<\/li>\n\n\n\n<li><strong>S<\/strong><strong>ourcegraph Cody<\/strong> <strong>\u2013 <\/strong>sprawdza si\u0119 \u015bwietnie w<strong> <\/strong>zaawansowanym przeszukiwaniu kodu. Pozwala na zrozumienie zale\u017cno\u015bci w projektach oraz \u2013 dzi\u0119ki kontekstowej analizie ca\u0142ej bazy kodu \u2013 na szybkie odnajdywanie i poprawianie b\u0142\u0119d\u00f3w.&nbsp;<\/li>\n<\/ul>\n\n\n<\/style><div class=\"promotion-box promotion-box--image-left \"><div class=\"tiles latest-news-once\"><div class=\"tile\"><div class=\"tile-image\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/Code-Faster-Tlo-2.jpg\" alt=\"\" title=\"\"><\/div><div class=\"tile-content\"><p class=\"entry-title client-name\">AI w programowaniu | bezp\u0142atny e-book<\/p>\r\nZautomatyzuj kodowanie z AI! Pobierz darmowy e-book i odkryj nowe mo\u017cliwo\u015bci\r\n<br \/><br \/>\r\n<a class=\"btn btn-primary\" href=\"https:\/\/www.engage.inetum.com\/ebook-code-faster-build-smarter\/\" target=\"_blank\" rel=\"noopener\">Pobierz teraz!<\/a><\/div><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Podsumowanie\">Podsumowanie<\/h2>\n\n\n\n<p>Mnogo\u015b\u0107 dost\u0119pnych technologii w \u015bwiecie IT potrafi przyprawi\u0107 o zawr\u00f3t g\u0142owy. Samo okre\u015blenie roli w projekcie IT jeszcze nie determinuje wyboru narz\u0119dzi, z kt\u00f3rych b\u0119dziemy korzysta\u0107. Decydowa\u0107 o tym b\u0119d\u0105 w g\u0142\u00f3wnej mierze wymagania systemu. Czy powinien by\u0107 nastawiony na wydajne przetwarzanie du\u017cych ilo\u015bci danych, czy mo\u017ce bardziej istotna jest prostota w implementacji i szybkie wdro\u017cenie rozwi\u0105zania kosztem ni\u017cszej wydajno\u015bci? Odpowiedzenie sobie na te pytania czasem nie wystarczy, poniewa\u017c bywa, \u017ce kilka technologii spe\u0142nia wszystkie wymagania i wyb\u00f3r sprowadza si\u0119 do wzgl\u0119d\u00f3w czysto estetycznych i preferencji osobistych.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Na szcz\u0119\u015bcie s\u0105 spo\u0142eczno\u015bci i organizacje, kt\u00f3re skupiaj\u0105 ludzi zainteresowanych okre\u015blon\u0105 tematyk\u0105 i pomagaj\u0105 odnale\u017a\u0107 si\u0119 w g\u0105szczu wiedzy oraz poszerza\u0107 horyzonty, by by\u0107 na bie\u017c\u0105co. Dla os\u00f3b zwi\u0105zanych zawodowo z j\u0119zykiem programowania Python takim miejscem jest w\u0142a\u015bnie konferencja Python Summit. Prelekcje dost\u0119pne w trakcie Python Summit 2024 i zagadnienia, kt\u00f3re om\u00f3wi\u0142em, stanowi\u0105 tylko ma\u0142y wycinek wiedzy, jaki mo\u017cna by\u0142o wynie\u015b\u0107 z tego spotkania. Zapewniam, \u017ce ka\u017cdy znalaz\u0142by co\u015b dla siebie, nawet je\u015bli wybrane przeze mnie tematy nie s\u0105 w centrum zainteresowania danego programisty.&nbsp;<\/p>\n\n\n\n<p>Przeczytaj tak\u017ce nasze artyku\u0142y dotycz\u0105ce bibliotek Python:&nbsp;&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/numpy-wstep-do-biblioteki-python\/\" target=\"_blank\" rel=\"noreferrer noopener\">NumPy<\/a>&nbsp;<\/li>\n\n\n\n<li><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/biblioteka-matplotlib\/\" target=\"_blank\" rel=\"noreferrer noopener\">Matplotlib<\/a>&nbsp;<\/li>\n\n\n\n<li><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/biblioteki-python-pandas\/\" target=\"_blank\" rel=\"noreferrer noopener\">Pandas<\/a>&nbsp;<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Jak zwi\u0119kszy\u0107 efektywno\u015b\u0107 pracy w Pythonie i zadba\u0107 o czysty kod? Jak asystenci AI wspieraj\u0105 codzienn\u0105 prac\u0119 programist\u00f3w? Przeczytaj artyku\u0142 i odkryj, jak programowa\u0107 efektywniej dzi\u0119ki narz\u0119dziom AI i Machine Learning! <\/p>\n","protected":false},"author":202,"featured_media":34627,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"iawp_total_views":140,"footnotes":""},"categories":[1,582],"tags":[620,602],"offering":[522],"class_list":["post-34615","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artykuly","category-technologie","tag-ai-2","tag-python-2","offering-tech-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/34615","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/users\/202"}],"replies":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/comments?post=34615"}],"version-history":[{"count":8,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/34615\/revisions"}],"predecessor-version":[{"id":37368,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/34615\/revisions\/37368"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media\/34627"}],"wp:attachment":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media?parent=34615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/categories?post=34615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/tags?post=34615"},{"taxonomy":"offering","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/offering?post=34615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}