OmniAICreator/Qiita-1.07M huggingface dataset:
laravel セッションのサンプル

# ルーティング

/routes/**web.php**

```php
<?php
Route::get('/session_sample', 'SampleController@sessionSample');

Route::post('/session_sample', 'SampleController@sessionDelete');
```

# コントローラー

app/Http/Controllers/**SampleController.php**

```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
 
class SampleController extends Controller{


     public function sessionSample(){
 
        $count = session()->get('count', 0);
        $count++;
 
        session()->put('count', $count);
 
        return view('samples.counter_sample', [
          'title' => 'セッションを利用するサンプル',
          'count' => $count,
        ]);
      }

      public function sessionDelete(){
 
       session()->forget('count');
 
        return 'セッションデータを削除しました。';
      }
 
}
```

# ビュー

resources/views/samples/**counter_sample.blade.phpp**

```php
@extends('layouts.default')
 
@section('title', $title)
 
@section('content')
 
<h1>{{ $title }}</h1>
@if($count === 1)
  <p>初めての訪問です。</p>
@else
  <p>{{ $count }}回目の訪問です。
@endif
 
<form method="post">
  @csrf
  <input type="submit" value="履歴を削除">
</form>
 
@endsection

```

# 共通レイアウトファイル

```PHP
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
    <style>
        .header_nav {
            display: flex;
            list-style: none;
            padding-left: 0;
        }
        .header_nav li {
            margin-right: 30px;
        }
        /* エラーメッセージ用のスタイル */
        .error {
          color: red;
        }
    </style>
</head>
<body>
    @yield('header')
 
    {{-- エラーメッセージを出力 --}}
    @foreach($errors->all() as $error)
      <p class="error">{{ $error }}</p>
    @endforeach
 
    @yield('content')
</body>
</html>
```
乃木坂46の現役一期生メンバーでアンダー経験のないメンバーをSinatraフレークワークを使ってWebページで表示する

Sinatraフレームワークを使って乃木坂46の現役一期生メンバーでアンダー経験のないメンバーのWebページを作りました。ソースコードはこちらです。


```Ruby
# erbでWebページを表示しよう
require 'sinatra'
require 'sinatra/reloader'
require 'erb'

get '/' do
#    @name = "Sinatra"
#    @now = Time.now
    @member = ["松村沙友理","秋元真夏","高山一実","生田絵梨花"]
    erb :index
end

__END__
```

```HTML
@@index
<!DOCTYPE html>
<html lang="ja">
    <head>
        <mata charset="utf-8">
        <title>Sinatra - paiza</title>
        <style>body {padding: 30px;}</style>
    </head>
    <body>
        <h1>乃木坂46</h1>
        <h2>乃木坂46一期生でアンダー経験ない現役メンバー</h2>
        <% @member.each do |person| %>
            <p><%= "#{person}は、選抜メンバーから落ちたことがない" %></p>
        <% end %>    
    </body>
</html>
```


RubyでSinatraフレームワークを使ってWebアプリケーションを作ってみました。
[Linux]sedコマンドとawkコマンドについて

#はじめに
sedコマンドとawkコマンドについて学んだのでまとめてみました

#sedコマンド

sedとは「Stream Editor」から来ています。そう、エディタのことです。ただし、sedコマンドでは非対話的エディタのため、編集し出力をしても元のファイルに変更は加えないという特徴があります。

```:terminal
% sed オプション　<スクリプト>　<対象ファイル>
```

おそらくこれだけではわからないと思います。使用例としては以下です。

```:terminal
% sed 1,5d sample.txt

% sed 's/aaa/bbb/g' sample.txt
```

うん、もっとわからなくなったはずです笑
とりあえず、sedコマンドは多くのことができるコマンドですが主なコマンド（d:削除、p:行を表示、s:行の置換）を紹介していきます。

###行の削除

sedコマンドでは、アドレスで指定した行のみ作用（削除）します。

例えば、以下のようなファイルがあったとします。

```:sample.txt
Beer
BeerBeer
BeerBeerBeer
Beeeeeeeeeeeeeeer!
```

それでは行を削除してみます。

```:terminal
% sed 1d sample.txt
BeerBeer
BeerBeerBeer
Beeeeeeeeeeeeeeer!
```
1行目のBeerが削除されていることがわかります。
行は範囲指定できます。

```:terminal
% sed 1,3d sample.txt
Beeeeeeeeeeeeeeer!
```

ちなみにアドレスを指定せずにコマンドを打てば全削除になりますし、アドレスに＄を使用すると最終行までを意味することができます。$を使うときは、シェルに解釈させないために''で囲みましょう！

```:terminal
% sed d sample

% sed '3,$d' sample.txt
Beer
BeerBeer
```

上記では行番号で削除するものを決めていましたが、正規表現でもOKです。
以下の場合は、先頭がBから始まる行を指定しています。

```:terminal
% sed /^B/d sample.txt
```

###行を表示する

今回はシンプルで削除した際にdとしていたところをpとするだけです。

```:terminal
% sed 1p samole.txt
Beer
Beer
BeerBeer
BeerBeer
BeerBeerBeer
BeerBeerBeer
Beeeeeeeeeeeeeeer!
Beeeeeeeeeeeeeeer!
```
あれ、、、2重になっている、、、
これはできれば各自調べて欲しいのですが、、「パターンスペース」の出力も同時に行われているためです。

これではみづらいので、-nオプションを使えばパターンスペースの出力をなくすことができます！

```:terminal
% sed -n 1p sample.txt
Beer
```

###行の置換

置換ではsコマンドを使用します

```:terminal
% sed 's/置換する文字列/置換後の文字列/フラグ'　ファイル名

```

フラグは省略可能です。
ただし、省略した場合は、見つかった文字列の最初しか置換しないので、フラグのところにgとつけてあげます。すると、見つかった文字列は全て置換します。

なお、置換が発生したときのみ出力するｐフラグを使うと便利です

```:terminal
% sed 's/beer/wine/gp' sample.txt
```

ちなみに、拡張表現を使ってグループ化、参照をうまく使えば、以下のようにすることも可能
()でグループ化したものは\1や\2といった形で参照できます。

```:sample.txt
My wine
My beer
```
```:terminal
% sed 's/My \(.*\)/--\1--/' sample.txt
--wine--
--beer--
```

#awkコマンド

awkコマンドはsedよりも高性能にテキストの抽出や加工をします。
書き方は以下のとおりです。

```:terminal
% awk パターン　{アクション}　ファイル名
```

当然これだけではわかるまい！と言うわけで解説。
awkではパターンにマッチした場合のみアクションを行います。もちろん、パターンは省略可能でその場合は、全データが対象になります。

具体例を見ていきます。例えば、以下の場合であれば第1フィールドがsで始まるレコードを行番号付きで表示します。

```:terminal
% awk '$1 ~ /^s/ {print NR,$0}' test.txt 
```

`$1,,,,,$9`は、レコードの並びを分割した際の各フィールドを示し、`$0`はレコード丸々を示します。また`$NS`はいわゆる最後のフィールドを指し、`$(NS-1)`とすることも可能です。

パターンの指定方法としては以下です。

```:terminal
% awk `$9 ~ /^cp/` {print $5,$8}
```

この場合は、第9フィールドの先頭がcpで始まっているレコードに対して、第5、8フィールドを表示させるコマンドになります。

より実践的な例としては、ｃｓｖファイルで平均を考えるときは以下のようにする。

```:terminal
% aws -F, `{sum+= $NF} END {print "Average:",sum/NR}` score.csv
```

ここで`-F,`はフィールド区切りの文字を指定するためのオプションであり、ENDはそれよりも前のアクションが終わってから次のアクションをさせるものです。
つまり、フィールド区切りのレコードに対して、最後のフィールドの合計値を求めた後に、平均を表示してます。ちなみに、`NR`はこれまで読み込んだレコード数が代入された組み込み変数です。


#おわりに

以上、sedとawkについてまとめました。
便利なコマンド？だと思われるので、是非使い慣れたいものです！
CloudFormationでCloudWatchアラームを作成する

##はじめに
複数環境への横展開を目的としてCloudWatchアラームをCloudFormationを用いて作成する機会があったので、備忘録として残そうと思います。

CloudWatchアラームに関する知識はあるが、CloudFormationを用いてアラームのリソースを作成したことがない方へ向けての内容になります。
CloudWatchアラームとは？という方は以下をご参照ください。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html

また今回はCloudFormationのテンプレートをYAML形式で作成していますが、Visual Studio CodeのプラグインでYAML⇔JSON変換もできるそうなので（試してはいません）、JSON派の方も参考にしていただければと思います。
https://bsblog.casareal.co.jp/archives/4936

##早速作ってみる
Lambdaのエラーを検知するCloudWatchアラームとそれを通知するためのSNSトピックを作成します。
環境ごとにリソース名を変える為に、環境識別子をパラメータにとり各リソース名の頭につけます。

以下がCloudFormationのテンプレートになります。

```CloudWatchAlarm.yaml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  # 環境識別子毎にリソースの名前を変える必要があるので、環境識別子をパラメータとして用意
  EnvironmentIdentifier:
    Description: Environment Identifier
    MaxLength: 15
    Type: String
