OmniAICreator/Qiita-1.07M huggingface dataset:
preztoでzsh構築した時のメモ

タイトルの通り。
突如、homebrewのANSIカラーコードの無変換が気になって、
構築やり直さなくちゃ行けなくなった時だったので、今後同トラブルのためのメモ
せっかくなので、oh-my-zshからPreztoへの切り替えもして見ようと思ったゾ

* 参考記事<br>
https://dev.classmethod.jp/tool/zsh-prezto/<br>
https://qiita.com/bake0937/items/79e350a474c1cd60a5e0


# 1.zshの入れ直し
念の為にやっておく

```
# zshからbashに切り替えておく
chsh -s /bin/bash 
```
ターミナル再起動して。。。。

```
# zshrc関係の設定ファイルをひとまず全てバックアップ
mkdir ~/BACKUP
cp ~/.zshrc* ~/BACKUP

# 削除する
rm ~/.zshrc
```
```
# アンインストール （"$ brew uninstall zsh"だと完全に消せないって言われたので）
brew uninstall zsh --force

# 再インストール
brew install zsh

# homebrewで入れたzshに切り替える
chsh -s /usr/local/bin/zsh
```


# 2.vimの設定
気づいたらvim設定も初期化されてしまったので、再設定が必要な場合に行う。

とりあえず、hybridテーマがローカルになければcloneする。
https://github.com/w0ng/vim-hybrid

```
git clone https://github.com/w0ng/vim-hybrid

cp vim-hybrid/colors/hybrid.vim ~/.vim/colors/
```
`.vimrc`を以下の通り設定して保存

```vim:~/.vimrc
let g:hybrid_use_iTerm_colors = 1
colorscheme hybrid
syntax on

set number
set cursorline
set ruler
```


