OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue.js】ディレクティブ "v-for"の謎(解決済)

#状況
Vue.jsの基礎学習中に色々コードを書き変えた際に偶然出会ったエラー

##事象
・以下の"v-for"の基本型を作り、連続処理を学習中

```html:index.html
<div id = "app">
  <ol>
    <li v-for="color in colors">{{ color }}</li>
  </ol>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="main.js"></script>

```
```js:main.js
var app = new Vue({
  el:"#app",
  data:{
    colors:["Red", "Green", "Blue"]
  }
})
```

結果：以下の通り正しく表示。よくあるv-forディレクトリの例文です。
![Document - Google Chrome 2020_12_09 1_57_16 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/c775099d-02ca-f8b7-8a92-e89fe5c89490.png)


・基本形ができたところで、構文の理解を深めるために色々とコードを変更していました。例えば、、、
<パターン1>

```html:index.html
<div id = "app">
  <ol>
    <li v-for="c in colors">{{ c }}</li>  <!-- v-forの値"color"を"c"に変更、マスタッシュ構文内も"color"を"c"に変更 -->
  </ol>
</div>
```


```js:main.js
//main.jsは上記と同じ
```

結果：正しく表示されます。
![Document - Google Chrome 2020_12_09 1_57_16 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/c775099d-02ca-f8b7-8a92-e89fe5c89490.png)

<パターン2>

```html:index.html
<div id = "app">
  <ol>
    <li v-for="c in colors">{{ c }}</li>  <!-- v-forの値"color"を"c"に、マスタッシュ構文内も"cに、keyも"colors"を"co"に変更 -->
  </ol>
</div>
```

```js:main.js
var app = new Vue({
  el:"#app",
  data:{
    co:["Red", "Green", "Blue"]  //プロパティ名"colors"を"co"に変更
  }
})
```

結果：雑な記述ですがこちらも正しく表示されました。
![Document - Google Chrome 2020_12_09 1_57_16 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/c775099d-02ca-f8b7-8a92-e89fe5c89490.png)

・ここからが本題です。
　ふとindex.htmlのv-for内の値"color"を"try"に変更
<パターン3>

```html:index.html
<div id = "app">
  <ol>
    <li v-for="try in colors">{{ try }}</li>  <!-- v-forの値"color"を"c"に、key"colors"を"co"に変更 -->
  </ol>
</div>
```

```js:main.js
// main.jsは基本形のまま
var app = new Vue({
  el:"#app",
  data:{
    colors:["Red", "Green", "Blue"]
  }
})
```

結果：**表示されません。。。**
　　「ん？」となり、原因を調べることに。

##原因

恐らく"try"を入力したことで、**コード上では「JavaScript上のtry文を作ろう！」とスタンバイしていること**が原因かと思われます。

