OmniAICreator/Qiita-1.07M huggingface dataset:
関数内関数

```py
def test(a, b, c):

    def plus(d, e):
        return d + e

    r1 = plus(a, b)
    r2 = plus(b, c)

    print(r1 * r2)

test(3, 4, 5)
```

```:実行結果
63
```

r1はplus関数に3,4を入れた値が入る。
よって、r1=7
r2はplus関数に4, 5を入れた値が入る。
よって、r2=9

test関数はr1とr2をかけた値を出力するので、
実行結果で63が出力される。
Map Valueでソート

MapのValueでソートする
pair型のvectorに移し替えてソートする。
pairの一つ目でソートされる。


```cpp

using namespace std;
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
int main()
{
    map<string, int> mp;
    mp["apple"] = 7;
    mp["orange"] = 3;
    mp["melon"] = 5;
    mp["peach"] = 0;
    mp["suica"] = 9;

    vector<pair<int, string>> v;

    for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++) {
        v.push_back({ it->second, it->first });
    }
    sort(v.begin(), v.end());
    return 0;
}
Q4.繰り返し処理をして、複数のセルに値を入力するには？

今回は、繰り返し処理を用いたマクロを作ってみましょう。

For文という構文を使います。
ExcelVBAに限らずほとんどのプログラミング言語で使われるので、
知っている方も多いかと思います。


今回の問題の内容は、
A1セル～A10セルまでの10個のセルに、1～10までの値を順番に入れるマクロを
作るには？とします。結果のイメージはこんな感じ↓ですね。


![Q4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/730bd444-cb05-ca4a-cc36-d839b2bf44dc.png)



たったの3行のコードでこれを実現できてしまいます。
今回は10個のセルですが、これは数が100個になろうと1000個になろうと、
同じく3行のコードで実現することができます。



では、マクロを覗いて見ましょう。こちらです。

```VB
Sub Q4_Answer()
    For i = 1 To 10
        Range("A" & i).Value = i
    Next i
End Sub
```



このマクロを実行すると、先ほどの画像のような結果が得られます。



さて、このマクロのポイントなんですが、For文よりも以下の表記がポイントだったりします。
Range("A"& i).value

このように表記することによって、iがFor文の中で変化するにつれて、
入力するセルがひとつずつ下へずれていくというわけです。




ちなみにちょっと変わった正解例もご紹介しておきます。

```VB
Sub Q4_Answer_ex()
    For i = 1 To 10
        Range("A1").Offset(i - 1, 0).Value = i
    Next i
End Sub
```



Offsetプロパティを利用して、入力するセルをずらすテクニックです。
Range().Offset(ずらす行、ずらす列）とします。(0なら省略も可)
例えば、Range("A1").Offset(1,)とすると、A1セルから1行下のセル、
つまり、A2セルを示します。
また、Range("A1").Offset(,1)とすると、列が1つ右にずれます。
つまり、B1セルを示すことになります。


これを、先ほどのようにFor文の中で利用することによって、
1つずつ下へ入力するセルをずらしています。



プログラミングの世界は正解はひとつとは限らず、いろいろなやり方が
考えらえます。実現したいことによって、いいやり方悪いやり方がありますが、
まずは、実現したいことを実現する為に、いろいろなやり方があるというのを
知っておくと、柔軟な発想ができるかも知れませんね。
初心者による ES6 イテレーター

#概要
イテレーターとは、オブジェクトの内容を列挙するための仕組みを備えたオブジェクトです。Array, String, Map, Setなどの組み込みオブジェクトは、デフォルトでイテレーターが備わっているため、for...ofで要素を列挙できる。これはC言語にもあるので確認してみる。

#C++ iterator
C++でのiteratorを復習してみる。C++ではiteratorは「共通のインターフェイスでコンテナに対する反復処理を行うことができるポインタのようなもの」と考えることができる。

```c++:main.cpp
#include<iostream>
#include<vector>
using namespace std

int main() {
 vector<int> V;
 vector<int>::iterator i;

 V.assign(5, 5)
 for(i = V.begin(); i != V.end(); i++){
 cout << *i << endl;
 }
}
```
V(ベクトルコンテナ)に格納されている要素を列挙している。
これと同じことをjavascriptで表してみる。

#javascript iterator

```javascript:sample.js
let data_ary['1', '2', '3']
let itr = data_ary[Symbol.iterator]()
let d
while(d = itr.next()){
 if(d.done) { break }
 console.log(d.done)
 console.log(d.value)
}
```

[Symbol.itrator]メソッドは、配列内の要素を列挙するためのイテレーター(iteratorオブジェクト)を返します。イテレーターは配列の次の要素を取り出すためのnextメソッドを持ちます。それぞれの値は、

```
done : イテレーターが終端に到達したか(=次の要素がないか)
value : 次の要素の値
```

列挙することが可能な自作classを作った場合の扱い方は、

```javascript:sample.js
class Data {
 constructor(data){
  this.data = data
 }
 
 [Symbol.iterator](){
  let current = 0
  let that = this
  return {
   next(){
    //オブジェクトを返す
    return current < that.data.length ? 
     {value: that.data[current++], done: false} : 
     {done: true}
   }
  }
 }
}
let iterator = new Data(['1', '2', '3'])
for(let value of iterator){
 console.log(value)
}
```

for...of命令は、内部的に「イテレーターの取得からdoneメソッドによる判定、valueプロパティによる値の取り出しまで」をすべてしてくれているのである。よって、Symbol.iteratorを組み込んでおくことでfor...ofで中身を列挙できる。

#参考資料
山田祥寛様 「Javascript 本格入門」
Jupyter学習ノート_001

## Pythonでgoogle driveにフォルダーを作成する方法：
1. [google Colaboratory](https://colab.research.google.com)に登録する　　
2. google driveをマウントする（/content/drive/My Drive/）
3. 下記のソースを実行する 

```crt_folder.py
import os
import subprocess
import re
import shutil

def res_cmd_lfeed(cmd):
  return subprocess.Popen(
      cmd, stdout=subprocess.PIPE,
      shell=True).stdout.readlines()

def main():
    #初期パスを指定する
    mount_path = '/content/drive/My Drive/'
    base_folder = 'python_list/'
    path_name = mount_path  + base_folder

    if not os.path.exists(path_name):
        os.mkdir(path_name)
    #else:
        ####サブフォルダーやファイルを削除する
        #shutil.rmtree(path_name) 
        ####サブフォルダーも再帰的に削除してくれます。ただし、フォルダー内にファイルがあると削除に失敗します
        #os.removedirs(path_name) 

    #コマンドをリストに出力する
    cmd = ("pip freeze")
    folders = res_cmd_lfeed(cmd)

    #FORループでリストの内容を読込み
    for folder in folders:
        result = str(folder).replace(".","_")
        folder_name = result[2:len(result)-3]
        path_name = mount_path + base_folder + folder_name
        #フォルダーが存在しない場合作成する
        if not os.path.exists(path_name):
            os.mkdir(path_name)
            ###必要あればコメントを外して実行する
        #else:
            #shutil.rmtree(path_name)
            #os.removedirs(path_name)

if __name__ == '__main__':
    main()
