OmniAICreator/Qiita-1.07M huggingface dataset:
enumからセレクトボックスを作る際に、表示する文言を変えたいとき

あまり無いケースだとは思うが、enumからセレクトボックスを作成する際に、文言を変えたい場合の方法をメモしておく。
前提として、gemに `enumerize` と `reform` を使用している。

```ruby:product_form.rb
extend Enumerize

enumerize :fluit, in: {
  apple:      1,
  orange:     2,
  peach:      3,
  strawberry: 4,
  cherry:     5,
}, predicates: { prefix: true }

property :fluit
```

```ruby:ja.yml
product:
  fluit:
    apple: りんご
    orange: オレンジ
    peach: もも
    strawberry: いちご
    cherry: さくらんぼ
```

普通に書けば、これで良い。

```ruby:new.slim
= f.select :fluit, f.object.class.fluit.options, {prompt: '果物を選択'}
```

しかし、「『りんご』と『さくらんぼ』は『（特別セール中）』という文言を入れたい」と言われたとする。
とはいえ、ja.ymlを変えたくはない。
`f.object.class.fluit.options` を使わずに1つずつ書くのも、メンテナンス性が悪い。

そこで、`f.object.class.fluit.options` が生成する Array を map で回して、特定の value の時のみ、文言を足して返すメソッドを作った。


```ruby:product_form.rb
def fruit_select_display
  self.class.fluit.options.map do |key, value|
    if value == 'apple' || value == 'cherry'
      [key + '（特別セール中）', value]
    else
      [key, value]
    end
  end
end
```

```ruby:new.slim
= f.select :fluit, f.object.fruit_select_display, {prompt: '果物を選択'}
```

これでいったん用は足せた。
Centos7 にてYou have new mail in /var/spool/mail/root を非表示にした

#環境
Centos7

#背景

Centos7 にてYou have new mail in /var/spool/mail/root
という通知がコマンド実行の度に表示されていました。

この通知がうっとおしいので非表示の方法について調べてみます。

#解決策
vi /etc/crontab
　
MAILTO=root から　MAILTO=“”に変更

その後、再起動後、表示されなくなりました。

#参考

以下のサイトを参照しました。ありがとうございます。
https://genchan.net/it/server/9970/
Sudachiで名詞のみ抽出

#Sudachi
説明はしません。自分で調べてください。

#コード
sudachiで名詞のみを取得するコードです。
素人のコードでごめんなさい。


```
from sudachipy import tokenizer
from sudachipy import dictionary

tokenizer_obj = dictionary.Dictionary().create()
mode = tokenizer.Tokenizer.SplitMode.C

sample="国家公務員に私はなりたい。"
content=[
    (
        m.surface(), 
        m.dictionary_form(), 
        m.reading_form(),
        m.part_of_speech()
    )
    for m in tokenizer_obj.tokenize(sample, mode)]

len_=len(content)
#print(content)
for i in range(len_):
	if content[i][3][0]=="名詞":
		print(content[i][0])
```
Rails link_toにパラメータを渡す

<h2>link_toを使ってgetsでコントローラにパラメータを受け渡したい</h2>
<p>やりたいこと</p>
<p>view側からコントローラにリンクする際に、値を受け渡したい</p>
<h3>結論</h3>
<p>以下のようにパスの引数にハッシュの形で追加してやる</p>
<p>※例）top/indexからtop/link1へ値を渡す場合</p>
```erb:top/index.html.erb
  <%= link_to "リンク１へ", top_link1_path(name: "piyo") %>
```
<p>パラメータを受け取る</p>
```ruby:top_controller
class TopController < ApplicationController
  def link1
    @params = params[:name]
  end
end
```
<p>色々と調べてみましたが、備忘録として</p>
【技術書まとめ】『Docker/Kubernetes 実践コンテナ開発入門』を読んだまとめ


## 第1章 Dockerの基礎

- 構成ファイルとコマンドだけで環境が作れる。
- アプリケーションと実行環境を同梱したデプロイがDocker流
- Dockerを利用するメリット
    - 環境起因のトラブルを最小限にできる
        - 冪等性が保てる
        - いつなんど実行しても同じ結果が保証される
- Docker Compose
    - yamlファイルで起動順を制御したりできる

## 第２章 Dockerコンテナのデプロイ

- Dockerイメージとは
    - コンテナを具現化するためのテンプレート

```terminal
$ docker image pull gihyodocker/echo:latest # イメージを取ってくる

$ docker container run -t -p 9000:8080 # コンテナ実行

$ curl http://localhost:9000/ # アクセスしてみる

$ docker stop $(docker container ls -q) # 停止
$ docker container stop $(docker container ls --filter "ancestor=example/echo" -q) # 停止

$ docker image build -t example/echo:latest . # dockerイメージを作成

$ docker image ls # dockerイメージを確認

$ docker container run -p 9000:8080 example/echo:latest # ポートフォワーディング
```

- Dockerに対する操作
    - イメージとコンテナの2つに大別される。


## Dockerイメージ
- 「Dockerイメージをビルドする」

```terminal
$ docker image --help # ヘルプを見る

$ docker search --limit 5 mysql # 検索する
```

- imaegeIDはバージョン番号としての役割もある
- `latest`はGitでいうこところの`master`ブランチ

```terminal
$ docker image tag example/echo:latest example/echo:0.1.0 # 特定地点をバージョン名などでタグ付けしておく
```

## Dockerコンテナ
- 実行・停止・破棄の3つの状態

```terminal
$ docker container run -t -d --name gihyo-echo example/echo:latest # 名前付きコンテナをつくる（開発時に便利）
$ docker container run -it alpine:latest # ターミナルが表示されて文字が入力できる。仮想環境にログインしたように使える。

$ docker container ls -q # コンテナIDだけ抽出する
$ docker container ls --filter "name=echo1" # 名前でフィルターする
$ docker container ls -a # 終了したコンテナを含める

$ docker container rm f66f6f2013da # コンテナを破棄する
$ echo '{"version":100}' | docker container run -i --rm gihyodocker/jq:1.5 '.version' # そのときだけ必要なコンテナは --rm で即時破棄する

$ docker container logs -f &(docker container ls --filter "ancestor=jenkins" -q) # ログを見る

$ $ docker container exec -it echo sh # コンテナ内でコマンド実行する

$ docker container cp echo:/echo/main.go . # コンテナ内のものをコピーしてくる
$ docker container cp dummy.txt echo:/tmp # コンテナへコピーする
```

## 運用管理向けコマンド

- prune
    - 実行していないコンテナを一括削除

```terminal
$ docker container prune # 実行していないコンテナを一括削除
$ docker image prune # 実行していないイメージを一括削除

$ docker container stats # コンテナ単位でのリソース使用状況を見る
```

- Docker Compose
    - docker同士を連携する
    - Jenkinsの例

```docker-compose.yml
version: "3"
services:
  echo:
    image: example/echo:latest
    ports:
      - 9000:8080

```

```terminal
$ docker-compose up -d # 起動
$ docker-compose down # 停止
$ docker-compose up -d --build # 毎回ビルドして裏で起動
$ docker-compose ps # 起動を確認
```

- `volume`はコピーでなく共有する


## 第3章 実用的なコンテナの構築とデプロイ

- Dockerはアプリケーションとインフラをコンテナ単位で分離したもの
- 1コンテナに1つの関心事
    - 「1分置きにHello!を出力する」など
    - レプリカとして複製された場合に副作用がないか
- Dockerのポータビリティの限界
    - CPUアーキテクチャやOSの前提
    - ダイナミックリンクの課題
- アプリケーションの挙動を環境変数で制御する


## 第4章 実践的なアプリケーション構築

SwarmでTODOアプリをつくる

```terminal
$ docker container run -v ${PWD}:/root ch04/tododb:latest
```

とりあえずここまで。
【Flutter】ColorFilteredで画像の色彩変更

## まえがき
Flutterを2020年初めから勉強始めていろいろパッケージやWidgetを使ってみています。

## ColorFiltered

これは入れ子にcolorFilterをかけられるWidgetです。

![Simulator Screen Shot - iPhone SE (2nd generation) - 2020-09-07 at 13.32.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311390/60ccd631-5677-e7c9-d881-3f3039650bf7.png)

こんな感じに、画像の色を変えられます。

上の段はただの普通に画像表示をしました。
右の真っ赤な画像は、`Image.asset()`の`color`で画像を指定しました。

下の段からColorFilteredを使った画像です。

```dart
ColorFiltered(
  colorFilter:
      ColorFilter.mode(Colors.green, BlendMode.colorBurn),
  child: Image.asset('images/sample1.png'),
),
```
このようなコードで、表示することができます。

