OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails]my sqlのテーブルとmigrationファイルを削除した際に生じた不具合の解決手順

【前提】
Rails 6.0.3.1
ruby 2.6.3

現在、オリジナルアプリの製作中。
その際に誤って作ってしまった。users_artistsというテーブルとマイグレーションファイルを削除しようとした際に生じたエラー内容についてまとめてみた。

```ターミナル.
％ rails db:rollback STEP=5
```
・migrationファイルを削除する為にターミナルにてrollbackを実行。

```ターミナル.
％ rails db:migrate:status
```
・確認の為、statusを上記コマンドにて確認したところ、一箇所だけ不具合を発見

```ターミナル.
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     000             ********** NO FILE **********
  down    20201014111144  Devise create users
  down    20201014111251  Devise create artists
  down    20201014121517  Create events
  down    20201020102544  Create bookmarks
```
↑一箇所だけstatusがupとなっており、ファイル名もなぜかNO FILEとして残ってしまった
[![Image from Gyazo](https://i.gyazo.com/baaaf9b3f5257e33a4929eeb03d2f62f.png)](https://gyazo.com/baaaf9b3f5257e33a4929eeb03d2f62f)
↑上記はその際に残ってしまったschemaファイルの内容
・versionの表示が消えた状態でdownにならず残ってしまっていた
本来、このファイル名にはMigrationIDがあるはず
がここでは”000”となってしまっている

【エラーの解決手順】
①statusをdownにする為にdb/migrate配下に新しく名前を”000_create_users_artists.rb”としてmigrationファイルを作成。
:point_right: 他のmigrationファイルの名前と同様とするために**create**を名前の先頭に付与して以下のように記述しました。

```000_create_users_artists.rb
class CreateUsersArtists < ActiveRecord::Migration[6.0]
  def change
    create_table :users_artists do |t|
      t.integer :user_id
      t.integer :artist_id

      t.timestamps
    end
  end
end
```
②もう一度、```rails db:migrate:status```を実行。下記のようにターミナル上にてup部分のMigrationNameが```Create users artists```に変わっている事が確認出来ました。

```ターミナル.
Status   Migration ID    Migration Name
--------------------------------------------------
   up     000             Create users artists
  down    20201014111144  Devise create users
  down    20201014111251  Devise create artists
  down    20201014121517  Create events
  down    20201020102544  Create bookmarks
```
③再度、statusをdownにするために下記のコマンドにてファイル名を指定して実行。

```ターミナル.
% rails db:migrate:down VERSION=000_create_users_artists.rb
```
④再度、指定したファイルのstatusがdownになっているか確認をして不要である```000_create_users_artists.rb```のファイルを削除すればOK！！

```ターミナル.
 Status   Migration ID    Migration Name
--------------------------------------------------
  down    000             Create users artists
  down    20201014111144  Devise create users
  down    20201014111251  Devise create artists
  down    20201014121517  Create events
  down    20201020102544  Create bookmarks
```
⑤最後に```rails db:migrate```を実行してテーブルを再度、作成し直して終了。

※まとめ※
schemaファイルに誤って残った記述内容と削除する為に作成したファイル名やカラム名の記述内容を同じにしないとうまくデータが消せなかったのでかなり苦戦しました:joy:苦戦した事でかなり勉強になり、自身の強みにもなったので内容をまとめて投稿してみました。誰かの参考になれば幸いです！！
MacでCPU温度を監視する

最近MBPが熱くなりがちなので(この季節にはありがたいカイロと化しつつある)、MacのCPUを監視したいなと思って方法を調べた。

## 方法
温度を確認するにあたり必要なパッケージは以下で入る。

```
$ sudo gem install iStats
$ brew install watch
```

例えば
`watch -n 0.5 'istats cpu'`
と実行すると0.5秒おきにCPU温度をセルシウス度で表示してくれる。

Linuxだとデフォルトで便利な`watch`コマンドがあるのだけど
Macは無いっぽく、brewで同等に機能するパッケージが入る。
(一昔前はbrewで入れられるような感じでも無かったようで、シェルで組んで頑張ってたエントリがいくつも見つかる)
【AWS Glue】ジョブパラメータを利用する

## ジョブパラメータ
AWS Glueではジョブ実行時にジョブパラメータを設定可能です。環境変数のようなもので、スクリプトの中でその変数を受け取ることが可能です。
同じスクリプトでも変数を変えることで挙動を変えることが可能となります。

## ジョブパラメータの取得方法

```py
import sys
from awsglue.utils import getResolvedOptions
args = getResolvedOptions(sys.argv, ['hoge_string', 'hoge_int'])
step_count = args['hoge_string']
store_name = args['hoge_int']
```
`getResolvedOptions(sys.argv, ['arg_name_1', 'arg_name_2',...])` のように引数に受け取るパラメータ名を並べていくとジョブパラメータの連想配列が取得できます。あとはその配列のkeyに取得したいkeyを指定するだけでOKです。
またパラメータはすべてstring型なので数値として扱いたい場合はキャストしましょう。


## 設定方法（AWSコンソール）
![スクリーンショット 2020-11-09 17.13.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290902/d3bc52e3-5570-6dba-39ad-2cfe468c0ec7.png)

AWSコンソールからは上記画像のようにパラメータを設定することが可能です。
ここでひとクセあるのが戦闘に`--`を付ける必要があるという点です。`--`をつけないとジョブパラメータとして認識してくれないので注意が必要です（どうして省略可能でないのでしょうか…）


## 設定方法（AWS CLI）
実行例

```sh
aws glue start-job-run --job-name "ジョブ名称" --arguments='--hoge_string="aiu", --hoge_int="123"'
```

[ドキュメント](https://docs.aws.amazon.com/cli/latest/reference/glue/start-job-run.html)
aws cliでは上記のように設定します。`--arguments`というoptionで設定するのですがその際もかならず`--`というものが必要となります。
その他にもワーカーの数やワーカーのタイプなどが指定可能です。
Gameobjectを取得する方法　一覧


このキータは、スタジオしまづ様の動画をもとに自分の勉強用にまとめた内容になっています。
もっと詳しく知りたい方は下記の動画を見ていただければよりわかるかと思います
https://www.youtube.com/watch?v=uyi2fRsO6EY
(※不適切な際は指摘いただければと存じます)

Gameobjectを取得する方法
+ GameObject.Find
+ GameObject.FindWidthTag
+ public ＋ エディタを使用
+ staticにする

＝Find＝


//GameManagerAという名前になっているオブジェクトを検索(Findメソッド)してゲームオブジェクト型の変数に格納して取得
//GameManagerA ： unity上でsceneに配置したオブジェクトの名前
GameObject gameManagerObj = GameObject.Find("GameManagerA");

//ゲームマネージャー自体に付属しているコンポーネントを取得して変数に格納し、そこからさらになんのオブジェクトなのかを指定する
//.GetComponent<>をすることでそのオブジェクトにくっついているコンポーネントを取得できる
GameManager gameManager = gameManagerObj.GetComponent<GameManagerA>();

//ゲームオブジェクト型の変数にそのクラス内のメソッドを続けて書くことで、実行しているスクリプト以外のメソッドを実行できる
gameManager.SampleMethod();




＝FindWithTag＝
ほぼFindの時と同じ

//GameManagerAという名前になっているオブジェクトを検索(Findメソッド)してゲームオブジェクト型の変数に格納して取得
//GameManagerA ： unity上でsceneに配置したオブジェクトのタグの名前を取得
GameObject gameManagerObj = GameObject.FindWithTag("GameManager");

//ゲームマネージャー自体に付属しているコンポーネントを取得して変数に格納し、そこからさらになんのオブジェクトなのかを指定する
//.GetComponent<>をすることでそのオブジェクトにくっついているコンポーネントを取得できる
GameManager gameManager = gameManagerObj.GetComponent<GameManagerA>();

//ゲームオブジェクト型の変数にそのクラス内のメソッドを続けて書くことで、実行しているスクリプト以外のメソッドを実行できる
gameManager.SampleMethod();

※tagから検索する方をUnityとしては推奨をしている



＝Public + エディタ＝

//まずクラス内でゲームマネージャー型の変数を宣言(メソッドの中に入れないように)
public GameManager gameManager;

//インスペクターにオブジェクトを指定できるようにインプット欄ができるので、そこに指定し、メソッドを実行する
gameManager.SampleMethod();

メリット・デメリット
メリット：何がアタッチされてるかわかりやすい
デメリット：変数名を変更するとその都度設定しなおさないといけない数が多いと面倒



＝static化＝  static:静的

//static化することでどこからでも取得できる
//まずクラス内でpublic staticを追記してゲームマネージャー型の変数を宣言(メソッドの中に入れないように)

public static GameManager instance;  //instance:どこからでも参照できる変数

private void Awake()
{
  instance = this;  //instanceに自分自身を設定する
}
//上記のコードをGameManager.cs内のクラスで書くことでどこからでもこのcsのメソッドにアクセスできるようになる

//PlayerManager側で下記のコードを実行するとGameManager.csのメソッドを実行できる
GameManager.instance.SampleMethod();

デメリット：１つしかないものでしか実行できない (ex.UI, プレイヤーのデータ etc..)
Laravel8のルーティング

### はじめに
laravelの8でこれまでのバージョンとルーティングの書き方が変わったようなので、変更点を記載する。

### 前提
PostControllerのindexアクションを呼びたい時

```PostController.php
<?php

namespace App\Http\Controllers;

use App\Models\Post;

/**
 * Class PostController
 * @package App\Http\Controllers
 */
class PostController extends Controller
{
    /**
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index()
    {
        $posts = Post::all();
        return view('post.index', ['posts' => $posts]);
    }

}
```

### laravel8より前

```web.php
<?php
use Illuminate\Support\Facades\Route;

Route::get('/posts', 'PostController@index');

```

### laravel8

```web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index']);

```

### まとめ
laravel8からはコントローラーをweb.phpでuseしてあげないといけなくなったみたいですね。
明示的にどのコントローラーが使われているのかが分かるけど、記述量が増えちゃいますね。
これは賛否両論ありそう。

### 参考
[laravelドキュメント](https://readouble.com/laravel/8.x/ja/routing.html)
LINEBOTで湯婆婆を実装してみる

# はじめに
**原作者(元ネタ)様の記事：**[Javaで湯婆婆を実装してみる - Qiita](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

何番煎じか分かりませんが、
執筆時点(2020/11/09)で**LINEBOT**で実装して記事にされている方がいなかったので、実装してみました。

# コード
**PHP7**で実装しました。
**(コピペして試される方はアクセストークンが記述されたtoken.txtファイルを読み込んでいる点にご注意ください。)

```php5
<?php

// 湯婆婆関数
function yubaba($name, $token_reply) {

  // 贅沢なリプライメッセージ
  $hun = [
    'type' => 'text',
    'text' => "フン。".$name."というのかい。\n贅沢な名だねぇ。"
  ];

  // 湯婆婆が名前を1文字ずつ認識できる様にする
  $name_arr = preg_split("/\B/u", $name);
  // 抜き出す1文字の位置を求める
  $num = mt_rand(0,count($name_arr));
  // 新しい名
  $na = $name_arr[$num];
  
  // 君の名は。
  $kiminonaha = [
    'type' => 'text',
    'text' => "今からお前の名前は".$na."だ。\nいいかい、".$na."だよ。\n分かったら返事をするんだ、".$na."!!"
  ];

  $content = [
    'replyToken' => $token_reply,
    'messages' => [$hun,$kiminonaha]
  ];

  return $content;
}

function follow_reply($token_reply) {
  $keiyaku = [
    'type' => 'text',
    'text' => "契約書だよ。\nそこに名前を書きな。"
  ];

  $content = [
    'replyToken' => $token_reply,
    'messages' => [$keiyaku]
  ];

  return $content;
}

// リプライメッセージ送信関数
function send($content,$token) {
  $ch = curl_init('https://api.line.me/v2/bot/message/reply');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($content));
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Content-Type: application/json; charser=UTF-8',
      'Authorization: Bearer ' . $token
  ));
  $result = curl_exec($ch);
  curl_close($ch);
}

// メイン関数
function main() {
  // アクセストークン
  $token_access = file_get_contents('token.txt');

  // リクエストjsonデータの処理
  $json_req = file_get_contents('php://input');
  $obj_req = json_decode($json_req);

  $event_type = $obj_req->{"events"}[0]->{"type"};
  if ($event_type === "message") { // メッセージの場合
    // メッセージデータ
    $msg = $obj_req->{"events"}[0]->{"message"}->{"text"};
    // 先頭及び末尾の空白などの余分な要素を削除
    $msg = trim($msg);
    // リプライトークン
    $token_reply = $obj_req->{"events"}[0]->{"replyToken"};
    // 湯婆婆
    $content_reply = yubaba($msg, $token_reply);
  } elseif ($event_type === "follow") { // 友達追加の場合
    // リプライトークン
    $token_reply = $obj_req->{"events"}[0]->{"replyToken"};
    // 友達追加メッセージ
    $content_reply = follow_reply($token_reply);
  } else {
    exit(0);
  }

  // 送信
  send($content_reply,$token_access);
}

main();
```

# 実行例
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266027/4c60b20d-e6a2-3aba-e0d1-372ac338654f.png" width="75%" alt="湯婆婆_実行例.PNG">
> 湯婆婆の画像は、[スタジオジブリ公式フリー素材ページ](http://www.ghibli.jp/info/013344/)から使用しています。

# 最後に
**湯婆婆の実装意外とおもしろい。**

LINEBOTの良い点はこの記事を読んだ人が**すぐに試せる点**ですね！
次の**友だち追加ボタン**もしくは**QRコード**から友達登録して使ってみてください！
<a href="https://lin.ee/vPYseOa"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0"></a>
![M.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266027/baa69003-8925-1719-14da-67bd9224be41.png)
副業に向けてのポートフォリオを作り直した話

# はじめに
最近、本業も安定してきたし、スキルアップを図るうえで副業に手を出してみようかなと思い、
色々とクラウドソーシングに登録してみました。

どんな人たちがいるのか、情報収集してみたところ、
副業でやっている方・フリーランスで本腰を入れてやっている方等、様々いらっしゃる様子。

特にフリーランスの方はかなり力が入っており、自己PRとして過去の制作物やポートフォリオを載せていました。

そういえば自分も昔、ポートフォリオ作ったなーとか思って見てみると、
副業する際の自己PRとしてはちょっと物足りない感じの内容だったので、
ガチで受注取るために、本腰入れて作り直しました。

**「自分のスキルをポートフォリオに実際に組み込んで公開することこそが最も信頼足りえる自己PRである」**
こんな言葉を心に思い、副業に向けてポートフォリオ作り直したよって話。


# できたもの
現在は都合上閉鎖しています

ログイン認証機能を持ったシステムが作れることをPRしたかったので、ログイン認証サイトとしています。
下記のID・パスワードでログインできます。

```
システムにあまり詳しくないユーザ向けに公開しているIDです。
自分のスキルや今まで参画した案件などを、公開しています

ID：user
PW：user
```


```
システムがわかる方向けに公開しているID
上記の内容に加え、マスタ情報も閲覧できるようにしています。
※ マスタ情報は閲覧だけ可能で、サーバサイドで登録・更新・削除を制限しています

ID：master
PW：master
```

## 自己PRしたい機能
#### フロントエンド
- SPA (Single Page Application)
- レスポンシブデザイン

#### バックエンド
- ログイン認証機能
- 実行できるAPI・表示メニューをユーザ権限によって制御
- RESTful API
- RDB使ってる

#### インフラ関連
- https化 (SSL対応)
- Docker利用
- GCPでのリリース

# 作ってみての所感
システムに詳しくない人が見たら、「自分のスキルを公開しているよくあるポートフォリオだよね」ってなりそう。
デザインとしてはグラフが少し見栄えがいいくらいで、他はすごく並みだな～・・・

自分としては、
**中規模システムでも十分対応できるアーキテクチャ！**
**クラウドでのリリース！**
**ログイン認証機能ちゃんとしてるよ！**
**レスポンス早いよ！**

って感じで、同一品質のお客様特化したシステムなら割と早く作れるよ！ってことを一番アピールしたいんですけど、
ポートフォリオでそこまでアピールする術をまだ持っていなくて、口頭でのアピールになりそうです。
あとは、実際にお客様に納品したシステムのリリース環境もポートフォリオで再現しているため、
GCP利用料が毎月数千円くらいかかるのがちょっとネック。

副業に向けて、ガチで作ったポートフォリオですが、どの程度の効果を発揮してくれるか、今後期待です。

色々とコメントお待ちしてまーす。
teraterm でファイルを転送する [備忘録]

###こんにちわ [@darry6335](https://twitter.com/darry6335)です。
teratermでファイルを簡単に転送する方法を調べましたのでここに記録します。

下記の記事を参考にさせて頂きました。
[@go-toさん](https://qiita.com/go-to/items/409e32116213bdf4b1ce)

####1.サーバからクライアントに転送
1.1 転送したいファイルのディレクトリに移動
1.2 メニュバーのファイル -> SSH SCP をclick
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866385/19a6db93-d93c-7838-95dd-ede49ff2123d.png)

1.3 Fromに転送したいファイルパスを入力　...1
1.4 Toに保存したい場所のパスを入力 ...2

![1キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866385/06b24622-8b2d-0dd9-eb5c-f4bd9764459e.png)

####2.クライアントからサーバーに転送
2.1 転送したいファイルをteratermターミナルにドラック＆ドロップする
2.2 転送元のファイルパスが表示されます ...1
2.3 SCPの送信先に保存先のパスを入力します ...2
2.4 OKをclickする
2.5 転送されているか確認
![2キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866385/2d7f1fa8-3405-6d8f-9b25-bf4d8a8b84eb.png)
MySQL8.0でcsvファイルをインポートする

## 環境
MySQL 8.0.21

## インポート失敗
MySQL8.0にcsvファイルをインポートしようとすると失敗する。

```
mysql> load data local infile "[ファイル名]" into table [テーブル名] fields terminated by ',';
ERROR 3948 (42000): Loading local data is disabled; this must be enabled on both the client and server sides
```

理由は、
1. セキュリティ強化のため、8.0から `LOAD DATA INFILE LOCAL` はデフォルトで無効にされた。
2. MySQL 8.0 で `LOAD DATA INFILE LOCAL` を利用するには、サーバとクライアント両方で `local-infile` パラメータを ON にする必要がある。

## インポートする

まず、サーバー側の`local-infile`をONにする。

```
mysql> select @@local_infile; // 設定を確認する
+----------------+
| @@local_infile |
+----------------+
|              0 |
+----------------+
1 row in set (0.01 sec)

mysql> set global local_infile=on; // パラメータを ON にする
Query OK, 0 rows affected (0.01 sec)

mysql> select @@local_infile; // 変更されたことを確認する
+----------------+
| @@local_infile |
+----------------+
|              1 |
+----------------+
1 row in set (0.00 sec)
```

次は、クライアント側の`local-infile`をONにする。

```
# mysql -h [ホスト名] --local-infile=1 -p
```
これらの設定をし、`LOAD DATA INFILE LOCAL`で無事にcsvをインポートできました。

※接続先のホスト名は以下のコマンドで確認できます。

```
mysql> show variables like 'hostname';
+---------------+--------------+
| Variable_name | Value        |
+---------------+--------------+
| hostname      | [ホスト名]     |
+---------------+--------------+
1 row in set (0.02 sec)
```


## 参考
https://mita2db.hateblo.jp/entry/2020/01/13/163218
https://qiita.com/nii_yan/items/0265f69370bbdb883655
Mendix アプリの日本語化

# はじめに

Mendixはローカライゼーションの仕組みがあるので、アプリを比較的簡単に多言語化することができます。

# 日本語化の流れ

アプリを作成した後で、Settingで言語に日本語を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751319/ea6c4681-9fbd-1609-185a-a360629413ac.png)

Language -> Batch translateを使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751319/b8fa6f62-f753-3a9b-2088-f0b6cdb0efee.png)

リソースの一覧が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751319/497fb7d3-f87c-79de-3d7d-c401bb3e5fcc.png)

Import from excelをクリックしてEnglishからJapaneseに翻訳します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751319/56647e1f-3b18-7a77-1ed8-7ae365086c80.png)

Excelファイルを指定してリソースを読み込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751319/174608a5-3f44-6473-8805-a9e24593df50.png)

Translateボタンを押すととで翻訳が実行されます。最後にCloseを押して閉じます。

# リソースファイル

独自に実装した部分は仕方がないにしても、標準で提供されている部分を毎回翻訳するのは効率が悪いです。最低限共通の部分はこちらを参照してください。

[日本語リソース](https://github.com/naofum/mendix-translation/blob/main/resources/mendix_translate.xlsx?raw=true)
【MotionBoard】他GEOアイテム統合すると下層GEO上のピンを選択できないんだけど？

#ツール（環境）
オンプレのMotionBoard6.0を使用してますが、クラウドでも同様だと思います。

#困りごと
複数のGEO（地図）を重ねることで属性の違うデータの分布を見ることができるが、重ねた結果、
下層になったGEOは背景扱いとなり、そこにあるデータ（ピン）はクリックすることが出来なくなる。

でも、他GEOアイテム統合で重ねたときって、分布をみて「このへんのピンってどんなデータかな？」ってクリックしたくなるんですよね。

絵で描くと、こうです。この絵、サポートに送りました。文字で説明するのが難しくて･･･
![IMG_6996.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/f3cbe746-980e-f5ce-df06-f0b8217ecbbd.jpeg)

#どう解決したか

重ねるのがダメなら、一枚のGEO上で、属性の違いを色でわかるようにするしかない。
デフォルト設定だと色は固定かグラデーション。さてどうするか。

##構想
カスタム項目で新規項目を作成、そこに属性を区別できるよう値をセットする。
その値によってピンの色を分ける。

##手順
###そのデータの属性を区別する項目を見極める
（例）ふたつの区分（区分A、区分B）の中身によって属性を区別。
　　　区分Aが'購入済'のとき→属性1(1)
　　　区分Aが'未購入'のとき→属性2(2)
　　　区分Bが'未調査'のとき→属性3(3)
　　　上記以外→NULL
　　

###カスタム項目 新規作成
カスタム項目「判定」を新規作成し、それぞれの属性に応じて 1,2,3,NULL を設定していく。

データソース編集→追加項目作成→カスタム項目　と遷移、
下画像の黄色の部分に、以下のように設定する

**DECODE(区分A,'購入済', '1', 区分A, '未購入', '2', 区分B, '購入済', '3',NULL)**

この書き方で、以下↓の仕様を示します。
（注）私はDBはDr.Sumを使っています。クラウドならばデータストレージでDECODE文が使えます。

* * *
区分Aが'購入済'のとき→属性1(1)
区分Aが'未購入'のとき→属性2(2)
区分Bが'未調査'のとき→属性3(3)
上記以外→NULL
* * *
![スクリーンショット 2020-11-09 184125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/e8da0ef9-dfcc-01b2-cb32-b4932c05d8e7.png)


###アイテムプロパティ GEOタブ 

GEOをクリック、プロパティを選択
GEOタブをクリック
項目設定で「判定」を探す
判定の種類に「値」を設定
![F43E280D-32B5-4136-B639-0FFE11A692D3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/5032d475-079f-e711-7adf-cbe4dd80e811.jpeg)

###アイテムプロパティ ポイント設定タブ 
「ピン」タブをクリック
（１）値項目のメイン：で「判定」を選択
※「判定」が出ない→ひとつ前の設定（GEOタブで「値」を設定する」が出来ていない可能性あり

（２）色の最小・最大
「グラデーションで補完」を選択し、最小→1、最大→3 と数字を入れる
「判定」に値は3種類（1,2,3）しかないため、最小が1, 真ん中が2、最大が3となり
それぞれのピンが緑、赤、黄で表示されるようになる。
![F8BC0A6E-B7DD-437E-A33D-A2D77D29536C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/34557a3d-106b-3316-a0d6-6bd328d949b2.jpeg)

###GEOはこんな感じ 
![EB60CC00-3FBE-4AA9-970C-1596417F2C46.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/0dd21016-7f77-65c5-2ee3-f71cbf652286.jpeg)


#ウイングアークのユーザコミュニティ「nest」
私も参加しています。多くの有益な情報があり、交流があります。
世の中が変わり、社外活動の重要性がより増していると考えております。
社外で自分の価値を計れるものさしを持とう。

https://www.wingarc.com/wug-nest/

以上
「誤差」②　情報落ち・打ち切り誤差・桁落ち・丸め誤差

##「情報落ち」とは

絶対値の大きな値と小さな値の加減算（足し算と引き算）を行った際に、**絶対値の小さな値が結果に反映されない**ことによって生じる誤差のことです。

「情報落ち」を理解するため、絶対値の大きな値と小さな値を用意したいと思います。
また、この2つの数を加算した数を、4ビットの仮数部がある浮動小数点数で表現するとします。

まず、絶対値の小さな値「$0.00001101$」を用意して、指数表現にします。
この数を仮数が「$0.M$（$M$は小数点以下の有効な桁）」という形の指数表現にすると、
「$0.1101\times2^{-4}$」になります。

次に、絶対値の大きな値「$1101$」を用意して、指数表現にします。
この数を仮数が「$0.M$（$M$は小数点以下の有効な桁）」という形の指数表現にすると、
「$0.1101\times2^4$」になります。

この2つの数を指数を$2^4$に調整して加算すると、次のようになります。

![スクリーンショット 2020-11-09 15.25.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657974/691f0c45-a8af-deb3-3d66-e13dba07c0e1.png)

加算した結果、「$0.110100001101\times2^4$」という数になります。

そして、この数を仮数部が4ビットの形式の浮動小数点数にします。
この形式に合わせて「$0.110100001101\times2^4$」を正規化すると、小数点以下の4桁を仮数部に格納するので「$0.1101\times2^4$」になります。
この数は絶対値の大きな数と小さな数を足した数ですが、**正規化によって有効な桁が含まれず、実質的に加算されなかったことにされてしまいました**。
そのため、加算したはずなのに数が反映されていないという問題が発生します。

##打ち切り誤差
計算処理を**完了まで待たずに途中で打ち切る**ことによって生じる誤差のことです。
あらかじめ計算に条件を設けておき、条件を満たしたら途中で打ち切ることになります。
その結果、完全な結果を得ることが出来ずに誤差が生じます。

たとえば、「小数点以下20桁まで値を求めたらその時点で計算を打ち切る」という条件を設定しておくとします。
この条件のもと、円周率を求めると、次のようになります。

```math
\pi=3.14159 26535 89793 23846
```
コンピュータが円周率の小数点以下20桁目の「$6$」を求めた時点で計算が打ち切られます。
円周率は延々と続く数ですが、そのうちの一部を切り取った結果になるわけです。

##桁落ち
絶対値がほぼ等しい数値同士の差を求めた時に、有効な桁が大きく減ってしまうことによって生じる誤差のことです。

「桁落ち」を理解するため、絶対値の大きな値「$1.1111$」と小さな値「$1.1110$」を用意したいと思います。また、この2つの数を減算した数を、4ビットの仮数部がある浮動小数点数で表現するとします。

絶対値の大きな値「$1.1111$」から小さな値「$1.1110$」を減算すると、「$0.0001$」という数になります。
大きな値と小さな値はともに有効な桁を5桁持っていたわけですが、**減算によって「$0.0001$」の有効な桁は最後の1桁の「$1$」のみになってしまいました**。

ここから「$0.0001$」を4ビットの仮数部がある浮動小数点数で表現するため、「$0.M$（$M$は小数点以下の有効な桁）」という形で正規化します。すると「$0.1000\times2^{-3}$」という表現になります。

ここで、減算直後の数「$0.0001$」と正規化された「$0.1000\times2^{-3}$」を比較してみます。
減算直後の数は最後の1桁の「$1$」のみが有効な数でしたが、正規化によってその後に「$0$」が3つ加えられた仮数「$0.1000$」になっています。この3つの「$0$」は**正規化という都合によって加えられた数であり、数学的に正しい数であるという保証がありません**。
したがって、この数を用いて計算を行うと誤差が生じてしまい、期待していた結果にならない場合があります。

##丸め誤差
表現できる桁数を超えてしまったことにより、最小桁よりも小さい部分を四捨五入したり、切り捨てたりして生じた誤差のことです。

たとえば、円周率を小数点以下20桁で求める際に、21桁目を四捨五入して表現するとします。
円周率を21桁目まで表示すると次のようになります。

```math
\pi=3.14159 26535 89793 23846 2
```
ここで、21桁目の数は「$2$」なので四捨五入すると20桁目の「$6$」で終わります。
円周率は延々と続く数ですが、四捨五入されたことでそれ以降の桁の分誤差が生じることになります。

##参考にさせて頂いた書籍
きたみりゅうじ 『キタミ式イラストIT塾 基本情報技術者平成31/01年』 技術評論社 2019年

##学習してみて
今回で「誤差」についての学習が終わりました。
コンピュータの計算の精度を確保するには今回学んだような誤差への対策が欠かせないわけですが、浮動小数点数のように形式化すればするほどそこから零れ落ちる例外が生まれやすくなるということもあると思います。
おそらく今後自分もこういった誤差に悩まされるような日が来るのかもしれません。
他人事とは言ってられませんね…
UIElements を使った画面に線を引く

# UIElements を使った画面に線を引く(Unity)

Unity のバージョンは 2020.1.10f1 を使用しています。

UIElement で直線を Handles.color で引いた時、線を引いた処理の VisualElement に背景色を使うと、背景色で線を塗り潰してしまいます。

その時は、 [ImmediateModeElement]クラスを継承して、次のコードを書けば、直線を引くことが出来ます。

```C#:ConnectionElement.cs
public class ConnectionElement : ImmediateModeElement
{
    Vector2 _positionA;
    Vector2 _positionB;


    static Material _lineMaterial;

    public Vector2 positionA
    {
        get { return _positionA; }
        set
        {
            _positionA = value;
            UpdateBounds();
        }
    }

    public Vector2 positionB
    {
        get { return _positionB; }
        set
        {
            _positionB = value;
            UpdateBounds();
        }
    }


    void UpdateBounds()  // ...1
    {
        Vector2 min = Vector2.Min(_positionA, _positionB);
        Vector2 max = Vector2.Max(_positionA, _positionB);

        style.left = min.x;
        style.top = min.y;
        style.width = max.x - min.x;
        style.height = max.y - min.y;
        MarkDirtyRepaint();
    }


    protected override void ImmediateRepaint()  // ...2
    {
        GetLineMaterial().SetPass(0);

        Vector2 min = Vector2.Min(_positionA, _positionB);
        Vector3 relA = _positionA - min;
        Vector3 relB = _positionB - min;

        GL.Begin(GL.LINES);
        GL.Color(Color.blue);  // 線の色です。
        GL.Vertex3(relA.x, relA.y, 0);
        GL.Vertex3(relB.x, relB.y, 0);
        GL.End();

    }


    static Material GetLineMaterial()
    {
        if (!_lineMaterial)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            _lineMaterial = new Material(shader);
            _lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            _lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            _lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            _lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            _lineMaterial.SetInt("_ZWrite", 0);
        }

        return _lineMaterial;
    }
}

```

1.境界(描画領域)を作成しています。
2.描画領域の中に線を引いています。

ImmediateModeElement クラスは VisualElement クラスを継承しています。
ですので、このクラスを VisualElement として EditorWindow に Add できます。

```C#:TestWindow.cs
public class TestWindow : EditorWindow
{

    [MenuItem("Window/UIElements/TestWindow")]
    public static void ShowExample()
    {
        TestWindow wnd = GetWindow<TestWindow>();
        wnd.titleContent = new GUIContent("TestWindow");
    }

    public void OnEnable()
    {
        VisualElement root = rootVisualElement;

        root.style.backgroundColor = Color.white;

        var ce = new ConnectionElement();  // ...1
        ce.positionA = new Vector2(50, 50);
        ce.positionB = new Vector2(100, 100);
        root.Add(ce);  // ...2

    }
}
```

1.ConnectionElement を VisualElement 継承クラスとしてインスタンス化
2.root の VisualElement に ConnectionElement を Add しています。

参考にしたサイト：
https://qiita.com/saragai/items/f7f88df863091946c9d1
https://forum.unity.com/threads/draw-a-line-from-a-to-b.698618/
【jquery】チェックボックスによるフォームの表示・非表示

#やりたい事

###・チェックボックスが1つでもチェックされていたら入力フォームを表示
###・チェックボックスが1つもチェックされていなかったら入力フォームを非表示

#実践
■初期表示
使用フォーム
名前
メールアドレス
住所

■初期非表示
変更理由

※デザインはなし

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<style>
.file_box{
  display: none;
}
</style>
<body>
  <dl class="cf">
    <dt class="title">
      名前
      <input type="checkbox" class="ch" name="subscribe" value="1">
    </dt>
    <dd class="data ">
      <input class="input" type="text" name="name" value="">
    </dd>
    <dt class="title">
      メールアドレス
      <input type="checkbox" class="ch" name="subscribe" value="2">
    </dt>
    <dd class="data ">
      <input class="input" type="text" name="mail" value="" maxlength="128">
    </dd>
    <dt class="title">
      住所
      <input type="checkbox" class="ch" name="subscribe" value="3">
    </dt>
    <dd class="data ">
      <input class="input" type="text" name="address" value="" maxlength="128">
    </dd>
    <div class="ch_box">
      <dt class="title">
        変更理由
      </dt>
      <dd class="data ">
        <textarea class="input ch_text" type="text" name="address" value=""></textarea>
      </dd>
    </div>
  </dl>
</body>
</html>
```

続いて、jquery

```js
  	$(function () {
      $(".ch").change(function () {
        var ch_checked = $(this).prop('checked');
        if (ch_checked) {
          $('.ch_box').css("display", "block");
        }
        if ($(".ch:checked").length == 0) {
          $('.ch_box').css("display", "none");
          $('.ch_text').val("");
        }
      });
    });
```

手順
①3つのチェックボックスに同名のclass名を付与
②どれか1つでも選択されたら入力フォームを表示
1つ以上の条件の方が統一いているかも・・
③チェックボックスのチェックが0ならボックスを隠し、内容を初期化

以上
[自分用メモ] IIAS 起動/停止 方法

#1. やりたいこと

IIAS はアプライアンス製品であり、
アプライアンス管理者 *apuser*で、起動/停止 操作を行うことができます。
#2. 手順

##① 接続

IIASに アプライアンス管理者 **apuser** で接続します。

```
ssh apuser@<IPアドレス>
```

Knowledge Center：接続
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.iias.getstart.doc/doc/app_login.html

##② 状態確認1

**ap** コマンドを実行し、アプライアンスの状態を確認します。

```
ap state -d
```

Knowledge Center：ap commands
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.iias.admin.doc/doc/appl_ap.html

IIASが起動状態であれば、以下のような結果が返されます。

```
System state is 'Ready'
Application state is 'Ready'
Platform management state is 'Active'
```

IIASが停止状態であれば、以下のような結果が返されます。

```
System state is 'Inactive'
Application state is 'Unknown'
Platform management state is 'Inactive'
```

アプライアンスの状態について、詳細は以下リンク先をご参照ください。

Knowledge Center：状態
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.iias.admin.doc/doc/appl_states.html


##③ 起動/停止

※ 起動/停止 コマンドの実行には、10分前後 時間がかかります。

###・ 起動

IIASの起動には、**apstart**コマンドを実行します。

```
apstart -w
```

Knowledge Center：apstart command
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.iias.admin.doc/doc/appl_apstart.html

###・ 停止

IIASの停止には、**apstop**コマンドを実行します。

```
apstop
```

Knowledge Center：apstop command
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.iias.admin.doc/doc/appl_apstop.html

##③ 状態確認2

もう一度 **ap** コマンドを実行し、
無事 IIASが起動/停止されたことを確認します。

```
ap state -d
```

#参考情報

Knowledge Center： IBM Integrated Analytics System
https://www.ibm.com/support/knowledgecenter/en/SSHRBY/com.ibm.swg.im.dashdb.kc.doc/welcome.html
Node-RED Flows file

# 　Flows file
なんとなくで作成したHello Worldフロー。
デプロイボタンはあるものの，メニューには保存アクションは見当たらず。
デプロイしたフローがどこに保存されているのかメモ。

## フローの保存先
Node-REDの起動時に以下メッセージがコンソールに出力されている。

    9 Nov 15:49:54 - [info] User directory : \Users\maema\.node-red
    9 Nov 15:49:54 - [info] Flows file     : \Users\maema\.node-red\flows_hostname.json
    9 Nov 15:49:54 - [info] Server now running at http://127.0.0.1:1880/

Flows fileはどうやら"\Users\maema\.node-red\flows_hostname.json"
にあるらしい。
Windowsマシンにインストールして，デフォルト設定のままなので，
ユーザーディレクトリ下となっている。

## Frows.jsonの中身について

### 作成したフロー
探し出しやすいように以下の名称でHelloWorldフローを作成。

- フロー名：[WST]WorkSpaceTest
- ノード1：[WST]inject
- ノード2：[WST]debug

![0000_Canvas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865740/6d4210a1-2c4f-6dad-f47f-923fe959f940.png)

### 少しFrows.jsonの中身を見てみる
Frows.jsonを開いて，オブジェクトを発見。

- フロー名：[WST]WorkSpaceTest

```
{
  "id": "d086bedd.26fb4",
  "type": "tab",
  "label": "[WST]WorkSpaceTest",
  "disabled": false,
  "info": ""
}
```

- ノード1：[WST]inject

```
{
  "id": "3128a95a.a79aa6",
  "type": "inject",
  "z": "d086bedd.26fb4",
  "name": "[WST]inject",
  "props": [
    {
      "p": "payload"
    },
    {
      "p": "topic",
      "vt": "str"
    }
  ],
  "repeat": "",
  "crontab": "",
  "once": false,
  "onceDelay": 0.1,
  "topic": "",
  "payload": "Hello World",
  "payloadType": "str",
  "x": 100,
  "y": 20,
  "wires": [
    [
      "9373d07f.90f06"
    ]
  ]
}
```

- ノード2：[WST]debug

```
{
  "id": "9373d07f.90f06",
  "type": "debug",
  "z": "d086bedd.26fb4",
  "name": "[WST]debug",
  "active": true,
  "tosidebar": true,
  "console": false,
  "tostatus": false,
  "complete": "payload",
  "targetType": "msg",
  "statusVal": "",
  "statusType": "auto",
  "x": 290,
  "y": 60,
  "wires": [
    
  ]
}
```

全部見るのはメンドクサイので，ぼんやり見てみるとフロー，ノード共に"id"を持っており，ノードの"z"にフローの"id"が指定されているのが分かる。

また，ノード1の"wires"にノード2の"id"が指定されており，ノード2の"wires"は空となっている。
ノードによって違うのかもしれないが，少なくともinjectノードとdebugノードを繋いだ場合，IN/OUTのリンク全てを持たせているのではなく，OUTノードの情報だけを"wires"に持たせているようだ。

そして"x"と"y"に座標情報を持っているのが見え，こんなにシンプルなら頭の良い人がすぐ自動整列機能を作ってくれる未来が見えた。
端にノードを配置してみたところ，サイズは5000 × 5000のようだ。試しにx:0, y:0を指定してみると...

![0001_Canvas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865740/47821476-ccf7-33ff-d642-8254cb9bd99b.png)

少しだけ見えているがほぼ隠れてしまう...
恐らくノードの中心のようなので，ある程度マージンを付けてあげないとダメみたいだ。
自動整列機能の実装を心待ちにしておこう。
Djangoをapiで使うときにTemplate doesnot exit かactivation emailでexample.comになる時の対処法

python manage.py shellでshell 開く

```
>>> from django.contrib.sites.models import Site
>>> current_site = Site.objects.get_current()
>>> current_site.domain = 'localhost:8000'
>>> current_site.name = 'localhost:8000'
>>> current_site.save()
```
domainだけ変えてもexample.comのままなので注意。


新しいのを作る場合。

```commandshell
>>> from django.contrib.sites.models import Site
>>> new_site = Site.objects.create(domain='127.0.0.1:8000', name='localhost')
>>> new_site.save()
>>> print(new_site.id)
```

これで出てきたidをsetting.pyに入れる。

```setting.py
SITE_ID = "出てきたid"

```

あとはadminでも変えられる。
Gatsby のURLに含まれる スラッシュ/ や index を消したい

元記事：[genkitech.net](https://genkitech.net/gatsby-url-delete-index)

Gatsbyのプロジェクトによっては、記事をディレクトリに分割してindex.mdを作成していると、URLが以下のようになる事があります。

http\://localhost:8000/blog-title/
http\://localhost:8000/blog-title/index/

これを

http\://localhost:8000/blog-title

にする方法です。

## コードを編集

gatsby-node.jsにあり、slugを生成しているところを書き換えます。

この部分はホットリロードに対応していないので、変更後リビルドしてください。

```
  switch (node.internal.type) {
    case 'MarkdownRemark': {
      const { permalink, layout, primaryTag } = node.frontmatter;
      const { relativePath } = getNode(node.parent);

      let slug = permalink;


      if (!slug) {

        // ↓↓↓↓↓↓↓↓↓ここを書き換え↓↓↓↓↓↓↓↓↓↓
        // slug = `/${relativePath.replace('.md', '')}/`;

        slug = `/${relativePath.replace('.md', '').replace('/index', '')}`;
      }

      // Used to generate URL to view this content.
      createNodeField({
        node,
        name: 'slug',
        value: slug || '',
      });

      // Used to determine a page layout.
      createNodeField({
        node,
        name: 'layout',
        value: layout || '',
      });

      createNodeField({
        node,
        name: 'primaryTag',
        value: primaryTag || '',
      });
    }
  }
};

```
Vue.js3でもSentry使って監視がしたい

# 要約

まだVue.js3でSentry未対応のため、グローバルなエラーハンドラを使って、監視設定する。

## 設定例

[Sentry公式ドキュメント](https://docs.sentry.io/platforms/javascript/)を見ながら

```console
$ yarn add @sentry/browser @sentry/tracing
```

```main.ts
import { createApp } from 'vue'
import App from './App.vue'
import * as Sentry from '@sentry/browser'
import { Integrations } from '@sentry/tracing'

Sentry.init({
  dsn: process.env.VUE_APP_SENTRY_URL, //ベタ書きでも好きなように
  release: 'my-project-name@' + process.env.npm_package_version,
  integrations: [new Integrations.BrowserTracing()],
  tracesSampleRate: 1.0
})

const app = createApp(App)
app.config.errorHandler = (err, vm, info) => {
  Sentry.captureException(err) // 手動でSentryに送信
}
app.mount('#app')

window.addEventListener('error', (event) => {
  Sentry.captureException(event) // 手動でSentryに送信
})
window.addEventListener('unhandledrejection', (event) => {
  Sentry.captureException(event) // 手動でSentryに送信
})

```
textareaで入力した情報をメソッド内の変数に格納する方法

今回はtextareaで入力した情報をメソッド内の変数に格納する方法を紹介します。


```ruby:new.html.erb

<div class="infomation_new">
 <%= form_tag("/infomations",method: :post) do |f|%>
 　<p class = "infomation_new_textarea"><%= text_field_tag :talent_name%></p></br>
 　<p class = "infomation_new_submit"><%= submit_tag '検索'%></p>
 <% end %>
</div>

```
今回注目するところはtext_field_tagの隣にある:talent_nameのところです。
この記述をして

```ruby:infomations_controller.rb
def create
        talent_name = params[:talent_name]
        agent = Mechanize.new
        personal_page = agent.get('https://talent-dictionary.com/' + talent_name)
        aaas = personal_page.at('.talent_name_wrapper')
        @ages = aaas.at('.age').inner_text.delete('歳').to_i if aaas.at('.age')
        @names = aaas.at('h1').inner_text  if aaas.at('h1')
        @image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
        @infomation = Infomation.where(name: @names).first_or_initialize
        @infomation.age = @ages
        @infomation.image_url = @image_urls
        @infomation.save
end

```


二行目のtalen_name = params[:talent_name]にすることでメソッド内の変数に格納することができます。
例えば山田太郎と入力すると

```terminal
[16, 25] in /home/ec2-user/environment/filebook/app/controllers/infomations_controller.rb
   16:         @ages = aaas.at('.age').inner_text.delete('歳').to_i if aaas.at('.age')
   17:         @names = aaas.at('h1').inner_text  if aaas.at('h1')
   18:         @image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
   19:         @infomation = Infomation.where(name: @names).first_or_initialize
   20:         @infomation.age = @ages
   21:         @infomation.image_url = @image_urls
   22:         @infomation.save
   23:         byebug
=> 24:     end
   25: end
(byebug) talen_name
*** NameError Exception: undefined local variable or method `talen_name' for #<InfomationsController:0x00007f0fb5777ce0>
Did you mean?  talent_name

nil
(byebug) talent_name
"山田太郎"
(byebug) 

```

これでお終いです。
chromeでのcookieの変更方法

# これはなに
- チームのプロダクトで特定のcookieが存在する際の挙動を実装した際、動作確認時のcookieの操作方法について尋ねられたので、メモとして残す
- 2020年11月9日現在chromeの方法しか記載しないが、気が向いたら別のブラウザにおける操作方法も追記する

# chrome
1. 開発者ツールの `Application` タブを開く
2. `Storage`メニューの中の`Cookies`を選択
3. cookieを操作したいドメインを選択する（今回はqiita.comを選択）
4. 操作したいcookieの`Value`をダブルクリックするとテキストエリアがアクティブ化されるので編集し、エンターボタン押下で保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144745/f56e686d-252c-f43f-efde-90c69c96bc14.png)
python mysql.connector で mysql接続のdebug

