OmniAICreator/Qiita-1.07M huggingface dataset:
論理回路 JavaScript

# はじめに
差分関数を実装する機会がありましたので、覚書程度に。
適宜追加・修正しようと思っています。
`includes()`methodを使いましたが、`indexOf()`methodを使っても実装できるみたいですね。
訂正等あればコメントください。

## 結論
![Web 1920 – 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341221/05ba4b19-1289-5516-ac41-7d57d8714f80.jpeg)

```js
const logical_expression = function (arr1, arr2) {
    let intersection = arr1.filter(e => arr2.includes(e));
    console.log(intersection);
}

logical_expression([1, 2, 3], [2, 3, 5])
    // -> [ 2, 3 ]
```
![Web 1920 – 3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341221/855771f2-e6fa-5f7f-465f-6de3f87456ff.jpeg)


```js
const logical_expression = function (arr1, arr2) {
    let differenceA = arr1.filter(e => !arr2.includes(e));
    console.log(differenceA);
}
logical_expression([1, 2, 3], [2, 3, 5])
    // ->[ 1 ]
```

![Web 1920 – 4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341221/648d269c-2368-72ad-bf0a-744723a80a0e.jpeg)

```js
const logical_expression = function (arr1, arr2) {
    let differenceB = arr2.filter(e => !arr1.includes(e));
    console.log(differenceB);
}
logical_expression([1, 2, 3], [2, 3, 5])
    // ->[ 5 ]
```

![Web 1920 – 5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341221/77a08ea6-33bd-92c1-94aa-d6972c45b681.jpeg)

```js
const logical_expression = function (arr1, arr2) {
    let symmetric = arr1
        .filter(e => !arr2.includes(e))
        .concat(arr2.filter(e => !arr1.includes(e)));
    console.log(symmetric);
}
logical_expression([1, 2, 3], [2, 3, 5])
   // ->[ 1, 5 ]
```
Azure Application Gatewayの課金を止めたい！

Azure Application Gatewayで提供されているWAF(Web Application Firewall)を触っているのですが、一度AzureにデプロイするとAzure Portalからは停止できないようです。

月額が結構高いんですよね。（サイズMのWAFで約15円/h、約11,000円/月）
[Application Gateway の料金 | Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/details/application-gateway/)

開発・検証中など、使わない時は停止して月額を節約したかったんですが、Azure Portalから停止するにはApplication Gatewayを削除するしかなく、また使うときには作り直す必要があるので、削除せずに停止する方法を調べました。

**2020/3/26追記**
[Application Gateway停止状態での課金状況](#課金停止の確認2020326追記)を載せました。
ちゃんと課金は止まっています。

**2020/3/30追記**
Automationを使って自動停止するシェルを作りました。
[【続】Azure Application Gatewayの課金を止めたい！（Automationで自動停止）](https://qiita.com/yoshiyuki-iwata/items/50d3690aff639d1b6332)

# どうやって停止する？
やっぱりAzure PortalのGUIから止めるのは無理！
なので、以下のどちらかの方法で停止します。

## ① ローカルPCのPowerShellから停止する

### Azure RMのインストール
まず、AzureRMをインストールし、PowerShellからAzureのコマンドを叩けるようにします。
Azureのマニュアルを参考にしてください。
https://docs.microsoft.com/ja-jp/powershell/azure/azurerm/install-azurerm-ps?view=azurermps-6.13.0

### 停止コマンド

AzureRMをインストールしたら、PowerShellから以下のコマンドを叩きます。

``` powershell:PowerShell（管理者権限のほうがいいかも）
# Application Gatewayのオブジェクト？的なものを取得する
PS C:\> $AppGw = Get-AzureRmApplicationGateway -Name [AppGwの名前] -ResourceGroupName [リソースグループの名前]

# とめる！
PS C:\> Stop-AzureRmApplicationGateway -ApplicationGateway $AppGw
```
2~3分かかるっぽいです。

### 開始コマンド

開始するときは以下のコマンドで。

``` powershell:PowerShell
# あげる！
PS C:\> Start-AzureRmApplicationGateway -ApplicationGateway $AppGw
```

10分くらいかかるっぽいです。

## ② Azure Cloud Shellから停止する

以下のアイコンを押してAzure Cloud Shellを起動します。
※初めてCloud Shellを起動すると、Storageを作れと言われるので作りましょう。
![AzureCloudShell起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/61dba156-90fa-ae75-6e5c-43ce7b5a6f93.png)


するとこんな感じでCloud Shellが起動します。
![AzureCloudShell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/8dbbcfc3-923a-e401-076d-e2aa3f91a47c.png)

あとは、①と同じコマンドで停止できます。
インストール不要なので、こっちのほうが楽ですね。

# 課金停止の確認（2020/3/26追記）

「Application Gatewayを停止しても、課金は継続する」というような記事をどこかで見かけました。

課金、止まってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/f0f56783-c84e-5ad4-9677-4fe3f2f1c836.png)

3/4頃は1日数時間起動していました。
3/14頃の急上昇は、土日あげっぱなしやっちまったなー！です。
3/18からは止めっぱなしです。

課金、止まってます。

[Application Gateway の料金 | Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/details/application-gateway/)

> Application Gateway の課金は、ゲートウェイがプロビジョニングされて利用可能になっている合計時間、および Application Gateway によって処理されたデータ量に基づいて行われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/d92229d1-20c7-007e-c278-a340759e0e18.png)

プロビジョニングはされていますが、動作状態が「停止中」なので、「利用可能ではない」という判断なのかと思われます。

# ちなみに
停止して開始すると、Application GatewayのIPアドレスが変わりました・・・。

https://docs.microsoft.com/ja-jp/azure/application-gateway/application-gateway-faq#does-the-ip-or-dns-name-change-over-the-lifetime-of-the-application-gateway
マニュアルに、V1だとIP変わるとの記載がありました。
（V2だと静的IPも可能だけど、月4万は高い・・・）
ただAzureが勝手につけてくれるホスト名（なが～い英数字.cloudnet.app）は変わらないようです。
Gatling環境構築

### 経緯
- 対して詳しくもないけど負荷試験することになった
- 知ってる負荷試験ツールはJMaterかGatlingくらい
- xml書きたくないからScalaでかけるGatling採用(Scalaも大してかけないけど)
- Localと攻撃サーバで構築変わるのめんどいのでDocker

### 構成

```
├── docker-compose.yaml
├── gatling
│   └── Dockerfile
├── nginx
│   └── default.conf
└── scenario
   ├── resources    シナリオで使うやつ置き場(user-passwordのCSVとか)
   └── simulations　シナリオのClass用ディレクトリ
```

### Gatling用環境

``` ../gatling/Dockerfile
FROM openjdk:11
ENV LANG C.UTF-8

RUN apt-get update -y \
    && apt-get upgrade -y \
    && apt-get install -y wget bsdtar

RUN mkdir /workdir && cd /workdir
WORKDIR /workdir

RUN wget -qO- https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.3.1/gatling-charts-highcharts-bundle-3.3.1-bundle.zip \
    | bsdtar -xvf-
ENV GATLING_HOME=/workdir/gatling-charts-highcharts-bundle-3.3.1
RUN ln -s /workdir/gatling-charts-highcharts-bundle-3.3.1/bin/gatling.sh /usr/local/bin/gatling && chmod a+x /usr/local/bin/gatling

```

### docker-compose
- gatling~/user-fileがシナリオ置き場なのでHostにvolumeMount
- 結果のHTMLをnginxにMountする
- とりあえず入力待ちにしとく
- そのうち立ち上げたら勝手にシナリオ走るように

``` ../docker-compose.yaml
version: "3"
services:
  gatling:
    build: ./gatling
    stdin_open: true
    tty: true
    volumes:
      - ./scenario/:/workdir/gatling-charts-highcharts-bundle-3.3.1/user-files
      - data:/workdir/gatling-charts-highcharts-bundle-3.3.1/results
    command: /bin/sh

  nginx:
    image: nginx:latest
    links:
      - gatling
    ports:
      - 80:80
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - data:/var/html

volumes:
  data:
    external: true

```

### 結果確認用のNginx設定
- マウント先をドキュメントルートに
- 結果わかりやすくするため、autoindex

``` ../nginx/default.conf
server {
    listen       80;
    server_name  localhost;
    autoindex on;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /var/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /var/html;
    }
}

```

### 実行(暫定)
- gatling.shを動かせば対話形式で実行するシナリオを選べる

```console

$ docker-compose up -d
$ docker-compose exec gatling gatling [-s TestClassName]
GATLING_HOME is set to /workdir/gatling-charts-highcharts-bundle-3.3.1
TestCodelikeAccess is the only simulation, executing it.
Select run description (optional)

Simulation TestCodelikeAccess started...
.
.
.
Reports generated in 0s.
Please open the following file: /workdir/gatling-charts-highcharts-bundle-3.3.1/results/testcodelikeaccess-20191212105057322/index.html

```

