OmniAICreator/Qiita-1.07M huggingface dataset:
フォルダ量産


	public static void main(String[] args) {


	    try{
	    	for(int i=1;i<=作りたいフォルダ数;i++) {
	    		Path p = Paths.get("パス"+String.valueOf(i));
	    		 Files.createDirectory(p);
	    	}

	    }catch(IOException e){
	      System.out.println(e);
	    }

	}
ABC248での学び

# ABC248で得た学び
今日はA,Bだけ解けて、Cは考えたけど難しそうすぎて飛ばしました。
その後のD問題を後から友達と答え合わせする中で得られた学びを記します。

* 1. ソート済み配列に対するBisectを使ったインデックス取得
D問題では、ソート済みの配列からある数L,Rについて、"L＜X＜R"を満たすような要素の数を取得する必要がありました。
僕は初め数列内のすべての要素に対してL<X<Rを比較して、それを満たしている要素の数をカウントしていたのですが、それではTLEとなりました。
これにたいして必要だったのが、配列の要素の中の、Lが入る位置、Rが入る位置を取得するという処理です。配列はソート済みなので、Lが入る位置からRが入る位置までの間の要素数が、最終的に求めたい"L＜X＜R"を満たすような要素の数となります。
Pythonではbisectというライブラリを使うことでソートされた配列の中に新しい要素を入れる際の位置を簡単にかつ高速に取得できるため、思いつきさえすれば実装も可能だったと思います。

* 2 辞書型の要素があるかないかの判定
辞書型の要素に対して、「あるキーKに対応する値が存在すればAという処理を、なければBという処理を行う」という場合があり、自分は今までTry-exceptを使った処理を実施していました。しかし、これは実際に競技プログラミングでは非常に重い処理らしいです。
このような処理を行いたい時に有効なのが、dict.get("key")という関数。これは、対応する値があればそれを返し、なければNoneを返すものらしいです。そのため、この関数の返り値に応じて条件分岐をすることで、キーが存在するかしないかの処理を分けることができます。
新入生、新人、一緒にJavaScriptしようぜ。第一日


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2014 年にアメリカで始まった完全無料のプログラミング学習サイトの「freeCodeCamp」<br><br>最近日本語訳されたみたいだね！！翻訳してくれた皆さんありがとう😭<br><br>思い切り勉強楽しむね！❤️<a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/freeCodeCamp?src=hash&amp;ref_src=twsrc%5Etfw">#freeCodeCamp</a> <a href="https://t.co/FPHkNP1aph">https://t.co/FPHkNP1aph</a></p>&mdash; LearnWith | Pythonでデータ分析 (@LearnWithHQ) <a href="https://twitter.com/LearnWithHQ/status/1512034354213449733?ref_src=twsrc%5Etfw">April 7, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

新入生、新人、一緒にJavaScriptしようぜ。

https://www.freecodecamp.org/

別に他の言語でもいい。たまたま私はここで、今日からJavaScriptをやろうと思った。

ここで選択肢がいくつかある。
1. 日本語版をやる。
2. 日本語版がないものの翻訳に協力する。
3. 英語版をやる。

私のお勧めは、まず英語版をやること。
そして、日本語版がないものの翻訳に協力する。

たぶん、日本語版はやらなくてもいい。

日本語版をやるのは、小学生か、英語が苦手な中学生が、
英語をやるか、プログラミング言語をやるか迷っている時くらい。

それでも、日本語盤がないものの翻訳に協力することはいいことだと思う。
翻訳していると、英語の間違いを見つけることがある。
結果として英文がよくなる。英語を読んでいると気がつかないことも、翻訳すると間違えに気がつく。

それなら最初から翻訳すればいいと思うかもしれない。
英語でやっていないことを、英語から日本語に直すのはほぼ無理。
やろうとしていることの意味を取り違えてしまう可能性がある。

英語でまずやってみると、ああ、英語ではこういうことをやらせたいのだと理解できる。
じゃ、日本語ならこういう表現でいいよねってわかる。

やらずに英語から日本語に翻訳すると、勘違いした日本語になる可能性がある。

# JavaScript


今年はTypeScriptかJavaScriptを本格的にやろうと思っていた。

これまでにも、何度かJavaScriptを動かしたことはあったはず。
全然身についていない。

50歳からのプログラミング言語入門。docker(152)

https://qiita.com/kaizen_nagoya/items/5c7cec79cb3b15237076

C言語を使っている人が、JavaScriptを始める場合と、C言語系の言語（C＋＋、 C#, JAVA)を使ったことがない人がJavaScriptを勉強するのを分けてみる。

まずC言語使用者が英語版をやってみる。

## C言語使用者

### 1. Comment

C言語と全く一緒。
ここからずっとC言語と一緒。

## 2. var
始めて違うのがvar.

## 3. let
次に違うのがlet.

## 4. const
constがどう違うかは確認予定。

## 5. backslash
文字列の中で文字列を表すのに\"を使う。
キーボードから¥を入れるのは駄目。コピペして\を使う。

##  あとがき

この記事は２つの行事参加記事です。

@torifukukaiou【毎日自動更新】新人プログラマ応援 - みんなで新人を育てよう！（2022年04月） LGTMランキング！

https://qiita.com/torifukukaiou/items/18dad64ba99aa5a40f95

@torifukukaiou 【毎日自動更新】データに関する記事を書こう！ LGTMランキング！

https://qiita.com/torifukukaiou/items/b10fa94764aaaa2c6db1

データに関する事項としては、JavaScriptでデータをどう扱うかと、
JavaScript勉強のデータという２つの観点で記録します。


＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20220417
ver. 0.02 ありがとう追記 20230504

## 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Ruby と crystal で解く AtCoder ABC248 C-D

# はじめに
AtCoder さん、ありがとうございます。
# C - Dice Sum
https://atcoder.jp/contests/abc248/tasks/abc248_c

動的計画法を応用して解きました。
## Ruby
```rb
n, m, k = gets.split.map(&:to_i)
MOD = 998244353
dp = Hash.new(0)
dp[0] = 1
n.times do |i|
  dp2 = Hash.new(0)
  (1..m).each do |x|
    dp.keys.each do |key|
      if key + x <= k
        dp2[key + x] += dp[key]
        dp2[key + x] %= MOD
      end
    end
  end
  dp = dp2
end
puts dp.values.sum % MOD
```
動的計画法では、配列をコピーしたりしますが、`Hash#keys`でコピーしている様な感じです。
## crystal
```cr
n, m, k = read_line.split.map(&.to_i)
MOD = 998244353
dp = Hash(Int32, Int64).new(0)
dp[0] = 1
n.times do |i|
  dp2 = Hash(Int32, Int64).new(0)
  (1..m).each do |x|
    dp.keys.each do |key|
      if key + x <= k
        dp2[key + x] += dp[key]      
        dp2[key + x] %= MOD
      end
    end
  end
  dp = dp2
end
puts dp.values.sum % MOD
```
`crystal`では`Hash`を使用する際、変数の型を指定する必要があります。
ここでは、`Int32`を越える可能性がありますので、`Int64`を指定しています。
||Ruby|crystal|
|:--:|--:|--:|
|コード長(Byte)|319|358|
|実行時間(ms)|706|179|
# D - Range Count Query
https://atcoder.jp/contests/abc248/tasks/abc248_d

二分探索を応用して解きました。
## Ruby
```rb
n = gets.to_i
a = gets.split.map(&:to_i)
h = Hash.new{ |h, k| h[k] = [] }
a.each_with_index do |e, i|
  h[e] << i + 1
end
q = gets.to_i
q.times do
  l, r, x = gets.split.map(&:to_i)
  if h.has_key?(x)
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size
    se = h[x].bsearch_index{ |e| r < e } || h[x].size
    puts se - ss
  else
    puts 0
  end
end
```
ここは、範囲を超えた場合の`nil`対策です。
```rb:nilガード
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size
```
## crystal
```cr
n = read_line.to_i
a = read_line.split.map(&.to_i)
h = Hash(Int32, Array(Int32)).new{ |h, k| h[k] = [] of Int32 }  
a.each_with_index do |e, i|
  h[e] << i + 1
end
q = read_line.to_i
q.times do
  l, r, x = read_line.split.map(&.to_i)
  if h.has_key?(x)
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size
    se = h[x].bsearch_index{ |e| r < e } || h[x].size 
    puts se - ss
  else
    puts 0
  end
end
```
`Ruby`でハッシュの値に配列を使用する場合の定番の書き方があります。
```rb:Hash
h = Hash.new{ |h, k| h[k] = [] }
```
`crystal`での書き方がよく分からないのですが、ごてごてしいです。
```cr:Hash
h = Hash(Int32, Array(Int32)).new{ |h, k| h[k] = [] of Int32 }  
```
||Ruby|crystal|
|:--:|--:|--:|
|コード長(Byte)|370|423|
|実行時間(ms)|665|164|
# まとめ
`crystal`はnil安全として静的な型チェックが入りますので、それを意識してコーディングする必要があります。
ラズパイでプライバシーに配慮した写真を撮る

