OmniAICreator/Qiita-1.07M huggingface dataset:
LPC812MAXでPWMの測定を作てみた。(1)


x あまり正確では、ない


x mbed2リビジョン144
x リビジョンを変更できる人むけ


目的
シェフの気まぐれ
シリアルに出力する。
レジスター直読み込みで高速化した。
内部タイマーを使いusでオン時間を測る
シリアル出力


![o_con791.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/49e4abe1-b808-1de8-9bf4-1d2f82b501e6.jpeg)


テストプログラム


https://qiita.com/caa45040/items/17e50864f1052d00bedd



```c++



//ser_pwm_in_812_1


#include "mbed.h"


//         TX    RX
Serial pc(P0_4, P0_0); //812


//10の割り算 0から9999までは、正しい。
#define DIV10(n) (((n*409)+((n*154)>>8))>>12)


#define HIGH 1
DigitalIn  ECHO(P0_7);    //red


//タイマーの設定
Timer t;

unsigned long times; //測定時間
//int distance;        //長さ


//PA_5のオン時間をusで測る　今のところ引数は、無効
int pulseIn(int pin1,int pu1,int timeout1)
{

    t.reset();//タイマーの開始

    //タイムアウトの設定
    //timeout1 = 32000000;
    timeout1 = 100000;    //28ms
    //timeout1 = 1000;   //degbu

    //while(PA_5 == 0) {} //オフの間は、無限ループ

loop_s1:
    timeout1--;
    //                                     5432109876543210
    if (     (~(LPC_GPIO_PORT->PIN0))  & 0b0000000010000000     ) {
        if ( timeout1 ) {
            goto loop_s1;
        }
    }


    int sd = t.read_us();//測定開始

    //タイムアウトの設定
    //timeout1 = 32000000;
    timeout1 = 100000;     //28ms
    //timeout1 = 1000;   //degbu

    //while(PA_5 != 0) {} //オンの間は、無限ループ

loop_in1:
    timeout1--;
    //                               5432109876543210
    if (   (LPC_GPIO_PORT->PIN0) & 0b0000000010000000   ) {
        if( timeout1 ) {
            goto loop_in1;
        }
    }


    return(t.read_us()-sd);//測定終了

}//pulseIn


//メインルーチン
int main()
{

    pc.puts("STAR\r\n");
    wait_ms(200); //debug

    //タイマーの開始
    t.start();

    //無限ループ
    while(1) {

        // 超音波を受け取る
        times = pulseIn( 5, HIGH,2000000);
        //times = 1234;//debug

        if( times >= 9999 ) {
            times = 9999;
        }

        //時間の表示 num debug
        int d = times;
        char data_read[5]; //バッファーの定義
        data_read[4] = 0;
        data_read[3] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        d = DIV10(d);
        data_read[2] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        d = DIV10(d);
        data_read[1] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        data_read[0] = '0' +  DIV10(d);                  // '0'+(d/10)
        pc.puts(data_read);
        pc.putc('u');
        pc.putc('s');
        pc.putc('\r');
        pc.putc('\n');

        //1秒の待ち
        wait_ms(1000);

    }//while

}//main




```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b32188cb-09ba-08aa-0fbe-c15e6351c197.jpeg)



-29-
【SwiftUI】URLスキームを受け取る

# はじめに
TwitterのURLスキームはURLスキームの種類によって起動する画面が振り分けられます。
今回はその挙動をSwiftUIで再現してみます。

# TwitterのURLスキーム
**タイムラインタブ**
twitter://timeline

**検索タブ**
twitter://search

**メンションタブ**
twitter://mentions

**DMタブ**
twitter://messages

# URLスキームの設定
① プロジェクトを選択します
② メインターゲットを選択します
③ 「Info」を選択します
④ 「URL Type」を開きます
⑤ 「+」を押します
![スクリーンショット 2022-09-22 18.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d13f68e5-95fa-f91d-304e-c84357d3471d.png)

⑥ 「Identifier」を設定する
⑦ 「URL Schemes」を設定する
![スクリーンショット 2022-09-22 18.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4b94b210-a780-c025-ba3d-3abf75149b1f.png)

これで設定完了です。

# サンプルの実装
```swift
import SwiftUI

struct ContentView: View {
    @Binding var index: Int
    var body: some View {
        TabView(selection: $index) {
            HomeView()
                .tabItem {
                    Image(systemName: "house")
                    Text("ホーム")
                }
                .tag(0)

            SearchView()
                .tabItem {
                    Image(systemName: "magnifyingglass")
                    Text("検索")
                }
                .tag(1)
            SettingView()
                .tabItem {
                    Image(systemName: "gearshape")
                    Text("設定")
                }
                .tag(2)
        }
    }
}

struct HomeView: View {
    var body: some View {
        Text("ホーム")
    }
}

struct SearchView: View {
    var body: some View {
        Text("検索")
    }
}

struct SettingView: View {
    var body: some View {
        Text("設定")
    }
}
```
こんな感じです。
![simulator_screenshot_D2E46C53-B1E8-47AB-9C25-C8189C3846A3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/cc638778-f3b9-5667-43e9-414ac809d6a6.png)

# 振り分ける方法
想定されるURLスキームは以下の通りです。

**ホームタブ**
sample-scheme://

**ホームタブ**
sample-scheme://home

**検索タブ**
sample-scheme://search

**設定タブ**
sample-scheme://setting

```swift
import SwiftUI

@main
struct URLSchemeApp: App {
    @State var index: Int = 0
    var body: some Scene {
        WindowGroup {
            ContentView(index: $index)
                .onOpenURL { url in
                    switch url.host {
                    case "home":
                        index = 0
                    case "search":
                        index = 1
                    case "setting":
                        index = 2
                    default:
                        return
                    }
                }
        }
    }
}
```

:::note info
ポイント
`onOpenURL`でURLスキームを受け取ることができます。
:::

URLの部分抽出を使えばURLパラメータでも処理を分ける事が可能です。

https://qiita.com/SNQ-2001/items/a5f7bce8854a2c19bf72

# 完成形
URLスキームによって起動するタブが切り替えられている事が確認できました。
![Simulator Screen Recording - iPhone 12 - 2022-09-22 at 19.05.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ed36427e-1277-87b7-5099-3f0fe28b634d.gif)

# おわり
URLスキームをうまく使えばユーザーにとって使いやすいアプリになること間違いなしです！！
anyについて


# protocolを利用する上で

protocol 内にassociatedTypeやSelfがあった場合、
例：
```Swift
protocol Caffeteria {
associatedType Caffe
var name: String { get }
func place(_ cafe: Caffe )
}

class StarBucks: Caffeteria {
typealias Caffe = String
var name = "StarBucks"
func place(_ cafe: String) {  "StarBucks is at Shinjuku" } 
}

let starBucks: Caffeteria = StarBucks()
// コンパイルエラーが出る。
```
なぜなら、starBucksを生成する際に、プロトコルであるCaffeteriaを型として利用しているが、型の中のassociatedTypeが何に準拠しているかその時点でわからない。（Selfの場合も同様）。

# TypeErasure
なので、別のクラスを生成してあげて、associatedTypeが何の準拠しているのかを伝えてあげる。
```Swift
class AnyCaffeteria: Caffeteria {
let name: String
let _place : (Caffe) -> Void?

init <X: Caffeteria >(_ base: X)  where X.Caffe = Caffe {
 name = base.name
 _place = base.place
}
 func place(_ cafe: String) {
  _place(cafe)
}
}
let starBucks: AnyCaffeteria = AnyCaffeteria(StarBucks())
```

AnyCaffeteriaを生成する際に、StarBucksのクラスをbase入れてあげる。そこで初めてassociatedTypeの型がわかるようにinit時にwhereを用いている。イメージ：whereは超静的に型をみてくれている。

# Anyを用いる
上記の件に対して、anyを使うことで簡単に記述が可能になる。
```Swift
protocol Caffeteria {
  associatedtype Caffe
  var name: String { get }
  func place(_ cafe: Caffe)
}

class StarBucks: Caffeteria {
  typealias Caffe = String
  var name = "Starbucks"
  func place(_ cafe: String) { "Starbucks is at Shinjuku" }
}

let starbucks: any Caffeteria = StarBucks()
```

any Caffeteriaのように記述することで、静的に出なく動的に判断してくれる！なので、コンパイルが通る！
正確には動的Dispatchを行なってくれている。

# 注意点
Existential Containerを用いて、メモリを多く取ってしまうため、パフォーマンスがあまり良くない。

イメージ：
何人誕生日パーティーに集まるかわからないので、とりあえずとても大きいケーキを用意しておく！
TreasureDataで複数行を1行に集約する方法

TDでクエリを作成している時に、複数行を1行に集約する方法を学んだので備忘録として残しておきます。


