OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】文系インフラエンジニアのプログラミング勉強法

# これから先生きのこるには
自分は文系出身のインフラエンジニアです。
プログラミングは無縁だと思って生きていました。
業務上必要になる事が少ないため周りの人も、同じような人が多かったです。
しかし昨今、プログラミングの必要性を感じて学習をしているため記事にしたいと思います。

IaaSやクラウドネイティブな開発が一般的になりました。
その流れでアプリケーションエンジニアがインフラ領域に携わる事が増えていると感じています。
サーバーレス環境はOSやミドルウェアを意識しなくてよいためインフラ的な要因が少ない為です。


また、AWSなどのクラウドサービスではAPIを公開しており利用者で自動化などの取り組みが可能です。
プログラミングでAPIを叩いてインフラを管理するのです。
するとプログラミングが全く出来ないとインフラ業務の幅も狭くなってしまいます。
プログラミングが出来る人と出来ない人の格差が圧倒的に広がっていくと思っています。

以上のことから、これから先生きのこるにはインフラエンジニアもプログラミングを勉強した方がいいと考えています。

![character_kinoko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242298/5ec1318d-a8f0-1b5f-05ee-bdbf2ecb9875.png)



# この記事の対象になる方
- プログラミング未経験だけどやってみたい
- Pythonを学習したい
- **自分に合った情報を取捨選択できる方**

# 自己紹介
- 文系出身
- インフラエンジニア（オンプレ/AWS）
- プログラミング歴は簡単なシェルスクリプトだけだった
- 現在はPythonを勉強して基礎文法をある程度理解済み
- 代表的なモジュールは調べながら扱うことができた。ググったら多少なんとかなる精神
- 業務ではAWS SDK(boto3)やSlack API+Lambda連携等で業務改善や自動化が出来るようになった

# おすすめの勉強法
## プログラミング学習サービス
鉄板ですが初学者がまず手を動かすのには最適だと思います。
初心者が挫折しにくい仕組みになっているのでおススメです。

サービスによって得意な範囲は異なりますが共通して以下の強みを感じます。
- 体系的に学べる
- **実行環境を用意しなくていい!**
- 月額1000円前後で気軽に始められる
- ゴールが用意されていて達成感がある

実際に利用したサービスをいくつかご紹介します

### Progate
https://prog-8.com/

プログラミングのはじめの一歩に最適だと思います。
基礎文法をやさしく丁寧に紹介してくれます。特に入門者向けのサービスです。
逆にモジュールの紹介とかは少なかったので、一通り終わったら次のステップに進むといいと思います。

スライド形式なので好きな音楽を聴きながらでも出来るのも好きなポイントでした。

### paiza
https://paiza.io/ja

progateよりも実践的な範囲まで学習することが出来ます。
競技プログラミング的な問題を解くサービスもあります。ランクが上がると難しいです。
学習の動画コンテンツは声優さんとコラボしています。
ゲーム感覚で学習するコンテンツもあります。

課題をクリアするとランクがあがり、転職にも繋げることができます。

### PyQ
https://pyq.jp/

動画やスライドはありません。
説明にそって写経して実行することで学習することができます。
そのあとには復習として参考コードなしで課題に挑戦します。
モジュールや実践的なコンテンツもあるので**基礎文法の後のステップ**としておススメです。

難点は安いプランでも3000円/月額と前述と比較すると高額。
長期休暇があるとき、頑張ると決めた月だけ加入がいいかと思います。

###

## Youtube
プログラミング学習サービスで理解しきれなかった点の確認/新しい情報の習得に利用しています。
無料で見れるのが凄すぎるチャンネルがいくつかあるので紹介したいと思います。
いつも感謝しているので今回の紹介でお返しできたら嬉しいです。


### いまにゅのプログラミング塾
https://www.youtube.com/channel/UC0xRMqPOyRNPTaL6BxhbCnQ

プログラミングはもちろん、学習に役立つコンテンツなども紹介されています
初学者に寄り添ったコンテンツが豊富です。

### Pythonプログラミング VTuber サプー
https://www.youtube.com/channel/UC5Kgc_HNzx4GJ-w4QMeeKiQ/about

汎用的に使えるモジュールを分かりやすく紹介されています。
一本当たり１０分前後に分かりやすくまとめられています。

## 勉強会
まさしく今、学びたいことを題材にしている勉強会に巡り合える時ばかりではないと思います。
自分はマンネリしてきたりモチベーションがあがらない時にも参加して刺激をもらっています
### connpass
https://connpass.com/

勉強会プラットフォームはいくつかありますが個人的に一番使いやすかったです。
LT会やハンズオンが多い印象です。
# おすすめしない勉強法

## 書籍（特に紙媒体）で学習する
これに関しては諸説あるかと思います。
自分も勉強は紙媒体のほうが馴染みがあったので書籍中心の時期がありました。

しかし誤表記が付き物でアップデートがなされない点など
プログラミング学習においては現代ではあまり有用ではないと感じています。

## 環境構築を頑張る
書籍で学習するとPCに実行環境をインストールするところから始まってしまいます。
本来学びたいことの前に障害があって体力とやる気ゲージを消費してしまいます。
Pythonのダウンロードが終わったぞ！と思ったらエディタのダウンロードと使い方が待ち構えています。。。
職業プログラマーとしては必須な項目だとは思いますが、**初学者はプログラミングの楽しさを感じた方がいい**と思います。

## 最初のうちに機械学習/AIに手を出す
Pythonは機械学習/AIの分野が得意なことが有名です。
しかし機械学習/AIの分野には数学の知識が必要です。
そのためもし興味があっても、文系の方はプログラミングの学習に専念したほうがいいかと思います。

# おわりに
自分もまだまだ初学者ですが自分が利用しているサービスの紹介を中心に行いました。
同じような人の助けになったり、提供して頂いている方への御礼になったら嬉しいなと思っています。
結局最後は自分が続けられるやり方が一番だとは思います。
**なぜ勉強したいと思ったか、という初心**を忘れない事が続けるコツなのかと感じています。
一般動詞

