OmniAICreator/Qiita-1.07M huggingface dataset:
Amplifyの公式チュートリアルをTypeScript×ReduxToolkit×Chakra uiでやってみた（Todoアプリ）

今回 [こちら](https://docs.amplify.aws/start/getting-started/installation/q/integration/react "Amplify")のAmplifyの公式チュートリアルをやってみました。
公式では言語をJS、状態管理をHooks、UIキットをMaterial-uiでした。
アレンジを加えるために言語をTS、状態管理をRTK、UIキットをChakraでやってみました。

#UIの共有
![スクリーンショット 2021-05-23 8.59.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/11740804-5f70-1d37-3653-6479daaf3561.png)
![スクリーンショット 2021-05-23 9.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/b250b492-19ca-fa12-e31e-49cc5a5dc5ab.png)

とてもシンプルなTodoアプリになりしました。

#制作を通じて学んだこと
Authenticationはかなりカスタマイズ性あるなと改めて実感しました。
デフォルト？だとwithAuthenticatorでログイン機能を以下のように実装するのかなと思います。

```
import { withAuthenticator } from '@aws-amplify/ui-react'

function App() {
  return (
    <Box
      w={{ base: "90%", md: "50%" }}
      mx="auto"
      mt="50px"
      bg="gray.50"
      minH="100vh"
    >
      <Heading as="h1" textAlign="center" pt="5">
        Amplify Todo
      </Heading>
      <InputArea />
      <TodoList />
    </Box>
  );
}

export default withAuthenticator(App)
```
![スクリーンショット 2021-05-23 9.31.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/d186b9cf-cb33-679c-48b9-751639cf4184.png)

ユーザーはサインアップするにはあれこれ入力する必要があります。
ここまでユーザーに入力してもらわなくて大丈夫という時には以下のようなコンポーネントを作るだけで簡単にカスタマイズできます。ちなみに下の例では電話番号を省略しています。
他にも色々とカスタマイズできるので[公式ドキュメント](https://docs.amplify.aws/lib/auth/emailpassword/q/platform/js "Amplify")を見てみてください。

```
import {AmplifyAuthenticator, AmplifySignUp} from '@aws-amplify/ui-react';

const App = () => {
return (
     <AmplifyAuthenticator>
        <AmplifySignUp
          slot="sign-up"
          formFields={[
            { type: "username" },
            { type: "password" },
            { type: "email" }
          ]}
        />
      </AmplifyAuthenticator>

)
}
```

#苦労した点
graphql周りの型定義にかなり苦戦しました。回避策としてasを使って型アサーションで強行突破しました。
型安全性が損なわれているような実装になってしまってので、もっと堅牢な方法を見つけていきたいと思います。

#最後に
Amplify SNS Workshopも同じようにやってみたので改めて記事にします。

参考記事

https://qiita.com/too/items/fc961283dcbef3aafdeb

https://qiita.com/nagym/items/e5b9f43b11ef2309c546
TypeError (no implicit conversion of Symbol into Integer)のエラー対応

# エラー内容

```
TypeError (no implicit conversion of Symbol into Integer)
```

hashでjsonから値を取りに行ったら上記エラーが

状況

- rails
- ruby

# エラーの原因

`no implicit conversion of Symbol into Integer`は数値が来るべきところにsymbolが来ちゃっているよという意味。hashだと思って下記で指定したんだけど

```
[:items][:data][:price][:product]
```

配列だったので

```
[:items][:data][0][:price][:product]
```

としたら解決。

stripeのsubscriptionを取得しに言ったんだけどよく見たら{}じゃなくて[]だった。

https://stripe.com/docs/api/subscriptions/retrieve
GCE環境上のWordPressの丸ごとお引越し手順

# TL;DR
* Google Compute Engine（GCE）上で構築済みのWordPressサイトを別GCE環境に引越し（コピー）する
* テーマ・記事・写真・プラグインなど、全ての設定・コンテンツをコピーする
* 無料で引越しできる容量には上限がある（100 MB）
* 手元の作業環境はMac（macOS Big Sur）
* FTPクライアントソフトにCyberduckを利用する

# 余談
GCEでのWordPressサイトの構築にはGoogle Cloud Platformの「[WordPress click to deploy](https://cloud.google.com/wordpress?hl=ja)」が簡単でおすすめ！

# 大まかな手順
1. 既存WordPressサイトにプラグイン「All-in-One WP Migration」をインストール
1. サイトデータをエクスポート
1. GCE環境にFTP接続するための認証鍵を生成
1. GCEインスタンスに認証鍵を登録
1. GCE環境にFTP接続して2.でエクスポートしたデータを取得する
1. 引越し先WordPressサイトにデータをインポート

# 詳細手順
### 1. 既存WordPressサイトにプラグイン「All-in-One WP Migration」をインストール
* 管理画面 → プラグイン → 新規追加 → 「All-in-One WP Migration」で検索
* 今すぐインストール → 有効化
![スクリーンショット 2021-05-22 18.12.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324285/c6d66679-2603-0ee7-1f1c-f24206f05402.png)

### 2. サイトデータをエクスポート
* 左メニューのAll-in-One WP Migration → エクスポート
* エクスポート先でファイルを選択
* この時点では何も起こらない（もしくはダウンロードに失敗する）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324285/e303e884-4912-a360-2a95-c977ea43ee0a.png)

### 3. GCE環境にFTP接続するための認証鍵を生成
* ターミナルで以下を実行して認証鍵を生成
* 鍵の名前（KEY_NAME）およびユーザーネーム（USER_NAME、FTP接続時に使用）は適宜変更すること
* パスフレーズを聞かれるがブランクのままエンターを押して良い

```bash
ssh-keygen -t rsa -f ~/.ssh/KEY_NAME -C USER_NAME
```

### 4. GCEインスタンスに認証鍵を登録
* Google Cloud Platform → Compute Engine → メタデータ → SSH認証鍵 →（編集）→ 項目を追加
* 以下のコマンドをターミナルで実行して認証鍵情報をコピー

```bash
cat ~/.ssh/KEY_NAME.pub | pbcopy # 3.で指定した認証鍵名の最後に.pubをつける
```

* コピーした認証鍵情報をペーストして保存

### 5. GCE環境にFTP接続して2.でエクスポートしたデータを取得する
* FTPクライアントソフト「[Cyberduck](https://cyberduck.io/)」をインストール
* 「+」マークで新規接続先を追加し、以下の項目を入力する
    * 最上部の接続方式：「SFTP（SSHによる暗号化FTP）」を選択
    * ニックネーム：任意の識別しやすい名前
    * サーバー：接続先サーバーのIPアドレス
    * ユーザー名：3. で決めたユーザー名（USER_NAME）
    * SSH Private Key：3. で作成した認証鍵のパス（.pubなし）

![スクリーンショット 2021-05-22 18.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324285/f03dcaea-60f3-5257-91fa-c3b4a6e2eb28.png)

* 上記画面を閉じ、作成した接続先をダブルクリックしてFTP接続
* 「そのホストは現在システムに認識されていません」と出てきた場合は「許可」を選択
* ```/var/www/html/wp-content/ai1wm-backups```にある```*.wpress```が2. でエクスポートしたファイル
* ```*.wpress```をダブルクリックするとファイルダウンロードが始まる

### 6. 引越し先WordPressサイトにデータをインポート
* プラグイン「All-in-One WP Migration」をインストール
* 左メニューのAll-in-One WP Migration → インポート
* 「インポート元」→「ファイル」を選択 → 5. でダウンロードした```*.wpress```ファイルをインポート
* インポート開始の確認ウィンドウが出る →「開始」を選択
* インポートが完了したらブラウザを更新 → ログイン画面に戻るので、元サイトの管理者ID&パスワードでログイン
* データが正しくインポートされていることを確認する
Vitis_HLS/Vivado/Vitis(2020.2.2) で作成した API がアップデートされない

Vitis_HLS(2020.2.2) で C 合成した回路を Vitis で使用する際、一部のドライバがアップデートされなくて嵌ってしまった。
このメモはその時の解決法を書いたものです。もっといい方法があれば教えてください。

# 再現方法

「FPGA プログラミング大全第2版」にある、Patblt 回路を構成したのですが、このとき、offset を slave にするのを忘れて合成し、Vivado に取り込んでしまいました。全く気づかないまま論理合成し（これは成功）、Vitis を起動してプログラムを打ち込んでみると、XPatblt_Set_dstout 関数がないというエラーが発生しました。

ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/libsrc/patblt_v1_0/src/xpatblt.h を見ると確かにこの関数は定義されていません。xpatblt.c を見ると、やはり定義されていませんでした。

Vitis_HLS に戻って確認したところ、offset を slave にし忘れていることが判明したため、slave を指定して C 合成をやり直し、Vivado でデバイスを update して bitstream を作成、ハードウェアを export し直しました。

次に Vitis に移り、「Update Hardware Specification」を選択してハードウェア構成を取り込みました。
Clean で全ての生成ファイルをクリアしたあと、ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/　libsrc/patblt_v1_0/src/xpatblt.h を見ると、相変わらず XPatblt_Set_dstout 関数が定義されていません。

もちろん、この関数を使ったサンプルプログラムはコンパイルできません。
さて、どうするか？

# hw ツリーにヒントが

よく見ると、hw/drivers/patblt_v1_0/src/xpatblt.h に定義されているファイルには XPatblt_Set_dstout 関数が定義されており、xpatblt_hw.h を見るとレジスタのオフセットも正しそうです。

そこで、以下の項目に修正を加えることにしました:

* ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/libsrc/patblt_v1_0/src/xpatblt.h: hw/drivers/patblt_v1_0/src/xpatblt.h の XPatblt_Set_dstout をコピーする。
* ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/libsrc/patblt_v1_0/src/xpatblt.c: hw/drivers/patblt_v1_0/src/xpatblt.c の XPatblt_Set_dstout をコピーする。
* ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/libsrc/patblt_v1_0/src/xpatblt_hw.h: hw/drivers/patblt_v1_0/src/xpatblt_hw.h を丸コピーする。

# 動くのか？

旧設定と新設定ではレジスタのオフセット値が異なっており、どちらか一方が正しいことになります。ここは新設定が正しいだろうという予想のもと、修正しましたが、実機で動くのか試して見る必要がありそうです。
そこで、patblt を使用したサンプルプログラムを Z7-20 ボードで実行してみました。

結果は新設定の方が正しいことがわかりました。
たまたま Vitis のバグを踏んだのですかねえ。。。
カルマンフィルター

# カルマンフィルターについてまとめておく
このブログでは線形カルマンフィルターを解説する。

## カルマンフィルターとは何か
カルマンフィルターとは時系列データから逐次的に状態を推定する1つの手法である。1960年代のアポロ計画の際に宇宙船の位置を推定する手法として利用されたことが有名であろう。

宇宙船の位置を推定する例でいうと、宇宙船が電波を発信し、地球上の観測点で電波を観測することになる。但し、そこには2つの誤差がある。１つは観測誤差、そしてもう一つが宇宙船そのものの状態の誤差（本来はまっすぐ飛んでいるが多少の揺らぎが生じる）である。宇宙船は電波を一定間隔で発信し続け、それを地球上で受信するので、時系列のデータとなる。この時系列の観測情報を$Y_t$であらわし、状態を$\beta_t$で表すことにする。この２つの時系列データは次のように表現できる。
$$Y_t = c + \tilde \beta_t + \tilde e_t \tag{1}$$
$$ \tilde \beta_t = d + \tilde \beta_{t-1} + \tilde v_t \tag{2}$$

(1)を観測方程式、(2)を状態方程式といい、いずれも線形モデルである。~がついている変数は確率変数であり、また$\tilde e_t ～ N(0, \sigma^2_e),\tilde v_t ～ N(0, \sigma^2_v)$に従うものとしている。$c$と$d$は定数である。

ここで観測できるのは$Y_t$のみであることに注意する。(1)の観測方程式をみると、$Y_t$は状態$\tilde \beta_t$と正規分布に従う確率変数$\tilde e_t$によって決まる。そして、(2)の状態方程式を見ると$\tilde \beta_t$は1期前の状態$\tilde \beta_{t-1}$と正規分布に従う確率変数$\tilde v_t$によって決まる。すなわち、今期の状態$\tilde \beta_t$を1期前の状態$\tilde \beta_{t-1}$に状態の誤差を加えて推定し、今期の観測値$Y_t$は推定された今期の状態$\tilde \beta_t$に観測の誤差を加えたものとなっている。これは1期前の状態が今期の状態に影響し、その結果として観測値が得られていると捉えることができる。このような構造方程式をもつモデルを状態空間モデルといい、時系列の情報に基づいて、逐次的に状態を推定できることを示している。

尚、上記の構造方程式は状態空間モデルの一例であり、実際には(2)の状態方程式の$\beta_{t-1}$に係数を持たせることや、(1)観測方程式に時間変化する説明変数を組み込む等、様々な構造を持つことが可能となっている。

次回以降、このブログで扱う記述のルールを述べたのちに、具体的にカルマンフィルターの持つ意味や推定の仕方等の解説を行う。またいずれpythonを用いたカルマンフィルターの利用方法、さらには誤差をMCMCを用いて推定する方法等の解説をしていく予定である。

### 参考文献
このブログの参考文献は下記の通り
[経済・ファイナンスのための カルマンフィルター入門 2019/2/6 森平 爽一郎  (著)](https://www.amazon.co.jp/dp/425412841X/?coliid=I1000DQ4SDSBTF&colid=90DKP73K7CJT&psc=1&ref_=lv_ov_lig_dp_it)
[時系列分析と状態空間モデルの基礎: RとStanで学ぶ理論と実装 2018/2/14 馬場 真哉  (著)](https://www.amazon.co.jp/%E6%99%82%E7%B3%BB%E5%88%97%E5%88%86%E6%9E%90%E3%81%A8%E7%8A%B6%E6%85%8B%E7%A9%BA%E9%96%93%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E5%9F%BA%E7%A4%8E-R%E3%81%A8Stan%E3%81%A7%E5%AD%A6%E3%81%B6%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E9%A6%AC%E5%A0%B4-%E7%9C%9F%E5%93%89/dp/4903814874/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E6%99%82%E7%B3%BB%E5%88%97%E3%83%A2%E3%83%87%E3%83%AB&qid=1621756736&s=books&sr=1-4)
再帰関数を用いた問題解決技法（メモ化、分割統治法）

種々のアルゴリズムで出くわすことになる再帰関数と、メモ化による高速化、分割統治法への適用を、簡単な問題解決事例でまとめました。



#再帰関数
再帰関数とは、手続きの中で自分自身を呼び出す（＝再帰呼び出しを行う）関数のことです。

```Python:Fibonacci-recursive.py
# フィボナッチ数列を求める再帰関数
# 計算量：O((1+√5/2)^N)
def fibo(N):
    if N == 0:
        return 0
    elif N == 1:
        return 1
    
    return fibo(N-1) + fibo(N-2)

# 入力受取
# 求めるフィボナッチ数列の番号
digits = int(input())

# 再帰的に解く
fibo(digits)

# 入力 40
# 出力 102334155
```


#メモ化による高速化
メモ化とは、計算済みの部分問題の解をメモしておき、再帰関数の中で同じ部分問題に２度目以降出くわした際はメモから解を取得し、部分問題が計算し直されるのを防ぐ手法です。

```Python:Fibonacci-memo.py
# フィボナッチ数列を求める再帰関数メモ化
# 計算量：O(N)
def fibo(N):
    if N == 0:
        return 0
    elif N == 1:
        return 1
    
    if memo[N] != -1:
        return memo[N]
    else:
        memo[N] = fibo(N-1) + fibo(N-2)
        return memo[N]

# 入力受取
# 求めるフィボナッチ数列の番号
digits = int(input())

# メモ準備
# フィボナッチ数10000番目分までのメモを-1で初期化
memo = [-1 for number in range(0,10000)]

# メモ化で解く
fibo(digits)

# 入力 100
# 出力 354224848179261915075
```
<br>



ちなみに大きな桁数のフィボナッチ数列は単純なfor文でも解けます。
再帰関数を使えるようになるとついついfor文を侮ってしまいますが、いけませんね。

```Python:Fibonacci-for.py
# フィボナッチ数列を求めるFor文
# 計算量：O(N)
def fibo(N):
    F = []
    F.append(0)
    F.append(1)
    for i in range(2, N+1):
        F.append(F[i-1]+F[i-2])
    return F[-1]

# 入力受取
# 求めるフィボナッチ数列の番号
digits = int(input())

# for文で解く
fibo(digits)

# 入力 100
# 出力 354224848179261915075
```



#分割統治法への適用
分割統治法とは、元の問題を小さな部分問題に分解し、その部分問題の解を組み合わせることで元の問題の解を求める手法です。

```Python:SubsetSum-recursive.py
# 部分和問題を再帰関数を用いる全探索で解く
# 計算量（O(2^N))
def func(i, w, a):
    if i == 0:
        if w == 0:
            return True
        else:
            return False
        
    if func(i-1, w ,a):
        return True
    
    if func(i-1, w-a[i-1], a):
        return True
    
    return False

# 入力受取
# 整数の数、求める総和
N, W = map(int, input().split())

# 入力受取
# N個の整数
a = list(map(int, input().split()))

# 再帰的に解く
if func(N, W, a):
    print("Yes")
else:
    print("No")

# 入力
# 4 7
# 2 3 6 0

# 出力
# No
```
Nike Run ClubのデータをApiで抽出してみた

## 背景
過去の走行データを解析したくてApiを探したがNikeRunClub(以下，NRC)には公式APIはない模様．
ただ，Bearer認証等をうまく準備すれば自作APIでデータ抽出できたのでここに纏めておく．
意外だが，日本語の記事は結構古いのしか見当たらなかった．
(注釈)非公式なのでサーバに負荷をかける使い方はやめておきましょう　あくまで自分のデータを抽出するだけ

[参考]
　https://yasoob.me/posts/nike-run-club-data-visualization/
　https://gist.github.com/niw/858c1ecaef89858893681e46db63db66
[環境]
 macOS Big Sur version11.5 Beta
 MacBook 2017model

## 前準備
NRCを使っていてデータがあること．
NikeRunのWebサイトのユーザidとパスがわかること(NRCと同じアカウントが必要です）

## やり方
[スクリプトの準備]
・次のシェルスクリプトを自分のローカルにダウンロードする　(https://gist.github.com/niw/858c1ecaef89858893681e46db63db66)
※シェルの実行にはJqueryが必要です 実行時に無ければ要求されるので brew install jq でインストールしてください．

[Bearer認証トークンの準備]
・ブラウザの開発ツールを開いてから次のサイトを開いてください→https://www.nike.com/member/profile
　※開発ツールはブラウザ上部のdevelop>Show Web Inspecter から開けます
・ログインを実行してから api.nike.comのドメインとやり取りしたパケットを確認してください．
　Authorizationの箇所にトークンが記載されているのでコピーして自分のローカルに保存してください．
　※"Bearer"の文言以下をコピーしてください．
　2021年5月現在，下記の図表のトークンよりももっと長いトークンになっていますが動作します
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934349/a5228313-6767-a26b-2de0-d4e199e64c0b.png)
https://yasoob.me/images/nike.png

[スクリプトの実行]
・コピーしたトークンを引数にとって，スクリプトを実行してください．(Bearer Tokenは上で取得したトークンに置き換えること)
 `./fetch_nike_puls_all_activities.bash {Bearer token}`
　※実行権限を要求される場合は，`chmod u+x ./fetch_nike_plus_all_activities.bash`

・うまく動作すると下記の感じでjsonファイルが走行データ分だけ取得できます．
![Screen Shot 2021-05-23 at 8.36.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934349/23f4a9fe-3e9a-578b-e8f6-70237b253d59.png)

## 最後に
jsonファイルはフォーマットして使って下さい．そのままだと見にくい．．．
まだ，何もできていないのですが，ほしい情報はだいたいありそうな印象
自分の場合は，朝はタイム出ないなーとか思っていたので，そこを解析したかったのがキッカケ
また，いい感じに処理できる方法があれば纏めてみようかと思う

[わかっていないこと]
そもそもBearer認証とは．．．　https://qiita.com/h_tyokinuhata/items/ab8e0337085997be04b1
openpyxlでPermissionError例外を出しちゃう人のための別名保存マクロ(VBA)

Pythonでopenpyxl を使ったコードを書いているとよく出くわすPermissionError例外。
openpyxlで開こうとしているファイルをExcelで編集しているときにでる例外ですが、Python側でreadonly指定していても出るのが痛いところ。

要はExcelでファイルをちゃんと閉じてからスクリプトを実行すればいいんだけど、値変えたりして試行錯誤しながらコードを書いていると地味に忘れがちだし面倒くさい。

解決策としては、編集中のExcelファイルを別名保存して、その別名の方をopenpyxlで開いて試行錯誤する方法が考えられるのですが、別名で保存すると元ファイルが閉じられて保存した別名のほうが開いている状態になってしまいます。

そこで、「編集中のExcelファイルを別名保存して、別名保存前のファイルを再度開いて保存後のほうのファイルを閉じる」というマクロをVBAで書いたのでシェアします。openpyxlで別名の方を開けばPermissionError例外に悩むことなくコーディングに集中できます。

個人用マクロファイルに入れてクイックアクセスツールバーに登録して使うという使い方を想定しています。バグなど見つけた方は編集リクエストください。

``` VB:sample.bas
Option Explicit
Sub ReOpenAfterBackup()
'
' 現在編集中のファイルを同じフォルダに別名で保存した後に現在のファイルを開きなおす
' 別名は、[編集中のファイル名の拡張子の前の部分]+ suffix+拡張子。上書き。
' 現ファイルが前回保存から変更ありの場合は問答無用で上書き保存する
' ファイル名がない場合(未保存)の場合は終了
'
    Const suffix As String = "_bk"      '自由に変更してください
    Dim fso As FileSystemObject
    Dim curFileName As String           '編集中ファイル名(パスなし)
    Dim newFileName As String           '別名ァイル名(パスなし)
    Dim absCurFileName As String        '編集中ファイル名(フルパス)
    Dim absNewFileName As String        '別名ァイル名(フルパス)
    Dim saveDir As String               '保存先(編集中ファイルの場所)
    Dim baseName As String              '編集中ファイルの拡張子の前の部分
    Dim extension As String             '編集中ファイルの拡張子
    
    ' 現在開いているブックが未保存(book1など)の場合は終了
    saveDir = ActiveWorkbook.Path
    If saveDir = "" Then
        MsgBox ("ファイルを保存してから実行してください")
        Exit Sub
    End If
    
    ' 現在開いているブックのファイル名を取得して保存するファイル名を決定する
    curFileName = ActiveWorkbook.Name
    absCurFileName = saveDir & "\" & curFileName
    
    Set fso = New FileSystemObject  'レアなので失敗時処理は省略
    baseName = fso.GetBaseName(curFileName)
    extension = fso.GetExtensionName(curFileName)
    Set fso = Nothing
    
    newFileName = baseName & suffix & "." & extension
    absNewFileName = saveDir & "\" & newFileName
            
    '以下の設定については元に戻す処理を省略(終了時自動でTrueになる)
    Application.ScreenUpdating = False 'ちらつき防止
    Application.DisplayAlerts = False  '上書き保存時の警告を出さない
           
    On Error GoTo ErrorHandler
        ' 編集中のファイルを上書き保存後、別名で保存する
        Workbooks(curFileName).Save
        Workbooks(curFileName).SaveAs fileName:=absNewFileName
        
        ' 元ファイルを開いて別名ファイルを閉じる
        Workbooks.Open fileName:=absCurFileName
        Workbooks(newFileName).Close
    On Error GoTo 0
    
    Exit Sub
    
ErrorHandler:
    MsgBox ("ファイルの保存・再オープンに失敗しました")
    Exit Sub
End Sub
```
HPFメモ_現在地の緯度経度を取得

**Geolocation API**　というやつで取得できる。

よく、WEBページで　現在地取得していいすか？ってでるやつのようだ。

http://www.htmq.com/geolocation/

↓へー　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/5c028123-1890-3f95-074d-be6a030066c0.png)

↓へーーー
getCurrentPosition() …… ユーザーの現在の位置情報を一回だけ取得する
watchPosition() …… ユーザーの位置情報を定期的に監視する
clearWatch() …… watchPosition()による位置情報の監視をクリアする


//ユーザーの現在の位置情報を取得
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);

/***** ユーザーの現在の位置情報を取得 *****/
function successCallback(position) {
  var gl_text = "緯度：" + position.coords.latitude + "<br>";
    gl_text += "経度：" + position.coords.longitude + "<br>";
    gl_text += "高度：" + position.coords.altitude + "<br>";
    gl_text += "緯度・経度の誤差：" + position.coords.accuracy + "<br>";
    gl_text += "高度の誤差：" + position.coords.altitudeAccuracy + "<br>";
    gl_text += "方角：" + position.coords.heading + "<br>";
    gl_text += "速度：" + position.coords.speed + "<br>";
  document.getElementById("show_result").innerHTML = gl_text;
}


latitude …… 緯度（-180～180、単位：度）
longitude …… 経度（-90～90、単位：度）
altitude …… 高度（単位：m）
accuracy …… 緯度・経度の誤差（単位：m）
altitudeAccuracy …… 高度の誤差（単位：m）
heading …… 方角（0～360、単位：度）
speed …… 速度（単位：m/秒）
HPFメモ_CodePen

CodePen便利！

https://codepen.io/

Topicsってどっから入るんだっけ？
https://codepen.io/topics/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/a8e25412-c092-f99f-953c-6ce879fc6a47.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/40218d0e-029f-1276-c950-2715daaf23ab.png)
HPFメモ_距離を計算する

JavaScript　距離でググったらでてきた
**GeoLib**　　これ

https://www.mmpp.org/archives/1663
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/674adefd-0f02-f87b-e38b-c2098bf35125.png)
緯度・経度を２点入れると直線距離を算出してくれる。
JSDELIVRにもあるでよ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/1b396a1c-7833-b61f-fd66-a85815c5e4a1.png)

これは簡単につかえそう
HPFメモ_地図を操作する仕掛け.JS

HPFを作るにあたり、まずはWEBで地図を使う方法を探る

王道GoogleMap

2018年6月から料金体系が変わって、クレジット登録が必要、APIキー発行が必須などになったらしい。お試しに使うには面倒かも
https://uniel.jp/news/before_using_mapapi/

**Leafletという　地図ライブラリ**が良いかも
https://qiita.com/mitch0807/items/7ed4eaf6253a9b879ae7

LeafLetは、地図サービスの画像を操作するライブラリのようで、地図データはほかのサービスを利用するようなイメージのようだ
ここではMAPBoxというのをつかっているが、openstreetmapなどいろいろあるみたい。

https://www.openstreetmap.org/#map=5/35.588/134.380
↓オープンライセンスらしいので、本格的に使って不満がでるまでは、これの使い方を極めたほうがいいかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/dd2ac7ef-0fbb-e754-0c14-a19c31a821bd.png)

Leafletの実装記事
https://ops.jig-saw.com/tech-cate/leaflet_maps
https://ops.jig-saw.com/tech-cate/leaflet_maps
https://dev.classmethod.jp/articles/serverless_map_service/
↑　トップの画像に絵があるとなんか　**簡単なのかも！！って読みたくなるね**
**CodePenあった！！！**
https://codepen.io/anon/pen/ROrMzo
↓　だってさ。Leafletには、機能拡張するライブラリがいろいろあるみたい。ここでは**「Leaflet Routing Machine」**というライブラリ。ルートを表示してくるって。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/3c485f5a-4920-549f-476e-16458c39b736.png)
**↓すげぇ！それっぽい！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/2c868407-4e90-882e-77d4-0f2969a240af.png)

