OmniAICreator/Qiita-1.07M huggingface dataset:
【iPhone】LINEで劣化しない動画の共有方法

LINEで動画をそのままアップロードしてしまうと、画質が落ちてしまうので、
劣化しない動画アップロードの方法を書いておきました。

先輩の結婚式の動画素材集め用に作ったマニュアルです。
iPhoneやLINEに疎い人にも分かりやすいように作ったので公開しておきます。

# 流れ
1. 写真アプリからiPhone内のフォルダに保存
    2. 写真アプリを開く
    3. 動画を選択して共有
    4. LINEから開けられるファイルとして保存
2. LINEからファイルをアップロード
    3. トークを開く
    4. ファイル形式でアップロード
    5. アップロードを確認
   

# 1. 写真アプリからiPhone内のフォルダに保存
## 1-1.写真アプリを開く
<img width="375" alt="IMG_7C3BB8B42D89-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/180836/52051fcf-8ed4-93f8-6001-c8d62f0102cd.jpeg">

## 1-2. 動画を選択して共有
共有したい写真や動画を選択して、左下の共有ボタンをタップしてください
<img width="375" alt="IMG_7C3BB8B42D89-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/180836/06671286-e908-a0ab-0a98-61a8f49e0385.png">

## 1-3. LINEから開けられるファイルとして保存
共有メニューから、「ファイルに保存」を選択してください
<img width="375" alt="IMG_7C3BB8B42D89-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/180836/761012a7-c2f4-d12e-f441-3f87954a6113.png">

「このiPhone内」を押すと、フォルダがたくさん出てくるので、その中から一つ適当に選んで（なんでもいいです）、追加を押してください

<img width="375" alt="IMG_7C3BB8B42D89-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/180836/f404420c-c386-1f7e-d498-dc339557239f.png">

これで、動画がiPhone内のフォルダに保存され、LINEにアップロードできる状態になりました。
次はLINEアプリを開いてください。

# 2. LINEからファイルをアップロード
## 2-1. トークを開く
動画を共有したい相手のトークを開いてください

## 2-2. ファイル形式でアップロード

左下の「＋」ボタンをタップしてください
<img width="375" alt="IMG_7C3BB8B42D89-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/180836/bc5357af-e76b-ba81-ef8a-9253939619f4.png">

ファイルをタップしてください
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/c877eee8-9914-9d62-996b-78b8ddd4eaa3.png">

先ほど追加したフォルダをタップして、下っていってください
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/9d71a92a-0485-2ce6-18be-5628d8f6b2b2.png">

追加した動画が表示されるはずなので、その動画をタップしてください。
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/652c0c93-529c-9bdd-f5da-1ad2b9c1eb2e.png">

「送りますか？」とダイアログが表示されるので、「送信」をタップしてください
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/82f23551-b720-c15b-4340-1177e62c92b5.png">


## 2-2.アップロードを確認
写真のようにファイルのアイコンがついているメッセージが出たらOKです
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/7a0d9b71-5e70-2600-1684-10d76411f5b0.png">


# （備考）iPhone内フォルダに保存した動画の削除
LINEにアップロードできたので、iPhone内のフォルダに保存した動画は削除してしまってOKです。
※フォルダ内の動画を削除しても、「写真アプリ」内の動画は削除されるわけではありません

LINEアプリ内で、先ほどと同じ要領で保存した動画まで下ってください
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/652c0c93-529c-9bdd-f5da-1ad2b9c1eb2e.png">

動画を長タップして離すと、メニューバーが出るので、右矢印を押してください。
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/f1ae269b-7016-99e3-1b0f-8f2f8149e902.png">

削除ボタンが表示されるので、これをタップすると削除できます
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/180836/dad974b5-c9ec-780b-d680-6181f59f6608.png">
xcrunが見つからない場合の対処

下記のようなエラーが発生し、gitコマンドなどが使えない場合の対処

```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

## 解決策その１
下記のコマンドで、xcode-selectをインストール

```shell
$ xcode-select --install
```

## 解決策その2
下記のコマンドで、xcodeのパスを指定

```shell
$ xcode-select --switch /Applications/Xcode.app
```
スワイプで戻るを簡単に実装

#スワイプバック
戻るボタンを押してpopViewControllerをするのってめんどくさいですよね。
TwitterとかSlackとか有名アプリはいちいち一番指の届きにくい左上の戻るボタンをタップしなくても、
スワイプで戻れるように実装されています。

#手順
1. UIViewControllerのExtensionを書きます

```
import UIKit

extension UIViewController {

    func setSwipeBack() {
        let target = self.navigationController?.value(forKey: "_cachedInteractionController")
        let recognizer = UIPanGestureRecognizer(target: target, action: Selector(("handleNavigationTransition:")))
        self.view.addGestureRecognizer(recognizer)
    }
}
```
2. Extensionに書いたsetSwipeBack()をViewDidLoad()あたりで呼んどきます

```
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setSwipeBack()
    }
}
```
3. 完成
【メモ】Atom Package: Rainbow CSV

# 概要
### 環境
MacBook Pro/Mojave/Atom

### やりたいこと
こちらでVSCodeのステキ拡張を知り、Atomにもあるのかしら？と。
https://qiita.com/0w0/items/07a481921a2ac09a049f

ご覧の通り、sublimeにもあり、フルラインナップ？
https://github.com/mechatroner

# 手順
### インストール
形式上、このセクションは設けたものの・・・
やることはインストールだけ。

環境設定>インストール　で"Rainbow-csv"で検索
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/c60ffaa2-d9a7-3fee-e6fa-b8610db01cb3.png)

### 確認
インストール後、CSV開くと次のような感じに。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/a77624cd-9c47-9e44-12e0-fa3ad1d4f133.png)

# まとめ
めでたしめでたし。
Unityで手軽なモーション修正（Timeline✕FinalIK）



この記事は [VTuber Tech #1 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/vtuber) 13 日目の記事です。

#自己紹介
こんにちは[ゆず](https://twitter.com/Yuzu_Unity)です。

自分はUnityエンジニア・3DCGデザイナーです。
VTuberのシステム構築、キャラクターセットアップ等を行っていたりするものです。
先日のVTuberハッカソン全国大会にてクラスター賞を貰いました！

#はじめに
VTuberを作る際モーションキャプチャーといった機材を用いることはよくあるのですが……
[11日目のさんたーPさん](https://qiita.com/Santarh/items/de41ca5662f7e3520091)が解説してくれています。

しかし、モーションキャプチャーには精度が綺麗に出なかったり、そもそもキャラクターの体型と(中の人)が違うので貫通してしまったりなどなど、修正する要素が出てきてしまいます。

それを修正する方法としては
DCCツール(Maya・MotionBuilder等)が最初に挙げられるかもしれませんが、
やはりランニングコストが高いのでUnity上で手軽に修正する方法を少し紹介したいと思います。

今回は有名な有料アセットFinalIKを利用して簡単な修正をしていきたいと思います。

#そもそもFinalIKは何をするアセット？？？
![FinalIK](https://d2ujflorbtfzji.cloudfront.net/key-image/36710990-aa59-4e1e-bcaf-d4f7eda7c40b.jpg)
VRChatやVR等でフルボディIKを使うもの…
だけではなく、もともとはUnityなのでゲームで使うもので
例えばAimIK銃を打つときに銃口がエイムの方向に向かせるなどなど。
*現在のアニメーションを[IK](https://shade3d.jp/store/marketplace/articles/startanimation/vol9.html)を使って上書きで修正*するアセットです。

#Timelineと併用してみよう
まずはTimelineのAnimationTrackにキャラクターを配置し
モーションキャプチャー等のアニメーションクリップを流し込みます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/308905/5ca98765-0ccb-3c84-4bed-5fd26795d05b.png)

再生！！！！

![gif_animation_004.gif](https://qiita-image-store.s3.amazonaws.com/0/308905/bda7006f-f900-4c96-b19b-689e19ef86ff.gif)
実際にあったデータです(PerceptionNueron)
これはひどい…（ここまで来たら流石に撮り直しますがｗ）

今回は左腕を貫通しないように直してみましょう。
キャラクターにFinalIKのFullBodyBipedIKを入れます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/308905/46db795d-1af0-2d99-5b8b-4d9e70a60731.png)

空オブジェクトを２つ生成し手の位置、肘の位置をイメージした場所に置きます。
LeftArmのターゲットにそれぞれドラッグして
PositionWeightの割合を少し上げるだけで…
![gif_animation_005.gif](https://qiita-image-store.s3.amazonaws.com/0/308905/24a26876-e64f-6e98-e3d2-1f2afc3d319e.gif)

と、とりあえず貫通しなくなりました…
一安心

モーションデータのすべてを修正することはないので、
このようにIKを使って修正といった細かい作業を少し加えるだけで
簡単に修正ができます。
Timelineを用いれば先程の空オブジェクトをアニメーションさせたりすることも可能になります。

#FinalIKをプレイモードじゃなくても実行する方法
FullBodyBipedIK.csのスクリプトを開き
[ExecuteInEditMode]属性を追加します！！（プレイ中ではなくても実行する属性）
※これはいろいろなアセットで使えるテクニック！！！

![DtZ2vB0V4AINsmv.jpg](https://qiita-image-store.s3.amazonaws.com/0/308905/c8c61d69-7e1f-f271-d234-70b5c30773df.jpeg)


#もっときれいに修正するには…
有料アセットのVeryAnimationやUMotionPro
でクリップ単位で修正
もしくは完全手動修正……

また、3DCGのリギングを勉強しよう！！！（きっと楽しい…IK、コンストレイント）
#もっと簡単に修正するには…
Timelineの拡張や、IKを自分で実装しちゃおう！
#まとめ
モーションキャプチャーのデータ修正は大変！
ここぞというところ以外はしないように、モーション撮影時にしっかりチェックしよう！！
BIOSの`GTSTCK`から得たスティックの状態に応じてXY座標を更新する

BIOSの`GTSTCK`から得たスティックの状態に応じてXY座標を更新する

```
# HレジスタをX座標
# LレジスタをY座標として
# Aレジスタのスティックの値に応じてXY座標(HL)を更新
# 破壊されるレジスタ: BC

