OmniAICreator/Qiita-1.07M huggingface dataset:
複数のアカウント情報でchromeを開きたい

# 方法
2ステップです。

## 手順1. 適当なディレクトリを作る
まず、開きたいchromeの数分の空のディレクトリを作ります。
場所も名前もなんでもいいです。

```.sh
% mkdir -p ${HOME}/tmp/chrome/1
% mkdir -p ${HOME}/tmp/chrome/2                                                                                  
% mkdir -p ${HOME}/tmp/chrome/3
% mkdir -p ${HOME}/tmp/chrome/4
% mkdir -p ${HOME}/tmp/chrome/5
```

## 手順2. 作ったディレクトリを指定してchromeを実行する
下記コマンドでchromeを開きます。
`--user-data-dir`に先ほど作成したディレクトリを指定しています。
あとは、新しいウィンドウやタブでコマンド入力画面を開いて、同様にディレクトリを指定して実行してください。

```.sh
% /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=${HOME}/tmp/chrome/1 --incognito
```


# 参考
- [MacのGoogle chromeをコマンドラインから起動してみる。 | developer's diary ](https://blog.be-dama.com/2015/04/08/chrome-muti-incognito/)
- [google chromeで複数のシークレット・ウィンドウを開く方法 | マイノリティでいこう](https://blog.be-dama.com/2015/04/08/chrome-muti-incognito/)
【一般】Sharperlight インストーラのダウンロード

西オーストラリア生まれのBIソリューション(多言語対応)のインストーラのダウンロード方法です。
Sharperlightは、WEBレポートやExcelアドインを使用したExcelレポートの作成等に使用できます。

Sharperlight(シャーパーライト)のサイトへ行きます。
https://www.sharperlight.com/


ResourcesのドロップダウンメニューからCurrent Buildsを選択します。
![Qiita 2022-02-17 -Resources - Current Builds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/42b93313-ca63-080d-210b-f90be3cd9dc8.png)


Current Buildsページでは最新のビルドを選択します。
現時点(2024-04-30)では、Sharperlight 6.0.89 64bit が最新ですね。（32bitバージョンは特殊なケースの場合のみ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/87bf1b09-d52a-1b20-85e5-232098b7036b.png)

Downloadボタンでmsiファイルをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/1b2cea44-4db6-4d6e-c153-97c031608ed0.png)
MonacaでMapboxを使う際のCSP設定について

Monacaに限った話ではありませんが、Mapbox JS SDKを使う際にはCSP（ Content Security Policy）の設定が必要です。

Framework7でMapboxを使って開発を行っている再、開発時にはGoogle Chromeを使っていました。Framework7プロジェクトでは `npm run start` で `http://localhost:8080/` が開くので便利です。

そして、Google Chromeでアクセスすると、最初に次のようなエラーが出ます。

```
Refused to create a worker from 'blob:http://localhost:8080/〜' because it violates the following Content Security Policy directive: "default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: content:". Note that 'worker-src' was not explicitly set, so 'default-src' is used as a fallback.
```

ということで、 CSP に `worker-src` を追加します。

```html
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: content:; worker-src blob:">
```

これでGoogle Chromeでは問題なく動くのですが、MonacaやCordovaでiOSアプリとして動作確認を行おうとするとエラーが出ます。

```
Refused to load blob:app://localhost/〜 because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.
```

なんとSafari（WKWebView）ではworker-srcディレクティブが存在しないようです。ということでCSPを次のように修正します。 `default-src` 側で設定せざるを得ないようです。

```html
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: content: blob:">
```

こうするとGoogle Chrome、iOSアプリのどちらでも動くようになります。

## ついでに

WKWebViewになってからなのか、CordovaアプリでHTML5 APIとしての `navigator.geolocation.getCurrentPosition` が使えなくなっていました。開発策としては[Geolocation - Apache Cordova](https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-geolocation/index.html)を使ってCordovaプラグインを使って位置情報を取得することになります。APIはHTML5 APIと同じなので、コードの修正は不要です。

```
cordova plugin add cordova-plugin-geolocation
```
Nuxt.jsでFullCalendarをGoogleカレンダーと連携させる。


2022年2月17日現在。
Nuxt.js でFullCalendarにGoogleCalendarのデータを取り込むのにものすごく苦労したので公開。

同じことをやろうとしているページをコピペしてやってもなかなかうまくいきませんでした。
ライブラリの仕様が変わったのか、それともvue.jsのバージョンが違うのかだと思いますが、自分が使っているフレームワークに合わせて記述方法が違うようです。

2022-2-18 追記
どうもFullCalendarの4系と5系では全然記述方法が違うみたいです。
コピペでうまくいかない時は、記事の作者がどのバージョンで使っているか確認した方が良さそうです。

動いた環境

```
npm nuxt -v
6.14.12
npx nuxt -v
@nuxt/cli v2.15.8
```

ポイントはFullCalendarコンポーネントのタグに渡すのは:optionsだけになっていること。
見る記事によっては:eventSourceとか、項目ごとにpropsを追加して渡していましたが、それだと今回はだめでした。
イベントもgoogleカレンダーのAPIキーもCalendarIdもoptionsの中に詰めこむ形でdata()に追記していきます。
この辺の階層が違うだけで、オプションの項目キー自体はどこの記事も大体同じようです。

あと、イベントソースが一つしかない記事がほとんどですが、このように配列の中にオブジェクトを追加していくことで、複数のカレンダーに対応できます。
この時、Apiキーは同じものを使い、カレンダーIDだけ固有のIDになっています。

japanese__ja@holiday.calendar.google.com　の部分はGoogleが一般公開している休日データでこのままコピペしたら使えるようになっています。


```

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import googleCalendarPlugin from '@fullcalendar/google-calendar';

export default {
  components: {
    FullCalendar // make the <FullCalendar> tag available
  },
  data() {
    return {
      calendarOptions: {
        plugins: [ dayGridPlugin, interactionPlugin,googleCalendarPlugin ],
        initialView: 'dayGridMonth',
        eventSources: [
          {
            googleCalendarApiKey: 'googleで取得したカレンダーAPIキー',
            googleCalendarId: 'japanese__ja@holiday.calendar.google.com',
            display: 'background',
          },
          {
            googleCalendarApiKey: 'googleで取得したカレンダーAPIキー',
            googleCalendarId: 'googleで取得したカレンダーID',
          },
        ]
      }
    }
  }
}
</script>
<template>
  <FullCalendar :options="calendarOptions"/>
</template>

```


#　参考
ここのコードをコピペしても動かなかったので上のように階層構造をNuxtに合わせました。

https://qiita.com/niever66/items/bef24d1f23e9075eb09d

階層構造はここをヒントにしました。こっちにはgoogle連携の話がなかったので上の記事と見比べ。

https://fullcalendar.io/docs/vue

Nuxtにフルカレンダーをインストールコマンドはここ。というか公式ページ。

https://fullcalendar.io/docs/vue

ここには使えるオプションとか使用法が色々書いてある。見た中で一番わかりやすかったかも。

https://www.mitsue.co.jp/knowledge/blog/frontend/202012/08_0900.html

GoogleカレンダーのAPIキーとカレンダーキーの取得方法はここが書いてくれている。
メニュー構成がちょっと変わっていて写真の通りにはならないけど、文章に書いてくれている項目名を探していけばたどりつけた。

https://webstudioleaf.com/blog/js/gcal-api/
Bootstrap4のSpacing

#Spacing
### property

m - margin
p - padding

###sides
Bootstrap5をちょっとだけ

|  |Bootstrap4| |Bootstrap5| 
|:------------:|:------------:|:------------:|:------------:|
|t|top|t|top|
|b|bottom|b|bottom|
|l|left|s|start|
|r|right|e|end|
|x|left & right|x|left & right|
|y|top & bottom|y|top & bottom|

###size
※`$spacer`=1rem=16px。$spacers Sassマップ変数にエントリを追加することで, サイズの追加可能

| 0 | 1 | 2 |3 |4 |5 |
|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
|`$spacer`× 0|`$spacer`× .25|`$spacer`× .5|`$spacer`|`$spacer` × 1.5|`$spacer` × 3|

auto - for classes that set the margin to auto
marginの場合、数字の前に n をつけるとマイナスに　例）mt-n1

###ブレークポイント
| xs |sm| md |lg |xl |
|:------------:|:------------:|:------------:|:------------:|:------------:|
|Extra small|Small|Medium|Large|Extra large|
|<576px|≥576px|≥768px|≥992px|≥1200px|

###記載方法