`ColorFilter.mode`のなかで、フィルターをかける色と、`BlendMode`でどのようにフィルターをかけるか決めます。

`BlendMode`はこちらの記事を参考にさせていただきました。
https://qiita.com/ko2ic/items/77521e4344f3bd73d326


## ソースコード
今回作ったコードのソースコードも一応載せておきます。

```dart
import 'package:flutter/material.dart';

class SampleColorFlitered extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SampleColorFlitered();
}

class _SampleColorFlitered extends State<SampleColorFlitered> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ColorFlitered'),
      ),
      body: Center(
        child: Table(
          // defaultColumnWidth: FlexColumnWidth(1),
          defaultVerticalAlignment: TableCellVerticalAlignment.bottom,
          children: [
            TableRow(
              children: [
                Image.asset('images/sample1.png'),
                SizedBox(),
                Image.asset(
                  'images/sample1.png',
                  color: Colors.red,
                ),
              ],
            ),
            TableRow(
              children: [
                Text('ただの画像'),
                SizedBox(),
                Text('画像の色変更'),
              ],
            ),
            TableRow(
              children: [
                ColorFiltered(
                  colorFilter:
                      ColorFilter.mode(Colors.green, BlendMode.colorBurn),
                  child: Image.asset('images/sample1.png'),
                ),
                ColorFiltered(
                  colorFilter: ColorFilter.mode(Colors.green, BlendMode.lighten),
                  child: Image.asset('images/sample1.png'),
                ),
                ColorFiltered(
                  colorFilter:
                      ColorFilter.mode(Colors.green, BlendMode.modulate),
                  child: Image.asset('images/sample1.png'),
                )
              ],
            ),
            TableRow(
              children: [
                Text('BlendMode.\ncolorBurn)'),
                Text('BlendMode.\nlighten'),
                Text('BlendMode.\nmodulate'),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
```
Eloquent のいろんなwhere

###単純なwhere
```
$query->where('col1', $val1)
$query->where('col1', '<>', $val1)
```

###where でAND
```
$query->where('col1', $val1)->where('col2', $val2)
```
###where でOR
```
$query->where('col1', $val1)->orWhere('col2', $val2)
```

###where で複数値
```
$query->whereIn('col1', array($val1,$val2))
$query->whereNotIn('col1', array($val1,$val2))
```

###where でNull
```
$query->whereNull('col1')
$query->whereNotNull('col1')
```

###where で(A AND B) Or (C or D)など
```
$query->where(function($query) use($val1,$val2){
        $query->where('col1',$val1)
              ->where('col2',$val2)
      })
      ->orWhere(function($query) use($val3,$val4){
        $query->where('col3',$val3)
              ->where('col4',$val4)
      })
```
VSCodeのセットアップメモ

# 最初に
PCが新しくなったのでVSCodeをセットアップしたのでメモ

# ダウンロード
[ここ](https://code.visualstudio.com/Download)からダウンロード

インストールオプションは基本デフォルトでインストールした。

# 認証Proxyの設定
インストールが完了して起動したら
FIle > Preferences > Settings
Search Setting でproxyと入力

Http:Proxy AuthorizationのEdit in settings.jsonをクリック

nullのパラメータを修正
```settings.json
{
    "http.proxyAuthorization": "http://ゆーざ:ぱすわーど@プロキシアドレス:プロキシポート"
}
```

上書き保存したらプロキシの設定はOK

# ところがどっこい

↑の設定したけどブラウザで設定しているpacファイルから勝手にプロキシ引っ張ってきていた。
設定いらんかったやんけ。

<b>ただ、インターネットアクセスする際に認証プロキシで認証情報を2回聞かれるので注意。</b>

# さいごに
認証情報2回聞かれる現象はネットでも困っている人が多かったですが解決策をみつけられませんでした。

今のPCで頻繁にProxyを超えることはないので、このままでよいかな...
解決策を知っている人がいたらコメントで教えてください。
FXのCSVデータを読み込んで大量のチャート画像を作成するプログラムをPythonで作ってみた

# 本記事について
深層学習(CNN)でFXの予測をするために、
CSVデータ(日時、始値、高値、安値、終値が記載されたもの)から
大量のチャート画像を生成してみようと思います。

# 成果物
以下のようなチャート画像をCSVから作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242659/98e6f1c7-f608-ef50-a8da-6d7ae6ffa6f0.png)


# CSVファイルについて
CSVファイルは、USDJPYの1時間足です。（2007年1月~2020年9月まで）
1時間足のCSVデータなんて無いよという方は、<a href="https://qiita.com/sw1394/items/6b74d629659f421e692a">こちらの記事</a>を参照してください。
CSVの中身は下記のような感じです。8万行以上あります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242659/d788fb32-b05e-3668-c551-3d42899fbd55.png)

# コード
コードは以下の通りです。

```Python
import matplotlib.pylab as plt
import pandas as pd
import numpy as np

def make_sma(parab, arr=None):
    """
    関数の説明：引数で受け取ったarrayに平均移動線を追加します。
    parab:期間
    arr:日時、始値、高値、安値、終値で構成されたarray
    """
    row = arr.shape[1] #配列の列数を取得
    arr = np.c_[arr, np.zeros((len(arr),1))] # 列の追加
    for i in range(parab, len(arr)):
        tmp = arr[i-parab+1:i+1,4].astype(np.float) #期間内の数値を入れる
        arr[i,row] = np.mean(tmp) #移動平均の値を記入

    return arr

def dataframe_to_img(chart_range, img_name, df=None):
    """
    関数の説明：DataFrameを画像に変換して保存する。
    chart_range:DataFrameの範囲
    img_name:画像の保存先
    df:描画するDataFrame
    """
    df = df[0:chart_range]

    plt.figure()
    df.plot(legend=None) #凡例を削除
    plt.axis('off') #枠線の削除
    plt.tick_params(labelbottom=False,
                    labelleft=False,
                    bottom=False,
                    left=False) #枠線の削除
    plt.box(False) #枠線の削除
    plt.savefig(img_name,bbox_inches="tight") #余白を削除して保存
    plt.close('all')


#csvをarrayに読み込む
arr = np.loadtxt(r'CSVファイル', delimiter=",", skiprows=1, dtype='object') 

#テクニカル指標を追加
arr = make_sma(parab=25, arr=arr)

#DataFrameに変換
col_name = ['Date',"Open","High","Low","Close","SMA"]
df = pd.DataFrame(arr,columns=col_name)

#DataFrameに変換して、画像を保存
df = df[df!=0].dropna() #0の行を削除
df.to_csv(r'tarintest_labels.csv',encoding='utf_8_sig') #あとで正解ラベルとして利用するので、DataFrameも保存
df = df[['Close','SMA']] #グラフに描画する列だけにする
df = df.astype('float') #floatに変換

chart_range = 360

for i in range(20):
    try:
        img_name = str(i) + '.png' #画像の保存先
        dataframe_to_img(chart_range, img_name, df=df[i:chart_range+i])
    except IndexError:
        pass


```

コードの解説です。
最初に、CSVをnumpyで読み込んでます。

その後、``arr = make_sma(parab=25, arr=arr)``で、
arrに移動平均線を追加します。移動平均線の期間はparabで指定します。
25だけじゃなく、75や200などの長期線を追加したい場合は、
parabの数値を変更して追加すればドンドン追加できます。

テクニカル指標の追加が終わったら、
``df = pd.DataFrame(arr,columns=col_name)``で
arrをDataFrameに変換します。

``chart_range = 360``は表示するチャートの範囲です。
今回は1時間足のCSVなので、360だと360時間分表示です。

最後はfor文で``dataframe_to_img関数``にDataFrameを渡して1枚1枚保存していきます。
dataframe_to_imgでは、matplotlibを使っています。
枠線などは、深層学習での学習に邪魔なので削除しています。

画像の出力が終わったら、DataFrameはCSVで保存しておきましょう。
深層学習の正解ラベルとして流用するためです。


# 確認
画像が保存されたことを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242659/98e6f1c7-f608-ef50-a8da-6d7ae6ffa6f0.png)

今回はシンプルな移動平均線だけですが、
ボリンジャーバンドや一目均衡表などを表示することも可能です。
OS自作 1日目

#はじめに
「作って理解するOS」を進める際の自分用のメモ。
本書の前半の内容はプログラムを作りながら適宜参照する。


##環境設定
本にあるようにディレクトリの設定とqemuのダウンロード、バッチファイルの生成を行った。
とりあえずqemuが起動した。

