OmniAICreator/Qiita-1.07M huggingface dataset:
パソコンってどうやってできている？

<h1>・はじめに</h1>
　この記事ではパソコンについて学んでパソコンの能力を最大限引き出したいと考えている自分向けの記事です。今回は、パソコンを構成する装置について学んでいきます。参考にできるところがあれば、是非参考にしてください！<br><br>

<h1>・パソコンってどうやってできている？</h1>
　はじめにパソコンはどのようにしてできているのかについて学んでいきましょう。パソコンは大きく２種類あり、それはデスクトップパソコンとノートパソコンです。これらの違いとしてはモニターやキーボードが一体化しているかそうでないかの違いで、使われている装置については能力の差などはあれど大きな違いはありません。
<br><br>
　基本的にパソコンは、<b>入力装置、出力装置、記憶装置、演算装置、制御装置</b>の５つを兼ね備えています。<br>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/b881b91b-2694-97af-2fd2-34090e52977d.png" width=500 height=400>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/ec98222a-84f3-9443-273f-04ea818e0258.png" width=500 height=400>

<ol>
    <li>入力装置とは、パソコンに入力を行う装置で代表的なものは<b>マウス、キーボード</b>が挙げられます。</li>
    <li>出力装置とは、パソコンが出した結果を出力する装置のことで<b>モニター、スピーカー、プリンター</b>などがあげられます。</li>
    <li>記憶装置とは、<b>HDDやSSD</b>、さらに<b>メインメモリ</b>などのことです。これらは<b>揮発性メモリ</b>と<b>不揮発性メモリ</b>に分けれられ、揮発性メモリは電源を落とせば、<b>忘れてしまうもの</b>でメインメモリがこれに当たります。反対に不揮発性メモリは電源を落としても<b>忘れることはなく</b>、半永久的に記憶することができます。HDD、SSDがこれにあたります。</li>
    <li>演算装置とは、計算ができる装置のことで主に<b>CPU</b>がこれを行います。パソコンの中心的な存在です。</li>
    <li>制御装置とは、プログラムや使っている人の入力を検知して他の装置に命令を送る装置のことです。これも<b>CPU</b>が行います。</li>
</ol>

　しかし、これらはどのようにして繋がっているのでしょうか？例えば、人の脳と他の器官などは脊髄によって繋がっています。他にも電子機器はコンセントを介して電気の受け渡しを行っています。では、CPUと他の装置はどのようにして繋がっているのでしょうか？

　結論からいうと、それは<b>マザーボード</b>という基盤によって繋げられています。マザーボードという基盤にはそれぞれメモリやHDD、CPUを挿す場所があり、挿したそれらを１つにまとめています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/5ce5202d-0d43-5e4a-1198-f025d7c188ce.png" width=40%>


<h1>・まとめ</h1>
　このようにパソコンは<b>入力装置、出力装置、記憶装置、演算装置、制御装置</b>の５つの装置を兼ね備えており、その代表的なもの、司令塔となっているのが<b>CPU</b>です。さらにそれらを１つにしているのがマザーボードという基盤であることがわかりました。次回からはそれぞれの装置について勉強していきます。閲覧ありがとうございました！
CSSのgrid-templateではrepeatが使えないかも

## Flex 一本で行く は逆に厳しい
CSSが苦手なのでFlex一本で行く！と決めたものの、Flexレイアウトでテーブルを作るのは辛いぞ！とわかってきた
やりたかったのは簡素なテーブルで、Flexで辛かったのは縦も横も幅を合わせたいという部分、Gridレイアウトの紹介記事を見るとGridレイアウトならその部分が簡単になりそうなので試してみました

## 作りたいテーブルの表示

![GreenShot20230328_005700-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154784/6846ee93-238d-4547-6246-7b5fbde232b2.png)

## HTML

```html
<div class="grid">
  <div class="img">img</div>
  <div>a</div>
  <div>b</div>
  <div>c</div>
  <div>d</div>
  <div>e</div>
  <div>f</div>
  <div>g</div>
  <div>h</div>
  <div>i</div>
  <div>j</div>
  <div>k</div>
  <div>l</div>
  <div>m</div>
  <div>n</div>
  <div>o</div>
  <div>p</div>
  <div>q</div>
  <div>r</div>
</div>
```

## 最終的にできたCSS

```css
.grid {
  display: grid;
  grid-auto-flow: column;
  grid-template:
    " . . . ." auto
    " . . . ."
    " . . . ."
    " . . . ."
    " . . . ."
    " . . . ."  / 
    auto 1fr 1fr 1fr
    ;
  column-gap: 4px;
  row-gap: 2px;
}
.img{
  width: 70px;
  height: 154px;
  grid-row: 1 / span 6;
}

div > div{
  border: 1px solid;
  text-align: center;
}
```

このテーブルは左上から下方向へ順番に配置していきたいので `grid-auto-flow: column` としています
areasはすべて`.`で指定されていますが、左上隅はhtmlのほうで`.img`クラスを付与してあります

### ハマった部分

`auto 1fr 1fr 1fr`の部分を `auto repeat(3, 1fr)`と書いていた

## 他の書き方

```css

.grid {
  display: grid;
  grid-auto-flow: column;
  grid-template:
    auto repeat(5, 1fr) / 
    auto repeat(3, 1fr)
    ;
  column-gap: 4px;
  row-gap: 2px;
}
```

.grid以外はそのままなので省略していますが、ちゃんとあります
先ほどとの違いは`grid-template`に`grid-template-areas` の指定がないこと、`repeat`が使えていること

先にこちらの書き方で正常に表示されたことを確認していて、その後に`-areas`を明示した書き方に変更しようとして上記のハマりに遭遇しました

## 終わりに

今回はグリッドレイアウトのgrid-templateでハマった部分について、原因はrepeat関数が意図せず動いてないということでした。
[AWS]EC2 MySQLのインストール　Error:  Problem: conflicting requests   - nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server

# 目的
AWS EC2にMySQLを導入する際に
```bash
Error:
 Problem: conflicting requests
  - nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libssl.so.10()(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libcrypto.so.10(libcrypto.so.10)(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libssl.so.10(libssl.so.10)(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server-8.0.12-1.el7.x86_64
...
```
なエラーになり解決に時間がかかったため備忘録として残します

# エラーまでの流れ
yumコマンドでMySQLパッケージをインストールします。
```bash
sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
```
として公式のリポジトリを追加します。その後、
```bash
sudo yum install mysql-community-server
```
でインストールしようとすると

```bash
Error:
 Problem: conflicting requests
  - nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libssl.so.10()(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libcrypto.so.10(libcrypto.so.10)(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libssl.so.10(libssl.so.10)(64bit) needed by mysql-community-server-8.0.11-1.el7.x86_64
  - nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server-8.0.12-1.el7.x86_64
...
```
openssl が libcrypto.so.10 を提供していることがわかりますが、モジュールがなく、依存関係が不足しているようです。

bssl.so.10 をインストールします
```bash
sudo yum install http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-3.el8.x86_64.rpm
```

再度
```
sudo yum install -y mysql-community-server
Rails Action Mailerのプレビューで発生したエラーの解決

# 環境
WSL2
Ruby 3.1.3
Rails 7.0.4
rspec

# 発生した問題
Railsチュートリアルの11章の「11.2.2 送信メールのプレビュー」にて `http://localhost:3000/rails/mailers/user_mailer/account_activation`にアクセスしたところ
「Unknown action Mailer preview 'user_mailer/account_activation' not found」というエラーが発生しました。

# やってみたこと
https://qiita.com/Utsubo/items/febc233ee15cdd7a6a77
こちらの記事を参考にして`config/application.rb`に
```bash
config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
```
を書いてみましたがダメでした

# 解決方法
根本の解決には至っていない気がしますが`user_mailer_preview.rb`を「`spec/mailers/previews/user_mailer_preview.rb`」から「`test/mailers/previews/user_mailer_preview.rb`」へ移動すると解決しました。

## 備考
もしかすると私の場合途中からRspecを導入したため`test`ファイルが残っていたのかもしれません。
DockerでRails7の開発環境構築(MySQL)

# 構築する環境のバージョン情報

- Ruby: 3.1.0
- Ruby on Rails: 7.0.4
- MySQL: 8.0

# 手順
### 1. プロジェクトフォルダを作成､移動
~~~sh
$ mkdir my-rails-app
$ cd my-rails-app
~~~
以下のファイルを作成します｡
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock

~~~sh
$ touch Dockerfile docker-compose.yml Gemfile Gemfile.lock
~~~

### 2. Dockerfileの中身を記述
~~~Dockerfile:Dockerfile
FROM ruby:3.1.0

RUN mkdir /app
WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

RUN bundle install
COPY . /app

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
~~~
なお､Rails 7 では Webpacker が標準では組み込まれなくなったので yarn や Node.js のインストールは不要です。

