OmniAICreator/Qiita-1.07M huggingface dataset:
M1 MacbookAirのPython環境構築（Miniforge）


最近バッテリーが60%までしか持たなくなった2017年版MacbookAirを卒業し、M1 MacbookAirを購入しました。新しくPythonの環境構築をすることになったので、過程をここにメモしておきます📝


## この解説で使っているパソコン環境

![スクリーンショット 2021-10-07 15.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912085/491b44a9-49e7-8366-d026-f5845083a456.png)

## 参考にした記事

今回の環境構築方法は、基本的にこれらの記事で紹介してくれている手順を参考にしたものになります。

https://tech-diary.net/install-python-on-m1-mac/#rtoc-1

https://degitalization.hatenablog.jp/entry/2021/05/23/185855

https://qiita.com/9bo0218/items/05a0935964633e410c09


## miniforgeをインストールする

https://github.com/conda-forge/miniforge

↑のリンクからMiniforgeのリポジトリにアクセスし、下にスクロールしていくとダウンロードするリンクが出てきます。

![スクリーンショット 2021-10-07 10.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912085/084cc037-ec9a-7556-e7e3-9c32662f8133.png)

今回はMacOSの中でもM1(Apple Silicon)なので、「**Minoforge3-MacOSX-arm64**」をクリックしましょう。

次にダウンロードが完了したらTerminalを開き、下記のコマンドを実行します。

```
cd ~/Downloads
bash Miniforge3-Linux-x86_64.sh
```

実行するとインストールが始まります。あとは指示に従ってEnterを押したり同意書を読んでyesを入力しましょう。もしここで詰まった場合、[こちらの記事](https://degitalization.hatenablog.jp/entry/2021/05/23/185855)のStep2で、どこでEnterを押すのか、何のコマンドを打てば良いのか画像で詳しく解説されているので参考にしてみてください。

`Thank you for installing Miniforge3!`と表示されればインストール完了です。

インストールが完了したら、一度Terminalを閉じ、再度新しく開きます。

```
conda --version
```

再度開いたTerminalで上記コマンドを実行し、`conda 4.10.3`のようなバージョンが表示されればインストールは成功です。


## Pythonをインストール

以下のコマンドを実行します

```
conda create -n python39_env python=3.9
```
「python39_env」というところは今回作成するPythonの仮想環境の名前なので、各自で好きな名前に変えて大丈夫です。

実行すると、途中で`Proceed ([y]/n)?`と確認されるので、`y`と打ってEnterを押すと先に進みます。

実行が完了すると以下の文言が表示されます。

```
#
# To activate this environment, use
#
#     $ conda activate python39_env
#
# To deactivate an active environment, use
#
#     $ conda deactivate
```

ここで表示されている二つのコマンドはPython環境を立ち上げるときや終了するときに必要なコマンドです。（控えておくと便利かもしれません。）

## 作成したPythonの仮想環境を立ち上げる
先ほど控えたactivateコマンドを実行します。実行すると`(python39_env)`が左につきます。
仮想環境名を変えていた場合は、「python3_env」の部分を差し替えてください。

```
conda activate python39_env
```
お疲れ様でした！ここまでくれば、あとは必要なPythonライブラリをインストールしたり、Pythonスクリプトを実行したりと自由にできます。

```
# pandasのライブラリをインストールする例
conda install pandas
```

Pythonのバージョン確認のコマンドを打つと、指定したバージョンがインストールされていることが確認できます。

```
python --version
# Python 3.9.7
```

立ち上げていた仮想環境を終了したい場合は、deactivateのコマンドからできます。

```
conda deactivate
```
npmについて

# npmとは
Node Package Managerの略であり、Node.jsのパッケージを管理するツール。
Node.jsをインストールすると**npm**もインストールされる。
また、パッケージとは予め用意された便利な機能をまとめたもの。

#npmの使い方
#### ■ npmのバージョン表示
**npm**のバージョンや動作しているか確認する。

```
npm --version
npm -v
```

####■ プロジェクトディレクトリの作成
**npm**で管理するプロジェクトディレクトリを作成する。

```
npm init
```

これを実行すると、**package.json**ファイルが作成される。**package.json**ファイルは、インストールしたパッケージに関する情報を記録している。

####■ パッケージインストール
**npm**でパッケージをインストールする。

```
npm install パッケージ名
```
ここで、パッケージインストールには以下の2種類がある。
**ローカルインストール** : カレントディレクトリのnode_modulesにインストールされる。
**グローバルインストール** : システムディレクトリのnode_modulesにインストールされる。
グローバルインストールされた場合、パッケージを全てのプロジェクトから使用できるようになる。

####■ インストール済みパッケージの確認
インストール済みのパッケージ一覧を表示する。

```
npm list
npm list -g  
```
"<font color="Red">-g</font>"のオプションをつけることで使用しているコンピュータ内すべてのパッケージを表示できる。
Lua5.4で#(長さ演算子)が早くなったらしいのでベンチマークしてみた

# はじめに

Luaでは`table.insert()`という関数が標準ライブラリとして用意されています。
しかし、この関数は遅く、単に末尾に要素を追加するだけならもっと早い方法があります。
その方法としては大きく2つ、カウンターを使う方法と`#`(長さ演算子)を使う方法が知られていると思います。
このうち、長さ演算子が5.4で高速化したと聞いたので、簡単にベンチを取ってみました。

# 使用したソースコード

1から1,000,000までの連番で配列を作る速度を競います。
グローバル変数へのアクセス自体が遅いという話もあるので、一度`table.insert`をローカル変数に束縛する方法も試してみます。

```lua
local function mean(arr)
  local sum = 0
  for i = 1, #arr do
    sum = sum + arr[i]
  end
  return sum / #arr
end

local time_insert = {}
for i = 1, 10 do
  time_insert[i] = os.clock()
  local new = {}
  for j = 1, 1000000 do
    table.insert(new, j)
  end
  time_insert[i] = os.clock() - time_insert[i]
end
print("table.insert: " .. mean(time_insert))

local time_insert2 = {}
for i = 1, 10 do
  time_insert2[i] = os.clock()
  local insert = table.insert
  local new = {}
  for j = 1, 1000000 do
    insert(new, j)
  end
  time_insert2[i] = os.clock() - time_insert2[i]
end
print("local insert: " .. mean(time_insert2))

local time_counter = {}
for i = 1, 10 do
  time_counter[i] = os.clock()
  local new = {}
  local c = 0
  for j = 1, 1000000 do
    c = c + 1
    new[c] = j
  end
  time_counter[i] = os.clock() - time_counter[i]
end
print("counter: " .. mean(time_counter))

local time_length = {}
for i = 1, 10 do
  time_length[i] = os.clock()
  local new = {}
  for j = 1, 1000000 do
    new[#new + 1] = j
  end
  time_length[i] = os.clock() - time_length[i]
end
print("length: " .. mean(time_length))
```

# 結果

比較用のLua5.3.3だとこうなります。

```
table.insert: 0.1646712
local insert: 0.1468932
counter: 0.0185333
length: 0.1276985
```

lua5.4.3だとこう。

```
table.insert: 0.0581953
local insert: 0.0498282
counter: 0.0133932
length: 0.0204012
```

全体的に早くなっていますが、特に`#`はかなり早くなっていますね。6倍くらいです。
`table.insert()`も倍以上早くなっているのは驚きでした。

# 結論

しかし一番早いのはカウンター使う方法で変わりませんでした。うーん。

# おまけ

neovimにbuilt-inされているluajitだとこうなります

```
table.insert: 0.0054451
local insert: 0.0057246
counter: 0.0052584
length: 0.0056855
```
リモートサーバのMySQLの管理用にphpMyAdminをDockerでmacOS上に建てる

# はじめに
MySQLサーバが動いていて、ちょっとphpMyAdminで繋ぎたかったです。

具体的にはRDSでMySQLが稼働中で、phpMyAdminのアドバイザー（チューニングのアドバイスを行ってくれる機能）を使いたかったのですが、通常phpMyAdminを入れるにはPHPが動くWebサーバを建てる必要があります。
EC2などでインスタンスを立てたりする必要があるのですが、閉じ忘れだったり、不用意にアクセスされたりするためお手軽に使えないか、と思いました。

結論からするととても簡単でした。

# コンテナ単独

phpMyAdmin公式のDockerイメージを起動するだけでOKです。
起動時に接続先ホストを与えるのでそちらを事前に用意しておきます。

```bash
$ export PMA_HOST=mysql.example.com
$ docker run --name myadmin -d -e PMA_HOST=mysql.example.com -p 8080:80 phpmyadmin
```

起動が完了したら http://localhost:8080 にアクセスするとphpMyAdminが開きます。後は通常の認証でOKです。（ただし外部からの接続が許可されたユーザーのみです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/0781e887-ef41-05ad-aa5a-1acfeff4b6e0.png)

終了はDockerコンテナを落とせばOKです。

```bash
$ docker down myadmin && docker kill myadmin
```

# docker-compose

```yaml:docker-compose.yml
version: '3'

services:
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=docker.for.mac.host.internal
      - PMA_PORT=3306
#      - PMA_USER=
#      - PMA_PASSWORD=


    ports:
      - "3000:80"

    # セション永続化
    volumes:
      - ./docker/phpmyadmin/sessions:/sessions
```


# SSHトンネル
対象のMySQLサーバが外部から接続できない場合、SSHでトンネルを張ると良いです。

例えばローカルホストのIP接続のみ（ `127.0.0.1` ）を許可している場合、下記のようにするとトンネルを張ることができます。

```bash
ssh -L 3306:127.0.0.1:3306  mysql.example.com
```

こうするとホストOSのポート `3306` で対象サーバのMySQLサーバに接続されます。

なおその場合、phpMyAdminからは `docker.for.mac.host.internal` というホスト名で接続します。
これはphpMyAdminのDockerコンテナからホストOSのmacOSへの接続名となります。
画像のアップロード 参考サイト

https://webukatu.com/wordpress/blog/20969/


https://gray-code.com/php/save-the-upload-file/

https://gray-code.com/php/get-kind-of-file/


https://mugenweb-note.com/web/php/php_image_resize

https://uxmilk.jp/14317


https://hirokun-notepad.com/210517-tumiage/

https://gray-code.com/php/make-the-board-vol19/

https://gray-code.com/php/make-the-board-vol20/

https://freeks-japan.blog/php/4/16/

https://yu-nix.com/blog/2020/9/24/php-file-get-contents/

https://techacademy.jp/magazine/18804

https://www.projectgroup.info/tips/php/tips_0003.html

https://ysklog.net/php/1577.html

https://techplay.jp/column/619
Laravel8 コントローラの使い方



>
Laravelにおけるコントローラクラスを理解しよう
人気のPHPフレームワークLaravelを習得しよう 第4回
https://codezine.jp/article/detail/11524

こちらで勉強しててLaravel8ではハマったのでメモします。
おそらく記事はver8以前の記述ではないかと思います。

#１．実装内容（エラー版）
ページに記載通りに
①Control Class

```php:\app\Http\Controllers\HelloBladeWithDataController.php
<?php
namespace App\Http\Controllers;  // （1）

use App\Http\Controllers\Controller;  // （2）

class HelloBladeWithDataController extends Controller  // （3）
{
	public function __invoke()  // （4）
	{
		$data["name"] = "武者小路";  // （5）
		return view("helloWithData", $data);  // （5）
	}
}
```


②web.php

```php:web.php
Route::get("/chap4/helloBladeWithData", "HelloBladeWithDataController");
```

③View Class 


```php:\resources\views\helloWithData.blade.php
<?php
namespace App\Http\Controllers;  // （1）

use App\Http\Controllers\Controller;  // （2）

class HelloBladeWithDataController extends Controller  // （3）
{
	public function __invoke()  // （4）
	{
		$data["name"] = "武者小路";  // （5）
		return view("helloWithData", $data);  // （5）
	}
}
```

#２．エラー内容
◆メッセージ
UnexpectedValueException
Invalid route action: [HelloBladeWithDataController].

◆イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095609/8d7665da-0c50-4452-2929-4bbe0db419ca.png)


