OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter] Android toolchainの謎のエラーの解消する方法


とりあえず、たくさん書こうと思います。

Google Play Storeにアプリを提出する際に、Udemyの動画教材を使ってみた。
その時に、`flutter doctor`をして確かめた方がいいと言われたので、やってみると、、

```
[✓] Flutter (Channel master, 2.4.0-1.0.pre.74, on macOS 11.4 20F71 darwin-arm, locale ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.57.1)
[✓] Connected device (1 available)
```


読んでみて、なんとなく把握できた。

けど、色々とやることがありそうだなと思った。




色々やった結果、、、


![スクリーンショット 2021-07-07 21.53.15（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/5b9d5538-98ec-e3aa-6dab-b7da7046b683.png)
丸が汚くてすみません。。。


① `Android SDK Command-line Tools(latest)`にチェックを入れる

②`Apply`でダウンロードできます。



こちらでできました。笑
AWS Systems Manager Automation とは

## 勉強前イメージ

Systems Managerの自動化版？

## 調査

### Systems Manager Automation とは

略してSSM Automation と記載されることがあります。
AWS Systems Manager の中の一つの機能になります。

![1AWS Systems Manager - Automation - Google Chrome 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b621f147-8b86-0f0f-af83-15d230081296.png)

機能としては、AWSで実施したい処理をymlかjsonで記載し、タスクを自動化出来ます。

### コンポーネント

AWS Systems Manager Automationでは以下のコンポーネントを使用して実行しています。

- オートメーションランブック

ランブックでは、Systems ManagerがマネージドインスタンスとAWSのリソースに実行するさアクションの定義を行います。
オートメーションには事前にランブックが定義されており、EC2の再起動やAMIの作成など一般的なタスクも使用することが出来ます。
また、同くじで作成することも出来ます。

- 自動化アクション

オートメーションにはステップというものがあり、各ステップごとにオートメーションを関連付けられます。

- オートメーションクォータ

AWSアカウントはオートメーションを同時に100個実行できます。
それを超えて実行しようとすると保留中のステータスになります。

- オートメーションキューのクォータ

100個の同時オートメーションの数より多くのオートメーションを実行しようとすると、後続にオートメーションが追加されます。
追加にも制限があり、最大1000個までキューに保存することが出来ます。

- レート制御のオートメーションクォータ

AWSアカウントは最大25個のレート制御のオートメーションを同時実行できます。
25個より多くの実行をしようとすると保留中のステータスになります。

- レート制御のオートメーションキューのクォータ

最大25個のレート制御のオートメーションより多くのオートメーションを実行しようとすると、後続にオートメーションが追加されます。
最大1000個のレート制御のオートメーションをキューに追加できます。

## 勉強後イメージ

コンポーネントで雰囲気だけど、わかった気がする。
同時に実行するのもキューに入れるのも制限があって、
ランブックで定義されてることを自動化するって感じかな

## 参考

