Slide 1

Slide 1 text

1ZUIPOʹΑΔ ܖ໿ϓϩάϥϛϯάೖ໳ ௕୩৔५໵ )"4&#"+VOZB BLB!QBJST 1Z$PO+1%BZ 4FQUFNCFS 

Slide 2

Slide 2 text

ࣗݾ঺հ speaker = Person( name = "長谷場 潤也 (HASEBA Junya)", url = "https://lit.link/7pairs", company = "株式会社アイモバイル", job = "Androidエンジニア", languages = {"Python", "Clojure"}, favorites = {"U-NEXT Pirates", "埼玉西武ライオンズ"} )

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

ηογϣϯͷΰʔϧ ‣ ܖ໿ϓϩάϥϛϯάͷجૅΛ਎ʹ͚ͭΔ ‣ 1ZUIPOʹΑΔܖ໿ϓϩάϥϛϯάͷ࣮ફํ๏Λ஌Δ ‣ ໌೔͔Βͷ1ZUIPOʹΑΔ։ൃͷࡍʹ ܖ໿ϓϩάϥϛϯάͷಋೖΛݕ౼Ͱ͖ΔΑ͏ʹͳΔ

Slide 6

Slide 6 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 7

Slide 7 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 8

Slide 8 text

ܖ໿ʹΑΔઃܭ BLBܖ໿ϓϩάϥϛϯά ‣ ܖ໿ʹΑΔઃܭʢʹܖ໿ϓϩάϥϛϯάʣ͸ #FSUSBOE.FZFSʹΑΔઃܭํ๏࿦ͷҰͭ ‣ ιϑτ΢ΣΞͷਖ਼͠͞ΛߴΊΔ͜ͱ͕໨త ʢ˞࣍ϖʔδҎ߱Ͱৄ͘͠ղઆ͠·͢ʣ ‣ .FZFSͷ࿦จ΍ஶॻͰఏҊ ‣ ʰΦϒδΣΫτࢦ޲ೖ໳ʱͳͲ

Slide 9

Slide 9 text

ਖ਼͠͞ʢʹਖ਼֬͞ʣ ‣ ਖ਼֬͞ʢDPSSFDUOFTTʣ ‣ ਖ਼֬͞ͱ͸࢓༷ʹΑͬͯఆٛ͞Ε͍ͯΔͱ͓Γʹ࢓ࣄΛ࣮ߦ͢Δ ιϑτ΢ΣΞ੡඼ͷೳྗͰ͋Δɻ ‣ ιϑτ΢ΣΞͷਖ਼͠͞ͷੑ࣭ ‣ ਖ਼͠͞͸૬ରతͳ֓೦Ͱ͋Δɻ #FSUSBOE.FZFSʰΦϒδΣΫτࢦ޲ೖ໳ୈ൛ݪଇɾίϯηϓτʱΑΓҾ༻

Slide 10

Slide 10 text

ਖ਼͠͞ʹϓϩάϥϜ͕࢓༷ʹै͍ͬͯΔ౓߹͍

Slide 11

Slide 11 text

<໰>͜ͷؔ਺͸ਖ਼͍͠ʁ import datetime def next_day(day: datetime.date) -> datetime.date: return day + datetime.timedelta(days=1)

Slide 12

Slide 12 text

<౴>࢓༷ͱরΒ͠߹Θͤͳ͍ͱ൑அͰ͖ͳ͍ ‣ ؔ਺ͷ࢓༷͕ʮྐྵͷ্Ͱͷཌ೔Λฦ͢ʯͰ͋Ε͹ʜʜ ‣ ͜ͷؔ਺͸ਖ਼͍͠ ‣ ؔ਺ͷ࢓༷͕ʮཌӦۀ೔Λฦ͢ʯͰ͋Ε͹ʜʜ ‣ ͜ͷؔ਺͸ਖ਼͘͠ͳ͍ʢٳۀ೔͕ߟྀ͞Ε͍ͯͳ͍ͨΊʣ ‣ ਖ਼͠͞͸ϓϩάϥϜͱ࢓༷ͷ૊Έ߹ΘͤͰܾ·Δ

Slide 13

Slide 13 text

ܖ໿ϓϩάϥϛϯά ‣ 4VQQMJFSʢΫϥε΍ؔ਺ͳͲͷػೳΛఏڙ͢Δଆʣͱ $MJFOUʢػೳΛར༻͢Δଆʣͷؒͷؔ܎Λ ͓ޓ͍ͷݖརͱٛ຿Λදͨ͠ܖ໿ʹͳͧΒ͑ͨઃܭख๏ ‣ 4VQQMJFS͸ࣗ਎ͷར༻ʹؔ͢Δ৚݅Λද໌͢Δ ‣ ද໌͸ࣄલ৚݅ɾࣄޙ৚݅ɾΫϥεෆมද໌ͳͲͰߏ੒͞ΕΔ ʢ˞࣍ϖʔδҎ߱Ͱৄ͘͠ղઆ͠·͢ʣ

Slide 14

Slide 14 text

ද໌ʢ"TTFSUJPOʣ ‣ ࣄલ৚݅ʢ1SFDPOEJUJPOʣ ‣ ػೳΛݺͼग़͢લʹ$MJFOU͕कΔ΂͖ٛ຿ ‣ ࣄޙ৚݅ʢ1PTUDPOEJUJPOʣ ‣ ػೳ͕ݺͼग़͞Εͨޙʹ4VQQMJFS͕อূ͢΂͖ٛ຿ ‣ Ϋϥεෆมද໌ʢ$MBTT*OWBSJBOUʣ ‣ ৗʹຬͨ͠ଓ͚Δ͜ͱΛ4VQQMJFS͕อূ͢΂͖ٛ຿

Slide 15

Slide 15 text

ݖརͱٛ຿ ΋ͦͪ͠Β͕QSFʢࣄલ৚݅ʣΛຬͨͨ͠ঢ়ଶͰSʢػೳʣΛݺͿͱ໿ ଋͯ͠Լ͞ΔͳΒ͹ɺ͓ฦ͠ʹɺQPTUʢࣄޙ৚݅ʣΛຬͨ͢ঢ়ଶΛ࠷ ऴతʹ࣮ݱ͢Δ͜ͱΛ͓໿ଋ͠·͢ɻ #FSUSBOE.FZFSʰΦϒδΣΫτࢦ޲ೖ໳ୈ൛ݪଇɾίϯηϓτʱΑΓҾ༻ ʢׅހ಺͸ൃදऀʹΑΔʣ

Slide 16

Slide 16 text

ॲཧͷྲྀΕͱද໌ ‣ $MJFOU͕ࣄલ৚݅Λक্ͬͨͰݺ ͼग़ͤ͹ɺ4VQQMJFS͸ࣄޙ৚݅Λ ຬͨ͢͜ͱΛอূ͢Δɻ ‣ ͣͬͱมΘΒͳ͍໿ଋͱͯ͠Ϋϥ εෆมද໌͕͋Δɻ $MJFOU 4VQQMJFS ݁Ռ ʢ໭Γ஋ʗ෭࡞༻ʣ ࣄલ৚݅Λ कͬͯݺͼग़͢ ࣄޙ৚݅Λ कͬͯ݁ՌΛฦ͢ Ϋϥεෆมද໌Λ ৗʹकΔ

