OmniAICreator/Qiita-1.07M huggingface dataset:
firewalldで特定IPアドレスのみsshを許可する

#はじめに
腐るほど記事があるが、ピンポイントでこれをやろうとすると結構手間だったので、このトピックに絞って記載する。

#環境
- CentOS8

#手順
ファイアウォールサービスを有効にする

```
systemctl enable firewalld.service
```

ファイアウォールサービスを起動する

```
systemctl start firewalld.service
```

許可されているサービスを表示する

```
firewall-cmd --list-services --zone=public
```

sshがデフォルトで許可になっているが、今回は限定するのでサービスから消す

```
firewall-cmd --remove-service=ssh --zone=public --permanent
```

richルールにより特定IPアドレス（ここでは192.168.11.29)のみ許可

```
firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.29" port protocol="tcp" port="22" accept"
```

リロード

```
firewall-cmd --reload
```

設定確認

```
[root@localhost ~]# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="192.168.11.29" port port="22" protocol="tcp" accept

```

##別端末からポートスキャンで確認
接続が許可されている端末、されていない端末からnmapでポートスキャンし、許可されている端末からのみ22番が見えることを確認する。

```
[kimisyo@localhost ~]$ nmap -p 1-500 192.168.11.24
Starting Nmap 7.70 ( https://nmap.org ) at 2020-10-04 12:06 JST
Nmap scan report for 192.168.11.24
Host is up (0.62s latency).
Not shown: 498 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh

Nmap done: 1 IP address (1 host up) scanned in 38.56 seconds
```

#参考
- https://www.atmarkit.co.jp/ait/articles/1602/18/news019_4.html
- https://qiita.com/MATO/items/e8ae2b528fe9ddc4c25a
コマンドライン入門 メモ