### 3. Gemfileの中身を記述
~~~Gemfile:Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.1.0'

gem 'rails', '~> 7.0.4'
gem 'mysql2'
~~~
Gemfile.lockは空のままで大丈夫です｡

### 4 .docker-compose.ymlに以下の内容を記述
~~~yaml:docker-compose.yaml
version: '3.9'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: myrootpassword
      MYSQL_DATABASE: myrailsapp_development
      MYSQL_USER: myrailsapp
      MYSQL_PASSWORD: myrailsapppassword
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - "3306:3306"
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && rails server -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  db-data:
~~~
### 5. Railsアプリケーションを作成
~~~sh
$ docker-compose run web rails new . \
--force --no-deps --database=mysql --skip-javascript
~~~
--skip-javascriptオプションを追加して、JavaScriptの設定をスキップしています。

### 6. 生成されたconfig/database.ymlを編集し、データベース設定を変更
~~~yaml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: myrailsapp
  password: myrailsapppassword
  host: db

development:
  <<: *default
  database: myrailsapp_development

test:
  <<: *default
  database: myrailsapp_test

production:
  <<: *default
  database: myrailsapp_production
  username: <%= ENV['MYRAILSAPP_DATABASE_USER'] %>
  password: <%= ENV['MYRAILSAPP_DATABASE_PASSWORD'] %>
  host: <%= ENV['MYRAILSAPP_DATABASE_HOST'] %>
~~~





### 7. RailsアプリとMysqlデータベースのコンテナをビルド＆実行
~~~sh
$ docker-compose up --build
~~~

# 動作確認
http://localhost:3000/ に移動し､起動を確認します。
以下のような画面が出れば成功です。
![スクリーンショット 2023-03-28 0.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/31820bca-bc0c-0a27-7c2f-d5d6f6bb5d0d.png)
ボタンが押された時の非同期処理と前後のアクションを表現

# はじめに
こんばんは、佐藤佑哉です。ボタンが押された時の非同期処理で処理されている間のアクションを表現したいなと思ったので、忘備録として残します！

## 何をするか？
Roomを介してローカルDBのデータをプライマリーキーを参照して消去します。
設計はMVVMアーキテクチャで実装しています。


## 進め方
### 1.MVVMにFragmentに通知をしてくれる役割を果たすMutableSharedFlow型の変数を宣言する
```Kotlin
//mutableなSharedFlowを宣言
private val _deleteEventFlow : MutableSharedFlow<Boolean> = MutableSharedFlow()
//Fragmentで使用するImmutableなSharedFlowを宣言する
val deleteEventFlow : SharedFlow<Boolean> = _deleteEventFlow
```
可変と不可変な変数を宣言することでFragmentからの影響（変数の変更など）を受けにくくします。
### 2.データを削除するメソッドを作成する
```Kotlin
fun deleteProfile(profileId: Int){
    viewModelScope.launch {
        //リポジトリに削除したいデータのIDを渡す
        profilerepository.deleteProfile(profileId)
        //完了したらdeleteEventFlowの値を変更する（trueに変換することで通知を送るようにしている）
        _deleteEventFlow.emit(true)
    }
}
```
削除ができたらemit関数で一回だけtrueに変更するよう実行します。
### 3.deleteEventFlowの値の変更Fragment側で監視する

```Kotlin
//onViewCreatedやonCreateViewでも監視可能（今回はonViewCreated）
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.RESUMED) {//RESUMEDになったら実行
                //変更した時に実行される処理を記述
                viewModel.deleteEventFlow.collect {
                    //削除したことを通知するトーストテキストを表示
                    Toast.makeText(requireContext(), "プロフィールを削除しました", Toast.LENGTH_SHORT).show()
                    //リスト表示画面に遷移する
                    findNavController().popBackStack()
                }
            }
        }
    //省略
}
```

collectラムダ関数でdeleteEventFlowが変更したときに実行される処理を書いていきます。

### 4.ボタンのリスナー設定

```Kotlin
//削除ボタンのリスナー設定
binding.deleteProfile.setOnClickListener {

    //削除したいデータのIDを格納（今回は遷移した時に引数から取得したIDを格納）
    val id = args.profileId.toString().toInt()

    //削除ボタンのテキストを変更
    binding.deleteProfile.text = "削除中..."

    //実行されたくないボタンを使用不可能にする
    binding.twitterIcon.isEnabled = false
    binding.githubIcon.isEnabled = false
    binding.detailBackButton.isEnabled = false
    binding.detailFavoriteButton.isEnabled = false

    //コルーチンスコープで非同期関数を呼び出す
    lifecycleScope.launch(Dispatchers.IO) {
        viewModel.deleteProfile(id)
    }
}
```
- 最初にスクリーンの状態を設定する
- 非同期関数を呼び出す
これにより、非同期処理をしている間のアニメーションを使用できるようにします。
### まとめ

最終的にこのようなアルゴリズムになると考えています。
1. ボタンが押される
1. UIの状態を変更する
1. 非同期処理が実行される
    -  非同期処理が完了してSharedFlowの変数の値が変更される
1. Fragmentで監視していた変数が変更されたと同時にcollect関数の記述した処理が実行される。
ニューラルネットワークとは

