OmniAICreator/Qiita-1.07M huggingface dataset:
未経験からインフラエンジニアを目指して③

## フリースペース(好きに書かせて貰いますのコーナー)
ここ数日、時間があればネットワークの本を読んだりWeb検索してみたりと、知識を摑み取り状態で頭に詰め込んでいます。
<font color="blue">(摑み取りで詰め込んじゃったので、最初の方に詰めたのが出て来ず苦労しています。。。)</font>

大変な事に変わりは無いけれども、不思議と全く辛く感じていないのは
> **｢今やっている事＝自分の好きな事/やりたい事｣**

だからです。

やはり好きな事なら、何時間取り組んでいても全く苦にならないですし、壁にぶち当たっても｢なんとか乗り越えてやる！｣とエネルギーが湧いてきます。
家族からは｢四六時中やってて疲れない？張り切り過ぎじゃない？｣と言われましたが
｢はい！疲れませんけど何か！！何ならまだまだ出来ますけど！！！｣と眩しい笑顔で返したら
見た事無い顔で呆れられました(笑)
・・・でも頑張り過ぎには注意します、やっぱり体が資本ですもんね。

**＜お知らせ＞**
当面の目標については目的意識がブレないように、毎回記載しています。
無事達成して次の目標を定める時には随時更新していきます。
## 取り組み内容(当面の目標)
- ネットワークについての知識を会得し、理解を深める
- 頭で覚えただけでなく、きちんと専門用語を用いて説明出来るようになる
- 資格取得(CCNA)する

**<font color="Red">資格取得はスタートライン！実際の作業で滞りなく行えるようになる！！</font>**
## 今回行った学習
**1. アプリケーション層**
ここまで進めてきて朗報です。
｢この用語の仕組みまで知っている！｣｢用語知らなかったけどその仕組み知ってる！｣
というのが結構出てきました。
量販店勤務時代に調べて覚えた事が役立つ日が来るとは、ありがとう、20代の自分。

これまで｢？｣の連続だったので「URL」や｢POP｣｢IMAP｣といった、見た事あるor知ってる
用語が出てきて、懐かしい旧友と再会した時のようなとても安心した気持ちになりました。

とはいえ、初めて見る用語やきちんと仕組みを理解出来ていない事もありましたので
これまで通り着実に学習を進めました。
それでも｢それってどういう事！？｣となる事は殆どなく｢なるほど、そういう仕組みなのか｣とすんなり理解できたと思います。

**2. インターネットとセキュリティ＆無線LAN**
ここでも｢知ってる！｣が結構ありました、本当にありがとう、20代の自分。
ただし、プロキシサーバーおいては｢よくわからないけど、現状ネット繋がっているし
覚えなくていいや｣と当時の私は考えていました。
今回はきちんと用語に向き合い、あちこち調べて仕組みについては理解出来たと思います。

無線LANについても｢規格｣｢SSID｣といった知っている用語が出て来てプチ同窓会気分です。
ただ気を引き締めなければと感じ、油断せず少しづつ学習を進めました。
何故なら｢<font color="red">無線LANは便利だけどトラブルが多いから</font>｣です。
かつての仕事でお客様対応時に｢無線が繋がらない｣といった問い合わせが一番多かったです。
学習で利用している本にも電波干渉の事やチャンネル切り替えの事が書いてあり
トラブル解決時には必要な知識になるので忘れないようにしようと思います。

**3. 冗長化について**
｢メインがトラブル発生した時のサブを事前に用意しておく事｣で合っているでしょうか。
STPやVRRPは初めて聞く用語でしたが、学習を進める事で概ね理解出来たと思います。

リンクアグリゲーションについてはこの用語自体は初めてでしたが、内容を理解する過程で
｢もしかして”あれ”と一緒か！？｣と思いました。
携帯の通信方法で｢キャリアアグリゲーション｣というのを聞いた事があり、そちらの方も
改めて調べてみたところ、リンクアグリゲーションとほぼ同じような仕組みだったので
｢ここでも以前の知識が役立った！｣と喜び飛び上がりました、周りに迷惑なので心の中で。

サーバーの振り分け機能については、今までなんとなくでしか分かっていなかったですし
負荷分散装置については初めて聞く装置でしたので、これまで通り少しずつ学習を進め理解を深めました。
## 今週の感想
今週から小さな一歩ではありますが、未来へ繋がる栄えある一歩を踏み出しました。
(せっかくなのでカッコ良く言ってみました)

覚悟をしていたとはいえ覚える事が多く、正直言えば頭パーン状態です。
でも冒頭に書いた通り｢やってて楽しい！｣の方がずっと上回っています。
今週でどうにかネットワークに携わる者として、必要な基本内容を頭に詰め込みました。
CCNA取得の問題集に取り組み始めていき、詰め込んだ知識を整理・定着させていきます。

最後に私はサッカー観戦が好きなので、某サッカー選手の座右の銘を書いて締めます。

>**｢頑張る時はいつも今｣**

ちなみに私は仕事をする時、この言葉を頭の片隅に置いて取り組んでいます。

**次回も学習した事を書いていきたいと思います。**
Rails Active Storageを用いた画像投稿機能