[Aidemy](https://aidemy.net/)　2020/10/4
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、Progateのコマンドライン入門の投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

#コマンドラインについて
・コマンドラインとは、ターミナルなど、文字だけでコンピュータを操作するためのものである。
・コマンドラインにおける「自分が今いるディレクトリ」のことを__カレントディレクトリ__という。
・コマンドラインにおける「一番親の階層」のことを__ルートディレクトリ__という。
・コマンドラインにおける「作業の起点になるディレクトリ」のことを__ホームディレクトリ__という。

#各種コマンド
##ファイル/フォルダの作成/表示
・ファイル作成：__touch ファイル名__
・ファイルの中身表示：__cat ファイル名__
・ディレクトリ（フォルダ）の作成：__mkdir ディレクトリ名__
・ディレクトリの移動：__cd ディレクトリ名__
・ディレクトリ階層の表示：__pwd__
・ディレクトリの中身表示：__ls__
・1つ親のディレクトリに移動：__cd ..__
・ホームディレクトリに移動：__cd__

##ファイル/フォルダの移動/コピー/削除
・ファイルの移動：__mv ファイル名 移動先のディレクトリ名__
・ディレクトリごと移動：__mv ディレクトリ名 移動先のディレクトリ名__
・ファイル名の変更：__mv ファイル名 新ファイル名__
・ディレクトリ名の変更：__mv ディレクトリ名 新ディレクトリ名__
・ファイルのコピー：__cp ファイル名 コピーのファイル名__
・ディレクトリのコピー：__cp -r ディレクトリ名 コピーのディレクトリ名__
・ファイルの削除：__rm ファイル名__
・ディレクトリの削除：__rm -r ディレクトリ名__
HTML/CSS　メモ書き

[Aidemy](https://aidemy.net/)　2020/10/4
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、HTML/CSS　メモの投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

#HTML
##HTML CSS とは
・HTMLは文書構造を定義するもの。平たく言えばページそのもの。
・CSSはHTMLを装飾するもの。色をつけたり大きさを変えたりするなど。

##Webページについて（HTML）
・Webページ(body)は、大まかに分けて、ヘッダー、メイン、フッターの3つで構成される。
・ヘッダー:__\<header>\</header>__
・メイン:__\<div class="main">\</div>__
・フッター:__\<footer>\</footer>__

・見出し:__\<h1>\</h1>__ (h1~h6)
・テキスト:__\<p>\</p>__
・リンク:__\<a href="URL">\</a>__
・画像:__\<img src="画像" alt="画像が表示できない時の代替テキスト">__

・入力フォーム：__\<form>\</form>__ (method="POST"で画像をアップロード)
・ファイルのアップロード：__\<input type="file" name="file">__
・送信：__\<input type="submit" value="ボタンの文字">__

##CSS
・CSSファイルでは、HTMLの各要素に対して、以下のように記述して装飾する。
・クラスごとに装飾したい時は、__.クラス名__のように表記する。

```css
header {
    background-color: #76B55B;
    height: 60px;
    margin: -8px;
}
```

・各表現についてはProgate参照。
Elixirで関数の戻り値の型を確認する。



`i`コマンドを使います。


__下準備__

ローカルで下記コマンドを実行し、iexを起動します。

```bash
docker run -v $PWD:/app -w /app --rm -it elixir:1.10.4 iex
```

```elixir

datetime1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
                utc_offset: -14400, std_offset: 0, time_zone: "Asia/Tokyo"}
datetime2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
                utc_offset: 3600, std_offset: 0, time_zone: "Asia/Tokyo"}

```

__確認__

例えば`DateTime.diff`を確認します。

```elixir
iex(5)> i DateTime.diff(datetime1, datetime2)
Term
  18000
Data type
  Integer
Reference modules
  Integer
Implemented protocols
  IEx.Info, Inspect, List.Chars, String.Chars
```

こんな風に値と型などが分かります。
ferenOSでBoincを使う

今現在、Covid-19(新型コロナウイルス）が世界中で猛威を奮っています。
このウイルスに対抗する多くのプロジェクトが進行していることと思います。
グリッドコンピューティングによるボランティアのプロジェクトに「Boinc」というものがありまして、Boincでは、Covid-19に対抗するための研究に力を貸してくれるコンピュータ、ユーザを求めています。

**Boincホームページ：https://boinc.berkeley.edu**

今回は、Boincをインストールして、その中のプロジェクトの一つであるWorldCommunityGrid(WCG)に参加したあと、暗号通貨であるByteballのもらい方を解説します。（次回）今回の解説内容は、ferenOSだけでなく、Ubuntuベースの他のディストリビューションにも使えます。参考にしてください。
#Boincのインストール
次のコマンドを実行
`sudo apt install boinc-client boinc-manager`
BoincManagerを起動してWCGに参加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/449a784b-6334-4a52-866d-9abad9a6178a.png)
メールアドレス（アカウント名）とパスワードを決めてアカウントを作成。
これでひとまずBOINC,WCGプロジェクトに参加できました。
ただ、WCGはさまざまなプロジェクトまとめたオムニバスであるため、Covid-19以外のプロジェクトの解析プログラム（タスク）が落ちてくる場合があります。
その場合、**WCGのホームページ：<https://www.worldcommunitygrid.org/>**にアクセスし、さきほど作成したアカウントでログインします。下の画面通り、「マイプロジェクト」から"OpenPandemics-COVID-19"のみを選択すると、Covid19のタスクだけ解析することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/57cba35e-4a39-7b71-7b7b-a255530f7e41.png)

#GPGPUを使って解析
Boincのプロジェクトの中には、CPUだけでなくグラフィックボードのGPUを利用して解析を行うものもあります。（注意：WCGはGPGPUに対応してません。対応しているプロジェクトはBoincのホームページで確認して下さい。）
Nvidiaに対応しているプロジェクトのほうが多いので、今回はNvidiaで解析を行います。ferenOSでは、Nvidiaのドライバのインストールを支援してくれるPPAリポジトリ（ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic main）やアプリがもともと導入されています（ほんま便利やな・・・。最初は、わざわざNvidiaの公式サイトからドライバをDLしてインストールなんやらしようかと思いましたが、ferenOSにもともと用意してあるドライバのインストール方法でも解析に悪影響はありませんでした。（あくまで、こちらの環境下では）
ドライバマネージャアプリを起動したあと、任意のドライバを選択、適用して再起動します。そのあと、BoincManaegerにGPU対応のプロジェクトに参加すると、GPUでの解析に対応したタスクが落ちてきます。
引数のデフォルト値はimmutableなものにする(記事解説)

こちらの記事を自分にわかるように解説します。
同じ内容を書くことにはなりますがご容赦ください。
https://qiita.com/yuku_t/items/fd517a4c3d13f6f3de40

関数定義やクラスのinitでは引数のデフォルト値を設定できます。
この時、初期値を与えた引数の型がmutable型だった場合よろしくないことが起こります。

```初期値あり関数(よくない例).py
def foo(bar=[]): # List型はmutableだよ、気をつけて！
    bar.append('baz')
    print(bar)
```

これをデフォルト値で実行すると

```実行.py
>>> foo()
['baz']
>>> foo()
['baz', 'baz'] # あれ？
```

結果が変わってしまっている。
何故このようなことになるかというと、Pythonでは関数のデフォルト値は関数定義時にメモリが割り当てられるからである。
上記では、関数定義時に作成されたList型に対して、appendの操作を2度を行ったために、"baz"が2こ入ったのである。

この問題をクリアするには、
つまり、問題なくmutable型の引数に初期値を与えたい時には、関数定義時ではなく、関数呼び出し時にメモリが割り当てられるようにすれば良い。
つまり、関数内部で初期化を行う。

```初期値あり関数(よい例).py
def foo(bar=None):
    if bar is None:
        bar = []
    bar.append('baz')
    return bar
```


immutable型引数に初期値を与えることは、問題ないです。
参考: https://qiita.com/makotoo2/items/fc3a617882916f9775f5
Githubの脆弱性(vulnerability)アラートの対応

## 記事の目的
初学者の為、間違っているところはご指摘頂けると幸いです。
備忘録・アウトプット目的で投稿しております。
初学者で微力ながら、少しでもお役に立てればという気持ちもあります。

##Githubからの通知（メールにて）

![7d5e164d16c659f78495edebd0a4a08c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613599/898a54d8-af92-a994-c984-26b9465166b9.png)

セキュリティの脆弱性がある、actionviewを6.0.3.3にせよ。との通知。
ここで注意点ですが、Gemfile.lockと書いてますが、Gemfile.lockはBundlerが自動的に作成・更新するファイルなので、開発者が独自に編集してはいけません。（チェリー本P430から引用）。
変更する場合は、gemfileです。

##Github上のアラート情報

![719c7944626cdcd0c51db76d40092759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613599/27f37afa-9712-83b1-0d22-5687bf0174ca.png)

ここでも、actionviewを6.0.3.3にせよ、と言っている。

##対処
こちらの記事を参考にしてみる。
https://qiita.com/Nash-BETA/items/0d4e876cf9460778b985
しかし、actionviewは、gemfileにない。修正できんぞ。。

こちらの記事を参考にしてみる。
 https://reasonable-code.com/github-security-alert/
指示に従い、以下のようにupdateするも以下のようにversionはそのままです、と言われる。 6.0.3.3に変更できんぞ。。

```
$ bundle update actionview Bundler attempted to update actionview but its version stayed the same Bundle updated!
https://reasonable-code.com/github-security-alert/
```

以下のteratailの回答を参考にしてみる。
https://teratail.com/questions/249997　
https://teratail.com/questions/240417
actionviewを変更するには、rails自体のgemを変更する必要があると書いてある。

ここが解決のヒントとなりました！！
actionviewに依存関係のあるRailsのバージョンを上げます。

```
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
```

から

```
gem 'rails', '~> 6.0.3', '>= 6.0.3.3'
```

に変更して、bundle update。

```
$ bundle update
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...........
Using actionview 6.0.3.3 (was 6.0.3.2)
```

6.0.3.3に変更できているみたい。。
gemfile.lockを確認してみると。

```
actionview (= 6.0.3.3)
```

無事に変更できています！！
githubのアラート情報も無事消えておりました。
ダークモードをReact + Material-Uiで設定する

最近気付きました。

利用しているサービスほとんどがダークモードに対応しているという事に。そして、それを利用している事に…。

ということで、簡単にダークモードをReactで設定できないかと、調べるとめちゃくちゃ簡単なことがわかったので、共有したいと思います。


今回利用するのは【Material-Ui】

以下公式サイト↓
https://material-ui.com/

こちらでダークモードでサイト内検索をかけるとこちらに飛びます
https://material-ui.com/customization/palette/#dark-mode

簡単に言ってしまえば親コンポーネントにこれを設定するだけです。

```react:App.jsx

const darkTheme = createMuiTheme({
  palette: {
    type: 'dark',
  },
});
```

実際に適用したコード共に、もう少し具体的に説明します。

```react:App.jsx

import React,{useState} from 'react';
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";

const App = () => {
  const [answers, setAnswers] = useState([]);
  const [chats, setChats] = useState([]);
  const [currentId, setCurrentId] = useState("init");
  const [dataset, setDataset] = useState({});
  const [open, setOpen] = useState(false);
  const theme = createMuiTheme({
    palette: {
      type: "dark",
    },
  });
}

```

```react

return (
    <ThemeProvider theme={theme}>
      <section className="c-section">
        <CssBaseline />
        <div className="c-box">
          <Chats chats={chats} />
          <AnswersList answers={answers} select={selectAnswer} />
          <FormDialog open={open} handleClose={handleClose} />
        </div>
      </section>
    </ThemeProvider>
  );
```

まずは下記をインポートします

```react
import React,{useState} from 'react';
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
```
そして、themeという変数でpaletteのtypeを'dark'にします

```react
const theme = createMuiTheme({
    palette: {
      type: "dark",
    },
  });
```

最後に、return内でThemeProviderで囲み、theme={theme}を指定。さらに、<CssBaseLine />を入れることで、完成です。

```react
return (
    <ThemeProvider theme={theme}>
        <CssBaseline />
    </ThemeProvider>
  );
```

これで設定できるようになります。
簡単なので皆さんも是非。

ライトモードとダークモードの切り替えも簡単に行えるそうなので、出来たら追記します。
男女認識　メモ

[Aidemy](https://aidemy.net/)　2020/10/4
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、男女認識　メモの投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。


#男女認識1
##行うこと
・データ収集とデータクレンジングを行う。
・データ収集は、Keras内蔵のものではなく、オンライン上の画像をダウンロードして収集する。
・データクレンジングでは、画像を扱うOpenCVを使う。

##データクレンジングについて
・今回扱う男女の画像データのチャンネルは「b,g,r」の順番であるが、画像を扱うOpenCVにおいてはデータを「r,g,b」の順にしなければならないので、__cv2.split__でデータを3つに分割し、__cv2.merge__でデータの配列の順番を整えることが必要。

```python
img = cv2.imread('./6100_gender_recognition_data/male/Aaron_Eckhart_0001.jpg')
b,g,r=cv2.split(img) 
img=cv2.merge([r,g,b])
```

##画像の縮小
・__cv2.resize(画像,（縦,横）)__を使う。cv2.imwrite()で保存した後、plt.imreadで縮小した画像を図として取得し、plt.imshow()で出力。

```python
import cv2
import matplotlib.pyplot as plt
import numpy as np

img=cv2.imread("./6100_gender_recognition_data/male/Aaron_Eckhart_0001.jpg")
my_img=cv2.resize(img, (50, 50))
cv2.imwrite("resize.img",my_img)
img=plt.imread("resize.img")
plt.imshow(img)
plt.show()
```

##色空間の変換
・カラー（赤、緑、青）からモノクロ（白、黒）に変更するときは__cv2.cvtColor(画像)__の第二引数に__cv2.COLOR_RGB2GRAY__と設定すれば良い。画像を扱うときにはこれがしばしば行われる。
・変換した画像をplt.show()で出力するときは、そのままだと第一引数を「緑」と認識してしまうため、__plt.gray()__と記述する必要がある。

#男女認識2
##行うこと
・CNN（＋ Keras+TensorFlow）を使ってモデルを作る。また、VGG16を使い転移学習を行う。

##モデルの作成（層追加）
・（復習）Sequential()インスタンスの作成、addで層の追加を行う。
・（復習）各層の定義
　・全結合層：__Dense(ユニット数,input_dim=データの次元数)__
　・畳み込み層：__Conv2D(filters,kernel_size,strides,padding)__
　・プーリング層：__MaxPooling2D(pool_size,strides,padding)__
　・平坦化層：__Flatten()__
　
　・活性化関数：model.add(Activation("sigmoid"))

##モデルの運用（コンパイル、学習、予測）
・（復習）compileでコンパイル、fitで学習、np.argmax(model.predict())で予測。
・__model.compile(optimizer,loss,metrics)__
・__model.fit(学習データ,教師ラベル,batch_size,epochs)__

##転移学習
・（復習）VGG16を使った転移学習

```python
#入力のshapeの設定
input_tensor = Input(shape=(32, 32, 3))
#VGGモデルの設定
vgg16 = VGG16(include_top=False,weights='imagenet',input_tensor=input_tensor)
#VGGモデルと新しい層の結合
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
#VGGモデルの層数と重みの固定
for layer in model.layers[:15]:
    layer.trainable = False
```
[ServiceNow] 「記憶する」チェックボックスの復活方法 (セッションタイムアウトをさせない方法)

#概要
以前のバージョンの ServiceNow では、ログイン画面に「記憶する」というチェックボックスがあり、このチェックボックスをつけた状態でログインすると、セッションタイムアウトしないようにできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756088/258435ee-07b6-cc1f-47f4-9f89c314e2c8.png)
あるバージョンから、「記憶する」を非表示にするほうがデフォルトになりましたので、最近 ServiceNow を始められた方は「記憶する」チェックボックスの存在自体をご存知ないかもしれません。
セッションタイムアウトしないようにできると、開発環境、検証環境などで、ID、Password を入力してログインする操作をかなり減らすことができ、便利ですので、復活方法を知っておくとよいでしょう。

このチェックボックスの表示、非表示は、「glide.ui.forgetme」というプロパティで制御されています。
true のときが非表示、false のときが表示です。
変更するには、security_admin になる必要があります。

#設定手順
「記憶する」チェックボックスを復活させるための手順としては、以下になります。

1. ロールを昇格 (elevate_roles) で security_admin になる
2. Navigation Menu の検索窓に「sys_properties.list」をいれて、Enter を押下し、System Property の一覧を表示する
3. 「glide.ui.forgetme」というプロパティを検索して、開く
4. 値を false に変更して、レコードを保存

以上です。

#補足
###補足1 
システムプロパティ > UI プロパティ に行っても該当のプロパティを変更できますので、2-4 の手順は、そちらで行うこともできます。
###補足2
利用ユーザーの多い本番環境で、このチェックボックスを有効にしてしまうと、セッションが残り続け、メモリを圧迫する原因になりますので避けるべきです。
利用ユーザーが少ない場合（例、数十人のIT部門内のみで使っているなど）は、有効化するのも要件次第ではありかもしれません。
そのような場合も、デフォルトでこのチェックボックスにチェックが入った状態にするかどうかのプロパティ (glide.ui.remember.me.default) がありますので、こちらを false にしておくとよいでしょう。デフォルトでは、チェックが入っていない状態にして、意図的にセッションを切れないようにしたい人のみチェックを付けてログインするのがよいかと思います。
Pythonのimmutable型 int編 メモ


int型はimmutable型である。
したがって、一度メモリに格納された値は変更できない。

値が同じ場合、例えば1を代入する変数が複数ある場合は、それらの変数は全て、1を格納するただ一つのメモリを参照することになる。
変数から参照されなくなったメモリは削除されるのだろうか。(要調査)(swiftの参照カウンターのようになるのか？)

```python:qiita.rb
>>> int1 = 1
>>> int2 = 1
>>> print(id(int1), id(int2))# 参照メモリidを出力
4383344848 4383344848
>>> int2 = 3
>>> print(id(int1), id(int2))
4383344848 4383344912
>>> int2 = 1
>>> print(id(int1), id(int2))
4383344848 4383344848


>>> intList = [1,2,3,4,5]
>>> print(id(intList[0])) # 1を格納するインデックス
4383344848

>>> print(id(intList[2])) #"3"の参照メモリid
4383344912 # さっきint2に代入した"3"のidと同じやなあ。(さっき3に対する参照変数の個数がゼロになったけど、、すぐにはメモリクリーンされないのかしらー)
```

---
<b>追記2020/10/04: 
> 変数から参照されなくなったメモリは削除されるのだろうか。(要調査)(swiftの参照カウンターのようになるのか？)
> さっきint2に代入した"3"のidと同じやなあ。(さっき3に対する参照変数の個数がゼロになったけど、、すぐにはメモリクリーンされないのかしらー)

コメント欄に上記の答えをコメントしていただきました。
@shiracamusさんありがとうございます。
Core ML Tools 変換エラー対応集（私家版）

###エラー１：
>the second input, which is the output size, must be known statically
出力サイズである2番目の入力は、静的に認識されている必要があります

#####対応１：
Inputsオプションで入力サイズを明示的に指定する。

```swift
import coremltools as ct
input = ct.ImageType(shape=(1, 513, 513, 3))
mlmodel = ct.convert(model,inputs=[input])
```

###エラー２：
>Unable to determine the type of the model, i.e. the source framework. Please provide the value of argument "source", from one of ["tensorflow", "pytorch"]. Note that model conversion requires the source package that generates the model. Please make sure you have the appropriate version of source package installed. E.g., if you're converting model originally trained with TensorFlow 1.14, make sure you have 'tensorflow==1.14' installed.
モデルのタイプ、つまりソースフレームワークを判別できません。 ["tensorflow"、 "pytorch"]のいずれかから引数 "source"の値を指定してください。 モデル変換には、モデルを生成するソースパッケージが必要であることに注意してください。 適切なバージョンのソースパッケージがインストールされていることを確認してください。 たとえば、元々TensorFlow 1.14でトレーニングされたモデルを変換する場合は、「tensorflow == 1.14」がインストールされていることを確認してください。

#####対応２a：
inputオプションをつける（エラー１と同じ）。

#####対応２b：
与えるモデルのフォーマットを変えてみる。例えば、凍結グラフの代わりに、グラフを直接与える。

#####対応3b：
TensorFlow1をインストールする。


*（このエラーが出た時は、エラーメッセージ通りにソースオプションでフレームワークを指定してもうまく行ったことがないです。自分の場合）

🐣

****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

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

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
Join Azure Using Go 〜GoでAzureを始めたい＆知りたい方々へ〜

2020年9月30日(水)にオンラインで「[★祝★Japan Azure User Group 10周年](https://jazug.connpass.com/event/186235/)」が開催されました。3年前の7周年の時にLTでチャレンジしたのですが失敗しており、また、Azure　SDK for Goの学習を始めた今年が記念の10周年にあたるのも何かのGo縁だと思い、再度、祝辞(LT)枠にて申し込みさせて頂きました。

今回は事前に動画を投稿し、公開された物から順に各自で閲覧するという、私も初めて体験する形式でした。

- [Japan Azure User Group 10周年 - YouTube](https://www.youtube.com/playlist?list=PLqVktDzfvX5D0PE7Tok5OsudQzZ-qD6Mu)

今夏の私の「Microsoft/Azure x Go」活動の集大成として、力一杯作成したところ少々長めの動画となってしまいました。ダメ元で [JAZUG](https://www.facebook.com/jazug.jp) のコミュニティリーダーの方々に相談させて頂いたところO.K.を頂くことができ、5分枠に対して21分の動画を採用して頂くことができました m(_ _)m

- 【動画】[Join Azure Using Go (10 items) - YouTube](https://www.youtube.com/watch?v=op-TmbrM3pI&list=PLqVktDzfvX5D0PE7Tok5OsudQzZ-qD6Mu&index=3)

現時点でのAzureサービスでのGoの使われ処やGoで使えるAzureサービスを目一杯紹介しています。これからGoでAzureを始めたい方や知りたい方などは、ぜひ一度みて頂けれたら！

- 【スライド】[Join Azure Using Go (10 items)](https://www.slideshare.net/qt-luigi/join-azure-using-go-10-items)
 
P.S. 18ページ目の「Web App for Contsainers」の補足：先日、Windowsコンテナーも一般提供(GA)になりました。
AWS SAM CLIの設定切替

# 経緯
新規プロダクトサービスの一環で、AWS SAMでServerlessを使ったんですが、今後の開発環境どうしよう？となりまして。
基本的なテストはローカルでいいにしてもステージング的な環境は欲しいし、複数のリリース先ってどうやって管理するん？
sam deployの設定をお手軽に切り替える、そんな機能ないの？
ドキュメントやhelp(当時sam --version 1.2.0)見てもそれっぽいものは見つからなかったんですが、AWS SAMのissue探してみたらあっさりありまして。

https://github.com/aws/aws-sam-cli/issues/1615

Release 1.3.0 - Support for Multi Config
https://github.com/aws/aws-sam-cli/releases/tag/v1.3.0


**ついこないだリリースされてた。**
※気づいた時点でちょうど1週間前

しかしまだあんまり情報ないようなので、とりあえずざっくり情報書いておきます。
あんまり詳しいわけではないので、間違ってたらごめんね！(修正ツッコミいただけると助かります

# 前提
```
$ sam --version
SAM CLI, version 1.3.2
```

# ファイル指定とセクション指定
実はドキュメント化されていなかっただけで、--config-envというsamconfig.tomlをセクションで切り替えるオプションはあったらしいです。(って前述のissueに書いてありました)
また、今回で--config-fileというsamconfig.tomlを直指定できるオプションができました。
ちなみにsam buildなど他のコマンドでも--config-envや--config-fileは有効のようです。

# --config-file [Filename]
samconfig.tomlファイル自体を指定します。
例えば本番用にsamconfig_prod.toml、開発用にsamconfig_dev.tomlというファイルを作成しておいて、コマンドで使い分ける感じです。

```
# 本番用
sam deploy --config-file samconfig_prod.toml

# 開発用
sam deploy --config-file samconfig_dev.toml
```
なお、1.3.0でマルチ構成がサポートされたタイミングで、sam deploy --guideで書き込み先ファイル名を聞いてくれるようになりましたので、別設定も作りやすいですね。
(私はコピペしちゃいましたけど)

# --config-env [section]
samconfig.toml内のセクションを指定します。
guideオプション使用時に--config-envでセクションを指定すると、そのセクションで設定を作ってくれます。

```
# devセクションで設定を作る
sam deploy --config-env dev --guide
```
--config-envの指定がない場合は従来通りdefaultセクションで作られます。

実行するときは前述のセクションを指定します。

```
# 本番用
sam deploy --config-env prod

# 開発用
sam deploy --config-env dev
```

また、他コマンド(buildなど)で設定を指定したい場合はsamconfig.tomlに追記して対応できます。
例えばsam buildのtemplate.yamlを指定したい場合、下記のような感じになります。

```samconfig.toml
[dev]
[dev.build]
[dev.build.parameters]
template_file = "template_dev.yaml"

[dev.deploy]
[dev.deploy.parameters]
stack_name = "stackname-dev"
s3_bucket = "deploy-bucket"
s3_prefix = "deploy-dev"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
```

これでsam build実行時にtemplate_dev.yamlを適用してくれます。

```
# template_dev.yamlを適用してsam build実行
sam build --config-env dev
```
sam build --template-fileで指定していたものが--config-envで指定できるようになるので、構成によってはちょっと楽かも。

# まとめ
この２種を組み合わせると、かなり複雑な設定でもできますね。
ただ、今回に関しては全く複雑な構成ではなく、むしろ本番と開発の2本のみ、開発者が私だけなので、シンプルに--config-envで指定する方向になりそうです。
【Rails】バリデーションを特定のコントローラで使う

## はじめに
特定のバリデーションを特定のコントローラでのみ作動させたい場合にどうすれば良いかについて書いていきます。

## 具体例
例えばユーザー情報を登録させるとき、ステップごとに情報を登録させたいときを考えてみます。

Usersテーブル

|column|type|
|------|----|------|
|name|string| |
|email|string| |
|password|string| |
|address|string| |
|image|string| |

1ページ目：name, email, password
2ページ目：address, image

というように、name, email, passwordを保存してから、adress, imageを保存するという処理を考えます。

全てのカラムを必須項目にしたい場合、モデルに`presence: true`をただ書いてしまうと、1ページ目の登録の際にエラーになります。（address, imageが空になっているため）

1ページ目と2ページ目でバリデーションを使い分けたい時はどうすれば良いでしょう？


## やり方
`with_options`というものを使って各アクションごとに使い分ければOKです。
イメージ的には、モデルに`with_options on: 〜 do`としてバリデーションのグループに名前をつけておいて、コントローラで`valid?(名前)`のメソッドを使ってバリデーションのチェックをする感じです。

具体的な書き方は以下のようになります。（少し端折って書いてる部分もあるのでご注意ください）

```ruby:モデル
with_options on: :step1 do
  validates :name, presence: true
  validates :email, uniqueness: true
  validates :password, presence: true, length: { minimum: 8 }
  validates :password, confirmation: true
end

with_options on: :step2 do
  validates :address, presence: true
  validates :image, uniqueness: true
end
```

```ruby:step1コントローラ
def create
  @user = User.new(user_params)
  if @user.valid?(:step1) && @user.save
    return redirect_to step2_path
  end

  render :new
end
```
```ruby:step2コントローラ
def update
  @user = User.find(params[:id])
  if @user.valid?(:step2) && @user.update(user_params)
    return redirect_to user_path
  end

  render :edit
end
```
## 補足
同時に全てのバリデーションをかけたい場合は、`valid?(:step1) && valid?(:step2)`のように書く必要があるので少々面倒です…
（valid?だけで全てのwith_optionsを使ってくれないかと思いましたがダメでした）

ちなみにcreateとupdateで使い分けたい場合は[こちら](https://qiita.com/kadoppe/items/061d137e6022fa099872)の記事を参考にしてください。（本投稿とかぶる部分もありますが…）
【Ruby on Rails】bootstrap4のcarouselをeachメソッドを使いスライドショーを実装

# 目標
eachメソッドを用いた上で
登録されている画像枚数に応じてスライドショーを実装する。

※※目標に近づいているものの、まだすべてを解消出来たわけではありません。
　解消でき次第更新いていきます。

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
[【Ruby on Rails】refileでの投稿画像プレビュー機能](https://qiita.com/japwork/items/920df937084c145b47b9)
画像投稿機能ができていればOKです。

bootstrap4に関してはこちらの記事がわかりやすかったです。
[Railsアプリで Bootstrap 4 を利用する](https://qiita.com/NaokiIshimura/items/c8db09daefff5c11dadf)

# 公式サイトをチェック
[Carousel - Bootstrap 4.1 日本語リファレンス](https://getbootstrap.jp/docs/4.1/components/carousel/)

今回はこの中の
With indicatorsの方法で実装を試みます。
※※結論からいうと、不具合があるため、解消でき次第更新します。

# viewの編集

```erb:app/views/
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel" data-interval="3000">
  <ol class="carousel-indicators">
    <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
    <% @post_images.drop(1).count.times do |index| %>
      <li data-target="#carouselExampleIndicators" data-slide-to="#{index}"></li>
    <% end %>
  </ol>
  
  <div class="carousel-inner">
    <div class="carousel-item active">
      <% @post_images.first(1).each do |image| %>
        <%= attachment_image_tag image, :image, class: "carousel_image"  %>
      <% end %>
    </div> 
    <% @post_images.drop(1).each do |image| %>
      <div class="carousel-item">
        <%= attachment_image_tag image, :image, class: "carousel_image" %>
      </div>
    <% end %>
  </div>
  <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>
```

# 考え方
公式サイトでは直接画像を記述しているため、今回の目標に近づけるために
一枚目を```<div class="carousel-item active">```に指定しています。
したがって、一枚目を<% @post_images.first(1).each do |image| %>で取得し、
2枚目以降をdrop(1)を用いて取得しています。

indicatorの部分は画像の枚数文あれば大丈夫なものの、
こちらもclass="active"が必要なため、
2枚目以降をdrop(1)を用いて取得しています。



# 不具合
1 indicatorの表示とスライドショーでのindicatorの流れは正しいものの、
　indicatorをクリックすると最後の画像から順に選択してしまう
2 .carousel-fadeが適用されない
　→（Herokuにデプロイ後、iphoneのsafariでは適用されました。）


# まとめ
indicatorとcarousel-fadeを使用しない場合はこの方法で合っていると思いますので、
少しでも参考になれば幸いです。
また、もし改善点などがあれば是非とも教えていただきたいです。


# 参考
[Bootstrap4 Carousel（カルーセル）の使い方とカスタマイズサンプル](https://homupedia.com/bootstrap4-carousel.html)
[RailsでBootstrapのスライドショーPartial](https://qiita.com/yushimizu/items/679064b8e97413441367)
create-react-app my-appすると「error @typescript-eslint/eslint-plugin@2.24.0: The engine "node" is incompatible with this module. 」と出る

## エラー内容
- 動作するversionが指定されている模様

```
error @typescript-eslint/eslint-plugin@2.24.0: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "9.11.2"
error Found incompatible module.
```

## 対処

### 今のバージョンを確認

```
yuta:~/react-google-api $ nvm list
->      v9.11.2
       v10.18.1
         system
default -> v9.11.2
```

### 対応していそうなバージョンを取得

```
nvm install 11.10.1
```

### 対応していそうなバージョンへ変更

```
nvm use 11.10.1
```

### リトライ

```
npm install -g create-react-app
create-react-app my-app
```
WebGLを使った点群のウェブ地図展開

この記事は投稿した論文と試作したアプリケーションの紹介記事である。またアプリケーション開発には多くの試行錯誤があったので、その内容をメモとして残すものである。

#はじめに

点群をウェブ地図に展開する場合において、WebGL以前ではその数量に限界があった（点の数量が多くなるとアプリケーションの起動時間や応答速度が著しく劣化した）。WebGLが手軽に使える（手軽ではないが）ようになったこと、手頃なお題を頂いたこと、仕事がなく暇だったということもあり、どのようにすれば高速動作が可能であるか1ヶ月程度実験したところ非常に高速に動作する仕組みの開発に成功したので、完成したアプリケーションについて紹介する。
このアプリケーションについて記述した論文は最後に紹介する。

#開発したアプリケーション（最終成果）

![スクリーンショット 2020-10-04 9.56.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731876/0922c4ce-7627-96d2-901b-ceaf01e1dd8b.png)

* [WebGL点群展開ウェブ地図アプリケーション：迅速測図](https://kitao.net/works/rsmap/pcpng/leaflet.html)

#データ

* [明治時代初期土地利用・被覆デジタルデータベース](https://github.com/wata909/habs_test)

上記ページ作成者の方とお話する機会があり、その際点群展開のお題としてデータをご提供いただいた。
データの点数は約170万点、表示分類12（実際は分類に含まれない点があったので本来は13）、geojsonファイルの容量約390MBである。上記ページ中には全点を一括展開する機能は実装されておらず、特定の領域ごとに表示する仕組みをLeafletで実装している。そのうち一つを開いてみると約2,500点ほどのデータで表示されるが動作速度の劣化が見られる。全点表示かつ高速動作するアプリケーションを開発できるか否か、半信半疑ではあったが幾つかの方法でテスト実装することを試みた。

#試したこと

##LeafletとPixiJSの組み合わせ

WebGLを容易に扱うことができるライブラリPixiJSを使うことで高速展開できるのではないか、と考えアプリケーションを試作した。元となるデータはサイズが大きいので、表示に必要なデータだけを抽出し無駄な桁を削除する等調整して独自のjson形式でデータを再作成した結果約100MBのjsonファイルとなった。
結果として全点を展開することは出来たが、低ズームレベル（縮小表示）時の動作速度は緩慢となった（それでも高ズームレベルでは程々の動作速度であった）。PixiJSが標準で装備する機能を利用したため、表示中のデータを識別するJavaScriptオブジェクトが肥大化することが動作速度劣化の原因と推察した。jsonデータをタイル単位で管理する等工夫したが結果として高速展開と言える状態とはならなかった。
LeafletとPixiJSを組み合わせる例として、Leafletのプラグイン[Leaflet.PixiOverlay](https://github.com/manubb/Leaflet.PixiOverlay)があり、100万点までの点群を展開するサンプルが表示されている。ソースコードを読むと数万点までは当該プラグインを使用するだけであるが、100万点のサンプルでは独自のシェーダを記述する等工夫が必要な様子であった。

##Leafletと2D-Canvasの組み合わせ

PixiJSを使っても保持するオブジェクトが大きすぎることが動作速度劣化の原因になるのであれば、2D-Canvasに点を打って表現する方法と変わりないのではないかと考え、その仕様でアプリケーションを試作した。データは前述のオリジナルjsonを使用した。結果としてPixiJSより若干動作は重くなるものの、ほぼ同等の速度で動作するアプリケーションを開発することができた。

##Leafletと生WebGLの組み合わせ

PixiJSのサンプルにおいて生WebGLを使えば100万点の点群を高速展開できることは把握していたので、これを機会にライブラリを用いず生WebGLでのアプリケーション開発に着手し、結果として良好な動作速度を得ることができた。
それに合わせて、普段より交流のある研究者の方から点群データの受け渡しをするための新たな書式の提案を受けたのでこれを採用したところ、データサイズは2MBまで軽量化することができ、データの扱いもWebGLと極めて高い親和性を持っていたためアプリケーションの高速化にも寄与したと推察できる。

#プログラム詳細

点群のデータはアプリケーション起動時に全て一括で取得する。データサイズが極めて小さいため起動時間の大きな低下を招くことはない。取得したデータはヘッダと点群の座標他に分割し、点群座標他を一括でシェーダに渡す。
シェーダでは与えられた座標をWebGLの座標系に変換し、かつ出力色を決定して描画する。これにより点群のウェブ地図高速展開が可能であることがわかった。

```
プログラムの詳細については後日記載予定
```

#感想等

* 生WebGLを学ぶことにより、Three.jsやPixiJS等のライブラリで用いる各種関数の意味が少しずつ理解できるようになった。開発においてライブラリを用いる場合、ライブラリに頼らない手法を学んでおくか、当該ライブラリのソースコードを読むことが実際の開発に役立つことがわかった。
* このプログラムの実力を発揮できるようなお題を見つけることが難しい。500万点程度の点群を展開する業務を受注できればさらなる発展を望むことができる（と思う）。

#今後の進展

試作したアプリケーションでウェブ地図上での点群高速展開を実現することができたが、これでは単に表示しただけに過ぎない。各種実用的なアプリケーションに適用するには幾つかの課題がある。例えば大量のデータの管理はデータベースソフトウェアを用いることが一般的であるが、このアプリケーションの現状ではデータベースとの連携が出来ない。
すでに課題の解決には成功しており、今後それらを取りまとめ、論文もしくは記事投稿等で紹介する予定である。

#参考文献

現在整理中。
PL/SQL練習記録（条件制御IF文）

##はじめに
javaとSQLには少し触れたことがあるのですが
PL/SQLは初めてなので練習するついでに記録をしていこうと思います。

##実行環境（事前準備）
・Oracle 12C を使用しました。
環境を作成後、スキーマを作成しようとしたところエラーが発生。
「ORA-65096: 共通ユーザーまたはロール名が無効です」
調べてみたところCDBに接続していたのが原因でした。（CDBってなんぞやレベル）
今回の記事内容とは異なるのでざっくりと書きますがPDBに接続をすることで解決しました。
いずれ詳しく記載しようと思います。

##IF文
条件制御（条件によって処理を分ける）といわれるもの。
IF文はjavaでも登場したのですんなりと理解できました。
実際に試したのはこちら↓

```sql:IF文.
DECLARE
　test NUMBER := 10;
BEGIN　
　IF test = 10 THEN
　　DBMS_OUTPUT.PUT_LINE('値は10');
  ELSE
  　DBMS_OUTPUT.PUT_LINE('値は10以外');
  END IF;
END;
```

実行すると「PL/SQLプロシージャが正常に完了しました。」のみが表示。
DBMS_OUTPUT～で記載した表示がでないなーと調べると下記実行が必要なようです。

```DBMS_OUTPUTの出力を表示する.
SET SERVEROUTPUT ON;
```

もう一度実行してみると「値は10」と表示されました。

##解説
作成したIF文についてコメント解説。

```sql:IF文解説.
DECLARE　　--宣言部
　test NUMBER := 10;　   --　NUMBER型の変数testに10を挿入
BEGIN　　　--処理部
　IF test = 10 THEN　　　--　もしtestの値が10だった時
　　DBMS_OUTPUT.PUT_LINE('値は10');　  --　「値は10」と表示
  ELSE                  --  それ以外の時（10ではない時）
  　DBMS_OUTPUT.PUT_LINE('値は10以外');　--  「値は10以外」と表示
  END IF;　　　　　　　　--IF文終了
END;
```


##参考文献
プロとしてのOracle　PL／SQL入門 

<table cellpadding="0" cellspacing="0" border="0" style=" border:1px solid #ccc; width:300px;"><tr style="border-style:none;"><td style="vertical-align:top; border-style:none; padding:10px; width:;"><a href="https://rpx.a8.net/svt/ejp?a8mat=3BQT58+6IKTWA+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00reb44.2bo11755.g00reb44.2bo12ad3%2Fa20112511629_3BQT58_6IKTWA_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Frakutenkobo-ebooks%252F58b5a0720c5d310d85e58fb4b2194cfd%252F%26m%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Frakutenkobo-ebooks%252Fi%252F13906097%252F" rel="nofollow"><img border="0" alt="" src="https://thumbnail.image.rakuten.co.jp/@0_mall/rakutenkobo-ebooks/cabinet/1325/2000002631325.jpg?_ex=64x64" /></a></td><td style="font-size:12px; vertical-align:middle; border-style:none; padding:10px;"><p style="padding:0; margin:0;"><a href="https://rpx.a8.net/svt/ejp?a8mat=3BQT58+6IKTWA+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00reb44.2bo11755.g00reb44.2bo12ad3%2Fa20112511629_3BQT58_6IKTWA_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Frakutenkobo-ebooks%252F58b5a0720c5d310d85e58fb4b2194cfd%252F%26m%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Frakutenkobo-ebooks%252Fi%252F13906097%252F" rel="nofollow">プロとしてのOracle PL/SQL入門 【第3版】（Oracle 12c、11g、10g対応）【電子書籍】[ アシスト教育部 ]</a></p><p style="color:#666; margin-top:5px line-height:1.5;">価格:<span style="font-size:14px; color:#C00; font-weight:bold;">1,320円</span><br/><span style="font-size:10px; font-weight:normal;">(2020/11/25 13:10時点)</span><br/><span style="font-weight:bold;">感想(1件)</span></p></td></tr></table>

Amazonは<a href="https://px.a8.net/svt/ejp?a8mat=3BQT58+6GSJ2Y+249K+BWGDT&a8ejpredirect=https%3A%2F%2Fwww.amazon.co.jp%2Fs%3Fk%3DPL%252FSQL%26__mk_ja_JP%3D%25E3%2582%25AB%25E3%2582%25BF%25E3%2582%25AB%25E3%2583%258A%26ref%3Dnb_sb_noss_2%26tag%3Da8-affi-308824-22" rel="nofollow">こちら</a>
<img border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3BQT58+6GSJ2Y+249K+BWGDT" alt="">
【Vue.js】Invalid prop: type check failed for prop ... Expected A, got B.エラーの対処

## 環境
vue.js 2.6.12

## 対処法

```
[Vue warn]: Invalid prop: type check failed for prop "itemData". 
Expected Object, got Array 
```

バインディングで渡された値の型がpropが期待する型と一致していないという内容です。
Invalid prop: type check failed for "プロパティ名", Expected 期待する型, got 実際に渡された型。

なので、今回は「itemDataにObject（オブジェクト）が渡されるはずが、Array（配列）が渡されている」ということです。対処としてはフロントで配列を期待する前提にするか、バックエンドからオブジェクトを渡すようにするか、という事になるかと思います。

端的には以下で解決します。

```item.vue
<script>
export default {
  props: {
    itemData: {
      type: Object //オブジェクトじゃなくて
    },
    itemData: {
      type: Array //配列を指定する
    },
  },
}
</script>
```
【1日30分】AWS認定ソリューションアーキテクトアソシエイト（SAA）3ヶ月で合格するためにやったこと

会社の個人目標でSAAの取得を設定しました。
理由は、AWSに興味があったこと、資格取得というわかりやすい目標にしたかったことです。

**1日平均勉強時間30分（3ヶ月）**SAAを取得することができたので、
記録として残したいと思います。
※あくまで平均時間であり、1日2時間の時や全くやらない日もありましたのでご了承ください🙇🙇🙇

## 自己紹介
 * AWS未経験（EC2を立ててPHPを動かす程度）
 * エンジニア歴1.5年<br>
参考：https://qiita.com/daichi_sugiyama/items/623218b6e9173d5e7ed7

## 教材
 * [徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E2%80%93-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8/dp/4295005495)
SAAの教材の中で一番有名なものです。
使い方は、平日寝る前に1章を読むの2周くらいしていました。（全6章構成）
AWS初学者はこれをとりあえず読んでおけばOK。
また、解説付きの模擬試験が1回分ついているのでオススメ。

 * [これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)
動画教材でハンズオン形式で学ぶことができます。
平日時間がある時と、休日に進めていきました。
**実AWSサービス全般を触るので記憶に残りやすいので、ぜひやってほしい**です。
私は1周しかしていませんが、2周すればよかったと後悔🤦‍♂️
こちらは模擬試験が3回分ついています。

 * AWS公式模擬試験
AWS公式から出ている模擬試験です。
1回2000円（+TAX）で20問出題されます。
私は1回受けましたが、50％しか取れませんでした（本試験は約70％で合格）
本番の問題文は少々クセがあるので、慣れるために受験することをおすすめします。
注意点は、後から問題を見返す事ができないのでどんな問題が出たかを記憶しておきましょう。

スケジュールは、
**2ヶ月（書籍とUdemy）+1ヶ月（模擬試験をひたすら回す）**
で行いました。

## 得たもの
* AWSの知見<br>
3ヶ月前よりAWSの概要を掴むことができました。<br>
特に、**AWS Well-Architected**と呼ばれるAWSが提唱しているベストプラクティスの考え方を学ぶことができました。
* 成功体験<br>
目標を立てて、達成するための行動力、計画力が身につきました。<br>
目標を達成することで自信をつける事ができました💪

## まとめ
上記の方法でSAAを取得することができました。
しかし、SAAを取得したからと言ってAWSを完璧に理解したとは言えません。
資格取得も目標に向けて、計画を立てて実行することが一番大切だと思います。
資格取得を機会に、個人開発でも業務でも積極的にAWSに関わっていきたいと思います。
[react] 三項演算子で条件によってクラス名を付与しながら、他のクラスを付与する方法

#はじめに
```test.js
       <span
          className={(
            "foo",
            "bar",
            open ? "active" : ""
          )}
        ></span>
```
上記のようにclassnamesなしだと最後の open ? "active" : ""　だけが付与され、fooとbarは付与されない。
どうしたら上記のパターンで複数のクラス名を付与できるか調べた結果、classnamesというライブラリを使えばいいことがわかった。

#classnamesというライブラリをインストールする

`npm install classnames`

#モジュールでimportする
```test.js
import React from "react";
import classNames from "classnames";
```

#クラスを付与したいタグでclassnamesを使用する
```test.js
       <span
          className={classNames(
            "foo",
            "bar",
            open ? "active" : ""
          )}
        ></span>
```

上記のように書くことで、
stateであるopenがtrueの場合にactiveというクラス名を付与、falseの場合にはクラス名を付与しないことに加え、
foo,barというクラス名を付与することができる。
仮想環境でdjangoアプリを初めてみる

#仮想環境で開発をしてみたい
dockerを使い慣れず、ローカルでの仮想環境を用意してdjangoアプリを開発する手順です。忘れっぽいので備忘録として。
環境：Mac OS　10.15.4, django 3.1.1


###なんで仮想環境なのか
第一に自分のパソコンをきれいに使いたい一心です。docker使いこなせるようになりたい。

#仮想環境の構築
virtualenvを使っていきます。では、インストール方法から。

```terminal
pip install virtualenv
```

パスワードを聞かれるので入力すれば、virtualenvがインストールができます。

virtualenvは「独立した環境」と捉えることができます。その「環境」の中に出入りすることで開発を行います。「環境」を作るには以下のコードを実行します。

```terminal
virtualenv <ENV_NAME>
```

ENV_NAMEは環境の名前、フォルダの名前となります。実際に環境を作ると新たにフォルダが作成され、その中に`binフォルダ`が作成されています。この`binフォルダ`内に存在する`activate`を指定することで先ほど作った環境内に入ることができます。

```terminal
source <ENV_NAME>/bin/activate
```

これによって環境の中に入ることができます。
反対に環境から出る時は、```deactivate```とすることで仮想環境から出ることができます。

#djangoを始める
仮想環境にはdjangoがインストールされていないのでインストールから始めます。

```terminal
pip install django
```

インストールが完了したら、一応バージョンの確認をしておきます。

```terminal
django-admin --version
```

3.1.1等表示されればインストールがちゃんとできています。

##プロジェクトの作成
特に指定をしないので、ディレクトリを移動します。

```terminal
cd <ENV_NAME>
django-admin startproject <project>
```

`startproject`によってdjangoが必要なものを作成してくれます。

##アプリの作成
ターミナルで先ほど作成したプロジェクトフォルダに移動します。

```terminal
python manage.py startapp <app>
```

実行すると、appにあたる名称がついたフォルダ作成されます。
これでdjangoアプリ開発の下準備ができました。
paramsとは

Ruby 2.6.5
Rails 6.0.3.2

Ruby on Railsについての勉強をしていた際に、paramsというものの理解に時間がかかってしまったので、自分の確認のために投稿してみました。

##paramsとは
一言でいうと、「情報が入っている箱」のことです。
例えば、ページを遷移する際には必ず「情報が入っている箱」を送っています。というより、「情報が入っている箱」を送ることでページの遷移を可能としています。
言葉だけでの説明ではわかりにくいと思うので、具体的な例を元に説明していきます。

##具体的な例
```ruby:routes.rb
Rails.application.routes.draw do
  resources :hoges, only: [:index, :new]
end
```
```ruby:index.html.erb
  <%= link_to "newページを開く", new_hoge_path %>
```
```ruby:new.html.erb
  ここはnewページです。
```
```ruby:hoges_controller.rb
class HogesController < ApplicationController
  def index
  end

  def new
  end
end
```
現在、index.html.erbのページにいるとします。
そこで、"newページを開く"をクリックすると、以下の情報が送られ、hogesコントローラーのnewアクションが動作し、new.html.erbが開き、「ここはnewページです。」と表示されます。

{"authenticity_token"=>"+wXNK4Z3C0wrq4AfslPS5zl/2LSUE6BvV+23hQpkHryrsVzPb0siDIkarIsNYLK2R502fuXlqQ==", "commit"=>"newページを開く", "controller"=>"hoges", "action"=>"new"}

この**送られた情報をparams**と言います。paramsはいくつかの情報を一纏めにしたものなので、「情報が入った箱」と言われます。

paramsをよく見てみると、"controller"=>"hoges"と "action"=>"new"が確認できます。これによって、どのコントローラーのどのアクションが動作するのかを指定しているので、new.html.erbを開くことができます。

paramsの確認方法については記載すると長くなってしまうので、他の記事を参考にしてください。
Laravel8 CRUD処理を使った投稿アプリを作成する その0 説明編

# 本記事の目的

- Laravel8を用いたCRUD処理をもった投稿アプリを作成する方法をチュートリアル形式で紹介する説明を行う。

# チュートリアルの最終目標

- Laravel8を使って投稿アプリを完成させる。
- 画像の投稿もカバーしメンテナンス性を考えたDBアクセス処理の分割なども実装する。

# おことわり

- 最終目標の達成後も記事投稿が続く可能性あり。
- 最終目標は変更になる可能性がある。

# 実施環境

- 筆者の実施環境を記載する。
- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 8.6.0 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |
| Node.jsバージョン | v12.14.1 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでNode.jsをインストールする](https://qiita.com/miriwo/items/73d1546220f1c091a7d5) |

# 前提条件

- 実施環境にまとめたものと近いソフトウェア環境が整っていること。

# 前提情報

- 本チュートリアルは画像つきの文字投稿アプリの作成を行うものである。
- 見た目は気にせずサーバサイドの処理を重点的に実装する。
- 本チュートリアルはシリーズとしていくつも記事を投稿する予定である。
- 筆者が実際にコーディングしたソースコードはGithubで公開する。また投稿記事ごとにブランチを切って管理する。
- 毎回記事に当該記事を見ながら実際にコーディングしたコードのリモートブランチのURLを記載する予定である。
- 大きな機能を先に作成しそこから細かい機能を作成するように説明を進めようと思う。
- Qiitaのタグ「miriwo_laravel8チュートリアル」で本チュートリアルの記事を確認する事ができる。
HTMLのiframeでfocusする／しないで枠の色を変える（FireFox/Chrome+Win/Mac版）

# 目的
- [前回同じタイトルでFireFox版を書きました。](https://qiita.com/Woodie/items/c533ddfb7149c7df3f4a)
- 今回はChrome版でもできたっぽいのでその備忘録です。
- Win/MacのFireFox/Chromeで確認しました。

それでは早速コードを。

## コード

```{main.html}
...
bootstrapを使っています。
...
 <iframe id="ifrm"  src="https://hogehoge/ifrm_canvas.html" width="650" height="518" scrolling="no" frameborder="0"></iframe>                                                                                                                              
...
```

```{main.js}
const ifrm = document.getElementById("ifrm"); 
// iframeをフォーカスする関数
function focus_ifrm () {
   ifrm.focus();
   // iframeの中のJavascript関数を読む
   ifrm.contentWindow.ifrm_focus();
}
//読み込み直後にiframeをフォーカスする
window.addEventListener('DOMContentLoaded', function () {
 ifrm.contentWindow.addEventListener('load', function () {
  focus_ifrm();
 },false);
```

### 説明
- `main.js`のポイントは次です。
    - 親のHTML`main.html`と子HTML`ifrm_canvas.html`の両方で.focus()する

- 子のHTMLのフォーカスは子のJavaScriptの関数を呼び出して`.focus()`します。それに可能にするのが`.contentWindow.関数名()`です
- HTML読み込み直後にフォーカスするために、`.addEventListener('load',...)`でiframe読み込み終了を待ちました。

```{infrm_canvas.html}
<body>
 <canvas width="624" height="500" id="canvas" ></canvas>
 <script src="/js/ifrm_canvas.js"></script>
</body>
```

```{inflame_canvas.js}
const canvas = window.document.getElementById("canvas");  

// フォーカスされたかどうかで枠線の色を変える
function ifrm_focus() {
   canvas.style="outline: 2px solid red";
   document.body.focus(); 
} 

function ifrm_blur() {
  canvas.style="outline: 2px solid gray";
   document.body.blur(); 
} 
...
document.addEventListener("focus", ifrm_focus, true);
document.addEventListener("blur",  ifrm_blur, true);
```

### 説明

- iframeで読み込まれる側で枠表示とfocus()される関数を用意しておきます。
- focusを外れると枠の色を変えて、blur()される関数も用意しました。
- focusイベントで呼ばれる関数で親から呼ばれた時に自分自身をfocusする不思議なコード`document.body.focus();`になってしまいました。

### 備考
- ChromeはセキュリティがFireFoxと考え方が違うのでインプリのポリシーが違うのかもしれません。
- もともとの目的はcanvasに描かれた背景画像に対してクリックしたりその画像のアノテーションするためにキー入力出来るようにすることでした。
- しかしBootstrap4でcanvas描画をレシポンシブル対応するとクリック位置の読み込みと打点座標がずれてしまいました。それを解決するためにiframeに描画することでズレを直したのですが、今度は親と子のHTML間のfocus()のやり取りがFireFoxではOKなのにChromeではできないとなってしましました。
- このブラウザの互換性はひと昔に戻ったみたいで、なかなか難しかったというわけです。
- これでキー入力が想定外など`alert()`を出してもfocusを制御できます（はずです）。
- まずは動いていそうだというレベルなのでまだ不具合があるかもしれません。こうしたら良いよとかありましたら教えていただけると勉強になります。
- 自分向けの備忘録に書きましたがどなたかの参考になりましたら望外の喜びでございます。
「もっとプログラム脳を鍛える数学パズル」_Q61 (code:Ruby) -> Rust (& SQL)

[「もっとプログラマ脳を鍛える数学パズル」](https://www.shoeisha.co.jp/book/detail/9784798153612)をRustで書き直すのは、ボケ防止にちょうど良いかもしれない、と思った。

# Q61:互い違いに並べ替え

## Ruby

```ruby:q61_2.rb
N = 20

z = Hash.new(0)
z[[0,0]] = 1
1.upto(N) do |n|
    1.upto(N) do |k|
        z[[n,k]] = z[[n, k - 1]] + z[[n - 1, n - k]]
    end
end
puts 2 * z[[N, N]]
```

なんとなく、書籍p.287のコードは、RubyとJavaScriptで内側ループの範囲が違ってませんかね・・・Rubyでは正しい結果が出てますが、たまたま0で初期化してるからではないか。

## Rust

```rust:main.rs
fn main() {
    println!("{}", q61());
}

pub fn q61() -> i64 {
    let mut z = [[0i64; 21]; 21];
    z[0][0] = 1;
    for n in 1..=20 {
        for k in 1..=n {
            let un = n as usize;
            let uk = k as usize;
            z[un][uk] = z[un][uk - 1] + z[un - 1][un - uk];
        }
    }
    return z[20][20] * 2;
}
```

配列のサイズを変数指定できないので、とりあえずベタうち。
Rustは何かあるとpanickedになるのがむしろありがたい。パズルを解いていると、境界値を認識していてくれるのは安心できる。

## SQL

ところで、数学パズルでは「パターンは何件あるか」という問題に対して数学的に答える問題が多い。実際の業務では、パターン数計算は見積りには使えても、「いや私は展開されたパターン自体が欲しいんですけど」という状況の方が多い。一番の理由は「テストデータを作りたい」といったところか。
本問の"交代順列"も、もしかしたらテストデータ作成に役立つかも、ということで、SQL版を書いた。

```sql:q61.sql
SELECT
    *
FROM
    (SELECT 1 AS v UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS c1,
    (SELECT 1 AS v UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS c2,
    (SELECT 1 AS v UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS c3,
    (SELECT 1 AS v UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS c4
WHERE
    (c1.v <> c2.v AND c1.v <> c3.v AND c1.v <> c4.v) AND
    (c2.v <> c3.v AND c2.v <> c4.v) AND
    (c3.v <> c4.v)
    AND (
    (c1.v < c2.v AND c2.v > c3.v AND c3.v < c4.v) OR
    (c1.v > c2.v AND c2.v < c3.v AND c3.v > c4.v))
```

実行するとこんな感じ。

```console
+---+---+---+---+
| v | v | v | v |
+---+---+---+---+
| 4 | 2 | 3 | 1 |
| 3 | 2 | 4 | 1 |
| 3 | 4 | 1 | 2 |
| 4 | 1 | 3 | 2 |
| 3 | 1 | 4 | 2 |
| 2 | 4 | 1 | 3 |
| 1 | 4 | 2 | 3 |
| 2 | 1 | 4 | 3 |
| 2 | 3 | 1 | 4 |
| 1 | 3 | 2 | 4 |
+---+---+---+---+
10 rows in set (0.00 sec)
```

SQLは集合論で考えられるので、「ありうる集合から、条件に一致する要素を抽出する」という極めて単純な考え方でデータが取り出せる。
pythonでたべろぐをスクレイピングしCSVに出力

<h1>はじめに</h1>
グノシーの福島良典さんの「センスのいらない経営学」を読みました。

データ分析と機械学習の重要さについてわかりやすく書かれていました。
さらに、グノシーのターゲティング、ユーザー最適化がどのように、どれくらいの労力をかけて行われているか書かれていました。

インターンで1か月ほどプログラミングから離れていたのですが、グルメ系キュレーションサイトを作ることをゴールに勉強することしました。

短期目標：簡易キュレーションサイト作成
最終目標：ぐるなびを超えるキュレーションサイト。時間コストをかけずに店を選べるように、レコマンド機能

本記事の目標：食べログをスクレイピングして店名とURLをSCV出力する

メモ兼日記として綴っていきます

<h1>やったこと</h1>
* URLからHTMLの取得
* HTMLから特定の情報を抜きだす
* タグやクラスを指定して抜き出す方法
* 正規表現を用いて欲しい要素を抜き出す

<h1>コード</h1>

```python:first.py

import csv
import requests
from bs4 import BeautifulSoup
import re

urlName = "https://tabelog.com/osaka/A2701/A270103/rstLst/?SrtT=rt&Srt=D&sort_mode=1"
dataHTML = requests.get(urlName)

soup = BeautifulSoup(dataHTML.content, "html.parser")

elems = soup.select('a.list-rst__rst-name-target.cpy-rst-name')
#data = elems.text

with open(r'C:\Users\daisuke\Desktop\python\first.csv', 'w') as f:
    for i in elems:
        url = re.search(r'"http.*/"', str(i))
        url = re.sub(r'"', '',  str(url.group()))

        name = re.search(r'target="_blank">.*</a>', str(i))
        name = re.sub(r'target="_blank">', '',  str(name.group()))
        name = re.sub(r'</a>', '',  name)

        print(url)
        print(name)

        writer = csv.writer(f)
        writer.writerow([name,url])

```

<h1>今後やりたいこと</h1>
1時間程度でスクレイピングが出来てしまった。
ひさびさにコードを書いたけどスクレイピングってこんなに簡単だったのか‥‥



* Djangoでhelloworld
* Djangoでスクレイピング結果をDBに格納
* DBから情報取得ー表示
* 各グルメメディアから取得した情報を整理して人気店ランキングを作る
* そのために、機械学習を絡める
スキルアップ、就職に向けた効率的なプログラミング学習ステップについて


# はじめに
数え切れない程の学習や知識経験、が必須になるエンジニア職は**独学未経験者凡人**では何から手をつけて、何を優先して学習すれば良いのかごちゃごちゃになってしまうのでは無いでしょうか？
少なくとも私はそうです。
完全初心者独学でプログラミングの学習をするのは、あまりにも知らないこと分からない事、PCの環境問題などにもより、つまずく事が多くあるなと私自身が感じています。(2020.10.04現在)
そこで、未経験中途採用として、実務経験を積めるようエンジニア転職と言う第一目標を、挫折率の高いプロフラミング学習を乗り越え少しでも挫折率を減らし、実現するにはどうしたら良いのかと言う事を調べました。

**（このステップだけを踏めば、立派なエンジニアになれると言うわけでは無い）**

就職をする際に、採用できる人材かどうかを見ようと思ってもらえる
**最低基準の課題だけに絞って**今回は書いて見ます。

#STEP

###### 1. 作るもの決める
（本番用のポートフォリオ作成方法は
下記のエンジニアチャンネルさんの動画の2分２０秒〜説明動画が参考になります。）
↓↓↓↓
[採用責任者が教える。エンジニアちゃんねる](https://www.youtube.com/watch? 
   v=yECZUUhljjg&list=PL2Tv7rY7kIZ02BA2W7svZysjnqISh77xE)

###### 2. 開発に必要なスキルを絞る（その他の技術はパクる、コードコピペなどする。Bootstrapなどでコード調べれる。）
###### 3. 最小限に基礎をインプット
    - プロゲートやドットインストールをそれぞれ１周〜２周にとどめる。それ以上は周回しない。
    - この時点で理解度は50％〜60％で良い。
    - 実際に制作しだしてどんどん慣れて理解していく
    
###### 4. 作り出す(ここまで最初の100時間で一気に学ぶ)
###### 5. また違うもの作る(１.有名サービスのコピー,2.完全オリジナルのサービス)


## 参考にした動画
###### - プログラミング勉強法最短ルート[セイト先生のWeb.IT塾](https://youtu.be/BOrx1GEZY4o)
###### - プログラミングにはやってはいけない勉強法がある！？爆速で成長する王道のプログラミング学習法を紹介！[東京フリーランス](https://youtu.be/ZJqVQJwvwNI)
###### - 月50万稼げるエンジニアになる最速勉強法[マコなり社長](https://youtu.be/gXH-A7tSos8)

以上で私の調べた学習ステップです。
私もできるだけこのステップに沿って学習を進めています。それでもつまずく事が多くあります。
３ヶ月〜６ヶ月をめどに、
**1ヶ月おきに計画立て、目標を作る⇨10日〜半月ほど実行⇨進捗確認⇨改善し実行**
を意識しながら行ない、今では教えてくださる先輩エンジニアや、運よく教えていただいた無料のカウンセリングスクールのようなサービスも利用したりして、一歩一歩進めています！
皆さんもなかなかつまずく事もあるかと思いますが一緒に頑張りましょう！

『有名企業のエンジニアから実務が学べるオンラインコミュニティー』
↓↓↓↓↓
**[TechTrain](https://techbowl.co.jp/techtrain)**
[aws,ecs]クラスターを削除できない時の解決例

# 何があった？
1枚目の画像のクラスターの削除を押して、２枚目の削除の手続きをしてもローディングがずっと続いてしまう状況が続きました。

１枚目
![スクリーンショット 2020-10-04 8.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/f6163d18-add2-3457-9273-5ad054190b11.png)
２枚目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/7efc6601-da6a-c5b6-3dc9-29ca97a2c3c2.png)

# 解決策
左のメニューのタスク定義画面に飛んでタスクを削除した後に、クラスター削除の手順を行うと削除を実行することができました。

# 原因
憶測になってしまいますが、クラスターの中に動いている複数のタスクがある場合に、クラスター削除で一度にタスクごと消せるようにしてしまうと、意図していなかったタスクまで削除してしまう恐れがあるからだと思われます。
k8sでノードをジョインし終えたあとに、ノードを確認する時に出たエラー備忘録



## 出たエラー

```
kubectl get nodes
```

を実行した際の、

```
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
```

のエラー

## 解決策

自分の場合は、単純にsudo 権限でkubectl を実行しないとこのエラーが出るようになっていた。

```
sudo -i
```

の後、

```
kubectl get nodes
```

で解決した。
Python で録音→ファイル保存 (sounddevice+wave)

# はじめに

書籍 [Pythonで学ぶ音源分離](https://book.impress.co.jp/books/1119101154) の2章で録音する場面があるのですが、ちょっと詰まったのでメモしておきます。

# 環境

`sounddevice` は `pip install sounddevice` が必要です。`wave`は組み込みなので必要ありません。

**macOS** 10.15.6
**Python** 3.7.8
**sounddevice** 0.4.1

# 録音+保存

```python
import numpy as np
import sounddevice as sd
import wave


FILE_NAME = './test.wav'  # 保存するファイル名
wave_length = 2  # 録音する長さ（秒）
sample_rate = 16_000  # サンプリング周波数

# 録音開始（wave_length秒間録音。wait で録音し終わるまで待つ）
data = sd.rec(int(wave_length * sample_rate), sample_rate, channels=1)
sd.wait()

# ノーマライズ。量子化ビット16bitで録音するので int16 の範囲で最大化する
data = data / data.max() * np.iinfo(np.int16).max

# float -> int
data = data.astype(np.int16)

# ファイル保存
with wave.open(FILE_NAME, mode='wb') as wb:
    wb.setnchannels(1)  # モノラル
    wb.setsampwidth(2)  # 16bit=2byte
    wb.setframerate(sample_rate)
    wb.writeframes(data.tobytes())  # バイト列に変換

```

* 書籍と異なり、ここでは `with`文を使いました
* `wave.open` は `wb` で開くので、`writeframes`の中身もバイト列にします
    * numpy配列は`tobytes()`でバイト列に変換になります
    * `sd.rec`は`float`を返すので、`data`を整数型（16bitの場合は`np.int16`）に変換する必要があります

自分は整数型に変換するのを忘れていて、何を録音してもホワイトノイズのような音になっていました。
ご参考になれば幸いです。

# 参考
* `wave` ドキュメント https://docs.python.org/3.7/library/wave.html
* `sounddevice` ドキュメント https://python-sounddevice.readthedocs.io/en/0.4.1/usage.html#recording