```
<div class="ml-1">左に（16px × 0.25）のmargin</div>
<div class="px-md-5">幅768px以上の時は　左右に（16px × ３）のpadding</div>
```
【自分メモ】MAMPのmysql起動、ログイン方法

# ①MAMP起動
ポチ
# ②MySQLサーバー起動
MAMPの起動と一緒にMySQLサーバーも起動しているはず

# ③MySQLにログイン
```
mysql -u root -p
```

デフォルトのPWは`root`

# 備考
.bash_profileに環境変数としてmampのmysqlが動くようパスを設定済み。
PHPも同様にMAMPのものが動くようにしている。
Macの.bash_profileに環境変数の設定が反映されなかった話

# 環境
MacOS Catalina 10.15.7

# 結論
`.bash_profile`の記述で
「usr/bin/php」より前に「Applications/MAMP/bin/php/php*.*.*/bin」が読み込まれるようにしたら無事パスが変更された

```
export PATH=/Applications/MAMP/bin/php/php*.*.*/bin:$PATH
```

# 補足
## `.bash_profile`とは
多分ルート階層に作成するファイル。
bashとはLinuxのシェルのことらしい。LinuxとはOSの一種で、シェルはOSの中核に対して指示を伝えるためのツール。
Macだとターミナルにあたる。
`.bash_profile`はターミナル起動時に初期設定をしてくれる設定ファイルのようなもの。

## `.bash_profile`の設定反映
記述を変更しただけでは反映されない
以下のコマンドで設定反映
`source .bash_profile`

# 参照サイト
https://jyu2log.com/phppathsetting#PHP
javascript58_スコープ

JSの中に２種類機能するスコープがあります。
1. 全てのスコープに使える
　　直接scriptタグの中に記載されます。
　　全領域スコープはページが開く時に作られ、ページを閉じる時に消える。
　　全領域スコープのなかに一つの全領域オブジェクトはwindowです。windowはブラウザのwindowを代表します。windowを直接使うことができます。

window: 全領域スコープのなかに作られた変数は全てwindowオブジェクトの属性として保存されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/e17d515c-b7b4-2848-88f1-7cd494c88c57.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/6a69906c-6815-e32e-8db9-82be8c920ecd.png)
作った関数は全てwindowのメソッドとして保存されます。

変数の宣言：
varを使用した変数の宣言は、全てコードが実行される前に宣言される。値は代入されないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/a14289e3-36b2-94e5-0ce6-4ff920534615.png)

関数の宣言：
- function() 関数名{}で作れられた関数は、
- 全てのコードが実行される前に宣言される。そのため、宣言される前に呼び出すことができます。

var　関数名　= function(){};で作られた関数は事前に宣言されることはできないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/8cf8061d-7d63-6a31-180b-7384dfc71284.png)
Flutterでリリースモード（ビルド）にログ出力させたくない場合にはprintではなくlogを使う

## Flutterでよく使うログ出力

Flutterで開発を進めていく中でデバッグする際によく使用するのが、

```Dart
print('hoge');
```
このログ出力。
 
　

このログ出力はデバッグモード時だけでなく、リリースモード時にも出力されてしまう(Androidのみ)のですが、
今回、***リリースモードではログ出力させたくないけど、デバッグモードではログ出力ができるようにしておきたい***というケースにあたりましたので、色々と調べた結果を記録として残したいと思います。
　
　　
【注意】
***iOSではprintでもlogでも、リリースモード時はログ出力されません。Androidのみリリースモードでの挙動が変わります。***

## Flutterでリリースモード時にログ出力されない方法
結論、以下のようにすることでデバッグ時のみログ出力をし、リリースモード時にはログ出力されないように出来ます。

```Dart
import 'dart:developer';

log('hoge');
```
　　

実際に、以下のログを仕込んでSimulatorでのログ出力（デバッグモード）と、`flutter run -release`コマンドでリリースモードでそれぞれの動きを確認してみました。




```Dart
print('hoge'); 
log('huga');
```
　

デバッグモード時は以下のようなログ出力に。

```
flutter: hoge
[log] fuga
```
　

リリースモードでのログは以下の通り。

```
I/flutter ( 5339): hoge
```

リリースモード時はlogは出力されず、printは出力がされました。
SwiftUIのListとTextFieldでインクリメンタルサーチっぽいあれ

とりあえずサンプルコード
ポイントは空の時のフィルター

元の要件で「選択したものはリストから削除して別途リストを作り、追加削除できるように」とあったので、Setを別に用意して含まれるかどうかも条件に追加した。
5000件レコードを放り込んでも大丈夫

```Swift:BookView.swift![Something went wrong]()

import SwiftUI

struct BookView: View {
    
    struct Book: Identifiable {
        let id :String = UUID().uuidString
    }
    
    var bookList: [Book] = []
    @State var searchText: String = ""
    @State var selected =  Set<String>()
    
    init() {
        for _ in 0...5001 {
            bookList.append(Book())
        }
    }
    
    var body: some View {
        TextField("search", text: $searchText)
        VStack{
            ForEach(Array($selected.wrappedValue),id:\.self) { book in
                Button {
                    selected.remove(book)
                } label: {
                    Text(book)
                }
            }
        }
        List(bookList.filter { ($searchText.wrappedValue.isEmpty || $0.id.contains($searchText.wrappedValue)) && !selected.contains($0.id) }) { book in
            Text("Book id= \(book.id)")
                .onTapGesture {
                    selected.insert(book.id)
                }
            .id(book.id)
        }
    }
}
```

![Simulator Screen Shot - iPhone 13 mini - 2022-02-17 at 14.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45591/db983330-c170-5239-4a11-83cd4bcc4783.png)
【Next.js x Amplify】リダイレクト設定が面倒なので一括で出力するシェルスクリプトを書きました【書き換えて、リダイレクト】

## Amplify Hosting の Next.js の Dynamic Routes の設定が面倒

何も考えずにURLに直接アクセスするとうまくページを表示できない。
なんてことは、おそらくタイトルの構成でホスティングされると経験されるかと思います。
それの対応策は以下のリンクが非常にわかりやすいので、こちらで対応すればサクッと対応できます。

https://zenn.dev/nus3/articles/e3da1bdb3ef302962f07

簡潔に言えば、Amplifyの「書き換えて、リダイレクト」画面で適切な設定をすれば対応ができます。

しかし私にとっての問題は設定の可否ではなく、**設定の煩わしさ**です。

私はバックエンドエンジニアなのであまりNext.jsに明るく無いのですが、AWSをよく触るのでこの辺りの設定担当になっています。
把握していないファイル構成を洗い出し、一つ一つぽちぽちするのが結構面倒なんです。

![書き換えて、リダイレクト 設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632997/28ebd02c-c5b4-1282-03e3-3098d904ade0.png)

↑こういうのを一個一個設定する必要があります。

## テキストエディタで設定することもできるよ

![テキストエディタ 設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632997/ed922148-29df-1574-2d9b-b8aa5e3e313e.png)

このように、テキスト形式で設定することもできるそうです。
**これを利用すれば少しは簡略化できそうですね！**

## なのでシェルスクリプトを作ったよ！

というわけでコマンド一つでファイルを出力して、
それをコピペして貼り付ければ設定できるようにしました！

`bash amplify_redirects.sh` で `redirections.json`というファイルに
設定用のjsonが吐き出されるようにしました。

以下は雛形として、各々の環境に合わせてカスタマイズしていただけると幸いです。


```bash:amplify_redirects.sh
#!/bin/bash

##### 各種パラメータ ######

# 拡張子
EXTENSION='.tsx'
# 削除するプリフィックス
ROOT_DIR='./src/pages'
# 除外するファイル
EXCLUDED_FILES=('/_app' '/_document' '/index')
# 出力先のファイルの名前
OUTPUT_FILE='redirections.json'

##### ここから処理 #####

pages=$(find ./src/pages -type f)
targets=(${pages// / })

echo "[" > $OUTPUT_FILE

for target in "${targets[@]}"
do
  target=${target#$ROOT_DIR}
  target=${target%$EXTENSION}
  
  if printf '%s\n' "${EXCLUDED_FILES[@]}" | grep -qx $target; then
    continue
  fi

  # /indexを削除
  target=$(echo $target | sed s/\\/index$//)

  # /[]を<>に書き換えるを削除
  source=$(echo $target | sed s/\\[/\</)
  source=$(echo $source | sed s/\\]/\>/)

  echo "    {" >> $OUTPUT_FILE
  echo "        \"source\": \"$source\"," >> $OUTPUT_FILE
  echo "        \"target\": \"$target\"," >> $OUTPUT_FILE
  echo "        \"status\": \"200\"," >> $OUTPUT_FILE
  echo "        \"condition\": null" >> $OUTPUT_FILE
  echo "    }," >> $OUTPUT_FILE
done

# 想定外のURLには404を返す
echo "    {" >> $OUTPUT_FILE
echo "        \"source\": \"/<*>\"," >> $OUTPUT_FILE
echo "        \"target\": \"/404.html\"," >> $OUTPUT_FILE
echo "        \"status\": \"404-200\"," >> $OUTPUT_FILE
echo "        \"condition\": null" >> $OUTPUT_FILE
echo "    }" >> $OUTPUT_FILE

echo "]" >> $OUTPUT_FILE

cat $OUTPUT_FILE
```

