OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonではじめる機械学習　決定木のアンサンブル法

#はじめに
"Pythonではじめる機械学習"の決定木のアンサンブル法(p82~90)の学習記録です。
・分からなかったコードやドキュメント
・自分にとって理解するのに時間がかかった内容
・用語の定義
に関する説明を主に記述しています。
参考書を読んでいて容易に理解できたことは記述していません。

#2.3.6　決定木のアンサンブル法
アンサンブル法(Ensembles)とは、複数の機械学習モデルを組み合わせることで、より強力なモデルを構築する方法である。
主なアンサンブル法は、ランダンフォレストと勾配ブースティング決定木である。

##2.3.6.1　ランダンフォレスト
ランダムフォレストとは少しずつ異なる決定木を集めたもの
✳︎p82~p83の説明が全体的に分からなかったので、再読する必要あり。

```
#In[66]
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_moons

X, y = make_moons(n_samples=100, noise=0.25, random_state=3)
# stratifyで指定したデータの比率を均等に分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)

# n_estimatorsで決定木の数を指定
forest = RandomForestClassifier(n_estimators=5, random_state=2)
forest.fit(X_train, y_train)

#In[67]:
# ravel関数は、多次元のリストを1次元のリストにして返す
# enumerateはforループの中でリストやタプルなどのイテラブルオブジェクトの要素と同時にインデックス番号（カウント、順番）を取得できる 
fig, axes = plt.subplots(2, 3, figsize=(20, 10))
for i, (ax, tree) in enumerate(zip(axes.ravel(), forest.estimators_)):
    ax.set_title("Tree {}".format(i))
    mglearn.plots.plot_tree_partition(X_train, y_train, tree, ax=ax)

# グラフの透過度の指定がalpha
mglearn.plots.plot_2d_separator(forest, X_train, fill=True, ax=axes[-1, -1], alpha=.4)
axes[-1, -1].set_title("Random Forest")
mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train)
```

Out[67]:
５つのランダム化された決定木による決定境界と、それらを平均して得られた決定境界
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1323856/30182c08-4063-1c15-c890-6cfb1cdf1089.png)

ランダムフォレストは個々のどの決定木よりも過剰適合が少なく、直感に合致した決定境界を描いている。
回帰でもクラス分類でも、ランダムフォレストが最も多く使われている機械学習手法である。


##2.3.6.2　勾配ブースティング回帰木(勾配ブースティングマシン)
勾配ブースティング回帰木は、複数の決定木を組み合わせてより強力なモデルを構築するもう一つのアンサンブル手法である。
1つ前の決定木の誤りを次の決定木が修正するようにして、決定木を順番に作っていく。
ランダムフォレストの方が頑健だが、予測時間が重要な場合や、機械学習モデルから最後の1%まで性能を絞り出したい場合は勾配ブースティングを試す。
勾配ブースティングが教師あり学習の中で最も強力で広く使われているモデルである。

###メモ：
jupyter notebookで何故か、定義した変数やインポートしたモジュールが定義されていないという表示が稀に起きる。その場合、jupyter notebookを終了して再起動した後、実行すれば直る。原因は不明。
Windows10にaglioをインストールしたかっただけなのに

Windows10環境でaglioを使ってAPI BlueprintをHTMLにしたかったけれど、エラーが出てだいぶハマった結果なんとか使えるようになったので共有。

# ハマったパターン

Node.js(v14.16.1)をインストーラーでインストール
おもむろにaglioをグローバルインストール

```console
npm install -g aglio
```

# 結果

悲しみのException

```console
gyp ERR! UNCAUGHT EXCEPTION
```

# やったこと

- Node.jsのアンインストール
  - スタートメニューからアンインストーラーを実行

- nodistのインストール
  - https://github.com/nullivex/nodist/releases

- バージョンを指定してインストール
※ 8以降でもいけるかも。最新だとエラーが発生した。

```console
nodist + 8.17.0
nodist npm 6.13.4
```

- Visual Studio Build Tools 2019 のインストール
  - https://visualstudio.microsoft.com/ja/thank-you-downloading-visual-studio/?sku=BuildTools

おもむろに

```console
npm install -g aglio
```

成功

# 結局？？

Node.jsのバージョンが新しすぎた
Visual Studio Build Tools が古すぎた

ということっぽい

# (追記)
PowerShellでnodistを動かす時に「このシステムではスクリプトの実行が無効になっているため、～」というメッセージが出て動かなかったことがありました。
下記の記事が参考になりました。
ありがとうございます。

https://qiita.com/ponsuke0531/items/4629626a3e84bcd9398f
GitHub ActionsでXserverにあるWPに自動デプロイを設定する

１．GitHubのSecretsにXserverの秘密鍵を登録する

公式を参考

https://docs.github.com/ja/actions/reference/encrypted-secrets

２．`.github/actions/deploy.yml` 作成

```yaml
name: deploy to xserver

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      # 必要に応じてgulpなど
      # - name: gulp build
      #   uses: actions/setup-node@v1
      # - run: yarn install && yarn run build\
      - name: Install SSH key
        uses: shimataro/ssh-key-action@v2
        with:
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          known_hosts: sv1111.xserver.jp
      - name: rsync deploy
        run: rsync -vrlp -e "ssh -p 10022 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" ./dist/ username@sv1111.xserver.jp:/home/username/example.net/public_html/dist/
```

参考

- https://www.to-r.net/media/github-actions/
- https://github.com/marketplace/actions/install-ssh-key

---

※こちらの記事は自ブログからの転載です

https://akinov.hatenablog.com/entry/2021/04/14/224709
springでwebアプリを作成する機会があったのでまとめてみました（メモ）

自社で資材を管理するシステムを作ったので復習も兼ねてまとめていきたいと思います。

**スキル**
・Java Silve 取得
・oracle_bronze[12c SQL基礎] 取得
・サーブレット、javaScriptは軽くわかる
・HTML、CSSはわかる

上記のスキルでspring開発に携わりました。

####spring開発で重要だと感じた3つの項目についてまとめていきたいと思います。
**・3層アーキテクチャ**
**・システム構成**
**・Webアプリ(apring)**

#3層アーキテクチャ
※アーキテクチャ・・・構成のこと

Webアプリは3種類のサーバーから成り立っています。
![ev074.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/f25ec46c-ca03-0edd-29fd-aef5b4211808.jpeg)


####■Webサーバー
クライアントからの要求に対して
「静的コンテンツを見せる」と「APサーバーに動的コンテンツを要求し、返ってきた結果を見せる」という2つの役割。
※静的コンテンツ　→　常に同じ内容
　動的コンテンツ　→　検索、送信内容によって異なる

####■APサーバー
Webサーバーからの要求に対して「動的コンテンツを生成」と「データを保存したり、やりとりができる」という2つの役割。

####■DBサーバー
Webサーバーからの要求に対して「データを書き込んだり、必要な情報を引き出したりできる」という役割。

![ev075.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/7817a253-c92b-f0e3-8a87-394c767ae271.jpeg)

さらに、**APサーバーは3層**に分けることができます。
各層によって役割が違います。

例えば、4択クイズアプリを作成する
（例）
プレゼンテーション層　→　ユーザとやりとり
ビジネスロジック層　→「問1は1番が正解、問2は4番が正解」などのルール決める
データアクセス層　→　問題の結果を保存

「表示方法、ルール、データの永続化を分離する」という 3 層が何より基本

#システム構成
今回のシステム構成はこんな感じだったと思います。

![ev079.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/6f4d5af3-7645-525a-6040-8152972a41ea.jpeg)

![ev080.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/d0f86944-4b98-00fb-bf5f-24cf029aa1cb.jpeg)






#Webアプリ(apring)
springの動きについてついて書いていこうと思います。


![ev076.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/a48c8873-1eb0-a5a9-0b81-62bc05362d2f.jpeg)
■APサーバー3層
こんな感じで役割が分かれています。


		
![ev077.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/e3d5ada8-1afe-c3a0-c1a9-695207a6ffbb.jpeg)
■プレゼンテーション層
・Controller・・・クライアントからのリクエストに対応し、処理の結果を再びクライアントに返す**司令塔**の役割をします。
・Model・・・ View と Controller 間のデータ受け渡しをする役割をします。
・view・・・画面への表示や入出力処理をする役割をします。
・ajax・・・非同期処理。※jQueryでajax作成
           　　　　　　(例)データ更新する
　　　　　　　同期：URL又は画面を変更することでデータの更新可能。
　　　　　　　非同期：URL又は画面を変更することなくでデータの更新可能。
　　　　　　　　　　　（実際は裏で変更している）


