OmniAICreator/Qiita-1.07M huggingface dataset:
[2022年]初心者におすすめのPython書籍(参考書)

初心者におすすめのPython書籍を紹介します。
プログラミングやIT系の勉強するときはKindleや電子書籍で勉強するのがおすすめです。
***
[Pythonで学ぶあたらしい統計学の教科書 第2版[Amazon]](https://amzn.to/3zwF5wL)
![a1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702119/a5ea79e1-ceb0-8583-5aca-9997e6455aea.jpeg)
統計学の基礎から統計モデリング、機械学習の入り口までしっかり学べる！
- 第1部　統計学をはじめよう
- 第2部　PythonとJupyter Notebookの基本
- 第3部　記述統計
- 第4部　確率と確率分布の基本
- 第5部　統計的推定
- 第6部　統計的仮説検定
- 第7部　統計モデルの基本
- 第8部　正規線形モデル
- 第9部　一般化線形モデル
- 第10部　統計学と機械学習
***
[Kaggleで磨く 機械学習の実践力[Amazon]](https://amzn.to/3NMzUNG)
![aa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702119/3a28b6de-0328-6551-44db-9604e0afa2b3.jpeg)
Kaggleは誰でも気軽に参加できるデータ分析の競技コンペです。
コンペで試した技を、実務に応用する――そのシナジーにより、みるみる実力が付きます。
- 第I部　分析実務とKaggle
  - 第1章　実務に必要なスキルとは
  - 第2章　Kaggleの概要
  - 第3章　Kaggleを学習ツールに
- 第II部　機械学習の進め方
  - 第4章　ベースライン作成
  - 第5章　特徴量エンジニアリング
  - 第6章　モデルチューニング
- 第III部　実践例
  - 第7章　2値分類のコンペ
  - 第8章　回帰問題のコンペ
  - 第9章　データサイエンティストの未来
***
[Python自動化簡単レシピ[Amazon]](https://amzn.to/3ttLbdQ)
![aaa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702119/fadf7b63-79c6-29d4-aebb-b53fb720b1e9.jpeg)
ビジネス現場では、様々な業務でPythonが利用され始めています。
Pythonを利用すれば、非常に短いコードで、日々の業務を劇的に効率化できます。
日常業務でもよくありがちな面倒な業務をPythonを利用して自動化する手法をまとめています。
- Chapter1 Pythonで仕事を自動化
- Chapter2 Pythonの基本
- Chapter3 アプリの作成
- Chapter4 ファイルの操作
- Chapter5 テキストファイルの検索・置換
- Chapter6 PDFファイルの検索
- Chapter7 Wordファイルの検索・置換
- Chapter8 Excelファイルの検索・置換
- Chapter9 画像のリサイズ・保存
- Chapter10 音声や動画の再生時間
- Chapter11 Webデータの取得
***
[実践Data Scienceシリーズ ゼロからはじめるデータサイエンス入門[Amazon]](https://amzn.to/3xkXCJS)
![aaaa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702119/96336857-8427-f0f4-4999-e9cd1e4b40f4.jpeg)
RとPython両方学べる。コスパ最強の一冊！
- 第1部　データサイエンスのための準備
  - 1章　コンピュータとネットワーク
  - 2章　データサイエンスのための環境
  - 3章　RとPython
  - 4章　統計入門
  - 5章　前処理
- 第2部　機械学習
  - 6章　機械学習の目的・データ・手法
  - 7章　回帰1（単回帰）
  - 8章　回帰2（重回帰）
  - 9章　分類1（多値分類）
  - 10章　分類2（2値分類）
  - 11章　深層学習とAutoML
  - 12章　時系列予測
  - 13章　教師なし学習
- 付録A　環境構築
***
[実践Data Scienceシリーズ Pythonではじめるテキストアナリティクス入門[Amazon]](https://amzn.to/3tuQ0U2)
![aaaaa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702119/457d13cf-ea63-eb90-31e1-ca30dce8777b.jpeg)
基礎技術と分析アプローチがわかる入門書の決定版！
- 第I部　テキストアナリティクスの基礎
  - 第1章　テキストアナリティクスことはじめ
  - 第2章　プログラミングの補足知識
  - 第3章　環境構築
  - 第4章　基礎技術
- 第II部　テキストアナリティクスの実践
  - 第5章　データ収集
  - 第6章　観光テキストの解析
  - 第7章　金融・経済テキストの解析
  - 第8章　ソーシャルメディアテキストの解析
- 第III部　応用技術・発展的な内容
  - 第9章　実践的なテクニック
  - 第10章　深層学習技術
  - 第11章　環境構築の要らないテキストアナリティクス
- 付録　本書で利用するPythonライブラリ
***
>他の記事
・[[2022年]おすすめ機械学習書籍(参考書)](https://qiita.com/metimeti/items/ad39b4a63e73e841ebb7)
・[[2022年]オライリーおすすめ書籍1(参考書)](https://qiita.com/metimeti/items/8ac3bfbdbde550e07d77)
・[[2022年]オライリー書籍ランキング1(O'Reilly)](https://qiita.com/metimeti/items/a349a5b7b521414c9e5a)
・[[2022年]初心者におすすめのPython書籍(参考書)](https://qiita.com/metimeti/items/85a92f9d5331b558bd9e)
Pythonを無料で学習！？

## Pythonを無料で取り組むことができる？
Pythonの環境構築を超簡単に取り組むことができる。
それは**google drive**を使用する方法である。

google driveのマイドライブを開いた状態から
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1034521/490d7118-d21a-ba0e-9961-67cf0242cfe9.png">

※一部写真の切り取りで分かりにくくてすいません💦



上記写真の新規を押して「その他」→「**Google Colaboratory**」を選択。
「**Google Colaboratory**」がない場合は、アプリを追加から追加する。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1034521/6e43c14e-61c5-860d-aa5f-b49ea65bc08b.png">


そうすると下記のようなアプリを取得することができる。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1034521/89f2b42d-0b3c-4bff-b4cc-e2de52ef8435.png">


これで環境構築が取得でき、Pythonを無料でできる環境は構築できる。
JavaGoldSE8に受かったので(前編)

# まず初めに
3部構成で読んでいただきたい。
理由としては、ただ単にスクロールが面倒なのと記事ごとで書いている内容を差別化させたいからだ。

[中編(試験に際して、覚えといたほうがいいこと)へ](https://qiita.com/Zombie_PG/items/6d0ee864157fa7ab23ed)
[後編(おそらく筆者の間違えた問題)へ]()

本章では以下を主要トピックとして扱う
・当日に必要なもの
・受験前について
・結果
・筆者の実力
・本について

# 【当日必要なもの】
・身分証2点
→筆者は運転免許証と保険証にした。マイナンバーとかでもいいのかな??

・夏場なら上着が必要
→前もって調べた結果、上着が必要とのことでZARAの上着を着ていったが、回収された。(型番調べ方わかりませんでしたすいません。)
明確な定義はないらしいが、**ジャンパー、コート**はだめらしい。
仕方なく、半そでで受けるようになったがクーラーガンガン効いていて寒かった。凍えてた。でも係員の人に言ったら調節してくれた、嬉しい。
→試験後に言ったら、ポケットの中身さえチェックすれば持ち込んでもよいよ！ということでした・・・

# 【受験前】
・oracle個人情報入力について
→筆者は心配性故、住所の書き方(英語版)をくまなく検索した。
→多分正規の書き方が一番いいだろうけど、筆者は結局ローマ字で平たく書いた。

# 【JavaGoldを受けた結果】
まず、本番の合格点は85%であった。[ツイッター](https://twitter.com/Zombie_PG/status/1535543980619751426?s=20&t=rFE02QjGtk-_ZB6rBJ-mPQ)にも乗っけたが、以下の画像を参照していただきたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748491/087ec81c-188b-40ac-cec8-743a1e39d400.png)

<font color="Red"> 85問で85%ということで10問少し落としている。
再受験レポートによりどんな問題を落としたのかは明瞭なため、後述する。</font>


# 【筆者の実力(?)】

①４大情報卒(Fラン)
①新卒で入った会社で8月にJavaSilverSE8(68% ボーダー65%)に合格
→JavaGoldの書籍を買ったが、自宅に環境を立てるのが面倒なのとラムダ式の動きがみただけじゃわからなくて断念。
→ちなみにそれまでは困ったら[paiza](https://paiza.io/ja)様にお世話になっていました。
③現在：PHP1.5年 Java1年、その他もろもろで今年4年目

# 【買った本の紹介】
まず、筆者は各本及び黒本付属のPDFを心配性なので**三周**解きました。

## ①黒本
絶対的に必要な本だと思います。
ベンダー資格を取るにあたって、重要な役割を果たしている本ですが全体的な大枠をつかむことができます。
この本の問題自体も非常に参考になりますが、解答もかなり参考になります。
本番の出題傾向も大きかったです。

## ②黒本(付属PDF)
このPDFの存在に受験日の3日前に気づきました。
結果から申し上げると、この問題は絶対にやるべきだと思います。
黒本と同じくして、本番では類似問題が多数出てきた気がします。
最後の最後に実力試しで解くのがいいと思います！黒本同様、解答もめっちゃ参考になります！
※ちなみに46/85でした。筆者は答え合わせしてる時、自信を喪失しました。

## ③紫本
教科書みたいな本。開発環境がある人でもない人でも書いてある挙動がなんとなくわかるようになっている。
黒本をサラッと解いた後に読んだので、特にスレッド回りが勉強になったのを覚えている。
絶対的に必要かと言われると、筆者の中では優先度は低い。があっても損はない。

## ④白本
筆者的には必要な本だと思っている。
電車の中やスキマ時間に有効的に使用することができた。
上記の各本と違って、1問1答形式になっており、自宅でがっつり詰め込んだものの復習のために使った。
問題量は豊富で
・ポリモーフィズムに係る問題
・JDBCの問題
・try-with-resources
・ラムダ式(ストリームAPI)
に関しては不安の払拭につながった。

## ⑤本に関する総括
優先度的には
**黒 > 黒PDF > 白 > 紫**
だと思っている。
正直、黒本だけでも合格できる人は多いんじゃないかなという印象。

**本については以上である**
ちなみに今回、筆者がJavaGold取得に要した時間は通勤時とかすべてもろもろ入れるなら350h~400h前後と思われる。

[中編(試験に際して、覚えといたほうがいいこと)へ](https://qiita.com/Zombie_PG/items/6d0ee864157fa7ab23ed)
[後編(おそらく筆者の間違えた問題)へ](https://qiita.com/Zombie_PG/items/bbe660ccae716879f92f)
SASE とは

## 勉強前イメージ

セキュリティのなんとか？

## 調査

### SASE とは

Secure Access Service Edge の略で、サシーと読みます。
SASEは2019年にガートナーが提唱したネットワークのセキュリティモデルです。

従来のセキュリティはセンターを中心として、内部ネットワークは安全・外部ネットワークは危険という前提で対策がされていますが
リモートワークが普及し、クラウドを中心とした業務を実行するということが多くなりました。
ネットワークとセキュリティの機能をクラウド上も含めて個々の働き方に合わせてどこからでも接続できるように提供するのがSASEです。

### SASEのメリット

- パフォーマンスの向上

ネットワーク経路がシンプルになるので
複雑な構造よりはパフォマンスが向上します。

- 複雑さの解消

単一のプラットフォームで暗号化した上でセキュリティ機能を提供するので
いろいろなサービスを使うより複雑さが解消されます。

### SASEを実現するための要素

- SWG(Secure Web Gateway)

セキュリティ機能をクラウドサービスとして提供するもの。
SWGを経由してwebにアクセスすることでウイルスからの感染リスクを低減します。

- SD-WAN(Software Defined Wide Area Network)

基本的には複数拠点をつなぐには閉じたネットワークとしてWANで構築します。
それをソフトウェアで構築したものがSD-WANです。
一元的に管理し、パフォーマンスの向上を図ります。

- CASB(Cloud Access Security Broker)

SASEの中心的な機能で、複数のクラウドサービスのセキュリティポリシーを一元管理します。
利用状況や制御、データセキュリティや脅威防御の機能によって [シャドーIT](https://qiita.com/miyuki_samitani/items/e731054526ca7e845c29) を防ぎます。

- ZTNA(ゼロトラストネットワークアクセス)

[ゼロトラスト](https://qiita.com/miyuki_samitani/items/5bfb9b7ae2eb7a36ad57) の考え方に基づいてネットワーク環境を提供するサービスで
通信のたびに認証を行います。

- FWaaS(Firewall as a Service)

クラウド型のfirewallでです。
IPSやアプリケーションの制御も備えたNGFWもあります。

## 勉強後イメージ

聞いたこともなかった...
リモートワークが増えていってるけど、環境とかはすぐに難しそう

## 参考

- [SASEとは何かをわかりやすく解説する ゼロトラストでセキュリティ・ネットワーク製品統合の意義とは](https://www.sbbit.jp/article/cont1/60582)
- [意外と知らない？ITトレンド用語](https://www.ntt.com/bizon/glossary/e-s/sase.html)
【AWS】AWS Certified Advanced Networking - Specialty 合格体験記 - 2022年6月12日

# AWS ANSについて
ネットワーキングの資格は専門知識の分野に属する資格になります。
※赤枠が取得済みの資格になります。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512673/8e70fdab-476f-9dd1-b211-4390b4767685.png)

# 結果
2022年6月12日に受験し、無事「合格(835点)」でした。
![スクリーンショット (21)_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512673/7f8e1525-6a8c-4bfa-4448-e3a74357832d.png)

# 勉強方法
[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)の有料会員になって
#01-#26を4周しました。なぜその答えになるのか、間違いの選択肢はなぜ間違いなのかを深堀していきました。
5/16に勉強開始、6/12に試験を受けてきたので約１ヶ月の勉強期間です。

# 総評
65問の選択問題が出ました。
2022/7/11に問題が最新化することもあり体験記や各問題集の対応が揃っているうちに
受験しようと勉強を進めました。
※少し問題が古いので今のベストプラクティスと比べるとあれ？って思う問題や選択肢もあります。

AWS公式サイトでは「ネットワークソリューションのアーキテクチャの設計と実装に 5 年間の実践的な経験がある人間が対象」とされていましたが、体感としては"AWSのネットワーク"がメインなので、
サブネットマスクの計算やBGPなどネットワークの基本がわかっていれば、
あとはAWSの範囲になるのでAWSサービスの勉強になりますが、メインはハイブリッド環境での
DirectConnect関連が多かったように感じます。

次回は下記3つから選んで挑戦しようと思っていますが、少し休みを挟みたい、、
・Certified DevOps Engineer - Professional
・Certified Database - Specialty
・Certified Security - Specialty
Ruby on Railsの環境を構築する際のNginx設定ファイルのコマンド及びコード理解

## なぜ記事を書こうと思ったか
  Nginx 用の設定ファイルを作成する際にコマンド及びコードの理解を備忘録として残すため。

## default.confのコマンド説明
default.conf
```
upstream puma {
    server app:3000;
  }

server {
    listen 80;
    server_name localhost;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    root /app/public;

    location @puma {
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_pass http://puma;
    }

    location / {
      try_files $uri @puma;
    }

    location ~ ^/(assets|packs)/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
    }

    location = /favicon.ico {
      access_log off;
      log_not_found off;
    }
    
    location = /robots.txt  {
      access_log off;
      log_not_found off;
    }

    error_page 404 /404.html;
    location = /404.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /500.html {
    }
}
```

  以下にコマンド及びコードの解説を致します。
- `server app:3000`
upstreameでpumaグループを定義、個々のサーバーに　app:3000を設定

- `listen 80`
デフォルトでは、 Nginx HTTP サーバーは受信接続を待機し、標準のWebポートを表すポート 80 にバインドする。

- `server_name localhost`
ホスト名を指定

- `access_log /var/log/nginx/access.log` `error_log /var/log/nginx/error.log`
access_logとerror_logのパス指定

- `root /app/public`
ドキュメントルートを指定

- `location`
locationはURI毎に異なる設定をできるようにする

- `proxy_set_header`
プロキシーサーバに送られるリクエストヘッダの フィールドを再定義、あるいは追加する。

- `proxy_pass http://puma`
リクエストをHTTP プロキシされたサーバに送る

- `try_files $uri @puma`
左から順に実体ファイルが存在しているかどうかを探し、あればそのままそのファイルを参照してくれる

- `gzip_static on`
圧縮していない物を圧縮し、既に圧縮済みのファイル(e.g. xxx.js.gz)があればそれをそのまま配信する

- `expires max`
クライアントキャッシュの有効期限設定

- `add_header Cache-Control public`
下位のレベル(location)にadd_headerを設定した場合、上位のレベル(server)のadd_headerは破棄される。
拡張子 gif、jpeg、jpg、png、ico、svg、css、jsのファイルをキャッシュする

- `access_log off` `log_not_found off`
アクセスログ、エラーログを捨てる

- `error_page 404 /404.html`
エラーページを作成する。

## 最後に
  何か間違っている所や気になった事があれば、コメントいただけると嬉しいです。

## 参考記事
- [Nginx+Rails6.0+MySQL8.0+Adminer：docker-compose で rails new | Zenn | 北山淳也](https://zenn.dev/junki555/articles/13da16e4f10c9dee2bb9)
Nuxt.js + TypeScriptにて、useAsync + $axiosで受け取ったresponseの型判定を行う方法

axiosのresponseは型がanyになってしまう...
その問題を解決するための方法です!
```vue
<template>
    <div>
        <h1>記事一覧</h1>
        <ul>
            <li v-for="post in posts" :key="post.id">
                {{ post.title }}
            </li>
        </ul>
    </div>
</template>

<script lang="ts">
import { defineComponent, useAsync, useContext } from '@nuxtjs/composition-api';

// 対象の型
type Post = {
    userId: number;
    id: number;
    title: string;
    body: string;
};

// ここで型ガード!!
const implementsPost = (arg: any): arg is Post => {
    return arg &&
        typeof arg.userId === 'number' &&
        typeof arg.id === 'number' &&
        typeof arg.title === 'string' &&
        typeof arg.body === 'string';
}

// ここでは配列の型ガード!!
const implementsPosts = (args: any[]): args is Post[] => {
    // 配列1つ1つに型がマッチしているか判定
    return args.every((arg: Post): boolean =>
        implementsPost(arg)    
    );
}

export default defineComponent({
    setup() {
        const { $axios } = useContext();
        const posts = useAsync<Post[]>(() =>
            $axios
                // $getでPost[]が返ってくる予定
                .$get("https://jsonplaceholder.typicode.com/posts/")
                .then(response => {
                    // ここでresponseの型チェック!!
                    if (implementsPosts(response)) {
                        return response;
                    } else {
                        throw new Error('responseの型がPost型と異なります。');
                    }
                })
        );

        return {
            posts
        };
    },
})
</script>
```
もっときれいに書けそうな気がするけど...
間違っている点・見づらい点などございましたら、お手数ですがご教示いただければ幸いです！
【SpringBoot】開発環境作成（プロジェクト作成）

SpringBootの開発環境作成をしていきます。

## 作成内容
**①Springプロジェクト作成**
[②BitBucketプッシュ](https://qiita.com/nmaolks/items/43dc670b6184d643c0b1)
③VPSにデプロイ
④Jenkins自動デプロイ

## プロジェクト作成
Web（Spring Initializr）もしくはSTS（SpringToolSuite）を使ってプロジェクトを作成します。
今回はWebで作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/0560f39f-b5e7-73ec-9cf4-fbc056b791bc.png)

依存関係は以下の3つです。
・「DevTools」は開発時、ソースコードに変更があれば自動で再起動
・「Spring Web」はWeb開発ツール
・「Thymeleaf」テンプレートエンジン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/f35eb959-f5da-8d6b-46ba-9822c6f75864.png)

Ecripseでインポートする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/c15a2f96-7ab6-a8e1-8d1e-3768d2eac9ed.png)

追加するのは以下の3点です。
・`MainController`　クライアントからのリクエストを受け取りHTML返却
・`Index.html`　画面に渡すテンプレートファイル
・`application.yml`　`.application`を`.yml`に変更、Portを80に設定。（デフォルト:8080）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/b9dcafdd-7c35-b124-3500-d403f0657913.png)

`"/"`にリクエストでHTML返却します。
```java:MainController
@Controller
public class MainController {

	@GetMapping("/")
	public String index() {
		return "index";
	}
}
```
返却されるHTMLです。Hello Worldという文字列を返します。
```html:Index.html
<!DOCTYPE html>
<html lang="ja">
 <head>
 <meta charset="utf-8">
 <title>Hello World</title>
 </head> 
 <body>
  <h1>Hello World</h1>  
 </body>
</html>
```
HTTPの場合PORT80で設定されている為、デフォルト:8080を80に変更しています。
```yml:application.yml
server:
  port: 80
```

SpringBoot起動後、`localhost`で以下画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/deb3a09a-a4b1-af96-2b99-8480e002ee3b.png)
cscの作法 その183

# 概要
cscの作法、調べてみた。
managed directxやってみた。
directsound、やってみた。

# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v2.0.50727;%PATH%

>csc /platform:x86 /r:"Microsoft.DirectX.dll" /r:"Microsoft.DirectX.DirectSound.dll" ds0.cs

```

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;

namespace mdx
{
	public partial class Form1 : Form {
		private Device _device = null;
		private SecondaryBuffer _buffer = null;
		public Form1() {
			this.Text = "DirectSound";
			this.Load += new EventHandler(this.Form1_Load);
			this.Closed += new EventHandler(this.Form1_Closed);
			Button btn1 = new Button();
			btn1.Location = new Point(140, 40);
			btn1.Size = new Size(80, 20);
			btn1.Text = "START";
			btn1.Click += btn1_Click;
			Controls.Add(btn1);
			Button btn2 = new Button();
			btn2.Location = new Point(140, 110);
			btn2.Size = new Size(80, 20);
			btn2.Text = "STOP";
			btn2.Click += btn2_Click;
			Controls.Add(btn2);
		}
		private void Form1_Load(object sender, EventArgs e) {
			try
			{
				this._device = new Device();
				this._device.SetCooperativeLevel(this, CooperativeLevel.Priority);
				this._buffer = new SecondaryBuffer("C:\\Users\\user\\01.femal.wav", this._device);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}
		private void Form1_Closed(object sender, EventArgs e) {
			if (this._buffer != null)
			{
				this._buffer.Dispose();
			}
			if (this._device != null)
			{
				this._device.Dispose();
			}
		}
		private void btn1_Click(object sender, EventArgs e) {
			if (this._buffer != null)
			{
				this._buffer.SetCurrentPosition(0);
				this._buffer.Play(0, BufferPlayFlags.Default);
			}
		}
		private void btn2_Click(object sender, EventArgs e) {
			if (this._buffer != null)
			{
				this._buffer.Stop();
			}
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
OSのロケールが日本語だと、PlayFrameworkのテストが失敗する人たちへ捧ぐ

現在の main ブランチ (a06ddb0) にて、OSのロケールが日本語だとテストが失敗するようです。

```
% sbt -error test
...(省略)
[error]     x when it is located in a subform (and sub-subform) and returns an error it should automatically prefix the error key with the parent form field (45 ms)
[error]      '0 から 1 の間のサイズにしてください' != 'size must be between 0 and 1' (FormSpec.scala:1507)
[error] Actual:   0 から 1 の間のサイズにしてください
[error] Expected: size must be between 0 and 1
[error]     x when it is located in a subform (and sub-subform) and returns an error it should automatically prefix the error key with the parent form field (14 ms)
[error]      '0 から 1 の間のサイズにしてください' != 'size must be between 0 and 1' (FormSpec.scala:1507)
[error] Actual:   0 から 1 の間のサイズにしてください
[error] Expected: size must be between 0 and 1
...(省略)
[error] Failed: Total 175, Failed 2, Errors 0, Passed 173
[error] Failed tests:
[error] 	play.data.CompileTimeDependencyInjectionFormSpec
[error] 	play.data.RuntimeDependencyInjectionFormSpec
[error] (Play-Java-Forms / Test / test) sbt.TestsFailedException: Tests unsuccessful
```

ベーススペックの `FormSpec.scala` に定義されたテストで失敗しているようです。

余談ですが、スペックの継承って結構難しいなと思いました。以前仕事でそういう仕組みを作ったことがあるんですが、指数関数的にスペック数が増えるので、管理が大変でした。。

# 前提

## OS

macOS

## Shell

zsh

## locale

```
% locale                                           
LANG="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_CTYPE="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_ALL=
```

日本語ロケールです。

# ロケールを変更する

Java ベースのソフトウェアはロケールの変更方法が複数あって、かなり戸惑いました。

## (NG) LC_ALL を変更する

```
% LC_ALL=C sbt test
```

OS のロケール設定をいじる方法です。sbt より手前に `LC_ALL=C` とすることで、英語のロケールになります。が、sbt ではこれだと反映されませんでした。

## (NG) システムプロパティを設定する

```
% sbt -J-Duser.language=en -J-Duser.country=US test
```

システムプロパティを設定します。JVM に設定を渡すには `-J` が必要です。しかしながら、これも反映されませんでした。

## (OK) JAVA_TOOL_OPTIONS を設定する

```
% JAVA_TOOL_OPTIONS=-Duser.language=en sbt test  
```

https://www.gwtcenter.com/acquiring-and-setting-locale

`JAVA_TOOL_OPTIONS` 環境変数に設定することで反映されました。sbt の出力を見ていると、こんな出力もあったので、なんか認識されているようです。

```
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en
```

# まとめ

ロケールの変更で困ったら `JAVA_TOOL_OPTIONS` に設定しましょう。
ダイアログの角を丸める方法

# はじめに
ダイアログの角を丸めるケースが比較的多い印象なので、備忘録的にまとめておこうと思います！

# 丸める方法
ダイアログの角を丸めるには、styleを使用します。
styleに角を丸める為のdrawableを設定する必要があるので、まずはdrawableを作成します。

```xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorWhite"/>
    <stroke android:width="1dp"
        android:color="@color/colorBlack"/>
    <corners android:radius="8dp"/>
</shape>
```
上記のように背景色や枠などの定義も可能なので、必要に応じて設定すると良いと思います。
次にstyleに定義します。

```xml
<style name="DialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
   <item name="android:windowBackground">@drawable/bg_dialog</item>
</style>
```

上記を定義したら、最後に設定したいダイアログの引数に作成した上記を設定します。

```kotlin
val builder = AlertDialog.Builder(requireContext(), R.style.DialogStyle)
```
これで設定は以上になります、ダイアログが角丸になっているかと思います。

# さいごに
styleを通して設定すれば比較的柔軟に設定が可能です。
こういった対応をスマートに解決していく為に、どんどん記事にしておこうと思います。
統計学学びなおし：２

# 統計学学びなおし

[こちら](https://bellcurve.jp/statistics/course/18766.html)を参考に、統計学を学びなおしていきます

## Step0 初級編1-2 
### まとめ
・集計表を作る際はいくつかの守りごとを守る
（適当に数値を並べない、単位を書かない　等）
・グラフには様々な種類がある

今回の内容も、基本的にすべてサイト内に書いてあることがすべてである。
ただ重要なポイントも数多く書かれている。
特に、この「度数」という言い方はのちほどまで長く見ることになるので
しっかりと理解しておいてほしい

以下、+αの内容なので流したい人は流してもらって全然問題ない

## グラフを書く際
今回の内容はグラフについては簡単に触れられていたが、グラフの書き方に関しては
触れられていなかった。
簡単に、pythonを用いてグラフをかける方法を紹介しておこうと思う。

### matplotlibを用いてグラフを簡単に記載する
グーグルコラボラトリー、もしくはanaconda、または普通のpython3を用いることで、今回出てきたグラフに関しては記載することが可能である。

#### いろんなグラフの書き方
```python:棒グラフ
from matplotlib import pyplot
x = [x for x in range(1,6)]
y = [y*10 for y in range(1, 6)]
pyplot.bar(x,y)
```
以上、先ほど挙げたプラットフォームで真似してみると棒グラフが記載できる。
（なぜかグラフの保存がうまくいかないため、各自試してみてほしい、コラボラトリーめ...）

同じように、matplotlibには円グラフを書くための関数なども用意されている。
```python:棒グラフ
from matplotlib import pyplot
y = [y*10 for y in range(1, 6)]
pyplot.pie(x,y)
```
以上を試すと棒グラフ同様、円グラフが記載できる。
ぜひ試してみてほしい。
C++11 or later で文字列ID的なのを実装したいメモ

## 背景

組み込み用とか, 言語パーサーなどで特定の文字列の ID 表現をもたせたい.
文字列もメモリに保存したい(`string_view` 単体は対応するメモリを持たないので今回の用途に向かない)

`"bora"` -> 1
`"dora"` -> 2

とか.

USD(Universal Scene Description) でいう TfToken: https://graphics.pixar.com/usd/release/api/class_tf_token.html

## 方法

* hash を計算するようにする
* hash から ID 割当
* 対応するメモリがなかったら確保
  * テーブルでストレージを持ったり
  * リファレンスカウントしたり

## foonathan/string_id

https://github.com/foonathan/string_id

ありがとうございます. とりあえずこれを使えばいいでしょう!

## 注意点

マルチスレッド環境では, メモリの管理では lock が必要になります.
多少メモリが増えてもいいのであれば, TLS(thread local storage)でやる手もあるでしょうか.
【Vue.js】createdとmountedの違いについて簡単に解説

# はじめに
Vue.jsで開発していて画面の初期表示はmountedを使うと良いと教えてもらったがよくわからなかったので、調べた内容を備忘録としてここに残しておきます。
また、createdとmountedの違いについても少し調べたため簡単にまとめておきます。
もし間違っている箇所があれば優しく指摘していただけると幸いです。

# 結論
- created：Vueインスタンスが生成され、データが初期化された後に実行される
        　　　　（DOMはまだ生成されていないので、DOM操作はできない）
- mounted：VueインスタンスがDOMにマウントされた後に実行される
        　　　　（DOM生成された後なのでDOM操作ができる）

## created
ここではまだDOMが生成されていないため、DOM操作はまだできない。
ただし、データは初期化されているため、リアクティブデータやメソッド等を参照することは可能。

```vuejs:App.vue
<script>
new Vue({
  el: 'app',
  data() {
    return {
      styles: {
        width: '100vw',
        height: '100vh'
      }
    }
  },
  created () {
    // created内で実行したい処理を記述
    console.log('width:' + this.styles.width)
    console.log('height:' + this.styles.height)
    // width: 100vw 
    // height: 100vh
  }
});
</script>
```

## mounted
インスタンス初期化時、DOMが生成された後に実行されるため、DOM操作ができる。

```vuejs:App.vue
<script>
new Vue({
  el: 'app',
  data() {
    return {
      value: 'Value'
    }
  },
  mounted() {
    // ここにmounted内で実行したい処理を記述
  }
});
</script>
```

**ただし**
mountedの段階で全ての子コンポーネントもマウントされているとは限らない。
全ての子コンポーネントがレンダリングされるまで待つ場合は$nextTickを使うと良い。

```vuejs:App.vue
<script>
new Vue({
  el: 'app',
  data() {
    return {
      value: 'Value'
    }
  },
  mounted() {
    this.$nextTick(() => {
    // ここにmounted内で実行したい処理を記述
    // 子コンポーネントもマウントされてから実行される
    });
  }
});
</script>
```
自作LispにFFT/NTT乗算を組み込んだ話

# はじめに
しばらく前に自作のEasy-ISLispにFFTによる乗算を組み込んでみました。巨大数になると計算がうまく行われず複素数を使ってるから誤差かな？と誤差のないNTTに取り組みました。FFTでうまくいかなかった原因は誤差ではなく単なる私の勘違いによるバグでした。ビットリバースで12bitで計算してました。そりゃ、ダメでしょうよ。ともあれそんなきっかけで剰余環を利用したNTTによる高速乗算に取り組み、動作するところまでこぎつけました。後日のために記録しておこうと思います。

# 初等整数論のお勉強
数十年前に買った高木貞二先生の「初等整数論講義」を引っ張り出してきて、原始根のあたりを読み直しました。この本には剰余環のことは書いてないようですが、どうもNTTというのは剰余環という整数論の理論を応用しているようです。下記のページの記事がとても勉強になりました。実装例も示されています。

離散フーリエ変換と数論変換 (6) NTT の高速化
https://mathlog.info/articles/2661

うんうん、なんとなくわかったような気になれました。要するに複素数でやっていた回転因子の計算を整数の剰余でやればいいのでしょう。それなら普通のFFTでやったバタフライ計算のコードに手を加えればできるのでは？とやってみました。それほど甘くはありませんでした。どうもうまくいきません。バタフライ計算の順序が先日勉強したあのわかりやすい動画の順序と逆になっているのでした。

【フーリエ解析05】高速フーリエ変換(FFT)ってなに？内側のアルゴリズムを解説！
https://www.youtube.com/watch?v=zWkQX58nXiw&t=39s

手計算であれこれと試行錯誤してみたのですがどうもわかりません。複素数のときには単位円でπ回転すると-1で都合がよかったのですが、剰余を使った１の原始ｎ乗根ではそれは使えません。上記の説明のとおりにやってみることとしました。

# 理屈はわかったけども
理解したつもりで実装を作り始めたのですが、やってみてハマったことが多々ありました。以下、列挙しますと・・・

### 桁そろえ
入力データであるベクトルを表す配列にどのようにデータを配置するのか？　半分にわけて前半に乗数のデータ、後半は０で埋めないと正しく計算されません。

### 空いた領域は？
乗数を前半部分に置いたとして、空いている領域はどうするのか？　単純に０で埋めておけばOKでした。

### 遅いんだけど
実装が素朴すぎました。回転因子に相当する計算をその都度mod計算で冪乗を計算してました。計算前にあらかじめ計算しておいたら速くなりました。

### 桁数が多くなると変な値がでるよ
最後はこれに悩まされました。なんのことはないビットリバースの計算をたったの12bit分だけしか計算していませんでした。最初は小さいデータで計算実験をしていたので32bitフルに使うなんて考えていませんでした。

# 性能評価
どうやらまともに動き始めたようでしたのでベンチマークをとってみました。ntt*という関数名でFFT乗算を計算しています。従来の筆算アルゴリズムの＊関数と比較してみました。

```lisp

Easy-ISLisp Ver2.47
> (load "tests/big.lsp")
T
> (time (bigtest1 100))
Elapsed Time(second)=1.274482
<undef>
> (time (bigtest2 100))
Elapsed Time(second)=31.525318
<undef>
> 

(defglobal a (expt 8 70000))
(defglobal b (expt 9 70000))

(defun bigtest1 (n)
    (if (= n 0)
        t
        (progn (ntt* a b) (bigtest1 (- n 1)))))

(defun bigtest2 (n)
    (if (= n 0)
        t
        (progn (* a b) (bigtest2 (- n 1)))))

```

おお！だいぶ高速になっています。数万桁どうしの乗算だと25倍ほど高速になっていました。

# 正しく計算できてる？
計算結果がおかしいのでは高速になっても意味がありません。brent-salaminのアルゴリズムで円周率1万桁を計算してみました。BIGNUMの桁数の和が100以上のときにNTT乗算を起動するようにしました。

```lisp
Easy-ISLisp Ver2.48
> (load "tests/pi.lsp")
T
> (pi-brent-salamin 10000)
314159265358979323846264338327950288419...
...
22955249887275846101264836999892256959688159205600101655256375574
> 
```

```lisp
This is SBCL 2.0.1.debian, an implementation of ANSI Common Lisp.
* (pi-brent-salamin 10000)
314159265358979323846264338327950288419...
...
22955249887275846101264836999892256959688159205600101655256375574
```
最初と最後は合ってます。たぶん大丈夫だよ。（大雑把な性格）

# GMPよ、あんたはすごいぜ！
Easy-ISLispでは1万行の円周率計算で5秒ほどかかっていました。NTT乗算を組み込みましたら3秒程度まで短縮されていました。ところがSBCLは1秒もかかりません。さすがです。GMPは世界一です。

# それでも作ってみたい
車輪の再発明といわれようがともかく自分でも作ってみたいのです。その昔、真空管でオーディオアンプを作ったことを思い出します。そりゃメーカー製のものを買ってきた方がコスパが圧倒的にいいのですけれども。あれから40年以上経って、相変わらず自作に拘っています。仕組みを理解したいのです。GMPを組み込んで・・・なんてのは自称Lisperの私のプライドに反するのです。

# 終わりに
最後まで駄文にお付き合いいただきまして誠にありがとうございました。実装はgithubに置いてあります。bignum.cの最後の方にNTT関係がまとめられています。コメントも英語でできるだけ入れておきました。後日のデバッグに備えるためです。よかったら実装の参考にしてみてください。

https://github.com/sasagawa888/eisl
Jetpack Compose 勉強記録その2 (Jetpack Compose チュートリアル レッスン:３)

Jetpack Compose 勉強記録その２です。

# 今回の内容

https://developer.android.com/jetpack/compose/tutorial?hl=ja

チュートリアルの続きをやっていきます。

今回はレッスン 3: マテリアル デザインをやっていきます

## テーマを設定
```MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialAppTheme{
                CardItem(Message("Android", "Jetpack Compose"))
            }        
        }
    }
```

MaterialAppThemeで囲うことによりテーマを設定することができます。

MaterialAppThemeはEmpty Compose Activity テンプレートで作成した場合はui.themeの中にあるTheme.ktの中にあります。

```　Theme.kt
@Composable
fun MaterialAppTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(colors = colors, typography = Typography, shapes = Shapes, content = content)
}
```

## マテリアルデータに設定してある色の設定

```MainActivity.kt
Image(
    painter = painterResource(R.drawable.ic_launcher_background),
    contentDescription = "picture",
    modifier = Modifier
        .size(50.dp)
        .clip(CircleShape)
        .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)

Text(text = message.name, color = MaterialTheme.colors.secondaryVariant)

```

``border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)``

こちらを追加することでImageに円の枠を作ることができます。


``color = MaterialTheme.colors.secondaryVariant``

こちらを追加することでTextの色を設定できます。


## styleの設定

```MainActivity.kt
Column {
    Text(text = message.name,
        color = MaterialTheme.colors.secondaryVariant,
        style = MaterialTheme.typography.subtitle2)
    Spacer(modifier = Modifier.height(12.dp))
    Text(text = message.body,
        color = MaterialTheme.colors.secondaryVariant,
        style = MaterialTheme.typography.body2)
}

```

``style = MaterialTheme.typography.subtitle2)``や``style = MaterialTheme.typography.body2)``でTextにstyleの設定をしてます。


## マテリアルデザインなViewの設定
```MainActivity.kt
Surface(shape = MaterialTheme.shapes.medium, elevation = 1.dp) {
    Text(
        text = message.body,
        color = MaterialTheme.colors.secondaryVariant,
        modifier = Modifier.padding(all = 4.dp),
        style = MaterialTheme.typography.body2
    )
}
```

``Surface``を追加することでTextViewを囲ったようなViewをつけることができました。角丸や影なども設定できるので使いやすいですね。
![Screenshot_20220612_173613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/8913df8e-c4c3-c733-26ae-117566133040.png)


## ダークテーマを有効にする
Jetpack Compose はデフォルトでダークテーマを処理できます。マテリアル デザイン カラーを使用した場合、テキストと背景は暗い背景に合わせて自動的に調整されます。
デフォルトで設定されているみたいです。
ライトテーマとダークテーマの色の選択はTheme.kt ファイルで定義するみたいです。

```MainActivity.kt
@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
    MaterialAppTheme {
        CardItem(message = Message("Colleague", "Take a look at Jetpack Compose, it's great!"))
    }
}
```

ダークモードのPreviewの表示方法です。
表示したい``@Composable``の上に設定をします。



以上です。

デザインがテーマで統一されているとかなり作りやすそうですね。
【Git】私たち、やり直しましょう？

未来のわたしのために最近覚えたやり直し方をメモ

## MR
今回のかなしい流れ
1. MRだす
1. 間違ってMerged
1. Revertで取消
1. 再MRの出し方が分からん！！！

### Revertとは
既存のコミットを取り消すためのコマンド

### 解決方法
もう１回Revertで、「取消」を取り消す！！

→って教えてもらったけど、そしたらMerged状態に戻ってしまうのでは…？
アドバイスをいただいただけで、まだ実践できていないので、自分でやって確かめたら再度記事を詳しく更新したい！！

## GitLab上のブランチを削除
GitLab>Branchで、ごみ箱マーク押す

## TESTブランチの作成
覚えきれないほどのコマンドやGUIがあるので、とにかく試してみたかったら開発中のブランチからブランチを作成する！
（開発中のブランチが一番開発が進んでいるので、その時点でブランチをきると開発中のブランチから派生してブランチを作成することができる）


## おまけ
### git pull origin master
定期的にやった方が良い
理由：MASTERブランチと開発ブランチの差分がどんどん開いていくから

### Mergedがおせない
コンフリクトが起きている場合がある
解決方法：git pull origin master→コンフリクト解消
【js】hasOwnPropertyメソッド

## hasOwnProperty()とは
オブジェクト自身が（継承されていない）、引数に指定されたプロパティを持っているかどうかを示す真偽値を返すメソッド。
インスタンス名.hasOwnProperty('検索したいプロパティ、メソッド名')の形。
例）`bob.hasOwnProperty('hello') // -> true or false` 

## inとは
inというキーワードを使うとプロトタイプチェーンを遡って、指定したプロパティ、メソッドがあるか真偽値を返す。
'検索したいメソッド名など' in インスタンス名の形。
例）`console.log('hello' in bob); // -> true or false`

### サンプルコード
```script.js

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    hello() {
        console.log('hello ' + this.name);
    }
}

const bob = new Person('Bob',18);



const result = bob.hasOwnProperty('hello');
console.log(result);// -> false。helloメソッドはprototypeプロパティ内のあるメソッドで、Personコンストラクター関数自身にはないのでfalse

console.log('hello' in bob);// -> true。inを使用すると、プロトタイプチェーンも遡って、該当のプロパティ、メソッドがあるか確認し真偽値で返してくれる。 

```

## Object.hasOwn()とは
参考：https://sosukesuzuki.dev/posts/stage-3-object-hasown/
>Object.hasOwn メソッドは、Object.prototype.hasOwnProperty()をObjectのスタティックメソッドにしたものだ。
つまり、次の２つのプログラムは同じ挙動になる。

hasOwnProperty()の上書きによる真偽値の変更や、Object.create(null)で生成されたオブジェクトにはhasOwnProperty()が存在しないなどの問題を、解決できるObject.hasOwn()。現段階で[ほぼ全ブラウザ](https://caniuse.com/?search=hasOwn)で使用できる点からこちらのメソッドを使用した方がよさそうです。

### サンプルコード
```script.js
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    hasOwnProperty(str){ // hasOwnProperty()の上書き
        return true;
    }
}

const bob = new Person('Bob',18);

bob.hasOwnProperty('hello'); // true ←
Object.hasOwn(bob, 'hello'); // false
```
初心者が在庫管理用のWebアプリをノーコードでちょちょいと作ってみた

皆さんこんにちは！食品会社のシステム部門で働いているAzarashiです。
皆さんの会社では在庫管理はうまくいっていますでしょうか？私の会社は食品会社ということもあり、原料や資材を始めとして多種多様な在庫を管理しなければなりません。もちろんそのための社内システムも存在しており、在庫管理にあたっている社員はそのシステムを駆使して日々在庫が不足しないように業務にあたっています。しかし、そうしたシステムを使えない（使うほどでもない）ごく一部の商品や備品の在庫管理はエクセルが使われていたり、単純に気づいたときに発注していたり、と少し管理がおろそかになっているものも存在しています。私の所属するシステムでもマウスやキーボード、LANケーブルの管理をしていますが、気づいたら在庫が無くなっており慌てて発注したということがありました。そこで、ちょっとした在庫管理に利用できるアプリの作成に取り掛かってみました。

出来上がったのはこちらになります。
https://scarce-silver-3595.glideapp.io/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/6ed50ae4-7e7a-a24a-53b9-b567ab1518a7.png)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/8bcb0a5c-c55c-8950-cdd1-ce0ece626b6d.gif" width=300>

トップ画面で各品目が表示され、タップすることで現在の在庫数がわかります。
また、出庫履歴を入力できるようになっており、出庫の度に現在庫数量が更新されるようになっています。

それでは、作成法をポイントを絞ってご紹介していきます。
## 使用ツール
**Glide**：アプリ開発ツールです。データベースをスプレッドシートで簡単に作成・管理できるためプログラミング言語やデータベースに関する専門的な知識がなくても利用することができます。

https://www.glideapps.com/



## 手順①：Googleスプレッドシートで在庫管理用シートを作成
今回はこのような在庫管理用のスプレッドシートを作成しました。
出庫履歴と入庫履歴は別シート入力できるようにし、在庫状況のシートでSUMIF関数を用いて各品目の在庫を計算するようにしています。

**●出庫履歴のシート(入庫履歴も同様)**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/bc7da947-e809-d5dd-20ff-912d68845b3f.png" width=300>
**●在庫状況のシート**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/3eb5d6f1-4617-7b8a-d0f8-807431115d84.png" width=500>
## 手順②：Glideでアプリ作成
### その①：プロジェクトの作成
Glideにログインしたら、まず【New project】を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/8b972e5a-909d-9718-6309-2b2b02c4ac36.png" width=500>
次に、【Name your project】の欄に作成するアプリの名称を入力します。
【Choose a Type】は【Glide App】を選択しておきましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/f9afb518-d614-3457-560e-f54c08b2b057.png" width=300>
次に、手順①で作成したGoogleスプレッドシートと連携するために【Select a source】で【Google Sheets】を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/32b283ce-7e58-8bcd-c725-a4b324eb1022.png" width=300>
### その②：別々のシートを連携させる
今回作成するアプリでは在庫状況の画面で出庫履歴や入庫履歴の内容を表示・編集したいのでGlideのData Editor画面でColumnを追加し、下記のように設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/3fd28a82-db15-fd67-9600-e9c9be60b610.png" width=500>
次にLayout画面でList Relationを選択し、出庫履歴・入庫履歴が表示されるように設定する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/c9c239da-6f78-6214-eee3-254ba0a490f4.png" width=500>
### その③：見た目を整える
ここまでの操作で必要な情報は表示されるようになりました。しかし、見た目がまとまっておらず、不要な情報も多いので、体裁を整えていきます。
今回は品目が見やすいように、在庫状況のStyleはTilesを使い、シートに対応して自動的に作られていた出庫履歴・入庫履歴のTABSは非表示にし、ユーザーが迷わないようにしています。


## 改善点
今回、このアプリを作成後にテスト稼働させ先輩社員に見てもらったところ、機能として在庫状況のアラート機能があった方が良いということと、未来の入庫予定が分かる方が良いとのアドバイスを受けました。この点についても少し調べたところ、Glide機能としてメール送信機能が使えそうだと思いました。しかし、この機能は無料では使えない機能のようで他の方法を模索中です。少し力技ですがRPA用ソフトなどを使用し、スプレッドシートを定期的に監視するというのも手かもしれません。

## 最後に
今回初めてGlideを使用してみましたが、簡単な操作ですぐにそれらしい見た目のものが作れてしまうことに感動しました。作成物は改善すべき課題もあり、すぐに実用化というレベルには到達していませんが、解決策を練り、実用に耐えるレベルのものが作成できるようにしていきたいものです。
【忘備録】Arbor3のノードのみを使ってプレイヤーの上下左右移動を可能にする。

# 完成像
Scriptsを書かずに、Arbor3のノードのみでプレイヤーを移動させて見たいと思います。
![move_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708142/d22a128f-3c0c-a6f8-7be1-180f83bc0b84.gif)
![sukusyo (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708142/0e96b64d-bb9e-96cf-28da-916aae93c92f.jpeg)

## 解説

まず、演算ノードでHorizontalとVerticalのGetAxisを取得、それをVector2に変換します。その値を実際にプレイヤーを移動させるために作ったノード、「SetVelocityRigidbody2d」の「Direction」に入れることで移動する方向を決定しています。
![sukusyo (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708142/c5644891-7ce6-bd35-0bc4-4e275ff47b93.jpeg)

ノードの起点には常駐ステートを使用します。キーの入力により先程取得したGetAxisどちらかの値が変化することで移動ノード、「SetVelocityRigidbody2d」に推移します。
![sukusyo (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708142/d16e2099-beb7-2954-627d-3ce7f18ea98b.jpeg)

最後にこのままでは移動し続けてしまうので、停止用のノードを作成しています。
![sukusyo (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708142/dbd742ac-f1e1-666f-f10a-796c7778aa18.jpeg)
### 最後に

移動するのにScriptsを書くのが面倒でノードを組んでみたのですが、普通にScriptsを書いた方が100倍早かったです。私のような思いをする人を二度と出さない為に、初めて記事を書いてみました。このノードよりも優れたノードの組み方をご存じの方は是非、教えてください。靴舐めます。
【js】bind,call,applyの挙動差異メモ

## bindとは
thisの参照先のオブジェクトや引数を指定できる。第一引数にthis参照先オブジェクト、第二引数以降は、関数に渡ってくる引数の値を入れられる。

## callとは
bindのようにthisや引数の参照先を変更できる。同時に関数を実行する。第二引数以降は、関数の引数の値を入れられる点もbindと同様。つまりcallとbindの違いはその場で実行されるかされないかのみ。

## applyとは
bindのようにthisや引数の参照先を変更できるが、同時に関数を実行する。第二引数に設定するのは配列。配列に渡された値が展開されて、関数の仮引数に渡っていく。

### サンプルコード
```script.js
function a(name,name2) {
    console.log('hello' + name + ' ' + name2);
}

//束縛したいオブジェクト
const tim = {
    key: 'value'
}

const b = a.bind(tim, 'Tim', 'Bob');
b();                    //bindを使ってthis参照先オブジェクトを束縛した場合は、このように関数式などに代入し、それを実行する必要がある。
a.call(tim, 'Tim', 'Bob');            //callを使って束縛した場合は、実行まで行われる。
a.apply(tim,['Tim','Bob']);           //applyを使って束縛した場合は、実行まで行われる。引数は配列   
```
💎 Crystal言語でも `eval` できる！ Anyolite 🟢🔴 がすごい

## はじめに

Crystal言語では `eval` を使うことができません。

もしもCrystal言語で `eval` を使わなければならないとしたら、そのためにはCrystalそのものを実行ファイルの中に組み込まなければならないからです。

Evalはバッドプラクティスとされることが多く、なるべく利用しない方がよいと言われています。しかし、Crystal言語を使っていると、Rubyのevalが恋しくなることがありますね。そんなときに、なんとmruby（やCRuby）をCrystalの実行ファイルに組み込むことによって、Crystal言語でもevalを実行できるようにしてしまう[^1]、というスゴいプロジェクトを見つけたので紹介します。


## Anyolite

https://github.com/Anyolite/anyolite

アニョライトって知っていますか？　私は知りませんでした。これはゾイサイトという結晶の中にルビーの結晶が含まれた宝石だそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/e7ebf2ae-3598-4918-e4fd-7c132426a036.png)

Google画像検索を見ると、アニョライトの雰囲気がわかると思います。結晶の中にRubyが埋め込まれているのです。まさに、このライブラリにふさわしいネーミングだと思います。

## 使い方

まず、shardsを利用してAnyoliteをインストールします。shards.ymlを編集して、anyoliteを追加します。

```shard.yml
dependencies:
  anyolite:
    github: Anyolite/anyolite
```

`shards install`

を実行すると、`lib/anyolite/third_party/mruby` に自動的にmrubyがコンパイルされて用意されるようです。（mrubyではなくCRubyを使うこともできるようです。）

例として、次のようなコードを書いてみます。Crystal側で、Kittyクラスを用意して、`Anyolite.wrap(rb, Kitty)` として、これをRuby側で呼び出せるようにしておきます。

```crystal
require "anyolite"

code = ARGV[0]

class Kitty
  def initialize(@n : Int32)
  end

  def mew
    puts "mew " * @n
  end
end

Anyolite::RbInterpreter.create do |rb|
  Anyolite.wrap(rb, Kitty)
  Anyolite.eval(code)
end
```

ビルドして、

`crystal build kitty.cr`

実行します。引数としてRubyのコードを与えます。

`./kitty "Kitty.new(n: 3).mew`

うまくいくと、

`mew mew mew `

と出力されるはずです。実行時にコードを評価してくれていることがわかります。Rubyの戻り値を利用することもできて、

```crystal
Anyolite::RbInterpreter.create do |rb|
  Anyolite.wrap(rb, Kitty)
  rv = Anyolite.eval(code)
  p Anyolite.cast_to_crystal(rv, Int32)
end
```

として、

`./kitty "Kitty.new(n: 3).mew; 6"`

とすれば、

```
mew mew mew 
6
```

と出力されます。

## 公式ドキュメント

https://anyolite.github.io/anyolite/Anyolite.html

https://github.com/Anyolite/anyolite/wiki

まだ使い始めたばかりで、全然わかっていないのですが、`eval` 意外にも、いろいろなマクロが用意されています。
Crystalのモジュール・クラス・メソッドをラップしてRubyから使ったり、変数・定数等を相互でやりとりしたり、Crystal側からRubyのメソッドやブロックオブジェクトを呼んだりすることもできるようです。

- `call_rb_block`
- `call_rb_class_method`
- `call_rb_method`
- `call_rb_method_of_class`
- `call_rb_method_of_object`
- `cast_to_crystal`
- `does_class_respond_to`
- `does_obj_respond_to`
- `eval`
- `get_cv`
- `get_gv`
- `get_iv`
- `get_rb_class_obj_of`
- `implementation`
- `link_libraries`
- `obtain_given_rb_block`
- `raise_argument_error`
- `raise_index_error`
- `raise_key_error`
- `raise_name_error`
- `raise_not_implemented_error`
- `raise_range_error`
- `raise_runtime_error`
- `raise_script_error`
- `raise_type_error`
- `referenced_in_ruby?`
- `self_in_rb`
- `set_cv`
- `set_gv`
- `set_iv`
- `wrap`
- `wrap_class`
- `wrap_class_method`
- `wrap_class_method_with_keywords`
- `wrap_class_with_methods`
- `wrap_constant`
- `wrap_constant_under_class`
- `wrap_constructor`
- `wrap_constructor_with_keywords`
- `wrap_getter`
- `wrap_instance_method`
- `wrap_instance_method_with_keywords`
- `wrap_module`
- `wrap_module_function`
- `wrap_module_function_with_keywords`
- `wrap_module_with_methods`
- `wrap_property`
- `wrap_setter`

ふだんは、もう少しよく理解できた段階でQiita記事に書くことが多いのですが、Anyoliteについては、Crystalでmrubyを使ってevalできるようになったということに感動したので、すぐに記事にしてしまいました。

この記事は以上でです。

[^1]: より正確には、Rubyのコードをevalできるようになる
Power Automateのクラウドフロー（DPA）からデスクトップフロー（RPA）を呼び出せるようにするときのポイント（Windows11版）

こんにちわ、 のりじ です。

デスクトップフロー（RPA）とクラウドフロー（DPA）を繋いで利用したい場合、個人的に色々引っかかったので備忘録的な記事です。

ちなみに、「Microsoft Power AutomateはRPAツール」と記載されたりしますが、これは厳密にいうと間違いです。  
Microsoft Power Autoamteは、DPA機能の「デスクトップフロー（Power Automate）」とRPA機能の「クラウドフロー（Power Autoamte for desktop）」両方の機能を持つ「プロセスオートメーション」というのを覚えていただけると嬉しいです！

# 1. クラウドフロー（DPA）からデスクトップフロー（RPA）を呼び出す方法の変更

デスクトップフロー（Power Automate for desktop）の前進である「UIフロー
のときから、[オンプレミスデータゲートウェイ](https://docs.microsoft.com/ja-jp/data-integration/gateway/service-gateway-onprem)で接続する方法があります。  
私もこれまではこの方法でやっていたのですが、以下の告知が公式Docsに出ました。

![pad001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/0022a772-a953-b8cc-628e-674e2b1a63d2.jpeg)

オンプレミスデータゲートウェイで接続する方法は6月30日で廃止になるので「コンピューター管理」に切り替えるように、とのこと。

- [ゲートウェイから直接接続に切り替える](https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/manage-machines#switch-from-gateways-to-direct-connectivity)

というわけで今後は「コンピューターの管理」を利用しましょう。

# 2. 「コンピューターの管理」を利用するときの注意点

「コンピューターの管理」を利用する方法ですが、まずは **有人（アテンド）RPA付きのユーザーごとのプレミアム プラン** を所有していることが条件になります。

- [Power Automate 価格](https://powerautomate.microsoft.com/ja-jp/pricing/)

このあと、古いバージョンのPower Automate for desktopを使用している場合は、最新版にアップデートする必要があります。（Power Automate 2.8.73.21119 以降のバージョンでのみ使用できるため）  
公式Docsに最新版への誘導URLがあるので参考にしてください。

- [コンピューターの管理](https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/manage-machines)

## 2-1. 利用したいPCのOSのエディションをチェック

Windows10もしくはWindows11を利用していれば、Power Automate for desktopの最新版をアップデートするだけで利用できるのですが…ここでポイントになるのが、**OSのエディション**です。

![pad002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/27551f4e-200e-3661-d9a9-dbf2920e9d95.jpeg)

「Win10 Home」および「Win11 Home」は、最新版のインストーラーを実行しても赤枠内の項目（ランタイムアプリのインストール）が表示されません。  
つまり、有人（アテンド）RPA付きのユーザーごとのプレミアム プランを取得しても「コンピューターの管理」が利用できないので注意してください。 

![pad003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/721b992f-80de-df6d-cecc-7feb9d0e9633.jpeg)

Windows11であれば、[設定] -> [システム] -> [バージョン]でOSのエディションが確認できます。

私は最近購入したPCでこれを試そうとして「なんでランタイムアプリがインストールできないんだろう？」と思ったら原因がOSのエディションでした…。（Win11 Home）

## 2-2. Power Autoamte for desktop（RPAのみ）を利用する場合

ちなみにPower Autoamte for desktop（RPAのみ）を利用する場合は、以下の要件を最低満たしていればPCで利用できます。

```

- Power Automate にサインインするための Microsoft 職場または学校アカウント

- システム要件:
Windows 10 Home、Windows 10 Pro、Windows 10 Enterprise、Windows 11 Home、Windows 11 Pro、Windows 11 Enterprise、Windows Server 2016、Windows Server 2019 または Windows Server 2022 を実行するデバイス  
※ARM デバイスはサポートされていません。
```

その他細かい「システム要件」についてはDocsを確認してください。

- [デスクトップ用 Power Automate の前提条件と制限](https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/setup)

このように、クラウドフローとつながず、RPA機能の「Power Autoamte for desktopのみ」を使いたい場合は「Win10 Home」および「Win11 Home」でも利用できます。  
クラウドフローと連携して利用したい場合は気をつけてみてください。

# 3. 最後に

既にデスクトップフロー（Power Autoamte for desktop）をバリバリに使ってる方たちは当たり前の情報だと思うのですが、自分的に地味にハマったので・・・。  
新しいWindowsマシンを購入するときはOSのエディションも気にしましょうね（泣）
三井寿「安西先生……！！Laravelでバリデーションがしたいです………」

# 安西先生「諦めたら、そこで堅牢なWebサイトの終了ですよ」

冗談は縦置き、さっそく本題です。

# `validate`メソッドを使おう

こちらの記事はLaravelドキュメントの[バリデーションの部分](https://laravel.com/docs/8.x/validation)の最低限の機能を分かりやすいようにかみ砕いたものになります。

「ドキュメントの表現が堅苦しくて分からないよ～」って方には丁度いいかと思います👍

それでは表題通り、Laravelでバリデーションを実装する方法をご紹介しましょう。

一番簡単なのはRequestオブジェクトが提供している`validate`メソッドを使うことです。

今回はこちらを紹介します。

# バリデーションって美味いん？

美味くはないですが、機能的にはかなり旨いです😋（全然上手いこと言えてない）

おさらいですが、バリデーションは「入力されたデータのフォーマットが正しいかを検証する」機能です。

入力必須の項目が空欄だったり、年齢のところに日本語が入ったり、メールアドレスのところにメールアドレスじゃないフォーマットの文字列が入ったりするのをバリデーションを挟むことで防いでくれます。

> 俺「バリデーションってなんやねん」

という方はこちらの記事も参考にしてみてください。

https://qiita.com/Sunasuna24/items/8592da9e7dbe3fd15a0f

# （準備１）routeの設定しよう

ここからは実際に簡単なLaravelのアプリを作成しながら、バリデーションの流れを見ていきましょう（ここからは主にドキュメントの内容）。

まずは投稿用のフォーム画面を表示するrouteとその投稿を追加するrouteをweb.phpに作成しましょう。

```PHP:web.php
use App\Http\Controllers\PostController;

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
```

Laravelが初めての方に説明すると、2行目の`GET`メソッドで投稿用のフォーム画面を表示するrouteで、`POST`メソッドはそれをDBに追加するためのrouteです。

# （準備２）Controllerを作成しよう

次は受け取ったデータを扱うためのコントローラーを作成しましょう！

一旦`store`メソッドは空のままにしておきます。

```PHP:PostController.php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /* 投稿を作成するフォームを表示する */
    public function create()
    {
        return view('post.create');
    }

    /* 投稿を追加する */
    public function store(Request $request)
    {
        // バリデーションしてからデータを追加する
    }
}
```

ざっとこんな感じですね。

# 【本題！】バリデーションを書こう

ここまで準備できたら、早速`store`メソッドの中にバリデーションするロジックを書いていきましょう！

Laravelでバリデーションを実装には`Request`オブジェクトが提供する`validate`メソッドを使いましょう。

バリデーションは通過したら処理は継続して実行され、失敗すると直前の画面に返されます。

バリデーションはこんな感じになります。

```PHP:PostController.phpのstore()
$request->validate([
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required']
]);
```

ご覧の通り、バリデーションルールは`validate`メソッドに渡されています。

繰り返しになりますが、バリデーションは失敗するとそれ以降の処理をしなくなります。成功すれば、コントローラーの処理を引き続き行います。

# （発展編）エラー内容を画面に表示しよう！

もし入力されたデータがバリデーションに引っかかったらどうしましょうか。

そんなときはエラーメッセージを表示して、ユーザーに「どの要素がダメだったか」を知らせてあげましょう。

> 俺「エラーメッセージってなんやねん」

という方はご安心を、下記ページからエラーメッセージが何かを学ぶことができます👍

「もう知ってるよ」という方は下記を飛ばしていただいてOKです。

https://qiita.com/Sunasuna24/items/ae9548f21c01587ba9ea

# エラーメッセージを実装しよう

途中でお伝えした通り、Laravelではvalidationに引っかかった場合には自動的に直前のページにリダイレクトされます。

（さらに専門的なことを言うと、全てのバリデーションエラーとリクエストの入力は自動的にセッションに一時的に保持されます。）

Laravelでは`$errors`という変数がWebアプリのviewで共通で使えるようになっています（厳密にいうと`web`middlewareが適用されているときですが、一旦は大体のときで使えるって思ってもらってOK）。

Laravelではvalidationに引っかかったとき、この`$errors`変数にエラーメッセージが格納されます。

これによって、バリデーションに引っかかって直前のページにリダイレクトしたときに、以下のようなにしてエラーメッセージを表示することが可能です。

```PHP:post/create.blade.php
<h1>投稿する</h1>

@if ($errors->any()) <!-- エラーがあるとき --->
<ul>
    @foreach ($errors->all() as $error) <!-- 全てのエラーをループ文で表示する --->
        <li>{{ $error }}</li>
    @endforeach
</ul>
@endif
```

こんな感じで実装すると、バリデーションを実装してかつ問題があった箇所のエラーメッセージを表示することができます！

以上っ！！！

# 余談

ちなみに筆者はスラムダンクを全く読んだことがありません。

昔に流行ったDSのゲーム[JUMP ULTIMATE STARS](https://www.nintendo.co.jp/ds/ajuj/index.html)に登場したコマを読んだことがあるくらいです。

# 大参考記事

https://laravel.com/docs/8.x/validation
Laravelの自動テストでDBの汚染を避けようとした結果、DBのテーブルを全て吹き飛ばした話

# Laravelの自動テストでDBの汚染を避けようとした結果、DBのテーブルを全て吹き飛ばした話

タイトルの通りですが、自分のようにドキュメントを流し読みしてしまっただけで同じ過ちを犯してしまう人が出ないよう、また使用するライブラリのコードはきちんと読みましょうという自身への戒めを兼ねて記録します。

## 自動テスト実行時に生成されたレコードを共有開発環境のDBに残したくない

この問いに対してLaravelは有効な機能を提供してくれています。
今回の主役である **Illuminate\Foundation\Testing\RefreshDatabaseトレイト** です。

> 前のテストがその後のテストデータに影響しないように、各テストの後にデータベースをリセットできると便利です。インメモリデータベースを使っていても、トラディショナルなデータベースを使用していても、RefreshDatabaseトレイトにより、マイグレーションに最適なアプローチが取れます。テストクラスにてこのトレイトを使えば、すべてが処理されます。
https://readouble.com/laravel/7.x/ja/database-testing.html

## 早速traitをuseして使ってみる

- 結論、下記のテストによって作成されたusersテーブルのレコードは残りません。が、それ以前の大問題が発生していました。

```php
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase; // トレイトを使用する

    public function test_record_created_by_this_test_does_not_persist()
    {
        User::factory()->create();
    }
}
```

## 数十あったテーブルがすべて消えて4つほどの見慣れないテーブルのみが残っている

私が上記の操作をして、数分もたたないうちにチーム内から、開発環境が全く動かないという声が多数上がりました。
そしてどの画面もBase table [] not foundのエラー。

結論から言うと、チームで共有している開発用DBに接続している状態で、RefreshDatabaseトレイトを使用してしまった結果、その開発用DBにあるテーブルが消え去ってしまったのでした。

## 何が起きたのか

答えは当然ながらRefreshDatabaseトレイトのコードにありました。
下記はRefreshDatabaseを使用した状態でのテストで実行されるコードです。

関数内の2行目で`php artisan migrate:fresh`に相当する処理の実行が見て取れます。
**その後**、最下部でトランザクションが張られ、その中でテストが行われる流れのようです。
**トランザクションで保護されるのは、migration実行後の状態であり、もともとのデータベースの状態ではなかったことを理解していなかった**というのが今回の直接的なミスの原因でした。

私たちのチームでは普段migrationを使用していませんでした。
そのためmigrationファイルはLaravelインストール時にデフォルトで含まれている4テーブル分のみ。
結果として、テスト終了後にトランザクションが終了して残るのはmigrate:freshコマンドによって作成された4テーブルとなります。


```php
    /**
     * Refresh a conventional test database.
     *
     * @return void
     */
    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $this->artisan('migrate:fresh', $this->migrateFreshUsing());

            $this->app[Kernel::class]->setArtisan(null);

            RefreshDatabaseState::$migrated = true;
        }

        $this->beginDatabaseTransaction();
    }
```

## 結局どうなったか

今回は社内での使用のみのテスト環境であり、AWS RDSで自動バックアップも取得していたためそこから復元し、大事には至りませんでしたが、接続先が本番環境であったり、バックアップを取得していなかったこと等考えると本当に肝が冷えました。

ただ、ここでinsert / delete系のテストは行わない、となってしまうとテストを導入していく意味合いが薄れてしまうため、マイグレーション環境を整えて、sqliteを使用したインメモリデータベースでのテストを導入する等の方向が取れないかさらに調査していきたいと思います。
【まとめ】Sequel Ace使い方

## はじめに
Sequel Aceの使い方をミスってしまったので、備忘録として残します。

## Sequel Aceとは

- macOSツールであるSequelProの「続編」で、MySQLおよびMariaDBデータベースを操作するための高速で使いやすいMacデータベース管理アプリケーションのこと。日々の業務でも使用しているツールの1つです。簡単にDB接続ができ、アプリ内でSQLをかくこともできます。色々調べてみるとER図もかけるみたいです。
- GitHub：[Sequel-Ace](https://github.com/Sequel-Ace)/**[Sequel-Ace](https://github.com/Sequel-Ace/Sequel-Ace)**

## インストール方法

2パターンあります。 
### Homebrew からインストールする方法

```
$ brew install --cask sequel-ace
$ mas install 1518036000 # Sequel Ace
```

### App Store からインストールする方法

- [GitHub:Sequel Ace](https://github.com/Sequel-Ace/Sequel-Ace)
- この中のMac AppStoreからインストールする

## 基本的な使い方
- 赤枠の必要な情報を入力して、接続をクリックするだけで簡単に接続できます。

![スクリーンショット 2022-04-29 9.13.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/e9205379-d4e2-9245-c2ad-467633f0ec48.png)

## インポート

①データベース名を追加する

②追加したいDBファイルをインポートする

この操作で、簡単にDB接続できる。

![スクリーンショット 2022-04-29 9.18.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/1ebee0cb-6f76-35e5-d501-3522ae95fe94.png)

## エクスポート

①エクスポートを選択する

![スクリーンショット 2022-04-29 9.57.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/05b11a4a-71cd-4318-ee9e-9985eaa18839.png)


②DBをDUMPする際は、「SQL」を選択する（CSV選択するとテーブル毎のデータしか取れない。インポートする時にものすごく大変になる。）

※DBをDUMPとは？

　指定したDBのバックアップをとって、その内容をファイルに出力すること。

③エクスポートをクリックで、SQLデータを出力することができる。
![スクリーンショット 2022-04-29 9.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/8aea6d83-8397-5b9b-71f1-514602c138b2.png)

## まとめ
エクスポートする際に、ミスってしまってテーブル毎のデータしか残してなくて、大変だったので備忘録としてまとめました。

## 参考記事
- ****[Sequel Aceを使ってみる](https://qiita.com/saoyagi2/items/1f15559e96a0a784efad)****