OmniAICreator/Qiita-1.07M huggingface dataset:
指定されたタグすべてに一致するデータを抽出することが一応できた。できた？

# 諸元

ブログエントリーを表す`blogsテーブル`に対して
任意の文字列のタグを紐づける`blog_tagsテーブル`が存在しています。
ユーザーが指定する複数のタグすべてに紐づいているブログエントリーを取得したい。

SQL標準の機能だけでできるのか。

# ワークアラウンド

「ユーザーに指定されたタグの個数」を使う。

"foo", "bar", "baz"が指定されたとして

```sql

SELECT
  *
FROM
  blogs b
WHERE
  3 = (
    SELECT
      COUNT(t.blog_id)
    FROM
      blog_tags t
    WHERE 
      t.blog_id = b.blog_id
      AND b.tag IN ('foo', 'bar', 'baz')
    )
```

# うーん？

最適とは思えない...。
何かを見落としている気もする。
チーム開発を通して分かった、git addやcommit, pushの他にもよく使うGitコマンド

## はじめに
個人で開発をしている時は、正直 `git add` と `git commit` , `git push` くらいしか使っていなかったのですが、Gitの研修やチーム開発を通してGitに関して様々なことを学びました。そこで、Gitを用いてチーム開発を行うときに、「これは知っておきたかったなー」というものをまとめてみました

流れとしては `master` ブランチから `develop` ブランチを切り、そこから `feature/・・・` という感じで作業ブランチを切り、そこで作業を行なっていきます。

## 🤔 「他のメンバーがプルリクを出したから、手元で確認してレビューしたい...」
**例**
自分が `feature/fix_top_page_view` ブランチで作業をしているときに、他のメンバーから `feature/fix_edit_page_view` ブランチで変更を行なってプルリクを出したからレビューしてほしいと依頼が来た時

### 1. 一旦は自分のブランチで修正を行なった分をコミット
```
$ git add hoge.md
$ git commit
```
コミットできるものは、この段階でコミットしておく

### 2. stashを使ってその他変更した部分を一旦退避
```
$ git stash -u
```
`u` オプションをつけることによって、untrackファイルも含めて全てstashしてくれる

### 3. リモートリポジトリの最新情報をローカルリポジトリに持ってくる
```
$ git fetch
```
`git pull` のようにファイルが更新される訳ではない

### 4. 一応ブランチを確認したあと、レビュー対象のブランチに切り替え
```
$ git branch -a
$ git checkout remotes/origin/feature/fix_edit_page_view
```
レビュー対象のリモートブランチに切り替えてレビューする

### 5. レビュー後、自分が作業していたブランチに戻る
```
$ git checkout -
```

### 6. 退避させていたコードを戻す
```
$ git stash pop
```
先ほど退避させておいたコードを元に戻す

## 🤔 「マージしようとしたらコンフリクトが発生していてマージできない...」
**例**
自分が `feature/fix_top_page_view` ブランチでの作業を終え、pushし、プルリクを送った後にコンフリクトが発生していた場合

```
$ git pull origin develop
```
`pull` してくるとコンフリクトが起きるので、エディタ上でコンフリクトを解消し、再度 `add` して`commit` して `push` 

## 😭 「Gitで管理したくないファイル・フォルダをpushしてしまった」
**例**
Gitで管理する必要のない `.vscode` フォルダを `push` してしまった...

```
// フォルダの場合rオプションが必要
$ git rm -r --cached .vscode
$ echo '.vscode/' >> .gitignore
```

## 😭 「マージを取り消したい」
**例**
コンフリクトを解消するために色々変更とかしたけど、編集内容もマージも取り消したい

```
$ git reset --hard HEAD~
```

- reset
    - インデックスを、指定した状態にリセット
    - HEADを指定したcommitに移動

- 「HEAD~」「HEAD^」