Resources:
  # SNS Topic （エラーアラームの通知用）
  TopicError:
    Type: AWS::SNS::Topic
    Properties: 
      TopicName:
        Fn::Join:
        - "-"
        - - Ref: EnvironmentIdentifier
          - topic-error
      Subscription:
        - Protocol: email
          Endpoint: xxxx@example.com

  # CloudWatchアラームのリソース
  AlarmLambdaError:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: 
        Fn::Join:
        - "-"
        - - Ref: EnvironmentIdentifier
          - alarm-lambda-error
      AlarmDescription: Alarm for Lambda Error
      # アラームのアクションとしてSNSのTopicを指定
      AlarmActions: 
        - Fn::Join:
          - ":"
          - - 'arn:aws:sns:ap-northeast-1'
            - Ref: 'AWS::AccountId'
            - Fn::Join:
              - "-"
              - - Ref: EnvironmentIdentifier
                - topic-error
      ComparisonOperator: GreaterThanThreshold
      MetricName: Errors
      Namespace: AWS/Lambda
      DatapointsToAlarm: '1'
      EvaluationPeriods: '1'
      Period: '300'
      Statistic: Sum
      Threshold: '0'

```

##CloudFormationスタックの作成
CloudFormationの「スタックの作成」からスタックの作成をします。
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545896/d4ab4a2c-a483-3ca2-167c-f11575f11451.png)

実際に作成されたリソースはこちら。
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545896/8c657376-6150-0d53-4d7b-82651ac42ad7.jpeg)




##まとめ
今回のシステムでは多い時で10環境程度あり、1環境に100個弱のアラームが存在していたため、コンソールからアラームを作成していたのではとても間に合いませんでした。
CloudFormationによってリソースをIaC化することにより、横展開の工数を大幅に削減することに成功しました。

皆様も環境数の多いシステムではIaC化を検討されてはいかがでしょうか。
HTTPとHTTPSの違い

## はじめに
面接でhttpとhttpsの違いを聞かれて恥ずかしながら、答えられなかった私です。

なんとなくhttpsは安全ってよく耳にするくらいだったのでちゃんと調べたことなかったなあ、と思い今回記事にさせていただきます。

## プロトコル
httpの説明の前に、調べていたら、プロトコルというものの理解も必要のようです。

プロトコル（protocol)とは直訳すると議定書とか外交儀礼という意味になります。
ネットワーク界のプロトコルの意味は**コンピュータ同士が通信を行うための規格（ルール）**のことを意味します。ちょっと対象は違いますけとニュアンス似てると思います。

ちなみに医療現場では治療計画や手順の意で使われるそうです。

世の中には様々なPCやサーバーがあり、それぞれいろんなメーカーが開発していますが、それらの通信のルールがバラバラだと同じメーカーじゃないと通信ができない！みたいなかなり面倒なことになります。
そうならないために共通のルールを作ることで異なるメーカーでも関係なく通信できるようにしているのです。

プロトコルにはいろんな種類が存在していて、それぞれが異なった役割を担っています。
それらプロトコルを組み合わせて階層構造にし、体系化したものがネットワークアーキテクチャーです。

ネットワークアーキテクチャーの代表的なものに
**OSI基本参照モデル**と**TCP/IP**というものがあります。
*※この記事では詳しくは記載しません。*

そのTPC/IPの第四層のアプリケーション層に用いられるプロトコルが**HTTP**になります。

ややこしいですね。。。
プロトコルに関してはまた別で記事にまとめる必要がありそうです。

## HTTP
HTTPは「Hyper Text Transfer Protocol」の略です。
webページを表示するためにクライアントとサーバー間で行われるデータの送受信のプロトコルです。

HTTP通信を使ってクライアントとサーバー間でリクエストとレスポンスが行われていますが、リクエストには「HTTPメソッド」や「リクエスト先」などの情報が含まれています。

また、レスポンスには「レスポンスの形式」や「HTTPステータスコード」、HTMLも含まれています。

このレスポンスの情報が変換されてブラウザ上に表示されます。

## HTTPS
HTTPSはSecure（安全な）がついただけで「Hyper Transfer Protocol Secure」の略です。

HTTPとHTTPSの違いは通信内容が暗号化されているか否かです。
HTTPはいわば、中身剥き出し状態で通信しているのに対し、HTTPSは暗号化されているので、安全に通信をすることが可能になります。

HTTPでは第三者が通信内容を見たり、編集する可能性があります。

## HTTPSの違いの見分け方
HTTPSはURLがhttpsから始まっています。
また、httpsで暗号化されているならば、ページを開いた後にURLに鍵マークのアイコンが表示されています。

## SSLサーバー証明書
httpsを導入に「SSLサーバ証明書」というものが必要になります。
これはインターネット上の身分証明書のようなものです。

常時SSL化のために独自SSLという証明書を使用します。これは規模や用途によって**DV(個人向け）、OV（法人向け）、EV（重要な個人情報を扱う法人向け）**という3種類から申請、取得をします。

これらのレベル分けは信頼度を示すもので、EVが最も厳格な審査が行われるとともに、費用も高額みたいです。

とりあえず、SSLを発行することで暗号化した通信が可能になるということを覚える！

## 最後に
httpとhttpsの違いを探していたら一石二鳥的に周辺の知識もいろいろ学べてよかったなと思いました。

https =　安全である

という認識は間違っているとは言いませんが、仕組みを知ると、誰でも比較的簡単にhttpsの認証が取得できるので、100%安全であるとは言えないなあと思いました。

今回のような、そもそものインターネットの仕組み、コンピューターサイエンスの知識は非常に大事だと思いますし、随時学習していきたいと思っています。
.NET 6 Preview on App Service を試してみた

## 背景と目的

Azure CLI で .NET 6 ランタイムの App Service が作れるようになったようなので、実際に試してみました。

## 前提条件

.NET 6 環境は、[.Net 6.0.0 Preview 2 を Visual Studio Code から Docker 利用してみた](https://qiita.com/mnrst/items/453a3204a9542086252b) で作成した環境を使用します。

コマンドの実施環境は、Mac + Azure CLI です。

```zsh:zsh
% sw_vers
ProductName:    macOS
ProductVersion: 11.4
BuildVersion:   20F71

% az version
{
  "azure-cli": "2.24.2",
  "azure-cli-core": "2.24.2",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}
```

## 実施内容

.NET 6 MVC でランタイム情報を表示するアプリを作成します。

```bash:bash
$ dotnet --version
6.0.100-preview.4.21255.9

$ dotnet new mvc -n mvcapp

$ cd mvcapp

$ cat << EOF > Views/Home/Index.cshtml
@using System.Runtime.InteropServices
@{
    ViewData["Title"] = "Home";
}
<div class="text-center">
    <h5>Environment</h5>
    <p>@RuntimeInformation.FrameworkDescription (@RuntimeInformation.ProcessArchitecture)</p>
    <p>@RuntimeInformation.OSDescription</p>
</div>
EOF

$ dotnet dev-certs https

$ dotnet run

https://localhost:5001

Ctrl+C
```

.NET 6 MVC アプリのディレクトリに移動して、Windows と Linux の App Service をそれぞれ作成します。なお、共同作成者権限でリソースグループの作成から App Service Plan と App Service の作成、カレントディレクトリの .NET 6 MVC アプリのアップロードまで、一連のリソース作成を一つのコマンドで実行します。

```zsh:zsh
# 環境変数を設定します
region=southeastasia
prefix=mnrdndev

# Windows の App Service を作成します
az webapp up \
  --resource-group ${prefix}-win-rg \
  --location $region \
  --plan ${prefix}-win-plan \
  --name ${prefix}-win \
  --runtime "DOTNET|6.0" \
  --os-type Windows \
  --sku F1

# 同じソースコードで Linux の App Service を試すので、Windows の App Service の情報を消します
rm -rf .azure

# Linux の App Service を作成します
az webapp up \
  --resource-group ${prefix}-lnx-rg \
  --location $region \
  --plan ${prefix}-lnx-plan \
  --name ${prefix}-lnx \
  --runtime "DOTNET|6.0" \
  --os-type Linux \
  --sku F1