下記のようなテーブルがあるとします。
|ID |category |
|---|:-------:|
|AAA|shoes    |
|AAA|furniture|
|AAA|apparel  |
|AAA|else     |
|BBB|shoes    |

このテーブルでIDが重複せず、categoryをスラッシュ区切りで1行にまとめたいとします。
なので上記のテーブルを以下のようにしたいです。
|ID |Category                    |
|---|:--------------------------:|
|AAA|shoes/furniture/apparel/else|
|BBB|shoes                       |

# 使用する関数
■array_join
→配列型のデータをdelimiterで分割して反映

```
array_join(array, delimiter)
```
array：ARRAY型のcolumn
delimiter：連結された配列要素を分離するために使用される文字列

■array_agg
→指定したカラムを配列型に変換
```
array_agg(column)
```

# 実際のクエリ
```SQL
SELECT
  ID
  ,array_join(array_agg(category), '/')
FROM 
  table
GROUP BY
  ID
```
array_agg で配列型に変換したデータを array_join で分割するという流れです。
ちなみにarray_aggは集約関数なので、他のカラムお反映したい場合はGROUP BYが必要です！




今後hiveでも実行できるようにprestoように作成したクエリを修正する必要があるかもなんですが、hiveではarray_joinとarray_aggは実行できないので、いい方法あれば教えていただきたいです...

### 参考
https://ohbarye.hatenablog.jp/entry/2018/02/25/095446

https://learn.microsoft.com/ja-jp/azure/databricks/sql/language-manual/functions/array_join

https://www.postgresql.jp/document/9.6/html/functions-aggregate.html
セルフブランディングで決めたい3つのこと（具体例あり）




## これを書いている人は誰か？

- みねぎしれい

エンジニア6年目 / Python Django Docker Javascript SQL / 人材関連企業の社内SE / みねぎしれい(minegishirei) / vim練習中です。

https://www.google.com/search?q=みねぎしれい

https://pm.short-tips.info/who/self_produce.md

ブランドとしては正直半人前もいいところですがそれでも誰かのためになればと思います。


## 参考情報

https://qiita.com/YumaInaura/items/76ce5f63a47e44f0193b

@YumaInaura さんの記事を参考にしました。


## セルフブランディングとは何か

そもそもセルフブランディングを定義は人や本によってまちまちなのですが、
ここでは**その人やものにまつわるイメージの全体**と定義することにします。

つまり

> 女子A「山田君って足が速いよね～」

とか

> 女子B「無色たろうさんって関数型プログラミング得意だよね～」

等々のイメージを言います。（単なる噂話とも言う）


## セルフブランディングのメリットとは何か

ここまでで世の中のほとんどの陰キャは感づいていると思いますが、**自分のアピールを失敗するとロクな噂が立ちません**

たとえば、生乾きの服を着て学校に到着した日には、

> 女子C「今日のみねぎし君なんかちょっと臭くない...?」

って言われてしまい、**「みねぎし==生乾き野郎」というイメージがついてしまうのです！**

自分の周囲の人に誤解を与えないためにセルフブランディングは有効なのです。


## セルフブランディングの効果を列挙する。

総じてアピールに関する内容ですがその効果は様々で

- 上司が自分の使い方を間違えなくなる(最重要)

- 自分がやらかしたときに真面目なツイートをしておけば予防線になる

- ITリテラシーが高くなる

- 採用担当は面接者のことを必ずGoogle検索するのでアピールの場になる

- 自己紹介が楽になる

- 新しいサービスの設定に迷いがなくなる

- ブログが栄える

等々嬉しいこといっぱいです。


## セルフブランドを確立するために必要な一つのこと

セルフブランディングを鍛えるために最も必要なことは「第三者から見えるものを統一すること」が大事です。
これは何となくイメージできる内容だと思いますが、同じ噂が流れたらその噂の信憑性は高くなりますよね。

**なので自分のブランドを確立するためには、自分の身の回りのありとあらゆるものを統一して自分のイメージに一貫性を持たせましょう！**


## セルフブランディングを確立するために統一したもの

統一する内容は以下の通りです。

- SNSのアイコン、プロフィール、ツイート内容、好きな色

- 携帯のTOP画像、LINEのアイコン、名前

- 会社携帯のTOP画像、プロフィール画像、URL、

特にSNSは

- Github

- Twitter

- Line

- Qiita

- PUBGのアカウント

などなど自分が使っているSNS全てを統一しました。


## 実際に統一したもの

### アイコン


<img src="https://github.com/kawadasatoshi/minegishirei/blob/main/img/beaver.png?raw=true">

<img src="https://github.com/kawadasatoshi/minegishirei/blob/main/img/beaver_picture.png?raw=true">



### カラー:エメラルドグリーン

<img src="https://img07.shop-pro.jp/PA01374/641/product/118087795.jpg?cmsp_timestamp=20170613005309">

### Profile文の一言

エンジニア6年目 / Python Django Docker Javascript SQL / 人材関連企業の社内SE / みねぎしれい(minegishirei) / vim練習中です。

### そのほか色々

## まずはSNSを本名に変えるところから

ここまでやったことはそこまで難しくはないことですが、それでも億劫な人はSNSの名前を本名に変えるだけでもいいでしょう。


## 現在の活動:検索結果をコントロールする

https://www.google.com/search?q=みねぎしれい

個人のブログを持っている人は自分の検索結果をコントロールしたくなると思います。

自分の場合は今のところまだまだで自分の名前で検索すると

- みねぎしれい (@se_maintain) · Twitter

- みねぎしれい (@rei_minegishi) • Instagram photos and videos

- 礼峰岸(みねぎしれい) - Facebook

- みねぎしれい kawadasatoshi - GitHub

と一部しらない人が出てきてしまいます。（実は同姓同名がいる）

これだと「同姓同名のだれかが炎上した場合に自分も巻き添えをくらってしまう」というリスクがあり得ます。

現在はこれを改善するべくSEO対策中です。


## 備考

title:セルフブランディングを確立するために具体的に決めたこと
SlackとGCP連携するときに3秒以内にレスポンスが帰らないとTimeoutする問題の回避策

# はじめに

日頃は描画周りでShader書いたりサウンドプログラム書いたり敵のAI作ったり
マルチプレイのネットワーク基盤整えたりしているUnityエンジニアのCovaです.

今回は業務中にSlackとクラウド環境で色々処理を行わせたい時に重い処理を行うと
強制的にSlack側でタイムアウトになる問題に遭遇したのでその回避方法を掲載しておきます

# TL;DR
Slack → CloudFunction と連携して動かす時に重い処理(DB操作や非同期処理など) をするときは重い処理を `Cloud Pub/Sub` 経由で `別のCloudFunction` を発火させてそちらで対応しよう
 

# 経緯
業務で Slack とCloudFunction を連携して SlackのBOTメンションや スラッシュコマンドをトリガーに色々処理をサーバレスな仕組みで構築していたところ、このようなエラーに遭遇しました.
![timeout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65257/fd6e3595-410e-b826-5dc4-9152b02934e3.png)

タイムアウトエラーと思いきや、実はCloudFunction側で行なっていた重たい処理(DB操作など) は裏で成功しているという挙動をしていて調べたところ、公式で「レスポンスは3000ms 以内に200を返せ」とのお達しでした.
https://api.slack.com/interactivity/shortcuts/using#shortcut_response

さすがに業務で使うコマンドが毎回TimeOut の表示が出ると、ユーザー(メンバー)側から絶対に毎回問い合わせが来るためなんとかしようと思いました.


# 解決にいたるまで
## 事前調査
https://zenn.dev/jcc/articles/c74fee5220a27d

こちらの記事にて試行錯誤の経緯が紹介されていましたが `Python + Slack (+ CloudFunction )` ならSlack.BOLTのLazy Listener を使えば遅延実行ができて解決するとのことでしたが、今回は「SlackCommand 」なども使っている都合上 Slack.BOLT は使えませんでした。


## 公式からのサポート
Twitter で ~~愚痴った~~ 悩みをツイートしたところ、なんと公式のSDK開発者の方からリプライを頂けました.

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">はじめまして！（急にすみません）3 秒以上かかる処理は、Bolt の lazy listener がやっているように非同期実行に逃すしかないんですよね。。Google Cloud であれば Cloud Run の always-on などを検討されるとよいかもしれません。お役に立てば幸いです！ <a href="https://t.co/4vpoFuRboY">https://t.co/4vpoFuRboY</a> <a href="https://twitter.com/hashtag/SlackDevJP?src=hash&amp;ref_src=twsrc%5Etfw">#SlackDevJP</a></p>&mdash; Kazuhiro Sera (瀬良) (@seratch_ja) <a href="https://twitter.com/seratch_ja/status/1572514535805972482?ref_src=twsrc%5Etfw">September 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