# 一般動詞
be動詞以外の動詞を一般動詞といいます。
一般動詞の種類には
* 動作動詞（主語の動作を表す)
* 状態動詞(主語の状態を表す）

## それ以外の動詞
* 他動詞(目的語を必要とする動詞）
* 自動詞(目的語を必要としない動詞)

## 他動詞を使った肯定文
```
I play tennis.
```
```play```は目的語を必要とするから他動詞だ。
```主語+他動詞+目的語```の順に単語を並べる。

## 自動詞を使った肯定文
```
I go to school.
```
目的語を置くときに前置詞を必要とする一般動詞を```自動詞```という。
名詞の前にある前置詞は```名詞が文の中でどのような役割を果たすか```で決めす。

## 不完全自動詞を使った肯定文
```
You look busy.
```
一般動詞にはbe動詞と同様に、動詞の前後を=（イコール）の関係にするものがある。
これらを```不完全自動詞```という。

### 気づき
状態を表しているのか。

動詞の種類にもいろいろあるんだな。
いつ使うかわからないが、動詞の種類があることを理解しよう。
Pythonしか知らないプログラマの地雷率の高さ

# はじめに
ただの愚痴です

最近ポンコツ案件に入ってそれでなくてもポンコツの私よりデキが悪くて愚痴らなきゃやってられないので
ただそれだけです
別にみんながみんなそうだとは思わないけどまあ、うん。経験則はある。

読んでて深不快に思われても私はなんの責任も取らないのであしからず。

# Pythonの何が悪いのか
スクリプト言語だからじゃね？
型宣言無いし変数好きな場所で宣言できるし他にも色々。
例えばCみたく関数の頭でしか変数宣言できなければ
書くのは不便でも変数の目的を予め知ってら処理見れるから可読性は上がる。（目次先読みできる感覚

つまりPythonは書きやすいけど可読性が💩になりやすい。
Pythonの思想で
「1つの処理を実現するのにベストな方法はいくつもない」
みたいな話があった気がする。
インデントに意味があるのも、
Pythonの思想で、誰が書いても同じコードになる。
みたいなのがあったようななかったような……

絶対嘘だろ…


# スクリプト言語ってなんじゃらほい
厳密にスクリプト言語って定義は無いんだろうけど、
Pythonとかjsとかあのへん

対になるのがc/c++とかgoやjavaとかか？

# 地雷ってどーゆこと？
先に散々書いた気もするけど、コードが汚い。
これに尽きる。

コードが汚いということは設計思想やデザインパターンも曖昧で、
まあつまりだ、動けばよくね？って低レベルな次元の話なんだわ
でも本人はこれこそ超大作！完璧！とばかりの自信を持っている
滅びろ。
これは多分後述する謎プライドによるものもあるのかもしれんけんども。

まあそいつはただエンジニアとして初心者なだけかもしれないし、
プライドが高いだけかもしれないし、
自分以外を知らないだけかもしれないし、
歳上ってだけで威張ってるのかもしれない。

稀によく歳食っててもポンコツなのは結構いる
この業界年齢とか糞より役に立たないことのほうが多いから……

# 特にPython。さらに言えばjupyterNotebook
便利なものほど使い方を誤ると危険なものに変貌するってのは古今東西いつの時代もどんなものでもそうだ。
例に漏れずプログラミング言語やエディタもそれに該当する。

## Python
もはや人気No1と言っても過言じゃないプログラミング言語。
だいたいのエンジニアが使ったことあるし、案件も多いし、ユーザが多いからライブラリも豊富。
Cやってた身からすると二度とcに戻れなくなる便利さ。
でも大体はその中で何やってるかわからない

## jupyterNotebook
Python向けのコードエディタ
ブラウザ上で書いて実行もできるし、スクリプト言語の特性を活かして変数の中身を容易に逐一確認できたりする。
機械学習系よでよく使われている印象（ほんとに使われてるかは知らんけど）

あとPythonの入門書にはほぼ100%出てくる。
あの京都大学が公開してるPythonの教科書でもjupyterNotebookを使って実装が書かれているくらいだし。
とてもメジャー
だがしかしこの便利でメジャーなツール、これこそが諸悪の根源。

# 著者が楽した結果、出来上がったのはポンコツプログラマ
jupyterNotebookは確かに便利だ。
VSCodeでもデバッグはできるしprint仕込めばサクッと変数の中身も確認できるけど、
jupyterNotebookのソースコード上に出力されるあの感じがわかりやすい。
ブロックごとに実行できて使うのも簡単。

教える手間も省ける。
そらみんな勧めるわ。

どーせ初心者向けの参考書とかでオブジェクト指向だのマイクロサービスだのやらんもんな
書いて動けばオッケーだもんな？
「できました！」って出てきたコードが環境依存しまくりだったりrequirements.txtすら無いとか1つのファイルに全部のコード書いてあるとか、当たり前だよなあ？

至るところで変数宣言して、
ビジネスロジックは複雑怪奇でコメントもなく
linterすら流してない糞コード

普通は現場で教えるのか？
まあ仕方なく教えるよ
でも教えたくても教わりたがらない連中は一定数いるんだよ
私より歳上でエンジニア歴が片手で余る浅さの私の注意や提案なんて聞く頭の柔らかいエンジニアならそもそも糞コードなんて書かねえよ

でもそーゆーポンコツを生成してる根幹にはこのjupyterNotebookがあると思ってる。

便利なツールってのは楽だ。
その裏で何が動いてるのか、どういう原理なのか、仕組みを教える手間も教わる手間も省ける
だが知らなければ理解することはない。



これがどれくらいヤバいことかというと、
料理家になろうってしてる料理初心者に
「とりあえず具材切ったらタッパーに入れてレンチン」
多分こんなノリ。

な？ヤバいだろ？
ワンチャンスーパーでカット済みの具材買うまである。

料理の教本がこれだったら笑っちゃうでしょ。
んで習ってる方はそれなりのものが出来ゃうもんだから（あ、これでいいのか）ってなるのは必至。

んで料理家と違って資格もなにもいらないプログラマは食える（動く）ものが作れればすぐ現場投入
電子レンジしか使えない料理人がレストランやってますってビビるだろ？

やっぱこの業界腐ってるよ(笑)


電子レンジが便利なものなのは周知の事実。
これが悪とは勿論思わない。
同じようにjupyterNotebookも悪ではないしとても便利なツールであるのは事実だ。

だからこそ正しい場面で利用して欲しいし、
教える側は責任持って教えてあげてほしい
じゃなきゃ出来上がるのはポンコツだ。

# 謎プライド
この業界はコミュ障が多い
そらしゃーない
pcオタクなんて陰キャ根暗と相場が決まってる

陰キャ根暗でも会話ができれば仕事には何の支障もない。
でも会話できない奴って腐るほどいる。
本人無自覚なのがまじF○CK

代表例を紹介しよう。
自分がやったことを否定されるのは死ぬほど嫌うやつ。
例えば他人の意見には「いや、」「でもそれは」って否定から入る。

うん、控えめに言って産廃である。
それを許してる社風も注意しない上司もまた同様。

だから他人のし指摘は聞き入れないし歳下や経験が浅い人からのものなら尚聞かない

理論攻めしても「でもそれは〜」「逆に〜」「あどちらかといえば〜」って意味のない接頭語でのらりくらり誤魔化す
（誤魔化せてないからね？なんなら無能ささらけ出してるから辞めたほうがいいよ

彼らにはきっと謎のプライドがあるんだろう。
話を聞かなくてもいいからせめてマシな仕事をしてくれ…
こういった連中に限って仕事できないんだから目も当てられない。

そんな謎プライド持った奴が「料理は具材切ったらタッパーに入れてレンジでチン！」を脇目も振らず遂行するわけである

な？最初からちゃんと教えとこうって思うっしょ？
思ってくれ、偉い人。。


# 業界が腐ってるよ
うん、多分業界が悪い。知らんけど。
でも私はこの世界でしか飯が食えない。
幸いなのはフリーだからハズレ案件引いてもすぐ辞められるとこか

なんともまあ悲観的な話か
ソリューションアーキテクト対策_タグ付け篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:

## タグ付けのベストプラクティス
・個人情報(PII)などの機密情報や秘匿性の高い情報をタグに格納しない

・タグには標準化された、大文字と小文字の区別がある形式を使用し、全てのリソースタイプに一貫して適用する

・リソースアクセスコントロールの管理、コスト追跡、オートメーション、整理など、複数の目的に対応したタグガイドラインを考慮する

・自動化されたツールを使用して、リソースタグを管理できる。
AWSリソースグループとリソースグループのタグ付けAPIを使用すると、プログラムによるタグの制御が可能になるため、タグとリソースの自動的な管理・検索・フィルタリングが容易になる

・タグの利用が少なすぎるよりは、多く利用することが好ましい

・ビジネス要件の変化に合わせてタグを変更するのは簡単だが、将来の変更の影響を考慮すること。
たとえば、アクセス制御タグを変更した場合、そのタグを参照してリソースへのアクセスを制御するポリシーも更新する必要がある。



## おわりに
引き続き追記します。

簡単ですが以上です。
コントローラの内容をレンダリングする

# railsチュートリアルの説明の大まかな流れ
まずユーザーに送信すべきレスポンスの内容を決定し、次にユーザーへの```レスポンスを作成する適切なメソッドを呼び出します。``` レスポンス画面を完全なビューで作成すると、Railsはそのビューを```レイアウトでラップ```して、場合によっては```パーシャルビュー```もそこに追加します。本ガイドではこれらの方法をひととおり紹介します。

### 気づき
レイアウトでラップするという意味がわからない。
包むというらしい。

https://coliss.com/articles/build-websites/operation/css/styling-layout-wrappers-in-css.html

# コントローラ名のビューを探してレンダリングする。
「コントローラのアクションの末尾で明示的に```レンダリングが指示されていない場合は、コントローラが利用可能なビューのパスからアクション名.html.erbというビューテンプレートを探し、それを使って自動的にレンダリング```する」

# renderメソッド
ほとんどの場合、アプリケーションがブラウザで表示するコンテンツのレンダリングには
```ActionController::Base#renderメソッド```が使われます。
### できること
```特定のテンプレート、ファイル、インラインコードを指定```してレンダリングすることも、```何も出力しないようにする```こともできます。```テキスト、JSON、XMLをレンダリング```することもできます。

### 他にも
レスポンスをレンダリングするときに```Content-TypeヘッダーやHTTPステータスを指定```することもできます。

## 別コントローラの配下のテンプレートをレンダリングする。
```あるコントローラのアクションから、まったく別のコントローラの配下にあるテンプレートを利用してレンダリング```することは可能です。これもrenderメソッドでできます。
...
renderメソッドには```app/viewsを起点とするフルパスを渡せる```ので、レンダリングする```テンプレートをフルパスで指定```します。

## renderで:inlineを指定する
renderメソッドを呼び出すときに:inlineオプションでERBを渡すと、ビューをまったく使わずにレンダリングできます。以下の書き方は完全に有効です。

```html
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
```

### 注意点
```このオプションを実際に使う意味はめったにありません。```コントローラのコードにERBを直接書き込むと、Railsの```MVC指向が損なわれ```、開発者がプロジェクトのロジックを追いかけることが難しくなってしまいます。```ERBビューをお使いください。```

## テキストをレンダリングする
renderメソッドで:plainオプションを指定すると、平文テキストをマークアップせずにブラウザに送信できます。
```
render plain: "OK"
```

# render_to_stringメソッド
render呼び出しの正確な結果をブラウザを使わずに調べたい場合は、render_to_stringを利用できます。このメソッドの振る舞いは、```レンダリング結果をブラウザに返さずに文字列を返す点を除けば、renderと完全に同じ```です。

### 気づき
いつか使えそうかな。

# redirect_toメソッドを使う。
renderはレスポンスを構成するときに使うビュー（または他のアセット）を指定しますが、redirect_toメソッドは、この点において```renderメソッドと根本的に異なります```。
redirect_toメソッドは、```別のURLにリクエストを再送信するようブラウザに指示```します。

たとえば以下の呼び出しを行なうと、アプリケーションで```現在どのページが表示されていても、写真のindexページにリダイレクト```されます。
```
redirect_to photos_url
```
redirect_toを実行すると、```コードはそこで実行を停止して、ブラウザからの次のリクエストを待ちます```（これは通常の```スタンバイ状態```です）。その直後、redirect_toでブラウザに送信したHTTPステータスコード302に従って、ブラウザは別のURLへのリクエストをサーバーに送信し、サーバーはそのリクエストを改めて処理します。

```rb
def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    render action: "index"
  end
end
```

上のフォームのコードでは、````@bookインスタンス変数がnilの場合に問題が生じる可能性があります```。render :actionを実行しても、対象となるアクションのコードは実行されないことを思い出しましょう。つまりindexビューでおそらく必要となる```@booksインスタンス変数には何も設定されず、空の蔵書リストが表示```されてしまいます。 これを修正する方法の１つは、```renderを以下のようにredirect_toに変更```することです。
```rb
def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    redirect_to action: :index
  end
end
```

上のコードでは、ブラウザから改めてindexページにリクエストが送信されるので、indexメソッドのコードが正常に実行されます。

上のコードで惜しい点は、ブラウザとの通信が1往復必要になることです。```ブラウザから/books/1に対してshowアクションが呼び出され、本が1冊もないことをコントローラが検出```すると、コントローラはブラウザにステータスコード302（リダイレクト）レスポンスを返し、```/books/に再度アクセスするようブラウザに指示```します。ブラウザはこの指示に沿って、```コントローラのindexアクションを呼び出すリクエストを改めてサーバーに送信```します。コントローラはこのリクエストを受け取って、データベースからすべての蔵書リストを取り出し、indexテンプレートをレンダリングして結果をブラウザに送り返すと、ブラウザで蔵書リストが表示されます。

## 気づき
renderとredirect_toの違いがわからなかった。
もっと勉強をしなければならない。
時間が来たのでまた。
とりあえずrenderメソッドを使い。
もう一度疑問点を洗い出す。

# 出典 
https://railsguides.jp/layouts_and_rendering.html
指定された範囲の数値（時間）によって処理が異なるプログラム

今日も学んだ事を忘れない為にメモします

### プログラム内容
第一引数に音が鳴った場合はtrueを指定し、鳴らない場合はfalseを指定する。（trueとfalseは真偽値）
第二引数に時間を指定し、指定した時間内（今回は21時から翌朝8時）に鳴った場合は"NG"を出力。
指定した時間内に鳴らない場合は"OK"を出力する。


### 記述内容
```
def siren_sound(sound, hour)
  if sound && (hour < 8 || hour > 21)
    puts "NG"
  else
    puts "OK"
  end
end

siren_sound(false, 12) 
siren_sound(true, 22) 
```
```:出力結果
OK
NG
```

第一引数soundの条件式は真偽の判定を行うだけなので、trueが入っているときに真（true）と判断される。

肝心なのは第二引数のhourの条件式。
2つの条件式が真(true)のとき「NG」が表示され、それ以外のとき「OK」が表示されるようにしたいので、それらを結ぶ演算子として「&&」を使用する。

判定したいのは、時間帯が「21時から翌朝8時までの間」か「それ以外」かという事。そのため、第二引数hourがtrueとなる条件式は(hour < 8 || hour > 21)と記述する。
hour < 8で０時から8時まで、hour > 21で21時以降の時間帯の指定をしている。

以上になります。
【備忘録】seleniumエラー対応（ChromeDriver is assuming that Chrome has crashed）

## エラー内容および対処法

**実行環境：** 
Ubuntu 20.04 LTS
Python 3.8.9

```言語:エラー内容
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /snap/chromium/2082/usr/lib/chromium-browser/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
```

かなり苦戦しましたが、下記対処で解決できました。
　・「--no-sandbox」オプションの追加
　・chromeのパスを指定


```python:サンプル
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


options = Options();
options.add_argument('--no-sandbox')
options.add_argument('--headless')
options.binary_location = '/usr/bin/chromium-browser'
driver = webdriver.Chrome(options=options)
driver.get('https://◯◯◯◯◯◯◯◯')
time.sleep(5)
print(driver)
time.sleep(5)
driver.quit()
```

chromium-browserのインストールは下記にて。
```
sudo apt install -y chromium-browser
```


## メモ

「google-chrome」のパスを指定するという記事もあったのですが、私の場合はそれでは解決しませんでした。

詳しくは不明、、、
また何か分かりましたら追記します。
python GUI入門　 QtDesigner + pySide　スライダーテキストボックス動作連携(小数点表示)

# 実行サンプル
小数以下でのスライダー動作。(Qsliderそのものは、0以上しか対応していないので換算あり。）
スライダーを動かすと、テキストボックスに値が入る
テキストボックス入力すると、スライダーが連携して動く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/cd3d21b9-e861-0f4c-5e97-d11df8f7dc91.png)



# 実行環境
windows10
python3.9.5
Qt5.1.5 (QtDesigner6.0.2コミュニティ)

pythonモジュール：pySide6（pipでインストールしておく）

# 実行手順
ソースコードを作成する
windowsコマンドプロンプトでプログラム作成したフォルダに移動し、下記実行する
```
python mainwindow.py 
```

# ソースコード作成手順
参考
https://qiita.com/taiko1/items/c19d75ba09d60ae5f5a6#4%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E4%BD%9C%E6%88%90%E6%89%8B%E9%A0%86

# ソースコード
https://github.com/sakurataiko1/Python_GUI_pySide/tree/main/pySide6_slider_decimal

下記で構成される。
form.ui
mainwindow.py
pySide6_slider_decimal.pyproject
pySide6_slider_decimal.pyproject.user
Ui_MainWindow.py

<B> mainwindow.py </B>
```
# This Python file uses the following encoding: utf-8
import os
from pathlib import Path
import sys

from PySide6 import *
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *

from Ui_MainWindow import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # スライダー　小数点対応(QSliderは整数しか対応していない。小数にも対応できるようにする)
        self.ui.lineEdit1.editingFinished.connect(self.func_on_lineEdit1_editingFinished)
        self.ui.slider1.valueChanged.connect(self.func_on_slider1_valueChanged)

        #　GUIフォーム初期値
        self.ui.slider1.setMinimum(1)
        self.ui.slider1.setMaximum(1000)

    def func_on_slider1_valueChanged(self):
        # スライダーは0以下数値を扱えないので、小数点以下にも対応できるように換算
        keta = -1 * 3
        value = self.ui.slider1.value()
        real_value = value * (pow(10, keta)) #round(value * (pow(10, -3)), 3)
        str_value = "%0.*f" % (abs(keta), real_value)
        # テキストボックスに値を入れる (lineEdit にしているので valueChangedにループはしない)
        self.ui.lineEdit1.setText(str_value)
        #　print("[DEBUG]01 MainWindow.py-func_on_slider1_valueChanged value=", value, " real_value=", real_value, " textBox=" , self.ui.lineEdit1.text())

    def func_on_lineEdit1_editingFinished(self):
        #print("[DEBUG]01 MainWindow.py-func_on_model1_editingFinished\n")
        keta = 3
        value = float(self.ui.lineEdit1.text())
        self.ui.slider1.setValue(int(value * 10 ** keta)) # スライダーは0以下数値を扱えないので、小数点以下にも対応できるように換算

if __name__ == "__main__":
    app = QApplication([])
    widget = MainWindow()
    widget.show()
    sys.exit(app.exec_())

```

スライダー と　スピンボックスの連携をしたいが
シグナルスロットでループしてうまくいかなかったので
EditingFinished が使えるテキストボックスで作成した。


# 関連資料
参考：
https://stackoverflow.com/questions/29543012/variable-number-of-decimal-digits-in-string-format

今後はクラス化も検討したい。
https://ymt-lab.com/post/2020/pyqt5-qdoublespinbox-and-qslider/
https://stackoverflow.com/questions/42820380/use-float-for-qslider
【Houdini】Point操作逆引き

Houdiniでモジュールアセットを活用したプロシージャルモデリングをする場合、Point操作に慣れている必要があると思ったので、まとめました。

## Primitive外周のポイントを取得する

[Groupノード](https://www.sidefx.com/ja/docs/houdini/model/groups.html)のBase Group中にあるEnableオフにする。
Groopノードの"Unshared Edges"のオプションをオンにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/1c16f65f-946b-76ae-63a2-58e5967b0b40.png)

## 異なるジオメトリで、同じ位置にあるPointをグループ化する。

[Group Transferノード](https://www.sidefx.com/ja/docs/houdini/nodes/sop/grouptransfer.html)で実現できます。
Primitive Groups、Edge Groupsはオフにします。
Distance Thresholdは要調整。

|均等にPointがあるPrimitive|両端と真ん中にポイントがあるPrimitive|位置が重なった場所だけをグループ化|
|---|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/c693cb2f-7c4c-0ce6-5689-7df2a756dfcf.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/97421975-5703-b9fa-03a4-7981737aee77.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/d613ce29-355c-60f1-3f6e-e8be6ae1f817.png)|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/2bc14569-83bc-667a-26fb-92292eba8dbf.png)


## Primitiveの真ん中のpointを取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/d2c17a74-80ed-0df5-b62b-728c8e5aa8f5.png)

- Assembleノードの"Create Packed Geometry"をオン
- Addノードの"Delete Geometry But Keep Points"をオン

|元の状態|結果|
|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/db95aeb8-c92c-600f-fff2-e514fb0b3b2e.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/78b0808d-29f1-43d2-5618-9216a263f356.png)|

## Ponint番号の並びを逆にする

[Sortノード](https://www.sidefx.com/ja/docs/houdini/nodes/sop/sort.html)のPoint SortをRandomに指定

## Box内にあるPointだけを取得
GroupノードのKeep in Bounding Regions(Bouding Type:Bounding Object)を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/70595adf-b6e5-a714-97f4-c753eefcb69f.png)

## 交互にPointを取得したい
Group Rangeノードで2つに1つを選ぶようにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/3306bbd4-4836-9fb3-35f9-92d4eb38cb15.png)


## ランダムなPointを1つ取得したい

SortノードでRandomに並び替え後、Groupノードで0番目を取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/4941fd7d-33a7-cebb-0cb5-0c99f677fa3d.png)




## Pointの両端を取得したい

- Group Expressionノードを操作
- GroupTypeをPointと指定。
- VexPressionのプリセットから”PointValence”を選択
- プリセットは入力フィールドの▼ボタンクリックで出てきます。
- 入力フィールド右端のスライダーボタンをクリック
- Valenceスライダーが表示されるので、Valenceを1に指定。
- Valence=2で、両端以外をグループ化できる。

### PointValenceでフィールドに入力される以下のエクスプレッションについて。

```jsx
neighbourcount(0,@ptnum)==chi("valence")
```

neighbourcount()は、つながっているポイント数を返します。
両端の隣接ポイント数は当然1だから、valence=1で取得できるわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256717/ddac4fbe-c3ca-2549-6a1b-a0a617808c68.png)

## Pointのノーマル方向を変更する

Attribute Wrangleノードで以下のように方向を指定する。

```jsx
@N=set(0,0,1);
```
pandasで文字列から数字以外を抽出

<h1>Pandasで文字列から数字以外を抽出</h1>
今回の記事は、競馬データを加工していく中で正規表現を使ってコラムを分けたい時によく出てくるのでメモとして記載しておきます。

<h2>したい事</h2>
データフレーム内のあるコラムでは、数字と文字が混合している場合があります。

<b>例：</b>

```python
test_list = ["1中山2", "11中京2", "阪神2"]
df = pd.DataFrame(test_list, columns={"開催場所"})
print(df)

#	開催場所
#0	1中山2
#1	11中京2
#2	阪神1
```

上記のデータの開催場所で、数字以外を抽出したい場合には<b>正規表現</b>を使って分割しましょう

<h2>解決策</h2>

```python
import regex

df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x))