Slide 17

Slide 17 text

ද໌Λίϝϯτͱͯ͠ॻ͍ͯΈ·͠ΐ͏

Slide 18

Slide 18 text

ࣄલ৚݅ʢ1SFDPOEJUJPOʣ ‣ ϝιου΍ؔ਺Λݺͼग़͢લʹຬͨ͢΂͖৚݅ ‣ Ҿ਺ͷੑ࣭ʢܕɾ஋ҬͳͲʣ ‣ ݺͼग़࣌͠ͷ4VQQMJFSͷঢ়ଶ ‣ $MJFOU͕कΔ΂͖ٛ຿ ‣ ϝιου΍ؔ਺͝ͱʹ4VQQMJFS͕ද໌

Slide 19

Slide 19 text

ࣄલ৚݅ͷྫᶃ Ҿ਺ͷੑ࣭ class BankAccount: def __init__(self, balance=0): self.balance = balance self.status = "active" def deposit(self, amount): # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 self.balance += amount return self.balance def withdraw(self, amount): # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 self.balance -= amount return self.balance ૝ఆ֎ͷ஋͕ೖΓࠐΉͷΛ ๷͙ͨΊɺೖΓޱͰߜΔɻ

Slide 20

Slide 20 text

ࣄલ৚݅ͷྫᶄ 4VQQMJFSͷঢ়ଶ def deposit(self, amount): # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 # PRE[状態]: status == "active" self.balance += amount return self.balance def withdraw(self, amount): # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 # PRE[状態]: status == "active" # PRE[関係]: amount <= balance self.balance -= amount return self.balance ॲཧ͕ՄೳͳλΠϛϯάͰ ͔͠ݺͼग़͠Λڐ͞ͳ͍ɻ

Slide 21

Slide 21 text

#BOL"DDPVOUΫϥεͷ࣮૷ͷΰʔϧ # 残高10万円の口座を作成 account = BankAccount(100_000) # セッションが終わるころの実装では # 表明に違反した呼び出しはエラーになります! account.deposit(-10_000) # ❌ マイナス金額の預け入れ account.withdraw(3.14) # ❌ 小数金額の引き出し account.withdraw(200_000) # ❌ 残高を超える引き出し

Slide 22

Slide 22 text

ࣄޙ৚݅ʢ1PTUDPOEJUJPOʣ ‣ ϝιου΍ؔ਺Λݺͼग़ͨ͠ޙʹຬͨ͢΂͖৚݅ ‣ ໭Γ஋ͷੑ࣭ʢܕɾ஋ҬͳͲʣ ‣ ݺͼग़͠ޙͷ4VQQMJFSͷঢ়ଶ ‣ ݺͼग़͠લޙͷ4VQQMJFSͷࠩ෼ ‣ 4VQQMJFS͕कΔ΂͖ٛ຿ ‣ ϝιου΍ؔ਺͝ͱʹ4VQQMJFS͕ද໌

Slide 23

Slide 23 text

ࣄޙ৚݅ͷྫᶃ ໭Γ஋ͷੑ࣭ def available(self): # POST[型]: 戻り値は整数 # POST[範囲]: 戻り値 >= 0 return self.balance ฦ͞Εͨ஋Λݺͼग़͠ଆ͕ ҆৺ͯ͠࢖͑Δɻ

Slide 24

Slide 24 text

ࣄޙ৚݅ͷྫᶄ 4VQQMJFSͷঢ়ଶ def freeze(self): # PRE[状態]: status == "active" # POST[状態]: status == "frozen" self.status = "frozen" def unfreeze(self): # PRE[状態]: status == "frozen" # POST[状態]: status == "active" self.status = "active" ݺͼग़͠ޙͷঢ়ଶ͕อূ͞ Ε͍ͯΕ͹ɺγεςϜશମ ͷঢ়ଶભҠΛ҆৺ͯ͠ߟ͑ ΒΕΔɻ

Slide 25

Slide 25 text

ࣄޙ৚݅ͷྫᶅ 4VQQMJFSͷࠩ෼ def deposit(self, amount): # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 # PRE[状態]: status == "active" # POST[型]: 戻り値は整数 # POST[範囲]: 戻り値 >= 0 # POST[差分]: balanceは実行前後でamountだけ増加 self.balance += amount return self.balance ࠩ෼Λอূ͢Δ͜ͱͰɺϏ δωεϩδοΫͷҰ؏ੑΛ ่͞ͳ͍ɻ

Slide 26

Slide 26 text

ࠩ෼ͷࣄޙ৚݅ͬͯ৑௕͡Όͳ͍ʁ <໰>ࣄޙ৚݅ʹ͸ϓϩμΫτίʔυͱಉ͡Α͏ͳ಺༰Λॻ͘ͷʁ <౴>͸͍ɺॻ͘͜ͱ΋͋Γ·͢ɻ #FSUSBOE.FZFSʰΦϒδΣΫτࢦ޲ೖ໳ୈ൛ʱͰ͸ ϓϩμΫτίʔυʹಛఆͷ΍ΓํͰঢ়ଶΛม͑ΔΑ͏ʹʢதུʣ༩͑Δ໋ྩ ࣄޙ৚݅ʹظ଴͞ΕΔऴྃঢ়ଶͷಛੑΛʢதུʣ͍ࣔͯ͠Δ͚ͩ ͱɺͦΕͧΕͷҧ͍ʹ͍ͭͯड़΂͍ͯ·͢ɻ ‣ ϓϩμΫτίʔυ͸࢓༷Λ࣮ݱ͢Δॲཧ ‣ ࣄޙ৚݅͸࢓༷͕कΒΕ͍ͯΔ͜ͱΛݕࠪ͢Δ࢓૊Έ

Slide 27

Slide 27 text

Ϋϥεෆมද໌ʢ$MBTT*OWBSJBOUʣ ‣ ࣍ͷλΠϛϯάͰৗʹຬͨ͢΂͖৚݅ ‣ @@JOJU@@ͷऴྃ࣌ ‣ ͢΂ͯͷQVCMJDϝιουͷ։࢝࣌ͱऴྃ࣌ ‣ ϝιουͷॲཧதʹҰ࣌తʹຬͨ͞Εͳ͍ঢ়ଶ͕͋ͬͯ΋ྑ͍ ‣ 4VQQMJFS͕कΔ΂͖ٛ຿ ‣ Ϋϥε͝ͱʹ4VQQMJFS͕ද໌

Slide 28

Slide 28 text