なるほど Cloud Run か... ってこれコンテナ起動だからサーバレスサービスじゃダメじゃん!

## 公式からのサポートその2

ということで再度質問したところ、従来のこのような構成から
![flow_normal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65257/a0eff1c7-a416-becd-f07a-605dcb5c771b.png)

以下のようなPub/Sub を用いて重い処理を別関数で実行させれば問題ないとのことでしたので実際に作ってみました
![flow_heavy_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65257/024f7f93-ff3f-0eb2-ee9d-8003a4b3858b.png)


# 実装について
特段難しいことは行っておらず、公式のサンプルを組み込めば実装可能です

Pub/Sub について
https://cloud.google.com/pubsub/docs/publish-receive-messages-client-library?hl=ja

## 落とし穴
- 当たり前ですが、1つ目のCloudFunctionで publish をできるようにするために `Pub/Sub 管理者` の権限をサービスアカウントに付与しないと Permission Denied で実行できません(1敗)
- Subscribe する側の引数の形式はSlackのSlackCommand受取とは異なるので確認しないと引数エラーになります (1敗)
```python
# EndPoint for Slack Command
def slack_command_endpoint(request: flask.Request):
...


# EndPoint for  Subscribe
def subscribe_endpoint(event, context):
...
```


# 結果

ちゃんと1つ目のCloudFunction 経由で1つ目のBOTメッセージが,
重い処理が実行されたあとに2つ目のBOTメッセージが返ってきてTimeOut は表示されませんでした.
![bot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65257/ddece1b8-8002-d148-e59c-9465947ee52e.png)


ということでSlack (BOT Mention / SlashCommand) とCloudFunction で連携するときは「処理が3000msで終わるかどうか」で構成が変わるので注意しましょう
Java: PDFに画像透かしを追加する

PDFは製品説明、会社契約などの重要な内容を保存するのによく使われています。文書の著作権を保護し、他人が勝手に修正しないようにしたい場合や、文書の権威性を高めたい場合は、透かしを追加することができます。そのため、PDFに画像透かしを追加するのも非常に実用的な機能です。[Free Spire.PDF for Java](https://jp.e-iceblue.com/introduce/free-spire-pdf-for-java.html)は、この機能を簡単に実装するのに役立ちます。以下は具体的な操作手順です。

## Spire.PDF.Jarのインストール
方法1：
mavenを使用している場合は、次のコードをプロジェクトのpom.xmlファイルに追加することで、JARファイルをアプリケーションにインポートできます。
```
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf.free</artifactId>
        <version>5.1.0</version>
    </dependency>
</dependencies>


```

方法2：
mavenを使用していない場合は、[このリンク](https://jp.e-iceblue.com/download/free-spire-pdf-for-java.html)からFree Spire.PDF for Javaをダウンロードできます。ダウンロードが完了したら、ダウンロードパッケージを解凍します。次にIDEAで新しいプロジェクトを作成し、「File」、「Project Structure」、「Modules」、「Dependencies」を順にクリックし、右側の緑の「+」の下の最初のオプション「JARs or Directories」をクリックして、前に解凍したファイルを見つけ、その中のlibフォルダの下にあるSpire.Pdf.jarファイルをプロジェクトにインポートします。

## PDFに画像透かしを追加する
次に具体的な操作を示します
* PdfDocumentオブジェクトを作成し、PdfDocument.loadFromFile()メソッドを使用してサンプルPDFをロードします。
* PdfDocument.getPages()メソッドを使用して特定のページを取得します。
* Pdfpage.setBackgroundImage()メソッドを使用して、画像を背景画像として設定します。
* Pdfpage.setBackgroundRegion()メソッドを使用して画像の位置とサイズを設定します。
* PdfDocument.saveToFile()メソッドを使用して、結果文書を保存します。

```
import com.spire.pdf.*;
import java.awt.geom.Rectangle2D;

public class watermark {

    public static void main(String[] args) {

        //PdfDocumentオブジェクトを作成し、PDF文書をロードする
        PdfDocument doc = new PdfDocument();
        doc.loadFromFile("sample.pdf");
        
        //最初のページを取得する
        PdfPageBase page = doc.getPages().get(0);  

        //画像を背景画像として設定
        page.setBackgroundImage("image.png");

        //画像の位置とサイズを設定する
        Rectangle2D.Float rect = new Rectangle2D.Float();
        rect.setRect(220, 300, 150, 150);
        page.setBackgroundRegion(rect);

        //結果文書を保存する
        doc.saveToFile("imageWaterMark.pdf");
        doc.close();

    }
}

```
![pdf水印2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/396d774e-2b9d-2aec-5609-6e7585f299c5.png)
【AWS】ストレージまとめ(インスタンスストア、EBS、S3、EFS)

# はじめに
AWSについて調べていた際にストレージにさまざまな種類があることは理解したが、
それぞれの特徴やメリデメが混同しがちであったためまとめてみた。

# ストレージ各種概要
EBS、S3、EFSはそれぞれ以下の言葉の略
EBS : **Elastic Block Store**
S3 : **Sinple Storage Service**
EFS: **Elastic File System**

それぞれの大まかな仕様と比較は以下の通り
||インスタンスストア|EBS|S3|EFS|
|-|-|-|-|-|
|ストレージ種類|ブロック|ブロック|オブジェクト|ファイル
|ストレージ最大サイズ|60TB※１|16TB|制限なし※２|制限なし※３|
|スピード|最も速い|速い|遅い|普通|
|料金|EC2に内包|普通|安い|最も高い|

※１ インスタンスタイプによってサイズは異なる
※２ 1ファイル5TBまで
※３ 1ファイル47.9TBまで

## インスタンスストア
EC2の一時的なデータ(バッファ、キャッシュ、スクラッチデータなど)を
保持するためのストレージ。
EC2インスタンスに物理的にアタッチされている。
このストレージに保存したデータはインスタンスの停止や終了などによって削除される。

### メリット
・高スループット
・低レイテンシー
・料金はEC2インスタンスに含まれているため利用に別途料金が発生しない

### デメリット
・データの長期保存は不可
・スナップショット取得もできない

## EBS
EC2インスタンスにアタッチして使用するブロックレベルのストレージ
OSやアプリケーション、データの置き場所など様々な用途で使用される。
容量は1GB単位で指定でき、最大容量は16TB。

### メリット
・データの長期保存が可能。
・EBS内のデータはAZ内で複数のHWにレプリケートされているため更なるRAID構成は不要
・Snapshotでバックアップ取得可能。

### デメリット
・1つのEBSを複数のEC2インスタンスで共有することはできない。
・ネットワーク接続型ストレージのため帯域に注意が必要

## S3
暗号化によるデータ保護が可能なオブジェクトストレージ
静的Webサイトをホスティングすることもできる。

### メリット
・高い耐久性(99.999999999%)
・とにかく安い(1GBあたり月額3円)

### デメリット
・EBSよりも読み書きが遅い

## EFS
複数のEC2インスタンスからNFSを使って
ネットワーク経由でアクセスできるようになるファイルシステム

### メリット
・フルマネージドであり管理が楽
・複数EC2でファイル共有を行う場合他ストレージを圧倒

### デメリット
・CIFS/SMBはサポート対象外
・コストは高め


# 補足
〜AWSのブロックストレージ、オブジェクトストレージ、ファイルストレージの違い〜
・ブロックストレージ
　→ データを単一または複数のディスクにブロックで格納される
　→ インスタンスにローカルでアタッチされる。

・オブジェクトストレージ
　→ データはフラットな空間にオブジェクトとして格納されキーで識別
　→ GETとPUTでAPIにアクセスするストレージ

・ファイルストレージ
　→ データはディレクトリ階層にファイルとして格納
　→ ネットワーク越しにアクセスするストレージ


# 参考資料
詳しく知りたい場合は公式のサービス別資料を見るのがおすすめ
[AWSサービス別資料](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)
PostgreSQLでハイフン入り数字(string型)をソートする

## はじめに

表題のことを実現するためにちょっと調べたりしたのでメモ。

## 前提

例えば、以下のようなデータがあるとする。

```sql
SELECT task_id FROM tasks;

| task_id |
|---------|
| 1-1     |
| 1-2     |
| 1-10    |
| 1-20    |
| 2-1     |
```

単純に`task_id`に対して`ORDER BY`をかけると、以下のような並びになってしまう。

```sql
SELECT task_id FROM tasks ORDER BY task_id DESC;

| task_id |
|---------|
| 2-1     |
| 1-20    |
| 1-2     |
| 1-10    |
| 1-1     |

```

子番号のソートがいけてない :cry: 


## 解決策

実現したいことは **「親番号の降順 と 子番号の昇順 で取得したい」** なので、整理すると以下の2ステップで実現できそう。

1. 親番号と子番号を取得する
2. それぞれを降順と昇順で並べる

### 1.親番号と子番号を取得する

ハイフンを起点にその前と後ろを取得すれば実現できそうということでちょっと調べてみる。
結果、文字列の分割は`substr`、ハイフン位置の特定は`strpos`が使えそう。

```sql
substr('対象の文字列', '開始位置', '抽出する文字数') -- 第3引数は省略可。省略した場合は開始位置から一番最後までの文字列を取得する。
strpos('対象の文字列', '検索する文字列')
```

親番号と子番号を取得してみる。

```sql
SELECT 
  task_id 
  substr(task_id, 1, strpos(task_id, '-') - 1) -- 親番号(1文字目〜ハイフンの1つ前)の取得
  substr(task_id, strpos(task_id, '-') + 1) -- 子番号(ハイフンの1つ後〜最後まで)の取得
FROM tasks
```

取得できた :clap: 

### 2.それぞれを降順と昇順で並べる

文字列のままではソートできないので、`::integer`でキャスト(`CAST AS`でも可)してから`ORDER BY`で並び替える。

```sql
SELECT task_id 
FROM tasks
ORDER BY
  substr(task_id, 1, strpos(task_id, '-') - 1)::integer DESC, -- 親番号を降順
  substr(task_id, strpos(task_id, '-') + 1)::integer; -- 子番号を昇順(ASCは省略可)

| task_id |
|---------|
| 2-1     |
| 1-20    |
| 1-10    |
| 1-2     |
| 1-1     |

```

無事並べ替えできた :clap:

## その他

### substr()の第2引数の開始位置について

プログラムとは異なり、1文字目は`1`になる。
仮に0を指定すると空文字が取得できてしまい、意図した文字を抽出できない。
fishのアンインストール

# あとで気づいた

いや、これでした

```
sudo apt remove fish
```

以下、手動でやったときの手順そのまま載せておきます

# 手動削除したときの手順

参考文献を見てfishを削除しました。
ubuntu18.04(wsl)
参考文献は自分の環境とはファイル構成が違ったので、そちらを参考に、自分の環境上のfish関連のファイルを削除しました

- /usr/local/etc/fish ない
- /usr/local/share/man/man1/fish*.1 ない
- /usr/local/bin/fish ない (/usr/bin/fish, fish_indent, fish_key_readerがある)


```sh
$ rm -Rf /usr/local/share/fish ~/.config/fish
$ rm /usr/bin/fish*
rm: remove write-protected regular file '/usr/bin/fish'? y
rm: remove write-protected regular file '/usr/bin/fish_indent'? y
rm: remove write-protected regular file '/usr/bin/fish_key_reader'? y

$ sudo vi /etc/shells
#/usr/bin/fishを削除
```

# 参考

https://natsukium.github.io/fish-docs-jp/faq/uninstall.html

https://zenn.dev/datchlive/articles/081a8529aa0395
【初個人開発】K P T管理アプリ「Animal KPT」を作りました。


# はじめに
こんにちは [@Taiga_aniK](https://twitter.com/home)と申します。

みなさんKPTはされたことはありますか。
KPT(ケプト)　:Keep(できた/継続すること)　Problem(改善するべき問題点)　Try(挑戦したいこと)の3要素を掘り下げ、学習や仕事を改善できるアクションを導き出すツールです。

Animal　KPT では、達成度を色で別け、「振り返り」をより確実にします。ツイッターと一緒に使えます。

【Twitter】
https://twitter.com/Taiga_aniK
【今回作ったアプリ】
https://obscure-chamber-30165.herokuapp.com/tops/index
【GitHub】
https://github.com/tai9174/animal_kpt

# 使用環境

•	 Ruby 3.0.1
•	Rails 6.0.3

# アプリの主な機能
### トップ画面
トップ画面のホワイトタイガーは丹精を込めて描きました。
Animal KPTという名前は、デザインに動物を取り入れたいのと響きの良さで決めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/5dc227c2-ac87-9343-f156-762eeca3b3fe.png)

### KPT一覧機能
新規登録、またはログインをすると以下の画面になります。
KPTの「Keep」,「Problem」、「Try」の達成度はテキストの色
（達成度：達成⇨<font color="SteelBlue">青</font>　、少し達成⇨<font color="Khaki">黄</font>　未達成⇨<font color="LightCoral">赤</font>）
によって分かれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/d7e96f5b-7908-d3c1-65a0-f6ae3961b70e.png)

### カレンダー機能
KPT一覧の下にProblemの達成度がカレンダーに表示されます。表示された達成度を押すと詳細画面に飛び、内容を確認できます。
![カレンダー機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/276ca4fc-42ce-53bc-ca10-aab99669d2cf.gif)

### New KPT機能
New KPTのボタンから新しいKPTを書けます。文字を打つと、残り文字数が表示されます。
![New KPT機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/bcc8fddb-e2e5-72e6-566c-1db15f6a8a80.gif)

### コピー機能
New KPT画面で「登録する」ボタンを押すと詳細画面になります。
詳細画面には、テキストをコピーするボタンがあります。
コピーボタンでテキストをコピーして、ツイッターに貼ることもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/fbd7cebe-2189-e7bf-16d8-588d1c16faac.png)