## 上手にできました

出力してみるとこんな感じです！
これをコピペして簡単に設定できるようになりました！

![出力結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632997/7b0ee3cc-f9be-5567-738b-177da8aab7e6.png)


しかしながら、相変わらずAWS先生の日本語って不思議ですね。
「書き換えて、リダイレクト」ってなんなんだろ...笑

※より良い書き方や、改善点などがあれば気軽にコメントいただけると嬉しいです。
WSL2でCan't open displayが出た時の対処

# はじめに
WSLのUbuntuでGUIを使いたくXmingを導入してみました。
その際すんなりいかず、色々調べたのでまとめてみます。
何番煎じか分かりませんが...

```
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print \$2}'):0.0
```

この設定で上手くいかなかった人向けです。
# 環境
- WSL2
    - Ubuntu 18.04 LTS
- Xming X server 6.9.0.31

# 方法
.bashrcに既に下記が書いてあるものとします。

```shell:.bashrc
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print \$2}'):0.0
```

結論から言うとProgram fileにあるXmingのX0.hostsというファイルに下記のようにwslのipアドレスを書き込むだけです。

```shell:X0.hosts
localhost
aaa.bbb.ccc.ddd //wslのipアドレス
```
ubuntuターミナルでip aをして、eth0のinetの部分がwslのipアドレスになると思います。
X0.hostsはここ　C:\Program Files (x86)\Xming
X0.hostsは管理者権限がないと書き込めません。
## 脇道
wslは起動毎にipアドレスが変更されるため、自動で書き込むbatファイルを作りました。すごい泥臭いやり方をしている気がするので、もっと勉強していきたいです。
**利用は自己責任でお願いします。**

```shell:hoge.bat
cd C:\Program Files (x86)\Xming
wsl touch temp1
wsl touch temp2
wsl touch temp3
echo | wsl ip -4 a > temp1
echo | wsl grep 172 temp1 > temp2
echo | wsl awk -F'[ /]' '{print $6}'  temp2 > temp3
wsl sed -i '1i localhost' temp3
wsl cp temp3 X0.hosts
wsl rm temp*
```

上記をbatファイルを管理者権限のコマンドプロンプトで実行したら自動で書き込まれます。
# 終わりに
タスクスケジューラで、wsl起動時に設定したかったけど面倒そうなのでやれませんでした。
いつかはやりたい。
# 参考
https://qiita.com/ryoi084/items/0dff11134592d0bb895c
【Project Euler】Problem 89: ローマ数字

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 89.ローマ数字

