7月1週

土曜:5h

  • gormの規約
    • ストラクト名がテーブル名になる(キャメルケースはスネークケースにマッピングされる)→MemberID→member_id

user-first.ikyu.co.jp

func main() {
    db, err := databases.Connect() // *gorm.DBが返却される
    defer db.Close()

    if err != nil {
        log.Fatal(err)
    }

    db.Debug().AutoMigrate(&models.BtcJpyS{}) //AutoMigrate(モデル)でマイグレーションする
    db.Debug().AutoMigrate(&models.BtcJpyM{})
    db.Debug().AutoMigrate(&models.BtcJpyH{})
    db.Debug().AutoMigrate(&models.SignalEvents{})
}
  • AutoMigrateにモデルを入れてgo run utils/migrateマイグレーション実行するとテーブルが作成できる f:id:yosuke0517:20200627203408j:plain

golangのDB操作が全然できていないことを再確認

  • orマッパーとgoの標準?の操作も明日を使って習得する

日曜:5h

月曜:11h

火曜:11h

  • Issueを1つ消化(レイヤードアーキ)
  • Issueを4つほど登録

水曜:11h

  • 個人開発(go)
  • 1h,1m,1sそれぞれのテーブルにbitcoin情報を格納するまではできた。と思ったらtimeフィールドに現在時間しか入らない・・・なぜ・・・

    木曜:11h

  • 昨日の状況の調査を引き続き・・・

    金曜:11h

  • 解決ー。問題はMySQL側にあった。MySQL5.7ではtimestamp型のデフォルト値を指定しないとinsert時の時刻がフィールドの値として登録されてしまう。
  • テーブル定義を以下のようにdefault値を追加して対応
-- +migrate Up
CREATE TABLE IF NOT EXISTS `SIGNAL_EVENTS` (
  `time` TIMESTAMP PRIMARY KEY NOT NULL,
  `product_code` VARCHAR(50),
  `side` VARCHAR(10),
  `price` float,
  `size` float
);
-- +migrate Down
DROP TABLE IF EXISTS `SIGNAL_EVENTS`;

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2860h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:flutter基礎・capreseデプロイ検討・関数型プログラミングおさらい
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得・k8s基礎
  • 来週の目標:k8s,golang進める

6月4週

もう今年も半分終わる・・・早すぎる

土曜:5h

  • 土曜はgolangの日
  • docker-composeで.envの内容を使用する
    • 設定オプションでこんな感じで対象のenvファイルを指定する
web:
  env_file:
    - web-variables.env
  • 使う時はこんな感じ
environment:
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - TZ=Asia/Tokyo

日曜:5h

  • golangのクリーンアーキテクチャでアクセスする順番
  • router →controller → usecase/interactor (この中でgatewayで外部APIを叩く)→ controllerへ戻りjsonで返す

日曜はk8sの日

  • マルチコンテナデプロイ
    • travisCIで実施。こんな感じでまずはdocker hubへpush
    • その他のCIツールとほぼ同じっぽい
sudo: required
services:
  - docker

before_install:
  - docker build -t ユーザ名/complex -f ./frontend/Dockerfile.dev ./frontend

script:
  # 各コンテナでのテストケース追加するならここで
  - docker run -e CI=true yosuke0517/complex yarn test

after_success:
  - docker build -t ユーザ名/multi-frontend ./frontend
  - docker build -t ユーザ名/multi-nginx ./nginx
  - docker build -t ユーザ名/multi-server ./server
  - docker build -t ユーザ名/multi-worker ./worker
  # Login to the docker cli
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_ID" --password-stdin
  # take those images and push them to docker hub
  - docker push ユーザ名/multi-frontend
  - docker push ユーザ名/multi-nginx
  - docker push ユーザ名/multi-server
  - docker push ユーザ名/multi-worker
  • 今日はとりあえずelastic beansTalkで f:id:yosuke0517:20200621204715j:plain

  • elastic beansTalkでもオートスケールは可能

    • しかし、細かいスケーリングはできない(全体のコピーを作成するだけ)