flaskのコネクションが切れない時に使ったデバッグコード

flaskじゃなかったらどうなんだ？を確認するのに利用

一応記録として残しておく


```python

import mysql.connector

from mysql.connector import Error
from mysql.connector.connection import MySQLConnection
from mysql.connector import pooling
try:
# alias mysqld="mysql -h db.com -P3306 -udev  -p "
    connection_pool = mysql.connector.pooling.MySQLConnectionPool(pool_name="pynative_pool",
                                                                  pool_size=5,
                                                                  pool_reset_session=True,
                                                                  host='db.com',
                                                                  port=3306,
                                                                  database='db',
                                                                  user='dev',
                                                                  password='****')

    print ("Printing connection pool properties ")
    print("Connection Pool Name - ", connection_pool.pool_name)
    print("Connection Pool Size - ", connection_pool.pool_size)

    # Get connection object from a pool
    connection_object = connection_pool.get_connection()


    if connection_object.is_connected():
       db_Info = connection_object.get_server_info()
       print("Connected to MySQL database using connection pool ... MySQL Server version on ",db_Info)

       cursor = connection_object.cursor()
       cursor.execute("select database();")
       record = cursor.fetchone()
       print ("Your connected to - ", record)

except Error as e :
    print ("Error while connecting to MySQL using Connection pool ", e)
finally:
    #closing database connection.
    if(connection_object.is_connected()):
        cursor.close()
        connection_object.close()
        print("MySQL connection is closed")
```
AmazonConnectの東京リージョンで米国電話番号を利用したテスト環境を構築する