#３．原因
Larave8でWeb.phpの記載ルールが変わった模様。。

#４.対処法
```php:web.php
//　エラー例
//Route::get("/chap4/helloBladeWithData", "HelloBladeWithDataController");
//　正解
Route::get("/chap4/helloBladeWithData", \App\Http\Controllers\HelloBladeWithDataController::class);
```

#５.おまけ invoke使わない例
|url |control class  | control method | 
|---|---|---|
|/chap4/helloMusha |\App\Http\Controllers\Chap4Controller |helloMusha  |
|/chap4/helloNakano |同上  |helloNakano  |

```php:\app\Http\Controllers\Chap4Controller.php
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class Chap4Controller extends Controller
{
	public function helloMusha()  // （1）
	{
		$data["name"] = "武者小路";  // （2）
		return view("helloWithData", $data);  // （2）
	}
	public function helloNakano()  // （3）
	{
		$data["name"] = "中野";  // （4）
		return view("chap3.hello", $data);  // （4）
	}
}
```



```php:web.php
Route::get("/chap4/helloMusha", [\App\Http\Controllers\Chap4Controller::class,'helloMusha']);
Route::get("/chap4/helloNakano", [\App\Http\Controllers\Chap4Controller::class,'helloNakano']);
```



#参考元

https://prograshi.com/framework/laravel/target-class-not-exist/
React:Bootstrap Tabタイトルを子コンポーネントから変更

ReactでBootstrapのTabsを使っていて、keyのあるオブジェクトから作ったTabのタイトルを子コンポーネントからkeyを指定して変更した。メモを2点ほど。

```react:ComponentParent
export default function ComponentParent(props) {
  const [tabTitles, setTabTitles] = useState(null)
  const [currentKey, setCurrentKey] = useState(null)

  useEffect(() => {
    // ここでは、例なので単純にオブジェクト直接記述
    setTabTitles({ 111: "タブ1", 222: "タブ2", 333: "タブ3" })
    setCurrentKey(111)
  }, [])

  useEffect(() => {
    // 何か選択が変わった時の処理
  },[currentKey]}
    

  const TabSample = () => {
    if (!currentKey || !tabTitles) return <div>Loading...</div>;
    return (
      <Tabs
        id="tab-sample"
        activeKey={ currentKey }
        onSelect={(k) => setCurrentKey(k)}
      >
　　　　　　　　　　　　　　　　{/* メモ1： オブジェクトをmapで展開するにはこう書けばよいみたい。 */}
        { Object.keys(tabTitles).map(key => <Tab eventKey={ key } title={ tabTitles[key]} key={ key }></Tab> }
      </Tabs>
    )
  }

  const changeTabTitle = (key, title) => {
    /* メモ2： tabTitles[key] = title してセットする方法だと更新されない。展開すること。 */
    setTabTitles({...tabTitles, [key]: title}) 
  }

  return (
    <TabSample />
    <ComponentChild 
       changeTabTitle={ (key, title) => changeTabTitle(key, title)　}　
    />
  )
}
```

```react:ComponentChild
export default function ComponentChild(props) {

 const clickChangeTabTitle1 = () => {
   props.changeTabTitle(111, "タブA")
 }

 return (
   <button onClick={ clickChangeTabTitle1 } >タブ1のタイトル変更</button>
 )
}
```
MySQLのコマンド

#MySQLの起動・停止

MySQLのバージョン確認
```$ mysql --version```
または
```$ systemctl status mysqld.service```

サーバーを起動
```$ mysql.server start```
または
```$ sudo systemctl start mysqld```

サーバーを停止
```$ mysql.server stop```
または
```$ sudo systemctl stop mysqld```

#MySQLに接続

テーブルとユーザを指定して接続（パスワードなし）
```mysql -u ユーザ名```

テーブルとユーザを指定して接続（パスワードあり）
```mysql -u ユーザ名 -p```

接続解除
```exit```

#データベース

データベース一覧
```show databases;```

データベース選択
```use データベース名```

#テーブル

テーブル一覧の表示
```show tables;```

テーブル構造の表示
```desc テーブル名;```

テーブルのオーナーの変更
```alter table テーブル名 owner to オーナー名;```

#ユーザー

ユーザー一覧（すべての項目）
```SELECT * FROM mysql.user;```

ユーザー一覧（ユーザー名、ホスト名のみ）
```SELECT User,Host FROM mysql.user;```
.Net6.0でワーカーサービスを作ると、UserSecretsがうまく働かない

# はじめに

.Net6.0でワーカーサービスを作ってみた。
デバッグ実行しても、UserSecretsが読み取られない。

これ書いてる時点では直ってないけど、あなたが読んでるときには直ってるかもしれません。
**とりあえずアップデートしましょう。**
アップデートしても直らない場合は↓

# 解決方法

UserSecretsのパッケージを、明示的に読み込むと直る。
NuGetするか、プロジェクトファイルを直接編集してどうぞ。

