OmniAICreator/Qiita-1.07M huggingface dataset:
phpのarrayキャストで元々arrayが二重arrayになるわけではない


すいません。マニュアルをよく読めば書いてあることです。

(array)の挙動を確認します。

* 文字列から配列に展開されるか？
* 配列は二重配列になるか？

phpのマニュアル

* [(array)は型キャストのひとつです](https://www.php.net/manual/ja/language.types.type-juggling.php#language.types.typecasting)
* [(array)は配列へのキャストです](https://www.php.net/manual/ja/language.types.array.php#language.types.array.casting)
 
```php

// 配列と文字は異なる値です
var_dump(["a"] === "a"); // false

// 文字が配列に変換され一致します
var_dump(["a"] === (array)"a"); // true

// 元から配列なら変換されません
// 配列で囲まれるわけではありません
// 型の変換なので、配列型は配列型のままでした
var_dump(["a"] === (array)["a"]); // true

// 配列と文字列なので当然異なる値です
var_dump(["a", "b", "c"] === "abc"); // false

// もしかして複数文字は配列に展開される？ ["a", "b", "c"]
var_dump(["a", "b", "c"] === (array)"abc"); // false

// そんなわけありません。
// c言語のchar型の配列と間違っていました。
// 文字列を配列にキャストすると項目が１つの配列になりました。
var_dump(["abc"] === (array)"abc"); // true

// 元から配列なら変換されません
var_dump(["a", "b", "c"] === (array)["a", "b", "c"]); // true

```
オンラインだけでOracle SQLを学ぶ環境構築

希望する条件は以下の通り。

- ローカルに環境を用意しない。
- ターゲットはOracle。

調べたところ、やや古いものとして「Oracle Application Express」、新しめのものとして「Oracle Live SQL」があった。
どちらもOracle公式だが、利用開始までの手順などをメモ。

# Oracle Application Express

[http://apex.oracle.com/pls/apex/](http://apex.oracle.com/pls/apex/)にアクセス。
「日本語」をクリックして日本語化した後「ワークスペースのリクエスト」をクリック。

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/9c752449-d15a-f805-bbf4-aaa84f48114f.png)

以後、ワークスペースのリクエストのための入力が続くので、順次入力し「次」クリック。
最後に「リクエストの送信」をクリックして数分でメールが届くはずです。

- 識別
 - 名
 - 姓
 - 電子メール
 - ワークスペース：任意でよいが、他のユーザと重ならないよう、日付を付けるなど長い名前に。
- アンケート
 - ２つとも「Yes」
- 正当性
 - 「ＳＱＬ学習のため」とか適当で良い。
- 同意書
 - 「条件に同意します」にチェック。

次のメールが来たら、「Create Workspace」クリック。

![h.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/350d39d9-c840-0da8-0a04-a1994250b2ba.png)

しばらくして「ワークスペースは正常に作成されました。」と表示されれば問題なし。
「サインイン画面に進みます」クリック。

![j.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/5f7f714c-921f-6082-d3b8-be9fc9325ab6.png)

ここでパスワードを設定することになるので、2回入力後「パスワードの変更」クリックで次のような画面が表示されれば成功です。

![k.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/7ae8b3eb-fb44-0fcb-c3b2-2d7c584b2d51.png)

このOracle Application Expressを使ったものとして、以下の記事がありました。
やや古くなっているので、Oracle Application Expressの使い方や見た目が違いますが、ここまでの方法でサインインできていれば中身はそのまま同じように操作できるようなので、第1回から順に読んで試せます。
（第2回の手順11までは終わっているはずです）

Webブラウザで気軽に学ぶ実践SQL講座
https://www.atmarkit.co.jp/ait/series/728/

# Oracle Live SQL

[https://www.oracle.com/technetwork/jp/database/application-development/livesql/index.html](https://www.oracle.com/technetwork/jp/database/application-development/livesql/index.html)にアクセス。
「コーディングを開始」をクリック。

Oracleプロファイルへのサインインを求められるので、IDを持っていれば入力して「サインイン」。
持ってなければ一番下の「プロファイルの作成」からIDを作ってサインインします。
サインインできると次の画面になります。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/e410fb97-60eb-5c0f-463b-189663d25261.png)

Oracle Live SQLには、英語ですがサンプルコードやチュートリアルが多数用意されています。
左の「Code Library」を選び、表示された選択のTypeを「Tutorials」にすると、チュートリアルだけが一覧表示されます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/7bcfd1c5-b046-f530-5a58-9b36dc648db1.png)

興味があるものを選択すると内容が表示されます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/1f6c511b-0400-57da-dde8-a30d2e9f7839.png)

そのままでも読めますが、右上の「Run Tutorial」をクリックすると、次のようにSQL Worksheetの横にチュートリアルの内容が表示され、内容を試しやすくなります。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/039acd19-f81f-1d68-fc44-454960393d5d.png)

具体的には左上のエリアにコードを入力し、右上の「Run」をクリックするだけでコードが実行され、下に結果が表示されます。
（コードは、チュートリアルの「Insert into Editor」をクリックすることでも入力できます）

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111541/4d35eeb9-60a0-72dd-21a8-9c76a7da80a0.png)
【rails】mysqlでdb:createしたらAccess denied for user 'root'@'localhost'

調べると`Access denied for user 'root'@'localhost' (using password: NO)`の対処はたくさん出てくるけど、`Access denied for user 'root'@'localhost'`で終わっているエラーはすぐに出てこないので自分用に残します。

##対処法

mysqlにユーザーを指定してログイン。
別のマシンでサーバーが動いていたら、ホスト名も指定する。
パスワード入力を求められるので、パスワードを覚えていたら入力。
間違えて何度もエラーが出るなら頭に`sudo`付けたら入れる。

```
$ mysql -u root -p
```
任意のユーザー名とパスワードを入力する。
ここではユーザーに全てのDB操作権限を付与している。
`*.*`にDBの名前を入れる。
大文字小文字区別しないので小文字でもいい。
私の場合は既存のユーザーに権限付与したので、存在しないユーザーを指定したらユーザー作成から始めないといけないかもしれない。

```
mysql> GRANT ALL PRIVILEGES On *.* TO ユーザー名@localhost IDENTIFIED BY ‘パスワード’;
```


このあとに`rails db:create`しても同じエラーが出たので,`database.yml`を修正。
`username`と`password`に先程作成した任意のユーザー名とパスワードを入力。



```yml:config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: ユーザー名
  password: パスワード
  socket: /var/run/mysqld/mysqld.sock

development:
  <<: *default
  database: hoge_development

test:
  <<: *default
  database: hoge_test

production:
  <<: *default
  database: hoge_production
  username: hgoe
  password: <%= ENV['HOGE_PASSWORD'] %>
```


```
$ rails db:create

Created database 'hoge_development'
Created database 'hoge_test'
```

上手く行きました。





##ちなみに表示されるプロンプトの意味

