OmniAICreator/Qiita-1.07M huggingface dataset:
複数行を三点リーダーで省略する（EI11対応）

# テキスト省略をCSSで行たい理由

親要素の横幅に収まるように、テキストを三点リーダーで省略したい場合、
CSSで行うのが簡単でシンプルです。

サーバーサイドで文字数を元に切り捨てた場合、HTML上に全文が載らないため、
title属性やその他UIで全文を表示させる時に不便です。

また、レスポンシブの場合は尚更CSSで行えると実装が楽です。

## 注意

IE11対応とありますが、三点リーダーはIE11では表示されません。（行数で切り捨て表示するのみ）

# 単一行はCSSのみで実装

単一行の場合は、下記CSSを適用することで、親要素の横幅を超えた分を「...」で省略できます。
こちらはIE11を気にせず使用できます。

```css
p {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
```

# 複数行はJavaScriptでCSSを適用する

複数行の場合は上記で対応できないため、`-webkit-line-clamp`プロパティを使用します。
`-webkit-line-clamp`で指定した値の行数以降（下記だと4行目から）が非表示になり、指定行の最後の文字が「...」になります。

```css
p {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;  
}
```

しかし、`line-clamp`自体-webkit-付きでIE11が未対応のため、JavaScriptで`-webkit-line-clamp`の対応を判定し、
対応していない場合は`height`を固定にして、`overflow-y: hidden;`ではみ出した分を非表示にしたいと思います。

また、JavaScriptでCSSを適用するため、カスタムdata属性で行数を指定できる実装にしておけば、
CSSで行数違いの`-webkit-line-clamp: n;`を複数記述する手間もありません。

## HTML

幅の基準になる親要素を用意し、その子要素としてテキストを省略する要素を置きます。
`data-truncation`属性の値に省略する行数を設定します。

```html
<div class="parent" style="width:300px;">
  <p data-truncation="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
```

## JavaScript

HTML要素単体（element）と、行数（lineNumber）を引数に持つ`addTruncationCSS`関数を作成します。
`element.style`オブジェクトに`WebkitLineClamp`が存在するかを判定します。

真の場合は、`element.style`オブジェクトにline-clamp用のスタイルを適用します。
偽（IE11）の場合は、`line-height`と指定された行数の乗算で固定する高さを決めて、`height`に指定します。

あとは、`querySelectorAll`で要素を取得して、各要素ごとに`addTruncationCSS`関数を実行します。

```javascript
const addTruncationCSS = (element, lineNumber) => {

  if('WebkitLineClamp' in element.style) {

    element.style.display = '-webkit-box';
    element.style.WebkitLineClamp = lineNumber;
    element.style.WebkitBoxOrient = 'vertical';
    element.style.overflow = 'hidden';

  } else {

    // IE11などline-clamp非対応の処理
    const limitHeight = parseFloat(getComputedStyle(element).lineHeight) * Number(lineNumber);
    element.style.overflowY = 'hidden';
    element.style.height = String(limitHeight) + 'px';
  }
}

const truncationElements = document.querySelectorAll('[data-truncation]');

if(truncationElements) {
  for (const elemet of truncationElements) {
    const lineNumber = elemet.dataset.truncation;
    addTruncationCSS(elemet, lineNumber);
  }
}
```

以上です。レンダリング時のガタつきが気になる場合は、省略する要素に`display: none;`や`hidden`属性を付与して、適宜JavaScriptを調整すれば解消できるかと思います。

# サンプル

https://jsfiddle.net/9qmLwuz7/

# `line-clamp`について

## ブラウザ対応

https://caniuse.com/#feat=css-line-clamp

## ドキュメント

https://developer.mozilla.org/ja/docs/Web/CSS/-webkit-line-clamp

## 複数行テキスト省略の実装についてより詳しく

Line Clampin' (Truncating Multiple Line Text) | CSS-Tricks
https://css-tricks.com/line-clampin/
NetworkManager で PPPoE マルチセッション接続＆同じ NIC を LAN接続と併用する

むかしはできなかったみたいだけど、いつの間にか実装されたようです。

Fedora で旧来の `ifup` をすると `'network-scripts' will be removed from distribution in near future.` と出るようになったし、いい加減に NetworkManager を覚えないといけませんね...

## 同じネットワークデバイスを、PPPoE と LAN とで併用する
![ネットワーク構成図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261973/7b05d263-1720-677d-0d9f-6f302c875a79.png)

こんな構成にして、1枚のネットワークカードで PPPoE によるインターネット接続と、LAN 内へのアクセスを同時に行いたいとき。

### （手段1） nm-connection-editor を使用する
`nm-connection-editor` から "DSL/PPPoE" 接続を作成し、"Claim インターフェース" のチェックを外す
![nm-connection-editor](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261973/40671594-851a-f4d2-33ca-3ea0eab1bc7f.png)
> 選択された場合、接続はインターフェースを排他制御し、別の接続を有効化することはできません。このオプションは、Ethernet のインターフェースでのみ使用可能です。このオプションが選択されている場合に限り、nm-applet は接続を有効化できます。

### （手段2） nmcli を使用する
上の方法で設定した前後で `nmcli connection show [name]` の diff を取ると、

```diff
@@ -5 +5 @@
-connection.interface-name:              ens33
+connection.interface-name:              ppp1
@@ -85 +85 @@
-pppoe.parent:                           --
+pppoe.parent:                           ens33
```

となっていることがわかるので、この通りに `nmcli connection modify` で設定しましょう。

- 設定ドキュメント https://developer.gnome.org/NetworkManager/stable/settings-pppoe.html

## PPPoE マルチセッション接続を行う
NTT フレッツ光ネクストでは、PPPoE セッションを複数確立し（無料では2セッションまで）、複数のプロバイダと接続することができます。また、フレッツのサービス情報サイト（フレッツ・スクエア）への IPv4 接続の際にも、インターネット接続と併用するにはマルチセッション接続が必要です。

単に2つの ppp connection を作って有効化しようとすると、
`エラー: 接続のアクティベーションに失敗: Failed to find a compatible device for this connection`
と表示されるかと思います。

これを解決するためには、上節の方法で PPPoE 仮想デバイスをネットワークインターフェースから切り離したあとに、 ppp デバイスの `connection.multi-connect` を `multiple` にセットすればよいです。

```shell
nmcli connection modify openadjp connection.multi-connect multiple
```

- 設定ドキュメント https://developer.gnome.org/NetworkManager/stable/settings-connection.html
- 対応する NetworkManager のソースコード
    - 当該エラーメッセージの生成箇所 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/fc837cbb6f43c3718752ac4c8884c18b64fdec7c/src/nm-manager.c#L5230
    - この前に呼び出している関数で、 multi-connect の設定を参照している https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/fc837cbb6f43c3718752ac4c8884c18b64fdec7c/src/nm-manager.c#L3602
Fortran で Brainf*ck