原文 [Problem 89: Roman numerals](https://projecteuler.net/problem=89)

**問題の要約：ファイルから読み込んだローマ数字は長さが最適化されていない。これを最短の表現に変換して短くなった文字数の合計を求めよ**

ローマ数字から数字に変換する**rom2num**と数字を最短の表現に変換する**num2rom**を作ってその長さの差の合計を求めます。例によってファイルの読み込みは下に添付しました。

```python 
romv = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
def rom2num(r):
  return sum([-romv[r[i]] if romv[r[i]]<romv[r[i+1]] else romv[r[i]]   
              for i in range(len(r)-1)])+romv[r[-1]]
romc = [('I', 'V', 'X'), ('X', 'L', 'C'), ('C', 'D', 'M'), ('M', 'MMM', '')] 

def num2rom(n):
  def _d2r(d, i, v, x):  # digit to roman number 
    return ['', i, i * 2, i * 3, i + v, v, v + i, v + i * 2, v + i * 3, i + x][d]
  
  return "".join([_d2r(int(d), *romc[3-i]) for i, d in enumerate(format(n,"04"))])

print(f"Answer: {sum([len(rn)-len(num2rom(rom2num(rn))) for rn in roman])}")
```

### ファイルの読み込み

```python 
# show upload dialog
from google.colab import files
uploaded = files.upload()
f = open("p089_roman.txt")
roman = f.readlines()
f.close()
roman = list(map(lambda s: s.strip(),roman))
print(len(roman),roman[:10])
```

（開発環境：Google Colab）
Gitでマージ済みで不要となったブランチを削除するエイリアスを登録する

開発を続けていると自分の機能ブランチ、レビューした他の人のブランチ、リリース作業用のブランチ…、とたくさんブランチが増えてきます。
よく忘れてしまうのでマージ済みのブランチを消すエイリアスのメモです。（エイリアスだけ残っていたのですが、おそらく[コチラ](https://qiita.com/hajimeni/items/73d2155fc59e152630c4)から頂いてきました）

`develop/main/master` を除外します。


```config:~/.gitconfig
[alias]
    delete-merged-branch = "!f () { git checkout $1; git branch --merged|egrep -v '\\*|develop|main|master'|xargs git branch -d; };f"
```

```bash
$ git delete-merged-branch
Your branch is up to date with 'origin/develop'.
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch feature/...
Deleted branch release/...
```


![Screen Shot 2022-02-17 at 13.03.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/414341a3-bf66-bceb-c350-8e61aa8a72c4.png)


# 参考
https://qiita.com/hajimeni/items/73d2155fc59e152630c4
BigQueryで2つのテーブルの共通カラムを取得

## 記事作成の背景

本当は2つのカラムの共通項目を出した後に、
その実行結果の内容のカラムのみを取得するSQLを書こうと思っていました。

ただ、調べていくうちにできそうにもないと感じ諦めました。
カラム取得の方法や共通項目の出し方など、せっかく調べたので記事にしました。


## テーブルの作成

まず2つのテーブルを作成します。
datasetは任意で変更してください。

作成されるテーブルは下記2つです。

![2022-02-17_12h45_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/0faae7af-955f-6ed8-fbe2-4b02096dbe99.png)
![2022-02-17_12h45_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/cd07de64-42a7-c94a-8329-b408a95e4a4d.png)


```sql
CREATE OR REPLACE TABLE `dataset.db1`
(list_no string,
company_name string,
list_flag int64,
);

INSERT INTO `dataset.db1`
values
('001', '株式会社AAA', 1),
('002', '株式会社BBB', 0),
('003', '株式会社CCC', 1)
```


```sql
CREATE OR REPLACE TABLE `dataset.db2`
(list_no string,
company_name string,
call_count int64,
);

INSERT INTO `dataset.db2`
values
('001', '株式会社AAA', 10),
('002', '株式会社BBB', 5),
('004', '株式会社DDD', 6)
```



## 2つのテーブルの共通項目のみ取得


カラム名の取得方法
https://cloud.google.com/bigquery/docs/information-schema-tables

共通項目の取得方法
https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#intersect_example


```sql
SELECT
 column_name
FROM
 `pj_name`.dataset.INFORMATION_SCHEMA.COLUMNS
WHERE table_name = "db1"
INTERSECT DISTINCT
SELECT
 column_name
FROM
 `pj_name`.dataset.INFORMATION_SCHEMA.COLUMNS
WHERE table_name = "db2"
```

結果

![2022-02-17_12h51_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/e63ed337-27a1-c995-ffc4-842c91509a50.png)


## 本当はやりたかったこと

上記の共通項目のカラム項目をSELECTで指定することをやりたかったです。
こうやればできるという情報があれば教えて頂けると嬉しいです。
【Project Euler】Problem 88: 積和数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 88.積和数

原文 [Problem 88: Product-sum numbers](https://projecteuler.net/problem=88)

**問題の要約：要素の積と和が一致するような$k$個の自然数の集合で、$k$に対する積和数の最小値をmps(k)としたとき$2 \le k \le 12000$でのmps(k)の合計を求めよ。ただしmps(k)の値が重複するものは数えない**

* 例えば$k = 2,3,4,5,6$の時の積和数の最小値は以下のようになり、その合計は重複する8を除いて30となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/16d259a6-13e4-65a7-c483-b66aec00cb54.png)

さすがに難易度が今まで最高の40%だけあって、難しいです。ポイントとしては、

* $k$に注目して最小値を求めるのではなく、積の因数を並べて積と和を求め、そこから$k$を出すと考えた方が探索しやすい。
* 例でいえば$2 \times 3$のように因数が決まると、以下のようにkも決まる。
    * $P = 2 \times 3= 6, \ \  S = 2+3 = 5$ なのでsを1つ増やすために1を1つ付けると考える。
    * すると$k |\lbrace 2,3,1 \rbrace| = 3$となる
    * 因数をどんどん発生させてkの最小値を更新していく 
* kの値は **K = P - S + Fn** (Fn は因数の数)で与えられる
    * $P = (2 \times 3 )$の例では $k = (2 /times 3) - (2 + 3) + 2  = 3$
* Pが最大になるのは$P = 2 \times 7$のような場合で$ k= 2 \times 7 - (2 + 7) + 2 = 7$となり、Pの最大値は$2 \times k$

そこで$P < 2 \times kmax$ の範囲内で取り得る因数を列挙してkを求めていくというアルゴリズムを考えます。

例えば$kmax$が$12$の時は以下のような感じです。その上で$P=8$と$10$で$k=5$となるので$k=5$の最小値は$P=8$を取るようにします。

```
k= 02, P = 04, [2, 2]
k= 05, P = 08, [2, 2, 2, 1, 1]
k= 12, P = 16, [2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1]
k= 08, P = 12, [2, 2, 3, 1, 1, 1, 1, 1]
k= 11, P = 16, [2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1]
k= 03, P = 06, [2, 3, 1]
k= 04, P = 08, [2, 4, 1, 1]
k= 05, P = 10, [2, 5, 1, 1, 1]
：
```

このような因数の発生を再帰関数で実装します。小さい因数で数を増やしていって$k$が$kmax$を超えたら戻って因数をカウントアップするコードになります。

因数の列挙が出来れば、あとは$k$を計算して$k$の最小値の配列**mps**を更新して、最後に重複を除くために、**set**に変換して合計を取ります。

このコードはなるべく分かりやすさを重視しているので、効率を求めれば改善の余地があります。（PとSは毎回計算している、等）

```python 
import itertools
import numpy as np
from copy import copy

def ps(flist, fn): 
  return np.prod(flist[1:fn+1]), sum(flist[1:fn+1])

def prodsum(flist, fn, f0):
  for f in itertools.count(f0):
    flist[fn] = f
    p,s = ps(flist, fn)  
    k = p - s + fn       # product - sum + fact
    if  k > kmax  or (fn==1 and p*f>kmax*2):
      return 
    if fn >= 2:
      print(f"k= {k:02}, P = {p:02}, {list(flist[1:fn+1])+([1]*(p-s))}")
      if p < mps[k]:  mps[k] = p
    prodsum(copy(flist), fn+1, f)
  return 

kmax = 12
flist = np.array([0]* kmax)
mps = [2*kmax] * (kmax+1)
prodsum(flist, 1, 2)   # d: num of digit, m0: next initial digit
print("Answer : ", sum(set(mps[2:])))
# Answer :  61
```

（開発環境：Google Colab）
その7（6の続きとエスケープシーケンス、ヒアドキュメント）

シングルクォートとダブルクォートの違いについて

<font color="green">変数を展開するか</font>

ダブルクォートは文字列に含まれる変数を解釈し、その値で変数の箇所を置き換える。

そのような処理のことを<font color="red">変数展開</font>または<font color="blue">変数のパース（Parse）</font>と言う。

シングルクォートは変数展開せずそのまま表示される。

前回の例

```
<?php
$title = ‘死霊館シリーズ’;

$data1 = “怖かったホラー映画は「{$title}」です。<br>“;

$data2 = ‘怖かったホラー映画は「{$title}」です。<br>’;

print $data1;
//結果: 怖かったホラー映画は「死霊館シリーズ」です。

print $data2;
//結果: 怖かったホラー映画は「{$title}」です。

```

変数全体を{~}で囲んでいるのは、変数の範囲を明確にするため。

例えば次の例

```
“I am $modifier_man!!”
```

この例では展開すべき変数が　\$modifier なのか　\$modifier_man なのか不明確である。

しかし次のようにすることで分かりやすく表示できる。

```
“I am {$modifier}_man!!”
```

変数の接頭辞である「\$」を前に出して次のように記述しても良い。

```
“I am ${modifier}_man!!”
```

{~}は省略できるが、誤認識によって思わぬ変数展開が行われるのを防ぐ為にもできるだけ省略しない。

ダブルクォートの中で「\$」という文字列そのものを含めたい場合には「\\\$」のようにエスケープする。

<font color="green">エスケープシーケンスを認識するか</font>

PHPではタブや改行など特殊な意味を持ちディスプレイに表示できない文字を「\\文字」の形式で表現できる。

このような文字のことを<font color="red">エスケープシーケンス</font>という。

PHPで利用可能な主なエスケープシーケンス

|エスケープシーケンス|概要|
|:-:|:-:|
|\\r|復帰（キャリッジリターン）|
|\\n|改行（ラインフィード）|
|\\t|水平タブ|
|\\v|垂直タブ|
|\\f|フォームフィード|
|\\$|ドル記号|
|\\\\|バックスラッシュ（円記号）|
|\\”|ダブルクォート|
|\\nnn|3桁の8進数で表された文字|
|\\xnn|2桁の16進数nnnで表された文字|
|\\u{nnnn}|4桁の16進数nnnnで表されたUnicode文字|

これらのエスケープシーケンスを認識できるのはダブルクォート文字列だけ。

シングルクォート文字列では「\\’」（シングルクォート）と「\\\\」（バックスラッシュ）だけが認識され、それ以外のエスケープシーケンスはそのまま表示される。

（逆にダブルクォート文字列では「\\’」は認識されずそのまま「\\’」として表示される）。

文字列リテラルの最後で「\\」と表示させたい場合には、シングルクォートでかかる場合も「\\\\」のように評価する。

```
$str = ‘今日は朝コーヒー作れて今飲んでるけど\’;
//結果: エラー

$str = ‘昨日は飲まなかった\\’;
//結果: 昨日は飲まなかった\
```

単に「\\」と書いた場合には「\\’」がエスケープされてしまい、「終了されていない文字列」とみなされてしまうから。

以上の違いから、基本的には文字列リテラルは<font color="red">シングルクォート</font>でくくるものとし、変数展開やエスケープシーケンスの利用などの意図がある場合にのみ<font color="blue">ダブルクォート</font>を利用するのが好ましい。

<font color="green">ヒアドキュメント</font>

文字列リテラルをあらんすもう１つの方法として、ヒアドキュメントという仕組みがある。
ヒアドキュメントは改行を含むような長い文字列を表すのに適した記法である。

具体例

```
<?php
$str = ‘PHP’;
$msg = <<<EOD
私は今現在仕事をしながら休みの日に与えられたカリキュラムをこなし、エンジニアになる為に日々勉強中です。
仕事は電量販店で接客業を通してコミュニケーション能力を鍛え、休日にはHTMLや{$str}を勉強しています。
EOD;

print $msg;

//結果:

私は今現在仕事をしながら休みの日に与えられたカリキュラムをこなし、エンジニアになる為に日々勉強中です。
仕事は電量販店で接客業を通してコミュニケーション能力を鍛え、休日にはHTMLやPHPを勉強しています。
```

ヒアドキュメントでは「<<<EOD」から「EOD;」までを文字列リテラルとみなす。

「EOD」は文字列の開始と終了を表すためのデミリタ（区切り文字）なので、開始と終了とが対応していれば適当に変更しても構わない。

たとえば、
「<<<CONTENT~CONTENT;」
や
「<<<HOGEHOGE~HOGEHOGE;」
なども正しいヒアドキュメント。

開始/終了文字列は小文字でも良いが、文字列リテラルそのものと識別しやすいように、全て大文字で表すのが一般的。

<font color="red">開始文字列によって、文字列の解釈が変化する点にも要注意</font>

ヒアドキュメントで使える開始文字列

|開始文字列|意味|
|:-:|:-:|
|<<<EOD|文字列に含まれるエスケープシーケンスを展開|
|<<<“EOD”|文字列に含まれるエスケープシーケンスを展開（上と同じ）|
|<<<‘EOD’|文字列に含まれるエスケープシーケンスを展開しない|

いわゆるダブルクォート文字列とシングルクォート文字列の違い。
先ほどの例を「<<<‘EOD’~EOD」に置き換えると

```
<?php
$str = ‘PHP’;
$msg = <<<‘EOD’
私は今現在仕事をしながら休みの日に与えられたカリキュラムをこなし、エンジニアになる為に日々勉強中です。
仕事は電量販店で接客業を通してコミュニケーション能力を鍛え、休日にはHTMLや{$str}を勉強しています。
EOD;

print $msg;

//結果:

私は今現在仕事をしながら休みの日に与えられたカリキュラムをこなし、エンジニアになる為に日々勉強中です。
仕事は電量販店で接客業を通してコミュニケーション能力を鍛え、休日にはHTMLや{$str}を勉強しています。
```

変数\$strが展開されずにそのまま表示されていることが確認できる。

ダブルクォート文字列、シングルクォート文字列と異なる点は、いずれの構文を利用した場合にも、ヒアドキュメントでは自由に（エスケープ処理することなく）クォート文字を含める事ができると言う点。

（正確には「<<<‘EOD’~EOD;」の構文はヒアドキュメントとは区別して<font color="red">NowDoc構文</font>と呼ばれる。）

<font color="green">次回　インデントの除法</font>
[Vue3] onMounted is called when there is no active component instance というエラーに悩まされたけど簡単な原因だった

# onMountedが実行されない

Vue3 で開発していて下記のエラーに遭遇しました。

>runtime-core.esm-bundler.js:38 [Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.

DeepL翻訳さん曰く

>onMountedは、関連付けるアクティブなコンポーネントインスタンスが存在しない場合に呼び出されます。ライフサイクルインジェクションAPIは、setup()の実行中にのみ使用することができます。非同期 setup() を使用している場合は、最初の await 文の前にライフサイクルフックを登録するようにしてください。

# 原因はシンボリックリンク

ライブラリの開発中に、distフォルダをプロジェクトにコピーするのが面倒になり、
**「そうだ！ distフォルダのシンボリックリンクを置けばいいんじゃね？」**
という浅い考えでシンボリックリンクを作成しました。

それまでに別のエラーが発生していたので新たなエラーが発生してもスクリプトに原因があると勘違いし、しばらくコンパイル環境まで疑ってましたｗ

普通に distフォルダをコピーしたら問題は解決されました。

なぜそれがライフサイクル問題になるのかは不明です。
PythonでCSVを読み込む方法

#概要
PythonでCSVを読み込む方法について、調べたので共有します。

#事前準備
サンプルでは、下記のコードを記述した.pyファイルと同階層に、「test.csv」を配置。
中身は以下です。

```

aaaa,1,10,100
bbbb,2,20,200
cccc,3,30,300

```

#コード
上記のファイルを読み込むコードは以下になります。

```

# CSVを読み込むためのモジュールをインポート
import csv

# withを使ってopenすることで、closeし忘れを防ぐ
# このスクリプトと同階層にあるtest.csvを開く
with open("./test.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    # rowにはcsvの一行分がlistで格納されている
    for row in reader:
        print(row)

```

#出力結果
```

['aaaa', '1', '10', '100']
['bbbb', '2', '20', '200']
['cccc', '3', '30', '300']

```
AZ-900 合格体験記

先日、Microsoft Certified: Azure Fundamentals（AZ-900）に合格しました。
本記事では、資格取得までの流れを紹介したいと思います。

##はじめに

まず、受験前の私の知識レベルは以下の通りです。
・AWS Certified Solutions Architect – Associate　所持
・Azureの実務経験　3ヶ月

AWSのSAAを取得していたので、クラウドに関する知識はある程度ありましたが、Azureの実務経験についてはほんの入り口に触れた程度であったので、サービス名はほどんど知らない状態でした。

##受験までの流れ
受験までの流れは以下の通りです。
　１．Microsoft Azure Virtual Training Day: Azure Fundamentalsの受講
　２．Udemyの問題集でとにかく暗記
　３．AZ-900試験当日


####1.Microsoft Azure Virtual Training Day: Azure Fundamentalsの受講
Microsoft Azure Virtual Training Day: Azure FundamentalsはMicrosoft公式のトレーニングでAzureの基礎知識はもちろんのこと一般的なCloud知識を身に着けることができます。
また、こちらのトレーニングに参加することでAZ-900に無料で受験ができるバウチャーがもらえるので、AZ-900の受験を考えている人はぜひ受けてみてはいかがでしょうか。

こちらのトレーニングの詳細・予約に関して、以下にリンクを載せておきます。

https://www.microsoft.com/ja-jp/events/top/training-days/azure?SilentAuth=1&wa=wsignin1.0&activetab=a1:primaryr4

####2.Udemyの問題集でとにかく暗記
私はAZ-900の勉強に以下の問題集を使用しました。

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

この問題集は模擬問題が7回分計430問と多くの問題量があります。
質としては、問題一つ一つに解説があるので十分理解できると思います。
私は4周して全模擬問題正答率100％になるまでやりこみました。
ポイントとしては選択問題特有のあれこれどっちだっけ。。。などが起きないくらいにやりこむのが大事かと思います。また似たようなサービスは違いを明確にしたうえで重点的に覚えましょう。

こちらの問題集を勉強で使用して試験に臨んだところ、
試験では「似たような問題を見たぞ」って何度も思いました。

####3.AZ-900試験当日
私はAZ-900をピアソンVUEで自宅からオンラインで受験しました。
以下、私がピアソンVUEでの受験で躓いた点です。

ピアソンVUEでのオンライン受験では試験以外のサービスを落とさなければなりません。ここで私の場合、開いているウィンドウはすべて落としていたのですが、バックグラウンドで動くサービス(ircamsrv.exe)によりエラーが出てしまいました。
そこでバックグラウンドで動くサービスの停止手順を以下に記載しておきます。

手順
１．[スタート]を右クリック
２．[コンピュータの管理]→[サービスとアプリケーション]→[サービス]の順でクリック
３．ピアソンVUEで警告の出ているサービスを右クリックし[停止]をクリック

試験に関して
私は試験を20分ほどで解き終わり835/1000(合格点700)で合格しました。
わかりづらい問題は多少ありましたが、Udemyで基本は全て押さえてあるので焦ることはありませんでした。

##最後に
AZ-900の合格過程で詰め込んだ知識を忘れないうちにハンズオンやさらに上のAZ-104の合格を目指すことによって身に着けていけたらと思っています。
３０代初心者インフラエンジニアが知っておくべきWindowsの機能

#タスクスケジューラの履歴が無効
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/aa3aaa58-da0b-89b8-893b-3caee161ada2.png)
#右側のすべてのタスク履歴を有効をクリック
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/fd913b02-dce1-df5b-f958-4cb2089bf790.png)
GradleやMavenとは

# Springプロジェクト作成時の選択項目
Springプロジェクト作成の時いつも
「GradleかMavenか」
を選ぶことになります。一体なんのことなんでしょうか。

そもそもSpringプロジェクト作成の時に選ぶ選択項目のほとんどを理解してない私ですが、
「最初Gradleで作成したら上手くいかなくて、Mavenにしたら動いた！」
と言うこともあったので調べておこうと思いました。

# サーバ起動と同時にコンパイルしてくれる便利なやつ
正体はJavaクラスからJARファイルやWARファイルを作成してくれるコンパイラーです。
https://tech-lab.sios.jp/archives/9500

Mavenの特徴はXMLファイルでビルドの手順を記述することです。
ビルドにMavenを選択した際は、pom.xmlというファイルが作成されるので、そこに必要なライラブリを記述します。
ビルドを実行するとここに記述されたライラブリをMavenリポジトリからダウンロードしてくれるのです。

GradleはMavenほど有名ではありませんが
最近人気になってきているようです。

これについては後日記述。
VSCodeのMDN reference"のみ"非表示にする

2021年2月リリースのバージョン1.54でMDNのreferencesを非表示にする設定が追加された。
hoverはtrueのままMDN referenceのみを非表示にできるため、
他に使っている拡張機能を邪魔せずに使える。これを待っていた。
今までホバーしたときの表示が邪魔に感じたところがこれで快適にcssが書けるようになります。


設定 command + ,
以下をそれぞれ検索する
```css.hover
less.hover
html.hover
```

チェックを全て外したら完了です。


![スクリーンショット 2022-02-17 11.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1947634/f80045e7-8432-41c4-6d4f-325e4acfc8e5.png)
![スクリーンショット 2022-02-17 11.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1947634/082c1f08-6f27-e665-05c4-6b3a4c8a9e24.png)
![スクリーンショット 2022-02-17 11.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1947634/a4222e0e-24b8-a523-f215-80f5222bd754.png)



引用
> Hovers in CSS/LESS/SCSS and HTML#
You can now fine-tune the content of hovers in HTML and CSS to:

> Not show the documentation from MDN
Not show the link to the MDN page
Use the settings css.hover.documentation and css.hover.references to change the hovers for CSS. Replace css with html, css, scss or less to change the settings for those languages.




https://code.visualstudio.com/updates/v1_54


https://github.com/microsoft/vscode/commit/d33b89256ea4f29143edde8836ddf631eda7308c
40 代おっさん GASのメソッドを学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## メソッドとは

メソッドとは
関数が格納されたプロパティのこと
オブジェクトの要素として関数を持たせた場合はメソッドと呼ぶ

構文

```javascript
メソッド: function (仮引数1, 仮引数2, ...) {
  //処理
}
```

メソッドは以下の書式で呼び出すことが可能

```javascript
オブジェクト.メソッド(引数1, 引数2, ...)
```

＊メソッドの場合はドット記法で呼び出すのが一般的

お試し

```javascript
function toshiki() {
  const like = {
    tosikiLike: function() {
      return '利樹大好き';
    }
  };

  console.log(like.tosikiLike());
}
```

## メソッドの追加

メソッドも代入ができる。
オブジェクトに存在しないメソッドを代入すると追加になる。

構文

```javascript
オブジェクト.メソッド = function (仮引数1, 仮引数2, ...) {
  //処理
}
```

お試し

```javascript
function toshiki() {
  const like = {
    tosikiLike: function() {
      return '利樹大好き';
    }
  };

  like.tosikiMikan = function() {
    return 'みかん好きです';
  }

  console.log(like.tosikiLike());
  console.log(like.tosikiMikan());
}
```

## メソッド定義

コード量が多くなり、見づらくなるため
簡略化して記述できるメソッド構文が用意されている。

構文

```javascript
メソッド (仮引数1, 仮引数2, ...) {
  //処理
}
```

お試し

```javascript
function toshiki() {
  const like = {
    tosikiLike() {
      return '利樹大好き';
    }
  };

  console.log(like.tosikiLike());
}
```

## 参考資料

https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52
Flexbox　gapでかんたん余白指定


# はじめに
今までFlexboxを使ったレイアウトで余白をつけるときには、marginを使ってましたがgapを使って余白をつけるというやり方を知ったので備忘録としてまとめました。

# gapとは
CSSのプロパティのひとつで行や列の間の余白を指定するものです。

以前はGridでのみ使えるものでしたが、今はFlexboxでも使えて主要ブラウザでも対応されているとのことです。
※IEは非対応

Flexbox gapの対応ブラウザ
https://caniuse.com/?search=gap

# 実装例
こんなレイアウトを組む場合を例に説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075212/c5a93bbd-4fbb-d576-d491-2fb1297913f1.png)

