{"id":10062,"date":"2017-06-03T16:09:23","date_gmt":"2017-06-03T20:09:23","guid":{"rendered":"https:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=10062"},"modified":"2017-06-10T13:54:33","modified_gmt":"2017-06-10T17:54:33","slug":"pl-6d","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/pl-6d\/","title":{"rendered":"6D: Projektowanie debugowanie i p\u0105czki"},"content":{"rendered":"<!-- Please retain this notice and add more notes if you create a new version.<br \/>\nOriginal lesson author: David Pritchard, daveagp@gmail.com, http:\/\/cscircles.ca<br \/>\nLicense: http:\/\/creativecommons.org\/licenses\/by-nc-sa\/3.0\/-->\n<p>Ta lekcja zawiera pewne sugestie dotycz\u0105ce \u0142atwiejszego projektowania i debugowania program\u00f3w. Im d\u0142u\u017cej b\u0119dziesz programowa\u0107, tym \u0142atwiej b\u0119dziesz unika\u0107 b\u0142\u0119d\u00f3w i je naprawia\u0107, ale spr\u00f3bujemy poda\u0107 tutaj bardzo og\u00f3lne i przydatne porady. Wyt\u0142umaczymy nast\u0119puj\u0105ce techniki:<\/p>\n<ul>\n<li>budowanie tylko jednej cz\u0119\u015b\u0107 naraz<\/li>\n<li>rozwi\u0105zywanie kilku przyk\u0142ad\u00f3w r\u0119cznie<\/li>\n<li>planowanie kodu przed rozpocz\u0119ciem jego pisania<\/li>\n<li>zapisywanie kodu<\/li>\n<li>testowanie przyk\u0142ad\u00f3w, kt\u00f3re zosta\u0142y rozwi\u0105zane r\u0119cznie<\/li>\n<li>testowanie dodatkowych przyk\u0142ad\u00f3w, w tym przypadki \"graniczne\" i losowe<\/li>\n<\/ul>\n<p>Ta magiczna recepta nie rozwi\u0105\u017ce wszystkiego automatycznie, ale mo\u017ce zaoszcz\u0119dzi\u0107 ci b\u00f3lu g\u0142owy i zmniejszy\u0107 liczb\u0119 problem\u00f3w, z kt\u00f3rymi zetkniesz si\u0119 p\u00f3\u017aniej.<\/p>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Gdy masz problem, pewne strategie s\u0105 pomocne w debugowaniu <em>u\u017cywaj\u0105c instrukcji drukowania diagnostycznego<\/em> (b\u0119dziemy to robi\u0107 w czasie p\u00f3\u017aniejszych lekcji), <em>u\u017cywaj\u0105c wizualizatora<\/em>, <em>czytaj\u0105c kod<\/em> i <em>pisz\u0105c dobre testy<\/em>. Je\u015bli <a href=\"\/run-at-home\">uruchamiasz Pythona w domu<\/a>, mo\u017cesz u\u017cy\u0107 narzedzi breakpoint i step tools  by lepiej zrozumie\u0107, co si\u0119 nie powiod\u0142o. <\/span><\/td><\/table><\/p>\n<p><strong><a href=\"http:\/\/en.wikipedia.org\/wiki\/Algorithm\">Algorytm<\/a><\/strong> oznacza ci\u0105g instrukcji. Chocia\u017c, program komputerowy, aby dzia\u0142a\u0107, musi by\u0107 napisany w okre\u015blonym j\u0119zyku, takim jak Python czy JavaScript, to s\u0142owo <strong>algorytm <\/strong>oznacza instrukcje krok po kroku, kt\u00f3re mo\u017cna napisa\u0107 w j\u0119zyku polskim lub przedstawi\u0107 z uzyciem schematu blokowego. Na przyk\u0142ad przepis na p\u0105czki to algorytm, w kt\u00f3rym \"mierzenie 3 szklanek m\u0105ki\" jest jednym krokiem, a \"niech ciasto ro\u015bnie przez 2 godziny\" to kolejny krok. Na tej lekcji opracujemy prosty algorytm. Nast\u0119pnie algorytm <em>zaimplementujemy<\/em>, co oznacza przekszta\u0142cimy go w dzia\u0142aj\u0105cy program komputerowy.<\/p>\n<h2>Problem: Kalkulator p\u0105czk\u00f3w<\/h2>\n<p>Tim Horton's, sie\u0107 sklep\u00f3w z kaw\u0105 w Kanadzie, sprzedaje <strong>timbity<\/strong>, kt\u00f3re s\u0105 smacznymi p\u0105czkowymi kulkami:<\/p>\n<div style=\"width: 510px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.flickr.com\/photos\/looking_and_learning\/5358233785\/\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"http:\/\/farm6.staticflickr.com\/5203\/5358233785_13e36e1d76.jpg\" width=\"500\" height=\"375\" \/><\/a><p class=\"wp-caption-text\">Photo: looking_and_learning, flickr<\/p><\/div>\n<p>Masz zorganizowa\u0107 kilka wieczork\u00f3w w ci\u0105gu najbli\u017cszych kilku tygodni i b\u0119dziesz zamawia\u0142 na ka\u017cde ze spotka\u0144 inn\u0105 liczb\u0119 timbit\u00f3w. Tak wi\u0119c, aby zaplanowa\u0107 bud\u017cet, chcia\u0142by\u015b, aby program obliczy\u0142 koszt dowolnej liczby timbit\u00f3w. W lokalnej filii s\u0105 nast\u0119puj\u0105ce ceny:<\/p>\n<table style=\"width: 350px; margin: auto;\">\n<tbody>\n<tr>\n<th>Liczba<\/th>\n<th>Cena<\/th>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>0,20$<\/td>\n<\/tr>\n<tr>\n<td>10 (ma\u0142e pude\u0142ko)<\/td>\n<td>1,99$<\/td>\n<\/tr>\n<tr>\n<td>20 (\u015brednie pude\u0142ko)<\/td>\n<td>3,39$<\/td>\n<\/tr>\n<tr>\n<td>40 (du\u017ce pude\u0142ko)<\/td>\n<td>6,19$<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Zr\u00f3b jedn\u0105 cz\u0119\u015b\u0107 naraz<\/h2>\n<p>Ostatecznie chcesz napisa\u0107 program, w kt\u00f3rym dane wej\u015bciowe to <strong>P liczba os\u00f3b na imprezie<\/strong>, a wyj\u015bciowe to <strong>koszt pocz\u0119stunku dla wielu os\u00f3b wraz z podatkiem<\/strong>. Na najwy\u017cszym poziomie s\u0105 trzy elementy tego programu:<\/p>\n<ol>\n<li>obliczy\u0107, jaka jest <strong>T<\/strong> liczba timbit\u00f3w jak\u0105 nale\u017cy kupi\u0107 dla <strong>P<\/strong> ludzi?<\/li>\n<li>obliczy\u0107 kwot\u0119 za kt\u00f3r\u0105 mo\u017cna kupi\u0107 dok\u0142adnie <strong>T<\/strong> timbit\u00f3w<\/li>\n<li>obliczy\u0107 podatek i ca\u0142kowity koszt.<\/li>\n<\/ol>\n<p>Mo\u017cna jednocze\u015bnie pracowa\u0107 nad tymi trzema cz\u0119\u015bciami. Rekomendujemy jednak prac\u0119 nad ka\u017cd\u0105 z cz\u0119\u015bci oddzielnie, jej testowanie i modyfikowanie przed przyst\u0105pieniem do pracy przy nast\u0119pnej cz\u0119\u015bci, poniewa\u017c <em>im wi\u0119kszy jest Tw\u00f3j program, tym trudniej jest znale\u017a\u0107 i naprawi\u0107 poszczeg\u00f3lne b\u0142\u0119dy<\/em>. \u0141atwiej rozwija\u0107 i testowa\u0107 trzy cz\u0119\u015bci oddzielnie przed po\u0142\u0105czeniem ich w jeden program. Przez reszt\u0119 tej lekcji skoncentrujemy si\u0119 na kroku 2: <strong>obliczy\u0107 cen\u0119,  za kt\u00f3r\u0105 kupimy odpowiedni\u0105 ilo\u015b\u0107 T timbits\u00f3w<\/strong>.<\/p>\n<h2>Rozwi\u0105\u017c niekt\u00f3re przyk\u0142ady r\u0119cznie<\/h2>\n<p>Aby nakaza\u0107 komputerowi co\u015b zrobi\u0107, musisz by\u0107 w stanie zrobi\u0107 to samodzielnie. Przyjrzyjmy si\u0119 przyk\u0142adowi: jaki jest koszt zakupu dok\u0142adnie <strong>45<\/strong> timbit\u00f3w? Patrz\u0105c na list\u0119 cen zale\u017cn\u0105 od ilo\u015bci nabywanych timbits\u00f3w, mo\u017cemy kupi\u0107 jedno du\u017ce pude\u0142ko (40), kt\u00f3re kosztuje 6,19 USD. Pozostanie <strong>45 - 40 = 5<\/strong> timbit\u00f3w, kt\u00f3re musimy kupi\u0107 osobno, co stanowi dodatkowe koszty 5 * 0,20 USD = 1,00 USD. \u0141\u0105czny koszt wynosi 6,19 USD + 1,00 USD = 7,19 USD.<\/p>\n<h2>Przed rozpocz\u0119ciem pisania zaplanuj sw\u00f3j kod<\/h2>\n<p>Co zrobi\u0107, je\u015bli chcemy kupi\u0107 4 lub 456 timbits zamiast 45? Og\u00f3lnie rzecz bior\u0105c, powinni\u015bmy kupi\u0107 tyle du\u017cych pude\u0142ek, ile jest to mo\u017cliwe, a nast\u0119pnie \u015brednich i \/ lub ma\u0142ych pude\u0142ek i w razie potrzeby pojedynczych timbit\u00f3w tyle, aby uzyska\u0107 ca\u0142kowit\u0105 sum\u0119. <table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Czy ten algorytm jest naprawd\u0119 optymalny? Tak! Mo\u017cna zauwa\u017cy\u0107, \u017ce kupno dw\u00f3ch \u015brednich pude\u0142ek (2 * 3,39 z\u0142 = 6,78 z\u0142) to z\u0142y pomys\u0142, poniewa\u017c 2 x 20 = 40 timbit\u00f3w mo\u017cemy naby\u0107 taniej w jednym du\u017cym pude\u0142ku. Podobne wypada por\u00f3wnanie indywidualnych i ma\u0142ych oraz ma\u0142ych i \u015brednich, mo\u017cna to wykorzysta\u0107 do udowodnienia, \u017ce algorytm daje najni\u017csz\u0105 cen\u0119 kupna okre\u015blonej liczby timbit\u00f3w. <em>Je\u015bli realacje ceny do rozmiaru by\u0142y inne, to musieli\u015bmy by\u0107 bardziej ostro\u017cni.<\/em> <\/span><\/td><\/table><\/p>\n<p>Powiedzieli\u015bmy, \u017ce przed rozpocz\u0119ciem pisania kodu nale\u017cy go zaplanowa\u0107. Mo\u017cesz:<\/p>\n<ul>\n<li>poda\u0107 kr\u00f3tki krok po kroku opis algorytmu w j\u0119zyku polskim zamiast w Pythonie<\/li>\n<li>u\u017cy\u0107 diagramu lub schematu blokowego, aby wy\u015bwietli\u0107 kroki<\/li>\n<li>skupi\u0107 si\u0119 na g\u0142\u00f3wnych pomys\u0142ach, a nie na szczeg\u00f3\u0142ach.<\/li>\n<\/ul>\n<p>Dla naszego przyk\u0142adu podajemy opis w j\u0119zyku polskim.<em> Nie pokazujemy Ci schematu blokowego dla tego konkretnego programu, poniewa\u017c b\u0119dzie on przebiega\u0142 z kroku 1 do kroku 2 i tak dalej w prostej linii. Przy programach z p\u0119tlami, jak zobaczymy p\u00f3\u017aniej, bardziej s\u0105 przydatne diagramy.<\/em><\/p>\n<div style=\"margin-top: 0px; margin-right: 100px; margin-bottom: 0px; margin-left: 100px; border-width: 1px; border-color: blue; border-style: solid;\">\n<p style=\"text-align: center;\"><strong>Algorytm oblicza koszt dowolnej liczby timbit\u00f3w<\/strong><\/p>\n<ol>\n<li>uzyska\u0107 dane wej\u015bciowe: liczb\u0119 timbit\u00f3w<\/li>\n<li>\u015bledzi\u0107 ca\u0142kowity koszt, zaczynaj\u0105c od zera<\/li>\n<li>je\u015bli mo\u017cesz, kup jak najwi\u0119cej du\u017cych pude\u0142ek\n<ol>\n<li>obliczy\u0107, ile jeszcze potrzebujesz timbit\u00f3w<\/li>\n<li>zaktualizowa\u0107 ca\u0142kowity koszt<\/li>\n<\/ol>\n<\/li>\n<li>je\u015bli mo\u017cesz, kup jak najwi\u0119cej \u015brednich pude\u0142ek i powt\u00f3rz kroki A. i B<\/li>\n<li>je\u015bli mo\u017cesz, kup jak najwi\u0119cej ma\u0142ych pude\u0142ek i powt\u00f3rz kroki A. i B<\/li>\n<li>kup pojedyncze timbity i powt\u00f3rz krok B<\/li>\n<li>wyprowad\u017a ca\u0142kowity koszt<\/li>\n<\/ol>\n<\/div>\n<p>Ten opisem algorytmu nazywamy <strong>pseudokodem<\/strong>, poniewa\u017c jest to seria instrukcji krok po kroku, ale nie w prawdziwym j\u0119zyku programowania. <\/p>\n<h2>Zapisz kod<\/h2>\n<p>Powtarzaj\u0105c pierwsz\u0105 cz\u0119\u015b\u0107 porad, <em>buduj tylko jedn\u0105 cz\u0119\u015b\u0107 naraz<\/em>, mo\u017cesz r\u00f3wnie\u017c pomy\u015ble\u0107 o pisaniu osobnego fragmentu kodu dla ka\u017cdego etapu od 1 do 7. Dodatkowo, oto jedna rzecz, o kt\u00f3rej musimy my\u015ble\u0107 dla wszystkich krok\u00f3w: Jakie zmienne b\u0119dziemy u\u017cywa\u0107? Jakie b\u0119d\u0105 ich nazwy, typy i warto\u015bci pocz\u0105tkowe?<\/p>\n<p>U\u017cyjemy <code>timbitsLeft<\/code> do reprezentowania liczby timbit\u00f3w, jakie musimy jeszcze kupi\u0107, <code>totalCost<\/code> u\u017cyjmy do przedstawienia ca\u0142kowitego kosztu. Nie musimy wcze\u015bniej ustala\u0107 typ\u00f3w danych dla Pythona, ale mo\u017cemy sobie wyobrazi\u0107, \u017ce <code>timbitsLeft<\/code> b\u0119dzie <code>int<\/code>, a <code>totalCost<\/code> b\u0119dzie zmienn\u0105 typu <code>float<\/code> mierz\u0105c\u0105 ca\u0142kowity koszt w dolarach. (Jeden cent to 0,01 dolara). W trakcie b\u0119dziemy potrzebowa\u0107 dodatkowych tymczasowych zmiennych, kt\u00f3rymi zajmiemy tylko w razie potrzeby.<\/p>\n<p>Kroki 1 i 2 mo\u017cna zapisa\u0107 jednym wierszem kodu:<\/p>\n<pre>timbitsLeft = int(input()) # krok 1: uzyska\u0107 dane wej\u015bciowe\r\ntotalCost = 0              # krok 2: nada\u0107 zmiennej totalCost warto\u015b\u0107 pocz\u0105tkow\u0105<\/pre>W kroku 3 musimy obliczy\u0107 maksymaln\u0105 liczb\u0119 du\u017cych pude\u0142ek, kt\u00f3re mo\u017cna kupi\u0107. Jak dok\u0142adnie mo\u017cemy to zrobi\u0107? Poniewa\u017c du\u017ce pude\u0142ko zawiera 40 timbit\u00f3w, liczba <code>bigBox\u00f3w<\/code> powinna by\u0107 liczb\u0105 ca\u0142kowit\u0105 uzyskan\u0105 z dzielenia <code>timbitsLeft<\/code> przez <code>40<\/code>. \u015aledz\u0105c dzielenie, koszty i odejmowanie, otrzymujemy kolejny fragment kodu:<\/p>\n<pre># krok 3: kupi\u0107, ile si\u0119 da, du\u017cych pude\u0142ek\r\nbigBoxes = timbitsLeft \/ 40\r\ntotalCost = totalCost + bigBoxes * 6.19    # zaktualizowa\u0107 ca\u0142kowity koszt\r\ntimbitsLeft = timbitsLeft - 40 * bigBoxes  # obliczy\u0107, ile jeszcze trzeba kupi\u0107 <\/pre>Wyobra\u017acie sobie, \u017ce ju\u017c pope\u0142nili\u015bmy b\u0142\u0105d. Najlepszym sposobem na wy\u0142apanie b\u0142\u0119d\u00f3w jest od samego pocz\u0105tku testowanie kodu  i robienie tego cz\u0119sto! M\u00f3wi\u0105c optymistycznie, w tym momencie przetestowali\u015bmy kod do tego punktu. Wystarczy doda\u0107 kilka polece\u0144 wydruku, aby obserwowa\u0107 jego dotychczasowe zachowanie. (<em>Aby sprawdzi\u0107 ka\u017cdy krok, zamiast u\u017cywa\u0107 instrukcji drukowania, mo\u017cemy r\u00f3wnie\u017c u\u017cy\u0107 wizualizatora<\/em>).<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform0\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox0'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Testowanie kodu w celu debugowania przy danych wej\u015bciowych <strong>45<\/strong> z u\u017cyciem instrukcji <code>print<\/code>.<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 370px;'><textarea wrap='off' name='usercode0' id='usercode0'  cols=10 rows=14 readonly='readonly'  style = 'height : 370px;'  class='pyboxCode RO'>\ntimbitsLeft = int(input()) # krok 1: wprowadzenie danych wej\u015bciowych\n\nprint('the input is', timbitsLeft)\n\ntotalCost = 0              # krok 2: zainicjowanie zmiennej totalCost (nadanie jej warto\u015bci pocz\u0105tkowej)\n\n# krok 3: kupowanie du\u017cych pude\u0142ek, ile si\u0119 da\nbigBoxes = timbitsLeft \/ 40\ntotalCost = totalCost + bigBoxes * 6.19    # aktualizacja ca\u0142kowitego kosztu\ntimbitsLeft = timbitsLeft - 40 * bigBoxes  # ile jeszce potrzebujemy timbit\u00f3w?\n\nprint('bigBoxes equals', bigBoxes)\nprint('totalCost equals', totalCost)\nprint('now timbitsLeft equals', timbitsLeft)<\/textarea><\/div>\n<div id='pbhistory0' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit0' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(0)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(0,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse0\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"0\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"931c802f3946d9615f3ad4fbadeddc2b\"\/>\n<div id='pbresults0' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit0\").value = \"Run program\";document.getElementById(\"inputInUse0\").value = \"N\";<\/script>\n<\/p>\n<p>To nie dzia\u0142a tak jak chcieli\u015bmy! W czym problem?<strong> Kt\u00f3ra linia jako pierwsza jest inna od tego co planowali\u015bmy?<\/strong> Spr\u00f3buj zlokalizowa\u0107 j\u0105 przed otwarciem nast\u0119pnego akapitu. Pami\u0119taj, \u017ce wcze\u015bniej rozwi\u0105zali\u015bmy ten przyk\u0142ad r\u0119cznie.<\/p>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nKliknij, aby przeczyta\u0107 wyja\u015bnienie. \n<\/div>\n<div class='collapseBody'>Sprawc\u0105 jest linia b<code>igBoxes = timbitsLeft \/ 40<\/code>, poniewa\u017c w <code>bigBoxes<\/code> otrzymujemy <code>1,125<\/code>, a spodziewali\u015bmy si\u0119 otrzyma\u0107 <code>1<\/code>. Nie mo\u017cna kupi\u0107 u\u0142amka pude\u0142ka. Jednym z mo\u017cliwych obej\u015b\u0107, kt\u00f3re b\u0119dzie mo\u017cna zobaczy\u0107 w lekcji 7A, jest u\u017cycie operatora dzielenia bez reszty <code>\/\/<\/code> (odrzuca cz\u0105\u015b\u0107 u\u0142amkow\u0105 i zaokr\u0105gla wynik do najbli\u017cszej liczby ca\u0142kowitej z lewej strony na osi liczbowej) zamiast <code>\/<\/code> zwyk\u0142ego dzielenia. Innym rozwi\u0105zaniem, opieraj\u0105cym si\u0119 na tym, co widzieli\u015bmy w \u0107wiczeniu 4, jest przekonwertowanie <code>timbitsLeft \/ 40<\/code> do <code>int<\/code>, co usunie cz\u0119\u015b\u0107 u\u0142amkow\u0105. U\u017cyjemy tego podej\u015bcia: linia zmieni si\u0119 <code>bigBoxes = int(timbitsLeft \/ 40)<\/code>.<br \/>\n<\/div><\/div>\n<p>Kroki 4 i 5 s\u0105 podobne do kroku 3. Alternatywnie, poniewa\u017c kupisz co najwy\u017cej jedno \u015brednie i co najwy\u017cej jedno ma\u0142e pude\u0142ko, mo\u017cemy u\u017cy\u0107 instrukcji <code>if<\/code>:<\/p>\n<pre>if timbitsLeft &gt;= 20: # step 4, czy mo\u017cemy kupi\u0107 \u015brednie pude\u0142ko?\r\n\u00a0 totalCost = totalCost + 3.39\r\n\u00a0 timbitsLeft = timbitsLeft - 20\r\nif timbitsLeft &gt;= 10: # step 5, czy mo\u017cemy kupi\u0107 ma\u0142e pude\u0142ko?\r\n\u00a0 totalCost = totalCost + 1.99\r\n\u00a0 timbitsLeft = timbitsLeft - 20<\/pre>Aby zako\u0144czy\u0107, musimy zap\u0142aci\u0107 20 cent\u00f3w za ka\u017cde z ostatnich potrzebnych timbit\u00f3w i wyprowadzi\u0107 wynik.<\/p>\n<pre>totalCost = totalCost + timbitsLeft * 20 # krok 6\r\nprint(totalCost)                         # krok 7<\/pre>\n<h2>Sprawd\u017a przyk\u0142ady, kt\u00f3re zosta\u0142y rozwi\u0105zane r\u0119cznie<\/h2>\n<p>Oto ca\u0142y program. Pierwsz\u0105 rzecz\u0105, kt\u00f3r\u0105 zrobimy to sprawdzenie, czy dzia\u0142a on przy danych wej\u015bciowych <strong>45<\/strong>, dla kt\u00f3rych wykonali\u015bmy obliczenia r\u0119cznie.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform1\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox1'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Jaka jest cena za 45 timbit\u00f3w?<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 448px;'><textarea wrap='off' name='usercode1' id='usercode1'  cols=10 rows=17 readonly='readonly'  style = 'height : 448px;'  class='pyboxCode RO'>\ntimbitsLeft = int(input()) # krok 1: wprowadzenie danych wej\u015bciowych\ntotalCost = 0              # krok 2: zainicjowanie zmiennej totalCost (nadanie jej warto\u015bci pocz\u0105tkowej)\n\n# krok 3: kupowanie du\u017cych pude\u0142ek, ile si\u0119 da\nbigBoxes = int(timbitsLeft \/ 40)\ntotalCost = totalCost + bigBoxes * 6.19    # aktualizacja ca\u0142kowitego kosztu\ntimbitsLeft = timbitsLeft - 40 * bigBoxes  # ile jeszce potrzebujemy timbit\u00f3w?\n\nif timbitsLeft >= 20:                # krok 4, czy mo\u017cemy kupi\u0107 \u015brednie pude\u0142ka?\n    totalCost = totalCost + 3.39\n    timbitsLeft = timbitsLeft - 20\nif timbitsLeft >= 10:                # krok 5, czy mo\u017cemy kupi\u0107 ma\u0142e pude\u0142ka?\n    totalCost = totalCost + 1.99\n    timbitsLeft = timbitsLeft - 20\n\ntotalCost = totalCost + timbitsLeft * 20 # krok 6\nprint(totalCost)                         # krok 7<\/textarea><\/div>\n<div id='pbhistory1' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput1\">You may enter input for the program in the box below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit1' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch1\" value=\"Input Switch\" onclick=\"pbInputSwitch(1,'N')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(1)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(1,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse1\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"1\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"52b38500b326535766ce4501a156e16f\"\/>\n<div id='pbresults1' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>pbInputSwitch(1,\"N\");<\/script>\n<\/p>\n<p>Musi by\u0107 b\u0142\u0105d, poniewa\u017c p\u0142acimy ponad 100 dolar\u00f3w za 45 timbit\u00f3w! Twoim ko\u0144cowym zadaniem jest znalezienie i wyeliminowanie tego b\u0142\u0119du oraz jeszcze innego b\u0142\u0119du ukrytego w kodzie. Zostanie on przetestowany w nast\u0119pnej sekcji.<\/p>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Wi\u0119c ju\u017c wiesz, \u017ce zabawna rzecz dzieje si\u0119  dzieje z cen\u0105, kt\u00f3ra nie jest b\u0142\u0119dem: mo\u017ce okaza\u0107 si\u0119 ta\u0144szy zakup dok\u0142adnie <strong>T + 1<\/strong> timbit\u00f3w ni\u017c zakup dok\u0142adnie <strong>T<\/strong> timbit\u00f3w. Na przyk\u0142ad zakup dok\u0142adnie 19 timbit\u00f3w kosztuje 3,79 USD, ale zakup dok\u0142adnie 20 timbit\u00f3w kosztuje tylko 3,39 USD. Niezale\u017cnie od tych spostrze\u017ce\u0144, b\u0119dziemy trzyma\u0107 si\u0119 zasady kupowania <em>dok\u0142adnie<\/em> <strong>T<\/strong> timb\u00f3w tak tanio, jak to tylko mo\u017cliwe i algorytm wyja\u015bniony wcze\u015bniej jest poprawny. Wi\u0119c tw\u00f3j program powinien  wygenerowa\u0107 wynik <code>3,79<\/code>, gdy na wej\u015bciu  podamy <code>19<\/code>. <\/span><\/td><\/table><\/p>\n<h2>Sprawd\u017a dodatkowe przyk\u0142ady<\/h2>\n<p>W Computer Science Circles staramy si\u0119 inteligentnie zautomatyzowa\u0107 testowanie kodu w celu upewnienia si\u0119, \u017ce rozwi\u0105za\u0142e\u015b dany problem prawid\u0142owo. Ale w prawdziwym testowaniu programu, na tobie spoczywa obowi\u0105zek sprawdzenia w\u0142asnego kodu. Oto kilka przydatnych wskaz\u00f3wek do testowania.<\/p>\n<ul>\n<li>Sprawdzi\u0107, czy <em>ka\u017cda linia kodu<\/em> programu dzia\u0142a prawid\u0142owo. W problemie z timbitami, gdy na wej\u015bciu jest <code>10<\/code> sprawdzisz, czy prawid\u0142owo obs\u0142ugiwane s\u0105 ma\u0142e pude\u0142ka. Podobnie, gdy na wej\u015bciu masz <code>20<\/code> i <code>40<\/code> sprawdzisz, czy \u015brednie i du\u017ce pola s\u0105 prawid\u0142owo obs\u0142ugiwane. Na koniec sprawd\u017a, czy prawid\u0142owo program dzia\u0142a dla  pojedynczych timbit\u00f3w (np. na wej\u015bciu <code>1<\/code>).\n<ul>\n<li>To\tmo\u017ce pom\u00f3c w sprawdzeniu, czy poprawnie wpisywano warto\u015bci, takie jak 3,39 USD i 1,99 USD.\n<\/li>\n<\/ul>\n<\/li>\n<li>Sprawd\u017a przypadki \"graniczne\", kt\u00f3re mog\u0105 spycha\u0107 program do jego granic. Na przyk\u0142ad minimalne mo\u017cliwe wej\u015bcie dla tego programu to <code>0<\/code>, poniewa\u017c nie mo\u017cna mie\u0107 ujemnych timbit\u00f3w. Nasz program dla danych wej\u015bciowych nie ma ograniczenia g\u00f3rnego, ale warto spr\u00f3bowa\u0107 takich warto\u015bci jak <code>39<\/code> i <code>41<\/code>, kt\u00f3re s\u0105 bliskie granicy kupowania jednego du\u017cego pude\u0142ka.\n<p>Mo\u017ce to pom\u00f3c w sprawdzeniu, czy przypadkowo nie wpisa\u0142e\u015b> kiedy powiniene\u015b wpisa\u0107> = zamiast tego.<\/p>\n<ul>\n<li>\nTo pomo\u017ce w sprawdzenie, czy przypadkiem nie wpisa\u0142e\u015b <code>&gt;<\/code> zamiast <code>&gt;=<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>Aby sprawdzi\u0107, czy program dzia\u0142a poprawnie w niekt\u00f3rych przypadkach mo\u017cna automatycznie sprawdzi\u0107 ka\u017cde wej\u015bcie lub sprawdzi\u0107 du\u017c\u0105 liczb\u0119 <em>losowych <\/em>wej\u015b\u0107. W testach wewn\u0119trznych CS Circles u\u017cywamy losowych danych wej\u015bciowych. U\u017cyj na pocz\u0105tku swojego programu <code>import random<\/code> a nast\u0119pnie na przyk\u0142ad <code>random.randint (10, 100)<\/code>, co wygeneruje losow\u0105 liczb\u0119 ca\u0142kowit\u0105 mi\u0119dzy 10 a 100.<\/li>\n<\/ul>\n<p>Czy mo\u017cesz znale\u017a\u0107 oba b\u0142\u0119dy i zaliczy\u0107 wszystkie testy? Spr\u00f3buj!<\/p>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Niekt\u00f3re obliczenia powoduj\u0105 bardzo ma\u0142e b\u0142\u0119dy w Pythonie:  <form class=\"pbform\" action=\"#\" id=\"pbform2\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox2'>\n<div class=\"heading\"><span class='type'>Example: <\/span><span class='title'>B\u0142\u0105d zaokr\u0105glenia<\/span><\/div> <div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 32px;'><textarea wrap='off' name='usercode2' id='usercode2'  cols=10 rows=1 readonly='readonly'  style = 'height : 32px;'  class='pyboxCode RO'>\nprint(35 * 0.01)<\/textarea><\/div>\n<div id='pbhistory2' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit2' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(2)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(2,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse2\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"2\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"087e07913c8dc4de9bf5b6a8bfbbcec5\"\/>\n<div id='pbresults2' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit2\").value = \"Run program\";document.getElementById(\"inputInUse2\").value = \"N\";<\/script>\n  To zaskakuj\u0105ce, \u017ce kod powy\u017cej nie daje dok\u0142adnie <code>0,35<\/code>! Ma to zwi\u0105zek z tym, jak Python przechowuje informacje. Nie przejmuj si\u0119 takimi drobnymi b\u0142\u0119dami: nasz automatyczny tester ignoruje je. Na ten temat powiemy wi\u0119cej w lekcji 7B. <\/span><\/td><\/table><\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform3\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox3'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Timbity<\/span><\/div>Napraw b\u0142\u0119dy i przejd\u017a wszystkie testy.<div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode3' id='usercode3'  cols=10 rows=20   class='pyboxCode RW'>\ntimbitsLeft = int(input()) # krok 1: wprowadzenie danych wej\u015bciowych\ntotalCost = 0              # krok 2: zainicjowanie zmiennej totalCost (nadanie jej warto\u015bci pocz\u0105tkowej)\n\n# krok 3: kupowanie du\u017cych pude\u0142ek, ile si\u0119 da\nbigBoxes = int(timbitsLeft \/ 40)\ntotalCost = totalCost + bigBoxes * 6.19    # aktualizacja ca\u0142kowitego kosztu\ntimbitsLeft = timbitsLeft - 40 * bigBoxes  # ile jeszce potrzebujemy timbit\u00f3w?\n\nif timbitsLeft >= 20:                # krok 4, czy mo\u017cemy kupi\u0107 \u015brednie pude\u0142ka?\n    totalCost = totalCost + 3.39\n    timbitsLeft = timbitsLeft - 20\nif timbitsLeft >= 10:                # krok 5, czy mo\u017cemy kupi\u0107 ma\u0142e pude\u0142ka?\n    totalCost = totalCost + 1.99\n    timbitsLeft = timbitsLeft - 20\n\ntotalCost = totalCost + timbitsLeft * 20 # krok 6\nprint(totalCost)                         # krok 7\n<\/textarea><\/div>\n<div id='pbhistory3' class='flexcontain' style='display:none;'><\/div>\n<input type='hidden' id='defaultCode3' value='timbitsLeft = int(input()) # krok 1: wprowadzenie danych wej\\u015bciowych\\ntotalCost = 0              # krok 2: zainicjowanie zmiennej totalCost (nadanie jej warto\\u015bci pocz\\u0105tkowej)\\n\\n# krok 3: kupowanie du\\u017cych pude\\u0142ek, ile si\\u0119 da\\nbigBoxes = int(timbitsLeft \\\/ 40)\\ntotalCost = totalCost + bigBoxes * 6.19    # aktualizacja ca\\u0142kowitego kosztu\\ntimbitsLeft = timbitsLeft - 40 * bigBoxes  # ile jeszce potrzebujemy timbit\\u00f3w?\\n\\nif timbitsLeft >= 20:                # krok 4, czy mo\\u017cemy kupi\\u0107 \\u015brednie pude\\u0142ka?\\n    totalCost = totalCost + 3.39\\n    timbitsLeft = timbitsLeft - 20\\nif timbitsLeft >= 10:                # krok 5, czy mo\\u017cemy kupi\\u0107 ma\\u0142e pude\\u0142ka?\\n    totalCost = totalCost + 1.99\\n    timbitsLeft = timbitsLeft - 20\\n\\ntotalCost = totalCost + timbitsLeft * 20 # krok 6\\nprint(totalCost)                         # krok 7\\n'><\/input>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit3' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(3)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(3,'N')\" ><\/td>\n<td><input type='button' name='history' value=\"History\" onclick=\"historyClick(3,'6d.timbits')\" ><\/td>\n<\/tr><\/table><select id='pbSelect3' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='default' data-pbonclick=\"pbSetText(3,descape($('#defaultCode3').val()))\" >Reset code to default<\/option>\n<option name='help' data-pbonclick=\"helpClick(3);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse3\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"3\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"4bc69af3bb59a0c9135d4bc2603a7594\"\/>\n<div id='pbresults3' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(3);});document.getElementById(\"submit3\").value = \"Run program\";document.getElementById(\"inputInUse3\").value = \"N\";<\/script>\n<\/p>\n<p>G\u0142odny? Jeste\u015b gotowy by kontynuowa\u0107 i przej\u015b\u0107 do nast\u0119pnej lekcji!<\/p>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> <img decoding=\"async\" alt=\"\" src=\"http:\/\/farm4.staticflickr.com\/3540\/3460673214_0292a66ffa_n.jpg\" \/>Podczas, gdy 10 timbit\u00f3w daje jedno pude\u0142ko, to 8 tim<a href=\"http:\/\/en.wikipedia.org\/wiki\/Bit\">bit\u00f3w<\/a> daje jeden tim<a href=\"http:\/\/en.wikipedia.org\/wiki\/Byte\">byte<\/a>. <a href=\"http:\/\/www.flickr.com\/photos\/thisisbrianfisher\/3460673214\/\"><em>Photo: thisisbrianfisher, flickr<\/em><\/a> <\/span><\/td><\/table><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ta lekcja zawiera pewne sugestie dotycz\u0105ce \u0142atwiejszego projektowania i debugowania program\u00f3w. Im d\u0142u\u017cej b\u0119dziesz programowa\u0107, tym \u0142atwiej b\u0119dziesz unika\u0107 b\u0142\u0119d\u00f3w i je naprawia\u0107, ale spr\u00f3bujemy poda\u0107 tutaj bardzo og\u00f3lne i przydatne porady. Wyt\u0142umaczymy nast\u0119puj\u0105ce techniki: budowanie tylko jednej cz\u0119\u015b\u0107 naraz &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/pl-6d\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-10062","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/10062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=10062"}],"version-history":[{"count":31,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/10062\/revisions"}],"predecessor-version":[{"id":10118,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/10062\/revisions\/10118"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=10062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}