> ~(チルダ)を後ろに付け加えることで何世代前の親かを指定することができます。^(キャレット)は、ブランチのマージで親が複数ある場合に、何番目の親かを指定することができます。
引用：[サルでも分かるGit入門](https://backlog.com/ja/git-tutorial/stepup/03/)

## その他

### 前回分のコミットメッセージと統合したい場合

```
$ git add .
$ git commit --amend
```

前回のコミットメッセージを書き換える。`git graph` を使って履歴を確認してみると前回のコミットメッセージが変更されている

### revertとは
コミットを打ち消すコマンド。コミットを打ち消すのではなく、新たにコミットを追加することによってコミットを取り消している。

- resetコマンド→コミットを取り消した形跡が残らない
- revertコマンド→コミットを取り消した形跡が残る

### 間違ってresetしてしまったのでreset前の状態に戻したい

```
$ git reset --hard ORIG_HEAD
```

ORIG_HEAD：resetを実行する直前のコミット

### rebaseでコンフリクトを解消した後どうすればいいの
rebaseで、コンフリクトを解消後はコミットではなく、`--continueオプション`を指定して実行

```
$ git rebase --continue
```

### rebaseの作業を中止したい

```
$ git rebase --abort
```

### 直前のコミットと現在のコミットをまとめたい

```
$ git rebase -i HEAD~~
```

- rebase
    - 作業が完了したブランチを分岐元のブランチと結合する際に使う（歴史を改変してしまう）
    
- -i (interactive)
    - 過去のコミットを編集できる
        - 指定できるオプション
            - squash（コミットメッセージが必要な際に使用）
            - etc...

### トピックブランチのコミットを1つにまとめて統合ブランチにしたい

```
$ git merge --squash ブランチ名
```


### 特定のコミットを取り出してdevelopブランチに追加する方法

```
$ git checkout develop
$ git cherry-pick fsdf342 //fsdf342はコミット番号
```
コンフリクトが起きた場合は修正して、`add` して `commit`

## 参考記事
- [サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)
- [Git レビューする時に使うコマンド](https://qiita.com/ucan-lab/items/f824580cbf995495de00)
【CircleCI】【Rails】【Docker】ArgumentError: key must be 16 bytes 

# assets:precompileで、ArgumentError: key must be 16 bytesが発生

```dockerfile:Dockerfile.rails
ARG RAILS_MASTER_KEY
ENV RAILS_MASTER_KEY ${RAILS_MASTER_KEY}

**略

RUN bundle exec rails assets:precompile # 問題の箇所
```

以下、エラー写真
![スクリーンショット 2020-07-23 12.01.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/1e5ef93e-5f26-fa92-260d-5634f55b82a3.png)
![スクリーンショット 2020-07-23 12.01.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/d37d43b0-9afd-c5ed-ddf4-815fae5db26c.png)

# 対処内容

ローカル環境でdocker buildしてみても同様のエラーは発生しなかったので、値の受け渡しに問題ありと仮説。

```yml:.circleci/config.yml
version: 2.1 
orbs:
  aws-ecr: circleci/aws-ecr@6.10.0
workflows:
  lint_and_test_and_ecr_push:
    jobs:
      - aws-ecr/build-and-push-image:
          account-url: AWS_ECR_ACCOUNT_URL_ENV_VAR_NAME_RAILS
          aws-access-key-id: ACCESS_KEY_ID_ENV_VAR_NAME
          aws-secret-access-key: SECRET_ACCESS_KEY_ENV_VAR_NAME
          dockerfile: Dockerfile
          no-output-timeout: 20m
          extra-build-args: "--build-arg RAILS_MASTER_KEY=${RAILS_MASTER_KEY}" # これが抜けていた…
          path: .
          region: AWS_REGION_ENV_VAR_NAME
          repo: repo-name
          filters:
            branches:
              ignore:
                - master
```

そもそも`--build-arg`について知見がなかったのが敗因。よく勉強しましょう。

`Dockerfile`で`ARG`を指定してdocker buildの際に指定できる引数を宣言しても、中身を持ってこなければ意味がない。

## イメージ

- CircleCIの環境変数に値をセット
- .circleci/config.ymlでDockerfileで展開する変数RAILS_MASTER_KEYを指定して、その変数にCircleCIで設定した環境変数RAILS_MASTER_KEYを代入
- DockerfileのARG(RAILS_MASTER_KEY)がCircleCIで設定した環境変数の値を持った変数として機能する
- DockerfileでENV(RAILS_MASTER_KEY)にARGで機能した変数RAILS_MASTER_KEYを代入することで、コンテナ内での環境変数(RAILS_MASTER_KEY)として機能する 

## 参考

[Dockerfile ARG入門](https://qiita.com/nacika_ins/items/cf8ceb20711bd077f770)
[circleci/aws-ecr@6.10.0](https://circleci.com/orbs/registry/orb/circleci/aws-ecr)
[Dockerfileの"ENV"と"ARG"と"環境変数"について](https://techblog.recochoku.jp/1979)
[Rails 5.2 + Docker, RAILS_MASTER_KEYをイメージ作成時に動的に入れる方法](https://medium.com/@_hiko1129/rails-5-2-docker-rails-master-key%E3%82%92%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E4%BD%9C%E6%88%90%E6%99%82%E3%81%AB%E5%8B%95%E7%9A%84%E3%81%AB%E5%85%A5%E3%82%8C%E3%82%8B%E6%96%B9%E6%B3%95-f26137ccb457)
Debian Buster で br_netfilter を無効化

#最初に

Debian 10 Busterでカーネルモジュール`br_netfilter`が有効になっているために
普通にブリッジを作るだけではブリッジの外にパケットが出てくれなかったので
ブリッジ外にパケットを通す設定をメモしておく。

#参考

https://manpages.debian.org/buster/systemd/sysctl.d.5.en.html

#設定手順

##起動時に`br_netfilter`モジュールを強制的にロードする。

この設定をしておかないと次の手順の設定内容が反映されないぽい。

```bash:/etc/modules-load.d/bridge.conf
br_netfilter
```

##ブリッジ内のパケットフィルタリングを無効化する。

```bash:/etc/sysctl.d/bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
```

##再起動する。

```bash
# reboot
```
Goでファイルアップロードアプリを作る

##ディレクトリ構成
imgフォルダにアップロードしたファイルが保存されます。

```text
./
　├ index.html
　├ main.go
　├ img/
　　　└ ここにファイルが保存される
　　　└ ここにファイルが保存される
　　　└ ここにファイルが保存される
　       　　   .
               .
               .
               .
　　　
```



##コード
###main.go
```go:main.go
package main

import (
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
)

func upload(w http.ResponseWriter, r *http.Request) {
	//メソッドをPOSTのみ許可
	if r.Method != "POST" {
		log.Fatal("許可されていないメソッド")
	}

	//formから送信されたファイルを解析
	file, fileHeader, err := r.FormFile("image")
	if err != nil {
		log.Fatal("ファイルのアップロード失敗")
	}
	//アップロードされたファイル名を取得
	uploadedFileName := fileHeader.Filename
	//アップロードされたファイルを置くパスを設定
	imagePath := "img/" + uploadedFileName

	//imagePathにアップロードされたファイルを保存
	saveImage, err := os.Create(imagePath)
	if err != nil {
		log.Fatal("ファイルの確保失敗")
	}

	//保存用ファイルにアップロードされたファイルを書き込む
	_, err = io.Copy(saveImage, file)
	if err != nil {
		log.Fatal("アップロードしたファイルの書き込み失敗")
	}

	//saveImageとfileを最後に閉じる
	defer saveImage.Close()
	defer file.Close()

	//もう1周
	http.Redirect(w, r, "/", 302)
}

func index(w http.ResponseWriter, r *http.Request) {
	tmp := template.Must(template.ParseFiles("index.html"))
	if err := tmp.Execute(w, nil); err != nil {
		log.Fatal(err)
	}
}

func main() {
	http.HandleFunc("/upload", upload)
	http.HandleFunc("/", index)
	log.Fatal(http.ListenAndServe(":8000", nil))
}

```

###index.html
```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ファイルアップロード</title>
  </head>
  <body>
    <div class="container">
      <h1>ファイルアップロード</h1>
      <form method="post" action="/upload" enctype="multipart/form-data">
        <input type="file" name="image" multiple="multiple" />
        <input type="submit" name="submit" value="アップロード" />
      </form>
    </div>
  </body>
</html>

```
##外観
<img width="828" alt="スクリーンショット 2020-07-23 12.02.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649199/65ac824b-81f9-5680-b143-34e0a78c71aa.png">
##できなかったこと
テンプレートで　\<img src="{{.}}/>　にimagePathを渡してみたが表示されなかったです。vscodeを右クリックした時に出てくるPHPサーバーってやつではみれました。原因不明ですが、アップロードした画像の表示は諦めました。

追記　githubに置いておきました。https://github.com/souhub/go-file-uploader
【Unity】NRSDKのエミュレーターサンプルを動かしてみる【Nreal】

##はじめに
今回は、NRSDKを使い、UnityEditor上でサンプルシーンを動作させます。
非常に簡単なので、Nreal本体を持っていない方でも体験可能なものとなっております。

早速始めましょう。

##使用環境
Windows10 Home 64bit
Unity2018.4.20.f1
NrealSDK 1.3.0

##１.NRSDKをUnityにインポートする
Nreal公式HP(https://developer.nreal.ai/) からアカウント作成後、ダウンロード可能です。
ダウンロードしたSDKのUnityPackageをUnityにインポートしましょう。

インポートができたらAssets直下に「NRSDK」というファイルが配置されます。

##２.エミュレーターのサンプルシーンを開く
エミュレーターのサンプルシーンは「Nreal/Emulator/Scene」にあります。
**・TrackableImageEmulator**
　　マーカー画像を認識するサンプル
**・TrackablePlaneEmulator**
　　平面検知した面を認識するサンプル

どちらかお好きなシーンを開きましょう。

##３.UnityEditorでPlayを押して、動作を確認する
実行すると、マーカーや平面にCubeが表示されると思います。

以下、操作方法

**移動**
前：W
後：S
左：A
右：D

**Nrealのコントローラー**
上：右クリック
中：左クリック
下：スクロールクリック

##マーカー画像認識、平面検知について
ちなみに、**どのようにマーカー画像や平面を認識してるのか？**と考えると思います。
エミュレーターでは、以下のメソッドで判定しているようです。

つまり、 「マーカー認識と言ってもマーカーの特徴点を取り、解析を行っている」のではなく、
「カメラが画面内にある時にマーカーのセンター座標にオブジェクトを表示する」という感じでしょうか。


```C#
       public bool IsInGameView(Vector3 worldPos)
        {
            if (centerCam == null) centerCam = GameObject.Find("CenterCamera").GetComponent<Camera>();
            Transform camTransform = centerCam.transform;
            Vector2 viewPos = centerCam.WorldToViewportPoint(worldPos);
            Vector3 dir = (worldPos - camTransform.position).normalized;
            float dot = Vector3.Dot(camTransform.forward, dir);
            if (dot > 0 && viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
}
```



##おわりに
サンプルシーンが用意されていたため、比較的容易に体験できました。
今後もNrealの理解を深めていこうと思います。
NuxtでFacebookの埋め込みコードを扱う

Nuxt.jsで作ったサイトにFacebookの埋め込みを行いたかったのでそのメモ。
（この方法がベストかどうかはわかりません。）

# Facebookの埋め込みコード
以下より発行できる
https://developers.facebook.com/docs/plugins/page-plugin?locale=ja_JP

これをbody直下に↓

```html

<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v7.0" nonce="wAXonegw"></script>
```

これを埋め込みたい場所に記述します。

```html
<div class="fb-page" data-href="https://www.facebook.com/facebook" data-tabs="timeline" data-width="" data-height="" data-small-header="false" data-adapt-container-width="true" data-hide-cover="false" data-show-facepile="true"><blockquote cite="https://www.facebook.com/facebook" class="fb-xfbml-parse-ignore"><a href="https://www.facebook.com/facebook">Facebook</a></blockquote></div>
```

問題はbody直下に書く方のコードで、これをbody直下に書くというのがNuxtでは少し難しいです。
body直下に書かないとFacebookのタイムラインが表示されない場合があるので適当な場所に埋めてはだめです。

# app.htmlを使う
`nuxt.config.js` がある場所に `app.html` を作ります。
このファイルがあるとnuxtでは大枠のテンプレートとして解釈してくれます。
ベースは以下なので

```html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>
```
↓

```html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    <div id="fb-root"></div>
    <script
      async
      defer
      crossorigin="anonymous"
      src="https://connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v7.0"
      nonce="wAXonegw"
    ></script>
    {{ APP }}
  </body>
</html>
```

としてやるとbody直下にコードが埋め込まれます。

# 動くけど・・・
なんとなくしっくりこないこの方法、、、
個人的には埋め込む記述をコンポーネントにしてそこでこのコードをbody直下にうまく書くみたいなことができたほうが管理しやすいと思う。

以下の記述でbody内にスクリプトを呼ぶみたいなことはできるんだけど、bodyの最下部になるし、htmlがかけないのかな？innerHtmlっていう項目もあるみたいだけど・・・
ここは調査しきれませんでした。（もう前者の方法で諦めたw）

```js
<script>
export default {
  head: {
    script: [
      { src: '/body.js', body: true }
    ]
  }
}
</script>
```
VBAからPowerShellを起動し、任意コマンドを実行する

VBAからPowerShellを任意コマンドで実行するため、いろいろ調べて辿り着いた結果を記しました。

## コード

```vb:runPshell.bas
Function runPshell(psCmd As String, intVsbl As Integer, waitFlg As Boolean)
'**** VBAからPowerShellを起動し、任意のコマンドを実行する  *********
' psCmd   : PowerShellコマンド(PowerShell仕様により260文字以内)
' intVsbl : PowerShell画面表示(1)/非表示(0)
' waitFlg : PowerShell実行終了を待つ(True)/待たない(False)
'***************************************************************
    Dim objWSH As Object
    Set objWSH = CreateObject("WScript.Shell")
    
    objWSH.Run "powershell -NoLogo -ExecutionPolicy RemoteSigned -Command " & psCmd, intVsbl, waitFlg
    
End Function
```
使用例として、txtファイルをコピーするコードを示しました。

``` vb:hoge.bas
Option Explicit
Sub TestPs()
    Dim sPath As String
    Dim dPath As String
    Dim psCmd As String
    Dim hoge As Variant
    
    sPath = "C:\work\hoge.txt"
    dPath = Replace(sPath, "hoge", "huga")
    psCmd = "Copy-Item " & sPath & " " & dPath
    hoge = runPshell(psCmd, 0, True)
End Sub
```
## コメント
* 参照設定をユーザに操作させたくなかったので`CreateObject("WScript.Shell")`を使っています。
* 変数`intVsbl`でPowerShell画面の表示(1)/非表示(0)を選択できます。
* 変数`waitFlg`でPowerShell実行完了を待つ(True)/待たない(False)を選択できます。
* PowerShellの仕様上、コマンド格納変数`psCmd`の文字長は260文字以内です。パスが深いファイルのコピーなどは注意が必要です。

##開発経緯など
ファイルを圧縮してサーバに転送したい！という仕事での要望に応えるために開発しました。圧縮、転送中もVBAが動くようにできない？という要望から、処理をOSに渡すのがいいと思い、PowerShell使用となりました。
VBAの`FileCopy`だとコピー処理完了まで他のことができませんが、PowerShellに渡してしまえばVBAが次の処理に入れるので効率的です。なお、変数`waitFlg`でPowerShellの処理完了を待つようにも設定できます。
\# 待つならFileCopyでもよくね？というのは置いといて。。。
参考サイトは各機能に特化したコードでしたが、もしかしてコマンド自体を引数で渡せば汎用化できる？と思い今回のFunctionとなりました。
最初は.Execで作っていましたが、PowerShell画面が邪魔！ということで、画面非表示機能を追加するために.Runを採用しました。
開発過程で、PowerShellコマンドに文字長制限があることが分かりました。ファイル転送がうまく行かずよくよく調べると、パスが深すぎて文字長制限に引っかかっていたようでした。Cドライブ直下に転送用フォルダを掘り、対応しました。
ひと段落ついて、さて記事にしようかとふと調べると、ほぼ同じことしているQiita記事を見つけたので一緒に紹介しておきました。

## 参考サイト
[VBAでZIP圧縮と解凍を行う](https://vbabeginner.net/vba%E3%81%A7zip%E5%9C%A7%E7%B8%AE%E3%81%A8%E8%A7%A3%E5%87%8D%E3%82%92%E8%A1%8C%E3%81%86/)
[PowerShell VBAでPowerShellを実行して結果を取得する（Run編）【初実験編08】](https://it-engineer-info.com/language/powershell/1903/)
[VBAからpowershellコマンドを実行(Qiita)](https://qiita.com/areanoblog/items/095abe477fd04bbfc7c4)
BlueGreenDeploy_DB操作

24時間稼働を約束している環境の仕様変更が決まり、
サービスを止めずに、DBの仕様変更を変えることが決まりました。
しかも、顧客データの変更も必須です。(Aという文字列が、変更後ではBになる。)

Blue Green Deploy　という方法をとることになりましたが、
DBのスキーマも変更するために、どの様に変更するかを実際に試したので、ここに残します。

前提：
サービスを停止させないこと。
そのため、本番と別途、仕様変更用のサーバーを用意。
ドメインの中身を入れ替えることで、大幅な修正を、顧客に影響させずに行う。

１．STGで、本番DBをClone、STGのDBとして用意。
２．STGで、STGのDBに新しいスキーマを追加
（既存のカラムに対して、制限の追加や削除しない、カラムを追加する場合もnullableやリファレンスの制限はかけない。）

３．STGの既存顧客のデータの変更
4．STGにてテストを行う。

5．新しいスキーマを本番DBに反映する。
6．本番にててうsとを行う。（古いプログラムは新しいDBにちゃんと動いているかどうか）
7. 本番の既存顧客のデータの変更
事前に、サーバー側で、旧productionで、新しいデータでも古いデータでもどちらでも稼働ができる様にする。

8．STG環境は本番DBに接続し、STG環境で新しい機能テストと回帰テストする。
(実行の手順はNODE_ENV=productionにして，再デプロイする。EBの利用を前提に、)
9.証明書等、本番に揃っているか確認する。
10．本番DomainをSTG環境にアサインする。
(AWSの場合、Route 53のエイリアスを変更する。)


11.  8、10の間にきたリクエスト分のデータの修正
追加したカラムへのデータの追加。

この時点で、本番には反映済みになる。
あとは調整。

12．本番にて必要ではないテーブル、コラム、データを削除する。
カラムの制限も追加する。
のをstgのDBで行う。
13．本番にて必要ではないテーブル、コラム、データを削除する。カラムの制限も追加する。
14.
reference等、追加する場合、大量のデータを修正する場合、DBがダウンする可能性があるため、
やり方も考える必要がある。
コピーして、修正、
その後に、他のやり方を対応するなど。
Netflixの字幕をVBAで抽出する

#英語学習のためお気に入りの映画の字幕をVBAで抽出してみる
私は英語とVBAの学習を同時に行っている。
Google Chromeの拡張機能で字幕をダウンロードしたところ必要ないテキストがついていたので
VBAで必要なテキストを抽出することにした。
前提条件
・Netflix - subtitle downloaderでダウンロードした.vttファイルがある
・エクセルがインストールされている

##ファイル読み込み
ファイルを読み込んでみる。

・モジュール
Option Explicit

Public Enum SETCOL
    C_PATH = 2
End Enum

Public Enum SETROW
    R_PATH = 2
End Enum

Private Const START_TAG_ = "<c.mono_sans>"
Private Const END_TAG_ = "</c.mono_sans>"

'''<summary>
'''<remarks>
''' NETFLLIXの英語字幕を抽出
'''</remarks>
'''</summary>
    Sub Extraction()
        'カレントディレクトリを変更
        ChDrive Left(ThisWorkbook.Path, 1)
        ChDir ThisWorkbook.Path
        Dim buf As String
        Dim str As String
        Dim myTitle As String
        Dim c As common: Set c = New common
        Open c.GetFilePath For Input As #1
            Do Until EOF(1)
                Line Input #1, buf
                debug.print byf
            Loop
        Close #1
    End Sub

・クラス
'''<summary>
'''<remarks>
''' テキストファイル出力
'''</remarks>
'''</summary>
    Function GetFilePath() As String
        Dim prompt As String: prompt = "ファイルを選択して下さい"
        Dim fPath As Variant
        fPath = Application.GetOpenFilename("", , prompt)
        If fPath = False Then End
        GetFilePath = fPath
    End Function

これで、ダイアログから選択した.vttファイルをプログラム内に読み込んだ。
しかしDebug.printで出力するとファイルの内容をすべて一回の読み込みで取ってきている。
一行ずつ抽出して加工したいのでこれではいけない。
次回は原因を調査し抽出したテキストを出力までたどり着きたい。
CPUのプログラムレジスタープログラムカウンタの役割

CPUのプログラムレジスタ(プログラムカウンタ)の役割はどれか。

応用情報技術者令和元年秋期 午前問9


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/672cf853-427d-527e-f713-7aee2a1c1c30.png)


１、プログラムカウンタは、」CPUの制御装置にある専用レジスタの1つで、次にフェッチ(メモリからの呼出し)・解読・実行される命令のアドレスを保持する役割を持ちます。命令が実行されると、プログラムカウンタは読み込んだ命令長だけ自動的に加算され、次の命令のアドレスを指すようになります。分岐命令の際は、ジャンプ先のアドレスをプログラムカウンタにセットすることで命令実行順序を制御します。

プログラムカウンタのカウンタとは、次の命令アドレスを指すため、自動的に**加算する**という意味ですね。


２、汎用レジスタの役割　⇒Reading Data From Memory
演算を行うために，メモリから読み出したデータを保持する。


３、アキュムレータの役割　accumulator  ⇒Saving temporary Result From CPU
条件付き分岐命令を実行するために，演算結果の状態を保持する。


４、命令レジスタの役割 ⇒Reading Command From Memory
命令のデコードを行うために，メモリから読み出した命令を保持する。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6fe446ff-4a9f-a603-c3f7-7204d4ae91b6.png)


参照：
https://www.ap-siken.com/kakomon/29_haru/q8.html
Next.jsでクロスオリジンエラーとたたかう

#はじめに
30代未経験からエンジニア転職をめざすコーディング初学者のYNと申します。お読みいただきありがとうございます。
初学者が一度はつまづくと思われるCORSエラーについて、自分の学びを本記事にまとめました。

#今回の問題
Next.jsを使って開発中、フロントエンドから外部API（今回は自作のAPI）にアクセスしようとするとクロスオリジンエラーが発生する。事象を簡単に図にすると以下の通り。
<img width="1173" alt="スクリーンショット 2020-07-23 11.27.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/a7e7a25e-0d12-b374-dae3-233c3dfa6eaa.png">

#クロスオリジンエラーとは
エラーについて正しく理解したい方は[こちらの記事](https://qiita.com/att55/items/2154a8aad8bf1409db2b)を参考にしていただくとして、自分の理解をかなりざっくり図にするとこんな感じです。
<img width="1234" alt="スクリーンショット 2020-07-23 11.08.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/ac5dbce0-0f6a-1a0d-da08-990c43d6b96e.png">

ブラウザ自身が、ホスティングサーバー以外のドメインにアクセスすることを禁止しているため、フロントエンドから外部APIなどにアクセスしようとするとエラーになる、というのがCORSエラーの正体です。


#解決策
上記を見ればお分かりいただけます（？）通り、解決策は2つあります。
* ブラウザちゃんに他の男（ドメイン）と直接会話してもらう
* ブラウザちゃんにバレないように、ホスティングサーバーの方で外部APIと会話して、その結果をブラウザちゃんに伝える。

本記事では、後者について対処法をまとめていきます。


#対処法
>ブラウザちゃんにバレないように、ホスティングサーバーの方で外部APIと会話して、その結果をブラウザちゃんに伝える。

この対処法を簡単に図にまとめると下記になります。
<img width="1173" alt="スクリーンショット 2020-07-23 11.40.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/a2be09e5-0494-7686-eded-2616860e37fd.png">

ブラウザが特定のAPIにアクセスする代わりに、ホスティングサーバー側でAPIとやりとりして、結果をブラウザに返すようにルートを変更します。
これを実現するために、Nextにカスタムサーバーを導入することで対処することができます。

#カスタムサーバーを設定する
やることは2つだけです。
まず、rootディレクトリにserver.jsをつくります。



```javascript:server.js
const express = require("express");
const next = require("next");
const { createProxyMiddleware } = require("http-proxy-middleware");

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  server.use(
    "/endPoint",
    createProxyMiddleware({
      target: "https://example.amazonaws.com",
      changeOrigin: true,
    })
  );

  server.all("*", (req, res) => {
    return handle(req, res);
  });

  server.listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});


```
これにより、ブラウザから`https://example.amazonaws.com/endPoint`にアクセスすることができます。


次に、package.jsonを変更します。

```json:package.json
"scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  }
```


一応補足ですが、ブラウザからアクセスするときは、`https://example.amazonaws.com/endPoint`でなく`/endPoint`にアクセスします。つまり、ブラウザとしてはホスティングサーバーにアクセスしているつもりです。

```javascript:TestComponent.js
import axios from "axios";

export default function TestComponent() {
  useEffect(() => {
    const opt = {
      method: "get",
      url: "/endPoint",
    };
    axios(opt).then((res) => {
      console.log(res.body);
    });
  }, []);
}

```

#最後に
いかがでしたでしょうか。
間違っている点などご指摘いただければ幸いです。

#参考にさせていただいた記事
>https://qiita.com/att55/items/2154a8aad8bf1409db2b
>https://qiita.com/lelouch99v/items/3dc11676bb9c23457d41
XcodeプロジェクトでTargetを複数つくる時に気をつける事

### 経緯

あるライブラリが、シミュレータでのビルドに対応していなかった。しかしシミュレータでビルドして確かめたい点などもあるため、ターゲットを複数作り、一つはそのライブラリ有り、もう一つはライブラリ無しという形にする事にした。

### やり方

#### Targetのコピー
- Xcode上で「プロジェクト名.xcodeproj」ファイル（青いやつ）をクリック -> Target よりコピーしたいTarget(ここでは`myProject`とする)を右クリックし、「Duplicate」を選択。「myProject copy」というTargetができる。クリックして、任意の名前に変える（ここでは、`myProjectWithLibrary`とする）。
   - 完全に同じ設定のtargetがコピーされている。
   - `The selected target is an iPhone target. Would you like to duplicate the iPhone target and transition the new target for running on iPad?`というダイアログが出てくる。意味的には、「コピー元はiPhoneがターゲットだけど、コピー先はiPad用にする？」と聞いてきている。特にそんなつもりはないため、「Duplicate only」を選択する。

#### Schemeの編集
- Schemeを編集する。Targetをコピーしたのに伴って、Schemeも自動で新設されている（Xcode左上より確認できる）。ただ名前は「myProject copy」のままなので、Schemeの名前も`myProjectWithLibrary`に直しておく。

#### Info.plist
- TargetのコピーによりInfo.plistもコピーされている。ただ、修正し忘れなどの観点から、特に事情がなければInfo.plistは同じものを一つだけ参照した方がいいと思われる。
    - まず、自動生成された`myProject copy-Info.plist`を削除する。
    - Targets > Build Settings > Packaging > Info.plist fileより、`myProject copy-Info.plist`を削除し、コピー元のInfo.plistのファイル名を入力する。
 
#### Target Membership
- Target Membershipの調整
   - 今回入れたライブラリをインポートしているファイルがTarget Membershipに入っていると、シミュレータでビルドできなくなる状況であった。そのため、それらのファイルの`Target Membership`で`myProject`を外した。
   - Xcodeの左メニューから各ファイルを選択し、右メニューのFile Inspector > Target Membershipより、どのTargetに追加するかチェックボックスで選ぶことができる。
   - 以降、新規ファイルを追加する際は、`myProject`と`myProjectWithLibrary`の両方にチェックボックスが入っていることを確認する。
   - マージなので、他の人が追加したファイルが流れてきた場合、`myProjectWithLibrary`にTarget Membershipがついていなかったりしたので、つけた上で、今後はつけてもらうよう周知した。

#### プリプロセッサマクロ
- プリプロセッサマクロ
   - 上記Target Membershipで、ファイル毎にどのTargetで使うか決められるわけだが、それだけでは足りない場合がある。ファイル内のあるコード（例えば、今回のライブラリをインポートする部分など） を、`myProjectWithLibrary`の時は実行したいが`myProject`の時は実行したくなかった。そのため、プリプロセッサマクロの設定をした。
   - Targets > `myProjectWithLibrary` > Build Settings > Swift Compiler - Custom Flags > Other Swift Flags　に、元々CocoaPodsの`-D COCOAPODS`が入っていたが、`-D WITHLIBRARY`というものを追加した。
   - マクロの使用例は以下のようになる。

```swift:AppDelegate.swift

#if WITHLIBRARY
import library
#endif

```

```swift:MainWireframe.swift
func presentXXXScene() {

   #if DEBUG && WITHLIBRARY 
   let vc = XXXBuilder().build()
   viewController.pushViewController(vc)
   #endif

}
```

#### Podfile

- Targetが増えているので、Target事にライブラリを管理しているPodfileも直さなくてはいけない。
 - 基本的には、`myProject`と`myProjectWithLibrary`で、CocoaPodで導入しているライブラリは全て同じであった。そのため、Podfile内で関数を定義するか、CocoaPodsのabstract target機能を用いて、同じ箇所に書いたライブラリ定義を二つのTargetで使いわ回すと良い。
 - 参考 [CocoaPods: The Elegant Solution To Installing The Same Pod In Multiple Targets](https://www.natashatherobot.com/cocoapods-installing-same-pod-multiple-targets/)、　[stack overflow - How do I specify multiple targets in my podfile for my Xcode project?](https://stackoverflow.com/questions/14906534/how-do-i-specify-multiple-targets-in-my-podfile-for-my-xcode-project)、[What's a pod file?](https://guides.cocoapods.org/using/the-podfile.html#what-is-a-podfile)
MVC, ルーティング

#本記事について
こんにちは。フロントエンドの学習を一通り進めたのでバックエンドの学習に踏み入れた駆け出しエンジニアです。
プログラミング学習サイト「白熱教室」でのエクササイズ課題のアウトプット兼メモとして記事にしました。
今回のエクササイズはこちらです ↓
[【エクササイズ】WebフレームワークのMVCとルーティングの復習](https://tsuyopon.xyz/learning-contents/web-dev/javascript/backend/excercise-for-mvc-and-routing/)
プログラミング学習にはおすすめのサイトなので、気になる駆け出しエンジニアの方は一緒に学習しましょう！！

##MVC

###1. MVCは何をするためのものか答える
ModelViewControllerの略。機能ではなくデザインパターンのひとつ。
「Model」,「View」,「Controller」の役割に分けてアプリの実装を行うことで、キレイなコードを書いたり管理がしやすくなる。

###2. MVCのそれぞれ3つの役割を答える
「Model」: データ管理の役割を実装する。
　　→　◦ データの操作・加工
　　　　◦ DBとのやりとり

「View」: 表示まわりの実装
　　→　◦ テンプレートファイルの実装
※引用: 「テンプレートファイル」という言葉は、実際にexpressの学習に入るときに具体的に説明しますが、ここでは「HTMLファイルではないが、HTMLのコードを返すことができるファイル」と認識していただけたらと思います。([引用元](https://tsuyopon.xyz/2019/02/21/what-is-the-mvc/))


「Controller」: 橋渡しをするコンテナーの様な役割
　　→　◦ クライアント・Model・Vierのそれぞれの操作にはControllerを仲介にやりとりをする

##ルーティング

###3. Webフレームワークのルーティングとは何を指すか答える
クライアントからのリクエスト(HTTPメソッド等)を実際の処理(サーバー処理)を紐付ける

###4.「GET /users」でリクエストをしたときの、クライアントとサーバーの処理の流れを答える(※ルーティング、MVCという言葉を使って說明すること)
1. クライアントのリクエスト「GET/users」が投げられる
2. 「Get/users」にルーティングされているControllerのgetUsersメソッドが実行され、Modelにユーザー一覧の取得を依頼
3. ModelがDBに問い合わせる
4. ModelがDBからユーザー一覧のデータを受け取る
5. Modelは受け取ったデータをControllerに渡す
6. Controllerは受け取った情報をVierに渡す
7. Viewはデータを元にHTMLに反映させる
8. これらの処理で動的反映させたHTMLをクライアントにレスポンスする。

// MVCの流れ

1. クライアント
2. Controller
3. Model
4. DB
5. Model
6. Controller
7. View
8. Controller
9. クライアント

//
IISサーバにサイトを追加する

#記事一覧
[Visual StudioのASP.NET Core MVC で Web アプリを作成してみた（記事一覧）](https://qiita.com/yuta-sasaki/items/31307b88f7234b92f728)

#「IISマネージャ」で「サイト」を追加する
「コントロール パネル\システムとセキュリティ\管理ツール」→「インターネット インフォメーション サービス (IIS) マネージャー」を起動する。
接続ウィンドウで、サイトを右クリックして、「Webサイトの追加」を選択する。
<img width="715" alt="Webサイトの追加.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/9a0b2dc3-6b39-5eb6-69a4-443cc544bbd9.png">

サイト名、物理パス、ポートを設定する。
<img width="707" alt="Webサイトの追加2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/ba7a9e7c-0578-b923-3aca-0f9f4c716b77.png">

物理パスに、任意のHTML「index.htm」を追加する。
http://localhost:87/ で追加したサイトにアクセスしてみる。
<img width="599" alt="Webサイトの追加3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/20900ff3-1715-cf72-9a2a-16d67daf4dc3.png">

上記の様にエラーとなる場合には、アクセス権の許可→セキュリティで、ユーザ「Users」のアクセス権を許可する。
<img width="704" alt="Webサイトの追加4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/d7a5e8b4-35b7-58fb-bfcd-10134b09b3d1.png">

アクセス権を許可したので、再度、http://localhost:87/ にアクセスする。
<img width="598" alt="Webサイトの追加5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/d451e1f9-8307-6f25-a95a-2872ece6204f.png">

#ファイアウォールでポートのアクセスを許可する
ポートのアクセスを許可すると、他の端末からもポートにアクセスすることが可能になります。
<img width="782" alt="IISサーバにサイトを追加する5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/026e9ab7-be71-927b-20be-9b7d4abf297f.png">
<img width="768" alt="IISサーバにサイトを追加する6.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/647393d8-d17f-cc87-7bc0-abb428c07339.png">

WiFiなどで同じネットワークに接続しているPCやスマホ端末のブラウザから「http://(ipadress※注1):87/」にアクセスすると、追加したサイトにアクセスすることができます。
注1：(ipadress)は、IISサーバのIPアドレスです。
分割統治法を適用した整列(ソート)アルゴリズムはどれか。

応用情報技術者令和元年秋期 午前問12

分割統治法を適用した整列(ソート)アルゴリズムはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/955a27a5-5b18-dad7-c62c-fbb641479bce.png)

**分割統治法**は、大きな問題をいくつかの小さな問題に分割し、その小さな問題の解を統合することで最終的に問題を解決しようとする考え方です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/666e85cc-b2a7-9071-599b-a5a65dbd42f1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5e984bbc-592a-89ad-84e1-a29197ac53ef.png)

From https://www.ap-siken.com/kakomon/18_haru/q12.html
BeautifulSoup .contents[ ]の使い方

BeautifulSoup .contents[ ]の使い方

HTMLの取得したいタグのところで、'<'が何番出てくるかカウントするぽい。

例：

```
[<a href="https://jicpa.or.jp/news/information/2020/20200703iig.html">
 <em class="date">2020年07月03日</em>
 <div class="tag-outer"><span class="tag color-blue-01">お知らせ</span>
 </div>
 <p class="mod-sentence">修了考査受験者へ後進育成担当常務理事からのメッセージ動画公開</p>
 </a>, <a ・・・・]
```

こういった場合には、'<'だけを拾っていく。'</'は拾わない。
.contents[]でその数字を入れる。
あとは、属性を入力する。

属性は'text','string','strings'など
denoでもお手軽スクレイピング2020年夏

## お題
[Node.js でお手軽スクレイピング 2020 年夏 - Qiita](https://qiita.com/otchy/items/244c19c561ecb7211fa5)をdenoでやってみたんだなも。
ぜひ読んでいってくださいだなも。

ちなみに当方は普段Pythonで、TypeScriptもnodeもJavaScriptも初心者だなも。


## ソース
いきなりソースだなも。

```typescript:test_scraping.ts
import jsdom from 'https://dev.jspm.io/jsdom'

const res = await fetch('https://www.jma.go.jp/jp/week/319.html')
const html = await res.text()
// console.log(html)

// jsdomでエラーが出るため、imgタグを削除
// error: Uncaught TypeError: Canvas.Image is not a constructor
//         this._image = new Canvas.Image();
const filt_html = html.replace(/<img.*?>/g, '')
// console.log(filt_html)

const dom = new jsdom.JSDOM(filt_html)
const document = dom.window.document
const nodes = document.querySelectorAll('#infotablefont tr:nth-child(4) td')

const tokyoWeathers = Array.from(nodes).map((td?:any) => td.textContent.trim())
console.log(tokyoWeathers)
```

### 実行結果
--allow-netを忘れずにだなも。

``` sh
$ deno --version
deno 1.2.0
v8 8.5.216
typescript 3.9.2
$ deno run --allow-net test_scraping.ts
[
  "雨時々止む", "曇一時雨",
  "曇", "曇時々晴",
  "曇時々晴", "曇時々晴",
  "曇時々晴"
]
```



## 解説
ほぼ参照元と同じだなも。
はまったとこだけ書くのだなも。

- jsdomライブラリのインポート
ここで解決しだなも。
[jsdom Port for 1.0 (Feature Request) · Issue #3447 · denoland/deno](https://github.com/denoland/deno/issues/3447)
jspm.ioはよくわからないけど、cdnだと思っておくだも。

- jsdom Imageエラー
jsdomでエラーが出たので、試行錯誤の末、imgタグを消すという荒業をやっただなも。
`(npm:jsdom@16.3.0)`

- any問題
mapで、(td?:any) をつけないと推論で、怒られるんだなも。

## 終わりに
この情報は、本来なら４００００ベルのところ、今だけ５０００ベルだなも。ローンも組めるだなも。
React初心者覚書01 - hello react - 

JSもままならない人（初級の中くらい）が、Reactをなんとか理解しようとしてみる試みです。初心者が理解できない例として捉えていただけたらと思います。

- 数年前からたまにやってみようとして何度か挫折し、読んだこともすぐに忘れるので、覚書を書いてみることにしました。
その際に、何がわからないかも（）で併記していきます。根本的に理解できていないので、もし何かコメントをいただけるとありがたいです。


基本的には[Reactの日本語サイト](https://ja.reactjs.org/)を見て、覚書を書いていきます。

## Reactとは
（出来たものを見ると便利そうだが、何なのか理解できていない）
 - インタラクティブな UI の作成
 - 宣言的なViewを用いる（そもそもViewが何なのかよくわかっていない）
 - コンポーネントベース（パーツを作って組み合わせる？具体的に何なのかわからない）


[一番短い例](https://ja.reactjs.org/docs/hello-world.html)
    　- React DOMが React要素に合致するようにDOMを更新する作業を担当している>UIを更新する唯一の方法

ReactDOM.render(要素, 書き出す場所);

```hello.js
ReactDOM.render(
  <h1>Hello,world!<?h1>,
  document.getElementById('root')
);
```

```hello02.html
<div id="root"></div>
```

```hello02.js
const element = <h1>Hello, world</h1>;
ReactDOM.render(element,document.getElementById('root'));
```
 - React DOM は要素とその子要素を以前のものと比較し、DOM を望ましい状態へと変えるのに必要なだけの DOM の更新を行


## JSXとは（なんとなく理解）
 - JSの構文の拡張
 - CSSに見えるが JSのオブジェクト

## コンポーネント
 - JSの関数と似ている。 propsからの任意の入力を受け取り、画面上にReact要素として返す。
 -  コンポーネント定義で一番簡単なのは、JSの関数
 -　下記の２つcomp01.jsとcomp02.jsは等価（よくわからない）

```comp01.js
function Welcome(props{
return <h1>Hello, {props.name}</h1>;
}
``` 

```comp02.js
class Welcome extends React.Component{
render(){
return <h1>Hello,{this.props.name}</h1>;
}
}
``` 

コンポーネントのレンダー

- コンポーネント名は常に大文字で始める

```comp-render.js
const element = <Welcome name="Hanako" />;
```
ここが多分自分がつまづく部分で、何がわからないかと言うと、
 element変数になぜ、Welcome関数を持ってきているのかがわからない。なぜわざわざ？と思ってしまう（普通のプログラマだとすぐわかると思いますが、お許しを）。自分だと自分の誤ったコード.jsのようにしたくなる。

```自分の誤ったコード.js
function Welcome(props) {
  return <h1>Hello, Hanako</h1>;
}
 ReactDOM.render(
Welcome,
document.getElementById('root')
);
```


```comp-render02.js　正しい
function Welcome(props){
return <h1>Hello, {props.name)</h1>;
}

const element = <Welcome name = "Hanako" />;

ReactDOM.render(
element,
document.getElementById('root')
);
```
でも、次の例を見て、なんとなく理解、、

```コンポーネント組み合わせ.js
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```
（レポート）Scrum Fest Osaka 2020 Day2 "プロダクトオーナーのチームビルディング 〜 心理的安全性が高く、自走できる組織の作り方。" #scrumosaka.fuk

# はじめに

[Scrum Fest Osaka 2020](https://www.scrumosaka.org/)は、6/26-27に開催された、オンラインでの大規模カンファレンスです。

この記事では、2日目の14:25～14:45 #scrumosaka.fuk（福岡）で行われた「[プロダクトオーナーのチームビルディング 〜 心理的安全性が高く、自走できる組織の作り方。](https://confengine.com/scrum-fest-osaka-2020/proposal/13823)」のレポートです。

このセッションは、07/22にasleadのメンバーと2人で視聴しました。

スライドは[こちらで公開されています](https://www.slideshare.net/cowappa/ss-236289288/cowappa/ss-236289288)

# 講演内容

## 開発対象のサービス

- 楽天市場の売れ筋ランキングページ
- 商品とお客様の出会いをつなぐ
- ステークホルダーが多い
    - 開発チームは大阪
    - 事業はリモート
        - エンジニアは20人弱
        - プロダクトチームのリーダーが私

## プロダクトオーナーのチームビルディング

- どんな状況？
    - **プロジェクトがうまく回っているとはいえない状態**
    - ＰＯとエンジニアとで認識のギャップがある
    - 社内でもSランクのトラブル連発
    - 自信がなくなる負のスパイラル
- 今は？
    - **夢みたいな状態に！**
        - 進行がスムーズに
        - トラブルが減る
        - 定時で帰れる
        - 仕事が楽しい
        - 賞を貰った

## 原因

- PO1人でやる範囲が大きい
- **人それぞれ得意分野が違うのに、同じ範囲をやろうとしていた**
    - 大きくて難しい仕事をバラバラのメンバーで何をどこまでやればＯＫかわからない
    - 何とか回している状態

## 施策

- 役割分担
    - **POをプロダクトマネージャとプロジェクトマネージャに分けた**
        - 役割に対するスキルセットを定義した
        - PO4人を分けた
- スキルセット定義
    - 役割が責任を持つ範囲
        - PDM = Why / What
        - PJM = How / Who / When
- 期待値を示す
    - 名刺に書くレベルの職種が変わる
        - 人ごとにPJM向けかPDM向けかを判断する
        - 本人が腹落ちして職種変更
- プロセス整理
    - プロジェクトの承認に対して
        - ドキュメントのテンプレートかと承認者の明確化
- 研修でスキルアップ
    - 苦手なスキルを研修でフォロー
    - 人ごとの目標・期待値を1on1でフォロー
- チームとしての取り組み
    - 心理的安全性ゲーム
    - チームビルディング系ゲーム
    - お互いの違いを知る
        - 価値観に触れる
        - 互いの職種に納得感
    - ふりかえりをKPTからFun Done Learnへ
    - **Lofty Goal**
        - チームとしてどうなりたいか、将来の像について語り合う
            - 「ろくろ回したい！」
            - 「何を評価してろくろ回したい？」
            - 向上心に繋がった

## やり始めて2-3か月

- ふりかえりにて
    - 仕事が楽しい、という付箋が
    - 心理的安全性が芽生えつつある…！
    - ふりかえりのあとにこっそり泣いた。

## 心を鬼にした場面も

- 得意なタスクを手放さないといけない部分もあった
    - 新しい職種の働き方を身に付けないといけないから、やるべきしごとをやってもらえるようにする
    - 厳しいけどNGははっきり言う

## まとめ

- 難易度のコントロールをしていた
    - 大きな塊を小さなサイズへ
    - 手探りだった仕事を何をどれくらいやればよいか分かるように
- 役割分担をすることで、One Teamに

## 仕事がうまく回ってないと感じたら…

- 仕事の難易度や量ってどうなっている？
- タスクの種類をリストアップする
- どれくらい頑張ればいいのかみんなが分かっているか？
    - 自分とメンバーの期待値のギャップを探る
    - 話しあってみよう

# 感想戦

視聴後、チームメンバーと感想戦をしました。

- 今のチームの中での期待値はすりあっているか？
    - このチームは大丈夫
    - 分業化しているチームだと、期待値のすり合わせが大事なのかも
        - 今のチームはモブがあたりまえ、チームで成果を出すという価値観のもとに動いているため、期待値をわざわざ伝えなくてもわかってくれる
        - 自分がやる仕事に、わざわざ期待を考えることはない。相手に渡す、みたいな考え方になって初めて期待値が出てくる
        - チームがチームとして動いているのであれば、上記のような状態になっているはず
    - チームの外の仕事は、期待値がすり合ってないことが多い
        - 色々考えるべきところがある
- Lofty Goal
    - 大事だよね
    - チーム名がLofty Goalを表す
        - チーム名を付けよう！
- ふりかえり、色々なフレームワークを学びたい
    - チームで楽しくやってみよう
27歳プログラミング未経験から開発エンジニアになる話

###どーも「りょうちん」と申します。  
###今回の記事は、Webエンジニアになるためにすべきこと！というテーマです！  
先日、業界未経験からエンジニアになるチャンス頂きました。27歳、前職ネジ売ってました男子です。  今は試用期間中ですけど、実務でプログラミングできることがめちゃ嬉しいです。  
これからプログラミング学ぼうかなーて考えてる人とか、どうやったらエンジニアなれんの？ってかエンジニアなるのって簡単そう？ってネット記事に踊らされそうになってる方。笑  
####是非読んでください！！エンジニアになるのってそんな甘くないです！！  
#####ちなみに僕は、Kintoneでのシステム提供を現在主軸としている会社に勤めさせていただくことになりました。主にJavaScriptを使用します。ですので、今後はKintone、JavaScript周辺情報をメインに発信させて頂きます。  
これから出来るだけ毎日投稿していきますので、Twitterフォローお願いしますー！  

####で本題です！ずばり未経験からエンジニアになるためにはどーすりゃいいの？  
先に結論書きますと、「差別化すべし」ってことです。例えばポートフォリオ。よく見かけるのが、「Railsで作りました、Docker、CircleCI使ってます。Rspecでテスト書いてます。ビューはSlimです。本番環境はAWSで構築しました。」  
2年くらい前でしたら、上記の内容で「結構頑張ってるね！採用！」ってなったかもしれませんが、現在はこれぐらい出来て当たり前。という状況です。
学歴良くて、今現在の勤め先も一流企業の方でしたら、上記の内容でもエンジニアに転職できると思います。でも私みたいに学歴も大したことなく、職歴も普通(いや普通以下か？転職回数も多いし...)な人は、恐らく厳しいです。
この辺りはRUNTEQさんでも[「未経験から自社サービス開発企業でWebエンジニアになるために必要な学習量について」](https://blog.runteq.jp/programming-school/knowledge/2887/)にもレベル分けされて載ってますね。  
####じゃあ差別化の方法教えろよ
わかりました。まあ採用側は性格とかやる気も見てると思うので、私がイチから学習するとして考えると、「Single Page Application」の実装にも力入れますかね。その為にReactかVue.jsどっちかを学ぶと思います。2020年7月現在、この辺りの実装を頑張ってる未経験者の方はまだそこまで多くないと思います。
例えばWantedlyの求人内容を見ていると、求められている技術が書かれていることが多いので、そこから学習すべき分野も考えられると思います。  
####ちなみに色んなプログラミング言語をあちこちかじるのはオススメしません。
オブジェクト指向言語だと書き方は違えど、内部の仕組みや考え方は似ているところも多いので、どれか一本に絞って学習する方が、後々他の言語も理解しやすいと思います。

下記は私が行なってきた学習内容です。下記プラス「ポテパンキャンプ」のカリキュラムです。学習内容が足りてるとは思いませんが参考になれば。
- Progate(HTML CSS JavaScript jQuery Python PHP Ruby Ruby on Rails コマンドライン Git) 200時間
- サイト模写(isara, ポテパンキャンプ)100時間
- Railsチュートリアル(4週) 240時間
- 著書「Webを支える技術」25時間
- 著書「プロを目指す人のためのRuby入門」80時間
- 著書「Ruby on Rails5速習実践ガイド」90時間
- 著書「データベース技術」25時間
- 著書「リーダブルコード」10時間
- 著書「SQLアンチパターン」25時間
- 著書「Ruby on Rails6実践ガイド」20時間
- 著書「基礎からのネットワーク＆サーバー構築改訂3版」20時間
- 著書「絵で見てわかるITインフラの仕組み【新装版】」20時間

未経験だと所謂web系エンジニア(自社開発)に勤めたいなーって考える人多そうですけど(なんかお洒落でカッコよく感じるよね！)、このコロナ渦の中ハードルは高いです。実戦ですぐ活躍できる実務経験者が求められてます。
周りとは違った技術を学習するなどして差別化することが大切だと思います！
serializers.pyでシリアライズしたデータでpkを使えるようにする方法

djangoのmodels.pyで定義したmodelをシリアライズして、テンプレートに返し、
返ってきたmodelの一つ一つをpkを使って自由自在に扱えるようにしたい！
と思って、getJSONを使ってデータを取得した後に、「data.pk」とかやって、「あれ、undefinedじゃねぇか」と悪戦苦闘したので、備忘録で記録しておきます。

```
class EvacuationSerializer(GeoFeatureModelSerializer):

    class Meta:
        model=Evacuation
        fields=('id','evacuation_site','location','geom',)
        geo_field=('geom')
```

やり方は簡単で、Metaクラスのfieldsにidを指定してあげるだけです。
忘れないようにしましょう。
TwitterAPIから特定のキーワードを含むツイート数を調べる


TwitterAPIの使い方の学ぶために、キーワードとして「コロナ」を含むツイートの件数を調べることにしました。

「コロナ」を含む全てのツイートを取得したいですが、TwitterAPIにはこちら[リンク](http://westplain.sakuraweb.com/translate/twitter/Documentation/REST-APIs/Public-API/API-Rate-Limits.cgi)のように
・180リクエスト/15分 かつ 100ツイート/１リクエストという取得件数の制限
・過去７日間分のみという取得対象期間の制限
があります。


そのため20分ごとに1秒間「コロナ」を含むツイートの取得を行いました。

期間指定の方法はこちらの記事を参考にさせていただきました。
[TwitterAPIで期間指定してTweetを取得する方法](https://qiita.com/areph/items/0745cb744a12810334c6)

##実行
試したコードがこちらです。

```python:qiita.py
import urllib
from requests_oauthlib import OAuth1
import requests
import sys
import datetime
import openpyxl


def search_tweets(CK, CKS, AT, ATS, word, count, range):

    # 文字列設定
    word += ' exclude:retweets' # RTは除く
    word = urllib.parse.quote_plus(word)
    # リクエスト
    url = "https://api.twitter.com/1.1/search/tweets.json?lang=ja&q="+word+"&count="+str(count)
    auth = OAuth1(CK, CKS, AT, ATS)
    response = requests.get(url, auth=auth)
    data = response.json()['statuses']
    # 2回目以降のリクエスト
    cnt = 0
    tweets = []
    while True:
        if len(data) == 0:
            break
        cnt += 1
        if cnt > range:
            break
        for tweet in data:
            tweets.append(tweet['text'])
            maxid = int(tweet["id"]) - 1
        url = "https://api.twitter.com/1.1/search/tweets.json?lang=ja&q="+word+"&count="+str(count)+"&max_id="+str(maxid)
        response = requests.get(url, auth=auth)
        try:
            data = response.json()['statuses']
        except KeyError: # リクエスト回数が上限に達した場合のデータのエラー処理
            print('上限まで検索しました')
            break
    return tweets


# APIの秘密鍵
CK = '*************************' # コンシューマーキー
CKS = '*************************************************' # コンシューマーシークレット
AT = '**************************************************' # アクセストークン
ATS = '*************************************************' # アクセストークンシークレット

d=datetime.datetime(2020,7,16,00,00,00)
td=datetime.timedelta(minutes=20)
n=72
f="%Y-%m-%d_%H:%M:%S_"
l=[]
for i in range(n):
    l.append((d+i*td).strftime(f))

dd=datetime.datetime(2020,7,16,00,00,1)
tdd=datetime.timedelta(minutes=20)
nn=72
f="%Y-%m-%d_%H:%M:%S_"
ll=[]
for i in range(nn):
    ll.append((dd+i*tdd).strftime(f))

print(l)
print(ll)
sss=[]
for (i,n) in zip(l,ll):
    word = f'コロナ since:{i}JST until:{n}JST' # 検索ワード
    count = 100 # 一回あたりの検索数(最大100/デフォルトは15)
    range = 5 # 検索回数の上限値(最大180/15分でリセット)
    # ツイート検索・テキストの抽出
    tweets = search_tweets(CK, CKS, AT, ATS, word, count, range)
    # 検索結果を表示
    
    kk=(str(len(tweets)))
    sss.append(kk)
    print(kk)
    wb=openpyxl.load_workbook("corona.xlsx") #Excelファイルを起動
    ws=wb["Sheet1"]

for (i, j) in enumerate(sss, 1) :
    ws.cell(row=i,column=1,value=int(j))
wb.save('corona.xlsx')'
```
こちらのコードでは、7月16日に20分ごとに1秒間72回取得し、件数を"corona.xlsx"に入力しています。
これを元に1日の件数を推定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672726/42318a62-4a3f-7d88-5fc3-a86516fdb3a2.png)

2020/7/16～2020/7/22の一週間でのツイートはこのようになり、合計で3561600件、一日平均50万件になることがわかりました！
【PHP】よく使う比較分、デバッグコード　等

最近、PHPのコードも書く事が増えてきて、
脳内ではやりたい事は決まってるんだけど、PHPだとどう書くんだったっけ？みたいなのを列挙。
見ればすぐに、思い出す系のやつです。

## 定数定義
`define("SYSTEM_NAME","hogehogeシステム");`

## 変数定義
`$i = 0;`
`$val = "moji";`
`$flag = false;`
`$data = SYSTEM_NAME;`

## 数値比較
これは、他の言語と変わらない。
`if($i > 0){
}`

## 文字比較
`if(strcmp("もじA","もじB") == 0){
            //一致した場合
}`

##文字連結
他の言語だと「+」とか「&」
`$buff =  $buff.$key.",".$name."end";`

##文字分割
他の言語だと「split」とか
カンマごとに分割する例
`$params = explode(",", $row);`

##連想配列
`$result = array();
$result["key"] = "value";`

##ループ
`for ($i = 0; $i < count($data); $i++) {
   $row = $data[$i];
}`

連想配列の時とか
`foreach ($result as $key => $value) {
  $item = $result[$key];
}`

##function
`function getValue($key){
    return "value";
}`

##コンソール出力
文字出力
`echo "出力";`
変数出力
`var_dump($val);`

##お約束
<?php
?>
「?>」は、最後までPHPのコード(htmlのコードが最後なら必要）ならなくてもいい。
スプレッドシートの関数メモ帳

たまに使う超便利な関数をメモしていく。

|説明  |関数  |
|---|---|
|セルAとセルBの文字列が等しいかどうかを調べる。  |=EXACT(A1,B1)  |
|A列にあってB列にないものだけを表示（重複の確認）  |=IF(COUNTIF(\$B$1:$B$1000,A1)=0,A1,)  |
|文字列結合の範囲指定。<br>""の中は空白または区切りたい文字をいれる。  |=JOIN("",A1:Z1)<br>=JOIN(",",A1:Z1) |
|文字列結合  |=A1&A2&A3  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |
|4  |5  |


# Google Apps Script で便利術

## セルの結合解除

スプレッドシート＞ツール＞スクリプトエディタを開き下記のコードをコピペして、保存→実行
※保存と実行はコード記載部分のすぐ上に小さいアイコンがある。
※実行後、権限の承認を要求するモーダルが開くこともある。

```
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var ranges = sheet.getDataRange().getMergedRanges();

  for (var i = 0; i < ranges.length; i++) {
    var mergedRange = ranges[i];
    var value = mergedRange.getDisplayValue();
    mergedRange.breakApart();
    mergedRange.setValue(value);
  }  
}
```
【Flutter】FirestoreのTimestampとDartのDateTimeの日付とタイムスタンプの相互変換の方法について

## はじめに

やりかた忘れるのでメモしておきます。

## Timestamp から DateTime への変換

```dart
Map<String, dynamic> map = ... // firestoreからのドキュメントデータが入ってるとする

if (map['createdAt'] is Timestamp) {
  DateTime createdAt = map["createdAt"].toDate();
}
```

## DateTime から Timestamp への変換

```dart
Timestamp createdAtTimestamp = Timestamp.fromDate(createdAt);
```
【Python】データサイエンス100本ノック（構造化データ加工編） 010 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/a3ShkYQiCcA)もしています。

##問題
P-010: 店舗データフレーム（df_store）から、店舗コード（store_cd）が"S14"で始まるものだけ全項目抽出し、10件だけ表示せよ。

##解答
```:コード
ddf_store.query("store_cd.str.startswith('S14')", engine='python').head(10)
```

##出力
|  | store_cd | store_name | prefecture_cd | prefecture | address | address_kana | tel_no | longitude | latitude | floor_area |
|--:|:--|:--|--:|:--|:--|:--|:--|--:|--:|--:|
| 2 | S14010 | 菊名店 | 14 | 神奈川県 | 神奈川県横浜市港北区菊名一丁目 | カナガワケンヨコハマシコウホククキクナイッチョウメ | 045-123-4032 | 139.6326 | 35.50049 | 1732.0 |
| 3 | S14033 | 阿久和店 | 14 | 神奈川県 | 神奈川県横浜市瀬谷区阿久和西一丁目 | カナガワケンヨコハマシセヤクアクワニシイッチョウメ | 045-123-4043 | 139.4961 | 35.45918 | 1495.0 |
| 4 | S14036 | 相模原中央店 | 14 | 神奈川県 | 神奈川県相模原市中央二丁目 | カナガワケンサガミハラシチュウオウニチョウメ | 042-123-4045 | 139.3716 | 35.57327 | 1679.0 |
| 7 | S14040 | 長津田店 | 14 | 神奈川県 | 神奈川県横浜市緑区長津田みなみ台五丁目 | カナガワケンヨコハマシミドリクナガツタミナミダイゴチョウメ | 045-123-4046 | 139.4994 | 35.52398 | 1548.0 |
| 9 | S14050 | 阿久和西店 | 14 | 神奈川県 | 神奈川県横浜市瀬谷区阿久和西一丁目 | カナガワケンヨコハマシセヤクアクワニシイッチョウメ | 045-123-4053 | 139.4961 | 35.45918 | 1830.0 |
| 12 | S14028 | 二ツ橋店 | 14 | 神奈川県 | 神奈川県横浜市瀬谷区二ツ橋町 | カナガワケンヨコハマシセヤクフタツバシチョウ | 045-123-4042 | 139.4963 | 35.46304 | 1574.0 |
| 16 | S14012 | 本牧和田店 | 14 | 神奈川県 | 神奈川県横浜市中区本牧和田 | カナガワケンヨコハマシナカクホンモクワダ | 045-123-4034 | 139.6582 | 35.42156 | 1341.0 |
| 18 | S14046 | 北山田店 | 14 | 神奈川県 | 神奈川県横浜市都筑区北山田一丁目 | カナガワケンヨコハマシツヅキクキタヤマタイッチョウメ | 045-123-4049 | 139.5916 | 35.56189 | 831.0 |
| 19 | S14022 | 逗子店 | 14 | 神奈川県 | 神奈川県逗子市逗子一丁目 | カナガワケンズシシズシイッチョウメ | 046-123-4036 | 139.5789 | 35.29642 | 1838.0 |
| 20 | S14011 | 日吉本町店 | 14 | 神奈川県 | 神奈川県横浜市港北区日吉本町四丁目 | カナガワケンヨコハマシコウホククヒヨシホンチョウヨンチョウメ | 045-123-4033 | 139.6316 | 35.54655 | 890.0 |

##解説
・PandasのDataFrame/Seriesにて、条件に当てはまる先頭データを確認する方法です。
・条件に当てはまる情報を確認したい時に使用します。
・**'startswith(<文字列>)'は、指定した文字列で始まるかどうかを判定する関数**であり、始まる場合はTrue、始まらない場合はFalseを返します。
・ただし、**'query('str_startswith(<文字列>))'は、指定した文字列で始まることを条件として指定します**。
・今回の場合、store_cd を文字列に置換するために'store_cd.str'とし、'.startswith('S14')'を続けることで、「S14」で始まる store_cd を指定しています。
・'engine = 'python''について、query の引数である engine には'python'か、'numexpr'かを選択することができますが、strを用いる場合は、'python'を指定してあげないとエラーが発生してしまいます。
競プロで使うための GO 入門 ～標準入出力～

# Index

- [はじめに](https://qiita.com/CamouflageSix/items/ab004a1078f491bd15ef)
- [Hello World](https://qiita.com/CamouflageSix/items/05e5a0f9616e28d6fca4)
- [標準入出力]
- [変数・定数]
- [型変換]
- [制御構文]
- [配列](https://qiita.com/CamouflageSix/items/41d901b9b170d5565895)
- [ソート](https://qiita.com/CamouflageSix/items/dbc2017504571e5a65aa)
- [関数](https://qiita.com/CamouflageSix/items/afb42d399a27f5ca3cf8)
- [ASCII変換](https://qiita.com/CamouflageSix/items/283655027e6581a79b4b)

# 標準入出力
標準入出力は、"fmt"パッケージをインポートする。

```GO:
package main

import (
    "fmt" // fmtパッケージ
)

func main() {

}
```

## 標準入力(Standard Input)

### fmt.Scan()
- 改行またはスペースまでの文字列を取得する。

```GO:
    // 入力に123と書く

    var d int
    fmt.Scan(%d)
    
    fmt.Println(d) // ->123
```

### 高速で読み込み(bufio.NewScanner(os.Stdin))
高速で大量に読み込む必要がある場合

```GO:
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

// 文字列を読み込み戻り値をintで返す
func nextInt() int {
    sc.Scan()
    ret, e := strconv.Atoi(sc.Text())
    if e != nil {
        panic(e)
    }
    return ret
}

// メイン
func main() {
    // スペースで文字列を区切る
    sc.Split(bufio.ScanWords)

    // 入力例
    // 5
    // 1 2 3 4 5
    
    n := nextInt()
    fmt.Println(n)
    for i := 0; i < n; i++ {
        m := nextInt()
        fmt.Printf("%d ", m)　// ->1 2 3 4 5
    }
}
```

##標準出力(Standard Output)

### fmt.Println()

- 引数を改行付きで出力する
- 引数が複数の場合は、スペースが入る

```GO:
    // 数値
    fmt.Println(123) // ->123
    
    fmt.Println(123, 456) // ->123 456

    // 文字列
    fmt.Println("abc") // ->abc
    
    fmt.Println("abc", "def") // ->abc def
    
    // 数値, 文字列
    fmt.Println(123, "abc") // ->123 abc
```

### fmt.Printf()

- フォーマットを指定して出力する
- 第１引数にフォーマットを指定しないこともできる
- 第２引数にスペースは含まれない

```GO:
    var d int = 123

    // %d数値指定
    fmt.Printf("%d\n", d) // ->123
    
    // %s文字列指定(エラーにならないが出力で指摘される)
    fmt.Printf("%s\n", d) // ->%!s(int=123)
    
    // %v汎用
    fmt.Printf("%v\n", d) // ->123


    var s string = "abc"
    
    // 文字列指定
    fmt.Printf("%s\n", s) // ->abc
    
    // %d数値指定(エラーにならないが出力で指摘される)
    fmt.Printf("%d\n", s) // ->%!d(string=abc)

    // %v汎用
    fmt.Printf("%v\n", s) // ->abc
    
    // %#vダブルクウォート付加（文字列であればダブルクウォートが付加される）
    fmt.Printf("%#v\n", s) // ->"abc"
```
vagrant 環境を配布する

vagrantを使うと自身のPC内に仮想環境を構築でき便利なのですが、
自分が使っていた環境を複製したり、他のメンバーに同じ環境を渡したいことがあります。

その時の手順です。

### 配布元
##### パッケージ化する 
まず、使っている環境を配布するように以下のコマンド使って使っている環境をパッケージ化します

```
vagrant package --output [好きなbox名].box
```

完了すると、実行したフォルダ直下に[好きなbox名].boxができているので、こちらのパッケージ.boxとVagrantfileを配布します


### 配布先

##### フォルダ作成 + 配布されたboxを配置
配布されたboxを配置するためのフォルダを作成します

```
mkdir [フォルダ名]
```
配布されたboxをそこに配置します


##### boxを登録
以下のコマンドを使用し配布元のboxからboxを登録します

```
vagrant box add [指定のbox名] ./[配布されたbox名].box
```

念のため実行した以下のコマンドでちゃんと追加されたか確認します

```
vagrant box list
```

##### boxを使用
先ほど登録した名で以下のコマンド追加Vagrantfileを作成します

```
vagrant init [登録したBox名]
```

##### Vagrantfileの編集 (不必要な場合は飛ばしてください)
配布されたVagrantfileを基に作られたVagrantfileを編集していきます

私の場合は、以下の設定の追加と、ipアドレスを変更しました

```
#IPアドレスの設定
config.vm.network "private_network", ip: "192.168.33.18"

#共有フォルダの設定
config.vm.synced_folder"./webroot","/var/www/html/",mount_options:['dmode=777', 'fmode=666']
```

##### vagrant 起動
以下のコマンドでvagrant を起動します

```
vagrant up
```

起動できたら完了です


手軽に配布できますね、これならグループ開発などでも、とても助かります