（今回もたくさんの癒しを提供してくれた先輩、、ありがとうございます！！）

## marginを使った余白指定
今まではmarginを使って以下のように余白指定していました。
```scss
  .news-list {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: -5%;
    @media screen and (max-width: 767px) {
      flex-direction: column;
    }
  }
  .article {
    width: 30%;
    margin-right: 5%;
    padding-bottom: 5%;
    @media screen and (max-width: 767px) {
      width: 100%;
      padding-bottom: 8%;
      margin-right: 0;
    }
    &:nth-child(3n) {
      margin-right: 0;
    }
  }
```

まず、列に余白をつけるために`margin-right: 5%;`をつけています。
こうすると不要なところにも余白がついてしまう（今回は3列のレイアウトなので3つ目の要素の右側に余白は不要）ので、`nth-child(3n)`（3の倍数）に`margin-right: 0;`をつけることで余白を調整しています。

次に行の余白は`padding-bottom: 5%;`をつけています。
こうすると全部の行にpadding-bottomがついて最後の行に不要な余白がでてくるので、.news-listに`margin-bottom: -5%;`をつけて余白を調整しています。

**全体のソースコード**
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="jOaGGjx" data-user="mgkita" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mgkita/pen/jOaGGjx">
  Untitled</a> by chisato (<a href="https://codepen.io/mgkita">@mgkita</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


わざわざネガティブマージンをつけたりマージンを0にしたり、こういうのを書かなくていいやり方、、それがgapです！

## gapを使った余白指定
```scss
  .news-list {
    display: flex;
    flex-wrap: wrap;
    gap: 45px 5%;
    @media screen and (max-width: 767px) {
      flex-direction: column;
    }
  }
  .article {
    width: 30%;
    @media screen and (max-width: 767px) {
      width: 100%;
    }
  }
```

`gap: 45px 5%;`で行と列の余白を指定しています。
左側が`row-gap`（行）、右側が`column-gap`（列）の値となってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075212/9a35d08f-5068-9f50-6395-c1c4e32f4467.png)


