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

MIXI TECH NOTE #09

MIXI TECH NOTE #09

#技術書典14 に出典された、MIXI GROUP エンジニア有志による技術書です。

<< 目次 >>
1章:静的解析ツールで Golang のうっかりミスをなくそう
2章:探訪 STM at Haskell
3章:Web の回帰テストの自動化
4章:micro:bit のおもしろ活用考査
5章:ChatGPT を QA が使いこなす為のアイデア

<< TECH NOTE 一覧 >>
mixi tech note #01
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-01

mixi tech note #02
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-02

mixi tech note #03
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-03

mixi tech note #04
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-04

mixi tech note #05
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-05

mixi tech note #06
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-06

mixi tech note #07
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-07

MIXI TECH NOTE #08
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-08

MIXI TECH NOTE #09
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-09

XFLAG Tech Note Vol.01
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-01

XFLAG Tech Note vol.02
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-02

MIXI ENGINEERS
PRO

May 22, 2023
Tweet

More Decks by MIXI ENGINEERS

Other Decks in Technology

Transcript

  1. Haskell
    ST
    #09
    CONTENTS
    ੩తղੳπʔϧͰ(Pͷ͏͔ͬΓϛεΛͳͦ͘͏
    ୳๚45.BU)BTLFMM
    8FCͷճؼςετͷࣗಈԽ
    NJDSPCJUͷ͓΋͠Ζ׆༻ߟࠪ
    $IBU(15Λ2"͕࢖͍͜ͳ͢ҝͷΞΠσΞ
    MIXI
    TECH
    NOTE
    Go
    ChatGPT

    View Slide

  2. MIXI TECH NOTE #09
    גࣜձࣾ MIXI ༗ࢤɹஶ
    2023-05-20 ൛ גࣜձࣾ MIXI ൃߦ

    View Slide

  3. View Slide

  4. ·͕͖͑
    ຊॻʮMIXI TECH NOTE #09ʯ͸ɺMIXI GROUP ʹॴଐ͢Δ༗ࢤୡʹΑͬͯࣥචɾ੍࡞͞Εٕͨ
    ज़ॻͰ͢ɻ࣮ࡍͷݱ৔Ͱ࢖ΘΕٕͨज़΍ߟ͑ํɺ·ͨɺݸਓతʹڵຯɾؔ৺ͷ͋Δ෼໺͔Βɺࢥ͍ࢥ
    ͍ʹࣥච͍ͨ͠·ͨ͠ɻͦͷͨΊɺ֤ষͦΕͧΕͰ׬͍݁ͯ͠Δ಺༰ʹͳ͍ͬͯ·͢ͷͰɺ޷͖ͳষ
    ͔Β޷͖ͳॱ൪Ͱָ͓͠Έ͍ͩ͘͞ɻ
    ·ͨɺຊॻ͸ɺMIXI GROUP ʹ͋Δٕज़త஌ݟ΍ΞΠσΞΛੵۃతʹڞ༗ɾެ։͍ͯ͘͜͠ͱ
    ͰɺੈͷதʹΑΓྑ͍αʔϏε͕ҲΕग़͢͜ͱΛئͬͯץߦ͞Ε͍ͯ·͢ɻܝࡌ͞Ε͍ͯΔ৘ใ͸ɺ
    ࣥචऀࣗ਎ͷ؀ڥͰݕূࣥ͠ච͞Εͨ΋ͷͰ͢ͷͰɺ͝ࢀߟʹ͞ΕΔࡍ͸ɺࣗ͝਎ͷ੹೚Ͱ൑அ͠
    ͝׆༻͍ͩ͘͞ɻͳ͓ɺจষදݱʹ͖ͭ·ͯ͠΋ɺࣥචऀࣗ਎ͷݴ༿Ͱ఻͑ͨ͘ɺϑϥϯΫͳදݱͱ
    ͳ͓ͬͯΓ·͢͜ͱ͝ཧղ͍͚ͨͩΕ͹ͱࢥ͍·͢ɻ
    MIXI DEVELOPERS Ұಉ
    ˗ຊॻʹؔ͢Δ͓໰͍߹Θͤઌ
    ɹ https://twitter.com/mixi_engineers
    ˗ MIXI GROUP ʹ͍ͭͯ
    ɹ https://mixi.co.jp/
    ˞ MIXI ͷ໊শɺ͜Εʹؔ࿈͢Δ঎ඪٴͼϩΰ͸ɺגࣜձࣾ MIXI ͷ঎ඪٴͼొ࿥঎ඪͰ͢ɻ·ͨɺ
    ֤ࣾͷձ໊ࣾɺαʔϏεٴͼ੡඼ͷ໊শ͸ɺͦΕͧΕͷॴ༗͢Δ঎ඪ·ͨ͸ొ࿥঎ඪͰ͢ɻ
    iii

    View Slide

  5. View Slide

  6. ໨࣍
    ·͕͖͑ iii
    ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1
    1.1 ͸͡Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
    1.2 Go Analysis Λ࢝ΊΔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
    1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
    1.4 ͓ΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
    ୈ 2 ষ ୳๚ STM at Haskell 13
    2.1 Software Transactional Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
    2.2 STM ͷ࢖ΘΕํ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
    2.3 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
    ୈ 3 ষ Web ͷճؼςετͷࣗಈԽ 23
    3.1 ճؼςετͱ͸ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
    3.2 ՝୊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
    3.3 Ξϓϩʔν . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
    3.4 ࣮ફ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
    3.5 ͍͞͝ʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
    ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 29
    4.1 ຊষʹ͍ͭͯ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
    4.2 ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ . . . . . . . . . . . . . . . . . . . . 32
    4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ . . . . . . . . . . . . . . . . . . . . . . 35
    4.4 ϚΠίϯνοϓ୯ಠϛχήʔϜ੍࡞ . . . . . . . . . . . . . . . . . . . . . . . . . . 45
    4.5 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
    ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 49
    5.1 ChatGPT ͔Β GPT-4 ͕ϦϦʔε . . . . . . . . . . . . . . . . . . . . . . . . . . 49
    5.2 ςετϓϩηε͝ͱͷ׆༻ΞΠσΞ . . . . . . . . . . . . . . . . . . . . . . . . . . 50
    5.3 ৼΓฦΓͰͷ׆༻ΞΠσΞ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
    v

    View Slide

  7. ໨࣍
    5.4 ࣮ફʂ ެࣜαΠτͷ͓஌ΒͤνΣοΫ . . . . . . . . . . . . . . . . . . . . . . . . 54
    5.5 ࠓޙͷల๬ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
    ஶऀ঺հ 59
    vi

    View Slide

  8. ୈ 1 ষ
    ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛ
    ͳͦ͘͏
    1.1 ͸͡Ίʹ
    ຊষʹڵຯΛ࣋ͨΕͨͱݴ͏͜ͱ͸ɺ͓ͦΒ͘೔ʑۀ຿΍झຯͰେྔͷιʔείʔυʹ೴Λম͔Ε
    ͍ͯΔํͱࢥ͍·͢ɻ
    ࢲ͕ܞΘ͍ͬͯΔڞ༡ܕεϙʔπϕοςΟϯάαʔϏε TIPSTAR *1
    Ͱ͸ɺօ͞Μͱಉ༷ʹ೔ʑ
    ਺ઍ͔Β਺ສͷίʔυΛॻ͍ͨΓϨϏϡʔͨ͠Γ (ॻ͖௚ͨ͠Γ) ͓ͯ͠ΓɺͦͷதͰͷେ͖ͳ՝୊
    ͱ࣮ͯ͠૷࿙Ε΍ϨϏϡʔ࿙Ε͕͋Γ·͢ɻ
    ࠷ۙͰ͸ਂ૚ֶशͷൃలʹ൐ͬͯࣗಈͰϓϩμΫτίʔυ͕ग़ͯ͘Δ & ϨϏϡʔͯ͘͠ΕΔະདྷ
    ΋ඵಡΈ͔ɺͱ͍͏ྲྀΕ΋͋Γ·͕͢ɺґવͱͯ͠ʮͰ͖ΔͳΒ࣮֬ʹ͜͜͸ݟಀͨ͘͠ͳ͍ʯͱ͔
    ʮ͜Μͳ໌Β͔ͳ͏͔ͬΓϛε͸ͬ͞͞ͱؾ෇͍ͯ΄͍͠ʯΈ͍ͨͳ͜ͱ͸͋Δͱࢥ͍·͢ɻ
    ͨͱ͑͹࣍ͷϖʔδͷ human.go ΛϨϏϡʔͯ͠Έ·͠ΐ͏ɻ
    *1 https://about.tipstar.com/ MIXI ͕ӡӦ͢ΔɺڝྠɾPIST6ɾΦʔτϨʔεͷωοτ౤ථΛجຊແྉͰָ͠Ή͜ͱ
    ͕Ͱ͖ΔαʔϏεͰ͢
    1

    View Slide

  9. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.1 ͸͡Ίʹ
    Ϧετ 1.1: human.go
    1: package main
    2:
    3: import (
    4: "errors"
    5: "fmt"
    6: "log"
    7: )
    8:
    9: type Human struct {
    10: Name string
    11: Age int
    12: }
    13:
    14: func (m *Human) IsValid() error {
    15: if m.Name == "" {
    16: return errors.New("Human has no Name")
    17: }
    18: return nil
    19: }
    20:
    21: func (m *Human) Profile() (string, error) {
    22: if err := m.IsValid(); err != nil {
    23: log.Printf("[err] Human Profile raise err: since %v", err)
    24: return "", nil // error handling ...
    25: }
    26: return fmt.Sprintf("Name: %s, Age: %d", m.Name, m.Age), nil
    27: }
    28:
    29: func main() {
    30: me := Human{Name: "Meguru", Age: 25}
    31: profile, err := me.Profile()
    32: if err != nil {
    33: log.Fatal(err)
    34: }
    35: fmt.Printf("[%s] Hello, World\n", profile)
    36: }
    ϩάΛग़ͯ҆͠৺ͯ͠͠·ͬͨͷ͔ɺProfile ؔ਺ͷ L.23 Ͱൃੜͨ͠ΤϥʔΛݟա͍ͯ͝͠·
    ͢Ͷɻ͜ͷ··Ͱ͸ main ؔ਺Ͱҙਤ͠ͳ͍ Hello, World ͕දࣔ͞Εͯ͠·͍·͢ɻ
    ຊষͰ͸͜ͷΑ͏ͳϨϏϡʔͷۤ͠ΈΛগ͠Ͱ΋ղফ͢Δɺ੩తղੳπʔϧͷ࡞Γํʹ͍ͭͯ঺հ
    ͠·͢ɻ
    2

    View Slide

  10. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.2 Go Analysis Λ࢝ΊΔ
    1.2 Go Analysis Λ࢝ΊΔ
    ੩తղੳͱ͸ϓϩάϥϜͷίʔυΛίʔυͱͯ͠ (࣮ߦ͢Δ͜ͱͳ͘) ݕূ͢Δ͜ͱΛࢦ͠ɺಘΒ
    Εͨղੳ݁ՌΛར༻͢Δ͜ͱͰҙਤ͠ͳ͍ಈ࡞Λݕ஌Ͱ͖·͢ɻ
    Go ͷ੩తղੳͷͨΊඪ४ύοέʔδͱͯ͠͸ Go Analysis *2
    ͕͋Γɺ͜ͷύοέʔδΛ༻͍ͯ
    ੩తղੳͷॲཧΛڞ௨Խ͢Δ͜ͱͰޮ཰తʹ੩తղੳπʔϧΛ࣮૷Ͱ͖·͢ɻ
    ·ͨઌਓͨͪ΋ଟ͘ͷπʔϧΛ࣮૷͓ͯ͠Γɺͨͱ͑͹ GoStaticAnalysis *3
    ϦϙδτϦʹ͸ଟ
    ͘ͷ੩తղੳπʔϧ͕ଘࡏ͢ΔͨΊɺ͜ΕΒΛࢀߟʹ͢Δ͜ͱ΋Ͱ͖·͢ɻ
    ʢࠓճ͸͔̍Β࡞ͬͯΈ
    ·͢ʣ
    ݸਓతͳܦݧͰ͸͋Γ·͕͢ɺಛʹ Go Analysis Λ༻͍ͯ੩తղੳπʔϧΛ࣮૷͢ΔͨΊͷύλʔ
    ϯͱͯ͠ɺҎԼͷΑ͏ͳྲྀΕͰ࣮૷͢Δ͜ͱ͕ଟ͍Ͱ͢ɻ
    1. ҙਤ͠ͳ͍ίʔυͷαϯϓϧΛ࡞Δ
    2. ͦͷαϯϓϧίʔυΛதؒදݱͱݺ͹ΕΔ੩తղੳʹศརͳܗʹม׵ͯ͠ɺҙਤ͠ͳ͍ڍಈ͕
    ͲͷΑ͏ͳঢ়ଶʹΑͬͯҾ͖ى͜͞ΕΔͷ͔Λௐ΂Δ
    3. αϯϓϧίʔυͷҙਤ͠ͳ͍෦෼ʹ͍ͭͯܯࠂΛൃੜ͢ΔΑ͏ʹ੩తղੳπʔϧΛ࣮૷͢Δ
    4. ࣮૷্ؾ෇͍ͨ͜ͱͳͲΛࢀߟʹɺαϯϓϧͷ௥Ճ + πʔϧͷϦϑΝΫλϦϯάΛߦ͏
    ࠓճ͸ 1. ͷαϯϓϧͱͯ͠ human.go Λ༻͍͍͖ͯɺ2., 3. ʹ͍ͭͯΛ͜ͷޙͷઅͰ঺հ͍ͯ͠
    ͖·͢ɻ
    Go ͷίʔυΛதؒදݱͰಡΈ௚ͯ͠ΈΔ
    தؒදݱͱ͸ Go ͷιʔείʔυΛ෼ੳ͠΍ͨ͘͢͠΋ͷͰ͋Γɺ۩ମతʹ͸ ந৅ߏจ໦ (AST,
    Abstract Syntax Tree) ͱ੩త୯Ұ୅ೖܗࣜ (SSA, Static Single Assignment) ͳͲ͕͋Γ·͢ɻ
    ҎԼʹͦΕͧΕͷදݱͱ Go ͷίʔυΛಡΈࠐΜͰͦΕͧΕͷதؒදݱͰग़ྗͯ͘͠ΕΔ؆қεΫ
    ϦϓτΛ঺հ͍͖ͯ͠·͢ɻ
    ந৅ߏจ໦ (AST)
    ந৅ߏจ໦ͱ͸ʮTreeʯͱ໊લʹ͋ΔΑ͏ʹɺϓϩάϥϜͳͲͷίʔυΛ໦ߏ଄ʹஔ͖׵͑ͨ΋ͷ
    ʹͳΓ·͢ɻͨͱ͑͹ 1 + 2 ͱ͍ͬͨ଍͠ࢉΛந৅ߏจ໦্Ͱද͢ͱ
    • Ճࢉԋࢉࢠ + Λ෼ذ఺
    • ࠨӈʹ஋Ͱ͋Δ 1 , 2 Λ༿
    ͱ͢ΔΑ͏ͳਫ෼ࢠͷΑ͏ͳΠϝʔδ͕ߟ͑ΒΕ·͢ɻ
    *2 https://godoc.org/golang.org/x/tools/go/analysis
    *3 https://github.com/gostaticanalysis
    3

    View Slide

  11. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.2 Go Analysis Λ࢝ΊΔ
    ਤ 1.1: 1 + 2 ͷந৅ߏจ໦
    Go ͷίʔυΛந৅ߏจ໦ʹ෼ղ͢Δʹ͸ҎԼͷΑ͏ͳαϯϓϧίʔυΛར༻Ͱ͖·͢ɻ
    Ϧετ 1.2: cmd/astdump/main.go
    1: package main
    2:
    3: import (
    4: "flag"
    5: "go/ast"
    6: "go/parser"
    7: "go/token"
    8: "log"
    9: )
    10:
    11: func main() {
    12: s := flag.String("f", "human.go", "file-path")
    13: flag.Parse()
    14:
    15: fset := token.NewFileSet()
    16: f, err := parser.ParseFile(fset, *s, nil, 0)
    17: if err != nil {
    18: log.Fatalf("Failed to parse file: cause %v", err)
    19: }
    20: if err := ast.Print(fset, f); err != nil {
    21: log.Fatalf("Print failed: cause %v", err)
    22: }
    23: }
    go run ./cmd/astdump -f human.go Ͱग़ྗΛಘΒΕɺͦͷ͏ͪͷ Profile ؔ਺ͷҰ෦ΛऔΓ
    ग़͢ͱ࣍ͷΑ͏ʹͳΓ·͢ɻ
    ಛʹ L.366 ͷ *ast.ReturnStmt ͸ human.go ʹ͓͚Δ return "", nil // error handlin
    g ... ͷ෦෼ʹ֘౰͠·͢ɻ
    4

    View Slide

  12. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.2 Go Analysis Λ࢝ΊΔ
    astdump.log
    226 . . 3: *ast.FuncDecl {
    283 . . . Body: *ast.BlockStmt {
    284 . . . . Lbrace: human.go:21:43
    285 . . . . List: []ast.Stmt (len = 2) {
    286 . . . . . 0: *ast.IfStmt {
    287 . . . . . . If: human.go:22:2
    321 . . . . . . Cond: *ast.BinaryExpr {
    322 . . . . . . . X: *ast.Ident {
    323 . . . . . . . . NamePos: human.go:22:25
    324 . . . . . . . . Name: "err"
    325 . . . . . . . . Obj: *(obj @ 293)
    326 . . . . . . . }
    327 . . . . . . . OpPos: human.go:22:29
    328 . . . . . . . Op: !=
    329 . . . . . . . Y: *ast.Ident {
    330 . . . . . . . . NamePos: human.go:22:32
    331 . . . . . . . . Name: "nil"
    332 . . . . . . . }
    333 . . . . . . }
    334 . . . . . . Body: *ast.BlockStmt {
    335 . . . . . . . Lbrace: human.go:22:36
    336 . . . . . . . List: []ast.Stmt (len = 2) {
    337 . . . . . . . . 0: *ast.ExprStmt {
    338 . . . . . . . . . X: *ast.CallExpr {
    339 . . . . . . . . . . Fun: *ast.SelectorExpr {
    340 . . . . . . . . . . . X: *ast.Ident {
    341 . . . . . . . . . . . . NamePos: human.go:23:3
    342 . . . . . . . . . . . . Name: "log"
    343 . . . . . . . . . . . }
    344 . . . . . . . . . . . Sel: *ast.Ident {
    345 . . . . . . . . . . . . NamePos: human.go:23:7
    346 . . . . . . . . . . . . Name: "Printf"
    347 . . . . . . . . . . . }
    348 . . . . . . . . . . }
    365 . . . . . . . . }
    366 . . . . . . . . 1: *ast.ReturnStmt {
    367 . . . . . . . . . Return: human.go:24:3
    368 . . . . . . . . . Results: []ast.Expr (len = 2) {
    369 . . . . . . . . . . 0: *ast.BasicLit {
    370 . . . . . . . . . . . ValuePos: human.go:24:10
    371 . . . . . . . . . . . Kind: STRING
    372 . . . . . . . . . . . Value: "\"\""
    373 . . . . . . . . . . }
    374 . . . . . . . . . . 1: *ast.Ident {
    375 . . . . . . . . . . . NamePos: human.go:24:14
    376 . . . . . . . . . . . Name: "nil"
    377 . . . . . . . . . . }
    440 . . }
    5

    View Slide

  13. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.2 Go Analysis Λ࢝ΊΔ
    ੩త୯Ұ୅ೖܗࣜ (SSA)
    ੩త୯Ұ୅ೖܗࣜͱ͸ղੳ͢Δίʔυ্Ͱม਺ఆ͕ٛҰҙʹͳΔΑ͏ͳ (ಉ໊͡લͷม਺Λڐ͞ͳ
    ͍) ܗͷதؒදݱͰ͢ɻ͜ͷදݱΛར༻͢Δͱɺಉ໊͡લͷม਺ʹ஋Λ্ॻ͖ͯ͠͠·ͬͨ͜ͱΛݕ
    ஌ͨ͠Γɺ͋Δ஋͕ͲͷܕͰѻΘΕ͍ͯΔ͔Λௐࠪͨ͠Γɺͱ͍ͬͨ͜ͱ͕༰қʹͳΓ·͢ɻ
    ιʔείʔυΛ SSA ΁ม׵͢Δʹ͸ golang.org/x/tools/cmd/ssadump Λར༻Ͱ͖·͢ɻ
    sample.sh
    go build -o ./bin/ssadump golang.org/x/tools/cmd/ssadump
    ./bin/ssadump -build=F ./human.go
    ग़ྗͷ͏ͪ Profile ؔ਺ͷΈΛऔΓग़͢ͱ࣍ͷΑ͏ʹͳΓ·͢ɻ
    ಛʹ return "":string, nil:error ͸ human.go ʹ͓͚Δ return "", nil // error han
    dling ... ͷ෦෼ʹ֘౰͠·͢ɻ
    ssadump.log
    func (m *Human) Profile() (string, error):
    0: entry P:0 S:2
    t0 = (*Human).IsValid(m) error
    t1 = t0 != nil:error bool
    if t1 goto 1 else 2
    1: if.then P:1 S:0
    t2 = new [1]any (varargs) *[1]any
    t3 = &t2[0:int] *any
    t4 = change interface any <- error (t0) any
    *t3 = t4
    t5 = slice t2[:] []any
    t6 = log.Printf("[err] Humun Profi...":string, t5...) ()
    return "":string, nil:error
    2: if.done P:1 S:0
    t7 = &m.Name [#0] *string
    t8 = *t7 string
    t9 = &m.Age [#1] *int
    t10 = *t9 int
    t11 = new [2]any (varargs) *[2]any
    t12 = &t11[0:int] *any
    t13 = make any <- string (t8) any
    *t12 = t13
    t14 = &t11[1:int] *any
    t15 = make any <- int (t10) any
    *t14 = t15
    t16 = slice t11[:] []any
    t17 = fmt.Sprintf("Name: %s, Age: %d":string, t16...) string
    return t17, nil:error
    6

    View Slide

  14. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ
    1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ
    ੩తղੳπʔϧΛ࣮૷͢ΔͨΊͷςϯϓϨʔτͱͯ͠ skeleton *4
    ͕͋Γ·͢ɻ
    skeleton Λར༻ͨ͠৔߹ͷ੩తղੳπʔϧͷςϯϓϨʔτ͸ҎԼͷΑ͏ʹͳΓ·͢ɻ
    ·ͣ͸ samplelinter/testdata/src/a/a.go ΁αϯϓϧίʔυ (hello.go) Λςετͱͯ͠഑
    ஔͯ͠ɺςετʹ߹֨͢ΔΑ͏ίʔυΛΰϦΰϦॻ͍͍͖ͯ·͠ΐ͏ɻ
    skeleton-tree
    .
    ᵋᴷᴷ samplelinter
    ᵓᴷᴷ cmd
    ᴹ ᵋᴷᴷ samplelinter
    ᴹ ᵋᴷᴷ main.go
    ᵓᴷᴷ go.mod
    ᵓᴷᴷ samplelinter.go // ͜͜ʹίʔυΛॻ͘
    ᵓᴷᴷ samplelinter_test.go
    ᵋᴷᴷ testdata
    ᵋᴷᴷ src
    ᵋᴷᴷ a
    ᵓᴷᴷ a.go // human.go Α͏ͳαϯϓϧσʔλΛ֨ೲ͢Δ
    ᵋᴷᴷ go.mod
    human.go ͷΈͷέʔεΛߟ͑Ε͹ɺҎԼͷΑ͏ͳ࣮૷Λ͢Ε͹Αͦ͞͏Ͱ͢ *5 *6
    ɻ
    Ϧετ 1.3: samplelinter/samplelinter.go
    1: package samplelinter
    2:
    3: import (
    4: "go/token"
    5: "go/types"
    6: "strings"
    7:
    8: "github.com/gostaticanalysis/comment"
    9: "github.com/gostaticanalysis/comment/passes/commentmap"
    10: "golang.org/x/tools/go/analysis"
    11: "golang.org/x/tools/go/analysis/passes/buildssa"
    12: "golang.org/x/tools/go/ssa"
    13: )
    *4 https://github.com/gostaticanalysis/skeleton
    *5
    ࣮ࡍ͸ΑΓଟ͘ͷαϯϓϧέʔεΛߟ͑ͨΓɺࣗಈੜ੒ͷϑΝΠϧΛݟಀͨ͠Γͱ͍ͬͨϓϩδΣΫτ͝ͱͷࡉ͔ͳઃ
    ఆΛ଍͍ͯ͘͠ඞཁ͕͋Γ·͢ɻ
    *6
    ࠓճͷΑ͏ͳΤϥʔϋϯυϦϯάʹ͍ͭͯ͸ https://github.com/gostaticanalysis/nilerr ͷΑ͏ͳطଘͷπʔϧΛ
    ར༻͢Δ͜ͱ΋ՄೳͰ͢ɻͰ͕࣮͢͸ࠓճͷ human.go ͷΑ͏ͳέʔε͸ nilerr ͩͱݕ஌͠ͳ͍έʔεͩͬͨΓ͠·
    ͢ (ࠓճͷٕज़ॻయΛॻ͘ʹࢸͬͨಈػ)ɻ
    7

    View Slide

  15. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ
    14:
    15: const (
    16: doc = "samplelinter is checker for missing error handling"
    17: nilErr = "nil:error"
    18: )
    19:
    20: var Analyzer = &analysis.Analyzer{
    21: Name: "samplelinter",
    22: Doc: doc,
    23: Run: run,
    24: Requires: []*analysis.Analyzer{
    25: buildssa.Analyzer,
    26: commentmap.Analyzer,
    27: },
    28: }
    29:
    30: var errorType = types.Universe.Lookup("error").Type()
    31:
    32: func run(pass *analysis.Pass) (any, error) {
    33: s := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
    34: cmaps := pass.ResultOf[commentmap.Analyzer].(comment.Maps)
    35:
    36: // ର৅ͷίʔυ಺ͷؔ਺ʹ͍ͭͯ෼ੳ
    37: for _, f := range s.SrcFuncs {
    38: fileName := pass.Fset.Position(f.Pos()).Filename
    39: // ςετͷϑΝΠϧ͸আ֎
    40: if strings.HasSuffix(fileName, "_test.go") {
    41: continue
    42: }
    43: // error ܕΛฦ͞ͳ͍ؔ਺͸আ֎
    44: if !hasErrInResults(f.Signature.Results()) {
    45: continue
    46: }
    47: for _, b := range f.Blocks {
    48: for _, instr := range b.Instrs {
    49: switch instr := instr.(type) {
    50: // if err != nll Λݕ஌
    51: case *ssa.BinOp:
    52: if isNilErrorCheck(instr) {
    53: retBlock := instr.Block().Succs[0]
    54: // ؼΓ஋ͷதʹ err (not nil) ͕
    55: // ೖ͍ͬͯͳ͚Ε͹ܯࠂ
    56: checkErrorReturnValue(
    57: retBlock, pass, cmaps,
    58: )
    59: }
    60: }
    61: }
    62: }
    63: }
    64: return nil, nil
    65: }
    66:
    67: func isNilErrorCheck(ifstmt *ssa.BinOp) bool {
    8

    View Slide

  16. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ
    68: if ifstmt.Op != token.NEQ {
    69: return false
    70: }
    71: // ‘if err != nil‘ or ‘if nil != err‘ Λݕ஌
    72: return (isTypeError(ifstmt.Y.Type()) && ifstmt.X.Name() == nilErr) ||
    73: (isTypeError(ifstmt.X.Type()) && ifstmt.Y.Name() == nilErr)
    74: }
    75:
    76: func isTypeError(t types.Type) bool {
    77: if _, ok := t.Underlying().(*types.Interface); !ok {
    78: return false
    79: }
    80: return types.Identical(t, errorType)
    81: }
    82:
    83: func checkErrorReturnValue(
    84: b *ssa.BasicBlock, pass *analysis.Pass, cmaps comment.Maps,
    85: ) {
    86: for _, instr := range b.Instrs {
    87: ret, ok := instr.(*ssa.Return)
    88: if !ok {
    89: continue
    90: }
    91: // ‘//lint:ignore samplelinter xxx‘ ίϝϯτΛແࢹ͢Δ
    92: if cmaps.IgnorePos(ret.Pos(), "samplelinter") {
    93: continue
    94: }
    95: hasErr := false
    96: for _, v := range ret.Results {
    97: if isTypeError(v.Type()) && v.Name() != nilErr {
    98: hasErr = true
    99: }
    100: }
    101: if len(ret.Results) != 0 && !hasErr {
    102: pass.Reportf(
    103: ret.Pos(),
    104: "[samplelinter] return err should be included "+
    105: "in this return stmt."+
    106: "you seem to be ignoring error handling",
    107: )
    108: }
    109: }
    110: }
    111:
    112: func hasErrInResults(rets *types.Tuple) bool {
    113: for i := 0; i < rets.Len(); i++ {
    114: ret := rets.At(i)
    115: if ret.Type() == errorType {
    116: return true
    117: }
    118: }
    119: return false
    120: }
    9

    View Slide

  17. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.3 ੩తղੳπʔϧΛॻ͍ͯΈΔ
    ϓϩδΣΫτʹಋೖ͢Δ
    ͍͟੩తղੳπʔϧΛ࡞ͬͨͱ͜ΖͰɺ࣮ࡍʹϓϩμΫτίʔυ΁ద༻Ͱ͖ͳ͚Ε͹͔ͤͬ͘ͷ౒
    ྗ͕ແବʹͳͬͯ͠·͍·͢ɻ
    TIPSTAR Ͱ͸ɺ࡞੒ͨ͠੩తղੳπʔϧ͸ϓϩδΣΫτ಺ʹ഑ஔͯ͠ CI ্Ͱ࣮ߦ͞ΕΔΑ͏ʹ
    ઃఆͯ͠೔ʑͷίʔυͷ҆৺ɾ҆શΛक͍ͬͯ·͢ɻ
    ۩ମతʹ͸࣍ͷΑ͏ͳσΟϨΫτϦߏ଄ͷ഑ஔΛߦ͍ɺ࡞੒ͨ͠੩తղੳπʔϧΛ myanalyzer/
    main.go ΁഑ஔͯ͠όΠφϦʹϏϧυ *7
    ͢Δ͜ͱͰར༻͍ͯ͠·͢ɻ
    app-dir
    ./app
    ᵓᴷᴷ Makefile
    ᵓᴷᴷ README.md
    ᵓᴷᴷ bin
    ᴹ ᵋᴷᴷ myanalyzer
    ᵓᴷᴷ go.mod
    ᵓᴷᴷ go.sum
    ᵓᴷᴷ internal
    ᵋᴷᴷ tools
    ᵋᴷᴷ myanalyzer
    ᵓᴷᴷ samplelinter/
    ᵓᴷᴷ xxxlinter/
    ᵋᴷᴷ main.go
    Ϧετ 1.4: tools/mylinters/main.go
    1: package main
    2:
    3: import (
    4: "golang.org/x/tools/go/analysis/multichecker"
    5:
    6: "github.com/project/app/tools/myanalyzer/samplelinter"
    7: "github.com/project/app/tools/myanalyzer/xxxlinter"
    8: )
    9:
    10: func main() {
    11: multichecker.Main(
    12: samplelinetr.Analyzer,
    13: xxxlinter.Analyzer,
    14: )
    15: }
    *7 go build -o bin/mylinters tools/myanalyzer/main.go
    10

    View Slide

  18. ୈ 1 ষ ੩తղੳπʔϧͰ Go ͷ͏͔ͬΓϛεΛͳͦ͘͏ 1.4 ͓ΘΓʹ
    1.4 ͓ΘΓʹ
    ຊষͰ͸ Go ͷ੩తղੳΛ௨ͯ͡͏͔ͬΓͳϛεʹؾ෇ͨ͘Ίͷ͘͠ΈΛ঺հ͠·ͨ͠ɻ೔ʑͷ։
    ൃ଎౓Λۤ͠·ͣʹՃ଎ͤ͞Δʹ͸ɺ։ൃऀ͕ੜΈग़͍ͨ͠Ձ஋ͷϝΠϯϩδοΫʹूதͰ͖Δ؀ڥ
    ͮ͘ΓΛࢧԉ͢Δ͜ͱ͕த௕ظతʹ͸༗ޮͰ͢ɻ
    ౰ͨΓલʹΘ͔Δࡉ͔͍࡞ۀ͸ AI ͷΈͳΒͣɺ͜ͷΑ͏ͳπʔϧΛ׆༻͢Δ͜ͱͰͲΜͲΜࣗಈ
    Խ͍͖ͯ͠·͠ΐ͏ɻ
    11

    View Slide

  19. View Slide

  20. ୈ 2 ষ
    ୳๚ STM at Haskell
    ϓϩάϥϛϯάݴޠͷओཁͳػೳͷҰͭʹฒྻɾฒߦϓϩάϥϛϯάͷͨΊͷػೳ͕͋Γ·͢ɻ
    ຊߘͰ͸ɺฒྻɾฒߦϓϩάϥϛϯάͷͨΊͷػೳͱͯ͠ Haskell ʹ͋Δ Software Transactional
    MemoryʢSTMʣʹ͍ͭͯɺOSS Ͱͷར༻ͷ͞ΕํΛަ͑ͳ͕Β঺հ͠·͢ɻ஫ҙ఺ͱͯ͠ɺSTM
    ͸ Haskell ͷσϑΝΫτελϯμʔυͳॲཧܥͰ͋Δ GHC Ͱ࣮૷͞Εͨػೳʢਖ਼֬ʹ͸ GHC 6.4
    ͔ΒʣͰɺҎ߱ Haskell ͱݴͬͨ৔߹͸҉໧తʹ GHC Λࢦ͠·͢ɻ·ͨɺຊߘͰ͸ STM ͷ಺෦࣮
    ૷΍ݪ࿦จʹ͍ͭͯ͸ಛʹݴٴͤͣɺར఺΍࢖͍ํɾ࢖ΘΕํͳͲʹ͍ͭͯ঺հ͢Δɺൺֱత؆୯ͳ
    هࣄͰ͢ɻ
    2.1 Software Transactional Memory
    Software Transactional Memory ͸ɺฒྻɾฒߦϓϩάϥϛϯάͷࡍʹϦιʔεΛڞ༗͢ΔͨΊ
    ͷ͘͠ΈͷҰͭͰ͢ɻσʔλϕʔεʹ͋ΔΑ͏ͳෆՄ෼ͳॲཧΛ࣮ߦ͢ΔͨΊʹ࢖͏τϥϯβΫγϣ
    ϯͷ͘͠ΈΛɺϝϞϦϦιʔεͰ࣮ݱ͠·͢ɻ
    ͨͱ͑͹ɺෳ਺εϨουͰڞ༗͍ͯ͠Δม਺ΛಡΈࠐΜͰߋ৽͍ͨ͜͠ͱ͕͠͹͠͹͋Δͱࢥ͍·
    ͢ɻଟ͘ͷ৔߹ɺഉଞ੍ޚΛར༻ͯ͠ɺม਺ΛಡΈࠐΜͰߋ৽ͯ͠อଘ͢ΔؒΛෆՄ෼ͳॲཧͱͯ͠
    ࣮૷͢Δͱࢥ͍·͢ɿ
    // ͜Ε͸ Go Ͱͷ࣮૷
    func (ConcurrentMap cm) insert(k, v string) bool {
    cm.mu.lock()
    defer cm.mu.unlock()
    if _, ok := cm.m[k]; ok {
    return false
    }
    cm.m[k] = v
    return true
    }
    ͜Ε͸ͨͩɺ࿈૝഑ྻͷܕʹ஋Λొ࿥͍ͯ͠Δ͚ͩͷؔ਺Ͱ͢ɻͨͩ͠ɺϚϧνεϨουʹ࣮ߦ͞
    13

    View Slide

  21. ୈ 2 ষ ୳๚ STM at Haskell 2.1 Software Transactional Memory
    Εͯ΋ྑ͍Α͏ʹɺlock() ͱ unlock() Ͱഉଞ੍ޚΛ͍ͯ͠·͢ɻରͯ͠ STM ͸ɺ͜ͷΑ͏ͳෆ
    Մ෼ͳॲཧΛ࣍ͷΑ͏ʹॻ͖·͢ɿ
    type ConcurrentMap = TVar (Map String String)
    insert :: ConcurrentMap -> String -> String -> STM Bool
    insert cm k v = do
    m <- readTVar cm
    if Map.member k m then
    return False
    else do
    modifyTVar cm $ Map.insert k v
    return True
    STM ͳڞ༗Ϧιʔεʹ͸ TVar a ܕΛ࢖͍·͢ɻ࣮ࡍʹѻ͏ܕ͕ a ͷํͰɺࠓճ͸ Map String
    String ͱݴ͏γϯϓϧͳ࿈૝഑ྻܕΛ࢖͍ͬͯ·͢ɻTVar a ܕͷ஋͔Β a ܕͷ஋ΛऔΓग़͢ͷʹ
    ͸ readTVar ؔ਺Λ࢖͍ɺ্ॻ͖͢Δ৔߹ʹ͸ writeTVar ؔ਺Λɺߋ৽͢Δ৔߹ʹ͸ modifyTVar
    ؔ਺Λ࢖͍·͢ɿ
    readTVar :: TVar a -> STM a
    writeTVar :: TVar a -> a -> STM ()
    modifyTVar :: TVar a -> (a -> a) -> STM ()
    औΓग़ͨ͠͸ͣͳͷʹ໭Γ஋ͷܕ͕ STM a ʹͳ͍ͬͯ·͢Ͷɻ͜ͷ STM ͱݴ͏෦෼͕ɺෆՄ෼ͳ
    ॲཧͰ͋Δ͜ͱΛදݱ͍ͯ͠·͢ɻSTM ͸ Monad ܕΫϥεͷΠϯελϯεͰ͢ͷͰɺDo ه๏ʹΑͬ
    ͯ؆୯ʹ߹੒ՄೳͰ͢ɻ
    ࣮͸ɺinsert ؔ਺ʹҾ਺Λ༩͑Δ͚ͩͰ͸ɺॲཧ͕࣮ߦ͞Ε·ͤΜɻSTM a ͳෆՄ෼ͳॲཧΛ࣮
    ߦ͢Δʹ͸ atomically ͱ͍͏ؔ਺Λ࢖͍·͢ɻ
    atomically :: STM a -> IO a
    -- insert ͸࣍ͷΑ͏ʹ࢖͏
    atomically $ insert cm k v
    atomically ʹΑͬͯෆՄ෼ͳॲཧ͕࣮ߦ͞Ε͍ͯΔ్தͰɺڞ༗Ϧιʔεʹߋ৽͕͋ͬͨ৔߹
    ͸ɺͳΜͱෆՄ෼ͳॲཧΛ࠷ॳ͔Β΍Γ௚͠·͢ɻinsert ؔ਺Ͱ͋Ε͹ɺreadTVar Λͯ͠ modif
    yTVar ͢ΔؒʹɺผͷεϨου͔Β cm ͕ߋ৽͞Εͨ৔߹Ͱ͢ɻ͜ͷΑ͏ʹෆՄ෼ͳॲཧΛࣗಈͰ΍
    Γ௚ͯ͘͠ΕΔͨΊɺഉଞ੍ޚΛ͢Δඞཁ͕ͳ͍ͱݴ͏Θ͚Ͱ͢ɻ
    14

    View Slide

  22. ୈ 2 ষ ୳๚ STM at Haskell 2.1 Software Transactional Memory
    ͪͳΈʹɺHaskell Ͱͷฒߦɾฒྻϓϩάϥϛϯάʹؔͯ͠͸ɺ
    ʮHaskell ʹΑΔฒߦɾฒྻϓϩά
    ϥϛϯάʯ
    ʢݪஶ͸ʮParallel and Concurrent Programming in Haskellʯ
    ʣ
    *1
    ͱ͍͏ྑॻ͕͋Γɺͦ
    ͜Ͱ͸ୈ 10 ষͰҰষؙʑΛ࢖ͬͯ঺հ͞Ε͍ͯ·͢ɻ2014 ೥ग़൛ʢݪஶͷ৔߹͸ 2013 ೥ʣͱগ͠
    ݹ͍ॻ੶Ͱ͕͢ɺຊߘΛಡΜͰڵຯΛ࣋ͬͨํ͸ͥͻɺΑΓৄ͘͠ॻ͍ͯ͋ΔʮHaskell ʹΑΔฒߦɾ
    ฒྻϓϩάϥϛϯάʯΛಡΜͰΈ͍ͯͩ͘͞ɻ
    stm ύοέʔδ
    ઌड़ͨ͠ܕ΍ؔ਺ɺ
    ʮHaskell ʹΑΔฒߦɾฒྻϓϩάϥϛϯάʯͰ঺հ͞Ε͍ͯΔ͍͔ͭ͘ͷ࣮૷
    ύλʔϯ͸ stm ύοέʔδ*2
    ʹ͋Γ·͢ɻͨͱ͑͹ɺTVar a ܕͷ΄͔ʹ࣍ͷΑ͏ͳΑΓϦονͳ
    σʔλߏ଄͕͢Ͱʹఆٛ͞Ε͍ͯ·͢ɿ
    • TChan a ܕɿແ੍ݶ௕ͷ FIFO νϟϯωϧΛදͨ͠ܕ
    • TQueue a ܕ : TChan ΑΓߴ଎͕ͩෳ੡ෆՄೳͳνϟϯωϧ
    • TBQueue a ܕ : TQueue ʹ௕͞ͷ্ݶΛઃ͚ͨ΋ͷ
    ޙड़͢Δ OSS Ͱ͸ɺ͜ΕΒͷܕΛར༻ͯ͠ɺ͞·͟·ͳڞ༗ϦιʔεΛѻ͏͘͠ΈΛ࣮૷͍ͯ͠
    ·͢ɻͪͳΈʹɺຊߘͰ͸ࣥච࣌఺ͷ stm ύοέʔδͷ࠷৽όʔδϣϯͰ͋Δ 2.5.1.0 Λલఏʹ͠
    ·͢ɻ
    Haskell Ͱฒߦϓϩάϥϛϯά
    Haskell ͸ɺGo ͷ goroutine ͷΑ͏ͳܰྔεϨουʢάϦʔϯεϨουʣΛ࣮૷͍ͯ͠ΔͨΊɺൺ
    ֱత؆୯ʹฒߦϓϩάϥϛϯά͕ՄೳͰ͢ɻผͷεϨουͰ IO ΞΫγϣϯΛ࣮ߦ͢Δʹ͸ forkIO
    ͱݴ͏ؔ਺Λ࢖͍·͢ɿ
    forkIO :: IO () -> IO ThreadId
    ThreadId ͸໊લͷ௨Γɺ࡞੒͞ΕͨεϨουͷ ID Ͱ͢ɻ·ͨɺ࡞੒ͨ͠εϨουͷऴྃΛ଴ͬ
    ͨΓɺྫ֎ॲཧΛ͏·͘΍ͬͨΓ͢ΔͨΊͷ async ύοέʔδ*3
    ͱݴ͏ͷ͕͋Γ·͢ɻ
    data Async a
    async :: IO a -> IO (Async a)
    wait :: Async a -> IO a
    cancel :: Async a -> IO ()
    *1 https://www.oreilly.co.jp/books/9784873116891/
    *2 https://hackage.haskell.org/package/stm
    *3 https://hackage.haskell.org/package/async
    15

    View Slide

  23. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    Async a ܕ͸ɺผεϨουͰ IO ΞΫγϣϯΛ࣮ߦͨ݁͠Ռɺa ܕͷ஋ΛಘΔͱݴ͏ͷΛදͨ͠ܕ
    Ͱ͢ɻasync ؔ਺ʹΑͬͯผεϨου͕࡞੒͞Εɺ࡞੒ݩ͸ wait ͰॲཧͷऴྃΛ଴ͬͨΓɺcance
    l Ͱڧ੍ऴྃͨ͠ΓͰ͖·͢ɻ
    ͪͳΈʹɺ಺෦తʹ͸ STM Λར༻ͯ͠ɺ͜ͷΑ͏ͳৼΔ෣͍Λදݱ͍ͯ͠·͢ɻ
    2.2 STM ͷ࢖ΘΕํ
    ͔͜͜Β͸ɺOSS Ͱͷ stm ύοέʔδͷ࢖͍ํΛྫʹͯ͠ɺSTM ͷศརͳ࢖͍ํΛ঺հ͠·͢ɻ
    MIXI Git Challenge ͷείΞαʔό
    MIXI Ͱ͸ɺGit Challenge ͱ͍͏ֶੜ޲͚ڝٕܕΠϕϯτΛఆظతʹ։࠵͍ͯ͠·͢*4
    ɻGit Λ
    ࢖ͬͯղ͘ڝٕϓϩάϥϛϯάͷΑ͏ͳ΋ͷͰ͢ɻ͜Εͷࣗಈ࠾఺Λͨ͠Γɺ
    ੒੷ΛӾཡͰ͖Δ Web
    ϖʔδΛฦͨ͠Γ͢ΔείΞαʔόΛ Haskell Ͱࣗ࡞͍ͯ͠·͢*5
    ɻ
    ͜ͷείΞαʔόͰ͸ɺࣗಈ࠾఺Λඇಉظʹߦ͏αʔό෦෼Ͱ STM Λར༻͍ͯ͠·͢ɻαʔό
    ͸ɺ࣮ࡍʹॲཧΛߦ͏ Worker Λෳ਺୆؅ཧ͓ͯ͠Γɺͦͷ Worker ͷ؅ཧ৘ใΛ STM ʹ͍ͯ͠
    ·͢ɿ
    src/Git/Plantation/Job/Worker.hs ΑΓൈਮ
    type Workers = TVar (Map Id (Maybe Worker))
    newtype Id = Id Int32
    deriving newtype (Show, Eq, Ord, Num, Binary, FromJSON, ToJSON, Display)
    type Worker = Record
    ’[ "id" >: Id
    , "working" >: Bool
    , "conn" >: WS.Connection
    ]
    Id ܕͱ Worker ܕ͸ͦΕͧΕɺ Worker ͷ ID ͱ Worker ࣗମΛදͨ͠ܕͰ͢ɻͦΕͧΕͪΐͬ
    ͱ Haskell ͷςΫχΧϧͳܕͷ͘͠ΈΛར༻͍ͯ͠·͕͢ɺͳΜͱͳ͘ಡΊΔ͸ͣͰ͢ͷͰɺ͜͜Ͱ
    ͸ׂѪ͠·͢*6
    ɻαʔόͱ Worker ͸ɺ Worker ͔Βͷ WebSocket ͰίωΫγϣϯΛհͯ͠௨৴Λ
    ͠·͢ɻͦͷίωΫγϣϯΛදͨ͠ܕ͕ WS.Connection Ͱ͢*7
    ɻͦͯ͠ɺMap Id (Maybe Worke
    *4
    ίϩφՒҎ߱ɺࣥච࣌఺·Ͱ͸গͳ͘ͱ΋։࠵͍ͯ͠·ͤΜ͕ɺMIXI ͷ৽ଔݚमͰ࠵͍ͯ͠·ͨ͠ɻ
    *5 https://github.com/matsubara0507/git-plantation
    *6 Id ܕͷํ͸ GeneralizedNewtypeDeriving ͱ͍͏ػೳͰɺWorker ܕ͸ extensible ύοέʔδΛར༻֦ͨ͠ுՄೳ
    ϨίʔυܕͰ͢ɻ
    *7 https://hackage.haskell.org/package/websockets Λ࢖͍ͬͯ·͢ɻ
    16

    View Slide

  24. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    r) ͕ɺαʔόͱ઀ଓ͕Ұ౓Ͱ΋ཱ֬ͨ͠ Worker ͷ৘ใ܈Ͱ͢*8
    ɻ͜ΕΛ TVar Ͱϥοϓ͢Δ͜ͱ
    ͰɺϚϧνεϨουͰ҆શʹڞ༗Ͱ͖ΔϦιʔεͱͳΓ·͢ɻ
    ͜ͷڞ༗ϦιʔεΛૢ࡞͢ΔϝιουΛ͍͔ͭ͘ݟͯΈ·͢ɿ
    src/Git/Plantation/Job/Worker.hs ΑΓൈਮ
    new :: Id -> WS.Connection -> Worker
    new = ...
    connect :: Workers -> WS.Connection -> STM Worker
    connect workers conn = do
    maxId <- Map.size <$> readTVar workers
    let worker = new (fromIntegral $ maxId + 1) conn
    modifyTVar workers (Map.insert (worker ^. #id) $ Just worker)
    pure worker
    disconnect :: Workers -> Id -> STM ()
    disconnect workers wid =
    modifyTVar workers (Map.update (\_ -> Just Nothing) wid)
    connect ؔ਺΋ disconnect ؔ਺΋ STM a ܕΛฦ͍ͯ͠ΔͷͰɺ͜ͷؔ਺୯ମͰ͸࣮ߦ͞Ε·ͤ
    Μɻ͜ͷؔ਺ͷ໭Γ஋Λ atomically ؔ਺ʹ౉͢͜ͱͰෆՄ෼ʹ࣮ߦ͞Ε·͢ɻconnect ؔ਺ͷํ
    ͸ɺId ܕͷ஋Λࡶʹ࡞ΔͨΊʹɺWorkers ͷαΠζΛऔಘ͠ɺͦΕΛ৽͍͠ Worker ܕͷ஋ʹؚΊ
    ͯ Workers ΁ૠೖ͍ͯ͠·͢ɻ͜͜Ͱ STM Λ࢖Θͳ͔ͬͨ৔߹ɺαΠζͷऔಘ͔Βཁૉͷૠೖ·
    Ͱͷؒʹ΄͔ͷεϨουʹΑͬͯཁૉ͕૿͍͑ͯΔͱɺId ͕ॏෳͯ͠͠·͏Մೳੑ͕͋Γ·͢ʢ͜
    ͷ࣮૷ͷ৔߹ɺ্ͨͩॻ͖͞Ε·͢ʣ
    ɻ͔͠͠ɺSTM Ͱϥοϓͯ͋͛͠Δ͚ͩͰɺ೉͍͠ഉଞ੍ޚΛ
    ͢Δ͜ͱͳ҆͘શʹڞ༗ϦιʔεΛ؅ཧͰ͖·͢ɻ
    Agda
    Haskell ͸ϓϩάϥϛϯάݴޠͷ࣮૷Ͱ࢖ΘΕΔ͜ͱ͕͠͹͠͹͋Γ·͢ɻAgda *9
    ͱ͍͏ϓϩά
    ϥϛϯάݴޠ΋ͦͷҰͭͰɺґଘܕͱ͍͏ܕΛ͓࣋ͬͯΓɺͦΕΛར༻ͯ͠ఆཧূ໌ͳͲʹར༻͞Ε
    ·͢ɻ·ͨɺه๏͕ Haskell ʹࣅ͍ͯ·͢ɻ
    ࣥච࣌఺ͷ࠷৽όʔδϣϯͰ͋Δ v2.6.3 ͷ Agda Ͱ͸ɺSTM Λ REPL ͷ࣮૷Ͱ࢖͍ͬͯ·
    ͢*10
    ɻTChan ͱ TVar Λ࢖ͬͯɺREPL ্ͰͷίϚϯυΛඇಉظʹॲཧ͢ΔͨΊͷΩϡʔΛ࣮૷͠
    ͍ͯ·͢ɿ
    *8 Maybe ʹͳ͍ͬͯΔͷ͸ɺId Λ࡞Δͷʹ Map ͷαΠζΛར༻͢Δ͔ΒͰ͢ɻେྔͷ Worker Λ઀ଓ͢ΔΘ͚͡Όͳ
    ͍ͷͰɺ͍ͩͿࡶͳ࣮૷Ͱ͢ɻ
    *9 https://github.com/agda/agda
    *10
    ΑΓਖ਼֬ʹ͸ɺଟ͘ͷݴޠʹ͋ΔΑ͏ͳλʔϛφϧ্Ͱͷର࿩؀ڥͰ͸ͳ͘ɺEmacs ্Ͱͷର࿩؀ڥͰ͢ɻ
    17

    View Slide

  25. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    src/full/Agda/Interaction/Base.hs ΑΓൈਮ
    data CommandQueue = CommandQueue
    { commands :: !(TChan (Integer, Command))
    , abort :: !(TVar (Maybe Integer))
    }
    ! ͷ෦෼͸ɺࠓճ͸ແࢹͯ͠ಡΜͰ΋Βͬͯେৎ෉Ͱ͢ɻAgda Ͱఆٛ͞Ε͍ͯΔ Command ܕʹ
    ͍ͭͯ͸ɺ͜͜Ͱ͸ׂѪ͠·͢ɻREPL Ͱઐ༻ͷίϚϯυΛड͚औͬͯΩϡʔʹૠೖ͠ɺͦΕΛඇಉ
    ظʹॲཧ͢ΔΑ͏ͳײͩ͡ͱࢥ͍ͬͯͩ͘͞ɻίϚϯυͷॲཧ͸ TChan ͷΩϡʔΛհͯ͠ඇಉظʹ
    ॲཧ͞Ε·͕͢ɺ
    ʢ͓ͦΒ͘ʣ͕͔͔࣌ؒΔΑ͏Ͱɺͦͷؒʹڧ੍ऴྃͷίϚϯυʢabortʣΛड͚औ
    ΔͨΊʹผͷ TVar Λ༻ҙ͍ͯ͠ΔΑ͏Ͱ͢ɻ࣮ࡍʹ CommandQueue ܕͷ஋͕࢖ΘΕ͍ͯΔͱ͜Ζ
    ΛݟͯΈ·͢ɿ
    src/full/Agda/Interaction/InteractionTop.hs ΑΓൈਮ
    -- ίϚϯυΛඇಉظʹॲཧ͢ΔผεϨουΛ࡞Δؔ਺
    initialiseCommandQueue :: IO Command -> IO CommandQueue
    initialiseCommandQueue next = do
    commands <- newTChanIO
    abort <- newTVarIO Nothing
    let readCommands n = do
    c <- next -- ίϚϯυΛͳΜ͔͠Βͷ֎෦ೖྗΑΓಡΈࠐΉ
    case c of
    Command c | IOTCM _ _ _ Cmd_abort <- c Nothing -> do
    atomically $ writeTVar abort (Just n)
    readCommands n
    _ -> do
    let n’ = (succ n)
    atomically $ writeTChan commands (n’, c)
    case c of
    Done -> return ()
    _ -> readCommands n’
    -- forkIO ͰผεϨουͱͯ͠Ҿ਺ͷ IO ΞΫγϣϯΛ࣮ߦ
    _ <- forkIO (readCommands 0)
    return (CommandQueue { .. })
    case ࣜͷ෼ذͷ͏ͪɺલऀ͸ abort Λड͚औͬͨ৔߹ͳͷͰ CommandQueue ͷ abort ͷํΛߋ
    ৽͠ɺͦΕҎ֎ͷ৔߹͸ίϚϯυΛඇಉظʹॲཧ͢ΔͨΊͷΩϡʔͰ͋Δ commands ΁ૠೖ͍ͯ͠·
    ͢ɻ͜͜Ͱ͓΋͠Ζ͍ͷ͸ abort ͷಡΈऔΓଆͷํͰ͢ɿ
    18

    View Slide

  26. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    src/full/Agda/Interaction/InteractionTop.hs ΑΓൈਮ
    waitForAbort :: Integer -> CommandQueue -> IO Integer
    waitForAbort n q = do
    atomically $ do
    a <- readTVar (abort q)
    case a of
    Just a’ | n <= a’ -> return a’
    _ -> retry
    ৽͘͠ retry ؔ਺͕ग़͖ͯ·ͨ͠ɻ͜Ε΋ STM ͷؔ਺Ͱɺ
    ʮݱࡏͷτϥϯβΫγϣϯΛഁغͯ͠
    ΋͏Ұ౓΍Γ௚͢ʯͱ͍͏ৼΔ෣͍Λ͠·͢ɻͭ·Γɺabort ͷ݁Ռ͕ Just a’ ʹͳΔ·Ͱʢ୭͔
    ͕ abort Λೖྗ͢Δ·Ͱʣ
    ɺӬԕͱ atomically ҎԼͷτϥϯβΫγϣϯΛ܁Γฦ͢Θ͚Ͱ͢ɻ΋ͪ
    ΖΜɺແݶϧʔϓͷΑ͏ʹԿճ΋࣮ߦͯ͠ CPU ϦιʔεΛ৯͍௵͢͜ͱ͸͋Γ·ͤΜɻSTM ͷ࣮
    ૷͸ݡ͘Ͱ͖͍ͯͯɺͳΜ͔͠ΒͷมԽ͕ͳ͍ݶΓτϥϯβΫγϣϯΛ࠶౓࣮ߦ͢Δ͜ͱ͸ͳ͍Α͏
    Ͱ͢ɻͭ·ΓɺreadTVar (abort q) ͷ݁Ռ͕มΘΒͳ͍ݶΓɺ͜ͷεϨου͸ϒϩοΫ͞ΕΔΘ
    ͚Ͱ͢ʢ·͞ʹ waitForAbort Ͱ͢Ͷʣ
    ɻ
    waitForAbort ؔ਺͸͜Μͳײ͡ʹ࢖ΘΕ͍ͯ·͢ɿ
    src/full/Agda/Interaction/InteractionTop.hs ΑΓൈਮ
    -- IO ͳؔ਺ͷத
    -- CommandQueue ܕͷ஋ q ͔Β Command Λ1ͭऔಘ
    (n, cmd) <- atomically $ readTChan (commands q)
    case cmd of
    ...
    Command c -> do
    result <- Async.race (run c) (waitForAbort n q)
    case result of
    Left ... -> ... -- abort ͷ৔߹
    Right ... -> ... -- Command ͕࣮ߦͰ͖ͨ৔߹
    async ύοέʔδͷ race ؔ਺͸ɺ౉ͨ͠ 2 ͭͷ IO ΞΫγϣϯΛผʑͷεϨουͰಉ࣌ʹ࣮ߦ͠
    ͯɺઌʹऴྃͨ͠΋ͷͷ݁ՌΛ Either Ͱฦ͠·͢ɻͭ·ΓɺίϚϯυ͕ऴΘΔલʹ abort ͕ೖྗ
    ͞ΕΔͱɺઌʹ waitForAbort Λ࣮ߦͨ͠εϨου͕ऴྃ͢ΔͨΊ race ؔ਺͕ίϚϯυͷ࣮ߦΛ
    ͱΊΔΘ͚Ͱ͢Ͷɻ
    ༨ஊͰ͕͢ɺretry Λ࢖ͬͨϒϩοΩϯάΛ͢Δํ๏͸ʮHaskell ʹΑΔฒߦɾฒྻϓϩάϥϛϯ
    άʯͰ΋঺հ͞Ε͍ͯΔํ๏Ͱ͢ɻ·ͨɺ͜ͷϒϩοΩϯάͷ͘͠ΈΛར༻ͯ͠νϟϯωϧܥͷσʔ
    λߏ଄͸ɺreadTChan ؔ਺ͳͲͷνϟϯωϧ͔ΒͷσʔλͷಡΈऔΓΛɺσʔλ͕ૠೖ͞ΕΔ·Ͱ
    ଴ػ͍ͯ͠·͢ɻ
    19

    View Slide

  27. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    haskell-language-server
    haskell-language-server *11
    ͸ɺHaskell ެࣜͰϝϯςφϯε͞Ε͍ͯΔɺHaskell ϓϩάϥϛϯ
    άΛࢧԉ͢ΔͨΊͷ Language Server Protocol ४ڌͳπʔϧͰ͢ʢIDEʣ
    ɻhaskell-language-server
    Ͱ͸ STM ΛԿϱॴ͔Ͱ࢖͍ͬͯ·͕͢ɺࠓճ͸ҎԼͷσʔλߏ଄ʹ͍ͭͯ঺հ͠·͢ɿ
    ghcide/src/Development/IDE/Types/Action.hs ΑΓൈਮ
    data ActionQueue = ActionQueue
    { newActions :: TQueue DelayedActionInternal,
    inProgress :: TVar (HashSet DelayedActionInternal)
    }
    DelayedActionInternal ܕ͸ haskell-language-server Ͱఆٛ͞Ε͍ͯΔܕͰɺඇಉظʹॲཧ͠
    ͍ͨͳΜ͔͠ΒͷΞΫγϣϯΛදݱ͍ͯ͠·͢ɻActionQueue ܕ͸໊લ͔Β෼͔ΔΑ͏ʹɺඇಉظ
    ॲཧͷͨΊͷΩϡʔΛදݱͨ͠σʔλߏ଄Ͱ͢ɻnewActions ϑΟʔϧυଆ͕ΩϡʔຊମͰɺinPro
    gress ϑΟʔϧυ͕ඇಉظॲཧதͷΞΠςϜΛೖΕ͓ͯ͘഑ྻͷΑ͏ͳ΋ͷͰ͢ɻΩϡʔ͔ΒΞΠ
    ςϜΛऔΓग़ؔ͢਺ popQueue ΛݟͯΈ·͢ɿ
    ghcide/src/Development/IDE/Types/Action.hs ΑΓൈਮ
    popQueue :: ActionQueue -> STM DelayedActionInternal
    popQueue ActionQueue {..} = do
    x <- readTQueue newActions
    modifyTVar inProgress (Set.insert x)
    return x
    Ωϡʔຊମ͔ΒΞΠςϜΛ 1 ͭऔΓग़ͨ͠ޙɺinProgress ͷํʹૠೖͯ͠ɺऔΓग़ͨ͠ΞΠςϜ
    Λฦ͍ͯ͠·͢ɻ໭Γ஋ͷܕ͕ DelayedActionInternal Ͱ͸ͳͯ͘ STM DelayedActionIntern
    al Ͱ͢ͷͰɺ͜ΕΒͷॲཧ͸ atomically ؔ਺ͳͲΛར༻ͯ͠ෆՄ෼ͳॲཧͱ࣮ͯ͠ߦՄೳͱ͍͏
    Θ͚Ͱ͢ɻ
    Semantic
    Semantic ͸ GitHub ͕։ൃ͍ͯ͠Δɺ͞·͟·ͳϓϩάϥϛϯάݴޠͷղੳΛ͢ΔͨΊͷπʔϧ
    Ͱ͢ʢݱࡏͰ΋࢖͍ͬͯΔ͔͸Θ͔Γ·ͤΜ͕ʣ
    *12
    ɻOSS ͱͯ͠ެ։͞Ε͓ͯΓɺϓϩάϥϛϯάݴ
    ޠͷߏจ໦Λ؆୯ʹѻ͏ͨΊʹ Haskell Λ࢖͍ͬͯΔΑ͏Ͱ͢*13
    ɻ
    *11 https://github.com/haskell/haskell-language-server
    *12 https://github.blog/2020-08-04-codegen-semantics-improved-language-support-system/ Ͱ঺հ͞Ε
    ͍ͯ·͢ɻ
    *13 https://github.com/github/semantic
    20

    View Slide

  28. ୈ 2 ষ ୳๚ STM at Haskell 2.2 STM ͷ࢖ΘΕํ
    Semantic Ͱ͸ stm ύοέʔδͷ୅ΘΓʹ stm-chans ύοέʔδ*14
    Λ࢖͍ͬͯΔΑ͏Ͱ͢ɻstm-
    chans ύοέʔδʹ͸ɺstm ύοέʔδʹ͋Δલड़ͨ͠νϟϯωϧܥͷσʔλߏ଄ʹɺνϟϯωϧͷ
    ΫϩʔζΛ௥Ճͨ͠Α͏ͳσʔλߏ଄Λఏڙ͍ͯ͠·͢ɻSemantic Ͱ͸ TBMQueue Λར༻ͯ͠ඇಉ
    ظॲཧͷΩϡʔΛ࡞͍ͬͯ·͢ɿ
    src/Semantic/Telemetry/AsyncQueue.hs ΑΓൈਮ
    data AsyncQueue a
    = AsyncQueue
    { asyncQueue :: TBMQueue a
    , asyncQueueSink :: Async ()
    }
    asyncQueue ͕ΩϡʔຊମͰɺasyncQueueSink ͸Ωϡʔ͔ΒཁૉΛऔΓग़͠ඇಉظʹॲཧͯ͠
    ͘ΕΔผεϨουΛදͨ͠ϑΟʔϧυͰ͢ɻAsyncQueue ͷॳظԽ࣌ʹ asyncQueueSink Λ࣮ߦ͠
    ͓͖ͯ·͢ɿ
    src/Semantic/Telemetry/AsyncQueue.hs ΑΓൈਮ
    newAsyncQueue :: Int -> (a -> IO ()) -> IO (AsyncQueue a)
    newAsyncQueue i f = do
    q <- newTBMQueueIO i -- i ͸Ωϡʔͷ௕͞
    s <- Async.async (sink q)
    pure (AsyncQueue q s)
    where
    shink q = do
    msg <- atomically (readTBMQueue q)
    maybe (pure ()) go msg
    where
    go msg = f msg >> sink f q
    asyncQueue ͸ɺΩϡʔ͕Ϋϩʔζ͞Εͨ࣌ʹ͸ Nothing Λฦ͢Α͏ʹͳΓ·͢ɻmaybe ͷͱ͜
    ΖͰɺNothing ͕ฦͬͯ͘Δ·Ͱ࠶ؼ͠ͳ͕Βͣͬͱ f Λ࣮ߦ͠ଓ͚͍ͯΔ͜ͱ͕Θ͔Δͱࢥ͍·
    ͢ɻAsyncQueue ΛΫϩʔζ͢Δʹ͸࣍ͷؔ਺Λ࢖͍·͢ɿ
    src/Semantic/Telemetry/AsyncQueue.hs ΑΓൈਮ
    closeAsyncQueue :: AsyncQueue a extra -> IO ()
    closeAsyncQueue AsyncQueue{..} = do
    atomically (closeTBMQueue asyncQueue)
    Async.wait asyncQueueSink
    *14 https://hackage.haskell.org/package/stm-chans
    21

    View Slide

  29. ୈ 2 ষ ୳๚ STM at Haskell 2.3 ऴΘΓʹ
    closeTBMQueue ؔ਺ͰΩϡʔຊମΛΫϩʔζ͠ɺasync ύοέʔδͷ wait ؔ਺Λ࢖͏͜ͱͰɺA
    sync ͳΞΫγϣϯ͕ऴྃ͢ΔͷΛ଴ͪ·͢ɻ͜͏͢Δ͜ͱͰɺ࣮ߦதͩͬͨඇಉظॲཧ͕ͪΌΜͱ
    ऴྃ͢Δ·Ͱ଴ͭΑ͏ʹͳ͍ͬͯΔΘ͚Ͱ͢ʢAgda ͷ࣌ͷΑ͏ʹڧ੍ऴྃ͸͠ͳ͍ʣ
    ɻ
    2.3 ऴΘΓʹ
    ଞʹ΋ଟ͘ͷ Haskell ੡ΞϓϦέʔγϣϯͰ STM ͕࢖ΘΕ͍ͯ·͢ɻ͜ΕΒͷ OSS ͷ͓͔͛
    ͰɺSTM Λ࢖͑͹ฒྻɾฒߦϓϩάϥϛϯάͰ؆୯ʹڞ༗ϦιʔεΛ࢖ͬͨॲཧ͕͔͚Δ͜ͱ͕఻
    Θͬͨͱࢥ͍·͢ɻಛʹɺඇಉظॲཧͷΩϡʔΛ࣮૷͢Δͷʹͱͯ΋ศརͦ͏Ͱ͢ΑͶɻ
    22

    View Slide

  30. ୈ 3 ষ
    Web ͷճؼςετͷࣗಈԽ
    Web αʔϏεͷ։ൃʹ͓͍ͯγεςϜ͕ظ଴௨Γʹಈ͔͘Ͳ͏͔ΛνΣοΫ͢ΔͨΊʹɺ͞·͟
    ·ͳςετΛߦ͏৔߹͕͋Γ·͢ɻ
    ςετΛߦ͏͜ͱͰϦϦʔεʹؚ·ΕΔෆ۩߹ΛݮΒ͢͜ͱ͕Ͱ͖·͢ɻΞδϟΠϧ։ൃʹ͓͍ͯ
    ͸ൺֱత୹͍ظؒͷதͰ։ൃͱϦϦʔεΛ܁Γฦ͢ͷͰසൟʹςετΛߦͬͨΓ͠·͢ɻ
    ςετʹ͸ɺ͞·͟·ͳछྨ͕͋Γ·͢ɻ
    • Ϣχοτςετ
    – Ϟδϡʔϧ୯ҐͰظ଴͢ΔڍಈΛ͢Δ͔Ͳ͏͔ΛνΣοΫ͠·͢ɻ
    • ΠϯςάϨʔγϣϯςετ
    – ϞδϡʔϧΛ͍͔ͭ͘૊Έ߹Θͤͯظ଴͢ΔڍಈΛ͢Δ͔Ͳ͏͔ΛνΣοΫ͠·͢ɻ
    – Web Ͱ͸ίϯϙʔωϯτͷςετΛߦ͏ࡍʹɺίϯϙʔωϯτʹ಺แ͞ΕΔϞδϡʔϧ
    ܈͕૊Έ߹Θͬͨ͞ঢ়ଶͰظ଴͢Δಈ࡞Λ͢Δ͔Ͳ͏͔ΛνΣοΫ͠·͢ɻ
    • E2E ςετ
    – ݶΓͳ͘ຊ൪؀ڥʹ͍ۙঢ়ଶͰɺαʔό͔ΒΫϥΠΞϯτ·ͰΛͭͳ͍ͩঢ়ଶͰظ଴͢Δ
    ಈ࡞Λ͢Δ͔Ͳ͏͔ΛνΣοΫ͠·͢ɻ
    – Web Ͱ͸ϒϥ΢β্ͰνΣοΫର৅ͷγεςϜΛ࣮ࡍʹૢ࡞͢Δ͜ͱͰνΣοΫ͠·͢ɻ
    ·ͨɺγεςϜ඼࣭ͷνΣοΫʹ΋ड͚ೖΕςετ΍ճؼςετͳͲ͞·͟·ͳछྨͷςετ͕
    ͋Γ·͢ɻࠓճ͸ൺֱతςετͷن໛΍޻਺͕ංେԽ͕ͪ͠ͳճؼςετͷࣗಈԽʹ͍ͭͯղઆ͠
    ·͢ɻ
    3.1 ճؼςετͱ͸
    ճؼςετͱ͸ɺίʔυΛมߋͨ͜͠ͱͰγεςϜͷ΄͔ͷՕॴͰ༧ظͤ͵ෆ۩߹͕ग़͍ͯͳ͍͔
    ΛνΣοΫ͢ΔςετͰ͢ɻͰ͢ͷͰɺճؼςετͷνΣοΫ࣌ʹ͸γεςϜશମΛର৅ʹҰ௨Γͷ
    ૢ࡞͕Մೳ͔Ͳ͏͔΍ಈ࡞ʹҟৗ͕ͳ͍͔ΛνΣοΫ͠·͢ɻ
    ࣮ࡍʹγεςϜΛૢ࡞ͯ͠νΣοΫ͢ΔͷͰɺϢʔβʔͷؾ࣋ͪʹͳͬͯͦͷγεςϜͷ࢖͍ͮΒ
    ͞ʹؾ෇͖͔͚ͬ͘ʹ΋ͳΓ·͢ɻ
    23

    View Slide

  31. ୈ 3 ষ Web ͷճؼςετͷࣗಈԽ 3.2 ՝୊
    ͨͩɺ࣮ࡍʹճؼςετΛ։ൃϑϩʔͷதʹಋೖ͍ͯ͘͠ͱൃੜ͢Δ՝୊΋͋Γ·͢ɻ
    3.2 ՝୊
    ճؼςετ͸γεςϜશମͷཁ݅ʹԊͬͯςετέʔε͕࡞ΒΕ͍͖ͯ·͢ɻͰ͢ͷͰɺ։ൃΛਐ
    Ίͯػೳ͕૿͍͚͑ͯ͹૿͑Δ΄Ͳςετ߲໨͕૿͍͖͑ͯ·͢ɻ
    ໢ཏ཰ 100% Λ໨ࢦͤ͹໨ࢦ͢΄Ͳςετ߲໨͸૿͍͖͑ͯςετͷίετ͸ରԠ͖͠Εͳ͍΄Ͳ
    ංେԽͯ͠͠·͏ͷͰɺςετ߲໨ʹ༏ઌ౓Λ͚ͭΔ͜ͱͰγεςϜ্ॏཁͳՕॴΛް͘ςετ͢
    Δɺͱ͍͏Α͏ͳํ๏΋͋Γ·͕͢ɺςετͷίετ૿େͦͷ΋ͷͷղܾࡦʹ͸ͳΓ·ͤΜɻ
    ςετͷίετ͕૿͑ͯճؼνΣοΫʹ͔͔Δ͕࣌ؒ૿͑ΔͱͦͷͿΜϦϦʔε͕஗͘ͳͬͯ͠·
    ͏Մೳੑ͕͋Γ·͢ɻ
    ࠓճ͸͜ͷςετ߲໨͕૿͑Δ͜ͱʹΑΔςετͷίετ૿େͷ՝୊ղܾΛࢼΈ·͢ɻ
    3.3 Ξϓϩʔν
    E2E ςετπʔϧΛಋೖ͢Δ͜ͱͰճؼςετͷࣗಈԽΛ࣮ݱͰ͖·͢ɻ
    E2E ςετπʔϧʹ͸ίʔυϕʔεͰςετ͢Δ΋ͷ΍ɺϊʔίʔυͰςετ͢Δ΋ͷͳͲ͕͋
    Γ·͢ɻ
    • Playwright
    – JavaScriptʢTypeScriptʣ
    Λ࢖ͬͨίʔυϕʔεͰςετΛߦ͏ E2E ςετπʔϧͰ͢ɻ
    • MagicPod
    – GUI ্ͰςετέʔεΛ૊ΈɺϊʔίʔυͰςετΛߦ͏ E2E ςετπʔϧͰ͢ɻ
    ্هͷΑ͏ͳ E2E ςετπʔϧʹΑͬͯɺਓྗͰߦ͍ͬͯͨճؼςετͷςετ߲໨ΛࣗಈԽ͢
    Δʹ͸ɺςετ߲໨ͷఆٛΛػց͕ղऍՄೳͳঢ়ଶʹ͢Δඞཁ͕͋Γ·͢ɻ
    ͨͱ͑͹ʮϔομʹ͋Δτοϓϖʔδ΁ͷϦϯΫΛΫϦοΫͨ͠Βҧ࿨ײͳ͘τοϓϖʔδʹભҠ
    ͞ΕΔʯͱ͍͏Α͏ͳςετέʔε͕͋ͬͨͱͯ͠ɺ͜ΕΛػց͕ղऍՄೳͳఆٛʹม׵͢Δͱ͢Ε
    ͹ɺ
    ʮDesktop Chrome ͱ iPhone14 ͷ Webkit ͷϒϥ΢β؀ڥʹ͓͍ͯɺϔομʹ͋Δτοϓϖʔ
    δͷϦϯΫΛΫϦοΫͨ͠ΒɺΤϥʔ͕ൃੜͤͣ URL ͕ /(τοϓ) ʹભҠ͞ΕΔʯͷΑ͏ʹͳΔͰ
    ͠ΐ͏ɻ
    ͦͷςετ͕ͲͷΑ͏ͳ؀ڥͰ࣮ߦ͞ΕΔ͔ʁ ૝ఆ͞ΕΔ݁Ռͷ৚݅ͷఆٛ͸Կ͔ʁ ҧ࿨ײͷఆ
    ٛ͸Կ͔ʁ ͱ͍ͬͨΑ͏ͳ҉໧తʹ૝ఆ͞ΕΔ৚݅Λ໌จԽ͢Δ͜ͱ͕ɺࣗಈԽ΁ͷҠߦʹ͸ඞཁ
    Ͱ͢ɻ΋͠ɺςετέʔεʹ͓͚Δʮҧ࿨ײͷͳ͞ʯ͕ʮભҠઌͷϖʔδͷද่͕ࣔΕ͍ͯͳ͍ʯͱ
    ͍͏Α͏ͳҙຯ΋ؚΉͷͰ͋Ε͹ςετέʔεΛ෼ղ͢Δ͜ͱ΋ඞཁ͔΋͠Ε·ͤΜɻ
    ͨͩɺςετͷ݁ՌʮγεςϜ͕࢖͍ͮΒ͘ͳͬͯ͠·͍ͬͯΔʯͱ͍͏Α͏ͳ௚ײΛཁ͢Δ΋ͷ
    ʹ͍ͭͯ͸ࣗಈԽ͢Δ͜ͱ͕೉͍͠৔߹͕͋ΔͷͰɺແཧ΍ΓࣗಈԽ͢ΔΑΓ΋ਓ͕ؒςετΛߦ͏
    ํ͕๬·͍͠৔߹΋͋Γ·͢ɻ
    ͜͏͍ͬͨςετέʔεΛͲͷΑ͏ʹࣗಈԽ͢Δ͔ʁ ࣗಈԽͨ݁͠ՌͲͷΑ͏ͳςετέʔεʹ
    24

    View Slide

  32. ୈ 3 ষ Web ͷճؼςετͷࣗಈԽ 3.4 ࣮ફ
    ͳΔ͔ʁ ͱ͍͏΋ͷ͸νΣοΫ୲౰ͷਓͱ࣮૷ऀ͕Ұॹʹௐ੔͍ͯ͘͜͠ͱͰɺͲͷΑ͏ͳڍಈ͕
    ୲อ͞Ε͍ͯΔͷ͔ͷڞ௨ೝࣝΛ࡞Γɺճؼςετͷݱ࣮ղΛಋ͘͜ͱ͕Ͱ͖ΔͰ͠ΐ͏ɻ
    3.4 ࣮ફ
    ࣮ࡍʹ E2E ςετπʔϧΛ࢖ͬͨςετέʔεͷ࡞੒Λͯ͠Έ·͢ɻ
    ࠓճ͸ Playwright Λ࢖༻ͯ͠Έ·͢ɻ
    Լه͸ෳ਺ϒϥ΢βʹΑΔςετέʔεͷ࣮ߦͷྫͰ͢ɻ
    Ϧετ 3.1: sample.spec.ts
    1: import { devices, expect, test } from "@playwright/test";
    2:
    3: // ςετΛߦ͏σόΠεͷҰཡ
    4: const EMULATE_DEVICES = [devices["iPhone 13"], devices["Desktop Chrome"]];
    5:
    6: test.use({
    7: ...EMULATE_DEVICES,
    8: locale: "ja-JP",
    9: });
    10:
    11: test("φϏήʔγϣϯ্ͷϦϯΫ͔ΒμογϡϘʔυ΁ભҠ", async ({ page }) => {
    12: await page.goto("https://github.com/microsoft/playwright");
    13:
    14: // φϏήʔγϣϯ͕഑ஔ͞Ε͍ͯΔμΠΞϩάΛ։͘
    15: await page.locator(’[aria-label="Open side panel"]’).click();
    16:
    17: // ϦϯΫͷ৔ॴΛಛఆͯ͠ԡԼ
    18: const siteNavigateArea = page.locator(’[aria-label="Site navigation"]’);
    19: await siteNavigateArea.getByText("Home").click();
    20:
    21: // ૝ఆ͞ΕͨϖʔδϦϯΫʹભҠ͔ͨ͠Ͳ͏͔ΛνΣοΫ
    22: expect(page).toHaveURL("https://github.com/dashboard");
    23: });
    ·ͨɺϩάΠϯঢ়ଶΛ E2E ςετͰ੍ޚ͢Δʹ͸ԼهͷΑ͏ʹ࣮ݱ͠·͢ɻ
    Ϧετ 3.2: auth.setup.ts
    1: import { test as setup } from "@playwright/test";
    2:
    3: export const USER_A_AUTH_FILE = "playwright/.auth/user1.json";
    4: export const USER_B_AUTH_FILE = "playwright/.auth/user2.json";
    5:
    6: setup("userA ೝূ", async ({ page }) => {
    7: const USER_NAME = /** Ϣʔβʔ໊ */;
    8: const PASSWORD = /** ύεϫʔυ */;
    9:
    25

    View Slide

  33. ୈ 3 ষ Web ͷճؼςετͷࣗಈԽ 3.4 ࣮ફ
    10: await page.goto("https://github.com/login");
    11: await page.getByLabel("Username or email address").fill(USER_NAME);
    12: await page.getByLabel("Password").fill(PASSWORD);
    13: await page.getByRole("button", { name: "Sign in" }).click();
    14:
    15: await page.waitForURL("https://github.com/");
    16:
    17: expect(
    18: page.getByRole("button", { name: "View profile and more" })
    19: ).toBeVisible();
    20:
    21: await page.context().storageState({ path: USER_A_AUTH_FILE });
    22: });
    23:
    24: setup("userB ೝূ", async ({ page }) => {
    25: const USER_NAME = /** Ϣʔβʔ໊ */;
    26: const PASSWORD = /** ύεϫʔυ */;
    27:
    28: await page.goto("https://github.com/login");
    29: await page.getByLabel("Username or email address").fill(USER_NAME);
    30: await page.getByLabel("Password").fill(PASSWORD);
    31: await page.getByRole("button", { name: "Sign in" }).click();
    32:
    33: await page.waitForURL("https://github.com/");
    34:
    35: expect(
    36: page.getByRole("button", { name: "View profile and more" })
    37: ).toBeVisible();
    38:
    39: await page.context().storageState({ path: USER_B_AUTH_FILE });
    40: });
    ϑΥϩʔɾඃϑΥϩʔͳͲͷෳ਺ΞΧ΢ϯτΛ࢖༻ͨ͠ςετʹ΋ରԠͰ͖ΔΑ͏ʹෳ਺Ϣʔβʔ
    Ͱͷೝূ৘ใΛอ࣋Ͱ͖·͢ɻ
    ԼهͷΑ͏ͳઃఆϑΝΠϧΛ഑ஔ͢Δ͜ͱͰɺςετͷલʹೝূ৘ใͷऔಘΛߦ͏Α͏ʹͳΓ
    ·͢ɻ
    Ϧετ 3.3: playwright.config.ts
    1: import { defineConfig } from "@playwright/test";
    2:
    3: const config = defineConfig({
    4: projects: [
    5: // Setup project
    6: { name: "setup", testMatch: /.*\.setup\.ts/ },
    7: ],
    8: });
    9:
    10: export default config;
    26

    View Slide

  34. ୈ 3 ষ Web ͷճؼςετͷࣗಈԽ 3.5 ͍͞͝ʹ
    ͜ͷ E2E ςετΛɺճؼςετ࣌ʹ୭Ͱ΋࣮ߦͰ͖ΔΑ͏ʹ GitHub Actions ͷ workflow
    dispatch Λ࢖༻ͯ͠खಈ࣮ߦͰ͖ΔΑ͏ʹͯ͠ΈΔͳͲ΋ྑ͍Ͱ͠ΐ͏ɻ
    ͜͏͍ͬͨ E2E ςετ͸ɺ։ൃΛਐΊΔ͝ͱʹͲΜͲΜϓϩάϥϜͷมߋ͕ೖΓɺؾ෇͍ͨͱ͖
    ʹ͸ E2E ςετ͕࣮ߦͰ͖ͳ͘ͳ͍ͬͯͨɺͱ͍͏Α͏ͳέʔε͕ԟʑʹͯ͋͠Γ·͢ɻͦͷͨ
    Ίɺఆظతʹ E2E ςετΛ࣮ߦͯ͠ςετͷࣦഊʹૣ͘ؾ෇͘͜ͱ͕ॏཁͰ͢ɻͦ͜ͰɺGitHub
    Actions ʹΑΔ E2E ςετͷఆظ࣮ߦΛಋೖ͢ΔͳͲͷํ๏͕͋Γ·͢ɻ
    3.5 ͍͞͝ʹ
    ͜ͷΑ͏ʹ Playwright Λ࢖༻͢Δ͜ͱͰ Web ͷճؼςετΛࣗಈԽͰ͖·͢ɻ
    ·ͨ 100% ׬શʹࣗಈԽ͢ΔΑΓɺͲͷΑ͏ͳςετͳΒࣗಈԽՄೳ͔ʁ ͜ͷςετ͸ਓؒͷ
    νΣοΫʹΑͬͯ୲อ͢Δ΂͖͔ʁ ͱ͍͏൑அΛճؼςετέʔεͷઃܭ͝ͱʹඞཁʹͳΔͰ͠ΐ
    ͏ɻͦͷͨΊɺγεςϜઃܭ࣌ͳͲɺͲͷΑ͏ͳ࣮૷ʹ͍͔ͯ͘͠Λ͢Γ߹ΘͤͨΓڞ༗͢Δ৔͕͋
    Ε͹ͦ͏͍ͬͨ৔Ͱςετઃܭ΋ҰॹʹߦͬͯΈ·͠ΐ͏ɻ
    27

    View Slide

  35. View Slide

  36. ୈ 4 ষ
    micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ
    4.1 ຊষʹ͍ͭͯ
    micro:bit ͱ͍͏ڭҭ༻ϚΠίϯϘʔυ͕͋Γɺֶߍڭҭʹܞ͍ͬͯΔιϑτ΢ΣΞΤϯδχΞͷ
    ਎ͱͯͦ͠Ε͕ͲΜͳ΋ͷ͔࣮ࡍʹ࢖ͬͯΈΔମݧهͷΑ͏ͳষͰ͢ɻઌߦςετࣄྫͳͲ͸ωοτ
    ʹͪΒ΄Βͱ͢Ͱʹ͋Δ΋ͷͰ͕͢ɺ࣮ࡍʹࣗ෼͕৮ͬͯಘΒΕΔ͜ͱ͸͖ͬͱଟ͋͘Δͱࢥ͍ࠓճ
    ΍ͬͱखΛ৳͹͠·͕ͨ͠ɺࢥ͍ͬͯͨΑΓ΋༗ೳͰͨ͠ͷͰڞ༗͍ͨ͠ͱࢥ͍·͢ɻ
    ຊষ͸ɺެࣜஂମ͕ఏڙ͍ͯ͠ΔΤσΟλͰ͋Δ Python editor *1
    Λ࢖ͬͯɺMacBook Pro ͱ
    USB ઀ଓ͢Δݕূ΍ιʔείʔυΛܝࡌ͠·͢ɻMicrosoft ࣾͷ MakeCode ΤσΟλͰͷ Python
    ΍ɺMu ΤσΟλͰͷ Python ͸ͦΕͧΕʹޓ׵ੑ͕͋Γ·ͤΜͷͰ͝஫ҙ͍ͩ͘͞ɻ
    *1 micro:bit ެࣜஂମͷ Python editor : https://python.microbit.org/
    29

    View Slide

  37. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.1 ຊষʹ͍ͭͯ
    ͓खܰͰ͓΋͠Ζ͍σόΠε
    ࠓճ࣮ࡍʹௐ΂ͳ͕Βςετͯ͠෼͔ͬͨ͜ͱΛ݁࿦͔Βݴ͏ͱɺ͜Ε͸= 3,000 ΄Ͳͷຊମ 1 ͭ
    ͚ͩͰͱͯ΋औΓ૊Έ͕͍ͷ͋Δڵຯਂ͍σόΠεͰ͢ɻ༡ͼͱֶͯ͠शͱͯ͠ɺ͋Δ͍͸ϥΠϑ
    ϋοΫͳͲɺ͏·͘΍Ε͹׆࿏͕͋Δϙςϯγϟϧ͕ײ͡ΒΕͯඇৗʹ͓΋͠Ζ͍σόΠεͰ͢ɻ
    ͦΕ͔Βɺιϑτ΢ΣΞ։ൃओମͰ͋ͬͨࢲʹͱͬͯϚΠίϯϘʔυ͸ීஈར༻͖ͯ͠·ͤΜͰ͠
    ͕ͨɺݱ࣮ͷσόΠεͱιϑτ΢ΣΞ͕࿈ಈ͢Δ͜ͱͰਓͱιϑτ΢ΣΞ͕ͭͳ͕Δ͜ͱ͸ඇৗʹ༗
    ҙٛͰ͢ɻ͞ΒʹՃ଎౓ηϯαɺ஍࣓ؾηϯαɺγϦΞϧϙʔτ઀ଓͳͲɺσόΠε੍ޚͷ؍఺͔Β
    ΋ଟ͘ͷऔΓ૊Έ୊ࡐ͕͋ΔͨΊɺࢠͲ΋ͷֶशڭࡐͱ͚ͯͩ͠Ͱ͸ͦͷද໘ͷҰ෦෼͔͠࢖͍ͬͯ
    ͳ͍ͱ͍͏ঢ়گͰ͋Δ͜ͱ͕෼͔Γ·ͨ͠ɻಉ༷ͷϚΠίϯϘʔυͰ͸ Raspberry Pi ͳͲ΋ڍ͛Β
    ΕΔͱࢥ͍·͕͢ɺຊػ͸Ձ֨= 3,000 લޙͳ͜ͱͱ͓खܰͰͱ͖ͬͭ΍͍͢͜ͱɺΉ͖ग़͠Ͱར༻
    Ͱ͖Δ͜ͱͳͲɺඞཁͳΒେྔߪೖͯ͠Կ͔Ͱ͖Δ͔΋͠Εͳ͍ՄೳੑΛײ͡·͢ɻ
    ࠓճ͢΂ͯ͸ਂ͘৮ΕΔ͜ͱ͕Ͱ͖·ͤΜͰ͕ͨ͠ɺͦͷਂΈͱՄೳੑ͕ײ͡ΒΕͨ͜ͱΛத৺ʹ
    ίʔυྫͱͱ΋ʹ঺հ͍͖ͯ͠·͢ɻ

    චऀϓϩϑΟʔϧ
    ήʔϜΛத৺ͱͨ͠ιϑτ΢ΣΞΤϯδχΞͱͯ͠׆ಈ͓ͯ͠ΓɺίϯγϡʔϚήʔϜ΍ϒϥ΢
    βήʔϜͱεϚʔτϑΥϯΞϓϦͷ։ൃɺWeb αʔϏε΍ήʔϜاըʹ΋ܞΘΔɻۙ೥͸ڭҭ
    ݱ৔ʹ޲͚ͯɺ
    ʮϓϩάϥϛϯάֶशʯΛਪਐ͢Δߨࢣͱͯͦ͠ͷֶशιϑτ΢ΣΞ΍ΧϦΩϡ
    ϥϜ։ൃͱซͤͯऔΓ૊ΜͰ͍Δɻ
    LinkedIn: https://www.linkedin.com/in/akira-tanabe/

    ໨࣍
    • micro:bitʢϚΠΫϩϏοτʣͱ͸
    • ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ
    • Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    • ϚΠίϯνοϓ୯ಠϛχήʔϜ੍࡞
    • ऴΘΓʹ
    30

    View Slide

  38. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.1 ຊষʹ͍ͭͯ
    micro:bitʢϚΠΫϩϏοτʣͱ͸
    micro:bitʢBBC micro:bitʣͱ͍͏ϓϩάϥϛϯάֶश޲͚खͷͻΒαΠζͷϚΠίϯϘʔυڭࡐ
    ͕ӳࠃ์ૹڠձ BBC ʹΑͬͯઃܭ͞Εɺݱࡏ͸શੈքͰ׆༻͞Ε͍ͯ·͢ɻόʔδϣϯ 1ʢV1ʣ͸
    2017 ೥͔Βఏڙ͞Εɺ2020 ೥ 10 ݄ʹ V2 ʹΞοϓσʔτ͞Εɺηϯαྨͱ API ͕௥Ճ͞Ε͍ͯ
    ·͢ɻ
    ಺ଂηϯαʹ͸
    • Ճ଎౓ηϯα
    • ஍࣓ؾηϯα
    • Թ౓ηϯα
    • ؀ڥޫηϯα
    ΠϯλϑΣʔεʹ͸
    • ϚΠΫϩ USB
    • ϚΠΫ
    • εϐʔΧʔ
    • A / B Ϙλϯ
    • ೖग़ྗ୺ࢠ 0/1/2/3V/GND ʜϫχΫϦοϓͱͷ઀ଓ༻
    • Bluetooth
    • ຊମ LOGO λονʢV2ʣ
    ͕උΘ͍ͬͯ·͢ɻ
    ։ൃ؀ڥ͸ɺMicrosoft ࣾͷ MakeCode ΤσΟλͰͷϒϩοΫϓϩάϥϛϯάɾJavaScript ɾ
    Python ͕ɺެࣜஂମ͔Β͸ Python editorʢ˒ࠓճར༻͢Δʣ
    ɺApple ͔Β Swift Playgrounds Ξϓ
    ϦͳͲ͕ఏڙ͞Ε͍ͯ·͢ɻ
    31

    View Slide

  39. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.2 ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ
    ը૾͸ micro:bit ެࣜ Web αΠτ *2
    ͱ Python editorɻ
    ͦͷ΄͔पลػثͱͯ͠ਓܕϩϘοτᝑମ΍ϥδίϯΧʔɺύουೖྗج൫ͳͲͷػث͕֤͔ࣾΒ
    ൢച͞Ε͍ͯ·͢ɻ೔ຊͷֶߍڭҭݱ৔Ͱൺֱతଟ͘໨ʹ͢Δ΋ͷ͸ϩϘοτΧʔͷλΠϓͰɺԿ
    Β͔ͷηϯαʹΑͬͯंΛ૸ΒͤΔϓϩάϥϛϯάΛ MakeCodeʢScratch ෩ϒϩοΫϓϩάϥϛϯ
    άʣͰखॱʹԊ࣮ͬͯફ͢Δͱ͍͏΋ͷʹऔΓ૊ΜͰ͍Δ͜ͱ͕͋Γ·͢ɻ
    ֶߍڭҭݱ৔ʹͱͬͯ͜ͷखͷֶशڭࡐ͸Ωοτʹͳ͍ͬͯΔ΋ͷΛߪೖͯ͠ॱΛ௥࣮ͬͯફ͢Δ
    ͔͠ͳ͘ɺઐ໳ՈͰͳ͚Ε͹௨ৗऔΓ૊ΈͮΒ͍΋ͷͰ͢ɻmicro:bit ͸ࠃ಺Ͱॳ୅όʔδϣϯ͕ެ
    ։͞Ε͔ͯΒ 5 ೥ఔ౓ܦա͍ͯ͠Δ͜ͱ΋͋Γɺωοτ্Ͱར༻ํ๏Λௐ΂Δͱ͍͔ͭ͘ίʔυαϯ
    ϓϧͳͲΛ໨ʹ͠·͢ɻֶश༻్ͱֶͯ͠ߍͰͷ׆༻ͱͯ͠΋ར༻Ҋ͕঺հ͞Ε͍ͯΔ͜ͱ͕͋Γ·
    ͕͢ɺ૊Έࠐ·Ε͍ͯΔ͜ͱ͕Ͱ͖Δ͔Λࢼ͢ઌͷൃలతͳల։͸গͳ͍Α͏ʹײ͡ΒΕ·͢ɻ·ͨ
    ೔ຊͷ৔߹ɺൺֱత໨ʹ͢Δࣄྫ͸पลػثͱ߹Θͤͯൢചఏڙ͞Ε͍ͯͯڭࢣ͕ར༻͠΍͍͢ύο
    έʔδ඼Λߪೖͯ͠ར༻͍ͯ͠Δ͜ͱ͕͋Γɺຊମ 1 ͭΛϋοΫͯ͠׆༻͍ͯ͘͠܏޲ʹ͸ͳ͍Α͏
    Ͱ͢ɻ
    ຊষͷ࣮ફʹ޲͚ͯ
    ຊମ 1 ͭ͋Ε͹͖ͬͱ͓΋͠Ζ͍͜ͱ͸Ͱ͖Δͱ͍͏Πϝʔδ͕͋Δ͜ͱͱɺಘҙͱ͢ΔήʔϜͷ
    ؍఺ͰԿ͔ੜ͔ͤΔΑ͏ͳയવͱͨ͠ՄೳੑΛײͨͨ͡ΊʹऔΓ૊ΈΛ࢝Ί·ͨ͠ɻ࣍ͷઅ͔Β͸͍
    ͔ͭ͘ͷΞΠσΞ੾ΓޱͰࢼͯ͠Έͭͭɺࢲ͕ײ͓ͨ͡΋͠ΖΈ΍Մೳੑ͕͜͜Ͱڞ༗Ͱ͖ͨΒ͏Ε
    ͘͠ࢥ͍·͢ɻ
    4.2 ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ
    *2 https://microbit.org/code/
    32

    View Slide

  40. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.2 ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ
    εϐʔΧʔ͕಺ଂ͞Ε͍ͯͯ Beep Ի͕ൃৼͰ͖Δ͜ͱ͕هࡌ͞Ε͍ͯͨͷͰप೾਺ΛׂΓग़ͯ͠
    ԻఔΛͱͬͯϝϩσΟʔʹ͠Α͏ͱߟ͑ͯ࡞੒ͨ͠ͷ͕͜ͷઅͰ͢ɻ݁࿦͔Βݴ͏ͱ music ͱ͍͏
    module ͕͋ͬͨʢͳΜͱʣͷͰ΋ͬͱ؆୯ʹ໐ΒͤΔ͜ͱ͕Ͱ͖·ͨ͠ɻ͜͜Ͱ͸ൃԻͱԻ֊ʹର
    ͢Δཧղͱ࣮ફͱ͍͏໨తʹ͠·͢ɻ
    Ի֊
    Իͷݪཧ͸ɺৼಈͷप೾਺ʢ଎͞ʣ͕Իఔʹɺৼಈͷڧ͕͞ԻྔʹͳΓ·͢ɻυϨϛ͸Ͳ͜ͷप೾
    ਺Ͱ͠ΐ͏ɻυϨϛϑΝιϥγυ͸ӳޠදهͰɹ C C# D D# E F F# G G# A A# B ɹͱ 12 Ի
    Ͱ 1 αΠΫϧΛΦΫλʔϒɻϐΞϊԻҬͰߟ͑Δͱɺ1 ΦΫλʔϒͷपظͰ A0ʢϥʣ͔Β C8ʢυʣ
    ͘Β͍·Ͱ͋Γ·͢ɻΦΫλʔϒͱΦΫλʔϒ͸प೾਺͕ 1/2 ഒ·ͨ͸ 2 ഒͱɺͪΐ͏Ͳ 1:2 ͷൺ཰
    ͰഒʹͳΔؔ܎ɻ1 ΦΫλʔϒͷؒΛۉ౳ʹ 12 ͰׂͬͯԻ֊ΛׂΓৼͬͨͷ͕ฏۉ཯ͱ͍͏νϡʔ
    χϯάํ๏ͰҰൠతʹ༻͍ΒΕΔํ๏Ͱ͢ɻͲͷप೾਺Λج४ʹઃఆ͢Δ͔Λʮඪ४Իʯͱݴͬͯɺ
    ࠃࡍࣜදهͰ A4 Λ 440Hz ʹઃఆ͢Δͷ͕࠷΋ϙϐϡϥʔͰ͕͢ίϯαʔτϗʔϧͳͲͰ͸ 442Hz
    ʹͳ͍ͬͯΔΑ͏Ͱ͢ɻ
    ܭࢉࣜ͸ Python Ͱදه͢Δͱ f(Hz)=440 * 2 ** n / 12 ͱͳΓ·͢ɻ440 Λഒഒʹ͍ͯ͘͠
    ͔ɺn Λ +-12 ͢ΔͱԻҬ্͕͛Լ͛͞Ε·͢ɻ
    pin_speaker.set_analog_period_microseconds
    micro:bit ͷεϐʔΧʔ͸ PWM ৴߸ͱ͍͏ৼ෯ͷपظʢmsʣΛࢦఆ͢ΔͨΊɺϒϒϒϒͱ Beep
    ԻΛͲͷ࣌ؒ։͚Δ͔Λࢦఆ͠·͢ɻԻ֊प೾਺ Hz ͷͭ΋ΓͰ 440,880 ͷΑ͏ͳ 2 ͭͷ৘ใΛ༩͑
    Δͱ 2 ͭ໨͕ߴ͍ԻʹͳΒͣϒϒϒͷαΠΫϧ͕஗͘ͳΓԻ͕Լ͕Γ·͢ɻ͜͜Ͱ͸ f(Hz)=440 *
    2 ** (12-n) / 12 ɹͱ 12 Իʹରͯ͠ٯʹ͢Δ͜ͱͰԻ֊ʹͰ͖·ͨ͠ɻ
    ࣮ݱ͍ͨ͠Ի֊Λӳޠදه c,d,e,f,g,a,b Ͱ͔͋ͭ͑ΔΑ͏ఆٛɻ
    Ի֊ɺʴٳූ
    c,d,e,f,g,a,b,v = 0,2,4,5,7,9,11,99 // 99 ٳූ
    ίʔυͷղઆ
    ॾػೳΛ੝ΓࠐΜͰΩϥΩϥޫΔʙͱ໐ΔϓϨΠϠʔ͕ҎԼͷΑ͏ʹͯ͠׬੒͠·ͨ͠ɻ
    • Իʢϊʔτʣ͸ͱΓ͋͑ͣ 2 খઅ
    • set_analog_period_microseconds ɹ͸ ms ࢦఆͳͷͰɹ 1000ʢ=1 ඵʣͰ 1 ഥΛج४ʹ sp
    eed Ͱ࠶ੜ଎౓
    • ϊʔτ௕͕༨നͳͭ͘ͳ͕͍ͬͯΔͱ࣍ͷϊʔτ͕ฉ͑͜ͳ͍ͷͰ 0.9 ࠶ੜɺ0.1 ແԻ
    • button_a Ͱ࠶ੜɺbutton_b Ͱఀࢭ
    33

    View Slide

  41. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.2 ಺ଂ Beep ԻεϐʔΧʔͰϝϩσΟϓϨΠϠʔ
    • write_analog ͰԻྔΛ্͛Լ͛ͯ͠ٳූ
    Ϧετ 4.1: ͖Β͖Β੕ playe@Pythonr
    1: from microbit import *
    2: while True:
    3: if button_a.is_pressed():
    4: pin = pin_speaker
    5: print("pin_speaker")
    6: speed = 1000/4
    7: power = 25
    8: rate = 440*4
    9: stp = 0
    10: c,d,e,f,g,a,b,v = 0,2,4,5,7,9,11,99 // 99 ٳූ
    11: musicstep = [c,c,g,g,a,a,g,v,f,f,e,e,d,d,c,v]
    12: while len(musicstep)>stp:
    13: note = int(2**((12-musicstep[stp]) / 12) * rate)
    14: if musicstep[stp] is not v:
    15: pin.write_analog(power)
    16: pin.set_analog_period_microseconds(note)
    17: print("({}){}".format(stp,note))
    18: sleep(int(speed*0.9))
    19: pin.write_analog(0)
    20: sleep(int(speed*0.1))
    21: stp+=1
    22: if button_b.is_pressed(): break
    23: print("stop")
    24: pin.write_analog(0)
    25:
    ׬੒
    [YouTube] https://youtu.be/qzfX0eibEKQ
    34

    View Slide

  42. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    ͜ͷηϯα͸ 3 ࣠ͷՃ଎౓͕Ճ଎࣌ܭʢaccelerometerʣʹΑͬͯಘΒΕɺͦͷ΄͔౗͍ͯ͠Δ޲
    ͖ͱͯ͠׆༻Ͱ͖·͢ɻ
    ਤͷΑ͏ͳػೳ͔Βɺઐ༻ήʔϜػͱಉ͡Α͏ͳ༡ͼํ͕ఏҊͰ͖ΔՄೳੑ͕͋Γ·͢ɻ͜ͷՃ଎
    ౓ηϯα͕͋Δ͜ͱʹΑͬͯ׆࿏͕֨ஈʹ޿͕Δؾ͕͠·͢ɻ
    Ճ଎౓ͷར༻ʹ͋ͨͬͯ͸ຊػ׬݁Ͱ΋Α͍Ͱ͕͢ɺUnity ͷ 3D ήʔϜͱ࿈ಈͤͯ͞αϯϓϧΛ
    ࣔ͢͜ͱʹ͠·͢ɻࢼ͘͢͠Έ͸ɺຊମ͔ΒҰఆִؒͰ print ʹΑͬͯ৘ใऔಘ͓͖ͤͯ͞ɺ֎෦
    ιϑτ΢ΣΞ͔Β print ৘ใΛऔಘ͢Δ͜ͱʹ͠·͢ɻ
    Unity ଆ͔Β͸औಘͨ͠ςΩετ৘ใΛ Json ύʔεͯ͠ߏ଄ମʹऩΊΔ͜ͱͱ͠·͢ɻ
    ίʔυͷ঺հ
    • accelerometer.get_values ɹ x,y,z ͷՃ଎౓৘ใͰ͢ɻ
    • accelerometer.get_strength ɹ x,y,Z ͢΂ͯͷ࣠ͷ߹ܭͰ͢ɻ
    • ૢ࡞ܥ button3 ͭ͸ Bit ϑϥάͰม਺ p ʹೲΊ͍ͯ·͢ɻ
    • ͦͷ΄͔ʹ΋ accelerometer.current_gesture ɹδΣενϟͱ͍͏ɺγΣΠΫͳͲ໊લΛ࣋ͬ
    ͨಈ͖΋औಘͰ͖·͕ͨ͠࢖͍·ͤΜɻ
    35

    View Slide

  43. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    Ϧετ 4.3: Ճ଎౓ηϯαൃ৴ػ@Pythonʢmicro:bit ଆʣ
    1: from microbit import *
    2: while True:
    3: p = 0
    4: if button_a.is_pressed(): p+=1
    5: if button_b.is_pressed(): p+=2
    6: if pin_logo.is_touched(): p+=4
    7: axisx,axisy,axisz = accelerometer.get_values()
    8: strength = accelerometer.get_strength()
    9: # gesture = accelerometer.current_gesture()
    10: # gest_histry = accelerometer.get_gestures()
    11: print("{},{},{},{},{}"
    12: .format(p, axisx,axisy,axisz, strength ))
    13: sleep(100)
    Mac ͰγϦΞϧ઀ଓʢUSBʣΛ֬ೝ͢Δ
    γϦΞϧ઀ଓ
    % ls /dev/cu.*
    >> ls /dev/cu.usbmodem10000
    ͜ͷ cu. ɹҎ߱ͷ໊લ͕ݱࡏ઀ଓ͍ͯ͠ΔػثͷγϦΞϧ઀ଓ৘ใͳͷͰ߇͓͖͑ͯ·͢ɻ
    C#γϦΞϧ Ports ࢖༻͸ System.IO.Ports.SerialPortɻ
    ʲखॱ 1ʳΧελϜͷ Receiver Ϋϥε͸ SerialPort ΠϯελϯεΛ࡞੒͠ Thread ΞΫγϣϯͰ୺
    ຤ͷ message Λड͚औΓ·͢ɻ
    SerialPortReciever ղઆ
    • SerialPort Λॴఆͷํ๏ͰΠϯελϯεΛ࡞੒͢Δ
    • thread Ͱ࣋ଓతʹ message Λड͚औΓ callback ͢Δ
    36

    View Slide

  44. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    Ϧετ 4.3: Ճ଎౓ηϯαड৴ΞϓϦ@C#ʢUnity ଆʣ
    ɾSerialPortReciever Ϋϥε
    1: using System;
    2: using System.Threading;
    3: using System.IO.Ports;
    4: using UnityEngine;
    5: ///
    6: /// SerialPortΠϯελϯεΛ࡞੒ͯ͠ػثͱ઀ଓ͢Δ
    7: ///
    8: [Serializable]
    9: public class SerialPortReciever
    10: {
    11: [SerializeField] SerialPort _serial;
    12: Thread _thread;
    13: public bool enable;
    14: public string recieve;
    15: public Action onreceiveaction;
    16: ///
    17: /// SerialPortΠϯελϯεͷ࡞੒
    18: ///
    19: ///
    20: public static SerialPortReciever Create(string portName)
    21: {
    22: var r = new SerialPortReciever();
    23: if (r._Create(portName))
    24: {
    25: r._thread = new Thread(r.RecieverAct);
    26: r._thread.Start();
    27: return r;
    28: }
    29: else
    30: {
    31: Debug.LogError("create failure");
    32: return null;
    33: }
    34: }
    35:
    36: bool _Create(string portName)
    37: {
    38: _serial = new SerialPort();
    39: _serial.BaudRate = 115200;
    40: _serial.Parity = Parity.None;
    41: _serial.DataBits = 8;
    42: _serial.StopBits = StopBits.One;
    43: _serial.Handshake= Handshake.None;
    44: _serial.PortName = portName;
    45: try
    46: {
    47: _serial.Open();
    48: _serial.DtrEnable = true;
    49: _serial.RtsEnable = true;
    50: _serial.DiscardInBuffer();
    51: _serial.ReadTimeout = 5000;
    52: this.enable = true;
    37

    View Slide

  45. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    53: return true;
    54: }
    55: catch (Exception e)
    56: {
    57: Debug.LogError($"failure.. {e}");
    58: _serial.Close();
    59: _serial = null;
    60: return false;
    61: }
    62: }
    63:
    64: void RecieverAct()
    65: {
    66: while (enable)
    67: {
    68: try
    69: {
    70: recieve = _serial?.ReadLine();
    71: onreceiveaction?.Invoke(recieve);
    72: }
    73: catch (Exception e)
    74: {
    75: recieve = e.ToString();
    76: }
    77: }
    78: }
    79:
    80: public void Dispose()
    81: {
    82: enable = false;
    83: _thread?.Abort();
    84: _thread = null;
    85: _serial?.Close();
    86: _serial = null;
    87: }
    88: }
    ʲखॱ 2ʳ࡞੒ͨ͠ SerialPortReciever ʹ֨ೲ͞Εͨ୺຤ͷ message Λࢀরͯ͠ GameObject Λ
    ੍ޚ͢Δ
    Player Ϋϥεͱద౰ͳ ObjectʢࠓճαϯϓϧʹඈߦػΛ࡞੒ʣΛ༻ҙ͠·͢ɻ
    38

    View Slide

  46. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    SerialPortPlayer ղઆ
    • DeviceContext ߏ଄ମ͸ message ͷ json ύʔε data
    • Ճ଎౓ܭ৘ใ͸ϒϨ͕ܹ͍͠ͷͰฏۉԽͤͯ͞ SerialPortPlayer.average ͔Βࢀর
    • σʔλͷసૹϩεස౓͕ߴ͍ͷͰड৴σʔλͷਪଌɾॳظ஋Λ getintvalue Ͱ༩͑Δ
    • Ճ଎౓ܭ܏͖ͷ͋ͦͼ஋Λ MINB , MINH ʹͯ 0.5 ౓ఔ౓ઃఆ͢Δ
    Ϧετ 4.3: Ճ଎౓ηϯαड৴ΞϓϦ@C#ʢUnity ଆʣ
    ɾSerialPortPlayer Ϋϥε
    1: using System;
    2: using UnityEngine;
    3: using System.Collections.Generic;
    4:
    5: public class SerialPortPlayer : MonoBehaviour
    6: {
    7: [SerializeField] string portname = "/dev/cu.usbmodem000";
    8: [SerializeField] SerialPortReciever receiver;
    9:
    10: void Awake()
    11: {
    12: receiver?.Dispose();
    13: receiver = SerialPortReciever.Create(portname);
    14: receiver.onreceiveaction = onreceive;
    15: }
    39

    View Slide

  47. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    16:
    17: void OnDestroy()
    18: {
    19: receiver?.Dispose();
    20: receiver = null;
    21: }
    22: string getvalue(string m, string ifempty = "0")
    23: => (string.IsNullOrEmpty(m))? ifempty : m;
    24:
    25: int getintvalue(string m, string ifempty = "0")
    26: => int.Parse((string.IsNullOrEmpty(m)) ? ifempty : m);
    27:
    28: void onreceive(string m)
    29: {
    30: if (!string.IsNullOrEmpty(m))
    31: {
    32: var ms = m.Split(",");
    33: if (ms.Length < 5) new Exception();
    34: // jsonԽ
    35: var ex ="{"+ $"\"press\":{getintvalue(ms[0])}," +
    36: $"\"axisx\":{(float)getintvalue(ms[1])}," +
    37: $"\"axisy\":{(float)getintvalue(ms[2])}," +
    38: $"\"axisz\":{(float)getintvalue(ms[3])}," +
    39: $"\"strength\":{getintvalue(ms[4])}" +
    40: "}";
    41: //print(m+"\n"+ex);
    42: try
    43: {
    44: history.Insert(0,JsonUtility.FromJson(ex));
    45: if (history.Count > MAXHISTORY)
    46: history = history.GetRange(0,SAMPLESIZE);
    47: //print(ex+ "\n" + average);
    48: }
    49: catch(Exception e)
    50: {
    51: Debug.Log($"format error ({e})\n{m}");
    52: }
    53: }
    54: }
    55:
    56: public Vector3 average
    57: {
    58: get
    59: {
    60: Vector3 t=Vector3.zero;
    61: for (var i = 0; i < SAMPLESIZE; i++) t += history[i].axis;
    62: var r = new Vector3(t.x/(float)SAMPLESIZE, 0f, t.z/(float)SAMPLESIZE);
    63: return new Vector3(
    64: (MINB > r.x || MINH < r.x)? r.x : 0f,
    65: (MINB > r.y || MINH < r.y)? r.y : 0f,
    66: (MINB > r.z || MINH < r.z)? r.z : 0f
    67: );
    68: }
    69: }
    40

    View Slide

  48. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    70: [Range(0f, 5f)] [SerializeField]float asobi = 0.5f;
    71: float MINB => asobi * -1f;
    72: float MINH => asobi;
    73: [Range(1, 16)]
    74: public int SAMPLESIZE = 3;
    75: const int MAXHISTORY = 1024;
    76: const float MAXVALUE = 1024f;
    77: public List history
    78: = new List() { default, default, default, default };
    79: public DeviceContext deviceinput => history.Count>0? history[0]:default;
    80: public GameObject target;
    81: }
    82: [Serializable]
    83: public struct DeviceContext
    84: {
    85: public PressButton press;
    86: ///
    87: /// Ճ଎౓͸ʶ2000
    88: ///
    89: public int axisx, axisy, axisz;
    90: public int strength;
    91: public string gesture;
    92: public string[] gest_histry;
    93: const float ANGLE = -1f;
    94: const float ANGLEZ = -3f;
    95: ///
    96: /// ӈखܥ࠲ඪ͔Βࠨखܥม׵
    97: ///
    98: public Vector3 axis { get {
    99: return new Vector3(
    100: ((float)axisy/1024f)*ANGLE, 0f, ((float)axisx/1024f)*ANGLEZ
    101: );
    102: }}
    103: public bool isA { get { return press.HasFlag(PressButton.A); } }
    104: public bool isB { get { return press.HasFlag(PressButton.B); } }
    105: public bool isLogo { get { return press.HasFlag(PressButton.LOGO); } }
    106:
    107: public override string ToString()
    108: {
    109: return $"{press} ... A:{isA}, B:{isB}, Logo:{isLogo}, " +
    110: $"axis:{axis}, gesture:{string.Join(",",gest_histry)}";
    111: }
    112: [Flags]
    113: public enum PressButton
    114: {
    115: None = 0,
    116: A = 1<<0,
    117: B = 1<<1,
    118: LOGO = 1<<2
    119: }
    120: }
    41

    View Slide

  49. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    ͦͯ͠ SerialPortPlayer ΫϥεͰड৴ͨ͠ճస৘ใΛ GameObject ʹ༩͑Δ Airplane Ϋϥεɻ
    • b ϘλϯɿՃ଎
    • a Ϙλϯɿݮ଎
    • logo ϘλϯɿϦηοτ
    • ϐονʢඓઌͷ্ঢԼ߱ʣͱϩʔϧʢ͉࣠ճసʣʹಠཱͨ͠ speed ઃఆ
    Ϧετ 4.3: Ճ଎౓ηϯαड৴ΞϓϦ@C#ʢUnity ଆʣ
    ɾAirplane Ϋϥε
    1: using System.Collections;
    2: using System.Collections.Generic;
    42

    View Slide

  50. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    3: using UnityEngine;
    4: using System;
    5: using static UnityEngine.GraphicsBuffer;
    6:
    7: public class Airplane : MonoBehaviour
    8: {
    9: [Range(1f, 1000f)] public float speed = 500f;
    10: [Range(1f, 10f)] public float boostspeed = 5.0f;
    11: [Range(-10f, 0f)] public float breakingspeed = -10f;
    12: [Range(1f, 180f)] public float rotatespeed = 45f;
    13: [Range(1f, 180f)] public float headupespeed = 66f;
    14: [SerializeField] public Rigidbody rb;
    15: [SerializeField] SerialPortPlayer player;
    16:
    17: [ContextMenu("Reset Rotation")]
    18: void ResetRotation() => this.rb.rotation = Quaternion.identity;
    19: [ContextMenu("Reset Transform")]
    20: void ResetTransform() {
    21: Debug.Log("reset trasf");
    22: rb.position = Vector3.up* 200f;
    23: rb.rotation = Quaternion.identity;
    24: rb.velocity = Vector3.zero;
    25: rb.angularVelocity = Vector3.zero;
    26: }
    27:
    28: // Start is called before the first frame update
    29: void Start()
    30: {
    31: player = GameObject.FindObjectOfType();
    32: rb = gameObject.GetComponent();
    33: }
    34:
    35: // Update is called once per frame
    36: void FixedUpdate()
    37: {
    38: // logo reset
    39: if (player.deviceinput.isLogo)
    40: {
    41: ResetTransform();
    42: return;
    43: }
    44: // A button ϒϨʔΩ, B button accel
    45: float boost = player.deviceinput.isB && !player.deviceinput.isA ?
    46: boostspeed: (player.deviceinput.isA? breakingspeed : 1f);
    47: // rotation
    48: if (player && player.history.Count >= player.SAMPLESIZE)
    49: {
    50: //Debug.Log(player.average);
    51: Quaternion r = rb.rotation;
    52: rb.rotation *= Quaternion.Euler(
    53: 0f,
    54: 0f,
    55: player.average.z * this.rotatespeed * Time.deltaTime
    56: )
    43

    View Slide

  51. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.3 Ճ଎౓ηϯαͰମݧܕήʔϜίϯτϩʔϥ
    57: * Quaternion.Euler(
    58: player.average.x * this.headupespeed * Time.deltaTime,
    59: 0f,
    60: 0f
    61: );
    62: }
    63: // accel
    64: #if true
    65: rb.AddRelativeForce(Vector3.forward * speed * boost, ForceMode.Acceleration);
    66: if (Vector3.Dot(rb.velocity,rb.transform.forward.normalized)<0f)
    67: {
    68: rb.velocity = transform.forward * speed;
    69: }
    70: #endif
    71: }
    72: }
    ࣮ߦ݁Ռ
    [YouTube ᶃճస͚ͩςετ] https://youtu.be/6SklthRLp44
    [YouTube ᶄՃ଎͋Γ׬੒൛] https://youtu.be/tMFQ0KQosSc
    44

    View Slide

  52. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.4 ϚΠίϯνοϓ୯ಠϛχήʔϜ੍࡞
    4.4 ϚΠίϯνοϓ୯ಠϛχήʔϜ੍࡞
    ϓϩάϥϜΛసૹͯ͠ه࿥Ͱ͖Δ͜ͱͱɺઐ༻ి஑ box Ͱڅి͢Ε͹ελϯυΞϩʔϯͷܞଳήʔ
    Ϝػͱͯ͠ػೳ͢Δ༁Ͱ͢ɻهԱ༰ྔ͸ V2 Ͱ Flash ROM 512KB ʗ RAM 128KB ͱ͍͏͜ͱͳ
    ͷͰϓϩάϥϜຊମ͚ͩͰ͋Ε͹͍ͩͿऩ·Δ༰ྔͷΑ͏Ͱ͢ɻ͓ࢼ͠ʹ୯ମͰಈͪ͘ΐͬͱʮ͓΋
    ͠Ζ͍ʯήʔϜΛ࡞ͬͯΈ͍ͨͱࢥ͍·͢ɻ
    ήʔϜΠϝʔδ
    • 5x5dot མͪ΋ͷΞΫγϣϯήʔϜ
    • dot ͕গͳ͍͜ͱ͕ٯʹࣦഊ·Ͱͷ༛༧͕গͳ͓ͯ͘΋͠Ζͦ͏
    • beep Ի͕໐ΔͱҰपճͬͯΫʔϧͳͷͰϓϨΠϑΟʔυόοΫͱͯ͠ੵۃతʹ໐Β͢
    • མԼ଎౓͕೉қ౓ʹͳΓϓϨΠΛ੝Γ্͛Δ
    DROPGAME ࢓༷
    • ԣ dot ҐஔΛϥϯμϜʹબग़͠ 1dot ͷো֐෺Λੜ੒
    • ࠷্෦͔ΒҰఆ࣌ؒͰ 1dot ͣͭམԼʢbeepʣ
    • ߴ͞ 5dot Λ௒͑ͨΒ GameOverʢbeepʣ
    • ࠷Լߦʹ 1dot ͷΛ഑ஔ
    • ຊମϘλϯ a/b ͰࠨӈҠಈ͕ͯ͠Λ৯΂ΒΕͨΒةػΛճආʢbeepʣ
    • 3 ͭ৯΂Δ͝ͱʹ LevelUp ͯ͠མԼ଎౓্͕͕Δ
    ήʔϜʹར༻͢Δ micro:bit ཁૉ
    • button_aʢࠨϘλϯʣ
    • button_bʢӈϘλϯʣ
    • display LED 5 x 5 dot
    45

    View Slide

  53. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.4 ϚΠίϯνοϓ୯ಠϛχήʔϜ੍࡞
    • speaker
    Ϧετ 4.3: ϚΠίϯνοϓ DROPGAME@Python
    1: from microbit import *
    2: import random
    3: MAX = 4
    4: MAXLEVEL = 10
    5: SCOREMAX = 3
    6: x,y=0,0
    7: px,py=int(2/MAX),MAX
    8: x = random.randint(0,MAX)
    9: steprate= [10,5,4,3,2,1,0.75,0.5,0.25,0.1]
    10: level = 0
    11: score = 0
    12: def beep(pt):
    13: pin_speaker.write_analog(10)
    14: pin_speaker.set_analog_period_microseconds(pt)
    15: sleep(100)
    16: pin_speaker.write_analog(0)
    17:
    18: def gameover():
    19: print("game over")
    20: for xx in range(MAX+1):
    21: for yy in range(MAX+1):
    22: display.set_pixel(xx,yy,9)
    23:
    24: while True:
    25: display.clear()
    26: display.set_pixel(x,y,5)
    27: if button_a.is_pressed() or button_b.is_pressed():
    28: px += -1 if button_a.is_pressed() else 1 if button_b.is_pressed() else 0
    29: px = max(0,min(MAX,px))
    30: display.set_pixel(px,py,9)
    31: if px==x and py==y:
    32: print("hit")
    33: score +=1
    34: if score>=SCOREMAX:
    35: level += 1
    36: level = min(MAXLEVEL,level)
    37: score = 0
    38: beep(880)
    39: else:
    40: beep(440)
    41:
    42: y = 0
    43: x = random.randint(0,MAX)
    44: else:
    45: y+=1
    46: if y>MAX:
    47: beep(440*30)
    48: gameover()
    49: break
    46

    View Slide

  54. ୈ 4 ষ micro:bit ͷ͓΋͠Ζ׆༻ߟࠪ 4.5 ऴΘΓʹ
    50: beep(220)
    51: sleep(100*steprate[level])
    ࣮ߦ݁Ռ
    [YouTube] https://youtu.be/fbkDtBVP4Y0
    4.5 ऴΘΓʹ
    ࠓճ͸ USB ઀ଓͰͷݕূͰ͕ͨ͠ɺຊମ੍ޚʹར༻ͨ͠ micro:bit αΠτͷ Python editor 3.0
    ʹ͓͍ͯຊػʹରͯ͠ Bluetooth ͷൃ৴͕Ͱ͖ͳ͍Α͏ͩͬͨͨΊɺ࣌ظΛΈͯɺผͷखஈΛऔΔͳ
    Ͳͯ͠ Bluetooth ෳ਺୆઀ଓͰ΋ͬͱ͓΋͠Ζ͍࣮ݧΛͯ͠ΈΑ͏ͱࢥ͍·͢ɻ
    ࠓճར༻ͨ͠ Python ίʔυͱ Unity ϓϩδΣΫτ͸ҎԼͷ GItHub ʹެ։͍ͯ͠·͢ɻڵຯ͕
    ͋Δํ͸ͥͻ͓ࢼ͍ͩ͘͠͞ɻ
    [GitHub] https://github.com/akira-tanabe/mb_serialport_app_1
    47

    View Slide

  55. View Slide

  56. ୈ 5 ষ
    ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠ
    σΞ
    5.1 ChatGPT ͔Β GPT-4 ͕ϦϦʔε
    2023 ೥ 3 ݄ 15 ೔ɺChatGPT Plus Ϣʔβʔ޲͚ʹɺGPT-4 Ϟσϧ͕ར༻Ͱ͖ΔΑ͏ʹͳΓ·͠
    ͨɻGPT-4 ʹΑΔΞ΢τϓοτʹ౓؊Λൈ͔Εͨࢲ͸ɺຖ೔นଧͪ૬खͱͯ͠࢖͍ͬͯ·͢ɻฐࣾ
    Ͱ͸ QAASAʢQuality Assurance Advanced Support Agencyʣͱ͍͏ɺ෦ॺΛ௒͑ͨ QA Τϯδ
    χΞͲ͏͠ͷ׆ಈ͕͋ΔͷͰ͕͢ɺͦ͜Ͱ ChatGPT ΛͲͷΑ͏ʹ׆༻Ͱ͖Δ͔࿩͠߹͓͏ʂ ͱࢲ
    ͕੠Λ͔͚ɺΞΠσΞΛूΊ·ͨ͠ɻ
    ʢ2023 ೥ 4 ݄ݱࡏɺMIXI ͸ɺٕज़มֵʹΑΔߟ͑΍ൃ૝ͷΞ
    ϯϥʔχϯάʹ޲͚৽͍ٕ͠ज़ʹ׳Ε਌͠ΜͰ΋Β͏͜ͱΛ໨తʹɺ౰ࣾͷਖ਼ࣾһɺܖ໿ࣾһΛର
    ৅ʹ 2023 ೥ 4 ݄͔Β໿ 3 ϲ݄ؒʮChatGPT Plusʯͷֹ݄ར༻ྉΛิॿ͞Ε͍ͯ·͢ʣຊߘͰ͸
    ChatGPT Λ QA ΤϯδχΞ͕࢖͏ͱͨ͠ΒɺͲͷΑ͏ͳ࢖͍ํ͕Ͱ͖ΔͷͩΖ͏͔ʁ ͱ͍͏ٙ໰
    ͔Βੜ·ΕͨΞΠσΞɺͦΕʹ΋ͱ͍ͮͯࢲ͕࣮ફͨ͠ྫΛ঺հக͠·͢ɻ
    ͜ͷΑ͏ͳ࢖͍ํ͕Ͱ͖ͦ͏ʂ
    QAASA ͷ׆ಈͰ͸ҎԼͷΑ͏ͳΞΠσΞ͕ڍ͕͍ͬͯ·ͨ͠ɻ
    • Selenium ΁ͷೖ໳ฤͱͯ͠ɺϒϥ΢βͷ؆୯ͳςετΛॻ͍ͯ΋Β͏
    • ϖΞϫΠζ๏Ͱ࠷খݶͷ૊Έ߹ΘͤͷύλʔϯΛ࡞ͬͯ΋Β͏
    • ςετέʔεΛಡ·ͤͯɺςετ؍఺Λநग़ͯ͠΋Β͍ɺ͞ΒʹϚΠϯυϚοϓͱͯ͠ग़ྗ͠
    ͯ΋Β͏
    ࿩͠߹͍ΛਐΊ͍ͯ͘தͰɺςετϓϩηε͝ͱʹݕ౼ͨ͠ͱ͜ΖΞΠσΞ͕ൃࢄͨ͠ҝɺ߲࣍ʹ
    ͯৄ͘͠঺հக͠·͢ɻ
    49

    View Slide

  57. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.2 ςετϓϩηε͝ͱͷ׆༻ΞΠσΞ
    5.2 ςετϓϩηε͝ͱͷ׆༻ΞΠσΞ
    ςετϓϩηεͷ͏ͪʮςετܭըʯ
    ʮςετ؅ཧʢϞχλϦϯάͱίϯτϩʔϧʣ
    ʯ
    ʮςετ෼ੳʯ
    ʮςετઃܭʯ
    ʮςετ࣮૷ʯ
    ʮςετ࣮ߦʯʹ͍ͭͯ࿩ΛਐΊ·͢ɻ
    ςετܭըͰͷ׆༻
    ςετܭըͰ͸ɺ·ͣɺաڈͷϓϩδΣΫτ͕σʔλϕʔεԽ͞Ε͍ͯΕ͹ɺͦΕΛ׆༻ͯ͠ࠓճ
    ͷϓϩδΣΫτͱྨࣅͨ͠ϓϩδΣΫτΛ ChatGPT ʹݕࡧΛͤ͞Δ͜ͱ͕Ͱ͖ΔͷͰ͸ͳ͍͔ʁ
    ͱਪଌ͠·ͨ͠ɻྨࣅͷςετ໨త/ςετର৅ΛࢀরͰ͖Ε͹ɺࠓճͷϓϩδΣΫτʹ౰ͯ͸Ίͯɺ
    ඞཁͳ޻਺΍εέδϡʔϧɺςετΞϓϩʔνΛࡦఆ͢Δखॿ͚ʹͳΔ͸ͣͰ͢ɻ
    ςετ؅ཧͰͷ׆༻
    ςετ؅ཧͰ͸ɺςελʔ͔Βͷద੾ͳใࠂΛଅ͢ͷʹ׆༻Ͱ͖ͦ͏ɺͱ͍͏ҙݟ͕͋Γ·ͨ͠ɻ
    Slack ͳͲͷνϟοτπʔϧͱ ChatGPT ͕࿈ܞ͞Εͯར༻Ͱ͖ΔΑ͏ʹͳΕ͹ɺAI ͷ bot ͔Βʮਐ
    ௙͸Ͳ͏Ͱ͔͢ʁ Կ͔ؾʹͳͬͨ͜ͱ͸͋Γ·͔͢ʁʯͷΑ͏ʹ࿩͔͚ͯ͠΋Β͏͜ͱ͕Ͱ͖ɺର
    ࿩Λ௨ͯ͡ࠓ͙͢Ϧʔμʔʹใࠂ͢Δ or ༦ձͰใࠂ͢Δɺͱ͍͏൑அ͕Ͱ͖Δͱྑͦ͞͏ɺͱ͍͏
    ΞΠσΞͰ͢ɻ
    ςετ෼ੳͰͷ׆༻
    ςετ෼ੳͰ͸ɺςετϕʔεʢ࢓༷ॻ΍ JIRA νέοτͷ಺༰ɺϛʔςΟϯάͷٞࣄ࿥ͳͲʣΛ
    ΋ͱʹͲͷΑ͏ͳςετ͕ඞཁ͔ݕ౼͠·͕͢ɺ͢ͰʹϦϦʔε͞Ε͍ͯΔαʔϏεͰ͋Ε͹ɺόά
    τϥοΩϯάγεςϜʢBTSʣͱ ChatGPT Λ࿈ܞͯ͠ɺӨڹൣғͷը໘ɾػೳͰൃੜͨ͠աڈͷෆ
    ۩߹΍໰୊ͷ·ͱΊΛग़ͯ͠΋Β͏͜ͱ͕Ͱ͖ΔͰ͠ΐ͏ɻ͔ͦ͜ΒɺରԠ͢΂͖ςετΛݕ౼͠΍
    ͘͢ͳΔͱظ଴͍ͯ͠·͢ɻ
    ςετϕʔεΛ ChatGPT ʹಡΈࠐ·ͤΔ͜ͱ͕Ͱ͖Ε͹ɺ৽ػೳͷϢʔεέʔε΍Ϣʔβʔε
    τʔϦʔΛ࡞੒ͯ͠΋Β͏͜ͱ΋Ͱ͖·͢ɻ͔ͦ͜Βຊདྷͷཁٻʹద߹͍ͯ͠Δͷ͔֬ೝͨ͠Γɺ࢓
    ༷ॻͰݴٴ͞Ε͍ͯͳ͍Օॴʹؾ෇͚ͨΓɺͱ͍ͬͨ͜ͱ΋Ͱ͖ΔͰ͠ΐ͏ɻ͞Βʹӡ༻ɾอकੑ΍
    ηΩϡϦςΟͱ͍ͬͨඇػೳͷ؍఺Ͱ΋ ChatGPT ͷ׆༻͕ظ଴Ͱ͖·͢ɻ
    QA ͸ಠࣗͷςετ؍఺ϦετʢνΣοΫϦετʣΛ͍࣋ͬͯ·͢ɻͦͷϦετ͸͞·͟·ͳϢʔ
    εέʔεΛߟྀ͍ͯ͠·͢ɻैདྷ͸ͦͷϦετΛϓϥϯφʔʹڞ༗ͯ͠ݟͯ΋Β͏ͷΈͰ͕ͨ͠ɺ
    ChatGPT Λ׆༻͢Δ͜ͱͰಥ͖߹Θͤ·Ͱ࣮ࢪͰ͖Ε͹ɺ࢓༷ॻΛิ׬͠ɺ࣮૷ޙʹݕ౼࿙Ε͕ൃ
    ֮ͯ͠͠·͏ͱ͍͏ࣄނΛ๷͙͜ͱ͕ՄೳͱͳΓ·͢ɻ
    ςετઃܭͰͷ׆༻
    ςετઃܭʹ͓͍ͯ΋ɺ΍͸Γࣗ෼ʹͳ͍ࢹ఺΍ح૝ఱ֎ͳΞΠσΞΛҾ͖ग़ͯ͠΋Β͏͜ͱΛظ
    ଴͍ͯ͠·͢ɻͨͱ͑͹ʮϢʔβʔ໊Λೖྗ͢Δʯͱ͍͏Ϣʔεέʔεͷ৔߹ɺChatGPT ʹʮ͜ͷ
    Ϣʔεέʔεʹ͍ͭͯςετ؍఺Λڍ͍͛ͯͩ͘͞ʯͱࢦࣔ͢Ε͹ɺ಺༰ʹԠͨ͡ػೳͷૢ࡞΍ը໘
    50

    View Slide

  58. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.2 ςετϓϩηε͝ͱͷ׆༻ΞΠσΞ
    ͷભҠͷύλʔϯΛڍ͛ͯ͘Ε·͢ɻ͞Βʹʮਖ਼ৗܥ͓ΑͼҟৗܥͷςετΛߟྀ͍ͯͩ͘͠͞ʯͱ
    ௥ՃͰࢦࣔ͢Ε͹؍఺Λ૿΍͢͜ͱ͕Ͱ͖·͢ɻ؍఺͕ͦΖ͖ͬͯͨΒɺ
    ʮϚΠϯυϚοϓͰݟΕΔ
    Α͏ʹ PlantUML Ͱग़ྗ͍ͯͩ͘͠͞ʯͱࢦࣔ͢ΔͱɺϚΠϯυϚοϓʹม׵ՄೳͳܗࣜͰग़ྗ͠
    ͯ͘Ε·͢ɻ
    ςετઃܭ࣌ͷ੒Ռ෺ʢϚΠϯυϚοϓͳͲʣΛ ChatGPT ʹಡΈࠐ·ͤͯɺཁ໿Λ࡞੒ͯ͠΋Β
    ͑Ε͹ɺॏෳ΍ෆ଍͍ͯ͠ΔςετΛු͖ூΓʹ͢Δ͜ͱ͕ظ଴Ͱ͖·͢ɻ͜Ε͸ςετͷϨϏϡʔ
    Ͱ͋ΓɺChatGPT Λ 1 ਓ໨ͷϨϏϡΞʔͱͯ͠׆༻Ͱ͖·͢ɻ΋ͪΖΜςετ׆ಈͰ͸ਓؒʹ΋Ϩ
    Ϗϡʔͯ͠΋Β͍·͕͢ɺࠓ͙͢ʹ࣮ࢪͰ͖Δͱ͍͏఺ͰϝϦοτ͕͋Γ·͢ɻ
    ςετ࣮૷Ͱͷ׆༻
    ςετ࣮૷Ͱ͸ɺςετσʔλͷੜ੒ʹ໾ཱͯΔ͜ͱ͕Ͱ͖·͢ɻμϛʔσʔλΛ࡞Γ͍ͨ৔߹
    ͸ɺग़ྗΛ csv ܗࣜͰࢦఆ͠ɺϔομͱ஋ͱ஋ͷൣғ΋ࢦఆ͢Ε͹ɺ͙͢ʹͦΕΒ͍͠σʔλΛੜ੒
    Ͱ͖·͢ɻQA ͸͓ख੡Ͱ Google εϓϨουγʔτͰσʔλϕʔεΛ࡞͍ͬͯΔ͜ͱ͕Α͋͘Γ·
    ͢ɻ
    ʢΩϟϥΫλʔҰཡɺΞΠςϜҰཡɺεςʔδҰཡͳͲɺ߈ུαΠτͷΑ͏ͳ৘ใΛهࡌ͍ͯ͠
    ΔʣͦͷεϓϨουγʔτΛಡΈࠐ·ͤΔ͜ͱ͕Ͱ͖Ε͹ɺग़ྗ಺༰ͷࢦఆ΋༰қʹͳΔͰ͠ΐ͏ɻ
    ʢͨͩڥք஋ςετͳͲɺݫີʹ஋Λܾఆͯ͠ςετΛ͍ͨ͠৔߹ɺChatGPT ʹੜ੒ͤͨ͞σʔλ
    Ͱ͸ͦΕΛਫ਼ࠪ͢Δख͕ؒൃੜ͢ΔͨΊɺࣗ෼Ͱ࡞ͬͨํ͕ૣ͍ͱײ͡·͢ʣ
    ςετ؅ཧπʔϧΛ࢖ͬͯςετέʔεΛ࡞੒͢ΔࡍɺTestrail ͳͲπʔϧʹΑͬͯ͸ςετέʔ
    εҰͭҰͭʹରͯ͠ݸผͷλΠτϧΛ෇͚Δඞཁ͕͋Γ·͢ɻͦͷࡍɺChatGPT ʹςετखॱ΍ظ
    ଴݁ՌΛݩʹɺλΠτϧΛ࡞੒ͯ͠΋Β͑Δͱॿ͔Γ·͢ɻ
    ςετ࣮ߦͰͷ׆༻
    ςετ࣮ߦͰ͸ɺෆ۩߹Λݟ͚ͭͨࡍʹɺͦͷෆ۩߹͕͢Ͱʹใࠂ͞Ε͍ͯΔ͔Ͳ͏͔ɺόάτ
    ϥοΩϯάγεςϜ্Ͱݕࡧ͢Δ͜ͱ͕Α͋͘Γ·͕͢ɺΩʔϫʔυ΍ΧςΰϦͳͲͰݕࡧͨ͠ࡍʹ
    ώοτ͠ͳ͍৔߹͕͋Γ·͢ɻ͜Εʹର͠όάτϥοΩϯάγεςϜͱ ChatGPT Λ࿈ܞ͢Δ͜ͱ
    Ͱɺ͍͋·͍ݕࡧ͕Ͱ͖ΔΑ͏ʹͳΔ͜ͱΛظ଴͍ͯ͠·͢ɻ
    ෆ۩߹Λىථ͢Δࡍʹ͸ɺChatGPT ʹจষΛϨϏϡʔͯ͠΋Β͏͜ͱ͕Ͱ͖·͢ɻಡΈखʹ఻Θ
    Δ಺༰ʹͳ͍ͬͯΔ͔ɺ࠶ݱखॱ΍؀ڥͷઆ໌ͷෆ଍͕ͳ͍͔ͳͲɺͰ͢ɻ
    ҎԼ͸ ChatGPT ͷ GPT-4 ʹόάϨϙʔτΛϨϏϡʔͤͨ͞ྫͰ͢ɻͳ͓ɺνΣοΫ߲໨͓Αͼ
    ϨϏϡʔର৅ͷόάϨϙʔτ΋ ChatGPT ʹߟ͑ͯ΋Β͍·ͨ͠ɻ
    user:
    νΣοΫϦετ:
    1.λΠτϧ
    ɾΘ͔Γ΍͘͢؆ܿͰɺ۩ମతͳόά಺༰ɺػೳ໊ɺൃੜՕॴʢը໘΍γʔϯʣ
    ɺτϦΨʔ΍৚ؚ͕݅·Ε͍ͯΔ
    ͔
    ɾλΠτϧ͚ͩͰόά಺༰͕ਪଌͰ͖Δ͜ͱ
    2.ৄࡉͳઆ໌
    ɾ࠶ݱखॱ΍৚͕݅໌֬ɺظ଴͢Δಈ࡞͕هࡌ͞Ε͍ͯΔ͔
    51

    View Slide

  59. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.2 ςετϓϩηε͝ͱͷ׆༻ΞΠσΞ
    ɾจষΛ؆ܿʹอͪɺ৘ใ͕੔ཧ͞Ε͍ͯΔ͜ͱ
    3.؀ڥ৘ใ
    ɾOSɺϒϥ΢βɺΞϓϦόʔδϣϯ͕هࡌɺσόΠε΍ωοτϫʔΫ؀ڥ͕ඞཁͰ͋Ε͹هࡌ͞Ε͍ͯΔ͔
    ɾඞཁҎ্ͷ৘ใ͸هࡌ͠ͳ͍͜ͱ
    4.৘ใͷ໌֬ੑ
    ɾ͢΂ͯͷ৘ใ͕໌֬Ͱ෼͔Γ΍͍͢ݴ༿Ͱهࡌ͞Ε͍ͯΔ͔
    ɾҰൠతͰͳ͍༻ޠ΍ུޠ͕ආ͚ΒΕ͍ͯΔ͜ͱ
    ࢦࣔɿ
    ҎԼͷόάϨϙʔτΛɺ্هͷνΣοΫϦετʹ΋ͱ͍ͮͯϨϏϡʔ͍ͯͩ͘͠͞ɻ
    ෼͔ΓͮΒ͔ͬͨΓ۩ମతͰͳ͍هड़͕͋Ε͹ڭ͍͑ͯͩ͘͞ɻ
    όάϨϙʔτ಺༰:
    1.λΠτϧ:
    ήʔϜதʹϓϨΠϠʔΩϟϥΫλʔ͕ফ͑Δόά͕ൃੜ͢Δ
    2.ৄࡉͳઆ໌:
    ϓϨΠதʹɺϓϨΠϠʔΩϟϥΫλʔ͕ফ͑ͯ͠·͏όά͕ൃੜ͠·͢ɻ࠶ݱखॱ͸ҎԼͷ௨ΓͰ͢ɻ
    - ήʔϜΛىಈ͢Δɻ
    - ήʔϜதʹϓϨΠϠʔΩϟϥΫλʔΛૢ࡞͢Δɻ
    - ͠͹Β͘ϓϨΠ͢ΔͱɺϓϨΠϠʔΩϟϥΫλʔ͕ը໘͔Βফ͑ͯ͠·͏͜ͱ͕͋Δɻ
    ظ଴͢Δಈ࡞͸ɺϓϨΠϠʔΩϟϥΫλʔ͕ਖ਼ৗʹදࣔ͞ΕɺϓϨΠ͕εϜʔζʹਐߦ͢Δ͜ͱͰ͢ɻ
    3.؀ڥ৘ใ:
    OS: Windows 10
    ϒϥ΢β: Google Chrome
    ήʔϜόʔδϣϯ: 1.2.3
    assistant:
    νΣοΫϦετʹ΋ͱ͍ͮͯϨϏϡʔΛߦ͍ɺҎԼͷϙΠϯτ͕վળ͞ΕΔͱΑΓ෼͔Γ΍͍͢όάϨϙʔτʹ
    ͳΓ·͢ɻ
    1.λΠτϧ:
    λΠτϧ͸ɺ֓ͶΘ͔Γ΍͘͢؆ܿʹॻ͔Ε͍ͯ·͕͢ɺൃੜՕॴʢը໘΍γʔϯʣ
    ɺτϦΨʔ΍৚ؚ͕݅·Ε
    ͍ͯ·ͤΜɻҎԼͷΑ͏ʹमਖ਼͢ΔͱɺΑΓ۩ମతʹͳΓ·͢ɻ
    ྫ:ʮϝΠϯը໘ͰͷϓϨΠதɺҰఆ࣌ؒܦաޙʹϓϨΠϠʔΩϟϥΫλʔ͕ফ͑Δόάʯ
    2.ৄࡉͳઆ໌:
    ࠶ݱखॱʹ͍ͭͯɺ۩ମతͳૢ࡞΍γʔϯɺ৚݅Λ௥Ճ͢Δͱɺ͞Βʹ໌֬ʹͳΓ·͢ɻͨͱ͑͹ɺҎԼͷΑ͏
    ʹमਖ਼Ͱ͖·͢ɻ
    - Ͳͷεςʔδ΍γʔϯͰൃੜ͢Δͷ͔
    - ಛఆͷૢ࡞΍ΞΠςϜΛ࢖༻͍ͯ͠Δ࣌ʹൃੜ͢Δͷ͔
    - ϓϨΠϠʔΩϟϥΫλʔ͕ফ͑ΔલʹԿ͔ಛఆͷݱ৅΍ΤϑΣΫτ͕͋Δͷ͔
    3.؀ڥ৘ใ:
    ؀ڥ৘ใ͸ɺඞཁͳ৘ใ͕ద੾ʹهࡌ͞Ε͍ͯ·͢ɻσόΠε΍ωοτϫʔΫ؀ڥ͕ؔ܎͍ͯ͠Δ͔Ͳ͏͔ʹͭ
    ͍ͯ΋ɺ֬ೝ͠௥ه͢Δͱྑ͍Ͱ͠ΐ͏ɻ
    4.৘ใͷ໌֬ੑ:
    ৘ใ͸֓Ͷ໌֬Ͱ෼͔Γ΍͍͢ݴ༿Ͱهࡌ͞Ε͍ͯ·͢ɻͨͩ͠ɺ࠶ݱखॱ΍৚݅ʹ͍ͭͯ͸ɺ͞Βʹ۩ମతͳ
    ৘ใΛఏڙ͢Δ͜ͱͰɺ։ൃऀ͕όάΛಛఆ͠΍͘͢ͳΓ·͢ɻ
    52

    View Slide

  60. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.3 ৼΓฦΓͰͷ׆༻ΞΠσΞ
    100 ఺ຬ఺Ͱਓؒͷग़Δນ͸ͳ͍ʂ ͱ͍͏݁ՌͰ͸͋Γ·ͤΜ͕ɺ͜ͷΑ͏ͳϨϏϡʔΛؾܰʹɺ
    ԿճͰ΋ར༻Ͱ͖Δͱ͍͏఺Ͱߟ͑Ε͹ɺδϡχΞϨϕϧͷςελʔ͸େॿ͔ΓͰ͠ΐ͏ɻ
    ·ͨόάϨϙʔτͷλΠτϧΛ୹͍ͨ͘͠৔߹͕͋Γ·͢ɻ
    ʢόάτϥοΩϯάγεςϜʹΑͬͯ
    ͸จࣈ਺੍ݶ͕͋ͬͨΓ͠·͢ʣͦͷ৔߹͸ҎԼͷΑ͏ʹࢦࣔ͢Δ͜ͱͰɺςΩετΛվળͯ͘͠Ε
    ·͢ɻ
    user:
    ҎԼͷจষ͸όάνέοτͷλΠτϧͰ͢ɻίϯςΩετΛਖ਼֬ʹ఻͑ΔͨΊɺ෼͔Γ΍͘͢໌ྎͳจষ΁Ϧϥ
    Πτ͍ͯͩ͘͠͞ɻ
    ϓϨΠϠʔ͕͋ΔότϧΛऴΘΒͤΑ͏ͱͨ࣌͠ɺຯํ͕ಟͷঢ়ଶҟৗʹ͔͔͍ͬͯͯΤϑΣΫτ͕ग़͍ͯΔ৔
    ߹ɺήʔϜ͕͍͖ͳΓΫϥογϡͯ͠͠·͍ɺότϧ͸ΫϦΞͨ͜͠ͱʹͳ͍ͬͯͳ͍
    assistant:
    ϓϨΠϠʔ͕ότϧऴྃ࣌ɺຯํ͕ಟঢ়ଶΤϑΣΫτதͷ৔߹ɺήʔϜ͕ಥવΫϥογϡ͠ɺότϧΫϦΞ͕ະ
    ׬ྃʹͳΔ
    ͜ͷΑ͏ͳ࢖͍ํ͸ɺόάϨϙʔτʹݶΒͣνϟοτ΍ϝʔϧͳͲจࣈίϛϡχέʔγϣϯશൠͰ
    ׆༻Ͱ͖·͢ɻࢲ͸ ChatGPT Λར༻͢Δࡍ͸Ի੠ͰςΩετೖྗ͍ͯ͠·͢ɻಠΓݴΛͨ͘͞Μ
    ͨ͠ͷͪɺͦΕΛਖ਼͍͠೔ຊޠʹ௚͠ɺ৑௕ͳදݱΛ࡟ͬͯ΋Β͏ɺͱ͍͏ܗͰ׆༻͍ͯ͠·͢ɻ
    5.3 ৼΓฦΓͰͷ׆༻ΞΠσΞ
    ςετҎ֎ͷ׆ಈʹ໨Λ޲͚ΔͱɺϛʔςΟϯά͕͋Γ·͢ɻৼΓฦΓͰ ChatGPT ͕׆༻Ͱ͖
    Δͱࢥ͍·͢ɻ
    ChatGPT ͱͷ 1on1
    ৼΓฦΓ͸ 1 εϓϦϯτɺ1 όʔδϣϯͱ͍ͬͨઅ໨Ͱ։࠵͞Ε·͕͢ɺৼΓฦΓͷϛʔςΟϯά
    ·ͰʹɺࠓճԿ͕͚͋ͬͨͬʜͱࢥ͍ฦ͢४උ͕ඞཁͰ͢ɻ͜ͷ࣌ࣗ໰ࣗ౴͢Δ୅ΘΓʹ ChatGPT
    ʹ࣭໰Λͯ͠΋Β͏ํ๏͕͋Γ·͢ɻͭ·Γ ChatGPT ͱͷ 1on1 Ͱ͢ɻͨͱ͑͹ҎԼͷΑ͏ͳϓϩ
    ϯϓτʢChatGPT ʹೖྗ͢ΔςΩετʣΛຖ೔ۀ຿ऴྃલʹ࢖༻͠·͢ɻ
    user:
    #ϧʔϧ
    ChatGPT͸ϝϯλʔͱͯ͠ৼΔ෣͍ɺࢲͷࠓ೔ͷۀ຿ͷ੒ՌΛฉ͍͍ͯͩ͘͞ɻ
    ࢲͷճ౴͸ޙ೔ৼΓฦΓͰར༻͢Δ͜ͱ͕͋Γ·͢ɻ
    ΠϯτϩμΫγϣϯͷ௨Γʹ։࢝͠ɺ࠷ॳͷ࣭໰Λ͍ͯͩ͘͠͞ɻ
    ࢲͷճ౴Λฉ͍ͯɺϙδςΟϒͳϑΟʔυόοΫΛฦͭͭ͠ɺ
    ந৅తͳՕॴΛਂ۷Γͯ࣍͠ͷ࣭໰Λ͍ͯͩ͘͠͞ɻ
    ࣭໰ͷΩʔϫʔυ͸͋͘·ͰྫͰ͢ɻࢲͷճ౴ͷ಺༰ʹԠͯ͡దٓมߋor௥Ճ͍ͯͩ͘͠͞ɻ
    53

    View Slide

  61. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.4 ࣮ફʂ ެࣜαΠτͷ͓஌ΒͤνΣοΫ
    #ΠϯτϩμΫγϣϯ
    ࠓ೔΋Ұ೔͓ർΕ༷Ͱͨ͠ɻࠓ೔ͷৼΓฦΓΛ͠·͠ΐ͏ɻ
    #ձ࿩ͷऴྃ৚݅
    ɾ࣭໰ͷճ౴͕3ճߦΘΕΔ
    ·ͨ͸
    ɾࠓ೔͸΋͏্͕Γ·͢ͱࢲ͕એݴ͢Δ
    #ऴྃޙͷϓϩηε
    ճ౴Λཁ໿͠ɺՕ৚ॻ͖Ͱฒ΂Δ
    #࣭໰ͷΩʔϫʔυ
    ࠓ೔΍ͬͨ͜ͱɹλεΫɹ׆ಈɹୡ੒ɹ೉͔ͬͨ͜͠ͱɹ՝୊ɹ໰୊ɹίϛϡχέʔγϣϯɹײ৘ɹײँɹށ࿭
    ͍ɹݒ೦ɹײͨ͜͡ͱɹվળ఺ɹ஫ҙ఺
    ͜ͷϓϩϯϓτͷ࠷ऴग़ྗ݁Ռ͸ҎԼͰ͢ɻ
    assistant:
    ৽͍͠ϛʔςΟϯά΁ͷট଴΍ػࡐ؅ཧʹؔ͢Δํ਑ͷܾఆ͸ɺϓϩδΣΫτͷਐ௙ʹͱͬͯେ੾ͳ৘ใͰ͢
    Ͷɻ͓ർΕ༷Ͱͨ͠ɻ
    ͦΕͰ͸ɺࠓ೔ͷճ౴Λཁ໿͠ɺՕ৚ॻ͖Ͱฒ΂·͢ɻ
    ։ൃதͷήʔϜͷςετϓϨΠΛ࣮ࢪ͠ɺճ෮ΞΠςϜͷճ෮ྔ͕গͳ͍ͱײ͡ΔϑΟʔυόοΫΛఏڙɻ
    େ͖ͳ໰୊͸ݟ͔ͭΒͣɺ։ൃ͕ॱௐʹਐΜͰ͍Δɻ
    Ϧʔμʔͱͷ1on1ͰίϛϡχέʔγϣϯΛਤΓɺ৽͍͠ϛʔςΟϯάΛઃఆ͢Δɻ
    ػࡐ؅ཧʹؔ͢Δํ਑͕ܾఆɻ
    ࠓ೔΋͓ർΕ༷Ͱͨ͠ɻ·ͨ࣍ճͷৼΓฦΓͰ͓ձ͍͠·͠ΐ͏ɻ
    ࣗ෼Ͱࢦ͍ࣔͯͯ͠΋ɺ͍͟ϙδςΟϒͳ൓Ԡ͕ฦͬͯ͘Δͱؾ෼͕ྑ͍Ͱ͢ɻݻఆͷ࣭໰Ͱ͸ͳ
    ͍ҝɺࣗ෼͕औΓ૊Μͩ׆ಈͰͷؾ෇͖ʹ͍ͭͯɺChatGPT ʹΑͬͯ૝ىͤ͞ΒΕΔͷͰ͢ɻࣗ෼
    ͕ൃݴͨ͠಺༰ΛՕ৚ॻ͖Ͱཁ໿ͯ͠΋Β͏͜ͱͰɺৼΓฦΓ࣌ʹͦͷ··ར༻Ͱ͖ΔͰ͠ΐ͏ɻ
    5.4 ࣮ફʂ ެࣜαΠτͷ͓஌ΒͤνΣοΫ
    ۩ମతͳ࣮ફྫΛ঺հக͠·͢ɻϞϯελʔετϥΠΫެࣜαΠτͷ͓஌Βͤϖʔδ͔Βɺ৽Πϕ
    ϯτ৘ใͷϖʔδΛର৅ʹɺΠϕϯτ಺༰ͷνΣοΫΛ ChatGPT ʹ࣮ࢪͯ͠΋Β͍·͢ɻ
    ˝νΣοΫର৅ͷ͓஌Βͤ
    2023.03.30 ৽Πϕϯτʮઓࠃ෩Ӣֆר-רϊ۝-ʯ͕ελʔτʂ ௒ϋϧۄ&ॳճ 24 ˋ CP ର৅ʂ
    https://www.monster-strike.com/news/20230330_5.html
    54

    View Slide

  62. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.4 ࣮ફʂ ެࣜαΠτͷ͓஌ΒͤνΣοΫ
    ҎԼ͸ϓϩϯϓτͰ͢ɻ࣮ࡍʹ͸#͓஌Βͤͷཝʹɺ͓஌Βͤͷ಺༰Λ͢΂ͯίϐʔ&ϖʔετͰ
    هࡌ͠·͕͢ɺຊߘͰ͸লུ͍ͯ͠·͢ɻ
    user:
    #ࢦࣔ
    ҎԼ͸ϞϯελʔετϥΠΫͷެࣜαΠτʹ͋Δ͓஌Βͤ಺ɺ৽Πϕϯτͷϖʔδͷ಺༰Ͱ͢ɻ
    Πϕϯτ಺༰શମΛɺϚΠϯυϚοϓͷ༷ʹϩδοΫπϦʔܗࣜͰϦετͰ੔ཧ͍͚ͯͨͩ͠·͔͢ɻͨͩ͠ɺ
    ա౓ͳཁ໿Λͤͣɺৄࡉͳ৘ใΛ࡟Βͳ͍Α͏ʹ஫ҙ͍ͯͩ͘͠͞ɻ
    ·ͨɺࠓճͷΠϕϯτͷ಺༰Λ࣌ܥྻͰฒ΂͍ͯͩ͘͞ɻ࣌ܥྻ͸ݟ΍͘͢͢ΔͨΊදܗࣜͰɺ׌ͭ೔࣌ͱΠϕ
    ϯτ಺༰Λਖ਼֬ʹग़ྗ͍ͯͩ͘͠͞ɻ
    #͓஌Βͤ
    Πϕϯτ
    2023.03.30
    ৽Πϕϯτʮઓࠃ෩Ӣֆר-רϊ۝-ʯ͕ελʔτʂ ௒ϋϧۄ&ॳճ24ˋCPର৅ʂ
    ৽Πϕϯτ͕4݄2೔ʢ೔ʣΑΓొ৔ʂ
    ৄࡉ͸ɺຊϖʔδ಺ΛνΣοΫʂ
    ஫ҙ఺ͱͯ͠ɺChatGPT ʹҰ౓ʹೖྗͰ͖Δจࣈ਺ͷ੍ݶ಺ʹऩ·Γ͖Βͳ͍৔߹͕͋Γ·͢ɻ
    ͦͷ৔߹͸͓஌ΒͤΛ෼͚ͯೖྗ͠ɺ
    user:
    Πϕϯτ಺༰ʹ͍ͭͯ௥Ճ͠·͢ɻ
    ҎԼͷ಺༰ͱ্هͷग़ྗ݁Ռͱ߹Θͤͯɺ࠶౓ϩδοΫπϦʔͱ࣌ܥྻͷग़ྗΛ͓ئ͍͠·͢ɻ
    #͓஌Βͤ
    ʨ͜͜ʹ͓஌ΒͤΛهࡌ͢Δʩ
    ͱͭͳ͙͜ͱͰɺग़ྗ݁ՌΛ݁߹Ͱ͖·͢ɻͦͯ͠ҎԼ͕࠷ऴग़ྗ݁ՌͰ͢ɻ
    assistant:
    ʲϩδοΫπϦʔʳ
    - ઓࠃ෩Ӣֆר-רϊ۝-
    - Ψνϟ
    - ௒ϋϧۄ
    - 10࿈Ψνϟແྉ
    - ˒5Ҏ্ΩϟϥΫλʔഉग़֬཰ 24ˋ
    - ॳճγϯάϧΨνϟ & ॳճ10࿈Ψνϟ
    - ˒5Ҏ্ΩϟϥΫλʔഉग़֬཰ 24ˋ
    55

    View Slide

  63. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.4 ࣮ફʂ ެࣜαΠτͷ͓஌ΒͤνΣοΫ
    - ৽ΩϟϥΫλʔ
    - ෱ౡਖ਼ଇ (ਫଐੑ)
    - ͶͶ (໦ଐੑ)
    - ౡࠨۙ (ޫଐੑ)
    - ৽Ωϟϥ֬ఆΨνϟˍΦʔϒ
    - Ձ֨: 4,900ԁ
    - ಺༰: ৽Ωϟϥ֬ఆΨνϟ1ճˍΦʔϒʷ50
    - ߪೖ੍ݶ: ͓ͻͱΓ༷1ճݶΓ
    - ৽ΠϕϯτΫΤετ
    - ඈͼग़͠ةݥʂ ѱྶ͕੗·͏Ҫށ (˒5 ڰࠎ)
    - ऺਓΛ࿭Θ͢ڊนͷո໎࿏ (˒5 ృน)
    - ౮ΓΛܝ͛͠ྶࠢͷҊ಺ਓ (˒5 ηϯϙΫΧϯϙΫ)
    - ফඅελϛφݮগˍεϖγϟϧϘʔφε
    - ফඅελϛφݮগ
    - ܹڀۃɿ50ˠ40
    - ڀۃɿ45ˠ36
    - εϖγϟϧϘʔφε
    - ֫ಘϙΠϯτ5ഒ
    - υϥʔχΞग़ݱ
    - ΠϕϯτΫΤετΫϦΞͰग़ݱ
    - ϚϧνϓϨΠͰۚཛυϩοϓ
    - ϥοΫϘʔφε༏଴Ωϟϯϖʔϯ
    - ۚཛ֬ఆഉग़
    - ظؒݶఆϛογϣϯ
    - τΫۄ֫ಘ
    - τΫۄΨνϟར༻ظݶ
    ʲ࣌ܥྻʳ
    - 2023೥4݄2೔ 12:00
    - Πϕϯτ։࢝
    - Ψνϟ։࢝ʢ৽Ωϟϥ֬ఆΨνϟˍΦʔϒൢച։࢝ʣ
    - ৽ΠϕϯτΫΤετొ৔
    - ফඅελϛφݮগˍεϖγϟϧϘʔφε։࢝
    - υϥʔχΞग़ݱ։࢝
    - ϥοΫϘʔφε༏଴Ωϟϯϖʔϯ։࢝
    - ظؒݶఆϛογϣϯ։࢝
    - 2023೥4݄15೔ 11:59
    - Πϕϯτऴྃ
    - Ψνϟऴྃʢ৽Ωϟϥ֬ఆΨνϟˍΦʔϒൢചऴྃʣ
    - ফඅελϛφݮগˍεϖγϟϧϘʔφεऴྃ
    - υϥʔχΞग़ݱऴྃ
    - ϥοΫϘʔφε༏଴Ωϟϯϖʔϯऴྃ
    - ظؒݶఆϛογϣϯऴྃ
    - 2023೥4݄18೔ 3:59
    - ظؒݶఆϛογϣϯใुडऔظݶ
    - 2023೥4݄18೔ 23:59
    - τΫۄΨνϟར༻ظݶ
    56

    View Slide

  64. ୈ 5 ষ ChatGPT Λ QA ͕࢖͍͜ͳ͢ҝͷΞΠσΞ 5.5 ࠓޙͷల๬
    ChatGPT ͸ཁ໿΍ิ׬Λͯ͘͠ΕΔ͜ͱ͕ར఺Ͱ͕͢ɺࠓճͷΑ͏ͳνΣοΫͰ͸ͳΔ΂͘ؾΛ
    ར͔ͤͳ͍Α͏ʹͯ͠΋Β͏͜ͱ͕ϙΠϯτͰ͢ɻ࣌ܥྻͰฒ΂ͯ΋Β͏͜ͱͰɺτΫۄ͕֫ಘͰ͖
    ΔϛογϣϯΑΓૣ͘τΫۄΨνϟ͕ऴΘͬͯ͠·͍ͬͯͳ͍͔ɺͱ͍͏͜ͱ΋ࣝผ͠΍͍͢Ͱ͢ɻ
    ͜ͷϓϩϯϓτʹ͞ΒʹνΣοΫ߲໨Λ௥Ճͨ͠Γɺ࣌ܥྻҎ֎Ͱͷํ๏Ͱ৘ใΛฒ΂ͯ΋ΒͬͨΓ
    ͱɺ޻෉ͷ༨஍͸·ͩ·ͩ͋Γͦ͏Ͱ͢ɻ
    5.5 ࠓޙͷల๬
    ChatGPT ʹυϝΠϯ஌ࣝΛ༩͍͑ͨ
    લड़ͷϞϯελʔετϥΠΫͷ͓஌ΒͤͷνΣοΫ΋ɺϞϯελʔετϥΠΫʹؔ͢Δ஌ࣝΛඞཁ
    ͱ͠ͳ͍ఔ౓ͷνΣοΫ·Ͱ͔͠པΉ͜ͱ͕Ͱ͖·ͤΜɻͨͱ͑͹ɺ͓஌Β͕ͤҎԼͷΑ͏ͳ಺༰
    ͩͬͨ৔߹ ChatGPT ͸ؾ෇͚ΔͰ͠ΐ͏͔ʁ
    • ৽ΨνϟͰഉग़͞ΕΔ˒ 4 ΩϟϥΫλʔͷਐԽૉࡐʹʮ्ਆۄʯ͕͋Δ
    • Ψνϟͷऴ͕ྃ࣌ؒ 23:59 ʹͳ͍ͬͯΔ
    • υϥʔχΞͷग़ݱʹؔ͢Δهࡌ͕ͳ͍
    ϞϯελʔετϥΠΫΛϓϨΠ͍ͯ͠Δɺ·ͨ͸։ൃʹܞΘ͍ͬͯΔਓؒͰͳ͍ͱؾ෇͘͜ͱ͸Ͱ
    ͖·ͤΜɻͨͩࣾ͠಺ͷυΩϡϝϯτΛ༩͑ɺϞϯελʔετϥΠΫͷυϝΠϯ஌ࣝΛ࣋ͨͤΔ͜ͱ
    ͕Ͱ͖Ε͹ɺ
    ʮ͍ͭ΋ͷ৽Πϕϯτͱҧ͏ͱ͜Ζ͕͋Ε͹ڭ͍͑ͯͩ͘͞ʯͱฉ͚ͩ͘ͰࡁΈ·͢ɻ
    কདྷۀ຿Ͱར༻Ͱ͖ΔΑ͏ʹͳΔ͜ͱΛظ଴͠ɺࠓ೔΋಺লͷҝʹ ChatGPT ͱձ࿩͠ͳ͕Βɺຊ
    ߘΛకΊ͘͘Γ͍ͨͱࢥ͍·͢ɻ
    57

    View Slide

  65. View Slide

  66. ஶऀ঺հ
    ߐാ ୓࠸ (ୈ 1 ষ୲౰, GitHub: @MokkeMeguru, @MeguruMokke)
    TIPSTAR ͱ͍͏ڞ༡ܕεϙʔπϕοςΟϯάαʔϏεͷ։ൃɾӡ༻Λߦ͍ͬͯ·͢ɻιγϟ
    ήͷ՝͕ۚࢭ·Βͳ͍ͷ͕࠷ۙͷ೰ΈͰ͢ɻEmacs Ͱ Clojure Λॻ͍ͯੜ͖͍ͯ·͢ɻ
    দݪ ৴஧ (ୈ 2 ষ୲౰)
    ॴଐ͸ϞϯεταʔόνʔϜͰ Ruby ΍ Go Λॻ͍ͯΔɻϓϩάϥϛϯά͕޷͖Ͱɺීஈ͸ਪ
    ͠ݴޠͷ Haskell Ͱ༡ΜͩΓɺ৽͍͠ϓϩάϥϛϯάݴޠΛษڧͨ͠Γ͍ͯ͠ΔɻHaskell-jp
    ΍ Elm-jp Ͱগ͚ͩ͠׆ಈ΋͍ͯ͠Δɻ
    ٢઒ ༐ଠ࿠ (ୈ 3 ষ୲౰)
    2021 ೥৽ଔೖࣾɻιʔγϟϧϕοςΟϯάࣄۀຊ෦ ։ൃࣨ ΫϥΠΞϯτάϧʔϓॴଐɻ
    WebGL ৮ΔͷͱΠϯυΧϨʔ͕޷͖Ͱ͢ɻ
    ాಹล ً (ୈ 4 ষ୲౰)
    ։ൃຊ෦ CTO ࣨॴଐɻιϑτ΢ΣΞΤϯδχΞͱͯ͠ήʔϜ։ൃͱӡӦɺͦΕ͔Βऩӹੑ΍
    ήʔϜੑͱ UX ໘౳ʑΫϦΤΠςΟϒʹ΋ܞΘ͖ͬͯ·ͨ͠ɻϓϩάϥϛϯάڭҭʹ͍ͭͯ
    ͷֶशιϑτͱΧϦΩϡϥϜΛࣗࣾ಺Ͱ࡞Γɺதɾߴߍੜʹ޲͚ͯϓϩάϥϛϯάߨ࠲ͷߨࢣ
    Ͱ΋׆ಈதɻ΄͔ࣾ಺ R&D ۀ຿΋ࢀՃɻ
    ౉ᬒ ݩً (ୈ 5 ষ୲౰, Twitter: @motokiwatanabe2)
    Asym Altered Axis ͱ͍͏։ൃதͷήʔϜͷ QA Λ୲౰͍ͯ͠·͢ɻϝΠϯδϣϒ͸ֶऀͰ
    ͢ɻChatGPT ͸ӳձ࿩ͷ࿅शͰ࢖͏ͱେมศརͰָ͍͠Ͱ͢ɻ
    59

    View Slide

  67. MIXI TECH NOTE #09
    2023 ೥ 5 ݄ 20 ೔ɹॳ൛ୈ 1 ࡮ɹൃߦ
    ஶɹऀ גࣜձࣾ MIXI ༗ࢤ
    ൃߦॴ גࣜձࣾ MIXI
    ҹ࡮ॴ ೔ޫاը
    ɹ
    ˜ MIXI

    View Slide

  68. View Slide