↓こんな感じに、UserSecretsの行を追加します。
Versionは、Hostingと一致させると良いでしょう。

```xml
<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-rc.2.21480.5" />
  <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0-rc.2.21480.5" />
</ItemGroup>
```

ワーカーサービスのプロジェクト作ると、自動でHostingのパッケージが追加されます。
UserSecretsは、Hostingパッケージの依存関係にあるから、一緒に読み込まれてるはずなのに…

.Net5.0では、Hostingのパッケージだけで、うまいことUserSecretsも有効になります。

# 具体的な症状

プロジェクトファイルにUserSecretsIdを入れてビルドすると、アセンブリにUserSecretsId属性がつきます。
ユーザシークレットさんは、この属性を見て、secrets.jsonのパスを特定しています。
この属性が無い場合、読み込まれません。

現在の.Net6.0では、UserSecretsパッケージを直接参照しないと、この属性がつかないっぽい。
PolygonArrayメッセージを使う ROS

# はじめに
3次元の点のリストのROSメッセージに geometry_msgs/Polygon というmsgがあります。
メッセージの例は以下の様になります。

```
points: 
  - 
    x: 235.61074829101562
    y: 235.62962341308594
    z: 0.0
  - 
    x: 393.2195739746094
    y: 235.62974548339844
    z: 0.0
  - 
    x: 550.6107788085938
    y: 235.62962341308594
    z: 0.0
  - 
    x: 235.60983276367188
    y: 393.2467041015625
    z: 0.0
  - 
    x: 393.2194519042969
    y: 393.2442321777344
    z: 0.0
```

これを更にリストにして使いたいと思い調べたところ jsk_recognition_msgs の PolygonArray というものが使えそうだと思い使い方を調べてまとめました。