木曜までにコレを読んでおく

qiita.com

月曜:11h

  • 業務の機能改修でreactできなかった

火曜:11h

  • css
  • :not(hoge)の使い方
  • 以下の例だとdisabledの要素には効かない&activeのときにこのcssが効く書き方。
  • カンマで別のクラスについても書ける
.c-btn-check:not(:disabled):active , .c-btn-check.is-active:not(:disabled):active {
    transform: translateY(6px);
    background-color: #ffffff;
    color: #000;
  }

水曜:11h

  • 本当はflutterの日だけどgoのモチベがあるのでしばらくは水曜もgoで
  • クリーンアーキでやろうと書いてたけどスタートダッシュには向いてなかった。今回はmvcチックに普通の構成でやる

木曜:11h

テスト駆動開発について

  • フロントエンドにおいてはテスト駆動開発は必要ないかなと思っていたが、業務要件が複雑な場合は有効だなと思った。
    • このアクションが正しく実装されているなら、この前提条件から実行すると、かならずこの結果になるはず、というテストケースを「ホワイトボックステスト」になるように書きます。
    • その上で、何も実行しない空のアクションを書いて、実行し、失敗させる。
    • 今度はアクションを本気で書いて、テストに合格するようにします。
  • この繰り返しで考慮漏れをなくす。

金曜:11h

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2795h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:golang基礎・capreseデプロイ検討・関数型プログラミングおさらい
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得・k8s基礎
  • 来週の目標:k8s,golang進める

6月3週

土曜:5h

  • フロントのモックで詳細検索をするのにハマった
  • 結局以下のようになった
server.get(new RegExp(`/api/v1/projects/id_*`), (req, res) => {
  let result = null
  const id = req.url.match(/[^/]+$/i)[0]
  const dbObj = Object.assign(db)
  Object.keys(dbObj).forEach((key) => {
    const detailPrj = dbObj[key].find((element) => element.id === id)
    if (detailPrj) {
      result = detailPrj
    }
  })
  res.jsonp(result)
})
  • 整理したら割と簡単な作りだった。。。。

土曜はgoの日

システムトレードAPIだけどせっかく作るならマイクロサービスにしたくてgRPCをインプット

RESTとgRPCの違い

RESTがリソース志向(リソースに対してHTTPメソッドで操作していく考えかた)に対してRPCはメソッド志向もしくはサービス志向

gRPCはHTTP/2を採用(RESTはHTTP/1.1)

HTTP/2はコネクションを張りっぱなし。要は速い

Protocol Buffers

  • protoファイルというIDL(インターフェース記述言語)を書いてコンパイラを実行すると任意の言語のサーバ/クライアント用コードを自動生成してくれる
  • 自分でAPIインターフェースを実装したり、シリアライズされたデータのエンコード/デコード処理を書く必要がない
  • スキーマを最初に書く(そのためAPI仕様書が古くてフロントエンドの人たちが怒ることがなくなる)
  • protoファイルは静的型付け

gRPCのデメリット

  • HTTP/2非対応である危険性(AWSのALBは非対応)←リクエストを受け付けることはできるが、バックエンドのサーバへの転送をHTTP/1で行うため
  • ↑同様に通信経路上でHTTP/2に非対応なサービスがある場合にgRPCを使う上で問題が生じる
  • ブラウザの対応状況が不十分

SPAとの相性はRESTに分がある

しかし、フロントエンドとバックエンドの間にgraphQLを挟むといい感じになるようだ

  • graphQLも少し見てみたが、フロントエンドは複数の言語で実装されている膨大なAPIを仕様等を意識することなく呼べるようで相当なメリットがあると感じた
  • 対してバックエンド側はメリットがよくわからなかった

日曜:5h

  • webstrom矩形選択:option + option押したらカーソルで選択可能

    docker

  • volumesにapp/node_modulesを記述するのはなぜかを考えていた
    • ホスト側でyarn installしていないとnode_modulesは空だからホスト側をマウントしないようにしているみたい
  • ただ、そうしたらIDEなどの補完が効かなくなるのではと思った。
    • 解決策としてdockerコンテナの中でyarn install したものをホスト側に持ってくる手法があるらしい

