OmniAICreator/Qiita-1.07M huggingface dataset:
vue-test-utils が v1.0.0-beta30 からDOM更新されなくなったお話

日本語情報が見当たらなかったので記事にしておきます。

## 結論
vue-test-utils で ``setData`` 等で値の更新をしてDOM更新を行いたい時は更新したいタイミングで``await wrapper.vm.$nextTick()``をするか、値更新の頭に await をつけるかをする必要がある。

## 該当issue
https://github.com/vuejs/vue-test-utils/issues/1384

## 事象
以前はなにも記述しなくても行われていたDOM更新がバージョン ``1.0.0-beta.30`` から行われなくなっていた。

## 起きたこと
vue-test-utils をバージョンアップさせたところ、``v-if`` での表示/非表示をテストするコードのテストが通らなくなった。
以下は同じエラーが起きるコード。（issueから抜粋）

```example.vue
<template>
  <div>
      <p v-if="show">Foo</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true
    }
  }
}
</script>
```

```test.spec.js
import { mount } from '@vue/test-utils';

import Example from './Example.vue';



test("should render Foo, then hide it", () => {
  const wrapper = mount(Example)
  expect(wrapper.text()).toMatch(/Foo/)

  wrapper.setData({
    show: false
  })

  expect(wrapper.text()).not.toMatch(/Foo/)
})
```

こちらのテストの場合、一番下のテストの結果が下記のようになり失敗する。
expect：false
received：true

原因は show の値を更新しただけではDOM更新が行われなくなったから。
なのでテストはエラーになるものの、``show`` の値自体は意図通り ``false`` に書き替わっている。

## 解決策
値更新後に ``await wrapper.vm.$nextTick()`` を追加し、DOM更新させることで意図したテストを実施できる。
この時テストの関数に async を追加することもお忘れなく。

```test.spec.js
import { mount } from '@vue/test-utils';

import Example from './Example.vue';



test("should render Foo, then hide it", async () => {
  const wrapper = mount(Example)
  expect(wrapper.text()).toMatch(/Foo/)

  wrapper.setData({
    show: false
  })
  await wrapper.vm.$nextTick()

  expect(wrapper.text()).not.toMatch(/Foo/)
})
```

またバージョン ``1.0.0`` からは ``await wrapper.vm.$nextTick()`` の代わりに
値更新のコードの頭に ``await`` をつけるだけで動作するようになりました。
参照：https://github.com/vuejs/vue-test-utils/releases/tag/v1.0.0

```test.spec.js
import { mount } from '@vue/test-utils';

import Example from './Example.vue';



test("should render Foo, then hide it", async () => {
  const wrapper = mount(Example)
  expect(wrapper.text()).toMatch(/Foo/)

  await wrapper.setData({
    show: false
  })

  expect(wrapper.text()).not.toMatch(/Foo/)
})
```

## 最後に
こちらのエラーについて調べた時に日本語で検索しても一切出てこなかったのに、
英単語で検索するとすぐに該当issueが出てきたのでこれからは検索方法として英語検索も積極的に使っていきたい。
【Docker】python(Flask)+GraphQL(graphene)+MySQL(sqlalchemy)の環境を構築する

# はじめに
pythonのwebフレームワークのFlaskを用いてGraphQL環境をdockerを用いて構築する。