```

## 実施結果

Windows の App Service で表示されるランタイム情報です。

![dotnet6-appservice-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/acafe2ff-d91d-6fb7-80b7-75581a5ae0a6.png)

Linux の App Service で表示されるランタイム情報です。

![dotnet6-appservice-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/8af71f12-c6c7-f641-aa12-b40f750860a7.png)

## 参考

[Azure CLI Release notes May 25, 2021](https://docs.microsoft.com/ja-jp/cli/azure/release-notes-azure-cli?tabs=azure-cli#may-25-2021)

[.NET 6 Preview on App Service](https://azure.github.io/AppService/2021/06/09/Dot-Net-6-Preview-on-App-Service.html)
S3バケットをインタラクティブに簡単に削除する

# はじめに
オブジェクトの入ったS3バケットをAWSCLIを使って、インタラクティブに削除する方法です。

## S3の削除コマンドって、、
意外と検討段階だったり、AWSサービス使ってると自動的に作られて、あー、消したいなぁって思うことがあります。ありますよね。
で、さすがにGUIはめんどくさいので、CLIで打つんだけど、何が面倒くさいって、バケットの名前って一意にしないといけないので、とても長ったらしくて、コマンド打つのがめんどくさい。ていうかよく間違えて、そんなバケット無いよ、って言われてイライラする。

```
# バケットを探す
aws s3 ls

# バケットを消す
aws s3 rb aaaabbbbccccdddd-backet --force
```
あー、backetじゃなくて、bucketだったーみたいな。

# 解決法
インタラクティブに消せたらいいよね。
ということで、[こちら](https://github.com/rcmdnk/sentaku)を使わせて頂く。

下準備として、sentakuをインストール。

```bash
brew tap rcmdnk/rcmdnkpac
brew install sentaku
```
下記スクリプトを準備。
個人的にはこういうオレオレスクリプトをどこかにまとめて作っておいて、環境変数のPATHに追加しておくといつでも使えて便利なのでそれをオススメする。やっていることはシンプルで、s3のリストを取得して、選んだバケットをごそっと消しちゃうというもの。（消えるので使い方には注意を・・責任は負いません。）

```bash:rm_bucket
#!/bin/bash

STR=`aws s3 ls | sentaku -s $'\n'`
ARR=(${STR// / })
BUCKET=${ARR[2]}
BUCKET=`echo ${BUCKET} | tr -d '\n'`

if [ -z ${BUCKET} ]; then
    echo "Error: Cannot find bucket name."
    exit
fi

read -p "delete ${BUCKET}? (y/N): " yn
if [[ $yn = [yY] ]]; then
    echo "s3://${BUCKET}"
    aws s3 rb s3://${BUCKET} --force
else
    echo "Abort."
fi
```

## 使ってみる
こんなふうに使えます。

```bash
$ rm_bucket
```
実行すると、下記のようなS3バケットのリストが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204712/5972801a-055a-0689-d31a-20875b394d73.png)

バケットを選択してエンターを押すと確認メッセージが表示されて、`y`を打てば、そのまま強制的に消せます。

```bash
delete example-example-2? (y/N): y
s3://example-example-2
remove_bucket: example-example-2
```

##　まとめ
快適！快適だ！
でも--forceで消してるので、気をつけて使ってください。

（既存バケット名をIntelisenseとか出来るなら、そのほうが快適な気がする・・）
Rubyで1桁、2桁、3桁の整数の0埋めの方法（2通り)

Rubyで1桁、2桁、3桁の整数の0埋めの方法を（2通り)の方法でプログラムを作成いたしました。

1通り目はsprintf関数を使う方法です。C言語を知っている方ならこちらでプログラムを書くと思います。

```Ruby
#sprintf関数を使う方法

puts '0から999までの整数を入力してください'
n = gets.to_i

puts '0で埋めて表示してください'
puts sprintf('%03d', n)
```

2通り目

```Ruby
#数値を入力します
N = gets.to_i
#数値を文字列に変換します
S = N.to_s
#Sのもじれつの長さを調べます
len = S.length
#文字列の長さが1,2,3でif文を作ります
if len == 3
   puts S
elsif  len == 2
   puts "0" + S
else
   puts "00" + S
end
```

どちらでプログラムを作成しても良いでしょう。
SSHにTerminalからログインできなくなった時の対処法【さくらVPS】

# SSHへのログイン方法

1. **さくらのVPS**サーバーのページ上部にあるコンソールをクリック
![スクリーンショット 2021-06-11 16.15.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688621/a24c2a06-1e42-a139-eeb5-f3506ad7214a.png)

2. プルダウンメニューの「VNCコンソール」「シリアルコンソール」のどちらかを開く
    **留意点：VNCコンソールは、コピーアンドペーストが出来ない**
2. CUIの画面が表示されるので、「**root**」と入力する
2. パスワードを入力する
2. ログイン完了

以上の流れで、SSHの管理者権限にログインすることができます！
ここから設定を直して、Terminalでもログインできるようにしましょう。
[Vuetify] v-combobox や v-autocomplete のプレースホルダーが表示されない問題

## 非フォーカス時にプレースホルダが表示されない
Vuetifyのあるバージョンから、v-combobox や v-autocomplete において、フォーカスが当たっていない状態ではプレースホルダが表示されない不具合がある。

どうやら、チップ表示時に限定の不具合らしい。

## 対策
単純に不具合らしいので、そのうち治ると思うが、v2.5.0 の時点では発生していたので対応策が必要です。

Vuetifyの指定を下記のCSSで上書きしてやれば治ります。

```scss
.v-autocomplete:not(.v-input--is-focused).v-select--chips input {
  max-height: inherit;
}
```

inputの高さがゼロになっているのが原因みたいですね。

### 参考
https://github.com/vuetifyjs/vuetify/issues/11553
Rubyである文字列に特定の文字が含まれているかをチェックする処理

Rubyであるある文字列に特定の文字が含まれているかをチェックする処理
のプログラムです

```Ruby
# 新規作成 2021/6/11 
# 作者  nogizakapython
puts '含まれる文字を入力してください'
N = gets.chomp

puts '文字列を入力してください'
S = gets.chomp

#文字列Sに文字Nが含まれているかチェックする処理
if S.include? N
    puts 'YES'
else
    puts 'NO'
end
```
CSSで吹き出し　作成方法

## CSSで吹き出しを作る
LPなどで吹き出しを付けたいときのために、簡単に作成する方法をご紹介致します。

まずは、吹き出しの中身を下記のように作成致します。

![スクリーンショット 2021-06-06 15.13.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/b9fb00f7-df3f-bf7e-497d-2cb659ad8dec.png)


```

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="fukidashi-block">
        <p class="sentence">吹き出し</p>
    </div>
</body>
</html>

<style>
    .fukidashi-block {
        text-align: center;
        background-color: green;
        padding: 10px 16px;
        position: relative;
        border-radius: 10px;
        color: white;
        font-weight: 700;
    }
   
</style>

```

次に、吹き出しで一番難しく感じる三角形部分。cssにコードを追加します。
これで完成です。


![スクリーンショット 2021-06-06 15.18.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/c4ab8332-91e7-9646-c10f-44ee2605e45b.png)



```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="fukidashi-block">
        <p class="sentence">吹き出し</p>
    </div>
</body>
</html>


<style>
    
    /* 追加 */
    .sentence::before {
        position: absolute;
        content: "";
        border: 9px solid transparent;
        border-top: 11px solid green;
        bottom: -40%;
        left: 50%;
        transform: translateY(-50%) translateX(-50%);
    }
    /* ここまで */

    .fukidashi-block {
        text-align: center;
        background-color: green;
        padding: 10px 16px;
        position: relative;
        border-radius: 10px;
        color: white;
        font-weight: 700;
    }
   
</style>

```

以上になります。
Psychパッケージを用いた因子分析用擬似データの作成

これまで，統計法の授業で使う練習用の架空データを作るのにかなり長時間を費やしていたのですが，`psych`パッケージを使えばかなり簡単にできてしまうことをいまさらながら知りました。この記事は完全に自分用の備忘録です。

必要なのは`psych`パッケージと`MASS`パッケージの２つだけです。`psych`パッケージの`sim.structure()`で因子負荷行列と因子間相関行列を指定して観測変数の相関行列を作り，そこから`MASS`パッケージの`mvrnorm()`で多変量正規乱数を生成します。

後は，適当にスケーリングして整数化したり，カテゴリー化したりすれば完成です。連続値のカテゴリー化には，`psych`パッケージの`con2cat()`が便利です。もちろん，サンプルサイズが小さかったりすれば因子分析結果が想定通りにならなかったりしますが，それは仕方ありません。


```r
require(psych)
require(MASS)

set.seed(20210611)

因子負荷行列 <- matrix( # 因子負荷行列を指定
					  c( 0.8,  0.0,  0.0,
					    -0.7,  0.0,  0.0,
					     0.6,  0.0,  0.0,
					     0.0,  0.7,  0.1, 
					     0.0,  0.7,  0.1,
					     0.0,  0.0,  0.6,
					     0.0,  0.0,  0.6), ncol=3, byrow=T)
					    
因子間相関行列 <- matrix( # 因子間の相関行列を指定
			           c( 1.0, 0.4, 0.4,
			              0.4, 1.0, 0.2,
			              0.4, 0.2, 1.0),ncol=3)

変数間相関行列 <- sim.structure( 因子負荷行列 , 因子間相関行列 )$model # ここで使うのは相関行列の部分(model)だけ

サンプルサイズ <- 100
平均値 <- rep(0, 7) # ここでは７つの変数の平均値をすべて0に設定

乱数データ <- mvrnorm(サンプルサイズ,平均値,変数間相関行列)

#### 連続変数の擬似データを作る場合（ここでは平均点50点前後，標準偏差4〜6点の整数値に変換）
整数データ <- 乱数データ * runif( n = 7, min = 4, max = 7) # 標準偏差を4倍から6倍にスケーリング
整数データ <- 整数データ + runif( n = 7, min = 45, max = 55) # 平均値を45点から55点の範囲に変更
整数データ <- round(整数データ) # 整数化

#### 7段階評価（1〜7）の回答値の擬似データを作る場合
回答データ <- 乱数データ * runif( n = 7, min = 1.5, max = 2.0) # 標準偏差を1.5倍から2倍にスケーリング
回答データ <- 回答データ + runif( n = 7, min = 2.5, max = 3.5) # 平均値を2.5点から3.5点の範囲に変更
回答データ <- con2cat(回答データ,cuts=c( 0.5, 1.5, 2.5, 3.5, 4.5, 5.5)) + 1　# 適当なところでカットして7段階化 + 最小評価値

```
開発環境自動化②

# 経緯
mac,linux(arch,ubuntu,debian),windows(wsl)で同じ環境作るのめんどくさすぎ問題。が発端

詳しくは以下の"開発環境めんどくさすぎる問題"を読んでください。
https://qiita.com/aki-f/items/494cefe0e98cc74249fa

##　問題
今までのやり方だとすべてのパソコンでhaskellやrustがインストールされてしまう。

## そして環境変数化へ

以下のファイルを作った。

```json:config.json
{
  "languages": {
    "haskell": {
      "enable" : true
    },
    "rust": {
      "enable" : true
    },
    "ruby": {
      "enable": true,
      "version": "3.0.1",
      "modules": [
        "solargraph"
      ]
    },
    "nodejs": {
      "enable": true,
      "version": "14.17.0",
      "modules": []
    },
    "jvm": {
      "enable": true,
      "version": "11.0.10",
      "modules": ["gradle"]
    }
  }
}
```

これを環境変数にするには

```bash:enviroment.sh
export RUBY_FLAG=$(cat ~/dotfiles/config.json | jq .languages.ruby.enable)
export RUBY_VER=$(cat ~/dotfiles/config.json | jq -r .languages.ruby.version)
export RUBY_MODULES=$(cat ~/dotfiles/config.json | jq -r .languages.ruby.modules\[\] | tr '\n' ' ' )

export NODE_FLAG=$(cat ~/dotfiles/config.json | jq .languages.nodejs.enable)
export NODE_VER=$(cat ~/dotfiles/config.json | jq -r .languages.nodejs.version)
export NODE_MODULES=$(cat ~/dotfiles/config.json | jq -r .languages.nodejs.modules\[\] | tr '\n' ' ')

export JVM_FLAG=$(cat ~/dotfiles/config.json | jq .languages.jvm.enable)
export JVM_VER=$(cat ~/dotfiles/config.json | jq -r .languages.jvm.version)
export JVM_MODULES=$(cat ~/dotfiles/config.json | jq -r .languages.jvm.modules\[\] | tr '\n' ' ')

export RUST_FLAG=$(cat ~/dotfiles/config.json | jq -r .languages.rust.enable)

export HASKELL_FLAG=$(cat ~/dotfiles/config.json | jq -r .languages.haskell.enable)

```

`source enviroment.sh`

## 例えばjavaだとこうなる

```bash:install/jvm.sh
if [ $JVM_FLAG ]; then
  curl -s "https://get.sdkman.io" | bash
  source ~/.sdkman/bin/sdkman-init.sh

  if [ "$(uname)" == 'Darwin' ]; then
    if [ "$(uname -m)" == 'arm64' ]; then
      sdk install java $JVM_VER-zulu
    else
      sdk install java $JVM_VER.9-ms
    fi
  else
    sdk install java $JVM_VER-ms
  fi
sdk install $JVM_MODULES
fi
```

$JVM_FLAGがfalseならインストールしないし、各種アーキテクチャによってパッケージを変えるが、すべて同じバージョン。
現状はruby,nodejs,jvm,rust,haskellに対応してる。

https://github.com/akihirof0005/dotfiles/tree/main/install

##　最後に
これからは`config.json`をパソコンごとに変更するだけで環境を作れます。
やっぱりdotfile用にフレームワーク作りたい。

もっとクールなやり方あったら教えて下さい。
Docker Machineインストールでエラー

#結論
```:コマンド
curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Darwin-x86_64 >/usr/local/bin/docker-machine && chmod +x /usr/local/bin/docker-machine
```

以下のDoc通りのコマンドではDocker Machineをインストールすることはできませんでした。
ご注意を。
https://github.com/docker/machine/releases/

本当にインストールしたかどうかを確認するコマンドは以下です。

```:コマンド
docker-machine version
```

みなさん、楽しいDocker Lifeをお過ごしください☺️

@ryu0121
【Rails】 Deviseでundefined local variable or method `resource_class'が出た時の対処

# undefined local variable or method `resource_class'が出た時の対処法

## 背景
- deviseのストロングパラメーターに新たなパラメーターを追加して新規登録画面を実装しようとしていたところ上記のエラーが発生
- ローカル変数またはメソッド`resource_class'が未定義のためエラーが発生している様子

## 該当箇所
```rails:application_controller
    before_action :configure_permitted_parameters
    
    protected
    
    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :phone_number, :postcode, :address])
    end