Ϋϥεෆมද໌ͷྫ class BankAccount: # INV[状態]: balance >= 0 # INV[状態]: status in {"active", "frozen"} def __init__(self, balance=0): self.balance = balance self.status = "active" ͲͷQVCMJDϝιουΛݺΜ Ͱ΋ঢ়ଶ͕յΕͳ͍͜ͱΛ อূ͠ɺݺͼग़͠ଆͷ҆৺ ײΛϧʔϧͰ࡞Γग़͢ɻ

Slide 29

Slide 29 text

Ϋϥεෆมද໌͕ ຬͨ͞ΕΔλΠϛϯά ‣ @@JOJU@@ऴྃ࣌ͱQVCMJDϝιουͷ࣮ ߦલޙͰ͸ɺඞͣΫϥεෆมද໌͕ ຬͨ͞Ε͍ͯΔɻ ‣ ϝιουͷॲཧத΍ɺݺͼग़͠ઌͷ QSJWBUFϝιουͷதͰ͸ɺҰ࣌తʹ ຬͨ͞Εͳ͍ঢ়ଶ͕͋ͬͯ΋ྑ͍ɻ ‣ ͨͩ͠ɺQVCMJDϝιου͕ऴྃ͢Δ લʹঢ়ଶΛճ෮ͤ͞Δɻ @@JOJU@@։࢝ @@JOJU@@ऴྃ QVCMJDϝιου"։࢝ QVCMJDϝιου"ऴྃ QSJWBUFϝιου#։࢝ QSJWBUFϝιου#ऴྃ ຬͨ͞Ε͍ͯΔ ຬͨ͞Ε͍ͯΔ

Slide 30

Slide 30 text

Ϋϥεෆมද໌͕ຬͨ͞Εͳͯ͘΋໰୊ͷͳ͍λΠϛϯά # INV[状態]: status in {"active", "frozen"} def freeze(self): self.status = "freezing" # メソッドの実行中なので不変表明に違反しても問題なし ... # 口座凍結のための重い処理... self.status = "frozen" # メソッドの終了時に不変表明を満たす状態に回復させる

Slide 31

Slide 31 text

ػೳ͢Δද໌ʹॻ͖׵͑·͠ΐ͏

Slide 32

Slide 32 text

ػೳ͢Δද໌ʹॻ͖׵͑Δ ‣ ͜͜·Ͱͷίʔυ಺ͷද໌͸୯ͳΔίϝϯτͰ͔͋͠Γ·ͤΜɻ ‣ ද໌ʹҧ൓͢ΔίʔυΛॻ͍ͯ΋εϧʔ͞Εͯ͠·͍·͢ɻ ‣ ͜Ε͔Β࣮ࡍʹػೳ͢Δද໌ʹॻ͖׵͍͖͑ͯ·͠ΐ͏ɻ

Slide 33

Slide 33 text

ܖ໿ϓϩάϥϛϯάΛαϙʔτ͢Δݴޠ ‣ &J ff FM ‣ "EB ‣ %ݴޠ ‣ 4QFDʢ$ͷ%C$֦ு൛ʣ ‣ ,PUMJO ‣ $MPKVSF ೔ຊޠ൛8JLJQFEJBʮܖ໿ϓϩάϥϛϯάʯΑΓҾ༻

Slide 34

Slide 34 text

1ZUIPO͸ܖ໿ϓϩάϥϛϯάΛ αϙʔτ͍ͯ͠·ͤΜͰͨ͠😭

Slide 35

Slide 35 text

1ZUIPOʹΑΔܖ໿ϓϩάϥϛϯά ‣ ݴޠʹΑΔ௚઀ͷαϙʔτ͸͞Ε͍ͯͳ͍ ‣ ίʔυͷॻ͖ํʹϧʔϧΛಋೖ͢Δ͜ͱͰ 1ZUIPOʹΑΔܖ໿ϓϩάϥϛϯάͷ࣮ફ͸Մೳ ‣ طଘͷݴޠ࢓༷Λ׆༻͢ΔʢܕώϯτɺBTTFSUͳͲʣ ‣ ઐ໳ͷϥΠϒϥϦΛಋೖ͢Δʢ1ZEBOUJDɺJDPOUSBDUͳͲʣ

Slide 36

Slide 36 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 37

Slide 37 text

෬ઢճऩᶃ speaker = Person( name = "長谷場 潤也 (HASEBA Junya)", url = "https://lit.link/7pairs", company = "株式会社アイモバイル", job = "Androidエンジニア", languages = {"Python", "Clojure"}, favorites = {"U-NEXT Pirates", "埼玉西武ライオンズ"} )

Slide 38

Slide 38 text

෬ઢճऩᶄ ‣ &J ff FM ‣ "EB ‣ %ݴޠ ‣ 4QFDʢ$ͷ%C$֦ு൛ʣ ‣ ,PUMJO ‣ $MPKVSF ೔ຊޠ൛8JLJQFEJBʮܖ໿ϓϩάϥϛϯάʯΑΓҾ༻

Slide 39

Slide 39 text

$MPKVSFͷྫᶃ ࢓༷ͱܖ໿ ; 単価 * 数量を整数に丸めて返す ; ※ 実はバグがあります (defn total [price qty] {:pre [(number? price) (>= price 0) (integer? qty) (> qty 0)] :post [(integer? %) (>= % 0)]} (* price qty)) ‣ 13&<ܕ>QSJDF͸਺஋ ‣ 13&<ൣғ>QSJDF ‣ 13&<ܕ>RUZ͸੔਺ ‣ 13&<ൣғ>RUZ ‣ 1045<ܕ>໭Γ஋͸੔਺ ‣ 1045<ൣғ>໭Γ஋

Slide 40

Slide 40 text

$MPKVSFͷྫᶄܖ໿͕όάΛݕ஌͢Δ ; 事前条件を満たさない引数はエラーになる (total "33" 4) ; => Assert failed: (number? price) (total 33 -4) ; => Assert failed: (> qty 0) ; 事後条件を満たさない戻り値はエラーになる (total 3.3 4) ; => Assert failed: (integer? %) ; 期待結果は13.2を四捨五入して13 ; 実際には整数が返っていない!バグ?

Slide 41

Slide 41 text

$MPKVSFͷྫᶅ ਖ਼͍࣮͠૷ ; 単価 * 数量を整数に丸めて返す ; Math/round(四捨五入)を追加 (defn total [price qty] {:pre [(number? price) (>= price 0) (integer? qty) (> qty 0)] :post [(integer? %) (>= % 0)]} (Math/round (* price qty))) ࣄޙ৚͕݅͋ͬͨͷͰɺ࣮ ૷࿙Ε͕͙͢ʹൃ֮ͨ͠ɻ

Slide 42

Slide 42 text

,PUMJOͷྫᶃίϯύΠϥͱͷܖ໿ // ※ KotlinのGitHubリポジトリより引用 // String::isNullOrEmptyがfalseを返すとき、そのStringはnullではないことを表明 // [注] 実行時のチェックではなく、コンパイラの最適化や解析のヒントとして使われる public inline fun CharSequence?.isNullOrEmpty(): Boolean { contract { returns(false) implies (this@isNullOrEmpty != null) } return this == null || this.length == 0 }