Amazon Connectの東京リージョンにて、テスト環境を構築するための手順を紹介します。
最近(2020年11月時点)、なぜか日本の電話番号が取得できないため、米国の電話番号を取得してLINE Out Freeを用いて電話をかけるようにします。

# 用意するもの
- AWSアカウント
- LINEを使うことができるスマホ
- 上記のスマホとは別に、Connectから電話を転送させるための電話機

# AWS側の設定
Amazon Connectのインスタンスを立てるところまでは他の記事にお任せします。
左側のメニューより、「ルーティング」⇒「電話番号」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/ccff4136-986a-f17b-5cb0-271d13168619.png)
右側の「電話番号を取得」ボタンをクリックすると、以下のような画面が表示されます。
日本の番号は取得できないので、米国のDID番号を取得します。
（米国の料金無料通話番号を取得してしまうと、LINE Out Freeでは発信することができません。Skypeであれば料金無料通話番号へも発信できます。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/36bfa6f0-b796-9a00-df01-39f3f953363a.png)

問い合わせフローは、「お電話ありがとうございます。」というプロンプトを流すだけのものにしています。作成したら公開するのを忘れずに！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/cb8afbdf-3bd9-f038-1e07-cf516c741bb1.png)

# LINE側の設定
iOSで操作しているため、Androidの場合は操作感が違うかと思います。
LINEアプリを立ち上げ、ホーム画面のサービスの「もっと見る」をタップ。
![IMG_2056.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/64d7c466-baba-e56e-4a7c-2681978c3208.jpeg)
便利ツール内の「LINE Out Free」をタップ。
![IMG_2060.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/cee0816b-5bef-481d-5531-6b0d0209c41a.jpeg)
左上のダイヤルマークをタップ。
![IMG_2061.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/6d100429-d2a9-d547-6f4b-7608c804e7dd.jpeg)
「日本」（もしくは他の国名）と書かれている部分をタップ。
![IMG_2062.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/f3670d35-302a-460b-70a5-88fd8e413adc.jpeg)
「アメリカ合衆国」をタップ。
![IMG_2063.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/ba1a6922-e23a-41ec-8665-054696451227.jpeg)
これで、電話が掛けられる状態になりました。AWSで取得した電話番号にかけてテストします。
<img width="300" alt="IMG_2064.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/208682b7-2606-ed15-24e7-2f13b17d48a7.jpeg">