```

- 実施した結果  
![creat folder](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/0e0a1bf3-51b9-cfae-135a-f035c3ee9129.png)
Reactでマップを作りたいと思った時の備忘録

##はじめに
今、Reactを使ってMapアプリを作ろうとしています。
どうやら、ReactにはUberが作っているReact-map-glというライブラリがあるとのことなので、それを使っています。

こちらがReact-map-glです
[公式ドキュメント](https://uber.github.io/react-map-gl/#/)


この記事は、ライブラリを使ってMapのサンプルを開くところまでを備忘録的に書き込んだメモです。
基本的に、いろんな記事をそのままなぞっていったらできたので、新規性ゼロです。

##流れ
今回の大まかな流れはこちらの記事通りに進めました。
[[React.js]REACT-MAP-GL入門(リンク)](https://qiita.com/ryosayo/items/0253411955b17392c229)


##手順
###「Reactてどんな物か」を掴む
まずは、Reactがどんな物かの感覚を掴んで行きます。

これは、公式ドキュメントがわかりやすかったです。
[公式ドキュメント(リンク)](https://ja.reactjs.org/tutorial/tutorial.html)



###Webpackの環境を構築する
JSのモジュールハンドラであるWebpackを使っていくそうです。
環境構築はこちらを元に行いました。
[Reactとwebpack2での環境構築](https://naoki-otsu.com/2017-05-15-react-webpack-bioplate/)

この時、「.babelrc」ってファイルの意味が分からなかったのでこちらで学びました。
[Babelの基本的な使い方(リンク)](https://qiita.com/one-kelvin/items/ae57250613aff3472917)

###Mapboxのアカウントを作り、トークンを取得する
ゼンリンが作っているMapboxのトークンが必要なので、準備します。
[Mapboxのサイト(リンク)](https://account.mapbox.com/)

###記事の手順をもとにクローンしていく。
最後にクローンしていきます。
↓の記事の後半の手順の通り進めたらできました！
[[React.js]REACT-MAP-GL入門(リンク)](https://qiita.com/ryosayo/items/0253411955b17392c229)


###結果を確認
結果はこんな感じ
めちゃ綺麗！！！！

![スクリーンショット 2020-01-09 20.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/35b26b38-9b28-dc1d-2d06-3f0277a5ca75.png)
AAD認証を使用してAzure VM(Linux)にログインする

こんにちは、kc-Dreamです。
今回はAAD認証を使用してAzure VM(Linux)へのログイン方法についてご紹介します。

※2019/12/27時点ではパブリックプレビュー

#概要
現在、Azure VMでは拡張機能のひとつとして、AAD認証を行うことができるエージェントが提供されております。
現時点ではパブリックプレビューとなっていますが、導入も容易でログ等も取得できるので、
すごく便利です。

以下公式ドキュメントからの抜粋となります。
- お客様の会社の AD 資格情報を使用して、Azure Linux VM にログインできます。 ローカル管理者アカウントを作成したり、資格情報の有効期間を管理する必要がなくなります。
- ローカル管理者アカウントへの依存度を低減することで、資格情報の損失/漏洩や、セキュリティ性の弱い資格情報をユーザーが設定することを憂慮する必要がなくなります。
- Azure AD ディレクトリ用に設定されたパスワードの複雑性と、パスワードの有効期間ポリシーを使用して、Linux VMもセキュリティ保護できます。
- Azure 仮想マシンへのログイン セキュリティをさらに強化するために、多要素認証を設定することができます。
- Azure Active Directory を使用して Linux VM にログインする機能は、フェデレーション サービスを使用するお客様も使用できます。
- ロールベースのアクセス制御 (RBAC) を使用することで、どのユーザーが、正規のユーザーまたは管理者権限を持つユーザーとして特定の VM にサインインできるかを指定できます。 
- ユーザーがチームに参加またはチームから脱退する場合は、適切なアクセス権が付与されるよう VM の RBAC ポリシーを更新できます。 この操作は、不要な SSH 公開キーを削除して VM をスクラブするよりも簡単です。 従業員が退職し、そのユーザー アカウントが無効化または Azure AD から削除されると、リソースにアクセスできなくなります。

※便利な機能ですが、下記パブリックプレビューの注意点はよく理解しておく必要があります。

###パブリックプレビューについて
パブリックプレビューについての補足事項となります。

以下公式ドキュメント抜粋
>Azure Active Directory 認証は、現在、パブリック プレビューの段階です。 このプレビュー バージョンはサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、[Microsoft Azure プレビューの追加使用条件に関するページ](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)をご覧ください。 テスト後に破棄する予定のテスト用仮想マシンでこの機能を使用してください。


##サポートされているLinuxディストリビューション
| ディストリビューション      |     Version |
|:-----------------|------------------:|
| CentOS        |        CentOS 6、CentOS 7 |
| Debian         |          Debian 9|
| openSUSE           |            	openSUSE Leap 42.3 |
|     RedHat Enterprise Linux           |                	RHEL 6、RHEL 7 |
| SUSE Linux Enterprise Server        |             SLES 12 |
| Ubuntu Server  |        Ubuntu 14.04 LTS、Ubuntu Server 16.04、Ubuntu Server 18.04|

###Ubuntuで使用する場合
Ubuntuで使用する場合の設定方法についてご紹介します。

- PortalからAzure VM(Ubuntu)作成時にAAD認証が項目として選択できるので選択し、構築をすすめます。

![コメント 2020-01-09 201942.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/411d4f12-e85d-09aa-186f-428f6936b334.jpeg)

###CentOSで使用する場合
CentOSで使用する場合の設定方法についてご紹介します。


- Ubuntuと違いPortalから構築時に項目として選択することができません。

![コメント 2020-01-09 202500.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/286ebebf-6c14-da78-1f47-0088dee12ffc.jpeg)


- CentOSのAzure VM構築後にCLIまたはCloudShellを使用し拡張機能としてエージェントをインストールする必要があります。
- 参考までにCloudShellにてインストールを行う際のコマンド載せておきます。

```text:sample
az vm extension set \--publisher Microsoft.Azure.ActiveDirectory.LinuxSSH \--name AADLoginForLinux \--resource-group リソースグループ名 \--vm-name VM名

※対象サブスクリプションで接続済みを想定
``` 
###VM作成後
VMのアクセス制御より、対象のAADユーザに対し許可設定をすることで、VMへのアクセス時にAADでログイン可能となります。

[仮想マシン ロールの割り当てを構成する](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/login-using-aad#configure-role-assignments-for-the-vm)

#おわりに
参考情報まとめておきます。

[プレビュー:Azure Active Directory 認証を使用して Azure の Linux 仮想マシンにログインする](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/login-using-aad)
[Azure AD 認証でLinuxへログイン！！](https://www.cloudou.net/azure-active-directory/aad011/)
vCenter（の構成ファイル）をSCPでバックアップする

#vCenterの構成ファイルを保存する記録
scpコマンドは登場しない。

##■登場人物
①vCenter Server Appliance
　192.168.100.254
②受け取るサーバ
　192.168.100.249
　ユーザー　hogehoge
　バックアップディレクトリ　/home/hogehoge/vcsa

##■準備
受け取るサーバにユーザーがいなければ作る。
例：ユーザー名 hogehoge を作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/4b041583-3f68-2d64-ff9f-c1e4962c6481.png)

##■バックアップ
vCenterへログインし、サマリからバックアップをクリックする。
https://サーバのアドレス:5480/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/1a0b44f0-19e3-ab26-2379-3da567401d60.png)

サーバ情報を入力する。
※ユーザーのホームディレクトリにvcsaというディレクトリは無い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/739d3083-77c9-a45d-1f75-68ecebf009bc.png)

認証が通るとバックアップ対象の選択画面となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/0ac7f7c6-faed-d477-d42f-7a7c184c6a1a.png)

内容確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/e2d96e69-83b5-8ce4-f987-feefa886708c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/ceb0e734-33bb-7ca1-ce55-4a64b0c076c7.png)

vcsaディレクトリが作成され、その中にバックアップされたファイルが収容されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91280/43c4e7f1-c2bd-1967-0586-4f0052babed2.png)


以上。
Docstrings

```py
def players(**kwargs):
    """名前と職種を出力する関数です。
    """
    for name, job in kwargs.items():
        print(name + 'は' + job + 'です。')

d = {
    '太郎':'勇者',
    '次郎':'戦士',
    '三郎':'魔法使い',
    '四郎':'僧侶'
}

players(**d)    
print(players.__doc__)
help(players)
```

```:実行結果
太郎は勇者です。
次郎は戦士です。
三郎は魔法使いです。
四郎は僧侶です。
名前と職種を出力する関数です。
    
Help on function players in module __main__:

players(**kwargs)
    名前と職種を出力する関数です。
```

関数のファンクションなどを
""" """に書く。
docメソッドで参照できる。
help関数でも参照できる。
phalcon で mssql(Microsoft SQL Server)を使ってみる

#PhalconでMicrosoft SQL Serverを使ってみる

もちろんリモートのSQL Serverを使います。

Windowsの場合もMacの場合もクライアントにODBCドライバが必要になります。

##ODBC Driver インストール

### 2020.11.25 macでpeclコンパイルインストールがうまくいかない模様。以下からバイナリを取得するのがベストNTSのやつを
https://github.com/Microsoft/msphpsql/releases

###MacにMSSQLのODBCドライバをインストール
Macにインストールは、Linuxとかと似てるんですが、以下にMicrosoftさんが丁寧に解説してくれてますので、コマンドもそのまま実行すれば大丈夫です。
ただ、一気にコマンドを実行するとうまく行かないケースがあるので、
1行ずつコピーして実行してください。

https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver15



###Windows にODBCドライバをインストール

以下サイトからダウンロード、インストールします。
https://www.microsoft.com/ja-JP/download/details.aspx?id=36434


## Microsoft SQL Server 用 PHP ドライバーのインストール

### Macの場合


https://docs.microsoft.com/ja-jp/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-ver15

ここにある、手順2と3だけでよい。基本的には。すでにいろいろ開発してる人は、3だけでも良いかもです。

```
手順 2. 必須コンポーネントのインストール
Linux と macOS のインストールに関するページの手順に従って、macOS 用 ODBC ドライバーをインストールします。
さらに、GNU make ツールをインストールする必要がある場合があります。