```

## 修正箇所
- before_action :configure_permitted_parametersの後にif: :devise_controller?を追加することで無事修正完了

```rails:application_controller
before_action :configure_permitted_parameters, if: :devise_controller?
    
    protected
    
    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :phone_number, :postcode, :address])
    end
```

## 補足情報
devise_contoller?はdeviseを導入することで利用可能なヘルパーメソッドの一つで、「deviseに関連する画面で処理を行った時に」という意味合いがあり、これによってapplication_controllerと紐付けている。
Rails マイグレーションファイルでミスがあった時

```db/migrate/202*********_create_items.rb
class CreateItems < ActiveRecord::Migration[6.0]
  def change
    create_table :items do |t|
      t.string :name, null: false
      t.text :info, null: false
      t.integer :category_id, null: false
      t.integer :status_id, null: false
      t.integer :fee_status_id, null: false
      t.integer :prefecture_id, null: false
      t.integer :schedule_delivery_id, null: false
      t.integer :price, null: false
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
  end
end
```

例えば、nameカラムをstringにしているわけですが、これをtextに変更したいという時ですね。

まずはマイグレーションの状況を確認します。

```
rails db:migrate:status
```

```
database: app_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210*********  Devise create users
   up     20210*********  Create items
```

こんな感じで出力されて、upとなっているのが、すでにマイグレーション済みとなります。

```
rails db:rollback
```

このコマンドを実行すると

```
database: app_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210*********  Devise create users
 down     20210*********  Create items
