OmniAICreator/Qiita-1.07M huggingface dataset:
[py2rb] トップレベル変数

# はじめに
移植やってます。
# トップレベル変数 (Python)
```other.py
a = []

class A:
    def __init__(self, s=None) -> None:
        self.arr = list(s)

a.append([A('mon').arr, A('tue').arr])
```
```main.py
import other

print(other.a)

# [[['m', 'o', 'n'], ['t', 'u', 'e']]]
```
トップレベルにあるローカル変数って凄いですね。
しかし、ファイル名＋変数名なので、名前空間的には大丈夫そうではあります。
# ローカル変数 (Ruby)
```other.rb
a = []

class A
  attr_reader :arr
  def initialize(s=nil)
    @arr = s.split('')
  end
end

a << [A.new('mon').arr, A.new('tue').arr]
```
```main.rb
require_relative 'other'

puts "#{a}"

# undefined local variable or method `a'
```
ぐぬぬ。

https://www.shoeisha.co.jp/book/detail/9784798168845

独習Ruby - P378
> トップレベルで宣言されたローカル変数は、トップレベルだけで有効であり、（略）この点は、JavaScript、python など、ほかの言語に慣れていると、意外と混乱しやすい点でもあるので注意してください。

# インスタンス変数 (Ruby)
```other.rb
@a = []

class A
  attr_reader :arr
  def initialize(s=nil)
    @arr = s.split('')
  end
end

@a << [A.new('mon').arr, A.new('tue').arr]
```
```main.rb
require_relative 'other'

puts "#{@a}"

# [[["m", "o", "n"], ["t", "u", "e"]]]
```
アクセスコントロールできるかどうか知らないGold持ち。
# クラス変数 (Ruby)
```other.rb
@@a = []

class A
  attr_reader :arr
  def initialize(s=nil)
    @arr = s.split('')
  end
end

@@a << [A.new('mon').arr, A.new('tue').arr]
```
```main.rb
require_relative 'other'

puts "#{@@a}"

# warning: class variable access from toplevel
# [[["m", "o", "n"], ["t", "u", "e"]]]
```
`warning`を頂いてしまうし、`Ruby3`では`RuntimeError`になるらしい。

https://zenn.dev/jnchito/articles/24e0bd7fd1045d#%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E3%81%A7%E3%82%AF%E3%83%A9%E3%82%B9%E5%A4%89%E6%95%B0%E3%82%92%E8%AA%AD%E3%81%BF%E6%9B%B8%E3%81%8D%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8%E5%AE%9F%E8%A1%8C%E6%99%82%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F
# グローバル変数 (Ruby)
```other.rb
$a = []

class A
  attr_reader :arr
  def initialize(s=nil)
    @arr = s.split('')
  end
end

$a << [A.new('mon').arr, A.new('tue').arr]
```
```main.rb
require_relative 'other'

puts "#{$a}"

# [[["m", "o", "n"], ["t", "u", "e"]]]
```
staticおじさんに近いが。
# トップレベル定数 (Ruby)
```other.rb
AA = []

class A
  attr_reader :arr
  def initialize(s=nil)
    @arr = s.split('')
  end
end

AA << [A.new('mon').arr, A.new('tue').arr]
```
```main.rb
require_relative 'other'

puts "#{AA}"

# [[["m", "o", "n"], ["t", "u", "e"]]]
```
定数ですと、名前が被った時にアラートが出るので、ひとまずこれで行こう。
# メモ
+ Python の トップレベル変数 を学習した
+ 道のりは遠そう
Atomエディターの日本語化手順

Atomのダウンロードは[こちら](https://atom.io/)から:octopus:


①Atomを開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/e1d5fbcc-76cd-caaf-a081-9342bdf8aa05.png)

②[File]＞[Settings]を押下します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/cbae4631-cf06-f232-f66a-a2438e6c3a0f.png)

③Settingsタブが開かれます
④Settingsタブの「+Install」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/02349e77-35b0-ec36-792d-3b33a25778a4.png)

⑤入力欄に「Japanese-menu」と入力します
⑥[Install]を押下します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/b04d4d74-ebe4-aa72-d26c-0c0fd9eab369.png)

⑦日本語化ができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/16537871-6b2b-8955-6faa-84e5b670d02f.png)
Masked Autoencoderで視覚のAIが自然言語系の道を辿るのか

**Masked Autoencoders Are Scalable Vision Learners**
論文: https://arxiv.org/abs/2111.06377
Peng Zhiliangらによる実装: https://github.com/pengzhiliang/MAE-pytorch
# 要約
自然言語処理によく使われる「マスク予測タスク」という自己教師あり学習の手法を、視覚データに転用するマスク自動符号化器(Masked Autoencoder、MAE)という手法が何愷明(Kaiming He)らによって提案されました。

このごく簡単な手法はバニラのViT-Hで、公開時点での**追加学習データなしのImageNetのSotAとなった(+0.7%で87.8%)**。

BEiTという同じく「マスク予測タスク」を使う既存手法に比べて、MAEはそれ以上の精度を持つとともに、学習時間を大幅に削減できる。(16枚V100 32GBの5日 →  128コアTPUV3の15.4時間。エンコーダFLOPsから見ると3.3xくらいの加速)

簡単でスケール可能な手法こそが深層学習の定石なので、このような研究によって、視覚分野の深層学習もやがて(超大型モデルを使った)**自己教師あり学習が教師あり学習を超えて**、今後の主導的な手法となるのではないかと著者が示唆している。
# 手法と結果
既存手法としてのBEiTはBERTのように画像のパッチをトークン化して、マスクされてないパッチからマスクしたパッチのトークンを出力するように学習させている手法である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/5717ab50-1061-1901-9514-73766a7dc451.png)
これに比べてMAEには2つの主な改善点がある。
1. トークンではなく、エンコードした表現から**ピクセル**を復元させる(事前学習の前にトークナイザーをつくる必要がなくなる)
2. マスクしたパッチをエンコードしない(その分計算が減る)
![Screen Shot 2021-12-08 at 15.49.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/8ed53162-4579-3ea1-0bfe-6b5c62fe996f.png)
さらに、BEiTなどの既存手法は20%~50%のパッチをマスクするが、MAEではマスク率(Masking Ratio)を75%まで押し上げることができる。
![Screen Shot 2021-12-08 at 14.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/e9d3c8b8-c053-bf75-931d-31e1473d6ae3.png)
自己注意の複雑度が線形ではなく二次であるため、入力パッチ数を1/4にする(=75%のマスク率)ことによって**スピードが4倍以上**となること理論上に可能である。実際、デコーダーを小さくする実験に4.1倍のスピードアップを達成できた。
![Screen Shot 2021-12-08 at 15.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/96d2aa58-b850-5641-0e87-fd154a92d7b9.png)
転移学習の実験としてCOCOとADE20Kで、MAEは教師あり学習より**3~4%**を超える精度を出せたことで、学習した特徴が優れていることを証明できた。そして、より少ない事前学習のデータでBEiTと同じ水準の精度を達成できた。
![Screen Shot 2021-12-08 at 15.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/5bfcaf44-8118-6a9c-e039-f44ebe373c7f.png)
![Screen Shot 2021-12-08 at 15.59.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/3109f099-b98e-0c21-8791-6afabca5a251.png)
マスクされる画像の再構築の主観的評価として、MAEは近隣のピクセルからの単純な補間を行っているのではなく、全体を見た上で妥当な画像を生成していることが観測される(特にマスク率が85~95%の場合きのこの株の数が減ったり、ひとつの大きいきのこになったり、ピーマンが隠されたら2つのトマトになったりする、ある意味想像力を持った補完と個人的に思う)
![Screen Shot 2021-12-08 at 16.53.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/61bb0127-b5e5-372b-d017-78df4faff197.png)
この現象は選別されてない画像の再構築からも観測される(マスク率75%)。ここの例では値札がキッチン温度計みたいなものとなってある。
![Screen Shot 2021-12-08 at 16.59.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1718678/5ab63efd-ec43-d593-6980-c14c07d52df0.png)
# 今後の発展への期待
今回公開したImageNet精度はバニラのViTを使っているが、ViT自体も1年の歴史を持つ技術としてどんどん発展している。追加データなしのImageNet精度の元SotAも、構造がより先進的なネットワーク(VOLO)を使っているので、ネットワーク構造の更新でより良いパフォーマンスが出るのではないかと、著者が提示している。

また、学習時にランダムにパッチを取り除いて、ピクセルレベルの再構築を求めることだけで、複雑かつ全体像を持った("complex and holistic")画像の再構築を行えるモデルを学習できた結果に対して、著者はMAE内部の豊かの表現のおかげで、数々の視覚的概念を習得できていると仮説を立てている。これで論文の冒頭に述べた、「自然言語が人間の故意による信号という本質に比べて、視覚信号が高い空間的重複性(spatial redundancy)を持つ」問題の答えになっているのではないのでしょうか。
実機でflutter run ios時にSigningを設定しているのにエラーが出る

# エラー

```
Building a deployable iOS app requires a selected Development Team with a 
Provisioning Profile. Please ensure that a Development Team is selected by:
  1- Open the Flutter project's Xcode target with
       open ios/Runner.xcworkspace
  2- Select the 'Runner' project in the navigator then the 'Runner' target
     in the project settings
  3- Make sure a 'Development Team' is selected under Signing & Capabilities > Team. 
     You may need to:
         - Log in with your Apple ID in Xcode first
         - Ensure you have a valid unique Bundle ID
         - Register your device with your Apple Developer Account
         - Let Xcode automatically provision a profile for your app
  4- Build or run your project again