# はじめに
個人識別に厳しい昨今、ラズパイのカメラで撮影する際に不用意に顔写真を保存したくない状況もあるんじゃないかなと思います。
自分や家族の写真を撮影した際、プライバシーに配慮して顔にスタンプを上書きした状態でSNSなどに投稿している方がいますが、同じようなことを自動でやるようにできないかと思い、MTCNNの顔検出を使ってやってみました。

# やったこと
ラズパイのカメラで撮影したキャプチャデータを保存する前に顔検出にかけて、顔の部分を塗りつぶします。目鼻口の位置だけ書いてあげることでどこを向いているかくらいはわかるようにしてみました。

撮影した画像は「privacy_camera.jpg」というファイル名で出力します。

``` python
import cv2
from mtcnn import MTCNN

filename = "privacy_camera.jpg"
detector = MTCNN()

# 画像の取得
capture = cv2.VideoCapture(0)
ret, frame = capture.read()
capture.release()

# 顔の検出
detect_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = detector.detect_faces(detect_image)

# 顔を検出している場合描画する
if len(result) > 0:
    #検出した顔の数だけ繰り返し
    for i in range(len(result)):
        bounding_box = result[i]['box']
        keypoints = result[i]['keypoints']

        # 顔を隠す
        cv2.rectangle(detect_image,
                    (bounding_box[0], bounding_box[1]),
                    ((bounding_box[0]+bounding_box[2]), (bounding_box[1]+bounding_box[3])),
                    (0, 0, 0), thickness=-1)
        cv2.circle(detect_image,(keypoints['left_eye']), 2, (0, 155, 255), 2)
        cv2.circle(detect_image,(keypoints['right_eye']), 2, (0, 155, 255), 2)
        cv2.circle(detect_image,(keypoints['nose']), 2, (0, 155, 255), 2)
        cv2.line(detect_image, (keypoints['mouth_left']), (keypoints['mouth_right']),
                (0, 155, 255), thickness=4, lineType=cv2.LINE_AA)

    # 画像を保存する
    cv2.imwrite(filename, cv2.cvtColor(detect_image, cv2.COLOR_RGB2BGR))

print(result)

```

# やった結果
ラズパイには、このような画像で保存されます。
多少左の方を向いていることと、ぼろぼろのパーカーを着ていることはわかりますが、顔はわからないようになっています。
顔がたくさん映っている場合も顔検出できれば全員プライバシーに配慮した形で保存されるようにしてみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1359985/b9b47625-25e6-b901-52e7-8295aacdbaed.png" width=50%>
JavaScriptのpushを使うときの注意点

初歩的なことだが初学者はハマってしまうと思うので備忘録

## push戻り値は要素数
pushメソッドは配列に追加してくれるが，**戻り値は要素数**となってしまう

つまり変数の上書きはダメです


```js
let numbers = [1, 2]
numbers.push(3)
console.log(numbers);
// 出力は，　　[1,2,3]　になる
```

```js
let numbers = [1, 2]
numbers = numbers.push(3)
console.log(numbers);
// 出力は，　3 になる
```

私は変数の上書きや別の変数をつけて使用しようとしてしまったのでハマりました
Amazon EC2で何も考えずにEBSボリュームだけを使う時代は終わったのかもしれない

# はじめに
- Amazon EC2コンソールのアップデートで、インスタンス作成時にAmazon EFSやAmazon FSx（for NetApp ONTAP / for OpenZFS）をマウントできるようになった。
    - https://aws.amazon.com/jp/about-aws/whats-new/2022/04/amazon-efs-integration-launch-ec2-console/
    - https://aws.amazon.com/jp/about-aws/whats-new/2022/04/amazon-fsx-file-system-ec2-launch-experience/
- これは、「**何も考えずにEBSボリュームを使うのはやめて、用途や要件に応じて適切なストレージサービスを使い分けるべし**」というAWS側のメッセージなのでは、と考えた。

# EBSボリューム以外に選択肢が増えると何が良いのか
- パッと思いつくメリットを書き出してみた。