```

というふうに、最新のマイグレーションファイルがdownになります。
この状態であれば、2番目のマイグレーションファイルを修正して、再度、

```
rails db:migrate
```
を実行すればOKです。

仮に上のマイグレーションファイルを修正したいときはもう一度

```
rails db:rollback
```

を実行して、ファイルを修正したのちにいつも通り、マイグレーションを実行です。
そうすると、全てのファイルがマイグレーションされるので、2番目のファイルも自動的にマイグレーションされます。
Gitコマンドにエイリアスを付けてみる件

##はじめに
この記事はGitの扱いに慣れていない方に向けた記事です。
そして私の備忘録にもなっておりますのでどうぞ温かい目で。。。

##この記事を書くに至った経緯
まだ新卒で今の会社に入社して２ヶ月。
現場の開発ではGitHubが多く使われるのは周知の事実ですが、お恥ずかしい話私自身gitやgithubはあまり詳しくありません。。。
学生時代は就活のためにSwiftでIOSアプリを作って、個人開発なのに無駄にbranchきって無駄にプルリク出してマージするといったことを行なっていました。当時は「Githubも使えるんだ」とアピールしたかった自分がいましたが今となっては逆効果な気もします。。。

話が逸れてしまいましたが、今回Gitコマンドの学習をするにあたって「エイリアス」という便利なコマンドを発見しました!!（素人なんです。どうか温かい目で。。。）

エイリアスとは何か、そしてどのような使い方をするのがこの記事でご説明させていただきます。

##エイリアスという言葉の意味は？

wikipediaによると「エイリアス (英: alias) は、「別名」あるいは「偽名」などを意味する英語の名詞である。」だそうです。
要は「あだ名」みたいなもんですかね。

例１）柿原さん→カッキー
例２）なつみさん→なつみーる

##gitにおけるエイリアスとは？？

もう上で答えを述べたようなもんでした。。。笑　
「コマンドにあだ名をつける」とでも言うのが正解でしょうかね。

例えば

```
$ git status
```

実に見慣れたコードであるが打つのはめんどくさい。。。
そこで登場するのがgitコマンドのエイリアスです。


```
$ git config --[option] alias.st status
```
このコマンドを打つことでgit statusが

```
$ git st
```
にて機能するようになります！
[option]には
--system にてマシン全体にコマンドを反映させる
--global にてユーザ単位でコマンドを反映させる
ことができるようです、便利すね。。、笑

例）ユーザ単位でコマンドのエイリアスを行いたい場合

```
$ git config --global alias.st status
```

もちろん、statusコマンドだけでなく、branchを変更するcheckoutコマンドなどもエイリアスを使用することができます！

例）checkoutコマンドをユーザ単位でエイリアスを行う場合

```
$ git config --global alias.co checkout
```

これはいい！！！（素人丸出し）

##終わりに
学生時代のgitといえばadd、commit、push。そしてbranchをきってmasterにマージしてとgitやgithubの浅いところまでしかできてなかったんだなと社会人になって気がつきました。。。
現在udemyのgit講座や実際に手を動かしながら学んでおりますので今後とも発信していきますのでどうぞよろしくお願いいたします。
Windows + Visual Studio 2019 で EDK2 の OVMF をビルドする【3.OVMFのビルド】

#【目標】
『Windows 10 に EDK2環境 を構築し、Visual Studio Community 2019 を
　使って OVMF(OvmfPkg) をビルドする。』


#【前回まで】
前回でEDK2環境の準備が完了し、HelloWorld.efiがビルドできました。
今回は目標となっていたOVMFをビルドします。
OVMFとは何ぞ？という方はこちらをご覧ください。
https://github.com/tianocore/tianocore.github.io/wiki/OVMF
ざっくりと仮想PCで動作するUEFI一式みたいな感じです。


#【今回の目標】
64bit版OVMF(OvmfPkg)をビルドします。
ビルドしたOVMFでQEMUを動作させたいと思います。


まず EDK2ビルド用コマンドプロンプト を準備します

#【EDK2ビルド用コマンドプロンプト】
・スタートメニューより<B>「x64 Native Tools Command Prompt for VS 2019」</B>を
　開いて、次の通り入力します
　<B>chcp 65001</B>
　※使用する文字コードをUTF-8にしてビルド実行中の日本語文字化け
　　に対処します。
　<B>cd C:\EDK2</B>
　<B>edksetup.bat</B>
　※以下の1つのエラーは気にしないでください
　　- 「!!! ERROR !!! Binary C tools are missing. They are required to be built from BaseTools Source.」
　　　BaseToolsでsplit.exeを生成しなくなったのにチェックして
　　　いるようです
　※以下の2つのワーニングが出ますが気にしないでください
　　- 「!!! WARNING !!! CLANG_BIN environment variable is not set」
　　　今後も CLANG は使わないので設定しません
　　- 「!!! WARNING !!! No CYGWIN_HOME set, gcc build may not be used !!!」
　　　今後も CYGWIN は使わないので設定しません
・<B>そのまま【64bit版OVMF(OvmfPkg)のビルド】へすすみます</B>
・https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems
　「Build」に記載の手順となります

次に 64bit版OVMF(OvmfPkg)のビルド をやってみます

#【64bit版OVMF(OvmfPkg)のビルド】
・引き続き<B>「x64 Native Tools Command Prompt for VS 2019」</B>で
　次の通り入力します
　<B>build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t VS2019 -b DEBUG</B>
　Visual Studio 2017 の場合は、VS2019 を VS2017 としてください。
・<B>"Done" が出たらビルドは終了です</B>
・以下のように入力して <B>OVMF.fd が出来ていたら成功</B>です
　<B>dir C:\edk2\Build\OvmfX64\DEBUG_VS2019\FV\OVMF.fd</B>
　こちらもVisual Studio 2017 の場合は、VS2019 を VS2017 としてください。


せっかくですので、QEMUを使って ビルドした64bit版OVMF の動作確認をします。
https://www.qemu.org/
まずはQEMUのインストールから。


#【QEMUのインストール】
・<B>64bit版のインストーラーを使ってインストール</B>します
　https://www.qemu.org/download/#windows
・このインストールでは特別な設定が必要ありませんでしたので、
　画像などは省略します
・その他はお好みで設定してください


#【ビルドした64bit版OVMF】
・コマンドプロンプトを開いて次の通り入力します
　"C:\Program Files\qemu\qemu-system-x86_64.exe" -machine q35,smm=on -m 8G -smp 4 -global ICH9-LPC.disable_s3=1 -bios C:\EDK2\Build\OvmfX64\DEBUG_VS2019\FV\OVMF.fd -net none
　こちらもVisual Studio 2017 の場合は、VS2019 を VS2017 としてください。
・各パラメータの意味は以下の通りです
　-machine q35,smm=on　：　仮想PCのHW構成を指定しています
　-m 8G　：　仮想メモリとして8GBを指定しています
　-smp 4　：　使用するCPUコア数として4を指定しています
　-global ICH9-LPC.disable_s3=1　：　64bit版OVMF使用時に必要となる指定です
　-bios C:\EDK2\Build\OvmfX64\DEBUG_VS2019\FV\OVMF.fd　：　ビルドした64bit版OVMFです
　-net none　：　ネットワークなしを指定しています
・ビルドした64bit版OVMFでQEMUが起動すると、以下のような画面になります。
![Qemu-Ovmf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1491958/b4f837dc-4706-13f4-49bd-000647fa404f.png)
・64bit版OVMFなしでQEMUが起動すると、以下のような画面になります。
　パラメータ不正の場合にはQEMUが起動しないかもしれません。
![Qemu-NoOvmf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1491958/adc65543-12d3-b5f9-399e-3e4ae1676938.png)




OVMFのビルドはここまでです。目標は達成しましたが、
もう少し続くかもしれません。
ありがとうございました。
React-Reduxに関する理解

# はじめに
React+React-Reduxを用いてWebシステムを開発しているの際に引っかかった所やよく分からなかった箇所の復習用にこのような記事を投稿しようと考えました。

# Reduxってなに？
簡単に説明すると、ReduxとはUIの状態を簡単に管理できるフレームワークです。
このReduxをReactと組み合わせて使う場合、UIの状態を専用の場所(ストア)で管理し、Reactはそれを表示するだけの役割を担っています。

# フロー全体図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614955/c977b3b0-ecfc-c88c-1f50-c7aa2e4d1a98.png">

* 画面から入力されたInputをもとにAction Creatorからactionがdispatchされる
* Reducerがdispatchに対してStore内のstateを更新する
* 更新されたstateを参照する

# Store
コンポーネントの状態(state)を集約している場所

# ActionとActionCreator
Actionとは、store内のstateを変更するためのオブジェクトになります。
Actionを発行することでReducerが現在のstateとactionを元に新しいstateを作成します。
Actionを追加するごとにconnectするわけにはいかないので、Actionを生成する関数を定義する必要があります。これをActionCreatorと呼びます。


# Reducer
Actionが発行された時、このReducerが反応します。Reducerは送られてきたActionと、元のstateをもとに新しいstateを返す関数です。

# connect
Reactのコンポーネント単体では、Reduxを利用することはできません。Reduxを使えるようにするためにはReact-Reduxのconnectという関数を用いて下記のように書きます。

```JavaScript:sample.js
1  export default connect(
2    (state) => (state.myStore),
3    (dispatch) => bindActionCreators({ ...myStore.actionCreators }, dispatch)
4  )(MyComponet);
```
* 2行目
    * storeのstateをpropsとしてコンポーネントに渡す。
* 3行目
    * 発行したactionを指定する。
* 4行目
    * どのコンポーネントにstoreを接続するのか指定する。

# mapStateToPropsとmapDispatchToProps
1. mapStateToPropsは、コンポーネントに渡したいstateを入れることができます。
2. mapDispatchToPropsは、actionをstoreにdispatchしてくれる関数です。

# 最後に
ここまで自分の理解できている範疇で書いてみましたが、まだまだ不明瞭な点が多いのが正直なところです。
さらに勉強して知識を蓄えていきたいと思います。
Git cmd (Note)

# Content
- Check Git version
- Add source to Git
- Clone
- Create new branch
- Delete branch
- Pull
- Push
- Merge

# Check Git version
- git version

# Add source to remote
1. Go to source folder.
1. Add source to Git.
    1. git init  `For first time using git`
    1. git remote add origin [GIT_LINK : Will get after created repository] `Set a new remote`
    1. git remote -v `Verify new remote : Will show detail of process`

# Clone

#### Clone master of Git repository
- git clone [GIT_LINK]

#### Clone branch of Git repository
- git clone -b [BRANCH_NAME] [GIT_LINK]

# Create new branch
1. Clone the original project for create branch.
1. Go to No.1's project folder.
1. Switch to new b
    1. git checkout -b [NEW_BRANCH_NAME] [No.1's BRANCH_NAME or MASTER]
1. Push created branch to remote.
    1. git push --set-upstream origin [NEW_BRANCH_NAME]

# Delete branch
- git push --delete origin [BRANCH_NAME]

# Pull
Firstly, go to project folder and run following command.

#### pull lastest source from master
- git pull origin master

#### pull lastest source from branch
- git pull origin [BRANCH_NAME]


# Push
- git push



# Merge
#### Merge
- git merge [BRANCH_NAME]

#### Cancel merge
- git merge --abort
RealSenseによるフィルター処理後の距離取得に関して

<h2>困ったこと</h2>

以下のソースコードでRealSenseで得た画像からピクセル座標指定で深度を取得しようとしました

```test.py
frames = pipeline.wait_for_frames()  # realsenseから画像取得
depth_frame = flames.get_depth_frame # 画像から深度画像取得

