OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel CSSの設定が反映されない

# 目的

- Laravelののビューファイルに記載された要素の設定を行うためにCSSを記載したがCSSの設定が反映されなかった時の対処法を記載する

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2GHzクアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHPバージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravelバージョン | 7.0.8 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 実施条件

- CSSの記載方法などに誤りがないこと。

# 実施情報

- chromeを用いて確認を行った際の解決方法を記載する。

# 読後感

- CSSの設定が正常にLaravelのビューに反映され、ブラウザから確認することができる。

# 詳細

1. chromeを開く。
1. 下記画像の矢印部分が指している部分をクリックする。

    ![新しいタブ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3ae5c2c9-b014-1cfb-89a7-1891017bb4e8.png)

1. 「設定」をクリックする。

    ![スクリーンショット_2020-09-04_22_59_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c0453c3a-6169-51d2-a097-d5166168238b.png)

1. 「閲覧履歴データの削除」をクリックする。

    ![設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5ea15fbe-d856-aa6a-5bdc-76504ddf0bc6.png)

1. 「キャッシュされた画像とファイル」のみにチェックを入れて「データを削除」をクリックする。

    ![設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5752656b-3de5-5d92-f03b-348997fed625.png)

1. CSSで設定をしたLaravelアプリのビューを確認する。
Houdini備忘録

# リファレンス
Houdini全体でHScriptとVEXとPythonを扱うので混乱しがち。HScriptはパラメータに。VEXはシェーダーっぽく並列処理する特化仕様。Pythonは他全部を担う。そんなイメージ。

HScript (パラメータに書けるやつ)
https://www.sidefx.com/ja/docs/houdini/expressions/index.html

VEX (主にwrangleで書けるやつ)
https://www.sidefx.com/ja/docs/houdini/vex/functions/index.html

Pythonでhoudiniを操るパッケージのリファレンス
https://www.sidefx.com/ja/docs/houdini/hom/hou/index.html

# HScriptで入力ノードを得る
例えば以下。（boundsのサイズを得る関数。）

```
bbox("../" + opinput(".", 0), D_XSIZE)
```

`"../" + opinput(".", 0)`が入力ノードへの相対パスを成してる。0の部分は入力ノードが複数ある時にどの入力ノードか選べる。


# 完全にリンクしたノードを作成する
ノードを右クリックして`Action>create reference copy`で全パラメータが参照された同ノードを作成できる。部分的に変えたい場合は、変えたいパラメータを右クリックで`Delete channel`で変えられる。

# 階層的なFBXの書き出し
Houdiniのデフォルトの機能だと、1オブジェクトを階層的に書き出しをしても全オブジェクトの原点が同じ一点に集まっていたりなど不便があるので下記のリンクのTakashi KoideさんのHDAを使わせてもらうと便利。
https://qiita.com/d658t/items/d9ff6682595312e92ab9
Word2016で一太郎(.jtd)ファイルを読み込めることが判明（ファイル修復コンバーター）

環境　Word2016
　　　一太郎pro2　で作成したファイル
　　　一太郎pro4　で作成したファイル
#一太郎コンバータが生きていた！
　かつて，Wordには一太郎コンバータという機能があり，一太郎ファイル（.jtd）を読み込むことができました。
https://support.microsoft.com/ja-jp/help/882158

　しかし，Word2010で廃止され，一太郎の機能で一太郎ファイルをWordに変換できるものの，Wordだけでは一太郎ファイルは読めなくなり，一太郎ファイル（.jtd）が読みたければ一太郎か一太郎ビューア，もしくはOpenOfficeの拡張機能がないとだめ，というのが定説でした。

　ただ，どうもWordの「ファイル修復コンバーター（recover text from any file）」の一部として一太郎コンバータが生きているようなのです…！
https://docs.microsoft.com/ja-jp/office/troubleshoot/word/damaged-documents-in-word
（ファイルの修復方法・マイクロソフト公式）

#Wordから一太郎ファイルを開く
[ファイル]→[開く]→[参照]でダイアログボックスを開きます。
![2020-09-05 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/2a54bd76-76d8-e311-1026-e7e9fd860766.png)

　ファイル名の右の拡張子の選択リストボックスから，

- 「ファイル修復コンバーター(****.****)」又は
-  「recover text from any file(****.****)」を選択します。

（環境によって表示が異なるようです。）
![2020-09-05 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/dd743b77-8564-ebbc-b517-4b7541285f95.png)
　一太郎ファイルを選択して[開く]
![2020-09-05 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/bf5f2f78-c593-7e55-a303-91920c199d3d.png)
「修正個所の表示」というダイアログボックスが表示されますが，[閉じる]を押してください。
　個人名が出てきますが，私は一太郎のテンプレートを使っただけです。JustSystemsの社員さんなんでしょうか・・
![2020-09-05 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/aeb4166d-d967-f70a-2a31-b6b464805768.png)
![2020-09-05 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/52885bee-c6fa-c716-aa0f-a8b32e48bc9a.png)

　ちなみに，元文書はこんな感じです。
![2020-09-05 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/b9e300b2-0151-e971-e841-b4f8e52ed358.png)
　文字化けしとるやん！と思いますよね。私も最初思ったんですが，どうも上下の文章を確認すると，文字化けした文章の上下どちらかにちゃんと正しい文章もあるようなんです。
　もちろん，書式は全て失います。でも，文書ファイルなんて，文章だけ取り出せれば十分じゃないでしょうか（偏見）。