print(df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x))

#0      (中山, 2)
#1      (中京, 3)
#2      (阪神, 1)

df["開催場所_new"] = df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x)[0])
print(df)

#	開催場所	開催場所_new
#0	1中山2	中山
#1	11中京2	中京
#2	阪神1	阪神
```

<h3>解説</h3>
regex.subn()の使いとして、第一因数に正規表現を指定し、第二因数に正規表現に一致する文字を変更する文字の指定、第三因数に文字列を指定して使います。

以下の例では、30という数字を10に変更する方法を記載しています。
例:
```python
test_txt = "今日の天気は、30度"

"""
30度を10度に変更します。
正規表現としては、30という数字部分を一致させたいので、r'\d*'と指定します。
30を10に変更したいので、第二因数は"10"に指定します。

実行結果は、タプル型の値を返します。
一つ目の値としては、変更後の文字列を返します。
二つ目の値としては、正規表現に一致する個数を返します。
"""

print(regex.subn(r"\d+", "10", test_txt))
# ("今日の天気は、10度", 1)


"""
上では、正規表現をr"\d+"として連続する数値<を探すようにしていました。
下では、正規表現をr"\d"として数値を探すようにしました。
実行結果は、数字がある箇所に10に置き換えられるため、1010度となっています。
又、正規表現に一致する個数は、2個となっています。
"""
print(regex.subn(r"\d", "10", test_txt))
# ("今日の天気は、1010度", 2)
```



<h2>自身のまちがい</h2>
元々のコード

```python
print(df['開催場所'].str.split("\d+", expand=True))
#	0	1	2
#0		中山	
#1		中京	
#2	阪神		None