# つまづいたポイント
LINE Call Outを利用する際、本人確認(電話番号のSMS認証)を実施していない状態だと電話がかかりませんでした。原因は不明ですが、電話がかからない場合は本人確認を実施しておくほうが良いと思います。

# おわりに
1日5回までしか通話することができませんが、DID番号に無料でかけることができるので、安くテストするには向いていると思います。また、1日5回以上通話する場合も、120円からチャージすることができるため（Skypeは500円から）、使いやすいと思います。
表から数値を読み取って水位レベルを描画したい

# やりたいこと
* 水槽が1つある
* 水槽には水位レベルが定められている  
* 水位レベルを正確に描画したい

↓こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96134/eaa1547f-2c1e-73a3-5e40-59e1f74d2be0.png)

# オブジェクト名を定める
1. `ホーム>選択>オブジェクトの選択と表示`を開く
2. オブジェクトに名前を付ける(水槽=>Aquarium, 水位表=>WaterTable, 線=>Lv3~Lv1)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96134/f1e20f1d-903d-50cd-0305-cac99cc0a84b.png)


# VBA
```VBA:VBA
Sub SettingWaterLvl()

    Dim shp As Shape
    Dim WaterTable As Table
    Dim Aquarium, Lv3, Lv2, Lv1 As Shape
    
    ' オブジェクトを設定する
    For Each shp In ActiveWindow.Selection.SlideRange.Shapes
        If shp.Name = "WaterTable" Then
            Set WaterTable = shp.Table
        ElseIf shp.Name = "Aquarium" Then
            Set Aquarium = shp
        ElseIf shp.Name = "Lv1" Then
            Set Lv1 = shp
        ElseIf shp.Name = "Lv2" Then
            Set Lv2 = shp
        ElseIf shp.Name = "Lv3" Then
            Set Lv3 = shp
        End If
    Next
    
    ' 表から水位レベルを読み取る
    Dim TableValues As CellRange
    Set TableValues = WaterTable.Columns.Item(2).Cells

    Dim MaxValue, Lv3Value, Lv2Value, Lv1Value, MinValue As Double
    MaxValue = CDbl(TableValues.Item(2).Shape.TextFrame.TextRange.Text)
    Lv3Value = CDbl(TableValues.Item(3).Shape.TextFrame.TextRange.Text)
    Lv2Value = CDbl(TableValues.Item(4).Shape.TextFrame.TextRange.Text)
    Lv1Value = CDbl(TableValues.Item(5).Shape.TextFrame.TextRange.Text)
    MinValue = CDbl(TableValues.Item(6).Shape.TextFrame.TextRange.Text)

    Lv3.Top = ((Aquarium.Top + Aquarium.Height) - Aquarium.Top) / (MinValue - MaxValue) * (Lv3Value - MaxValue) + Aquarium.Top
    Lv3.Left = Aquarium.Left

    Lv2.Top = ((Aquarium.Top + Aquarium.Height) - Aquarium.Top) / (MinValue - MaxValue) * (Lv2Value - MaxValue) + Aquarium.Top
    Lv2.Left = Aquarium.Left

    Lv1.Top = ((Aquarium.Top + Aquarium.Height) - Aquarium.Top) / (MinValue - MaxValue) * (Lv1Value - MaxValue) + Aquarium.Top
    Lv1.Left = Aquarium.Left

End Sub
```

