OmniAICreator/Qiita-1.07M huggingface dataset:
再配置可能プログラムとプログラムの４つの性質

# 再配置可能プログラム
CPUはメモリアドレスをレジスタへ読み込んでいる。
主記憶上でプログラム全体が別の場所へと移動する。
中断された次の命令が納められているメモリアドレスも変化している。
これに```ベースアドレス指定方式```を使う。
プログラムが主記憶上にロードされた時の、先頭アドレスからの差分を使って命令やデータの位置を指定する。
このような性質を持つプログラムを、再配置可能プログラムと呼ぶ。

# プログラムの４つの性質
## 再配置可能（リロケータブル）
主記憶上の```どこに配置しても実行することができる```性質

## 再使用可能（リユーザブル）
主記憶上にロードされて```処理を終えたプログラムを、再ロードすることなく、繰り返し実行できる```性質

## 再入可能（リエントラント）
```複数のタスクから呼び出されても、お互いに干渉することなく同時実行できる性質```。
* プログラムの中に```手続き部分とデータ部分に分けられている```。
* データ部分を```タスクごとに持つことでお互いに干渉せず並行して動作```できる。
* 使用した変数の値を、プログラムの```最初か最後に初期化しておくことで繰り返しの実行```に備える。

p２５０の図

### タスクとは？（忘れた）
CPUの実行単位
ジョブをジョブステップに分解した後タスクを生成してコンピュータが仕事をする。

## 再起的（リカーシブ）
```実行中に自分自身を呼び出す```ことができる性質。
フォルダを探すために繰り返し調べて渡して、渡されたファイルをまた探す。

## 気づき
こういうプログラムには性質を持っていることなのかな。
いまいち理解が追いついていない。
これからまた勉強だ。
ペースアドレス指定方式がここに出てくるのか。

# 問題を解いた時の気づき
## イベントドリブンとは？
* コンピュータプログラムの開発および実行方式の一つで、```利用者や外部の別のプログラムなどが引き起こす出来事に対応する形で処理を記述あるいは実行する```方式。

開発者は「操作画面上のメニューが選択された」「キーが押された」など、利用者が行う個々の操作などに応じて起動され、対応した処理を行うプログラム部品（モジュール）を記述する形でソフトウェアを開発していく。

```ソフトウェア側に通知される出来事は「イベント」（event）```と呼ばれ、利用者による入出力装置の操作だけなく、周辺機器や装置の状態の変化、外部の他のプログラムからの通知、例外やエラーの発生などを受け取ることもできる。通知に呼応して呼び出せるようにしたプログラムを「イベントハンドラ」（event handler）あるいは「イベントリスナ」（event listener）という。
出典 https://e-words.jp/w/%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%83%89%E3%83%AA%E3%83%96%E3%83%B3.html

* ```イベント駆動型プログラミングとは```
プログラミング手法の1つ。```「イベントドリブン」```とも呼ばれる。マウスを操作したり、キーを叩いたりするといった```要求が発生したとき処理を実行するようにプログラムを記述するプログラミング手法```。イベント単位でプログラムを記述するため、```処理の分割や開発が容易になる```。

```「ボタンをクリックすると写真が反転する」「画面をスワイプするとページが替わる」```といったパソコンや携帯端末で当たり前のように使っている機能にも、イベント駆動型プログラミングが利用されている。
例えば、パソコンや携帯端末のOSが「ボタンのクリック」を感知すると、それをメッセージとしてアプリケーションに伝え、そのメッセージに関連付けられたプログラムがあれば、それを実行する。ちなみに```プログラムの実行中に発生する出来事を「イベント」```といい、```イベントに応じて実行するプログラムのことを「イベントハンドラ」```という。

イベント駆動型プログラミングと対比されるのは、「フロー駆動型プログラミング」である。これは、プログラムに記述された処理の流れに沿って、すべてが実行されるプログラミング手法。多くの手続き型言語がこのプログラミング手法をとっている。
出典 https://mypage.otsuka-shokai.co.jp/contents/business-oyakudachi/words/event-driven-type-programming.html

## 気づき
説明を読んで、
『あらかじめ決められた順番ではなく、起きた事象に応じた処理を行う』のが
イベントドリブンだな。

出典 キタミ式イラストIT塾　基本情報技術者　令和03年
【Django】Adminページの「Django 管理サイト」の文字は3分で変えられる（CSSも）

## Adminページは便利

Djangoの管理ページはとても便利なので極力そのまま利用したい。

でも、ページ上部には「Django 管理サイト」と大きく表示されていてちょっともやもやする。

きっとプロジェクト名やアプリ名だったらいいのにと思っている人は多いはず・・・ｗ

ということで、さくっと変更しちゃいましょう。

## いじるのはAdmin.pyのみ

アプリのadmin.pyを開き、次のコードをコピペするだけでOKです！

:::note info
下記の日本語の部分を変えると表示が変わります。
:::

```Python:admin.py
from django.contrib.admin.sites import AdminSite

AdminSite.site_header = 'Django 管理サイト'
AdminSite.site_title = 'サイト管理者'
AdminSite.index_title = 'サイト管理'
```
たったこれだけ！

変更が必要ない部分は削除しちゃってください。


## 他にも色々あったりする

| 属性 | 説明 |
|:-:|:-:|
| site_header | 上部にあるh1テキスト。デフォルトは「Django 管理サイト」 |
| site_title | ページタイトルの後ろにつくtitleテキスト。デフォルトは「Django管理者」 |
| site_url | 「サイトを表示」のURLリンク。デフォルトはsite_url。削除する場合はNone |
| index_title | インデックスページ上部の文字。デフォルトは「サイト管理」 |
| index_template | 管理サイトのメインインデックスビューで使うカスタムテンプレートへのパス |
| etc... | 　|

公式ドキュメントで全て確認できますので興味のある方はどうぞ！

https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#adminsite-objects

## CSSも簡単に変更できる

`templates`フォルダの中に、`admin`フォルダを作成し、その中に`base.html`を作り以下を記述すると色が紫になる。

```html:base.html
{% extends 'admin/base.html' %}

{% block extrastyle %}{{ block.super }}
<style>
:root {
  --primary: #9774d5;
  --secondary: #785cab;
  --link-fg: #7c449b;
  --link-selected-fg: #8f5bb2;
}
</style>
{% endblock %}
```


以上、簡単にですが、文字の変え方とCSSの書き方でした！
Java基礎 まとめ

基本知識
<details><summary>・ネスト</summary>
□{ } の中に { } を記述すること
</details>

<details><summary>・ブロック</summary>

![スクリーンショット 2022-08-02 13.42.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061654/9cfe6909-76c1-4277-2026-33ee7d96a6e7.png)
</details>

<details><summary>・変数宣言</summary>
□変数を新しく作ること<br>
型名 変数名 ;<br>

```
int age;
```
</details>

<details><summary>・初期化</summary>
□変数宣言と同時に値を代入すること<br>
型名 変数名 = 初期データ;<br>

```
int age = 20;
```
</details>

<details><summary>・定数</summary>
□初期化された状態からデータを変更することのできない変数のこと<br>
※定数名は半角英数の大文字で記述することが一般的<br>
final 型名 定数名 = 初期値(固定値);<br>

```
final String USER_NAME = tarou;
```
</details>

<details><summary>・リテラル</summary>

![スクリーンショット 2022-08-02 14.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061654/fe70e289-ee99-d6c2-5d69-06ee90e135eb.png)

</details>

基本ルール
<details><summary>・ファイル名とクラス名を同じにする</summary>

ファイル名：Sample1.java

```java
class Sample1 {

}
```
</details>
CircleCIのローカル実行で詰まった話

Error: tar: main.go: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

circleci local execute を実行したのだが上記エラーが発生していた。
原因としてはチェックアウトするのはローカルのリポジトリの内容でコミットしないで実行していたからだった。
コミットしたら正常に動作した。
「A Tour of Go」 の Exercise: Fibonacci closure を解きました