UPDATE_PLAYER_XY:
    SLA A
    SLA A
　　LD C,A
    LD B,0
    PUSH HL // 追記
    LD  HL,TABLE_XY
    ADD HL,BC
    LD (JUMP + 01H),HL
    POP HL // 追記
JUMP:
    JP 0000H 

TABLE_XY:
# 0:
    NOP
    NOP
    NOP
    RET
# 1:
    NOP
    DEC L
    NOP
    RET
# 2:
    INC H
    DEC L
    NOP
    RET
# 3:
    INC H
    NOP
    NOP
    RET
# 4:
    INC H
    INC L
    NOP
    RET
# 5:
    NOP
    INC L
    NOP
    RET
# 6:
    DEC H
    INC L
    NOP
    RET
# 7: 
    DEC H
    NOP
    NOP
    RET
# 8:
    DEC H
    DEC L
    RET
```
SATySFi 用のフォントライブラリを作ってみた

新世紀に相応しい組版処理ソフトウェアであるところの [SATySFi] であるが、現在の所、フォントを追加するためには fonts.satysfi-hash を手動で<ruby>弄<rp>（</rp><rt>いじ</rt><rp>）</rp></ruby>らねばならず、少々手間なので簡易パッケージマネージャー [Satyrographos] とフォントライブラリ [SATySFi-fonts-theano] を作ってみた。


## インストール方法
まず、SATySFi がビルドできるようになっていることを要求する。

### SATySFi の依存ライブラリとOPAM
既に SATySFi をインストールをしている読者はこの節を飛ばしてほしい。

Ubuntu （含 WSL）の場合は以下のようになる。この節は [zr-tex8r/make-satysfi.sh](https://gist.github.com/zr-tex8r/0ab0d24255ecf631692c1f0cbc5ca026) を参考にした。

```sh
$ sudo apt -y update
$ sudo apt -y install build-essential git m4 unzip curl ruby

$ yes '' | sh <(curl -sL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)
```

OPAM のインストール後には、OPAM を設定せねばならない。また、ここでは OCaml 4.06.0 をインストールすることにする。筆者の環境では OCaml 4.07.1 でも動くが、SATySFi の README.md には 4.06.0 が指定されているので、ここではそれに従う。

```sh
# 普通の Ubuntu はこちら
$ opam init --auto-setup --comp 4.06.0
# WSL はこちら
$ opam init --auto-setup --comp 4.06.0 --disable-sandboxing
```

OPAM のインストール後はシェルに環境変数を設定する。

```sh
$ eval $(opam env)
```

### Satyrographos と SATySFi
以下の様に、SATySFi と Satyrographos をインストールする。

```sh
$ opam repository add satysfi-external https://github.com/gfngfn/satysfi-external-repo.git
$ opam repository add satyrographos https://github.com/na4zagin3/satyrographos-repo.git
$ opam update

$ opam install -y satysfi
$ opam install -y satyrographos

$ satyrographos install
```

この時、以下の様なエラーが出ることがある。Satyrographos は `~/.satysfi/dist` に変更を加えるので、`mv ~/.satysfi ~/.satysfi.old` として、`~/.satysfi` を一旦消してほしい。

```shell-session
$ satyrographos install
opam dir: /home/<username>/.opam/4.06.0/share
Directory /home/<username>/.satysfi/dist is not managed by Satyrographos.
Please remove /home/<username>/.satysfi/dist first.
```

```sh
$ mv ~/.satysfi ~/.satysfi.old
$ satyrographos install
```

### SATySFi-fonts-theano
以上で SATySFi-fonts-theano をインストールする準備が整った。以下の様にインストールできる。

```sh
$ opam install satysfi-fonts-theano
$ satyrographos install
```

これにより、フォントが `~/.satysfi/dist/fonts` にコピーされ、適切なエントリが `~/.satysfi/dist/hash/fonts.satysfi-hash` に書き込まれる。

## 利用法
SATySFi-fonts-theano は以下のフォントを含んでいる。

|SATySFi フォント名|フォントファイル名             |
|-----------------|--------------------------|
|`TheanoDidot`      |TheanoDidot-Regular.otf   |
|`TheanoModern`     |TheanoModern-Regular.otf  |
|`TheanoOldStyle`   |TheanoOldStyle-Regular.otf|

例えば、SATySFi 0.0.3 において `TheanoOldStyle` を利用したい場合は、以下の以下の様にフォントを指定すればよい。

```satysfi
let-inline ctx \greek it = 
  let ctx =
    ctx |> set-font Latin (`TheanoOldStyle`, 1., 0.)
      |> set-font OtherScript (`TheanoOldStyle`, 1., 0.)
  in
  read-inline ctx it
```

[用例](https://github.com/na4zagin3/SATySFi-fonts-theano/blob/master/doc-fonts-theano-ja.saty)を以下に掲げる。

![フォント用例](https://qiita-image-store.s3.amazonaws.com/0/20044/16859159-eb3e-6d91-c136-7899cef147bb.png)


[SATySFi]: https://github.com/gfngfn/SATySFi
[Satyrographos]: https://github.com/na4zagin3/satyrographos
[SATySFi-fonts-theano]: https://github.com/na4zagin3/SATySFi-fonts-theano
SQSにキューされるメッセージをサーバにポーリングして、コンソール上に自動表示させてみた。

# やりたいこと
AWSのSQSヘキューされたメッセージをEC2へポーリングしてサーバのコンソール上に通知させたい。以前「[AWSのboto3を使ってサーバのコマンド結果をメールに飛ばしてた。](https://qiita.com/ninvjin/items/ec5e9a2f94e057473db0)」を書きましたが、今回はその延長で。
 

# 方法
boto3を利用して、Linuxサーバ上（EC2上で）にスクリプトを作成・実行(スクリプト内容はのちほど)。

# 前提
***※今回は[以前作成した記事](https://qiita.com/ninvjin/items/ec5e9a2f94e057473db0)の延長で、サーバのコマンド結果がSNS経由でSQSへキューされることを前提としています。***

- EC2を立てる(ここでのサーバはRHEL系を想定してます。)
- EC2にaws cli、python3、boto3のインストール。
- aws configureでユーザ認証。
- SQSでキュー作成。

# コード
事前にSQSのURLを記載したiniファイル作成する。（スクリプトファイルにこれを記載する事も可能だとは思いますが、それを試す余裕がなかったのでQiitaの他記事を参考に今回作成してます。）

```
### config.ini (拡張子.iniファイル) ###
[sqs]
url :https://sqs.ap-northeast-1.amazonaws.com/9999999999/sqs_queue_test
```
そして、boto3を利用したスクリプトを以下のように作成。内容としては、SQSのキューにメッセージが受信される度（本スクリプトでは1分毎）に、ポーリング処理でサーバのコンソール上にそのメッセージを表示させる。メッセージは表示後に削除。

```
### receive_sqs.py ###

import configparser
import boto3
import json
import time

# configファイルの読み込み（iniファイルのパスを指定）
ini = configparser.ConfigParser()
ini.read("/XXXX/config.ini")

sqs = boto3.client('sqs')
url = ini.get("sqs", "url")

# キューの先頭にあるメッセージを表示・削除（ここでは1分毎にポーリング処理）
while True:
    response = sqs.receive_message(
        QueueUrl=url,
        AttributeNames=['SentTimestamp'],
        MaxNumberOfMessages=1,
        VisibilityTimeout=0,
        WaitTimeSeconds=0
    )

    if 'Messages' in response and response['Messages']:
        message = response['Messages'][0]
        print(message)
        receipt_handle = message['ReceiptHandle']
        sqs.delete_message(
            QueueUrl=url,
            ReceiptHandle=receipt_handle
        )
        
    time.sleep(60)