### お気に入り一覧機能
KPTを作成する際にお気に入りにチャックをするとお気に一覧から確認できます。
見返したいKPTをお気に入り登録すると便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/02995145-b665-a3ce-58b8-9cc7410d25b7.png)

 ### メンバーに加わる　外れる機能
チームのアイコンを押すとチーム一覧に飛びます。チーム一覧の「チームに加わる・外れる」のボタンからチームに加わったり、外れたりすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/23463f34-2ee5-0a9d-0017-d02bfbcc6347.png)

### 新チーム機能
新チームボタンから新しいチームを作ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/aaf579b2-ef33-e17f-5bb7-c00eaa606f09.png)

### チームKPT機能
チームに参加しているメンバーのKPT一覧を見ることができます。
過去一週間分見ることができます

![みんなの KPT機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683204/7893ddeb-a698-ac37-3a2d-6f5024ef7eec.gif)

# 今後挑戦したこと
Twitter API：ツイッターに自動で呟ける機能

# 終わりに

最後まで、見てくださりありがとうございます。
まだまだ、改善点がたくさんあるので、さらに使いやすいアプリにブラッシュアップしていきます。
【GAS】Googleカレンダーからメンバーの1on1実施数を取得

# 経緯
チーム内で1on1をメンバーに対して行っているのですが、他のチームのマネジャー・リーダークラスのメンバーも1on1を実施していてその実施数を毎週報告することが私の役目になっています。
これまではgoogleカレンダーからその実施数を1つ1つ目視で数えていました。
とても非効率！！なのでGASを使用して集計できるようにしました。

この手法は1on1に限らず別のイベントの集計でも使えますので頭の片隅に入れておくと幸せになれるかもしれません。

# 下準備
・集計したいユーザーのカレンダーをあらかじめGoogleカレンダーの設定から追加しておく
・1on1実施しているメンバーにはカレンダーにいれるときは「1on1」固定の文言を入れてもらう

# GASのコード

各メンバーのカレンダーのイベントを取得するためにまずCalendarApp.getCalendarByIdでカレンダー情報を取得し、開始日と終了日を指定してgetEvents()でイベントを取得。
そのイベントの中で1on1と一致するイベントがあれば集計。重複排除の処理も入れる。
下記がその実施コードになります。

```js
function get1on1EventNum() {
  // 1on1実施メンバーのアクセス可能なカレンダーのIDを指定して、Googleカレンダーを取得する
  let menber1Calendar = CalendarApp.getCalendarById('menber1@gmail.com');
  let menber2Calendar = CalendarApp.getCalendarById('menber2@gmail.com');
  let menber3Calendar = CalendarApp.getCalendarById('menber3@gmail.com');
  let menber4Calendar = CalendarApp.getCalendarById('menber4@gmail.com');
  let menber5Calendar = CalendarApp.getCalendarById('menber5@gmail.com');

  // 開始日と終了日を定義
  let startDate = new Date();
  let endDate = new Date();
  startDate.setDate(endDate.getDate() - 7);

  // 各メンバーの開始日～終了日に存在するGoogleカレンダーのイベントを取得する
  let menber1Event = menber1Calendar.getEvents(startDate, endDate);
  let menber2Event = menber2Calendar.getEvents(startDate, endDate);
  let menber3Event = menber3Calendar.getEvents(startDate, endDate);
  let menber4Event = menber4Calendar.getEvents(startDate, endDate);
  let menber5Event = menber5Calendar.getEvents(startDate, endDate);

  const menmberEvents = [menber1Event, menber2Event, menber3Event, menber4Event, menber5Event];
  const events = [];

  //forループの処理で取得したイベントの件名をログ出力する
  var count = 0;
  for (let t = 0 ; t < menmberEvents.length ; t++) {
    for(let i = 0 ; i < menmberEvents[t].length ; i++ ){
      // 1on1という文字列が一致したらカウント
      var title = menmberEvents[t][i].getTitle();
      if (title.match("1on1")) {
        if (!events.includes(title)) {
          count += 1;
          events.push(title);
        }
      }
    }
  }
  // 1on1実施数を最後に出力
  console.log(count);
}

```