### 結果確認
- http://localhost をブラウザで開いて結果を確認
![スクリーンショット 2019-12-12 19.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177957/5530c964-2e1d-fe23-e090-1ab00414d6e7.png)
tslearnで時系列データのパターンマッチング

センサなどから得られる時系列データから、
tslearnを使ってパターンマッチングをやってみたいと思います。


## 事前準備

- anaconda3環境
- `conda install -c conda-forge tslearn`
- Jupyter Notebook

https://github.com/rtavenar/tslearn
https://tslearn.readthedocs.io/en/latest/index.html

## DTW

DTWを使って時系列データ同士の類似度を算出します。

まず、波形データとして、下記のような2種類のデータを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15008/f1ae4b9d-5631-83a9-e50e-d248d48b481d.png)


これらの波形の類似度を計算してみます。

```
import numpy as np
import pandas as pd
from tslearn.preprocessing import TimeSeriesScalerMeanVariance
from tslearn import metrics
from tslearn.utils import to_time_series_dataset
from pandas import DataFrame, Series

csv_file_names = ['down1.csv', 'up1.csv']

def generate_df(csv_file_names):
    df = pd.DataFrame()
    for i, file_name in enumerate(csv_file_names):
        csv = pd.read_csv(file_name, header=None)
        df[file_name] = csv[1]
    return df

df = generate_df(csv_file_names)

scaler = TimeSeriesScalerMeanVariance(mu=0., std=1.)
t = scaler.fit_transform(np.nan_to_num(to_time_series_dataset(df.values.T)))

path, sim = metrics.dtw_path(t[0], t[1])

### DTW 距離
sim
```

出力が下記となり、0に近ければ近いほど類似度が高くなります。

0.9090998233320118


では、少し異なる波形を比べてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15008/cee11f77-1145-de7f-488d-643677b07da6.png)


この場合、距離は下記になります。

5.773573185101321


以前は、ライブラリではなく、いちからDTWの実装していましたが、手軽になりましたね。

参考: 
https://tslearn.readthedocs.io/en/latest/gen_modules/metrics/tslearn.metrics.dtw.html

## あとがき

時系列データのクラスタリングについて書こうと思いましたが、
また別の機会にしようと思います。

時系列データのクラスタリングに関する参考記事

https://blog.brains-tech.co.jp/entry/tslearn-time-series-clustering

http://irukanobox.blogspot.com/2019/05/python.html

https://techblog.nhn-techorus.com/archives/6452
【Appium】findElementByImageの実装を追いかけてみた

## はじめに
こちらの記事は「Selenium/Appium Advent Calendar 2019」13日分の投稿です。
@kazurasaka がお届けします。

### あらすじ
それは数ヶ月前のことだった。転職した先で与えられたのはQAエンジニアの肩書。自社アプリのテスト自動化研究の始まりが訪れ、QA界隈に突如飛び込んだ私は色々と勉強することになる。

課せられた制約は２個
1. 実際に動いているsourceをテストのために変更することはできない
2. 複数タイトルに流用できるテストを構築しなくてはならない

IDで検索する方法は使えない……そんななか一つの記事が目に留まる。

画像による要素検索
http://www.selenium.jp/translation/huaxiangniyoruyaosujiansuopart1

こ、これだーーーー！！

### 本題
では見ていきましょう。

おもむろにgithubでappium縛りで「findElementByImage」と検索をかけます。
https://github.com/search?q=org%3Aappium+findElementByImage&type=Code

なんとなく関係ありそうなコード**ってjavaかよ**ってなりながら読みます（javaまともにやったことないからフィーリングで切り抜けます）
https://github.com/appium/java-client/blob/14786471f4abb85a01dfe79879d7a617cd2fc669/src/main/java/io/appium/java_client/FindsByImage.java

```java
default T findElementByImage(String b64Template) {
    return findElement(MobileSelector.IMAGE.toString(), b64Template);
}
```

次は `findElement` ね。ふむふむ。

これは探すとjsの実装を見つけられました。
https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/commands/find.js

```js
commands.findElement = async function findElement (strategy, selector) {
  if (strategy === IMAGE_STRATEGY) {
    return await this.findByImage(selector, {multiple: false});
  } else if (strategy === CUSTOM_STRATEGY) {
    return await this.findByCustom(selector, false);
  }

  return await this.findElOrElsWithProcessing(strategy, selector, false);
};
```

`custom` も気になりましたが `findByImage` のほうがそれっぽいので追いかけます。

長いので一部抜粋
https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/commands/find.js#L204

```js
const comparedImage = await this.compareImages(MATCH_TEMPLATE_MODE, b64Screenshot, b64Template, {threshold, visualize});
```

なんでこの行に目をつけたかって？引数の内容からです。

- screenshot
- template
- threshold

がありますね？

- screenshot：ベースの画像。探す対象。
- template：テンプレート画像。この画像をscreenshotから探す。
- threshold：閾値

です。
ここらへんは読む前にopenCVの画像認識を触っていたのでなんとなくわかりました。

次、 `comparedImage` を探します。
https://github.com/appium/appium-base-driver/blob/5b12eebcf011cf7676a2987b646a6394ddafb639/lib/basedriver/commands/images.js#L34

```js
case MATCH_TEMPLATE_MODE.toLowerCase():
      // firstImage/img1 is the full image and secondImage/img2 is the partial one
      result = await imageUtil.getImageOccurrence(img1, img2, options);
      break;
```

`TEMPLATE_MODE`が引数なのでこの行ですね。
`getImageOccurrence` を探します。

https://github.com/appium/appium-support/blob/23d09f4e92c099eebc5db2124434c7d17e021248/lib/image-util.js#L433

```js
const matched = await fullImg.matchTemplateAsync(partialImg, cv.TM_CCOEFF_NORMED);
```

たどり着いたーーーー！ここの実装が肝！なぜなら `matchTemplate` って `openCV` のやつだから。
このまま `matchTemplateAsync` も辿ってみるのもありですが、それは `opencv4node.js` さんの領分なので今回はここまでです。

ざっと読んでみたところ、 `matchTemplate` つまりはテンプレートマッチングで対象から検索していますね。なるほど。

なるほど？

### オチ
appium + webdriverio + mocha でやってるんですけどfindElementByImageがwebdriverioになかったね！！！！
普通にopencv4node.js直接使って構築しましたとさ。

#### 更に小ネタ
テンプレートマッチングだとやりたい画像ではmatch率イマイチだったので特徴点抽出つかって識別しました。
pecl install imagick がエラーになる場合の原因と対策

# やりたいこと


CakePHP3で

```
use Imagick;
new Imagick();
```

# 問題

```
yum install ImageMagick ImageMagick-devel
```

のあと、

```
pecl install imagick
```


がエラーになる。


# 対策

gccが無いことが原因であれば、下記を実行する。

```
yum -y install gcc
```

その後、


```
pecl install imagick
```

を再度実行する。


# 使えるようにするまで

```
pecl install imagick
```

が成功したら、

```
vi /etc/php.ini
```

で最下部に

```
extension=imagick.so
```

を追記して


```
chmod 755 /usr/lib64/php/modules/imagick.so
systemctl restart httpd
```

で、

```
new Imagick();
```

が動くようになればＯＫ。

# 確認コマンド

```
php -r "echo phpinfo();" | grep "imagick"
imagick
imagick module => enabled
imagick module version => 3.4.4
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
imagick.locale_fix => 0 => 0
imagick.progress_monitor => 0 => 0
imagick.skip_version_check => 0 => 0
```
Chrome拡張機能作成〜超基礎編〜

# はじめに
みなさんは普段、Chrome拡張機能は使ってますか？ 

動画をダウンロードできたり、デザインを変更できたり、クソアプリを作れたりと、
なかなか面白いGoogle Chromeの機能です。

実はChrome拡張機能は、シンプルな物であれば、物凄く簡単に作ることができます。
そこで今回は、Chrome拡張機能をさっくりと作りたい人向けの超さわりの部分だけを説明します。