地図をクリックすると経度緯度を表示するライブラリ
**Leaflet Coordinates Control**
https://kita-note.com/leaflet-plugin-coordinates_control
↓こんなかんじ。　すてき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/4716addc-e3b6-a509-4d8c-91443a17e2c8.png)

つーか　Leafletについてサンプルがおおいサイトだな！
https://kita-note.com/category/programming/leaflet

とりあえず　したのやつらを使ってみるか
Leaflet　本体
Leaflet Routing Machine　　経路ライブラリ
Leaflet Coordinates Control　緯度経度表示ライブラリ

JSDELIVRにもちゃんとあるね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365273/90842991-9c4a-3f0b-eda8-d832f52ebbff.png)
Docz (Powered by Gatsby) で静的サイト構築

[🚀10 Trending projects on GitHub for web developers - 21st May 2021 - DEV Community 👩‍💻👨‍💻](https://dev.to/iainfreestone/10-trending-projects-on-github-for-web-developers-21st-may-2021-2c6h)
で紹介されていたDoczというもの。

## Docz


> Doczは、あなたのコードのための美しいインタラクティブなドキュメントを簡単に書いて公開することができます。コードを紹介するMDXファイルを作成すると、Doczがそれをライブローディング可能な本番用サイトに変換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/4db27c8d-9cc1-621d-c40f-e40eecd3e6d8.png)

