OmniAICreator/Qiita-1.07M huggingface dataset:
愛知県の新型コロナ発生事例のPDFをCSVに変換

2020年と2021年でPDFが分かれているので暫定対応

```python
import datetime
import pathlib
import re
from urllib.parse import urljoin

import pandas as pd
import pdfplumber
import requests
from bs4 import BeautifulSoup


def fetch_file(url, dir="."):

    r = requests.get(url)
    r.raise_for_status()

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p


def days2date(s):

    y = s["年"]

    days = re.findall("[0-9]{1,2}", s["発表日"])

    if len(days) == 2:
        m, d = map(int, days)
        return pd.Timestamp(year=y, month=m, day=d)
    else:
        return pd.NaT


def wareki2date(s):

    m = re.search("(昭和|平成|令和)([ 0-9元]{1,2})年(\d{1,2})月(\d{1,2})日", s)

    if m:

        year, month, day = [1 if i == "元" else int(i.strip()) for i in m.group(2, 3, 4)]

        if m.group(1) == "昭和":
            year += 1925
        elif m.group(1) == "平成":
            year += 1988
        elif m.group(1) == "令和":
            year += 2018

        return datetime.date(year, month, day)

    else:
        return dt_now.date


url = "https://www.pref.aichi.jp/site/covid19-aichi/"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}

JST = datetime.timezone(datetime.timedelta(hours=+9), "JST")
dt_now = datetime.datetime.now(JST)

r = requests.get(url, headers=headers)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

dfs = []
dt_text = ""

for i, tag in enumerate(
    soup.find("span", text="▶ 愛知県内の発生事例").parent.find_all(
        "a", href=re.compile(".pdf$")
    )[::-1]
):

    link = urljoin(url, tag.get("href"))

    path_pdf = fetch_file(link)

    with pdfplumber.open(path_pdf) as pdf:

        for page in pdf.pages:

            if page.page_number == 1:

                text = page.within_bbox((0, 70, page.width, 90)).extract_text()

            table = page.extract_table()

            df_tmp = pd.DataFrame(table[1:], columns=table[0])

            df_tmp["年"] = 2020 + i

            dfs.append(df_tmp)

df = pd.concat(dfs).set_index("No")

df.dropna(subset=["発表日"], inplace=True)

df["発表日"] = df.apply(days2date, axis=1)

# 年代と性別を分割
df_ages = df["年代・性別"].str.extract("(.+)(男性|女性)").rename(columns={0: "年代", 1: "性別"})

df = df.join(df_ages)


dt_update = wareki2date(dt_text)

path_csv = pathlib.Path(dt_update.strftime("%Y%m%d") + ".csv")

df.to_csv(path_csv, encoding="utf_8_sig")
```
【簡単すぎる】Laravel+Vueで星評価機能を実装してみた

# 背景
* Laravelで星評価機能を実装する必要があった
* Vueの既存ライブラリ「vue-star-rating」を活用すると楽に実装出来そうだったので、やってみた

# やり方
### ターミナルで以下をそれぞれ実行
```
npm install vue
npm install vue-star-rating
```

### jsファイルに追記
```javascript:resources/js/app.js
import StarRating from 'vue-star-rating'
Vue.component('star-rating', StarRating);
const app = new Vue({
    el: '#star',
    data: {
        rating: 0
    }
});
```

### ターミナルで以下を実行
```terminal
npm run dev
```
→これで、```<star-rating>```タグを利用可能になります。

### ブレードで星表示
```html
<div id="star">
　<star-rating v-model="rating"></star-rating>
</div>
```
→これで星が表示されるはずです。

星のサイズなどの調整は以下を参考にすればできると思います。

###参考
https://github.com/craigh411/vue-star-rating
https://jsfiddle.net/craig_h_411/992o7cq5/
https://www.kabanoki.net/4632/
『エンジニアの知的生産術』第二章　やる気を出すには　を読んでのメモ

##はじめに
「エンジニアの知的生産術」という本を読んだので、一章ずつ印象に残った部分を投稿していきたいと思います。
今回は第二章　やるきを出すにはです。
『エンジニアの知的生産術　西尾泰和』[Amazonリンク](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93-%E2%94%80%E2%94%80%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B3%E3%80%81%E6%95%B4%E7%90%86%E3%81%97%E3%80%81%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88%E3%81%99%E3%82%8B-WEB-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774198765)

[第一章のリンク](https://qiita.com/sioiriomame/items/82afa0985b6ca926a81b)

##この章のメモ（マインドマップ？字が汚くてごめんなさい）
![IMG_6908.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661656/2b95554e-dad4-2f2c-6bed-2e10704328f5.jpeg)
![IMG_6906.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661656/87d14aa1-01f3-a624-c23f-5d72e1835813.jpeg)

##印象に残ったこと
###まずは全体像の把握
やる気を出すためにはやるべきタスクを一つに絞る。一つに絞るには、まずは全体像の把握が必要。
まずは必要かどうかはさておき気にかかっていることを集めるフェーズ　→　行動を起こす必要があるか、次に何をするべきかを考えるフェーズの二段構えで進める方式がある（GTD)。

###集めたタスクをどれからやるか
部屋の掃除と同じで、まずは基地を作る（一部の掃除に集中して達成感を得る）ことがおすすめ。つまり、今日やることリストを作成してそれを達成する。このリストはきちんと終わらせることができるように、無理があるものは消したり納期や仕様を変える。

###優先順位付けについて
評価軸が複数あり、それらがトレードオフになる場合優先順位付けは難易度を増す。あらかじめ軸の優先順位をつけておくことも有効。（トレードオフスライダーと呼ばれる。xはyの2倍重要というように決めておく）
また、不確定要素がある場合の優先順位付けでは、「不確かな時は楽観的に」という法則がある。楽観的な勘違いには修正チャンスがあるが、悲観的勘違いには修正チャンスがないため。

###やるべきタスクを一つに絞ったのにやる気が出ないとき
タスクが大きすぎる場合がある。そういうときはタイムボックスで目標を区切る（３０分だけやる等）ことが有効。
ポモドーロは有効な手段。

##メモ
・ポモドーロは２５分作業、５分休憩というのは知っており、やったこともありますが

- タスクの大きさをあらかじめ何ポモドーロかで見積もる、
- １ポモドーロの間はタスクは変更しない、
- 割り込みがあった場合は記録する、
- １ポモドーロ終わったら数歩歩くなど視点を変える

という本書で紹介されているルールを適用して行うとより効果がありそうに感じました。

・今回は数日前に読んでマインドマップでメモした章について書いているのですが、マインドマップが結構話の流れをたどりやすいと感じました。これからの読書メモの定番にするかもしれません。
OpenCV  「画像の保存」

##概要
今更ですが、画像の保存の方法をこの記事に載せるのを忘れていました。
基本的ではありますが、保存できないと意味ないですからね。

##Mark6 画像の保存方法


```
#include <opencv2/opencv.hpp>
#include<iostream>

#if _DEBUG
#pragma comment(lib,"opencv_world411d.lib")
#else
#pragma comment(lib,"opencv_world411.lib")
#endif

using namespace cv;
using namespace std;

int main(void) {
	Mat img = imread("C:\\opencv\\sources\\samples\\data\\lena.jpg");

	imshow("img", img);

	imwrite("C:\\abc\\img.jpg", img);

	waitKey(0);

}

```
このような形で保存されます。
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843242/aa543630-38cb-f322-d432-2d80466b10d2.png)


######解説①
ここでの大事なところはここです。

```
imwrite("C:\\abc\\img.jpg", img);
```
imwriteの関数でフォルダに保存します。

```
imwrite("フォルダまでのパス\\名前.拡張子", 入力変数);
```

######解説②
.jpgや.pngや.BMPのように拡張子を変えればいろいろ変えれるのでいろいろしてみてください。
######解説③
ちなみにｃ++言語だけなのかな？パスを入力するときは￥だけでなく￥￥としないといけないから面倒くさいね。


##最後に
次回は連続した画像の読み込みと連続で書き出す記事を書きます。よろしく！！
railsの基本理念を僕なりに解釈

##はじめに
脱初心者にむけてアウトプットをしていこうと思って記事を書いております。
間違ったことがありましたら、ぜひコメントいただけると幸いです。

##Railsとは何か
railsはRubyのフレームワークです。
フレームワークとはアプリケーション開発やシステム開発を楽に行えるように必要な機能を予め用意してあるプログラムの雛形のこと。