```

# 参考にしたもの
以下参考にさせていただきました。ありがとうございました。
・[CloudWatchからSNS→SQS、AWS SDK for RubyでQueue取り出し](http://www.smokeymonkey.net/2013/10/aws2cloudwatchsnssqsaws-sdk-for.html)
・[Boto3(AWS SDK for Python)でSQSに送信したメッセージをLambdaでポーリングして受信してみた](https://dev.classmethod.jp/cloud/aws/boto3_sqs_lambda_schedule_trial/)
・[AWS SDKでSQSをPythonで操作する](https://qiita.com/paper2/items/31fe6b0d29f7f72991df)
LXDをapt版からsnap版に移行する

# 概要

余っているマシン2台にUbuntu Server + LXDをいれて実験用にコンテナを作って遊んでいるのだが、
1台はUbuntu Server 16.04で、もう1台が18.04なので、インストールされたLXDのバージョンが違う。

そのため2台のマシン間でLXDコンテナのマイグレーションができなかった。

ということで、どちらのマシンにもsnap版のLXDをインストールしてバージョンを揃え、
マイグレーションができるようにした(
残念ながらsnap版ではライブマイグレーションは今の所できない
追記: どこのバージョンからかはわからないが、`snap set lxd criu.enable=true`でできる模様、ただ実験してみると失敗することが多い)。

# 手順

まずはsnap版のLXDをインストール

~~~
$ sudo snap install lxd
~~~

apt版からsnap版への以降には、`lxd.migrate`という便利コマンドがある。
コマンドを叩いたあと、`yes`とタイプすればapt版からsnap版に移行してくれる。助かる！

~~~
$ sudo lxd.migrate 
=> Connecting to source server
=> Connecting to destination server
=> Running sanity checks

=== Source server
LXD version: 2.0.11
LXD PID: 1429
Resources:
  Containers: 1
  Images: 2

=== Destination server
LXD version: 3.1
LXD PID: 8716
Resources:
  Containers: 0
  Images: 0
  Networks: 0
  Storage pools: 0

The migration process will shut down all your containers then move your data to the destination LXD.
Once the data is moved, the destination LXD will start and apply any needed updates.
And finally your containers will be brought back to their previous state, completing the migration.

Are you ready to proceed (yes/no) [default=no]? yes
=> Shutting down the source LXD
=> Stopping the source LXD units
=> Stopping the destination LXD unit
=> Unmounting source LXD paths
=> Unmounting destination LXD paths
=> Wiping destination LXD clean
=> Backing up the database
=> Moving the data
=> Updating the storage backends
=> Starting the destination LXD
=> Waiting for LXD to come online
=> Converting the network configuration
=> Reloading LXD after network update
=> Waiting for LXD to come online

=== Destination server
LXD version: 3.1
LXD PID: 10286
Resources:
  Containers: 1
  Images: 2
  Networks: 1
  Storage pools: 1

The migration is now complete and your containers should be back online.
Do you want to uninstall the old LXD (yes/no) [default=no]? yes

All done. You may need to close your current shell and open a new one to have the "lxc" command work.
To migrate your existing client configuration, move ~/.config/lxc to ~/snap/lxd/current/.config/lxc
~~~

最後はapt版のアンインストールまでやってくれた。

2台のマシンともsnap版に移行したあとは、普通にコンテナのマイグレーションができる。
(ライブマイグレーションはできないので、一旦stopしてからmove、start)

~~~
$ lxc stop CONTAINER
$ lxc move CONTAINER MACHINE2:
$ lxc start MACHINE2:CONTAINER
~~~
RecyclerViewでアニメーションが止まってしまう時に…

# アニメーションが止まってしまう…
RecyclerViewのアイテムでアニメーションを走らせて、画面外に出る→再度画面内に表示、となった場合にアニメーションが止まってしまうことがありました。

# 対策

下記のように、アイテムに対して `setHasTransientState(true)` を呼べばアニメーションが止まってしまうのを防ぐことができました。

```
holder.image.setHasTransientState(true)
```

# 参考
https://stackoverflow.com/questions/41780094/android-animation-stop-works-in-recyclerview-when-view-go-off-the-screen
最速でレポートを作る環境を最速で作る (3ステップ)

markdown でレポートを作る方法を最速で説明します。

####環境
 Mojave 10.14
 Homebrew 1.8.1

####1. インストール　pandoc
 ```sh
$ brew install pandoc
```

####2. 作成　markdown
```sh
$ nvim input.md
```

####3. markdown -> pdf
```sh
pandoc repo.md -o repo.pdf  -V documentclass=ltjarticle --pdf-engine=lualatex
```
--latex-engine ではなく --pdf-engineであることに注意してください

####markdown の書き方
markdown の書き方はこちらをおすすめします -> https://qiita.com/Kumassy/items/5b6ae6b99df08fb434d9
MPIにおけるデッドロックサンプル

# はじめに

よく知られているように、以下のようなコードはデッドロックの可能性がある。

```cpp
  MPI_Status st;
  if (rank == 0) {
    MPI_Send(sendbuf.data(), size, MPI_INT, 1, 0, MPI_COMM_WORLD);
    MPI_Recv(recvbuf.data(), size, MPI_INT, 1, 0, MPI_COMM_WORLD, &st);
  } else {
    MPI_Send(sendbuf.data(), size, MPI_INT, 0, 0, MPI_COMM_WORLD);
    MPI_Recv(recvbuf.data(), size, MPI_INT, 0, 0, MPI_COMM_WORLD, &st);
  }
```

しかし、送るデータサイズが小さい時にはデッドロックしない。
これは、サイズが小さい場合にはEager(イーガー)プロトコルが選択されるため。
Eagerプロトコルは、送信側が受信側の応答を待たずにバッファにデータをコピーし、
データのコピーが完了したら次に進んでしまう。これにより、`MPI_Send`に対する相手からの応答がなくても、
次の`MPI_Recv`が実行され、データの送受信が完了する。
しかし、データサイズが大きい場合にはRendezvous(ランデブー)プロトコルが採用される。
こちらはデータの送受信に際して送信側と受信側のハンドシェイクをするため、上記のコードがデッドロックする。

簡単に図解するとこんな感じ？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79744/a27ab9a1-b98c-cfcc-40f6-1dad45f7ee1a.png)

図は[一週間でなれる！スパコンプログラマ](https://github.com/kaityo256/sevendayshpc)より。

EagerプロトコルからRendezvousが切り替わるデータのサイズはシステムや処理系に依存する。
多くの場合マニュアル等に書いてあったり環境変数で参照できたりするのだろうが、ここでは
実際にデッドロックしたりしなかったりすることと、2つのプロトコルが切り替わるデータサイズを
調べてみる。

サンプルコードは以下に置いておく。

https://github.com/kaityo256/deadlock

# 試し方

必要に応じて`makefile.opt`を作成すること。
もしインテルコンパイラを使いたいなら、例えば以下のようにすれば良い。

```makefile
CC=icpc
CPPFLAGS=-lmpi -lmpi_cxx
```

`make`すると2つの実行バイナリができる。

```sh
$ make
mpic++ test.cpp -o a.out
mpic++ test2.cpp -o b.out
```

`a.out` はデッドロックする可能性のあるコードで、`b.out`はデッドロックしないもの。
引数にデータのサイズを指定する。

```sh
$ mpirun -np 2 ./a.out 1000
I am 1: Recieved 0
I am 0: Recieved 1

$ mpirun -np 2 ./a.out 2000 # デッドロックして処理が返ってこない
```

2つのプロトコルが切り替わるサイズを調べるには、`search.rb`を使う。
「デッドロックしてない場合には1秒以内に終了するだろう」と決め打ちして、

```rb
system("timeout 1 mpirun -np 2 ./a.out #{n} > /dev/null")
```

の結果が成功かどうかでデッドロックしているかどうか判定している。
Macで実行する際は`timeout`を`gtimeout`に修正するか、`timeout`で実行できるように環境設定すること。

手元のMac+OpenMPIで実行するとこんな感じになった。

```sh
$ ruby search.rb
500050 NG
250075 NG
125087 NG
62593 NG
31346 NG
15723 NG
7911 NG
4005 NG
2052 NG
1076 NG
588 OK
832 OK
954 OK
1015 NG
984 OK
999 OK
1007 OK
1011 NG
1009 OK
1010 OK
```

データの切り替えサイズが1010であることがわかる。`int`を送っているので、切り替えサイズは4040バイトになる。

ちなみに、`b.out`では、該当箇所がこうなっている。

```cpp
  MPI_Status st;
  if (rank == 0) {
    MPI_Send(sendbuf.data(), size, MPI_INT, 1, 0, MPI_COMM_WORLD);
    MPI_Recv(recvbuf.data(), size, MPI_INT, 1, 0, MPI_COMM_WORLD, &st);
  } else {
    MPI_Recv(recvbuf.data(), size, MPI_INT, 0, 0, MPI_COMM_WORLD, &st);
    MPI_Send(sendbuf.data(), size, MPI_INT, 0, 0, MPI_COMM_WORLD);
  }