Slide 43

Slide 43 text

,PUMJOͷྫᶄ εϚʔτΩϟετ var nullableString: String? = "I am nullable." var nonNullString: String = "I am not null." // null許容型の値はnull非許容型に代入できない nonNullString = nullableString // ビルドエラー if (nullableString != null) { // このブロック内ではnullではないことを // コンパイラが推論可能なので代入できる nonNullString = nullableString } if (!nullableString.isNullOrEmpty()) { // 通常のメソッド呼び出しでは推論できないが // contractがあるためnullではないと推論可能 nonNullString = nullableString } ,PUMJOͰͷܖ໿͸4VQQMJFS ͱ$MJFOUͷؒͷ໿ଋͰ͸ͳ ͘ɺίϯύΠϥʹର͢Δอ ূ͕໨తʢεϚʔτΩϟε τ΍෭࡞༻ղੳʹ࢖༻ʣɻ

Slide 44

Slide 44 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 45

Slide 45 text

1ZUIPOʹΑΔܖ໿ͷஈ֊త࣮૷ ‣ -FWFMܕώϯτ ‣ -FWFMBTTFSU EPDTUSJOH ‣ -FWFM1ZEBOUJD ‣ -FWFMJDPOUSBDU

Slide 46

Slide 46 text

1ZUIPOʹΑΔܖ໿ͷஈ֊త࣮૷ ‣ -FWFMܕώϯτ ‣ -FWFMBTTFSU EPDTUSJOH ‣ -FWFM1ZEBOUJD ‣ -FWFMJDPOUSBDU

Slide 47

Slide 47 text

-FWFMܕώϯτ࣮૷ํ਑ ‣ ࣄલ৚݅ͰҾ਺ͷܕΛද໌͢Δ৔߹ ‣ ౰֘ͷҾ਺ʹܕώϯτΛࢦఆ͢Δ ‣ ࣄޙ৚݅Ͱ໭Γ஋ͷܕΛද໌͢Δ৔߹ ‣ ໭Γ஋ʹܕώϯτΛࢦఆ͢Δ ‣ ࣄલ৚݅΍ࣄޙ৚݅ͰܕΛද໌͍ͯ͠ͳ͍৔߹ ‣ ݱ୅తͳ1ZUIPO։ൃͷ͓࡞๏ͱͯ͠ܕώϯτΛࢦఆ͢Δ

Slide 48

Slide 48 text

ܖ໿ϓϩάϥϛϯά͸໌೔͔ΒͰྑ͍Ͱ͕͢ ܕώϯτ͸ࠓ͜ͷॠ͔ؒΒॻ͍͍ͯͩ͘͞ʂ

Slide 49

Slide 49 text

-FWFM ܕώϯτ࣮૷ def deposit(self, amount: int) -> int: # PRE[型]: amountは整数 # PRE[範囲]: amount > 0 # PRE[状態]: status == "active" # POST[型]: 戻り値は整数 # POST[範囲]: 戻り値 >= 0 # POST[差分]: balanceは実行前後でamountだけ増加 self.balance += amount return self.balance def freeze(self) -> None: # PRE[状態]: status == "active" # POST[状態]: status == "frozen" self.status = "frozen" Ҿ਺ͱ໭Γ஋ʹܕώϯτΛ ࢦఆ͢Δɻ ˞࿩Λ୯७ʹ͢ΔͨΊɺۚ ֹͷܕΛJOUʹ͍ͯ͠·͢ɻ

Slide 50

Slide 50 text

-FWFMܕώϯτܖ໿ͷޮՌᶃ account = BankAccount(100_000) # mypyで引数の型のミスを静的に検出できる # => error: Argument 1 to "deposit" of "BankAccount" has # incompatible type "str"; expected "int" [arg-type] account.deposit("10_000")

Slide 51

Slide 51 text

-FWFMܕώϯτܖ໿ͷޮՌᶄ # mypyでreturnの書き忘れを静的に検出できる # => error: Missing return statement [return] def deposit(self, amount: int) -> int: self.balance += amount # 値を返していない

Slide 52

Slide 52 text

-FWFMܕώϯτ·ͱΊ ‣ Ҿ਺ɾ໭Γ஋ͷޡͬͨܕΛ੩తʹݕग़Ͱ͖Δ ‣ -FWFMҎ߱ͷݕग़͸࣮ߦ࣌ˠܕώϯτ͕Ұ൪ૣ͍ʂ ‣ ٯʹ࣮ߦ࣌ʹ͸Կͷݕূ΋ߦΘͳ͍ͨΊ NZQZͳͲͷܕνΣοΫπʔϧΛ࢖͍ͬͯͳ͍ͱҙຯ͕ͳ͍ ‣ ܕώϯτ͸खܰͰڧྗͳ࠷଎࠷ڧͷܖ໿ ‣ ࠓ͙͢QJQJOTUBMMNZQZVWBEENZQZFUDʜ

Slide 53

Slide 53 text

1ZUIPOʹΑΔܖ໿ͷஈ֊త࣮૷ ‣ -FWFMܕώϯτ ‣ -FWFMBTTFSU EPDTUSJOH ‣ -FWFM1ZEBOUJD ‣ -FWFMJDPOUSBDU

Slide 54

Slide 54 text

-FWFMBTTFSU EPDTUSJOH࣮૷ํ਑ ‣ ࣄલ৚݅ͰҾ਺ͷੑ࣭Λද໌͢Δ৔߹ ‣ ϝιουͷઌ಄ʹBTTFSUʹΑΔݕূΛ௥Ճ͢Δ ‣ ද໌ͷ಺༰ΛEPDTUSJOHʹهࡌ͢Δ ‣ ࣄޙ৚݅Ͱ໭Γ஋ͷੑ࣭Λද໌͢Δ৔߹ ‣ ໭Γ஋ΛSFUVSO͢Δ௚લʹBTTFSUʹΑΔݕূΛ௥Ճ͢Δ ‣ ද໌ͷ಺༰ΛEPDTUSJOHʹهࡌ͢Δ

Slide 55

Slide 55 text

-FWFMBTTFSU EPDTUSJOH࣮૷ྫᶃ def withdraw(self, amount: int) -> int: # ---------- Precondition ---------- assert amount > 0, "PRE violation: amount must be > 0" assert self.status == "active", "PRE violation: status must be 'active'" assert amount <= self.balance, "PRE violation: amount must not exceed balance" # ---------- Product Code ---------- self.balance -= amount # ---------- Postcondition ---------- result = self.balance assert result >= 0, "POST violation: result must be >= 0" return result

Slide 56

Slide 56 text