### 公式
https://www.docz.site/docs/getting-started

- 特長
    - Powered by Gatsby
    - Zero config
    - Easy to customize
    - Based on MDX
    - Fully pluggable
    - TypeScript support

どうやらまた新たな静的サイトをジェネレートな何かか...と思ったが、既にVersion 2ではあり、過去記事発見。

https://qiita.com/ozaki25/items/fdf1e0b52ff1fee26514

ただ多少情報更新もありそうなので以下試した流れをメモる。


### お試し

`npx create-docz-app my-docz-app`
で、以下になります。

```md
Success! Created my-docz-app at C:\workspaces\nodejs\docz\my-docz-app
Inside that directory, you can run several commands:

  npm run dev
    Starts docz in dev mode.

  npm run build
    Builds the docz app for production.

We suggest that you begin by typing:

  cd my-docz-app
  npm run dev
```

`npm run dev` で `http://localhost:3000/` に立ち上がる。

> Note that you don't need to follow any file architecture or convention. You can just create your .mdx files and put them anywhere in your project.
> DeepL訳: なお、ファイル構成や規約に従う必要はありません。.mdxファイルを作成して、プロジェクトのどこにでも置くことができます。

本当？以下ファイルを適当においてみた。


```mdx
---
name: Hello world
route: /doc/
---

# こんにちは

Hello, I'm a mdx file!
こんにちは。MDXふぁいるです。


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/1498f0ef-4cc1-81c6-b55e-686e3a7abc73.png)

無事できあがった。



### netlify にデプロイ

https://www.docz.site/docs/deploying-your-docs

https://e99h2121-docz.netlify.app/


### MDX とは

https://zenn.dev/nbr41to/articles/e8d795b316c41d15dcef

https://mdxjs.com/


### Gatsbyと静的サイトについては

https://qiita.com/umamichi/items/9bd08a21fddc71588efc




## まとめ

ともかく簡単だったのでなにかに使えたらなあというメモでした。



### 他記事、動画

https://blog.tagbangers.co.jp/ja/2019/09/29/getting-started-docz


<iframe width="517" height="270" src="https://www.youtube.com/embed/VCvum6COleQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>





参考になればさいわいです。
棒読みちゃんをPythonから喋らせる(http連携)

#経緯
WEBカメラの映像をリアルタイム解析し、何かあったら棒読みちゃんに喋らせる、というプログラムを画策していた。その中の喋らせる部分のピンポイントな記事がPythonだと見当たらなかったので書いてみた。

#まとめ
喋らせたい内容とかをURLパラメータにした上で`requests`モジュールで棒読みちゃんのhttpサーバにGETリクエスト送るだけ。

#開発環境
- Windows 10 Home 21H1 64bit
- Python 3.9.4
- 棒読みちゃん Ver0.1.11.0 Beta21

#コード
棒読みちゃんを事前に立ち上げた上で以下を実行すると多分喋り出します。
`requests`モジュールは事前にpipとかでインストールして下さい。GETリクエスト送れればいいので`urllib`モジュールでもおそらく出来ます。
棒読みちゃんのサーバポート変えてたら適宜修正して下さい。

```Python
import requests