　気になるのが一太郎の別シートの扱いです。Wordは別シートの概念がないですから。
　こちらが元文書の別シート。くどいようですが一太郎のテンプレートです。JustSystemsは実名使う文化なのでしょう，きっと。
![2020-09-05 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/916c040d-f1db-e07a-5217-978a33030878.png)
　Wordで開いた文書をスクロールしていくと「Sheet2」の文字が！
![2020-09-05 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/8943fc9e-0cd0-2bea-b167-c21abe5c4a20.png)
来るか，来るか！？
![2020-09-05 (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/ea3725e6-6fea-1f43-a1a7-f0f1718f2693.png)
　来ました。別シートも復元されています。
　ただ，罫線の一部の情報は失われていますね…（「責任者」など）

#まとめ

 - Wordのファイル修復コンバーター（recover text from any file）を使うと，一太郎ファイルを読み込める。
 - 読み込めるのは基本的に文章だけ，でも別シートも読み込める
 - 罫線枠を使用したデータの場合，一部の文章が失われることがある


　別シートまで復元されるあたり，microsoftが一太郎を全く意識せずにファイル修復コンバーターを実装した可能性は低いような気がしています。私の勝手な憶測ですが，一太郎コンバータの文章を読み込む部分を組み込んだのではないでしょうか。
　拡張子の指定が全てのファイルの選択(****.****)となっているのも意味深です。Wordファイルの修復機能というだけなら，docxやrtfなどで十分でしょうから。
　もしかしたら，一太郎がWordとの互換性を意識して開発していった結果，奇跡的にファイル修復コンバーターに対応した可能性もありますが，どうでしょう。

　それより，ファイル修復コンバーター（recover text from any file）の可能性に期待が膨らみます。
　これは別記事で書く予定ですが，どうも壊れて開けない一太郎ファイルも修復できるようなんです。すごいですよね。
　もしかして，一太郎ファイル以外も読み込みできるんじゃないでしょうか。
　ネット上にもファイル修復コンバーターについてはあまり情報が載っていませんし，詳しい方いたら教えてください。
MATLAB Image Acquisition ToolboxのTriggerは適切に使いましょう。

カメラを手軽に高度に制御したいときに、MATLAB Image Acquisition Toolboxは便利なツールだと思われています。しかし、その対価も有していることからあなたは目を背けてはいけません。関数の数こそ少ないですが、その仕様をきちんと理解していないと、あなたは自分で気づかないうちに落とし穴に落ちていることでしょう。
この記事では、撮影タイミングをカメラに指示するためのTriggerの前に空いている穴と、その回避方法について解説します。


記事の流れ
・取り扱う問題点と筆者の環境
・解決するコードの書き方
・コードの書き方の論拠

##取り扱う問題点と筆者の環境
・MATLAB 2020a
・Image Acquisition Toolbox
・Image Acquisition Toolbox Support Package for GenICam Interface
・windows機
・研究用カメラ（秘匿）

####問題点　triggerの後に、カメラがrunning状態ではなくなっている。

ちなみに、Triggerを使うシーンにはどのようなものがあるでしょうか。
たとえば、高速でカメラのシャッターを切りたいという需要を考えてみましょう。一枚一枚撮影するたびにパソコンへ読み出すのではなく、たくさん撮ってから一度に読み出すことで、カメラの読み出し時間を考慮せずシャッタースピードを変更できます。
これは、MATLAB Image Acquisition Toolbox のtrigger と getdata を使用することで実装できます。

ちょっと実装してみましょう

```
% 間違い例です

vid = videoinput('Camera name', 'option');
src = getselectedsource(vid);

vid.FramesPerTrigger = 1;
Triggerconfig = (vid,'manual');
src.ExpousureTime = 5000;

start(vid);
trigger(vid);
pause(0.01);
trigger(vid);
pause(0.01);
trigger(vid);

getdata(vid,3);

stop(vid);
delete(vid);
clear vid  

% これは間違い例です
```

こうすれば、カメラの読み出し時間が50 msであろうとも、10 ms毎に露光時間5000 usで撮像できます。
しかしながら、これでは動きません。２つ目のtriggerに対してエラーメッセージ「カメラがrunning状態ではありません」が出てきます。

必要最低限の指示さえすれば動くものと思っていたのですが、何か足りないようです。これでは高級言語の名折れです。
なかなか問題を解決できないと、ここまでの悪態をつくような精神状態に追い込まれます。そうならないうちに、続きを読みましょう。

 
##解決するコードの書き方
start(vid)の前に vid.TriggerRepeat = Inf を追加します。

```
vid = videoinput('Camera name', 'option');
src = getselectedsource(vid);

vid.FramesPerTrigger = 1;
Triggerconfig = (vid,'manual');
src.ExpousureTime = 5000;
vid.TriggerRepeat = Inf;

start(vid);
trigger(vid);
pause(0.01);
trigger(vid);
pause(0.01);
trigger(vid);

getdata(vid,3);

stop(vid);
delete(vid);
clear vid  
```



##論拠
そんなことはMATLAB documentationのrunningやtriggerには書かれていません。
documentationの中では、startの中に関連する記述があります。
https://jp.mathworks.com/help/imaq/start.html?s_tid=srchtitle

以下、documentationからの引用

>An image acquisition object stops running when one of the following conditions is met:
>
>The stop function is issued.
>
>The requested number of frames is acquired. This occurs when
>
>FramesAcquired = FramesPerTrigger * (TriggerRepeat + 1)
>where FramesAcquired, FramesPerTrigger, and TriggerRepeat are properties of the video input object.
>
>A run-time error occurs.
>
>The object's Timeout value is reached.

と書いてあります。
FramesAcquiredというのは、startしてから撮ったframeの数を数えている変数です。

重要なのは、**デフォルトが TriggerRepeat = 0 である**ことです。
https://jp.mathworks.com/help/imaq/triggerrepeat.html?s_tid=srchtitle (TriggerRepeatのdocumentation)

この値を　Infに設定してしまえば、憂うことはなにもないということですね。（本当かな？）


・Trigger一回までは許容される
・startとTriggerRepeatに分散して記述がある
あたりが沼ポイントでしょうか

#### 余談
ちなみに、startとtriggerをひたすら繰り返すことでも解決できますが、カメラのほうに余裕があればの話です。
私が使ったカメラと環境では、このコードだと2回目のstartでMATLABがクラッシュしました。

startのMATLAB documentationの記述ですが、imaq(toolboxのファイル内)にあるstart.mのコメント欄にも
同じような記述が見られます。筆者は、documentationを見つける前にこちらの記述に当たりました。

デフォルトが0になっている意味ですが、おそらく「意図しない無限ループを避ける」目的があるのかと思います。

##追記ログ
Pythonで数独認識して解く② (数字認識)

##初めに
- [前回(Pythonで数独認識して解く①)](https://qiita.com/TKC-tkc/private/818b8dbbff95fda2781a) の続編です
- 数独を認識して解くプログラムを作る
- 次は文字を認識します

[環境]
・Python 3.7.3
・numpy 1.16.4

##方法①
- CNN(畳み込みニューラルネットワーク)でMNISTデータセットを学習
- PyTorchを用いたプログラムを作成
- 細かいことは以前の記事([こちら](https://qiita.com/TKC-tkc/items/42ff569be496621fc016))を参照お願いします

##結果①
- うまくいかなかった
- 空白を含めた81マスをすべて正確に識別するモデルを作れなかった
- うまくネットワークを構築できれば活用できるかもしれない

##方法②
- Tesseractをpyocrから利用した
- [Tesseractダウンロードページ](https://github.com/UB-Mannheim/tesseract/wiki)からダウンロード
- インストーラをダウンロードし，順に進めるだけ。
- 日本語の認識を行いたい場合は`Additional script data (download)`で追加が必要
- インストール後，Pathを通す必要がある。(久しぶりだったので少し手間取った)

```python
import numpy as np
from PIL import Image,ImageOps
import pyocr                    # OCR ラッパーライブラリ 対応OCR:Tesseract, Cuneiform
import pyocr.builders           # OCR ラッパーライブラリ 対応OCR:Tesseract, Cuneiform
import sys                      # 実行環境関連ライブラリ

"""
数字認識
"""
N = 9
number_detection = np.zeros((N,N),dtype=np.int)

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)

tool = tools[0]

for i in range(N*N):
    img_path = "split_sudoku/{}.jpg".format(i)
    img = Image.open(img_path)
    img = ImageOps.invert(img)
    txt = tool.image_to_string(
            img,
            lang="eng",
            builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
    
    if txt != "":
        number_detection[i//N,i%N] = int(txt)

print(number_detection)
print()
```
- 補足(パラメータについて)
    - `lang = "~~"`
    - `builder = pyocr.builders.~~`
    - `tesseract_layout = ~~`

    |lang|種類|
    |:-:|:-:|
    |"eng"|英語|
    |"jpn"|日本語|
    |その他|割愛|
    - 今回は`lang="eng"`とした。(の本後よりも英語のほうが選択肢が少なくて良いみたい)

    |pyocr.builders|用法|
    |:-:|:-:|
    |TextBuilder|文字列を認識|
    |WordBoxBuilder|単語単位で文字認識 + BoundingBox|
    |LineBoxBuilder|行単位で文字認識 + BoundingBox|
    |DigitBuilder|数字 / 記号を認識|
    |DigitLineBoxBuilder|数字 / 記号を認識 + BoundingBox|

    |tesseract_layout|用法|
    |:-:|:-:|
    |0|Orientation and script detection (OSD) only.|
    |1|Automatic page segmentation with OSD.|
    |2|Automatic page segmentation, but no OSD, or OCR|
    |3|Fully automatic page segmentation, but no OSD. (Default)|
    |4|Assume a single column of text of variable sizes.|
    |5|Assume a single uniform block of vertically aligned text.|
    |6|Assume a single uniform block of text.|
    |7|Treat the image as a single text line.|
    |8|Treat the image as a single word.|
    |9|Treat the image as a single word in a circle.|
    |10|Treat the image as a single character.|

    (OSD : サブタイトルなどの認識に利用?)
    - `builder=pyocr.builders.DigitBuilder(tesseract_layout=6))`とした。

##結果②
- 結構うまくいく。
- 体感での成功率70%~80%
- 81マスすべてを完璧に認識するのはさすがに厳しい

##まとめ
- OCRはすごい
- インストールするのはちょっとめんどくさい
- CNNとかのネットワークで高性能なものを作るのは難易度高い
銀行口座で理解するgitの使用感覚

# tl;dr
- 何もわからないよりはマシレベルの説明
- 以下説明対象のコマンド
  - init
  - clone
  - add
  - commit
  - push
  - pull


# 対応表
厳密には置いといて「んーまぁ全く分からんよりはマシだけどさぁ…(´・ω・｀)」レベルの精度

| 銀行                                        | git                |
| ------------------------------------------- | ------------------ |
| 通帳                                        | ローカルリポジトリ |
| 銀行内の口座データ                          | リモートリポジトリ |
| 口座作成                                    | init               |
| 引出/預入データ登録(札食わせたり吐かせたり) | add                |
| 引出/預入実行                               | commit             |
| 書き込んだデータを銀行に送信          | push               |
| 通帳記入                                    | pull               |



# 以下大体あってろ説明
### 口座を作る
- 口座(`リモートリポジトリ`)作成
    - `git init`
- 口座に連動する通帳(`ローカルリポジトリ`)作成
    - `git clone 口座`


### 取り敢えず適当に突っ込む
- お財布から札を食わせる
    - `git add 入金`
- 通帳記入
    - `git commit`
- 通帳に記入したデータを銀行に送信
    - `git push`

「順番おかしくね？先に銀行に送信して成功したら通帳に記入じゃね？」って？
gitの説明なので勘弁して('ω')

### ついでにデビットカードも作って何かしら支払う
- 口座に連動するデビットカードを作成
    - `git clone 口座`
- デビットカードで買い物
    - 口座確認
        - `git pull`
    - 出費額計上
        - `git add 出費`
        - `git commit`
    - 出費を口座に登録
        - `git push`

「失敗したパターン」は省略

### 通帳記入
- ATMに通帳突っ込んでデビットカードで支払った分を通帳に記入(更新)
    - `git pull`
【Vue3に向けて】viteのconfigを書いて、resolve aliasを設定する。

## はじめに

Vue3がRCになって速幾年、待ち遠しいですね。
私も今更ですが、Vue3を少しづつ試したり、viteを使ってみたりしてます。

vite、初めてHMRを見たとき、「え、本当にリロードされたの？」とびっくりしたのを覚えてます。

今回はviteでもwebpackのようにresolve aliasの設定の仕方を記事にしていきます。

## やりたいこと

- `src/components/*.vue`を設定したい。
  - importする時に`./components/Hoge.vue`とかしない。

```
vite-app
  ├ src
  │  ├ components
  │  ├ pages
  │  └ main.js
  └ vite.config.js
```

## 設定方法

viteには、`vite.config.js`という、`webpack.config.js`の様な設定ファイルを記述することでresolve aliasの設定をできます。

`vite.config.js`に書ける設定は公式の[こちら](https://github.com/vitejs/vite/blob/master/src/node/config.ts)を見てもらうのが一番ですが、今回はresolve aliasの部分だけ抜粋して紹介。
公式のファイルを読んでるとこんな文章が、

```js:vite/config.js
  /**
   * Import alias. The entries can either be exact request -> request mappings
   * (exact, no wildcard syntax), or request path -> fs directory mappings.
   * When using directory mappings, the key **must start and end with a slash**.
   *
   * Example `vite.config.js`:
   * ``` js
   * module.exports = {
   *   alias: {
   *     // alias package names
   *     'react': '@pika/react',
   *     'react-dom': '@pika/react-dom'
   *
   *     // alias a path to a fs directory
   *     // the key must start and end with a slash
   *     '/@foo/': path.resolve(__dirname, 'some-special-dir')
   *   }
   * }
   * ```
   */
```

`// alias a path to a fs directory`の部分の通りに設定してしまえば良いのだが注意点

`// the key must start and end with a slash`

どうやら、`/`に始まる様に設定しなくてはならないらしい(パッケージに大してalias貼るのとバチらない様にだろうか)

ともかく設定する。

- プロジェクトのrootディレクトリに`vite.config.js`を作成する。

```js:vite.config.js
import path from 'path'

module.exports = {
  alias: {
    // alias a path to a fs directory
    // the key must start and end with a slash
    '/@components/': path.join(__dirname, 'src/components')
  }
}
```

設定はこれで終わり。
vueファイルで下記の様にimportを書いてあげることでcomponentを呼び出すことができる。

```vue:pages/index.vue
<script>
import Hoge from '/@component/Hoge.vue'

export default {
  components: {
    AppTimeTable
  }
}
<script>
```

## 終わりに

`vite.config.js`、設定を見てみるといろいろできそうなのでもう少しみてみて、まとめようと思います。
それにしてもfsのaliasは`/`から始めなくちゃいけないのが少し変な感じがしてしまいますね。。。
vscodeでパスかく時、localの/配下を保管してしまうw
`jsconfig.json`もしっかり書いてあげねばだ。
SQLの記述順序と実行順序の基本

#記述の順序
1.select 取得する列の指定
2.from テーブルの指定
3.(inner,outer) join 結合処理
4.where 絞り込み条件の指定
5.group by グループ条件の指定
6.having グループ化後の絞り込み条件の指定
7.order by 並び替え条件の指定
8.limit 取得する行数の指定

#実行順序
1.from テーブルの指定
2.(inner,outer) join 結合処理
3.where 絞り込み条件の指定
4.group by グループ条件の指定
5.having グループ化後の絞り込み条件の指定
6.select 取得する列の指定
7.order by 並び替え条件の指定
8.limit 取得する行数の指定

#集約関数
集約関数とは、集計操作を行う際に用いる関数です。代表的な集約関数と使い方は以下。
```select count(*) from users; /* usersテーブルのレコード数を数える */
-- 出力結果:6
select avg(age) from users; /* ユーザーの平均年齢を求める */
-- 出力結果:23.5000
select sum(math + japanese) from users where user_name = 'tani'; /* 谷さんの合計点を求める　*/
-- 出力結果:188
select max(math) from users; /* 数学の最高点を求める */
-- 出力結果:90
select min(math) from users;　/* 数学の最低点を求める */
-- 出力結果:39
```
#GROUP BY
グループ化を行うときに使用する。特定の場所で集約関数を使用したいときに使用する。基本的には、カラムでグループ化して、その別のカラムに関して集約関数を適用することが多い。

#HAVING
group byで指定した場所を計算した後に、その計算結果に関してwhere句のように条件指定できるのがhaving句。

```
select user_name, sum(math+japanese)
from users
group by user_name
having sum(math+japanese) >= 180;
```

#order by
selectで取り出したデータの順番を並び替えることができる。ascで昇順、descで降順になる。

#IN
リスト形式に比較が可能になる

#limit
取得するレコードを制限できる

#date関連
業務において日付や時間に関するデータの取り扱いは重要。
時間・日付関数の代表例は以下。
current_date:現在の日付
current_time:現在の時間
date_format:指定した書式にフォーマット
IBM Cloud DNSへの移行 from お名前.com

##目的
お名前.comで取得したドメインを、IBMCloud DNSのNSで名前解決できるようにしてみる。
今回は、**fsas.work**というテスト用ドメインの名前解決をIBMCloud DNSサービスで実施する。

##環境
* ローカル端末：macOS Catalina 10.15.6
* プラットフォーム:IBMCloud
    * IBMCloud DNS
    * Webサーバ:CentOS 7.7.1908(Virtual Server for Classic)
* ドメイン取得サイト:お名前.com

###変更前の状態
`ローカル端末での作業`

変更前は**fsas.work**のNSは、**お名前.com**になっている。
つまり、**fsas.work**へのDNS問い合わせは**お名前.com**の以下４つのサーバがIPを返す。
**https://fsas.work**にアクセスが来た際に、返答するIPアドレス

```
% dig fsas.work ns
;; ANSWER SECTION:
fsas.work.		86400	IN	NS	01.dnsv.jp.
fsas.work.		86400	IN	NS	02.dnsv.jp.
fsas.work.		86400	IN	NS	03.dnsv.jp.
fsas.work.		86400	IN	NS	04.dnsv.jp.
```

##IBMCloud DNSの設定
`IBMCloudポータルでの作業`

IBMCloudポータルへログインし、下記の通り**前方ゾーン**を**選択**する。

![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/337683d8-1e56-7960-7057-3ecdfc6bbf5a.png)

**Add DNS Zone**を**選択**し、**Domains**に**NS移行対象のドメイン名**を**入力**する。
続けて、**Default IP**には、移行対象ドメインにアクセスが来た際のアドレスを入力し、**Add Zone**を**選択**する。
今回の例では、**fsas.work**へアクセスが来た場合に**165.192.xx.xx**にアクセスするようになる。

![IBM_Cloud____DNS_Forward_Zones-2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/3449d14b-5c33-9649-a8bd-a7b3001e2784.png)

続けて、不要なレコードがあれば削除し、必要なレコードも追加する。
今回は、**www**だけ残して後は削除した。
![IBM_Cloud____DNS_Edit_Zone-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/e12055df-f17a-ee32-f63b-a06a6b1b997b.png)

NSレコードのTargetアドレスをお名前.comに登録する為、これを**控えておく**
* ns1.softlayer.com
* ns2.softlayer.com

![IBM_Cloud____DNS_Edit_Zone-3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/54c8fd7f-c282-8c2c-12f7-8cac78103716.png)


##お名前.com側の設定変更
`お名前.comポータルでの作業`

お名前.comポータルへログインする。
**ドメイン**の設定から、変更したいドメイン名の横にある、ネームサーバー列を**選択**する

![お名前_com_Navi-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/6360c267-6d08-0c01-c09f-eac2d4c165a7.png)

**2.ネームサーバーの選択**で、**その他**、**その他のネームサーバーを使う**を選択し、
先程記録した、ネームサーバの情報を記入し、**確認**を選択する。
* ns1.softlayer.com
* ns2.softlayer.com

![お名前_com_Navi-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/000df23f-517c-1d23-6e0e-619001a1472e.png)

**OK**を**選択**する
反映まで24時間から72時間と記載されているが、私の場合はすぐ反映された。
![お名前_com_Navi-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/4abd3687-d439-24d8-e382-42b0a30502d7.png)



##移行確認

Aレコード確認

```
% dig www.fsas.work
;; ANSWER SECTION:
www.fsas.work.		86400	IN	A	165.192.xx.xx
```

NSレコード確認

```
% dig fsas.work ns
;; ANSWER SECTION:
fsas.work.		86400	IN	NS	ns1.softlayer.com.
fsas.work.		86400	IN	NS	ns2.softlayer.com.
```

これで完了
あとは、IBMCloud DNSの前方ゾーンを随時追加する事で、インターネットから**fsas.work**の名前解決が可能
mysqlの使い方

#データ型
データ形式のことで、テーブル作成時に、それぞれのカラムに指定した形式のデータしか入力できないように設定することが可能。主に3つのデータ型が存在している。
・数値型(int型、float型、double型)
・文字列型(char型、varchar型、text型)
255文字未満はvarchar型、それ以上はtext型
・日付、時刻型(date型、datetime型、time型)

#データベース操作の一連の流れ
1.データベース一覧を確認する
2.データベースを作成する
3.useコマンドで使用するデータベースを選択する
4.テーブルを作成する
5.作成したテーブルに対してデータの追加や取得を行う

##1.データベース一覧を確認する
```show databases;```

##2.データベースを作成する
```create database sample_database;

##3.使うデータベースを選択する
```use sample_database;```

##4.現在使用しているデータベースを確認する
```select database();```

##5.データベースの削除
```drop database sample_database;

##存在するテーブルの確認
```show tables;```

##テーブルの作成
テーブル名、データ型、名前が必要。
```create table users(
user_id int AUTO_INCREMENT NOT NULL primary key,
user_name varchar(20),
) engine = MyISAM default charset = utf8;```
CentOS7にPython3をインストール

## Python3をインストール

- 現在のバージョン確認

```
$ python --version
Python 2.7.5
```

- CentOS7にyumリポジトリの追加

```
yum install -y https://repo.ius.io/ius-release-el7.rpm
```

- パッケージの検索

```
yum search python36
==========
=============================================== N/S matched: python36 ===============================================
python36-cairo-devel.x86_64 : Libraries and headers for python36-cairo
python36-greenlet-devel.x86_64 : C development headers for python36-greenlet
python36-psycopg2-tests.x86_64 : Test suite for python36-psycopg2
boost-python36.x86_64 : Shared object symbolic links for Boost.Python 3
boost-python36-devel.x86_64 : Shared object symbolic links for Boost.Python 3
boost-python36-static.x86_64 : The Python3 Boost C++ static development libraries
libpeas-loader-python36.x86_64 : Python 36 loader for libpeas
python36.x86_64 : Interpreter of the Python programming language
python36-Cython.x86_64 : A language for writing Python 3.6 extension modules
python36-GitPython.noarch : Python3 Git Library
python36-HepMC3.x86_64 : HepMC3 Python 3 bindings
python36-HepMC3-rootIO.x86_64 : HepMC3 ROOT I/O module Python 3 bindings
python36-HepMC3-search.x86_64 : HepMC3 search module Python 3 bindings
python36-PyMySQL.noarch : Pure-Python MySQL client library
python36-PyYAML.x86_64 : YAML parser and emitter for Python 3.6
python36-SecretStorage.noarch : Python 3.x module for secure storing of passwords and secrets
python36-abimap.noarch : A helper for library maintainers to use symbol versioning
python36-aiosmtpd.noarch : Asyncio-based SMTP server
==========
```

いろいろ出てきましたが、必要なパッケージをインストール

- パッケージのインストール

```
yum install python36u python36u-libs python36u-devel python36u-pip
```

- バージョン確認

```
$ python --version
Python 2.7.5

$ pip --version
pip 20.2.2 from /usr/lib/python2.7/site-packages/pip (python 2.7)

$ python3.6  --version
Python 3.6.8

$ pip3 --version
pip 20.2.2 from /usr/local/lib/python3.6/site-packages/pip (python 3.6)
```

python3.6が入りました。
Javaの開発環境を作ろう(更新中)

# はじめに

新人エンジニアです。
会社でJavaを使って開発を行っているので、練習としてJavaの開発環境を構築することしました。
Javaってオワコンじゃね？？って声が聞こえそうですが、まあ会社の標準フレームワークなので仕方ないですね。

コツコツ更新していくので、長い目で見守っていただけると嬉しいです。

# 環境

| 役割 | ツール名 |
|:-:|:-:|
| OS  | WSL2  |
| エディター | VScode |
| Java  | OpenJDK 8  |
| フレームワーク  | Spring Boot |
| ビルド | Maven |
| テスト | JUnit |
| CI | Jenkins |
| コンテナ | Docker |
| コンテナ管理ツール| Kubernetes |

# Jenkinsコンテナを作る

今回はCI用ににJenkinsのコンテナを構築します。
注意点としては、Dockerイメージとして`jenkins/jenkins:lts`を使うこと。
`jenkins:latest`はプラグインのダウンロードで失敗します。(2020/09/06現在)

```:WSL2
$ sudo docker run -p 8080:8080 -p 5000:5000 -v ~/jenkins:/var/jenkins_home jenkins/jenkins:lts

(中略)

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

Your_Password [初回起動に必要]

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************
```

コンテナが起動したので、ブラウザで`http:\\localhost:8080`にアクセスしてみましょう。


- 初回登録画面 [コンソールのパスワードを入力]

![jenkins-1-700x383.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703667/8a6ecb9b-b60e-1153-dc16-78cc0738df27.png)

- Pluginのインストール（とりあえず推奨の方をインストール）

![getting-started-setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703667/4ef2fb57-8584-d1d3-2e49-c506b78dd0c4.png)

- Pluginインストール画面

![jenkins-install-suggested-plugin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703667/946951c0-b9cd-31b2-2904-1083485398f4.png)

以上でユーザー登録が完了しました。
次の作業としてはジョブの作成、Gitとの連携がありますが、記事作成までお待ちください。
VercelとNetlifyの違いが分からなかったので実際に比べてみた。

## はじめ

敬愛するエンジニア@sho0211との何気ない会話

僕「ホスティングサービス試そうと思ってるんですけど、何かおすすめありませんか？」
@sho0211「Vercelいいんじゃない？知らんけど」
ちょろい僕「ほぉ！じゃあそれ使って見ます！」

1日後、、、
僕「おぉ、Vercel良いな」
僕「でも正直他のホスティングサービスとの違い、強みが正直分からないゾ...」
僕「せっかくだしちょっと比べてみようかな」

というわけで、本編入ります。

## やったこと

- VervelとNetlifyに同一アプリケーションをデプロイしてみて、下記内容を比較してみました。
  - buildの速度
  - サイト表示の速度
  - 付随機能の違い
  - その他(サービスの使いやすさなど)

## 検証するアプリ概要

下記のような小規模な同一アプリをVercel、Netlifyそれぞれにデプロイをしてみました。

- Vue.js2.x(3系使う予定だったけど、いろいろあったんです、、、)
  - Gridsomeを採用(今回作ったアプリ要件的にプラグインが良さそうだったので、、、)
- コンポーネントは大小合わせて10ないくらいの小規模
- 外部APIは叩かない(Jsonでデータを保持していて、そいつをimportして読んであげている)
- GitHub Integration
  - masterにpushされたら勝手にデプロイされる、これ便利だよね。
- VercelもNetlifyも無料プラン

### build速度

まずはbuildの速さ、pushされたモノをすぐに公開したいですよね
こちら微修正を加えた時の結果です。commit id見てもらうとわかりますが、同じ内容です。

- Netlify(37秒)
![スクリーンショット 2020-09-04 23.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/54fcd95e-fa39-88c0-997a-70012e9ba2a7.png)

- Vercel(25秒)
![スクリーンショット 2020-09-04 23.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/885d434f-5c4d-bd5e-83af-299c3e6f03c4.png)

なるほど、軽微な修正だと、そこそこの差がありますね。

では次は、nodeのpackageを追加したcommitの結果を見てみましょう。

- Netlify(46秒)
![スクリーンショット 2020-09-04 23.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/f5d00712-4a84-9336-dcfc-ce8fa05c1346.png)

- Vercel(25秒)
![スクリーンショット 2020-09-04 23.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/9b84bf2a-61bc-fcad-ec5a-e243ff8c077d.png)

倍ほどの差が出ましたね。。。！
buildに関しては、**Vercelが速い**と思っても良いかもですね。

### サイト表示速度

実際にサイトの読み込みが完了するまでを見ていきましょう。
2パターン、見てます。

#### 初回アクセス時の読み込み速度

- Netlify(およそ3300ms)
![スクリーンショット 2020-09-04 23.12.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/fe7264ce-f886-2ee3-ee72-67b81d8731f4.png)

- Vercel(およそ1300ms)
![スクリーンショット 2020-09-04 23.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/c0381e91-4366-5f38-961f-6ceaca611480.png)

#### リロードしたときの読み込み速度

- Netlify(およそ1500ms)
![スクリーンショット 2020-09-04 23.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/2b17db81-b546-4006-2dd5-9f0049f4acc5.png)

- Vercel(およそ850ms)
![スクリーンショット 2020-09-04 23.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/fa449640-8b23-e412-8361-d7d17912603f.png)

これは大きく差が出ましたね。
サイトの表示速度に関しても、**Vercelが速い**と思っても良いかもです。
[NetlifyのCDNが遅いという話](https://blog.anatoo.jp/2020-08-03)はありましたが、ここまで差があるとは。

### その他

以下は完全に個人の主観です。

#### Netlify

- 情報は多い
  - Qiitaだけでみても30記事ほど比べてNetlifyは340記事ほどあります。
  - 公式が充実してるとは思いますが、英語onlyなので、少し読むのに時間がかかりそう。_
- 実際のプロダクトでの利用実績
  - Code for Japanの立ち上げた新型コロナウイルス感染症対策サイトはNetlifyでも挙げられており、プロダクション利用も十分に可能である[(記事)](https://www.atmarkit.co.jp/ait/articles/2003/06/news137.html)

#### Vercel

- 画面がすごいシンプル
  - buildのログ、serverless関数のlog、設定くらいしかないので、迷わず使える。
- Basic認証が無料枠でも利用できる
  - NetlifyだとPRO以降しか利用できません。
  - Vercelは自身でnodeなどで実装は必要になりますが、無料枠でも使用が出来る。

## まとめ

調査の母数が少ないため、これが間違い無いとは言えないですが、build時間、サイトの表示速度共にVercelの方が改めて速いと今回調べてて感じました。
大きく機能に差はないため、

- 情報量でNetlify
- 速さ、シンプルさを求めてVercel
で考えるのは今のところ良いのかなと思いました。

ホスティングサービス、この2つ以外にもまだまだあるので、それぞれの良し悪しを理解して使うことが大事かなと思います。
少しでも参考になれば幸いです。
PowerAutomateでAzureADの従業員IDを取得する

# はじめに
当社ではMicrosoft365を導入しているので、MS365で使用できるAzureAD(以下、AAD)に社員の情報を集約しています。当社には社員を一意に識別する社員番号があるのですが、それをAADのどこに入れるか悩んでいました。AADには「employeeId」というフィールドがあるんですが、Azure Active Directory管理センターでは「employeeId」を入力するところがなかったので、「employeeId」を使うことを諦めていました。
PowerShellを使えば「employeeId」に値をセットできますが、当社ではMS365アカウントを作成するのは非IT部門のためPowerShellを使うのは敷居が高いです。

2020年8月前半に久しぶりにAzure Active Directory管理センターを見たら「従業員ID」なる項目が増えていました。元々あったのか見落としていたのか分かりませんが、管理センターのUIであれば非IT部門でも編集できるので、「従業員ID」を使うことにしました。「employeeId」の和名が「従業員ID」のようです。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/4fd6efdf-2a0d-693f-57da-2f5173771b20.png)
いつからあったんだ。。？


# やりたいこと
PowerAutomateでメールアドレスから従業員IDを取得する。

# (参考)PowerShellで従業員IDを更新
こんな感じです。従業員IDは拡張項目なんですね。

```PowerShell
Set-AzureADUserExtension -ObjectId "メールアドレス"  -ExtensionName "employeeId" -ExtensionValue "従業員ID"
```

# PowerAutomate
## ユーザの情報を取得
AADなので、AzureADコネクタの「Get user(ユーザーの取得)」アクションと思いきや、これだと取得できません。
Office 365 Usersの「Get user profile (V2)(ユーザー プロフィールの取得 (V2))」アクションを使用します。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/f3929835-98c5-d8d2-2be6-65931bf2bdf7.png)
「フィールドの選択」は任意項目ですが、従業員IDは指定しないと返却されないので、「employeeId」を入力します。フィールド名を入力するとこのフィールドの値しか返却されなくなってしまうので、他のフィールドも返却して欲しい場合はカンマ区切りでフィールドを指定します。
試しに実行してみると従業員IDのみが返却されます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/5bb40f02-5d72-3d10-1253-2d0a1b1e386b.png)

## 従業員IDを取得
この後のアクションで従業員IDを使用できるか確認します。通常であれば「動的なコンテンツ」で指定できるはずですが、従業員IDというコンテンツは見当たりません。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/a5f79c73-1261-3a17-199b-542d8c219cde.png)

こういう場合は仕方なくJSONから値を取得します。

## JSONの解析
Get user profile (V2)アクションの戻り値はJSONですが、それを解析するには「JSONの解析」アクションを使用します。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/1688c300-17ca-4b31-1f01-d988d0118695.png)
コンテンツにはGet user profile (V2)アクションの戻り値である「Graph APIからのユーザ」を指定します。
スキーマは「サンプルから生成」で作成しました。Get user profile (V2)アクションの戻り値をそのまま使用すると良いでしょう。


```json
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(employeeId)/$entity",
  "employeeId": "従業員ID"
}
```

# 終わりに
従業員IDの存在を知るまではCommon Data Serviceに従業員ID相当の値を入れていたのですが、これで使わなくて済みます。CDSの場合、Excelで簡単に編集できるんですが、PowerAutomateだといつからかは知りませんがDynamics365コネクタが非推奨になってしまったので。
Ubuntu20.04でクリップボードを使いやすくする


- 範囲選択で画面をとると画像がファイル保存されてしまい、クリップボードからのコピペができない

## インストール

```
sudo apt install flameshot
```


## 起動
```
flameshot &
```

## 範囲選択で取る
![Screenshot from 2020-09-04 23-59-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/59ee576a-c9b4-2c53-4f0b-594bb6ff8135.png)
2分以内にQiita記事に貼り付けるgif画像を作る方法



# 流れ
１、収録する(所要時間1分)
２、.movを.gifに変換する(所要時間1分)

#1,収録する。
1,Shift+Command+5（条件:macOS 10.14 Mojave　以上）を同時に押して画面収録を開始する。それ以外の場合はQuick Time Playerを立ち上げる。
有名なスクショのコマンドはShift+Command+3or4(3だと普通に4だと選択範囲)。
macOS 10.14 Mojave以上ではShift+Command+5のショートカットが追加されています。
こんな感じのがでるので、
![スクリーンショット 2020-08-31 22.23.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/b0ba8f00-a4e3-ddc9-2eaf-03798bf17221.png)

これを選択すると、
![スクリーンショット 2020-08-31 22.23.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/0f9f7934-acbd-50bc-0dd9-7c4b0c49b4f1.png)

上の画像の「取り込む」のところが**「収録」**に変わるので、
![スクリーンショット 2020-08-31 22.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/7bfbf26a-2d7d-b4fc-ad45-de39cdb1e68c.png)
**「収録」**を押して撮影開始します。
停止すると.movファイルができます。

#2、.movを.gifに変換する
.movはそのままだとQiitaに載せられないので、.gifに変換します。

```sh
# homebrewでインストール
brew install ffmpeg

# 変換する
ffmpeg -i hoge.mov fuga.gif

# (応用) 動きを滑らかにしたい場合、rオプションでフレームレートをあげる(1秒あたりのコマ数)
ffmpeg -i hoge.mov -r 10 fuga.gif
```

完了するとgifが作成されこんな感じで貼れます。
![load2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/71716a9a-cca4-5e90-1348-989ed76cee85.gif)

# 補足
FFmpegは無料で使用することのできる動画、および音声のエンコーダです。
LinuxでもWindowsでもMacでも使用することが可能です。
公式サイト:
https://www.ffmpeg.org/download.html
【node.js】process.env.{変数名}

大抵の場合、環境変数はハードコードされていて、

```js
process.env.ENVNAME
```

たまに必要になってぼちぼち忘れてしまうので、メモ


```js
process.env[ENVNAME]

// ユースケース(条件によって環境変数を出し分けたい時)
const env1 = 'ENV1';
process.env[env1];  // process.env.ENV1　と同じ
```

こんな感じ。:sunglasses:
PHP学習要点(随時更新予定)

・PHPはHTMLに埋め込んで使うことができる。<?php 〜 ?>の中にPHPの命令を書いていき、<?php 〜 ?>の部分がHTMLに変換された上で表示される。

・PHPでは文末にセミコロン「;」を使って文を区切る。 
※セミコロンを忘れるとエラーが起きるので注意する。

・「//」から行末まではコメントになります。動作には関係しない情報で、主にメモなどに用いられる。

・「echo」は文字列などを出力するための命令である。文字列を出力する場合はシングルクォーテーション「'」かダブルクォーテーション「"」で囲む。
※echoの後に半角スペースを入れるのを忘れないようにする


・頭に「$」記号をつけることによって変数を定義する。「$変数名 = 値;」で様々な値を変数に入れることが出来る。

・変数に、その後再び値を代入すると、後で代入した値によって変数の中身が上書きされる。

・足す数字が１の時だけ、さらに省略した書き方が可能になる。++を変数の前に書くとその行の命令が実行される前に足されるのに対し、++を変数の後に書くとその行の命令が実行された後に足される。１だけ引くための--も同様である。

・ドット「.」記号を用いると文字列を連結することができ、文字列同士の連結、変数と文字列の連結、変数同士の連結をすることができる。

・「.=」を用いると変数と文字列の連結を省略して書くことができる。

・ダブルクォーテーションで文字列を囲んだ場合、中の変数を{}で囲むとその部分が変数に入っている値で置き換えられる(変数展開)。シングルクォーテーションで文字列を囲んだ場合は変数展開されず、変数が{}で囲まれていてもそのまま文字列としてみなされる。

・if, elseifによる分岐が多く複雑な場合、switch文で書き換えるとシンプルで読みやすいコードにできる。switch(式)の(式)がcaseの値と一致したとき、そのブロックが実行される。caseのどれにも一致しなかった時、defaultのブロックが実行される。
※case や default の最後は：(コロン)になるので注意。

・caseブロックの最後にはbreak命令を指定します。break命令は現在のブロックから脱出するための命令である。
※break命令がないと、後ろに続くcaseブロックが続けて実行されてしまうので注意。

・配列の基本構文は「$配列名 = array(値１, 値2, ・・・);」のようになっている。

・配列の末尾に値を追加するときは「$配列名[] = 値;」とする。また、すでに存在するインデックス番号を指定すると、配列の値を上書きすることもできる。

・連想配列は、配列と同じく複数のデータをまとめて管理するのに用いられる。連想配列では「$配列名 = array('キー名' => '値１', ・・・);」といったように、「=>」を用いてキーと値をセットする。
※配列との違いは、個々の要素を管理するのにインデックス番号ではなく、「キー」と呼ばれる文字列などの値を指定することができる点である。
최신 Git 커밋메시지 Jenkins 환경 변수로 저장하고, 다른 Job에 전달하기

![commit-message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/d0473922-1227-6c25-ded5-3ad074382b95.png)
## TL;DR
> Jenkins의 기본 제공되는 [environment variables](https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables) 에는 Git 커밋메시지 환경변수가 없습니다.
> 최신 Git 커밋메시지를 추출하여 환경 변수로 저장하고, 다른 Job에 전달하는 방법을 기록하였습니다.

## 사전설치
- Jenkins v2.235.3
    - [Environment Injector Plugin](https://plugins.jenkins.io/envinject/) v2.3.0
    - [Parameterized Trigger Plugin](https://plugins.jenkins.io/parameterized-trigger/) v2.37

## Jenkins Job 설정 및 실행
> 예시)
> Pre-Job은 최신 Git 커밋메시지를 `commit_message` 변수로 저장하고, Post-Job을 실행시킵니다.
> Post-Job은 전달 받은 `commit_message`를 화면에 출력합니다.

### 1. Pre-Job
https://github.com/jenkinsci/jenkins 의 master 브랜치에서 소스를 가져옵니다.
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/a1d3d534-7acf-9a97-7cbc-6f892cb570e3.png)

`commit_message` 에 최신 Git 커밋메시지를 저장하고, `Inject environment variables`을 추가합니다.

```bash
echo commit_message=$(git log --oneline --format=%B -n 1 HEAD | head -n 1) > ./temp.properties
```
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/cb0fa794-7501-39a9-7e82-996461978114.png)
Post-Job을 실행시킵니다.
`Trigger parameterized build on other projects` 과 `Predefined parameters` 를 활용합니다.
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/1146f629-3699-7cc5-282c-2c5c23904062.png)
Pre-Job 콘솔 출력은 다음과 같습니다.
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/bf3c5856-5b3e-cbcb-5d57-36af56fc5af3.png)