brew install autoconf automake libtool

手順 3. Microsoft SQL Server 用 PHP ドライバーのインストール

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
```

pecl (PHPのライブラリを扱うやつ）自体が入ってない可能性もあるので、command not found となる場合はググってくださいｗ

pecl install sqlsrv
と
pecl install pdo_sqlsrv
の結果画面に、
どこにインストールされたかパスが出力されるので、しっかりと覚えておいてください。
そこのパスを
php.ini
に以下のように記述することになるかとおもいます。以下は例です。

```
extension=/usr/local/lib/php/pecl/20180731/sqlsrv.so
extension=/usr/local/lib/php/pecl/20180731/pdo_sqlsrv.so
```

※順番もpdoのほうが後がよいかとおもう。

Mac(Linux系）は、sqlsrv.soとpdo_sqlsrv.soです。


## Windows のPHP ドライバもMacのときと同じ
URLは同じです。現時点では
https://www.microsoft.com/en-us/download/details.aspx?id=57916
ここにあるのが最新っぽいです。
sqlsrv.dll
pdo_sqlsrc.dll

windows と mac/Linuxの違いはso or dllの違いなのでmacのときみたいに、
インストールされた場所をphp.iniに書けば良い。


#ここまでは、PHPでMSSQLを使う方法でした。ここからがPhalcon

#Phalconでmssqlを扱う！

## Phalcon用Adapter/dialectを用意する

どんなに探しても、Phalcon2.xまでだったり、Phalcon3.0.xといいつつも、ちゃんと動かないものだったりしたので、私が作りまいsた！

https://github.com/QualiaSystems/phalcon-sqlsrv

composer で扱えるようにもしたので、

### composer installできるようにしたよ（packagistに登録しといた）

https://packagist.org/packages/qualiasystems/phalcon-sqlsrv

```
composer require qualiasystems/phalcon-sqlsrv
```

とりあえず、これで一通りfindfirstとかfindとか使えたのでこのまま行ってみようと思ってますが、
もし使ってみてここが変だよ！ってところはコメントください。
IISへのデプロイで「展開」が選べない＆VisualStudioから接続できない

# 概要
Visual StudioからWindows ServerへWebアプリをデプロイするとき、うまくいかずに原因の特定に時間がかかった。結果、以下の対応で無事にデプロイができた。

- WebDeploy3.6はダメだが、3.5だとOKだった
- WebDeployはフルインストールすること

### 開発環境
サーバ：Windows Server 2016 Standard Ver.1607
IIS Ver.10.0.14393.0
開発機：Windows 10 Home
Visual Studio Community 2019 Ver.16.4.2

### 参考サイト
デプロイの手順は以下のサイトが分かりやすい。
[ASP.NET > WindowsServer > Web Deployの設定](https://qiita.com/sugasaki/items/914eb0f2fa4e9337614e)
[リモートのIISへVisual StudioからWebアプリをWeb Deployする](https://www.nuits.jp/entry/iis-web-deploy)

問題解決にあたって以下のサイトを参考にした。
[IIS 「管理サービスの委任」が開けない](https://ja.stackoverflow.com/questions/44848/iis-%E7%AE%A1%E7%90%86%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E5%A7%94%E4%BB%BB-%E3%81%8C%E9%96%8B%E3%81%91%E3%81%AA%E3%81%84)
[MSDeploy - Destination Not Reachable](https://stackoverflow.com/questions/18887023/msdeploy-destination-not-reachable)

# 事象と解決方法
## IISで『展開』が選べない
最初にサーバへWebDeployTool3.6をインストールした。が、IISでサイト名を右クリックしても「展開」が表示されず、Web配置による発行の有効化ができない。
対策として、WebDeployTool3.6をアンインストールし、3.5をインストールしたら、以下のように表示されるようになった。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/b5b15844-ecaf-7c87-7a1b-4d4371062881.png)

## Visual Studioからサーバーに接続できない
Visual Studioのアプリの発行で接続の検証を行うと、以下のエラーが出る。

```
リモート コンピューター("xxxxxx")に接続できませんでした。
リモート コンピューターで、Web配置がインストールされていること、
および必要なプロセス("Web Management Service")が開始されていることを確認してください。
ERROR_DESTINATION_NOT_REACHABLE リモート サーバーに接続できません。
```
対策として、WebDeployToolのインストーラーを起動し、フルインストールをやり直した。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/2cb32a2b-8bd2-305d-d365-b3215c4f4883.png)
上記インストーラーの画面で「変更」を選択した。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/27e1a151-c45c-a7b7-271c-e6beb5d9d400.png)
上記画面で各機能ごとのアイコンをクリックして、すべての機能をインストールするよう選択した。
この状態でインストールを行うと、エラーが出ずに接続できるようになった。
なお、いったん削除（アンインストール）して再インストールしても効果は同じ。

# IISとVisual Studioの設定方法
最後に、接続成功した設定方法をまとめておく。
まずは以下のように、サーバー側のIISにtest_siteという新規サイトを追加する。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/701b9cb2-6abd-aae7-8542-71f7cc7f9b5d.png)
作成するサイトを複数のアプリケーションに分割したいため、adminというアプリケーションを追加する。
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/72fa0e78-6773-c226-d30b-f452d611d3d3.png)
サイトの右クリックから「展開」→「Web配置による発行の有効化」を開くと、以下のように発行サーバー接続情報が「SERVER:8172/msdeploy.axd」と表示されている。
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/c675e5c9-8b28-06dd-1c3e-45576fdf7fe2.png)
続いてVisual Studio側の設定で以下のように、サーバー欄に先ほどの発行サーバー接続情報を指定する。サイト名欄の設定内容はサイト名 / アプリケーション名とする。
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/e0c0086d-05d7-e4c5-b49f-7787533cf579.png)
サーバー欄のPC名は、IPアドレスでも構わない。
![8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/1c62a161-844f-7c24-ca61-72d1ad917af4.png)
中間テーブルを経由して別テーブルから取得した値をviewに反映させる方法

chatアプリケーション制作時に、中間テーブルを経由して、別のテーブルから特定の値を出力する方法がわからず、苦しめられたので、その備忘録に。

###やりたいこと
・現在のchatグループのメンバーリストをヘッダーに反映させたい。
（下画像のピンク色の部分）

![１.png](https://gyazo.com/344cce0d97d0f1ac471b81be47a9bdd1.png)

hamlは以下の通り

```haml:_main_chat.html.haml
.chat-main
  .top
    .top__left-box
      .top__left-box__group-name
        = @group.name
      .top__left-box__members
        -# ここに何を記述すれば良いかが今回の論点
        -# =@group.users.name    左記では上手く呼び出せない
    .top__edit-btn
      = link_to edit_group_path(current_user) do
        = "Edit"

```


・アソシエーションは以下の通り

```ruby:models/group.rb
class Group < ApplicationRecord
  has_many :group_users
  has_many :users, through: :group_users
  has_many :messages
end
```

```ruby:models/user.rb
class User < ApplicationRecord
  has_many :group_users
  has_many :groups, through: :group_users 
  has_many :messages
end
```

```ruby:models/group_user.rb
class GroupUser < ApplicationRecord
  belongs_to :group
  belongs_to :user
end
```

###方法


任意のカラムの配列を取得する、pluckメソッドを使用する

**pluckメソッド**:特定のカラムの配列を使用する。
使用方法　　`＠モデル名.pluck(カラム名)`

取り出した値を” , ”で区切りたいので、区切り文字をjoinメソッドを使用して指定する。
**joinメソッド**：配列の各要素の値を文字列に変換し、それらを連結した文字列を作成する。
使用方法　　`join(指定したい区切り文字)`

今回のケースに上記メソッドを当てはめてみる。


```haml:_main_chat.html.haml
.chat-main
  .top
    .top__left-box
      .top__left-box__group-name
        = @group.name
      .top__left-box__members
        ="Member:" + @group.users.pluck(:name).join(", ")
        -# "頭に表示したい文字列" + モデル名.users tableへのアソシエーション.pluck(:取り出したいカラム).join("取り出した値の区切り文字")
    .top__edit-btn
      = link_to edit_group_path(current_user) do
        = "Edit"
```
viewを確認すると

![１.png](https://gyazo.com/b73466e42fcde784c3427eea414ced55.png)

上手く反映される。

###現状の理解
文字列を + を使って挿入するところなど、もう少しきれいに描けるような気がする。
よりきれいな記述方法がございましたら、ぜひご教示ください。


######参考記事
https://www.javadrive.jp/javascript/array_class/index3.html
https://hyuraku.hateblo.jp/entry/2018/10/09/222026
[iOS13] ステータスバー・ナビゲーションバーのサイズ取得方法

[[Swift] ステータスバー・ナビゲーションバーのサイズ取得方法](https://qiita.com/mochizukikotaro/items/28d964affc882d430892)


こちらの情報がさすがに古くなりましたので私の方で更新してみます。

```swift