marginで余白とるより、すっきりした記述になりました！

**全体のコード**
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="RwjjogX" data-user="mgkita" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mgkita/pen/RwjjogX">
  Flexbox gap</a> by chisato (<a href="https://codepen.io/mgkita">@mgkita</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# おわりに
不要な記述が減るgapですが、サポートがSafari 14.1以降だったり新しめなので注意して使用する必要があります。

また、こういうタイル状のレイアウトはGridを使う方法もあるので、それはまたの機会に記事にしたいと思います。
javascript57_メソッド

オブジェクトの属性値はどんなデータ型でもOKです。関数にすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/15257bdd-df49-08d7-d8d3-23769e94d4a5.png)
関数はオブジェクトの属性とも言えます。
一つの関数をオブジェクトの属性として保存する場合、
その関数を該当オブジェクトのメソッドと言います。
開発中に、関数内の属性がわからない時はたくさんあります。
その時にはfor in 処理で属性を確認することができます。
構文：　for(var変数　in オブジェクト）{
       }
オブジェクト内に属性の数に応じて、繰り返される回数が決める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/f5f6bfac-48c7-c7da-c7d6-2e6c5e189d4a.png)
属性値を確認する方法：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/e304d482-12c8-c99b-509a-76ea31b16e88.png)
Rubyのハッシュロケット記法{ :key => value } を{ key: value } に一括で修正する方法（erubis, hamlも含む）

## Rubyファイル

Rubyファイルの場合、rubocopのコマンドで一気になおせます
（rubocop のインストールは `gem install rubocop`）

`rubocop --only Style/HashSyntax -a`

`-a` オプションが自動適用なので、これを外すとどのように修正されるかを確認することができます

## erubis ファイル

erubisファイルの場合、[erb-lint](https://github.com/Shopify/erb-lint)を使う必要があります。
(インストールは `gem install erb_lint`)

以下のような yaml を `~/.erb-lint_only_hash_syntax.yml` として定義し

```yaml
---
glob: "**/*.{html,text,js}{+*,}.{erb,erubis}"
EnableDefaultLinters: false
linters:
  Rubocop:
    enabled: true
    only:
      - Style/HashSyntax
```

views 以下にerubisファイルがある場合は、以下のようなコマンドを実行します

`erblint --config ~/.erb-lint_only_hash_syntax.yml -a views/**`

`-a` オプションが自動適用なので、これを外すとどのように修正されるかを確認することができます

## haml

ruby, erubis のような便利なコマンドがないので、正規表現でなおします

`:([_a-z]+)\s*=>` -> `$1: `

## 参考：Ruby, rubocop, erb-lint のバージョン

記事執筆時で利用しているバージョンを書いておきます

```
$ ruby -v
ruby 2.6.9p207 (2021-11-24 revision 67954) [x86_64-linux]
$ rubocop -v
1.25.1
$ erblint -v
0.1.1
```
javascript56_即実行される関数

関数が定義された後、すぐに呼び出される。
基本的には１回しか使いません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/e5ea49de-e782-04bf-e941-8b895cef8ac1.png)
また、即実行関数に引数を定義することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/41be50a1-e8a1-9ccf-39ff-7bf950a341c5.png)
40 代おっさん GASのスコープを学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## スコープ

変数や定数には、どこからそれらからを参照できるかという範囲が定められている。
そのことをスコープと呼ぶ

### グローバル領域

```javascript
console.log('利樹君です！');

function toshiki() {
  console.log('利樹はかわいいです');
}

console.log('利樹はとてもかわしいです。');
```

これを実行したとします。
ログ情報は
16:49:30	情報	利樹君です！
16:49:30	情報	利樹はとてもかわしいです。
16:49:30	情報	利樹はかわいいです
この順番になったと思います。