# 実施結果
今週は6件実施されていたみたいでした。
![スクリーンショット 2022-09-22 17.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/a8c15457-f2f8-7458-21c8-ad0b8c8b5ca8.png)
【競プロ典型90問】010 Score Sum Queries をわかりやすく解説したい【Python】

# この問題から得られる学び
* 何度も入力データを初めから見る処理になりそうなときは前処理を考える
* l番目からr番目みたいにある区間の和を求めるなら累積和の処理がおすすめかも

# 010 Score Sum Queries
（問題ページはこちら >>> [010 - Score Sum Queries（★2）](https://atcoder.jp/contests/typical90/tasks/typical90_j "010 - Score Sum Queries（★2）"))
（公式解説はこちら >>> [010 - 公式解説](https://twitter.com/e869120/status/1380652465834532865 "解説ツイート"))
>ABC 大学には N 人の一年生が在籍しています。クラスは 2 つあり、学籍番号 i 番の生徒のクラスは Ci組です。今日は期末試験が返却され、学籍番号 i 番の生徒の点数は Pi点でした。以下の形式の質問が Q 個与えられます。j=1,2,…,Q それぞれについて答えてください。
[query = lからr番までの1組の点数合計, 2組の点数合計を出力せよ] (一部表現変更)

# 環境
Python(3.8.2), PyPy3(7.3.0)
どちらでも動きます

# どう考える？
* 1クエリごとに点数データを初めから見直すのは時間かかりそう
`N<=10^6, Q<=10^6, O(N*Q) <= 10^12`
* TLEになりそうなときは前処理ができないかを考えてみる
* i番目の入力を読み込む毎に, 1組/2組のi番目までの合計点数を出せないかな?

# 方針
```python:solution.py
#lからr番までの合計点数 = [1~r番までの合計点数 - 1~l-1番までの合計点数]
|--------| |-------------------|----------|
1----(l-1) l-------------------r----------N
#図示すればこんな感じ, 2番目の区間出すためには, 1+2番目の区間 - 1番目の区間でできる
```

# ACコード
```python:main.py
N = int(input())
sum_array = []  # この配列に学籍番号i番目までの1組の点数合計, 2組の点数合計をappendしていく
c1_sum = 0
c2_sum = 0
for _ in range(N):
    c, score = map(int, input().split())
    if c == 1:
        c1_sum += score
    else:
        c2_sum += score
    sum_array.append([c1_sum, c2_sum])

Q = int(input())
for _ in range(Q):
    l, r = map(int, input().split())
    # 下端の処理をするとき, 1番目からn番目の合計みたいに引き算しなくていい場合を考慮
    if l == 1:
        c1_l = 0
        c2_l = 0
    else:
        c1_l = sum_array[l-2][0]    # 1~l-1番まで(下端)の1組の合計点数
        c2_l = sum_array[l-2][1]    # 1~l-1番までの2組の合計点数
    c1_r = sum_array[r-1][0]        # 1~r番まで(上端)の1組の合計点数
    c2_r = sum_array[r-1][1]        # 1~r番までの2組の合計点数
                                    # 添字が0始まりであることに注意

    ans_c1 = c1_r - c1_l
    ans_c2 = c2_r - c2_l
    print(ans_c1, ans_c2)
```
# 終わりに
可能な限りわかりやすくしたかったので冗長なコードになっています。また、自分用のメモとして記事を作成しましたので、何かしらのミスがあった場合にはスルーしていただくか、お手柔らかにご指摘していただけると嬉しいです。
Xcode14.0でiOS15.7がインストールされた端末の実機デバッグができない！

`/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/` にiOS15.7に対応するサポートファイルがあれば動くのですが、今のところ（2022-09-22現在)そんなものは存在しないようです。

https://stackoverflow.com/questions/73721778/looking-for-ios-15-7-support-files-for-xcode14

XCode14の[リリースノート](https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes)を読んでみると、Known Issues欄の最後にこのような記述が。

> ・Xcode 14 cannot be used with iOS 15.7 for development. (99847608)
> 　Workaround: Use Xcode 13.4.1 with iOS 15.7.

というわけで大人しくXcode13.4.1を使いましょう。


2022-09-22 17:45追記

Xcode 14.0.1[リリースノート](https://developer.apple.com/documentation/xcode-release-notes/xcode-14_0_1-release-notes)で対応するようです。

> Resolved Issues
> Fixed: Xcode 14 cannot be used with devices running iOS 15.7. (99847608)
EloquentのCollectionをCSVファイルにする

# DBから取得したEloquentのCollectionをCSVファイルにしたい！

一応コードとしては掛けたのですが、もっといいCollectionの機能がありそうなので助言ありましたらお願いします…。

やり方としては各Eloquentをarrayにしてkeyをarray_valuesで配列にして、implodeで結合してます。
最後にjoinで改行でくっつけています。
注意点としては最後の `->join("\n")` ですが、`->join('\n')` とシングルクォーテーションだと改行コードとして認識されないので必ずダブルクォーテーションにする必要があります。

```php
$collection_string = $collection->map(function ($item, $key) {
    return implode(',' ,array_values($item->toArray()));
})->join("\n");

Storage::disk('example-backet')->put('hoge.csv', $collection_string);
```
【Google Cloud】資格取得レポート: Professional Cloud Architect

# 資格取得レポート: Professional Cloud Architect
2022年9月、 Professional Cloud Architect の遠隔監視オンライン試験を受験し、取得いたしました。
Google Cloudに触れてから約4か月、Google Cloud関連資格2つ目の受験となりました。
資格の勉強方法についてまとめます。
オンライン試験の準備、当日の流れなどについては、Associate Cloud Engineer 受験時と同様でしたので、前回のレポートをご参照いただければ幸いです。

https://qiita.com/ha_shio/items/2527930017e6538de16e

以下のような方へ、少しでも参考になれば幸いです。
・Professional Cloud Architect の取得を考えている方

【__注意__】
本記事は2022/09の情報をもとに、資格の勉強方法などを記載しています。
これらの情報は更新されている可能性がございますので、実際に受験する際は、必ず公式ページなどから最新の情報をご確認ください。

## 経緯
目標として、Google Cloudのプロフェッショナル認定資格をいくつか取得したいと考えております。
初めてのGoogle Cloudの資格受験では、Associate Cloud Engineer を選択しました。
自信のある方は、Associate Cloud Engineer と出題範囲が類似している、プロフェッショナル認定資格のProfessional Cloud Architect を初受験から検討しても良いかと思います。
また、Associate Cloud Engineer 合格後も、学習した記憶が新しいうちにProfessional Cloud Architect を受験するべきかと考えております。

https://cloud.google.com/certification/cloud-engineer?hl=ja

https://cloud.google.com/certification/cloud-architect?hl=ja


## 学習方法について
Professional Cloud Architect の資格受験にあたり、学習したことを記載いたします。
また、今回の試験に対してのフィードバックも記載します。1回の受験(50問)での感覚なので、流し読みいただければ幸いです。
### 行ったこと
- 基本的な知識の振り返り (Associate Cloud Engineer 受験時と同程度)
- 模擬試験の実施
    - Google Cloud公式
    - Udemy 模擬試験問題集(170問)

https://docs.google.com/forms/d/e/1FAIpQLScpVCxsKSrqMBmqJ4fiYrJfCSlMhJVIFaW_v3MD4xEd6NW0Bw/viewform?hl=ja

https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/

- 公式ドキュメントの閲覧
- Google Cloudでの実際の操作

#### 学習効果が高かったと感じたこと
- 模擬試験の繰り返し実施(暗記)
今回の試験では、模擬試験/問題集と非常に類似している出題が半数以上はありました。
特に、Udemyの【最短攻略】問題集は実際の出題と酷似している、と感じました。
Associate Cloud Engineer についても、100問の問題集がありましたので、これからの受験を考えている方は活用を検討する価値があるかもしれません。

https://www.udemy.com/course/google-cloud-associate-cloud-engineer-z/



- ケーススタディの事前把握
本試験では、架空の会社やソリューションを説明するケーススタディが4社分存在しています。
詳細は認定試験ガイドから確認でき、実際の試験の際も問題と同時に確認ができるような仕組み(画面分割)となっておりました。

https://cloud.google.com/certification/guides/professional-cloud-architect?hl=ja

試験中も確認しながら設問に取り組むことはできますが、事前に把握して取り組むことで大きなアドバンテージとなると感じました。それぞれの特色などを把握しておくことをお勧めします。


ケーススタディ(4社分)

https://cloud.google.com/certification/guides/cloud-architect/casestudy-ehr-healthcare?hl=ja

https://cloud.google.com/certification/guides/cloud-architect/casestudy-helicopter-racing-league?hl=ja

https://cloud.google.com/certification/guides/cloud-architect/casestudy-mountkirk-games?hl=ja

https://cloud.google.com/certification/guides/cloud-architect/casestudy-terram-earth?hl=ja

## おわりに
初のプロフェッショナル資格を取得することができました。
引き続き、他のプロフェッショナル資格の受験も予定しております。
その際は、改めてレポートできればと考えております。よろしくお願いいたします。
AWSでVue.jsのスマホレイアウトを確認する方法

メモ書き
AWSでVue.jsのレイアウトを確認する方法
・VScode内で、npm run buildを叩いてdistフォルダを作成
・S3のバケット内にそれを配置する。この際、css,js,img,index.html,favicon.icoを分けて配置する。
・バケットのプロパティから、一番下らへんにある静的ウェブサイトホスティングにhttpリンクがあるので、そのリンクでスマホから飛ぶ。

iPhoneのノッチがヘッダーにかかっていないかを確認したかったが、そもそもブラウザから見ているのでかかるわけがなかった。。。

ああああああああああああ
Tableau Desktop Specialist合格体験記


## はじめに
2022年9月、Tableau Desktop Specialistを受験し、見事合格したのでその体験記をまとめます。

目次
* Tableau Desktop Specialistとは
* 試験概要
* 試験までに準備したこと（学習方法含む）
* 試験実施時のこと
* その他

## Tableau Desktop Specialistとは
Tableau製品に関する基本的なスキルと製品知識を証明する資格です。

Tableauの認定資格には、
・Tableau Desktop Specialist
・Tableau Certified Data Analyst
・Tableau Server Certified Associate
の3種類があり、そのうち最も易しい資格となります。

資格についてはこちら
https://www.tableau.com/ja-jp/learn/certification

## 試験概要
受験料: $100
スケジュール変更料金: $25 
受験に必要な前提条件: なし
認定資格の有効期間: 有効期限なし
提供言語: 英語、日本語、中国語 (簡体字)

試験時間：60分間
問題数：45問

試験の詳細はこちら
https://www.tableau.com/ja-jp/learn/certification/desktop-specialist

## 試験までに準備したこと（学習方法含む）

1. まずは試験の申し込み

https://www.tableau.com/ja-jp/learn/certification/desktop-specialist
にアクセスし、「スケジュールにログイン」ボタン押下でサインインページに遷移します。
アカウント未作成の場合はtableauアカウント作成を行い、ログインすると

Tableau Certification Accountの画面が表示されるので
SCHEDULE MY EXAM
→Schedule or Manage my exam with Pearson
の順にクリックして下にスクロールして「Go to Pearson」をクリック

あとは受けたい試験を選んで（私の場合はTDS-C01: Tableau Desktop Specialist）試験の予約を行います。
※決済がUSDで行われるので為替の影響で受験料が1,000円単位で変動することがあります。

2. 試験に向けて学習

下記を利用して学習しました。
それぞれ本質的に理解をし、覚えながら進めました。
画面上のそれぞれのボタンや機能など、正確に覚える必要があります。

https://note.com/yuri5854/n/n0196ef3e1dea
https://knowledge.insight-lab.co.jp/tableau/tableau_fundamental-chart15
note記事の方は有料なので、無料のもっといいツールはたとえばYoutubeなどを探せば出てくるかもしれません。

## 試験実施時のこと

私はテストセンターで受験しました。
テストセンター到着後、受付でCBT方式の試験を受けたことのある人ならお馴染みの説明を受け試験開始。
45問しかなかったので時間は半分くらい余ったので十分な見直しの時間が取れると思います。

見直し後、「試験の終了」ボタン押下でアンケート画面が表示されます。
アンケートに答えて再度「試験の終了」ボタンを押下すると結果が出ます。
結果等々確認しつつ次へ次へと画面指示に従ってログイン画面が表示されたら受付に戻って結果を受け取ります。

試験結果：Pass

と記載されるので一瞬合格・・・？と焦りますがPass（合格）です。

## その他

試験に向けた学習でnoteの記事を紹介していますが、同記事で2022年9月試験を受験したところ
肌感覚での合否は五分五分だったので、別で教材を探す方が良いと思いました。
（同記事のメンテナンスはされていないように見えるため）
React 子から親へ入力内容を渡す

以前はpropsでset〇〇を直接渡していましたが、修正しました！(23/05/06)
# やりたいこと
子コンポーネントのテキストボックスに変更があるたび、入力内容を親コンポーネントに表示する

# 前提
同じコンポーネント内でのステートの変更、取得ができている状態とする。
（詳細はこちら→[React inputのvalueを表示する](https://qiita.com/aliceroot0678/items/d46ea5bee020f14502df)）
# propsの基本おさらい
結論を見たい方はさくっとこちらへ→ [実装](#実装)

Reactではコンポーネント間のデータの受け渡しはpropsを使って行う。
## 親→子へ値を渡すとき
### 親から子へ送る

子コンポーネントを呼び出すところで、`props名={値}`で渡す
```react:Parent.js
// 親コンポーネント
import Child from './Child';
import React from 'react';

const Parent() {
  return (
    <div>
      <Child count={1000} />
    </div>
  );
}

export default Parent;
```
### 子で受け取る
**引数にpropsを指定**。
`{props.props名}`で親から送られているデータは取得可能。
引数でpropsを受け取るのを忘れないで！:point_up:
```react:Child.js
// 子コンポーネント
const Child = (props)=>{   // 引数でpropsを受け取る
    return(
        <>
           <p>{props.count}</p>
        </>
    )
}
export default Child
```
# 子から親にデータを渡す流れ
では子から親にデータを渡したいときは？:thinking:
大まかな流れ↓
1. 親コンポーネント：
Stateと、Stateを更新する関数（`Set〇〇`）を定義
1. 親コンポーネント：
1.で作成した`Set〇〇`を呼び出す**関数A**を定義（引数の値で`State`を更新するような処理にする）
1. 親コンポーネント：
2.で作成した**関数A**を子コンポーネントに`props`で渡す
1. 子コンポーネント：
`props`経由で**関数A**を受け取る
1. 子コンポーネント：
**関数A**の引数に親に渡したい値を入れる
→子コンポーネントから親コンポーネントに値を渡せる

# 実装
（私が）ごちゃごちゃしてくるので、しつこいほどコメントを入れていきます。:triumph:

## 親コンポーネント

```react:Parent.js
import React, { useState } from "react";
import Child from "./Child";
//↑useStateを使う宣言 & 子コンポーネントの場所はここだよ宣言


const Parent = () => {
  const [text, setText] = useState("");
  // ↑親コンポーネントで使う：textの初期値とtextを更新する関数を宣言
  // ↓子コンポーネントから受け取った値で親コンポーネントのtextを更新する関数A
  const handleValueChange = (newValue) => {
    setText(newValue);
  };

  return (
    <div>
      <Child handleValueChange={handleValueChange} />
      {/* textを子コンポーネント側の値で更新するためにpropsで渡す */}
      <h1>{text}</h1>
      {/* ↑textはここに表示 */}
    </div>
  );
};

export default Parent;


```

## 子コンポーネント
※子コンポーネントは以前の記事のものを一部流用。
[React inputのvalueを表示する
](https://qiita.com/aliceroot0678/items/d46ea5bee020f14502df)
```react
import React, { useState } from "react";
//propsで値を受け取る宣言。（忘れがちなので注意）
const Child = (props) => {
  // 親コンポーネントから受け取った関数を使って、inputの値を渡す
  const handleInputChange = (event) => {
    const value = event.target.value;
    props.handleValueChange(value);
  };

  return (
    <>
      <input
        type="text"
        // フォームが更新されるとhandleInputChangeが呼ばれる
        onChange={handleInputChange}
      />
    </>
  );
};

export default Child;


```
## 登場人物
親側と子側それぞれの変数と関数について整理。
### 親側
+ `text`→変数。子コンポーネントから値を受け取ったらここに入れる。
+ `setValueText`→上記textを更新できる関数。
+ `handleValueChange `→setValueText関数を使って、引数の値でtextを更新する関数。
### 子側
 + `props.handleInputChange`→親側から子へ**props**でもらった関数。
 + `handleInputChange`→フォームに変更のあった場合呼ばれる。valueを見てpropsで受け取った関数を使い親に更新した値を渡す。
Javaを始めました

Eclipseを使用して、「Hello, World」のプログラムを実行した。
上手くいって嬉しかったが、まだ何が何だかよく分からないので、発展したプログラムが動かせるように練習していきたい。

kintoneでJavaで書いたプログラムを走らせるのが目的なので、
使い方をもう少し調べて、連休中に試してみようと思う。

▼参照した記事
@koukonko　さん
https://qiita.com/koukonko/items/98d36c3bae2f5e119bd7

Eclipseの押すボタンから詳しく書かれていて、とても助かりました。有難や…
access etcd in minikube

start k9s

and list the pods and select the following pod and type "s" (shell)

│ kube-system                etcd-minikube                                   ●                1/1                                      0 Running                192.168.49.2                 minikube                 5h48m



```sh
# set env
ADVERTISE_URL="https://192.168.49.2:2379"
 
# list all
ETCDCTL_API=3 etcdctl --endpoints $ADVERTISE_URL \
--cacert /var/lib/minikube/certs/etcd/ca.crt \
--cert /var/lib/minikube/certs/etcd/server.crt \
--key /var/lib/minikube/certs/etcd/server.key \
get --keys-only \
--prefix=true \
"/"
```
GitHubアカウント作成＆アクセストークン取得 (2022/09/22)

GitHubアカウントを久々に作るので備忘録でメモ
トークンはEclipseを使って push のときに必要になったのでそちらも

## アカウント作成

1. GitHub ページ開く https://github.co.jp/ - [GitHubに登録する] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/7c849ea6-82da-8014-3723-19d7f2f7dfe7.png)

1. 必要な項目入力 - Verify you account で質問に回答 - [Create account] クリック
　- Username : ユーザ名(アカウントID)
　- Email address : メールアドレス ※アカウント登録時にワンタイムコードが送られてくるのでその場で見れるやつ
　- Password : パスワード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/ee34d132-f651-c770-80e8-14c45ebee542.png)

1. メールに GitHub からサインアップ用のコードがくるのでそれを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/741eee1f-340a-ca98-669c-5e24590a0c7e.png)

1. 適当に選択 - [Continue] クリック
　- How many team members ... : 個人使用なら Just me
　- Are you a student or teacher : 学生 or 先生 なら選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/12f36fe1-7f27-1a23-16cf-758663b16b8d.png)

1. デフォルト(何もチェックしない状態) - [Continue] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/ebc687ce-2c7d-da55-0973-b543cae97c15.png)

1. 無料の [Continue for free] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/e0b84d88-82fa-9205-3b9e-680c613d7342.png)

