OmniAICreator/Qiita-1.07M huggingface dataset:
Elmスクリプトをサッと実行する

Elmを書いていて、どんな結果が表示されるのかすばやく見てみたい！と思われたことはないでしょうか。

Elmにはビルトインの高機能なREPLが備わっていますし、`elm reactor`コマンドや[Ellie](https://ellie-app.com/)のようなオンラインIDEもありますので、開発するうえで困ることはほとんどないかもしれません。わたしはコマンドラインツールが好きなので、ターミナルから同じようにElmを試せる選択肢もあると楽しいかも？と思いついてしまいました。

GitHubを検索してみると[run-elm](https://github.com/jfairbank/run-elm)というパッケージがすでに公開されていますが、`elm`コマンドがサブコマンドをサポートしていなかった頃から更新されていない様子で、Elm 0.19のコンパイラではうまく動いてくれないようです。

というわけで、自分で作ってみることにしました。

[elm-render](https://github.com/lettenj61/elm-render)のご紹介です。



## 使い方

### インストール

最初に、実行したいElmファイルを管理するプロジェクトを作りましょう。`elm-render`はnpmパッケージですので、`npm`からインストールして`npx`で実行するのが便利です。

```
$ mkdir elm-render-test
$ cd elm-render-test
$ npm init -y
$ npm install elm-render --save
```

### Elmを書く

今回はこんな内容にしてみました。

```elm
module Example exposing (main)

import Html

main =
  let
    today =
      14

    christmas =
      24
  in
  Html.h1 []
    [ Html.text <|
        "クリスマスまであと" ++ String.fromInt (christmas - today) ++ "日！"
    ]
```

### 実行する

```sh
$ npx elm-render Example.elm
<h1>クリスマスまであと10日！</h1>
```

うまくいきました :tada:

`elm`コマンドをグローバルインストールしていることを前提としていますが、もし`node_modules`以下などの別のパスを指定したいときは`--elm-binary`オプションで変更できます。

```sh
$ npx elm-render --elm-binary=/path/to/your/elm Example.elm
```


## しくみ

[RE:DOM](https://redom.js.org/)というDOM操作ライブラリと、Node.jsでRE:DOMを使えるようにする[NO:DOM](https://github.com/redom/nodom)というパッケージを使って、Elmが出力するJavaScriptをレンダリングして表示しています。

RE:DOMとElmの組み合わせは、SSRにも応用できそうで夢が広がりますね！


## できないこと・今後の課題

思い付きを急いで形にしただけなので、パッと思い付くだけでもこんなに制限があります。

- `elm/core`、`elm/html`以外のパッケージは使えない
- 複数のElmモジュールに対応しておらず、実行できるのは`main`を公開しているモジュールだけ
- テスト、エラーハンドリングが適当

改善点やすてきな使い道を考えついた方はぜひ教えてください！
【Vue.js】transitionのin-outとout-inの表示結果デモ

## はじめに
Vue.jsの`transition`タグの属性である`in-out`と`out-in`の動きの違いが分かるデモを作ってみました。

[公式ドキュメント](https://jp.vuejs.org/v2/guide/transitions.html)はこちら。
## 環境
```yaml
- OS: macOS Catalina 10.15.1
- Vue: 2.6.10
```

## 基本構文

```vue
<transition mode="out-in">
  <!-- ... the buttons ... -->
</transition>
```
この`mode`の値を`in-out`、`out-in`どちらにするかで表示が変わります。

## 指定なし

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="terufumi1122" data-slug-hash="LYERjdZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="LYERjdZ">
  <span>See the Pen <a href="https://codepen.io/terufumi1122/pen/LYERjdZ">
  LYERjdZ</a> by terufumi (<a href="https://codepen.io/terufumi1122">@terufumi1122</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## in-out
> 最初に新しい要素がトランジションして、それが完了したら、現在の要素がトランジションアウトする。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="terufumi1122" data-slug-hash="wvBzPJG" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="wvBzPJG">
  <span>See the Pen <a href="https://codepen.io/terufumi1122/pen/wvBzPJG">
  wvBzPJG</a> by terufumi (<a href="https://codepen.io/terufumi1122">@terufumi1122</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## out-in
> 最初に現在の要素がトランジションアウトして、それが完了したら、新しい要素がトランジションインする。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="terufumi1122" data-slug-hash="XWJjzME" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="XWJjzME">
  <span>See the Pen <a href="https://codepen.io/terufumi1122/pen/XWJjzME">
  XWJjzME</a> by terufumi (<a href="https://codepen.io/terufumi1122">@terufumi1122</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

特に意図が無ければ`out-in`を指定しておくのが無難ですね:thinking:


## 参考にさせて頂いたサイト（いつもありがとうございます）
[Enter/Leave とトランジション一覧 — Vue.js](https://jp.vuejs.org/v2/guide/transitions.html)
個人的なプログラミングのイメージ

大学に入学してからプログラムを始めて、もうすぐ2年が経ちます。そこで大学の所属サークルでアドベントカレンダーの14日目を担当するこの機会に記事にまとめてみようかな～と思ったのでまとめます。
主にprocessingを触っているのでprocessingを使っていきたいと思います。
それぞれの命令をどんなイメージで使ってるか書いていくだけです。あくまで個人的なイメージですのでイメージが違くても許してください。1時間くらいで書いたので雑かもしれません……（誤字脱字あるかもしれません）
最初のころに**processing**で習った命令を少しだけ書いていきます。

#プログラムの実行画面
はじめに、プログラムの実行画面のイメージから行こうと思います。
↓これです↓
![sketch_191215a 2019_12_15 0_07_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/fe9ee2be-b306-27e3-a55b-52cc61fbe27a.png)![sketchbook_blank_zabuton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/68eccb01-979a-0eb1-791f-5d24b234b529.png)
個人的に実行画面は「紙、スケッチブック」みたいなイメージです。この「紙、スケッチブック」にいろいろ描いていく。そんなイメージでやってます。

#void setup()
必ずと言っていいくらいに書くこいつ。個人的なイメージは「お絵描き前の準備」です。お絵描きする前には**ペン**だったり**紙**だったり準備しますよね？その準備を行うのがvoid setup関数ってイメージです。（実際には違うと思いますが…）

#size()
「用意する紙の大きさ」というイメージです。()の中で大きさを決められます。

#void draw()
setupについて書いたらこれにも触れないとね。これは単純。「描く」。まあ、*draw*って言ってるしね！
書いてある順番で、紙（実行画面）にお絵描き（draw）するよってことです。
初期設定だと確か1秒間に60回お絵描きするはずです。よくそんな速度でお絵描きできるもんだ…
といってもそんな速度でお絵描きするって言われても…ってなるので、そこは個人的には「パラパラ漫画」のイメージですね。
1秒で60枚の絵をパラパラしている。そう思うとわかりやすくなるかなって思ってます。![parapara_manga.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/6ee4318d-c1d2-4e11-23c6-8a2ecd5855a4.png)

#background()
次はbackgroundです。ズバリ背景のことなんですが…「新しい紙の用意」ってイメージですね。（）の中で設定した色の紙や画像の写真を用意する感じです。これを書かなかったがために図形などの絵が重なりまくったことがある人は少なくないはず。新しい紙を用意せずに同じ紙にずっと絵を描いてたらそうなりますよね？

#stroke() , strokeWeight()
これらのイメージは「ペンの持ち替え」です。お絵描きするときには色鉛筆だったりクレヨンだったり使いますよね？strokeは**ペンの色**を、strokeWeightは**ペンの太さ**を変えます。これを使って自分が使いたい色や太さのペンに持ち替えるというわけです。
何も設定しないと黒いペンを持った状態から始まります。
![pen_iroenpitsu01_red.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/32c26a18-683c-a94c-f7ff-647de1958a78.png)![crayon07_blue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/7b09aec8-be8d-f981-34fa-c5e4a93eb563.png)


#rect() , ellipse()　などの図形
次に図形を描く命令にいきます。イメージは「シールを貼る」って感じです。それぞれの命令の形をしたシールを紙に貼ります。()内で貼る位置やシールの大きさが指定できます。最初は白色のシールです。色を変えるときは後述するfill()で変えられます。

#fill()
前述した通り「シールの色」です。()の中で何色にするかは決められます。

#上の命令を使ったお絵描き
```
void setup(){
  //横400,縦200の紙を用意
  size(400,200);
}
void draw(){
  //新しく白色の紙を用意
  background(255,255,255);
  //赤色の太さ3のペンを用意
  stroke(255,0,0);
  strokeWeight(3);
  //黄色い四角のシールを貼る
  fill(255,255,0);
  rect(100,50,100,100);
  //青色の太さ10のペンを用意
  stroke(0,0,255);
  strokeWeight(10);
  //ピンク色の丸いシールを貼る
  fill(255,0,255);
  ellipse(200,100,100,100);
}
```
↓実行結果↓
![sketch_191215a 2019_12_15 1_16_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550883/e5053371-cc54-bb26-6beb-b198bb86c4d1.png)

四角のシールの上から丸いシールを貼ったので重なってますね。

#終わりに
個人的なイメージについて書いてきましたがあくまでイメージです。イメージが絶対に正しいわけじゃありません。あくまでわかりやすくしたまでです。もっと詳しく知りたい方はReferenceや他の方の記事を読むといいと思います。ここまでお読みいただきありがとうございます。
pythonのbinpackingライブラリーのすゝめ

#binpacking問題とは
説明しよう！binpacking問題とはあるランダムなサイズの品物とそれを詰める同じサイズのビンが複数あり、そのビンの数を最小にしようという問題である。

[英語wiki](https://en.wikipedia.org/wiki/Bin_packing_problem)

#1次元binpacking問題

oneDpackというのがあります。
anconda promptで

```python
pip install oneDpack
```

使い方
capとしてbinのサイズ、itemsに入れるもののサイズを入れます。
capが大きいととても遅くなります。

```python
from oneDpack import*

cap=60
items=[2,4,5,2,7,4,7,3,7,3,7,43,8,2,4,13,6,4,3,2,4,7,9,10,40,23]
for i in packing(cap,items):
    print(i)
    print(sum(i))
```
出力

```
[4, 13, 43]
60
[2, 3, 4, 4, 7, 40]
60
[2, 2, 3, 3, 4, 7, 7, 7, 7, 8, 10]
60
[2, 4, 5, 6, 9, 23]
49
```

#2次元binpacking問題

reckpackというのがあります。
anconda promptで

```python
pip install reckpack
```

使い方
binsのサイズ、cargoの縦横のサイズを入れます。

```python
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from collections import*
from rectpack import newPacker
from pandas import*
from numpy import*

bins = [(50,50)]
cargo = [(15,20),(30,20),(15,20),(10,20),(20,14),(15,20),(11,20),(30,10)]

packer = newPacker()

# 容器を設定する。
for i, b in enumerate(bins):
    packer.add_bin(*b, bid=i)

# 箱を設定する。
for i, r in enumerate(cargo):
    packer.add_rect(*r, rid=i)

# マス埋めを実行する。
packer.pack()


for i, abin in enumerate(packer,1):
    for r in abin:
        print(r.x,r.y,r.width, r.height)
```
出力

左下からのx座標,左下からのy座標,左から右への長さ,下から上への長さを出力します。

```
0 0 30 20
30 0 20 15
30 15 20 15
0 30 15 20
0 20 30 10
15 30 14 20
29 30 11 20
40 30 10 20
```
可視化するとこうなります。

```python
%matplotlib inline

def draw_result(packer):
    # 画面のサイズ
    fig = plt.figure(figsize=(20,10))
    for i, abin in enumerate(packer,1):
        ax = fig.add_subplot(i, len(packer), 1, aspect="equal")
        
        # 容器を描画する。
        ax.add_patch(Rectangle((0,0), abin.width, abin.height, fc="none", ec="g", lw=2, zorder=10))
        for r in abin:
            # 箱を描画する。
            ax.add_patch(Rectangle((r.x, r.y), r.width, r.height, fc="lightblue", ec="k"))
            cx, cy = r.x + r.width / 2, r.y + r.height / 2
            ax.text(cx, cy, r.rid, ha ="center",va="center", color="k", fontsize=14)
        
        ax.relim()
        ax.autoscale_view()

draw_result(packer)
```

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369642/f2d92615-433d-c37c-ab54-e3bf01fd4005.png)


#3次元binpacking問題

目下捜索中です、おすすめがあればコメントにて教えてください。
僕のP2HACKS譚

#はじまり
　12月7日～15日に開催される「P2HACKS」に参加してきました！当初に予定していたRailsではなく全く触ったことのない「React」で製作しました。というより、していますのほうが正しいんですが。しかし、全く触ったことのないものでアプリ製作を行って生じる苦労が１つや２つで収まるわけがないんです。

　とういうわけで、アプリ製作中に僕が学んだことや苦労したことのいくつかを書いていこうと思います。注意：書いてることの正確さは保証しません。

##１index.htmlをいじらない
　まずそこからかよって思う人もいると思いますが、そこからなんです。HTMLとCSSは少しわかるがJavaScriptはあんまりわからない、という状況で僕はまず初めに脳死でindex.htmlをいじり始めました。
　Reactは基本的にindex.htmlをいじりません。App.js以下をいじっていれば何か変なことをしない限り勝手にindex.htmlを書き換えてくれます。少しだけ具体的に説明します。

index.htmlでは「root」という名前のidを読み込むことになっています。下記の画像は実際のindex.htmlのコードの一部です。
![accc1131ed4d6eb22e7f23ed40b62025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504838/939aef80-b545-70be-afa6-3172447c2b12.png)

次にindex.jsですが、「ReactDOM.render(<App />, document.getElementById('root'));」の部分でAppの部分を編集すれば'root'という名前のidの場所でhtmlを書き換えてくれます。さらに、上の方にある「import App from './App'」でApp（fromの後）という名前でexport defaultされたモジュールをApp（fromの前）という名前で受け取ってます。 
下記の画像はindex.jsのコードです
![97efcb8bad6974329bdc827ca4d3ea67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504838/9225f45e-a510-f561-b41c-bd1940660618.png)

最後にApp.jsです。ここで直接HTMLを操作したりするコードを書きます。下記の画像を見てください。これはApp.jsのコードです。一番下の「export default App」でこのファイルのデフォルトとしてAppというものをexportするよって意味です。だからfunction App(){ ~ }の中を書き書きすれば動きます。

![挿入ミス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504838/291c9c43-b1ab-58a5-4631-69d629de14b1.png)

##２jQueryとReactを併用するな
　jQueryとReactを併用してはいけない。理由はjQueryは本物のDOMをいじるがReactは仮想のDOMを使ってコンポーネントを描画するから処理がコンフリクトするらしい。...正直、説明聞いてもよくわからなかったので「併用してはいけない」という知見しか僕は得ることが出来なかった。それとjQueryを使うと問答無用で猫先輩に怒られる。下記は併用してはいけないことを知らずに僕がどや顔で書いたコードです。やりたかったことは画像をクリックしたとき、それが何の画像でも、src属性の値を持ってくるということです。それ自体は成功しましたが、当然没になりました。
![ea0ee1d5737ae6f91a1721b130819e71.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504838/467e5671-9090-8ceb-c968-fafce5f64059.png)

##３flexboxについて（css）
　実装した機能の中に、HTMLでulとliを使って画像をたくさん表示するものがありました。しかし、何もしないままだと画像が縦一列に並んでしまうのでとても見にくいUIになってしまいます。
　そこで利用したものが「flexbox」というレイアウトモジュールです。flexboxでは要素を縦や横に柔軟に配置するためのものらしいです。今回やったことは画像をたくさん表示するときに横に３つずつ並べて居れていくことです。4つ目は次の行の一番左に…って感じです。要素を左から右に、入りきらなくなったら下に行を追加していく、ということを実装するには親要素に「flex-wrap:wrap;」を加えてあげればできます。その後、配置する要素の大きさを(100% /n)の大きさにしてあげれば、横一列にn個の要素が入ります。下記は今回実際に実装したulに対して加えたクラスのコードです。
![18aa8c2cf806150658ef79fb75ca145e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504838/6cfed8d3-9e05-b666-89ca-beadf8c00f11.png)


#今回のオチ
　今回、自分が先輩に教わったり自分で調べたりしたりして解決した苦労の一部を書きました。画面遷移とかも書きたかったんですが、自分のコード見ても何で動いてるのか思い出せなかったので止めました（笑）。しかも、かなりあやふやな知識で書いてるのであんまりあてにしないでください。あぁ、こいつはこんなことしてたんだな、くらいの気持ちで読んでいてくれたら嬉しいです。（本当はP2HACKSと関係ないことを紹介したかったけど出来なかったなんて口が裂けても言えない。）
　これ書いてる時間がP2HACKS最終日の1時なんですが、まだ開発が終わっていない...。ということで僕は開発を再開しなければならないので今回はこの辺りで。
[AWS]ALB +ACM + EC2でWordPressをSSL化した際の勘所

####■概要
AWS上に構築したWordPress環境をSSL化しました。
構成は下記となりALBで終端してALBから先はHTTP通信となります。
ALBのリダイレクト機能とx-forwarded-protoを利用して構築したので
WordPressサーバの.htaccessにリダイレクト設定を入れる必要がありません。
また、ACMを利用したのでSSL証明書費用を抑えることができました。

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/36b3181c-c2df-6a06-6333-6ad1ed93d3ee.png)

通信プロトコルのシーケンス図は下記です。
ユーザからのアクセスがHTTPでもHTTPSのいずれでもALBとEC2間はHTTP通信となり
ユーザへの応答はHTTPSに統一されます。

![FireShot Capture 009 - js-sequence-diagrams by bramp - bramp.github.io.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/34a0b0af-1678-33b1-41be-5e839dc05e2e.png)

####■環境
・WordPress:5.3.x
・MW:apache httpd2.4,php7.x
・OS:Amazon Linux 2

####■やったこと
AWSリソースの作成・環境構築、WordPressのインストールは割愛しています。
以下、実施内容となります。

・ALBのリスナー設定
①HTTP用のターゲットグループを作成します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/99497501-86df-fdd7-dff2-fc8f1ebca8d9.png">

②HTTPのリスナーを作成し、HTTPSへのリダイレクト設定を入れます。
　リダイレクト設定の詳細は下記を参考にしました。
　参考:[[新機能]Webサーバでの実装不要！ALBだけでリダイレクト出来るようになりました！](https://dev.classmethod.jp/cloud/aws/alb-redirects/)

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/8ae5de91-87e2-a496-11e6-416a5e68a234.png">


③HTTPSのリスナーを作成し、転送先のターゲットグループをHTTPにします。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/61ba9e03-b7c4-afad-2d6b-b0aa02a626e2.png">

④HTTPとHTTPSのリスナー設定がある状態です。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/518fbf2b-77f9-27aa-4cf2-19c8f138d038.png">

・EC2
ALBの設定だけだとWebアクセス時にcssが崩れており
確認するとHTTPで読み込んでいました。
参考：[ELB + SSL + WordPressについて](https://norm-nois.com/blog/archives/3869)
サーバがHTTPSで認識できるようリクエストヘッダー：[x-forwarded-proto](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/x-forwarded-headers.html#x-forwarded-proto)を利用して、ユーザがALBの接続に使用したプロトコル (HTTP または HTTPS) を識別して、HTTPSの場合はPHPの環境変数にHTTPSを設定するよう記述しました。

```bash:wp-config.php
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  $_SERVER['HTTPS'] = 'on';
  $_ENV['HTTPS'] = 'on';
}
```

これで、cssが崩れることなくWordPressのSSL化が実現できました。

参考記事
https://qiita.com/snoguchi/items/f5ccb67592f87942480d



以上。
Install WiringPi for RaspberryPi 4B

```bash
sudo apt-get install wiringpi
```
で入るWiringPiのバージョンは`2.50`。
2.50はラズパイ4をサポートしていないので、最新のバージョン`2.52`を入れる必要がある。

# install
[参考](http://wiringpi.com/wiringpi-updated-to-2-52-for-the-raspberry-pi-4b/)

```bash
$ wget https://project-downloads.drogon.net/wiringpi-latest.deb
$ sudo dpkg -i wiringpi-latest.deb
```

# Verify
```bash
$ gpio -v
gpio version: 2.52
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 4B, Revision: 02, Memory: 4096MB, Maker: Sony
  * Device tree is enabled.
  *--> Raspberry Pi 4 Model B Rev 1.2
  * This Raspberry Pi supports user-level GPIO access.
```

# Q.なんでapt-getで2.52が入らないの？
A. 開発者がユーザーに失望して開発辞めたから

>and thanks to the incompetence of many people who have done just this,  I’ve had over 10,000 emails
(無能な人間のおかげで10000通ぐらいメール受け取ったわ)

参考：http://wiringpi.com/wiringpi-deprecated/

恐らくこれから新しいボードが出てももう新しいバージョンはでず、対応しないのでこれからは別のライブラリを使うべきですね...
Python + RequestsでGaroon REST APIから組織に所属するユーザーの取得



備忘録。
GaroonのRESTの機能、もう少し充実させてほしい。

###参照

Garoon REST APIの共通仕様
https://developer.cybozu.io/hc/ja/articles/360000503306

組織の取得（GET）
https://developer.cybozu.io/hc/ja/articles/360017843172

###ソース
```Python
import requests

url = 'https://(サブドメイン名).cybozu.com/g/api/v1/base/organizations/1/users'

headers = {
    'Host': '(サブドメイン名).cybozu.com:443', 
    # 'Content-Type': 'application/json',
     # 「ログイン名:パスワード」をBASE64エンコードしたものを値に指定。
     # xxxxxxxxxを書き換えること
    'X-Cybozu-Authorization': 'xxxxxxxxx',
    'Authorization': 'Basic xxxxxxxxx'
}

params = {
    'limit':1000
}

response = requests.get(url, headers=headers, params=params)

downloadData = response.json()

if len(downloadData) > 0:
    print(downloadData['users'])
        
```

###出力結果
```Python
[{'id': '1', 'name': '山田 太郎', 'code': '0001'},
 {'id': '2', 'name': '山田 花子', 'code': '0002'}}]
```
###補足

SOAPだと
「組織情報を取得する」で同様の情報の取得が可能
（ただしユーザー情報のうち、返却されるのはユーザーIDのみ）
https://developer.cybozu.io/hc/ja/articles/202511450

###参考にした記事
Requests の使い方 (Python Library)
https://qiita.com/sqrtxx/items/49beaa3795925e7de666
golangでmapの中の構造体を書き換えようとしたらcannot assign to struct field in mapになる

# エラー

こういう構造体があって

```go
type User struct {
  Id int
  Connected bool
}
```

`User{0, true}`という構造体をmapに追加してその要素を書き換えようとすると

```go
users := map[int]User{0: User{0, true}}
users[0].Connected = false
```

`cannot assign to struct field users[0].Connected in map`とエラーが出る。

# 解決策
## 構造体ごと書き換える
```go
users := map[int]User{0: User{0, true}}
u, ok := users[0]
if ok {
  u.Connected = false
}
users[0] = u
```

## 値をポインタにする
 
```go
users := map[int]*User{0: &User{0, true}}
users[0].Connected = false
```

# コメント

他にいいやり方ないですかね。

# 参考
https://www.pospome.work/entry/2017/02/01/015856
Vue.jsのコンポーネントのimport文をdynamic importに変換するCLIコマンドを作りました


Vue.jsのコンポーネントのimportをdynamic importに変換するCLIコマンドを作りました。
その名も「dynamic-import-converter」
特定のディレクトリ配下のvueファイルを全てdynamic importに変換します。

ソースはこちらで公開しています。
https://github.com/harhogefoo/dynamic-import-converter

```vuejs:通常のcomponentのimport文
<template>
  <div>
    <hoge />
    <piyo />
  </div>
</template>

<script>
import Hoge from "@/components/Hoge.vue"
import Piyo from "@/components/Piyo.vue"

export default {
  components: {
    Hoge,
    Piyo
  }
}
</script>
```


```vuejs:dynamic_importに変換
<template>
  <div>
    <hoge />
    <piyo />
  </div>
</template>

<script>

export default {
  components: {
    Hoge: () => import("@/components/Hoge.vue"),
    Piyo: () => import("@/components/Piyo.vue")
  }
}
</script>
```

# 使い方
```bash
$ yarn global add dynamic-import-converter
or
$ npm install -g dynamic-import-converter

$ dynamic-import-converter ./Vueファイルが格納されたディレクトリのパス/
```

バグ、改善要望などは、リポジトリのissueまで！
https://github.com/harhogefoo/dynamic-import-converter/issues
AWS CLI の認証情報　設定まとめ（プロファイル追加、ロール使用）

AWS CLI の認証情報の設定について、いつも調べつつ利用していたので、自分用にまとめました。


## 認証情報の設定
以下のように aws configure コマンドでセットアップした場合、default という名前のプロファイルに保存される。

```bash
$ aws configure
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ********************
Default region name [None]: ap-northeast-1
Default output format [None]: text
```

プロファイル設定ファイルは `~/.aws/credentials.`（機密性の高い認証情報）と `~/.aws/config`（機密性の低い設定）に保存される。

```bash
$ cat ~/.aws/credentials
[default]
aws_access_key_id=********************
aws_secret_access_key=********************
```

```bash
$ cat ~/.aws/config
[default]
region=ap-northeast-1
output=text
```

default プロファイルは、プロファイルを指定せず AWS CLI コマンドを実行する場合に使用される。

```bash
# default プロファイルの認証情報を使用
$ aws s3 ls
```


## プロファイルの追加
default と異なるアカウントとリージョンの認証情報を追加設定することができる。

```bash
$ aws configure --profile user1
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ********************
Default region name [None]: eu-west-1
Default output format [None]: text
```

プロファイル設定には以下のように追加される。

```bash
$ cat ~/.aws/credentials
[default]
aws_access_key_id=********************
aws_secret_access_key=********************

[user1]
aws_access_key_id=********************
aws_secret_access_key=********************
```

```bash
$ cat ~/.aws/config
[default]
region=ap-northeast-1
output=text

[profile user1]
region=eu-west-1
output=text
```

追加プロファイルは、コマンドに --profile <profile-name> オプションを追加して認証情報を使用できる。

```bash
# 追加プロファイルの認証情報を使用
$ aws s3 ls --profile user1
```

毎度 --profile オプションで指定するのが面倒な場合は、 AWS_PROFILE 環境変数を設定する。

```bash
$ export AWS_PROFILE=user1

# オプション指定無しで追加プロファイルの認証情報を使用
$ aws s3 ls
```


## IAM ロールを使用
CLI でスイッチロールをする場合は、プロファイルにパラメータを追加する。
`role_arn` に IAM ロールの Amazon リソースネーム (ARN) を指定し、
`source_profile` に指定したロールを引き受ける認証情報を持つプロファイルを指定する。（例では iam-user1）

プロファイル設定には以下のように設定する。

```bash
$ cat ~/.aws/credentials
[iam-user1]
aws_access_key_id = ********************
aws_secret_access_key = ********************
```

```bash
$ cat ~/.aws/config
[profile iam-user1]
output = json
region = eu-west-1

[profile iam-role1]
role_arn = arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE>
source_profile = iam-user1
output = json
region = eu-west-1
```

スイッチロールする場合は、追加プロファイルと同じく --profile オプションで指定する。

```bash
# スイッチロール用の認証情報を使用
$ aws s3 ls --profile iam-role1
```


## 最後に

AWS CLIv2 のプレビューバージョンが来たことでドキュメントが結構更新されていて、改めて読み直していると解説が昔より優しくなっている気がしました。
それか昔の自分が理解できない箇所が多かっただけなのか…。
認証情報の利用が煩雑にならないように自戒を込めてのまとめでした。

- AWS ドキュメントリンク

[AWS Command Line Interface » ユーザーガイド » AWS CLI の設定]
(https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration)

[AWS Command Line Interface » ユーザーガイド » 名前付きプロファイル]
(https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html)

[AWS Command Line Interface » ユーザーガイド » 環境変数]
(https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html)

[AWS Command Line Interface » ユーザーガイド » AWS CLI での IAM ロールの使用]
(https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.html)
macへnode.jsのインストール

macにnode.jsをインストールする時に、３記事くらい参考させていただいてやっとできたので、自分ができたやり方をメモしておく。
何か間違いなどあれば言っていただければ嬉しい。

##まず、インストールの手順としては以下になる。
1.homebrewのインストール
2.nodebrewのインストール（一瞬詰まった）
3.Node.jsのインストール（ここで結構詰まった）

自分は、特に手順3の環境パスを通すところで詰まった。

##1.homebrewのインストール
####まずは、すでにインストールされているか確認。

```
$ brew -v
-bash: /usr/local/bin/brew: No such file or directory
```

上記のメッセージが表示されている場合は、インストールされていない。

####インストール
https://brew.sh/index_ja.html に書いてあるスクリプトを実行する

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

2019/12/11現在は上記

####homebrewがインストールできているか確認

```
$  brew -v
Homebrew 2.2.1
Homebrew/homebrew-core (git revision 9ee2; last commit 2019-12-10)
```

##2.nodebrewのインストール

####まずはインストールされているか確認

```
nodebrew -v
-bash: /usr/local/bin/nodebrew: No such file or directory
```

上記のメッセージが表示されている場合は、インストールされていない。

####インストール
homebrew から nodebrew をインストールする

```
$ brew install nodebrew
```

####nodebrewがインストールできているか確認

```
$ nodebrew -v
nodebrew 1.0.1
```

上記のようにバージョンが表示されていれば、インストールに成功している。

##3.Node.jsのインストール

####インストールできるバージョンの確認

```
$ nodebrew ls-remote
```

```
v0.0.1    v0.0.2    v0.0.3    v0.0.4    v0.0.5    v0.0.6    

v0.1.0    v0.1.1    v0.1.2    v0.1.3    v0.1.4    v0.1.5    v0.1.6    v0.1.7
v0.1.8    v0.1.9    v0.1.10   v0.1.11   v0.1.12   v0.1.13   v0.1.14   v0.1.15
v0.1.16   v0.1.17   v0.1.18   v0.1.19   v0.1.20   v0.1.21   v0.1.22   v0.1.23
v0.1.24   v0.1.25   v0.1.26   v0.1.27   v0.1.28   v0.1.29   v0.1.30   v0.1.31
v0.1.32   v0.1.33   v0.1.90   v0.1.91   v0.1.92   v0.1.93   v0.1.94   v0.1.95
v0.1.96   v0.1.97   v0.1.98   v0.1.99   v0.1.100  v0.1.101  v0.1.102  v0.1.103
v0.1.104  

v0.2.0    v0.2.1    v0.2.2    v0.2.3    v0.2.4    v0.2.5    v0.2.6    

v0.3.0    v0.3.1    v0.3.2    v0.3.3    v0.3.4    v0.3.5    v0.3.6    v0.3.7
v0.3.8    
（略・・・）
```

上記コマンドで以下のようなエラーが発生する場合もあるそうです。（自分はならなかった）

```
取得：https://nodejs.org/dist/v7.10.0/node-v7.10.0-darwin-x64.tar.gz
警告：ファイルの作成に失敗しました 
警告：/Users/whoami/.nodebrew/src/v7.10.0/node-v7.10.0-darwin-x64.ta
警告：r.gz：そのようなファイルまたはディレクトリはありません

curl：（23）本文の書き込みに失敗しました（0！= 941）
ダウンロードに失敗しました：https://nodejs.org/dist/v7.10.0/node-v7.10.0-darwin-x64.tar.gz
```

その場合は以下のコードでディレクトリを作成すると良い。

```
$ mkdir -p〜/ .nodebrew / src
```

####インストール
バージョンを指定してインストールするためには、以下のようにする。

```
$ nodebrew install-binary v10.16.3
```

最新版をインストールしたい場合は以下を実行する。

```
$ nodebrew install-binary latest
```

インストールされた Node.js のバージョンを確認する

```
$ nodebrew list
v10.16.3

current: none
```

使用する Node.js のバージョンを指定する

```
$ nodebrew use v10.16.3
use v10.16.3
```

####Node.js のパス設定
Node.js のバージョンを確認する。

```
$ node -v
-bash: node: command not found
```

※ 上記のようなメッセージが表示されていると、Node.js へのパスが通っていません

以下を実行する。

```
echo export PATH=$HOME/.nodebrew/current/bin:$PATH >> ~/.bash_profile
```

node から Node.js のバージョンを確認する（パスの疎通を確認する）

```
$ node -v
v10.16.3
```

※ 上記のように、バージョン情報が表示されれば Node.js にパスが通っています。

以上です！


大変お世話になったサイト
https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09
あと2つ、なんて調べたか忘れてしまったので、また記載しておきます。
Github ActionsでFactorio ModをGithub Releasesに用意する

# はじめに
CI/CDは、最近の開発では標準的に取り入れられているかと思います。

何かしらの仕組みを使って、機械的にチェックすることで、うっかりミスなどが簡単に防げるだけでなく、複合要素のバグなども、防げる可能性が高くなります。

Jenkins、CircleCI, Shippable, Argo CDなど、様々なツールやサービスがあり、導入は比較的簡単に行えるようになってきました。
そんななか、GithubからもGithub Actionsという仕組みが公開され、パブリックリポジトリでは無料で利用できるなど、気軽に導入することが可能になりました。

Factorioという工場を建設して自動化を行うゲームのMod開発でも、Modの動作確認やリリース作業が必要です。
自動化が大好きなら、FactorioのMod開発も自動化したいと考えるのは当然ですよね。

そんななか、 :octocat: [Roang-zero1/factorio-mod-package](https://github.com/Roang-zero1/factorio-mod-package) というGithub Actionsを見つけたので、作っていたCoastal Erosion(海岸浸食)というFactorioのModに導入しました。

これにより、Gitでリリースしたいバージョン番号のタグを付けてリポジトリにpushすると、自動的にGitHub Releaseにリリースが作られ、Modポータルにアップするためのzipファイルが用意されるようになりました。

導入することは簡単にできたので、導入のポイントを紹介します。

# ポイント

以下のリポジトリでGithub Actionsを有効にしたコードを公開しています。

:octocat: [Tei1988/factorio-coastal-erosion](https://github.com/Tei1988/factorio-coastal-erosion)

ただ、Coastal ErosionはTypeScriptからLuaにする処理が含まれているので、より簡単な導入例も以下で公開してもらいました。

:octocat: [iida-hayato/FoodSpaceExplorationModmash](https://github.com/iida-hayato/FoodSpaceExplorationModmash)

詳しくはリポジトリの中の[`.github/workflows/build.yaml`](https://github.com/Tei1988/factorio-coastal-erosion/blob/master/.github/workflows/build.yaml)や、[`.github/workflows/releas.yaml`](https://github.com/iida-hayato/FoodSpaceExplorationModmash/blob/master/.github/workflows/release.yaml)を見てもらうとして、自動的にzipファイルをGitHub Releasesに用意するために抑えるべきポイントは2つあります。

`Tei1988/factorio-mod-package`と、既存のGithub Actionsを使うことです。

# Tei1988/factorio-mod-package
1つ目のポイントです。
`Tei1988/factorio-mod-package`を使います。
元のGithub Actionsには、作られたzipファイルに不要な物が含まれていたので、入らないように修正を加えたものを公開しています。
PRがマージされるまでは自分のリポジトリを参照するようにしています。

```
      - name: Package
        id: packaging
        uses: Tei1988/factorio-mod-package@master
```

もし、`info.json`がリポジトリのrootディレクトリにない場合は、以下も追加します。
        
```
        with:
          mod_base_dir: <info.jsonのあるフォルダのパス>
```

# 既存のGithub Actionsを使う
二つ目のポイントです。
既存のGithub Actionsを使います。
Github ReleasesにファイルをアップロードするためのGithub ActionがGithubから公式に提供されています。

```
        uses: actions/upload-release-asset@v1.0.1
```
すべてを自分で一から作るのではなく、まずは既存のGithub Actionsを組み合わせるところから始めると良いと思います。

# おわりに
いかがだったでしょうか。
以上のポイントで開発後のビルドする作業を自動化することができました。
みなさんも快適なMod開発をライフを過ごしてください。
Maplat CoreでTMS/WMTS地図をオーバーレイとして追加する

Maplat Advent Calendar 15日目は、Maplat Coreで昨日と同様TMS/WMTS地図を追加しますが、ベース地図としてではなく、オーバーレイできる地図として追加してみます。
今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 15](https://codesandbox.io/s/maplat-advent-calendar-day15-3v0gd)

今日のプログラムは[昨日のプログラム](https://codesandbox.io/s/maplat-advent-calendar-day14-swipz)をベースに改造されています。
追加したのは[農研機構の迅速地図](https://habs.dc.affrc.go.jp/)になっています。

```maplat_ac_day15.json
{
  "home_position": [139.5321, 36.249302],
  "default_zoom": 17,
  "start_from": "tatebayashi_ojozu",
  "sources": [
    {
      "mapID": "tatebayashi_ojozu",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_ojozu.json"
    },
    {
      "mapID": "tatebayashi_castle_akimoto",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_castle_akimoto.json"
    },
    "osm",
    "gsi",
    {
      "mapID": "ort",
      "maptype": "base",
      "url": "https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg",
      "maxZoom": 18
    },
    {
      "mapID": "rap",
      "maptype": "overlay",
      "url": "https://www.finds.jp/ws/tmc/1.0.0/Kanto_Rapid-900913-L/{z}/{x}/{y}.jpg",
      "maxZoom": 17,
      "envelopLngLats": [
        [139.454802, 36.209997],
        [139.63024, 36.209997],
        [139.63024, 36.283371],
        [139.454802, 36.283371]
      ]
    }
  ]
}
```

追加されたのはこの部分です。

```maplat_ac_day15.json(追加分抜粋)
    {
      "mapID": "rap",
      "maptype": "overlay",
      "url": "https://www.finds.jp/ws/tmc/1.0.0/Kanto_Rapid-900913-L/{z}/{x}/{y}.jpg",
      "maxZoom": 17,
      "envelopLngLats": [
        [139.454802, 36.209997],
        [139.63024, 36.209997],
        [139.63024, 36.283371],
        [139.454802, 36.283371]
      ]
    }
```

これは、TMSまたはWMTS形式の地図を、オーバレイする地図として新たに追加する際の設定です。
`mapID`は地図を切り替える一意なIDを指定します。
`maptype`は、TMSまたはWMTS形式のオーバレイ地図を追加する場合、`overlay`を指定します。
`url`はTMSまたはWMTS形式のタイル地図URLを指定します。
`maxzoom`は、地図の最大ズームを指定します。
`envelopLngLats`は、地図の提供範囲を指定します。これを指定すると、地図タイルのあるなしにかかわらず、この地図の表示中に視点が領域外に移動すると、領域内に引き戻されます。

他にも、単に上記追加地図に切り替えるボタンを追加するためだけですが、`html`と`Javascript`も以下のように変更します。

```index.html(変更部抜粋)
      <button id="rap">迅速</button>
```

```app.js(変更部抜粋)
  document.getElementById("rap").addEventListener("click", function(e) {
    app.changeMap("rap");
  });
```

これで、以下のような動作になります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/417e7146-bb9d-4457-442e-c20792492c13.gif)

明日はいよいよ、古地図などをオーバーレイ地図として追加する場合を説明しますが...そうなるとMaplatEditorの使い方に触れないといけないので、面倒くさいなあ...
kintoneからLINEに通知を送りたい！[JS簡易版]

##「kintoneに登録したタイミングで、LINEでお知らせできます？」
kintone導入して、よし明日から稼働開始、よろしくお願いします。
そろそろ帰ろうかなという瞬間に出た、まさかのご相談＾＾；

よくよく話を伺ってみると、導入する前、社内全員でLINEグループで業務の連絡をされていて、それもまあ評判が悪くなかったと。
kintoneを導入するメリットはわかったが、これまでの習慣から、LINEで飛び込んできていた情報がkintoneに移ることで、あえてkintoneを開いて取りに行く事になるのは大多数には億劫だと。まあ確かにわかります。

##「kintoneの通知でどうでしょう？メールにも届きますよ？」

残念ながら、今回はパート・アルバイトなどの毎日会社スマホを持ち帰らない方にも通知したいとのことでした。1人1アカウントではなく、部署のPCやiPadのkintoneを確認する運用となっているので、確かに意識していないと厳しい。。（うーん、しまったな。。）

**「kintoneの利用を促進するために社内で啓蒙していかないとね！」**
　から、
**「このままではkintone導入早々、撤退かも」**
と状況が180度変わった瞬間でした。

##「どうにかせな！今日中に！！」

過去にLINE WORKSとのAPI連携はやりましたが、LINE連携は無いなー・・・。
というわけでググってみたら、トヨクモのトッティさんのブログを発見。

＜kintoneをLINEと連携してみた＞
https://kintoneapp.com/blog/kintone_line_connected/

これこれ、こういうのでいいんですよ！100点じゃなくても、目的が達成できれば！

##「というわけでさっそく作ってみよまい！（方言）」

岐阜弁丸出しで申し訳ないですが、帰れないより帰れた方が嬉しいのでテンションが上がります。
トッティさんのブログをさらに読み込みます。

> http://line.me/R/msg/text/?{文章}
って感じで投げればLINEの投稿画面が表示できて送信する文章もセットできる模様。
宛先は都度選んでもらえばいいかな。


>調べてみると、PCにインストールしたLINEアプリには対応していない様子。
こちらは、現時点でのPC用LINEアプリでも対応していました！

      kintone.events.on(['app.record.create.submit','app.record.edit.submit'], function (event) {         
      　　　　if(confirm("LINEで報告しますか？"))
      　　　　{ 
      　　　　　　　　location.href = 'http://line.me/R/msg/text/?【日報報告】%0D%0A＜今日の実績＞販売数：' + event.record['販売数']['value']+'個　売上金額：'+ event.record['売上金額']['value']+'円　%0D%0A連絡事項:' + event.record['連絡事項']['value']; 
      　　　　}   
      　　　　return event;
        });

こんな感じで実装してみました。実質１行！笑
※皆さんがお試しの場合は自己責任で！笑

報告する事項もさほど多くないので、kintoneのライセンスを持っていない方のためにもある程度の情報をkintoneから引用しておきます。

##「よし、動いた！」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76660/b7a69431-ebb2-b448-9e34-320aef9ee772.png)

こんな感じの日報アプリを保存すると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76660/ac2e2e25-44e9-6106-2e39-1a4037223b05.png)

メッセージを送ることができました。

実際はここからあれこれ弄ったのですが、何とかやりたいことは実現できました！ということで。
送れることは送れます！＾＾。

##2019/12/15 追記
kintoneエバンジェリストの久米さん（[@yumekajun](https://twitter.com/yumekajun)）より、LINE Notify使うと楽ですよー！」とコメント頂きました！(ホント、こんな時twitterやってて良かった！)

調査してみて続報こちらに書きました
kintoneからLINEに通知を送りたい！[LINE Notify版]
https://qiita.com/tarimo34/items/b2210c16b198a7185e7e

久米さんのスライドはこちら！
↓
https://www.slideshare.net/jkume/20180906-kintone-hive-fukuoka-vol3
androidでfortran開発する

#概要
androidでfortranコードを書いて実行する。

# スタック
CUI環境はUserLAndを使った。Termuxというものもあるが、昔試したところfortranコンパイラが使えなかった。UserLAndではLinuxパッケージもUbuntuやArch、kaliなどから選ぶことができ、Ubuntuの場合はaptでgfortranが入る。

エディタは別にEmacsでなくてもvimでもnanoでもお好きなものをどうぞ。

# 方法
## UserLAndのインストール
完全に焼き直しで申し訳ないが、下記の記事を参照してほしい。

https://qiita.com/bluepost59/items/7f5608dff98c82ffb668

Google Playからアプリをインストールして、環境を作る。結構でかいダウンロードが走るので、回線を確認してから環境構築に入ること。時間は5分〜10分程度かかる。今回はUbuntuを使った。

うまく行けば下記のようにCUIが立ち上がる。ソフトキーボードだと画面が半分圧迫されるので、ハードウェアキーボードを使うほうがよい。百均でOTGケーブルを買ってくればUSBキーボードを使える。自分はbluetoothキーボードを使ったが快適に使える。

![Screenshot_20191214-235114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107045/8c94790a-6971-e93d-b6f2-0b78785f1a79.png)

## aptで環境構築する
aptでgfortranをインストールする。ちゃんと```apt update```しないとインストールでNot Foundエラーが出る。

```
apt update && apt install gfortran emacs
```

## プログラミング
あとは通常のCUIプログラミングと一緒

![Screenshot_20191215-000955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107045/b4a4e137-9e3d-99e9-8627-b34a0864f727.png)

![Screenshot_20191215-000944.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107045/37bc2432-5cc8-4a92-860d-7579ef4de4bc.png)

無事hello worldが実行できました。
zshで前のディレクトリに簡単に戻る方法

ターミナルで `cd` して「あ〜前のディレクトリに戻りたい〜」ってことよくあるじゃないですか。

`cd -1` とかでも戻れますが、もっとブラウザの戻るみたいな感じでライトに戻りたいじゃないですか。

それを可能にするのがこういう設定です。

```shell:.zshrc
zle -N dir_forward
zle -N dir_back
bindkey '[1;6C' dir_forward # 私の環境ではCtrl-Shift-Left
bindkey '[1;6D' dir_back    # 私の環境ではCtrl-Shift-Left
```

![zsh_back_dir.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107220/133c56c8-2058-49ac-6209-188a1f927f74.gif)



これでブラウザみたいな感じでディレクトリを行き来することができます :tada:
[Flutter] Google Analyticsでページ遷移がscreen_viewになるのを解決する方法

## 前提
[firebase_analytics](https://pub.dev/packages/firebase_analytics)を使用して、下記のような形でnavigateObserversにFirebaseAnalyticsObserverを設定している。

```dart:main.dart
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';

FirebaseAnalytics analytics = FirebaseAnalytics();

MaterialApp(
  home: MyAppHome(),
  navigatorObservers: [
    FirebaseAnalyticsObserver(analytics: analytics),
  ],
);
```

## 結論

named routes または、 RouteSettings を使用して遷移するようにする。

```dart
// 下記のどちらかの方法でページ遷移するようにする。

// named routes
Navigator.pushNamed(context, '/search');

// RouteSettings
Navigator.of(context).push(
    MaterialPageRoute(
      builder: (context) => SearchScreen().
      settings: RouteSettings(name: '/search'),
    ),
  );
}
```

## 参考
[Using Firebase Analytics in Flutter](https://medium.com/flutterpub/using-firebase-analytics-in-flutter-2da5be205e4)

## おまけ
タブ移動は[firebase_analyticsのドキュメント](https://pub.dev/packages/firebase_analytics)に記載されている通り[これ](https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_analytics/firebase_analytics/example/lib/tabs_page.dart)を見ると良さげ。
rayonでお手軽並列処理

この記事は[Rustその3 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/rust3) 12/14の記事です。
並列処理ライブラリ[rayon](https://docs.rs/crate/rayon/1.2.1)の紹介です。

## rayonとは？

rayonは、[スレッド](https://doc.rust-jp.rs/book/second-edition/ch16-01-threads.html)をいい感じに使って、非常に気軽に並列処理ができるライブラリです。

## 配列の各要素に対して並列処理: par_iter

最も手軽に利用できるのが、`use rayon::prelude::*;`だけですぐに利用できる`par_iter`です。
配列の各要素に対して並列処理を行うことができます。`iter()`を`par_iter()`に置き換えるだけで、配列操作の感覚で処理の並列化ができます！
par_iter()した後に使えるメソッドは[ここ](https://docs.rs/rayon/1.2.1/rayon/iter/trait.ParallelIterator.html)から見られます。

```rust
extern crate rayon;

use rayon::prelude::*;
let food_prices = [100, 120, 2000, 1840, 600, 100, 120, 2000];

let takeout_price = food_prices
    .par_iter()
    .map(|&i| (i as f32 * 1.08) as i32) // これ以降の処理が並列処理に！
    .reduce_with(|m, n| m + n)
    .unwrap();

println!("{}", takeout_price);
```

## カスタムな並列処理

上記の`par_iter`以外にも、自分でカスタマイズした並列処理を行うためのAPIが用意されています。

### 2つの並列処理: join

2つの処理の結果を利用したい場合、`join`を使います。分割統治法を使うアルゴリズムのような、1つの大規模な処理をたくさんの小さな処理に分割できるケースで適用できます。

```rust
use rayon::join;

fn hell_fibonacci(x: u64) -> u64 {
    if x < 2 {
        return x;
    }
    let (prev, prevprev) = join(|| hell_fibonacci(x - 1), || hell_fibonacci(x - 2));
    prev + prevprev
}

println!("{}", hell_fibonacci(5));
```

### 任意の数の並列処理: scope

joinでは扱えない、任意の数の並列処理はscopeで行います。自由にタスクをspawnできます。

```rust
use rayon::scope;

use std::sync::atomic::{AtomicUsize, Ordering};
static COUNTER: AtomicUsize = AtomicUsize::new(0);

scope(|s| {
    s.spawn(move |_| {
        COUNTER.fetch_add(1, Ordering::SeqCst);
    });

    s.spawn(move |_| {
        COUNTER.fetch_add(2, Ordering::SeqCst);
    });

    s.spawn(move |_| {
        COUNTER.fetch_add(3, Ordering::SeqCst);
    });
});
println!("COUNT:{:?}", COUNTER);
```

## ベンチマーク
[リポジトリ内のベンチマーク](https://github.com/rayon-rs/rayon/tree/master/rayon-demo) に入っている階乗計算のベンチマークを、手元の環境(MacBook Pro Retina 13inch 4コア/8スレッド)で実行してみました。

```
test factorial::factorial_iterator  bench:  15,679,758 ns/iter (+/- 817,472)
test factorial::factorial_par_iter  bench:   2,262,074 ns/iter (+/- 153,986) 
test factorial::factorial_recursion bench:   4,060,433 ns/iter (+/- 394,378)
test factorial::factorial_join      bench:   2,129,283 ns/iter (+/- 190,471)
```

_par_iterが_iteratorの並列化に、_joinが_recursionの並列化に対応しています。
このベンチマークでは9999!を計算してますが、十分並列化による効果が出ているという印象です。
Maplat Coreでベース地図を追加する

Maplat Advent Calendar 14日目は、Maplat Coreでプリインストールベース地図以外のベース地図を追加してみます。
今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 14](https://codesandbox.io/s/maplat-advent-calendar-day14-swipz)

今日のプログラムは[5日目のプログラム](https://codesandbox.io/s/maplat-advent-calendar-day5-u2lio)をベースに改造されていますが、
今回、設定はこのように変更されました。
追加したのは地理院地図のオルソ航空写真になっています。

```maplat_ac_day14.json
{
  "home_position": [139.5321, 36.249302],
  "default_zoom": 17,
  "start_from": "tatebayashi_ojozu",
  "sources": [
    {
      "mapID": "tatebayashi_ojozu",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_ojozu.json"
    },
    {
      "mapID": "tatebayashi_castle_akimoto",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_castle_akimoto.json"
    },
    "osm",
    "gsi",
    {
      "mapID": "ort",
      "maptype": "base",
      "url": "https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg",
      "maxZoom": 18
    }
  ]
}
```

追加されたのはこの部分です。

```maplat_ac_day14.json(追加分抜粋)
    {
      "mapID": "ort",
      "maptype": "base",
      "url": "https://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg",
      "maxZoom": 18
    }
```

これは、TMSまたはWMTS形式の地図を新たに追加する際の設定です。
`mapID`は地図を切り替える一意なIDを指定します。
`maptype`は、ベース地図を追加する場合、`base`を指定します。
`url`はTMSまたはWMTS形式のタイル地図URLを指定します。
`maxzoom`は、地図の最大ズームを指定します。
他にも、地図の名前や著作権者、説明文その他を追加する設定もあるのですが、UIのないAPIベースだととりあえず上記だけで動きます。

他にも、単に上記追加地図に切り替えるボタンを追加するためだけですが、`html`と`Javascript`も以下のように変更します。

```index.html(変更部抜粋)
      <button id="ort">オルソ</button>
```

```app.js(変更部抜粋)
  document.getElementById("ort").addEventListener("click", function(e) {
    app.changeMap("ort");
  });
```

これで、以下のような動作になります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/17f73287-355d-832b-e19e-8fbccf1debc6.gif)

ちなみになんですが、今回は説明のため、地理院地図オルソを生設定を追加して追加しましたが、実は地理院地図オルソはAPIにプリセットされています。
なので、今日の結果を簡単に得ようと思うと、実は`gsi_ortho`を追加するだけでよかったのです。

明日は、オーバーレイ地図としてTMS/WMTS地図を追加する場合を説明します。
【永久保存版】pyenv+venvをubuntuに入れる【もう迷わない】

# はじめに

VMインスタンス立てる度にもう死ぬほど毎回初期設定するんで、
毎回環境汚さないためにpyenv+venvを入れるんですけど、
**必ず間違った情報**がQiitaには出てくるので、ここに新しくメモします。

# VMを立ち上げたらすること

pyenvを実行するにはsudo権ありで、まずこちらを実行する必要があります。
(情報源は[こちら](https://bgasparotto.com/install-pyenv-ubuntu-debian))

```sh:初期実行
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev
```


# pyenvを入れる

pyenvとは、pythonをsystemベースで管理するのではなく、
個人のディレクトリごとでパッケージ管理するためのものです。

具体的な仕組みは~/.pyenv配下にpython関連のシステムをInstallしてあげ、
その上pythonコマンドを打つとそこをちゃんと読んでくれるようにしてくれるシステムです。

ちなみに**python2**コマンドには対応してませんのでご注意を。

## pyenvをインストールする

**Ubuntuの場合**、以下をコピペして入力すればOKです。

```sh:入力
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
exec "$SHELL"
```

yyuu/pyenvでも`~/.bash_profile`でもありません。**ubuntuはこれです。**
DebianとかCentOSは知りません。
[公式](https://github.com/pyenv/pyenv)にもそう書かれています。
ちなみにZshを使いたい方は`~/.zshenv`に書くそうです。

## pyenvで新しいPython環境を入れる

```sh:pythonを入れる
pyenv install 3.6.9
pyenv global 3.6.9
pip install --upgrade pip
```
これで個別環境のpythonが出来上がります。pipでもなんでも好きにして大丈夫です。

# venvを入れる

venvとは、Python公式の**パッケージ管理ツール**です
pipで入れるmoduleとかをフォルダごとに管理してくれます。

```sh:venv
python -m venv ~/env/hoge
```
pipで何か新しく入れる時はvenv状態で入れるとクリーンで管理がしやすいです。

```sh:venv_activate
. ~/env/hoge/bin/activate
```
とすることで、venv環境が構築できます。
これでフォルダごとに完全に独立したpip環境で構築することができます。

# pyenvとvenvの違い
pyenvで作られたpythonのバージョンでvenvを使用すると、
pyenvで作られたpythonバージョンの仮想環境ができます。

で、`activate`した環境で`which python`すると、
なんとvenvで指定したフォルダが出てきます。

つまり、pyenvは**好きなpythonバージョンを入れることに特化**していて、
venvは今のPythonバージョンで**好きなパッケージを入れることに特化**しています。

ここが大きな違いですね。

# おわりに

くそ殴り書きメモなんですが、毎回Ubuntuで建てる人はブクマかストックしておくと便利かと
いいねしていただければ、正しい情報が伝わりやすいかと思うので、
共感していただければいいねください。ありがとうございます。
AtCoderチュートリアル(Python編)

## はじめに
本記事は[Volare Advent Calendar 2019](https://qiita.com/advent-calendar/2019/volare)の14日目の担当分です。
私は関西の情報系の学生で、学校法人角川ドワンゴ学園が運営する[N高等学校](https://nnn.ed.jp/)にてプログラミングTAとしてインターンをさせてもらっています。その業務の中でプログラミングに興味のある生徒に何から始めたらよいのか度々質問してもらうのですが、そもそもプログラミングを使って作りたいものが特に決まっていないことがあります。その場合にプログラミングの入門の一つの選択肢として紹介している「競技プログラミング」についての記事を初心者向けに書かせていただくことにしました。

## 競技プログラミングとは
* 与えられた入力から求められている出力を満たすプログラムを作成する競技
* 週末にリアルタイムのオンラインコンテストが開催されており、レーテイングで自分の実力を数値化することができる
* 日本語で競技プログラミングの問題を解けるサイトとしては[AtCoder](https://atcoder.jp/)、[AOJ](https://onlinejudge.u-aizu.ac.jp/courses/list)などが有名

ざっくりとこんな感じの問題を解く競技です。
<img width="1022" alt="スクリーンショット 2019-12-13 14.01.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318449/cbb94aab-3ff6-54b3-9109-a8457e469b23.png">

## この記事について
### 読者の想定
* プログラミングおよび競技プログラミングに関心のある人だれでも
    * プログラミング文法をProgateを一通りするくらい勉強していると理解できて楽しめます
    * 初学者のひとでもなんとなくどういうものか知ることはできると思います
    * 特にプログラミング初学者に寄せています ~~ので、できる人はマサカリを投げてください~~

### なぜPythonなのか

競技プログラミングといえばC++の記事や書籍などの情報が多いですが、
Pythonは学習コストが低く、少ない記述量で書けるため初学者の学習に向いていると思い選択しました。
また、Progateなどの初心者向けの教材が豊富であることも学習しやすい理由の一つにあります。

[Progate](https://prog-8.com)

### この記事を楽しむための必要知識
#### プログラミング
* Pythonの基礎的な文法を知っている
    * 逐次処理・条件分岐・反復・変数・演算子(＋ ー ＊ など)
* Pythonを手元で実行する環境が整っている
    * まだの場合[コチラ](https://qiita.com/kgrlizst/items/1f8f6b7d0014a2d7eb16)の記事で先に環境構築をするといいかもしれません。

#### 数学
* 四則演算と負の数の概念

### 構成
* まず、競技プログラミングに参加できるようにAtcoderの会員登録をする
* 競技プログラミングのコンテストを運営しているAtCoderの問題1題をプログラムだけでなく思考の過程にそって回答を作成、問題を提出するまでの流れを記事に沿って行うことで競技プログラミングの参加方法を知る

## AtCoderで回答を提出する準備
[新規登録のページ](https://atcoder.jp/register)からAtcoderの会員登録をする

## 本編
今回の記事では[Atcoder Begginer Contest106](https://atcoder.jp/contests/abc106/tasks/abc106_a)のA問題を例に競技プログラミングの解き方を解説していきます。リンクを開いて画面を横並びにしてやるといいかもしれません。
 
### ざっくりとした解き方
1. 問題文を読む
2. 入力例・出力例を確認する
3. 解き方を考える
4. プログラムを書いていく
5. 提出

### 1. 問題文を読む
問題の要素をざっくりと抽出する

* 条件
    * 縦A[yard]、横B[yard]の畑がある
    * 縦と横にそれぞれ幅1[yard]の道があり畑の面積に含まれない
* 出力
    * 畑の面積[yard]

### 2. 入力・出力を確認する

* 入力されるもの
    * 2以上100以下の整数がスペースで区切られて2個入力される

* 出力するもの
    * 畑の面積[yard]を出力する

### 3. 解き方を考える
まず、求める面積を算数の式に起こしてみる。
今回の問題においては、道が畑のどこにあっても求める面積は同じなので式は以下の図のようになります。
<img width="1012" 2019-12-13 11.21.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318449/a2ede018-8ada-1d07-2b5b-fc045285b937.png">

### 4.プログラムを書いていく

面積を計算する式が求められたので実際にプログラムを書いていきます。

処理の順序は
1. 入力を受け付ける
2. 面積を求める
3. 求めた面積を出力する

なので順番に実装していきます

```入力部分.py
A, B = map(int, input().split())
```

```面積計算.py
S = (A-1) * (B-1)
```

```出力.py
print(S)
```

完成したプログラムは以下のようになります。

```ABC106_A.py
A, B = map(int, input().split())

S = (A-1)*(B-1)

print(S)
```

### 5.提出
問題文の下部に提出用のフォームがあるので、そこに先ほど作成したプログラムを貼り付けて提出します。

＊注意点＊

* 言語をPython3を選択するのを忘れないようにする
* 貼り付ける際に余計な空白が入っていないことを確認する
<img width="1092" alt="スクリーンショット 2019-12-13 13.24.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318449/59b657d6-8d25-71ee-be9d-356ecd20b793.png">


このようにACと表示されていたら正解です
<img width="1088" alt="スクリーンショット 2019-12-13 13.26.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318449/8bd90247-a9e8-fe40-5053-1ee7fa441620.png">

以上がAtCoderで競技プログラミングをする際の問題提出までの一連の流れです。
Haskellで逆ポーランド記法の計算機をつくる　その2

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の十四日目の記事です。

Haskellで逆ポーランド記法の計算機をつくってく記事の続きです

# 前回のぷよぐやむ
前回はcalc関数の足し算引き算の部分の計算を行う部分の実装を行いました。

```hs
calc :: String -> Double
calc = head . foldl folding [] . words
    where   folding (x:y:ys) "+" = (y + x):ys
            folding (x:y:ys) "-" = (y - x):ys
```
これが前回のプログラムですね。これで、足し算引き算を畳み込みを行うことで実現していました。

しかしこれではまだプログラムは動作しないので、今回は動作させること、そして、掛け算割り算などの追加を行うことを目標にしていきます。

#　じっそー

今は「+」と「-」しか処理ができないので、普通に数字がきた場合のパターンを作成しましょう

```hs
calc :: String -> Double
calc = head . foldl folding [] . words
    where   folding (x:y:ys) "+" = (y + x):ys
            folding (x:y:ys) "-" = (y - x):ys
            folding xs num       = read num:xs
```

これで、最低限の動作が行えます。

main関数から特定の文字列でcalcを呼んでみましょう。

```hs
main = do 
    print $ calc "12 34 + 3 -"
```

```
$ runghc rpn_parser.hs
43.0
```
これを普通の数式にすると`12 + 34 - 3`で`43`になりますね。
戻り値はDouble型なので出力は43.0になりますね。

次はこれをコマンドライン引数に対応させていきます。

```hs
main :: IO ()
main = do 
    args <- getArgs
    print $ calc $ args !! 0
```
入力した文字列を引数にcalcを実行します。

```
$ runghc rpn_parser.hs "12 34 + 15 -"
31.0
```
計算もちゃんとあっていますね。

最後に掛け算、割り算、累乗を実装します。
これは各演算子と同様に計算を行うだけですね

```hs
calc :: String -> Double
calc = head . foldl folding [] . words
    where   folding (x:y:ys) "+"  = (y + x):ys
            folding (x:y:ys) "-"  = (y - x):ys
            folding (x:y:ys) "*"  = (y * x):ys
            folding (x:y:ys) "/"  = (y / x):ys
            folding (x:y:ys) "**" = (y ** x):ys
            folding xs num        = read num:xs
```

これで、最低限動作する逆ポーランド記法の計算機が完成しました。

```rpn_parser.hs
import System.Environment


calc :: String -> Double
calc = head . foldl folding [] . words
    where   folding (x:y:ys) "+"  = (y + x):ys
            folding (x:y:ys) "-"  = (y - x):ys
            folding (x:y:ys) "*"  = (y * x):ys
            folding (x:y:ys) "/"  = (y / x):ys
            folding (x:y:ys) "**" = (y ** x):ys
            folding xs num        = read num:xs

main :: IO ()
main = do 
    args <- getArgs
    print $ calc $ args !! 0
```
Power automateでteamsに自動投稿～返信できるようにした話

今回はPowerPlatformを活用して会社の業務改善・・・・をやる予定です。(まだ検証中)
備忘録として書いておきます。

###やろうと思ったきっかけ

12月5日～6日にMicrosoft Ignite The Tour Tokyoが開かれていて二日間参加。
https://www.microsoft.com/ja-jp/ignite-the-tour/Tokyo

Azureの話を聞きに来たけどPowerPlatformにかなり力を入れていると感じ、途中からPowerPlatformばかり見てた


###メール返信がきたら、最初に投稿したメッセージの返信のところに内容を記載したい。

飛んできたメールをメッセージとして投稿するのはどこのチャットアプリでもできたのですが
**その投稿に対して返信を自動投稿する**ことがどこのチャットアプリも簡単ではない
なのでOffice365契約してるしteams使いたい。

![コメント 2019-12-12 150135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/79d488b0-0973-fb90-2a78-328273b6b8be.png)

###そこでPowerPlatformの出番
teamsのMicrosoft Automate機能のベータ機能がある。
![コメント 2019-12-12 133155.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/5a368609-e615-6d08-cf27-877aa274a24c.png)

![コメント 2019-12-12 133712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/b71a0328-1ce4-3219-68b3-9517a76621ba.png)

メッセージの返信の投稿（V2）という機能を使って自分に届いたメールを引数としてteamsに投稿されている内容を件名で検索し、投稿の返信にかけるように挑戦した。

<img width="658" alt="スクリーンショット 2019-12-14 20.57.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/dc2a880b-8215-60c0-1d68-bf671a029032.png">
特定のメールだけを抽出したいときは件名で引っ掛ける等で対応

<img width="781" alt="スクリーンショット 2019-12-14 20.58.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/297dd134-53f9-7ef6-1a8d-f1fec72135da.png">
変数を３つ用意。名前は何でもいいけど。
・sub
届いたメールの件名の文字列を入れ込む
・id
あとでTeamsのメッセージに対して返信するときにメッセージidを入れ込むときの変数
・tsub
あとでTeamsのチャンネル内のメッセージを読み込んだときにメッセージの件名を入れるための変数

<img width="1213" alt="スクリーンショット 2019-12-14 20.59.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/1e3e4582-db87-2052-1aa9-ca30cd50a7ad.png">

<img width="591" alt="スクリーンショット 2019-12-14 21.00.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/80cde0b0-c134-dfcf-419b-802eeee1c6b4.png">
条件分岐で件名にREがついていたらTeamsにもう投稿されていると判断させて左へ。
いいえの場合はそのままメールの内容をTeamsのチームチャンネルを指定してメッセージを投稿する。
件名を入れておくのが重要
<img width="965" alt="スクリーンショット 2019-12-14 21.01.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/184d3c1c-1b55-4418-107d-695f08aa4c23.png">
はいの場合
Teamsのチャンネルのメッセージを取得。
Apply to eachでループ？を作成。Teamsのメッセージの件名を変数tsubに当てはめる。

<img width="1013" alt="スクリーンショット 2019-12-14 21.01.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/58baa3f8-e5df-44d1-5bf0-5c1778204916.png">
条件で、先程引き込んだsub（メールの件名）とtsubが一致する場合にTeamsの対象のメッセージIDを変数idに代入する。
empty関数はTeamsのメッセージに件名が入っていない場合に除外する処理。


###結果
<img width="631" alt="スクリーンショット 2019-12-14 22.45.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/d0b5e4c3-65af-15cb-fe3b-64408fae6238.png">

やったぜ


今後は添付ファイルも投げられたりできたらいいなと思ってます。
メッセージに対して返信を簡単にBOT実装できるのは非常に有用ではないでしょうか。

またこの件については改善の余地があるのでいろいろまとまったらまた書こうと思います。