つまりfunction toshiki()が一番最後に実行されたのです。
function toshiki()の外はグローバル領域と言われ、関数より先にステートメントが先に実行されるのです。

次に

```javascript
function toshiki() {
  console.log(`${calcArea_(3, 4)}`);
  const calcArea_ = (x, y) => x * y;
}
```

これを実行すると
ReferenceError: Cannot access 'calcArea_' before initialization
とエラーコードが出ます。
これはcalcArea_ が関数呼び出しが先に行われたことにより発生しました。

```javascript
function toshiki() {
　const calcArea_ = (x, y) => x * y;
  console.log(`${calcArea_(3, 4)}`);
}
```

こちらだと普通に動くと思います。

グローバル領域を多用すると順序が分かりずらくなるので、特定のファイルにまとめて行うなどの工夫をするといいみたいです。

### スコープの種類

グローバルスコープ　プロジェクト全体から参照できる
ローカルスコープ　  特定の範囲のみから参照できる
関数スコープ　      宣言された関数の内部からのみ参照できる
ブロックスコープ　  宣言されたブロックの内部からのみ参照できる

### ブロック

ステートメントをグループ化したもの

構文

```javascript
{
  //処理
}
```

## 参考資料

<https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52>
CoreMLの画像出力をプレビューできるようにする

#ファイルだけでプレビューできるようにする方法です

![スクリーンショット 2022-02-17 10.49.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f0dc7473-05d1-aa27-d2bd-84b524cfb367.png)

#画像プレビューはどうやるの？
CoreMLの出力を画像タイプにすると、ファイルを開いたときにプレビュータブが現れ、プレビューできるようになります。
しかし、画像をドロップしてみると、インディケーターが回り続けてStylized画像が表示されない場合や、
ノイズのような画像が表示されるなど、うまくプレビューできない場合があります。
何が間違っているのでしょうか？

#画像の出力形状の並べ替えや非正規化が必要

例えば、モデルの出力形状が[1,256,256,3]の場合、
CoreMLファイルがプレビューできるRGB画像の形状は[3,256,256]なので、形状を並べ替える必要があります。

```swift
spec = mlmodel.get_spec()
builder = ct.models.neural_network.NeuralNetworkBuilder(spec=spec)
builder.spec.description

builder.add_permute(name="permute",dim=[0,3,1,2], input_name={output name in printed description}, output_name="permute_out")
```

そして、最初の１の次元は必要ないので、削ります。

```swift
builder.add_squeeze(name="squeeze", input_name="permute_out", output_name="squeeze_out", axes = None, squeeze_all = True)
```

これで、出力形状がCoreMLでプレビューできる形になります。

また、モデルの出力が−１〜１の範囲の場合、１〜２５５の色範囲に非正規化する必要があります。

```swift
builder.add_activation(name="activation",non_linearity="LINEAR",input_name="squeeze_out",output_name="image",params=[127.5,127.5])
```

最後に、追加したアクティベーション層の出力を画像に指定します。

```swift
from coremltools.proto import FeatureTypes_pb2 as ft
builder.spec.description.output.pop()
builder.spec.description.output.add()
output = builder.spec.description.output[0]
output.name = "image"

output.type.imageType.colorSpace = ft.ImageFeatureType.ColorSpace.Value('RGB')
output.type.imageType.width = 256 
output.type.imageType.height = 256
```

これで、プレビューできるようになります。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。
PHP Stormでtailwindの補完が効かないバグ?

npx create-nuxt-app で作った新規プロジェクトでtailwindのインテリセンスが効かないバグに遭遇した。

プラグインにはtailwindの補完が入っているのになんでだろうとハマりました。

幸い動いているプロジェクトが他にあったので、そこからtailwind.config.jsonをコピーして問題のプロジェクトフォルダに貼り付けました。
tailwind.config.json内の赤線ランプマークからインポートしているライブラリをインストール。
その後、プロジェクトだけじゃなくてphpstorm自体を閉じて、再起動したら補完できるようになりました。

バグというより、tailwind.config.jsonがないと補完できない仕様なのかもしれません。
あとtailwind.config.jsonはphpstormかプロジェクトの読み込み時に１回だけ読まれている？
【Java】Stream APIの使い方

## はじめに
先輩エンジニアの方から学んだ方がいいとアドバイスをもらいStream APIについてキャッチアップをしました。
なんだか難しく聞こえますが、使ってみると意外と簡単なので忘備録を兼ねまとめています。

## Stream APIとは？

Java8で導入された配列やCollectionなどを扱い、値の集計やデータを使った処理などができる便利なAPIのこと。

これだけではあまりイメージが湧かないので、**for文で記述していた処理をシンプルに記述できる便利機能**と覚えておけばOK！

## for文とStream APIの比較

今回は「**1から5までの整数の中から偶数を取得する処理**」をfor文とStream APIを利用して実装する。

```java
import java.util.Arrays;
import java.util.List;

public class StreamTest {
	public static void main(String[] args) {
		
		// 1から5までの整数
		List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5);
		
		// for文を利用した処理
		for (Integer num : numList) {
			if (num % 2 == 0) {
				System.out.println(num);
			}
		}
		
		// Stream APIを利用した処理
		numList.stream() // Streamを生成
			.filter(i -> i % 2 == 0)　 // numListの中から該当する値のみを取得
			.forEach(i -> System.out.println(i)); // 上記で該当した値のみを出力する
		
	}
}
```

## Stream APIを使うメリット

### ◎可読性の高いコードを実装できる

上記の実装の通り、for文ではどのような処理かぱっと見わからない。

一方、Stream APIを使った処理は、Streamが保持するメソッドで**処理を宣言してから条件を記述**しているため、どんな処理が行われるのか分かり易いというメリットがある。

また、コード量も減らすことができるのでリーダブルなコードにするのに適している。

その他にもメリットはあるようですが、自分が感じたメリットはこれだけだったので割愛します。。。

## Stream APIの実装方法
![スクリーンショット 2022-02-17 9.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516225/8bad7521-db8f-e106-6609-69e5a3546f4a.png)

### 1ステップ：Streamの生成
配列やListに対して**.stream()**でStreamを生成する。
Streamを生成することで、データの変換や加工が可能になる。

```java
// 上記の例のnumListを参考にstreamを生成
numList.stream()
```

### 2ステップ：中間操作
1ステップ目で生成したStreamに対してデータの変換や加工を行う。
中間操作にはデータをの変換や加工を行うメソッドが複数用意されている。
中間操作は複数記述が可能。また、省略することもできる。

```java
// 中間操作のメソッドを一部抜粋

// sortedメソッド
.sorted() // 昇順にする
.sorted(Comparator.reverseOrder())　// 降順にする

// filterメソッド
.filter(i -> i % 2 == 0) // 条件に合ったデータのみを取得する
												 // iは一時変数のためnumでも好きなものでOK

// limitメソッド
.limit(3) // 引数の値分データを取得する（今回の場合3つ分のデータを取得する）
```

### 3ステップ：終端操作
2ステップ目で加工した結果を操作する。
中間操作同様メソッドが複数用意されている。
終端操作は省略ができない。

```java
// 終端操作のメソッドを一部抜粋

// forEachメソッド
.forEach(i -> System.out.println(i)); // 拡張for文同様、要素を繰り返し出力する

// collectメソッド
.collect(Collectors.toList()); // データを扱いやすいStreamの形に変換していたため、元のListに戻す
```
## さいごに
Stream APIを実際に使ってみて、コード量を減らすだけでなく、ぱっと見てなんとなく理解できるコードを感動しました。
皆様の参考に少しでもなれたら嬉しいです。

## 参考
https://www.casleyconsulting.co.jp/blog/engineer/191/
https://qiita.com/takumi-n/items/369dd3fcb9ccb8fcfa44
javascript53_return

returnの値は関数の実行結果です。
構文：　return 値；
値を受け取るために一つの変数を定義することができます。

注意：return後の処理は実行されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/d2a3c994-afdf-4bda-4a72-dca921dbea8b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/ea9bfbdb-3965-52df-2138-e190189c7328.png)
docker-compose up時にUnixHTTPConnectionPool(host='localhost', port=None): Read timed out.エラーが発生

docker-compose up -dでアプリケーションを起動しようとすると以下のエラーが発生。

```
Starting date_course_db_1 ... 
Starting date_course_frontend_1 ... 

ERROR: for date_course_frontend_1  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for date_course_db_1  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for frontend  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for db  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
```

調べてみるとDockerforMacが原因で起こるエラーみたいです。