-FWFM BTTFSU EPDTUSJOH ࣮૷ྫᶄ def withdraw(self, amount: int) -> int: """ 事前条件: - amountは整数 - amount > 0 - status == "active" - amount <= balance 事後条件: - 戻り値は整数 - 戻り値 >= 0 - balanceは実行前後でamountだけ減少 """ ... EPDTUSJOHʹද໌ͷ಺༰Λه ࡌ͢Δɻ ܕʹ͍ͭͯ͸ܕώϯτͰରԠ ࡁΈɻCBMBODFͷݮগ෼ʹͭ ͍ͯ͸-FWFMͰରԠ͢Δɻ

Slide 57

Slide 57 text

-FWFMBTTFSU EPDTUSJOHܖ໿ͷޮՌ account = BankAccount(100_000) # 引数の範囲のミスを実行時に検出できる # => AssertionError: PRE violation: amount must not exceed balance account.withdraw(200_000) # Supplierの状態のミスを実行時に検出できる # => AssertionError: PRE violation: status must be 'active' account.freeze() account.withdraw(50_000)

Slide 58

Slide 58 text

๷ޚతϓϩάϥϛϯάͱͷҧ͍ ‣ ๷ޚతϓϩάϥϛϯά ‣ ݺͼग़͠ݩɾݺͼग़͠ઌΛ৴༻ͤͣʹଟ͘ͷ৔ॴͰ஋Λݕূ͢Δ ‣ ҆શͰ͸͋Δ͕ίʔυ͕৑௕ʹͳΓ͕ͪ ‣ ܖ໿ϓϩάϥϛϯά ‣ 4VQQMJFSͱ$MJFOUͷ੹೚ൣғΛ໌ࣔ͢Δ ‣ ҆શʹಈ࡞ͤ͞ΔͨΊͷٛ຿Λ͸͖ͬΓͱ෼୲͢Δ ‣ ίʔυ͸γϯϓϧͰ໌շʹͳΔ

Slide 59

Slide 59 text

๷ޚతϓϩάϥϛϯάͱͷ࢖͍෼͚ ‣ ܖ໿ϓϩάϥϛϯάʢ಺෦Ͱͷ໿ଋʣ ‣ ৴པͰ͖Δ૬खʢνʔϜ಺ͷίʔυɺಉҰϞδϡʔϧ಺ͷݺͼग़͠ʣͱͷؔ܎ ‣ ʮࣄલ৚݅Λकͬͯ͘ΕΔͳΒɺͪΌΜͱࣄޙ৚݅Λอূ͢ΔΑʯ ‣ ઃܭΛ໌֬ʹͯ͠όάΛૣظʹݕग़͢Δ ‣ ๷ޚతϓϩάϥϛϯάʢ֎෦ͱͷڥքʣ ‣ ৴པͰ͖ͳ͍૬खʢϢʔβʔೖྗɺ֎෦γεςϜʣͱͷؔ܎ ‣ ʮ૬ख͕ԿΛૹͬͯ͘Δ͔෼͔Βͳ͍ͷͰɺյΕͳ͍Α͏ʹࣗ෼ΛकΔʯ ‣ γεςϜͷݎ࿚ੑ΍ηΩϡϦςΟΛ֬อ͢Δ

Slide 60

Slide 60 text

-FWFMBTTFSU EPDTUSJOH·ͱΊ ‣ ϓϩάϥϜͷޡͬͨঢ়ଶΛ࣮ߦ࣌ʹݕग़Ͱ͖Δ ‣ ҧ൓ͷݕग़͸BTTFSU͚ͩͰ΋࣮ݱͰ͖Δ͕ ΄͔ͷਓ΍ະདྷͷࣗ෼ͷͨΊʹEPDTUSJOH΋ॻ͍͓ͯ͘ ‣ BTTFSU͸1ZUIPOͱͷ໿ଋɾEPDTUSJOH͸ਓؒͱͷ໿ଋ ‣ ςετ؀ڥ΍$*؀ڥͰ͸๨ΕͣʹBTTFSUΛ༗ޮԽ͓ͯ͘͠

Slide 61

Slide 61 text

1ZUIPOʹΑΔܖ໿ͷஈ֊త࣮૷ ‣ -FWFMܕώϯτ ‣ -FWFMBTTFSU EPDTUSJOH ‣ -FWFM1ZEBOUJD ‣ -FWFMJDPOUSBDU

Slide 62

Slide 62 text

-FWFMͷ࣮૷͸ΦϓγϣϯͰ͢

Slide 63

Slide 63 text

ಋೖͷ൑அج४ ‣ ͋ͳͨͷϓϩδΣΫτͰ͸1ZEBOUJDΛ࢖͍ͬͯ·͔͢ʁ ‣ :FTˠ-FWFMΛڬΉՁ஋͋Γ ‣ /Pˠ-FWFMʹ௚ߦͯ͠΋ྑ͍͔΋ ‣ ͋ͳͨͷΞϓϦͷҰ൪ͷܹઓ஍͸Ͳ͜Ͱ͔͢ʁ ‣ ֎෦ͱͷσʔλڥքˠ-FWFMΛڬΉՁ஋͋Γ ‣ ΞϓϦͷৼΔ෣͍ˠ-FWFMʹ௚ߦͯ͠΋ྑ͍͔΋

Slide 64

Slide 64 text

-FWFM1ZEBOUJD࣮૷ํ਑ ‣ ࣄલ৚݅ͰҾ਺ͷੑ࣭Λද໌͢Δ৔߹ ‣ Ҿ਺Λ1ZEBOUJDϞσϧʹ͢Δ ‣ ࣄޙ৚݅Ͱ໭Γ஋ͷੑ࣭Λද໌͢Δ৔߹ ‣ ໭Γ஋Λ1ZEBOUJDϞσϧʹ͢Δ ‣ ͦΕҎ֎ͷද໌͸BTTFSUͱͯ͠࢒͢

Slide 65

Slide 65 text

-FWFM1ZEBOUJD࣮૷ྫ class WithdrawAmount(BaseModel): value: conint(gt=0) # 0より大きい整数 def withdraw(self, amount: WithdrawAmount) -> int: """※docstringは省略""" # ---------- Precondition ---------- assert self.status == "active", "PRE violation: status must be 'active'" assert amount.value <= self.balance, "PRE violation: amount must not exceed balance" # ---------- Product Code ---------- self.balance -= amount # ---------- Postcondition ---------- result = self.balance assert result >= 0, "POST violation: result must be >= 0" return result

Slide 66

Slide 66 text

-FWFM1ZEBOUJDܖ໿ͷޮՌ account = BankAccount(100_000) # Pydanticで引数の性質のミスを実行時に検出できる # => pydantic.ValidationError: 1 validation error for WithdrawAmount value # Input should be greater than 0 [type=greater_than, input_value=-500, gt=0] amount.withdraw(WithdrawAmount(value=-500)) # 引数とSupplierの関係性のミスを実行時に検出できる(assertでカバー) # => AssertionError: PRE violation: amount must not exceed balance account.withdraw(WithdrawAmount(value=200_000))