##アセンブラの復習
アセンブリ言語で関数の呼び出し、メモリのコピーと比較を行うプログラムを作成した。
・関数を呼び出す前に引数がスタックにpushされる
・引数や定数へのアクセスはbpからの差分で行う

##何もしないブートプログラムの作成
無限ループするだけのブートプログラムを作成する
・ブートプログラムとは
　・起動時にBIOSによって読み込まれるプログラム
　・必要なプログラムをROMからメモリに順次ロードする
　・指定されたROMの先頭512バイトがメモリの0x7C00番地にロードされる
・ブートプログラムは末尾の2バイトが0x55,0xAAである必要がある

##BIOSパラメータブロックの領域を確保
・512バイトの中には外部記憶の属性などのデータを保持する領域(BPB)がある
　・プログラム(IPL)はBPBの後ろにあるのでブートプログラムの一行目はIPLへのジャンプ
・今回は90バイトをBPB用に確保する
　・90バイト分はNOP(何もしない命令:0x90)で埋める

```boot.s
entry:
    jmp ipl
    times 90 - ($- $$) db 0x90

ipl:
    jmp $     ;無限ループ

```
LaravelでClass 'Hoge\FooClass' not found

Laravelに限りませんが、Composerを利用していてClass not foundエラーに遭遇することがあります。
まず対応することは

```
composer dump-autoload
```

のコマンドを打ってautoloadさせます。

それでもなお

```
Class 'Hoge\FooClass' not found
```

が継続する場合は
`vendor/composer/autoload_classmap.php` ファイルを参照して、上記エラーなら`FooClass`が存在するか確認します。
おそらく存在しないと考えられます。今回は新規追加したディレクトリを読み込めていないことが原因でした。

その場合は`composer.json`を確認をすると

```json:composer.json
"autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
```

の記述のclassmapに新規追加したディレクトリ`Hoge`が存在しないことがわかります。

```json:composer.json
"autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories",
            "app/Hoge"  ←追加行
        ]
    },
```

これで再度`composer dump-autoload`でファイルが読み込まれました。
[入門] javascript を少し触ってみた

##railsを勉強していく上でフロント側の機能も必要になってきたので少し触ってみました。

##対象
javascriptをとりあえず動かしてみたい人

とりあえず動かしてみたら作法をしっかり学んでいきましょう。。。

####検証ツール大事！

あと、CodePenというサービスがとてもいいです。

