Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kadai3-1 imura81gt #49

Open
wants to merge 6 commits into
base: kadai2-imura81gt
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions kadai3/imura81gt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
【TRY】タイピングゲームを作ろう
===========================================

- [ ] 標準出力に英単語を出す(出すものは自由)
- [x] 標準入力から1行受け取る
- [x] 制限時間内に何問解けたか表示する


【TRY】分割ダウンローダを作ろう
===========================================

分割ダウンロードを行う

- [ ]Rangeアクセスを用いる
- [ ]いくつかのゴルーチンでダウンロードしてマージする
- [ ]エラー処理を工夫する
- [ ]golang.org/x/sync/errgourpパッケージなどを使ってみる
- [ ]キャンセルが発生した場合の実装を行う

ref: https://qiita.com/codehex/items/d0a500ac387d39a34401


Range Request
-------------------------------------------------

https://developer.mozilla.org/ja/docs/Web/HTTP/Range_requests

> Accept-Ranges が HTTP レスポンスに存在した場合 (そして値が "none" ではない場合)、サーバーは範囲リクエストに対応しています。これは例えば、 HEAD リクエストを cURL で発行することで確認することができます。


https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Accept-Ranges

> Accept-Ranges: bytes
> Accept-Ranges: none

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Range

> Range: <unit>=<range-start>-
> Range: <unit>=<range-start>-<range-end>
> Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
> Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
68 changes: 68 additions & 0 deletions kadai3/imura81gt/typ/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------

FROM golang:1

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux,
# this user's GID/UID must match your local user UID/GID to avoid permission issues
# with bind mounts. Update USER_UID / USER_GID if yours is not 1000. See
# https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Configure apt, install packages and tools
RUN apt-get update \
&& apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
#
# Verify git, process tools, lsb-release (common in install instructions for CLIs) installed
&& apt-get -y install git iproute2 procps lsb-release \
#
# Install gocode-gomod
&& go get -x -d github.com/stamblerre/gocode 2>&1 \
&& go build -o gocode-gomod github.com/stamblerre/gocode \
&& mv gocode-gomod $GOPATH/bin/ \
#
# Install Go tools
&& go get -u -v \
github.com/mdempsky/gocode \
github.com/uudashr/gopkgs/cmd/gopkgs \
github.com/ramya-rao-a/go-outline \
github.com/acroca/go-symbols \
github.com/godoctor/godoctor \
golang.org/x/tools/cmd/guru \
golang.org/x/tools/cmd/gorename \
github.com/rogpeppe/godef \
github.com/zmb3/gogetdoc \
github.com/haya14busa/goplay/cmd/goplay \
github.com/sqs/goreturns \
github.com/josharian/impl \
github.com/davidrjenni/reftools/cmd/fillstruct \
github.com/fatih/gomodifytags \
github.com/cweill/gotests/... \
golang.org/x/tools/cmd/goimports \
golang.org/x/lint/golint \
golang.org/x/tools/cmd/gopls \
github.com/alecthomas/gometalinter \
honnef.co/go/tools/... \
github.com/golangci/golangci-lint/cmd/golangci-lint \
github.com/mgechev/revive \
github.com/derekparker/delve/cmd/dlv 2>&1 \
#
# Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user.
&& groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
# [Optional] Add sudo support
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME \
#
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
32 changes: 32 additions & 0 deletions kadai3/imura81gt/typ/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or the definition README at
// https://github.com/microsoft/vscode-dev-containers/tree/master/containers/go
{
"name": "Go",
"dockerFile": "Dockerfile",
"runArgs": [
// Uncomment the next line to use a non-root user. On Linux, this will prevent
// new files getting created as root, but you may need to update the USER_UID
// and USER_GID in .devcontainer/Dockerfile to match your user if not 1000.
// "-u", "vscode",

"--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"
],

// Use 'settings' to set *default* container specific settings.json values on container create.
// You can edit these settings after create using File > Preferences > Settings > Remote.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"go.gopath": "/go"
},

// Uncomment the next line if you want to publish any ports.
// "appPort": [],

// Uncomment the next line to run commands after the container is created.
// "postCreateCommand": "go version",

// Add the IDs of extensions you want installed when the container is created in the array below.
"extensions": [
"ms-vscode.go"
]
}
8 changes: 8 additions & 0 deletions kadai3/imura81gt/typ/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