##Railsには基本理念がある
この基本理念を遵守することでこのフレームワークの能力を最大限に生かすことができる。
つまりこの基本理念を守ってプログラムを書こうということです！

##DRY
DRYとはDon't Repeat Yourselfの略で、同じ情報を繰り返し定義しない、という考え方です。メリっどとしてコードの量を減らすことで、可読性が向上することや、アプリケーション自体の動作が早くなるというメリットがある

####例えば
```
class EventsController < ApplicationController

  def index
    @events = Event.all
  end

  def new
    @event = Event.new
  end

  def show
    @event = Event.find(params[:id])
  end

  def create
    Event.create(event_params)
    redirect_to events_path notice:"作成しました"
  end

  def destroy
    @event = Event.find(params[:id])
    @event.destroy
    redirect_to events_path, notice:"削除しました"
  end

  def edit
    @event = Event.find(params[:id])
  end

  def update
    @event = Event.find(params[:id])
    if @event.update(event_params)
      redirect_to events_path, notice: "編集しました"
    else
      render 'edit'
    end
  end

  private

  def event_params
    params.require(:event).permit(:title, :start_time, :content)
  end

end
```
このような記述があったとして、繰り返し記述してる部分は
@event = Event.find(params[:id])　　です。

#####これを構文をDRYの理念に遵守すると
```
class EventsController < ApplicationController
  before_action :set_event, only: [:edit, :show, :update, :destroy]
  def index
    @events = Event.all
  end

  def new
    @event = Event.new
  end

  def show
  end

  def create
    Event.create(event_params)
    redirect_to events_path notice:"作成しました"
  end

  def destroy
    @event.destroy
    redirect_to events_path, notice:"削除しました"
  end

  def edit
  end

  def update
    if @event.update(event_params)
      redirect_to events_path, notice: "編集しました"
    else
      render 'edit'
    end
  end

  private

  def set_event
    @event = Event.find(params[:id])
  end

  def event_params
    params.require(:event).permit(:title, :start_time, :content)
  end

end
```
このようにコードが少なくなり可読性を向上させることができます。
(わかりずらかったら申し訳ないです。)
この場合before_actionというそれぞれのアクションが実行される前に処理を行うことでそれぞれのアクションの記述量を減らして結果的に可読性も上がるということで、いいことしかないのです。


##CoC
CoCとはConvention Over Configurationの略で、設定よりも規約を優先するという考え方です。
Railsを使ったことがある方ならわかるかと思いますが、コマンドだけでファイルを生成してくれたりrailsが勝手に処理を用意してくれたりなど、『全て設定よりも規約を優先』することにより開発スピードが上がったり結果的に質も担保してくれるなど、いいことしかないのです。
####例えば
```
規約を無視しているコード
class TestsController < ApplicationController
 def render_top_page
  render template: "tests/index"
 end
end
```

```
規約にそったコード
class TestsController < ApplicationController
 def index
 end
end
```

このように記述量も減り可読性が上がり、結果的に開発スピードをあげることになるのです。

##まとめ

私は初心者なのですが、この基本理念を忘れて強引にコードを書いたりしてしまい、エラーが起きてしまうことが多々ありました。
なので、今回は初心に戻るという意味で、基本理念を記事にしてみました。

ここまで読んでいただきありがとうございます。
UE4でIOS/Android用のアイコン画像を爆速で入れる

#UE4でIOS/Android用アイコンを爆速で入れよう


>https://qiita.com/Chi__no_/items/f7d9f8e943d0da0b5f80
この記事は↑の画像作成スクリプトを実行している事が前提です。

UE4は一つ一つの画像を選択する度にプロジェクトルートから辿らないと行けないから面倒くさい。。。
そんな問題を一気に解決しちゃおうって話！


一番上の記事の内容を実行するとこんな画像ファイル達が出来ると思う。
![スクリーンショット 2020-11-22 220132.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500172/326b7275-6811-4cf4-3ab9-692752875ff2.png)

#Engineのデフォルトに設定する。

そしたらEngineのPathに行く。
<font color="Red">
Androidでは色々ファイルが分かれているから各自でやって欲しい。
参考Directory→C:\Program Files\UnrealEngine\UE_4.25\Engine\Build\Android\Java\res
</font>

>###IOSの場合:Engine\Build\IOS\Resources\Graphics

僕の場合は↓のPath
C:\Program Files\UnrealEngine\UE_4.25\Engine\Build\IOS\Resources\Graphics
↑のPathに行ったらとりあえずBackUpフォルダを作ってUE4のデフォルト画像をBackUpの中にコピーしておこう
![スクリーンショット 2020-11-22 221051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500172/46de8a61-0a4d-22bd-cd1f-8b4fea6a1be1.png)

そのフォルダに前記事で作った大量の画像データを全部コピーしてやる。
![スクリーンショット 2020-11-22 221353.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500172/e58615e6-0918-f2f6-16bd-3e3c089013e2.png)

そうしたらUE4を再起動するだけ！
もし他の画像に変更しているなら全ての画像をデフォルトにリセット→再起動で画像が変わる。

#メリットと欠点

####メリット
何より早い。面倒くさい作業がほぼないから楽
画像を変えたい時もスピーディーに対応できる。

####欠点
再起動したタイミングで毎回フォルダから更新するため、複数のプロジェクトを同時進行して居る時、ビルド毎に画像を差し替える必要がある。


#最後に
エラー、不具合等あれば報告して下さい！
色々雑でしたがqiita初心者なので多めに見てやって下さい。

中学生の時に起業し、今高校三年生で色々なプロダクトをリリースしています！一回だけでも見ていって下さい！
https://geekline.biz ←会社のページ
Agribus NAVI WEBに保存されているデータをQGISで解析する

###Agribus NAVI WEB
https://agri-info-design.com/agribus-web/
Agribus NAVIを年間購読すると使える、クラウドサービスの一つ。

###ダウンロード
![スクリーンショット 2020-11-22 21.42.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/7a9fb10f-fb62-8937-10d0-660cbab4cb63.png)

zipファイルを解凍するとUUIDっぽいファイル名のデータが出てきますが、どこがどこの圃場かわかりませんよね。
そんなときは、Agribus WEBの作業履歴を開いたときのURLを元に探します。

![スクリーンショット 2020-11-22 21.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/50ba78ae-75dc-9fea-9a92-64980d667294.png)

このURLの場合だと、こんな感じでファイルを見つけられます。

![スクリーンショット 2020-11-22 21.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/b9dd49cf-438d-2171-0ded-0e3ac969a4c9.png)

###下処理
エクセル(16.43)でファイルを開くと自動でセル分割してくれるたので、ファイル→名前を付けて保存→ファイル形式→CSV（コンマ区切り）で保存します。

###QGIS
新規プロジェクトを作成。

レイヤ→レイヤの追加→CSVテキストレイヤの追加
破棄するヘッダー:64
X属性：UtmX
Y属性:UtmY
Z属性：Z

![スクリーンショット 2020-11-22 22.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/ef746220-90a1-00b0-d1c2-3093a86e0c81.png)
を設定します。

「ジオメトリのCRS」については、当方は北海道の道央圏なのでUTM zone 54Nを選んでいますが、東京以南ぐらいになると53とかそれ以下のものを選んだほうがいいと思われます。

####ベクタレイヤーの保存
読み込んだCSVファイルレイヤは、そのままだとうまく使えないので、とりあえず扱える形式で保存します。
レイヤーの窓に先程読み込んだファイルがあるので、右クリック→エクスポート→地物の保存
ファイル名はわかり易い名前に変更したほうがいいです。
![スクリーンショット 2020-11-22 22.23.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/0d191858-b612-519e-868b-25da642c92a0.png)

ここで保存したレイヤーが、あれこれ弄るのに使う原型データになります。

####高さをカラー表示する
先程エクスポートしたレイヤがQGISの左下にあるので右クリック→プロバティ
![スクリーンショット 2020-11-22 22.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/a23e0f31-12e3-eaf0-1515-77f0909d1db0.png)

値：Z
カラーランプ：Spectral
分離ボタンを押すと、自動で色分け作ってくれます。→OKボタン

![スクリーンショット 2020-11-22 22.32.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/4df6789a-6051-e8df-f605-7cfd505b7087.png)
pythonコメントアウト

・行単位のコメントは、#に続けて記述

```php
# Hello, world!を表示
print "Hello, world!"
```

