Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to Write Robust Python Code

How to Write Robust Python Code

Avatar for HayaoSuzuki

HayaoSuzuki

May 29, 2023
Tweet

More Decks by HayaoSuzuki

Other Decks in Technology

Transcript

  1. Who am I ? ͓લ୭Α ໊લ Hayao Suzukiʢླ໦ɹॣʣ Twitter @CardinalXaro

    ࢓ࣄ Software Developer @ BeProud Inc. › גࣜձࣾϏʔϓϥ΢υ › IT ษڧձࢧԉαʔϏε connpass › ΦϯϥΠϯֶशαʔϏε PyQ › γεςϜ։ൃͷͨΊͷυΩϡϝϯταʔϏε Tracery › 2023 ೥ 5 ݄ 23 ೔ʹ૑ཱ 17 प೥Λܴ͑ͨ 2 / 46
  2. Who am I ? ؂༁ٕͨ͠ज़ॻ › ϩόετ Python(O’Reilly Japan) New!

    › ೖ໳ Python 3 ୈ 2 ൛ (O’Reilly Japan) ࠪಡٕͨ͠ज़ॻʢൈਮʣ › Effective Python ୈ 2 ൛ (O’Reilly Japan) › ϚΠΫϩϑϩϯτΤϯυ (O’Reilly Japan) › ϚΠΫϩαʔϏεΞʔΩςΫνϟ ୈ 2 ൛ (O’Reilly Japan) › SQL Ͱ͸͡ΊΔσʔλ෼ੳ (O’Reilly Japan) New! https://xaro.hatenablog.jp/ ʹϦετ͕͋Γ·͢ɻ 3 / 46
  3. Who am I ? ൃදϦετʢൈਮʣ › ϨΨγʔ Django ΞϓϦέʔγϣϯͷݱ୅Խ (DjangoCongress

    JP 2018) › SymPy ʹΑΔ਺ࣜॲཧ (PyCon JP 2018) › Python ͱָ͠Ήॳ౳੔਺࿦ (PyCon mini Hiroshima 2019) › ܅͸ cmath Λ஌͍ͬͯΔ͔ (PyCon mini Shizuoka 2020) › ΠϯϝϞϦʔετϦʔϜ׆༻ज़ (PyCon JP 2020) › ૊ΈࠐΈؔ਺ pow ͷ஌ΒΕ͟ΔਐԽ (PyCon JP 2021) https://xaro.hatenablog.jp/ ʹϦετ͕͋Γ·͢ɻ 4 / 46
  4. ࠓ೔ͷςʔϚ ݪஶʰRobust Pythonʱ ஶऀ Patrick Viafore ग़൛ࣾ O’Reilly Media ൃߦ೔

    2021 ೥ 7 ݄ ๜༁ʰϩόετ Pythonʱ ຋༁ऀ ླ໦ ॣ ؂༁ɺ௕ඌ ߴ߂ ༁ ग़൛ࣾ O’Reilly Japan ൃߦ೔ 2023 ೥ 3 ݄ ௕ඌ͞Μɺླ໦ͷϖΞ͸ʰೖ໳ Python 3 ୈ 2 ൛ʱҎདྷ 2 ճ໨ 5 / 46
  5. ϩόετ Python ͷߏ੒ 4 ෦ߏ੒ ୈ I ෦ ܕΞϊςʔγϣϯ ୈ

    II ෦ Ϣʔβఆٛܕ ୈ III ෦ େن໛ͳมߋ΁ͷରԠ ୈ IV ෦ ηʔϑςΟωοτͷߏங ͳ͓ɺୈ 1 ষʮϩόετ Python ೖ໳ʯ͸ಋೖͱͳΔষ 7 / 46
  6. ैདྷͷٕज़ॻͱͷҧ͍ Python ͱܕώϯτ › ܕώϯτ͸ Python 3.5 ͰಋೖʢPEP 484ʣ ›

    Python 3.5 ͸ 2015 ೥ 9 ݄ʹϦϦʔε ܕώϯτͷ෇͚ํ͸͢Ͱʹ஌ͬͯΔΑ › ܕώϯτͷ෇͚ํͷղઆهࣄ΍ॻ੶͸ଟ͍ʢ8 ೥ͷ஝ੵʣ › ܕώϯτͷӡ༻ํ๏΍ߟ͑ํʹ౿ΈࠐΜͩຊ͸ଘࡏ͢Δͷ͔ ͦ΋ͦ΋ɺதڃऀҎ্޲͚ͷ Python ຊͷઈର਺͕গͳ͍ΑͶ 8 / 46
  7. ϩόετ Python ͷ͕͍͜͜͢͝ ϩόετ Python ͷಛ௃ › ܕώϯτʹ͍ͭͯ 14 ষʹΘͨͬͯৄࡉʹղઆʢୈ

    I ෦ɺୈ II ෦ʣ › ϩόετͳઃܭ࿦ʢୈ III ෦ʣ › ܕώϯτ΍ܕ͚ͩͰ͸Χόʔ͖͠Εͳ͍ཁૉ΋ରԠʢୈ IV ෦ʣ 9 / 46
  8. ୈ 1 ষ ϩόετ Python ೖ໳ ϩόετ Python ͬͯͲΜͳຊ ཁ͢Δʹɺຊॻ͸ϩόετʢؤৎ/ؤ݈/ݎ࿚ʣͳ

    Python Λॻͨ͘ΊͷຊͰ͋Δɻ ʢP. 1ʣ ͦ΋ͦ΋ϩόετͬͯԿʁ ίʔυϕʔεͷϩόετωεͱ͸ɺઈ͑ͣมԽͯ͠΋଱ٱੑ͕ߴ͘ɺΤϥʔΛى͜͞ͳ ͍͜ͱͰ͋Δɻ ʢP. 4ʣ 11 / 46
  9. ୈ 1 ষ ϩόετ Python ೖ໳ ྫɿ ԿΛ͢Δؔ਺Ͱ͠ΐ͏͔ʁ def adjust_recipe(recipe,

    servings): old_servings = recipe.pop(0) factor = servings / old_servings # ؆୯ʹܭଌͰ͖Δ஋͚ͩΛ࢖͍ͬͯͩ͘͞ new_recipe = {ingredient: (amount * factor, unit) for ingredient, amount, unit in recipe} new_recipe["servings"] = servings return new_recipe 13 / 46
  10. ୈ 1 ষ ϩόετ Python ೖ໳ ௿ίετͰۙ઀ੑ͕ෆཁͳίϛϡχέʔγϣϯ › ίʔυΛಡΉ͚ͩͰཧղͰ͖Ε͹Α͍ ›

    ίʔυΛཧղ͢Δͷʹඞཁͳ࣌ؒΛ࠷খݶʹ཈͍͑ͨ ͦͷͨΊʹ͸ʁ σʔλܕͷબ୒͸কདྷͷ։ൃऀʹରͯࣗ͠෼ͷҙਤΛදݱ͢Δ͜ͱͰ͋Γɺਖ਼͍͠σʔ λܕΛબ୒͢Ε͹อकੑ͕޲্͢Δɻ ʢP. 19ʣ 16 / 46
  11. ୈ 1 ষ ϩόετ Python ೖ໳ ྫɿ ԿΛ͢Δؔ਺Ͱ͠ΐ͏͔ʁ from fractions

    import Fraction def adjust_recipe(recipe: Recipe, servings: int) -> Recipe: # ࡐྉσʔλͷίϐʔΛ࡞Δ new_ingredients = list(recipe.get_ingredients()) recipe.clear_ingredients() for ingredient in new_ingredients: ingredient.adjust_proportion( Fraction(servings, recipe.servings) ) return Recipe(servings, new_ingredients) 17 / 46
  12. ୈ I ෦ ܕΞϊςʔγϣϯ 2 ষ Python σʔλܕೖ໳ › Python

    ͸ڧ͍ܕ෇͚ݴޠ › Python ͸ಈతܕ෇͚ݴޠ ಈతܕ෇͚ݴޠ͸ຊ࣭తʹϩόετͰ͸ͳ͍ͷ͔ › ಈతܕ෇͚ݴޠͰ΋ϩόετʹॻ͚Δɺগ͠େมͳ͚ͩ › ੩తܕ෇͚ݴޠͷ৔߹ΑΓ΋Α͘ߟ͑Δඞཁ͕͋Δ › ੩తܕ෇͚ݴޠΛ࢖͑͹ඞͣ͠΋ϩόετʹॻ͚ΔΘ͚Ͱ͸ͳ͍ 18 / 46
  13. ୈ I ෦ ܕΞϊςʔγϣϯ 3 ষ ܕΞϊςʔγϣϯ › ܕώϯτͷߏจతͳ෇͚ํ͸஌͍ͬͯΔΑͶʢ8 ೥ͷ஝ੵʣ

    › ܕώϯτ͸πʔϧʢmypy ͳͲʣͱ૊Έ߹ΘͤͯਅՁΛൃش͢Δ ܕώϯτ΋ mypy ΋λμͰ͸ͳ͍ › ެ։ APIɺϥΠϒϥϦͷΤϯυϙΠϯτ › ෳࡶͳܕɺΘ͔Γʹ͍͘ܕ › mypy ઌੜͷࢦࣔʹै͏ 19 / 46
  14. ୈ I ෦ ܕΞϊςʔγϣϯ 4 ষ ܕ੍໿ › Optional Ͱ͵ΔΆόάΛ௵ͦ͏

    › Union ͰදݱՄೳͳঢ়گΛݮͦ͏ › Literal Ͱ͞Βʹ੍໿Λ͔͚Α͏ › Final Ͱఆ਺Ͱ͋Δͱओு͠Α͏ › NewType ͰજࡏతͳόάΛ௵ͦ͏ Annotated ͷ͜ͱɺ࣌ʑͰ͍͍͔Βɺࢥ͍ग़͍ͯͩ͘͠͞ › ೚ҙͷϝλσʔλΛ௥ՃͰ͖Δ͕ɺ୯ͳΔϝλσʔλ › ઐ༻ͷπʔϧ͕Ͱ͖ͨΒ೤͘ͳΔ͔΋ 20 / 46
  15. ୈ I ෦ ܕΞϊςʔγϣϯ ྫɿ දݱՄೳͳঢ়ଶ͸Կ௨Γʁ @dataclass class Snack: name:

    str # 3 ௨Γ condiments: set[str] # 4 ௨Γ error_code: int # 6 ௨Γʢ੒ޭ͕ 0 Τϥʔ͕ 1 ͔Β 5ʣ disposed_of: bool # 2 ௨Γ snack = Snack("Hotdog", {"Mustard", "Ketchup"}, 5, False) ౴͑ɿ3 ˆ 4 ˆ 6 ˆ 2 = 144 ௨ΓɻNone ΋ڐ༰͢Δͱʁ 21 / 46
  16. ୈ I ෦ ܕΞϊςʔγϣϯ ྫɿ දݱՄೳͳঢ়ଶ͸Կ௨Γʁ @dataclass class Snack: name:

    str # 3 ௨Γ condiments: set[str] # 4 ௨Γ @dataclass class Error: error_code: int # 5 ௨Γʢ੒ޭύλʔϯΛऔΓআ͚Δʣ disposed_of: bool # 2 ௨Γ snack: Union[Snack, Error] = Snack("Hotdog", {"Mustard", "Ketchup"}) ౴͑ɿ3 ˆ 4 + 5 ˆ 2 = 22 ௨Γɻ 22 / 46
  17. ୈ I ෦ ܕΞϊςʔγϣϯ 5 ষ ίϨΫγϣϯܕ › ಉछίϨΫγϣϯͱҟछίϨΫγϣϯͷ֓೦Λཧղ͠Α͏ ಉछίϨΫγϣϯ

    ֨ೲ͞Εͨ͢΂ͯͷ஋͕ಉ͡σʔλܕͰ͋ΔίϨΫγϣϯ ҟछίϨΫγϣϯ ҟͳΔσʔλܕΛؚΉίϨΫγϣϯ 23 / 46
  18. ୈ I ෦ ܕΞϊςʔγϣϯ యܕతͳྫɿJSON Λࣙॻʹม׵͢Δ › dict[str, Union[str, int,

    float, None]] ͷΑ͏ͳܕ͸ॻ͖ͨ͘ͳ͍ʂ › dict[str, Any] Ͱ͸ܕώϯτ͕ܗͳͩ͠ʂ ͦΜͳ࣌͸ TypedDict ܕώϯτΛ಺ଂͨࣙ͠ॻ ͦΜͳ࣌͸ dataclass ࣗ෼Ͱ JSON ͷܗࣜΛ੍ޚͰ͖ΔͳΒ dataclass ͕Α͍ɻ 24 / 46
  19. ୈ I ෦ ܕΞϊςʔγϣϯ 6 ষ ܕνΣοΧͷΧελϚΠζ › mypy Ͱ͸

    Optional ΍ None ʹؔ͢ΔνΣοΫΛ༗ޮʹ͢Δͱྑ͍Α › mypy ͕஗͍ʁ ͳΒ͹σʔϞϯϞʔυ΍ϦϞʔτΩϟογϡͰߴ଎Խ͠Α͏ ܕνΣοΧ͸ mypy ͚ͩ͡Όͳ͍ Pyre Facebook ੡ɺ੩తղੳπʔϧ Pysa ΋͍ͭͯ͘Δ Pyright Microsoft ੡ɺVSCode ֦ுͷ Pylance ͷϕʔε 25 / 46
  20. ୈ I ෦ ܕΞϊςʔγϣϯ 7 ষ ࣮ફతͳܕνΣοΫͷಋೖ ϖΠϯϙΠϯτΛಛఆͯ͠ίετΛ͔͚ա͗ͣʹܕώϯτΛ͍ΕΑ͏ ·ͣ͸͔͜͜Β ›

    ৽نίʔυͷΈܕώϯτ › ϘτϜΞοϓʢϢʔςΟϦςΟɺϥΠϒϥϦʣʹܕώϯτ › རӹΛੜΈग़͢ϏδωεϩδοΫʹܕώϯτ › Α͘ॻ͖׵͑Δ৔ॴʹܕώϯτ › ෳࡶͳ෦෼ʹܕώϯτ › MonkeyType ΍ Pytype Ͱࣗಈతʹ෇༩΋༗ޮ͔΋ 26 / 46
  21. ୈ II ෦ Ϣʔβఆٛܕ 8 ষ ྻڍܕ ੩తͳ஋ͷίϨΫγϣϯ͔Β஋Λ 1 ͚ͭͩදݱ͍ͨ͠৔߹ʹ࢖͏

    ྻڍܕͷΞϯνύλʔϯ › ಈతʹ஋͕มԽ͢ΔྻڍܕɻࣙॻΛ࢖͓͏ɻ › IntEnum ΍ IntFlag ͸ޙํޓ׵ੑͷͨΊʹ࢖͏ɻ৽نʹ࢖͏ͷ͸όάͷݩɻ 27 / 46
  22. ୈ II ෦ Ϣʔβఆٛܕ 9 ষ σʔλΫϥε Python ͷੈքΛେ͖͘ม͑ͨσʔλΫϥεʢݪஶऀҰԡ͠ʣ σʔλΫϥεͷ࢖͍Ͳ͜Ζ

    › ҟछίϨΫγϣϯ͸σʔλΫϥεɺࣙॻ͸ಉछίϨΫγϣϯ › TypedDict ͱσʔλΫϥε͸ɺ·ͣ͸σʔλΫϥεΛݕ౼͠Α͏ › namedtuple ͸ޙํޓ׵ੑͷͨΊʹ࢖͏ σʔλΫϥε͸ສೳͳͷ͔ʁ › σʔλΫϥε͸ଐੑಉ͕࢜ಠཱ͍ͯ͠Δ৔߹ͷΈ༗ޮ 28 / 46
  23. ୈ II ෦ Ϣʔβఆٛܕ 11 ষ ΠϯλϑΣʔε › ࢖͍΍͍͢ΠϯλϑΣʔεͱ͸ ›

    ͜ͷষ͸΍΍؍೦తͰ͋Δ ࢖͍΍͍͢ΠϯλϑΣʔεΛ௥ٴ͢Δ › ར༻ऀͷΑ͏ʹߟ͑ΔʢTDDɺREADME ۦಈ։ൃɺϢʔβϏϦςΟςετʣ › ಛघϝιουɺίϯςΩετϚωʔδϟͷ׆༻ 30 / 46
  24. ୈ II ෦ Ϣʔβఆٛܕ 12 ষ ෦෼ܕ › ܧঝ͸ஔ׵ՄೳੑʢLiskov ͷஔ׵ݪଇʣʹ஫ҙ͢Δ

    › ܧঝΑΓ΋ίϯϙδγϣϯʢ߹੒ʣ ਖ਼ํܗ͸௕ํܗ͔ʁ › ਺ֶతʹ͸ɺਖ਼ํܗ͸௕ํܗͰ͋Δɻ › ਖ਼ํܗΛ௕ํܗͷܧঝͱͯ͠ද͢ͱഁ୼͢Δɻ ໰ɿਖ਼ํܗͱ௕ํܗͷఆٛΛड़΂Αɻ·ͨɺ໋୊ʮਖ਼ํܗ͸௕ํܗͰ͋ΔʯΛਖ਼ํܗͱ ௕ํܗͷఆٛʹج͍ͮͯূ໌ͤΑɻ 31 / 46
  25. ୈ II ෦ Ϣʔβఆٛܕ 13 ষ ϓϩτίϧ › ੩తܕνΣοΧͷ݀ΛຒΊΔଘࡏ ›

    μοΫλΠϐϯάͱ੩తܕνΣοΧΛͭͳ͙ϓϩτίϧ › ߏ଄త෦෼ܕͱ໊໨త෦෼ܕΛͭͳ͙ϓϩτίϧ 32 / 46
  26. ୈ II ෦ Ϣʔβఆٛܕ ߏ଄త෦෼ܕɿσʔλܕͷߏ଄Λجૅͱ͢Δ෦෼ܕ class ShuffleIterator: def __iter__(self): ...

    def __next__(self): ... ໊໨త෦෼ܕɿσʔλܕͷ໊લΛجૅͱ͢Δ෦෼ܕ class ShuffleIterator(Iterator): ... 33 / 46
  27. ୈ II ෦ Ϣʔβఆٛܕ 14 ষ pydantic ʹΑΔ࣮ߦ࣌ܕνΣοΫ › ੩తܕνΣοΧͷ݀ΛຒΊΔଘࡏ

    › ࣗવʹೖྗ஋ͳͲΛνΣοΫͰ͖Δ pydantic ͸ύʔεϥΠϒϥϦͰ΋͋Δ › int ͳΒ͹ “123” ΋ 5.5 ΋ int ʹม׵͢Δ › StrictInt ͳͲΛ࢖͏ඞཁ΋͋Δ͔΋ 34 / 46
  28. ୈ III ෦ େن໛ͳมߋ΁ͷରԠ 15 ষ ֦ுੑ › ֦ுੑͱ͸ɺγεςϜͷطଘ෦෼Λมߋͤͣʹ৽ػೳΛ௥ՃͰ͖Δͱ͍͏γες Ϝͷੑ࣭

    › ։์ด࠯ͷݪଇ͕ϕʔεʢͲͪΒ͕ઌͩΖ͏͔ʁʣ ݪଇҧ൓ͷݟ͚ͭํ › ؆୯ͳ͜ͱ͕೉͘͠ͳ͍ͬͯͳ͍͔ › ྨࣅͷػೳͷ࣮૷͕஗Ε͍ͯͳ͍͔ › ݟੵ΋Γ͕͍ͭ΋େن໛ʹͳ͍ͬͯͳ͍͔ › ίϛοτʹେن໛ͳࠩ෼ؚ͕·Ε͍ͯͳ͍͔ 35 / 46
  29. ୈ III ෦ େن໛ͳมߋ΁ͷରԠ 16 ষ ґଘؔ܎ ґଘؔ܎͸ 3 छྨ͋Δ

    › ෺ཧతґଘؔ܎ › ࿦ཧతґଘؔ܎ › ࣌ؒతґଘؔ܎ ґଘؔ܎ΛՄࢹԽͤΑ › αʔυύʔςΟϥΠϒϥϦಉ࢜ͷґଘؔ܎ › ΠϯϙʔτϞδϡʔϧؒͷґଘؔ܎ › ؔ਺ͷݺͼग़͠ͷՄࢹԽ 36 / 46
  30. ୈ III ෦ େن໛ͳมߋ΁ͷରԠ ྫɿ ϙϦγʔͱϝΧχζϜͷ෼཭ def repeat(times: int =

    1) -> collections.abc.Callable def _repeat(func: collections.abc.Callable): @functools.wrap(func) def _wrapper(*args, **kwargs): for _ in range(times): func(*args, **kwargs) return _wrapper return _repeat ϝΧχζϜʢؔ਺Λ܁Γฦ͠ݺͼग़͢ʣͱϙϦγʔʢؔ਺ͷத਎ʣΛσίϨʔλͰ෼཭ ͢Δɻ 38 / 46
  31. ୈ III ෦ େن໛ͳมߋ΁ͷରԠ 18 ষͱ 19 ষ 15 ষʮ֦ுੑʯ

    ɺ16 ষʮґଘؔ܎ʯ ɺ17 ষʮίϯϙʔβϏϦςΟʯͷ۩ମྫͱͯ͠ಡ ΋͏ɻ ۩ମతͳઃܭ࿦ʹ͍ͭͯ͸ΦϥΠϦʔ͔Β͍͍ຊ͕ͰΔΒ͍͠...ʁ 39 / 46
  32. ୈ IV ෦ ηʔϑςΟωοτͷߏங 20 ষ ੩తղੳ ੩తղੳ ຊॻͰ͸ Pylint

    ͕঺հ͞Ε͍ͯΔ͕ɺݸਓతʹ͸ flake8 ͕Α͍ͱࢥͬ ͍ͯΔɻ ෳࡶ౓νΣοΧ MeCabe ͷ॥؀తෳࡶ౓ɺۭന਺ώϡʔϦεςΟΫε ηΩϡϦςΟ Bandit ੩తղੳ͚ͩʹߜͬͯ͸͍͚ͳ͍ ෳ਺ͷղੳπʔϧΛಋೖͯ͠๷ӴઢΛෳ਺ߏங͠Α͏ 40 / 46
  33. ୈ IV ෦ ηʔϑςΟωοτͷߏங 21 ষ ςετઓུ ҎԼͷ 2 ࡭ΛಡΜͰ͍Δਓʹ͸΋ͷͨΓͳ͍͔΋͠Εͳ͍ɻ

    › ςετۦಈ Pythonʢᠳӭࣾʣ › ୯ମςετͷߟ͑ํʗ࢖͍ํʢϚΠφϏग़൛ʣ pytest Λ࢖͏ͱࣗવʹ࣮ફͰ͖Δ͔΋͠Εͳ͍ 41 / 46
  34. ୈ IV ෦ ηʔϑςΟωοτͷߏங 22 ষ ड͚ೖΕςετ Gherkin ݴޠΛ঺հ͍ͯ͠Δ͕ɺݸਓతʹ͸Ͳ͏ͩΖ͏ɺͱ͍͏ɻ ͋ΔϓϩάϥϚͷࢥ͍ग़

    աڈɺ࢓ࣄΛ࢝Ίͨ͹͔Γͷࠒɺ·ͱ΋ʹϓϩάϥϛϯά͕Ͱ͖ͳ͍ঢ়ଶͰ BDD ΍ Cucumber ΛؚΉ Ruby on Rails ͷνϡʔτϦΞϧΛಡΜͰɺBDD ΍ Cucumber ͕ۤखʹͳͬͨɻͦΕΛະͩʹҾ͖͍ͣͬͯΔͷ͔΋͠Εͳ͍ɻ 42 / 46
  35. ୈ IV ෦ ηʔϑςΟωοτͷߏங 23 ষ ϓϩύςΟϕʔεςετ Hypothesis ʹΑΔϓϩύςΟϕʔεςετͷ঺հ ϓϩύςΟϕʔεςετͱ͸

    ݻఆͨ͠ೖग़ྗʹجͮ͘ςετͰ͸ͳ͘ɺೖग़ྗ͕ຬͨ͢΂͖ੑ࣭Λهड़͢Δςετɻ ͦͷੑ࣭Λຬͨ͢஋Λπʔϧ͕ࣗಈੜ੒ͯ͠ςετέʔεΛੜ੒͢Δɻ 43 / 46
  36. ୈ IV ෦ ηʔϑςΟωοτͷߏங 24 ষ ϛϡʔςʔγϣϯςετ mutmut ʹΑΔϛϡʔςʔγϣϯςετͷ঺հ ϛϡʔςʔγϣϯςετͱ͸

    ςετࣗମΛςετ͢ΔςετɻιʔείʔυΛπʔϧͰॻ͖׵͑ͯطଘͷςετΛ ૸Βͤͯɺςετ͕੒ޭͯ͠͠·ͬͨ΋ͷΛᖰΓͩ͢ɻ 44 / 46
  37. ·ͱΊ ͬͦ͘͞ߪೖ͠Α͏ › https://www.oreilly.co.jp/books/9784814400171/ › https://www.ohmsha.co.jp/book/9784814400171/ ΦϥΠϦʔֶशϓϥοτϑΥʔϜͱ͸ › https://www.oreilly.co.jp/online-learning/ ›

    6 ສ࡭Ҏ্ͷॻ੶ʢ೔ຊޠॻ੶΋͋Δʂʣ › 3 ສ࣌ؒҎ্ͷಈը › ۀքΤΩεύʔτʹΑΔϥΠϒΠϕϯτ › ΠϯλϥΫςΟϒͳγφϦΦͱαϯυϘοΫεΛ࢖࣮ͬͨફతͳֶश › ެࣜೝఆࢼݧରࡦࢿྉ › ʰϩόετ Pythonʱ΋ΦϥΠϦʔֶशϓϥοτϑΥʔϜͰಡΈ์୊ʢ༧ఆʣ 46 / 46