OmniAICreator/Qiita-1.07M huggingface dataset:
GASでスプレッドシートを扱うときに分割代入が使えることを知りました。

このような表があります。


![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/f9a560e4-f006-2e42-e360-da5b3c518a6f.png)

1行ずつの情報を出力するときに、こんな感じでやってました。

```js
function sample1() {
  const data = SpreadsheetApp.getActive().getDataRange().getValues();
  data.shift();

  for(const row of data){
    const id    = row[0];
    const name  = row[1];
    const price = row[2];

    console.log(`ID:${id} の ${name} は ${price}円 です`);
  }
}
```

ログ出力結果

```
ID:100 の えんぴつ は 50円 です
ID:200 の けしごむ は 60円 です
ID:300 の ノート は 70円 です
```

でも、今回こんな回答を教えてもらって、ワタシ的に衝撃だったので共有します。

```js
function sample2() {
  const data = SpreadsheetApp.getActive().getDataRange().getValues();
  data.shift();

  for([id, name, price] of data){
    console.log(`ID:${id} の ${name} は ${price}円 です`);
  }
}
```

forの中がコンパクトになりました。


```js
for([id, name, price] of data){
```

↑ こんなことできるんだね！！

確かに「分割代入」という言葉は知っていたのですが、こういうときに使えるのかと。