ライブラリを複数使う場合はCDNで読み込む必要がありますが html~javascript の間は勝手に読み込んでくれているため毎回書く必要がありません。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="kota_0623" data-slug-hash="qBZpYKy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qBZpYKy">
  <span>See the Pen <a href="https://codepen.io/kota_0623/pen/qBZpYKy">
  qBZpYKy</a> by kota (<a href="https://codepen.io/kota_0623">@kota_0623</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>




```hoge.html
<button id='practice'>ボタン</button>

<div class='practice'>テキスト</div>
```



```hoge.js
// html上のid='practice'を受け取る為のもの。
const element = document.getElementById('practice');
// 定数elementに代入されているスタイル(CSSの要素)に` color: red; `を追加
element.style.color = 'red';
// 検証ツールのコンソールでjavascript側で受け取っている要素を見ることができます
console.log(element);

// html上のclass='practice'を受け取る為のもの。
const element2 = document.querySelector('.practice');
// <div class='practice'> に`style="color: blue;"`を追加
element2.style.color = 'blue';
//  . で一つ下の階層を参照することができます。
// 以下でelement.style.colorにblueが代入されていることをhtmlで確認できます。
document.write(element2.style.color);
```


それでは、ライブラリを使用していきます。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="kota_0623" data-slug-hash="qBZpYKy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qBZpYKy">
  <span>See the Pen <a href="https://codepen.io/kota_0623/pen/qBZpYKy">
  qBZpYKy</a> by kota (<a href="https://codepen.io/kota_0623">@kota_0623</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>





まずanime.jsを読み込める用、CDNを書いておきます。

```hoge.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.0/anime.js"></script>
```


変更のない部分は省略していきます。

```hoge.js
...
//括弧内で文章と変数等を使用したい時にはテンプレートリテラルという書き方があります。
//これでjavascriptで入力したものが<div>タグ等で囲うことができます
document.write(`<div>${element2.style.color}</div>`);

//ちなみにdocument.writeはあまり使わない方が良いらしいです。
//今はconsole.logが通常画面に出せないため、例としてわかりやすいので使っています。


// 変数buttonにanime.jsの動作を入れていきます。
// 変数の定義はlet var とうかかなくても動作しますが、必ず書くようにしましょう。
// ↓は悪い例です。 ※基本的には定数のconstを使うのがいいようです。
button = anime({
  // targetsで今回はid="practice"を指定しています。
  targets: '#practice',
  // Xを250移動させるものです。
  translateX: 250
});

// セレクタの後に.onclickとすることでクリックした時の動作を受け取ることができます。
// functionでクリックした時どうするかを書いていきます。
document.querySelector(".practice").onclick = function() {
  anime({
    targets: '.practice',
    translateX: 115,
  });
}
```
QuasarのVirtualScroll

せしまるです。

本日は業務で使ったq-virtual-scrollについてメモ残し_φ(･_･


# VirtualScroll（仮想スクロール）とは？

リスト形式で表示しているものなどは、項目数分要素を作ってしまう（レンダリングしてしまう）のですが、
VirtualScrollを使用すると、*表示している項目＋アルファ*分しかレンダリングしないのです。
スクロールしたときも、同じ様に表示項目＋アルファ分しかレンダリングしません。

そんな必要あるのか？と思う人もいると思います。
では、仮にリストに表示する項目が何万、何十万件もあるとしましょう。
VirtualScrollを使用しない場合は項目数分レンダリングするので、アプリ（というかブラウザ？）がめっちゃ重くなります（業務内でもこれが問題だった）。
こうなると、他の機能も正常に動かなかったり、ボタン1つ押すのに数秒かかったりなど…使い物にならなくなる場合があります。

VirtualScrollを使用すると、表示項目＋アルファ分しかレンダリングしないので、めっちゃ軽い！
ボタンも即反応！快適快適(・∀・)



# 使い方

基本は[公式ドキュメント](https://quasar.dev/vue-components/virtual-scroll)から。

```test.vue
<template>
 <!--q-virtual-scrollで表示するリストのデータを指定する-->
 <q-virtual-scroll :items="items" separator>
  <!--v-slotで1データとindex-->
  <template v-slot="{ item, index }">
   <!--q-itemのkeyにindexを指定-->
   <q-item :key="index" dense>
    <q-item-section>
     <q-item-label>#index:{{ index }} - {{ item.message }}</q-item-label>
    </q-item-section>
   </q-item>
  </template>
 </q-virtual-scroll>
</template>

<style>
/* スクロールのスタイル指定もできる */
.scroller {
 height: 100%;
}
</style>

<script>
items = new Array<string>();

for(let i = 0; i < 100; i++){
  items.push(`hello!Mr.${i}`);
}

Object.freeze(items);

export default {
  data() {
    return {
      items
    }
  }
}
</script>
```

# 感想

最初はvue-virtual-scroller使おうとしてたけど、q-virtual-scrollのほうが簡単に感じた（個人差）

おわり
JetBrains IDE 2020.2 が sencha プラグインでクラッシュする

## 現象

JetBrains IDE (WebStorm/PHPStorm など) の 2020.2 以降のバージョンに、[Sencha JetBrains Plugin](https://docs.sencha.com/ide_plugins/guides/jetbrains_ide_plugin.html) をインストールすると、IDE がクラッシュします。再起動するとプラグインが disable にされますので、Sencha JetBrains Plugin を使用することはできません。

## サポートの現状

この件について、Sencha の公式サポートに連絡しました。
次の回答が来ました。(DeepLで翻訳)

> これは、IntelliJ製品の2020.2バージョンの既知の問題であり、IntelliJがこのリリースのために使用したGroovyのバージョンとプラグインがビルドされたバージョンの非互換性によって引き起こされます。我々はこの問題に対処している最中であり、うまくいけばIDEプラグインの次期リリースで解決されることを期待しています。

この返事をもらってから1ヶ月以上経ちますが、まだ次期リリースとやらは出る気配がありません。

## 解決策

さすがに、新しいバージョンの IDE を使いたいのでなにか対策はないかと調べたところ、Sencha Forum で[この記事](https://forum.sencha.com/forum/showthread.php?473145-Inetllij-2020-2-not-supported&p=1328069&viewfull=1#post1328069)を見つけました。

> I see this error in IntelliJ 2020.2 during startup:
Caused by: groovy.lang.GroovyRuntimeException: Conflicting module versions. Module [groovy-xml loads in version 2.5.8 and you try to load version 2.5.11
I was able to fix this by removing the groovy * -2.5.8 * .jar files from the plugin. The plugin seems to work with 2.5.11. I have not tested the plugin thoroughly, but have not seen any errors yet. This is, of course, a temporary solution.
> 
> On my windows 10 machine the Sencha plugin are located here: C:\Users\<my user id>\AppData\Roaming\JetBrains\IntelliJIdea2020.2\plugins\sencha-jetbrains-plugin\lib. I just deleted all the groovy jars and the enabled the plugin again.

プラグインのディレクトリを見つけて、そこにある `groovy*-2.5.8.jar` を削除するといいよ、と書いてあります。IDE 本体との間でバージョン競合しているので、プラグイン側から groovy を削除することで動作するということらしいです。ずいぶん乱暴な方法に見えますが...

## プラグインのディレクトリはどこにあるのか

[PHPStorm の公式マニュアル](https://pleiades.io/help/phpstorm/tuning-the-ide.html#plugins-directory) に場所が書いてあります。
macOS の場合は次のディレクトリになります。

```
~/Library/Application Support/JetBrains/<product><version>/plugins
```

### Toolbox を使っている場合

しかし私の環境では、上記のディレクトリが存在しませんでした。
非常に混乱しましたが、どうも JetBrains Toolbox を入れている場合は違うディレクトリになるようです。

```
~/Library/Application Support/JetBrains/Toolbox/apps/PhpStorm/ch-0/202.6948.87/PhpStorm.app.plugins
```

`202.6948.87` という部分はバージョンによって変わるのではないかと思います。同様に環境によっては `ch-0` 以外のディレクトリもあるかもしれません。

## 実施

上記でみつけた plugins ディレクトリから、`groovy*-2.5.8.jar` を削除します。
3つのファイルがあると思います。

- groovy-2.5.8.jar
- groovy-xml-2.5.8.jar
- groovy-json-2.5.8.jar

これらを削除します (私の場合は他のディレクトリに移動しました)。 次に IDE を起動し Sencha JetBrains Plugin を有効にします。そして IDE を再起動します。
Sencha JetBrains Plugin を使うことができるようになりました。
Gatsbyでページごとに個別にCSSを読み込む方法

#はじめに
HTML, JavaScript, CSSで構築された既存のサイトを、Gatsbyで再構築しています。

一般的なサイトでは、CSSの読み込みは

    <link rel="stylesheet" href="style.css">

でページごとに読み込むCSSを指定できますが、Gatsbyの場合は少し特殊だったのでメモを残します。

#Gatsbyでの一般的なCSSの読み込み方法
1. gatsby-browser.jsで読み込む
2. `import`で読み込む
3. CSSモジュールを使う

上記の1.の方法は、全ページで使用するCSSの読み込みに適しています。

2.の方法は一見ページごとに個別に読み込むかと思いきや、グローバルスタイルとして読み込まれるので全てのページに反映されてしまいます。

3.の方法は個別にCSSを指定する方法ですが、モジュール化して、要素ごとにclassNameを記述して・・・と既存コードの書き換えが面倒です。

これらの方法は、Gatsbyで推奨されている方法で、サイト高速化のためには取り組むべきことだと理解しています。
ですが、とりあえずGatsbyで動かしたいんだー、面倒なことは後から調整したいんだー！という方は以下の方法を試してみてください。

#ページごとに個別にCSSを読み込む方法
結論から言うと以下の方法で、実現できます。

    import React from "react"

    export default () => (
           require("style.css")
    )

各ページの `export default` の中で `require` で読み込むことで、
ページごとに個別にCSSを読み込むことができます。

コンポーネント化していて、ページごとに.jsファイルがないという場合は、
下記のようにページ名で場合分けしてCSSを読み込み分けすることができます。

     import React from "react"
     import { withPrefix } from "gatsby"

     export default ({location}) => (
            if (location.pathname == withPrefix ("/pageName/")){
                require("pageName.css")
             }
     )

以上、急場しのぎ的な方法ですが、お試しください。
google広告、yahoo広告 来訪キーワードをダウンロード

google広告やyahoo広告を利用している場合、
実際の来訪キーワードをダウンロードしたい

#google広告

まずはgoogle広告にログイン
https://ads.google.com/aw/overview

キャンペーンを選択

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/a6bd3638-045d-c697-51f7-be246ba3f463.png)

広告グループを選択

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/7b14bf4c-4652-3e66-ad64-3220f38b5ce9.png)


すべての検索を　クリック

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/7fa28831-01e1-cf0d-a657-a0c552229e17.png)


以上で来訪キーワードが見れるようになる。

#yahoo広告

https://promotionalads.business.yahoo.co.jp/ols/dashboard/

キャンペーン「あなたのサイト名」を選択
キーワードを選択

グラフ下の
「検索クエリーを表示」ボタンをクリック
表示されている全てのキーワードをクリック

表示された画面で、期間と表示件数を確認し、ダウンロードボタンをクリック





#古い管理画面: google広告

画面左側
概要、最適化案の
キャンペーンを選択

「あなたのサイト名」を押す

左側の縦に並んだ項目に、キーワードがあるので、選択
その中の「検索語句」というのが実際に検索されたキーワード

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/f0a52606-f14d-5db5-9097-58c7dd525c26.png)


以上
Rails6で標準搭載されたwebpackerでハマる

## 発端
「ん？こっちで見ましょうか？」

から、なかなか気づかずに恥ずかしいハマり方してたので備忘録。

npmやらyarnなどのお話はたくさん情報あるのでそちらで。

## 対象システムのwebpackerでのbuild対象

```:application.html.erb
<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
```
としてるので、js,css 共にbuild対象。

## ファイル構成（必要部分のみ）
```
app/
└ javascript/
  └ packs/
  | └ application.js
  └ stylesheets/
    └ application.css
    └ custom.min.css
```

```:application.js
~~ 省略 ~~
import "../stylesheets/application";
```

```:application.css
@import "~bootstrap/scss/bootstrap";
@import "./custom.min";

```
ふむふむ。

```
$ bin/webpack
~~ 省略 ~~
ERROR in ./app/javascript/stylesheets/application.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Failed to find '~bootstrap/scss/bootstrap'
~~ 省略 ~~
```

この辺含めてファイル構成だったり確認したけれど特に問題なし、と。

改めてエラーを確認したところ。。。

```
ERROR in ./app/javascript/stylesheets/application.css
```

application.css!!

```
$ mv app/javascript/stylesheets/application.css app/javascript/stylesheets/application.scss

$ bin/webpack
```

無事build成功。
トホホ。。

### 結論
拡張子には気をつけよう。
Firebaseを学習されるみなさまへ

MENTAでご相談いただいた経験から、複数名の学習者が**Firebase Realtime Database**を利用しているケースに気づき記事を書いています。

Firebaseは複数のサービスから構成されます。その中にDBを担当するものとして**Firebase Realtime Database**と**Firebase Firestore**があります。

Google(Firebaseの提供者)は、その２つの選択についてこのように述べています。

> 新しくプロジェクトを開始する場合、ほとんどのケースで Cloud Firestore のご利用をおすすめします。
https://firebase.google.com/docs/database/rtdb-vs-firestore?hl=ja

学習者の方は特に意図があって**Firebase Realtime Database**を選択しているわけではないと思います。

Firebaseには初めは**Realtime Database**しか無く、Firestoreが後から出てきた関係から古い教材では**Realtime Database**が使われており自然と使ってしまうのだと思われます。

**Firestore**の方が比較的簡単で扱いやすい側面もありますので、やはりこれから学習される方は**Firestore**を扱っている教材を利用される事をオススメします。

Firebaseの学習について相談したい事がありましたら何なりと[MENTA](https://menta.work/?nic=owAl5EbX7N3uIo7i&ref=ni)よりご相談ください。
LaravelをDockerで開発している際におこるPermission Deniedを回避する

LaradockではなくLaravelをDockerでローカル開発している際にPermission Deniedで`/storage/logs`の書き込みが失敗する事象が見られた。
この際の回避方法を残しておきます。

おそらくPermission Deniedになる原因はホストとクライアントとでUID、GIDが異なることで発生する。
docker-composeにより構成はNginx > php-fpmとしている場合以下のようにphp-fpm側のDockerfileにNginxのユーザーである`www-data`に対して任意のUID、GIDが指定できるようにしておく。

```docker:Dockerfile
ARG PUID=1000
ARG PGID=1000

RUN echo "-> $PUID"
RUN echo "-> $PGID"

RUN groupmod -o -g $PGID www-data && \
    usermod -o -u $PUID -g www-data www-data
```

これを`docker-compose build`時に自身のMacのUID、GIDをを差し込む。

```zsh
$ docker-compose build --build-arg PUID=$(id -u) --build-arg PGID=$(id -g) app
```

これで無事ホストとクライアントのUID、GIDが同じになった。

## おまけ
Makefileで上記のコマンドを設定していると`$(id -u)`が正しく解決できなかった。
以下のように書くとうまくいく

```:Makefile
build_app:
	$(eval UID := $(shell id -u))
	$(eval GID := $(shell id -g))
	@docker-compose build --build-arg PUID=$(UID) --build-arg PGID=$(GID) app
```
Rustのpetgraphクレートを使ってAtCoderのグラフ問題を解く

## はじめに
AtCoderの言語アップデートによりRustでいろいろなクレート(ライブラリ)が使えるようになりました。

ここではグラフアルゴリズムを提供する[petgraph](https://docs.rs/crate/petgraph/0.5.0)クレートを使ってグラフの問題を解いてみます。


## [ABC 070 D - Transit Tree Path](https://atcoder.jp/contests/abc070/tasks/abc070_d)

**問題概要**
n頂点の木とQ個のクエリと整数Kが与えられます。
j(1<=j<=Q)番目のクエリ:頂点x<sub>j</sub>から頂点Kを経由した頂点y<sub>j</sub>までの最短距離を求めよ

**制約概要**
3<= N <= 10^5
1<= Q <= 10^5
1 <= K <= N
1 <= x<sub>j</sub>, y<sub>j</sub> <= N(1 <= j <= Q)
x<sub>j</sub> != y<sub>j</sub>(1<= j <= Q)
x<sub>j</sub> != K, y<sub>j</sub> != K(1 <= j <= Q) 


```rust
use petgraph::algo::dijkstra;
use petgraph::graph::{NodeIndex, UnGraph};
use proconio::input;

fn main() {
    input! {
        n: usize,
        edges: [(usize, usize, usize); n-1],
        q: usize,
        k: usize,
        pairs: [(usize, usize); q],
    }

    //グラフを作る。
    let g = UnGraph::<usize, usize, usize>::from_edges(&edges);

    //ダイクストラ法で頂点kから他の頂点の最短距離を計算
    let res = dijkstra(&g, k.into(), None, |e| *e.weight());


    for (start, end) in &pairs {
        //頂点x_jと頂点kの最短距離 + 頂点kと頂点y_jの最短距離を計算
        let distance =
            res.get(&NodeIndex::new(*start)).unwrap() + res.get(&NodeIndex::new(*end)).unwrap();
        println!("{}", distance);
    }
}
```


**解法**
頂点x<sub>j</sub>から頂点Kを経由した頂点y<sub>j</sub>までの最短距離というのは頂点x<sub>j</sub>と頂点Kの最短距離+頂点kと頂点y<sub>j</sub>の最短距離と等しいです。したがって事前に頂点Kから他の頂点の最短距離を求めておけば各クエリはO(1)で処理できます。

## おわりに
petgraphクレートを使うことでグラフとアルゴリズムを一切実装せず、解くことができました。petgraphクレートにはほかにも様々なデータ構造やアルゴリズムが存在するので使いこなせれば、力強い味方になってくれそうな気がします。
Synapse SQLプールのバックアップ

Synapase SQLプールはPaaSサービスの為、自動でバックアップが取得されます。このバックアップに関して調べました。

#Synapse SQLプールのバックアップは自動で取得され7日間保存
Synapse SQLプールのバックアップは基本的には自動で取得され、バックアップデータが7日間保存されます。取得されたバックアップよりSynapse SQLプールを復元することが可能で、バックアップを取得されたタイミングの状態で復元することが可能です。この「復元できるタイミング」の事を復元ポイントといいます。なので、過去7日間にわたり取得されている任意の復元ポイントから復元することが可能という事になります。

自動バックアップの取得タイミングはRPOが8時間以内になるように自動で取得されます。この自動バックアップのタイミングはユーザでコントロールすることはできません。

以下のSQLで復元ポイントを確認することが可能です。

```SQL
select   *
from     sys.pdw_loader_backup_runs
order by run_id desc;
```

上記SQLを実行した例を記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/2e6e3199-0088-1ed7-1116-c290796890b3.png)

このポイントにSynapse SQLプールを復元することが可能となります。

#バックアップは手動で取得することも可能
バックアップについては自動以外にも手動でバックアップが可能です。例えば日次や月次による大規模なバッチ処理の後などで手動でバックアップを取得するように設定すれば、復元ポイントが作成されるので、運用設計などがしやすくなるのではないでしょうか？

ただし、手動でバックアップした復元ポイントも自動バックアップで作成される復元ポイント同様に保存期間は7日間です。また、7日間の内、自動、手動の復元ポイント合わせ42個までが作成可能です。保存期間の7日を過ぎるか、42個以上の復元ポイントが作成されているとき、古いバックアップから自動で削除される事になります。

#一時停止中はバックアップの取得がされない
Synapse SQLプールは停止機能があります。一方、Synapse SQLプールは停止中、バックアップを取得しないので、長時間の停止の際にはこのポイントを理解しておいた方がよさそうです。

#別のリージョンにバックアップも可能
Synapse SQLプールが起動しているリージョン以外の別のリージョンにバックアップを取得することができます。この機能を「geo冗長バックアップ」といいます。
ただし、別リージョンと言っても、自分で指定することはできません。現在Synapse SQLプールが稼働しているリージョン（プライマリリージョン）とペアとなるリージョンがAzureでは設定されており、このペアになっているリージョンに対してバックアップデータは送付されます。
日本でよく使われるリージョンは東日本リージョンと西日本リージョンですが、このリージョンはペアリージョンとなっています。なので、東日本リージョンにSynapse SQLプールを起動し、geo冗長バックアップを使用して別リージョンへバックアップデータを取得する場合は、おのずと西日本リージョンに取得されることになります。

geo冗長バックアップはRPOが24時間に設定されていますので、平たく言うと日に1回、geo冗長バックアップが別リージョンにて取得されることになります。


##geo冗長バックアップの確認
`AzurePortal`→`Azure Synapse Analytics(以前のSQL DW)`→`概要`
または、`AzurePortal`→`Azure Synapse Analytics(以前のSQL DW)`→`geoバックアップ ポリシー`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/ca302b3e-e581-ccd7-7064-1962efffa0dd.png)
基本的にデフォルトで有効になっています。

#さいごに
Synapse SQLプールのバックアップの説明のみになりましたので、次の機会には手動復元ポイントの作成や、Synapse SQLプールの復元を実際に試してみたいと思います。試したらまた報告します。
Tomcat管理ツールを起動する

EC2上にインストールしたTomcat8の設定変更をブラウザから行いたい
ということで、設定していく。

Tomcatのバージョン：8

# 1. 管理ツールのcontext.xmlファイルを更新
$CATALINA_HOME/webapps/manager/META-INFディレクトリにある「context.xml」を編集する

```$ sudo vi $CATALINA_HOME/webapps/manager/META-INF/context.xml```

接続元IPアドレスのホワイトリストに、自PCのIPを追加する。

```
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
```

を以下のように修正（自PCのIPが123.456.789.123の場合）

```
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|123\.456\.789\.123" />
```


# 2. tomcat-user.xmlァイルの更新
$CATALINA_HOME/confディレクトリにある設定ファイル「tomcat-user.xml」を編集する

```$ sudo vi $CATALINA_HOME/conf/tomcat-user.xml```

・最終行に以下を追加

```
<role rolename="manager-gui"/>
<user username="tomcat" password="**********" roles="manager-gui"/>
```

# 3. Tomcatの再起動
Tomcatサービスをrestartして設定を有効化
```$ sudo systemctl restart tomcat.service```

サービスの起動状態を確認
```$ sudo systemctl status tomcat.service```

「Active:」欄が"active(xxx)"になっていればOK

```
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sun 2020-09-06 23:50:25 UTC; 48s ago
```

# 4. 管理ツールにアクセス
ブラウザから以下のURLにアクセス
```[サーバ]:8080/manager/html```

context.xmlの設定が正しければ、管理ツールへのログイン画面が表示される
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613975/55c9a91b-a39b-27f0-78b7-10778abfa11f.png width=250>

tomcat-users.xmlに指定したユーザ名とパスワードでログインする

Tomcat Webアプリケーションマネージャ画面が表示された
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613975/796dab87-35a9-ba2d-909a-5eb1fa475d16.png width=250>
DockerでMySQLを5.7から8.0にアップデートする

# これはなに
DockerのMySQLを5.7から8.0にアップデートする方法です。
docker composeを使ってる前提です。

# 手順



```diff:docker/mysql/Dockerfile 
- FROM mysql:5.7
+ FROM mysql:8.0
```

`docker/mysql/Dockerfile`のバージョンを書き換えます。

```bash
docker-compose build mysql
```

`docker-compose build`するとバージョンアップされます。
ダメそうなら
`docker-compose build --no-cache mysql`
で試してみてください。

再度mysqlコンテナを起動すると、自動でデータのアップグレードが行われ、MySQL8.0として使えるようになります。
一度データがアップグレードされてしまうと、過去のバージョンのMySQLでは動作しなくなってしまう可能性があるので注意してください。

# Laravelで発生する問題の解消

mysql8からデフォルトの`auth plugin`が変更になっていて
それにlaravelが対応していなく以下のエラーが発生します。

```
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from `users` where 
```

そこで、以下の設定を`my.conf`に設定します。

```my.conf
default-authentication-plugin = mysql_native_password
```

以上、 参考になりましたら幸いです。
Tencent CloudのTCPlayerを使ってみた

## TCPlayerLiteとは
TCPlayerLite（Tencent Cloud Web Super Player ）は、モバイルやPCのブラウザ上でオーディオやビデオストリームを再生する問題を解決するために設計された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/2ce7d682-e30c-a2c9-d5d6-dc39488e1e89.png)


## 機能
### 1.ビデオの再生の他に、ライブ配信の再生機能も持っている。

- ビデオの再生
- ライブ配信の再生

### 2.サポートするプロトコールは以下のようです。

- HLS(M3U8)（ビデオとライブ配信） format: http://xxx.liveplay.myqcloud.com/xxx.m3u8
- FLV（ビデオとライブ配信） format: http://xxx.liveplay.myqcloud.com/xxx.flv
- RTMP(ライブ配信の再生)  format: rtmp://xxx.liveplay.myqcloud.com/live/xxx
- MP4(ビデオの再生)  format: http://xxx.vod.myqcloud.com/xxx.mp4

## 実装方法
### 1. Scriptの導入

```html
<script src="https://cloudcache.tencent-cloud.com/open/qcloud/video/vcplayer/TcPlayer-2.3.2.js" charset="utf-8"></script>;
```

### 2. Playerのタグを追加

```html
<div id="id_test_video" style="width:100%; height:auto;"></div>
```

### 3. jsでTcPlayerを設定

```js
var player = new TcPlayer('id_test_video', {
"m3u8": "https://1256993030.vod2.myqcloud.com/d520582dvodtransgzp1256993030/cc9f922c5285890781386012275/v.f220.m3u8", //ビデオのURL    
//"mp4":"http://1301505281.vod2.myqcloud.com/dc455e1cvodcq1301505281/d98e77ce5285890806134848415/pmdn9YUDQBYA.mp4", // mp4のURL
"autoplay" : true,      // 自動再生
"poster" : "http://www.test.com/myimage.jpg", //動画のヒントとなる画像を表示する
"width" :  '480',//playrの幅
"height" : '320'//playrの高さ
});
```
ここまではTcplayerをできた。
全部のソースコード：

```html

<html lang="en">
       <head>
           <meta charset=utf-8/>
       </head>
       <body>
            <script src="https://cloudcache.tencent-cloud.com/open/qcloud/video/vcplayer/TcPlayer-2.3.2.js" charset="utf-8"></script>;
            <div id="id_test_video" style="width:100%; height:auto;"></div>
            <script>
                var player = new TcPlayer('id_test_video', {
                    "m3u8": "https://1256993030.vod2.myqcloud.com/d520582dvodtransgzp1256993030/cc9f922c5285890781386012275/v.f220.m3u8", //ビデオのURL
                     "mp4":"http://1301505281.vod2.myqcloud.com/dc455e1cvodcq1301505281/d98e77ce5285890806134848415/pmdn9YUDQBYA.mp4",
                    "autoplay" : true,      //自動再生
                    "poster" : "",
                    "width" :  '1280',// playerの幅
                    "height" : '720'//playerの高さ
                });
            </script>
       </body>
</html>
```
TcPlayer:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/2ce7d682-e30c-a2c9-d5d6-dc39488e1e89.png)


##　まとめ
数行のソースコードでビデオとライブ配信を再生できるWeb Playerをできた。めっちゃ簡単！！！他の機能、例えばniconicoのような画面位コメントを流す機能がありそうです。まだ今度試します。

参考資料：

- VOD Web Player: https://intl.cloud.tencent.com/zh/document/product/266/33977
Cloud Run上でLaravel×React(Mix使用)のサイトを爆速で動かす - 必要な設定と料金関連

# サーバレスVPCで関連サービスと繋ぐ

Laravelをサーバレスで動かすに当たって、最低限使う、かつ、少し考慮が必要と思われるのは

* データベース(MySQL)
* セッション
* ログ

あたりだと思います。ここについては設定方法が公式にありますのでここではその情報だけまとめておきます。

## データベース(MySQL)
当然、データベースの情報はどこからでも直接アクセスさせるとマズいですよね。なので、IP制限をするケースなどもあるかと思います。
ただ、Cloud SQLにはローカルIPを付与してCloud RunからそのIPへ向けてアクセスすることも可能です。
設定方法については、

[Cloud Run（フルマネージド）から Cloud SQL に接続する](https://cloud.google.com/sql/docs/mysql/connect-run)

を参考にすると良いと思います。
ここで重要担ってくるのが、[サーバーレス VPC アクセスの構成](https://cloud.google.com/vpc/docs/configure-serverless-vpc-access?hl=ja)です。このサービスは下記のような構成を実現します。(画像は公式ページから引用)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651593/198d5bba-61ab-eac7-2564-9ba44c75d16d.png)

非常にわかりやすい図解ですね。中心にある「サーバレスVPCアクセスコネクタ」を使うことで、Cloud SQLをはじめとするGCPのリソースをグローバルに晒すことなくセキュアに使えます。

## セッションはMemory Store(Redis)を使う
サーバレスでログインなどのセッションを使う場合は必須のサービスですね。これをやらないと、コンテナが変わるたびにセッションも無効になるので、ログイン状態が度々無効になってしまいます。。。

こちらも[Cloud Run（フルマネージド）サービスから Redis インスタンスへの接続](https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-cloud-run?hl=ja)として公式に情報があります。

Laravelはセッションに`memcached`や`redis` を使う機能が標準で備わっているのでそれを利用しましょう。`config`を変更するだけなので非常に簡単に対応できます。

[HTTP Session(英語)](https://laravel.com/docs/7.x/session)
[HTTPセッション(日本語)](https://readouble.com/laravel/7.x/ja/session.html)

## ログは標準出力にする

コンテナ×サーバレスなので、当然の事ながらコンテナ内に`laravel.log`などを作ったとしても意味はありません。ログを追えるようにするためには、ログの出力方法をファイルから標準出力に変更する必要があります。弊社の場合には下記のような設定をして、ワーニング以上のログを標準出力するようにしています。

```php
'custom' => [
    'driver' => 'monolog',
    'handler' => StreamHandler::class,
    'with' => [
        'stream' => 'php://stdout',
    ],
    'level' => 'warning',
],
```

こうする事でログビューからエラーやログを探すことが簡単になります。

### Cloud Runでみた時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651593/72ec1b2f-2640-3b9d-1503-fa426d2e2e1f.png)

### Logs Viewerでみた時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651593/40f4019a-d368-f7e4-4583-3b43dc371f0f.png)


# 上記の構成を実現する上で最低限、必要になると思われる料金
※あくまで現時点で弊社が考える目安です。

|サービス名|用途| 月額 |
|:--|:--|:--|
| Cloud Run | フロントとバックエンド | [従量課金](https://cloud.google.com/run/pricing?hl=ja) | 
| Memorystore | laravelのセッション保持 | 5,162 | 
| Cloud SQL For MySQL | MySQL | 1,357 | 
| Severless VPC Access Connector | Cloud RUNとMySQLの接続 |  1,480 | 
| Container Registory | デプロイに利用(Cloud Storageに対して課金) | 10 | 0 | 0 |

Cloud Runは無料枠が大きいのも魅力的ですね。(2020/9/7時点 公式サイトより引用)
どちらかということ、固定費用が必要なのは`My SQL`や`Redis`関係のサービス。`サーバレスVPCコネクタ`もかかります。
ちなみに、`サーバレスVPCコネクタ`は`Micro Instance with burstable CPU`として請求が上がるのでこちらも注意が必要です。(最初分からなくてGCPのサポートに問い合わせてしまいました。。。[料金](https://cloud.google.com/vpc/docs/configure-serverless-vpc-access?hl=ja#pricing)に記載はきっちりとあります)

|階層|CPU|メモリ|リクエスト|ネットワーキング|
|:--|:--|:--|:--|:--|
|無料|最初の 180,000 vCPU 秒は無料|最初の 360,000 GiB 秒は無料|200 万リクエストまで無料|北米内の下り（外向き）は、1 GiB まで無料|

# まとめ
インフラに対する意識をほとんどすることなく、ここまでスケーラブルかつ低料金でサービスを開始できる`Cloud Run`は本当に素晴らしい製品だと思います。
デプロイまでの手順も非常にシンプルなので、学習コストも低いことが特徴的ですね。(Developer Experience高い)

ここまでお付き合いいただきまして、ありがとうございました！
yum が使えなくなったとき

yum が使えなくなったとき用にメモで追記していく。



#1. Another app is currently holding the yum lock; #

■エラー内容

```
[root@study ~]#  yum install httpd
読み込んだプラグイン:fastestmirror
ロックファイル /var/run/yum.pid が存在します: PID 1278 として別に実行されています。
Another app is currently holding the yum lock; waiting for it to exit...
 他のアプリケーション: yum
   メモリー:  48 M RSS (588 MB VSZ)
    開始   : Mon Sep  7 09:37:03 2020 - 04:40 秒経過
    状態   : トレース/停止、PID: 1278
Another app is currently holding the yum lock; waiting for it to exit...
 他のアプリケーション: yum
   メモリー:  48 M RSS (588 MB VSZ)
    開始   : Mon Sep  7 09:37:03 2020 - 04:42 秒経過
    状態   : トレース/停止、PID: 1278
Another app is currently holding the yum lock; waiting for it to exit...
```

■対処

```
kill -9 1278

rm -f /var/run/yum.pid

yum clean all
```

【1.】の内容を実行しても、【2.】のエラーが表示されることがある。



#2.Thread died in Berkeley DB library#

■エラー内容

```
[root@study ~]# yum check-update
エラー: rpmdb: BDB0113 Thread/process 1278/140418154268480 failed: BDB1507 Thread died in Berkeley DB library
エラー: db5 エラー (-30973) (dbenv->failchk において): BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery
エラー: Packages インデックスを db5 で開けません -  (-30973)
エラー: /var/lib/rpm にある Package データベースを開けません。
CRITICAL:yum.main:
```

■対処

```
rm -rf /var/lib/rpm/__db.00*

rpm --rebuilddb
```
【Folio LSP】チュートリアルで出てくるCURLオプション


####随時更新

```
curl -w '\n' -D - -X POST -H "Content-type: application/json" -d '{"id":"okapi"}' http://localhost:9130/_/proxy/tenants/diku/modules
```

| オプション |意味|
|:-:|:--|
| -w | 出力フォーマット |
| -D | （-を付けて）標準出力にヘッダーを書き出す |
| -X |　リクエストコマンドの指定 |
| -d |　POSTデータ |
byebugの導入から使い方まで

Railsの勉強の際にデバッグツールは使っていますか？
デバッグツールとは、プログラミングにつきもののデバッグ作業をサポートしてくれるツールのことで、ステップ実行といって一行ごとにプログラムを実行してその時に宣言されている変数の中身をみながら動作を確認する事が出来ます。

それではRailsの開発に使っているbyebugについて紹介していきます。


まずはbyebugのgemをインストールして、デバックしたいコードに「byebug」というメソッドを仕込んでおくと、プログラムがそこを通過した時に止まり、デバッグモードが開始、対話形式でコマンドを打ち込んでおくと自由にメソッドを実行したり変数の値を確認したり出来ます。

# インストール方法
インストールはGemfaileに

```
gem 'byebug'
```

を追記するだけです。 (railsをインストールしている場合はデフォルトでインストールされています)

追記したら

```
bundle install
```

でgemをインストールしてきます。


# byebugの使い方
まずbyebugを開始するには、デバッグをしたいところにbyebugというメソッドを書いて上げます。
(今回の場所は例となります。)

![スクリーンショット 2020-09-03 10.44.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489056/aa14f2c4-1b63-072b-6867-2ac191851a4d.png)


今回はstatic_pages/homeページの部分にbyebugを挿入してみます。




byebugを挟み込んだら、実際にメソッドを叩いてみます。


![スクリーンショット 2020-09-03 10.45.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489056/8e6640bf-2f21-cb70-8b18-8b1c784a748b.png)


このように処理が止まり入力プロンプトが出てきます。
ここでnextを入力してEnterを押すと

![スクリーンショット 2020-09-03 10.46.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489056/a4cb385f-3256-962a-6713-2fa56444c632.png)


次の行に移動しました。ここでhelpメソッドを調べる為に入力してEnterを押すと

![スクリーンショット 2020-09-03 10.48.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489056/73544365-6780-1ad0-de78-22d04eec03c2.png)


helpの中身を確認する事が出来ます。(変数の中身も見れます)
実際のデバッグ作業ではこのように変数の値やメソッドを実行してみて、期待通りの動きをしているかを確認していきます。

# よく使うコマンド一覧

```
next       一行進む
continue   次のブレイクポイントに進む
step       メソッドの内部にステップインする
list       ソースコードを表示する
up         ソースコードの上を表示する
down       ソースコードの下を表示する
```

他にも使ってみたいコマンドがあればhelpを入力すると表示されるので確認してみて下さい♪

ここまで覚えてしまえば、あとは実際に書いてみて慣れるのが一番早いと思います。

# まとめ
byebugの紹介をしましたが、いかがでしたでしょうか？
byebugではそれぞれの変数の型も見れるのでブラックボックス化しがちなプログラミングの細かいところを見れるようになり、開発スピードの高速化と一石二鳥です。

慣れればとても使えるツールだと思うのでぜひ使ってみてください♪


駆け出しエンジニアなので間違っている部分やわかりにくい点などあるかと思います。
その場合はコメントなど入れていただけるとこれからの成長につながりますのでよろしければお願いします。
【LGTM】を押していただけると飛び跳ねて喜びます。
Twitteの方でも呟いたりしておりますのでもしよろしければ遊びにきてください♪
wemosでspiffs

#概要

wemos d1 r1でspiffsやってみた。

#サンプルコード


```
#include <Arduino.h>
#include <FS.h>

void setup() {
	Serial.begin(115200);
	bool res = SPIFFS.begin();
	if (!res) 
	{
		Serial.printf("SPIFFS error \n");
		while (true) {};
	}
	FSInfo fs_info;
	SPIFFS.info(fs_info);
	Serial.println("");
	Serial.println(">SPIFFS info");
	Serial.println("totalBytes: " + String(fs_info.totalBytes));
	Serial.println("usedBytes: " + String(fs_info.usedBytes));
	Serial.println("blockSize: " + String(fs_info.blockSize));
	Serial.println("pageSize: " + String(fs_info.pageSize));
	Serial.println("maxOpenFiles: " + String(fs_info.maxOpenFiles));
	Serial.println("maxPathLength: " + String(fs_info.maxPathLength));
	Serial.println("ok");
	Serial.println(">File list");
	Dir dir = SPIFFS.openDir("/");
	while (dir.next()) 
	{
		String fn, fs;
		fn = dir.fileName();
		fn.remove(0, 1);
		fs = String(dir.fileSize());
		Serial.printf("<%s> size=%s\n", fn.c_str(), fs.c_str());
	}
	Serial.println("ok");
	Serial.println(">File write");
	File fd = SPIFFS.open("/test.txt", "w");
	if (!fd) 
	{
		Serial.println("open error1");
		return;
	}
	fd.println("0123456789 abcdefghi");
	fd.close();
	Serial.println("ok");
	Serial.println(">File read");
	File fd2 = SPIFFS.open("/test.txt", "r");
	if (!fd2) 
	{
		Serial.println("open error2");
		return;
	}
	int len = fd2.available();
	Serial.printf("file size=%d\n", len);
	String str = fd2.readString();
	Serial.println(str);
	fd2.close();
	Serial.println("ok");
	Serial.println(">File write");
	File fileToWrite = SPIFFS.open("/test.txt", "w");
	if (!fileToWrite)
	{
		Serial.println("There was an error opening the file for writing");
		return;
	}
	if (fileToWrite.println("ORIGINAL FILE LINE"))
	{
		Serial.println("File was written");
	} 
	else 
	{
		Serial.println("File write failed");
	}
	fileToWrite.close();
	Serial.println("ok");
	Serial.println(">File append");
	File fileToAppend = SPIFFS.open("/test.txt", "a");
	if (!fileToAppend)
	{
		Serial.println("There was an error opening the file for appending");
		return;
	}
	if (fileToAppend.println("APPENDED FILE LINE"))
	{
		Serial.println("File content was appended");
	} 
	else 
	{
		Serial.println("File append failed");
	}
	fileToAppend.close();
	Serial.println("ok");
	Serial.println(">File read");
	File fileToRead = SPIFFS.open("/test.txt", "r");
	if (!fileToRead)
	{
		Serial.println("Failed to open file for reading");
		return;
	}
	Serial.println("File Content:");
	while (fileToRead.available())
	{
		Serial.write(fileToRead.read());
	}
	fileToRead.close();
	Serial.println("ok");
}
void loop() {
	delay(300);
}





```

#実行結果


```
>SPIFFS info
totalBytes: 957314
usedBytes: 502
blockSize: 8192
pageSize: 256
maxOpenFiles: 5
maxPathLength: 32
ok
>File list
<test.txt> size=40
                  ok
>File write
ok
>File read
file size=22
            0123456789 abcdefghi

ok
>File write
File was written
ok
>File append
File content was appended
ok
>File read
File Content:
ORIGINAL FILE LINE
APPENDED FILE LINE
ok

```

以上。
Ruby始めました

<h1>こんにちは</h1>
<p>今日から主にRubyに関して記事を書いていけたらなあと思います。</p>
<p>普段は検索して記事を見つけて勉強していましたが、メモ代わりに書き出していきたいと思います。</p>

```ruby:ruby.rb
puts "hello Qiita!"
```

うん、見やすい！
初心者がWordファイルを一括でPDFに変換してみる

# 取り組みのきっかけ
仕事柄よくWordを使って書類を作るのですが、
ペーパーレス化の推進、グループウェア導入を経て、
「WordファイルをPDFにして書類を一元管理しよう!!」という上司の一声でスタート。

いくつあるかわからない無数の「.doc」「.docx」との戦いが始まる...
もちろん社内でpython使える人はおらず、それとなくやってみました。

# 実装
```python
import win32com.client
import os
#必要なモジュールをインストールする

wd = win32com.client.Dispatch('Word.Application')
#「Wordを操作する」という宣言

documents_path = 'C:/test/'
word_list = []
#ファイルが保管されているフォルダのパスを設定
#word_file_nameを格納する空のリスト(word_list)を作成

for word_file_name in os.listdir(documents_path):
    if os.path.isfile(os.path.join(documents_path, word_file_name)):
        word_list.append(word_file_name)

for i in range(0,len(word_list)):
  try:
    word_file = wd.Documents.Open(documents_path + '/' + word_list[i])
    base_name, ext = os.path.splitext(word_list[i])
    #base_name, ext　により、extに拡張子が入り、ファイル名がbase_nameに格納される
    word_file.SaveAs2(FileName = documents_path + base_name + '.pdf', FileFormat = 17)
    #ファイル名を指定、フォーマット(17がPDF[https://docs.microsoft.com/ja-JP/office/vba/api/word.wdsaveformat])を設定
  except Exception as e:
    print(e)
    #try以外の例外処理をeに格納、あれば表示する
  finally:
    word_file.Close()

print('complete')
```
色々試行錯誤し、上記のコードとなりました。
初心者故にかなり冗長な作りになっていると思います。

documents_pathは、今回掲載用なので、testとしていますが、
使用する際にはWordファイルが保管されているフォルダのパスを指定します。

#課題
・for文が2回入っており、本来は1つにまとめたかったのですが、
with文の中で、pywin32が上手く動作しなかったので、今後改善策を講じる必要がある。

・pywin32以外のモジュールでも試してみる。

・冗長的な部分をキレイにしてあげる。


# 初めて自作してみて
pythonはもともと興味があり、色々取り組んできていましたが実際になにかを完成させたというのは初めてでした。まだまだ本職の人から見れば下手くそかもしれませんが、まずは些細なものでもコード書いてみて書くことに慣れていきたいです。
社内で自動化を用いて改善できる部分は多々あるので、取り組み結果を備忘録も兼ねてコツコツQiitaに投稿していきます。

改善点やアドバイスいただけたら幸いです！よろしくお願いいたします。
Laravel https環境下でCSSが反映されない

# 目的

- Laravelでオリジナルのcssファイルを作成しビューファイルに反映しようとしても一切されない問題を解決した話をまとめる

# 原因

- Laravelアプリが可動しているWebサーバがHTTPS化されていたためcssファイルの読み込み方法が異なるため読み込まれなかった。

# 原因と解決方法

- 下記の様に`asset()`で記載するとhttps環境下だとCSSファイルを読み込むことができない。

    ```html
    <link rel="stylesheet" href="{{ asset('アプリ名ディレクトリ/publicディレクトリからCSSファイルまでのパス') }}">
    ```
- 下記の様に`secure_asset()`を用いることによりhttps環境下でもセキュアを保ったままCSSを読み込むことができる。

    ```html
    <link rel="stylesheet" href="{{ secure_asset('アプリ名ディレクトリ/publicディレクトリからCSSファイルまでのパス') }}">
    <!-- 少しだけ具体的に記載する -->
    <link rel="stylesheet" href="{{ secure_asset('/css/CSSファイル名') }}">
    ```

# 参考文献

- [https://qiita.com/sakuraya/items/411dbc2e1e633928340e](https://qiita.com/sakuraya/items/411dbc2e1e633928340e)
指定したEC2インスタンスのEIPを開放するスクリプ

時代遅れだけど。

```
cat <<EOD | xargs aws ec2 describe-instances --instance-ids \
| jq '.Reservations[].Instances[] | select(has("PublicIpAddress")) | .PublicIpAddress' -r \
| tee \
>(xargs -I{} aws ec2 disassociate-address --public-ip {}) \
>(xargs -I{} aws ec2 describe-addresses --filter Name=public-ip,Values={} | jq '.Addresses[].AllocationId' -r | xargs -I{} aws ec2 release-address --allocation-id {})
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
i-xxxxxxxxxxxxxxxxx
(好きなだけ改行区切りでどうぞ)
EOD
```
GitHubで簡単にタスク管理をするテクニック

**issues**で残タスクなどを把握するよりかは
**Github Projects**でissue管理と進捗管理をしようという、記事です。

簡単にこんな感じになります。

![スクリーンショット 2020-09-06 22.16.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/7d889b26-8123-65cb-8633-de7c895c12f6.png)


## Github Projects
カンバン方式のタスク管理ツール。
Project上でissueを作成したり、既存のissueを追加したりと優れもの。
マイルストーンも設定できる。


## Github Projectsの運用
`Column` は

- Pending
- Todo
- InProgress
- Done

で分けてます。

プリセットも設定でき、
issueが作成されたら自動的にTODOカラムに追加されたり、
PRがマージされたらDoneに自動で移動したり、など諸々自由に
設定できます。

![スクリーンショット 2020-09-06 22.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/d35bb0f6-c3d0-e403-510e-4362dce0f03a.png)

## フィボナッチ数列を使った工数管理

![スクリーンショット 2020-08-25 0.29.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/6cc344ce-e108-ac11-4e43-fce1937c18d7.png)

上記のようなラベルを用意し、各チケットに対し、作業の重みをラベリングしていきます。
ラベリング後、トータルのラベルを計算すれば工数がざっくりとわかります。
例: 2+3+5+8+13=33 => **6.5日弱**


## まとめ
・無料 
・全体のイシューを俯瞰できるのでMTGの際、課題を整理しやすい。 
**・朝会などのMTGでProjectsを見ながらだと、話を進めやすい。**
・フィボナッチ数で暫定的でのあるが残りの作業工数がわかる。 
・Githubでコードレビュー、プロジェクト管理ができるのでまとまる。 
・TrelloやZiraを使わなくても必要な機能の揃っている。
・とはいえフィボナッチ数列は感覚的な決めてることが多いので、個人開発とかなら有効。

## 参考
・[作業効率がグンと上がる!“カンバン方式”を採用しているツール5選 |ferret](https://ferret-plus.com/10551)

・[フィボナッチ工数見積は「完成させます！（徹夜で）」という無理ゲーによる弊害を最小化するプロジェクトマネージメント手法 - ベルリンのITスタートアップで働くソフトウェアエンジニアのブログ](https://www.jabba.cloud/20170613054635/)