## 1. ストレージコストが安くなる（かもしれない）
- Amazon EFSやFSx for ONTAPはストレージ階層化の機能があり、パフォーマンスが必要のないアーカイブファイルなどはより安価な階層に落とすこでコストを削減できる。
- FSx for ONTAPは、さらに重複排除や圧縮の機能があるのでよりコストを削減できる可能性がある。
- [過去の記事](https://qiita.com/seijitanabe/items/f16af0425d2f2f00af24)で比較したところ、高性能なio1などのEBSボリュームタイプの場合、プロビジョニングするIOPSによってはFSx for ONTAPの方が安価になる。
- コストが安くなるのは嬉しい。
 
## 2. バックアップ/リストア運用が楽になる
- EBSボリュームは、EBSスナップショットからデータを復元するのが地味に面倒くさい。
- 別のEBSボリュームとして復元し、元ボリュームをデタッチして付け替えるか、元ボリュームとは別の領域としてマウントして復元しないといけない。
- その点、Amazon EFSは同じボリューム上にデータを復元できるし、FSx for ONTAPのSnapshot（NetApp ONTAPの機能）も同様。
- 運用負荷はいくら下がっても良い。

## 3. EC2インスタンスをステートレスに保ちやすくなり、IaC（Infrastructure as Code）が捗る
- EBSボリュームはEC2インスタンスとの結びつきが強いため、密結合になりがち。
- ルートボリューム以外のデータをAmazon EFSやFSx for ONTAPなどの共有ストレージに置くことで、EC2インスタンスをステートレスに保ちやすくなる。
- IaCでインフラ構築を自動化している環境でEBSボリューム内にステートフルなデータが格納されていると、そのEBSボリュームをアタッチしているEC2インスタンスを作り直すときになかなか手間がかかる。
- ステートフルなデータがフルマネージドなストレージサービスに集約されていると、その辺がやり易くなる気がする。

# まとめ
- Amazon EBSは特にリッチな機能が備わっているわけではないただのブロックストレージなので、用途や要件に応じて最適なストレージサービスを使うというのは理に適っているし、メリットは多そう。
- ということで、Amazon EC2で何も考えずにEBSボリュームだけを使う時代は終わったのかもしれないし、少なくとも自分は少し考えてストレージサービスを使い分けようと思う。
- ちなみに、早速試してみようと思ったのだが、同時に自動作成されるセキュリティグループの作成に失敗してうまくいかなかった。AWS側の不具合とのこと。（2022/4/16現在）

# （おまけ）GUI以外でどうやるのか
- 自動化推進過激派としては、インスタンスを作るのにGUIでポチポチやりたくない。
- APIリファレンスを見る限り、今回のGUIのアップデートによるAPIの変更はなさそうなのでこれまでと変わらないと思う。
- 事前にファイルシステム側を作っておいてインスタント作成時にUserDataでマウントしてあげるとか。後は他の構成管理ツール側でやるとか。
- やり方は変わらないが、改めて何も考えずにEBSボリュームを使うのは変えていこう。
【朗報】全GASユーザー歓喜！アンケートの声を受けGoogleがスクリプトプロパティが復活

**ここでニュースです。** 2020年12月にGoogle Apps Scriptのスクリプトエディタがリニューアルされた際に、行方不明になってしまっていた「スクリプトプロパティ」が4月13日に復活したとGoogleが発表しました。

GASユーザーが不便さを感じていたスクリプトプロパティがアンケートでの鬼回答によって、Googleが復活をさせてくれました。

https://auto-worker.com/blog/?p=5608

# 消えたGASスクリプトプロパティ設定

Google Apps Scriptのスクリプトエディタ(IDE)は2020年12月にバージョンアップされました。

よりモダンなスクリプトエディタにアップデートされたのですが、まさかの機能から削除されてしまったのがスクリプトプロパティでした。

これまでは「プロジェクトのプロパティ」からスクリプトプロパティが設定できたのですが、新しいエディタにはどこにも見当たらず・・・

何時間もスクリプトプロパティの設定場所を探すユーザーが続出しました。

# 対応策はメソッド or 従来エディタ戻し

GASのスクリプトプロパティは、APIキーやトークンなどコードに直書きしたくない情報の保存先として重宝されていました。

しかし、アップデートされたIDEには、設定画面が忽然と消失し、設定方法を模索した結果、2つの代替案がでてきました。

1. GASのsetPropertyメソッドで設定
1. 従来のクラシックエディタに戻して設定

https://auto-worker.com/blog/?p=2365

新IDEのままスクリプトプロパティを設定するには、前者の方法しかありません。

しかし、スクリプトプロパティはもともと **「コードにAPIキーやトークンを直書きしたくない」** から使われていました。

それなのに、**設定のために一時的に直書きが発生するというなんとも本末転倒なやり方になりました。**

そのため、多くのユーザーは従来版エディタに戻して、スクリプトプロパティを設定する対応を取りました。

# アンケートによる声を送り続ける日々

> メロスは激怒した。必ず、かのスクリプトプロパティを復活させねばならぬと決意した。

Googleの方針に異を唱えるため、GASユーザーは動き出しました。

IDEを従来版に戻す際、なぜ戻すのかGoogleフォームで理由を回答できるので、毎回「スクリプトプロパティがないから」と回答しました。

![Snipaste_2022-04-16_21-28-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365005/b13a4486-6dcf-1b35-dd25-87c23be8283d.png)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GASのスクリプトプロパティをGUI操作できなくしたのは、新しいIDEでよくない変更点だと思っている。<br><br>コードでスクリプトプロパティを設定できるけど、内容のチェックが難しくなった。<br><br>旧スクリプトエディタを表示する際は、必ずアンケートで「スクリプトプロパティを戻して」と答えてる<a href="https://twitter.com/hashtag/linedc?src=hash&amp;ref_src=twsrc%5Etfw">#linedc</a></p>&mdash; ヤマタケ-業務自動化とSEOを極め中 (@gas_seo) <a href="https://twitter.com/gas_seo/status/1500779886335520770?ref_src=twsrc%5Etfw">March 7, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 祝！リリースノートで復活が発表

GASユーザーの願いがアンケートを通じて届けられた結果、Googleがとうとう動きました。

2022年4月13日のリリースノートでスクリプトプロパティを復活させたことを発表しました。

[Release Notes | Apps Script | Google Developers](https://developers.google.com/apps-script/releases)
![Clipboard01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365005/f36c4afe-ca1f-fab5-9d81-84c3dfdada05.jpeg)

まだ、すべてのユーザーが使えるようにはなっていませんが、現行IDEでもプロジェクトの設定ページにスクリプトプロパティが表示されるアカウントも確認されました。

![20220416_auto_003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365005/8a893b85-3e10-2b17-4c7b-4b2c1a30358e.jpeg)

**もうGASユーザーはわざわざ一時的にスクリプトプロパティを設定するコードを書いたり、従来版エディタに戻す必要はなくなったのです(感涙)**

# 終わりに

Google Apps Scriptのスクリプトエディタが2020年にアップデートされて、設定できなくなっていたスクリプトプロパティが設定可能になりました。

多くのユーザーから待望され、アンケートでも意見が届けられた結果、Googleが2022年4月13日のリリースノートで復活を発表しました。

まだ、アカウントによっては表示されないユーザーも多いですが、設定できるようになったアカウントも確認されています。

以前のようにスクリプトエディタからサクッとスクリプトプロパティを設定するようにしましょう！
ノーコードツール「Bubble」について調べてみた

# できること
- 自由度や拡張性が高く、細かい設定が可能
    - PlatioやAdaloなどがセミオーダーだとすると、Bubbleはフルオーダー
- ドラッグ＆ドロップでページが作れる
- パソコンからスマホまで対応
    - レスポンシブ対応が可能
- エコシステムが発達している
    - 世界中のデベロッパーが作ったテンプレートやAPIがマーケットプレースで取引されている
- カスタムコードを実行できる
- イベントハンドラがマウス操作だけで作れる
- APIを介して外部サービスとハードウェアに接続できる
- 外部データベースに接続できる
- 閲覧制限をかけられる
- 利用料はアプリ公開しなければ無料

# できないこと
- ネイティブアプリは作れない
↓有料で作る方法もある

https://blog.nocodelab.jp/entry/nativator

- プライベートサーバー、オンプレミスサーバーでアプリをホストできない
- JavaScript以外の言語は実行できない
- 複雑なアルゴリズムは開発できない
- 複雑なゲームは作れない
- コードをエクスポートできない
- ピクセル単位の精度でレイアウトするのはかなりやりにくい
- 他の要素とのmargin間隔は分かりづらい

# Bubble以外の主なノーコードツール
- Adalo（Webアプリ、ネイティブアプリ）
- Glide（Webアプリ）
- SAP appGyver（マルチプラットフォーム対応）
- softr（Webアプリ、Webサイト）
- Platio（モバイルネイティブアプリ）
- Yappli（モバイルネイティブアプリ）
- Unifinity（業務用モバイルアプリ　）
- Power Apps（ビジネスアプリ）
- MatrixFlow（AI構築）

https://tech-camp.in/note/technology/92173/


# 学べること
- 全て英語で書かれているので英語学習も同時にできる
- プログラミング的思考が身に付く
- データの関係性を直感的に学習できる


# Bubbleで作成されたアプリ
#### 公式サイトに掲載されている事例

https://bubble.io/showcase

#### その他の事例（海外）

https://billmo.jp/

https://www.escapethecity.org/

https://www.sendpilothq.com/

https://getmarlow.com/

https://www.theappdujour.com/

https://repstracker.com/

https://zoidii.com/

https://freeat2020.wixsite.com/

https://mydomos.com/

https://www.onotto.com/

https://sneak/

https://outkarma.org/

https://www.nalfe.com/

https://hackerhouse.world/

https://sprrk.ly/

https://moonehq.com/

https://yardguru.com.au/

#### その他の事例（国内）

https://awardpool.com/

https://koremo.bubbleapps.io/

https://bridal-renovation.com/

https://aihome-vr.com/

https://awardpool.com/

https://libris.ne.jp/

https://tripbook.jp/

# おすすめ教材・記事
#### テキスト

https://nocodewalker.com/bubble-all-tutorial/

https://note.com/hamasan918/n/n43b92e677182

https://blog.nocodelab.jp/links

https://hironk-blog.net/category/bubble/

https://note.com/taku_nocode/n/n9de487319e5d

https://monzcode.com/bubble_sample_app/

#### 動画

https://www.youtube.com/playlist?list=PLY4ztRF8YsV_FXljzz6Mj5JRsrEFIoAT7

https://www.youtube.com/watch?v=XqJIZ9OIY9E&t=10s


# 参考記事

https://plat.io/ja/posts/nocode_bubble

https://no-code.media/2021/12/30/post-2898/#outline__4

https://nocodedb.world/archives/3337

https://ktkm.net/bubble-io-can-do/

https://qiita.com/ikezzz/items/a638f3d3c05def0e826c
Flutter WebのBase URLを変更する方法

通常Flutter Webを起動するとアドレスの直下になってしまいます。
そのBaseの変更方法を紹介します。
既存のサーバーに相乗りする場合などに使います。

これをBaseというのかRootというのか。
Rootで検索すると本記事の３つ目が出てきました。
検索難民の助けになれば幸いです。

# Flutter Web の base / を変更する方法

build/web/index.html の15行目あたりの base タグを編集します。

```
<base href="/">
↓↓↓
<base href="/test/">
```

これで 192.168.1.1/index.html だったのが 192.168.1.1/test/index.html で実行できます。
既存のサーバーに相乗りする場合に使います。

# Flutter WebのURLの後ろに付く # を消す方法

main.dart を編集します。

```
import 'package:flutter_web_plugins/flutter_web_plugins.dart'; // 追加

void main() {
    setUrlStrategy(PathUrlStrategy()); // 追加
    runApp(MyApp());
}
```
これで消えます。URLの後ろに # が付くのが鬱陶しいと思っていました。

# Flutter Webのページのルートを変更する方法

```
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/': (context) => MainScreen(),
        '/test': (context) => TestScreen(), // 最後にスラッシュは不要
      },
```

これでブラウザでURLから直接ページに移動できます。
例 192.168.1.1/#/test

注意：「後ろに付く # を消す」状態だとこの方法は無効です。やはり # は残しておいた方が良さげです。
Spring Boot(Koltin) で独自エラーレスポンスを作成したい場合

# 何についての説明か？
- 独自のエラーレスポンスを作成する場合のやり方
    - 主に、API 開発で使うことができると思います。


# やりたいこと
- 以下のようなエラーレスポンスを返したい（独自エラーレスポンスを行いたい）

```json
{
   "status": 400,
   "message": "リクエストの値が異なります"
}

```

# 使用するコード

今回は、タスクの作成時を想定します。

タスクを作成する時は以下のような値を入力する
- summary
    - タスクの説明
- deadline
    - タスクの期限日


```kotlin
// タスクを作成する
@PostMapping
fun createParent(
    @RequestBody task: Task
) {
    taskService.create(
      summary = task.summary,
      deadline = task.deadline
   )
}
```

```kotlin
data class Task(
   // タスクの説明
   val summary: String,
   // タスクの期限日
   val deadline: Date
)
```
## 正常に動作する

```
$ curl -X POST -H "Content-Type: application/json" -d '{"summary":"サンプル", "deadline":"2022-04-30"}' http://localhost:8080/api/task/parent

{
   "summary":"サンプル",
   "deadline":"2022-04-30"
}
```

## 例外処理の作成

```kotlin

@RestControllerAdvice
class ApiControllerHandler : ResponseEntityExceptionHandler() {

//  リクエストに入る値の型が異なる場合、エラーとなる
    override fun handleHttpMessageNotReadable(
        ex: HttpMessageNotReadableException,
        headers: HttpHeaders,
        status: HttpStatus,
        request: WebRequest
    ): ResponseEntity<Any> {
        headers.contentType = MediaType(MediaType.APPLICATION_JSON)
        val res = ResponseError(
            status = HttpStatus.BAD_REQUEST.value(),
            message = "リクエストの値が異なります"
        )
        return handleExceptionInternal(ex, res, headers, status, request)
    }
}

// エラーレスポンス用のクラス
class ResponseError(
    val status: Int,
    val message: String?
)

```

## 説明
- `@RestControllerAdvice` を宣言している
    - API開発の場合は、これは**必須**
    - **「例外が発生した場合、このクラスでキャッチをして、処理をする」** ということを宣言している（例外の共通化）
- `ResponseEntityExceptionHandler()` を継承している
    - 例外処理を作成する際に必要なクラスであり、大部分の例外をキャッチし、処理してくれる
    - このクラスを継承することで、特定の例外時のレスポンスを作成することができる（ない場合は、↓のような Spring 標準の例外が返される）

```json
{
    "timestamp": "2022-.....",
    "status": 400,
    .
    .
}
```

- `HttpMessageNotReadableException` が使用されている
    - リクエストされた `body` の値変換が失敗した場合に出てくる例外クラス（`@RequestBody` をつけると発生する）
    - 今回の場合、`summary`, `deadline` の型が正しいかどうかを検証してくれる
- `headers.contentType = MediaType(MediaType.APPLICATION_JSON)`
    - JSON形式で返すことができる
- `return handleExceptionInternal(ex, res, headers, status, request)`
    - JSON 形式の`body` にすることができる

## エラーとなる リクエスト

```
$ curl -X POST -H "Content-Type: application/json" -d '{"summary":"サンプル", "deadline":"2022-04-30AAAAA"}' http://localhost:8080/api/task/parent

{
   "summary":"サンプル",
   "deadline":"2022-04-30AAAAA"
}
```


# エラー集（実装している最中に出たエラーなど）

## Content type 'application/x www form-urlencoded;charset=UTF-8' not supported


- レスポンスで返す際に、JSON形式にならないため、エラーになっていた
- `headers: HttpHeaders` で　
    - `headers.contentType = MediaType(MediaType.APPLICATION_JSON)`でJSON形式にすることができる


## Ambiguous @ExceptionHandler method mapped for [class org.springframework.web ~~~~ 
- クラス内に、`ResponseEntityExceptionHandler` 側で既に例外処理を行ってくれている部分を、自分で作成しようとしている。（同じ名前が存在しているため、エラーとなる）
- `override fun ~~` で作成しようとしていた例外処理のクラスを使うことで解決できる
ブラウザ版のPostmanを使用して、laravelにapiの動作確認を行う

こんばんは、kumaです。
現在プライベートでReactとlarvelで共同開発を行っており、その際にAPIの動作確認をPostmanを使用して行ったので、その際の確認方法を備忘録として残していきたいと思います！
自分と同じように、初めてPostmanを使用する方のお役に立てれば幸いです💦

## Postmanとは
> Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs—faster.

→ WebAPI開発を行う上で、自分でパラメータやtokenの中身を設定してHTTPリクエストを行ったり、返ってきたレスポンスデータの中身を確認したりできるツール。返却値が正しいものかどうかテストできたりもするらしい。他にもいろいろ機能があるみたい。

https://www.postman.com/product/what-is-postman/

## 動作確認手順
予め、laravel側でAPIを用意していると仮定します。
また、postmanにはwebクライアント版も存在しますが、MacOS11以上でないと対応しておらず、今回はブラウザ版で動作確認を行うことにしました。（本当はOSを上げてwebクライアント版を使用するのが推奨されているようなのですが、OSを上げて他の部分に影響が出るのがとても怖かったので今回はブラウザ版で対応しております。）

### postmanへの登録

postmanの公式ページから、ユーザー登録を行う。

https://www.postman.com/

### ワークスペースの作成

https://web.postman.co/home に移動し、下記画像の左側にある`Workspaces`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/5d01472e-7b4d-77c4-d42d-dde46f8552b6.png)

`Create Workspace`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/8f569df6-3cac-b0e5-b43b-d45f58b424df.png)

任意の名前、概要などを記入してワークスペースの作成を行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/0d0394df-65a1-1490-6d88-8d6be26dd182.png)