Slide 67

Slide 67 text

Ҿ਺ͷΠϯλʔϑΣΠεΛม͑ͨ͘ͳ͚Ε͹ # メソッドの引数はintのままにする def withdraw(self, amount: int) -> int: # メソッドの内部でモデル化する param = WithdrawAmount(value=amount) ...

Slide 68

Slide 68 text

-FWFM1ZEBOUJD·ͱΊ ‣ 7BMVF0CKFDU΍%50Λ1ZEBOUJDϞσϧʹ͢Δ ‣ ϓϩδΣΫτͷੑ࣭ʹ߹Θͤͨબ୒͕ඞཁ ‣ ؔ਺΍ϝιουͷΠϯλʔϑΣΠε͕มΘΔͨΊ طଘͷϓϩάϥϜʹಋೖ͢Δࡍʹ͸ద༻ൣғΛ৻ॏʹ ‣ ಛʹ໭Γ஋ʹద༻͢Δ৔߹͸ӨڹൣғΛચ͍ग़͔ͯ͠Β

Slide 69

Slide 69 text

1ZUIPOʹΑΔܖ໿ͷஈ֊త࣮૷ ‣ -FWFMܕώϯτ ‣ -FWFMBTTFSU EPDTUSJOH ‣ -FWFM1ZEBOUJD ‣ -FWFMJDPOUSBDU

Slide 70

Slide 70 text

-FWFMJDPOUSBDU࣮૷ํ਑ ‣ ࣄલ৚݅ɾࣄޙ৚݅ɾΫϥεෆมද໌ΛJDPOUSBDUͰ࣮૷͢Δ ‣ Ϋϥε΍ϝιουʹσίϨʔλΛ෇༩͢Δ ‣ <ิ଍>JDPOUSBDUͱ͸ ‣ JDPOUSBDUQSPWJEFTEFTJHOCZDPOUSBDUUP1ZUIPOXJUI JOGPSNBUJWFWJPMBUJPONFTTBHFTBOEJOIFSJUBODF ʢJDPOUSBDUͷυΩϡϝϯτΑΓҾ༻ʣ ‣ ޙൃϥΠϒϥϦͳͷͰػೳ͕ॆ࣮͍ͯ͠Δ

Slide 71

Slide 71 text

-FWFMJDPOUSBDU࣮૷ྫᶃ import icontract # @invariantデコレータでクラス不変表明を定義 # publicメソッドの実行前後でチェックされる @icontract.invariant(lambda self: self.balance >= 0) @icontract.invariant(lambda self: self.status in {"active", "frozen"}) class BankAccount: def __init__(self, balance: int = 0) -> None: self.balance = balance self.status = "active"

Slide 72

Slide 72 text

-FWFMJDPOUSBDU࣮૷ྫᶄ # @requireデコレータで事前条件を定義 # @snapshot / @ensureデコレータで事後条件を定義 @icontract.require(lambda self, amount: self.status == "active") @icontract.require(lambda self, amount: amount > 0) @icontract.require(lambda self, amount: amount <= self.balance) @icontract.snapshot(lambda self: self.balance, name="bal") @icontract.ensure(lambda self, amount, result, OLD: result == self.balance and OLD.bal - self.balance == amount) def withdraw(self, amount: int) -> int: self.balance -= amount return self.balance

Slide 73

Slide 73 text