1. アカウント登録完了！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/df1b18e8-22a3-9288-d33f-a2a1f2f21970.png)

## アクセストークン取得

1. ログイン - 右上の [アイコン] クリック - [Settings] クリック 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/25cdbaac-6aa7-5f3c-7e5e-ff674a816f8a.png)

1. 左メニュー - 一番下の [Developer settings] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/f22af8c4-9df4-901b-9938-98d739570abe.png)

1. 左メニュー - [Personal access tokens] クリック - [Tokens (classic)] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/c7defcab-9d76-775a-f495-2cecafe82453.png)

1. 右上 [Generate new token] クリック - [Generate new token (classic)] クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/9c724e53-49a4-af3b-4d37-3910b0a773c2.png)

1. 必要な項目を入力 - 一番下までいって [Genarato token] クリック
　- Note : 適当な文字列入力
　- Expiration : No Expiration(無期限) ※ 期限きって都度更新が安全かも．．．
　- Select scopes : 一番上の [ **repo** ] を必ずチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/cbb22872-d285-6bc1-36ae-ed5e98b70088.png)

1. 下の赤枠の **トークンをコピーして忘れないように必ず保管** ※忘れると取得できない．．．再作成．．．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/b9244993-aa65-0fab-acf3-fe5c389dcfe1.png)


