OmniAICreator/Qiita-1.07M huggingface dataset:
プログラミング初心者が書いたGit/GitHubの使い方

**はじめに**
-----
現在プログラミングを勉強中の初心者が、初心者なりにGitとGitHubの
基礎的な使い方についてまとめてみました。
備忘録的な感じでの記事になりますのでご了承くださいませ。
前提として私はMacのターミナルにて操作していきます！

流れとしては....

+ ローカルリポジトリの作成、編集、コミット
+ ローカルリポジトリからリモートリポジトリへのプッシュ

としていきます。

**ローカルリポジトリの作成、編集、コミット**
---
まずはローカルリポジトリから作成していきます。
最初にデスクトップの中に練習用のディレクトリを作成します。
ここでは`git_test`という名前のディレクトリを作ります。

そしてターミナルで以下のコマンドを打ち`git_test`まで移動します。

```
cd ~/Desktop
mkdir git_test
cd git_test
```

続いて`git_test`に移動したら以下のコマンドを実行し
**ローカルリポジトリ**を作成します。

```
git init
```

上記が終わりましたら一度vscode上にて`git_test`を開き編集します。
`git_test`ディレクトリの中に`test.html`というファイルも作成しましょう。

`test.html`の中に以下の文章を入力します。

```
<h1>こんにちは！</h1>
```

そしてvscode上で一度保存します。
次にローカルリポジトリにコミットをします。

```
git add .
git commit -m "何かコメントを書く"
```
コミットを行うことにより、**ファイルの変更や追加**を
ローカルリポジトリに反映させることが出来ます。