def speak_bouyomi(text='ゆっくりしていってね', voice=0, volume=-1, speed=-1, tone=-1):
    res = requests.get(
        'http://localhost:50080/Talk',
        params={
            'text': text,
            'voice': voice,
            'volume': volume,
            'speed': speed,
            'tone': tone})
    return res.status_code


if __name__ == "__main__":
    print(speak_bouyomi('あいうえお'))
```

#参考
- [Python, Requestsの使い方 | note.nkmk.me](https://note.nkmk.me/python-requests-usage/)
- Sample_HtmlConnection.html(棒読みちゃんに付属しているサンプルコード)
【SQL】SQLまとめ

#はじめに
SQLに関する自分の記事をまとめていきます。

#SQL

https://qiita.com/REON/items/35ddc2bf287abcb51c7e

https://qiita.com/REON/items/610ec8e41d0194c29ccc

https://qiita.com/REON/items/07508bbaa86f4ccccb14

https://qiita.com/REON/items/6d375fca3353bc4205ea

https://qiita.com/REON/items/9d2bcad003c6de78aa1a

https://qiita.com/REON/items/31cbf7728ebe89923e9c

https://qiita.com/REON/items/a075fdaf91a84fa4eb36

#おわりに
随時更新予定です。
【SQL】ORDER BY, LIMIT

#はじめに
今回は、データの並び替えとデータ取得を制限する方法についてみていきたいと思います！


#ORDER  BY
昇順に並べたい場合は「ASC」、降順に並べたい場合は「DESC」と指定します。

以下のusersのテーブルを値段が小さい順に並べたい場合を考えます。

![ScreenShot 2021-05-23 4.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/fa1153ce-58ea-ff32-9156-bf9b7481b25d.png)

```SQL
SELECT *
FROM users
ORDER BY price ASC;
```

![ScreenShot 2021-05-23 4.05.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/54174855-c5ca-40c9-9d33-884e9ddeaa80.png)


#LIMIT
最大何件のデータを取得するのかを指定することができます。
以下の表から、上から4件のみ取得したい場合を考えます。

![ScreenShot 2021-05-23 4.09.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/a6dd69bd-b25b-e4bc-2e92-b0148f49e931.png)

```SQL
SELECT *
FROM users
LIMIT 4;
```

![ScreenShot 2021-05-23 4.10.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/bf2bceea-a92b-a0d1-38de-6147cc0f4617.png)

このように、LIMITの後に取得したいデータ数を指定するだけで簡単に制限することができます。

#おわりに
今回は、ORDER BYとLIMITについて学びました。
【SQL】LIKE, NOT, NULL, AND, OR

#はじめに
SQLの基本をまとめていこうと思います！
今回は、LIKE, NOT, NULL, AND, OR演算子について、それぞれみていきます!

#LIKE
`LIKE`は、「ある文字列を含むデータ」を取得したい場合に使えます。

```SQL
SELECT * 
FROM users
WHERE language LIKE "%java%";
```

このようにクエリを記述ことによって、以下の表のように、`java`という文字列を含むレコードを選択することができます。

![ScreenShot 2021-05-22 2.15.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/c09ada59-0e67-d8e0-608c-e6c92a8de884.png)

「%」はワイルドカードと呼ばれるもので、どのような文字列であっても一致させますというLIKE演算子に用意された記号です。

以下のように、前後のみ一致させるということもできます。

```SQL
SELECT * 
FROM users
WHERE language LIKE "java%"; // languageがjavaとjavascriptのレコードを指定