1. 終了！！トークン忘れない！！
VS Code の Remote Development は仕組みを理解してないと危ない

Visual Studio Code には便利なExtensionが色々ありますよね
Remote Development に含まれる Remote SSH というのを便利だから使っていたんですが
ちょっと問題を起こしてしまったので備忘録です
そんなことも知らなかったのかと言われそうで怖いんですが

##  経緯
 - とある仕事の開発環境がAWSのインスタンス上に構築
 - 構造上ローカルでの動作確認が無理だったので編集はローカル、確認はファイルを都度アップロードしサーバー上で
 - vim で直接いじるの慣れてなくて辛いし編集した都度 winscp でやり取りするのもなぁ・・・
 - VScodeでどうにかできんか？軽くググったら Remote SSH 出てくるし便利だなぁこれ
 - 管理者「それちょっとやばいんで使うのやめてください」

## 何が起きていたか
Remote SSH (Remote Development) の仕組みは単にSSH接続してファイル編集できるというものではなく
接続した先の環境上に vscode-server というのをインストールして vscodeの機能を持ったサーバーを起動、そこに接続してなんやかんやするものでした
この vscode-server が曲者でメモリやディスクといったリソースを遠慮なくバカ食いしポートも空いているところを勝手に使用するそう

```
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
(略)
myuser  2538  0.0  0.0 119848   188 ?        S    00:03   0:00 sh /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/server.sh --start-server --host=127.0.0.1 --enable-remote-auto-shutdown --port=0 --connection-secret /home/myuser/.vscode-server/.622cb03f7e070a9670c94bae1a45d7
myuser  2546  0.0  2.7 1008360 56036 ?       Sl   00:03   0:17  \_ /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/out/vs/server/main.js --start-server --host=127.0.0.1 --enable-remote-auto-shutdo
myuser  2680  2.9  5.7 1204864 114760 ?      Sl   00:03  13:41      \_ /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/out/bootstrap-fork --type=extensionHost --uriTransformerPath=/home/yuta.matsu
myuser  2716  0.6 15.3 1139148 307560 ?      Sl   00:03   2:50      |   \_ /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/myuser/.vscode-server/extensions/bmewburn.vscode-intelephense-client-1.6.3/node_modules/intelephense/lib/intelephense.js --node-ipc --client
myuser  2691  0.0  1.1 881344 22788 ?        Sl   00:03   0:06      \_ /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/myuser/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/out/bootstrap-fork --type=watcherService
```
当時の開発環境のメモリは2GBでした、その上でなんか使用率15%とか見えますね

```
[myuser@ip-XXX-XX-XX-XXX .vscode-server]$ pwd
/home/myuser/.vscode-server
[myuser@ip-XXX-XX-XX-XXX .vscode-server]$ du -sh *
408M    bin
101M    data
75M     extensions
```
インストールされた vscode-server のファイルサイズもなかなか男前ですね

こんなにリソースを食っているが真に恐ろしいのは個人専用であるということ
別の人が同じ環境にRemote SSHを使った場合、新たにその人専用のvscode-serverがインストールされて更にサーバーリソースを圧迫します。

これをチーム内の3人くらいがそれぞれ使ってた結果、開発環境の大部分のリソースを食い尽くし
サーバーがダウン寸前まで行く不調を起こして注意を受けたということがありました

※参考記事
https://qiita.com/Ishotihadus/items/469b8f59ce74333a0a2e#remote-development

## 結論
 - Remote SSH(Remote Development) は便利だけどヤバい
 - ググるとベタ褒めする記事ばっかり見つかるから気軽に使用されそう、実際その一人だった
 - 拡張機能各種は共用の環境で使って大丈夫なものなのか要注意
 - 共有する環境ではなく確実に個人だけが使う環境なら自己責任で使う選択肢はある

## 代替策
sftp という拡張機能を使うようにしました。
https://rfs.jp/sb/vsc/vscsftp.html

リモート編集しているのとほぼ変わらない操作感だったので便利でした
少なくとも今回やりたかったことはsftpで充分カバーできた
SPSS Modelerで日付マスターを作成する

<h1>記事の目的</h1>
<p>
　著者はSPSS Modelerを使用して分析を行う機会がよくありますが、ストリーム作成する際に、自身が役立った内容などを 小ネタとしてQiitaに投稿していこうと思います。第一弾として日付マスターの作成を取り上げます。例えば、店舗の販売データを時系列分析する際に、時系列に販売データをソートすると、所々レコードが欠損し歯抜け状態になっている場合があります。この様な場合、カレンダーなどの日付マスターと結合し適切な時系列データに変換する必要があります。ここでは、ユーザーノードを使用して、日付マスターを作成する方法を説明します。
</p>

<h1>前提知識</h1>
<p>
本記事では、SPSS Modelerの概要や基本的な操作についついては記載しておりません。
必要に応じて、参考リンクに記載の情報をお読みください。
</p>