### 2. Post-Job
`commit_message` 를 `String Parameter` 변수로 받고, 화면에 출력합니다.
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/355b5e46-4fc9-f932-38e4-9a0f003dad4d.png)
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/6013846d-1033-5bfe-ac55-674067021f13.png)
Post-Job 콘솔 출력은 다음과 같습니다.
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/fdda1c1b-e2ed-5810-6b14-a95828382b3b.png)

## 참고
- https://zuminternet.github.io/JENKINS-BUILD/
- http://confluence.augkorea.org/pages/viewpage.action?pageId=19630268
Vuejsでイベントリスナーが削除できなかったのはこういう理由か

## できなかったこと

- 登録したイベントリスナーが削除できていなかった

## 原因

- 登録したイベントリスナーと別のイベントリスナーを削除していたから

## 詳細

- イベントを以下のように登録した

```javascript
mounted: {
  document.addEventListener('scroll', this.scroll, {
    capture: true
  })
}
```

- イベントを以下のように削除していた

```js
destroyed: {
  document.removeEventListener('scroll', this.scroll)
}
```



## こうすべき

- イベントを以下のように登録したら

```javascript
mounted: {
  document.addEventListener('scroll', this.scroll, {
    capture: true
  })
}
```

- イベントを以下のように削除すべき

