OmniAICreator/Qiita-1.07M huggingface dataset:
Python の SpeechRecognizer を用いて音声認識するためにWAVファイルを分割して投入

# 音声ファイルの分割
Google Speech Recognitionを使って、音声認識が可能な最大ファイルサイズには制限があるようなので、以下で、ファイルを分割します。
（Google Speech RecognitionはWAVしか受け付けないので、違う場合は、ffmpeg などを使って変換しておいてください。）

pydubのsplit_on_silenceを使って、まず無音部分を検出して分割し、さらにまだファイルサイズが大きい場合は強制的に分割しています。
これで、datas_output/outputs/ というフォルダの下に、
output0.wav ...　という通し番号がついたファイルに分割されます。

```python
# ファイルの読み込み～無音部分での分割
# pydubにsplit_on_silenceというクラスがあるので、これを使う
# 注意：：：時間がかかる
# -*- coding: utf-8 -*-
from pydub import AudioSegment
from pydub.silence import split_on_silence
import os
new_dir_path_recursive = 'datas_output/outputs/'
os.makedirs(new_dir_path_recursive, exist_ok=True)

# wavファイルのデータ取得
sound = AudioSegment.from_file("OUTPUT.wav", format="wav")

# wavデータの分割（無音部分で区切る）
# min_silence_len=2000	2000ms以上無音なら分割
# silence_thresh=-40	-40dBFS以下で無音と判定
# keep_silence=600	分割後500msは無音を残す
chunks = split_on_silence(sound, min_silence_len = 2000, silence_thresh = -45, keep_silence = 200, seek_step = 5)

kaisuu = 0
# 分割したデータ毎にファイルに出力
for i, chunk in enumerate(chunks):
    print(i)
    # duration
    duration_in_milliseconds = len(chunk)
　　# ファイルサイズが大きい場合に分割する
    if duration_in_milliseconds > 400000:
       print(duration_in_milliseconds)
       # split sound in 200-second slices and export
       for ii, slice in enumerate(chunk[::200000]):
          with open("datas_output/outputs/output" + str(kaisuu) + ".wav" , "wb") as f:
             slice.export(f, format="wav")
             kaisuu += 1
    else:
       file_path = 'datas_output/outputs/output' + str(kaisuu) + '.wav'
       chunk.export(file_path, format="wav")
       kaisuu += 1
```

# 音声認識
上で分割したファイルを通し番号順に認識して、myfile.txt というファイルに書き込んでいきます。
なぜか、認識できないファイルがたまにあるので、そこはスキップして書き込みます。

```python
import speech_recognition as sr
r = sr.Recognizer()
foo = open('myfile.txt', 'a')
text1 = None
for n in range(0,100):    #(12,14):
  # with sr.AudioFile("output_audio_file_0" + f'{n:02}'  + ".wav") as source:
  with sr.AudioFile("datas_output/outputs/output" + str(n)  + ".wav") as source:
    audio = r.record(source)
    try:
        text = r.recognize_google(audio, language='ja-JP', show_all=False)
        foo.write('\n')
        foo.write(str(text))
        print(n)
    except sr.RequestError as e:
        print(str(n) + ":Could not request results from Google Speech Recognition service; {0}".format(e))
        foo.write("\n" + str(n) + ":Could not request results from Google Speech Recognition service; {0}".format(e))
        continue
    except:
        foo.write("\n" + str(e) + ":" + str(n) + '--kesson--' + "\n")
        continue
foo.close()
```

パラメータはだいたいこんな感じかと思いますが、適宜調整してください。
git　リポジトリの設定方法


https://qiita.com/minoringo/items/917e325892733e0d606e

まず作業ディレクトに移動する

```
$cd //ディレクトリ名
```

```
$ git remote -v　//現在のリモートURLを確認（fetchとpushが表示される）
```

```
$ git remote set-url origin （gitのSSH　） //新しいリモートURLに変更する
```

↓画像の<font color="Red">赤</font>の部分がSSH
![image0-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1787372/9ea69ed1-45cb-5ebd-8abf-b7be102c17a9.jpeg)



```
$ git init　//作業ディレクトリにGitを使う宣言　
```

#ここからはプッシュ方法

```
$ git add .
```

```
$ git commit -m "メッセージ（何をしたか書く）" //コミット
```

```
$ git push origin  ディレクトリ名 //プッシュ
```

ssh key 求められる（？）
→求められたら公開鍵設定

```
$ less ~/.ssh/id_rsa.pub
```
kintoneの標準機能で対数を求める #1

今回はkintoneの標準機能の数式を使って自然対数ln(X)を求めます。
このln(X)、数学では

```math
\ log_eX\\
\ logX\\
```

のように書かれますね。
「ろぐいーていえっくす」のように読まれるやつです。
プログラミングの世界ではlogではなくてlnを使うようです。

というわけで、kintoneの標準機能で自然対数の近似をしてみたいと思います。

# 計算方法

ln0は定義されておらず
X=0の周りのマクローリン展開をすることができません。

そこで、X=x+1 とおいて、ln(x+1)をx=1でテイラー展開すると

```math
\ -1<x\leqq1 のとき\\
\ln(x+1) = x -\frac{x^2}{2} +\frac{x^3}{3} - \frac{x^4}{4} + ・・・\\
```

のような多項式に近似することができます。
※詳しくは以下をご参照ください。

https://manabitimes.jp/math/1180

これを利用して、たとえば以下のように近似したいと思います。

```math
\ -1<x\leqq1 より0<X\leqq2 \\
\ X=1.5 のとき\\
\ x = 1.5 - 1 = 0.5 なので\\
\ lnX = ln1.5 = ln(0.5+1) =  0.5 -\frac{0.5^2}{2} +\frac{0.5^3}{3} - \frac{0.5^4}{4} + ・・・\\
```

# アプリの準備

アプリ自体は結構シンプル。

アプリ名は**lnX(0<X≦2)を求めるアプリ**としておきましょう。
※あとでルックアップしてくるときに使います。

| フィールド種類 | フィールドコード | 数式 |備考 |
|:-:|:-:|:-:|:-:|
| 数値  | X  |   ||
| 計算  |  lnX | SUM(項)  ||
| 数値  | 次数  |   |テーブル内フィールド手入力が大変だけど1から100まで行作ってね。|
| 計算  | 項  |  後述 |テーブル内フィールド|
| 計算| x  | X-1  |グループ内に隠してもOK|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/0b251574-a59b-3710-544f-3b162ec26533.png)

計算フィールドの「項」の数式はこんなかんじ。

```
(-1)*(-x)^次数/次数
+(-1)*(-x)^次数*(-x)^100/(次数+100)
+(-1)*(-x)^次数*(-x)^100*(-x)^100/(次数+200)
+(-1)*(-x)^次数*(-x)^100*(-x)^100*(-x)^100/(次数+300)
+(-1)*(-x)^次数*(-x)^100*(-x)^100*(-x)^100*(-x)^100/(次数+400)
+(-1)*(-x)^次数*(-x)^100*(-x)^100*(-x)^100*(-x)^100*(-x)^100/(次数+500)
```

## 有効桁数の設定

アプリの設定で、その他の設定→高度な設定の
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/446c184b-81de-17ef-6627-adc3112da296.png)

数値と計算の精度の桁数は
全体の桁数：30
小数部の桁数：10
にしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/00d88d15-df43-2590-5aa5-b0dee79c1386.png)



# 使い方

準備：テーブル行を追加して次数フィールドに1～100まで入力します。（csvなど読み込ませてもいいかも）
準備ができたらXに0より大きくて2以下の値を入力すると、lnXフィールドに計算結果が表示されます。
近似値なのでピッタリ！というわけにはいかないけど近い値が計算結果が表示されます。

別の計算がしたくなった場合は、テーブル内の入力が面倒なので
新規レコードを追加するのではなく、「レコードの再利用」をして計算してね。

実際に計算してみた動画コチラ↓

<iframe width="480" height="360" src="https://www.youtube.com/embed/p9P7yShpQ5Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
HTML と CSS で動くボタンを作ってそれっぽく見せる

#HTMLとCSSのみで影付きで動くボタンを実装します。

こんなの

![button.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1844196/4d4dfc36-1bbc-95ce-7462-ad92111a19a7.gif)

まずは下準備

```html
<div class="container">
     <span class="btn message">さっそく購読する</span>
</div>
```

ここではセレクタとしてクラスにbtn messageを設定します。

次いでCSS

```css
.btn{
    padding:8px 24px;
    color:white;
    display:inline-block;
    opacity:0.8;
    border-radius:4px;
    cursor: pointer;
    background-color:#5dca88;
}
```
この時点で角丸のかわいらしいボタンが出来ますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1844196/d97b9271-ea7b-5a6e-7ac3-ff12346230f6.png)