# ゴール
作業中についつい見たくなってしまうTwitter。。。ちょっと見るはずが気づけば30分。。
そんな悩みを解決すべく、今回はTwitterをみたら叱ってくれるChrome拡張機能を作ろうと思います。
ソースコードは[こちら](https://github.com/ryo-s2000/twitter-miruna)

# 1.最低限度必要なファイルの作成

```
.
├── content.js
├── icon.png
├── manifest.json
```

```content.js
window.alert("努力だ。\n勉強だ。\nそれが天才だ。\n誰よりも三倍、四倍、五倍勉強する者、それが天才だ。\n\nby野口英世");
```
弱い自分自身に負け、もしTwitterを開いてしまったら、野口英世先生の激励の言葉が飛んできます。

```manifest.json
{
    "name": "Twitter Miruna",
    "version": "1.0.0",
    "manifest_version": 2,
    "description": "Twitterを見たら叱ってくれます。",
    "icons": {
      "16": "icon.png",
      "48": "icon.png",
      "128": "icon.png"
    },
    "content_scripts": [{
      "matches": ["https://twitter.com/"],
      "js": [
        "content.js"
      ]
    }]
}
```
作成するChrome拡張機能の設定について書いてあります。
詳しくは公式サイトをどうぞ。
https://developer.chrome.com/extensions/manifest

icon.pngには、Chrome拡張機能に登録したい画像を選択してください。

# 2.Chrome拡張機能を読み込む

1.Chromeの拡張機能管理画面を開いてください。
検索窓に「chrome://extensions/」と直接入力すると出てきます。

2.右上のデベロッパーモードをオンにしてください。
<img width="1672" alt="スクリーンショット 2019-12-12 19.28.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199666/2cb545d0-82c5-7770-c1c0-7ab2d4199dfa.png">
3.パッケージ化されていない拡張機能を読み込むを選択、作成したフォルダを指定します。

4.読み込まれると、このようなタブが1つ増えます。
<img width="410" alt="スクリーンショット 2019-12-12 19.36.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199666/11ba7f9b-3449-cf7c-3527-e2f98cab5244.png">
5.実際にTwitterを開いてみてください、このようなポップアップが出て来たら成功です。
<img width="470" alt="スクリーンショット 2019-12-12 19.34.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199666/cc9e870f-1d05-555d-66e1-57e467cac61e.png">
6こちらをoffにすることにより、ポップアップが出てこないようになります。
<img width="413" alt="スクリーンショット 2019-12-12 19.36.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199666/abe15de2-0c1c-34c6-0a14-71f0b8a3997e.png">

# まとめ
案外簡単に作れたかと思います。
皆さんもぜひ、自分だけのChrome拡張機能を作ってみてください！！

参考記事
https://qiita.com/RyBB/items/32b2a7b879f21b3edefc
https://qiita.com/suin/items/2b31079056f1356257cb
形態素解析ツール「treetager」 

# 形態素解析ツール「treetager」とは？
英語用の形態素解析ツール。

某顧客様から英文の虫食いテストを掲載したいとの要望がありました。
この「treetager」を使えば実現するんでは？とアドバイスもいただいたので、
実装してみることしました。

# どうやって使うの？

今回は、サーバにtreetager一式をインストールします。

1．[treetagerのサイト](https://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/)から4ファイルをダウンロード。
　　・Download the tagger package for your system
　　・Download the tagging scripts into the same directory.
　　・Download the installation script install-tagger.sh.
　　・Download the parameter files for the languages you want to process. 
　　（サイトより抜粋）

2．適当なフォルダに置いたら、インストール用のシェルスクリプト実行。

3．動作確認。以下のコマンドを実行。

      echo 'Hello world!' | cmd/tree-tagger-english

　 実行した結果は以下の通り。  

      reading parameters ...
        tagging ...
        Hello   UH      Hello
        world   NN      world
        !       SENT    !
         finished.

#使い方

解析された結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540410/340d0b0d-0f5a-dd07-b3db-f51764cd296c.png)


「NNの結果を除外する」と設定した場合、
ｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰ
**Q.（　　）内に入る単語は？**
（　　　　　） world!　
和訳：こんにちわ世界！
ｰｰｰｰｰｰｰｰｰｰｰｰｰｰｰ

というような問題を作成することができます。

#導入した結果
予想以上に反響がありました。
英語を勉強している人には、かなり好評です。
使い道は限られていますが、
わざわざ、問題と解答のようにデータを保持する必要はなく、
1つの英文で問題と解答をまかなうことができます。
今回のようなニッチなご要望があった場合、
提案してみるのもありかと思います。
AWS Lambdaで"ELF load command address/offset not properly aligned"のエラーが出る際の知見

# 背景
PythonでAWS Lambdaの開発をする際、Serverless Frameworkとserverless-python-requirementsプラグインを使うことがあると思います。
その際に、表題のエラーで少し詰まったので解決のために役に立ったことをまとめます。

# 動作環境
本記事は以下の環境で確認しています。

* OS : Mac OS Mojave
* Serverless Framework : 1.54.0
* serverless-python-requirements : 5.0.1

# エラーが出るまで
本記事では、以下のような構成を考えます。

```text:requirements.txt
opencv-python
```

```python:handler.py
import cv2 

def hello(event, context):
    response = {
        "statusCode": 200,
        "body": cv2.__version__
    }

    return response
```

```yml:serverless.yml
service: test

provider:
  name: aws
  runtime: python3.7

functions:
  hello:
    handler: handler.hello

custom:
  pythonRequirements:
    dockerizePip: true
    slim: true

plugins:
  - serverless-python-requirements
```

これは、単にOpenCVのバージョンを返す関数です。
これをデプロイして、`sls invoke -f hello`で実行すると以下のようなエラーが出ると思います。

```
{
    "errorMessage": "Unable to import module 'handler': /var/task/cv2/cv2.cpython-37m-x86_64-linux-gnu.so: ELF load command address/offset not properly aligned",
    "errorType": "Runtime.ImportModuleError"
}
```

本記事では、このような場面で試すことをまとめていきます。


# プラグインの設定を見直す
この`ELF load command address/offset not properly aligned`というエラーについてはプラグインの[README.md](https://github.com/UnitedIncome/serverless-python-requirements/blob/master/README.md#option-not-to-strip-binaries)に記載があり、

```yml
custom:
  pythonRequirements:
    slim: true
    strip: false
```

と書けば良いようです。ということで、serverless.ymlを書き換えて再度実行してみます。
ここでエラーが出ない場合は問題ないと思います。本記事では、ここでエラーが出た際の知見を紹介します。


# キャッシュを確認する
serverless-python-requirementsは毎回pipをしなくても良いように、キャッシュの機能を持っています。
https://github.com/UnitedIncome/serverless-python-requirements/blob/master/README.md#caching

先ほどの`strip: false`の変更ではキャッシュを利用してしまうらしく、デプロイされるパッケージには変更が反映されません。
例えば、`sls remove`などしてもキャッシュは削除されないので、`ELF load command address/offset not properly aligned`が出続けてしまいます。

したがって、

```console
$ rm -rf /Users/xxx/Library/Caches/serverless-python-requirements
```

のようにキャッシュを削除してからデプロイし直すと解決する可能性があります。
（当然、パスは環境によって変わると思います。）

# まとめ
ELF load command address/offset not properly alignedが発生したら

* プラグインの設定を確認する
* キャッシュを確認する

と良いかと思います。
他にも知見がある方はぜひ教えて下さい。
中古 PC に Linux を入れた記録 2019

これは株式会社ACCESS Advent Calendar 2019 14日目の記事です。

## はじめに

こんばんは、電子出版事業部の @aRyoKuroda です。
昨年は [ThinkPad X61 に Linux を入れて遊ぶ](https://qiita.com/aRyoKuroda/items/4d75af18f47fdd753866)記事を投稿しました。
今年はそれよりも実用的なマシンで遊んでいたのですが、あまり面白みがない気もするのでさらっとご紹介します。

## 概要

![CF-NX4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42210/19decba2-a022-5d3a-c68c-cb67c14b3883.jpeg)

今回のターゲットは Let's Note CF-NX4 です。本体（OSなしジャンク品）・ACアダプタ・換装用 SSD で1万円ちょっとしました。

## やったこと

### SSD 換装

バッテリーを外しネジを1本開けると内臓 HDD (2.5インチ、7mm) にアクセスできます。メモリ増設も可能ですが、SSD の交換で十分と判断しました。

### Manjaro Linux

[Manjaro \- Downloads](https://manjaro.org/download/)

今回も Manjaro Linux XFCE Edition を採用しました。 CF-NX4 のスペックであれば他のエディションも十分動作しそうです。なお、 64bit 版をインストールできました。

### 初期設定

#### 日本語入力

インストール時に日本語を選ぶと Noto Sans CJK が入りますが、インプットメソッドは別途、パッケージマネージャから Mozc をインストールしました。
しかしインライン入力ができなかった（変換してEnterを押すまで入力されない）ため、以下のページを参考に設定します。

[Fcitx: リアルタイム入力（インライン入力）のための設定 \- DEV Community 👩‍💻👨‍💻](https://dev.to/nabbisen/fcitx--1n59)

また、ターミナルで Noto Sans CJK を使うとあんまりイケてない感じになったので、 [HackGen](https://qiita.com/tawara_/items/374f3ca0a386fab8b305) などのプロポーショナルフォントをオススメします。

#### 照度

インストールして再起動するとディスプレイの照度がほぼ0になり画面が全く見えなくなるため、故障を疑ってしまいます。またホットキーでの照度操作が効かないこともあったため、こちらを参考に修正しました。

[Ubuntu 18\.04をインストールしたLet's note CF\-NX2で輝度調節をする \- Qiita](https://qiita.com/uluvtu/items/fd6f61770e3c6e760a4b)

### 課題

#### 復帰後

電源オンではなく、サスペンドの復帰後に画面が暗くなることがあります（全く見えなくなるほどではない）。調査不足でまだ改善していません。

#### 回転スクロール

Let's Note といえば回転スクロール！　いずれは有効にしたい。

#### Bluetooth

Logicool のマウスを使用しているのですが、たまに切れることがあります。省電力設定？

## おまけ

その他 2019年に Linux をぶち込んだ端末をご紹介……

### ThinkPad 10 2014年版

* タブレットPC はなかなか鬼門で、タッチ操作がまともに使えるウィンドウマネージャが Gnome くらいしかなかった
* Atom Z3795 はちょっときつい

### MacBook Air late 2010 11-inch

* 現在でも High Sierra までアップデート可能。ただしアップデートマラソンをすることになるためデュアルブートは辛い
    1. インストールディスクで v10.6 に初期化
    2. Firefox をインストール
        * Safari が古いためかサイトを開いても以下のインストールができなかったため
    3. Mac OS X v10.6.8 統合アップデートをダウンロードして で v10.6.8 までアップデート
        * App Store をつかうため
    4. App Store から v10.11 にアップグレード
    5. App Store から v10.13 にアップグレード
* 本体よりも初代 MagSafe の確保が問題かもしれない
* Peppermint OS で試しましたがストレスはない
* でも Retina ディスプレイでないのは気になるかも
【Rails】Twitterのリストのメンバー全員を取得したい


#概要

Twitter廃人です。
2019-12-12、PCでのリスト閲覧が出来なくなっており、俺のツイッターライフが滅亡の危機に瀕しています。
スマホでは出来るけどなんで……。

Twitterくん頑張ってるけど、ふとしたことでリスト機能自体を消しちゃったりしそう……？
そうでなくてもアカウント永久凍結されたりしたら本気でヤバいなと思い、リストのメンバーを取得しておきたいと思います。


#追記
リスト見れない問題、解決しました。
https://qiita.com/MATO/items/8af58e6db5bb3df60a84


#環境
Ruby2.5.3
Rails5.2.1


#前提

TwitterAPI使えるようにするまでとかは他記事でお願いします。

gemで'twitter'を追加してbundle installするだけで良かった気がする。
他にもやった気もする。

忘れました


#Model

```ruby:app/model/tweet.rb

class Tweet < ApplicationRecord

  # --- Twitter API ---

  # APIに接続するためのクライアント生成
  def self.get_client
    client = Twitter::REST::Client.new do |config|
      # applicationの設定
      config.consumer_key           = Settings.consumer_key
      config.consumer_secret        = Settings.consumer_secret

      # ユーザー情報の設定
      config.access_token           = Settings.access_token
      config.access_token_secret    = Settings.at_secret
    end

    return client
  end

end

```

# 共通設定ファイル
使うために何入れたかは忘れました……。

```yml:config/settings.local.yml
# Twitter OAtuh Setting
consumer_key:     "NAISYODAYODAYO"
consumer_secret:  "NAISYODAYODAYO"

access_token:     "NAISYODAYODAYO-NAISYODAYODAYO"
at_secret:        "NAISYODAYODAYO"
```


# Console

```rails c```で入るやつ

```shell
> c = Tweet.get_client

> c.lists.each { |list| p list.slug }
```

必要なのはリストのslug……とのことですが、リスト名そのままでいいかも。
けど一応取っておいた方が良さそう。

```
> c.list_members('screen_name','お気に入り').each { |member| 
> p member.id.to_s + "," + member.screen_name.to_s + "," + member.name.to_s 
> }
```

#まとめ

これでtwitter_id,screen_name,nameのCSVデータっぽいの取れますね。
screen_name（＠なんとか）は変えられるので、一応twitter_id取っておいた方が良いと思います。

アカウントが何度死んでも、俺はお前らを逃さねぇからな……❤


# 注意点

APIの回数制限ありますが、だいたい15分ごとの制限です。
なので「多すぎ！」で怒られても、しばらく待つだけで使えると思います。

終わり


#参考にさせて頂いたサイト

##twitter-rubyのGit
https://github.com/m92o/twitter-ruby

##メソッド一覧
https://sites.google.com/site/gyakuhikiruby/home/twitter-gem#TOC--4

Twitter公式のやつ見てもメソッド名違うから超助かりました。
他のことしたくてもこれ見れば良さそう

##REST-APIの解説
http://westplain.sakuraweb.com/translate/twitter/Documentation/REST-APIs/Public-API/GET-lists-members.cgi
Qiita Advent CalendarのランキングをPythonでスクレイピングしてみた

QiitのAdvent Calenderには、ランキングが公開されてます。
[全体カレンダーランキング](https://qiita.com/advent-calendar/2019/ranking/feedbacks/all)

最初は、面白カレンダーを見つけることが目的でちょいちょい見てましたが、よくよく見てみると、弊社もランキングされてました！:clap::clap:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77333/77426e99-34c7-4496-8c8c-d4af2eb8dd90.png)

ただし、いいね数が1でもランキングされているので、まあ当然なんですけどね。

ランキングされていることを知ってから、**「今日のランキングは何位かな？」**を初めて３日目。
これは面倒くさい・・・

「QiitaにAPIがあるから、それでランキング取れるやろ」と、ランキング取得を自動化することにしました

## APIがないならスクレイピング！
QiitaにはAPIがあります。ここです→[Qiita API v2の仕様](https://qiita.com/api/v2/docs)
しかし、ドキュメント見ても、Advent CalenderのAPIが無い:sob:

APIが無いならPythonでスクレイピングしてみることにしました。
`Python スクレイピング`で検索すると、[Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/)が多くヒットしましたので、**Beautiful Soup**を使うことにしました。

# スクレイピングは簡単だ
目的は明確です。自分の会社のランキングを取得することです。HTMLタグを調べて見ました。

![スクリーンショット 2019-12-12 19.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77333/3e8fa6a8-9071-853c-9008-719203022836.png)

ランキングの数字を取得するには、カレンダーリンクの`<a class="adventCalendarRankingListItem_calendarName">`から２個上に昇ってテキストを取得すればよさそうです。

BeautifulSoupを使ってコードにしてみました。

``` python
from urllib import request
from bs4 import BeautifulSoup

targethref = '/advent-calendar/2019/fork'

def main():

    url = 'https://qiita.com/advent-calendar/2019/ranking/feedbacks/all'
    targetclass = 'adventCalendarRankingListItem_calendarName'

    response = request.urlopen(url)
    soup = BeautifulSoup(response,features="html.parser")
    ranking = soup.find('a',class_=targetclass,href=targethref).parent.parent.contents[0].text
    response.close()

    print(ranking)


if __name__ == "__main__":
    main()
```
これだけです、とっても簡単です！
**BeautifulSoup** 素晴らしい！（スクレイピングできる他のライブラリを知らないので、自分の感覚です）

*自分の好きなカレンダーのランキングを取得したい場合は、4行目の`targethref=`を書き換えてください。*

# おわりに
このロジックをAWS Lambdaにのっけて、1日1回実行してます。実行した結果は、社内のChatツールに投げて情報を共有するようにしました。

APIが公開されてなくても、スクレイピングでもいけるなと認識した1日でした:sunny:


----
:fork_and_knife: [FORK Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fork)
私が書いたAdvent Calenderの記事は[こちら](https://qiita.com/izanari/items/cb15017661c45efe12d9)です
【GAS+TypeScript】開発環境を構築する

GoogleAppsScriptをローカルかつTypeScriptで開発するための環境を構築してテンプレートリポジトリを作成しました。

## 必要なもの

- Node.js
- エディタ(僕はVisual Studio Code)
- Googleアカウント

## 手順

### `clasp`の導入

[`clasp`](https://github.com/google/clasp)というGoogleが提供しているGoogleAppsScriptにアクセスするCLIツールを利用します。

```
npm install -g @google/clasp
```

https://script.google.com/home/usersettings
上記URLでGoogleAppsScriptAPIを利用可能にします。

Googleアカウントに`clasp`でログインしておきましょう。

```
clasp login
```
実行するとブラウザが起動するので

![GoogleLogedIn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299625/7eafddee-cf59-9795-ed77-7179bdfb7965.png)
Googleアカウントを選択して

![GoogleLogedIn2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299625/09c2bafd-7935-ac38-7613-cb828e22ae41.png)
許可をクリック。

これで`clasp`からGASを操作する権限付与ができました。

### プロジェクトテンプレート

先駆者たちのお知恵をお借りして作りました。
https://github.com/stin-dev/gas-ts-template

イメージは下記のような感じ。

- `src`配下でTypeScript開発
- src以下のtsファイルをWebpackでバンドルして`dist/index.js`を作成
- `clasp`で`dist/index.js`をGASにアップロード

#### 経緯
`clasp`はTypeScriptに対応しているのでtsファイルをそのままアップロードしても実行可能なのですが、`import`, `export`などモダンな記法に対応していないので少し処理が大きくなってモジュール分割したいと思ってもできません。
なのでデプロイ時にWebpackで一つのjsファイルに圧縮することで開発中はモダンな記法を利用することが可能になります。


#### 参考記事

[[GAS] TypescriptでGoogle Apps Scriptの開発を加速する](https://qiita.com/jerrywdlee/items/a037bb7764b0671d4059)
[Google Apps ScriptをTypeScriptで書いてWebpackでbundleする](https://qiita.com/nsawa/items/96c5300c811856024789)

## 使い方

プロジェクトをクローンしてパッケージをインストールしておきます。

```
git clone https://github.com/stin-dev/gas-ts-template <your-project-name>
cd <your-project-name>
npm install
```

gitのリモートURLを書き換えておきます。

```
git remote set-url origin git@github.com:<your-account>/<your-repository-name>.git
```

`clasp`で新しいGASプロジェクトを作成します。

```
clasp create --type standalone --title "Your GAS Project Name" --parentId "1D_Gxyv*****************************NXO7o" --rootDir ./dist
```

[Webコンソール](https://script.google.com/home)に新しいプロジェクトが追加されます。
![GASConcole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299625/7500feb7-4c69-dce2-be59-dcde1b3019d0.png)

実行する関数は`src/index.ts`内の`global`オブジェクトに挿入していきます。

```ts:src/index.ts
global.hello = () => { console.log("Hello GoogleAppsScript!"); }
```

こうすることで[Webコンソール](https://script.google.com/home)で`hello`関数が実行可能になります。


<hr/>

GoogleAppsScriptは処理の定期実行をしたりGoogleの種々なサービスと連携できて便利ですが、Webエディタで書くのは非常に苦痛です。
TypeScriptを導入することでコーディングの自動補完も効くしWebpackでフォルダ分割もできるし今後は楽に開発できそうです。
Pandocの環境構築を素早く行う方法

このブログは[Pandoc Advent Calendar 2019 \- Adventar](https://adventar.org/calendars/4338)の12日目のブログです。

Pandocはmarkdown記法で修飾されたテキストをHTMLやPDFに変換したり、MediaWikiなどの別記法に変換したりといった変換処理を得意とするコマンドラインツールです。

# この記事を書くに至った動機

今回受託で作ったアプリのマニュアルをいちいちPDFで出力するのが面倒だったので、Pandocを使ってPDFを出力したい と思いました。

ただ、Pandocや、そこからPDFを出力するのに使うLaTeXのセットアップは結構面倒 という話を聞いていたのでどうしようかと思っていました。

ただ、実際調べてみると割と簡単に環境構築できる方法がわかったので、それを書きます。

## といっても、そんなたいしたことはないのですが

タグがネタバレになっている気がしますが、Chocolateyを使います。

ChocolateyはWindowsデスクトップアプリ用のパッケージ管理ツール。Linuxを使っている方はapt-getやyumのようなものだと思ってもらえれば。

Pandocのインストールはここから行うことができます

```powershell
> choco install -y pandoc
```

次にLaTeXですが、こちらはChocolateyからインストールすることができません。

ただ、Pandocのマニュアルを見ると、PDF化には[wkhtmltopdf](https://wkhtmltopdf.org)を使うことも可能とあります。最近はこちらを使ってPDFを作成することもできるようになったんですね。

こちらはChocolateyにありますので、これをインストールします。

```powershell
> choco install -y wkhtmltopdf
```

コマンドラインでPandocを呼び出すとき、次のコードを書けば、wkhtmltopdfを使ってPDF出力ができます。

```powershell
> pandoc [mdfile] -t html5 -o [pdffile]
```

また、ページ数などのフッタを付与したい場合は、次のように返還対象のMarkdownファイルの文頭に**フッタのHTMLファイルを**指定します（HTMLタグではないので注意！）

```md
---
footer-html: footer.html
---
```

```html:footer.html
<html><head><script>
  function subst() {
    var vars={};
    var x=document.location.search.substring(1).split('&');
    for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
    var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
    for(var i in x) {
      var y = document.getElementsByClassName(x[i]);
      for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
    }
  }
  </script>
  </head>
  <body style="border:0; margin: 0;" onload="subst()">
  <div style="text-align: center;">
    Page <span class="page"></span> of <span class="topage"></span>
  </div>
  </body>
  </html>
```


これを適当に呼び出すPythonなりPowerShellなりのコードを作成すれば、気軽に最新のマニュアルを作成することができます。

どうぞおためしあれ。
掃除当番つぶやきボットを作ってみた

## はじめに

お掃除当番を抽選し、Mattermostに発言するボットです。
抽選されるとちょっとした楽しみになりますよ。

<img width="1029" alt="スクリーンショット 2019-12-12 19.13.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/0be6a424-f721-5925-07ef-1e512ba8ce57.png">

## インストール

1. [GitHub](https://github.com/radiance1104/tweet-cleaning-bot)からファイル一式をクローンもしくはダウンロードする

1. Mattermostにボット用のアカウントを登録する

1. Node.jsをインストールする

1. モジュールをインストールする

    ```
    $ npm ci
    ```

1. `app/environment.ts`ファイルを設定する

1. ビルドする

    ```
    $ npm run build
    ```

## 発言させる

  ```
  $ npm start
  ```

  定時実行させたい時はcronなどを利用してください。

## 利用しているモジュール

* @types/node
* request
* typescript

## さいごに

よければいいねをお願いします。
Python で LINE にメッセージを送信（LINE Notify）

# はじめに
LINE Notify を Python で利用し、LINE にメッセージを送信するボットの備忘録です。

手順は、以下になります。

1. LINE アカウントの作成と LINE Notify のサービス登録
2. メッセージを送信


# 環境
+ Windows 10 Pro
+ Python 3.6.9 (anaconda)

# LINE Notify を利用するために
## LINE Notify とは
[LINE Notify 公式サイト](https://notify-bot.line.me/ja/)には、以下の説明があります。
>Webサービスと連携すると、LINEが提供する公式アカウント"LINE Notify"から通知が届きます。
>複数のサービスと連携でき、グループでも通知を受信することが可能です。
>
>LINE Notifyと連携を行うことで、LINEユーザーが簡単にサービスの通知を受信できるようになります。

# LINE アカウントの作成と LINE Notify のサービス登録
## LINE アカウントの作成
割愛します。

## LINE Notify のサービス登録
1. アカウントを作成したら、[LINE Notify 公式サイト](https://notify-bot.line.me/ja/)にアクセスして LINE アカウントでログインします。その際、LINE アカウントに登録されているメールアドレスでログインとなりますので、事前に登録が必要です。
2. [LINE Notify 登録サービス管理ページ](https://notify-bot.line.me/my/services/)より、サービス名やサービス概要などの必要事項を入力し、サービスを登録します。
3. [LINE Notify マイページ](https://notify-bot.line.me/my/)より、トークン名と通知を送信するトークルームを指定し、アクセストークン情報を取得します。アクセストークン取得後、トークルームの友だちに LINE Notify が登録されます。

メールアドレスの登録は、以下のサイトをご参照下さい。

+ [ヘルプセンター | LINE　メールアドレスを登録するには？](http://help.line.me/line/mac/?contentId=20002406)

# LINE Notify を利用し、メッセージを送信
```Python
import requests

url = "https://notify-api.line.me/api/notify"
access_token = 'xxxxxxxxxxxxxxxx'


class LineNotify:
    
    def __init__(self, url, access_token):
        self.url = url
        self.headers = {'Authorization': 'Bearer ' + access_token}

    def send_message(self, message, image=None, sticker_package_id=None, sticker_id=None):
        
        payload = {
                'message': message, 
                'stickerPackageId': sticker_package_id, 
                'stickerId': sticker_id
                }
        
        files = {}
        
        if image != None:
            files = {'imageFile': open(image, 'rb')}
            
        r = requests.post(
                self.url, 
                headers=self.headers, 
                data=payload, 
                files=files
                )


## メイン
if __name__ == '__main__':
    
    bot = LineNotify(url, access_token)

    bot.send_message('このメッセージはテストです。')
```

# 送信結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425339/59dfa325-dc3a-f0a8-6dad-23b3e34e33ca.png)
matter-jsで発射とヒット判定でobj削除

発射した玉に当たったオブジェクトを消すだけのプログラム

###発射した玉に当たったオブジェクトを消す

<p class="codepen" data-height="520" data-theme-id="dark" data-default-tab="result" data-user="mmt-codepen" data-slug-hash="oNgLzZY" style="height: 520px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="matter-jsで発射とヒット判定で消す">
  <span>See the Pen <a href="https://codepen.io/mmt-codepen/pen/oNgLzZY">
  matter-jsで発射とヒット判定で消す</a> by MMT (<a href="https://codepen.io/mmt-codepen">@mmt-codepen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

###参考サイト

List of plugins
https://github.com/liabru/matter-js/wiki/List-of-plugins

demo
https://brm.io/matter-js/demo/#mixed

物理演算エンジンMatter.jsを触ってみた
https://magnets.jp/web_design/coding/8495/

matter-collision-events
https://github.com/dxu/matter-collision-events
AKS トラブルシュートのために Cluster Node に SSH する

AKS の運用をしていると、メンテナンス、トラブルシューティング目的でサーバーへ　SSH したくなることがあります。今回の記事では、AKS Cluster Node へ SSH する方法を見ていきたいと思います。

#SSH アクセス用の仮想マシンスケールセットを構成する
SSH アクセス用の仮想マシンスケールセットを構成するには、クラスターの仮想マシンスケールセットの名前を見つけ、そのスケールセットに SSH 公開キーを追加する必要があります。
まずは、`az aks show` コマンドで AKS クラスターのリソースグループ名を取得したあと、`az vmss list` コマンドでスケールセットの名前を取得します。
※どちらも Azure Portal から確認できるので、すでに把握できいる場合はその値をそのまま挿入します。

```
CLUSTER_RESOURCE_GROUP=$(az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv)
SCALE_SET_NAME=$(az vmss list --resource-group $CLUSTER_RESOURCE_GROUP --query [0].name -o tsv)
```
次に、SSH キーを仮想マシンスケールセット内のノードに追加します。以下二つのコマンドで完了します。尚、AKS ノードの規定のユーザー名は azureuser です。

```
az vmss extension set  \
    --resource-group $CLUSTER_RESOURCE_GROUP \
    --vmss-name $SCALE_SET_NAME \
    --name VMAccessForLinux \
    --publisher Microsoft.OSTCExtensions \
    --version 1.4 \
    --protected-settings "{\"username\":\"azureuser\", \"ssh_key\":\"$(cat ~/.ssh/id_rsa.pub)\"}"

az vmss update-instances --instance-ids '*' \
    --resource-group $CLUSTER_RESOURCE_GROUP \
    --name $SCALE_SET_NAME
```

スケールセットを追加したあとに、Node の一覧を取得します。Cluster 上で起動している Node 一覧が取得できるので、トラブル対応したい Node の IP アドレスをメモしておきます。

```
$ kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE   VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE  KERNEL-VERSION      CONTAINER-RUNTIME
aks-nodepool1-38358128-vmss000000   Ready    agent   43m   v1.13.12   10.240.0.4    <none>        Ubuntu 16.04.6 LTS  4.15.0-1061-azure   docker://3.0.7
aks-nodepool1-38358128-vmss000001   Ready    agent   43m   v1.13.12   10.240.0.5    <none>        Ubuntu 16.04.6 LTS  4.15.0-1061-azure   docker://3.0.7
aks-nodepool1-38358128-vmss000002   Ready    agent   43m   v1.13.12   10.240.0.6    <none>        Ubuntu 16.04.6 LTS  4.15.0-1061-azure   docker://3.0.7
```

#SSH 接続を作成する
AKS ノードへの SSH 接続を作成するには、AKS クラスターでヘルパー　Pod を実行します。ヘルパー Pod を実行することで、クラスターへの SSH アクセスが提供され、SSH ノードアクセスが提供されます。

```
kubectl run -it --rm aks-ssh --image=debian
```

ターミナルセッションがコンテナーに接続されるので、apt-get で SSH クライアントをインストールします。

```
apt-get update && apt-get install openssh-client -y
```
このコマンドが環境したら、`kubectl get pods` してみます。SSH 用の Pods が作成されているのが分かります。

```
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
aks-ssh-6fd7758688-l5fhr   1/1     Running   0          36m
```

SSH キーを Pods にコピーします。そのあとでコンテナーへのターミナルセッションに戻り、id_rsa SSH 秘密キーに対するアクセス許可を読み取り専用に更新します。

```
kubectl cp ~/.ssh/id_rsa aks-ssh-6fd7758688-l5fhr:/id_rsa　(Azure CLI で実行)
chmod 0600 id_rsa (コンテナーターミナルセッションで実行)
```

ここまで出来たら SSH の準備は完了です。あとは `ssh -i id_rsa azureuser@IPアドレス` を実施することで、トラブルシュートをしたい Node にアクセスすることが可能です。

#参考
メンテナンスまたはトラブルシューティングのために SSH を使用して Azure Kubernetes Service (AKS) クラスター ノードに接続する
https://docs.microsoft.com/ja-jp/azure/aks/ssh#create-the-ssh-connection
micro:bitの拡張ブロックを一番簡単(?)に作ってみた

この記事は[micro:bitアドベントカレンダー2019](https://qiita.com/advent-calendar/2019/microbit)の10日目です。
遅刻です…

# micro:bitの拡張ブロックを作る3つの方法

## pxtを使う
[micro:bitのMakeCode拡張ブロックをつくる](https://qiita.com/yokobond/items/00ed26289a3d3130c20c) 

一番わからなかったなぁ
失敗しました

## githubを使う
[ブラウザだけで micro:bit javascriptブロックエディター用パッケージ（拡張）が作れるGitHub package authoring](https://qiita.com/asondemita/items/0da65f1dc1ab24918af4)

成功しました
もし子供に教えるときにgitから教えるの大変かなぁと
サイトも横断するし…
microbitのサイト内のMakeCodeエディタ画面だけで作成できたので共有します

## カスタムブロックを作る

新規プロジェクトを立ち上げ、「JavaScript」タグへ

[![Image from Gyazo](https://i.gyazo.com/6fd2b3b2eb0483d205ed8b961d2f3ba2.png)](https://gyazo.com/6fd2b3b2eb0483d205ed8b961d2f3ba2)

左下のエクスプローラーから「＋」ボタン

[![Image from Gyazo](https://i.gyazo.com/b22c51da17a079b34d88dd0885c8c6a6.png)](https://gyazo.com/b22c51da17a079b34d88dd0885c8c6a6)

カスタムブロックを作成、「つづける」ボタン

[![Image from Gyazo](https://i.gyazo.com/35b93650cdb8dbb1ad1d4d53ca3fe607.png)](https://gyazo.com/35b93650cdb8dbb1ad1d4d53ca3fe607)

すると「custom.ts」が追加されている

[![Image from Gyazo](https://i.gyazo.com/03b680f9a969f46613856e1e3d66fa8f.png)](https://gyazo.com/03b680f9a969f46613856e1e3d66fa8f)

最初から書かれているコードによって「Custom」ブロックがすでにできている

[![Image from Gyazo](https://i.gyazo.com/92479874da3cceae9cebd5e244d8d7c3.png)](https://gyazo.com/92479874da3cceae9cebd5e244d8d7c3)

コードを自作して

[![Image from Gyazo](https://i.gyazo.com/9d3d3c4f0048081fe15f5d82361dd63e.png)](https://gyazo.com/9d3d3c4f0048081fe15f5d82361dd63e)

```
//% weight=70 icon="\uf075" color=#555555 block="点がコロコロ"
namespace comment {
    let x = 2;
    let y = 2;
    //% blockId=show_strings block="点がコロコロ %v"
    export function noaction(): void {
        led.unplot(x, y);
        x += input.acceleration(Dimension.X) / 1000;
        y += input.acceleration(Dimension.Y) / 1000;
        x = Math.constrain(x, 0, 4);
        y = Math.constrain(y, 0, 4);
        led.plot(x, y);
    }
}
```

セーブをしっかりと
すると「ブロック」タブではまだ「Custom」だけども「Javascript」タグ内で書くと候補がでてくるので動作できる

[![Image from Gyazo](https://i.gyazo.com/4ae3b19f91054d5d0ddc30058151c4c0.png)](https://gyazo.com/4ae3b19f91054d5d0ddc30058151c4c0)

一度「ブロック」タグへ行っちゃうとエラーや警告がでず、コード消えちゃうし

[![Image from Gyazo](https://i.gyazo.com/dff6a9ff16f1416cf6e400374c503335.gif)](https://gyazo.com/dff6a9ff16f1416cf6e400374c503335)

ブロックを出すには今の所プロジェクトをセーブしてもう一度立ち上げるのしかわかってないです…

[![Image from Gyazo](https://i.gyazo.com/3f8c0f069de60b85b2ad0ab3d6e59304.png)](https://gyazo.com/3f8c0f069de60b85b2ad0ab3d6e59304)

「ずっと」のところに「update」をすれば常に加速度によってLEDが移動する拡張ブロックができました！
エミュレーターですができています

[![Image from Gyazo](https://i.gyazo.com/a5bd6bc53e80871fd09e878820baa69f.gif)](https://gyazo.com/a5bd6bc53e80871fd09e878820baa69f)

# カスタムブロック所感
他の作り方と比べて初動が楽なのはあるが、他の人にシェアはもちろん、プロジェクトを渡っての利用もできなさそうです。
MakeCode内で書くのは逆に動作が見えるのでよいです。
半端にvscodeなどでgitにコミットってやろうとしてもvscode内でエラーがでちゃう感じになりますし。
なので、実はgitからもってきた拡張コードも、MakeCodeエディタ内で編集でき、pushもできちゃいますので、欠点はそれほど感じません。

# 最後に
[micro:bitアドベントカレンダー2019](https://qiita.com/advent-calendar/2019/microbit)まだまだこれからですので、ご注目＆飛び入り参加しちゃってください！
Visual Studio Codeでのカスタマイズ（主にpython用）したのでまとめてみる

VScodeでのカスタマイズ方法に関する記事はたくさんありますが、一発で終わりになるようなページはない（人によって用途が違うので当然ではある）ので自分のカスタマイズについてまとめてみることにしました。

まずは自分がVScodeをどのように使うか、また使いたいかについて書いていきます。

##VScodeの用途

一番多いのはpythonのコードを書くことになります。これは機械学習を研究で主に使っているのでここを書きやすくしたいという思いがあります。
jupyterという選択肢もありますが、カスタマイズ性の問題からあまり使いたくないなという思いがあります。（完全に好き嫌い）


また、すべてを任せていいものかとも思いますが趣味で作っているFlaskを使ったWebアプリケーションもVScodeを使って書きたいとも思っています。

さらにGitHubでのバージョン管理も行いたいため、その辺も楽にできるようにしたいです。

最後にキーバインドを使えるようにしてマウスに手を動かさずにコードを書けるようにしたい（なりたい）です。

これは願望ですが以前に挫折したvimのキーバインドを使いこなせるよう勉強します。

大体この辺が現在考えている用途です。

読んでわかる通り駆け出しプログラマー感があふれる自己紹介のようになりましたが、上記のことを実現していくためにVScodeをカスタマイズしていきます。（すでに導入しているものについても備忘録的に書いていきます）

雑感は自分で書いていきますが、導入についてはリンクを張っていきます。


###VScode日本語化

導入方法
https://qiita.com/nanamesincos/items/5c48ff88a4eeef0a8631

手前味噌ですがまずは自分の日本語化の記事です。


日本語化については個人的にはやるべきではないかもしれないと思っています（海外の情報に当たれず、二次情報やそもそも情報を得られないことがあるため）。

しかしながら自分の英語力の問題でVScodeの利用に差し支えることがあるので日本語化しています。


英語圏でのVScodeベストプラクティスみたいなやつを参考にしてみたい。


###TabNineによる補完機能

導入方法
https://qiita.com/blue0513/items/2634fcb3757629124c87

これに関してはまああっていいかなぐらいの印象。AIのすごさを実感するほどコードをかけていないだけかもしれない。

ふつうにVScodeのpython系拡張機能を普通に入れえるだけで十分に使える。

ただかっこいいので入れている感じ。


###Python Extension Pack

導入リンク（ここからインストールクリックすればいいはず。というかVScodeで.pyファイル開くと入れろって言われる）
https://marketplace.visualstudio.com/items?itemName=donjayamanne.python-extension-pack

いろんなpythonお役立ち拡張機能の数々を自動でインストールしてくれる愛いやつ。

とりあえずこれ入れとけばpythonコード書き始められる。これを入れよう。


###Visual Studio IntelliCodeによる補完

Python Extension Packに入っている様々な言語に対応した補完機能。

とてもすごい（）。

真面目に一番重宝している。統合開発環境に負けない補完がきくので（そもそもVisualStudioの補完機能なので統合開発環境由来なのだが）
これがないとコードを書いていられないとすら感じる。

（こいつもAI由来だったかも。そうしたらこれだけでいいのでは？）

###Anaconda PromptをVScode上のターミナルで利用できるようにする

拡張機能ではないが導入方法
https://qiita.com/_meki/items/5b4f06318f1a0986c55c

自分は機械学習用にpythonのコードを書くことが多いのでAnacondaを使って計算系のライブラリは一括で入れています。

それ以外にも仮想環境の作成などでAnacondaの機能を利用するのでVScodeのターミナル上でAnaconda Promptが使えるかどうかは快適さに強く影響してきます。

いろいろな諸事情からpython2系統を使う羽目になっているので仮想環境は不可欠です。

しかし、設定をいじらないとPowershellかコマンドプロンプトしか利用できないので導入しました。

わざわざ別ウィンドウでAnaconda Promptを開く必要がなくなり快適です。

setting.jsonの勉強をしないとなあ。


###pythonのフォーマットを自動化する

導入方法
https://qiita.com/firedfly/items/00c34018581c6cec9b84

VScodeでコードが真っ赤っかになって構文エラーが見にくいと思っていたので導入
結果的に規則に従ったコードが自動生成されて可読性が上がったし、エラーも見やすくなったので万々歳です。

##まとめ

とりあえず現在使っているものはこの辺です。

備忘録でもあるので随時更新していきたいと思います。
AWS上のlinuxで動かしているflaskサーバーを半永続化(バックグラウンド実行)した日

aws上のlinuxサーバー起動時、sshログインが切れるとサーバーが落ちちゃうので解消したい！

こんな感じで起動すればいいっぽい！

```ruby:
nohup COMMAND >out.log 2>err.log &
```

flaskファイルrun.pyを起動するときは以下のようにコマンドした。

```ruby:
nohup FLASK_APP=run.py FLASK_DEBUG=1 nohup flask run --host='0.0.0.0' --port=5000 >out.log 2>err.log &
```


#参考
https://www.ukeyslabo.com/linux/ps-bg/
↓ほぼこちらの記事ママです
https://mick3355-dev.hatenablog.com/entry/2018/04/16/125133
その面倒、本当に必要？

割と前から無人レジだの、自動化だのに対して「温かみがない」「手抜きだ」みたいな見方をされる風潮があるみたいですが、
そういう方達は効率化という概念がないのでしょうか。

私はとても面倒くさがりなので、作業における一挙手一投足に少しでも滞りがあると面倒臭ぇと思ってしまいます。
例えば、webページを閲覧中、ページの一番下までスクロールをしたい時。
マウスホイールをカリカリ回すよりも、macだったらcommand + ↓キーを押せばよいのです。
(windowsだったらendキーを押すだけ)

割と疑問なのが、こういう動作を効率的なやり方を調べずに手間をかけてる人が多い気がするということ。
私は作業中、マウスカーソルを動かすことすら面倒だと思ってるので、なるべく最小手数で作業を行いたいと思っています。

少しでも面倒、非効率だと思った瞬間に調べる癖をつけていれば、割と楽になることが多いと思うのです。
それはコーディング中に限らず、様々なソフトを触っている時や、ブラウジングをしている時でも。
では、どんな時にどういう風に考えれば良いか？
例えば、マウスカーソルを動かすのが面倒な時。
割とこれ結構あると思います。そもそもそういう時のためにショートカットキーなどがあるとはおもうのですが、
わからないのがわからない状態といいますか、自分では普通にやっているつもりが、実はもっと楽に作業を行える方法があったりします。煩わしさを感じられるかどうかだとは思いますが、何かいい方法ないかなと思った瞬間には調べましょう。

ショートカット一覧や便利ツールなどは恐らく調べれば大量に出てくると思います。

上記は作業中に煩わしく思った場合に心がけようという話をしていますが、
そもそも効率化を念頭において作業した方がいいよなと思ってます。

調べ方がわからなかったら人に聞けばいいですし、周りに人がいなかったらteratailやスタックオーバーフローなどで書き込んでもいい。とにかく考えることを止めないことが大事なのでは、と思います。

調べないままマウスをポチポチするより、ショートカットやツールを使いこなしてより楽(負担が少ない)な作業を行いましょう。
Nutanix Xi IoTを試してみよう(2) サンプルアプリで動作確認

# はじめに
この記事は、[[2枚目]Nutanix Advent Calendar 2019](https://adventar.org/calendars/4014) 12月11日の分として作成しました。本記事の内容はこの日付の情報に基づいています。

前回の記事では、Xi IoTで提供されている10日間の無償トライアルの開始の仕方をご紹介しました。
本記事ではサンプルアプリを使用した動作確認の方法をご紹介します。


#サンプルアプリの利用方法
Xi IoTでは、初期状態からいくつかのアプリケーションがサンプルとして登録されています。その一つ、スマートフォンのXi IoT Sensorアプリを使用して、物体検出を行う"phone-object-detection"はすぐに利用できる状態になっています。こちらを使用してXi IoTの動作を確認しましょう。

## Xi IoT Sensorアプリの操作

スマートフォンにインストールされたXi IoT Senserアプリから操作します。

- Xi IoT Senserアプリを起動します。トップ画面に"phone-object-detection"のメニューがあるのでクリックします。
<img width="375" alt="Xi IoT Sensor画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/7e425265-3456-6e66-bfdb-5e10440658ea.jpeg">

- 動画をXi IoTのサービスドメインに送信する方法を選択します。今回は”Use Camera”を選択します。Wifi接続でない場合は警告がでます。

<img width="375" alt="カメラ選択メニュー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/14c4591a-08fc-5d33-828f-4dea6a6c2b07.jpeg">


- しばらくすると下図のような画面でリアルタイムの物体認識が開始されます。左上の小さい画面がリアルタイムの画像で、大きな画面はエッジで物体認識がなされた処理後の画像です。
<img width="375" alt="物体認識" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/dd37b937-05d5-3896-af08-70b6f2a58710.jpeg">



## Xi IoTコンソールの確認
Xi IoTの管理コンソールから"phone-object-detection"を確認しましょう。

- 左上のメニューから"App and Data"→ "Data Pipelines"を選択します。
- 登録済みのデータパイプラインの一覧が表示されるので、"phone-object-detection"をクリックします。
<img width="1268" alt="Data Pipelines画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/e2d9dc7f-37b5-bc46-10f9-ea6ceee5ffbd.png">

- "phone-object-detection"アプリケーションのダッシュボードが表示されます。Summary画面からはどの程度のリソースが消費されているか、Deployment画面からはどのサービスドメインにアプリケーションが配信されているかを確認できます。初期状態ではxi-cloudサービスドメインに配信されているはずです。

<img width="1435" alt="サービスドメイン" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/f61b91e1-7ba4-d9fd-0a85-02209e9422ad.png">

- Summary画面の左上にある"View Live Stream"をクリックするとスマートフォンのXi IoT Sensorと同様の物体認識の画像ストリームが出力されます。

<img width="1440" alt="Live Stream画面
" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/f8132f32-d6ec-6860-f03a-ca20a3e0d913.png">

# アプリケーションの中身を確認

"phone-object-detection"アプリケーションの中身を確認してみましょう。

- "phone-object-detection"アプリケーションのダッシュボードから"Edit"をクリックします。
- Input(データの入力元)、Transformation(処理の内容)、Output(出力先)が確認できます。このアプリケーションでは、Xi IoT Sensorアプリを入力元として、"objdetect_func-python"という処理を実施後に、サービスドメインに対してLive Streamを出力しています。
<img width="1264" alt="データパイプライン編集画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/fe098757-95b1-088c-93ef-4823435079de.png">

"objdetect_func-python"の中身を見てみましょう。
- 左上のメニューから"App and Data"→ "Functions"を選択します。
- 登録されているファンクションのリストより、"objdetect_func-python"を選択

<img width="1259" alt="Functions画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/baa45f99-a43b-f570-a233-676c4c73692b.png">

- Edit → Next を選択すると、コードを確認することができます。

<img width="1265" alt="Function編集画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83432/87ce64ab-9f82-38f3-ffe2-2c1b3f8b1490.png">

# 終わりに
Xi IoTに最初から登録されているサンプルアプリを使って、動作確認する手順をご紹介しました。とりあえずトライアルを開始したけれど、どこから始めたら良いかわからない。という場合は、この辺りから手をつけてみるとわかりやすいかと思います。
Shopifyの開発で知っておくと便利なツール

## はじめに

Shopifyのテーマ開発もしくはアプリ開発どちらでも知っておくと便利なツールを紹介したいと思います。

## Add Cart Attributes

注文詳細ページでNote Attributesを追加することが出来るようになります。
Note Attributesの値を元に開発をする際に気軽に追加が出来て便利です。
[Add Cart Attributes](https://chrome.google.com/webstore/detail/shopify-add-cart-attribut/ndabhcdbgabeekhnhpafnochallhfhio
)

## Shopify Developer tools

ダミーデータの追加やAPIドキュメントなどがさっと確認出来たりする公式のツールです。
[developer-tools](https://help.shopify.com/en/api/tools/developer-tools)


## GraphiQL App

こちらはストアにインストールするアプリですが、インストールしたストアでGraphiQLのテストが出来ます。
GraphiQLを使用したいときに定義したqueryが動作するのか検証することが出来ます。

[GraphiQL App](https://help.shopify.com/en/api/graphql-admin-api/graphiql-app)

## GraphiQL Explorer

GraphiQL Appと合わせて使うことになるかと思いますが、
ブラウザでチェックボックスにチェックをつけていくだけでqueryを生成することが出来ます。
GraphiQL Explorerでqueryを生成、GraphiQL Appで動作検証のようにスムーズに検証することが出来ます。
[GraphiQL Explorer](https://help.shopify.com/en/api/graphql-admin-api/graphiql-explorer)
ActiveDirectoryでユーザー作成後RDPできない

ActiveDirectoryでAdmin権限ではないユーザーを作成してRemoteDesktop作れなくてハマったのでメモ

RemoteDesktopUserのグループをそのユーザーに紐づけて、Default Domain Controllers Policyを変更しないといけない。

```
変更のしかた
管理ツールから[グループポリシーの管理]でも良い
[サーバーマネージャー]
　→[機能]
　　→[グループポリシーの管理]
　　　→[フォレストXXX]
　　　　→[ドメイン]
　　　　　→[ドメイン名]
　　　　　　→[グループポリシーオブジェクト]
　　　　　　　→[Default Domain Controllers Policy]

適当なとこでマウスを右クリックして編集を選択し、以下の場所まで潜る。

[コンピュータの構成]
　→[ポリシー]
　　→[Windowsの設定]
　　　→[セキュリティの設定]
　　　　→[ローカルポリシ]
　　　　　→[ユーザ権利の割当]
　　　　　　→[リモートデスクトップサービスを使ったログオンを許可]
```
YouTubeのJukeboxを作ってみた

## どんなもの

YouTubeのURLを登録しておくと指定した時間帯にランダム再生するジュークボックスです。
音専用で、映像は流れません。
ブラウザでサーバにアクセスし、曲登録や編集ができます。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/429ce65d-7e92-6319-5647-e1a60e522dd2.png)

## 注意事項

* ssl設定はしていないので、VPNやローカルネットワークなどのセキュアなネットワーク内で利用してください
* 著作権は守ってください。ご自分の演奏動画などが推奨されます。

## 構成

![structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/bea6cb8f-816d-bee5-bc7e-3070a9d2083e.png)

## インストール

[GitHub](https://github.com/radiance1104/juketube)からファイル一式をクローンするかダウンロードしてください。

### バックエンド

1. Node.jsをインストールしてください

1. MongoDBをインストールしてください

1. `back/app/environment.ts`を環境に合わせて編集してください

1. 下記のコマンドを実行しプラグインをインストールしてください

    ```
    $ npm install
    ```

1. 下記のコマンドを実行すると起動します

    ```
    $ npm start
    ```

### フロントエンド 

1. Angular7をインストールしてください

1. `front/src/environments/environment.ts`を環境に合わせて編集してください

1. 下記のコマンドを実行しプラグインをインストールしてください

    ```
    $ npm install
    ```

1. 下記どちらかの方法でWEBページを公開してください
  * 下記のコマンドを実行するとnginxやapacheなしでWEBページが公開されます

      ```
      $ ng serve --host 0.0.0.0
      ```

  * 下記のコマンドを実行すると`dist`ディレクトリにindex.htmlやjs, css一式が生成されるので、apacheやnginxでWEBページを公開してください
  
      ```
      $ ng build
      ```

## 利用しているモジュール

### バックエンド

* @microlink/youtube-dl
* @types/express
* @types/mongodb
* @types/node
* body-parser
* cluster
* crypto
* express
* moment
* mongodb
* node-cron
* typescript

### フロントエンド 

* angular