For more information, please visit:
  https://flutter.dev/docs/get-started/install/macos#deploy-to-ios-devices

Or run on an iOS simulator without code signing
```

# 解消法
runner.xcworkspaceを開き、TargetsのRunner -> Build SettingsからSigninigを手動でteamに設定する。
配列から最大値を見つけて値を出力する。


アウトプット用！！
1回目は
配列から最大値を見つけて値を出力する方法。

①はじめにこのような配列を作ります。

```java
int[] numbers = {36,23,19,199,382,2,5,18,30};
```

②配列内の要素を比較するために最初の配列[0]をMax変数に代入します。

```java
int Max = number[0];
```

③最大値を検索します。
　　　そこでfor文を使用してMax変数(配列[0])と他の配列[1]から配列[8]を順番に比較します。
　　　ここで注意してほしい所はループを回す時に配列[1]からはじめるので初期化式には、int i = 1が入ります。

```java
for(int i = 1; i < numbers.length; i++) {

   if(Max < numbers[i]) {　　//Max変数と他の配列の比較
    Max = numbers[i];   //もしnumbers[i]がMax変数より大きければ、numbers[i]がMax変数に代入   
 }
}

System.out.println("最大値は" + Max + "です。");
```

④if文を使用して配列[0]よりnumbers[1]が大きければ、Maxにnumbers[1]が代入される。
　　　　この場合36は23より大きいので、値はそのままで次のnumbers[2]と配列[0]の比較がはじまる。それを配列[8]ま　　　　 
  で繰り返す。
　　　　〜比較を繰り返す〜
  配列の中で1番大きい値は配列[4]の382なので、
　　　　Max = numbers[4]
　　　　
になり、

```java
System.out.println("最大値は"　+ 382 + "です。")
```

おまけ
実は最小値も同時に求めることができ、その場合はMax変数同様にはじめにint Min = numbers[0];
を指定してあげてfor文で初期値 = Min(numbers[0])とnumbers[1]〜[8]を比較してあげる。
もしMin変数がnumbers[i]より大きければnumbers[i]にMinが代入され、numbers[i]が最小値になって変数Minに代入される。

＊＊配列から最大値と最小値を同時に見つけて値を出力する。
＊＊参考程度に

```java
public static void main(String[] args) {
		int[] numbers = {36, 23, 19, 199, 382, 2, 5, 18, 30};
		
		int Max = numbers[0];
		int Min = numbers[0];
		
		for(int i = 1; i < numbers.length; i++) {
			if(Max < numbers[i]) {
				Max = numbers[i];
			} else if(Min > numbers[i]) {
				Min = numbers[i];
			}
		}
		System.out.println("配列内の最も大きい数値は" + Max + "です。");
		System.out.println("配列内の最も小さい数値は" + Min + "です。");
	}
```

＃SIer#java#プログラミング勉強中
エンジニアとしてキャリアをスタートした2021年【前編】

2022年、あけましておめでとうございます🎍
今年もよろしくお願いします。
2022年はアウトプットを習慣化・継続するのが目標です。
そこで昨年の振り返りを兼ねて私のエンジニアのキャリアについて話をしたいと思います。

***はじめに***
私は2021年の頭までタイピングは決して早くはなく、むしろ遅。
もちろん、プログラミングのプの字も知らない人間でした。
英語は海外留学に行っていたので自信はある方です。

そんな私が、2021年４月から本格的にプログラミングを始めて仕事を始めるまでの簡単の振り返りをしたいと思います。


***javascriptの基礎***
まず初めに、プログラミングとはなんぞやということで、ドットインストールやプロゲイトをやりました。
また、海外にプログラミング教材も色々やりました。

***学校に行きたいが結構高いな***
独学でもできるとネットの情報にはたくさん書いてありましたが、まず何をしたらいいのか、どれが基礎知識でどのぐらいの知識や経験があると仕事をできるレベルになるのかなど迷路の中で一人でいる気持ちだったので、学校に行くことに。
プログラミングの学校はよく知られている通り、安くはないんですね。プログラミングをまだほとんど知らないのに、いきなり大金を出せないと思っていた時に無料にプログラミングスクールを見つけ、参加することにしました。
しかし、無料にも理由があるなとつくづく感じ行くのを途中で辞めてしまいました。

***基礎を学べる学校にいく***
無料の学校に行くのを辞めてからもプログラミングをまだ学びたい気持ちがあったので、他の学校が探していたところ面接で受かった１人のみ無料（本来は20万円ほど）でコースを受けられるのをたまたま見つけ、面接に行ったところなんと合格をもらい4月からの１か月間のコースを受講させてもらいました。
これがプログラミングの世界に本格的に足を踏み入れるきっかけとなりました。
合格してなかったらどうなってたかな？と今、思えば考えるポイントでもあります。

***フルスタックになる３ヶ月***
基礎コースを終え、もっと本格的に学ぼうと思い基礎コースを受けた学校のフルスタックのコースを見ていましたが、またまた金額の壁にぶち当たりました。
知り合いがやっているシンガポールの学校が金額的にも、内容もよくそこに8月から入学しようと思い、勉強を進めていましたが学校側の事情により授業が受けられなくなってしまい、基礎コースを受けた同じ学校のフルスタックのコースを受けることに。

このコースに入るにはテストと事前課題があったので、この時点で勉強をスタートしました。
この時期にやっていたのが[watch and code](https://watchandcode.com/)です。プレミアムまで完了し、基礎のまた奥にある基礎を理解できる内容でした。
また、エンジニアとして大事なことも教えてくれるコースで大満足でした。

８月から10月31日までの３ヶ月間でフロントエンドからバックエンドまでフルスタックエンジニアとして必要な技術を学び11月に晴れて卒業しました。（寝不足と脳のキャパを超えました）


続きは後編へ。
「heroku run rails db:migrate:reset」時に発生したエラーを対処

# 状況

Heroku上のRailsアプリDB(PostgreSQL)を修正しようと`heroku run rails db:migrate:reset`を実行したところ下記のエラーが発生しました。

```irb
rails aborted!
ActiveRecord::ConnectionNotEstablished: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket

Caused by:
PG::ConnectionBad: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?
```

# 環境

+ macOS Big Sur 11.6.1
+ Rails 6.1.2
+ PostgreSQL 14.0



# 改善

エラー文の内容では、postgresqlのファイルまたはディレクトリが存在しないとのこと。
何らかの理由で消えてしまっているようなので下記のPostgreSQLのアドオンを実行。


```irb
$ heroku addons:create heroku-postgresql
```

再度、マイグレートを実行して解決出来ました。

```irb
$ heroku run rails db:migrate
```

# まとめ
デプロイ時にはcreate出来ており問題なく使えていました。
ローカル側のエラーを疑ってしまい解決まで時間を要してしましたが、Heroku上でも起こり得ることを学びました。
また、Heroku上のアプリページにあるConfigure Add-onsというページでもDBの確認が可能です。


# 参考
https://stackoverflow.com/questions/42653690/psql-could-not-connect-to-server-no-such-file-or-directory-5432-error

https://devcenter.heroku.com/ja/articles/heroku-postgresql
UnityでiOSリリースするときにエラー起きたらチェックすること

Unityでニフクラ、Admobつかってリリースするときによくエラーが出るので確認する項目＆参考になったサイト

Admob向け
https://qiita.com/nekojoker/items/231273c8422a88485b27

ニフクラ
https://blog.mbaas.nifcloud.com/entry/2020/06/23/100456

このへん、本当に自分で解決するの無理だと思うというエラーばかりなんですよね・・・
EC2でAmazon Chime SDKを動かしたときにKMSエラーで困った件

# この記事の概要
以下の記事を参考にAWS EC2上でAmazon Chime SDKを動かそうとしたら、AWS KMS関連のエラーが理解できず困ったが、最終的に「とりあえず」動くようになった話。
<a href="https://qiita.com/tmatsumura6290/items/d2e404a76a191743afa4">Amazon Chime SDKをEC2を使ってサクッと動かしてみる</a>


# 状況
* 知人から記事を参考にChime SDKをとりあえず動かそうとしたら、うまくいかないので助けてほしいと依頼された。
* 概要にある記事を参考にEC2（t2.small）上で、Amazon Chime SDKのdemos/serverlessを起動してみた。
* CloudFormation eventsを確認しつつ、不足したIAMポリシーをchimeTestUserに順次追加して解決済み。
* IAMポリシーの追加では、KMSのエラーが解決できなかった。
* 筆者のAWS関連技術は低い。
* EC2のログインユーザーは一般ユーザーで、本記事ではchimeTestUserと記述する。

# 課題
CloudFormation events from stack operationsで、以下のログが確認できた。つまり、AWS KMSの設定に関する不備がある。

```
Resource handler returned message: "The new key policy will not allow you to update the key policy in the future. 
(Service: Kms, Status Code: 400, Request ID: xxxxxxxx-xxxx-xxxx-xxx x-xxxxxxxxxxxx, Extended Request ID: null)" 
(RequestToken: xxxxxxxx-xxxx-xxxx-xxx x-xxxxxxxxxxxx, HandlerErrorCode: InvalidRequest)
```

# 参考情報
最初に参照した記事で質問したら以下のサイトが参考になるのではと紹介されました。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/update-key-policy-future/

実は質問以前に上記の記事を見ていたのだが、AWSの知識が乏しいのでイマイチ理解できず、有効に生かせなかった。

# 対策
demos/serverless/template.yaml を変更した。この方法が完璧とは思えないが、とりあえず動作させるという目的は果たせた。
EC2でdemos/serverlessを起動したユーザーにKMSの権限を全て与えたことになる（はず）。

```
ChimeKMSKey:
  Type: AWS::KMS::Key

        - Sid: Enable IAM User Permissions
          Effect: Allow
          Principal:
            AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
          Action: kms:*
          Resource: '*'