# 能書き
最近 [Code-golf](https://code-golf.io/) が Fortran に対応したというニュースが流れていました。のぞいてみると問題の中に Brainf*ck があったので作ってみました。Brainf*ck は有名ながらウザそうなのでスルーしていましたが、今回初めて Brainf*ck の中身を知りました。

https://code-golf.io/brainfuck#fortran

今までコードゴルフの様なものは、特殊な悪い癖をつけるものだと思い、あまり興味がなかったのですが、問題を解くのは面白かったです。（大きいローマ数字の読み方をはじめて知ったような気がしますｗ）

Fortran 自体は code golf には不向きなので、短くないのはご愛嬌と思って勘弁してください。

## code-golf 版 Brainf*ck の仕様 
入力コマンドが無く、プログラムはコマンドラインに複数与えられるようになっています。

```
Brainfuck is a minimalistic esoteric programming language created by Urban Müller in 1993.

Assuming an infinitely large array, the entire Brainfuck alphabet matches the following pseudocode:

Cmd	Pseudocode
>	ptr++
<	ptr--
+	array[ptr]++
-	array[ptr]--
.	print(chr(array[ptr]))
[	while(array[ptr]){
]	}
Write a program that will receive various Brainfuck programs as arguments and execute each program in turn.
```

## 参考プログラム
ここでは入力を標準入力から brainf*ck プログラム 1 本だけ取るようにしたものを示します。

プログラムは仕様をそのまま書けばいい感じになっています。面倒なのは対応ブラケット括弧([,])同士に移動する所でした。一見対称にみえて少し違うので、まとめる時に混乱しました。 

追記：本来のテープ仕様はバイト単位の様なので integer(1)/integer*1 にしておくべきかもしれません。


```fortran
program brnfck    !brainf*ck interpreter [Codegolf]
  integer a(30000)     !tape 
  character(10000)::t  !bf program 
  read *,t             !read bf program
  a=0                  !clear tape
  k=1                  !program position (program counter pc)
  m=1                  !tape position    (pointer ptr)
  do 
    if (k > len_trim(t)) exit !end of input 
    select case(t(k:k))
      case('>');m=m+1             !inc ptr
      case('<');m=m-1             !dec ptr 
      case('+');a(m)=a(m)+1       !inc (ptr)
      case('-');a(m)=a(m)-1       !dec (ptr)
      case('.');write(6,'(a)',advance='no')char(a(m)) !out char((ptr))
      case('[');if(a(m)==0)call w(1) !while (ptr)
      case(']');call w(-1);k=k-1     !wend
    end select
    k=k+1 !inc pc
  enddo

contains
    
subroutine w(n) ! jump to corresponding bracket  n=1 -----> ']', n=-1 '['<-----
  j=1
  do while(j>0)
    k=k+n
    if(t(k:k)=='[')j=j+n
    if(t(k:k)==']')j=j-n
  enddo
end subroutine w

end program brnfck
```
### 実行例 Fortran と出力
末尾に改行(LF)を入れてあります。

```
+++++++[>++++++++++<-]>.<++++++[>+++++++<-]>-.+++.++.--.<++++[>----<-]>-.<+++[>++++<-]>+.>+++[>+++<-]>+.
Fortran
```

### code-golf 用圧縮版
コマンドライン引数に関するループを付け加えました。

サブルーチン呼び出しの代わりに、戻り値なしの関数をダミー変数に無意味な代入をして呼び出しています。select case は祖型の行き先 goto 文にしましたが fall through の効果をキャンセルするために上の方ほど余分な値を与えてあります。

```fortran
integer a(99)
character t*999
do l=1,iargc()
call getarg(l,t)
k=1
m=1
a=0
1 goto(2,3,4,5,6,7,8)index('[].><+-',t(k:k))
2 if(a(m)==0)v=w(1);goto 9
3 v=w(-1);goto 1
4 write(6,'(a)',advance='no')char(a(m));m=m-1
5 m=m+2
6 m=m-1;a(m)=a(m)-1
7 a(m)=a(m)+2
8 a(m)=a(m)-1
9 k=k+1
if(k<=len_trim(t))goto 1
enddo
contains
function w(n)
j=1
1 k=k+n
if(t(k:k)=='[')j=j+n
if(t(k:k)==']')j=j-n
if(j>0)goto 1
end
end
```

402 bytes
Pycaretを使ってみた

###Pycaretのインストール

```
pip install pycaret
```
事前にdataframeを作っておく。
（ココではdfという名前にした）

###準備

```
from pycaret.regression import *                #回帰
from pycaret.classification import *            #分類
```

 ###環境をセットアップ

```
exp1 = setup(df, target = "目的関数の列の名前")
```
下のようなエラーが出た。

```
Library not loaded: /usr/local/opt/libomp/lib/libomp.dylib
```
[I can't import PyTorch, libomp.dylib can't be loaded.](https://github.com/pytorch/pytorch/issues/20030)
上の記事にしたがって、

```
brew install libomp
```
をしたら解決した。

###手法の比較

```
compare_models()
```
で手法どうしを比較できる
分類の場合の指標: Accuracy、AUC、recall、Prec、F1、kappa
回帰の場合の指標： MAE、MSE、RMSE、R2、RMSLE、MAPE

データに日本語が含まれていいたために以下のようなエラーが出た。

```
LightGBMError: Do not support non-ASCII characters in feature name.
```
だが、すでに精度が良さげなモデルは把握できたのでスルー

###モデルの生成

```
変数 = create_model（'モデル名'）
```
これだけでモデルが生成できる。
[Create Model](https://pycaret.org/create-model/)
↑ここにモデル名の一覧がある。
例

```
decision_tree = create_model("dt")
```

###モデルの保存

```
save_model("上でモデルを代入した変数名",model_name = 'example_name')
```

###保存したモデルの使い方

```
変数名 = load_model('保存した名前')
new_prediction = predict_model(変数名, data=試したいdataframe)
```

参考
-
[Announcing PyCaret 1.0.0](https://towardsdatascience.com/announcing-pycaret-an-open-source-low-code-machine-learning-library-in-python-4a1f1aad8d46)
react-routerでList componentを使わずにページ遷移する（Hook以降）

Link ComponentではなくEvent経由で遷移したかったのでやり方を確認。
以前はwithRouterを利用するやり方だったようだかReact Hookに対応してからはuseHistoryを使えばwithRouterは不要になったようだ。
下記でページ遷移できた。

```js

import { useHistory } from "react-router-dom";

const LinkButton = () => {
  const history = useHistory();

  const handleClick = () => {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      リンクボタン
    </button>
  );
}
```
カレントディレクトリに対するコマンド　Python

#カレントディレクトリに対するコマンド
全てosモジュールを使用するので

    import os
を最初に打っておく。

- カレントディレクトリのパス名を取得

        path = os.getcwd()
        print(path)

- カレントディレクトリ内のフォルダやファイルの表示

        ls = os.listdir(os.getcwd())
        print(ls)

- ディレクトリの移動

        os.chdir("Desctop")    #移動はこれだけでOK
        curdir = os.getcwd()
        print(curdir)

- カレントディレクトリのディレクトリ名を取得

        curdirname = os.path.basename(os.getcwd())
        print(curdirname)
【XCode】~no working copies~リポジトリだって外出したい！【Git機能】


**注意：こちらの解決方法は論理的とは言えないものなので、反面教師として扱ってください。**
# リポジトリ失踪事件
昨日、XCodeでpushした生まれたてホヤホヤリポジトリくん。
今日になったらウンとスンしか言わなくなりました。
コロナウイルス に感染しちゃったのかな。かわいそうにね、リポジトリくん。


![スクリーンショット 2020-04-26 13.23.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507693/da573e58-4f4c-e122-bfd2-6eeef1666e9a.png)
更に、no working copiesも出てた。



# 確認したこと 
1. もしかしてAccount類吹っ飛んだ？と思って、Xcode > preferences > Accountを確認。
   ちゃんとGitHubのアカウントは追加されたまま。

2. 寝ている間にリポジトリだけ爆発した？と思って、ターミナルから直接確認。
普通に.gitディレクトリあるし中のconfigの中身も正常そう。
ターミナルからadd, commit, pushもできた。

ますます原因がわからなくなった。調べてもあまり似たような現象はヒットしない。
念の為createしようとしてみると、ちゃんと怒ってくれる。
もうあるってよ。じゃあこっちからもcommitさせてくれよ。
![スクリーンショット 2020-04-26 13.12.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507693/6941e19c-f930-6f0f-c337-b89fd4447d11.png)



# 解決手段

１時間ほど下手くそな検索を続け、[apple公式developerのフォームに寄せられたある質問](https://forums.developer.apple.com/thread/108718)にたどり着いた。
「もっと早く公式みにいけよ」とは私が一番思ってるので言わないで。思うだけにして。

リンク先の質問への御回答で、以下のテキストを発見した。

>"Just to be sure, have you already tried all the usual stuff:
・make sure you're running the latest version of Xcode 10 (currently Version 10.0 (10A255), different from first GM)
・check to make sure the .git/ directory exists somewhere (what does $ git status in the terminal give?)
・restart Xcode
・restart the computer"


**＜＜＜＜restart Xcode＞＞＞＞**

そう、私はXCodeの再起動という初歩的なことを試し忘れていた。
速攻でXCodeの再起動を試したところ、治った。
同じ現象で、XCodeの再起動・Macの再起動でもダメだった場合は上記URLに飛んで、より詳しいその後のやり取りを読もう。

# まとめ
一度紐づけたはずのリポジトリが急に失踪したら、慌てずに一度XCodeの再起動を試してみてほしい。

初心者のくせに初歩的なことを忘れるの、本当によくない。
同じような駆け出しエンジニアが出て欲しくないので戒めとして共有した。
firebase(FCM)で購読したトピックの一覧を取得する

**2020/4/27時点での情報です**

FCMのトピックメッセージングではクライアントから簡単にトピックの購読、購読解除が可能です。
しかし、購読したトピックの一覧を取得する方法は少し面倒です。
具体的には以下のAPIを使用します。

```
URL:
https://iid.googleapis.com/iid/info/$IID_TOKEN?details=true
HEADER:
Authorization: key=$SERVER_KEY

IID_TOKE: クライアントで取得できるトークン
SERVER_KEY: firebaseのコンソールから確認できるキー
```

上記のAPIにリクエストを送ると購読しているトピックの一覧を取得することができます。
APIがあるなら簡単では？と思うかもしれませんが問題なのは**SERVER_KEY**です。
**SERVER_KEYが分かると任意のtopicにプッシュ通知を送ることができます。**
要するにSERVER_KEYをクライアントに埋め込んでリリースしてしまうと悪意のあるユーザーからプッシュ通知送り放題になってしまう可能性があります。
安全にするためには必ずwebサーバーを用意し、webサーバー経由で購読しているトピック一覧を取得しなければならず面倒です。

明らかに面倒なのでFCM SDKから取得できるようにしてほしいというissueが立っています。
[FR: Add API for checking subscription status of a given topic #225](https://github.com/firebase/firebase-ios-sdk/issues/225)

2017年から存在しているissueで未だに解決してなくてもう無理だと思ってましたが最近になって以下のコメントが付いています。

>Thanks for bring this up to our attention, please upvote at the top, and I will bring this to our PM again to see if priority shifts.

この機能が必要だと思った方はぜひ:+1:しておきましょう。
AWS Elastic BeanstalkでEBSボリュームを暗号化するには？

# 背景

現状Elastic Beanstalkのサービスとして、EBSを暗号化するための設定を行う機能はありません。

EBSを暗号化するには下記のうち、どちらかの方法をとる必要があります。

(1) EBSボリュームがデフォルトで暗号化されるよう設定する

(2) Elastic Beanstalk環境用のAMI から、EBSボリュームに対して暗号化の設定を行なったカスタムAMIを作成し、そのAMIを使用する

今回は(1)の方法を使ってEBSを暗号化する方法を紹介します。

この方法の注意点としてはデフォルト暗号化を有効化すると、以降設定したリージョン内で構築されるEBSが全て暗号化されます。

# 手順
## KMSを作成する
デフォルトKMSキーを使用する場合はこの手順は飛ばして問題ないです。

※デフォルトKMSキーを使用すると暗号化したスナップショットをAWSアカウント間でコピーが行えなくなるので注意

カスタマーキーを作成する際、注意点としてオートスケーリングで使用するサービスロールからKMSへのアクセス許可をキーポリシーで明示しておく必要があります。

Elastic Beanstalkはオートスケーリングを使ってEC2を起動するため、サービスロールがKMSへのアクセスができないとEC2が起動できずターミネートされてしまいます。

<img width="609" alt="スクリーンショット 2020-04-26 23.28.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237468/6bdace4d-93cb-abe1-8232-425a35473cdb.png">

キーポリシー例

```json
{
    "Id": "key-consolepolicy-3",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::アカウントID:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "オートスケーリングのサービスロール"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": "オートスケーリングのサービスロール"
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}
```

※躓きメモ
僕は最初Elastic Beanstalkのサービスロールをキーポリシーで許可していました。

何度やってもEC2が立ち上がらず苦戦していたのですが、「どのサービスがEC2を起動しているのか？」を考えたら分かりました。

Elastic Beanstalkはオートスケーリングの設定を行う所までしか関与して良いないので、オートスケーリング側に対してKMSへのアクセス許可を与えてあげる必要があります。

## EBSのデフォルト暗号化設定
KMSを作成したらEC2が起動する際にEBSがデフォルトで暗号化されるようにします。

EC2のダッシュボード画面から「設定」を押してください。

<img width="982" alt="スクリーンショット 2020-04-26 23.54.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237468/41c00c73-75c0-160f-9b12-f086da4139b7.png">

設定画面が表示されるので以下のように設定してください。デフォルトKMSキーを使用する場合は「(デフォルト)aws/ebs」というものをデフォルトの暗号化キーで指定してください。

<img width="852" alt="スクリーンショット 2020-04-26 23.58.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237468/1fd9c300-42fd-5199-f7ef-bd58a7de33ad.png">

## Elastic Beanstalkを使って環境を作成する
これで準備は完了です。特にElastic Beanstalk側で設定を変更する必要は無いです。いつも通りのやり方でElastic Beanstalkを使って環境を作成すればEBSが暗号化された状態で構築されます。

## まとめ
Elastic BeanstalkでEBSを暗号化するには現状だと少し工夫が必要になります。

カスタムAMIを作成して暗号化を行う方法だと別途AMIの作成を行う必要があるため工数がかかりますが、デフォルト暗号化を使った方法だと簡潔に実現できます。

カスタムAMIを作成する方法はいずれまた別の記事として投稿しようかなと考えてます。
ピンポイントに文字サイズを変更する方法『HTML』



```html.erb

<span style="font-size:10px; color:red;"> 文字 </span>
```

``<span>``から``</span>``まで挟んだ部分が適用されます。
文字の大きさは、10pxの部分を変更すれは変わります。
color:red;で色も変更できます。
PHPオブジェクト指向基礎まとめ（１）

# オブジェクト指向
**もの（オブジェクト）を中心にした考え方**
サイトやWEBサービスはユーザー、アイテム、グループなど１つ１つのものを組み合わせて出来上がっていると考えることができる。
この考え方によって、コードをユーザーに関するコード、商品に関するコード・・・という具合に役割を明確に分けてプログラムを作り上げることができる。
# クラスの定義
クラスとはオブジェクトの設計図のようなもの。
**class クラス名**という形で定義し、{}の中に定義したクラスの内容を書いていく。
クラス名は大文字から始まる。（Dog、Cat、Car、Menu・・・）

```php
class クラス名 { //クラス名は大文字から始まる。
 //クラスの内容
}
```
# インスタンス
クラスを元に作成された実体のこと。
**new インスタンス名()**という形で生成される。
**$変数名 = new クラス名();**
という感じに変数に代入し、クラスの外で生成する。

```php
class クラス名{
}
$変数名1 = new インスタンス名1(); //クラスの外で生成
$変数名2 = new インスタンス名2();
```
# プロパティ、メソッド
クラス（設計図）から生成されたインスタンス（実体）が持つ
**データのことをプロパティ**という　name(名前）、price(価格)など
**処理のことをメソッド**という　getName（名前を取得、getPrice（価格を取得）など

### プロパティ
**public $プロパティ名;**　という形で定義する。
インスタンス -> プロパティ でインスタンスのプロパティにアクセス出来る。

```php
class Drink {
 public $name; //nameを定義
}
$coffee = new Drink();　//Drinkインスタンスを生成
$coffee -> name = 'COFFEE'; //Drinkインスタンスにnameをセット
echo $coffee -> name;  //セットしたnameを呼び出す。
//結果：COFFEE
```
インスタンスにプロパティをセットする際に$はいらないことに注意
### メソッド
**public function メソッド名(){処理}**　という形で定義する。

```php
class Greet {
 public function hello() {
  echo 'こんにちは’;
 }
}
```

今日はここまで！！
シェルプログラミングをやってみた

#はじめに
この記録はJSとかを適当にやっている学生がメモ代わりにしているものです。内容は期待しないでください。

#1.シェルプログラミングとは
シェルとは,画面に入力されたコマンドを解釈し、カーネルに引き渡します。カーネルはOSの中核部分を担っています。また,このカーネルが出力した結果をシェルに渡して画面に表示するのです。簡単に言うとOSの中核となる部分（カーネル）を包み込み,OSと対話をする機能です。
シェルスクリプトは、このシェルで用いられるスクリプト言語のことです。一般的にシェルスクリプトは複雑な業務を行わず,定期作業の自動化,作業の記録,複数のコマンドをまとめて処理する簡単な業務を行います。
Linuxにおいて一般的なシェルはbashであり,今回はこれを使用します。

#2.作業ファイルの作成
```touch firstshell.sh
```
touchコマンドはUbuntuに対して引数で渡された名前のファイルが存在しなかった場合には,空ファイルを作成します。 存在した場合には,そのファイルやディレクトリの更新日時を更新します。

#3.シェルスプリクトを書いてみる
このシェルスクリプトを /bin/bash にある bashシェルで実行するため以下を記述する。
```#!/bin/bash```
ここでクイズを作りたくなったので以下を追加記述しました。
```read -p "プロテインはタンパク質？ [y/n]" yn
if [ $yn = "n" ]; then
  echo 不正解です。
else
  echo 正解です。
fi
```
readコマンドは-p"文字列"で文字を表示しながら変数を受け取ることができるらしい。このスクリプトでは変数ynにyかnを代入して扱っている。以下は単純な条件分岐で最後にfiをつけ忘れないように。

#4.シェルスクリプトのプログラムを動かしてみる
シェルスクリプトのプログラムを動かすためには、その実行を許可するような権限がファイルに付与されている必要があり,今回は全てのユーザが実行可能なように以下をコンソールに記述しました。
```chmod a+x firstshell.sh
```
./を含めた相対パスを使ってこのスクリプトを実行
```./firstshell.sh
```
すると思いの他スムーズに動きました。
そうです,プロテインはタンパク質です。特にエラー等も起こらなかったので今回はここまでです。お疲れ様でした。
Solaris SoftwareRAID なシステムでの DISK 交換手順

> 昔の Solaris 9 と 10 の時代に使っていた手順書が出てきたので、一応書き記しておく。
> 最早使う機会も無い気はするが、どこかの誰かが参考にする事があれば幸い。

# ■ 情報

|項目|値|
|:--|:--|
|ホスト|test01|
|ミラー対象ディスク|/dev/dsk/c0t2d0s0 (/var/log)|
|追加ディスク|/dev/dsk/c0t3d0|
|meta デバイス名|d200<br>/dev/dsk/c0t2d0s0 -> d30<br>/dev/dsk/c0t3d0s0 -> d40|


# ■ 手順

## 1. ディスク追加
ディスクを物理的に入れる。

## 2. 追加ディスクを format コマンドで /dev/dsk/c0t2d0s0 と同一スライスにする
```
# format
# > Specify disk (enter its number): 3
# > partition
# >> print
# >> select
# >> Specify table (enter its number)[2]: 1 # 正しくなければ改めて別の番号を select してみる
# >> print
# >> label
# >> print
# >> quit
# > quit
```

## 3. metadb を追加
```
# metadb -f -a -c 3 c0t3d0s7
```

## 4. メタデバイス名の割り当て
```
# metainit -f d30 1 1 c0t2d0s0
# metainit d40 1 1 c0t3d0s0
```

## 5. 片肺ミラーの設定
```
# metainit d200 -m d30
```

## 6. /etc/vfstabファイルの編集
```
#-- 元データ
# /dev/dsk/c0t2d0s0       /dev/rdsk/c0t2d0s0      /var/log        ufs     2       yes     -
# 
#-- 以下へ修正
# /dev/md/dsk/d200       /dev/md/rdsk/d200      /var/log        ufs     2       yes     -
```

## 7. システムリブート
```
# shutdown -y -g0 -i6
```

## 8. ミラーリング
```
# metattach d200 d40
```
Scipy optimizeで離散値を変数として使う方法

# 解決したいこと（モチベーション）
scipy optimizeを使って最適化したいものの、ものの個数など整数しか取らない変数を入力とするやり方がわからなかったので、その備忘録に

#解決策
scipy 公式の中に答えを見つけました。
https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.brute.html
scipy.optimize.brute (Minimize a function over a given range by brute force.)
Brute forceは無理やりにということであり、総当たり的に力づくで最適値を探すということですね

scipy.optimize.brute(func, ranges, args=(), Ns=20, full_output=0, finish=<function fmin at 0x2b45cb917e60>, disp=False)
という定義なのですが、このfinishは総当たり後にさらにその周辺を最適化するものなので、こちらをNoneにすると、rangesに定義されたグリッドのみを計算して最小の位置とその時の値を返して終わります
なので、これを用いてrangesで(slice(0,15,1),slice(0,10,1))の様に整数しか取らない様にslice()を定義すれば、整数のみで最小値を探します。

# 所感
正直総当たりであれば、np.meshgrid使って、あとはfor文を使ってえばいいじゃないという突っ込みはもちろん理解していますが、APIとして提供されていれば、不要な間違いなどが避けられていいかなと思うので、便利に使いたいと思います
PMP試験に出てくるコミュニケーション・チャンネル数を計算しよう！

# コミュニケーション・チャンネル数とは
ステークホルダー間のコミュニケーション経路の数のことである！
任意のステークホルダー２人の組み合わせの数だけ存在する！

## 計算方法
異なるn個からk個の組み合わせを選ぶ際の組み合わせの公式[n!/k!(n-k)!]より、
n=ステークホルダー数、k=2
になるため

```
コミュニケーション・チャンネル数 = (n) * (n - 1) / 2
```

# ステークホルダー数を2人から99人までをpythonでサクッと計算してみよう！
```python
$ python3
Python 3.7.3 (default, Mar  6 2020, 22:34:30) 
[Clang 11.0.3 (clang-1103.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> list(zip(list(range(2,100)) , list(map(lambda x:int(x*(x-1)/2), list(range(2,100))))))
[(2, 1), (3, 3), (4, 6), (5, 10), (6, 15), (7, 21), (8, 28), (9, 36), (10, 45), (11, 55), (12, 66), (13, 78), (14, 91), (15, 105), (16, 120), (17, 136), (18, 153), (19, 171), (20, 190), (21, 210), (22, 231), (23, 253), (24, 276), (25, 300), (26, 325), (27, 351), (28, 378), (29, 406), (30, 435), (31, 465), (32, 496), (33, 528), (34, 561), (35, 595), (36, 630), (37, 666), (38, 703), (39, 741), (40, 780), (41, 820), (42, 861), (43, 903), (44, 946), (45, 990), (46, 1035), (47, 1081), (48, 1128), (49, 1176), (50, 1225), (51, 1275), (52, 1326), (53, 1378), (54, 1431), (55, 1485), (56, 1540), (57, 1596), (58, 1653), (59, 1711), (60, 1770), (61, 1830), (62, 1891), (63, 1953), (64, 2016), (65, 2080), (66, 2145), (67, 2211), (68, 2278), (69, 2346), (70, 2415), (71, 2485), (72, 2556), (73, 2628), (74, 2701), (75, 2775), (76, 2850), (77, 2926), (78, 3003), (79, 3081), (80, 3160), (81, 3240), (82, 3321), (83, 3403), (84, 3486), (85, 3570), (86, 3655), (87, 3741), (88, 3828), (89, 3916), (90, 4005), (91, 4095), (92, 4186), (93, 4278), (94, 4371), (95, 4465), (96, 4560), (97, 4656), (98, 4753), (99, 4851)]
```

----
よかったよかった
AWSに静的ウェブサイトを構築する

AWSのS3を使って静的ウェブサイトを公開する。今回はCloudFrontを使わないためhttpまでの公開。「この時代にhttp？いるの？？」とツッコミたくなるが、新入社員向け入門用のメモとして記載してます。

# 全体構成図
AWS公式サイトより画像転載。
[静的ウェブサイトをホスティングする](https://aws.amazon.com/jp/getting-started/projects/host-static-website/)

![AWS_StaticWebsiteHosting_Architecture_4b.da7f28eb4f76da574c98a8b2898af8f5d3150e48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115108/a465c644-cd0f-9842-191e-069b467d6e1a.png)

- Aレコードの役割は別途

# 手順
[実装ガイド](https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html) に従って作業を行っていけばOKです。以下ざっくり手順。

### S3
1. S3にwebsiteホスティング用のバケットを作成（example.com)
2. S3にredirect用のバケットを作成(www.example.com)
3. ログ取得用のバケットを作成。無くてもいい
4. 1で作ったバケットに静的コンテンツ(html一式)をアップロード
5. パブリックアクセスを許可
6. バケットポリシーに書いてある内容をコピペし保存

### route53
1. ホストゾーンからレコードセット作成
2. ルートドメインのAレコード追加。設定内容はガイドどおり
3. サブドメインのAレコード追加。設定内容はガイドどおり

NSの値が４つあると思いますが、後で使います。


### お名前どっとこむ
私の場合、ここでドメインを取っています。
お名前どっとこむにログインし、`ネームサーバー設定 > その他のネームサーバーを使う`にし、route53のNSに設定されている値を登録。
<img width="817" alt="スクリーンショット 2020-04-27 0.33.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115108/1543c15a-ce35-2398-1ebe-7ff42c0c16bc.png">


# 接続テスト
S3に配置したindex.htmlの内容が表示されていることでしょう。
Jupyter Notebook Kernel errorについて(初心者)

# 事の発端
Jupyter notebookを２年前にインストールして使っていたが、環境が構築されておらず、デフォルトのまま使っていた。プログラミングにも慣れてきた事なので、さすがにデフォルト環境では使いづらくなり、とりあえずテーマから変えようと思った。

```
pip install jupyterthemes
```
したらば、カーネルが接続中のままいつまでたっても動き出さない。
そして…

```
Connection failed

A connection to the notebook server could not be established. 
The notebook will continue trying to reconnect. 
Check your network connection or notebook server configuration.
```
これ以降うんともすんとも…
1+1のような単純計算すらもしてくれなくなってしまいました。

一回Jupyterを再インストールしてみるも効果なし…
kernelの位置を動かしても効果なし…

マジで詰みました。

#エラーの分析
エラー解析をしているうちに得た知識は、「エラーがどこで発生しているか読む事」
今までは状況だけググって何がいけないか見てなかったですね。反省。
ターミナルに戻ってエラーの様子を見て見ました。

```
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py", line 16, in <module>
    app.launch_new_instance()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance
    app.start()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel/kernelapp.py", line 477, in start
    ioloop.IOLoop.instance().start()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 132, in start
    self.asyncio_loop.run_forever()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 408, in run_forever
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
ERROR:tornado.general:Uncaught exception in ZMQStream callback
```
これ以降同じような事の繰り返しになっていました。
ここでエラー吐いているのはtornadoのところですね。
ここのエラーメッセージでググって見ました。
すると…
[Jupyter notebookにRを追加したらPythonが動かなくなった時の対処の方法](https://qiita.com/hikusema189/items/5c3f988a88850c059fd2)
このページが表示。私とは状況が違うので今までの状況での検索には引っかからなかったみたいです。
このページの説明をみると、ipykernelをアップデートすれば良いとのこと。
なお、私はpipで環境を構築しているのでcondaではなくpipを用いて見ました。

```
pip install --upgrade ipykernel
```

すると、今までのエラーが嘘のように動いたのです！！よかった〜

#今回得られた知識
**エラーを吐いた時は、状況だけではなく、エラーコードを見つけて検索をかけること**
プログラマーにとっては基本中の基本かもしれませんが、初学者の私にとっては新たな気づきでした。また一つ賢くなった。

私と同じ現象で悩んでいる人がいる可能性もあるので残しておきます。私の方法でも解決しなかった方は、上のようにエラー部分を見つけることが大切になると思います。初歩的なことしか書いてなくてごめんなさい。
devise ユーザー登録場面でパスワード文字数を指定する方法



**deviseを用いsign_up,sign_in機能を実装しています。**
**よくある、パスワードの文字数指定について、どこに何を追記すべきかメモしておきます。**

環境
rails (5.2.4.2)

userモデルの:validatableに続けて、password_length: （指定文字数）..128と
記載すればOKです。
※128の意味は勉強中

7文字以上としたい場合は以下のようになります。

```ruby:user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable, password_length: 7..128

  validates :nickname, :password, :email, :last_name, :first_name, :ruby_last_name, :ruby_first_name, :birthdate, presence: true
  has_many :products
  has_one :ship_address
end
```

他にもいろいろと方法はあるようですが、比較的わかりやすいもののメモでした。

参考にさせていただいた記事
https://qiita.com/hirokihello/items/862284c60429be5e01cd

誤認識等あればご指摘いただければ幸いです🙇‍♂️
オンラインミーティングを字幕付きで翻訳しながら聞く

オンラインミーティングが増えている今日このごろ. 
国際会議もオンラインで開かれていることでしょう. 
そんなときに, 英語が聞き取れなくて「**自動で文字起こししたい**」とか「**翻訳したい**」って思いませんか?

実際に使ったわけではないですが, ふと思いついたのでここに記します. 

# 手順
- ループバック音源 (ステレオミキサー)
- Chrome
- ミーティングツール (zoom, skype, teams, pragli, ...)

## ループバック音源 (ステレオミキサー)の用意
ここではWindows環境を想定して書くが, Macでも「ループバック音源」って調べれば何か出るかもしれない. 
追記: どうやらMacでは有料or体験版のものしかないみたい. 何か無料のいい方法を見つけた方はコメントをお願いします. 

**ループバック音源**とはPCから出る音源のことである. 
たとえば, YouTubeで動画を再生すれば, その流れている音がループバック音源として扱われる. 
すなわち, Zoomなどでミーティング中は, 相手の声がループバック音源になるわけだ. 

**基本方針:「ループバック音源」を「Google翻訳」のマイク入力とする**

Windowsでは, ループバック音源は「ステレオミキサー」として知られている. 
ステレオミキサーのデバイスをONにするには, 以下のwebサイトがわかりやすい. 

- [Windows10でPCから出る音を録音 (ステレオミキサーを有効にする)](https://freesoft.tvbok.com/win10/general/stereo_mixer.html)
- [WINDOWSで再生される音声をループバック録音する方法](https://wolfish.org/blog/p2008052702/)

ステレオミキサーがどうしても現れない場合は, 次のサイトを参照していただきたい. 

- [ステレオミキサーがどうしても現れない場合の設定方法](http://ginga-express.cocolog-nifty.com/blog/2016/07/post-9840.html)
- [Stereo Mix missing in Windows 10? Did they remove it?](https://answers.microsoft.com/en-us/windows/forum/windows_10-hardware-winpc/stereo-mix-missing-in-windows-10-did-they-remove/abd60f1a-1ad2-4928-a7a2-b723d84bc5bc)

レジストリをいじるため, よく読んで自己責任で行ってください. 
よくわからない人は諦めることをオススメします. 

サウンドの「録音」タブで「ステレオミキサー」が表示されている状態になればOK. 
<img width="330" alt="sound.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/125a9fd3-fd4c-c738-ca2d-9172b601e72b.png">
※このとき, 「既定のデバイス」は「マイク」にしておかないと, ミーティング時に, 設定次第では自分の声が相手に届かず, パソコンの音が相手に届いてしまう可能性があります. 

## ChromeでGoogle翻訳を使う
Chromeで[Google翻訳](https://translate.google.com/?hl=ja)を開いて, 「音声入力をオンにする」を押して, マイクの使用を許可する. 
<img width="451" alt="google.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/47ffc7f3-9765-b7bf-37fa-f50b0aefa3c3.png">
そのあと, アドレスバーの右端のビデオマークを押して, マイクを「ステレオミキサー」に変更. 
<img width="243" alt="mic.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/7632e0f7-14e6-cdc2-c2f1-0c4a5f7480af.png">
変更後, リロード (Ctrl+R)してください. 
これで準備は整いました. 

## ミーティング時に使う
あとは, Zoomなどのミーティング時に, Google翻訳の「音声入力をオンにする」を押すだけです. 
特にミーティングに特化したことではないので, 試しにYouTubeの動画を翻訳してみよう. 
たとえば, [英語の耳を作る！中級リスニング特訓（日本語音声なし）](https://www.youtube.com/watch?v=-pGqGTB-V0Y)で試したところ, 
<img width="896" alt="translate.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/4412c458-141e-24aa-07e5-8569714636fa.png">
うまくいきました. 
これで自動文字起こしと翻訳が同時にできますね. 
Google翻訳以外にも, マイク入力から文字起こしするWebツールがあると思うので, ぜひ試してみてください. 

# おまけ
Zoomだと画面共有時にデフォルトでPCの音の共有もできますが, マイクをステレオミキサーにすれば, PCの音だけ共有できますね. (そのかわり, 自分の声が届かなくなるけど. )
また, PCの音声を共有できないミーティングツールでも, 共有できるのはいいですね. 

<img width="253" alt="zoom.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/72935aa4-2066-0a24-1905-7540dc19a026.png">

古いWindows時代にあった「ステレオミキサー」がなくなっていて, 表示させるのに苦労したので, そのメモとして残すために時代の流れに乗せて記事を書きました.
Vagrant + Arch Linux でCDイメージを挿入せずに VirtualBox Guest Additions を使えるようにする

# 手順 

```shell
sudo pacman -S base-devel linux-headers virtualbox-guest-utils-nox
```

（x11を使っている場合は -nox を外す必要があるかもしれない。これは未検証）

# 未起動で初回の `vagrant up` 時に自動で実行したいときの Vagrantfile の例
`Vagrant.configure("2") do |config|` のブロック内側に挿入すること。

```shell
# Enable Virtualbox Guest Additions without CD image.
config.vm.provision "shell", inline: <<-SHELL
  pacman -S --noconfirm vim
  vim -e /etc/pacman.d/mirrorlist -c '/Japan/;/^$/m0' -c 'wq!'
  pacman -Syuu --noconfirm
  pacman -S --noconfirm base-devel linux-headers virtualbox-guest-utils-nox
SHELL

### NOTE: Set false below if you have executed 'vagrant plugin install vagrant-vbguest'.
###       Or exec 'vagrant plugin uninstall vagrant-vbguest' instead.
# if Vagrant.has_plugin?("vagrant-vbguest") then
#   config.vbguest.auto_update = false
# end
```

- vim が関与する 2 行は日本のサーバを優先的に探しに行くために mirrorlist を変更すべく追記したもの。
- （コメントアウトした部分について）
  - プラグインを `vagrant plugin uninstall vagrant-vbguest` したことある場合に、行頭の # を解除すること。
      - `vagrant-vbguest` がインストールされているときに false にしてあげる必要がある。
  - `vagrant plugin uninstall vagrant-vbguest` しても似たような結果を得る。（が、プラグインアンインストールしてしまうので注意）

# 環境
- ホストOS: Windows 10 Pro (Version 1909, Build 19363.778)
- ゲストOS: archlinux/archlinux (virtualbox, 2020.04.02)
- VirtualBox バージョン 6.1.6 r137129 (Qt5.6.2)
- Vagrant 2.2.7 (64bit)
fish で ssh agent を永続化

# TL;DL
`~/.config/fish/config.fish`に以下を追記

```shell
set SSH_AGENT_FILE "$HOME/.ssh/ssh_agent"
test -f $SSH_AGENT_FILE; and source $SSH_AGENT_FILE > /dev/null 2>&1
if not ssh-add -l > /dev/null 2>&1
  if not ps -ef | grep -v grep | grep ssh-agent
    ssh-agent -c > $SSH_AGENT_FILE 2>&1
  end
  source $SSH_AGENT_FILE > /dev/null 2>&1
  find $HOME/.ssh -name id_rsa | xargs ssh-add
end
```

# fish 固有の仕様や構文の解説
## set
fish には代入構文がないため `set` コマンドを使います。

```
set 変数名 値
```

変数置換は bash などと同じように `$変数名` で使用可能です。
ちなみに `-x` オプションを付けることで `export` に相当するものになります。

## test [EXPRESSION]; and hogehoge

fish では 他のシェルと違って `&&` や `||` の代わりに以下を用います

```
&& -> and
|| -> or
!  -> not
```

そのため上記コード2行目 `test -f $SSH_AGENT_FILE; and source $SSH_AGENT_FILE > /dev/null 2>&1` では、 `$SSH_AGENT_FILE` が通常のファイルの場合 `source` コマンドで `$SSH_AGENT_FILE` を評価します。

## > と 2> と /dev/null
`>` と `2>` は標準出力と標準エラー出力をリダイレクトするために使います。
`echo "hoge" > file.txt` とすることで `file.txt` を `hoge` に書き換えることが出来ます。
しばしば上記コード内で出てくる`/dev/null`はnullデバイスとも呼ばれ、このファイルに出力することで、出力を捨てることが出来ます。
そのため `hoge > /dev/null 2> /dev/null`と書くことで標準出力と標準エラー出力ともに破棄することが出来ます。
また `&` の後にファイル記述子の番号を入れることで短く書くことも出来ます。

```
source $SSH_AGENT_FILE > /dev/null 2>&1
```

*標準エラー出力で使われていた`^`は廃止され将来削除予定なので`2>`を使いましょう。

# そのほか
ざっと fish 固有の構文や仕様などを解説しましたが、残りは bash などでも共通のものなので、上記コードがどういった流れで動作するのかを書いて終わりにしたいと思います。

1. `$SSH_AGENT_FILE` が通常のファイルの場合 `source` コマンドを用いて評価する
2. `ssh-add -l` からSSH Keyの登録を確認し無ければ分岐する
3. `ps -ef | grep -v grep | grep ssh-agent` で現在動作している `ssh-agent` プロセスがあるか確認、なければ `ssh-agent` を起ち上げる
4. `ssh-agent` を起動した際に書き込んだ `$SSH_AGENT_FILE` を再度 `source` コマンドを用い評価
5. SSH Key を `ssh-add` に渡して登録

# あとがき
これで WSL + VSCode で開発している際に Terminal を立ち上げるたび `passphrase` を入力しなくてすみます！すみました！🎉
PHPでの数字系の関数

**学習記録**

#前提条件
・PHP version 5.4

#数字系の関数

|関数|概要　　　　　　　　　|
|:-------------- |:------------------|
| ceil()　　　　　　　　　　|切り上げ|
| floot()　　　　　　　　　　|切り捨て|
| round()            　　　　|四捨五入|
| round(a, '○')　　　　　　　|aを小数○桁になるように四捨五入|
| mt_rand(a, b)             |aからbのランダム整数値を返す|
| max(a, b, c,...)          |()内の最大値を返す|
| min(a, b, c,...)          |()内の最小値を返す|
| M_PI         |円周率|
| M_SQRT2          |2の平方根|
PHPビルトイン関数～配列に関する関数～

**学習記録**

#前提条件
・PHP version 5.4

#配列に関するの関数
・array_unshift
・array_push
・array_shift
・array_pop
・array_slice
・array_splice

##array_unshift
配列の**先頭**に追加する

```PHP:書式
$変数=array_unshift(配列, 追加したい要素);
//追加したい要素は何個でも可能
```
```builtin.php
$input = [30, 40, 50];
array_unshift($input, 10, 20);
print_r($input);
//結果 : Array ( [0] => 10 
//　　　　　　　　[1] => 20 
//　　　　　　　　[2] => 30 
//　　　　　　　　[3] => 40 
//　　　　　　　　[4] => 50) 
```

##array_push
配列の**末尾**に追加する

```PHP:書式
$変数=array_push(配列, 追加したい要素);
//追加したい要素は何個でも可能
```
```builtin.php
$input = [30, 40, 50];
array_push($input, 60, 70);
print_r($input);
//結果 : Array ( [0] => 30 
//　　　　　　　　[1] => 40 
//　　　　　　　　[2] => 50 
//　　　　　　　　[3] => 60 
//　　　　　　　　[4] => 70) 
```

##array_shift
配列の**先頭**を削除する

```PHP:書式
$変数=array_shift(配列);
```
```builtin.php
$input = [30, 40, 50];
array_shift($input);
print_r($input);
//結果 : Array ( [0] => 40 
//　　　　　　　　[1] => 50 ) 
```

##array_pop
配列の**末尾**を削除する

```PHP:書式
$変数=array_pop(配列);
```
```builtin.php
$input = [30, 40, 50];
array_pop($input);
print_r($input);
//結果 : Array ( [0] => 30 
//　　　　　　　　[1] => 40 ) 
```

##array_slice
配列から切り出したい位置の先頭から何個分か切り出す

```PHP:書式
$変数=array_slice(配列, 切り出したい要素の先頭, 個数);
```
```builtin.php
$input = [30, 40, 50, 60, 70, 80];
$a = array_slice($input, 2, 3);
$b = array_slice($scores, 2);
$c = array_slice($scores, -2);
print_r($a);
//結果 : Array ( [0] => 50 
//               [1] => 60 
//               [2] => 70 ) 

print_r($b);
//結果 : Array ( [0] => 50 
//               [1] => 60 
//               [2] => 70 ) 

print_r($c);
//結果 : Array ( [0] => 60 
//               [1] => 70 )
```

##array_splice
配列のある位置から個数分排除

```PHP:書式
$変数=array_splice(配列, 切り出したい要素の先頭, 個数);
```
```builtin.php
$input = [30, 40, 50, 60, 70, 80];
array_splice($input, 2, 3);
print_r($input);
//結果 : Array ( [0] => 30 
//               [1] => 40 
//               [2] => 80 ) 

//追加することもできる
array_splice($input, 2, 3, 100);
print_r($input);
//結果 : Array ( [0] => 30 
//               [1] => 40 
//               [2] => 100 
//               [3] => 80 ) 


//個数を0にすると削除せずに置換する
$scores = [30, 40, 50, 60, 70, 80];
array_splice($scores, 2, 0, [100, 101]);
print_r($scores);
//結果 : Array ( [0] => 30 
//               [1] => 40 
//               [2] => 100 
//               [3] => 101 
//               [4] => 50 
//               [5] => 60 
//               [6] => 70 
//               [7] => 80 )
```
PHPのタイムスタンプについて

**学習記録**

#前提条件
・PHP version 5.4

#UNIXタイムスタンプ

|関数|概要　　　　　　　　　|
|:-------------- |:------------------|
| ceil()　　　　　　　　　　|切り上げ|
| floot()　　　　　　　　　　|切り捨て|
| round()            　　　　|四捨五入|
| round(a, '○')　　　　　　　|aを小数○桁になるように四捨五入|
| mt_rand(a, b)             |aからbのランダム整数値を返す|
| max(a, b, c,...)          |()内の最大値を返す|
| min(a, b, c,...)          |()内の最小値を返す|
| M_PI         |円周率|
| M_SQRT2          |2の平方根|

#日時を扱う関数

```builtin.php
//現在の秒数を表示する
echo time() . PHP_EOL;
//結果:1587889548

//年-月-日 曜日の表示
echo date('Y-m-d l', time()) . PHP_EOL;
//結果:2020-04-26 Sunday

//特定日時は時、分、秒、月、日、年の順で書く
echo date('Y-m-d l', mktime(0, 0, 0, 5, 1, 2020)) . PHP_EOL;
//2020-05-01 Friday

//日時のような文字列から UNIX タイムスタンプを作ることもできる
echo date('Y-m-d l', strtotime('2020-05-07')) . PHP_EOL;
//2020-05-07 Thursday

//足すこともできる
echo date('Y-m-d l', strtotime('2020-05-07 +1 day')) . PHP_EOL;
//2020-05-08 Friday
```
【googleスプレッドシート】シートIDを割り出す関数をつくる（セルへのリンクを動的に拾う方法）

スプレッドシートのシートにはIDが振られます。
シートのアドレスの末尾にある「#gid=XXXXXXXXX」というやつですね。

このIDを取得したい！ということがよくありませんか？
私はありません。

ないのですが、たまたまそういう場面に遭遇したので、解決方法を記しておきます。

ちなみにノンプログラマーの私が初めてGASをいじったのはこれをやるためでした。

#【解決方法】GASでシートIDを割り出す関数をつくる

スクリプトエディタを開き、以下の関数を定義して保存します。

```javascript
function sheetid() {
  return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId();
}
```
以上です。

これで、スプレッドシート上で`sheetid()`という関数を入力すれば、そのシートのシートIDを返してくれるようになります。

#【余談】セルへのハイパーリンクを動的に補足するために、この関数が必要だった
なぜこの関数が必要だったかといえば、セルへのハイパーリンクの仕様が原因でした。

スプレッドシートでは同スプレッドシート内のセルへのリンクが次のような形でつけられます。

`=HYPERLINK("#rangeid=XXXXXX")`

あるとき、特定のテキストをキーにして、このリンクするセルを動的に補足したいシーンがありました。
（特定のテキストが入ったセルにmatchさせてリンクしたかった）

なので、このrangeidというものをどうにか割り出せないかいろいろ調べたのですが、どうも方法が見つけられませんでした。（あるのかな…。）

それでいろいろ調べたところ、どうも同スプレッドシート内のセルへのリンクは、このような形でもできることがわかりました。

`=HYPERLINK("#gid=XXXXXXX&range=A1")`
そう、シートIDさえわかれば、「A1」などの単純な行列指定でリンクできるのです。

というわけでさらに調べた結果、シートIDなら割り出せたので事なきを得た…ということでした。

しかし今考えると、`getRow()`とか`getColumn()`あたりを使ってもやりようはあったな、とも思います。
ですがまあ、これはこれでシンプルでよかったかもしれない。
文字列を配列に、配列を文字列にする

**学習記録**

#前提条件
・PHP version 5.4

#配列⇔文字列　
・implode
・explode

##implode
配列を文字列にする

```PHP:書式
$変数=implode('配列の要素をつなげたい文字', 配列);
```
```builtin.php
$input = [10, 20, 30];
echo implode('-', $input);
//結果 : 10-20-30
```

##explode
文字列を配列にする

```PHP:書式
$変数=explode('どの区切りで配列にするか', 文字列);
```
```builtin.php
$input = '10:20:30';
print_r(implode(':', $input));
//結果 : Array ( [0] => 10 [1] => 20 [2] => 30 )
```
PHPビルトイン関数～固定長のデータを扱う～

**学習記録**

#前提条件
・PHP version 5.4

#固定長データを扱う関数
・substr
・substr_replace
・preg_match
・preg_replace

##substr
文字列の一部分を切り返す

```PHP:書式
$変数=substr(文字列, 抜き出したい最初の位置, 抜き出したい桁数);
//抜き出したい桁数を負にすると文字列の後ろから始まる
```
```builtin.php
$input = '20200422 Item-A  1200';
$date = substr($input, 0, 8);
echo $data;
//結果 : 20200422
```

##substr_replace
文字列の置換

```PHP:書式
$変数=strpos(文字列, 置換文字列, 抜き出したい最初の位置, 抜き出したい桁数);
```
```builtin.php
$input = '20200422 Item-A  1200';
echo substr_replace($input, 'Item-B', 8, 8);
//結果 : 20200422Item-B 1200
```

##preg_match
文字列からある文字列を抜き出して配列にする

```PHP:書式
preg_match(検索したい文字列, 文字列, 検索結果が代入される);
```
```builtin.php
$input = 'Call at 01-2345-6789 or 10-1112-1214';
$pattern = '/\d{2}-\d{4}-\d{4}/';
preg_match($pattern, $input, $matches);
print_r(($matches);
//結果 : Array ( [0] => 03-3001-1256 )

//allをつければすべて配列にはいる
preg_match_all($pattern, $input, $matches);
print_r($matches);
//結果 : Array ( [0] => Array ( 
//                              [0] => 03-3001-1256 
//                              [1] => 03-3015-3222 ) )
```

##preg_replace
文字列からある文字列を置換する

```PHP:書式
preg_replace(検索する文字列, 置換したい文字列, 文字列);
```
```builtin.php
$input = 'Call at 01-2345-6789';
$pattern = '/\d{2}-\d{4}-\d{4}/';
$input = preg_match($pattern, '**-****-****', $input);
echo $input;
//結果 : **-****-****
```
PHPで配列をソート、シャッフルする

**学習記録**

#前提条件
・PHP version 5.4

#配列のソートとシャッフル
・sort
・rsort
・shuffle
・array_rand

##sort
配列の要素を小さい順に並べる

```php:built.php
$scores = [40, 50, 20, 30];

sort($scores);
print_r($scores);
//結果: Array(
//             [0] => 20
//             [1] => 30
//             [2] => 40
//             [3] => 50)
```

##rsort
配列の要素を大きい順に並べる

```php:built.php
$scores = [40, 50, 20, 30];

rsort($scores);
print_r($scores);
//結果: Array(
//             [0] => 50
//             [1] => 40
//             [2] => 30
//             [3] => 20)
```

##shuffle
配列の要素をシャッフルする

```php:built.php
$scores = [20, 30, 40, 50];

shuffle($scores);
print_r($scores);
//結果: Array(
//             [0] => 40
//             [1] => 30
//             [2] => 50
//             [3] => 20)
```


##array_rand
配列からランダムでいくつかのキーを抜き出して新しい配列をつくる

```php:書式
array_rand(配列, 個数)
```

```php:built.php
$scores = [40, 50, 20, 30];

$picked = array_rand($scores, 2);

echo $scores[$picked[0]] . PHP_EOL;
//結果 :  50
echo $scores[$picked[1]] . PHP_EOL;
//結果 :  30
```
配列の値を集計する

**学習記録**

#前提条件
・PHP version 5.4

#配列のソートとシャッフル


##array_fill
配列を作る

```php:書式
array_fill(最初のインデックス, 要素の数, 要素の値)
```
```php:built.php
$scores = array_fill(0, 5, 10);
print_r($scores);
//Array(
//  [0] => 10
//  [1] => 10
//  [2] => 10
//  [3] => 10
//  [4] => 10)
```

##range
ある範囲の整数を有する配列を作成する

```php:書式
range(最初の値, 終わりの値)
```
```php:built.php
$scores = range(1, 5);
print_r($scores);
//Array(
//  [0] => 1
//  [1] => 2
//  [2] => 3
//  [3] => 4
//  [4] => 5)

//第三引数に数字を入れるとその数字分増加する
$scores = range(1, 10, 2);
print_r($scores);
//Array(
//  [0] => 1
//  [1] => 3
//  [2] => 5
//  [3] => 7
//  [4] => 9)
```

|関数|概要　　　　　　　　　|
|:-------------- |:------------------|
| max()　　　　　　　　　　|配列の要素の最大値|
| min()　　　　　　　　　　|配列の要素の最小値|
| array_sum()            　　　　|配列の要素の合計|
| conut()　　　　　　　|配列の要素の数|
graphql-playgroundでcookieが使われなくて困ったときに

ログインができなくて困るので、

画面右上の歯車をクリックして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/b78826f3-a0a6-94a3-c743-cceea8c060c5.png)

`request.credentials`を`omit`から`include`に編集して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/237e83ae-7235-6035-81f4-f84540f676bf.png)

歯車の下に現れたSAVE SETTINGSをクリックして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/bff49077-8b14-1ba8-65e4-82e0ffce16c3.png)

解決する。
シェルスクリプトでポインタ渡しっぽいものを使う

備忘録として記録しておく

# 概要
シェルスクリプト内で、引き渡した変数の値を変更する方法があった。
方法はいたってシンプルで変数の名前を関数に渡すことだ。

以下のようにすると関数内で変数の値を変更できる。

```shell

TEST(){
  eval $1=10
}

var=1
echo "var=$var"
TEST var
echo "var=$var"

```
結果

```
var=1
var=10
```

local 変数であっても変更できる

```shell
TEST(){
  eval $1=10
}
     
MAIN(){
   local var=1
   echo "var=$var"
   TEST var
   echo "var=$var"
}

MAIN

```

結果

```
var=1
var=10
```

引き渡された変数を横流ししても変更できる。

```shell
TEST1(){
    TEST2 $1
}

TEEST2(){
    eval $1=10
}

MAIN(){
    local var=1
    echo "var=$var"
    TEST1 "var"
    echo "var=$var"
}

MAIN

```

結果

```
var=1
var=10
```

インクリメントは以下の様に行う。

```shell
TEST2(){
    TEST1 $1
}

TEEST1(){
    eval "$1=\$((\$$1+1))"
}

MAIN(){
    local var=$1
    echo "var=$var"
    TEST2 "var"
    echo "var=$var"
}

MAIN 1
MAIN 5
```

結果

```
var=1
var=2
var=5
var=6
```
PHP関数～文字列を扱う関数～

学習記録

#前提条件
・PHP version 5.4

#文字列を扱う関数
・strlen / mb_strlen
・strpos / mb_strpos
・str_replace
・trim

##strlen/mb_strlen
文字をバイト数調べる

```PHP:書式
$変数=strlen(調べたい文字列);

//日本語対応
$変数=mb_strlen(調べたいの文字列);
```
```builtin.php
$input = 'string';
echo strlen($input);
//結果 : 6

$input = 'こんにちは';
echo mb_strlen($input);
//結果 : 5
```

##strpos/mb_strpos
文字列からある文字を探す
もし探したい文字列がなかったら**false**を返す

```PHP:書式
$変数=strpos(文字列,'探したい文字');

//日本語対応
$変数=mb_strpos(文字列,'探したい文字');
```
```builtin.php
$input = 'string';
echo strlen($input, 't');
//結果 : 1

$input = 'こんにちは';
echo mb_strlen($input, 'に');
//結果 : 2
```

##str_replace
文字列を置換する

```PHP:書式
$変数=str_replace('文字列にある文字' , '置換したい文字' , 文字列); //日本語にも対応できる
```
```builtin.php
$input = 'こんにちは';
echo mb_strlen('にち' , 'ばん' , $input);
//結果 : こんばんは
```

##trim
文字列の先頭及び末尾にある空白や改行を除去できる

```PHP:書式
$変数=trim(文字列);
```
```builtin.php
$input = ' string  ';
echo strlen($input);
//結果 : string
```
モーダル実装（Bootstrap不使用）

#モーダルを実装

モーダルを作りたいと思って調べてみると、
Bootstrapを使えば簡単にできそうです。

しかし、勉強の為にも、１から作ってみました！


**HTML**

```
  <div id="modal">
      <div class="modal-content">
         　<div class="modal-body">
            　<h1>hello</h1>
            　<button id="closeButton">Close</button>
          　</div>
       </div>
  </div>
  <!-- モーダル表示用ボタン -->
  <button id="openButton">Open Modal</button>

```

**CSS**

    #modal{
    　　display: none;
    　　position: fixed;
    　　z-index: 1;
    　　left: 0;
    　　top: 0;
    　　height: 100%;
    　　width: 100%;
    　　overflow: auto;
    　　background-color: rgba(0,0,0,0.5);
    }
    
    .modal-content{
    　　background-color: white;
    　　width: 500px;
    　　margin: 15% auto;
    }

**JavaScript**

```

const modal = document.getElementById('modal');
const openButton = document.getElementById('openButton');
const closeButton = document.getElementById('closeButton');


openButton.addEventListener('click', () => {
  modal.style.display = 'block';
});

closeButton.addEventListener('click', () => {
  modal.style.display = 'none';
});

```

以上です！
Herokuへのアップロードでつまづいた時の対処法 Node.js + MongoDB

自分の経験をここに記述します。

【経緯】先日、EJS, CSS, JavaScript, MongoDB, Nodeを使って作成したWebsiteをHerokuにアップロードしようと試みた時、正常にアップロードできず、丸2日間の時間を犠牲にした上でようやく問題解決までに至りました。ここで記載することがいつかこれを見た未来の困っている方々への手助けになればと思います。

【方法】ステップに分けて説明していきます。MongoDBを使用している場合には、別の記事でその追加で必要な方法を記述します。

１：Command Line(Hyper Terminal)がアップロードしようとしているファイルのパスを正しく選択しているか確認する。

２：Command Line(Hyper Terminal)からHerokuへとログインする。
コマンド：$heroku login　

３：GitをInitializeし、add、commitする。以下順々にコマンドを実行する。
コマンド：$git init 　

コマンド：$git add . 

コマンド：$git commit -m "sample message"

４：HerokuでURLを作成する。　
コマンド(urlが何でもいい場合)：$heroku create 　
コマンド(自分のオリジナルを作成する場合)：$heroku create ここに半角英数でタイプする。但し他ユーザーがすでに使用している場合は、そのurlは使えない。

５：Gitにpushをする。　
コマンド：$git push heroku master

６：現状では正しくHerokuへとアップロードはされません。ほぼ100%エラーの表示がでます。これからそのエラーを直していきましょう。

７：自分のファイル内にprocfileが作成しているか、確認する。procfileが何か分からない場合はこの方の記事を参考にしてみてください。 https://creepfablic.site/2019/06/15/heroku-procfile-matome/

８：procfileの中身が正しく記載されているか確認する。私の場合、web: node app.js、app.jsはあくまでも私がよく使うファイル名のためindex.jsや他のファイル名の場合はそちらに書き換えてください。

９：app.listen(process.env.PORT || 3000, function( ){

console.log("The server 3000 is now up and runnning")

});

私の場合、app.jsの中にローカルサーバーを立ち上げるためのapp.listenを入力しているので、そこにprocess.env.PORTと追加されているか確認する。

１０：再度、Command Line(Hyper Terminal)の画面に戻る。そして自分のファイルへのパスが選択されている状態で、次のコマンドを入力する。コマンド：$heroku buildpacks

そのコマンドを入力した時にheroku/nodejsと表示されていれば特に何もしなくて良い。しかし、何も表示されない、もしくは別のものが表示された場合には次のコマンドを入力する。
コマンド：$heroku buildpacks:set heroku/nodejs

１１：もう一度、コマンド：$heroku buildpacksを入力して正しくheroku/nodejsと表示されるか確認する。

１２：自分のパソコンにインストールされているNodeとNpmが最新版であるか確認する。どこでインストールするか分からない場合は👉 https://nodejs.org/ja/ で推奨版をダウンロードする。左のバージョン。

コマンド：$node --version 　

コマンド： $npm --version

１３：自分のファイルの中にpackage-lock.jsonというファイルが作られているか確認する。作成されていない場合は次のコマンドを入力する。
コマンド：$npm install

１４：package-lock.jsonの中に以下のプログラムが記載されているか確認する。されていない場合は順番はどこでもいいのでファイル内に付け加える。NodeとNpmのバージョンは2020/04時点のものなので、最新かどうかは👉https://nodejs.org/ja/　　
で確認する。右側の最新版のバージョンをnodeに記述する。最後のxの部分は変更しなくて大丈夫。scriptsのapp.jsはあくまでも私が使用しているファイル名なので、これは各個人のファイル名に直す。

"engines": {
"node": "^14.0.x",
"npm": "6.14.x"
}

"scripts": {
"start": "node app.js"
}

１５：.gitignoreファイルが作成しているか、確認する。まず次のコマンドを入力する。

コマンド：$git ls-files | grep node_modules

もしも、上記のコマンドを入力した際にリストがズラーーーっと表示された場合は以下のコマンドを順々に入力する。表示されなかった場合は多分.gitignoreが作成されていると思う。

コマンド：$echo "node_modules" >> .gitignore

コマンド：$git rm -r --cached node_modules

コマンド：$git commit -am 'untracked node_modules'

１６：再度、.gitignoreが作成されているか、コマンド：$git ls-files | grep node_modules、を入力して確認する。自分のファイル内で.gitignoreというファイルが作成されているのを確認できればおっけい。

１７：.gitignoreの中にnode_modulesと記載されていると思うので、その下に以下のコマンドを入力する。

/lib　　←この4文字を記述する。

１８：これであとは再度Herokuへのアップロードを試みる。以下の順でCommand Line(Hyper Terminal)内でコマンドを実行する。

コマンド：$heroku login

コマンド：$git init

コマンド：$git add .

コマンド：$git commit -m "whatever you want to type"

コマンド：$git push heroku master

これで正しくHerokuへとアップロードが完了するはずです。

１９：最後に、冒頭にも書きましたが、MongoDBを使用している場合はもうワンステップ必要な作業がありますので次回のストーリーを参考にしてみてください。
Mysqlで外部ファイルを実行する。

コマンドプロンプトで外部ファイルを実行したいフォルダに行く。

mysql -u root
でログインをする

 \. 「create_myapp.sql」
または

source 「create_myapp.sql」

「」は外部ファイル名

これで実行可能


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620350/5cdddbd6-7665-e1b9-d110-585c9fd9150f.png)