castaneai.hatenablog.com

月曜

  • jestでエラーハンドリングテスト
it('should throw error status 400', async () => {
    store.commit('setQrCodeObj', {})
    store.commit('setAgencyCode', 'A99999999')
    store.commit('setCrewCode', '0000000000')
    // mockを用意
    mock.onPost('api/systemAdminCertify').reply(400, systemAdminCertifyResult.RESULT_NG)
    try {
      await store.dispatch('certify')
    } catch (e) {
      const error = JSON.parse(e.message)
      expect(error.errorObj.response.status).toBe(400)
    }
  })
  • try/catchでやったら簡単だった(errorがjsonで来るからparseしてる)

caprese

  • qsて何に使ってるのかわからなかったけど、オブジェクト→クエリだったりクエリ→オブジェクトに変換するやつだったんだ・・・
  • 例えば、APIのアクセストークンの再取得をcurlでやろうとすると
curl 'https://securetoken.googleapis.com/v1/token?key=APIキー' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token&refresh_token=既存のトークン'
  • で、ソースコードにすると以下のようにqsを使いオブジェクトをクエリに変換してからリクエストを投げることができる
      if (refreshToken) {
        const data = {
          grant_type: 'refresh_token',
          refresh_token: refreshToken
        }

const res = await this.axios.$request({
          method: 'POST',
          headers: {
            Authorization: '',
            'Content-Type': 'application/x-www-form-urlencoded'
          },
          data: qs.stringify(data),
          url:
            'https://securetoken.googleapis.com/v1/token?key=' +
            process.env.YOUTUBE_API_KEY
        })
}

アクセストークンとリフレッシュトークンの認識についてちょっと誤解していた

火曜:11h

  • goの日
    • とりあえずリアルタイムで株価情報取得まではいったよ
    • コレからはissue管理しよう
    • goの静的解析ツールを試す

github.com

水曜:

スクロールについて

  • 今日はイベント系の勉強になった
  • 以下はtouchmoveイベントとtouchendイベントを制御してスクロール
this.scrollElement = document.getElementById('campaign-inner')
    this.scrollElement.addEventListener('touchend', (e) => {
      this.previousY = undefined
    })
    this.scrollElement.addEventListener('touchmove', (e) => {
      console.log('touchmove')
      e.preventDefault()
      if (!this.previousY) {
        this.previousY = e.touches[0].clientY
      } else {
        const moveY = e.touches[0].clientY - this.previousY
        const newY = this.scrollElement.scrollTop - moveY
        this.scrollElement.scrollTop = newY
        this.previousY = e.touches[0].clientY
        this.scrollBottom = this.scrollElement.clientHeight - this.scrollElement.scrollTop
        if (this.scrollBottom < 20) {
          this.$store.dispatch('data/condition/updateScrollValidationOfCampaign', true)
        }
      }
    }, { passsive: false })

木曜:

  • APIへアクセスするときのクエリーの作成
  • Objectの中にhoge: "hoge"みたいに入っている
const queryString = Object.keys(params)
      .map((key) => key + '=' + params[key])
      .join('&') // ②
    const query = queryString.length > 0 ? `${uri}?${queryString}` : uri

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2730h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:flutter基礎・capreseデプロイ検討・関数型プログラミングおさらい
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得・k8s基礎
  • 来週の目標:k8s,golang進める

6月2週

土曜:5h

  • 土曜はgolangの日。システムトレードアプリのバックエンドを作っていく
  • 今日できた機能
    • bitflyerAPIから自分の残高(円・BTCとか)を取得するメソッドを作成
    • bitflyerAPIから現状の仮想通貨(BTCとか)の情報を取得するメソッドを作成
    • http.ListenAndServe(":8080", nil)の後にhttp.Handlefuncを書いてて、落ちる現象でハマった