# もくじ
> [前置き](#前置き)
[ニューラルネットワークとは](#ニューラルネットワークとは)
[パーセプトロンってなんぞ](#パーセプトロンってなんぞ)
[後付け](#後付け) 


# 前置き
　皆さん、AI技術を使ったモノを頭の中で考えてください。

<font color="GhostWhite">Chat-GPT</font>
<font color="GhostWhite">Stable Diffusion</font>
<font color="GhostWhite">NovelAI</font>
<font color="GhostWhite">Bard</font>
<font color="GhostWhite">AIのべりすと</font>　　　　
　　
　皆さんが考えたそれらのAI技術には**ニューラルネットワーク**というものが採用されています。
　ニューラルネットワークと聞いて「あぁ～～あれね」と感じる人はそうそういないと思います。もし、そう感じた人がいるなら今すぐ寝なさい。あなたは頑張りました。


# ニューラルネットワークとは
　まず、AIというのは人間の脳を模して造られたものなので、話は人間の脳から始まります。
　生物の脳は**ニューロン**(神経細胞)と呼ばれる細胞(とその他諸々)で構成されており、人間の脳には100億から1000億ものニューロンがあるとされています
　これらのニューロンをもとに作成されたものを何層にも重ねたり繋げたりする、そうするとニューロンのネットワーク、つまりニューラルネットワークができる。
　このニューロンをPC内で計算できるように数理モデル化したものを「(単純)**パーセプトロン**」といいます。

# パーセプトロンってなんぞ
　パーセプトロンでは入力された情報に対して重要度と呼ばれる**重み**を掛けて、総和したものに**活性化関数**の一つである**ステップ関数**と呼ばれているものを使い、その結果を出力します。
 このパーセプトロンを何層にも重ねて、活性化関数を**シグモイド関数**と呼ばれているものに変更し、つなげたものを多層パーセプトロンと呼びます。また、多層パーセプトロンはニューラルネットワークと呼ばれています。
(これぞタイトル回収)


## 活性化関数のちょっとした説明
　活性化関数は各パーセプトロンの結果を調整するために使われています。
　例えば「ステップ関数」と呼ばれているものは結果を0or1に、「シグモイド関数」は結果を0~1の間にみたいな感じです(確率的な)

# 後付け
　調べものあるあるなのですが、わからない単語をわからない単語で説明されていたりしており、どこから調べ始めたらいいかわからない方もいると思います。そんな方々のための調べ始め、きっかけになれたら幸いです。
(Aを調べるとBといわれ、Bを調べるとAといわれるときは、~~画面ぶち抜きたくなった…~~)

キーワード
・ニューラルネットワーク
・ニューロン
・パーセプトロン
・重み
・活性化関数
・ステップ関数
・シグモイド関数
Rust研究：ZIP圧縮

ZIP 圧縮の練習をしたのでメモを残します。

zip クレートを使用します。

# その１

関数 process1 は、aaa.txt、hoge/bbb.txt、../ccc.txt を圧縮して test1.zip に保存します。

```rust
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io::Seek;
use std::path::Path;
use std::path::PathBuf;
use zip::result::ZipResult;
use zip::ZipWriter;
use zip::write::FileOptions;

fn process1() -> ZipResult<()> {

    let mut zw = ZipWriter::new(File::create("test1.zip")?);

    let opts = FileOptions::default();

    // aaa.txt を追加
    zw.start_file("aaa.txt", opts)?;
    zw.write("私の名前はカルメンです。".as_bytes())?;

    // hoge/bbb.txt を追加
    zw.start_file("hoge/bbb.txt", opts)?;
    zw.write(b"It's better to burn out than to fade away.")?;

    // [MEMO] "Zip Slip" と呼ばれるパス・バーサルの脆弱性 (CWE-22) のチェック
    // ../ccc.txt を追加。
    zw.start_file("../ccc.txt", opts)?;
    zw.write(b"!!! Zip Slip !!!")?;
    // ⇒ ../ccc.txt は test1.zip に追加されない。

    zw.flush()?;
    zw.finish()?;

    Ok(())
}
```

最後の ../ccc.txt は test1.zip に保存されませんでした。
"Zip Slip" と呼ばれるパス・トラバーサルの脆弱性 (CWE-22) に対応しているようです。

# その２

関数 process2 は、target ディレクトリ配下のファイルをすべて圧縮して test2.zip に保存します。

ディレクトリ名を渡したらいい感じに再帰的にサブディレクトリをたどって圧縮してくれるような API だと思っていたら、全然そんなことはありませんでした。
仕方がないので自分で実装しました。

```rust
fn process2 () -> ZipResult<()> {

    let mut zw = ZipWriter::new(File::create("test2.zip")?);

    let opts = FileOptions::default();

    // target ディレクトリ配下のファイルをすべて圧縮
    let p = Path::new("target");
    if p.is_dir() {
        process_dir(&mut zw, p.to_path_buf(), opts)?;
    }

    zw.finish()?;

    Ok(())
}

// ディレクトリ配下を圧縮する。サブディレクトリを再帰的に処理する
fn process_dir <W:Write+Seek> (zw:&mut ZipWriter<W>, p:PathBuf, 
    opts:FileOptions) -> ZipResult<()> {

    for entry in p.read_dir()? {
        if let Ok(entry) = entry {
            println!("{:?}", entry.path());

            if entry.path().is_dir() {

                // ディレクトリのとき
                process_dir(zw, entry.path(), opts)?;

            } else {
                
                // ファイルのとき
                if entry.path().is_file() {
                    let mut bytes:Vec<u8> = vec![];

                    // ファイル読み出し
                    let mut r = File::open(entry.path())?;
                    r.read_to_end(&mut bytes)?;

                    // zip に追加
                    let filepath:String = entry.path().to_string_lossy().into_owned();
                    zw.start_file(&filepath, opts)?;
                    zw.write(&bytes)?;
                    zw.flush()?;
                }
            }
        }
    }

    Ok(())
}
```

ZipWriter のインスタンスを再帰的に受け渡すところでジェネリクスが必要で少しとまどいましたが、なんとか乗り越えられました。

ファイルに書き出すところは、BufWriter を使うともう少しパフォーマンスが上がりそうな気がします。
【備忘録】Flutterの状態管理ライブラリRiverpodについて

使い始めて約半年になりますが、備忘録としてまとめてみました。

## Riverpodとは
RiverPodは、Flutterの状態管理ライブラリの一つで、Providerパターンを実現するためのライブラリ。Flutterの機能であるInheritedWidgetとChangeNotifierを組み合わせて実装されているらしい。
状態の範囲を柔軟に指定でき、UIの状態をより明確に表現することができる。

## RiverPodのメリット
RiverPodを使って便利だなと思った事を以下に挙げます。

#### 状態管理が簡単
プロバイダーを定義して状態を提供することができるため、Flutterのみの状態管理に比べて必要なコードの量が減り、コードの可読性が良い。

#### 状態の範囲を柔軟に指定できる
状態の範囲を柔軟に指定できるため、UIの状態をより明確に表現することができる。
例えば、ウィジェットの子孫にのみ状態を伝播させることができるため、状態の変更が想定外の場所で発生することがありません。

#### 状態変更通知が簡単
ChangeNotifierを使用して状態変更通知を簡単に行うことができる。ChangeNotifierを継承することで、状態変更があった際に自動的に通知されるため、状態変更に伴う処理が簡単。

## RiverPodを使う際の注意点

以下、RiverPodを使用する際に注意したい点をまとめてみました。

#### Providerの使い分け
RiverPodにはProviderという機能がありますが、Providerには複数の種類があります。例えばProvider、StateProvider、StreamProvider、FutureProviderなどです。これらを適切に使い分けることが大切です。例えば、単純な値を扱う場合にはProviderを使用し、複数のウィジェットから共有する値を扱う場合にはStateProviderを使用するといった具合に使い分けましょう。

#### データの型付け
RiverPodでは、値を提供する場合にデータの型付けが必要です。これにより、コンパイル時に型チェックを行うことができます。値の型が誤っている場合、コンパイル時にエラーが発生するため、バグの発生を防ぐことができます。

#### StateNotifierを活用する
RiverPodでは、StateNotifierという状態管理のためのクラスを提供しています。これを使うことで、状態の変更を容易に行うことができます。また、状態の変更に伴って、自動的にウィジェットが再構築されるため、状態管理をスムーズに行うことができます。

#### Providerのスコープ
RiverPodでは、Providerのスコープを定義することができます。例えば、ProviderScopeやScopedProviderなどです。これらを活用することで、必要な時に必要な範囲でProviderを提供することができます。適切なスコープを定義することで、不要な再構築を防ぎ、パフォーマンスを向上させることができます。

## 約半年使ってみて
慣れるまで非常に苦労しましたが、慣れるとすごく便利でRiverpod様様な感じです。
今後もRiverpod様におんぶにだっこで開発していきたいと思ってます。
Pythonで複数の画像を一気に270度回転してまとめてPDFへ出力

# Pythonで複数の画像を一気に270度回転してまとめてPDFへ出力

複数の画像ファイルを一気に270度回転して、1つのPDFファイルに出力するPythonコードなり。

家庭用スキャナで、ガンガン横向き資料をスキャンしたときに愛用。

回転不要な場合は、rotateImageの呼び出しをコメントアウトするだけ。

```python
import img2pdf
import os
from PIL import Image

def rotateImage(folder, image_file):
    im = Image.open(image_file)
    im_rotate = im.rotate(270, resample=Image.BICUBIC, expand=True)
    filename = os.path.basename(image_file)
    filename = f"{folder}/rotate_{filename}"
    im_rotate.save(filename)
    return filename

if __name__ == '__main__':
    pdf_filename = "d:/images/output.pdf" # 出力先PDFファイル名
    folder = "d:/images/" # 入力元の画像フォルダ
    extension  = ".jpg" # 処理対象の拡張子

    image_files = []
    for filename in os.listdir(folder):
        if filename.lower().endswith(extension):
            image_file = os.path.join(folder, filename)
            image_file = rotateImage(folder, image_file) # 画像を270度回転
            image_files.append(image_file)
    image_files.sort()
    with open(pdf_filename, "wb") as pdf_file:
        pdf_file.write(img2pdf.convert(image_files))
```
Marpを使って書いたスライドで、プレゼンの最中にコメントを台本として表示する方法

最近、スライドをMarpで作ることがどれだけエンジニアにとって有意義なことかを発見しました。
今まで、パワーポイントやGoogleスライドで作成していたのが嘘のように、マークダウンに慣れきってしまった僕にとってはVSCodeでスライドを作成することはDXの向上以外ありません。

ただ、まだ使い始めたばかりなので、プレゼン中に台本を表示する方法がわかりませんでした。
今回は僕のようなMarp初心者の方のために、プレゼンの最中に台本を表示する方法について紹介していこうと思います。

まず、次のように通常のスライドを作成してください。

```markdown
---
marp: true
theme: uncover
paginate: false
backgroundImage: url('https://marp.app/assets/hero-background.svg')
---

# ここにタイトル

たかぎとねこ
```

そして、次のようにHTMLコメントを加えてください。

```markdown
---
marp: true
theme: uncover
paginate: false
backgroundImage: url('https://marp.app/assets/hero-background.svg')
---

# ここにタイトル

たかぎとねこ

<!-- こんにちわ、みなさん -->
```

完成したら、`HTML slide deck`としてエクスポートを行います。

エクスポートされたら、ブラウザが立ち上がります。
下部に表示されているメニューから、`Open presenter view`をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/7a740547-72d0-b6ac-e9f3-12d4f0f49f55.png)

すると、プレゼンタービューが表示されます。
みてください！、画面の右側に先ほど書いたコメントが台本として表示されているのが確認できます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/c8df1305-d2ff-33cd-1574-45e7688b757a.png)

`Powerpoint document`でエクスポートしても、ノートの部分に台本が表示されることが確認できました。

![名称未設定のデザイン (79).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/4be31a3b-fa61-8797-7104-d44e3f182ea2.png)

みなさんも、スライドを作る際はコメントをいっぱい書いて、台本として役立ててみてください！
【Dependabot】GitHub PackagesのGemをアップデートする方法

## `dependabot.yml`を編集する

`.github/dependabot.yml`に`registries`の項目を追加します。

```yml
version: 2

# 追加
registries:
  github-packages:
    type: rubygems-server
    url: https://rubygems.pkg.github.com
    token: ${{secrets.MY_GITHUB_TOKEN}}

updates:
  - package-ecosystem: bundler
    directory: "/"
    # 追加
    registries:
      - github-packages

```

## DependabotのSecretsを設定

DependabotのSecretsに`MY_GITHUB_TOKEN`を追加します。
変数名が`GITHUB`で始まるとエラーになりますのでご注意ください。

`gh`コマンドで追加するには次のように実行します。

```terminal
gh secret set MY_GITHUB_TOKEN -a dependabot -b 自分のGitHubパーソナルアクセストークン
```

GUIで設定するには次の手順で設定します。

リポジトリのページを開き、「Settings」→「Secrets and variables」→「Dependabot」の順にクリックします。

![スクリーンショット 2023-03-27 23.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1c32d528-e331-0782-509a-c2d27bfc2470.png)

開いた画面右上の「New repository secret」をクリックします。

![スクリーンショット 2023-03-27 23.42.15のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6f30846b-4f36-07f1-6575-c02c12e7a4e1.png)

入力画面が開きますので必要事項を入力してSecretを作成します。

![イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b88bf8d8-605a-b2e7-b853-70ca9fa93211.png)
Spigot Bukkit#craftItem の奇怪な動作

# Env
Spigot API : version 1.19.2

# craftItem
Bukkit#craftItem は長さ9の ItemStack の配列を渡すと、渡した配列で作成することが出来るアイテムを返してくれるメソッドである。
> "Get the crafted item using the list of ItemStack provided."
> [Java Doc Bukkit#craftItem](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Bukkit.html#craftItem(org.bukkit.inventory.ItemStack[],org.bukkit.World,org.bukkit.entity.Player))

とあるプラグインを作成していて、craftItem メソッドを使うことになった。
渡した配列をその後の処理でも使いまわすコードを書いたがどうにもうまく動いてくれない。
どうしてだろうと渡した配列の中身を覗いてみると全て null に変更されていた。

```java
Player player = ~~~ ;
ItemStack[] items = ~~~ ;
ItemStack result = Bukkit.craftItem(items,player.getWorld(),player);

Arrays.stream(items).forEach(s->{
            String name = s == null ? "null" : s.getType().name();
            int amount = s == null ? -1 : s.getAmount();
            System.out.println(String.format("name : %s | amount : %d",name,amount));
        });

--- 
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
name : null | amount : -1
```
インターフェースまでは追跡することが出来たが、実装クラスのコードを覗く方法が分からなかったので、どういう経緯により配列の中身が真っ新になってしまったのかを突き止めることはできなかった。


# 対応
craftItem へ渡す前に配列をクローンしておく。
```java
ItemStack[] send = ~~~ ;
ItemStack[] copy = send.clone();
ItemStack result = Bukkit.craftItem(send,player.getWorld(),player);
Arrays.stream(copy).forEach(s->{
            String name = s == null ? "null" : s.getType().name();
            int amount = s == null ? -1 : s.getAmount();
            System.out.println(String.format("name : %s | amount : %d",name,amount));
        });

---
name : OAK_LOG | amount : 2
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1
name : AIR | amount : 1

```
OK.
React & JestでpreventDefaultをテストする

# はじめに
Reactでformタグを使用しているときenterを押すとでformが送信されページがリロードしてしまうのを
防ぎたくてformのonSubmitでe.preventDefault()を実行することでデフォルト動作をキャンセルさせましたが
テストの書き方にだいぶ苦労したのでまとめておきます。

テストはtesting/Libraryとjestを使って記述しています。

# 実装
```React:実装
export function TaskAddInput() {
    const handleSubmit = (e:FormEvent<HTMLFormElement>) => {
     e.preventDefault()
    };

    return (
        <div>
            <form onSubmit={handleSubmit} data-testid="form1">
                <input type="text" placeholder="add a text"/>
            </form>
        </div>
    );
}
```
上記の実装に対して
formにsubmitイベントを発火させた際
preventDefaultが正しく実行されていることを確認するテストを書きます。



# テスト
```React:テスト
 it('submitイベント発火時preventDefaultが実行されていること', () => {

        const formEvent = new Event('submit', { bubbles: true })// ①

        Object.assign(formEvent,{preventDefault:jest.fn()})// ②
        render(<TaskAddInput/>)

        const form = screen.getByTestId("form1")
        fireEvent(form ,formEvent )// ③
        expect(formEvent.preventDefault).toHaveBeenCalledTimes(1)// ④
            })
```

順番に解説していきます。
①submitのイベントオブジェクトを作成します。オプションで { bubbles: true }を指定してイベントを親要素に伝搬します。
②Object.assignでオブジェクトのマージを行います。①で作成したformEventに
　preventDefaultをキーにjest.fn()をvalueに持つオブジェクトをマージさせます。
　これでpreventDefaultはjest.fn()に置き換えられました。
③fireEventを使ってformにformEventを渡してsubmitイベントを発火させます。
④preventDefaultが1回呼び出されたことを確認しています。




# まとめ
このテストがなかなか書けずにかなりの時間を浪費したので
同じような方の役に立てば幸いです。
　
間違い等ありましたらご指摘お願いします。
SSDを換装してみた（i5-12450君改）

新ノート君のSSDを早いやつに換装したので
ディスクベンチしてみました。

# ディスク速度比較

換装前後の速度変化はこんな感じ。
換装前から割と速度出ててSSD変えるか迷ったけれど、
全体的に早くなりました。


| 項目 | 12450H君改（換装後） | 12450H君（換装前） |
|:----------:|:-----------:|:------------:|
| SEQ1M Q8T1 (Read) | 5277    | 3027       |
| SEQ1M Q1T1 (Read) | 3467  | 2595      |
| RND4K Q32T1 (Read) | 479    | 319     |
| RND4K Q1T1 (Read) | 74         | 71         |
| SEQ1M Q8T1 (Write) | 4959    | 1643        |
| SEQ1M Q1T1 (Write) | 3619  | 1580      |
| RND4K Q32T1 (Write) | 461    | 409     |
| RND4K Q1T1 (Write) | 171         | 152         |


## SSD比較

### 換装前ディスク（ノートのデフォルト）
・ [Intel SSD 670p M.2 PCIEx4 SSDPEKNU512GZ 512GB]()
ASUSノートに使われてたやつ。
どうやらIntelのらしい。
普通の速さ。
普段使いには問題なさそう。

### 換装後ディスク（今回交換したディスク）
・[WD_BLACK SN770 NVme SSD WDS100T3X0E 1TB](https://www.westerndigital.com/ja-jp/products/internal-drives/wd-black-sn770-nvme-ssd#WDS100T3X0E)
Western Digital製のSSDの上位モデル。
PCIe Gen4対応のやたら早いやつ。
パフォーマンス重視でコストもそこそこ安いからこれに決定。

## 換装前後のディスク速度比較（CrystalDiskMark）

### 換装前
![20230312_CristalDiskMark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/1fd51495-55e5-ec8d-04ee-126dbc6f7303.png)

### 換装後
![20230327_12450H改_SSDベンチマーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/ea6af2a6-0095-8ce1-79e8-6447775923b5.png)


# 感想

多分、体感速度あまり変わらないと思うが、
自己満足のためにSSD変更。
今のところはすごく快適。
あとは安定して長持ちしてくれると嬉しい。
【Spring Security】WebSecurityConfigurerAdapterが使えないのを解決する

# はじめに

SpringSecurityを久々に触り、ん？となった箇所があったため備忘録の意も踏まえて記事にします。
SpringSecurityの設定ファイルである`SecurityConfig`を記述していたときのことです。

# 問題点

`SecurityConfig`を以下のように書いたところ、「`WebSecurityConfigurerAdapter`なんて無い！」と怒られてしまいました。

```java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    public void configure(HttpSecurity http) throws Exception {}
}
```

エラーのメッセージは以下の通りです。

```
The import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter cannot be resolved
```

[こちら](https://qiita.com/suke_masa/items/908805dd45df08ba28d8)の記事によると、バージョンアップによって使えなくなったみたいです。

# 解決方法

以下のように`SecurityFilterChain`をBeanで定義することで同じ振る舞いを実現できます。

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		return http.build();
	}
}
```

メソッドの中身は基本的にこれまでと同じように書くことができます。
バージョン上がったことで動かなくなると、もともとあった記事が廃れてしまいますね…。
JavaScriptを使ってCookieを操作する方法についての覚書

JavaScriptを使ってCookieを操作する方法について。

## Cookieの設定
Cookieを設定するには、以下のようにdocument.cookieに値を設定。


```javascript
document.cookie = "key=value";
```
これで、名前が「key」で値が「value」のCookieが設定されます。

## Cookieの取得
Cookieを取得するには、以下のようにdocument.cookieからCookieの値を取得。

```javascript
let cookieValue = document.cookie;
```
## Cookieの削除
Cookieを削除するには、Cookieの有効期限を過去の日付に設定します。以下のように設定。

```javascript
document.cookie = "key=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
```
これで、名前が「key」のCookieが削除されます。

以上が、JavaScriptを使ったCookieの操作方法になります。


## ※Cookieとは
WebサイトがWebブラウザに保存する小さなデータの塊で、ユーザーの行動や設定を記憶するために使用されます。Cookieは、Webブラウザに保存され、Webサイトがリクエストを送信するたびに、WebブラウザからWebサーバーに送信されます。

Cookieは、以下のようなことができます。

セッション管理：Cookieを使用して、ユーザーがログインしているかどうかを確認したり、セッションIDを管理したりすることができます。

パーソナライズ：Cookieを使用して、ユーザーの好みや設定を記憶し、それに基づいてコンテンツや広告をパーソナライズすることができます。

トラッキング：Cookieを使用して、ユーザーの行動を追跡することができます。これにより、ユーザーの行動に基づいて、広告やコンテンツをカスタマイズすることができます。

ショッピングカート：Cookieを使用して、ユーザーがオンラインストアで商品をショッピングカートに追加したり、注文したりすることができます。


## Cookieに含むことができる情報例

名前（key）
値（value）
有効期限（expires）
ドメイン（domain）
パス（path）
セキュアフラグ（secure）
有効期限は、Cookieが有効である期間を指定します。期限を指定しない場合、Cookieはブラウザのセッションが終了するまで有効です。ドメインとパスは、Cookieが送信される対象のWebサイトのドメインとパスを指定します。セキュアフラグは、CookieがHTTPS接続でのみ送信されるように制限するために使用されます。

Cookieは、ユーザーがブラウザの設定で削除することができます。また、Webサーバー側でも、有効期限が切れたCookieを自動的に削除することができます。

Cookieは、Webサイトの利便性を向上させるために重要な役割を果たしています。ただし、Cookieがユーザーのプライバシーに関する問題を引き起こすこともあるため、Webサイトは、Cookieの使用に関する適切な情報提供と同意の取得を行うことが求められます。
最小限の努力でゆるくやっていく情報収集のコツ

どうもこんにちはたくびー(@takubii)です。

みなさんは日々のインプットについてどうしていますか？
どこから情報を取得すればいいか分からない、そもそもインターネットの大海が広すぎるといった悩みを持った方もいると思います。

今回は私が日々どのようにインプットを行なっているかを記事にして、少しでもみなさんの参考になればいいなと思って書きます。

### RSSを使ったインプット
結論から言うと私はFeedlyというRSSサイトに以下のサイトを登録して日々情報を得ています。
- はてなブックマーク テクノロジー 新着
- Qiita
- Zenn

これらを登録すると1日約50〜100件くらいの記事が更新されます。
これと別途企業のテックブログなどを登録するだけでインプットに関しては十分ではないかと思います。

特にはてぶのテクノロジーに関してはテック系に関してはほぼほぼ網羅できるので是非RSS登録していただけると捗ると断言できます。

### 業務で身につけるインプット
業務中で分からないことを調べることも立派なインプット活動です。
ただ、調べて実装して終わりというのは少し勿体無いので一歩進んで調べた内容やコマンドをメモに残すことをオススメします。

私も最近になって始めましたが、調べた内容をURLから概要までメモを取ることで「あの時調べた内容なんだっけ」という状況ですぐに見返せて調べる手間が省けています。

また、そのメモをQiitaやZennといったブログに投稿することでアウトプットの一環にもなるので、そこまで興味がある方にはおすすめの方法です。

### 最後に
エンジニアというのはインプットが重要と言われる職業ですが、重要なことだからこそ楽に情報を集められるようにしていきたいですね。

本日ご紹介した私の方法は職場でもちょこッとRSSのチェックやメモを取るといったことができるので是非実践してみてください。

そして、プライベートでは仕事を忘れて趣味活動に精を出していきましょう。
ここまで読んでいただきありがとうございました。また機会があればお会いしましょう。
iOS App Dev Tutorialsを読んで実際にやってみた。その6

### 前回の記事
[iOS App Dev Tutorialsを読んでみた。その5](https://qiita.com/shomiya181210/items/c417c569863048f5f90f)
前回の記事を読んだ後に、この記事をご覧ください。
## 今回の範囲

[Managing data flow between views　](https://developer.apple.com/tutorials/app-dev-training/managing-data-flow-between-views)
今回はビュー間のデータフローを管理する事について学びます。
### 1.真実の源
　真実のソースを複数箇所に保存すると、アプリのバグにつながる可能性があるため、アプリの各データ要素には単一の真実のソースを使用する必要があります。ScrumdingerAppでは、真実のソースを用い、他のビューがそのアクセスを共有することになっている。これにより、データ整合性が維持され、アプリのパフォーマンスが向上する。
### 2.Swiftプロパティラッパー
　Swiftにおいて、プロパティラッパーは、共通のプロパティ初期化パターンをカプセル化し、プロパティに効率的に動作を追加するのに役立ちます。ための真実の単一のソースを維持するのを助けます。
### 3.状態
SwiftUIでは、ユーザーの操作に基づいて@Stateプロパティが変更されると、それに依存する全てのビューが更新されることでUIが新しいバージョンにレンダリングされます。状態プロパティは、一時的な状態を管理するために役立つので、永続的なストレージに使用することは避けるべきです。Stateプロパティラッパーは、ローカルな真実のミュータブルソースを定義するためのシンタックスであり、他のビューでも同じソースを使用したい場合は、@EnvironmentObjectプロパティラッパーを使用する必要があります。
### ４.結合
＠Bindingは、既存の真実のソースとビュー間で双方向の接続を作成することで、データの表示および更新を実現します。親または子ビューは、このソースを変更できます。この機能は、DailyScrumを編集するためにも使用されます。ビューがバインディングに変更を加えると、SwiftUIは真実のソースを更新します。
### ５.アーキテクチャ
バインディングを使用して単一の真実のソースを伝達させるこのパターンは、ビュー階層内の任意の数に対して有効である。
### まとめ
今回はビュー間のデータフローを管理する事について学びました。次回は編集ビューの作成をしていきます。
[GraphQL][next.js]graphql-codegenでInputの型が見つからなくて困ったところが解消できた

# 前提

以下の環境

- `next.js`

- `typescript`

- `GraphQL`

# 結論

`user_profiles_insert_input`のように`mutation名_insert_input`の型を指定する

# やりたかったこと

Mutationの定義をしたかった。

```
export const CREATE_USER_PROFILES = gql`
  mutation CreateUserProfiles($userProfiles: [UserProfilesInput!]!) {
    insert_user_profiles(objects: $userProfiles) {
      returning {
        user_id
        profile
      }
    }
  }
`
```

# エラー

エラーに書いてんじゃん、、、

```
✖ GraphQL Document Validation failed with 3 errors;
      Error 0: Unknown type "UserProfilesInput". Did you mean "user_profiles_insert_input", "user_profiles_set_input", "user_profiles_inc_input", "users_obj_rel_insert_input", or "user_profiles_constraint"?
```

# 修正後

`UserProfilesInput` -> `user_profiles_insert_input`

```
export const CREATE_USER_PROFILES = gql`
  mutation CreateUserProfiles($userProfiles: [user_profiles_insert_input!]!) {
    insert_user_profiles(objects: $userProfiles) {
      returning {
        user_id
        profile
      }
    }
  }
`
```

# まとめ

エラーはしっかり読む
OSについて調べてみた

## はじめに

OSの知識を整理したかったのでこちらの記事を書きました。内容としては初心者向けの内容になります。


## OSとは

Operating System（オペレーティングシステム）の略。
広義の意味でのOS、狭義の意味でのOSがある。
広義のOSは、基本ソフトウェア一般を指す。基本ソフトウェアの制御プログラム、言語処理プログラム、サービスプログラムの全てを含む。

Windows、Mac OS、Linuxなどがこれらにあたる。これらのOSは、それぞれ異なる特徴や機能を持っているが、共通しているのは、ハードウェアとアプリケーションの間に立って、スムーズなコンピュータの動作を支える役割を果たしている。

一方、狭義のOSは、Kernelとも呼ばれ、基本ソフトウェアの中の制御プログラムに相当する部分のことを指す。つまり、コンピュータのハードウェアを制御する最も重要なプログラムであるカーネルだけを指します。狭義のOSには、デバイスドライバ、ファイルシステム、プロセス管理、メモリ管理などの機能が含まれる。



## ソフトウェアとは
ソフトウェアは大きく以下3つに分けることができる。

#### 基本ソフトウェア
基本ソフトウェアは、OSやデバイスドライバ、仮想マシンなど、コンピュータシステム全体を制御するためのソフトウェア。ユーザーが直接操作することはできず、裏で動いているもの。（後ほど詳しく書きます）

#### 応用ソフトウェア
応用ソフトウェアは、ユーザーが直接操作するためのソフトウェアで、ユーザーが行いたいタスクを実現するためのプログラム。例えば、Webブラウザ、ワープロソフト、ゲームなどが挙げられる。

#### ミドルウェア
ミドルウェアは、基本ソフトウェアと応用ソフトウェアの間にあるソフトウェアで、データベースシステム、Webアプリケーションサーバー、フレームワーク、ライブラリなどが挙げられる。ミドルウェアは、アプリケーションソフトウェアがシステムリソースを効率的に利用できるように、また基本ソフトウェアが応用ソフトウェアに必要な機能を提供できるように役立っている。


## 基本ソフトウェア

基本ソフトウェアには制御プログラム、言語処理プログラム、サービスプログラムの3つに分けることができる。


#### 制御プログラム

制御プログラムには、以下のような種類がある。

カーネル
OSの中核となるプログラムで、ハードウェアの制御や、プロセス・ファイル・メモリ管理などの機能を提供する。
カーネルは、OSの一部であり、直接操作することはできない。

カーネルには、メモリ管理やプロセス管理などに機能を限定したマイクロカーネルと、多くの機能を網羅したモノリシックカーネルがある。

ジョブ管理、タスク管理、記憶管理、データ(ファイル)管理などの管理を行う。

#### 言語処理プログラム(言語プロセッサ)

C言語やJavaなどのプログラミング言語で書かれたプログラムを、コンピュータが理解できる機械語に翻訳するプログラム。

コンパイラ
プログラマーが作成したソースコードを、実行可能なバイナリコードに変換するプログラム。コンパイルによって生成されたバイナリコードは、プログラマーが直接実行することができる。

インタプリタ
プログラマーが作成したソースコードを、逐次的に解釈して実行するプログラム。インタプリタは、実行するためのバイナリコードを生成せず、ソースコードをそのまま解釈して実行する。

アセンブラ
プログラミング言語で書かれたソースコード（プログラム）をコンピュータが理解できる機械語に変換しながら同時に少しずつ実行していく。


#### サービスプログラム

コンピュータの機能を補う、補助的なプログラムのことで、ユーティリティとも呼ばれる。
ファイル圧縮などが該当する。



#### 参考

[キタミ式イラストIT塾基本技術者](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C05%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF-%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297131862/ref=pd_lpo_1?pd_rd_w=VfHG0&content-id=amzn1.sym.d769922e-188a-40cc-a180-3315f856e8d6&pf_rd_p=d769922e-188a-40cc-a180-3315f856e8d6&pf_rd_r=N96994XZNT5B9Z58V3QJ&pd_rd_wg=5adiI&pd_rd_r=7e49d55a-0adf-4fc4-986b-4d28a7935a08&pd_rd_i=4297131862&psc=1)
RailsのrspecにてRecordNotUniqueが発生！！

# はじめに
rspecにてテストを書いていた際に起こった不可解なエラーについて今回は記載します。
間違い等ございましたらご指摘いただけますと幸いです。


# 起きた事象
rspecにて個別ファイルでテストを実施するとエラーにならないのに、テスト全部を一気に実施するとエラーになりました。
エラーの内容は下記です。

```java:エラー内容
 ActiveRecord::RecordNotUnique:
   Mysql2::Error: Duplicate entry '97' for key 'users.PRIMARY'
```

# まずは開発環境
- Ruby 3.1.2
- Rails 7.0.4
- RSpec 3.12

# 結論
userテーブルのidが重複したことによるエラーなので
テスト環境のuserデータを全て削除すれば問題なしでした。
私の場合Dockerを使っていたので、下記で修正完了です。
```java:bash
// テスト環境のRails consoleを開く
docker-compose run web bundle exec rails c -e test

// consoleを開いたらuserデータを全件削除
// 一応dependent: :destroyを指定して関連付けたデータも削除
// モデル名.destroy_allでOK
User.destroy_all
```

上記を実行したら、97というidのuserが削除されました。
その後rspecを実行すると無事にエラーにならず処理が完了しました。

めでたしめでたし


# 導き出すまで
エラー文をまずはしっかり読みましょう。(自戒の念を込めて)
エラー文にはuserテーブルのid97が重複していると教えてくれています。

ただなんじゃこれは状態です。
idの97だけが存在することなんてあるのか？という気持ちが解決までの時間をさらに引き延ばします。
ただ、テスト環境にuserを作ったわけでもないですし、ましてや97だけ？そんなわけないだろって思いますよね？？

でもdestory_allしたら確かにSQLが発行されていました。
本当にidが97だけ本当にできていたようです。

なぜか分かりませんが、どうやら`テストの途中で保存されていたらしい`です。
rspecの処理中にbinding.pryで値を確認していた際に何かの間違いで保存されてしまったのかも？
idが1じゃなくてもレコードが存在することはありえます！！(stap細胞)
どなたかの参考になれば幸いです。


参考：https://qiita.com/keisukee/items/cf0ccb6f7e8b4e8a775b
beep コマンドが使えない時の対処法

:::note warn
詳細はコメントを確認してください
:::

****

beep コマンドを使うとコマンドラインからbeep音を鳴らすことができます。
今回は`arch linux`を使用して解説していきます。

### beep パッケージのインストール
```shell:shell
sudo pacman -S beep
```
これでインストールは完了です。
### エラー発生
本来であれば
```shell:shell
beep
```
で音がなるはずなのですが、
```
beep: Error: Could not open any device
```
とエラーが出てしまい、verboseモードで実行すると
```shell 
beep --verbose
beep: Verbose: evdev: driver_detect 0x55b68e1e50c0 (nil)
beep: Verbose: lib: could not open(2) /dev/input/by-path/platform-pcspkr-event-spkr: Permission denied
beep: Verbose: console: driver_detect 0x55b68e1e4e60 (nil)
beep: Verbose: lib: could not open(2) /dev/tty0: Permission denied
beep: Verbose: lib: could not stat(2) /dev/vc/0: No such file or directory
beep: Error: Could not open any device
```
となり実行権限がたりなさそうな気がしたのでsudoをつけると
```
beep: Error: Running as root under sudo, which is not supported for security reasons.
beep: Error: Set up permissions for the pcspkr evdev device file and run as non-root user instead.
```
beepはsudoで実行したらだめみたいです。
`
### 対処法

/etc/beep.confに`device /dev/input/by-path/platform-pcspkr-event-spkr
`を追加すると良いみたいです。
```shell:shell
sudo vim /etc/beep.conf
```
エディタで開いたら以下の行を追加します。
```/etc/beep.conf
device /dev/input/by-path/platform-pcspkr-event-spkr
```
あとは保存すればbeepコマンドが使えるようになります。

以上です。
laravel＋コマンド

- プロジェクトの作成
 
```
laravel new プロジェクト名
```
- モデルの作成
```
php artisan make:model モデル名
```

- コントローラーの作成
```
php artisan make:controller コントローラー名
```
- マイグレーションファイルの作成
```
php artisan make:migration マイグレーション名
```
- マイグレーションの実行
```
php artisan migrate
```
- データベースシーダーの作成
```
php artisan make:seeder シーダー名
```
- データベースシーダーの実行
```
php artisan db:seed
```
- ルートの定義
```
Route::get('/example', [ExampleController::class, 'methodName']);
```
上記の例では、/example にアクセスされた時に ExampleController クラスの methodName メソッドを呼び出します。
- ビューの作成
```
touch resources/views/ビュー名.blade.php
```
- キャッシュの削除
```
php artisan cache:clear
```

- コンフィグのキャッシュの削除
```
php artisan config:clear
```

- ルートキャッシュの削除
```
php artisan route:clear
```
- ビューキャッシュの削除
```
php artisan view:clear
```

- コントローラーの作成（リソースコントローラー）
```
php artisan make:controller コントローラー名 --resource
```

- リソースルートの定義
```
Route::resource('リソース名', 'コントローラー名');
```
- モデルファクトリーの作成
```
php artisan make:factory ファクトリー名 --model=モデル名
```
- モデルファクトリーの実行
```
factory(モデル名::class)->create();
```
- サーバーの起動
```
php artisan serve
```
【対処法】StaticMeshComponent0 has to be 'Movable' if you'd like to move. 

# Massage Logで出てきたエラー
```
Mobility of /Game/FirstPerson/Maps/UEDPIE_0_FirstPersonMap.FirstPersonMap:PersistentLevel.StaticMeshActor_UAID_50EBF6D696A1817301_1130467303 : StaticMeshComponent0 has to be 'Movable' if you'd like to move. 
```
level　blueprintからアクターを動かそうとしたらでてきたやつ
動かしたいなら'Movable'にしろって言ってる
# 解決方法
![UnrealEditor_gKyrcBvGcF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/8cc4ab04-94f2-9f62-afef-96883e5920c5.png)
対象のアクターのTransformにあるMobilityをMovableにするだけ

自分は脳みそ止まってたのでこれに気付くまでに３０分かかりました対戦よろしくお願いします
【Rails】お気に入り機能いいね機能

# お気に入り機能（いいね機能）を付ける

「いいね機能」のテーブル設定
<table>
<thead>
<tr>
<td>カラム名</td>
<td>データ型</td>
<td>カラム名説明</td>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td>integer</td>
<td>いいねごとのid</td>
</tr>
<tr>
<td>user_id</td>
<td>integer</td>
<td>いいねしたユーザーのid</td>
</tr>
<tr>
<td>book_id</td>
<td>integer</td>
<td>いいねされた本のid</td>
</tr>
</tbody>
</table>

-----

```php:app/models/favorite.rb
class Favorite < ApplicationRecord

  belongs_to :user
  belongs_to :book
  
end

```


```php:app/models/book.rb
class Book < ApplicationRecord

  belongs_to :user
  has_one_attached :image
  has_many :favorites, dependent: :destroy #これを追加
  :


  def favorited_by?(user)                   #この3行も追加
    favorites.exists?(user_id: user.id)
  end

end

```


```php:app/models/user.rb
class User < ApplicationRecord

.
.

has_many :favorites, dependent: :destroy #追加
```


```php:app/controllers/favortes_controller.rb
class FavoritesController < ApplicationController

  def create
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.new(book_id: book.id)
    favorite.save
    redirect_to book_path(book)
  end

  def destroy
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.find_by(book_id: book.id)
    favorite.destroy
    redirect_to book_path(book)
  end

end

```
【PHPerKaigi】オフラインカンファレンスの魅力

PHPerKaigi2023の参加レポートです。

## なんで参加したか

普段研修講師をしていると、
なかなか現場でコードを書くというのが難しく、
どうしても「現場感」が薄れてしまうなという危機感があります。

また、学習モチベーションも下がり気味だったので、
なんとかしたい、と思っていました。

そんなときに目についたのがPHPerKaigi。

いま現場で活躍されている方が、

- どんなことに興味があるのか
- どういったことに苦労しているのか
- どんなモチベーションで開発しているのか

を知りたい！　ということで参加することにしました。

## 参加してみてどうだったか

とにかく面白かった。

この一言に付きます。

私は、Day1(という名前の２日目)から参加したのですが、
オープニングから活気に驚きました。

拍手の大きさ（３割増しでなくても大きい）から、
お祭り感あふれるというか、みんなこの日を待っていたんだなというのが伝わってきました。

各トークや参加者とのコミュニケーション、イベントとしての盛り上げ方も良い意味で驚かされることばかり。

申し込む前はややグズっていましたが、参加して良かったです。
(申し込むのが遅くなって名札が手書きとなったことが残念・・・)

## 気になったトーク
今回、LTを除き、14本のトークを聞きました。
その中でも特に印象に残っているものをご紹介。

### PHPで学ぶCache距離の話
@hanhan1978

https://fortee.jp/phperkaigi-2023/proposal/280706e0-7158-4237-8202-c9d64330b96f

効果的なキャッシュ運用について、「距離」という観点からのトーク。
速い遅いの結果だけでなく、なぜそうなるのか、をわかりやすく説明されていました。
「なんとなくキャッシュ」、ダメ絶対。

https://speakerdeck.com/hanhan1978/study-cache-with-php

（手書きの図の作り方を教わったので、今度使ってみようと思っています）

### 時間を気にせず普通にカンニングもしつつ ISUCON12 本選問題を PHP でやってみる 
@sji_ch

https://fortee.jp/phperkaigi-2023/proposal/7e212cb2-be37-43e8-b6ee-5236d259fcbf

ISUCON優勝者の実装を参考に、PHPで本選問題にチャレンジするというトーク。
PHPでどのように戦うかというだけでなく、計測した上でボトルネックに対してアプローチするということがどういうことなのか、非常に興味深かったです。
（「PHPで学ぶCache距離の話」を聞いた後だったので、なおさら分かりやすかった）

https://speakerdeck.com/sji/shi-jian-woqi-nisezupu-tong-nikanningumositutu-isucon12-ben-xuan-wen-ti-wo-php-deyatutemiru

### CodeCrafters にチャレンジして PHP で Redis を作ってみる
@gennei 

https://fortee.jp/phperkaigi-2023/proposal/dc54af9b-f879-47b6-9737-12ae6e84bf1d

CodeCraftersというサービスを使った学習法についてのトーク。
「車輪の再発明を通じてプログラミング」を学ぶというコンセプトが素敵で、言語のことも技術のことも学べるのは一石二鳥で良いなと思いました。

本当の初学者には少し難しいかなと思いつつ、研修に役立てられないかな？と思慮しています。

https://speakerdeck.com/gennei/codecrafters-nitiyarensisite-php-te-redis-wozuo-tutemiru


### 問い合わせ調査に素早く回答するための「アキネイター」的アプローチの模索
@myblackcat7112 

https://fortee.jp/phperkaigi-2023/proposal/538a222e-0e86-4cd3-ac3d-fdcd7a280f35

「非開発」な開発者の仕事のひとつである「問い合わせ対応」。属人化していた業務をどのように効率化していくかというトークでした。

miroやUMLを使用するなど、試行錯誤の様子が伺えて面白かったです。運用を進めるうちに、「育ってきた」という感想が出たのが良いなと感じました。

figmaで作って、プロトタイプ機能とかで遷移できるようにしたら面白そうだなと思いつつ、検索に課題がありそう。

https://speakerdeck.com/myblackcat7112/phperkaigi-2023-wen-ihe-wasediao-cha-nisu-zao-kuhui-da-surutameno-akineita-de-apurotinomo-suo

### Laravelへの異常な愛情 または私は如何にして心配するのを止めてEloquentを愛するようになったか

@KentarouTakeda 

https://fortee.jp/phperkaigi-2023/proposal/6211083d-fc51-49a3-8b27-485d8e231b1f

スライドタイトルから魅力的でしたが、言葉の一つ一つが重く、哲学的な感銘をうけました。

- 技術を知るにはその技術が解決しようとしている課題を知るべき
- FWが用意した答え＝ベストプラクティス

といった言葉が重かったですね。「本当に理解するとは？」と考えさせられました。

Laravel内部の相関図が非常にわかりやすかったです。過去の自分に教えてあげたい。

https://speakerdeck.com/kentaroutakeda/laravelhenoyi-chang-naai-qing-matahasi-haru-he-nisitexin-pei-surunowozhi-meteeloquentwoai-suruyouninatutaka


## 来年も参加したい

書ききれませんでしたが、他のトークも面白く、本当に時間が経つのがあっという間でした。

トークの他にも、

- スポンサーブースのクイズ
- ポスターセッション
- アンカンファレンス

何から何まで面白い内容でした。

今回、トーク内容としては、
「推測するな、計測せよ」というものが多かったように感じます。

私が普段担当している新人研修のレベルでは、
なかなか伝えにくい内容ですが、
こういったどんどん情報も伝えていきたいですね。

また、エネルギッシュな皆さんを見えているうちに、
モチベーションも高まったので、明日の成長に繋げたいですね。
（なんやかんやで運良く二冊ほど本もいただきました）

ぜひ、来年も参加したいと思っています！
自分のような「なんちゃってPHPer」でも楽しめるので、非常におすすめです！
MEMZを入れなくてもNyanCatを聞く方法

ネタです。
動作環境
+ arch linux
 
Ubuntuとかはbeepを各自インストールしてください。
### beep のインストール
```shell:shell
sudo pacman -S beep
```
beepコマンドが使えないときは以下を参考にしてください。

https://qiita.com/H-goto16/items/0d2ade41be1f1b5514ca
### NyanCatのデータの入手
```shell:shell
git clone https://github.com/ShaneMcC/beeps.git
```
### 再生
```shell
cd beep
./nyancat.sh
```

これでスピーカーではなくbeep音でNyanCatが聞けます。

~~MEMZのNyanCatと少し違いますが雰囲気は味わえます。~~
MacOSにMicrosoft Edgeで作成したAppが残ってしまった時の対処法

## 事象
MacOSにMicrosoft Edge（以降Edgeと記載する）をインストールした後にEdgeのWEBページからAppを作成。その後Appより先にEdgeをアンインストールしてしまうとAppが残ってしまいLaunchpadからアンインストールできなくなってしまう。

## 対処方法
1. Finderかターミナルで「/Users/ユーザ名/Applications」に移動する。
1. 「Edge Apps.localized」というディレクトリを削除する。

以上
Python演習問題100本ノック買った

100本ノックに日和ってるやついる！？いねえy…
俺だああああああああああああああ！！！！

ってことでいきなり100問はヤバそうだったのでまずはどんな感じなのか…

https://norari-kurari-way.com/python-lesson/

こちらのサイト様の練習問題10問やってみた。


○1問目
四則演算で「？」ってなったのは「f"{}"」で、意味分からんかったから調べてみた。

『f文字列。print関数などで違うデータ型を出力する時、それぞれ分けて記述する必要があるけど、f文字列を使うと変数や数値を埋め込むことができる。』

めちゃくちゃ便利やんけ。


○2問目
これは何か出来た。「int(input(""))」使うんだﾙｫｫｵｵ！！って感じ。


○3問目
これfor文か？までは行ったんだけど文法が全然出てこなくて手が止まった。
毎回思うけど「for i in range」の「i」って何なん？って疑問になったから調べた。

『「index」なり「integer」なりの先頭文字だから(ｷｯﾊﾟﾘ)』

そんなんでいいのか…いいみたい。(適応の天才)


○4問目
またもやfor文ってことは前回の文法と同じようになるんじゃ、って思ったけどそんな甘くなかった。
例えば「if i %4 ==0」のように倍数にするには「%数値」の形になる。
これの「if」はどっちもで、そうじゃなかった場合は片方だから「elif」が2つの条件が必要で、それ以外は「else」になる。コロンのつけ忘れが無くなってきたから意識できてるZE🌟


○5問目
listの「l」に[]を代入する。あとはfor文。「.append()」ってなんだっけ？って思ったそこの俺！！
これは文字列を追加するぜ！！()の中に””で囲って指定するとできるぜ！！！！！


○6問目
「sum」はexcelでも使ってるやつ？って感じだった。文法全然出てこなかったけど…
ここは練習で慣らしてく。


○7問目
これは代入時「dic = {}」でやったんだけど回答が「d　=　{}」だったってとこ以外は出来た。
1問目の「f""」も使えるようになってきた。


○8問目
「変数名.update」で追加できるのか。「変数名["文字列"]=数値」で追加できるのしか思いつかなかった。てか思いついただけえらいぞ俺👏


○9問目
最大値は「max_value」で求められる。なるほど( ﾟдﾟ )ｸﾜｯ!!
もうひとつは「max」を使う。


○10問目
「for 変数名,変数名 in zip()」のzipって何ぞや？圧縮してんの？？調べた。

『複数のリストの要素をまとめて取得したり、複数のリストを結合したい時に使う。』

なるほどそういうことね💡完全に理解した(唐突なポプテピ)



------------------------------------------------------

文法が全然浮かばなかった。
これが今の実力なのかって思うと、逆に考えればまだまだ上を目指せるってことだよね。
こういうのって全然出来ないとネガティブになったりするかもだけど、基礎を流れるようにやってスラスラできたら世の中エンジニアだらけやて。
落ち込んでる時間がもったいないから、何周もして頭と身体に慣れさせて行く時間に当てるぞ。
ReactNativeでのアプリ開発、ExpoSDKがいい感じになってきたようなので試してみた：その１

# はじめに
2018年ごろからReactNativeを利用してのiOS/Androidモバイルアプリ開発に関わってきました。
（もっと前はJavaとObjective-Cで・・・）

Expoというものの存在は知ってはいたのですが、「手っ取り早くアプリを作れるが制約が多いツール」という認識でした。
特に、予め用意されている以外のネイティブ利用コードを使うためにはejectが必要になる、という点が、業務で利用する場合は使えないことが多いだろうと考え、深く知る機会もないままでした。

月日は流れ2022年の終わり頃、OTAアップデートを導入しようとCodePush（VisualStudio AppCenterのアレ）とExpoを比較するために調査していて、Expo SDK 47のドキュメントを眺めていました。
どうやら以前とかなり様子が違うようで、Development Buildを利用することでカスタムネイティブコードを導入することが可能で、かつExpo Goのような手軽さで開発が回せそうなこと、"eject"も死語になっていること、などが書かれており、これはちょっと試してみよう、と思い立って少し触ってみました。

せっかくなので、整理して記録しておきます。

何回かに分けて、次のようなネタを扱う予定です。
- 土台作り
- Expo Module作成
- の前にモノレポ化
- Development BuildをEASで作る
- Expo Router

ReactNativeそのものや、コンポーネントの作り方・・・などについては触れないつもりです。

# 最初のサンプルアプリを作る
## 事前準備
使用マシンはMacですが、Mac依存な部分はそれほどないつもりです。
（iOSシミュレータを利用してる箇所などはWindowsでは無理なのでAndroidエミュレータで）

以下がインストールされている環境です。
（とりあえず関係ありそうなものだけ）
- Visual Studio Code
- Node.JS (v16だった)
- yarn (v1)
- ruby (プリインストール)
- cocoapods

rubyとcocoapodsはMacの場合ですが、ネイティブのビルドをローカルで実施しない限り不要なはず。

後ほど[EAS](https://docs.expo.dev/eas/)(Expo Application Services)を使いますが、それまではExpoアカウントは不要です。

## Create a new app
[公式ドキュメント](https://docs.expo.dev/get-started/create-a-new-app/)を参考に、テンプレートから作成します。
が、yarn使いたいので、コマンドは以下です。
```shell
yarn create expo-app ExpoLab -t expo-template-blank-typescript@sdk-47
```
アプリ名はExpo実験場なので`ExpoLab`としました。
TypeScriptのテンプレートを選択しています。
本記事執筆時点でSDK48がリリース済みで、後ほどアップグレードを確認したいために、あえて`@sdk-47`を指定しています。
（最新でいい場合はSDK指定はナシで大丈夫です）

作成された`ExpoLab`ディレクトリ以下はこうなっていました。
```
├── assets
│   ├── adaptive-icon.png
│   ├── favicon.png
│   ├── icon.png
│   └── splash.png
├── node_modules
├── App.tsx
├── app.json
├── babel.config.js
├── package.json
├── tsconfig.json
└── yarn.lock
```

自動でgitに"initial commit"までされています。

何はともあれ動かしてみます。
```shell
yarn start
yarn run v1.22.19
$ expo start
Starting project at *****/ExpoLab
Starting Metro Bundler

（ここにQRコード）

› Metro waiting on exp://192.168.0.11:19000
› Scan the QR code above with Expo Go (Android) or the Camera app (iOS)

› Press a │ open Android
› Press i │ open iOS simulator
› Press w │ open web

› Press j │ open debugger
› Press r │ reload app
› Press m │ toggle menu

› Press ? │ show all commands

Logs for your project will appear below. Press Ctrl+C to exit.
```
「ここにQRコード」の部分にQRコードが表示されます。
（行間が広くて、いい感じに表示させられなかったので割愛）

このコードを手持ちのスマホで読み込むとExpo Goが起動して、JSバンドルがロードされます。
（Expo Goが未インストールならインストールされるはず。多分。知らんけど）

手元にスマホがない場合（？）、<kbd>i</kbd>キーでiOSシミュレータが起動します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243061/6e7408b6-063b-023b-3e6e-ca93b331dc8c.png" width="50%">

とりあえず土台ができたので、ここから色々と~~遊んで~~試していきたいと思います。

つづく
tableauのダッシュボード上でフィルターを追加する

# はじめに
tableauのダッシュボード機能では複数のワークブックを同時に表示させることができます。
ワークブックでは集計したい項目および条件の絞り込みなどをパラメータやフィルターなどで設定できます。

私は上記のような認識からダッシュボード上ではフィルターやパラーメータを追加できないと思っておりました。
しかし、いろいろ検証していると、ダッシュボード上でも追加できることがわかったため、今回記事にしました。

私はこの機能に初め気づかず、ワークブックのフィルターを更新するたびダッシュボードを
新しく作り直して膨大な時間を費やしていました。
この機能を忘れないためにも備忘録として記載します。

# やりたいこと
ダッシュボード上の操作でフィルターやパラメータを追加します。
以下の図左から右のようなダッシュボードを作成します。
図のダッシュボードの右赤枠にフィルターが表示されますが、赤枠の項目が表示されることがゴールとなります。
(フィルターもパラメータも追加方法は同じなので今回はフィルターの追加をいたします。)
![x５.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522066/2329930a-2720-89ac-c3b7-94ccf879e39e.png)
※データはtableauのサンプルデータのスーパーマーケットを使用

# 手順
①ダッシュボード上の画面をどこでも良いのでクリック。
②下図の右赤枠部分をクリック。
![x６.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522066/512d5a7b-7046-b229-c0d4-ef270c9d98d7.png)
③フィルターを選択。
④表示させたい項目を選択するとダッシュボード上でフィルターを表示できます。
　今回はRegionを選択。
![x７.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522066/ecda905f-fc38-242a-9708-0f548909aed8.png)
※注意点として、④に表示される情報はビューで使用している項目およびフィルターに設定されている項目となります。
　利用の際は上記の点にご注意ください。

上記までの項目を実施することで上図のようなダッシュボードの作成が完成します。

# おわりに
他にも方法があるかもしれませんが、本記事が皆さんの解決の方法の一つとなれば幸いです。

今後もこの様な形でtipsを投稿していければと思います。