```

片方が「先にSend、後でRecv」なのに対して、もう一方が「先にRecv、次にSend」なので、こちらはRendezvousプロトコルでもデッドロックしない。

## まとめ

MPIでよく出てくるデッドロックの例が、実際にやってみるとデッドロックしなかったりして、初心者は混乱するかもしれない。
ここで、EagerプロトコルとRendezvousの二種類が自動で切り替わっていることを知らないと、とりあえず小さい系では動くのに、大きな系ではデッドロックするような、分かりづらいバグを入れることになる。とりあえずこういうデッドロックを防ぐために、普段から`MPI_Sendrecv`を使うようにしておけば問題ない。著者の経験ではSend/Recvを使うより`Sendrecv`を使うほうが早いことがほとんどだった。
Diffuse色とSpecularの強さからマテリアル名を決める (Python for Blender クックブック)

# Diffuse色とSpecularの強さからマテリアル名を決める

Pythonを使ってBlenderでできる事をまとめています。解説もあります。
[はじめに](https://qiita.com/KTakahiro1729/items/5de5f60982af37d23aa0)
[レシピ一覧](https://qiita.com/KTakahiro1729/items/57f4e1f5495c5e54d431)

Pythonの難易度: ★★☆☆☆

### 動機
気がついたら`Material.004`みたいな名前のマテリアルが増えていて困りますよね？
マテリアルの特徴を元にマテリアル名を改名しましょう。

### 細かい仕様
- Diffuse色は下表の通りです。0~1の間の値は四捨五入してください

|色名|大体のRGB値(0〜1)|
|:--|--:|
|black|(0,0,0)|
|<font color="Red">red</font>|(1,0,0)|
|<font color="Green">green</font>|(0,1,0)|
|<font color="Blue">blue</font>|(0,0,1)|
|<font color="#33CCFF">aqua</font>|(0,1,1)|
|<font color="Purple">purple</font>|(1,0,1)|
|<font color="#777700">yellow</font>|(1,1,0)|
|white|(1,1,1)|

- Specularの強さを四捨五入した結果が0なら`rough`、1なら`smooth`です。
- 「M_black_smooth」のように「M_Diffuse色_Specularの強さ」とマテリアルを改名してください。
- マテリアル名の重複は気にしないでください。

## サンプルコード

```python
color_dict = {
  (0,0,0):"black",
  (1,0,0):"red",
  (0,1,0):"green",
  (0,0,1):"blue",
  (0,1,1):"aqua",
  (1,0,1):"purple",
  (1,1,0):"yellow",
  (1,1,1):"white"}
spclr_dict = {0:"rough", 1:"smooth"}

def describe_color(rgb):
  """rgbを文字列で表現する

  引数
  rgb: (float, float, float)
    文字列で表現したい色のrgb値

  返り値: str
    color_dictのvalueのどれか
  """
  round_rgb = (int(0.5 <= rgb[0]), # 四捨五入
               int(0.5 <= rgb[1]),
               int(0.5 <= rgb[2]))
  return color_dict[round_rgb]

def describe_spclr(spclr):
  """Specularの強さを文字列で表現する

  引数
  spclr: (float, float, float)
    文字列で表現したい色のrgb値

  返り値: str
    spclr_dict
  """
  return spclr_dict[int(0.5 <= spclr)]

import bpy
for mat in bpy.data.materials:
    dif_color = mat.diffuse_color
    spclr = mat.specular_intensity
    new_name = "M_" + describe_color(dif_color) + "_" + describe_spclr(spclr)
    mat.name = new_name
```


上記サンプルコードを、Blender内蔵のテキストエディタに貼り付けた後、<kbd>Alt</kbd>-<kbd>P</kbd>を実行してください。

## 解説

### `bpy.data.materials`
PythonからBlenderを使うにはbpyというライブラリを使います。
例えば、`bpy.ops`には編集のための関数が格納されています。

`bpy.data`にはBlender内の様々な変数（オブジェクトのインスタンス）が格納されています。
オブジェクト一覧は`bpy.data.objects`から、マテリアル一覧は`bpy.data.materials`からアクセスできます。

### `mat.diffuse_color`・`mat.specular_intensity`
`mat.diffuse_color`と`mat.specular_intensity`からはどちらもMaterial共通のプロパティーです。
それぞれ、Diffuse色とSpecularの強さを指します。

「OOのXXという設定のpythonの名前ってなんだろうなぁ」と思った時は、その設定の上でマウスをかざすとわかります。
ec2の作成と同時に任意のOSユーザを作成する

## やりたいこと

ec2を新規作成すると、

- AmazonLinuxの場合 `ec2-user`
- CentOSの場合 `centos`

こんな感じでデフォルトのOSユーザが作成されると思います。

ですが、セキュリティ上、デフォルトのユーザや共通の鍵ペアを使いたくないので、
こちらで任意に決めた管理用ユーザを、ec2作成時に自動作成するようにしたいと思います。



## 手順
ec2を作成する際に、

`インスタンスの作成 > 3.インスタンスの設定 > 高度な詳細 > ユーザーデータ`

と進み、ユーザーデーター項目のラジオボタンを `テキストで` にチェックします。

そして以下の内容をユーザーデータとして入力します。

```yaml
#cloud-config
cloud_final_modules:
- [users-groups,always]
users:
  - name: ${作成したいOSユーザ名}
    groups: [ wheel ]
    sudo: [ "ALL=(ALL) NOPASSWD:ALL" ]
    shell: /bin/bash
    ssh-authorized-keys: 
    - ${設置したい公開鍵1}
    - ${設置したい公開鍵2}
```

あとはいつも通りにec2を作成します。

すると、ここで指定したOSユーザが、デフォルトユーザのかわりに`UID:1000`として作成されます。
デフォルトユーザは作成されません。

## 簡単な解説
今回の内容は`cloud-init`の仕組みを利用しています。

AWSの公式ドキュメント(ユーザーデータやcloud-initについて記載されています)
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html

### groups: [ wheel ]
指定したOSユーザが、サブグループwheel付きで作成されます。

### sudo: [ "ALL=(ALL) NOPASSWD:ALL" ]
wheelグループが、パスワード無しでsudoできるようになります。

### ssh-authorized-keys:
ここに記載した内容が、`/home/${作成したいOSユーザ名}/.ssh/authorized_keys`にそのまま書き込まれます。
そのため、ここに`no-agent-forwarding`のようなオプションを含めて記載することもできます。


## おわりに
この方法を知るまでは、一旦デフォルトユーザでログインして管理ユーザを作成。管理ユーザで入りなおしてデフォルトユーザを削除。
みたいな面倒なことをしていましたが、これでその煩わしさから開放されました。
手順やansibleも、よりシンプルになりました～
mojaveでbundle installできない

#環境
- MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
- macOS Mojave 10.14
- Xcode 10.14
- Ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin18]

#エラー
ターミナルでbundle installを実行
下記のエラーでbundle install失敗

```
An error occurred while installing nokogiri (1.6.6.2), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.6.6.2' --source 'https://rubygems.org/'` succeeds before bundling.
```

#解消方法
下記をターミナルで実行し、xcode10.14を再インストール

```
sudo open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```
無事にbundle installできました。


#参考資料
https://techracho.bpsinc.jp/hachi8833/2018_10_10/62963
教育系ブロックチェーンエンジニアが語るkaggle実践術

### はじめに

この記事は、WebBenchというプログラミング勉強会を実施している筆者が分かりやすくプログラミングの技術を伝達するために作成しました。
過去に何回か、セミナーを都内で実施しております。
団体の説明などはこちら→Web Bench 公式　https://twitter.com/bench_web

また、最近では、こちらのTeam AIの石井さんの本が凄く参考になります。
http://blog.team-ai.com/8steps-for-studying-ai/

### kaggleとは、何ぞや

Kaggleは企業や研究家が、データサイエンス、機械学習関連のお題をだして、それを解くサイトです。https://www.kaggle.com/

賞金がつくものもあり

こちらが公式のホームページとなっています。
https://www.kaggle.com/competitions


### なぜ機械学習が話題となるほどの進歩を遂げているのか

学習進歩の要因 

①計算能力の向上 ②・大量データの取得が容易になったなど


### はじめ方について

環境
ubuntu 16.04
python 3.6
pip 10.0

上記などが推奨されます。

概ね以下のREADMEに書いてあることを試しています。
https://github.com/Kaggle/kaggle-api

まず、上記のコマンドでkaggleを導入します。

```
pip install kaggle
```

### Kaggleチュートリアル（Titanic: Machine Learningfrom Disaster）
・乗客がタイタニックの沈没を生き延びたかどうか
を予測
・訓練用データ（891行 × 12列のcsv） データに一部欠損あり
・テストデータ（418行 × 11列のcsv） データに一部欠損あり
・訓練用データで学習し、テストデータに対して、生き延びたかどうかを予測します

###  データの中でどれを使う？
・PassengerId：データにシーケンシャルでついている番号
・Survived：生存（0 = No, 1 = Yes）　訓練用データにのみ存在
・Pclass：チケットのクラス（1 = 1st, 2 = 2nd, 3 = 3rd）
・Name：名前
・Sex：性別
・Age：年齢
・SibSp：タイタニック号に乗っていた兄弟と配偶者の数
・Parch：タイタニック号に乗っていた両親と子どもの数
・Ticket：チケット番号
・Fare：旅客運賃
・Cabin：船室番号
・Embarked：乗船場（C = Cherbourg, Q = Queenstown, S = Southampton）

```
import numpy as np
import pandas as pd
train = pd.read_csv("train.csv", dtype={"Age": np.float64}, )
test  = pd.read_csv("test.csv", dtype={"Age": np.float64}, )
train.head(10)
```

###使用データを選び、、、、

例、、、
・チケットのクラス
・性別
・年齢
・旅客運賃
・乗船場

###使用する学習手法を選びます

例、、、
・ロジスティック回帰
・サポートベクターマシン
・k-最近傍法
・決定木
・ランダムフォレスト


###kaggleの流れ

基本的には、アカウントを取得したら、ローカルかkernelを使うか選択し、参加したいコンペごとにデータのモデルを手法を用いて作成し、提出してランキングを出すまでが、一連の流れとなります。

###参考文献


一から始める機械学習（Kaggleで学ぶ機械学習）
https://qiita.com/taki_tflare/items/8850ac5ba8b504a171aa

人工知能は人間を超えるか ディープラーニングの先にあるもの 
東京大学　松尾豊(角川EPUB選書)
https://www.ipa.go.jp/files/000048577.pdf

10秒で学べる学習サービス「Aidemy」
https://aidemy.net/
SSHでgit clone したときにエラー

# 前座

開発環境を Ubuntu 16.04 から Windows 10 WSL 上で動作する Ubuntu 18.04 に切り替えたところ、 git clone でエラーをはくようになってしまった。ggってもよくわからないし、結構長時間ハマったので、メモ。

# 環境

前述のとおり、以下が動作環境

```
Ubuntu 18.04 / WSL
```

# エラー内容
以下のようなエラーが出る。

```
$ git clone ssh://git@git.myserver.com:10022/MyGroup/awesome-project.git
Cloning into 'awesome-project '...
git@git.myserver.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