SELECT * 
FROM users
WHERE language LIKE "%java"; // languageがjavaのレコードのみを指定

SELECT * 
FROM users
WHERE language LIKE "%script"; // languageがjavascriptとtypescriptのレコードを指定
```

#NOT
そのままですが、否定です。一致しないデータや、その範囲を含まないと言った指定をすることができます。

```SQL
SELECT * 
FROM users
WHERE NOT language = "java";
```

![ScreenShot 2021-05-22 2.40.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/dcbe54f8-c097-4dac-0165-85254c757e9b.png)

```SQL
SELECT * 
FROM users
WHERE NOT language LIKE "java%";
```

![ScreenShot 2021-05-22 2.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/c9fafda5-85e2-10bc-61a9-b1e8722f7d16.png)

#NULL
中身がないという状態を扱うときに使います。
以下のように、`IS NULL`とすることで、numberカラムにデータがないレコードを指定できます。

```SQL
SELECT * 
FROM users
WHERE number IS NULL;
```

![ScreenShot 2021-05-22 2.44.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/1f429875-9e6b-a850-fa0b-822cd4aca823.png)


逆に、NULL以外のデータを指定する場合は、以下のように`IS NOT NULL`とします。

```SQL
SELECT * 
FROM users
WHERE number IS NOT NULL;
```
![ScreenShot 2021-05-22 2.42.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/2bcd14e2-4ba3-9a26-4d8b-17e644485925.png)


数値や文字列の時のように、`=`を使って`= NULL`などとしないように注意が必要です。

#AND, OR
WHEREに複数の条件を付けたいときに用います。

AND例
numberが2かつ前方にjavaという文字列を含むレコードを指定しています。

```SQL
SELECT * 
FROM users
WHERE number = 2
AND language LIKE "java%";
```

![ScreenShot 2021-05-22 2.53.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/cf4d1515-4637-8a64-cf83-cbf5dc093ad5.png)

OR例
numberが2または前方にjavaという文字列を含むレコードを指定してみます。

```SQL
SELECT * 
FROM users
WHERE number = 2
OR language LIKE "java%";
```

![ScreenShot 2021-05-22 2.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/b7b0e8e7-aa3f-5a36-e77a-8648bb76bd44.png)


#おわりに
今回はLIKE, NOT, NULL, AND, ORなどを扱いました！
【SQL】SELECT, FROM, WHERE

#はじめに
いつもは主にSwiftの投稿をしている自分ですが、ふとデータベースを学びたいと思い、SQLを触ってみることにしました。
今回はSQLの基本をまとめていきたいと思います！
また、注意点としまして、今後扱うデータベースはリレーショナルデータベース(RDB)と言われるものです。ですので、今後の自分の記事で特に断りなく、DBやデータベースと表記されていましたらリレーショナルデータベース（RDB）だと考えてください。このデータベースは、表でデータを管理するような仕組みになっています。

#SQLとは
データベースを扱うための言語で、データ分析などに使われる。

#DB
DB(データベース)が何かを理解する必要があります。
DBの仕組みを簡単に説明しますと、DBは以下のような表（テーブル）でデータを管理しています。

|学籍番号|名前|出身|
|:--|:--|:--|
|1|明石家|和歌山|
|2|大西|三重|
|3|浜田|兵庫|
|4|松本|兵庫|

行（横）のことをレコード、列（縦）のことをカラムと言います。

#クエリ
クエリとは、DBに送る命令のことで、SQLはこれを書くための言語です。

![ScreenShot 2021-05-21 2.19.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/8f0042ee-d123-e1cc-8a9c-8000df204aae.png)

#クエリを書く

##SELECT
データを取得するために、「SELECT」を使います。このクエリを用いると、どのカラムのデータを取得するかを指定できます。
name列を取得するクエリを記述してみます。

```SQL
SELECT name
```

![ScreenShot 2021-05-21 2.34.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/8cc3b5b2-0c78-59da-8833-8f7ffe46c6f7.png)

##FROM
SELECTで選んだカラムがどのテーブルのものかを指定するために、「FROM」を使います。

```SQL
SELECT name
FROM users
```

![ScreenShot 2021-05-21 2.40.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/341ccdd0-43c5-937e-564e-a97d387dc59b.png)


最後に、記述をし終わったクエリにはセミコロンをつけます。（Swiftにはないから忘れそう。。。）

```SQL
SELECT name
FROM users;
```

また、SQLでは大文字と小文字の区別はないので、小文字で記述しても構いません。

##複数カラムを取得
カラムを複数取得する際に、一つ一つSELECTで指定する必要はなく、まとめて指定できます。

```SQL
SELECT name, birthplace
FROM users;
```

![ScreenShot 2021-05-21 2.48.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/80669c2e-68b4-bc3d-8768-b18964cb7b2e.png)

また、全てのカラムを取得する場合、先ほどのようにコンマで全て取得しても良いのですが、100カラム全てを取得するとなったときに対応しきれないので、省略記号「*」が用意されています。

```SQL 
SELECT *
FROM users;
```

![ScreenShot 2021-05-21 2.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/91097cd1-58f6-ea53-1765-aaab0ed861b4.png)

##WHERE
条件に合うものだけを取得したいときに使うクエリです。
「WHERE」は行（レコード）を指定します。

```SQL
SELECT *
FROM users
WHERE birthplace = "兵庫";
```

このようにすることで、birthplaceが兵庫であるレコードを取得することができます。
また、今回のようにテキストを指定するときはダブルクオーテーションマーク「"」で指定する必要があることに注意が必要です。
しかし、numberカラムのような数値を指定するときにはダブルクオーテーションマークで囲む必要はありません。

![ScreenShot 2021-05-21 2.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/33b6f131-eeb4-2784-b79c-569c1c3a2a79.png)

さらに、WHEREには比較演算子を用いることもできます。比較演算子はご存知だと思いますので、説明しませんが、以下のようにすることでnumberが2以上のレコードを取得できます。

```SQL
SELECT *
FROM users
WHERE number >= 2;
```

![ScreenShot 2021-05-21 3.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/dd14f2f3-88a9-7c4b-c453-7ea6b5ff6e8a.png)


#おわりに
今後はDB周りの投稿もしていきたいと思います！
エイシングプログラミングコンテスト2021(AtCoder Beginner Contest 202) 参戦記

# エイシングプログラミングコンテスト2021(AtCoder Beginner Contest 202) 参戦記

## [ABC202A - Three Dice](https://atcoder.jp/contests/abc202/tasks/abc202_a)

1分で突破. 書くだけ.

```python
a, b, c = map(int, input().split())

print(21 - (a + b + c))
```

## [ABC202B - 180°](https://atcoder.jp/contests/abc202/tasks/abc202_b)

3分で突破. 書くだけ.

```python
S = input()

d = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'}
print(''.join(d[c] for c in reversed(S)))
```

## [ABC202C - Made Up](https://atcoder.jp/contests/abc202/tasks/abc202_c)

11分半で突破、TLE1. Aに含まれる値 a に対して、同じ値である B のインデックスの値を求め、そのインデックスの値と同じ値が C にいくつ含まれているかを求めれば良い.

```python
from collections import Counter

N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))

x = Counter(A)
y = Counter(B[c - 1] for c in C)

result = 0
for a in x:
    if a not in y:
        continue
    result += x[a] * y[a]
print(result)
```

## [ABC202D - aab aba baa](https://atcoder.jp/contests/abc202/tasks/abc202_d)

作れる文字列の総数は重複組合せで求められる. 次の文字を 'a' としたときの組み合わせの数を求めてそれを K と比較すれば一文字づつ確定していくことができる.

```python
A, B, K = map(int, input().split())