# PolygonArray
このメッセージの内部を調べてみると PolygonStamped のリストであることがわかりました。
(参考)[messageの型](http://docs.ros.org/en/indigo/api/jsk_recognition_msgs/html/msg/PolygonArray.html)

更に使い方として以下のようなサンプルプログラムがあり参考にしました。
(参考)[sample program](https://github.com/jsk-ros-pkg/jsk_visualization/blob/master/jsk_rviz_plugins/samples/polygon_array_sample.py)

# 使い方

最後に実際に使ってみます。

(環境) ros noetic, ubuntu20.04

まず、インストールします。

```
sudo apt install ros-noetic-jsk-recognition-msgs 
```

pythonでpub,subするサンプルプログラムは次のようになります。

次にサンプルを作成します。
publishする場合は次のようになります。

```python:p_array_pub.py

import rospy
from jsk_recognition_msgs.msg import PolygonArray
from geometry_msgs.msg import Polygon, PolygonStamped, Point32

msg = PolygonArray()

p1 = PolygonStamped()
p1.polygon.points = [Point32(x=1, y=2, z=3),
                     Point32(x=1, y=2, z=3),
                     Point32(x=1, y=2, z=3)]

p2 = PolygonStamped()
p2.polygon.points = [Point32(x=4, y=5, z=6),
                     Point32(x=4, y=5, z=6),
                     Point32(x=4, y=5, z=6)]


msg.polygons = [p1,p2]

pub = rospy.Publisher('p_array', PolygonArray, queue_size=1)
rospy.init_node('pub')
r = rospy.Rate(1)
while not rospy.is_shutdown():
  pub.publish(msg)
  print("publish!")
  r.sleep()

```

Subscribeする場合は次のようになります。

```p_array_sub.py
import rospy
from jsk_recognition_msgs.msg import PolygonArray

def callback(msg):
  print("*** callback ***")
  print(msg)

rospy.Subscriber('p_array', PolygonArray, callback)
rospy.init_node('sub')
rospy.spin()

```
Confluence：Excel VBAからConfluenceの作成済みページにラベルを追加する (Server/DataCenter)


# 手順
## １．VBA-JSONの追加

以下を参照ください。

https://qiita.com/tabimoba/items/7da7e19cef8d956129dd

## ２．参照設定の追加

以下を参照ください。

https://qiita.com/tabimoba/items/7da7e19cef8d956129dd


## ３．VBAコードの追加

Microsoft Visual Basic for Applications を開き、次のコードを入力し、実行します。

```vb
Sub GetPage()
  Dim ohttpReq As New XMLHTTP60
  Dim dJsonParsed As Dictionary
  Dim sUrl As String
  Dim sJson As String
  Dim label As New Dictionary

  ' ラベルを追加する
  label.Add "name", "ラベル"
  sJson = ConvertToJson(label, Whitespace:=2)

  ' エンドポイントのURLを指定する
  sUrl = "https://<ConfluenceのベースURL>/rest/api/content/<ページID>/label"

  ' HTTPリクエストする
  With ohttpReq
    .Open "GET", sUrl
    .setRequestHeader "Authorization", "Basic <Basic認証のユーザー名とパスワード(Base64エンコード)>"
    .setRequestHeader "Content-Type", "application/json; charset=UTF-8"
    .setRequestHeader "X-Atlassian-Token", "no-check"
    .send (sJson)

    Debug.Print .responseText ' HTTPレスポンスをイミディエイトに出力
  End With
End Sub
```
【第３回】Confluent Platformのデモを試してみる(トピック編)

###概要
今回は、[第一回](https://qiita.com/Alex-hiro/items/0209b2faec9c00cf3ca1)で構築したConfluentのクラスタを利用しConfluent Control Centerにログインしてトピックの状態をGUIで確認してみたいと思います。

###Confluent Control Centerにログイン
１.以下のURLにWebブラウザからコンフルエントコントロールセンターGUIにアクセスします。

```sh
http://localhost:9021
````

２.次にログイン画面が表示されますので、ここで、クラスターへのスーパーユーザーアクセス権を持つ"superUser"とパスワード"Confluent"でControlCenterにログインします。
![スクリーンショット 2021-09-22 14.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/ceb36135-f497-ea9b-c17e-aaa039c5d4d5.png)

###トピック
１.Confluent Control Center(CCC)で「Topics」をクリックしKafkaクラスター内のトピックの状態を見てみましょう。
![スクリーンショット 2021-10-04 16.32.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/b779bd7e-949f-675e-31f0-b2825c11d49d.png)
2.上記画面で「wikipedia.parsed」をクリックすると以下の画面に遷移します。
![スクリーンショット 2021-10-04 16.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/793ba96c-7a7b-723e-31d2-1fa8d75a0b6d.png)
この画面ではスループットやパーティションのレプリカの状態などの概要を確認することができます。さらに、この画面の下部ではどのブローカーがどのパーティションのリーダーであるか、すべてのパーティションがどこにあるかといった情報も確認することができます。

３.このトピック（wikipedia.parsed）のリアルタイムのメッセージを確認するために「Messages」（赤丸のところ）をクリックします。
![スクリーンショット 2021-10-05 13.49.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/65fec830-37d8-5c25-c312-34ff63b2ed59.png)
リアルタイムに変化する様子がGUIで確認できました。

４.このトピック（wikipedia.parsed）のスキーマを確認するために「Schema」（赤丸のところ）をクリックします。
![スクリーンショット 2021-10-05 14.15.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/67092e41-ce48-3be9-6a38-d2bfeecd767b.png)
このトピックのトピック値はスキーマレジストリに登録されているスキーマを使用しています。

５.このトピック（wikipedia.parsed）の構成の設定を確認するために「Configuration」（赤丸のところ）をクリックします。
![スクリーンショット 2021-10-06 15.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/4a169fdc-bbae-8e7b-4289-6035d30b66e9.png)
上記のような画面が表示されトピックの構成をGUIで確認することができました。

６.今度は左のメニューで[Topics]をクリックし、右上の[+Add a topic]ボタンをクリックして、Kafkaクラスターに新しいトピックを作成します。GUIから簡単にトピックが追加できました。さらにクラスター内のKafkaトピックの設定を表示および編集することもできます。 
詳細については、[Confluetのトピック管理のドキュメント](https://docs.confluent.io/platform/current/control-center/topics/overview.html)を参照ください。
![スクリーンショット 2021-10-06 16.08.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/155453d6-98da-0422-9ddf-6653015253cf.png)

個人的にはトピックを追加する時GUIから簡単にできるので楽（便利）だなと思いました。

時間をみつけて別の項目も見てみようかなと思います。
AWS CLI による Lambda Layer のアップデートについて


CodeBuildを使ってLambdaに対して自動デプロイしていたのだが、Layer部分で急にエラーが出るようになったので調べてみた。

## TL;DR

- CodeBuild だけでなく、コンソールからの AWS CLI でも起きる
- update-function-configuration を利用しなければ影響はない
- Lambda関数の説明に「aws:states:opt-out」を追加すれば、取り敢えずは今まで通り動く
- 2021/12/1 以降は上記説明を付けても無理そうなので、検討必要

## Error Log

```
An error occurred (ResourceConflictException) when calling the UpdateFunctionConfiguration operation: The operation cannot be performed at this time. An update is in progress for resource: [ARN]
```

## ResourceConflictException

さて、エラーログに例外が明記されていますので調べました。

しかし、上記で検索すると以下の解決策が出てきますが、これでは解決できません。

> リソースが既に存在しているか、別のオペレーションが進行中です。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/API_UpdateFunctionConfiguration.html

ということで、もう少し調べてみました。

## update-function-configuration

Layerの設定を行うコマンドなのだが、これを利用するときだけエラーが発生した。

使っているレイヤーに問題があるのかどうか考えたり、レイヤーの上書きが問題の可能性も考えたが、Layerを消すコマンド（「update-function-configuration」コマンドで空リストを指定するだけ）を使ってもエラーが起きたことから、「update-function-configuration」コマンド自体に問題があると想定して、コメントアウトするとエラーが出なくなったことから確信へと変わった。

## the state of AWS Lambda functions

あまり気にしていなかった（知らなかった）だけなのだが、どうやら Lambda には状態というものが存在するようです。

調査中なので割愛しますが、アップデートする際に「LastUpdateStatus」という状態があり、これが「InProgress」になっているとアップデート（上書き）出来ないようになっており、このタイミングで「update-function-configuration」をかけて失敗したものと思っています。

実際にエラーログにも「InProgress」と書かれていました。

何で急にこうなったのかはちゃんと調べます。。

## 解決策

取り敢えずは、Lambda 関数の説明文に「aws:states:opt-out」と書けば、従来通りに動いてくれました。
「opt-out」なのでデフォルトでは「ON」になっているんですね。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56144/c356b9a4-d198-4722-4a0f-25656b2caaaf.png)

## 最後に

常に情報をアップデートすることと、常に勉強しなくては、、と思いました。

## Ref

- [update-function-configuration](https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-configuration.html)
- [Coming soon: Expansion of AWS Lambda states to all functions](https://aws.amazon.com/jp/blogs/compute/coming-soon-expansion-of-aws-lambda-states-to-all-functions/)
- [Tracking the state of AWS Lambda functions](https://aws.amazon.com/jp/blogs/compute/tracking-the-state-of-lambda-functions/)
[Golang]Goでの繰り返し処理をまとめる

# はじめに
改めてGoの繰り返し処理についてまとめて行きます。

# for文

### 普通のfor文

```golang
  for i := 1; i <= 5; i++ {
        fmt.Println(i)
        // 1,2,3,4,5
    }

```

#### continueを使って、スキップする

```golang
for i := 0; i < 10; i++ {
    if i%2 == 0 {
        continue
    }
    fmt.Println(i)
}
```

#### breakを使って処理を終了する

```golang
for i := 0; i < 10; i++ {
    if i == 5 {
        break
    }
    fmt.Println(i)
}
```

# for range

```golang
for i, v := range []string{"foo", "bar", "baz"} {
    fmt.Println(i, v)
}
```

結果 
0 foo
1 bar
2 baz

### 連想配列を使う場合

```golang
for k, v := range map[string]int{"key-1": 100, "key-2": 200, "key-3": 300} {
    fmt.Println(k, v)
}
```

結果
key-1 100
key-2 200
key-3 300

# Eachを使いたい人向け

```golang
package main
import "fmt"


type StrSlice []string

func (a StrSlice) Each(f func(i int, v string)) {
    for i, v := range a {
        f(i, v)
    }
}

type IntSlice []int

func (a IntSlice) Each(f func(i int, v int)) {
    for i, v := range a {
        f(i, v)
    }
}

func main() {
    StrSlice{"foo", "bar", "baz"}.Each(func(i int, v string) {
        fmt.Println(i, v)
    })

    IntSlice{10, 20, 30}.Each(func(i int, v int) {
        fmt.Println(i, v)
    })
}
```

# 終わりに
多言語にあるようなeachを使えないことに不満をいだいている人が多いけど、
自分的には、for range使えればいいかなと思ってます。
マジで使いたかったら、上記の用に作っちゃえばいいかなって感じですね！

# 参考文献
https://golang.hateblo.jp/entry/2019/10/07/171630
Gtk3アプリ パーシャルクラス自動生成ツール

###パーシャルクラス自動生成ツール

https://github.com/iotagtk1/GtkCategoryGenerator

[Release](https://github.com/iotagtk1/GtkCategoryGenerator/releases)

既存のクラスからパーシャルクラスを生成す
るツールを作りました。

####使い方

####Riderの外部ツールに登録する
<img width="300" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/61c8752e-3163-5e25-4516-b80a94fe6774.png">
####引数を設定する
```
引数はReadMeを参照ください
```
####ファイル名に使いたい文字をコピーする
<img width="200" alt="Screenshot from 2021-10-07 13-10-13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/781e8c8c-9430-6059-a206-629f8eb18497.png">
####エクスプローラーで生成したい元クラスを選択する
<img width="300" alt="Screenshot from 2021-10-07 13-12-23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/5e30f9fe-d58b-c089-523b-d97130b47bf0.png">
元のクラスの中身
<img width="600" alt="Screenshot from 2021-10-07 13-13-47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/6ea6dfb7-0539-dbc3-92af-59849ac5db65.png">
####外部ツール　実行する
Riderのエクスプローラーの右クリックから実行します
####生成されたパーシャルクラス
パーシャルクラスが同じ階層に生成されます。
<img width="300" alt="Screenshot from 2021-10-07 13-13-15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/13c965ac-219f-0fc9-b686-5315353e0ede.png">

生成されたパーシャルクラスの中身
<img width="400" alt="Screenshot from 2021-10-07 13-13-27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/2fe5c83e-2518-de83-7b64-50382b5900a6.png">

[C#とNode.jsを連携する](https://qiita.com/iota_11/items/f3ddb4fbb27ffd192685)へ続く
はじめてのIoTCentral（Arduino MKR WIFI 1010編）

M5Stack編に引き続きデバイスをArduino MKR WIFI 1010にしてみました。
IoT Centralアプリケーションは変更なしです。デバイステンプレートも変更の必要はありませんでした。
IoT Centralアプリケーションの作成方法は[こちら](https://qiita.com/linyixian/items/93d6edb83b9e1f09d1c1)を参照してください。

デバイス用のサンプルプログラムは、Arduino公式サイトから[このレポジトリ](https://github.com/firedog1024/mkr1000-iotc)へリンクされてるのですが、試してみたけどなんか動かなかったのとCo2センサー（SCD30）を使いたかったので参考にしつつちょっと書き換えてみました。元のサンプルではDeviceTwin、DirectMethod、C2DMessageなども実装されていますが、今回のプログラムではD2CMessageだけになっています。あとMKR WIFI 1010専用です。

レポジトリがPublicだったのでユーザーさんかなと思ったら、プロフィール見てみるとIoT Centralの主任エンジニアさんでした。中の人が作ってたんだ・・・

#使用するデバイス
さて、[MKR WIFI 1010](https://store-usa.arduino.cc/products/arduino-mkr-wifi-1010)ですが今年8月から国内で販売が開始されました。MKRシリーズの基板にWIFI-BTチップが搭載されています。チップメーカーはublox社なのですがどうなら中身はESP32のようです。チップはSPI接続となっています。Wifiチップが新しくなったのでライブラリも従来の物から変更になっています。

#インストールするライブラリ
・WiFiNINA
・ArduinoMqttClient
・RTCZero
・SCD30　[ここ](https://github.com/Seeed-Studio/Seeed_SCD30)からダウンロードしてインストール

#準備
ArduinoIDEは最新にしてください。現時点での[最新版](https://www.arduino.cc/en/software)は1.8.16です。
サンプルプログラムを実行する前にWifiモジュールのファームウェアのアップデートとSSL Root証明書の登録が必要になります。
デバイスがMQTTプロトコルを使う場合には、TSL/SSL経由で接続する必要があります。その際Root証明書を参照しますが、MKR WIFI 1010ではFirmware Updaterを使ってWifiモジュール内に登録することができます。

ArduinoIDEを立ち上げて、ライブラリのインストールが完了したらツールメニューの「WiFi101/WiFiNINA Firmware Updater」をクリックします。
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/8f88dfed-17fa-b071-ca77-50311998d58b.png)

Updaterウィンドウが開いたら、右上の「Open Updater Sketch」ボタンをクリックします。Updaterスケッチが開きますのでそのままデバイスに書き込んでください。
スケッチが書き込めたら一番新しいファームウェア（現時点での最新は1.4.8）を選択してから「Update Firmware」ボタンをクリックします。
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/9487b1ec-37a1-2776-3a43-6ec68dc5534b.png)

次は「Add domain」ボタンをクリックします。
ダイアログが開きますので、「microsoft.com:443」と入力し、OKボタンをクリックします。
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/ceb567b5-8743-528d-4699-1b71766664b5.png)

リストに先ほど入力したドメインが表示されているのを確認してから、「Upload Certificates to WiFi module」ボタンをクリックして証明書を登録します。
![004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/21db42b2-0059-c409-2d27-59ac14483bc1.png)

以上で準備が完了しました。

#プログラム
[こちら](https://github.com/linyixian/MKRWIFI1010IoTC)からプロジェクトをダウンロードして、適当な場所に展開してください。

IoT Centralアプリケーションで新たにデバイスを使いして、接続情報をメモしておきます。

メインプログラムを開いたら、「arduino_secrets.h」タブに切り替えて無線LAN設定および接続情報を書き込みます。
![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/aa15375a-4c8e-2189-9b6c-1e763b116ff1.png)

後はプログラムをデバイスに書き込んで完了です。
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62606/e3e8ed6e-7b21-c467-2405-8da8e85c1505.png)

以上になります。

サンプルを作り始めた当初はMQTT接続がうまくできなかったのですが、証明書の登録方法がわかりそれから接続ができるようになりました。
一つ気になるのは登録した証明書のリストがUpdaterを開きなおした際には反映されないところです。
リストには上がっていなくてもちゃんと記録されているようなので今のところ問題はなさそうです。
登録できる証明書数は10件ほどということなので、確認のためにもいつか修正されるといいのですが。
AWSデプロイ時のプリコンパイルでつまづいた話


https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1

こちらの記事を参考にAWSのデプロイを進めていると、最後の最後であるプリコンパイルで詰まる

```
rake assets:precompile RAILS_ENV=production
```

を実行すると長文のエラー
よくみてみると

```
error /var/www/rails/myapp/node_modules/node-sass: Command failed.
```

node-sass周りに問題がある？

https://qiita.com/kensuke_kumaki/items/54e749e623cdaedce472

こちらの記事を参考に解決。

```
node -v 
v16.1.0
```

nodeのバージョンが非推奨だったようで記事の方法を試すと解決。
DNN-featureimportance(null importance)

```
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.set()
plt.style.use('ggplot')
sns.set_style('whitegrid')

'''
必要なオブジェクト
- numpy 3d-array
- numpyにする前のdataframeのカラム名リスト

通常の損失を計算
ある特徴量を複数回シャッフルした状態で複数回損失を計算し平均をとる
seabornでプロット

array: 3Dnp.array
numiteration: シャッフルして損失を計算する回数
maximize指標の時は棒グラフがプラスなら有益ということになる
'''

# 3次元のnumpyの列をシャッフルする。
# イテレーションごとに3次元配列を再定義しないとすべての列がシャッフルされてしまうので注意
def shuffletensorcolumns_loop(array,i: int) -> None:
    tmp = array[:,:,i]
    for j in range(array.shape[0]):
      np.random.shuffle(tmp[j]) # 破壊的処理なので代入不要
    array[:,:,i] = tmp
    
# 3次元配列ともともとの特徴量のカラムを用意する
valid_X = np.arange(1,101).reshape(2,5,10)
columns = [["a","b","c","d","e","f","g","h","i","j"]]

losslist = []
# モデルロード
model.load()
# 普通に予測したスコア
pred_y = model.predict(Valid_X)
loss = rmse(pred_y,valid_y)
losslist.append(loss)

for i in range(valid_X.shape[2]):
  valid_X2 = valid_X.copy()
  featureimportancelist=[]
  
  for j in range(5):
    shuffletensorcolumns_loop(valid_X2,i)
    pred_y = model.predict(valid_X2)
    loss = rmse(pred_y,true_y)
    featureimportancelist.append(loss)

  losslist.append(featureimportancelist)

# 損失のリストを獲得できたら後はプロットするだけ
kizyun = np.array(losslist[0])
lossmean = np.array([np.mean(loss) for loss in losslist][1:])
lossstd = [np.std(loss) for loss in losslist][1:]
featureimportances = lossmean-kizyun

pfi = pd.DataFrame(data={'lossmean':lossmean,'lossstd':lossstd,'lossmean-originaldiff_pfi':featureimportances})
pfi['features'] = pd.DataFrame(columns).T
fig = plt.figure(figsize=(16,12))
ax = fig.add_subplot(1, 1, 1)
ax.barh(width=pfi["lossmean-originaldiff_pfi"], y=pfi.features)
ax.set_ylabel('feature')
ax.set_xlabel('featureimportances')
ax.set_title('featureimportances')
plt.show()

```
Electron+ReactでHello world

ElectronのUIをReactで作ってみます。
次のステップで作っていきます。

1. Reactアプリをcreate-react-appで作る。
1. 作ったReactアプリをElectronで読み込み表示する。

ググるとlocalhost:3000で起動したReactアプリを読み込む例が多いですが、ここではビルドしたものを読み込むことにします。

※環境: Windows 10 Home, Node.js v14.17.4, Electron v15.1.1

# Reactアプリを作る

まずはcreate-react-appでReactアプリを作ります。
アプリ名は適当にerhelloとしますが何でもOKです。

```
> npx create-react-app erhello
```

一応Hello worldですので`App.js`でHello, world!と表示するように変更しますが、そのままでもかまいません。

```jsx:App.js
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello, world! 
        </p>
      </header>
    </div>
  );
}

export default App;
```

# ReactアプリをElectron上で表示する

Electronを追加インストールします。

```
> cd erhello
> npm i -D electron
```

続いて、package.jsonを編集します。
いつも通りエントリーポイントのファイル名を変更します。
加えて、Reactのアウトプットが相対パスで動作するように`homepage`も指定します。

```package.json
  ...
  "main" : "main.js",
  "homepage" : "./",
  ...
```

main.jsは[前回](https://qiita.com/fumi-410/items/4539582fb84e09290ab6)のElectron単独のHello,worldで作ったものを使い回します。
今回の変更点は、読み込むindex.htmlのパスをReactのビルド先に合わせることだけです。

```main.js
const { app, BrowserWindow } = require('electron');

function createWindow () {
  // ウインドウ作成
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
  });

  // index.htmlの内容でウィンドウ表示
  mainWindow.loadFile('./build/index.html'); // パス変更
}