| 促す | 意味 |
|:--|:--|
| mysql> | 新しいクエリの準備ができました |
| -> | 複数行クエリの次の行を待機しています |
| '> | 一重引用符（'）の完了を待つ |
| "> | 二重引用符(")の完了を待つ|
| `> | バックティック（`）の完了を待つ |
| /*> | コメント(/*)の完了を待つ |
【学習メモ】Git、GitHubの基礎（１）

#0. 目標
Gitの基本的なワークフロー、コマンドの内容や機能を理解する

#1. Gitの基本的なワークフロー
変更をコミットする流れ
1.ファイルの変更をステージングエリア（≒控え室）へ追加
2.ローカルリポジトリにcommit（委託する）
3.リモートリポジトリにpushする

#2.ステージングエリアへの移動
ステージングエリア：複数ファイルを変更する際に、コミットするファイルを選択する

ステージングエリアへの移動は、、、

```
$ git add [ ファイル名 ]
$ git add.　（ファイル全体を移動させる）
```

#3.ローカルリポジトリへCommit

ステージングエリアへの追加が終わったら、Commitする

```
$ git commit
$ git commit -v 
```
すると、こんな感じでVimエディタというCommitを編集するエディタが表示される

```
■ ← #入力画面
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
#   (use "git push" to publish your local commits)
#
# Changes to be committed:
#       modified:   first.txt
```

入力方法は、次の通り

**＜Vimエディタの使い方＞**
①ターミナルでgit commitを入力する
②Vimエディタが立ち上がる
③半角英数字に入力を切り替える
④「i」を入力する（挿入モードになる）
⑤コミットメッセージを入力する
⑥「esc」を押す（ノーマルモードに戻る）
⑦「:wq」を入力してエンターを押す
（commitメッセージを保存してエディタを閉じる）

**※Vimエディタ（⑤）の書き方のポイント**
１行目：変更内容の要約
２行目：空行（空白）
３行目：変更理由（何のため？背景は？）

⑦が終わると、こんな感じの履歴が残り、元のターミナルに戻る

```
[master ***] ***を〜〜（変更内容）
 1 file changed, 2 insertions(+), 1 deletion(-)　※一例
```

＜その他補足＞
最初に変更する時は、「initial commit」と書くのが慣例

#4.GitHubへのプッシュ

GitHubへプッシュするためには、GitHub上でリモートリポジトリを用意する必要がある

###流れ
1.ブラウザでGitHubを開き「NewRepository」をクリック
2.Repository nameを設定
3.Public を選択
4.Create Repositoryを押す
5.push用のコマンドがブラウザ表示されるので、ターミナルに実行

```
5.の様子
git remote add origin ... （イメージ）
6.の様子
git push -u origin master ...（イメージ）
```

続きは明日以降投稿予定

参考
1.Railsチュートリアル　Git
https://railstutorial.jp/chapters/beginning?version=5.1#sec-version_control


2.udemy講座
https://www.udemy.com/course/intro_git/learn/lecture/6449716#content
RPGツクールMVのゲーム画面の大きさ・スケール（拡大）を変えるあれこれ

# やりたいこと
16px/32pxのタイルセットやキャラクターセットを使いつつ48pxと同じ画面サイズ感にする。

# まず
RPGツクールMVのリサイズ・スケール周りは何かとややこしい


- F4 でフルスクリーンモード
- F3 Streach Mode（ウィンドウサイズに応じてゲーム画面がリサイズされる）
 - スマホ・プレイヤー(nwui)の場合はデフォルトON、PCの場合はOFF
 - 参考： `_updateRealScale()` (rpg_core.js:1644)

# 初期ウィンドウサイズ（スケール）を変えたい
`Graphics.scale` を書き換えてウィンドウサイズを変えればよい

```js
    var Graphics_initialize = Graphics.initialize;
    Graphics.initialize = function (width, height, type) {
        Graphics_initialize.call(Graphics, width, height, type);

        // streach mode = offの場合、scaleをもとに計算される
        Graphics.scale = 2;

        // streach mode = onの場合は、ウィンドウサイズ=スケールなのでウィンドウを変えてしまう
        window.resizeTo(SceneManager._screenWidth * Graphics.scale, SceneManager._screenHeight * Graphics.scale);
    }


```

# 整数倍でスケールさせる
http://www.yanfly.moe/wiki/Core_Engine_(YEP)
の `Update Real Scale` をtrueにする
デフォルトでは 0.5, 1, 1.5, 2, 3倍。 1.5が邪魔なら消してしまう。
このプラグインを導入すると上記のスケールが動かなくなる
（後述のゲーム解像度変更のためウィンドウサイズを初期化時にかえるため）

```js:YEP_CoreEngine.js:1040
Graphics._updateRealScale = function() {
  if (this._stretchEnabled) {
    var h = window.innerWidth / this._width;
    var v = window.innerHeight / this._height;
    this._realScale = Math.min(h, v);
    if (this._realScale >= 3) this._realScale = 3;
    else if (this._realScale >= 2) this._realScale = 2;
    else if (this._realScale >= 1.5) this._realScale = 1.5;
    else if (this._realScale >= 1) this._realScale = 1;
    else this._realScale = 0.5;
  } else {
    this._realScale = this._scale;
  }
};
```

# ゲーム画面のピクセル数(デフォルト:816x624)を変える
上記プラグインの`Screen Width`と`Screen Height`を変えるだけ。
いわゆるビューポート自体が変わるので画面に映る範囲は狭くなる

# 本題
RPGツクール2000みたいな化石の資産を使おうとしてもMVではタイルセットが48px固定になっている。
（逆にキャラクターセットは比率が合っていればどのサイズでもOK。なぜ？ https://tkool.jp/mv/course/04.html）

そのためプラグインでタイルセットの基準サイズを変えるプラグインを入れる
https://forums.rpgmakerweb.com/index.php?threads/change-tile-size.46748/

- これ単体で16pxタイルセットを使うと広い画面に対して小さなタイルセットが並んでしまうので
- 上記解像度を1/3(272x208)にするとぴったり納まる
- ウィンドウが小さいのでスケールで2～3倍にする
- たぶんいい感じになる

# 問題点
- いろいろ描画が壊れる。テキストボックスとか。

# 結論
**下手にプログラムをいじらずに素材を48pxにスケールしてそのまま使ったほうが楽。**
JS初級者がYouTubeMusic→Youtubeに移動するためののChrome拡張機能を作ってみた。

#悲しきかな
最近のニュースに、こんなのがありました。

>Google play musicの年内サービス終了

私は結構な頻度でGooglePlayMusicを使ってたわけですが、
こういうニュースもあったのでYoutubeMusicに移行することにしました。
と言いましても、まだ移行手続きの準備はできてないとかなんとか。
そこで試しにYoutubeMusicの下見に行きました。
#コレナンデ概要欄ないん
私が使ってはじめに抱いたのはこの疑問でした。
確かに無いならないでいいのですが、
ちょっと気になります。
しかも、YoutubeMusicなのにYoutube上の同じ動画に、飛ぶ直リンクが無いではありませんか。

しかもちょうどよく、URLをちょっといじれば飛べるじゃないですか。

これはChrome拡張機能を作るしかねぇ。（作ったことはありません。）
#こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/354f61c9-415f-79d9-7c56-b667df55cfb5.png)
moveというのがボタンになっている。
（違和感しかない）

#用意するもの
メモ帳、、、は無理なのでVSCODE
Chrome
パソコン
絵を書くやつ（とりあえずクリップスタジオ？みたいなやつ）
Githubにファイル一式あります。
https://github.com/haraday0403/YoutubeMusic_to_Youtube_links
#１manifest.jsonを作ろう
私：これ何
知り合い：定義書みたいなもの？

```json

{
  "name": "YoutubeMusic_linker",
  "version": "1",
  "description": "YoutubeMusicで再生中の動画をYoutubeで見るためのボタンみたいなのを出してくれます。\nとってもいびつですね。",
  "permissions": ["activeTab","declarativeContent"],
  "content_scripts": [{
    "js": ["background.js"],
    "css":["bootstrap.min.css"],
    "matches": ["https://music.youtube.com/*"],
    "run_at": "document_end",
    "all_frames": true
  }],
  "icons": {
    "48": "images/get_started48.png"
  },

  "manifest_version": 2
}

```
name:拡張機能名
version:拡張機能のバージョン
description:説明文
permissions：権限？知り合いに任せた。
content_scripts：ページ内で実行するものの読み込むコードなど書く場所
matches：動作させるページの指定
run_at:実行タイミング（確か最後に読み込む？）
all_frames:よくわからんけど書けって言われた
icon：アイコンの設定前の数字が何かはわからん
manifest_version：このファイルのバージョン（あってるかは不明）

チェックポイント
今回はBootstrapを使いたかったので、ダウンロードして、作業フォルダにコピーしました。
（UIデザインが全くできないため）
アイコンは先に用意しましょう。
![get_started48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/2bff2804-e3a4-2d14-f3f4-470fc2dd0d3a.png)
ダサ（IconにもBootstrapをください）

#2 jsを書こう
知り合い：適当にエレメント触ればいいぞ。
私：appendChildさせてくらないんですが。
知り合い：（こいつマジで何も知らねえんじゃ）

今回一番の闇ポイント（同時に本題でもある）

```js

const target=document.getElementsByClassName("title style-scope ytmusic-player-bar")
const observer = new MutationObserver(records => {
    loader()
  })
  observer.observe(target[0] ,{
    childList: true
  })
function loader(){
if (!document.getElementById("urlteleporter")){
main();
}
else{
var url=location.href;
document.getElementById("urlteleporter").href=url.replace("music.youtube","youtube");
}
}
function main(){
    var elem=document.getElementsByClassName("player-minimize-button style-scope ytmusic-player");
    var alter=document.createElement("a");
    var url=location.href;
    alter.id="urlteleporter"
    alter.innerText="Move";
    alter.href=url.replace("music.youtube","youtube");
    alter.classList.add("btn","btn-dark","text-center");
    elem[0].parentNode.appendChild(alter);
    }


```
ざっくり動きの説明
１：タイトルバーが変化（もしくは出現）すると、オブザーバーが検知してLoaderを実行
２：Loaderはこっちで用意したIDを持つものがあるか検知し、なければ生成、あればURL書き換えを行う。
３：ない場合は、Mainを実行し、新しくボタンを作成する。
BootstrapはCSSで読み込んでるので無問題。

チェックポイント
1：最初オブザーバーなしで行った
＝＞ページ移動がないせいでURLが変化しない
2：オブザーバーをおいた
＝＞一回目の実行のときに何故か２こ出てきたので、初期化処理しないようにした。
3：Classlistはスペースで区切れない＝＞,で分けてやる

#読み込み
chrome://extensions/
からデバッグモード＝＞パッケージ化されてない拡張機能を読み込むで作業フォルダを読み込めば完成。

対応しないページは灰色アイコンになる。
#言いたいこと
デザインって大事だわ。
（皆さんはaタグ内にimgタグとボタン用画像を用意するのをおすすめします。）

#この拡張機能をGoogleに出してこよう。
多分通らない気がしますが出してきます。
【ステイホーム】zoom麻雀用Webサービスを1.5日で作った話【お家で過ごそう】

## はじめに

こんにちは。
みなさん、いかがお過ごしでしょうか。

僕は、仲間で麻雀をするのが楽しみの一つなのですが、この状況下、みんなでそろって麻雀することは控えております。
そこでzoom飲み会ならぬ、zoom麻雀をしております(笑)

オンライン麻雀で、仲間用の部屋を作ってそこに集まって、zoomで会話しながら麻雀をするって形ですね。

これがなかなかスムーズで快適で、みんなとも色んな話ができて楽しいです(^^)

ただ、1つの難点を除けば、、、

## 難点とは

難点とは、そう！

**チップのやり取りができない！**

麻雀は、点数そのもののやり取り以外に、「チップ」というのを使って、和了(あが)り方によって、点数とは別に何枚払う/もらう、みたいなルールも追加できるんですね。
和了ったときに、

1. 赤いドラがあったら1つにつきチップ1枚
2. 裏ドラがあったら１つにつきチップ1枚
3. 役満あがったら5枚

などなど。
まぁ、このルールは仲間の中で好きに決めますがｗ

## ないなら作れ

初めて仲間内でzoom麻雀したのがある日の金曜日だったんですね。そのときは、「あー、これだとチップやり取りできないねぇ」ってなったんですが、ぼくはITエンジニア。

**「じゃ、作るわ！」**

と、言いました。

この時に、構想とかあったわけじゃないんですけどね(笑)

で、土曜の朝から構想して、日曜の夕方に麻雀仲間に

**「できたよー」**

と、できたのが、これ！

**チップくん**
https://mahjang-chips.an.r.appspot.com/
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/083dc04e-813f-b965-63f1-5d587aec2c4c.png)
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/bc083d6e-76c1-8bbf-3a23-bbc557ad0404.png)
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/e3c58732-7bd4-b2ec-7b68-13bb46ce3219.png)

## システムの流れ
と、前置きが長かったんですが、システムの流れは以下。
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/1b6b3e3b-5b68-daed-37bd-69858b08b9bf.png)

1. 主催者が面子(メンツ）を設定する。
2. 生成されたURLをメンツに連絡する。
3. 全員、同じURLにアクセスする。
4. そこの画面でチップのやり取りを行う。

と、シンプルなもの。

この通り、画面としては、3つだけ。
チップのやり取りを行う画面では、

1. チップの枚数の増減ボタン
2. 増減の確定ボタン
3. 画面の更新ボタン

があるのですが、2,3の処理は非同期処理にて実装しました。
ボタンを押すたびに画面ごとリロードするのは、ダメだな、ってことで。

## システム構成
このサービスを運用するのに、できるだけお金かけたくないなぁっと思って色々検討した結果GCP(Google Cloud Platform)を使うことにしました。
最小のVMならタダっぽかったんで。

あとは、データベースをどうするか考えたんですが、使ったことないけど「Datastore」にしました。
エンティティはたった1つだけです(笑)

* Chips
    * プレイヤー4人の名前
    * プレイヤー4人のチップ数
    * キーとなるID
    * 作成日

GCPの要素は以下です。

* GAE
    * Python
        * Flask
* Datastore

以上！
初めてGAE、Datastore使ってみましたが、ドキュメント読みながらでなんとかなるもんですねー。
いやー、時代は進んでますね（笑)

詳しいことは、ソースを見てもらったほうが早いと思うので、Githubのリンクを張っておきます。

https://github.com/pon-wchoco/mahjang-chips

## 今後の展望
1. リファクタリング
    2. 急いで作ったので、コピペが多い
    3. ループですっきりする箇所がいくつもある
4. 試合結果のOCR
    5. 試合結果の点数が画像であるので、それをOCRしてテキストにしたい
って感じですー。

## 最後に
今、苦しく厳しい状況ですが、大なり小なり、ITのチカラで課題を自分なりに解決していけたらいいなぁ、って思っています。
自分ができることを考えて、世の中に発信していきたいと思います。

チップくん、よかったら使ってみてくださいねー！(^o^)/
ステイホームだけど、楽しく過ごしていただける一助になれば幸いです。

ではでは。

## 2021/06/09
チップ君が生まれ変わりました！！

https://www.chip-kun.ml/create/

以前のものは、良かれと思って作り込んだもの実際は使いづらかった。。。。

なので、一気にシンプルに作り直しました！！
よかったら使ってみた下さい！

目玉機能は

**チップのやりとり履歴が見れる！！**

です。
![chip01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/06d4ff1c-34ea-5840-1291-f2d72938f708.png)

![chip02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639318/9c9bf5a5-1b4d-b824-c5ed-69805f7f9b84.png)
SlaxのVirtualbox上のHDDインストール

#はじめに　
Lightweight LinuxのひとつであるSlaxをVirtualboxへインストールした。

###サイト
[本家サイト](https://www.slax.org/)からISOファイルをダウンロードする。

###Virtualboxでの起動
ライブCD（ISOファイル）を指定して起動。RAMは512MBとした。

###Virtaulboxでのあとしまつ
ライブCDを取り除く。

###Terminalでの作業
1. fdisk
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7276bffb-f814-0a01-c606-5487c9db3a8e.png)
PartitionにBootable flagをつける。

2. mkfs
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/565a5cc7-69c6-1d79-3636-ed8630f25031.png)

3. HDDにPathわりあて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/68ab0f62-2937-110e-d436-eae40958fd97.png)

4. SlaxのISOファイルをこのVM内にコピー
今回、別マシンからscpでもってきました。

5. SlaxのISOファイルのマウント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/cda7f2ae-9875-1860-a356-1740586f5923.png)

6. ファイルのHDDへのコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/8bf5de01-f904-7bf6-5d49-525234c397d2.png)

7. HDDブートの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f4945a1b-36ed-51eb-d3de-c0b9963ef034.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c85b2095-4c75-598f-b354-d8b4cbfc51f1.png)

8. Shutdown
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/887d5432-3974-8dae-e27c-eca38f056d54.png)

9. あとしまつ（ライブCDの除去）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fe920dac-d1e6-ff2c-d969-e6a5f1557825.png)

10. 起動
略。

###感想
たしかに軽い気がする。

###参考サイト
[Slax 9.6.3 VirtualBox Install](https://www.youtube.com/watch?v=Vec6EIXEs0A)
【Rails】directory for stderr_path=log/unicorn_stderr.log not writable (ArgumentError)

定期的に再起動しているDocker上のRailsコンテナが、稀に起動失敗する。
Dockerが原因かと思い色々調べたが、ごく簡単な理由でした。

# 原因
logディレクトリがgitignoreされていた。
unicornの起動にはパスまでのディレクトリが予め存在していないといけないため注意。

通常は`rake db:migrate`する際にlogディレクトリも生成されるためたまたま起動に成功していたが、
何らかの理由でスキップされるとunicornの実行時にコケる。

# 対処
`log/.keep`を作ってgitignoreを以下の様ににする。
(デフォルトでこれになっているはずなんだけど、何故か別の設定で上書きされていた)

```shell:.gitignore
/log/*
!/log/.keep
```

`.dockerignore`もある場合はlogディレクトリが消されていないか確認しておく。

ちゃんちゃん
20200517 進捗 APG4b参照前まで

#APG4b / C++
##オーバーロード
>「引数の型」または「引数の数」が異なる場合は、同じ名前の関数を定義することができます。これを関数のオーバーロードと言います。
次のプログラムでは「2つの引数を取るmy_min関数」と「3つの引数を取るmy_min関数」を定義しています。

```c++
#include <bits/stdc++.h>
using namespace std;

// 2つの引数のうち最も小さい値を返す
int my_min(int x, int y) {
  if (x < y) {
    return x;
  }
  else {
    return y;
  }
}

// 3つの引数のうち最も小さい値を返す
int my_min(int x, int y, int z) {
  if (x < y && x < z) {
    return x;
  }
  else if (y < x && y < z) {
    return y;
  }
  else {
    return z;
  }
}

int main() {
  int answer = my_min(10, 5); // 2つの引数
  cout << answer << endl; // 5

  answer = my_min(3, 2, 5); // 3つの引数
  cout << answer << endl; // 2
}


```
##コンテナ
>範囲for文はコンテナと呼ばれるデータ型に対して使うことができる。
配列の要素に対する処理ではなく、具体的に何回処理を繰り返せば良いのかということも分からない。
→この処理にはwhile文が適している。

| 内容      |   間違い    |    正解    |
|:-----------------|------------------:|:------------------:|
| 配列             |              scores.a[i] |        scores.a(i)        |
ServerlessFrameworkでAPIGatewayのログを確認する

### APIGatewayのログ確認方法

まず、CloudWatchのログを有効化する
(providerの配下にlogsを追加)

```serverless.yml
service: lambda-demo

provider:
  name: aws
  runtime: python3.8
  region: ap-northeast-1
  stage: ${opt:stage, 'dev'}
  logs:
    restApi:
      role: !Join
              - ''
              - - 'arn:aws:iam::'
                - !Ref "AWS::AccountId"
                - ':role/★★★'  
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /
          method: get
          integration: lambda

resources:
  Outputs:
    ApiGatewayRestApiLOGTailCommand:
      Value: !Join
              - ''
              - - 'aws logs tail --follow  API-Gateway-Execution-Logs_'
                - !Ref ApiGatewayRestApi
                - '/${self:provider.stage}'

```

★★★にはAmazonAPIGatewayPushToCloudWatchLogsのポリシーが付与されたロール名を設定する

以下のIAM画面を参考にしてください。自分でロールを作成する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191895/0fae8f7d-d0f6-a87f-a3b3-eae486b9dbaf.png)


### デプロイしてoutputsを確認

```bash
$ sls info -v

Stack Outputs
ApiGatewayRestApiLOGTailCommand: aws logs tail --follow  API-Gateway-Execution-Logs_m32jkcrrq6/dev

# m32jkcrrq6はAPIGatewayのID
```

awscli2.0以上で`aws logs tail --follow  API-Gateway-Execution-Logs_m32jkcrrq6/dev`するとAPIGatewayのログがtailされる
HomesteadのBoxインストールエラー対策（Windows + Vagrant アップデート手順）

# 環境
OS：Windows10 Pro
Vagrant：2.2.4

## １．背景
Laravel5.x系の環境を利用していたが、laravel6.x系をインストールするのに、Homesteadを新しくしようとしたら、BOXのインストールエラーが出てしまったので、その時の対応メモ

```cmd
$ vagrant box add laravel/homestead
    homestead: Calculating and comparing box checksum...
The specified checksum type is not supported by Vagrant: sha512.
Vagrant supports the following checksum types:

md5, sha1, sha256
```

## ２．対応
どうやらVagrant2.2.6からはCheckSumのサポートが変わった模様。Vagrantを2.2.9(2020.05 最新)にアップデートする。
VagrantのWindowsインストーラーを使ってアップデート（インストールすると、古いバージョン情報もクリーンしてくれるので、手動クリーニング作業などは不要でした）

・Vagrantのインストーラー
https://www.vagrantup.com/downloads.html

```cmd
C:\Users>vagrant -v
Vagrant 2.2.9
```
以前のバージョンで利用していたローカルLaravel5.8系のサイトもVagrant upで起動・確認し影響ないことを確認。


再度実行

```cmd
C:\Users\murat>vagrant box add laravel/homestead
==> box: Loading metadata for box 'laravel/homestead'
    box: URL: https://vagrantcloud.com/laravel/homestead
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) hyperv
2) parallels
3) virtualbox
4) vmware_desktop

Enter your choice: 3
==> box: Adding box 'laravel/homestead' (v9.5.1) for provider: virtualbox
    box: Downloading: https://vagrantcloud.com/laravel/boxes/homestead/versions/9.5.1/providers/virtualbox.box
Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
    box:
    box: Calculating and comparing box checksum...
==> box: Successfully added box 'laravel/homestead' (v9.5.1) for 'virtualbox'!
```

HomeStead + Vagrantで仮想サーバ起動してブラウザ経由でPHPファイル表示できたので、とりあえずここまで。
Rails Docker 環境構築

#前提
railsでDockerの環境構築をした時の備忘録。
Docker for macインストール済み

#本題

```
rails
|--Dockerfile
|--Gemfile
|--Gemfile.lock
|--docker-compose.yml
```


```Dockerfile.
FROM ruby:2.4.5
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```
DockerfileをbuildしDocker Image（コンテナ仮想環境の雛形が作成される）

```Gemfile.
source 'https://rubygems.org'
gem 'rails', '5.0.0.1'
```
Gemfile（Installしたいgemを定義）→bundle installコマンド実行→gemがインストールされる→InstallしたgemがGemfile.lockに記載される


```docker-compose.yml
version: '3'
services:
  web:    #Railsコンテナの定義
    build:  .  #Dockerfileを元にイメージを作成し使用すること
    command: bundle exec rails s -p 3000 -b '0.0.0.0'  #Rails起動のコマンド
    volumes:
      - .:/app
    ports:
      - 3000:3000  #<公開するポート番号>:<コンテナ内部の転送先ポート番号>
    depends_on:
      - db  #Railsが起動する前にMySQLサーバーが先に起動するように設定
    tty: true
    stdin_open: true
  db:    #MySQLサーバーコンテナの定義
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:  #この定義によりPC上にdb-volumeという名前でボリューム（データ保持領域）が作成される
```

上記設定が終わったらターミナルにてRailsプロジェクトの作成

```terminal.
rails$ docker-compose run web rails new . --force --database=mysql
```
<code>docker-compose run web</code>でwebサービスのコンテナで後ろのコマンドを実行するコマンド

<code>--force</code>は、既存ファイルを上書きするオプション
<code>--databace=mysql</code>はMySQLを使用する設定を入れるオプション

buildが完了したら、Railsで使用するデーターベースファイルを編集

```config/database.yml
#省略

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: password  #編集
  host: db  #編集

#省略
```

設定が完了したら下記のコマンドをターミナルに入力

```terminal.
rails$ docker-compose up -d
```
上記は、現在のディレクトリにあるdocker-compose.ymlに基づいてコンテナ（仮想環境）を起動するコマンド


続いて、開発環境用のデータベースが作成されていないため、下記コマンドで作成

```terminal.
rails$ docker-compose run web bundle exec rake db:create
```
<code>bundle exec rake</code>の部分は、Rails環境にインストールされているrakeコマンドを実行している
<code>rake db:create</code>でRailsで使用するデータベースをMySQLサーバー上に作成してくれる


ブラウザでlocalhost:3000と入力しRailsの画面が出てきたら完了！
【Ruby on Rails】NoMethodError undefined method `devise_for'のエラー解消

# NoMethodError undefined method `devise_for'...のエラーの対処方法
実装が完了したあとにブラウザを更新して内容を確かめようとしたときにこのようなエラーがでてしまいました...
<img width="876" alt="スクリーンショット 2020-05-17 21.05.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/4e628eac-1567-e00a-1bb9-29f7ed4d1fd5.png">
打ち間違えを確認しても問題がないのにどうしてエラーになったんだろう...と思った方は**サーバーをもう一度立ち上げ直す**ことで解消されます！簡単なエラーです^_^
phpの「=>」（ダブルアロー演算子）と「->」（アロー演算子）

#「=>」:ダブルアロー演算子

連想配列のこの「キー」にこの「値」を入れますよー
というのを表すための演算子。

phpの
ダブルアローがわからなければこれを読むんだ！！

http://raichel.hatenablog.com/entry/2015/01/15/012116


#「->」:アロー演算子

インスタンスの持つ、プロパティにアクセスするための演算子。

この記事で私は理解した。

https://techacademy.jp/magazine/19296


インスタンスは「クラスを実体化したもの」。
インスタンスがわからないときには、オブジェクト指向を学ぼう。
Dockerfileのdebug

## Dockerfile の debug

```bash
# docker startが終わったcontainerを確認
$ docker ps -a

# 対象のCONTAINER IDをコピーする

# containerを一時的にimage化する
$ docker commit <container-id> builddebug

# image化したdockerをdocker runする
$ docker run --rm -it builddebug /bin/bash

# これでdocker buildで失敗した時点のコンテナに入る事ができる
```
graphviz をポータブルな python 環境に導入する


# はじめに

graphviz は scikit-learn でも使用されている、
グラフ（木）描画用のライブラリです。

https://www.graphviz.org/

このgraphvizを導入せずにライブラリを使用してしまうと、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/5527318c-2ce9-1b12-d5cd-b8ad034f36eb.png)

```
FileNotFoundError: [WinError 2] 指定されたファイルが見つかりません。
```

アバー

```
graphviz.backend.ExecutableNotFound: failed to execute ['dot', '-Tpng', '-O', 'binary_tree'], make sure the Graphviz executables are on your systems' PATH
```

`graphviz` 内の `dot.exe` が見つからなくて怒られます。

というわけで、今回はgraphvizを導入していくわけですが、
タグを見ればわかる通り、今回もWinPythonを用いてポータブルに導入します。

# インストール手順

今回の手順は
- Windows 10 Pro 64bit
- WinPython 3.8.10

で実施します。

## graphvizのダウンロード

Windows用のダウンロードページが用意されています。

https://graphviz.gitlab.io/_pages/Download/Download_windows.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/91729752-a61c-6737-31f0-a64e9793c8b9.png)

何も考えずにインストールするのであれば、「graphviz-2.38.msi」のインストーラ形式を選べばよいのですが、
私はインストーラを使用してシステムを汚すのが嫌なので、
ポータブルに導入すべく、 **「graphviz-2.38.zip」** をダウンロードしました。

## graphvizのインストール

まずは先程ダウンロードした graphviz-2.38.zip を WinPython展開先の `t` フォルダに展開します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/28e85ca9-f6e0-2c40-e2e8-56c621a17384.png)

展開した中を見ると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/66d96b62-db23-277c-11ab-78ccdce619c5.png)

`dot.exe` がある！

ということで、このフォルダをPATHに追加していきます。
んですが、何度も言うようにシステムを汚してしまうので、WinPythonを実行するときだけPATHが通るようにします。

そういうときに使うのが、
`{winpythonInstallDir}\setttings\winpython.ini` ファイルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/ff984f87-a3b6-1e1b-1ffe-d5258c103ea9.png)

ここにPATHを追加していきます。
追加するPATHは `{winpythonInstallDir}\t\graphviz-2.38\release\bin\` ですが、
WinPythonを展開したフォルダのパスは環境変数`WINPYDIRBASE` に格納されるので、
`D:\Applications\WPy64-3810\t\graphviz-2.38\release\bin\` を追加するためには下記のように記載します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/f4200f08-bfca-bda5-afdf-3dbbca68c91f.png)

ここで、`WINPYDIRBASE` を使用せずにPATHを追加してしまうと、WinPythonフォルダを移動したときに使えなくなるので注意が必要です。
（USBメモリに入れて環境を持ち運んだりするとドライブレター変わってしまったりするので。）

## 動作確認

では、先程問題になった `dot.exe` が使用できるかチェックしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/a41dbc24-5b09-a02e-bf50-6d61041cd12b.png)

`WinPython Command Prompt.exe` をダブルクリックして、 `dot -v` コマンドを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/d83d21c4-9a37-216d-ab5b-5a9bb7d12b37.png)

いいぞ。

## Jupyterでも使えます

こちらの記事を参考に、graphvizを試してみました↓

https://qiita.com/msuz/items/bd41a8fe67fd56707116

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328319/391971dc-293e-bd21-0f13-753a059438e6.png)


# おわりに

WinPython、一番好きなPythonディストリビューションです！
Trimble CFX等の12pinコネクタ周りのメモ

##Trimble CFX等の12pinコネクタ周りのメモ

##ピンアサインとかケーブルカラー
https://talk.newagtalk.com/forums/thread-view.asp?tid=764687&DisplayType=flat&setCookie=1

##Digikeyのパーツ番号

DTM06-12SC
1734-1068-ND
CONN PLUG HSG 12POS

DTM06-12SA
1734-1066-ND
CONN PLUG HSG 12POS

WM-12S
1734-1044-ND
DT, DTM WEDGELOCK

0462-201-20141
1734-1332-ND
CONN SOCKET 20AWG NICKEL CRIMP
・20AWGだとこれがピッタリでした。

##応用例
・10,11でフットスイッチ
https://thefarmingforum.co.uk/index.php?threads/trimble-gfx-750-foot-switch.302701/

・3,4,5でRTCMの補正データ
BERTを30分ぐらいでちょっと経験してみる。

#目的
BERTを、ちょっと、動かしてみたいと思い、
ぐぐって、一瞬で動きそうな例を試してみた。

#選んだ例

以下のサイトで、
https://www.ai-shift.jp/techblog/281

BERTを使って、**TOEICのPart 5の問題を解く**、例が示されていた。
30行程度のコードだったので、これを動かしてみた。

#問題の作成

穴埋め問題として、
Pythonの英語の入門書
「introducing Python」 O'Reilly Media,Inc (First Edition 2016-02-26 Third release)
の文章を引用し、1文に対して、穴を一個開けてみた。

textが1個穴の開いた（*が穴）文章。
candidateが穴埋めの候補。5個程度。

以下、3問作ってみた。

```
text = "In Python, a lambda function is an anonymous function * as a single statement."
candidate = ["experssion", "used", "expressed", "using", "known"]
```

```
text = "Truncating integer division * you an integer answer."
candidate = ["gives", "makes", "presents", "takes", "give"]
```

```
text = "What * you get if you typed the following?"
candidate = ["did", "will", "would", "do", "are"]
```

1問追加。これは、Pythonの入門書ではなくて、tensorflow lite?か何かの
実行時のエラーメッセージ。

```
text = "Model provided has model identifier 'TFL2', * be 'TFL3'"
candidate = ["can", "could", "would", "shall", "should"]
```

#結果発表！
以下のとおり、**全問正解**。

```
(3, 'expressed')
(0, 'gives')
(0, 'would')
(0, 'should')
```

#まとめ
BERTのレベルの高さを感じた。
正解以外の候補は、ワタシが考えたが、ちょっと、BERTとの力の差がありました。。。（日本語で再度トライするか、別の問題を考えたいと思います。
雑談ですが、shouldとかwouldとか、とっても、簡単なんでしょうね。。。）
コメントなどあれば、お願いします。


#追記(2021/2/14)
以下の記事を書いた

[BERTとワタシで、論文『Attention Is All You Need』に対する読解力を、競ってみた(全20問）。](https://qiita.com/enoughspacefor/items/12640c58646eea2f516d)
Let's Encrypt 証明書更新

# 証明書確認
```
sudo certbot certificates
```

# 証明書更新
```
sudo certbot renew
```
以下のようなエラーが発生する場合は、80番ポートが利用されていて更新できないためWebサーバを停止する必要がある。
```
Problem binding to port 80: Could not bind to IPv4 or IPv6.
```
停止・スタートコマンド
```
sudo systemctl stop httpd
```
```
sudo systemctl start httpd
```
LaravelでJSONリクエストを受け取る

# 目次
Laravelの記事一覧は下記
[PHPフレームワークLaravelの使い方](https://qiita.com/toontoon/items/c4d0371e504c37f6576e)

# Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています

# 前提条件
[eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)](https://qiita.com/toontoon/items/76fa7f8845b20776077c)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

# Controllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにrequestJson1メソッド、requestJson2メソッドを追記

```
    public function requestJson1(Request $request)
    {
        return view('sample.requestJson');
    }

    public function requestJson2(Request $request)
    {
        $data = [
            'a' => $request->input('a'),
            'b' => $request->input('b.bb'),
            'c' => $request->input('c')['cc']
        ];
        return $data;
    }

```

(2) /sample/routes/web.phpに下記を追記
`Route::get('sample/request-json1', 'SampleController@requestJson1');
Route::post('sample/request-json2', 'SampleController@requestJson2');`


# viewの作成
/sample/resources/views/sample/requestJson.blade.phpファイル作成

```requestJson.blade.php
<html>
    <head>
        <title>sample</title>
        <script type="text/javascript">
            function ajax(){

            	var form = document.getElementById("sampleForm");

            	var reqData = {"_token": null, "a": null, "b": {"bb": null}, "c": {"cc": null}};
            	reqData._token = form._token.value;
            	reqData.a = form.a.value;
            	reqData.b.bb = form.b.value;
            	reqData.c.cc = form.c.value;

            	var req = new XMLHttpRequest();
            	req.open(form.method, form.action);
            	req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
            	req.responseType = 'json';
            	req.send(JSON.stringify(reqData));
            	req.onload = function () {
            		var json = req.response;
            		alert("a:" + json['a']  + "\n" + "b.bb:" + json['b']+ "\n" + "c.cc:" + json['c']);
            	}
            }
        </script>
    </head>
    <body>

        <form id="sampleForm" action="{{ url('sample/request-json2') }}" method="post"  onsubmit="ajax(); return false;">
            @csrf
            <input type="text" name="a" >
            <input type="text" name="b" >
            <input type="text" name="c" >
            <input type="submit" >
        </form>

    </body>
</html>

```

Laravelでjsonリクエストを受け取るようにするために
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
を書きました
LaravelのControllerクラスはjsonを受け取るからと言って特別な記載は要りません
Content-Typeヘッダプロパティにapplication/jsonが指定されていれば、inputメソッドで値を取得できます

# 動作確認
`http://localhost/laravelSample/sample/request-json1`

インプットフォームに値を適当に入力して送信ボタンをクリック
インプットフォームに入力した値がalertで表示された
laradock環境下のmysqlで文字化けしちゃった

#はじめに
laradockで環境構築を行ってからseederでデータ投入。
その後にmysqlコンテナに入り、データが入っているか確認すると英語や数字は問題なく表示された。が、
日本語のデータが文字化けしていた。
それを解決するのにハマってしまったので、備忘録としてこの記事を書きたいと思う。
#原因
mysqlにて`status`コマンドで文字コードを確認。
```Server characterset:	utf8
Db     characterset:	utf8
Client characterset:	latin1
Conn.  characterset:	latin1```

上記にあるように
```Client characterset:	latin1
Conn.  characterset:	latin1```

ClientとConnの文字コードがlatin1になってたのが原因だとわかった。
#解決策
latin1をutf8にするためにlaradock/mysql/my.cnfに下記を追加した。
```character-set-server=utf8
[client]
default-character-set=utf8
```
それから
```docker-compose stop mysql
docker-compose down build mysql
docker-compose up -d mysql```
でmysqlコンテナを再起動すると解決した。
#参考サイト
https://qiita.com/luccafort/items/0553c589dcc6459746bc
第3回Flutterもくもく会@Zoom 実施レポート

# はじめに 

2020年5月17日にZoomにて[Flutterもくもく会](https://flutter-okurayama.connpass.com/event/175366/)を実施したので、
そのレポートになります。個人的所感メインです。
何かご意見などありましたらよろしくお願いします。


もし良ければ過去のものもご覧ください。

* [第１回](https://qiita.com/glassmonkey/items/7dd8cf2037e17c5131f8)
* [第２回](https://qiita.com/glassmonkey/items/9ed36f0e8f27952c7c6d)


# トピック

## Dartの難易度について
今回Flutterを初めて触るって方もいらっしゃってましたので、Dartの難易度について話題にあがりました。
基本的には癖のない言語ですが、個人的には下記の２点ぐらいは調べた覚えがありました。

* [名前つきコンストラクタ](https://dart.dev/guides/language/language-tour#named-constructors)  
名前をつけて、より特殊なコンストラクタを作ることが可能。イミュータブルなオブジェクトを作るときに個人的に重宝してます。

```dart
class Point {
  num x, y;

  Point(this.x, this.y);

  // Named constructor
  Point.origin() {
    x = 0;
    y = 0;
  }
}
```


* [カスケード表記] (https://dart.dev/guides/language/language-tour#cascade-notation-)  
 メソッドチェーンで書けるようになる `..` のこと

```dart

querySelector('#confirm') // Get an object.
  ..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));
```


細かい文法は[dart pad](https://dartpad.dev/)で学んで、Lint(静的解析)を動かすようにして極力調べるコストを下げるのがいいかなという結論になりました。(参考: [Lint参考記事](https://medium.com/flutter-jp/analysis-b8dbb19d3978) )

[第１回](https://qiita.com/glassmonkey/items/7dd8cf2037e17c5131f8)のときにも触れましたが、設定ファイルは現状は下記のFlutter公式のものを私は使っております。
https://github.com/flutter/flutter/blob/master/analysis_options.yaml

※また、超絶手抜きですが、現在、Lintを下記のシェル経由でCI上で動かす運用をしてたりしてます。
もしよければご利用ください。warningのときにステータスコードが0で返ってくるのでこのようなものを用意しました。

```bash
#!/bin/bash

RESULT=$(dartanalyzer --options analysis_options.yaml . | wc -l)
# エラー表示がない場合の最低行数が２行なので
if [ "$RESULT" -eq  2 ]; then
  echo "Not Exist Lint Error"
  exit 0
fi
echo "Exist Lint Error"
exit 1
```

## 勉強方法について
改めて、今日初めて触る方もいらっしゃいましたので、各自学習方法が様々だったので意見交換も行いました。
動画がやはり優しそう。個人的にはgithubの既存コードをがちゃがちゃしてますｗ

*  コードラボでトレーニング
https://flutter.dev/docs/codelabs

*  Flutter galallyでウィジェットと仲良くなる
https://github.com/flutter/gallery

* KBOY氏のFlutter大学 (勝手に名前を名前を出してしまってすみませんっ
https://www.youtube.com/channel/UCReuARgZI-BFjioA8KBpjsw

* ゼロからのFlutter】iOS/Androidアプリを"いっぺんに"開発入門・初級編＜みんプロ式＞
https://www.udemy.com/course/flutter-ios-android/

## Flutter Outline
エディタの話からAndroid Stdioの優位性としてFlutter Outlineなるものを教えてもらいました。
RowとかColumnとか手動であれこれやってたので、便利そうですね。いい感じにアイコンクリックすると挿入とかやってくれてレイアウト修正が格段にやりやすくなりました。
[公式](https://flutter.dev/docs/development/tools/devtools)をみると色々ツール拡充してそうなので、ウィジェット触るときは色々遊んでみようと思います。


（スクショは自分の開発中アプリのものです。）
![スクリーンショット 2020-05-17 20.26.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/b3b1da1e-68f2-c4c5-c81b-8e6cee149d17.png)


## その他
環境構築で困ってる方がいたので、画面共有しながら相談にのったりもしました。
こういうときにZoomだと便利ですね。`flutter doctor`に従って問題ないなら大丈夫だよって話をしたりもしました。


# おわりに次回開催と宣伝
こちらで定期的にもくもく会を隔週の頻度で実施予定です。次回は5月31日を予定しています。
LTなど発表したい方いましたら [@glassmonekey](https://twitter.com/glassmonekey)にご連絡いただけますと嬉しいです。

下記のコンパスも良ければ登録お願いします。これを機に一緒に始めましょう
https://flutter-okurayama.connpass.com/


# 感想というかメモ
開発中のアプリを主催者権限で画面共有で見せたりしちゃいましたｗ
モチベを保つための場とかにしていけるといいですね。
他の人のアプリの実装とか見たい。
虫の頭でcoffeescriptを理解しようとしてみる。クラス文メソッド作成

前のまとめ
虫クラスを生成して捕獲したオオカマキリを入れた

```coffeescript:musi.coffee
class 虫
  カマキリ:"カマキリだよ"
オオカマキリ=new 虫
```

今回
何匹捕まえたか出力したいのでメソッドを作る
メソッド「見つけた数」を作るため、クラス内に新しく記述
今回は引数に匹数を入れることで捕まえた数を出力してくれるようにする

```coffeescript:musi.coffee
class 虫
  見つけた数:(数)->
    console.log(数+"匹見つけた")
オオカマキリ=new 虫
```

オオカマキリさんにメソッド「見つけた数」をくっつけて()内に捕まえた数を代入し出力

```coffeescript:musi.coffee
オオカマキリ.見つけた数(1)
#1匹見つけた
```
PuttyのPageantを使って認証鍵による多段ssh時の秘密鍵をローカルのみで管理する方法

## 記事を書いた動機

AWS EC2からGitで認証鍵を用いたsshによるリモートへの操作をするときにssh-agentが必要だったのが発端です。
ssh接続時に使用しているPuttyで上手く対応したかったので調査・検証しました。

## 想定環境

- Windows
- Puttyがインストール済み
- 認証に使用する秘密鍵をppkに変換済み

※あまり環境依存する内容ではないのでMacでも変わらないかもしれないです
　筆者はWindowsでしか確認してません

## Puttyとは？

> PuTTY(パティ)とは、リモートログオンターミナルクライアントソフトです。

[オープンソースのPuTTYとは](https://www.ossnews.jp/oss_info/PuTTY)

## Pageantとは？

> PuTTYに付属のソフトウェアです。
これを使うと、サーバーへ接続するためのパスワード入力などの認証処理を、自動化することができます。

[PuTTY & WinSCP による快適SSH環境の構築法](https://tipszone.jp/20111205_putty-winscp/#Pageant)

## 今回やりたいこと

sshでサーバーに接続して、接続先のサーバーからさらに認証鍵によるssh接続をしたい場合があると思います。

例）踏み台サーバーからさらに別サーバーにssh接続する
　　Gitでsshを用いてサーバーにソースを反映させる

そういった場合の対応として一番安直な方法はサーバーに秘密鍵を配置することでしょう。
ただ、多くの場合サーバーには複数人でアクセスすることが想定され、不正なアクセスが行われるリスクへの考慮もしたいと思います。

そのような場合に、ローカルの秘密鍵を読み込んでおいてssh接続先でも使用したいということです。
Puttyを用いる場合にはPageantで実現できます。
このような手段は環境に合わせてPageant以外にもあります。

[SSH エージェントフォワードで多段ログインを実現](https://www.qoosky.io/techs/16ad375055)

## Pageantに秘密鍵を登録する

1. Puttyの実行ファイルが配置されているフォルダに`pageant.exe`があります。
この実行ファイルでPageantが起動します。
2. ダブルクリックして実行するとタスクトレイに常駐するので、右クリックでadd Keyを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/252223f4-17a6-dca4-412e-ce08b9bb7aed.png)

3. ファイルの選択画面が表示されるので登録したい秘密鍵(.ppk)を選択します。

4. タスクトレイのPageantアイコンを右クリックでView Keysを選択します。
選択した秘密鍵が登録されていることが分かると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/a46e1a1c-16fe-f32f-8b51-0c88e0c032f6.png)
![Pageantキャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/ee5cab44-07d3-5446-b694-762df42d22b5.png)

※pageantのプロセスの起動のたびに上記の登録が必要です

## 実際に多段ssh接続してみる

試したいサーバーにアクセスして別の接続先にssh接続してみてください。
なにも指定していなくても勝手に認証鍵が処理されるはずです。（Git等も同様）
ちなみにAWS EC2等では外部へssh接続する場合、ssh-agentを起動して接続のたびに認証鍵を登録する必要がありますが、この手順を用いれば不要になります。

## Pageantを自動起動させる

勝手には起動してくれません。
常用するのであればスタートアップに登録しましょう。

Windowsであれば`C:\Users\[ユーザー名]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`に`pageant.exe`のショートカットファイルを作成して配置すれば良いです。
また、起動時に自動で秘密鍵を読み込むこともできます。（下記参考）

[Pageantに秘密鍵をセットして自動起動する(Windows)](https://qiita.com/reflet/items/6d74851f033ddc325df9)
[自動的に複数の秘密鍵を読んでPageantを開始する方法](https://mistymagich.wordpress.com/2013/10/18/how-to-automatically-start-pageant-with-loading-private-key-files/)

## Pageantを用いれば絶対安全？？

絶対安全な手段はありません。
Pageantを用いた場合、接続元のPCメモリ上に秘密鍵が生で存在している状態になるため、不正なプログラムが実行されていれば参照される危険はあるようです。
ただし、サーバーに秘密鍵を配置するよりはるかに安全だと思います。

[pageant.exe の仕組みと危険性](http://tech.nitoyon.com/ja/blog/2008/01/07/pageant-security/)
laravel  ルーティング

#ルーティングとは

特定のアドレス（URL）にアクセスしたとき、どの処理を呼び出して実行するのか、を管理するもの。

たとえば、　以下のようなURLがあったとき、

https://domain.com/create
https://domain.com/search

ドメイン（domain.com）より後ろ側を見て
/createなら、登録の処理
/searchなら、検索の処理
というように処理します。

このURLを見て、「コントローラーのどのアクションにつなげるか」を指定しています。
つまり、ルーティングを見て、「どのコントローラのどの処理（メソッド）を呼び出すか」を指定しています。

ルーティングの指定は以下のようになります。

```php
Route::get('/create','TestsController@create');
Route::get('/search','TestsController@search');
```

get送信で、URLが「/create」のときは、　TestsController　の　create　アクションに通してね。
という意味です。searchも一緒。


#get送信

```php
Route::get('/hoge', 'HogeController@index');
```
【意味】
→「/hoge」パスにget送信でリクエストが来たら、HogeControllerのindexアクションへつなぐ（indexアクションの中で処理する）

という意味。


#名前つきルーティング

```php
Route::get('/hoge', 'HogeController@index')->name('hoge');
```

【使い所】
→コントローラやビューの中で URL を指定する時。

素のPHPではソースコードに直にパスを書いていた。
しかし、この方法だと、パスに変更があった時に、多くの箇所を変更する必要がある。
そこで、ルートに名前を付け、ルート名で URL を指定することで、この問題を解決できる。
toio.py でくるっと文字動画  #toio #おうちでロボット開発

# やったこと

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">くるっとtoio〜♪<br>開発者向けマットを白バックに<a href="https://twitter.com/hashtag/toio?src=hash&amp;ref_src=twsrc%5Etfw">#toio</a> <a href="https://twitter.com/hashtag/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E9%96%8B%E7%99%BA?src=hash&amp;ref_src=twsrc%5Etfw">#おうちでロボット開発</a> <a href="https://t.co/69BcmsuCMf">pic.twitter.com/69BcmsuCMf</a></p>&mdash; 水落 大 mizumasa (@_mizumasa) <a href="https://twitter.com/_mizumasa/status/1261970633350504449?ref_src=twsrc%5Etfw">May 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
toioの非公式ライブラリ toio.py に指定角度への回転コマンドを追加しました。

[非公式 Python ライブラリ(https://github.com/mizumasa/toio.py.git)](https://github.com/mizumasa/toio.py.git)


# できること

- スピードの指定(speed オプション)
- 回転方向の指定(clock オプション)
- 加減速の指定(ease オプション)

などの機能を盛り込んでいます

# サンプルコード
```
import toio                                                                               17 import random

def main():
    T = toio.TOIO()
    T.connect()
    for i in range(4):
        T.turn_to(i,int(360*random.random()))
    for i in range(4):
        T.turn_to(i,int(360*random.random()))
    for i in range(4):
        T.turn_to(i,90)
    T.disconnect()
    return

if __name__ == '__main__':
    main()
```

https://github.com/mizumasa/toio.py/blob/master/example_turn.py
不均衡データに対する対策

E資格対策でもないのですが気になったのでまとめます。


#不均衡データとは
正例と負例のデータ数が一方に（通常負例に）偏るデータを指します。


#どうしてだめなのか
モデルの良さを評価するAccuracyですが、不均衡度合いが大きいほど実際には使えなくなります。
例えば負例を1000個のうち900個正しく判別できるモデルがあったとします。
Accuracy(負例を負例と見抜く)は0.9でかなり良い性能に見えますが、分類モデルでは正例を正例と見抜く性能も必要になってきます。

つまりデータに偏りがあるデータで学習してしまうと悪いモデルができてしまったり、正しくモデルを評価できなくなってしまいます。

#対策



##ランダムアンダーサンプリング：多い方を減らす

多い方（負例）を減らす手法です。
例えば多い方からランダムサンプリングし、データ数を減らすやり方があります。

これにより不均衡の低減、データが大規模であれば処理コストの低減が見込めます。
ですが負例に含まれる有益な情報の損失、ランダム抽出時にデータが歪むデメリットがあります。


##ランダムオーバーサンプリング：少ない方を増やす
少ない方（正例）を増やす手法です。
例えばアノテーションや、少ない方のデータを重複して取り、データ数を増やすやり方があります。

これによりアンダーサンプルのような情報ロスがなく、不均衡を低減できます。
ですが過学習の危険性がデメリットとしてあります。


##SMOTE
少ない方（正例）を増やす手法です。
ランダムオーバーサンプリングと違う点はデータ(下図の黒点)の内分点でデータ(下図の赤点)を新たに作ります。。

![1_6UFpLFl59O9e3e38ffTXJQ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/ea0d2288-817f-1d76-7e7d-d38ffa924fee.png)

引用：http://precog.iiitd.edu.in/pubs/What_sets_Verified_Users_apart-WebSci19-Slides.pdf

過学習をある程度抑制できます。

以上の3つが対策となります。
関数(Swift)

##この記事について
プログラミングの勉強をしています。
勉強の過程で得た知識を、忘れないようまとめておくのと共に、誰かの助けになればと思います。

##関数の定義
関数の定義は

```
func 関数名(引数名1: データ型, 引数名2:　データ型, ...,) -> 返り値のデータ型　{

 　　　　　　　　　　　　　　　　関数の処理

    return 返り値
}
```
と行う。

例として、２つの少数の足し算を行い、少数の解が帰ってくる関数を定義する。
関数名を**add**, 引数を**x(Double型)**と**y(Double型)**として

```
func add(x: Double, y:　Double) -> Double　{
    return x + y
}
```

となる。
実際に使うと

```
let sum = add(x: 2.10, y: 6.12)
print("x + y = \(sum)")
```

で、出力は

```
x + y = 8.22
```

となる。
postsuper -d メールキューに滞留したメール削除

##-d queue_id

Delete one message with the named queue  ID  from  the  named  mail  queue(s)
(default: hold, incoming, active and deferred).

If  a  queue_id  of - is specified, the program reads queue IDs from standard input. 
For example, to delete all mail with exactly one recipient  user@example.com:

```
mailq | tail +2 | grep -v '^ *(' | awk  'BEGIN { RS = "" }
# $7=sender, $8=recipient1, $9=recipient2
{ if ($8 == "user@example.com" && $9 == "")
  print $1 }
' | tr -d '*!' | postsuper -d -
```

Specify  "-d  ALL"  to  remove  all  messages;  
for  example, specify "-d ALL deferred" to delete all mail in the deferred queue.  
As a safety measure, the word ALL must be specified in upper case.

Warning:  Postfix  queue IDs are reused (always with Postfix <= 2.8; and with
Postfix >= 2.9 when enable_long_queue_ids=no).  There is a very small  possibility  that  postsuper  deletes  the  wrong message file when it is executed while the Postfix mail system is delivering mail.

The scenario is as follows:

1)     The Postfix queue manager deletes the  message  that  postsuper(1)  is asked  to  delete, because Postfix is finished with the message (it is delivered, or it is returned to the sender).

2)     New mail arrives, and the new message is given the same  queue  ID  as the  message that postsuper(1) is supposed to delete.  The probability for reusing a deleted queue ID is about 1 in 2**15 (the number of different microsecond values that the system clock can distinguish within a second).

3)     postsuper(1) deletes the new message, instead of the old message  that it should have deleted.
MongeDP AOJ 2415 刺身

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2415#
##見た感じ
[前回](https://qiita.com/hidekikangeki/items/f81f29541ef749c27104)と同じように区間についての小問題を解けば溶けそうだと思って、以下の漸化式を愚直に計算しようとしたが、計算量が$O(N^3)~~N<=4000$なので、間に合わない。

```math
s[i][j]=\sum_{k=i}^j w_k　\\
dp[i][j]=\min_{i\leq l<j}(dp[i][l]+dp[l+1][j]+sum[i][j])
```
けんちょんさんのサイトでmonge という名前が出ていたので、調べてみたところ、monge性を満たすと$O(N^2)$でとけるらしい。
monge性の定義等は[この](https://topcoder-g-hatena-ne-jp.jag-icpc.org/spaghetti_source/20120915/1347668163.html)サイトが詳しくてわかりやすかった。
monge性によって、lの調べるべき範囲がnによって広がらなくなるみたい。
##解法
上の漸化式をとくのは変わらないが、探索の仕方を$|j-k|=i$としてこのiとjについてloopを回し、$K[i][j]=(dp[i][s]+dp[s+1][j]がminをとる最大のs)$として、記録していくことで、lの調べるべき範囲を狭めている。
##ソースコード
```c++
const int N_MAX=4002;
ll dp[N_MAX][N_MAX],n,s[N_MAX][N_MAX],k[N_MAX][N_MAX];

ll solve(){
    rep2(i,2,n){
        rep(j,n-i+1){
            s[j][j+i-1]=s[j][j+i-2]+s[j+i-1][j+i-1];
        }
    }
    rep(i,n){
        k[i][i]=i;
    }
    for(int i=2;i<=n;i++){
        rep(j,n-i+1){
            ll res=INF18,r;
            rep2(l,k[j][i+j-2],k[j+1][i+j-1]){
                if(res>dp[j][l]+dp[l+1][i+j-1]+s[j][i+j-1]){
                    res=dp[j][l]+dp[l+1][i+j-1]+s[j][i+j-1];
                    r=l;
                }
            }
            dp[j][i+j-1]=res;
            k[j][i+j-1]=r;
        }
    }
    return dp[0][n-1];
}

int main(){
    int i;
    //入力
    cin>>n;
    rep(i,n){
        cin>>s[i][i];
    }
    //処理
    ll ans=solve();
    //出力
    cout<<ans<<endl;
}
```
Dobot Magician Liteの紹介ページ

# Dobot社 Magician Liteの紹介ページ

大阪府立大学高専と共同研究をしている[株式会社GRIPS様](https://grips.co.jp/)から、待望の[DOBOT Magician Lite](https://www.dobot.cc/magician-lite.html)が届きました。
順次、動作させて、ここで紹介していきます。

# 各種紹介
## デモ２：ブロックのピッキング　[■動画](https://youtu.be/An60kk7dEYk)
こちらも制御要ソフトがなくてもピッキングのデモが動きました。同封されていたブロックを何度も左右に動かします。無限ループなのかと思いましたが、１０回ほど繰返して止まりました。
なお、動画には入っていませんが、電源を落とすと、ホームポジションに復帰してからシャットダウンされました。

## デモ１：書写　[■動画](https://youtu.be/CZDH593-3M4)
パソコン用の制御ソフトをダウンロードしなくてもDraw（書写）のデモが動きました。自分自身の外観を書いていきます。とても、健気な動きです。
注意：紙がずれてしまうので、文鎮を用意しました。

## 開封　[■動画](https://youtu.be/YFmGIAw35hA)
Dobot Magicianより少し小さなケースです。しっかりと収納されていて、とても充填率がいいです。
吸盤ハンド、３つ指ハンド、筆ペンハンドとカメラユニットが入っています。
せっかくなので、開封の様子を動画撮影してみました。

## 関連サイト
- [Dobot Magician Liteの購入方法](https://grips.co.jp/archives/596)
- [Dobot社のサイト](https://www.dobot.cc/)
- [かんたん!!マイコン教室のホームページ](https://qiita.com/tmdoi/items/61be444e1879912aa2a5)

## 更新履歴
- 2020.05.17 待望のDobot Magician Liteが届いたので、開封して、DEMO1とDEMO2をやってみた。
駆け出しエンジニアの機械学習メモ その２

#はじめに
「ゼロから作るDeep-Learning」の学習メモその2です。

#2層ニューラルネットワーク(4章)
* mnist.pyよりデータの読み込みを行う。正規化、one_hot配列化、データの1次元配列化を行う。

```java:train_neuralnet
# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True,flatten=True, one_hot_label=True)
```
* two_layer_net.pyより重みの初期化を行う。辞書型でparams{W1:,b1:,W2:,b2:}のkeyを生成。
print(network.params)で中身を見ることができる。

```java:train_neuralnet
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
```
* 各初期値の設定、60000枚の画像データを100枚ずつ処理していく。

```java:train_neuralnet
iters_num = 10000  # 繰り返しの回数を適宜設定する
train_size = x_train.shape[0] # 60000
batch_size = 100
learning_rate = 0.1

train_loss_list = []
train_acc_list = []
test_acc_list = []
# 1エポックあたりの繰り返し処理 60000 / 100
iter_per_epoch = max(train_size / batch_size, 1)
```
* 訓練データから無造作に一部のデータを取り出し学習を行う。ここでは60000枚のデータから100枚取り出す。
*  
```java:train_neuralnet
for i in range(iters_num): #10000
    # ミニバッチの取得
    batch_mask = np.random.choice(train_size, batch_size) # (100,)の形
    x_batch = x_train[batch_mask] # (100,784)の形
    t_batch = t_train[batch_mask] # (100,784)の形
    
    # 勾配の計算
    #grad = network.numerical_gradient(x_batch, t_batch)
    grad = network.gradient(x_batch, t_batch)
    
    # パラメータの更新
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]
    
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)

    # 600で1エポックのため条件を満たしたらデータの保存
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(x_train, t_train)
        test_acc = network.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))
```
* リストに保存していたデータを利用してグラフの描画を行う。

```java:
# グラフの描画
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list,'o', label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
```
*　描画結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624848/c8b8e30c-9af4-081a-f54b-d3d7388845f9.png)



# 参考
ゼロから作るDeep Learning