def comb(n, k):
    if n == 0 and k == 0:
        return 1
    if n < k or k < 0:
        return 0
    a = 1
    b = 1
    for i in range(k):
        a *= n - i
        b *= k - i
    return a // b


def h(n, k):
    return comb(n + k - 1, k)


n = 0
result = ''
a, b = A, B
while a != 0 and b != 0:
    t = h(b + 1, a - 1)
    if n + t >= K:
        result += 'a'
        a -= 1
    else:
        result += 'b'
        b -= 1
        n += t
result += 'a' * a + 'b' * b
print(result)
```
$ nodebrew install-binary stableができないとき

メモです。

```
$ nodebrew install-binary stable
```
node.jsを入れたくてnodebrewをインストールしようとしていますが、エラーが出てしまった。
エラーは以下。

```
$ nodebrew install-binary stable
Fetching: https://nodejs.org/dist/v16.2.0/node-v16.2.0-darwin-x64.tar.gz
Warning: Failed to create the file 
Warning: /Users/masahito/.nodebrew/src/v16.2.0/node-v16.2.0-darwin-x64.tar.gz: 
Warning: No such file or directory
curl: (23) Failure writing output to destination

download failed: https://nodejs.org/dist/v16.2.0/node-v16.2.0-darwin-x64.tar.gz
```

このようなエラーが出たので下記のコマンドを実行。

```
$ curl -L git.io/nodebrew | perl - setup
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100 24696  100 24696    0     0  10893      0  0:00:02  0:00:02 --:--:-- 10893
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```
以下のコマンドで、~/.bash_profileに適用。

```
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```
```
$ source ~/.bash_profile
````

このあともう一度最初のコマンドを実行してみる。

```
$ nodebrew install-binary stable
Fetching: https://nodejs.org/dist/v16.2.0/node-v16.2.0-darwin-x64.tar.gz
######################################################################### 100.0%
Installed successfully
```

こんな感じ。ダウンロードできたっぽい。
pyenv globalでversionを切り替えたのに切り替わらない

## 環境
- macOS Big Sur 11.3.1
- pyenv 1.2.27

## 事象
pyenvでPython3.8.9をインストールしました。
`pyenv global 3.8.9` でpythonのversionをスイッチしても、
もともとMacにインストールされている古いPythonを見に行ってしまうという事象です。

```
% pyenv versions
  system
* 3.8.9 (set by /Users/〇〇/.pyenv/version)

% python --version
Python 2.7.16

% which python
/usr/bin/python
```

## 結論
pythonの実行Pathが差し替えられていない。
ゆえに、Pathを差し替えてあげるために以下をprofileに追加する。
私はzshを使用しているため、 `~/.zshrc` に書き込んだ。

```
eval "$(pyenv init -)"
```
ターミナルを再起動するか、`source ~/.zshrc` コマンドで設定を反映する。
pythonのバージョンとPathを確認する。

```
% which python          
/Users/〇〇/.pyenv/shims/python

% pyenv versions
  system
* 3.8.9 (set by /Users/suto/.pyenv/version)

% python -V      
Python 3.8.9
```

## 原因と補足
原因はPythonの環境変数Pathが書き変わってなかったことでした。
Pathを正しく書き換えてあげると、 `pyenv` でインストールしたversionを見に行くようです。

githubにあるpyenvのREADMEを確認してみると、Pythonの環境変数Pathに `:shims` というが入ることによって複数のversionを使い分けられるというようなことが書いてありました。
（恥ずかしながら英語はあまりできないので理解が違っているかもしれません。。。）

> pyenv works by inserting a directory of shims at the front of your PATH:
> `$(pyenv root)/shims:/usr/local/bin:/usr/bin:/bin`
> Through a process called rehashing, pyenv maintains shims in that directory to match every Python command across every installed version of Python—python, pip, and so on.

※ 以下から抜粋しました。
https://github.com/pyenv/pyenv

また、今回実行するようにしたinitコマンドですが中身は以下のようになってました。
pyenvの初期化を毎度行うようにしないと、次にターミナルを開いた時にpythonのPathが元に戻ります。
ですので `~/.zshrc` に初期化コマンドを書くことで、ターミナルを起動した時に初期化コマンドが実行され、pythonのPathを差し替えてくれるみたいです。
※ 余談ですが、 `.xxxrc` のrcは run command の意です。

```
% echo "$(pyenv init -)"
export PATH="/Users/〇〇/.pyenv/shims:${PATH}"
export PYENV_SHELL=zsh
source '/usr/local/Cellar/pyenv/1.2.27/libexec/../completions/pyenv.zsh'
command pyenv rehash 2>/dev/null
pyenv() {
  local command
  command="${1:-}"
  if [ "$#" -gt 0 ]; then
    shift
  fi

  case "$command" in
  rehash|shell)
    eval "$(pyenv "sh-$command" "$@")";;
  *)
    command pyenv "$command" "$@";;
  esac
}
```
esa.io.tar.gz プログラミング 

```esa.io.tar.gz
esa.io/d2e-master.zip
esa.io/feedback-sync-master.zip
esa.io/hello-esa-master.zip
esa.io/html-js-projs-master.zip
esa.io/inuicon-rails-master.zip
esa.io/middleman-esa-master.zip
esa.io/nyauth-master.zip
esa.io/omniauth-esa-master.zip
```
.tar.gzファイルを介して圧縮されたesa.ioパケット 記事で取り上げたソフトウェアのバージョンは何か、記事中のコードを実行するためにはどんな手順が必要かを書いておくと、自分の環境に当てはまるかどうかを後から読む人が判断しやすくなります。

https://github.com/esaio

https://ppworks.jp/
Java アプリで CPUプロファイリング

## 環境

- Vagrant 2.2.16
- Ubuntu 18.04
- OpenJDK 11
- https://github.com/jvm-profiling-tools/perf-map-agent
- https://github.com/brendangregg/FlameGraph

## Linux 環境準備

Vagrant を使って環境を作る。bento/ubuntu-18.04 を使うことにする。Linux perf tools が必要。

Vagrantfile

```bash
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-18.04"
  config.vm.synced_folder "./data", "/vagrant_data",create:true

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1536"
  end

  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get upgrade -y
    apt-get install -y build-essential cmake openjdk-11-jdk maven default-jdk linux-tools-$(uname -r) linux-tools-generic apache2-utils
  SHELL
end
```

## ツールの準備

環境変数 `FLAMEGRAPH_DIR` で perf-map-agent から FlameGraph を使えるようにする。

```bash
git clone --depth 1 https://github.com/jvm-profiling-tools/perf-map-agent.git
git clone --depth 1 https://github.com/brendangregg/FlameGraph.git

cd perf-map-agent
cmake .
make
```

プロファイリング対象になる JVM の実行時オプションに `-XX:+PreserveFramePointer` を追加する必要がある。

## perf top

CPU 時間を使っている関数、Java メソッドが見える。root ユーザーで実行する。

```bash
`perf-java-top <PID>`
```

出力例

```bash
  34.28%  [kernel]            [k] finish_task_switch
   1.26%  [kernel]            [k] _raw_spin_unlock_irqrestore
   0.44%  [kernel]            [k] do_syscall_64
   0.43%  perf-5228.map       [.] Lorg/glassfish/json/JsonGeneratorImpl;::writeEscapedString
   0.39%  perf-5228.map       [.] Lcom/ibm/ws/tcpchannel/internal/ChannelSelector;::run
   0.38%  perf-5228.map       [.] Interpreter
   0.35%  libjvm.so           [.] 0x00000000009b7238
   0.34%  perf-5228.map       [.] Lorg/apache/cxf/jaxrs/utils/JAXRSUtils$3;::run
   0.31%  perf-5228.map       [.] Lorg/jboss/weld/manager/BeanManagerImpl;::getReference
```

## Flame Graph

Flame Graph を出力する。root ユーザーで実行する。環境変数 `FLAMEGRAPH_DIR` で FlameGraph のインストールパスを指定する。デフォルトでは 15 秒のみプロファイリングを行うが、環境変数 `PERF_RECORD_SECONDS` で時間を変更可能。

```
export FLAMEGRAPH_DIR="/home/vagrant/github/FlameGraph"
./perf-java-flames <PID>
```

出力例
![スクリーンショット 2021-05-23 2.14.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376039/277848d1-6970-c117-63cb-9afa186e336b.png)
マーケティング勉強会　第一回　〜参入時期〜

#　マーケティング
##　マーケティングのプロセス
1. 外部、内部環境分析（世の動向と自社の強み）：分析手法：３C
2. セグメンテーション（市場細分化）、ターゲティング、ポジショニング：分析手法：STP分析
3. マーケティングミックス：分析手法：4P、４C
4. 継続調査

