OmniAICreator/Qiita-1.07M huggingface dataset:
ルービックキューブつくってみた（ただしユーザ操作はできない）

前身：https://qiita.com/kob58im/items/c86f09f57a153bf34d05

ドラッグすると視点を動かせます。（タッチデバイスは非対応）

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

応用元：https://qiita.com/kob58im/items/a35a0ae753a3093d21ba

# ちょっとだけ説明（備忘録）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/d3d6d290-cf4b-1f84-c879-fe0fcbe1cd21.png)
回転させたいboxを9個選んで回転させる。

```js:回転処理（抜粋）

  mat.makeRotationFromEuler(new THREE.Euler( Math.PI*degX/180, 0, 0, 'XYZ' ));
  for(let y=0;y<3;y++){
    for(let z=0;z<3;z++){
      boxes[ほげほげ].geometry.applyMatrix(mat);
    }
  }
```

ただし、回転させると対象のboxの位置が変わってしまうので、配列(本プログラム上の変数`boxIndexConversion`)を使って、初期位置のboxが今3x3x3の立方体のどこにいるのかを把握する。（下記で変換している。）

```js:位置情報の追従管理（Y軸抜粋）

  if (rotDirId==="Y"){
    swapBoxIndex(9*rotPIndex, 0, 6, 8, 2);
    swapBoxIndex(9*rotPIndex, 1, 3, 7, 5);
  }
  else if(rotDirId==="y"){
    swapBoxIndex(9*rotPIndex, 2, 8, 6, 0);
    swapBoxIndex(9*rotPIndex, 5, 7, 3, 1);
  }

～中略～

function swapBoxIndex(b, i0,i1,i2,i3) {
  let t = boxIndexConversion[b+i0];
  boxIndexConversion[b+i0] = boxIndexConversion[b+i1];
  boxIndexConversion[b+i1] = boxIndexConversion[b+i2];
  boxIndexConversion[b+i2] = boxIndexConversion[b+i3];
  boxIndexConversion[b+i3] = t;
}
```


そんな感じ。
M5Stackで始めるIoT学習メモ

初心者がM5Stackを使おうと思って調べた事を列挙しています。
同じ初心者の方が調べる助けになれば幸いです。
今後色々と追加予定

# M5Stack
ESP32互換の画面とバッテリーついたやつ。
Wifiにもつなげるからそういう用途だと利用しやすい。
中身はESP32