<h1>参考リンク</h1>
<ul>
<li><a href="https://qiita.com/416nishimaki/items/503037195081d3323eee" target="_blank">SPSS Modeler ノードリファレンス目次</a></li>
</ul>
<h1>①ユーザー入力ノードで年月日のベース情報を入力</h1>
ユーザー入力ノードに下記ように「Day」「Year」「Month」列を追加し値を入れます。入力された値のすべての組み合わせのレコードが生成されます。

![userinput.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/d742564f-6c34-8c86-42e4-76245f903787.png)


<h1>②datetime_dateを使用して日付にする</h1>
①の出力の「Day」「Year」「Month」をdatetime_date関数の引数として入力し「暫定日付」を生成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/bca75330-ca81-d420-abc8-7dca1299da8a.png)

<h1>③無効な日付を除去する</h1>
②の結果、無効な日付(例えば、30日までの月に31日が入っているなど)はnullが返されるので、条件抽出ノードにより除去します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/e2cb7056-409b-6188-5081-1ec5727907de.png)

除去して得られた結果を「日付」として出力できました。下記のように2020年が閏年であることも反映した出力になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/6aeafa70-6e55-36d5-fbed-238b54e81a67.png)


<h1>(少し応用#1)曜日と組み合わせる</h1>
datetime_weekday関数を使用して、日にちに対する曜日を出力させることもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/59d9cea1-ec36-eeba-42ca-ac3af5034430.png)


<h1>(少し応用#2)時間帯と組み合わせる</h1>
ユーザー入力ノードに入れる値を0〜23にして、日付マスタと完全外部結合することにより下記のような時間帯を加味した出力にすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299863/81d4cafe-6dfb-a6bd-f149-e8d5929e3c97.png)

<h1>サンプルストリーム</h1>
上記のストリームを含むサンプルストリームは<a href="https://github.com/nishinok/spss/raw/main/generate_date.str">こちら</a>からダウンロードできます。
<h1>おわりに</h1>
<p>
　お時間を割いてご覧いただきましてありがとうございました。今後もこのような小ネタを掲載していく予定です。

<br>
本記事が、SPSS Modelerでストリームを作成する際のHints&Tipsとなれば幸いです。
</p>
embulkのglobalなgemをbundleで管理する

## 引っかかったこと
docker buildにて、embulkのpluginをbundle installする際、ローカル環境は汚れないにも関わらず、わざわざbundle_dirを切り、embulkの実行時に-bオプションを付与することになんとなく気持ち悪さがあった。
```bash
embulk mkbundle bundle_dir
cd bundle_dir && embulk bundle
```
```bash
embulk run -b bundle_dir config.yaml
```

## 解決方法1
当然だが、dockerfileにてgem installを行えばいいだけ。
```docker
RUN embulk gem install embulk-input-jdbc embulk-output-bigquery
```
ただし、dockerfileの記述が長くなる他、Gemfileで管理できないことが美しくない。
dockerfileにpip install pyyaml pandas等と記述することがないのと同様に。
僕は過去にやったことがありますが…。

## 解決方法２
おすすめはこちらの解決方法。
そもそも、embulk bundleの実態は内包されたjrubyでbundle installを行っているだけだと考えられる。
つまり、以下のようなGemfileを用意しておき、--systemオプションをつけてbundle installをすればよい。

```ruby
source 'https://rubygems.org/'

gem 'embulk', '=0.9.24'
gem 'jwt', '2.3.0'
gem 'embulk-output-bigquery'
gem 'embulk-filter-add_time'
```

```docker
RUN embulk bundle install --system
```

あらゆるパターンで検証を行ったわけではないので、自己責任でお願いします。

embulk version 0.9.24

## まとめ
解決方法2にてプロジェクトディレクトリがすっきりした。
加えて、-bオプションのつけ忘れによる例外の発生もなくなった。

今後、embulkがv1.0になり、プラグインのリポジトリがGemからMavenになったときには、build.gradleで管理を行うことになるのだろうか。
あまり文献がなくてよくわからない。
Rails nil?とempty?とblank?メソッドの違い？・・・わかってます・・・

# はじめに
実務でコードを書いているときに次の3つの違いを先輩に問われたことがありました。
- nil?
- empty?
- blank?

どれもレシーバに値ががない状態？であることを確認するときに使っていました。
私自身よく考えずに使っていたので詳しく調べてみることにしましたので備忘録として残します。
間違いや補足がありましたら教えてください。

# 環境
Ruby 2.7.1
Rails 6.0.5

# ３つの違いとは
### nil?
Rubyのドキュメントによると次の通りです。
>レシーバが nil であれば真を返します。

~~レシーバ自体が存在しない場合~~、つまりnilであればtrueを返します。

※追記
>nil は何かが存在しないことを表すために用いられるオブジェクトです。

レシーバが存在しないということはあり得ないというご指摘をいただきましたので追記です。


https://qiita.com/scivola/items/da2480ca4597a7dcf73d



### empty?
Rubyのドキュメントによると次の通りです。
>文字列が空 (つまり長さ 0) の時、真を返します。

nilとは違い、空の場合にtrueとなります。

@scivola さんよりご指摘いただいています。
empty?メソッドにも様々な種類があるようで、詳しくはコメント欄をご覧ください。

### blank?
@koki_73 さん、@scivola さんよりご指摘いただきましたので追記です。
Rails公式によると
>An object is blank if it's false, empty, or a whitespace string. For example, nil, '', ' ', [], {}, and false are all blank.

直訳すると
>オブジェクトが false、empty、または空白文字列である場合、blankとなります。例えば、nil, '', '', [], {}, false はすべてblankです。

と記されています。

~~おお便利。ただ理解して使わないとバグの原因にもなりそう。
blank?はつまりnil?とempty?を一緒に確認して、どちらかがtrueであればtrueを返すということですね！~~
falseであればnil?メソッドであればfalseを返し、empty?であればNoMethodErrorを返します。
しかし、blank?ではtrueとなりますね。

今回も自分の目で確かめてみようと思います。

# やってみた
一方の変数にnil1を、もう一方の変数には""を代入します。
~~~ ruby
nil_str = nil
empty_str = ""
~~~
それぞれメソッドを試してみます。

### nil?の場合
nil?の場合を見てみます。
[![Image from Gyazo](https://i.gyazo.com/600444899080094d93f5f7b3f3b4f481.png)](https://gyazo.com/600444899080094d93f5f7b3f3b4f481)
nilの値が代入されたレシーバのみtrueを返しました。

### empty?の場合
empty?の場合を見てみます。
[![Image from Gyazo](https://i.gyazo.com/1af409b566bc1847d3ae34d6f2d99133.png)](https://gyazo.com/1af409b566bc1847d3ae34d6f2d99133)
""のレシーバの時にはtrueとなっています。
また、nilの値にempty?メソッドを使うとNoMethodErrorとなってしまいます。

### blank?の場合
blank?の場合を見てみます。
[![Image from Gyazo](https://i.gyazo.com/dab5d019b7496f41f27953c87d42e986.png)](https://gyazo.com/dab5d019b7496f41f27953c87d42e986)
nilのレシーバ、""のレシーバともにtrueを返しています。

なるほどそういうちがいがあったのか。

# その他のメソッド
今回調べていくうちに分かったことがあるので補足しておきます。

### present?
present?はblank?の反対の動きをするメソッドです。
[![Image from Gyazo](https://i.gyazo.com/9c4aa77fc7b56e7ece6fbdf046591212.png)](https://gyazo.com/9c4aa77fc7b56e7ece6fbdf046591212)
blank?とは反対の値を返していることがわかります。

### exists?
>exists?メソッドとは、指定した条件のレコードがデータベースに存在するかどうかを真偽値で返すメソッドです。存在すればtrueを存在しなければfalseを返します。

つまりデータベースにおいて条件にマッチするレコードがあればtrueを返し、レコードがなければfalseを返します。
~~~ ruby
User.exists?(name: 'クロロ')
~~~
上の場合Usersテーブルのnameレコードにクロロという文字列があればtrueを返します。

# おわりに
メソッドの中には意外とその場の空気で使っているものって結構あるなあと思いました。
書いてすんなり動くとそのままよくわからない状態でほったらかしてしまうことがよくあります。
時間は限られているのですが、立ち止まってバグのないアプリケーションの開発を進めていきたいと思います。

# 参考
https://docs.ruby-lang.org/ja/latest/method/Object/i/nil=3f.html

https://docs.ruby-lang.org/ja/latest/method/String/i/empty=3f.html

https://style.potepan.com/articles/27128.html

https://qiita.com/somewhatgood@github/items/b74107480ee3821784e6

https://pikawaka.com/rails/exists