今回はマーケットインのタイミングについて理解

## プロダクトライフサイクル
マーケティングには4期からなるライフサイクルがある

- 導入期
- 成長期
- 成熟期
- 衰退期

各タイミングで導入に必要な機能・価格は変わってくる
講義の結論としては、`市場が大きくなるタイミングが一番良い参入期`

どのタイミングで成長期になるのか、分析できれば自ずとマーケットインのタイミングがわかる
その方法論として`イノベータ理論`、`キャズム理論`がある

##　イノベーター理論
新しいものがどのように伝搬していくか（普及していくか）をまとめた理論

人類を以下の5つのパターンに分けて、定義した時、`Early AdoptersからEarly Majority`へ進む上で大きな溝（キャズム）があるということをまとめた

- Innovators(革新者、革新的採用者)：上位２.５%が利用
- Early Adopters(初期採用者、初期少数採用者)：上位16%が利用
- Early Majority(前期追随者、初期少数採用者)：上位50%が利用
- Late Majority(後期追随者、後期多数採用者)：上位84%が利用
- Laggards(採用遅滞者、伝統主義者)：全人類が利用

## キャズム理論
著書「キャズム」(原題　Crossing the Chasm)の中で、「ジェフリー・ムーア」が提唱した理論

イノベータ理論での`大きな溝（キャズム）を越えるための方法論`がキャズム理論

- ボーリングレーン
- ホールプロダクト

などがある

講義の結論としては、`市場における上位16%に到達するタイミング`を見極めろとのこと

個人的な主観では市場成長は伸び率は株式に近しいものと理解

`雨が降ってからしか傘はささない`

マーケットイン：成長期に参入しシェアをとっていくのが王道
プロダクトアウト：なるべく早く参入

---
# 参考
以下は一般的なマーケティング知識をサマったもの

## マーケティングの定義
ざっくりいうとマーケティングは`売れる仕組み・利益が上がる仕組み`


```:アメリカ・マーケティング協会（AMA）の定義
マーケティングとは、消費者、顧客、パートナー、および社会全体にとって
価値のある提供物を創造、伝達、流通、交換するための活動、一連の精度、およびプロセスをいう
```

### コトラーのマーケティング論
コトラーは近代マーケティングの父であり、マーケティング理論の基礎を築いた

#### マーケティング1.0
産業革命により、大量に作り、大量に消費することから`製品管理`に重きを置いた概念
１９６０年台に`4P分析`が普及し`Product(製品)`、`Price（価格）`、`Promotion（プロモーション）`、`Place（流通）`の仕組みでマーケティングコンセプトを策定していた

T型フォードが有名で、単一車種、単一デザインのみ販売し、`良い商品を大量に作ってマス広告`を打てば成功するというもの

#### マーケティング2.0
消費者にフォーカスしたマーケティングが2.0
見直しが発生したきっかけは、オイルショックにより、消費者の買い控えがおこったこと

顧客に焦点を当てる戦略として`STPマーケティング`が編み出され4Pを確立するよりも
`Segmentation（セグメンテーション）`、`Targeting（ターゲティング）`、`Positioning（ポジショニング）`を重視するようになった

### マーケティング3.0
世界をより良い場所にすることに焦点を当てた`価値主導`のマーケティング
ソーシャルメディアの台頭により生まれた

これまで、「差別化」を重視しマーケティングをしていたが、困難になってきた。
マーケティング３.０では消費者という考えから、`生産消費者（Prosumer）`と変わった
ソーシャルメディアは参加型であり、自身がコンテンツを生み出すからである
ソーシャルメディアをコトラーは2つのカテゴリーに分類している

#### 表現型ソーシャルメディア
FacebookやTwitter、YouTube、ブログなどのメディアのこと
消費者が自分の意見や経験を公表し、他の消費者に影響を与える「クチコミ」というマーケティング手法を取ることができるようになった。
また、低コストで発言できることを利用し、テキストマイニングをし、市場の分析をするように変化した

#### 共同型ソーシャルメディア
ウィキペディアや食べログなどのメディア
参加者が自由に編集作業を行い、多数の声が反映された内容であるため、マーケターが無視できなくなり、消費者とともに製品・サービスを作っていく`共創（Co-Creation）`状態になった。

### マーケティング4.0
自己実現論を元にした概念で、個々人の`あるべき自分になりたい`という欲求を叶えることを主眼にしたマーケティング

これまで「モノ」を買っていたところから`コト（体験）`を買うことに関心が変わってきたことがマーケティング４.０のきっかけ

企業はターゲットとなる`コミュニティ`を利用するではなく、コミュニティの力になり、関係性を築くことが重要になってきている。
これは企業とコミュニティが対等の関係に変化しているということ

また、手法としても、これまでのものから`4C`や`3i`、`5A`へ変化していく
#### 4C
`Co-Creation（共創） `、`Currency（通貨） `、`Communal Activation（共同活性化）`、`Conversation（カンバセーション）`

https://www.pkmarketing.jp/articles/marketingmix

#### 3i
`brand identity（ブランド・アイデンティティ）`、`brand image（ブランド・イメージ）`、`brand integrity（ブランド・インテグリティ）`

https://www.pkmarketing.jp/articles/3imodel