df["開催場所_new"] = df['開催場所'].str.split("\d+", expand=True)[1]
print(df)

#	開催場所	開催場所_new
#0	1中山2	中山
#1	11中京2	中京
#2	阪神1	
```

自身としてはpandasのstr.split()でいけると思っていたが、これだと先頭に数字がない場合には同じコラムに数字以外の文字が値が返されていません。
そのため、結合してもNoneとなる行が存在します。


<b>[参考資料]</b>
regexについて
https://note.nkmk.me/python-re-regex-character-type/
webページにカスタムCSSを導入する拡張機能を作ってみた

Qiitaへの投稿は初めてになります。Kendeaです。
クローム拡張機能を作ってみたので紹介をしたいと思います。

# 概要
- カスタムCSSを活用して、学校の通信アプリを改造したいと思った
- もともと、調べてみるとStylishという拡張機能を使っていた
- だけど、要素を調べながら書きたいから自分で作ろうと思った

## 作ったファイル
- manifest.json
- Classi-platform
  - script.js
  - style.css
- Google
  - script.js
  - style.css
- twitter
  - script.js
  - style.css
- YouTube
  - script.js
  - style.css


## コード
#### manifest.json
```json
{
  "name": "Vialdi CSS Import for Kendea",
  "author": "Kendea",
  "description": "chrome extension for customize CSS and JS.",
  "version": "1.0.0",
  "manifest_version": 2,
  "web_accessible_resources": ["*"],
  "permissions": ["storage"],
  "icons": {
   "48": "icons/48.png"
  },
   "content_scripts": [
    {
      "matches": ["https://www.google.com/*"],
      "css": ["google/style.css"],"js": ["google/script.js"]
    },
    {
      "matches": ["https://platform.classi.jp/group2/*"],
      "css": ["classi-platform/style.css"],"js": ["classi-platform/script.js"]
    },
    {
      "matches": ["https://www.youtube.com/*"],
      "css": ["YouTube/style.css"],"js": ["YouTube/script.js"]
    }
  ]
}
```

#### Classi-Platform/script.js
```javascript
consol.log("正式にインポートできています")
```
#### Classi-Platform/style.css
```css
@import url('https://fonts.googleapis.com/css2?family=DotGothic16&display=swap');