参考: [分割代入 \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
ActiveHashからnameが取得できなかった原因

##ActiveHashからnameが取得できなかった原因

### 結論

取得の際に、カラム名.name(例:subject_id.name)と書かずに、モデル名.name(例:subject.name)と書かなければいません。

ダメな例
`<td><%= record.subject_id.name %></td>`

良い例
`<td><%= record.subject.name %></td>`
         

###注意点
- カラム名とモデル名を同じにすること。
- 表示を確認する際は、既存のデータの空のデータは消してから確認すること(エラーになりました)
- Activehashに変更した際に、formの型を　f.number_field→f.collection_select　に直すこと。(これでプルダウンメニューになります)


```    <%= form.collection_select :subject_id, Subject.all, :id, :name, {},{class: 'form_fixed'} %>
```

以上です。
初歩的なことですが、困っている方の助けになりますように！

### 参考にさせていただきました
[【ざっくり解説】ActiveHashモデルからnameが取得できない原因と対処法](https://qiita.com/WAKO_program/items/60d07cdead20dff11563)
Nodejs のためになる話、ORMライブラリを使わずにsqlの内部結合

どうもこんにちは、マッスルエンジニアの真です。

今回も有益なお話をさせてもらえたらと思います。


内容はORMライブラリを使わずに内部結合させて、データベースの従属関係もつくっちゃうって
やつです。


早速説明します。



app.get('/staff_shift', wrap(async (req: Request, res: Response, next: NextFunction) => {

//データベースの構成は無視してください
    const staffs: {
        id: number,
        name: string,
        email: string,
        date: number,
        shift:string,
    }[] = await <any>pool.query(`
        SELECT 
        user.id AS id,
        user.name AS name,
        user.email AS email,
        staff.data AS date,
        staff.shift AS shift
        FROM user 
        INNER JOIN staff ON (user.id = staff.staffId)
        WHERE 
        staff.year = ? 
        AND 
        staff.month = ? 
        AND 
        staff.check = ?
    `, [2021, 2, true]);
    const formattedStaffs: {
        id: number,
        name: string,
        email: string,
        shifts: {
            date: number,
            shift:string,
        }[]
    }[] = [];
//この下からが肝かなと、、、、
    staffs.map(staff => {
        const exist_data = formattedStaffs.find(v => v.id === staff.id);
        if (exist_data) {
            exist_data.shifts.push({
                date: staff.date,
                shift:staff.shift,
            });
        } else {
            formattedStaffs.push({
                id: staff.id,
                name: staff.name,
                email: staff.email,
                shifts: [
                    {
                        date: staff.date,
                        shift:staff.shift,
                    },
                ]
            });
        }
    });
    res.json({staffs});
}));

コードだけ記載するので、もし質問、ご指摘、こんなやりかたもあるよというかた
ぜひおしえてください！

それでは
CentOS7 Slackをインストールする

# 目的

- CentOS7にSlackをインストールする方法をまとめる

# 方法

1. 下記にアクセスする。
    - [https://slack.com/intl/ja-jp/downloads/linux](https://slack.com/intl/ja-jp/downloads/linux)
1. 「.RPM（64ビット）をダウンロード」をクリックする。

    ![Linux___ダウンロード___Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b07bc308-b21e-8e22-0985-548820dfee78.png)

1. ターミナルを開く
1. `$ cd`コマンドを実行してダウンロードディレクトリに移動する
1. 下記コマンドを実行する。（slack-4.12.2-0.1.fc21.x86_64.rpmはダウンロードしたファイルにより異なる。）

    ```terminal
    $ sudo yum install slack-4.12.2-0.1.fc21.x86_64.rpm
    ```

1. 下記のように出力されたらリポジトリを確認してyを入力してEnterを押下する。

    ![UserRepository_php_—_j-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c2e289f3-762d-1875-8c8f-f90fa8286908.png)

1. 「アプリケーション」→「インターネット」にある「Slack」をクリックしてSlackを起動する。
1. 無事にSlackアプリが起動したらインストールは完了である。
Python3: Excelファイル(*.xlsx)  を JSON に変換

## プログラム

```py:xlsx_to_json.py
#! /usr/bin/python
#
#	xlsx_to_json.py
#
#					Feb/02/2021
# ------------------------------------------------------------------
import sys
import pandas as pd
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_xlsx = sys.argv[1]
file_json = sys.argv[2]
sys.stderr.write(file_xlsx + "\n")
sys.stderr.write(file_json + "\n")
#
df=pd.read_excel(file_xlsx,header=None)
#
df.to_json(file_json,orient='records')
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## 実行例

```bash
./xlsx_to_json.py cities.xlsx cities.json
```

コラムを削除するサンプルはこちら
[Python3: Excelファイル(*.xlsx) を JSON に変換 （コラムを削除）](https://qiita.com/ekzemplaro/items/b0468c39a6b9ec39a7f4)

## 確認したバージョン

```text
$ python
Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> pandas.__version__
'2.1.4'
```
elmを使って統計ライブラリを作って実際にそれを利用するまで。-第二話　確率-

# 確率について

統計にとって確率は避けて通れない話です。判断が行われるときはデータが手に入る確率に基づいて行われるからです。
[統計学入門](https://www.amazon.co.jp/%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80-%E5%9F%BA%E7%A4%8E%E7%B5%B1%E8%A8%88%E5%AD%A6%E2%85%A0-%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E6%95%99%E9%A4%8A%E5%AD%A6%E9%83%A8%E7%B5%B1%E8%A8%88%E5%AD%A6%E6%95%99%E5%AE%A4/dp/4130420658/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80&qid=1612304349&s=books&sr=1-1)にはこう書いてあります。
> カードのマークの赤、黒を言いあてられるという。(中略)その能力を試した時、52枚中、40枚をあてた、この人は偶然あてたというべきだろうか。ここで問題なのは40という数そのものよりも40の**確率論的意味**だろう。

ソースコード：[https://github.com/saburooo/simple-stat](https://github.com/saburooo/simple-stat)
成果物：[https://mysimple-stat.web.app/](https://mysimple-stat.web.app/)

## 階乗計算
階乗とは指定した数字から初めて0になるまで1つずつ引いて出てきた複数の値を一気に掛けていく計算方法です。
複数の集団が一気に並ぶ時に使われ、よく再帰の題材になっているあれです。

```elm
factorial : Int -> Int
factorial n =
    case n of
        0 ->
            1

        _ ->
            n * factorial (n - 1)
```
これを応用した計算が多い印象です。
## 順列
与えられた一つ目の数値の階乗計算を１つ目の数値から２つ目の数値引いた値の階乗計算で割ることで求められます。

```elm
permutation : Int -> Int -> Int
permutation n m =
    factorial n // factorial (n - m)
```
これを求めることで順番を決めて１つの列にした時のパターンはいくらか求められます。

# 組み合わせ
組み合わせは順列と違い並び順を考慮しません、計算の仕方は先程の順列の割る数に１つ目の値から２つ目の値を引いた数の階乗を加えるだけです。

```elm
combination : Int -> Int -> Int
combination n m =
    factorial n // (factorial (n - m) * factorial m)
```
名前通り、どれくらいの組み合わせがあるのかを調べるときに有効です。

## スターリングの公式

本で初めて知ったのですが階乗計算で叩き出す数値によく似た数値を出す方法として知られているみたいですね。これをうまく利用した計算方法を模索していきたいです。

```elm
starling:Int -> Float
starling n =
    let
        loge = logBase Basics.e
    in
        (toFloat n + 0.5) * ( loge (toFloat n)) - (toFloat n) + 0.5 * loge 2 * Basics.pi 
```

今回はここまで。
[javascript] アロー関数について勉強してみた

# アロー関数とは
関数リテラルをよりシンプルにかけるもの。らしい。

## 関数リテラルって？
無名関数、匿名関数とも呼ばれるそう。データ型の一種で、変数に代入が出来る。
書き方はこう。

``` js

var hoge = function(){
  console.log("hogehoge")
};

hoge();
```

ちなみにこの場合、関数の呼び出しを先に書くと怒られる。

``` js
hoge();

var hoge = function(){
  console.log("hogehoge")
};
```

> Uncaught TypeError: hoge is not a function


functionとして宣言しておく方法では怒られない。

``` js

hoge();

function hoge(){
  console.log("hogehoge");
}
```

> hogehoge

この**関数リテラル**を簡単に書けるのが、アロー関数らしい。

# 書き方
これが

``` js
var hoge = function(){
  console.log("hogehoge")
};

hoge();
```


こう！

``` js
var hoge = () => {
  console.log("hogehoge")
};

hoge();
```

`function()`の部分が`()`だけになって、矢印（アロー）`=>`がついていますね。
functionと書かなくて良くなり、多少楽になりました。

他にも引数が一つの場合、括弧を省略できるなどの書き方が出来るようです。

これが

``` js
var hoge = function(a){
  console.log(a);
};

hoge("hello!");
```

こう！

``` js
var hoge = a => {
  console.log(a);
};

hoge("hello!");
```

また、関数の中身が一行だと`{}`も省略可能。

``` js
var hoge = a => console.log(a);

hoge("hello!");
```

あと、return書かなくて良くなる。

``` js
var hoge = a => a*a*a;

console.log(hoge(3));
```
> 27

見やすい・・・？のか？分かりづらくなってきたな・・・。笑

## メリットなど

こんな書き方も出来そう。例えばsetTimeout関数。

これを

``` js
var aisatsu = function(){
   alert("hello!");
}

setTimeout(aisatsu , 2000);
```

こう。

``` js
setTimeout(() => alert("hello!"), 2000);
```

一度しか使わない関数であればこれで良さそうですね。
ちなみに、

``` js
setTimeout(alert("hello!"), 2000);
```

これだと意図したとおりに動きません。最初にalert("hello")を解釈するので、呼び出した瞬間にalertがかかり、後続でalertからのreturn（undefined）が解釈されて、実質
`setTimeout(undefined, 2000);`
を処理していることになります。

まぁ、``setTimeout(alert, 2000, "hello!");``みたいな書き方もありますが。


まだ違和感はありますが書きなれてくると良くわかるようになるようです。
またthisとかpromiseとかコールバックとかちょっと聞きなれない単語がいっぱい出てきているので、しばらくはjavascript頑張って勉強して記事にしていこうと思います。
APIとは

<h1>はじめに</h1>

実際に手を動かしながらAPIの勉強をしていく中で、背景情報も気になったので整理。

<h1>APIとは</h1>
APIとはApplication Programming Interfacesの略であり、アプリケーションやソフトウェアの一部を外部に公開することで、<br/>第三者である開発者が複雑な機能をより簡単に実装できる仕組みのことを指す。

開発者にとっては大変有難いもので、これによって質の高いサービスが一気に増えたんだろうなと理解。

ただ、昔のAPIは同じシステム・言語間でないと連携ができず汎用性が低かったそう。

そこで**WEB API**が登場。

WEB APIはAPI提供者とAPI利用者とのやり取りを**HTTPベース**で可能に。
これによって、異なるプログラミング言語で開発されたアプリケーション間の連携もできるようになった。

つまり、HTTPという共通の通信規約を用いることで、汎用性が一気に高くなったということ（HTTP偉大。）

<h1>WEB APIの利点</h1>

WEB APIの利点は以下のようなものが挙げられる。

・開発の効率化
・セキュリティの向上（大手企業の高いセキュリティ機能を活用することができるため。）
・外部アプリ連携によるUXの向上

APIを使いこなせると、俄然開発が楽しくなる気しかしない。。。がんばろう。

<h1>まとめ</h1>
WEB APIの重要性を改めて認識。
そして、HTTPの偉大さも知る。。
ダブルクォーテーションで囲まれたエリアを取り出す正規表現

SublimeTextでhtmlにインラインで記述されたスタイルを一括削除するときに使用。

```
style="(.*?)"
```
なおSublimeTextの正規表現検索は検索窓左上の「.*」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216609/f4a51632-2423-5171-6483-811273d30e04.png)
manimの作法 その42

#概要

manimの作法、調べてみた。
camera_config使ってみた。

#サンプルコード

```
from manimlib.imports import *

class test(Scene):
	CONFIG = {
		"camera_config": {
			"background_color": "#ffffff"
		},
	}
	def construct(self):
		dot = Dot(color = RED).scale(30)
		self.add(dot)
		self.wait()


```

#生成した動画

https://www.youtube.com/watch?v=0LKercjpRAs

以上。
firebase_admob: ^0.11.0+1を使ったらFlutterがビルドエラーになった話

2021年2月4日

firebase_admob: ^0.11.0+1を使ったらFlutterがビルドエラーなりました！

英語での情報もふくめ色々試しましたが、エラーは解消せず。
firebase_admobのバージョンを下記に下げたらビルドできる様になりました！
firebase_admob: ^0.10.3

下記その時のエラー情報を載せます！
```
* What went wrong:
Execution failed for task ':app:processDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > Android resource linking failed
     /Users/tanakayohei/.gradle/caches/transforms-2/files-2.1/804bb16bf16b5e91bc08a39b6997ce12/play-services-ads-lite-19.6.0/AndroidManifest.xml:27:5-38:15: AAPT: error: unexpected element <queries> found in <manifest>.


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 12s
The built failed likely due to AndroidX incompatibilities in a plugin. The tool is about to try using Jetfier to solve the incompatibility.
Building plugin firebase_admob...
Exception: The plugin firebase_admob could not be built due to the issue above.
Exited (sigterm)
```


Flutterのバージョン

``
Flutter 1.22.6 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 9b2d32b605 (12 days ago) • 2021-01-22 14:36:39 -0800
Engine • revision 2f0af37152
Tools • Dart 2.10.5
```
PDFのコピペからGoogle翻訳のURLを開くPythonスクリプト 

# はじめに
PDF の文章をコピペして Google 翻訳に入力すると文章の途中で改行が入って使いづらいので、コピペした文章内の改行を自動で削除し翻訳の結果を開く簡単なスクリプトを作成しました。

※ターミナル上で長文を表示すると見づらいので、 Google 翻訳の URL を Web ブラウザで開く様にしています。

#動作確認した環境
Python 3.8.6

#Python スクリプト

```url_ggl_trans.py
import webbrowser

head='https://translate.google.co.jp/?sl=en&tl=ja&text=' # 言語の指定
term='&op=translate'
txt='start'
flag=0

while not flag:
    send=''
    print('Input sentences (if finish, press enter twice) -> ')
    while txt!='':
        txt=input()
        if txt == '':
            continue
        txt=' '.join(txt.split()) # 改行の削除
        send=send+txt+' '
    webbrowser.open(head+send+term) # 翻訳用 URL の表示
    if input('continue? (y/n) -> ') == 'n':
        flag = 1
    print()
    txt='start'
    
```

#実行
クリップボードの文章をペーストして Enter を 2 回押すと翻訳ページが開かれます。

```shell-session
python url_ggl_trans.py
Input sentences (if finish, press enter twice) ->
(コピーした文章のペースト)
```

#おわりに
今のままだと翻訳する毎にタブが増えていくので、既に Google 翻訳をブラウザで開いていたらページを更新するなどの機能を追加したいところです。

#追記
Google 翻訳の URL に % などを入力すると別のコマンドとして解釈されてしまうようです。

Google の Translator モジュールを使ってターミナル上で表示すると特殊文字を良しなに扱ってくれるみたいなので、そのスクリプトも書いてみました。

Translator モジュールの導入は[こちらの記事]
(https://qiita.com/_yushuu/items/83c51e29771530646659)を参考にさせていただきました。


```url_ggl_trans_v2.py
from googletrans import Translator

head='https://translate.google.co.jp/?sl=en&tl=ja&text='
term='&op=translate'
txt='start'
flag=0

while not flag:
    send=''
    print('Input sentences (if finish, press enter twice) -> ')
    while txt!='':
        txt=input()
        if txt == '':
            continue
        txt=' '.join(txt.split())
        send=send+txt+' '
    print(Translator().translate(text=send, src="en", dest="ja").text)
    if input('continue? (y/n) -> ') == 'n':
        flag = 1
    print()
    txt='start'
    
```
初心者がdockerでphpの開発環境を整える#2 [dockerをインストールする] 

#dockerをインストールする
docker: ![docker](http://cdn-ak.f.st-hatena.com/images/fotolife/p/portaltan/20150528/20150528170949.jpg "docker")

##dockerをインストールする手順は？
1. [docker](https://www.docker.com/ "docker") の公式サイトにアクセス
2. アカウントを作成
3. Get Startedをクリック
4. Docker Desktopを自分が使っているパソコンに合わせたバージョンをインストール。

詳しくは下記にスクショを用いて案内しています。
これだけでも自分のパソコン内だけでdocker fileを設定して開発環境を整えることができるみたい…

でも、dockerの特徴である、
**「制作データだけではなく、制作環境の基礎設定まで共有することができる。」**
ができません。dockerの機能を最大限に活かしたい方は追加でDocker Hubをインストールしましょう。

##スクショを使って詳しく案内
投稿のデータ制限があるので画像が荒くなってますがご了承ください。
まずは、[docker ( docker.com )](https://www.docker.com/ "docker") にアクセス

1, アカウントをお持ちでない方も、まずはSign inへ
![docker-sign in.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077136/2bdfe731-f01b-5870-a6bd-7566395a3fec.jpeg)

2, アカウントをお持ちの方はそのままログインを、持ってない方はSign Upへ
新しくアカウントを作る方は「ロボットではないです」の質問が英語なので翻訳できる状態にしておきましょう
![docker-sign up.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077136/cf7af13a-40ac-a1ed-a648-2a8705c3d68f.jpeg)

３, どちらでもいいのでGet Startedをクリック
![docker-get started.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077136/9fb75835-6815-355d-0559-462f5b476a48.jpeg)

4, 自分のPCにあったDocker Desktopをインストールしましょう
![docker-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077136/92fffaa3-0736-5a59-0928-79d70bf8edfc.jpeg)


Macの方は外部のファイルですがダウンロードしていいですか？みたいなこと質問されますが、大丈夫です。と許可しましょう。
Windowsの方は~~知りません~~、分からないですが、質問に答えてダウンロードしてみてください。

##次回予告
次回は、Docker Desktopだけでphpを動かしてみたいと思います。
これを書いてる時点で少し勉強してるんですがコマンドが怖すぎて辛いです。
学習中の方、一緒に頑張っていきましょう！

##参考にしたサイト
[Docker のインストール](http://docs.docker.jp/engine/installation/ "Docker のインストール")

Dockerの説明を日本語化してくれているサイトです。
ぜひ一度読んでみてください。

##初心者がdockerでphpの開発環境を整える 一覧
[初心者がdockerでphpの開発環境を整える#1 [dockerとは？]](https://qiita.com/fulu/items/30728918802b6a96520a "dockerとは？")
[初心者がdockerでphpの開発環境を整える#2 [dockerをインストールする]](https://qiita.com/fulu/items/b2c5504278115f440c59 "dockerをインストールする")
[初心者がdockerでphpの開発環境を整える#3 [docker imageの準備方法]](https://qiita.com/fulu/items/b85fa89afc002837510f "docker imageの準備方法")
[初心者がdockerでphpの開発環境を整える#4 [レンタルサーバーでdockerが使えない？]](https://qiita.com/fulu/items/ab599c73354151e8e80a "レンタルサーバーでdockerが使えない？")
Gnome Shellがなんかおかしくなったときの対処法

たまーに死にますよね。。。
具体的な症状としてはdock、メニューバー、デスクトップアイコンがクリックできなくなるぐらい？

## 対処方法
https://wiki.gnome.org/Projects/GnomeShell/CheatSheet#Developer_tools
> Alt + F2プロンプトで「r」または「restart」と入力するとGNOMEShellが再起動します。

らしいですよ。

上記でも無理だった場合は
https://wiki.archlinux.jp/index.php/GNOME/%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0#.E3.82.B7.E3.82.A7.E3.83.AB.E3.81.8C.E3.83.95.E3.83.AA.E3.83.BC.E3.82.BA.E3.81.99.E3.82.8B
> 他の TTY に切り替えて (Ctrl + Alt + F2) から次のコマンドを入力して下さい: pkill -HUP gnome-shell

この際、現状UbuntuだとF2だとデスクトップ画面か表示されてしまうと思うので、F3(tty3)から使うのがいいんでないかなーとか思ってます。
【Node.js】インストール済みNode.jsのバージョンを変更する

# はじめに
この記事では、gulpのプラグイン導入時に詰まった原因と、
npmパッケージの1つである「__n__」の導入方法や、
Node.jsのバージョン変更の方法についてメモ程度に記載しています。

# 対象読者
- Node.jsを既にインストールしている方
- Node.jsの旧バージョンを利用したい方
- Macを利用している方（Windowsはサポート外のため）

# 私の環境
- OS: macOS Catalina Version 10.15.7
- Node.js: v15.8.0
- npm: 6.14.10
- gulp: CLI version 2.3.0
- gulp: local version 4.0.2

# 今回の状況

学習でhomebrewを利用してNode.jsをインストール。(2021/02/03時点ではv15.8.0)
npmを利用して各種ライブラリのインストール方法等を学習中。
gulpとそのプラグインをインストール中にエラーがでた。
(具体的には下記プラグインの内、gulp-sassのみエラーが出てインストールできなかった)

- browserify
- gulp-cli
- gulp
- gulp-clean-css
- gulp-sass
- gulp-imagemin
- gulp-changed

# 先に結論
2時間くらい試行錯誤した結果、__Node.jsのバージョンを下げることで解決__。
その方法を記載しておきます。


# 実際の作業

1.下記のコマンドを実行してインストールします。

```:nをグローバルにインストール
sudo npm install n -g
```

管理者権限での実行なのでパスワードの入力があると思います。
PCログイン時のパスワードでOK。

2.現在インストールされているNode.jsのバージョンを確認

```:インストールされているバージョンの確認
node -v
v15.8.0 (現在インストールされているバージョンです)
```

3.Node.jsの安定版を確認
何でも良いのかもしれませんが、安定版が良いと思います。

```:安定版を確認
n --stable
14.15.4 (現在公開されている安定バージョンです)
```

4.Node.jsをダウングレード
今回は上記のバージョン(14.15.4)にダウングレードします。
時期や状況によって必要なバージョンは変わると思いますので、適宜変更してください。

```:v14.15.4にダウングレード
sudo n 14.15.4
```

今回もパスワード入力があります。(たぶん)

5.キチンとダウングレードできたか確認

```:現在のバージョンを確認
node -v
v14.15.4 (ダウングレード成功！)
```

これで前述のプラグインは全てインストールできました。(2021/02/03時点)
「なぜかインストールできない」ってハマってる人の助けになれば幸いです。

「この手順マズイヨー！」みたいなのあったら教えてください。

# 参考

- [インストールしている Node.js のバージョンをダウングレードさせるために n を使ってみる](https://zenn.dev/ymasaoka/articles/using-n-for-downgrade-nodejs)
- [[Node.js] Node.js の導入(Linux/Mac編)](https://qiita.com/ksh-fthr/items/c272384f73f8e319733c)
- [node.jsのバージョンを変更する](https://qiita.com/k3ntar0/items/322e668468716641aa5c)
reactのhistory.pushした後のURLへ画面遷移しない

## 症状
- /loginへ画面遷移しようとしているものの真っ白
- /loginのURLがOpenIDConnect用の認証URLで認証プロバイダーへリダイレクトしているからかも？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/c335e939-8284-acfd-3beb-ef478c1447e6.png)


## 直し方
- URLへ移動したあとに画面更新する

```react
history.push("/login");
location.reload()
```

## 別な方法
```javascript

window.location.href = "/login"
```
topコマンドの可愛い設定

alias top="top -t -S -s0.1"

解説
　-t top自身を表示しない
　-S システムプロセスも表示(大文字S)
　-s0.1 更新頻度(小文字-s の後に秒数を"スペース無しで"書く)

これで
「わたくしといふ現象は　仮定された有機交流電燈の　ひとつの青い照明です（あらゆる透明な幽霊の複合体）風景やみんなといっしょに　せわしくしせわしく明滅しながら　いかにもたしかにともりつづける...」

...といふ top になります。
devise導入方法【Ruby on Rails】

#導入
deviseを用いたログイン機能をアプリケーションに実装していきます。


##開発環境
ruby '2.6.5'
rails '6.0.0'

#実装開始
###deviseのインストール
deviseを使ったログイン機能には、最初にGemfileを編集してからターミナルでコマンドを実行します。

```ターミナル:Gemfile
gem 'devise'
```

```:ターミナル
% bundle install
% rails g devise:install
```

実行するとモデルが生成されます。そしてroutes.rbにdeviseに関連するパスが自動で追加されます。

###Userモデルを作成

```:ターミナル
% rails g devise user
```

###マイグレーションファイルを編集
ユーザー登録で必要となるカラムを追加します。emailとpassworsはデフォルトで存在するので、それ以外の追加したいカラムを記述してきます。
次にターミナルでマイグレーションを実行します。

```ruby:
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
 def change
   create_table :users do |t|
     ## Database authenticatable
     t.string :email,              null: false, default: ""
     t.string :encrypted_password, null: false, default: ""
     t.string :name,               null: false

     # 省略

end
```
```:ターミナル
% rails db:migrate
```

###viewsを追加

```:ターミナル
% rails g devise:views
```
###viewsの編集
追加したカラムの分だけ記入欄を追加していきます。

```html:app/views/devise/sessions/new.html.erb
<div class="contents row">
  <div class="container">
    <h2>Log in</h2>
    <%= form_with model: @user, url: user_session_path, id: 'new_user', class: 'new_user', local: true do |f| %>

      <div class="field">
        <%= f.label :name %><br />
        <%= f.text_field :name%>
      </div>
      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email, autofocus: true %>
      </div>

      <div class="field">
        <%= f.label :password %><br />
        <%= f.password_field :password, autocomplete: "off" %>
      </div>

      <% if devise_mapping.rememberable? %>
        <div class="field">
          <%= f.label :remember_me %><br />
          <%= f.check_box :remember_me %>
        </div>
      <% end -%>

      <div class="actions">
        <%= f.submit "Log in" %>
      </div>
    <% end %>
  </div>
</div>
```
###モデルにバリデーションを記述
モデルにバリデーションを記述してデフォルトのemailとpassword以外が許可されるように、カラム名を記述します。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
```
application_controllerにbefore_actionを使用しているため、全てのアクションが実行される前に、実行されます。

before_action :authenticate_user!により、ログインしていないユーザーをログインページの画面に促すことができます。

configure_permitted_parametersで、configure_permitted_parametersメソッドを呼び出しています。
HTMLとCSS、HTMLの構成

###HTMLとは
▶︎webページ上に文字や画像などの**情報を記載させることができる**言語です。<br>ファイル名を**〇〇.html**とすることで作ることができます。
###CSSとは
▶︎HTMLで記述した文字などの**情報を装飾することができる**言語です。<br>ファイル名を**〇〇.css**とすることで作ることができます。

また、ファイルを生成するときファイル名のあとにつける「.html」や「.css」のことを**拡張子**といいます。

この拡張子で**言語の種類を識別**することができます。

-----
###HTMLの構成

HTMLファイルではまず、「これはHTMLの文章です」と宣言しなければなりません。そのときに使う要素が**DOCTYPE**と**html要素**です。それぞれの記述は以下の通りです。

```html
<!DOCTYPE HTML>
<html>
</html>
```

そしてhtml要素の中は**head要素**と**body要素**で構成されています。それぞれ<br>・head要素にはブラウザ上では表示されない基本情報など<br>・body要素にはブラウザ上に表示する情報<br>を記述します。

###head要素###
head要素内には基本情報として、**meta要素**,**title要素**,**link要素**などの要素を記述します。

```html
<meta charset="UTF-8">
<title> </title>
<link rel="stylesheet" href="">
```
・**meta要素**----charset(キャラセット)属性を指定し、文字コードを指定します。
・**title要素**---ウェブサイトのタイトルを指定します。（ブラウザのタブなど）
・**link要素**----rel属性をstylesheet,hrefにcssのファイル名を記述することでcssファイルを反映させることができます。

--------
#####まとめるとHTMLの構成は以下のようになります。

```html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ウェブサイトのタイトル</title>
    <link rel = "stylesheet" href = "ファイル名.css">
  </head>
  <body>
  </body>
</html>
```

------
###次回はbody要素で主に使う要素達を紹介しきたいとおもいます！
ブレイクポイントで改行する方法

# 対象
モバイルレイアウトにした際に改行が見づらい、、、
改行したい！そんな方が対象です！

## 前提知識
- html, cssの基礎


# 実践

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
<body>
  <div>
    <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります改行したい</p>
  </div>
</body>
</html>
```
とりあえず適当に書きます。
改行したいの部分で改行する感じです。
![スクリーンショット 2021-02-04 0.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/e5824001-8bd5-cc4a-3c3f-777f9042e7c3.png)
こちらPCレイアウト

![スクリーンショット 2021-02-04 0.44.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/386c22f8-c7eb-b97b-7513-4a68a0e9fbaf.png)
モバイルレイアウト

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
<body>
  <div>
    <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります<br>改行したい</p>
  </div>
</body>
</html>
```
こーするとPCでもモバイルでも改行されてしまいます。
ではPCでは改行せず、モバイル飲み改行したい場合はどうすれば良いのか？

```style.css
.br {
  display: none;
}

@media (max-width: 480px) {
  .br {
    display: block;
  }
}

```
結論これだけです！
GLDM : Gray Level Dependence Matrix

# Gray Level Dependence Matrix (GLDM)
ピクセル値iを中心として、|i-j|<=αを満たす近傍ピクセル値（依存ピクセル）が何個あるかを数え、その個数ごとに表にまとめたものです。
ここで、αは近傍ピクセルのカットオフ値となります。
iは中心ピクセル値、jはiの近傍にある依存ピクセル候補です。
近傍はδ（デルタ）の範囲まで拡大できるものとします。
デルタが1のとき、近傍の依存ピクセルの個数は最小が0、最大が8なので、GLDMはユニークなピクセル値の数だけ行を持つ、0-8の9列からなる表になります。
ただし、ある列以降の内容がすべて0などのときは、省略可能です。
図に、α=0, δ=1の場合の例を示します。
![GLDM.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/6851b862-a317-3f58-d4b0-5f3912af0955.png)

# References
* Sun C, Wee WG. Neighboring Gray Level Dependence Matrix for Texture Classification. Comput Vision, Graph Image Process. 1983;23:341-352.
* https://stackoverflow.com/questions/25019840/neighboring-gray-level-dependence-matrix-ngldm-in-matlab?fbclid=IwAR14fT0kpmjmOXRhKcguFMH3tCg0G4ubDLRxyHZoXdpKdbPxF7Zuq-WKE8o
[Javascript]ブラウザバック時にステータスを反映させる

ブラウザバックした際に
・ページを閲覧したのにステータスが変わっていない
・一度見たはずの通知が消えてない
等の問題に対処する方法です。

## 解決方法
### その1: PerformanceNavigationTimingを使う

PerformanceNavigationTimingとは、ブラウザーの文書ナビゲーションイベントに関するメトリックを格納および取得するためのメソッドとプロパティを提供するインターフェース。
getEntriesByTypeからリスト形式でnavigation オブジェクトを取得し、読み込みタイプを取り出します。
ブラウザバックを表すのは、back_forwardなので、以下のように記述すればOK。

```javascript:Sample
var perfEntries = performance.getEntriesByType("navigation");
var type = null;
 
perfEntries.forEach(function(pe){
	// 読み込みタイプを取得
	type = pe.type;
});

// ブラウザバックかどうかの判定
if(type == 'back_forward'){
	// 実行したい処理を記述
}
```

なお、読み込みタイプには、以下の4種類があります。

|戻り値|条件|
|---|---|
|navigate|通常読み込み<br>【例】URL直打ち, フォーム送信後の遷移|
|reload|更新<br>【例】更新ボタン or F5キー押下時|
|back_forward|戻る or 進む<br>【例】戻るボタン or 進むボタン|
|prerender|事前のページ読み込み<br>【例】linkタグでrel="prerender"を使用<br>→ 発生するのはこの場合のみ|

### その2: PerformanceNavigation.typeを使う

PerformanceNavigation.typeは、対象ページへの移動方法を表すunsigned short型の定数です。
ブラウザバックの判定は以下のように行います。

```Javascript:Sample
// ブラウザバックかどうかの判定
if(performance.navigation.type == performance.navigation.TYPE_BACK_FORWARD){
	// 実行したい処理を記述
}

```

なお、PerformanceNavigation.typeで、使用できる値および定数名は以下の通り。

|値|定数名|意味|
|---|---|---|
|0|TYPE_NAVIGATE|通常読み込み|
|1|TYPE_RELOAD|更新|
|2|TYPE_BACK_FORWARD|戻る or 進む|
|255|TYPE_RESERVED|その他の方法|

TYPE_RESERVED以外は、PerformanceNavigationTimingと同じですね。
ただし、<b>このインターフェースは非推奨となっている</b>ので、原則その1のPerformanceNavigationTimingを使うようにしましょう。

## 参考
* [PerformanceNavigationTiming | MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/PerformanceNavigationTiming)
* [PerformanceNavigation.type | MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/PerformanceNavigation/type)
* [JavaScriptでページが更新 or 戻る・進むされたかなどを調べる方法 | PisukeCode - Web開発まとめ](https://pisuke-code.com/js-get-navigation-type/)
Reactでfont awesomeを活用してアイコンを実装する

# 前提知識
- Reactの基礎
- JavaScriptの基礎

## 早速やってみる
```
npm i --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/react-fontawesome
```
まずはインストールします！
エラーが出た方はnpm -vで確認しましょう。

## 使用するアイコンを調べる
今回はまずTwitterのアイコンを調べていきます。
![スクリーンショット 2021-02-04 0.20.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/c78b2636-d70a-8a53-5e49-b73e5a1f481f.png)

確認すべき点は2つです
今回はアイコンの種類がBrandsなので

```
npm install --save @fortawesome/free-brands-svg-icons
```
これは種類によって使い分けてください。
例えばregularなら

```
npm install @fortawesome/free-regular-svg-icons
```
って感じです。

## 導入する
書き方としてはこんな感じです。

```components/footer/index.jsx
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTwitter } from "@fortawesome/free-brands-svg-icons";
import { faInstagram } from "@fortawesome/free-brands-svg-icons";

const Footer = () => {
  return (
    <>
      <FontAwesomeIcon icon={faTwitter} />
      <FontAwesomeIcon icon={faInstagram} />
    </>
  )
}
export default Footer
```
今回は勝手にfooterコンポーネントに追加する程で書いています。(フッターにツイッターとかのアイコン入れるってよくあると思います。)
今回はおまけでインスタのアイコンも追加しています！！！！

説明するとまずFontAwesomeIconをインポートします。
その後使いたいアイコンをインポート。

```
import { faTwitter } from "@fortawesome/free-brands-svg-icons";
```
１枚目の写真をもう一度確認しましょう！！
fa-twitterなのでimportする際はfaTwitterです。
fromのあとはbrandsの部分をアイコンによって変更する感じです。
regularなら

```
import { faTwitter } from "@fortawesome/free-regular-svg-icons";
```

アイコンによって種類が違うのでいろいろ試してみましょう！！
はじめまして

###今日から復習のアウトプット用でQiitaをはじめたいとおもいます！
------
##簡単なプロフィール

####経歴は？
▶︎高卒して印刷工場の製造業を５年半し退職。<br>現在はテックキャンプでプログラミング学習しております！（実家で居候しながら）
####プログラミンを始めたきっかけは？
▶︎以前職場ではエクセルをつかい業務効率化を目指していました。<br>そうしていくなかで「もっと凝ったものを作ってみたい！」とおもい、たどり着いたのがプログラミングでした。<br>ある時エクセルの外注の部署の移動を勧められた際、「どうせならグループ会社から出て、外の社会をみてみたい」とおもい、離職を決断しました！
####目標は？
▶︎自分は常日頃から「こういうサービスあったらいいのになぁ」とおもってしまう癖があります。そういうサービスを自分で作れるようになりたいです！
####趣味は？
▶︎結構多趣味で、音楽、ギター、スケボー、スノボー、カメラなどいろいろやっています（笑）※浅く広くタイプです。<br>普段街歩いてる時に「ここ滑りやすそうだな」とかただの縁石などみて「こういう技できそうだな」とか考えてしまいます（笑）「こういうサービスあったらいいのになぁ」を常に考えてしまうのはここから来てるかもしれませんね。
####生年月日
▶︎1997年生まれです！JUDY AND MARYの「くじら12号」のリリース年の同じってだけで自慢になります！！！

---------
こんな感じで簡単ではありましたが自己紹介でした！これからも勉学に励んでいきます！Qiitaよろしくおねがいします！
Googleにインデックス登録されない 1


自分の会社のホームページ作ってみたんですけど、2ヶ月ぐらい経ってもインデックス登録されないみたいです。
原因が、いまだにわかっていません。

とりあえず、外部リンクの意味も込めてリンクを貼っておきます。
https://www.ailabse73.com/

GoogleSearchConsoleでURL検査して問題なかったら、インデックス登録をリクエストしたら大丈夫だろうと思ったのですが、20回くらいやったけどダメでした。
https://search.google.com

ちなみにURL検査結果の結果は、全部問題なさそうでした。

サイトマップを登録すれば良いとかも見かけるんですが、面倒で特になにもしていません。

ついでに、PageSpeed Insightsとか試してみたんですけど、素晴らしいですね。。どこを改善すればいいかとか色々でてきます。

ま、もう少し待って登録されなかったら諦めてサイトマップでも作ってみます

せっかくなので、順番に試してみようと思います。
・ Qiitaにブログを書いてリンクを貼る
・ その他の会社登記情報サイトなどに登録する (外部リンクを増やす)
・ Yahooの会社情報に登録する
・ 広告を出してみる

他にも思いついたら増やしていこうと思います

**追記 2021/02/14**
Googleにインデックス登録されない 1
https://qiita.com/JunichiFujimoto/items/55a086c2b332e71f33dd
Googleにインデックス登録されない 2
https://qiita.com/JunichiFujimoto/items/a6b77bd38b820b2cfc3c
Googleにインデックス登録されない 3
https://qiita.com/JunichiFujimoto/items/e797dedd56963548ebb8
<hr>
Salesforce Classic での Pardot を使用した対ビジネスマーケティングの自動化 ⇒ B2B Marketing Analytics の基本 ⇒ B2B Marketing Analytics の使用開始

１．B2B Marketing Analytics とは何ですか?
２．B2B Marketing Analytics の 3 つの主要なコンポーネントは何ですか?
３．ディメンションとは何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/ccc7d78b-1170-437c-f8c4-4507cff99a6f.png)
MacOS ローカル環境を構築 CentOS6.8

# Virtualbox インストール
https://www.virtualbox.org/
# Vagrantインストール
https://www.vagrantup.com/

```
ホームディレクトリに移動

今後複数の仮想マシンを作ることを想定して、それらをまとめるフォルダ（MyVagrant）を作る
mkdir MyVagrant

MyVagrantに移動する
cd MyVagrant

仮想マシンを作るフォルダを作る（MyCentOS）
mkdir MyCentOS

MyCentOSに移動する
cd MyCentOS

仮想マシン設定用のVagrantfileを作る
vagrant init bento/centos-6.8

Vagrantfileを編集して仮想マシンのIPアドレスを192.168.33.10にする
sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network"private_network", ip: "192.168.33.10"/' Vagrantfile

仮想マシンを起動する（少し時間かかります）
vagrant up

仮想マシンの状態を確認する
vagrant status
```

# 仮想マシンの設定

```
vagrantに接続
Vagrant ssh

OSを最新状態にアップデート
sudo yum -y update

スクリプトを入手するためのgitをインストール
sudo yum -y install git

gitを使ってアプリケーション設定用のスクリプトをダウンロード
git clone https://github.com/dotinstallres/centos6.git

centos6フォルダができるのでそちらに移動
cd centos6

スクリプトを実行
./run.sh

設定を反映
exec $SHELL -l
```
###補足
エラー（YumRepo Error: All mirror URLs are not using ftp, http[s] or file）が発生した場合はvagrantに接続した状態で下記のコマンドを実行
CentOS 6のサポートが終了した為、このようなエラーが発生するとのこと。
参考：https://qiita.com/imunew/items/3810a41960f40db85c94

```
sed -i -e "s/^#baseurl=http:\/\/mirror.centos.org/baseurl=http:\/\/vault.centos.org/g" /etc/yum.repos.d/CentOS-Base.repo

権限に関するエラーが発生したらroot権限を持って実行しましょう
sudo su 
```

#接続確認

```
php -S 192.168.33.10:8000
```
【batファイル】所定のフォルダにファイルが提出されてるかチェック

※投稿として雑すぎるので後日手直し予定。それよりキーボードの下キーが外れてピンチ。

## 解決したい課題
チームメンバーに毎月提出してもらうファイルについて、提出チェックが面倒。

## 前提条件
・毎月の初めに、先月の報告を所定のフォルダに提出する。
・ファイル名のテンプレートは「氏名_YYYYMM.txt」。姓名の間に半角スペースを入れたり入れなかったりが定められていない。
・特定フォルダ以下に、各月のフォルダがYYYYMMの名称で作られ、さらに各月のフォルダ配下にいくつかのチーム分のフォルダが作られる。各メンバーはそこにファイルを提出する。

ex.
報告フォルダ＞202101＞東日本チーム＞パンダ一郎\_202101.txt
報告フォルダ＞202101＞西日本チーム＞うさぎ 花子\_202101.txt
報告フォルダ＞202102＞海外チーム＞コアラ豪\_202102.txt

## 解決策：batファイル

```winbatch
@echo off
setlocal enabledelayedexpansion

rem set YYYYMM=202101
set /P YYYYMM="YYYYMMを入力してください："
rem 毎回入力するのが面倒なときは、上の行のrem を削除、下の行の頭にrem を追記する。

echo -----全表示
dir C:\test\%YYYYMM% /s | findstr /r /C:"パンダ *一郎" /C:"うさぎ *花子" /C:"コアラ *豪"
echo;
echo -----総数表示
dir C:\test\%YYYYMM% /s | findstr /r /C:"パンダ *一郎" /C:"うさぎ *花子" /C:"コアラ *豪" | find /c /v ""
echo;

:retry
set /P SELECT="個別結果を表示しますか？(Y/N)"
if /i {%SELECT%}=={y} (goto :yes)
if /i {%SELECT%}=={yes} (goto :yes)
if /i {%SELECT%}=={n} (goto :exitlabel)
if /i {%SELECT%}=={no} (goto :exitlabel)
goto :retry

:yes
echo;
echo ----------パンダ 一郎
dir C:\test\%YYYYMM% /s | findstr /r /C:"パンダ *一郎"

echo ----------うさぎ 花子
dir C:\test\%YYYYMM% /s | findstr /r /C:"うさぎ *花子"

echo ----------コアラ 豪
dir C:\test\%YYYYMM% /s | findstr /r /C:"コアラ *豪"
echo ----------
echo;

pause
:exitlabel
```

## テストケースでの実行イメージ
・対象月：2021年1月
・パンダ 一郎：提出済みだが、姓名の間の半角スペースなし
・うさぎ 花子：提出済み
・コアラ 豪：未提出

```
YYYYMMを入力してください：202101
-----全表示
2021/02/03  20:10                 0 うさぎ 花子_202101.txt
2021/02/03  20:09                 0 パンダ一郎_202101.txt

-----総数表示
2

個別結果を表示しますか？(Y/N)hai
個別結果を表示しますか？(Y/N)
個別結果を表示しますか？(Y/N)y

----------パンダ 一郎
2021/02/03  20:09                 0 パンダ一郎_202101.txt
----------うさぎ 花子
2021/02/03  20:10                 0 うさぎ 花子_202101.txt
----------コアラ 豪
----------

何かキーを押すと終了します。
```

## 残っている課題

####batファイルを何度も実行するのが面倒
タスクスケジューラで自動実行する。
####メンバーの増減時のbatファイルのメンテナンスが面倒
For文でメンバーリスト.txtから持ってきたいが、難易度高そう。姓名の間にアスタリスクを入れる必要もある。batファイルを作るマクロを仕込んだExcelファイルを作るのは簡単そうだが、だったらbatファイル使わずにVBAマクロで確認すればいいって話。
####そもそもフォルダに提出する仕組みがイケてない
それを言っちゃあおしまいよ。
API Gatewayとは？

## 勉強前イメージ

なんかの拠点になるもの？
あんまりイメージついてないけど、AWSのサービスの綱渡しみたいなことしてるのかな？

## 調査

### API Gatewayとは？

APIの管理や実行を簡単にできるサービスです。
クライアントからのリクエストを受け取り、AWSのサービスに渡します。

### API Gatewayの主な機能

- APIの作成

APIの作成を行うことができます。
作ることの出来るAPIは、REST API、 HTTP API、 WebSocket API の3つあります。

- APIの管理

インフラの管理、運用、バージョン管理、認証、APIのレスポンスのモニタリング・監視など
様々な機能があります。
APIに必要な機能をAWS Gatewayを使うことで楽に作ることができます。

### API Gatewayのメリット

- バージョン管理が出来る
	- 複数バージョンのAPIを管理できる
- モニタリングができる
	- ダッシュボードからAPIのコールやレイテンシーなど見ることが出来る

## 勉強後イメージ

APIとAWSの綱渡しみたいな感じかな？
一回触ってみる。
lambdaとくっつけることが多いって聞いた。

## 参考

- [5分でわかるAmazon API Gateway](https://recipe.kc-cloud.jp/archives/7944)
- [API Gatewayの概要とメリット](https://blog.api.rakuten.net/ja/jp-api-gateway/)
- [AWS API Gatewayを使うメリット4つ｜主な機能も紹介](https://www.fenet.jp/aws/column/aws-beginner/317/)
さくらVPSにgithubから自動デプロイしようとしてハマった話

#はじめに
Web初心者がハマった問題を共有します。
より良いソリューションがあれば、有識者の方どんどんコメントください。
#やろうとしたこと
さくらのVPS上に自作のWebサイトを作るにあたって、GithubにPushしたタイミングでサーバー側にも自動で反映させたかった。

以下の記事を参考にしています。
https://qiita.com/misskabu/items/fb70d59deb02ae0efb12

この記事通りにやっている前提で書きます。

#ハマったこと
##エラーコードが出ていないのにVPS側で反映されない

```deploy.php
<?
echo "<p>webhook start</p>";
exec('cd /home/アカウント名/www/gitpullしていたディレクトリ名/',$op);
print_r($op); 
exec('git pull');
echo "<p>webhook finish</p>";
?>
```
_#参考にしたページより

github側では特にエラーもはかず、こんなログを出してくる。

```
<p>webhook start</p>Array
(
)
<p>webhook finish</p>
```
echoできているのでphpは叩けているっぽい.
VPS側にSSHした時にphpを実行するとpullできているので、エラー系に落ちて何も表示できていないのかと考えた。
##エラー出力してみた
```deploy.php
<?
echo "<p>webhook start</p>";
exec('cd /home/アカウント名/www/gitpullしていたディレクトリ名/');
exec('git pull2>&1'$log);#エラー出力を標準出力へ
print_r($log);
echo "<p>webhook finish</p>";
?>
```
結果

```
<p>webhook start</p>Array
(
    [0] => error: cannot open .git/FETCH_HEAD: Permission denied
    [1] => 
)
<p>webhook finish</p>
```
権限がないらしい
##じゃあお前誰やねん
```deploy.php
<?php
$user = exec('whoami');
$group = exec('groups ' .$user);
echo "user:{$user}<br>";
echo "group:{$group}<br>";
echo "<p>webhook start</p>";
chdir('cd /home/アカウント名/www/gitpullしていたディレクトリ名/');
exec('git pull 2>&1', $op);
print_r($op);
echo "<p>webhook finish</p>";
?>
```

結果

```
user:apache<br>group:apache : apache
```

#アッ、apache~~~~~~www
何わろてんねん。
適切な管理権限をapache君にも分けてあげてください。
Perl で二次元配列の行と列を入れ替える

Perl を書いていて二次元配列の行と列を入れ替える関数が欲しくなったため作成してみました。

## 関数

```perl
sub transpose {
    my @dimension_array = @_;

    my @result;
    my @first_row = @{$dimension_array[0]};
    foreach my $column_index (0..$#first_row) {
        my @row;
        foreach my $row_index (0..$#dimension_array) {
            push @row, @{$dimension_array[$row_index]}[$column_index];
        }

        push @result, \@row;
    }

    return @result;
}
```

## 使用例

```perl
my @row1 = (1, 2, 3);
my @row2 = (4, 5, 6);
my @row3 = (7, 8, 9);
my @array = (\@row1, \@row2, \@row3);

foreach my $row (@array) {
    print "@{$row}\n";
}
# => 1 2 3
#    4 5 6
#    7 8 9

my @transposed_array = transpose(@array);
foreach my $row (@transposed_array) {
    print "@{$row}\n";
}
# => 1 4 7
#    2 5 8
#    3 6 9

```
サーブレット・JSPでの画像表示

#問題
DBにバイナリーファイルとして保存したimageデータを、
jspのsrcよりdoGetにてjspへレスポンスが出来ず画像を出力する事が出来ずに困っております。

DB保存画像　64KBのpng画像
型　BLOB型


#実際のプログラム
##JSP

```
・・・・・・・・・・
<body>
<h1>データを表示する</h1>

ログインID:	${JavaBean.id}<br>
プロフィール写真:<img src="/プロジェクト名/ImageServlet?id=${JavaBean.id}"  > <br>

</body>
・・・・・・・・・・・
```

##サーブレット

```
package servlet;
import........

@WebServlet("/ImageServlet")
public class ImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
        String id = request.getParameter("id");
        ImageDAO dao = new ImageDAO();
        BufferedImage bimg = dao.selectImageById(id);

        response.setContentType("image/png");
        OutputStream os =null;
        os=response.getOutputStream();
        ImageIO.write(bimg, "png", os);
        os.flush();
    }
}
```

##DAO

```
package dao;

import .........

public class ImageDAO {
	private String url = "jdbc:h2:tcp://localhost/~/DB名";
	private String user = "";
	private String passwd = "";

public BufferedImage selectImageById(String id) {

	　　　Connection con = null;

		try {
			Class.forName("org.h2.Driver");
			con = DriverManager.getConnection(url, user, passwd);

			//SQL文
			String sql = "SELECT FILE FROM テーブル名 WHERE USER_ID =  ?  ";

			PreparedStatement ps = con.prepareStatement(sql);
			ps.setString(1, "id");
			ResultSet rs = ps.executeQuery();

			//データ取り出し
			if (rs.next()) {
				while (rs.next()) {
					InputStream is = rs.getBinaryStream("FILE");
					BufferedInputStream bis = new BufferedInputStream(is);
					return ImageIO.read(bis);
				}
			}
		} catch (IOException | SQLException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
}

```

#エラー内容
Tomcatのエラーログのエラー
![スクリーンショット 2021-02-03 23.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916828/ef9f2c22-0c4f-7f67-04d7-19edbae55aff.png)

実行後に表示されるimage表示アイコンの上を右クリックで開くと現れるエラー
![スクリーンショット 2021-02-03 23.06.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916828/460aa1b1-b0cd-2196-79f8-2d034d0789f9.png)
![スクリーンショット 2021-02-03 23.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916828/cd231712-1f00-4673-426f-98935a5f69c7.png)

Googleの検証ページのコンソール
![スクリーンショット 2021-02-03 23.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916828/e46a3045-f5c3-2ac3-eb92-decdd8f4d39a.png)

#考察

エラーログにはServlet.service()が例外をなげました。と記載があり、
Googleの検証ページではデータが大きので変換ができないのようなエラーの記載がありました。

上記のエラーが抽出されServletのレスポンスが帰らない状態です。
画像データ変換容量の問題と解釈をしました。
getBinaryStream("FILE")で受け取り、
BufferedInputStreamにしてコンテンツタイプの指定を行いOutputStreamで返しているはずなのですが、
Servletが例外を出しレスポンスが帰りません。

良い解決法があればご教授をお願いたします。
【Vue.js】コンポーネントにおける親子間のデータの受け渡し方法を図解で理解する。

#親から子にデーターを渡す

###静的なデーターを渡す


![IMG_7242.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/997faa22-67bd-b503-7e90-80fe709ed633.jpeg)

1 子コンポーネントを読み込む
2 読み込んだ子コンポーネントを変数に格納し、componentsプロパティに格納
3 カスタムタグで、templeate内に子コンポーネントを読み込む
4 カスタム属性(number)に渡したい値("6")を設定
5 子コンポーネントのpropsプロパティーで親コンポーネントのカスタム属性の値を受け取る
6 受け取った値を、子コンポーネントのtemplateで表示する。

###動的なデーターを渡す

```App.vue
<template>
  <div>
    <likeHeader v-bind:number="number"></likeHeader>
  </div>
</template>

<script>
import likeHeader from "./components/likeHeader.vue";

export default {
  name: "App",
  data() {
    return {
      number: 10,
    };
  },
  components: {
    likeHeader,
  },
};
</script>
```

```likeHeader.vue
<template>
  <div>
    <p>{{ number }}</p>
  </div>
</template>

<script>
export default {
  props: ["number"],
};
</script>
```
カスタム属性numberをv-bindの引数にして、dataの返り値numberを値に設定する。


#子から親にデーターを渡す

![5c9f5bf115ac60898309ba60c7bfa7ec.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/a92db17c-7818-0713-8742-b36f3ff7f760.gif)
上: 親コンポーネント
下: 子コンポーネント

![IMG_4495C569C4C2-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/88835578-b519-cd9f-b74e-ea24efc9b32c.jpeg)

1 子コンポーネントのクリックイベントにincrementメソッドを登録する。

2 incrementメソッドで、$emitメソッドによりカスタムイベントmy-clickを発火させる。

3 カスタムイベントmy-click引数は、$emitメソッドの第二引数に設定した"子から来たデータ"という文字列が渡る。

4 親コンポーネントでカスタムイベントmy-clickが発火し、登録しているメソッドrecieveWordが実行される。

5 引数には、"子から来たデータ"という文字列が入っている。

6 this.wordが更新される。

7 this.wordが更新されたので {{word}}の表示が変わる。
HomebrewでM1 MacにInkscapeをインストールする

# はじめに
先日購入した、M1 MacにHomebrewでIncscapeをインストールしたので、手順を紹介します。

# 目次
[1. 検証環境](#1-検証環境)
[2. Inkscapeとは](#2-Inkscapeとは)
[3. インストール手順](#3-インストール手順)
[4. 起動](#4-起動)

# 1. 検証環境
* OS: macOS Big Sur Version 11.1
* Chip: Apple M1
* Homebrew

  ```bash
  $ brew --version
  Homebrew 2.7.7
  Homebrew/homebrew-core (git revision 200f4; last commit 2021-02-03)
  Homebrew/homebrew-cask (git revision 00135; last commit 2021-02-03)
  ```

# 2. Inkscapeとは

![120px-Inkscape_Logo.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984188/c3315d8d-4280-29e3-0ae8-ae77e3aaf8c2.png)


ベクター画像を作成したり、編集することができるオープンソースのエディタです。Adobe Illustratorが一番近いツールだと思います。オープンソースですが、かなり高機能で、お金がない大学時代に使っていました（社会人の今も使おうとしているが笑）。また、M1チップだからなのかわかりませんが、かなりサクサク動いてます。詳細は、[公式サイト](https://inkscape.org/)を御覧ください。

# 3. インストール手順
## 3.1 Homebrewのアップデート

```bash
$ brew update
```

## 3.2 homebrew/caskリポジトリを追加
Inkscapeですが、homebrew/cask リポジトリにあるので、まずリポジトリを追加します。

```bash
$ brew tap homebrew/cask
==> Tapping homebrew/cask
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 547893 (delta 2), reused 4 (delta 2), pack-reused 547886
Receiving objects: 100% (547893/547893), 240.49 MiB | 4.75 MiB/s, done.
Resolving deltas: 100% (386975/386975), done.
Tapped 3803 casks (3,924 files, 258MB).
```

## 3.3 Inkscapeのインストール

まずは、詳細の確認。記事投稿時のバージョンは `1.0.2` でした。

```bash
$ brew info inkscape    
inkscape: 1.0.2
https://inkscape.org/
Not installed
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/inkscape.rb
==> Name
Inkscape
==> Description
Vector graphics editor
==> Artifacts
Inkscape.app (App)
/usr/local/Caskroom/inkscape/1.0.2/inkscape.wrapper.sh -> inkscape (Binary)
==> Analytics
install: 1,998 (30 days), 5,754 (90 days), 26,371 (365 days)
```

以下のコマンドでインストール

```bash
$ brew install inkscape
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 5 formulae.

==> Downloading https://media.inkscape.org/dl/resources/file/Inkscape-1.0.2.dmg
######################################################################## 100.0%
==> Installing Cask inkscape
==> Moving App 'Inkscape.app' to '/Applications/Inkscape.app'
==> Linking Binary 'inkscape.wrapper.sh' to '/usr/local/bin/inkscape'
🍺  inkscape was successfully installed!
```

インストール後の確認

```bash
$ inkscape --version
Inkscape 1.0.2 (e86c8708, 2021-01-15)
    Pango version: 1.43.0
```

# 4. 起動

```bash
$ inkscape
```

以下の様に起動できれば、完了です。

![Screen Shot 2021-02-03 at 23.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984188/db1f2e42-2e1d-a30e-ad5d-1254a556eb6e.png)
NGTDM : Neighbouring Gray Tone Difference Matrix

# Neighbouring Gray Tone Difference Matrix (NGTDM)

NGTDMは、Matrixと呼ばれるものの、最終的には、正規化前後のヒストグラムと、「ピクセル値[i]近傍の平均とiとの絶対誤差の総和」を求めるものです。
近傍の距離はδで指定します。通常はδ＝１です。
このとき、pi(割合)はiが出現する確率という意味もあります。

![NGTDM.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/9e8e1e5a-1241-ed1d-bd2a-fb0c1c3ee582.png)

# References
* Amadasun M, King R; Textural features corresponding to textural properties; Systems, Man and Cybernetics, IEEE Transactions on 19:1264-1274 (1989). doi: 10.1109/21.44046
Laravel8 リレーション

Laravel初学者です。
オリジナルアプリを作成しているのでその過程を記事にしています。

理解が曖昧なところも多いため、ご指摘等ありましたらご連絡いただければ幸いです。

今回はリレーションについて勉強したのでそのまとめです。
自分用メモです。

## 環境

|                | Version     |
|:---------------|------------:|
| PHP            | 7.4.14      |
| Laravel        | 8.24.0      |
| mysql          | 8.0.23      |
| docker         | 20.10.2     |
| docker-compose | 1.27.4      |


## 参考

[こちら](https://readouble.com/laravel/8.x/ja/eloquent-relationships.html)から勉強させていただきました。

翻訳してくれてありがたい。。。


## 今回の設定

- Phoneモデル
- Userモデル

こちらの2つが存在しいろいろな場合で定義します

## 1対1

```PHP:App/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }
}
```

```PHP:App/Models/Phone.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Phone extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```

上記のようにそれぞれモデルに定義します。
1対1の関係ってどちらがhasOneで、どちらがbelongsToか分かりにくいので
私は
`親=それが存在しないとそもそも子も存在しないモデルが親`
`子=自分が消えても親は消えないモデルが子`
というように覚えてます。

つまり今回の場合でいうとUserモデルが親でPhoneモデルが子です。

例えば
投稿に対してコメントできる機能があった時には

- 投稿が消えたらその投稿に対するコメントも消えるべき
- コメントはそもそも投稿が存在しないとそのコメントは存在しない

ということを踏まえると投稿が親でコメントが子です。


分かりにくい。。。
DB設計って難しい。


## 1対多

UserはたくさんのPhoneを持っている関係です。
User：1
Phone：多

```PHP:App/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function phones()
    {
        return $this->hasMany(Phone::class);
    }
}
```

ここで注意なのは`phones`と複数形になっていることです。
たくさんのphoneなので複数と覚えました。


```PHP:App/Models/Phone.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```

今回はuserは1なので単数形です。
1つのphoneを持つのはは1人のuserしか存在しないということです。
Scrapy Shellの自動補完のトラブル解決方法

Scrapy Shellの自動補完（オートコンプリート）でよく発生するトラブルとその解決方法です。

# そもそも自動補完が使えない
**IPythonをインストールしましょう。**

```bash
$ pip install ipython
```

Scrapy ShellはIPythonがインストールされていれば標準Pythonコンソールの代わりにそちらを使います。

# 補完しようとするとログが出力されて邪魔だ
**Scrapy Shell起動時にログレベルを変更しましょう。**

```bash
$ scrapy shell -s LOG_LEVEL='INFO' <URL>
```

デフォルトのログレベルがDEBUGになっています。
そのままだと初めて補完するときや補完しようとして候補がないときなどに以下なログが出力されてしまいます。

```
# res(ponse)を補完する
In [1]: res2021-02-03 23:29:19 [parso.cache] DEBUG: pickle loaded: /PATH/venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/builtins.pyi
2021-02-03 23:29:19 [parso.cache] DEBUG: pickle loaded:/PATH/venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/sys.pyi
In [1]: response
Out[1]: <200 https://www.google.com/>

# hogeを補完する
In [2]: hoge2021-02-03 23:29:34 [parso.python.diff] DEBUG: diff parser start
2021-02-03 23:29:34 [parso.python.diff] DEBUG: line_lengths old: 1; new: 1
2021-02-03 23:29:34 [parso.python.diff] DEBUG: -> code[replace] old[1:1] new[1:1]
2021-02-03 23:29:34 [parso.python.diff] DEBUG: parse_part from 1 to 1 (to 0 in part parser)
2021-02-03 23:29:34 [parso.python.diff] DEBUG: diff parser end
```

表示内容をもっと減らしたければ以下のようにしてもよいです。

```bash
# ログレベルを更に上げる
$ scrapy shell -s LOG_LEVEL='WARNING' <URL>
$ scrapy shell -s LOG_LEVEL='ERROR' <URL>
$ scrapy shell -s LOG_LEVEL='CRITICAL' <URL>

# ログを無効にする
$ scrapy shell -s LOG_ENABLED=False <URL>
```

# Scrapy Shellを起動するときにいちいちログレベルを指定するのが面倒だ
**Scrapyプロジェクトのsettings.pyでログレベルを設定しましょう。**
settings.pyの場所はプロジェクトルートのscrapy.cfgに書かれています。

```config:scrapy.cfg
[settings]
default = your_project_name.settings
```

settings.pyに以下のように設定を記述します。

```python:settings.py
LOG_LEVEL = 'INFO'
```

現在のディレクトリでScrapy Shellを実行したときに適用されるログレベルは、以下のコマンドで確認できます。

```bash
$ scrapy settings --get LOG_LEVEL
INFO
```
ActiveRecord::RecordInvalid: （バリデーションに失敗しました: Userを入力してください）エラーの解決例

現在、顧客管理アプリを作成しており、顧客を登録した時に、

```
ActiveRecord::RecordInvalid: バリデーションに失敗しました: Userを入力してください
```
というエラーが出て、顧客情報が登録できませんでした。

binding.pryを入れてcreateアクションを検証してみました。
エラーが出た時は、createアクションに、

```
Client.create!(name: client_params[:name], gender: client_params[:gender], age: client_params[:age], address: client_params[:address])
```
入力していました。

`Client.create(client_params)`で検証してみると、

```
 Client.create(client_params)
=> #<Client:0x00007fcec135ebd8 id: nil, name: "浅井健介", gender: "男", age: 36, address: "東京都港区456-789", user_id: nil, created_at: nil, updated_at: nil>
```
と返ってきました。

おや？どうやら `user_id`, `created_at`, `updated_at`の情報が入っていない？
という事で、deviseのヘルパーメソッド `current_user`を使い、コードを書き換えた所、

```
client = current_user.clients.create!(client_params)
  TRANSACTION (1.5ms)  BEGIN
  ↳ (pry):4:in `create'
  Client Create (54.8ms)  INSERT INTO "clients" ("name", "gender", "age", "address", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["name", "浅井健介"], ["gender", "男"], ["age", 36], ["address", "東京都港区456-789"], ["user_id", 1], ["created_at", "2021-02-03 14:08:05.191944"], ["updated_at", "2021-02-03 14:08:05.191944"]]
```
と、User情報入り、問題解決が出来ました。

## まとめ
メンターさんにアドバイスを求めた所、binding.pryを使ってエラーの本質を見つけてくださいとのことでした。参考になる記事をいただけて、問題解決もできたので、メンターさんに感謝です！同じエラーで苦しんでいる人の参考になれば幸いです。