// Electronの初期化完了時に呼ばれる
app.whenReady().then(() => {
  createWindow();

  // Mac用処理
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  })
});

// (Mac以外は)ウインドウが全部閉じられたら終了
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit();
});
```

ビルドを実行し、Electronアプリを起動してみます。

```
> npm run build
> npx electron .
```

次のようにHello world画面が表示されれば成功です。

![electronreact.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149951/17d26aed-994e-fa3a-0182-2865e30b9ff8.png)

次回は、Electronのメインプロセスとの通信を試してみたいと思います。
[Golang]GinでCookieをセットする方法

# はじめに
GinでCookieをセットするやり方でハマったので、記録します。

# やり方
```golang
	// Cookieをセット
	cookie := new(http.Cookie)
	cookie.Value = token //Cookieに入れる値

    // samesiteをnonemodeにする
	c.SetSameSite(http.SameSiteNoneMode)

    // ローカルの場合
	if os.Getenv("ENV") == "local" {
		log.Println("cookieをセットする")
		c.SetCookie("jwt", cookie.Value, 3600, "/", "localhost", true, true)
	}

　　　　　　　// 本番環境の場合
	if os.Getenv("ENV") == "production" {
		log.Println("productionでcookieをセットする")
		c.SetCookie("jwt", cookie.Value, 3600, "/", "your_domain", true, true)
	}