# フィルター処理
temporal = rs.temporal_filter()
depth_frame = temporal.process(depth_frame)

# 深度画像からピクセル座標(100, 100)の深度を取得
distance = depth_frame.get_distance(100, 100)

```

すると以下のようなエラーが起きます。

```
distance = depth_frame.get_distance(100, 100)
AttributeError: 'pyrealsense2.pyrealsense2.frame' object has no attribute 'get_distance'
```

フィルター処理しなければこのようなエラーは起きません。
しかしフィルター処理した後のdepth_frameからはget_distance関数が呼べないそうです。

<h2>解決方法</h2>
フィルター処理した後に以下のコードを追加します。

```
 depth_frame = depth_frame.as_depth_frame()
```

すなわち最初のソースコードは以下のように修正されます

```test.py
frames = pipeline.wait_for_frames()  # realsenseから画像取得
depth_frame = flames.get_depth_frame # 画像から深度画像取得

# フィルター処理
temporal = rs.temporal_filter()
depth_frame = temporal.process(depth_frame)
depth_frame = depth_frame.as_depth_frame()　# ←追加

# 深度画像からピクセル座標(100, 100)の深度を取得
distance = depth_frame.get_distance(100, 100)

```
JPCYBER S3 DriveのACL適用オプションを確認する

# はじめに
S3をマウントしてエクスプローラーから扱えるようにするJPCYBER S3 Driveですが、その設定オプションの中に「親バケットのACLをアップロードするファイルに適用する」というものがあります。
この動きが良く理解できていなかったので試してみました。

・JPCYBER S3 Drive
https://www.jpcyber.com/

# 実行手順
## 事前準備
以下は事前に準備しています。
・EC2(Windows)
・JPCYBERインストール
・S3バケット作成


## 事前確認
開始前のS3バケットACLの設定は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/078fc006-6be1-5740-9c88-2be23c0ce6b0.png)


## オプションを設定しない場合
まずは何もオプションを設定しない状態でアップロードした時のオブジェクトACLを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/5e387fee-c2e0-b9e3-182e-b06438bab643.png)

オブジェクトACLはS3バケットACLと同じものが設定されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/3f4c642b-ed07-13f6-e6cf-dfafde3da677.png)

S3バケットACLに外部アカウントを1つ追加してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/b87c70fe-ed35-4089-cca3-3216a6a05c78.png)

再度ファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/4551e914-9e2f-9c3b-63f0-9dac5b7538ab.png)

ACLは最初のものと特に変わっていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/546d4af6-ad43-b5db-378b-f5d0af28033d.png)


## オプションを設定した場合
それでは次はオプションを設定して試してみます。

以下の項目にチェックをつけて保存ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/5cd70e43-53e4-e74a-3627-c5a9862d8be2.png)

サービスの再起動が終わったらファイルをアップロードしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/51cd3900-9001-f548-2176-af8f827a3c25.png)

アップロードしたファイルのオブジェクトACLを確認するとS3バケットACLと同じ設定になっていました。
オブジェクト一つ一つに同じACLを設定するのは手間なので、JPCYBER経由でアップロードする時には自動的に設定したいということがあればこのオプションを使えば良さそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/65fb658c-c8c3-1656-f832-987f8aafd30a.png)

## 注意点
公式の[JPCYBER S3 Driveのオプションを設定する](https://www.jpcyber.com/support/s3-drive-option-settings)ページに以下の注意書きが書いてますので、使用する際は理解した上でご使用ください。

>有効にした場合は性能が低下します。必要ない場合は、off のままにしてください。

# 終わりに
そもそもACLについての理解も曖昧だったので、前回記事含めて理解のために検証してみました。
[過去記事](https://qiita.com/handy-dd18/items/8bd91eba22d46ab66ba9)にも書いてますが、JPCYBERのインストール先が別のAWSアカウントの場合は権限の問題で失敗することもあるのでご注意ください。
【SQLの学習】SQLコマンド/テーブル処理

# 今週の学習課題
・ SQLのコマンド/テーブル処理の知識習得

# 学習内容・結果
#### 1. SQLコマンド
　　-SELECT
　　–DISTINT
　　–WHERE
　　–AND OR
　　–IN
　　 etc...

#### 2. テーブル処理　
　　–CREATE TABLE
　　–SHOW DATABASE
　　–DROP DATABASE
　　–SHOW TABLE
　　 etc....

**覚えておきたいSQLのルール**
必ずコマンド分の語尾には「；」(セミコロン)を入力すること。

 > SELECT NAME FROM Food_Information;

アスタリスク「＊」は「全て」を意味する

 > SELECT * FROM Food_Information
   WHERE Price > 1000;

#### 《SQLコマンド:SELECT》
名の通り、データを選ぶ時に使用しますが、具体的には「どのカラム名(列)からデータを持ってくる」か指定できます。
使用する際は「FROM」と一緒に打ち込みます。
 > SELECT **<カラム名>** FROM **<テーブル名>**;
 > SELECT NAME FROM Food_Information;

「Food_Information」というテーブルから「NAME」の情報を持ってくるという意味になります。

####《SQLコマンド:WHERE》
WHEREは特定のデータを取得する際に必要となります。
どこのレコードを取得するかという意味になります。

> SELECT * FROM Food_Information
   **WHERE Price > 1000;**

「Food_Information」というテーブルから「Price」が1000以下のものを表示(全カラム：SELECTで＊を指定している為)させる。

####《SQLコマンド:CREATE TABLE》

データベースの追加が実行できます。

 > CREATE TABLE **<テーブル名>**
 > CREATE TABLE Food_Information;

####《SQLコマンド:SHOW DATABASE》
CRETE TABLEで作成されたデータベース名一覧を表示させます。

 > SHOW DATABASE;


# 来週の目標
SQLの復習・学習
最終的にはCRUD・TRUNCATEを習得
旧Edgeの長所を発見したったwww

Chromiumを取り入れたことにより、今までの使い辛さが一新され、[復活を見事果たした](https://gs.statcounter.com/browser-version-partially-combined-market-share/desktop/japan/#monthly-202001-202012 "Edge 79+のシェアの伸びに注目！1月のEdge18よりも12月のedge 79+の方がシェアが高い。")Edge。しかし、かつてのEdgeHTML版Edge(以降旧Edge)にもいい部分はある。それは`<select>`要素に`Tab`キーを使ってフォーカスした際に分かる。
なんと、CSSの`outline`を`0`にしていても、必ずフォーカスした要素の中身を青塗りしてくれるので、フォーカスしているのが分かりやすいのだ。

[クロノドライブのHTML辞典さんのサンプル](https://html-coding.co.jp/annex/dictionary/html/select/)を旧Edgeで開いてみると…
![Edge_Focus.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/0e2063e2-ed3f-06ec-1fcb-9ba8a02b0581.jpeg)

これはIEの表示を引き継いでいます。技術的負債の代表格と言えるIEだが、これはGJ。
![IE_Focus.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/ec3ce161-a084-7661-41a4-142629d41313.jpeg)


こちらはChrome。きれいな白だろ。うそみたいだろ。フォーカスしてるんだぜ。これで。なお、中身が同じ新生Edgeも同様。退化してるじゃん。
![Chrome_Focus.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/d62e18a4-776b-382d-897c-7221afccca51.jpeg)

Firefoxは申し訳程度にふちを着色します。旧Edgeに比べるとしょぼいです。わかりづらい。
![Firefox_Focus.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/2bb3b7f1-3c49-83d7-4551-f1d13b830a58.jpeg)

知り合いのMacを借りてSafariを見てみたが、やはりフォーカスが無い。

なんということでしょう。アクセシビリティを考えると、旧Edge（およびIE）は大変素晴らしいではありませんか。かろうじて次点が~~人気の無い（けど私は好き）~~Firefox。まあ、`outline`を消さなければいい話なのだが。

#他のブラウザでもこの挙動を再現してみる
`<select>`の中身が青く塗られていて、見やすい旧EdgeのフォーカスをCSSで再現してみると…

``` select_color_blue.css
select:focus {
    color: white !important;
    background-color: dodgerblue !important;
}
select:focus option {
    color: black !important;
    background: white !important;
}
```

これでChromeでも、`select`を選択していることが丸わかりになるぞ。ちなみにfocusフォーカスした`<option>`の色はブラウザで決まっていて、Chrome、旧Edge、IEは`dodgerblue`、Safariもおそらく`dodgerblue`、Firefoxは青系統だが`dodgerblue`より濃い色、新生Edgeは渋い灰色だ。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="NagayamaToshiaki" data-slug-hash="rNypKyJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Chromeでも旧Edge風select">
  <span>See the Pen <a href="https://codepen.io/NagayamaToshiaki/pen/rNypKyJ">
  Chromeでも旧Edge風select</a> by Nagayama Toshiaki (<a href="https://codepen.io/NagayamaToshiaki">@NagayamaToshiaki</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

そもそも、見てくれがかっこよくても使い勝手が悪ければ悪印象だ。良い子のみんなは`:focus`の`outline`を上書きしないようにな。そのうえで、今回の青背景を採用するとさらにユーザーにやさしくなるぜ。マウスが動かせない人だけじゃなく、マウスを触るのがおっくうな人もいる（アクセシビリティは、しょうがいを持った人に対する特別な配慮に留まらない）ことを忘れないようにしてくれ。お兄さんとの約束だぞ！
[Ruby]無限ループ方法まとめ

## はじめに
Rubyで無限ループを使う時に調べたらいくつかの方法が出てきたのでメモ。

## 無限ループ方法
無限ループとは、eachなどのメソッドのように、何回ループさせるか決めない時、処理を常に実行し続けたい時にしようします。
無限ループを止める場合は`break`や`return`を使って終了させます。

###1. while
`while`は`true`の時にループします

```
while true do
  p “ループ”