try文では本来その後にcatchブロックやfinallyブロックが必要で、このブロックがないままRunしているので、エラーが発生しているのかと思います。
[try...catch構文(MDN)](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/try...catch#Syntax)

ふと頭に浮かんだ"try"の記述が偶然構文の一つであったとは。。。


##最後に
今回学んだコトとして以下3点になります
・構文を色々と変更してみると**想定外の挙動をする**ことがある
・その想定外の挙動の原因を突き止めた結果、今回のように自分にとって**新しい構文と出会うことがある**
・この一連の作業が少し結論を導くのに時間がかかりましたが、**楽しさを感じた自分がいる、ということに気づいた**

以上、私が経験したエラーでした！
最後まで読んでいただきありがとうございました。
ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD


```
mysql> CHANGE MASTER TO MASTER_HOST='10.146.0.18',
    -> MASTER_USER='rpl_user',
    -> MASTER_PASSWORD='password',
    -> MASTER_LOG_FILE='mysql-bin.000091',
    -> MASTER_LOG_POS=1372;
ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD FOR
 CHANNEL '' first.
```

というエラーが出たので、

```
mysql> STOP SLAVE;

mysql> CHANGE MASTER TO MASTER_HOST='10.146.0.18',
    -> MASTER_USER='rpl_user',
    -> MASTER_PASSWORD='password',
    -> MASTER_LOG_FILE='mysql-bin.000091',
    -> MASTER_LOG_POS=1372;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> START SLAVE;

```

と対応した。
#lesson 2 tableau public で100万行以上（エクセルでは無理）のオープンデータを公開 viz の削除

# 作成したviz(ビズ）を削除する。

練習中にはviz をアップしたり、削除したりします。そこで、viz の削除をしてみましょう。

[この動画](https://youtu.be/XRJpfbRWWak)をご覧ください。
Nginx 

# ベーシック認証
```
server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html index.htm;

    location / {
        auth_basic "Basic Ninsyo";                   # 認証時に表示されるメッセージ
        auth_basic_user_file /etc/nginx/.htpasswd; # .htpasswdファイルのパス
    }
}
```
俺たちはなぜアドベントカレンダーを書くのか

[ちゅらデータ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/churadata) の13日目です。

まだ12月9日だけど細けぇことはいいんだよ。

創業4年目に突入したちゅらデータ社では社員も増えてきたので企業アドベントカレンダーを作成してみた。しかし社内で「アドベントカレンダー書こうぜ」と告知しても集まりが悪い。一人の社員に「なぜアドベントカレンダーを書かないんですか？」と訊くと、返ってきた答えは**「なぜアドベントカレンダーを書くんですか？」**だった。

たしかに。

自分は前職が Web 企業で同僚も Web に長くいる人が多かったので、アドベントカレンダーのような文化は当たり前のものと思っていたし特に疑うことがなかった。しかしちゅらデータの社員は多様な業種,業界から集まってきており、いままで狭い常識の中に囚われていたのだなと痛感したのであった。

たしかに、この文化に馴染みのない人に「なぜそれに参加するか」を簡潔に説明できないな、と思った。

せっかくなので「アドベントカレンダー書こうよ〜」と勧めたいときに「これを読んでみてくれ」と紹介できるような記事をまとめておこうと思った次第。

前置きしておくと、以下の内容は「**自分は**こういう理由でアドベントカレンダーを書く」という話であって「だから皆そうするべきだ」と主張するものではない。念の為。

## アドベントカレンダーとは

アドベントカレンダーはもともとクリスマスまでの日数を数えるための風習だったのが転じて、IT 業界では「12月に特定のテーマで皆でブログを書くイベント」となっている。[^wiki] 歴史を遡ると2000年に英語圏の Perl コミュニティで始まって、日本では2008年から始まって広まっていったらしい。[^qiitazine]

日本のアドベントカレンダーの Web サービスとしては [Qiita](https://qiita.com/advent-calendar) と [Adventar](https://adventar.org) が2大巨頭で、Qiita が技術系、Adventar が何でもアリという棲み分けになっている気がする。

[^wiki]: [アドベントカレンダー \- Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC)
[^qiitazine]: [アドベントカレンダーに関するアレコレ、QiitaアドベントカレンダーとAdventarの中の人に聞きました。 \- Qiita Zine](https://zine.qiita.com/products/adventcalendar/)

## なぜアドベントカレンダーを書くか

### 1. 楽しいから

なぜかと言われると一番の理由は**「そういうお祭りだから」「楽しいから」**となりそう。ハロウィンに渋谷で仮装している人に「なぜ仮装してるの」って訊くのと同じ感じ。そういうイベントであって、乗っかって楽しいなら乗っかればよい。何も難しい話ではない。

しかしそれを言ってしまうと興味ない人は「興味ないので参加しません」で終わってしまう。自分もハロウィン興味ないし。だから「アドベントカレンダー書こうよ〜」と言えるような理由をもう少し考えていきたい。

### 2. 会社の広報になるから (企業アドベントカレンダーの場合)

それはそうなんだけど、広報や採用の担当者が考えるメリットであって、そのへんに責任がない社員からすると別に知ったこっちゃない。あとそれだけだと企業アドベントカレンダー以外に参加する理由にはならない。

### 3. アウトプットするきっかけを作るため

個人にとってメリットがある話といえばこれ。

自分の持っている技術や考えをアウトプットするお祭り。普段ブログとかを書かない人でも「ちょっと書いてみようかな」と思わせるようなハードルを下げる効果はある。それによってアウトプットの習慣が身につくための一助となれば、その人自身にとってもインターネットにとっても良い影響があるだろう。

しかし**「アウトプットする習慣が身につくことは個人にとってメリットである」**は本当か？

## なぜアウトプットするか

自分は Qiita で 150 記事書いて 3700 Contribution している (2020年12月時点) ので、「そこそこ書いている方」といっても怒られはしない気がする。そんな自分が「なぜ書くか」というと、理由はいくつもある気がする。

### 1. 備忘録になるから

自分が技術記事を書く理由の8割はこれ。

半年後,1年後に「あのときアレどうやったっけ」となったときにちゃんとまとめてあると本当に便利。

半年後の自分は他人なので、他人が読んでも理解できる程度にはちゃんと書く必要がある。そこまでちゃんと書くのであればインターネットに放流してしまったほうがよい。

### 2. 理解が深まるから

技術記事をちゃんとまとめようとすると「ここ厳密にはどうなってたっけ」とか「ここ実はよくわかっていないな」という箇所が発生して、ドキュメントを読み漁ったりして調べる作業が発生する。

手間なのは間違いないけど、そういう作業が自分の地盤を固めていっているような気がしなくもない。

### 3. まとめる力がつくから

「議事録をまとめられる」や「伝わる資料が書ける」といったスキルは、少なくとも IT 業界では必須と言っても過言ではないが、そういう基礎的なスキルは勝手に身につくものではなくて「やってみてフィードバックをもらう」を繰り返し行う必要がある。文章を書くことはそういった「まとめる力」の訓練になる。

特に「業務で得た知見をインターネットに書く」となると業務ドメインの情報はマスクする必要があり、「何を書く必要があって何を書いてはいけないか」を意識して内容を構成していくことは訓練として極めて有効だと思う。

### 4. ポートフォリオになるから

GitHub などもそうだけど、アウトプットが公開されていると「自分はこれくらいの技術力があります」という証明になる。転職活動の際に「わたしは Python ができます」と言うよりも Python で書いたリポジトリや Python について書いた技術記事を読んでもらったほうが伝わるに決まっている。転職活動したことないから知らんけど。

### 5. 誤りを指摘してもらえるから

技術記事をインターネットに公開すると見知らぬ人から「それは厳密にはこうで」とか「その情報は少し古くて」とか「こういうやりかたもあって」とかコメントを貰えることがあって、学びになる。

しかしあくまで副次的な効果ではあって、あまり期待してはいけない。

### 6. 知らない誰かの役に立てるといいから

こう言えるとカッコいいと思うけど、ぶっちゃけ自分はあまりそこ気にしていないし、少なくともそれが書くモチベーションになっているわけではない。

Qiita で LGTM がたくさんついてデイリートレンドに載ると承認欲求が満たされはする。

## まとめ

アウトプットするのは良いことだし、アドベントカレンダーは楽しい文化だと思うよ。
学習の備忘録(Macターミナル操作方法:Linuxコマンド)

###Macのターミナルの操作方法(Linuxコマンド)

####・pwdコマンド

```bash
# カレントディレクトリのパスを表示する
% pwd
# 下記のような出力結果。具体値はカレントディレクトリにより変わる。
/Users/ユーザ名/Desktop/sample
```

####・lsコマンド
カレントディレクトリ直下にあるディレクトリやファイル名が一覧で表示される

```bash
# カレントディレクトリの中身を一覧表示する
% ls

# 指定したディレクトリの中身を一覧表示する
% ls [中身を表示したいディレクトリのパス]
```
####・cdコマンド
カレントディレクトリを移動したいときに使用。
cdだけ入力した場合はホームディレクトリに移動

```bash
# 指定したディレクトリへ移動
% cd [移動したいディレクトリのパス]

# ホームディレクトリへ移動
% cd

# ルートディレクトリに移動
% cd /
```

ど忘れしたときの振り返りようです！！
PythonからCOMオブジェクトを扱う / HoudiniからPhotoshopをちょっと操作する

この記事は[Takumi Akashiro ひとり Advent Calendar 2020](https://qiita.com/advent-calendar/2020/takumi_akashiro "ひとり Advent Calendar 2020")の10日目の記事です。

今日はHoudiniからPhotoshopを起動して操作します。
興味のある方はどうぞ。

## 始めに

pythonでCOMオブジェクトを使いたい瞬間はありませんか？
ありませんね。エクセルとか操作したくなったら、pyWin32とか使うし……
いやでも、pyWin32ってDCCツールに組み込みずらいし……と嘆いている方に朗報です！

簡単にCOMオブジェクトを扱える拡張モジュールがあるんです！
その名も`comtypes`！

---

[comtypes · PyPI](https://pypi.org/project/comtypes/ "comtypes · PyPI")
> comtypes は、ctypes FFI ライブラリをベースにした Python の軽量な COM パッケージで、
10000 行以下のコードで構成されています (テストはカウントされていません)。

ビルドされたバイナリも使っておらず、依存関係も標準モジュール以外はないので、
DCCツールにも組み込みやすいのもいいですね。

## 通常の導入方法
いつも通り`pip install comtypes`ですね。

## MayaとかHoudiniとか
`pip install -t <pythonpath> comtypes`
で適当なパスが通ったディレクトリにインストールします。

無法ですが、Zipを落としてきて、展開して適切なフォルダを適当に投げ入れても動きます。
というか、今後pipで管理する予定が無いなら、不要なegg-infoとかbinフォルダはいらないので、
pipを使わずに適当に入れたほうが無駄なファイルは減りますね。

3系は元の構文が2系ベースで書かれていて、そのままだとSyntaxErrorで動かないので、
pipを通すか自前で2to3をかける必要がありました。

無法なことをやるなら、まあsetup.pyには目を通しておいたほうがいいとは思いますね。

## 試す
ではHoudiniからPhotoshopをCOMオブジェクト経由で起動し、適当なファイルを保存するスクリプトを試してみます。

```python
#!python
# encoding:utf-8

import comtypes.client
import gc

def main():
    photoshop = comtypes.client.CreateObject("Photoshop.Application")
    document = photoshop.Documents.Add()

    color = comtypes.client.CreateObject("Photoshop.SolidColor")
    color.RGB.Red = 255
    color.RGB.Green = 0
    color.RGB.Blue = 0

    document.Selection.SelectAll()
    document.Selection.Fill(color)

    document.SaveAs("D:\COMControl_Sample.psd")
    photoshop.Quit()

    # 関数が終了すればオブジェクトが破棄されて、
    # 解放されると思うが、念のために明示的にガベコレする。
    del photoshop, document, color
    gc.collect()


main()
```

![10_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294868/36f5a304-9a44-ce01-0552-2eaeeeaf0a4a.gif)

出来ましたね！DドライブにPSDファイルができてます。

## 締め

最初はCOMオブジェクトを簡単に使える拡張モジュールを紹介するつもりだったんですが、
調べて記事に起こしていくうちに、思った以上に有用になってしまって自分でもびっくりしています。

……PhotoshopってCOMオブジェクト経由でコントロールできるんですね…初めて知ったわ…

## 追記

でもPhotoshopをPythonから操作するなら、正直に`photoshop-python-api`を使うほうがいいかもですね……
[photoshop-python-api · PyPI](https://pypi.org/project/photoshop-python-api/ "photoshop-python-api · PyPI")

こっちもrequirementsを読む限りはcomtypesを使ってるみたいですん。
ChromebookでGAS開発用にclasp入れる備忘録

Node.jsも何も知らないのに調べて出てきた話がつよつよエンジニアたちの構築済環境の話でつらかったので自分の環境でやったことをメモ。
注釈は参考にしたサイト/記事なので、全然無関係で頓珍漢なことやってる可能性はある。

**追記: あまりにも頓珍漢なことやってたので修正しました。**

#基本手順
公式にある(GASの[ヘルプ]→[ローカルで開発]にある)し、Qiitaで日本語で説明してくださっている方も居る。

[Command Line Interface using clasp](https://developers.google.com/apps-script/guides/clasp)

[GAS のGoogle謹製CLIツール clasp](https://qiita.com/HeRo/items/4e65dcc82783b2766c03)

問題はLinuxの仮想環境とNode.js入れるところ。

#Linuxの仮想環境を使えるようにする
設定画面の左にあるメニュー1番下のやつ。
![Screenshot 2020-12-08 at 15.11.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519665/7aef20a1-eb6e-17c0-5e54-2673bee241f4.png)
オンにして、構築処理に5分くらい掛かるが特に難しい点もなかった。
ユーザー名と、ディスク容量いくつ使うかくらいしか聞かれない。
ディスク容量は推奨サイズ(7.5GB)にした。

Linuxを有効にするとコマンドラインが勝手に起動するが、とりあえずシェルフに固定しといた方が良い。
間違えて閉じちゃった場合はランチャーから「ターミナル」で検索すると出るはず。

#CLIで必要なものをインストール
Claspを入れるにはNode.jsの環境を構築しなければならない。
下記のサイトを参考に`nvm`→`nodejs`→`npm`の順に入れていく。

[node.jsとnpmとnvmをインストールしよう。node.jsの環境を用意する（Mac OSX編）](https://photo-tea.com/p/17/hexo-start-kit-tools-4/)

サイトはMac OSX版だが、ChromeOS(Pixelbook)でも特に相違点は無かった。

まず`nvm`を入れる。
このコマンドは公式リポジトリにある。[^nvm-sh/nvm]

```shell:
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

#wgetを使いたい場合は下記
$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
```

`nvm`使って`nodejs`のLTSを入れる。[^nodejs]

```shell:
$ nvm install --lts --latest-npm
$ nvm alias default lts/*
```

>nvmにより、node.jsがインストールされると、npmも一緒にインストールされています。つまり、npmに関しては特に行う作業がありませんが、念のため最新バージョンにアップデートしておきましょう。

と書いてある通りバージョンは上がらなかった。

```shell:
$ npm -v
6.14.9
$ npm update -g npm
$ npm -v
6.14.9
```

ここでやっと`clasp`を入れることができる。

```shell:
$ npm install @google/clasp -g
```

以上。
ChromebookでもCLIをどんどん使っていくぞ！

[^nvm-sh/nvm]: [nvm-sh/nvm](https://github.com/nvm-sh/nvm)

[^nodejs]: [nvm(Node Version Manager)を使ってNode.jsをインストールする手順](https://qiita.com/ffggss/items/94f1c4c5d311db2ec71a#ltslong-term-support%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88)
igraphで重み付き隣接行列から重み付きグラフを生成する

igraphを用いて重み付きグラフを生成する。

```python
from igraph import *
```

重み付き隣接行列は以下で与える。

```python
adj = np.array([[1, 2, 3], [2, 2, 1], [3, 1, 5]])
```

#Graph.Adjacency
Graph.Adjacencyという関数で隣接行列からグラフを生成できる。

```python
adj = [[1, 2, 3], [2, 2, 1], [3, 1, 5]]#igraphにおいてはリストで与えないとエラーを起こしてしまう。
G = Graph.Adjacency(adj)

print(G.is_weighted())
#False
print(G.is_multiple())
#[False, False, True, False, True, True, False, True, False, True, False, False, True, True, False, False, True, True, True, True]

```
このようにうまく生成することができなかった。
この原因として、隣接行列の定義が考えられる。
頂点$i$と$j$の間に辺が1本存在するとき隣接行列の$(i, j)$成分が1と定義されている。
つまり例の隣接行列の$(1, 2)$成分の値は2であるが、それは2本の辺が頂点$1$と$2$の間に存在することを意味する。
そのため多重辺が存在するグラフを生成してしまった。

#GraphBase.Weighted_Adjacency
重み付き隣接行列を読み込む関数があった。

```python
G = GraphBase.Weighted_Adjacency(adj, mode=ADJ_UNDIRECTED)
print(G.is_multiple())
#[False, False, False, False, False, False]
```
多重辺と認識せずに読み込んでくれた。
GraphのEdge Sequenceから重みを読み込む。

```python
print(G.es['weight'])
#AttributeError: 'igraph.Graph' object has no attribute 'es'
```
このようなエラーが出力されてしまった。
うまく重み付き行列が入力されているのかわからず、少し大きな隣接行列を読み込みコミュニティ抽出を行おうとしたところうまくいかずこの関数はよくなかった。

#networkx　(解決策)
networkxで生成したグラフを保存しigraphで呼び出すことでうまくいった。
networkxで生成し、保存。

```python
G = nx.from_numpy_array(adj)
nx.write_gml(G, 'graph.gml')
```

それをigraphで呼び出す

```python
G = Graph.Read_GML('graph.gml')
print(G.es['weight'])
#[1.0, 2.0, 3.0, 2.0, 1.0, 5.0]
```
うまく実装できた。

#コミュニティ抽出
networkxでコミュニティ抽出を失敗したため、igraphで重み付きグラフの生成を始めた。
networkxでコミュニティ抽出（greedy法）を行おうとしたところ、うまく分類できなかった。
それはnetworkxにおいて重み付きのグラフが対応していなかったためである。
>Find communities in graph using Clauset-Newman-Moore greedy modularity maximization. This method currently supports the Graph class and does not consider edge weights.
引用元: [greedy_modularity_communities](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.community.modularity_max.greedy_modularity_communities.html#networkx.algorithms.community.modularity_max.greedy_modularity_communities)

networkxで用いた方法により揉み付きグラフのコミュニティ分類を行えた。

```python
txt = G.community_fastgreedy()

print(txt)
#Dendrogram, 3 elements, 2 merges
#
#2 0 1
#| | |
#| `-'
#|  | 
#`--'
```

また他の例として空手クラブの分類も行なった。
![スクリーンショット 2020-12-09 4.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330569/965adc70-4602-73da-236e-6e10c89c4416.png)

重みがない隣接行列でもうまく生成できている。
enebular-agentで何かを作る改め紹介＆使い方

enebular-agentを使って作ったアイディアを書くつもりでしたが、完成が間に合わなかったため、代わりにenebular-agentの紹介&使い方を書きます。

# そもそもenebular-agentとは
Linux上で動作するIoT向けのエージェントソフトです。動作保証がされている環境は[オフィシャルドキュメント](docs.enebular.com/ja/Other/Support.html#enebular-agent)に書いてありますが、enebular-agentは[オープンソース](github.com/enebular/enebular-runtime-agent)となっているので、他のLinux環境でも多少のカスタマイズで動作させることも可能だと思います。

## 何ができる？
enebularで管理されているアセット（フロー、ファイル、AIモデル）をデプロイすることができます。
そもそもIoT向けのエージェントソフトなので、最初のインストール以降はデバイスに触ることなくクラウドから遠隔で管理、アプリケーションの更新ができるようになっています。

## 遠隔で管理？
enebular上では、enebular-agentのステータスやログを見ることができます。さらにリモートメンテナンス機能を使うとインターネットを介してSSH接続できるようになってます。（もちろんセキュアに）

# インストール方法
enebular-agentはコマンドで自動的にインストールできるようになってます。

## インストール前に必要なもの
enebular-agentとenebularと繋ぐため、以下のいずれかのサービスを必要とします。インストール時に接続情報が必要になります。

* [AWS IoT](https://aws.amazon.com/jp/iot/)
* [Pelion](https://pelion.com/)

※AWS IoTを使用する場合は、AWSの設定を含め、enebular-agentのインストール方法を詳細に説明した記事「[enebular-agentをRaspberry Piにインストールする](https://qiita.com/jksoft/items/e007c94e7673374ddf7c)」があるのでこちらも参照下さい)

## インストールコマンド
インストールは自動ですが、インストールコマンドのオプションがちょっと複雑です。

次の例はAWS IoTを使う場合に、普通にインストールするためのコマンド例です。

```shell
wget -qO- https://enebular.com/agent-install | sudo -E bash -s -- --aws-iot-thing-name={iot thing name} --aws-access-key-id={access key id} --aws-secret-access-key={secret access key} --aws-iot-region={iot region}
```
中カッコ内はAWS IoTの接続情報に書き換えてください。`iot thing name`は他と被らなければある程度自由に決められます。インストーラーの中でこの名前を使って、AWS IoTのThingを自動的に作って、接続します。

# フローのデバッグ方法
フローはenebular上のWebフローエディタでもデバッグできますが、デバイス上でしか動作しないものはWebフローエディタではデバッグできません。基本的にデバッグする方法は2種類です。

## デバイスログでデバッグ
debugノードのオプションで`システムコンソール`にチェックを入れるとenebular上のデバイスログで確認ができます。これで処理の結果を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/fb2a7981-8b5c-a4c4-2e33-5536fcd2e3b4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/674adfb1-4f90-4a00-1ca9-d0a95f0e7b95.png)


ただし、デバイスのログは5分に1回しかアップロードされないため、リアルタイムに確認することができません。リアルタイムに確認するにはリモートモードが便利です。

## enebular editorでデバッグ
enebular editorを使うとリモートでenebular-agentのフローエディタに接続することができるリモートモードが使用できます。ただし、enebular-agentとenebular editorが動作するPCが同一のネットワーク内でないと使用できません。


リモートモードは、事前にenebular-agentが動作しているデバイス上もしくはSSH接続を行い、以下の手順でenebular-agentの動作モードを切り替える必要があります。

1.enebular-agentを一旦停止する

```
> sudo systemctl stop enebular-agent-{user名}.service 
```
※user名はenebular-agentをインストールするときにオプションで指定したユーザ名になります。指定していない場合は`enebular`です。

2.Nodejsのパスを環境変数に追加

```
> export PATH=$PATH:/home/{user名}/nodejs-v12.18.1/bin
```
※上記パスのnodejsのバージョンはenebular-agentのバージョンによって異なりますので、インストールしたバージョンに合わせて変更して下さい。

3.enebular-agentを開発者モードで起動

```
> /home/{user名}/enebular-runtime-agent/ports/awsiot/bin/enebular-awsiot-agent --dev-mode
```
※AWS IoTの場合


enebular-agentを開発者モードで起動したらenebular editorからリモートモード接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/26d0478b-4dbe-5a39-2768-75fd8e0afeab.png)
※IPアドレス選択のダイアログが表示される場合は、enebular-agentと同じネットワークを選んでください。

接続に成功すればフローエディタが表示されます。デバッグメッセージを開けばリアルタイムでdebugノードの結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/852d2b9c-35c6-d5ff-c6ef-e94aa53ce92a.png)
プログラミング学習1周目を終えて

今回が初めての投稿になる、(@KEIGO_web)です。

この記事では、未経験からwebエンジニアにジョブチェンジを目指して独学をしている私が1週間目で学んだことを備忘録として残していく記事です。

12/1~12/7の1週間の学習内容としては以下の通りです。
✅学習時間：10時間
✅学習内容：Progate/HTML・CSS初級編完了


Progate/HTML・CSS初級編で学べること
・見出しと段落の記法
・タグの使いかた
・画像の挿入の仕方
・リストの作り方
・CSSの基本記法と文字色変更の仕方
・文字の大きさと種類/背景と幅
・CSSで特定の要素に変化を適応したい場合の記述法
・HTMLの全体構造とレイアウト
・ヘッダー/フッター/メインのレイアウト・お問い合わせページ



特に学んだこと
✔︎特定の要素にCSSを適応したい場合は、クラス名を追加してCSSで記述する場合は.(ドット)selected(クラス名)のように記述する
✔︎webサイトにおけるレイアウトにおいて重要なのは(class)と(div要素)で2つによって指定される
✔︎リスト要素における黒点の削除は(list-style)プロパティを用いる
✔︎レイアウトを横並びさせたい場合は(float)プロパティを用いる
✔︎ 要素に空白を作るpaddingの上下左右の指定方法は時計回りにpx（ピクセル）を用いて記述する
✔︎paddingとmarginの違いはborderを境に内側はpadding,外側はmargin

反省点としてすでに理解して実践ですぐに応用できる技術キーワードについては復習しないようにし、効率を高めていきます。
VSCode で編集すれば仮想マシン中で動作する Web サーバでも Live Reload できるよという話

Vagrant を使うと VirtualBox で VM を立ち上げてホスト OS との間で共有フォルダの設定をするのも簡単でいいですよね.
ただ、ホストから共有フォルダ中のファイルを編集しても、VM 中で動いている Web サーバ (`webpack-dev-server` など) はファイルの更新を認識してくれなくて Live Reload できないのは難点だったりします.

**でも、VSCode を使っているなら実は割と簡単に VSCode 上での編集を Live Reload で反映できます.**

VSCode を開き、`Extensions` から `Remote Development` という拡張をインストールしてください.
この拡張は VSCode から SSH でサーバに接続し、そのサーバ上のファイルを VSCode 上で編集できるようにしてくれるという拡張です.
この拡張がインストールされると、VSCode のウィンドウの一番左下 (歯車マークの `Manage` の下) に `≶` というアイコンが表示されるようになります. 

あとは、VSCode から VM に対して SSH で接続するための鍵情報が用意できれば OK です.
Vagrant を使っている場合、シェル上で以下のようにして鍵情報を用意することができます.

```bash
$ vagrant ssh-config --host "Vagrant の VM 名" >> ~/.ssh/config
```

これにより、以下のような内容の SSH の鍵情報が `~/.ssh/config` へと追記されることになります.

```
Host Vagrant の VM名
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /path/to/vagrant/folder/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

VSCode に戻って `≶` のアイコンをクリックしてみましょう.
コマンドパレットが現れるので、その中から `Remote-SSH: Connect to Host...` をクリックしましょう.
すると、先程追記した `~/.ssh/config` の内容が自動的に読み取られ、コマンドパレットの一覧中に `"Vagrant の VM 名"` が表示されると思います.
これをクリックすると新たに VSCode のウィンドウが現れます.

この新たに表示された VSCode ウィンドウ上では選択した VM 中に既に SSH で接続されている状態となっており、`Open` や `Open Folder` をクリックするとホストのディレクトリツリーではなく VM のディレクトリツリーが表示されることになります.

あとはここから編集したいプロジェクトのディレクトリを開き、普段 VSCode を使う際と全く同じように編集して上書きすれば、VM 中で動作するサーバによってファイルの更新が検出されて Live Reload がうまく動くはずです.

VSCode 便利ですね.
ローカル環境で実行しているPower BI Desktopに対してExcelからピボットテーブルで接続する方法


## 概要
ローカル環境で実行しているPower BI Desktopにて、ローカル環境のExcelから、Analysis Servciesとして接続する方法を紹介します。Power BI（バックで起動しているAnalysis Services）のポート番号を調べ、Excelから接続します。

表形式の可視化についてはExcelのほうが使いやすい場合があり、データの内容確認時には重宝します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b5fa57d0-b9e5-5bd2-a508-88ae9a3ad223.png)


ポートの確認方法には下記がありますが、DAX Studioの利用をおすすめします。

- DAX Studioにて接続のポートを確認する方法 <- おすすめの方法
- Powershellにてポートを確認する方法


DAX Studioの利用法については下記記事をご確認ください。

- [DAX Studio利用ガイド - Qiita](https://qiita.com/ryoma-nagata/items/0a8c5327f51284aced44)


## 接続方法
### 1. Power BI Desktopにてレポートを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/237e4087-9f22-70cf-92da-061acf867365.png)


### 2. ポートの確認
#### 実施方法1. DAX Studioにて接続のポートを確認する方法
DAX Studioにてレポートに接続し、右下の表示されるポート番号（例：localhost:65205）を控えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7975369e-d2b7-d537-e8b6-035eae44a7f6.png)

#### 実施方法2. PowerSshellにてポートを確認する方法
Powershellを管理者で実行し、"msmdsrv.exe"のポート番号をひかえます。

```powershell
netstat -b -n
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e1b96dca-f963-be13-7fd1-39aea626819d.png)


### 3. Excelから接続
#### 1. Excelを起動し、"データ" -> "データの取得" -> "データベースから" -> "Analysis Servciesから"を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/811ad092-3bdf-f287-2648-a0a75fbf2cb8.png)

#### 2. "サーバー名"に"localhost:<ポート番号>(例：localhost:65205)" を入力し、"次へ"を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/bf711a34-a194-e533-bcc8-168002430df9.png)

#### 3. "次へ"を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c2db0ee0-f9c8-26da-1994-d09263e4c452.png)

#### 4. "完了"を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3f811728-7bbc-23d4-441b-9f70a0f85ebc.png)

#### 5. "OK"を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7247bfe6-38c1-e724-247f-dd3de7320490.png)

#### 6. データを取得可能であることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/722184ac-aecb-c376-aa00-ed32b26cf075.png)
Eコマースストアのドメイン権限を増やすためのSEOのヒントとコツ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/1939441c-a31a-16d3-b8de-566af5ff976f.png)

ご存知かもしれませんが、ドメインスコアが高いと、オンラインストアに初めてアクセスする顧客の信頼につながる可能性があります。 さらに、ドメイン権限は、ウェブサイトのユーザーエクスペリエンスを向上させるのにも役立ちます。これは、検索エンジンでのランキングの位置を上げる方法です。

[ここ](https://whidegroup.com/blog/increase-the-domain-authority-of-e-commerce-store/)あなたはドメイン権限を増やす方法についての完全な情報を得ることができます。

サイトのドメインオーソリティとは何ですか？

Webサイトのドメイン権限は、0〜100のスコアです。高いほど良いです。 このスコアは、ウェブサイトが検索エンジンでどれだけランク付けされているかをある程度示していると言えます。 その理由は、ドメイン権限に影響を与え、検索エンジンのランキングを向上させるいくつかの要因が同じであるためです。

これはランキング番号ではなく、Googleのランキングとも関係がないことを忘れないでください。 MOZや他のさまざまなSEO企業は、ランキングに影響を与えると予想されるすべての既知の要因を考慮に入れて、Webサイトの評価を予測する独自のツールを開発しました。 彼らはスコアを紹介して、ウェブサイトを改善してGoogleSERPで上位にランク付けするために非常にうまく使用できるようにします。 ドメインオーソリティの要因に従ってeコマースストアを最適化すると、上位にランク付けされる可能性が高くなります。

ドメイン権限は自然に増加する必要があります。 アルゴリズムはドメイン権限を高めるために操作する要因を検出できるため、このトリックはサイトに害を及ぼす可能性があります。

ドメイン権限の自然な増加は、50を超えるまでに数年かかる場合がありますが、適切に最適化すると、数か月以内に増加する可能性があります。

ただし、ドメインスコアが高いと、ユーザーはより多くのドメイン権限を持つWebサイトを信頼するため、ユーザーの関心を高めることができます。
Herokuで瞬間デプロイ(flask+python+heroku)



#はじめに

今までは**ローカル環境**でwebアプリを作っていましたが、最近になって**"自分で作ったアプリをネット公開してみたい!"**と思うようになりました。
そのために、**「無料 簡単 デプロイ」**でググって、トップに表示された**「Heroku」**を用いてアプリを運用していこうと思います。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/9bc59267-43c9-c57d-89b3-e842c0c0b3a0.png" class="img" alt="ローカル環境"> 　**→**　　<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/93eb38ac-e08a-1fe8-bdb4-3a7390065e26.png" class="img" alt="リモート環境"> 


#Herokuとは？
**「アプリケーションを実行するための環境」**
PaaS（Platform as a Service）と呼ばれる形態でサービスを利用できます。
PaaSを簡潔に言うと、**アプリの公開に必要な手順を代行サービス**です。


#Herokuを利用する前の準備 (ファイル構成など)
https://github.com/pi-to/Hello
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/da9da5e2-955a-f98b-3811-0779d5cbe4ed.png" class="img" alt="ローカル環境"><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/1fa936e7-3266-aac5-19d4-01c1660f4b22.png" class="img" alt="ローカル環境"><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/3d5e0a13-ad6d-d6d7-80b0-5c15f8fe997b.png" class="img" alt="ローカル環境">


```ファイル構成.
(any directory)
 ├app/
 │　├templates/
 │  │       └ index.html
 │  └app.py        
 │　　
 ├.DS_Store
 ├.gitignore
 ├Pipfile
 ├Pipfile.lock
 ├Procfile
 ├requirements.txt
 └run.py 
```

#HerokuにCUIで操作するために
[Getting Started on Heroku with Python]
(https://devcenter.heroku.com/articles/getting-started-with-python#set-up)

# デプロイ手順(前半)
```py
heroku login
```
```py
git clone https://github.com/pi-to/Hello.git
```
## 必要ライブラリ

```py
#pythonの軽量フレームワーク
pipenv install Flask
#Flaskで作成したアプリとHerokuのサーバーの間を繋げるもの
pipenv install Flask gunicorn
```
# デプロイ手順(後半)

```py
heroku create
```
```py
git add .
git commit -m "upgrade"
git push heroku main #左のコマンドが効かない場合は「git push heroku master」
````
```py
heroku ps:scale web=1
```
```py
heroku open
```

# 参考文献

1:[Webアプリ開発未経験者がFlaskとSQLiteとHerokuを使って1週間でサービス公開までする](https://qiita.com/kiyokiyo_kzsby/items/f8aa0bf68007e18d6882#gunicorn%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

2:[Flaskアプリをherokuにデプロイ（苦苦々）]
(https://qiita.com/atomyah/items/91196f5fda95e4b9c7a6)

3:[python初心者がDjangoのProcfileに悩まされた話]
(https://note.com/shoakkin/n/n7d98b4e4740d)

４:[pipenvとは？]
(https://rinatz.github.io/python-book/ch04-05-pipenv/)

5:[【完全版】Flaskで作ったAPIをHerokuにデプロイする手順（備忘録）]
(https://qiita.com/ahpjop/items/e333eaf304dcdd72d886)
GitHub「公式」ダークモードを適用する方法

# 設定ページに行く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237877/f52d8ad9-037f-4958-0f74-50fc9c9b5ae1.png)

# Appearanceタブに行く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237877/7cffa7e7-3df2-b925-a0d8-03261873f5a3.png)

# 「Dark」を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237877/27dbe226-d93f-1d52-f3a9-bdba248c1bd0.png)

# この記事にLGTMする。(任意)

以上です。

ついに来ました。GitHubに公式のダークモードが来ました。

https://twitter.com/github/status/1336362679506784256
Railsのredirect_toとrenderについて

### renderとは
viewだけが返される処理

### redirect_toとは
アクションを行う処理(viewも返される)


###状況

- 投稿ができるフォームとコントローラーが存在している。

##### 投稿フォーム(new.html.erb)

![スクリーンショット 2020-12-08 2.40.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616056/e6e2c114-730f-965c-3e0a-c8383eae0208.png)

##### コントローラー(posts_controller.rb)
```
class PostsController < ApplicationController

 def index
   @posts = Post.all
 end

 def new
    @post = Post.new
 end
 
 def create
   @post = Post.new(post_params)

   if @post.save
     redirect_to posts_path
   else
     render :new
   end

   def post_params
     params.require(:post).permit(:title, :content)
   end

end
```

※post.rbには`validates :title, presence: true`を設定。（タイトルが空白の時は投稿ができない）

### 解説
#### titleが空じゃなかった場合
投稿することができるので、createアクションの`if @post.save`はtrueとなり、`redirect_to posts_path`が選ばれる。`redirect_to`ではアクションが実行されるため、`posts_path`に対応するindexアクションが実行される。

#### titleが空だった場合
投稿することはできないので、createアクションの`if @post.save`はfalseとなり、`render :new`が実行される。`render`ではアクションが実行されずviewだけが返されるため、newアクションは実行されず、newアクションに対応したnew.html.erb(view)が返される。

### renderとインスタンス変数
#### 結論 renderの記述をしているアクションには、render先で記述しているアクションのインスタンス変数を持っていなければエラーが出るので注意すべき。
解説のtitleが空だった場合の例の場合ではcreateアクションの中にいて、viewだけがnew.html.erbを返している事になる。 **この場合のインスタンス変数はcreateにある`@post`が使われている。**仮にcreateに`@post`が存在しない場合に、`render :new`を返すとどうなるだろうか？
本来viewで使われている`@post`が存在しないため、`new.html.erb`が表示できずエラーとなってしまう。
Power BI Desktopにて項目を整理するフォルダー機能の利用方法について

## 概要
Power BI Destopにて、ディメンションやメジャーをフォルダーで整理する方法を共有します。"\"で区切ることで、複数階層のフォルダーに整理することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/da192eba-a7ad-f7af-8c40-29e7326916d1.png)


下記ドキュメントにおいて紹介されております。
[Power BI Desktop のメジャー - Power BI | Microsoft Docs](https://docs.microsoft.com/ja-jp/power-bi/transform-model/desktop-measures#organizing-your-measures)

## 設定手順
### 単一階層のフォルダーを設定する方法
フォルダーに格納する項目を選択後、"フォルダーの表示"にフォルダー名（例：フォルダー①）を入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/17af440f-d96b-c459-3e1e-9762623c5310.png)

### 複数階層のフォルダーを設定する方法
フォルダーに格納する項目を選択後、"フォルダーの表示"にフォルダー名（例：フォルダー①\フォルダー②）を入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2d3400ef-9b47-89e3-176f-49a227402940.png)

## その他共有
Power BIにおいても大規模データセットに対応したこともあり、下記記事で紹介されているメジャーテーブル機能と組み合わせた利用がおすすめです。
[【PowerBIメモ】メジャーテーブルを作ろう！ - Qiita](https://qiita.com/h_kobayashi1125/items/b262e786b50c99493ab0)
まるで風景の中にいるみたい。パノラマ画像表示ビューワーCTPanoramaViewがすごい。

パノラマ写真を３６０度表示できるライブラリ。一枚もののパノラマなのに、歪みが補正されてすごい臨場感。
**SceneKitの球体もしくは円筒にパノラマ写真を貼り付けてSceneカメラを回転させる原理みたい。**
いいアイデアだなあ。
![timothy-oldfield-luufnHoChRU-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/068075f8-7794-4d34-effa-43823bbf66b7.jpeg)
![Dec-09-2020 02-06-43.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/28fc7956-4062-0655-32c4-0484bd64208f.gif)



[CTPanoramaView](https://github.com/scihant/CTPanoramaView)

#使い方

CTPanoramaViewをZipでダウンロード。
プロジェクトにCTPanoramaView.swiftを追加。

使い方はUIImageViewとおなじ。

```swift

let panoramaView = CTPanoramaView(frame: view.bounds)
panoramaView.image = UIImage(named: "panorama")
view.addSubview(panoramaView)
```
あとはドラッグで写真を動かせます。

デバイスのジャイロでも動かせます。

```swift
panaromaView.controlMethod = .motion // Accelerometer & gyroscope based control
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Nuxt.jsのUniversalモードでSocket.IOを使ってみる

こんにちは。今年もこの季節がやってきました。
今年もNuxt.jsの話を書いてみます。

## 作成アプリケーションの概要
Twitter APIを利用したTweets取得APIの結果を画面にリアルタイム反映してくれるアプリです。
こんな感じです。 ※ GIFではIDとツイート内容は非表示にしています。
![画面収録-2020-12-06-22.53.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302413/748b219c-1554-042d-37f1-897fc8effb24.gif)
元々自動的にツイート取得しゴニョゴニョできないものかと思って試してみたものの一部を今回簡易的にまとめてみました。

## 環境
Nuxt.js 2.14.9
Socket.io 2.3.0
socket.io-client 2.3.1

## 前置
Socket.IO v3がリリースされていますが、この構成では動かなかったのでv2の場合の構成です。
本来の使い方ではない気がするのでネタだと思ってください。
試してみた上で**まだ検証が必要な内容**だと思いましたのでその点はご理解ください。

## 実装編

### クライアント
``` pages/index.vue
<script>
import io from 'socket.io-client'
const socket = io(process.env.SOCKET)
export default {
  data() {
    return {
      tweets: []
    }
  },
  mounted() {
    socket.on('new-tweets', tweets => {
      this.tweets = tweets
    })
  }
}
</script>
```
イベント'new-tweets'を受け取れるようにします。これにより'new-tweets'が実行される度に画面がリアルタイムに更新されます。

### Socket.IO
``` socket/index.js
const http = require('http')
const app = require('express')()
const server = http.createServer(app)
const io = require('socket.io')(server)

io.on('connection', socket => {
  console.log(`Socket ID: ${socket.id}を接続しました。`)

  socket.on('post-tweets', tweets => {
    socket.broadcast.emit('new-tweets', tweets)
    console.log(`新しいTweetsをクライアントへ送信しました。`)
  })
})

server.listen(4000)
```
'post-tweets'が実行された場合、送信元以外の接続済の全クライアントに対して'new-tweets'を実行するようにします。


### Tweets取得API

#### リクエストの例
http://localhost:3000/api/tweets?query="クリスマス"

``` api/controllers/tweets.ts
import io from 'socket.io-client'
import services from '../services'
import config from '../../nuxt.config.js'

export default {
  async search(req: any, res: any) {
    const socket = io(config.env.SOCKET)
    const query: string = req.query.query
    const result = await services.tweets.search(query)
    socket.emit('post-tweets', result)
    res.status(200).json(result)
  }
}
```
Tweets取得APIの機能は２点です。
・Tweetsの返却（今回は使ってないです。）
・'post-tweets'を実行


主な実装は以上です。
リクエスト例を参考にAPIを実行することで画面がリアルタイム更新されると思います。
これにより目的の動作をすることを確認できました。

## まとめ
動き自体は意図したものとなったものの正直怪しいためもう少し試してみたいと思います。

## ソースコード
※もし試す場合は以下が必要となりますのでご注意ください。
・Twitter APIの利用申請
・.env.example -> .envへの変更

https://github.com/hyois/nuxtjs-socketio
関数にサマリーを書こう

Advent Calendar 2020年の9日目です。
あまり書くことがないため、
ほぼ忘備録のような内容になります。

# 関数のサマリー

## 悩ましい問題

関数にサマリー(コメント)を書くことで、
コードヒントに必要なパラメータや関数のチップスを表示することができます。
コードを読めばわかりますが、ロジックを理解するには時間がかかります。
参照元に飛んだり、検索したりするのもなかなか面倒です。
コメントやGitのコミットにコメントを含ませるのも手ですが、
今回はIDEでの開発効率を高める方法をメモ代わりに残します。

## 解決策

例えば以下のようなFunctionを用意したとします。

```vb
Public Function ReturnNumber(ByVal Number As Integer)
   Dim Value As Integer = Number
   Return Value
End Function
```

**Public**の一行上にカーソルを合わせ、
「'''」と入力すれば、

```vb
''' <summary>
''' 引数の数字をシンプルに返すだけ
''' </summary>
''' <param name="Number"></param>
''' <remarks></remarks>
Public Function ReturnNumber(ByVal Number As Integer)
   Dim Value As Integer = Number
   Return Value
End Function
```

上のようにXMLが挿入されます。

このFunctionをコーディングすると、
作成したチップスが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/0c52e1ce-10eb-0277-fbba-c8f013d68d6f.png)

## まとめ

みんなもっとVB.NETを愛そう。
C#でも同様のことできるけど。


MS公式ドキュメント
[方法: ドキュメント生成のための XML コメントを挿入する](https://docs.microsoft.com/ja-jp/visualstudio/ide/reference/generate-xml-documentation-comments?view=vs-2019)
初心者がAndroidアプリを作ってみる　～レイアウトエディタの画面構成について～

#**初めに**

Androidアプリの自己学習として、シリーズ化を目指しています。
過去の記事を記載しておきますので、
Androidアプリは作ったことがないよ！
という方がいれば、以前の記事から見ていただければ幸いです。

リンク
・[初心者がAndroidアプリを作ってみる　～開発に必要なツールの設定～](https://qiita.com/t-namba/items/e9272635e9e85f25438d)
・[初心者がAndroidアプリを作ってみる　～プロジェクトの作成～](https://qiita.com/t-namba/items/69161387bee61c0187aa)
・[初心者がAndroidアプリを作ってみる　～アプリを起動する～](https://qiita.com/t-namba/items/ff24bca81be9459bd302)


はい。期間空きました！
せめてペースを維持したいなと思いつつ、さっそく進めていきます…！
今回はリハビリを兼ねてさくっと、レイアウトエディタを触っていきます。


#**レイアウトエディタ**
AndroidアプリのレイアウトはXMLを用いて作成するのですが、
Android Stadioのレイアウトエディタは、ほとんどプログラミングせずに、
簡単にレイアウトを作成することができます。

[activity_main.xml]をダブルクリックすると、レイアウトエディタでファイルが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/8ab846e6-fd3f-9431-5ced-b47e9bf5fe72.png)

画面構成ですが、大きく分けると下記の5つです。
・パレット
・コンポーネント・ツリー
・デザインエディタ
・ツールバー
・属性

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/aedcb661-77a3-1fc7-4344-1430a64247d9.png)


**パレット**
上記画面の左上がパレットです。
カテゴリ毎に部品が並んでおり、ここからボタンなどを配置することができます。

**コンポーネント・ツリー**
画面左下がコンポーネント・ツリーです。
現在配置されている部品の構成をみることができます。

**デザインエディタ**
画面中央はデザインエディタです。
左側が画面のプレビュー、右側がブループリントと呼ばれる、
画面部品どうしの配置の制約が見やすくなっている画面になります。
どちらでも編集可能です。

**ツールバー**
デザインエディタの上部にあるツール群です。
左の青いアイコンからは、「プレビューのみ表示させる」、「ブループリントのみ表示させる」、
「両方表示させる」等の表示切替が可能です。
他にも、画面の向きやサイズを変更する等の便利な機能が備わっています。

**属性**
画面右側が属性です。
選択された部品に関する詳細設計を見ることができます。

尚、レイアウトエディタはほとんどプログラミングせず、
簡単にレイアウトを作成することができるといいましたが、
画面右上にある[コード]や[Split]から、XMLで記述することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/1b82428d-abd5-c294-04fb-2a015687f9b2.png)


#**もう終わり？**
次こそは早く上げるという固い決意を抱きつつ、
ここで一旦区切ります。
記事が短くとも、期間も短く刻んでいくことが今の目標です。。。

次回はウィジェットについて取り上げていきます。
OpenWeatherMapを使用してみた

#この記事でできること
1.OpenWeatherMapを知る
2.JavascriptでのAPIの扱い方
3.天気情報を取得する

#OpenWeatherMapとは
OpenweathermapはWebやモバイルアプリケーションの開発者に、現在の天候や予測履歴を含む各種気象データの無料APIを提供するオンラインサービスである。(Wikipediaより)
![weather.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/7f4beaa8-2911-2ea2-5e2e-d7929cee200f.png)
しかしAPIのみではなく上記画像のように都市名を入力するとGUIで天候情報を確認することも可能である。

#APIを使用するための準備
1.アカウントの作成を行う。
ユーザー名、メールアドレス、パスワードを設定する
2.apiキーの取得
![weather1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/f62f8798-0617-244a-bee1-796df5349158.png)
![weather2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/c3a8fbda-a8bd-d0cc-2956-98b652fc4675.png)
3.APIの選択
多くのAPIが用意されているので選択します。
今回はCurrent Weather Dataを使用します。
![weather3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/a8635df7-bff7-7747-3627-435881cf099d.png)
#郵便番号から地域と天気を取得する
```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>json_get</title>
</head>
<body>
	<script src="jquery-3.1.0.min.js"></script>
<!--郵便番号入力フォーム-->
	<form id="form1" action="#">
		<input type="text"id="input_message" value="">
		<input type="button" onclick="func1()" value="送信">
		</form>
<!--取得した天気を表示-->
		<div id="output_message"></div>
	<script language="javascript" type="text/javascript">
	function func1() {
//郵便番号を変数post_numへ代入
	var post_num = document.getElementById("input_message").value;
//zipに郵便番号を代入
	url = `http://api.openweathermap.org/data/2.5/weather?zip=${post_num},jp&appid=apiキー`;
//取得したJSONデータを読み込む
	$.getJSON(url, (data) => {
//地域名
			console.log(`${data.name}`);
//天気
			document.getElementById("output_message").innerHTML = `${data.weather[0].main}`;

	});
	}
	</script>
</body>
</html>
```

取得したJSONデータ(横浜市西区高島の場合)

```json
{
    "coord": {
        "lon": 139.62,
        "lat": 35.46
    },
    "weather": [
        {
            "id": 803,
            "main": "Clouds",
            "description": "broken clouds",
            "icon": "04n"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 283.85,
        "feels_like": 277.79,
        "temp_min": 283.71,
        "temp_max": 284.15,
        "pressure": 1021,
        "humidity": 62
    },
    "visibility": 10000,
    "wind": {
        "speed": 6.7,
        "deg": 20
    },
    "clouds": { "all": 75 },
    "dt": 1607444694,
    "sys": {
        "type": 1,
        "id": 8074,
        "country": "JP",
        "sunrise": 1607463548,
        "sunset": 1607498931
    },
    "timezone": 32400,
    "id": 0,
    "name": "Takashima",
    "cod": 200
}
```
###表示結果
![weather4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/6e9a670c-3233-933e-d8f5-3768b18a4711.png)

#やってみて
「`」と「'」の違いは初心者にとっては難しいかもしれませんが（私もプログラミング自体久しぶりで忘れていました）
他の記事などを参考にする際には気を付けたいですね

意外とJavascriptの入門書でAPIの扱いを記述しているものが少ないのでこの記事で
最初の一歩を踏み出していただけたらなと思います。

数あるAPIの中から今回はOpenWeatherMapを選択しましたがAPIを使えるようになるととても幅が広がります。
ラビットチャレンジ - 深層学習 Day4 Section2 AlphaGo

# 0．概要
本記事は日本ディープラーニング協会認定の講座プログラムである「ラビット・チャレンジ」が提供している科目の1つである深層学習のレポートである。
記事タイトルに記載のとおり、Day4 Section2 AlphaGoについて以下にまとめる。

# 1．AlphaGo
ニュースでも取り上げられた世界最強の囲碁棋士を破った強化学習による囲碁AI。

参考：
http://7rpn.hatenablog.com/entry/2016/06/10/192357
https://qiita.com/shionhonda/items/7a3eb79f55299e743630

## 1.1．AlphaGo Lee
PolicyNet、ValueNetいずれも畳み込みニューラルネットワーク。

### 1.1.1．PolicyNet(方策関数)
19x19の盤面特徴(48チャンネル)を入力とする。
通常のカラー画像ではRGBの3チャンネルだったが、48チャンネル持っている(石が自石・敵石・空白か、着手履歴、取れる石の数はいくつか等)。

出力はソフトマックス関数によって19x19の着手予想確率(どこに打つと良いか)が得られる。

### 1.1.2．ValueNet(価値関数)
19x19の盤面特徴(49チャンネル)を入力とする。手番というチャンネルが増えているだけでほかはPolicyNetと同じ

出力はtanh関数によって現局面の勝率を-1～1の範囲で得られる。
PolicyNetと違い、出力は2次元ではなく1次元(単一値)であるため平滑化(Flatten)をする。

### 1.1.3．Alpha Go Leeの学習ステップ
1．教師あり学習でRollOutPolicyとPolicyNetの学習を行う。
2．強化学習でPolicyNetの学習を行う。
3．強化学習でValueNetの学習を行う。

#### 1.1.3.1．RollOutPolicy
ニューラルネットワークではなく線形の方策関数。
探索中に高速に着手確率を出すために使用される。

PolicyNetのような方策関数は畳み込みをしているため計算量が多かったがRollOutPolicyは遥かに速い。

#### 1.1.3.2．PolicyNet、RollOutPolicyの教師あり学習
過去の棋譜データから教師データを用意して教師と同じ着手を予測できるよう学習する。
教師データの着手点のみを1、19x19の他を0とした分類問題として扱う。

### 1.1.4．モンテカルロ木探索
強化学習の手法の1つ。
価値観数を学習する時に使用する。

minmax探索やαβ探索というものでは盤面の価値や勝率の予想と行った値が必要になるが囲碁のようなゲームでは出すのが困難。
モンテカルロ木探索はこういった盤面評価値を使用せず末端評価値(勝ちor負け)を使って探索する手法。

現局面から末端局面からランダムシミュレーション(PlayOut)を多数回行って勝敗を集計して着手の優劣を決める。

ある着手のシミュレーション回数が一定数を超えたらその手の後の局面を次のシミュレーション開始局面とする(探索木の成長)。

## 1.2．AlphaGo Zero

### 1.2.1．AlphaGo LeeとAlphaGo Zeroの違い

* AlphaGo Leeは教師あり学習をするが、AlphaGo Zeroはしない。
* AlphaGo Leeはヒューリスティック(経験則、試行錯誤)をして特徴を選択するが、AlphaGo Zeroは石の配置のみ与える。
* AlphaGo LeeはPolicyNetとValueNetが分かれているがAlphaGo Zeroは統合している。
* AlphaGo ZeroはResidual Netを導入した。
* AlphaGo Zeroはモンテカルロ木探索からRollOutシミュレーションを廃止した。

### 1.2.2．PolicyValueNet
PolicyNetとValueNetが統合されたが、それぞれ方策関数と価値観数の出力が得たいため途中で枝分かれしたニューラルネットワークとなる。

Residual Net(Residual Block)を導入することで勾配消失、勾配爆発を防いでいる。
Residual Blockの考え方はResNetと同じ。

### 1.2.3．Residual Blockの工夫

#### 1.2.3.1．Bottleneck
Residual Blockの工夫として次元削減を取り入れることで2層のものと計算量はほぼ同じとしつつも1層増やしたもの。

#### 1.2.3.2．PreActivation
Residual Blockの並びをBatchNorm、ReLU、Convolution、BatchNorm、ReLU、Convolution、Addにして性能向上したもの。

### 1.2.4．ネットワークの工夫

#### 1.2.4.1．WideResNet
Convolutionのフィルタをk倍に段階的に幅を増やしていくResNet。
フィルタを増やすことで層が浅くても深い層のものと同等以上の性能を発揮する。

#### 1.2.4.2．PyramidNet
WideResNetのように段階的にフィルタを増やすのではなく、各層でフィルタを増やすResNet。

# X．ラビットチャレンジとは
ラビットチャレンジとは、日本ディープラーニング協会認定の講座プログラムの1つ。
E資格を受験するためにはこのラビットチャレンジ等、いずれかの講座プログラムを修了しなければならない。

ラビットチャレンジの特徴は「現場で潰しが効くディープラーニング講座」の通学講座録画ビデオを編集した教材を使用した自習スタイルであるという点。
サポートは他の講座より少なく、受け身ではなく自主的に学んでいく姿勢でなければ進められないが、その分、他の講座に比べると安価であり、手が出しやすい。
ある程度知識がある人、自力で頑張るぞというガッツのある人向けではないかと感じる。

![bnr_jdla.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389699/bce66671-a2f5-a7f9-de6f-3f87e15c253b.png)
gatsby 公式チュートリアルメモ part1

### 公式チュートリアルリンク
https://www.gatsbyjs.com/tutorial/part-one/

### starterを使う
以下のようなコマンドを打ってスターターからプロジェクトを生成

```
gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world
```

スターターはここに色々ある
https://www.gatsbyjs.com/starters/?

localhostで表示してみる

```shell:shell
gastby develop
```

### pageを作る
プロジェクト内のsrc以下にpageが存在する．ホームはindex.jsになる．
以下のように編集して保存．

```src/pages/index.js
import React from "react"

export default function Home() {
  return <div style={{ color: `purple`, fontSize: `72px` }}>Hello Gatsby!</div>
}
```

```src/pages/about.js
import React from "react"

export default function About() {
  return (
    <div style={{ color: `teal` }}>
      <h1>About Gatsby</h1>
      <p>Such wow. Very React.</p>
    </div>
  )
}
```

`localhost:7000/about` という感じでアクセスできる
index.jsは ``localhost:7000` 
`localhost:7000/index`はだめだった

### componentを作る
共通のパーツとして使えるコンポーネントを作る．これはパラメータを持つこともできて，便利．

``` src/pages/header.js
import React from "react"

export default function Header(props) {
  return <h1>{props.headerText}</h1>
}
```

``` src/pages/about.js
import React from "react"
import Header from "../components/header"

export default function About() {
  return (
    <div style={{ color: `teal` }}>
      <Header headerText="About Gatsby" />
      <p>Such wow. Very React.</p>
    </div>
  )
}
```
`<Header headerText="About Gatsby" />` のようにして，コンポーネントに対して変数を渡せる．
### Linkコンポーネント
``` src/pages/index.js
import React from "react"
import { Link } from "gatsby"
import Header from "../components/header"

export default function Home() {
  return (
    <div style={{ color: `purple` }}>
      <Link to="/contact/">Contact</Link>
      <Header headerText="Hello Gatsby!" />
      <p>What a world.</p>
      <img src="https://source.unsplash.com/random/400x200" alt="" />
    </div>
  )
}
```
htmlにおけるaタグのような存在のリンクタグ

### deployする
https://surge.sh/ のサービスを使ってデプロイしてみる

```shell:shell
# gatsbyのビルドコマンド
gatsby build 

# publicフォルダが生成され以下に静的なページが生成される
ls public 

# surge の install
npm install --global surge 

# surgeのアカウント生成
surge login

# surgeでデプロイ
surge public/
```
surgeを使ってデプロイし，webPageを作成するところまで確認
図形を拡大・縮小する transformScale

移動、回転と来たら拡大縮小もやらざるを得ない。。

![cap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/403607a5-ffe1-e10c-6368-336514783bc6.gif)


```javascript
let polygon1 = {
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [ 137.796, 34.940 ],
        [ 137.748, 34.882 ],
        [ 137.887, 34.888 ],
        [ 137.796, 34.940 ]
      ]
    ]
  }
};

const dataSource = {
  'type': 'geojson',
  'data': {
    "type": "FeatureCollection",
    "features": [
      polygon1,
    ]    
  }
};

const bounds = turf.bbox(dataSource.data);

let anchor;

const map = new mapboxgl.Map({
  container: 'map',
  bounds: bounds,
  style: {
    version: 8,
    sources: {
      OSM: {
        type: "raster",
        tiles: [
          "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
        ],
        tileSize: 256,
        attribution:
        "OpenStreetMap",
      },
    },
    layers: [{
      id: "BASEMAP",
      type: "raster",
      source: "OSM",
      minzoom: 0,
      maxzoom: 18,
    }],
  },      
});

map.once('load', () => {

  map.fitBounds(bounds, { padding: { bottom: 200, top: 200, right: 200, left: 200 }});

  map.addSource('polygons', dataSource);
  
  map.addLayer({
    'id': 'polygons',
    'type': 'fill',
    'source': 'polygons',
    'paint': {
      'fill-color': '#FF0000',
      'fill-opacity': 0.7
    }
  });

  const center = turf.center(polygon1);
  anchor = new mapboxgl.Marker()
    .setLngLat(center.geometry.coordinates)
    .setDraggable(true)
    .addTo(map);

});

document.getElementById('scale').addEventListener('click', () => {
  const scale = Number(document.getElementById('scl').value);

  turf.transformScale(polygon1, scale, { origin: anchor.getLngLat().toArray(), mutate: true });

  const dataSource = map.getSource('polygons');
  dataSource.setData({
    "type": "FeatureCollection",
    "features": [
      polygon1,
    ]    
  });
});
```

``turf.transformScale(図形, 倍率, { origin: 基点 })`` という感じです。
倍率は 1.0未満が縮小、1.0より大きいと拡大です。
基点が指定できるのは便利でよいですね。

### 完全なコードはこちら

- [Scale features - JSFiddle - Code Playground](https://jsfiddle.net/amay077/94f57x2d/)

## 参考

- [transformScale - Turf.js | Advanced geospatial analysis](https://turfjs.org/docs/#transformScale)
[Vue.js] $emitを使って子で作成したイベントを親コンポーネントで発火させる

emitを使ってカスタムイベントを作り出し、それを親コンポーネントで発火させる例を記事にあげます。
子コンポーネントで作成したイベントを親で発火させて定義したメソッドを呼ぶという内容です。
最近仕事でフロントエンドを触り始めたので備忘録として書きました。
間違いや覚えておいた方が良い知識があればコメント下さい！！

```child_component.vue
#子コンポーネント
<script>
    export default {
        methods: {
            test(){
                this.$emit('input');
            }
        }
    }
</script>
```

```parent_component.vue
#親コンポーネントでのイベント発火
<template>
    <input @input='onSubmit' />
</template>

<script>
    export default {
      methods: {
        onSubmit() {
          console.log('test')
        },
      },
    }
</script>
```

イベント発火させてメソッドを呼び出すとconsole.logの中身がコンソールに表示される

```debug.
#console.logの中身
test

```

参考記事
https://qiita.com/d0ne1s/items/f88ecd6aaa90c7bbc5d4
jpholiday...めっちゃ便利だけどmapすると遅いとき

#内容
jpholidayというライブラリがあって、日付を渡すと祝日かどうか教えてくれます。
特徴量として、平日か祝日かみたいなことを考えるときに、月～金のうち祝日を主に取り出したいって感じ

参考
[u++さんの記事](https://upura.hatenablog.com/entry/2018/12/21/070000)
[ほかの記事](https://qiita.com/hid_tanabe/items/3c5e6e85c6c65f7b38be)

```
import jpholiday
from datetime import date
today = date.today()
print(today)
print(jpholiday.is_holiday(today))
```

```
#2020-12-09
#False
```

こんな感じで。

ただ、何となくpandasでぶちこむと残念ながらうまくいきません

```
import pandas as pd
from datetime import date, timedelta

today = date.today()
date_time = []
for i in range(1000):
    for _ in range(1000):
        date_time.append(today + timedelta(days = i))
df = pd.DataFrame({
    'datetime': date_time
})

print(df.head())
```

```
     datetime
0  2020-12-09
1  2020-12-09
2  2020-12-09
3  2020-12-09
4  2020-12-09
```

このdfのdatetime列について投入すると

```
jpholiday.is_holiday(df.datetime)
```

```
...
AttributeError: 'Series' object has no attribute 'month'
```

できないので、こうするとできます

```
df.datetime.map(jpholiday.is_holiday)
```

しかし、列数が100万超えてくるデータセットだとこの作業でも時間がかかります。

```
import time
import logging
from contextlib import contextmanager
@contextmanager
def timer(name, logger=None, level=logging.DEBUG):
    print_ = print if logger is None else lambda msg: logger.log(level, msg)
    t0 = time.time()
    print_(f'[{name}] start')
    yield
    print_(f'[{name}] done in {time.time() - t0:.1f} s')
with timer("map"):
    df.datetime.map(jpholiday.is_holiday)
```

```
[map] start
[map] done in 54.4 s
```

遅い。多分mapが1行ずつやってるからと思われます
そこで、unique()で重複している列を消して、dict形式でmapします

```
with timer("make_map"):
    dates = df.datetime.unique()
    date_dict = {}
    for i in dates:
        date_dict[i] = jpholiday.is_holiday(pd.to_datetime(i))
    df.datetime.map(date_dict)
```

```
[make_map] start
[make_map] done in 0.3 s
```

for文でもそれなりに早くなった
内包表記にするともうちょっと早くなるかも

#要するに
このスクリプトはデータが1日1件しかない場合は使えません。
今回のデータ定義みたいに、1日に1000件が1000日みたいなときに早くできます。
参考になれば幸いです。
adbコマンド覚書



サイネージの Android アプリ開発で adb コマンドを使ったのでまとめ


# 接続
```terminal
adb kill-server
adb start-server
adb tcpip 5555
adb connect 192.168.x.x:5555
```
connect に失敗した場合は、もう一度 kill-server から。
connect するときの ip アドレスは、
Android の 設定 --> 端末情報 的なところに表示されているのでそれを丸々タイプすればおk。

# 接続確認
接続確認コマンド

```terminal
adb devices
```

出力例

```terminal
List of devices attached 
XXXXXXXX    device
```

ここで、device と出力されない場合は、これ以降の apk インストールやら、ファイルの push やらができない
解決策として以下があるので参考まで

1. Android端末 の wifi を ON OFF してみる
2. Android の開発者オプションから USB デバッグを ON OFF してみる
3. 接続 kill-server からやり直す

これでダメならわからん。。とりあえず自分は基本的に 3 の解決策で解決、開発が進んだ。

# 接続した Android 端末の /sdcard とかを確認したい時
```terminal
adb shell
```

これで Android の内部に入れるので、あとは ls とか cd とか使ってフォルダの中身とかを確認できる。
/sdcard の中身とかも見れる。


# 接続した Android 端末の /sdcard とかにファイル送りたい時
```terminal
adb push xxx.png /ファイルを送りたいフォルダの絶対パス
```
絶対パスは、adb shell で潜って、pwd で取得とかすれば問題ない。
pull は使わなかった。使う必要があるときにときググればおk。



# apk ファイルのインストール
```terminal
adb install xxx.apk
```
install が reject されるときは、signed_apk ではなかった場合、プレイストアのプロテクトが ON になっていたりする場合があった。

# インストール時に adb で接続された Android 端末が複数ある時
```terminal
adb -s xxxxxxx(端末名) install xxxx.apk
```

xxxxxxx(端末名)については、adb devices で出力される端末名を入れればおk。
補完で出てくるので Tab を押せばわからなくても解決。

# log を出力したい
```terminal
adb logcat
```
Android Studio でいつも見ている Logcat 画面が terminal で流れる。
とはいえ、adb connect した時点で Android Studio の Logcat 画面に ログが流れるのであんまり意味ないかもしれない。
Android Studio を起動しない、できないけどデバッグしたい時に使うくらいしか用途がわからない。


# その他
開発中に BroadCastIntent とかの intent 周りを adb を使って起動できたコマンドを使ったけど、ちょっとコマンドを忘れてしまった。
https://maku77.github.io/android/adb/adb-am-start.html
こちらの方のサイトのおかげで思い出したので書いておく。

```terminal
am broadcast -a android.intent.action.アクション名
```
確かこれで動作したはず。ダメだったらもう一度確認が必要。