OmniAICreator/Qiita-1.07M huggingface dataset:
Kali Linuxのインストール楽に

[Kali Linuxのインストール for Mac](https://qiita.com/Yuki_BB3/items/3cd1a799672ee226dc78)
[Kali Linuxのインストール-つづき-](https://qiita.com/Yuki_BB3/items/9c81cf32c3e96afc1681)
これより、もっと楽にやる方法もあります。

![スクリーンショット 2021-08-20 17.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/a491dfec-4cb1-b710-3669-ba8597e67e15.png)

こっちからova形式のファイルを落としてくることで最初の設定不要で起動できます。

クレデンシャルは kali/kali

![スクリーンショット_2021-08-20_17_59_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/112c9978-75fc-8625-8199-33d361ecfb9e.png)

ツールーインポート

これでova形式ファイルを選択してImportする。

![スクリーンショット_2021-08-20_18_04_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/e4b2b463-06ae-397a-5f85-71ae25ea9e5c.png)

数分待てば追加されます。

![スクリーンショット 2021-08-20 18.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/c8bf4ba3-f26f-1060-ca2f-95e1ac70a3a5.png)

kali/kaliでログインが可能です。
kintone カスタマイズ　アクション機能の落とし穴

kintone のカスタマイズで、アクション機能を利用したときに、急に動作が遅くなったり、エラーになったりすることが無いだろうか？
私は、このアクション機能の落とし穴に何度もハマっている。

# 動作検証用アプリ

テーブルにいくつか項目を配置

![2021-08-20_17h28_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/37238be7-dc95-6275-0fea-e0c80e26704c.png)

## アクション機能で、レコードをそのままコピー

![2021-08-20_17h32_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7e65603c-d1a7-4076-bd43-9737708a4563.png)


# イベント動作検証用カスタマイズ
イベント発生時に console.log でイベントタイプを表示するだけ。

```test1.js
(function() {
  'use strict';
  const changeEvents = [
    'app.record.create.show','app.record.edit.show',
    'app.record.create.change.顧客ランク','app.record.edit.change.顧客ランク', // テーブル以外
    'app.record.create.change.Table','app.record.edit.change.Table',            // テーブル
    'app.record.create.change.サービス名1','app.record.edit.change.サービス名1', // テーブル項目
    'app.record.create.change.商品名1','app.record.edit.change.商品名1'           // テーブル項目
  ];
  kintone.events.on(changeEvents, function(event) {
    console.log('event', event.type);
    return event;
  });
})();
```

# アクション機能を使ったときのイベント発生順

![2021-08-20_17h34_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a761bf33-94b2-0b12-97a0-49746fc2267f.png)

※テーブル内項目のサービス名1 のイベントが 12回、商品名1 のイベントが 10回。
テーブル項目自体とテーブルに無い項目は、 change イベントの発生は無い。

普通に考えると、create.show イベントが発生後に、項目の値をいじったタイミングで、change イベントが発生すると思う。
***実際は、テーブル内項目の change イベントが先に発生し、それも値がセットされたテーブル行数分のイベントが発生する。***

たぶん、アクション機能のコピー処理を行うと change イベントが発生してしまう仕組み。
これで、create.show が先に発生する前提で、カスタマイズすると、思わぬエラーが発生するときがある。
行数が多いレコードで change イベントに重い処理を行うと、画面が操作できるまでしばらく待たされる。
テーブル行数が多ければ多いほど、遅くなっていく。

カスタマイズ済のものに、あとから change イベント処理を追加すると、この落とし穴にはまりやすい。
最近は、特によくはまる。物覚えが悪くなったせいか？



# 対策

change イベント処理の登録を、create.show イベント内で行うと、アクション機能時も余計な change イベント処理が発生しなくなります。
ただし、change イベント処理の登録は、一回だけするように制御しましょう。

```test2.js
(function() {
  'use strict';
  
  const changeEvents = [
    'app.record.create.change.顧客ランク','app.record.edit.change.顧客ランク',　// テーブル以外
    'app.record.create.change.Table','app.record.edit.change.Table',            // テーブル
    'app.record.create.change.サービス名1','app.record.edit.change.サービス名1',　// テーブル項目
    'app.record.create.change.商品名1','app.record.edit.change.商品名1'           // テーブル項目
  ];
  var changeEvents_flag = true;

  kintone.events.on(['app.record.create.show','app.record.edit.show'], function(event) {
    console.log('event', event.type);
    
    // changeEvents 登録
    if (changeEvents_flag) {
      changeEvents_flag = false;
      kintone.events.on(changeEvents, function(event) {
        console.log('event', event.type);
        return event;
      });
    }
    
    return event;
  });

})();
```

# 対策後のアクション機能を使ったときのイベント発生順

アクション機能でも create.show イベントだけの発生になりました。

![2021-08-20_17h52_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6bbbc467-f311-1ba5-ab6d-4aab87d25e83.png)

# あとがき

こんな対策がいらなくなるように、アクション機能時の change イベントは、やめてください。
Kali Linuxのインストール-つづき-

https://www.kali.org/docs/installation/hard-disk-install/
公式を参考に追っていきます。


VirtualBoxでKaliLinuxのインストールがスタートできる様になっているところからスタート
つまり、この続きから
[Kali Linuxのインストール for Mac](https://qiita.com/Yuki_BB3/items/3cd1a799672ee226dc78)


- Graphical install

を選択して始めます。

![スクリーンショット 2021-08-20 17.12.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/ea86b01a-f4fd-b1d2-2eb2-c40defcdc87f.png)
![スクリーンショット 2021-08-20 17.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/26fe84a6-1ff4-9916-e4c9-496769cb6be4.png)
![スクリーンショット 2021-08-20 17.13.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/8ca9df79-a100-5a86-7071-9e474fa4ae8f.png)

キーボードは環境に合わせて

![スクリーンショット 2021-08-20 17.14.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/ca9dc3a2-1512-4827-f1a8-f312c348aeaa.png)
![スクリーンショット 2021-08-20 17.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/7bf0e47f-87ff-8fdd-264b-eaba8be60bb3.png)

ドメイン部分はオプションと記載されていたので空白にしている。

![スクリーンショット 2021-08-20 17.14.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/386ce0b6-9ce3-d564-e4ac-27d0a6558505.png)
![スクリーンショット 2021-08-20 17.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/6380608a-5b09-a547-e3ad-150df89e70c3.png)
![スクリーンショット 2021-08-20 17.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/4009d4b2-20d0-29fa-038b-20ec8ad1b39b.png)

ID/P忘れないように。

![スクリーンショット 2021-08-20 17.16.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/17d01b05-8db0-65fc-e64d-c1148cbbd684.png)
![スクリーンショット 2021-08-20 17.16.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/3eaf19b4-6980-6ee8-50a0-607c3cf570ad.png)
![スクリーンショット 2021-08-20 17.17.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/6c7d89fe-185b-c992-1211-e94ae9c9e6d6.png)
![スクリーンショット 2021-08-20 17.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/d79c0fb1-4fc1-7829-579a-4982c081419d.png)
![スクリーンショット 2021-08-20 17.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/22e5359a-b304-1717-58c7-8633746cfd85.png)

基本的にディスクはdefault値で最後に`はい`に変更する

![スクリーンショット 2021-08-20 17.19.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/4e7d00bc-9e6b-b8bc-7195-31ae2d5db3fe.png)

![スクリーンショット 2021-08-20 17.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/c60f666a-45ea-3423-1597-7bd4ac221189.png)
![スクリーンショット 2021-08-20 17.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/4503429f-d756-7f0e-ac6e-e9592c833651.png)
![スクリーンショット 2021-08-20 17.49.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/655caff9-a2f9-6ac8-4668-5f4db557c8e4.png)

おつかれさまでした。一度仮想マシンを終了し、再度起動します。

![スクリーンショット 2021-08-20 17.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/bac4a509-8441-dfb6-72eb-62c500c021b4.png)

使えるようになりました。めでたしめでたし
LaravelにVue3を導入した際にブラウザ描画されないエラーの解消法（バンドラー使用）

#LaravelとVue３実装時につまずいた
Qiitaの記事にもなかった解消法だったので備忘録も兼ねて投稿いたします。

システム開発でLaravel＋Vue３で実装する事があった際に起こったエラーです。
Vue2のテスト時では接続できていたのに、
Vue3になるとVueを実装しているブラウザが何も表示されなくなるバグが起きました。

原因はここだった。

```main.js
import { createApp } from 'vue';
```

これを

```main.js
import { createApp } from 'vue/dist/vue.esm-bundler.js';
```

こうで解決。

vue.esm-bundler.jsから直接createAppを読み込む必要があったようです。
公式にも注意書きがありました。

https://v3.ja.vuejs.org/guide/installation.html#%E3%83%8F%E3%82%99%E3%83%B3%E3%83%88%E3%82%99%E3%83%A9%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88

![スクリーンショット 2021-08-20 17.46.29（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542241/abb86bf5-4039-d80f-9ec3-2782592ae49a.png)

公式にだいたい乗ってますね。
良いVueライフを！！！
Laravelで愛犬のお世話記録アプリを作るまで(2)【開発環境】

# はじめに
我が家の愛犬の世話は、家族で分担しています。
家族間で情報を共有し、愛犬の体調管理をスムーズにするために、散歩や餌の時間・量、排泄の回数などの記録（以下、お世話記録とする）を手軽に行えるアプリを作りたいと思います。

# バックナンバー
[(1)【構想】](https://qiita.com/ddrpg2ki/items/394888946e2bd6fbbdab)
(2)【開発環境】　＜　**今回はここ**

# 開発環境
|   | 名前  | バージョン  |
|:---------------|:--------------------|:---|
| OS 　　　　　　 | Windows 10 Home 　 | 随時更新 |
| エディタ　　　  | Visual Studio Code | 1.59.1 |
| 言語 　　　　　 | PHP 　　　　　　　 | 8.0.9 |
| フレームワーク  | Laravel 　　　　　 | 8.55.0 |
| 開発環境  　　　| XAMPP　　　　　　　 | 8.0.9 |
| その他　 　　　 | Docker　　　　　　 | 20.10.8 |

:::note info
2021/8/20追記
どうもDockerはXAMPPと併用するものではないらしいということが分かってきました。もう少し勉強してから修正したいと思います。
:::

# 参考URL

https://biz.addisteria.com/laravel_basic2/

https://dotinstall.com/lessons/basic_dockerdesktop_win

:::note warn
情報が古い場合があります。
:::

今回は以上です。
[Material UI]CardActionAreaとCardActionの違い

CardActionAreaとCardActionAreaの違いが公式ドキュメントでは分からなかったので生成されるHTML単位で違いを比較してみた。

CardActionArea
https://material-ui.com/api/card-action-area/

CardAction
https://material-ui.com/api/card-actions/

今回比較するコードは以下の２つ。
~~Cardが入っているけど今更変更するもの面倒なのでこのまま続けます~~

```tsx:card.tsx
<Card>
  <CardActionArea>カードアクションエリア</CardActionArea>
  <CardActions>カードアクション</CardActions>
</Card>
```

生成されたのが以下のコード

```html:card.html
<div class="MuiPaper-root MuiCard-root MuiPaper-elevation1 MuiPaper-rounded">
  <button class="MuiButtonBase-root MuiCardActionArea-root" tabindex="0" type="button">
    カードアクションエリア
    <span class="MuiCardActionArea-focusHighlight"></span>
    <span class="MuiTouchRipple-root"></span>
  </button>
  <div class="MuiCardActions-root MuiCardActions-spacing">
    カードアクション
  </div>
</div>
```

CardActionAreaにはcssが適用されていないがCardActionには```flex```が適用されていた。

```css:card.css
.MuiCardActions-root {
　　display: flex;
　　padding: 8px;
　　align-items: center;
}
```

## 使い分
**CardActionArea**
CardActionAreaは単体としてイベントを登録する。

**CardAction**
CardActionはButtonを複数用意するなど子要素で自由にカスタマイズ可能。

以上。
facebook Graph API を使ってworkplaceにメッセージを通知する

業務案件で、facebook Graph API を使ってworkplaceにメッセージを通知する事があったのでメモ。
※ちなみに送信できるメッセージは2000文字です。

``` python
import requests

def _send_message_workplace(message: str):
    """
    workplaceにメッセージを送信
    """
    # メッセージの上限を超えた部分は削除して送信する
    if len(message) > 2000:
        warn_msg = 'message is omitted to first 2000 characters.'
        print(warn_msg)
        message = message[:2000]

    # アクセストークンを事前に生成しておく必要がある
    token = 'xxxxxxxxx'
    
    # 通知先のグループチャットのID
    thread_key = 't_xxxxxxxxxxxxxxx'

    headers = {
        'Content-type': 'application/json',
        'Authorization': 'Bearer ' + token
    }

    data = {
        "recipient": {
            "thread_key": thread_key
        },
        "message": {
            "text": message
        }
    }

    post_url = 'https://graph.facebook.com/v10.0/me/messages'

    print("sending message...")
    response = requests.post(post_url, headers=headers, json=data)
```

参考
https://developers.facebook.com/docs/graph-api/
Rubyにおけるインデントについて

これまでインデントについてあまり考えたことがなかったのですが、今回その機会があったので**Rubyにおけるインデント**について書いていきます。

##インデントとは？
>インデントとはコードを読みやすくするための空白。字下げをするという意味。

##インデントの種類
一般的にインデントは3種類が様々な言語でに用いられています。
>● タブインデント　
● 半角スペース2インデント
●半角スペース4インデント
※今回Rubyでは公式な規定はありませんが、例えばGo言語ではインデントはタブじゃないとそもそもコンパイルできないそうです。

#どれを使えばいいのか？➡半角スペース2文字のインデントを用いる
Rubyには正式なコーディング規約はありませんが、有志が作ったコーディング規約があります。この目的としては可読性（コードの読みやすさ）を保つためです([Ruby Assosiation](https://www.ruby.or.jp/ja/tech/development/ruby/050_coding_rule.html))。
ここで紹介されている５つではいづれも半角スペース2文字のインデントを用いるように書いてあります。

##VSCodeで半角スペース2文字のインデントをTabを用いて挿入する
とはいえ実際にコードを書くている中、毎回インデントの時にスペースを2回押すのは面倒くさいです。なので、Tabキーを用いてこれを実現する方法を紹介したいと思います。

まず初めに**設定画面の検索バーでtabを検索**します。するとこれが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644130/58267628-c3eb-15ba-c639-86c1e44634cb.png)
このチェックボックスにチェックを入れるとtabキーを入力するとスペースが入力できます。
しかしこれだけだとtabを入力したときのスペースのが4になってしまうのでそれを変える必要があります。
次に先ほどの**チェックボックスの右側の青文字「Editor: Detect Indentation」をクリック**します。すると下の画面が現れるので、「Editor: Tab Size」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644130/90c237b9-537b-3845-45ac-dc4fd4449411.png)
クリックするとすぐ下に入力する場所が出てくるのでそこに2を入れて完了です！

#VSCodeでTabを押してもTabだかSpaceだかわからない場合
エディタ画面でどちらかわからない場合は設定画面でwhitespaceと検索しましょう。
この画面が出てきたら、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644130/c28d9d47-e5e8-0c04-3161-570b13219ac6.png)
allを選択すると、スペースが点々、タブは矢印で表示されます。
Elastic BeanstalkにTypescript＋Expressのアプリをデプロイ

AWS Elastic Beanstalk（以下EB）を使ってNode.jsアプリをデプロイしようとしてつまづいたので、備忘録として残しておく。

# アプリケーションの概要

* Typescript＋Expressで書かれたNode.jsアプリケーション。
* ローカルでは`ts-node`を使って起動している。

# デプロイしようとして失敗

[EBのドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_nodejs.container.html)には

> Procfile を指定しない場合、package.json ファイルを指定すると Elastic Beanstalk は npm start を実行します。これを指定しない場合、Elastic Beanstalk は app.js または server.js をこの順序で探し、実行します。

と記載されていたので、特に何もしなくても`npm start`が実行されて、`ts-node`でサーバが起動すると思っていた。

が、実際デプロイしてみるとヘルスは「低下」、アクセスしてみると502 Bad Gateway。
ログを見ても特にエラー内容が見当たらず、なぜ動作していないのかがよく分からなかった。

# 参考になりそうな記事を発見

似たような事例がないかを探していたところ、参考になりそうな記事を発見した。
[Deploying a TypeScript, ExpressJS app into ElasticBeanstalk NodeJS server \| by Viet Hoang Le \| Medium](https://medium.com/@lhviet88/deploy-a-typescript-expressjs-into-elasticbeanstalk-nodejs-server-8381e00e7e52)

要約すると、`.ebextensions`を使って起動前にtsファイルをコンパイルすると良いとのこと。

# .ebextensionsとProcfileを追加

### .ebextensions

記事に書かれているとおりに`.ebextensions/source_compile.config`を追加した。
ただし、そのままだと`node_modules`内の`tsc`を実行するところでエラーになってしまったので、下記のように修正した。（指定の場所にtscがあるのは確認済み。原因不明。）

```yaml:.ebextensions/source_compile.config
container_commands:
  compile:
    command: "tsc -p tsconfig.json"
    env:
      PATH: /opt/elasticbeanstalk/node-install/node-v14.17.3-linux-x64/bin/
```

`/opt/elasticbeanstalk/node-install/node-v14.17.3-linux-x64/bin/`下のtscを使ってコンパイルを行うようにしたが、デフォルトの状態ではtscがインストールされていない。
EBによって立ち上がっているEC2にsshで接続し、`npm install -g typescript`を実行する必要がある。


### Procfile

前述のとおり、`package.json`には`npm start`で`ts-node`を実行するように書いているので、`Procfile`を追加しEBでは`node`を実行するようにした。

```:Procfile
web: node app.js
```

コンパイルしたファイルを実行するように記述するだけ。


これでデプロイしてサーバが動作するようになった。

# 余談

環境変数をマネジメントコンソールや`.ebextensions`で指定したのに、sshで接続して`export`コマンドや`env`コマンドで確認しても全然反映されなくて困ったけど、そういうものだった。（実際特に問題なく動作していた。）

[Elastic Beanstalk 環境から Linux および Windows インスタンスに変数を渡す](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elastic-beanstalk-pass-variables/)

> PHP を実行するスタック以外では、環境プロパティがインスタンスに存在していたとしても、それらがシェルに自動的にエクスポートされることはありません。その代わりに、環境プロパティは、使用されているプラットフォームに基づいて、アプリケーションが実行されているスタックを通じてアプリケーションに提供されます。
mimemagicのインストール エラーと格闘した軌跡

# mimemagicをインストールしたい
ここ5時間くらいmimemagicのインストールに悩まされています。（泣）
未来の自分に向けて解決策を備忘録として残しておきたいと思います。
<h2>
mimemagic との戦い
</h2>
一通りgemgileやらなんやらを用意して、いざ以下のコードを書いたところ、

```
subaru$ docker-compose run web rails new . --force --database=mysql
```

全てはこのエラー文から始まった。

```
An error occurred while installing mimemagic (0.3.10), and Bundler cannot continue.
Make sure that `gem install mimemagic -v '0.3.10' --source 'https://rubygems.org/'` succeeds before
bundling.
```
gem meme
https://qiita.com/friendtree16/items/62c7ec366c107c4b1313


```
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.
```

https://qiita.com/HrsUed/items/ca2e0aee6a2402571cf6

```
$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib
Fetching mysql2-0.5.2.gem
Building native extensions with: '--with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib'
This could take a while...
Successfully installed mysql2-0.5.2
Parsing documentation for mysql2-0.5.2
Installing ri documentation for mysql2-0.5.2
Done installing documentation for mysql2 after 0 seconds
1 gem installed
```

```
subaru$ brew install shared-mime-info
Updating Homebrew..
```

```
subaru$ brew info openssl
```

```
subaru$ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
```

```
subaru$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
```

```
subaru$  bundle install
.
.
.
Bundle complete! 26 Gemfile dependencies, 91 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

```
subaru$ docker-compose run web rails new . --force --database=mysql
```

そして以下のコードを記入したら、こんなエラー文が出た。

```
You must use Bundler 2 or greater with this lockfile.
ERROR: Service 'web' failed to build : The command '/bin/sh -c bundle install' returned a non-zero code: 20
```
この記事を参考にして、
https://qiita.com/___xxx_/items/8b62633b59d7d72e6719

```
subaru$ rm Gemfile.lock
subaru$ rm -rf vendor/bundle
subaru$ gem install bundler -v '2.2.17'
```
をしたところ治った！どうやらBundlerのバージョンとローカルのバージョンが異なることが原因だったらしい。


https://stackoverflow.com/questions/53231667/bundler-you-must-use-bundler-2-or-greater-with-this-lockfile/67632652#67632652
【FileMaker】新規ウインドウでウインドウ名をレイアウト名でつけるときの注意点

# 前提
この記事は、単一ステップを使い始めた初心者を対象としています。
単一ステップでうまくウインドウにレイアウト名をつけれないな、と思ったら記事を読んでみてください。

# 単一ステップで新規ウインドウを開く場合
[Claris FileMaker](https://www.claris.com/ja/)で新規ウインドウを開くとき、単一ステップで「[新規ウインドウ](https://help.claris.com/ja/pro-help/content/new-window.html)」を実行することがあると思います。

この時、ウインドウ名を"[Get(レイアウト名)](https://help.claris.com/ja/pro-help/content/get-layoutname.html)"と設定して新規ウインドウを実行しても、新規で開くレイアウトの名前にはなりません。

サンプルを見てみましょう。
下のレイアウトモードでは、ボタンに単一ステップで新規ウインドウを開くようにしています。
![スクリーンショット 2021-08-20 16.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/c561f0dd-6428-f396-23f4-ce3369624ec8.png)
ここで、新規ウインドウの設定として、名前を"Get(レイアウト名)"としましょう。
結果は、ボタンを実行したレイアウトがアクティブレイアウトということで、開いた先のレイアウト名とはなりません。
![スクリーンショット 2021-08-20 16.43.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f8aca643-a14d-3104-c980-7c2da3b0976b.png)

# スクリプト実行でちょっと詳しく組む
ということで、ローコード・ノーコードを推進している立場ですが、ウインドウ名を適切に設定したいときは、2行くらいのスクリプトステップを用意します。
スクリプトの2行目に注目してください。
「[ウインドウタイトルの設定](https://help.claris.com/ja/pro-help/content/set-window-title.html)」で、ウインドウタイトルを適宜設定できます。
![スクリーンショット 2021-08-20 16.51.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/e7cd66a1-8e93-dcd9-8683-88bf5008729d.png)

# どういうことかというと
「新規ウインドウ」スクリプトステップのヘルプを参照すると、「ウインドウ名」は新たに開くウインドウの名前を設定する箇所なので、新規ウインドウで展開するレイアウトの名前をうっかり入れそうになりますが、"Get(レイアウト名)"関数は「現在表示されているレイアウトの名前を返します。」とあるので、「次に表示するレイアウトの名前を拾ってこない」のです。

レイアウト名に関係なく、ウインドウに固有の名前をつける場合は、単一ステップでウインドウ名をつけて問題ありません。

# 困ることはあるのか？
ウインドウの名前を指定せずにウインドウを開いたときに困ることは、ウインドウを指定してその前面に出したいときや、表示されているウインドウ名を指定して処理をしたい時に意図しない内容のデータを処理してしまう可能性があることです。
必要に応じてウインドウの名前を適切につけましょう。

初心者の方にはスクリプトワークスペースを開くのにハードルを感じる方もいらっしゃるかもしれませんが、ここだけ、ちょっと頑張って2行書いてみて下さい。
railsで簡単にCRUD処理ができるようになる（コントローラー編）

## railsで簡単にCRUD処理ができるようになる（コントローラー編）

このhogeもしくはhogesを任意の名前(taskでもboardでもなんでもいい)に変えるだけで、CRUD処理実装におけるコントローラーがマルっと解決する。

hogeもしくはhogesは、userと一対多(user:hoge = 1 : N )の関係にあるものとする。

```jsx
class HogesController < ApplicationController
  before_action :set_hoge, only: %i[edit update destroy index show]

  def index
    //全件表示
    @hoges = Hoge.all
  end

  def show
    //投稿されたものの詳細を表示
    @hoge = Hoge.find(params[:id])
  end

  def new
    //新しくインスタンス（投稿する記事など）を作成
    @hoge = Hoge.new
  end

  def create
    //form_withで作成した新しいデータ(hoge_paramsにストロングパラメータとして格納されている。)がpostされてきた
    //新しいデータなので、updateではなくてcreateアクションで処理する。
    @hoge = current_user.hoges.build(hoge_params)

    if @hoge.save
      redirect_to @hoge, success: t('defaults.message.created', item: Hoge.model_name.human)
    else
      flash.now[:danger] = t('defaults.message.not_created', item: Hoge.model_name.human)
      render :new
    end
  end

  #  current_userの編集、削除ボタンの表示
  def edit; end

  def update
    //form_withからすでに存在しているデータ(パスからidを受け取ってeditする。)がpostされてきた
    // updateで処理を開始する。
    if @hoge.update(hoge_params)
      redirect_to hoge_path(@hoge), success: t('defaults.message.updated', item: Hoge.model_name.human)
    else
      flash.now[:danger] = t('defaults.message.not_updated', item: Hoge.model_name.human)
      render :edit
    end
  end

  def destroy
    @hoge.destroy!
    redirect_to hoges_path, success: t('defaults.message.deleted', item:Hoge.model_name.human)
  end

  private

  def set_hoge
    @hoge = current_user.hoges.find(params[:id])
  end

  def hoge_params
    params.require(:hoge).permit(:title, :body, :category)
  end
end
```
【AWS SAM CLI】GoからRubyへの移行

# はじめに

AWS SAM CLIでランタイムにGoを使っているプロジェクトがありましたが、プロジェクトを作った人は退職してしまいました。
私含め、他のメンバーはRubyでの開発が主であり、Goの知識が薄い状態です。
そこで、GoからRubyに書き直してメンテナンスしやすくした時にやった事をまとめました。

# 環境

* SAM CLI, version 1.27.2
* ランタイム, go1.x =>  Ruby2.7

# 1. Rubyプロジェクトの初期化

`sam init`コマンドを使って新規のRubyプロジェクトを立ち上げました。
ディレクトリ構成は下記のようにしました。

```text
sam_cli
 |
 |-- sam-app-go # Goで書かれたプロジェクト(既存)
 |
 |-- sam-app-ruby # Rubyで書かれたプロジェクト(新規)
```

以下は対話型でruby2.7のランタイムを指定して作成している例です。

```bash
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1
What package type would you like to use?
	1 - Zip (artifact is a zip uploaded to S3)
	2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1

Which runtime would you like to use?
	1 - nodejs14.x
	2 - python3.8
	3 - ruby2.7
	4 - go1.x
	5 - java11
	6 - dotnetcore3.1
	7 - nodejs12.x
	8 - nodejs10.x
	9 - python3.7
	10 - python3.6
	11 - python2.7
	12 - ruby2.5
	13 - java8.al2
	14 - java8
	15 - dotnetcore2.1
Runtime: 3

Project name [sam-app]: sam-app-ruby

Cloning from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
	1 - Hello World Example
	2 - Step Functions Sample App (Stock Trader)
Template selection: 1

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app-ruby
    Runtime: ruby2.7
    Dependency Manager: bundler
    Application Template: hello-world
    Output Directory: .

    Next steps can be found in the README file at ./sam-app-ruby/README.md
```

# 2. コードをGoからRubyへ移行

Goで書かれたLambda関数のコードをRubyに移行します。
importしているライブラリをLambda関数を定義してあるフォルダのGemfileに置き換えていきます。
プロジェクト直下にあるGemfileはテストで使うファイルなので、テストを書く場合は、ここにも記載します。

# 3. template.ymlの修正

Go側のResourcesでLambda関数を定義している箇所をRuby側のtemplate.ymlにコピーします。
HandlerやRuntimeプロパティを修正していきます。
修正後、`sam validate`でチェックしましょう。
例として、以下に`sam init`で作成した初期テンプレートの変更箇所を上げます。

```diff:template.yml
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
-      Handler: hello-world
-      Runtime: go1.x
-      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
+      Handler: app.lambda_handler
+      Runtime: ruby2.7
       Events:
-          CatchAll:
+          HelloWorld
           Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
           Properties:
           Path: /hello
           Method: GET
-      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
-        Variables:
-          PARAM1: VALUE

```

# 4. sam deploy

`sam deploy`コマンドでデプロイします。
スタック名は別名に変えてデプロイしました。(同じスタック名でデプロイするとどうなるかは未確認)
AWS Cloudformationにアクセスしてデプロイが出来ていたら完了です！

# まとめ

`sam init`で作成されるテンプレートを基にRubyに移行しました。
Goを勉強した事がなく、Rubyに書き直すのに苦労しましたが、いい経験になりました。
Laravelで愛犬のお世話記録アプリを作るまで(1)【構想】

# はじめに
我が家の愛犬の世話は、家族で分担しています。
家族間で情報を共有し、愛犬の体調管理をスムーズにするために、散歩や餌の時間・量、排泄の回数などの記録（以下、お世話記録とする）を手軽に行えるアプリを作りたいと思います。

# 構想
![portfolio_raugh01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861066/2200c886-2850-acb1-3749-1727271f3b40.png)

最終的には上記画像のようなものにしたいです。
必要な機能から順次開発を行う予定で、開発環境など詳細は次回以降書いていきます。

# 実装の優先順位（予定）
1. ログイン機能　　：　家族だけが使用できる
1. お世話記録　　　：　時刻とお世話の種類、メモなど
1. カレンダー表示　：　その日のお世話記録と天気が確認できる
1. グラフ表示　　　：　体重、餌の量
1. 掲示板　　　　　：　健康問題があるとき、トピックスごとに経過を記録できる
1. TODO　　　　 　：　通院予定などを登録しカレンダーに表示
1. フォトアルバム　：　入れられそうならついでに入れる

今回は以上です。
grepコマンド使いこなすエンジニアはかっこいい(偏見)

# grepコマンドとは
grepコマンドとは、あるファイル中の文字列に対して正規表現を利用して検索し表示することができるコマンドです。

## 基本操作
使い方は以下のようになります。

```bash
$ grep 検索正規表現 ファイル名

# 例:cssディレクトリの中から「red」という文字列を検索している
$ grep red css/*
```

ちなみに複数の条件を設定する場合は「|(パイプ)」で繋ぎます。

```bash
$ grep 検索文字列 ファイル名 | grep 検索文字列2

# 例:cssディレクトリの中から「red」と「blue」という文字列を検索している
$ grep 'red' css/* | grep 'blue'
```

## オプション一覧
`$ grep オプション 検索正規表現 ファイル名`とすることで、オプションをつけた検索を行うことができます。

| オプション | 内容 |
|:-:|:-:|
| -i  | 大文字小文字を区別しない  |
| -E  | 拡張正規表現で検索  |
| -e  | 一致処理に指定した正規表現で検索  |
| -v  | 一致しないものを検索  |
| -n  | 検索結果に行番号を表示  |
| -l  | 検索結果にファイル名のみ表示  |
| -h  | 検索結果にファイル名を表示しない  |
| -o  | 検索結果に一致した文字を表示  |
| -C  | 検索結果に一致した箇所から前後に指定した行数を表示  |
| -r  | ディレクトリ内も検索対象とする  |
| -L  | 検索結果に該当しなかったファイルを表示  |


# 参考
[grepコマンドの詳細まとめました【Linuxコマンド集】]
(https://eng-entrance.com/linux-command-grep)
[Rails]rack-corsの導入でCORS設定

# rack-colsとは
RackアプリケーションにCORSの制御機能を追加するRackミドルウェアのことです。 
CORSを使うことで、Webアプリケーションは特になんの回避策も無しでクロスドメインのAJAXの呼び出しを行うことができます。

# 使い方
## インストール方法
Gemfileに以下を記載して、`bundle install`するだけです。

```ruby
gem 'rack-cors'
```

## Railsの設定
`config/initializers/cors.rb`に設定を行う。

- origins
    - スキーム（http）、ドメイン（example.com）、ポート（8080）を組み合わせたもの。簡単に言うとURLのこと。
    - `*`とすることで、すべてのoriginsを許可する。
- resource
    - 許可するリソースファイルのこと。
    - `*`とすることで、すべてのリソースファイルを許可する。
- headers
    - 許可するHTTPヘッダーのこと。
    - `any`とすることですべて許可する。
- methods
    - 許可するHTTPメソッドのこと。

```config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    # どのオリジンからのリクエストも許可する
    origins '*'
    resource '*',
              headers: :any,
              methods: [:get, :post, :patch, :put]
  end
end

```


# 参考
[cyu/rack-cors]
(https://github.com/cyu/rack-cors)

[gem rack-cors の README を翻訳しました]
(https://qiita.com/ikamirin/items/2bd494142610960071a9)

[【Rails6】Gem rack-corsを導入してCORS設定を行う(オリジン・CORSとは何か)]
(https://blog.cloud-acct.com/posts/u-rails-rackcors/)
Javaのlibrosa的ライブラリjlibrosaをandroid studioで使う

【追記】20210906　loadAndReadのバグに注意。

最近アンドロイドアプリを作ろうとしているので備忘録

#Javaでサクッと音の特徴量求めたいけどどうしよう
pythonだったらLibrosaに頼るところですが、Javaにも似たようなライブラリがないか探してみたところありました！
その名も[jlibrosa](https://github.com/Subtitle-Synchronizer/jlibrosa)！！！
Java版Librosa作ろうぜ、みたいなところがモチベーションで開発されているようです。
androidでどうやって使うかも、[神記事](https://heartbeat.fritz.ai/a-definitive-guide-for-audio-processing-in-android-with-tensorflow-lite-models-d90de896f0c4)にちょいと書かれており、非常に助かりました。
ただライブラリのインストールのところでちょっと躓いたので記事に残しておきます。

#jlibrosaをandroid studioにライブラリとしてインポートする手順
1. githubからjlibrosaをダウンロードしてくる　#zipでどんとやっちゃいましょう
1. android studioをプロジェクトビューにしてlibsフォルダを出現させる
1. ダウンロードしたjlibrosa-master/binaries以下に.jarファイルが2つ入っているのでそれをlibsフォルダに追加する
1. それぞれの.jarファイルを右クリックして「ライブラリーとして追加」を選ぶ

個人的にはlibsフォルダどこあんねん、っていうのと、
どのファイルをandroids studioに追加すればいいかで躓きました。

libsフォルダはandroid studio左上のプルダウンから「プロジェクト」(デフォはandroidになっているはず？)を選択すると出現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594517/7ba94d5d-cb5a-eab8-4585-2a1d4b70cd4a.png)

以上！
作ったアプリについても記事にできたらいいな。

#追記　20210906　loadAndReadのバグに注意。
issuesにも書いてあるのですが、loadAndReadで任意のサンプリング周波数で読み込めないというバグがあります。
[https://github.com/Subtitle-Synchronizer/jlibrosa/issues/3](https://github.com/Subtitle-Synchronizer/jlibrosa/issues/3)
デフォルト値として取り扱いたいサンプリング周波数を与えてあげれば思うように動作するようなので、回避するためには上記のようにライブラリとしてインポートするのではなく、コードとしてプログラムに取り入れてデフォのサンプリング周波数を変えてあげる必要があるみたいです。要チェキです。
単一ファイルLambdaのデプロイ用PowerShell

# 背景

Lambdaのデプロイって関連するオブジェクトがある場合や複数ファイルで構成されている場合は、
SAMとかserverlessを使うのが、メリットを多く受けられますが、
単一ファイルのシンプルなLambdaの場合は設定ファイルを書くほうが手を取られてしまいますよね

# 対応方法
Lambdaのデプロイって、zipファイルを作ってAWSにアップロードすれば良いので、スクリプト書いたほうが早いと思い書いてみました

```powershell:upload.ps1
if((Test-Path app.zip) -eq "True"){
  Remove-Item app.zip
}
Compress-Archive -Path .\app.py -DestinationPath app.zip
aws lambda update-function-code --function-name [Lambda名] --zip-file fileb://app.zip --profile [AWSプロファイル名]
```

# 所感
やっている内容はシンプルなので、処理の説明は不要かと
今はLambda名もプロファイルもベタがきですｗ
パラメータで渡すとなるとスクリプトのシンプルさが失われてしまうので、ちょっと考えてしまいますね

複数ファイルで構成されている場合はアーカイブで工夫が必要ですが、必要に迫られたらまた考えます


同じ悩みを抱えている方の参考になりましたら
liveviewのhandle_event/3が動かない時の対処法その１


liveview v0.16.0にアップデートしてからhandle_eventが動かなくなり、色々試したところ

```elixir:page_live.ex
defmodule MyAppWeb.PageLive do
  use MyAppWeb, :live_view
  ...
end
```
use MyAppWeb, :live_view
が原因らしかったので、もともとmyapp_web.exで定義されていたlive_viewの中身で置き換えて対応。

```elixir:myapp_web.ex
defmodule MyAppWeb.PageLive do

　　...

  def live_view do
    quote do
      use Phoenix.LiveView,
        layout: {MyAppWeb.LayoutView, "live.html"}

      unquote(view_helpers())
    end
  end

  ...

  defp view_helpers do
    quote do
      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML

      # Import LiveView helpers (live_render, live_component, live_patch, etc)
      import Phoenix.LiveView.Helpers

      # Import basic rendering functionality (render, render_layout, etc)
      import Phoenix.View

      import MyAppWeb.ErrorHelpers
      import MyAppWeb.Gettext
      alias MyAppWeb.Router.Helpers, as: Routes
    end
  ...
end
```

下記のように変更。

```elixir:page_live.ex
defmodule MyAppWeb.PageLive do
  use Phoenix.LiveView
  use Phoenix.HTML
  import Phoenix.LiveView.Helpers
  import Phoenix.View
  import MyAppWeb.ErrorHelpers
  import MyAppWeb.Gettext
  alias MyAppWeb.Router.Helpers, as: Routes
  ...
end
```

一旦は動くようになりました。
AWSのデータベースについて学び直した話

##背景
MySQLについての基礎を学習した後、AWSでのデータベース機能について知りたくなり、本を買って読んでみた。
あくまで学習の補助メモ機能として記載しているので、文が整っていない場合もある。ご了承いただきたい。

###読んだ本
[AWS認定 データベース・専門知識](https://booklive.jp/product/index/title_id/971824/vol_no/001)

###読んだ章
今回読んだのは3章。NoSQLについて記載されていた章だった。
MySQLについての基礎は概ね理解してきたが、NoSQLのしかもAWSサービスについて知らないことが多すぎるので、読みながら学習し直した。

##はじめまして、NoSQL
この章は大きく分けて2つのサービスについて説明が書いてある。
1つ目はDynamoDBについて、もう一つはDocumentDBについてである。

###DynamoDBとは？
一言で言うと、AWSが提供するフルマネージド型のNoSQLサービスのこと。
特徴としては、**低レイテンシーである**こと、また**マルチリージョンに対応**していることが挙げられる。
主な仕組みとして、まず「パーティションキー」と呼ばれる領域に分散させてデータを保持することを理解しておく必要があり、
そのパーティションキーを元にハッシュ値を取得→データをどのパーティションに格納するのか決めるというのが一連の流れとなっている。
####DynamoDBの可用性
主な特徴をまとめると以下だった
>・書き込まれたデータは3つのAZへレプリケーションされて保存される
・データを読み込む際、「結果整合性」を担保してデータを読み込む

####DynamoDBのパフォーマンス
DynamoDBは書き込み操作・読み込み操作それぞれ「ユニット」と呼ばれる単位に換算し、その単位ごとに料金が発生する仕組みになっている。
利用する場合はこの単位を基準に考えるべきだと知った。
DynamoDBはオートスケーリングすることが出来るらしく、AWSコンソールで作成した場合はデフォルトでオートスケーリングがオンになっている。
設定値について、後ほど最小値や最大値を設定することも可能だ。
#####スキャンとクエリ
DynamoDBには「スキャン」と「クエリ」と呼ばれるAPIが2種類存在している。以下引用を記載する。

>スキャンは前件を走査する方法です。読み込みユニットを消費します。
クエリはキーを元にDynamoDB側で絞り込んだデータを取得する方法です。クエリリクエストにおいて指定されたキーのみが読み込まれる為、対象となるItem分の読み込みユニットのみ消費します。

どちらも読み込みユニットを消費するが、データを取得する際はクエリを利用した方が読み込みユニットの消費を抑えられるとあった。

#####ローカルセカンダリインデックスとグローバルセカンダリインデックス
DynamoDBのテーブル内で検索する時、パーテイションキーとソートキーだけで検索するのは大変なので、検索用のタグのようなものを付けられるサービスが存在する。それが「ローカルセカンダリインデックス」と「グローバルセカンダリインデックス」だった。それぞれ引用する。

**ローカルセカンダリインデックス(LSI)**
>・同一パーティション内への追加のインデックスという意味で、ローカルセカンダリインデックスと呼ばれます。
・シンプルなプライマリーキーのみをもつテーブルには、この概念は存在しない。
・ローカルセカンダリインデックスを含むテーブルの容量は10GBと決められている。


**グローバルセカンダリインデックス(GSI)**
>・異なるパーティションキーをもつItemを含むデータ群からクエリを絞り込みたい時、グローバルセカンダリインデックスを作成することが出来る。
・テーブルの全パーティションにまたがるインデックスのこと。
・グローバルセカンダリインデックスは1つのテーブルに対し、２０個まで作成可能

#####DAXって何？
DAXとは、インメモリキャッシュのこと
例えば、EC2からDynamoDBへアクセスした時、以前にもアクセスした記録＝キャッシュがあった場合、DAXが値を返してくれる。
＝DAXを活用することで、EC2などサービスからのアクセスをスムーズに行うことが出来る。

####DynamoDBのセキュリティ
#####アクセス制御
アクセスを制御する手段は、IAMによるもので、IAMユーザーやIAMポリシーをグループにアタッチすることで、各々のアクセス制御を行うとこと。
また、VPCエンドポイントを使用することで、インターネットを経由せずにDynamoDBへのアクセスが可能になる。

####DynamoDBのコスト
著書内では、コストがかかる場合についての詳細が記載されていた。
代表的なものだけ挙げる。
>・読み込み/書き込みリクエスト
・バックアップと復元
・グローバルテーブルのレプリケート
・データ転送
※個々の料金については公式を参照するか、実際の本を購入して読むと良い

####DynamoDBのメンテナンス
基本的にフルマネージドサービスで且つサーバーレスの為、利用者がメンテナンスを考慮する必要はない。
一方、作成されたテーブルの管理は利用者の責任とあった。
パフォーマンス改善やバックアップなどのメンテナンスはどうしても利用者側が管理し運営する必要がある。
#####バックアップについて
DynamoDBのバックアップは2種類ある。
>①オンデマンドバックアップ
②ポイントタイムリカバリ(PITR)

それぞれの特徴は以下の通り。
######オンデマンドバックアップ
>・ユーザーの任意のタイミングで取得できるバックアップ
　→特定の時点のバックアップが可能になり、いつでも復元できる
・AWSマネジメントコンソールで使える
・テーブルのサイズに関わらず、バックアップにかかる時間は数秒
　→バックアップの時間を気にせず、巨大なテーブルに対するバックアップができる
　→長期バックアップとしても利用される

#####ポイントタイムリカバリ(PITR)
>・自動バックアップ
・突然のデータ損失が生じても、過去35日間の任意の時点に復元できる
　→長期バックアップには向いてない
・復元データを新しいテーブルとして作成する
　→以前利用していたテーブルに新規内容として追加で書き込まれる訳ではない

####DynamoDBのモニタリング
モニタリングを行う時は、CloudWatchを用いて実施するのが望ましいとあった。
また、他の方法として、CloudTailが挙げられており、CloudTailを利用することで、IAMユーザがDynamoDBへリクエストを行ったのかを確認できる。

###DocumentDBとは？
フルマネージド型のMongoDB互換ドキュメントデータベースサービスのことをDocumentDBと呼ぶ。
また、DocumentDBはAmazon Auroraとも似通った特徴を持っている。著書内では2つの比較図が記載されていた。
MongoDBのことをよく知らなかったので、参考資料に記載のサイトで学習した。


##参考資料
[やってみようNoSQL MongoDBを最速で理解する](https://qiita.com/Brutus/items/8a67a4db0fdc5a33d549)
今更ですが、BIOSについてまとめてみました！

3月からインフラエンジニアとして働き始め、最近は現場のサーバー保守に本格的に関わることが増えていく中でBIOSという言葉頻繁に聞くようになりました。

それまでは口頭ベースだったり軽く調べて済ましていましたが、
今回改めて、自分の言葉でまとめてみたいと思い記事にしてみました！

参考URL
https://www.dospara.co.jp/5info/cts_str_pc_bios
https://jisakupc-technical.info/basic/motherboard/


#BIOSとは

正式名称はBasic Input Output System
一言で役割を表すなら「デバイスなどを制御するプログラム」となります。

なのでキーボードなどの入力装置のデバイスの制御もしてくれているプログラムもこのBIOSという認識になります！
（Aを押しているのにDとか入力されたら困りますよね笑。その手助けしてくれるプログラムとなります！）

ちなみにこのBIOSがOSの起動するプログラムを呼び込んでいます。
一応BIOSはマザーボード上に格納されているシステムBIOS、拡張カード上にある拡張BIOSといった種類もあります。

#マザーボード

上記の説明でマザーボードというのも出てきたのでここにも軽く触れると、
「コンピュータ内で利用される装置（CPUとかメモリーとか）を構成するための電子基板回路」のことを指しています。

いわゆる基板です。笑
この基板は実際写真でみた方が分かりやすいと思います。（検索するとすぐに出てきます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626890/de0d664f-cbd4-0309-debb-c2c63e940329.png)

参考　https://jisakupc-technical.info/basic/motherboard/


写真からもわかるようにマザーボード上には様々な装置とのインターフェイスがありますこれらに、
実際のパーツをつける形となります！
製品によってもちろん中身が多少違うようです。
仕事の際に触るサーバ内にはファンのコネクトだったりバッテリーのコネクトがあったりします。

ここまでは言葉でしっかりまとめてみましたが、
いわゆる基板というぐらいですから全てのパーツの「土台」にあたる箇所ってことですかね！

基礎的なことですけど、改めて調べてまとめてみるとスッキリしますね！
アプリを作るにあたっての便利ショートカット

#php storm上
Option +command +l
→インデントを整えてくれる

useの部分でcommandを推しながらクラスやメソッドをクリックする(command+Bでもいける)
→定義元にジャンプできる


#ターミナル上
command n
→新しいターミナルを表示

#ブラウザ上

検証ツール

```
option command i
```
もしくは

```
Fn +12
```
consoleはjsのエラーを見る時に便利

スーパーリロード

```
ctrl shift R
```
読み物としての時刻設定

## 時刻設定

Linuxを使っていると、システムクロックが狂ってくることがある。Windowsではシステム時計といっていたが、Linuxでは一般的に`システムクロック`といういい方をする。そのままではあるが。システムクロックを表示するコマンドが、`dateコマンド`。dateコマンドを使って、時間合わせをすることもできる。

システムクロックだが、OS起動時に`ハードウェアクロック`から引用されることになる。クロックシステムが狂っているということは、つまり、ハードウェアクロックが狂っているということになる。システムクロックの時刻さえ正しければ、ハードウェアクロックが多少狂っていたとても何ら問題はない。各種システムが参照する時刻は、システムクロックから参照しており、ハードウェアクロックを直接参照しているわけではないからだ。

Windowsを使っている時は、システムクロックを時々修正することはあっても、ハードウェアクロックを修正するモチベーションまではなかった。ハードウェアクロックを修正するにはWindows起動前にBIOS画面を立ち上げて、そこで修正しないといけないからだ。しかし、Linuxであれば、CUIから直接ハードウェアクロックを修正することができる。

システムクロックを表示するコマンドが`dateコマンド`であったが、ハードウェアクロックを表示するコマンドは`hwclockコマンド`になる。`date ; sudo hwclock`とワンライナーでコマンド入力すると、２つの時間がほぼ同時に表示できるので、差異が一目瞭然で確認できる。また、ハードウェアクロックを修正する時も、hwclockコマンドを使って修正が行える。

hwclockには様々なオプションが用意されている。ハードウェアクロックをシステムクロックに同期させたり、逆に、システムクロックをハードウェアクロックに同期させることもできる。OS起動時は、ハードウェアクロックをシステムクロックに同期させ、シャットダウン時には、逆に、システムクロックをハードウェアクロックに同期させる処理を、内部的に行っているようだ。なので、運用途中に、手動で同期合わせを行う必要性はほぼないということになる。

さて、システムクロックが狂っていたら、スマホで時間を確認して、dateコマンドで手動で修正してもいいのだが、折角なので、NTPサーバーから標準時刻を秒単位で取得することもできる。この時に使うコマンドが、`ntpdateコマンド`になる。

`ntpdate NTPサーバーのURL`とすると、NTPサーバーから時間を取得することができる。そして、取得した時刻はシステムクロックに反映される。ハードウェアクロックではない。そして、その後、hwclockコマンドを使って、ハードウェアクロックに同期させるという手順となる。

NTPの次期バージョンとして`Chrony`というツールがあるが、Chronyを使うと、NTPサーバーから取得した時刻を、ハードウェアクロックに直接反映させることができるようになる。どうも、NTPを使うよりもChronyを使う方がトレンドになっているようだ。

ntpdateコマンドを使って、手動で時刻合わせを行う以外にも、ntpdサービスを常駐させて、自動で定期的に時刻を合わせる方法もある。ntpはデフォルトでは入っていないため、別途インストールすることになる。また、ntpの設定を行うファイルは、`/etc/ntp.confファイル`となる。ここを編集して、ntpdを起動すればOKのようだ。

サービスを常駐させると、メモリ容量を圧迫することになり、ネットワークトラフックも増えることになるため、そこまでしてクライアントでNTPを使うべきかどうかは、少し考えた方がいいかも。
JavaScriptを基本からまとめてみた【15】【コールバック関数】

##はじめに

####学習するに至った経緯
2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

##コールバック関数とは
『コールバック関数』とは、ある関数に引数として渡される関数のこと。コール(実行)する関数の引数に処理(関数でも可)を追加して、必要な処理が終わった後に引数の処理を実行する方法になる。
「関数の中で別の関数を呼び出し、呼び出した関数の結果を使って結果を返す」という動作が、「一度電話をかけて用件を伝えたのち、相手に折り返して返事をもらう」という「Call back（電話をかけ直す）」に似ているため、「コールバック関数」と呼ばれるらしい。
######※ JavaScriptの関数は、文字列や数値、変数だけでなく、関数も引数として受け取ることができる。

##関数の引数（ひきすう）とは
『引数』とは、関数に入力する値のこと。

```main.js
const sampleFunc = function(引数){ console.log("My name is"+"引数") }
sampleFunc("kaimen"); //出力結果：My name is kaimen
```
この関数sampleFunc(引数)では、入力された「引数」を受け取り、関数内でconsole.log(“My name is”+”引数”)という処理を行った結果を出力する。

#####※　sampleFunc(引数)という関数において、引数に関数を指定する場合、この関数(引数）はコールバック関数となる。

##コールバック関数の例

```main.js
//引数xに関数を指定する場合、その関数xはコールバック関数である
const sampleFunc = function(x){
  console.log("My name is"+"x")
}
const callbackFunc = function(){ return "kaimen" } // 関数callbackFunc()は文字列"kaimen"を返す

sampleFunc(callbackFunc()); //出力結果：My name is kaimen
```

この例の場合、sampleFunc()の引数にcallbackFunc()を指定している。このcallbackFunc()は関数であるため、callbackFunc()はsampleFunc()のコールバック関数にあたる。

これらの関数は、下記の順番で呼ばれる。コールバック関数の結果が出力されたのち、外側の関数の結果が出力される。

① sampleFunc()が呼ばれる
　　　　　↓
② sampleFunc()内の、callbackFunc()が呼ばれる
　　　　　↓
③ callbackFuncの出力結果をもとに、sampleFunc()の結果が出力される





##参考サイト
[【JavaScript】コールバック関数とは？ 簡単にまとめてみた（サンプルあり）]
(https://kaimenlife.com/archives/1169/js-callback-1/)
[JavaScriptの非同期処理を同期させる方法【初心者向け】]
(https://www.otwo.jp/blog/asynchronous-processing/)
Python twint インストール方法


twinと使用して、ツイッターの情報を取得しようとした時の失敗例を書いておきます。

```:上手く動かなかった
pip install twint
```

```:Python
pip install --upgrade git+https://github.com/twintproject/twint.git@origin/master#egg=twint
```

gitから引っ張ってこないと最新の状態でtwintを取得できないようです。
他のライブラリでも似たようなことが起きたときはgitから引っ張ってきましょう！
【javascript】要素を取得して操作するときに気をつけること~備忘録~

getElementByIdばかり使っていて、その他のgetElementsByClassName、getElementsByName等を使う時に少し注意する点がある。

id属性を取得するやり方は、getElementByIdと<b>element</b>が単数であるように、その直後に関数をくっつけるだけで良い。
例えば、

```js
getElementById('hoge').setAttribute('disabled', true)
```

と書けば良い。

だが、getElementsByClassNameやgetElementsByNameは<b>elements</b>と複数形であるように、その直後にはどの要素かを指定する必要がある。仮にその要素が1つだけだとしても。
例えば

```js
getElementsByName('hoge')[0].setAttribute('disabled', true)
```
と書く必要がある。
Markdown+mermaidで、シーケンス図が表示されない時の解決方法

# 概要
シーケンス図を手軽に描くのに、マークダウンのマーメイドを使用しますが、サクッと書けて便利ですよね？
でも、ある時、シーケンス図がプレビュー画面に表示されなくなりました。

その時の解決方法です。

#現象
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/4d10a1ef-6c23-7f80-5c3d-2830fe66ca9d.png)
赤枠の部分のシーケンス図が表示されてない。

#解決方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/085486b9-e876-211e-cd31-cb11b8cf0412.png)
右下の歯車アイコン → ワークスペースの信頼を管理 を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/94eda7b0-fe86-7c8e-2737-7418c9946499.png)
信頼するを押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/51b56845-0153-fb34-3811-5645072bf06a.png)
"このウィンドウは信頼されています。"が表示される。
もう、このウィンドウは不要なので閉じる。ついでに元のプレビュー画面も閉じる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/abf25db7-6a7c-22a0-af80-ba475399782e.png)
"このウィンドウは信頼されています。"と、もとのプレビュー画面を閉じたところ。

もう一度、プレビューを表示する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723966/00faeb8c-354b-e234-5f46-a037c2b719c7.png)

これで、無事、期待通り、シーケンス図が表示されるようになりました。

#結論
原因は、VSCodeの「制御モード」でした。ワークスペースの信頼で解決。
Rails + heroku + CloudinaryでのURLからの画像保存方法

##前提条件
rubyとrailsのバージョンは以下の通り。
ruby：2.6.3p62
rails：6.1.3.2

##herokuにcloudinaryを追加
herokuのweb画面からcloudinaryを追加する
![スクリーンショット 2021-08-20 12.08.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717720/efc44888-1a1a-d137-08f2-85fca6aaf752.png)

料金プランは無料プランにしている
![スクリーンショット 2021-08-20 12.10.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717720/a64f4f30-0638-d7d6-9dc7-55e06825c93f.png)

##cloudinary.ymlの追加
cloudinaryの画面でYMLリンクをクリックしてymlをダウンロードする。（YMLリンク小さすぎ）
ここにapikeyとか全部書かれている。

![スクリーンショット 2021-08-20 12.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717720/26ace09e-cdc4-c8da-ab6a-14164cbbddb5.png)

ダウンロードしたymlはapp/configの下に配置する

##gemの追加
Gemfileに以下を追加

```rb
gem 'carrierwave'
gem 'cloudinary'
```

##uploderの生成と編集
以下のコマンドでapp/uploaders/cloudinary_image_uploader.rbが生成される

```
bundle exec rails g uploader CloudinaryImage
```

cloudinary_image_uploader.rbに以下を追加

```
include Cloudinary::CarrierWave
```

以下がcloudinary_image_uploader.rbにあるとcloudinaryに保存されないのでコメントアウト

```
storage :file
```

##画像の保存
今回はURLからjpeg画像を取得してcloudinaryに保存する

```rb
temp_file = Tempfile.new('temp_')
temp_file.binmode
open('画像のURL') do |file|
  temp_file.write(file.read)
end
temp_file.rewind

model.image = ActionDispatch::Http::UploadedFile.new(filename: "ファイル名", type: 'image/jpeg', tempfile: temp_file.open)
model.save!

temp_file.close
```

##参考
https://blog.favy.co.jp/8554/
Gitに接続出来なくなった話

##経緯
GitHubを使ってcloneしたり、pushしたりを日常的に実施する。
そんな中、ある日突然手元のローカル環境にgitのリポジトリがclone出来なくなった。
その原因を探りつつ、備忘録として記す。

##この記事が実施すること
git cloneがローカル環境で出来なくなった時の対処法を記載する

##解決方法
結論から言うと、単純な問題だった。
「gitアカウントに前までログイン出来ていたのに、ログイン出来なくなった」という事実がある以上、パスワードでのログインが出来なくなったといって良い。
よって、パスワードの代わりに「個人アクセストークン」と呼ばれるものをgit上で作成することで、ログインができるようになった。

①[公式のドキュメント](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)を参考にtokenを作成
②コマンドプロンプトを開く
③clone実行

```
# git clone repository_name.git
```

##まとめ
パスワード入力でダメならtokenを発行する！！
Laravel 多対多リレーション

# 多対多

###命名規則に従う場合

＜条件＞
中間テーブル名：”user_role”
カラムを"user_id", "role_id"とする。

ユーザー：User
役割：Role
中間テーブル：user_role

####Model/User

```.User.php
    public function roles()
    {
      return $this->belongsToMany(Role::class);
    }
```

####Model/Role

```.User.php
    public function users()
    {
      return $this->belongsToMany(User::class);
    }
```

##命名規則に従わない場合

＜条件＞
中間テーブル名を、”pivots"

ユーザー：User
役割：Role
中間テーブル：pivots

####Model/User

```.User.php
    public function roles()
    {
      return $this->belongsToMany(Role::class,'pivot');
    }
```

####Model/Role

```.User.php
    public function users()
    {
      // return $this->belongsToMany(どのモデル,'どの中間テーブル','このモデルファイル自身に該当するカラム','　相手のidに該当するカラム');
      return $this->belongsToMany(User::class,'pivot','xxx_role_id','xxx_user_id');
    }
```
[Ruby on rails] RuboCop（リーダブルコード）②Rubocop-airbnbを導入してみた

<h2>初めに</h2>

以前の記事でrubocopを導入しましたが、
rubocop-airbnbの方が使い勝手が良かったので、そちらに変更しました。
圧倒的に設定やら何やらはこっちの方が楽です！！！

https://qiita.com/ki_87/items/1ee43808784652cd1608

<h2>Gemfile導入</h2>
前入れたrubocopとはおさらばです。

```Gemfile
gem 'rubocop-airbnb'

```

bundle install します。

<h2>ファイルの作成</h2>

.rubocop.ymlと.rubocop_airbnb.ymlを作成します。
Gemfileがあるところと同じところです。

![スクリーンショット 2021-08-20 13.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/efaf19ed-17e8-97f1-7034-0dac9a9ef692.png)

<h2>ファイルに記述</h2>

```perl:.rubocop.yml
inherit_from:
  - .rubocop_airbnb.yml

#ここにはrubocopでコード解析したくないファイルやフォルダを指定します
AllCops:
  Exclude:
    - 'db/**/*'
    - 'bin/*'
    - 'config/environments/*'
    - 'config/application.rb'
    - 'config/initializers/*'
    - 'config/spring.rb'
    - 'lib/tasks/*'
    - 'vendor/**/*'
    - 'path/ruby'
```

```perl:.rubocop_airbnb.yml
require:
  - rubocop-airbnb
```

<h2>起動！</h2>

起動のコマンド

```
bundle exec rubocop --require rubocop-airbnb
```

自動修正のコマンド

```
bundle exec rubocop --require rubocop-airbnb -a
```

もう１回起動し、以下のようになりました。ここからは自分での訂正になります。

![スクリーンショット 2021-08-20 13.26.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/bdac719a-f084-dcae-ab25-8eb5980dd325.png)

<h2>コードの修正作業</h2>

①Gemfileに同じ記述が２つあると指摘されています。
→gemfileに同じ記述を２回していたので削除しました。

②unless A また　Bという記述をしていましたが、
unlessのときは、one conditionalしか使えないそうなので修正。

③そして少し厄介なのが以下です。
default scopeはNGなんですね・・・・。
![スクリーンショット 2021-08-20 13.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/18b80c23-56e5-29bb-455b-f89558b085c7.png)


<h2>終わりに</h2>
前回入れた通常のrubocopだとメソッド名が長すぎる！！！！という指摘や、
日本語のコメントアウトも大量に指摘されていましたので、圧倒的にこちらの方が使いやすいというか、
コードを整えやすいと感じました。
TextFieldで変換が出来なくなった！

## 背景
シュミレータで動きを確認しつつ、実機で実行してみたらTextFieldに入力した値が濁点、半濁点のつけ外し、変換が出来なくなっていて困ったのでメモ。

## 原因
TextFieldで文字列の入力数の制限をかけていたのですが、それが問題でした。
TextFieldは、Eding Changedで接続してあります。
・問題のソースコード

```swift
  guard let text = username.text else { return }
  username.text = String(text.prefix(20))
```

最大文字数を20文字とし、それ以上は入力できないようにしていたのですが、この"prefix"が値を確定してしまうため、入力できませんでした。

## 解決策
一旦のしのぎとしてはこのような感じ（パワープレイ感は否めない）

```swift
 guard let text = username.text else { return }
 if text.count > 20 {
     username.text = String(text.prefix(20))
 }
```
カウントが20文字を超えたときに固定するようにしています。
ただこれだと20文字を超える変換が出来ませんが、20文字以上の入力はそもそも受け付けないということになっているため、一旦これで良しとします。
【ShellScript・MYSQL】シェルスクリプトで、テーブルデータを削除し、csvファイルをインポートする

DBに接続し、テーブルデータを削除し、csvファイルをインポートすることをshellscriptで表現してみます。

まず、SQLはこちら。

```sql:

/*「table_name」というテーブルの内容を削除する*/
TRUNCATE TABLE table_name;

/*「file_path」にある「csv_file_name」というCSVファイルを「table_name」というテーブルにインポートする*/
LOAD DATA LOCAL INFILE "file_path/csv_file_name" INTO TABLE table_name FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"';

/*【余談】CSVファイルの1行目は飛ばしてインポートするには、「IGNORE 1 LINES」を最後につけましょう*/
LOAD DATA LOCAL INFILE "file_path/csv_file_name" INTO TABLE table_name FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' IGNORE 1 LINES;

``` 

では、shellscriptで上記のSQLを連続して、実行してみましょう。


```shell:sample.sh
 #テーブル削除
  truncateSql="TRUNCATE TABLE table_name;"
  
  #CSVファイルをインポート
  loadSql="LOAD DATA LOCAL INFILE \"file_path/file_name\" INTO TABLE table_name FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';"

  #sql実行
  mysql -h host_name -D bd_name -u user_name -Pport_number -ppassword -e"${truncatesql}${loadsql}"
```

\"file_path/file_name\" や OPTIONALLY ENCLOSED BY '\"' の「”（ダブルクォーテーション）」の前に「\（円マーク バックスラッシュ）」があります。「\」はエスケープ文字として扱われます。エスケープ文字とは、特別な意味が無効になる文字のことです。ここでは、「"」の特別な意味を無効にして、ただの文字として扱うようにしています。

また、DBに接続するsqlコマンドで、パスワードを指定する際は、「-p」と「password」の間にスペースを入れてはいけません。

さらに、mysqlコマンドのオプション「-e」をつけると、SQLも実行できます。
連続で複数のSQLを実行したい場合は、「SQL文;SQL文;」のように連続して記述します。

selectした結果をcsv出力したい場合はこちら↓

https://qiita.com/aki_number16/items/080ecc78d037838a0057

#参考
Qiita『よく使うMySQLコマンド&構文集』（2021年8月14日利用）
https://qiita.com/CyberMergina/items/f889519e6be19c46f5f4

Qiita『シェルスクリプトでMySQLにCSVデータをインポート』（2021年8月14日利用）
https://qiita.com/moritam@github/items/6b5aa4a479348257b017

Qiita『ShellScript 変数 に \ を格納する』（2021年8月14日利用）
https://qiita.com/miriwo/items/8bf37eedf92fc6ea8b77

DBOnline『MySQLに接続するユーザー名とパスワードの指定』（2021年8月14日利用）
https://www.dbonline.jp/mysql/connect/index3.html

MYSQL5.6リファレンスマニュアル『13.2.6 LOAD DATA INFILE 構文』（2021年08月14日利用）
https://dev.mysql.com/doc/refman/5.6/ja/load-data.html
PythonでMariaDBに接続

#概要
AWS Cloud9にて、Pythonでデータ収集し、MariaDBにデータ保存しておくためのスクリプトを作成しました。

---

#依存関係
環境の条件となります。
>- Python – one of the following:
    - CPython >= 3.6
    - Latest PyPy 3
- MySQL Server – one of the following:
    - MySQL >= 5.6
    - MariaDB >= 10.0

---

#モジュールをインストール

```shell
$ pip install PyMySQL
Defaulting to user installation because normal site-packages is not writeable
Collecting PyMySQL
  Downloading PyMySQL-1.0.2-py3-none-any.whl (43 kB)
     |████████████████████████████████| 43 kB 3.8 MB/s 
Installing collected packages: PyMySQL
Successfully installed PyMySQL-1.0.2
```

---

#事前準備
サンプル用に環境を整えます。

##データベースの作成
`sample`というデータベースを作成します。

```sql
MariaDB [(none)]> CREATE DATABASE sample;
Query OK, 1 row affected (0.00 sec)
```

---

##ユーザの作成

```sql
MariaDB [(none)]> create user 'user'@'localhost' identified by 'passwd';
Query OK, 0 rows affected (0.00 sec)
```

##ユーザへの権限付与
データベース内の全テーブルに与える権限を与える

```sql
MariaDB [mysql]> grant all on sample.* to 'user'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
```

---

##テーブルの作成
`users`というテーブルを作成します。

```sql
CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `email` varchar(255) COLLATE utf8_bin NOT NULL,
    `password` varchar(255) COLLATE utf8_bin NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
AUTO_INCREMENT=1 ;
```
これで準備完了です。

---

##pythonファイル
やっていることは、`users`テーブルにデータを追加し、追加されているかSELECTで確認をします。

```python:sample.py
import pymysql.cursors

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='user',
                             password='passwd',
                             database='sample',
                             cursorclass=pymysql.cursors.DictCursor)

with connection:
    with connection.cursor() as cursor:
        # Create a new record
        sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
        cursor.execute(sql, ('webmaster@python.org', 'very-secret'))

    # connection is not autocommit by default. So you must commit to save
    # your changes.
    connection.commit()

    with connection.cursor() as cursor:
        # Read a single record
        sql = "SELECT `id`, `password` FROM `users` WHERE `email`=%s"
        cursor.execute(sql, ('webmaster@python.org',))
        result = cursor.fetchone()
        print(result)
```

---

#実行し、検索結果を確認

```shell:
$ python sample.py
{'id': 1, 'password': 'very-secret'}
```

```sql
MariaDB [sample]> select * from users;
+----+----------------------+-------------+
| id | email                | password    |
+----+----------------------+-------------+
|  1 | webmaster@python.org | very-secret |
+----+----------------------+-------------+
1 row in set (0.00 sec)
```

---

#まとめ
環境さえ整えることが出来れば、DB接続やSQL操作は簡単に行えそうです。
開発がより、はかどりそうです。

##参考サイト
- https://github.com/PyMySQL/PyMySQL