OmniAICreator/Qiita-1.07M huggingface dataset:
fsモジュールとpathモジュールを使う

Next.jsのチュートリアルをやっていたらいきなり`import fs`だの`import path`だの出てきて分からなくなったので調べました。
したがって本稿ではチュートリアルに出てきた内容に絞って書いています。
なお、当方は初心者ですので間違っているところがあれば教えていただけると助かります。

# fsやpathはNode.jsでファイルを操作するためのモジュール

「fs」はファイルを読み込んだり、新規作成したり、追記したり、削除したりできる。
File Systemの略ってとこですかね。

「path」はファイルパスからディレクトリ名を取得したり、文字列としてパス操作ができます。
pathはファイルパスのことですね。

# 前提
当たり前だけど、Node.jsを使うわけだからあらかじめnodeをインストールしておく必要があります。
Next.jsのチュートリアルだったので初めに`create-next-app`したときにインストール済みだったわけですね。

# モジュールをインポートする
プレレンダリングとデータフェッチの段階でいきなりこいつらが現れました。
[Next.js公式チュートリアル](https://nextjs.org/learn/basics/data-fetching/implement-getstaticprops)

~~~javascript
import fs from 'fs'
import path from 'path'
/*
 const fs = require('fs') および
 const path = require('path') という書き方で解説してるサイトもあるが、同じこと。
*/
~~~

ここでは、fsやpathといったモジュールをインポートして以降このファイルでファイル操作を可能としているわけです。
続いて以下のコードが記述されています。

# 

~~~javascript
const postsDirectory = path.join(process.cwd(), 'posts') // ...１

export function getSortedPostsData() {
  // Get file names under /posts
  const fileNames = fs.readdirSync(postsDirectory) // ...2
  const allPostsData = fileNames.map(fileName => {
    
//... 中略

  })

 return(
//...　中略
  )
~~~

# path.join( )はディレクトリ名を結合する
まず***1.***の内容について

~~~javascript
const postsDirectory = path.join(process.cwd(), 'posts') // ...１
~~~

`path.join(引数1, 引数2, ...)`は引数にディレクトリ名を複数指定することで`/`を追加して`引数1/引数2/...`という文字列を取得します。

今回は`process.cwd()`で現在のワーキングディレクトリ(current working directory)を取得し、`posts`ディレクトリまでのパスを戻り値として`postDirectory`という名前をつけているんですね。


※このチュートリアルではブログ記事を作成しています。

[path.join( )について＜Node.js公式ドキュメント＞](https://nodejs.org/api/path.html#path_path_join_paths)

# fs.readdirSync( )はディレクトリの内容を読み取る（同期処理）
続いて***2.***の内容について

`readdir`はディレクトリを読み込み、中身のファイルを配列で返します。
そして`Sync`は処理を同期的に実行するという意味です。


~~~javascript
  const fileNames = fs.readdirSync(postsDirectory) // ...2
~~~


`fs.readdirSync(引数1[オプション],引数2)`について

`引数1`には読み込みたいファイルのパスを文字列で記述します。
また、オプションで文字コードやファイル情報の取得要否を設定できます。

`引数2`にはファイルが存在しない場合の処理を記述できます。（省略可能）

[fs.readdirSync( )について＜Node.js公式ドキュメント＞](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback)


今回は`引数1`のみで、前述した`path.join`で辿ったところにあるディレクトリ`postDirectory`を渡しています。
`postDirectory`内のファイルのファイル名を、配列として`fileNames`に渡しています。

# おまけ
最後にmap処理をしているのでそれも見ていきましょう。
本筋ではない＆チュートリアルのコードは結構長文なので、ここではサラッと触れるだけにします。

~~~javascript
const allPostsData = fileNames.map(fileName => {
    
//... 中略

  })
~~~
先ほどの`readdirSync( )`で取得した`postDirectory`ディレクトリの中にあるファイル名の配列(`fileNames`)から、各要素に対して一つずつ順番に`{ }`内の処理を実行したのち、`allPostsData`という新たな配列を生成しています。

ふう...
ようやくこれでNext.jsのチュートリアルに戻れます。

# さいごに
`path`と`fs`についてはまだまだたくさんのメソッドが用意されています。
また、同期処理か非同期処理かについて今回は割愛しましたが、とても奥深いですので気になった方は調べてみてください。

[侍エンジニア【JavaScript入門】誰でも分かるPromiseの使い方とサンプル例まとめ！](https://www.sejuku.net/blog/52314)
【AtCoder】ABC203をPython3で解説

ABC203の解説。

https://atcoder.jp/contests/abc203

## A - Chinchirorin
### 解説
3つのサイコロを振って、a,b,cで2つが同じ目ならもう一つの目を、同じものがないときは0を出力する問題。

これは単純に2つが同じ目が出るとき、`a==b`、`b==c`、`c==a`の場合で、もう1つの目を出力、この条件に引っかからなければ、`0`を出力すれば良い。

### コード

```python
a, b, c = map(int, input().split())

if a == b:
    print(c)
elif b == c:
    print(a)
elif c == a:
    print(b)
else:
    print(0)
```

## B - AtCoder Condominium
### 解説
N階建て、K号室まで持つマンションの総部屋番号の合計を出すもの。

i階のj号室の部屋番号は`i0j`、つまり、`i * 100 + j`と表せる。これらをループで表現し、`total`に加えていくだけ。

### コード

```python
N, K = map(int, input().split())
total = 0

for i in range(1, N+1):
    for j in range(1, K+1):
        total += i * 100 + j

print(total)
```

## C - Friends and Travel costs
### 解説

この問題を要約すると、最終的な所持金により太郎君がたどりつける村が決まるということ。

わかりにくい方は、日本全国を車で移動しているということを考えてほしい。
このとき村→距離、所持金→ガソリン、友達→ガソリンスタンドと考えてほしい。
最初、車には`K`Lのガソリンが入っている。車を走らせ、`A`だけ進んだところにガソリンスタンドがあれば、`B`L補充する。そしてガソリンが切れるまで走り続けると、イメージしてもらえばわかりやすいかと思う。

解き方だが、制約を見てもらうと分かる通り、単純にforループを回しただけでは、TLEしてしまう。

そこで所持金と村番号だけに注目する。
コードに沿って説明していく。

まず、`l`に`A`と`B`の入力値をいれる。そして、これら入力値を昇順にソートする。これで村番号が早い順に並び替えることができる。

元々の所持金`mny`を、現在の所持金`now_mny`に代入する。
これを友達`frd`の数だけループを回していく。

回していく段階で、村$A_i$が所持金よりも大きい場合は、到達できないので、その段階で`break`する。対して、村$A_i$が所持金よりも小さい場合は、友達からお金$B_i$もらえるので、これを所持金`now_mny`に足す。

結果、最終的な所持金`now_mny`が進んだ村番号と対応しているので、これを出力すればよい。

### コード

```python
frd, mny = map(int, input().split())
l = []

for _ in range(frd):
    A, B = map(int, input().split())
    l.append((A, B))

l.sort()
now_mny = mny

for i in range(frd):
    A, B = l[i]
    if now_mny >= A:
        now_mny += B
    else:
        break

print(now_mny)

```
DSレコードとは

## 勉強前イメージ

DNSSECに関係ある感じ？

## 調査

### DSレコードとは

Delegation Signerの略で、ゾーンの管理者は、親のゾーンに設定される子のゾーンのDNSKEYリソースレコードを参照するためのリソースレコードになります。
「親のゾーンのDSレコードの内容」と「子ゾーンのDNSKEYリソースレコードの情報」 が一致し、
また同様のことが行われることでDNSSECが信頼の連鎖が行われます。

### そもそもDNSSECとは

DNSの情報に電子署名を付けることで、
DNSのデータが正しい発行元のデータであることを検証することができるようにする拡張仕様になります。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/0f26423cf54d7bd20c07) をご確認ください。

### 信頼の連鎖とは？

そもそもDNSSECは信頼の連鎖と呼ばれる仕組みで担保できる仕組みになっています。

あるゾーン(子)の管理者は、親のゾーンの管理者に公開鍵のハッシュ値(DS)を送信し、
親ゾーンの管理者は、子のゾーンから送られてきた公開鍵のハッシュ値(DS)が正しいことを確認してから、親ゾーンの秘密鍵で署名を行い公開します。
その親ゾーンも同様に、さらにその親のゾーンにDSを登録することで `信頼の連鎖` が行われます。

### 他にもリソースレコードが存在する

DNSSECの仕組みを使用するためのリソースレコードがあります。

- DNSKEY
	- DNSSEC検証に使用する公開鍵を格納するためのリソースレコード
	- 1つの鍵に1つのDNSKEレコードがある
- RRSIG
	- Resource Record digital SIGnature の略で、電子署名が格納されるリソースレコード
- DS
	- 今回調査していたリソースレコード
	- Delegation Signerの略で親のゾーンに設定される子のゾーンのDNSKEYリソースレコードを参照するためのリソースレコード
- NSEC
	- 存在していないゾーンについて問い合わせがあった時、ゾーンを管理する権威ネームサーバが不存在との旨の回答に署名するためのリソースレコード
- NSEC3
	- NSECのようにゾーン名を記載せずに、ゾーン名がわからないようにハッシュ値でゾーンを示します

## 勉強後イメージ

DSレコードだけじゃなくて、他にもDNSSECを使用するためのレコードはいくつか存在するのね
特にNSECはややこしや

## 参考

- [DSリソースレコード（ディーエスリソースレコード）](https://jprs.jp/glossary/index.php?ID=0213#:~:text=%E8%A7%A3%E8%AA%AC-,DS%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%EF%BC%88%E3%83%87%E3%82%A3%E3%83%BC%E3%82%A8%E3%82%B9%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%EF%BC%89,%E9%80%A3%E9%8E%96%E3%81%8C%E6%A7%8B%E7%AF%89%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)
- [DNSSEC](https://www.nic.ad.jp/ja/newsletter/No43/0800.html)
Oracle Analytics Cloudことはじめ：データの追加

皆さんこんにちは。
Oracle Analytics CloudのセルフサービスBIの機能を利用する際に、最初は誰かに作成してもらった分析を利用していたけれど、その後データを追加したいというニーズがあった場合の手順をお知らせします。

データ・ソースから追加されたデータを管理するための一般的なワークフローは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/f8ad84da-15cb-f888-2466-904d1b17c539.png)
Oracle Analytics Cloudことはじめ：セルフサービスBIの「説明」機能

皆さんこんにちは。
今回はセルフサービスBIの「説明」機能についてご紹介します。

この機能を利用することにより、データがどのような構成になっているのか、どのような分析をするのが良いかOracle Analytics Cloudからのアドバイスを受けることができます。

この機能ではOracleの機械学習を使用して、データに関する正確で迅速かつ強力な情報を生成します。データ・セットの列を選択して「説明」オプションを選択します。 Explainでは、機械学習の統計分析が自動的に適用され、データ内で最も重要なパターン、相関(ドライバ)、分類および異常が検出されます。 その後、Explainによって、検出されたインサイトを表示するビジュアライゼーションが返されます。 ユーザーは、ビジュアライゼーションを選択してプロジェクト・エディタを開き、ビジュアライゼーションをカスタマイズしてデータを詳細にドリルできます。


実際に動画をご覧ください。
とても便利な機能です。動画では英語ですが、もちろん日本語で動きます。

https://youtu.be/wWaJYnBUT7s
stringクラスのFormatメソッド

（作業用の忘備録なので、不親切な書き方になっていても怒らないでね）

stringクラスのFormatメソッドの第１引数に文字列を指定するが、その際「{}」波括弧を使い以下のような記述を行うことで、「{}」波括弧で囲まれた数字に応じて、第２引数以降で設定した文字列を、指定した位置に表示することができる。

```C#:C#
string str = string.Format("今日の日付は{0}です。今日は{1}です。", "1月1日", "元旦"）;
```
この方法で記述すると、この文字列を表示する時、{0}のところに、続く第２引数で設定した1月1日という文字列が代入され、同じく{1}のところには第３引数で設定した元旦という文字列が代入され、最終的には「今日の日付は1月1日です。今日は元旦です。」という文字列がstring型の変数strに代入される。
phpMyAdminのSQL文が小さすぎて読めなぁぁぁぁい!!

## 問題
`phpMyAdmin`のSQL文を入力する欄のフォントサイズが**小さすぎて読めなぁぁぁぁい!!**
(自分の作業環境がモニターから1m近く離れていることが最大の原因なんですけどね)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/35555684-938d-2b08-4534-42c1210393cb.png)



## 原因の特定
`Chrome`の検証ツールでSQL文の入力欄を見てみる。
`<textarea>`で構成されている入力欄の直下に**`CodeMirror`**クラスがあったので、そこを触ってみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/fbe9bb51-846f-2b0d-6669-9292920345ed.png)


**`CodeMirror`**クラスが何処のファイルに記述されているのか、`~\xampp\phpMyAdmin\`を検索してみると、`~\xampp\phpMyAdmin\pmahomme\css\codemirror.css.php`にあった。


## 解決策
**`codemirror.css.php`**を開いて、`CodeMirror`クラスの箇所に好きなフォントサイズを追記する。

```codemirror.css.php
.CodeMirror {
    height: <?php echo ceil($GLOBALS['cfg']['TextareaRows'] * 1.2); ?>em;
    direction: ltr;
    font-size: 18px;

}
```

自分が設定した18pxだと、このぐらいの大きさになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/5d762dcd-1be4-cc34-bdf8-5cb1002f26c5.png)


**これならハズ●ルーペがなくても安心!!**

## 参考記事
[phpMyAdminのSQLクエリの文字サイズ変更 | 古松](http://old-pine.net/css/phpMyAdmin%E3%81%AESQL%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B5%E3%82%A4%E3%82%BA%E5%A4%89%E6%9B%B4)
mimemagicのバージョンがエラー時のメモ



`bundle install` をしたときに `mimemagic` に関するエラーが出てきた。

```
$ bundle install
Your bundle is locked to mimemagic (0.3.5), but that version could not be found in any of the sources listed in your Gemfile. If you haven't changed sources, that means the author of mimemagic (0.3.5) has
removed it. You'll need to update your bundle to a version other than mimemagic (0.3.5) that hasn't been removed in order to install.
```

少し調べててみると `0.3.6` 以下のバージョンが消されているようだった。　

```
0.4.3 - March 26, 2021 (11.5KB)
0.4.2 - March 25, 2021 (11KB)
0.4.1 - March 25, 2021 (11KB)
0.4.0 - March 24, 2021 (42.5KB) yanked
0.3.10 - March 26, 2021 (12KB)
0.3.9 - March 25, 2021 (11KB)
0.3.8 - March 25, 2021 (11KB)
0.3.7 - March 25, 2021 (11KB)
0.3.6 - March 24, 2021 (407KB) yanked
0.3.5 - May 04, 2020 (401KB) yanked
0.3.4 - January 28, 2020 (401KB) yanked
0.3.3 - December 20, 2018 (394KB) yanked
0.3.2 - August 02, 2016 (358KB) yanked
0.3.1 - January 04, 2016 (345KB) yanked
0.3.0 - March 25, 2015 (347KB) yanked
```

そこで対象のGemfileをupdate

```
$ bundle update mimemagic
```

無事に`bundle install` できました。
Oracle Analyticsことはじめ：Youtubeの面白い動画

皆さんこんにちは。
Oracle Analytics Cloudを知るために面白い動画があるのをご存知ですか？

マニュアルを読むのもいいですがたまには動画を見て楽しくOracle Analytics Cloudを知ってみましょう。

https://www.youtube.com/watch?v=KcJL47E0Kac

https://www.youtube.com/watch?v=Fw49TDtgdLw

分析を作成するための全体の流れはこちら
https://www.youtube.com/watch?v=bA0trkKDSZc

データの結合についての詳細はこちら
https://www.youtube.com/watch?v=HKVNupPd2pY

他にもたくさんの動画があります。
この記事に追加していきますのでお楽しみに！
はじめてC++で画面を作ろう! (5) getSaveFileName編

#15.「名前を付けて保存」を作ろう!!  
手順は、前回の「ファイルを開く」編とさほど変わりがない。

__[1] actionOpenに処理を書く__ 
アクションエディタ画面より、「actionOpen」をクリック、続けてマウスの右ボタンをクリックすると、ポップアップ メニューが表示されるので、「スロットへ移動」をクリックします。

QAction trggered()をタプルクリックすると、自動的にC++のエディタに移動します。

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
   ...中略...

void MainWindow::on_actionSaveAs_triggered()
{
    
}
```  
on_actionSaveAs_triggered()関数にカーソルが移動しています。

__[2] QFileDialogをインクルードを確認__
前回の「ファイルを開く」編で、既にQFileDialogをインクルード済なので、ここでは確認のみです。

__[3] ファイル名の変数を用意__
次にファイル名を入れる変数を用意します。
Qt5の文字列型の変数 (変数名:fileName) 

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
   ...中略...

void MainWindow::on_actionSaveAs_triggered()
{
    QString fileName; /* これを追加 */
}
```  
__[4] 「名前を付けて保存」画面を呼び出す__
次に用意した変数に「名前を付けて保存」画面の戻り値を入れます。 

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
   ...中略...

void MainWindow::on_actionSaveAs_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), "", tr("Text File(*.txt)"));
}
```  

__[5] ステータスバーに表示する__ 
前回と同様 せっかく、戻り値で、ファイル名を取得したので、とりあえずステータスバーに表示しましょう!!

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
   ...中略...

void MainWindow::on_actionSaveAs_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), "", tr("Text File(*.txt)"));
    ui->statusbar->showMessage(fileName); /* これを追加 */
}
```  
#16.動作確認!! 
画面の左下にある、右三角マークの「実行」ボタンをクリックすると、何やら右下側にビルドしている状況が表示され、「MainWindow」が出てくる!

作ったアプリのメニューで、[File | SaveAs]で、「名前を付けて保存」画面が動く事をを確認しましょう!!

「名前を付けて保存」画面で、「キャンセル」ボタンをクリックすると、fileName = ""となる。

既にあるファイルをファイル名に指定した時は、自動的に__「○○は既に存在します。上書きしますか?」__と聞いてくる。

拡張子を省略しても、選択しているフィルターで、自動で拡張子が付く。

#17.getSaveFileName関数の引数の説明
[1] __this__ :ここは、親オブジェクトの設定
[2] __tr("SaveAs")__ :ここは、「名前を付けて保存」のタイトル
[3] __""__ :ここは、画面を呼び出した時のファイルパス
「マイ ドキュメント」などを設定できる。
[4] __tr("Text File( *.txt )")__ :ここは、拡張子のフィルター
フィルターは、セミコロン(;)を二つで区切りする

フィルターは、拡張子を自動的に付けるため、「ファイルを開く」の時のような、複数径は、使わないようにしましょう。

悪い例：__Text File(*.txt *.xml *.json)__ 
良い例：__Text File(*.txt);;XML File(*.xml);;JSON File(*.json)__

今回は、ここまで次回は、「ファイル情報をチェックする」を作ろう!!です。
Rubyアルゴリズム（Find the Highest Altitude）

## 問題

There is a biker going on a road trip. The road trip consists of n + 1 points at different altitudes. The biker starts his trip on point 0 with altitude equal 0.

You are given an integer array gain of length n where gain[i] is the net gain in altitude between points i​​​​​​ and i + 1 for all (0 <= i < n). Return the highest altitude of a point.

 
```
Example 1:

Input: gain = [-5,1,5,0,-7]
Output: 1
Explanation: The altitudes are [0,-5,-4,1,1,-6]. The highest is 1.
```

```
Example 2:

Input: gain = [-4,-3,-2,-1,4,3,2]
Output: 0
Explanation: The altitudes are [0,-4,-7,-9,-10,-6,-3,-1]. The highest is 0.
``` 

Constraints:

n == gain.length
1 <= n <= 100
-100 <= gain[i] <= 100


## 私の回答

```ruby
def largest_altitude(gain)
    alt = 0
    hi = [0]
    gain.each do |g|
        hi << alt += g
    end
    hi.max
end
```

**無事Acceptedです。**

解くことよりも、よりシンプルに書くことの方が難しいです。もっとシンプルに書ける気しかしない。
今回も考え方を書いていきます。

```ruby
alt = 0
hi = [0]
```
初期値を入れておきます。
altitudeはスタート地点の高度0、highestには移動していった中で一番高度の高かったポイントを入れます。
配列に0を入れているのは、高度マイナスの場所しか通過しなかった場合、スタート地点が最も高度が高いからです。
配列に入れて最終的に

```ruby
hi.max
```
で一番大きい数値を取り出しています。

```ruby
gain.each do |g|
    hi << alt += g