```


### SetCookieについて

```golang
SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
```

# ハマったところ
- samesiteをnoneモードにしないといけないところ
- 環境に合わせて、ドメインを入力するところ

# 終わりに
なかなかGinに関する情報って出てこなかったので、苦労しました、、

# 参考記事
https://www.sakurasaku-labo.jp/blogs/samesite-none
ハンズオン5 HTTPS通信でアクセス可能にする

この記事を書いている私について

インフラ系PMO歴半年でAWSクラウドプラクティショナーを取ったばかりの私が
AWS CloudTechという動画学習サービスに参加し、AWSエンジニアを目指すための備忘録です:fire:

構築→記事作成→指摘反映の中で間違いがあったら業務でも発生するので、これからも気を引き締めて行きたいと思います。


本記事の目標
-
前回の「独自ドメインの設定/障害時にSORRYページへ通信を流す」に引き続き、
今回はAWS Certificate ManagerをセキュアなHTTPSで通信できるように設定を変更していきます。

https://qiita.com/zetzetn/items/2bdeb8817c6c456ba4f7


前回の記事ではブログサービスにアクセスするのにHTTPで通信をしており、
このままではセキュリティに問題があります。

本記事ではAWS Certificate Managerで証明書を発行してELBにアタッチすることでHTTPS通信を可能にし、
ELBのセキュリティグループでHTTPS通信を許可する設定の追加なども行なっていきます。



今回の構成図
-
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465906/4c5b02ef-45aa-3e33-67df-6713f5ba5cf0.png)


※構成図の作成に[cloudcraft](https://app.cloudcraft.co/ "cloudcraft")を利用しています。

https://app.cloudcraft.co/


構築の流れ
-

以下の流れで構築を進めます。

・前回の環境を再構築
・ロードバランサーでHTTPS通信を受けるよう設定
・ELBのセキュリティグループでHTTPS通信を許可
・WordPressの対応
・HTTPS通信が出来るか確認
・HTTP通信の許可設定を削除


・前回の環境を再構築
-
・EC2インスタンスが2台立ち上がっていることを確認する。
・RDSを削除した場合はスナップショットから復元する。
・ALBを削除した場合は作成する。
・S3を削除した場合は作成する。
・前回取得したドメインでブログが閲覧できること確認する。

＊余談ですが、前回までの復習になるので再構築はとても勉強になります。
　素早くミスなく構築したいので、近いうちにqwiklabsを使って反復練習をしてみたいと思います。
　年内にはqwiklabsを使った社内勉強会を開きたいですね。

https://run.qwiklabs.com/

・ロードバランサーでHTTPS通信を受けるよう設定
-

###リスナーを追加
　※リスナーとは通信を受付けるポートの許可設定のことになります。

転送先に作成したターゲットグループを選択し、ACM証明書を発行します。
完了すると、Route53のCNAMEに検証用のレコードが追加されます。


・ALBのセキュリティグループでHTTPS通信を許可
-
インバウンドルールで、全てのIP（0.0.0.0/0)からのHTTPS通信を許可します。
　※私の体感ですが、証明書が発行されるまで数分時間がかかります	


・WordPressの対応
-
この時、HTTPS通信を許可することでWordPressの仕様により、ブログの表示が崩れます。
その為、2台のEC2インスタンスに下記の設定ファイル(wp-config.php)にコードを追加することで対応します。

```
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  $_SERVER['HTTPS'] = 'on';
  $_ENV['HTTPS'] = 'on';
}
```

この段階でまだ表示が崩れている場合はEC２インスタンスにログインして下記のコマンドを実行します。

```
UPDATE wp_options SET option_value = 'https://[独自ドメイン名]' WHERE option_name IN ('siteurl', 'home');

```
※独自ドメイン名]はご自身で取得したドメインになります。

上記のコマンドによりRDSのDBに保存されているURLを更新することで正常にブログを表示することが出来ます。

・HTTPS通信が出来るか確認
-
ブログのURLに鍵マークがついていることで確認します。


・HTTP通信の許可設定を削除
-
HTTP通信を許可した状態だとセキュリティ上の問題があるためELBのセキュリティグループ・リスナーにて、HTTP通信の許可設定を削除します。

これにて課題は終了です。



サービス停止
-
次のハンズオンでも今回の設定を使いますので、サービス停止は行わず一気に次のハンズオンもやってしまうことをお勧めします。
一旦学習を止められる場合は下記のサービスを停止しておきましょう。

■EC2(オンデマンド)→時間単位または秒単位で計算されるため停止中にすること。

■RDS(オンデマンド)→RDS の使用料は秒ごとに課金されるため、スナップショットを取って削除すること。

■ALB→実行時間に対して時間単位、または1時間未満で使用料を課金されるため、削除すること。

■S3→保存したオブジェクトのサイズ、保存した期間の長さによって課金されるため、削除すること。


ハンズオン5に発生する費用一覧
-
・EC2 x 2
・RDS x 1
・ALB x 1
・Route 53 x 1
・S3 x 1

1時間に13円ほど費用が発生します。


最後に
-

AWS Certificate Managerで証明書を発行してHTTPS通信を行う方法を学びました。
当たり前のようにHTTPSを使って色んなサイトを見ていますが、自分で発行すると
普段見ているサイトがHTTPSになっているか気になってきますね→私だけ？(笑)

AWS CloudTechの課題としてこれらが残っていますので、
やったことを今後のQiita記事にして発信していきたいと思います。
これから始められる方の参考になれば嬉しいです。

今後の学習予定↓↓↓
・キャッシュサーバーの配置
・CloudFormationの作成、更新
・Lamda関数
・Docker

内容に不備がございましたら、ご指摘いただけますと幸いです。


今後の励みになりますので、良ければ「LGTM」をお願いします。 :bow:
閲覧ありがとうございました。

---
この記事はAWS初学者を導く体系的な動画学習サービス「AWS CloudTech」のハンズオンを基に作成しました。

https://aws-cloud-tech.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465906/00637e63-5339-1b83-c3c1-720e95174ec0.png)
[React]フォームをエンターキーで送信する方法

# はじめに
検索フォームを入力したときに、検索ボタンをわざわざ押すのが面倒だったので、
エンターキーで検索条件を送信する方法を探しました。

# やり方
```tsx
export default function SearchField() {
  const dispatch = useDispatch();
  const [inputText, setInputText] = React.useState("");

  const pressEnter = (e: any) => {
    // ここでエンターキーを指定する
    if (e.key == "Enter") {
      dispatch(
        fetchPresentations({
          query: e.target.value,
        })
      );
    }
  };

  return (
    <Search>
      <SearchIconWrapper>
        <SearchIcon />
      </SearchIconWrapper>
      {/* onKeyDownを使用する */}
      <StyledInputBase placeholder="検索" onKeyDown={(e) => pressEnter(e)} />
    </Search>
  );
}
```

# 完成
これで、エンターキーを押すだけで検索することが出来ます。
検索ボタンも必要なくなったので、非表示にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456505/c8606a4e-a1fa-3f8f-1252-f82cfee84754.png)
Unity x Androidビルドで「Failed to update Android SDK package list. See the Console for details.」

２ヶ月ぶりに、久々Androidビルドをしたらこんな下記エラーが。

```
Failed to update Android SDK package list. See the Console for details.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37406/2d909f2a-459d-5bf4-6813-1cc86fe6de5b.png)


## 試したこと

### UnityHubのAndroidモジュールが正しいかチェック

Android SDKが新しいかチェック。
UnityHubのモジュールを使っているので、下記をチェック。
問題なさそう、念の為Unity2019をつかっていたので最新版のUnity2019.4.30f1を入れ直し＋Androidのモジュールも

下記画像のようにした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37406/8cb28178-0946-0aab-bc81-4231af969110.png)

が、結局改善されず。

## Javaを入れ直す

Javaを入れ直すという方法がいくつか見つかりました。
新しめのUnityは無料で商用OKなOpenJDKを使っている認識だったので関係ないのでは、
と思って、試しに普通のJDKを入れなおしなど行いましたが改善せず。。



## 改善した方法

色々設定を触った結果、以下キャプチャの
Unity > Prerences のExternal Toolsの

* JDK
* Android SDK
* Android NDK 

のチェック外して、反映させてUnity閉じる。
次に、再度チェックをいれなおす事で改善しましたｗ
※Unity再起動や、NDKは関係ないかもですが、一応チェック入れおなしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37406/efd2946e-f1ba-9b23-d327-e76693e61ca0.png)


### 環境

* macOS BigSur 11.4
* Unity 2019.4.30f1 (UnityHub)
* AdmobSDK+FirebaseSDK投稿時点最新版

