OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS7 SSH接続

####SSHとは？？
SSH = `S`ecure　`SH`ell
ネットワークに接続された機器とデータを暗号化して遠隔操作するために使用するアプリケーション層のプロトコル。
サーバー側ではSSHデーモン、クライアント側ではSSHクライアントを使用して通信する。
SSHにはSSHバージョン1とSSHバージョン2がある。SSHバージョン２の方が暗号化の安全性が高いと言われていてSSHバージョン２を使うのが主流のようです。
今回はSSHバージョン2、RSA公開鍵暗号方式で簡素にリモート接続する方法を記述します。

####公開鍵暗号方式とは？
暗号化されて対になっている鍵で認証を行う。サーバー側に「公開鍵」を設置してクライアント側で持つ「秘密鍵」でログインする。公開鍵Aがサーバーに設置されていたら対となる秘密鍵Aがログインに必要。別の秘密鍵Bを持っててもサーバーの公開鍵Aからはログインできない。秘密鍵Bでログインするなら対となる公開鍵Bがサーバにないとダメ。



#### 鍵の作成
クライアント側で鍵を作る。ユーザーのホームディレクトリで作業。

```
mkdir .ssh
chmod 700 .ssh 
cd .ssh
```

ssh-keygen コマンドで鍵を作成する。

```
ssh-keygen -t rsa -b 4096 -C "sample@sample.com" 
```
-t rsa : SSH2のRSA公開鍵暗号方式
-b : バイト数。指定なしだと2048バイト
-C : コメント
オプションなしでも作成可能。

```
$ ssh-keygen　(オプションなしで作成)
Generating public/private rsa key pair.
Enter file in which to save the key (/home/guest1/.ssh/id_rsa): ⇦ Enter押す（鍵の保存場所）
Enter passphrase (empty for no passphrase): ⇦ Enter押す(パスフレーズ設定)
Enter same passphrase again: ⇦ Enter押す(パスフレーズ確認)
Your identification has been saved in /home/guest1/.ssh/id_rsa.
Your public key has been saved in /home/guest1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:TZ6gO14OKhQW3pjmf7IbZzZ83PPwXbkRG+cwnnKJK/k guest1@Cliant
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|  .              |
| . =    . .      |
|  B .  . = .     |
| + .  . S +   oo.|
|  o  . o .   o **|
| . .. X + +.o =+o|
|  . oB.B  o= = .o|
|   .+=. .  oE .. |
+----[SHA256]-----+
```
id_rsa(秘密鍵)とid_rsa.pub(公開鍵)ができた。秘密鍵の権限を変更。

```
chmod 600 id_rsa
```

####サーバーに公開鍵を設置
今度はサーバー側のホームディレクトリで作業。

```
mkdir .ssh
chmod 700 .ssh
cd .ssh
vi authorized_keys
```
authorized_keysにクライアント側で作成したid_rsa.pub(公開鍵)の内容をコピペする。

```
chmod 600 authorized_keys
```
autorized_keysの権限の変更。

####接続する

```
ssh ユーザー名＠ホスト名 or IPアドレス
```
.sshやauthorized_keysが適切な権限じゃないと接続できないので注意。
細かい設定をするファイル → /etc/ssh/sshd_config
OpenCV の Video Capture で 任意のフレームレートで処理する

動画をフレームごとに処理できる cv2.VideoCapture ですが、ffmpeg とちがって切り出すfps（1秒あたりに切り出すフレーム数）を引数で指定できません。
動画によって1秒あたりの読み込む枚数が自動で決定されるからです。

（もしできたら僕の不勉強ですのでコメントお願いします）

そこで以下のコードで、任意のfpsで処理することができます。

```python
import cv2

cap = cv2.VideoCapture('./video.mp4') #読み込む動画のパス
read_fps= cap.get(cv2.CAP_PROP_FPS) #cv2.VideoCaptureが動画1秒あたり何枚を読み込むのかを取得（これは自動で設定される）

print("もとのfps" + str(read_fps))

fps = 5 #希望のfps（動画1秒あたり何枚切り出して処理したいか）
thresh = read_fps / fps #フレーム何枚につき1枚処理するか

frame_counter = 0

while True:
    # 1フレームずつ取得する。
    ret, frame = cap.read()
    if not ret:
        break

    frame_counter += 1

    print("frame_count" + str(frame_counter))

    if (frame_counter >= thresh): #フレームカウントがthreshを超えたら処理する
      print("処理")
      frame_counter = 0 #フレームカウントを０に戻す

    key = cv2.waitKey(30)
    if key == 27:
        break
cap.release()
```

>もとのfps30.0
frame_count1
frame_count2
frame_count3
frame_count4
frame_count5
frame_count6
処理
frame_count1
frame_count2
frame_count3
frame_count4
frame_count5
frame_count6
処理
frame_count1
frame_count2
frame_count3
frame_count4
frame_count5
frame_count6
処理
frame_count1
frame_count2
frame_count3
....
....

もとのfpsが３０なので、6枚に1枚の割合で、1秒に5フレーム処理されています。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
授業8回目：rake



# 参考サイト