##影をつけます。

```css
.btn{
    padding:8px 24px;
    color:white;
    display:inline-block;
    opacity:0.8;
    border-radius:4px;
    cursor: pointer;
    background-color:#5dca88;
    box-shadow: 5px 7px 5px 1px rgba(68, 73, 70, 0.3); /*影を追加*/

}
```
するとこんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1844196/00f5f181-dc78-2c41-2b4e-c6dd31c6c218.png)


box-shadowはプロパティ値が多いので説明します。
左から順番に要素から相対的な X および Y のオフセット、ぼかしと拡散の半径、色を指定しています。
つまり、一つ目の値である5pxのところを10pxにすれば右方向に影が生成され、2つ目の7pxを変えれば下方向に生成されます。
あとはぼかし具合と影の半径（大きさ）を決めて、最後にrgbaで色味と透明度の設定をしています。

詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow)でも読みやがってください。

##お次はマウスオーバーした際に色が変わるようにします。
その方がかわいいから。

以下をCSSに記述します。

```css
.btn:hover{
    opacity:1;
}
```
こんな感じになります。（画像が雑ですみません）
![button hover.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1844196/703bad49-126c-8e45-bcac-7272527235f1.gif)

マウスオーバーした際にopacity(透明度）が0.8 から1.0変更されることによって選んだ感を出してるわけです。

##最後に押下時の動きをつけます。

```css
.message:active{
    box-shadow:none;
    position:relative;
    top:7px;
}
```
出来上がり(画像雑ですみません）
![button.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1844196/4d4dfc36-1bbc-95ce-7462-ad92111a19a7.gif)

セレクタ:activeによって押下時の動きをつけているのですが、
box-shadow:none;にすることで影を消し、
position:relative; で要素の基準位置を設定し、
更にtop:7pxで、ボタンの左上（基準位置）から7px下にボタンを表示する、となっているわけですね。

すると結果的ボタンに動作を与えることが出来るんですね。

また一つ賢くなってしまったね。
テスト環境でディスクキャッシュを避けるためにUserDefaultsをDIする


##前提
UserDefaultsはディスクキャッシュなので、テスト環境ではメモリキャッシュにしたい。
その為ディスクキャッシュとメモリキャッシュをDIによって分けられるようにする。

##1.Protocolを作る
使用しているUserDefaultsのメソッドを、
UserDefaultsTypeとしてプロトコルに記述する。
今回はsetメソッドとobjectメソッドを例とする。

```Swift
protocol UserDefaultsType {
    func set(_ value: Any?, forKey: String)
    func object(forKey: String) -> Any?
}
```
##2.UserDefaultsをProtocolに準拠させる
UserDefaultsのDIであり、UserDefaultsにあるメソッドを
Mockクラスで使用する前提なのでUserDefaultsは準拠するだけでよい。

```Swift
extension UserDefaults: UserDefaultsType {}
```

##3.Protocolに準拠したMockクラスを作る
ここでメモリキャッシュになるよう単純に内部で辞書を持たせる。

```Swift
class MockUserDefaults: UserDefaultsType {

    private var store: [String: Any] = [:]

    func set(_ value: Any?, forKey: String) {
        store[forKey] = value
    }
    func object(forKey: String) -> Any? {
        return store[forKey]
    }
}
```

##4.DIする
userDefaultsにUserDefaults.standardが代入されれば
内部の処理はUserDefaults.standardで行われ、
MockUserDefaultsが代入されれば
内部の処理はメモリキャッシュで行われる。

```Swift
struct Hoge {

    let userDefaults: UserDefaultsType

    init(_ userDefaults: UserDefaultsType) {
        self.userDefaults = userDefaults
    }

    func set(_ value: Any?, forKey: String) {
        userDefaults.set(value, forKey: forKey)
    }
    func object(forKey: String) -> Any? {
        return userDefaults.object(forKey: forKey)
    }
}

// 使い方

// ディスクキャッシュ
let hoge = Hoge(UserDefaults.standard)
hoge.set("hogeString", forKey: "hoge")
hoge.object("hoge") // hogeString
// メモリキャッシュ
let mock = Hoge(MockUserDefaults())
mock.set("hogeString", forKey: "hoge")
mock.object("hoge") // hogeString
```

##終わりに

これで外部から注入することによってディスクキャッシュとメモリキャッシュを
切り替えることができるようになりました。
テスト環境ではなるべくメモリキャッシュを使っていきたいですね。
SQL Server JDBCでTLSエラーが出る時の対処法

SQL Serverのサーバー側がTLS1を使用していると、セキュリティの制限でエラーとなることがある。

環境
Debian 10
OpenJDK 8 JRE Headless
Python 3.9
SQL Server JDBC 9.2.1.0 Jpn

# エラー
```
com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: ドライバーが SSL (Secure Sockets Layer) 暗号化による SQL Server への安全な接続を確立できませんでした。エラー: "The server selected protocol version TLS10 is not accepted by client preferences [TLS12]"。
```

# Javaの場所を探す
```
$ /usr/sbin/update-java-alternatives -l
java-1.8.0-openjdk-amd64 1061 /usr/lib/jvm/java-1.8.0-openjdk-amd64
```

参考：https://symfoware.blog.fc2.com/blog-entry-1166.html

# java.securityを編集
jre/lib/security/java.securityという設定ファイルを確認すると、
クライアント側のTLSについて下記の設定が見つかる。
ここでTLSv1が制限されていることが当初のエラーの原因

なお、JDK 11では、/conf/security/java.securityにある。

```
$ cat /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/security/java.security

(略)
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves
(略)
```
↓

```
$ cat /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/security/java.security

(略)
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves
(略)
```
としてやればok.
後ろの行が優先されるので、編集ではなく末尾に新たな行を作って追記しても動作する。


参考：
https://stackoverflow.com/questions/32466407/how-to-force-java-server-to-accept-only-tls-1-2-and-reject-tls-1-0-and-tls-1-1-c
laravelにおいてのbootstrap導入方法

ダウンロードとかいろいろ書いてあるけど、、、
headの部分に

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
```
を書くだけでOK！

#テンプレート
```html
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
</body>
</html>
```

#Bootstrapのドロップダウンが動かない場合

**→必要な jQuery とか popper.js を読みこんでないから**

その場合は以下のテンプレートを貼り付けて使って下さい

```html
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
</body>
</html>
```
多対多の参照関係のオブジェクトの抽出

SOQLはSQLとちがって、簡単にリレーション出来ない。
どうするのかなぁって思っていましたが、やはり結果を変数に入れて検索するみたいです。
ひとつのクエリーではできんな。

https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C57zPSAR
Flutter と React Native: 現在、どちらが最良でしょうか。（第一部）


<!-- wp:image {"id":1168,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://ints.vn/wp-content/uploads/2021/08/flutter-vs-react-native-copy-1024x534.png" alt="" class="wp-image-1168"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Flutter と React Native？次のプロジェクトにどの「武器」ほうが適切するかと疑問することはありませんか？新人の場合はどの言語を習得する価値があるのか悩んでいます。この記事では、上記の質問に対する最も一般的な回答を見つけるお手伝いをします。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>毎日、世界中で独特なビジネスアイデアを持つ数千ベンチャー企業、特にテクノロジー会社が生まれています。**Uber やAirBnb** などの企業の成功から熱狂的な歓声とともに、**「ゼロ・トゥ・ヒーロー」** の向上心を持つ数千のアイデアが生まれ、徐々に何百万の若者の高貴な理想になります。&nbsp;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>現在のビジネス会社にとってモバイルアプリやウェブサイトの開発は必要があるため、最初の部分に質問を載せました。モバイルアプリの出現のおかげで、私たちと顧客のつながりを作り、顧客のロイヤルティシステム(会員システム)を構築します。したがって、パフォーマンスも高いし、実行速度も速いし、セキュリティが高いアプリを構築できるように、多くの作業が必要です。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>アイデアを早く実現して市場に投入するために、テクノロジー会社はそれを素早く実施できる**cross-platform app** というツール を優先で選択します。**Flutter と React Nativeは現在の最も人気がある２つのcross-platform appです** 。**Androidと iOSの両方のプラットフォームで実行できる** アプルを作成することで、多くの時間、労力とお金を節約できます。Cross-platform appは、クロスプラットフォーム構築するために **コードベースのほぼ80％** を共有します。それで、アプリを別のプラットフォームで発行するために、開発者はコードの20％だけ変更する必要があります。ネイティブソリューションの場合はコードの約90％を書き直す必要があります。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":1169,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image size-full"><img src="https://ints.vn/wp-content/uploads/2021/08/cross-platform-mobile-app-2021-1024x728-1.png" alt="" class="wp-image-1169"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>*2021年のクロスプラットフォームモバイルアプリ開発*</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>つまり、高品質な製品など目的を達成するためには、さまざまな面に注意する必要があります。これにチームの構成、開発者の位置とSDLCモデルが含まれます。ただし、最も重要な部分は**tech stack**です。専門家は、cross-platform app開発で一流のテクノロジーであるため、FlutterまたはReactNativeをよく選択します。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>市場にの多くのCross-platformフレームワークのうち、FlutterとReactNativeは激しい競争にさらされています。ITコミュニティは、それらを今日の最も高度なソリューションと見なしています。しかし、**Xamarin, Cordova, Ionicと他のフレームワーク** などの他の競合他社がまだあります。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>上記に基づいて、開発中に、チームは **「FlutterとReactNativeのどちらが優れているのか」** という質問をよく挙げます。次の記事では、FlutterとReact Nativeの長所と短所を詳細に比較します。</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><a href="https://ints.vn">株式会社INTS</a>　開発部　ハイ・アン</p>
<!-- /wp:paragraph -->
異なるアカウント間でS3バケットを同期する

## 事前準備
送信元のバケットポリシーで、送信先からのアクセスを許可しておく。

```json
{
     "Version":"2012-10-17",
     "Statement": [
          {
               "Sid": "DelegateS3Access",
               "Effect": "Allow",
               "Principal":{ "AWS": "xxxxxxxxx"},
               "Action":"s3:*",
               "Resource": [
                    "arn:aws:s3:::test-sync-src/*",
                    "arn:aws:s3:::test-sync-src"
               ]
          }
     ]
}
```

* 送信元にファイルをアップロード、送信先は空であることを確認

```
$ aws s3 ls s3://test-sync-src/
2021-08-04 01:45:13     133384 apple.png
$ aws s3 ls s3://test-sync-dst/
```

## 同期する
* 2つのバケットをsyncする

```
$ aws s3 sync s3://test-sync-src s3://test-sync-dst
copy: s3://test-sync-src/apple.png to s3://test-sync-dst/apple.png
```

## 削除を同期する
* 両方のバケットにapple.png, mikan.pngがある状態にしておく
* そこから、送信元だけmikan.pngを削除
* 削除を同期するには`--delete`をつける

```
$ aws s3 sync --delete s3://test-sync-src s3://test-sync-dst
delete: s3://test-sync-dst/mikan.png
```

## 参考
* [AWSアカウント間のS3 syncを実行してみました。](https://dev.classmethod.jp/articles/test-s3-sync/)
* [AWS CLIでS3を操作するコマンド一覧](https://qiita.com/uhooi/items/48ef6ef2b34162988295)
[Ruby on rails]検索結果でもページネーション使う　kaminari

<h2>初めに</h2>

過去の検索機能実装の記事はこちら。

https://qiita.com/ki_87/items/eb6d4e440195c3b3c5a2

ページネーション導入済みで、一覧画面では使用してましたが、
検索結果では使わず、全表示にしていました・・・。
なので、今回検索結果の表示画面でもページネーションを使用していきたいと思います。

<h2>コントローラー</h2>

```
class Users::SearchesController < ApplicationController
  def index
  users= User.search(params[:keyword])
  @users=users.page(params[:page]).per(25)
  end

end
```

これでほぼOKです！

<h2>VIEW 検索結果表示画面</h2>

```
       <div class="pagination pagination-sm justify-content-center">
       <%= paginate @users %></div
```

以上で、完了です。
Jetpack Composeを触るときにInteractive Previewが便利

こちらに書いてある内容です。

https://developer.android.com/jetpack/compose/preview?hl=ja#interactive

Jetpack Composeを利用するときに、Interactive Previewを利用すれば、アプリをビルドすることなくタップやアニメーションなどの動作確認ができます。
ドキュメントに掲載されている以下の例では、Android Studio内でボタンをタップしたときの挙動を確認することができます。

![Interactive Preview](https://developer.android.com/images/jetpack/compose/preview-interactive.gif?hl=ja)

# 設定方法
1. Jetpack Composeに対応しているAndroid Studio（Arctic Fox以上）をダウンロードします
2. 設定を開き、 `Experimental`→`Jetpack Compose`の`Enable interactive and animation preview tools` を有効にします
![スクリーンショット 2021-08-04 11.02.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227196/ce17a273-d8fe-9119-6192-6ff996d2284f.png)

3. Composeのプレビュー画面にあるInteractive Previewボタン<img src="https://developer.android.com/images/jetpack/compose/preview-interactive-button.png?hl=ja" width="25">をタップします。
Android Studioをアップデートしたら文字列検索で文字化けしてしまった

#解決方法

### Preferances→Appearance→Use custom fontにチェックをつける

![スクリーンショット 2021-08-04 11.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694541/da0151aa-f6d9-38d6-4935-aff454df58f5.png)
【Google Cloud Day'21】「API 活用最前線：Apigee 最新情報と国内事例」を視聴して

API 活用最前線：Apigee 最新情報と国内事例
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d1-appdev-06
最近の国内事例をベースに、Apigee が導入される 3 つの主要な API 活用パターン（エコシステム構築、ビッグデータ活用、IT モダナイズ）を紹介する。あわせて、Apigee X（次世代 Apigee SaaS）など、Apigee の最新情報を紹介する。

<table>
	<tr>
		<th>質問</th>
		<th>回答</th>
	</tr>
	<tr>
		<th>Apigee X、Google Cloudに取り込まれたことですが、Backendとの通信がプライベートなのでGKE、Cloud load balancingとのレイテンシーとか有利な点ありますでしょうか。</th>
		<td>はい、バックエンドがGCP上にある場合、GCP内部での通信になるため、NWレイテンシー的には明らかに有利になります</td>
	</tr>
	<tr>
		<th></th>
		<td>またInterconnectと組み合わせることで、フロント・バックエンドとの通信にVPNや専用線を使うことができるようになりました。</td>
	</tr>
	<tr>
		<th>どの業界のユーザーが多いのでしょうか？</th>
		<td>失礼しました。Web API エコノミーやエコシステムの構築にApigeeは強力な武器になりますので、業界にこだわらず、すべてのインダストリーのお客様でお使いいただいております。</td>
	</tr>
	<tr>
		<th>料金体系の情報を教えて下さい。</th>
		<td>こちらをご覧ください https://cloud.google.com/apigee/pricing</td>
	</tr>
	<tr>
		<th>具体的な構成例などの資料などありますでしょうか？</th>
		<td>Apigee事例はこちらにまとまっています（英語モードでご覧ください） https://cloud.google.com/customers/?hl=en#/products=API_Management</td>
	</tr>
	<tr>
		<th></th>
		<td>下記事例などにも構成図が含まれています。セブンイレブン様事例 https://cloud.google.com/blog/ja/topics/customers/seven-central-on-google-cloud-platform</td>
	</tr>
	<tr>
		<th></th>
		<td>アサヒグループ様事例 https://cloudonair.withgoogle.com/events/google-cloud-inside-retail-4?talk=session-12</td>
	</tr>
</table>

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>APIgeeとは</th>
		<td>バックエンドシステムの前に配置して、管理する。</td>
	</tr>
	<tr>
		<th>APIの活用パターン</th>
		<td></td>
	</tr>
	<tr>
		<th>最新情報</th>
		<td></td>
	</tr>
	<tr>
		<th>これまでとこれから</th>
		<td></td>
	</tr>
	<tr>
		<th>aspigee x のメリット</th>
		<td></td>
	</tr>
</table>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e93e2f07-6f3e-19a4-7508-c21fe7ff6fd1.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/da832278-8875-b4e7-f9b1-50fe96d6050a.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/0a9390bf-760e-0194-0091-feacfe5e58e0.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/7cfd48a8-5e55-1788-ea54-6c7106608d02.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/b055226a-3d43-d1f9-de7a-09f116e3c81d.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/c7add099-2378-045f-117b-6b93331d5e73.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/417998cf-028c-7278-4ca6-d109e1fe5e2a.png)
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/2a5881a4-1620-3340-36e2-34b3fd0ec4d2.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/812e7525-80f2-ec58-638d-ce76141550ad.png)
jarファイルをjdbcドライバも含めて作成する

## 概要
jdbcドライバも含めたjarファイルを作成する方法。
ここでは、Sample.javaというファイルと、sample-jdbc-1.0.0.jarとsample002-jdbc-1.0.0.jarというjdbcドライバを使う例を書く。

## Classファイル生成
まずはclassファイルを作成する。
ドライバは`:`でつなぐ。windowsの場合は`;`でつなぐらしい。（未確認）

```
$ javac -classpath "./sample-jdbc-1.0.0.jar:./sample002-jdbc-1.0.0.jar" Sample.java
```

実行

```
$ java -cp ".:./sample-jdbc-1.0.0.jar:./sample002-jdbc-1.0.0.jar" Sample
```

## jarファイル作成
以下コマンドでjarファイルを作成する。

```
$ jar cvf Sample.jar *.class
```

jarの中身を見てみるとこんな感じ。このまま実行するとエラーになるので、MANIFEST.MFに追記をする必要がある。

```
$ jar tvf Sample.jar
     0 Wed Aug 04 09:47:44 JST 2021 META-INF/
    66 Wed Aug 04 09:47:44 JST 2021 META-INF/MANIFEST.MF
  2559 Wed Aug 04 00:56:48 JST 2021 Sample.class
```

## MANIFESTファイルに追記
jarファイルを解凍する。

```
$ jar xvf Sample.jar
  created: META-INF/
 inflated: META-INF/MANIFEST.MF
 inflated: Sample.class
```

解凍すると、META-INF/MANIFEST.MFというファイルがあるので、Main-Classと、jdbcドライバを使う場合はClass-Pathを追記する。jdbcドライバが複数ある場合は、スペース区切りで定義する。

```diff:META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 13.0.2 (Oracle Corporation)
+Main-Class: Sample
+Class-Path: sample-jdbc-1.0.0.jar sample002-jdbc-1.0.0.jar
```

## 再度jarファイルの作成
編集したMANIFESTファイルとjdbcドライバをjarにまとめる。

```
$ jar cvfm Sample.jar META-INF/MANIFEST.MF *.class sample-jdbc-1.0.0.jar sample002-jdbc-1.0.0.jar
added manifest
adding: Sample.class(in = 2559) (out= 1505)(deflated 41%)
adding: sample-jdbc-1.0.0.jar(in = 8394004) (out= 7238099)(deflated 13%)
```

## 実行
これで実行可能となる。

```
$ java -jar Sample.jar Sample
```


## javadocを作る場合
ソースコード中に埋めたコメントを使ってリファレンスマニュアルを自動生成することができる。
以下コマンドを実行すると、docというディレクトリが作成され、その中にマニュアルが作成される。

```
$ javadoc -d doc Sample.java
```

## 参考
https://www.tohoho-web.com/java/other.htm
AZ　IDってなんだ？？

AWS案件の中で「AZ ID」なるものが出てきたので、なんぞやといろいろ調べてみました。

#1.アベイラビリティーゾーン（AZ）とは

:::note info
「AZってなんだっけ？」という方以外は、この項目を飛ばしてください！
:::

AWSは以下の構造で構成されています。
※基本的な部分のみ大雑把に記載しています。

**リージョン（Regions）**
AWSが構築したデータセンタで、各国にあり、物理的に完全に分離されています。

　＜リージョン例＞

| コード | 名前 |
|:-----------|:------------|
| us-east-2 | 米国東部 (オハイオ)|
| ap-northeast-1 | アジアパシフィック (東京)|
| ap-northeast-3 | アジアパシフィック (大阪)|
AWSリソースを作成する際に、どこで作るかを最初に決めていますよね。

**アベイラビリティーゾーン（Availability Zones／AZ）**
リージョンごとにアベイラビリティーゾーンと呼ばれる複数の物理的に完全に分離した場所があります。

＜アジアパシフィック (東京)のAZ例＞

| AZ名 |
|:-----------|
| ap-northeast-1a |
| ap-northeast-1c |
| ap-northeast-1d |

:::note alert
アジアパシフィック (東京)において「ap-northeast-1b」は存在しない
:::

これらはSubnet作成時に指定しているものですね。

#2.AZ IDとは
では「AZ ID」とはなんなのでしょう。
実は**AWSの物理的なデータセンタ群と紐づいたAZのID**です。
AWSでは、各リソースがリージョン内の複数のAZに分散するように、ユーザ側で指定するAZ名と実際のAZ(物理的なDC群)との関連性について、AWSアカウント毎にマッピングする仕様となっています。
**AWSアカウント作成時にAZ名とAZ IDがAWSによって自動的にマッピングされる**のですね！

:::note alert
AZ IDを直接指定する事は出来ません。
:::

:::note warn
各AZ IDで機能差異はありません。
:::

＜アジアパシフィック (東京)のAZ ID例＞

| AZ ID |
|:-----------|
| apne1-az1 |
| apne1-az2 |
| apne1-az4 |

マッピングイメージはこんな感じです。
![AZ名とAZID関連図_210730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588693/f279edd6-5bb5-b05d-2bb9-f3826b60eb7e.png)


#3.AZ ID実装経緯
AWSの大規模な利用が進むにつれ、「**複数アカウントを利用しながら可用性を高める目的でマルチAZを進めても、AWS側の物理DC群が同じになってしまっては可用性担保にならない**」というユーザの声に応える形で「AZ ID」が実装されたようです。
AWSアカウントごとに同じAZ名でもAZ IDが異なる実体を見える化したと言い換える事も出来そうです。
※AWSの中の人にこっそり聞きました。

#4.AZ IDの使用用途
AWS側の物理的なDC群を明示的に指定する必要がある場合に利用します。
例えばこんな感じでしょうか。

| AWSアカウント | リージョン | AZ ID | AZ名 |
|:-----------|:------------|:------------|:------------|
| アカウントA | ap-northeast-1 | apne1-az1 | ap-northeast-1a |
| アカウントB | ap-northeast-1 | apne1-az1 | ap-northeast-1c |

AZ IDを「apne1-az1」にしたいから、このアカウントでマッピングされている「ap-northeast-1a」を選択するといった考え方になります。
ちなみに、AZ IDの数字が大きいものが新しい設備だそうです。
この事から、AWS側の新しい設備を使用したいという理由でAZ IDを利用する事も可能です。

#5.AZ IDの確認方法
AZ IDはAZ名選択時に画面表示される訳ではありません。
AZ IDとAZ名のマッピング状態を確認する画面が別にあるので、そこでどのAZ名がどのAZ IDに割り当てられているかを確認した上で、AZ名を選択する必要があります。
確認方法はこちらになります。

①AWSコンソールから「Resource Access Manager」を選択する。
②Resource Access Managerコンソール画面の右下の方に以下のような項目がある。
＜リージョンが東京の場合＞
![AZID表示_210730.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588693/e720b1b3-dd9c-fb2e-7cbc-f1d6ddfe9131.jpeg)
＜リージョンが大阪の場合＞
![AZID表示（大阪）_210730.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588693/3eba6f5f-a14a-89d1-b38d-148ec559b24c.jpeg)

:::note warn
上記は私の個人所有AWSアカウントの情報ですので、別のアカウントではマッピング結果が異なっていると思います。
:::

#6.最後に
複数アカウントを組み合わせて1つのシステムをAWS構築するなんて案件はそうそうお目にかかった事はないのですが、クラウドといえども根っこはオンプレである事を再認識しました。
クラウドのハード側はクラウド事業者（AWSなど）の責任範囲になっているので普段あまり気にしないのですが、大規模の場合はクラウド側のハード領域まで気にしないといけない場合もあるのだなと、ちょっと目から鱗状態でした。
そして、「そこはAWSの責任範囲だから気にしないで！」と跳ね返す事をせず、逆にユーザ意見を取り込んで機能実装するAWSの心意気をちょっと感じた今日この頃でした。
このAWSの心意気はマネしたいマインドだと思います。
[備忘録]SQLクエリまとめ①

今回は、SQLを少し勉強したので、備忘録として残しておきます。

今までは、Railsで開発をしていて、SQLについて深く考えることはなかったですが、今回SQLを学んでみて、ログを見るときなど意味を理解して見れるようになりました。

#FROM

- どのテーブルからデータを取得するか
- `FROM テーブル名`

```sql:
FROM posts
```

#SELECT

- どのカラムのデータを取得するか
- `SELECT カラム名`

```sql:usersテーブルのnameカラムのデータを取得
SELECT name
FROM users;
```

```sql:複数のカラムからデータを取得
SELECT name, email
FROM users;
```

```sql:全てのカラムからデータを取得
SELECT *
FROM users;
```

#WHERE

- どこのレコードを取得するか
- `WHERE 条件`

```sql:nameがカレーのレコードを取得
SELECT *
FROM menus
WHERE name = "カレー";
```

```sql:priceが1000円以上のレコードを取得
SELECT *
FROM menus
WHERE price >= 1000;
```

####LIKE

- 部分一致（あいまい）のデータを取得できる
- `WEHERE カラム名 LIKE "%条件%";

```sql:nameがラーメンのレコードを取得
SELECT *
FROM menus
WHERE name LIKE "%ラーメン%";
```

####NOT

- 条件を満たさないデータを取得する
- `WEHERE NOT 条件`

```sql:priceが1000円以上ではない、レコードを取得
SELECT *
FROM menus
WHERE NOT price >= 1000;
```

```sql:nameがラーメンではない、レコードを取得
SELECT *
FROM menus
WHERE NOT name LIKE "%ラーメン%";
```

####AND

- WHEREに複数の条件を指定できる
- 条件を全て満たすデータを取得できる
- `WHERE 条件1 AND 条件2`

```sql:nameがラーメンかつ1000円以上のレコードを取得
SELECT *
FROM menus
WHERE name LIKE "%ラーメン%"
AND price >= 1000;
```

####OR

- WHEREに複数の条件を指定できる
- いずれかの条件を満たすデータを取得できる
- `WHERE 条件1 OR 条件2`

```sql:nameがラーメンまたはカレーのレコードを取得
SELECT *
FROM menus
WHERE name LIKE "%ラーメン%"
OR name LIKE "%カレー%";
```

#ORDER BY

- 取得したデータを並び替えられる
- `ORDER BY カラム名　順番`
- ASC（昇順）小さいから大きい数、DESC（降順）大きいから小さい数

```sql:priceの大きい順
SELECT *
FROM menus
ORDER BY price DESC;
```

#LIMIT

- 何件取得するかを指定できる
- `LIMIT データの件数`

```sql:menusテーブルのデータを5件取得
SELECT *
FROM menus
LIMIT 5;
```

#まとめ

今回は、ここまで！

メモ帳みたいになってますが、またSQL関連の記事あげます。
MacでPrivate NetworkのMWAAのURLを立ち上げるコマンド

MWAAは、Private Network Onlyでのアクセスが推奨されていて、自分たちのチームでもAirflowをPrivate Networkに立ち上げて、適切にアクセス制限したALB経由でUIにアクセスするようにしています。

ただ、そうすると毎回awscliでtokenを作成してURLを作成する必要があり、少し煩雑なので、コマンドで立ち上げるようにエイリアスを設定しました。

```zsh:~/.zshrc
# {YOUR PROFILE}　と　{YOUR DOMAIN} 、{YOUR MWAA NAME} はそれぞれ置き換えてください
# jqとawkが必要です
alias mwaa="aws mwaa create-web-login-token --name {YOUR MWAA NAME} --profile {YOUR PROFILE} | jq -r '.WebToken' | awk '{print \"https://{YOUR DOMAIN}/aws_mwaa/aws-console-sso?login=true#\"\$1}' | xargs open"
```

実は標準入力からの文字列結合に詰まってて、[Stackoverflow](https://stackoverflow.com/questions/4181703/how-to-concatenate-string-variables-in-bash)によるといくつかやり方があるみたいですが、awkを使った方法にしました。

また、Macでは`open`コマンドでURLをブラウザで開けることを初めて知りました。

# 参考資料

* [Apache エアフロー UI へのアクセス（公式ドキュメント）](https://docs.aws.amazon.com/ja_jp/mwaa/latest/userguide/access-airflow-ui.html)
* [How to concatenate string variables in Bash](https://stackoverflow.com/questions/4181703/how-to-concatenate-string-variables-in-bash)
Vue.js 公式ドキュメントを読めるようにする 用語集

#基本的な使い方

##はじめに
|用語|意味|
|--|--|
|プログレッシブフレームワーク||
|モノリシックなフレームワーク||
|宣言的レンダリング||
|描画||

##Vueインスタンス
|用語|意味|
|--|--|
|el:||
|data:||
|ディレクティブ||
|トランジションエフェクト||
|双方向バインディング|v-modelで行える|
|コンポーネントシステム|小さな利用可能なコンポーネントを組み合わせることで大規模アプリケーションを構築することが可能になる|
|コンポーネント|本質的にはあらかじめ定義されたオプションを持つVueインスタンスのこと。|
|タグ|<a></a>など|
|要素|タグ＋その中身|
|カスタム要素|自分の好きな要素を作成することが出来る。<br> <自由に名前を決められる>-----<自由に名前を決められる>|
|プロフィル|polyfill|
|vm|MVVMパターンから部分的に影響を受けているため、vm（ViewModelの略）をVueインスタンスの変数名としてよく使う|
|★Vueインスタンスの生成|オプションオブジェクトを渡す？|
|オプションオブジェクト||
|レンダリング||
|ビューのレンダリングの特徴|dataのプロパティはインスタンスが作成されたときに存在していた場合のみリアクティブ|
|リアクティブ||
|便利なインスタンスプロパティ・メソッド|頭に$がついている|

##テンプレート構文
|用語|意味|
|--|--|
|||
|||
|||

|||
|||
|||
|||
|||

##算出プロパティとウォッチャ
##クラスとスタイルのバインディング
##条件付きレンダリング
##リストレンダリング
##イベントハンドリング
##フォーム入力バインディング
##コンポーネントの基本

#コンポーネントの詳細

##コンポーネントの登録
##プロパティ
##カスタムイベント
##スロット
##動的&非同期コンポーネント
##特別な問題に対処する

#トランジションとアニメーション

##Enter/Leaveとトランジション一覧
##状態のトランジション

#再利用と構成

##ミックスイン
##カスタムディレクティブ
##描画関数とJSX
##プラグイン
##フィルター

#ツール

##単一ファイルコンポーネント
##テスト
##TypeScriptのサポート
##プロダクション環境への配信

#スケールアップ

##ルーティング
##状態管理
##サーバサイドレンダリング
##セキュリティ

#内部

##リアクティブの探求

その他

##他のフレームワークとの比較
【モバイル対応】URLでアプリを開く

# 背景
スマホのブラウザで閲覧するWebアプリケーションに配置されたボタンから
インスタグラムの**アプリ**に遷移する要件があった。
しかし、ただの https://www.instagram.com/ をhrefに設定しても、アプリには遷移されない場合があった。
そこで、どうしたらアプリが開くURLになるか調べた。

# URLでアプリを開く、とは
> 「入力されたURLを画面遷移の情報に変換し、その結果に従って画面遷移する」という処理が組み込まれているアプリに対して、URLを入力すること

引用：[「URLでアプリを開く」を丁寧に深堀りしていく](https://note.com/toridori_inc/n/nb7237a217a51)

それらは**ディープリンク**とも呼ばれている。
そして、そのディープリンクにはいくつか種類がある。

# Custom URL Scheme
今回の要件で必要なインスタグラム　アプリへの遷移は
**Custom URL Scheme**が対応している。

これは、このディープリンクを踏むと、該当するアプリが端末にインストール

- されていればそれを開く
- されていなければ何もしない

その為、インストールされていない場合は何かする場合、
それに応じた処理を別途書く必要がある。

# 実際のURL
インスタグラムのCustom URL Schemeはこのようになっている。

> instagram://app
Instagramのアプリを起動する。

> instagram://camera
Instagram内のカメラを起動する。

> instagram://media?id={メディアID}
メディアIDを指定することで、アプリを起動し、その投稿ページに移動させる。


引用：[Instagram APIでwebサービスを作りたい全ての人に向けて書きました](https://syncer.jp/instagram-api-matome)

# 参考
[「URLでアプリを開く」を丁寧に深堀りしていく](https://note.com/toridori_inc/n/nb7237a217a51)
[ディープリンクとは？仕組み・メリット・事例を詳しく解説！](https://wacul-ai.com/blog/site-improvement/method/deeplink/)
[Instagram APIでwebサービスを作りたい全ての人に向けて書きました](https://syncer.jp/instagram-api-matome)
Power Apps オンライン勉強会 ～コンポーネント祭り～に参加してきました

# Power Apps オンライン勉強会 ～コンポーネント祭り～
https://powerapps.connpass.com/event/217180/?utm_campaign=event_publish_to_follower&utm_source=notifications&utm_medium=twitter

こちらのイベントに一般参加させていただきました。
タイトル通りPower Appsのカスタムコンポーネントが中心の話題で、この日は３人の方が登壇されました。

## セッション1.「コンポーネント勉強会の登壇決まったからコンポーネントの登壇内容決めるためにコンポーネント勉強してみた」
登壇者：[あきらさん](https://twitter.com/akira_365)

初学者目線で見たコンポーネントのお話でした。
途中デモも行われましたが、初めてコンポーネントを触る人のがどのように考え、作っていったかをトレースできるような内容で、私自身コンポーネントが未経験でしたので自分が学習を進める上で参考にしたい内容でした。
またコンポーネントの用途として凝ったデザインのUIなどを複製しそれを集約、流用、共有…といった展開は実際に多くあるパターンなのではないかと思いました。

そして発表に触発されてイベント終了後にさっそくDocsを参考に初コンポーネントを作りました。
個人的にDocsの更新日次を日本語と英語で比べるということをしたことがなかったので今後心がけたいと思います。

スライドはこちら
<script async class="speakerdeck-embed" data-id="7950f690c4564d3ab2e0fb23771208b7" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

## セッション2.「コルネと学ぶコンポーネント」
登壇者：[コルネさん](https://twitter.com/koruneko32767)

こちらはコンポーネントをもう少し掘り下げた内容というか、コルネさんが実際にいくつかコンポーネントを制作されるなかで得られた知見を中心とした発表とのことでした。
カスタムコンポーネント自体がプレビューの状態なためか、色々と設定項目から有効にする必要があったり、廃止予定なため現在は推奨されない作り方、ハマりそうなところなど、作る前に知れて良かったという内容多めでした。
また命名規約やコンポーネントの置き方、業務の特にチームで利用するような場合にも参考になりそうな内容でしたので今後のために是非頭に入れておきたい内容でした。

スライドはこちら
<iframe src="//www.slideshare.net/slideshow/embed_code/key/LVdH76TIbIMbKm" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/ssuser7dbf10/ss-249898640" title="コルネと学ぶコンポーネント" target="_blank">コルネと学ぶコンポーネント</a> </strong> from <strong><a href="https://www.slideshare.net/ssuser7dbf10" target="_blank">korune ☆</a></strong> </div>


## セッション3.「コンポーネントの利用と共有 +最近のアップデート」
登壇者：[Hiroさん](https://twitter.com/mofumofu_dance)

こちらはコンポーネントの基本的な特性（ブラックボックス化）からコンポーネントライブラリの運用を含めたお話でした。
特にコンポーネントライブラリを使いましょう（アプリから作らない）、というところや、各種リソースはアプリのものなのでコンポーネントから直でアクセスしないようにしましょう（コンポーネントのプロパティから利用する）というところは個人的にはうっかりやりそうなので注意したい点でした。
また権限周りのお話や、外部からのコンポーネントをコンポーネントライブラリに持ってくる方法があることなども知ることができ、学びの多い内容でした。

スライドはこちら
<iframe src="//www.slideshare.net/slideshow/embed_code/key/mRmAUr8oot5R84" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/NagaoHiroaki/component-249893944" title="Component勉強会" target="_blank">Component勉強会</a> </strong> from <strong><a href="https://www.slideshare.net/NagaoHiroaki" target="_blank">Nagao Hiroaki</a></strong> </div>

## 全体の感想として
シンプルかつ奥深いテーマでした。
カスタムコンポーネントの使用経験がない私でもとっつきやすい内容でしたし、発表順も初学者向けから深堀りされていくような流れになっていて順を追うようにしてコンポーネントに関する知識に触れることができたように思います。
コンポーネントを使いはじめるハードルは低いですが、効率的な運用などを実現する為には考慮すべき、知るべき点も多くあるのだと感じました。

また、発表中に出てきた[ギャラリーのページ](https://powerusers.microsoft.com/t5/Canvas-Apps-Components-Samples/bd-p/ComponentsGallery)はコンポーネントの作り方やPower Appsにおけるデザインの参考にもなりそうで、これを知れたことも個人的には収穫でした。
初級：ターミナルのコマンドメモ

##位置や移動に関するコマンド
- pwd：現在いるディレクトリを知る
- ls：現在いるディレクトリにあるフォルダやファイルの一覧を確認する
- cd ディレクトリ名：「ディレクトリ名」に移動（change directoryの略）
- cd ..：一つ親のディレクトリに移動（change directoryの略）
- cd：何も位置を指定せずに、cdを実行するとホームディレクトリに移動できる

##位置指定（絶対位置・相対位置など）に関するコマンド
- .. ：【相対位置】一つ親のディレクトリを指定する

##新規作成に関するコマンド
- touch 任意のファイル名：「任意のファイル名」の新規ファイルを作成
- mkdir 任意のディレクトリ名：「任意のディレクトリ名」の新規フォルダ（ディレクトリ）を作成（make directoryの略）

##ファイルやディレクトリを操作するコマンド
- cat ファイル名：「ファイル名」の中身を見る
- mv ファイル名 ディレクトリ名：現在いるディレクトリにある「ファイル名」を「ディレクトリ名」に移す
- mv ディレクトリ名 移動先のディレクトリ名：現在いるディレクトリにある「ディレクトリ名」を「ディレクトリ名」に移す
- mv mv ファイル名 新しいファイル名：現在いるディレクトリにある「ファイル名」を「新しいファイル名」に変更する
- cp コピーするファイル名 新しいファイル名：「コピーするファイル名」を、「新しいファイル名」でコピー版を作成する
- cp -r コピーするディレクトリ名 新しいディレクトリ名：-rを付けることで、cpはディレクトリもコピーできるようになる（ディレクトリの中身も同時にコピーされる）
- rm ファイル名：「ファイル名」を削除する
- rm -r ディレクトリ名：-r を付けることで「ディレクトリ名」を削除できる
Vue.js(作成途中)

#Vue.js

##emit
##v-model
##v-bind＝"boundedVar"
##<slot name="my-slot" v-bind="boundedVar">
##<template #my-slot="boundedVar">
##watch
##emit('input')

#Nuxt.js
##storeでモジュール作成
##const value: any等　any型を使わないで書く
PhigrosのGoogle Play Store版からTapTap版へと移行する大まかな手順

# TL;DR
- できないのは署名の問題だからLuckyPatcherでチェック無効化しよう

***

# 環境
- Android(11 バージョンは関係無いはず)
  - Phigros(リンク無いです...) 1.6.9
  - TapTap
  - (以下入れてない人はリンクから導入してください)
  - [Lucky　Patcher](https://www.luckypatchers.com/download/)
- APKComboでそのままインストールする時に、署名がだめですみたいなエラーが出る( 出てなくても試してみても良いかもね )
- PCは必要ないです

***

# 具体的な手順

## Lucky　Patcherで署名チェックを無効化
まずLucky Patcherを開いてください。
その後、上の虫眼鏡アイコンを押して `Phigros` と検索してください。
一番のあたりに1.6.9のPhigrosが出るはずなのでそれを押してください。
パッチのメニューを開いて、
`Re-sign with original signature for android patch "APK ファイルの署名認証を無効化"`
を押してください。 他のものは選択しないほうが良いでしょう（色々やばい）

（ちょっと待つ）

「正常に完了しました」と出たらファイルを検索を押してください。
またメニューが出るので、「インストール」を押して署名認証が無効化されたAPKファイルをインストールしてください。

## TapTapで1.6.10にアップデート
これは多分難なく行けると思うので割愛で

---
# おわり
史上最高に短くなってしまいましたがこれで終わります。
ありがとうございました！！！
【Ruby on Rails】autofocus: trueを使って自動で焦点をあてる方法


#対象者

* 投稿フォームを作ろうとしている方
* クリックしなくても自動で入力待機状態を作りたい方


#目的

* autofocus属性を使って、自動でカーソルをあわせられるようにする！

#実際の手順と実例
###1.autofocus属性とは？？

* autofocus:trueでページを読み込んだ後、クリックすることなく、カーソルが移動して入力待機状態を作るというメソッド(?)です。


###2.具体例

本の投稿をするアプリを例とします。
入力は下記の通り

````app/views/devise/registrations/new.html.erb 
<h2>Sign up</h2>
 <%= form_with model: @user, url: user_registration_path, id: 'new_user', class: 'new_user', local: true do |f| %>
   <div class="field">
    <label for="user_name">Name</label><br>
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
   </div>

   <div class="field">
    <label for="user_email">Email</label><br>
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
   </div>
:
:
 <% end %>
````

![スクリーンショット 2021-08-04 8.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/3ee6436c-bedd-ee0c-c7cc-f5c9b72a6fd5.png)

画像だと少しわかりにくいですが
上記のように入力するとページ開いたとき
対象のフォームにカーソルが合います。


###3.autocompleteとは、、、？

補足で**autocomplete： "カラム名"**とは自動で入力補助をしてくれる機能です。

途中まで文字を入力すると
「もしかして、、これ打ちたいの？？？」って自動で提案してくれます。

#参照

>[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典　オートコンプリート (AutoComplete)](https://wa3.i-3-i.info/word1552.html)
>[属性 : autofocus (オートフォーカス属性) の解説](https://ywork2020.com/content/property-autofocus.html)


####投稿者コメント

タイトルはrailsですがHTMLでもあるので悩みました笑　
たまに見かけるこれなんだろうと思って調べたらすごく便利そうだったので記事にしてみました。
PFにどんどん実装していこうかなと思います。


####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
【VBscript、Java】Tumblrのエクスポートファイルからホームページを生成する。

こんばんは。

写真共有サービスのTumblrをご存じですか？写真に特化したSNSで、世界中の写真好きの投稿を見る事ができます。ユーザー数はtwitterやfacebookには及びませんが、SNSのデメリットの誹謗中傷なども（自分が知る限りは）殆ど目に触れる事はなく、とっても快適なサービスです。自分は2014年頃から愛用しており、ほぼ毎週投稿しているので、300件くらいの投稿があります。

今回は、Tumblrに投稿した記事を、ホームページ風にアレンジするプログラムを作りましたのでご紹介します。


事情により、VbscriptとJavaの合わせ技という事もあり、またTumblrのアーカイブも（Tumblr社には申し訳ないですが）非常に使い辛く苦慮しました。
空き時間にちょこちょこプログラムを作り、テストでもバグが大量に出まして、結果6か月かかりました（途中でモチベーションが下がりサボった期間含む・・）。

全体像はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/dedcd139-79aa-72a2-df60-ad1fd0d0fa0e.png)


プログラムが多数ありますが、次回解説をしていきます。
改めて振り返るとなんとも複雑なイケてないプログラムになっています・・。
根性と執念を評価していただければと思います。

##1.目的
・Tumblrで投稿してきた写真を好みのフォーマットで作り直す。
→Tumblrは、過去の記事を年月指定で読む機能もない（たぶん）です。過去の記事を見たいなと思う事はありますが、記録として蓄積されるだけの状態になっているので難しいです。facebookやtwitterなど最近のSNSはみんなそうですね。

・Javaでモノづくり
→GASやVbscriptでは経験がありますが、PCにインストールしたJavaで自分の生活に役に立つモノづくりが殆どできていないので、これを機に何か作りたいと思います。

##2.読んでいただきたい方

・Tumblrユーザーの方
・エクスポートファイルを受け取ったものの活用に困っている方

##3.Tumblrのエクスポート

Tumblrは、過去の記事をエクスポートができます。
https://tumblr.zendesk.com/hc/ja/articles/360005118894-%E3%83%96%E3%83%AD%E3%82%B0%E3%82%92%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/66229f48-a58f-0aa0-d3c2-2042a2f86f64.png)

↓設定画面の下段の「エクスポート」を押下します。
これは、これまでの記事をhtmlファイル形式でもらうことができるというものです。
こんなイメージです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/95d00f9e-d2ce-5cec-181d-91833602e13f.png)

インデックスのページになります。「Post：xxx」となっているのは、各記事へのリンクです。リンクの名前の体系は不明です。年月日などが分かると良いのですが・・。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/277d888c-d18b-3c68-1555-8e7561062831.png)

リンクに飛ぶと、こんな感じ。
白地のhtmlファイルに画像と文章が表示されています。シンプルで自分は結構好きです。
しかしながら、記事の数だけファイルが分かれていたり、どの記事がいつ書かれたものかもファイルを開かないと分かりません。また、最大の問題点として、複数の画像を投稿した記事は画像が正しく表示されないのです。これはさすがにちょっと衝撃でした。
記事をダウンロードできるサービスは便利でありがたいものだと思いますが、なかなか活用に困るところです。

##4.作成イメージ

エクスポートファイルは過去の記事を保存する目的はクリアしていますが、そのままでは活用が難しいものになっています。
そこで、ホームページに掲載できるように作り込んでみました。
　・年月毎に記事をまとめる
　・年月ごとのリンクを生成する
主にこの2点の対応で、かなりアクセスしやすくなると考えました。

もはや個人ホームページの文化は廃れているのかも知れませんが、やはり自分だけのオリジナルホームページというのは個性も出るし、温かみもあって良いものです。

こんな画面になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/fbb70e6c-2619-a5b4-b2bd-96dcc98a6975.png)

同じ月の投稿を1つのページにまとめています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/fb2b68c1-82e4-5781-feb9-ba883d4e4702.png)

これがページの末尾です。ここで各投稿月のリンクを生成しています。

プログラムはVBscript、Javaを使いました。恐らくJavaのみでもっとシンプルにできると思いますが、自分がVBscriptの方が使い慣れているため混在しました。
周囲の黄色い枠や、文字のフォントはスタイルシートで定義しました。

##3.次回から

概要を語ったら長くなりましたので、ここで切ります。
次回以降、具体的なプログラムを紹介していきます。
興味のある方は覗いてみてください！
Next.jsでSSRのページをSSGに書き換える

## はじめに

大した内容ではないのですが、詰まった個所 (具体的には後述する3番目)があったので知見として共有します。

## 1. getServerSideProps => getStaticProps

変数名を変更する。
TS使用時は、`GetServerSideProps`と`GetServerSidePropsContext`も、それぞれ`GetStaticProps`と`GetStaticPropsContext`に書き換える必要があります。

## 2. getStaticPaths の作成

以下の返り値を持つ`getStaticPaths`を作成します。

```
{
  paths: {params: object}[],
  fallback: boolean | 'blocking'
}
```

TSを使用する場合、関数の型は`GetStaticPaths`です。

## 3. getStaticPropsでNext.js APIを使用するのを止める

(このAPIは、`/page/api`のことを指します)
Next.jsのAPI機能を使用しており、かつgetStaticProps内でfetchしている場合、ビルド時点ではAPI機能が立ち上がっていないため、別にサーバーを立ててそちらに向けるか、getStaticProps内で同様の処理をする必要があります。
個人的には好きではありませんが、API側の根幹の処理部分を別の関数として切り出してimportするのが修正としては手っ取り早い形になるかと思います。
CloudFormationで遊んでみる(EC2編)

##記事作成にあたって
インフラ環境の開発や運用コスト、保守性を考慮して、最近流行りのIaCを意識している。
今まで触ったやつだと、ServerlessFrameworkやAmplify。
リファレンス読んでてもしっくりこないなぁって思ってたら、上記2つはCloudFormationを使っている。
だkら、CloudFormation理解してないとそれは深い理解につながっていかんなぁという事で、
今回、遊んでみる事にしました。

##実装
今回はEC2インスタンスを作って見ます。作って見てから、コードの解説をしていきます!!

```yml:ec2.yml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  NamePrefix:
    Type: String
    Description: EC2をテンプレートで作成する
    MinLength: 1
    Default: ec2
  InstanceType:
    Type: String
    Description: EC2のインスタンス
    MinLength: 1
    Default: t2.micro

Resources:
  MyInstance:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: ami-4af5022c
      Tags:
        - Key: Name
          Value: !Sub "${NamePrefix}-ec2" 
```

##AWSマネジメントコンソールでの操作
![スクリーンショット 2021-08-03 14.01.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/f7c876f4-50b1-2aaa-56cb-57f70f2bef02.png)

![スクリーンショット 2021-08-03 14.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/6baeb197-584e-5cad-96b8-6b4bdafb82bf.png)

![スクリーンショット 2021-08-03 14.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/fa4e81d0-dc03-7469-e159-722305789720.png)

![スクリーンショット 2021-08-03 14.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/35d18945-0da8-648d-46dc-6ab91c040acc.png)

![スクリーンショット 2021-08-03 14.08.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/e8271e16-7d16-984b-15b6-d3caf8c8875b.png)

![スクリーンショット 2021-08-03 14.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/59f4c95e-0e2d-bef1-c4a7-a0b0c5ad2735.png)
Matplotlibでダークモード対応の図をいい感じに作る

Matplotlibの表示要素に白色のボーダーを追加することで、同一の画像ファイルでライトモード（白背景）とダークモード（黒背景）の両方で見やすい表示となる作図方法をまとめました。以下の例のように、図の背景を透明にしても線やテキストが黒背景に埋もれず、そこそこ見やすい形で両立できるようになります。

![darkmode-compatible-figure-light.png][light] | ![darkmode-compatible-figure-dark.png][dark]
:---: | :---:
ライトモード（白背景）での表示 | ダークモード（黒背景）での表示

[light]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44000/8fc1a286-8bae-5c49-1407-709dc8dfc3d6.png
[dark]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44000/ea13f77f-f571-0184-3efe-97bb8d6ea897.png

:::note warn
Qiitaの制限によりHTMLを使って背景色を変えられないため、上の例は画像自体に黒背景を描画しています。実際に背景色に応じて表示が変わる様子は<a href="https://astropengu.in/posts/35">こちら</a>をご覧ください。
:::


## Path effects

表示要素（artists）にボーダーを追加するにはpath effects（`matplotlib.patheffects`）を使用します。名前から分かるように、ボーダーを追加できるのはテキストやラインプロットなど線（パス）を持つ要素のみとなります。今回の場合、`withStroke()`でボーダーの線の色と線幅を設定したpath effectオブジェクトを作成します。

```python:要素にボーダーを追加する設定
import matplotlib as plt
from matplotlib.patheffects import withStroke


border = withStroke(linewidth=3, foreground="white")
```

## Examples

ボーダーを追加するには、作成したpath effectオブジェクトを（1）rcParamsでグローバルに設定するか、（2）プロット関連の関数やメソッドが持つ`path_effects`オプションで個別に設定するか、（3）表示要素が持つ`set_path_effects()`メソッドで個別に設定します。以下では（1）の例を紹介します。

```python:全ての要素にボーダーを追加する場合
with plt.rc_context({"path.effects": [border]}):
    plt.plot([1, 2, 1, 3], label="A")
    plt.plot([2, 1, 3, 2], label="B")
    plt.title("Darkmode-compatible figure")
    plt.legend()

plt.savefig("figure.png", transparent=True)
```

:::note warn
rcParamsの"path.effects"は複数の設定を受け取るため、[border]のように配列で渡します
:::

:::note info
rc_context()を使うと、withブロックに書かれた要素のみにボーダーを適用することができます
:::

上の例では図（画像）の外周にもボーダーが追加されてしまうため若干見づらいかもしれません。少し複雑になりますが、以下のように書くことで外周のボーダーを消すことができます。

```python:図の外周のみボーダーを追加しない場合（推奨？）
fig = plt.figure()

with plt.rc_context({"path.effects": [border]}):
    ax = fig.add_subplot()
    ax.plot([1, 2, 1, 3], label="A")
    ax.plot([2, 1, 3, 2], label="B")
    ax.set_title("Darkmode-compatible figure")
    ax.legend()

fig.savefig("figure.png", transparent=True)
```

## References

https://matplotlib.org/stable/tutorials/advanced/patheffects_guide.html

https://matplotlib.org/stable/api/patheffects_api.html#matplotlib.patheffects.withStroke
Cloud Functionsでview数カウンターを作ろう、GA使わんよ

はじめまして。
マインドツリーを使ってメモ書きするサービス<a href="https://qnqtree.com" target="_blank">Q&Q</a>を作っているあどにゃーです。
突然ですがQiitaの記事のオーナーだけが見れることview数って良くないですか？
![スクリーンショット 2021-08-02 23.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/a6591b30-aa39-d69d-027d-1f1f66af6db0.png)
記事のオーナーしか見れないのでマウントの取り合いにもならないですし、記事のオーナはモチベーションにも繋がります。
ということで、<a href="https://qnqtree.com" target="_blank">Q&Q</a>にもこの機能を実装してみたいと思います。:relaxed:

今回はCloud Functionsを使って、記事の閲覧数を記事のオーナがチェックできるようにする機能の解説になります。Google Analytics(GA)つかったサイト全体の解析とかではないです:persevere:

#個人開発のつらみ
個人開発サービスは基本過疎なので一つの記事がどれくらいの人に届いているか不明でモチベーションが難しくなることが多いです:cry: GA解析も全体俯瞰はできますが、一つひとつの記事がどう見られているかってのは案外わかりにくいです:sob:　個人開発にこそ、記事のオーナがView数を見れる機能は付与してみるといいんじゃないかなと思います！

#全体実装の流れ
1. ユーザが記事を閲覧したらUserのuidをFirestoreに保存します。
2. 記事のFirestore上にuidが作成されたことをトリガーにCloud Functionsを発火させます。
3. view数をインクリメントしてview数を管理するFirestore上に書き込みます。
![flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/28e59387-4def-da2c-8b61-95f80a01ca10.png)

##1. uidをFirestoreに保存
UserのuidはfirebaseのAuthenticationの機能でかんたんに取得することができます。

```javascript
const uid = firebase.auth().currentUser.uid
```
これをuserが記事(tree)を開いてreadしたタイミングで、trees/treeId/viewers/{uid}に書き込みます。

###記事のuidsをそのまま読み込むのはだめなの？
trees/treeId/viewers/{uid}にuserのuid Dataがあるなら、下記のようにそのまま読めばview数がわかるのですが、このやり方はイケていません:frowning2:

```javascript
db.collection('trees'+treeId+'viewers').get().then(snap => {
   size = snap.size // viewersのコレクションのサイズを返す
})
```
イケてない理由は２つです。
1. コレクションを全部GETするやり方はuid(view数)が100を超えたあたりで重くなり処理に時間がかかる
2. 記事のオーナが権限上全員のuidをgetできてしまうのはセキュリティルール上弱い

ということで、Admin権限のCloud Functionだけがuidのコレクションをreadできるようにして、記事のオーナはCloud Function経由でview数をインクリメントした先だけ見れるようにします。

##2. 記事上にuidが作成されたことを契機にCloud Functionsを発火
こちらはスタンダードな使い方で、trees/{treeId}/viewers/{uid}が作成されたことをトリガーにするonCreateでイベントを発火させます。

```javascript
 export default functions.firestore
   .document('trees/{treeId}/viewers/{uid}')
    .onCreate( async (snap: any, context: any) => {
})
```

##3. view数をインクリメントしてview数を管理するFirestore上に書き込み
発火させたFunctionsの中で、view数をインクリメントします。インクリメントなので、admin.firestore.FieldValue.increment(1)するだけです。

```javascript
 export default functions.firestore
   .document('trees/{treeId}/viewers/{uid}')
    .onCreate( async (snap: any, context: any) => {
      const treeView = {
        views: admin.firestore.FieldValue.increment(1)
      }
      // tree ownerのuidを取得
      const treeDoc = await db.collection('trees').doc(context.params.treeId).get()
      const treeData: any = treeDoc.data() ? treeDoc.data() : { userId: false }
      const ownerUid = treeData.userId
      // Treeのview数の更新
      try {
        await db.collection('views/' + ownerUid + '/trees').doc(context.params.treeId).update(treeView)
      } catch (err) {
        throw err
      }
})
```
#まとめ
マインドツリーを使ってメモ書きするサービス<a href="https://qnqtree.com" target="_blank">Q&Q</a>にも、記事オーナがview数をチェックする機能を実装できました。
めでたしめでたし:relaxed:
![スクリーンショット 2021-08-03 23.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/c9475444-ae26-3379-0b59-2d3eb7e125c8.png)
AWS Marketplace とは

## 勉強前イメージ

いろいろ買えるところ・・・？Marketplaceだし
曖昧。。。。

## 調査

### AWS Marketplace とは

データベースやアプリケーションなどがインストールされた、AMIを提供しているオンラインストアです。
そのAMIを利用することで、EC2を立ち上げてから手動でインストールする必要はないです。

### Marketplace EC2でデプロイする場合

- Open Source

ソフトウェア分の費用はかかりません。
下記が例になりますが、料金の詳細がなくソフトウェアの費用は$0.00と記載されています。

![32021-07-30インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a9d57851-2411-49e0-0973-64f3bb7664ae.png)


- BYOL (Bring Your Own License)

すでに別で購入しているライセンスを導入することが出来ます。

![1インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/bff4aa7a-3fb0-7890-2a57-a6a09b0d4e01.png)

- Utility

ユーザ数、帯域幅、ホスト数等に応じた従量制の価格体系で、
フリートライアルも提供されている場合があります。

![22021-07-30インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3ac3c5ea-4546-67c9-b818-4f98fa9600f2.png)

### Marketplace の料金体系

- Free Trial

↑とかぶりますが、初期の試用期間がありその期間中は利用分が無料になります。

- Hourly

時間ごとやユーザごとなどで金額が異なる場合です。

- Annual/MultiYear

月額払いで月額費用に割引が得られる料金体系になります。

- Private Offers

交渉してカスタム金額の設定が出来ます。

### 利用方法

利用方法は普通にEC2でOSを設定するのと変わらず、以下になります。
選択したAMIによっては、インスタンスタイプが制限される場合があります。(選択できないようになっている)

- AMIの設定

![42021-07-30インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/d336326f-f468-a9e3-bede-6f5036e3d55b.png)


- 費用確認

![52021-07-30インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/46bef0d6-14eb-dadd-4637-ce7d8c6acd36.png)


- インスタンスタイプの選択

![62021-07-30インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/752593f3-0049-7573-54b1-754d2b60bcb1.png)

## 勉強後イメージ

そういえばそんな身近にMarketplaceあったのか・・・見逃してた
必要になることはなかったけどすでにインストールしてくれてある状態なら楽だよね。
Lightsailの難しい版みたいな感じする。
あれもwordpressとかnode.jsとか入るやつあったから・・・

## 参考

- [AWS Marketplaceを使って、環境セットアップをお手軽に！](https://style.potepan.com/articles/10100.html)
- [AWS Marketplace の製品を活用する #AWSSummit](https://dev.classmethod.jp/articles/aws-summit-berlin-2018-spp-marketplace/)