引き続き、Goの公式のチュートリアル「[A Tour of Go](https://go-tour-jp.appspot.com/list)」を読み進めています。当記事は、関数の一種「クロージャー」に関する練習問題「[Exercise: Fibonacci closure](https://go-tour-jp.appspot.com/moretypes/26)」を解いた記録です。

# コード

```go
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	first := 0
	second := 1
	result := 0
	return func() int {
		result += first
		first = second
		second = result
		return result
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

```

# 解説
フィボナッチ数列はご存知かと思います。f(n)=f(n-1)+f(n-2) (n>=0)で表される数列です。f(0)=0 f(1)=1が与えられると、
```
f(2) = f(0)+f(1) = 1, f(3) = f(2)+f(1) = 2, f(4) = f(3)+f(2) = 3,
f(5) = f(3)+f(2) = 5, f(6) = f(4)+f(5) = 8, f(7) = f(5)+f(6) = 13 ...
```
という感じで直前の2つの値が結果となります。なので直前の値の和を結果とし、結果を求めたら右に1つずれるイメージで変数を更新すれば上手く行きます。

# 最後に
対して解説することもありませんでしたが、同じような境遇の方のご参考になれば幸いです。
Buefy触ってみた

## はじめに
最近Vueの勉強をしているのですが、見た目に凝るのはなかなか大変でそんなときに超便利なUIコンポーネントセットのBuefyなるものを知ったのでちょっと触ってみました。

またいつかBuefyを利用したアプリも公開したいですが、今回は備忘録がてら簡単な紹介のみです。

## Buefyのインストール

そもそもですが、Buefyは公式のドキュメントが非常にわかりやすく整備されているので[公式ドキュメント](https://buefy.org/documentation/start)を見れば大体わかります。

とはいってもそれでは書くことがないのでインストール方法は以下となります。

```
npm install buefy
```
インストールできたらmain.jsに以下の設定を加えれば準備完了です。
```main.js
import Vue from 'vue'
import Buefy from 'buefy'  //追記
import 'buefy/dist/buefy.css' //追記

Vue.use(Buefy) //追記
```

## どんなUIを使えるのか
以下、すごい適当ですがアプリケーションを作るときに大体欲しいのは揃っていますし、カラッピッカーやカレンダーの入力も用意されているのはありがたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/7c07f4c9-fb2a-6516-4886-a861d28117ac.png)

上記のようなUIをCSSノータッチで大体は1行くらいで簡単に書けちゃうのは非常に便利ですね。
[公式ドキュメント](https://buefy.org/documentation/start)にはほかにも様々なUIセットとサンプルコードが用意されているため作りたいアプリケーションのイメージと照らし合わせてドキュメントを眺めるだけでも楽しそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/d1d8933c-59e5-f0f1-5139-5a7f60e0a4b6.png)

以上。簡単な紹介でした。
また、Buefyを利用したアプリケーションを作った際には記事にしたいと思います。
CoolerMasterのソフトウェア、MasterPlus+がクラッシュし続ける

## 症状
私はCoolerMasterのMM720というマウスを買ったのですが、そのソフトウェアMasterPlus+が起動も遅いし永遠にクラッシュし続けてました。

## 結論
v1.0.7にダウングレードしたらうまくいきました（ケースのライトとかはピカピカできないかも）

↓ ダウングレードのソース（v1.6.7とかそのあたりは全部クラッシュしました）

https://www.reddit.com/r/coolermaster/comments/s5x24t/comment/ht2umwi/


https://www.reddit.com/r/coolermaster/comments/q4ck09/cooler_master_masterplus_v170_released/

ちなみに、ダウングレードすると毎回アップデートを求められるので、
```
\Program Files (x86)\CoolerMaster\MasterPlus　
```
にあるRENEWというファイルをrenameするなり、削除するなりすると求められなくなります。
pythonで引数のデフォルト値にリストを指定した場合の動作

# なぜこんな記事を？
pythonには、割と理解し難い仕様が含まれていますが、引数のデフォルト値にリストなどを指定した場合の問題は、特に理解しづらいようです。

私の持っている書籍には、この問題に対して1ページ使いながら、「ある種グローバルな変数を参照することになり．．．」という説明をしています。しかしこの説明は間違ってはいませんが、不適当です。

# 何が起きるのか
引数のデフォルト値にリストを指定したら、何が起きるかをサンプルで示します。
```python:sample
def func(a, b=[1]):
    b[0] += a
    print(b[0])

func(1) # --> 2
func(1) # --> 3
```

同じ引数で2回実行すると、結果が変わりました。呼び出す度に結果が異なる関数が出来てしまいました。

より複雑なコードでこの様なバグを作ってしまうと見つけづらいと思われます。例えば、引数bを指定する場合としない場合が混在しているケースでは、バグの原因を特定するのに時間がかかるかも知れません。

# 動作
どうして上記の様な結果になったのでしょうか。
ポイントは、**def文が宣言文ではなく、他の要素と同様に命令文である**ということです。def文は、関数型のオブジェクトを生成し、それに名前をつけて格納する命令文です。

そして、引数のデフォルト値は、遅延評価されず、def文の実行時に行われます。
ここにpythonにおけるリストなどのimmutableな型の値の扱いが関わってきます。

上記の例では、`[1]`を格納した無名のリストが生成され、その参照が変数bのデフフォルト値とされる様になります。
変数bが引数で与えられなかった場合、2行目のコードは、def文を実行時に`[1]`を格納していた無名のリストの中身を書き換えます。このために、同じ引数を与えて実行した2回目の結果が変わるのです。

この仕様を理解すべきことは、**def文は実行文で、デフォルト値の評価はdef文実行時に行われる**ということです。

# 対処方法
この仕様への対処方法は、下記のようにデフォルト値にimmutableな値を与えないことです。

```python:sample2 (対処済み)
def func2(a, b=None):
    if b is None:
        b = [1]
    b[0] += a
    print(b[0])

func2(1) # --> 2
func2(1) # --> 2
```

## その他の仕様の理解のヒント
pythonで分かり難い仕様は、インタプリタとしてどう動作するのかを想像すると、理解し易いことが多いです。
また、デコレータの様なSyntax sugar (構文糖衣)な仕様については、同等の動作をするコードを知り、それを簡単に描けるようにしているだけだと考えた方が理解し易いかと思います。
下に示した参考図書も、分かり難い仕様の理解に役立つものです。

### 参考ページ、図書
* [Python 3.10.4 ドキュメント なぜオブジェクト間でデフォルト値が共有されるのですか？](https://docs.python.org/ja/3/faq/programming.html#why-are-default-values-shared-between-objects)

* 『python文法詳解』(オライリー)
未経験で独学中

・pythonを勉強するが。。
だめです。未経験で募集がありません。

私は、工業高等専門学校の機械科を専攻していたのですが、意外にもプログラミングとかかわることが多く、卒業研究で「機械学習についてやってみてくれ」と言われ、pythonを独学で学びながら取り組むことになりました。
最終的には、サル、犬、猫の判別ができる画像識別のプログラミングを参考書などを見ながら作成。識別できたから何ができるんだ。。。？というのが最初の意見でした。

　その後は、機械系の修理部門に就職し、4年間働いた。4年間働いても自信もっていえるスキルはほぼゼロに等しい。。。人手不足の中働いているとほしくなってくるものは自動化。機械学習で画像で覚えさせできそうじゃね。。？4年もプログラミングを忘れ、ゲームと仕事に打ち込んでいたら、まあ、知識は0よね。
　エクセルの自動化から行い少しづつプログラミングの楽しさがわかり、またpythonを思い出しながら環境構築を行った。かといってビッグデータはないし、なにも作れなくない？？？

世の中の機械業界はだんだん人口が減っているため人手不足や人件費などを削減した部分と現場からわかっているため、プログラミング業界に参入してみればいいじゃないかと感じ、プライベートで勉強、転職活動。


あれ、、、？「【募集要項＜必須＞】業務経験二年　開発の経験があるかた」。

無理や――――ン！！業務を一度でも積むために探しているのに業務経験二年って！？！？
未経験からの中途が難しいといわれている理由が分かった。

途方に暮れているなう


皆さんが投稿しているような見た目にならないな～
TypeScript(JavaScript)によるカタカナ五十音順の行を判定

### はじめに

`Map`オブジェクトを使っています。  
キーは数字ですが、ニーズによって「第一行目」みたいな文字列に変更することができます。
下のコメント欄に他の方々からの方法もありますので、参考にしてください。みなさんありがとうございます。

### コード

[TypeScript Live Demo](https://codepen.io/kensoz/pen/eYMMqbY)
[JavaScript Live Demo](https://codepen.io/kensoz/pen/bGMbKNg)


```typescript
  // TypeScript

  const handleNameCode = (str: string): number => {
    // カタカナ定義
    const kana: Map<number, string> = new Map([
      [1, 'アイウエオ'],
      [2, 'カキクケコガギグゲゴ'],
      [3, 'サシスセソザジズゼゾ'],
      [4, 'タチツテトダヂヅデド'],
      [5, 'ナニヌネノ'],
      [6, 'ハヒフヘホパピプペポバビブベボ'],
      [7, 'マミムメモ'],
      [8, 'ヤユヨ'],
      [9, 'ラリルレロ'],
      [10, 'ワヲン'],
    ])

    for (let [key, value] of kana.entries()) {
      // 存在の場合、カタカナの行数のkeyを返す
      if (value.indexOf(str) !== -1) return key
    }

    // 存在しない場合、数字などの場合
    return kana.size + 1
  }
```

### 使用

```typescript
  console.log(handleNameCode('カ')) // 2
  console.log(handleNameCode('a')) // 11
```
Salesforceのダッシュボードで空欄日付のレコードのみ抽出しよう

Salesforceのダッシュボードには
・検索条件
がございます

今回は検索条件の設定で

### 「日付が空欄のレコードのみ表示」（日付が空欄ではないレコードのみ表示）
の設定の仕方をお教えします。


### 日付が空欄のレコードのみ表示　のダッシュボード設定方法

まずは「+検索条件」をクリック
「検索条件を追加」をクリックします
![検索１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/aa21cbf8-0e7a-bcc7-73ce-1f11d5949b48.png)


次に検索条件を以下のように設定します。
大事なのは「相対日付」に設定し
値を「""」と記載ください
![検索２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/695efb2d-3ca1-d6db-33bd-a0acf1a165fa.png)


このまま「更新」をクリックしダッシュボードを保存してください

保存した後、再度編集をすると

日付種別が（さきほどは相対日付を選んだはずですが）「カレンダー」となっていて
値が「」（何もなし。空欄）
になっているので確かに空欄の検索条件になっているのが分かります
![保存状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7b2f607d-15b1-6549-2d9e-a6ec3d9dcf7f.png)


実際にダッシュボードでも検索条件が空欄のレコードのみ抽出可能なので試してみてください。
【Rails】rails db:migrateが実行できない / PG::DuplicateTable: ERROR:  relation "users" already exists / PG::ObjectInUse: ERROR:  database "scaffold_app_development" is being accessed by other users

### 前提
Rails 6.1.6.1
ruby 2.6.6
database postgresql

### 実現したいこと
```rails db:migrate```をエラーなく、実行する。

### エラー内容の確認
```rails db:migrate```を実行したところ、次のようなエラーが出ました。
```
rails db:migrate
Running via Spring preloader in process 31813
== 20220802023637 CreateUsers: migrating ======================================
-- create_table(:users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DuplicateTable: ERROR:  relation "users" already exists

略

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicateTable: ERROR:  relation "users" already exists
```
エラー内容を見ると、「作ろうとしているusersはもうあるよ」ということでした。

いったん、```rails db:reset```を行おうとしてみたところ、次のようなエラーが出ました。
```
 rails db:reset
Running via Spring preloader in process 32451
PG::ObjectInUse: ERROR:  database "scaffold_app_development" is being accessed by other users
DETAIL:  There is 1 other session using the database.
Couldn't drop database 'scaffold_app_development'
rake aborted!
ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR:  database "scaffold_app_development" is being accessed by other users
DETAIL:  There is 1 other session using the database.

略

Caused by:
PG::ObjectInUse: ERROR:  database "scaffold_app_development" is being accessed by other users
DETAIL:  There is 1 other session using the database.

Tasks: TOP => db:drop:_unsafe
(See full trace by running task with --trace)

略

```
「他のユーザーがアクセスしてるからいじれません、他のセッションがDBを使っている」といった内容のエラーが出てきました。
「セッションが残っている」というところに目をつけて、データベースにアクセスしているユーザを確認することにしました。

### DBにアクセスしているユーザーの確認
```
psql scaffold_app_development
```

データベース名の確認方法(database.yml参照)
```
development:
  <<: *default
  database:　scaffold_app_development <= ココ！！
```
実際に、アクセス状況を確認する。

```
psql scaffold_app_development

psql (14.4)
Type "help" for help.

scaffold_app_development=# select * from pg_stat_activity;

略

(7 rows)
```
datnameにデータベース名が記載されているところがDBにアクセスしているユーザーになるので、その箇所を削除する。
pidを削除することでアクセスしているユーザーも削除できる。
こんな感じ。

```
kill 32414(pidに記載されている数字)
```
killコマンド実行後、再度```psql データベース名(database.yml内に記載されている)```を実行してみると、
```
psql scaffold_app_development
scaffold_app_development=# select * from pg_stat_activity;
server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
```

データベースにアクセスしているユーザーがいないことを確認した上で、```rails db:reset```を実行すると、
```
 rails db:reset
Running via Spring preloader in process 32553
Dropped database 'scaffold_app_development'
Dropped database 'scaffold_app_test'
Created database 'scaffold_app_development'
Created database 'scaffold_app_test'
略
```
問題なく実行できました。
初心者学習メモ　スネークケースとキャメルケース

## スネークケースとキャメルケース

プログラムを始めた際にスネークケース、キャメルケースという言葉を聞きましたが何のこと？
となったので簡単にまとめました。

スネークケースとは、単語の間を_でつなぐ命名規則です。
キャメルケースとは、単語の先頭を大文字にする命名規則です。

```
hot_coffee スネークケース
HotCofffee キャメルケース
```



### 命名規則をなぜ用いる？
命名規則がないと、関数や変数、class名がバラバラになり可読性が低くなります。
その結果バグの原因になったりもします。
仕事となればチームで開発することがほとんどです。
命名規則をしっかり守ることで、他の人が書いたコードでも変数なのか、関数なのか、classなのか判断ができるようになります。

初心者の私は、人によって見やすさが違い使い方は好みで違うのかな〜なんて思ってました...
実際はそれぞれの言語によって命名規則が決まっているみたいです。


### Railsの命名規則
クラス名 : キャメル
それ以外 : スネーク
定数 : 全て大文字
error: failed to push some refs to 'github.com:jojo232/raistech-aws202208.git'

git pishしようと思ったら下記エラー発生

```
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:jojo232/raistech-aws202208.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

このcommitを行う前に、私がリモートでgithubのREADMEの変更を行っていたことが
今回のエラーの原因でした。

「リモートのファイルがローカルのファイルも最新版だから、そのファイルにpushできないですよ」ということみたいです。

対処法
いくつか対処法があるみたいです。

①git pull origin develop
git pull origin developでリモートの環境をローカルファイルにpullした後、
再度pushを行う。

②git fetchした後、git mergeする
①とやっていることはほとんど変わらず、pull＝fetch + mergeという意味合いなのかと思います。

③git push ––forceで矯正的にpushする
こちらは、個人開発なら自分一人しかリポジトリを操作しないので大きな影響はなさそうですが、
チーム開発の場合だと自分以外にcommitやpushする人がいる無闇に使用すべきでは無い、という記事をいくつか確認しました。

まあ、再度作り直して、github上でファイルをいじらなければないも問題はなかったです。
NHK-FMのJAZZ

[NHKのAPI](https://api-portal.nhk.or.jp/)を使って向こう一週間のJAZZの放送の一覧を作ってみました。

NHK番組表APIのジャンルID(genre)の説明のARIBのpdfのURLがリンク切れになってるうえに、一般向けには[STD-B10](https://www.arib.or.jp/kikaku/kikaku_hoso/std-b10.html)は売り物で1万円以上します。^ ^;

世の中には親切な人がいて、一覧を上げてくれていてJAZZは0403でした。

```html
<!DOCTYPE html>
<html lang="en">
<script src="js/jquery.min.js"></script>
<script>
window.onload = function(){

  var key = "naisyo";
  const today = new Date()
  for (let i = 0; i < 7; i++) {
  const day = new Date(today)
  day.setDate(day.getDate() + i)
  var month = day.getMonth()+1;
  var date = day.getDate();
  var mstr = ('0' + month).slice(-2);
  var dstr = ('0' + date).slice(-2);
  var datestr = day.getFullYear() + "-" + mstr + "-" + dstr;
  $.ajaxSetup({async: false});
  $.getJSON("https://api.nhk.or.jp/v2/pg/genre/130/r3/0403/" + datestr + ".json?key=" + key , function(data) {
  if(data.list) {
  data.list.r3.forEach(function(val) {
$("#output").append("<li>" + val.start_time.slice( 0, -6 ) + " " + val.title + "</li>");
  })
  }
  });
    $.ajaxSetup({async: true});

  }
}
</script>

    <head>
                <meta charset="UTF-8" />
        <title>NHKJAZZ</title>
    </head>
    <body>
<ul id="output"></ul>
    </body>
</html>
```

JavaScriptは素人なので、yyyy-mm-ddの形式を作る方法や、同期でのgetJSON処理など、検索で調べました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5f4974d9-e667-6445-af88-2ae9108c21c1.png)

NHKのAPIは一個しかアプリケーションが作れないみたいです。

正月にあった「しぶやさんといっしょ」の再放送を確認したいと思い作ったのですが、もしも0403じゃないと引っかかりません。。。

あ、まったくテレビは見ないのですが、ちゃんと地上波の受信料は払っているので、NHKさんよろしく頼みます。
MacでTerraformの入力補完機能を使用する際の設定

### 前提
bashあるいはzshを使っている場合、入力補完機能なるものが使えるとのこと。

### 自分の環境
* ログインシェルはzsh
* ターミナルはiterm2

### auto-complete機能を有効にする
[公式サイト](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started#enable-tab-completion)を確認し、コマンドを打つ。

```:terminal
$ terraform -install-autocomplete
$ source ~/.zshrc
complete:13: command not found: compdef
```
…あれ???
調べたところ、Zshで補完機能を有効にするには、一手間必要らしい。以下のサイトを参考にさせていただいた。
* Zshの補完について
https://rcmdnk.com/blog/2015/05/15/computer-linux-mac-zsh/
* .zshrcで見かけるautoloadの意味と使い方
https://qiita.com/yuku_t/items/77c23390e52168a2754a

というわけで `.zshrc`を以下のように修正。
```:~/.zshrc
autoload -Uz compinit
compinit
complete -o nospace -C /usr/local/bin/terraform terraform
```


再度`$ source ~/.zshrc`を打ち、補完が働くか確認。

```:terminal
$ terraform v
validate  version
```
成功。

### 余談
Linuxの知識が足りてない。
シェルコマンドとかシェル関数とか、多分基本ですよね。勉強します。
Dart 3点リーダー(ドット３つ)の利用法

配列の結合によく使われている３点リーダーの役割に関しての記述です。ズバリ、配列の中身を展開してくれる演算子となっています。
```dart
var arrayInt = [1, 2, 3];

print(...arrayInt); => // 1 2 3
```

```dart
var arrayString = ['a', 'b', 'c'];

print(...arrayString); => // a b c
```
展開した配列を結合。
```dart
var arrayInt = [1, 2, 3];
var arrayString = ['a', 'b', 'c'];

var addArray = [...arrayInt, ...arrayString];

print(addArray); => // [1, 2, 3, a, b, c]
```
新しい配列を作成して関数で値を操作。
```dart
void main() {
  final list = ['A', 'B', 'C'];
  print(list); // [A, B, C]
  print(add(list, 'D')); // [A, B, C, D]
  print(list); // [A, B, C]
}

add(List list, String v) {  
  final list2 = [...list];
  list2.add(v);
  return list2;  
} 
```
アロー関数で１行で返すと。
```dart
add(List list, String v) => [...list,v];
```
100vhに指定しているのにスクロールが出てしまう原因と改善策

HTML、CSSのコーディングをしていて、htmlタグにheightを100vh指定して、スクロールが出ないようにしたいのに、iPhoneやiPadで確認すると、なぜかスクロールが出てしまう、どころか、なんか数ピクセル上に上がって表示されてしまう現象が開発していて起こりました。

この時の解決法を残します。

# 現象
htmlタグをcssでheightを100vhに指定する。

```style.css
html {
    max-height: 100vh;
}
```

ブラウザのデバッグモードでは、スクロールはでず、きちんと想定内の表示が確認できる。

<strong>iOS端末のsafariやChromeアプリではなぜかスクロールバーが出てしまう！</strong>

# 原因

iOS端末は上部（もしくは下部）のアドレスバー込みが100vhとして計算されてしまっているため。

# 改善策

下記にサンプルコードを示す。
jsを組み合わせることによって実現できる。（なお、jqueryを用いています）

```style.css
html {
    max-height: calc(var(--vh, 1vh) * 100);
}
```

```index.js
$(function () {
    // windowの高さの1/100を取得する
    const vh = $(window).height() * 0.01;
    // cssの--vh要素に画面から取得した1px分を代入する
    document.documentElement.style.setProperty('--vh', `${vh}px`);
});
```

ざっくりコードの解説をします。

jsでwindowの高さを取得し、その1/100をsetPropertyでcssの変数に渡して、cssのcalcを利用して、100倍した高さが、100vhと同等になります。


。。。？？？

jsで1/100倍して、cssに渡して100倍する。。。？

なんかおかしくない...と思うかもしれないが、
これで確かに、100vhが適用されている。


# まとめ
どういうロジックかはわからないが、これでうまくいくことは確認できているので、
とりあえずは、そのままコピペで使用できます。

他に良い方法があれば教えていただきたいです。

この現象で半年悩みましたので、こちらで共有して他の人の役に立てればと思っております。

読んでいただきありがとうございました。
【Rails】現場Rails Bootstrapが機能していない

# はじめに
本記事はプログラミング初心者が、「現場で使える RubyonRails5 速習実践ガイド」(通称)「現場Rails」で学習を進めていくにあたって、つまずいた点、バージョンの違いによるエラーが出た点などを解決した方法を備忘録も兼ねてまとめているものです。
そのため、記事の内容には誤りがある可能性があることをご理解ください。
誤りがあればお手数ですが、ご指摘いただければと思います。よろしくお願いします。

# 環境
Ruby 3.1.2
Rails 7.0.3.1
bootstrap 5

# 起きている問題
現場Rails5で新規登録画面を実装している時に、なんだか登録フォームがしっくりこない。いくらシンプルといえ、cssが機能していない気がするので、問題を見ていく。

![スクリーンショット 2022-08-02 12.31.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737125/43d1fe7b-36d8-10d5-d0ff-52e1d0b52d01.png)

まず、問題のページ。気持ち悪いですよね。
この問題の解決の方法をわかりやすく明記していきます。

まず、フォームのコード↓をチェック。特に問題はなさそう。
```:_form.html.slim
- if task.errors.present?
  ul#error_explanation
    - task.errors.full_messages.each do |message|
      li= message

= form_with model: task, local: true do |f|
  .form-group
    =f.label :name
    =f.text_field :name, class: 'form-cotrol', id: 'task_name'
  .form-group
    =f.label :description
    =f.text_area :description, rows: 5, class: 'form-cotrol', id: 'task_description'
  = f.submit '登録する', class: 'btn btn-primary'
```

検証コードを見てみると、小さくて見にくいかもしれませんが、対応しているクラスは、親要素が、「form-group」で子要素が「form-cotrol」。
![スクリーンショット 2022-08-02 12.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737125/5b7ce270-04c5-e651-a9f9-8e9d762cbc3d.png)


実際にbootstrapでこれらのcssを見ていきましょう。
![スクリーンショット 2022-08-02 12.37.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737125/8aa32430-4ab6-f069-850b-edaafe8707d7.png)

みなさん、お分かりでしょうか。ただのスペルミス...!
てことで、「form-cotrol」を「form-control」に

![スクリーンショット 2022-08-02 12.39.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737125/59b0aa5b-5b45-2edc-3426-8170779bdd52.png)

はい、きれいになりました。

# 終わりに
今回のように、初心者が参考書を進めていく上で、なんか参考書と違うんだよな。でも、コードは一緒だと思うし..と思ってて止まることはよくあると思います。
自分でいうのもなんですが、どこがエラーなのかをしっかり把握して、そこを集中してみていくことで、解決するスピードは格段に上がるんだなと思います。
特に今回は、bootstrapのcssが反映されていなかったということで、検証コードでcssが一応反映されていることを確認し、大元となるbootstrapで確認することでスペルミスが発覚しました。
一番いいのは、スペルミスがないことなのですが、起こってしまうことは仕方ないので、起こった時の対処に慣れていきましょう。
記事を読んでくださりありがとうございました。
Dockerについて

# Dockerとは
> 思うようにならない境遇や不運な境遇のことを言う！
> （島本和彦「逆境ナイン」より）

嘘です。冗談です。（ちなみに上記は「逆境」の定義です）
世の中にはDockerに関するいろんな良質なドキュメントがあるので自分なりの解釈をまとめてみました。

## 一言で言うと
Dockerとは、コンテナ型仮想環境プラットフォームの一種。[^1]

[^1]: https://ja.wikipedia.org/wiki/Docker

## 優しく詳しく言うと
あるOS上でWebサーバーやアプリケーションサーバーなどをまるでOS上に別のコンピューターが動いているかのように独立した環境で動かす仕組みを仮想化と呼んでいる。
仮想化には、仮想のコンピューター（仮想マシン）をOS上にソフトウェア(HyperVisor)で作りその中で別のOSを動かすもの（Xen, Hyper-V, VirtualBoxなど）もあるが、コンテナの場合は、OSの中核を担うプログラム(カーネル)にはコンテナが稼働しているOSのものを利用する。コンテナの場合、独立した環境を作るために割当てされていないコンテナの外のリソースをコンテナの中のプログラムは利用することができないようになっている。

## なぜDockerを使うのか
### 開発に仮想環境を用いる優位性
- 開発者のPC上に環境構築できるので経済的
- 構成管理ファイルを使うことで、どこでも同じ構成の環境が構築できる → gitなどと相性がいい
- コンテナが稼働しているOSからリソースが分離されているので、コンテナの外に悪影響を与えにくい
  - 環境作成・環境の破棄が容易にできる
### コンテナ型仮想環境がHyperVisor型仮想環境より有利な点
- OSとの間にHyperVisorを挟まず、直接OSの基本機能を使うので、オーバーヘッドが少ない → 動作が軽い
### Dockerが有利な点
- コンテナイメージが公開・共有されているので他の人が作ったイメージを再利用して独自のイメージにできる
- アプリケーションベンダーの公式コンテナイメージがあるため、安心して再利用することができる
- 不要なアプリケーションの搭載を抑えたコンテナイメージがあるため、コンテナの省スペース化を図り易い

# まとめ
Dockerとは！？
思うように作ったり壊したりできる自由な環境構築ができる、コンテナ環境型プラットフォームのことを言う！
そしてそれは現代の開発環境構築やCI/CDに有利で不可欠なものだと人は言う！
パソコンとスマホでメール文をコピー・ペーストするには

# 解説
スマホでメール文を入力するのが億劫なときは、パソコンがあれば、パソコンから、メールをまず自分宛に送ります。その場合、Gメールが手軽です。その後、スマホでGメールを開き、メールをコピーします。どのようなケースで利用できるかと言うと、例えば、Lineのトークで比較的長いメッセージを入力する場合です。
ここで、コピー、ペーストを簡単に行う方法を説明します。
そのために、スマホにBluetooth接続のキーボードとマウスを用意します。Bluetooth接続
して、先に、パソコンのGメールで入力した文書をスマホのGメールで開き、キーボードのCtrl+Cで文書をコピーします。
次に、スマホのLineのトークでメッセージを入力するところへカーソルを起き、そこへキーボードのCtrl+Vでペーストします。
少々、手がかかりますが、スマホで長いメッセージを入力するよりも、ストレスが少なくなります。

# あとがき
なれてくると、パソコンでメール文書を書き、スマホのキーボードで、Ctrl+C,Ctrl+Vでコピー、ペーストするとストレスなく、Lineで比較的長いメッセージを送れます。
パソコンで文書作成しているとスマホでは大変面倒でストレスがかかります。
やはり、文書作成はパソコンでおこない、スマホではコピー・ペーストで文書を取り込むのがストレスなくいいようです。
vue-simple-suggestで読み仮名でもサジェストさせる

## 背景・課題
- 漢字でリスト表示していても、ひらがな入力時点でサジェストさせたい
- 漢字に変換するまでサジェストがされないのが不便すぎる

## vue-simple-suggestのサジェストをカスタマイズする
使っていたのは、`vue-simple-suggest`でした。既にスタイルが当たっていたのでどうにかしてこれを使いたかったです。
https://github.com/KazanExpress/vue-simple-suggest

結論としては、`display-attribute`と、`filter`を指定すれば実装できました。
（ドキュメントに書いてあるけど、filterの指定はわからなさすぎてソースコード読みました :tea:  ）
`display-attribute`で、どのkeyの値をサジェストのリストに表示するかを指定できます。
`filter`は入力された値に対してリストの値をどう返すか処理が書けます。

以下は、listDataが`[{ name: "hogehoge", kana: "ほげほげ"}]`みたいな配列になっている前提でのサンプルコードです。(nuxt.js)

```vuejs
<vue-simple-suggest
    :value="value"
    display-attribute="name"
    :list="listData"
    :filter="vueSimpleSuggestfilter"
    :filter-by-query="true"
    :max-suggestions="100"
/>
```

```vuejs
 data () {
    return {
      listData: [{ name: "hogehoge", kana: "ほげほげ"}]
    }
  },
  methods: {
    vueSimpleSuggestfilter (el, value) {
      return el.name.indexOf(value) !== -1 || el.kana.indexOf(value) !== -1 ? el : false
    },
```

`el`に`list`で指定した値が一つずつ入ってきて、`value`に入力値が入ってきます。
returnした値がサジェストのリストとして表示されます。
拡張したら、カタカナとかアルファベットも追加できますね :ok_hand:
pythonハマり仕様

# 1
Pythonで、実行対象ファイルAにおいてモジュールBをインポートし、そのモジュールBでモジュールCをインポートしているとき、モジュールCのインポートpathはAからのパスである必要がある。モジュールBがAと同階層にないときは気をつける必要がある。
### 引用
https://qiita.com/papi_tokei/items/bc34d798dc7a6d49df30

# 2
pandasにおいて、locはスライスの最後を含むがilocは含まない。
### 引用
https://deepage.net/features/pandas-location.html
画面全体で共通したCSSを適用させる方法

## 目次

1.はじめに
2.対処方法
3.まとめ
4.参考

## 1.はじめに

Responsive WebをSafariで開いた際に、
Widgetをクリック・タップすると下記のように枠が表示されてしまうことがあります。

![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/7a8e9c20-ce28-c05d-a3ff-cfdb7cdd6e31.gif)

このように自分で設定していないにも関わらず枠が表示されたりしてしまうのは、
`user agent stylesheet`というブラウザごとに定義されているデフォルトのCSS設定が関係している可能性があります。

下記画像のようにブラウザの要素を見てみると、
「ユーザエージェント・スタイルシート」というCSSがありますが、
これが表示されている場合はデフォルトでこのCSSが適用されているということです。

![User agent stylesheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/cd612006-107f-f4f5-70c9-ddb1db945d22.png)

このuser agent stylesheetを打ち消し、
Widgetをクリック・タップした際に、
枠がでないようにする対処方法について紹介します。 

## 2.対処方法

### 1.HTML Headで、全体に適用させるCSSを埋め込む
クリック・タップをした際に枠がでないようにするために**outline:none**を設定していきます。
この設定を画面全体に適用させる方法を紹介します。
`1.Project Settingsを開く`
![ProjectSetting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/78c72a08-3fe1-9714-35a8-3270fb8977c2.png)
`2.　Responsive　Webを開き、HTML Headに下記コードを記入する。`
`3.Doneをクリック`
![Responsive Web.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/ce2c4efd-7df9-4c3d-216d-e34042bfa906.png)

```php:HTML Head
<style type="text/css">

*:focus{
 outline:none;
}

</style>
```
このようにコードを記入したことで、
下記のように画面全体でWidgetをクリック・タップしても枠が表示されないようになりました。
![ezgif.com-gif-maker (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/f7b243a7-f25e-210b-a97f-9bc42b80edc8.gif)

### 2.HTML Headで、特定のWidgetに適応させるCSSを埋め込む
先程の方法では画面全体に
クリック・タップ時に枠がでないように設定していましたが、
今度はこの設定を特定のWidgetに適応させる方法を紹介します。

例として、今回はListBox WidgetのみにCSSを適用させます。

先程同様HTML Headにコードを記入していくのですが、
今回は下記コードを記入します。

```php:HTML Head
<style type="text/css">

select[kw="ListBox"]:focus{
    outline:none
}

</style>
```
コードを記入したことで、
下記のようにListBox Widgetをクリック・タップしても枠が表示されないようになりました。
![ezgif.com-gif-maker (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/07ac84c5-2f56-c9c1-d13c-90ced2b61161.gif)

特定のWidgetをコード記入時に宣言するためには、
HTMLタグとWidget名を記入する必要があります。
今回の画面を作成する際に使用したWidgetのHTMLタグとWidget名は以下になります。
|Widget|HTMLタグ|Widget名|
|:---:|:---:|:---:|
|FlexContainer|dev|FlexContainer|
|Button|button|Button|
|ListBox|select|ListBox|
|TextArea|textarea|TextArea2|
|TextBox|input|TextBox2|

この他にも様々なWidgetがありますので、HTMLタグやWidget名を調べる際には、
ブラウザでコンソールを開いて確認してみましょう。
![wight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/3b722cbf-fc6b-16b9-2814-400ffb3d9f38.png)

## 3.まとめ
Responsive WebをSafariで開いた際に、
Widgetをクリック・タップすると枠が表示されてしまう場合の対処法を紹介しました。
Safariで枠が表示されてしまったという場合はこちらを参考に対応してみてください！

## 4.参考

[CSSのuser agent stylesheetとは](https://snownotes.org/understanding-about-user-against-stylesheet-and-reset-css/)
実記憶管理

# 実記憶管理の役割とは？
マルチプログラミング環境だと同時にプログラムが複数実行される。
限られた主記憶装置の空間に複数はプログラムをロードしているわけだから
p２４１の図のように空間には限りがある。
うまくプログラムを割り当てることができなかったらその容量を使い切れず無駄になってしまう。
## 気づき
主記憶装置の無駄をなくすのが実記憶管理の役割なのか。

次はプログラムの割り当て方法について紹介するのか。

# 固定区画方式
主記憶装置に固定長の区画(パーティション)を設ける。
それによってプログラムを読み込む管理方式。

全体を単一に区画する```単一区画方式```と複数の区画に分ける```多重区画方式```がある。
## 単一区画方式
* 一つのプログラムしかロードできない。
* 一つ入ると余りの容量に他のプログラムを読み込めない。
* マルチプログラミングができない。

## 多重区画方式
* 区画ごとにプログラムをロードすることができる。
* 区画は均等である必要は無く、サイズの変更ができる。
* 区画の容量を超えるプログラムをロードすることはできない。

この２つの方式は無駄があるからあまり良くない。

# 可変区画方式
* プログラムをロードするタイミングで必要なサイズに区切る管理方式
* 余剰スペースは生じない。
* 主記憶の利用効率は良くなる。

## 気づき
可変区画方式は圧倒的にすごい。
しかし新たな問題が出てきてしまうらしい。

# フラグメンテーションとメモリコンパクション
可変区画方式だと、主記憶上にプログラムを隙間なく読み込むことができる。
しかし
必ずしも読み込み順にプログラムが終了するとは限りない。
p２４４の図のように```シマシマみたいに空きとプログラムが交互になっていることもある```。
こうなると足りるサイズがあったとしても```区画が小さくて読み込めない```状態になる。
```フラグメンテーション(断片化)```が発生している。

この状態をなくすために細切れになった```空きの容量を一つの領域```にしなくてはならない。
この操作を```メモリコンパクション```または```ガーベジコレクション```と呼ぶ。

# オーバーレイ方式
そもそも元の主記憶装置の全体の容量がロードしたいプログラムの方が大きい場合は読み込むことができない。
その時プログラムを```セグメント```という単位で分割する。
その必要なセグメントだけを読み込んでプログラムを実行する。

p２４５の図のようにABCDとセグメントで分れている。
全体のプログラムの１の機能を使いたい時はABCのセグメントを使う。
2の機能を使うときはADのセグメントを使う。

このように分割することで```読み込む容量を小さくする```工夫がある。
これを```オーバーレイ方式```という。

## 気づき
主記憶の空き容量を一つにしたり、読み込むプログラムを分割したりと工夫がいっぱいだ。
すごいな。

# スワッピング方式
優先度の高いプログラムによる割り込みを行いたい。
しかし主記憶装置に容量がない場合は
優先度の低いプログラムを補助記憶装置に移動させて空いた容量で読み込む方法がある。
```主記憶から補助記憶```に移動させることを```スワップアウト```という。
これで優先度の高いプログラムを読み込むことができる。

また移動させられたプログラムが再びCPU使用権を与えられる場合は
退避させられた内容を補助記憶装置から主記憶へロードし直して、```中断箇所から処理```する。```補助記憶から主記憶```に移動することを```スワップイン```という。

主記憶から補助記憶、補助記憶から主記憶の移動の処理を```スワッピング```という。
こうすると低速な補助記憶にアクセスするために```処理速度は極端に低下```する。

## 気づき
スワッピングはすごいけどそれなりの代償があるのか。
それだけ処理速度の差があるのか。
キャッシュメモリを使えば少しは緩やかになるのかな？
rails 他人のユーザー情報、投稿情報を変更できないようにする。

初投稿です
railsで 他人のユーザー情報、投稿情報を変更できないようにする方法を記述していこうと思います
今回は、投稿情報のケースを紹介します(投稿に関するモデルはBookとし、Userモデルと関連づけているものとします。)
まず、以下のように記述します。
（こちらの記事は以下の記事を参照させていただいて作っております）
https://qiita.com/nao0725/items/47606b8975603a12fd5e


```books_controller.rb
①before_action :correct_user, only: [:edit, :update]
def edit
:
end

def update
:
end

private

def correct_user
②@book=Book.find(params[:id])
③redirect_to(books_path) unless @book.user_id ==current_user

```
①before_actionは各アクションが実行される前に呼びます。
    詳細ページなどはどのユーザーからでも閲覧できるようにしたいので、今回はonlyを使って
    before_actionの対象をedit,update飲みにしています。

②@book=Book.find(params[:id])で編集しようとしていた投稿のIDを取得します

③redirect_to(books_path) unlessを使い@book.user_id==current_userが正しくなければ一覧ページに戻されます。

これで機能が完成しました。
for、forEach、mapの使い方

### 動作環境
Node.js v16.14
Ubuntu20.4 （Vagrant + Windows10）


### はじめに
JavaScriptで配列を処理する方法はいくつかあります。色々なパターンを試してみました。テストで利用する配列がこちらです。
```node.js
var ary = ["aa","bb","cc","dd"];
```

### 内容
一番原始的なやり方がことらです。初学者であれば、まずは、このやり方が思いつくかと思います。この書き方でも、全然問題はありません。ただし、エレガントさに欠けるという言い方はできるかと思います。
```node.js
for (let i = 0; i < ary.length; i++) {
    console.log("val=" + ary[i] + " idx=" + i );
}
```

動作結果です。
```node.js
val=aa idx=0
val=bb idx=1
val=cc idx=2
val=dd idx=3
```

上記のfor文をエレガントに書くと、次のようになります。何がエレガントなのかと言えば、ループする条件を記述する必要がありません。これだけで、配列の全ての要素を取得してくれます。この書き方は、ECMAScript 2015以降で追加になった仕様です。随分と以前の話であるため、今となっては、特段、モダンな書き方というわけでもないでしょう。ただし、この書き方では、インディックスを取得することはできません。インディックスを取得したい場合は、i++でループした数をカウントして取得することになります。そんなことをする位なら、上記の書き方の方が逆にシンプルな書き方と言えるかと思います。
```node.js
for (let val of ary) {
    console.log(val);
}
```

動作結果です。
```node.js
aa
bb
cc
dd
```

配列の要素を全て取得する場合、**forEach**文を使うこともできます。forEach文では、自分でループした数をカウントすることなく、インデックスを取得することができます。ただし、forEach文のブロック内では、breakや、continueが使えないため、正直いってあまり使えないといった印象です。
```node.js
ary.forEach(function (val, idx) {
    console.log("val=" + val + " idx=" + idx);
})
```

動作結果です。
```node.js
val=aa idx=0
val=bb idx=1
val=cc idx=2
val=dd idx=3
```

**map**を使って、forEachと同じように、配列の値とインディックスを取得することができます。mapもforEachと同じように、ブロック内で、breakや、continueを使うことができません。下記のmapを使た記述は、上記のforEachを使った記述と同じ結果になります。この結果だけ見れば、mapとforEachはどっちを使っても同じです。
```node.js
ary.map(function (val, idx) {
    console.log("val=" + val + " idx=" + idx);
})
```

動作結果です。
```node.js
val=aa idx=0
val=bb idx=1
val=cc idx=2
val=dd idx=3
```

mapとforEachの違いは、mapには戻り値をセットできるところにあります。つまり、元の配列をループして、加工した結果を、別の新しい配列にセットすることができます。forEachにはこのようなことはできません。この点がforEachとmapの違いです。
```node.js
let ret = ary.map(function (val, idx) {
    return val + " : " + idx;
})
console.log(ret);
```

動作結果です。
```node.js
[ 'aa : 0', 'bb : 1', 'cc : 2', 'dd : 3' ]
```
UnityでAndroidbuildで「Gradle build failed. See the Console for details」エラーが出た時の解決法(複数ある物の1つ)

# 今回起きていたAndroidbuildエラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/cf897a8b-b21c-9978-3a95-d04d912d4f62.png)
今回起きていたエラーは「Bulid failure」このエラーの文を翻訳すると「gradle ビルドに失敗しました。」

## 今回のエラーの解決方法
今回のエラーについていろいろ調べていたらAndroid SDKとかいろいろな原因が出てきたのですが全部試したも解決しませんでした
翌日buildsettingsを見ていると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/22861198-b3a6-5ad3-61b7-b8eee775bd01.png)
Bundle Version Codeが0になっていてこれを1に変更してbuildしてみると無事buildできました
難しく考えないでよく見てみると解決できました
Linux BIOSと仮想化について（自分用メモ


●BIOS
BIOS（Basic I/O System）は最もハードウェアに近い部分を司るシステムで、物理的なハードウェア（マザーボード）上に書き込まれています。コンピュータの電源を入れると、まずBIOSが起動し、周辺機器の制御を行います。
最近のシステムでは、BIOSよりも高機能なUEFI（Unified Extensible Firmware Interface）への移行が進んでいます

コンピュータの起動時に特定のキー（DEL、F2など）を押すことで呼び出せるBIOS/UEFIセットアップ画面では、主に以下の設定ができます。
・日付と時刻
・電源管理
・起動デバイスの優先順位
・組み込みデバイスの有効/無効化


仮想化（Virtualization）とは、コンピュータリソースを実際の物理的な構成にとらわれず、論理的に分割・統合して提供する技術です。
仮想化の実現方法の1つである仮想マシン（VM：Virtual Machine）は、仮想化のための専用のソフトウェア上で仮想的なハードウェア（仮想マシン）を起動し、ゲストOS（仮想マシンにインストールしたOS）を動作させる方式です。

【libvirt】
libvirtはオープンソースの仮想化管理用のライブラリです。libvirtを利用するプログラムとしては、GUIの仮想マシン管理ソリューションであるvirt-managerや、CLIのvirshコマンドなどがあります。
また、libvirtは以下のような数多くの仮想化ソフトウェアに対応しています。

Xen、KVM、OpenVZ、LXC、Oracle VM VirtualBox、VMware など

仮想化の種類
仮想化を実現する方法には、大きく分けて仮想マシンとコンテナがあります。

・仮想マシン（VM：Virtual Machine）
ハイパーバイザーという仮想化ソフトウェア上で仮想的なハードウェア（仮想マシン）を起動し、ゲストOS（仮想マシンにインストールしたOS）を動作させる方式。ゲストOSからは通常の物理マシン上で動作しているように見えるため、これまでのサーバにOSをインストールしているのと同様に環境を構築したり、運用できます。ハイパーバイザーがサポートしているOSであれば、ホストOSと異なる種類のゲストOSを使用できます。

ハイパーバイザーの種類には、ネイティブ型（またはベアメタル型）とホスト型があります。

[ネイティブ型（Type1）]
ハードウェア上でハイパーバイザーを直接起動し、その上で仮想マシンとゲストOSを動作させます。
ホストOS（物理マシンにインストールした通常のOS）を介さないため、ホスト型に比べてパフォーマンスが良く、近年の企業における仮想化の主流。
ネイティブ型の仮想化ソフトウェアには、Xen、MicrosoftのHyper-V、VMwareのvSphere Hypervisorなどがあります。

[ホスト型（Type2）]
ホストOS上にアプリケーションの一つとして仮想化ソフトウェアをインストールし、その上で仮想マシンとゲストOSを動作させます。
既に利用しているコンピュータ上に手軽に仮想環境を構築できますが、ホストOSを介してハードウェアにアクセスするため、ネイティブ型に比べて仮想化のオーバーヘッド（余分な処理の量）が大きくなります。
ホスト型の仮想化ソフトウェアには、Oracle VM VirtualBox、VMware Workstation、Parallels Desktopなどがあります。

・コンテナ
ホストOSのリソースを隔離して「コンテナ」という仮想環境を作成する方式です。
ホストOSのカーネルを共有することで、仮想マシンやゲストOSを起動せずにアプリケーションの実行環境を構築できます。ただし、ホストOSと異なるOSをコンテナで使用することはできません。
コンテナはホストOSのプロセスとして動作するので、仮想マシンに比べてリソース消費が少なく、軽量で起動が速いのが特徴です。作成したコンテナはDockerイメージのように、別の環境に配布して実行することも可能です。

コンテナ型仮想化では、Linuxカーネルの機能によってコンテナごとのユーザ管理やリソース制御を行います。例えば、cgroups（Control Groups）はグループごとにCPUやメモリなどのリソースを割り当て・制限し、コンテナのリソースを管理します。
また、コンテナ内のrootユーザはホスト上でもroot権限を持つことになりセキュリティ上望ましくありません。Linuxのユーザ名前空間（User Namespace）の機能を使うことで、コンテナ内のrootユーザをホスト上の一般ユーザとして扱うことができ、コンテナとホスト間でユーザ権限の分離ができるようになります。

コンテナ型ソフトウェアには、LXC、Dockerなどがあります。


【Linuxでの仮想化】
KVM（Kernel-based Virtual Machine）は、Linuxに標準搭載されている仮想化ソリューションです。仮想化の種類としては通常Type1に分類されます。
KVMを使用するためには仮想化支援機能を搭載したCPUが必要です。仮想化支援機能とは仮想化ソフトウェアが行う処理の一部をCPUが分担することで処理を高速化する機能で、Intel VT（Intel Virtualization Technology）やAMD-V（AMD Virtualization）という名称で実装されています。
CPUが仮想化支援機能をサポートしているかどうかを調べるには、「/proc/cpuinfo」のflagsにおいて"vmx"(Intel VT)または"svm"(AMD-V)という値があるかどうかを確認します。
ウェブサイトが危険なサイトと誤検知されてしまったら

この記事では、[YoURL.jp](https://yourl.jp/) という URL 短縮サービスのウェブサイトが「危険なサイト」と判定されて、アクセスしようとすると画面が真っ赤になってしまったので、そのときのことを書いています。あなたのサイトが誤検知されてしまった際の参考になれば幸いです。
# なぜ判定されるのか
※ 基本的なことなので、お分かりの方は次のセクションに進んでください。
　この世の中には、他人のメールアドレスやパスワードを盗んで勝手にログインしようとする人や個人情報を抜き取ったりファイルを暗号化したりする機能を仕込んだアプリケーション（マルウェア）をインストールさせる人がいます。この様な人たちに対抗しようと、世界中の研究者やセキュリティソフト開発者が考えたのが、個人情報を盗んだりマルウェアをばら撒くサイトの URL をデータベースに登録して被害を食い止めよう、というものです。この仕組みを URL レピュテーション（評価）やフィルタリングといい、Google やトレンドマイクロ、ノートンなどが運用しています。
　しかし、この仕組みも万能ではないため、「URL 短縮サービス」のようなサイトも間違えて検知してしまうことがあります。もしかすると、サービスが不正に使われたのを検知して、サイト全体が危険だと判断してしまったのかもしれません。（たぶんそう）
# 判定を直してもらう
フィルタリングやマルウェアを仕込んでいないサイトなのに「危険」だと判定されてしまったら、、ちゃんとそんなこともあろうかと各社考えてくれています。ここでは主要なレピュテーションサービスを紹介します。
## Google Safe Browsing
Google がやってるレピュテーションサービスです。Chrome や Android を使っていると、これが守ってくれます。

:::note info
公式ドキュメント：https://web.dev/request-a-review/#3.-request-a-review
:::
### ① まずは、判定を確認
https://transparencyreport.google.com/safe-browsing/search で確認しましょう。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323431363631382f31353037383334332d326135382d383631612d616134352d6334326635656631623537322e706e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416618/5766dcfa-38db-1641-8723-cef8d5f56143.png)
### ② [Google Search Console](https://www.google.com/webmasters/tools/security-issues) に登録する（していない場合）
:::note warn
「フィッシングまたはソーシャルエンジニアリング」と判定された場合は、登録していなくても構いません。③ に進んでください。
:::
[Google Search Console](https://www.google.com/webmasters/tools/security-issues) は、Google がドメインの所有者向けに提供するサービスで、検査結果への表示をリクエストしたり検索結果内でのクリック数を教えてくれたりするものです。「セキュリティの問題」が発生したときにも教えてくれますので、登録しましょう。「望ましくないソフトウェア」などに分類された場合は、ここからリクエストするしかありません。
### ③-1. フィッシングまたはソーシャルエンジニアリングの場合
[Google Search Console > セキュリティの問題レポート](https://www.google.com/webmasters/tools/security-issues) か、[｢フィッシング警告の誤りを訂正｣ページ](https://safebrowsing.google.com/safebrowsing/report_error/?hl=ja) から、誤検知である旨を報告してください。
### ③-2. それ以外
サイト内にマルウェアがないかどうかを確認して（自分のサイトが攻撃を受けて改ざんされていることがあります）、[Google Search Console > セキュリティの問題レポート](https://www.google.com/webmasters/tools/security-issues) の通知から「審査をリクエスト」を押します。
### ④ 待つ。

## Norton Safe Search
ノートンライフロック社が提供するアンチウィルスソフトの、ウェブレピュテーションサービスです。
### ① まずは、判定を確認
https://safeweb.norton.com/ から判定状況を確認できます。
![Image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416618/66482943-e65c-f4c6-393d-6115fb1e7049.png)
### ② 異議を送信
判定画面の「ここをクリックして異議を送信」を選択します。
![Image-2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416618/e132348b-9242-7586-c8bb-7a624986d26f.png)
電子メールアドレス、本来のカテゴリ、コメントを入力して送信します。メールアドレスは念の為公開されても問題ないものを使うことをお勧めします。
![Image-3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416618/090fb938-ae95-6de7-2ccc-7afee57f96fd.png)

## Trend Micro
トレンドマイクロ社が運用するウェブレピュテーションサービスです。
ここは、公式が詳しいヘルプ（日本語）を出しているので、それを見るのが一番です。
[トレンドマイクロ ヘルプセンター「危険ではないはずのソフトウェア/アプリケーションやWebサイトが『危険』と判定される」](https://helpcenter.trendmicro.com/ja-jp/article/tmka-16601)

## 他にもあるかも
ほんの一部かもしれません。。出来ればコメントでお知らせください。

# 最後までお読みいただきありがとうございました
最後に少しだけ宣伝させてください、、無料で高機能な短縮 URL を是非ご利用ください！

https://yourl.jp/
【Docker】 Restarting xxxx が繰り返してコンテナが立ち上がらない場合

# 概要

`docker compose up -d`で起動したコンテナが`Restarting`から抜け出せなくなったので対策をまとめる

```bash
docker  ps          
CONTAINER ID   IMAGE                          COMMAND                  CREATED              STATUS                                  PORTS     NAMES
bb79284b1635   hasura/graphql-engine:v2.9.0   "graphql-engine serve"   About a minute ago   Restarting (1) Less than a second ago             hasura-postgress-graphql-engine-1
17e57dc1b6c4   postgres:12                    "docker-entrypoint.s…"   About a minute ago   Restarting (1) 2 seconds ago                      hasura-postgress-postgres-1

```

# 対策

```bash
# Volumeごと消し去る
docker compose down -v

# 再度起動する
docker compose up -d  

# 正常に起動できる
docker  ps            
CONTAINER ID   IMAGE                          COMMAND                  CREATED         STATUS         PORTS                    NAMES
8255c7a4297f   hasura/graphql-engine:v2.9.0   "graphql-engine serve"   4 seconds ago   Up 2 seconds   0.0.0.0:8080->8080/tcp   hasura-postgress-graphql-engine-1
1578783e7786   postgres:12                    "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   5432/tcp                 hasura-postgress-postgres-1
```
vCenter 6.7.0でRemote Consoleが強制起動される状態を解消

vCenter 6.7.0でweb consoleを選んでもRemote consoleが
強制起動されてしてしまう状態を解消
sonving a problem : remote console opens even you chose web console


1.ユーザー名の右にある矢印を押下
choose down arrow next to username

2.My preferencesを選択
choose My preference

3.開いたポップアップから Default Console を選択
choose Default Console tab

4.Web Consoleを選択
choose Web Console

5.SAVEを押下し閉じる
press SAVE

![vCenter65.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628705/81009205-cba8-9c3c-b734-b49f3bc2b0fb.png)
CaseMilestone オブジェクト

元の質問 : [How can we write the test class for a class where CaseMilestone is queried.](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HEX0v)

さて、実際にコードを検証しようとすると何故かCaseMilestone オブジェクトが存在しない？　何で？

Setup --> Entitlement Settings で有効化する必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/10bce79b-20e2-0bc3-8b3f-250116aa7a82.png)

```
public class MilestoneUtils {
    public static void completeMilestone(List<Id> caseIds, 
            Set<String> milestoneName, DateTime complDate) { 
            System.debug('cm==>'+[select Id,MilestoneType.Name, completionDate from CaseMilestone]);
    List<CaseMilestone> cmsToUpdate = [select Id, completionDate
            from CaseMilestone cm
            where caseId in :caseIds and cm.MilestoneType.Name in: milestoneName 
            and completionDate = null limit 1];
    if (cmsToUpdate.isEmpty() == false){
        for (CaseMilestone cm : cmsToUpdate){
            cm.completionDate = complDate;
            }
        update cmsToUpdate;
        }
    }
}
```
RM mini3用にリモコン信号を変換

これでリモコンを無くした機器があっても、[リモコン・データベース](http://www.256byte.com/remocon/iremo_db.php)で機器のコードがあればRM mini3経由で操作することが可能になる。

下記のWebサイトにて、テレビやエアコンのリモコンデータが公開されているのでこのデータを元に、RM mini3用の信号データに変換を行う。
http://www.256byte.com/remocon/iremo_db.php

# ■MSB firstをLSB firstに変換
公開されているデータはMSB firstなので、LSB firstにスクリプトで変換する。
```convLM.py
#!/usr/bin/env python3

import sys
import re

hex_s = sys.argv[1]
bin_n = bin(int(hex_s,16))

bin_l = len(bin_n[2:])
stn_l = 7 - ((bin_l-1) % 8) + bin_l

bin_zf_n = bin_n[2:].zfill(stn_l)
bin_r = re.split('(........)', bin_zf_n)[1::2]

l = list()
for b in bin_r:
    rev_bin_n = ''.join(list(reversed(b)))
    l.append(format(int(rev_bin_n,2),'02x'))

print(*l)
```
例：[NEC照明の信号](http://www.256byte.com/remocon/iremo_db.php?mode=view&id=284)(0x41B618E7)を変換
```bash
./convLM.py 0x41B618E7
82 6d 18 e7
```

# ■NEC フォーマットの汎用信号定義データにエンコード
変換したデータを、スクリプトで汎用信号定義データにエンコードする。

NEC製向けのスクリプトは下記サイトの**irnec**を参照
http://shrkn65.nobody.jp/remocon/nec.html
```
#! /usr/bin/perl
#
#  Usage: irnec hex hex hex ...
～
```

例：NEC照明の信号を変換
```bash
./irnec 82 6d 18 e7
38 1 9000 4500 562.5 562.5 562.5 1687.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 1687.5 562.5 562.5 562.5 562.5 562.5 1687.5 562.5 1687.5 562.5 1687.5 562.5 41062.5
```

**※Panasonic製などはこちらのスクリプトを参照**
http://shrkn65.nobody.jp/remocon/aeha.html
```
#! /usr/bin/perl
#
#  Usage: iraeha hex hex hex ...
～
```

# ■汎用信号定義データをRM mini3用定義へ変換
変換したデータを、スクリプトでRM mini3用定義へ変換する。

スクリプトは下記サイトの**irconvert**を参照
http://shrkn65.nobody.jp/remocon/convert.html
```
#! /usr/bin/perl
#
#  Usage: irconvert [options ...] [input_file ...]
～
```

例：NEC照明の信号を変換
```bash
./irnec 82 6D 18 E7 | ./irconvert --in generic --out mame
26004800000127931312133712131213121312121312133712381213123713371213123812371312131213121213123812371312131212131238123713371213121312381237133712000d05
```

# ■BlackBeanControlに登録してテスト
BlackBeanControl.iniのCommandsに追記
```
$ cat BlackBeanControl.ini
[General]
～略～

[Commands]
aircon = 26004800000127931312133712131213121312121312133712381213123713371213123812371312131213121213123812371312131212131238123713371213121312381237133712000d05
```
リモコン信号送信
```
python3 BlackBeanControl.py -c aircon
```
無事家電が反応すればOK

# ■RM mini3、Google Homeとの連携
下記のサイト等で紹介されている、「リモコンを学習」させるところでリモコン信号送信コマンドを流せば、自分自身で信号の取り込みができる。
https://garapappa.hatenablog.com/entry/20210201/1612148727

これで日常的にGoogle Home→RM mini3と声だけでリモコン操作が可能になる。
ちなみに私はこの方法で複数の照明を操作しており、部屋が暗いときなど動き回らなくても電気がつけられるので重宝している。


## 参考サイト
http://www.256byte.com/remocon/iremo_db.php
http://shrkn65.nobody.jp/remocon/
DNSレコードを登録するときはドメイン名の最後に.を付ける

# QiitaのDNSレコードを確認してみる
```bash
> dig qiita.com                                                                                      (⎈ jpc1-caas1-prod1|tam-prod-cmntool)

; <<>> DiG 9.10.6 <<>> qiita.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54797
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;qiita.com.			IN	A

;; ANSWER SECTION:
qiita.com.		58	IN	A	54.95.57.105
qiita.com.		58	IN	A	52.197.186.23
qiita.com.		58	IN	A	3.115.129.60

;; AUTHORITY SECTION:
qiita.com.		298	IN	NS	ns-171.awsdns-21.com.
qiita.com.		298	IN	NS	ns-1956.awsdns-52.co.uk.
qiita.com.		298	IN	NS	ns-772.awsdns-32.net.
qiita.com.		298	IN	NS	ns-1049.awsdns-03.org.

;; Query time: 45 msec
;; SERVER: 192.168.113.201#53(192.168.113.201)
;; WHEN: Tue Aug 02 10:48:12 JST 2022
;; MSG SIZE  rcvd: 223
```
`qiita.com.`というようにドメイン名の末尾に.が付いているのがわかる。

# .がないとどうなるのか
末尾にORIGINが補完される。
https://straypenguin.winfield-net.com/bind9.html#rr_std
例えば`qiita.com -> qiita.com.qiita.com.`のような感じ。
ORIGINを省略した場合は、named.confで指定したゾーン名が暗黙に使われる。
https://straypenguin.winfield-net.com/bind9.html#rr_misc
asdf でPythonの最新安定版をインストールする

以前はPythonインタープリタのインストールは pyenv が定番でしたが、今後は他ツールも統一管理できる asdf の方が良さそう。

asdf のインストール

```shell
brew install asdf
asdf plugin-add python
```

全バージョンがインストールできますが、最新の安定版をインストールするには以下のように grep で抽出する。

```shell
n=python
for v in 3.7 3.8 3.9 3.10; do asdf install $n $(asdf list all $n | grep ^$v | tail -1); done
```
Railsコールバック、ActiveRecord::Enum

### コールバックによる制御
**コールバックとは**
特定の処理に引っ掛けて別の処理を呼ぶことをコールバックと言います

メリット
* 前処理、後処理などを宣言的に書くことができる
* 必ず保存後に行いたい処理がある時に、実行の漏れを防ぐことができる

**コールバックの基本的な使い方**
(例)
本の名前を保存する前に、名前に"Dog"が含まれていた場合
"Dog Cute"と文字列を置き換える

~~~md:
class Book < ApplicationRecord
  略
  before_validation do
    self.name = self.name.gsub(/Dog) do |matched|
        "Dog Cute #{matched}"
    end
  end

  # メソッドを使って書くこともできます
  before_validation :add_Cute_to_dog(独自メソッド)

  def add_Cute_to_dog
    self.name = self.name.gsub(/Dog/) do |matched|
        "Dog Cute #{matched}"
    end
  end
            
end
~~~

上記の記述のgsubメソッドとは何？
##### gsubメソッド
gsubメソッドはマッチしたすべての部分を特定の文字列に置換します。
パターンには文字列や正規表現が使えます。

~~~md: 実行結果
irb(main):001:0> Book.create(
irb(main):002:1* name: "My Dog",
irb(main):003:1* publsiher: Publisher.find(1),
irb(main):004:1* price: 1000,
irb(main):005:1* )

[["name", "My Dog Cute Dog"], 
 ["price", 1000],
 ["created_at", "2022-07-28 10:00:58.584937"],
 ["updated_at", "2022-07-28 10:00:58.584937"], 
 ["publisher_id", 1]
]
~~~

### ActiveRecord:Enum

**ActiveRecordにenum型とは**
モデルの数値のカラムに対してプログラム上で扱えるように名前を定義してくれるもの

例
本に販売の状況に関する状況を追加する場合
販売の状況はテーブルに定義する際に数ないバリエーションのため、文字列として保存するのが効率的になります
このような数値を扱うコードをプログラムで扱う場合
下記のようになります。
```
RESERVATION = 0 予約受付
NOW_ONSALE = 1　発売中
END_SALE = 発売終了
```

このような時に役に立つのがenum型になります
Bookモデルに販売状況のカラムを追加し、値を管理する方法としてenum型を定義します
```
rails g migration AddStatusToBooks sales_status:integer
rails db:migrate
```

次に、enumクラスメソッドにカラム名と対応する値を定義する。
定義する値はハッシュ形式で名称と値の組み合わせで定義。
または、名称を文字列かシンボルの配列とすることができる。

~~~md:app/models/book.rb
class Book < ApplicationRecord

  enum sales_status: {
    reservation: 0, # 予約受付中
    now_on_sale: 1, # 発売中
    end_of_sales: 2, # 発売終了
  }
~~~

上記のようにし、データを保存してみると
```
irb(main):013:0> Book.create(
irb(main):014:1* name: "samplebook",
irb(main):015:1* publisher: Publisher.find(1),
irb(main):016:1* sales_status: 1,
irb(main):017:1* price: 1000,
irb(main):018:1* )
<Book id: 3, name: "samplebook", 
published_on: nil, 
price: 1000, 
created_at: "2022-07-30 09:37:44.399443000 +0000", 
updated_at: "2022-07-30 09:37:44.399443000 +0000", 
publisher_id: 1, 
sales_status: "now_on_sale"
```
先ほどのカラムの出力結果を見てみると、
保存の際に数値で行なったが定義した文字列で戻ってきている

このようにenum型を利用すると、コード上で分かりやすいシンボルなどで指定しつつ、
DB上の定義に合わせて保存することが可能となります。


### Enumで定義された状態を見たい場合
ステータスごとに述語メソッドで状態を確認する子おtができる
```
irb(main):013:0> book.now_on_sale?
=> true
irb(main):015:0> book.end_of_sales?
=> false
```

DBに保存されている実際の値を確認したい場合
**カラム名_before_type_cast**メソッドで確認することができます。
```
irb(main):016:0> book.sales_status_before_type_cast
=> 1
```

また、enumの定義を確認したい場合、
カラム名の複数形メソッドをクラスメソッドとして呼び出します
```
irb(main):019:0> Book.sales_statuses
=> {"reservation"=>0, "now_on_sale"=>1, "end_of_sales"=>2}
```