OmniAICreator/Qiita-1.07M huggingface dataset:
ヘルスチェックがInServiceにならない

#はじめに
CLBにインスタンスをアタッチしたらInServiceにならなかった時の調査アーカイブです。

##ヘルスチェックとは
調べた感じ、CLBからぶらさがってるインスタンスにPingを投げてレスポンスがなかったらOutofServiceになるらしい。
なのでミドルとかApacheとかのコンフィグに異常があるのかな？て心配はしなくてよさげ。

##CLBのパラメータ確認
![スクリーンショット 2020-06-07 20.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/b3002255-fae0-5bea-5683-1bd7b87fc859.png)

25（SMTP）は例があまり多くないのですが、読んだ感じ25ポートが空いてれば良いっぽい。
となるとSGのインバウンドが怪しいのですが、普通に25許可してました。

##ポートがListenか疑う
となるとこれだな！と思ったのは良いが調べ方がわからないw
今回はAmazonLinux2なのですが、こんな感じで設定状況を確認できました。

```
$ netstat -ant
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN
```

25を22と同じように設定してあげればいいんじゃ！
内部のコンフィグ的には全受けで、SGで制御してセキュアにする感じですかね。

##設定変更
AmazonLinux2はデフォでPostfixが入ってます。
知らなかったw

```
$ vi /etc/postfix/main.cf
116 inet_interfaces = all
```

変更後はPostfixを再起動します。

```
$ systemctl restart postfix
$ netstat -ant
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
```

成功！
無事InServiceになりました。

公式のトラブルシューティングがめっちゃわかりやすかったです！
調べ甲斐がありますね。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/ts-elb-healthcheck.html

簡単ですが以上です: )
ＶＲデバイスがなくても、ＶＲを体験する方法


今回はＶＲを疑似体験する方法をご紹介します。　

こちらは　Windows１０ＰＣがあれば　できます。　




# ステップ１　

まず　スタートから設定　そして開発者向けを開いて　

開発者モードにします。

![bandicam 2020-06-07 19-10-08-362.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/2db953c2-afce-d5d4-3bbc-ca1403d2c4ec.jpeg)





# ステップ２　

スタートメニューからMixed Reality ポータルを開きます。
Mixed Realityない場合は　Microsoftストアからダウンロードします。


そしたら画面左下に　［シミュレーションのセットアップ（開発者向け）］と出てくるので　そちらから入ります。　

そうすると　ダウンロードが開始されます。　

【再起動を求められることもあります】




# ステップ３　

ダウンロードできたら　Windows Mixed Realityを開きます。　

開いたら　画面左下のスパナみたいなアイコンを押して　

一番上のヘッドセットのエミュレーションをONにします。 


ＯＮにすると、　マウスやゲームパッドで操作ができるようになります。　

ゲームパッドでやると　操作が楽ですよ。



![bandicam 2020-06-07 19-12-46-746.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/23145c12-4a9a-17b3-b193-7eaf4328e611.jpeg)







# ステップ４

次にMixed Reality ポータル

【ホーム画面】に行きます。

　ホーム画面に行ったら　まず　windowsキーとＶキー　を押します。　

それで　メニューが画面が出てきますので　

【下の画像みたいに　なっていればＯＫ】

そこから　いろんな操作ができます。　

３６０度動画なども見れますし　

SteamVRなどもできます。　


【SteamVRをやるには、steamの方で

Windows Mixed Reality for SteamVRを入れる必要があります】



![bandicam 2020-06-07 19-13-36-253.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/0fae7ae3-4b44-86cd-f2c3-00c52cd27652.jpeg)




ＶＲデバイスがなくても　一通りのことはできるので　

結構便利ですね。
GatsbyJS・microCMS用の画像を扱うnpmモジュールを公開してみた

初めてオープンソースの物を作成したのでいろいろな点が分からない中でリリースまでこぎつけられたのがうれしかったです。

# 何を作ったのか