end
```

###2. until
`until`は`false`の時にループします

```
until false do
  p “ループ”
end]
```

###3. loop

```
loop do
  p “ループ”
end
```

###4. step
```
1.step do |i|
  p “ループ”
end
```

## おわりに
今回は無限ループの方法をまとめてみました。
他にも別のループ方法があるよ！という方はメッセージいただけると幸いです。
AWS CLIを使ったカスタム属性の変更

# 環境構築
　　ここではWindowsだけに関しての環境構築について説明する。MacやLinuxに関しては公式サイトをご覧ください。まずは、msiexec.exeをダウンロードして、環境を備える。

```Windows:Windows-cmd
C:\Users\User.Name>msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
C:\Users\User.Name>aws --version
aws-cli/2.2.7 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
C:\Users\User.Name>aws configure
AWS Access Key ID: ACCESSKEYID
AWS Secret Access Key:SECRETACCESSKEY
Default region name:ap-northeast-1
Default output format:json
```
　　基本的にインストールして、バージョン確認する感じ。次に、IAMでユーザーを作成して、必ずSecret Access Keyをダウンロードしてください。次に、ユーザーの権限をAdministratorAccessに変更または追加する。これで環境構築は終わる。

# Cognitoに対するアクセス 
　　AWSのサービスに対するアクセスはすべて「aws」で始める必要がある。Cognitoに対するアクセスも同じである。

```Windows:Windows-cmd
C:\Users\User.Name>aws cognito-idp
```

　　こんな感じだね！次に、何の操作をするかを考える。カスタム属性の変更をするので、admin-update-user-attributesでカスタム属性を変更しましょう。

```Windows:Windows-cmd
C:\Users\User.Name>aws cognito-idp admin-update-user-attributes
```

　　AWS Configureではどのユーザーがアクセスするかを決めたが、ユーザープールはどうするか、ユーザーネームはどうするかをこれから決める。

```Windows:Windows-cmd
C:\Users\User.Name>aws cognito-idp admin-update-user-attributes --user-pool-id ap-northeast-1_userpool --username TestUser
```

　　最後はどの属性を変更するかを決める。

```Windows:Windows-cmd
C:\Users\User.Name>aws cognito-idp admin-update-user-attributes --user-pool-id ap-northeast-1_userpool --username TestUser --user-attributes Name="custom:status",Value="1"
```

　　これだけで特定のユーザーのカスタム属性を1に変更することができた！ちなみに実行したら、何も返ってこないので、実際にCognitoを起動して確認しましょう。
GravioでCO2の移動平均を測定する

Gravioで測定していたCO2の測定結果のグラフがギザギザして気持ち悪いので移動平均をとってみた。
GravioにはStatisticsコンポーネントというのがあって、簡単にデータの統計が計算できる。

# 使用環境

* Raspberry Pi 4 Model B w/4GB RAM
* Ubuntu Server 20.04.2 LTS
* Gravio HubKit v4.3.0-6722
* Gravio Studio v4.3.4162.0
* Gracio CO2センサー (Gravio Standardの契約が必要)
* PowerBI

# 事前準備
* 「[Gravio 4とPower BIでCO2を可視化する][CO2-PowerBI]」「[Gravio 4で2つの部屋のCO2濃度をPowerBIで可視化する][CO2-PowerBI2]」を参考にCO2データを取得できるようにしておいてください。

# アクションにコンポーネントを追加する
「[Gravio 4で2つの部屋のCO2濃度をPowerBIで可視化する][CO2-PowerBI2]」でロケーション付きでポストしていたアクションの中に、[Sensor Data DBコンポーネント][Gravio-SensorDataDB]、[Statisticsコンポーネント][Gravio-Statistics]、[HTTP Requestコンポーネント][Gravio-HTTPRequest]の3つのコンポーネントを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/9ef25bb2-7670-a24a-b4f6-9cd906107cfc.png)

Sensor Data DBでは、移動平均を取るための過去データを取得します。
Statisticsでは取得してきた過去データから統計値を計算します。
HTTP Requestでは移動平均の値を別途PowerBIにポストします。
つまり、上のStep 1では生データを、Step 4では移動平均をPower BIにポストするということですね。

各コンポーネントの中身です。
まずはSensorDataDBです。今回は10分間の移動平均を取りたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/c7e8c776-f571-5eaa-45b6-97d5e416dc7d.png)

「エリアID」と「レイヤーID」には対象のレイヤーを指定します。
「From Previous」と「タイムスケール」で「10分」となるように指定します。
これで、10分間のデータが取得できます。

次にStatisticsです。統計データを計算する対象を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/f2cab8b3-0e0f-2c4e-4abd-30bb902a31b9.png)
今回はSensorDataDBから取得したデータの統計を取りますので、「値式」には `cv.Payload.Data`を指定します。SensorDataDBからの出力はペイロードのDataとして渡されますからね。

最後にHTTPRequestで平均値をPowerBIにポストします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/0ea0e822-031e-1ae4-c77e-541ffdc6e61c.png)

PowerBIへ投げるために、Step 1と同じように「HTTPメソッド」と「URL」を指定します。
ポストする内容は同じように`cv.Payload`に指定します。ここで、Statisticsコンポーネントの計算結果は`cv.Statistics`として格納されています。ですから、ここではこのように平均値を参照します。
エリア名にもわかりやすいように `10分移動平均`と追加しておきます。

```:cv.Payload
cv.Payload = [{"Location": tv.AreaName + "10分移動平均", "Timestamp": tv.Timestamp, "CO2": cv.Statistics.Average}]
```

# 結果
PowerBIに移動平均を送ることができました。移動平均にするとグラフが滑らかになりますね。
まぁ、BIツールならそちら側で移動平均を計算することも簡単だとは思いますが、エッジで計算するのもの簡単ですね。これくらいの修正なら慣れれば3分ですよ。😁

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/69a327ec-3921-7d5f-a650-049f78b95fdd.png)

# 発展
Statisticsコンポーネントでは他にも最大値や最小値、中央値なども計算できます。いろいろポストすると面白いと思います。
また、今回はCO2データを取得するたびに計算してましたが、1時間に1回、1日に1回実行することでもっと粒度の大きな傾向がつかめてくると思います。
ぜひいろいろ試してみてください。


# 参考
* [Gravio 4とPower BIでCO2を可視化する][CO2-PowerBI]
* [Gravio 4で2つの部屋のCO2濃度をPowerBIで可視化する][CO2-PowerBI2]
* [Gravio][]
* [Sensor Data DBコンポーネント][Gravio-SensorDataDB]
* [Statisticsコンポーネント][Gravio-Statistics]
* [HTTP Requestコンポーネント][Gravio-HTTPRequest]



[CO2-PowerBI]:https://qiita.com/zrock/items/08148659ebf523f5c160
[CO2-PowerBI2]:https://qiita.com/zrock/items/8ccbbe588a4aaa675122
[Gravio]:https://www.gravio.com/jp
[Gravio-SensorDataDB]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/sensordb-recent
[Gravio-Statistics]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/statistics
[Gravio-HTTPRequest]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/http-post-action-component
Dockerコンテナの中で Github Actions のセルフホストランナーを動かす

# 概要
- Github Actions には[セルフホストランナー](https://docs.github.com/ja/actions/hosting-your-own-runners)と言う仕組みがある
    - 以後、セフルホストランナー = ランナーと表現する。
- 1台のマシンで複数のランナーを動かしたい場合、コンテナで動かすことができれば最大メモリの指定など他への影響を抑えることが出来る。
- コンテナで動かす手順をメモとして残す

# ざっくり処理の流れ
- Dockerfile で apt-get して必要なライブラリをインストール、ランナーのファイルをコピーしてベースとなるイメージを作成。
- コンテナを起動し bash などでシェルからランナーの設定コマンドを実行
- ランナーの起動コマンドを実行

# コマンド実行しなければ設定できないのか?
- github で提示されている手順にまずは則るため
- (Dockerfile のみで完結するのが望ましいのが…)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517184/9393734e-a1fa-7643-e625-d453a0e9b094.png)

# 検証環境
- Windows10 Pro
- WSL2
    - Ubuntu 20.04
- Docker Desktop

#  手順
- WSL2 の Ubuntu で操作
- 以下内容で `Dockerfile` を作成

```Dockerfile:Dockerfile
FROM ubuntu:20.04
COPY *.tar.gz /root
COPY packages-microsoft-prod.deb /root