// ステータスバーの高さを取得
 let statusBarHeight = UIApplication.shared.statusBarFrame.height
       
// ナビゲーションバーの高さを取得
let navBarHeight = self.navigationController?.navigationBar.frame.size.height
```

# iPadのNavigationBarのheightが50pxに変更

[iPad Navigation Bar and Toolbar Height Changes in iOS 12](https://medium.com/@hacknicity/ipad-navigation-bar-and-toolbar-height-changes-in-ios-12-91c5766809f4)

iOS12 のどこかのタイミングからiPadのNavigationBarの高さが50px になっていたからです。
今まで44pxで記憶していましたのでテストでベタ打ちで44pxで打つと6pxがズレてしまいます。

iPad Navigation Bar height now 50
https://forums.developer.apple.com/thread/103659
引数のデフォルト値について

##関数定義時に引数をデフォルトで設定

関数定義の際に、 == で引数の値を設定すると、その値をデフォルトで呼び出すことができる。

```
function rolePlay($role == "モブ"){
　echo "私は".$role."です";
}
```

##関数の呼び出し
```
rolePlay("主人公");
rolePlay();
```

##出力結果
```
私は主人公です
私はモブです
```

上の出力結果は、関数を呼び出した際の引数が"主人公"となっているので、「主人公」が入る。
下の出力結果は、関数定義の際、引数のデフォルトを"モブ"に設定しているので、こちらが引数となっている。
Google colab　OANDA APIで取得した時刻（ISO8601）を日本時間に変換する(JST)

少しだけ手こずったのでメモ
#1.動作環境　
・GoogleColaboratory
・OANDA API V20
#2.やり方
どうやらOANDA APIで拾ってきた時刻はISO8601という規格だそうで。
売買した時刻を表示させたいと思って
日本時間で知りたいな～なんておもって少々はまった。
まず、OANDAからどんなデータが帰ってくるかというと、

```python
trading_data=api.request(trades.OpenTrades(accountID=accountID))
trading_data["trades"][0]["openTime"]
```
上記のように売買した時刻がopenTimeに記載があります。
その中身は

```
'2020-01-09T10:28:23.567698657Z'
```
すごい細かくナノ秒くらいまでもってこれます。
しかしそこまで詳細な秒数は知らなくてもよいので
以下のようなコードで変換できました。

```python
time=trading_data["trades"][0]["openTime"]
def iso_to_jstdt(iso_str):#ISO8601→JST変換関数
  dt = None
  split_timedate=iso_str.rsplit(".",8)#ここでマイクロ病以下を切り落とし
  iso_str=split_timedate[0]
  print(iso_str)
  try:
    dt = datetime.strptime(iso_str, '%Y-%m-%dT%H:%M:%S')
    dt = pytz.utc.localize(dt).astimezone(pytz.timezone("Asia/Tokyo"))
  except ValueError:
    try:
      dt = datetime.strptime(iso_str, '%Y-%m-%dT%H:%M:%S')
      dt = dt.astimezone(pytz.timezone("Asia/Tokyo"))
    except ValueError:
      print("変換できてない")
      pass
  if dt is None:
    df=""
    return df
  return dt.strftime('%Y/%m/%d %H:%M:%S') #文字列に再変換


Jtime=iso_to_jstdt(trading_data["trades"][0]["openTime"]) #ISO8601を入れる
print(Jtime)
```

```
2020-01-09T10:28:23
2020/01/09 19:28:23
```
きれいに日本時間にしてくれました！
マイクロ秒以下を切り落としてるけどそこはいらない！！！！
#3.参考文献
>https://qiita.com/estaro/items/2b7074839d2a5e883dc1
RでQiitaの記事をスクレイピングしよう

# 1. 趣旨

最近スクレイピングに挑戦中なので、素振り的な感じでやってみました。
意外とあっさりできた。

# 2. コード

```R
# 今回は以下のURLの記事のタイトルと本文を引っこ抜きます。
# https://qiita.com/zakkiiii/items/1f02471d49264b4bd64a

# 必要なパッケージ
> library(rvest)

# ウェブページの取得
> qiita.article <- read_html("https://qiita.com/zakkiiii/items/1f02471d49264b4bd64a")

# 記事のタイトルの取得
> qiita.article.title <- qiita.article %>% html_nodes(xpath ='//*[@class="it-Header_title"]') %>% html_text()

# 記事本文の取得
> qiita.article.content <- html_nodes(xpath = '//*[@class="it-MdContent"]') %>% html_text()

# 一応ベクトルとしてがっちゃんこしておく。
> qiita.article.data <- (qiita.article.title, qiita.article.content)

# 中身の表示
> cat(qiita.article.data)

R・Rstudio・パッケージのアップデート 

趣旨

何だかんだよく忘れるので、備忘録として。
必要最低限やればいいことを書いておく。... 
```

# 3. 解説
## 3-1. rvestパッケージ
`rvest`は、Rでのウェブスクレイピングを手助けしてくれるパッケージです。
以降登場する`read_html()`などはこのパッケージを利用しています。
未導入の場合はスクリプトを実行する前に必ずダウンロードしておきましょう。

```R
> install.packages("rvest")
```

## 3-2. ウェブページの取得
`read_html()`を使用します。
深く考えず、`read_csv()`と同じような感覚で使えばよいです。
引数として設定したURLからウェブページを取得しますが、出力されるオブジェクト（データ）はXML形式のような階層構造をとっています。

```R:記事全体の情報を取得
qiita.article <- read_html("https://qiita.com/zakkiiii/items/1f02471d49264b4bd64a")
```
これを、`qiita.article`として格納しておきます。
## 3-3. 特定の情報の抽出
ブラウザのデベロッパーツールなどでスクレイピングしたいウェブページのHTMLソースを見ると、各コンテンツが以下のタグで囲われた部分にあることがわかります。

| コンテンツ | タグ |
|---|---|
| 記事タイトル | \<h1 class="it-Header_title" itemprop="headline"> |
| 本文 | \<section class="it-MdContent" itemprop="articleBody"> |

そこで、それぞれのタグで囲われた部分を`qiita.article`から抜き出します。
前述の通りオブジェクト（データ）がXML形式なので、一般的なリストやデータフレームと同じ方法では抜き出すことができません。

### 3-3-1. 要素の抽出
`html_nodes()`は、`read_html()`が出力したオブジェクトから、「要素」（指定したタグ等で囲われたソースコードのこと。）を抜き出してくれる関数です。
抜き出すタグ（id、class等の引数も組み合わせて利用可能。）は、`xpath`という引数で設定します。

xpathについては、こちらが分かりやすかったのでご紹介しておきます。
[【R】Rを使ってXPathをスクレイピング【XPathの説明あり】｜さぎのみや家の事情](https://miyastyle.net/r-xpath)

```R:class="it-Header_title"要素を取得
> qiita.article %>% html_nodes(xpath = '//*[@class="it-Header_title"]')
{xml_nodeset (1)}

[1] <h1 class="it-Header_title" itemprop="headline">R・Rstudio・パッケージのアップデ ...
```

`//*[@class="it-Header_title"]`の意味は、「headだろうとbodyだろうと、とにかくどこでもいいから、class="id-Header_Title"となっているところを抜き出して！」ということになります。

### 3-3-2. テキストの抽出
次に、`html_nodes`で抜き出した要素からタグ等を取り除き、テキストだけを取り出します。
この時に使うのが、`html_text()`。名前の通り、HTMLからテキストだけを抜き出してくれます。

```R:抽出した要素から本文だけを抜き出す
> qiita.article %>% html_nodes(xpath ='//*[@class="it-MdContent"]') %>% html_text()
[1] "\n\n趣旨\n\n何だかんだよく忘れるので、備忘録として。\n必要最低限やればいいことを...
```
先の`html_nodes()`の結果出力されたオブジェクトをそのまま`html_text()`に渡すことで、必要な要素のテキストだけを取り出すことができました。

## 3-4. 抽出テキストの表示
本文中の改行は改行コード`\n`として出力されるので、`cat()`を使えば、改行コードを反映した上で表示させることができます。

```R
> qiita.article %>% html_nodes(xpath = '//*[@class="it-MdContent"]') %>% html_text()　%>% cat()


趣旨

何だかんだよく忘れるので、備忘録として。
必要最低限やればいいことを書いておく。
```