```js
destroyed: {
  document.removeEventListener('scroll', this.scroll, {
    capture: true
  })
}
```

## 補足

- イベントを削除せずに、同じ名前で登録したら処理は上書きされない
  - つまり、同じイベントで複数の処理が追加で実行されるようになる
Line, Message Push Broadcast で LineBotの友達全員にメッセージを送信

```bash:push_broadcast.sh
curl -X POST https://api.line.me/v2/bot/message/broadcast \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer アクセストークン' \
-d @"C:\Users\kuma\event.json"
```
GitHubとの連携

GitHubでローカルリポジトリとリモートリポジトリを連携させることにうまくかないことがあったが、ちょっとしたことで解決ができたのでここに記載したいと思います。

連携がうまくいかなかった原因は、コードを書くフォルダ内のターミナルにgit initをしたら解決ができた。

git initコマンドとは？ gitのリポジトリを作成することができるコマンドである。

以下、ローカルとリモートリポジトリの連携を行い解決した方法。

1.編集中のターミナルでgit initコマンドを打つと、リモートにリポジトリを作成することができる。

2.Git HubデスクトップのAddからAdd Existing Repositoryを選択し、編集ファイルを貼り付けるとcommitができるようになる。

3.commitとpushを行ったら、次にpublish branchを押す。するとリモートリポジトリと連携するのにprivateかpablicかを選択できるので
keep code this privateというチェック項目を外し、作成を完了させる。もし、チェックを外し忘れた場合は、GitHub.comにある編集中のリポジトリを開いてsettingを押し、一番下にスクロールしたらあるDanger Zoneの中のChange repository visibility(This repository is currently private.)このリポは現在プライベートである。とあるので、　Change repository visibility　(リポの見え方を変える)を押し、Make public(皆がみれるようにする)を押し、下部のフォーム内にPlease type gitの(ユーザー名)/(リポの名前) to confirm.とあるのでフォーム内に gitの(ユーザー名)/(リポの名前)を入力し、 I understand,　change repository visibility.(リポの見え方の変更について理解しました。)を押すとprivateからpublicに切り替えることが出来ます。