日曜:5h

  • 日曜はk8s
  • システムトレードアプリのフロントエンドの自動デプロイをElasticBeansTalkで作成。masterへpushのみでデプロイ確認OK。
    • 簡単なアプリだったらコレが一番早い。。。
    • 来週の木・日でバックエンドも含めたもう少し複雑なサンプルをデプロイしてみて、6月いっぱいは色々と試す。
    • 7月からシステムトレードアプリのインフラを構築していく

月曜:

aws反復記事

aws.amazon.com

cssでボーダーの幅を左右上下別々に指定する

border-left: 600px solid #000;
border-right: 600px solid #000;
border-top: 200px solid #000;
border-bottom: 200px solid #000;
  • 月曜はreact
    • hooks登場前
    • React Way 的にはクラスコンポーネントよりも関数コンポーネントのほうが望ましいけど、関数コ ンポーネントは Local State もライフサイクルメソッドも持てないという話はしたね。それで HOC を 使って関数コンポーネントに Local State やライフサイクルメソッドといったクラスコンポーネントが 持っている機能を始めとする便利な機能を付与できる Recompose*3 というライブラリが、意識高い開 発者のあいだでよく使われていた

火曜:11h

  • base64の意味があいまいだったので調べてみた
  • あー、画像を文字列として送るのね

qiita.com

  • 正規表現で最後のスラッシュ以降(URL)の文字列を取得する
    • str.match( /[^/]+$/i )[0];

水曜:11h

  • 今日はflutterの日
  • 画像のリサイズにどれを使えばいいのか悩んだ