**ローカルリポジトリからリモートリポジトリへのプッシュ**
----
続いてはGitHub(https://github.com/ )にアクセスしリモートリポジトリを作成します。
![リポジトリの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/daf19a14-951d-1a35-6031-bdfb868e42b4.png)
右上のベルのアイコンをクリックし、`New repository`を選択します。
すると以下の画面に遷移します。![クリエイトリポジトリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/033fee87-2377-5436-c018-4d5dfe108d3e.png)
`Repository name`の部分は好きな名前で登録して大丈夫です。
画面真ん中の`Public`を選択すると誰でも閲覧可能となります。

実務では`Private`の方を選択することが多いのではないかと思われますので
自分自身も設定には気をつけたいですね。

![クリエイトリポジトリ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/958e4e4a-538a-97a9-fdfc-8bd57aae7cb9.png)

`Create repository`を選択すると上記の画面に移ります。
この際には必ず`HTTPS`を選択し、一番右側のボタンを押すとURLをコピーすることが出来ます。

そしてURLをコピーしましたらそのまま先ほどのターミナルに戻り、以下を実行します。

```
git remote add origin コピーしたURL
git push origin master
```
上記までのコマンドが正常に行われると以下のようになります。![プッシュ後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/34a49ead-2fc8-e49e-3ca4-062603bb8cc5.png)

ローカルリポジトリからリモートリポジトリへのプッシュが完了した状態になります。
以上がローカルリポジトリからリモートリポジトリへプッシュするまでの基礎的な流れになります。

ブランチを切ってそれをマージするなどについてはまた後日追記したいと思います！
ここまでご覧頂きありがとうございました。

引用元：https://tech-blog.rakus.co.jp/entry/20200529/git
AmazonLinux2にLet'sEncrypt(無料SSL)を導入する

・前提
　AmazonLinux2のインタンスを作成してSSHで接続できる。
　セキュリティグループに
　　タイプ：HTTPS
　　プロトコル：TCP
　　ポート範囲：443
　　ソース：0.0.0.0/0
　が追加されている。

・http24の導入
`sudo yum update -y`
`sudo yum install httpd`
`sudo service httpd start`
`sudo service httpd status`
`sudo systemctl enable httpd.service`
`httpd -v`

※ ブラウザから確認。apacheの画面が表示されればOK

・スーパーユーザになっておく
`sudo su -`

・timezone設定
`timedatectl set-timezone Asia/Tokyo`
`ll /etc/localtime`
※ dateで確認

・mod_sslインストール
`yum install --enablerepo=remi,remi-php74 mod_ssl.x86_64`

・snapdが入っているリポジトリの追加
`cd /etc/yum.repos.d/`
`wget https://people.canonical.com/~mvo/snapd/amazon-linux2/snapd-amzn2.repo`


※/etc/yum.conf に以下の設定を追加。[main] の最後に追加する
`vi /etc/yum.conf`
↓追加する文

```
exclude=snapd-*.el7 snap-*.el7
```

snapdインストール
`yum install snapd`

snapd自動起動設定
`systemctl enable --now snapd.socket`

パスを通す
`ln -s /var/lib/snapd/snap /snap`

core インストール
※ 実行するとエラーになるけど、もう１度実行するとなぜか成功する
`snap install core`

全てのパッケージをアップデート
`snap refresh core`

cerbotのインストール
`snap install --classic certbot`

`snapパス通し`
ln -s /snap/bin/certbot /usr/bin/certbot


httpd.confの編集
`vi /etc/httpd/conf/httpd.conf`

↓一番下の行に追記

```
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin メールアドレス
DocumentRoot ドキュメントルート
ServerName ドメイン
</VirtualHost>
```
・証明書を取得 & インストール
`certbot --apache`
※初めにメールアドレスを求められたり、
　　Yes/Noを求められるので答えていくと証明書の取得とインストールが始まる

証明書の期限確認
`openssl x509 -in /etc/letsencrypt/live/ドメイン/fullchain.pem -noout -dates`

番外
　　うまくいかないで何回も試してたら怒られてしばらくドメインが使えなくなったので、
　　まず、お試しでやるならサブドメイン作ってからやった方が良いかもw

```
There were too many requests of a given type 
:
: Error creating new order 
:: 
too many certificates (5) already issued for this exact set of domains in the last 168 hours: ドメイン: see https://letsencrypt.org/docs/rate-limits/
```
エラー「warning: adding embedded git repository」が発生した。

#今回発生したエラー
任意のディレクトリでリモートリポジトリを作成し、git add . をしたところ今回のエラーが発生した。

```
$git init
$git add .
```
warning: adding embedded git repositoryを翻訳すると 「警告: 埋め込まれた git リポジトリを追加しています」 となる。
#エラー発生原因
任意のディレクトリのカレントディレクトリや親または子のディレクトリに、誤って git init してしまっている。
#エラーの解決方法
1. 誤って git init してしまったファイルを探す。
2. 発見したファイルの .git を削除する。

#具体的なエラー解決方法の手順
###誤って git init してしまったファイルを探す。
  * cd コマンドで任意のファイル周辺のディレクトリに移動しする。ls -a コマンドで .git が存在しない確認する。

 　　　　　　　　または　　

  * cd コマンドで親のディレクトリに移動する。find . -type d -name '.git'　コマンドで　.git が存在しないか確認する。

```
$cd ファイルパス
＄ls -a
```

または

```
$cd 親ディレクトリのパス
ファイル＄find . -type d -name '.git'
```

###発見したファイルの .git を削除する。
  * cdで発見したディレクトリに移動し、rm -rf .git　コマンドで .git を削除する。　  

```
$cd ファイルパス
$rm -rf .git
```
Scipyのsolve_ivpで条件を満たすまでシミュレーションを行う

# 概要
scipyライブラリのsolve_ivpのevent機能について試すために自由落下のシミュレーションを行います。
今回は地面に到着した瞬間までシミュレーションを行います。

# 式
自由落下の式は次のようになります。

```math
\begin{align}
\frac{dy}{dt} &= v \\
\frac{dv}{dt} &= -mg
\end{align}
```

ここで、物体の高さを$y$、速度を$v$とします。
$m$と$g$は定数です。


$y=0$のとき地面と衝突したと考えます。
solve_ivpのeventはfloatを返す関数で定義され、eventの発生時に0を返します。
今回はそのまま物体の高さ$y$を返します。


# プログラム
上記の式を用いてシミュレーションプログラムを作成します。

```python
from scipy.integrate import solve_ivp
import numpy
from matplotlib import pyplot

# 物理定数
m = 1
g = 1


def free_fall(t, y):
    '''
    自由落下の方程式
    '''
    return numpy.asarray([y[1], -m * g])

def ground(t, y):
    '''
    地面との衝突の判定式
    '''
    return y[0]
ground.terminal = True  # 条件が満たされたらシミュレーションを終了する


if __name__ == '__main__':
    # 初期値
    y0 = numpy.asarray([10, 0])
    # 0から10までの時間を100分割してシミュレーションを行う
    sol = solve_ivp(free_fall, [0, 10], y0, t_eval=numpy.linspace(0, 10, 100), events=ground)
    print(sol.t)
    print(sol.y)
    # グラフ出力
    pyplot.plot(sol.t, sol.y[0])
    pyplot.ylabel('y')
    pyplot.xlabel('t')
    pyplot.show()
```

# 結果
プログラムを実行すると次の出力とグラフが得られます。

```
[0.         0.1010101  0.2020202  0.3030303  0.4040404  0.50505051
 0.60606061 0.70707071 0.80808081 0.90909091 1.01010101 1.11111111
 1.21212121 1.31313131 1.41414141 1.51515152 1.61616162 1.71717172
 1.81818182 1.91919192 2.02020202 2.12121212 2.22222222 2.32323232
 2.42424242 2.52525253 2.62626263 2.72727273 2.82828283 2.92929293
 3.03030303 3.13131313 3.23232323 3.33333333 3.43434343 3.53535354
 3.63636364 3.73737374 3.83838384 3.93939394 4.04040404 4.14141414
 4.24242424 4.34343434 4.44444444]
[[10.          9.99489848  9.97959392  9.95408632  9.91837568  9.87246199
   9.81634527  9.75002551  9.6735027   9.58677686  9.48984797  9.38271605
   9.26538108  9.13784308  9.00010203  8.85215794  8.69401082  8.52566065
   8.34710744  8.15835119  7.9593919   7.75022957  7.5308642   7.30129579
   7.06152433  6.81154984  6.55137231  6.28099174  6.00040812  5.70962147
   5.40863177  5.09743904  4.77604326  4.44444444  4.10264259  3.75063769
   3.38842975  3.01601877  2.63340475  2.2405877   1.8375676   1.42434445
   1.00091827  0.56728905  0.12345679]
 [ 0.         -0.1010101  -0.2020202  -0.3030303  -0.4040404  -0.50505051
  -0.60606061 -0.70707071 -0.80808081 -0.90909091 -1.01010101 -1.11111111
  -1.21212121 -1.31313131 -1.41414141 -1.51515152 -1.61616162 -1.71717172
  -1.81818182 -1.91919192 -2.02020202 -2.12121212 -2.22222222 -2.32323232
  -2.42424242 -2.52525253 -2.62626263 -2.72727273 -2.82828283 -2.92929293
  -3.03030303 -3.13131313 -3.23232323 -3.33333333 -3.43434343 -3.53535354
  -3.63636364 -3.73737374 -3.83838384 -3.93939394 -4.04040404 -4.14141414
  -4.24242424 -4.34343434 -4.44444444]]
```

![result_free_fall_true.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257212/2b09319e-5c31-c9ff-8353-fd28f23a071e.png)

地面に衝突したタイミングでシミュレーションが終了していることがわかります。
ground.terminal = Trueの行をコメントアウトしたり、値をFalseに設定するとt=10までシミュレーションが継続します。


# 参考文献
scipy.integrate.solve_ivp — SciPy v1.6.3 Reference Guide (https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html)
ubuntu20.04でgpuをつかうdockerイメージを走らせるまで

# はじめに

ubuntu 20.04 desktop + nvidia gpu + docker で環境構築したときのメモ

やることは以下の３つだ。

- nvidiaドライバーのインストール
- dockerのインストール
- nvidia container toolkitのインストール

このリンク役に立つ。

https://medium.com/nvidiajapan/nvidia-docker-%E3%81%A3%E3%81%A6%E4%BB%8A%E3%81%A9%E3%81%86%E3%81%AA%E3%81%A3%E3%81%A6%E3%82%8B%E3%81%AE-20-09-%E7%89%88-558fae883f44

# nvidiaドライバーのインストール

初期状態だとnouveauというドライバーが入っているので、nvidiaのドライバをインストールする。

- ソフトウェアとアップデートを起動
- 追加のドライバー　タブを選択
- nvidia...を使用します。をチェック
- mokがなんたらかんたらでパスワードを作れと言われるのでパスワード作成
- 再起動
- 再起動するとなんか選択肢が現れるので「Enroll MOK」を選択
- さっき作ったパスワードを入力 

これで完成。MOKのところがよくわからんかったが、以下の記事を読んで解決した。

![Screenshot from 2021-06-06 16-10-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233578/7ecdfa54-ddbc-df96-6526-5b7fbdf0aea8.png)

https://qiita.com/junkoda/items/0c58e0c996b56b773d50

# dockerのインストール

ここに従ってやれ。

https://docs.docker.com/engine/install/ubuntu/


# nvidia container toolkitのインストール

ここに従ってやれ。

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installing-on-ubuntu-and-debian

# 実行例

```
sudo docker run -it --gpus all --name study-ai -v ~/notebooks:/tf/notebooks -p 8888:8888 tensorflow/tensorflow:latest-jupyter
```

終わり。
memberpressのユーザーカスタムフィールドを翻訳可能にする。

memberpressではカスタムフィールドでユーザーに属性をつけることができますが、このカスタムフィールドの名前、フォームで入力するときに表示されるのですがこれがpotファイルを使ったりで翻訳することができません。

管理上良い方法ではないかもしれませんが、プラグインファイルを編集することで翻訳できるようになります。というメモ。

#翻訳できる文字列にする方法

`/wp-content/plugins/memberpress/app/views/checkout/signup_row.php`を編集します。

```php:signup_row.php
<?php if(!defined('ABSPATH')) {die('You are not allowed to call this page directly.');} ?>

<div class="mp-form-row mepr_custom_field mepr_<?php echo $line->field_key; ?>">
  <?php if($line->field_type != 'checkbox'): ?>
    <div class="mp-form-label">
      <label for="<?php echo $line->field_key . $unique_suffix; ?>"><?php printf( '%1$s:%2$s', _x(stripslashes($line->field_name), 'ui', 'memberpress'), $required ); ?></label>
      <?php //↓この行だけ編集する ?>
      <span class="cc-error"><?php ($line->required) /*here for email custom fields that are not required*/ ? printf(_x('%s is Required', 'ui', 'memberpress'),  _x(stripslashes($line->field_name), 'ui', 'memberpress')) : printf(_x('%s is not valid', 'ui', 'memberpress'), _x(stripslashes($line->field_name),'ui', 'memberpress')); ?></span>
    <?php //↑この行だけ編集する ?>
    </div>
  <?php endif; ?>
  <?php echo MeprUsersHelper::render_custom_field($line,$value,array(),$unique_suffix); ?>
</div>

```

#やってること
Wordpressでは関数`_x()`で翻訳可能な単語を示してあげることができるのでこれを利用します。
【Flutter】Firestoreのデータを取得時のエラー

Firestoreからドキュメント一覧を取得ときに出てきたエラーの解消法を記述します。

`FirebaseFirestore.instance.collection('users').getDocuments();`は非推奨で、
List<DocumentSnapshot>をsnapshotから取り出すときの`documents`も非推奨のようです。
古いテキストで時々みるので、`.getDocuments()をget()`にしましょう。


`getDocuments()`のエラー


```
The method 'getDocuments' isn't defined for the type 'CollectionReference'.
Try correcting the name to the name of an existing method, or defining a method named 'getDocuments'.
```

`documents`のエラー

```
The getter 'documents' isn't defined for the type 'QuerySnapshot<Map<String, dynamic>>'.
Try importing the library that defines 'documents', correcting the name to the name of an existing getter, or defining a getter or field named 'documents'.
```
非推奨の書き方

```main.dart
class _MyFirestorePageState extends State<MyFirestorePage> {
  List<DocumentSnapshot> documentList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            ElevatedButton(
              child: Text('ドキュメント一覧取得'),
              onPressed: () async {
                final snapshot =
                    await FirebaseFirestore.instance.collection('users').getDocuments();
                setState(() {
                  documentList = snapshot.documents;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}
```

新しい書き方

```main.dart
class _MyFirestorePageState extends State<MyFirestorePage> {
  List<DocumentSnapshot> documentList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            ElevatedButton(
              child: Text('ドキュメント一覧取得'),
              onPressed: () async {
                final snapshot =
                    await FirebaseFirestore.instance.collection('users').get();
                setState(() {
                  documentList = snapshot.doc;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}
```
このように書くとエラーがでなくなります。
jwt(Json Web Token)について

こんにちは、プレイライフの熊﨑です。
最近一番幸せだった時は、サウナに入った後水風呂に入って、全裸で外気浴を行っていた時ですw

そんなサウナにハマりつつある私が本日は、jwtについて今現在自分がわかっていることをまとめてみました。

## jwtとは？
jsonデータに署名や暗号化を施す方法を定めたものです。
主に認証用のトークンなどで用いられます。

## どんな構成？
ヘッダー・ペイロード・署名の３つで構成されています。

### ヘッダー
ヘッダーは通常、2つの部分で構成されています。1つはトークンのタイプ（JWT）、もう1つは使用されている署名アルゴリズム（HMAC SHA256やRSAなど）です。
署名アルゴリズムは、JWT文字列の暗号化に用いられるアルゴリズムのことを指しています。

```
{
  "alg": "HS256",
  "typ": "JWT"
}
```

### ペイロード
ペイロードには以下のようなuserの認証情報などが格納されています。

```
{
  "id": "1",
  "name": "John Doe",
  "admin": true
}
```

### 署名
トークン検証用の署名。
トークン内のヘッダーやペイロードを用いているためトークンの中身が途中で変更されていないことを確認できます。

```
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

// secret: 秘密鍵
// HMACSHA256: 暗号化アルゴリズムの１種
// headerの中身とpayloadの中身をbase64エンコーディングして、ピリオドでつなげた後に秘密鍵とHMACSHA256を使って、署名を作成する
```

## どんな時に使用されるのか？

### 認証
ユーザーがログインすると、その後の各リクエストにトークンが含まれ、そのトークンで許可されたルート、サービス、リソースにアクセスできるようになります。

イメージとしては、旅行者がパスポートを発行（ここがログイン処理でトークンを発行するところ）してもらい、そのパスポートを使用して、世界各国に行ける。というものだと思います。

### 情報交換
jwtは公開鍵と秘密鍵を用いて署名することができるため、送信者に公開鍵を使ってもらい、自身の秘密鍵で復号することができるため、情報を交換するときにも使用できます。

## jwtのメリット
Cookieでの認証を行う際はサーバ側でsession情報を保持しております。そしてCookieにはsessionIdを入れており、リクエストの都度sessionIdに紐づくサーバ側sessionデータを参照しています。そのsessionIDを元にDBからsession情報を取得する処理が必要になります。
一方で、jwtの場合は署名の検証処理だけですむというところが利点にあります。

また、ステートレスなため、サーバ資源をすぐに開放できるという利点があり、利用者や負荷に応じて性能や機能を向上させられます。

## jwtのデメリット

個々のJWTトークンを無効にすることはできないということがあります。その気になればいつでもサーバーが無効にできるセッションとは異なり、個々のステートレスJWTトークンは無効にできません。侵害を検出した後に攻撃者のセッションを無効にすることはできないということです。

## まとめ
- jwtはヘッダー・ペイロード・署名の３つから構成される。
- jwtは認証や情報交換の際に使用される。
- jwtはcookie認証に比べて処理が早くスケーラブル。
- 一方で、個々人のトークンを無効にすることができないことから、セキュリティ面に懸念が残る。

メリットとデメリットをもっと深掘りして、どのような認証形式を使うか選択する必要がありそうですね、、、

## 参考文献
[https://jwt.io/introduction](https://jwt.io/introduction)
[http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/)
[https://qiita.com/doyaaaaaken/items/02357c2ebca994160804](https://qiita.com/doyaaaaaken/items/02357c2ebca994160804)
Shellについてざっくりまとめてみた

#きっかけ
この記事を書こうと思ったきっかけ。
所属している「もりけん塾」で、`nodenv`の勉強会があり、そこでいろいろ知らない用語が出てきた。
そして先生から「開発者として必須」と言われたので、せっかくの機会だし、調べてみようと思った。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">実は昨日の勉強会は次の勉強会の前提知識になるので出た方はラッキーだったのです<br>shell、.bash_profile, .bashrc or .zshrcなどの設定、環境変数、パスを通すみたいなのはフロントというより開発者として必須なので</p>&mdash; フロントエンドエンジニア (@terrace_tech) <a href="https://twitter.com/terrace_tech/status/1398775238142267392?ref_src=twsrc%5Etfw">May 29, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

##shellとはざっくり
`shell`は、ユーザとOSの中心部にある`カーネル`との中継を担ってくれるソフトウェアのこと。
ユーザからコマンドが入力されることで、OSの中核である`カーネル`とやり取りし、カーネルのプログラムを呼び出す。 
カーネルがプログラムを実行したら、`shell`に結果を伝えてターミナルに出力する。
ユーザとカーネルが直接やりとりすることはできず、必ずshellを通じてやりとりすることになっている。

##ログインシェルとは
ユーザがログインした直後に自動的に起動されるシェルのこと。

## インタラクティブシェル（対話的シェル）
コマンドラインで bash とか zsh と入力すると起動するシェルのこと。対話形式で入力する。


##自分が使っているshellを調べる方法

```
$ echo $SHELL
```
私の場合は、`/bin/zsh`と表示されるので、使っているシェルは`zsh`です。

以前までは`bash`がログインシェルとして使われていたようですが、
MacOS Catalinaからはデフォルトのログインシェルが変更されており、ログイン時に読み込まれるのは`zsh`となっています。

## shellの変更方法
こちらはあまり使うことはないと思いますが、一応備忘録として残しておく。
### 現在変更できるshellの一覧を確認
```
$ cat /etc/shells
```
僕の環境では

```

# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
```
このように表示されました。よく見る`sh`、`bash`、`zsh`などが確認できます。


##shellの設定ファイル
[参考: zshrcとzprofileについて](https://gallard316.hatenablog.com/entry/2020/11/24/185634)

### zshの設定ファイル
記述したものから順に読み込まれる。👇
#### .zshenv
> ログインシェル、インタラクティブシェル、シェルスクリプト、どれでも常に必要な設定を定義する
zsh が起動して、必ず最初に読み込まれる設定ファイル
影響範囲が大きいので記述は必要最低限にするべき

#### .zprofile
> ログインシェルに必要な設定だけを記述する
zshenv の次に読み込まれる設定ファイル
zsh ログイン時の一回だけ読み込まれる

#### .zshrc
> ログインシェル、インタラクティブシェルの場合に読み込まれる
一般的に紹介されている記事ではこの設定ファイルにいろいろ記述することが多い。

#### .zlogin
> ログインシェルに必要な設定だけを記述する
最後に読み込まれる
役割は .zprofile とほぼ一緒。混乱を避けるため併用しないこと

#### .zlogout
> exit コマンドで zsh を抜けたときに読み込まれる

### bashの設定ファイル
[引用：本当に正しい .bashrc と .bash_profile の使ひ分け](https://qiita.com/magicant/items/d3bb7ea1192e63fba850)
#### .bash_profile
>.bash_profile はログイン時にのみ実行されます。
具体的な用途は: 環境変数を設定する (export する変数)

#### .bashrc
> .bashrc は対話モードの bash を起動する時に毎回実行されます。具体的な用途は:
・環境変数でない変数を設定する (export しない変数)
・エイリアスを定義する
・シェル関数を定義する
・コマンドライン補完の設定をする
これらは bash を起動する度に毎回設定する必要があるものです。

##shellを変更する
`zsh`から`bash`にしてみます。

```
// 使っているshellを確認
$ echo $SHELL
-> /bin/zsh

// shellの変更
$ chsh -s /bin/bash 

// shellを再起動
$ exec $SHELL -l　

// 使っているshellを確認
$ echo $SHELL
-> /bin/bash
```
#紹介
私が所属している「もりけん塾」は、[もりけん先生](https://twitter.com/terrace_tech)が運営するJavaScriptに特化したコミュニティーです。（とは言ってもいろんな方がいらっしゃいます。）
フロントエンドエンジニアになりたい方にむけて、先生が道標となって初学者が迷わないように導いてくれます。コードの書き方、自走力を身に着けるにはとても良い環境です。
毎月1日に募集をかけていたのですが、ここ最近は募集かけなくても入塾したいとDMがくるそうです...!!（大人気）

[先生のブログ](https://kenjimorita.jp/)
[先生のTwitter](https://twitter.com/terrace_tech)
フローでのLeadの変換について

フローでのLeadの変換について、まずは関連情報を整理したいと思います。

質問的には、特別感はないです。ただコーディングを最初から排除している私が一番嫌いな質問。
まず、how can i do with the help of Flows without writning a code.　とか書かれていたら
分かっていても答えません。経験的にこういう人って回答しても逆切れするか、質問ごと消して再投稿する。
まぁ、そこはどうでもいい。今回の回答が重要です。さすがお師匠さんの回答。

[Auto Convert Lead without Code, with the help of Flows](https://trailblazers.salesforce.com/answers?id=9064S000000DwAFQA0)

Flows do not have an action to convert a lead - you must build one yourself, which you can't do on professional edition. Your only option is to find an ISV application with an invocable method to convert a lead included in the package, but a quick search doesn't show anything of that sort.

Of course, you can always try to convert the lead manually as part of the flow. The flow can receive a lead ID, and use the information from the lead to create an account and a contact, but it wouldn't work like normal conversion.
ハンズオンはじめの一歩: AWS アカウントの作り方 & IAM 基本のキ[動画4~8]

## 動画5：IAM (ポリシー、グループ、ロール)について学ぶ　4min

https://www.youtube.com/watch?v=iSKNbcV3rSo

IAMについて深堀りを行う
→ IAMポリシー・IAMグループ・IAMロールの説明

### IAMポリシー

- **アクセス許可の定義** を行うJSONドキュメント
- IAMユーザーやグループ、ロールに紐付けて扱う
- AWSが予め所持するポリシーに加え、独自に定義することも可能（IAMジェネレーターを使用する）

### IAMグループ

- **IAMユーザーの集合** を定義
- 複数のユーザーへのアクセス許可を容易にする

### IAMロール

- **AWSリソースに割り当てる**。（ユーザーではなく、特定のEC2やS3に

## 動画6：IAM ポリシーと IAM グループを作ってみる…　12min

https://www.youtube.com/watch?v=j_vPzjhZLcc

実際にハンヅオンでIAMポリシーの作成・割り当て、IAMグループの作成・割り当てを行う
具体的に...

まず新しいIAMポリシーを作成する、以下の権限を許可

1. EC2インスタンスの参照
2. EC2インスタンスのスタート
3. EC2インスタンスのストップを許可する

このポリシーを付与されたIAMユーザーの作成とIAMグループの作成を行う

## 動画7：IAM ロールを試してみる…　7min

https://www.youtube.com/watch?v=ayEiFpztUbc

実際にリソース（EC2）にIAMロールをアタッチする。

具体的には...

1. 何も許可しないIAMロールを作成（何も許可しない）。そのIAMロールをEC2にアタッチ。
2. 確認作業のためにコンソールがコマンドを叩く → 許可されていないと表示
3. 次にIAMロールの内容を適切に変更
4. 確認作業のためにコンソールがコマンドを叩く → 表示可能（IAMロールを変更したから。

最後にこれまで作成したユーザーやロール、グループを削除する

## 動画8：まとめ + Next Action としてオススメのコンテンツを紹介　4min

https://www.youtube.com/watch?v=HD5eHfmjXno

## まとめ

これまでの学習をまとめる。IAMの概要からIMAポリシーやグループなどについて学んだ。
今後のオススメのアクション

1. スケーラブルハンヅオン
2. サーバーレスWebAPI編
3. サーバーレス × AIサービス編

## 感想

初めてのAWSハンヅオン学習。とても初歩的な事であると思うが、公式が作成したハンヅオンは正確であり、わかりやすくとても勉強になった。AWS学習の導入としては最適と思いました。

最後までお読み頂きありがとうございました！！
【Rails】投稿をいいねされた順で表示する

# 目的
投稿をいいねされた順番で表示する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- いいね機能が導入されている。
[【Rails】いいね機能の実装（非同期）](https://qiita.com/oak1331/items/3e5508d9405c96ae6786)

# 方法

方法は単純で、全投稿を`いいねされた数が多い順`で並びかえることが出来ればOKです！
今回は`sort`を使用しました！

```ruby:app/controllers/posts_controller.rb
def index
#省略
  like_posts = Post.includes(:liked_users).sort {|a,b| b.liked_users.length <=> a.liked_users.length}
  @like_posts = like_posts.first(3)
end
```

今回は、いいねされた数が多いTOP3投稿までを表示したかったため、`@like_posts = like_posts.first(3)`と記述し、
並び替えた後の最初の3投稿を取得しています。

全投稿表示する場合は、`@like_posts = like_posts.first(3)`の記述はいりません。

# 最後に

並び替えまではスムーズにできましたが、その後の3投稿のみを取得する方法に手間取りました。
探したところ、同じような記事が無かったため誰かの参考になれば幸いです。
では。
IT企業でエンジニアになりたい文系未経験学生に告ぐ！

僕は某IT企業にて採用を担当している人事担当者である。 

22卒学生さんとも、今日までにかなりの人数とお会いしてきた。

その中でズバリ言いたいことがあって、良いお天気の休日午後にブログを書いているわけだ。

（文系未経験の学生がHIDEに辿り着くわけないって？twitterで拡散するから大丈夫！＾＾）



<h4>君の手はプログラミング言語と知り合いか？</h4>
僕ら人事担当者が真っ先に知りたくなることがこれだ。
JavaScriptでもPythonでもRubyでもなんでもいい。
ProgateでもPaizaでもどこでもいい。
手段やモノはとにかくどうでもいいんだけれど、何かしら触ってみたか？ということ。



>学生「私は文系でプログラミングは未経験ですが、なんちゃらかんちゃらであるIT業界にはとても興味を持っています！将来的にはSEとして貢献したいです！！」

>人事「なるほど。熱い気持ちをお持ちですね。では、何かしらの言語に触れてみたり本で学習したり、そうした経験はこれまでにありますか？」

>学生「今はまだありません（キリッ）しかし、御社では手厚い研修があると伺ったので、入社した際には研修での学びを最大限に・・・・・・・（僕はもう何も聞いていない。この話はいつ終わるのかなあ〜とあくびをしている）・・・・です！（再キリッ）」

>人事「そうなんですね〜。よくわかりました。では今回の結果はまた追ってご連絡しますので〜〜。」


今、新卒採用界隈をこのような学生が闊歩している。
学歴の高さは無関係だ。
こういう学生ほど、どういうわけか自身に満ち溢れた顔をしているから不思議で仕方がない。

僕は、このような思考の学生に問いたい。
「君たちは無意識の内に詐欺師になっている。それもすぐに相手にそうとバレるような。自分の興味を根拠づけるエビデンスを何一つ持っていない。採用それ自体にそもそもリスクが伴うってのに、こんな人をわざわざ採用するかい？」

・今は就活が忙しいので、就活が終わったら必ずやってみます！
・IT企業に受かったら、やってみます！（そうじゃないと無駄な時間になるので）

これ、シーズン中に何度も聞いていると、このフレーズを聞くだけでパソコンを切りたくなりますまじでw

このフレーズを学生さんの身近なものに置き換えると、こうです。


・来週の日曜に飲み会するって？　ああ〜行けたら行くわ〜。
・明日の予定？　ああ〜今んとこ空いてるよ〜。（だけど、君が誘ってくれてるその内容によっては行かないし、他の予定が入るかも。

僕たちの脳内ではこのようなフレーズに変換されるわけですね。
悪い冗談でもなんでもないです。本気で、です。



<h4>とにかく手を動かしてみる</h4>
文系未経験だから、何もしなくたって許される？
そんなことはないのです。
あなたの持っているという興味を本当の意味で伝えるためには、やってみなければ。


本当に興味のあるものには、自然と手を伸ばすものです。
それを知りたいから。
それを知る中で、ますます心が踊ってくるから。
そして、こうした人を仲間として迎え入れて、一緒に成長していきたいのです。

僕はそう考えていますし、こうした考えを持つ人事担当者は多くいることでしょう。


<h5>twitter</h5>
twitterアカウントを開設しました。
質問や相談等あれば、こちらまでご連絡ください。

@recruit_ITman
【DNS】テスト用ドメインには*.testを使用しましょう

# 結論から

## テスト用途のドメインには以下を使いましょう

```bash
*.test
```
`*`はなんでもよくて、例えば`example.test`とかです

##ドキュメント例示用途のドメインには以下を使いましょう

```bash
example.com
example.net
example.org
*.example
```

# 何故？
例示用、テスト用にはこれを使用するといったドメインがRFC2606で定められているからです。　
https://datatracker.ietf.org/doc/html/rfc2606
試しにwhoisで`example.com`を調べてみるとIANAのドメインということがわかります。
https://whois.domaintools.com/example.com

# 守らないとどうなる？
正体のわからないサイトに意図せずアクセスしてしまうかもしれません。

# おまけ
日本の例示用ドメインもあります

```bash
$ whois example.co.jp
[ JPRS database provides information on network administration. Its use is    ]
[ restricted to network administration purposes. For further information,     ]
[ use 'whois -h whois.jprs.jp help'. To suppress Japanese output, add'/e'     ]
[ at the end of command, e.g. 'whois -h whois.jprs.jp xxx/e'.                 ]

Domain Information:
a. [Domain Name]                EXAMPLE.CO.JP
g. [Organization]               Reserved Domain Name
l. [Organization Type]          Reserved Domain Name
m. [Administrative Contact]
n. [Technical Contact]
p. [Name Server]
s. [Signing Key]
[State]                         Reserved
[Registered Date]
[Connected Date]
[Last Update]                   2000/08/31 19:32:02 (JST)
```

# 参考
- 参考にさせていただきました。  
https://blog.ko31.com/201304/sample-domain-example/
- RFC2606  
https://datatracker.ietf.org/doc/html/rfc2606
- whois検索  
https://whois.domaintools.com/example.com
- 国内のドメイン  
https://jprs.jp/faq/use/#q3
【Kotlin】AWS SDK Chimeを使ってデモアプリを作成する


# はじめに

ビデオチャットSDKを利用してみたいと思い、**AWS Chime SDK**を利用してみました。
AWS Chime SDKについては[こちら](https://aws.amazon.com/jp/chime/chime-sdk/)をご覧下さい。


# 大まかな流れ

*1.[Github for android](https://github.com/aws/amazon-chime-sdk-android) をクローン
2.[Github for backend](https://github.com/aws/amazon-chime-sdk-js) をクローン
3.AWSにデプロイをして「https: ~.com/prod/」のURLを受け取る
4.端末にAWSから受け取ったURLを設定
5.接続確認*

# 事前に必要な事など

*AWSのアカウント*
*AWS IAMユーザーの設定*
*S3バケットの作成*
*端末*

# サーバーレス構築をした事ない方向けに参考になる動画 & サイト
[サーバーレスについて（AWS公式）](https://aws.amazon.com/jp/builders-flash/202003/awsgeek-serverless/?awsf.filter-name=*all)
[AWS Chime SDKを使ったサーバーレス構築](https://www.youtube.com/watch?v=XVHGq2uJu9s)


# デモアプリを使って出来る事

*下記を見る限り基本的なビデオチャットアプリの機能は用意されている印象です。*

会議の準備、参加
会議タイトル（会議URL）の作成
URLを使用した会議招待
自分の会議参加者名の設定
クライアントが接続するメディアリージョンの自動選択・手動選択
メディア入出力の準備
音声入力デバイス（マイク）の選択
映像入力デバイス（カメラ、画像）の選択
映像入力クオリティ（幅、高さ、フレームレート、最大通信帯域幅）の調節
音声出力デバイス（スピーカー、イヤホン）の選択
音声・映像入出力のプレビュー
音声出力のテスト
会議の実施
Web会議（音声、ビデオ）
音声入力のミュート
会議参加者の一覧の表示
会議参加者のステータスの表示（「発言中」「ミュート」など）
画面共有（デスクトップ、コンテンツ）
テキストチャット
メディアメトリクス（送信・受信可能帯域幅）の確認
会議の退出
会議の終了
その他
サイマル配信
Web Audio
SIPによる会議参加




# ZOOMとの比較

AWS Chimeが100名以上の通話が可能である事、通信障害がZoomに比べて少ない点以外はZOOMに軍配が上がるのではないかと思います。

![Screen Shot 2021-06-06 at 15.17.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694541/e3d2b1c9-6783-20b2-5d2a-0b1b289c55c1.png)
Cyber Detective CTF に挑戦

# Cyber Detective CTF とは
Cyber Detective CTF は公開情報を使ったOSINT(open-source intelligence)に特化したCTFです。OSINT(オシント)とは諜報活動の種類の一つです。諜報活動というと「スパイ」を連想する人が多いかもしれません。これは諜報活動の中でもHUMINT(ヒューミント)に分類されるもので非合法的な活動を行うこともあります。一方でOSINTは、合法的に入手できる公開されている情報(SNS、ニュース、政府の公式発表等)を情報源とし、分析を行うのが特徴です。

# writeupについて
日本語のwriteupが少ない印象だったので英語の勉強になるかもしれません。
オリジナリティを出すために、自分がつまずいたところは特に詳しく書くように心がけるました。

# Cyber Detective CTF の始め方
<https://ctf.cybersoc.wales/> でメアドとパスワードを登録．

# 各問のヒントへのリンク
1. [voteforme](https://qiita.com/guchipon/items/f373f2bf984ec2998336)
RaspberryPiのmicroSDの作成方法

#RaspberryPiのmicroSDを作成する手順
何度もOSを作成することが多く，備忘録としてまとめておきます．

##手順
1. Raspberry Pi Imagerをダウンロードし，実行する
2. boot フォルダに'ssh'フォルダを作成する
[mt08さんのコメント](https://qiita.com/scralet_investigator/items/8973fdeabfc4c1b9eeba#comment-dfb133d1e7ba52fdb23b)より，Raspberry Pi Imagerの設定変更可能とのことです


3. wpa_supplicant.conf を boot フォルダに作成する

```shell:wpa_supplicant.conf
   country=JP
   ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
   update_config=1
   network={
       ssid="xxxxxxxxxxxxxx"
       psk="xxxxxxxxxxxxxxxxx"
   }
```

4. ARPテーブルを更新する(RaspberryPiのIPアドレスを調べる)

5. Raspberrypiにssh接続することができます
LightGBMをOptunaでチューニング

# LightGBMをOptunaでチューニングする

## 前提条件
Python 3.7

## Optunaでチューニング
 `import`部分を書き換えるだけ。　　
これで、KaggleのHouse Pricesコンペの結果が0.13120 -> 0.12557に改善した。

**変更前**

``` Python
 import lightgbm as lgb
```

**変更後**

``` Python
 import optuna.integration.lightgbm as lgb
```

## 参考
[LightGBMとOptunaを導入・動かしてみる](https://kiseno-log.com/2019/11/05/lightgbm%E3%81%A8optuna%E3%82%92%E5%B0%8E%E5%85%A5%E3%83%BB%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/ "LightGBMとOptunaを導入・動かしてみる")
voteforme ヒント (Cyber Detective CTF)

# 1 voteforme
![2021-04-10-16-42-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1548368/af0c1877-f6d3-3524-f60a-81404cf8f7ed.png)
問題文を順に読んでいきます。まず、ある Twitter アカウントへのリンクが表示されています。次に「政治は少しつまらないお題だと思うかもしれない」「Jamesがここで(Twitter上でという意味か？)支持しているアメリカの政党は何でしょう」これが今回の問いですね。

## アプローチ
まずはTwitterアカウントを見てみよう．<https://twitter.com/jammymarkson>
![2021-04-10-17-22-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1548368/f2427937-b8de-853d-6282-1536808d04be.png)
英語を使っている人は世界中にいますが、とりあえずイギリス人かアメリカ人の可能性が高いのではないでしょうか。国籍を調査することもOSINTでは重要だと思います。さて、政治的なツイートを探してみると二つほど見つかります。まずは1つめ  
![2021-04-11-20-02-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1548368/8246efe6-a660-5ad6-824d-67a596709888.png)
まずは、何かに対して驚いた！(おそらく批判的なニュアンス)というツイート。何に対してかというと、引用元の記事の見出しからトランプ政権の予算(案?)に対してだといえます。これだけで，トランプ=共和党だから，共和党じゃない方の有力な政党(お察し)を支持しているのではないか？と推測できます。
では2つめ
![2021-04-11-20-09-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1548368/6039c271-7c59-ded7-08f6-1754aaa3b4a9.png)
「miss this guy like crazy」 誰を懐かしんでいるのか？ 引用しているのオバマ前大統領のツイートです。これでJamesがどの政党を支持しているか分かったでしょう。オバマ大統領はトランプ大統領の一つ前の大統領です。オバマ大統領は共和党ではない方の有力な政党(お察し)でしたね。
余談ですが，アメリカでは現役の大統領も前大統領も，大統領経験がある人は「president ~」と呼ぶ習慣があるそうです。「前大統領」だからといって「former president」とか呼ばずに、全員「president ~」と呼ばれます。

## まとめ
最初の問題なので分かりやすかったのではないでしょうか。でも現実的に、どの政党を支持していそうか、というような調査は人物像を調べるうえでは非常に重要かもしれないですね。
[Writeup一覧](https://qiita.com/guchipon/items/1f0bfc552bce94a2581b)
文字コードが違うことによる文字化けについて

### 文字→バイト列の変換図

![unicode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681029/5b4cad6c-8876-bd97-0aa9-f35a1f6950c8.png)



### unicode
「符号化文字集合」とい呼ばれるも、文字に対して数字が割り振られたものです。
下記がunicode変換表。

https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7%E8%A1%A8

ここで割り振られたコードポイントを、コンピュータが理解できる数字に変換する符号化方式がunicodeに用意されています。代表的なのが、`utf-8`、`utf-16`、`utf-32` です。


### コードポイント
文字に対応する数字を16進数で表したもの。


### utf-8
**Unicodeの符号化方式**。文字にunicodeで紐付けられたコードポイントと呼ばれる数字を、8ビット方式の数字のバイト列にエンコード（変換）する際のルールです。

以下のような特徴があります。
- UTF-8はほぼ全ての国の文字に対応しているため文字化けがおきずらい
- 日本語の場合は3バイト以上使うため、Shift_JIS、EUC-JPなどと容量を比較すると1.5倍程度に容量が大きくなる


### バイト列
8桁の0か1の整数。
一桁を1ビットと呼び、この1ビットには0か1の**２進数**しか入りません。つまり1ビットなら2通り、8ビットなら0から255までの256通りの数字を表現できます。

「変換されるイメージがわかない・・」という方は、下記ツールで2進数、10進数、16進数、の切り替えができます。

https://hogehoge.tk/tool/number.html

### 文字コードが違うことで文字化けが起きる理由

設定された文字コードが違うことで、文字が割り当てられていない数値が渡されたり、意図しない文字として認識されることが原因です。

つまり、「**HTMLファイル自体の文字コードと、ブラウザが解釈した文字コードが異なる**とき」に文字化けが起きます。例えば、Shift_JISで保存されたHTMLファイルをブラウザがUTF-8だと認識し、UTF-8で表示し用途した時に、文字化けが発生します。


# 参照記事
- [「文字コード」と「文字エンコード」の違い](https://wa3.i-3-i.info/diff16moji.html)
- [unicode変換表](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7%E8%A1%A8)
sudoにエイリアスを貼って、開発環境では気楽に実行する

私は開発環境等のみ`.bashrc`に下記のようなエイリアスを貼って使っています。

```sh:.bashrc
alias s='sudo'
```

この`s`は**気軽に実行して良い`sudo`**として使っています。

たとえば`$ sudo apt upgrade nginx`だったり`$ sudo shutdown -h now`を実行したい時。本番環境と開発環境とを間違えて実行してしまったら大変です。`$ s shutdown -h now`は気楽に実行してよく、誤って本番環境に実行してしまったとしても何も起こりません。
RailsからHerokuにデプロイしようとしたらerror: failed to push some refs to 'https://git.heroku.com/xxx.git'というエラーが出た

#開発環境
macOS Catalina
Rails 6.1.3.2
Ruby 2.6.7

#Herokuにデプロイしようとするとエラーが出る

RailsからHerokuにデプロイした際に以下のようなエラーが...

```
error: failed to push some refs to 'https://git.heroku.com/xxx.git'
```

プッシュに失敗しましたと出ています。


#解決方法
ブラウザからHerokuにログインし、作成したアプリケーション画面のOverviewタブの
![スクリーンショット 2021-06-06 15.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1101177/4e987a72-18ec-d81b-364e-b5efb309de88.png)

右側にある「Latest activity」の「Build failed」となっているアクティビティの「 **View build log**」をクリック。
するとこのような記載がありました。

```
-----> Building on the Heroku-20 stack
-----> Determining which buildpack to use for this app
 !     Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used.
			Detected buildpacks: Ruby,Node.js
			See https://devcenter.heroku.com/articles/buildpacks#buildpack-detect-order
-----> Ruby app detected
-----> Installing bundler 2.2.16
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.6.7
-----> Installing dependencies using bundler 2.2.16
       Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
       Your bundle only supports platforms ["x86_64-darwin-19"] but your local platform
       is x86_64-linux. Add the current platform to the lockfile with `bundle lock
       --add-platform x86_64-linux` and try again.
       Bundler Output: Your bundle only supports platforms ["x86_64-darwin-19"] but your local platform
       is x86_64-linux. Add the current platform to the lockfile with `bundle lock
       --add-platform x86_64-linux` and try again.
 !
 !     Failed to install gems via Bundler.
 !
 !     Push rejected, failed to compile Ruby app.
 !     Push failed
```

エラー文を日本語訳して抜粋すると
>バンドルはプラットフォーム["x86_64-darwin-19"]しかサポートしていませんが、あなたのローカルプラットフォームはx86_64-linux です。
現在のプラットフォームをロックファイルに追加するには、`bundle lock--add-platform x86_64-linux`でロックファイルに現在のプラットフォームを追加して、もう一度試してみてください。
>

となっており、その通りに実行。

```
% bundle lock--add-platform x86_64-linux
```

そして変更を忘れずにコミットする。

```
% git add .
% git commit -m 'Add platform'
```

再度Herokuにデプロイ。

```
% git push heroku master 
```
無事にデプロイできましたー！！！
【Java】関数型インターフェース(Function)の使い方

# Functionインターフェースとは？
Functionは1つの引数（Type T）を受けて、1つのオブジェクト（Type R）を返す関数型インターフェースです。

```java
public interface Function<T, R> {

    R apply(T t);
}
```

# 使い方
以下の例では、`func1`の`apply()`メソッドに`Hello`を引数として渡すことで、`Hello World!`が返されます。

```java
import java.util.function.Function;

public class FunctionExample1 {

    public static void main(String[] args) {

		Function<String, String> func1 = x -> x + " World!";

        String result = func1.apply("Hello");

        System.out.println(result); // Hello World!
    }
}
```
以下は、匿名クラスでFunctionインターフェースを使用する例です。

```java
import java.util.function.Function;

public class FunctionExample2 {

//不規則なリストを作成
List<Integer> randomNumbers = new ArrayList<>(Arrays.asList(378,121,190));

//リストをソートするメソッドを定義
List<Integer> sortedList = new Function<List<Integer>,List<Integer>>() {
	@Override
    public  List<Integer> apply(List<Integer> randomNumbers ) {
		Collections.sort(randomNumbers);
		return randomNumbers;
    }
//不規則なリストを引数として渡す
}.apply(randomNumbers);

//ソート済のリストを出力
for (Integer sortedNum:sortedList) {
	System.out.println(sortedNum); //121 190 378
    }
}
```

#参照
[Java Platform SE8 #Function](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Function.html)
SenseHAT でスペクトログラム表示

今までと趣向を変えて、今回は音声を扱ってみました。思いついたのが、瞬間ごとの周波数分布を表示するスペクトログラムを、SenseHATの画面で出してみるというものです。結果が正しいかちょっと怪しいですが…それっぽくは出来たかな？

![IMG_0046.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238815/94f3da5c-b441-f856-f338-dab408a4ac9a.jpeg)

なお、今回RaspberryPiは表示のみで、画面として使いました。フーリエ変換などはPC側でやっており、その結果（単位時間ごとの周波数分布の配列）をWebSocketでRaspberryPiへ送ります。なぜかというと、RaspberryPiにlibrosaという音声系ライブラリのインストールが出来なかっただけです。。が、今となってはこの表示と処理を分けた構成もアリかなと思えます。

参考：https://jorublog.site/python-voice-analysis/

それにしても、scipyは初めて使いましたが、便利ですねー。

以下は、PC側で実行した解析処理のコードです。最終的に、変数`amp_msg`をWebSocketでRaspberryPiへ送ります。

```python
import scipy.io.wavfile
import numpy as np
import librosa

def analyze(filename, timespan=0.001, timerate=0.1):
    rate, data = scipy.io.wavfile.read(filename)
    data = data / 32768
    time = np.arange(0, data.shape[0]/rate, 1/rate)  

    fft_data = np.abs(np.fft.fft(data))    
    freqList = np.fft.fftfreq(data.shape[0], d=1.0/rate)  

    fft_size = 1024
    hop_length = int(fft_size / 4)

    cols = 8
    dBMax = 100
    dBMin = -100
    tpitch = int(rate*timespan)
    timecount = int(len(data)/tpitch)
    timecount = int(timecount*timerate)

    amp_msg = list()
    for f in range(timecount):
        tstt = f*tpitch
        tend = tstt + tpitch
        amplitude = np.abs(librosa.core.stft(data[tstt:tend], n_fft=fft_size, hop_length=hop_length))
        log_power = librosa.core.amplitude_to_db(amplitude)
        fpitch = int(log_power.size/8)
        amp = np.ndarray(cols)
        msg = ''
        for p in range(cols):
            stt = fpitch*p
            end = stt + fpitch
            freq = np.max(log_power[stt:end])
            freq8 = int(np.ceil( (freq-(dBMin))/(dBMax-dBMin)*cols ))
            amp[p] = freq8
        amp_msg.append(
            str(int(amp[0])) + ',' +
            str(int(amp[1])) + ',' +
            str(int(amp[2])) + ',' +
            str(int(amp[3])) + ',' +
            str(int(amp[4])) + ',' +
            str(int(amp[5])) + ',' +
            str(int(amp[6])) + ',' +
            str(int(amp[7]))
        )
    return amp_msg
```
Pythonによる手取り計算

# 概要
月ごとの手取り額をpythonで簡単に概算できるようにしました。
結果は以下の通りです。
![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323237/30e8ed3c-740f-8060-b279-e26139ffc9db.png)


# はじめに
新卒でお給料をもらったものの、実際には額面から色々と引かれることを実感したこの頃です。
そこで、
 - どのくらいのお給料が税金や社会保障費となっているのか
 - 今後額面が増えると仮定して、実際にどの程度手元に残るのか
を可視化しました。

# 仕様等
実装は[こちら](https://github.com/isokiso/FinancialTool])をご覧ください。
環境：Python 3.7.4
入力変数：額面, 年齢, 都道府県, 交通費, 残業代, 扶養人数
出力：手取り、控除費用（グラフ順に健康保険費用、介護保険費用、厚生年金、雇用保険、所得税、住民税）

# おわりに
表形式で羅列されたものは存在します。しかし、より詳細かつ直感的にグラフ化されたものは見つからなかったので、自分で計算を実装し可視化することにしました。
以下のサイトを計算の参考に用いました。
https://funjob.jp/keisan/gekkyu/
実装はかなり地道ですが、勉強になったので良しとします。

# 注意
ボーナス等は考慮しません。
住民税は前年の収入に対してかかるので、正確ではありません。
また、原点付近の挙動も正しくありません。
参考までにお使いください。
Kaggle のHouse Prices で実施したデータ前処理(備忘録)

## KaggleのHouse Pricesコンペで実施したデータ前処理(備忘録)
### 前提条件
Python3.7.10を使用
### 1.目的変数の分布の確認  
目的変数の分布が正規分布になっているかどうか確認し、正規分布になっていなかった。
`log1p`関数で、目的変数で変換し、目的変数の分布を確認。学習を行う際に、正規分布にした方が、精度が上がるらしい。
※`log1p`関数は、$\log(1+x)$の演算を行う関数 
 
**`log1p`演算前)**  正規分布になっていない。
![seaborn_distplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583464/2d11c807-c96d-4502-797b-acfc16b193b5.png)!

**`log1p`演算後)** ほぼ正規分布になった
![seaborn_distplot_after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583464/1ee078ed-d8cc-60c4-f144-26d208313539.png)

### 2.欠損値の補完
欠損値を確認し、データ補完を実施した。
補完方法は、None/ゼロ/最頻値/平均値/中央値など。  

| 補完方法 | コード |
|---|---|
| None | `df.fillna({colum_name : 'None'}, inplace=True)`|
| ゼロ | `df[colum_name].fillna(0, inplace=True)`|
| 最頻値 | `df[colum_name].fillna(df[colum_name].mode()[0], inplace=True)`|
| 平均値 | `df[colum_name].fillna(df[colum_name].mean(), inplace=True)`|
| 中央値 | `df[colum_name].fillna(self.df[colum_name].median(), inplace=True)`|

※dfはPandasのDataFrame

### 3.外れ値の除去
各列のデータを箱ひげ図などで確認し、外れ値を除去する。以下はLotFrontageが160以上の場合、160に値を変更するプログラム

``` Python
df.loc[df['LotFrontage'] >= 160,  'LotFrontage'] = 160
```

### 4.数値データのカテゴリ化
数値データであるが、実際は、カテゴリデータである場合。数値データを文字列に変換する。

``` Python
df['MSSubClass'] = df['MSSubClass'].apply(str)
```
GitHubのイベントをGoogleAppScriptでWebhook

# GoogleAppScriptの準備
1. スプレッドシートを新規作成
1. スクリプトエディタを開く
   ![スクリーンショット 2021-06-06 14.21.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/8db84ed7-0a74-29a2-bc30-f61b42d42e46.png)
1. スクリプトエディタでGETとPOSTのイベント関数を用意<br>
   doPost関数の中でwebhookした後の処理をコーディングする
   ![スクリーンショット 2021-06-06 14.41.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/1e8288f0-6e94-950a-dd30-d20a49b363df.png)
1. デプロイする
 1. 右上のデプロイより新しいデプロイをクリック
  ![スクリーンショット 2021-06-06 14.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/0cb405b7-4a53-f748-e5ac-aa503ca84a3b.png)
 1. ウェブアプリをクリック
  ![スクリーンショット 2021-06-06 14.54.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/d64e90ea-ef59-1e50-2f9e-fd146835416c.png)
 1. アクセスできるユーザーを全員にしてデプロイをクリック
  ![スクリーンショット 2021-06-06 14.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/f6eb63d4-69c5-e748-e870-668014dc1ae5.png)
 1. ウェブアプリのURLをコピー
  ![スクリーンショット 2021-06-06 14.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/82c229ec-fd7e-b417-d00e-094b7e92bd15.png)

※デプロイ後にスクリプトを変更すると、再デプロイが必要になり、またウェブアプリのURLも変わるため、GitHubに設定したPayload URLを変更する必要がある

# GitHubの設定
SettingsのWebhooksからAdd webhookより新しいwebhookを追加する
Payload URLに先ほどコピーしたウェブアプリのURLをペーストする
最下部にあるAdd webhookで登録する
![スクリーンショット 2021-06-06 14.06.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/0502aa8d-f1d9-b186-e2cf-f29bd7d50d47.png)
Firefoxのアドオン審査をスムーズに通過するために気をつけること

気をつけること・・・というか、実際に指摘されたことのまとめです。

# 拡張のターゲットを明確にする

Firefoxのアドオンは用途があまりに限定的だと弾かれてしまうようです。どういう人を対象としたアドオンなのかを明確に記述すると良いようです。アドオンをストアで公開する時は、開発した機能をある程度一般向けに公開したい時だと思いますので、それを素直に書けばよいと思われます。

# テスト方法を記述する

実際にどうやって使うのか、その方法を記述しないと、「テスト方法がわからないから教えてくれ」と怒られます。審査担当者宛のホワイトボードという所にテスト方法を書くと良いようです。すべての機能の厳密なテストを行っているわけではなさそうですが。

# third-party製ライブラリは改変せず使用する

jQueryなどのライブラリを含めるときは、改変せず使用する必要があります。リネームもおそらく不可で、怒られます。また、使用したバージョンのソースコードが閲覧できるURLを合わせて提出する必要があります。詳しくは[公式ドキュメント](https://extensionworkshop.com/documentation/publish/third-party-library-usage/)を参照してください。

# ページに要素を追加するときは、危険なコードが埋め込まれないよう対策する

特にユーザーに入力させたものなどを追加するときなど、innerHTMLなどを対策無しで使ってしまうと、悪意あるスクリプトを挿入される恐れがあります。それを防ぐために、innerText等を用いるか、`DOMPurify`のようなライブラリを使用して、挿入する要素を安全に保つ必要があります。jqueryを使う際はhtml()に直接DOMを書くのではなく、多少面倒でも要素を生成し、appendなどのjqueryのメソッドを用いるのが安全です。

# おまけ

アドオンの説明などは日本語での記述が可能ですが、審査レビューは全て英語なので、おそらく審査してるのは日本人ではないと思われます。自動翻訳などを使っていると思いますので、主語と述語のはっきりした翻訳向きの文章にすると、心象がちょっとよくなる・・・かもしれません。答案用紙はきれいに書け程度の話ですが。

また何か怒られたら追記します。
株式会社div「UNCOMMON」第5期卒業

#第5期UNCOMMONを終えて

僕は株式会社divが運営している。オンライン学習「UNCOMMON」に入構し6/5に修了しました。
すばらしい学習体験を終えて、今後の人生が楽しみで仕方がないです。

僕がUNCOMMONを受講した理由は2つあります。
・漠然と社長になりたいけど、どうしたら良いのか分からない。
・一流のビジネスマンはどういう事をしているのか気になったこと。でした。
正直かなり不安でした。金額も高い。YouTubeでも学習が十分じゃないのかな等考えていました。
しかし、受講後はやってよかったな、今後の人生が変わっていく明確なビジョンが見える。
様々な効果が出ていました。

僕が学習をしていてこれは良かったなと思う学ばせ方は3つあります。
・ペアワークであること
・自ら考え行動せざるを得ない環境づくり
・小手先のテクニックではなく人のマインドを変えるところ

逆によく感じなかったことは2つあります。
・学習についていけない人が居たとしても運営側は分からず、講座が進んでいく。
・変化のきっかけはもらえるものの、自分で出来る人じゃないと脱落する。

#メリット
##◎ペアワークであること
　僕は話すことがそんなに得意ではないと思っているので、ペアワークという自体が不安でした。
気まずい雰囲気になり、あまり喋れず意味がないのではないかと思っていました。
しかし、やってみると違うことがすぐに分かりました。
まずイメージしていた勉強しようとしている人を嘲笑う行為は絶対発生しないことです。
参加者は皆、人生を変えたい、今の自分に何かしら不満がある、このままではいけないと
思っている人しか講座に参加しないので、やる気満々の人ばかりでした。
仮に消極的だとしても周りの人が引っ張ってくれ、ペアの人に迷惑をかけたくないと思う気持ちがでてくる。
少なくとも私は、そうでした。
私自身一人でも別に良いじゃないかと思っていました。
しかし、仲間に迷惑をかけたくない、仲間が頑張っているから僕も頑張ろうと思いました。
やってみるとわかります。僕も今後一緒に学習する人を見つけて、学習していきたいです。

##◎自ら考え行動せざるを得ない環境づくり
　日々のワークはアウトプットが当たり前で行われます。
これにより必ず自分の意見を自分で考え、相手に伝える事が発生します。
時間も決まっており、簡潔にわかりやすく伝えなければいけません。
僕はかっこつけたがりのところが多少あるので相手より良い意見を伝えてやろうと考えていました笑。
やはりここでも自分の意見はありませんでは、相手に申し訳ないという気持ちが出てきました。
必死になって考えました。負けるわけにはいけないと日々強く思いました。
　このアウトプット中心のワークで日々のアウトプットが重要なのだなと身に染みて分かりました。
今後はつたない文章でも良いので何かしら書こうと決めました。

##◎小手先のテクニックではなく人のマインドを変えるところ
　毎朝30分瞑想とメモ書きを行いました。瞑想の効果はまだ感じられないものの、
今後も継続して瞑想を続けたいです。
　メモ書きがもたらしてくれる恩恵は大きかったです。自分の頭の中をとにかく書きました。
「えーと」「まずはあれだよね」「〜だよねー」「これもあったな」「えーなんだろう」という
話し言葉も書いていくと、自然と自分の意見がぬるぬると出てきました笑。
そして、テーマが今後の人生を考える内容になっているので、自分の人生を考えさせられます。
ワークを通して、自分の夢を明確に出来ました。

#デメリット
##学習についていけない人が居たとしても運営側は分からず、講座が進んでいく。
　時間内に終わらない人、サボった人は置いて行かれます。
私は全て参加したのでわからないのですが、恐らくアフターフォローはないのでは？
発表原稿を書くワークがありました。ペアの方は原稿書けず、アウトラインだけでアウトプットしていました。
　宿題はありませんと謳っているものの、終わらなければ次のワークまでに終わらせなければ置いて行かれます。
その方は発表の時に間に合わせてきました。しかし、出来ない人は脱落するのではないかなと思いました。
あくまで自己責任ですね...

##変化のきっかけはもらえるものの、自分で出来る人じゃないと脱落する。
　これ以上はないのではないかというくらいの変化の環境はありました。
少なくとも僕の頭ではこの環境は思いつきませんでした。
しかし自分の心に変化を与えられるのは、自分しかいません。
きっかけはもらえるものの、自分の心、マインドが変わらないと見える世界は変わりません。
もしかしたら、なんとなく変わりたいと思っている人は変われないのかもしれないです。

#まとめ
　僕は1ヶ月前の自分とは違う自分になれました。
変わっていなかったらまずこのような記事を書こうとも思わなかったでしょう笑。
この文も分かりづらいかもしれないものの、前の自分とは見違えるほど書けています。
　受講すると間違いなく変われるとは言えないです。あくまで個人の問題なので。
しかし、これ以上ないのではないかと言うくらいの環境は整っていました。
周りの方も上辺だけではなく本心で受講してよかったと言っていました。
この記事が皆さんの変化のきっかけになって頂ければ幸いです。
【TeraTerm】設定ファイル消失事件

##概要
**TeraTermの設定ファイルが突然消えた！**
と思ったら別のフォルダで発見。

##事象
職場の環境で、TeraTermMenuからBIG設定(黒背景・白文字・文字サイズ大きめ)で踏み台サーバにログインしようとしたら、謎の設定(白背景・黒文字・文字サイズ普通)でログインされた。
いったん切断して、別の設定(黒背景・白文字・文字サイズ普通)で開こうとしたが、これも先ほどと同じ謎設定でログインされた。

##対応
**踏み台サーバへのログインはできているが、設定ファイルが適用されていない**ことから、設定ファイルの格納先である`C:\Program Files (x86)\teraterm`を確認。**設定ファイルがすべて消えていた。**参照先の設定ファイルが見つからないため、デフォルト設定(白背景・黒文字・文字サイズ普通)になったと考えられる。

「TeraTerm 設定ファイル 消える」で検索してみたところ、**WindowsのVirtualStore機能**なるものが疑わしい。

https://memo.furyutei.work/entry/20140112/1389501754

上記リンクを参考に、**別フォルダで無事に発見。**
`%UserProfile%\AppData\Local\VirtualStore\Program Files (x86)\teraterm`
※AppDataフォルダは隠しフォルダになっているので、`Alt＋D`でパスを直接指定して階層移動。

コピーして`C:\Program Files (x86)\teraterm`に貼り付けて、再度TeraTermMenuからのログインを試し、問題なく設定ファイルが読み込まれることを確認。

##原因
思い当たることは2つ。
・朝イチで職場のドメイン参加に失敗して、一時プロファイルでログインさせられたこと。
(すぐに再起動して本来のドメインに参加できた)
・6/1に発生したので、6月になって初めてTeraTermを使ったこと。
(他のメンバーからは同様の報告が上がってないので、おそらく関係ない)

##対策
原因がハッキリしないので、**発生後の対策を考える。**
・`C:\Program Files (x86)\teraterm`に、VirtualStoreフォルダへのショートカットを配置。手動復旧を楽にするため。
・Qiitaに書き残す。メンバーを含めたTeraTermユーザに周知するため。
・ローカルセキュリティポリシーで無効にする。
※職場のPCの場合は、変更する前に管理者に要相談。たぶん断られるけど。

https://laboradian.com/windows-virtualstore/#3
App Engine(GAE)でサービスごとに複数ドメインを使用する方法

## GAEのサービス

GAEには「サービス」という概念があって、アプリをデプロイする際にサービス名を指定することで、複数のアプリを１つのプロジェクトで同時に立ち上げることができます。
また、各サービスにドメインを割り当てることもできるので、複数のアプリにそれぞれ異なった複数のドメインを割り当てることも可能です。

## app.yamlでサービスを設定する
最初に、アプリごと別のサービスとして立ち上げるためにはapp.yamlにサービス名を指定する必要があります。

```app.yaml
service: SERVICE_NAME
runtime: nodejs10
# ...
```

これをデプロイすればGAEにサービスが立ち上がります。（コンソールのGAE⇨サービスで確認可能）

## dispatch.yamlでルーティングルールを変更する
ここからようやく本題ですが、
dispatch.yamlを使ってドメインんとサービスを紐づけます。

```dispatch.yaml
dispatch:
  - url: "*www.example.com/*"
    service: default # ターゲットとなるサービス名
  - url: "*app.example.com/*"
    service: backend # ターゲットとなるサービス名
```

この設定は1つのプロジェクト内で共通の設定とされるため、この場合だと、defaultかbackendどちらか1つのディレクトリからデプロイしておけば正しく動作します。

あとは、DNSでそれぞれのドメインをGAEサーバに向ければ完了です。

## デメリット
GAEで複数のサービスを立ち上げるのはとても便利ですが、その分注意しなければならないデメリットもあります。
コストの最適化のためにも以下の点に注意して適宜Cloud Functionを利用するなり他の選択肢を取ることも考慮すべきです。

1. サービスの分だけインスタンスが立ち上がる。
2. 価格が高くなりがち
Node.js: 高齢者等の都道府県別接種回数を数える

こちらにあるデータを加工して、高齢者等の都道府県別接種回数を数えます。
[新型コロナワクチンの接種状況（高齢者等）](https://cio.go.jp/c19vaccine_dashboard)
「都道府県別接種回数詳細」の prefecture.ndjson　をダウンロードします。

```js:sum_up.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	sum_up.js
//
//						Jun/06/2021
// ---------------------------------------------------------------
'use strict'

const ndjson = require('ndjson')
var fs = require("fs")

const file_in=process.argv[2]
const file_json=process.argv[3]
console.log (file_in)

var first = Array(47)
var second = Array(47)
first.fill(0)
second.fill(0)

fs.createReadStream(file_in)
	.pipe(ndjson.parse())
	.on('data', function(obj) {
	const pref = obj.prefecture
	const index = parseInt(pref,10) - 1
	if (obj.age == "65-")
		{
		if (obj.status == 1)
			{
			first[index] += obj.count
			}
		else if (obj.status == 2)
			{
			second[index] += obj.count
			}
		}
  })

	.on('end', function() {
		var data_out = new Object()
		for (var it in first)
			{
			const jt = parseInt(it) + 1
			const code_pref = ("00" + jt).slice( -2 )
			var unit_aa = new Object()
			unit_aa["first"] = first[it]
			unit_aa["second"] = second[it]
			data_out[code_pref] = unit_aa
			}

		const json_str = JSON.stringify(data_out)
		fs.writeFile (file_json,json_str,function (err)
	{
	if (err) {
		console.error ("Error on write: " + err)
		}
	else {
		console.log("File written.")
		console.error ("*** 終了 ***")
		}
	})	
//		console.log ("num_first = " + first[8])
//		console.log ("num_second = " + second[8])
		console.log("*** end ***")
	})


// ---------------------------------------------------------------
```

実行コマンド

```bash
export NODE_PATH=/usr/lib/node_modules
/sum_up.js prefecture.ndjson korei.json
```

次のファイルが作成されます。


```json:korei.json
{
  "10": {
    "first": 131155,
    "second": 13156
  },
  "11": {
    "first": 364873,
    "second": 24304
  },
  "12": {
    "first": 327663,
    "second": 24921
  },
  "13": {
    "first": 741621,
    "second": 45711
  },
  "14": {
    "first": 367928,
    "second": 22566
  },
（省略）
```

参考ページ
[Node.js: ndjson の使い方](https://qiita.com/ekzemplaro/items/3e1bc65b966e8d54ec88)
PysimpleGUIラジオボタンの使い方


### はじめに

PysimpleGUIのラジオボタンの配置の例題はいくつかあったのですが、実際の使い方の例があまりなかったので、覚えとして記載します。

ラジオボタンの使い方ではないですが、こちらのチェックボックスの使い方を参考にしました。
[PySimpleGUIで動的にチェックボックスを作成して選択した値を取得してみた ](https://nanpole.com/pysimplegui-dynaminc-control/110/)


```python
import PySimpleGUI as sg

sg.theme('Dark Blue 3')

radio_dic = {
    '-1-': 'aaa',
    '-2-': 'bbb',
    '-3-': 'ccc',
}

# Create radio Buttons by list comprehensions
layout = [
    [sg.Text('select input file', size=(45, 1))],
    [sg.Text("file"), sg.InputText(key="-file-")],
    [sg.Radio(item[1], key=item[0], group_id='0') for item in radio_dic.items()],
    [sg.Submit(key='-submit-')],
    [sg.Output(size=(45, 10))]
]

window = sg.Window('Example for radio button', layout)

while True:
    event, values = window.read()

    if event is None:
        break

    if event == '-submit-':
        print(values)
        print(values['-1-'],values['-2-'],values['-3-'])
        window['-2-'].update(True)


window.close()
```

### 実行例

![sg_radio.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/39f486dd-18ee-d94e-c389-eeafd8b04719.png)

### コードの説明

`radio_dic`でラジオボタンの名前と、キーの辞書形式を作成します。
`layout`のラジオボタンをリスト内包表記で作成します。この時Radioボタンは、group_idを指定しないといけないので、idを指定します。キーはpysimpleGUIの習慣で`-`で囲んでいます。（例えば、`"-file-"`など）
リスト内包表現を使わないで一つ一つ設定する場合には、デフォルト（True、False)を設定することができます。
ラジオボタンは、同じグループのうち一つだけ`True`になります。
`Submit`ボタンを押すと、`values`に入っている値が`OUTPUT`に表示されます。`values`は辞書型ですので、キーと値が表示されます。その次の`print`で、キーを指定した値が表示されます。
次の`window`表示されているウィンドウを指定して、値をアップデートしています。最初はラジオボタンにチェックが入っておらず、すべて`False`になっていますが、`Submit`を押すと、`bbb`にチェックが入ります。また`Submit`を押すと今度は、`-2-`が`True`になります。