ちなみに、private時は作成したリポの横に鍵マークがついているのでリポを見ればどちらになっているかがすぐにわかります。

以上でGitHubとの連携については終わりにしたいと思います。
Railsのtime_selectでデフォルトで入力される日付を、画面上にある別のフィールドの入力値にする

### 背景とやったこと
Railsのアプリで、こんな感じのフォームを作っていました。
実施日を`date_field`で選択し、開始時間・終了時間をそれぞれ`time_select`で選択します。

なお、実行環境は`rails 5.2.4.2`です。
[![Image from Gyazo](https://i.gyazo.com/8732f9653b30168bf4ddf8251658e334.png)](https://gyazo.com/8732f9653b30168bf4ddf8251658e334)

viewファイルの中身はこんな感じです。データ型は、全てのフィールドで`DateTime`型でした。

```haml:view
.form-group  
  = f.label :date, "実施日"
  = f.date_field :date
.form-group  
  = f.label :begin_at, "開始時間"
  = f.time_select :begin_at
.form-group  
  = f.label :closed_at, "終了時間"
  = f.time_select :closed_at
```

### 起こっていた問題
このフォームから、データを送信すると、次のようになりました。

```Ruby
#<Activity:0x00007fc97030fe30
 id: 1,
 date: Fri, 11 Sep 2020 00:00:00 JST +09:00,

 begin_at: Mon, 1 Jan 0001 00:10:00 JST +09:00,
 closed_at: Mon, 1 Jan 0001 00:20:00 JST +09:00

 time_took: 600,

 created_at: Fri, 04 Sep 2020 13:53:01 JST +09:00,
 updated_at: Fri, 04 Sep 2020 13:53:01 JST +09:00>
```

…はい？？:sweat_smile:
何で、**西暦１年の１月１日の時間になっている**のでしょうか....。

いろいろ調べたところ、これはRailsの仕様でしょうがないようです。
こちらの記事のように時間だけを入力させる方法もあるにはありました。
（ただし、`begin_at`、`closed_at`のデータ型はTime型にする必要がありそうです）

[time_selectで時間だけを入力させる[rails]](https://hellhellmymy.hatenablog.com/entry/2019/09/29/223203)

ただ、今回は、`time_took`という別カラムで「かかった時間」を計算していたり、今後これらの数字を分析に使うことが予想されていたりと、

色々と`begin_at`、`closed_at`の値を使い回しそうだったので、正確に日時を表すよう、`time_select`フォームの入力値に、`date`フィールドで入力した年・月・日を入れることにしました。

### やったこと
モデルに以下のようなメソットを定義し、それを`before_save`コールバックで呼び出します。

```ruby:model
class Activity < ApplicationRecord
  before_save :set_the_day_implement
  
  private

  def set_the_day_implement
    year = self.date.year
    month = self.date.month
    day = self.date.day

    self.begin_at = self.begin_at.change(year: year, month: month, day: day)
    self.closed_at = self.closed_at.change(year: year, month: month, day: day)
  end
end
```

コードの解説です。`self.date.year`のかたちで、フォームから入力した「実施日(`date`)」の年をそれぞれ取り出すことができます。month, dayもそれぞれ同様です。

```Ruby
# dateフィールドの値が '2020-09-04'の場合
self.date.year
#=> 2020
self.date.month
#=> 9
self.date.day
#=> 4
```

また、`self.begin_at`、`self.closed_at`の値には、それぞれ以下のような形でアクセスできます。

```ruby
self.begin_at
#=> Mon, 1 Jan 0001 00:10:00 JST +09:00
self.begin_at.year
#=> 1
self.begin_at.month
#=> 1
self.begin_at.day
#=> 1

self.begin_at.change(year: 2020, month: 9, day: 4)
#=> Fri, 4 Sep 2020 00:10:00 JST +09:00
```

ただし、最後に`self.begin_at`に、`self.begin_at.change(引数)`で定義した内容を代入しないと、**カラムの値は更新されません。**（←ここに気づかなくて結構ハマった）

```Ruby
# dateフィールドの値が '2020-09-04'の場合
year = self.date.year
month = self.date.month
day = self.date.day

self.begin_at.change(year: year, month: month, day: day)
#=> Fri, 4 Sep 2020 00:10:00 JST +09:00
self.begin_at
#=> Mon, 1 Jan 0001 00:10:00 JST +09:00
# 西暦１年に戻っている

self.begin_at = self.begin_at.change(year: year, month: month, day: day)
self.begin_at
#=> Fri, 4 Sep 2020 00:10:00 JST +09:00
# 代入するとカラムの値が更新される
```

さて、これで無事欲しいデータを手に入れることができました。

最終的にビューで表示されるのはこんなデータです。(カッコ内の数字は、別のコールバックで作成した「かかった時間」です。)

[![Image from Gyazo](https://i.gyazo.com/4eaebbbad9b97452865dd06976e9e5f0.png)](https://gyazo.com/4eaebbbad9b97452865dd06976e9e5f0)

今後活用が予想されるデータなので、正しい日付のデータがきちんと入って満足なのでした:relaxed:
引き続きお仕事頑張っていきます♪
Macが空き容量不足でXcodeをupdateできない時の対処

## 結論
自分の場合はこの子が容量食ってました...
消していい子のようです。

```
sudo rm -rf '/Users/xxxxx/Library/Developer/Xcode/iOS DeviceSupport'
```
この辺りの細かいところは調べると色々記事が出てくるため割愛します...m(_ _)m

## 背景
SSD128GBのMacbook pro 2017を使っており、事あるごとに容量不足（謎の「その他」肥大化）に悩まされていました。
Xcodeは毎度updateできず、色々消してなんとか容量空けてダウンロードサイト([https://developer.apple.com/download/more/](https://developer.apple.com/download/more/))からXcode落としてのやり方でしのいでいましたが、今回はどうにも行かず...

「mac その他 削除」や「mac 容量不足 xcode」等で調べてでてくる方法は一通り試したものの、キャッシュ削除してもPC再起動したりセーフモードで起動しても空き容量はあまり変わらず、だいぶ遠回りしてXcode関連の不要ファイルを削除する方法にたどり着きました..。

探すフレーズが違うとこうも情報にたどり着けないものか、と。難しい:sweat:

## 追記(2021.1.5)
それでも容量が足りなくなったため、ダウンロードサイト([https://developer.apple.com/download/more/](https://developer.apple.com/download/more/))から落としたxipファイルを外付けHDDに移し、そこで解凍（本体Mac内に展開される）する方法を今はやっています
Vuejsでスクロール下までいかないと利用規約に同意できないようにする仕組み

## まえがき

- 利用規約など、全てを読み終えてほしいためスクロールで一番下までいかないと次に進めないという処理を入れたいときどうするか

## 前提

- 以下のコードは参考程度なので適宜変えてください
  - 改行など
  - ボタンのbindする変数など


## できるようになること

- 長い文章を一番下までスクロールしたときに、ボタンを有効にするという処理を入れられる
- スクロールする文章がない場合は、初めからボタンを有効にするという処理を入れられる



## 
## 手順

- html部分の中

```html
<template>
  <div class="scroll_area">
    ここに文章を入力する
  </div>
  // 何かしらのボタンで有効にする変数をbindする
  <v-button>
  </v-button>
</template>
```

- js部分の中

```js
  mounted () {
    window.addEventListener('scroll', this.checkScrollArea, {
      capture: true
    })
    const scrollAreaElement = document.querySelector('.scroll_area')
    const scrollAreaScrollHeight = scrollAreaElement.scrollHeight
    const scrollAreaClientHeight = scrollAreaElement.clientHeight
    // スクロールするテキストが少なくてスクロールできない場合に対応
    if (scrollAreaScrollHeight === scrollAreaClientHeight) {
      this.isDisabledButton = false
    }
  },
    
  destroyed () {
    window.removeEventListener('scroll', this.checkScrollArea, {
      capture: true
    })
  },
  methods: {
     checkScrollArea () {
      const scrollAreaElement = document.querySelector('.scroll_area')
      const scrollAreaScrollTop = scrollAreaElement.scrollTop
      const scrollAreaScrollHeight = scrollAreaElement.scrollHeight
      const scrollAreaClientHeight = scrollAreaElement.clientHeight
      if (scrollAreaScrollHeight - scrollAreaScrollTop <= scrollAreaClientHeight) {
        // ここにボタンを有効にする変数などを変える処理をいれる。
        this.isDisabledButton = false
      }
    },
  }
```

- CSS部分の中

```CSS
.scroll_area {
  overflow-y: scroll;
}
```



## 参考

- https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
yukicoder contest 264 参戦記

# yukicoder contest 264 参戦記

## [A 1217 せしすせそ](https://yukicoder.me/problems/no/1217)

ループを回して、一致しないインデックスを求めて、XtoY を出力するだけ.

```python
S = input()

for i in range(26):
    a = chr(i + ord('a'))
    if S[i] == a:
        continue
    print('%sto%s' % (a, S[i]))
    break
```

## [B 1218 Something Like a Theorem](https://yukicoder.me/problems/no/1218)

何も考えずに全探索しても TLE にならなくて、あれってなった.

```python
n, z = map(int, input().split())

for x in range(1, z + 1):
    for y in range(x, z + 1):
        if x ** n + y ** n == z ** n:
            print('Yes')
            exit()
print('No')
```

## [C 1219 Mancala Combo](https://yukicoder.me/problems/no/1219)

操作としては一番左側の A<sub>i</sub>=i を操作してを繰り返すわけだけど、もちろんナイーブにそれをシミュレートする実装をすると TLE になる(なお、heapq で実装して体験しました orz). よくよく考えると、A<sub>i</sub> より右の A<sub>i+1</sub>～A<sub>N</sub> を消した回数だけ積み増されるので、その積み増しを c とした時に c + A<sub>i</sub> が i の倍数になっていればいい. c を積みながら右からスキャンすると *O*(*N*) となって解ける.

```python
N, *A = map(int, open(0).read().split())

c = 0
for i in range(N - 1, -1, -1):
    if (A[i] + c) % (i + 1) != 0:
        print('No')
        break
    c += (A[i] + c) // (i + 1)
else:
    print('Yes')
```
make[1]: warning:  Clock skew detected.  Your build may be incomplete. と言われた時

時刻ズレているとMakeに言われる時の対応。

```sh
sudo ntpdate ntp.nict.jp
```

# 参考

https://www.atmarkit.co.jp/ait/articles/1906/21/news013.html

（追記）WSLであれば以下が暫定対応として最速。

```
wsl --shutdown
```
vuetifyを使って爆イケwebページを超簡単に作成する方法

お久しぶりです。

今回はwebページの作成方法で困っているそこのあなたにとっておきな超簡単にそれなりのものが作れてしまう方法を伝授したいと思います

#vuetifyとは?

Vuetifyは、美しく手作りされたマテリアルコンポーネントを備えたVue UIライブラリです。設計スキルは必要ありません。まじです。

私もインターン先で作業をする際に初めて使用したのですが、デザインスキルなくてもちょっとしたweb知識があれば簡単にイケイケなwebアプリが作れてしまいます。まじです。

今回は「デザインスキルなんてないよお〜」ってお困りの方にも無料テンプレを利用してシャレオツなものが本当に簡単に作れてしまうのでぜひ試してみてください!

# 環境

macOSCatalina 10.16.6

#テンプレのダウンロード
[こちら](https://vuetifyjs.com/ja/themes/premium/)にアクセスして希望のテンプレートをダウンロードします
(目のアイコンをクリックしたらデモが見れます!)

![スクリーンショット 2020-09-04 22.40.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249044/53ebdd2c-a60a-e0e7-e5ef-5dd4b9236209.png)

#開き方

ダウンロードした「parallax-starter-master」を解凍すると以下のファイル構成となってます

![スクリーンショット 2020-09-04 22.45.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249044/1b51d3fa-ddc6-d93e-d709-787e5c22c126.png)

index.htmlをブラウザから開くとテンプレートがすぐに利用できます。(ドラック&ドロップで簡単にできます!)


![スクリーンショット 2020-09-04 22.47.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249044/f4ea0833-46ab-a34f-b335-508816125dfb.png)


#おわりに

無料テンプレートもたくさん種類がありますし、課金をすればもっと素敵なものがたくさんあるので、初心者の方など、自分の作りたい形に似ているものから自分好みにhtmlファイルを編集して作り始めて見るのも全然ありだとおもうので、ぜひぜひ取り組んでみてください！！！
【Mysql】CSVファイルをDBにインポートする

##今日やること
CSVでダウンロードしたファイルをmysqlを使ってDB（phpmyadmin）へ格納する

以前結構悩んだ上に無事成功させたのですがメモるのを忘れ再度時間を要してしまったため備忘録という意味も込めてまとめる。

##前提
スプレッドシートに入力したトレーニング情報をcsvでダウンロードしmysqlを用いてDBへ格納させる。

##スプレッドシートをCSV形式でダウンロードする
該当のSSのシートを表示し「ファイル→ダウンロード→カンマ区切りの値（.csv、現在のシート）」の順に押下しダウンロードする。
![スクリーンショット 2020-09-04 21.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589286/9abba886-bf5b-1cce-f9a3-b5d4c276b965.png)

とっても簡単。

##現在使っているオブジェクトの傘下に置いてあげる
![valuX-AWS-Cloud9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589286/1ef98e87-3b83-8a72-409c-e2c39196a893.png)

今回Torekaというオブジェクトを使って開発しているのでその上に該当のCSVファイルをスクロールして持っていけばOK

これで事前準備OKということで。
（デスクトップ上などに置いてもできるそうですがなんかうまくいかなかったのでこのやり方が間違いないかと）

##ターミナル上でMysqlを動かしていく
では準備ができたので実際にsqlを使ってDBにCSVファイルを格納していきます。

###前提条件
・予めアプリケーションを用意し、CSVファイルのデータを格納するモデル（今回はadvicedateモデル）を用意しておく
・今回はウェブアプリケーションの作り方はノータッチ。過去の記事を読んでね
・またコマンドの意味なども趣旨とは異なるので書きません。もし気になる人は検索してみてね

###mysql(マイ エス キュー エル)とは
mysqlとは、データを保存するデータベースを管理するソフトの一種
今回はCloud9を使って開発していくので既にインストールされている。ので起動させましょう。

※$ が先頭についている場合はターミナルでの作業となります。
また今回は全てターミナル上での作業になります。

```
#mysqlの起動(すでに起動している場合もあります)
$ sudo service mysqld start
```

```
#mysqlにユーザー名『root』で接続する
$ mysql -u root
```

```
#データベースの確認
mysql> SHOW DATABASES;
```
```
#データベースの選択（今回はadvicemenuモデルを使う）
mysql> USE toreka_development;
```
```
#tableの中身を確認
mysql> SHOW TABLES;
```

```
#table内のカラム一覧を確認（今回はadvicemenusのカラム確認）
mysql> SHOW columns FROM advicemenus;
```
これでほんとに準備完了。
次から実際にCSVを取り込んでいきます。

```
mysql> load data local 
       infile "/home/ec2-user/environment/toreka/advicemenudb.csv" 
       into table advicemenus 
       fields terminated by ',';
```
1行ずつ入力してエンターで進んでいくでもOKです。

今回はスプレッドシート上にカンマがないので上記だけでOKですが、
例えば"ベンチプレス"などカンマが入っている場合は下記のように書きます。

カンマなどの囲み文字がある場合は最後の行に
「enclosed by '"';」
を足してください。

その際 ; が最終行の意味をもっているのでこのように書きます。

```
mysql> load data local 
       infile "/home/ec2-user/environment/toreka/advicemenudb.csv" 
       into table advicemenus 
       fields terminated by ','
       enclosed by '"';
```

こんな感じで結果が出れば成功です。

```
Query OK, 184 rows affected, 368 warnings (0.01 sec)
Records: 184  Deleted: 0  Skipped: 0  Warnings: 368
```

![スクリーンショット 2020-09-04 22.42.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589286/9de223f8-8873-5f7a-c1f4-ac4ca6977780.png)

しっかり格納されていますね。

##参考

[【MySQL】CSVファイルをデータベースにインポートする](http://blog.chatlune.jp/2018/03/01/mysql-import-csv/ "Qiita")
[【MySQL】csvファイルをDBにインポートする方法](https://qiita.com/oden141/items/239a7ce3cfe3197a3ba7 "Qiita")

基本参考をみていただければうまくいくかと思います。
が、もしうまくいかなかったら上記試してみてください。では。
MessageActionをimport する時のエラーを解消

### LINE公式アカウントでテンプレートメッセージを送りたくてネット記事を参考に実装していたところ、

```.py
from linebot.models import (
MessageAction 
)
```
の部分でエラーが出てしまいました。

### 結局、

```requirements.txt
line-bot-sdk==1.7.2
```

line-bot-sdkのバージョンを1.5.0(?)とかから1.7.2まであげたらエラーが解消されました。


参考
-
[PythonでLINEの「Messaging API」でテンプレートメッセージを実装してみた](https://qiita.com/kotamatsuoka/items/c4e651f1cb6c4490f4b8)
【Java】ランダムメソッド

Javaに初めから用意されているクラス、java.util.Random  java.lang.Math
この２つがあります。

今回はMathクラス（java.lang.Math）のランダムメソッドについて簡単な説明をします。
Math.random()
ポイント
・戻り値の型は　double
・0.0　～　1.0未満　の範囲で乱数を取得します

例
①double rand = Math.random();
②double rand = Math.random() * 10;
③int rand =  (int)(Math.random() * 10);

①戻り値の型がdoubleなので変数の型は基本doubleでないとコンパイルエラーとなります。
②0.0から10.0未満の範囲で乱数を取得する場合、ランダムメソッドの後に　* 10　をつけます。
③整数での乱数を取得する場合、②をint型にキャストする必要があります。