[@mako-tos/gatsby-transformer-for-microcms](https://www.npmjs.com/package/@mako-tos/gatsby-transformer-for-microcms) を作りました。

gatsby-source-microcms と一緒に使う前提の GatsbyJS プラグインを作りました。
microCMS で設定したコンテンツの中でリッチエディタ(html)のフィールドを指定すると、html 内の img タグを picture タグに変換した html を子 Node に追加します。

# なぜ作ったのか

最近 GatsbyJS を触ってかなりいいなと思ったのでお客様にも利用を提案できるようにしたいと考えました。
しかしお客様に提案するのに海外製の headless CMS を利用すると保守に自信がもてませんでした。
そこで microCMS に注目して色々触っているうちに、何か作りたいと考えました。
そのため、自分でもできそうで公開する意味がありそうなものはないかと考えて他にやっている人がい無そうだったので作りました。

## どう利用するのか

install 方法
yarn ではこうなります。

``` $ yarn add @mako-tos/gatsby-transformer-for-microcms
```

npm の場合はこうなります。

```$ npm install @mako-tos/gatsby-transformer-for-microcms
```

## 設定方法

### 設定例

```gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-source-microcms',
      options: {
        apiKey: process.env.MICRO_CMS_API_KEY,
        serviceId: process.env.MICRO_CMS_SERVICE_ID,
        endpoint: 'blog',
      },
    },
    {
      resolve: '@mako-tos/gatsby-transformer-for-microcms',
      options: {
        mediaType: 'MicrocmsBlog', // 必須 string 型
        field: 'body', // 必須 string 型
        useHljs: true, // 任意 boolean 型
        image: {
          sizes: '80vw', // 任意 string 型
          loading: 'auto', // 任意 string 型
        },
      },
    },
  ],
};
```

gatsby-source-microcms より後に @mako-tos/gatsby-transformer-for-microcms を設定してください。

### パラメータについて

- mediaType には graphQL 上で MicrocmsXxx と表示されるテーブル名を設定してください
- field には html が入力されている MicrocmsXxx のテーブルを設定してください

残りのパラメータは任意入力です。

- useHljs は highlight.js を使ってコードにシンタックスハイライトを行いたい場合は `true` にしてください。デフォルト値は `false` です
- image.sizes は img タグの sizes 属性にそのまま渡されます。デフォルト値は `'(max-width: 800px) 80vw, 800px'` です
- image.loading は img タグの loading 属性にそのまま渡されます。デフォルト値は `'lazy'` です

ここまで読んでいただきありがとうございます。
もし興味を持っていただけたら試して頂けると嬉しいです。
宜しくお願い致します。
Anaconda環境で「The environment is inconsistent...」の警告が出た時の対処方法

# conda と pip

Pythonを使い始めてからずっとAnacondaを使っていますが、最初の頃は **conda** と **pip** の違いをあまり意識せず使っていました。

今でこそ両者は「混ぜるな危険」なものと知っておりますが、これまで新しいパッケージをインストールする時は、たまたまググったページで紹介されている方を使っておりました。

その結果、conda と pip のごちゃ混ぜ状態。というか、ほとんど pip install でした（汗）

# conda のアップデート時に警告を受ける…

そんな中、最近 conda のアップデートを試みる機会があったのですが、その時にこんな警告メッセージが出ているのに気づきました。

```
 Collecting package metadata (repodata.json): done
 Solving environment: | 
 The environment is inconsistent, please check the package plan carefully
 The following packages are causing the inconsistency:

   - defaults/osx-64::smart_open==1.5.7=py36_0
   - https://repo.continuum.io/pkgs/main/osx-64/widgetsnbextension-3.1.0-py36_0.tar.bz2/osx-64::widgetsnbextension==3.1.0=py36_0
   - https://repo.continuum.io/pkgs/main/osx-64/datashape-0.5.4-py36hfb22df8_0.tar.bz2/osx-64::datashape==0.5.4=py36hfb22df8_0
   - defaults/osx-64::s3transfer==0.1.13=py36_0
   - https://repo.continuum.io/pkgs/main/osx-64/dask-0.16.1-py36_0.tar.bz2/osx-64::dask==0.16.1=py36_0
 ...
 （以下ダラダラとたくさん）
```

conda と pip を気にせず混ぜ混ぜ使用してしまった結果でしょうか。有毒ガスが出て再起不能になってないのは幸運だったかもしれませんが、"inconsistent" とか言われると、ただの１ユーザーでしかない私としてはとっても気になってしまいます。
（一応アップデート自体は警告を無視して出来そうではありましたが。）

# 私が対処した方法

とりあえずググる、ということで警告メッセージをそのまま検索窓へ。それで見つけたのが、stack overflow の 「[The environment is inconsistent, please check the package plan carefully](https://stackoverflow.com/questions/55527354/the-environment-is-inconsistent-please-check-the-package-plan-carefully)」 です。

ここによると、単純に以下をするだけで警告メッセージが出なくなる、とのこと。

``` 
conda install anaconda
```

試してみると、確かに警告メッセージは出なくなりました。

さてこれで何の不具合もなく解決したのかはよくわかりませんが、今のところ問題なく使えています。同じ症状で悩んでいる方、この方法を試す場合は、念のためバックアップを取った上で行ってみて下さい。
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～HTML第2-4回～

# アジェンダ
* HTMLのタグ
    * abbr
    * cite
    * address
    * br
* HTMLの属性
    * title
* 実践

# HTMLのタグ
## abbr
その文書が略称であることを示すタグ。
後ほど記載するtitle属性を用いると、原語を合わせて示すことができる。

## cite
その文書が特記すべき(固有名詞など?)ものであることを示すタグ。

## address
その文書が住所であることを示すタグ。

## br
改行を示すタグ。記載した箇所で文書が改行される。
\</br>は使用しない。

(何の紹介もなく、動画内でしれっと使われていた)


# HTMLの属性
## title
略称の原語を示す属性。値には言語を記載する。

# 実践
上記のタグ・属性を用いて、以下のindex.htmlを作成した。

```html:index.html
<!DOCTYPE html>

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Lorem Ipsum</title>
  </head>
  <body>
    <h1>Lorem Ipsum</h1>
    <p>
      私が好きな読み物は<cite>Lorem Ipsum</cite>である。<br>
      多くの人に<abbr title="Lorem Ipsum">Lipsom</abbr>と呼ばれ親しまれている。
    </p>
    <p>
      興味がある方はこちらまで。<br>
      <address>大阪府東京市福岡町北海道番</address>
    </p>
  </body>
</html>
```

これをWebブラウザに表示させるとこんな感じ。
![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/23948150-6d69-8335-30cb-401911ea3dec.png)

\<cite>タグを使用した箇所は斜体になっている。

潰れていて見づらいが、\<abbr>タグを使用した箇所には下線が引かれている。
また、カーソルを合わせるとtitle属性に記載した原文が表示された。
![abbr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/7fce5c53-4cad-bf00-eae6-6a1644ebefd4.png)

\<address>タグを使用した箇所はブロック要素として区別されている。

# おわりに
今回は特殊な文書の表現に関する内容だった。
HTMLのタグは、文書の種別(?)を区別するために使用するものが多く、見た目の変化は重要ではない、と感じた。

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/40127694bfc3a9dce341)

## 参考
[2-4 略語・名前の特記・住所表現（HTMLのテキスト）](https://www.youtube.com/watch?v=HMdEGGSpjUA&list=PLjw-30bsJNVU87F5iCPAW9kB4QDUGQxUG&index=8)
Rails環境構築　mac

#Rails環境構築　
バージョン
macOS 10.15.5
ruby  2.5.8
rails 5.2.4


##概要
Railsの環境構築をする度にググっても、情報が多過ぎるので迷ってしまいました。

今回はtechpitさんの記事に沿って環境構築をしました。
参考記事
https://www.techpit.jp/courses/ruby-on-rails/lectures/9644688



途中で
`Gem::FilePermissionError`でエラーになった場合は
先頭に`sudo`を付けて、再度実行する。
参考記事
https://qiita.com/NAKKA-K/items/6b5de9459b3c952f5b2e

`therubyracer`でエラーに場合は
`
$ brew install v8-315
$ bundle config --local build.libv8 --with-system-v8
$ bundle config --local build.therubyracer --with-v8-dir=$(brew --prefix v8-315)
`を実行する
参考記事
https://qiita.com/shimx/items/32e85093f21e673c7127

`ActiveRecord::NoDatabaseError (FATAL:  role "root" does not exist):`でエラーになった場合は
database.ymlを開いて、development:の部分に
`
username: 登録した名前（ターミナルの行の先頭名前）
assword: <%= ENV['BIG-TWEET_DATABASE_PASSWORD'] %>
`を追加して、再度エラーになったコマンドを実行する
参考記事
https://qiita.com/NAKKA-K/items/6b5de9459b3c952f5b2e
高卒業務系システムエンジニアが、Courseraで学ぶ機械学習（1-2週目）

# 高卒業務系システムエンジニアが、Courseraで機械学習を学ぶ（1-2週目）
前回:[高卒業務系システムエンジニアが、Courseraで学ぶ機械学習（0週目）](https://qiita.com/ginzi44338489/items/aaf4cc1b1de6c65313db)
## イントロダクションとしての１周目
まず、僕が受けた機械学習コースは、**動画とクイズと実習形式のコーディング**で構成されています。
そして、**１周目**は実習形式のコーディングはなく、**動画とクイズだけ**です。

また、内容も機械学習の大雑把な全体像を捉えることに集中しており、とてもスムーズに進めることができました。

`そんなこんなで、「余裕、余裕」と僕は油断していました。`

## 炎上と２週目

それは、ある日突然のこと。
本業の方で、リリースされたモジュールに、不具合が見つかった。
そんな報告が入りました。

これの復旧作業で、この週は基本的に１１時帰宅です。

![alt](https://4.bp.blogspot.com/-KYM-XTBoyGs/Wj4IcCneKEI/AAAAAAABJLY/ow1IVnww3EYZKPANHp0YzdU4oRK-gF3iACLcBGAs/s800/figure_shouka.png)

当然、平日は作業を進めることなどできません。（毎日英会話５０分勉強してたのもあって）

幸い、休日出勤はなかったので、休日にコースを進めよう。
そう考えてました。

###土曜

土曜日は多めに寝て、午前歯医者に行っていたのもあり、学習を開始したのは、夕方。

一気に動画をみて、クイズを答える。
**残り実習課題のみ。**
お腹が空いたこともあり、自己満足してその日は終了。
英会話の勉強もして、眠たくなり、風呂に入ってグッナイ。

###日曜日

疲れが残っていたのか、この日も多めの睡眠。
最近運動不足であることを思い出し、`公園を散歩。`

僕は、`買い物や水回りの掃除`など、定期的に行っていることを終える。
そして、疲れて`お昼寝`。

いつの間にか夕方に。
`軽くストレッチをして、英会話を25分、先にはさみ軽食を取る。`

そんな優雅なことをしていたら、外は暗く。

いざ、実習へ。

となったが、**実習内容が結構重い。**

というか、コーセラ内で使っている、インタープリターのpythonコード練習サイトみたいなものの使い方を少し覚える必要もある。

そして、Pythonのnumpyを別に日常的に使っているわけではない僕は、その各メソッドも知る必要がある。（コース内で、　レクチャーはあります）

そして、Tの右上表記をT乗だと勘違いして、時間を食ったり。

などなど、そして極めつけは機械学習の変数の動的決定(勾配降下法)がweb上で遅い...
そして結果出て期待値と違ってたり。`(正解率70以上でクリアなのに100目指してました。疲れてのかも）`

**色々いじったり、お風呂をはさみながら、深夜を迎えること、小一時間。
ようやくクリア！**

そして、僕は思いました。

`納期はやっぱり、最速守るべきなんだなって...`(１周目に早く終わらせて、２周目を進めることもできた）

果たして、無事終えることができるのか！（ネタバレ：３周目はすでに終わっている。）

#### **次回に続く！**
windows home wsl2 及び docker , docker-composeインストール

#1.WSLを有効にする
######WSLはデフォルトで無効になっています。コマンドラインからPowerShellを管理者権限で実行して、下記のコマンドを入力します。

```
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```
#####下記のように表示されます。

```
PS C:\> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Path          :
Online        : True
RestartNeeded : False
```



#####検索エリアに「windowsの機能」を入力し、検索する「windowsの機能の有効化また無効化」をクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218041/65b3f82a-b0c3-d1f0-278f-96c8f93770bd.png)



#####「Windows Subsystem for Linux」にチェックを入れて「OK」をクリックします。
#####windowsのバージョンにより、Windows Subsystem for Linuxの表示が違ったりする,僕の方は「linux用Windowsサブシステム」になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218041/60cf1c10-0b35-2c73-3bfd-5fe13b5c1769.png)



#####WSLの有効化が終了したら再起動を要求されるので再起動します。以上で準備完了です。


#2.ディストリビューションのインストール
####Microsoft Storeにアクセスして、「Ubuntu」を検索する
下記のバージョンはどれでも使えるはずです、今回はUbuntuを選択して、インストールします。
「Ubuntu」を選択した後、「入手」ボタンをクリックすると自動的にインストールされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218041/06151984-aae7-9253-6bec-24b65d5e5b13.png)


####初起動時の設定
インストールしたら、下記のアイコンできているはず、それをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218041/34794ab1-424e-78e2-9b57-38ed49a669eb.png)

システムのユーザ名、パスワードを設定する、ここは画像を取り忘れていた。

```
new UNIX username [username]
new UNIX userpassword [password]
```

####パッケージのアップデート
```
$ sudo apt update
$ sudo apt upgrade
```
#WSL 2 に更新する

[Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#update-to-wsl-2)
を参照してください。
※注意点
　1．バージョン 2004、ビルド 19041 以上に更新された Windows 10 を実行している。
　2. 上記の条件に未達成してない場合、[ Windows 更新アシスタント]ダウンタウンして、インストールしてください。

####WSL2を更新する際、エラーが発生した場合、下記のURLを参照してください。
[やさしいWSL2のインストール手順とエラー](https://qiita.com/kekenonono/items/14b725ce3d00cd5281ec)

####補足
```
PS>wsl --set-version IMAGE_NAME 2
ディスク システムの制限により、要求された操作を完了できませんでした。仮想ハード ディスク ファイルの圧縮と暗号化が解除されて
いる必要があります。また、仮想ハード ディスク ファイルをスパースに設定することはできません。
```
下記のフォルダを内容の圧縮を解除する

```
PS>cd C:\Users\USER_NAME\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
```
[右クリック] → [プロパティ]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218041/5fce7d9f-15d6-d770-b2e5-b7b37cd426e4.png)

再度下記のコマンドを実行すれば、wsl2に切り替えるはず。
[IMAGE_NAME]は今回Ubuntuになります。

```
PS>wsl --set-version IMAGE_NAME 2
```

#3.WSL 2 + Docker
下記のURLを参照してください
[Windows 10 Home で WSL 2 + Docker を使う](https://qiita.com/KoKeCross/items/a6365af2594a102a817b)
以上
環境構築最新版@Mac

#Macの環境構築

####最近何度目かのMacの環境構築をしたので忘備録

#####入れたモノのリスト
- homebrew
- docker desktop
- VScode
    - 拡張機能
        - Iceberg
        - Python
        - Docker
        - Github, Git History

今のところこれが自分の中でのmin。
VScodeに出会ったときの興奮も冷めてはいないというにもかかわらず、dockerというこれまた便利なものに出会ったおかげでほとんどがdocker上で完結するようになり、自分のmac環境をぐちゃぐちゃにしなくて済むことがほとんどになりそうだ。ただdockerhubのhomebrewイメージを発見してCabochaインストールを試したところ、そのままではc++でのコンパイルができないようであるのでそのへんはその都度チェックしたいところ。dockerのポテンシャルに大いなる期待。`Dockerfile`、`docker-compose.yml`の書き方があまりよくわかっていないので勉強していきたい。
ネットカフェで一人ハッカソンする

最近ネットカフェは「個室、半個室で漫画やインターネットを楽しめる場所」だと知りました。

試しに初めてネットカフェを利用したのですが、結構居心地が良いんですよね。

ってことで早速、ネットカフェで「一人ハッカソン」をしてきました。

試したところ好評でしたので、忘れないうちに書き留めておきます。

#対象読者
・自宅での作業はかたどらない方
　→「ずっと家だとしんどい...　気分転換もしたいな...」
・集中して作業されたい方
　→「明日は休日だし、徹夜して開発したい！！」
・ネットカフェを好んで利用されている方
　→「家にあるなら、ネットカフェで漫画でも読むか....」

#なんで一人でハッカソンをするの？
それは 本当に開発に集中したい、もしくは自分がやりたい作業に集中したい為です。

一人なので、誰にも迷惑はかからないし、自分の好きなだけ開発に集中できます。

#準備物
準備物は以下になります
・自分の使用しているPC
・自分のPCとネットカフェにあるディスプレイをつなげるHDMLケーブル
・必要に応じてキーボード(ちなみに私は持参しました)

#早速開始！！
深夜の時間帯8:00〜４：００を使っての開発です　
部屋は個別ルームを使用しました
(行った内容は今回省略させて頂きます。ご了承ください)

#やってみたメリット
個人的にネットカフェを使ってハッカソンをした感想を述べます
1.落ち着ける静かな環境
2.ゆったりくつろげる個室
3.お金を払っている為強制力がある
4.好きな飲み物が飲める


#落ち着ける静かな環境
漫画を読んでいるか、パソコンを触っている人しかいないので、ネットカフェは基本的に静かな空間です。

密閉されている空間だったため、開発しやすい環境でした。
※ケーブルがあればネットカフェのディスプレイとつなげることも可能です(使ったら戻しておいてください)

#個室
席にもよるのですが、基本的にネットカフェは個室です。(オートロックだったのがびっくりです)

そのためゆっくりとくつろいで作業できました。
理由としては自宅にある椅子よりネットカフェの椅子の方が断然良いです
家の椅子に不満のある人は使ってみてください

#強制的にお金を払っている

お金を支払っている状況なので、開発しなければという思いになり、家にいる以上に集中できます。

#好きな飲み物が飲める
個人的にはこれが一番良かったです
コーヒーからジュースまで好きなものを飲むことができます。
アイクリームも無料で食べることができ、注文すれば食事も可能です(食事は有料)

眠くなったときはコーヒーを飲んだりすることもできます

#やってみたデメリットは？
実際にデメリットもありました。
1.シンプルにお金がかかる
2.尋常ではない誘惑
3.場所によっては清掃に不備がある場合も...

#シンプルにお金がかかる
普通にお金がかかります。
平日１日いるとかなりの金額が必要になります....

解決策としては
深夜の時間は安くなっているので、夜利用するのがお得だと思います。
※住んでいる町によるので注意してください
私個人的には深夜パックが一番オススメです

#尋常ではない誘惑
誘惑の数が尋常ではないです。
漫画、映画、アニメ、VRもあるところも....
寝ようと思えば寝ることだってできます。
後、びっくりしたことはアダルト動画も見ることができます。

是非、利用する際は気をつけてください

#場所によっては清掃に不備がある場合も...
場所によっては清掃に不備がある場合もあるようです。
ちなみに私が利用したネットカフェは清掃が行き届いていました。

やっぱり値段と場所はしっかり吟味したほうが良さそうです
→値段を妥協しすぎるとそういう場所に当たる可能性も....

#まとめ
ネットカフェを使ってみての感想について紹介してみました。参考になれば幸いです。
基本的には誘惑の多いネットカフェですが、定期的に利用するのも良いかもしれません。

後は潔癖症の人には合わないかも....です

気になる方はぜひ一度、ネットカフェでの勉強を体験してみてください！
Firebaseアナリティクスについて（オレオレプラクティス）

Firebaseアナリティクスについて、じっくり調べて、ガッツリ実装したので、忘れないように自分メモです。
とはいえ、Firebaseアナリティクスについて記事が少ないので、どこかの誰かの何かになったら嬉しいので、公開します。

##Firebaseアナリティクスとは
　Googleが提供している、どこまでも無料で計測できるアナリティクスツール
　無料で使用できるが、クセが強く導入前に計測内容の設計が重要
　（何も考えずに計測していてたら、リファレンスにも書いていない落とし穴が結構あって結果作り直すことになった）

##各種特徴
###イベント数について
- 登録できるイベント数は500個まで
- 削除はできない
- ユーザーリスト（同じイベントを起こしたことがあるユーザーのグループ化）ができるFirebaseAudienceを使用する場合、イベント名が日本語だとグループ化できない
- 管理画面での設定は必要なし
- イベント名は40字まで

###パラメータについて
- パラメータとは、イベントに付与することができる、そのイベントの詳細情報のようなもの
- 「パラメータKey」と「パラメータValue」で構成されてる
- 1イベントあたり25個まで
- 管理画面に表示させるためには、管理画面で登録する必要がある
- 管理画面で確認できるように表示させるかどうかの登録と削除はできる
- 1プロジェクトあたり、管理画面で確認できるパラメータ総数は100個まで（数値50個,文字50個）
- 同名パラメータでも、イベントが違う場合それぞれ1個として計測される
- パラメータKeyは40文字、パラメータValueは100文字まで
- Nullを送ればパラメータの計測はされない

###ユーザープロパティについて
- プロパティ名とプロパティ値で構成される
- 1つのプロパティ名に複数のプロパティ値を設定できる
- 1プロジェクトあたり、25個まで作成できる
- 削除はできない
- プロパティ名は24文字まで
- プロパティ値は36文字まで
- 管理画面で設定を行う必要がある


##設計
イベントは消すことができないことと計測数に上限があるため、何でもかんでもイベントにする訳にはいかない。
パラメータもBigQuaryに連携していたら問題はないが、Firebase管理画面だけで計測を行う場合、閲覧の制限がある。
パラメータValueにはおそらく無制限（制限についての記事がなかったため）の種類の計測ができる。
イベントを大カテゴリ、パラメータKeyを中カテゴリ、パラメータValueで個別の計測を行うように設計。
ex:)　登録したメモ一覧、メモ登録画面、マイページ（設定ページ）の3要素とし、マイページ（設定）の計測なら、

 - イベント：mypage
 - パラメータKey：content
 - パラメータValue：選択した項目（「問い合わせ」や「情報変更」など）

##注意事項
- 無料でできるGA連携を行えば、GA上でファネル分析などが行える
- パラメータ数は実装がちゃんとできていて管理画面ではズレる事がある
 - Google側も把握している既存バグ（？）
 - BigQuaryに連携していたため、BigQuaryが確認したら、パラメータ数は合致していた
 - Googleに問い合わせをしても返答は返ってこなかったため、原因究明はできていません。（知っている人がいたら教えてください！）
  


##参考
[Firebase収集の上限と設定](https://support.google.com/firebase/answer/9237506?hl=ja&ref_topic=6317484)
[パラメータの数値、文字の計測画面](https://qiita.com/KIRIN3qiita/items/7cafe260706c2c0a40ff#%E3%80%87%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AB%E3%81%99%E3%81%B9%E3%81%8D%E3%81%8B%E6%95%B0%E5%80%A4%E3%81%AB%E3%81%99%E3%81%B9%E3%81%8D%E3%81%8B)
[パラメータ設定](https://wootan1102.hatenablog.com/entry/2017/05/31/234843)
[ユーザープロパティ設定](https://qiita.com/yamacraft/items/d0e860e1cc13d1c8ce8e#%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E7%94%BB%E9%9D%A2%E3%81%A7%E3%81%AE%E8%A8%AD%E5%AE%9A)
製薬企業研究者がPythonを用いたウェブスクレイピングについてまとめてみた

# はじめに

ここでは、Pythonを用いたウェブスクレイピングについて解説します。


# BeautifulSoup

以下のHTMLファイルを表示するウェブページに対してクローリング、スクレイピングを行うとします。

```html
<ul class="list-group">
  <li class="list-group-item"><a href="">要素１</a></li>
  <li class="list-group-item"><a href="">要素２</a></li>
  <li class="list-group-item"><a href="">要素３</a></li>
</ul>
```

Pythonスクリプトは以下のようになります。

```python
import requests
from bs4 import BeautifulSoup


url = HTMLを取得するURL
response = requests.get(url)
response.encoding = response.apparent_encoding

bs = BeautifulSoup(response.text, 'html.parser')

ul = bs.select('ul.list-group')

for li in ul[0].select('li.list-group-item'):
    a_tags = li.select('a')
    a_tag = a_tags[0]
    item_name = a_tag.text.strip()
```


# Scrapy

上のBeautifulSoupを用いる場合と同様のHTMLファイルに対してクローリング、スクレイピングを行うとします。

```html
<ul class="list-group">
  <li class="list-group-item"><a href="">要素１</a></li>
  <li class="list-group-item"><a href="">要素２</a></li>
  <li class="list-group-item"><a href="">要素３</a></li>
</ul>
```

```python
import scrapy


class SampleSpider(scrapy.Spider):
    name = 'sample'
    allowd_domains = [ドメイン]
    start_urls = [
        対象URL
    ]

    def parse_list(self, response):
        ul = response.css('ul.list-group')[0]
        for li in ul.css('li.list-group-item'):
            item_url = li.css('a::attr(href)').extract_first()

            yield scrapy.Request(item_url, callback=parse_detail)

    def parse_detail(self, response):
        item_name = response.css('h1.item-name::text').extract_first()
        return item_name
```


# まとめ

ここでは、BeautifulSoupおよびScrapyを用いたウェブスクレイピングの方法について解説しました。


# 参考資料・リンク

[プログラミング言語Pythonとは？AIや機械学習に使える？](https://pharma-engineer.com/basic-programming/python-summary/)
flaskでボタンで遷移したい

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 　ポチッと押したら切り替わってほしい
##やること

flask で 「AAAA.html」の中にあるボタンを押したら「BBBB.html」に遷移する。

##環境

- flask

##やり方

flaskのpythonの中身の一部

```python:sample.py
from flask import Flask, request, render_template
app = Flask(__name__)

(中略)

@app.route("/BBBB", methods=["POST"])
def move_BBBB():
    return render_template("BBBB.html")

(後略)
```
POSTが来たらBBBB.htmlに遷移するようにしておく。


```html:templates/AAAA.html
{% block content %}
<form action="/BBBB" method="POST">
    <input type="submit" value="ボタン">
</form>
{% endblock %}
```
AAAA.htmlの中にボタンを書いておく。
BBBB.htmlも準備しておく。

これでできていはいるようだけど、なにかダメな気がする。
ArudunoでLCDモジュールでHello World


# Goal

- Arduinoを利用する
- I2Cの使い方を学ぶ

# はじめに

はんだ付けや一般的なプログラミング方法を学ぶため、壊しても痛くないLCDモジュールをつかって遊んでみよう。

# 使用したもの

**Ｉ２Ｃ接続小型ＬＣＤモジュール（８×２行）ピッチ変換キット**
http://akizukidenshi.com/catalog/g/gK-06795/

コントローラに `ST7032i` を使っているので「オレ工房」さまのライブラリが使えそうです！感謝！
https://ore-kb.net/archives/195

# 参考にさせていただいたサイト

「オレ工房さま」が公開されていたgithub
https://github.com/tomozh/arduino_ST7032

# 情報をあつめる

とっても[製品ページ](http://akizukidenshi.com/catalog/g/gK-06795/)を見るだけなんですが。製品ページには丁寧に

- 動作に必須なコンデンサが実装済み
- プルアップ抵抗付き

と記載あります。詳細は製品ページに記載のPDFに記載されていますが、とにかくはんだ付けだけすればOKなようなので、やってみます。

http://akizukidenshi.com/download/ds/akizuki/AE-AQM0802-sch.pdf

# はんだ付け

クッソへたくそなはんだづけですが、張り付けてしまいます。いつか笑える日が来ますように:kissing:

![front.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/ddea89f4-b14c-e663-9e1c-da5ba7e6780b.jpeg)

改めて見ても裏は特にひどいですね…

![back.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/a18515dd-2186-9d34-33c8-4758f3689173.jpeg)


ちなみにこの作業中、キーボードのWindowsボタンをはんだで溶かしてしまいました。よい勉強になりましたなぁ:angel:

# 接続方法について調べる

http://akizukidenshi.com/download/ds/akizuki/AE-AQM0802-sch.pdf

外部のIFが5つのみのシンプルな回路図なんですが、記号の意味がわからんので調べてみました。

- VDD
    - Voltage Drain Drainの略らしい。VSS(Voltage Source Source)は見たことあるんですが。違いはよくわかない（し、なんで２回繰り返すんだろう）けど、電源で間違いないはず。Arudinoの3.3Vにつないでみよう
- GND
    - これはグランドだろうから普通につなげばよいはず。
- SCL
    - I2C接続で利用。クロック線。ArduinoUnoだときちんと印字されていた！
- SDA
    - SCLと同じくI2C接続で利用。データ線。同じく印字されていました。
- RESET
    - 一般的なI2Cの回路図には出てこないな。必要なのかな？とりあえず線をつなげないでやってみます。もし駄目でも動かないだけだろうし[^RESET]:wink:

[^RESET]: ライブラリの作者さまのサイトでもRESETつないでいないので、大丈夫みたいです！https://ore-kb.net/archives/195


# 回路図

シンプルにつなげてみました。
:bangbang:ご注意:bangbang:
回路図のLCDモジュールは `AE-AQM080` ではないので、実際のつなぎ方はことなりますのでご注意ください！端子名をあわせて接続するだけでよいので、難しくはないはずです。


![LCD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/b2f3f659-dbee-3854-304a-fe269b401e82.png)

# スケッチ

```C
#include <Wire.h>
#include <ST7032.h>

ST7032 lcd;

unsigned long sec;

void setup() {
  lcd.begin(8, 2); // この指定がないと表示すらされなかった
  lcd.clear();
  lcd.setContrast(30); //0～63が指定可能みたい

  lcd.setCursor(0,0);
  lcd.print("Hello!!!");
  delay(1000);
}

void loop() {
  sec = millis() / 1000;
  lcd.setCursor(3,1);
  lcd.print(String(sec));
  lcd.setCursor(7, 1);
  lcd.print("s");
}
```

# 動かしてみた

![result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/506252ef-d24f-3ec0-3454-997c74eaf3dc.jpeg)

# 感想

- はんだごては武器。散らかった机の上では使っちゃダメという知見を得た。
- 部品についてくる説明書を読み取れるようにならないといけないな。
- 楽しい。
Laravelに似ているPythonのWEBフレームワークMasoniteの環境をDockerで作ってみた！

## 目的
Laravelに似たPythonのWEBフレームワークMasoniteの動作環境をDockerを利用して作成する事で、共同開発で使えるようにしました。

## 動作環境
Mac: Catalina10.15.5
Docker: 19.03.8

## 環境構築方法と起動方法
作業ディレクトリに以下の内容のDockerfileとdataディレクトリを作成する。

```
FROM ubuntu:latest

COPY ./requirements.txt /opt

RUN apt-get update && apt-get -y upgrade && \
    apt-get install tzdata language-pack-ja gcc libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6 wget -y && \
    wget -P /opt https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
    bash /opt/Miniconda3-latest-Linux-x86_64.sh -b -p /opt/anaconda3 && \
    rm /opt/Miniconda3-latest-Linux-x86_64.sh && \
    echo "export PATH=/opt/anaconda3/bin:$PATH" >> ~/.bashrc && \
    . ~/.bashrc && \
    conda init && \
    pip install -r /opt/requirements.txt

ENV TZ Asia/Tokyo
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

RUN rm /opt/requirements.txt
RUN mkdir /opt/myproject
```

また、以下のrequirements.txtを作成する。

```
masonite
```

この段階で、以下のディレクトリ構成になります。

```
.
├── Dockerfile
├── data
└── requirements.txt
```

Dockerイメージをビルドして、コンテナを起動させる。

```
docker build . -t masonite
docker run -v $(pwd)/data:/opt/myproject -p 8000:8000  -it masonite /bin/bash
```

/opt/myprojectディレクトリに移動して、Masoniteのアプリケーションを作成する。

```
cd /opt/myproject
craft new
```

ビルドインサーバーを起動する。

```
craft serve -h 0.0.0.0 -r
```

また、Dockerコンテナを再度、起動させるときは、/opt/myprojectに移動して、以下のコマンドを起動させて下さい。

```
craft install
```

## 参考文献
[UbuntuベースのDockerでタイムゾーンを設定する](https://qiita.com/apollo_program/items/2495a109ce7afec21f25)
pyenvでバージョンが切り替わらないときに確認すること

# 作業メモ

pyenvをインストールするときの問題の切り分け方についてまとめます
なるべく公式の資料を見てインストールを行ってください。
公式：https://github.com/pyenv/pyenv#installation

# どこのpythonを使っているか確認

「pyenvで設定しpython」「OSにデフォルトでインストールされているpython」かを判断します

```shell
# macデフォルトのpython
$ which python
/usr/bin/python

# pyenvのpython
$ which python
/Users/xxxx/.pyenv/shims/python
```

# shellの設定ファイルを確認
## どのshellか確認

shellで、pyenvの環境変数を読み込む必要があります
shellによってpyenvの環境変数をloadする場所が異なるため、確認をします

```shell
$ echo $SHELL
/bin/zsh
```

記述方法は、公式の `2. Define environment variable PYENV_ROOT ...`  に記述されています
各shellによって記述方法が異なるため、説明は省略します
https://github.com/pyenv/pyenv#basic-github-checkout

## 環境変数を設定したがうまく動かない

shell, pyenvの設定をリフレッシュさせることにより、正常に動く可能性があります

```
// shellの設定をリフレッシュする
$ exec "$SHELL"
// pyenvの設定をリフレッシュする
$ pyenv rehash
```

# 公式さんは最高


最後に、今回のqiitaでは、問題の切り分け方についてまとめました。
あくまでもインストール方法は「公式を見れば大丈夫b」とはおみますが、どうしても最初の設定でつまずくことがあると思うので、その時に問題の切り分けができるエンジニアになりたいですね。
公式：https://github.com/pyenv/pyenv#installation
GithubAPI(v3)のissue一覧の取得について

GASとGithubAPIを使って、日毎のissueの状況をスプレッドシートに集計するツールを作成中です。
備忘録として綴っておきます。

利用したgithubAPI
https://developer.github.com/v3/issues/

### APIのresponseで送られてくるものはissueだけではない

issue APIを利用して受け取れるデータにはpull requestも含まれているようです。
pull requestの場合、レスポンスのkeyに`pull_request`があるので
純粋にissueだけ欲しい場合は条件分岐など利用して取り除かないといけない。

https://developer.github.com/v3/issues/#response

APIドキュメントより

```json
    "pull_request": {
      "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
      "html_url": "https://github.com/octocat/Hello-World/pull/1347",
      "diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
      "patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"
    },
```

純粋なissueは`pull_request`keyが用意されていない
kubectl get pods でPod名だけを抜き出す2パターン

通常の`kubectl get pods` の出力

```
$ kubectl get pod
NAME                             READY   STATUS    RESTARTS   AGE
details-v1-b649ff69-mdqg7        2/2     Running   0          20h
productpage-v1-64bc9d48c-lm4qr   2/2     Running   0          20h
ratings-v1-5fc49bf9cb-9bqwr      2/2     Running   0          20h
reviews-v1-7bcff9b8d6-w8x8r      2/2     Running   0          20h
reviews-v2-cf6f69b7d-gmzt9       2/2     Running   0          20h
reviews-v3-55c7b5f478-s85gb      2/2     Running   0          20h
```

シェルなどでこのPod名を再帰的に利用したくてPod名だけを抜き出す場合の2パターン。

### kubectl get pods -o name
```
$ kubectl get pods -oname
pod/details-v1-b649ff69-mdqg7
pod/productpage-v1-64bc9d48c-lm4qr
pod/ratings-v1-5fc49bf9cb-9bqwr
pod/reviews-v1-7bcff9b8d6-w8x8r
pod/reviews-v2-cf6f69b7d-gmzt9
pod/reviews-v3-55c7b5f478-s85gb
```

この`pod/`を入れたくない場合はawkで整形する。

```
$ kubectl get pods -oname | awk -F '/' '{print $2}'
details-v1-b649ff69-mdqg7
productpage-v1-64bc9d48c-lm4qr
ratings-v1-5fc49bf9cb-9bqwr
reviews-v1-7bcff9b8d6-w8x8r
reviews-v2-cf6f69b7d-gmzt9
reviews-v3-55c7b5f478-s85gb
```

### kubectl get pods -o jsonpath

```
$ kubectl get pods -n bookinfo -o jsonpath={.items..metadata.name}
details-v1-b649ff69-mdqg7 productpage-v1-64bc9d48c-lm4qr ratings-v1-5fc49bf9cb-9bqwr reviews-v1-7bcff9b8d6-w8x8r reviews-v2-cf6f69b7d-gmzt9 reviews-v3-55c7b5f478-s85gb
```
この場合Pod名がスペース区切りで出てくる。
MNISTにオリジナル画像を加えたTensorflow Sequentialモデルの作成

※完全版は、有料Noteにて販売しております。
https://note.com/academicagent/n/nf046848f5c04

MNISTの画像に、数字記号の『-』を加えたモデルを作成してみました。

![SnapCrab_NoName_2020-6-7_19-10-52_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651297/bb513d1e-d11a-7219-091f-570a33922d12.png)



```python:mk_model.py
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.optimizers import Adam
from keras.utils import np_utils
from keras import backend as Keras
from PIL import Image, ImageFilter
import numpy as np
import numpy
import os
import matplotlib.pyplot as plt
import cv2
import keras




def load_images_to_data(image_label, image_directory, features_data, label_data):
    ####関数の中身は有料Noteで公開いたします！！####

(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Reshaping to format which CNN expects (batch, height, width, channels)
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], X_test.shape[2], 1).astype('float32')


X_train, y_train = load_images_to_data('10', '-', X_train, y_train)
X_test, y_test = load_images_to_data('10', '-', X_test, y_test)


# normalize inputs from 0-255 to 0-1
X_train/=255
X_test/=255

# one hot encode
number_of_classes = 11
y_train = np_utils.to_categorical(y_train, number_of_classes)
y_test = np_utils.to_categorical(y_test, number_of_classes)

# create model
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(X_train.shape[1], X_train.shape[2], 1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(number_of_classes, activation='softmax'))

# Compile model
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])

# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=7, batch_size=200)

model.save('my_model.h5')

```
-記号の画像は、10枚だけ追加したモデルをまず簡易的に作成し、

![SnapCrab_NoName_2020-6-7_18-19-16_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651297/4e2629f6-b8fa-ce6a-fad2-a6841fd81081.png)

テストも無事、完了いたしました。

![SnapCrab_NoName_2020-6-7_19-47-59_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651297/89905764-bcda-2825-1bec-7f0a6c138689.png)

※有料Noteでは、使用した画像、pygameのテストで使用したプログラムファイルも配布しております。
是非、ご購入ください。
https://note.com/academicagent/n/nf046848f5c04
【jQuery】スムーススクロール

```index.js
$(function(){
        // #で始まるリンクをクリックしたら実行されます
  $('a[href^="#"]').click(function() {
    // スクロールの速度
    var speed = 500; // ミリ秒で記述
    var href= $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
      $('body,html').animate({scrollTop:position}, speed, 'swing');
        return false;
    });
  });
```
自前のResponseクラスを作ってテストしやすくする

Laravelはとても便利なので、ControllerでLaravelが提供してくれるリクエストとレスポンスのクラスを活用するだけで簡単に処理が書けてしまいます。

例えば

```php
return view('view_name', $params);
```

このようにするとレスポンスが簡単に返せます。

ただ、これだとControllerを呼ばないとレスポンスが得られないため、`$params`の色んなパターンを試すのが面倒です。

# Responsableインターフェース

LaravelにはResponsableインターフェースというものがあります。このInterfaceを実装しているクラスをControllerから返せば、いい感じにレスポンス化してくれます。

```php
<?php
declare(strict_types=1);

namespace App\Http\Response\Top;

use Illuminate\Contracts\Support\Responsable;
use Illuminate\View\View;

class IndexResponse implements Responsable
{
    /**
     * @var Params
     */
    private $params;

    public function __construct(Params $params)
    {
        $this->params = $params;
    }

    public function toResponse($request = null): View
    {
        return view('top.index', [
            'params' => $params
        ]);
    }
}
```

このように簡単にResponsableなクラスが作れます。

# Responsableなクラスのテスト

レスポンスクラスがControllerと分離していることで、外から引数を渡し、簡単にテストすることができます。

```php
<?php
declare(strict_types=1);

namespace Tests\Unit\App\Http\Response\Top;

use App\Http\Response\Top\IndexResponse;
use Tests\TestCase;

class IndexResponseTest extends TestCase
{
    public function testMakeResponse()
    {
        $response = new IndexResponse(['title' => 'トップページです']);

        $this->assertContains('<h1>トップページです</h1>', $response->toResponse()->render());
    }
```

渡す引数を変えることで、簡単に複数のレスポンスを作ることができます。
Certbotのアカウント鍵(JWK形式)をPEM形式に変換する

# はじめに

Let's Encrypt の証明書を発行するのに [Certbot](https://certbot.eff.org/) を使う時は、はじめにアカウントが作られます。このアカウントの鍵は [JWK (JSON Web Key)](https://tools.ietf.org/html/rfc7517) 形式で収められているのですが、ここから `openssl` で使われるPEM形式に変換するスクリプトを書きました。

# アカウント鍵

以下の場所にあります。（`XXXX` の部分はアカウントIDです）

```
/etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/XXXX/private_key.json
```

# 変換スクリプト

https://github.com/keioni/qiita-sample/blob/master/jwk_to_pem.py

```python:jwk_to_pem.py
import sys
import json
import base64

with open(sys.argv[1]) as fp:
    pkey = json.load(fp)

print('asn1=SEQUENCE:private_key\n[private_key]')
print('version=INTEGER:0')
for k,v in pkey.items():
    if k == 'kty':
        continue
    missing_padding = 4　-　len(v) % 4
    if missing_padding != 4:
      v = v + ('='*missing_padding)
    v_hex = base64.urlsafe_b64decode(v).hex().upper()
    print('{}=INTEGER:0x{}'.format(k, v_hex))
```


参考にしたスクリプトはここにあります
……が、ちょっと変なコードだった＆Python 3系で動作しないので作り替えました。
https://github.com/szepeviktor/debian-server-tools/blob/master/security/jwk_convert.py

# 使い方

スクリプトを実行すると、`openssl` の `asn1parse` サブコマンドで扱えるファイルを出力します。

```
python jwk_to_pem.py private_key.json > private_key.asn1
```

それを使って、まずDER形式のファイルを作り、最後にPEM形式にします。

```
openssl asn1parse -genconf private_key.asn1 -noout -out private_key.der
openssl rsa -inform der -in private_key.der -outform pem -out private_key.pem
```

以上です。

# 参照

[RSA鍵、証明書のファイルフォーマットについて - Qiita](https://qiita.com/kunichiko/items/12cbccaadcbf41c72735)
ASN.1とかDERとかPEMとか、そういったものに興味がある方は、こちらに情報がまとまっています。

[RSA 秘密鍵/公開鍵ファイルのフォーマット - bearmini's blog](https://bearmini.hatenablog.com/entry/2014/02/05/143510)
ちょっとマニアックですが、DER形式について詳説されています。
ハッシュについて

[前回のシンボルに関する記事](https://qiita.com/mofuko0213/items/c4b660325c54f29823fe)

## ハッシュのキーにシンボルを使う

前回の、シンボルに関する記事で紹介したように、ハッシュのキーには文字列よりもシンボルの方が適しています。
ハッシュのキーにシンボルを使うと次のようなコードになります。

```ruby
menu = { :food => 'rice', :dessert => 'cake'}
# 値を取り出す場合
menu[:dessert] # => "cake"
# 新しいキーと値の組み合わせを追加する場合
menu[:drink] = 'water'
p menu # => {:food=>"rice", :dessert=>"cake", :drink=>"water"}
```

シンボルがキーになる場合、=> を使わずに`シンボル:値`という記法でハッシュを作成できます。
(※コロンの位置が左から右に変わります)

(例)

```ruby
menu = {food: 'rice', dessert: 'cake'}
# 値を取り出す時は同じ
menu[:dessert] # => "cake"
```

(例)キーも値もシンボルの場合のコード

```ruby
{food: :rice, dessert: :cake, drink: :water}
```

## メソッドのキーワード引数とハッシュ
メソッドに引数を渡す場合、メソッドのキーワード引数を使うと可読性が上がります。
メソッドのキーワード引数は次のように定義します。

```ruby
def  メソッド名(キーワード引数1: デフォルト値1, キーワード引数2: デフォルト値2)
# メソッドの実装
end
```

(キーワード引数を使用した例)

```ruby
def buy_food(menu, drink: true, dessert: true)
  # foodを購入
  if drink
    # ドリンクを購入
  end
  if dessert
    # デザートを購入
  end
end
# ライスとドリンクとデザートを購入
buy_food('rice', drink: true, dessert: true)
# ピザとドリンクを購入
buy_food('pizza', drink: true, dessert: false)
```

キーワード引数を持つメソッドを呼び出す場合は、ハッシュを作成した時と同じように
シンボル:値の形式で引数を指定します。

また、キーワード引数はデフォルト値が設定されているので、引数を省略することができます。

```ruby
buy_food('rice', drink: true, dessert: true)
```
⬇︎ drink,dessertもデフォルト値のtrueを使用するので、指定しない。

```ruby
buy_food('rice')
```

キーワード引数のデフォルト値は省略することもできます。

```ruby
def buy_food(menu, drink:, dessert:)
# 省略
end
```
デフォルト値を持たないキーワード引数は、呼び出し時に省略できません。
(省略すると、エラーになります。)

```ruby
buy_food('rice', drink: true, dessert: true)
```

キーワード引数を使うメソッドを呼び出す場合、
キーワード引数に一致するハッシュ（キーはシンボル）を引数として渡すことも可能です。

```ruby
Params = { drink: true, dessert: false }
buy_food('rice', params)
```

## 参考にした文献

[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/dp/4774193976/ref=cm_sw_em_r_mt_dp_U_shaUEbXSFD416)
API Gatewayでファイルアップロード（multipart/form-data）を扱う

お疲れ様です。

先日、Amazon API Gatewayでファイルをアップロードする際、
めちゃくちゃハマったお話です。

# 事象

アプリに到達するまでにファイルのデータが消えてしまっている。
アップされたはずのファイルを参照するとnull。

# 結論

APIの「設定」でバイナリメディアタイプをサポートする設定を追加（この場合multipart/form-data）し、
**デプロイ**します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103853/adc9c751-8e26-063b-d383-3709aa99a6d7.png)

※デプロイしないと設定が反映されないことを見逃していて、めちゃくちゃハマりました。

ぶっちゃけ設定する箇所はこれくらいかも知れません。
プロキシ統合でもリソースでもVPCリンクでも特に変わらないと思われます。
Vite と VitePress のつなぎ込み




## はじめに

* バージョン ... 0.2.0
* SHA-1 ハッシュ ... 3d2f7e27dea15bab9b6100789c4e75f76d0048ad

1. [VitePress のディレクトリ構成](https://qiita.com/domodomodomo/items/1048f51d98ab5fd52d12)
2. [src/client/app と src/client/theme-default のつなぎ込み](https://qiita.com/domodomodomo/items/49b1944f09f8f9f57519)
3. [Markdown ファイルと src/client/app, Vue インスタンス本体のつなぎ込み](https://qiita.com/domodomodomo/items/f44bf1f49cff511890c7)
4. [Vite と VitePress のつなぎ込み <-- いまココです。](https://qiita.com/domodomodomo/items/c3b828bf9f7cb7e9a18f)
  1. [dev 編](https://qiita.com/domodomodomo/items/aea100ae69344d6dcc39)
  2. build 編(未着手)


## 概要

VitePress をどのようにして Vite につなぎ混んでいるかを見ていきます。起動するコマンドからはじめて、npx vitepress dev の場合はサーバの起動まで、npx vitepress build の場合は、html ファイルの出力までを見ていきます。


## 1. コマンドの書式

`$ npx vitepress ...` で起動するスクリプトです。

```
$ # 書式
$ npx vitepress [dev | build] [対象のディレクトリ] --port [ポート番号]
$
$ # 例
$ npx vitepress dev docs/ --port 3002
```


## 2. ライブラリ

`/bin/vitepress.js` で使用されているライブラリの動作を簡単に示します。

```
// chalk
//   console.log を色付けしてくれます。

// minimist
//   引数を解析してくれます。例えば、
//
//   以下のように打ち込んだとき...
//   $ npx vitepress dev docs/ --port 3002
//
//   以下のように解析されます。
//   const argv = require('minimist')(process.argv.slice(2))
//   argv === { _: [ 'dev', 'docs/' ], port: 3002 }
//
//   argv._[0] ... dev | build
//   argv._[1] ... 対象のディレクトリ
//   argv.port ... ポート番号
```



## 3. ソースコードと補足

```/bin/vitepress.js
#!/usr/bin/env node
const chalk = require('chalk')
const argv = require('minimist')(process.argv.slice(2))


console.log(chalk.cyan(`vitepress v${require('../package.json').version}`))
console.log(chalk.cyan(`vite v${require('vite/package.json').version}`))


const command = argv._[0]

//
// 1) dev の場合
//      `createServer` して `server.listen` する。
//      server には Koa というライブラリを用いる。
//
if (!command || command === 'dev') {
  const port = argv.port || 3000
  const root = command === 'dev' && argv._[1]
  if (root) {
    argv.root = root
  }
  require('../dist/node')  // <--- ../src/node がトランスパイルされたものが保存されています。
    .createServer(argv)
    .then((server) => {
      server.listen(port, () => {
        console.log(`listening at http://localhost:${port}`)
      })
    })
    .catch((err) => {
      console.error(chalk.red(`failed to start server. error:\n`), err)
    })
//
// 2) build の場合
//      `build` する。
//
} else if (command === 'build') {
  require('../dist/node')
    .build(argv)
    .catch((err) => {
      console.error(chalk.red(`build error:\n`), err)
    })
} else {
  console.log(chalk.red(`unknown command "${command}".`))
}
```

* [vue/vitepress - /bin/vitepress.js](https://github.com/vuejs/vitepress/blob/a3df035babe28fd086098fea26087fd3fbca17d0/bin/vitepress.js#L1-L28)



## おわりに

以上になります。ありがとうございました。次は、以下の記事になります。

* [Vite と VitePress のつなぎ込み - dev 編](https://qiita.com/domodomodomo/items/aea100ae69344d6dcc39)
IntelliJとSpring bootでHello Worldしよう

# IntelliJとは

IntelliJ IDEA (インテリジェイ アイディア) は、チェコに本社を置くJetBrains社が開発した、Javaなど数多くのプログラミング言語に対応した統合開発環境である。

https://www.jetbrains.com/ja-jp/idea/
https://ja.wikipedia.org/wiki/IntelliJ_IDEA

# IntelliJのダウンロード
https://www.jetbrains.com/ja-jp/idea/download/#section=windows

# プロジェクト作成
[Spring Initializr](https://start.spring.io/)でプロジェクトのひな型を作成します。

各種設定は初期設定のまま、DependenciesにてSpring Webを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399736/78e3f9c7-c485-4522-8e2a-ea6606332742.png)

「Generate」ボタンをクリックします。

zipファイルがダウンロードされるので解凍してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399736/b5a8dbad-aadf-0afc-4cfe-99a1e4434b01.png)

# Projectのインポート
解凍したdemoフォルダにあるpom.xmlを右クリックします。
「プログラムから開く」->「別のプログラムを選択」->IntelliJを選択します。

IntelliJは自動的にdemoプロジェクトを開きます。

下記のDemoApplicatoin.javaを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399736/372917d0-0d36-822e-baef-53b3a027e62f.png)

# Demo用Javaファイルを編集
demoApplication.javaのファイルを編集します。

```java:DemoApplicatoin.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

	@RequestMapping("/helloworld")
	String index(){
		return "Hello World!";
	}

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}
```
src配下のdemoApplication.javaを右クリックします。
Run DemoApplication mainを選択します。
実行が完了まで待ちます。

# デモサイトへアクセスします。

http://localhost:8080/helloworld にアクセスすると、下記の画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399736/045bfbcb-4ef5-2860-2607-1a01d6a5626f.png)

# 次回
IntelliJで簡単なREST APIを作ります。
Enumで状態が最後まで行ったら最初の状態に戻す(繰り返し)の実装

初投稿です。
C#を使って、音楽プレイヤーライクなものをつくっていました。
その中で、音楽をループさせない「NoLoop」・その一曲だけループさせる「FileLoop」・フォルダー内をループさせる「FolderLoop」の３つの状態が必要になり、ループボタン１つでモードが切り替えられるようにしたかったので、「状態が最後まで行ったら最初の状態に戻す」のを繰り返したく、以下を実装しました。
コードの説明は、まず各モードが書かれたEnumとそのEnumに対し「次の状態」と「前の状態」を取得できるような関数を書いたstaticなクラスを作ってます。

``` cpp
public class Test{
    public static void Main(){
        // Your code here!
        LoopStates loopState = LoopStates.NoLoop;
        System.Console.WriteLine(loopState);
        loopState = LoopStatesExtension.GetNextState(loopState);
        System.Console.WriteLine(loopState);
        loopState = LoopStatesExtension.GetNextState(loopState);
        System.Console.WriteLine(loopState);
        loopState = LoopStatesExtension.GetNextState(loopState);
        System.Console.WriteLine(loopState);    
        loopState = LoopStatesExtension.GetPreviousState(loopState);
        System.Console.WriteLine(loopState);    
    }
}

public enum LoopStates
{
    NoLoop,
    FileLoop,
    FolderLoop
}
```

mickey_devさんからもっとスマートなコードをいただいたので再編集します。
こっちのほうがif文使ってないのでスマートですね。

``` cpp
    public static class LoopStatesExtension
    {
        public static LoopStates GetNextState(LoopStates loopState)
        {
            int statesCount = System.Enum.GetValues(typeof(LoopStates)).Length;
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates), ((int)loopState + 1) % statesCount);
        }

        public static LoopStates GetPreviousState(LoopStates loopState)
        {
            int statesCount = System.Enum.GetValues(typeof(LoopStates)).Length;
            // 負の数の剰余は求められないので loopState == 0 のために statesCount を加算しておく
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates), ((int)loopState + statesCount - 1) % statesCount);
        }
    }
```

修正前は以下です。

``` cpp
public static class LoopStatesExtension
{ 
    public static LoopStates GetNextState(LoopStates loopState)
    {
        int MaxNumber = System.Enum.GetValues(typeof(LoopStates)).Length - 1;
        if ((int)loopState == MaxNumber)
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates), 0);
        else
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates),(int)loopState + 1);
    }
    public static LoopStates GetPreviousState(LoopStates loopState)
    {
        int MaxNumber = System.Enum.GetValues(typeof(LoopStates)).Length - 1;
        if ((int)loopState == 0)
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates), MaxNumber);
        else
            return (LoopStates)System.Enum.ToObject(typeof(LoopStates),(int)loopState - 1);
    }
}

```
探せない😭「FirebaseのAuthenticationのウェブ設定」から、SDKが探せない件について

この記事では、vueの勉強中に、「せっかくなので、firebaseと連携してみよう！」と思い本をみながら進めていたのですが、SDK設定の部分で「FirebaseのAuthenticationのウェブ設定」からapi等の情報を探していたけど、ない？？？となり調べた結果です。

## 結論
firebaseと接続するためのapi等の情報は、

設定したいアプリケーションの「設定→プロジェクトを設定」を選択する。
<img width="1440" alt="スクリーンショット 2020-06-07 18.44.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269844/e7e53d5e-9f5c-6127-d417-773f46c7f8f7.png">

下の部分に、「マイアプリ」の項目があり、そこに「Firebase SDK snippet」の中にあるapiキーとかいろいろある項目をコピーして使いましょう。
<img width="1440" alt="スクリーンショット 2020-06-07 17.27.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269844/e83525ad-355b-38f9-e2cd-e13ba63bc24e.png">



## 最後に
本の通り進めてたら、「ないんだけど😭」となったので調べました。
本が書かれた日から、月日が経ってfirebaseのUIが更新されているためだと思います。裏どりできたらよかったんですけど、とりあえず困っている人いるかも？とおもったので書いてみました。
【Ruby】paizaで頻出メソッドまとめてみた②

#前編
 - [【Ruby】paizaで頻出メソッドまとめてみた](https://qiita.com/umaibou1126/items/cd9192aa008e386d96de)

#参考文献

 - [Ruby　標準入力から値を受け取る方法](https://qiita.com/Hayate_0807/items/2e9705091b181a104621)

# ◆ eachメソッド + 配列

```
//サンプル用の配列作成
sample = [1,2,3,4]

//出力結果を格納する配列を作成
result = []

//オブジェクト：sample配列　
sample.each do |i|

//変数t：sample配列から変数tに格納される
if i == 1

//上記で作成した配列に格納する
 result.push(i)
end
```

# ◆ 入力値の受け取り方4選

```
//入力値が１行の場合　
input = gets.split.map(&:to_i)

//入力値を一括で配列格納
input = readlines.map &:to_i

//変数宣言 + 配列①
a,b,c = gets.split(" ").map &:to_i

//変数宣言 + 配列②　改行なし
a,b,c = gets.chomp.split(" ").map &:to_i

//入力値を改行なしで配列格納
input = readlines(chomp: true).map(&:to_s)
```

# ◆ include? / blankメソッド

 - **include?メソッド**：配列に``特定の値が存在するか``判定
 - **blank?メソッド**：``配列の中身が存在するか``判定

```
sample = ["a","b","c"]

//include?メソッド
if.sample.include?("a")
  puts "true"
end

//blank?メソッド
if.sample.blank?
  puts "true"
end

//include?メソッド + 変数
sample_num = 3

if.sample.include?("#{sample_num}")
  puts "true"
end
```

# ◆ each_consメソッド

```
//sample配列作成
sample = [1,2,3,4,5]

//each_consメソッドで分割
result = sample.each_cons(2).to_a

//eachメソッドで計算
result.each do |t|
   puts result[1] - result[0]
end
```
Pythonの仮想環境を作成してみる

# 仮想環境が必要な理由を理解して、実際に仮想環境を作成する
PythonでWeb情報をスクレイピングして情報を解析してゴニョゴニョしたいなぁと思っています。
それにあたり、まずは基本的な環境づくりについて書いていこうと思います。
間違いがあったらご指摘いただけると助かります。

## 仮想環境が必要なワケ
Pythonには外部ライブラリが豊富に揃っているがゆえに、１つのバージョンアップにより今まで動いていたアプリが動作しなくなるといったトラブルが起きる可能性があります。

とくに、複数のPythonアプリを１つの端末に同居させるような場合は注意が必要です。
複数のライブラリを使用している場合、バージョン違いによって依存関係が崩れて動作しなくなります。

こういった事態を招かないためにも、何かしらアプリを作ろうと思ったら仮想環境を作成し、そのアプリ用のライブラリとそのバージョンを管理することがトラブルを招かないコツです。
要はアプリ毎に仮想環境を作ると後々の管理が楽になります。

## 仮想環境の作り方
ここでは、下記の環境でおこないます。

- Python 3.7.4
- Windows10 home

仮想環境の作成には「venv」を使用します。

- コマンドプロンプトを開きます。
- cdコマンドで作業するディレクトリに移動します。
- 仮想環境作成コマンドを実行します。<br>※env02は仮想環境名で任意です。

```
python -m venv env02
```    

- 仮想環境をアクティベートします。

```
c:\venv\env01\Scripts\activate
```
## 仮想環境にjupyter notebookをインストールしてみる
ここではjupyter notebookをインストールしてみます。

- jupyterをインストール

```
pip install jupyter
```

- 仮想環境上（venv）でjupyter notebookを実行するために、kernelをインストール

```
pip install ipykernel
ipython kernel install --user --name=env02
```

- jupyter notebookを起動

```
(env02) C:\venv\jupyter
```

- jupyter notebookが起動したらカーネルを作成してアクティベートした仮想環境名に変更する。
![jupyter01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/476e21f6-e9fb-8da1-5769-8e336bc0e390.png)

- カーネルが変更されたら、対話式でコードを書いてみます。
![jupyter02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/2394b75b-5a28-66b3-b29a-847f5d73a667.png)

うまく実行されているようです。
ということで、Pythonで何か作ろうと思っている方は、あとでライブラリやバージョン依存でトラブルが起きる前にしっかりと仮想環境を使いこなしましょう。