ssh の設定がうまくいってないことはわかる‥

# ssh 設定内容

<code>~/.ssh/config</code> には以下のように設定している。
gitlabを立てており、<code>IdentityFile</code>で設定した鍵で接続する設定だ。
内部でポートフォワードしているため、ポートが一般的でないかもしれないが、その他は極めて普通に設定だ。

```
Host myhost
  HostName git.myserver.com
  IdentityFile ~/.ssh/id_rsa
  User git
  Port 10022
```

# 解決策

以下でいけた。

```
$ git clone myhost:/MyGroup/awesome-project.git
```

違うのはホスト名のところ。<code>config</code>で設定したエイリアスをURLに指定している。

要するに<code>config</code>で設定したHost名で接続しないと設定をみてくれないみたいだ。

今までの環境だと普通にフルパス名で接続できたし、ggってもこのような例はあまり出てこなかった。もしかしたらgitのバージョンの動作差分なのかもしれないが、そこまでは調査できていない。
Count Files By Extension

拡張子別にファイル数をカウントします。

```file_count.rb
#! /usr/bin/env ruby
require 'pathname'

@directories = 0
@files = {}

def file_count(pathname)
  pathname.each_child  do |child|
    if child.directory?
      @directories += 1
      file_count child
    else
      add_file_by_extenstion child
    end
  end
end

def add_file_by_extenstion(pathname)
  if @files[pathname.extname].nil?
    @files[pathname.extname] = 1
  else
    @files[pathname.extname] += 1
  end
end

if ARGV[0]&.start_with? '-'
  puts <<-EOT
usage: file_count {directory}
  EOT

  exit
end

unless ARGV[0].nil?
  file_count Pathname.new(ARGV[0])
else
  file_count Pathname.new('.')
end

puts "#{@directories}\tdirectories"
@files.each do |extension, count|
  if extension == ""
    puts "#{count}\tno extension"
  else
    puts "#{count}\t#{extension}"
  end
end
```

# 実行例