![スクリーンショット 2022-02-17 10.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571061/77e7cedb-1e21-a5b6-74a7-a0eb713a4cd4.png)

なのでDockerのDawhboardを再起動しました。

```
Starting date_course_db_1       ... done
Starting date_course_frontend_1 ... done
Creating date_course_backend_1  ... done
```
無事に起動することができました。
"git pull"と"git pull origin main"の挙動の違い

基本的なことを備忘録として残しておく。

- git pull (mainブランチで実行)
    - 全てのリモートの変更をもってきてリモートのmainブランチの情報をローカルのmainブランチにマージ
- git pull origin main (mainブランチで実行)
    -  リモートのmainブランチの変更情報だけを持ってきてローカルのmainブランチにマージ
- git pull (main以外のブランチで実行)
    -  全てのリモートの変更をもってくるだけでローカルのどこのブランチにもマージはしない
javascript52_関数の引数

関数の（）内に、一つまたは複数の引数を指定することができます。（形式引数）
引数と引数の間は,を入れる。
引数を宣言するとは、該当する変数を宣言したと同じです。
関数の形式引数に値を代入しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/d81846c2-f991-0859-aacb-b24b6fe02b86.png)

関数を処理する時、実行するブラウザは代入する実引数の種類と
数をチェックしません。
実引数の数が形式引数の数より少ない場合、対応する実引数のない形式引数の値はundefinedです。
関数の実引数にデータ型の制限はありません。
homebridge-gshをhomebridge-config-ui-xを介さずに使う

# 経緯
Google Homeからhomebrideを扱うにはhomebridge-gshをインストールする必要があります。githubにあるhomebridge-gshの[README](https://github.com/oznu/homebridge-gsh#readme)を見てみるとhomebridge-config-ui-x(以下ui-x)を介してgoogleまたはgithubのアカウントと紐づけているようです。しかし、現在私はRaspberryPiZeroを使ってスマートホームを構築しており、ui-xを使うには少し非力な気がしています。どうにかui-xを使わずにアカウントを紐づける方法を見つけたのでここに書こうと思います。
#必要なもの
・ウェブ開発者ツールのネットワークモニター(この記事ではFireFoxのものを使用しています)
・homebridge
・homebridge-gsh
・Googleアカウント
#Step 1 (Googleアカウントとの紐付け)
まずはアカウント紐づけに必要なトークンを知る必要があるので、[アカウント紐づけを行うページ](https://homebridge-gsh.iot.oz.nu/link-account)へアクセスします。ウェブ開発者ツールのネットワークモニターを開いたまま、Googleアカウントでログインしてください。ログインし終わったら、ここまでの通信の中に```https://homebridge-gsh.iot.oz.nu/token```とのトランザクションがあるはずです。そのトランザクションの応答(json形式)の```token```キーの値(文字列)が目的のデータなので、どこかに保管しておいてください。(Step2で使います)

```
 token:"xxxxxxxxxx"
```

#Step2 (homebridgeの設定)
Homebridgeのconfig.jsonを書き換えます。場所は環境によって異なると思いますが私の環境では```~/.homebride/config.json```でした。

homebridge-gshはプラットフォームを追加するプラグインなのでplatformsの中に書いていきます。```plarforms```がなければ自分で書き足してください。

```token``` の ```xxxxxxxxxx``` の部分はStep1で取得したものを貼り付けます。

:::note warn
platformsはbridgeと同じ階層に書くようにしてください
:::

```json:config.json
{
    "bridge": {
        "name": "Homebridge",
        "username": "hogehoge",
        "port": 0000,

        "username": "hogehoge",
        "pin": "000-00-000",
        "advertiser": "ciao"
    },

    "description": "<DESCRIPTION>",
    
    "platforms": [
    
        {
               "platform": "google-smarthome",
               "name": "google home",
               "token": "xxxxxxxxxx",
               "notice": "hoge",
       }
   ]
}
```


**各キーの意味について**

| キー       | 型          |説明　　　　  |
|:-----------|:------------|:------------| 
| platform   | String      |値は固定で"google-smarthome"です。|
| name       | String      |任意の文字列です。|
| token      | String      |Step1で取得したものを入力します。|
| notice     | String          |任意の文字列でtokenを漏らさないようユーザーに伝える注意書きです。           |

:::note warn
これらのキーは必須です。必ず追加するようにしてください。
:::



#Step3 (実行)
以下のコマンドを入力して実行します。

```
homebridge -I
```
ログに ```[google home] Connected ```と出れば紐づけは成功です


:::note warn
オプションの-Iを忘れずにつけてください。こうすることでhomebridge-gshがhomebridgeに追加されているデバイスにアクセスすることができるようになります。
:::

#Step4 (完了)
あとはgoogle homeアプリをインストールしてGoogleと連携ボタンからhomebridgeを選択すれば快適なスマートホーム生活が待っています。(外出先からも操作できて結構便利です)

#参考
https://github.com/oznu/homebridge-gsh#readme
2月17日のコースレビュー

final、finally、finalizeはどのような目的で使用されますか？
final：レタッチされたクラスは継承できません。レタッチされたプロパティは変更できません。レタッチされたメソッドはオーバーライドできません。
finally：try and catchでは、最終的に実行されることを意味する。
Finalize：オブジェクトのガベージコレクター、プログラマーの操作なしで自動的にリサイクルできる

String、StringBuffer、StringBuilderの違いは何ですか？
String：文字列を作成しているとき、それは多くの役に立たないオブジェクトを作成する。そして、頻繁に文字列をつなぎ合わせた後に多くのメモリを占有する。
StringBuffer：appendメソッド「文字列のスプライシング（splicing）、1つのオブジェクトのみ」スレッドはセーフ、低速
StringBuilder：appendメソッドがある、スレッド-安全ではない、高速
Java系バージョン対応表

JRE仕様とクラス形式のバージョン対応表

| JRE | class |
|----:|------:|
| 1.6 | 50.0  |
| 1.7 | 51.0  |
| 1.8 | 52.0  |
| 9   | 53.0  |
| 10  | 54.0  |
| 11  | 55.0  |
| 12  | 56.0  |
| 13  | 57.0  |
| 14  | 58.0  |
| 15  | 59.0  |
| 16  | 60.0  |
| 17  | 61.0  |

Apache TomcatとServletのバージョン対応表

| Tomcat | Servlet |
|-------:|--------:|
| 6.x    | 2.5     |
| 7.x    | 3.0     |
| 8.x    | 3.1     |
| 9.x    | 4.0     |
| 10.x   | 5.0     |
javascript51_関数

関数も一つのオブジェクトです。
そのため、オブジェクトの特性について関数は全部あります。
関数は後で呼び出されることはできます。

関数例：
var fun = new Function();
この書き方はほぼ使わない。
console.log(typeof fun);
結果としてfunctionが返される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/766ff315-c02d-435b-231e-a2b2d7237b5d.png)
関数は呼ばれた時だけ実行される。
関数を呼ぶ方法：　関数対象（）

＊関数の一般的な書き方は下記です。
function 関数名（引数1,引数2....){
　　処理；
}
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/0b4ebe38-8173-6d71-cae7-3da110d4dc12.png)

＊書き方３
var 関数名 = function(引数1,引数2...){
   処理；
}

例：
var fun3　= function(){
   console.log("私は匿名の関数です");
};
fun3();
Model.model_name.humanなどについて

## いつ使うのか
Model.model_name.humanはいつ使われるのかというとI18nと呼ばれる国際化をする際に使われます。
実際にこのように書かれています。
config/locals/ja.yml
```
ja:
  activerecord:
    errors:
      models:
        user:
          attributes:
            name:
              blank: "が空になっています。入力してください。"
            email:
              blank: "が空になっています。入力してください。"
    models: 
      user: "会員"
    attributes:
      user:
        name: "名前"
        email: "Eメール"
```
このようにすることで、エラーメッセージ等の文言を日本語化することができるんです。
models階層の文字列を取得するには、
```
User.model_name.human
=> 会員

I18n.t("activerecord.models.user")
=> 会員
```
attribute階層の文字列を取得するには
```
User.human_attribute_name :email
=> Eメール

I18n.t("activerecord.attributes.user.email")
=> Eメール
```
書き方が似ているようで微妙に違うので、わからなくなったら当記事を参照してください
以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

https://pikawaka.com/rails/i18n

https://railsguides.jp/i18n.html

https://qiita.com/yshr04hrk/items/cb7b81c104321f660661

https://techracho.bpsinc.jp/kotetsu75/2019_09_26/80592