・複数行にまたがるコメントアウト
'''(シングルクォーテーション3つ）あるいは"""（ダブルクォーテーション3つ）で囲まれた部分が
コメントアウトされる

```php
'''
この行はコメントです。
この行もコメントです。
'''
```
codesignがキーチェーン に含まれるキー"private key"を使用して署名しようとしています - keychainのパスワード入力ダイアログを出さないようにするには

### 経緯

開発において、Macをgitlab runnerとしてgitlab CI/CDを走らせている。その際、CIがMacの木ーチェーン内の証明書にアクセスしようとする。すると、掲題のようなダイアログが出て、keychainのパスワード入力を求めてくることがある。入力すれば先に進めるのだが、いちいち手で入力しないとCIが止まってしまうため非常に困っていた。

### 対策

`codesign`というプログラムがkeychainにアクセスしようとしているのであるから、`codesign`はパスワードなしでkeychain内の証明書にアクセスできるようにする。

keychain内部の証明書一覧を見て、証明書アイコンの左の三角形のボタンをクリックする。
すると子要素である鍵アイコンが出現する。鍵アイコンを右クリックし、その証明書の詳細情報を閲覧する。

ダイアログが出てくるので、アクセスコントロールから、パスワードなしでその証明書にアクセスできるプログラムを手動で追加する。今回はcodesignである。codesignはmac標準のプログラムであるから通常/usr/bin内部にあるはずだが、わからなければコマンドラインで`which codesign`を打ち込み、codesignの場所を調べておこう。

この手順を全証明書に対して行えば、上記ダイアログは出てこなくなる。
"safari"を保存するキーチェーン"login"が見つかりません - keychainを作り直すには

### 経緯

CIからMacのKeychain access にアクセスする際、「"safari"を保存するキーチェーン"login"が見つかりません」というダイアログが必ず出てしまうようになった。ダイアログには「デフォルトに戻す」というボタンがあり、これを押すとキーチェーンをリセットするという事のようだった。キャンセルをすればCIの処理は先に進むものの、いちいちダイアログを手で消さなくてはならなくなった。

### 原因

何らかの理由で、keychain accessのデフォルトのデータベースである「ログインキーチェーン」が壊れてしまったものと思われる。

### 対策

まず、キーチェーン以外のものが少し前の状態に巻き戻ってもいいなら、macのバックアップ機能であるタイムマシーンを利用して、壊れる前に戻せばいいだろう。

それができない場合は、手動でログインキーチェーン を消して作り直す。

ただ、内部に入っていた証明書が全部消えてしまうため、まず証明書を書き出して保存しておく。

「自分の証明書」欄の証明書をcommand + Aで全選択し、右クリックでエクスポートを選ぶ。ファイル書き出し形式が.p12になっていることを確認し、任意の場所に書き出す。そうすると、全証明書が一つに纏まった最強のp12ファイルが出来上がる。

これを別のmacに移し、ダブルクリックすると、証明書の内容がそちらのキーチェーン に全てコピーできることをあらかじめ確認しておいた方がいいだろう。

証明書のバックアップが済んだら、上記「デフォルトに戻す」ボタンを使って、ログインキーチェーンをリセットする。

その後、保存しておいたp12ファイルをダブルクリックし、証明書を復活させる。

### 参考文献

[Appleコミュニティ - キーチェーンが見つかりません](https://discussionsjapan.apple.com/thread/10055713)
[木ーチェーンアクセス ユーザーズガイド - Macのキーチェーンアクセスでキーチェーンを削除する](https://support.apple.com/ja-jp/guide/keychain-access/kyca2423/mac)
ボタンクリックにより、同じIDの別のカラムのフィールドを出力する

前提: DBが作成されデータが入っている状態

例えば、こんな感じのデータベースを用意して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863480/583ac575-202b-af09-cfe2-fdc3ca448463.png)

キャラ名の隣のボタンをクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863480/2e9e6485-6958-473b-b8fd-0accb25d00b9.png)

そのキャラのタイプが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863480/6406f2ef-c99e-8ae8-e08c-90fcf0270327.png)

（↓動画にするとこんな感じ）
https://gyazo.com/8e68421fe20af2d6b68093ba0108cc9f

みたいな実装をしたい場合は、以下のように書く。

```php:index.php
// DB接続に必要な記述
$con = mysqli_connect('127.0.0.1', 'root', '');
$result = mysqli_select_db($con, 'データベース名');
$result = mysqli_query($con, 'SET NAMES utf8');
$result = mysqli_query($con, 'SELECT * FROM テーブル名');

while ($data = mysqli_fetch_array($result)) {
  print '<form method="post" action="next.php">';
  // next.phpに「id」というnameの「$data['ID']」というvalueが送られる
  print '<input type="hidden" name="id" value="'.$data['ID'].'">';
  // $data['']の中に表示させたいDBのカラム名を記載する
  print '<input type="hidden">' . $data['NAME'] ;
  print '<input type="submit" value="何の呼吸？">';
  print '</form>';
}
```

```php:next.php
try
{
  // $_POST['']の中には、qiita_index.phpから受け取るname属性の値が入れる
  $kimetsu_id=$_POST['id'];

  // DBへ接続
  $dsn = 'mysql:dbname=yurutto;host=localhost;charset=utf8';
  $user='root';
  $password='';
  $dbh = new PDO($dsn, $user, $password);
  $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

  $sql = 'SELECT TYPE FROM kimetsu WHERE ID = ?';
  $stmt = $dbh->prepare($sql);
  $data[]=$kimetsu_id;
  $stmt->execute($data);

  $rec = $stmt->fetch(PDO::FETCH_ASSOC);
  $kokyu_type=$rec['TYPE'];

  $dbh = null;

  //  同じIDのTYPEカラムのフィールドを出力する
  // （= submitボタンで選択したキャラのタイプが出力する）
  print $kokyu_type;

}
catch (Exception $e)
{
  print 'ただいま障害により大変ご迷惑をお掛けしております。';
  exit();
}
```
nginxにオレオレ証明書をセットする

## 認証局用の秘密鍵を作成
```
openssl genrsa -aes256 2048 > server.key
```

## 証明書要求ファイルを作成
- CNのみ`*.vamdemicsystem.com`のように指定する
- あとはどうでもいい

```
openssl req -new -key server.key > server.csr
```

## CSRを認証局へ送って証明書を発行してもらう
```
openssl x509 -in server.csr -days 36500 -req -signkey server.key > server.crt
```

## 起動時のパスワード入力無効化設定
```
openssl rsa -in server.key -out server.key.nopass
cp -p server.crt /etc/httpd/conf/
cp -p server.key.nopass /etc/httpd/conf
```

## nginxのディレクトリにセット
```
cp -p server.key.nopass /etc/nginx/server.crt
cp -p server.key /etc/nginx/server.key
```

## nginx起動

```
systemctl restart nginx
systemctl status nginx
```
電卓app 〜％計算〜


 
# はじめに
　最近は便利なものでYoutubeで探せばアプリ開発を１〜１０まで動画で説明してくれる動画が見つかります。

全くSwiftを触ったことがない状態で電卓アプリを１から作成したときに立ちはだかった壁についてご紹介します。

今回は壁の中でも％計算方法について書きたいと思います。

# 壁その１
　まず立ちはだかったのはどこを探しても％計算のコードが見当たらない！！！

私がやってほしかった計算は、**１０００円のものの３０％引きはいくら？**と計算してくれる％計算。

検索してもしてもこうやってね、が出てこずに途方に暮れていました。。。

コードはどこか探せばあって全てコピペするものだ、という勘違いをしていたこともいけませんでした。

# ％計算ってどうやるの？？

１０００円の商品が１０％引きになってました。さて、いくらになるでしょう、が％の問題です。

１０００ー（１０００円の１０％オフ）＝支払い金額

ということは、１０００円の１０％オフという計算を覚えさせれば良いということだ！！と分かりました。

# %計算のコード
かくかくしかじか、コードに当してみると、

```
　　　　　　　case "%":
                let huga:Double = Double(firstNumber) ?? 0
                let huga1:Double = Double(secondNumber) ?? 0
                let hoge:Double = 100
                secondNumber = String(huga * huga1 / hoge)

```

こんな感じに書いたら％の計算をしてくれる様になりました。

とりあえず今回は計算方法のみ、に焦点をしぼってみました。

#最後に
プログラミングは理解すれば楽しいけど、理解するまでが時間かかりますね。。
精進あるのみだと再度確認できました！
is_arrayについて

##is_arrayとは
`is_array()` = `()の中の引数が変数か配列か判定する関数。`
               変数が配列の場合「true」、配列ではない場合「false」が返される。

```

$number = array( 1,2,3,4);  //array()で配列を作成

if(is_array($number) ){
  print '$numberは配列です。';  //true時の処理
} else{
  print '$numberは配列ではありません。'; //false時の処理
}

↓ //出力結果

$numberは配列です。
```

参考元はこちら
(https://www.php.net/manual/ja/function.is-array.php)
(https://php-beginner.com/function/var/is_array.html)
GitHub Container Registry(ghcr.io)のPrivateイメージをKubernetesで使う

# はじめに

GitHub Container RegirstryにPrivateで配置したコンテナイメージをKubernetesで使う方法を紹介する．

# 結論

imagePullSecretsを利用する．

[プライベートレジストリを使用する方法 - イメージ | Kubernetes](https://kubernetes.io/ja/docs/concepts/containers/images/#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%AC%E3%82%B8%E3%82%B9%E3%83%88%E3%83%AA%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

# 方法

## (1) imagePullSecretsの登録

プライベートイメージをPullするときに使うシークレット(imagePullSecrets)を登録する．

今回は以下のリンク先にある既存Docker用設定ファイルを流用する方法を使った．

GitHub Container Registryのセットアップ方法は[過去の記事](https://qiita.com/tomoyk/items/1caaa03bc5d78cc26fc1)にある．

[Pull an Image from a Private Registry | Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials)

```json:~/.docker/config.json
{
        "auths": {
                "https://index.docker.io/v1/": {
                        "auth": "xxxxxxxxxxxxxxxxx"
                },
                "ghcr.io": {
                        "auth": "xxxxxxxxxxxxxxxxx"
                }
        }
}
```

手元のマシンで以下のコマンドを実行してYAMLを生成した．

```bash
kubectl create secret generic regcred \
    --from-file=.dockerconfigjson=~/.docker/config.json \
    --type=kubernetes.io/dockerconfigjson --dry-run=client -o yaml
```

コマンドの実行結果

```yaml:ghcr.yaml
apiVersion: v1
data:
  .dockerconfigjson: XXX
kind: Secret
metadata:
  creationTimestamp: null
  name: regcred
type: kubernetes.io/dockerconfigjson
```

YAMLの中身をリモートにコピーしてデプロイする．

```bash
kubectl apply -f ghcr.yaml
``` 

## (2) imagePullSecretsをDeploymentに追記

以下を参考にDeploymentに imagePullSecrets を記述する．

```dep.yaml
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      imagePullSecrets:
        - name: regcred
# 略
```

kubectlコマンドでデプロイする．

```bash
kubectl apply -f dep.yaml
```

# おわりに

プライベートレジストリも慣れれば簡単にPullできるので，この機会に利用していきたい．
File uploading with CKEditor on Laravel-Admin


## Install CKEditor on Laravel-admin

At first, install CKEditor on laravel-admin follow the steps below.
https://github.com/laravel-admin-extensions/ckeditor


## Adding file upload function on CKEditor


```php:config/admin.php

...
        'ckeditor' => [
            'enable' => true,
            'config' => [
                'filebrowserImageUploadUrl' => '/admin/fileupload', // Add here
            ]   
        ]   
...

```

Another options [here](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html).


```php:app/Admin/routes.php

use Illuminate\Routing\Router;
 
Admin::routes();
 
Route::group([
    'prefix'        => config('admin.route.prefix'),
    'namespace'     => config('admin.route.namespace'),
    'middleware'    => config('admin.route.middleware'),
    'as'            => config('admin.route.prefix') . '.',
], function (Router $router) {
 
    $router->get('/', 'HomeController@index')->name('home');
    $router->post('/fileupload', 'FileuploadController@index'); // Add here
    ... 
});

```

```php:app/Http/Middleware/VerifyCsrfToken.php

<?php
 
namespace App\Http\Middleware;
 
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
 
class VerifyCsrfToken extends Middleware
{
    /** 
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [ 
        '/admin/fileupload', // Add here
    ];  
}

```

```php:app/Admin/Controllers/FileuploadController.php

<?php
 
namespace App\Admin\Controllers;
 
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
 
class FileUploadController extends Controller
{
 
    public function index(Request $request)
    {   
        $image     = $request->file('upload');
        $name      = substr(str_shuffle('1234567890abcdefghijklmnopqrstuvwxyz'), 0, 12);
        $extension = $image->getClientOriginalExtension();
        $newname   = $name . '.' . $extension;

        // you can change third variable as filesystem you want.
        $image->storeAs([ANY_DIRECTORY_YOUWANT], $newname, 'public');
        $url = [YOUR_PUBLIC_PATH] .$newname; 
 
        $param = [ 
            'uploaded' => 1,
            'fileName' => $newname,
            'url'      => $url
        ];  
 
        return response()->json($param, 200); 
    }   
}

```
寿司職人への道～元寿司屋アルバイトの寿司打記録～

初めまして、プログラミング初学者のえんどこです。

ITエンジニアになる為に情報収集していた所、「初歩的な事でも良いので継続的なアウトプットが大切」といった内容の記事を見掛けたので文章作成の練習も兼ねてこの記事を書いています。


1. 目的・理由
・現状のタイピング速度が非常に遅く、転職後の業務に支障が出ると感じた為。
・タイピング速度が速い人間はシンプルに格好良いと感じた為。


2. 現状
・現在の寿司打記録
![スクリーンショット 2020-11-22 205236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618977/33502e0c-8c8d-9a89-2841-51a23cacbcff.png)
中々に悲惨...

3. 目標　
・高級コースで10,000分寿司を食べる。

4. 期間
・11/23~12/23までの1ヶ月間

5. 計画
・1週目～ ブラインドタッチの練習
・2週目～ 誤字、ミスタッチの削減
・3週目～ 普通コースでの目標達成
・4週目～ 正確重視コースでの目標達成


以上となります。
毎週途中経過を報告しますので温かく見守っていただけると幸いです。

また、文章の誤字脱字、表現におかしな点等あればご指摘ください。
Rubyで絶対値を返したい時はabsメソッド

ruby 2.7.0の記事です

- abs 絶対値を返す<br><a href="https://docs.ruby-lang.org/ja/latest/method/Integer/i/abs.html"> Integerクラスabs</a>

```ruby
-12345.abs   # => 12345
12345.abs    # => 12345
```
Rubyの入力と出力メソッド

ruby 2.7.0についての記事です。
# Rubyの入力メソッドのまとめ
1.gets 
getsメソッドを使って入力した値は全て文字列になる
<a href="https://docs.ruby-lang.org/ja/latest/method/IO/i/gets.html">公式ドキュメント(IOクラスgets)</a>

【関連するメソッド】

- chomp　文字列末尾の改行を取り除く <br>
<a href="https://docs.ruby-lang.org/ja/latest/method/String/i/chomp.html">公式ドキュメント(stringクラスchomp)</a>
- split　 先頭と末尾の空白を除いたうえで、空白文字列で分割する <br>
<a href="https://docs.ruby-lang.org/ja/latest/method/String/i/split.html">公式ドキュメント(stringクラスsplit)</a>
- to_i　文字列を整数（integer）に変換する。小数に使うと整数に変換する<br>
<a href="https://docs.ruby-lang.org/ja/latest/method/String/i/to_i.html">公式ドキュメント(stringクラスto_i)</a>
- to_s　文字列（string）に変換する<br>
<a href="https://docs.ruby-lang.org/ja/latest/method/String/i/to_s.html">公式ドキュメント(stringクラスto_s)</a>

```ruby
num = gets.split # "10 100"と入力します
print num #=> ["10", "100"]
print num[0] #=> 10
print num[1] #=> 100

answer = num[0].to_i * num[1].to_i # 整数に変換します
print answer #=> 1000

```

# Rubyの出力メソッドのまとめ

- puts 末尾に改行が入る形で出力する<br><a href="https://docs.ruby-lang.org/ja/latest/class/Kernel.html#M_PUTS">公式ドキュメント（Kernelモジュールputs）</a> 
- print 改行を入れずに値を出力する<br><a href="https://docs.ruby-lang.org/ja/latest/method/Kernel/m/print.html">公式ドキュメント（Kernelモジュールprint）</a> 

```ruby
num = gets.split # "10 100"と入力します
puts num #=>
10
100
puts num[0] #=> 10
puts num[1] #=> 100

answer = num[0].to_i * num[1].to_i # 整数に変換します
puts answer #=> 1000

puts "hello"
puts "world" #=>
hello
world

print "hello"
print "world"
#=> helloworld

```
【Vue.js】v-bindを基礎から学ぶ

Vue.jsを学んでいる中で、ディレクティブでも重要なv-bindについて言語化するために、シンプルかつ分かりやすさを心掛けて記事化しました。

# v-bindとは？
まず、頭に「v-」が付くと、これはVue.jsが用意しているディレクティブ・特別な属性であることを示しています。v-text,v-modelなどディレクティブには色々と種類がありますが、ここではv-bindについて学びます。v-bindにより要素の属性をバインディング、つまり縛ることができます。

# いつ・どのように使うのか？
ではこのv-bindをいつ使うのか、例を挙げますと以下のようにHTMLの内部で{{ }}(マスタッシュ構文)を使用した場合、

```ruby:誤
<div id="app">
 <a href="{{ url }}">Google></a>
</div>

<script>
new Vue ({
  el: '#app',
  data: {
  　url: 'https://google.com',
  }
})
</script>
```

このように書くとGoogleを押下しても{{ url }}というリンク先に飛ばされてしまい、意図していない結果になってしまいます。

ここではマスタッシュ構文ではなく、Vueが用意しているv-bindを使うことにより正しくリンク先を表示させることができます。

```ruby:正
<div id="app">
 <a v-bind：href="url">Google></a>
</div>

<script>
new Vue ({
  el: '#app',
  data: {
  　url: 'https://google.com',
  }
})
</script>
```

以下のような省略形でも表記可能です。私は慣れていないのでv-bind表記を使用します。

```ruby:省略形
<a :href="url">Google></a>
```

v-bind時には{{ }}(マスタッシュ構文)ではなく、単に""内にurlを入れるということに気をつけてください。

# まとめ
このように、v-bindというディレクティブを利用することで、JSにより動的に変化させることができる、というものでした。
ディレクティブには、v-on,v-model,v-if,v-forなど様々ありますので、随時まとめていきます。
【Python】Beautiful SoupでWeb上の画像を一括で保存する方法

## はじめに
ここではWebスクレイピングで『Web上の画像を一括で保存する方法』について紹介します。

:warning: 注意 :warning:
著作権で保護されている場合や著作権的にはOKだが利用規約でスクレイピングを禁止している場合、損害賠償請求などの可能性があるのでしっかり著作権法や利用規約を理解した上でWebスクレイピングを行いましょう。


## 目次
1. [Webスクレイピングを行う方法](#1-Webスクレイピングを行う方法)
1. [実際に画像を保存してみる](#2-実際に画像を保存してみる)
1. [抽出の流れ](#3-抽出の流れ)
1. [まとめ](#4-まとめ)
1. [おまけ](#5-おまけ)
1. [参考](#6-参考)

## 1. Webスクレイピングを行う方法
Webスクレイピングを行うためには「Ruby」や「PHP」、「Javascript」など様々な言語で可能ですが、今回はPythonの『Beautiful Soup』を用いた方法を紹介します。 

## 2. 実際に画像を保存してみる
① pipでbeautifulsoup4をインストールする

```
pip install beautifulsoup4
```
② Webスクレイピングを行うサイトを決める
※今回は『いらすとや』の画像をダウンロードしていきます。
https://www.irasutoya.com/search/label/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9

③ 一覧ページから各画像リンクページURLを取得する

```python
url = "https://www.irasutoya.com/search/label/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9"
# 画像ページのURLを格納するリストを用意
link_list = []
response = urllib.request.urlopen(url)
soup = BeautifulSoup(response, "html.parser")
# 画像リンクのタグをすべて取得
image_list = soup.select('div.boxmeta.clearfix > h2 > a')
# 画像リンクを1つずつ取り出す
for image_link in image_list:
    link_url = image_link.attrs['href']
    link_list.append(link_url)
```

④ 画像ファイルのタグをすべて取得する

```python
for page_url in link_list:
    page_html = urllib.request.urlopen(page_url)
    page_soup = BeautifulSoup(page_html, "html.parser")
    # 画像ファイルのタグをすべて取得
    img_list = page_soup.select('div.separator > a > img')
```

⑤ imgタグを1つずつ取り出し、画像ファイルのURLを取得する

```python
for img in img_list:
    # 画像ファイルのURLを取得
    img_url = (img.attrs['src'])
    file_name = re.search(".*/(.*png|.*jpg)$", img_url)
    save_path = output_folder.joinpath(file_name.group(1))
```

⑥ 画像ファイルのURLからデータをダウンロード

```python
try:
   # 画像ファイルのURLからデータを取得
   image = requests.get(img_url)
   # 保存先のファイルパスにデータを保存
   open(save_path, 'wb').write(image.content)
   # 保存したファイル名を表示
   print(save_path)
except ValueError:
   print("ValueError!")
```
手順としては以上です。

↓　↓　実行結果　↓　↓ 
![result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/860879/8be7696e-6ede-ec20-ec9a-b809d4676f46.png)

## 3. 抽出の流れ
手順③～⑤が少しイメージしづらいと思ったので、大まかな抽出の流れを作成してみました。
![process.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/860879/fc0116e6-0d97-56a6-03a9-7fe9abacb6b6.png)

また、今回のソースはGithubにも掲載してありますので、下記からご参照ください。
https://github.com/miyazakikna/SaveLocalImageWebScraping.git

## 4. まとめ
ここではPythonのBeatiful Soupを使って画像を一括で保存する方法について解説しました。
今回はいらすとやの画像を取得しましたが、他のサイトでも基本的に同じ要領で画像がダウンロードできるかと思いますので、是非活用してみてください。

## 5. おまけ
画像ダウンロード後、ファイル名を一括で変更する方法はこちら↓↓
[【仕事効率化】Pythonでファイル名を一括変更する方法]
(https://qiita.com/miyazakikna/items/b9c6d6d83ebcd529afd7)

## 6. 参考
・[Pythonで画像スクレイピングをしよう](https://qiita.com/neet-AI/items/98d4194872ee4f53e3b4)
・[webスクレイピングで画像収集](https://qiita.com/kataege/items/9af0a68e8ae3e0faa7d0)
firebaseのCloud Functionsがnode8でも10でも使えない

nuxtのSSRを試していたらnodeのバージョンが新しい(node10以降)とデプロイに失敗する件

以下の記事を参考にfirebaseにアプリケーションをデプロイしようとしたら以下のエラーがでました

https://note.com/hagure_melon/n/n2065f5e4c736

```
Error: HTTP Error: 400, Billing account for project '<プロジェクトID>' is not found. Billing must be enabled for activation of service(s) 'cloudbuild.googleapis.com,containerregistry.googleapis.com' to proceed.
```

とりあえず、cloud functionsのpackage.jsonのnodeの指定を8にすることでエラーは回避できる。

```
  "engines": {
    "node": "8"
  },
```

が、プロジェクトをSparkからBlazaにアップグレードするのが正しいらしい。
（手軽に試したいだけなのに...とは思いつつも無料枠で収まると言われているので従うのみ）

そもそもnode8は2021/2/15までしか使えない、node10以降はSparkでは使えないとありました

#### 参考

- https://stackoverflow.com/questions/63932639/400-billing-account-for-project-is-not-found-billing-must-be-enabled-for-activa
- https://qiita.com/azukiazusa/items/edd6ca9cba2d48c4c3e2
- https://www.lancard.com/blog/2020/06/25/firebase-cloud-functions-node10-upgrade/
欠損値のあるデータの文字列を数値に変換する

欠損値などの数値に変換できないデータが混じっているときはastype()で文字列から数値に変換することが出来ないため、to_numericを使用します。

```python
data['col1'] = pd.to_numeric(data['col1'], errors='coerce')
```
errorsに'coerce'を設定することで文字列から数値に変換することのできないデータをNaNとして扱います。
【Outlook】カレンダーのショートカットキーまとめ【Google】

##どうしてこんなに違うのよ。

仕事ではOutlookカレンダー、個人的にはGoogleカレンダーを使っているが、
ショートカットキーがけっこう違うのでまとめてみた。
これで脱マウスを進めて生産性アップにつながれば。

| 【予定系】 | Outlookカレンダー | Googleカレンダー |
|:-:|:-:|:-:|
| **予定の作成** | N | C |
| **予定の作成(簡易版)** | なし | QまたはShift+C |
| **予定の保存**  | Ctrl+S  | Ctrl+S |
| **予定の検索**  | Alt+Q  | /  |
| **予定を開く・編集**  | Enter  | E  |
| **【移動系】** | **Outlookカレンダー** | **Googleカレンダー** |
| **今日へ移動**  | HomeまたはShift+Alt+Y  | T  |
| **前の期間に移動**  | Shift+←  | PまたはK  |
| **後の期間に移動**  | Shift+→  | NまたはJ  |
| **指定した日に移動**  | なし  | G  |
| **【ビュー変更系】** | **Outlookカレンダー** | **Googleカレンダー** |
| **日ビュー**  | Shift+Alt+1  | 1またはD  |
| **稼働日ビュー**  | Shift+Alt+2  | なし  |
| **週ビュー**  | Shift+Alt+3  | 2またはW  |
| **月ビュー**  | Shift+Alt+4  | 3またはM  |
| **カスタムビュー**  | なし | 4またはX  |
| **予定一覧を月間ビューで開く**  | Shift+Alt+5 | なし |
| **スケジュールビュー**  | なし | 5またはA  |
| **年ビュー**  | なし | 6またはY  |
| **【その他】** | **Outlookカレンダー** | **Googleカレンダー** |
| **ヘルプを表示** | ？ | ？またはCtrl+/ |
| **設定を表示**  | なし | S  |
子プロセスを含めたkill 


#概要
子プロセスを含め、killをするためのツールです。python用です。
（pythonのプロセスで縛りを掛けています。）
検証はlinuxのみしてあります。

使い方は、
そのまま実行すると、子プロセスを持つ親プロセスの一覧が表示されるので、
（例としてproc_01.py proc_02.pyの子プロセスを持つプログラムが実行中とします。）


```
$ python terminate_children_process.py

python 関連の子プロセスを持つprocess一覧
コマンドラインにPIDを指定すると、子プロセスを含めてterminate します。
{'pid': 26727, 'cmdline': ['python', 'proc_01.py']}
{'pid': 26747, 'cmdline': ['python', 'proc_02.py']}
```
 

終了させたいpidを指定し再び実行します。 

```
$ python terminate_children_process.py 26747

terminate 子プロセス　26849
terminate 子プロセス　26850
terminate 子プロセス　26851
terminate  親プロセス　26747
```




#ソース(terminate_children_process.py)
```
#terminate_children_process.py
import sys
import psutil

if len(sys.argv)==1:
    #python 関連の子プロセスを持つprocessの表示
    print("python 関連の子プロセスを持つprocess一覧")
    print("コマンドラインにPIDを指定すると、子プロセスを含めてterminate します。")
        
    PROCNAME = "python"
    for proc in psutil.process_iter([ "pid"  ,  'cmdline'  ]):
        if proc.name()[:len(PROCNAME)] == PROCNAME:
            p = psutil.Process(proc.pid)
            if len(p.children()) >0:
                print(proc.info)
    
else:
    #指定したPIDとその子プロセスを含めてterminate
    
    target_pid=int(sys.argv[1])
    p = psutil.Process(target_pid)
    
    #子のterminate
    pid_list=[pc.pid for pc in p.children(recursive=True)] 
    for pid in pid_list:
        psutil.Process(pid).terminate ()
        print("terminate 子プロセス　{}" .format(pid))
    
    #親のterminate
    p.terminate ()
    print("terminate  親プロセス　{}" .format(target_pid))

```
# 参考
[psutil documentation](https://psutil.readthedocs.io/en/latest/#)
エクセル勤怠、VBAで土・日を〇で囲う作業を自動化させた

過去に使っていた勤務表作成の中でめんどくさい作業があったので
VBAを作り、一部作業を自動化しました。今は別の勤務管理システム
へと移行したので現在は使ってはいないのですが、過去の産物として
NETに公開しようと思います。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276575/189c41af-759a-b522-e191-535a498bb145.png)

このようにエクセル上に直接手入力で出勤時間と退勤時間を入力します。

毎月の曜日が土、日である場合丸を付けないといけないのですが、毎月日付と曜日が違い
一個一個ずらすのが煩わしかったのでマクロを作り、自動化しました。

以下がそのコードです。

```
Sub donichi()
Dim n As Long
n = 10
For i = 9 To 39
    If Cells(i, n) = "土" Then
        With Cells(i, n)
            With ActiveSheet.Shapes.AddShape(msoShapeOval, .Left, .Top, 18, .Height)
            .Fill.Visible = False
            .Line.ForeColor.RGB = RGB(0, 0, 0)
            .Line.Weight = 1
            End With
        End With
    End If
    If Cells(i, n) = "日" Then
        With Cells(i, n)
            With ActiveSheet.Shapes.AddShape(msoShapeOval, .Left, .Top, 18, .Height)
            .Fill.Visible = False
            .Line.ForeColor.RGB = RGB(0, 0, 0)
            .Line.Weight = 1
            End With
          End With
    End If
Next
End Sub
```



これを実行するとこうなります。↓

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276575/2b754988-298c-4129-09d2-73132fc9ad04.png)



何かのお役に立てれば幸いです。
ラズパイのセットアップ

## 概要
* ラズパイ4Bを使って初期設定とRasbianのインストールをしていきます。

## 使うもの
* [TRASKIT Raspberry Pi 4 Model B Starter Kit](https://www.amazon.co.jp/dp/B08BFZ7PXS)
    *  ラズパイ4B本体と備品のキット
    * SDカードにOSがインストール済みのため細かい準備がほとんど不要（買ってから知った）

## あると便利なもの（なくてもよいがあると楽）
* モニター（HDMI）
* USBマウス
* USBキーボード

## 手順
* 箱を開けると **取扱説明書** が入っている。
* 物理的な接続の方法からデスクトップ画面が表示されるまでの手順が記載してあるためそれに従う！以上！
    * 他のキットだとそのあたりの手順が入っていないものがある。
Ubuntu20.04でansible-playbookのセットアップをする

## インストール

```
sudo apt update -y
sudo apt install -y software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible
```

### バージョン確認

```
ansible-playbook --version
```

### Ansibleを流し込むマシンのauthorized_keysへ登録する

```
ssh-copy-id 128.22.133.120
```

#### 公開鍵を指定する場合
- なんかエラーになった

```
cat ~/.ssh/vamdemickey.pem | ssh ec2-user@18.179.207.62 -i ~/.ssh/vamdemickey.pem "cat >> ./.ssh/authorized_keys"
```

### ansible用のhostsに実行先のIPアドレスを書く
- `/etc/ansible/hosts`

```/etc/ansible/hosts
[servers]
128.22.133.120
```

### 接続確認

```
ansible 128.22.133.120 -m ping
```

```
128.22.133.120 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
```

### playbookを作成
```wget.yml
- hosts: servers
  tasks:
    - name: install the latest version of wget
      yum:
        name: wget
        state: latest
```

### 実行

```
ansible-playbook wget.yaml 
```


```
PLAY [servers] ************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [128.22.133.120]

TASK [install the latest version of wget] *********************************************************************
ok: [128.22.133.120]

PLAY RECAP ****************************************************************************************************
128.22.133.120             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignore
d=0   
```

## 参考
https://qiita.com/s-nishimaki/items/bd396b5ceaa9370d79c7
Node.js バージョン管理nodenvを使ってみる

nodeのバージョン管理についてnというものを使ってみたが、
今回CentOs環境で別のnodenvを使ってみることにしました。

バージョン管理には他にも、
nodebrewがありますが、nodenvだとディレクトリごとにバージョンが変更できるみたいです
※ ついでに、win機はNodistというのがあるみたいです

※こちらの記事は、nodeが入っていることを前提にしてます。もしまだなら、インストールして置くようにしてしてください。またgitも入れておいてください

```
sudo yum install nodejs
sudo yum install npm

sudo yum install git-all　#gitのインストール
```

https://www.deep-rain.com/programming/program/611

## anyenv インストール
「[anyenv](https://github.com/anyenv/anyenv)」というツールを用いてインストールします

```
[vagrant@vagrant ~]$ git clone https://github.com/riywo/anyenv ~/.anyenv
```

パスを通して設定します

```
[vagrant@vagrant ~]$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
[vagrant@vagrant ~]$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
[vagrant@vagrant ~]$ exec $SHELL -l
```
こちらを実行すると以下のようにでました。

```
ANYENV_DEFINITION_ROOT(/home/vagrant/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:
> anyenv install --init
```

指示通り初期をおこないます

```
anyenv install --init
```


## nodenv インストール
anyenvを使用し、nodenvをインストールします

```
anyenv install nodenv
exec $SHELL -l
```

以下のコマンドを実行できたら成功です

```
nodenv
```

## バージョンを切り替え

欲しいnode.jsのバージョンを以下のコマンドでインストールします

```
nodenv install 12.19.0
```

切り替えます

```
nodenv local 12.19.0
```

## バージョン切り替え確認
今までインストールしている切り替え可能なバージョン一覧を確認

```
nodenv versions
```

## インストール可能なバージョン確認
nodeのインストール可能なバージョン確認する

```
nodenv install --list
```

参考URL
https://qiita.com/tonkotsuboy_com/items/5322d226b6783d25b5df
docker-compose.ymlで名前付きvolumeを使う方法

###結論
僕もまだあまり理解できてないのでものすごく乱暴な説明なのですが、
下記のようにdocker-compose.ymlファイルを記述すると名前付きvolumeが使えます。

```docer-compose.yml
version: '3'

services:
    web:
      build: .
      
      ...
      volumes:
          - .:/myapp      
          - gem_data:/usr/local/bundle
          #ここと
      ...
volumes:
  gem_data:
  #ここが大事です。
```

`- gem_data:/usr/local/bundle`
これが名前付きパスです。

上記コードの下部にある、

```yml
volumes:
    gem_data:
```

これが無いと
`ERROR: Named volume "gem_data:/usr/local/bundle" is used in service "gem_data:" but no declaration was found in the volumes section.`
とエラーが出てしまい相対パスや絶対パスを使わないと指定できないみたいです。


相対パスなどを使うよりは、名前付きパスを使う方が基本的にはいいみたいです。

参考

Docker上のMySQLのデータをVolumeでホストのディレクトリにマウントすると権限周りで面倒なことになる 
https://qiita.com/ysd_marrrr/items/e8a50c43cff87951385c
Pythonでのアスタリスク(*)の使われ方(gg = {**ff,'c':3}とか)。たぶん、これで全部？。

#概要
Python（いま自分が使っている3.7）でのアスタリスク(*)の使われ方が、よくわからなかったので調べた。
リファレンスでの説明を確認した。
ポイントは、リファレンスで、どこで説明されているかを示したこと。あと、関数の引数でのアスタリスクは有名だが、引数だけで、極端な使い方の特殊がされているわけでない、ことを示したい（ したい）と感じたため。

引用は、すべて、
https://docs.python.org/ja/3.7/reference/

#結果
##使い方１（乗算演算）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/860d83ea-ade5-9015-af36-2e7637853713.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/bc77ba97-51a0-8f9d-c9ce-9c2c7dbbd534.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/f007fdc5-3e14-4f29-78de-59bfdac1220e.png)

##使い方２（べき乗演算）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/3dce7296-2f28-ed46-6756-5ef6cf5792c1.png)

##使い方３（引数リストのアンパック）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/b4d11202-c450-df49-5875-57620009d6d2.png)

##使い方４（辞書のアンパック）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/a41a35bc-adf9-e08c-1704-26d916460d8a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/940c99ac-e8fe-6ccc-3454-94815e12252d.png)

例↓。これは、あまり使う可能性がない。

```
>>>
>>> ff = {'a':1,'b':2}
>>> gg = {**ff,'c':3}
>>> gg
{'a': 1, 'b': 2, 'c': 3}
>>>

```

##使い方５（イテラブルのアンパック）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/a293d1c3-971c-0ed7-05ae-54067433d939.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/174d4cbc-bfe0-06b5-3565-b08ad875a021.png)

例↓。これは、使うことがあるかも。ただ、この項の例としては適切でない。これは、、、しいていえば、引数系？？

```
>>>
>>> (hh,*ii)=1,2,3,4,5,6
>>> ii
[2, 3, 4, 5, 6]
>>>
```

こちら↓の例が適切だと思う。

```
>>>
>>> ii=[1,2,3]
>>> jj=[100,200,*ii]
>>> jj
[100, 200, 1, 2, 3]
>>> jj=[100,200,ii]
>>> jj
[100, 200, [1, 2, 3]]
>>>

```


#まとめ
特にありません。
コメントなどあれば、お願いします。:candy:
MySQL 5.7(Docker)環境構築メモ

Dockerを用いてMySQL5.7環境を構築し、MySQL Workbenchで接続するまでの手順をまとめる。
※Dockerなどはインストール済みであること。

* フォルダ構成

  ```
  project/
        ├ docker/
        |       └ db/
        |          L data    # マウント場所
        |          ├ my.cnf  # 設定ファイル     
        └ docker-compose.yml  
  ```



**1.`docker-compose.yml`を作成する。**

   ```yaml
   version: '3'
   
   services:
     db:
       image: mysql:5.7
       container_name: mysql_container
       environment:
         MYSQL_ROOT_PASSWORD: rootpass
         MYSQL_DATABASE: sample_db
         MYSQL_USER: mysqluser
         MYSQL_PASSWORD: mysqlpass
       volumes:
       - ./docker/db/data:/var/lib/mysql
       - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
       restart: always
       ports:
       - 3306:3306
   ```

   ※環境設定は自環境に合わせて適宜設定する。

**2.`my.cnf`(MySQL設定ファイル)を作成する。**

   ```cnf
   [mysqld]
   character-set-server=utf8mb4
   collation-server=utf8mb4_unicode_ci
   
   [client]
   default-character-set=utf8mb4
   ```

   ※要件に合わせて適宜設定する。上例は文字コードのみを設定している。

**3.MySQLコンテナを起動する。**

   上記`project`フォルダに移動し、以下のdocker-composeコマンドを実行する。

   ```shell
   docker-compose up -d
   ```

   ※`docker ps`コマンドを実行し、`mysql_container`のステータスが`UP`になっていることを確認する。

**4. MySQL Workbenchからコンテナにアクセスする。**
   ※MySQL Workbenchは[公式](https://www.mysql.com/jp/products/workbench/)よりインストールする。

   1. タブ`Database` -> `Manage Connections...` を選択する。

      以下の`Manage Server Connections`画面が表示される。![mysql_manage_server_connections.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/61177aa0-27e9-8dcb-7420-4c2f17ac5cf8.png)


   2. `New`を押下し、`docker-compose.yml`に記載した接続情報を入力する。

   3. `Test Connection`でコンテナに接続できるかを確認する。
[初心者必見]git log --online とgit log の違い

commitメッセージを確認するときに

```
$ git log
```

を使うと思いますが

コミットメッセージ だけ確認したい時は

```
$ git log --oneline
```

を使うとかなり見やすくなるのでおすすめです！

実際にやると

これが

![スクリーンショット 2020-11-22 19.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674994/fa820313-9722-f59e-f90b-0d5a0fe2432c.png)

こう![スクリーンショット 2020-11-22 19.53.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674994/1aed6ad1-e066-21b9-f022-562a122b08da.png)

です。

"git log"のオプションは他にも便利なものがあるみたいなので気になる方はこちらのページがおすすめです。
https://techacademy.jp/magazine/10200

是非！
NimでSDL2 ① 準備とウィンドウ表示

# はじめに
NimでSDL2を使用する方法を書いていきます。
なるべく機能毎にシンプルにかければ良いなと思ってます。

NimでSDL2と言ったら以下が有名なので、こちらも参考にすると良いすね。
[SDL2を使い、Nimで2Dのプラットフォーム・ゲームを書く](https://postd.cc/writing-a-2d-platform-game-in-nim-with-sdl2/)

# SDL2のインストール
SDL2を使うのでまずはSDL２をインストールする。
Macだとこんな感じ。（他のプラットフォームの方は適宜ググってくださいー）

```sh
# とりあえず色々突っ込んでおく
$ brew install sdl2{,_gfx,_image,_mixer,_net,_ttf}
```

# NimのSDL2ライブラリのインストール
SDL2のラッパー。普通にnimbleでインストール

```sh
$ nimble install sdl2
```

# リファレンス
困ったらここで調べればOK
[SDL 2.0 日本語リファレンスマニュアル](http://sdl2referencejp.osdn.jp/index.html)

# とりあえずウィンドウを表示
```nim
# sdl2をimport、osはsleepを使うので
import sdl2, os

# メイン関数
proc main() =
  # SDL2初期化
  if not sdl2.init(0): # まずはサブシステムなし
    raise Exception.newException("[ERROR] init SDL2: " & $getError())
  # SDL2クリーンアップ処理（deferで関数終了時に実行)
  defer: sdl2.quit()
  # Window作成
  let window = createWindow(title = "SDL2 Window Sample", # Windowのタイトル
                            x = SDL_WINDOWPOS_CENTERED, # Windowの位置(真ん中)
                            y = SDL_WINDOWPOS_CENTERED, # Windowの位置(真ん中)
                            w = 640, # Windowの幅
                            h = 480, # Windowの高さ
                            flags = SDL_WINDOW_SHOWN) # Windowフラグ*1
  # Window作成エラーチェック
  if window.isNil:
    raise Exception.newException("[ERROR] createWindow: " & $getError())
  # Windowsクリーンアップ処理
  defer: window.destroy
  # 終了フラグ
  var done = false
  # メインループ
  while not done: # 終了フラグが立つまで実行
    # イベント格納変数
    var event = defaultEvent
    # 全てのイベントを処理
    while pollEvent(event):
      case event.kind:
      of QuitEvent: # 終了イベントの場合
        done = true # 終了フラグを立てる
      else:
        discard
    # CPUを使い切らないようにちょっと(0.1秒)待つ(とりあえず実装)
    sleep(100)

# メイン関数実行
main()
```

Windowフラグに関しては以下を参照
[SDL_WindowFlags ウィンドウの状態の列挙体](http://sdl2referencejp.osdn.jp/SDL_WindowFlags.html)

## 実行結果
![window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268503/d6852c03-1bee-1247-158c-1d5f4d63f7a9.png)

# 次は？
画像とか表示していきたいですね。

以上〜。
WSL2上でcartographer_rosを動かしてみる

# 何の記事？
WSL2（Windows Subsystem for Linux）上でcartographer_rosのデモプログラムを実行するまでの手順をメモしたものです。

# 何が出来たの？
[cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/demos.html)のページにある「Deutsches Museum」のデータ（2D, 3D）を使ったデモを実行しました。
気になったのがPCへの負荷だったので、タスクマネージャーのパフォーマンスも併せて確認しました。
通常時：
![通常時Prof2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897206/e01e2653-b32c-bd6b-01a1-232c848ffa19.png)
デモ（２Ｄデータ）：メモリは1G増、GPUは17%くらい
![2DProf2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897206/90cf75b8-d998-5df9-1530-269cb4834f63.png)
デモ（３Ｄデータ）：メモリは2G増、GPUは20%くらい
![3DProf2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897206/db4015da-8215-a77a-f9d3-e889422a5138.png)
RVIZをグリグリすると少しメモリ喰われました。（＋2GB）
![3D-RVIZ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897206/00e77add-add9-afc1-8063-fd54392c967a.png)![3DProf_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897206/5d628367-0c0f-8954-8457-37b5597da084.png)

GPUよりもメモリが大事そう？

#### 実行環境
- OS: Windows 10 Home 64bit
- Linux: Ubuntu 18.04 LTS
- プロセッサ: AMD Ryzen 7 3700X 8-Core 3.6GHz
- RAM: 16GB
- GPU: GeForce RTX 2070 SUPER

# 何をしたの？
1. WSLのインストールとWSL2の有効化、Linux(Ubuntu)のインストール
1. WSL2でROSのインストール
1. cartographer_rosのインストール
1. デモプログラムの実行

基本的にはWebで公開されている記事を参考に手順を踏むだけ。
ただ３でちょっと躓いた。

### WSLのインストールとWSL2の有効化
参考先：[Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
手順１～７まで順番に実行する。
手順３の後、しれっと**再起動を要求されてる**ので忘れずに再起動する。
LinuxディストリビューションはUbuntu 18.04 LTSを選択する。

※追加でWSL2のGUI化
参考先：[WSL2+ubuntu20.04: GUI化して使う方](https://qiita.com/atomyah/items/887a5185ec9a8206c7c4)
cartographer_rosのデモプログラムはRVIZで可視化されるので、CUIなWSL2だと厳しい。
なので、簡単にGUI化するためにを参考にリモートデスクトップを採用した。

### WSL2でROSのインストール
参考先：[ロボットプログラミングⅡ：ROS Melodicのインストール](https://demura.net/education/16135.html)
WSL2+ROSということで身構えていたけど、通常のLinuxでインストールするような感覚で問題なかった。
なお、上記参考サイトは[WSL2でGazeboを動かすための手順](https://demura.net/misc/16305.html)の中の1Step。

### cartographer_rosのインストール
参考先：[Compiling Cartographer ROS](https://google-cartographer-ros.readthedocs.io/en/latest/compilation.html)
ここも手順に従ってコマンドを実行していく。個人的に間違い、見落としやすいポイントは次の通り。

- Ubuntu 18.04のROSはMelodicなので、最初にインストールするTool類は**python2系**になる。
- 最後のBuildでcatkin_make_isolatedをするときは、rosの**setup.bash**を実行してから行う。
- Build時に**Ceres**と**Lua**が見つからずにエラーが発生するため、事前にaptでインストールする。

CeresとLuaは[StandAloneなCartographer](https://google-cartographer.readthedocs.io/en/latest/#system-requirements)の要件に含まれているが、ROS統合版での手順では見逃されている模様？
なお、Lua >= 5.2と言われたのでLua5.3をインストールしたところ、LuaのBinaryはあるけど実行できない状態になった。
大人しくLua5.2をインストールしたら解消した。
LuaはCartographerのビルドに使うので、devもインストールしておく。

### デモプログラムの実行
引き続き手順に従ってデモ用のデータのダウンロードと実行。
結果は上記の通り。

# まとめ
WSL2のLinux(Ubuntu18.04LTS)でcartographer_rosを動かしてみました。
実はWSLも初めて触ったけど、かなり簡単にLinuxを動かせることに驚きです。
Computer Vision APIを5分で触る

# Microsoft Cognitive Servicesとは
クラウドベースのサービスで、REST APIとクライアントライブラリSDKが用意されています。システムに「見る」「聞く」「話す」「理解する」「意思決定」など認知機能を加え、AIを実現することができます。

# Computer Vision API
画像やビデオのコンテンツを分析するAIサービスです。
https://azure.microsoft.com/ja-jp/services/cognitive-services/computer-vision/

# 実際に触る
1. Azureにログインして「リソースの作成」
![paint1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/fcc1ca9e-0ca6-092c-d311-edb1ca5889d7.png)

2. 「AI + Machine Learning」を選択し、「Computer Vision」を選択
![paint2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/45a11b3b-3516-6233-bc05-9d8a56cec102.png)

3. インスタンスについての情報を記載
![screencapture-portal-azure-2020-11-22-00_02_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/c2ca1190-640e-05c7-1a53-e810d553b9eb.png)

4. APIにアクセスするためのキーをコピー
![paint4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/a05ab190-64b2-f75b-e0a0-ed8c6aa5946d.png)

5. APIコンソール画面に移動
![paint5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/33d98db5-4744-a600-bfb9-a249e6ee8555.png)

6. 4で指定したリージョンを選択。
![screencapture-westcentralus-dev-cognitive-microsoft-docs-services-computer-vision-v3-ga-operations-56f91f2e778daf14a499f21b-2020-11-22-00_14_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/0e90e3b5-5a82-51a5-898e-f2fa9ae2dedf.png)

7. パラメータを設定する
「visualFeatures」をDescription（画像の説明文）に設定し、Ocp-Apim-Subscription-Keyに、4でコピーしたキーを貼り付ける
JSON形式で、ネット上に公開されている画像を指定する
![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/3245b7d3-fda7-6656-5960-29dcd200d704.png)

8. 結果①
![画像](http://gahag.net/img/201601/27s/gahag-0050118949-1.jpg)
こちらの[画像](http://gahag.net/img/201601/27s/gahag-0050118949-1.jpg)は下記の結果になりました。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/0901da3e-c527-ba87-1801-36a57231ca6d.png)

9. 結果②
![画像](https://farm4.static.flickr.com/3258/3146713862_5bb4597b5b.jpg)
こちらの[画像](https://farm4.static.flickr.com/3258/3146713862_5bb4597b5b.jpg)は下記の結果になりました。
![screencapture-japaneast-dev-cognitive-microsoft-docs-services-computer-vision-v3-ga-operations-56f91f2e778daf14a499f21b-console-2020-11-22-00_20_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132064/b9af9396-060b-c856-318b-5706901c9b1c.png)

# 所感
数分で画像認識を試せる環境が整い、API呼び出しもクライアントが用意されているため、思った以上に簡単です。
AIを触るといっても、とてもハードルが低かったので、いろいろなAPIを試してみたいです。