# 4. まとめ
| 関数名  | 内容 |
|---|---|
| read_html("URL") | ウェブページの情報を、XML形式のオブジェクトとして出力する。 |
| html_nodes(x, xpath = 'hoge') | x (XML文書または1つ以上のノード[^1]) からxpathで指定した要素 (ソース) を抽出する。 |
| html_text(x) | x（上に同じ）からテキストだけを抽出する。 |
[^1]: 厳密には違うが、ノードは、階層型のオブジェクトであるXMLの各階層（各要素）を指す。

おしまい。
Next.js にaliasを追加してimportの手間を減らす

Next.jsのデフォルト設定では相対importを使うようになっていて、大量のコンポーネントをimportする際に何度も `../../` を書く必要があり面倒です。

この問題は `next.config.js` 内の `webpack config` をカスタマイズすることで解決できます。

## aliasのカスタマイズ
```javascript
const path = require('path');

module.exports = {
  webpack: config => {
    config.resolve.alias['~'] = path.resolve(__dirname);
    return config;
  }
};
```
これにより、 `import {Button} from "~/components"` のように使うことができます。

## VSCodeの設定
VSCodeをしているのであれば、下記を `tsconfig.json` に追加することで補完が効くようになります。

```json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./*"]
    }
  }
}
```

## 参考
https://remysharp.com/2019/11/04/nice-imports-with-nextjs#targetText=That's%20it.%20Now%20I%20can%20import%20from%20'~%2Fcomponents%2FWidget'%20and%20all%20is%20well.
bashでjsonの設定値をbash変数に変換する

# やりたいことと前提
`main.json`に設定されている値をbashスクリプトで扱えるようにします。

`main.json`は以下のようなシンプルなものです。（私はjsonをこういう形しか扱ったことがありません...入れ子とかわからん（））

```main.json
{
   "name" : "John",
   "money" : "28",
   "like" : "apple"
}
```

# bashスクリプトでjsonを扱う
`jq`というものを使うらしいです。
私は全くわからないので、[こちらの記事](https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af)をご覧ください。

# bashスクリプト

```bash
#jsonの値を表示
#
# load_json [値] [ファイル名]
function load_json () {
    jq -r .$1 $2
}

# jsonの値を同じ名前のbash変数に格納
#
# load_json_to_var [値] [ファイル名]
function load_json_to_var () {
    eval $1="$(eval echo -n $(load_json $1 $2))"
}
```

## 問題点
- 値に空白があるとエラーが出る

どうしてもわからなかったので諦めました。誰かもっと簡単にできる方法を知っていたら教えてほしいです。
Python3入門学習　0回目

本稿はPython初心者がWin10 64bit環境でPython3を勉強していく過程を記している。
特に前提知識を想定していないが、逆に筆者にも前提知識がないため、必ずしも正確な情報を適切に提供できるわけではないことを予めお断りしておく。
また、本稿はオライリー・ジャパンより出版されている『入門　Python3』を参照して書かれている。

# Pythonのインストールと簡単な動作確認
## Python3のインストール
なにはともあれPython3が手元になければプログラミングをすることができないので、簡単に環境を整えていく。
まずは以下のアドレスにアクセスする。自分の実行する環境にあったPython3の実行環境を作るのだ。
https://www.python.org/downloads/
「Download Python3.8.1」のボタンを押してダウンロードする(3.8.1は本稿記載時点でのバージョン情報)。ダウンロードしたexeファイルを実行すればよいはずだ。
インストール先を適切に指定して(もちろん、特別な事由がない限りはデフォルトの指定先でよいだろう)、インストールする。インストール終了後、追加オプションの画面が出るが、ひとまず「close」ボタンを押して閉じておく。困ったら追加していけばそれでいい。

## 動作確認
インストールが終わったらスタートメニューからIDLE(Python 3.8 64-bit)を起動する。
ターミナルが起動するので以下のように入力して、結果を確認する。
`>>> print(47)
47`

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564409/50d5c26f-4002-31bc-d297-11e5ffe813b6.png)

こんな感じで出力されたら、たぶん大丈夫でしょう。
というところで今回はここまで。次回は型とかやりたいですね。
Azure LogAnalytics 番外編

こんにちは、kc-dreamです。
今回はAzure LogAnalyticsの番外編ということで、Kustoクエリについてご紹介します。

#Kusto概要
Kusto は、ビッグ データに対する対話型分析を格納して実行するためのサービスです。
これはリレーショナル データベース管理システムに基づいており、データベース、テーブル、列などのエンティティをサポートし、複雑な分析クエリ演算子 (計算列、検索とフィルター処理、行、グループごとの集計、結合など) を提供します。