■ビジネスロジック層
この層ではルールを決めていきます。
基本、コントローラに呼ばれ、各メソッド単位での**トランザクション処理**が行われます。

トランザクション処理・・・処理が始まり終わるまでの処理のことをいいます。

※メモ
DI（Dependency Injection）・・依存性の注入

DIを用いることによってメリット
・newしてインスタンスを生成しなくていい
・インスタンス化は1回でいい

```java
@Controller
public class ItemController {
    @Autowired //DI
    private ItemService itemService;

    （メソッドなど）
}
```


![ev082.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/881c3e4a-19d2-05d5-942c-2d89defcef90.jpeg)
■データアクセス層
・DAO(Data Access Object)・・・DBとやりとりするクラスのこと

・MyBatis・・・オブジェクト指向言語におけるオブジェクトとデータベースの関係を築いてくれる便利ツールのこと。
※MyBatisのようなにオブジェクトとデータベースの関係を築いてくれることを**総称O/Rマッパー**という。
　MyBatisもO/Rマッパーの一つということ。MyBatis以外にもSpring Data JPAなど便利なツールはたくさんあります。

・Mapper・・・Javaファイル（インターフェイス）とXMLファイル（SQL）の２セット生成する。
　　　　　　　　DBとのやりとりが可能になる。




###感想
・jQuery、springフレームワークを慣れるのに時間がかかった。
・デバックがどれだけ重要かわかった。
・成果物があると達成感がある。
初学者がLaravelを学ぶ3（コントローラー）

##コントローラーについて
webページの基本的な処理はコントローラを使って行うのが基本です。
またMVCアーキテクチャの基本となるものです。

##MVCとコントローラ
ルーティングはアクセスしたアドレスをもとに処理を割り振る役割でした。ただそれだけではなく、具体的に実行するべき処理は別に用意されていて、それを特定アドレスに割り振って呼び出すための処理です。

MVCとはモデル、ビュー、コントローラの頭文字をとったものです。

モデルはデータ処理全般を担当します。具体的にはデータベースに関する処理全般を司ると言って良いと思います。

ビューは画面表示を担当します。表示に使うテンプレートなどがこれに相当します。

コントローラは全体の制御を担当します。必要に応じてモデルからデータを取得したりビューを利用して画面表示を作成したりします。

##コントローラの作成
作成中のアプリのフォルダディレクトリで以下のコマンドを実行することで作成できます。

```
php artisan make:controller HelloController
```

これによってHelloControllerが作成できます。
ちなみにHelloの部分の名前を変えることで違うコントローラ名で作成することができます。

下記はHelloController.phpの中身です。
順番に内容を見ていきます。

```
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
   //
}

```
###controllersと名前空間

コントローラはクラスとして作成されます。このクラスはApp\Http\Controllersという名前空間に配置されます。
名前空間とはクラスを階層的に整理するための仕組みです。フォルダを使って階層的にファイルを管理するのと同じだと思っておけばいいと思います。
一行目のnamespace App\Http\Controllers;
は名前空間を指定しています。


###useによるインポート
次に記述されているのはuse文です。以下のように記述されています。

```
use Illuminate\Http\Request;
```
ここではIlluminate\Httpパッケージ内に用意されているRequestを使える状態にしています。
まだこの段階ではRequestは不要ですがこれから多用することとなるクラスのためデフォルトでuse文が追加されています。

###クラスの定義
続いてクラスが提起されています。HelloControllerは以下のように定義されています。

```
class HelloController extends Controller
```
コントローラクラスはこのようにControllerというクラスを継承して作成します。

##アクションを追加する
コントローラに用意される処理はアクションと呼ばれる。これはメソッドの形で用意されます。
今回は以下のようにindexメソッドを追加してみます。
ここではindexのように引数を持たないメソッドとして用意されています。（場合によっては引数を用意することもあります。）
アクションメソッドはreturnを使ってHTMLのコードを返しています。結果、returnした内容がウェブブラウザに返され表示されることになります。


```
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
  
   public function index() {

       return <<<EOF
<html>
<head>
<title>Hello/Index</title>
<style>
body {font-size:16pt; color:#999; }
h1 { font-size:100pt; text-align:right; color:#eee;
   margin:-40px 0px -50px 0px; }
</style>
</head>
<body>
   <h1>Index</h1>
   <p>これは、Helloコントローラのindexアクションです。</p>
</body>
</html>
EOF;

   }
}
```

ただこれだけでは表示はできません。ルーティングを変更する必要があります。
web.phpを開き先程の記述を削除しルーティングを変更していきます。

```
Route::get('hello', 'HelloController@index');
```

第二引数には関数ではなくコントローラ名@アクション名が記述されています。
これにより第一引数のアドレスにアクセスしようとすると第二引数に指定されたアクションが実行されるようになります。

###コントローラを使ったルートパラメータの利用

ルートパラメータ（アクセスする際にパラメータとして値を渡すことができる）を使用する場合は以下のように編集します。

```
class HelloController extends Controller
{
  
   public function index($id='noname', $pass='unknown') {

      return <<<EOF
<html>
<head>
<title>Hello/Index</title>
<style>
body {font-size:16pt; color:#999; }
h1 { font-size:100pt; text-align:right; color:#eee;
   margin:-40px 0px -50px 0px; }
</style>
</head>
<body>
   <h1>Index</h1>
   <p>これは、Helloコントローラのindexアクションです。</p>
   <ul>
       <li>ID: {$id}</li>
       <li>PASS: {$pass}</li>
   </ul>
</body>
</html>
EOF;

   }
}
```

ルーティングも以下のように編集していきます。

```
Route::get('hello/{id?}/{pass?}', 'HelloController@index');
```

これによって/hello/taro/yamadaというようにhelloの後に二つのパラメータをつけてアクセスするとそれらのパラメータが画面に表示されます。


![スクリーンショット 2021-04-15 22.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927542/84144b42-8653-ff4b-053f-aa41947e7226.png)
WSL2でWindowsのPATHを引き継がないようにする

会社でよくハマっている人がいるのでメモるシリーズ

WSL2はデフォルトでWindows側の環境変数引き継ぐ。
${PATH}を引き継ぐので、Windows側をいじっている人ほどLinuxで使えない文字が混じって他のところではまる。

```/etc/wsl.config
[interop]
appendWindowsPath = false
```

こうすると引き継がなくなる。
ローカル環境にDockerを使用しLaravelをgitからclone後、php artisan migrateのエラーでハマった件

どうも、初心者プログラマーTKOです。
今回は新しいdocker環境を試そうと今まで作っていたLaravelアプリをgitからcloneした際に、php artisan migrateのエラーではまった件について話させていただきます。


#新規Laravelプロジェクト　初期設定#

リポジトリをクローン後

```
$ docker-compose up -d --build 

$ docker-compose exec app bash 

# composer install

```

これで設定したローカルのポート番号にアクセスするとLaravelの画面が表示されます。


ここから
mysqlのDockerfileで設定した

MYSQL_DATABASE=laravel_local
MYSQL_USER=phper
MYSQL_PASSWORD=***
MYSQL_ROOT_PASSWORD=***

の値を参考にホスト側の.envファイルを設定します。

DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=***

その後


```
# cp .env.example .env

# php artisan key:generate
```

後はマイグレーションで終わり

と思ったのですが、、、

```
  Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

  at /work/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673| 

  Exception trace:

  1   Doctrine\DBAL\Driver\PDO\Exception::("SQLSTATE[HY000] [2002] Connection refused")
      /work/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18

  2   Doctrine\DBAL\Driver\PDO\Exception::new(Object(PDOException))
      /work/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:42

  Please use the argument -v to see more details.

```

出ました！予想外のエラー、、、

とりあえず何らかのキャッシュが残っているんだろうなと思い

```
# php artisan config:clear

# composer dump-autoload
```

を試してみましたが解決せず

DBが登録されていないのかと思いDB内に入るも

```

$ docker-compose exec db bash 
# mysql -u phper -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.22 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| laravel_local      |
+--------------------+
2 rows in set (0.02 sec)
```

ちゃんと登録されている、、、


調べたところ

.envの
DB_HOST=127.0.0.1
が
DB_HOST=db
だそうです!


なるほど、dockerはコンテナ同士で通信してるからローカルのIPアドレスを指定しても意味ないってことですね。

以後気をつけます。
LeetCode日本語修行2日目- [213- House Robber]

HouseRobberで適切な日本語は何。。。
強盗？
泥棒？

#House Robber
参考:https://leetcode-cn.com/problems/house-robber-ii/

###問題の内容