end
```

その為にhighestに通過した高度をどんどん入れていきます。

以上です。だいたい同じこと解き方ばかりするようになってきてしまった。
次は新しいメソッドを使う問題を解きたいです。



## もっと簡単に書けた！

```ruby
def largest_altitude(gain)
    alt = 0
    gain.unshift(0).map{ alt += _1 }.max
end
```

これでAcceptedです。すごく短くなりました！
というのも、コメントで

```ruby
alt = 0
gain.map{ alt += _1 }
```
で再起的な処理を書けるのでは？と教えていただきました。なるほど〜！

_1は|g|のように明示的なブロック変数を記述する代わりに、連番となる仮引数（受け取り側）として記述するものです。
ちなみにeachの返り値は元の配列、mapの返り値は処理後の**配列**になるようです。
返り値が配列なので、そもそも初期値を入れた配列の準備も不要になります。

```ruby
alt = 0
gain.map{ alt += _1 }.max
```
なので直接gainから最大値を取得できるようになりました。かなりスッキリ！
ただこれだと、マイナスの数値しか配列に入らなかった場合に、初期値の0を返したい場合にうまくいかないので、もう最初からgainの頭に0を入れ込んでしまいます。

```ruby
gain.unshift(0)
```
これで配列gainの先頭に0が入ります。あとは順番に足していくだけ。
終了です。

最近実務でもmapが使われているのをよく見るので、理解の為に自分でも積極的に使っていくようにしたいと思います。
どうしても明示的にブロック変数を記述してのeach文に（わかりやすいので）逃げがちですが、それではいつまでも進歩がないので。。
rails テーブルのカラム確認、名前の変更方法


<h2>経緯</h2>
unknown attribute "カラム名" for User.　〜〜〜
といった感じのエラーが発生。

色々と調べてみるとUserテーブルに記述したはずのカラム名のスペルミスのせいで発生してしまったエラー。

備忘録として、書きます。

<h2>解決方法、やったこと</h2>
①現状のカラム名の確認
②カラム名の変更

<h3>カラム名の確認</h3>

<pre>rails console</pre>
rails console で確認することができるようなので上記コマンドを入力。

確認するコマンド？は記述の仕方次第で何通りかあるようで、


<pre>テーブル名.columns</pre>
この記述の仕方だとカラム名だけでなく他の情報も表示されてしまう、知りたい情報だけ抜き取るのは面倒

<pre>テーブル名.column_names</pre>
このようにコマンドを入力するとカラム名だけ取得することができるのでカラム名がどうなっているか確認。

確認したら
<pre>exit</pre>
でrails console を終了

<h3>カラム名の変更</h3>

<pre>rails generate migration rename_【変更前のカラム名】_column_to_【モデル名（複数形）】</pre>

上記コマンドを入力後、タイムスタンプ付きのmigrationファイルが作成されるので、作成されたファイルを編集。


<pre>
def change
    rename_column :users, :変更前のカラム名, :変更後のカラム名
end
</pre>


migrationファイルを保存した後にrails db:migrate で反映させて終了


<h2>参考サイト<h2>
https://qiita.com/kumasato1992/items/786643d41c6cdc9cb8a6
https://qiita.com/littlekbt/items/48fa2b428147921db5a5
https://qiita.com/littlekbt/items/48fa2b428147921db5a5
[JS]スプレット構文について

## はじめに
Javascriptでスプレット構文を使ったので勉強用として残しておきます。

##使い方
[公式ドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)ではスプレット構文について以下のように書かれています。

`スプレッド構文 (...) を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数 (関数呼び出しの場合) や要素 (配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0 個以上のキーと値のペア (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。`

言葉だけだとちょっとわかりにくいですね。
例文を見てみましょう。

```
const argumentArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'];

console.log(argumentArray);
// ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']

※スプレット構文の場合
console.log(...argumentArray);
// a b c d e f g h i j k l m n
```

以上のように配列になっている変数に`...`を変数名の前に付け加えると14個の配列が展開されることがわかります。
また、以下のように関数に対してもスプレット構文は使えます。

```
function getData() {
     const argumentArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'];
     return argumentArray
}

console.log(...getData())
// ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"]

※スプレット構文の場合
console.log(getData())
// a b c d e f g h i j k l m n
```

## 参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
Next.js × Nest.js & Prisma2 で個人開発したら最高だった 

# 作ったサービス

 [BUZZ STOCK .COM](https://buzz-stock.com/ "BUZZ STOCK .COM")
![スクリーンショット 2021-05-31 20.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235657/80e480b3-268e-3843-cf49-560e956633bb.png)

株式情報の確認や、コメントの投稿ができるサイトを作りました！
機能はまだこれからも追加予定ですが、ひとまず、フォロー・いいね・タグなどの基本的なSNS機能とチャートや財務情報の確認機能を備えています！(株式データのAPIには[Yahoo Finance](https://rapidapi.com/developer/dashboard)のAPIを使用)
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235657/a6fdca19-e515-4e57-a830-ab75797698d0.png' width='300px'>
スマホも対応しています。

# 技術構成

フロントエンド　[Next.js](https://buzz-stock.com/ "BUZZ STOCK .COM")（CSSはビルトインのCSS Modulesを利用 Vercelにデプロイ)
バックエンド [Nest.js](https://nestjs.com/)(ORMに[PRISMA2](https://www.prisma.io/)を使用　DBはPostgresql AWSにデプロイ)

# Next.jsについて
Routing周りの設定や、ディレクトリー構成、CSS Modulesのサポートなど、Reactでプロジェクトをスタートする最初のしんどいスタートがこれで解決して最高でした。ReactやNext.jsというと基本的にはWebアプリケーションのフロントエンドの構築に使われることが多いと思いますが、Next.jsは静的サイトの出力もサポートしているので、これまでGulpなどのタスクランナーで構築されていたホームページ制作のスターターテンプレートの代替としても十分採用できるものだと思いました。CSS Modulesでコンポーネント毎にスコープを切ってCSSを書くことができるので、これまでBEMなどを使用してクラス名が長くなりすぎて悩んだりしていましたが（俗に言うエレメント地獄）、それらに煩わされることももうありません（しかしBEMの基本的な考え方は依然として有用だと思っています）！
そして、Next.jsで最も強力だと思ったのが、Vercelとの組み合わせで稼働することができるISR(Incremental Static Regeneration)です。
この機能によって、SSRなどで処理すると際限なく大きくなってしまうAPIへのデータのリクエスト回数を減らしつつ、ハイパフォーマンスにページを配信することができたりしました。ISRは革命といってもいいのではないでしょうか。コンテンツの追加のたびにアプリケーションのBuildを丸ごとしなければならなかったこれまでのSSGの問題も解決しているため、これまでCMSの王座を守り続けてきたWordPressなどの牙城を遂に崩すことができるんじゃないかというポテンシャルも感じます。


# Nest.js＋Prisma2

最初、バックエンドはRailsのAPIモードで開発していたのですが、フロントエンドでJSを書いてからRubyに頭を切り替えるコンテキストスイッチが煩わしく、そしてAPIモードとはいえRailsはAPIサーバーを建てるだけの用途に使うには『しっくりこない感』が強くありました。
そして、TypeScript製のNode.jsフレームワークとして近年話題になってきていたNest.jsを採用したのですが、これが大当たりでした！
最初こそ、見慣れないTypeScriptのデコレーターや、Module,Contoroller,Service　と責務を切り分けて機能を実装するデザインパターン？に親しむのに時間を要しましたが、レールに乗ると、最高の生産性と『しっくり感』を得ることができました。
VSCODEのTypeScriptの静的型チェックのおかげでデバッグの手間が体感で半分以上減ったり、依存関係のあるモジュールを自動でインポートしてくれたりで、感動の開発体験でした。
ORMとしてはPrisma2を採用したのですが、こちらも大当たりでした。
自分はバックエンドの知見がWordPressとRailsが少しできるくらいしかなかったので、多対多のリレーションなどのDB操作をRailsなしでやることに不安を感じていたのですが、結果からいうと、Prisma2によってリレーションを定義したり欲しいデータを取ってくるのはRailsよりももっと簡単になりました。
こちらについては、公式ドキュメントとそれに付随するexampleが非常に充実していますので、興味のある方はぜひ、チェックなさってください。
フォロー・フォロワーやカテゴリー・タグ　などのよくある実装がほとんどexampleに入っています。
ペインポイントになりがちなJWTの認証の実装も、@nestjs/jwt @nestjs/passport passport passport-jwt　などのパッケージを利用することでサクっと実装できましたし、今回はREST APIでつくりましたが、将来的にGraphQLでAPIを構築したくなったときなども、Nest.jsはサポートが充実していそうです。そしてAWSにデプロイするときもNestのサーバーはNode.jsさえインストールすれば動きますので、NginxやPumaなどの設定をしなければならないRailsに比べてはるかに簡単だと思いました。
とにかく、RailsからNest.js＋Prismaの構成に切り替えることで、言語の切り替えによるストレスがなくなり、そしてRailよりもさらに簡単に無駄なく開発ができるようになったので、『正しいレールに乗っている感』が強くありました。

# インフラ構成

インフラ構成につきましては、下記の構成図にて省略させていただきます。
[AWSではじめるインフラ構築入門 安全で堅牢な本番環境のつくり方](https://user-images.githubusercontent.com/24717695/119268484-347c2200-bc2e-11eb-93bf-741c8f756f01.jpg)
という本に非常に助けられました。ありがとうございました。
<img src='https://user-images.githubusercontent.com/24717695/119268484-347c2200-bc2e-11eb-93bf-741c8f756f01.jpg'>
Oculus Quest 2でいちゃいちゃしてみよう！Part3

# 目次

[1. BlenderでVroidのモデルを編集しよう](https://qiita.com/KayaTakashiro/items/65838261b896117915dd)
[2. Oculus Quest 2の準備をしよう](https://qiita.com/KayaTakashiro/items/15c58867c84e24a96dd3)
[3. UnityにVRMモデルを入れてみよう](https://qiita.com/KayaTakashiro/items/ccd532fe20fdc80be0f8)
[4. VeryAnimationで遊んでみよう](https://qiita.com/KayaTakashiro/items/307c91c8a40df4eff115)
[5. DynamicBoneでいろいろ遊んでみよう](https://qiita.com/KayaTakashiro/items/f39dc45a686aca6f3d12)
[6. UnityのAnimationでいちゃいちゃしよう](https://qiita.com/KayaTakashiro/items/f25e950c268d9a239576)

## デモとパッケージ

https://youtu.be/-Ao8o2OWVVU

https://youtu.be/a25QZY0NA9I

https://github.com/blackpopo/MakingOutWith2DGirls

##3.UnityにVRMモデルを入れてみよう

###VRMモデルのImport手順

まず、UnityにAssets > Import Package > Custom Packageから、[UniVRM](https://github.com/vrm-c/UniVRM/releases)をimportします。

つぎに、AssetsのなかにVRM用のFolderを作成してVRMモデルをDrag&Dropします。

VRMモデルのImportが完了したら、モデルのPrefab AssetをHierachyにDrag&Dropします。

### VRMモデルの設定
まず、Projectのところで右クリックして、適当にAnimationControllerの作成

VRMモデルのInspectorにあるAnimatorにとりあえず、先ほど作成したAnimationControllerを入れます。

次に VRM Look At Headの編集をします。

Targetに**CenterEyeAnchor**, Headに**J_Bip_C_Head**を入れます。

そして、VRM Look At Bone Applyerの編集に移ります。

画像のようにパラメータを設定してください。

![スクリーンショット 2021-05-29 212551.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/59e22f40-c428-d65b-a64f-67e8295bfac5.png)

次にこちらの[Blend Shape Blink](https://udasankoubou.blogspot.com/2017/07/unityblendshapeblink.html)をお借りして、瞬きするように設定します。

モデルのInspectorからBlende Shape BlinkをAdd Componentします。基本はデフォルトのままで大丈夫です。

Blink Shapesについて以下の写真のように設定してください。

![スクリーンショット 2021-05-30 154032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/580fd20f-3218-c847-5dc6-74201d855371.png)

最後に[Oculus Quest 2の準備をしよう](https://qiita.com/KayaTakashiro/items/15c58867c84e24a96dd3)のOVRCameraRigにアタッチされているCameraPositionのTarget Objectについて、写真のようにモデルのオブジェクトを設定してください。

![スクリーンショット 2021-05-31 191730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/f62e03ce-d0ef-7b9a-3859-806a525d02bf.png)

[使用したVRMモデルとScriptについてのGit repository](https://github.com/blackpopo/MakingOutWith2DGirls)

[次回に続きます。](https://qiita.com/KayaTakashiro/items/307c91c8a40df4eff115)
Oracle Analytics Cloudことはじめ：Oracle Analytics Cloudの学習方法

皆さんこんにちは。
Oracle Analytics Cloudを使ってみたいけど、どうやればいいのかわからないという方はいませんか？
以下の方法で動画を見ながら簡単に使い始めてみませんか？

ご参考URL：
https://apexapps.oracle.com/pls/apex/f?p=44785:50:3947099954604:::50:P50_COURSE_ID,P50_EVENT_ID:236,5907

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/9c4128f9-c44f-f135-5145-f8585e81cd38.png)
Oracle Analytics Cloudことはじめ：視覚化の追加ライブラリ

皆さんこんにちは。
Oracle Analytics Cloudでは視覚化の追加のためのライブラリがあるのをご存知ですか？
以下はコンテンツをダウンロードするためのURLです。
https://www.oracle.com/se/business-analytics/data-visualization/extensions.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/e4fe5b89-5524-8cc2-44c9-16fbf04a4231.png)

設定直後から使えるグラフとは別に追加でのグラフやサンプルを見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/d9b4f5bd-cc1a-7d5e-d666-9d262404851a.png)

これらによって、表現力はより豊かになります。
ぜひ既存の機能に追加をしてみて下さい。
curlコマンドでJSONデータをAPIにPOSTする

APIの動作確認をしたいときに使えます。

今回はAPIのURIを```localhost:5000/api/v1/```とします。また、v1の後の文字列でリクエスト先を定義します。(例: ユーザ登録... localhost:5000/api/v1/users)

### コマンドでリクエストを投げる

```sh
curl -X POST -H "Content-Type: application/json" -d "{"name" : "佐藤" , "mail" : "sato@example.com"}" localhost:5000/api/v1/users
```

- -X POST : POSTでリクエストを投げるときに使います。

- -H : リクエストヘッダを指定する時に使います。 今回はリクエストボディとしてjsonデータを送信したいので、```Content-Type: application/json``` を指定しています。
- -d : リクエストボディを指定します。

引数でリクエスト先のエンドポイントを指定することも忘れないように注意です。

### シェルスクリプトで効率化

軽く動作確認するだけならコマンド入力で問題ありませんが、別のエンドポイントにアクセスする・正常系異常系のテストをするとなれば毎回同じコマンドを入力するのは面倒です。

シェルスクリプトでAPI実行を効率化してみましょう。
今回は
・ エンドポイント
・ リクエストで投げるJSON

を引数で受け取るようにしました。また、今回は/usr/local下にスクリプトを配置することにします。

```sh:postRequest.sh
#/bin/bash

# APIにPOSTリクエストする

### 引数一覧
# $1 : エンドポイント
# $2 : リクエストボディ(JSON)

### 変数定義

# エンドポイント
ENDPOINT="localhost:5000/api/v1/${1}"

# リクエストボディ(JSON形式で受け取る)
JSON="${2}"

# リクエストを出す
curl -X POST -H "Content-Type: application/json" -d "${JSON}" "${ENDPOINT}"
```

### 実行例

```sh
/bin/bash /usr/local/postRequest.sh users "{"name" : "佐藤" , "mail" : "sato@example.com"}"
```
コマンドを全て入力するよりも少ない手間でAPIを実行することができました。

### 余談
今回はスクリプトのパスを通していないのでフルパスで実行していますが、パスを通しておくと更に少ない手間でAPIにアクセスできるでしょう。

また、どのようなJSONデータを使うのか予め決まっている場合はデータをjsonファイルに定義しておき、引数でファイルパスを渡すという方法も良いかもしれません。
【Docker】Dockerに関する概念的な理解を整理してみた

#はじめに
この記事はDocker初学者を対象としています。
特に（私のような）Linuxやサーバ構築の経験が皆無の方です。

今回はDockerについて概念的な理解を備忘録も兼ねて整理していきたいと思います。

#Dockerとは
DockerはDocker社が開発した「オープンソースのコンテナ管理ソフトウェア」です。

昨今では本番環境やフロントエンジニアの開発環境にも多く取り入れられるようになりました。

次に「コンテナ」とは何かを見ていきます。

#コンテナとは
WebサーバやDBサーバなどが動く仮想環境のことを指しています。
PCやサーバ上の環境を分けたもので、そこにはデータやプログラムが入っています。

このコンテナを使うことができる仕組みがDockerであり、
コンテナの理解に従ってDockerというものを捉え直すと
Dockerとは、
「複数のデータやプログラムを、それぞれ独立した環境に隔離できる仕組み」と換言できます。

#コンテナの作成方法
コンテナはDocker Engineの操作の中でイメージによって作成されます。

Dockerではコンポーネント単位で複数の機能が開発されており、
その中でもDocker Engineはイメージ作成やコンテナ起動などを行うコアコンポーネントです。

イメージには多くの種類があり、ソフトウェアによって、それぞれ用意されたイメージを使います。

またコンテナは複数作成することができます。
容量が許す限り、Dockerの上にいくつもコンテナを用意することが可能です。

#データやプログラムを隔離する理由
前述で「Dockerとはデータやプログラムをそれぞれ独立した環境に隔離できる仕組み」と表現しましたが、そもそもなぜデータやプログラムを隔離する必要があるのでしょうか。

結論から申し上げますと
その理由は「システムの共有部分に関わるトラブルを回避するため」です。

具体的に見ていきます。

そもそもの前提として多くのプログラムは他のプログラムと連携して動き、
ソフトウェアは複数のプログラムで構成されています。

例えばPythonで書かれたプログラムはライブラリを使用することが殆どです。

このように複数のプログラムが関係している場合に起こり得るのが
前述した「共有部分に関わるトラブル」です。

以下に例を示します。

システムAとシステムBがあり、
それらがPostgreSQLのようなプログラムを共有していたとします。
そこで、それぞれのシステムにとって適したPostgreSQLのバージョンが異なってしまうとき
一方にバージョンを合わせるともう一方は動かなくなる、なんてことが起きます。

これが「共有部分に関わるトラブル」です。

そして、このトラブルを解消するのが本記事の主役の「Docker」です。

何度も書きますがDockerはデータやプログラムをそれぞれ独立した環境に隔離できます。

それ故に先ほどの例であればDockerでは
「システムAにとって最適なバージョンのPostgreSQL」、
「システムBにとって最適なバージョンのPostgreSQL」を用意してあげることができるのです。

#おわりに
次の記事では実際にDockerを動かし、その操作方法について書いていきたいと思います。

#参考
[仕組みと使い方がわかる Docker＆Kubernetesのきほんのきほん](https://www.amazon.co.jp/仕組みと使い方がわかる-Docker＆Kubernetesのきほんのきほん-Compass-Booksシリーズ-小笠原-ebook/dp/B08T961HKP)
コンテナ内へファイル転送 (docker-compose)

## 概要
docker-composeのvolume機能で、ホストファイルをdocker内に共有可能です。
しかし、ディスクI/Oの問題で、パフォーマンスが落ちる。

そのため、相互書き込みが必要なければ、転送した方が良さそう。
そこで、調べたことをメモしておく。

## dockerでのコピー
下記コマンドでコピーできるが、コンテナ名を調べたりする必要があり、ちょっと面倒と思う。

```bash
$ docker cp {ホスト側ファイルパス} {コンテナ名}:{docker内のパス}
```

## docker-composeでのコンテナ内へコピー（転送）
`docker-compose cp`みたいにできたら便利なのだけど、そのようなコマンドなさそう。
そこで、参考サイトに記載のサイトで見つけた方法で転送することにする。

```bash
# hoge.txtをコンテナへ転送する
$ docker cp ./hoge.txt $(docker-compose ps -q php):/var/www/
```

## docker-composeでのコンテナ内からコピー（取得）
逆にコンテナ内からファイルを取得する場合は、下記となる。

```bash
# コンテナからhoge.txtを取得する
$ docker cp $(docker-compose ps -q php):/var/www/hoge.txt ./
```

## docker-composeでのコンテナ名を取得する
`$(docker-compose ps -q php)`だとコンテナIDになる。
コンテナ名を取得したい場合は、こんな感じになりそうです。

```bash
$ CONTAINER=$(docker inspect -f '{{.Name}}' $(docker-compose ps -q php) | cut -c2-)
$ echo $CONTAINER
```

コンテナ名の`php`は、`docker-compose.ymlファイル`で定義している名前となります。
※ コンテナ名を調べたりしなくて済むから少しは楽なのかな...

```yml:docker-compose.yml
version: '3'
services:
  php:                     # ← ここの名前！！
    image: php:7.3
    build:
      context: ./
      dockerfile: ./docker/php/Dockerfile
    tty: true
    ports:
      - '9000:9000'
```

## まとめ
そのうち、docker-composeコマンドに`cp`コマンドできないかな（＾＾；）

## 参考サイト
* [docker-composeで特定のコンテナの中のファイルをホスト側にコピーする](http://hirokts.hatenablog.jp/entry/2018/03/22/141228)

以上
Oracle Analytics Cloudことはじめ：セルフサービスBIの予測機能

皆様こんにちは。今回はセルフサービスBIで予測モデルを作成するための一般的なタスクと、そのモデルをデータ・セットに適用してプロジェクトで使用する方法についてご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/4a93d736-81cf-5a35-4785-7ed9ec21bc29.png)

Oracle Analyticsは、機械言語のあらゆるモデリング・ニーズに対するアルゴリズム(数値、予測、多項分類子、二項分類子、クラスタリング)を提供しています。
通常、ユーザーは、複数の予測モデルを作成し、それらを比較して、基準および要件を満たす結果を出す可能性が最も高いモデルを選択します。
以下が提供されているアルゴリズムとなります。
皆さんのビジネスに近いアルゴリズムをお試しください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/6d36f42d-6df6-327a-84b3-27b8569f876e.png)
VIDEO_MEMORY_MANAGEMENT_INTERNALの対処法

環境：Windows10 Home 64Bit
##対処法
**・GPUドライバーの更新**

**・ハードウェアアクセラレータによるGPUスケジューリングの無効化**

**・Windows標準のメモリ診断ツールの使用**

ブラウザで動画を再生していたらこのブルスク（VIDEO_MEMORY_MANAGEMENT_INTERNAL）に遭遇しました

上記の三項目を行ったら取り敢えずは落ち着きました

原因はよく分かっていませんが、ドライバー関連かなぁと思います
fluentdからslackへ通知する

## 公式リポジトリ
https://github.com/sowawa/fluent-plugin-slack

## プラグインをインストール

```bash
sudo gem install fluent-plugin-slack
```

## コンフィグ

```flentd.conf
<source>
  type forward
  port 24224
  bind 0.0.0.0
</source>

<match *.**>
  @type copy
  <store>
    @type slack
    webhook_url https://hooks.slack.com/services/TMGL7M997/B01NLKW8AFJ/4VPj28Q6H5xxxxxxxxxxxxxxxxx
    channel general
    username sowasowa
    icon_emoji :ghost:
    flush_interval 60s
  </store>
</match>
```
【SwiftUI】"" is not a valid digit in integer literalエラー

"◯" is not a valid digit in integer literal
というエラーが発生しました。

翻訳してみると
>整数リテラルの有効な数字ではありません

という意味のエラーでした。

###解決策
原因は本当に単純なもので、宣言した変数名の初めを数字にしてしまっていたからでした。
確かに、参考書にそういったルールが書かれていた気がしますがすっかり忘れていました。

もう間違えることは無いと思いますが、万が一のために備忘録として残しておきます。
システム設計ランキング

システム設計について参考させてもらった記事

#第1位
https://qiita.com/NagaokaKenichi/items/5f0c4de0030fc03eb999
#第2位
https://qiita.com/OzoraKobo/items/8e4d9225100e5f00c139
#第3位
https://qiita.com/chocode/items/fd51dd8f561e2a0fbd70
#その他
https://qiita.com/dich1/items/4d9efc731424cfbe8256
https://qiita.com/kamakuniya/items/e59b29b0b44cb608fefd
https://qiita.com/mikakane/items/b8045a11dba8d08e5fe4

わかりやすい記事をいつもありがとうございます
PHP で日付が正しいかをチェック (YYYYMMDD)

# PHP で日付が正しいかをチェック (YYYYMMDD)

```php
<?php
$date = "20210321";
validateDateFormat($date);
$date = "202103213333";
validateDateFormat($date);
$date = "20210";
validateDateFormat($date);
$date = "2010aass";
validateDateFormat($date);
$date = "20101333";
validateDateFormat($date); 
function validateDateFormat($date)
{
    // 右0埋め
    $_date = str_pad($date, 8, 0, STR_PAD_RIGHT);
    // 8桁以上の場合は切り詰め
    $_date =substr($_date, 0,8);
    print($_date)."\n";
    // checkdate の引数は int
    $year = intval(substr($_date, 0,4)); 
    var_dump($year);
    $month = intval(substr($_date,4,2));
    var_dump($month);
    $day = intval(substr($_date, 6,2)); 
    var_dump($day);
    if(checkdate($month, $day, $year) === false)
    {
        echo 'NG : 日付が正しくありません。'."\n";
    }
    else
    {
        echo 'OK！'."\n";
    }
}
```

### perl DBD:Pg

```text
https://metacpan.org/release/TURNSTEP/DBD-Pg-3.15.0/source/README
```

```text
https://base64.work/so/perl/3606027

# DBI_DSN                     dbi:Pg:db="postgres";port=5440;host=localhost/dbdpg_test_database/data/socket
# DBI_USER                    jgp
#DBI_USER=<username>
#DBI_PASS=<password>
```

```bash
cpan YAML
cpan Test::Simple
cpan DBD::Pg
```

```bash
export POSTGRES_HOME=/var/lib/pgsql/13
export PATH=$PATH:/usr/pgsql-13/bin
export DBI_DSN='dbi:Pg:db="postgres";port=5432;host=localhost'
export DBI_DSN='dbi:Pg:dbname=testdb;;port=5432;'
export DBI_USER='postgres'
export DBI_PASS='postgres'
```
使っていないEBSボリュームをcliでサクッと全部削除する

OpsWorksやらAutoscale等々、検証でEC2をぽんぽこ立てたり消していると何だかんだで溜まっていくavailableのEBS......
そういやどうだったかなと調べてみるとなんと100台以上も！！

どうせ使ってないしそもそもこれはヤバいということでawsコマンドを使用して使っていないEBS一覧を取得し、それをforで回してパワーで消していくのが本題です。

ではまずは使っていないEBS一覧の取得の前にavailableになっているEBSの数を確認してみます。

この辺のドキュメントを参考にしていきながらコマンドを考えていきます。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ebs-volume-snapshot-ec2-instance/

statusがavailableのEBSをすべて削除したいので使用コマンドは以下

```
$ aws --profile hogehoge --region ap-northeast-1 ec2 describe-volumes --filter "Name=status,Values=available" | jq -r '.Volumes[].VolumeId' | wc -l
```

これで台数が出せました。
profileとregionを環境に合わせて指定していただければコピペで出せるはず。
ホントは検証用を判別させるためにtagを付けておけばこんなことしなくて済むのですが今更仕方なし。

今度はID一覧を適当なファイルに出力します。

```
aws --profile hogehoge --region ap-northeast-1 ec2 describe-volumes --filter "Name=status,Values=available" | jq -r '.Volumes[].VolumeId' > hugahuga.txt
```

出力出来たら一応中身を見てみましょう。
そしたらパワーで削除していきます。

```
$ for x in `hugahuga.txt`; do aws --profile hogehoge --region ap-northeast-1 ec2 delete-volume --volume-id $x; done
```

以上で削除完了です。
注意点としては、当然ですがクライアントの環境で実行する際は重々気を付けて実行しましょうといったところですね。
これに限らず何かを消す際はインシデントの元だったりしますので。

ではまた。
最後まで閲覧いただきありがとうございました。
Oracle Analytics Cloudことはじめ：セルフサービスBIのタスクについて

皆さんこんにちは。
今回はセルフサービスBIで実施する一般的なタスクについてご紹介します。
これらのタスクを実行することで、分析を実行し、会議での報告業務などを簡単に行うことができるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/5ec81a9b-d553-946b-4766-ac9b8dfc5310.png)

以下はサンプルプロジェクトです。設定を行うときにインストールするかどうか選択することが可能です。
英語のデータになっていますが、当然日本語での分析が可能です。

開発画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/567aa0a5-64f2-29f9-b4f6-24cb8563eaa3.png)

報告時の画面
マイクロソフトのPowerPointのスライドショー機能のように利用することができます。
グラフの上に説明の文字などを書くこともできるため、PowerPointと同じような感覚です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/7e837971-4e57-0348-2253-295e9436e795.png)
Pythonのリストから括弧を除く

`*` 演算子を使うとリストから括弧を除くことができる。

```sample.py
list = [a, b, c]
print(list)
>> [a, b, c]
```

```sample.py
list = [a, b, c]
print(*list)
>> a b c
```

https://docs.python.org/ja/3/tutorial/controlflow.html#tut-unpacking-arguments
ブログ収益を500倍にした方法

技術ブログ (https://swiswiswift.com) 運営しています。
Google AdSense の広告の自動最適化を有効にしたら収益が500倍になりました。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63855/0f98db9d-d8a8-9984-8b60-7957671970ec.png)

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63855/e7862ab7-f18d-3357-9fbe-7361c99ab0fa.png)


✳︎　PV数は 6000-8000/月です。
✳︎　最適化後はだいたい500円/月です。最適化前は0-1円でした。
✳︎　広告が最適化されたことで全画面広告が有効になり収益が増えたのだと思います。
Oracle Analytics Cloud ことはじめ：エンタープライズ利用のための設定

今回はエンタープライズ利用にあたって、管理者用画面で設定をするリポジトリについて、以前ご紹介した、エンタープライズ利用についての内容の裏の設定の流れについてご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/d8856405-e4b7-a4a4-b8b8-ba92b69abcb1.png)

リポジトリは利用者が意識せずとも、分析を進めやすくするための仕組み作りとなります。

セルフサービスBIでは自由にドリルダウンする項目を選択することが可能です。
別の言い方をすると、どの項目にドリルダウンするか自分でデータの中身を知っていないとドリルダウンすることができません。業務あるいはデータについてご存知の方で、自由に分析したい場合にはとても便利な機能となります。
一方で、エンタープライズ利用の場合は誰でも簡単に利用するために、クリックしたら見るべき項目に簡単にデータをドリルダウンすることが可能です。
そのための設定の流れは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/e7c0453f-3346-c98b-8ce9-18fc58f70c5e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/3d01be60-d40f-fdf8-612a-a2be7422bfb8.png)

これらの定義を行うことにより以下のことが可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/4c0570e7-7f1e-d980-d15f-8aa749d345f1.png)

様々なメリットのあるリポジトリ設定を皆さんもちゃんレンジしてみて下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/c6b18cd7-a719-1c09-964d-a44637f39a57.png)
Quadkey  備忘録

雑に書いた

地球は周囲40,075Km

Quadkey


| ズームレベル（Quadkey桁数）|タイル一辺の距離[Km]|      [m]      | 
|:--------------------:|:---------------:|:-------------:|
|   0                  |  40,075[Km]     |  40,075017[m] |
|   1                  |  20,037[Km]     |  20,037508[m] |
|   2                  |  10,018[Km]     |  10,018754[m] |
|   3                  |  5,009[Km]      |  5,009377.1[m]|
|   4                  |  2,504[Km]      |  2,504688.5[m]|
|   5                  |  1,252[Km]      |  1,252344.3[m]|
|   6                  |  626.1[Km]      |  626172.1[m]  |
|   7                  |  313.0[Km]      |  313086.1[m]  |
|   8                  |  156.5[Km]      |  156543[m]    |
|   9                  |  78.2[Km]       |  78271.5[m]   |
|   10                 |  39.1[Km]       |  39135.8[m]   |
|   11                 |  19.5[Km]       |  19567.9[m]   |
|   12                 |  9.78[Km]       |  9783.94[m]   |
|   13                 |  4.89[Km]       |  4891.97[m]   |
|   14                 |  2.44[Km]       |  2445.98[m]   |
|   15                 |  1.22[Km]       |  1222.99[m]   |
|   16                 |  0.611[Km]      |  611.496[m]   |
|   17                 |  0.305[Km]      |  305.748[m]   |
|   18                 |  0.152[Km]      |  152.874[m]   |
|   19                 |  0.076[Km]      |  76.437[m]    |
|   20                 |  0.038[Km]      |  38.2185[m]   |
|   21                 |  0.019[Km]      |  19.10926[m]  |
|   22                 |  0.009[Km]      |  9.55463[m]   |
|   23                 |  0.004[Km]      |  4.777315[m]  |
|   24                 |  0.002[Km]      |  2.3886575[m] |


Km = 40,075[Km] / 2^zoomLevel

Quadkey16桁の精度は0.611[Km]



もし2点間の距離をざっくりとでも求めたい場合（非推奨）

A = 11011011011011011111
B = 11011011011011022222

110110110110110の15桁は一致しているので
1辺の長さは1.22km

直角三角形斜辺の長さ = 辺 × 辺 × √2  より
3.45068 = 1.22×1.22×√2  

この2つの距離は0<x<3.45068[Km]の範囲内にあると分かる



注意
A = 011111111111111111111
B = 100000000000000000000
は隣どうしだが，上記の方法で計算すると範囲は広くなる
AWS LambdaでRDSのdump-restoreするための設定(SAM)

## Sam Template

```yaml
  CopyDatabaseFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      Timeout: 120
      Environment:
        Variables:
          FromDbSecretId: !Ref UserDbSecretArn
          ToDbSecretId: !Ref InitTargetDbSecretArn
      VpcConfig:
        SecurityGroupIds:
          - !Ref SecurityGroupId
        SubnetIds: !Ref SubnetIds
      Policies:
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: !Ref UserDbSecretArn
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: !Ref InitTargetDbSecretArn
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./container/copy_data
      DockerTag: v1
```

## Dockerfile

```dockerfile
FROM public.ecr.aws/lambda/python:3.8

RUN yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm \
    && yum install -y mysql-community-client

RUN mkdir /work

COPY ./index.py ./index.py

CMD ["index.handler"]
```

## Code

```python
import os
import subprocess

import boto3


def get_secret(client, secret_id):
    import ast
    rds_response = client.get_secret_value(SecretId=secret_id)

    return ast.literal_eval(rds_response['SecretString'])


def run(from_db_secret_id: str, to_db_secret_id: str):
    print('start program')
    client = boto3.client('secretsmanager')
    from_db_setting = get_secret(client, from_db_secret_id)
    to_db_setting = get_secret(client, to_db_secret_id)

    dump_response = subprocess.Popen([
        'mysqldump', 'fromdb',
        '-u', from_db_setting['username'],
        f"-p{from_db_setting['password']}",
        '-h', from_db_setting['host'],
        '-t'
    ], stdout=subprocess.PIPE)

    subprocess.run([
        'mysql', 'todb',
        '-u', to_db_setting['username'],
        f"-p{to_db_setting['password']}",
        '-h', to_db_setting['host'],
    ], stdin=dump_response.stdout)

    print('end program')


def handler(event, context):
    run(os.environ['FromDbSecretId'], os.environ['ToDbSecretId'])
```
BOOTSTRAPを使って装飾してみました

###NEXT.JSを使って[前回それらしき郵便番号検索フォーム](https://qiita.com/ume-bar/items/c3eb55f27dfe9d232be2)を作成したのですが、相性がいいBOOTSTRAPを使って装飾をしてみようと、APIは別で叩いているので、今回弄るのはindex.tsxファイルのみ。state使ってるとホント便利です。BOOTSTRAPをインストールしてコードを以下のように書き換えてみました。

```index.tsx
import Head from 'next/head'
import React, { useState } from "react";
import { values } from 'sequelize/types/lib/operators';
import { Button, Card, Container, FormControl, Row, Col } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

const Home = (props: any) => {
  const [post, setPost] = React.useState("");
  const [prefectures, setPrefectures] = React.useState("");
  const [municipalities, setMunicipalities] = React.useState("");
  const [address, setAddress] = React.useState("");
  const [count, setCount] = useState(0);

  React.useEffect(() => {
    fetch('/api/prefec?prefectures=' + prefectures + '&municipalities=' + municipalities + '&address=' + address)
      .then(response => response.json())
      .then(data => {
        if (data !== null) {
          setPost(data.post)
        } else {
          setPost(null)
        }
      }); 
  }, [prefectures, municipalities, address])

  return (
    <Container>
      <Row>
        <Col md={6} lg={6} className="mt-3">
          <Card>
            {/* <Card.Img variant="top" src="holder.js/100px180" /> */}
            <Card.Header>都道府県から住所を入力して下さい</Card.Header>
            <Card.Body>
              <FormControl
                placeholder="都道府県"
                value={prefectures}
                onChange={event => setPrefectures(event.target.value)}
              />
              {prefectures != "" &&
                <FormControl
                  className="mt-3"
                  placeholder="市区郡"
                  value={municipalities}
                  onChange={event => setMunicipalities(event.target.value)}
                />}
              {municipalities != "" &&
                <FormControl
                  className="mt-3"
                  placeholder="市区町村"
                  value={address}
                  onChange={event => setAddress(event.target.value)}
                />}
            </Card.Body>
          </Card>
        </Col>
        {post &&
          <Col md={6} lg={6} className="mt-3" >
            <Card>
              <Card.Header>あなたの調べた郵便番号はこちらです</Card.Header>
              <Card.Body>
                <FormControl
                  value={post}
                  onChange={event => setPost(event.target.value.replace("-", ""))
                  } />
              </Card.Body>
            </Card>
          </Col>}
      </Row>
    </Container>
  )
}
export default Home;
```

###いい感じに仕上がりました。placeholderによって誘導項目もバッチリです。
![スクリーンショット 2021-05-29 20.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/a1ba6a02-1680-3c24-2de3-949cf99f9ee3.png)
【初心者でもわかる】tableの要素を縦に並べてレスポンシブ対応する方法

# どうも7noteです。tableの要素を強制的に縦に並べる方法を解説

table要素を使った場合、PC表示のときはいいのですがスマホだとあまり横に長い表組みだと小さくなりすぎたり、文字が収まらず縦になってしまったりします。

![NG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/119f389d-1196-0da3-1a55-c2a7c11b7104.png)
※文字が収まらず縦書きになってしまった例


これを解決するために、**スマートフォンの時だけ横並びの要素を縦に並べて対策をおこないます。**

## ソース

```index.html
<table>
  <tr>
    <td>りんご</td>
    <td>ごりら</td>
    <td>らっぱ</td>
    <td>ぱんつ</td>
  </tr>
</table>
```

```style.css
table,td,th {
  border-collapse: collapse;  /* 罫線を引くための指定 */
}
td,th {
  border:1px solid #333;  /* 線を引く */
  padding: 10px 30px;     /* 余白を指定 */
}
@media screen and (max-width: 768px) {
  table,tbody,tr,td,th {
    width: 100%;    /* 幅を100%にする */
    display: block; /* ブロック要素にする */
  }
}
```


![OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/36ddf070-e40c-a18d-3f25-ea5f262c7cfb.png)

## 解説

tableは本来`<tr>`1つで1行ですが、子要素になる`<td>``<th>`をブロック要素に変えて幅を指定することで、縦に並べることができます。

## まとめ

レスポンシブ対応でつかえる技術系はなんぼあってもいいですからね。
tableは使用頻度がそこまで高くはないですが、それでもまだまだ利用される場面が多いのでレスポンシブサイトでも使えるようにテクニックは覚えておくといいかもしれません。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Oracle Analytics Cloud ことはじめ：インスタンスの作成手順 Oracle Cloud Infrastructure版 ver5.7

今回はAnalytics Cloud  Oracle Managed  - Oracle Cloud Infrastructure OACインスタンスの作成手順 対象version 5.7の方法について記載いたします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/979093ca-d66f-dca6-d7ff-3fa05e77e2ae.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/df3c27a8-ad1e-e85b-abf9-b9ebd71231fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/07bcb59c-e61d-037a-de33-acdf9a3626f0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/d4680308-dcdb-782a-4517-2e1f7a9a6cb6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/87f40fee-9585-70ee-dc27-2bafe4b9cbf0.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/71ac4c07-60b9-1ca6-e4fa-f5179e14ea44.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/e952819a-c25f-a2e2-6da0-bf1d28ab654d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/c429ffae-96eb-51d4-f18d-b98a71846664.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/ace910b5-0e5b-cbc3-da61-e853173a6c2c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/7419a33b-e414-c141-dea8-de113256add0.png)


いかがでしたか？
詳細は以下マニュアルをご参照ください
日本語
https://docs.oracle.com/cd/E83857_01/paas/analytics-cloud/acoci/create-services.html
英語(最新版)
https://docs.oracle.com/en/cloud/paas/analytics-cloud/acoci/create-services.html
クラスを使用するメリットについて

こんにちは、プレイライフの熊﨑です！
現在rubyの基礎知識を補填するために、チェリー本を読んでいるのですがクラスに対する理解をアウトプットを通して深めたいと感じたので、記事にすることにしました。

## クラスとは
オブジェクトの設計図を指します。ちなみに、クラスから作られたオブジェクトをインスタンスと呼びます。
例えるなら、クラスは「車の設計図」、インスタンスは「車」といったところです。

## クラスを使用するメリット
多分、クラスとインスタンスの話については調べるとよく出てくるので、皆さんもご存知だと思います。
では次に、クラスを使用するメリットについて説明します。

例えば、ユーザーの個人情報を表すデータを管理したいと思います。
ハッシュと配列を使用する場合は以下のように処理することができます。

```.rb
users = []
users << { first_name: 'Taro', last_name: 'Tanaka', age: 20 }
users << { first_name: 'Ziro', last_name: 'Suzuki', age: 30 }

def full_name(user)
  "#{user[:first_name]}#{user[:last_name]}"
end

users.each do |user|
  puts "氏名：#{full_name(user)}、 年齢：#{user[:age]}" 
end
```

ハッシュを使用すると、キーをタイプミスしたときにnilが返ってくるので不具合に気づきにくいです。

```.rb
users[0][:name] #=> Taroが返ってくる。
users[0][:neme] #=> nilが返ってくる。 エラーにはならない。
```

また、ハッシュは新しいキーを追加したり内容を変更できるので「脆くて壊れやすいプログラム」になりがちです。

```.rb
users[0][:sex] = 'male' #=> 勝手に新しいキーを追加できる
users[0][:name] = 'Saburo' #=> 勝手にnameを変更
users[0] #=> {:name=>"Saburo", :age=>20, :sex=>"male"}と返ってきており、ハッシュの中身が変更されてしまう。。。
```
今回のような小さなプログラムではハッシュのままでも問題ないかもしれませんが、大量のデータを扱うとハッシュでは管理しきれなくなります。そこで、クラスの出番がきます。クラスを使ってデータを管理することで、ハッシュを使用するより、堅牢なプログラムにすることができます。
今回のハッシュと配列で管理していたデータをクラスを用いて管理すると以下のように書くことができます。

```.rb
class User
  attr_reader :name, :age
  
  def initialize(first_name, last_name, age)
    @first_name = first_name
    @last_name = last_name
    @age = age
  end

  def full_name(user)
    "#{user[:first_name]}#{user[:last_name]}"
  end
end

users = []
users << User.new('Taro', 'Tanaka', 20)
users << User.new('Ziro', 'Suzuki', 30)

users.each do |user|
  puts "氏名：#{user.full_name}、 年齢：#{user.age}" 
end
```

Userクラスを導入することでタイプミスをした時にエラーが発生します。

```.rb
users[0].first_name #=> 'Taro'
users[0].first_neme #=> NoMethodError: undefined methodが出る。
```

また、新しく属性を追加することもできません。

```.rb
users[0].sex = 'male' #=> NoMethodError: undefined methodが出る。
```

このように、クラスを使うことで、ハッシュや配列を用いてデータを管理するよリも堅牢なプログラムが出来上がりました。

また、クラスはこのように内部にデータを保持し、さらに自分の保持しているデータを利用する独自のメソッドを持つことができます。データのそのデータに関するメソッドがセットになるので、クラスを使用しない場合と比べて、データやメソッドの整理が格段にしやすくなります。小規模なプログラムならあまりメリットを感じづらいかもしれませんが、プログラムの規模が大きくなるほど、データとメソッドを同時に持ち運べるクラスの重要性を感じることができるはずです。

## まとめ

- クラスを導入することで、ハッシュや配列のみを用いてデータを管理するよりも堅牢なプログラムを作れる。
- クラスはデータとデータに関するメソッドをセットで保持できるので、データやメソッドの整理がしやすくなる。

## 最後に
ということで、今回はクラスを使用するメリットについてまとめてみました。
次回はクラスつながりで、クラスメソッドとインスタンスメソッドの違いについて書いていこうと思います！
クラスメソッドの中でインスタンスメソッドを呼び出すとエラーが出る理由について

こんにちは、プレイライフの熊﨑です！
本日は、実際に私が業務で遭遇したエラーについて記事にしていこうと思います。

## エラー内容

```.rb
class A
  def self.foo
    bar
  end

  def bar
    puts "インスタンスメソッドが呼び出されました！"
　end
end

A.foo
#=> NoMethodError: undefined method `bar' for A:Class
```

上記のコードのように、クラスメソッドの中でインスタンスメソッドを呼び出そうとしてエラーになりました。

## 原因
「クラスメソッドの中でインスタンスメソッドを呼び出しているから」

これだけだとイメージがつきづらいと思うので、もう少し詳しく説明していきたいと思います。

### なぜクラスメソッドの中でインスタンスメソッドを呼び出すと、エラーが出るのか？
クラスメソッドは以下のように、クラスをレシーバーとして呼び出すことのできるメソッドです。
例：Userクラスのfull_nameというクラスメソッドを呼び出す場合

```.rb
User.full_name
```

ですので、クラスが読み込まれたタイミング（railsの場合はrailsが起動したタイミング）から使用できるようになります。

一方、インスタンスメソッドはインスタンスをレシーバーとして、呼び出せるメソッドになっています。

例：Userクラスのhelloというインスタンスメソッドを呼び出す場合

```.rb
user = User.new
user.hello

# インスタンスメソッドの場合、レシーバーはインスタンス（上のコードのuser）になるので、エラーになる。
User.hello #=> NoMethodError: undefined method `hello' for User:Class
```
つまり、インスタンスメソッドと、クラスメソッドでレシーバーが違うので、エラーが起きる。ということでした。

## 補足　〜クラスとインスタンスのイメージ〜
スマートフォンの電源を点けたとき、スマホの横のボタンをいじって音量調整を行うかと思います。この音量調整を行う作業がクラスメソッドです。一方、ラインアプリを開いて、友達にメッセージを送る。このメッセージを送るという作業がインスタンスメソッドです。（ちなみにラインアプリを開くという行為がインスタンスを生成するというイメージ）

## まとめ
- クラスメソッドの中でインスタンスメソッドを呼び出すとエラーが出る。
- railsの起動直後にクラスが読み込まれるため、クラスメソッドはrails起動直後から呼び出せる。
- インスタンスメソッドはインスタンスをレシーバーとして呼び出せるメソッド。
- クラスメソッドを実行しているタイミングでインスタンスが生成されていないので、クラスメソッドの中でインスタンスメソッドを呼び出すとエラーが生じる。
- クラスメソッドとインスタンスメソッドでは、レシーバーが違うためエラーが起きた。

## 最後に
今までインスタンスメソッドとクラスメソッドの違いについての認識がとても曖昧なものでした。しかし、今回このエラーに遭遇したことで自身のクラスメソッドやインスタンスメソッドに対する認識の曖昧さに気づくことが出来てよかったと感じています。これからもたくさんのエラーにぶつかっていくと思いますが、その度に自分の糧としていくことでどんどん成長していけたらと思います。