[Kusto の概要](https://docs.microsoft.com/ja-jp/azure/kusto/concepts/)


##Kustoクエリとは
Kusto クエリは、データを処理して結果を返すための、読み取り専用の要求です。 要求は、構文を読みやすく、作りやすく、自動化しやすくするように設計されたデータフローモデルを利用してプレーンテキストで述べられます。 クエリでは、データベース、テーブル、列など、SQL に似た階層に編成されたスキーマ エンティティが使用されます。

[概要](https://docs.microsoft.com/ja-jp/azure/kusto/query/index)

##Kustoクエリの使用方法
```text:KustoSample
StormEvents 
| where StartTime >= datetime(2007-11-01) and StartTime < datetime(2007-12-01)
| where State == "FLORIDA"  
| count 
```
- Kustoクエリにはステートメントが1つありますが、それは表形式ステートメントです。 このステートメントは StormEvents という名前のテーブルの参照から始まっています (このテーブルをホストするデータベースはここでは接続情報の一部として暗に示されるだけです)。
- そのテーブルのデータ (行)が StartTime 列の値でフィルター処理され、さらに State 列の値でフィルター処理されます。
- "FLORIDA" 行の数がクエリにより返されます。


###Kustoチートシートまとめ
SQLクエリからKustoクエリを使用する際のクエリをまとめています。


[SQL から Kusto カンニングペーパー](https://docs.microsoft.com/ja-jp/azure/kusto/query/sqlcheatsheet#sql-to-kusto-cheat-sheet)
[SQL から Azure Monitor へ](https://docs.microsoft.com/ja-jp/azure/azure-monitor/log-query/sql-cheatsheet#sql-to-azure-monitor)

###LogAnalyticsで実際に使用してみる
別記事でご紹介しているので、参考にしてもらえると幸いです。
別記事リンクは以下になります。

[Azure LogAnalytics 概要についてまとめてみた](https://qiita.com/kc-Dream/items/c91cbe7deb61ba96707d)
[Azure LogAnalyticsでWindowsServerを監視してみた](https://qiita.com/kc-Dream/items/e1ffed2b9be931bb73a0)
[LogAnalyticsのデータ取得時間の調査方法](https://qiita.com/kc-Dream/items/80ab00486e1955bcfbe2)

###参考情報
[Azure Monitor ログ クエリ](https://github.com/MicrosoftDocs/azure-docs.ja-jp/blob/master/articles/azure-monitor/log-query/query-language.md)
[Kusto Query Language (KQL) from Scratch](https://www.pluralsight.com/courses/kusto-query-language-kql-from-scratch)
[Azure Monitor でログ クエリの使用を開始する](https://docs.microsoft.com/ja-jp/azure/azure-monitor/log-query/get-started-queries?toc=%2Fazure%2Fazure-monitor%2Ftoc.json)

#おわりに
Kustoクエリについては、Azure環境にてログや各種リソースメトリックを収集したデータを活用する際に使用するので、自身がよく使うコマンドは覚えておくのが便利です。
【Rails】メールを送信する（ローカル）

##基本
```terminal
$ rails g mailer SampleMailer hoge
```
メーラーとViewファイル×2（HTML版とプレーンテキスト版)が生成されます。

```app/mailers/sample_mailer.rb
class SampleMailer < ApplicationMailer
  def hoge
    @greeting = "Hi"

    mail to: "to@example.org"
  end
end
```
```erb:app/views/sample_mailer/hoge.html.erb
<h1>Sample#hoge</h1>

<p>
  <%= @greeting %>, find me in app/views/sample_mailer/hoge.html.erb
</p>
```
```erb:app/views/sample_mailer/hoge.text.erb
Sample#hoge

<%= @greeting %>, find me in app/views/sample_mailer/hoge.text.erb
```
あとはControllerの任意の箇所で`SampleMailer.hoge.deliver_now`と記述することで、ローカル環境でメールを送信することができます。

送信されるメールの内容は、サーバーのログから確認できます。

##よくあるカスタマイズ
メールの文面は、Viewファイルを修正することで自由に変更できます。
またMailerのアクションに引数をとって、引数からメールの送信先や本文に埋め込むテキストを抽出することが多いです。

```app/mailers/sample_mailer.rb
class SampleMailer < ApplicationMailer
  def hoge(user)
    @user = user
    mail to: user.email, subject: 'Hello World!'
  end
end
```
```erb:app/views/sample_mailer/hoge.html.erb
<p>こんにちは<%= @user.name %>さん！</p>
```
```erb:app/views/sample_mailer/hoge.text.erb
こんにちは<%= @user.name %>さん！
```
```app/controllers/user_controller.rb
class FooBarController < ApplicationController
  def foobar
    @user = find(params[:id)
    SampleMailer.hoge(@user).deliver_now
  end
end
```

##メールのプレビュー
冒頭の`$ rails g mailer SampleMailer hoge`を叩いた時に、以下のファイルが自動生成されます。

```test/mailers/previews/sample_mailer_preview.rb
# Preview all emails at http://localhost:3000/rails/mailers/sample_mailer
class SampleMailerPreview < ActionMailer::Preview

  # Preview this email at http://localhost:3000/rails/mailers/sample_mailer/hoge
  def hoge
    SampleMailer.hoge
  end

end
```
コメントアウトに記載されている`http://localhost:3000/rails/mailers/sample_mailer/hoge`等のアドレスにアクセスすることで、メールのプレビューを確認することができます。

メーラーに引数が必要な場合には、プレビューファイル内で定義ましょう。

```test/mailers/previews/sample_mailer_preview.rb
# Preview all emails at http://localhost:3000/rails/mailers/sample_mailer
class SampleMailerPreview < ActionMailer::Preview

  # Preview this email at http://localhost:3000/rails/mailers/sample_mailer/hoge
  def hoge
    user = User.first
    SampleMailer.hoge(user)
  end

end
```

##TODO
本番環境（特にHeroku）でのメール送信
https://railstutorial.jp/chapters/account_activation?version=5.1#sec-activation_email_in_production
Oculus Questのハンドトラッキングを使って何かやる（２）

#概要
前回の記事では、Oculus Questのハンドトラッキングを使用して開発したアプリを一つご紹介しました。
今回はその続きで、新たに開発したアプリをご紹介していきます。

#開発環境
 + Windows10 Home
 + Oculus Quest
 + Unity 2019.2.6

#ハンドトラッキングと音楽
音楽を始めたての初心者の人は、上級者の人はどのように手を動かしているのかということを少なからず考えたことがあると思います。著者自身もギターを弾いていて、どうやって弦を押さえているのか、ストロークはどうやっているのかなど、よう〇べの動画を見ながら必死に練習したのはいい思い出です。
演奏中の手の動きのアーカイブを取っていつでも再生できるようにするだけでも需要はありそうだし、演奏者と同じ目線に立って動きの確認ができるのでより効率的に習得できるのではないかと思います、、、そんなことを考えつつ早速アプリ開発！！今回はピアノとドラムを作成してみました。
####（楽器に触れて音が出る、、それだけでも楽しそう！という単純な思考で作ろうと思ったわけじゃないんだからね！！）

まずはモデルを用意！！前回と同じく標準のProbuilderでモデルの制作を行いました。
そして、各楽器のキーを配置し、手との当たり判定をつけていきます。

###完成

![piano.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/2696586e-f0bb-db5f-560e-2091cf117e68.jpeg)
![drum.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/c2431c36-dd82-a418-525c-cff1b40111dd.jpeg)

#所感
触れて音が出るだけだが、十分楽しめるものになっていました。しかし、キーボードと同様に課題も多くありました。大きな課題として、どちらも高速で手を動かすことが多いので、手の認識が追い付いていないことや、またドラムでは、叩き方として手をクロスしながら引くことが多く、そもそも手が検出されないことなど（根本的にだめじゃん、、、）
これですべてを補うことは正直不可能であると感じました。しかし、部分的にハンドトラッキングの技術を取り入れることで演奏技術の習得を効率的に進められる楽器や指導方法などがあるのではないかと、可能性を感じることはできました。
やはりエンタメに寄せていった方が良いのかな、、、？
アプリ自体の出来は悪くないと思ったので、これからもさらに拡張していこうと思います。
Bootcamp上のWindowsで，トラックパッドのスクロール慣性を有効にする 

Bootcampを使い始めてからの懸案でした。

https://qiita.com/Khromium/items/8e5c54fe385d395dd9b1#trackpad%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B

ここで解決しました。感謝です！

# 環境
MacBook 12インチ
Bootcamp Windows10 Home Build 17763

# 手順

- 以下のページにアクセス。

https://github.com/imbushuo/mac-precision-touchpad

- あとはREADME.mdの通りなのですが，

```
Converged Installation Guide
Disable Secure Boot if your MacBook comes with Apple T2 Security chip: Boot with Command + R, select Startup Security Tools and disable Secure Boot (No Boot Security)
Go to the release tab in Github and download the newest version
Open the zip and navigate to x64\ReleaseSigned
Go to AmtPtpDeviceUniversalPkg directory
Right click AmtPtpDevice.inf and install it
Confirm driver publisher
```

- いちおう書きますと，Releases タブに移動し，AmtPtpDeviceUniversalPkg.zip をダウンロード，解凍し，`AmtPtpDevice.inf`をインストールします。私は以下の zip でした。

https://github.com/imbushuo/mac-precision-touchpad/releases/download/1910-3665/AmtPtpDeviceUniversalPkg.zip

3本ジェスチャーも有効になりました。[Win] - 設定 - デバイス - タッチパッド を見ると確認できました。3本指 上スワイプで，「マルチタスク表示」になります。すばらしい！
新世代GPUで古いバージョンのChainer (v1.24) を使う

# 背景

私は製造業の研究職です。少し前より深層学習モデルを用いた外観検査システムを運用しており、システムのGPUにはQuadro P6000 (Pascal世代), 深層学習ライブラリにはChainer v1.24, CUDAはv8.0を使っていました。
今回、新たなラインに外観検査システムを導入することとなりましたが、Quadro P6000はディスコンとなっており、代わりにQuadro RTX6000 (Turing世代) を積んだPCをベンダより薦められました。
しかし、

- Turing世代のGPUでは（古いバージョンである）CUDA8.0はそのままでは使用できないため、CUDAのアップデートが必要
- Chainer v1.24がサポートするCUDAは8.0までのため、CUDAアップデートをするとchainerもアップデートが必要
- chainerをアップデートするとソースコードの改修が必要

ことが問題でした。
ソースコードが異なるソフトが存在すると、外観検査システムの今後の運用保守のトラブルになりうるため、Turing世代GPU, CUDA8.0, Chainer v1.24を使う方法を探しました。

# Turing世代GPU, CUDA8, Chainer v1.24をそのまま動かすと？

下記のエラーが出てソフトが止まります。
`nvcc fatal : Value 'sm_75' is not defined for option 'gpu-architecture'`

これはCUDA8のプログラム上ではTuring世代のGPUがサポートされていない（定義されていない）ため、NVCC ( NVIDIA CUDA C++ compiler) がChainerの動作に必要なCUDAプログラムをコンパイルしようとする際にエラーが出ています。

# 解決法

NVCCにはcubinファイルと呼ばれるGPU世代に固有のファイルを生成するオプションと先方互換性ーーつまり、自分より新しい世代のGPUへの互換性ーーを持たせたptxファイルと呼ばれるファイルを生成するオプションがあります。
これを使うと（古い）Pascal世代までをサポートするCUDA8を使って（新しい）Turing世代で動作が可能になります（[参考](https://docs.nvidia.com/cuda/turing-compatibility-guide/index.html)）。

そこで、chainer内部でcubinファイルを生成する処理を行っている箇所をptxファイルを生成するように変更します。
具体的には、site-packages/cupy/cuda/compiler.pyのnvcc関数でその処理が行われていますので、ここを変更します。

## 変更１
```python
    # cmd = ['nvcc', '--cubin', '-arch', arch] + list(options)
    cmd = ['nvcc', '--ptx', '-gencode=arch=compute_61,code=sm_61']
```

コメントアウトしたオリジナルのコードでは、`--cubin`という引数から推測できるようにcubinファイルを生成しています。
ここを`--ptx`に変更し、`-gencode`引数でPascal世代より先に先方互換性を持たせたptxファイルを生成することを宣言します。
'sm_XX'がどの世代のGPUを指しているのかは[このサイト](https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/)に分かりやすくまとめてあります。

## 変更２

```python
    with TemporaryDirectory() as root_dir:
        path = os.path.join(root_dir, 'kern')
        cu_path = '%s.cu' % path
        cubin_path = '%s.cubin' % path
        ptx_path = '%s.ptx' % path ## modified

        with open(cu_path, 'w') as cu_file:
            cu_file.write(source)

        cmd.append(cu_path)
        _run_nvcc(cmd, root_dir)

        with open(ptx_path, 'rb') as bin_file: ## modified
            return bin_file.read()
```
オリジナルのコードでは（ptxファイルでなく）cubinファイルを読み込むように作られているので、変更１だけではcubinファイルが見つからない、と怒られます。
なので、ptxファイルをreadするように修正します。

これで（私の環境では）動きました。

## 注意

コンパイルは時間のかかる処理のため、一度コンパイルしたファイルはhome/.cupy/kernel_cache下にキャッシュされています。
そのため、変更前の動作しないキャッシュファイルが残っていると、chainerはキャッシュファイルを読み込み、「compiler.pyを修正したのに動かない！」となるかもしれません。

# 副作用：cuDNN初期化処理が遅い

cubinファイルでは、cuDNNの初期化処理は1秒未満で終わっていましたが、ptxファイルを使うと30～60秒ほど時間がかかるようになってしまいました。
この初期化処理はNVIDIA謹製のsoファイル内で行われているようで、私の力で修正するのは諦めました。

私の外観検査システムでは初期化に30～60秒ほどかかるのはNGであるため、cuDNNを使用しないようにすることで解決しました。
その結果、推論速度が0.2s -> 0.4sと倍かかるようになりましたが、これは私のシステムでは許容できます。

chainerでcuDNNをdisableにするには環境変数で設定すればいいです。
ただし、chainerをimportする前に設定しておく必要があります。

```python
os.environ['CHAINER_CUDNN'] = '0'
```

# P.S.

Chainerすごく使いやすく大好きでした。おかげで深層学習の研究開発スピードが非常に上がりました。
Preferred Networksさん、ありがとうございました。

# さいごに

- （外観検査システムなど）機械学習システムの運用保守についての工夫・苦労をお聞きしたいです。
「うちではこんな風にエッジ側の環境構築してる/AIモデルをデプロイしてる/モデル精度を監視してる」などなど...。
- cuDNNの初期化が遅くなる問題について、解決法と思しきものをご存知でしたらお聞きしたいです。
【Homebrew】Windows10で$ brew install chromedriverはできない

# コトの顛末
Windowsにrubyを導入して、seleniumを使用した自動テストや情報収集をするツールを作りたくて、
環境構築をしておりました。
そのなかで、**chromedriver**なるものをDLして**パスを通す**をしてくださいということが書いてあったのですが、
「え、何言ってるのわからない。エラーでるし。」ってなっていろいろ調べていたら、

```console
$ brew install chromedriver
```
このコマンドで簡単にインストールできるよ。
って記事を見たので打ち込みでみたら、
**「Homebrewが入ってないからこのコマンドを実行できないよ」**となりました。

と、いうことで
Windows10にHomebrewをインストールしてから、再度selenium用の環境構築しよう！
ってなわけで始まりました。

# 結論 Windowsで```$ brew install chromedriver```はできない
**できない**と言ったら語弊がありますが、キッパリ言いました。
悲劇は繰り返してはならない。
そのためのQiita、そのためのteratail。

ちゃんと説明すると、
環境構築で```$ brew install ~```の類のコマンドは使えるようになります。
しかし、```$ brew install chromedriver```はMACしかサポートしてないため、

コマンドは動く、やってほしいことはできない。

という結果に終わりました。

```console
$ brew install chromedriver
Updating Homebrew...
==> Auto-updated Homebrew!

~ 省略 ~

Error: No available formula with the name "chromedriver"
You can access it again by running:
  brew tap homebrew/cask
And then you can install it by running:
  brew cask install chromedriver
```

エラーが出て、```$ brew cask install chromedriver```でやってみたら？
という提案がターミナル上に表示されます。

``` console
$ brew cask install chromedriver
Error: Installing casks is supported only on macOS
```

**supported only on macOS**

うわぁ...たまげたな....
環境構築中にもいろいろエラー出て、やっとbrew使えるようになったのに

MACだけよ＾＾

とかいう喜劇。

# たった１つのコマンドを入力するためにやったこと
結果的に**MACでやろうね＾＾**と一蹴されてしまったのですが、
Windowsでbrewを使用するには下記のような環境構築が必要でした。

1.WSLを有効にしてLinuxを使用できるようにする
2.UbuntuをストアからDLしてLinuxコマンドを使用できるようにする
3.Homebrewをインストールしてbrew hogehogeコマンドを使えるようにする。

## 各種参考記事

 [Windowsでもbrewを使いたい！WSLのインストールとホームディレクトリの変更、そしてbrewが使えるようになるまで](https://qiita.com/yukiarrr/items/1e1562fb2a3ba7384d1b)

まず、「brew導入しよう！」ってなった時に見た記事はこちらです。
ニッチなことがらだったので、記事があるか不安だったのですが、先人の知恵記事があり大変助かりました。

こちらの記事でもできるようですが、私の環境では途中で「コマンドがないよ」的なエラーが出てしまいました。

そしたら、下記のような記事を教えて貰いました。

[Windows 10にUbuntuをインストールしよう](https://news.mynavi.jp/article/liunx_win-2/)

この記事内では**Ubuntuアップデートコマンド**が書かれており、「コマンドがないよ」のエラーは解決しました。

``` console
$ sudo apt update
$ sudo apt upgrade
```

**日本語環境用パッケージのインストール**コマンドと、日本語環境の設定についても書かれており、大変助かりました。

```
$ sudo apt install language-pack-ja
$ sudo apt install manpages-ja
```

これで、なんとかWindowsでLinux環境が整い、
brew hogehoge的なコマンドが使用できるようになりました。

ここから、brewを入力していくのですが、

rubyを入れてね！とかそういうエラーが出ました。

コマンドプロンプト（winのターミナル）でruby使用できるのになんでだろうと想ったら、
コマンドプロンプトと、Ubuntuで別物なので、再度ruby入れないといけないようで入れました。

### それでも出る出るwarning

``` console
Warning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.)
```
いわゆるパスを通してないってことでしょうか。
指定された場所にファイルがないから実行できないっていう感じですかね。

下記のサイトを見て解決しました。

[linuxbrewのインストール時(Warning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.)が発生する](https://mo3789530.hatenablog.com/entry/2019/02/11/231033)

``` console
＄echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' >>  ~/.bashrc
＄source ~/.bashr
```

# 結局どうしたこうした

[windowsならruby + selenium webdriverも環境設定は15分で終わる](http://katsulog.tech/if-windows-ruby-selenium-webdriver-also-ending-the-configuration-in-15-minutes/)

上記の記事を参考に、書かれたことを忠実に行い、
とりあえず、指定のURLをchromeで開くだけのミニマム実装したプログラムを実行したら動作しました。
なのでここからは普通にseleniumを使用した実装に突入します。

# おわりに
いかがでしたでしょうか。
時間はかかったし、簡単なゴールだったはずなのに
な　ぜ　か　苦戦した事案でした。
環境構築ってそんなに何度もすることではないし、
すばらしい記事がそこらへんに転がっているので、
苦戦しながら構築するっていい経験だったなぁと思いました。
アフターエフェクトで「線が伸びる」アニメーションを作るときにごっちゃになったこと

結論（とても似た方法があるのでごちゃごちゃになっていました。）

アフターエフェクトを勉強し始めたんだけど色々触るところがあってまだまだ混乱しています。


はじめの方で線が伸びるというアニメーションを作っていた。

参考になる動画を見ながら作ってみた。

できた。

数日たってまた作ろうとするとなぜかできない。どこをいじっていたか忘れてしまう。
こんな感じで作っていただろうと思い出しながらやってみてもうまくいかない。


そこで、また動画で解説されているものを見ながら作る。

できる。


数日後、自分で作ってみようとするがまたなぜかできない。終了点というところをいじるはずが出てこない。


そこでまた動画を見て
忘れて
見て


を繰り返したが、やっとごちゃごちゃになる理由がわかった。

とても似た方法が2つあってごっちゃになっていたのだ。


一つ目は何かバックグラウンドのレイヤーを作っておいて
ペンツールで線をかく(この線はマスクと呼ばれるもの)
エフェクト→描画→線
そうするとエフェクトの中に線というところが出てきて「終了」を設定してアニメーションを作ることができた。
https://btuber.jp/after-effects-yajirushi/


もう一つの方法は
バックグラウンドのレイヤーとは違うシェイプレイヤーをまず作る
ペンツールで線をかく（この線はシェイプのパスと呼ばれるもの？）
ここでエフェクトではなくレイヤーの横の方にある三角形みたいなボタンを押して「パスのトリミング」を選択するとそれが追加されるそこに「終了点」というものがあるのでアニメーションを設定することができる
https://www.cyber-promote-movie.com/wp/2018/06/13/ae_line_animation/




この２つの方法が自分の中でめちゃくちゃ混同してしまう。
どのレイヤーでペンツールを使うかでパスになるかマスクになるかが変わるのがめっちゃわかりにくい。

パスに対しては「パスのトリミング」を追加する したyoutubeの緑線
マスクに対してはエフェクトの「描画→線」を追加する　　　赤線
　　
ややこしすぎるでしょ！　　自分だけですかね


https://www.youtube.com/watch?v=F-23D2fWKXA
Angularで認可(Guard)、成功したら認可前のページへリダイレクト

# 概要
ログインが必要なページなどには認可をするわけですが、それをAngularでやりました。
ついでに、認可が成功したらアクセスしようとしていたページへ飛ばすというのもやりました。

# 環境
- Angular 8.2.9

# 実装
## 認可(canActivate)
まずはGuardを作ります。ここでは`Auth`という名前で作っています。

```
ng g guard Auth
```

できたファイルを編集して認可をします。

```src/app/auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private router: Router,  private authService: AuthService) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (!this.authService.isLogin()) {
      this.router.navigate(['sign-in'], {queryParams: {history: state.url}});
      return false;
    }
    return true;
  }
}

```
`canActivate`が認可判定をする本体で、`true`を返せば認可、`false`を返せば否認ということになります。私のプロジェクトでは`AuthService`というサービスで認証を行っていて、認証が失敗すればログインページにリダイレクトし、認証が成功すれば認可をするという実装になっています。
ログインページにリダイレクトする際に、クエリパラメータに現在のURLを付けています。例えば、`/edit/12`というページからログインページにリダイレクトする際には、`/`がエンコードされ、`/sign-in?history=%2Fedit%2F12`にリダイレクトされます。

## 認証
リダイレクト先の処理は以下の通りになります。

```src/page-sign-in.component.ts
(省略)
export class PageSignInComponent implements OnInit {

  login: Login = {
    email: '',
    password: '',
  };

  private history: string;

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private authService: AuthService,
    private alertService: AlertService
  ) { }

  ngOnInit() {
    this.activatedRoute.queryParams.subscribe(
      params => {
        this.history = params.history;
      }
    );
  }

  onSubmit() {
    this.authService.login(this.login)
      .then((res) => {
        this.router.navigate(this.history ? [this.history] : ['home']);
      })
      .catch((err) => {
        console.error(err);
        this.alertService.showErrorAlert('メールアドレスとパスワードに間違いがないか確認してください。');
      });
  }
}

```
`ngOnInit`でクエリパラメータからリダイレクト前のURLを抜き出しています。ログインボタンが押され、`onSubmit`で認証が成功し、リダイレクト前のURLがある場合にはそのURLに、なければ`'home'`にリダイレクトさせています。

# 参考
https://qrunch.net/@tercel/entries/5Nchk71nQYRbgqQP
ReactNative (expo)でSHA256とかを使ってみる


どうやらexpo-cryptoってのを使えばできるみたい。
試しに出力してみる。


```jsx:App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

import * as Crypto from 'expo-crypto';

export default class App extends React.Component {

  componentDidMount = async () => {

    const digest = await Crypto.digestStringAsync(
      Crypto.CryptoDigestAlgorithm.SHA256,
      'Hello'
    );

    console.log(digest);
  }

  render() {
    return (
      <View>
        <Text>App</Text>
      </View>
    );
  }
}

```

consoleに下記のように出た。いてけてるみたい。

```bash
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
```

いちおう別ツール（Macのコマンドライン）で確認。



```bash
echo -n "Hello" | shasum -a 256

185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969  -
```

同じ内容となってますね。
[Mac] SSH git cloneでポート番号がおかしくなった時の対処方法

## 何が起きた
SSHで`git clone`しようとすると、次のようなエラーが出ました。

```sh
$ git clone git@github.com:hoge/fuga.git
Cloning into 'fuga'...
ssh: connect to host github.com port 10022: Operation timed out
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
`git clone`  する際のポート番号が10022へ変わっています。(22が正常)

## 何故起こった

Macへのリモートアクセスを設定する際、sshのポート番号をデフォルトの22から変更したことが原因でした。

次の記事によると、MacでSSHポート番号を変更する方法は次の3つがあります。
[Mac に SSH でリモートログインする方法 | Mac person](https://macperson.net/mac_ssh_server/)

>ポート変更を行うには以下のいずれかの方法を取る必要があります
1. ssh_port.plist 等の別の plist ファイルを作成し、OS 標準の SSH デーモンとは別で SSH デーモンを立ち上げる
2. 「System Integrity Protection」を一度無効化し、ssh.plist を書き換える
3. /etc/services の ssh の項目を変更し、ssh = 22 の割り当てを別に変更する
（ただし、ssh クライアントのデフォルト接続ポートも変更されます）

このうち、今回は3.でポート番号を変更したため、デフォルトの接続ポートまで変更されていたようです。


## どうすればよいか

3.の設定を元に戻し、1.で新しく接続設定します。
まず、`/etc/services`をデフォルトに戻します。

```
$ sudo vim /etc/services
```

該当行を次の通り修正します。

```
ssh              22/udp     # SSH Remote Login Protocol$
ssh              22/tcp     # SSH Remote Login Protocol$
```

次に、デフォルトとは別のSSHデーモンを立ち上げていきます。

```sh
# ssh.plistをコピー
$ sudo cp /System/Library/LaunchDaemons/ssh.plist /Library/LaunchDaemons/ssh_port.plist
# ポート番号を10022へ変更
$ sudo defaults write /Library/LaunchDaemons/ssh_port.plist Sockets '<dict><key>Listeners</key><dict><key>Bonjour</key><array><string>ssh</string><string>sftp-ssh</string></array><key>SockServiceName</key><string>10022</string></dict></dict>'
# launchdにサービスを登録
$ sudo launchctl load /Library/LaunchDaemons/ssh_port.plist
```

`システム環境設定>共有>リモートログイン`でチェックボックスのチェックを外し、再度チェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/bebeb207-171e-4cd5-18af-79573b5ee381.png)

次のように表示されれば正常に設定できています。

```sh
$ netstat -anl | grep 10022
tcp4       0      0  *.10022                *.*                    LISTEN
tcp6       0      0  *.10022                    
```

最後に再度`git clone`します。

```sh
$ git clone git@github.com:hoge/fuga.git
Cloning into 'fuga'...
remote: Enumerating objects: 144, done.
remote: Counting objects: 100% (144/144), done.
remote: Compressing objects: 100% (74/74), done.
remote: Total 3116 (delta 85), reused 105 (delta 64), pack-reused 2972
Receiving objects: 100% (3116/3116), 33.57 MiB | 4.13 MiB/s, done.
Resolving deltas: 100% (2073/2073), done.
```

正常に`git clone`出来るようになりました。


## 参考
[Mac に SSH でリモートログインする方法 | Mac person](https://macperson.net/mac_ssh_server/)
[Mac OS X SSHのポート番号を変更する方法  【ブログ】 » 群馬県高崎市の写真撮影・ホームページ制作会社| Kiraba（キラバ）](https://kiraba.jp/how-to-change-machintosh-ssh-port-number/)
[Macでdefaultsコマンドで設定出来るオプションを調べる](https://rcmdnk.com/blog/2015/03/22/computer-mac/)
【サンプルロボ】日付によって ロボットで行う処理を変える場合の判定方法

【アルゴリズム<img width="482" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/152f64a7-8833-d1ee-34b7-950a2e7ffe91.png">
】
クロンでもひづけごとに分けることは可能
位置引数とタプル化と辞書化の混在

```py
def players(job, *args, **kwargs):
    print(job)
    print(args)
    print(kwargs)

players('勇者', '戦士', '魔法使い', job1='僧侶', job2='魔法剣士')
```

```:実行結果
勇者
('戦士', '魔法使い')
{'job1': '僧侶', 'job2': '魔法剣士'}
```

jobに'勇者'が
argsに('戦士', '魔法使い')がタプル型で
kwargsに{'job1': '僧侶', 'job2': '魔法剣士'}と辞書型で
格納されている。

ただし、
*1つが*2つよりも先でないと、
syntax errorとなるので注意。
【サンプルロボ】パラメータで指定した条件に沿って ディレクトリ フォルダ 内のファイルを検索するSnippetとロボット

【アルゴリズム】<img width="285" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/15850ac2-89ab-8ba3-6523-d50c92284783.png">

【ぽいんと】
<img width="390" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/45da5d3c-d0a0-df27-f9ed-c56de9572b91.png">

・分岐しているが、違いはサブディレクトリを含めるにチェックがついているかどうかだけ。
・変数に検索対象の文字列や拡張子（extention）をいれる