今、プロの泥棒としてのあなた、壮大な目標がありまう。
#####この町の全ての家を盗む。
各家に一定の現金が隠れています。
家と家並んでて、丸に成っています、最初と最後の家がくっついているということです。
また、家と家の間に防犯システムがあります。隣の家が同じ夜に入られたら、自動的に通報します。
各家の現金を整数配列を指定します。
警報装置に触せず、最高額を目指せよ
通訳、難しい。。。
###例:
示例 1：

入力：nums = [2,3,2]
出力：3
解释：一番と三番は繋いでいますので、同じ夜で盗むは禁止。

示例 2：

入力：nums = [1,2,3,1]
出力：4
解释：一番と三番　1+3

示例 3：

输入：nums = [0]
输出：0
###ヒント:
1 <= nums.length <= 100
0 <= nums[i] <= 1000

---
今回は、198の問題ほぼ同じですが、相違点は、最初と最後の家が繋いで
この場合、二つの状況に分けましょう。
一つは最初の家に手を出す、この場合：nums計算範囲は0...nums.size-2
も一つは最初の家に手を出さない、この場合：nums計算範囲は1...nums.size-1
そして、それぞれの条件の結果を出す、二つを比較して、　OK

```Kotlin
class Solution {
    fun rob(nums: IntArray): Int {
        if(nums.size == 1){
            return nums[0]
        } else if(nums.size == 2){
            return Math.max(nums[0],nums[1])
        } else{
            return Math.max(myRob(0,nums.size-1,nums),myRob(1,nums.size,nums))
        }

    }

    fun myRob(start: Int,end: Int,nums: IntArray) : Int{
        var pre = nums[start]
        var cur = Math.max(nums[start],nums[start+1])

        for(i in start+2 until end){
            var temp = cur
            cur = Math.max(cur,pre + nums[i])
            pre = temp
        }
        return cur
    }
}








js domから要素を取得して、必要な値のみ取得する

複数のradioボタンから情報を抜き出し、どこが選択されているかを調べる処理を行う。

radioボタンから、必要なvalueのみを取得する。
この時3パターンできることに気がつき書いてみた。

1はforeachで回す
2はfilterで取得する
3はfor of で回す

```html
A<input id="text1" name="sample" type="radio" value="https://media/1">
B<input id="text2" name="sample" type="radio" value="https://media/2">
C<input id="text3" name="sample" type="radio" value="https://media/3">
<input id="btn" type="button" value="test" onClick="sample()">
```

```js
let sample = function(){
  let link_ids = document.getElementsByName('sample');
  //#sample1
   link_ids.forEach(element => {
     if (element.checked == true){
         location.href = element.value
          //radioボタンが選択されているurlに飛ぶ
     }
   });

  //#sample2
   let array_ids = Array.from(link_ids)
   let data = array_ids.filter(link => link.checked == true)
    for (let i of data){
        if (i.checked){
            location.href = i.value
        }
    }

  //#sample3
  for (let i of link_ids){
    if(i.checked){
      location.href = i.value
    }
  }

  //sample4
  let data = document.querySelector('input[name=mytext]:checked');
    if(d !== null) {
       location.href = d.value;
    }
```

radioボタンの要素を取得すればnodelistとして取得できる。
link_idsは[object NodeList]として扱われる。
その時、foreachで回すことが可能

filterを使う際にはArrayに一度変換しなければならないようです。
filterは配列限定みたいですね。

for ofであれば、nodelistも回すことができるようです。

filterのみ、純正なarray(配列)しか回せないことが判明し勉強になりました。。。

###追記
sample4では、選択されたradioのみを取得





```js
  //豆知識
  let toString = Object.prototype.toString;
  console.log(toString.call(link_ids))
  //valueの型を調べてくれる link_idsは"[object NodeList]"
  //配列は"[object Array]"

  let ele = Array.from(link_ids)
  //配列に変換 objectがNodelistの場合にも可能


```

参考資料：

nodelist foreach
https://developer.mozilla.org/ja/docs/Web/API/NodeList/forEach
filter
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
型確認
https://techacademy.jp/magazine/35968
配列に変換
https://lab.syncer.jp/Web/JavaScript/Snippet/53/
Google app Scriptでゴミ出し通知botを作った話

#はじめに
学びのアウトプットとしてQiita初投稿したいと思います。
最近自動化って面白いなと感じてるyamkです

#Google app Scriptとは
Google app Script（通称:GAS)とはGoogleが開発、提供しているプログラミング言語です。

名前くらい知ってんねん。何ができるか教えろやって方が多いと思うので
何ができるか簡単にまとめると...

- Googleのアプリケーション(スプレッドシートやGmailなど)をクラウド上で簡単に操作できる。
- 各社が提供しているAPIを用いて様々なサービス(Lineやslackなど)と連携ができる.
- 大体javascript っぽいのでなんとなくハードルが低い（主観、まじで主観)

などなど
私自身まだまだ知らないことも多いですが、ざっとこんなところ。
初めて知ったとき”これめっちゃ便利に使えるんでは？”と感動した覚えがあります。

#ゴミ出し通知botを作るに至る経緯
最近引越しをしまして、新しい地域のゴミ捨ての種類(月曜は可燃ごみの日やら、土曜はペットボトルやら..)が
全く覚えらへん！毎回毎回カレンダー見て今日は可燃ゴミね！とかもだるい！
ならラインで前日の夜に通知すれば確認も楽やなと思いbotを作ることに

#bot
とりあえずコード

~~~gas
function trash_res_bot() {
  var accessToken = '########'; 

  var date = new Date();
  date.setDate(date.getDate() + 1);
  var comment = [];
  
  var f=1;
  switch(date.getDay()) {
      case 1:
      comment.push('燃えるごみ')
      break;
      case 2:
      comment.push('なんもなし')
      break;
      case 3:
      comment.push('古紙・雑紙・古着')
      break;
      case 4:
      comment.push('一般ごみ')
      break;
      case 5:
      comment.push('びん・缶ごみ・スプレー缶')
      break;
      case 6:
      if(f===1){
        comment.push('燃やせないゴミ')
        f=0
      }
      else{
        comment.push('ペットボトル')
        f=1
      }
      break;
      
  }
  
  if (comment.length < 1) return;
  
  var text = '\n明日は' + comment.join('、') + ' の日です!\nゴミあるならだしなよ' ;
  
  var message = text;
  var options = {
    'method' : 'post',
    'headers': {
      'Authorization': 'Bearer ' + accessToken
    },
    'payload' : {
      'message': message
    }
  };
  var response = UrlFetchApp.fetch('https://notify-api.line.me/api/notify', options);
  Logger.log(response);
}
~~~

これを上から見ていきます。

~~~gas
function trash_res_bot() {
  var accessToken = '########'; 
~~~
この部分ですね、
accessToken="#######";

Lineのアクセストークンを##### に入れてください.

以下リンクで自分のLINEアカウントでログインしたら、トークン発行でボタンあると思うので
コピペして#####の部分に貼り付けてください。
https://notify-bot.line.me/ja/

これでLINEとの連携はほぼ完了みたいな感じ。

~~~gas
  var date = new Date();
  date.setDate(date.getDate() + 1);
~~~
new Date()は実行したその年月日時分秒を取得する関数
今回ゴミ捨ては明日の情報が欲しいので、date+1になってる。

~~~gas
   switch(date.getDay()) {
      case 1:
      comment.push('燃えるごみ')
      break;
      case 2:
      comment.push('なんもなし')
      break;
      case 3:
      comment.push('古紙・雑紙・古着')
      break;
      case 4:
      comment.push('一般ごみ')
      break;
      case 5:
      comment.push('びん・缶ごみ・スプレー缶')
      break;
      case 6:
      if(f===1){
        comment.push('燃やせないゴミ')
        f=0
      }
      else{
        comment.push('ペットボトル')
        f=1
      }
      break;
      
  }
~~~
この部分、明日が何曜日かで処理を変えている
0:日曜、1:月曜,...,6:土曜という対応になっている
今回case 6の部分は自分の地域では土曜が
燃えないゴミ→ペットボトル→燃えないゴミ→...
となっているので交互になるように雑に実装した。

あとはGASのトリガー機能で実行したい時間を適当にセット
自分は午後8時〜午後9時の間に届くようにした。

またGASのファイルの作り方やトリガー設定の仕方(需要あるのかしら）
とかは別でアウトプットしようかなと思います。

ラインの通知はこれをいじればなんとなくなんでも実装出来そう。

結論　GASは便利、LINE Notifyは神。

以上でございます。
スパコン ITO フロントエンド で PyTorch

スパコン ITO の フロントエンドのベアメタルを利用すると，GPUを用いたインタラクティブな PyTorch の実行が可能です．バッチ処理であれば，ITO-BでもGPUの利用が可能です．
Miniconda をインストールしていることを前提に，`conda-forge` を highest priority に設定し，仮想環境 torch を作成し，activate しておきます．
**補足：** 当初は [こちらの記事](https://qiita.com/jsasaki/items/9aa4ec0bcbecf48aedbd) にあるように，dockerhubの[pytorchイメージ](https://hub.docker.com/u/pytorch)を Singularity で実行しようとしましたが，動きませんでしたので，ローカルインストールすることにしました．

```bash
conda config --add channels conda-forge
conda update conda
conda create -n torch
conda activate torch
```

# インストール

ITO の cuda ドライバは[最新バージョン](https://pytorch.org/get-started/locally/)に対応していませんので，利用可能な cuda ドライバのバージョンに合わせて，[以前のバージョン](https://pytorch.org/get-started/previous-versions/)から適切なインストールコマンドを見つける必要があります．ここでは `cuda/11.0` を load して利用します．

```bash
module load cuda/11.0
conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=11.0 -c pytorch
```

# テスト
インストールが成功したかテストします．Pythonのインタラクティブ環境では**Shift** + **Enter**（Windowsのキーボード）で入力になります．

```bash
(torch) $ python
Python 3.8.8 | packaged by conda-forge | (default, Feb 20 2021, 16:22:27)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> x=torch.rand(5,3)
>>> print(x)
tensor([[0.7027, 0.1075, 0.9553],
        [0.6718, 0.3508, 0.2277],
        [0.6082, 0.3109, 0.6119],
        [0.6703, 0.1544, 0.2207],
        [0.7046, 0.0201, 0.6421]])
>>> torch.cuda.is_available()
True
```

# バッチ処理

ITO-B では[バッチ処理](https://www.cc.kyushu-u.ac.jp/scp/system/ITO/02-2_batch.html)で **GPU** の利用が可能です．PyTorch を利用する実行用の bash スクリプトを `run.sh` とします．以下の `ito_b.sh` は GPU を1つ使用する場合の例です．矢印部分 `←` 以降はコメントですので，実際は削除する必要があります．リソースグループは [公式サイト] (https://www.cc.kyushu-u.ac.jp/scp/system/ITO/subsystem/06_limit.html)を参照して決めます．

```bash:ito_b.sh
#!/bin/bash
#PJM -L "rscunit=ito-b"          ← ITO-B を指定       
#PJM -L "rscgrp=ito-g-4"       ← リソースグループ指定
#PJM -L "vnode=1"          ← 使用するノード数を指定
#PJM -L "vnode-core=36"          ← ノード当たりのコア数を指定
#PJM -L "elapse=12:00:00"          ← 最大の計算時間の指定（12時間を指定）
#PJM -X          ← ログインノードの環境変数をバッチ処理でも引き継ぐ指定

source ~/.bashrc     # ← MinicondaがPythonの設定を.bashrcに書き込んでおり，これを読み込みます
module load cuda/11.0     # ← GPU を使用するため，CUDA 11.0 を load します
module list     # ← CUDA が load されたことを確認します
conda activate torch     # ← 仮想環境 torch に入ります
conda info -e     # ← 仮想環境 torch に入ったことを確認します

source ./run.sh     # ← 実行用の bash script
conda deactivate     # ← 仮想環境から抜けます
```

バッチ処理はログインノード環境を（環境変数以外は）引き継ぎませんので，CUDA の load や Python 環境の準備が必要になります．この例では `ito_b.sh` と PyTorch のコードを実行するスクリプト `run.sh` が同一ディレクトリに存在しています．

# バッチジョブの投入

作成したバッチ処理スクリプト `ito_b.sh` をバッチ処理システムに投入します．

```bash
pjsub ito_b.sh
```

後は処理が終わるまで待つだけですので，ログアウトして構いません．
ジョブの状況を確認するには以下のようにします．

```bash
pjstat
```

バッチジョブが終わると，標準出力および標準エラー出力が，それぞれ `ito_b.sh.o0000000` および `ito_b.sh.e0000000` のようなファイル名で出力されます．ファイル名はバッチ処理スクリプト名に加え，oまたはeと7桁の数字で構成されています．標準出力ファイルが大きくなりすぎないよう，注意が必要です．
[PHP] 2つ以上の配列の中の共通の値を取得する

#概要
二つの配列を比較して同じ値だけを取り出したい場合の方法をメモします。

#方法
* array_intersect()を使うことで共通の値だけを取り出すことが可能

```.php
<?php
$array1 = [1, 2, 3];
$array2 = [2, 3, 4];

$result = array_intersect($array1, $array2);

print_r($result);
```

出力結果

```
Array
(
    [1] => 2
    [2] => 3
)
```

３つ以上を比較する場合は第三引数以降に配列を追加することで可能

```.php
$result = array_intersect($array1, $array2, $array3, $array4);
```
プログラミングを学び始めたときに知っておきたかった超基本的なこと

僕の友達がプログラミングを学び始めたということで、僕もプログラミングを学び始めた時は大変だったなということを思い出し、僕がプログラミングを学び始めた時に知っておきたかったことをまとめてみました。

#1.エンジニアの職種について知る
エンジニアの職種は色々な種類があり、webエンジニアやフロントエンドエンジニアなど他にもいろいろあるので自分で調べてから、これをやりたいというのを決めて勉強することをお勧めします。
僕がプログラミングを学び始めたときは、とりあえず模写しておけみたいな風習があって、プログラマーはこういうことをする仕事なんだと思い込んでしまい、模写をやっていましたがしばらくして、自分のやりたいことはこれじゃないということに気がつきました...:sob:
皆さんはそうならないようにしてください:sweat_smile:

#2.作りたいものを決める
プログラミングを勉強すれば稼げると聞いてとりあえずプログラミングを始めた人のほとんどが、作りたいものがないと思います。
なんの目標もなく勉強していても終わりが見えず挫折してしまうので、なんでもいいから目標を決めましょう！
web制作を勉強して稼ぎたいんだったら、自分でサイトを作りつつ、javascrtptやsassなどのスキルを身につけるのがいいと思います。
目標に向けて勉強するとモチベーションが全然かわってきます。

#4.調べる力、質問する力をつける
自分で悩み続けてもわからないものはわからないので、調べる癖をつけましょう。目安は15分ぐらい調べて、それでもわからない場合は相談するのがいいと思います。
質問する時は相手にとってわかりやすく、現在つまずいている状況を説明するようにして、できるだけ結論から伝えるようにしましょう。
もしエラーが出ている場合は相手が調べやすいように、スクショではなく、コードで渡すようにしましょう。
しかし相談する相手がいない人が多い思うのでteratailなどのサービスを使うか、プログラミングスクールに通うことを検討してみるのもいいかもしれません。

#5.継続すること
これは全てにおいて言えることですが、継続すればいつかできるようになるということ、そうは言っても挫折せず続けることが難しいのは知っています。未経験の挫折率は約9割と言われています、逆に言えば続けているだけで上位10％に入るということです、こう聞くとやる気が出てきませんか？
毎日少しでもいいからコードを書く！最初は慣れないかもしれませんが、5分だけやろうと思ってコードをかくと意外と集中してしまうものです、最初のパソコンを開く作業さえやれば、30分は経っているはずです:grin:

#最後に
プログラミングの勉強はよく階段に例えられます、エラーやわからないことで壁にぶつかりその問題を解決することで壁を登ることができて、スキルアップしていくのです。なので最初は完璧に覚える必要はないと思ってます。なんとなくこんなことができるのかということさえ覚えていれば、そういえばこんなのあったなと言った感じで調べて実際に使うことで覚えていくものです:grinning:
先ほども言いましたが、未経験の挫折率は約9割です。壁にぶつかった時に頑張って乗り越え続けることができれば上位10％です！試練だと思ってがんばりましょう:blush:
エラー：TypeError: 'module' object is not iterableの対処方法

# はじめに
Djangoを勉強する中で、躓くことが出てきたので、備忘録として残していきます。
動かす都度、いろんなエラーにぶつつかり、その度に原因を探して時間がかかってしまうことが多々ありました。しかも凡ミス多めという。。。
自分自身への戒めという意味でも書き留めていこうと思います。

## 事象
Djangoでプロジェクト内にアプリを作成して、setting.pyなどでアプリを接続する設定などを行い、サーバーを立ち上げた時にこんなエラーが発生しました。

```terminal:ターミナル
TypeError: 'module' object is not iterable

※※おそらく、urlがバグってる的なことが色々書かれていますが、割愛します。※※
```

## 原因

プロジェクト内のurl.pyで、アプリを呼び出そうとしたのですが、呼び出し先が誤っていたためエラーが発生しました。本来なら`start.urlsファイル`を呼び出さないといけないのに、`start`のみしか記載されていなかったため、エラーが発生しました。

![スクリーンショット 2021-04-15 21.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226672/bcf94fa4-c8da-75c1-384f-f03951ec2fea.png)

# 最後に

こちらを参考にさせていただきました。いつも助かっています。

DjangoのmakemigrationsのところでTypeError: 'module' object is not iterableエラー

https://teratail.com/questions/259362
バイナリとテキストファイルの差分比較　Linuxコマンド

メモ書きです。

差分を出すコマンド
diff
cmp

#diff

テキストファイルを一行ずつ最後まで比較する。

参考
https://linuxize.com/post/diff-command-in-linux/#:~:text=diff%20is%20a%20command%2Dline,applied%20using%20the%20patch%20command

#cmp

ファイルを1バイト単位で、比較するコマンド。

違いを見つけると、その位置を表示して終了する。ファイル末尾まで比較したい場合は、以下のオプションを使う。

オプション
-l 違いのあるすべての個所について表示する。
HTTPにおけるTCPによる通信

WebブラウザからのHTTPリクエストと、それに対してのWebサーバーからのHTTPレスポンスを繰り返し行うことでWebサイトを閲覧できるが、これらのやりとりを行うのは**TCP（Transmission Control Protocol）**である。TCPはWebサイト閲覧だけでなく、メールの送受信やファイル転送といったさまざまなデータ転送時に利用されている。
## TCPの役割
TCPでは、まずクライアントとサーバーがお互いに通信できる状態なのかを確認し、「**コネクション**」とよばれる通信経路を確立してからデータのやりとりをする。
コネクションの確率は、次の３回のやりとりにより行われる。

1. クライアントからの接続要求（**SYN**）
   クライアントからサーバに対して接続を要求するための**SYNパケット**を送る。SYNパケットを受け取ったサーバーはそれに対して応答する。
2. クライアントに対して確認応答および、サーバーからの接続要求（**SYN＋ACK**）
   TCPでは信頼性を確保するために、データ送信後必ず送信相手からの確認応答を受け取ってデータの送信が完了したと判断する。この確認応答が**ACKパケット**である。
   クライアントからの接続要求に対してサーバーがACKパケットを送信することで、接続可能であることを伝える。また、同時にクライアントに対して接続を要求するためにSYNパケットを送信する。
3. サーバーに対して確認応答（**ACK**）
   サーバーからの接続要求に対してクライアントはACKパケットを送信する。
   お互いにSYNパケットを送りACKパケットで応答することで、双方向で通信が可能なことを確認し、コネクションを確立する。
![イラスト (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/b56f5264-502a-55fb-7f11-43107ad42a04.jpeg)

コネクション確立は３回のやりとりで行われるため、「**３ウェイハンドシェイク**」と呼ばれる。データの送受信が終了して通信を終了（コネクションの切断）する際は、４回のやりとりが必要になる。
また、信頼性を担保するため、データ転送時に一定時間ACKの応答がなかった場合、データを再送信する「**再送制御**」や、順序が入れ替わっていた場合に番号通りに組み立てる「**順序制御**」を行なっている。
さらに、データを送るたびにACKを送るのでなく、複数のデータを受け取ってからACKパケットを送信する。

# 参考
[イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/gp/product/B06XNMMC9S/ref=ppx_yo_dt_b_d_asin_title_o05?ie=UTF8&psc=1)
【AWS】マネーシド型とアンマネーシド型

#プログラミング勉強日記
2021年4月15日

#AWSの仕組み
　[こちらの記事](https://qiita.com/mzmz__02/items/45d2ebb70ad4f638cb59)でも述べているように、パーツを組み合わせてインフラのアーキテクチャを設計・構築できる。AWSのアンマネーシド型とマネーシド型がある。

#アンマネーシド型
　スケーリング・耐障害性・可用性をユーザ側で設定して管理する必要がある。
　メリットとしては、設定を柔軟に変更することができる。デメリットは、管理が面倒という点である。
　代表的なサービスとしては、AWS側で仮想サーバを作るサービスのEC2がある。EC2は、サーバーを作ったらその設定はユーザ側が行う。

#マネーシド型
　スケーリング・耐障害性・可用性がサービスに組み込まれて、AWS側で管理されている。
　メリットとしては、管理が楽という点である。デメリットは、設定を行える範囲が限られていることである。
　AWSのほとんどのサービスがマネーシド型だが、代表的なサービスとしてRoute53がある。冗長性や可用性とか全てAWS側で管理されていて、サーバーが落ちることのない100％の稼働率をAWS側が保証している。
【Rails6】エラー対処法｜Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

RailsでDeviseのセッティング中にmigrationファイルを作成し`rails db:migrate` (または`rake db:migrate`)を実行したところ以下エラーが発生した。これの対処法について。

```
/app # rails db:migrate
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

  class AddConfirmableToDevise < ActiveRecord::Migration[4.2]
```


##対処法
migrationファイルの**継承したクラス名の末尾でRailsのバージョンを指定する必要がある**。Rials6の場合は`[6.0]`を追記する。


```rb:例：20210415115443_migration_file.rb
class AddConfirmableToDevise < ActiveRecord::Migration[6.0]
  処理
end
```

再度、`rails db:migrate` を実行。

```
# rails db:migrate
== 20210415115443 AddConfirmableToDevise: migrating ===========================
-- add_column(:users, :confirmation_token, :string)
   -> 0.0048s
-- add_column(:users, :confirmed_at, :datetime)
   -> 0.0023s
-- add_column(:users, :confirmation_sent_at, :datetime)
   -> 0.0019s
-- add_index(:users, :confirmation_token, {:unique=>true})
   -> 0.0048s
== 20210415115443 AddConfirmableToDevise: migrated (0.0214s) ==================
```

無事migrationが成功。


<br>
##エラーの詳細
表示されたエラー内容を見ると

>Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

>class AddConfirmableToDevise < ActiveRecord::Migration[4.2]


クラスActiveRecord::Migrationの直接の継承はサポートされていない。バージョンを指定してください。

例　class AddConfirmableToDevise < ActiveRecord::Migration[4.2]

という記述が書いてある。

つまり、マイグレーションファイルでクラスを継承する場合は、バージョンの指定が必須ということ。


<br>
##補足
なお、今回はdeviseにconfirmableモジュールを追加するため後からマイグレーションファイルを追加作成したが、初期の`$ rails g devise モデル名`で自動生成されたマイグレーションファイルにはきちんとバージョンが記載されている。

```rb:マイグレーションファイル
class DeviseCreateモデル名複数形 < ActiveRecord::Migration[6.0]
  処理
end
```
Windows10のバージョンを確認・表記する

Y子です。気づいてしまいました。
バッチファイルの記事を書きがちですが、OSのバージョンが違うと挙動が変わることありますよね。
そこで今回は、 __OS（Windows10）のバージョンの確認方法__ を調べます。

# 概要
Windows10の、バージョンの確認方法と、表記方法のメモです。
_【確認環境：Windows 10 Home (Bld. 19042.867)】_

# 「バージョン」にもいろいろある
ひとことで「バージョン」と言っても、Windowsってそれっぽい数字や記号がいくつもありますよね。
何を使えば、OSの状態を一意に表現できるでしょうか。

まず、わたしのパソコンの今日現在（2021/04/15）の「バージョン」をご紹介します。

|エディション|バージョン|OSビルド|コードネーム（コード名）|
|:-|:-|:-|:-|
|Windows 10 Home|20H2|19042.867|20H2|

<dl>
<details><summary>【もうちょっと詳しく】</summary>
<dt>エディション</dt>
<dd>「Home」とか「Pro」とか「Enterprise」とかあるやつです。これが違うと、値段や機能が変わります。</dd>
<dt>バージョン</dt>
<dd>おおよそ半年に1回配信される、OSの機能アップデートに付けられた名前です。かつては、2015年7月にリリースされた「1507」のように、「年と月」を使って表現していましたが、2020年からは「月」の代わりに「上半期（H1）」「下半期（H2）」を使って、「20H2」のように表現するようになりました。</dd>
<dt>OSビルド</dt>
<dd>前半（19042）は、バージョンが変わると増えていく数字です。後半（867）は、パッチが当たると変わる数字です。</dd>
<dt>コードネーム</dt>
<dd>バージョンに付けられた別名のようなもので、バージョンと一緒に変わります。かつては、バージョン「1809」がコードネーム「Redstone 5 (RS5)」と呼ばれるなど、かっこいい別名だったのですが、2019年から「年」と「半期（H1/H2）」を使って、「19H2」のように表現するようになりました。その結果、2020年から「バージョン」と「コードネーム」が同じになりました。</dd>
</details>
</dl>

ここにも「（狭義の？）バージョン」が出てきましたが、あまり悩まないことにして…。
続けて、どうすればその情報が確認できるのかをご紹介します。

# 確認方法
確認方法も3種類ぐらいあるようですが、それぞれどんな情報が得られるかを見てみます。

## (1) verコマンド
コマンドプロンプトから`ver`と打つと表示されます。
コマンドプロンプトを開いた時点で、最初の行に同じ情報が表示されていますが。

OSビルドと同じ数字（19042.867）に、OSのサブバージョンみたいな「10.0」がくっついています。
これも「Version」…。
![01_ver_加工.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265690/c7f8dae9-2443-35fa-0aa2-9300e51f802e.png)

## (2) winverコマンド
コマンドプロンプトや「ファイル名を指定して実行」から`winver`と打つと表示されます。
バージョン（20H2）、OSビルド（19042.867）、エディション（Windows 10 Home）が表示されます。
![02_winver_加工.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265690/acc94c46-b7fa-1b53-e70e-f18e79daeb26.png)

## (3) 詳細情報
スタートメニューから、「設定」→「システム」→「詳細情報」と辿ると表示されます。
エディション（Windows 10 Home）、バージョン（20H2）、OSビルド（19042.867）に加え、CPUやRAMの情報も表示されるので、`winver`の上位版みたいなものですね。
![03_詳細情報_加工.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265690/a3b63b48-1912-7082-e5a6-8b4ef06ae3f7.png)

# 「コードネーム」の確認方法
(1)～(3)では、「コードネーム（コード名）」が出てきません。
Microsoftのサイト等で、ビルド番号と対比すれば確認できるようです。
（Microsoftより、Wikipediaの方が見やすいです）

https://ja.wikipedia.org/wiki/Microsoft_Windows_10%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%B1%A5%E6%AD%B4

最近は「バージョン」と「コードネーム」が同じになったの、ちょっと嫌ですね。
今後もずっと同じなのかな。

# とりあえず結論（どう表記すればいいか）
OSやコマンドの動作に影響を与えるパッチもありそうですので、環境を一意に特定するには「OSビルド」は書いておいた方がよさそうです。
`winver`で確認し、エディションとOSビルドをつなげて書けばいいかな…。
こんな感じ？
_【確認環境：Windows 10 Home (Bld. 19042.867)】_

他の方がどう書いてるか興味がありますが、Windowsのビルドまで書いている記事はなかなかなく、わかりませんでした。

今後の記事には、なるべくバージョン情報も書き添えていこうかなと思います。
ではー。
40代おっさんIAMを深堀して勉強してみた

## 本記事について

本記事はAWS初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

### ポリシーをJSON形式で記述

＊IAMのことをサラッと知りたい方は↓を
<https://qiita.com/kou551121/items/5adf2241f0e106e18e50>

```JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListBucketRstIP",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::sample-bucket",
            "Condition": {
                "StringEquals": {
                    "aws:SourceIP": "12.34.56.78"
                }
            }
        }
    ]
}
```

こちらがJSON形式のドキュメントになりますがわからないですよね・・・
詳しく細分化してみたいと思います。

#### "Version"

こちらはバージョン情報になります。

#### "Statement"

大事になるのがStatementの中の情報になります。
こちらも細分化して説明します。

#### "Sid"

IDになり名前のようなもの（省略もできる）

#### "Effect"

許可するポリシーだったら"Allow"
拒否する（無効にする場合は）"Deny"

#### "Principal"

プリンシパルはリソースにアクセスする情報を記載します上の*はすべてのアカウント対しての記述になります。
そのほかに

"Principal":{"AWS":"arn:aws:iam::123456789012:root"}
これで特定のアカウントを指定

"Principal":"AWS":"arn:aws:iam::123456789012:user/username"
これで特定のIAMユーザーを指定

"Principal":{"Federated":"www.amazon.com"}
"Principal":{"Federated":"graph.facebook.com"}
これでフェデレーティッドウェブ ID ユーザーを指定

"Principal":{"Service":"ec2.amazonaws.com"}
これでEC2を指定

#### "Action"

ActionはあらかじめAWS決められた形式で何のサービスでどのような操作かを指定
ListBucketはバケットの中身をList(lsやdir)するアクション
そのほかに

"Action":"ec2:StartInstances"
ec2のインスタンスをスタートするアクション

"Action":"iam:ChangePassword"
IAMユーザーのパスワードを変更するアクション

"Action":"s3:GetObject"
S3のオブジェクトを取得するアクション

"Action":["sqs:SendMessage","sqs:ReceiveMessage"]
[,]カンマ区切りで複数のアクションを指定できる

"Action":"iam: \*AccessKey* "
アクションの一部に*(ワイルドカード)を入れることもできる

#### "Resource"

どのリソースに対してのポリシーかを指定します
AWSでリソースを作成すると arn と言う固有の文字列が割り振られます。
上だとリソースにs3のsample-bucket指定していることになります。
そのほかに

"Resource": ["arn:aws:dynamodb:us-west-2:123456789012:table/books_table",
             "arn:aws:dynamodb:us-west-2:123456789012:table/magazines_table"]
上のように[,]カンマ区切りで複数指定できることできます。

"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*"
こちらだと123456789012アカウントのus-east-1リージョン内のec2インスタンスすべてと指定しています。

#### "Condition"

こちらはIPアドレスの接続元を制限したり、ポリシーの有効期限（何時から何時まで有効など）

```JSON
"Condition" : {
    "DateGreaterThan" : {"aws:CurrentTime" : "2015-10-08T12:00:00Z"},
    "DateLessThan" : {"aws:CurrentTime" : "2015-10-08T15:00:00Z" },
    "InAddress" : {"aws:SourceIp" : ["192.0.2.0/24", "203.0.113.0/24"]}
```

上のような場合
縦はAND条件
[,]カンマ区切りはOR条件になります

#### その他に

NotPrincipal
NotAction
NotResource
とNotがあり、意味は指定した物以外ある

#### アイデンティティベースのポリシーについて

IAMユーザーや、IAMロールなどのなどの認証主体に付与するポリシー

↓アイデンティティベースのポリシー記述例

```JSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*"
         }
    ]
}
```

アイデンティティベースのポリシーでは基本、Principalは書きません
なぜならポリシーをアタッチする対象が明確だから

#### リソースベースのポリシーについて

上とは逆に操作される側であり、Amazon S3やAmazon SNSなどのAWSリソース側にアタッチするポリシー

## 最後に

またこの記事は AWS 初学者を導く体系的な動画学習サービス「AWS CloudTech」の課題カリキュラムで作成しました。
<https://aws-cloud-tech.com/>
ソートキーのあるDynamoDBのテーブルにCSVファイルを一括アップロードする方法

# したかったこと

* DynamoDBに一括でCSVファイルの内容をアップロードしたい
* テーブルにはソートキーを設定したい

プライマリキーだけの場合の記事はいっぱいあったが、ソートキーのあるものはみなかった。

# 方法

**CloudFormationに「CSVをDynamoDBに入れる」スタックを作成**

以下の一括アップロードの方法をベースにして、テンプレートファイルの中身だけ少し変える。

* 一括アップロードの方法は[ここ](https://dev.classmethod.jp/articles/csv-import-to-dynamodb-table/)が参考になった。
* ソートキーのあるテーブルの作成方法は[ここ](https://qiita.com/yamamoto_y/items/2c70e0f856680967fb36)が参考になった

## テンプレートファイル

テンプレートファイルにソートキーの情報を足す。
データ型はStringなら "S" にする。

```json:
 "Resources": {
        "DynamoDBTable":{
            "Type": "AWS::DynamoDB::Table",
            "Properties":{
                "TableName": {"Ref" : "DynamoDBTableName"},
                "BillingMode": "PAY_PER_REQUEST",
                "AttributeDefinitions":[
                    {   
                        "AttributeName": "【パーティションキー名】",
                        "AttributeType": "【データ型】" 
                    },  
                    {   
                        "AttributeName": "【ソートキー名】",
                        "AttributeType": "【データ型】" 
                    }   
                ],  
                "KeySchema":[
                    {   
                        "AttributeName": "【パーティションキー名】",
                        "KeyType": "HASH"
                    },  
                    {   
                        "AttributeName": "【ソートキー名】",
                        "KeyType": "RANGE"
                    }   
                ],  
                "Tags":[
                    {   
                        "Key": "Name",
                        "Value": {"Ref" : "DynamoDBTableName"}
                    }   
                ]   
            }   
        },  
```


# 備考

bucket already existエラーが出た
-> 一意でなければならないよう
スタックを削除して、一意なバケット名を入れて、もう一度作り直した。
Monologでログファイルのパーミッションを指定する

Monologでファイルにログを出力する場合、StreamHandlerまたはStreamHandlerを継承したクラスを使用しますが、ファイルのパーミッションを指定する方法を記述します。
ファイルのパーミッションを指定する場合、コンストラクタの第4引数の`$filePermission`に8進数で指定します。

```php
new StreamHandler('/app.log', Logger::INFO, true, 0755);
```

https://github.com/Seldaek/monolog/blob/0dc10f86b8514171d1ae5cc8b95ebbb7f632dc91/src/Monolog/Handler/StreamHandler.php#L44

StreamHandler.phpの105行目でchmod関数で設定しています。(chmodなのでWindowsでは効果はありません。)

```php:StreamHandler.php
if ($this->filePermission !== null) {
    @chmod($this->url, $this->filePermission);
}
```
ディレクトリのlnリンクコマンドがうまくいかない？

# はじめに
リンクを上書きしようとしたらリンクがうまく貼れないのでしらべた。

# 結論
ディレクトリのリンクは循環参照になってしまうので`-n`オプションをつかう

```
ln -nfs linkA linkB
```

https://qiita.com/takeoverjp/items/bb1576e90a8a495db4b3
kintoneの一日のAPIリクエスト数を監視するプログラム - Python

## 定義
kintoneの使用頻度が高そうな二つのアプリの一日のAPIリクエスト数を毎朝8:55分にExcelに保存する

## モジュールのインポート
```python:
import os, time, datetime
from selenium import webdriver
from selenium.webdriver.common.by import By
import openpyxl as excel
```
## ログインしてアプリ管理ページに飛ぶまで
```python:
driver = webdriver.Chrome()
driver.get("https://your-domain.cybozu.com/k/admin/app/index")    
usr = driver.find_element_by_name("username")
usr.send_keys("your-user-name")
pwd = driver.find_element_by_name("password")
pwd.send_keys("your-password")
pwd.submit()
time.sleep(3)
```
## テーブルの中を取得
テーブルの値は、\<tr>（行ごと）のループの中で\<td>の配列のインデックスを指定することで得られる。
`tds[0]`がアプリID、`tds[8]`が一日のAPIリクエスト数。`report_obj` に値を保存する。
![applikannri.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233009/b90099c4-f122-9138-3bdc-2b31e98442f2.png)


```python:
tableElem = driver.find_element_by_class_name("gaia-admin-app-table-body")
trs = tableElem.find_elements_by_tag_name("tr")

report_obj = {"your-application-name1": "", "your-application-name1": ""}
for i in range(0, len(trs)):
    tds = trs[i].find_elements_by_tag_name("td")
    if tds[0].text == "1": # your-application-id1
        report_obj["your-application-name1"] = tds[8].text
    elif tds[0].text == "2": # your-application-id1
        report_obj["your-application-name2"] = tds[8].text
```

## Excelファイルに保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233009/19c0648c-b43e-a4d2-a294-6b6fbba65b70.png)

```python:
book = excel.load_workbook(r"D:\your-folder-path\your-excel-file-name.xlsx") # rにすることでバックスラッシュをリテラルで保つ
sheet = book.active
next_row = sheet.max_row + 1

# 日時
sheet.cell(row = next_row, column = 2, value = datetime.datetime.now())
# 曜日
weekday = datetime.date.today().weekday()
jaWds = ["月", "火", "水", "木", "金", "土", "日"]
sheet.cell(row = next_row, column = 3, value = jaWds[weekday])
# your-application1
sheet.cell(row = next_row, column = 4, value = int(report_obj["your-application-name1"]))
# your-application2
sheet.cell(row = next_row, column = 5, value = int(report_obj["your-application-name2"]))

book.save(r"D:\your-folder-path\your-excel-file-name.xlsx")
print("ok")
```

## タスクスケジューラー
このファイルをタスクスケジューラーに登録して朝8:55分に実行させる。
Webpacker::Manifest::MissingEntryError in 〇〇エラーに詰まった時の話

```
Showing /myapp/app/views/layouts/application.html.erb where line #20 raised:

Webpacker can't find application in /myapp/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
```

application.html.erbの20行目

```
 <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
```

開発環境でだけページを開こうとすると上記のエラーが出る。

# 環境
Dockerを使用しており、本番環境ではruby:2.6.6-alpine3.11のイメージを、開発環境ではruby:2.6.6のイメージを使用していた。（本当は開発環境と本番環境でイメージ変えるのよくないとのこと。）


# 原因

開発環境用のDockerfile

```dockerfile

FROM ruby:2.6.6

RUN apt-get update && apt-get install -y  yarn \
...
```

本番環境用のDockerfile

```dockerfile

FROM ruby:2.6.6-alpine3.11

RUN apk --no-cache add yarn \
...
```
yarnのインストールについて上記のように記載していたが、イメージによってデフォルトでインストールされるバージョンが決まっているっぽい？？（特に指定しなければどのＯＳでも最新のものが入ると思っていた）
それぞれのコンテナでバージョンを確認すると違うyarnがインストールされているようで、開発環境では      
`ERROR: There are no scenarios; must have at least one.`となっていてnodejsもインストールできてなさそうだった。

# 解決策
`(OS名) to (パッケージ名)`等で検索して公式のダウンロード方法を調べる
↓
今回参考にさせていただいた記事
[Debian/Ubuntuにnodejsとyarnをinstall](https://qiita.com/darai0512/items/9e0a2c77d8d3ddf5c0fe)
[パッケージマネージャを利用した Node.js のインストール](https://nodejs.org/ja/download/package-manager/#debian-and-ubuntu-based-linux-distributions-debian-ubuntu-linux)


公式の`Debian と Ubuntu ベースの Linux ディストリビューション、エンタープライズ Linux/Fedora と Snap パッケージ`部分を参考にする。→Node.js 公式のバイナリディストリビューションのリンクが貼ってあるので遷移。

```
Node.js v14.x:

# Using Debian, as root
curl -fsSL https://deb.nodesource.com/setup_12.x | bash -
apt-get install -y nodejs
```
この部分をDockerfileに記載する。

↓最終的にDockerfileはこんな感じに

```dockerfile
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - 
RUN apt-get update && apt-get install -y  nodejs 
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y  yarn
```

# それでもエラーが解消されない
ビルドしなおしたのに

```
Webpacker::Manifest::MissingEntryError
```
上記のエラーが出る。

```
# yarn -v    
1.22.5
# node -v 
v12.22.1 
```
バージョン確認するとnodejsとyarnはちゃんと入ってそう。

# 解決策
どうやらwebpackerがインストールされていないっぽい。`rails webpacker:install`を実行すると解決。

# 余談
このコマンド`rails webpacker:install`が必要になったのは上でだけで開発環境上でだけで、ステージング本番環境共にwebpackerをインストールしなくてもエラーは出いない様子...。なぜかわかる方いらっしゃれば教えてもらえると助かります。。
Promise を返す window.open()

非同期に window.open して Promise を返す関数を作りました。
日本語がめちゃくちゃですが、伝わりますかね……？

```js
async function openNewWindowAsync(urlOrForm) {
    const windowName = + new Date();
    const subWindowRef = window.open('_blank', windowName);
    if (urlOrForm instanceof HTMLFormElement){
        urlOrForm.target = windowName;
        urlOrForm.submit();
    }else{
        window.open(urlOrForm, windowName);
    }
    return new Promise(resolve => {
        function _loadCheck() {
            if (subWindowRef.document.readyState == "complete") {
                return resolve(subWindowRef);
            }
            setTimeout(_loadCheck, 1000);
        }
        setTimeout(_loadCheck, 1000);
    });
};
```

# 別タブにページを開いて、開いた先で何かする

URLを渡すと、別ウィンドウ（タブ）に開いて Promise を返し、ロードが終わった感じになったら開いた先の Window オブジェクトで解決します。
当然ですが、同一オリジン前提です。（開くだけならできますが）

```js
openNewWindowAsync('http://example.com/').then(w=>w.alert('元ページからこんにちは。'))
```

# 別タブでフォームを送信して、開いた先で何かする

たとえば、https://www.google.com/ にキーワードを入れたのちに実行すると、別タブで検索結果を表示して、ロードが終わった感じになったら、そこで何かをすることができないこともないです。

```js
openNewWindowAsync(document.querySelector('form')).then(w=>w.alert('検索は終わりましたか？'))
```

# なお

当たり前ですがポップアップブロックにばっちり引っかかります。
自分用のブックマークレットとかユーザースクリプトとか、そういうの向け？みたいな？
Firefox87とChrome89でしか確認していません。
【Blender2.9】マテリアル設定で関数のノードの追加

Blenderを最近触りだしたのですが、マテリアル設定で自分的に分かりにくい部分があったので書きます。

#わかりづらかった部分
ノードを追加するとき、Shift[A]を押すなどしてから、検索欄にノードの名前を入力する方法でやっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1252667/3773d555-9fb7-4bba-4343-332a9b897c13.png)
↑この乗算のノードを追加しようとしたときに、初心者的にわかりづらい部分がありました。
乗算と検索欄に入力してもそのノードは見当たりませんでした。
「blender　乗算」と検索しても、ぱっと見た感じノードを追加する方法は書かれていませんでした。

#関数のノードを追加する方法
追加>コンバーター>数式とやると、青色のノードが登場しました。
そこから、乗算などの関数を選択することで関数のノードを追加することができました。
【勉強メモ】Next.js を Typescript で扱う初期準備

## create-next-app から Tyescript を設定する

`with-typescript`テンプレートを使用して、`create-next-app`から作成する。

```cmd
npx create-next-app next-ts-sample-app --example with-typescript
```

その後は `yarn dev` コマンドで、`http://localhost:3000`にアクセスでき、Typescript で Next.js を開発できるようになる。

```cmd
npx create-next-app --example with-typescript
cd next-ts-sample-app
yarn dev
```

↓結果
![20200413214932.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407150/4ba321ff-9cde-8668-913c-6489387e43c3.png)
以上。
【Laravel】fakerのtextでエラーになった



## 実行環境
- PHP 7.4
- Laravel 6.20.0

## エラー内容
Faker使ってダミーデータたくさん作ってやるぞ!
と思いまして、

```php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Model\Tag;
use Faker\Generator as Faker;

$factory->define(Tag::class, function (Faker $faker) {
    return [
        'title' => $faker->name,
        'slug' =>  $faker->word,
        'description' => $faker->text,
    ];
});
```

こういったFactoryを用意し、`php artisan db:seed`を実行したところ

```
 ErrorException  : implode(): Passing glue string after array is deprecated. Swap the parameters
```
と、`$faker->text`のところで怒られてしまいました。

## 原因
php7.4になり、`implode`の書き方が変更されたのが原因のようです。

【参考記事】　[php7.4からimplode関数の引数順序の推奨について](https://qiita.com/a-nishimura/items/f9fe9584cfd01f6f11fd)

```php
implode(',', ['a','b','c']);
```

とすると、 `a,b,c`という文字列を作ってくれるのですが、今までは

```php
implode(['a','b','c'],',');
```

のように逆でも問題なかったそうです。それが、Fakerのパッケージ内で使われてたということですね。

## 改善方法
Fakerをアップデートしてみました。

```
$ composer update fzaninotto/faker
```

これでOK!と思いきや...

`Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.`
と、そもそも`fzaninotto/faker`がabandonedだと注意されてしまいました。

仕方ないのでこちらに切り替えます。

https://fakerphp.github.io/

```
$ composer remove vendor/fzaninotto/faker // 既存のfakerパッケージを削除
$ composer require fakerphp/faker // 新パッケージインストール
```

これで無事初期値を実装することができました。
Kubernetes上にデプロイされたNginxの中身をいじりたいとき

# はじめに
この記事は既にNginxをKubernetes上にデプロイしている前提でスタートします．
Kubernetesの構築方法やNginxのデプロイ方法については他記事(※今後記事を追加するかもしれません)をご参照ください．

クラスターのサーバーバージョン：**v1.20.5-34+40f5951bd9888a**

# Nginxの中身を見る
###現在立っているpodを確認

```sh
$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
default                nginx-pod                                    1/1     Running   0          4h22m
```

私の場合はNamaspace：**default(指定なし)**， サービス名:**nginx-pod**と設定しています．


### podへアクセス
下記コマンドを使ってpodへアクセスする

```sh
$ kubectl exec -it nginx-pod(サービス名) /bin/bash
```

もし`stat /bin/bash: no such file or directory: unknown`のようなエラーが発生した場合は

```sh
$ kubectl exec -it nginx-pod(サービス名) /bin/ash
```

/bin/bash　を　/bin/**ash**　へ変更して実行してください．

上記コマンドを実行すると

```sh
/ #
```
のように出力されていればOKです．

試しにlsコマンドを使ってみます．

```bash
/ # ls
bin    dev    etc    home   lib    media  mnt    proc   root   run    sbin   srv    sys    tmp    usr    var
```
フォルダが見れました

### nginxのデフォルトのコンフィグファイルを確認

nginxのデフォルトのコンフィグファイルを確認したい場合は下記．

```bash
/ # cat /etc/nginx/conf.d/hello.conf
server {
    listen 80;

    root /usr/share/nginx/html;
    try_files /index.html =404;

    expires -1;

    sub_filter_once off;
    sub_filter 'server_hostname' '$hostname';
    sub_filter 'server_address' '$server_addr:$server_port';
    sub_filter 'server_url' '$request_uri';
    sub_filter 'server_date' '$time_local';
    sub_filter 'request_id' '$request_id';
}
```
ちゃんと確認できています．

もしrootを`/var/www/html/`等に変更した場合はリロードをする必要がありますが`systemctl`や`service`コマンドが使えないので下記コマンドでリロードできます．

```bash
/ # nginx -s reload
```

### ページにアクセスしてみる
`http://localhost:xxx/`(アドレスやポートは各々によって変更してください)

![スクリーンショット 2021-04-15 18.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/951f1835-ad22-2b5c-54e7-905e64cdc208.png)

デフォルトでこのような画面が見れればOKですね


# 終わりに
本当はデプロイする際に設定を変更するのがいいらしいですが，ひとまずこの方法で色々できるんだとわかりました．
rbenvの簡単な備忘録

## rbenvとは
複数のRubyのバージョンを管理し、プロジェクトごとにRubyのバージョンを指定して使うことを可能としてくれるツールです。

引用：[rbenvでRubyを管理し、Rails開発環境を構築する](https://mae.chab.in/archives/2612)

https://mae.chab.in/archives/2612


**つまりrbenvをインストールしていれば自分のPCのRubyのバージョンを簡単に切り替えることが出来るようになります。**

## 1つだけ注意
>`互換性に関する注意：rbenvはRVMと互換性がありません。rbenvをインストールする前に、必ずRVMを完全にアンインストールし、シェル初期化ファイルからRVMへの参照を削除してください`

とのことです。（GitHub公式より引用）

**GitHub公式**

https://github.com/rbenv/rbenv

## 各コマンド一覧

**macOSを使用している場合はHomebrewを使用したインストールがオススメです。**

・rbenvのインストール
`brew install rbenv`

・バージョンの確認
`rbenv -v`

・インストール可能な最新の安定バージョンだけを表示
`rbenv install -l`

・インストール可能なすべてのローカルバージョンを表示
`rbenv install -L`

・Rubyバージョンを指定してインストール
`rbenv install x.x.x`（バージョンの番号を指定）

・現在設定中のバージョンの確認
`rbenv version`

・rbenvで管理しているインストール済みのRubyのバージョンを表示
`rbenv versions`

・デフォルトのRubyのバージョンを指定
`rbenv global x.x.x`（バージョンの番号を指定）

・そのディレクトリ以下で適用されるRubyのローカルバージョンを指定（グローバルより優先）
`rbenv local x.x.x`（バージョンの番号を指定）

・ローカルバージョンの解除
`rbenv local --unset`

・新しいバージョンのRubyをインストールした後、またはコマンドを提供するgemをインストールした後に実行するコマンド
`rbenv rehash`

rbenv rehashについての詳細は以下の参考ページにて
【参考リンク】
・[rbenv rehashをちゃんと理解する](https://www.mogulla3.tech/entry/2020/12/29/205441)
・[rbenv rehashは何をやっているのか？](http://dqn.sakusakutto.jp/2014/02/rbenv_rehash_what_it_does.html)
・[rbenvの使い方と仕組みについて](https://qiita.com/Kodak_tmo/items/73147ed4f0eec54d6e94)





## 参考サイト
・[rbenvでRubyを管理し、Rails開発環境を構築する](https://mae.chab.in/archives/2612)
・[rbenvの使い方と仕組みについて](https://qiita.com/Kodak_tmo/items/73147ed4f0eec54d6e94)