+        - Sid: Allow access for Key Administrators
+          Effect: Allow
+          Principal:
+            AWS: !Sub arn:aws:iam::${AWS::AccountId}:user/chimeTestUser
+          Action: kms:*
+          Resource: '*'
```

# あとから見つけた情報
KMSでは、いざという状況で完全な管理を行うrootとは別に、利用する際の管理者、利用者を分けるのが普通らしい。
今回の対策では、chimeTestUserに管理者、利用者を任せたことになる。「とりあえず」の動作なので問題ないが、実際にChimeを運用するのであれば、KMSの設定を見直す必要がある。

https://dev.classmethod.jp/articles/kms-admin-user/
mrubyの複数ファイルのコンパイル

mruby on YABMで複数ファイルのスクリプトをコンパイルできるようにしてみました。

SOC依存部分をサブルーチン化して別ファイルにしてみました。

bcmbm-mrubyでのサンプルです。

```ruby:samples/sub_4712.rb 
#
# yabm mruby script
# BCM4712 subroutine script
#

def gpioinit yabm
  yabm.gpiosetdat(1 << 3 | 1 << 4)
end

def ledon yabm
    yabm.gpiosetdat(1 << 3)
end

def ledoff yabm
  yabm.gpiosetdat(1 << 3 | 1 << 4)
end
```

```ruby:samples/thingspeak_main.rb 
#
# yabmbm-mruby mruby script
# need compile with subroutine file
#
#

APIKEY = "naisyo"

#
# main
#

begin

yabm = YABM.new

yabm.netstartdhcp

gpioinit yabm

# sync date by ntp use https X.509
ntpaddr = yabm.lookup("ntp.nict.jp")
yabm.sntp(ntpaddr)

#start = yabm.count()
#while yabm.count() < start + 3 * 1000 do
#end
#ntpaddr6 = yabm.lookup6("ntp.nict.jp")
#yabm.print ntpaddr6 + "\r\n"
#yabm.sntp(ntpaddr6)

count = 0
interval = 30

yabm.watchdogstart(300)

while 1 do
  count = count + 1
  ledon yabm
  yabm.print count.to_s
  res = SimpleHttp.new("https", "api.thingspeak.com", 443).request("GET", "/update?api_key=" + APIKEY + "&field1=" + count.to_s, {'User-Agent' => "test-agent"})
  ledoff yabm
  yabm.print "." + "\r\n"
  start = yabm.count()
  while yabm.count() < start + interval * 1000 do
  end
  yabm.watchdogreset
end

rescue => e
  yabm.print e.to_s
end
```

```
% make image RBSCRIPT="samples/sub_4712.rb samples/thingspeak_main.rb"
```

これでmain.trxにスクリプトのバイナリが入ります。

ファイル名の補完が使えないのでちょっと不便ですね。

admbm-mruby,ksbm-mrubyは同じようにできます。

蟹さんの場合は

```
% ./mkmrb.sh foo.rb bar.rb
```

するとhoge.imgができるので、これを焼きます。

サブルーチンは使用するコードより先にしないとダメみたいです。
準正常系試験ってなにをみるの？

## 勉強前イメージ

準ってなに・・・？

## 調査

### 準正常系試験 とは

設計・実装されたエラーが発生した際の動作を確認することになります。
例えば、郵便番号を入れるフォームに文字を入力すると「数字を入力してください」とエラー出るよね？
ってことを確認します。

### 準正常系試験と異常系試験の違い

なんとなくわかったけど、異常系との違いってなに？って思ったので確認します。

- 準正常系試験 : 想定内の異常処理が正常に動作してることを確認
- 異常系試験 : 想定外の異常が発生した際の動作を確認

基本的には想定内かどうかかな？

### まとめ

- 正常系試験 : 正しい入力に対して動作を確認する
- 準正常系試験 : 想定内の異常処理が正常に動作してることを確認
- 異常系試験 : 想定外の異常が発生した際の動作を確認

## 勉強後イメージ

準ってのがややこしいね。
異常系だけど、想定内だと準正常系になるのね。

## 参考

- [「正常系」・「準正常系」・「異常系」テストについて、まとめてみました。](https://gokushiteki-softtest.hatenablog.com/entry/2017/09/09/170828)
- [正常系テスト、準正常系テスト、異常系テストの違いまとめ](http://tooljp.com/windows/chigai/html/Test/NormalSystemTest-NearNormalSystemTest-AbnormalSystemTest-chigai.html)
[TypeScript]引数任意&&返り値の型固定な関数の型付けをしてみた

# 前書き

ButtonコンポーネントのPropsとして、クリック時に発火する関数を受け取りたい
その関数は返り値はvoid固定だが、引数は任意にしたい
その関数の型はどう書けばよいか、すぐに出てこなかったため、その備忘録。

# 使用

* TypeScript v4.5.4
* React v17.0.2

# 書き方

```typescript
type Props = {
  onClick: (...args: any[]) => void; // ← こちら
};
``` 

# 実装例

```typescript
type Props = {
  label: string;
  onClick: (...args: any[]) => void;
};

export const Button = ({ label, onClick }: Props) => {
  return (
    <button onClick={onClick}>
      {label}
    </button>
  );
};

// 例えば、一方は引数なし、もう一方はidを引数に取るような関数を受け取る時
// 各データに依存するボタンなどは後者だと便利

const CardWithNoArgsButton = () => {
  const handleButton = () => {
    console.log('引数なし');
  };
  
  return (
    <div>
      <Button label="ボタンA" onClick={handleButton} />
    </div>
  );
};

const CardWithIdButton = () => {
  const handleButton = (id: string) => {
    console.log(`引数あり ${id}`);
  };
  
  return (
    <div>
      <Button label="ボタンB" onClick={handleButton} />
    </div>
  );
};

``` 

# 参考

* https://stackoverflow.com/questions/29689966/how-to-define-type-for-a-function-callback-as-any-function-type-not-universal
アーカイバコマンドの代替としての StreamRelay.NET.exe のサポートプログラム

複数のファイルをまとめるようなアーカイバとなると、(ファイルごとにストリームとなるので)複数のストリームに対応する必要がある。
よって、StreamRelay.NET.exe とは相性が悪い。
StreamRelay.NET.exe 内部にまとめてしまってよかったのか知れないけど、サポートプログラムとして独立させることにした。

### ZipStreamNET.exe

StreamRelay.NET.exe と同じディレクトリに存在していると思う

`ZipStreamNET.exe`
でヘルプが出る

`ZipStreamNET.exe list "zipfile"`
で zip ファイル内部のエントリー(zipに格納されたファイル)の一覧が表示される

`ZipStreamNET.exe read "zipfile" "file1" > "file2"`
「zipfile」というzipファイル内部の「file1」というエントリー(ファイル名)の内容を読み出して、(シェルのリダイレクト機能で)「file2」というファイルとして保存する

例えば "file1" が「..\filename」のような通常の zip 展開ツールがエラーとなるような場合でも内容を確認できるよ。
(ZipStreamNET.exe はzipファイルに格納されたファイル名ではなくて、ただのエントリ名(文字列)として認識しているため)

`type "file3" | ZipStreamNET.exe write "zipfile" "file4"`
または
`ZipStreamNET.exe write "zipfile" "file4" < "file"`

とすると、ファイル「file3」の内容を「zipfile」というzipファイル内の「file4」というエントリで圧縮保存するよ。

### ZipStreamNET.exeの「-e」オプション

「-e」オプションで、エントリ名(いわゆる圧縮されたファイル名)の文字コードを明示することも可能。
(WindowsではShitf_JISで、MacではUTF-8で、文字化けした。といった場面で役立つと思う)

---
### 圧縮コマンドの代替としての StreamRelay.NET.exe

- [圧縮コマンドの代替としての StreamRelay.NET.exe](https://qiita.com/tomoki0sanaki/items/763bda379b32d968135d)

---
### リンク

- [アーカイバ内部のLog4jのバージョンを調べる](https://qiita.com/tomoki0sanaki/items/e3b435fa19c84d3735a0)

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
二箇所でsubmoduleのあるブランチを開発

二箇所でsubmoduleを使ったブランチを開発する手順です。

submoduleを使っているのでリカーシブでcloneします。

```
% git clone --recursive git@github.com:yamori813/rtlbm-mruby.git
```

サブモジュールを本家の最新にしてpushします。

```
% git submodule foreach git pull origin master
% git commit -m "update" mruby
% git push
```

別の所ですでにcloneしてあったものを同じにします。

```
% git submodule update
```

![submodule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d119ae28-7115-c1ac-3140-dce65a735785.png)


他も変更がある場合はpullします。
バックエンドに『FastAPI』、フロントエンドに『Vue.js』を用いて開発する際の『CORS』対策

バックエンドに『FastAPI』、フロントエンドに『Vue.js』を用いてWebアプリを開発する際、
それぞれローカルサーバーを立ち上げ、『Vue.js』から『FastAPI』にAPIをたたくと『CORS』エラーがでます。
これを回避するため、『FastAPI』のコードに下記を追記します。

```
from starlette.middleware.cors import CORSMiddleware