# 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96134/381438db-4ea7-6478-1e56-e85bdd09fb8f.png)
ContentSecurityPolicy(CSP)

#はじめに
先日、仕事でセキュリティに関する内容の仕事をしていたがそれまでクリックジャックって〜フィシングサイトって〜みたいな概念的な物しか把握してなかったので調べました。
もっと具体的に〜があって、〜が問題でだからこの設定が必要である。
というもうちょっと掘り下げた内容を備忘録として残していきたいと思います。

#ContentSecurityPolicy(CSP)って？
ドキュメントより
https://developer.mozilla.org/ja/docs/Web/HTTP/CSP
>コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (XSS) やデータインジェクション攻撃などのような、特定の種類の攻撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。これらの攻撃はデータの窃取からサイトの改ざん、マルウェアの拡散に至るまで、様々な目的に用いられます。

つまりやXSSという脆弱性があると悪意のあるユーザーによって仕込まれた任意のJavaScriptが実行できてしまい、データの窃盗や改竄などができてしまう。

XSSへの内容としては
>CSP の第一の目的は XSS 攻撃の軽減と報告です。 XSS 攻撃とは、サーバーから取得したコンテンツをブラウザーが信頼する性質を悪用した攻撃です。ブラウザーはコンテンツの送信元を信頼するため、たとえ実際の送信元が見かけ上とは異なっていたとしても、悪意あるスクリプトが被害者のブラウザー上で実行されてしまいます。

