OmniAICreator/Qiita-1.07M huggingface dataset:
C言語グローバル変数の宣言

#目的
グローバル変数の使用方法及びその確認

***@fujitanozomu さんから色々アドバイスを頂きましたので、このメモを大幅に修正しました。
修正履歴をできるだけキープしたいですがプログラムファイルの差分の表示はできませんでしたので記事だけを差分するようにしました。***

#ファイル
main.c：~~グローバル~~変数numの~~宣言~~定義および順番でAとB ***（AもBも外部関数。外部で変数は確実にグローバルになったかを確認）***を処理
***（追記）main.h：変数numをexternで宣言。他のcファイルはこのヘッダーをincludeすることで変数numはグローバルになる。***
A.h：~~グローバル変数numを使用することを宣言~~関数Aは外部で使用されることを宣言
A.c：***main.hをincludeし***numを変更して出力（グローバル変数numが変更される）
B.h：~~グローバル変数numを使用することを宣言~~関数Bは外部で使用されることを宣言
B.c：***main.hをincludeし***numを変更せずに出力（Aで変更されたグローバル変数numを出力）

上記のファイルで、mainで宣言されているnumは、AとBからも使用でき（グローバル変数になるため）、numがAで変更されても、Bからもその変更を確認できることを証明

#ファイルの中身
```c:main.c
#include"main.h"
#include"A.h"  //Aの関数を使用するため
#include"B.h"  //Bの関数を使用するため

int num;   //変数を宣言

int main(int argc, char *argv[]){
    A();   //numを他のファイルで変更させる
    B();   //他のファイルで変更されたnumを確認
    return 0;
}
```

```c:main.h
extern int num;  //他のファイル（ここはmain.c）にnumは定義されているよ、という意味
```


```c:A.h
extern void A();  //A.cで定義されている関数Aは外部で使用されるためにexternで宣言
```

```c:A.c
#include<stdio.h>
#include"A.h"
#include"main.h"  //ここでnumはグローバルになる

 void A(){
     num = 10;   //グローバル変数を変更
     printf("inside A, num = %d\n", num);   //グローバル変数を変更して出力
 }
```

```c:B.h
extern void B();  //B.cで定義されている関数Bは外部で使用されるためにexternで宣言
```

```c:B.c
#include<stdio.h>
#include"B.h"
#include"main.h"  //ここでnumはグローバルになる

void B(){
    printf("inside B, num = %d\n", num);   //グローバル変数を変更せずに出力
}
```

```shell
#Aの共有ライブラリを作成
[pirlo@centos8 02]$ gcc -shared -o libA.so -c A.c
#Bの共有ライブラリを作成
[pirlo@centos8 02]$ gcc -shared -o libB.so -c B.c
#メイン処理をコンパイルして実行ファイルを作成
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  B.c  B.h  libA.so  libB.so  main  main.c  main.h
```

```shell:実行結果
[pirlo@centos8 02]$ ./main 
inside A, num = 10   #Aでグローバル変数を変更
inside B, num = 10   #BからAで変更されたグローバル変数を確認
```

***追記***
>https://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

***この記事により、関数は変数と違い、コンパイルされる際、コンパイラはexternがあるように処理するためexternを明記しなくても大丈夫のようです。実際にテストしたところ、main.hから#include"A.h"と#include"B.h"を削除しても無事コンパイル・実行できました。***
componentDidMountでReflow

chromeブラウザでReflowがCSSアニメーションと相性悪いようで、余計なアニメーションが走ってしまうことがある。

### 画面内容

画面遷移が発生する時に、次のように遷移先の画面が右側から左に移動するようCSSアニメーションが実装されている。

```scss
	&SlideFromRight-enter,
	&SlideFromRight-appear {
		left: 100%;
		transition: all 300ms cubic-bezier(.165, .84, .44, 1);
		pointer-events: none;
		opacity: 0;

		&-active {
			left: 0;
			opacity: 1;
		}
	}

	&SlideFromRight-exit {
		left: 0;
		transition: all 300ms cubic-bezier(.165, .84, .44, 1);
		pointer-events: none;
		opacity: 1;

		&-active {
			left: -100%;
			opacity: 0;
		}
	}

```

### 問題点

低スペックのandroid端末で、偶に真白な画面が描画されてしまって、アニメーションが止まってしまったように見える。

### 調査

React.ComponentのcomponentDidMountで`window.innerHeight`などをアクセスしている為、Reflowが発生してしまう。その時、余計なアニメーションが走っていることがわかる。

`window.innerHeight`をアクセスする処理を削除すると、余計なアニメーションがなくなり、真白画面もなくなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123446/a984d266-d7d6-c1a7-7eaf-fb479fb5c10a.png)

### 対応

Reflowを発生させる上記処理をsetTimeoutで遅延することで、余計なアニメーションがなくなる。


### 参考記事