SizedBox(
   width: 60,
   height: 60,
   child: Image.network(
         "https://yt3.ggpht.com/a/AATXAJx2LQwh1kNX09biNyCenCNGzh5Rvwoue-an_Q=s288-c-k-c0xffffffff-no-rj-mo"),
   ),
   Column(...
  • このようにSizedBoxを使うと簡単そう

木曜:11h

  • ついついforEach使いがちだけど用途に応じてfilter/map/reduceあたり使った方が可読性あがるな

    ハッシュ化と暗号化の違い

  • ハッシュ化は不可逆(戻せない)
    • パスワードを管理する場合はハッシュ化する。ログイン時は入力されたパスワードを同じアルゴリズムでハッシュ化して突合する
  • 暗号化は可逆
  • もし、sha1→sha2に移行する場合で、オリジナルのパスワードをハッシュ化した文字列しか持っていない場合、とりあえずテーブルにsha2用のフィールドは追加しておいて、ユーザがログインした際にそっちのフィールドにもハッシュ化したパスワードを保持する等して、ユーザがいつか全員ログインしてくれることを願って徐々に移行していくしかない

    k8sの概要をさらっと理解するめちゃくちゃ良い記事があった

qiita.com

金曜:11h

  • これは
isQrFooter () {
      if (this.$store.state.routing.baseRouter.viewPage.isQrFooter) {
        return true
      } else {
        return false
      }
    }
  • これと同じ意味。返り値としてobjectやundefinedではなく,trueかfalseがほしいとき使うらしい。。。
isQrFooter () {
      return !!this.$store.state.routing.baseRouter.viewPage.isQrFooter
    }

6月1週

土曜:5h

golang

日曜:5h

  • docker on reactアプリが立ち上げと同時にコード0で終了してしまう問題
    • docker-compose.ymlにstdin_open: trueを追加することで回避できた
  • dockerのreactアプリのテスト実行でハマった以下のようにitオプション(正確には-i -tオプション)を指定すればいけた
  • docker run <imageID> yarn test
  • テスト実行用のserviceを作る
version: '3.5'
services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - /app/node_modules
      - .:/app
    stdin_open: true
  tests:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - /app/node_modules
      - .:/app
    command: ["yarn","test"]
  • これでテストを編集するたびにテスト用コンテナ内で実行される
  • けど、欠点がある。それは入力ができないということ(全てのテストを実行する)
  • これの対応策としては普通にコンテナ入ってやるしか・・

nginxを使って本番用のDockerfileを作る

FROM node:alpine as builder
WORKDIR '/app'
COPY package.json .
RUN yarn install
COPY . .
RUN yarn build

FROM nginx
# builderフェーズからコンテナにコピーする
COPY --from=builder /app/build /usr/share/nginx/html
  • 動くか確認docker run -p 8080:80

月曜:11h

  • webstormファイル検索時はshift * 2
  • react
    • tsxでのif~elseの書き方{value ? <foo /> : <bar />}こんな感じ
    • 配列をフィルターにかけてその結果に対する処理をするとき
    • targets.filter(t => t.length > 5).map(t => <...>)
  • スプレッド演算子でオブジェクトをまとめて渡す(img
import logo from './logo.svg';

const logoOptions = { 
  alt: "logo", 
  className: "App-logo", 
  src: logo
};

return (
  <div className="App">
    <header className="App-header"> {
      // コメントはこう書く }
      <img {...logoOptions} /> 
      {title && <p>{title}</p>} 
      {targets.map(target => (
      <p>Hello, {target}!</p> ))}

火曜:11h

  • curlでヘッダーにCookieをセットしたい時
jWyS0nQee2lARKfkQKS6wXkDXQWcZolse2gSb5zrci4p8oWxQlhfXZOayH; sessionid=ixw7g5wxd
06njdcdwbctcn2fok5c4mgu;'
  • こんな感じ

水曜:11h

  • $toastedとか$tとかはjsファイル内では使えない

木曜:11h

  • stateにバリデーションオブジェクトを格納しようとして全然できなくてハマった
  • バリデーションは関数なので、関数をjson化しようとしていた

    マルチステップビルド

  • こんな感じ。
FROM node:alpine as builder
WORKDIR '/app'
COPY package.json .
RUN yarn install
COPY . .
RUN yarn build

FROM nginx
# buildした成果物(/app/build)をbuilderフェーズからコンテナにコピーする
COPY --from=builder /app/build /usr/share/nginx/html

- dockerhub

Docker Hub

金曜:11h

react

  • やはりできるエンジニアはフロントエンドはvueじゃなくてreact選びがちだなぁ。
  • reactでeslint
    • yarn add -D eslint-plugin-react @typescript-eslint/eslint-plugin @typescript-eslint/parser
    • あとは.eslintrc.js以下コピペで、node_modulesのeslint-pluginを見るように設定(webstormならポチポチで勝手にやってくれる)
module.exports = {
    env: {
        browser: true,
        es6: true
    },
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/recommended',
    ],
    globals: {
        Atomics: 'readonly',
        SharedArrayBuffer: 'readonly'
    },
    parser: '@typescript-eslint/parser',
    parserOptions: {
        ecmaFeatures: {
            jsx: true
        },
        project: './tsconfig.json',
        sourceType: 'module'
    },
    plugins: ['@typescript-eslint', 'react'],
    root: true,
    rules: {
        '@typescript-eslint/explicit-function-return-type': 'off',
        '@typescript-eslint/explicit-member-accessibility': 'off',
        'indent': 'off',
        '@typescript-eslint/indent': ['error', 2],
        '@typescript-eslint/no-unnecessary-type-assertion': 'error',
        'eol-last': ['error', 'always'],
        'func-style': ['error', 'expression', { allowArrowFunctions: true }],
        'newline-before-return': 'error',
        'no-dupe-class-members': 'error',
        'no-var': 'error',
        'object-shorthand': ['error', 'always'],
        'prefer-arrow-callback': 'error',
        'prefer-const': 'error',
        'prefer-spread': 'error',
        'require-yield': 'error'
    }
};

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2600h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:flutter基礎・capreseデプロイ検討・関数型プログラミングおさらい
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得
  • 来週の目標:新機能追加

5月5週

土曜:5h

  • 今日はgoの日
  • docker + airを使用してリモートデバッグができるようにした

    詰まった箇所

  • ブレイクポイントが効かない事象が発生

    • 2種類のgopathを設定しており、プロジェクトgopathを消したら直った f:id:yosuke0517:20200523205149j:plain
  • go moduleが効かない事象が発生していた

    • golandでgo moduleを有効化したら直った f:id:yosuke0517:20200523205332j:plain

日曜:5h

月曜:11h

  • caprese共通エラーメッセージ作成
  • z-indexで重なりを指定

火曜:11h

  • jestにてスキーマ毎??(言い方がわからない)にstoreを定義する
import { actions, mutations, state } from '~/store/api/customerInfo'
import { actions as certifyActions, mutations as certifyMutations, state as certifyState } from '~/store/data/certify'
import { actions as dataActions, mutations as dataMutations, state as dataState } from '~/store/data'
import { actions as rootActions, mutations as rootMutations, state as rootState } from '~/store'
import { actions as innerRouterActions, mutations as innerRouterMutations, state as innerRouterState} from '~/store/routing/innerRouter'

こんな感じ

css :100%では画面いっぱいという意味にならない

  • 親要素がいたとすると、親要素の大きさの100%のことだから画面いっぱいという意味にはならない
  • 画面いっぱいを表したいときは100vhを使う(横はvw
  • jsnotice.com

水曜:11h

<div class="parent">
            <div class="child">■1</div>
            <div class="child">■2</div>
            <div class="child">■3</div>
          </div>

.parent {
    background: #55BE2E;
    font-size: 32px;
    display: flex;
    .child:nth-child(3) {
      background: #EE6E73;
      font-size: 32px;
      margin-left: auto;
    }
  }

タブ内でスクロールバリデーション(一番下までスクロールしないと次へボタンが活性化されないやつ)しようと思ったときにハマったのでメモ

  • 1番下の値を求める
    • 底 = スクロール対象の要素の画面高さ - スクロール対象の要素の画面に表示されている分の高さ
  • コードにするとこんな感じ
data () {
  scrollY: 0,
  scrollElement: {},
  scrollBottom: 0
},
mounted () {
    this.scrollElement = document.getElementById('device-inner')
    this.scrollElement.addEventListener('scroll', this.handleScroll)
    // 底 = スクロール対象の要素の画面高さ - スクロール対象の要素の画面に表示されている分の高さ
    this.scrollBottom = this.scrollElement.scrollHeight - this.scrollElement.clientHeight
},
methods: {
    handleScroll () {
      this.scrollY = this.scrollElement.scrollY
      if (this.scrollElement.scrollTop === this.scrollBottom) {
        alert('一番下')
      }
    }
  }

木曜:11h

  • TypeScriptの各型の真偽
  • 0, ''(=空文字), null, undefinedが false でそれ以外はtrue

金曜:11h

  • vueで動的にcssクラスを付与する
  • :classを使ってshow === 'options'がtrueのときにis-activeクラスが付与される
<b-button
        @click="showUpdateCommit('options')"
        name="options"
        :class="{'is-active': show === 'options'}"
        class="c-btn-check btn-block text-left font-weight-bold"
      >

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2535h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:flutter基礎・capreseデプロイ検討・ライブラリの改造
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得
  • 来週の目標:新機能追加

5月4週

土曜:5h

  • 今日も一日実装

日曜:5h

  • 今日も一日実装

月曜:11h

  • 共通のエラーメッセージ実装

関数型プログラミング

const arr=[1,2,3,4,5,6,7,8];

console.log(arr.map(n => n * 2)); // [ 2, 4, 6, 8, 10, 12, 14, 16 ] 
console.log(arr.filter(n => n % 3 === 0)); // [ 3, 6 ]
console.log(arr.find(n => n > 4));// 5
console.log(arr.every(n => n !== 0));// true
console.log(arr.some(n => n > 8));// false
console.log(arr.includes(5)); // true
console.log(arr.reduce((n, m) => n + m)); // 36 
console.log(arr.sort((n, m) => n < m));// [ 8, 7, 6, 5, 4, 3, 2, 1 ]
  • map() は対象の配列の要素一つ一つを加工した新しい配列を作る
  • filter() は条件に適合する要素だけを抽出して新しい配列を作る
  • find() は条件に適合した要素をひとつだけ取り出す。見つからない場合はundefindを返す ・ every() はすべての要素が条件を満たすかを真偽値で返す
  • some() は条件を満たす要素がひとつでもあるかを真偽値で返す
  • includes() は指定した要素が含まれるかを真偽値で返す
  • reduce() は配列の要素を、与えた式で畳み込んだ値を返す
  • sort() は各要素を、与えた条件によって並び替えた新しい配列を返す

高階関数

  • 高階関数とは、引数に関数をとったり戻り値として関数を返したりする関数のこと
  • 例えば、filterメソッドは引数にn => n % 3 === 0という無名関数を受け取っている
const arr=[1,2,3,4,5,6,7,8];

console.log(arr.filter(n => n % 3 === 0)); // [ 3, 6 ]

  • 戻り値として関数を返したりするの部分は
const hof = (ex, fn) => { 
  return n => fn(n + ex);
};
const plusOneDouble = hof(1, n => n * 2); 
console.log(plusOneDouble(4)); // 10
  • 1ブロック目:関数hofは第一引数に数値、第二引数に関数を受け取り、引数を受け取る関数を返す。
  • 2ブロック目:第一引数に1、第二引数にn*2する関数を渡す。
  • 第3ブロック:n(4)を関数に渡して、1+4をしてから関数n2が実行されるため52が実行されて10が出力される

クロージャ

  • 目的:グローバル変数を作成せずに外部(子関数)から親関数スコープの変数へアクセスする方法
  • ポイント:counterMakerが最後に関数を返しているいこと。const count = counterMaker(1)の中身は関数。
const counterMaker = (initialCount) => { 
  let c = initialCount;
  const increment = () => c++;
  
  return increment; 
};
const count = counterMaker(1); 
console.log(count(),count(),count()); //123

ジェネレータ

  • Redux-Sagaを使用する際に書くので飛ばす

カリー化

const curriedMulti = n => { 
  returnm=>n*m;
} 
console.log(curriedMulti(2)(4)); // 8
  • n(2)を引数に取り、nmを返す。そして、m(4)を引数にとり、24している
  • (4)の部分がmを引数にとって、返ってきた関数にぶつけている箇所

  • returnを省略するとこんな感じ

const simpleCurriedMulti = n => m => n * m; 
console.log(simpleCurriedMulti(2)(4));// 8
  • 部分適用
  • ×3するだけの関数を変数に代入し、その変数に第二引数を与えて計算結果を出す
constmulti=n=>m=>n*m; 
const triple = multi(3); 
console.log(triple(5)); // 15

火曜:11h

- json-serverでエラーハンドリングをテストしたい時

qiita.com

server-jsonでエラーハンドリング

  • server.jsを作ってこんな感じでレスポンスするファイルの中身(mock.json)を読み込む
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('mock.json')
const middlewares = jsonServer.defaults()
const db = require(`./mock.json`)

server.use(middlewares)
// Add custom routes before JSON Server router
server.get('/echo', (req, res) => {
  res.jsonp(db.list)
})

server.use(router)
server.listen(8000, () => {
  console.log('JSON Server Port is 8000 running')
})

golang久々に再開

  • docker on golangの環境構築でずっとモジュールがないよ的なこと言われていた。。。go mod init appでgo.modを作らないといけなかった・・・

水曜:11h

  • nullチェック構文
{ servicePriceMax: servicePriceMax || '' }
  • こうやって書くとservicePriceMaxがnullまたはundefinedのときは''が設定される

木曜:11h

  • テストデータの出しわけ考え方
    • 例えば、認証時の電話番号の1桁または2桁に意味を持たせる(1桁目は性別・2桁目は料金プランとか)

金曜:11h

  • テストケース作成

週次報告

  • 年間(2019/8~2020/8)目標時間(業務での設計・実装含む):3380h
  • 今週を含む累積時間:2470h
  • 週次目標時間:65h
  • 週次実績時間:65h
  • 何を得たか:flutter基礎・capreseデプロイ検討・ライブラリの改造
  • 何が必要か:golang基礎・認証の知見・Nuxt・React・テスト手法の取得
  • 来週の目標:新機能追加