>サーバー管理者が CSP を利用する場合、実行を許可するスクリプトの正しいドメインをブラウザーに向けて指定することにより、 XSS の発生する箇所を削減・根絶することができます。 CSP をサポートするブラウザーは、サーバーから指定された許可リストに載っているドメインのスクリプトのみ実行し、他のスクリプトはすべて無視します (インラインスクリプトや HTML 属性値のイベントハンドラも無視する対象に含まれます)。

>究極的な防衛策として、スクリプトを決して実行させたくないサイトは、スクリプトの実行を全面的に拒否することも可能です。

設定することでスクリプトの実行制限をかけたりホワイトリストにして限定的に許可したりできたり
するそうです。

パケットへの内容については
>取得するコンテンツのドメインを制限することに加えて、サーバーは通信に使うプロトコルを指定することも可能です。例えば、 (セキュリティの観点からはこれが理想的ですが) すべてのコンテンツを HTTPS で取得されるようにサーバーから指定することが出来ます。データ通信におけるセキュリティ戦略を完全なものとするには、HTTPS 通信を強制するだけではなく、すべての Cookie に secure フラグ を付けたり、HTTP ページから対応する HTTPS ページへの自動リダイレクトを整備することも必要です。また、ブラウザーが暗号化された通信路のみを用いてサイトに接続することを保証するため、Strict-Transport-Security HTTP ヘッダーを利用することも可能です。