### collectionの作成

`collections`を選択し、`+ボタン`を押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/abb7ab44-6cd2-7eb7-8f14-9025fc461adc.png)

そうすると下記画像のようにあたらしいcollectionができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/7f3561f9-28e6-90c4-b739-a565c160d287.png)

### HTTPリクエストの作成
`New Collection`の横の`>`を押して、`Add a request`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/5a40b20c-cc3b-31c4-92e8-dd02426c5b9d.png)

下記のような画面になるので、この画面からリクエストの編集を行う。
今回はpostリクエストを行うので、赤枠部分の箇所を任意の値に設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/1dc3aa7d-ce8f-ee33-b5cb-cc7f792c5335.png)

### PostmanAgentのインストール
リクエストを送る場合、PostmanAgentをインストールしていないと、エラーになるのでインストールする必要がある。
下記記事を参考にして、PostmanAgentをインストール

https://www.cdatablog.jp/entry/postmanfortheweb

### 動作確認
`Send`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/1c0927f0-28e7-21d6-9e67-fd879955a44b.png)

以上になります！

## 最後に
調べてみると、レスポンスデータの値が自分の期待する値がどうかも確認できるようで、以前railsを使用してAPIを作成していたときはtを書いてAPIのテストを行っていたのですがPostmanでもテストができそうです！
アプリ側でテストを書くか、Postman側でテストを書くかどうかはまだ決めてないのですが、このような選択肢もあるということを知れて少し引き出しが増えた気がします！

最後に、もしこの記事を読んでいただいて、役に立ったと感じて頂けましたらLGTMをいただけますと幸いです💦（記事執筆のモチベーションになりますw）
頻出ワードランキング関数 forスプレッドシート

# 頻出ワードランキング関数 for Google スプレッドシート
- 背景
ウェブの記事やRSSをスクレーピングしてキーワードを引っ張ってランキングをつけたいことは、SEO 対策などで欲しくなることがよくありますね。スクレーピングしたものを引っ張ってきて、マニュアルでコピペして邪魔くさい作業を繰り返すのが辛くなることってままあります。関数で作れれば便利だろうな、という発想で作ってみました。

## WordRanking 関数

A 列に RSS で取得した Summary が入っているとします。この中から頻出ワードを取得するとします。対象列(今回は A列)の範囲を指定して、何位まで順位を表示するかを第二パラメーターで指定すると、ワードランクが出現回数付きで一覧させる関数です。

=WordRanking(セル範囲,表示する順位) と入力すると、A 列に入っている文字列全体からの頻出数が取得できます。

例) Engadget 日本語サイトの RSS の Summary を使って出現回数を取得しています。

![スクリーンショット 2022-04-16 21.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533932/f14c6683-c579-f4d7-234c-291a52ad7d36.png)
##### Special Thanks to Engadget!! 残念ながら Engadget は、2022年3月31日をもって日本での活動を終わりました。好きなサイトだったので寂しい限りです。