# インストール
```
$ bundle install
```
```:Gemfile
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```
```
% rails active_storage:install
% rails db:migrate
```
MiniMagickはImageMagickをrailsで扱えるようにしてくれるGem
ImageProcessingはMiniMagickで提供できない画像サイズを調整する機能です。
Active Storageは、ファイルアップロードを行うための機能でこれを使えば、フォームで画像の投稿機能が作れます。
## 参考記事
[【Rails 5.2】 Active Storageの使い方](https://qiita.com/hmmrjn/items/7cc5e5348755c517458a)
[RailsのActive Storageを使って画像アップロード機能の実装](https://takapinosuke.hatenablog.com/entry/2020/10/21/234140)
# 投稿画面の作成
```posts/new.html.erb
 <%=form_with(model: @post, url: posts_path, local: true) do |f| %>
 <h1>投稿する</h1>
 <textarea name="content"><%= @post.content %></textarea>
 <%= f.file_field :image %>
<input type="submit" value="投稿">
 <% end %>
```
file_fieldでファイル選択ボックスを生成
## 参考記事
[Railsドキュメント](https://railsdoc.com/page/file_field)
# コントローラの作成
```posts_controller.rb
def create
    @post = Post.new(
      content: params[:content],
      user_id: @current_user.id
    )
  if image = params[:post][:image]
      @post.image.attach(image)
 end
    if @post.save
      flash[:notice] = '投稿を作成しました!'
 redirect_to('/posts/index')
    else 
      render('posts/new')
    end
  end
```
@post.image.attach(image)で画像の添付を行います。
## 参考記事
[【Rails 5.2】 Active Storageの使い方](https://qiita.com/hmmrjn/items/7cc5e5348755c517458a)

# 画像の表示

```posts/show.html.erb
  <% if @post.image.attached? %>
<%=image_tag @post.image %>
          <% end %>
```
attached?メソッドで画像の添付をチェックします。
image_tagとは画像を表示するためのimgタグを作成するヘルパーメソッドです
## 参考記事
[rails ActiveStorageを用いての画像投稿方法](https://qiita.com/on97-nakamatsu-mayumi/items/cbf2a3f2fce63f0afbcb#)
[【Rails】 image_tagを使って簡単に画像を表示させよう！](https://pikawaka.com/rails/image_tag)
# モデルファイルの作成
```post.rb
class Post < ApplicationRecord
 has_one_attached :image
end
```
保存したいテーブルのレコードと画像を紐づけるためにhas_one_attachedというメソッドを利用します.
これは各レコードとファイルを1対1の関係で紐づけるメソッドです。
これによってPostモデルに一つの画像が紐づきます。
## 参考記事
[rails ActiveStorageを用いての画像投稿方法](https://qiita.com/on97-nakamatsu-mayumi/items/cbf2a3f2fce63f0afbcb#)
[ファイルをレコードに添付する](https://railsguides.jp/active_storage_overview.html#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E6%B7%BB%E4%BB%98%E3%81%99%E3%82%8B)
【G検定対策】ロジスティック回帰 (logistic regression)

# ロジスティック回帰とは
機械学習(**教師あり学習**)の手法の1つ．ロジスティック関数を用いた線形回帰を応用した**分類**手法のアルゴリズム(名前に回帰とあるが，**分類**手法の1つ)．テキストベース(感情分析や，文章分類など)の分類問題に使われることが多い．

与えられた任意の値が正例(1)か?負例(0)か?の，確率(0~1の間)を求める．**閾値**を設定し，正例(1)，負例(0)の分類を行う．

2種類の分類では**シグモイド関数**を使うが，より多くの分類を行う場合は**ソフトマックス関数**を用いる．

### 使用可能シーン
- データが線形分離可能な場合

# 見るべき解説動画
https://www.youtube.com/watch?v=SL-kq73uIYs

https://www.youtube.com/watch?v=Xzwik2yGFig

https://www.youtube.com/watch?v=-QcW4tnfjGI

# 数式を交えた解説動画
https://www.youtube.com/watch?v=mMMzDFttZ8A

https://www.youtube.com/watch?v=KXE8fTlF44s

https://www.youtube.com/watch?v=zbk0fC7K7Ws

# ハンズオンを用いた解説
https://www.youtube.com/watch?v=DYo2vUWwDBk

https://www.youtube.com/watch?v=iFcToFruNss

https://isolution.pro/t/machine-learning-with-python/classification-algorithms-logistic-regression/bunrui-arugorizumu-rojisuthikku-kaiki
【G検定対策】決定木 (decision tree)

# 決定木 (decision tree)とは
機械学習(教師あり学習)の手法の1つ．分布しているデータの適切な境界線を求めるアルゴリズム．**条件分岐により，データを分けていくことを繰り返す**という流れ．

#### メリット
- 学習結果を木構造で表せるため，説明変数と目的変数の因果関係が明らかになる**解釈性の高いモデル**といえる．
- データの前処理と，予測の煩わしさが少ない．
- 外れ値の影響を受けにくい．


#### デメリット
- 条件分岐が不適だと過学習する．
- 分類性能が高いとは言えない．⇢ **剪定(枝刈り)**を行う．

## ランダムフォレスト
決定木に，バギング(アンサンブル学習)を組み合わせた手法

https://qiita.com/Rumi_Yamaguchi/items/a421d2446b9490fc6a3f

## Xgboost
https://www.youtube.com/watch?v=AEhym-wo3mc

https://www.youtube.com/watch?v=BjniSO867ac

### CART, C4.5 ジニ係数，エントロピー

https://www.youtube.com/watch?v=WATSZrIu1zw



# 見るべき解説動画
https://www.youtube.com/watch?v=3LrbL8Ip_eg

https://www.youtube.com/watch?v=Gu31SuTwUZw

https://www.youtube.com/watch?v=EARJurFDkiM


# 数式を交えた解説動画
https://www.youtube.com/watch?v=irTbuevXauk


# ハンズオンによる説明
https://www.youtube.com/watch?v=ynZXzHdZNpY

https://isolution.pro/t/machine-learning-with-python/classification-algorithms-decision-tree/bunrui-arugorizumu-dhishijon-tsuri
【G検定対策】ランダムフォレスト (random forest)

# ランダムフォレスト (random forest)とは
決定木の1つ．バギング(アンサンブル学習)を組み合わせた手法．決定木のデメリットである過学習を抑えるために使われる．

- 条件分岐のもととなる特徴量
- それぞれの決定木に対して用いる学習データ (**ブートストラップサンプリング**)

以上2点をランダムに選ぶ．複数の決定木(モデル)を作成し，ランダムに選んだ**それぞれの結果の平均を用いて多数決**したものを予測結果とする．

**アンサンブル学習**
複数のモデルで学習させること

https://www.youtube.com/watch?v=h0p6RiuhdrE


**バギング**
アンサンブル学習の1つ．全体から一部のデータを，複数のモデルを1度に並列して作成し用いて学習する方法のこと．
cf ) **ブースティング**
⇢ 複数のモデルを逐次的に作成し用いて学習する方法のこと．1つのモデルを作成・学習したあと，次のモデル作成する際，前のモデルで誤認識してしまったデータを優先的に正しく分類できるように学習し，最終的に1つのモデルとして出力を行う．
ex ) **勾配ブースティング**



# 見るべき解説動画
https://www.youtube.com/watch?v=DXHB0j7cU68

https://www.youtube.com/watch?v=pwzkqub9BpQ

https://www.youtube.com/watch?v=dyuWRmXWbt8

https://www.youtube.com/watch?v=NY7g139Ave8


# ハンズオンによる説明
https://www.youtube.com/watch?v=odqb8oXcJMY

https://www.youtube.com/watch?v=TBtdUcntCpI

https://isolution.pro/t/machine-learning-with-python/classification-algorithms-random-forest/bunrui-arugorizumu-randamufuxoresuto
テスト技法

# 同値分割
- 同じ結果になるテスト条件の中から代表的なものを選択してテストする
 **（例）** エラーになる、ならない

# 境界値分析
- 境界値でテストする

# C0（命令網羅）
- それぞれの命令文が少なくとも1回は実行されるようにテストする

# C1（分岐網羅）
- それぞれの判定条件における真偽が少なくとも1回は実行されるようにテストする
- 単体テストはここまでやることが多い

# C2（条件網羅）
- それぞれの条件文における真偽が少なくとも1回は実行されるようにテストする

# ディシジョンテーブル
- 複数の条件とその条件から求められる期待値を整理するための表のこと
- パターン漏れを防ぐ

# オールペア法
- 2項目間の全組合せを網羅する
- ほとんどの不具合は多くとも2つの因子の相互作用によって引き起こされているという考えに基づいた手法
AWS LambdaからTwilio Functionsに値を渡す

# これはなに？
AWSLambdaからTwilio Fnctionsへ値を渡すときに使用した例です。

例えばですが、CloudWatchAlarmの発生をトリガーにLambdaが動き、
LambdaからTwilio Functionsが呼び出されSMSの通知内容でアラート名をお知らせするなど行えると思います。

## Lambda側
下記にて紹介されているコードを転用して作成しております。
今回はCloudWatchAlarmよりアラートが上がった際のアラート名を連携するようにしています。

https://qiita.com/mobilebiz/items/406461282a23d2e056a6#%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%BA%96%E5%82%99

```index.js
exports.handler = function (event, context, callback) {
  const crypto = require('crypto');
  const https = require('https');

  // Twilio Account Sid and Auth Token
  const authToken = process.env.TWILIO_AUTH_TOKEN;

  // Twilio Function Domain
  let functionDomain = process.env.FUNCTION_DOMAIN;

  // Make a X-Twilio-Signature
  const signature = crypto.createHmac('sha1', authToken)
    .update(new Buffer.from(`https://${functionDomain}/serial-call-studio`, 'utf-8'))
    .digest('Base64');

  const message = JSON.parse(event.Records[0].Sns.Message);
  const alarmName = message.AlarmName;

  const data = JSON.stringify({
    alarm_name: alarmName,
  });

  // HTTPS Options
  const options = {
    method: "POST",
    hostname: functionDomain,
    port: 443,
    path: '/serial-call-studio',
    headers: {
      'X-Twilio-Signature': signature
    }
  };

  // Function request
  const req = https.request(options, (res) => {
    let result = '';
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      result = chunk;
    });
    res.on('end', () => {
      callback(null, result);
    })
  });

  // Error handling
  req.on('error', (e) => {
    callback(e);
  });
  req.write(data);
  req.end();
}

```

## Twilio Function側
下記のような形で、`event.<パラメーター名>`で値を取得することが出来ます。

```twilio_function.js
exports.handler = function (context, event, callback) {

  let alarm_name = event.alarm_name;
  console.log(alarm_name)
};

```
Javascriptでメッセージテンプレートをclassで管理する

## 背景
ノーコードツールでの開発で、メッセージの定義などができる機能がないので何かいい実装方法はないかと、考えてたんですが、JavaScriptからAPIリクエストを投げて結果をもとにメッセージを出すという実装なので、画面側でメッセージを持っておきたいと思ったのがきっかけです。

## 経緯
ただ、ライブラリが使えない環境なので、JavaScript・jQueryだけでメッセージを管理する
楽な方法がないか調べました。けれど、あ、これでいいやっていう方法が見つからず。。(´・ω・｀)ﾏ?

まあ、replaceメソッドを使えば何とかなるだろうと。ほかでも使えるかなと思い、ここに残します。

## ソースコード

```javascript:Message.js
class Messages {
    #common_mes = {
        "required" : "$1 is null or empty.",
        "maxLength" : "$1 within $2 characters maximum."
    }
    
    makeCommonMes(param_arr, key) {
        var str = "(" + param_arr.join(").*(") + ")";
        return str.replace(new RegExp(str,"g"), this.#common_mes[key]).replace(/[()]/g,"");
    }
    
    getViewMessages(target_arr) {
        var message_arr = [];
        target_arr.forEach((arr) => {
            message_arr.push(this.makeCommonMes(arr.param_arr, arr.key));
        });
        return message_arr;
    }
}

// Usage
var m = new Messages();
var message_param_arr = [{
    "param_arr" : ["name"],
    "key" : "required"
},{
    "param_arr" : ["login id", 9],
    "key" : "maxLength"
}];
console.log(m.getViewMessages(message_param_arr));
// [ 'name is null or empty.', 'login id within 9 characters maximum.' ]
```


。。。以上です(∩´∀｀)∩

あとはcommon_mesにテンプレートのメッセージを追加していけばOKですね。

## 参考にしたサイト

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes

https://web-tsuku.life/replace-1-2-regrex/
Laravelの基礎（備忘録）

Laravelの基本文法を自分用にまとめています。
簡単なメモ代わりですがお役に立てば幸いです。


# Routingの基本
<br>

```php
Route::メソッド ( 値 , 関数 );
```
第１引数が、ルーティングで割り当てるドレスなどの情報を示すものになります。
そして、第２引数（関数と表記されている部分）が、そこにアクセスされた際に呼び出される処理になります。
<br>　

```php
Route::get( アドレス , 関数 );
Route::post( アドレス , 関数 );
Route::put( アドレス , 関数 );
Route::delete( アドレス , 関数 );
```
HTTPアクセスの[GET,POST,PUT,DELETE]のそれぞれに対応しています。　
<br>　

```php
Route::any( アドレス , 関数 );
Route::match( 配列 , アドレス , 関数 );
```
複数のHTTPメソッドに対応させるためのものです。anyは、あらゆるHTTPメソッド（GET, POST, PUT, DELETE）にルーティングを行います。matchは、第１引数にHTTPメソッド名の配列（例えば、['get','post'] など）を用意し、そのHTTPメソッドでのアクセスに対してルーティングを行います。
<br>

#### viewテンプレートを表示する。

1、まずは\test\routes\web.phpにrootを設定します。（test部分は自分が作成したlaravelのプロジェクト名です。）
2、今回は以下のように書いてみます。
```php
Route::get('/', function () {
    return view('welcome');
});
↑デフォルトで設定されています
↓ここから
Route::get('/hello', function () {
    return view('hello',['name' => 'ソウタ','age' => 22]);
});
```
3、\test\resources\views\hello.phpとなるようにhello.phpを作成しましょう
4、hello.phpの中身はこんな感じに記述しておきます。（あくまでview表示をしてみようという目的なので実際はこんな適当に書いてはいけません。）
```php
<p>私の名前は<?php echo $name; ?>です。</p>
<p>年齢は<?php echo $age; ?>歳です。</p>
```
5、URL(test/hello)にアクセスします
![スクリーンショット 2022-03-06 182559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522554/e8671af7-716e-5af0-2128-59a41b73b5d4.png)

以上がview表示の流れになります。
環境はそれぞれなのでURLなどは人によって変わると思います。

以下、詳しく書いてみます。
まず、web.phpです。今回は関数にview関数を利用しています。
```php
view('テンプレート','連想配列')
```
テンプレートにはviewフォルダ内の〇〇.php 〇〇.blade.php などの拡張子を外した〇〇の部分になります。
今回はhelloですね。
連想配列についてはPHP 連想配列　とかで調べてみてください。
実際のviewファイルでは先程書いた連想配列のkeyを使用して値を出力できます。
今回はnameで'ソウタ'を　ageで22を出力できました。
Power Queryで加工した104万行超のデータを、csv出力する方法

# はじめに
Power Queryで加工したデータをcsv形式でエクスポートしたいとき、
104万行(正確には1,048,576行)以内であれば、
「デスクトップ版ExcelのPower Queryで加工→Excelワークシートにテーブル出力→csvで保存」で対応可能である。
一方で、104万行を超える場合には、上記のやり方では対応できない。

この問題に対する主な解決策を以下にてまとめた。


# 解決策1：DAX Studioを利用する
DAX Studioに内蔵されているcsv出力機能を利用する。
以下記事にて、わかりやすくまとめられている。

https://marshal115.hatenablog.com/entry/2020/06/06/182918#Excel%E3%81%8B%E3%82%89%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92CSV%E3%81%A8%E3%81%97%E3%81%A6%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88


# 解決策2：Power BI DesktopでPower QueryとRを併用する
Power BI Desktopでは、Power Query Editor内でRを利用することができる。
したがって、Rのcsv出力関数 `write.table()` の利用によって、csv出力が可能である。

https://blog.truestar.co.jp/micorosoft/power-bi/20201211/41225/

```R:スクリプト例
# 'dataset' はこのスクリプトの入力データを保持しています
write.table(dataset,"フォルダパス/ファイル名.csv", quote=T, row.names=F, col.names=T, sep=",", append=F)
```

### 補足
上記ブログのとおりに進めると、1列目にレコード番号が付与される。
もし必要ない場合は、以下記事を参考に `row.names=FALSE` を追記すると良い。

https://a-habakiri.hateblo.jp/entry/2019/11/04/222811


# 解決策3：Power BI DesktopでPower QueryとPythonを併用する
Power BI Desktopでは、Power Query Editor内でPythonを利用することができる。
したがって、Pythonのcsv出力関数 `to_csv()` の利用によって、csv出力が可能である。

```Python:スクリプト例
# 'dataset' はこのスクリプトの入力データを保持しています
import pandas as pd
file = pd.DataFrame(dataset)
file.to_csv('フォルダパス/ファイル名.csv', index=False)
```


# 解決策同士の比較
## 処理速度
2つの異なるサンプルデータで検証したところ、処理速度の順位が逆転したので、現時点では結論不明。
判明でき次第追記する。
(個人的な推測では、データ量が多くなればなるほどPython・R(特にPython)が相対的に速くなるように思われる。)


## 難易度
Pythonは事前に環境構築(Pythonのインストールと、Pandas等のライブラリのインストール)が必要。
したがって、Pythonを含むプログラミング言語未経験者には少しハードルが高いと思われる。
(DAX StudioやRは、本記事のケースではインストールするだけで済む。)


## 結論
DAX Studioが最も使いはじめやすいと思われるので、
まずはDAX Studioで試してみて、処理速度に難があると判断した場合にRやPythonを試すのが良さそう。
Gradle で Azure Web Apps にデプロイする

# Gralde で Azure Web Apps にデプロイする

Gradle を使って Azure Web Apps にデプロイする必要があったので、その覚え書きです。いつもは maven を使っている Gradle 初心者です。

リポジトリは以下で公開されており、

https://github.com/microsoft/azure-gradle-plugins

プラグイン情報は以下から参照できます

https://plugins.gradle.org/plugin/com.microsoft.azure.azurewebapp

GithubのほうはReleaseタグが真面目に切られていない気がしますが、執筆時点での最新版は、 Dec 2021 にリリースされた `1.2.2` です。 Maven プラグインと比べても歩調を合わせてアップデートされているようには見えます。

## 設定方法

ゼロからやろうとすると、色々説明することが多いので、すでに az コマンドサブスクリプションに繋がっている前提で話しを進めます。

細かい話は、Github Wiki に書かれているので参考にしてください。

https://github.com/microsoft/azure-gradle-plugins/wiki/Webapp-Configuration#configuration-for-azure-webapp-plugin-for-gradle

普段、Gradle を使ってないのでよく理解していないのですが、新しい記述方式と古い方式があって、さらに `Groovy`やら `kotlin` やらで記述方式が違うようで初心者にとっては悩ましい。

新しい方式（DSL)では以下、

```gradle
plugins {
    id 'com.microsoft.azure.azurewebapp' version '1.2.2'
}
```

レガシー形式では以下のようです。適当に`build.gradle`に書き込みます。

```gradle
buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "com.microsoft.azure:azure-webapp-gradle-plugin:1.2.2"
  }
}

apply plugin: "com.microsoft.azure.azurewebapp"
```

## デプロイ先の設定

デプロイ先の設定も `build.gralde`に記述します。ざっと、Azure 上にApp Serviceがある状態ならば、以下でデプロイできます。

`appServicePlanResourceGroup` や `appServicePlanName` も指定できるので、リソースが無い状態からきっとデプロイできるでしょう。

```gradle
azurewebapp {
    subscription = '11111111-1111-1111-1111-111111111111'
    resourceGroup = 'some-resource-group'
    appName = 'some-webapp-service'
    pricingTier = 'P1v2' 
    region = 'japaneast' 
    runtime {
        os = 'Windows' 
        webContainer = 'Java SE'
        javaVersion = 'Java 8'
    }
}
```

## デプロイ

`gradle azureWebAppDeploy` 

でデプロイできます。

## 雑感

Maven版は、Configがあって、設定をインタラクティブに聞いてくれるGoal があったハズなので、ちょっと面倒といえば面倒。


## 参考

動画付きで以下のDevBlobにも紹介されておりました（が見てません）

https://devblogs.microsoft.com/java/gradle-deploy-java-web-apps-to-azure-in-one-step/

ちなみにMaven版は以下です。

https://github.com/microsoft/azure-maven-plugins
Dockerの基礎的なコマンドまとめ

Dockerをコマンドラインから利用する際によく使うコマンドについてまとめた自分用のメモです。

# DockerHubにログイン
```
docker login
```
アカウント名とパスワードを求められるので入力すると、ログインできます。

# DockerHubからイメージをpull

```
Docker pull イメージ名
```

# ホストにあるイメージの一覧を表示する

```
docker images
```

# ホストにあるイメージを削除する

```
docker rmi イメージ名
```

# イメージからコンテナを作る

```
docker run [オプション] イメージ名[:タグ|@ダイジェスト値] [コマンド] [引数...]
```
オプションとして有名なのは以下です。

|オプション  |説明  |例文  |
|---|---|---|
|-it  |コンソールに結果を表示する（標準入出力）  |docker run -it ubuntu bash  |
|--name |コンテナ名を指定する  |docker run --name "my_ubuntu" ubuntu  |
|-d  |起動後にコンテナをデタッチされ、バックグラウンドでコンテナが実行される（このコマンドがついていない場合はコンテナをexit後に削除されるフォアグランドモードになる）  |docker run -d ubuntu  |

コンテナから出る場合は`exit`で出ることができます。

# コンテナの一覧を表示する

```
// アクティブなコンテナのみ
docker ps
// 全てのコンテナ
docker ps -a
```

# コンテナを削除する
```
docker rm コンテナID
// 複数の場合はスペースを空けてIDを続けることでまとめて削除できる
docker rm コンテナID1 コンテナID2
// UP状態以外のコンテナを全て削除する場合は以下のコマンドを利用できる
docker system prune
```

# コンテナを停止する
```
docker stop [オプション] コンテナID
```

# コンテナを起動する
```
docker start　[オプション] コンテナID
```

# コンテナを再起動する
```
docker restart　[オプション] コンテナID
```

# コンテナに対してプロセスを実行する
```
docker exec -it コンテナID コマンド
```

# コンテナからイメージを作る
```
docker commit [オプション] コンテナID イメージ名[:タグ名]
```

# イメージ名を変更する
```
docker tag 元の名前　変更後の名前
```

# dockerhubにpushする
この時、イメージ名とリポジトリの名前が一致していないとpushできないので注意です。
```
docker push イメージ名
```
【Automation Anywhere】フォルダの作成（基本編）　- はじめてのAA

# 今日はこれを覚えよう！

ここではまずはシンプルにAutomation360でフォルダを作成する流れを押さえましょう。
今回はCドライブのtempフォルダ（「C:\temp」）配下に、新しく「Automation Anywhere」という名前のフォルダを作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/268e4885-ca94-4fe7-5139-7ba1860c711e.png)

# 作り方

[Botの作成画面を起動](https://qiita.com/IQ_Bocchi/items/27a23969bcb4917824ec)し、以下の手順でBotを作成します。

---
「アクションを検索」の入力欄をクリックし、「フォルダー」と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/dfc3089c-7bb4-d4cc-b02d-d465d627694d.png)

---
絞り込まれたアクションの中から、「フォルダー」パッケージの「作成」アクションを開始と終了の間にドラッグします。
その後、画面右側の「フォルダー」欄に、作成するフォルダ名を絶対パスで入力します。
※ ここで既に存在するフォルダを上書き／作成する場合は「既存のフォルダーを上書き」にチェックします[^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/becf2ac2-6988-8304-4f1d-0b894b054007.png)

なお、絶対パスとは「最上位に位置するディレクトリ（ルートディレクトリ）から、対象のファイルまでの道順(階層構造)をすべて記述する方法」です。
今回の例の場合は、
　・作成先のフォルダ ＝「C:¥temp」
　・作成するフォルダ名 = 「Automation Anywhere」
なので、「C:¥temp¥Automation Anywhere」と入力します。
「作成先のフォルダ」と「作成するフォルダ名」の間にフォルダ階層の区分を示す「¥」も忘れないよう注意してください。

[^1]: 「既存のフォルダを上書き」を行う場合、既存フォルダー内のファイルが消去されるため注意してください。

---
「保存」をし、「実行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/4e554697-ee76-9997-4c2a-0be03934e34a.png)

---
Botの正常終了を知らせる「キラキラ」が表示されるので、「閉じる」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/1aec56a1-9143-f1ae-a779-453d8bd1bada.png)

なお、「既存フォルダを上書き」がOFFで、且つ指定フォルダが既に存在している場合は下記のエラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/76c3151a-a4e9-a247-5754-5ff92f1cb142.png)

---
先ほど⑤で指定したフォルダが作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517299/7691741e-fe4c-6652-208e-520da6f1ee95.png)

# この演習で学んだこと
この演習では、Botでフォルダを作成する流れを学びました。

作成時のポイントとしては、下記になります。

- フォルダの作成では「フォルダ：作成」アクションを使用する
- 作成するフォルダは必ず絶対パスで指定する
- 既存フォルダを上書きする場合は既存のフォルダーを上書き」にチェック
*既存フォルダを上書きすると、既存フォルダー内のファイルが消去されるため注意！

非常にシンプルなアクションですが、一連の処理の中で一時的にフォルダが必要な場合など、実践的な処理を行うさまざまなケースで活用する機会があるかと思います。どんどん活用してみましょう！
また、今回は作成するフォルダの指定の際に固定の値を入力しましたが、ここで変数の使用も可能ですので「フォルダの作成（応用編）」でご紹介したいと思います。

# もっと知りたい！　学びたい！

この記事を読んで、「Automation 360 の使い方をもっと知りたい！」と思った方は、以下のシリーズをチェックしてみてください。

Automation360の基礎知識や使い方を、わかりやすくまとめたシリーズで、この記事もシリーズの１トピックとなっています。

https://qiita.com/IQ_Bocchi/items/8d28f12256037b5f9058

Automation Anywhere を使い始めたばかりの方はもちろん、これから使ってみようと思っている方や、ずっと使っているけど改めて基本を学びたい方などは、ぜひチェックしてみてください！
小道具：開平法（二進数）による整数平方根

[開平法（二進数）による平方根](https://qiita.com/ikiuo/items/b62d17e1e9e8ec5de1d0)【C++版】を見つつ、正の整数専用で Python 版を作ってみる。

```python:
def lsqrt(x):
    if x < 0:
        raise ArithmeticError
    l, r, s = x.bit_length() >> 1, 0, 0
    for b in range(l, -1, -1):
        r <<= 1
        t = 1 << b
        u = s + t
        v = u << b
        if x < v:
            continue
        x -= v
        r |= 1
        s = u + t
    return (r, x)
```

```python:テスト
>>> [lsqrt(x) for x in range(1,101)]
[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (6, 11), (6, 12), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (7, 11), (7, 12), (7, 13), (7, 14), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (8, 11), (8, 12), (8, 13), (8, 14), (8, 15), (8, 16), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (9, 11), (9, 12), (9, 13), (9, 14), (9, 15), (9, 16), (9, 17), (9, 18), (10, 0)]
>>> [r * r + s for (r, s) in [lsqrt(x) for x in range(1,101)]]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
```

C++ 版と違って多倍長整数の利用が容易なので、高精度の固定小数点として使ってみる

```python:固定小数点の10進数文字列化
fixdec = (lambda x, b, p=0: (lambda x, b, p, f: f(x >> b, x & ((1 << b) - 1), b, p))
          (x, b, (b, int(b * 0.301), p)[min(2, p + 1)],
           lambda h, l, b, p: (('%d.' % h) + ('%d' % (((l | (1 << b)) * (10**p)) >> b))[1:])))
```

```python:テスト
>>> fixdec(lsqrt(2 << 256)[0], 128)
'1.41421356237309504880168872420969807856'
>>> fixdec(lsqrt(2 << 256)[0], 128, -1)
'1.41421356237309504880168872420969807856899607931908261748958951509877704601116619082283240582675887253572000190615653991699218750'
```
【docker】dockerコマンド

dockerコマンドを備忘録としてメモしておく。各コマンドのオプションなどの詳細についてはdocker docsを参照。

# dockerコマンド
## dockerimage
### Dockerfileからのイメージ作成
``cd``コマンドでDockerfileがあるディレクトリに移動して実行。【参考：[docker docs（build）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/build/)】

```
docker build .

// 名前を付ける場合
docker build -t <リポジトリ名:タグ名> .
```
また構築済みのイメージについても以下のコマンドで名前やタグをつけられる。

```
docker tag <イメージID> <リポジトリ名:タグ名>
```

### イメージの一覧表示

```
docker images
docker image　ls
```
【参考：[docker docs（images）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/images/)】

### イメージの削除
```
docker rmi <イメージID>
```
``-f``オプションを付けることで実行中コンテナのイメージも削除できる。【参考：[docker docs（rmi）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/rmi/)】

## コンテナ

### コンテナの実行

```
docker run -d -p <ホストポート>:<コンテナポート>　<イメージID>
```
``d``はバックグランドでのコンテナ実行、``-p <ホストポート>:<コンテナポート>``はポートフォワードの設定をしている。【参考：[docker docs（run）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/run/)】

### コンテナの一覧表示

```
docker ps
docker container ls
```
デフォルトは実行中のコンテナのみだが、オプションとして``-a``を付けることで、すべてのコンテナを表示させることができる。【参考：[docker docs（ps）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/ps/)】

### コンテナの削除
```
docker rm <コンテナID>
```
``-f``オプションを付けることで実行中コンテナも削除できる。【参考：[docker docs（rm）](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/rm/)】
Dynamics365 フィールドサービスとは

## 【大事なとこ】
・マイクロソフトさんの製品
・Dynamics365という製品の中の一つ
・コールセンターの人が使う


## 【簡単に言うと】
フィールドサービスとは
**商品を買った後の修理とか点検を行うこと**

Dynamics 365 フィールドサービスとは
**フィールドサービスの管理をするシステムのこと**

やで


## 【ちょっと詳しく】
フィールドサービスの大きな流れとしては
**1．お客さんから商品のクレームが来る
2．クレームに対して現地に行って修理をする
3．修理完了をお客様に報告する**

となる。

この中でシステム化できることは
**・お客様とのやり取り
・修理内容の整理
・誰に修理に行ってもらうかの管理**

などがある。

これらを管理できるのが
↓
**Dynamics 365 Field Service**


### じゃあこのシステムはどんな企業に向いているのか？？？
**・製造業**
　➡アフターサービス
**・医療**
　➡在宅医療や訪問サービス
**・公共事業**
　➡回線の修理や作業員の派遣
**・その他様々な日本企業に当てはまりやすい**
　➡Microsoftが日本でフィールドサービスの営業を始めたのも近年のこと。まだまだ多業界に開拓中。


## 【最後に一言でいうと】
なんか管理するシステムなんやなぁ

くらいでおｋ
【G検定対策】kNN法 (k Nearest Neibor法)

# kNN法とは
機械学習(**教師あり学習**)の**分類**手法の1つ．「k近傍法」とも呼ばれる．k-means法(教師なし学習)とは全く違うアルゴリズム．

なお，ディープラーニングG検定公式テキストには，このアルゴリズムの説明がありませんでした．黒本には問題があります．

|フェーズ|処理|
|:--|:--|
|**訓練段階**|事前に正解ラベルの付いたデータセットの用意をし，ベクトル空間上にプロット．(**訓練データ**)|
|**推論段階**|正解ラベルのない**未知データ**を，訓練データと同じベクトル空間上にプロットする．任意の未知データのカテゴリ・クラスは，その未知データの近く(ユークリッド距離)にある k個(kの数は学習前に定義)の訓練データの正解ラベルよりどのカテゴリ・クラスに分類されるかを推論する．|

#### 弱点
以下の場合でないと，kNN法での判定が不正確になりやすい．
- 訓練データ内の各クラスのデータ数の偏りが少ない
- 訓練データの各クラスがよく分かれている

任意の未知データから最も近いk個を選ぶので，多数決が成り立つ訓練データ(正解ラベルが付いているデータ)が必要となる．


# 見るべき解説動画
https://www.youtube.com/watch?v=7HEQy4BoBiQ

# 数式を交えた解説動画
そんなに難しくない数式なので，数式アレルギーの人はここから見ていきましょう．

https://www.youtube.com/watch?v=sc_7OZ5uQKQ

# ハンズオンによる説明
https://www.youtube.com/watch?v=4Vk1UhRDB34

https://isolution.pro/t/machine-learning-with-python/knn-algorithm-finding-nearest-neighbors/knn-arugorizumu-saikin-hata-o-mitsukeru
TypeProf for IDEについてまとめてみた

## 前提
ども、Rubyエンジニアです。
最近は静的型付け言語の流行に伴いRubyの人気が下がってきてるようで寂しいばかりです。
静的型付け言語が流行している理由を調べる中でRuby Kaigi 2021で遠藤さんがお話しされていた
TypeProf for IDEのことを思い出したので、動画振り返りながら自分の理解を深める為に所感含めてまとめてみました。
すでに変化している内容もあるかもしれませんがご了承ください。

## なぜ静的型付け言語が流行っているのか？
### まず静的型付け言語とは？
変数や返り値の型を明示的に定義する言語
例：Java, C言語, Go, TypeScript

型を定義しながら実装することで、現代的な開発体験ができるから流行しているらしい

### 現代的な開発体験って？
- エラーレポーティング
- 補完
- 引数のヒント
- 定義元へのジャンプ

が挙げられる（他にももっとある)ので、TypeScriptを例に順番に説明していきます

- エラーレポーティング
実行前、もっと言えばファイルが保存される前にエラーの所在と原因を忠告してくれる
動的型付け言語と違って、実行して初めてエラーの発見することを避けることができます
![スクリーンショット 2022-03-03 0.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/04ef4515-3ffa-fcfa-347a-3432f891aed8.png)

- 補完
そもそもエラーを出しにくくしてくれるサポートです。
コードの文脈から次に書かれるであろうメソッドや引数をサジェスチョンしてくれる
![スクリーンショット 2022-03-03 0.05.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/83457948-ada9-0957-2383-8891f3c59034.png)

- 引数のヒント
補完と似ていますが、引数を必要とするメソッド名を書いて「()」を書くだけで与えられるべき引数の個数と型をサジェスチョンしてくれる
![スクリーンショット 2022-03-03 0.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/eefa558a-a2d8-b951-1fe3-20b255612d23.png)

- 定義元へのジャンプ
メソッドの呼び出し先で右クリックして「Go to Definition」をクリックすることで定義元へ飛ぶことができる
![スクリーンショット 2022-03-03 0.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/b4921134-f141-90b7-4333-ed4f6608a3da.png)

↑
たしかに便利。昔の開発体験を経験した訳じゃないが、現代的っぽい。
ただ、これって静的型付け言語で開発しないと受けられない恩恵だっけ？
いやrubyでもできるようにすればいい！というのがTypeProf for IDEです。

## TypeProf for IDEの前に TypeProfって何？
動的型付け言語であるrubyの型を予想してくれる型推論のツールです
※TypeProf for IDEの型推論の仕組み
![スクリーンショット 2022-03-03 0.09.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/db7a4863-c36d-c4b2-1c02-c8e133beac40.png)
一般的な処理：引数に渡された値をメソッドの定義元で参照し、評価した結果を返す
型推論の処理：まずは引数の型を評価し、型の情報のみをメソッドが評価し、返り値の型を判定し返す
　　　　　　　その上で実際に渡される値を改めて確認し計算する

実際にTypeProf for IDEをInstallしてみると

```ruby
Use Ruby 3.1.0 or later, and TypeProf 0.20.0 or later
Add gem "typeprof" to your Gemfile, and execute bundle install
```

とあるので、Ruby 3.1.0 以降でTypeProf 0.20.0以降を使用し
typeprof gemをインストールすることで利用できるようになるそうです。
（今回は時間がなくて手元で動かせませんでしたmm）

実際の画面はこんな感じ
![スクリーンショット 2022-03-03 0.35.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1333754/ab8be2e4-3659-b897-30b0-4b906f3d48ef.png)

おおおrubyファイルなのに静的型付け言語のように型の情報が表示されている！
これで先ほどの現代的な開発体験（エラーレポーティング・補完・引数のヒント・定義元へのジャンプ)がrubyでもできる！すごい！！！
ただ、まだ完璧ではなく欠点や注意点があります。

## 欠点・注意点
- RBSに型を定義していくのが面倒
型を表示している薄いグレーになっている箇所をクリックすることで.rbsファイルに飛びすぐに定義ができるが、
やはり別ファイルに記載することは少し工数という印象

- 実行速度が遅い
遠藤さんも念を押してましたが、かなり遅くなるっぽい
理由としてはrequireしたgemやファイルがあればその中身をすべて解析し型推論する為
→しかしこれには対策を打っているみたいで、1秒以内に解析できないファイルは無視する実装になっている
これは1ファイルの実装量を減らすきっかけにもなるから完全悪ではないかなという印象(gemなどは仕方ないが)

- 特殊な動き
  - 引数に誤った型を渡すと、メソッドの定義元でエラー表示される
     RBSで定義してしまえば呼び出し元でのエラーになる
表示の先頭に「#」がついていればRBSで定義済の意味
  - エラーのハイライトが実行文全体に表示されてしまう
  今後改善予定とのこと

## 所感

業務で主にrubyを使っていますが色々調べていると静的型付け言語の開発体験の魅力にヤラれそうです。
ただこのようにrubyでも同様の恩恵が受けられるのであれば最高ですね！
今後もrubyと型の話は活発化しそうなので注目すると共に、手元で動かしてみるようにします
neosでlogix その60

# 概要

neosでlogixやってみる。
StaticMeshコンポーネント、使ってみた。

# 写真

![2022-03-04 05.15.49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5ee3fdcb-65e2-be3a-1d34-559ad236ae58.jpeg)

# 手順

- devtooltipを装着
- 新規->空のオブジェクト
- コンポーネントを追加
- Assets -> StaticMeshを追加
- 設定
Url: neosdb:///551018e3e5c219a48e0e0e8138bc565a8a1fc4d30c380336a4cb8271020d8e18.meshx
- Renderering -> MeshRendererを追加
- 設定
Mesh: StaticMesh



以上。
neosでlogix その59

# 概要

neosでlogixやってみる。
QuadMeshコンポーネント、使ってみた。

# 写真

![2022-03-03 22.49.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dd82b1a3-6577-1e4e-2947-97fb66a98a71.jpeg)

# 手順

- devtooltipを装着
- 新規->空のオブジェクト
- コンポーネントを追加
- Assets -> Procedual Meshes -> QuadMeshを追加
- Assets -> Materials -> PBS_Metallic を追加
- 設定
EmissiveColor:
R: 1
- Renderering -> MeshRendererを追加
- 設定
Mesh: QuadMesh
Materials(list): add
0: PBS_Metallic

以上。
SQLServerトランザクションログを小さくする

# 概要
完全復旧モデルでは、データベースの完全バックアップの後に
トランザクションログのバックアップを取得する必要があります。

トランザクションログを連続的に採取しておけば、データベースに障害が起こった時に
そのトランザクションログを適用していく事で復旧する事ができます。

トランザクションログのバックアップを行う事でログファイルの中身は消えますが、
ファイルサイズ自体はまだ小さくなりません。ログの圧縮を行うことで小さくなります。

# 手順
## １．データベースの復旧モデルを確認する。
　データベースの所で右クリック。プロパティで、「単純」、「完全」「一括ログ」いずれかを確認します。

## ２．ログファイルのバックアップを取得する。
　復旧モデルが「完全」「一括ログ」の場合（「単純」の場合は３．へ）
　データベースの所で右クリック。「タスク」→「バックアップ」
　バックアップの種類は、「トランザクションログ」を選択する。

## ３．トランザクションログを圧縮する。
　対象のデータベースを右クリックし、「タスク」→「圧縮」→「ファイル」の順に選択する。
　ファイルの種類は「ログ」を選択する。

　圧縮アクションは、”未使用領域の解放前にページを再構成する”を選択する。
　ファイルサイズは1024KBくらいを指定する。

## サイズが小さくならない場合
　２と３を再度繰り返してみるとたいていの場合は効きます。
　それでもダメならば、チェックポイントとか他の要因になります。
BlenderのMetallic,RoughnessテクスチャをUnityのMetallic+SmoothnessテクスチャにPhotoshopで変換する

# 背景

UnityのStarndard ShaderのMaterial設定を見るとRoughnessテクスチャの設定がありません。
Roughnessは粗さを表す値です。

詳しくはこの記事！

https://kairandou.blogspot.com/2020/10/blendermetallicroughnessunitymetallicsm.html

大事なのはここ

> ・BlenderのRoughness MapとUnityのSmoothness Mapはどちらも0〜1の濃淡で表現される画像である
・BlenderのRoughness MapとUnityのSmoothness Mapは白黒反転すれば同じものになる
・Metallic Mapは共通である
・UnityではMetallic Mapの各ピクセルの不透明度(0〜1の値)がSmoothnessに使われる

糸凪邑さんの記事ではGIMPで作業していましたが、この記事ではPhotoshopを使った変換方法をメモします。

# 準備するもの

- Adobe Photoshop (今回は2022を使用)
- Metallic Mapを担当するTexture (pngなど)
    - T_Sample_Metallic.pngとする
- Roughness Mapを担当するTexture (pngなど)
    - T_Sample_Roughness.pngとする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/6487c17a-53d0-dfba-bdff-11193da76841.png)

# アウトプット

- Unity用に変換したMetallic Mapを担当するTexture (tgaファイルに書き出し)

# 手順

## 各画像をレイヤー化

まずPhotoshopでT_Sample_Metallic.pngを開きます。そこからT_Sample_Roughness.pngをドラッグ&ドロップで追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/b79a9d26-e300-9c3b-93a2-65ebf459c648.png)

各画像をレイヤーとして操作できるようにします。

レイヤーの[T_Sample_Roughness]を右クリックし、[レイヤーをラタライズ]を選択します。

レイヤーの背景を右クリックし[背景からレイヤーへ]を選択します。
レイヤー名を「T_Sample_Metallic」として、OK

[T_Sample_Metallic]が上に来るように順番を組み替えるとこうなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/47ac65c5-fc2e-2099-83d0-2cc3ff4684db.png)

## モードをRGBに

メニュータブから[イメージ]>[モード]>[RGBカラー]を選択します。
ホップアップにたいして、レイヤーを **[結合しない]** を選択します。

## Roughnessを白黒反転

レイヤーから[T_Sample_Roughness]を選択した状態で
メニュータブの[イメージ]>[色調補正]>[階調の反転]を選択します。

すると、反転しているのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/35ec32fc-dc21-e224-62df-b52995f38994.png)

## MetallicのアルファチャンネルにRoughnessをアサインする

レイヤーで[T_Sample_Metallic]を選択。
チャンネルタブを選択。
下のプラスボタン「新規チャンネルを作成」を選択。

するとアルファチャンネル1が現れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/9bbbe237-aaac-e876-5b4c-b97891f4134c.png)

チャンネルタブでRGBを選択した状態で、レイヤーに戻る。
[T_Sample_Roughness]をコピーするために、表示を変更。
Ctrl+A, Ctrl+Cで全部選択してコピー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/32757e0f-0cef-3844-6efc-8acbabba970e.png)

レイヤータブで[T_Sample_Metallic]を選択する。
チャンネルタブを選択、アルファチャンネル1を選択して、Ctrl+Vで貼り付け。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/94f341c4-6552-66f4-4a46-39cfe241726b.png)


## 画像を結合

メニューバーから[レイヤー]>[画像を結合]を選択

## 別名で保存

メニューバーから[ファイル]>[別名で保存]を選択
Targa形式を選択。保存。32bit/pixelsを選択。

## Unityで確認

Alphaが追加されるようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/291db510-33e2-1d92-90ea-d173988ad353.png)

# Unityでのルック

変換前のMetallic Textureでは、テカる必要のないところがテカっていたが、変換後では、質感に合わせて調整されるようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/6130f723-a984-1f7c-9fcc-9531467108a3.png)
Fortranで関数を引数にとる方法

## Fortranで関数を引数にとる方法についての備忘録です．

Fortranで数値解析のコードを書いているとき，引数に関数をとりたいときってありますよね．
たとえば，関数$f(x)$のある点における微分$\frac{\partial f(x)}{\partial x}|_{x=a}$を計算したいときに，

```Fortran

dfdx = d_dx(func=f, x=a)

```

のように書けると嬉しい場合があります．
そこで今回は，$f(x) = x^2 + 1$を実装した以下の関数

```Fortran
function myfunc(x) result(ret)
    real(real64),parameter :: a=1.0d0
    real(real64),parameter :: b=1.0d0
    real(real64),intent(in) :: x
    real(real64) :: ret
    ret = a*x*x + b
end function

```
の数値微分を例に，実装例を紹介します．

### 呼び出し型のmainプログラム

この記事では，以下の```main.f90```が動くように，```DerivativeClass```モジュールを作成します．

```main.f90
program main
    use DerivativeClass
    implicit none
    
    ! 数値微分 
    ! 第一引数は関数，第二引数は微分点のxの値
    print *, d_dx(myfunc      ,x=1.0d0)
    
contains

! 微分したい関数
function myfunc(x) result(ret)
    real(real64),parameter :: a=1.0d0
    real(real64),parameter :: b=1.0d0
    real(real64),intent(in) :: x
    real(real64) :: ret
    ret = a*x*x + b
end function

end program
```


### 手順1．普通の関数と同様に実装を行う．

中心差分の式

$
\begin{equation}
\frac{\partial f(x)}{\partial x} = \frac{f(x+\epsilon) -f(x-\epsilon)}{2 \epsilon} 
\end{equation}
$


により，数値微分を行う関数を書きます．ここで，```func```は関数型の引数のつもりですが，今は未定義のまま，他を実装します．

```DerivativeClass.f90
module DerivativeClass
    use iso_fortran_env
    implicit none
contains


! ########################################################
real(real64) function derivative_scalar(func,x,eps)
    ! >>> Define func()
    ! funcについてはまだ未定義
    ! <<<

    ! >>> arg
    real(real64),intent(in) :: x
    real(real64),optional,intent(in) :: eps !小さい値
    ! <<< 

    real(real64)  :: eps_val =dble(1.0e-4)
    if(present(eps) )then
        eps_val = eps
    endif
    
    ! >>> operation
    ! numerical derivative 
    ! 中心差分による数値微分
    derivative_scalar = (func(x+eps_val) - func(x-eps_val) )/(2.0d0*eps_val)
    ! <<<

end function
! ########################################################

end module DerivativeClass
```

### 手順2．```Interface```文により，第一引数を関数とする．

```Interface```文を使い，```func```が，```real(real64)```型の戻り値・引数を持つことを定義します．
この定義により，```real(real64)```型の戻り値・引数をもつ任意の関数を，引数```func```にとれるようになります．

```DerivativeClass.f90

! ########################################################
real(real64) function derivative_scalar(func,x,eps)
    ! >>> Define func()
    interface 
        real(real64) function func(x)
            use iso_fortran_env
            real(real64),intent(in) :: x
        end function
    end interface 

    ! <<<

    ! >>> arg
    real(real64),intent(in) :: x
    real(real64),optional,intent(in) :: eps
    ! <<< 

    real(real64)  :: eps_val =dble(1.0e-4)
    if(present(eps) )then
        eps_val = eps
    endif
    
    ! >>> operation
    ! numerical derivative 
    
    derivative_scalar = (func(x+eps_val) - func(x-eps_val) )/(2.0d0*eps_val)
    ! <<<

end function
! ########################################################

end module DerivativeClass
```
あとは，コンパイルして動かすと，

```
   2.0000000000000000 
```

と数値微分が行われます．

### おわりに

汎関数がつくれたり，最適化問題が実装できたりと素敵ですね！

### 参考

NAG様の記事(https://www.nag-j.co.jp/fortran/tips/tips_HowToPassArgumentsSafely.html)
CloudHubで/tmpフォルダにアクセス

# 一時データ保存領域
APIをMuleSoftが提供するCloudHubと呼ばれるクラウド上で稼働させる際に、一時的にデータを保管しておきたいことがあります。その場合に利用可能なのが下記の通り。

| オプション | 概要 |
|:-:|:-:|
| Object Store  | Key-Value型でのデータ保存が可能です。ただし、Base Subscriptionでは10 TPS（Transaction per second）が上限となり、それ以上のトラフィックは有償オプションが必要。 |
| Anypoint MQ  | メッセージキューです。処理プロセス間でのデータ受け渡しなどが中心となるかと思います。 また、有償オプションです。 |
| 外部のストレージ  | SMBやAmazon S3等のファイル共有ストレージやデータベース等。  |
| APIが稼働するワーカー内の領域  | ワーカーのサイズによって、既定の外レージサイズが割り当てられています。  |

推奨としては、Muleアプリケーションの再起動の影響を受けず大きなファイルも取り扱える外部ストレージかと思います。
ただ、非常に短い期間の一時保持であったり、Muleアプリケーションの再起動を考慮しなくても良いようなケースの場合、ワーカー内の作業領域を利用することも出来ます。(**/tmpの利用は、推奨にはなりませんのでご注意ください!!!**)

## /tmp領域

各CloudHubワーカーは、EC2インスタンスで構築されており、OSおよびMule Runtimeそして稼働させるMuleアプリなどで構成されています。この時、ワーカーサイズ毎にパーティションが決められています。

https://docs.mulesoft.com/jp/runtime-manager/cloudhub-architecture#cloudhub-%E3%83%AF%E3%83%BC%E3%82%AB%E3%83%BC

注意点としては、上記の製品ドキュメントに記載された値には、OSやMule Runtime、ログ等も含まれる為、/tmpフォルダに割り当てられた容量はより小さなものとなるという事です。

また、現在、FTPやFile、HTTP、Salesforce連携など、様々な場所でストリーミングオプションが利用可能となっています。
このストリーミングオプションを利用することでデータの複数回の利用が可能となりますが、この時、/tmp領域には一時データファイルが作成されることになり領域を消費しますので注意が必要です。

また、Batchを利用した場合も、/tmp領域に一時的にデータが格納されることになりますので、
大量のデータを取り扱い場合は注意が必要となります。

## /tmpへのアクセス

CloudHubの/tmpフォルダには、Fileモジュールを利用してアクセスすることが出来ます。

Fileモジュールは下記の通り、各種操作が用意されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/6b242d17-911a-d582-1089-b22e6053735d.png)

例えば、/tmpフォルダに存在するファイルを一覧するには、下記のようにフローを組みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/2e14412a-78e7-950c-9f57-c993b909af90.png)
尚、ファイルマッチングルールを指定しない場合、内部プロセスで利用中のファイルにアクセスしようとして失敗します。
ここでは、下記のようにMin sizeを指定することで回避しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/c5134257-c257-c1f6-4864-305cb3f78e99.png)

実行すると、下記のように結果が取得されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/b2ae2eca-01b3-05fc-9f92-df591c792342.png)
Blenderアドオン「BlendArMocap」を使ってモーションキャプチャしてみたときのメモ

# やったこと
BlendArMocapのベータ版が1/31に無料リリースされたので、それを使ってBlender上のモデルに対してモーションキャプチャを使ってポーズやアニメーションを作成してみた
![Blender_-_C__Users_User_Downloads_01.blend_-2022-03-04-14-17-08_Trim-_2_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/3b239f16-2330-5606-cf6a-3fb7376fe930.gif)

# 環境
Windows11
Blender2.93
使用アドオン：BlendArMocap, MBLab, Rigify
※BlendArMocapについて→[GitHub](https://github.com/cgtinker/BlendArMocap)
# 手順
### BlendArMocapアドオンを追加する
[BlendArMocapダウンロードページ](https://cgtinker.gumroad.com/l/rotom)からzipファイルをダウンロードし、Blenderのアドオンに追加
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/97d83ef5-2041-c140-af78-32355fca92c4.png" width="300">
Install dependenciesを実行
→``No module named 'mediapipe'``と怒られる

BlendArMocapを使うために必要な[mediapipe](https://google.github.io/mediapipe/)(Googleが提供するオープンソースのメディアデータ向け機械学習用フレームワーク)がBlenderの標準Pythonモジュールに入っていないので別途インストールが必要
→pipなどでインストール(パッケージインストール先がちゃんと``Path/To/Blender 2.93/2.93/python/lib/site-packages``になるように注意)

Blenderに戻りInstall dependenciesを実行
→ContextMenuにBlendArMocapが表示される
### リグコントローラ付きモデルを用意する
[MBLabアドオン](https://mblab.dev/)を追加し、ContextMenu>MBLabから特に何も指定せずCreate characterでモデルを生成する(自作モデルがあればそれを使う)

Rigifyアドオンを追加し、Add>Armature>Human(Meta-Rig)でリグを追加
→ リグの編集モードでモデルと合うように調節する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/cc3deb2f-83b9-420e-6ef7-2ce1d1e510c3.png" width="250">
metarigのObjectDataProperties>RigifyButtonsからGenerateRigを実行してリグコントローラを生成
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/94a61303-3908-396e-d386-574a62677bc1.png" width="300">
モデル→生成したrigの順で選択しSetParentで自動ウェイトでスキニングする
``BoneHeatWeighting: failed to find solution for one or more bones``というエラーログが出たらモデルのメッシュの重複頂点を削除する(エラーが出なくなるまでMergeDistanceを大きくする)
### モーションをキャプチャする
以上でモーションキャプチャする準備が整ったのでオブジェクトモードに切り替えてBlendArMocapを開く
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/3b19fb5a-7b70-51de-f575-c95c5c20a0e8.png" width="200">
- WebcamDeviceSlot: モーションキャプチャに使用するWebカメラを指定
- KeyStep: キーフレームの頻度を指定
- Target: BlendArMocapではHands(手)、Face(顔)、Pose(ポーズ)を別々でキャプチャできるので、キャプチャしたいターゲットを選ぶ

StartDetectionボタンを押すとBlender上でWebカメラの映像が表示されモーションキャプチャが開始される(Q/ESCキーか右クリックで終了できる)
### キャプチャしたモーションをrigに流す
キャプチャしたモーションはDriverとしてOutlinerに生成される
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/46323693-d878-13c3-0964-0e4b12e69abb.png" width="400">
BlendArMocapのAnimationTransferでrigに流したいDriverコレクションを指定してStartTransferで実行する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541528/fd838df1-aaad-e034-500a-0d3f30466797.png" width="200">
Timelineで再生するとキャプチャしたモーションでモデルが動いていることが確認できる
# 参考ページ
https://forest.watch.impress.co.jp/docs/serial/blenderwthing/1390871.html
https://github.com/cgtinker/BlendArMocap
https://www.youtube.com/watch?v=pji6IHNCnAk
1つのドメインでサブディレクトリを作り別のWordPressサイトを作る

WordPressのテーマ開発をしていて、複数のテーマを開発したい時やテスト開発をしたい時。
それぞれに新しいドメインを買えるのであれば、その方が楽なんですが、
お金もかかるし、
テストサイトだとそもそも不便だし、
同じドメインの中にディレクトリを別で作ってWordPressいれれたらお得じゃん！

そう思って、以前チャレンジしたのですが、なぜかうまくいかず。
大元のWordPressのcssが崩れたり、そもそも反映がうまくいかず。
WP以外のサイトならなんら問題ないのですが。
例えば、サンプルアプリやLPを作って、新しいフォルダPortfolioを作ったとして。
そうすると、
取得したドメイン/portfolio
で表示できるので、WordPressだってうまくいくはずじゃない？
実際実務では企業の社員さんがテスト開発環境を作ってくれてたので、できるはず。
と思ったのですが、なかなかうまくいかなかったので、3日間ぐらいやきもきしてましたが解明しました。
理解したら、なんだ、、そんなに簡単だったの、、！？という感じです。

## サーバーの設定

私はXサーバーを使用しているので、他の会社のサーバーはちょっとやり方がわからないのですが、
Xサーバーにログインして、使いたいドメインを選択して、設定をします。

<strong>サーバーパネル>WordPress簡単設定>ドメイン選択画面</strong>

ここで使うドメインを選択します。

Wordpressインストールのタブ（右側）を選択して
![名称未設定のデザイン (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139887/31f6e8a9-9778-dd33-c8af-79d3917615d9.png)


サイトURLのところの/以降にサブディレクトリの名前を入れます。
そのほかは全部各々うめて、キャッシュ自動削除やデータベースのところは問題なければ全部初期設定のままで。
確認画面へ進む→インストールで完了
サブディレクトリが作成されたものの中にWPの設定がされます。

## マルチサイトの指定する
もしかしたら、これは私のやり方だと必要ないかもしれませんが、もともとのドメインで使ってた親になるWordpressの中の設定を少し変更します。
<strong>public.html>wp-config.php</strong>
の中のコードを追加します。

```
define('WP_DEBUG', false);
define('WP_ALLOW_MULTISITE', true); ←追加！
/* 編集が必要なのはここまでです ! WordPress でのパブリッシングをお楽しみください。 */

```
define('WP_ALLOW_MULTISITE', true);を追加します。
変更したら、wp-config.phpをアップロードします。
そのあと、親のWPのダッシュボードに行って、一旦入れてるプラグインを全部無効化します。

## ダッシュボードからネットワークを作成

<strong>ダッシュボードのツール>ネットワークの設置</strong>
ここでサブディレクトリにおくネットワークを設置します。
![スクリーンショット 2022-03-04 14.23.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139887/d04436b7-7129-4713-839d-ae4cda655443.png)

サイトネットワーク名　：任意
メールアドレス：wordpress設置時の自分のメールアドレス
を入力して、インストール。

:::note warn
（プラグインが有効化されてると、うまくいかないです。全て一旦無効化します。）
:::

## 開発したテーマをインストールする

FTPをで確認すると、サブディレクトリができています。
その中にローカルで作成した開発テーマのフォルダを入れます。
<strong>サブディレクトリ名/wp-content/themes</strong>
の中に入れます。
あとは普通のWordpressの設定と同じように、ダッシュボードから外観の選択の中に開発テーマが入っているので、そちらを有効化します。
これでサブディレクトリで開発テーマを運用することができます。

サーバーにアップしてから、どうやら2重にWPをインストールする形になってしまったので、フォルダ構造やネットワークの設定などに戸惑ったので、忘れないように書いてみました。
SP_Page一覧

#### 目的
SP_Pageは、ServicePortalで画面作成するときによく使う機能と思います。
これらは標準機能からクローンして作成すると思いますが、それをいちいちTryItボタンを押して確認するのが手間なので、こちらに記事化してまとめました。

#### Pages

- 404
- actsub_notif_pref
- adaptive_authentication
- announcements
- appointment_list
- approval
- bhome
- branding_editor



404
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/9f69af97-a04a-f7e0-cdbb-b968d06a1cb9.png)

actsub_notif_pref
...表示されない...調査
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/e4c37649-002c-170d-6152-447d59cd99cc.png)

adaptive_authentication

つづきます...
AWS 構築したEC2からRDSとS3に疎通確認する

## 概要

- 別記事で構築したEC2インスタンスから別記事で構築したRDSとS3に接続できるかを確認する。

## 前提

1. 下記に記載されている記事をそれぞれ実施して作業完了していること。
    1. [AWS VPCの作成](https://qiita.com/miriwo/items/b28a4395264c08d183c6)
    1. [AWS VPCの中にサブネットを作成する](https://qiita.com/miriwo/items/9abebd478c53744b1b05)
    1. [AWS インターネットゲートウェイの作成](https://qiita.com/miriwo/items/20f05f40a3f2d5314a1d)
    1. [AWS ルートテーブルの作成とルートの追加](https://qiita.com/miriwo/items/02ec1626632a53081cb3)
    1. [AWS EC2 → S3接続用のIAMユーザーの作成](https://qiita.com/miriwo/items/9b20caab0ac85733a5d0)
    1. [AWS Webサーバー用のセキュリティグループを作成](https://qiita.com/miriwo/items/65e8e7f9f65617d02746)
    1. [AWS DBサーバー用のセキュリティグループを作成](https://qiita.com/miriwo/items/cd50169047f6c903f6c7)
    1. [AWS S3バケットの作成](https://qiita.com/miriwo/items/9ac70b0020e465980ee3)
    1. [AWS RDS用のサブネットグループを作成する](https://qiita.com/miriwo/items/1c4015bd26f8f03ee9f9)
    1. [AWS RDS用のパラメータグループを作成する](https://qiita.com/miriwo/items/288873d24f1ec17b505e)
    1. [AWS RDS用のオプショングループを作成する](https://qiita.com/miriwo/items/5c4c7116597a55b665ee)
    1. [AWS RDS MySQLインスタンスの作成](https://qiita.com/miriwo/items/e89c1d5eaa2c6468f772)
    1. [AWS EC2 AmazonLinux2インスタンスの作成](https://qiita.com/miriwo/items/58b11c88570d76261bce)

## 準備作業

### EC2へのsshログイン

1. AWSにログインしてEC2の画面を開く。
1. 一覧に表示されている「dev-web-ec2」を選択し、画面上の「アクション」をクリックし「接続」をクリックする。
1. 「SSH クライアント」のタブをクリックする。
1. 当該のページに表示されている手順を実行してEC2にSSH接続できるかを確認する。

### EC2へMySQLクライアントのインストール

1. AWSのEC2インスタンスにログインして下記コマンドを実行する。（本来は-yは付けず、インストールするパッケージを目視確認してから入れるべきです。）

    ```terminal
    sudo yum update -y
    sudo yum install mysql -y
    ```

### EC2にS3接続用IAMの情報を追加

1. 下記記事でIAMユーザーを作成した際に発行されたcsvファイルを開く。
1. 先に記載した「EC2へのsshログイン」の方法を用いてEC2のインスタンスにssh接続する。
1. 下記コマンドを実行する。

    ```terminal
    aws configure
    ```

1. 下記の様に対話型でcsvファイルの情報を入力してゆく。

    ```
    AWS Access Key ID [None]: csvのAccess Key ID
    AWS Secret Access Key [None]: csvのSecret access key
    Default region name [None]: 何も入力しない
    Default output format [None]: 何も入力しない
    ```

# 疎通確認

### EC2 → RDS

1. AWSにログインしてRDSの画面を開く。
1. 既に作成されているdev-dbを選択して詳細を確認する。
1. 「エンドポイント」の内容をコピーする。
1. 先に記載した「EC2へのsshログイン」の方法を用いてEC2のインスタンスにssh接続する。
1. 下記コマンドを実行してRDSのMySQLに接続できる事を確認する。（パスワードの入力を求められたらRDS構築時の「マスターパスワード」を入力する。）

    ```terminal
    mysql -h エンドポイント -u root -p
    ```

1. 下記の様にMySQLにログインできたらEC2 → RDSに接続ができている事となる。

    ```
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 42
    Server version: 8.0.28 Source distribution

    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    MySQL [(none)]> 
    ```

1. MySQLにて`exit`と入力してEnterを押下するとEC2に戻れる。

### EC2 → S3

1. 先に記載した「EC2へのsshログイン」の方法を用いてEC2のインスタンスにssh接続する。
1. 下記コマンドを実行してEC2からS3のバケットを見ることができるか確認する。

    ```terminal
    aws s3 ls
    ```

1. 別記事で作成したバケットが下記の様に表示されれば接続ができている事となる。

    ```terminal
    aws s3 ls
    2022-03-03 10:05:12 dev-bucket-example
    ```
フロントエンド攻略！はじめてのReact x LIFFハンズオン #1 React & Vite編に参加してみた

先日[フロントエンド攻略！はじめてのReact x LIFFハンズオン #1 React & Vite編](https://linedevelopercommunity.connpass.com/event/237619/)というオンラインハンズオンイベントに参加して来ました。

そこで学んだことや勉強になったことなどをメモがてら記述していきます。

## イベント概要
今回のイベントではReactとLIFFを使って簡単にwebアプリを作ってみようというものです。
LIFFを用いて、LINEの認証を使ってReactのアプリケーションを閲覧したりできるようになります。

## 使用教材
当日のライブアーカイブ: [Youtube LIVE](https://youtu.be/D8GeQyrueEY)
テキスト: [Zenn](https://zenn.dev/jiyuujin/books/react-x-vite-x-liff/viewer/page1)
サンプルリポジトリ: [リポジトリ](https://github.com/jiyuujin/vite-react-liff)

## LIFF（リーフ）とは
LINE Front-end-Frameworkの略
LINEの機能をWebアプリなどで使えるようにしたフレームワーク

> ユーザー情報
> OS / 言語情報等
> Bot との友達情報
> メッセージ送信（LIFF ブラウザのみ）
> QR スキャン（LIFF ブラウザのみ）

[LIFF公式ドキュメント](https://developers.line.biz/ja/docs/liff/overview/)

今回は単純にReactのデフォルトページをLINEで認証してLIFFを介して閲覧するというものでした。

## 簡単な手順方法
1. LINE DevelopersでLIFFのセットアップをする
1. Reactアプリをサーバーで動かす。アプリのエンドポイントURLを生成しておく。
1. LINE DevelopersでセットアップしたLIFFに上記のエンドポイントURLをセットする。
1. ReactアプリにLIFF IDをセットする。
1. LINEにLIFFアプリのURLをトークで投げてリンクを踏むとアプリを触れるようになる

|ログイン画面|開いたアプリ|
|:--:|:--:|
|![Screenshot_2022-03-04-12-04-43-84.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583420/1d4fa0e1-9e3c-93ee-aaca-797e61a8b857.png)|![Screenshot_2022-03-04-12-04-59-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583420/cb9171c7-7a6a-9414-eac8-06da3ad26648.png)|

## Vite(ビート)とは
Viteはビルドツールです。
Reactのビルドツールは`react-create-app`が有名どころではありますが、それよりも高速化が図れるビルドツールです。
`react-create-app`は、コマンド一つで雛形は作れますが、必要に応じてwebpack.configを書き換えたり記述が必要だったりすることが多いため、煩雑になりがちです。

Viteでは

```
# @vitejs/plugin-react
npm install @vitejs/plugin-react
yarn add @vitejs/plugin-react
```

でインストールしたのちに

```vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
})

```
viteのconfigファイルにこのように記述するだけで、Vite上でReactが動作してくれます。