origins = ["http://localhost:8080"]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

『Vue.js』のローカルサーバーは、デフォルトで"http://localhost:8080"ですので、
これを開放します。
①PythonAnywhereの無料アカウントからメールを送る

(2022/7/30 追記）
Gmailのポリシー変更により、gmailのアカウントではメールを発信できなくなりました。
代わりにmailgunというサービスで対応できました（無料）。
https://www.mailgun.com

--------------

クラウド上のサーバーでPythonのコードを実行できるPythonAnywhereでスクレイピングして結果をメールで送ろうと思いますが、まずはメールを送るところまで紹介したいと思います。思ったより簡単にできました。

まず、PythonAnywhereで無料でアカウントを作ります。

それから使用するGmailでダミーアカウントを作ります。もちろん、普段使っているGmailアカウントを使ってもいいのですが、パスワードをコード中に記載することになるので、お勧めしません。
また、無料ユーザーはSMTPは使えないのですが、Gmailは特別に使えるようになっているそうです。
https://help.pythonanywhere.com/pages/SMTPForFreeUsers/

さっそくですが、コードです。
Gmailのアカウント名とパスワードは書き換えてください。

```python
import smtplib, ssl
from email.mime.text import MIMEText


# SMTP認証情報
account = "XXXXX@gmail.com" #書き換える
password = "ZZZZZ1234" #書き換える
 
# 送受信先
to_email = "YYYYY@gmail.com" #書き換えなくても大丈夫かも・・
from_email = "XXXXX@gmail.com" #書き換えなくても大丈夫かも・
 
# MIMEの作成
subject = "Test mail"
message = "テストメールですよ"
msg = MIMEText(message, "html")
msg["Subject"] = subject
msg["To"] = to_email
msg["From"] = from_email
 
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=ssl.create_default_context())
 
server.login(account, password)
server.send_message(msg)
server.quit()
```

これをメモ帳か何かで"sendmail.py"などとして保存して、次のようにファイルをuploadします。

![PAスクリーンショット 2022-01-04 103740.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/28fdfa34-8122-d868-960b-501ebbd248c1.png)

そして、bash consoleから実行するだけです。
python sendmail.py

![スクリーンショット 2022-01-04 104126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/09108d95-7de9-2459-e1a0-7869521f0feb.png)

----

参考にしたページなど：

初心者向け Pythonanywhereを使ってみよう
https://qiita.com/tonytani37/items/60c7185b7cc235f45daf

こちらでアカウントは作れるかと思います。


次は実際にスクレイピングしてそれをこのメール発信のしくみを作り、毎日決まった時間に届くところを紹介したいと思います！
ゲーム音楽をバグらせる

RTA in japanのドラクエ3みててBGMいいなあと思ったので作れんかなと思った

https://youtu.be/BO46AZ46Vp8?t=957

# バグらせる

なんかこの動画を見てたら一つの音階が丸ごとずれてるっぽいなと思ったのでそれをやる

https://www.nicovideo.jp/watch/sm18803120

```python:

import mido
midi = mido.MidiFile("original.mid")

import random

# いじりどころ
bugtone={}
for i in range(20):
    bugtone[random.randint(10, 80)] = random.randint(1, 4)

for track in midi.tracks:
    for msg in track:
        if hasattr(msg, 'note'):
            if msg.note in bugtone:
                msg.note = msg.note - bugtone[msg.note]

midi.save("bug.mid")

```

ランダムで適当な音階を選んで適当に音下げてる

# 聞いてみた

https://soundcloud.com/bjack_mijilme/aqvbuhbjjjah

バグってる

音源はYMCKが出してるやつ使った

# おしまい
おしまい
【Ruby 】 ターミナルから数値出力　gets.to_iで数値変換

※初心者向け
※アウトプット練習の為

開発環境
rails 6.1.4.1
ruby 2.6.5

#問題内容
ターミナルから数字を入力して、数字に応じて以下のように出力するプログラムを書いてください。
・0以下の数値なら0以下の数字です
・10以上の数値なら10以上の数字です
・1以上9以下の数値なら0より大きく10より小さい数字です

**雛形**

```csharp
input = gets.to_i

#ここからソースコード記述。

```


#解答

```
input = gets.to._i

if number <= 0
 puts "0以下の数字です"
elsif input >= 10
 puts "10以上の数字です"
else
 puts "0より大きく10より小さい数字です"
end
```

#解説

**①ターミナルから数値を入力する書き方**
**②条件分岐の書き方**
の2つに分けて解説します。


#**①ターミナルから数値を入力する書き方**
ターミナルから数値を入力するにはgetsというメソッドを使います。このgetsメソッドを使って入力した値は全て文字列になります。そのためターミナルでは数字を入力しても、プログラムで使うときには文字列に変換されてしまいます。

そこでgetsの値をto_iメソッドを使って数値に変換します。

```
 input = gets.to_i
```

#**②条件分岐の書き方**
条件分岐はif文を使います。今回は3つのパターンで条件を分けるため、elsifとelseも使います。

```
if 条件1
  # 条件1のときの処理
elsif 条件2
  # 条件2のときの処理
else
  # 条件3のときの処理
end
```

今回の条件は数値の比較です。比較には<や==などの比較演算子を使います。
今回は10以上や0以下という比較なので、<=または>=を使います。=を付けた場合は以下や以上という意味になります。
『Docker』で『OpenCV』を扱う際に出るエラーの対処法

【エラー内容】
```ImportError: libGL.so.1: cannot open shared object file: No such file or directory```
【対処法】
『libgl1-mesa-dev』をインストール

【エラー内容】
```ImportError: libgthread-2.0.so.0: cannot open shared object file: No such file or directory```
【対処法】
『libglib2.0-0』をインストール
Railsで条件に一致する要素の個数を数え上げる時のコードのリファクタ例

railsで作られているアプリで、countを使用する機会があったので、具体例として書きました。
countを知らない人はググってみてください。

```ruby
 class User
   has_many :qualifications # 資格証
 end

 class Qualification
   has_one_attached :image # 画像
 end
```
例えばこんなクラスがあったとして、あるuserが持っているqualificationsのうち、
imageが添付されているものの個数を数えたい場合を考えます。

私はまず以下のように書きました。

```ruby
  attached_count = 0 # 添付されているものの個数を入れる変数
  user.qualifications.each do |qualification|
    attached_count += 1 if qualification.image.attached?
  end
```
このコードでも、あるuserの、imageが添付されているqualificationの個数を数えることができます。

しかし、countを使えば一行で済みます。

```ruby
  user.qualifications.count { |qualification| qualification.image.attached? }
```
気持ちいい！！！
【超重要!!】Djangoでモデルのマイグレートを元に戻す方法

# 目的
Djangoのmodels.pyでモデルを作成し、マイグレーションを行ったものの間違いを見つけて修正したい。しかし一箇所を直すためにmigrationファイルを作成するのもあとで保守がしづらくなると考え、前回(もしくはそれ以前)のバージョンに戻して情報を編集したい。

# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| python  | 3.8.12 |
| anaconda  | 4.10.1 |
| django  | 21.2.4 |
| pip  | 3.1.2 |

# 概要


1. ```python manage.py showmigration```でこれまでのmigrationの履歴を確認する
1. ```python manage.py migrate app_name migration_version_name```migrationのバージョンを指定して戻る
1. 最新のマイグレーションファイル(/migrations/配下の番号が一番古いもの)を直接削除

# 詳細
### これまでのmigrationの履歴を確認する

```
$ python manage.py showmigrations
tinder
 [X] 0001_initial
 [X] 0002_auto_20211219_1625
 [X] 0003_auto_20211223_1038
 [X] 0004_hotguys
```
ここからtinderというデータベースには4つのマイグレーションファイルが存在し、Xが左についている全てのマイグレーションが現在のアプリに反映されていることがわかる。

今回は一個前のマイグレーションに戻したいため、0003_auto_20211223_1038まで戻ることとする。

### migrationのバージョンを指定して戻る
```python manage.py migrate アプリ名 マイグレーション名```で戻る

```
$ python manage.py migrate tinder 0003_auto_20211223_1038
Operations to perform:
  Target specific migration: 0003_auto_20211223_1038, from tinder
Running migrations:
  Rendering model states... DONE
  Unapplying tinder.0004_hotguys... OK
```
完了しているため、もう一度マイグレーションの反映状況を確認。

```
$ python manage.py showmigrations
tinder
 [X] 0001_initial
 [X] 0002_auto_20211219_1625
 [X] 0003_auto_20211223_1038
 [ ] 0004_hotguys
```
0004_hotguysの左には[X]がないため、反映されていないことがわかる

### 最新のマイグレーションファイルを直接削除
/migration/配下の0004_hotguysファイルを右クリックで削除する
お決まりの確認だ。

```
$ python manage.py showmigrations
tinder
 [X] 0001_initial
 [X] 0002_auto_20211219_1625
 [X] 0003_auto_20211223_1038
```
反映され、消えている!!!

# 参考文献
[Djangoのマイグレーションをロールバック、元に戻す方法](https://hodalog.com/how-to-revert-migrations/)
AprilTag 距離テスト用シートを作ってみた

AIカメラモジュールでARマーカーを使って色々検知しようと思ってます

モジュールごとに写り方が変わるのでARマーカーがどれくらいのサイズにしたらいいか
決めるためのAprilTagチェック用シートをPowerPointで作ってみました。
![aprilTag サイズテストシート.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/80b2ff1b-4a61-337b-7628-94cb7790ef4f.jpeg)

iPhoneアプリで検知するとこのようになります。

![IMG_2625.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/542dd7fd-3565-aeb3-a66e-2dd669ad62de.jpeg)
![IMG_2626.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/10472e86-07ad-f4a9-e9d8-f4c7dbafabe7.jpeg)

サイズはタグIDセンチで作ってます
例）タグＩＤ＝１０の場合１０ｃｍ

印刷などするとサイズは変わりますし
PowerPointで制作したので精度はそこそこです。

必要な方はＰＤＦ版を [こちら](http://lirevo.com/aipic/AprilTag/aprilTag_sizetest.pdf) からダウンロードできます。

##AIカメラモジュール
[HUSKYLENS]
(https://amzn.to/3qIjHi9)
![](https://d2air1d4eqhwg2.cloudfront.net/images/6248/500x500/91c856df-5710-4edb-8dfc-1ab9daf95220.jpg)
[UnitV AI Camera]
(https://amzn.to/3nf2fBd)
![](https://d2air1d4eqhwg2.cloudfront.net/images/6212/500x500/38515113-cded-4e1a-8eb8-3ba5bf7a737b.png)
アニメからスケッチを抽出　あのアニメもAnime2Sketchでかんたんに

#画像をドロップするだけでアニメ画像をスケッチに変える機械学習モデルがかんたんにつかえる
<img src=https://user-images.githubusercontent.com/23278992/147995515-01ecf1b7-4f26-4086-b08f-feab52f0e4b3.jpeg width=500>
<img src=https://user-images.githubusercontent.com/23278992/147995541-2da34bdb-a04a-4681-8c44-d275da47fd02.jpeg width=500>

#アニメをきれいに線画にしたい
アニメから線だけ抽出できれば、ぬりえや２次創作などいろんなことに使える。

#線だけ抽出することはできるのか？
ただモノクロにするだけではこうなる。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6fb5c6c9-445a-aaed-da6e-baca892a8b81.jpeg width=500>

塗りつぶしはなくして線だけ抽出することはできるのか？

#OpenCVでもできる。。。?
OpenCVでもスケッチ効果を作ることはできる。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ee8718c1-6e40-db02-a211-3d6db0c6c83d.jpeg width=500>
これはこれで素敵だが、まだ塗りつぶしが残っている。

もっと線だけ抽出できるだろうか？

#Anime2Sketchで解決

Anime2Sketchという機械学習モデルを使えば、かんたんに線画にできる。

https://github.com/Mukosame/Anime2Sketch

さらに、CoreMLというiOS対応のモバイル形式にすれば、ドラッグ&ドロップで使え、アプリにも組み込める。
[CoreML-Models](https://github.com/john-rocky/CoreML-Models)からモデルファイルをダウンロードして、画像をドロップするだけ。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/47bfddd7-7ed6-d138-74b1-d9a8d2513c73.png width=500>
このように、かんたんにきれいに線画だけが抽出できる。

https://github.com/john-rocky/CoreML-Models

アプリに組み込むには、Visionリクエストをすれば良い。

```swift
do {
    let mlModel = try anime2sketch(configuration: MLModelConfiguration()).model
    let model = try VNCoreMLModel(for: mlModel)
    let request = VNCoreMLRequest(model: model)
    let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
    try handler.perform([self.sketchRequest])
    guard let result = self.sketchRequest.results?.first as? VNPixelBufferObservation else { return }
} catch let error {
    print(error)
}
```

#いろいろあそべる
自動着色でぬりえ。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6970b9cb-f099-1bf9-35a9-79a87fcfcdff.jpeg width=500>
https://petalica-paint.pixiv.dev/index_ja.html

動画にも適用できる。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/fd5c11b3-1137-87fd-72c9-999ee8c6b3ba.gif width=500>



線画にしてみることで、クリエイターのすごさがわかり、いろんなサービスや創作に展開できればいいな。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
README.md の書き方の例

情報処理学会論文誌 「フレッシュマンへ向けて」より引用 ← 具体的な情報はあとで追記。

# README.md
- 機能概要
- 使用方法
- 動作環境
- 動作環境の構築方法
- インストール方法
- テスト方法

# 感想
- 毎回、気分で書くことが変わっていたため、必須の条項があると楽。
- 実際に書いてみると、順番がおかしいような気もする。改善の余地あり。
Django個人メモ 

# Django個人メモ
初めての投稿です、至らないところもあるかと思いますが復習と整理も踏まえて書きます。

## Djangoに入る前に“フレームワーク“自体の理解
https://www.sejuku.net/blog/27387

## MTVモデル
 概要
　・Model（データベースに格納されているデータ）← DB, Table関連
　・Template（テンプレートファイルによって定義されたそれぞれのページのデザイン）← HTML, CSS, Javascript関連
　・View（どのページを表示させるかを決定する処理）← コアとなる関数

## データ構造反映
http://farewell-work.hatenablog.com/entry/2017/05/07/160813

```
$python manage.py showmigrations （確認）
$python manage.py makemigrations （migrationsファイル作成）
$python manage.py showmigrations（確認）
$python manage.py migrate （反映）
$python manage.py runserver ….でシステムが動くはず
```
## MySQL,SQL
https://qiita.com/knife0125/items/bb095a85d1a5d3c8f706
最低限のSQL

## Django逆引き
https://qiita.com/uenosy/items/54136aff0f6373957d22

## Template inheritance
https://docs.djangoproject.com/en/3.0/ref/templates/language/#template-inheritance

extends – Django Template Tags
https://www.geeksforgeeks.org/extends-django-template-tags/

## Djangoでの開発　ダイジェスト
https://qiita.com/zaburo/items/0e15f6c150caa13ca34c

## 中国語資料、個人的に結構まとまってる
Django(框架)
https://www.zhihu.com/topic/19572108/hot
Python Django+SQL+Pandas+Pyecharts自建在线数据分析平台（三）
https://zhuanlan.zhihu.com/p/143369908
Django 教程
https://www.runoob.com/django/django-tutorial.html

## 日本語化
https://narito.ninja/blog/detail/86/

## Django フォーム + Bootstrap 4 で、本格的な「お問い合わせ」フォームを手軽に作成する
https://medium.com/@kjmczk/django-contact-form-5a35d43b00a6

## Djangoの多対多
https://qiita.com/aqmr-kino/items/5875c388d5fc405ee606

## 番外編MySQL Problem
```
$sudo apt-get install python3.6-dev libmysqlclient-dev
$sudo apt-get install libsqlclient-dev
$sudo apt-get install -y libmysqlclient-dev
$sudo apt-get install -y default-libmysqlclient-dev
$pip install mysqlclient
$pip install mysql-python
$pip install mysql-connector-python
```
【GCP】App EngineとCloud Runの違い



App EngineとCloud RunってどちらもGCPのサーバーレスサービスだけど、何が違うのかよくわかっていなかったので調べてみた。

## 技術的な違い
GCPが管理してくれる範囲、マネージドな範囲が違う。

- App Engine: PaaS
- Cloud Run: CaaS(Container as a Service)寄り

下の図でグレー四角で囲われた部分が各サービスでユーザーがカスタマイズする部分。
言い換えるとそれ以外はGCPにマネージドされている部分。

![スクリーンショット 2022-01-04 8.30.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495868/0a5d2df6-f3f7-f5af-4d38-cb99e5a12008.png)
[参照](https://speakerdeck.com/glaforge/serverless-micronaut-on-google-cloud-platform?slide=6)

つまり、App Engineのほうが寄り多くの部分がマネージドされている。
Cloud Runを「CaaS寄り」としているのは、CaaSはコンテナ管理機能までを提供しているサービスのことで、GCPではKubernetes Engineがこれに該当し、Cloud Runは厳密にはCaaSではないから。

Cloud RunはKubernetes EngineとApp Engineの中間（どちらかというとKubernetes Engine寄り？）で、コンテナを作成、指定すれば勝手にアプリケーションがデプロイされるサービス。

この違いによりApp EngineではGCPが用意しているランタイム環境(python Node javaなど)のみに限られるが、Cloud Runでは任意にランタイム環境でコンテナを作ってデプロイすることができる。


## 料金的な違い

###App Engine
インスタンスの従量課金制。時間あたりの料金インスタンスクラスのごとに異なる。
最後のリクエストが終了してから15分後にインスタンスは終了する。
![スクリーンショット 2022-01-04 9.03.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495868/81184fab-d6df-baeb-cd6f-8e91c62c2136.png)
[参照](https://cloud.google.com/appengine/docs/standard?hl=ja#instance_classes)

###Cloud Run
リソースごとの従量課金制。つまりCPU、メモリなどのリソースごとに課金される。
100ms単位で切り上げられたリソースの使用時間が課金対象。
![スクリーンショット 2022-01-04 9.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495868/d8f0d235-b336-4ee9-b5e0-5f32dcb97e37.png)
[参照](https://cloud.google.com/run/pricing)


App Engineのインスタンスが最終リクエスト終了から15分後に終了するのに対し、Cloud Runは100ms単位の課金なので、常時アクセスがあるわけではないアプリケーションならば、Cloud Runのほうが良さそう？🤔


## 余談
App EngineもCloud Runのどちらもサーバーレスなサービスに分類される。
サーバーレスに明確な定義はない（と思っている）が、一般に以下のようなサービスのことを言う。

- サーバーの管理が不要
- 自動スケーリング
- 従量課金制

本当にサーバーが無いのではなく、アプリケーションが動いている物理的なサーバーは存在する。
ただ、サービスを使うユーザーからはサーバーが抽象化され、サーバーの状態を気にしなくて良く、管理が不要（レス）なサービスのこと。
エッジAI端末を使ってみた 〜物体検知編〜

## 概要
* データの発生源に近い場所でデータを処理する「エッジAIコンピューティング」が注目されている
* まず、エッジAIのおおまかな概念を理解し、実際にエッジAI端末を購入して使ってみる
* 今回はYOLOというアルゴリズムを利用して物体検知のデモの動作を確認する

## エッジAIとは何か
* 通常AI利用する場合は、センサーから収集された各種データはマイコンボードやスマホ、ネットワークを経由し  
、クラウド上や従来型のサーバーで解析処理を行う
* エッジAIを利用すると、センサーから収集された各種データはマイコンボードやスマホ内で解析される

![スクリーンショット 2021-11-05 9.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/c860f214-fb02-3180-c4a4-554e91e7371a.png)

物体検知のデモが動作している様子
![IMG_0569.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/aa5bd646-deb7-3aab-63c9-9e2f426fc6d6.jpeg)

![IMG_0572.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/ea201a8b-1e9f-5b87-97a0-edb44100b8b7.jpeg)

![IMG_0571.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/31dc8642-807a-899d-23b1-3b3e3fa5a044.jpeg)

## 用意するもの
* Jetson Nano開発者キット 2GB
* RaspberryPi4 対応 電源セット(5V 3.0A)　←Jetson Nanoにも使えます
* USBカメラ
* microSDカード(32GB以上推奨)
* USB接続のマウス・キーボード
* HDMI接続のディスプレイ(4K推奨)

## インストール  
今回は、こちらのリポジトリの内容を利用させて頂いた
https://github.com/tsutof/tiny_yolov2_onnx_cam

パッケージ一覧を更新、必要なライブラリをインストール　　

```
# sudo apt update
# sudo apt install python3-pip protobuf-compiler libprotoc-dev libjpeg-dev cmake
```

Pythonの拡張モジュールcysonをインストール

```
# pip3 install --user cython 
```

gitからリポジトリごとcloneし、環境変数を設定、pipコマンドでインストール

```
# git clone https://github.com/tsutof/tiny_yolov2_onnx_cam
# cd tiny_yolov2_onnx_cam
# export PATH=$PATH:/usr/local/cuda/bin
# python3 -m pip install -r requirements.txt
```

## アプリケーション実行  

Jetson nanoを最大クロック数で動作させるよう次のコマンドを実行

```
# sudo nvpmodel -m 0
# sudo jetson_clocks
```

物体検出プログラム実行（USBカメラ使用の場合は--cameraオプションで0を指定）
初回の起動時には、解析エンジンの作成処理が入るため、1分ほどの時間がかかる  

```
# python3 tiny_yolov2_onnx_cam.py --csi --camera 0
```

一眼レフで撮影した写真をモニターに映し検出
※初回起動時、解析エンジン構築途中でカメラ映像が出ない不具合が発生したが、２回目以降は動作良好
（電力不足、メモリ不足のエラーが出ていたことを確認）

![photo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/3de753ce-94f3-c5b3-855d-0572927c00ce.jpeg)

![IMG_0566.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/1882db6f-90c7-0cc6-9634-37385b526ed6.jpeg)

![IMG_0563.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/180458b2-f8ee-56cd-4e77-c571a68e8961.jpeg)

![IMG_0562.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/2d3994f7-7abd-e6ea-8598-22d135bf4797.jpeg)

![IMG_0559.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/f5bd10d3-e3bf-4f1c-64f4-d8941679cb45.jpeg)

動物によっては誤検知もあり

![名称未設定-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/8f58e496-f24c-6b7c-c907-0ea49c97ea16.gif)

AIで生成された著作権フリーの顔を検出

![IMG_0567-1 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/f026f47c-99e0-4a35-29ab-f4d948979b60.gif)

## 次回に向けて
* JetsonNanoの電力が足りないとのエラーが表示されていたので、電力周りを見直す
* 動画でも検知できるのかを試してみる
【Ruby】変数について

## 変数とは？
変数とは、値を入れる箱のようなものです。この箱には名前をつけることができ、どんな値が入っているのかを簡単に識別できるようになります。この名前を変数名と言います。変数を利用することで、値を再利用したい場合に、変数の名前を使うだけで呼び出すことができます。

## 宣言と定義

例） number = 3

【number】　宣言→変数名をつけて変数を作ること。
【３】　　　  定義→変数にどのような値を格納するのか記述すること。

###変数の命名規則

|命名規則           |説明|
|:----------------:|:--|
|変数の中身が何かわかる|どんな名前もつけられますが、aaaのような意味のない名前は避けましょう。|
|小文字で始める|大文字からも開始できますが、とくに理由がない場合は避けましょう。|
|_(アンダーバー)で始めない|_からも開始できますが、とくに理由がない場合は避けましょう。2文字目以降には使えます。|
|数字で始めない|1文字目に使うとエラーが生じます。2文字目以降には使えます。|
|日本語を使わない|文字列以外では日本語は使えないため、変数名も日本語は使えません。|
|スペースを含めない|名前にスペースが入るとエラーが生じます。|
|予約語を使用しない|Rubyには文法などで使うことがあらかじめ決まっている単語があり、それを予約語と呼びます。これらを使うとエラーが生じます。|
Databricksのダッシュボード

[Dashboards \| Databricks on AWS](https://docs.databricks.com/notebooks/dashboards.html) [2020/7/14時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

ダッシュボードを用いることで、ノートブックの出力結果のグラフやビジュアライゼーションを組織内で公開し、プレゼンテーション形式で共有することができます。ダッシュボードを作成し、まとめ上げる方法に関しては以下のノートブックを参照ください。以降では、ダッシュボードを更新するためのジョブをスケジューリングする方法や、特定のバージョンのダッシュボードを参照する方法を説明します。

# ダッシュボードノートブック

https://github.com/taka-yayoi/public_repo/tree/main/notebook_dashboard

> **注意**
[htmlファイル](https://raw.githubusercontent.com/taka-yayoi/public_repo/main/notebook_dashboard/Databricks%E3%81%AE%E3%82%BF%E3%82%99%E3%83%83%E3%82%B7%E3%83%A5%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99.html)をインポートすることで、保持されているダッシュボード、グラフの設定も読み込むことができます。pyファイルではダッシュボード、グラフの設定は保持されていません。

# ダッシュボードを更新するためのジョブをスケジューリングする

ダッシュボードビューからダッシュボードを表示した際、ライブで内容は更新されません。特定の周期でダッシュボードを更新するようにスケジュール処理を行うには、ダッシュボードのグラフを出力する[ノートブックの処理をスケジューリング](https://qiita.com/taka_yayoi/items/c306161906d6d34e8bd5#%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF%E3%81%AE%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E5%87%A6%E7%90%86)します。

# 特定バージョンのダッシュボードを参照する

1. ![](https://docs.databricks.com/_images/schedule.png)ボタンをクリックします。
1. ノートブックジョブの**Last successful run**のリンクをクリックし、参照したい時点の処理結果を参照します。<br>
    ![](https://docs.databricks.com/_images/dashboard-run.png)



### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
リセットCSS

##リセットcssとは？
各ブラウザにデフォルトで設定されているCSSを打ち消す役割をもったCSSです。

###そもそも何故打ち消す必要があるのか？
各ブラウザは固有のCSSがデフォルトで指定されています。このデフォルトのCSSの影響で、自分で書いたCSSが本来意図しない表示になることがあります。よって、ブラウザがデフォルトで持っているCSSを打ち消すために、リセットCSSというCSSを使用します。



**_打ち消す為に記述_**

```qiita.rb
/* リセットCSS */
body {
  font-size: 14px;
  color: #333;
  margin: 0 auto;
}
h1,h2,h3,h4,h5,h6,p {
  padding: 10px 0;
  margin: 0;
}

ul,li {
  padding: 0;
  margin: 0;
}

```
フォーム実装について

##form要素
form要素とは、フォーム関連要素の集まりを表すブロック要素です。この```<form>...</form>```のなかに、入力フォームや送信フォームを作成します。

##input要素
フォームの入力欄や実行ボタンなどを作成することができるインライン要素です。
input要素にはtype属性という設定があり、それを指定することによって様々な種類のフォーム部品を作り出すことができます。

| type属性  | 用途 |
|:--------:|:-----|
| text     |1行入力できる欄を作成できます。|
|checkbox  |チェックボックスを複数作成できます。|
|radio     |複数の選択欄から一つだけ選択できるラジオボタンを作成できます。|
|submit    |送信ボタンを作成できます。|

###placeholder属性

入力フォームに仮の文字列を入力できます。
例文や入力ガイドの役割があります。

```qiita.rb
< input type = "text"  placeholder = "タイトル"  class = "クラス名" >
```

##textarea属性
複数行を入力できるインライン要素です。
textareaは終了タグが必要となるのが注意⚠️

```qiita.rb
< textarea name = "message"  placeholder = "メッセージ入力"  class = "クラス名" ></textarea>
```

##送信ボタンの実装
###value属性
フォームの送信をした時に、どのような値を送信するのかを決めることができます。**_送信ボタンに限っては、_**value属性で指定した文字が、送信ボタンに表示されます。

```qiita.rb
< input type = "submit" value = "送信" class = "クラス名" >
```
_________________________________________
####ちなみに、、、
インライン要素は、横に並んで表示されます。
そこで、CSSにdisplay:block;を使用するとインライン要素をブロックレベル要素に変換でき、縦に並べる事ができます。
TypeScript: Array.isArrayを読み取り専用配列(readonly)に対応させる方法

この投稿では、TypeScriptのビルトイン型定義の`Array.isArray`を読み取り専用配列(readonly array)に対応する方法を紹介します。

## `Array.isArray`の問題点

TypeScriptの`Array.isArray`メソッドの型宣言は次のようになっています。

```ts
interface ArrayConstructor {
    /* 中略 */
    isArray(arg: any): arg is any[];
    /* 中略 */
}
// from: https://github.com/microsoft/TypeScript/blob/9a75d2acc8f7175d1ada327a0e457f7ea1ea1c46/src/lib/es5.d.ts#L1440
```

このメソッドは[型ガード関数](https://typescriptbook.jp/reference/functions/type-guard-functions)で、戻り値はtype predicateになっています。これにより、if文などで`Array.isAarray`を使った場合、変数が配列型に絞り込みがなされます。

[![Array.isArrayによりnumber[] | undefinedが絞り込まれる例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/ff238402-4d5f-718f-33ff-3f9ead7e60ce.png)](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3gNyhAriAFzwr4C2ARiDANoC68APvPiqAGYCWKIwA3ACguHeAAoAgjBhQAngDouaKTNljcBEAEot8AN6D4OPISFGA9OfgA9APyCAvoMFA)

ところが、読み取り専用配列に対して、`Array.isArray`を使って型の絞り込みを行うと、`any[]`型になってしまいます。

[![Array.isArrayによりreadonly number[] | undefinedがany[]になる例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/b9646e9b-0c21-6e8c-408b-a186d6e867ad.png)](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3gNyhAriAFzxxTCoQCe8K+AtgEYgwDaAuvAD7z4qgAzAJYoQwANwAoIQPgAKAIIwYUKgDohaJSqpzcBEAEpD8AN6T4OPISmWA9HfgA9APySAvpMlA)

読み取り専用配列に対応してほしいという声はあるようで、issueに上がっていますが解決されていません。

https://github.com/microsoft/TypeScript/issues/17002

## `Array.isArray`を読み取り専用配列に対応する方法

この問題を解決するには、`isArray`の型定義を上書きします。型の上書きには、宣言マージ(declaration merging)を応用します。具体的には、次の`ArrayConstructor`インターフェースを定義します。

```ts
declare global {
  interface ArrayConstructor {
    isArray(arg: readonly any[] | any): arg is readonly any[];
  }
}
```

これを書いておくと、読み取り専用配列に対しても型の絞り込みがうまくいくようになります。

[![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/a37a10a6-9463-5da0-a82f-89066a5558f1.png)](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3gNyhAriAFzxxTCoQCe8K+AtgEYgwDaAuvAD7z4qgAzAJYoQwANwAoIQPgAKAIIwYUKgDohaJSqpzcBEAEpD8AN6T4OPISmWA9HfgA9APySAvpMmhIsBAHMIJEY8Mwt4EQwWASgwBG1VAGFUTBh8MAwkGDDLS00E3Vh-EjIKFGp4KBQqDm5K6sMSIoi0UhByShoqmvZbeE9PEAAPAAcsrAwqEYQADXgAXngARnF4B3hAZQZAOwZAToZAeoZAK4ZAdYZACYZAJIZAI4ZADoZAU4ZAH4ZAa4ZANGVATQZAaIZAfQZAQIZAawZAD7NACIMgDMGAFvSRAA)

ちなみに、読み取り専用タプル(readonly tuple)に対してもちゃんと効くようになります。

[![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/d9bc400e-102a-384f-88d1-17e43e415211.png)](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3lFBPAalBAK4gBc2eA3AFACWAZvABQCCMMUuAdHWu51zMcBIqQCU4yqJIhaAennxlK1WvXqAegH4aNUJFgJk6LCmIBbAEYgYArhXPXbAbQC6tRi3s8+P5k42dhxckvCBtj4KShqxcWo6egbQcIiomPBwUMCoELgAcpZBPhRZOSh54UWuHvRMbCG+-I3MZbkF1cGCYW0VHc5dXNHxI6MJuvrgKcbpWBjEAA4Q5PAuETC1Xg2CvM2CzPNLIGGHy8Nj8YmThqkmGb15ACqLy6Ug2e2r65v1Prv+D1wzyOPXe5SeLzkNEUF1hKiuySMaVMVQGAHkYIUBiVUUF4AAfTJgz7rdyeeoAQj+fha6wxWOKjTCAG8aMo7mZOmhHJ14ABeXG2emdKJs+AwuGqRIAXySUyRAHMIEgrER4KzlHQUBhbAwoGAED4AMKzGDEMAYJAwdVizV7LjCGAKt4fPrSdwE6TiCiwBXwPhE12VERksWy2U0EAADwWVrmuAWCAAGvz4ABGKjipSAZQZAHYMgE6GQD1DIArhkA6wyACYZAEkMgCOGQAdDIBThkAPwyAa4ZAGjKgE0GQDRDIB9BkAgQyAawZAB9mgBEGQBmDMPOzQgA)
参照ゲノムからコード領域の座標を抽出する

## 参照ゲノムからコード領域の座標を抽出する

- specificな目的ですが、非モデル生物のエクソーム解析をスピーディに進めるうえで便利なので、Tipsとして紹介します。
- データベースが完備されているゲノムから、タンパクコード領域（CDS）の領域の座標を一括してリスト化する方法です。

## SnpEff

- [SnpEff](http://pcingola.github.io/SnpEff/)に登録されている参照ゲノムを使います。2021年12月時点で、v5.0eが利用可能です。
- 例としてヒトに最も近縁な生物であるチンパンジー（学名Pan troglodytes）のCDSをリスト化してみます。
- まず、チンパンジーのデータベース名を確認します。

```
java -jar snpEff.jar databases > snpEff_database.list  # 全データベースをリスト化

grep 'Pan_troglodytes' snpEff_database.list  # チンパンジーを含む行を検索
$ CHIMP2.1.4.75  Pan_troglodytes 
 https://snpeff.blob.core.windows.net/databases/v5_0/snpEff_v5_0_CHIMP2.1.4.75.zip
$ Pan_tro_3.0.99  Pan_troglodytes 
 https://snpeff.blob.core.windows.net/databases/v5_0/snpEff_v5_0_Pan_tro_3.0.99.zip
```

- チンパンジーゲノムのデータベースは`CHIMP2.1.4.75`と`Pan_tro_3.0.99`の2種類があって、後者の方が最新なので、こちらをダウンロードします。

```
java -jar snpEff.jar download Pan_tro_3.0.99
```

- `genes2bed -cds`で、CDSを取り出してbed形式で保存できます。

```
java -Xmx8g -jar snpEff.jar genes2bed -cds Pan_tro_3.0.99 > Pan_tro_3.0.99_cds.bed
```

- 中身を見てみると、並びが必ずしもソートされておらず、領域の重複もあります。

```
head -6 Pan_tro_3.0.99_cds.bed
$ #chr    start   end     geneName;geneId;transcriptId;exonRank;strand
$ 1       44314   44488   ENSPTRG00000047549;ENSPTRG00000047549;ENSPTRT00000090571;1;+
$ 1       57173   57284   ENSPTRG00000047549;ENSPTRG00000047549;ENSPTRT00000090571;9;+
$ 1       56011   56523   ENSPTRG00000047549;ENSPTRG00000047549;ENSPTRT00000090571;7;+
$ 1       55588   55704   ENSPTRG00000047549;ENSPTRG00000047549;ENSPTRT00000090571;5;+
$ 1       56732   56857   ENSPTRG00000047549;ENSPTRG00000047549;ENSPTRT00000090571;8;+
```

- もし[GATK](https://gatk.broadinstitute.org)などでソートされていて重複のない領域のリストを必要とする場合は、あらかじめ[bedtools](https://bedtools.readthedocs.io)で編集しておくといいでしょう。

```
bedtools sort -i Pan_tro_3.0.99_cds.bed \  # ソートする
> Pan_tro_3.0.99_cds_sorted.bed

bedtools merge -i Pan_tro_3.0.99_cds_sorted.bed \  # 重複領域をマージする
> Pan_tro_3.0.99_cds_sorted_merged.bed

head -6 Pan_tro_3.0.99_cds_sorted_merged.bed
$ 1       44314   44515
$ 1       45175   45210
$ 1       49376   49567
$ 1       49653   49688
$ 1       50212   50314
```

- [GATK](https://gatk.broadinstitute.org)などの領域ファイルとして使いたい場合は事前にindex化しておきます。

```
gatk --java-options "-Xmx64G -Xms64G" IndexFeatureFile \
-I Pan_tro_3.0.99_cds_sorted_merged.bed
```

以上。（2022年1月4日、了。）
画像表示について

## 画像を表示させる方法について
```qiita.rb
<img scr = "images/画像ファイル名" , alt = "画像が表示されなかった場合の補足文" , class = "クラス名" >
```
imgはImageの略で、img要素を用いることで、Webサイト上に画像を表示することができます。img要素には、画像の場所を指定するsrc属性（Sourceの略） 、画像が表示されなかった場合に代替テキストなどを表示するためのalt属性（Alternativeの略）も併せて使用します。
勉強する意味とは？大人でも答えづらい質問を回答

#結論　答えをずばり回答
以下の3つが答えです。

やりたくないことをやらないため
自分のやりたいことに気づくため
やりたくないことをやらず、やりたいことをやる状態を維持するため
以下に理由を説明します。やりたくないことを避けて、やりたいことを毎日やり、その状態を維持するために勉強します。

#理由　なぜ3つを成し遂げられるのか
##やりたくないことをやらないため
日本には約1億2000万人の人がいて、約半数が大人と呼ばれる人達です。他は子供と老人と病人です。日本の約半分の大人たちのうち、ほんとんどはやりたくないことをやっています。やりたくないこととは、嫌な人に会う、嫌な作業をやる、嫌なことを考えることです。やりたくないことをやっている理由は、選択できないからです。「みんなやっているから」、「私はこれしかできないから」、「他のことをすると怒られる」といった理由で、何も代案を考えられず、そのままやりたくないことをやっています。代案を考えるように勉強することが大事です。

##自分のやりたいことに気づくため
やりたくないことは皆さん気づくと思いますが、やりたいことって何なのかを回答できますでしょうか。世界はどうなっていて、どういうことをやると人に喜ばれるのか、嫌がられるのか、どういう活動をするとどういう結果になるかは、勉強することで知ることができます。勉強できないと、身の回りの人からの浅い情報や、今現在の刹那的な情報しか手に入りません。勉強することで、世界中とつながり、過去と現在をつなげることができます。

例えば、「コロナワクチンを打つと体調が悪くなる」という情報を、勉強していない人と勉強する人でどのようにとらえるでしょうか。勉強していない人は、コロナワクチンは危険なモノだと判断するでしょう。勉強している人は、体調が悪くなる人の割合であったり、体調が悪くなるのは本当にコロナワクチンが直接の原因なのかを調べて判断します。定期的に体調を崩す人がコロナワクチンを接種した後に体調が悪くなった場合、定期的に起こるものなのか、コロナワクチンのものなのかが、本人にもはっきりわからないでしょうか。「コロナワクチンを打つと亡くなる」という情報も、日本人があたかも亡くならない民族だと信じる方(勉強していない人)だとコロナワクチンが直接の原因で亡くなったと判断するでしょう。1日1人以上、日本人は亡くなっているので、たまたまコロナワクチンを打った方にそういう方がいた可能性もあります。コロナウイルスの情報は統計学を学ぶと正しいか、正しくないかがはっきりわかります。

##やりたくないことをやらず、やりたいことをやる状態を維持するため
勉強しないと、情報が更新されません。運良く一時的にやりたいことをできる状態になっても、20年後もその生活を継続できますか。インターネットがない時代であればもしかするとうまくいくかもしれませんが、インターネットから情報を得られなければやりたくないことを避けて、やりたいことをやることを継続することができなくなります。インターネットからの情報ですが、自分以外の誰かから定期的に届く情報だと意味がありません。自分以外の誰かの情報だけで過ごすと、奴隷になるように世界はできています。自分から必要な情報を探し、正しいことの検証を行うために勉強でやり方を学ぶんです。

#対偶　3つを成し遂げるために勉強が必要なのか
「やりたくないことを一生続けていい。」という方など、上記3つを手に入れる必要が無いのであれば、勉強する必要はありません。また、上記3つはすでにできるため、勉強をする必要がないということであれば不要になります。ごく稀に生まれた時点で3つを手に入れる方もいますので、そういう方には不要な作業です。

#結び　
繰り返しますが、やりたくないことを避けて、やりたいことを毎日やり、その状態を維持するために勉強します。 https://ja.wikipedia.org/wiki/%E5%AD%A6%E7%BF%92
GitHubにpushしても芝生が生えないとき、過去に遡って草を再生する魔法


GitHubの芝生は主にissueやmasterへのpushなどで生えます
詳しくは[ここを参照](https://help.github.com/en/github/setting-up-and-managing-your-github-profile/why-are-my-contributions-not-showing-up-on-my-profile)

しかし、ローカルの.gitconfigに登録されているメールアドレスとリモートリポジトリのメアドが一致してないと、ローカルブランチのcommitをプッシュしても芝生に反映されません

違うアドレスでcommitしてしまったり、そもそも.gitconfigが設定されてなかったりなど、あとから気づいて困ることがあると思います

ミスしたコミットがひとつやふたつならひとつずつ手作業で解決できますが、該当コミットがいくつもある場合は一つずつやってられないので`git filter-branch`コマンドを使って修正する必要があります

過去のコミットにさかのぼって芝生を生やす方法を総括的に解説した記事が見当たらなかったので、メモがてらこの記事にまとめます

環境によってうまく行かない場合もあるようなので要注意です
すべての操作はバックアップを取った状態で行ってください

## 方法
ローカルブランチの過去コミットのAUTHOR情報とCOMMITTER情報を書き換えます
```bash
git filter-branch -f --commit-filter '
    GIT_AUTHOR_NAME="your_name"
    GIT_AUTHOR_EMAIL="your_email@gmail.com"
    GIT_COMMITTER_NAME="your_name"
    GIT_COMMITTER_EMAIL="your_email@gmail.com"
    git commit-tree "$@"
' HEAD
```
リモートブランチに反映させます
```bash
git push -f origin master
```
この時点で芝生に反映されたはずなので確認してみましょう

ここからが重要なのですが、過去のコミットをすべて書き換えたため、このままだとローカルから新しいコミットをプッシュできません
また`git pull origin master`とすると以下のエラーが出ます
> `fatal: refusing to merge unrelated histories`

そのため、一旦ローカルリポジトリを削除したあと、リモートリポジトリからクローンしてくる必要があります[^1]

```bash
cd ../
rm -r your-repository/
git clone https://github.com/username/your-repository.git
cd your-repository/
```


[^1]: [git filter-branchでパスワードを全ブランチの歴史から消す手順 - Qiita](https://qiita.com/konpyu/items/ecce04e3713f12c43fb4#%E6%B3%A8%E6%84%8F)
jqコマンドを使わずにjsonを一行にする裏技


`curl`コマンドでapiのテストをするときに用意したjsonを１行にする必要があった。
でも`jq`コマンドをインストールするのはめんどくさい。

そこで、デフォルトでmacなどに入っている`tr`コマンドでjson文字列内の改行と空白を削除する方法を考えた。

```bash
$ echo <json> | tr -d ' ' | tr -d '\n' && echo
```

最後の`echo`はbashのプロンプトを改行するため。

---

その逆
[Linux標準機能で簡単JSON整形 - Qiita](https://qiita.com/yuji_azama/items/27c776ecaa8d95910a69)