import "github.com/gopherdojo/dojo7/kadai3/imura81gt/typ/typing"

func main() {
g := typing.Game{}
g.Run()
}
111 changes: 111 additions & 0 deletions kadai3/imura81gt/typ/typing/typing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package typing

import (
"bufio"
"context"
"fmt"
"io"
"math/rand"
"os"
"time"
)

// ----- for time
type Clock interface {
Now() time.Time
}

type ClockFunc func() time.Time

func (f ClockFunc) Now() time.Time {
return f()
}

type Game struct {
Clock Clock
}

func (g *Game) now() time.Time {
if g.Clock == nil {
return time.Now()
}
return g.Clock.Now()
}

// -----------

func input(r io.Reader) <-chan string {
ch := make(chan string)
go func() {
s := bufio.NewScanner(r)
for s.Scan() {
ch <- s.Text()
}
if err := s.Err(); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
close(ch)
}()
return ch
}

func (g *Game) load() string {
var ws = []string{"すもも", "もも"}
rand.Seed(g.now().UnixNano())
w1 := ws[rand.Intn(len(ws))]
w2 := ws[rand.Intn(len(ws))]
w3 := ws[rand.Intn(len(ws))]

return fmt.Sprintf("%sも%sも%sのうち", w1, w2, w3)
}

func show(score int, chars int, txt string, out io.Writer) {
fmt.Fprintf(out, "%d %d > %s\n%d %d > ", score, chars, txt, score, chars)
}

// Run is a function to start typing-game.
func (g *Game) Run() {

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

const (
limit = 60
interval = 10
)
chi := input(os.Stdin)

var score int
var chars int

txt := g.load()

show(score, chars, txt, os.Stdout)

B:
for {
select {
case v := <-chi:
if txt == v {
fmt.Println("GOOD!!!")
score++
chars = chars + len([]rune(txt))
txt = g.load()
show(score, chars, txt, os.Stdout)
} else {
fmt.Println("BAD....")
show(score, chars, txt, os.Stdout)
}
case <-time.After(limit * time.Second):
fmt.Println()
fmt.Println("Time up!")
fmt.Println("Score:", score, "points!", chars, "charactors!")
cancel()
case <-ctx.Done():
fmt.Println(ctx.Err())
break B
}
}
}
91 changes: 91 additions & 0 deletions kadai3/imura81gt/typ/typing/typing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package typing

import (
"bytes"
"fmt"
"testing"
"time"
)

func TestInput(t *testing.T) {
testcases := []struct {
caseName string
input string
expected string
}{
{caseName: "input some word", input: "foo bar", expected: "foo bar"},
{caseName: "input line feed", input: "\n", expected: ""},
}
fmt.Println(testcases)
for _, tc := range testcases {
tc := tc // capture range variable. need to set when run parallel test.

t.Run(tc.caseName, func(t *testing.T) {
t.Parallel()

var buf bytes.Buffer
buf.Write([]byte(tc.input))
actual := <-input(&buf)

if tc.expected != actual {
t.Errorf("\ncaseName:%s\nactual:%+v\nExpected:%+v\n",
tc.caseName,
actual,
tc.expected,
)
}
})
}

}

func TestLoad(t *testing.T) {
g := Game{
Clock: ClockFunc(func() time.Time {
return time.Date(2019, 11, 04, 02, 0, 0, 0, time.UTC)
}),
}

expected := "すもももももももものうち"
actual := g.load()
if actual != expected {
t.Errorf("\ncaseName:%s\nactual:%+v\nExpected:%+v\n",
"load test",
actual,
expected,
)
}
}

func TestShow(t *testing.T) {
testcases := []struct {
caseName string
score int
char int
txt string
expected string
}{
{caseName: "score10char300", score: 10, char: 300, txt: "テスト", expected: "10 300 > テスト\n10 300 > "},
}

for _, tc := range testcases {
tc := tc // capture range variable. need to set when run parallel test.

t.Run(tc.caseName, func(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
show(tc.score, tc.char, tc.txt, &buf)
actual := buf.String()
if tc.expected != actual {
t.Errorf("\ncaseName:%s\nactual:%+v\nExpected:%+v\n",
tc.caseName,
actual,
tc.expected,
)
}
})
}

}

func TestRun(t *testing.T) {}