- [AWS Systems Manager Automation](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-automation.html)
- [AWS Systems Manager オートメーション を利用して作業を自動化しよう](https://www.skyarch.net/blog/?p=17125)
【Streamlit】Session Stateで変数の値を保持する方法 

# 初めに
本記事では2021年7月1日のアップデートによって追加された新機能 "Session State"を用いて，Streamlit上で変数の値を保持する方法をについて解説します．(公式ドキュメントに沿って解説を行います．)

そもそもStreamlitってなに？という方は，以下の記事が参考になります．
[[簡単爆速]HTMLファイル要らずのStreamlitで数分でWebアプリを作る](https://qiita.com/Nate0928/items/566c2073358b4df3ceec)

# Streamlitでは変数の値が保持できない？
Streamlitで，ボタンを押してそのクリック回数を記録するようなアプリを考えます．

```python:counter.py
import streamlit as st

st.title('Counter Example')
count = 0

increment = st.button('Increment')
if increment:
    count += 1

st.write('Count = ', count)
```

`counter.py`では，**Increment**と書かれたボタンをクリックした回数を変数`count`に格納しようとします．
ですが，これだとボタンを1回押して'count'が1に変化した後，そのあと何度ボタンを押しても`count`は1のまま変化しません．

![count11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982284/4a40312f-205d-3079-82fc-8e00bfa8a017.gif)

このような挙動を示すのは，**Increment**が押されたとき，`count.py`が一番最初から実行され，毎回`count=0`と初期化されそのあとに`count+=1`が実行されてしまうことに起因します．

# Session Stateとは
Streamlitでは，ブラウザのタブ単位でセッションを管理しています．このタブ上で更新や再実行が発生した際に，前後で変数の値を共有するための方法がSession Stateです．
Session Stateでは，セッション内での更新や再実行の前後で保持したい値を辞書形式で保存することができます．

```python
#辞書のように，keyとvalueをsession_stateに追加．
st.session_state['key'] = 'value'
#Session Stateにkeyと値を割り当て．上と同じ挙動を示す．
st.session_state.key = 'value'
```
上のようにsession_stateに追加した値は以下のように呼び出すことができます．

```python
st.write(st.session_state.key) #文字列'value'が出力される
#st.session_state['key']でも同様．
```

また，追加されていないkeyに対してsession_stateを呼びそうとすると例外が発生します．

# Session Stateを用いた解決法
上述のSession Stateを用いて，`count.py`を修正すると以下のようになります．

```python:count.py
import streamlit as st

st.title('Counter Example')
if 'count' not in st.session_state: 
	st.session_state.count = 0 #countがsession_stateに追加されていない場合，0で初期化

increment = st.button('Increment')
if increment:
    st.session_state.count += 1 #値の更新

st.write('Count = ' + str(st.session_state.count))
```
![counter_new.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982284/59215f86-22e1-559c-e532-bbcfacea9c7e.gif)

# 終わりに
Session Stateを利用をすれば，複雑な処理を経ずにセッション内での値を保持することが可能となります．より詳しく知りたい方は，参考にあるAPIレファレンスをぜひ見てみてください．
また，<a href="https://discuss.streamlit.io/">Streamlit公式フォーラム</a>も，様々なStreamlitのTipsが共有されていてお勧めです．

# 参考

- <a href="https://docs.streamlit.io/en/stable/add_state_app.html">Topic Guide: Add State to your App</a>
- <a href="https://docs.streamlit.io/en/stable/session_state_api.html">Session State API</a>
CKAとCKAD試験の紹介


# 1. Certified Kubernetes Administrator (CKA)試験
Certified Kubernetes Administrator (CKA) プログラムは、CKAがKubernetes管理者の責任を遂行するスキル、知識、および能力を備えていることを保証します。
![cka-exam.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535698/eb81a8cd-64dd-7bca-9175-4368e5e7d8bc.png)


### 対象者
この認定は、Kubernetes管理者、クラウド管理者、およびKubernetesインスタンスを管理するその他のITプロフェッショナルを対象としています。 

### この認定試験について
CKAは、Kubernetesエコシステムの開発を支援するための継続的な取り組みの一環として、Linux FoundationとCloud Native Computing Foundation（CNCF）によって作成されました。試験はオンラインで監督されたパフォーマンスベースのテストであり、Kubernetesを実行するコマンドラインから複数のタスクを解く必要があります。

### 証明されるスキル
certified K8s administrator は、基本的なインストールを実行できるだけでなく、本番環境レベルのKubernetesクラスタを構成および管理する機能を実証しました。また、Kubernetesのネットワーキング、ストレージ、セキュリティ、メンテナンス、ロギングとモニタリング、アプリケーションのライフサイクル、トラブルシューティング、APIオブジェクトプリミティブ、エンドユーザーの基本的なユースケースを確立する機能などの主要な概念を理解します。


# 2. Certified Kubernetes Application Developer (CKAD)試験
Certified Kubernetes Application Developer (CKAD) 試験は、ユーザーがKubernetesのクラウドネイティブ アプリケーションを設計、構築、構成、公開できることを証明します。 

### 対象者
この認定は、Kubernetesによるクラウドネイティブアプリケーションの構築、デプロイ、構成を担当するKubernetesエンジニア、クラウドエンジニア、その他のITプロフェッショナルを対象としています。 

### この認定試験について
CKADは、Linux FoundationとCloud Native Computing Foundation（CNCF）によって開発され、標準化されたトレーニングと認定を通じてKubernetesエコシステムを拡大するのに役立ちます。この試験は、オンラインで監督された、パフォーマンスベースのテストであり、コマンドラインで解決する一連のパフォーマンスベースのタスク（問題）で構成されています。

### 証明されるスキル
K8アプリケーション開発者は、Kubernetesのクラウドネイティブアプリケーションを設計、構成、公開できます。 CKADは、アプリケーションリソースを定義し、コアプリミティブを使用して、Kubernetesでスケーラブルなアプリケーションとツールを構築、監視、トラブルシューティングできます。 この試験は、コンテナ ランタイムやマイクロサービス アーキテクチャの知識があることを前提としていますが、それらを問うものではありません。 以下のような知識を持つ受験者を想定しています。 -DockerやrktなどのOCI準拠のコンテナランタイム。 -クラウドネイティブアプリケーションの概念とアーキテクチャ。 -Python、Node.js、Go、Javaなどのプログラミング言語。

# 3. 受験方法
試験形式：オンライン

直接Linux Foundationのサイトで購入できます。
https://training.linuxfoundation.org/ja/certification/certified-kubernetes-administrator-cka-jp/
https://training.linuxfoundation.org/ja/certification/certified-kubernetes-application-developer-ckad-jp/

再受験：1回のみ無料で可能

CKAの有効期限：3年間
 
CKADの有効期限：3年間
[C#] GenericHost環境でSerilogを年や月フォルダに振り分けさせる

# あらまし

`Serilog`の出力をフォイルに保存する際に、`年/月/日.txt`のように保存したくて情報探しまくった結果、やっとこさ見つかったのでそのメモ

# 方法

いつもの`Serilog.Sinks.Console`や`Serilog.Sinks.File`に加え、`Serilog.Sinks.Map`をパッケージ参照として加える

https://www.nuget.org/packages/Serilog.Sinks.Map/

あとは、以下の`issue`に書かれた方法で年や月フォルダに振り分けできる。

https://github.com/serilog/serilog/issues/534

# GenericHostでの実装例

`WriteTo`に次いで指定する`Map`メソッドの引数にて、

* 引数`keySelector`で日付を作成
* 引数`configure`で`keySelector`で作成した日付を基にフォルダパスを構成

```csharp
await Host.CreateDefaultBuilder(args)
    .ConfigureServices((ctx, services) => {
        // snip...
    })
    .ConfigureLogging((logging) => {
        logging.ClearProviders();

        var logger = 
            new LoggerConfiguration()           
            .WriteTo.Map(
                keySelector: logEvent => new DateTime(logEvent.Timestamp.Year, logEvent.Timestamp.Month, logEvent.Timestamp.Day),
                configure: (month, writer) => {
                    writer.File(path: $"./logs/{month:yyyy}/{month:yyyyMM}/log-{month:yyyyMMdd}.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information);
                },
                sinkMapCountLimit: 1
            )
            .WriteTo.Console(restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information)
            .CreateLogger()
        ;

        logging.AddSerilog(logger);
    })
    .RunConsoleAsync()
;
```
opencvの基本操作をまとめる（画像処理）

#はじめに

Opencvによる画像操作について初心者向けに備忘録としてまとめました。
機械学習で画像を扱う際において使うシーンがあるかと思います。


#Opencvとは
OpenCV（Open Source Computer Vision Library）とはコンピュータビジョン用ライブラリです。画像処理・画像解析および機械学習等の様々な処理を行うことが可能です。基本的に無料で利用することができ、商用利用も可能です。Linux、MacOS、Windowsや、iOS、AndroidといったOSとC++、Python、Javaの三つのプログラミング言語に対応しています。

詳細は本家チュートリアルをご確認ください。

http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_tutorials.html

#Opencvでできること

画像処理や機械学習など幅広い用途を活用することができます。
非常に多くの項目があるので、興味がある方は以下のリンクを参照してください。

https://ja.wikipedia.org/wiki/OpenCV



今回は画像処理の基本操作と色変換について説明します。


#画像入出力
必要なライブラリのインポート

```ruby:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
```
#入力画像を指定

入力画像を指定します。
引数が１の場合カラー、０の場合白黒で表示されます。

```ruby:python.py
img0 = cv2.imread('/content/test.jpg',1)
```

#画像を表示

画像を表示させます。


```
cv2.imshow('image',img0)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
![443.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/c15b7fc9-affa-f69c-2ce3-3ac29af59c02.jpeg)

入力画像が無事に表示されたかと思います。
ここから先はこの画像に処理を加えていきます。

#画像サイズを表示

```
print(img0.shape)
(300, 300, 3)
```
画像のサイズが表示されました。

#画像のサイズを変更（任意のサイズ）

入力画像を横150ピクセル、縦150ピクセルに変更して画像を保存する。


```
#リサイズする
img1 = cv2.resize(img0,(150,150))

#画像を保存する
cv2.imwrite('test1.jpg',img1)
```

![4431.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/e0266fcd-0af4-d45b-5e22-b37424df48e2.jpeg)



#画像のサイズを変更
入力画像を横を1/3倍、1/3倍に変更します。

```
w = img0.shape[1]
h = img0.shape[0]
img2 = cv2.resize(img0,(int(w/3),int(h/3)))
```





#画像を回転
入力画像を時計回りに90度回転させます。

```
img3 = cv2.rotate(img0, cv2.ROTATE_90_CLOCKWISE)
```


引数を変更することで別な回転も可能です。
`cv2.ROTATE_90_CLOCKWISE`: 時計回りに90度
`cv2.ROTATE_90_COUNTERCLOCKWISE`: 反時計回りに90度
`cv2.ROTATE_180`: 180度

角度を指定して回転することもできます。


```
w = img0.shape[1]
h = img0.shape[0]
center = w / 2, h / 2
M = cv2.getRotationMatrix2D(center=center, angle=230, scale=1)
img3 = cv2.warpAffine(img0, M, dsize=(w, h),borderValue=(255, 255, 255))
```
`angle`:回転角度

![test333.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/a72b1d00-049d-92cd-414c-2006d51c3500.jpeg)


#画像を反転
入力画像を上下反転させます。

```
img4 = cv2.flip(img0, 0)
```

引数を変更することで別な反転も可能です。
`0`: 上下反転
`1`: 左右反転
`-1`: 上下左右反転
#画像拡大
小さい画像を拡大することができます。画像を拡大する場合にはデータを補完する必要があります。補完のモードはいくつか存在しますが、ここでは`INTER_CUBIC`を使用して画像を拡大してみます。



```
img5 = cv2.resize(img0, (int(img0.shape[1]*4), int(img0.shape[0]*4)), interpolation=cv2.INTER_CUBIC) 
```

`cv2.INTER_NEAREST`: 最近傍補間
`cv2.INTER_LINEAR`: バイリニア補間
`cv2.INTER_CUBIC`: バイキュービック補間
`cv2.INTER_AREA`: ピクセル領域の関係を利用したリサンプリング
`cv2.INTER_LANCZOS4`: Lanczos 補間

#トリミング

```
img6 = img0[36:337, 85:325]
```

座標は`img[top : bottom, left : right]`となります。
各座標の位置は下の画像を参考にしてください。

![44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/30ffd09e-febb-25b6-6294-0089fe6099e4.jpeg)




#繰り返し（タイリング）

```
img7 = cv2.repeat(img1, ny, nx,img0)
```
ny - 縦方向繰り返し数.1以上.
nx - 横方向繰り返し数.1以上.

ny、nxを3とすると以下の画像を得ることができます。
![test7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/b64e0633-8ac9-d5eb-0ac3-0872011ee3d2.jpeg)

#まとめ
最後までご覧いただきありがとうございました。
RustのWeakについて気付いたどうでもいいこと

RustのWeakについて気付いたどうでもいいこと。

下記のdowngradeの引数に直接&RC::new(値)を渡すコードだとupgrade()で復元した際に値がNoneになる

```Rust:main.rs
use std::rc::Rc;

fn main() {
    let result = Rc::downgrade(&Rc::new(5));
    println!("result:{}", result.upgrade().is_none())
}
```

出力結果

```
fujii@DESKTOP-5KAHK0S:~/test_20210707$ cargo run
   Compiling test_20210707 v0.1.0 (/home/fujii/test_20210707)
    Finished dev [unoptimized + debuginfo] target(s) in 0.29s
     Running `target/debug/test_20210707`
result:true
```

一旦、RC::new(値)の値を変数に格納するとupgrade()で復元した際に値が保持される

```Rust:main.rs
use std::rc::Rc;

fn main() {
    let temp = Rc::new(5);
    let result = Rc::downgrade(&temp);
    println!("result:{}", result.upgrade().is_none());
    println!("value:{}", result.upgrade().unwrap());
}
```

出力結果

```
fujii@DESKTOP-5KAHK0S:~/test_20210707$ cargo run
   Compiling test_20210707 v0.1.0 (/home/fujii/test_20210707)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/test_20210707`
result:false
value:5
```

関数で&RCを返すとエラーになるんやから、 
コンパイル時にdowngradeに変数に格納されていない値をいれたら 
エラーにしてくれてもバチは当たらんと思う。

関数の場合

```Rust:main.rs
use std::rc::Rc;

fn main() {
    let result = Rc::downgrade(test_fn(5));
    println!("result:{}", result.upgrade().is_none());
    println!("value:{}", result.upgrade().unwrap());
}

fn test_fn(param:i32)->&'static Rc<i32>{
    &Rc::new(param)
}

```

出力結果

```
fujii@DESKTOP-5KAHK0S:~/test_20210707$ cargo run
   Compiling test_20210707 v0.1.0 (/home/fujii/test_20210707)
error[E0515]: cannot return reference to temporary value
  --> src/main.rs:10:5
   |
10 |     &Rc::new(param)
   |     ^--------------
   |     ||
   |     |temporary value created here
   |     returns a reference to data owned by the current function

error: aborting due to previous error

For more information about this error, try `rustc --explain E0515`.
error: could not compile `test_20210707`

To learn more, run the command again with --verbose.
```
【備忘録】 IntelliJ にて import 自動挿入時にシングルクォートで囲うように設定する

▼ メモ記事: 下記を参考に設定

https://memememomo.hatenablog.com/entry/2018/04/01/162414

## 改善方法

`エディター > コードスタイル > JavaScript > 句読点` にて、
使用を `ダブル` から `単一` にする

![スクリーンショット 2021-07-07 20.58.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441218/9fe49ba9-3a79-a9f2-2244-11af6365e0ed.png)

## 設定後の挙動 

■ before

```javascript
import React from "react";
```

■ after

```javascript
import React from 'react';
```
[Ruby on rails]referencesってなに？　初心者メモ

こんな感じのreferencesが出てきたコード



```
$ rails g model entry user:references room:references
$ rails g model message user:references room:references content:text
```

※userモデル、roomモデルは作成済み

こんな感じでうつと、

```perl:entry.rb
class Entry < ApplicationRecord
  belongs_to :user
  belongs_to :room
end
```

```perl:model.rb
class Message < ApplicationRecord
  belongs_to :user
  belongs_to :room
end
```

アソシエーションが勝手に入ってくれる。
#4 webアプリケーション（領域編）

#HTTP通信の復習
PCとwebアプリケーションの架け橋がインターネットでありHTTP通信でした。
今日は送受信する2つの領域（側）をまとめていきます。

#クライアントサイド
リクエストを送る側であり、レスポンスを受ける側
####クライアント
文字の通りwebアプリケーションを使用する顧客（ユーザー）のこと。

#サーバーサイド
リクエストを受ける側であり、レスポンスを送る側
####サーバー
画面のないPCのこと（自分でも消化できていないのが現状ですが、そう覚えるしかない。）です。
一つ一つのwebアプリケーションは、サーバーの中に保存されていて、インターネットを通じて閲覧したり、サービスを利用したりすることができます。


#サーバーの種類について
大きく分けて3つの種類がありました。
##①webサーバー
クライアントからのリクエストを処理したり、レスポンスを返したりする役割。（門番的な）
##②アプリケーションサーバー
webサーバーを介してきたリクエストを受け取り、webサーバーに情報を返す役割。
##③データベースサーバー
データを管理する役割。（写真やユーザー情報等）

※イメージ↓
💻→webサーバー→アプリケーションサーバー→（必要があればデータベースサーバー）↓
💻←webサーバー←アプリケーションサーバー←←←←←←←←←←←←←←←←←←←

#データベース（通称DB）とは
**データの集まり**のこと。図で書くと、パンケーキ４段みたいな円柱形。
動的コンテンツでは特に、各ユーザーの情報が毎時更新されることから、データベースが必要不可欠。
データの検索や更新追加等**SQL**という言語で行うことができる。


#まとめ
クライアントサイドとサーバーサイドで役割が違うし言語も違う。
フロントサイド（目に見える・表側）とバックサイド（目に見えない・裏側）とも言う。
PHP $thisとselfの違い

# 目的

- $thisとselfの違いが説明できなかったので簡単にまとめてみる

# `$this`とは

- webで調べたら下記のように記載されていた。

    ```
    $thisは、自分自身のオブジェクトを指し、インスタンス化した際、クラス内のメンバ変数やメソッドにアクセスする際に使う。
    ```

- また、独習PHPには下記のように記載されていた。

    ```
    $thisはインスタンスメソッド内でのみ利用できる特別なメソッドで、現在のインスタンスを指します。
    ```

# `self::`とは

- webで調べたら下記のように記載されていた。

    ```
    self::は、自クラスを示す。
    static変数はインスタンス化せずに使用します。この場合$thisは使用できません。
    ```

# 簡単なまとめ

- `$this`は現在のインスタンスを表している。そのため静的メソッドはそもそもインスタンス化されていないから`$this`は使用する事ができない。
- `self::`は静的メソッドや静的プロパティを呼び出すことができる。

# `$this`と`self::`の使い分け

| 項目 | 内容 |
| --- | --- |
| $this | インスタンス化されているメソッドやプロパティを呼び出す時に使用する |
| self:: | 静的メソッドや静的プロパティを呼び出す時に使用する |
IntelliJ をアップデート後に CLI から起動できなくなった

## 前提
端末: MacBook Pro
OS: macOS Big Sur 11.4
IntelliJ: 2021.1.3

## 事象

最近 macOS を最新にしたので、ついでに ToolBox 経由で IntelliJ も 2021.1.3 にアップデート。
その後いつものように下記のコマンドを叩く

```terminal
$ idea ${projectName}
```

何やら見たこともないエラーを吐く

The application /Applications/IntelliJ IDEA.app cannot be opened for an unexpected reason, error=Error Domain=NSCocoaErrorDomain Code=260 "The file “IntelliJ IDEA.app” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Applications/IntelliJ%20IDEA.app, NSFilePath=/Applications/IntelliJ IDEA.app

コマンドを確認しても、パスは通っている

```terminal
$ which idea
/usr/local/bin/idea
```

以前に参考にした記事を参照し、再度設定を確認
ランチャースクリプトの設定は、ツールボックス上で設定できるようになったとのこと

https://ema-hiro.hatenablog.com/entry/2019/02/15/234745

![スクリーンショット 2021-07-07 20.41.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441218/f8680e92-cacf-78f3-a3d2-0d65dc467d09.png)

公式のページを参照し、再度設定

https://pleiades.io/help/idea/working-with-the-ide-features-from-command-line.html#toolbox

![スクリーンショット 2021-07-07 20.44.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441218/9f3b03f9-ef8d-71f1-1a6f-021314e26527.png)

それでもエラーは変わらず・・。

## 原因と解決方法

`/usr/local/bin/idea` に定義されているパス情報が間違っていたことが原因
適切なパスに修正したら、問題なく `idea` コマンドが叩けるようになった

```
.
.
RUN_PATH = u'/Applications/JetBrains\ Toolbox/IntelliJ\ IDEA\ Ultimate.app'
CONFIG_PATH = u'${homeDirectory}/Library/Application Support/JetBrains/IntelliJIdea2021.1'
SYSTEM_PATH = u'${homeDirectory}/Library/Caches/JetBrains/IntelliJIdea2021.1'
.
.
```

恐らくアップデート前の IntelliJ は dmg からインストールし、
今回は ToolBox 上でインストールしたのが原因かと思われる
【Vue.js】コンポーネントの3つのナビゲーションガード

## はじめに
仕事で使う事になったので1からVue.jsについて学んだ。
ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。

## コンポーネントの3つのナビゲーションガード
### ナビゲーションガードとは
その名の通り、何かをガードするための処理の事で、大体ページ遷移前に特定の処理を実行させてページ遷移させないようにするとかで使う。
具体的には、ログイン前であればログイン画面にリダイレクトさせる、というような感じ。

### Vue.jsのvue-routerが持つナビゲーションガードの仕組み3つ
1. グローバルビフォーガード
1. ルート単位ガード
1. コンポーネント内ガード

の3つがある。

#### グローバルビフォーガード
全てのページ遷移前に何かの処理を実行する事で、ガードを実現できる仕組み。
具体的には`router.beforeEach`を使い、以下のようなソースコードを書く。
以下のようなソースコードでは、ページ遷移先のURLが`/user/1`である時、`/`にリダイレクトするというもの。

```js:main.js
import router from "./router";

router.beforeEach((to, from, next) => {
  if (to.path === "/users/1") {
    next("/");  
  }
  next();
})
```

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/90c766f99864f98aed2e4b931dd841b22ca99a6b

#### ルート単位ガード
特定のページへの遷移時に何かの処理を実行する事で、ガードを実現できる仕組み。
具体的には`beforeEnter`を使い、以下のようなソースコードを書く。
（以下では特に何のガードもしていない）

```js:route.js
import Vue from "vue";
import Router from "vue-router";

import Home from "./views/Home.vue";
import HeaderHome from "./views/HeaderHome.vue";

Vue.use(Router);

export default new Router({
    routes: [
        {
            path: "/",
            components: {
                default: Home,
                header: HeaderHome
            },
            beforeEnter(to, from, next) {
                next();
            }
        },
        // 省略
});
```

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/a34f06273d5101cda1fd5f143b3bd391f7aef89d

#### コンポーネント内ガード
本題のコンポーネント内ガードだが、これはVueインスタンスのオプションとして定義する。
定義できるものとしては3つあり、それぞれ以下のようなタイミングで実行される。

- **beforeRouteEnter**<br>自身のインスタンス（User.vueのインスタンス）が作成される前に実行される<br>通常のthisが使えないが、`next(vm => {})`のようにする事でthisに相当するものが使える
- **beforeRouteUpdate**<br>URLが変わったタイミング（$routeが変化したタイミング）で実行される<br>Vueインスタンスのライフサイクルフックがない代わりに、インスタンス変化(=URLの変化)を捕捉するためにこのbeforeRouteUpdateを使う（watchでも代替可能ではある）<br>※watchについては[ここ](https://github.com/yuta-katayama-23/intro-vuecli/commit/acc7728a68450e6804d6933606fe1ade239bd896)を参照
- **beforeRouteLeave**<br>URLが変わり、自身のインスタンスが破棄されるタイミングで実行される<br>一般的に、今いるページから離れてよいか？を確認してOKであればページ遷移するなどの使い方をする

![ezgif.com-gif-maker (33).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/de8cb543-820b-cc56-9a1d-0a7e125f4168.gif)
動画のソースコードは以下。

```vue:User.vue
// 省略

<script>
export default {
  // 省略
  beforeRouteEnter(to, from, next) {
    console.log("beforeRouteEnter");

    // nextのCallBack関数はVueインスタンスが作成されてthisにアクセスできるようになったタイミング(＝非同期)で実行される
    next((vm) => {
      console.log(vm.id);
    });
  },
  beforeRouteUpdate(to, from, next) {
    console.log("beforeRouteUpdate");
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log("beforeRouteLeave");

    const isLeave = window.confirm("本当にこのページを離れますか？");
    if (isLeave) {
      next();
    } else {
      // falseにするとページ遷移がStopする
      next(false);
    }
  },
};
</script>
```

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/9d40d557bbc60a1a36f31565c4e132ff4de1336b

## Vue.jsの勉強メモ一覧記事へのリンク
Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。

https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
「【プログラマーのための数学】余弦定理」を参考にWolframAlphaとSymPy Liveでやってみた。

(オリジナルポスト)

https://qiita.com/Esfahan/items/421619087c29cf0feed5#%E4%BE%8B%E9%A1%8C

例題
a^2 = 5^2 + 3^2 - 2・5・3・1/2
a^2 = 19

## WolframAlphaで

余弦定理 5,3,60°

https://www.wolframalpha.com/input/?i=%E4%BD%99%E5%BC%A6%E5%AE%9A%E7%90%86%E3%80%805%2C+3+%2C+60%C2%B0&lang=ja

結果:
3番目の辺の長さ | 4.359
1番目の辺の対角の角度 | 1.456 ラジアン
= 83.41° (度)
= 83 度 24 分角 47.61 秒角
2番目の辺の対角の角度 | 638.6 mrad (ミリラジアン)
= 36.59° (度)
= 36 度 35 分角 12.39 秒角

https://www.wolframalpha.com/input/?i=4.359*4.359&lang=ja

結果:
19.000881

## WolframAlphaで(変数入力はできませんでした。)

余弦定理 5,3,A-B

https://www.wolframalpha.com/input/?i=%E4%BD%99%E5%BC%A6%E5%AE%9A%E7%90%86+5%2C+3+%2C+A-B&lang=ja

最も近いと考えられるWolfram|Alphaの解釈を使います：5, 3 ,



# SymPy Liveで
以下のソースコードを貼り付けて、Evaluateです。

https://live.sympy.org/

```python
from sympy import *
var('b c A')
def cosd(mydeg):
    return cos(mydeg*pi/180)
print("#",(b**2+c**2-2*b*c*cosd(A)).subs({b:5,c:3,A:60}))
print("#",(5**2+3**2-2*5*3*cosd(60)))
# ('#', 19)
# ('#', 19)
```
Flutter×Firebaseで複数のアカウント種別を作成する

#1. はじめに
アプリケーションを作成していると複数のアカウント種別(何と表現していいのかわからない)を作成したくなることがあると思う。つまり、管理者アカウントと一般アカウントだったり、先生アカウントと生徒アカウントなど異なる属性のuserを作成するシチュエーションである。
Flutter×Firebaseの技術構成で上記のことを実現する方法を記事にする。


#目次
[1.はじめに](#1-はじめに)
[2.前提](#2-前提)
[3.今回採用した方法](#3-今回採用した方法)



#2. 前提
まず前提として今回は先生アカウントと生徒アカウントが存在するアプリケーションを考える。
アカウントはFirebaseAuthを使って作成し、情報をFirestoreに保存する。
ここで、先生アカウントと生徒アカウントに持たせたい情報が同じであれば、/users/{id}などとし、documentのfieldにフラグを持たせて先生か生徒かを判別すれば良い。
しかし、先生と生徒に持たせる情報が大きく異なる場合、同じ階層のdocumentに違うスキームのdocumentが混ざってしまう。そこで、/teachers/{id}や/students/{id}などとしてデータを扱いたい。

しかし、上記のようにデータを格納するとauthで手に入れれる情報(userId)からでは先生か生徒か判断できないため、ユーザの情報を取得できない。一つの手段としては/users/{id}も作成し、そちらには先生と生徒の両方に共通するデータを保持し、さらに先生か生徒かを判別するフラグを立てることが考えられる。そうすることで、ログインした後に、/users/{id}から先生か生徒かを取得することができる。

デメリットとして考えられるのは、データが散らばってしまうことと、user情報を取得するために2回アクセスする必要があることなどが考えられる。2回アクセスしたら時間もかかりそう(知らんけど)

#3. 今回採用した方法
最近[実践Firestore](https://www.amazon.co.jp/dp/B0851BGDQG/)を読んでいて知ったのですが、FirebaseAuthのCustomClaimsには任意のデータを置くことができるそう。つまりFirebaseAuthに先生か生徒かの情報を入れとけば、Authから判断してどちらのデータにアクセスするかを決めれる。さらに、CustomClaimsの値はセキュリティールールにも使えるため先生か生徒かという情報を使ってアクセスを制限することもできるようになる。一石二鳥である。
ただし、一つ注意が必要なのがCustomClaimsはAdmin SDKでアクセスしなければならない。
そこで、今回はCloudFunctionsを使ってCustomClaimsを設定する方法を取る。


CustomClaimsを設定する流れ

1.FirebaseAuthでアカウント作成
2.Firestoreにデータを保存(この際/teachers/{id}, /students/{id}のどちらかにdocumentを作成)
3.CloudFunctionsでdocumentの作成をトリガーにFirebaseAuthのアカウントにCustomClaimsを設定


1と2は今回の内容とは関係ないので3についてどのようなコードを書いたかを記載する。

```index.ts
exports.signUpAsATeacher = functions.region("asia-northeast1")
    .firestore.document("teachers/{id}").onCreate(async (snap, context) =>{
      const uid = snap.id;
      console.log(uid);

      firebaseAdmin.auth().setCustomUserClaims(uid, {
        role: "teacher",
      });
    });
```

```index.ts
exports.signUpAsAStudent = functions.region("asia-northeast1")
    .firestore.document("students/{id}").onCreate(async (snap, context) =>{
      const uid = snap.id;
      console.log(uid);

      firebaseAdmin.auth().setCustomUserClaims(uid, {
        role: "student",
      });
    });
```

上記の関数はそれぞれ/teachers/{id}もしくは/students/{id}にdocumentが生成された時に呼ばれる。
snap.idで生成されたdocumentIDを取得している。（これはauthのuserIDと一致させている。）
setCustomUserClaims()でCustomClaimsを設定する。

これで先生アカウントが作成された時には上の関数が、生徒アカウントが作成された時には下の関数が呼ばれ、それぞれCustomClaimsが適切に設定される。

設定されたCustomClaimsはFlutter側でどう取得するのって人のためにFlutter側のコードも少しだけ記述する。

```
final _auth = FIrebaseAuth.instance;
final userInfo = _auth.currentUser.getIdTokenResult(true);
String role = userInfo.claims["role"];
```
こんな感じでCustomClaimsは取得できる。
あとは取得したroleからfirestoreのデータを取得したり、画面遷移を変えるなりできる。


複数アカウント種別を管理するもっといい方法があるよという方がいらっしゃれば教えていただけると幸いです。
【Rails】アプリにファビコン(favicon)を設定しよう

### はじめに
Ruby on Railsでアプリを製作中です。久々にfaviconを設定しようとしたら、手順を全く覚えていなかったので、備忘録を兼ねてまとめてみました。

### faviconとは
ブックマークした時やタブ表示をした際に、webページ名の横に表示されるアイコンのことです。
<img width="400" alt="Qiitaアイコン.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689555/b3b0fad6-6872-168f-c1ff-9010c32f42d9.png">
(Qiitaだと緑の丸いアイコンですね。)

### 環境
- mac.os バージョン10.15.6
- Ruby 2.7.2
- Rails 6.1.3.1
- psql (PostgreSQL) 12.6

### 手順
#### ①faviconにしたい画像を探して、保存する
このときに、ファイル名を`favicon.ico`にしておきます。
#### ②アプリ内に格納する
`app/assets/images`内にfaviconを格納します。
※格納はドラッグ&ドロップでできます。

#### ③コードを記述する
`app/views/layouts/application.html.erb`

 ```r
<html>
  <head>
    <!--(省略) -->
    <%= favicon_link_tag('favicon.ico') %>
  </head>
  <body>
    <!--(省略) -->
  </body>
</html>
```
#### ④faviconが適用される
`rails s`でサーバーを起動させると、faviconが適用されていることが確認できます。

### 参考
1.[favicon（ファビコン）とは？役割や作成ツール、検証時の注意点までを解説](https://ferret-plus.com/8036/)
2.[favicon設定 Rails](https://qiita.com/ntkgcj/items/6643a07a43a36029dc9b)

### 最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
Flutterでデバッグ時のみ実行される処理を書く

当たり前すぎるから記事がないような気もしますが、`kDebugMode` でQiitaを検索してもズバリな記事がヒットしなかったので書いておきます。

Flutterのデバッグモードでのみ実行され、リリースビルドでは実行されない（[Tree shaking] 最適化で削除される）コードを書く方法です。

[Tree shaking]:https://en.wikipedia.org/wiki/Tree_shaking

# 方法1 kDebugMode を使う
```dart
import 'package:flutter/foundation.dart';

if (kDebugMode) {
  // ここにデバッグ時のみ実行したいコードを書く
}
```

kDebugMode は foundation.dart で定義されている定数です。上記のコードスニペットどおりに書いた場合は、リリースビルド時には[Tree shaking]によってデバッグ用のコードが削除されます。

ただし、kDebugModeを別の変数に突っ込んだものをif文で評価したり、kDebugMode以外の条件式を加えてif文で評価すると、[Tree shaking]が効かなくなる場合があるので、注意が必要です。

# 方法2 assert を使う
flutter の SDK 内で主に使われている方法がこちら。`assert` で常に true を返すような関数を書いてその場で実行するだけです。

```dart
assert(() {
  // ここにデバッグ時のみ実行したいコードを書く
  return true;
}());
```

機能的には kDebugMode を使った方法と変わりませんが、コードの foundation.dart への依存がなくなるのと、うっかりkDebugModeを使って複雑なif式を書いてしまいTree shakingが効かなかったー、みたいなミスを回避できる点がうれしいです。
# おわりに

基本的に方法2を使うのが良いと思います。

万一レビューで`assert`はこんな使い方するための機能じゃない！って言われた場合は、flutter SDK的にはこう書く流儀のようでして...と言えば円満に解決するかな...？
Nuxt.js + Pug + Stylus の開発環境構築メモ

## npm パッケージ一覧

### Nuxt.js アプリケーション

```
npm init nuxt-app <project-name>
```

https://ja.nuxtjs.org/docs/2.x/get-started/installation

https://note.com/youtarow/n/nf7e8d2aff2b1

https://ma-vericks.com/nuxt-init/

### pug インストール

```
npm i pug pug-loader pug-plain-loader
```

### stylus インストール

```
npm i stylus stylus-loader
```

### stylus の変数・mixinなどを共通で使えるようにするパッケージ

```
npm i @nuxtjs/style-resources
```


```js:nuxt.config.js
  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    '@nuxtjs/style-resources' // ①
  ],

  styleResources: {
    stylus: [
      '~/assets/styles/variables.styl' // ②
    ]
  },
```

### google fontsを読み込むためのパッケージ

```
npm i nuxt-webfontloader
```

```js:nuxt.config.js
  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    'nuxt-webfontloader'
  ],
  webfontloader: {
    google: {
      families: [{{フォント名}}]
    }
  },
```

https://mebee.info/2020/04/02/post-6660/


https://tech-broccoli.life/articles/engineer/use-google-fonts-with-nuxt/


## 参考記事

https://qiita.com/amishiro/items/38fe1b102d7e91a93ada
HGWを使用したv6プラス環境でのポート開放

#この記事で説明していること
- HGW（ホームゲートウェイ）を使用したv6プラス環境でポート開放（静的NAPT設定）をする方法

#背景
- 今住んでいる地域で PPPoE での IPv4 接続のあまりのあんまりさに嫌気がさしたので、IPv4 over IPv6 on IPoE を検討。
- NAPTをしたいので MAP-E のプロバイダを選択。
- しかしいざ開通してみると、HGW の NAPT 設定が神隠しに遭うというあんまりな（ｒｙ

#環境
- **プロバイダ**：So-net
- **回線**：Flets光（東）
- **HGW**：RS-500KI（v0.7.0.0030）

#問題
- 普通に HGW に接続して NAPT 設定をしようとすると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/b419763c-8065-8cce-6c5c-9cff52a4e18f.png)

**詳細設定にあったはずの「静的IPマスカレード設定」がない！！！**

#本題
ここからが本題。
静的NAPT設定の手順です。

1. 「http://**HGWのLAN側IPアドレス**:8888/t」にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/b75bd1be-c53a-a97c-b821-4048558cbcea.png)
2. 「IPv4設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/65b3c104-5f3d-e966-5037-1ff5f8251558.png)
※ ここで表示される「利用可能ポート」が MAP-E で割り当てられたポート番号です。

3. 「静的NAPT設定」をクリックすると、初回はパスワードの設定を求められるので設定します。これは HGW 設定画面のパスワードではなく、この「IPv4設定」画面のパスワードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/269ef52d-b0d4-9394-9c5f-82c8e5c8ee1c.png)
4. パスワードを入力して改めて静的NAPT設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/9967ebb3-29a1-ff57-c3c8-c5411f79356a.png)
5. 見慣れた感じの画面になるので、No.の数字をクリックして設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165947/762e8e2b-d316-aa05-1e92-05395ef1bd8c.png)
※ ​MAE-E で割り当てられていないポートを設定しようとすると警告が出ます。設定自体は可能ですが、当然通信はできません。

#蛇足
以上、v6プラス来たけどポート開放できないんだけどどうなってるんじゃ！ってなっていた方の参考に少しでもなれば。
さてこんな記事を書きましたが、実は今週末に HGW 環境から ONU-自前ルータ 環境に切り替えます。
この方法に気づく前に契約変更の申請をしてしまったので今更という（）
今回インターネット環境改善に際してプロバイダ変更や回線契約絡みのごたごたがあったので、それは別途記事にしてみようと思っています。
それでは。
Git GitHub　リモートリポジトリの作成とファイルのpush方法（初心者向け）

##概要
スクールでの課題を終えた後、
GitHubを使った提出ができず苦労したので手順をまとめました。

##状況
**以下は終わっている状態からのスタートです**
・GitHab登録、SSHキー作成、公開鍵の登録、GitHubとの接続確認
・送信したいファイルの用意
#手順


**GitHubにて**
1. git hub上にリポジトリを作成する　create repository

 **ターミナルにて**
*まず自分のプッシュしたいディレクトリに移動します*
(1)```& cd ディレクトリ名```　（移動）
(2)```& pwd``` （現在の場所確認）
　　 *そのフォルダが初めてgit準備をする場合、ディレクトリにgitファイルがない場合のみ(3)を実施*
(3)```& git init```　（そのディレクトリにgitディレクトリが作成される）
(4)```& ls -a``` (-aは隠しファイルを画面に見えるようにするため)
(5)```& git status``` （現在の状況を確認　[masterというbranchにいる][commitしていない]など知ることができる）
 　　*ここでUntracked files配下に出力されたファイルは、ステージングエリアに追加していないファイルです*
(6)```& git add 対象ファイル```　or ```& git add .``` (ステージングエリアへ追加)
　　*```& git add .```を使うと、カレントディレクトリ内の変更があったファイルを一括してステージングエリアへ追加*
(7)```& git commit -m "コミットメッセージ"``` (リポジトリの内容保存)
(8)```& git log``` (メッセージ確認)　
(9)```& git status``` (状況確認)

**GitHubに戻ります（githubのリポジトリにソースコードを送信）**
2. GitHubのsetting左側のRepositoriesをクリック
3. リポジトリのリンクをクリック
4. SSH（グレー）プロトコルURLをコピー ```& git remote add origin git@github.com:yourname/######.git```
5. ```& git remote -v```　（登録確認）
6. ```& git status```（commitしたか確認）
7. ```& git push origin master``` (GitHubのリモートリポジトリにソースコードを送信,masterブランチの場合master)
未経験からCCNA取得までの道のり　ver６

昨日は1日体調を崩していたので、投稿ができなかった！！
毎日投稿できなかった！！だから決めた！
もしまた体調を崩したりして投稿できなかった分はストックして、元気になった時にその日の分も投稿する！


ルータにIPアドレスを設定したり、インターフェイスの状態を確認したりという動作を行うには、管理者のPCとルータを接速する必要がある
管理アクセスする方法は２つ

🚩コンソール接続
　機器に物理的に装備されているコンソールポートとPCを専用ケーブルで直接接続
　する
　
　コンソール接続が済んだら、管理者のPCからCiscoルータにコマンドを送る
　ターミナルソフトを使用して送る


🚩VTY接続
　機器に仮想的に用意したVTYポートに、離れた場所からネットワークを介して
　TelnetまたはSSHで接続する

　Telnetのプロトコルを利用してCiscoルータに管理アクセスするにはVTY（仮想端末回線）と呼ばれるポートに接続。
VTYとは、ルータ内に用意される論理ポートで管理者はVTYを通してルータを離れた場所から操作することができる。論理ポートのため、コンソールのように物理的にケーブルで接続することはできない。


Cisco IOSモード

🚩ユーザEXECモード　プロンプト「＞」
機器の状態を確認したりするモード。確認できる項目が制限される。

🚩特権EXECモード　プロンプト「＃」
機器の設定や状態を確認できるモード。設定ファイルの操作やシステムの再設定なども行える。

🚩グローバルコンフィギュレーションモード　プロンプト「（config)#」
機器全体に関わる設定を行える。

🚩インターフェイスコンフィギュレーションモード　プロンプト「（config-if)#」
インターフェイスに関わる設定を行える。

🚩ラインコンフィギュレーションモード　プロンプト「（config-line)#」
コンソールやVTYモードに関する設定を行える。

🚩ルータコンフィギュレーションモード　プロンプト「（config-router)#」
RIPやOSPFなどのルーティングに関わる設定が行える。


とりあえず「ccnaの基礎が一週間で学べる本」は3日で読破しました！
全く知識がないところから、ざっくりとどんなことをしているのか等基礎はわかった気がします！！
もう一周しながら、白本の一周目始めていきます！
FreeDOSでTCP/IP

DOSなので、PKTドライバーでTCP/IPが話せるようにしてみました。ネットワークカードはPLANEXのPCIのFNW-9700-Tで、メーカーサイトのサポートファイルにPKTドライバーが入っていました。

TCPスタックはいくつか選択肢があったのですが、開発が続いている[mTCP](http://www.brutman.com/mTCP/)を使うことにします。mTCPはFreeDOS 1.2のCD-ROMに入っているので、FDIMPLESコマンドでインストールできます。

~~環境変数のMTCPCFGで設定ファイルを指定します。~~
FreeDOS 1.3では\NET\FDNET\FDNETPD.BATにパケットドライバーを書くと自動的にロードされるようになりました。

DHCPコマンドを動かすとIPアドレスが拾えて、設定ファイルにその設定を書き込むようです。

これでPINGコマンドなどが使えるようになります。

mTCPはそれぞれのコマンドにTCPスタックが入っていて、常駐プログラムはありません。このため外部からpingを打っても返答がありません。

mTCPにはtftpコマンドがありませんがNCコマンドがあるので、ファイル転送はこのコマンドでできます。

FreeDOS側

```
C:\MTCP>nc -listen 8080 -bin > test.exe
```

FreeBSD側

```
% nc -N <IP ADDRESS> 8080 < test.exe
```

mTCPにはftpのクライアントとサーバがありますが、ncの方がお手軽です。httpでファイルを取得するhtgetもありますがサーバが必要です。

3.5incフロッピーでコピーする方法もあります。

sntpのコードをいじって、tftpクライアント作ってみました。

https://github.com/yamori813/mTCP

FreeBSDのLinuxエミュレーションで実行しているOpen Watcom v2でビルドしてます。最初の転送は上記のncコマンドで行います。

Wifiルーターの子機にEthernetをつないで、Wifiでのネットアクセスも出来ました。
未経験からCCNA取得までの道のり　ver５

アドレス編

✽宛先IPアドレス（インターネット層）
最終的にどこに届けるか

✽宛先MACアドレス（リンク層）
次にどこに届けるか


🚩ARP

宛先IPアドレスから宛先MACアドレスを調べるプロトコル！！

ARPリクエストをブロードキャスト通信で送信して、ARPリプライをユニキャスト通信で受け取りARPテーブルに一時的に保存する

ARPテーブルに保存は、リクエストの時とリプライの時両方で行われる

⭐︎外部ネットワークと通信するとき！

ARPリクエストはブロードキャスト通信で行われるが、ルータはスイッチのフラッディングと異なり、ブロードキャストを他のネットワークに転送しない。
そのためルータを超えた先にある、MACアドレスは検出できない。

そもそもMACアドレスは同じネットワークに接続されたノード同士で通信するために定義されたリンク層のアドレス！！

ホストが外部のネットワークと通信する際は、デフォルトゲートウェイとして設定されているルータに転送してもらう！

つまり。デフォルトゲートウェイのMACアドレスをARPで取得して、それをあて先としたフレームを送信する。


IPアドレスには、
「プライベートアドレス」と「グローバルアドレス」がある

プライベートアドレスの範囲は

・クラスA　　10.0.0.0~10.255.255.255
・クラスB      172.16.0.0~172.31.255.255
・クラスC      192.168.0.0~192.168.255.255

これは内部ネットワークで自由に使用できるが、インターネット上では使用できない。
BH3-FA SDカードの初期化


###はじめに
本作業を行うことでBH3-FAで使用するSDカードを工場出荷時の状態に戻すことができます。

###手順
1. 下の写真のようにHB3-FAの蓋を外しSDカードを取りだします。取りだしたSDカードをWindows PCに挿入します。
2. SDカードを挿入したPCで該当するOSデータをダウンロードします。

Raspbian Buster Desktop 2021-05-07 版 + bh-fa-tools（約4.8GB）：https://download.bizright.jp/bh-fa-buster-2021-05-07-latest.zip

Raspbian Stretch Desktop 2019-04-08 版 + bh-fa-tools（約3.4GB）：https://download.bizright.jp/bh-fa-stretch-2019-04-08-latest.zip

3. Win32DiskImagerなどイメ－ジファイル書き込み用ソフトウェアを使ってSDカードにダウンロードしたイメージファイルを書き込みます。書込みが完了するとf2fsファイルシステムへの変換およびセットアップツ－ルのインスト－ルが適応されています。

|![main_05 -.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590352/35e822b0-ed96-d8cc-f0d6-cfbea5b256df.jpeg)
|:---:|
|【ビズライト・テクノロジー社製 BH3-FA】|
BHシリーズは、株式会社ビズライト・テクノロジーが開発・生産する、シングルボードコンピュータの実用化した商品です。BHシリーズではRaspberryPiを産業利用するための対策が施されています。詳しくは、[こちら](http://bh.bizright.co.jp/)をご覧ください。
【連載】Arduinoを使って学ぶ、Win/Macドライバ開発講座

# この講座で学べること

<a href="https://sciencepark.co.jp/device_driver/">サイエンスパーク株式会社</a>では、WindowsやMacのデバイスドライバの開発やデバイスドライバを利用した情報セキュリティ対策ソフトウェア(Driverware SDK)を提供しております。デバイスドライバの開発だけではなく、情報発信についても力を入れてきました。

 

古くは日本のデバイスドライバ開発の黎明期である1999年に「Windows Device Driver Developer's Conference」(WDDDC)として、海外から講師を招待してデバイスドライバ開発者向けにカンファレンスを開催いたしました。WDDDCはデバイスドライバ開発者向けセミナーとして「Windows Device Driver Developer's Seminar」(WDDDS)と名称を変え、現在も毎年開催しております。当初は弊社によるデバイスドライバ向けの講演のみでしたが、最近では日本マイクロソフト社に協賛いただきデバイスドライバや新しい技術について講演いただいております。また、WDDDSはデバイスドライバ技術者同士の交流の場となっており、企業の枠を超えて情報を交換していただいております。
 
これらのセミナー以外にも情報発信としてWindowsドライバ開発書籍の日本語訳版を2巻出版しました。
既に絶版されておりますが、以下が弊社にて出版した書籍となります。
https://www.amazon.co.jp/s?rh=p_27%3A%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E3%83%91%E3%83%BC%E3%82%AF


また、Web上でもドライバに関する情報を発信しており、<a href="https://qiita.com/spc_qiita/items/f7aea7a92b4f53106d3d">Qiitaにて連載中のデバドラ講座</a>の前身である弊社ホームページ上の「<a href="https://sciencepark.co.jp/device_driver/dvdr/">デバドラ講座</a>」は多くの方にご覧いただいており、人気コンテンツとなっております。



 

本連載では、今年(2021年)のWDDDSにて講演いたしました「Windows/Mac対応デバイス向けドライバ開発(初級編)」について、シリーズ化して連載いたします。

 

今回の講座では
「WindowsまたはMacでドライバの開発をはじめたい」
「WindowsとMacで同一の機能を開発する場合、どのような相違点があるのか」
などの内容について知りたい方に向けた投稿です。
初心者向けにWindowsとMacのドライバ開発について解説し、最終的にその相違点についてまとめていきます。
# 目次

この講座の構成は、以下の通りです。

第1回：Arduinoの仕様

第2回：Windowsでの実装1 ~スケルトンの解説とドライバ実装~

第3回：Macでの実装1 ~プロジェクト作成とドライバ実装~

第4回：Windowsでの実装2 ~操作用アプリの実装と動作確認~

第5回：Macでの実装2 ~ドライバインストールアプリと操作用アプリの実装~

第6回：Windows/Macのドライバ開発方法の違いについて
GTMとGAを使って、特定のコンポーネントが表示された回数を計測する

## 状況
- 投稿完了後に表示されるモーダルの表示回数を計測したい
- 投稿完了後に必ず表示されるわけじゃない→`投稿数`≠`モーダルの表示回数`
- 投稿完了後に遷移するページも一定じゃない
- モーダルを表示するかどうかをサーバーサイドで制御していて、非表示の時には要素自体が出力されないようになっている。
    - 表示/非表示をCSSの`display: none`の付け外しとかで制御している場合、今回の方法は使えないかも

## 実装すること
計測したいモーダルが表示されたタイミングでタグを発火し、GAにイベントを送信

## 設定方法
### 前提
GAやGTMのアカウント登録、タグの埋め込み等ができている。

### トリガーを作成
トリガーのタイプに`要素の表示`をセットし、特定の要素が画面に表示されたタイミングで発火されるように設定。
![ 2021-07-07 18.53.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/38c5fafc-d84c-2f0e-4d6b-8926dfed8551.png)

### タグを作成
どのページで表示されたかを計測するために、ラベルに`{{Page Path}}`をセットしています。
![ 2021-07-07 18.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/1cb78325-b974-0f1d-6af8-637cf5c2911e.png)

### 公開
公開しないと、変更が反映されないので注意
![ 2021-07-02 12.51.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/bbd857b7-d0ac-a24e-b52e-bb7c12f23085.png)

### GAで確認
GoogleAnalyticsにアクセスし、`行動`>`イベント`メニューよりデータを確認することができる。
![ 2021-06-29 19.46.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/619b2eaa-67ff-50bf-960c-a623a929427b.png)

## トリガー「要素の表示」についての補足
検証はできてないけど、調べてたら以下の情報がヒットしたので書いておく。

- 1画面に収まらない巨大なブロックを指定する場合、視認の最小割合の指定に注意
    - 100％などにすると、大きさ的に1画面内に収まらないので発火しなくなる
- 「各要素が画面に表示されるたび」を指定すると、一度画面外に外れてまた表示した場合に複数回カウントされる
- 初期表示画面内などで複数の対象が一度に表示された場合でも、問題なく動作する
    - 要素数分、個別にイベントが発生する
- CSSで対象要素の上に別の要素がかぶさっていて実際には見えない場合でも、トリガーは反応する
- CSSで非表示や画面外飛ばしなどをしていると、トリガーは反応しない
- IDで指定した場合、HTML内に同一IDが複数存在した場合（本来はHTML的にNG）は最初のIDの要素のみに反応する

https://jdash.info/archives/Google_Tag_Manager_Element_Visibility_Trigger_not_fire
非モデル生物などから比較的安価に集団解析をする方法：RAD-seq

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/1669.html)から移行中です。
元記事：2016/10/13 公開 非モデル生物などから比較的安価に集団解析をする方法（RAD-seq)
</font>

　ゲノムサイズが未知で、Whole-genomeを使っての集団解析を行うのは厳しい、それでも解析を行いたいというときに活躍する方法としてRAD-seq（Restriction-site Associated DNA Sequencing）という方法を紹介します。

#解析範囲
　RAD-Seqは次世代シーケンシング技術を用いた、制限酵素認識サイトの近隣領域（ゲノム全体の0.1~1%程度）を解析する手法です。この方法では下記の図のようにゲノムを制限酵素で切断し、切断した部位から50-100bp程度のシーケンスを読み、SNPsを探索します。シーケンス範囲が狭いため、通常のWhole genomeをショットガンシーケンスで読むよりも低コストで効率よく解析が行えます。

![RAD-Seqのシーケンス範囲](https://www.pictbio.com/wp-content/uploads/tips/RAD1.png)

また制限酵素の種類を変えることで、高密度解析、低密度解析の調整が可能となります。

###低密度解析
低コスト、探索範囲は狭い (e.g. 8bp認識の制限酵素カット)

###高密度解析
高コスト、探索範囲は広い (e.g. 6bp認識の制限酵素カット)

　ただいろいろやってみた感想ですが、ゲノムサイズが大きすぎると制限酵素サイトもそれに応じて大きくなるので、カバレッジが低くなる傾向があるようです。

　変異が生じていると断ずるには最低5カバレッジは欲しいところです。カバレッジが低くても、候補を増やしたい時には、ツールの方でカバレッジを低くして、よりセンシティブに検出できるようにする方法があります。・・・が、あまりお勧めしません。一度解析して、いい結果が出そうであれば、素直にもう一度読んでデータ量を増やしたほうがいいと思います。

# 解析内容

+ 種内での分子系統解析
+ 品種・系統・集団間での遺伝的変異の同定
+ 集団構造解析
+ 連鎖解析
+ 特定の遺伝子のマッピング
+ QTL解析

など。

>["Double Digest RADseq: an inexpensive method for de novo SNP discovery and genotyping in model and non-model species" Peterson et al., 2012](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0037135)

　上の使える解析をみて、あれ？そういえば似たようなことが分かる解析があったぞ。って思った方正解です。ISSR（Inter Simple Sequence Repeat）で行う解析も同じようなことが出来ましたね。これらを利用したMIG-Seq（multiplexed ISSR genotyping by sequencing）という解析手法もあります。考え方としてはRAD-seqと同じで、制限酵素の部分がISSR認識のプライマーに変わった手法となります。

>["MIG-seq: an effective PCR-based method for genome-wide single-nucleotide polymorphism genotyping using the next-generation sequencing platform" Suyama, Y. & Y. Matsuki. 2015](http://www.nature.com/articles/srep16963)

#解析ソフト

有名なものに、 

+ [Stacks](https://catchenlab.life.illinois.edu/stacks/)
+ [pyRAD](http://dereneaton.github.io/software/pyrad/)

があります。

　pyRADのほうがInDelを考慮してくれる反面、そのせいで解析時間が結構かかるという特徴があります。また使ってみた個人的感想として、1サンプル当たりの配列数が少ないと、Stacksと比較して、データが出にくい傾向があるように思います。

　受託解析や共同研究では、上のStacksを使うことの方が多く論文もStacksのほうが多いようです。


#最後に
　コツですが、まず制限酵素選びが重要です。先ほど6塩基認識、8塩基認識のところでも説明しましたが、探索範囲が大幅に変わってきます。生物種によっても異なるため、一度少量だけでも読んでみて、検討してみたほうがいいと思います。

　こちらにわかりやすくまとまっておりますので、確認してみてください。
>[DDBJing33 ゲノムワイド多型を利用した遺伝解析の実際.pdf](https://drive.google.com/file/d/14_SVeNUN-r-pTHxumFDZFXhRa-DfZn53/view?usp=sharing)
NGS受託解析サービスの選び方

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/832.html)から移行中です。
元記事：2015/09/15 公開 受託解析サービスの選び方
</font>

　今回は受託解析サービスの選び方についてお話しします。

最初に結論から言いますと、サービスを選ぶときは、

+ その会社が出してくるデータが自分の想定している要件を満たしているか
+ 予算

などを鑑みて頼まれるといいと思います。

　弊社はNGSが出始めたくらいから受託解析サービスを行っており、当時は数社しか受託解析を行っているところはありませんでした。しかし最近はこれらのサービスを行っているところが、かなり増えてきました。大手さんはWetからDryまで一通りの解析を格安でやっていますし、他社ではパイプラインを用意して、自分の手で解析を行えるようにしています。ただその中でもある程度すみわけが存在します。それが下記の図です。

![NSG受託解析サービスの種類](https://www.pictbio.com/wp-content/uploads/tips/characteristic.png)

#シーケンシング＋データ解析
　これは大手さんに多いサービスになるのですが、サンプルまたはライブラリを送るとデータとなって返ってくるサービスになっています。メリットはなんといっても 安く済むことにあります。

　なぜ安く済むのかというと、wetとセットの価格ということもありますが、解析がルーチンで回せるからというのが大きいでしょう。その分デメリットも存在し、ある程度までは解析をしてくれるのですが、論文にするときなどにさらに解析が必要な場合がほとんどです。そのためそのデータをどう扱えばわからない方たちが、データを持て余しお蔵入りしているケースを多く耳にします。

#データ解析のみ
　これはNGSを持っている人が、解析だけを他所に委託するケースです。メリットは シーケンサーを自由に選択 できることです。

　また解析はルーチンワークで回しているため、安く済みます。ただ前述と同様、その後のデータの扱いで困っている先生が多くみられます。

#データ解析＋コンサルティング
　失敗したくなくサンプリングから相談に乗ってほしい方、自分独自でやり方をカスタマイズしたい方に向けた「初心者の方から玄人の方まで」、経験を選ばないサービスです。ルーチンではなく一つ一つの案件に対して先生の意向を汲みながら解析を行うので、予算やアルゴリズムに応じた 柔軟な解析 が行えるのが特徴です。

　また前述のお蔵入りしているデータを、論文に使える図表にしてお渡しするというサルベージサービスも行っているところもあります。しかしカスタマイズ性が高いため、時間がかかることが多く、少々割高になる場合があります。

#最後に
　大方この三種類に分別され、弊社はデータ解析＋コンサルティングに分類されます。利点は何といっても柔軟に対応できるところです。

案件もすこし特殊で、例えば、

+ 論文に書いてある最新の情報で解析を行いたい
+ 無料配布のツールが使いにくいから、新たにもっと使いやすいソフトを作りたい
+ 他社の解析サービス項目にない解析を行いたい
+ このInputからこのOutputを吐き出すスクリプトを書いてほしい

などサービス内容は多岐にわたります。

最後に注意ですが、

　NGS関連予算を取得する際、シーケンサーでデータを出すところまでで見積もっておられて、解析にこんなにお金がかかるとは思ってなかったという方をたまにお見受けします。予算どりにはくれぐれもお気を付けください。
NGSを活用する際に考える必要のある事

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2941.html)から移行中です。
元記事：2018/10/12 公開 NGSを活用する際の注意点
</font>

NGSの解析を実際に行うには、実験計画と2次解析であるドライの計画をしっかり立てることが重要です。

#NGSを使う際の実験計画
　NGSはDNAがあれば塩基配列を読んでくれるのと、低価格化で気軽に使えるようになったため「とりあえず読んでみた」ということが可能です。ですが、実際に解析するには目的に沿った条件をそろえる必要があります。

+ 適したシーケンサー
+ 適した手法
+ 必要なサンプルセット

　得たデータをどのように使うか。例えば、データセットをどのように組み合わせたら何がわかるだろうかということをイメージする。シーケンサーの機種の特徴とアプリケーションはデータ解析のロジックにあっているか。データ解析まで予算の計画ができているか。といったことが必要です。弊社ではウェットからドライまで、ご相談いただけます。

#2次解析の計画
　コンピュータが「高速」で「自動」に結果を出してくれるものではありません。

###計算処理にかかる時間
　NGSで得られるデータは、普段コンピュータが処理しているよりもはるかに巨大なサイズのため、時間の消費があります。場合によってはニュースで見るような計算用コンピュータが使われることもあります。2次解析だけで、最低でも2-3カ月、長ければ半年以上となります。

###計算のフロー
　NGSデータ用に研究開発された計算ツールは多くあります。最初から最後まで自動化されたツールというものはなく、「この条件の時に使用する」といった目的をもって作られています。そのため、どのツールを使うか、実験目的に適した使い方になっているか、といった模索が必要です。多くは複数のツールを使うため、この処理の結果はどうだったか、といった段階ごとの結果の確認が必要です。ツールがない場合はプログラムを書くといった専門的な手法も考えられます。

　計算には生物学的な知識も入るため、生物学と情報科学の両方を理解できる人材がベストといえます。また、その人材が計算の試行錯誤を行う労力を払うこととなります。

#NGSを簡単に使う方法
　現在は、解析の一部または全部を委託するサービスがそろってます。ウェブを検索するとたくさんの提供機関が出てきます。

![NGS解析受託サービスの分類](https://www.pictbio.com/wp-content/uploads/tips/32b60070f69172cd82e61fad4648b899.jpg)

#予算について
　NGSの解析は多岐にわたるため、解析によって金額は大きく変わります。例えば、NGSで配列を読む際は、データ量、生物種、サンプル数、解析の種類等で変わります。以下のような情報があると委託がスムーズになります。

+ 解析する生物種
+ サンプル数
+ 想定の配列解析のアプリケーション
+ 想定の配列解析の方法
+ ゲノムや遺伝子データベースの存在の有無

　NGSは研究手段として一般的なものとなってまいりましたが、全てを自身で行うとまだまだ大変な部分も多くあります。ですが、計画さえ立てれば作業自体は相談できる先が多くございます。是非NGSを利用してみてください！
NGS解析の流れ

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2927.html)から移行中です。
元記事：2018/10/03 公開 NGS解析の仕組みとは
</font>

　NGSの解析は大きく分けて二段階あります。それは「ウェット」と呼ばれる試薬などを使った実験室での作業と「ドライ」と呼ばれるコンピューターの計算を使った作業です。前者はNGSを使用してDNA溶液から配列決定を行い、一次解析とよく言われます。後者はデータとなった大量の配列を処理し、二次解析とよく言われます。
#一次解析
　基本的にNGSは配列の決定のみを行います。DNAの断片が入った溶液からランダムに大量に配列を読み、データファイルが得られます。
#二次解析
　一次解析で得られるのは配列データのみである為、考察できるように計算を行います。非常に大量の配列が得られるため、コンピュータの計算にて実行します。

　図のように、INPUTのサンプルと二次解析を変更することにより、手法の多様性があります。
![NGS解析の流れ](https://www.pictbio.com/wp-content/uploads/tips/e92e27d1271bb8b7580f061ab0c68003.jpg)
#NGSを使用した研究例
>["MED12, the Mediator Complex Subunit 12 Gene, Is Mutated at High Frequency in Uterine Leiomyomas”　Netta Mäkinen et al.
](http://science.sciencemag.org/content/334/6053/252)

　正常とターゲットを比較することで、ターゲットに特異的な変異をリストアップしています。さらに、各人の特異的な変異を除くため、17人の患者で同様にリストアップを行い、17のリストから共通した変異を探しています。
![NGSを使用した研究例](https://www.pictbio.com/wp-content/uploads/tips/101eb84271959bfcc677ca9aad4950c7.jpg)
【Python】Altair でビッグデータを可視化する

# 概要

グラフ可視化ライブラリ [Altair](https://qiita.com/keisuke-ota/items/aa93f45b3a9fc520541d) は、pandas の DataFrame を入力することで様々なグラフを作成することができる。しかし、DataFrame の行数が 5000 を超えると次のようなエラーが起こる。

```
altair.utils.data.MaxRowsError: 
The number of rows in your dataset is greater than the maximum allowed (5000). 
For information on how to plot larger datasets in Altair, see the documentation
```

本稿では、関数型プログラミングライブラリ [toolz](https://toolz.readthedocs.io/en/latest/api.html) を用いて、入力可能な最大行数を変更する方法を紹介する。

# データの作成

[前稿](https://qiita.com/keisuke-ota/items/aa93f45b3a9fc520541d) と同様に、疑似乱数を用いて架空の学校で行われた期末試験の得点をテストデータとして用いる。この学校には学生が 10000 人在籍し、普通、特進、理数の 3 クラスが存在する。期末試験の科目は国語、数学、理科、社会、英語で各教科 100 点満点とする。

```python:データの作成
import numpy as np
import pandas as pd

np.random.seed(1) # 乱数の固定

df = pd.DataFrame()

n = 10000 # 学生の人数
s = np.random.normal(55,10,n) # 学生の学力
c = np.random.randint(0,3,n) # クラス
s = s * (1 + c * 0.015) # クラスの学力差をつける
g = np.random.randint(0,2,n) # 性別

s1 = np.random.uniform(0.75,1.1,n) * s * (1 + g * 0.02)
s2 = np.random.uniform(0.9,1.1,n) * s * (1 - g * 0.05)

sex = ['男','女']
cl = ['普通','理数','特進']

df['学生番号'] = list(map(lambda x: 'ID'+str(x).zfill(5), range(1,1+n)))
df['国語'] = list(map(lambda x: round(x), s1))
df['数学'] = list(map(lambda x: round(x), s2))
df['クラス'] = list(map(lambda x: cl[x], c))
df['性別'] = list(map(lambda x: sex[x], g))
print(df)
```

```df
  学生番号  国語  数学 クラス 性別
0     ID00001  63  80  特進  男
1     ID00002  44  48  理数  女
2     ID00003  48  43  普通  女
3     ID00004  46  40  特進  女
4     ID00005  55  63  普通  男
...       ...  ..  ..  .. ..
9995  ID09996  59  60  特進  男
9996  ID09997  53  59  普通  男
9997  ID09998  36  48  普通  男
9998  ID09999  58  54  特進  女
9999  ID10000  41  45  普通  男

[10000 rows x 5 columns]
```

# toolz を用いたエラーの回避

以下のように ``toolz`` の ``pipe`` で合成関数を作成する。関数内の ``max_rows`` で最大行数を指定すればよい。

```python:demo.py
import altair as alt
from altair_saver import save
from altair import limit_rows, to_values
import toolz
t = lambda data: toolz.curried.pipe(data, limit_rows(max_rows=10000), to_values)
alt.data_transformers.register('custom', t)
alt.data_transformers.enable('custom')

scatter = alt.Chart(df).mark_circle(
		size=30
		).encode(
		x=alt.X('国語',
			scale=alt.Scale(
				domain=[0,100]
				),
			axis=alt.Axis(
				labelFontSize=15, 
				ticks=True, 
				titleFontSize=18, 
				title='国語の得点')
			),
		y=alt.Y('数学',
			scale=alt.Scale(
				domain=[0, 100]
				),
			axis=alt.Axis(labelFontSize=15, 
				ticks=True, 
				titleFontSize=18, 
				title='数学の得点')
			),
		column=alt.Column('クラス',
			header=alt.Header(
				labelFontSize=15, 
				titleFontSize=18), 
			sort = alt.Sort(
				cl
				), 
			title='クラス'
			),
		color=alt.Color('性別', 
			scale=alt.Scale(
				domain=sex,
				range=['blue', 'red']
				),
			),
		tooltip=['国語', '数学'],
	).properties(
		width=300,
		height=300,
		title="国語と数学の得点分布"
	).interactive()

save(scatter,'scatter_10000.html',embed_options={'actions':True})
```

![visualization (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/f8bc7230-45e8-63e9-50f9-d82a0371ce51.png)