### 参考にさせて頂いたサイト様
https://qiita.com/tkyko13/items/e1509ed03a482e278d04
Pythonの仮想環境の構築についてやったのでメモ 

#仮想環境とは
仮想環境では、すべてのPythonのパッケージから切り離して、独自のパッケージをインストールできる仮想のファイルを作成してくれます。プロジェクトごとに必要なパッケージを用意できるので、モジュールの管理も簡単。

##仮想環境の作成手順

###01. 仮想環境を作成するファイルの階層にて、
```python
python -m venv ll_env
```
＊(ll_env)は仮想環境の名前なので、任意の名前

###02. 仮想環境を有効化
```
source ll_env/bin/activate
```
＊(ll_env)は仮想環境の名前なので、任意の名前

###03. 仮想環境の無効化
```
deactivate
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 124: invalid continuation byte が出たときのその場しのぎ対処

Python力が低いのでメモ。

https://github.com/deepmind/alphafold/blob/1d43aaff941c84dc56311076b58795797e49107b/alphafold/data/tools/jackhmmer.py#L131-L140

```python
      process = subprocess.Popen(
          cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      with utils.timing(
          f'Jackhmmer ({os.path.basename(database_path)}) query'):
        _, stderr = process.communicate()
        retcode = process.wait()

      if retcode:
        raise RuntimeError(
            'Jackhmmer failed\nstderr:\n%s\n' % stderr.decode('utf-8'))
```

のなかで、エラーが発生するのだが、

`UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 124: invalid continuation byte` 

となってしまい、エラー処理中にさらにエラーが発生して、肝心のエラーが見られないという状況になってしまった。Python力が低いのでぐぐってみたが、open時に適切なエンコーディングを指定する話が上位にヒットしてあまり役に立たなかったのでメモを残す。

公式リファレンスをみると、`decode` は第二引数を取って、失敗したときにどうするか決められる。ここで `ignore` を指定して

https://docs.python.org/ja/3/library/stdtypes.html#bytes.decode

```
decode('utf-8', errors='ignore')
```

などとすれば、とりあえず回避できる。ちなみにエラーの内容は

```
Error: Parse failed (sequence file /mnt/mgnify_database_path/mgy_clusters_2018_12.fa):
Line 29325242: non-ASCII character  in sequence
```

であった。mgnify database にどこかおかしいところがあるようだ。ダウンロードに失敗したのだろうか？

追記：メモリーのトラブルにより、ダウンロードしたファイルに損傷が生じていたようです。

この記事は以上です。
pythonで、CPPのヘッダ部分をかき集めてCSVに書く！

こんな感じでパス設定すればOK

```
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import glob
import csv

if __name__ == '__main__':


    filelist=[]
    filelist.extend(glob.glob('./src/**/*.cpp', recursive=True))
    filelist.extend(glob.glob('./src/**/*.c', recursive=True))
    filelist.extend(glob.glob('./inc/**/*.hpp', recursive=True))
    filelist.extend(glob.glob('./inc/**/*.h', recursive=True))

    header_list=[]
    header_list.append(["src","line","include"])

    for filepath in filelist:
        print(filepath)
        with open(filepath, encoding='utf-8') as f:
            for i, line in enumerate(f):
                if '#include' in line:
                    line = line.replace('\n','')
                    header_list.append([filepath,str(i),line])


    with open('./sample_writer.csv', 'w') as f:
        writer = csv.writer(f)
        writer.writerows(header_list)
```
3次元配列の各列をシャッフルする

feature importance用のコード
numpy配列のシャッフルが一番可用性が高そうなので作った

- numpyのシャッフルからのtensor変換
- イテレーションごとに配列の再定義
が必要
列ごとの要素をとってきてシャッフルして再代入

```


# 3次元のnumpyの列をシャッフル
# イテレーションごとに3次元配列を再定義しないとすべての列がシャッフルされてしまうので注意
def shuffletensorcolumns_loop(array,i: int) -> None:
    tmp = array[:,:,i]
    for j in range(array.shape[0]):
      np.random.shuffle(tmp[j]) # 破壊的処理なので代入不要
    array[:,:,i] = tmp


df = np.arange(1,201).reshape(5,4,10)
for i in range(df.shape[2]):
    df2 = df.copy()
    shuffletensorcolumns_loop(df2,i)
    print(df2)
```

追記
メモリチェック

```
df = np.arange(1,201).reshape(5,4,10)

for i in range(df.shape[2]):
    df2 = df.copy()
    print(id(df))
    shuffletensorcolumns_loop(df2,i)
    print(id(df2))
    print(np.may_share_memory(df,df2))

>>>
140643364911504
140643364910064
False
140643364911504
140643365525984
False
140643364911504
140643364911824
False
...
【Rails】便利な正規表現まとめ

オリジナルアプリ作成にあたり使用した正規表現を、備忘録としてアウトプットします。

#英数字混合
※大文字・小文字の区別なし

```
/\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i
```

#半角数字のみ

```
/\A[0-9]+\z/
```

# 全角（漢字・ひらがな・カタカナ）

```
/\A[ぁ-んァ-ヶ一-龥々ー]+\z/
```
・`ァ-ン`ではなく`ァ-ヶ`としているのは`ヴ、ヵ、ヶ`を含めるため。
・`一-龥`ではなく`一-龥々`としているのは`々`を含めるため。
・末尾に`ー`があるのは「ジュリー」「メアリー」などのハイフンを含めるため。

# 全角(カタカナのみ)

```
/\A[ァ-ヶー]+\z/
```

#電話番号10桁以上11桁以下(ハイフンなし)

```
/\A[0-9]{10,11}+\z/
```

#郵便番号(ハイフンあり)

```
/\A\d{3}[-]\d{4}\z/
```

#今回登場した正規表現のパターン表記一覧

`[a-z]`：	角括弧で囲まれた文字のいずれか 1個にマッチ
`\d`：数字にマッチ
`{n, m}`：	直前の文字が少なくともn回、多くてもm回出現するものにマッチ
`.`	：改行以外のどの1文字にもマッチ
`+`	：直前の文字の1回以上の繰り返しにマッチ
`\A`	：直後の文字が先頭にある文字列にマッチ
`\z`	：直前の文字が末尾にある文字列にマッチ
`[ぁ-んァ-ヶ一-龥々]`：	角括弧に囲まれたかな、カナ、漢字のいずれかにマッチ（ヴ、ヵ、ヶ、々を含む）
`?=`	：直後に設定した文字が続く文字列にマッチ
`*?`	：直前に設定した文字が0回以上続く文字列をチェックし、?の直後の文字が出た段階でその1文字を返す

<br>
ご指摘などあれば、ご教授いただけると幸いです。
jQueryリダイレクトが遅くて画面が表示する。

#ある条件の時リダイレクト、別の画面に移動してくれと依頼発生
リダイレクトってどうやるんだろう...から調べていきました。
.htaccessの設定を操作する、サーバーサイドで操作する等が出てきて、
どうしようかなと思っていたところ。
jQueryでリダイレクト設定できるというのを見つけたので実装しました。

####環境
MovableType 7
MtappjQuery 
jQuery 3.4.1


```ruby:jQuery　リダイレクト設定
window.location.href = "https://sample.com"
```

windowはいるのか要らないのかよくわかってないです...。
なくてもできると思います。

```ruby:jQuery　初期実装
$(document).ready(function(){
    if((mtappVars.me.name == "sample1" || mtappVars.me.name == "sample2") && mtappVars.scope_type == "user" && mtappVars.screen_id == "dashboard"){
        window.location.href = "https://sample.com"
    }
});
```

ただ単に入れるだけだと飛んでほしくないページが少しの時間表示され、
読み込みが完了後リダイレクトされるようになっていてカッコ悪い...。

.readyを入れて読み込むタイミングを変えても上手くいかなかったです。

##最終結果

```ruby:jQuery
if((mtappVars.me.name == "sample1" || mtappVars.me.name == "sample2") && mtappVars.scope_type == "user" && mtappVars.screen_id == "dashboard"){
    $('body').hide();//読み込み遅いためページ全てを非表示
    window.location.href = "https://sample.com"
}
```
読み込んでいる間[body]要素を非表示にして読み込んでるんだなと思わせることにしました。
これだと真っ白な画面が表示されます。

##まとめ
根本的な改善にはならなかったので、
もっと時間をもらったときよく調べたいなと思いました。

2021-10-08追記
いろいろ調べた結果bodyの一番下でjsファイルが読み込まれている為
動作が遅いことが判明しました。head内に移動させるとスムーズに移動できました。
小技シリーズ第２弾 リンクURLの有効活用

#小技2 リンクURLの有効活用

このシリーズでは、Yellowfinのレポートやダッシュボードをより魅力的なものに作成するための小技集を紹介したいと思います。第2回目はリンクURLの有効活用です。

YellowfinのデータをURLに受け渡して、外部サイトの関連情報を閲覧することが可能です。今回は、「都道府県コード」(JIS X 0401)を政府が運用するe-stat (https://www.e-stat.go.jp/) のURLの引数に受け渡して、関連情報を閲覧してみたいと思います。

以下の手順を自分でも試してみたい方は、[こちら](https://github.com/ChasingHH/ShareFiles/blob/Share/Pref_MST.csv)から都道府県マスタを入手してください。


####1. 新規レポートの作成
新規でレポートを作成し、ビューを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/065a9c4c-b016-bbaa-007b-40417b06941d.png)  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/2ddfc8d7-3975-c4af-aa8c-f37e57493504.png)

####2. テーブルの作成
「都道府県コード」と「都道府県」をカラム(列)に追加します。今回、都道府県コードをリンク先のURLの引数の一部として利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/a5ffdb9a-7605-fddc-543e-3bbed61e8178.png)