![sample.jpg](https://qiita-image-store.s3.amazonaws.com/0/28376/271b0cac-5f0b-a43a-ed79-245127930b6c.jpeg)
デスクトップ通知調査(with RoR)

# デスクトップ通知

https://www.lanches.co.jp/blog/6723
https://qiita.com/otolab/items/72ac10a0880ea411d77e
https://tech.speee.jp/entry/2017/12/21/111404
https://tech.mercari.com/entry/2017/12/19/workbox

## 大まかな流れ

![uml.png](https://qiita-image-store.s3.amazonaws.com/0/207007/5cf17c44-52da-b0c9-b1fe-c4ec3df3e32e.png)

## ライブラリ

### Gem

#### webpush

https://rubygems.org/gems/webpush

* `Ruby` のアプリケーションに `Web Push` の機能を追加する。
    * `VAPID Key` の生成。
    * 鍵を使ったサーバー・クライアント間の安全な通信。
    * 通知の発行。

#### serviceworker-rails

https://rubygems.org/gems/serviceworker-rails

* `Rails` を `PWA` 対応する。
* `Assets` 等は起動時にコンパイルされてファイル名が動的に決定されるので、素の `Service Worker` では対応できないなど。

### Npm

#### Workbox

https://developers.google.com/web/tools/workbox/

* `Google` 製の `PWA` 構築のためのライブラリ。
* `PWA` に関する諸々を簡単に実装できる。
* 標準的な事以外をやらせようとすると上手くいかない。

## キーワード

### VAPID (Voluntary Application Server Identification)

https://qiita.com/tomoyukilabs/items/9346eb44b5a48b294762
https://tools.ietf.org/html/rfc8292


> *Abstract*
> 
>    An application server can use the Voluntary Application Server
>    Identification (VAPID) method described in this document to
>    voluntarily identify itself to a push service.  The "vapid"
>    authentication scheme allows a client to include its identity in a
>    signed token with requests that it makes.  The signature can be used
>    by the push service to attribute requests that are made by the same
>    application server to a single entity.  The identification
>    information can allow the operator of a push service to contact the
>    operator of the application server.  The signature can be used to
>    restrict the use of a push message subscription to a single
>    application server.



## 謎

* `manifest.json` が必要とか必要ないとか、情報源によって差がある。
    * スマホのホームにアプリとして追加するときに必要な設定
* ページロード時に購読を確認するか、ボタン等で購読するか選ばせる。
    * ボタン等で購読するか選ばせる方がトレンドっぽい。
        * 訪問者に負担にならないように
        * https://mizchi.hatenablog.com/entry/2017/12/05/223520
ブランチと同じ名前のファイルがあるときに git checkout の挙動を制御する

Git のワーキングブランチを`<name>`という名前のブランチに切り変えるとき
ふつう `git checkout <name>` するかと思いますが、
もしワーキングディレクトリの `<name>` と同じ名前の unstaged なファイルがある状況では
`git checkout <name>` は abort されてしまいます。

なぜかというとブランチにチェックアウトしたいのかファイルの変更を破棄したいのか分からないからです。

この状況では次のように書くことで望む操作を行うことができます。

### ブランチ `<name>` にチェックアウトしたい

```console
$ git checkout <name> --
```

### ファイル `<name>` の unstage な変更を破棄したい

```console
$ git checkout -- <name>
```

## 参考

https://git-scm.com/docs/git-checkout#_argument_disambiguation

## 2019/11/21 追記

`git switch` と `git restore` が使えるようになったのでそれを使いましょう。
vba【無限ループの止め方】

### Alt + Esc

Windows7以降有効。

本来はウィンドウを切り替えるショートカットだが、DoループなどでCtrl + Breakが効かないとき、しばらくAlt + Escを押しっぱなしにしてウィンドウを切り替え続けているとVBEのウィンドウになったタイミングで止まる。

### Ctrl + Break

キーボードの入力を受け付ける処理（DoEvents）を入れていれば有効。
MsgBoxを無限表示してしまった際などにもメッセージボックスをフォーカスしてこれを押すと止まる。
暇なのでnoteをbookにしてみた

## はじめに
こんにちは。
みなさん、[note](https://note.mu/)は使っていますか？
情報発信やコンテンツの販売場所として今や大人気のnoteですが、
記事によっては縦読みの方がいいなと思い、適当なスクリプトを書きました。
タイトルは大げさなので、お手柔らかに、、🙏笑
## TL;DR
1. noteで適当な記事を開く
2. 下記のスクリプトを実行する
3. noteがbookに！！（個人差あり）

```
var b_props = {
  writingMode:'vertical-rl',
  width:'1000px',
  overflowY:'scroll',
  margin:'0 -200px',
  textOrientation:'upright'
}
$('.ns-note .note-body p').css('height', '680px');
$('.ns-note .note-body img').css({'cssText': 'height: 100%!important;'});
$('.body-wrapper').css(b_props);
```
## 対象
- noteを縦読みしたい方

以上
## 感想
CSSってすげえ〜〜
PowerShellからデータを出力するパターンまとめ

PowerShell上に表示させた情報を別の形式やファイルに出力する方法をまとめます。

## 環境

* PowerShell Version：5.1.17134.228

## テキストファイル(.txt)に出力

### Start-Transcript

コマンドの入出力を全てテキストファイルに記録するコマンドです。
入力したコマンドがそのまま記録されるので、作業のログに適してます。

#### 記録の開始

```PowerShell
Start-Transcript
```

既定の保存先`C:\User\%UserName%\Documents`に記録される。

#### 保存先を指定して記録を開始

```PowerShell
Start-Transcript C:\Temp\Transcript.txt
```

ファイルを絶対パスで指定する。

#### 既存のテキストファイルに追記して記録を開始

```PowerShell
Start-Transcript C:\Temp\Transcript.txt -Append
```

指定したテキストファイルの一番下に追加して記録を開始する。  
(-Appendを指定しない場合、同じ名前のファイルがあると上書きして記録を開始してしまう）

#### 記録の終了

```PowerShell
Stop-Transcript
```

### Out-File

1つのコマンドや変数をテキストファイルに出力するコマンドです。

#### 実行例

```PowerShell
Get-Mailbox -Identity User01 |Out-File C:\temp\User01.txt
```

#### リダイレクト演算子で実行

```PowerShell
Get-Mailbox -Identity User01 > C:\temp\User01.txt
```

`Out-File`は`>`でも代替できる。  

あっ、この出力、テキストで欲しいな、なんてときは、
`↑`キーで直前のコマンドを呼びだして、これを書き足してあげましょう。

## CSVファイル(.csv)に出力

### Export-Csv

コマンドの結果をCSVファイルで出力します。  
メールの配信ログなど情報量が多いときによく使います。  
Excelで再編集もしやすいです。

#### 実行例

```PowerShell
Get-Mailbox -Identity User01 | Export-Csv -Path C:\temp\User01.csv -Encoding UTF8 -NoTypeInformation
```

`-Encoding`パラメーターで文字化けを防ぎ、  
 `-NoTypeInformation`パラメーターで先頭行に型の情報を入れないようにします。

#### 実行例(応用)

```PowerShell
$Output = Get-Mailbox -Identity User01
$Output += Get-Mailbox -Identity User02
$Output | Export-Csv -Path C:\temp\User.csv -Encoding UTF8 -NoTypeInformation
```

変数からパイプ処理が可能なので、
こうして、まとめて１つのファイルに出力することができます。便利。

## XMLファイル(.xml)に出力

### Export-CliXml

コマンドの結果をXMLファイルに出力します。  
ひとつのオブジェクトの情報を出力するときによく使います。

#### 実行例

```PowerShell
Get-Mailbox -Identity User01 | Export-CliXml -Path C:\temp\User01.xml
```

#### 実行例(応用)

あとからファイルをPowerShellにインポートして、オブジェクトとして扱うことができます。  

まず、変数にインポートします。

```PowerShell
$File = Import-CliXml -Path C:\temp\User01.xml
```

この$Fileを以下のようにPowerShellのコマンドで操作できます。

```PowerShell
$File | fl
```

```PowerShell
$File | ?{$_.Alias -eq "User01"}
```

```PowerShell
$File | Set-Mailbox -UseDatabaseQuotaDefaults $False
```

設定変更する前の状態をXmlファイルに出力しておけば、
変更前の値を簡単に参照したり、そこから簡単に戻したりできます。

## クリップボードにコピー

### | Clip

ファイルではなく、コマンドの出力をクリップボードにコピーします。

### 実行例

```PowerShell
Get-Mailbox -Identity User01 | Clip
```

入力したコマンドの出力がそのままコピーされます。  
以下のように出力を整形するとキレイです。

```PowerShell
Get-Mailbox -Identity User01 | fl | Clip
```

```PowerShell
Get-Mailbox -Identity User01 | fl Alias,SamAccountName -AutoSize | Clip
```

## 参考

自身の[過去記事](http://tkd-o365.hatenablog.com/entry/2016/06/17/162006)を加筆修正しました。
マンガで分かるDocker①を実際にやってみました

# 前置き
「マンガで分かるDocker①」を実践したいと思います。
（ぼちぼち技術書典で手に入れた本たちを実践紹介していけたらいいなと思っています。）
では、始めます！

## マンガで分かるDockerとは？

こちらの技術書は、知っている方も多いと思います。有名な「わかばちゃんシリーズ」の方の技術書です。
研修中にわかばちゃんシリーズを知り、gitやsourcetreeの使い方など、大変お世話になりました。


## Dockerとは？
「コンテナ型の仮想環境を作ったり、配布したり、実行してくれるもの」
というざっくりとした理解をしました。
マンガでは「パソコン上でファミコンが動くみたいなもの」と説明があったのですが、
ファミコンしたことないのでちょっとイメージが付かなかった・・・。
コンテナ型の仮想環境なんだな、ということですね。

### Dockerを使うことのメリット

- 自分の環境が汚れない
- いつでも同じ環境を立ち上げられる

開発に合わせてバージョンを揃えたり環境整えたりするの、すっごい大変だなと感じていたので、すごく便利だなと感じました。
また、Aさんの環境なら動くけど、私の環境だとなんか違う…みたいなことも起きないので便利だなと感じました。

同じ環境で開発してほしいから、このコンテナインストールしておいてーってことができるのかな、というイメージでした。

## いざ実践
### インストール
こちらのサイトからインストールをしてきました。
ちゃんとインストールができたのか確かめるために、

```
$ docker version
```
を叩くと、Client情報やServer情報のようなものが。インストールは成功したようです！

### イメージをDocker Hubからpull
マンガではhello-worldというイメージを例に挙げていたので同じように

```
$ docker run hello-world
```
を叩きました。これでpullできるはず・・・！！

と思いきや、何かエラー！なんで！

```

Unable to find image ‘hello-world:latest’ locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: unauthorized: incorrect username or password.
See ‘docker run --help’.
```
まず1行目のエラー。これはローカルにhello-worldっていう名前のイメージが見つからなかったよという意味。それはその通りなのでここはスルーです。
2行目以降のメッセージを検索したところ、どうやらDockerにログインしないといけないようです。

```
$ docker login
```
このコマンドを叩いてログインをします。
この時に聞かれるUsernameはメールではなくIDです。
なんとなくこれかな？と思われるIDとパスワードを入力したところ成功しました。
登録していたのかもしれませんし、もしかしたらここで適当につけてログインができるのかもしれません。ここはまた調べたいと思います。

再度runを実行したらpullに成功しました！！

### $ docker run のしてくれたこと


1. イメージの取得
2. コンテナ生成
3. コンテナ起動

つまり

```
$ docker pull
$ docker create
$ docker start
```

を一気に行ってくれたのです。
今回は勉強もかねて一つ一つ実行してみました。
マンガの例にあったalpine(アルパイン)をpullします。

``` 
$ docker pull alpine
$ docker create -it alpine
$ docker start 539
```

createコマンドについている　-it オプションは、ターミナルでコンテナを実行できるようにしてくれるものらしいです。

start の後についている539という数字は、createしたときに割り振られたコンテナIDの頭3桁です。
コンテナIDすべてを入力せずとも、このように最初の文字を入力するだけで大丈夫なようです。



### コンテナの中に入ろう
ここで少し問題です
① $ docker exec -it alpine bin/ash
② $ docker exec -it 539 bin/bash
③ $ docker exec -it 539 bin/ash


コンテナに入るためにはどのコマンドを入力したらよろしいでしょうか？？？

(	 ˊ̱˂˃ˋ̱ ) ・・・
(	 ˊ̱˂˃ˋ̱ ) ・・・
(	 ˊ̱˂˃ˋ̱ ) ・・・
(	 ˊ̱˂˃ˋ̱ ) ・・・答えは3です！

今回pullしてきたalpineはlinuxの軽量版らしいのですが、bashではなく、ashらしいです。
最初知らなくて、誤字では？なんて思ったりしてしまいました。

コンテナに入るためには、コンテナIDが必要なのですね。

**ただし！！**

```
$docker run -it alpine bin/sh 
```

でも動きます。


### ほかによく使うコマンド・ショートカット

```
$ docker images
```
今までにpullしてきたイメージ一覧を見れます。

```
$ docker ps
```
起動しているコンテナを確認できます。
-a オプションをつければ停止中のコンテナも表示してくれます。

```
$ docker rm 【コンテナID】
```
コンテナを削除するコマンドです。


```
$ docker stop 【コンテナID】
```
コンテナを停止するコマンドです。

コンテナから抜けるには、「 ctrl + P + Q 」です。

## 最後に
以上が私がマンガで分かるDocker①で学んだことです。
次回は②を実践したいと思います。

これからも頑張ります！
OracleText 結合したテーブルに対し全文検索を行う方法

#概要
結合したテーブルに対しOracleTextの全文検索を行うためには、ストアドプロシージャを作成しIndexに設定する必要があります。
Oracleの公式サイトにも情報がありますが、より分かりやすくまとめてみました。
[公式サイト Oracle12c](https://docs.oracle.com/cd/E82638_01/ccref/index.html)
[Oracle Textの使い方](https://blogs.oracle.com/oracle4engineer/oracle-text-v5)

以下のようなテーブルに対し、AとBのNameを全文検索し、AのIDを取得する方法です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148666/7edce2f4-2772-e133-1418-97e832531b12.png)
※NameはNot Nullとする。

#ストアドプロシージャについて
CROB型のデータに全文検索したい文字列を連結し、AテーブルのROWIDを紐づけます。

###A
|A_Id|Name|
|---|---|
|A0|人事部|
|A1|総務部|

Dummyはデータ更新時に、Indexへ反映するための項目です。
A,BテーブルのUpdate時にDummyを更新してください。Dummyは日付等でよいです。

###B
|B_Id|A_Id|Name|
|---|---|---|
|B0|A0|採用グループ|
|B1|A1|環境グループ|
|B2|A1|庶務グループ|

###ストアドのデータイメージ
|ROWID|CROB|
|---|---|
|1|人事部採用グループ|
|2|総務部環境グループ 総務部庶務グループ|

###SQL
```sql:create_procedure.sql
CREATE OR REPLACE PROCEDURE ORACLE_TEXT_CREATOR (p_rowid IN ROWID, p_clob IN OUT NOCOPY CLOB)
IS BEGIN FOR r IN (
  SELECT A.Name As A_NAME, B.Name As B_NAME
  FROM   A INNER JOIN B ON A.A_Id = B.A_Id
  WHERE  A.ROWID = p_rowid
)
 LOOP
  DBMS_LOB.writeappend (p_clob, LENGTH (r.A_NAME), r.A_NAME);
  DBMS_LOB.writeappend (p_clob, LENGTH (r.B_NAME), r.B_NAME);
  DBMS_LOB.writeappend (p_clob, 1, ' '); 
 END LOOP;
END;
```

作成したプロシージャーにctxsysの権限を付与します。

```sql:grant_procedure.sql
GRANT EXECUTE ON ORACLE_TEXT_CREATOR TO ctxsys;
```

#ctx_ddlについて
LEXERを指定し、DATASTOREに先ほど作成したストアドプロシージャーを設定します。

```sql:create_ctxddl.sql
BEGIN
ctx_ddl.create_preference('LEXER',     'JAPANESE_LEXER');
ctx_ddl.create_preference('DATASTORE', 'user_datastore');
ctx_ddl.set_attribute    ('DATASTORE', 'procedure', 'ORACLE_TEXT_CREATOR');
ctx_ddl.set_attribute    ('DATASTORE', 'output_type', 'CLOB');
END;
```

#Indexについて
先ほど作成したLEXERとDATASTOREを指定し、Indexを作成します。
Commit時に同期する形です。

```sql:create_index.sql
create index ORACLE_TEXT on A ( DUMMY ) 
indextype is ctxsys.context
  PARAMETERS ('
    datastore      DATASTORE
    lexer          LEXER
    sync (on commit)
  ');
exit;
```

#検索について
以下の検索でA1が取得できます。

```sql:select.sql
select A_Id from A 
where CONTAINS(DUMMY, '環境') > 0;
```
Pythonで作るじゃんけんゲーム


```janken.py
import random
import time

win = 0
lose = 0
draw = 0

while win < 3:
    time.sleep(2)
    print('\n最初はグー・・・')
    time.sleep(1)
    print('じゃんけん・・\n')
    time.sleep(1)
    you = int(input('1:グー\n2:チョキ\n3:パー\n'))
    com = random.randint(1,3)
    
    time.sleep(1)
    print('\nあなた：'+str(you)+'\nコンピュータ：'+str(com))
    
    r = (com-you+3)%3
    
    time.sleep(1)
    if r == 0:
        print('\ndraw')
        draw += 1
        
    elif r == 2:
        print('\nlose..')
        lose += 1
    else:
        print('\nwin!')
        win += 1
print('\n'+str(win)+'勝'+str(lose)+'敗'+str(draw)+'引き分け')

```
PhotonUnityNetwork（PUN）のRPC通信を知る

# PhotonUnityNetwork（PUN）のRPC通信を知る

最近Photonを使うようになったのですが、良く使われる通信方式「RPC通信」ってどういう通信なのか、よくわかってなかったので調べてみました。

## RPC?

**Remote Procedure Call** （直訳で遠隔手順呼び出し）の略。
要は、Photonの通信イベントから指定関数を呼び出すことができるとのこと。
でもそれってイベントを通信するのとどう違うのか、考えてみました。

## RPCの特性

PUNでのRPC通信は、必ず`PhotonView`を介して行う必要があります。
つまり、シーン内に`PhotonView`がアタッチされたゲームオブジェクトがなければ、RPC通信はできません。
そして、RPC通信で呼び出す関数は、呼び出すPhotonViewと同じゲームオブジェクトにアタッチされた`[PunRPC]`属性が付いた関数になります。

```
photonView.RPC("Hoge", RpcTarget.All);
```

```
[PunRPC]
public void Hoge() {
   //Fuga
}
```
このように、呼び出したい関数名をstring型で指定します。
なお、string型で指定する関係上、同じ名前の関数を別クラスでそれぞれ`[PunRPC]`属性を付けて指定することは可能ですが、実行時にエラーが出ます。


## RPC通信に向いているイベント

ユーザーごとに別の値になり、その値を他のユーザーに通知する必要があるものなどはRPC通信に向いていると思います。
たとえば、対戦ゲームでユーザーごとのHPに変動があるとき、RPC通信でDamage(int damage)関数を呼んでHPの変動を共有したりできます。
でも公式ドキュメントを見ると、RPC通信は即座に共有するわけではないので、ほどほどの頻度の通信に使うように、とのことです。ターン制バトルとかには向いてそうですね。


## RPCを使わないイベント

「ゲーム開始」など、全体に関係するイベントは、RPC通信である必要がないと思います（RPCで通信しても別にいいです）
ルーム内全員が同じ反応をする場合は、別に必要なさそうですね。
また、ユーザーの現在位置など、とても頻繁に変更がある通信は`Object Synchronization`という別の通信が推奨されるようです。


## 余談：PUN2を使ってみた

今まで、PUN無印を使ってたのですが、せっかくなので今回PUN2を入れてみました。
予想外に普通にルームに入れるようになるまでに苦労しました。

### PUN無印と違ったので注意する点

- AutoLobbyLoginが無くなりましたが、OnJoinedLobbyが呼ばれなくてもルームを生成・参加できるようです
  - OnJoinedLobbyの代わりに、OnConnectedToMasterが呼ばれた時点でロビーに入ったのと同じ処理ができます
- 各種イベント通知を受け取るには、対応したインターフェースを継承している必要があります
  - ついでに、コールバックターゲットに前もって指定しておく必要もあります
  - 全部の必要関数を書くのがとても面倒なので、`MonoBehaviourPunCallbacks`を継承すると一発で必要関数をすべて定義したことになります。あとは適宜必要部分だけoverrideでOK


## 参考
公式ドキュメント：https://doc.photonengine.com/ja-jp/pun/v1/gameplay/synchronization-and-state
「プログラマが知るべき97のこと」をクローリングしてPDFを作る


# はじめに
「[プログラマが知るべき97のこと](https://www.oreilly.co.jp/books/9784873114798/)」というエッセイ集がWeb上で公開されていたのでクローリングしてPDF化してみました。

# プロジェクトの作成
今回はクローリングスクリプトではScrapyを使用し、PDF化スクリプトではreportlabを使用します。

```console
$ mkdir ninety_seven_things
$ cd ninety_seven_things
$ pipenv install scrapy reportlab
```

# クローリングスクリプト
```python:crawler.py
from scrapy import Spider, Request
from functools import reduce
from operator import add

class NinetySevenThingsSpider(Spider):
    name = 'ninety_seven_things_spider'

    # クローリングを開始するURL
    start_urls = ['https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/']

    custom_settings = {
        "DOWNLOAD_DELAY": 3, # ページ遷移間隔(秒)
        "FEED_EXPORT_ENCODING": 'utf-8', # エンコード指定
    }

    def parse(self, response):
        url_obj = response.xpath('/html/body/div/div/div/div/ol//li//a/@href')
        full_urls = map(lambda href: response.urljoin(href.extract()), url_obj)
        for full_url in full_urls:
            yield Request(full_url, callback=self.output)
            
    def output(self, response):
        title = response.xpath('/html/body/div/div/article/h1/text()').extract_first()
        author = response.xpath('/html/body/div/div/article/span/a/text()').extract_first()
        body = reduce(add, map(lambda x: x.extract() + '\n', response.css('p::text')[:-3]))
        yield {
            'title': title,
            'author': author,
            'body': body.replace('。', '。\n')
        }
```

# クローリング
```console
$ pipenv run scrapy runspider crawler.py -o output.json
```

# PDF作成スクリプト
```python:pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
import json
from functools import reduce

FILENAME = 'プログラマが知るべき97のこと.pdf'
pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))
styles=getSampleStyleSheet()
styles["Normal"].fontName = 'HeiseiKakuGo-W5'

doc = SimpleDocTemplate(FILENAME,pagisize=A4)

with open('output.json', 'r') as f:
    texts = json.loads(f.read())
    story = reduce(lambda x, y: x + y, map(lambda text: [
        Paragraph('<font size=18>' + text['title'] + '</font>', styles["Normal"]),
        Spacer(1, 18),
        Paragraph('<font size=12> 著者: ' + text['author'] + '</font>', styles["Normal"]),
        Spacer(1, 12),
        Paragraph('<font size=10>' + text['body'] + '</font>', styles["Normal"]),
        PageBreak()
    ], texts))

    doc.build(story)
```

# PDF作成
```console
$ pipenv run python pdf.py
```

おわり

# 出典
[プログラマが知るべき97のこと](https://プログラマが知るべき97のこと.com/)
[CC-by-3.0-US](https://creativecommons.org/licenses/by/3.0/us/deed.ja)でライセンスされているようです。
django-adminでstartprojectできない時の解決法

Djangoでプロジェクトを作成する際に、以下のようなエラーが出ることがあります

```shell
$ django-admin startproject idd-corporate-site
Failed to execute process '/usr/local/bin/django-admin'. Reason:
The file '/usr/local/bin/django-admin' specified the interpreter '/usr/local/opt/python/bin/python2.7', which is not an executable command.
```

Pythonのバージョンに問題がありそうですね。そういうときは、

```shell
$ python3 -m django startproject projectname
```
としてあげればOKです。

それか、先にPython3の仮想環境を作った上でpipでDjangoをインストールしてからdjango-adminを叩くのもあり。てかそれが正当な気がする。
PHP初学者備忘録②

- htmlspecialcharsはユーザが入力を間違えた際のプログラム誤作動や、セキュリティ対策のために使う。
タグなどをそのまま表示させたい時に使う。

- ENT_QUOTESはダブルクォート、シングルクォートを意味のなさないものにする。
上記と同じで、プログラムの誤作動防止、セキュリティ対策に使う。
基本的には、ブラウザ上で表示させたい場合には使うくらいの気持ちでいたほうがいい。
※ユーザに記入してもらう送信フォームなどを作る時には必ず使うこと！
print htmlspecialchars($str, ENT_QUOTES);

- XSSクロスサイトスクリプティング（フィッシングサイト）AのサイトにBのサイトを表示させる

- 浮動小数点は小数点がつく数字のこと。
なぜ、浮動なのか（float）0.123の場合、123という数字と、どこに小数点を持ってくるかという処理が別々になされている。
なので、小数点が左についたり右についたり動く→浮動小数点
[入門]Go言語でファイル読み書きをやってみよう

# はじめに
* 当記事は、Go言語のファイル読み込み、書き出しの方法を記載しております。

## 注意点
* 読者の知識レベルは、以下の方を想定しております。
    * プログラミングの基礎的な知識がある
        * 変数とは何か、関数とは何か
        * 変数や関数を定義できるか
    * 何か言語を触ったことがある
        * C言語やJava言語、Python言語など

* 上手く実施できなかった場合や、不明な点がある際は、コメントを記載していただければ幸いです。


## 実行環境
* OS
    * Windows10 Pro 64-bit
* エディタ
    * VisualStudio Code
* 作業ディレクトリ
    * C:\Users\Romeo\Documents\go

# ファイル読み込み
## 事前準備
* 今回は、テキストファイルの読み込みを実施するので、先にファイルを用意しておきましょう。
* "C:\Users\Romeo\Documents\go"配下に、test.txtを作成します。
* 内容は何でも良いですが、私は以下のように作成しました。

```txt:test.txt
Hi.
This is a test file.
```

## ソースコード
* FileRead.goを新規作成し、以下の内容を格納します。

```go:FileRead.go
package main

import (
	"fmt"
	"log"
	"os"
)

const BUFSIZE = 1024	//読み込む際のバッファサイズ指定

func main() {
	file, err := os.Open(`C:\Users\Romeo\Documents\test.txt`)	//ファイルオープン
	if err != nil {
		log.Fatal(err)	//ファイルが開けなかったときエラー出力
	}
	defer file.Close()	//全部の処理終了後にファイルクローズ

	buf := make([]byte, BUFSIZE)	//byte型配列に格納
	for {	//繰り返し読み込み
		n, err := file.Read(buf)	//ファイル読み込み
		if n == 0 {
			break	//中身がなくなったらbreak
		}
		if err != nil {
			log.Fatal(err)
			break	//ファイル読み込みに失敗したらbreak
		}

		fmt.Printf(string(buf[:n]))	//読み込んだ内容を出力
	}
}
```

## 実行結果

```cmd:
C:\Users\Romeo\Documents\go> go run FileRead.go
Hi.
This is a test file.
```

## ソースコード解説
* 基本的には、よくあるファイル読み込みアルゴリズムと同じだと思います。
* 今回インポートしたパッケージは3つです。
    * fmt
        * 標準出力のため
    * log
        * エラー出力のため
    * os
        * ファイルを取り扱うため

* ファイルオープン時には、エラー変数が返ってきます。しっかり受け取り、エラー処理まで記載しましょう。
    * deferにファイルクローズ関数を記載することを忘れずに

```go:一部抜粋
file, err := os.Open(`C:\Users\Romeo\Documents\test.txt`)	//ファイルオープン
	if err != nil {
		log.Fatal(err)	//ファイルが開けなかったときエラー出力
	}
defer file.Close()	//ファイルクローズ
```



# ファイル書き込み
## ソースコード
* FileWrite.goを新規作成し、以下の内容を格納します。
* 今回のプログラムでは、test2.txtを新規作成し、そこに"testmessage"を書き込みます。

```go:FileWrite.go
package main

import (
	"os"
)

func main() {
	file, err := os.Create(`C:\Users\Romeo\Documents\test2.txt`)
	if err != nil {
		log.Fatal(err)	//ファイルが開けなかったときエラー出力
	}
	defer file.Close()

	output := "testmessage"
	file.Write(([]byte)(output))
}
```

## 実行結果

```txt:test2.txt
testmessage
```

## ソースコード解説
* こちらも、よくあるアルゴリズムだと思います。
* outputという変数に、書き込みたい内容を記載しております。



# 最後に
* 変数定義やエラー出力など、慣れない点も多々ありました。
* ファイル読み書きは初歩中の初歩なので、これをベースに更に勉学に励みます。
実際のアジャイル開発、スクラム開発における問題点、疑問点

アジャイル開発、スクラム開発における問題点、疑問点を話す会に参加したので、知見の共有。

# 前提条件
アジャイル開発、スクラム開発の体制を前提としています。
[スクラムをざっくり説明するときのスライド](https://qiita.com/halhorn/items/5cf7d28034ad9132d311)が特に参考になりました。

- PO プロジェクト価値を最大化することが使命
- PM/SM チームが上手く回ることが使命
- developer(dev) 機能を実装することが使命
- ストーリー/プロダクトバックログアイテム(PBI) 「〇〇は〇〇したい、なぜなら〇〇だから」

# ケース1: 「価値」と「画面イメージ」と「ロジック」について
POは価値を最大化するためにストーリーを作るが、そこは価値のみが書かれてるケースが多く、dev側では完成画面イメージが提供されていないため、どう作成すればいいのか悩むケース
### 問題点
POが「価値」を描く
devは「価値」と「画面イメージ」と「ロジック」を書く
**画面イメージは誰が？？**
POは「なんでもいいよ/うまくやってよ」
devは「やる前にワイヤー欲しいなぁ」

### 解決策
このようなケースではデザイナーが居ないことが多く、画面デザインにはこだわってないことが多い
もちろん、POが納得するワイヤーをスプリントバックログを作成する、ブレイクダウンのタイミングでササッと書き、okをもらうのが良い
webの場合、最低限を担保するbootstrapを使うというのを事前に伝えておくのが良い

# ケース2: 本当のPOについて
POを任された人が居るが、実はもっと強い鶴の一声を持っている人がいるケース
### 問題点
差し戻しが多くなったりする事が予期される
鶴の一声さんは忙しくてスプリントプランニング/レビューには出てこない
**決定権/仕様の決定は誰が？？**

### 解決策
現状のPOがメッセンジャー的な役割ならば、**POは鶴の一声さんの意図を汲み取った上でストーリーを作成すること**をdev側から求める。できてないと感じるならば、POの差し替えを要求する

# ケース3: デザイナーが入ってる場合(リリース前)
デザイナーが画面イメージを作るが、ストーリーはどう作るのがいいのか
### 最良案
リリース前なら、画面モック(ワイヤー)を作成してもらい、POがストーリーを作成する
### デザイナーより開発者が早い場合
バランスが悪いので、タイミングをずらすか、スポットでデザインを手伝ってあげる
デザイナーより早く作らない方が良い

# ケース3: デザイナーが入ってる場合(リリース後)
リリース後の追加機能に関してのストーリーはどう作るのがいいのか
### 現実
画面のストーリーと、ロジックのストーリーを分けてあげるのが良い

# ケース4: 開発メンバーの実力/理解度の差に関して
スプリントプランニングのタイミングで、対象ストーリーに対しての開発メンバーの実力/理解度の差があるケース
### 問題点
プランニングの時間が伸びる
**時間、もったいない？？**

### 解決策
**時間、もったいなくない。**
スプリントプランニングのタイミングでキャッチアップが足りないならば、PM/SMがギャップを埋める時間を個別に作成してあげる。
 - 前提知識をインプットするミーティング
 - ペアプロ
 - モブプロ
が役に立つ。
むしろプランニングの段階で理解度にギャップがあることがわかることは良いこと。

# 参考

- アジャイルとスクラムを継承した、新しい開発、モジャイル開発を発明した会社、[株式会社mofmof](https://www.mof-mof.co.jp/)のミーティング
- [スクラムをざっくり説明するときのスライド](https://qiita.com/halhorn/items/5cf7d28034ad9132d311)

# あとがき
アジャイル開発初心者なので、間違ったこと/間違った前提/偏った前提を元に記事を作成している可能性があります、ご容赦ください。