[チャート式ruby-appendix-IV(rake)](https://qiita.com/daddygongon/items/1c2d6d2895333ccf5e62)


# rake

README.org の方にも書いてあるが、Github上にプログラムをあげるためだけでも多くのコマンドを必要とする.
rake はそういったコマンドを覚えさせて1コマンドで実行できるようにする.
githubへの共有をrakeにやらせる.
まずはRakefileにtaskを記入していく. まずはファイル作成.

```ruby
emacs -nw Rakefile
```

できたファイルに以下を書き込む.

```ruby
desc 'git push'
task :push do
  p comm = "git add -A"
  system comm
  p comm = "git commit -m 'hoge hoge'"
  system comm
  p comm = "git pull origin main"
  system comm
  p comm = "git push origin main"
  system comm
  exit
end
```

上記のプログラムであれば、push とコマンドを打てば動作する（はず）.


# note

達人のプログラマはコマンドを覚えているのではなく忘れそうな事はメモしたり簡略化したりしてる.
rake なんかはその1例みたいなものなのだとか.



------
 - **source** ~/grad_members_20f/members/batamon-427/task8.org
初めてのGraphQL〜GraphQLって何編〜

今日の当番：てん

最近会社の大先輩におすすめされてGraphQLの本を買いました。
初めてのオライリー！

ということで、GraphQLについて学んだ軌跡を残していきたいと思います。



## GraphQLとは
GraphQLってなんやねん。

GraphQLは、APIのための問い合わせ言語です。
RESTと比較されることが多いように思います。
通信プロトコルは指定されていませんが、一般的にはHTTPが使われているそうです。



## GraphQLを使うメリット
- GraphQLを使うと、１回のHTTPリクエストで複数の異なる種類のデータを受け取ることが可能に
- RESTなどのように
    - レスポンスのデータを使ってさらにリクエストを送る、といったことを何往復も繰り返す必要がなくなる
    - 過剰なデータ取得を抑えられる
    - クライアントの変更に伴う新たなエンドポイント作成の必要がなくなる（GraphQLは基本的に単一のエンドポイント ）

## GraphQLの誤解
GraphQLは、<b>宣言型</b>データ取得言語であると誤解されがちですがそれは違います。
これはつまり、GraphQLの開発者は、<b>どのような</b>形でデータを渡すかを重要視して、<b>どうやって</b>それらのデータを取得するかを蔑ろにしているという意味ですが、本当に違います。

## GraphQLのクライアント
開発チームの作業効率向上＆アプリケーションのパフォーマンス向上を目的に作られた、ネットワークのリクエスト、データのキャッシュ、ユーザーインターフェースへのデータ注入といった処理を肩代わりしてくれる便利ツールが存在します。

特に注目されているのが、RelayとApolloです。
RelayはFaceBookが開発したクライアントで、ReactとReact Native上で動作するもので、Apolloはどこでも動きます。


これからたくさん触っていきたいですね！

おわり
メルマガの心得

今日の当番：ちむ

いろんなメーラーに対応するのは骨が折れます。
強い心をもって作成しましょう。

メディアクエリと縁を切る
-
メルマガにおいて、メディアクエリは信用なりません。
特に、スマホのブラウザでメーラーを開いたときなど、
「そうじゃない」ってなることが多いです。
なるべくレスポンシブしなくて済むような、シンプルなデザインにするといいでしょう。

Gmailの102KB問題
-
Gmailでは、メールの容量が102KBを越えると省略表示されます。
まあそれのせいでデザインが崩れるよ〜〜〜〜なんてことはたまにしかないのですが、
デザインの他に１つ困る場合があります。
それは<b>開封タグを```</body>```の直前に置いているとき</b>です。

メールの開封率なんかを測るためにちっこい画像を配置して、その画像urlにリクエストが飛ぶことで開封したかどうかをカウントするのはメルマガでよく見かける手法です。
しかし、この開封計測画像を```</body>```直前に置くと、Gmailで省略表示されたときに、<b>メールは開いているけど全体表示がされていないから開封にカウントされない</b>事象が起こります。

一大事ですね。

開封タグをつける場合は```<body>```開始タグの後ろにつけてあげましょう。


marginに潜む罠
-
web画面では当たり前のように使うmargin。
marginなしでは生きていけないほど重要なプロパティですが、
メルマガではたまに、無効化されるのです！！！！！

私が出会った事象は、yahooメールでした。
ある日突然yahooメールだけ余白がなくなってしまったのです。
とんでもねえな。

こんな恐ろしい体験をしたくないかたは、ぜひスペーサー画像を使ってあげてください。
1px × 1pxの透明な画像を使って空白をあけてあげることで、
余白のことを心配せず、健やかな毎日を送れるようになります。アーメン。


## まだ終わらない戦いの日々
随時、恐怖体験を追加していきます。
皆様のメルマガ作成に、健康と癒しを捧げて今日も元気に生きていきます。
PDFium の Windows DLL をビルドする

# PDFium とは
[PDFium](https://pdfium.googlesource.com/pdfium/) は chrome で利用されている PDF レンダリングエンジンです。
[Apache ライセンス](https://pdfium.googlesource.com/pdfium/+/refs/heads/master/LICENSE)なので、**商用利用** も可能です。

レンダリングエンジンですが、新規PDFの作成、PDFのマージ、PDFのページ追加／削除なども可能です。


# ビルド環境
Windows 10 Pro バージョン2004
Visual Studio 2019
Windows SDK 10.0.19041.0

# ビルド手順
一応、この手順でビルドできましたが、冗長な部分があるかもしれません。

## depot_tools ツールのダウンロード
 [depot_tools](https://storage.googleapis.com/chrome-infra/depot_tools.zip) をダウンロードして、解凍します。

## depot_tools ツールフォルダの python_bin_reldir.txt を編集
各自の python 実行ファイルがある場所を示すようにします。
私は anaconda でインストールしているので、以下のようにしました。
>..\\..\\Anaconda

## 環境変数の追加

- Path 環境変数に depot_tools のパスを追加
- DEPOT_TOOLS_WIN_TOOLCHAIN=0
- vs2019_install=C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional

## PDFium ビルドフォルダの作成
コマンドプロンプトを開き、新規フォルダを作成して、そこに移動します。

```bat
c:\
mkdir hoge
cd hoge
```

## gclient の実行

まずは引数無しで

```bat
gclient
```

次に引数ありで

```bat
gclient config https://pdfium.googlesource.com/pdfium.git
```

生成された .gclient ファイルを開き、"managed" を False にして、保存します。

最後に

```bat
gclient sync -vv
```

最後は少し時間がかかりますので、お風呂でも入るか、テレビでも見ていてください。

## 作成された pdfium フォルダに移動

```bat
cd pdfium 
```

## BUILD.gn の変更

以下を修正し、保存します。（右が修正後）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30578/3ebf4d3b-d183-9e56-9924-575344818d36.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30578/96b9e89b-55c1-dce6-2da9-eb8119961828.png)

## public\fpdfview.h" の変更

以下を修正し、保存します。（右が修正後）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30578/6d51049c-59e7-f905-1ce0-1555bb21f4a1.png)


## ビルドファイルの生成

out\Custom_x86_Release 以下にビルドファイルを生成します。フォルダ名はお好きに指定してください。
以下は x86/Release の設定です。x64 にしたり、debug にしたい場合、その他オプションは該当箇所を書き換えてください。

```bat
gn gen –-ide=vs out\Custom_x86_Release -–args="target_cpu=\"x86\" pdf_is_standalone=true is_component_build=false is_official_build=true is_debug=false pdf_enable_xfa=false pdf_enable_v8=false chrome_pgo_phase=0 pdf_use_skia=false pdf_use_skia_paths=false clang_use_chrome_plugins=false"
```

## ビルド

out\Custom_x86_Release に all.sln があるので、Visual Studio で開いて、pdfium を右クリックからビルドすれば、DLLが生成されます。
設定にも拠りますが、ビルドにもかなり時間がかかります。

私は、Visual Studio からよりも手軽にビルドできる、以下のコマンドを実行しました。

```bat
ninja -C out\Custom_x86_Release pdfium

# 以下のような出力でビルドが完了します。
ninja: Entering directory `out\Custom_x86_Release'
[981/981] LINK(DLL) pdfium.dll pdfium.dll.lib pdfium.dll.pdb

```

## DLL 利用時
C/C++ | 全般 | 追加のインクルードディレクトリ : pdfium\public
C/C++ | プリプロセッサ | プリプロセッサの定義 : FPDFSDK_EXPORTS
リンカー | 入力 | 追加の依存ファイル：pdfium.dll.lib

レンダリングで必要なヘッダは以下です。

```cpp
#include "fpdfview.h" // pdfium\public
```


## Tips

できあがった sln ファイルを開いて、Visual Studio 上 でビルドの構成を新規に作ろうとしたら、単に時間がかかっているだけなのか、固まってしまいました。
なので、新規構成を作りたければ、```gn gen``` のコマンドで出力フォルダを変えて、```--args``` の内容も変えて、別なフォルダに作るようにしましょう。


## 参考URL

[PDFium を Windows on ARM (ARM64) 向けにビルドする - しばやん雑記](https://blog.shibayan.jp/entry/20200701/1593535393)

[Pre-compiled binaries of PDFium](https://github.com/bblanchon/pdfium-binaries)
GridLayoutで、DefineListをいい感じに書いてみた

# 前おき

お問い合わせフォームとか会社概要の会社情報の部分とか、
あとグルメサイトとか予約サイトの店舗詳細みたいなところのやつとかもそうかな。
ああいった、定義リストみたいな感じのものって、
みんなどんなHTML要素使ってるんですかね～？


ちなみにわたしは、フォームは`div` ~~地獄~~ & `legend` `label`を組み込んでいく派
会社情報みたいな定義リストっぽいものは`dl dt dd` 派（そのままや）。
`table`は本当の表に対してのみ使いたいものです。（表と定義リストの差ってなんでしょう？）
~~…なつかしいな～　ガラケーサイト延々の`tr`積んで作ってたの…~~

ところで、1つのサイトに上記で書いたような定義リストというか、2カラムリストがいくつか必要になってきたとき、
タイトル部分の幅に困ったことありませんか？

デフォルトで設定していたカラム幅が、なんかここではしっくりこない…みたいな。
…わたしがヘタなだけかな……。

そんなこんなで、これをこうしたらなんとかなるんやないか？と ふと思いついたからやってみたよ。

# 要件

 - 2カラムレイアウト
 - タイトル部分のコンテンツ量にあわせて、幅をいい感じに可変
 - 項目の数はその時によるので、数には縛られない

という内容のもと、GridLayoutを使って組んでいきます。
HTMLは`dl dt dd`。　同じコンテナ-コンテンツ関係を作れれば、なんでもいいのですが、
`li`の子要素に`div * 2`とか、`tr th td` とかの組み方だと1項目のときしかタイトル部分の幅がいい感じにできないな…。


## 注意

GridLayoutを使います。が、使い方的にInternetExplorerではバグがあります。
1カラムで表示になるので、そんなに困ったことにはならないですが、
2カラム表示にはならないです。

# やり方

なにはともあれHTMLを作ります。

```html

<dl>
  <dt>項目1</dt>
  <dd>項目1の内容</dd>
  <dt>項目の2個め</dt>
  <dd>項目2の内容</dd>
  <dt>項目3もつけておいたんだってばよ～</dt>
  <dd>項目3の内容</dd>
</dl>
```

項目名部分がいろんな文字数ですね。

で、CSSの設定

```css

dl {
  display: grid;
  grid-template-columns: minmax(min-content, 23%) auto;
}
``` 

`grid-template-rows`　を書かないことで項目数に縛られなくしました。
知らないだけで、grid のコンテンツ個数に縛られないやり方あるのかな？

※ちなみに、前述のIE NGはここに由来します。
IEのGridLayoutは
`grid-template-columns` `grid-template-rows` が必須となります。


そして、ポイントは `minmax(min-content, 23%)`。
（並び替えをしていないので、）奇数番目のコンテンツ（＝`dt`）の幅が、

 - 最小: 全該当コンテンツの最小長
 - 最大: コンテナの23%幅

になります。


# あとがき

さてさて、いくつかの定義リストには適応させてみましたが、
拡張してく中で、どうなのですかね？不便がでてきたらまた考えましょう。


この仕様を適応させる前は
項目の幅を固定にしたり、リストごとに設定して、
FlexLayoutにして各項目ごとにコンテナを持たせてやってました。

```html
<dl>
  <dt>項目1</dt>
  <dd>項目1の内容</dd>
</dl>
<dl>
  <dt>項目の2個め</dt>
  <dd>項目2の内容</dd>
</dl>
<dl>
  <dt>項目3もつけておいたんだってばよ～</dt>
  <dd>項目3の内容</dd>
</dl>
```
```css

dl { display: flex; }
dt { width: 10em; }
dd { flex: 1; }
```

どっちが使いまわしいいかな～？


ということで、
なんか、こんな考え方もいけるのかな？というご参考になれば。
授業10回目：Recursion(再帰)



# 参考サイト

[チャート式ruby-V(Recursive Fibonacci)](https://qiita.com/daddygongon/items/1bb27b8920c201d5c520)


# 再帰(Recursive)とは

関数内の振る舞いのうち、自分自身を呼び出す処理のこと. 


# お題：フィボナッチ数列

フィボナッチ数は、以下の式に基づいて定義される. 
参考：[wikipedia:フィボナッチ数](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0)

    fib(n) は n 番目のフィボナッチ数を表すとする
    ・ fib(0) = 0
    ・ fib(1) = 1
    ・ fib(n) = fib(n-1) + fib(n-2)

n = 0 ～ 10 番目のフィボナッチ数を並べると 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55

こうしてできるフィボナッチ数列を再帰処理で求める


# 実装例

fib(n) = fib(n-1) + fib(n-2)　のルールでは求められない n = 0,1 から求めよう

    require './assert_equal.rb'
    
    def fib(n)
      if n = =0
        return 0
      end
      if n = =1
        return 1
      end
    end
    
    puts assert_equal(0, fib(0))
    puts assert_equal(1, fib(1))

第9回の assert\_equal が再登場. 1行目の宣言により呼び出し可能になる. 
今回の assert\_equal のお仕事は関数 fib がちゃんと動いているかのテストである. 

assert\_equal の重複が気になるので配列にしてしまう. (リファクタリング)

```ruby
test = [[0,0],[1,1]]
test.each do |index, expected|
  puts assert_equal(index, fib(index))
end
```

記述を綺麗にしつつ、fib(n) = fib(n-1) + fib(n-2) の部分を作る.

```ruby
require './assert_equal.rb'

def fib(n)
  return 0 if n==0 
  return 1 if n==1
  return fib(n-1) + fib(n-2)
end

test = [[0,0],[1,1],[2,1],[3,2],[4,3],
	[5,5],[6,8],[7,13],[8,21],[9,34]]
test.each do |index, expected|
  puts assert_equal(expected, fib(index))
end 

```

出力結果はこんな感じ

```ruby
["expected", 0]
["result", 0]
true

["expected", 1]
["result", 1]
true

["expected", 1]
["result", 1]
true

["expected", 2]
["result", 2]
true

["expected", 3]
["result", 3]
true

["expected", 5]
["result", 5]
true

["expected", 8]
["result", 8]
true

["expected", 13]
["result", 13]
true

["expected", 21]
["result", 21]
true

["expected", 34]
["result", 34]
true

```


# note

・再起はあんまりやりすぎると処理が重くなったり無限ループになったりするので気を付ける.



------
 - **source** ~/grad_members_20f/members/batamon-427/task10.org
踏み台で sudo -u しているsshでの ssh_config

# やりたいこと

今回想定する接続の流れ

手元(local/mac) -> 踏み台(bastion_host/linux) -> 最終ターゲット(target_host/linux)

以下のようなワンライナーを.ssh/configで表現したい

```
ssh -t foo@bastion_host -p 22 sudo -u bar ssh target_host
````

制約として、  `bastion_host` に置いてある `target_host` の鍵を localにもってこれないとする。

この制約があると、すんなり .ssh/config には記載できない...。

# 環境
- local
  - OpenSSH_7.9p1, LibreSSL 2.7.3

# どうするか

- helper scriptでなんとかする（[参考](https://qiita.com/komazarari/items/d32581c82d9af1223436))
  - .ssh/config に設定をまとめたいがそれはできない
- `RemoteCommand` に記述する（今回やってみる）
  - .ssh/config に設定をまとめられる


#  `RemoteCommand` に記述する

具体的には、.ssh/config に以下のように記載する

```
Host foobar
  HostName bastion_host
  RequestTTY force
  User foo
  Port 22
  RemoteCommand sudo -u bar ssh -t target_host
```

そして以下のようにsshすればOK

```
$ ssh foobar
```

# `RemoteCommand` とはなにか

- OpenSSHの7.6で入った比較的新しい機能（[参考](https://www.openssh.com/txt/release-7.6))
- サーバーへの接続に成功した後、リモートマシンで実行するコマンドを指定するものです。（[参考](http://man.openbsd.org/ssh_config#RemoteCommand))
Pass the Ticket攻撃とは

【Pass the Ticket攻撃とは？】

窃取したドメイン管理者権限で不正なチケットを作成し、
そのチケットを悪用して不正ログインすること。
なりすまし攻撃の1種。
正規ユーザになりすますため検知されにくい。

チケットを利用するタイプの認証（ケルベロス認証）の悪用。
全ての認証でチケットが利用されるわけではないので、
数あるネットワーク認証の中にある１つのタイプに対する攻撃と捉える。

■ケルベロス認証とは？
一度認証に成功するとチケットを発行し、
以降はそのチケットを使って認証なしにサーバ（サービス）が利用できるようになる認証のこと。
その利便性を逆手に取って不正行為を行うのがPass the Ticket攻撃といえる。

このチケットを利用するというのが、ケルベロス認証の最大の特徴とのこと。
ちなみにケルベロスとはギリシャ神話に登場する、３つの首を持つ冥府の番犬。

■ドメインとは？
インターネット上の住所。
webサイトがどこにあるのかを判断する情報として利用する。
webサイトURLやメールアドレスで使われている。
※https://○○●○.com　→○○●○.com　この部分
はじめてのLogiX（HTTP GET/POST編）

※手順については、後日、更新します。

# はじめに
みなさんNeosVR、楽しんでますか？

日々いろんなものがユーザによって制作されて、公開されているので、最初は遊んでいるだけだった人も、自分でも何か作ってみたいってなぁなんて、考えてる人いますよね？

僕もその一人で、LogiXを学んで何かやりたいなぁと思ったものの、半年ぐらい放置していたら、気が付けば、カジノができていたり、麻雀が遊べるようになっていたりして、ビックリしています。
しかもこれ、他のユーザのみなさんが自分で作ってるんですよね！

そこで、何か作ってみたいと思ってしまった貴方の「LogiXって、HTTP通信もできるって聞いたのですが、どうしたら良いの？」っていう疑問にお答えするために、
つい２週間ぐらい前までは、なんもわかっていなかった@Garyumaruが、
どうやってLogiXを学んでいるのか、その一例をご紹介していきます。

# 対象
これを理解することで、LogiXを使って、サーバーとHTTP通信（GET/POST）ができるようになります。

#LogiXとは何か
そもそもNeosVRのLogiX、なんもわからんという方は、先に次の投稿などを見ておくと良いかと思います。

@0_VEX_0さんの【Neos VR】LogiXのはじめかた
https://qiita.com/0_VEX_0/items/650d8c6ad346a2a6b96c

@GaryumaruのはじめてのLogiX
https://qiita.com/garyumaru/items/10c8948821b43016451b

# HTTPとは
HTTP 【 HyperText Transfer Protocol 】
http://e-words.jp/w/HTTP.html

HTTPとは、WebサーバとWebクライアントの間でデータの送受信を行うために用いられるプロトコル（通信規約）です。
HTTPリクエストとHTTPレスポンスをやりとりします。
GET/POSTといったHTTPメソッドとパラメータをHTTPリクエストとしてサーバーに送り、サーバーからは処理結果をHTTPレスポンスとして受け取ります。

# ProbablePrimeさんの動画を見よう！（GET編）
Neos VR Tutorial: HTTP Pt.1 - GET String (約9分)
https://www.youtube.com/watch?v=zyJlzayp7Q0

# ProbablePrimeさんの動画を解析しよう！（GET編）
### GETリクエストで使用するURI（接続先）
https://i.probableprime.co.uk/Tutorials/hello.txt
※自分でHTTPサーバーを用意できた人はここを自分のURIに置き換えると良い
### 何をしてるの？
指定されたURIにGETリクエストを送り、ファイルの内容を表示している。
### 作業手順


# ProbablePrimeさんの動画を見よう！（POST編）
Neos VR Tutorial: HTTP Pt. 2 - POST String (約9分30秒)
https://www.youtube.com/watch?v=eujuGf8ddCk

# ProbablePrimeさんの動画を解析しよう！（POST編）
### POSTリクエストで使用するURI（接続先）
https://ptsv2.com/t/NeosTutorial/post
※自分でHTTPサーバーを用意できた人はここを自分のURIに置き換えると良い
### 何をしてるの？
1) 指定されたURIにPOSTリクエストを送り、ファイルのURIを取得する。
2) 取得したURIにGETリクエストを送り、ファイルの内容を表示している。
### 作業手順

# おわりに
以上で、LogiXを使って、サーバーとHTTP通信（GET/POST）ができるようになりました。

あとは自分でサーバーを用意することができれば、複雑な処理をサーバー側で行い結果を取得したり、ユーザデータをデータベースに保存して管理したりできるようになりますね！

サーバーとの通信にはもう一つの方法があり、WebSocketによる通信について知りたい人は、こちらの記事をどうぞ！
はじめてのLogiX（WebSocket編） https://qiita.com/garyumaru/items/a6860409996f8eaa16fd

ProbablePrimeさんの動画、すごく良いです。勉強になります。
Tips: YouTubeの字幕をONにすると、完全ではないけど、英語字幕をつけてくれるので、何て言ったのかわかりづらいときに助けになります。
選択されているOptionに設定されているカスタム属性の値を取る方法

datesetで指定したら取れるかと思ったが、カスタム属性の値を取るには少し工夫が必要だった。


```html
<select id="pet" name="pet">
    <option value="tamajirou" data-age="2" selected>たまじろう</option>
    <option value="tamao" data-age="3">たまお</option>
    <option value="tamako" data-age="5">たまこ</option>
</select>       
```

```javascript
//対象のSelect
const pet = document.getElementById('pet');

//選択されているoptionを抽出
const selectedOption = Object.values(this.staff.options).find(option => option.selected === true);

//たまじろうのageが出力される
console.log(select.dataset.age)
```
Windows10にGitを導入

Windows10にGitを導入するのでメモします．
# 環境
* Windows10 Pro(64bit)

# Gitのダウンロード
1. Gitの[Windows10用ダウンロードサイト](https://gitforwindows.org/)にアクセス  
2.  **Download**をダブルクリックでダウンロード(今回はver2.29.2.3でした)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/0dd34698-99e2-992e-3e84-503381dee074.png)


# git for windowsのインストール
1. ダウンロードしたexeファイル(Git-2.29.2.3-64-bit.exe)をダブルクリックで実行．
1. デバイスに変更を加えることを許可．
1. デフォルトのままNextをクリック．
![スクリーンショット (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/62f56497-27dd-c412-b81d-3ebcb31cc197.png)
1. デフォルトのままNextをクリック．
![install2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/87886859-7574-8099-b319-a9ad59ef0c43.png)
1. デフォルトのままNextをクリック．
![install3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/78c2e9ed-2955-0bb8-35e4-cefeb04eb2ce.png)
1. デフォルトのままNextをクリック．
![install4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/b4f6ea6f-10fa-2802-2dcf-00e9910e2b4f.png)
1. ドロップダウンでエディタを選択してNextをクリック．今回はVScodeを選択しました．
![install5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/c4a6b916-b789-8f8f-dce3-70b027729f23.png)
1. デフォルトのブランチ名を選択してNextをクリック．GitHubリポジトリではmainブランチがデフォルトになったため，下を選択し「main」を指定しました．
![install6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/f1178b4d-8dce-484a-2097-6c5ec70cf72d.png)
1. コマンドプロンプトでGitを使いたいので，デフォルトのままNextをクリック．
![install7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/4e44acc0-cbb1-b225-cc6c-6cc391a28fd4.png)
1. デフォルトのままNextをクリック．
![install8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/3a184653-21c0-bbd3-7dca-0d4329394a5b.png)
1. 一番下を選択してNextをクリック．
![install9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/43840a4d-34b0-2dd0-a076-60a5acc46aeb.png)
1. デフォルトのままNextをクリック．
![install10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/d421693e-4e99-7910-b961-7ef5d29ee27a.png)
1. デフォルトのままNextをクリック．
![install11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/616348b2-95ec-39fa-9f04-d26f606068a8.png)
1. 真ん中を選択してNextをクリック．
![install12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/3697e1a6-f136-b6d4-9fb7-e084b5f14882.png)
1. デフォルトのままNextをクリック．
![install13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/34f93d0e-d623-dcbb-bbc7-b968f7ee9264.png)
1. こちらはチェックを入れずにinstallをクリック．
![install14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/e96b0caf-9da8-3639-e8d2-17cab15e5ae8.png)
1. インストール完了
![install15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625773/f7440295-c25d-8a66-c6f8-37bd156fa837.png)
1. コマンドプロンプトで  
```
$ git --version
```  
等でエラーが出なければOK．

インストール時のそれぞれの設定については以下の記事を参考にしました．
[Windows10にGitをインストールして初期設定する](https://qiita.com/taketakekaho/items/75161e1273dca98cb4e1)
[GitをWindowsにインストールする方法｜Git For Windows 2.28.0](https://blog.totsugeki.com/post-279/)

# ユーザー情報の設定
以下のコマンドでユーザー情報の設定をします．

```
$ git config --global user.name "user name"
$ git config --global user.email "user email"
```
【#PowerApps】Power Apps の Patch で SQL Database とかに NULL を入れる方法 【Tips】

# 概要

Power Apps の Patch 関数でカラムに NULL を入れる方法の解説です。


# 追加は問題なしただし更新は普通にやるとできない

Patch で NULL を入れようと例えば以下のような式を書きます。

```
Patch(
    '[dbo].[sample]',
    Defaults('[dbo].[sample]'),
    {
        hoge: Blank(),
        update_datetime:Now()
    }
)
```

この場合 追加になるのでカラム（列）を指定しなくても NULL を入れることはできます。例えば以下のような式になります。

```
Patch(
    '[dbo].[sample]',
    Defaults('[dbo].[sample]'),
    {
        update_datetime:Now()
    }
)
```

この要領で**更新**を書こうとすると以下のようになります。

```
Patch(
    '[dbo].[sample]',
    Gallery1.Selected,
    {
        hoge: Blank(),
        update_datetime:Now()
    }
)
```
しかし、この方法では NULL が入ることはなく、何も更新されません。

# 解決策

実は式は正しく、 Power Apps の設定が漏れていることで、 NULL を入れることができません。
ファイル→設定→詳細設定から実験的な機能の「数式レベルのエラー管理」を ON にします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/4e27da63-c137-e6c3-5553-f66696c2d2ed.png)


このように変更すると、先ほど書いた式で 指定したカラムに対して NULL を入れることができるようになります。


# 注意点

実験的な機能の１つなので急に利用できなくなる可能性がありますのでご注意ください。
（というか、ほかに方法ないのかな？）

# 参考

- [Patch a NULL value](http://powerappsexamples.com/patch-null-value/)
【初学者必見】 投稿時刻の表示を日本時刻に変更してみた 【l（エル）メソッド】

Railsで作ったアプリのデータベースから情報を引っ張り出してcreated_atやupdated_atを出力すると日本時刻ではありません。
そのため、
1. 設定ファイルで時刻を日本時刻に変更する
2. l(エル)メソッドを用いて時刻を表示する
を実行し、直していきます。

# 1. 設定ファイルで時刻を日本時刻に変更する
その前に↓
> ## 設定ファイルってなに？？
>railsでは、configディレクトリにて実行環境に関する物を管理しています。
>configディレクトリのapplication.rbファイルでは、そのRailsアプリケーションの開発環境すべてにおいて共通となる設定が記述されています。

まず、config/application.rbファイルを開き、以下の設定を追加します。

```ruby:config/application.rb
module ”アプリ名”
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    config.i18n.default_locale = :ja   # ←←←←←←←←この行を追加
    config.time_zone = 'Tokyo'         # ←←←←←←←←この行を追加

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end
```

次に、config/localesディレクトリに「ja.yml」というファイルを作成して、以下のように記述します。

```yaml:config/ja.yml
ja:
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"
```

これで時刻の変更の設定が終わりました！

# 2. l（エル）メソッドを用いて時刻を表示する
その前に↓
> ## l（エル）メソッドとは
>l（エル）とは英語でlocalizeの頭文字からとって来ています。
>"localize" 即ち、現地に対応させるっていう意味ですね。
>このメソッドは日付や時刻を表す際に使いますが、指定した現地時間に対応させる事ができます！

以下のようにviewファイルに書いてみます。

```erb:app/views/reviews/index.html.erb
<h4 class="title is-2 is-centered has-text-white">クチコミ</h4>
<% @reviews.each do |review| %>
<div class="card review_card mb-4">
  <header class="card-header">
    <div class="card-header-title">
      <%= review.user.nickname %>
    </div>
  </header>
  <div class="card-content pt-2">
    <div class="content">
      <div class="star-rating mb-4">
        <div class="star-rating-front" style="width: <%= review.score * 20 %>%">★★★★★</div>
        <div class="star-rating-back">★★★★★</div>
      </div>
      <%= simple_format(review.content) %>
      <div class="has-text-right is-italic" ><%= l review.updated_at %></div>   #←←←←←←←←←←←←←←ココ
    </div>
  </div>
  <% if user_signed_in? %>
    <%if current_user.id == review.user_id %>
      <footer class="card-footer">
        <%= link_to '編集する', edit_agent_review_path(review.agent_id, review.id), method: :get, class: "card-footer-item" %>
        <%= link_to '削除する', agent_review_path(review.agent_id, review.id), method: :delete, class: "card-footer-item" %>
      </footer>
    <% else %>
      <footer class="card-footer">
        <a href="#" class="card-footer-item">コメントする</a>
      </footer>
    <% end %>
  <% end %>

</div>
<% end %>
```
ただ、<%= l review.updated_at %>のように出力したい変数の前に”l”(エル)を加えるだけ！
ちゃんとサーバーを再起動してくださいね！
![スクリーンショット 2020-12-24 18.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914577/617c8d94-0ed1-9cb2-dda1-2218677ae99e.png)

l（エル）メソッドを使う事によって簡単に、あらかじめ設定した日本時刻のフォーマットを通して、投稿時刻の日本時間への修正ができました。


# 最後に
私の初めてのQiitaの投稿はいかがでしたでしょうか。
間違っている点やわかりにくい点があったらお気軽に教えてください！
では次回の投稿でお会いしましょう。
vue.jsでGoogle Fontsの日本語webフォントを適用する

vue-cliで作成したwebpackテンプレートでgoogleの日本語webフォントを使えるように設定します。


## 好きなフォントを見繕う
Google Fonts
https://fonts.google.com/
https://googlefonts.github.io/japanese/

上記サイトから使用したいフォント名をコピーしてきます。
例では"M PLUS Rounded 1c"を選択。

## いつもの


```
npm i google-fonts-webpack-plugin --save-dev
```

または

```
yarn add google-fonts-webpack-plugin --dev
```

## webpack.base.config.jsに追記

```
const GoogleFontsPlugin = require("google-fonts-webpack-plugin")

module.exports = {
    "entry": "index.js",
    /* ... */
    plugins: [
        new GoogleFontsPlugin({
            fonts: [
                { family: "M PLUS Rounded 1c" }
            ]
        })
    ]
}
```

使用したいフォントを指定します。

これでプロジェクト内でGoogle Fontを使用できるようになりました！

## 使ってみる
適用したい箇所にスタイルを指定するだけ。

```
<style>
#app {
  font-family: 'M PLUS Rounded 1c';
</style>
```

![vue.png](https://qiita-image-store.s3.amazonaws.com/0/169464/13a86805-dcf2-b480-8476-706269e8ede5.png)

できました！

参考：Google Fonts Webpack Plugin
https://github.com/gabiseabra/google-fonts-webpack-plugin
[Windows]ディレクトリ毎の大文字小文字を区別する設定をプログラムから行う

Windows 10上のNTFSでディレクトリ毎の大文字小文字を区別する設定を取得・設定する場合、`fsutil file queryCaseSensitiveInfo`および`fsutil file setCaseSensitiveInfo`コマンドにて操作できるが、Windows APIを通してプログラムから行う方法のメモです。

https://gist.github.com/0xbadfca11/4ababeff1e3eaa2bb7dcb95b0a89b8ee を参考にさせてもらいました。

## 取得(`fsutil file queryCaseSensitiveInfo`相当)

ディレクトリに対するファイルハンドル`hDir`を用意して、下記の様に行う。

`FileCaseSensitiveInfo`列挙子、`FILE_CASE_SENSITIVE_INFO`構造体は2020年12月時点ではドキュメント化されていない模様。

```c
    FILE_CASE_SENSITIVE_INFO caseSensitiveInfo = { 0 };

    GetFileInformationByHandleEx(
        hDir,
        FileCaseSensitiveInfo,
        &caseSensitiveInfo,
        sizeof(caseSensitiveInfo));
```

## 設定(`fsutil file setCaseSensitiveInfo`相当)

ディレクトリに対するファイルハンドル`hDir`を用意して、下記の様に行う。

```c
    FILE_CASE_SENSITIVE_INFO caseSensitiveInfo = { 0 };
    caseSensitiveInfo.Flags |= FILE_CS_FLAG_CASE_SENSITIVE_DIR;

    SetFileInformationByHandle(
        hDir,
        FileCaseSensitiveInfo,
        &caseSensitiveInfo,
        sizeof(caseSensitiveInfo));
```

## サンプルコード(実行する度に設定を反転させる)

長いので折り畳んでいます。

<details><div>

```c:dir_casesensitiveinfo.c
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

int wmain(int argc, PWSTR argv[])
{
    HANDLE hDir = CreateFile(
        argv[1],
        FILE_WRITE_ATTRIBUTES,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
        NULL);

    if (INVALID_HANDLE_VALUE == hDir)
    {
        printf("CreateFile Failed: %08x\n", GetLastError());
        return EXIT_FAILURE;
    }

    FILE_CASE_SENSITIVE_INFO caseSensitiveInfo = { 0 };
    if (!GetFileInformationByHandleEx(
        hDir,
        FileCaseSensitiveInfo,
        &caseSensitiveInfo,
        sizeof(caseSensitiveInfo)))
    {
        printf("GetFileInformationByHandle Failed: %08x\n", GetLastError());
        return EXIT_FAILURE;
    }

    wprintf(L"%s: %u\n", argv[1], caseSensitiveInfo.Flags & FILE_CS_FLAG_CASE_SENSITIVE_DIR);

    caseSensitiveInfo.Flags ^= FILE_CS_FLAG_CASE_SENSITIVE_DIR;

    if (!SetFileInformationByHandle(
        hDir,
        FileCaseSensitiveInfo,
        &caseSensitiveInfo,
        sizeof(caseSensitiveInfo)))
    {
        printf("SetFileInformationByHandle Failed: %08x\n", GetLastError());
        return EXIT_FAILURE;
    }

    CloseHandle(hDir);
}
```

</div></details>
Qiskitで反復量子位相推定を勉強する 

# 反復量子位相推定とは

以前の記事で量子位相推定(QPE)をやりました。
https://qiita.com/notori48/items/6522389a7582a40d3f15

その発展版として反復量子位相推定(Iterative QPE : IQPE)があります。
https://dojo.qulacs.org/ja/latest/notebooks/7.1_quantum_phase_estimation_detailed.html
IQPEは、QPEよりも補助量子ビットを少なくして実行できますので、
量子ビット数や量子ビット間の接続が制限されている場合には有用といえます。

# IQPEの入出力

QPEでは固有値の規格化位相を一気に$t$桁読み出していたので、補助量子ビットも$t$個必要でした。
IQPEでは、1桁ずつ読み出す操作を$t$回繰り返すことで、一度に必要な補助量子ビットは1個で済みます。
基本的にはQPEを逐次処理に分解しただけと思ってよいかと。

#qiskitでIQPE

qiskitでやってみます。
問題に対して非常にスペシフィックなコードを書いていますが、、

問題は過去の記事
https://qiita.com/notori48/items/6522389a7582a40d3f15
に書いたとおりです。

固有ベクトルとして$|1 \rangle$ を入れます。出力の期待は001です。
末尾から読み出していきます。
初段は 1 が出れば正解。

```python
pip install qiskit pylatexenc
#initialization
import matplotlib.pyplot as plt
import numpy as np
import math

# importing Qiskit
from qiskit import IBMQ, Aer
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, execute

# import basic plot tools
from qiskit.visualization import plot_histogram
```

```python
# U = [1 0 ; 0 exp(pi/4)]
# eigen value is 2pi(0) for |0> , 2pi(0.001) for |1>
t = 3 # num of iteration
k = 3 # iteration
qpe = QuantumCircuit(2, 1) # 1 bit for eigen state and 1 ancilla bit for phase kick back
qpe.x(1) # 2nd bit becomes eigen state, |0>
qpe.h(0) # Hadamard for 1st ancilla bit

for i in range(2**(t-1)):
    qpe.cu1(math.pi/4, 0, 1); # This is Controlled-U , controll-qubit is 0 (ancilla) , target-qubit is 1 (eigen)

qpe.h(0) # Hadamard for 1st ancilla bit
qpe.measure(0,0)

backend = Aer.get_backend('qasm_simulator')
shots = 1
results = execute(qpe, backend=backend, shots=shots).result()
answer = results.get_counts()
print(answer)
```
とやると"1"と出ます。正解。

この結果も活用して1桁シフトして再度読み出します。

```python
k = 2 # iteration
phi = math.pi/2; # pi * [0.1]_{2} = pi/2
qpe = QuantumCircuit(2, 1) # 1 bit for eigen state and 1 ancilla bit for phase kick back
qpe.x(1) # 2nd bit becomes eigen state, |0>
qpe.h(0) # Hadamard for 1st ancilla bit
qpe.rz(-1*phi,0)
for i in range(2**(k-1)):
    qpe.cu1(math.pi/4, 0, 1); # This is Controlled-U , controll-qubit is 0 (ancilla) , target-qubit is 1 (eigen)

qpe.h(0) # Hadamard for 1st ancilla bit
qpe.measure(0,0)
backend = Aer.get_backend('qasm_simulator')
shots = 1
results = execute(qpe, backend=backend, shots=shots).result()
answer = results.get_counts()

print(answer)
```
とやると、"0"と出ました。正解。
では最後の桁へ。

```python
k = 1 # iteration
phi = phi/2 + math.pi*0; # pi * [0.1]_{2} = pi/2
qpe = QuantumCircuit(2, 1) # 1 bit for eigen state and 1 ancilla bit for phase kick back
qpe.x(1) # 2nd bit becomes eigen state, |0>
qpe.h(0) # Hadamard for 1st ancilla bit
qpe.rz(-1*phi,0)
for i in range(2**(k-1)):
    qpe.cu1(math.pi/4, 0, 1); # This is Controlled-U , controll-qubit is 0 (ancilla) , target-qubit is 1 (eigen)

qpe.h(0) # Hadamard for 1st ancilla bit
qpe.measure(0,0)
```
とやると、"0"が出ました。正解。

以上、3度の結果をつなげると　"0""0""1" = "001" ということで、ちゃんと固有値の規格化位相が出ています。

ちょっと不満足なのは、うまいことfor文で書けていないところです。
まだpythonもqiskitも慣れていないので、、
まぁそこは本質的な部分ではないので、おいおい慣れていきます。

# 結論
QPEがわかっていれば、IQPEはそんなに難しくない。
Herokuでデプロイしたらエラーになった


ポートフォリオを公開するためにHerokuを使用しています。

HTML、CSS、JSのみのアプリをデプロイしようと思い
Herokuでアプリを作成し、デプロイしましたが
下記エラーが出てデプロイできませんでした。

```
-----> App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/php.tgz
       
 !     ERROR: Application not supported by this buildpack!
 !     
 !     The 'heroku/php' buildpack is set on this application, but was
 !     unable to detect a PHP codebase.
 !     
 !     A PHP app on Heroku requires a 'composer.json' at the root of
 !     the directory structure, or an 'index.php' for legacy behavior.
 !     
 !     If you are trying to deploy a PHP application, ensure that one
 !     of these files is present at the top level directory.
 !     
 !     If you are trying to deploy an application written in another
 !     language, you need to change the list of buildpacks set on your
 !     Heroku app using the 'heroku buildpacks' command.
 !     
 !     For more information, refer to the following documentation:
 !     https://devcenter.heroku.com/articles/buildpacks
 !     https://devcenter.heroku.com/articles/php-support#activation
       More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
 !     Push failed
```

な、、なが、、、

ってなりましたがとりあえずGoogle先生に翻訳頼みました。

読み解いてみると、どうやら

「アプリケーションはこのビルドパックでサポートされていません！
　'heroku / php'ビルドパックはこのアプリケーションに設定されていますが、
　PHPコードベースを検出できません。
　HerokuのPHPアプリでは、のルートに「composer.json」が必要です。
　ディレクトリ構造、またはレガシー動作の場合は「index.php」。」

的なことをいうてます。


## 解決法

index.phpとcomposer.jsonのファイルを新たに作って、
Gitにプッシュした後、デプロイしたら解決しました。
ファイルの中身はこんな感じです。

```:index.php
<?php include_once("index.html"); ?>
```

```:composer.json
{}
```


どうやら、HTMLベースのサイトだと、Herokuがアプリとして認識してくれない為、このようなエラーが出るようです。
index.phpとcomposer.jsonを作ることでアプリと認識してもらえ、無事デプロイできました。



## まとめ
二回ほどこのエラーを経験して「あっ、そうだった そうだった」となったので、この記事を書くことで自分の頭に今叩き込めた気がします。気だけです。
Nuxt.js で簡単な WebAPI を作成

次のページを参考にしました。
[Nuxtに「serverMiddleware」を設定して、API サーバ的な動きをさせてみた](https://liginc.co.jp/438249)

実行結果
![nuxt_api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e8c3803c-ec4d-63a8-b338-0df983359b92.png)

￼プロジェクトの作成

```bash
npx create-nuxt-app proj01
```

この時点でのフォルダー構成

```text
$ tree -L 1
.
├── README.md
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── nuxt.config.js
├── package.json
├── pages
├── plugins
├── static
├── store
└── yarn.lock
```

次のスクリプトでフォルダー構成を変更

```bash:go_folder.sh
mkdir client
mv assets/ client/
mv components client/
mv  layouts client/
mv middleware client/
mv pages client/
mv plugins client/
mv static client/
mv store/ client/

mkdir server
mkdir api
```

スクリプトを実行後のフォルダー構成

```text
$ tree -L 1
.
├── README.md
├── api
├── client
├── node_modules
├── nuxt.config.js
├── package.json
├── server
└── yarn.lock
```

nuxt.config.js の変更

```js:nuxt.config.js
export default {
serverMiddleware: ["~~/api/"],

srcDir: "./client/",
（省略）
```

```js:api/index.js
const express = require("express");
const app = express();
const json_str = '{"en": "Hello World","ja": "こんにちは"}'

app.get("/", function(req, res) {
res.send(json_str);
});

module.exports = {
path: "/api/",
handler: app
};
```

サーバーの実行

```bash
yarn dev
```

クライアントで、
http://localhost:3000/api/
にアクセスする。

```text
$ curl http://localhost:3000/api/ | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    45  100    45    0     0  15000      0 --:--:-- --:--:-- --:--:-- 15000
{
  "en": "Hello World",
  "ja": "こんにちは"
}
```
ObsidianのVimモードで<C-d>問題をなんとかしようとおもっていろいろやってみた

### 背景

[Obsidian](https://obsidian.md)というメモアプリがすばらしい。

- デフォルト機能で、Vimキーバインドにもできる
- サードパーティプラグイン「Obsidian Vimrc Support」をつかって、キーマップをカスタマイズもできる

ところが、個人的な好みで、挿入モードで`<C-d>`は`右一文字削除`にしたいのだが、これだけがうまく設定できなくて困っていた。

Vimrc Supportプラグインの作者に相談すると「[CodeMirrorのバグだとおもうから、バグレポートするといいとおもうよ](https://github.com/esm7/obsidian-vimrc-support/issues/8)」とのことだけど（いちおうレポートはしたけど）、バグフィクスを待ってるのもやだ。


### 対応

サードパーティプラグインの`main.js`に一行追加する（場所は`VAULT_ROOT/.obsidian/plugins/obsidian-vimrc-support/main.js`）

```main.js
（前略）

 // Make sure that we load it just once per CodeMirror instance.
 // This is supposed to work because the Vim state is kept at the keymap level, hopefully
 // there will not be bugs caused by operations that are kept at the object level instead
 CodeMirror.Vim.unmap('<C-d>', 'insert'); // ←ココ
 //
 CodeMirror.Vim.loadedVimrc = true;

（後略）
```

けっしてきれいな対応ではない（プラグインがアップデートするたびに、追記しなければならない）けれど、いまのところ確実に動く。

- どこかほかに書くとよいのだとおもうが……だれかヘルプ……


### やったけどうまくいかなかったこと

`.obsidian.vimrc`に下記を書くのではうまく行かなかった。

`imap <C-d> <Del>`　→　`<Del>`はnormalモードの`x`にマッピングされているから

`unmap <C-d>`　→　normalモードでの`ScrollDown`は消えるが、insertモードの`indentRight`は残る。`CodeMirror`でのバグだとおもわれる

Obsidianで`:imap <C-d> <C-d>`とやってうまくいくこともあったが、`console`を見ていると、キーマップが解釈できずにスタックを使い果たし、困ってデフォルト動作をするようになっているように見えた。再現性も低いし、Obsidianに負担もかけているようなので、この方法は却下。


### リソース（リンク）

`jk`を`<Esc>`にというイシューを手がかりにしてすすめた
https://github.com/codemirror/CodeMirror/issues/6386

`CodeMirror`のキーマップ定義ファイル
https://codemirror.net/keymap/vim.js

`CodeMirror`のイシューにも上げてみた
https://github.com/codemirror/CodeMirror/issues/6535

`CodeMirror`のオンラインデモ
https://codemirror.net/demo/vim.html

`CodeMirror`のマニュアル
https://codemirror.net/doc/manual.html


### 環境

Obsidian Vimrc Support version 0.2.1
Obsidian v0.10.1
macOS BigSur バージョン 11.0.1
MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)


### 後日談

もう少しちゃんとコードを書いて、プラグインにマージしていただいた。
⇒　[Obsidianの<C-d>問題の解決を少し前に進めた](https://qiita.com/hann-solo/items/09643d723d762538224a)
Rails6系に関するMEMO

# Rails6系のディレクトリ構造

何となくでもそれっぽいアプリが作れてしまう `Rails`。
本当にありがたいんだけど、ディレクトリ構造がよくわからないまま実装を進めていくとメンテナンス製がとっても悪くなりそう。。。
なので改めてディレクトリの概要をメモしておきたいと思います。

![railsディレクトリの概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908918/8dbb84a5-48a9-426e-0013-dde2353f7b3a.png)

各ディレクトリの中身に関してはゆくゆく追記していきます。

# 参考記事

- [Railsガイド](https://railsguides.jp/getting_started.html)
- [Railsドキュメント](https://railsdoc.com/rails_base)
- [デフォルトのRailsフォルダ構造](https://qiita.com/RMEL/items/d2fc650396be67e52ef1)
Oracle Cloud Infrastructure（OCI）のフリーフォーム・タグを使ってコスト分析してみた


クラウド上に複数のシステムを展開している場合に、システム毎にコスト負担部門が異なるケースがあります。
このような場合、システム毎（コスト負担部門毎）の利用量を把握したい！、という要望が出てきます。

Oracle Cloud Infrastructure（以下、OCI）には、コスト分析機能があり、期間、サービス、コンパートメント、タグなどの切り口で利用量を把握することができます。
今回はその中でも、もっとも自由度が高いと思われるタグを利用して、コスト分析を行ってみました。

### 1.事前確認

OCIにはコスト・トラッキング・タグというコスト分析用のタグが準備されており、これを利用することでタグ付けしたリソースの利用量が確認できました。
....と思い、[「タグ付け」のマニュアル](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Tagging/Concepts/taggingoverview.htm#concepts)を確認したところ....

<table><tr><td>コスト・トラッキング<br>
コスト・トラッキングは、定義されたタグで使用できる機能です。<br>
この機能は非推奨になっており、現在予算での使用にのみ関連しています。
</td></tr></table>

現在はコスト・トラッキングの利用は予算機能に限定されているようです。

思い直して、[「コスト分析」のマニュアル](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Billing/Concepts/costanalysisoverview.htm#Cost_Analysis_Overview)を確認すると、以下の記載がありました。

<table><tr><td>
コスト追跡タグだけでなく、すべてのタグがサポートされています。
</td></tr></table>

この記載を読む限り、コスト・トラッキング・タグを使わず、フリーフォーム・タグでもコスト分析ができそうです。
というわけで、フリーフォーム・タグを使って、コスト分析を行ってみることにします。 


### 2.リソースにタグを適用

例えば、既存のコンピュート・インスタンスにタグを適用するのはとても簡単です。
コンピュートの詳細画面で[他のアクション]ボタンから「タグの追加」を選択し、キーと値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/47d61f14-f4e6-5032-5ed5-d910bdd9f72a.png)


インスタンス作成時であれば、拡張オプションより設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/ab2ed858-9625-7363-f3e2-b317086a8eb8.png)

設定したタグを、インスタンス詳細画面の「タグ」タグの「フリーフォーム・タグ」で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/192fcaf8-e347-debe-1f0a-33bdc80683c1.png)



### 3.コスト確認

タグ付けしたリソースの利用量をコスト分析画面で確認してみます。
注：集計はバッチで行われるため、すぐには確認できません。

左上三本線メニューより、アカウント管理＞コスト分析と進み、「フィルタの追加」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/4b40508d-2f43-43b2-0461-2e3928cff2c2.png)

今回はタグ値でフィルタをかけるので、「タグ」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/3cc93538-9be2-2659-077a-f94fbc6bdf32.png)

タグには手順2.で設定したキーと値を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/e91f7a4b-a2e9-7682-06e3-64b3dc3e80dc.png)

フィルター条件が指定できたので、[適用]ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/ebccfedd-3b5b-fe5d-4d9b-f71057d2abc4.png)

該当リソースの使用量が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/c9d43674-585e-cb87-5f46-08bf9b73ff94.png)
【Rails】FFmpegで自動作成した動画サムネイルが表示されない不具合について【AWS S3 + EC2 + CarrierWave + Fog】

# はじめに

本記事は、Railsアプリに動画投稿機能を実装したものの、動画のサムネイルが表示されない不具合について解説します。

Railsアプリへの動画投稿機能の実装については下記記事をご参照ください。
[【Rails】ポートフォリオに動画投稿機能を実装してみた【AWS S3 + EC2 + CarrierWave + Fog】](https://qiita.com/devmatsuko/items/bc64b14fd45732d67ad3)

# 事象

動画を投稿する際に、FFmpegを用いてサムネイルを自動生成し、画像をAmazon S3に保存するようにしていました。
しかし、実際に保存した画像を読み込むと下図のように表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/998b67cd-3123-e4e8-1516-db8530e5cb67.png)

# 原因

サムネイル画像のContent-Typeが「video/mp4」となっていたことが原因でした。
おそらく動画を保存するのと同時にサムネイルも保存する動きをしていたので、動画と同じContent-Typeで保存されたのだと思われます。

# 解決策

アップローダはCarrierWaveを利用しています。
CarrierWaveで作成したアップローダのスクリーンショットを作成する処理の中に、content-typeをimage/jpegに変換する処理を入れてあげればOKです。

```ruby:uploader.rb
  version :screenshot do
    process :screenshot
    def full_filename (for_file = model.logo.file)
      "screenshot.jpg"
    end
  end

  def screenshot
    tmpfile = File.join(File.dirname(current_path), "tmpfile")

    File.rename(current_path, tmpfile)

    movie = FFMPEG::Movie.new(tmpfile)
    movie.screenshot(current_path + ".jpg", {resolution: '512x312' }, preserve_aspect_ratio: :width)
    File.rename(current_path + ".jpg", current_path)
    
    # ここから追加
    # サムネイルのcontent_typeをvideo/mp4→image/jpegに変換する
    file.content_type = "image/jpeg"
    # ここまで追加

    File.delete(tmpfile)
  end

```

また、既に投稿済みの動画のサムネイル画像のcontent-typeはAmazon S3から直接変更することもできます。
該当サムネイル画像の[メタデータ] > [編集する]をクリックするを下図のようなメタデータの編集画面が表示されるので、ここでContent-Typeの値をimage/jpegに変更します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/3459694e-474b-25f8-cc50-475b09fb1833.png)

# おわりに

画像の表示エラーの原因の切り分けを行う際は、コードをじっくり見ることも重要ですが、ブラウザから送られるリクエストやサーバーからのレスポンスもしっかり見ると良いかもしれません。

今回、Content-Typeが原因だったこともレスポンスのデータを見て気づくことができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/666a89e7-5c81-892c-9d2d-32aefb59e545.png)

ご参考になれば幸いです…！
Markdownで書いたいい感じの書式のままOneNoteに貼り付け（荒業）

## 経緯
OneNoteでリアルタイムに議事録取り合って共有するのいい感じだとおもってます。
でもかなしいかなMicrosoft製品はエディタとしての機能はちょっと……。
個人的にはMarkdownでいい感じにメモを取りたい。
でもOneNoteはMarkdownで書いてもいい感じにしてくれない。
なんとかならんのかと思い右往左往してみました。

## 調査
既存のやり方を調べてみたら、アドオン使ったり色々。
- [Markdown for OneNote 2.02019-11-26 08:10](https://www.onenotegem.com/a/documents/gem-for-OneNote/Review_Tab/2019/1126/1214.html)
    - OneNoteのアドオンのようなソフト。興味はあるけど使うのにちょっとハードル高そう。
- [QASTACK Onenoteへのマークダウンのインポート](https://www.it-swarm-ja.tech/ja/markdown/%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%80%E3%82%A6%E3%83%B3%E3%82%92onenote%E3%81%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B/958980426/)
    - [PanDoc](https://pandoc.org/)というソフトで、MarkdownをHTMLに変換してOneNoteへコピペしたらどうや。→なるほど賢い

## 私が選んだ解決策
1. OneNoteでとりあえずMarkdown書式に則ってメモとる（←リアルタイムに共有したいのでOneNoteで書いてる。個人のメモを後で貼り付けるならOneNoteじゃなくてもいい。
2. いちど適当なテキストエディタに貼り付けてから、適当なMarkdown用エディタに貼り付けて、「HTML形式」でエクスポートしてファイル保存
3. エクスポートされたHTMLファイルを~~ブラウザ~~ **InternetExplorer** で開いてコピー（Ctrl+C）
~~4. OneNoteにペースト（Ctrl+V）~~　（以下、2021/02/19 11:55追記）
4. 空白領域を右クリックして「OneNoteを送る」を使ってとりあえずクイックノートに送る
5. クイックノートに持ってきた内容を、別のページにコピペ

## Typoraについて
愛すべきTypora。使いやすいMarkdownエディタです。
- Typora
    - https://typora.io/
- Qiita 強力なMarkdownエディタ「Typora」に今更入門 @4_mio_11 
    - https://qiita.com/4_mio_11/items/223326c3289f6b2c2a07
    
## まとめ
2021/01/06 11:41 修正
~~結局、一回HTMLでエクスポートしてしてブラウザで開いてコピペかいって感じですが、それでもその価値は俺にはあると信じてる。~~
アドオンみたいなやつのインストールやってみたい。でも会社のPCにインストールするのちょっと微妙な感じなんでまたいつか。

2021/02/19 11:57
この記事かいた当初はブラウザからコピペするだけで行けてたような気がするんだけど、なぜかうまくいかないので（）
IEで開いてOneNoteを送るで逃げました。謎。
【CSS】画像を親要素内からはみ出さずに表示する


サイトをコーディングしていて、`div`にクラス`container`とし、下記CSSを指定した。

```CSS:CSS
.container {
  height: 600px
}
```

その中に画像を設置。
しかし、画像の縦幅が600pxを超えており、親要素をはみ出してしまいました。　


## 解決法
下記のプロパティを設定したら解決しました。

```CSS:CSS
.container {
  height: 600px
  overflow: hidden; /*overflowプロパティを追加*/
}
```


## overflowプロパティとは

領域内に収まりきらなかった内容を、どう処理するか、を指定するプロパティです。

**`visible`**
領域をはみ出して表示する（デフォルト値）

**`hidden`**
はみ出した部分を表示しない　今回適用したのはコレです。

**`scroll`**
はみ出した部分は、スクロールバーを出して表示する

**`auto`**
自動


## まとめ
`overflow`プロパティは、
テキストの回り込み回避や、floatの解除にも使えるようなので
ぜひとも覚えておきたいプロパティだなと思いました◎


**参考サイト様**
[いろいろと便利なoverflow:hidden;についてのあれこれ](https://cra.jp/blog/skill/1503_skill_overflow/)
ngrok - ローカル環境でhttps通信（サーバーを外部公開）

## この記事について
ローカル環境でhttps通信をする必要性が出てきたので、その実現方法を記述した記事です。

## 環境
macOS Catalina：10.15.7
ngrok：2.3.35

## なぜhttps通信をする必要があったんか
Webアプリで現在地の取得をするときにchrome, firefoxの場合だと、ブラウザで許可をすればすんなり位置情報を取得できたけど、safariだと**https**じゃないと位置情報を取得ができなかったので、頑張ってhttps通信を実現させる必要があった。




## ngrokとは何者か？

>ngrok allows you to expose a web server running on your local machine to the internet. Just tell ngrok what port your web server is listening on.

そのまま翻訳すると、
**「ngrokはローカルで動いとるサーバーをインターネットに公開できるようにさせんで〜。ngrokにサーバーがlistenしているポート番号を教えるだけでできちゃうんやで。」**
https://ngrok.com/docs

 

## ngrokを使うまでの流れを紹介。まずはじめになぜか上手くいかなかった公式ホームページのパターン（多分僕のせい）
https://dashboard.ngrok.com/get-started/setup

#### ①ngrokへの登録
githubと連携できるのですぐにできちゃう！！！

#### ②`Download for Mac OS`をクリック
これでダウンロードフォルダにzipがダウンロードされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/cb0bf566-edfe-95ea-df47-5bcf6ee2892e.png)
スクリーンショット 2020-12-24 17.16.26

#### ③ダウンロードしたzipを解凍

```
unzip /path/to/ngrok.zip
```

#### ④認証トークンの取得
認証トークンの取得が成功すると、~/.ngrok2/ngrok.ymlが生成され、認証トークン情報が登録される。
これを実行することで、より多くの機能がつかるようになるみたい。

```
./ngrok authtoken 1m5phzLi6zWczGbAKKigfWZMmOX_2TXGc5biazsTbXm58buiP
```


#### ここから後はサーバーを起動して、ngrokでWebサイトを公開するだけ、、、のはずやった。
railsで開発しているので`rails s`でサーバーを立ち上げた後に、別のターミナルで`ngrok http 3000`を実行したが、該当のページを開くことができず。。。。

```
$ rails s

$ ngrok http 3000
ngrok by @inconshreveable
Session Status                online
Account                       hanatareman (Plan: Free)
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://d3f630bc2c4f.ngrok.io -> http://localhost:3000
Forwarding                    https://d3f630bc2c4f.ngrok.io -> http://localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
```

両方ともアクセスしてもうまいこといかへんかった。
なんでやったんか未だに謎ちゃん。

```
http://d3f630bc2c4f.ngrok.io
https://d3f630bc2c4f.ngrok.io
```





## うまくできたパターン（失敗した後に実行）
どうやら`brew`でインストールできるみたい。

#### ①`brew`でインストール
```
$ brew install ngrok
```

#### ②再度サーバーの立ち上げ

```
$ rails s

$ ngrok http 3000
ngrok by @inconshreveable
Session Status                online
Account                       hanatareman (Plan: Free)
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://d3f630bc2c4f.ngrok.io -> http://localhost:3000
Forwarding                    https://d3f630bc2c4f.ngrok.io -> http://localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
```


#### 生成されてるURLにアクセスすると。。。
ページが表示された！！！！！
ちゃんとsafariでも現在地取得してくれた！！！！


## 参考記事
ありがとうございました。

https://qiita.com/mininobu/items/b45dbc70faedf30f484e


## 最後に
開発環境の状況を共有するのに役に立ちそうやし、いちいちデプロイせずに本番環境を確認できるから便利ですな〜。
ポートフォリオ作成してた時に知りたかったなり。