- [Reflowを制するものはDOMを制す](https://qiita.com/jkr_2255/items/5cdead4ee7fa289bfeed)
- [CSS プロパティのアニメーション](https://developer.mozilla.org/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties)
🧩いれてよかったChrome拡張

## おはようございます🌿
こんにちは，はじめまして．久野です．Qiita投稿初めてです．
すごくいきなりですがエンジニアとしてQOLの上がったChrome拡張を紹介します．

## Wappalyzer

[ここ](https://chrome.google.com/webstore/detail/wappalyzer/gppongmhjkpfnbhagpmjfkannfbllamg?hl=ja)からダウンロード．
サイトが使用しているCMSや言語などの種類，バージョンが一発でわかる．下記写真は自分のGithubです．

<img width="494" alt="スクリーンショット 2020-03-23 10.18.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149433/d4ef9ac9-4758-54e3-273a-77cbfe6223a6.png">


## JSON Viewer

[ここ](https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh)からダウンロード．
ブラウザ上で見るとただのテキストと化すjsonを色付けしてくれる．

<img width="635" alt="スクリーンショット 2020-03-23 10.22.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149433/9f5f0278-c289-017f-8ed2-d523d11931aa.png">

## Octotree

[ここ](https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc/related?hl=ja)からダウンロード．
Github上でソースコードを左側にツリーで表示できる．（プライベートリポジトリだと表示されず…）

<img width="1440" alt="スクリーンショット 2020-03-23 10.25.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149433/97484a8e-5879-e695-1004-adad4b9d630f.png">


## vimium
[ここ](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb)からダウンロード．
クロームブラウザをvimコマンドで動かせます．下の画像はFを押した後の画面で，示されているコマンドを次に打つとその場所へ遷移します．

<img width="1000" alt="スクリーンショット 2020-03-28 11.23.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149433/ca84ee33-a004-8253-acee-ab9f89aad0cb.png">

## Embark（2020.12.22追記）
[ここ](https://chrome.google.com/webstore/detail/embark-new-tab-page/aeajehgeohhgjbhhbicilpenjfcbfnpg?hl=en)からダウンロード．
Chromeの新規ブラウザにお洒落な壁紙とミニマル時計を表示してくれるもの！リロードするたび画像が変わります．お洒落だし時計が見やすくて好き．
![スクリーンショット 2020-12-22 16.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149433/7b5497bc-c5ba-7f10-d90b-6e82c9b9f143.png)


## おわり🥀
また何かいいのがあれば紹介します．
Android Studioのstudioコマンドでカレントプロジェクトが開けない


# そもそもstudioコマンドとは

以下を実行すると、デフォルトでは'/usr/local/bin/'にstudioがインストールされます。

Android Studioのメニュー -> Tool -> Create Command-line Luncher...

![create_command_line_launcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/e44f64f6-09eb-68f1-d6a0-b2ffe080193e.png)

これをやっておくと、コマンドラインでプロジェクトのカレントディレクトリにいるとき、以下でプロジェクトを開くことができます。

```shell
studio .
```

もちろん相対パスでも開くことができるのでUI上から開くより楽ですね。


# 解決方法

いつからかプロジェクトが開かずAndroid Studioが起動するだけになっていました。

`/usr/local/bin/studio`を見てみると以下のようになっていました。

```shell
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import socket
import struct
import sys
import traceback

# see com.intellij.idea.SocketLock for the server side of this interface

RUN_PATH = u'/Applications/Android Studio.app'
CONFIG_PATH = u'/Users/kanari3/Library/Preferences/AndroidStudio3.5'
SYSTEM_PATH = u'/Users/kanari3/Library/Caches/AndroidStudio3.5'
.
.
.
```

Android Studioのversionをアップデートしたのでパスがあっていなかったようです。
現行のversion (今回は3.6) に書き換えて正しく動作するようになりました。

# おわり

ほとんどのマシンでは「Create Command-line Luncher...」を再度実行するだけで修正されると思います。
どうしても直らないときは確認してみると良いでしょう。
自動デプロイ

Encrypted Credentials
外部に公開したくない値を管理するための仕組み

vsコードで、shell入力
メニューに、「PATH内に'code'コマンドをインストールします」という項目が表示されるので、それをクリック

credentialsを編集
編集したいディレクトリにいることを確認
ターミナルで
EDITOR=vim bin/rails credentials:edit
ActiveSupport::MessageEncryptor::InvalidMessage (ActiveSupport::MessageEncryptor::InvalidMessage)
が出て表示されない。
原因
vsコードのcredentials.yml.encを削除してから
EDITOR=vim bin/rails credentials:edit
を行うと作成されて編集できる、このとき，config/master.key は，存在していなければ作られるし，存在していればそれが使われる
【Python】OpenCVによる画像の画素へのアクセスと切り取り (初心者向け)

#はじめに
OpenCVを用いて画像をどうやって切り取るかを解説します。一応[前回](https://qiita.com/sino20023/items/b14c0dd7f90cda99b47f)の続きなので、もしこの記事でわからないところがあれば、ご覧ください。

#環境
MacOS Mojave
Python 3.7

#使用画像
以下の画像 (neko.jpg) を使用します。
![neko.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288555/e45a175e-acd1-8142-5ab5-2bac563dc97e.jpeg)


#画像の大きさを確認
以下のコードで画像の大きさを確認できます。

```Python:
#ライブラリの読み込み
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("neko.jpg")
print(img.shape)
```
以上のコードを実行すると、以下の結果が出ます。

```
(900, 1600, 3)
```

これは、縦が900ピクセル、横が1600ピクセル、チャンネル数が3という意味です。チャンネル数はカラー画像の場合はGBRの３つなので、３になります。グレースケールだと、白色の度合いだけなので、チャンネル数は１となります。

#画像の座標
Opencvにおいて、画像の座標軸は以下のようになります。
![座標.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288555/6be14dba-c72e-5f8a-604d-21d3b0037027.png)

位置を(x,y)とするとき、原点(0,0)は図のように左上にきます。画像を扱う場合は下方向がy軸の正の方向になるので注意してください。
この画像の大きさは縦が900ピクセル、横が1600ピクセルなので、画像の末端のピクセルのx,y座標はそれぞれ899,1599となります。900、1600にならないのは、原点0から数えているためです。

#画像の座標へのアクセス
画像の座標を以下のように指定すると、その位置の色の値を取得することができます。

```python:
img = cv2.imread("neko.jpg")
print(img[450,800])
```

```:出力
[153 161 190]
```
これは、座標(450,800)の位置の色が(R,G,B) = (153,161,190)であることを示しています。
また、以下のようにすると座標を複数指定できるようになります。

```python
print(img[450:650,800:1000])
```
```出力
[[[153 161 190]
  [153 161 190]
  [152 160 189]
  ...
  [169 178 205]
  [169 178 205]
  [169 178 205]]

 [[152 160 189]
  [152 160 189]
  [153 161 190]
  ...
  [169 178 205]
  [169 178 205]
  [169 178 205]]

 [[151 159 188]
  [152 160 189]
  [154 162 191]
  ...
  [171 178 205]
  [172 179 206]
  [172 179 206]]

 ...
以下省略。。。

```
[]の中にある":"は私たちが普段数字の範囲を表す時に使う"~"と同じと考えてください。上の例では、座標(450,800)から(649,999)までの範囲の色の情報を出力しています。
![座標_位置指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288555/2ce4e0df-0407-92a7-9686-a166a50b3530.png)

#任意の位置で切り取り
指定した画像の範囲を別のオブジェクトに入れれば、その位置を切り出した画像を得ることができます。

```python:
#ライブラリの読み込み
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("neko.jpg")
#指定した画素をimg_trimに代入
img_trim = img[450:650,800:1000]
#色を変更
img_trim = cv2.cvtColor(img_trim, cv2.COLOR_BGR2RGB)
#表示
plt.imshow(img_trim)
plt.show()
```

![切り取り画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288555/2f4da262-f4c9-e404-5715-1d7841890aa0.png)

以上のような画像が出力されれば成功です!(畳なので切り取りが行われているかどうかわかりずらいですが。。。笑)
次回は画像の拡大縮小反転など、こねくり回す作業を解説したいと思います:blush:

#Twitterやってます
今後の記事の情報や質疑応答など色々やりたいと思うのでよければ、フォローお願いします、、、！:relieved:
https://twitter.com/ryuji33722052
プログラム無しでチャットボット作ってみた〜アカウント作成編〜

#はじめに
**[IFRO](https://ifro.ai/)**はパルスボッツ株式会社が提供するサービスで、プログラム無しで誰でもかんたんにチャットボットが作れるようになるサービスとのこと。
今回は、こちらのサービスを利用して、ユーザーと自動でやりとり出来るチャットボットを作成することをゴールにします。
![スクリーンショット 2020-03-23 05.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/3b4f8b69-8124-475b-fb53-8c79b3fea701.png)
なんか個人的にはとても好きなデザインのページです。

料金プランは、この4つに加えてエンタープライズプランというプランの5つのようです。
今回は一旦お試しということで、「FREE」でやってみようと思います。

![スクリーンショット 2020-03-23 05.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/c30cd8e6-1938-5c93-888c-e52808ef0511.png)

**[「無料ではじめる」](https://ifro.ai/)**を押すと登録画面が現れます。
![スクリーンショット 2020-03-23 05.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/f789e736-4603-d59d-1a89-596255efc7e3.png)

アカウント作成用のID、表示名、メールアドレスとパスワードを聞かれるので入力して登録します。
ちょっとわかりにくいですが、IDはメールアドレス、表示名は自分お名前を入れたら大丈夫そうです。

![スクリーンショット 2020-03-23 05.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/e7030ba7-c3cd-d543-590b-5c680c3c44c2.png)

登録したメールアドレスにIFROから確認メールがすぐに届くので、登録完了ボタンを押せば登録完了です。
<img width="787" alt="スクリーンショット 2020-03-23 05.53.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/065b81bb-9481-9095-4b21-5776c45e3188.png">

これでIFROアカウントの作成は完了です。
<img width="444" alt="スクリーンショット 2020-03-23 05.53.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/3a8a9839-5ced-b18f-4856-6dccdc779bbb.png">

この時点ではクレジットカードなどの登録は必要なく、先ほど入力した情報のみで大丈夫です。

![スクリーンショット 2020-03-23 06.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/4835906f-4e73-2473-84d6-fa8238089374.png)

今回は無料で試しますが、有料プランに変更する時は左下の自分の名前(表示名で入力した名前)をクリックしてアカウント情報のページからクレジットカードを登録してプラン変更をすれば良さそうです。
![スクリーンショット 2020-03-23 06.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56585/74840a2e-3551-7d8d-5765-5c23f78b9e3d.png)

#関連
[プログラム無しでチャットボット作ってみた〜とりあえず動かしてみた編〜](https://qiita.com/mat_aaa/items/c791905b6965fd2faa43)
[プログラミング無しでのLINE BOTの作り方](https://qiita.com/mat_aaa/items/3357bcb1d7f7e9f404cc)
[プログラミングせずにLINEでQ&Aボット作った](https://qiita.com/mat_aaa/items/80732b73a2985eb32cfb)
メモ: CircleCI

## 概要

* 無料枠がある
    * docker buildが出来る
    * 定期的に実行が出来る
* GitHubのリポジトリに以下ファイルを用意

```go
.circleci/config.yml

project/requirements.txt
project/test_run.py
```

### `.circleci/config.yml` について

* 定期実行の定義

```diff:.circleci/config.yml抜粋
 workflows:
   version: 2
   normal_workflow:
     jobs:
       - build
   schedule_workflow:
     triggers:
       - schedule:
           # UTCで記述。例: JST10時 => UTC1時
+          cron: "5 1,13 * * *"
           filters:
             branches:
               only:
                 - master
     jobs:
       - build
```
lockファイルがコンフリクトしたときの対処法



ヾ(・ω<)ﾉ"　三三三●　ⅱⅲ コロコロ♪

----
------------------- ↓ 余談はここから ↓-------------------

lockファイルでインストールを制御ってのは、
割と理想論だと思っている。

まぁ、それはいいとして、
lockファイルをコミットすると、
ほぼ間違いなくコンフリクトする。
そんなときの対処法を残しておこう。

----
------------------- ↓ 本題はここから ↓-------------------

## composer.lock

コンフリクトを適当に解消して以下のコマンドを打つ

```
$ composer update --lock
```


## package-lock.json

コンフリクトした状態のまま以下のコマンドを打つ

```
$ npm install
```
C#：列挙型の解説

```Sample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 列挙型とは？
// * コードを読みやすくするためのもの（可読性をあげる）
// * 制限の中から選択可能にするもの

public class Sample : MonoBehaviour
{
    enum DIRECTION {
        UP,
        DOWN,
        RIGHT,
        LEFT,
    }

    DIRECTION direction = DIRECTION.DOWN;
    int directionInt = 0; // 0:上

    void Start()
    {

        if (directionInt == 0)
        {
            Debug.Log("下");
        }
        else if(directionInt == 1)
        {
            Debug.Log("上");
        }

        switch (direction)
        {
            case DIRECTION.DOWN:
                Debug.Log("下");
                break;
            case DIRECTION.UP:
                Debug.Log("下");
                break;
            case DIRECTION.RIGHT:
                Debug.Log("下");
                break;
            case DIRECTION.LEFT:
                Debug.Log("下");
                break;
        }

        /*
        if (direction == DIRECTION.Down)
        {
            Debug.Log("下");
        }
        else if (direction == DIRECTION.Up)
        {
            Debug.Log("上");

        }
        else if (direction == DIRECTION.RIGHT)
        {
            Debug.Log("右");

        }
        else if (direction == DIRECTION.LEFT)
        {
            Debug.Log("左");
        }
        */

    }
}

```
C#：2次元配列の解説


<img width="597" alt="スクリーンショット 2020-03-23 9.51.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67439/82fd1fb7-f4c4-1c98-6abf-34fcfb17b8f4.png">


```Sample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 2次元配列
// * Table/表

public class Sample : MonoBehaviour
{
    // 宣言方法
    // １次元配列
    int[] arrayInt = new int[3];
    // 2次元配列
    int[,] tabelInt = new int[3, 2];
    void Start()
    {
        // 代入方法
        tabelInt[0, 0] = 1;
        tabelInt[2,1] = 10;
        // 取得方法
        //int x = tabelInt[0, 0];

        //長さ
        //Debug.Log(arrayInt.Length);
        Debug.Log(tabelInt.GetLength(0));
        Debug.Log(tabelInt.GetLength(1));
        for (int x = 0; x<tabelInt.GetLength(0); x++)
        {
            for (int y = 0; y < tabelInt.GetLength(1); y++)
            {
                Debug.Log(tabelInt[x,y]);
            }
        }
        for (int y = 0; y < tabelInt.GetLength(1); y++)
        {
            for (int x = 0; x < tabelInt.GetLength(0); x++)
            {
                Debug.Log(tabelInt[x, y]);
            }
        }
    }
}
```
Golangで、デザインパターン「Singleton」を学ぶ

GoFのデザインパターンを学習する素材として、書籍「[増補改訂版Java言語で学ぶデザインパターン入門](https://www.hyuki.com/dp/)」が参考になるみたいですね。
取り上げられている実例は、JAVAベースのため、Pythonで同等のプラクティスに挑んだことがありました。
[Qiita記事: "Pythonで、デザインパターン「Singleton」を学ぶ"](https://qiita.com/ttsubo/items/c4af71ceba15b5b213f8)

今回は、Pythonで実装した”Singleton”のサンプルアプリをGolangで実装し直してみました。

# ■ Singleton（シングルトン）
Singletonパターン（シングルトン・パターン）とは、オブジェクト指向のコンピュータプログラムにおける、デザインパターンの1つである。GoF (Gang of Four; 4人のギャングたち) によって定義された。Singleton パターンとは、そのクラスのインスタンスが1つしか生成されないことを保証するデザインパターンのことである。ロケールやルック・アンド・フィールなど、絶対にアプリケーション全体で統一しなければならない仕組みの実装に使用される
![600px-Singleton_UML_class_diagram.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103595/89b5b15a-231d-54e6-87d5-291393f2b045.png)
[(以上、ウィキペディア（Wikipedia）より引用)](https://ja.wikipedia.org/wiki/Singleton_パターン)

# ■ "Singleton"のサンプルプログラム

# ■ サンプルプログラムの詳細
Gitリポジトリにも、同様のコードをアップしています。
https://github.com/ttsubo/study_of_design_pattern_with_golang/tree/master/Singleton

- ディレクトリ構成

```console
.
├── step1
│   └── Main.go
└── step2
    └── Main.go
```

インスタンスが一つしか作成できないようなクラスを定義してみます。

```go:step1/Main.go
package main

import "fmt"

// Singleton is struct
type Singleton struct {
}

// MyClass is struct
type MyClass struct {
	Singleton
	input int
}

var instance *MyClass

func getInstance(input int) *MyClass {
	if instance == nil {
		instance = &MyClass{input: input}
	} else {
		instance.input = input
	}
	return instance
}

func main() {
	one := getInstance(1)
	fmt.Printf("one.input=%d\n", one.input)
	two := getInstance(2)
	fmt.Printf("one.input=%d, twe.input=%d\n", one.input, two.input)
	one.input = 0
	fmt.Printf("one.input=%d, twe.input=%d\n", one.input, two.input)
}
```
動かしてみる

```console
$ go run step1/Main.go 
one.input=1
one.input=2, twe.input=2
one.input=0, twe.input=0
```
なるほど、まるでグローバル変数のように振る舞いますねぇー

あと、こちらのWeb記事["Go 言語における Singleton Pattern"](https://text.baldanders.info/golang/singleton-pattern/)を参考に、少し、実装を修正してみます。

```go:step2/Main.go
package main

import "fmt"

// Singleton is struct
type Singleton struct {
	input int
}

func (s *Singleton) getInstance(input int) *Singleton {
	s.input = input
	return s
}

// MyClass is struct
type MyClass struct {
	Singleton
}

var myclass = &MyClass{}

func main() {
	one := myclass.getInstance(1)
	fmt.Printf("one.input=%d\n", one.input)
	two := myclass.getInstance(2)
	fmt.Printf("one.input=%d, twe.input=%d\n", one.input, two.input)
	one.input = 0
	fmt.Printf("one.input=%d, twe.input=%d\n", one.input, two.input)
}
```
動かしてみる

```console
$ go run step2/Main.go
one.input=1
one.input=2, twe.input=2
one.input=0, twe.input=0
```
同じ結果になりました
個人的に、こちらの書き方の方が、しっくりくる感じです

# ■ 参考URL
- [Pythonで、デザインパターン「Singleton」を学ぶ](https://qiita.com/ttsubo/items/c4af71ceba15b5b213f8)
- ["Go 言語における Singleton Pattern"](https://text.baldanders.info/golang/singleton-pattern/)
WebRTCでスマホのカメラ切り替え(前面-背面)

agora.io WebSDKを利用したスマホのカメラ切り替えの説明です。
サンプルコードは[こちら](https://github.com/fu-jimoto/AgoraIO-MobileSwitchCamera)にあります。
基本的に映像Trackを切り替える事で実現可能ですが、一部Android(HUAWEIやSamsung）で正常に動作しない場合があるので2種類記載します。

## 利用するAPI一覧
- AgoraRTC.createStream()
- Stream.replaceTrack()
基本的にはこの２つで実現可能です。

## 初期のカメラ指定
```javascript:index.html
var facingMode = "user";
//中略
rtc.localStream = AgoraRTC.createStream({
  streamID: rtc.params.uid,
  audio: true,
  video: true,
  screen: false,
  microphoneId: option.microphoneId,
  facingMode: facingMode
})
```
"facingMode"で前面カメラか背面カメラを選択できます。"user"が前面カメラ、"environment"が背面カメラになります。

## 手法１
Stream.replaceTrack()で簡単に切り替える方法です。

```javascript:index.html
var facingMode = "user";
if(facingMode == "user"){
  facingMode = "environment";
}else{
  facingMode = "user";
}
var localStream2 = AgoraRTC.createStream({
  video: true,
  audio: false,
  facingMode: facingMode
});

localStream2.init(function(){
  var newVideoTrack = localStream2.getVideoTrack();
  rtc.localStream.replaceTrack(newVideoTrack);
  rtc.localStream.stop();
  rtc.localStream.play("local_stream");
});
```
新規で映像ストリームを作成し、そのストリームに差し替える手法になります。
冒頭で記載の通り、この方法では一部正常に動作しません。理由は同時に前面・背面のカメラをオープンさせることができない為です。その代替手法は以下になります。

## 手法２
一度カメラを閉じて、再度映像を取得してパブリッシュします。(サーバーとの接続は途切れないので、チャネルからの離脱にはなりません）

```javascript:index.html
var facingMode = "user";
if(facingMode == "user"){
  facingMode = "environment";
}else{
  facingMode = "user";
}
rtc.localStream.stop();
rtc.localStream.close();
unpublish(rtc);
var params = serializeformData();

rtc.localStream = AgoraRTC.createStream({
  streamID: rtc.params.uid,
  audio: true,
  video: true,
  screen: false,
  microphoneId: params.microphoneId,
  facingMode: facingMode
})

rtc.localStream.init(function () {
  rtc.localStream.play("local_stream")
  publish(rtc);
}, function (err)  {
})
```
こちらの手法ですべてのスマホに対応ができます。

## 2021/11/11追記
WebSDK4系でのカメラ切り替えはサンプルは以下になります。

```javascript
var facingMode = "user";
async function cameraSwitch() {
  if(facingMode == "user"){
    facingMode = "environment";
  }else{
    facingMode = "user";
  }

  await client.unpublish(Object.values(localTracks));
  await localTracks.videoTrack.stop();
  await localTracks.videoTrack.close();
  
  [ localTracks.videoTrack ] = await Promise.all([
    AgoraRTC.createCameraVideoTrack({facingMode: facingMode})
  ]);

  // play local video track
  localTracks.videoTrack.play("local-player");
 
  // publish local tracks to channel
  await client.publish(Object.values(localTracks));
  console.log("publish success");
}
```


## 最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=9d294a7386c0f9326dc2)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=9d294a7386c0f9326dc2)
GPOでMSIファイルによるインストールがうまくいかない

[link1]:https://www.atmarkit.co.jp/ait/articles/0712/07/news142.html
[link2]:https://docs.microsoft.com/ja-jp/windows/security/threat-protection/windows-defender-smartscreen/windows-defender-smartscreen-available-settings
# 事象
[この辺][link1]を参考にGPOを作成しOUへリンクしたものの、自動インストールが行われない。

# 環境
ActiveDirectoryサーバ：Windows2012 R2
インストール先のPC：Windows10 Pro 1809

# 確認したこと

- 「gpresult /r」にて、対象のGPOが適用されていることは確認できた
- イベントビューアに特に変わったログは無いようだった
- 対象の端末の一部に手動インストールを試みたところ、Windows Defender SmartScreenの警告が発生したが、正常にインストールできた

# 対応方法

### 仮対応

- 対象端末の一部について、手動でWindows Defender SmartScreenを無効化
    - 「スタート > 設定 > 更新とセキュリティ > Windowsセキュリティ」からWindowsセキュリティ画面を表示する
    - 「アプリとブラウザーコントロール」の「アプリとファイルの確認」をオフにする
    ![SS20200323001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246683/8512a852-e0a8-17bd-dd32-f2df7614896e.png)
- 端末を再起動したところ、自動インストールされたことが確認できた

### 本格対応
- SmartScreenを無効化するGPOを作成し、対象の端末へ適用する
    - [Microsoftのサイト][link2]を参考にして、Windows Defender SmartScreenを無効化するGPOを作成
    - コンピュータの構成 > 管理用テンプレート > Windowsコンポーネント > Windows Defender SmartScreen > エクスプローラ > Windows Defender SmartScreenを構成します
    ![SS20200323002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246683/23ce33cc-5cf8-3a37-2b4e-29de13b588e1.png)

    - 適用後のWindowsセキュリティ画面では、アプリとブラウザーコントロールがオフとなり、手動による変更が不可となっている。
    ![SS20200323003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246683/1350d488-0e66-3cef-4219-3bf09443da5c.png)


- 端末を再起動し自動インストールが正常していることを確認
- 作成したGPOを無効化し、SmartScreenを有効化する


# 教訓
SmartScreenは、プログラムを誤ってインストールするのを防いでくれるというイメージ
全体へプログラムを配布する場合は、テスト用の端末を作っておいて手動でインストールを実施し、挙動を確認した方が良いと思いました
Laravel7 新たに追加された3つのマイグレーションエイリアス

## Laravel7 で追加されたマイグレーションエイリアス

使用できるカラムタイプのエイリアス

- `id`
- `foreignId`

外部キー制約のエイリアス

- `constrained`

上記の3つのエイリアスが追加されてます。

## 環境

```
$ php artisan -V
Laravel Framework 7.2.2
```

## 使い方

```php
Schema::table('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
});
```

上の定義は、下記のように定義したのと同じ内容になります。

```php
Schema::table('posts', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users');
});
```

## 補足

- https://github.com/laravel/framework/blob/7.x/src/Illuminate/Database/Schema/Blueprint.php
- https://github.com/laravel/framework/blob/7.x/src/Illuminate/Database/Schema/ForeignIdColumnDefinition.php

### id

```php:src/Illuminate/Database/Schema/Blueprint.php
    /**
     * Create a new auto-incrementing big integer (8-byte) column on the table.
     *
     * @param  string  $column
     * @return \Illuminate\Database\Schema\ColumnDefinition
     */
    public function id($column = 'id')
    {
        return $this->bigIncrements($column);
    }
```

シンプルなエイリアスですね。
個人的には `bigIncrements` って指定されてた方が分かりやすいと思うんですけど...

### foreignId

```php:src/Illuminate/Database/Schema/Blueprint.php
    /**
     * Create a new unsigned big integer (8-byte) column on the table.
     *
     * @param  string  $column
     * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
     */
    public function foreignId($column)
    {
        $this->columns[] = $column = new ForeignIdColumnDefinition($this, [
            'type' => 'bigInteger',
            'name' => $column,
            'autoIncrement' => false,
            'unsigned' => true,
        ]);

        return $column;
    }
```

`ForeignIdColumnDefinition` のインスタンスが返ってきますね。

### constrained

```php:src/Illuminate/Database/Schema/ForeignIdColumnDefinition.php
    /**
     * Create a foreign key constraint on this column referencing the "id" column of the conventionally related table.
     *
     * @param  string|null  $table
     * @return \Illuminate\Support\Fluent|\Illuminate\Database\Schema\ForeignKeyDefinition
     */
    public function constrained($table = null)
    {
        return $this->references('id')->on($table ?: Str::plural(Str::before($this->name, '_id')));
    }
```

`foreignId` に返ってきた `ForeignIdColumnDefinition` にメソッドチェーンでつなげて呼び出します。
`$table->foreign('user_id')->references('id')->on('users');` このようにテーブル名を指定しますが、 `->foreign('user_id')` から `users` と複数形のテーブルを自動的に設定してくれます。
[IPhone]で使えるGitHubアプリを比較してみた

# スマホでGithubを使いたい
##　対象読者 
- githubを使い始めた方
- IOSブラウザで使うGithubに不満を感じている方

# はじめに
最近Githubを使い始めたものです。ウェブ上でバージョン管理できるのは非常に便利ですね。最近では、コードだけではなく簡単なメモ等もマークダウンで書いて使ったりしています。そこで出先や隙間時間にさっき書いたメモを見たいなと感じたときに携帯のウェブページにアクセスするのですがスマホでみるには適していないように感じます。そこで、App StoreでGithubアプリを探したところいくつか見つかったので今回はそれらの特徴を簡単にまとめました。

# Github公式アプリ
 まずは[公式アプリ](https://apps.apple.com/jp/app/github/id1477376905)からダウンロードしました。
アプリを起動した感じでは、Iphoneの設定画面に似ている感じがあります。ウェブページから閲覧するのに比べRてアイコン等が大きく操作性は非常によいと感じました。
また、ダークモードに対応しているので夜間に目の負担を軽減することができます。
しかし、ウェブページと比較するとコードの編集等はできないようです。~~また、マークダウンで記述したファイルがマークダウンとして表示されないのが残念なところです。(README.mdは例外的にマークダウンとして表示されますが)~~
最近のアップデートでmarkdownが表示されるようになりました。これは神では！？
<img width="320" alt="2FB1EC69-61C1-44F9-BB50-A517EC449915.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/d6ff65d4-d539-dc98-903f-f493cef4b80e.png">　　　<img width="320" alt="4F9646DB-B2EF-40CD-9B6F-72B020A49FBA.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/4318e5ff-431f-9f3b-ebfa-ab59032e2d26.png">

# CodeHub
 次は[CodeHub](https://apps.apple.com/jp/app/codehub-a-client-for-github/id707173885 "codehub")をダウンロードしました。
サインインしてみると、まずニュースのページが開きました。設定からアプリ起動時に表示するページを指定できるようです。これは便利ですね。
また、このアプリではマークダウンの表示もできます。しかし、難点としてコード表示時の画面移動がスクロールではなくダブルタップである点です。
<img width="320" alt="989AC310-D260-4B99-80F4-553BE5F7A3AD.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/8a7d6bfc-1b43-9959-706c-cf466abca741.png">　　<img width="320" alt="A39A2988-5C4C-488D-9472-066334BC317E.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/0ac42c33-d0ea-ff5e-df2a-45e252ac78c4.png">
マークダウンは表示はできます。こちらもコードの編集はできないようです。

# GitHawk
次は、[GitHawk](https://apps.apple.com/jp/app/githawk-for-github/id1252320249 "GitHawk)です。こちらは通常のアプリとは異なり、自分のリポジトリを見るというよりはリポジトリのサーチに向いているように感じました。
検索したリポジトリも保存され、通知も受け取ることができるのが特徴です。
ブックマークも可能。
<img width="320" alt="E520E53D-C976-4BA2-8104-416730CD2B86.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/4059b3bb-f4f1-3044-659a-77465b8dd459.png">　　<img width="320" alt="F712C7FE-1304-4841-8AD7-F7825DEAB1D4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455763/f8eedf5d-83b8-8a37-e48a-c342823f841f.png">

## 結論
私は動作の観点から、公式アプリを使っていますがアプデでマークダウンが完全に表示されるようになり、大満足です。他の物もアプデで変わっているかもしれませんが、2020年4月以降に公式アプリ以外は使っていないので詳細はわかりません。ぜひ、いいアプリがあるよ！という方がいたら教えてください！
remoteブランチをcheckoutする方法 - Git

## まずはフェッチしてリモートのブランチをローカルの追跡ブランチへ持ってくる
```
% git fetch
```

## フェッチされた追跡ブランチを見る、ここにあればチェックアウトできます
```
% git branch -a                                           
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/feature/dev
```

## 追跡ブランチをローカルの新しいブランチとしてチェックアウトする、これでリモートへpushできます
```
% git checkout -b dev origin/dev
```
PHPStormでクラスのnamespaceを移動する

以前 [PHPStormでnamespaceを一括変更](https://qiita.com/kazuhei/items/fc52a27706db30b64ff7) でディレクトリの移動にあわせてnamespaceも一緒に移動する方法を書いたのですが、今回はクラスを特定のnamespaceに移動させる方法です。

PHPStormでファイルを開き、クラス名にカーソルを当てた状態でF6キーを押すと、
namespaceの移動のダイアログが出ます。

<img width="890" alt="phpstorm.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/b94c5406-b6ea-53f1-e52e-6338b3a42a29.jpeg">

Move Class 〇〇 to namespaceのところを編集して保存するとクラスのnamespaceとあわせてファイルのディレクトリも移動します。
メモ: selenium/standalone-chrome-debug

* Ubuntu 20.04 で確認

## 起動

```sh:起動
docker run \
 -d \
 --restart=always \
 -p 4444:4444 \
 selenium/standalone-chrome-debug
```

```sh:応答があることを確認
curl http://localhost:4444/status
```

## 操作

```sh
sudo apt install -y python3-selenium
```

```py:qiita.py
from selenium import webdriver

# Chrome のオプションを設定する
options = webdriver.ChromeOptions()
options.add_argument('--headless')

# Selenium Server に接続する
driver = webdriver.Remote(
    command_executor='http://localhost:4444/wd/hub',
    desired_capabilities=options.to_capabilities(),
    options=options,
)

# Selenium 経由でブラウザを操作する
driver.get('https://qiita.com')
# 画面キャプチャ
driver.save_screenshot('screenshot.png')
# urlが出力されればOK
print(driver.current_url)

# ブラウザを終了する
driver.quit()
```

```sh:実行
python3 qiita.py
```

> https://qiita.com/

と表示されれば成功。

画面キャプチャは`screenshot.png`を確認。
Azure Data FactoryをPowerShellで実行する

AzureのETLサービスであるAzure Data FactoryのPipelineをトリガー機能によるスケジュールではなくPowerShellから実行したい。

# Pipelineの実行
以下コマンドでPipelineを実行できます。
ただし、`Invoke-AzDataFactoryV2Pipeline`コマンドは実行完了を待ちませんのでRun IDを取得して別のコマンドで処理の状態をチェックする必要があります。

```powershell
$runid = Invoke-AzDataFactoryV2Pipeline -ResourceGroupName hoge-rg -DataFactoryName hoge-df -PipelineName pipeline1
```
# 実行結果の確認
先ほど取得したRun IDを使用して処理の状態を取得します。
正常終了している場合はStatusがSucceededとなります。

```powershell
Get-AzDataFactoryV2PipelineRun -ResourceGroupName hoge-rg -DataFactoryName hoge-df -PipelineRunId $runid

ResourceGroupName : hoge-rg
DataFactoryName   : hoge-df
RunId             : 0f5dae66-c986-49ee-bb60-f4c787517014
PipelineName      : pipeline1
LastUpdated       : 2020/03/20 15:03:10
Parameters        : {}
RunStart          : 2020/03/20 15:03:04
RunEnd            : 2020/03/20 15:03:10
DurationInMs      : 6215
Status            : Succeeded
Message           :
```

![Datafactory実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/839d1ed6-a18a-5669-3c5c-78a94d255063.png)

# 処理が完了していない…
成否問わず一回の結果確認で完了ステータスが取得できれば良いですが、中々そうもいきませんね。
ですので完了するまで何度もコマンドを実行してステータスを取得します。
ループで定期的にステータスを取得するようにすれば問題ないでしょう。
次のサンプルでは10秒ごとに結果を確認し、処理が10分で完了しない場合ループを抜けるようにしています。

```powershell
$limitTime = (Get-Date).AddSeconds(600)
$RunEnd= $false
do{
    Start-Sleep 10

    $result = Get-AzDataFactoryV2PipelineRun -ResourceGroupName hoge-rg -DataFactoryName hoge-df -PipelineRunId $runid

    Write-Output $result.Status
    if (!$result.RunEnd) {
        continue
    }
    $RunEnd= $true
    break
} while ((Get-Date) -lt $limitTime)
```

# まとめ
トリガーによるPipelineのスケジュール実行は便利ですが、Pipelineに設定できない別のプログラム等と
先行後続関係を持っての実行制御が難しいです。
PowerShellから実行することでその辺りの制御に有効だと思います。
【Vue】モーダルコンポーネント（コピペ用）

### 概要

- 何の変哲もないモーダルコンポーネントです。
- 業務でもよく使うのでコピペ用に残しておきます。
- 動作確認はお手軽な[codesandbox](https://codesandbox.io/)で！！

```vue:/components/Modal.vue
<template>
  <div>
    <div class="el-modal" :aria-hidden="isOpen ? 'false' : 'true'">
      <div class="el-modal__holder">
        <button @click="close()">閉じる</button>
      </div>
      <div class="el-modal__overlay"></div>
    </div>
    <button @click="open()">開く</button>
  </div>
</template>

<script>
export default {
  name: "Modal",
  data: function() {
    return {
      isOpen: false
    };
  },
  methods: {
    open: function() {
      this.isOpen = true;
    },
    close: function() {
      this.isOpen = false;
    }
  }
};
</script>
<style lang="sass">
  .el-modal
    visibility: hidden
    
    &__holder
      position: fixed
      z-index: 1100
      background-color: blue
      width: 50%
      height: 50%
  
    &__overlay
      position: fixed
      z-index: 1000
      background-color: red
      width: 100%
      height: 100%

    &[aria-hidden=false]
      visibility: visible
</style>
```
```vue:App.vue
<template>
  <div id="app">
    <modal/>
  </div>
</template>

<script>
import Modal from "./components/Modal";

export default {
  name: "App",
  components: {
    Modal
  }
};
</script>
```
Raspberry Pi ZeroにWindows10からBluetoothでログイン

# 概要
Raspberry Pi Zeroの開発をしていて、場所を移動してWifiが変わる度にディスプレイやキーボードが必要になるのが不便だったので、BLEからログインできるようにする。

# 手順
### WindowsからRaspberry Pi Zeroを検出可能にする

```
sudo bluetoothctl
[bluetooth] power on
[bluetooth] discoverable on
```

上記で検出できない場合は以下まで実施。（筆者の環境では↓だと検出できず、↑であれば検出可能でした。）

```
sudo bluetoothctl
[bluetooth] power on
[bluetooth] discoverable on
[bluetooth] agent on
[bluetooth] default-agent
```

### Windowsの設定からRaspberry Pi Zeroを見つけてペアリング
「Bluetoothとその他のデバイス」⇒「+Bluetoothまたはその他のデバイスを追加する」⇒「Bluetooth」で見つかるはず

### RasPi側でペアリング状況を確認

以下のようになっていればOK

```
pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX raspberrypi [default]
[NEW] Device XX:XX:XX:XX:XX:XX WINPC
```

### RasPiのbluetoothdの設定変更
/etc/systemd/system/dbus-org.bluez.serviceのExecStartを以下の通りに変更

```sh:/etc/systemd/system/dbus-org.bluez.service
ExecStart=/usr/lib/bluetooth/bluetoothd --compat
```

### /var/run/sdpへの権限付与

```sh
sudo chmod 777 /var/run/sdp
```

### Serial Port serviceを登録

```sh
pi@raspberrypi:~ $ sudo sdptool add --channel=22 SP
```

### RasPiのbluetootdを再起動

```sh
pi@raspberrypi:~ $ sudo systemctl daemon-reload
pi@raspberrypi:~ $ sudo systemctl restart bluetooth
```

### シリアル通信をlisten

```sh
pi@raspberrypi:~ $ sudo rfcomm listen /dev/rfcomm0 22
```

### Windows側での仮想ポートの割り当て
コントロール パネル＞ハードウェアとサウンド＞デバイスとプリンターからRaspberry Piを選択してプロパティを開いて、
「サービス」タブの「シリアルポート (SPP) 'Serial Port'」のチェックボックスをONにする。
するとCOMXのポートが割り当てられる。

### Windows側からの接続（TeraTerm）
TeraTermを起動し、「シリアル」を選択すると「ポート」のプルダウンで先ほどのCOMXのポートが選択可能になっている。
COMXのポートを選択して、接続を実行

# 起動時に自動でRasPiの設定を反映したい場合（デーモン化）

```sh:/etc/systemd/system/dbus-org.bluez.service 
ExecStart=/usr/lib/bluetooth/bluetoothd --compat
ExecStartPost=/usr/bin/sdptool add SP
```

```sh:rfcomm.service
[Unit]
Description=RFCOMM service
After=bluetooth.service
Requires=bluetooth.service

[Service]
ExecStart=/usr/bin/rfcomm watch 0 1 /sbin/agetty rfcomm0 115200 linux

[Install]
WantedBy=multi-user.target
```

serviceファイルを登録

```sh
sudo systemctl daemon-reload
sudo systemctl restart bluetooth
sudo systemctl enable rfcomm.service
```

後は再起動すればOK

```sh
sudo reboot now
```
UIkit3の拡張用CSSファイル(UIkit Plus α)を公開してみた

最近Web開発をする際のフロント側のCSSフレームワークに、[`UIkit3`](https://getuikit.com/) をよく使用しています。(特に指定が無い限り)
個人的に`Bootstrap`や`Materialize`などいろいろと使ってきましたが、自分的にこれが一番使いやすかったので。(あとデザインが好き)

ただし`UIkit`のみで全てを賄える訳ではもちろんないので、必要に応じて独自のCSS定義を追加するのですが、そういった時には決まって、

* そういえば以前にも同じ定義を書いたなようなと思いつつ同じ定義をまた書く
* 以前作ったものを探してきてコピーして使用する

ということを繰り返してました。

そんな経緯から、なら **良く使うものをまとめてしまえ！** と思い至り、
せっかくまとめたのなら、どれだけ需要があるのか分かりませんが、 **公開してしまえ！** とｗ
*そして`UIkit`がもっと普及するといいな。*

というわけで公開したのが [**UIkit Plus α**](https://playree.github.io/uikit-plusa/) になります。
`UIkit3`の使用が前提となりますが、ご自由にお使いいただければと。

余談ですが、
昔は自分にもデザインはデザイナーさんの仕事だよね？と思っていた時もありました。
ただ最近はこういったCSSフレームワークの普及などにより、ある程度なら簡単にデザインが組めるようになり、開発時の線引きも曖昧に。
さすがにある程度はデザインをいじれないとマズイかなと思い、手を出したところ、、、見事にハマってしまいました。(笑)
開発するうえで、機能的な要件を満たすことは当然ですが、見栄えというのも大事ですよね。

# [UIkit Plus α](https://playree.github.io/uikit-plusa/)
UIkit3と合わせて取り込むことで、少し拡張(使用できるCOMPONENTSを追加)することができます。
日頃の開発の中で今後も使いそうだなと思ったものをCOMPONENT化しています。(独断と偏見によりｗ)
同じくUIkitを使用する方の手助けになれば幸いです。
まだまだCOMPONENTの数は少ないですが、今後も随時COMPONENTを追加していく予定です。

使い方や追加されるCOMPONENTSの詳細は下記ページをご覧ください。
実際のデザインやサンプルコードを確認頂けます。
[Document](https://playree.github.io/uikit-plusa/)

「こんなCSS定義をよく使うんですけど」などを
[GitHubのIssue](https://github.com/playree/uikit-plusa/issues)に書き込んでくれれば、もしかしたら(もしかしたらですよ？)追加されるかもしれません。

## UIkit Plus α で追加されるCOMPONENTS

### Paragraph - 段落表示
h1～h6の先頭にシンボルを表示します。
### Sub Text - サブテキスト
h1～h6にサブテキストを表示します。
### Box List - ボックスタイプのリスト
枠線で囲うタイプのリスト表示です。
リンクとして設定することもできます。
### Border Table - 枠線タイプのテーブル
シンプルな枠線タイプのテーブルです。
### Titled Preformatted Text - タイトル付き整形済みテキスト
ソースの表示などに適した整形済みテキストです。
左上にタイトルを付けることができます。
### Side Fix Nav - 右上固定のナビゲーション
右上に固定表示するナビゲーションです。
### Floating Button - フローティングボタン
フローティングの丸ボタンです。
### Margin Mini - 極小のマージン設定
本家UIkitの.uk-margin-smallよりも、さらに小さいマージンを設定します。
### Message Box - メッセージ表示
シンプルなメッセージ表示です。
### Movable Label Input - ラベルが動くインプットボックス
プレースホルダ的な表示(通常時)から、ラベルが上部に移動する(フォーカス時)タイプのインプットボックスです。
### Infinite Scroll - 無限スクロール
最後までスクロールした際に自動で続きのデータを読み込むことで、最終データまでの無限スクロールを実現します。
[JavaScript] "10" + 1 は "101" だが "10" - 1 は 9  を理解する

そういうものなんです！仕様です！（完）

## だけではあれなので、仕様をちゃんとみてみる
### 加算演算子（＋）
[12.8.3 The Addition Operator ( + )](https://tc39.es/ecma262/#sec-addition-operator-plus)をみていきます。

>
**NOTE** The addition operator either performs string concatenation or numeric addition.  
12.8.3.1 Runtime Semantics: Evaluation
AdditiveExpression:AdditiveExpression+MultiplicativeExpression  

加算演算子は文字の連結と数値の加算を担うことがわかりました。
次に処理の流れをみていきましょう。

>
1. Let lref be the result of evaluating AdditiveExpression.
1. Let lval be ? GetValue(lref).
1. Let rref be the result of evaluating MultiplicativeExpression.
1. Let rval be ? GetValue(rref).
1. Let lprim be ? ToPrimitive(lval).
1. Let rprim be ? ToPrimitive(rval).
1. If Type(lprim) is String or Type(rprim) is String, then  
  a. Let lstr be ? ToString(lprim).  
  b. Let rstr be ? ToString(rprim).  
  c. Return the string-concatenation of lstr and rstr.
1. Let lnum be ? ToNumeric(lprim).
1. Let rnum be ? ToNumeric(rprim).
1. If Type(lnum) is different from Type(rnum), throw a TypeError exception.
1. Let T be Type(lnum).
1. Return T::add(lnum, rnum).

流れを確認すると**7\.**で型チェックをしていますね。
どうやら評価する値が**String**だった場合は**ToString**する仕様となっています。
そうでない場合はToNumericですね。

#### 確認してわかったこと
加算演算子（＋）は文字の連結と数値の加算の機能を担っている。
評価する値を型チェックして文字列か数値に変換している。

### 減算演算子（ー）
[12.8.4 The Subtraction Operator ( - )](https://tc39.es/ecma262/#sec-subtraction-operator-minus)をみていきます。

>
12.8.4.1 Runtime Semantics: Evaluation
AdditiveExpression:AdditiveExpression-MultiplicativeExpression  
>
1. Let lref be the result of evaluating AdditiveExpression.
1. Let lval be ? GetValue(lref).
1. Let rref be the result of evaluating MultiplicativeExpression.
1. Let rval be ? GetValue(rref).
1. Let lnum be ? ToNumeric(lval).
1. Let rnum be ? ToNumeric(rval).
1. If Type(lnum) is different from Type(rnum), throw a TypeError exception.
1. Let T be Type(lnum).
1. Return T::subtract(lnum, rnum).

お気づきになったと思いますが、型チェックがないですね。
減算演算子には文字列連結の機能はないので型変換する必要がないということでしょう。
評価する値を数値に変換してそのまま処理していることがわかりました。

#### 確認してわかったこと
減算演算子（ー）は数値の減算を担う機能。
評価する値を（型チェックせずに）数値に変換している。

## まとめ
加算演算子（＋）は、型チェックの結果、文字の連結として処理されるから**"10" + 1 は "101"**となる。
減算演算子（ー）は、数値の減算のみを行うから**"10" - 1 は 9**となる。

これで何故 `"10" + 1 は "101" だが "10" - 1 は 9 `になるのかが確信を持って言えるようになりました！ :tada:

これからはこんな挙動を質問されてもキリッと答えられますね！

```js
"10" + 1       // => '101'
"10" - 1       // => 9
"10" + 1 - 1   // => 100
"10" + (1 - 1) // => "100"
"1" - 1 + "1"  // => "01"
1 - "1" + 1    // => 1
```

## 余談
「"10" + 1 は "101" だけど "10" - 1 は 9 なのなんでだろ :thinking: 」
みたいな質問が流れてきたのがきっかけでした。

ちゃんと根拠を持って教えてあげようと思い、初めて仕様書リーディングに挑戦してみました。
こちらが、仕様書を読む勇気をもらった素晴らしい記事です。（唐突な宣伝。）
[JavaScriptの「継承」はどう定義されるのか仕様書を読んで理解する - Qiita](https://qiita.com/uhyo/items/b63ac11e8ec54d2c3a2b)

いつもだったら、「キモい動きするなー、雑学として覚えておこう。」くらいで終わっていたと思います。やっぱり仕様は大事ですね。

## 追記
@suin さんが非常に有用な日本語訳をコメントしてくださいました。
本当にありがとうございます。:bow_tone2:
併せてお読みいただけるとさらに理解が深まります！
[＋/ー演算子 日本語訳へのリンク](https://qiita.com/kozzzz/items/26372bb1a17160d983b6#comment-9cc08ec0b2866dd7a5db)

## 参考
https://tc39.es/ecma262/
PHP Intelephense の有償版を Neovim で使ってみる

[PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client) は PHP の Language Server の一つ。
VS Code での利用例は

- [VSCode PHP用のインテリセンス拡張機能は「Intelephense」の方がオススメ！ │ wonwon eater](https://wonwon-eater.com/vscode-php-intelephense/)
- [VS CodeのPHP Intelliphenseがとても心地よくコードを補完してくれる件 \- Qiita](https://qiita.com/motuo/items/1600ca1fc4e8dd6a19f2)
- [VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう \| 株式会社ビヨンド](https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/)

など様々見られる一方、 Neovim での利用に関する情報があまり見つからなかったので、導入手順をメモ。
また有償版だとクラスやメソッドの実装へのジャンプやリネームなどの機能も利用できるようになるとのことで、せっかくなので有償版を購入して使ってみた。

## 有償版のライセンスキー取得

[ライセンス購入ページ](https://intelephense.com/) から必要な情報を入力して購入する（記事投稿時点で ¥1,000 ）。
後から送付されるメールにライセンスキーが記載されている。

## Neovim 側の設定

language server のプラグインは [coc\.nvim](https://github.com/neoclide/coc.nvim) を使用した。
coc.nvim の PHP 拡張である [coc\-phpls](https://github.com/marlonfan/coc-phpls) を使えばライセンスキーを `coc-settings.json` に記載するだけで特にその他の設定なしで利用できる。
ちなみにキーに含まれる `licence` のスペルは `license` ではないので注意（ Intelephense の開発元はオーストラリアらしいが、アメリカ英語と異なる？）。

```json:coc-settings.json
{
    "intelephense.licenceKey": "your licence key",
}
```

後は `:CocInstall phpls` で拡張機能を追加すればオーケー。

## 課題

前述した実装へのジャンプやリネームもきちんと動作したので、 PHP の language server としてはこれがベストかもしれない。
ただインターフェースへのジャンプが上手くできなかったりするので、まだ諸々の設定を調べる余地がありそう...。
Mac Catalina 10.15 に、古いバージョンのPHPをインストールする

# Mac Catalina 10.15 に、古いバージョンのPHPをインストールする

CakePHP2のアプリを修正依頼が合ったが、Mac Catalinaではhomebrewに
もう古いバージョンが無く・・・

（なんでそんなに古いまま、ほっといたんだよってツッコミはなしで、、、）

brew tap exolnet/homebrew-deprecated
でも、php 5.6

どうしても、php5.5を入れたいと調べてたら、binary packageを入れる方法がありました。

https://php-osx.liip.ch/

PHP 5.3〜PHP 7.3がある

## インストールする

```
curl -s https://php-osx.liip.ch/install.sh | bash -s 5.5
```

## pathを通す

```
export PATH=/usr/local/php5/bin:$PATH
```
ユーザーの状態によって表示を変更する方法　Rails 

#初めに

Rubyのライブラリの1つである、便利機能のdeviseを使いました

-----------------------------------------

##devise

ログイン機能の実装を簡単にしてくれるgemです


#本題

今回は、ログインしているかしていないかで見せ方を変更したかったので、、、


```
  - if user_signed_in?  
    .purchase
      = link_to '購入ページ','#'
  - else
    %p.setumei 親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるかも知れぬ。別段深い理由でもない。新築の二階から首を出していたら、同級生の一人が冗談に、いくら威張っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃したからである。小使に負ぶさって帰って来た時、おやじが大きな眼をして二階ぐらいから飛び降りて腰
```

と記述しました。

#ログインしている

<img width="1068" alt="スクリーンショット 2020-03-23 3.10.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/2f20660c-b449-9cdb-eb7f-9b93b069a3ed.png">


#ログインしていない

<img width="1092" alt="スクリーンショット 2020-03-23 3.10.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/dd7d9aed-170d-fcaf-b0f8-4a3c09fbc986.png">
Next.jsでGoogle Analyticsを適用する（react-gaは使用しません）

Next.jsでGoogle Analyticsを適用する方法は色々ありますが、日本語情報が少ないので低レベルながら僕の方でも情報を残しておきます。

`next/router` でのページ遷移も問題なく動作することを確認しています。

# こんな感じで動作します

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Next.jsでGoogle Analyticsを組み込んだ<br>（Qiita備忘録用ビデオ） <a href="https://t.co/p1vw9vJSqO">pic.twitter.com/p1vw9vJSqO</a></p>&mdash; masa5714 (@b95oss) <a href="https://twitter.com/b95oss/status/1241840495296253952?ref_src=twsrc%5Etfw">March 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

※ビルド前で動作させているのでページ遷移が遅いです。
※公開済みのトラッキングIDを使用したため、ちょうど他の人がアクセスしてて分かりづらくなってしまいました...すみません。（2アクセス目が僕のアクセスです。）

# 公式にExampleがありました
https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics
zeitが管理するnext.jsリポジトリの中にexampleがありましたので、こちらを参考に実装していきます。（ほぼ転載ですが...w）

# lib/gtag.jsを作成する（最終的にimportできればフォルダ名・ファイル名はなんでも良いです）

```javascript:gtag.js
export const GA_TRACKING_ID = '<YOUR_GA_TRACKING_ID>'

// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = url => {
  window.gtag('config', GA_TRACKING_ID, {
    page_path: url,
  })
}

// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }) => {
  window.gtag('event', action, {
    event_category: category,
    event_label: label,
    value: value,
  })
}
```

`<YOUR_GA_TRACKING_ID>` をGoogle AnalyticsのトラッキングIDに差し替えます。


# pages/_app.jsに記述を追加する

```javascript:_app.js
import App from 'next/app'
import Router from 'next/router'

import * as gtag from '../lib/gtag'

Router.events.on('routeChangeComplete', url => gtag.pageview(url))

export default App
```

`import * as gtag from '../lib/gtag'` でlib/gtag.jsを呼び出します。

# pages/_document.jsに記述を追加する

```jsx:_document.js
import Document, { Head, Main, NextScript } from 'next/document';

import { GA_TRACKING_ID } from '../lib/gtag'

export default class extends Document {
  render() {
    return (
      <html>
        <Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
          />
          <script
            dangerouslySetInnerHTML={{
              __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', '${GA_TRACKING_ID}', {
              page_path: window.location.pathname,
            });
          `,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}
```

ここは何も変更する必要はありません。
`import { GA_TRACKING_ID } from '../lib/gtag'` で `gtag.js` を読み込みを行って、 `Head` の中にGAのスクリプトを記述します。

---

ここまで完了すれば導入は終わりです。
実際にサイトにアクセスして動作確認をしてみましょう。

ページ遷移を行うとGoogle Analyticsの「リアルタイム」で閲覧ページを追従できていることがお分かり頂けるはずです。
初心者によるプログラミング学習ログ 270日目

#100日チャレンジの270日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
270日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>270日目<br>・webサイト模写<br>・noteの、コーディング教材1つ終了<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1241816991331041280?ref_src=twsrc%5Etfw">March 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
新しいアプリを作る際のLaravel環境構築（2回目以降）

## はじめに
初回の環境構築はやったけど，新しくアプリを作りたいときにいろいろ調べ直すのが面倒なので，自分用にまとめました．間違い等ありましたら，ご指摘お願いします．

## Homesteadの設定([参考1](https://qiita.com/7968/items/97dd634608f37892b18a))
### 1.homesteadをgitからクローン
```ruby:ターミナル 
$ mkdir ~/ws/Hoge
$ cd ~/ws/Hoge
$ git clone https://github.com/laravel/homestead.git Homestead
```
### 2.init.shを実行(homesteadの初期化）
```ruby:ターミナル
$ cd Homestead
$ bash init.sh
```
### 3.Homestead.yamlを編集([参考2](https://qiita.com/kuriya/items/98bfaca6fe1ae653f409))
 
```ruby:ターミナル
$ vim Homestead.yaml
```

```ruby:Homestead.yaml
ip: "192.168.10.20" #前回作ったHomesteadなどとかぶらないIPの方が良い
#--------
#〜このあたりの行はほぼ変更しないから省略〜
#--------
folders:
    - map: ~/ws/Hoge #localからプロジェクトファイルまでのパス
      to: /home/vagrant/code #vagrant(仮想環境上で）からプロジェクトファイルまでのパス

sites:
    - map: Hoge.hoge #localでアクセスするURL(これかipを使ってブラウザでアクセス）
      to: /home/vagrant/code/public # rootディレクトリのパス
```

### 4.hostsファイルを編集
```ruby:ターミナル(~/ws/Hoge)
$ sudo vim ~/../../etc/hosts
```
```ruby:hostsファイル内
#ipとホスト名を下記のようにそれぞれ追加
192.168.20.10   Hoge.hoge
```

### 5.vagrantの起動&ssh
```ruby:ターミナル
$ cd ~/Hoge/Homestead
$ vagrant up
$ vagrant ssh
```

### 6.composer install
```ruby:vagrant@homestead
$ cd code
$ mkdir Hoge
$ cd Hoge
$ composer install 
$ composer create-project laravel/laravel --prefer-dist 'ディレクトリ名'
```

### 7.git管理
```ruby:ターミナル
# 2つめのターミナルを起動する
$ cd ~/ws/Hoge
$ git init
$ git remote add origin 'githubのリポジトリURL' #('は要らない）
```


## Herokuへデプロイ ([参考3](https://blog.nakamu.life/posts/heroku-laravel-deploy))([参考4](https://devcenter.heroku.com/articles/buildpacks#setting-a-buildpack-on-an-application))
```ruby:ターミナル（初めてのときはこれを実行）
# Heroku CLIのインストール
brew tap heroku/brew && brew install heroku
```
### 1.Herokuへのログイン＆アプリの新規作成
```ruby:ターミナル
# Herokuへログイン
$ heroku login
# Herokuアプリを新規作成し、同時にPHPを使用可能にする
$ heroku create HogeHoge --buildpack heroku/php

# リモートリポジトリの確認
$  git remote -v
```

### 2.LaravelのプロジェクトルートにProcfileを作成
```ruby:ターミナル
# ProcfileはHerokuアプリの起動時に実行するプロセスを定義するためのファイル
$ echo 'web: vendor/bin/heroku-php-apache2 public/' > Procfile
```
### 3. Herokuへプッシュ（アップデート）
```ruby:ターミナル
$ git push heroku master
```


## おわりに
とりあえず最低限は書けたと思うので，今後は以下を書き足していこうと思います．

Laravel
- [認証機能](https://readouble.com/laravel/7.x/ja/authentication.html)

Heroku
- [データベースの設定](https://qiita.com/tamappe/items/a175596e9aec725e1d2d)（環境変数）

Pusher
- [初期設定](https://qiita.com/shotashimura/items/d0019032f941458b0963)

## 参考文献
1.[【Laravel超入門】開発環境の構築（VirtualBox + Vagrant + Homestead + Composer）](https://qiita.com/7968/items/97dd634608f37892b18a)
2.[Homesteadの設定方法](https://qiita.com/kuriya/items/98bfaca6fe1ae653f409)
3.[HerokuにLaravelをデプロイする方法](https://blog.nakamu.life/posts/heroku-laravel-deploy)
4.[Heroku Dev Center Buildpacks](https://devcenter.heroku.com/articles/buildpacks#setting-a-buildpack-on-an-application)
[【Laravel】Herokuを利用して無料でデプロイしてみた【手順】](https://entsukablog.com/laravel-heroku-deploy/#HerokuMySQL)
[Laravelをherokuにデプロイする(データベースはMySQL)](https://qiita.com/tamappe/items/a175596e9aec725e1d2d)