body{
    font-family: 'DotGothic16', sans-serif;
    background-image: url(https://img.freepik.com/premium-photo/digital-cyberspace-and-data-network-connections_24070-1044.jpg?w=2000);
}

#header{
    background-image: url(https://img01.jalannews.jp/img/2020/11/20201124_hoshizora_019.jpg)
}

#header .gNavi li {
    border-right: 0px!important;
}
.spen-ly-global-header {
    background-image: url(https://img01.jalannews.jp/img/2020/11/20201124_hoshizora_019.jpg)
}

.spen-ly-global-menu-list .menu-list-wrapper {
    backdrop-filter: blur(9px);
    background-color: rgb(98 98 98 / 11%);
}

.spen-ly-global-header .header-content {
    border-right: 0px!important;
}

.spen-ly-global-header .user-information .user-icon {
    border-radius: 34px;
    backdrop-filter: blur(9px);
}

.mod-message {
    display: block;
    color: blue;
    border: 1px solid #ccc;
    padding: 16px 13px 0;
    background-color:#c8e7fa;
    border-radius: 15px;
}

.group-item-list{
    background-color: rgb(255, 222, 172);
}

.new-item-list{
    background-color: #ccc;
    border: 1px black;
}

.header{
    background-color: blanchedalmond;
}
```

#### YouTube/script.js(雑)
```javascript
console.log("インポートできています")
```

#### YouTube/style.css(手抜き)
```css
*{
    color: #607d8b;
}
```

#### Google/script.js
```javascript
console.log("インポートできています")
```

### Google/style.css
```css
@charset "utf-8";

*{
  background: #333 !important;
}
```
## 最後に

現在掲載しているコードは三つのサイトと少ないですが、僕の[Github](https://github.com/kendea1221/custom-css-import-system-kendea)を見てもらうとわかるのですが、いろいろコードを載せているので持って行っちゃってください、
一応licenseはありますのでお読みください。

最期までありがとうございました
python gmail send mail

1. 
https://myaccount.google.com/security
Allow 2 step add app password
2. 
https://accounts.google.com/DisplayUnlockCaptcha

```Python
import os
import smtplib

def sent_gmail(user, password, send_to, subject=None, body=None):
   if isinstance(send_to, list):
      send_to = ', '.join(send_to)
   email_text = f'From: {user}\nTo: {send_to}\nSubject: {subject}\n\n{body}'

   try:
      server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
      server.ehlo()
      server.login(user, password)
      server.sendmail(user, send_to, email_text)
      server.close()
      return True, 'Success'
   except Exception as e:
      return False, str(e)

if __name__ == "__main__":
   user = "youremail@gmail.com"
   password = "apppassword"
   to = 'youremail@gmail.com'
   result, reason = sent_gmail(user, password, to)

   print(result, reason)
```
Let's try Qiita api v2 via curl of powershell

powershellにもcurlがあることを知りQiita apiを試してみた。
curlはInvoke-WebRequestのAliasなのでInvoke-WebRequestを試してみたといった方が正確なのだろう。
受け取ったJSON形式のデータはconvertfrom-jsonでPSCustomObjectの配列に変換する。

```powershell
PS >get-command  curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest

PS >$url = 'https://qiita.com/api/v2/items?page=1&per_page=10'
PS >$r = curl -URI $url
PS >$r | get-member


   TypeName: Microsoft.PowerShell.Commands.HtmlWebResponseObject

Name              MemberType Definition
----              ---------- ----------
Dispose           Method     void Dispose(), void IDisposable.Dispose()
Equals            Method     bool Equals(System.Object obj)
GetHashCode       Method     int GetHashCode()
GetType           Method     type GetType()
ToString          Method     string ToString()
AllElements       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection AllElements {get;}
BaseResponse      Property   System.Net.WebResponse BaseResponse {get;set;}
Content           Property   string Content {get;}
Forms             Property   Microsoft.PowerShell.Commands.FormObjectCollection Forms {get;}
Headers           Property   System.Collections.Generic.Dictionary[string,string] Headers {get;}
Images            Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Images {get;}
InputFields       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection InputFields {get;}
Links             Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Links {get;}
ParsedHtml        Property   mshtml.IHTMLDocument2 ParsedHtml {get;}
RawContent        Property   string RawContent {get;set;}
RawContentLength  Property   long RawContentLength {get;}
RawContentStream  Property   System.IO.MemoryStream RawContentStream {get;}
Scripts           Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Scripts {get;}
StatusCode        Property   int StatusCode {get;}
StatusDescription Property   string StatusDescription {get;}

PS >$c = ($r.content | convertfrom-json )
PS >$i = 0
PS >foreach ( $a in $c ){ Write-Host "[${i}]"  ${a}.title; $i ++ }
```
scriptにしておく。
```powershell:qiita.ps1
$url = 'https://qiita.com/api/v2/items?page=1&per_page=20'
$r = curl -URI $url
$c = ($r.content | convertfrom-json )
$i = 0
foreach ( $a in $c ){
    Write-Host "[${i}]"  ${a}.title
    $i ++
}
```
apiの利用には「1時間に60回まで」など制限事項があるので注意方。
※2022-10-26 どうにかmarkdown?に変更。
Pythonの特殊メソッド__getitem__の用例

# [公式ドキュメント](https://docs.python.org/ja/3/reference/datamodel.html#object.__getitem__)
*Called to implement evaluation of self[key].*

なるほど。オブジェクトに対して角括弧でkeyを指定したときの挙動を実装できるらしい。

# 用例


少し調べてみたがあまり良い例が見つからなかった。ところでPythonでは時々インスタンスのプロパティに動的にアクセスしたくなる時がある。

例えば以下のようなUserクラスに対して
```
import dataclasses

class User():
    age: int = 20
```
以下のようにプロパティageにアクセスしたいのだけれど
```
user.age
```
このageというプロパティ名自体を変数として表現したい場合だ。そのような場合はgetattrを用いると良い。

```
var = 'age'
getattr(user, var)
```

getattrについては本記事の本題から逸れるが以下の記事がわかりやすい。

https://www.yoheim.net/blog.php?q=20161002

ただ、アクセスのたびに毎回getattrという特殊メソッドを呼び出したくはないので、何らかの形でクラスの実装として組み込みたい。つまり

```
user[var]
```

のようなアクセスができるようにしたい。ここで、角括弧でkeyを指定したときの挙動を定義したくなったので、__getitem__をうまく活用してみよう。

```
class User():
    age: int = 20
    def __getitem__(self, item):
        return getattr(self, item)
```
これで
```
user = User()
var = 'age'
user[var]
```
のようなアクセスができるようになった。
【AWS初心者向け】5分でわかるCloudFront

# はじめに
「AWSのサービスを学ぼうと公式サイトを見たけど、よくわからなかった」という人は多いと思う。自分もAWSを本腰入れて勉強するまで、各サービスの特徴や出来ることの理解に時間がかかった。
~~だって[AWSの公式](https://aws.amazon.com/jp/cloudfront/)見ても用語とか意味がわからんのじゃもん！！！~~

最近仕事でCloudFrontを構築し、メリットや出来ることが理解できたため、復習も兼ねて記事を書いてみようと思った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554133/323ad42e-c7e4-7e47-aa29-08480f2edfab.png)


# CloudFrontとは
CDN（コンテンツ・デリバリ・ネットワーク）です。
そのまま言葉を飲み込めばよくて
- コンテンツ（画像・動画・ファイル など）を
- デリバリ（運んでくれる）
- ネットワーク

って感じです。


じゃあ具体的にどうコンテンツを運んでくれるの？ を理解すればCloudFrontの特徴が掴めます。


## 特徴1 : CloudFrontは世界中にエッジロケーションを持つ
エッジロケーションとはコンテンツをキャッシュしてくれるサーバーです。
これによって世界中どこにいても、**コンテンツを高速で取得**することが可能になります。
（AWS公式では、高スループット・低レイテンシーと表現されたりします。）

日本だと、東京・大阪にエッジロケーションがありますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554133/a9a3479d-0dca-53bf-a3a0-495e4e7c0922.png)
参照：https://aws.amazon.com/jp/cloudfront/features/?whats-new-cloudfront.sort-by=item.additionalFields.postDateTime&whats-new-cloudfront.sort-order=desc

## 特徴2 : 複数のリソースにアクセスできる
1つのドメインから、複数のリソース（S3やロードバランサーなど）に名前解決することができます。
聞くだけでは直感的にメリットを理解しにくい部分ですが、自分の現場ではこちらを目的としてCloudFrontを利用しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554133/889d462a-741a-9104-1930-475c85ac7591.png)

上の例で言うと、CloudFrontは２つのリソースへのアクセスを実現しています。
1. ```xxxx.cloudfront.net/page``` にアクセスした場合は ALBへ
2. ```xxxx.cloudfront.net/image/xxx``` にアクセスした場合は S3へ

このようなリソースへのアクセスは、```オリジン``` と ```ビヘイビア```と呼ばれるパラメータの組み合わせで作られます。

### オリジン
オリジンとは、CloudFrontからアクセスするリソースです。
下の例では、S3のリソースを指定したオリジンを作成しています。
![スクリーンショット 2022-09-19 14.05.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554133/74f67ab2-8caa-c0b5-7540-2f393b2bb468.png)

### ビヘイビア
上記オリジンへのアクセスパターンを決めるのが、ビヘイビアです。
下の例では、```/image/xxxx というパスでアクセスしたら、S3のオリジンに名前解決するよー```といったビヘイビアを作成しています。
![スクリーンショット 2022-09-19 14.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554133/25066e73-f39d-5a66-b763-a2b93b798e6b.png)

この状態で、```{cloudfrontのドメイン名}/image/xxxx```にアクセスすると、S3にアップロードされたファイルにアクセスすることができます。
こういった設定を追加することで、複数のリソースへのアクセスを可能にしていきます。

# まとめ
CloudFrontはCDN（コンテンツ・デリバリ・ネットワーク）

**特徴1 : CloudFrontは世界中にエッジロケーションを持つ**
　→ エッジロケーションにキャッシュを持たせることで、コンテンツを高速で取得できるようになります。
**特徴2 : 複数のリソースにアクセスできる**
　→ オリジン・ビヘイビアの組み合わせで実現する。

次回は実際にCloudFrontを立てて、S3にアクセスする部分をハンズオン形式で記事にしようと思います！
Googleスプレッドシートのquery内で年月で抽出する方法 

家計簿を作る段階で、年月で抽出する方法がわからず頭を抱えたのでここに残します。

問題解決は一瞬でした。

## 年月日をテキスト化
これだけでできました。

![スクリーンショット 2022-09-19 14.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846105/c269343f-0cb1-cc6c-8fb4-43f84c1fdc8b.png)

参照元の年月日の列を選択して、上記画像箇所で「書式なしテキスト」を選択、
そして、別スプシである抽出先の1セル目に以下の式を入れました。
~~~
=query(IMPORTRANGE("参照元スプレッドシートのURL","参照元スプシタブ名!B:H"),"select* where Col1 like '"&Q1&"%'",true)
~~~

「B:H」は参照範囲、参照元のB列にはテキスト化した年月日が入っていて、参照先Q1セルには
抽出したい年月「yyyy/mm」の形で入っています。
B列には「yyyy/mm/dd」の形で年月日が記載されているので、Q1セルと前方一致する抽出命令で年月抽出させています。

## 書式なしテキスト化がうまく行かない場合
抽出元の年月日が記載されるB2セルに以下の式を入れることでテキスト化して解決できました。(「B2」と2行目からにしてるのは、1行目にはタイトルが入ってるからです、範囲等は変更しちゃってくださいね)
~~~
=arrayformula(text(to_date(B2:B),"yyyy/mm/dd"))
~~~

参考にさせていただいた記事は次です。ありがとうございました。

https://pumpuppineapple.com/query-like/

https://pumpuppineapple.com/query-date/


## 余談
年ごと、月ごと、日ごと、もしくは年月日で抽出はできるのですが、
年月ごとが調べてもどうしてもできず・・・

初めはこんな感じで、
![スクリーンショット 2022-09-19 14.01.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846105/6298d9f5-6cba-ea7d-ebbb-def9b73557da.png)
年月だけの文字列の列「``=arrayformula(text(C2:C,"yyyymm"))``」をあたらめて作って、この列と一致するように抽出していたのですが、
やっぱり別の行作るのっていけてないよ〜〜〜と抗った末に発見。
それなりにスッキリした式になって満足です。
【OracleDB】パッケージの作成～ストアドとファンクションの定義

## パッケージの作成方法
従業員マスタを対象にデータを取得するストアドとファンクションを作成しました。

### 仕様部
```sql
create or replace NONEDITIONABLE PACKAGE pkg_emp AS

  --ファンクション
  FUNCTION get_emp_no(NAME IN VARCHAR2) RETURN VARCHAR2;
  --プロシージャ
  PROCEDURE get_emp_name(NO IN VARCHAR2, NAME OUT VARCHAR2);

END;
```

### 本体部
```sql
create or replace NONEDITIONABLE PACKAGE BODY pkg_emp AS


  FUNCTION get_emp_no(NAME IN VARCHAR2) RETURN VARCHAR2
  -- 宣言部
  IS
    wk_no VARCHAR2(50);
  -- 処理部
  BEGIN
    SELECT
    EMPNO INTO wk_no
    FROM EMP
    WHERE EMPNAME = NAME;
    
    RETURN wk_no;

  END get_emp_no;
  
  FUNCTION get_emp_gender(NAME IN VARCHAR2) RETURN NUMBER
  -- 宣言部
  IS
    wk_gender NUMBER;
  -- 処理部
  BEGIN
    SELECT
    GENDER_F INTO wk_gender
    FROM EMP
    WHERE EMPNAME = NAME;
    
    RETURN wk_gender;

  END get_emp_gender;

  PROCEDURE get_emp_name(NO IN VARCHAR2, NAME OUT VARCHAR2)
  -- 宣言部
  IS
    wk_name VARCHAR2(50);
    wk_no VARCHAR2(50);
    wk_gender NUMBER;
  -- 処理部
  BEGIN
    SELECT
    EMPNAME INTO wk_name
    FROM EMP
    WHERE EMPNO = NO;
    
    wk_no := get_emp_no(wk_name);
    wk_gender := get_emp_gender(wk_name);
    NAME := wk_name;
    DBMS_OUTPUT.PUT_LINE(wk_gender);
    DBMS_OUTPUT.PUT_LINE(wk_no);
    DBMS_OUTPUT.PUT_LINE(NAME);

  END get_emp_name;
END pkg_emp;
```

## 補足
以下の点に気を付けないとエラーに悩みます。
・仕様部で定義したストアドとファンクションの引数が本体部とも一致していること
・引数と同じ変数名を定義していないこと
・selectしてきた値と代入先の変数の型が一致していること

※仕様部と本体部のパッケージ作成は分けて実行したほうが良いです。
　定義が重複しているエラーなのか、処理の記載ミスなのかの判断が遅くなります。
UnityとMadMapperとプロジェクションマッピング

# プロジェクションマッピングに憧れて

簡易なものでいいからということで実施することになり、ちょっと調べてみた。

## Syphon

:::note info 
Syphonとは？
macOS向けOSS。
静止画・動画をリアルタイムで共有できるようになるため、MadMapperなどに送出できる
:::

ググると2つほど出てくるが、KlakSyphonの方がメンテされ続けているっぽいので、KlakSyphonで試してみた。
Apple siliconもサポートされている

https://github.com/Syphon/Unity3D/releases

https://github.com/keijiro/KlakSyphon/releases


#### 1. KlakSyphonをダウンロード

ダンロードして解凍しておく

#### 2. Unityプロジェクト作成

- 3D
- Syphonをインポート

###### インポート


解凍したフォルダを丸ごとAssetsにドラッグ＆ドロップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/8f141fa9-2c19-5fcb-6a23-35b9244c76c9.png)


###### Main Cameraにコンポーネント追加

`Syphon Server`を追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/ba80b9c7-fc67-5308-9807-3a7ed0db8f3a.png)


###### Unityプロジェクトの実行

Unity側はこれで準備OK


#### 3. MadMapper

###### Syphon

Syphonに`Unity - Main Camera`が表示されるので選択すると、MadMapper内のオブジェクトにUnity側の画面がリアルタイムに送信される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/f9c05a82-7b3e-a983-bfb3-015fa56b8c20.png)

###### プロジェクタ出力を設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/b0900900-afc8-a95f-80e6-eb16435c19e2.png)

###### フルスクリーンモード

フルスクリーンモードにすることでと選択したプロジェクタに投影される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/0846da15-b7dd-6a31-154e-2b7a66c0c0d4.png)






# 以下メモ：Unity エディタをVSCodeに

## Unityの設定

External Script EditorでVSCodeを指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/f62ca180-8d0b-0e89-f8f4-e2522ce95749.png)



## VSCodeの設定

###### monoがインストールされていなければインストール。


```
brew install mono
```

settings.json で設定を変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/da83ef6a-423a-bb30-6c77-1ea3db39b9a7.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/4ef3c2f4-d666-451a-5f4a-8b73da138b53.png)

###### Extensions

C#のExtensionをインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/c1097326-ca5b-f536-7baf-d49e95097f8b.png)


無事に補完が効きました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/3db3e2b1-7af8-f788-6c07-ee7835871114.png)



## 参考

#### VSCode Pythonライブラリのエラー表記

必要なライブラリは pip install済みの認識だったが、以下の通り赤い波線が。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/c6489e92-06af-96a6-d1da-d3d934369456.png)

VSCodeでアクティブなインタプリタを切り替える。（自分の場合はpyenv-virtualenvを使用）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/0c50a861-6505-e6be-98f4-c61fe0c7b4dd.png)

無事に認識されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/68602240-0476-4e0e-06b2-a16aba0f0196.png)





- [Unity動画再生](https://xr-hub.com/archives/15798)
- [Syphon](https://qiita.com/sada_lp1/items/c892aeb3462b86bcd469) 
- https://qiita.com/asus4/items/6c4f8b2a0c681eb54a4a
ソリューションアーキテクト対策_AWSとActiveDirectory篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:


## ActiveDirectoryを利用する時のAWSサービス×3
### AWS Directory Service Simple AD
AWS側にスタンドアロンのフルマネージド型のADを新規作成する時に使うサービス。簡易なディレクトリサービスを起動することができる。
ユースケースはAWSの仮想デスクトップサービスなどへのアクセスを外部ユーザーに許可する際に利用される。
※ADとIAMの統合には利用できない

スモールは最大500ユーザー、ラージは最大5000ユーザー。


### AWS Directory Seveice AD Connector
オンプレのADとAWSのIAMを統合する。AWS側のIAMのディレクトリ・リクエストをゲートウェイがオンプレ側のADにリダイレクトする、ディレクトリゲートウェイである。
AWS SSOと連携したシングルサインオンが可能。
ADとロールに割り当てられたIAMポリシーに基づいてユーザーのAWSサービスへのアクセスを制御する。


### AWS Managed Microsoft AD
一番パワーのあるADで、最大50000ユーザーの管理が可能。
AWS側にADとの互換性があるフルマネージド型のADを作成。SSOが使える。
AWSにディレクトリをセットアップして実行したり、AWSリソースを既存のオンプレミスADに接続可能。


## おわりに
引き続き追記します。

簡単ですが以上です。
PediaRouteを使った探索的テストトレーニングゲーム

# やったこと
[PediaRoute](https://pediaroute.com/)と言うページを使うと、ウィキペディアのある単語ページAから、ある単語ページBまでにどんなリンクをクリックしてたどり着けるかを教えてくれる。

例えば、「きゅうり」から「ソフトウェアテスト」までを調べてみると、、

![スクリーンショット 2022-09-19 13.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211061/821499bb-3be2-9836-7bf7-09b7a6d6a8ba.png)

きゅうりには、セレンと呼ばれるミネラルが含まれており、
セレンのページにはSelenium（ソフトウェア）の曖昧さ回避のリンクがあり、
Seleniumからソフトウェアテストにたどり着くとのこと。

他の単語もいくつかやってみましたが、たどり着けない単語ページはないんじゃないかなってぐらい。
なんかこれって探索的テストのトレーニングに使えそうだなと思いました。

# やり方
参加人数：1人以上

1.適当な単語ページA、単語Bを決める（日本語ウィキペディアに単語ページがあることは確認しておくこと）
2.よーいスタートでAからBまで実際にウィキペディアを操作して、どのリンクをクリックしたかを記録しながら進める
3.一定時間経過後、以下のルールで点数をつける。下にいくほど点数が高い。

    -単語Bにたどり着けそうだったか（正解が4リンクに対して、2リンクは合っていたとか）
    -単語Bにたどり着けたか
    -単語Bにたどり着けていれば、リンク数はいくつか（少ない方が良い、PediaRouteで出てくるリンク数が最小とする）
    
4.1〜3を繰り返して、点数がより多く入手できた人が勝ち。

# 感想
・１つの記事へのリンクが多いほど、どこから進めるかは個人のカンによるので、考え方の違いが楽しめる。
・単語の特性をより良く知っている人が強そうにも見えるが、思いもよらぬ方向から単語Bにたどり着けることもありそうで、意外性がある。
 　例えば、きゅうり→ワニまでたどり着くのに、
　「きゅうり」→「古代エジプト」→「ナイル川デルタ」→「ナイルワニ」→「ワニ」(4リンク)でまぁまぁかなと思っていたら、
　「きゅうり」→「千葉県」→「三重県」→「ワニ」（3リンク)というようなやり方もある。
typescriptでデザインパターン（Factory Method)

# Factory Methodをtypescriptで書いてみた。

## クラス図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193053/1109e043-982d-29a3-3ebb-5bddd49261a6.png)

## コード
```typescript
abstract class Product {
    public abstract use(): void
}

abstract class Factory {
    public abstract create(owner: string): Product
}


class IdCardFactory extends Factory {
    create(owner: string): IdCard {
        return new IdCard(owner)
    };
}

class IdCard extends Product {
    owner: string;
    constructor(owner: string) {
        super();
        console.log(`${owner}さんのカードを作ります`)
        this.owner = owner;
    };
    public use(): void {
        console.log(`${this.owner}のカードを使います`)
    }
}



function main() {
    const idFactory = new IdCardFactory();
    const fooId = idFactory.create('foo');
    fooId.use();
}

main()

```

## 出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193053/2fb7b18c-9dfb-b98e-3e0a-ffb593d32c95.png)


## 参考文献
* [TECHSCORE](https://www.techscore.com/tech/DesignPattern/FactoryMethod)
Ruby On Rails で 主キーに UUID を使用する

# Ruby On Rails とは？
- Ruby On Rails (以下、Rails)については[こちら](https://ja.wikipedia.org/wiki/Ruby_on_Rails)をご確認下さい。

# UUID とは何か？
- UUID とは **Universally Unique IDentifier** のことで普遍的な一意の識別子のことを指す。

# なぜ Rails で主キーに UUID を使用するのか？ 
- 例えば MySQL であれば主キーに **AUTO_INCREMENT** を使用するケースが多いと思いますが、そうすると該当ページへアクセスする場合、 Rails では URL が `https://example.com/users/1` というようになってしまい、 **1** の部分が **2** だったらどうなのか、 **10**、**100** だったらどうなのか・・・というような感じで簡単に推測されてしまいます。
- [cancancan](https://github.com/CanCanCommunity/cancancan) や [pundit](https://github.com/varvet/pundit) のような権限管理 gem を使用することで URL が推測されてもアクセス不可にさせることもできますが、認証/認可していることが前提となってしまう為、例えばログインはしなくてもいいけれど URL を知っている人だけにアクセスさせたいというようなことができません。
- そこで、今回は URL を知っている人だけにアクセスさせることを実現できるようにしつつ、URL を推測できないようにする為に主キーに UUID を使用します。
該当ページへアクセスする場合の URL が `https://example.com/users/9332ba51-d7de-4661-acb9-a1b481917dd4` のようになり、推測不可能になります。

# ソースコード
- **app/models/concerns/uuid_module.rb** を作成して下記のように記述する
  - 各々のモデルで使用したい為、モジュール化して concerns/ 配下に配置
  - 何らかの理由で id が存在しないテーブルに対して create してもエラーにならないように `has_attribute?(:id)` を行い、 id が存在する場合のみ uuid を生成する
  - 滅多にないが生成された id が既に存在した場合は再生成する
```ruby
module UuidModule
  extend ActiveSupport::Concern

  included do
    before_create :generate, if: -> { has_attribute?(:id) }
  end

  def generate
    self.id ||= loop do
      uuid = SecureRandom.uuid
      break uuid unless self.class.exists?(id: uuid)
    end
  end
end
```
- **app/models/application_record.rb** の上部へ **include UuidModule** を記述
```ruby
class ApplicationRecord < ActiveRecord::Base
  include UuidModule

  # ...
end
```

## 留意事項
- マイグレーションの際には主キーは必ず36文字の文字列が保存可能な型にする
```ruby
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users, id: :string, limit: 36 do |t|
    # ...
    end
  end
end
```

# まとめ
- 上記のようにすることでデータ新規保存の際には id が推測不可能な文字列になり、該当ページへアクセスする際には冒頭述べたような `https://example.com/users/9332ba51-d7de-4661-acb9-a1b481917dd4` になります。
  - 該当ページがない場合は `$ rails g scaffold_controller user` などで作成後、レコードを新規作成した上で詳細ページへアクセスしてみて下さい。
プレイリストシステム②

## 初めに
[前回](https://qiita.com/wawon1111/items/0ba1eb451edc166ca6e4)までに簡単なアプリの画面イメージとAWSのアカウント開設・初期設定まで行いました。かなり雑ですが、[プレイリストシステム①の記事](https://qiita.com/wawon1111/items/8b7bfaddbd8f0a15d4d8)での画面イメージなどを機能要件として今回は非機能要件を定義していきたいと思います。

## 非機能要件とは
まず簡単に非機能要件とはについて簡単にまとめます。

非機能要件とは、その名の通り「機能以外のすべての要件」のこと。
性能や可用性、セキュリティなどの「必要とする機能以外の要件」を指す。

構築したシステムが顧客の希望する機能をすべて実装していたとしても、処理の性能が悪かったり、障害から復旧するのに時間がかかったりなどでは運用に耐えられないので、これらについても要件をしっかりと定義することが大事。

### 非機能要件で定義すべき項目
①可用性
　システムが継続して利用できるかどうかです。
AWS上では可用性を高めるために片AZがダメになった時に別のAZにもサーバーを構築したりします。このシステムでも複数AZに跨る構成とします(マルチAZ)

②性能・拡張性
　システムの処理性能および拡張に関する要件です。構築するシステムで処理するトランザクション数や利用ユーザー数、負荷などを決めます。また、将来のキャパシティ・プランニングを検討します。

そんな凝ったアプリは作らないのでほぼほぼ自分しかアクセスが来ない想定で以下の数字を想定しました。

ピーク時
利用ユーザー数:2人/1時間
トランザクション数:20/1時間

③運用・保守性
システムの運用・保守に関する要件です。システムの監視方法やバックアップ方法、問題発生時の体制などを決めておきます。

監視はec2、rdsの標準的なメトリクスを取得します。
バックアップはec2、rdsを週1回とります。書きながら思ったんですが、ec2に関してはアプリの回収やインストールされているソフトなどサーバーに対して何かしら変更を加えない限り必ずしもしなくてもよいのかな？と思ったのでこれもまた調べてみます。

運用については商用システムではないので一旦スルーとさせていただきます。

④移行性

現行システムからの移行に関する要件です。新システムへ移行するための移行期間、移行体制、移行リハーサルなど、移行計画についての要件を定義します。

現行のシステムがあるわけではなく、新規にaws上に構築するので以降に関しては今回考慮しなくて大丈夫そうです。

⑤セキュリティ

システムのセキュリティ確保について定義します。アクセス制限や不正検知・監視の方法、システム運用者に対する情報セキュリティ教育について定義します。

セキュリティソフトは使用せずawsサービスを使ってアクセス制御やDDOS対策などを行っていきたいと思います。また、運用者のセキュリティ教育も商用ではないので一旦スルーで。

⑥環境・エコロジー
システムを設置する環境・エコロジーに関する要件を定義します。環境負荷を低減する構成や、電気設備・規格の適合性について定義します。

今回はaws上にシステムを構築するのでこちらでは実際の設備は触れることができないのでこちらも特に考慮はしない事にします。

https://products.sint.co.jp/obdz/blog/nonfunctionalrequirements

## まとめ
ざっくりでしたが今回はシステムの要件を決めました。実際の要件定義は顧客の要望だったり、クラウドにシフトする際は現行のシステムの要件だったりを考慮する必要がありますが個人で勉強ついでに作るので色々とざっくりでした。
次回はこの要件をもとにaws上でどういった設定をするかの方式設計とパラメータシートの中間みたいなイメージの項目を決めていきたいと思います。
R で閏年判定

# 1.　tis パッケージを使う。

```R
> library(tis)
> isLeapYear(c(2020, 2022, 2100, 2400))
[1]  TRUE FALSE FALSE  TRUE
```
isLeapYear は以下の関数定義

```R
isLeapYear <- function (y) 
{
    y%%4 == 0 & (y%%100 != 0 | y%%400 == 0)
}
```
---
# 2.　lubridate パッケージを使う。

```R
> library(lubridate)
> leap_year(c(2020, 2022, 2100, 2400))
[1]  TRUE FALSE FALSE  TRUE

引数に Date オブジェクトも使える。
> leap_year(as.Date(c("2020-09-29", "2022-09-19", "2100-09-19", "2400-09-19")))
[1]  TRUE FALSE FALSE  TRUE
```
leap_year は以下の関数定義

```R
leap_year <- function (date) 
{
    if (is.numeric(date)) {
        year <- date
    }
    else {
        year <- year(date)
    }
    (year%%4 == 0) & ((year%%100 != 0) | (year%%400 == 0))
}
```
---
# 3.　結論

他にもあるかもしれないが，基本は `y%%4 == 0 & (y%%100 != 0 | y%%400 == 0)`
【React】チェックボックスのデザインを画像に変更する方法


# やりたいこと
チェックボックスを画像にする
・押下したらアイコンの色を変える
・複数選択可能
### デフォルト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2553351/1ed043ec-0eab-d78b-dc02-fec624859c1f.png)
### これにしたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2553351/7304484b-97a9-41ee-c782-1808a13a17bb.png)
### 選択時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2553351/54c82f20-0863-a0bd-6c86-44c6ad67ff2e.png)

# 準備
アイコン画像は、src/public/imgに格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2553351/43fd2ba1-f39f-847d-fa0d-b28807717d80.png)

# コード
```React:App.js
import "./styles.css";
import React, { useState } from "react";

const unCheckIconPath = "./img/ic_check.png";
const checkedIconPath = "./img/ic_checked.png";

const listItems = [
  {
    id: "checkbox1",
    title: "Apple"
  },
  {
    id: "checkbox2",
    title: "Orange"
  },
  {
    id: "checkbox3",
    title: "Banana"
  }
];
export default function App() {
  const [selected, setSelected] = useState({});

  const confirmCheck = (e) => {
    setSelected({
      ...selected,
      [e.target.id]: e.target.checked
    });
  };
  const changeIcon = (item) => {
    return selected[item.id]
      ? (item.icon = checkedIconPath)
      : (item.icon = unCheckIconPath);
  };
  return (
    <div className="App">
      {listItems.map((item, index) => (
        <label key={index}>
          <span className="is-flex">
            <img
              className="width-40"
              src={changeIcon(item)}
              alt={item.id}
            />
            <input
              className="is-hidden"
              type="checkbox"
              id={item.id}
              onChange={confirmCheck}
              checked={selected[item.id]}
            />
            <span className="is-flex is-align-items-center">{item.title}</span>
          </span>
        </label>
      ))}
    </div>
  );
}

```



## 参考にさせていただいたサイト
[React hooks で複数のcheckboxを実装してみる](https://qiita.com/seira/items/ccdb70b63cdce097aeb3)
Markdown テキストをボックスで囲む

## ■ はじめに
Markdownのテキストをボックス（四角）で囲む方法です。
[マークダウンのメモ用のテキストボックスを作成するにはどうすればよいですか？](https://qastack.jp/programming/25654845/how-can-i-create-a-text-box-for-a-note-in-markdown)
の記事を試したものです。
※元ネタの記事(執筆者：浅尾 貴子　[遅い夜ご飯でも太らない方法！ダイエット中の遅い時間の夜ご飯](https://allabout.co.jp/gm/gc/67897/))
## ■ 前提
* Windows 10 以上のOS
* VSCode(ver 1.7.1.2)
* VSCode拡張機能 Markdown Preview Enhanced(ver:3,354,209)

## ■ 元ネタの文章
### ①
<b>私達のカラダには「体内時計」をつかさどるタンパク質があります。それが脂肪を溜め込んだり積極的に燃焼したりと、時間によって働き方に違いがあることがわかっています。
※ 榛葉繁紀、大野俊治、手塚雅勝（日本大学薬学部）の研究による</b>

### ②
<b>このタンパク質はBMAL1（ビーマルワン）と呼ばれています。それが働くと、夜22時頃から急激に脂肪を溜めやすくなり、深夜2時～4時が脂肪蓄積のピークになるのだそう。逆に午後の15時くらいが最も少なく、最も脂肪になりやすい深夜との差は、何と約30倍なのだとか！</b>

### ③
<b>また残念な事に、肥満傾向にある人ほど、昼間のBMAL1の値までもが高いままの傾向にあるとも言われています。この働きに従う場合は、夜20時くらいまでに夕食を食べるのが良いと言われています。</b>

## ■ テキストにボックスを付けてみる

### ①
|私達のカラダには「体内時計」をつかさどるタンパク質があります。それが脂肪を溜め込んだり積極的に燃焼したりと、時間によって働き方に違いがあることがわかっています。|
|:-|

### ②
|このタンパク質はBMAL1（ビーマルワン）と呼ばれています。それが働くと、夜22時頃から急激に脂肪を溜めやすくなり、深夜2時～4時が脂肪蓄積のピークになるのだそう。逆に午後の15時くらいが最も少なく、最も脂肪になりやすい深夜との差は、何と約30倍なのだとか！|
|:-|

### ③
|また残念な事に、肥満傾向にある人ほど、昼間のBMAL1の値までもが高いままの傾向にあるとも言われています。この働きに従う場合は、夜20時くらいまでに夕食を食べるのが良いと言われています。|
|:-|

## ■ Markdownの記述方法

### ①
```
|私達のカラダには「体内時計」をつかさどるタンパク質があります。それが脂肪を溜め込んだり積極的に燃焼したりと、時間によって働き方に違いがあることがわかっています。|
|:-|
```
### ②
```
|このタンパク質はBMAL1（ビーマルワン）と呼ばれています。それが働くと、夜22時頃から急激に脂肪を溜めやすくなり、深夜2時～4時が脂肪蓄積のピークになるのだそう。逆に午後の15時くらいが最も少なく、最も脂肪になりやすい深夜との差は、何と約30倍なのだとか！|
|:-|
```

### ③
```
|また残念な事に、肥満傾向にある人ほど、昼間のBMAL1の値までもが高いままの傾向にあるとも言われています。この働きに従う場合は、夜20時くらいまでに夕食を食べるのが良いと言われています。|
|:-|
```

## ■ Markdownのテキストにボックスを付けるテクニック

* 左寄せ
```
|テキスト|
|:-|
```

* 中央寄せ
```
|テキスト|
|-|
```

* 右寄せ
```
|テキスト|
|-:|
```

# まとめ
Markdownのテキストにボックスで囲むテクニックです。表の見出しを作る方法でできました。
自己研究してみました。以外と簡単にできます。
Boomi】最先端iPaaSソリューション を資格取得しながら触ってみる

弊社がパートナーをやらせていただいているiPaaSソリューションのBoomiのご紹介です。

## Boomiとは？
Boomiとはエンタープライズ企業が保有・管理する多種多様なシステムおよびアプリケーションの統合を可能とするインテグレーション・サービス（iPaaS）です。Boomiの保有する各ソリューションは『Boomi AtomSphere Platform』として提供されています。今回はその中でも『[Integration](https://boomi.com/platform/integration/)』というサービスについて触れていきたいと思います。

せっかくなので著者が保有するBoomi資格『Professional Developer Certification』を取得するまでの学習内容に沿ってBoomi Integrationの機能を紹介していきたいと思います。



*Boomiの各資格はboomiverseというDell Boomi社が提供している無料のオンライントレーニングを通して取得できます。学習コンテンツも豊富で質も高いです。

 

## 触ってみる。
Boomi Integrationでは下図のようなBuildタブをWebブラウザで表示しながら、GUIで各コンポーネント（プロセス・シェイプなど）を作成してくイメージです。

![Flow1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6544/16232e35-60e0-1d53-af7b-0dfd55dc0283.png)


上図はProfessionalのひとつ前の資格であるAssociate Developerの学習コンテンツで実際に作成するプロセスになります。

上図プロセスではSalesForceに接続し一定の条件でフィルターした企業情報を取得し、条件分岐を実施した後にTrueの結果のレコードに対してはフォーマットを整形してDBにレコードをインサートしています。

 

もうひとつプロセス例を見てみましょう。こちらはProfessional Developerのコース内容です。

![Flow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6544/04ad24f0-9f28-e75a-4116-6907514d7b7a.png)


こちらのプロセスではBoomiでWebサービスを作成しています。Boomiでは他アプリに対して自らデータを取得する（＝リクエスト投げる）ことに加えて、Webサービスを作成することでデータを受信（＝リクエストを受ける）ことも可能です。イベント・ドリブンのアーキテクチャにも対応できるというわけです。

 

もちろんBoomiからAPIリクエストをコールすることもできます（下図）。

![Flow3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6544/39c2490a-b82d-f00f-02b2-dfde463c5949.png)


## 感想と考察
今回ご紹介したのはBoomi Integrationで実装できるほんの一部の機能でしたが、実利用を想定したより複雑なビジネスロジックや、一般的なエラーハンドリング、作成済みの他プロセスを複利的に利用（Process Call）したりすることもできます。また、今回の例は１対1システムの統合でしたが、多：多のシステム統合を実施する時にはBoomiキャンバス上で視覚的にシステム間の接続が把握できるのは大きな利点かと思いました。またSalesForceだけでなくOracleやSAPなどのERP、AzureやAWSなどのクラウドサービスとの接続に利用するコネクターも利用可能であり、それらのサービスを利用している企業にとっても使い勝手のよいサービスだと思いました。

複数システムが複雑に組み合わさったエンタープライズ企業にとって、今後のシステム統合を進めて行く上でBoomiは一つの切り札になる可能性が高いと感じています。

Go Boom it!