#### 5A
`Aware（認知）`、`Appeal（訴求）`、`Ask（調査）`、`Act(行動）`、`Advocate（推奨）

https://www.is-assoc.co.jp/brandinglab/kotler-5a

## KSF:key success factor

主要成功要因。事業を成功させるための必要条件。

##KBF：key buying factor
購買決定要因(KBF)とは、Key Buying Factorの略で、購入対象となる製品を構成する価値や価格の中で、顧客が商品の購買を決める際に、重視する要素(Key Factor)のこと

市場の成熟度合いによって変化していく（例、飲料製品）
 初期：飲めるか
 中期：味が良い、イメージが良い
 長期：早く届く、おしゃれ

KSFとKBFの関係性のわかりやすい解説

https://globis.jp/article/5009
1ヶ月でIT初心者がオラクルマスターブロンズを取得する日記＃1

# まえがき

まず初めに、タイトルはIT初心者としていますが、そもそもIT業界での経験がなく右も左も分からないため、初心者どころか「エンジニアの卵」ですないことをご理解いただければ幸いです。

私は以前、建築やインテリアの業界で施工管理や営業などしていましたが、中々将来を思い描けず、このままでいいのかと色々と将来像を描く中で、エンジニアになることを決意した。
思いたったが吉日、すぐに退職願を提出、退職後に某プログラミングスクールで学び、現在就職活動中という状況。

業界に詳しい人に話を聞くと、ご時世も相まって未経験採用の会社が少なくなっているとのこと。
しかしなんとかエンジニアとして羽ばたくために、少しでも自分に翼を授けるために、今回オラクルマスターブロンズを取得しようという決意に至った。

IT業界の諸先輩方からすれば、もしかすると「初めにその資格？」などとのご意見をいただくかもしれません。
しかし、とにかくなんでもいいから一歩を踏み出したいとの思いから検索した結果、「オラクルマスターブロンズが良い！！」に辿り着き勉強を今日から始めるところ。

自分のお尻を叩くために、試験日を2021/6/19に決め、さらにはQiitaに記録を残すことでもはや逃げも隠れもできない状況に身を置くことに。

そしてこの記事を読んでくれた未来のエンジニアの卵に、「今のあなたと同じ状況ですよ。」が届けばいいなと思ってます。

# これから
昨日、オラクルマスターブロンズを取ることを決意して、すぐに参考書をネットで注文、本日届いたのでこの本をベースに勉強を開始したいと思う。

オラクル認定資格試験学習書
Bronze DBA Oracle Database Fundamentals

いわゆる”黒本”というらしい。
この本は資格取得の会社から公式に刊行されている本である。
そのほかネットやなども利用しながら合格に向けて走り出したいと思う。
本来であればスケジュールを立ててから勉強開始がセオリーかと思うが、自身の性格上、そんなことをしてしまうとやる気が湧かない。まずは足を踏み入れてガンガン勉強を進めていきたい。なんとなく方針が見えた段階でスケジューリングをして本番に間に合うように調整していきたい。

### では、勉強開始。


# 詳細

誰かの役に立てばと思い今回受ける試験の詳細について記載しておきます。
（※なお本記事は、2021年5月23日現在のため参考にする際にはご注意ください。）

- 試験名　　： Bronze DBA Oracle Database Fundamentals（通称：オラクルマスターブロンズ）
- 試験番号　： 1Z0-085-JPN
- 試験費用　： 29,400円（税抜）

- 参考書　　：　オラクル認定資格試験学習書（ISBN 978-4-7981-6636-0）
- 参考書価格：　3,800円（税抜）
AWS CLIでEC2のIAMRole作成方法

CLIでEC2のIAMRoleを作成する際に初心者がハマったポイントの備忘録です。
AWSの公式ドキュメント以外に記事があまり見当たらなかったので、まとめてみました。

##コンソールとCLIの違い
CLIでEC2のIAMRoleを作成するにあたって、最初は以下の手順で作成しようとしてました。
Policy作成
Roleの作成
RoleにPolicyをアタッチ

作成時にエラーが出てきて困惑。。。
>A client error (MalformedPolicyDocument) occurred when calling the CreateRole operation: Has prohibited field Resource

調べてみると、***インスタンスプロファイル***を意識しないとCLIでは作成できないっぽい
コンソールでの作成では自動的にインスタンスプロファイルが作成されるとのこと。

インスタンスプロファイルも知らなかったので、調べました。
(知らないことが多すぎる、、、)

作成するIAMRoleはEC2のRoleだよと関連づけるものがインスタンスプロファイルなのだと理解。

##CLIでIAMRole作成リベンジ
Policy作成

```
aws iam create-policy --policy-name hoge-policy --policy-document file://hoge-policy.json --describe "hoge"
```

Role&EC2の信頼関係作成

```
aws iam create-role --role-name hoge-role --assume-role-policy-document file://ec2-assume.json
```

Policyのアタッチ

```
aws iam put-role-policy --role-name hoge-role --policy-name hoge-policy --policy-document file://hoge-policy.json
```

インスタンスプロファイルの設定
(インスタンスプロファイル名とロール名が一致しないとエラーになるとの噂も)

```
aws iam create-instance-profile --instance-profile-name hoge-role
aws iam create-instance-profile --role-name hoge-role --instance-profile-name hoge-role
```

ここまでコマンドを実行すれば、EC2のIAMRoleが作成できてました！

##感想
コンソールで作成できる簡単さに感激した。
記事にして自分のやったこと見直したけど、最初のPolicy作成いるのかな？
Role作成時にPolicyも作っている気がしてきた・・・

##参考ページ
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#create-iam-role

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html

https://dev.classmethod.jp/articles/do_you_know_iaminstanceprofile/
【基本用語まとめ】「Webアプリケーション」超初心者向け（メモ）

「**Webアプリケーション**」を数日前に学び始めたばかりの超初心者です。
CodePenを使い、まずは色々なPen（ペン）【※】を探して改良してみるところからスタート。
【※】HTML、CSS、JSを編集できる画面のことを「Pen」（ペン）と呼ぶそうです。

しかしながら、基本用語そのものがよく分かっていないため、苦戦中・・・

「これ何だっけ？」と用語を調べ直すのが手間なので、そんな超初心者の自分に向けて、基本用語や参考サイトをまとめておきます。（自分用メモ）

##基本用語まとめ

|用語|説明|
|:---|:---|
|HTML|WEBページの構造や装飾などに使われるプログラム言語。<br>**見出しの設置**や**文字・画像等の配置**などを決めるのに使う。|
|CSS|HTMLと同じく、WEBページ作成に使われるプログラム言語。<br>HTMLと組み合わせて利用。CSSは、WEBページの**デザイン（スタイル）**に関する情報を決めるのに使う。|
|Javascriptライブラリ|JavaScriptベースのアプリケーションを書きやすくするために、あらかじめ<br>書かれたJavaScriptのライブラリ。例）**Vue.js**、**jQuery**|
|CSSフレームワーク|Webにおける装飾を記述するCSSのフレームワーク。<br>簡単に見栄えを良くしたり、複雑なユーザーインターフェースが一発で作成できる。例）**Bootstrap**
|Bootstrap|有名な**CSSフレームワークの１つ**。<br>デザイン性が確保されており、よく使われるフォーム、ボタン、メニューなどの部品がテンプレートとして用意されている。|



##参考サイト##

以下、今後「Webアプリケーション」を作成するにあたり、参考になりそうだと思ったサイトです。
###CodePen
▶画像付きで、初心者向けの丁寧な説明あり。
[CodePenの使い方(知らない人向け)](https://qiita.com/fumu238/items/f73274aa1a188eb15794)
▶主要機能の細かい解説が分かりやすい。
https://libra-nk.net/codepen/

###CSSフレームワーク
▶数ある中でおすすめのフレームワークと、種類ごとの特徴がまとまっている。
https://webdesign-trends.net/entry/11473
▶今後使いたいと思っているタブ機能。解説がとても丁寧。
https://bagelee.com/design/css/create_tabs_using_only_css/

###Javascriptライブラリ
▶Javascriptライブラリの種類ごとに特徴が解説されている。初心者におすすめ。
https://www.sejuku.net/blog/4559

###Webアプリケーション
▶デザインがとにかくかっこいい。おしゃれなWebアプリが作れそう。
https://creive.me/archives/37813/
▶Webアプリの種類がとにかく豊富。
https://note.com/haken_se_30manen/n/n4f379cc91f11#c0pws
Okta 초간단 사용기

![okta_usage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/f132cff0-d915-26fb-3942-b8737005e4a3.png)

# [Okta](https://www.okta.com/login/) 란
> Okta는 쉽게 말해, 접속을 위한 솔루션 입니다.
> 로그인 가능한 앱 대시보드(대문) 입니다. 

Okta에 로그인 하면 아래 그림과 같이 나에게 권한이 할당된 어플리케이션 목록을 확인할 수 있습니다.
어플리케이션 카드를 클릭하면, 아이디와 패스워드 입력 없이 로그인을 할 수 있습니다.
(거짓말 조금 보태서) 이게 전부(?)입니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/62661f03-909f-b90c-37c8-3eeb876a2942.png)

# Okta 예시
Gmail에 로그인하는 과정을 기록해 보았습니다.
Okta와 Google Workspace(구 G Suite) 사전에 연동되어져 있는 환경 입니다.
※ Okta는 문서화(스크린샷 다수)가 잘되어져 있어서 복붙 느낌으로 따라할 수 있습니다.
그래서 쉽게 연동 설정이 가능합니다. (30분 내외) 
https://saml-doc.okta.com/SAML_Docs/How-to-Enable-SAML-2.0-in-Google-Apps.html

## 일반적인 Gmail 로그인 (SP Initiated)
일반적인 Gmail 방식으로 로그인을 시도하면, Okta 사이트로 리다이렉션 시킵니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/f45b409b-7f52-d678-e52a-0a34ff84c2b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/aa118aa0-70a0-66b7-57c4-f40b4f22bf56.png)
Okta의 아이디와 비밀번호를 입력하고 로그인 버튼을 누르면, Gmail에 접속 됩니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/7f104715-7f0d-318e-913d-b9f8fdcb7450.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/d3c4f965-3b7d-836a-be4d-b8997a0730da.png)

## Okta에서 Gmail 로그인 방법 (IdP Initiated)
Okta에 로그인을 합니다. 
`GWS Mail` 카드를 클릭합니다.
진행되는 액션이 잠깐 화면에 보이고, Gmail에 접속 됩니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/a6eb1c52-85bf-ba90-2b05-6d83e4176b6e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/0ec61514-ef73-8dcd-be95-c496d92b931f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/91ed6ba0-324c-75d2-0b8e-18353553e970.png)

물론 사전에 Okta 관리자는 messi `사용자`를 GWS Groups라는 `그룹`에 추가해둔 상태입니다.
또한 Google Workspace `어플리케이션`에 GWS Groups 그룹을 추가해둔 상태입니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/257d900b-f934-78dc-8c4f-296d420e405e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/49f56011-c1bb-e375-6b73-f72b360686d3.png)


Okta의 기본 3요소인 `사용자`, `그룹`, `어플리케이션` 설정이 없었다면, Okta 로그인 시 화면은 이렇습니다.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/ff8b0a12-aa2a-d424-50df-3e246d8271bb.png)

모바일 화면도 남겨봅니다 ^^;
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/0eeabe00-669d-5a95-43d4-aede7332eb01.png)

# Okta 특징
- Okta는 완전 SaaS 제품입니다. 
- 고가용성은 지난 2년동안 99.999x% 라고 합니다. (연간 5분내 장애)
- Okta와 연동할 수 있는 어플리케이션 수는 현재 약 7100여개 입니다. 
- Okta와 연동할 어플리케이션의 기본은 클라우드 제품이라고 합니다. 온프렘과의 연동을 위한 선택은 잘못된 선택이라고 합니다.
- [한 달 무료 트라이얼](https://www.okta.com/kr/free-trial/) 가능합니다.

※ 올해 초 [Okta Korea](https://www.okta.com/kr/contact/)가 생겼습니다. 문의하면 친절히 설명해주십니다.

# 참고
- https://www.okta.com/kr/
- https://www.youtube.com/watch?v=dUSUx2dbTIw