!TOBQTIPU0-%ͬͯʁᶃ ‣ !TOBQTIPUϝιου࣮ߦલͷ஋Λอଘ͢Δ࢓૊Έ ‣ 0-%!FOTVSFͷத͔Βࢀর͢Δ࣮ߦલͷ஋ͷίϯςφ ‣ ར༻͢ΔγνϡΤʔγϣϯ ‣ ࠩ෼ͷݕূʢྫCBMBODF͸࣮ߦલޙͰBNPVOU͚ͩݮগʣ ‣ ˢࠓճͷྫʂ ‣ ঢ়ଶભҠͷݕূʢྫTUBUVT͕BDUJWF͔ΒGSP[FOʹมԽʣ

Slide 74

Slide 74 text

!TOBQTIPU0-%ͬͯʁᶄ # 実行前のself.balanceの値をOLD.balとして保存 @icontract.snapshot(lambda self: self.balance, name="bal") # @ensureデコレータの中でOLD.balを参照 @icontract.ensure(lambda self, amount, result, OLD: result == self.balance and OLD.bal - self.balance == amount)

Slide 75

Slide 75 text

-FWFMJDPOUSBDUܖ໿ͷޮՌᶃ account = BankAccount(100_000) # icontractで引数の性質のミスを実行時に検出できる # => icontract.errors.ViolationError: ... # amount > 0: # amount was -500 account.withdraw(-500)

Slide 76

Slide 76 text

-FWFMJDPOUSBDUܖ໿ͷޮՌᶄ account = BankAccount(100_000) # icontractで引数とSupplierの関係性のミスを実行時に検出できる # => icontract.errors.ViolationError: ... # amount <= self.balance: # amount was 200000 # self.balance was 100000 account.withdraw(200_000)

Slide 77

Slide 77 text

-FWFMJDPOUSBDUܖ໿ͷޮՌᶅ # withdrawなのに残高に足してしまった!(デコレータ略) def withdraw(self, amount: int) -> int: self.balance += amount return self.balance # icontractで実行時に検出できる # => icontract.errors.ViolationError: ... # result == self.balance and OLD.bal - self.balance == amount: # OLD was a bunch of OLD values # OLD.bal was 100000 # amount was 50000 # result was 150000 # self.balance was 150000 account.withdraw(50_000)

Slide 78

Slide 78 text

-FWFMJDPOUSBDUܖ໿ͷޮՌᶆ # ステータスを壊してしまった!(デコレータ略) def withdraw(self, amount: int) -> int: self.status = "error" self.balance -= amount return self.balance # icontractで実行時に検出できる # => icontract.errors.ViolationError: ... # self.status in {"active", "frozen"}: # self.status was 'error' account.withdraw(50_000)

Slide 79

Slide 79 text

-FWFMJDPOUSBDU·ͱΊ ‣ ද໌ʹର͢Δҧ൓Λ࣮ߦ࣌ʹݕग़͢Δ ‣ ೖޱʢ!SFRVJSFʣɾग़ޱʢ!FOTVSFʣɾৗ࣌ʢ!JOWBSJBOUʣͰकΔ ‣ !TOBQTIPUͰࠩ෼΍ঢ়ଶભҠ΋ݕূͰ͖Δ ‣ ͨͩͷίϝϯτͩͬͨܖ໿͕͍ͭʹຊ෺ͷܖ໿ʹͳΓ·ͨ͠ʂ

Slide 80

Slide 80 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 81

Slide 81 text

ͦ΋ͦ΋ςετͬͯԿ͚ͩͬʁ ‣ ࣄྫϕʔεςετʢ&YBNQMF#BTFE5FTUJOHʣ ‣ ैདྷͷςετͷଟ͘͸ࣄྫϕʔεͰ͢ɻ͜͜Ͱݴ͏ࣄྫͱ͸ɺϓϩάϥϜ ΁ͷೖྗ஋ͱظ଴͞ΕΔग़ྗ஋ͱΛ૊ʹͯ͠ฒ΂ͨ΋ͷͰ͢ɻ ‣ ϓϩύςΟϕʔεςετʢ1SPQFSUZ#BTFE5FTUJOHʣ ‣ ʮͲͷΑ͏ͳೖྗ஋Λ༩͑ͯ΋ৗʹಉ͡Ͱ͋ΔΑ͏ͳৼΔ෣͍ʯΛهड़ ͢ΔϧʔϧΛݟ͚ͭͯɺͦΕΛ࣮ߦՄೳͳίʔυͱͯ͠ॻ͖ද͢ͷͰ͢ɻ 'SFE)FCFSUʰ࣮ફϓϩύςΟϕʔεςετʕ1SPQ&Sͱ&SMBOH&MJYJSͰ͸͡ΊΑ͏ʱΑΓҾ༻

Slide 82

Slide 82 text

ࣄྫϕʔεςετʢ&YBNQMF#BTFE5FTUJOHʣ ‣ ֬ೝ͢Δ಺༰Λਓ͕ܾؒΊΔςετ ‣ ୯ʹʮςετʯͱฉ͍ͨͱ͖ʹ࿈૝͢ΔΑ͏ͳ΋ͷ ‣ ڧΈγφϦΦ͕෼͔Γ΍͍͢ ‣ ऑΈ඼࣭΍໢ཏੑ͸ςετઃܭʹґଘ͢Δ

Slide 83

Slide 83 text

ࣄྫϕʔεςετͷྫ def test_deposit(): account = BankAccount(100_000) assert account.available() == 100_000 assert account.deposit(50_000) == 150_000 assert account.available() == 150_000

Slide 84

Slide 84 text

ϓϩύςΟϕʔεςετʢ1SPQFSUZ#BTFE5FTUJOHʣ ‣ ੑ࣭ʢʹϓϩύςΟʣΛఆٛͯࣗ͠ಈੜ੒ͨ͠஋Ͱߦ͏ςετ ‣ 1ZUIPOͰ͸)ZQPUIFTJTͳͲͷϥΠϒϥϦ͕༗໊ ‣ ڧΈϥϯμϜੜ੒ͷ͓͔͛Ͱҙ֎ͳόάΛൃݟͰ͖Δ ‣ ऑΈ׳ΕΔ·Ͱ͕೉͍͠

Slide 85

Slide 85 text

ϓϩύςΟʢ1SPQFSUZʣ ‣ ʮͲͷΑ͏ͳೖྗ஋Λ༩͑ͯ΋ৗʹಉ͡Ͱ͋ΔΑ͏ͳৼΔ෣͍ʯ ʢ'SFE)FCFSUʰ࣮ફϓϩύςΟϕʔεςετʱΑΓҾ༻ʣ ‣ EFQPTJUΛݺͿͱCBMBODF͕BNPVOUͷͿΜ͚ͩ૿Ճ͢Δ ‣ XJUIESBXΛݺͿͱCBMBODF͕BNPVOUͷͿΜ͚ͩݮগ͢Δ

Slide 86

Slide 86 text

ͦΕͬͯܖ໿ͳͷͰ͸ʁ

Slide 87

Slide 87 text

ϓϩύςΟϕʔεςετͷྫ from hypothesis import given, strategies as st from bank import BankAccount # 事前条件を満たすランダムな入力に対して事後条件を満たすことを確認 @given(balance=st.integers(min_value=0, max_value=1_000_000), amount=st.integers(min_value=1, max_value=1_000_000)) def test_deposit_property(balance, amount): account = BankAccount(balance) new_balance = account.deposit(amount) assert new_balance == balance + amount assert account.available() == new_balance

Slide 88

Slide 88 text

ࣄྫϕʔεςετͱϓϩύςΟϕʔεςετͷҧ͍ ‣ ࣄྫϕʔεςετ ‣ ࢒ߴ͕ ԁͷޱ࠲ʹ ԁͷ༬͚ೖΕΛ͢Δͱ ࢒ߴ͕ ԁʹ૿͑Δͱ͍͏఺Λςετ͢Δ ‣ ޮ཰తʹ఺ΛબͿͨΊͷςΫχοΫ͕֤छͷςετٕ๏ ‣ ϓϩύςΟϕʔεςετ ‣ ࢒ߴ͕CBMBODFͷޱ࠲ʹBNPVOUͷ༬͚ೖΕΛ͢Δͱ ࢒ߴ͕CBMBODF BNPVOUʹ૿͑Δͱ͍͏ੑ࣭Λςετ͢Δ ‣ ੑ࣭ͱ͍͏໘ʹϥϯμϜʹ఺Λଧͬͯ֬ೝ͢ΔΠϝʔδ

Slide 89

Slide 89 text

ܖ໿ͱࣄྫϕʔεςετ ‣ ܖ໿͸ந৅తʹ໢ΛுΔΠϝʔδ ‣ ೖग़ྗͷ੍໿ɾෆม৚݅ ‣ ࣄྫϕʔεςετ͸۩ମతͳ஋ͰγφϦΦΛԡ͑͞ΔΠϝʔδ ‣ ڥք஋ɾҟৗܥɾϏδωεγφϦΦ ‣ ྆ྠͰΞϓϦͷ඼࣭ΛߴΊΔ

Slide 90

Slide 90 text

ܖ໿ͱϓϩύςΟϕʔεςετ ‣ ܖ໿͸ੑ࣭ΛίʔυͰ໌ࣔͨ͠΋ͷ ‣ ϓϩύςΟϕʔεςετ͸ͦͷੑ࣭ΛϥϯμϜʹݕূ͢Δ࢓૊Έ ‣ ܖ໿ͱςετ͕௚݁͢ΔͷͰ૬ੑൈ܈ʂ ‣ JDPOUSBDUͱ)ZQPUIFTJTΛ౷߹͢ΔJDPOUSBDUIZQPUIFTJT

Slide 91

Slide 91 text

ϓϩμΫτίʔυɾܖ໿ɾςετ ‣ ϓϩμΫτίʔυ ‣ ࢓༷Λ࣮ݱ͢Δॲཧ ‣ ܖ໿ ‣ ࢓༷͕कΒΕ͍ͯΔ͜ͱΛݕࠪ͢Δ࢓૊Έ ‣ ςετ ‣ ࢓༷͕कΒΕ͍ͯΔ͜ͱΛ֎͔Β֬ೝ͢Δ࢓૊Έ

Slide 92

Slide 92 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 93

Slide 93 text