# 3.preztoをインストール
今回はzshフレームワークで[oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh)より動作が軽いという[prezto](https://github.com/sorin-ionescu/prezto)を使う。どちらも`agnoster`テーマが使える。

```
# ローカルにclone
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
```
普通に`$ touch .zshrc`ではなく、専用の設定場所にリンクするようにして設定する必要があるらしいので、以下を実行。

```vim
# これで設定ファイルを作ってくれるらしい
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```
ターミナル再起動して。。。。プロンプトがprezto初期仕様に変わるが。。。。
`$ prompt -s <theme name>`でやってもいまいち形にならなかった（要検証）ので、直接設定ファイルに変更を促す。

```vim:~/.zpreztorc
# 117行目のthemeを、sorinからagnosterにする
zstyle ':prezto:module:prompt' theme 'agnoster'
```
更新しとく

```
source ~/.zpreztorc
```
## 文字化け対処
`agnoster`テーマは[powerline Fonts](https://github.com/powerline/fonts)が必須なので、なければcloneする

```
# cloneする
git clone https://github.com/powerline/fonts.git --depth=1

# インストール
cd fonts
./install.sh

# 必要なければcloneファイルを削除
cd ..
rm -rf fonts
```
インストールした後、iTerm2の設定をする

* `Preferences...`>`Profile`>`Text`>`Change Font`で設定ウィンドウを開く。<br>右上の検索バーで`Powerline`と検索して好みのフォントを決定して閉じる。<br>この時は`12pt Noto Mono for Powerline`を選んだ。
* `Preferences...`>`Profile`>`Terminal`>`Terminal Emulation`の<br>`Report terminal type`を`xterm-256color`に設定する。(必須か不明。要検証)

# 4.`.zshrc`を再設定
バックアップで取った`.zshrc`を戻す

```
# 上書き
cat ~/BACKUP/.zshrc > ~/.zshrc

# チェック
diff ~/BACKUP/.zshrc ~/.zshrc
```
# 5.構築終了だゾ
疲れた。。。
あとは適当にiTerm2のcolorを好みに合わせて変えるべし
Djangoでfactory_boyを使って、データが保存されない時に読んでほしい

## この記事で書いていること
- factory_boyのclassを定義する時に`factory.Factory`を継承してると、データが保存されない
- 代わりに`factory.django.DjangoModelFactory`を継承しよう
- 公式DOCSで最初に出てくる例が`factory.Factory`を継承していてその先をちゃんと読まなかった。反省。


## factory.Factoryを継承すると、データがsaveされない

factoryのクラスを定義する時に、以下のようにfactory.Factoryを継承すると、テスト内で使う時にデータがsaveされません。

そのため、作られたテストデータが保存されていることを前提とする処理が必ずfailしてしまいます。

例えば、UpdateとかDeleteとかのテストは全部失敗してしまいます。


## テストデータを作った時に、ちゃんと保存してほしい時はこうすればいい

```
class CustomerFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Customer

    name = "石原さとみ"
    gender = "女性"
    age = 31
```

そうすると、以下のようなテストも無事通ります。

```
class TestEditView(TestCase):
    def test_edit_http_get(self):
        CustomerFactory.create()
        response = self.client.get("/customer/1/edit")
        self.assertEqual(response.status_code, 200)
```


## 公式Docsはある程度まで読むべき
公式DOCSのURLはこちら。
https://factoryboy.readthedocs.io/en/latest/index.html#

見てもらえるとわかる通り、最初の方の例は全部factory.Factoryになっています。

私はこれに飛びついた結果、ビミョーに時間を取られてしまいました。

Introductionの下の方にあるstrategiesまで読めば、継承すべきはDjangoModelFactoryだとわかったはずでした。

Introductionくらいは全部読むべき。反省。
スタートアップの成長に役立つツール6選！

あなたが起業やベンチャーにキャリアチェンジすることを考えたことがありますか？正直、私があります、特に仕事がうまくいかない時ですね。でも、何からはじめますか？ 資金、経験、失敗、アイデア……と、いろいろな疑問が浮かび上がってきます。

今のビッグデータ時代には、ビッグデータを活用してビジネスに生かすことは、今や当たり前になりつつあり、この激しい競争の中でスタートアップが生き残る道も厳しいです。大企業などのように潤沢な資金と時間を費やせないスタートアップにとって、限られているリソースをどのように最大の効果に出るのか？

近年では、ソーシャルメディアような無料ツールが低予算でマーケティング戦略を実行することができます。マーケティングにかけられる予算が少ないスタートアップ企業は、マーケティングや広告の面ではかなり役に立ちます。

そこで今回は、タートアップの成長に欠かせないツールを6個、まとめてみました。

#[1. Googleトレンド](https://trends.google.co.jp/trends/?geo=JP)

どんな業界でも、市場の動向を研究し予測することは不可避です。起業者として、最も経済的な方法は、ビッグデータを活用して、業界の情報を了解できることです。Googleトレンドは、起業家が業界の発展トレンドを把握するのに役立つ便利なツールです。

Googleトレンドとは、特定のキーワードがどれくらい検索されているのか、どんなキーワードが人気なのかを視覚的にみることができるサービスです。例えば、自社のブランドはどのように検索されているでしょうか？検索数が急増するタイミングは？競合他社の状況は？Googleトレンドでは、リアルタイムの検索データをもとに顧客の検索行動の推移を分析することができます。Googleトレンドを使って市場の動向・人気度を把握しながら、戦略調整に活かすことができます。

#[2. Googleアナリティクス](https://analytics.google.com/analytics/web/?hl=ja#/)

オンラインビジネスで起業を行う場合、まず最初は、自社の製品や商品をアピールするWebサイト/ホームページを作るのは普通ですね。そこでWebサイトの分析に欠かせないのはアクセス解析ツールです。アクセス解析ツールを入れると、

どれくらいの人が訪問しているのか

どれくらいの成果が出ているのか

どのページがよく見られているのか

といった情報が分かります。この情報をもとにマーケティングを行っていくのが基本です。

Google アナリティクスは、Googleが提供している無料で高機能なアクセス解析ツールです。サイトへのアクセス数をリアルタイムに把握したり、アクセスデータを期間ごとやデバイスごとで比較もできるため、課題を抽出してサイト運営に活かすことができます。今では、多くの投稿サイト（Qiitaなど）でもGoogleアナリティクスのトラッキングコードを埋め込むことができます。トラッキングコードを埋め込むことで、自分の投稿やマイページなどがどの程度見られているかを把握することができるようになります。

#[3. SimilarWeb](https://www.similarweb.com/ja)

Webサイトのアクセス解析をするうえで、競合サイトのアクセス状況と自社のWebサイトのアクセス状況を比較したい時がありますよね？しかし、競合サイトを運営している会社に直接聞くわけにはいきません。そこでURLを入力するだけで、そのサイトのアクセス状況などを把握することができるツール「SimilarWeb」お勧めします。

SimilarWeb（シミラーウェブ）とは、イURLを入力するだけで、対象のサイトのトラフィック数、流入、検索のキーワード等などといった競合サイトのアクセス状況を把握できるツールです。その数字は、統計的な推測値ですが、ある程度の近似値が得られるという認知が広がっています。その精度は、もちろん100％完全にわかるものではありません。しかし、競合他社のある程度の傾向がつかめるなど、世界中から注目を集めています。

#[4. Octoparse](https://www.octoparse.jp/)

ビジネスを成長させるためには、市場やターゲット顧客を拡大することが不可欠です。そのため、ネット上に掲載されている会社情報から、攻めたい企業を選ぶだけで、ターゲットリストを作るのは普通です。ターゲットリストを基に、リードやアポイントを追加し、顧客への適切なアプローチを可能にします。そこで、 Web情報を自動収集できるツール「Octoparse」を紹介したいです。

Octoparseは無料のWebスクレイピングツールで、コーディングせずにWebデータをすばやく取得でき、エクセルファイルなど利用可能なデータに変換できます。セールスにおいて、例えば、[ｉタウンページからお店・企業の電話番号を取得する](http://jp.octoparse.com/tutorial/scrape-phone-number-from-itpnejp/)場合、コピペは面倒で、OctoparseのようなWebスクレイピングツールを使うと、電話番号を簡単に抽出し、効率的にセールスリストを作成できます。

#[5. Mailchimp](http://mailchimp.com/)

近年、日本でもデジタルマーケティングに関する施策を行う企業が増えてきました。そのなかで、もっとも身近な施策の１つが「メールマーケティング」です。企業は自社の持つ顧客リストに対してEメールを配信することで、集客やファンの育成、リピーターの醸成などの目的を達成しようとします。古くからあるメルマガ（メールマガジン）もメールマーケティングの一形態です。今回はメールマーケティングで大人気の「MailChimp」お勧めします。

MailChimpの最大のメリットは、無料で使用できる範囲が広い点です。簡単にHTMLメールが作成できて、日時指定でメール配信設定ができて、配信先メールアドレスリストの作成・管理、A/Bテスト、各種分析レポート、Facebook広告の作成などメール配信システムで使える一般的な機能はほぼ実装されています。

#[6. Canva](https://www.canva.com/ja_jp/)

Webサイト/ホームページを作る時、ソーシャルメディアで投稿するとき、プロモーションをする時、必ずいろいろな画像を設計する必要がありますよね。スタートアップは広告宣伝費に大きな予算を割けないので、宣伝画像のデザインに苦戦している会社も多いと思います。そこで、無料で使えるグラフィックデザインツール「Canva」を利用できます。

「フライヤー（チラシ）」「バナー広告」「ポスター」「ロゴ」「名刺」「プレゼンテーション」などのマーケティングや集客用のデザインテンプレートも用意されています。中には飲食店用のメニューデザインなんかもあります。テンプレの中から気に入ったものを選んで、文字や写真を変えたりすることで、簡単におしゃれなデザインが作成できます。コスト削減したいスタートアップにとってはかなり経済的ですね！



いかがでしたでしょうか？
これらのツールを一つずつ、消化してあなたのビジョンや目標達成に役立てて頂ければと思います。
Julia Text I/O writeとprint

私はプログラミング初心者なので，テキストファイルとバイナリファイルの違いも知りませんでした(笑)．

#1 `write`はバイナリ出力
 
##例1-1
```
julia> write(stdout, [1,2,3]);
```
バイナリ出力なので返り値なし．
##例1-2
```
julia> write(stdout, "hello");
hello
```

#2 `print`はテキスト出力

##例2-1
```
julia> print(stdout, [1,2,3]);
[1, 2, 3]
```

##例2-2
```
julia> print(sdtout, "hello");
ERROR: UndefVarError: sdtout not defined
Stacktrace:
 [1] top-level scope at none:0

```

# ちなみに
セミコロンがないと，

```
julia> write(stdout, "hello")
hello5
```
Androidアプリのアプリ名のローカライズについてのメモ

Qiitaデビュー記念にとりあえず何かアウトプットしてみたかったので。

・環境
Unity2017.3.1f1
Android

# 国、言語ごとにアプリ名の変更の手順
 1. **Assets/Plugins/Android/res/**のフォルダの中に**values-[言語コード]-r[国コード]**のフォルダを作る。
 2. **values-[言語コード]-r[国コード]**の中に**strings.xml**ファイルを作る。

```strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">アプリ名</string>
</resources>
```

以上。

**values-[言語コード]-r[国コード]**の例だが、
 - 日本語 values-ja
 - 英語 values-en
 - 韓国語(韓国) values-ko-rKR
 - 簡体字(中国本土) values-zh-rCN
 - 簡体字(シンガポール) values-zh-rSG
 - 繁体字(香港) values-zh-rHK
 - 繁体字(マカオ) values-zh-rMO
 - 繁体字(台湾) values-zh-rTW
 - スペイン語 values-es
 - アラビア語 values-ar
などなど。。。

[言語コードはここの639-1を参照](https://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7)
[国コードはここのalpha-2を参照](https://ja.wikipedia.org/wiki/ISO_3166-1)

何か違ったり、別の方法もあるよって方はコメントください。
Bottle使ってAWSでAPIを動かして見た

#はじめに
AWS上でWebAPIを動かす機会があったのでそのやり方を忘れないように、ここに綴っていきます！

##事前に準備するもの
- AWSアカウント

以上。

##手順
###AWSマネジメントコソールにログイン
<img width="400" alt="スクリーンショット 2018-11-09 14.09.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/237542/7d37f405-4664-47cf-a76f-18394e2f20f0.png">

その後EC2ダッシュボードへ

###サーバの設置
インスタンス作るだけ
青い「インスタンスの作成」から、
1.Amazonマシーンイメージを選択(AMIがあればそれを選択)
2.インスタンスの選択(CPUやメモリ)
3.インスタンスの設定(ネットワークなどの細かい設定)
4.ストレージの追加(サーバのストレージの増減)
5.タグの追加
6.セキュリティグループの設定(トラフィックを制御するファイアウォールのルールセット)
7.確認
を経てサーバを作成する
このとき,**pemファイル**を作っておくとsshやscpの際にいちいちメンドくさいことやらなくて良くなります。
私は**~/.ssh**ディレクトリにpemファイルを置きました。


####AMIの作成(必要なら)
やっぱ公式が最強
https://docs.aws.amazon.com/ja_jp/toolkit-for-visual-studio/latest/user-guide/tkv-create-ami-from-instance.html

###サーバに必要なパッケージなどをぶち込む 
yum で頑張る
python3(pyenv)
僕はpyenvを入れたのですが、ここではpython3.6を入れるコマンド書いときます

```commandline:
$ sudo yum install python36u python36u-libs python36u-devel python
```
bottle

```commandline:
$ pip install bottle
```

###ポートの解放
aws上でできます
インスタンスを指定し、説明欄のセキュリティグループのインバウンドに行きます
編集ボタンを押してタイプ,プロトコル,ポート範囲,ソースを設定します
<img width="400" alt="スクリーンショット 2018-11-09 14.26.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/237542/6d8f662c-1e1a-977b-7ea2-f2137e0a3b3e.png">
この例だと80,20,10080番ポートを開放してます


###実行
####ログイン
```commandline:
$ssh -i .ssh/***.pem ec2-user@¥¥¥¥¥.?????.amazonaws.com
```
###pythonのコード
bottleを用いたpythonコードを書きます

```python:api.py
# -*- coding:utf-8 -*-

from bottle import route, run
from bottle import get, post, put, delete, request, response
import json

test_data = {"flag":"True","test":"OK"}

@get('/test')
def return_json():
	return json.dumps(test_data)
	#return test_data

@get('/test/<element:re:[a-z]+>')
def return_specific_element(element):
	print(element)
	if element in test_data:
		print("OK")
		return test_data[element]
	else :
		response.status = 404
		return {}

@post('/test/post')
def post():
	#requestはjson形式
	print(request.params.keys())
	for key in request.params.keys():
		print("key:",key)
		if key not in test_data :
			test_data[key] = request.params[key]
			print("add_data")
	print(test_data)
	return "succeess"

run(host='0.0.0.0',port=10080,debug=False,reloader=True)
```
テスト用です
bottleについて詳しく知りたい人は[ここ](https://bottl-translate-ja.readthedocs.io/en/latest/index.html)をみるといいと思います

####コンソールから実行

```commandline:
$ python api.py
```

すると・・・

```commadline:
Bottle v0.12.13 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:10080/
Hit Ctrl-C to quit.
```
みたいな感じのが出ます。これで無事動いています
この例だと10080ポートを指定しているので、
*AWSのインスタンスのURL:10080/test/flag*
を叩くと・・・
![スクリーンショット 2018-12-04 16.07.24.png](https://qiita-image-store.s3.amazonaws.com/0/237542/15f1acc2-27be-2dc8-3f7b-5f6607e47b89.png)
上のコードのtest_dataの中身が確認できています

##おまけ
AMI : インスタンスの作成に必要なソフトウェア構成 (OS、アプリケーションサーバー、アプリケーション) を含むテンプレートです

###サーバで使えるコマンド
ファイル送る時

```commandline:
$ scp -i .ssh/***.pem -r (ローカルの指定のディレクトリ) ec2-user@¥¥¥¥¥.?????.amazonaws.com:(サーバの指定のディレクトリ)
```

プロセス情報を見る &　削除

```commandline:
$ ps -ef | grep ***
$ kill (process number)
```
##感想
やっぱ定期的に使ってないと忘れるよね
メタって何？

## メタ〇〇ってよく聞くけど、実際どういう意味なの

メタレベル、メタ言語、メタ認知、メタ的、メタプログラミング、メタフィクション...
メタがつく言葉は沢山あります。

しかし、メタが何を示しているのかイマイチよく分からず、毎回どういうこと？となっていたのでちゃんと調べました。

## 「メタ」の用法は主に２つある

#### ①　接頭語としてのメタ
> メタ（meta-）とは、「高次な－」「超－」「－間の」「－を含んだ」「ーを入れた」「－の後ろの」等の意味の接頭語。ギリシア語から。[Wiki](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF)

先ほど紹介した例のうちこの用法で使われているのは、「メタレベル」「メタ言語」「メタ認知」「メタプログラミング」「メタフィクション」です。

Wikiには色々書かれていますが、 `あるものより１つ上の(高次元)` とか `より広く深い` とか `次元を超えた` といった意味で使われていることが多いと思います。

Wikiに照らして例達を訳していくと、

- 「メタレベル」 = 高次元
- 「メタ言語」 = ある言語の(後ろの)背景にある言語
- 「メタ認知」 = より広く深い認知
- 「メタプログラミング」= 高次元のプログラミング
- 「メタフィクション」= 次元を超えたフィクション(超次元、高次元の作り話)

こんな感じになるのかな。
正確な定義は辞書等をご参照ください。

意訳してみたところでイマイチ意味が分からないのは、そもそも `高次元` という概念が抽象的すぎるから。また、その`高次元` にあたる概念や `次元` が何を指しているのかはそれぞれで異なるため、一概に「メタ」を説明することは難しいです。

##### そもそも高次元とは
> **次元 (じげん)**
ｎ 個の変数で状態を記述する時、その ｎ を次元と言う。
例、直線は一次元、平面は二次元、空間の三方向のひろがりを表す時は三次元。[google](https://www.google.co.jp/search?&q=%E6%AC%A1%E5%85%83)

次元がこのように定義されているとすると、高次元は`n+1次元` 以上を指すということになるのでしょうか。~~(ど文系なので詳しいことは数学科の方に)~~

とりあえず `より多くのもの(概念)を内包するもの` 、誤解を恐れずかなりざっくり言えば `より複雑なもの` だと捉えれば良さそうです。
<br>

#### ②　メタファーの略

> メタファー（希: μεταφορά[1]、羅: metaphorá、独: Metapher、英: metaphor）は、隠喩（いんゆ）、暗喩（あんゆ）ともいい、伝統的には修辞技法のひとつとされ、比喩の一種でありながら、比喩であることを明示する形式ではないものを指す。[Wiki](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E3%83%95%E3%82%A1%E3%83%BC)

先ほどの例で言うと「メタ的」がそれにあたります。

例えば `「この小説はメタ的要素が多くてわかりづらい。」` という表現は、 `「この小説は隠喩が多くてわかりづらい。」` という意味です。

小説やアニメ等の話をしている際によく使われる言葉に「メタ発言」や「メタ表現」がありますが、これらは用法①です。

`「先週の最後のシーンで〇〇がしてたhogehogeっていうメタ発言(超次元)、すごくメタ的(隠喩)じゃなかった？」`
`「なんのメタ(隠喩)なの？」`

ややこしいですね。
とりあえず私は「メタ+的」となっていたら隠喩と判断することにしています。


## まとめ

- 接頭辞としての「メタ」はかなり抽象的な言葉である。
- 「メタ」のつく言葉はそれぞれ具体的なイメージを掴まないと理解が難しい。
<br>(結局１つ１つ調べないと理解できない)
- メタ的って書いてあったら大体メタファーの略


誤りや不足等あればご指摘いただけると幸いです...。


## おまけ
[メタにまつわる用語解説（リンク集）](https://qiita.com/bambis13s/items/60b908f181f02878184b)

## 参考
[メタ・メタレベルの意味が89％くらいわかる解説](https://storymaker.click/%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AA%E3%83%BC%E7%94%A8%E8%AA%9E/4962/)
atcoder 対策(rate 0~ 1200)

#テクニック集
##パスカルの三角形
・使い道
組み合わせの数を計算したい時、普通にやろうと考えると分母と分子についてそれぞれfor文で求めることを考えるが、そうすると簡単に桁溢れしてしまう。そこで、このパスカルの三角形を使う。これは二項展開を用いて、組み合わせの数を求めていくもので、dpで実装できる。実装例は下の通り

```java

long[][] pdp = new long[51][51];
		pdp[0][0] = 1;
		for (int x = 1; x <= 50; x++) {				//組み合わせの数の計算
			for (int k = 0; k <= x; k++) {
				if (k - 1 >= 0) {
					pdp[x][k] = pdp[x-1][k-1] + pdp[x-1][k];
				} else {
					pdp[x][k] = pdp[x-1][k];
				}
			}
		}

```
元Flash使い・現JS使いの僕がUIアニメーション作成時に工夫しているポイント

[aptpod Advent Calendar 2018](https://qiita.com/advent-calendar/2018/aptpod)の5日目担当蔵下です。2日目（[JSで描画したViewをHeadless ChromeでPDF化するまで](https://qiita.com/umi_kappa/items/11f4470b75e01bff5c1b)）に続き2記事目です:joy:

現在はJSでガリガリとUIアニメーションを実装することが多いのですが（それ以外にも実装してます笑）、社会人スタート当時はFlash（ActionScript3.0）をメインで触ってました。某検索エンジン掲載用のバナーを100本ノックとかやったな〜とおじさんらしく懐かしむ。

言語は変われど人体（ユーザーの目）や視覚・感覚は変わらないため、いまでもUIアニメーション作成時に工夫しているポイントをいくつか紹介します。

# ボタンが硬いものか柔らかいものかを考える

コード上ではただの `<button>` ですが、デザインのトンマナによってはそのボタンが硬いものだったり柔らかいものだったりします。硬いとscaleは変化させずにパキっと背景の色を変えたり、柔らかいものだとほわんとscalseが変化して長めのアニメーションしたり。そのボタンがどういう場所に置かれるのかを意識するといいかと思います。

# 特殊なEasingはなるべくそのまま使わない

ここでいう特殊なEasingとは、開始〜終了までの変化を超えるものとします（例えばscaleが0.5→1.2→1.0などのように、2つめのscaleが終了のscaleを超えているなど）。UIアニメーションを実装するときにいつもお世話になっている[Easing Function 早見表](https://easings.net/)。この中でいうと`Back`, `Elastic`, `Bounce`が特殊なEasing。

![特殊なEasing](https://qiita-image-store.s3.amazonaws.com/0/55103/fc81f000-03fe-5c6e-a6cf-8cfcec988bb0.png)
引用「[Easing Function 早見表](https://easings.net/)」

指定するだけで動きのあるアニメーションになってくれるので便利なのですが、変化量や変化する間隔が調整しづらいため使い所によっては違和感が出てしまいます。違和感を感じたときは、一つ一つの変化を分割してアニメーションを作りつなげていくと自然なアニメーションになります。使っているEasingは違いますがこちらの記事「[フロントエンド演出：ふわふわ浮遊する動きの作り方](https://qiita.com/umi_kappa/items/9efe0478a8a5bf98141b)」で雰囲気は感じられるかと思います。

# 時間の短いアニメーションにはlinearもあり

`linear`はアニメーション時間に対しての変化量が一定のEasingです。

![linear](https://qiita-image-store.s3.amazonaws.com/0/55103/f91f110c-f718-ae61-a88a-f98599de5885.png)
引用「[Easing Function 早見表](https://easings.net/)」

`linear`は等速なのでなかなかUIアニメーションには使いづらい印象がありますが、MouseOut時などの時間の短いアニメーションには`linear`が向いています。時間が短いと人の目で追うことは難しいですし、MouseOutのアニメーションをシンプルなものにすることで、次の操作の邪魔にならないようになります。

# ときにはベジェ曲線でEasingを作る

なかなかハマるEasing無いな... と思ったら思いきって作っちゃいましょう！ [cubic-bezier.com](http://cubic-bezier.com/)なら、GUIで細かなEasingが作れます。

![cubic-bezier.com](https://qiita-image-store.s3.amazonaws.com/0/55103/021920fd-1ad3-4d91-968b-4a06365cebc4.png)

# 一つのアプリで複数種類のEasingは多用しない

デザインにキーカラーがあるように、Easingもある程度絞り込むことをおすすめします。UIによってEasingがバラバラだと統一感がなくごちゃっとした印象になってしまいます。個人的に使うことが多いのは、`Expo`と`linear`の組み合わせです。in（MouseOver）は`Expo`0.5s、out（MouseOut）は`linear`0.2sのように指定したりします。

# 複数の要素を表示するときはテンポよく

Webページやアプリだと、オープニングでスプラッシュが入りそれからUIが表示されることが多いかと思います。ヘッダー・サイドメニュー・フッターなど、スプラッシュの後に1秒でも早く表示させてユーザーにテンポよく使ってもらいたい！ と思って一気に表示するとごちゃっとなったり、一気に描画負荷が上がってカクついたり... かと言って一つずつ表示すると待たせてしまう... そういうときは、ある程度アニメーションを並行して表示させて邪魔にならずテンポのいいポイントを探すと気持ちいい表示が実現できます。

# まとめ

現在のアプリケーションは、Flash全盛期に比べて性質も異なり、アニメーション自体が主役になってしまうと、かえってユーザーに混乱を与えてしまうことにもなりかねません。ユーザーが気づかない間に「あれ？ このアニメーション気持ちいいな。ついつい触っちゃうな」と思わせるような絶妙な加減を探って、クリック率の向上を目指したり、あくびしてても使えちゃうUIの実現を目指して、これからもUIアニメーションを作っていけたらと思います。
Djangoでプロジェクト内で共通のテンプレートを使う

# 背景

- Djangoでプロジェクト内に複数のアプリがある場合に、サイト全体でスタイルを統一したい。

# 環境

- Python 3.7.0 (3.7.1が出ていて、3.7.2も近々リリースされるので、入れ替え予定です)
- Django 2.1.3

# やり方

- プロジェクト直下にtemplatesフォルダを作成
- 上記で作成したフォルダに、sitebase.htmlを作成(サイト全体でユニークな名前にする)
- settings.pyを修正し、テンプレートを探すフォルダに上記を追加

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')],      # ここを変更
        'APP_DIRS': True,
        'OPTIONS': {
            (略)
        },
    },
]
```

- 上記のsitebase.htmlにHTMLを記述

- アプリ側のテンプレートで、上記を呼び出す。

```{% extends 'sitebase.html' %}```


# 感想

Djangoで静的ファイルをどこに置いてsettings.pyをどう書くのがベストか、まだ悩んでいます。
接続したAndroid端末のキャプチャ簡単に取る + クリップボードに貼り付けてくれるスクリプトを作った(Mac)

PCからAndroid端末のキャプチャを取る方法はいくつかありますが、既存のものに不便さを感じていたので効率化してみました。
私はよく、接続しているAndroid端末のキャプチャを取ってPCで開いているSlackに貼り付けたいことがあります。
最終型だけ見たい方は[④リサイズできるようにしてみる](#リサイズできるようにしてみる)からどうぞ。

#既存のキャプチャ方法はどれももう一つ足りない
* 端末で取って転送
* AndroidStudio
* Adbそのまま

どれも今やっている作業を中断する必要があります。

#キャプチャを効率化する
なるべく早く、少ない手順でキャプチャを取る・利用できることを目指す。

##①キャプチャ用のshellスクリプトを組む
ファイル名は日付にしてみます。
お馴染みのadbコマンド使いshellを作成。

```sh:screencap.sh
# 必要に応じてadbをexportする
DATETIME=$(date +%Y-%m%d-%H%M-%S)
DEVICE_FILE_PATH="/sdcard/${DATETIME}.png"
LOCAL_FILE_PATH="キャプチャを保存したいパス/${DATETIME}.png"
adb shell screencap -p ${DEVICE_FILE_PATH}
adb pull ${DEVICE_FILE_PATH} ${LOCAL_FILE_PATH}
adb shell rm -f "${DEVICE_FILE_PATH}"
````
exportですが、②以降でapplescriptで呼ぶ際にパスが通っていない状態になるので、1行目でadbのパスを通すと良いです。

##②どこでもキャプチャできるようにする
applescriptを作る。
アプリケーションとして保存してアプリケーションフォルダに入れれば、alfredから呼べるのでどこからでも呼べるようになります。

```applescript:screencap.app
do shell script "上で作ったシェルスクリプトのパス"
display notification "キャプチャ完了"
```
これで呼び出す際はPATHが通っていないので、screencap.sh側でexportするまたはadbコマンドをフルパスで書く必要があります。

##③：クリップボードに貼り付ける
slackで貼り付けたい場合が多かったので、実行したときにクリップボードに貼り付けられるようにしてみる。
AppleScriptにクリップボードのコマンドがある + シェルからAppleScriptを呼べることが分かったのでshに突っ込む。
最下行にクリップボード貼り付け処理を追加

```sh:screencap.sh
# 必要に応じてadbをexportする
DATETIME=$(date +%Y-%m%d-%H%M-%S)
DEVICE_FILE_PATH="/sdcard/${DATETIME}.png"
LOCAL_FILE_PATH="キャプチャを保存したいパス/${DATETIME}.png"
adb shell screencap -p ${DEVICE_FILE_PATH}
adb pull ${DEVICE_FILE_PATH} ${LOCAL_FILE_PATH}
adb shell rm -f "${DEVICE_FILE_PATH}"

# AppleScriptでクリップボードにキャプチャをセット
osascript -e "set the clipboard to (read (POSIX file \"${LOCAL_FILE_PATH}\") as JPEG picture)"
````
set the clipboard toでクリップボードに貼り付けられる。
画像パスではただの文字列になってしまうので、readを使って画像を読み取る。
JPEGと指定してもpngでクリップボードに貼り付けられたので、JPEGでも大丈夫そう(PNGではダメだった)


##④リサイズできるようにしてみる
Bitbucketを利用することがあり、プルリクにキャプチャを貼り付けることがあったが、デフォルトだとサイズがそのままになってしまい大きすぎることがあった。
プルリクに画像を貼るときにはリサイズできたら便利・・・と思いリサイズ機能も付けてみた。

```sh:screencap.sh
# 必要に応じてadbをexportする
DATETIME=$(date +%Y-%m%d-%H%M-%S)
DEVICE_FILE_PATH="/sdcard/${DATETIME}.png"
LOCAL_FILE_PATH="キャプチャを保存したいパス/${DATETIME}.png"
adb shell screencap -p ${DEVICE_FILE_PATH}
adb pull ${DEVICE_FILE_PATH} ${LOCAL_FILE_PATH}
adb shell rm -f "${DEVICE_FILE_PATH}"

# 引数が指定されていた場合、その引数の値にリサイズする
if [ $# -eq 1 ]; then
    sips --resampleWidth $1 ${LOCAL_FILE_PATH}
fi

# AppleScriptでクリップボードにキャプチャをセット
osascript -e "set the clipboard to (read (POSIX file \"${LOCAL_FILE_PATH}\") as JPEG picture)"
```
sipsコマンドは、Macで画像処理ができるコマンドで、簡単にリサイズをすることができました。
これで、新しくresize_screencap.appをAppleScriptで作ればAlfredから選んで実行できるようになります。
Amazon CloudWatch Eventsについて

# CloudWatch Eventsとは？
> Amazon CloudWatch Events は、Amazon Web Services (AWS) リソースの変更を示すシステムイベントのほぼリアルタイムのストリームを提供します。すぐに設定できる簡単なルールを使用して、ルールに一致したイベントを 1 つ以上のターゲット関数またはストリームに振り分けることができます。オペレーションの変更が発生すると、CloudWatch イベント はその変更を認識します。CloudWatch イベント は、オペレーションの変更に応答し、必要に応じて、応答メッセージを環境に送り、機能をアクティブ化し、変更を行い、状態情報を収集することによって、修正アクションを実行します。

引用 [公式](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html)
ざっくり説明すると、**何かが起こったら、何かを実行する**といったことを設定できるということ

# どんなことができるの？
* EC2の起動停止した際に、Slackを送信するためのlambdaを実行する
* 2018/04/21 00:00:00秒にlambda関数を実行したい

|Input|Output|
|---|---|
|EC2停止|Slackを送信|
|時間の設定|lambdaを実行|

# 用語
- イベント  
EC2が保留中から実行中に変わったなど、**何かが起こったら**の部分
- ターゲット　  
イベントに起因して実行されるもの。Amazon SQSキュー・AWS Lambdaなどなど
- ルール  
任意に設定することができ、そのルールに基づいたイベントが発生した場合にターゲットが実行される。  
Cronのようなことも可能
[Laravel5.7] Eloquent リレーションにおける saveメソド と createメソド の特徴

Eloquentでは新しく作ったモデルとのリレーションに使える `save` メソド、 `create` メソドなどが用意されている。

※ 5.7 から追加された `push` については[こちら。](https://qiita.com/shosho/items/18e78985a702573e6444)

## `save` メソド
リレーションの `save` メソドを使えば、親テーブルのidを子テーブル該当のカラムに直接入れることが可能。

```php
$comment = new App\Comment(['message' => 'A new comment.']);

$post = App\Post::find(1);

//これで Comment の post_id に Post の id が入る
$post->comments()->save($comment);
``` 

動的プロパティ `->` で呼ぶのではなく、メソド `comments()` でよんでリレーションインスタンスをとってきているのがミソ。

## `saveMany` メソド
複数のモデルについて同様にセーブかつ親のidを入れたいときは `saveMany` メソドが使える。

```php
$post = App\Post::find(1);

$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);
```

## `create` メソド
`save` や `saveMany` と似た様な動きをする。
ただし、`save` はEloquentまるごとのインスタンスを受け入れるのに対し、 **`create` が受け入れるのはPHPの配列** という点で異なる。

```php
$post = App\Post::find(1);

$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);
```

こちらにも複数のリレーションモデルがいっぺんに作れる `createMany` が用意されている。

```php
$post = App\Post::find(1);

$post->comments()->createMany([
    [
        'message' => 'A new comment.',
    ],
    [
        'message' => 'Another new comment.',
    ],
]);
```

### 公式ドキュメント
https://laravel.com/docs/5.7/eloquent-relationships#inserting-and-updating-related-models
AWS System Manager セッションマネージャーを利用してEC2インスタンスにシェルアクセスする時に楽したい

昨日は@cfikenによる[TensorFlow で学習したモデルのグラフを `tf.train.import_meta_graph` でロードする](https://qiita.com/cfiken/private/bcdd7eb945c5c3b2bb5f)でした。
とても素晴らしい内容でしたね！
まだ、見てない方がいらしたらどうぞ！！！

では、本題に入ります。
# AWS System Manager セッションマネージャー
インスタンスへアクセスをする時に使っているのが下記です。

```
$ aws ssm start-session --target instance-id
```

毎度、同じインスタンスへアクセスするのでしたら気にならないのですが別のインスタンスへアクセスする時もあります。
その都度、`aws ec2 describe-instances`を利用してインスタンスIDを調べるのは面倒だったのでjqとpecoを使用して簡単にインスタンスへアクセスが出来るようにshellを作成しました。

# 作成したやつ

```shell
#!/bin/sh

PROFILE=''
if [ $1 ]; then
    PROFILE="--profile $1"
fi

ID=`aws ec2 describe-instances $PROFILE | \
    jq -r '.[][].Instances[]
         | [.InstanceId,
            [.Tags[] | select(.Key == "Name").Value][]]
         | @tsv' | \
    column -t | \
    peco | perl -pe 's/\s.*//'`
aws ssm start-session --target $ID $PROFILE
```

## やっていること
まず、`aws ec2 describe-instances`でインスタンスの情報を取得します。
次にjqを使ってインスタンスIDとタグのNameをtsvで吐きます。[^1]
その結果をpecoに渡してサーチできるようにします。
選択されたもので必要なのはインスタンスIDだけなのでNameの部分の正規表現を利用して削除します。
最後に`aws ssm start-session --target`に選択されたインスタンスIDを渡してインスタンスへアクセスします。

### --profileについて
複数のアカウントを使用していると`--profile`でデフォルト以外のアカウントを使用する機会があります。
なので、引数を渡して別のアカウントを使用することが出来るようにしました。[^2]


# 動かしてみる
```
$ ssm $PROFILE
```
![ssm一覧.png](https://qiita-image-store.s3.amazonaws.com/0/27949/fe88b5ec-be93-098a-e0af-437a6af8176c.png)
こんな感じで出てくるのであとは任意のものを選択すると
![loginssm.png](https://qiita-image-store.s3.amazonaws.com/0/27949/155db20c-6714-c0f6-d144-270ef9ee28a9.png)
このようにインスタンスへアクセスしてくれます。[^3]
楽できるようになりましたね！
お疲れ様でした。

明日は@SAMUKEIが[looker](https://looker.com/)について話してくれるのでとても楽しみですね！
ワクワクして眠れないですね！！！

[^1]: タグのNameを設定している前提です。
[^2]: デフォルトの設定のみなら引数は渡す必要はありません。
[^3]: aliasはssmではなくてお好きなものをどうぞ
NodeMCU ESP-32 MotorShield FULL  IO Extension Board

NodeMCU　ESP32用拡張ボード兼モーターシールドフルの使用方法です。

![ESP-32-MotorFull.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/3f2331df-7442-af7e-c0d0-f223dfea6a99.jpeg)


![230554946_Top.png](https://qiita-image-store.s3.amazonaws.com/0/285344/af19437e-218a-d433-87c0-c959c893f695.png)

搭載しているモータードライバー　L293DDは１２V のモーターも使用できます。
ただし、NodeMCUのキャパシタの制約から１２Vを印加すると、キャパシタが飛びます。(飛びました）
このため、１２Vを一度５Vに降圧し、さらに降圧しESP-32に3.3vを供給することとなります。

回路図は以下の通りです。
![ESP-32-Motor.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/13c9346c-8b97-8167-f5ec-d3a2cc4104da.jpeg)

DCモーターは出力が２系統出ており、XHコネクタには同じ向きの接続で、２台ずつモーター制御可能です。
モーター出力は１４,２７ピンをPWM制御する事でスピードコントロール可能です。

モーターを２個制御する場合
モーター１には１２ピンと１３ピンを
モーター２には２５ピンと２６ピンを
設定します。
モーター１の動作には、１４ピンを
モーター２の動作には、２７ピンを
Highにするか、PWMで制御します。

使用環境により以下のジャンパーをつなぐ必要があります。
USB電源
VDDのみ：JP1,JP5

５V以上供給の場合
・VDDに直結したい場合（Servoに５V以上を供給したい）：JP1、JP3
・VDDには、５Vを供給したい場合：JP3、JP5

・モーターをつなげたい場合はJP4も接続(入力電圧をそのまま印加します）
＊入力電圧が５V以上でモーターに５Vをつなげたい場合は、JP2の＋と,JP4の出力を接続します。

本製品の製作理由は、NodeMCUに12Vモーターを接続し、Servoなどを稼動する時に５Vに降圧できるほうが良い為です。
かなりオーバースペックな内容となっていますが、あるかないかは大きな違いと思っています。

完成品としては、こういったものになります。
![47572600_354187148470550_5927828611133341696_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/eb7c615d-81fc-9c4b-ef7c-85c839cd5458.jpeg)

PCBWay 2nd PCB Design Contestに応募しました。
https://www.pcbway.com/project/shareproject/NodeMCU_ESP_32_MotorShield_FULL__IO_Extension_Board_.html
日本国内では、当方が製作し頒布可能ですが、国外の業者さんで、大量に廉価で販売して貰えるならば最高ですね。
![undefined]()

BOMリスト
![image.png](https://qiita-image-store.s3.amazonaws.com/0/285344/503b1bee-18bd-a188-e588-bed97bd0940d.png)
Circle CI で GCRのイメージを使用する際の注意

## Circle CI で GCRのパスを指定する時の注意
GCRのパスを取得するときにauthのpasswordにあらかじめ設定しているCircle CIの環境変数をいれるのですが、これはBASE64でEncodeせずサービスアカウントのjsonを直接入れます。

```
version: 2.1
executors:
  default:
    working_directory: /root/project/
    docker:
      - image: gcr.io/$PROJECT_ID/appengine/go:latest
        auth:
          username: _json_key
          password: $GCLOUD_SERVICE_KEY
    environment:
      - TZ: "/usr/share/zoneinfo/Asia/Tokyo"
```

base64にencodeされた環境変数を指定していると以下のようなエラーがでます

```
Error response from daemon: Get https://gcr.io/v2/...: unknown: Unable to parse json key.
```

## 参考
- https://github.com/circleci/circleci-docs/issues/2193
- https://github.com/circleci/circleci-docs/pull/2195
CryptZombiesレッスン2(チャプター11~15)の自分なりのまとめ

# 最初に
この記事は私がCryptZombiesを進めていく上で自分なりにまとめたものです。
前回の記事
https://qiita.com/daichi77/items/a3d758853da726f25874
参考にしたサイト
サイト名: イーサリアム上のDApp開発をゲームを作って学びましょう
URL: https://cryptozombies.io/jp/　
チャプター１１ Interfaceを使用する
## 今回したこと
KittyInterfaceの初期化

# チャプター１２  複数の返り値の処理
## 今回の要点
値を複数返す関数を呼び出した場合(値が３つ帰ってくる場合)

```
(a,b,c) = 関数;
```
という風に受け取る。

```
(,,c) = 関数;
```
と書くと3つ目の変数のみ格納することもできる。

## 今回したこと(テスト)
1. feedOnKitty関数の定義
2. kittyDnaを定義
3. kittyContract.getKittyを使ってgenesをkittyDnaに格納。
4. feedAndMultiplyで_zombieIdとkittyDna渡して呼び出し。
この時点でキティをゾンビにできるようになった。

# チャプター１３ ボーナス:KittyGenes
## 今回の要点&今回したこと
if文はjsと書き方一緒。
DNA最後の２桁を99にすることでkittyかどうかを判断できるようにした。
# チャプター 14&15
実行するだけなので特になし
Custom Instrumentsのインストール方法

## iPhoneターゲットでArchive

<img width="392" alt="Screen Shot 2018-11-22 at 16.32.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/fdf0ac0e-0c34-6e3c-38db-8de13f534a23.png">

## Built Productsでexport

<img width="433" alt="Screen Shot 2018-11-22 at 16.33.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/5222a455-2b19-1750-2fea-ea9d7422753c.png">

## `*.instrdst` をダブルクリックしてインストール
<img width="769" alt="Screen Shot 2018-12-04 at 15.01.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/33376d04-e0d0-3a9d-c589-805a8f6fa90e.png">

## 以下、共通で使う `*.tracetemplate` を作成する方法 (すでにある場合は不要)

## Instrumentsを開き、最初はBlankを選択
<img width="769" alt="Screen Shot 2018-12-04 at 15.03.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/55d60ce9-1090-cd80-68d5-a5f756688fab.png">

### 右上のプルダウンにインストールしたpackageがある

<img width="922" alt="Screen Shot 2018-12-04 at 15.04.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/1dd93b64-cbc7-2428-c6b5-dd4c2db42af8.png">

必要なものと合わせてtraceviewに追加する。
<img width="406" alt="Screen Shot 2018-12-04 at 15.04.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/11d7d93b-af9e-854b-3049-b4e36ec45456.png">

### File => Save as Template

<img width="411" alt="Screen Shot 2018-12-04 at 15.05.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/19ad1942-b392-2d55-dcfe-d18d82a18c95.png">

### 保存したTemplateをダブルクリックでいつでも上記で選択した設定でProfileが開始できる

<img width="110" alt="Screen Shot 2018-12-04 at 15.06.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/6b536218-e615-911d-622f-e1c2ccaae748.png">

### repositoryにコミットするのがオススメ

- `*.instrpkg`
- `*.tracetemplate`

チームで共有できる。各メンバーごとに上記packageのインストールは必要そう。
`*.instrdst` (archive&exportした成果物) をコミットしてもいいかもしれないが、各自でデバッグできた方がいいと思うし各自でarchiveしてもらうということでいい気がする。

## Debugする

### Custom Instruments をDebug実行
<img width="397" alt="Screen Shot 2018-12-04 at 15.22.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/c11454d6-46a4-f681-81db-8f711c497b78.png">

### `*.tracetemplate` は `*.instrpkg` のデフォルトtemplateとして指定できる。

```xml
    <template>
        <import-from-file>relative/path/to/VideoContentKeySession.tracetemplate</import-from-file>
    </template>
```

たしかこれで一覧にも自分が作ったものが現れるようになる。
<img width="773" alt="Screen Shot 2018-12-04 at 15.23.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/35008/0b0fcddf-6915-9ee2-0e98-9e136746e5ef.png">


## 参考
- https://developer.apple.com/videos/play/wwdc2018/410/
git参考にしたサイトまとめ

#git ignoreファイルの書き方
https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff

#gitignore 特定ディレクトリの特定ファイルだけを除外したい時などに役立つ
https://qiita.com/anqooqie/items/110957797b3d5280c44f

#会社のサーバーをgitで使用する時のurlの指定など
https://qiita.com/laineus/items/d61e004545ef0ef0b004

#リモートリポジトリは、ベアリポジトリにするべきなのか

https://open-groove.net/git/git-branch-merge/

#ノンベアリポジトリは、作業用でベアリポジトリにpushさせてそのベアリポジトリ(更新履歴しか持たないリポジトリ)から本番用のリポジトリなどをpullさせるように構築させてあげる(git のhookというものを使用する)
http://www.nekotricolor.com/entry/theory-of-bare-and-non-bare-repository-manage-wordpress-themes-with-git

#git pushしてもリモートリポジトリに反映されない(hooksファイルをいじって自動デプロイ環境を作成する)

https://qiita.com/zaburo/items/8886be1a733aaf581045

#サービス時に考えないといけない視点
http://www.neopathos4.com/entry/2018/09/09/043217

#git のremoteの向き先のurlなどを変更する(git hooksで自動デプロイするように変更にした時に設定)
https://qiita.com/minoringo/items/917e325892733e0d606e

#git pushでremote rejectedと怒られた時にやったことメモ
https://qiita.com/ssm_snow/items/3041be842cadf68e6d67

#リポジトリが壊れた時に確認すること
https://bokunonikki.net/post/2018/0910_git_object_empty/



#gitでローカルにブランチがなくて引っ張ってきたい時のやり方(一人で複数端末を使用している時も同じ状況になることもある)
https://qiita.com/kota9/items/4226e9d4e538c881d410

#gitでコンフリクトした際に参考にしたサイト

http://www-creators.com/archives/1938
ブロックチェーンプロダクトを始めるときにする3つのこと

この記事は[Gaiax Group Advent Calendar 2018](https://qiita.com/advent-calendar/2018/gaiax-group)の5日目の記事です。

2018年も多くのブロックチェーンプロダクトが世の中にリリースされました。その裏でテクノロジーハイプ・サイクルではブロックチェーンは過度な期待のピーク期を通り越し、幻滅期へ突入しました。そんな難しい状況の中、これからブロックチェーンのプロダクトを開発する方はたくさんいらっしゃると思います。この記事はそんな方へ少しでも役立つように書きました。

#1.メンバー全員で勉強会
ブロックチェーンについて精通したメンバーのみでプロジェクトがスタートできるなら、それはものすごくラッキーなことです。ほとんどの場合は、ブロックチェーンについてよく知らないメンバーが混ざっているでしょう。そこで、まずはブロックチェーンについて基本期な部分を学ぶことが重要になってきます。詳しいメンバーがいるなら、そのメンバーが教えるのが一番良いです。いないならば、外部で勉強しましょう。そして勉強した内容をチームメンバーへ共有することでアウトプットしましょう。そうやって、営業メンバーであれ、なんであれ、プロジェクトメンバーは全員ある程度以上の知識を持つようにしましょう。また、後からプロジェクトにジョインするメンバーにも必ず勉強会を開催するようにしましょう。

#2.ブロックチェーン活用のメリットを理解する
勉強をした結果、ブロックチェーンの活用のメリットを理解されたと思います。そこで、今進めているプロダクトにおけるブロックチェーン活用のメリットを理解しましょう。絶対に消えない台帳としての活用、C2Cのプラットフォームとしての活用、スマートコントラクトによる自動化、いろいろな側面を持つと思います。正しくメリットを理解することが、今後の開発やサービスの展開をやりやすくするでしょう。

#3.従来のクライアント・サーバー型との比較を行う
よくある話として、クライアント・サーバー型で実現できるのに、なぜブロックチェーンを使うのかというツッコミを受けることがあります。この問に対する答えを持つことは、必ずやらなくてはいけないことです。よくある勘違いとしては、「ブロックチェーンじゃないと出来ないこと」が必要になると考える人がいますが、その必要はありません。ブロックチェーンを使うことによって簡単に実装できる、ブロックチェーンを使ったほうが少し優れている程度でも大丈夫です。この議論をしブロックチェーンを使ったほうが良いという結論が出ていることが重要です。

#まとめ
細かい実装の話はプロダクトによって全く違い一概には言えないので、ここでは触れませんが、まずは必ずプロトタイプを作ってから、本開発に移りましょう。ブロックチェーン活用のメリット、従来のクラサバ型からのメリットを証明しながら進んでいけば、きっとよいブロックチェーンプロダクトが作れると思います。2019年いいプロダクトが産まれてくることを夢見て2018年を終えたいと思います。
[Laravel5.7] Eloquent リレーションで新たに追加された push メソド

## `push` メソド : 再帰的に保存
5.7から追加されたメソド。
`push` を使えば全部のリレーションに対し、再帰的に `save` することができる。
（親のidが子の該当カラムに自動的に入る）

```php
$post = App\Post::find(1);

$post->comments[0]->message = 'Message';
$post->comments[0]->author->name = 'Author Name';

$post->push();
```

### 公式ドキュメント
https://laravel.com/docs/5.7/eloquent-relationships#inserting-and-updating-related-models
Dockerの概念をつかむ講習を受けてきたのでその備忘録

#はじめに
Dockerの講習を受けてDockerの大枠だけある程度理解したつもりなので備忘録としてまとめておきます。
認識に違いがある場合は指摘してくださると助かります。
#読者対象
・Dockerってよくわかんないんだけどなに？
・Dockerってなんかすごそうだよね
・とりあえずDockerの雰囲気だけつかみたい

みたいな人を対象にしています。
#Dockerってなにがいいの？
Dockerのことをよくわからないとそもそもなにがいいのか？
というのがよくわかんないですよね？

Dockerを使うことでいいことは主に３つ！
**１、誰でも同じ環境で作業ができる！**
**2、作成した環境を配布しやすい！**
**3、とりあえず早い！**


##１、誰でもどこでも同じ環境で作業ができる！
これが個人的に一番すごいと思っている点なのですが、どういうことなのかというと、、、
例えば、新しい機能を追加して本番環境へデプロイを行う場合

先にテスト環境を用意してで動作に問題が無いかを確認してから本番に反映させますが、

テスト環境では問題なく動作したのに本番環境だとエラーが発生してしまうということとが発生してしまうことがあります。
そのような事態をDockerは起こらないようにカバーしてくれます。


##2、作成した環境を配布しやすい！
DockerにはDocker fileという環境をコードに落とし込んで保持する仕組みがあります。
これによりコードベースで環境を共有できるので環境の保持が簡単となるのです。

##3、とりあえず早い！
同じようなことを行えるVMよりも容量が小さく起動が早いのが特徴です


#登場人物

###Dockerイメージ
・Dockerを使って動かす物
・１度作ったら変更不可能
###DockerFile
Dockerの変更などをコードベースで保持するもの。
###Dockerレジストリ（DockerHub）
・Docker版のGithubのようなイメージ
・Dockerのベースファイルが多数集約されている
###Dockerエンジン
・Dockerイメージを起動させるための土台のようなもの


##Dockerイメージを扱う
###Dockerを初めて使う場合
<img width="1025" alt="スクリーンショット 2018-12-05 12.09.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/6401ae53-658b-6b75-0df1-b144b16b7699.png">

Dockerイメージを扱う手順は、、、
１、DockerレジストリからベースとなるDockerイメージをpull
2、Dockerエンジンを用いて起動

この２ステップのみです。

めっちゃ簡単ｗ

###既存のDockerイメージに変更を加えたい場合
<img width="679" alt="スクリーンショット 2018-12-05 12.48.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/5f7f727c-d8a1-d3cf-1ba4-3838ee00bec2.png">
Dockerに変更を加えたい場合は、直接Dockerイメージを変更するのでは無く
Dockerファイルの中身を書き変えて、そのDockerファイルをもとに新しくDockerイメージを作成するという形でDockerイメージを変更していきます。



#まとめ
今回の講義ではDockerの動かし方では無くDockerとはそもそもどのようなものなのか？
どのような動きをしているかの講義でした。
スピーカーの方もおっしゃっていたのですが、ある程度Dockerの雰囲気がわかったらチュートリアルやってくださいって行っていたので、とりあえず自分も手を動かしてみようとおもいます。

それでは良きDocker生活を〜
$form.submit() が発火しない場合に確認すること

jQueryを使って、JavaScriptからformのsubmitを行いたい場合にsubmitが発火しないことがある。
この調査で1時間くらい取られてしまったので、記録しておく。

# $form.submit()が発火しないコード

```js:index.js
$form = $('form')
$form.submit() // 効かない。画面遷移しない。
```

```html:index.html
<form action="/" method="post">
  <input type="submit" name="submit" />
</form>
```

inputの`name`に`submit`と定義してしまうと

```js
$form.submit()
```

実行時に、submitが発火せず、DOMが返却される。

# 解決策
jQueryでformのsubmitを行いたい場合は、nameに `submit` 以外のものを付与する。
例: `name="submitBtn"`などに変更する。

# 参照文献
[jQueryでsubmitしたり無効にしたりする方法](https://www.flatflag.nir87.com/submit-1356)
日本語でvimのfを使う

# f
vimでは`f`, `F`, `t`, `T`を使うことで、瞬時に目的の文字上にカーソルを移動することができます。

## 動作
`fa`でカーソルから右側の方向の１番近い「a」の位置に移動することができます。
`3fa`でカーソルから右側の方向の３番目に近い「a」の位置に移動することができます。
`fa`を実行した後に、`;`で次に`,`で前に移動できます。

## 日本語の場合
`f`の次にIMEを有効にして「あ」を打つことで「あ」に位置に移動できます。

# ダイグラフ
ダイグラフを使うことでキーボードには存在しない文字を入力することができます。インサートモードで`<C-k>SE`と打つことで§を入力することができます。そしてこれは平仮名や片仮名も入力することができるので、この機能を使えばIMEを有効にすることなく日本語で書かれた文字の位置に移動できます。漢字は知りません。

## 例
`f`を押した後に`<C-k>a5`と打つことで「あ」に位置に移動できます。

- `<C-k>a5` あ
- `<C-k>A6` ア
- `<C-k>n5` ん
- `<C-k>ta` た
- `<C-k>Se` セ
- `<C-k>tU` っ
- `<C-k>yA` ゃ
OpenStackでcpu世代の異なるハードウェアを使うときの設定


この記事は、[MicroAd Advent Calendar 2018](https://qiita.com/advent-calendar/2018/microad)の15日目の記事です。

## はじめに
OpenStackでCPUの世代が異なるハードウェアを使う場合に必要な設定のメモです

OpenStackをある程度の規模・サイジングをしてから導入する場合、CPU世代が異なるHWを使うことは稀かと思います。
ただ、どうしても異なるCPU世代のHWを追加する必要がある場合や、ミニマムのハードウェア構成で構築するなどの場合はコンピュートホストで事前に設定を投入しておくと安心です。

## 動作環境
OpenStack（Newton）を使った環境でのメモですが、
基本的には他でも一緒だと思います。

## 起きる問題
コンピュートホストのCPU世代が異なるとき、インスタンスを新しい世代のCPUから古い世代のCPUにライブマイグレーションしようとすると、
エラーが発生してライブマイグレーションができません。

但し、停止を伴うマイグレーション、古いCPU世代から新しいCPU世代へのライブマイグレーションは可能です

## 回避方法
nova-computeの設定を変更して、インスタンスに見せるCPU世代を隠蔽することで回避

### 設定する内容
コンピュートホストのnova.confに以下の設定を投入します。

```nova.conf
[libvirt]
cpu_mode = custom
cpu_model = Broadwell
```
cpu_modelは、/usr/share/libvirt/cpu_map.xmlにある`model name`を設定します。
この設定を投入したら、nova-computeサービスを再起動して反映します。

### 注意点
この設定はインスタンスを起動する前に設定しておく必要があります
あとから変更する場合は、インスタンスを停止して再起動する必要があります
その場合、インスタンスのOS上からリブートや、OpenStackのコントローラーからソフトリセットでの再起動ではなく、
インスタンスを完全に停止することが必要です。
またこの設定により新しい世代の**CPU性能をフルに使えない**場合が発生します。

## 確認
設定が反映されているか確認する方法は、インスタンス上から`/proc/cpuinfo`を参照して
`model name`が設定したものになっていれば問題なし
もしくは、コンピュートホスト上で`ps`コマンドでqemuプロセス確認したときに
`-cpu XXXXX`と意図CPUモデルになっていればOK

## まとめ
個人的には仮想基盤で使用するCPUは、世代を合わせておいたほうが得策と思っています。
とはいえ、ハードウェアをあとから追加調達するケースでは、CPU世代が変わってしまうケースも少なくないので、
予めこの設定を入れておくことが良いと思いました。
Incoming Webhooksを使ってSlackチャンネルに投稿してみる

### 1. 投稿用のチャンネルを作成

- Slackを開いて投稿用のSlackチャンネルを作成

![01_1_1.png](https://qiita-image-store.s3.amazonaws.com/0/239358/db81a5eb-8e34-9e8f-d61e-c4c088834a3e.png)
とりあえずsample_roomという名前で作った。

### 2. IncomingWebhooks用のSlackアプリを作成

- 以下のリンクをクリックする。(ログインしていない場合はログインする)

　　[https://api.slack.com/apps](https://api.slack.com/apps)

- [Create an App]をクリック(既に作成済みの場合は[Create New App]をクリック)

- Slackアプリを作成するための情報を入力して[Create App]をクリックする。

　　[App Name] 任意のアプリ名(とりあえずIncomingWebhooksSampleという名前にしてみた)
　　[Development Slack Workspace] ワークスペース名を選択

![01_2.png](https://qiita-image-store.s3.amazonaws.com/0/239358/084a1e97-417d-f06e-23c0-80b47758f76c.png)

- 左側にあるメニューより[Incoming Webhooks]をクリックし、[Activate Incming Webhooks]をOffからOnに変更する。

- [Add New Webhook to Workspace]ボタンを押す。

- 投稿先(投稿したいチャンネル名)を選択して[許可する]を押す。

![01_3.png](https://qiita-image-store.s3.amazonaws.com/0/239358/dbafa90a-268a-83c6-b98b-5fc1546e30a9.png)

- [Webhook URL]にIncomingWebhooks用のURLが追加されるので控えておく。

### 3. Slackに投稿してみる

- curlを使ってsample_roomチャンネルにhogehogeという言葉を投稿。

```
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"hogehoge"}' <控えたIncomingWebhooksのURLを貼る>
```

- 結果
![01_4.png](https://qiita-image-store.s3.amazonaws.com/0/239358/025904e9-2928-9f13-8465-2001c8631d66.png)
[Perl]RPC::XML::Clientモジュール

Perlモジュールガイドに書いてない闇のモジュールで調べるのに苦戦したのでメモ。

`RPC::XML` の派生系です。 https://metacpan.org/pod/RPC::XML::Client

```perl

require RPC::XML;
require RPC::XML::Client;
 
$cli = RPC::XML::Client->new('http://www.localhost.net/RPCSERV');
$resp = $cli->send_request('system.listMethods');
 
print ref $resp ? join(', ', @{$resp->value}) : "Error: $resp";
```

* `RPC::XML::Client->new( URL )` で$clientを作成 
* `$client->send_request( APIに渡すパラメーター )` でAPIに送信
* `$resp` にレスポンス結果が入っている

という形になります。Dumpしてみるとこんな感じです。

```
$VAR1 = bless( {
                 'mike' => [
                             bless( {
                                      'A' => bless( do{\(my $o = 123)}, 'RPC::XML::int' ),
                                      'B' => bless( do{\(my $o = 456)}, 'RPC::XML::int' ),
                                      'C' => bless( do{\(my $o = 789)}, 'RPC::XML::int' )
                                    }, 'RPC::XML::struct' )
                           ]
               }, 'RPC::XML::request' );
```

XML形式にしたい場合、追加で以下を指定しましょう。

```perl

# XML化
$res->as_string();

# responseヘッダにxml形式であると明示
$c->res->content_type('text/xml');

# output
$c->res->output($res->as_string());
```
git ブランチ作成関係と設定ファイルのメモ

#ローカルのブランチからブランチを作成する方法

#ブランチを作りたいgitのディレクトリに入る
cd ディレクトリパス

#ブランチの一覧を見る
```
git branch -a
```

#ブランチを作る元のブランチに切り替える
```
git checkout master
```

#ブランチを作成
```
git checkout -b develop
git checkout -b 作成するブランチ名
```

#ブランチの一覧を見る
```
git branch -a

実行結果
* develop
  master
  remotes/origin/master
```

#ブランチをリモートに登録
git push -u origin 作成したブランチ名

#リモートブランチから作る方法
#リモートブランチからローカルブランチを作成
```
git checkout -b ローカルに作成するブランチ名 origin/作成元のリモートのブランチ名
```

#ブランチの一覧を見る
```
git branch -a
```
#gitでpushできない時に試したこと(githubでpushできない時などは、branchが違う可能性があるのでブランチを切り替えてpushするか作成したbranchでpushしてあげる。)
```
git push -u origin develop
```

https://bacchi.me/git/git-push-troubleshooting/

#ブランチをリモートに登録
```
git push -u origin 作成したブランチ名
```
#Gitの設定ファイルの種類と場所(system,global,local)
| 種類       |       対象範囲 |    場所    | 備考|
|:-----------------|------------------:|:------------------:|:------------------:|
| system|システム全体（全ユーザーの全リポジトリ）|        /etc/gitconfig|
| global|該当ユーザーの全リポジトリ|       ~/.gitconfig|ホーム直下|
| local| 該当リポジトリ| repository/.git/config|リポジトリの.git直下|

#設定項目の確認
```
git config <name>
```

**nameに値する例**
- color.ui : Gitの出力の色分け（通常はautoと設定）
- core.editor : コミットメッセージなどの編集で用いるエディタ
- user.name : ユーザー名
- user.email : Eメール

設定の一覧表示
git config --local <name>
git config --global <name>
git config --system <name>

#設定を上書きする方法

```
git config --global user.email example@example.com(value値)
```

#設定ファイルをエディタで直接編集(複数修正がある時など)
```
git config -e #ローカルの設定を変更
git config --global -e
git config --system -e
```
vCenter Server Appliance[VCSA]のマイナーバージョンアップ手順

VCSAのマイナーバージョンアップ(パッチ)手順です。

今回は6.7.0.0から6.7.0.2にバージョンアップしました。

## 1.vCenterのAppliance Managementにログイン
![vcsa-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/251778/0247d143-7c81-a916-f145-1705a2f311e5.png)
<i>https://[FQDN or IP:5480]</i>  
でログイン画面に進めます。

## 2.事前準備
### 2-1.データのバックアップ
![vcsa-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/251778/f9dae3cb-f808-3e44-f369-eda2a76f5557.png)
バックアップ画面に進み、事前にデータのバックアップを取得します。


## 3.インストール
![vcsa-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/251778/7a273f56-1b80-5b54-c374-aef55c99387a.png)

右上の更新を確認をクリックし最新情報を確認します。
<b>ステージングしてインストール</b>をクリックするとインストールされるはずが、どうやら問題があるようでインストールに失敗しました。  

<span style="color: #ff5252">※ステージングだけにするとインストール直前でストップしてくれるので好きなときに短い時間でインストールできるようになります。  </span>

成功した人はこれにて作業完了です。

失敗した人は以下のワークアラウンドを参照ください。



## 4.ワークアラウンド
### 4-1 ISOの手動ダウンロード
以下のサイトから該当のISOをダウンロードします。

https://my.vmware.com/ja/group/vmware/patch

これをデータストア等にアップロードするなどし、vCenterの仮想マシンへマウントしてください。  

### 4-2 vCenterへSSHで接続
rootユーザでvCenterに接続します。  

### 4-3 コマンドでインストール

#### 4-3-1.マウントされているISO経由でステージング  
<i>software-packages stage --iso</i>

利用規約てきなものが表示されるのでエンターでスクロールしていきます。  
最後に以下の質問が表示されるので同意する場合はyesと入力します。  
> Do you accept the terms and conditions?  [yes/no] 

#### 4-3-2.ステージングされたISOの確認  
<i>software-packages list --staged  </i>

#### 4-3-3.インストール  
<i>software-packages install --staged  </i>

以下のような感じでインストールされます。  
大体15分程度かかりました。  
> Command> software-packages install --staged
>  [2018-12-] : Validating software update payload
>  [2018-12-] : Validation successful
>  [2018-12-] : Copying software packages
>  [2018-12-] : ISO mounted successfully
> 124/124
>  [2018-12-] : ISO unmounted successfully
>  [2018-12-] : Running test transaction ....
>  [2018-12-] : Running pre-install script.....
>  [2018-12-] : Upgrading software packages ....
>  [2018-12-] : Setting appliance version to 6.7.0.20000 build 10244745
>  [2018-12-] : Running pre-patch script.....
>  [2018-12-] : Running post-patch script.....
>  [2018-12-] : Packages upgraded successfully, Reboot is required to complete the installation.

インストールが終了するまで通信断はありませんでした。
最後にvCenterを再起動すればインストール完了です。

### 4.懸念点
1.VCHA状態だとエラーになる。  
VCHAの状態でインストールコマンドを叩くと以下のエラーが返ってきます。  
  
> Installing patch update is allowed only on Passive or Witness node when the cluster is running in maintenance mode. Err: b''  

エラー内容的にVCHAをメンテナンスモードにしてパッシブノードにならパッチ当てられるような気がするのですがインストールに失敗しました。  
そこまでしてVCHA状態をキープしておく必要も無かったので今回はVCHAを解除した状態で実施しました。  
インストール後は問題なくVCHAが組めたので、一旦VCHAを削除してバージョンアップ後に最後組み直すのが今のところ一番安定していて簡単だと思われます。  
  
便利に数クリックでvCenterのバージョンアップができるようになったのかと思っていたのですが、思ったよりきちんと動かない印象でした。  
大した手順では無いですが参考になれば幸いです。
語尾にゲスをつけて返すslack bot(enebular + Firebase)

# 出オチ

![22.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/80bd2ffd-5d14-2ca0-8dfd-0262d6e63201.png)


***うわああああああ・・・・・***


# という夢だったとさ

enebularを使って、語尾にゲスをつけて返すbotを作ってみました。
正規表現が甘くて言葉遣いが甘いところも可愛いところ。

![24.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/3350797b-7344-f327-0fc7-72928085afa5.png)



# つくりかた

フローの全体像はこのようになっています。
![23.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/70a192de-86f8-15b5-60d8-cfa43f41f9b1.png)


## Slack関連ノード

### Slack Bot In
Bot API Tokenが必要であったため、
以下を参考にしてレガシートークンを取得しました。

Slack APIのTokenの取得・場所
https://qiita.com/ykhirao/items/0d6b9f4a0cc626884dbb



### Slack
こちらはWebhook用のURLを取得して投入しています。
SlackのWebhook URL取得手順
https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008



## firebase関連ノード
firebaseの初期設定はこちらのブログを参考にしました。

M5StackとFirebaseを使ってenebularとつないでみよう
https://blog.enebular.com/firebase/m5stack-firebase-enebular-collaboration/


### firebase modify
Child Pathは任意です。次の、firebase.onと合わせます。

![26.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/d9d247ea-9442-fdbb-2ea2-d886884590f6.png)


### firebase.on()
Child Pathは先ほどのfirebase modifyと合わせる形で。
event typeはchild_addにします。
![27.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/8717313b-57c8-c95c-e6be-67e4d65997b9.png)


## その他ノード

### Switchノード
冒頭の無限ループを回避するためにつけたノードです。
すでにゲス化したメッセージはスルーしてdebugノードに放り投げます。

![28.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/ef7caaa5-cb20-28ab-338a-e733696e6088.png)


### Changeノード
文字列をゲス化するためのノードです。

![29.PNG](https://qiita-image-store.s3.amazonaws.com/0/60109/15db1e5a-3f8e-a0f4-3437-eeb2043753df.png)


### debugノード
そのまま繋げるだけで機能します。


# そんなこんなで
enebularはライトにNode-REDで遊べていいですね。

ちなみに、冒頭のゲスループは、
投稿を拾ってゲス化して投稿⇒botのその投稿を拾ってさらにゲス化⇒botのその投稿を拾って・・・
のループにより起きました。
slack botを作るときは無限ループにご注意ください。
WebRTCで音声ミックス

#agora.ioのWebRTC SDKで音声ミックスを実装
[Githubに公開しています](https://github.com/fu-jimoto/AgoraIO-AudioMixing)

##音声ミックスの使い所
・カラオケ
・教材用

##作成するアプリ
・マイクの音声とオンライン上の音楽ファイルをmixして配信

##開発環境
Chrome 85.0.4183.83
AgoraVideoSDK for Web 3.1.2

##使用するAPI
```javascript
startAudioMixing(options: object, callback: function): void
```
[公式ドキュメント](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.stream.html#startaudiomixing)
##実装内容
ボタンクリックで音楽ファイルのmix開始。

```javascript
function startAudioMixing(){
  localStream.startAudioMixing({filePath:"/path/to/file.mp3",cycle:1,playTime:0,loop:false,replace:false},function (err) {
    console.log("audiomix err:"+err);
  });
}
```

##画面
ビデオ通話画面にボタンが付いただけですね。。。
![スクリーンショット 0030-12-04 14.43.11.png](https://qiita-image-store.s3.amazonaws.com/0/300377/02f45838-a7ad-5d11-d9a3-36dc894b5e84.png)

##補足
今回はWebSDKでの紹介でしたが、Native用のSDKでも同様の実装が可能です。

##関連リンク
・[音声をミックスして配信できますか？](https://vcube-support.zendesk.com/hc/ja/articles/900002433726)
・[startAudioMixingの音声ソースでオンラインファイルを利用する際のプロトコルは何ですか？](https://vcube-support.zendesk.com/hc/ja/articles/360037143632)
・[Android 10でstartAudioMixing APIを利用して音楽を再生できないのはなぜですか？](https://vcube-support.zendesk.com/hc/ja/articles/900002433826)


#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=733c43a501aa33469908)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=733c43a501aa33469908)
ExoPlayerでHLSライブストリーミングを再生しているとBehindLiveWindowExceptionが出て止まる

## 原因

[issue](https://github.com/google/ExoPlayer/issues/1074)にも書かれていた。
HLSのプレイリスト(m3u8)およびチャンク(tsとか)は定期的にサーバー側で更新されており、ライブストリームの場合は古くなったチャンクはアクセスできなくなることがある(サーバー側の実装によるけど)。
クライアント～サーバー間に十分な帯域があれば問題ないが、帯域が不足していてクライアント側でバッファリングの時間が発生するとクライアント～サーバー間の時差が大きくなり、それが一定量を超えるとクライアントが再生しようとするチャンクがサーバーからなくなってしまう。するとBehindLiveWindowExceptionが発生する。

## 対応方法

`ExoPlayer.addListener()`でExoPlayerの状態を監視し、BehindLiveWindowExceptionが発生したら再度`ExoPlayer.prepare()`を実行して再生を継続する。

もちろん、再生不可能なチャンクがあるので何秒間か再生できない時間ができますが、一応再生を継続することができます。アプリケーションによっては必要に応じてバッファリング状態を示すダイアログを出したりすると良いと思います。
Qiitaはじめました

# テスト記事

UnityのC#プログラムを書いていくつもりですヽ(・ω・*)

いろいろテストしておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/322674/ce137643-c03a-544c-883e-7b83fb4f7420.png)

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test : MonoBehaviour {

	private int a;

	void Start () {
		a = 0;
	}

	void Update () {
	}
```

ほっほおー