## コードとスプレッドシート(2024/7/30 カタカナの正規表現に誤りがあったため変更しました）
コードを含んだスプレッドシートは[こちら](https://docs.google.com/spreadsheets/d/1LLjinuyR8k6rJpF7p9bBvj8fBiaKAtNHAR5PBPj00Xc/edit?usp=sharing)です。読み込み専用なのでコピーして使ってください。


``` function WordRanking(targetRange,numOfList) {
  var stringarg=""
  var stringarg=JSON.stringify(targetRange)     // 配列を連続した文字化
  var ret=[]                                    // 仮配列 
  var namedArray={}                             // Unique 集計
  var res=[ /([\u30A1-\u30FAーー]){2,}/g,            // ２文字以上連続したカタカナ
            /([々〇〻\u3400-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF]){2,}/g,    //２文字以上連続した漢字
            /([-a-zA-Z]{3,})+/g]      // ３文字以上連続した英数字
// namedArray を利用して、出現回数の計測
  for (i=0;i<res.length;i++){
    var re=res[i]
    var ms=stringarg.match(re)
    for (m in ms){
      if (namedArray[ms[m]]==undefined){
        namedArray[ms[m]]=1
      } else {
        namedArray[ms[m]]=namedArray[ms[m]]+1
      }
    }
  }
  // 配列に格納
  for (key in namedArray){
    ret.push([key,namedArray[key]])
  }
  // 出現数によって降順ソート
  ret=ret.sort(function(a,b){if(a[1]>b[1]){return(-1)}else{if (a[1]==b[1]){return(0)} else return 1}})
  // ヘッダー追加
  ret.unshift(['Word','Frequency'])
  var topN=[]
  for (i=0;i<Math.min(ret.length,numOfList+1 );i++){
    topN.push(ret[i])
  }
  return(topN)
}
```
【SwiftUI】アクセシビリティでレイアウトが崩れる件について

# きっかけ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">稀に左側の様にレイアウトがバグってる端末の方がいるんですけど原因わかる方いますか？<br><br>背景にグレーの枠が付くのはSwiftUIで作ったボタンのみです<br><br>🌐と⌨️はUIKitで作ったボタンだから正常<br><br>これはSwiftUIのバグなのかな？<br>仕様なら発動条件がしりたい <a href="https://t.co/cBnK5ZQPlD">pic.twitter.com/cBnK5ZQPlD</a></p>&mdash; SNQ (@_SNQ) <a href="https://twitter.com/_SNQ/status/1492588580794888192?ref_src=twsrc%5Etfw">February 12, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 問題点

おそらくSwiftUIでしか発生しないです

**本来**
![IMG_0086.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/23dda5bc-5c01-b792-80e9-b416350e2a30.jpeg)
**アクセシビリティの「ボタンの形」がオン**
![IMG_0087.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/31dd39da-cb81-413c-2ccb-39354302f0c7.jpeg)

上記の画像のようにボタンのレイアウトが崩れてしまいます。

# 原因
```ContentView.swift
Button(action: {
    // 処理
}) {
    Text("Hello, world!")
        .foregroundColor(.white)
        .frame(width: 140, height: 60)
        .background(Color.black)
        .cornerRadius(10)
}
```
Button自体にframeが指定されていないのが原因です。

# 解決策
```ContentView.swift
Button(action: {
    // 処理
}) {
    Text("Hello, world!")
        .foregroundColor(.white)
        .frame(width: 140, height: 60)
        .background(Color.black)
        .cornerRadius(10)
}
.frame(width: 140, height: 60)
```
Buttonにframeを指定する事で解決します。
アクセシビリティの「ボタンの形」がオフであればレイアウトに問題ないので正直気付きにくいです。

# 「ボタンの形」の場所
設定→アクセシビリティ→画面表示とテキストサイズ→ボタンの形
【ng-ifは便利だけど少しクセがあるんじゃ！】

### はじめに
ある案件でコーディングしていた時、HTMLで制御しないといけない箇所があって、
他の分岐点と同じく、ng-ifを使用したのですがそれが思わぬ落とし穴にはまってしまいました。。
知識の定着のため、この記事を書くことにしました。

#### ng-ifに引っ掛かてしもた
例えば、以下のHTML文があったとします。
``` qiita.html
<td>
<span ng-if="hogeOption==1;" class="hoge">Hoge</span>
<input class="hoge" ng-model="hogedayo">
<div class="hoge" role="alert">
</div>
</td>
```
このHTML文は、hogeオプションが1の場合のみhogeという入力欄を表示するものです。
どうやら「ng-if」と「ng-model」が同じtdタグに入っていることが分かります。

#### ng-if とは？
ng-ifはもともとDOMツリーの一部を削除または再作成するものだそうです。
(DOMについては、DOMとは？の章を確認ください。)
この時、ng-modelの要素も一緒に削除されてしまうのです。
例えば、入力項目欄があり、入力フォームの中に「あああ」が入力されていたとします。「あああ」を削除したくて、削除ボタンを押したとき、削除したはずの「あああ」が残ってしまいました。ng-ifのもともとの機能のせいで、削除ボタンがうまく発動していないような表示になってしまいました。。

#### ng-showを召喚！
ng-showは、ng-ifと違い、DOMツリーの一部が削除されず、要素を表示もしくは非表示にする役割を持っています。なので一時的にデータが担保？されると考えています。(違っていたらすみません。。)
先ほどのqiita.htmlを少しだけ変更します。
``` qiita.html
<td>
<span ng-show="hogeOption==1;" class="hoge">Hoge</span>
<input class="hoge" ng-model="hogedayo">
<div class="hoge" role="alert">
</div>
</td>
```
「ng-if」を「ng-show」に変更するのみです。
「ng-show」に変更したら、「あああ」も無事削除できました。
めでたしでした。。

#### 余談
このバグを見つけるのに、私1人の力で解決するのが難しく、
お客さん先の方に夜遅くまで原因を見つけてくださりました。
本当に感謝してもしきれない。。ありがとうございます。。

#### DOMとは？
DOM・・・「Document Object Model」の略です。
ドキュメントを物として扱うモデルです。HTMLやXMLを自由に動かすものと思ってください。


#### 最後に
この記事が誰かの役に立っていたら幸いです。
最後まで読んでいただき、ありがとうございました。

#### 参考URL
https://teratail.com/questions/104471

https://code-examples.net/ja/q/124a104

https://eng-entrance.com/what-is-dom
Magicodeという簡単に稼げるエンジニア向けブログサービスを作ったので使って欲しい

> Magicodeは現在収益化機能・広告・エディター・記事ページの強化にフォーカスしており、コード実行機能についてはお休みしていますm(_ _)m 
そのうち超絶ハイクオリティで復活できたらいいなと思います👀

> 以下2022年4月時点での機能紹介記事です。

https://jp.magicode.io/

# Magicodeとは？
QiitaさんやZennさんのようなエンジニア向けのブログサービスです。Magicodeという名称は，magicとcodeを組合せた造語です。基本的にはマークダウンで自分のブログが書けるサービスですが，特殊な機能が以下の４つほどあります。

# 機能1. ブラウザ上でコードを実行できる
<img src="https://i.imgur.com/RAOa5as.jpg" width="480">

ハリーポッターの新聞は動きますよね。そんな感じでMagicodeの記事も動きます。この機能はMagicodeという名称の元にもなっています。PythonやGo, Rustほか10程度の言語のランタイムにブラウザから接続できます。投稿者は，直感的なエディターを用いてコード動かしながら記事を作成することができます。さらに，読者も投稿された記事のコードを自由に編集しオンデマンドで実行することができる（編集内容は元の記事には反映されません）ので，コードの挙動を確認しながら記事を読むことができます。

![](https://i.imgur.com/prsiuny.png)

# 機能2. お手軽な収益化方法

コミュニティを支える投稿者の方々に最大限還元するために，多様な収益化方法を用意しました。具体的には

1. 記事の広告
2. 有料コンテンツ
3. スーパーチャット

を提供しています。

従来のサービスでは有料コンテンツや投げ銭が主な収益化方法でした。しかし，例えば有料コンテンツでは一定の分量とクオリティが要求されたり，継続的なメンテナンスが必要だったりと，また，投げ銭はごく一部の投稿者しかもらえなかったりと，既存の投稿サイトでは収益化までのハードルが高く，誰もが気軽に収益を得られる訳ではありませんでした。

そこで，Magicodeではコミュニティを支える全ての投稿者が収益を得られるように，従来の収益化方法に加えて，記事に含まれている広告の収益をもらえるようにしました。また，投稿サイトでは初のスーパーチャットも導入しました。
そして，1円からアマゾンギフト券に交換できるので気軽に収益化することができます！アマゾンギフト券以外には銀行振込での受け取りに対応しています。
収益レポートではわかりやすく収益の様子を把握することができます。

![Screen Shot 2022-04-16 at 21.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751753/04125382-f3be-b562-1951-e5e77c24df66.png)

# 機能3. 様々な記事作成方法

収益化方法だけでなく，記事の作成についても色々な方法を用意しました。従来のサービスでは記事を作成するためにはマークダウンに準じたエディタでの編集が一般的でした。
Magicodeでは，より簡単に記事を作成できるように，ローカルおよびGithubからjupyter notebook(.ipynbファイル)やmarkdown(.mdファイル)をアップロードし，お手持ちのファイルから一瞬で記事を作成できるようにしました。もちろんゼロからマークダウンで執筆もできます。
その他，広告の量や挟む位置，接続するランタイムの言語，有料公開なども自由に設定でき，本の執筆も可能です！

<img src="https://i.imgur.com/zYXIl96.png" width="400">

![Screen Shot 2022-04-16 at 20.24.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751753/deff57af-a1bf-abc4-9f20-1f7dbba94aa2.png)

# 機能4. ダークモード
ダークモード、ライトモード、自由に切り替え可能です。目に優しいです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751753/76f4a904-8488-c16d-a33e-4351a5b7ee35.jpeg" width="400">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751753/6161807c-cd1d-e08f-2a6b-41291db851cc.jpeg" width="400">


# まずは試しにご利用してみてください！

こちらからぜひ使ってみてください！

https://jp.magicode.io/
UnityでVisualStudioのアタッチが外れた(ビルドができない)時の対処法

# 結論


```
Edit->Preferences->External ToolsのExTernal Script EditorをVisualStudioにセット

それでも無理ならExternal Toolsの下の方にあるRegenerate project filesを押し
プロジェクト内の.vsファイルを削除
```
![スクリーンショット 2022-04-16 213840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608292/21674f31-035a-a1f8-beca-d75d51cc9a4d.png)

# 参考記事

https://monmon.jp/881/you-can-no-longer-attach-debug-to-unity-in-visual-studio/


# なぜ急にアタッチが出来なくなるのか

わかりません。
別のC++プロジェクトを開いたままUnity立ち上げてC#を変更しようとしたら起きてた:frowning2:
変更しようとしてたのは、Standard AssetsのCarAIControllerってスクリプト。
using System;が、勝手に Unity using Systemに書き換えられてたのもあやしい。
それが原因だとは思えないけど...

Unity再起動したら、SafeModeで起動してとか、プロジェクト破損するかもよーって出てきてめっちゃ焦った(笑) 
作業進まないからignoreで進めたけど、特に変わったところはなさそう！責任はとれない。
【新人プログラマー応援】Qiitaのアカウントを作って分からないことを共有しよう

だれしも最初は産みの苦しみを味わう。（最初はいつもそう）
そんなとき誰か頼れる人がいればと思う人は多いはず。
今回Qiitaを使ってそんな人を応援すべくQiitaのページをどんどん投稿していこうというページを作ってみる。
https://qiita.com/official-events/3f21c92121aa125807b4

# Qiitaってどんなところ?
Qiitaってどんなサイトなの？って言われると意外と難しい。
技術的なこと全般を書いてあるページだと思ってくれるといいんじゃないかな。
結構こんなことでページ作っているんだという人も多いと思う。

# Qiitaにページを作るのに必要なもの
最低限Qiitaにページを作るにはQiitaのカウントが必要である。
ちょっとインターネットを探ればQiitaのアカウントの作り方等は調べられるので、ちょっとググって。

# どんなことを書けばいい?どんな風に書けばいい
一応Qiita内でもルールは存在する。だけど、そんなルリールをいちいち照らし合わせて確認して。。。。なんて時間は新人さんにはないと思う。
だからこそ最初は題名だけのページだけでもいいと思う。
特に最初にどんな風に書けばいいのか分からないのであれば、題名に（ここが分からない）とだけ書いてあるページを作ってもいいと思う。
本文なんて書けなくてもこの人は初心者さんなんだなとか思って、いろいろと教えてくれる人も少なからずいる。

# 編集方法を学んで自分なりのページに仕上げる。
一応マークダウンの技法とちょっとしたhtmlの知識があれば、Qiitaのページは見やすくなる。
そこまで学べればいっぱしのQiitaのユーザである。

# 質問に解答があったら
質問に対し、コメント等を残してくれる人がいたら、感謝の意と参考になったのであれば、質問の後に解決した方法とかを載せると後後この人はこういう方法で解決したんだという風になるだろう。
もちろんコメントを記載してくれた人への感謝の意とそのコメントをしようしていいかどうか等の確認はお忘れなく。
メンションとか効率よく使えると相手としてもコメントして良かったなと思える限り。

# 質問するのは恥ずかしい?いや、逆ですよ、質問しないことこそ恥。
最初はインターネットのQiitaのページなんて作ってデジタルタツー（一緒残る電子データ）になることを恐れるあまり、
Qiitaの質問ページすら作れないかもしれない。
ただ、インターネットのページなんて腐るほどあるし、全世界の人からすれば見る人なんてごく一部の人だしとか思って気軽に投稿してほしい。
同じように悩んでいる人なんているわけだし、その人の役には立てるぞ。
逆に質問しないことを悪や恥だと思った方がいい。
残せるデータ（機会）があったにも課買わず、そのチャンスをなくしているのも同然。
分からないことは分からないわけだし、聞いてしまえ。
新卒の仕事の一つに上司へ質問という項目を作りたいくらいである。
上司としてはつまらない質問かもしれないが。

# ときにはコメントに傷つくこともある。
質問ページも同様なのだが、他人の誹謗や中傷はよくない。なので、投稿する前にちょっとだけ他人のことを考えてほしい。
だけど、それでも投稿にしてしまうことだってあるだろうし。それはそれで指摘された時に修正すればいい。
分からなかっったでは済まされないことは新卒の君らなら分かる筈だ。
そしてそういうコメントが書かれたとしても無視すればいい。
自分の都合のいい情報だけ書けばいい。コメントを消す機能だってある。

# 余談
公私は混同しないようにしよう。
あくまでも研修は業務の一環。
業務中のQiitaの確認はいいかもしれない（場合による）が、ほとんどの場合は質問の投稿やコメントの記載はダメ。
こういうことを混同していると上司から指摘対応になる可能性も留意してほしい。
あくまでコメントとか文章を書くのは私の時間でね。
また、Qiitaのアカウントも自分のメールアドレス等で作ろう。

# 最後に
つまらない長い文章で大変失礼。
Javaでの乱数記述の仕方

# Javaでの乱数の記述の仕方について

乱数の表記表には複数種類存在する。

#### 1.Random関数を用いた記述
　Randomクラスは、疑似乱数を生成するためのクラスである。戻り値はint型であり、乱数のように見えるが、実際には一定の規則で生成されている数字。
　Randomクラスを使用するには`java.util.Random`をimportする必要がある。
#### ソースコード
~~~Java
import java.util.Random;

public class Main {
  public static void main(String[] args) {
    Random r = new Random();
    int r = random.nextInt(➀);
    //0以上➀未満までの間で乱数を取得する
  }
}
~~~
import文も含めて1文にまとめることも可能である。`int r = new java.util.Random().nextInt(➀);`
また、コンストラクタに初期値(シード)を与えると、生成される疑似乱数列を固定することができる。`Random r = new Random(0);`

#### 2.Math関数を用いた記述
　MathクラスはRandomクラスとは異なり、double型の0.0 以上 1.0 未満の完全ランダムな数値が返される。
　Mathクラスはdouble型であり、小数点以下をいじることができるメソッドが3つ存在する。
　1つ目は、Math.ceilメソッドで、引数に指定した数値に対して、数値以上の値で最小の整数を戻り値として返す。いわゆる切り上げである。
　2つ目は、Math.floorメソッドで、引数に指定した数値に対して、数値以下の値で最大の整数を戻り値として返す。いわゆる切り捨てである。
　3つ目は、Math.roundメソッドで、引数に指定した数値に対して、数値を四捨五入した値をlong 型の整数で戻り値として返す。
Livedoorニュースコーパスの1記事をMeCabで形態素解析して名詞だけを抽出するまで

# 環境
Python 3.7.6（Jupyter Notebook）
MeCab 0.996

# Livedoorニュースコーパスのダウンロード
https://www.rondhuit.com/download.html からldcc-0140209.tar.gzをダウンロード・解凍。

# MeCabで名詞の抽出
次のコードを実行して、「独女通信」の1記事を形態素解析・名詞のみ抽出する。
```python
import MeCab

# 形態素解析の辞書を指定
mecab = MeCab.Tagger("-Ochasen")

# 適当なパスを指定
text = open("dokujo-tsushin-6915005.txt", mode="r").read()

result = []
for line in mecab.parse(text).splitlines():
     if "名詞" in line:
            result.append(line.split()[0])
            
print(result)
```
### 《解説》
* ファイルオブジェクトのread()でファイル全体を文字列として取得します
* mecab.parse(text)で形態素解析して得られるデータはtsv形式です
* splitlines()で1行に分割し、"名詞"を含む場合はresult(リスト)に追加します

↓ 形態素解析で名詞だと解析された1行を抜粋
```
男女	名詞,一般,*,*,*,*,男女,ダンジョ,ダンジョ
```


# 結果
```
['http://', 'news', 'livedoor', '.com', 'article', 'detail', '6915005', '2012', '09', '03', 'T', '14', '00', '00', '0900', 
'男女', '間', 'カワイイ', '基準', '理由', 'マナ', 'さん', '26歳', '塾講師', '顔立ち', '柳原可奈子', 'メイク', 'ファッション', '方', '参考', 'こと', 'の', '以前', 'の', '嫌', 'しかた', '柳原', 'な！', '最初', 'の', 'アルバイト', '先', '先輩', '男性', '肥満', '体型', '丸', '顔', '無駄', 'ところ', '場', '私', 'そうそう', 'ん', 'ある時', '期', '柳原可奈子', 'の', '理由', '同僚', '女性', '塾', '生徒', '女子', 'たち', '柳原可奈子', 'カワイイ', 'よう', '彼女たち', '柳原可奈子', '存在', 'ん', '言葉', 'ん', '自分', '自信', 'よう', 'マナ', 'さん', '人', '印象', '男女', 'こと', 'カワイイ', '感覚', '差', 'よう', '男性', 'たち', '女性', 'カワイイ', 'あて', 'もの', 'カワイイ', '女性', 'たち', '感性', 'ボキャブラリー', 'の', '声', 'の', '…。', 'カワイイ', '感覚', '的', '理由', 'ん', 'の', 'アサコ', 'さん', '33歳', '広告', '関連', '好き', '人', 'モノ', 'カワイイ', '男性', '前', '声', 'トーン', '態度', '女性', '容姿', '性格ブス', '男性', 'カワイイ', '容姿', '重視', 'の', '既婚', '者', 'ヒロコ', 'さん', '37歳', '公務員', '彼女', '結婚', '同僚', '友人', '紹介', '反応', 'ん', '最初', '見た目', '振り分け', '性格', 'しぐさ', '関心', 'ん', '彼女', '結婚', '私たち', '女性', 'カワイイ', '言葉', '周囲', '男性', 'たち', 'ヒロコ', 'さん', '話', 'ところ', '男性', '見た目', '優先', 'の', '異性', 'の', '仕方', '女性', 'イケメン', '反論', 'の', 'アキヒロ', 'さん', '34歳', '設計', '意見', '彼女', '容姿', 'カワイイ', '女性', 'つながり', 'こと', '自分', 'ステイタス', '自信', 'ん', '新た', '女性', '紹介', 'とき', '容姿', 'ん', '容姿', '重視', '男性', 'たち', 'ガード', 'そう', 'お金', 'そう', 'そう', '判断', '瞬時', '知り合い', 'メリット', '女性', '女性', '無意識', '区別', 'の', '8月24日', '配信', 'ブス', '森山中', '大島美幸', 'ブス', '理由', 'Gow', 'Magazine', '放送作家', '鈴木おさむ', 'ネタ帳', 'アメブロ', '妻', '美幸', '魅力', '共感', '女性', '彼女', '魅力', '多く', '男性', 'たち', '男女', '間', 'カワイイ', '溝', 'こと', '共感', '範囲', 'こと', '大切', '女性', 'カワイイ', 'ポイント', '男性', 'たち', '共有', 'よう', 'カップル', '世の中', '何', '倍', 'こと', 'オフィスエムツー', '神田', 'はるひ']
```
配布された状態のテキストは最初の2行がリンクと時間情報を含むため、
2行分の無駄な英単語や数字を含んでしまったが、とにかく名詞を抽出できた。
JavaScript 学びまとめ１

●console.log(" ");
 ()内に書かれた文字を出力

●//console.log
 コメントアウト

●let name
 変数　変数は書き換え可能
※nameの部分は自由に命名可能　英単語、２文字以上の英単語は大文字で区切る　例）oddNumber

変数更新の際は、"let"　は付けない

●const name
 定数

テンプレートリテラル
文章の中に変数や定数を用いることができる
console.log(`~${変数or定数}~`) ()内は``(バッククォーテーション)で囲む
変数（定数）は${}で囲む

●if
 条件分岐　if (条件)　｛　処理　}

●演算子
・演算子　< <= > >=
・等価演算子　== 等しい　!= 異なる
・厳密等価演算子　=== 厳密に等しい　!==　厳密に異なる

●else
 ifの条件が成り立たない場合の処理
if (条件) { 条件trueの時の処理　} else { 条件falseの時の処理　}

●else if
 条件追加
if (条件１) { 条件１がtrueの処理 } else if(条件２) { 条件１がfalse、条件２がtrueの時のしょり } else { 条件２がfalseの時の処理 }

●&&or||
&& かつ　|| または

●switch
if分以外の条件分岐
switch(条件の値) {
 case : 処理
   ...
fault: caseにしない値の処理
※処理ごとにbreakを必ず忘れない！！
【jQuery UI】sortableで並び替え+表示順更新

# はじめに
`jQuery UI`の`sortable`を使用して項目を入れ替え、
その後表示順を更新する機能を作成しました。

# 読み込むもの

```html
<!-- jQuery -->
<script
  src="https://code.jquery.com/jquery-3.6.0.js"
  integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
  crossorigin="anonymous"></script>

<!-- jQuery UI -->
<script
  src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"
  integrity="sha256-xH4q8N0pEzrZMaRmd7gQVcTZiFei+HfRTBPJ1OGXC0k="
  crossorigin="anonymous"></script>
```

最新のリンクはこちらから↓
https://releases.jquery.com/

# sortableにする

親要素に対して`sortable()`を付与するだけで、ドラッグアンドドロップで
順番を変えることができます！簡単！

```html
<script>
  $(function(){
    $('#sortable').sortable();
  });
</script>

<div id="sortable">
  <div>
    項目1
  </div>
  <div>
    項目2
  </div>
  <div>
    項目3
  </div>
</div>

```

# 表示順を変える
**sortable**で順番を変えたものを保存するために、
順番変えたあとに表示順を更新する機能を追加させます。

まずインプット要素のhiddenタイプで順番を持たせます。
そして**sortable**が終了したらその順番を更新させる
というロジックを実装します。

```html
<script>
  $(function(){
    $('#sortable').sortable();
    $('#sortable').bind("sortstop", function(){
      $(this).find('[name="display_order"]').each(function(idx){
        $(this).val(idx + 1);
      })
    })
  });
</script>

<div id="sortable">
  <div>
    <input type="hidden" name="display_order" value="0">
    項目1
  </div>
  <div>
    <input type="hidden" name="display_order" value="1">
    項目2
  </div>
  <div>
    <input type="hidden" name="display_order" value="2">
    項目3
  </div>
</div>
```

`sortstop`をトリガーとして、name属性で指定しvalue値を更新してます。

他のイベントをトリガーとしたい場合はこちらのイベントタブに一覧あります↓
https://js.studio-kingdom.com/jqueryui/interactions/sortable
【Next.js】共通レイアウトの適用方法

## はじめに
本記事は、プログラミング初学者が学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。  
そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。  
間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。  

## 共通レイアウトの適用方法
以下の手順で複数画面に同じレイアウトを適用します。  

### `Layout.js`を作成
共通レイアウトを定期ようさせるために`components`フォルダを作成し、その中に`Layout.js`を作成します。  

![スクリーンショット 2022-04-16 20.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/dd0ff671-4cc9-b86b-4739-24212157a835.png)


`Layout.js`に以下のように共通のレイアウトを記述します。  

```Layout.js
import Head from "next/head";
import styles from '../styles/Home.module.css'

export const appName = "Sample App"

function Layout({ children }) {
  return (
    <div>
      <Head>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <header>
        <h1>{appName}</h1>
        <p>ここにはLayout.jsの内容が表示されています。</p>
      </header>
      <main className={styles.main}>
        { children }
      </main>
    </div>
  );
}

export default Layout;
```

### 各ページにレイアウトを適用する
次に、`Layout.js`で記述したレイアウトを`index.js`に適用するため、`index.js`に追記します。  
なお`index.js`の画面は以下のようになっています。

![41514252-5915-4238-95BF-A479208886AD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1a3a2f01-14a7-0967-a3cb-0ab582dc74b7.png)


```index.js
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import Image from 'next/image'
import Link from 'next/link'
import Layout from '../components/Layout'  // 追記


export default function Home() {
  return (
    <Layout>
      <h1 className={styles.title}>
        Welcome to
        <Link href="/posts/samplePost">
          <a> Sample App!!</a>
        </Link>
      </h1>
      <Image src="/sample/sample.jpg" alt="Sample Image" width={500} height={500} objectFit="contain" />
    </Layout>
  )
}
```

`Layout`コンポーネントをインポートして`index.js`の内容を`<Layout></Layout>`の中に入れました。  
すると、以下のように`index.js`の画面に`Layout`で設定した記述が表示されます。

![3E69E46C-66E2-428A-B2CA-18E5D65E8D8D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c3ed10be-2a8b-1adf-139d-f5c59c0ba2b7.png)


### 他のページにも適用する
`samplePost.js`にも同じようにレイアウトを適用します。
`samplePost.js`の画面は以下のようになっています。

![6762DCDD-9824-416B-B312-E67A951BE3BC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5600d925-4ce4-1b29-fa1b-4a2e9e0006a7.png)


`samplePost.js`を以下のように記述します。

```samplePost.js
import Layout from "../../components/Layout";

export default function() {
  return (
    <Layout>
      <h1>samplePost</h1>
      <p>samplePostのページが表示されています。</p>
    </Layout>
  );
}
```

`index.js`と同じように`Layout`で設定した記述が表示されました。

![92FCBDDF-C51D-46FB-99D1-2E33ACBE6D27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5ba8ae7b-e4fa-6c5a-930f-73018457fa1c.png)
Nanogui で日本語入力ができるようにした

# 対応したのは TextBox

入力のコードがあるのは TextBox だけなので（試してませんが、TextArea は入力できないような）、当然ながらそこしか対応していません。
[github で fork したリポジトリ](https://github.com/oikumene/nanogui) の feat/unicode-input ブランチに置いてあります。
日本語に特化した変更ではないので、ほかのIMを使う言語も入力できると思います。

## 使い方

resources/ に日本語TTFフォントを置いて、 ~~theme.h と~~ theme.cpp にフォント名を追加します。例えば GenShinGothic-Medium.ttf、GenShinGothic-Heavy.ttf、GenShinGothic-Monospace-Medium.ttf を置いたら、

2022/04/17 修正:

set_font() を持っている Widget は Label と TabWidget と TextArea だけぽいので、全体を通してフォントを変更したい場合、打ち消し線で消した部分のやり方だと C++ では

> Some widgets allow you to set fonts directly, but if you want to apply the font
> globally, you should create a sub-class of `nanogui::Theme` and explicitly
> call `nanogui::Widget::set_theme` for each widget you create.

とある通り `Theme` のサブクラスを書かないとならず、python では手段がありません。
ということで、デフォルトフォントを書き換えてしまう方が良いでしょう。

```diff_cpp:theme.cpp
-    m_font_sans_regular = nvgCreateFontMem(ctx, "sans", (uint8_t *) roboto_regular_ttf,
-                                           roboto_regular_ttf_size, 0);
-    m_font_sans_bold = nvgCreateFontMem(ctx, "sans-bold", (uint8_t *) roboto_bold_ttf,
-                                        roboto_bold_ttf_size, 0);
+    m_font_sans_regular = nvgCreateFontMem(ctx, "sans", (uint8_t *) genshingothic_medium_ttf,
+                                           genshingothic_medium_ttf_size, 0);
+    m_font_sans_bold = nvgCreateFontMem(ctx, "sans-bold", (uint8_t *) genshingothic_heavy_ttf,
+                                        genshingothic_heavy_ttf_size, 0);
     m_font_icons = nvgCreateFontMem(ctx, "icons", (uint8_t *) fontawesome_solid_ttf,
                                     fontawesome_solid_ttf_size, 0);
-    m_font_mono_regular = nvgCreateFontMem(ctx, "mono", (uint8_t *) inconsolata_regular_ttf,
-                                           inconsolata_regular_ttf_size, 0);
+    m_font_mono_regular = nvgCreateFontMem(ctx, "mono", (uint8_t *) genshingothic_monospace_medium_regular_ttf,
+                                           genshingothic_monospace_medium_ttf_size, 0);
```

~~include/nanogui/theme.h に~~
~~int m_font_genshin_medium;~~
~~を追加して、~~
~~src/theme.cpp に~~
~~m_font_genshin_medium = nvgCreateFontMem(ctx, "genshin-medium", (uint8_t *) genshingothic_medium_ttf,genshingothic_medium_ttf_size, 0);~~
~~を追加して、~~

あとは cmake してビルドします。

## 変更の解説とか必要?

面倒なので差し当たっては割愛します。[commit の diff](https://github.com/oikumene/nanogui/commit/15aabbf4cb1b0c5656698065c0f63f9d5f51eea5) を見てください。

## 困りごと

オリジナルの nanogui では、TextBox で enter を押したところで入力が確定（commit）されて編集モードを抜けるのですが、GLFW的に「単にENTERを押した」のと「日本語入力を確定したENTER」が区別できなくて、文字列が確定されるのは Screen のその TextBox 以外の部分がクリックされた時だけにしてしまいました。これなんとかならないものでしょうか。

## 今後

コメントとか整えたら[本家](https://github.com/mitsuba-renderer/nanogui)に pull request を出そうと思ってはいます。挫けなければ。
コードの変更は小さいですが、上で書いた文字列確定の仕様変更があるので受け入れられるか心配ではあります。
あと、utf8() 関数はいじっていないのですが、ちょっとまずい（弾くべき値を弾いていない）気がするんですよね。直す必要があるでしょうか。
【MEO対策】【Googleマイビジネス】口コミと評価一覧をExcel形式で取得するブックマークレット

Googleマイビジネス（GoogleMap）の店舗の直近の口コミレビューと評価について、APIや専用ツールを使わずに簡易的に取得するブックマークレットです。PC版GoogleChromeで確認しています。MEO対策の一環として、まだAPIや専用ツール使うほどじゃないないんだけどまとめたい・・・という時などにご活用ください。

※あくまで表示されているものをまとめているので、日付は明確な日付でなく、〇ヵ月前、〇週間前といった表記になります。

## 結果イメージ
こんな感じで、Excelにまとめやすいタブ区切りのデータを出力出来ます。
![revew-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/26bde87d-7354-0a31-3498-94eb4009b0a3.png)


## 使い方
事前準備：後述するコードを、適当なブックマークのURLに貼り付け。

1.知りたい店舗を検索→マップに表示
![revew1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/b25514b7-fe51-4911-b51e-932222fbffaf.png)

2.クチコミを表示
取得したい件数分まずは表示する必要がありますので、
必要な分スクロールする必要があります。
![revew2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/7f42329d-c65d-9c70-b7c6-1cf965583b47.png)

3.ブックマークレットを起動（保存したブックマークを押す）
ポップアップが表示されるので、これをコピーしてExcelに貼り付け
![revew-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/c047c124-f36b-5d1c-a496-159057098bce.png)



## Javascriptコード
Googleの口コミ結果から、クラス名を読み取って、必要な部分だけ抜き出しています。また、この結果をポップアップウインドウかつテキストエリアに書き出しています。Excelにコピーしやすいようにタブ区切りにしています。

```
javascript:a();function a(){moji = "";com = document.getElementsByClassName('Jtu6Td');all = document.getElementsByClassName('PuaHbe');p = all.length;for(i = 0;i < p; i++){moji+=all[i].querySelector('.Fam1ne').getAttribute("aria-label") + "\t" + all[i].querySelector('.dehysf').innerText + "\t" + com[i].innerText.replace(/[\n\r]/g,"") + "\n";} subWin = window.open("sub.html","sub","width=500,height=740");subWin.document.open();subWin.document.write("<textarea style='width:300px;height:500px;'>" + moji + "</textarea>");subWin.document.close(); };
```

## 最後に
MEO専用ツールを使ったり、APIから取得すれば、これは不要だと思いますが、何らかの事情で簡易的にまとめたい時などにご活用くださいませ！
※Googleの仕様（class名など）が変わった場合は使えませんので、ご了承ください。
TableViewプロパティ詰め合わせ

# はじめに
TableViewで使えるプロパティ、調べれば調べるほどごろごろ出てきます。
そこで、override.func viewDidLoad内に置くだけですぐに使えるプロパティを紹介しますので、是非使ってみて下さい。

```swift:ViewController
        //空白のセルの表示を設定。デフォルトで空白は表示されない
        tableView.tableFooterView = UIView(frame: .zero)
        // trueでセルの選択、falseで選択無効※isEditingモードでは無効になる
        tableView.allowsSelection = true
        //trueで複数選択、falseで単一選択※isEditingモードでは無効になる
        tableView.allowsMultipleSelection = true
        //編集を可能にする
        tableView.isEditing = true
        //セルの選択が出来る様にになる※isEditingモードで有効になる
        tableView.allowsSelectionDuringEditing = true
        //左にチェックマークが付く※isEditingモードで有効になる　同時に複数選択可能になる
        tableView.allowsMultipleSelectionDuringEditing = true
```

このプロパティをtrueにしたりfalseにしたり色々試してみる事でtableViewの理解が深まるので遊んでみて下さい!!
Swiftでネイピア数を求める。

```Swift
func exp(_ x: Double) -> Double {
    if abs(x) < 1e-12 {
        return 1 + x
    }
    let a = exp(x/2)
    return a*a
}

print(exp(1)) // 2.718281808182473
```

理論値: $e = 2.71828 18284 59045 23536 02874 71352$
【🔴RSpecエラー】「Docker」+「Rails6」環境で、request（コントローラー）テスト時に発生する「403」エラーについて

# ✅当方の環境
- 開発環境 : Docker
- ruby 2.7.5
- rails 6.1.5

# ✅Gemの内容（必要なもののみ）
```言語:Gemfile
＜中略＞

group :development, :test do
  gem 'pry-rails'
  gem "rspec-rails", "~> 4.0.1"
  gem 'factory_bot_rails', '~> 5.0'
end

＜中略＞

group :test do
  gem 'capybara', '~> 3.28'
  gem 'selenium-webdriver', '~> 3.142'
  # gem 'webdrivers', '~> 4.1'　
　#「webdrivers」は、Docker上では使用しません。（以前は、chromedriver-helperという名称）
end

＜中略＞
```


# ✅ エラー内容
- 「bundle exec rspec」コマンドのエラー内容
```
Failure/Error: expect(response).to have_http_status(200)
expected the response to have status code 200 but it was 403
```

# ✅エラー発生箇所

```言語:app\spec/requests/food_enquete_spec.rb
get food_enquetes_path
expect(response).to have_http_status(200)
```

# ✅解決法
- 「rails_helper.rb」を修正する
```言語:app\spec\rails_helper.rb
ENV['RAILS_ENV'] ||= 'test' #修正前
ENV['RAILS_ENV'] = 'test' #修正後
```

# ✅エラー原因
:::note warn
実は、RSpec時は「development」環境でテストを実行していたから、エラーが発生した。
- そのため、モデルテストでは「development」環境のデータベースにてデータの登録を行っていた。
- なぜ「development」環境でテストが実行されているのかというと、「Dockerfile」または「docker-compose.yml」に「RAILS_ENV=development」に環境変数を設定しているから
- 自身の環境変数を確認したい場合は、「echo ＄RAILS_ENV」で確認できる。(rails Cの場合は、「.echo $RAILS_ENV」)
- RSpec時の実行する環境の判断は、「app\spec\rails_helper.rb」で行っており、環境変数が設定されていれば、その設定でテストを実行。
- 環境変数がなければ、「RAILS_ENV=test」として、テストを実行する
- それが「ENV['RAILS_ENV'] ||= 'test'」コードである。
:::
:::note alert
なぜ「development」と「test」環境で処理が違うのか？、については以下を参考
- [docker環境でrspecで403エラーが出た時の解決](https://zenn.dev/akhmgc/articles/5fa1ed2bc018e4)
- [RSpec(rspec-rails)のrails_helperの初期設定は「RAILS_ENVがなければtestにする」という設定なので気をつける](https://shinkufencer.hateblo.jp/entry/2019/12/28/000000)
:::