νʔϜಋೖͷεςοϓ ‣ 4UFQ৽نͷίʔυʹ͚ͩಋೖ͢Δ ‣ طଘͷίʔυ͸৮Βͳͯ͘΋0, ‣ 4UFQςετͷް͍Ϟδϡʔϧ͔Βಋೖ͢Δ ‣ ҆શੑ͕୲อ͞Ε΍͍͢ ‣ 4UFQϧʔϧΛνʔϜͰڞ༗͢Δ ‣ EPDTUSJOHͷϑΥʔϚοτͳͲ ‣ 4UFQ੩తղੳͱ૊Έ߹Θͤͯίʔυن໿ͱͯ͠ఆணͤ͞Δ ‣ ͜͜·ͰདྷΕ͹ࣗಈతʹճΓ࢝ΊΔ

Slide 94

Slide 94 text

νʔϜಋೖ࣌ͷϙΠϯτ ‣ ͍͖ͳΓ͢΂ͯͷίʔυʹಋೖ͠ͳ͍ ‣ ৘೤ʹ೩͍͑ͯΔͷ͸࠷ॳ͚ͩ ‣ ϋʔυϧΛ্͛͗͢ͳ͍ ‣ খ͞ͳ୯ҐͰࢼ͢ˠ੒ޭମݧΛੵΉˠڞ༗ͯ͠޿͛Δ ‣ ࠷ॳ͔Β఺Λ໨ࢦ͢ͷͰ͸ͳ͘ νʔϜͰܖ໿ΛಡΉɾॻ͘จԽΛҭͯΔ͜ͱΛ༏ઌ͢Δ

Slide 95

Slide 95 text

ܖ໿νΣοΫͷ༗ޮʗແޮ੾Γସ͑ ‣ ։ൃ؀ڥ ‣ جຊతʹ͸͢΂ͯͷܖ໿νΣοΫΛ༗ޮʹ͢΂͖ ‣ ςετ࣮ߦ΍εςʔδϯάͰଈ࠲ʹྫ֎Λ౤͛ͯݪҼΛಛఆ͢Δ ‣ ϓϩμΫγϣϯ؀ڥ ‣ 0QUJPOܖ໿νΣοΫΛແޮԽ͢ΔʢੑೳΛॏࢹʣ ‣ 0QUJPOக໋తͳෆม৚͚݅ͩ༗ޮԽ͢Δʢ҆શੑΛॏࢹʣ ‣ 0QUJPOϩάʹग़ྗ͢Δ͚ͩͰॲཧ͸ଓߦ͢Δʢམͱͤͳ͍γεςϜʣ

Slide 96

Slide 96 text

ܖ໿νΣοΫͷϙΠϯτ ‣ ։ൃத͸جຊతʹνΣοΫΛ͢΂ͯ༗ޮԽͯ͠όάͷݕग़ʹ࢖͏ ‣ ຊ൪؀ڥͰ͸ίετ΍ӨڹൣғΛߟ͑ͯͲ͏ѻ͏͔ΛܾΊΔ ‣ ΦʔόʔϔουΛܭଌ͢Δ ‣ ઈରʹམͪͯ͸͍͚ͳ͍WTޡͬͨঢ়ଶͰಈ͘ΑΓམͪͨํ͕Ϛγ ‣ Ͳͷܖ໿Λຊ൪Ͱ΋࢒͔͢͸ϓϩδΣΫτͷੑ࣭࣍ୈ ‣ ಛఆͷܖ໿͚ͩ࢒͢ͱ͍͏બ୒ࢶ΋͋Δ

Slide 97

Slide 97 text

ܖ໿ͱςετ͸໾ׂ͕ҧ͏ ‣ ܖ໿ʢࣄલ৚݅ɾࣄޙ৚݅ɾΫϥεෆมද໌ʣ ‣ ϓϩάϥϜͷڥքΛकΔ ‣ ςετ ‣ ࣮ࡍʹίʔυΛಈ͔ͯ͠࢓༷Ͳ͓Γʹಈ͘͜ͱΛ֬ೝ͢Δ ‣ ܖ໿ͰΧόʔͰ͖ͳ͍෦෼Λݕূ͢Δ ‣ ܖ໿Ͱ͸දͤͳ͍࢓༷ ‣ ྫ֎తͳϑϩʔ ‣ ྆ྠͰ࢖͏͜ͱͰ҆৺ײΛߴΊΔ

Slide 98

Slide 98 text

ςετͷϙΠϯτ ‣ ܖ໿͕ಘҙͱ͢Δൣғ͸ܖ໿ͷྗΛआΓΔ΂͖ ‣ ܗࣜతʹදݱͰ͖Δ෦෼ ‣ Ҿ਺΍໭Γ஋ͷੑ࣭ ‣ ΦϒδΣΫτͷ੔߹ੑ ‣ ςετ͕ಘҙͱ͢Δൣғʹ஫ྗ͢Δ ‣ ࣮ߦͯ͠Έͳ͍ͱ෼͔Βͳ͍෦෼ ‣ ֎෦γεςϜͱͷ࿈ܞ ‣ ྫ֎ܥͳͲಛघͳϑϩʔ

Slide 99

Slide 99 text

໨࣍ ‣ ܖ໿ϓϩάϥϛϯάͱ͸ʁ ‣ ଞݴޠͷྫΛݟͯΈΑ͏ ‣ 1ZUIPOͰ࣮ࡍʹ΍ͬͯΈΑ͏ ‣ ܖ໿ͱςετͷؔ܎͸ʁ ‣ ࣮ફͷͱ͖ʹؾΛ͚͍ͭͨ͜ͱ ‣ ·ͱΊ

Slide 100

Slide 100 text

ৼΓฦΓ ‣ ܖ໿ϓϩάϥϛϯά͸࢓༷ΛकΔ࢓૊Έ ‣ ਖ਼͠͞͸࢓༷ʴίʔυͰܾ·Δ ‣ ࣄલ৚݅ɾࣄޙ৚݅ɾΫϥεෆมද໌Ͱ࢓༷Λ؂ࢹ͢Δ ‣ 1ZUIPOͰ΋ஈ֊తʹಋೖͰ͖Δ ‣ ܕώϯτˠBTTFSUˠ1ZEBOUJDˠJDPOUSBDU ‣ ܖ໿ͱςετ͸ഉଞؔ܎Ͱ͸ͳ͘खΛऔΓ߹͏૬๮

Slide 101

Slide 101 text

·ͱΊ ‣ ܖ໿ʹίʔυʹ૊Έࠐ·Εͨ҆શ૷ஔ ‣ ςετͱ૊Έ߹Θͤͯೋॏͷ҆શ໢Λ࡞Ζ͏ ‣ ๷ޚతϓϩάϥϛϯά΋ؚΊͨ࢖͍෼͚͕ॏཁ ‣ ϓϩδΣΫτʹ߹ΘͤͯεΠʔτεϙοτΛ୳ͦ͏ ‣ ໌೔͔Β͋ͳͨͷ1ZUIPOϓϩάϥϜʹ΋ܖ໿Λʂ

Slide 102

Slide 102 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