ここでは、docker,docker-composeについて説明する。grapheneの設定は[Python (Flask) with GraphQL Server implementing SQLAlchemy, graphene, and SQLite](https://medium.com/swlh/python-flask-with-graphql-server-with-sqlalchemy-and-graphene-and-sqlite-ac9fcc9d3d83) を参照

# 必要ファイル、ディレクトリ

```
.
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
├── books/ ←　上記のサイトを参照

```

# ファイルの内容
## requirements.txt

```text:requirements.txt
Flask==1.1.2
Flask-GraphQL==2.0.1
graphene==2.1.8
graphene-sqlalchemy==2.3.0.dev1
SQLAlchemy==1.3.17
pymysql
```

## Dockerfile

```dockerfile:Dockerfile
FROM python:3.7-slim

WORKDIR /mnt

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt


```

## docekr-compose.yml

```yaml:docker-compose.yml
version: '2'
services:
  graphql: 
    build: .
    volumes: 
    - './:/mnt'
    ports:
        - "5000:5000"
    tty: true
  db:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_DATABASE: test
      MYSQL_ROOT_PASSWORD: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
    ports:
        - "3306:3306"

```
他のファイルは[Python (Flask) with GraphQL Server implementing SQLAlchemy, graphene, and SQLite](https://medium.com/swlh/python-flask-with-graphql-server-with-sqlalchemy-and-graphene-and-sqlite-ac9fcc9d3d83)を参照
# 実行
以下のコマンドを実行する

```
$ docker-compose up -d
```

http://localhost:5000/graphql   にアクセス

以下の画面が表示されれば成功！

![スクリーンショット 2020-10-05 23.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308470/ccc50eee-c939-e67a-5aca-c0c8a63379e1.png)
さらっと流してしまいがちだけど、改めてtimesメソッドについてまとめてみた。

###timesメソッドとは
　数値オブジェクトに使うことができる、メソッド。`do~end`で囲った処理を数値の数だけ繰り返す。

##結論
あえて、最初に結論から述べる。

<font color=red>・~~ブロック変数~~ブロックパラメーターは、ブロックの中でのみ有効（スコープ）
・外で定義したものも、ブロックの中では使える（書き換えられることに注意）</font>

このことを頭の片隅に置き、読み進めていって欲しい。

###スコープ
　スコープとは、定義した変数が使える範囲のこと。

###ブロック
 `do~end`もしくは、`{  }`(波括弧)の中をブロックと呼ぶ。さらに、ブロックの中で`|変数名|`　||（パイプライン）の中の変数を~~ブロック変数~~ブロックパラメーターという。

###STEP1

確実に理解するために、まずはここから。

```ruby

num = 1
puts num
#=>1
```

こんなプログラム、変数のいちばん初めに出てくる。
丁寧に説明をすると、１という数値を変数numに代入し、それをputsで呼び出している。意識はしていないが、変数numの及ぶ範囲（スコープ）だから、putsで呼び出すことができる。


###STEP2

```ruby
num = 1

3.times do
 puts num
end
#=>1
#  1
#  1
```
これは、`puts num`が３回繰り返され、「１」が３回結果として出された。注目すべき点は、変数numのスコープ。`do~end`の外で定義された変数を使うことができている。

###STEP3

```ruby
3.times do
 num = 1
end
puts num
#=>NameError
```

STEP2と似たコードだが、エラーが出ます。↓

```bash

NameError (undefined local variable or method num for main:Object)
```
簡単に訳すと、「`puts num`の`num`が定義されていないよ」ということ。
そうです、`do~end`の中で定義されたものは、`do~end`の外では呼び出すことができないということ。
実はつまずきポイント！！

###STEP4

```ruby
num = 1

3.times do|i|
 num = num + i
end
puts num
#=>4
```

読み解くポイント
①~~ブロック変数~~ブロックパラメーターは0から始まり、1ずつ増える。上の例でいくと、１週目には「0」が、２週目には「１」が、３週目には「２」が代入されていると考える。


②外の変数は書き換えられている。

丁寧に書くと↓
１週目　num + 0 =>numが１と定義されているので、「1 + 0」がnumに代入される。
２週目　num + 1 =>上記より、numは１で、2週目なので、iが1に変わり、「1 + 1」がnumに代入される。
３週目　num + 2 =>上記より、numは2で、3週目なので、iが2に変わり、「2 + 2」がnumに代入される。

##ポイント

- [x] 　~~ブロック変数~~ブロックパラメーターはその名の通り、ブロックの中でのみ有効。
- [x] 　ブロックの外で定義した変数をブロック内の処理によって書き換えることができる。

##最後に
　繰り返し処理については、プログラミングを学習して、早い段階で覚える内容で、理解したつもりでも細かいところまでは覚えていないことがあるので、この機会に復習を。
MongoDBコマンドの最低限の自分用メモ

# はじめに
Node.js × expressでAPIを作る際にDatabaseでmongoDBを採用しました。
そのときに、CLIからの使い方で少し躓いたので必要最低限のメモを残す。


# CLIに入る

```
mongo
```

# DB一覧確認

```bash
show dbs
```

# DB選択

```bash
use db_name
```

※mongo時に省略可能

```
mongo db_name
``` 

# Table一覧確認

```
show collections
```

※tablesでもいける

```
show tables
```

# 全件取得

```
db.table_name.find();
```

# 一件取得

```
db.table_name.findOne();
```

# 個数

```
db.table_name.count();
```

# sort

```
db.table_name.find().sort({ createdAt: -1 }); 
```

※ `-1`は降順`1`は昇順

# 登録

```
db.table_name.insert({ title: "mongo" });
```

# 更新

```
db.table_name.update({ title: "mongo2" });
```

# 削除

```
 db.table_name.remove({title: "mongo2" });
```
Docker仮想環境でオフライン音声認識システムJuliusをpythonで動かしてみた

初めての記事を投稿します。

#Julius(ユリウス)
　Juliusとは京大が開発した音声認識システムであり、精度は悪いものの、無料かつオフラインで動かすことができるといったメリットがあります。

　今ある記事の中では、Juliusをpythonで解析するためにソケット通信を用いないと出来ないものばかりで煩わしさを感じたので、pythonから直接Juliusを動かすコマンドを叩き、その結果を解析するコードをクラスとしてまとめました。

※2020年12月19日追記
実行環境 mac(Catalina ver 10.15.4)

以下githubソースコード
https://github.com/rirma/JuliusVoiceAnalyzer.git

必要ないライブラリもインストールされますがご了承願います。
必要でなければ下の方のpip3インストールなどは削除してください。

#Juliusを動かすまでの流れ
*2020年12月19日追記
##ホスト側の処理
　① まず、macにpulseaudioをダウンロードします。

```
brew install pulseaudio
```

　② ホスト側でpulseaudioを立ち上たままにしておきます。(docker仮想環境内でマイクを認識するために必要です)

```
pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1
```

##サーバ側の処理
　① ダウンロードしたフォルダ内で下記コマンドを叩き、dockerコンテナを作成します。

```
$ docker-compose up -d --build
```

　②作成したコンテナ内に入ります。

```
$ docker-compose exec python bash
```

　③VoiceAnalyzer.pyの置いてあるフォルダに移動し、プログラムを実行します。

```
# cd opt/public/src
# python3 VoiceAnalyzer.py
```

　④何か声を発し、次のような実行結果になれば成功です。

```
start record
Saved.
20201005220733.wav
enter filename->...........................................................................................................................................................................................................enter filename->1 files processed
おはよう。
```

*2020年12月19日追記
　また、音声を解析したい場合は以下のコマンドを実行します。(your file pathには解析したいファイルを入れます)

```
$ bash julius-start.sh
...
enter filename->'your file path'
```
　これを利用すれば、pythonサーバに音声ファイルを送り、認識結果を返すようなアプリの開発もできるかと思います。

#音声解析のためのプログラム
VoiceAnalyzer.py内にJuliusで音声解析をしやすくするためのクラスが定義されています。

###初期化

```python
def __init__(self, chunk = 1024, format = pyaudio.paInt16, channels = 1, rate = 44100, record_seconds = 2, threshold = 0.1)
```

必要に応じて変更するパラメータ

chunk: 音声ファイルのchunk
channnels: 音声ファイルのチャンネル
rate: サンプリングレート
record_seconds: 録音する長さ(秒)
threshold: 録音を開始する音の大きさ(0~1)、雑音で録音スタートしないようにするため

###録音開始

```python
def start_record(self, dir_name = '../sound/')
```

dir_name: 音声ファイルの保存先ディレクトリ名
返却値: 保存されたファイル名(ディレクトリ名は省略)

###音声解析

```python
def analyze_voice(self, file_path)
```

file_path: 解析するファイル(例　'../sound/20201005220733.wav')
返却値: ファイルの音声認識結果文字列

#最後に
　Juliusはあまり精度はよくないですが、例えば「Hey Siri」などのような起動音を独自で作りたいといったときに役に立つのではないかと思います。私はJuliusに認識させたい起動音を何回も発声し、それらをリスト化することで誤差を吸収しました。対話アプリなどに役立てていただければ幸いです。

#2020年12月19日追記
バグを含んだ状態でアップしていたようです。
見ていただいた方々、ご迷惑をおかけしたこと、お詫び申し上げます。
修正版をgithubにアップしましたので、もう一度試していただければ幸いです。
また、それに合わせて記事も修正しました。（いろいろ説明が足りていない部分がありました）
今後ともよろしくお願いします。
【RSpec】プロフィール画像のアップロードのテストを書いてみました。

現在個人開発しているRailsアプリにはユーザーがプロフィール画像を設定できる機能があります。今回はその機能がちゃんと正しく機能しているかテストを書いてみたので、良ければ参考にしてみてください！

【環境】

- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- RSpec 3.9

##テストコード
システムスペックでテストを行っております。

```ruby:spec/system/upload_avatar_spec.rb

require 'rails_helper'

RSpec.describe'UploadImage', type: :system do
  let(:user) { FactoryBot.create(:user) }
  let(:item) { FactoryBot.create(:item, user_id: user.id) }

  #画像をアップロードして保存する
  def upload_user_avatar(user)
    valid_login(user)
    visit edit_user_path(user)
    attach_file 'user_avatar', "#{Rails.root}/spec/fixtures/images/test.jpg"
    click_on '保存する'
  end

  it 'user successfully upload image user#show' do
    upload_user_avatar(user)
    expect(page).to have_selector("img[src$='test.jpg']")
  end

  it 'user successfully upload image on item#show' do
    upload_user_avatar(user)
    visit item_path(item)
    expect(page).to have_selector("img[src$='test.jpg']")
  end
end
```
valid_loginメソッドは```spec/support/login_support.rb```に定義してます。
このフォルダに定義したメソッドはテスト時に呼び出すことができます。
私のアプリではログインした状態じゃないと、edit_user_pathにアクセスできないようになっているため、このコードを書いています。書かないと失敗します。（失敗しないといけない）

```ruby:spec/support/login_support.rb

module LoginSupport
  def valid_login(user)
    visit root_path
    click_link 'ログイン'
    fill_in 'session[email]', with: user.email
    fill_in 'session[password]', with: user.password
    click_button 'ログイン'
  end
end
```

順番に解説していきます。
まず、**FactoryBot**でuserとitemのテストデータを生成します。
（あらかじめ```spec/factries/```にテストデータを定義する必要があります。ここでは割愛させていただきます。）

画像をアップロードするという行為はどのブロックでも共通して行われるので、upload_user_avatarメソッドとしてまとめて定義してます。
このメソッドでは、ログインしてユーザーの編集ページにいき、attach_fileメソッドを使いテスト用の画像データをアップロードして保存しています。
あらかじめ```/spec/fixtures/images/```にテスト画像を用意する必要があります。
また、attach_fileメソッドの引数には f.file_fieldで生成されるinputタグのidを指定したらうまくいきました！（画像参照ください。生成されるHTMLはデベロッパツールから確認できます。）
![スクリーンショット 2020-10-05 231134.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/689a40ab-873b-a8e3-97b1-26b96d37cd8e.png)

今回は2つのテストを行っております。

1つ目は、画像がアップロードされたら、コントローラで指定されたリダイレクト先に画像データがあるか調べています。
have_selectorを使い、imgタグのsrc属性にtest.jpgの画像データが入っているか調べています。

2つ目もやっていることはほぼ同じです。同じ画像が投稿詳細ページでも使われているので、投稿詳細ページに移動して、have_selectorを使い、imgタグのsrc属性にtest.jpgの画像データが入っているか調べています。

##最後まで読んでいただきありがとうございます！
日々学習したことをアウトプットしてます！！感想やご指摘ありましたらコメントいただけると嬉しいです！！
LinuxでWi-Fi接続ができなくて悩んだときのログ

Raspberry Pi 4で2.4GHzネットワークには接続できるのに5GHzネットワークに接続できなくて悩んだときの記録。

`wpa_supplicant.conf` にSSIDとPSKを書いただけだと接続できず、エラーログは以下のような感じ。

```
Successfully initialized wpa_supplicant
wlan0: Trying to associate with SSID 'Buffalo-A-1234'
wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:24:a5:**:**:** status_code=16
wlan0: Trying to associate with SSID 'Buffalo-A-1234'
wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:24:a5:**:**:** status_code=16
wlan0: Trying to associate with SSID 'Buffalo-A-1234'
wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:24:a5:**:**:** status_code=16
wlan0: Trying to associate with SSID 'Buffalo-A-1234'
wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:24:a5:**:**:** status_code=16
```

`wpa_supplicant.conf` を以下のように書いたら接続できた。

```wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
	ssid="Buffalo-A-1234"
	key_mgmt=WPA-PSK WPA-PSK-SHA256
	psk="********"
	pairwise=CCMP
	group=CCMP
	proto=WPA2
	ieee80211w=1
}
```

5GHzネットワークを提供する無線APの暗号化を「WPA2-PSK/WPA3-SAE Mixed」にしていたのが接続に苦労した原因のようで、`key_mgmt=WPA-PSK-SHA256`が必須だったようです（参考資料：[wpa\_supplicant \- ArchWiki](https://wiki.archlinux.jp/index.php/Wpa_supplicant)）。
(Wordpress) MW WP Formで送信成功ページ、失敗ページからページ遷移に起きる不具合

##環境
page-contact.php
↓送信すると以下にページ遷移
page-success.php

##不具合
コンタクトフォーム(page-contact.php)から送信成功ページ(page-success.php)にページ遷移し、
もう一度コンタクトフォームに遷移しようとすると、送信成功ページ表示される

##原因
page-contact.phpからpage-success.phpにとばしていたが
page-success.phpにMWWPFormのショートコードを記述がなかったため、
ページ遷移は出来るが、MWWPFormの処理が行えてなかった。

##解決策
page-contact.phpで使用したショートコードをpage-success.phpでも表示させる
このままではpage-success.phpにもフォームが設置されてしまうので、
page-success.phpのCSSの該当箇所にdisplay:none；をかけて非表示にする。
本日の『railsチュートリアル』で詰まったところ(2020/10/05)

<h1>詰まったところ</h1>
<h2>1.4.1 インストールとセットアップ</h2>
･事象: 

```
$git add -A
```

でファイルが追加できない

･解決方法: 既にコマンドを一度打っていたため、変化点として出なかった。そのまま進めて問題なし。

･留意点: 各コマンドがローカルなのか、リモートなのかを意識しないと、何をやっているかを見失いそう。

<h2>1.4.3 Bitbucket</h2>

･事象:

```
$ git push -u origin --all
```
で差分が表示され、プッシュできない。

･解決方法: 

```
$ git push -f origin --all
```
で無理やりプッシュ(うろ覚え)

<h1>本日のまとめ</h1>
進捗: 1章 1.4読了

感想
･勉強のためにローカル開発環境で進めようかと思ったが、会社や別PCで続きの作業を行いたいときにそのまま再開できるという点で、クラウド環境は神。
･会社で勉強する場合、Qiitaの執筆までするのは憚れる。帰宅してから思い出す必要がある。ただし、Qiitaより勉強を進めることを優先。
･Qiitaでのコード挿入方法が分かった。多少見やすくなるはず。一度マークダウン記法をちゃんと勉強する必要あり。
[jQuery]入力フォームのバリデーション

##概要
チャットなどでメッセージを送る時に、フォームが空の状態で相手にチャットが送れないようにバリデーションを実装しました。
slackみたいに、初期状態ではボタンが押せない状態でメッセージが入力されるとボタンが押せるようになります。
送信後は、フォームが空になるのでボタンが再び押せなくなります。


####チャット送信フォーム

```index.html
 <div class="chat-form">
   <textarea id="message-input" placeholder="メッセージ入力"></textarea>
   <button id="sending-button" disabled onclick="$sendMessage">
      送信
   </button>
</div>
```

###jQueryの処理

```chat.js

//バリデーション
let sending = false;

$('#message-input').keyup(function () {
  const chatMessage = $(this).val().replace(/^\s+/, "");
  if (chatMessage.length > 0) {
    sending = true;
  $('#sending-button').prop('disabled', false).css({
    background: '#0a65cc',
   });
  } else {
   $('#sending-button').prop('disabled', true).css({
     background: '#ccc',
    });
  }
});


//メッセージ送信のajaxの処理
if (sending) {
  $.ajax({
  //ajaxの設定
  }).done(function () {
   sending = false;
   $('#sending-button').prop('disabled', true).css({
        background: '#ccc'
    });
  });
};

```

###解説


```js

$('#message-input').keyup(function () {
```
`keyup()`イベントでフォーム入力の変更を検知する

```js

const chatMessage = $(this).val().replace(/^\s+/, "");
```
フォームに入力した値を`val()`で取得して、先頭の空白は空文字に変換している

```js
if (chatMessage.length > 0) {
//文字入力がないと文字数が０のため、１文字以上入力を条件にする
    sending = true;
//ボタンが押せる状態となる
  $('#sending-button').prop('disabled', false).css('background', '#0a65cc');
  } else {
//文字入力がないとボタンを押せなくさせる
   $('#sending-button').prop('disabled', true).css('background', '#ccc');
  }
```

```js
//sendingがtrueの時にメッセージを送信する処理を実行する
if (sending) {
  $.ajax({
  //ajaxの設定
  }).done(function () {
//　送信後は処理されないようにfalseを設定
   sending = false;
// ボタンの色を変更し、再び押せないようにする
   $('#sending-button').prop('disabled', true).css({
        background: '#ccc'
    });
  });
};

```

初期状態の送信フォーム
![スクリーンショット 2020-10-05 17.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365177/38bf0a15-f87c-ed8b-51f2-fb883d553527.png)

空白で送られないように半角、全角スペース、改行のみだとボタンが押せないようにバリデーションされている状態

![スクリーンショット 2020-10-05 17.09.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365177/6a36da30-321a-c889-ce79-6c46c4cad0ef.png)

メッセージが入力されると、ボタンが押せるようになった状態
![スクリーンショット 2020-10-05 17.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365177/44cc3517-3d1d-24de-c1e9-542ec0b95b4c.png)


###終わりに
jQueryのバリデーションで検索するとプラグインなどで実装してることが多いので、また使うかもしれないのでメモとして残しています。
【Python超入門】リストとタプルの違いとは

Python始めたての頃につまずいた『リスト』と『タプル』の違いについてお話します。

元々C言語を初期に習っていた私は、配列に色んな種類があることに最初戸惑いました。
それぞれの仕様を理解すると、無駄に時間を取られたりしなくなるので、ぜひ知ってほしいです。

Pythonには、『リスト』と『タプル』というよく似たデータ管理の方法があります。
しかし、それらの`要素の書き換え`や`コードの記述方法`に微妙に違いがありますので、その違いについて説明していきたいと思います。

# リスト（list）とは
複数の要素を順番に並べて格納するためのデータ型です。
## 記述のしかた

```python:list1.py
$ a = [1,2,3,4,5]
$ a
[1,2,3,4,5]
```
このように、`[]`の中に要素を並べて記述をします。

## 要素の扱い方
これらの要素は書き換えすることができます。

```python:list2.py
$ a = [1,2,3,4,5] #リストを定義
$ a[1] #2番目の要素を表示
2
$ a[1]="two" #2番目の要素を"two"に書き換える
$ a
[1, 'two', 3, 4, 5]
```


# タプル（tuple）とは
基本的にリストと同様です。
しかし、最初に述べたように、要素の扱い方やコードの記述方法に違いがあります。

## 記述のしかた

```python:tuple1.py
$ b = (1,2,3,4,5)
$ b
(1,2,3,4,5)
```

先ほどのリストでは`[]`でしたが、今度は`()`の中に要素が記述されている点に注意です。

## 要素の扱い方
リストと同様に、要素の書き換えをしてみましょう。

```python:tuple2.py

$ b=(1,2,3,4,5) #タプルを定義
$ b
(1, 2, 3, 4, 5)
$ b[1] #2番目の要素を表示
2
$ b[1]="two" #2番目の要素を"two"に書き換える
Traceback (most recent call last):

  File "<ipython-input-9-6d86f5f6feb4>", line 1, in <module>
    b[1]="two"

TypeError: 'tuple' object does not support item assignment
```

やってみましたが、エラーが発生してしまいました。
このように、**タプルは要素の書き換えができません。**

タプルを連結して新しいタプルを作ることはリストと同様にできます。
しかし、タプル自体を変えているわけではないので可能なわけです。

```python:tuple2.py
$ b2 = b + (11,12) #タプル同士を連結
$ b2
(1, 2, 3, 4, 5, 11, 12)
```

## なぜ書き換えができないのか
リストに比べて自由度の低いタプルですが、書き換えができない利点があるから存在しています。
変更してはいけない重要なデータを扱っている時、タプルに入れておけば変更される心配はありません。

# まとめ
ちょっとした違いですが、把握していないとツボにはまってしまいます。しかし、知っておけば問題ないでしょう。
ちなみに、配列の種類はもっとあります。リスト型、タプル型、配列型、辞書型、集合型、array型の５つもあります。これだけあると使い方を覚えるのは難しいので、**型の違いによってエラーが出る可能性がある**ということだけは心に留めておいてください。そして、もし原因不明のエラーが出たら、型の仕様の違いを疑ってみる。それでいいと思います。

最後まで読んでいただきありがとうございました。
何か誤りがありましたら、遠慮なくご指摘ください。
【Java】オーバーロードとオーバーライド

オーバーロードとオーバーライドについてまとめます

#オーバーロード
名前は同じだが**シグニチャ**の**違う**メソッドを複数定義すること。
→名前は同じでも**メソッドとしては別物**

**※シグニチャとは**
・メソッド名
・引数リストの型
・引数の数
・引数の順番

**【オーバーロード時に考慮しないもの】**
・戻り値の違い
・引数の変数名
・アクセス修飾子の違い

例）

```java
int price(int a, double b){
   return a * b;
}
```

【オーバーロードするパターン】

```java
double price(int a){   //別メソッド扱いなので戻り値を変えても問題ない。シグニチャが異なっているのでオーバーロード 
  //処理
}

int price(double a, int b){  //引数の順番が逆→オーバーロード
  //処理
}

```

【**finalがついているメソッド**をオーバーロードすることも**可能**】

```java
final void price(){
   //処理
}

void prince(int a){  //finalメソッドもオーバーロード可能！別メソッド扱いだから。
  //処理
}

```


【オーバーロードにならないパターン】

```java
int price(int product, double tax){  //引数名はシグニチャではない。オーバーロードにならない
   //処理
}

```

#オーバーライド

**親クラス**を**継承**して**子クラス**を宣言する際に、**親クラスのメンバを子クラスで上書き**すること。


**【オーバーライドの条件】**
・シグニチャが同じであること
・**戻り値型**は親クラスのメンバと**同じ型**か**サブクラス型**であること
・**アクセス修飾子**は親クラスのメンバと**同じ**かより**緩い**ものを指定すること
・親クラスのメンバに**finalがついていない**こと
・throwsで宣言する例外は、スローする例外と同じ型かサブクラスであること

例）

```java
class Infant{
  protected void talk(){
     System.out.println("おぎゃあ");
  }
} 
```

【オーバーライドできるパターン】

```java
class Adult extends Infant {
  public void talk(){   //親クラスのtalkメソッドより緩いアクセス修飾子
    System.out.println("こんにちは");
 }
}

```

【オーバーライドできないパターン】

```java
class Adult extends Infant {
  void talk(){   //親クラスのtalkメソッドより厳しいアクセス修飾子
    System.out.println("こんにちは");
 }
}

class Adult extends Infant {
  void talk(String a){   //親クラスのtalkメソッドと異なるシグニチャ（オーバーロードになる）
    System.out.println("こんにちは" + a);
 }
}
```
EC2のリブートについて

## 勉強前のイメージ

rebootって、webの画面から「インスタンスの停止」ってやるだけじゃないの？

## 調査

### インスタンスリブート

#### 特徴

- グローバルIPアドレスが変わらない
	- 物理的に実行されるハードウェアが変わらないから

#### 実施方法

- webコンソールでの方法
	1. インスタンスにチェック
	2. 右クリック or アクション
	3. インスタンスの状態 → 再起動

- AWS CLIでの方法
	1. `$ aws ec2 reboot-instances --instance-ids [ インスタンスID ]`

- EC2のサーバでの方法
	1. `# reboot`

### システムリブート

#### 特徴

- グローバルIPアドレスが変わる
	- 物理的に実行されるハードウェアが変わるから
	- ElasticIPを使用することで防ぐことが出来る
- インスタンスストアのデータが消える

#### 実施方法

- webコンソールでの方法
	1. インスタンスにチェック
	2. 右クリック or アクション
	3. インスタンスの状態 → 停止
	4. インスタンスの状態 → 開始

- AWS CLIでの方法
	1. `$ aws ec2 start-instances --instance-ids [ インスタンスID ]`
	2. `$ aws ec2 stop-instances --instance-ids [ インスタンスID ]`

### リタイア

#### 特徴

- ハードウェアが故障し、運用できない際に出るアラート
- AWSから通知が来た、スケジュールの日以降は終了されてしまう

#### 実施方法

- webコンソールでの方法
	1. インスタンスにチェック
	2. 右クリック or アクション
	3. インスタンスの状態 → 停止
	4. インスタンスの状態 → 開始

- AWS CLIでの方法
	1. `$ aws ec2 start-instances --instance-ids [ インスタンスID ]`
	2. `$ aws ec2 stop-instances --instance-ids [ インスタンスID ]`

## 勉強後のイメージ

サーバの`reboot`と画面の`再起動`は一緒。
サーバの`shutdown→起動`と画面の`停止→開始`は一緒。
あまり今まで考えてrebootとかしてなかったけど、勉強になった。
リタイアの通知が来たときは、`停止→開始`をしないといけない。

## 参考

- [Amazon EC2のシステムリブートを経験して感じたこと](https://sole-color-blog.com/blog/428/)
- [EC2 メンテナンスで慌てないための 4 つの設計ポイント](https://blog.manabusakai.com/2014/09/ec2-design-pattern/)
- [AWSのEC2インスタンスリタイア通知が届いた時の対応](https://qiita.com/ishizukih/items/f4477acafe6940241e90#)
Rials6でJqueryの使い方


railsが5から6に変わって、仕様が変わったので
メモ書き代わりに投稿します。

導入はこちらのページから
https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker

Qiitaには必要な情報だけのった記事もあるので
そちらも見てください

# ファイルの準備

app/javascriptsにjsを作成して
packに使うためのリンクを作ります。

```js:app/aseets/javascript/test.js

//例としてtest.jsを作成します。コードを書きます。

$(function() {
    
  $("#sample").css("color", "red");

});
```

# リンクの作成

```js:app/aseets/javascript/packs/application.js
require("test.js")
//このコードを追記してtest.jsを読み込みます。
//""を忘れないようにしましょう
```

# Htmlの作成

```html:index.html
<h1 id="sample">Hello World</h1>
```

これでHello worldが赤くなりました。
ターミナル プロセスが起動に失敗しました: シェル実行可能ファイル "/usr/local/bin/zsh" へのパスが存在しません。

VSCodeを起動したときにzshが見つからないと出たときの対処法

ターミナル起動して下を実行

```
ln -s /bin/zsh /usr/local/bin/zsh
```
PHP　~個人的アウトプット用語集2~

# trim
前後に空白や改行を除去してくれます。
# nl2br関数
textareaから改行つきのメッセージを受け取ってもただの空白になってしまいます。
nl2brを使う事で改行の為のタグにしてくれます。
![スクリーンショット 2020-10-05 18.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/88c789a8-5a63-bce6-77d6-60f73406f15a.png)

# multiple
selectタグにmultipleと記述する事で、複数選ぶ事ができます。
その際で配列で送信されますので、colorsに[]をつけています。
![スクリーンショット 2020-10-05 18.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/83d43b60-0cc1-14b2-4946-16c347e57bf1.png)
# FILTER_DEFAULT, FILTER_REQUIRE_ARRAY
デフォルトのフィルターを使いつつ、配列で受け取りたいですをいう意味です。
![スクリーンショット 2020-10-05 18.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/caf8eded-8814-2caf-3f89-3c33173c6aa8.png)
# implode()
配列で指定された複数の文字列を連結するための関数になります。
第一引数で、連結文字
第二引数で、連結したい文字列（配列であること）
![スクリーンショット 2020-10-05 18.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/dde9758e-adc2-7023-b307-510a842f0f79.png)
# 条件演算子
[解説]
colorsが空の場合にNone selectedを返します。
そうでない場合
implodeで配列を,で連結します。
![スクリーンショット 2020-10-05 18.57.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/657a667f-ac0e-bd7c-9e80-d6e1286eafc2.png)
バイナリファイルをWordで解析する(ファイル修復コンバーター)

環境
Windows10
Word2016
ExcelVBAで作成したバイナリファイル

#概要
　バイナリファイルをWindowsOfficeのみで読める方法を見つけました。
　必要なものはWordだけです。

　一太郎ファイルをWordで読む方法はこちら↓
https://qiita.com/harryyuni/items/7172efe01fc061337bd0
#使ったバイナリファイル
 バイナリファイルはExcelVBAのADODB.Streamを使用して作成しました。本筋から外れますが，以下のようなプロシージャです。

```vb:ExcelVBA
Sub output_binarydat()
    Dim wShell As Object
    Set wShell = CreateObject("wscript.shell")
    Dim dtpPath As String
    dtpPath = wShell.SpecialFolders.Item("Desktop")
    Dim txtFilePath As String
    txtFilePath = dtpPath & "\test.txt"
    
    Dim txtInfo As String
    Dim adoDbStream As Object
    Set adoDbStream = CreateObject("ADODB.Stream")
        With adoDbStream
        .Open
        .LoadFromFile txtFilePath
        txtInfo = .ReadText
        .Close
        End With
    
    Dim txtByte() As Byte
    txtByte = txtInfo
    Dim binaryFilePath As String
    binaryFilePath = dtpPath & "\unicode.dat"
        With adoDbStream
        .Type = 1
        .Open
        .Write txtByte
        .SaveToFile binaryFilePath, 2
        .Close
        End With
    Set adoDbStream = Nothing
End Sub
```
　文章は，一太郎のテンプレートをテキストファイルにコピペしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/a48a8afc-ca5e-9821-399e-8208b67dfdae.png)

　これを前記プロシージャでバイナリに変換したのがこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/55beb440-3ea3-c5b5-f0fc-cfdf41c53cd7.png)
いい具合に文字化けしていますね。もちろん，Wordで普通に開いても文字化けしています。

#解析方法
[ファイル]→[開く]→[参照]でダイアログボックスを開きます。
![2020-09-05 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/0b6ca3a9-5a5a-b679-2f36-3f96ec51a7dd.png)



　ファイル名の右の拡張子の選択リストボックスから，
「ファイル修復コンバーター(*.*)」又は
「recover text from any file(*.*)」を選択します。
（環境によって表示が異なるようです。）
![2020-09-05 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/0b5b2ab6-9dfb-01be-8880-d43c7edc9d2c.png)

　バイナリファイルを選択して[開く]
![2020-10-05 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/6334ff35-7409-9f9a-b619-d8580ad71751.png)



「修正個所の表示」というダイアログボックスが表示されますが，[閉じる]を押してください。
![2020-10-05 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/dfbe26f6-d68a-a52e-154f-74a88969f176.png)

　復元されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/72209754-2b86-27c5-cf5e-f3375af23042.png)

#まとめ
　もちろん，全てのバイナリファイルが解析できるとは言いません。
　ただ，officeのマクロなどで文字列をバイナリにして保存されたファイルの中には，Wordで開けるものもあるようです。
　一太郎ファイルもバイナリファイルも専用のアプリなしで開けるなんて，すごいぞ，ファイル修復コンバーター！
　ぜひ活用してみてください。
ThinkPad E14 に Ubuntu20.04 を導入


WSL2 での Docker のつらみから Linux 機を作ろうと ThinkPad E14 を購入した。
問題なく Ubuntu を導入できたので共有。

## マシンスペック

- Lenovo ThinkPad E14
- CPU: Intel Core i5-10210 @ 1.60Ghz
- RAM: 8GB
- OS: Windows 10 Home 64bit

## Ubuntu のイメージをダウンロード

[Ubuntu の入手 | Ubuntu Japanese Team](http://ubuntulinux.jp/download)より iso をダウンロード。

## Ubuntu のライブ USB の作成

[Rufus](https://rufus.ie/)を用いてライブ USB を作成。USB メモリは 16GB のものを使ったが、iso のサイズは 2.6GB なので、4GB でもよさそう。

USB をセットした後 rufus を起動、
**選択**より iso イメージを選択、パーティション構成は**GPT**、ターゲットシステムは**UEFI(CSM 無効)** を選択した。

## BIOS 設定

再起動後、Lenovo のロゴが表示されている画面において F1 を押し、BIOS 設定画面に入る。
Security -> **SecureBoot を OFF** にしておく。

## Ubuntu を立ち上げ

再び再起動後、Lenovo のロゴが表示されている画面において F12 を押し、ブート設定画面に入る。
**USB:....**を選択し、**ubuntu**を選択。

しばらくするとインストール画面が表示される。

## インストール後

その後は特に問題らしいことは起きていない。マウスパッドやトラックポイントも認識されている。
TLP 等をセットアップして好きなように使える。

マシンとの相性等が気になる人がいると思うので、20.04は普通に動きましたという共有でした。
Iｆによる分岐かSelectか

２つならifの方がよい

例
If a = 1 Then
1111111
Else
If a = 2 Then
2222222
Else
If a = 3 Then
・・・


数個にわたって場合分けを行うときに使う。


例
Select Case 場合分け用の変数など
　Case　範囲１
　　範囲１の場合に実行させたい命令ブロック
　Case　範囲２

③

　ＦＯＲ～ＮＥＸＴ文　：指定回数分，繰り返し計算を実行

　　　ＦＯＲ　ループ変数　＝初期値　ＴＯ　最終値　［ＳＴＥＰ　増分値］

　　　　繰り返される　　　　　　　　　　　　　→ループ変数を初期値から増分値ずつ増し，
　　　　ステートメントブロック　　　　　　　　　　最終値になるまで繰り返す。

　　　ＮＥＸＴ　ループ変数
　　範囲２の場合に実行させたい命令ブロック
　Case Else
　　全て（範囲１，２）に当てはまらなかった場合の命令ブロック
End Select

ＦＯＲ　ｉ＝１　ＴＯ　１００
　　　　　　　　　　　　ＦＯＲ　ｊ＝１　ＴＯ　１０
　　　　　　　　　　　　　　　　ＦＯＲ　ｋ＝１　ＴＯ　５０
　　　　　　　　　　
　　　　　　　　　　　　　　　　ＮＥＸＴ　ｋ
　　　　　　　　　　　　　　　　ＦＯＲ　ｍ＝１　ＴＯ　２０

　　　　　　　　　　　　　　　　ＮＥＸＴ　ｍ
　　　　　　　　　　　　ＮＥＸＴ　ｊ
　　　　　　　　　ＮＥＸＴ　ｉ
【Java Silver】クラス変数インスタンス変数・ローカル変数・とは何か

インスタンス変数・ローカル変数・クラス変数の違いについてまとめます。



##static変数（クラス変数）
- **static**で宣言する変数のこと
- クラスの全てのインスタンスに共通する値を持つ。クラスにつく形で値を持つので**クラス変数**ともいう
- クラス変数、クラスメソッドにアクセスするには**「クラス名.フィールド」**と書く必要がある
-  **初期化していなくても**、**インスタンス生成を行なっていなくても**、**デフォルト値**で初期化する

##インスタンス変数
- **クラスの直下**、**メソッドの外**に定義する変数
- **初期化していなくても**、**インスタンス生成時**に**デフォルト値**で初期化する
- 同名のローカル変数がある時、「this.フィールド」、または「インスタンスを格納している変数名.フィールド」でアクセスする

※thisとは：そのクラスのオブジェクト自身のことをさす

##ローカル変数
- **メソッド内**で宣言する変数のこと(メソッドの中の仮引数または引数として使われる)
- **インスタンス変数、クラス変数と同名**のローカル変数を定義しても問題ない！！！
- 同名のローカル変数がある時、「this.フィールド」でインスタンス変数を表す。クラス変数は「クラス名.フィールド」で表す
- **var**による型推論ができるのはローカル変数のみ
- **初期化されていないローカル変数**は、参照すると**コンパイルエラー**

##コードで確認

```java
public class Main{
 public static void main(String[] args){
  Party P1 = new Party();
  Party P2 = new Party();
  Party.budget = 10000;
  
  P1.participants = 5;
  P1.remain();  //budgetは9500として出力
  
  System.out.println(Party.budget); //9500と出力
  System.out.println(P2.budget); //9500と出力
  
  P2.participants = 10;
  P2.remain();  //8500と出力
  
  System.out.println(Party.budget);  //8500と出力
  System.out.println(P1.budget);   //8500と出力
 }
}



class Party {
   int participants; //インスタンス変数
   static int budget;  //static変数（クラス変数）

   void remain(){
       int expense = 100 * participants;  //ローカル変数
       budget -= expense;
       System.out.println(budget);
   }
}
```

**・インスタンス変数と同じ名前のローカル変数**を持たせる場合

```java
public class Main{
 public static void main(String[] args){
  Party P1 = new Party();
  Party P2 = new Party();
  Party.budget = 10000;
  

  P1.remain();  //budgetは8000として出力
  
  System.out.println(Party.budget); //8000と出力
  System.out.println(P2.budget); //8000と出力
  

  P2.remain();  //6000と出力
  
  System.out.println(Party.budget);  //6000と出力
  System.out.println(P1.budget);   //6000と出力
 }
}

 class Party {
   int participants; //インスタンス変数
   static int budget;  //static変数（クラス変数）

   void remain(){
       int participants = 20;  //インスタンス変数と同名のローカル変数
       System.out.println(participants);
       System.out.println(this.participants);  //thisを使うとインスタンス変数にアクセスできる
       budget -= participants*100;
       System.out.println(budget);
   }
 }  

```
JWTで使用する鍵の長さについて

Auth0の[公式サイト](https://auth0.com/blog/brute-forcing-hs256-is-possible-the-importance-of-using-strong-keys-to-sign-jwts/)に以下の記述があります。

> Security Concerns and Recommendation
Let's take another look at the keys we used to generate the tokens that were cracked easily. What are the key sizes? The first key, Sn1f is 32-bit.

> 1 character = 8 bits

> The second key, secret is 48-bit. This is simply too short to be a valid key. In fact, the JSON Web Algorithms RFC 7518 states that a key of the same size as the hash output (for instance, 256 bits for "HS256") or larger MUST be used with the HS256 algorithm.

> I therefore recommend that anyone trying to generate a JSON Web token and signing them with HS256 to use a properly sized secret key. Auth0 secret keys are 512 bits in length and not susceptible to this type of brute force attack. Additionally, Auth0 allows you to easily sign your JWTs with RS256.

要約すると、ブルートフォースアタックに対処するためにハッシュ出力と同じサイズ（たとえば、「HS256」の場合は256ビット=32文字）以上のキーをHS256アルゴリズムで使用する必要があるとのことです。
auカブコム証券のkabuステーションAPIを使ってみる

#はじめに
金融商品の取引API公開は、Bitcoinなどの仮想通貨分野ではずいぶんと前から様々な事業者にて行われていましたが、株やETFにおいてはまだそれほど多くはないと感じています。
そんな中、auカブコム証券がREST形式に対応した取引APIを公開した為、使ってみました。

#環境
- Windows10
- Python3.8.6


#事前準備

kabuステーションAPIの利用にあたってはauカブコム証券に口座を開設済みであり、かつFintechプラン以上のプランに加入している必要があります。
その為、口座を持っていない方が利用を開始するには以下の手順を実行する必要があります。詳しい手順は[こちら](https://kabucom.github.io/kabusapi/ptal/howto.html)を参考ください。

1.auカブコム証券にて口座開設を行う
2.「Fintechプラン」もしくは「Premiumプラン」に加入する
3.「kabuステーションAPI」の利用設定を行う
4.「kabuステーション」を自身のPCへインストールする
5.「kabuステーション」の「APIシステム設定」にて「APIを利用する」にチェックを入れ、APIパスワードとソフトリミットを設定する
6.「kabuステーション」を再起動し、5の設定を反映する

#トークン取得

各種APIリクエストを行うにあたってはリクエストヘッダーに事前に取得したトークンを指定する必要がある為、まずはそのトークンを取得します。
トークン取得の際、前項の事前準備5にて設定したAPIパスワードが必要となりますが、今回は環境変数に入れておきます。

```python
import os
import json
import requests

API_URL = "http://localhost:18080/kabusapi"
API_PASSWORD = os.environ["API_PASSWORD"]

def get_token():  

    URL = API_URL + "/token"
    
    headers = {"content-type": "application/json"}
    payload = {"APIPassword": API_PASSWORD}

    try:
        response = requests.post(URL, data=json.dumps(payload).encode("utf8"), headers=headers)  
    except Exception as e:
        print (e)
    
    return json.loads(response.text).get("Token")

```

#時価情報の取得

任意銘柄の時価情報を取得します。
レスポンスには他にも詳細な板情報等が含まれています。
ちなみにsymbolを101に指定すると日経平均株価が取得出来ます。

|変数 |説明 |
|--- |--- |
|token |前項で取得したトークン |
|symbol |取得したい銘柄コード |
|exchange |取得したい市場コード (1が東証) |



```python

def get_price(token):

    symbol = "9433" 
    exchange = "1"	
    URL = API_URL + "/board/" + symbol + "@" + exchange

    headers = {
        "content-type": "application/json",
        "X-API-KEY": token
    }

    try:
        response = requests.get(URL, headers=headers) 
    except Exception as e:
        print (e)
    
    return json.loads(response.text).get("CurrentPrice") 
```

#その他
[リファレンス](https://kabucom.github.io/kabusapi/reference/index.html)に他様々なリクエスト方法が記載されていますので、実行したい操作がある方はこちらを参照すると良いです。
APIが使用可能になるまでの事前準備がありますが、それさえ済んでしまえばAPIリクエスト自体は特に難しくないように思いました。
このようなリソースは日本にはまだまだ少ないと感じてますので、仮想通貨分野のようにオープン化が進むと良いですね。
【GAS】数値型の二次元配列を宣言したい

## 概要
スプレッドシートから数字を受け取って、配列にバンバン足し込んでいきたい時、宣言した空の配列に足しても数字として扱われず計算されない。

最初から数値型で二次元配列を宣言したいな～って話。

## ネタばれ
最初から数値型で宣言する方法が分からなかったので、要素すべてに「0」の入った二次元配列を作る形に着地^^;

割とスマートに記述できた（と思う）ので、メモがてら投稿。

※ちゃんとした方法があるのかもしれないけど、無教養なため今回の方法で解決（笑）
## とりま力技ならこんな感じ？

```javascript
function arrays() {
  
  //５×３の要素すべてにゼロが入った配列
  var arrays = [[0,0,0,0,0], 
                [0,0,0,0,0],
                [0,0,0,0,0]];
  
  //出来栄えを確認
  Logger.log('\n', arrays, '\n');
  
  //全ての要素に１を足してみる
  for(var i=0; i<3; i++){
    for(var j=0; j<5; j++){
      
      arrays[i][j] += 1;
      
    }
  }
  
  //数値型なので足し算OK！
  Logger.log('\n', arrays);
  
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/476c689a-04e2-23aa-2f83-90ba3bd54d5b.png)
要はこう言う事なんだけど、なんかカッコよくないし、要素数が多い時の記述が面倒臭そう。
## 成功例の前の失敗例
・空の配列作成 `var array = Array(5);`
・全ての要素にゼロ `array.fill(0);`
・別の配列にプッシュ `arrays.push(array);`
で行けんじゃね？と思って書いたのがコチラ。

```javascript
function arrays() {
  
  var arrays = [];
  var array = Array(5).fill(0);
  
  for(var k=0; k<3; k++){

    arrays.push(array);

  }
  
  Logger.log('\n', arrays, '\n');
  
  for(var i=0; i<3; i++){
    for(var j=0; j<5; j++){
      
      arrays[i][j] += 1;
      
    }
  }
  
  Logger.log('\n', arrays);
  
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/8a12e1df-509e-1426-b4cd-b1c73f772f52.png)
出来上がりの見た目だけは良かったんだけど、全ての要素に１を足した時の挙動が変。なぜか全ての要素に３回ずつ足されてる？？？

同じ配列が３回並べて表示されてるだけのような・・・次元が歪んでる。
## 成功！
だったら、配列の宣言もfor文の中に入れて、繰り返しの度に再宣言させたらどうだろう。

```javascript
function arrays() {
  
  var arrays = [];
  
  for(var k=0; k<3; k++){
    
    var array = Array(5).fill(0);
    arrays.push(array);
    
  }
  
  Logger.log('\n', arrays, '\n');
  
  for(var i=0; i<3; i++){
    for(var j=0; j<5; j++){
      
      arrays[i][j] += 1;
      
    }
  }
  
  Logger.log('\n', arrays);
  
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/0d5f8881-3927-5cb7-b5bb-35749fbdf3b5.png)
上手く行ったみたい^^)b
## まとめ
**「x個」×「y個」の配列を持った数値型の二次元配列を宣言する**、たったひとつの冴えたやりかたは・・・

```javascript
var arrays = [];
  
for(var i=0; i<y; i++){
    
  var array = Array(x).fill(0);
  arrays.push(array);
    
}
```
たったひとつとも、冴えてるとも思わないけど、結構シンプルに仕上がったと思う（自画自賛）。

### おしまい
Amplify,GraphQL,AppSyncでカスタムリゾルバーを作成して簡単なmutationを行う

# やりたいこと
- カラムの値をインクリメントしたい。

# 前提
- 環境はAmplify,GraphQL,AppSync,DynamoDBを使っている。

# 参考記事
こちらのドキュメントの「Create upvotePost and downvotePost Mutations (DynamoDB UpdateItem)」をセクションを読んだ。

* [Tutorial: DynamoDB Resolvers - AWS AppSync](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-resolvers.html#create-upvotepost-and-downvotepost-mutations-ddb-updateitem)


# 手順1「Schemaに追記」
AWS AppSyncのコンソール画面 > Schema > 「type Mutation」にリゾルバを追記する > 保存

例えば「incrementCount」を追加するならこのように書く。

```
type Mutation {
	incrementCount(id: ID!): Post
	createPost(input: CreatePostInput!, condition: ModelPostConditionInput): Post
	updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post
	deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post
}
```

# 手順2「アタッチ」
ドキュメントを読んでください。

```
In the Data types pane on the right, find the newly created upvotePost field on the Mutation type, and then choose Attach.

In Data source name, choose PostDynamoDBTable（選択できるテーブル名は人によって違う）.
```

# 手順3「リクエストマッピングテンプレートの修正」

AWS AppSyncのコンソール画面 > Schema > 画面右のResolverからMutationセクションにある「incrementCount」を選択 > リゾルバー編集画面 > 編集後、保存。

リクエストマッピングテンプレート（DynamoDBへの命令？）、レスポンスマッピングテンプレート（DynamoDBからのレスポンス）を編集できる。テンプレートはJSON形式。

ここではリクエストマッピングテンプレートを下に示した内容で上書きする。

例えばups,versionカラムをそれぞれ1だけインクリメントするテンプレート。

```
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
        "expression" : "ADD ups :plusOne, version :plusOne",
        "expressionValues" : {
            ":plusOne" : { "N" : 1 }
        }
    }
}
```

# 手順4「mutation.jsを編集」

```mutation.js
export const incrementCount = /* GraphQL */ `
  mutation IncrementCount(
    $id: ID!
  ) {
    incrementCount(id: $id) {
      id
    }
  }
`;
```

# 手順5「インクリメントするコードを追記」

importのパスはそれぞれの環境に合わせて修正してください。

idが「SAMPLE ID」のレコードのカラムups,versionを1だけインクリメントする例。

```js

import Amplify, { API, graphqlOperation } from "aws-amplify";
import { incrementCount } from "../graphql/mutations";

API.graphql(graphqlOperation(incrementCount, { id: "SAMPLE ID"}))
```
なぜ「スプリントゴール」は必要か？

## はじめに

これまでスクラムでの開発業務を2年以上の間で3チームほど経験してきていますが、
経験上スプリントゴールというものを設定したことがありませんでした。
そんな中、社外のアジャイル・スクラム研修を受講する機会があり、その中でスプリントゴールの設定について話を聞きました。そこで今までスプリントゴールについて勘違いをしていたことと、スプリントゴールを設定する重要性を認識できたので、そのことについてここでまとめたいと思います。

## 今まで勘違いしていたスプリントゴール

これまで私は「スプリントゴール = 今スプリントで予定した全PBIを完了・受入してもらうこと」と認識していました。
つまり、これまでは予定したPBIを問題なく完了させるために、予定したタスクをすべて完了させることに全力を注いでいました。

## なぜ、「スプリントゴール = 今スプリントで予定した全PBIを完了・受入してもらうこと」ではいけないのか？

それは、[アジャイルソフトウェア宣言の背後にある原則](http://agilemanifesto.org/iso/ja/principles.html)の冒頭に答えは書かれています。
>顧客満足を最優先し、
価値のあるソフトウェアを早く継続的に提供します。

要するにアジャイルにシステムを開発するということの目的は、ユーザーにとって価値のあるソフトウェアを(早く継続的に)提供することであり、開発メンバーが計画したタスクを全て完了させることや、スプリントで予定したPBIをプロダクトオーナーに受け入れてもらうことは、その目的を達成するためのプロセスの1つでしかありません。

## 正しいスプリントゴールとは何か

先ほども記載しましたが、アジャイルにシステムを開発するということの目的は、ユーザーにとって価値のあるソフトウェアを(早く継続的に)提供することです。
したがって、スプリントの成果として(リリースするか否かは関係なく)何かしらの価値をユーザーに提供している(もしくは、提供できる状態である)ことが求められます。
要するに**「このスプリントが終了したときにユーザーに対してどのような価値を提供できるか？」をスプリントゴールに設定すべき**なのです。

## 正しいスプリントゴールを設定することによる効果

正しいスプリントゴールを設定することで次のような効果が得られると考えられます。

### 開発メンバーが目指すべきはタスクの完了や予定していたPBIを全て受け入れてもらうことではなく、ユーザーに価値を提供することであることを明示することができる

こちらについてはこれまで記載してきた通りですが、スプリントゴールを明示することでアジャイルの元々の目的である「ユーザーに価値を提供する」ことを意識させることができます。

### 開発メンバーがタスクを完了した先にあるものを明示することで、開発に対するモチベーションを上げることできる

今担当しているタスクが最終的にユーザーへ対して与えることができる価値を知れることによって、開発のモチベーションに繋げることができます。
自分の作ったものでユーザーを喜ばせる姿を想像することが、どれだけモチベーションに繋がるかはもはや説明不要だと思います。

### デイリースクラムで着目すべきポイントが明確になる

デイリースクラムをする上でよくあるあるなパターンとして聞かれるのが、デイリースクラムがただの進捗共有になってしまうということです。
[スクラムガイド](https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf)の中ではデイリースクラムについて以下のように書かれています。
>開発チームはデイリースクラムを使って、スプリントゴールとスプリントバックログの進捗を検査する。
デイリースクラムは、開発チームがスプリントゴールを達成する可能性を最適化する。開発チームは、自己組織化チームとしてスプリントゴールを達成し、スプリント終了までに期待されるインクリメントを作成できるかを毎日把握しなければいけない。

つまり、開発チームはデイリースクラムの場では、このままスプリントを進めるとスプリントゴールを達成することができるのか、また、スプリントゴールを達成するために障害となっていることや困難になっていることが無いかを毎日検査する必要があります。

このようにスプリントゴールを設定し、デイリースクラムを運営することにより、ただの進捗共有で終わってしまうデイリースクラムは避けることができます。

### スクラムチーム全体で目標を意思統一できる

一般的にプロダクトオーナーはビジネス側の立場として、開発チームへお願いをするのに対し、開発チームはどうしても作ることに注力してしまい、ビジネス面での興味が薄れてしまいます。
もう何度も記載していますが、これではアジャイルの目的から逸れてしまい、アジャイルに開発する意味が無くなってしまいます。
そのためにもスプリントゴールという目標をスクラムチーム全体で共有する必要があります。

### 開発チームがスプリントゴール達成のためにより良い方法やアイデアは無いか考えるようになる

今スプリントで予定した全PBIを完了・受入してもらうことのように誤ったスプリントゴールを設定してしまうと、ただ設定されたPBIの受入条件を満たすことに全力を注いでしまい、より良いものを作ろうというマインドが働きづらくなってしまいます。
逆に正しいスプリントゴールを設定すると、そのゴール達成に向けた良い方法や新しいアイデアが開発チームからも出るようになります。

## スプリントゴールの設定の仕方

どのようなスプリントゴールを設定するかについては、先ほど記載した通り**「このスプリントが終了したときにユーザーに対してどのような価値を提供できるか？」**をテンプレートに毎スプリントでゴールを設定すればよいです。

要するに決めることは、
1. **どのユーザー**に価値を与えたいか
2. そのユーザーに**どのような価値**を与えたいか

の2つです。これだけ簡単なテンプレートで多くの効果が得られるのがスプリントゴールの役目です。

## 最後に

チームによっては、ユーザーを直接的に幸せにするようなモノを作ることがないスプリントを経験することがあるかと思います。
しかし、その先には必ずユーザーにとっての価値があるはずです。
例えば、今自分のチームではシステムの脆弱性対策をしていますが、確かに脆弱性を対策することでユーザーが何か幸せを感じたり、使いやすさを直接的に感じる訳ではありません。しかし、その脆弱性対策にもその先には「ユーザーがより安全にこのシステムを使うことができる」という素晴らしい価値があります。
我々が作り出そうとしているのは必ずしもユーザーが直接感じる価値ではありませんが、必ずユーザーにとって価値になっているものを作り出そうとしています。
そんなことをスプリントゴールとして設定するだけで、開発していく上でのモチベーションが上がると思いませんか？

是非スクラムで開発をしているのに正しいスプリントゴールを設定できていなかったという方、チームのみなさんもこれからスプリントゴールを設定してみてはいかがでしょうか。
OnVUE.appでMission Controlが使えなくなったあなたへ

先日， Az-900の試験（pearson VUE提供）を自分のPCで受験しようとしたところ様々なトラブルに見舞われたので忘備録として残しておきます．


## 環境
Macbook pro 2019
OSX Catalina 10.15.7

## トラブル1 なんにもしてないのにOnVUE.appが終了する．
原因はkarabinerというキーボードカスタマイズアプリだったようです． アンインストールしたら解決しました．

## トラブル2 なんにもしてないのに入力ができなくなる
これは原因がわかりません． カスタマーサポートに問い合わせた結果， 再試験になりました．

## トラブル3 なんにもしてないのにMission Controlが使えなくなる．
再起動してもジェスチャーが反応しなくなりました．
下記リンクの記事の通りですが，
http://blog.brianbeach.com/posts/2020-02-17-pearson-onvue-mission-control/

Mac OS X（MCX）用のManaged Clientを使用して、OnVUE.appがMissionControlを無効にしているようです。次のコマンドを実行することで無効になっている事を確認できます．

```
$ defaults read com.apple.dock mcx-expose-disabled
```
これは、TRUEを示す1を返します。有効にするには、値を削除し、次のコマンドを実行してDockサービスを再起動します。

```
$ defaults delete com.apple.dock mcx-expose-disabled
$ killall Dock
```
以上が完了すると、Mission Control（およびApp Expose）の両方が再び機能しました。

## 結論
オンライン試験はWindows使おう
dockerについて学んだことをとにかく書いていく(2つ目)

# 前回
[dockerについて学んだことをとにかく書いていく\(1つ目\) \- Qiita](https://qiita.com/taninao1122/items/e2ec6509a2fac2cfd9fd)

# 次回

# 参考図書
[Docker/Kubernetes 実践コンテナ開発入門 \| 山田 明憲 \| コンピュータ・IT \| Kindleストア \| Amazon](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2-ebook/dp/B07GP1Q3VT/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3M8BPC6XQJ2SA&dchild=1&keywords=docker+kubernetes&qid=1601461470&sprefix=docker+%2Caps%2C263&sr=8-2)

# イメージのビルド
## コマンド

```
docker image build -t イメージ名[:タグ名] Dockerfile配置ディレクトリのパス
```

## -fオプション
- `docker image build`コマンドはデフォルトでDockerfileを探しに行く
- しかし、そうでない名前のDockerfileを利用したい場合は-f オプションを利用
- 例えばDockerfile-testという名前のDockerfileを使うなら以下のようになる

```
docker image build -f Dockerfile-test -t example/echo:latest
```
# イメージの検索
## コマンド
docker searchコマンドを利用すると、Docker Hubのレジストリに登録されているレポジトリを検索

```
docker search [options] 検索キーワード
```

## --limit [表示数]
`--limit`オプションを使用するとsearchコマンドで表示する件数を制限する

```
$ docker search --limit 5 mysql
NAME                  DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                 MySQL is a widely used, open-source relation…   10014               [OK]                
mysql/mysql-server    Optimized MySQL Server Docker images. Create…   733                                     [OK]
mysql/mysql-cluster   Experimental MySQL Cluster Docker images. Cr…   76                                      
bitnami/mysql         Bitnami MySQL Docker Image                      45                                      [OK]
circleci/mysql        MySQL is a widely used, open-source relation…   19                                  
```

# イメージのタグ付け
## イメージへのタグ付け
Dockerのイメージタグはある特定のイメージIDを持つDockerイメージを識別しやすくするために利用
- イメージID = Dokcerイメージのバージョン 

latestの特定の地点をバージョン名等でタグをつけて、いつでも特定のバージョンのdockerイメージを取得できるようにする。

```
docker image tag 元イメージ名[:タグ] 新イメージ名[:タグ]
```

例:example/echoのlatestに0.1.0のタグをつける

```
docker image tag example/echo:latest example/echo:0.1.0
```

(出力)
```
$ docker image ls

REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
example/echo                                  latest              4bc94bb3c1af        3 days ago          750MB
example/echo                                  0.1.0               4bc94bb3c1af        3 days ago          750MB
```


# Dockerコンテナの操作
## docker container restart コンテナの再起動
```
docker container restart コンテナIDまたはコンテナ名
```

# dokcer container rm コンテナの破棄
```
docker container rm コンテナIDまたはコンテナ名
```

# docker container cp ファイルのコピー
## コンテナ内　→　ホスト

```
docker container cp [options] コンテナIDまたはコンテナ名:コンテナ内のコピー元　ホストのコピー先
```

## ホスト　→　コンテナ内

```
docker container cp [options] ホストのコピー元 コンテナIDまたはコンテナ名:コンテナ内のコピ-先
```


# 運用管理向けコマンド
##　prune　破棄

- `docker container prune`では実行していないコンテナを一括で削除することができる
- 実際に停止したコンテナの多くは不要であることが多いので定期的に削除するのが良い

```
docker container prune [オプション]
```

イメージを一括で削除したいとき

```
docker image prune [オプション]
```

利用していないDockerコンテナやイメージ、ボリューム、ネットワークといったすべてのDockerリソースを一括で削除

```
docker system prune [オプション]
```
国勢調査2020の回答状況を可視化

# はじめに

![kokusei2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/9c2016fe-695d-136e-00d4-b96a67da7d34.png)

[国勢調査2020](https://www.kokusei2020.go.jp/internet/)の都道府県別回答状況のExcelをスクレイピングしてインターネット回答率・郵送回答率を可視化

# スクレイピング
```python
import requests
from bs4 import BeautifulSoup

import re

from urllib.parse import urljoin

url = "https://www.kokusei2020.go.jp/internet/"

r = requests.get(url)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

links = {}

for i in soup.find_all("span", text="Excel"):

    link = urljoin(url, i.find_parent("a").get("href"))

    m = re.search("census_answers_(pref|city)_\d{6}.xlsx", link)

    if m:
        links[m.group(1)] = link

links
```
# 都道府県別
```python
import pandas as pd

df_pref = pd.read_excel(
    links["pref"],
    index_col=[0, 1],
    header=None,
    skiprows=9,
    usecols=[1, 2, 3, 4, 5, 6, 7],
    names=["コード", "都道府県", "H27世帯数", "ネット", "郵送", "ネット率", "郵送率"],
)

df_pref["回答数"] = df_pref["ネット"] + df_pref["郵送"]

df_pref["ネット率"] *= 100
df_pref["郵送率"] *= 100

df_pref["回答率"] = df_pref["ネット率"] + df_pref["郵送率"]

df_pref.to_csv("pref.csv", encoding="utf_8_sig")
```

# 市町村別
```python
df_city = pd.read_excel(
    links["city"],
    index_col=[0, 1, 2],
    header=None,
    skiprows=9,
    usecols=[1, 2, 3, 4, 5, 6, 7, 8],
    names=["コード", "都道府県", "市区町村", "H27世帯数", "ネット", "郵送", "ネット率", "郵送率"],
)

df_city["回答数"] = df_city["ネット"] + df_city["郵送"]

df_city["ネット率"] *= 100
df_city["郵送率"] *= 100

df_city["回答率"] = df_city["ネット率"] + df_city["郵送率"]

df_city.to_csv("city.csv", encoding="utf_8_sig")

df_city
```

# 可視化
```python
import matplotlib.pyplot as plt
import seaborn as sns

sns.set()

import japanize_matplotlib

# 解像度
import matplotlib as mpl

mpl.rcParams["figure.dpi"] = 200

df1 = df_pref.sort_index(ascending=False).reset_index(level="コード", drop=True)

df1.loc[:, ["ネット率", "郵送率"]].plot.barh(stacked=True, figsize=(5, 10))

plt.legend(bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0, fontsize=8)

plt.savefig("01.png", dpi=200, bbox_inches="tight")
plt.show()
```
![pref.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/d17b87d6-580c-ce0e-2b78-aa88b81c1db0.png)
AI学習のためのPython学習計画

# 背景と目的
- <h5>AIを勉強するための一番最初のスタートとなる記事です　</h5>
  学びたいと思いつつ何をしたらいいのかわからなかったのでやることを調べてまとめた記事です。

- <h5>ちゃんとAIが勉強できるように計画を立てる</h5>
方向性を間違えて明後日の方向に勉強してしまっては勿体無いので、まずはどういう勉強をしたらいいのかwebベースで調べて、計画します。

# 結論
<ul>
<li>下記サイトが非常によくまとめられているので<b>下記サイトをシラバスとして取り扱う</b>
https://blog.kikagaku.co.jp/2020/04/06/how-to-learn-ai/</li>
<li>実際の学習は下記<b>「ディープラーニング入門Chainer チュートリアル」で進める</b></li>
https://tutorials.chainer.org/ja/index.html
<li><b>開発環境はGoogle colaboratory(ブラウザで実行できる手軽さがあるようです）</b></li>
</ul>
余談、マークアップもっと綺麗に書きたい笑


# 内容
下記サイトを参考に計画しました。
https://blog.kikagaku.co.jp/2020/04/06/how-to-learn-ai/
<ul>
<li><b>AI でしたいことを決める</b><br>
まずはAIとは何か、今までのシミュレーションとは何が違うのかをしっかり理解することが必要だと思っています。ここがしっかり分かれば自然とできることしたいことが分かってくると思います。したいことというよりは危機感がモチベーションです
- <h5>なぜAIを勉強しようと思ったのか</h5>
私情なので、飛ばしても構いません。現職のメーカーで技術開発をしていく中で、AIが頻繁に登場してきます。詳しく書くことはできませんが、私が入社した数年前に比べてAIを業務利用とする動きは日に日に近づいてきてます。自社情報はもちろん、他社がどんなことをやっているのかも含めてです。<br>
<b>将来、効率的に問題解決できる手段にAIがくるのは間違い無いと思っています。だからAIを使いこなせる人が、効果的な提案活動もできるようになると思います。</b><br>
ですので、今のうちからAIを勉強して将来AIをつかいこなせるようになりたいと思って勉強します。
</li>
<li><b>学習を進めるための全体像を理解する</b></br>
基礎は、大きく下記を学べばいいみたいです。
<b>機械学習に必要な数学
Python
機械学習に関する知識</b>

ITを知るためにプログラミングスクールにも通いましたが、この手の言語は、誰でもできてしまう時点で参入障壁の低い分野であり競争人口が多く、いわゆる量産型エンジニアになってしまうのを危惧しました。ですので、基礎に専門性の高い内容を含んでいるのはgoodです。

<li>最低限の数学
下記の内容を抑えておけば良いようです。私の場合、太字の内容は新たに学習が必要そうです。
<i>微分（偏微分まで）
線形代数</i>
<b>基礎統計（平均、分散、標準偏差など）
単回帰分析の数学
重回帰分析の数学</b></li>

<li>Python
学習環境はとりあえずVSCodeで問題なさそう。chainerというオープンソースライブラリが紹介されていて、実際にプログラミングしながら覚えるには良さそう。</li>

<li>機械学習
下記のカリキュラムを抑えると良いみたい。専門書レベルなので購入の必要ありかな
<b>教師あり学習の代表的なアルゴリズム
重回帰分析, リッジ回帰, ラッソ回帰, ロジスティク回帰, k 近傍法, サポートベクトルマシン, 決定木, ランダムフォレスト, 教師なし学習の代表的なアルゴリズム, k 平均法, 主成分分析, ハイパーパラメータの代表的な調整方法, グリッドサーチ, ランダムサーチ, ベイズ最適化, 分類の代表的な評価指標, 正解率, 適合率, 再現率, F 値</b>

さらにディープラーニングについても勉強する必要あり・・・
<b>ニューラルネットワークの計算（順伝播）, 線形変換, 非線形変換 ,ニューラルネットワークの計算（逆伝播）
誤差逆伝播法, 勾配降下法, ミニバッチ学習, ニューラルネットワークの実装（TensorFlow もしくは PyTorch）</b>

機械学習まわり濃すぎてビビる 以下取り扱うデータについて
<b>画像データ, 畳み込みニューラルネットワーク (CNN), 物体検出のアルゴリズム (R-CNN 、YOLO 、SSD など), セマンティックセグメンテーションのアルゴリズム, 文章データ, 文章データの特徴抽出方法（Bag of words 、Word2Vec など）, 機械翻訳のアルゴリズム (Seq2Seq 、Attention など)<br>
時系列データ（1/1 の来店者数は 100 人のデータに前後関係が存在するデータ）
再帰型ニューラルネットワーク (RNN 、LSTM 、GRU など)
畳み込みニューラルネットワーク (CNN)<br>
表データ（Excel のシートに記載されるようなデータ）
特徴量エンジニアリング
発展的な機械学習アルゴリズム (XGBoost 、LightGBM など)</b>
</ul>