# sudo せず root で実行するための設定
ENV RUNNER_ALLOW_RUNASROOT=0

# ランナーが .NET を使うのでインストールする
RUN apt-get update && \
    apt-get install -y ca-certificates && \
    dpkg -i /root/packages-microsoft-prod.deb && \
    apt-get update && \
    apt-get install -y dotnet-runtime-5.0
```

- Dockerfile と同じ場所に以下をダウンロードして配置
    - https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz
    - https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb

- 以下コマンドでコンテナイメージをビルド
    - `docker build -t testrunner .`
    - `docker images` で確認

- 以下コマンドでコンテナを起動し bash で接続
    - `docker run -i -t testrunner bash`

- ランナーのファイルを解凍し、github のランナー追加時の configure に従い config.sh を実行する
    - `cd /root`
    - `tar zxf actions-runner-linux-x64-2.278.0.tar.gz`
    - `./config.sh --url <githubのランナー追加対象URL> --token <トークン>`
        - ランナー名やラベルを適当に設定
   
- run.sh で起動
    - `./run.sh`
    - バックグラウンドで実行する場合は & をつける
[Symbol] ノード(bootstrap)のバージョンアップ

# 概要
- 前回記事で構築したノードのbootstrapのバージョンアップ手順を残します。
- 本記事は、ubuntu 20.04、symbol-bootstrap (v1.0.3 -> v1.0.6 へ更新)で確認しています。
- 委任してもいいよという方は「**symbol-node.takagi-tech.com**」まで
- 投げXYMは「**NDLS6GYOIPHATATNAVVOUNJXBD6X4BXU6IRBHIY**」まで

https://qiita.com/nobu_kyutech/items/beb5e05992c926e9f6ac

# 事前準備
最新バージョンの確認
GitHUb nemtech / symbol-bootstrap

https://github.com/nemtech/symbol-bootstrap/releases

# バックアップ
```sh
# target（一番大事なのはharvesters.dat）をバックアップ
$ cp -r ~/symbol-bootstrap/target ~/target_bak_v103_20210611
```

最悪ノードが壊れてしまった場合は、新規構築してharversters.datを置き換えれば、委任状態を保持して復旧可能です。


# バージョンアップ作業

```sh
# symbol-bootstrapの停止
$ cd ~/symbol-bootstrap/
$ symbol-bootstrap stop

# rootユーザーにスイッチ
$ sudo su -

# bootstrapのアップデート
$ npm update -g symbol-bootstrap
$ symbol-bootstrap -v
----
symbol-bootstrap/1.0.6 linux-x64 node-v14.16.1
----

# rootユーザーから抜ける
$ exit

# 設定反映
$ symbol-bootstrap config -p mainnet -a dual -c my-preset.yml --upgrade
$ symbol-bootstrap compose --upgrade

# 起動
$ symbol-bootstrap run -d

# 起動確認
$ symbol-bootstrap healthCheck
```

```
                         _             _         _                    _         _
  ___  _   _  _ __ ___  | |__    ___  | |       | |__    ___    ___  | |_  ___ | |_  _ __  __ _  _ __
 / __|| | | || '_ ` _ \ | '_ \  / _ \ | | _____ | '_ \  / _ \  / _ \ | __|/ __|| __|| '__|/ _` || '_ \
 \__ \| |_| || | | | | || |_) || (_) || ||_____|| |_) || (_) || (_) || |_ \__ \| |_ | |  | (_| || |_) |
 |___/ \__, ||_| |_| |_||_.__/  \___/ |_|       |_.__/  \___/  \___/  \__||___/ \__||_|   \__,_|| .__/
       |___/                                                                                    |_|
2021-06-11T07:18:40.541Z info     Container db is running
2021-06-11T07:18:40.542Z info     Container node is running
2021-06-11T07:18:40.547Z info     Container broker is running
2021-06-11T07:18:40.548Z info     Container rest-gateway is running
2021-06-11T07:18:40.550Z info     Container node port 7900 -> 7900 is open
2021-06-11T07:18:40.551Z info     Container rest-gateway port 3000 -> 3000 is open
2021-06-11T07:18:40.552Z info     Testing http://localhost:3000/node/health
2021-06-11T07:18:40.574Z info     Rest http://localhost:3000/node/health is up and running...
2021-06-11T07:18:40.574Z info     Network is running!
```

# 参考情報
- [Symbol Bootstrap更新手順](https://nemlog.nem.social/blog/63758)
- [NEM Symbol bootstrap のバージョンアップ](https://qiita.com/curupo/items/adbfe1b58119d3ffa401)
行列のMonge性（全単調性）について

#Monge性（全単調性）とは
<dl>
<dt>定義</dt><br><dd>$m$行$n$列の実数値行列$A=(a(i,j))$がMonge性（全単調性）を持つとは、
任意の$1\leqq s\leqq t\leqq m$, $1\leqq k\leqq l\leqq n$にたいして、$a(s,k)+a(t,l) < a(s,l)+a(t,k)$を満たすことをいう</dd>
</dl>

これは三角不等式になぞらえて、四角不等式とも呼ばれます。

さて、より詳しく理解するために行列で考えていきましょう。以下のような2行2列の行列を考えます。

```math
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
```

この時、$a+d \leqq b+c$であれば、この行列は**単調**であるといいます。
これを拡張し、任意の行列$A$に対して、どのように部分行列を選んでも単調であること場合に、$A$は**Monge（全単調）行列**といいます。

そこまで難しくありませんね。

#Monge性の応用
##SMAWK algorithm
Monge性の応用として最も有名なものに、高速な行列探索法として知られる_SMAWK algorithm（Aggarwal-Klawe-Moran-Shor-Wilbur 87）_というものがあります。
これは、行最小値発見問題を線形時間で解くアルゴリズムとして1987年に発表されたものです。この著者たちはものごっつい有名な方々なのでぜひ調べてみてください。
<dl>
<dt>行最小値発見問題</dt><br><dd>$n$行$m$列$（m>n）$の行列が与えられたとき、各行の最小値を求めよ</dd>
</dl>

参考書によっては最大値を扱うものもありますが、どちらの場合も同じアルゴリズムで解くことができます。（Monge性の不等式の不等号が反転しますが...）

詳しいアルゴリズムは元論文：[_Geometric applications of a matrix-searching algorithm_ ](https://link.springer.com/article/10.1007/BF01840359)をご覧ください。

##DAG（有向非閉路グラフ）への応用
計算幾何学における有名な問題の1つに、凸$n$角形の最適$k$角形近似問題$（k<n）$があります。
この問題は、凸$n$角形の各頂点をグラフのノードとすることでDAGの$k-$リンク最大重み経路問題に帰着することができます。

Monge性を持つDAGにおいて、最大重み経路は$O(n)$で計算できることが知られています。

これを、$k$個のリンクを持つ経路に拡張するために、**パラメトリック探索**という探索方法が用いられます。

より詳しい理解を得たい方は、こちらの論文：
[_Finding a Minimum-Weight k-Link Path in Graphs with the Concave Monge Property and Applications_ ](https://link.springer.com/content/pdf/10.1007/BF02574380.pdf)を参照ください。

<br>
この他、競技プログラミングなんかでもMongeDPを用いることで高速化を図るなんてことが多いみたいです。

#参考文献
- [浅野哲夫. "計算幾何―理論の基礎から実装まで." (2007).](https://www.kyoritsu-pub.co.jp/bookdetail/9784320121768)
- [Wikpedia _'SMAWK algorithm'_, (2021/6/11 access)](https://en.wikipedia.org/wiki/SMAWK_algorithm)