設定することで取得するコンテンツのドメインやプロトコルを制限することができるそうです

これによりどこらか、どこへかの制限ができる

設定のしかたについてはこちら
https://developers.google.com/web/fundamentals/security/csp/?hl=ja

ディレクティブの早見表を作ってくださったかたがいらっしゃるのでディレクティブな内容はそちらを参照
https://qiita.com/zabu/items/d2fbac1abc81eba38efb
プラットフォーム（OS）の利用率

システムを作る上で、たくさんの人が使っているプラットフォームで最初から開発したいなぁと思ったので、
掲題のように各利用率を幾つかウェブ検索して探しました。その中で参考にしたサイトを載せます。
新しく始める方も、ユーザー数が多い方が見てくれる人や協力者が単純に多くなるので参考にしてみてください。
（ライバルも多くなりますが。。。）

資料の見方
見出しの名前はサービス名です。
アップロードの頻度やデータの生成方法、ライセンス等使いたい時に知っておきたい情報も載せます。


##[①Operating System Market Share](https://netmarketshare.com/operating-system-market-share.aspx?options=%7B%22filter%22%3A%7B%22%24and%22%3A%5B%7B%22deviceType%22%3A%7B%22%24in%22%3A%5B%22Desktop%2Flaptop%22%5D%7D%7D%5D%7D%2C%22dateLabel%22%3A%22Trend%22%2C%22attributes%22%3A%22share%22%2C%22group%22%3A%22platform%22%2C%22sort%22%3A%7B%22share%22%3A-1%7D%2C%22id%22%3A%22platformsDesktop%22%2C%22dateInterval%22%3A%22Monthly%22%2C%22dateStart%22%3A%222019-11%22%2C%22dateEnd%22%3A%222020-10%22%2C%22segments%22%3A%22-1000%22%7D)
開発者：Net Application（webをメインに分析対象とし、多くの企業のパートナーとして活躍しているアメリカの会社）
UP頻度：毎日
生成方法：製品の市場シェアを通じてこれらのサービスを提供しています(wikiより）
        クライアントを監視している40,000のサイトにアクセスするマシンを追跡することでブラウザの使用状況を測定しています(wikiより）
ライセンス：記載無し
その他：大手の会社が利用している。
　　　ボットトラフィックの回避ができる。
　　　CSVとJSON形式でダウンロードできる。
　　　検索方法を変えると、モバイル版のOS比較やブラウザの利用率比較もできる。


##[②statcounter global status](https://gs.statcounter.com/os-market-share/all/japan)
開発企業：statcounter社（ウェブサイトのトラフィック等のデータ収集をするシステムを開発・販売しているアイルランドの会社）
UP頻度：毎月
生成方法：自社サービスのトラっフィック情報を収集し分析した結果と思われます。
ライセンス：Creative Commons Attribution-Share Alike 3.0 UnportedLicense
その他：ブラウザの利用率比較ももちろん掲載されています。
　　　　CSVでデータをダウンロードできる。
　　　　日本に特化することもできる。


##[③OSのシェアの統計情報](https://lab.syncer.jp/Statistic/OS/)
開発者：Syncerさん（ブログ）
UP頻度：２０１９年まで、毎月
生成方法：不明
ライセンス：不明
その他：日本に特化している
　　　　多分Net　Marketshareを利用していた？と思います。
Laradock環境でnpm run devエラー

#顛末#
Windows版XAMPPを使った環境で作成していたアプリを、macのLaradock環境に移そうとして試行錯誤した話です。
フロントエンドでvue.jsを使いたいと思った矢先の出来事でした。

結局のところ、Npmでインストールしたパッケージのバージョンが、Laradock環境のNode.jsに対応していなかっただけと思われます。

蓋を開けてみればアホみたいな原因でしたが、忘備録としてまとめてみました。
端末の実行結果は殆ど取り忘れてたので、打ち込んだコマンドを中心に掲載します。

同じような症状の方の一助になればと思います。

#ハマるまで#

まずはリポジトリからソースコードを取り込み。

```
git clone https://username/appname.git
```

で、composerとnpmでパッケージをインストール。

```
composer install
npm install
```

そいでもってnpm run

```
npm run dev
```

ここでエラー吐いて詰みました。

#原因と思われる要因#

##1. lockファイルが残ってたため##
調べてみると、composer.lock、package-lock.jsonというファイルがそれぞれcomposer、npmによりインストールされているライブラリの実際のバージョンを示しているそうです。

これとは別に、composer.json、package.jsonというファイルがありますが、こちらはインストールするパッケージのみを示し、バージョンは"〇〇以上"といったラフな指定のみを行っているようです。

composer.jsonはプロジェクト作成時に生成されるものなので残しておく必要があります。package.jsonはcomposer installで生成されるので消しても大丈夫。
パッケージ本体はvendor/、node-modules/ディレクトリにそれぞれ入っています。

そのため、以下のコマンドでファイルを削除してからパッケージを再インストールしました。

```
rm -rf vendor/ node-modules/ composer.lock package.json package-lock.json 
```

##2. キャッシュが悪さをしていたため##

1.を実行しても状況は改善しない。と同時に、何やらcomposer install時にエラーを吐いているのを見つけました。

読んでみるとUnzipコマンドのエラーとのこと。
ネットで調べた結果、残留しているキャッシュのせいでzipファイルが正しく取得・解凍できなくなることがあるようです。
composer、npmともにキャッシュを削除する以下コマンドがあったので、さっそく実行し再度インストール。

```
composer clearcache
npm cache clear
```

そしてnpm run失敗。

##3. Composerとnpmパッケージのバージョンが適合していなかったため##

これが1番効いてる気がします。

2度の失敗で失意の中ターミナルを睨んでいると、とある部分に目が留まりました。

```
npm installlaradock@9b2fcf1e464f:/var/www$ npm install
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
```

そういえばWin版のNode.jsバージョンは12、Laradockに入れている方は最新版の15.1.0を入れている。
というかこのエラーを見てLaradockのNode.jsバージョンを14から15にかえたんだっけか。

更に踏み込んで読んでみる。
なるほど、Chokidar ver.2.1.8という~~変な名前の~~パッケージはnode.js Ver.14では動かない。ChokidarのVer.3以降をインストールしろという事か。

ということでさっそく実行。

```
npm install chokidar@3.0.0
```

結果、見事npm run devが通りました。

#学び・教訓#

エラーコードはちゃんと読もう。これに尽きると思います。
英語で書かれているからと言って特別難しい単語が出てくるわけでもないので、面倒がらずに読むのが一番ですね。

環境構築はプログラミングの前段階ですこぶる地味なので、個人開発において心が折れやすいポイントだと思っています。Laravelなどのフレームワークは管理するパッケージも多く大変です。

とは言え今回の件でComposer、Npmに対する理解を深めることができたのは大きな収穫だったと言えます。自分にとってもちょっとしたマイルストーンになったと思いました。


原因特定に費やした2週間かえして
Luaで湯婆婆を実装してみる

#初めに
元ネタ様：[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

このビックウェーブに乗るしかない
初投稿です

#コード
```lua:Yubaba.lua
print("契約書だよ。そこに名前を書きな")
Name = io.read()
print("フン。"..  Name .."というのかい。贅沢な名だねぇ。")

Len = string.len(Name)

Seed = os.time()
math.randomseed(Seed)
rand = math.random(Len / 3) -1

cnt = 3 * rand + 1

newName = string.sub(Name,cnt , cnt + 2) 

print("今からお前の名前は".. newName .. "だ。いいかい、" .. newName .."だよ。分かったら返事をするんだ、" .. newName .. "!!")
```

#実行例
最新版のZerBrainStudioで実行しました
![Yubaaba.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320969/2d4e7794-dc54-098c-6af0-86175c20a319.png)

#終わりに
Lua歴1ヶ月なのでまだ雑なところがあるかもしれないです
【Docker】[18116] Failed to execute script docker-compose Tracebackの解決

#概要
業務でDocker使用する事になったため、公式や記事を参考に環境構築を行っていたが、タイトルのエラーが表示され続けて、composeコマンドがまったく通らなくなってしまったため、解決策をメモする。

docker-compose upなどと叩くと下のようなエラーが吐き出される。
>[18116] Failed to execute script docker-compose
Traceback (most recent call last):

###ローカルの環境
開発環境は以下の通り
* Windows 10 Pro
* Docker v19.03.13

#解決方法
結論を言うと、DockerやPowerShellの実行をとり消すか、<b>1回PCを再起動</b>すれば普通に治り、composeコマンドが通る。
動作確認のためにdockerコマンドを色々と試したせいで、プログラムが正常に終了されず<b>「すべてのパイプ インスタンスがビジー状態」</b>になってしまったのが原因。

支給されたPCがやや低スペックなのもあり、しっかり叩いたコマンドの完了を確認せず次のコマンドを叩いたのも要因だった。

#追記
再起動せずとも、Docker desktopのQuit docker desktopでDocker自体を一旦停止させて、再度Dockerを立ち上げ直せば動作することを確認。