[カラムの書式] > [都道府県コード] > [書式] から 「URLリンク」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/c9127ee0-6a0c-7629-a301-4a55da7fd771.png)

URLに値を渡すためには```##```文字列を使用します。
https\://dashboard.e-stat.go.jp/radarChart?screenCode=00560&regionCode=```##```000
上記書式を「URL」欄に入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/98df4ad1-d211-7cd2-3a64-e3d51baed389.png)

####3. プレビュー
デザインステップに推移し、任意の都道府県コードを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/2d15384a-9061-da14-2f29-e81574515b9d.png)

選択した都道府県に関する「統計ダッシュボード 地域のレーダーチャート・ランキング」が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/355bdbd8-bf7e-4fd5-b2e3-8d1e3d69f987.png)

とても簡単な仕組みで、動きのある画面を作成できました。
是非参考にしてみてください。
Cheers!
Postmanではform-dataのリクエストが通るのにaxiosで失敗する場合

# はじめに
Postmanだとリクエスト通るのに、axiosだとうまくいかなかった（404が返ってくる）ので調べました。

# 結論
[ここ](https://github.com/axios/axios/issues/789#issuecomment-508114703)に書いてあるとおりですが、headerを下記のようにするとうまく通りました。

```
const formData = new FormData();
const headers = {
    ...formData.getHeaders(),
    "Content-Length": formData.getLengthSync()
};
```
getHeadersだけではContent-Lengthが入ってないようですね。
なくても良いような気がするんですが、送信先で必須とかになってるのかもしれません。
scipyでサンプル画像を読み込むワンライナー

テスト用画像が欲しいときに使ってます。

```py
from scipy import misc
img=misc.ascent()
```

```py
import matplotlib.pyplot as plt
plt.imshow(img, cmap='gray')
```
512x512のグレー画像が得られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997363/b1f70222-7687-e14f-758f-74f709adcd09.png)

または、

```py
img=misc.face()
plt.imshow(img)
```
768x1024x3のカラー画像が得られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997363/a261517a-b71c-c5aa-a1de-c71ded392f52.png)
いつの間にか(scipy 0.17~)misc.lenaは無くなっていました。
標準画面をcssの上書きでハックする

Salesforceの標準のCSSと同じ名前のスタイルシートをつくれば、以前なら親のコンポーネントのCSSを上書きできたのですが、現状では.THISの指定がちゃんと効いて（当たり前か）、上書きされません。自分のコンポーネントの中だけに限定されます。

悩んだけどあったねぇ。上書きできる方法。

CSSを静的リソースに書いて、呼び出せば.THISを書かなくて済む（コンポーネントのスタイルシートでは.THISがないと保存できない）。


質問者さんは、このタブの幅を広くしたいらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2655bfdd-94a8-285e-be82-b2be6c393377.png)


結果は、広くできた。分かりやすいように背景色をつけています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b85ecdc6-60f0-3d96-35d9-b923b65abd06.png)


静的リソースに保存したCSSを以下のようにして呼び出します。

```
<aura:component implements="flexipage:availableForAllPageTypes" access="global">
	<ltng:require styles="{!$Resource.oneActioncss}"/>    
</aura:component>
```

本当は、この中の１つでいいはず。

```
.oneActionsComposer.SMALL li.uiTabItem {
    width:150px !IMPORTANT;    
}

.oneActionsComposer.SMALL li.uiTabItem>a {
    background-color: #99cc00 !IMPORTANT;   
    width:150px !IMPORTANT; 
}        

.tabHeader{
    background-color: #99cc00 !important;   
    width:150px !IMPORTANT; 
}
```

これを静的リソースに保存して呼び出せばハック完了です。一晩悩んだなぁ、朝起きたら思いついた。

[How do I make the Lightning Mobile Action tab wider?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000CiPkFSAV)


# コミュニティーの場合はもっと簡単みたい

[How to hide the Title and URL Name fields from Article detail component on community](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A7syrSAB)
FlutterにてAppIcon, SplashScreenを作成

# image file
AppName > images > icon.png(1024 * 1024)
AppName > images > splash.png(1500 * 1500)

imagesディレクトリを作成し、その中に今回適応するimagefileを配置

# SplashScreen

```yaml:pubspec.yaml
flutter_native_splash:
  color: "#262626"
  image: "images/splash.png"
  color_dark: "#262626"
  image_dark: "images/splash.png"
  #ios_content_mode: center
  #android_gravity: center

dependencies:
  flutter_native_splash: ^1.2.1
```

```undefined
$ flutter pub run flutter_native_splash:create
```

## 一言
### iOS
コメントにしてあるios_content_modeは以下で指定可能
便利です。
> scaleToFill, scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight, bottomLeft, or bottomRight.

### Android
コメントにしてあるandroid_gravityは以下で指定可能
しかしこれでは対応できない場合もありました
> bottom, center, center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal, fill_vertical, left, right, start, or top.


AppName > android　をAndroidStudioで開くとわかりますが
res > drawable にforeground, background等のxmlが追加されている。
`launch_backgroud.xml`を見るとitemタグのbitmapで生成されているので
例えば横or縦を画面いっぱいに広げてaspect比は固定のまま縦を。。　とiOSでいうところの`scaleAspectFit`したい場合に困る。
苦し紛れにitemタグにwidth, heightを適応するという方法があるが、これを利用するためにはAPI24以上にする必要がある。
そのため少し大きめの画像を用意する必要がある。

海外の方は3000 * 3000で実装している人もいました。

## 公式
https://pub.dev/packages/flutter_native_splash

# AppIcon

```yaml:pubspec.yaml
flutter_icons:
  android: true //利用するか
  ios: true　//利用するか
  remove_alpha_ios: true
  image_path: "images/icon.png"
  #image_path_android:
  #image_path_ios:
  adaptive_icon_background: "#262626"
  adaptive_icon_foreground: "images/icon.png"

dependencies:
  flutter_launcher_icons: ^0.9.2
```

```
$ flutter pub run flutter_launcher_icons:main
```

## 一言
iOSとAndroidでimageを分けることができるので助かります

### iOS
xcodeから`Assets.xcassets`をみるとリサイズしてくれて全て埋まっている。
便利です。

### Android
いつも問題児なイメージ。。。笑

paddingの影響を受け、画像が思ったように表示されないケースが多々あるようです。
この場合AndroidStudioを用いて縮小する、もしくはpaddingを考慮した画像を用意する必要があります。

縮小のやり方を記載しておきます。

- androidディレクトリをAndroidStudioで開く
- File > New > image Asset 
- Foreground Resizeを60〜70％に変更
- Background Layerに色を設定
- resoure/values/ic_launcher_backgroud.xmlが作成される。同階層のcolor.xmlに同名のcolor nameがすでに作成されているためビルドエラーが発生する。そのためcolor.xmlファイルのcolorタグをコメントにする

> 2021/9/28日現在未修正
>
> https://github.com/fluttercommunity/flutter_launcher_icons/issues/96

## 参考
https://pub.dev/packages/flutter_launcher_icons
centos ログイン時にメッセージを出す

`vim /etc/motd`

で、表示したい内容を記載

```

表示されるかな
お疲れ様です。
vim /etc/motd の内容が表示されています。

```

これでログインしたときにメッセージが表示される。
サーバー構築時のメモなどを入力しておくと良い。