## 最初に一読しとくと良いもの
M5Stack公式のライブラリの[getting_started_ja.md](
https://github.com/m5stack/M5Stack/blob/master/docs/getting_started_ja.md)

ESPについてよく知りたい人むけ
- [ESPr One 32(ESP-WROOM-32 Arduino互換ボード)のピン配置について](http://trac.switch-science.com/wiki/espr_one32)
- [ESP-WROOM-32に関するTIPS](https://trac.switch-science.com/wiki/esp32_tips#SPI%E9%80%9A%E4%BF%A1)
- [ESP32 用クイックリファレンス](https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#adc-analog-to-digital-conversion)

## (知らないなら)絶対見とくべきサイト
[Arduino API -M5Stack Docs](https://docs.m5stack.com/#/ja/api)

## 私がわかんなかった単語
通信関係

- RXD/TXD
    - UART通信でのデータの送受信に用いる。
- HSPI
    - SPI。他のIC機器とかと通信させるらしい。
- SDA,SCL
    - I2Cに使用

## I/Oについて
[I/O (GPIO/ADC/DAC/PWM)](https://docs.m5stack.com/#/ja/api/gpio)をまず読んでおくと良い。
IoTで使用する以上、センサーの活用や信号の出力といった事を行う。これに関するページ。

**よく使うやつ**

- pinMode(pin,mode)
    - 大前提。Setup関数内で使う。これ使わずに色々するのは無理だと思う。
    - 使用するピン番号、何に使うのかという事を設定する。
- analogRead(pin)
    - 入力値を取得する。対応電力は0V-5Vっで、戻り値は0-1025。
    - G35ピン、G36ピンで使える
- dacWrite(pin,val)
    - ArduinoにおけるanalogWriteに近いが、あれはPWM信号（0-5Vをデューティ比で切り替える形で疑似アナログ信号を出力する）がこれは普通にアナログ信号を出力する。
    - valは0-255
    - G25ピン,G25ピンが使える。
    - スピーカー使わない時はこれで２５ピンに明示的に0Vを印加するという事がよくある。
    - 255の時は５Vではなく3.3V程度しか出力されないっぽい

## 最初
参考: https://docs.m5stack.com/#/en/arduino/arduino_development

Arduinoを用いる
Arduino>Preferencesの追加のボードマネージャーのURLに
「https://dl.espressif.com/dl/package_esp32_index.json 」を追加し、ボードマネージャーにesp32を追加しする。

スケッチ>スケッチをインクルード>ライブラリマネージャー
で
M5Stackを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/53c3d476-b89e-202b-64bc-5eec73f6496c.png)
あとは
ツール>ボードマネージャー>ESP32 Arduino>M5Stack-Core-ESP32
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/9df1e8c9-1066-ffde-93e5-e28acaf58e58.png)
あとはスケッチ例などを使うと効率的に開発、学習ができる。
LaravelのStorageでプロジェクト外のローカルディスク上にファイルを出力する

#行うこと
Windows10のxampp上で立ち上げたLaravel8.4.0のプロジェクトで、textファイルをLaravelプロジェクトフォルダ外であるD:/testに出力する。

#方法
config/filesystems.phpを編集して、Storageのdiskに新たに保存先を加える。

```php:config/filesystems.php
'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

        /* -----付け加え箇所----- */
        'local_test' => [
            'driver' => 'local',
            'root' => 'D:/test',
        ],
        /* ---------- */

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
        ],

    ],
```


ファイルを出力したいタイミングで記述する

```php:app/Http/Controllers/PostController.php
Storage::disk('local_test')->put($file_name, $file_content);
```

#参考
[stack overflow: Adding Custom path for storage in filesystems.php Laravel](https://stackoverflow.com/questions/54039755/adding-custom-path-for-storage-in-filesystems-php-laravel "Adding Custom path for storage in filesystems.php Laravel
")
[LaravelでStorageを使ったファイルおよびディレクトリの操作をまとめてみた](https://qiita.com/t1k2a/items/50081988363cf2fa1bca "LaravelでStorageを使ったファイルおよびディレクトリの操作をまとめてみた")
[Laravel File Storage(英語)](https://laravel.com/docs/7.x/filesystem "Laravel File Storage")
[Laravel File Storage(日本語)](https://readouble.com/laravel/5.8/ja/filesystem.html "Laravel File Storage")
Human augumentation 人間拡張に関するアブストまとめ


##Automatic Smile and Frown Recognition with Kinetic Earables
耳に装着するデバイスから、笑顔かしかめつらかの表情が割と高い精度で認識できるようになった。
https://dl.acm.org/doi/10.1145/3311823.3311869


##Prospero：パーソナルウェアラブルメモリコーチ
あれやりたい！っていう短期記憶みたいなものを維持するバーチャルトレーニングアシスタントアプリ。
しかもこいつは頭が冴えてるタイミングでトレーニングを実行してくれるのだ。
これにより今後は記憶力の低下とかなくなるかもね！
https://dl.acm.org/doi/10.1145/3311823.3311870

##Hearing Is Believing: Synthesizing Spatial Audio from Everyday Objects to Users
日常の物体から出る音を、全て人工のものに変えるぞ！というもの。
https://dl.acm.org/doi/10.1145/3311823.3311872



##MusiArm: Extending Prosthesis to Musical Expression
ハンディカップを持つ人のためだけでなく、そうでない人の為の義手を開発。
楽器として使える。
楽器未経験の人でも楽しめるようなものを作成した。
https://dl.acm.org/doi/10.1145/3311823.3311873
スクレイピングしてみた

はじめまして
山田長政です。
言葉を調べるプログラムをスクレイピングのやつを使って作れないかやってみました
google colaboratoryでやりました
https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja
#目的
pythonを使って言葉の意味を検索するプログラムを作る
#こんなかんじの仕組み
input➡スクレイピングするやつで情報をオンライン辞書でとる➡表示する
#使うオンライン辞書
![1C5E273B-9F1A-4C57-9270-162562B6628E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/795753/2ceb6a44-4aae-56fd-4375-fbd88bb730ae.png)

#プログラム

```ruby:
from bs4 import BeautifulSoup
import urllib
import urllib.parse
#うえのはにほんごをエンコードするやつ
g=input()
m= urllib.parse.quote(g)
url =f'https://dictionary.goo.ne.jp/srch/all/{m}/m0u/'
headers = {
          "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0",
          }
request = urllib.request.Request(url, headers=headers)
html = urllib.request.urlopen(request)
soup = BeautifulSoup(html, 'html.parser')
a = soup.select('div[class="example_sentence"] ul[class="content_list idiom lsize"] p[class="text"]')
for x in a:
  print(x.text)
```
```ruby:
from bs4 import BeautifulSoup
import urllib
```
これはスクレイピングするのに必要なやつです

```ruby:
import urllib.parse
```
これはエンコードするのに必要なやつです

```ruby:
g=input()
m= urllib.parse.quote(g)
```
これでinputしたのをエンコードしてます。
私はここを忘れててうまくいきませんでした

```ruby:
url =f'https://dictionary.goo.ne.jp/srch/all/{m}/m0u/'
headers = {
          "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0",
          }
request = urllib.request.Request(url, headers=headers)
html = urllib.request.urlopen(request)
soup = BeautifulSoup(html, 'html.parser')
a = soup.select('div[class="example_sentence"] ul[class="content_list idiom lsize"] p[class="text"]')
for x in a:
  print(x.text)
```
urlのとこにオンライン辞書のurlが入ってます
｛ｍ｝に調べたい言葉が入っています

```ruby:
a = soup.select('div[class="example_sentence"] ul[class="content_list idiom lsize"] p[class="text"]')
```
これで知りたいとこを特定してます。

```ruby:
for x in a:
  print(x.text)
```
これでaの中に入っているのをすべて取り出しています
（終わり）
はじめてかいたのでわかりにくいかもしれませんが読んでくれてありがとうございます。
Sassの大まかな仕組み

#はじめに
初学者がネット記事を参照にしながら、Sassについて学習した記録です。
誤りがあれば暖かく指摘頂けると幸いです。

##Sassとは
一言で、CSSを簡単に記述出来る言語です。
中には2種類あり、
SASS記法とSCSS記法がありますが私が学習したのがSCSS記法です。
理由は2点有り、
①SASS記法とCSSでは、記述ルールが全然異なる。
②SCSS記法とCSSは記述ルールがほぼ同じでわかりやすい。

②は、自分が学習しやすいというメリットの他に
エンジニアとして他の人にコードを見てもらう際にも理解してもらい易いと感じました。

##学習内容
###1.環境構築
コードエディタの拡張機能で専用ファイルをインストール

###2.ファイル構成
|ディレクトリ|HTMLファイル|SCSSファイル|
|:---:|:---:|:--:|
|example|example.html|①example.scss|

コードエディタ下部にある
Watch Sassをクリック
![スクリーンショット 2020-10-25 17.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747711/99f1f951-d3c0-2dde-367b-84289c489f38.png)

クリックしたあと2つのファイルが追加されます。
②example.css
③example.css.map

ここで、計3つのcssファイルが制作されていますが、
編集するのは、①のみで、①の編集結果が②へ反映されるようになっておりますので、
.htmlファイルへのリンクも通常通り②をリンクさせていきます。

###3.機能
|記号|内容|
|:----:|:---:|
|&|擬似クラスを使用する時に、クラスの前に&を付けて使用|
|変数|複数回使用するカラーを代入して使用|
|@mixin 定義名|同じCSSを複数回使用する時に、定義名によって定義する|
|@include 定義名|mixinにて定義したCSSを使用する|
|import|他のscssファイルを反映させる(※)|

(※)@import "アドレス";　で既存のcssファイルにリンクされているscssファイルの先頭につける事でリンク

以上
今後も出来る限り学んだことをアウトプットする場として使用したいと思っています。
宜しくお願い致します。
GitlabにおけるRemote Branch名の変更

## コマンドの場合
1. ローカルの branch名変更します。
    * git branch -m [hoge] [hoge2]
1. リモートの対象branchを削除します。二通りあります。
    * git push origin :[hoge]
    * git push --delete origin [hoge]
1. ローカルbranchをプッシュします。
    * git push origin [hoge]

## TortoiseGit、Gitlabの場合
Gitlabのみではできないので、あらかじめローカルのbranch名を変更する必要があります。

1. ローカルの branch名変更します。
    * ![2020-10-25_17h43_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34174/3a03d1ca-beff-a358-cd30-854426c81689.png)
    * ![2020-10-25_17h43_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34174/8f1e8a22-77d6-3e59-327f-87f2db53765f.png)

1. リモートの対象branchをbranch一覧から削除します。
    * ![2020-10-25_17h50_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34174/c358eccd-5a2a-ca76-4398-54a504670a81.png)


1. ローカルbranchをプッシュします。
    * ![2020-10-25_18h27_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34174/8afd8816-55bf-9e93-9023-f473b8a38de1.png)


## master Branch名の変更
リプレース、なおかつGitlabでのPrjectは既存のものを使用したため、masterの名前を変更しました…。他に良い方法が有ったかと思いますが、この方法しか思いつきませんでした。
え、第三正規形でも更新時異常って発生するんか

DBの論理設計で出てくる第〇正規形みたいなやつ。
資格の本とかで出てくるけど、適当に読んで思い込みで第三正規形なら更新時異常は発生せんと思ってました。

でも厳密には違うっぽいですね。

2020/11/16 
商品番号に対して商品名が一意なだけでなく、商品名に対して商品番号が一意でないと言っていることがおかしくなるので修正しました。

# 何の話

|注文番号  |商品番号  |商品名  | 数量 |
|---|---|---|---|
|1  |A1  |良い商品  |2 |
|1  |B1  |それなりの商品  |1|
|2  |B1  |それなりの商品  |2|
|1  |C1  |悪い商品  |3|

みたいなテーブルで、~~「商品番号に対して商品名は一意」~~ 「商品番号:商品名 = 1:1」という場合、候補キーは（注文番号、商品番号）or（注文番号、商品名）になります。


で、第三正規形の定義は以下のようになっています。

```
1. 第二正規形であること
2. 全ての非キー属性（どの候補キーにも入っていないもの）は他の非キー属性に推移的関数従属しないこと
```

このテーブルの場合、もともと第二正規形です。また、数量は独立なので `2` も満たしています。
商品番号→商品名は推移的関数従属では？ とか一瞬思いますが、候補キーなのでスルーされます。

（2020/11/16 追記）
コメントで指摘いただいているように、同じ商品名で商品番号が複数存在する場合は（注文番号、商品名）が候補キーにならず、第2正規形になりません。
(2020/11/16 追記終）

けど、`商品番号=B1` の商品の名前を `まぁまぁな商品` に変えたいと思った時、テーブルのすべての `それなりの商品` を更新しなければ矛盾を起こします。

え、第三正規形って完璧じゃなかったのか、、、というわけで。


# わかったこと

上のような表を見ると発作的に改造したくなる形、

|注文番号  |商品番号  | 数量 |
|---|---|---|
|1  |A1  | 2 |
|1  |B1   |1|
|2  |B1   |2|


|商品番号  |商品名  |
|---|---|
|A1  |良い商品  |
|B1  |それなりの商品 |

これは候補キーに入っている属性のことも考える `ボイスコット正規形` というらしいですね。

名前は知ってたけど、ちゃんと調べてなかった。。。orz


# まとめ

思い込みはやめましょう。ちゃんと調べましょう。
docker-compose --help 日本語訳

``docker-compose --help`` 実行時に表示されるヘルプドキュメントの日本語訳。

Docker を使用してマルチコンテナーアプリケーションを定義し、実行します。

# 使用法:

```bash
docker-compose [-f <arg>...] [options] [--] [COMMAND] [ARGS...]
docker-compose -h|--help
```

# オプション:

* -f, --file FILE
  代替の compose ファイルを指定します(デフォルト: ``docker-compose.yml`` )
* -p, --project-name NAME
  代替プロジェクト名を指定します(デフォルト: ディレクトリ名)
* -c, --context NAME
  コンテキスト名を指定します。
* --verbose
  より多くの出力を表示します。
* --log-level LEVEL
  ログレベルを指定します。
  * DEBUG
  * INFO
  * WARNING
  * ERROR
  * CRITICAL
* --no-ansi
  ANSI 制御文字を非表示にします。
* -v, --version
  バージョンを表示して終了します
* -H, --host HOST
  接続するデーモンソケットを指定します。
* --tls
  TLS を使用します; ``--tlsverify`` によって暗示されます。
* --tlscacert CA_PATH
  この CA によってのみ署名された信頼証明書
* --tlscert CLIENT_CERT_PATH
  TLS 証明書ファイルへのパス
* --tlskey TLS_KEY_PATH
  TLS キーファイルへのパス
* --tlsverify
  TLS を使用して接続を確認します
* --skip-hostname-check
  デーモンのホスト名をクライアント証明書で指定された名前と照合しないようにします
* --project-directory PATH
  代替作業ディレクトリを指定します(デフォルト: compose ファイルのパス)
* --compatibility
  設定されている場合 Compose は v3 ファイルのキーを Swarm 以外の同等のものに変換しようとします(非推奨)
* --env-file PATH
  代替環境ファイルを指定します

# Commands:

* build
  サービスのビルドまたは再ビルドを実行します
* config
  compose ファイルを検証して表示します
* create
  サービスを作成します
* down
  コンテナ、ネットワーク、イメージ、ボリュームを停止して削除します
* events
  コンテナからリアルタイムのイベントを受信します
* exec
  実行中のコンテナでコマンドを実行します。
* help
  コマンドのヘルプを表示します。
* images
  イメージを列挙します。
* kill
  コンテナを停止します。
* logs
  コンテナからの出力を表示します。
* pause
  サービスを一時停止します。
* port
  ポートバインディングの為の公開ポートを表示します。
* ps
  コンテナを列挙します。
* pull
  サービスイメージをプルします。
* push
  サービスイメージをプッシュします。
* restart
  サービスを再起動します。
* rm
  停止されたコンテナを削除します。
* run
  一度限りのコマンドを実行します。
* scale
  サービスに使用するコンテナ数を指定します。
* start
  サービスを開始します。
* stop
  サービスを停止します。
* top
  実行中のプロセスを表示します。
* unpause
  サービスの一時停止を解除します。
* up
  コンテナを作成して開始します。
* version
  バージョン情報を表示して終了します。
1分で学習手順OK！ AWS認定クラウドプラクティショナー 合格へ

#【1分で学習手順OK！ AWS認定クラウドプラクティショナー 合格へ】

![スクリーンショット 2020-10-25 18.18.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472549/2d904879-717c-4b28-160f-4f578b49b324.png)

10/24に受験して、1回で合格しました！
（隠した方が良さそうなところは隠しました。スコアは700点台でした。）
私が実践した学習手順は合格の再現性が高いと思ったので簡単な記事にまとめてみました。

##はじめに

これだけでAWS認定試験クラウドプラクティショナーに合格することが可能だと思います。

##私の保有IT資格（一応記載）

ITパスポート のみ。

（今年度秋期の基本情報技術者試験を受験予定でしたが中止になりました。。）

##AWS認定試験クラウドプラクティショナーの概要など。

700/1000 点 なので、約7割解けたら合格です。
制限時間100分。65問です。

![2020-10-25 16.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472549/9149c0af-50e6-8797-cd8f-c1a87e042323.png)

分野 1: クラウドの概念
1.1 AWS クラウドの概念とその価値提案について説明する
1.2 AWS クラウドエコノミクスの特徴を説明する
1.3 多種多様なクラウドアーキテクチャの設計原理を定義する

分野 2: セキュリティおよびコンプライアンス
2.1 AWS の責任共有モデルについて理解する
2.2 AWS クラウドのセキュリティとコンプライアンスに関するコンセプトを理解する
2.3 AWS のアクセス管理機能を特定する
2.4 セキュリティサポートのリソースを特定する

分野 3: テクノロジー
3.1 AWS クラウドにおけるデプロイと運用の方法を理解する
3.2 AWS のグローバルインフラストラクチャについて理解する
3.3 AWS の主要なサービスを識別する
3.4 テクノロジーサポートのリソースを特定する

分野 4: 請求と料金
4.1 AWS のさまざまな料金モデルを比較対照する
4.2 AWS 請求と料金に関連した多様なアカウント構造を認識する
4.3 請求サポートに利用できるリソースを特定する

試験の質問には以下の 2 種類があります。
• 択一選択問題: 選択肢には 1 つの正解と 3 つの不正解 (誤答) があります。
• 複数選択問題: 5 つの選択肢のうち、2 つが正解です。

（AWS認定公式サイトから引用）


<strong>詳しい内容は、こちらからご確認頂くと良いと思います。</strong>
→[AWS 認定 クラウドプラクティショナー]
(https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)

##学習教材

使用した学習教材は2つのみです。
AWS公式のデジタルコースなどの利用はしていません。

・[一夜漬け AWS認定クラウドプラクティショナー 直前対策テキスト]
(https://chrome.google.com/webstore/detail/wappalyzer/gppongmhjkpfnbhagpmjfkannfbllamg?hl=ja/)

・[この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）]
(https://www.udemy.com/course/aws-4260/)

※Udemyの教材は、セール時の購入が良いと思います。

##学習順序

1、テキストを1周流し読み

2、テキストに演習問題が65問あるのでとりあえず解いてみる。

3、Udemyの模擬試験を解く。
（基礎①、基礎②、応用①、応用②だけで大丈夫です。）

4、Udemyの模擬試験の間違えた箇所をテキストで復習する。

1、2を終えたら、3、4をひたすら繰り返すのみです。
わからない用語が出てきたら、その都度調べるようにしました。

とりあえず量をこなせば、大丈夫だと思います。

##+α を求めるなら

Qiita @sew_sou19さんの記事を参考にすれば、合格に必要なレベルがわかると思います。
・[AWS クラウドプラクティショナー 勉強〜合格までのメモ]
(https://qiita.com/sew_sou19/items/578ce49cf3c0e637403c)

学習当初、不安で色んな方のブログやQiitaを見ていました。
ただ、ほとんど意味のないことだったと後からわかりました。
他の教材や他人の体験談が気になってしまっても見る意味はさほどないと思います。

やるべきことは、ひたすら問題を解くだけです。
通勤電車や昼休憩にUdemyの模擬試験を解くだけで合格は目指せます。

##おわりに （ここを読むと1分超えると思います）

[この記事](https://qiita.com/uejima_haruki/items/0523c064cd551885fff4)の最後で「【今年、残り３ヶ月の目標】 AWS認定クラウドプラクティショナー、LPIC１の資格を取得する！！」と目標を立てていました。
まず、1つ目標達成出来てよかったです。
今回は基礎レベルの試験に合格しただけで慢心せずに今後もAWSに触れていき、実践的な知識を身につけていこうと思います。

###・おまけ　Udemyの模擬試験の点数推移を参考に。

このような感じでした。
1度目は、全問回答しないで問題文と解答を照らし合わせました。

基礎① 0%正解→66%正解→73%正解→76%正解→96%正解→100%正解
基礎② 0%正解→52%正解→69%正解→83%正解→92%正解→98%正解
応用① 0%正解→56%正解→70%正解→90%正解→96%正解→96%正解
応用② 0%正解→64%正解→72%正解→89%正解→95%正解→92%正解
応用② 0%正解→33%正解（1回のみ。不要という記事をQiitaで何度か見たため。）
【Windows Terminal】右下にキャラクターを表示させる【海外でよくある】

※[私のブログ](https://monkey999por.hatenablog.com/entry/2020/10/23/175941?_ga=2.166224125.210081228.1603542464-1041237349.1603542464)にも同じ記事があります。
### どんなやつ?
こんなやつです。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/monkey999por/20201023/20201023170852.png)
###1.画像の用意
まずは透過画像の用意です。`Transparent anime`とかでググるといいでしょう。
わたしは[ここ](https://www.hiclipart.com/search?clipart=anime)を使わせていただきましたm(__)m

こんな感じでいくつかダウンロード！
上記のサイトからダウンロードする場合、リサイズして200pxくらいがちょうどいいです。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/monkey999por/20201023/20201023171627.png)
###2.setting.jsonの書き換え
以下のように書き換えます。透過率は0~1の間でいじってみてください。

```json:setting.json 
// ファイルのパス。使用可能な拡張子は`.jpg`、`.png`、`.gif `。
"backgroundImage": "%USERPROFILE%\\Documents\\my_contents\\Transparent_image_with_wt\\item\\1.png",

// 背景画像のストレッチ モード。元の画像をそのままのサイズで使用
"backgroundImageStretchMode": "none",

// 背景画像の配置。右下
"backgroundImageAlignment": "bottomRight",

// 背景画像の不透明度。0~1の間で設定。0に近いほど透明。
"backgroundImageOpacity": 0.8

```
そして起動。完成です。

###3.表示する画像をランダムにしてみる
ここまでの内容だと画像が固定されてしまっているので、ちょっとつまらないです。ランダムにしてあげましょう。
調べてみた感じ`windows terminal`にそのような設定は無さそうだったので、ちょっと工夫します。
#####仕組み
1.読み込み先の画像パスを固定

```json
"backgroundImage": "%USERPROFILE%\\Documents\\my_contents\\Transparent_image_with_wt\\main.png",
```
2.以下のようなバッチを用意。

```winbatch:mwt.bat
@chcp 65001 > nul
@pushd %~dp0

@rem windows terminalが読み込む画像パスにランダムで画像を配置する

@set /a n=0
@for%%A in (..\Transparent_image_with_wt\item\*) do @if exist %%A ( @set /a n=n+1 )

@rem 最初のランダムは使えない
@echo %RANDOM% > nul

@set /a R=(%RANDOM%*%n%/32768)+1

@copy /Y ..\Transparent_image_with_wt\item\%R%.png ..\Transparent_image_with_wt\main.png > nul

@wt
```
3.上記のバッチにパスを通す
4.`win+r`でランチャー起動⇒作成したバッチファイル名(`mwt`)を入力しエンター。

何回か試してみます。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/monkey999por/20201023/20201023175024.png)
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/monkey999por/20201023/20201023175059.png)
![](https://cdn-ak.f.st-hatena.com/images/fotolife/m/monkey999por/20201023/20201023175344.png)

まだ画像が少ないんでかぶる率も高いですが、動作はOKですね！
読んでいただきありがとうございました。
### 参考
https://www.hiclipart.com/search?clipart=anime
https://docs.microsoft.com/ja-jp/windows/terminal/customize-settings/profile-settings
IPアドレスの基礎学習

# はじめに
AWSはAmazon Web Servisesの略で、Amazonが提供しているクラウドサーバーのサービスです。
AWSへの理解度を高めるために、学んだことをアウトプットします。
今回はIPアドレスのことを説明します。


# IPアドレス
インターネットで使われるTCP/IPというプロトコルでは、通信先を特定するのに、IPアドレスを用います。
IPアドレスは、ネットワーク上での住所のようなもので、ネットワーク上が重複しないようになっています。
IPv4とIPv6が存在しますが、今回はIPv4を説明すると、4つに区切られた最大１２桁の数字になります。

例)192.168.1.2

ピリオドで区切られた数字は0~255までの数字が入ります。（0.0.0.0 ~ 255.255.255.255）
IPアドレスは32ビットで構成されます。
ピリオドで区切られた数字はそれぞれ８ビットずつとなります。(２５５は８桁の2進数の最大値)
簡単なイメージでいうと、1ビットの中には0か１の数字が入り、それが8個連なって8ビットが構成されているということです。


# パブリックIPアドレスとプライベートIPアドレス

### パブリックIPアドレス
インターネットで使われるIPアドレスのこと。
IPアドレスが重複すると正しく通信できないため、ICANNという機関がパブリックIPアドレスを管理しています。

### プライベートIPアドレス
インターネットで使われないIPアドレスのこと。

10.0.0.0 ~ 10.255.255.255
172.16.0.0 ~ 172.31.255.255
192.168.0.0 ~ 192.168.255.255

上記の範囲のIPアドレスはプライベートIPであり、どこかに申請する必要がなく、自由に使えます。


# IPアドレス範囲と表記方法

VPCで指定したIPアドレスはネットワーク部とホスト部に分けられます。
ネットワーク部は同じネットワークに属する限り、同じ値となる部分です。
ホスト部は割り当てたいサーバーやクライアント、ネットワーク機器に対しての値となる部分です。

例)192.168.1.0 ~ 192.168.1.255
192.168.1までは変わらないため、ネットワーク部です。
0や255は変わるため、ホスト部です。（数字を割り当てるために、変化させる）

IPアドレスの範囲を表す際に、192.168.1.0 ~ 192.168.1.255のような表現は長いため、通常しません。
CIDR表記、もしくは、サブネットマスク表記を使うことが一般的です。

### CIDR表記
例)192.168.1.0 ~ 192.168.1.255
CIDR表記 192.168.1.0/24

24という数字はネットワーク部のビット長を表します。
192.168.1までがネットワーク部となるため、24ビットとなります。(1つの数字ごとに8ビット)
ちなみに、この24ビットはプレフィックス(prefix)と呼ばれます。

### サブネットマスク表記
例)192.168.1.0 ~ 192.168.1.255
サブネットマスク表記 192.168.1.0/255.255.255.0

プレフィックスのビット数だけ2進数の1を並べ、残りは0を記述した表記になります。
8ビットに全て１を入れた時が255なので、プレフィックスが24ビットの時は255.255.255.0となります。



# 参考
「Amazon Web Services 基礎からのネットワーク＆サーバー構築」
著者：大澤文孝、玉川憲、片山暁雄、今井雄太

# 最後に
本投稿が初学者の復習の一助となればと幸いです。
地図タイルにおけるピクセルの大きさをメートルに変換する

## 1. 概要
地図タイルにおける**1ピクセルの大きさ（メートル）**を計算したい。

地球は平面ではないため、ピクセルの大きさは**位置に依存**することになる。したがって、タイル座標が与えられた時、当該タイルにおける1ピクセルの大きさを計算できるようにしたい。


## 2. 計算式
[Understanding Scale and Resolution - Bing Maps Articles](https://docs.microsoft.com/en-us/bingmaps/articles/understanding-scale-and-resolution) によると、以下のように緯度とズームレベルに依存した式で計算することができるらしい。

```
Map resolution = 156543.04 meters/pixel * cos(latitude) / (2 ^ zoomlevel)
```

この式を[タイル座標とピクセル座標の関係、ピクセル座標と緯度経度の関係](http://www.trail-note.net/tech/coordinate/)と組み合わせれば、目的を達成することができる。

## 3. 実装 (JavaScript)

### 3.1. 緯度・ズームレベルからピクセルサイズを計算
計算式通り実装する。latitudeの単位が[rad]であることに注意。

```javascript
// Calculate resolution [meter/pixel]
const resolution = (latitude, zoom) => 156543.04 * Math.cos(latitude) / (1 << zoom)
```

### 3.2. タイル座標から緯度経度を計算
ここでは、タイル座標 `tileZ / tileX / tileY` のタイル上の `(pX, pY)` 要素の緯度経度を計算する関数を実装している。

```javascript
// Calculate lat/lon of pixel (pX, pY) on tile tileZ/tileX/tileY
function pixelOnTileToLatLon(pX, pY, tileZ, tileX, tileY) {
  const L = 85.05112878;
  // Pixel coordinate
  const x = 256 * tileX + pX;
  const y = 256 * tileY + pY;

  const lon = 180 * (x / (1 << (tileZ + 7)) - 1);
  const lat = (180/Math.PI) * Math.asin(Math.tanh(
    - Math.PI / (1 << (tileZ + 7)) * y + Math.atanh(Math.sin(L * Math.PI/180))
  ));
  return {lat: lat, lon: lon};
}
```

### 3.3. タイル座標からピクセルサイズを計算
上記の関数を組み合わせ、タイル座標で指定されたタイルにおけるピクセルサイズを計算する関数を実装する。
同じタイル内でも緯度によって結果が異なるため、与えられたタイル座標について北西 / 南東 / 中心の緯度経度を計算し、それぞれについて計算する。

```javascript
// Calculate pixel size [m] of given tile
function pixelSize(tileZ, tileX, tileY) {
  // North west / South east / Center
  const pNW =pixelOnTileToLatLon(0, 0, tileZ, tileX, tileY);
  const pSE = pixelOnTileToLatLon(255, 255, tileZ, tileX, tileY);
  const pCenter = pixelOnTileToLatLon(128, 128, tileZ, tileX, tileY);

  const deg2rad = deg => deg / 180 * Math.PI;

  return {
    min: resolution(deg2rad(pNW.lat), tileZ),
    max: resolution(deg2rad(pSE.lat), tileZ),
    center: resolution(deg2rad(pCenter.lat), tileZ)
  };
}
```

## 4. 例
例えばタイル座標 `13/7262/3232` （鍋割山付近）について`pixelSize(13, 7262, 3232)`を計算すると、1ピクセルあたり15.56 - 15.57 [m] であることが分かる。

```javascript
{min: 15.564756939473298, max: 15.57165416877383, center: 15.568219450043276}
```

以上
Human augumentation の論文


##Augmented Recreational Volleyball Court: Supporting the Beginners' Landing Position Prediction Skill by Providing Peripheral Visual Feedback
バレーボールの落下地点予測
https://dl.acm.org/doi/10.1145/3311823.3311843
拡張とは言っても、初心者のサポート的使い方もある


##Social Activity Measurement by Counting Faces Captured in First-Person View Lifelogging Video
ライフログで顔を測定することで、着用者の社会的活動を測定する。
社会活動の万歩計のようなもの。
声データは取っていないけど、相手の顔が写っているから、それを好スコアと捉えている。
https://dl.acm.org/doi/10.1145/3311823.3311846



##SubMe: An Interactive Subtitle System with English Skill Estimation Using Eye Tracking
英語のテキストとかにはあるけど、英語の総合的な脳力トレーニングとして適している映画に関するアプリはなかった。
アイトラッキングデータを利用して、視聴者の英語レベルを推定し、必要な分だけ字幕を生成するアプリを作成した。
https://dl.acm.org/doi/10.1145/3311823.3311865



##Sentiment Pen: Recognizing Emotional Context Based on Handwriting Features
手紙文字から感情が認識できるよ〜精度70%
https://dl.acm.org/doi/10.1145/3311823.3311868
Djangoでbase.htmlが呼び出せないとき

#Djangoで共通テンプレートを作成してTemplateDoesNotExistと怒られたときの対応
######自分がすぐ忘れるので、自分用メモです。

##状況
- プロジェクトディレクトリ直下にtemplatesディレクトリを作成し、その中にbase.htmlを作成
- 各アプリディレクトリ中のtemplatesディレクトリ直下のhtmlから、base.htnlを呼び出すと[TemplateDoesNotExist]エラーが発生

下の図だと、list.htmlからbase.htmlを呼び出したい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611400/65429907-2448-e890-1efb-da5cfb50b7af.png)


##Djangoのバージョン
3.1.1

##解決策
プロジェクトディレクトリ直下のsettings.pyに
import os
'DIRS': [os.path.join(BASE_DIR, 'templates')]
を追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611400/87e57813-022a-bdf6-4845-09c689526bd5.png)

あとは、base.htmlを読み込みたいhtmlファイルで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611400/f717635d-914e-dbfd-8ebe-38172c5e938c.png)

でOK!

[import os]を忘れていると
[name 'os' is not defined]
と怒られます。
Gitで使う用語のまとめ

Gitでは様々な用語が出てきます。結構頻繁にいろんな用語が出てきますのでその用語を簡単にまとめてみました。
用語の意味を理解してからいろいろな記事を見るとより理解が深まると思いますのでよかったら参考にしてください。

---
###リポジトリ
変更履歴の保管場所、過去のソースコードやファイルのデータベースの様なもの
###リモートリポジトリ
専用サーバやGitHub等のサービス上にある複数人で共有するためのリポジトリ
###ローカルリポジトリ
自分の作業端末、ネットに繋がってなくても作業できる環境にあるリポジトリ
###クローン（clone）
リモートリポジトリをローカルに複製することクローンすることでローカルリポジトリが作られる
###ワークツリー
gitの管理下に置かれた実際に作業するディレクトリのこと
###インデックス(index)
リポジトリにコミットするためにコミットする対象を登録するところ
###アド(add)
インデックスに対象を追加すること
###コミット(commit)
インデックスに登録された変更をリポジトリに反映させるこ、ゲームで例えるとセーブ
###ブランチ(branch)
変更履歴の保存場所。新たなブランチを作る（ブランチを切る）と変更履歴の保存場所を分岐させることができる。
ブランチを切ることによって何か変更を加えたい時にmasterブランチ（基本的にはプロジェクト等の本体になる部分）に影響を与えずに変更履歴を保存できる。
###ツリー（樹形図）orブランチツリー
コミットの履歴やブランチの状態などを見やすくしたもの
↓こんな感じのやつです
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394397/db6aa794-65d0-0ff4-ab8b-13bc2b73c375.png" width="400">
###マージ(merge)
各ブランチでの変更をまとめること、例えばブランチAをmasterにマージするとmasterにブランチAの変更が反映される
↓ツリーで見るとこんな感じになります
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394397/2902c0b6-03f9-b699-10ee-250d7ce01063.png" width="400">
###ヘッド（HADE）
現在自分が作業している所を示すポインタ
###チェックアウト（checkout）
ブランチを切り替える際などにヘッドを切り替えること
###オリジン（origin）
リモートリポジトリのことgitのコマンドを使う時にもよく出てきます
###フェッチ(fetch)
ローカルリポジトリにリモートリポジトリの特定のブランチをコピーすること
###プル（pull）
リモートリポジトリの状態をローカルリポジトリに反映すること
リモートのmasterブランチをフェッチしてきてローカルのmasterブランチにマージという一連の流れをやってくれる
###プッシュ(push)
ローカルリポジトリの変更をリモートリポジトリに反映すること
###コンフリクト（競合）
マージやリモートリポジトリにプッシュする際に変更箇所等が重複した際に発生する現象のこと、gitが『同じ所が変更されているよ！どっちが正しいの？』と言っている状態のこと

---


とりあえずよく使われるのはこんな感じかと思います。
自分なりにまとめてみましたが他にもいろいろな用語があるのでまとめ次第追記していこうと思います。
よく使うffmpegコマンドのメモ

# はじめに

毎回調べるのもアレなので、まとめておく。
詳細なコマンド説明はなし。

## ffmpeg

手抜きしてffmpegはdockerイメージのものを使用。
もちろん自前でビルドするのも、バイナリをダウンロードしてのインストールでも可。
（今回はMacでビルドするのが面倒だったため）

パスの通っているところへシェルを作成。

```sh
$ touch /usr/local/bin/ffmpeg
$ chmod +x /usr/local/bin/ffmpeg
$ vi /usr/local/bin/ffmpeg
#!/bin/bash

TAG=4.1-alpine
DOCKER_RUN="docker run --rm -it"
DOCKER_IMG="jrottenberg/ffmpeg:${TAG}"
DOCKER_VOL="-v ${PWD}:${PWD} -w ${PWD}"

#echo $DOCKER_RUN $DOCKER_VOL $DOCKER_IMG "$@"
$DOCKER_RUN $DOCKER_VOL $DOCKER_IMG "$@"

exit 0

$ ffmpeg -version
ffmpeg version 4.1.6 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.0 (Alpine 9.3.0)
  configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-fontconfig --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-libzmq --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-libopenjpeg --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-libsrt --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
```

# コマンド集

## x265エンコード

dockerコンテナ内のffmpegでx265エンコすると不正なファイルになる？
「moov atom not found」エラー
Windowsではエンコード可

* インタレース解除
* CRF 18
* プリセット：slow tune ssim
* フォーマット：yuv420p
* 30fps
* 1280x720へリサイズ（lanczos）

```sh
$ ffmpeg -i input.mov -movflags faststart -flags +loop+global_header -vf bwdif=0:-1:0 -c:v libx265 -crf 18 -preset slow -tune ssim -vf format=yuv420p -r 30 -vf scale=1280:720 -sws_flags accurate_rnd+lanczos -c:a aac -b:a 128k output.mp4
```

## mov -> mp4

Macで画面キャプチャして作成されたmov（x264+aac）をmp4コンテナに変更したいとき。

```sh
$ ffmpeg -i input.mov -movflags faststart -flags +loop+global_header -c copy output.mp4
```

## 音声抽出

```sh
$ ffmpeg -i input.mov -vn -acodec copy output.aac
```

## aac -> m4a

```sh
$ ffmpeg -i input.aac -bsf:a aac_adtstoasc -vn -acodec copy output.m4a
```

## カット

* -ss：カット開始時間
* -t：（-ssから数えて）カットする時間

```sh
$ ffmpeg -ss "hh:mm:ss" -i input.mp4 -t "hh:mm:ss" -c:v copy -c:a copy output.mp4
```

## m3u8のストリーム保存

chromeの場合、アドレスバーに「chrome://version/」と入力して確認できる。

```sh
$ ffmpeg -user_agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" -i "http://exsample.com/hoge.m3u8" -movflags faststart -flags +loop+global_header -map_metadata -1 -c copy -bsf:a aac_adtstoasc output.mp4
```
Unity「Add Script Component "****"…」が表示されC#スクリプトがアタッチできない

Unitでオブジェクトに作りたてのC#Scriptをアタッチすると
Can't Add Script - Add Script Component "***"
と表示されてアタッチできない事がある

いくつか要因があるようで、まとめる。
※関係ないものもあるかもしれませんがご容赦を。
　私の場合はおそらく3,4,5,6,7が原因でした

1.ファイル名とクラス名が異なる場合
　ファイル名がTestの場合、クラス名もTestにする必要がある。(ファイルをリネームした場合クラス名に反映されない。逆もしかり)
　＜参考資料＞
　https://freesworder.net/unity-cant-add-script/

2.Unity Hubのバグ
　＜参考資料＞
　https://teratail.com/questions/229361

3.Visual Studio に「Unityによるゲーム開発」
　がインストールされていない
　＜参考資料＞
　http://www.code-magagine.com/?p=3854

4.Visual Studioが最新バージョンでない
　＜参考資料＞
　http://www.code-magagine.com/?p=3854

5.デバッガ(Visual Studio)がUnityにアタッチされていない
　下記手順で解決することがある
　①スクリプトをダブルクリックし、Visual Studioを起動
　②メニューバー→デバッガ→Unityデバッガのアタッチを選択
　③ウィンドウが開くので該当するUnityのインスタンスを選択
　＜参考資料＞
　http://www.code-magagine.com/?p=3854

6.Standard Assetsをインポートしている場合
　Visual Studioでビルドすると「GUITextが旧形式です」と表示される場合はこれに該当する
　SimpleActivatorMenu.cs内に
　using UnityEngine.UI;を追加
　GUIText→Textに書き換える
　＜参考資料＞
　https://connect.unity.com/p/standard-assets-guitexture-and-guitext-are-obsolete

7.上記を実施した上で再起動
　最後はUnityとVIsual Studioを再起動したところでビルドが通り解決しました
【Windows】MacOSからWindowsにリモートデスクトップ接続する場合の日本語キーボード設定

# はじめに
MacからWindowsServer(もしくはWindows10)にRDP(リモートデスクトップ接続)する場合に、キーボード設定の影響でかな変換がうまくいかない場合があります。
今回は、こちらの事象の改善方法についてアウトプットしたいと思います。

# 確認した環境

- macOS Catalina 10.15.7
- WindowsServer2012 R2(VirtualBox上の仮想マシン)
- Microsoft Remote Desktop Version 10.4.1 (1825)

# 事象

Macキーボードの「英数キー」や「かなキー」を入力しても、文字が変換されない。
(別の文字が入力される。)

# 解決策

レジストリを変更する。

## 修正する場所

```
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\KeyboardType Mapping\JPN
```

## 修正内容

「00000000」のデータを以下のように修正します。
初期値：kbd101.dll
修正後：kbd106.dll

**修正後、再起動すると「英数キー」「かなキー」で文字の変換ができるようになります。**

![スクリーンショット 2020-10-25 17.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/ee6d6a6c-80f8-6444-ed2c-2de336b11594.png)


# 参考記事
[【新】Microsoft Remote Desktopで日本語キーボードを使う](https://sutepulu.com/japanese-keyboard-with-microsoft-remote-desktop-2/)
CPythonに機能追加してみた（三項演算子）

# はじめに
ここでは、CPythonに三項演算子を追加する手順ついて説明します。
本記事ではPython3.10を使用しています。CPythonのビルド、ファイル構造の説明は[こちら](https://qiita.com/takashi-o/items/d557033179e8d879ac31)でしているので併せてご参照ください。
* この記事はEEIC(東京大学工学部 電気電子工学科/電子情報工学科)3年の後期実験「大規模ソフトウェアを手探る」のレポートとして書きました。
* 以下の記事はチームメンバーが書いたものです。
[CPythonに機能追加してみた（ビルド&構造把握）](https://qiita.com/takashi-o/items/d557033179e8d879ac31)
[pythonに２種類のswitch文を追加する](https://naomi-notebook.hatenablog.com/entry/2020/10/20/200733)
[Pythonに前置インクリメントを追加](https://kkti4216.hatenablog.com/entry/2020/10/30/025233)


# 2. 三項演算子の追加
## 2.1 Pythonの三項演算子
Pythonの三項演算子は以下です。Pythonでは(条件がTrueのときの値)が先に来て、(条件)がその次、最後に(条件がFalseのときの値)が来ます。三項演算子の文法で(条件)が真ん中に来るのは一般的ではありません。

```python
(条件がTrueのときの値) if (条件) else (条件がFalseのときの値)
```

## 2.2 変更後の三項演算子
変更後の三項演算子は以下です。(条件)が先に来て、その後に、(条件がTrueのときの値)、最後に、(条件がFalseの値)が来るようにしました。C言語などはこの順番で三項演算子を記述します。

```python

if (条件) then (条件がTrueのときの値) else (条件がFalseのときの値)
```

## 2.3 コード変更
それでは、Pythonの三項演算子を2.2で示したものに変更していきます。Pythonには既に三項演算子が存在します。なので、これを流用して、if then elseが来た時に同じ処理を呼ぶようにすれば良いです。ここで、変更するのはpython.gramだけです。Grammer/python.gramのL341に以下の記述があります。

```:Grammer/python.gram
a = disjunction 'if' b=disjunction 'else' c=expression { _Py_IfExp(b, a, c, EXTRA) }
```

これは、元のPythonの三項演算子の記述です。これを真似して、下の行に変更後の三項演算子を記述します。

```:Grammer/python.gram
'if' a = disjunction 'then' b=disjunction 'else' c=expression { _Py_IfExp(a, b, c, EXTRA) }
```

ここで、_Py_IfExpを呼ぶときの変数の順番に注意します。以上の変更で

```
$ make regen-pegen
```

を実行し、再ビルドを行えば、三項演算子の追加ができます。もちろん、元の三項演算子の文法を使うこともできます。

# 3. デモ
以上の変更で実装された三項演算子は以下のように動作します。
![Peek 2020-10-20 13-05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/a1ba7e40-3f8d-6087-fd88-5cc3b7049acf.gif)


# 参考資料
- [大規模ソフトウェアを手探る](https://doss.eidos.ic.i.u-tokyo.ac.jp/)<br>実験のサイトです

- [CPython](https://github.com/python/cpython)<br>CPythonのリポジトリです

- [24. Changing CPython’s Grammar](https://devguide.python.org/grammar/)<br>CPythonに機能追加を行う時のチェックリストが載っていてCPythonの構造理解に役立ちました
[Scala] F[_] 高カインド型についてまとめ

## なぜ

scalaのライブラリを読んでると、`F[_]`、`G[F[_]]`のような記述が多くて、よく分からんかったので調べた。

## ソース


以下の記事を自分なりにまとめただけなので、以下の記事をまずは参照されると。
https://qiita.com/KtheS/items/649fbffcef18c74430f8


## valueとは

以下のような純粋な値のことをvalueという。
これが低階層の値である。

```scala
val name = "high kind"
val number = 1
```



## proper type

先ほどの例であげると、nameの`String`型や、numberの`Int`型、`List[String]`などをproper typeという。
先ほどのvalueよりも一段、抽象度が上がった表現である。

```scala
val name: String = "high kind"
val number: Int = 1
val listStr: List[String] = List("1", "2")
val listInt: List[Int] = List(1, 2)
```


## first-order type

List, Option, Mapのような型をfirst-order typeという。
これらfirst-order type型は、１つ以上のスロットを持つ。（List, Optionなら１つ、Mapなら２つ）
`List[_]`, `Option[_]`, `Map[_, _]`のことを、type constructorという。

```scala
val list: List[_] = List(1, 2)
val opt: Option[_] = Option(1)
val map: Map[_, _] = Map(a -> "1")
```

さらに一段と抽象度が上がった。


## second-order type

`F[_]`と型を抽象化した型をさらに抽象化したもの
下でいうと、`WithMap`

型コンストラクタ（`F[_]`）を取る型コンストラクタ（`WithMap[]`）ということで、`WithMap[F[_]]`を高カインド型という・


```scala

trait WithMap[F[_]] {
  
}

```


## F[_]の良い点

`F[_]`は、１つのスロットを持つ型を抽象化したもの

これによって、メソッドなどを共通化できる。


```scala
trait WithMap[F[_]] {
  def map[A, B](fa: F[A])(f: A => B): F[B]
  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
  def OrElse[A, B](fa: F[B]): F[B]
  def filter[A](fa: F[A])(f: A => Boolean): F[A]

}
```

上記例のようにメソッドを定義できる。
実態(Listなのか、Optionなのか)によらず、何個のパラメータをとる型なのかで、型を判断できる。


## 使ってみた

```scala

object TypeClassExercise {
  def executeUnwrapped[F[_], A](value: F[A])(implicit objectUnwrapper: ObjectUnwrapper[F]): A = {
    objectUnwrapper.unwrape(value)
  }
  
  // executeUnwrappedのimplicitの糖衣構文
  def executeUnwrapped2[F[_]: ObjectUnwrapper, A](value: F[A]): A = {
    implicitly[ObjectUnwrapper[F]].unwrape(value)
  }
}

trait ObjectUnwrapper[F[_]] {
  def unwrape[A](x: F[A]): A
}

object ObjectUnwrapper {
  implicit def listUnwrapper = new ObjectUnwrapper[List] {
    override def unwrape[A](list: List[A]): A = list.head
  }

  implicit def optionUnwrapper = new ObjectUnwrapper[Option] {
    override def unwrape[A](option: Option[A]): A = option.get
  }
}


object Run extends App {
  val objectUnwrappedListResult = TypeClassExercise.executeUnwrapped(List(1, 2))
  val objectUnwrappedOptionResult = TypeClassExercise.executeUnwrapped(Option(33))
  println(objectUnwrappedListResult)
  println(objectUnwrappedOptionResult)
}
```
"100TB"のファイルサーバにあるファイルを断捨離するために(1)

#はじめに
ファイルサーバを何年も運用していると、大量のファイルがわんさかと溜まって
容量の限界が今にもやってきそうな状態に。
ファイルサーバの更新がもうすぐ…といった都合の良いことはなかなかないものです。

じゃあ、どうする？

__ファイルサーバのファイル断捨離(整理)！__

でも、大量にあるデータやファイルをどうすれば良い？？？

ファイルサーバの整理を行う前の工程に取り組む機会がありましたので、
実際にやってみたことをまとめていきたいと思います。

# ファイルサーバの断捨離を始める前に
断捨離を行うまでにどのような取り組みが必要なのか、リストアップしてみると以下のような感じになるでしょうか。
　
 __1.__ どんなデータが、どのくらいあるのか把握したい
 __2.__ 実際にファイルサーバの使用容量やファイルの種類を可視化したい
 __3.__ 断捨離するにあたり、保存/削除するファイルを決めたい
 　(運用ルールがある場合は、状況把握とルールの見直しを)
 __4.__ 利用ユーザに利用状況やファイルの断捨離に向けた参考情報を共有したい
 __5.__ 利用ユーザに協力を得て、断捨離を行う！

これから連載として記載していく記事では、特に __1__ と __2__ についてまとめていきたいと思います。

また、今回断捨離に向けての準備を行うのに使用したツールを少しご紹介します。

ZiDOMA data
https://ari-jp.com/lp/zidoma/

ファイルサーバの分析＆移行ツールです。
実際に使用したのは、「__分析__」機能を使用しました。
分析機能をした後、どのように作業を進めていったのか？というところを踏まえて
ご紹介できればと思います。

次回は、

ZiDOMA dataでの分析の実施、分析データの活用方法の検討

について書いていきたいと思います。
俺的RxSwiftまとめ④(disposebagとは?)

この記事は、[俺的RxSwiftまとめ①](https://qiita.com/_Masa_asaM_/items/5b15094e047633070b92),[俺的RxSwiftまとめ②](https://qiita.com/_Masa_asaM_/items/4c75b2be7e4074efec45),[俺的RxSwiftまとめ③(Observableとは何か?)](https://qiita.com/_Masa_asaM_/items/17bf07d13aae320b464f)の続きです。

# 始め方は`subscribe`/終わらせ方は`dispose bag`
`Observable`の特徴として、「3つのイベント(`next/error/completed`)を持ち、subscribeすることでそれらの要素を取り扱えるようになる」というものがあった。
始め方は`subscribe`があるが、終わらせ方はどのようにすれば良いのか?それは、下記の3通りが考えられる。

- `error`イベントが流れてくる
- `completed`イベントが流れてくる
- `disposebag`(ゴミ袋)に`observarble`を追加する

今回は、3番目の`dispose bag`について詳しく記す。

## `disposebag`とは何なのか?

`observable`をまとめて破棄するためのゴミ袋

### なぜ必要なのか?
`observable`の中には、`completed`や`error`を流したくないものがある(ex:〇〇)。その場合は、`observable`に備わっている`dispose`メソッドを用いて、明示的に`observable`を完了させる(≒廃棄する)必要がある。(完了させないと、永遠に`subscribe`状態になり、メモリリークの原因となってしまうため。)

その際、`observable`個別に`dispose`メソッドを使う代わりに、管理コストを抑えるために`observable`をまとめて入れる`disposebag`をインスタンスのプロパティとして持たせておいて、インスタンス破棄のタイミングで全ての`observable`を`dispose`することができる(`ViewController`のプロパティとして持たせるパターンをよく見かける)
Exposedを使ってDBアクセス 

kotlinでのDBアクセスにExposedを使ったので忘備録。
動作確認にはDockerでテスト用のDBをたてて確認しました。

DOckerの環境構築は以下を参考にしました。
・WSL2とDockerの導入
https://qiita.com/KoKeCross/items/a6365af2594a102a817b

・WSL2のメモリ枯渇対策
https://qiita.com/yoichiwo7/items/e3e13b6fe2f32c4c6120


##Exposedとは
Kotlinで書かれたSQLライブラリです。
https://github.com/JetBrains/Exposed

##サンプルプログラム

まずはDockerでDBを作成するためのdocker-compose.yamlファイル。

```docker
version: '3'
services:
  db:
    image: postgres:12.3
    ports:
      - 5433:5432
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: admin
      POSTGRES_DB: test_db
```


次にテーブル定義。

```kotlin
object Member : Table("member") {
    val id = integer("member_id").autoIncrement().primaryKey()
    val name = varchar("name", 50)
    val age = integer("age")
}
```


最後にメイン関数。

```kotlin
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.SchemUtils.create

fun main() {
    Database.connect("jdbc:postgresql://localhot:5433/test_db", "org.postgresql.Driver", "admin", "admin")

    transaction {
        addLogger(StdOutSqlLogger)

        create(Member)

        Member.insert {
            it[id] = 1
            it[name] = "abc"
            it[age] = 20
        }

        Member.insert {
            it[id] = 2
            it[name] = "efd"
            it[age] = 30
        }

        for(member in Member.selectAll()) {
            println("${member[Member.id]}: ${member[Member.name]}: ${member[Member.age]}")
        }

        Member.update({Member.name eq "abc"}) {
            it[name] = "あいうえお"
        }

        for(member in Member.selectAll()) {
            println("${member[Member.id]}: ${member[Member.name]}: ${member[Member.age]}")
        }

        Member.deleteAll()

        drop(Member)
    }
}
```

やっつけですが、とりあえず一通りCRUDができることを確認できました。
Redux-saga備忘録

#Redux-saga備忘録

##generator関数

functionの末尾に*をつける
redux-sagaはgenerator関数にyieldを記述することで処理を実装する

```js
function* allNightNippon() {
  yield takeEvery(actions.Types.GET_USERS_REQUEST, getUsers);
}
```

##select
現在のstateから情報を取得する関数

```js
const waka = yield select(state => state.keidash.owarai.audrey);
```

##put
引数に渡したactionをdispatchする関数

```js
const waka = yield put({
 type: WAKABAYASI_NO_FAN,
 payload: {
  masayasu,
  toshiaki,
 }
});
```

##call
 Promiseの完了を待つ

```js

import wakatyan form './keydash/owarai/audrey';

const masayasu = yield call(callpost, wakatyan.run);
```

##fork
タスクの並列処理を行う

```js

import wakatyan form './keydash/owarai/audrey';
yield fork(wakatyan.run);
```

##takeEvery
Actionがdispatchされるたびにredux-sagaのtaskを起動する関数
Actionのとりこぼし対策に使用

```js

import wakatyan form './keydash/owarai/audrey';

function* allNightNippon() {
   yield fork(wakatyan.run);
}

yield takeEvery(ACTION, allNightNipponn);
```
エクセルの、ワークシート関数のみでQRコードを作成する


#参考（別投稿）
１ファイルのHTML(+JavaScript)で、QRcodeを生成する
https://qiita.com/santarou6/items/db17788158dba38f3a5c

- - -


# ＜本編＞エクセルの、ワークシート関数のみでQRコードを作成する

# エクセルファイル

excel2013以上

１．
型番５（37x37）最大62バイト
※日本語なら、utf-8で、１文字３バイトなので、２０文字まで

手作成QR_wrksht37.xlsx
https://github.com/santarou6/QR_EXCEL/blob/master/%E6%89%8B%E4%BD%9C%E6%88%90QR_wrksht37.xlsx

２．
型番１（21x21）最大7バイト
（もっとも小さいサイズのQRコードのみ。データ数は最大７バイト。UTF-8）

手作成QR_wrksht.xlsx
https://github.com/santarou6/QR_EXCEL/blob/master/%E6%89%8B%E4%BD%9C%E6%88%90QR_wrksht.xlsx

# 外観

１．
![外観_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/a8f522ca-bca5-b7f8-85ba-bb22065e3383.png)


２．
![エクセル外観.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/f397b3f6-bc09-d397-c17e-cd29e142d214.png)


# （過去投稿）
EXCELのVBAだけでQRコード。一部修正して日本語（全角）でも作成可能に。サンプルのエクセルファイルあり。
https://qiita.com/santarou6/items/d623417ea8ba33756108

↑の過去投稿では、VBA版のエクセルQRコード作成の例を挙げた


# 参考ＵＲＬ

ＱＲコードをつくってみる
https://www.swetake.com/qrcode/qr1.html

QRコードを人力で読み取る
https://qiita.com/amanao/items/b7c54a3c73a8301b2412

第3章 QRコードを作ろう!
https://kouyama.sci.u-toyama.ac.jp/main/education/2008/infomath/pdf/text/text10.pdf

「あ」を UTF-8 エンコード
https://qiita.com/yuu-eguci/items/9e85df49d8c27bb4b7f6

肉眼でも読める！QRコード入門
https://quizknock.com/qrcode-nikugan

特集：あなたも描ける！　JIS X0510準拠 QRコード®超入門
https://sites.google.com/a/osshc.co.cc/web/studies/it/qr

JIS X 0510_2004 二次元コードシンボル—ＱＲコード—基本仕様
http://kikakurui.com/x0/X0510-2004-01.html

QRコードのデコードソフトウェアの開発及び高速化に関する検討
https://www.nara-k.ac.jp/nnct-library/publication/pdf/h22kiyo3.pdf
【並び替え】あるユーザーのフォロー、フォロワーをフォローした、フォローされた順（降順）に並び替える！

# 概要
あるユーザーのフォロー、フォロワーをフォローした、フォローされた順（降順）に並び替えた時のことを備忘録として記録します。

# 環境
・ruby '2.5.7'
・rails '5.2.3'

# 前提
・ユーザーのフォロー機能は実装済であること

【参考】
[第14章 ユーザーをフォローする - Railsチュートリアル](https://railstutorial.jp/chapters/following_users?version=5.1#cha-following_users)

# 過程
## 1.実装することの確認

「あるユーザー（``@user``）のフォロー、フォロワーを（``@users``）フォローした、フォローされた順（降順）に並び替える（``order("relationships.created_at DESC")``）」

これを具体的にコードにしていきます！

## 2.following,followersアクションを定義する

users_controllerにfollowing,followersアクションを定義していきます。

```controllers/users_controller.rb
class UsersController < ApplicationController
（省略）

  def following
    @title = "フォロー"
    @user  = User.find(params[:id])

    get_follower_user_ids = Relationship.where(follower_id: @user.id).pluck(:followed_id)
    @users = User.includes(:passive_relationships).where(id: get_follower_user_ids).order("relationships.created_at DESC").paginate(page: params[:page])

    render 'show_follow'
  end

  def followers
    @title = "フォロワー"
    @user  = User.find(params[:id])

    get_followed_user_ids = Relationship.where(followed_id: @user.id).pluck(:follower_id)
    @users = User.includes(:active_relationships).where(id: get_followed_user_ids).order("relationships.created_at DESC").paginate(page: params[:page])

    render 'show_follow'
  end

（省略）
end
``` 

コードを順番に説明していきます！（followingアクションのみ説明します）

①　``@user  = User.find(params[:id])``で表示されているユーザーを``@user``に代入します。

②　``get_follower_user_ids = Relationship.where(follower_id: @user.id).pluck(:followed_id)``で``@user``にフォローされているユーザーのidを``get_follower_user_ids``に代入します。

③　``@users = User.includes(:passive_relationships).where(id: get_follower_user_ids).order("relationships.created_at DESC").paginate(page: params[:page])``で``@user``にフォローされているユーザーを``@users``に代入します。

　ここで、``includes(:passive_relationships)``とすることで、Relationshipモデルを参照できるようになり、``order("relationships.created_at DESC")``で並び替えることができます。

# 結果
これで、あるユーザーのフォロー、フォロワーをフォローした、フォローされた順（降順）に並び替えることができました！
配列の中に配列がある場合の値の出力の仕方

# 普通の配列

```ruby
colors =["white", "black", "red", "green", "blue"]
```
colorsという配列の中に、5つの要素が入っています。
先頭から順番に0、1、2、3…とインデックス番号が割り当てられています。
※1、2、3…ではないので注意！

出力する際は、

```ruby
puts colors[2]
```
とすると、3番目の*red*が取り出せます。

# 配列の中に配列

```ruby
animals = [["tuna", "octopus", "shark"], ["dog", "cat", "pig"], ["crow", "swan", "eagle"]]
```

こんな感じのやつです。
animalsという配列の中に、海の動物、陸の動物、空の動物をそれぞれ3種類ずつ入れた配列が入っています。


### 中身を全てまとめて出力する

```ruby
puts animals
```
↓

```
＜出力結果＞
tuna
octopus
shark
dog
cat
pig
crow
swan
eagle
```


### 海の動物だけを出力する
海の動物は0というインデックス番号が割り当てられています。

```ruby
puts animals[0]
```
↓

```
＜出力結果＞
tuna
octopus
shark
```

### タコだけを出力する
インデックス番号0という海の動物の中で、
さらにインデックス番号1が割り当てられています。

```ruby
puts animals[0][1]
```
↓

```
＜出力結果＞
octopus
```

### 指定して全て出力したもの
=> は出力されたものを表しています。

```ruby
puts animals[0][0]
=> tuna
puts animals[0][1]
=> octopus
puts animals[0][2]
=> shark
puts animals[1][0]
=> dog
puts animals[1][1]
=> cat
puts animals[1][2]
=> pig
puts animals[2][0]
=> crow
puts animals[2][1]
=> swan
puts animals[2][2]
=> eagle
```
# さらに複雑な配列
構造が複雑になっても、同じような感じで取り出すことができます。

```ruby
countries = [["Japan", "America"], [["Brazil", "Russia"],["China", "India"]]]
```
countriesという配列の中に2つの配列があり、
2つ目の配列の中にはさらにもう1つの配列が入っています。

```ruby
puts countries[0]
```
↓

```
＜出力結果＞
Japan
America
```


```ruby
puts countries[1]
```
↓

```
＜出力結果＞
Brazil
Russia
China
India
```


```ruby
puts countries[1][0]
```
↓

```
＜出力結果＞
Brazil
Russia
```

### 指定して全て出力したもの

```ruby
puts countries[0][0]
=> Japan
puts countries[0][1]
=> America
puts countries[1][0][0]
=> Brazil
puts countries[1][0][1]
=> Russia
puts countries[1][1][0]
=> China
puts countries[1][1][1]
=> India
```

ここからさらに四重とかになったとしても、同様の記述で値を取り出せます。
Pydriveの認証ファイルを，スクリプトと別ディレクトリに保存する


## 結論
Pydriveの認証ファイルをスクリプトと別ディレクトリに保存したい場合は，以下のように書けばOK．

```py
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from oauth2client.file import Storage

gauth = GoogleAuth(settings_file=f"{保存したいディレクトリの絶対Path}/settings.yaml")
gauth.credentials = Storage(f"{保存したいディレクトリの絶対Path}/credentials.json").get()
gauth.CommandLineAuth()
drive = GoogleDrive(gauth)
```

## 依存環境
```
python==3.7.6
pydrive==1.3.1
```

## 背景
### はじめに
Pydriveの基本的な使用方法や設定方法は，以下のサイトが丁寧に解説しているため割愛．

参考サイト：
[Python, PyDriveでGoogle Driveのダウンロード、アップロード、削除など - note.nkmk.me](https://note.nkmk.me/python-pydrive-download-upload-delete/)

### デフォルトだと，認証ファイルを別ディレクトリに保存できない．
Pydriveの認証ファイルは，(デフォルトだと)スクリプトが保存されているディレクトリと同じディレクトリに保存されていないと認証NGとなる．

例えば以下のように，スクリプト`main.py`と同じディレクトリに，認証ファイル`client_secrets.json`, `credentials.json`, `settings.yaml`を保存することがMust．

```
/home/hogehoge/
  └ hoge_project/
    └ src/
      ├ client_secrets.json
      ├ credentials.json
      ├ settings.yaml
      └ main.py
```

```main.py
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.CommandLineAuth()
drive = GoogleDrive(gauth)
```

### でも別ディレクトリに保存したい．
でも，`src`ディレクトリの中にスクリプトと認証ファイルとが混在しているのはなんか気持ちが悪い．
そこでなんとかして，以下のように認証ファイルを`creds/`ディレクトリ下に移動させたい．

```
/home/hogehoge/
  └ hoge_project/
    ├ creds/
    │  ├ client_secrets.json
    │  ├ credentials.json
    │  └ settings.yaml
    │
    └ src/
      └ main.py
```

### 引数を指定することで，別ディレクトリの認証ファイルを読み込むことが可能．
以下のように書けば，`creds/`以下の認証ファイルを，`main.py`が認識することが可能となる．

```main.py
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from oauth2client.file import Storage

gauth = GoogleAuth(settings_file=f"/home/hogehoge/creds/settings.yaml")
gauth.credentials = Storage(f"/home/hogehoge/creds/credentials.json").get()
gauth.CommandLineAuth()
drive = GoogleDrive(gauth)
```

参考サイト：[pythonのスクレイピングで躓いたところをメモ - Qiita](https://qiita.com/nacopon/items/515194278d0aa875cca0#pydrive-crontab%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%A8%E3%82%A8%E3%83%A9%E3%83%BC)

## さいごに
なかなか情報が見つからなくて苦労した．
他に何かあれば教えて下さい．
【JavaScript】外部JSファイルをmoduleとして読み込む方法【ES6】


## scriptタグにtype="module"を忘れずに
```html:index.html
<script type="module" src="js/main.js"></script>
```

## webpackではないので拡張子の「.js」は必要
```js:main.js
import { incidentDatalist } from './module.js'
console.log(incidentDatalist);
```

## 今回は変数としてexportする
```js:module.js
export let incidentDatalist = [
  { year: 1192, name: '鎌倉幕府が開かれる'},
  { year: 1600, name: '関ヶ原の戦い'},
  { year: 794, name: '平安京へ遷都'},
  { year: 1923, name: '関東大震災が起きる'},
]
```

console.log(incidentDataList);などで外部JSの読み込みができたことを確認できる。