OmniAICreator/Qiita-1.07M huggingface dataset:
システム開発の種類について

就職活動を行っていく中、毎回さまざまなIT用語が出てきて
日々勉強です。
エンジニアといっても仕事内容は多岐に渡るようです。

そんな中、本日はシステム開発の種類についてまとめてみました。


### web系
web系とは、Webサイトを構築するシステムやアプリケーションを開発するエンジニアのこと。
ECサイトやSNS、不特定多数が利用掲示板などに利用される。
何度も訪れて利用するリピーターを獲得する点が重視される分野で活躍しする。
わかりやすく、インパクトのあるサイトを開発できる力が必要

### モバイル系
携帯電話やスマートフォン専用のサイトなどを開発する仕事。
かつては、パソコン用と携帯電話用でサイトが分けられて作られていたが、現在は同じwebサイト
に統合されることが多くなってきた。
現在は、スマートフォンアプリとの連携などの仕事に移行してきた。

### オープン系
業務系のアプリケーションを開発するための仕事。
業務の効率化やコストダウンに役立つシステムの開発を行う。
特徴は企業の業務環境に合わせて独自のシステムを構築していく仕事が多いこと。
オーダーメードのシステムを組んでいくことになるわけで、より専門性が問われる部分がある。

### 汎用系
汎用機と呼ばれる大型のコンピューターのシステム開発を行う職種。
伝統ある企業を中心に大型のコンピューターを導入し、現在でもメインのコンピューターとして活用しているところは少なくない。
この汎用機では膨大なデータが蓄積され、処理されているのが特徴、これを問題なく機能し続けるよう保守・再構築などを行うのが汎用系のおもな仕事内容になる。

### 制御系
機械の制御を行うためのシステム開発がおもな仕事。
スマホ、カメラ、自動車、電子レンジなど安全性も含めた制御機能が重要な意味を持つ家電製品で制御系のシステム開発を行う。

### 運用管理・保守
現在稼働しているサーバやネットワークの安全性と安定性を守お仕事。
「運用」とはサーバやネットワークの性能を保全し、さらに最適化または性能を向上させるための業務。これに対し「保守」とは故障対応やセキュリティパッチの実施、バックアップなどでトラブルに備え、万が一トラブルが発生した際に速やかな回復を行うための業務。
例えばバックアップの計画や設定を行うのは運用管理の仕事で、実際にバックアップを行うのは保守の仕事。

### 制御・組み込み系
ハードウェアの中にプログラムを組み込んでいく仕事。
例えば工場の生産ラインや、あるいは道路の信号などの設備や機械は、あらかじめ「こういった動きをする」というプログラミングがされており、これを「制御」と言う。
身近でいうとオートマ自動車など。

### パッケージソフト・ミドルウェア開発
自社でソフトを開発して製品として売り出す会社のプログラマー。
例えば会計ソフトや人事給与ソフト、経理ソフト、あとは顧客管理ソフトなどの開発。

### 社内情報システムエンジニア
自分たちでツールやシステムを開発することもあるが、社内のIT環境に関する総務的な役割になることが多い。
業務用ソフトの導入に際しては、ソフトを開発している会社とやりとりして比較検討したり、発注や納品なども担当する。



こんなにたくさんあるんですね！！
それぞれ求められる能力だったり、知識は違うらしいので
興味あるものについては、しっかり勉強することが大切だと感じました。
VDI

#背景
- Horizon Cloud on Azure with WVDとHorizon Cloud on Azureの違いがよく分からない
- 調べているとそもそもAzure VMとAzure WVDの違いも分からない





#本題（結論）
https://cloud.nissho-ele.co.jp/vdiblog/horizoncloud_with_wvd/

これがわかりやすかった。
- Horizon Cloud on AzureはコントロールプレーンがSaaSのVMware Horizon
- WVDはコントロールプレーンがAzure管理
- Horizon Cloud on AzureとHorizon Cloud on Azure with WVDの違いは、前者がAzure VMの払い出し、後者がWVDの払い出し




#経緯（これを読む）
https://www.cloud-for-all.com/blog/horizon-cloud-on-azure

Azure推しがきつくて眩しいが、これによると…
- Horizon Cloud on AzureとWVDがDaaS
- Azure VMは単体VM
- Horizon Cloud on Azureはライセンスとして、1. VMware Horizonのライセンス、2. Azure費用、3. Windowsライセンスが必要
- WVDはAzure費用にまとめられる


#経緯（つぎにこれを読む）
https://vmware-juku.jp/solutions/wvd-horizoncloud-azure-nw/

つぎはVMware推しがきつ・・きつ・・・やめて・・・
- WVDはマルチセッション
- Azure VMはシングルセッション
- Horizon Cloud on Azure with WVDはコントロールプレーンはHorizonのままでWVDを操作する


#あとでよむ
https://www.cloudou.net/vmware/hzn010/
R shiny でデータの基礎分析用アプリの作成①

# はじめに
R shiny でアプリを作ってみた（詳細は[こちら](https://qiita.com/ryamamoto0406/items/1bc520c39729b2e1a9b7)）があまりにもシンプルであったため、もう少し、複雑なものを作ってみたいと思い取り組んだ。内容としてはcsvファイルを読み込んで、データの基礎分析（統計量の計算、可視化等）を自動で行えるようなアプリを開発したい。長くなりそうなので、テーマごとに分けて記事を書いていきたいと思う。

# 使うデータの準備
まずは[こちらの記事](https://qiita.com/ryamamoto0406/items/489e00fe693b688a4a5e)で作成した人の性別、身長、体重、血液型があるデータを取り扱いたいと思う。記事の通り1000人分のデータを作成したら、それを csv ファイルに出力する。

```R:
> str(df)
'data.frame':	1000 obs. of  4 variables:
 $ SEX   : chr  "female" "male" "male" "male" ...
 $ HEIGHT: num  154 178 163 176 156 ...
 $ WEIGHT: num  48 70.8 48.2 76.4 40.9 ...
 $ BLOOD : chr  "O" "A" "A" "O" ...
> write.csv(df, "./data.csv")
```

これで使用するデータが用意できた。

# ファイルの読み込みと表示
まず基礎となるファイルを読み込んで表示するアプリを作成する。

```R:app.R
# Load packages ----
library(shiny)


# Source helpers ----


# User interface ----
ui <- fluidPage(
  titlePanel("Basic analysis"),
  
  sidebarLayout(
    sidebarPanel(
      fileInput("file",
                label = "File input",
                accept = c("text/csv"),
                multiple = FALSE,
                width = "80%")
    ),
    
    mainPanel(
      dataTableOutput("outFile"),
    )
  )
)

# Server logic
server <- function(input, output) {
  
  inFile <- reactive({
    tmp <- input$file
    if (is.null(tmp)){
      return(NULL)
    } else {
      df <- read.csv(tmp$datapath, header=TRUE)
      return(df)
    }
  })
  
  output$outFile <- renderDataTable({
    data.frame(inFile())
  })

}

# Run the app
shinyApp(ui, server)
```

これを実行し、data.csvを読み込ませると、

![analysis_app_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/661e6ae7-10f5-b1ba-9850-b335850711ba.png)

となりデータテーブルの表示ができた。

# タブの作成
mainPanel に tabsetPanel を加えて書き換える。タブごとにデータ、統計量、可視化を変えれるように作成する。タブの中身については次の記事で書いていこうと思う。

```R:app.R
# Load packages ----
library(shiny)


# Source helpers ----


# User interface ----
ui <- fluidPage(
  titlePanel("Basic analysis"),
  
  sidebarLayout(
    sidebarPanel(
      fileInput("file",
                label = "File input",
                accept = c("text/csv"),
                multiple = FALSE,
                width = "80%")
    ),
    
    mainPanel(
      tabsetPanel(type = "tabs",
                  tabPanel("Data", dataTableOutput("outFile")),
                  tabPanel("Statistic", h1("Statistics value")),
                  tabPanel("Visualize", h1("Plot"))
      )
                  
    )
  )
)

# Server logic
server <- function(input, output) {
  
  inFile <- reactive({
    tmp <- input$file
    if (is.null(tmp)){
      return(NULL)
    } else {
      df <- read.csv(tmp$datapath, header=TRUE)
      return(df)
    }
  })
  
  output$outFile <- renderDataTable({
    data.frame(inFile())
  })

}

# Run the app
shinyApp(ui, server)
```
![analysis_app_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/7ca7738f-4f0c-7c3c-d877-460c5022068b.gif)


# おわりに
次の記事ではタブの一つである基礎統計量の算出と表示を行いたいと思う。

[R shiny でデータの基礎分析用アプリの作成②](https://qiita.com/ryamamoto0406/items/ef72ed9b0fdbbbda929d)
embulkでSSL Inspection環境下でplugin install

# 概要


`embulk gem install hogehoge`を実施しようとするとこんな感じで怒られた

```
$ embulk gem install embulk-parser-grok
2021-03-05 13:26:25.684 +0900: Embulk v0.9.23

Gem plugin path is: /Users/***/.embulk/lib/gems

ERROR:  SSL verification error at depth 1: unable to get local issuer certificate (20)
ERROR:  You must add /OU=GlobalSign Root CA - R3/O=GlobalSign/CN=GlobalSign to your local trusted store
ERROR:  While executing gem ... (OpenSSL::SSL::SSLError)
    certificate verify failed
```

社内環境だとよくあるSSL Inspectionが間に挟まっていて、
OSにはそのためのroot証明書がインストールされているがRuby, PythonといったCLI上で実行するものはうまく読んでくれないケースがちょいちょいある。


# えいやで解決

embulkに同梱のjrubyでも、gemの設定自体は`$HOME/.gemrc`を参照する模様
証明書を指定する方法もありそうだが、一旦証明書検証を無効化

```$HOME/.gemrc
~~~省略 下記を追記~~~
:ssl_verify_mode: 0
```

これで証明書検証が無効になり、エラーがでなくなった

その他、下記のように証明書の場所を指定することもできるようだが、
私の環境ではうまく反映できなかったので諦めの境地

```
:ssl_verify_mode: 1
:ssl_ca_vert: /path/to/ca-certificates.crt
```
VSCodeでSvelte+bluma(scss)の環境を作る

##はじめに
　この記事はSvelte(TypeScript)+Bulma(scss)+C#(WEB.API)でSPAの認証が必要なアプリの構築をする手順を試した最初の記事になります。
　順次記事を作成し、最終的に上記の環境構築手順になればいいかと思っています。（途中で投げ出したらごめんなさい）

##Svelteのひな型作成
　[Svelteのホームページ](https://svelte.dev/)にあるように、「npx degit sveltejs/template my-svelte-project」でカレントフォルダの下に「my-svelte-project」という名のフォルダを作成してひな型を起こすのですが、VSCodeで実行するのであれば、先に作成したフォルダをVSCodeの「フォルダを開く」で開き、「新しいターミナル」を開いて「npx degit sveltejs/template」とするとそのフォルダに直接ひな型を作ってくれます。

##Bulmaとnode-sassの取り込み
　VSCodeのターミナルから「npm install bulma --save-dev」を実行すると「node_modules」フォルダにbulmaが追加されます。さらに「npm install node-sass --save-dev」を実行してnode-sassをインストールします。

##Sass(scss)ファイルの作成
　[Bulmaのカスタマイズのページ](https://bulma.io/documentation/customize/with-node-sass/)にbulmaのカスタマイズとnode-sassを利用したcssへの変換手順があります。これを参考に、以下の「src/mystyles.scss」ファイル（ファイル名は自由に変えてください）を作成します。

```scss:src/mystyles.scss
@charset "utf-8";

// Import a Google Font
@import url('https://fonts.googleapis.com/css?family=Nunito:400,700');

// Import only what you need from Bulma
@import "../node_modules/bulma/sass/utilities/_all.sass";
@import "../node_modules/bulma/sass/base/_all.sass";
@import "../node_modules/bulma/sass/elements/button.sass";
@import "../node_modules/bulma/sass/elements/container.sass";
@import "../node_modules/bulma/sass/elements/title.sass";
@import "../node_modules/bulma/sass/form/_all.sass";
@import "../node_modules/bulma/sass/components/navbar.sass";
@import "../node_modules/bulma/sass/layout/hero.sass";
@import "../node_modules/bulma/sass/layout/section.sass";
```

　ここでは変数の変更はしていません。変更したい場合はBulmaのホームページを参考に変更してください。

##scssファイルの変換
　package.jsonに以下の２つのエントリーを追加してください。「--output-style compressed」はbulmaのホームページにはありませんが、ファイル圧縮です。


``` json:package.json
 // "scripts"に以下の２つのエントリーを追加する。

  "css-build": "node-sass --omit-source-map-url src/mystyles.scss public/global.css --output-style compressed",
  "css-watch": "npm run css-build -- --watch"
```

　設定した「package.json」を保存して、VSCodeのタスクの実行で「npm:css-build」を実行すると、「global.css」がbulmaのカスタマイズしたものに置き換わります。基本的にはタスク実行で「npm:css-watch」を実行して「src/mystyles.scss」が書き換わるごとに自動で変換するのがいいかと思います。

##Bulmaの拡張
　Bulmaはclassを利用したフレームワークで、タグには依存しません。また、複数のファイルに分かれていて必要なもののみ利用できるようになっています。しかしながら、設定が分かれているため、classの記述が長くなるのも事実です。開発では特定のパターンを利用することが多いので、先に作った「src/mystyles.scss」の後ろに、複数のクラスをまとめたクラスを作ることで短くできます。

```scss:src/mystyles.scss

...

.primeButton{
    @extend .button;
    @extend .is-primary;
}
```

を追加して、svelteファイルで以下のようにすると、

```html:App.svelte
<button class="primeButton">テスト</button>
```
「class="is-prime button"」が短縮できます。よく使う長い設定はこれでまとめると楽だと思います。

##私が作ったツールの宣伝
　svelteファイルを編集しているとhtmlの見た目の確認を何度もしたくなると思います（俺だけかなー）。そのたびにコンパイルを実行すると結構めんどくさくなります。そこで、前回の記事「[VSCodeでsvelteファイルのインスタントビュワー拡張を作ってみた](https://qiita.com/nosa67/items/501e779459dac8f707be)」にある拡張機能を利用すると、ちょっと便利かと思います（ブラウザの表示は初回のみ少し時間がかかりますが、２回目以降はすぐに表示されます）。注意事項としては、「public/index.html」の「&lt;link rel='stylesheet' href='/global.css'&gt;」は「&lt;link rel='stylesheet' href='global.css'&gt;」と、パスの最初のスラッシュ(/)を外してください。ローカルファイルを開いているのでルート相対パスはドライブルートになってしまい、「global.css」が参照できません。
【Laravel】Seedデータファイルを作るコマンド 


```
php artisan make:seeder UserTableSeeder
```
USerTableSeeder.phpファイルをつくることができる。

```php
<?php

use Illuminate\Database\Seeder;

class USerTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}
```
コマンドで作られたファイルの中身はこのような記述になっている.
証明書のインポート時に「ストアが読み取り専用か･･･」のエラー

## 発生した問題
* Windows10のIE11でルート証明書をインポートしようとしたところ
「ストアが読み取り専用か、ストアがいっぱいか、ストアが正しく開かなかったため、インポートができませんでした」
というエラーが発生してインポートに失敗する
* IEを管理者として実行してもインポートエラーになる
* ユーザーはドメインに参加していて、Administrator権限を持たせているものの失敗する

## 解決に至った手順
```msshell
C:\Windows\System32\certlm.msc
```
を「管理者として実行」してインポートすると成功しました。
* certmgr.msc では解決出来ませんでした
RedHat8でXMindを使用する

環境:
Red Hat Enterprise Linux release 8.3
kernel:5.10.16-1.el8.elrepo.x86_64

epelのリポジトリを使用できるようにする。
参考手順：
https://rheb.hatenablog.com/entry/2019/08/16/EPEL8がリリースされました。使い始めましょう。

以下、snapdおよびxmindインストールコマンドを実行
sudo dnf install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo dnf install libXScrnSaver.x86_64
sudo snap install xmind

※以下のURLの手順にて、snap-storeを先にインストールし、その後snap-storeからXMindをインストールする方法の方が、今後のsnapcraftからのソフトウェアのインストールが容易になります。
https://snapcraft.io/install/snap-store/rhel

プログラムのアイコンにて、XMindのアイコンが表示されるのでクリックして起動します。

参考：
How to install XMind on Red Hat Enterprise Linux
https://snapcraft.io/install/xmind/rhel

Snap(Snappy) コマンドの使い方
https://mekou.com/linux-magazine/snapsnappy-コマンドの使い方/

XMindの起動の起動方法
https://ameblo.jp/kurabeat/entry-10530453938.html

フォアグラウンドジョブ、バックグラウンドジョブ
https://www.infraeye.com/study/linuxz17.html
https://kazmax.zpp.jp/linux_beginner/jobs_fg_bg.html
【QA・障害001】Azure Portalで表示名が文字化け（チェコ語）

# Azure Portalで表示名が文字化け（チェコ語）

以下はLBの画面になりますが、日本語設定だと一部表記がチェコ語となっており読めません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111921/53673088-84df-919e-80ec-8889d32450e3.png)

英語に変えることで英語表記にはなりなんとか進めることはできます。ちょっと困りますよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111921/a160ad52-c83b-cd7b-3a85-03e97a8cdf5f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111921/ee82e064-258a-5d44-e23d-f2c21ceaa53e.png)
【Swift】シングルトンを1分で理解する


##シングルトンとは

初期化処理を内部に梱包することで、外部から初期化しないようにし、
データを保持することのできる記法。
タスクキルしない限りデータを保持し続ける。
破棄(再初期化)されないので画面遷移してもデータが保持される。
言い換えればタスクキルでデータは消えるので
ローカルにデータを保存したい場合は、使えない。

```Swift
class Singleton {
    var name:String = ""
    //内部に梱包>>
    static let shared = Singleton()
    private init() { //何も初期化しない
    }
    //<<
}
```

##使い方
```Swift
print(Singleton.shared.name) //""
Singleton.shared.name = "hoge"
print(Singleton.shared.name) //"hoge"
//...画面遷移
print(Singleton.shared.name) //"hoge"
```
Linuxコマンド 〜もしスペース入れてファイル名やディレクトリ名を作ってしまった時の削除方法〜

**初投稿！**

学習記録やメモ書き目的で始めることにしました！
web開発をちょろっと学んでいましたが色々あって今はインフラ関連を中心に学習しております。ほぼ初学者レベルなので理解が浅いところや誤りがあるかと思いますがよろしくお願いします。またアドバイス等コメントいただけるとすっごく嬉しいです。
早く先輩方のお力になれるよう精進します。
では本題！



#もしスペース入れてファイル名やディレクトリ名を作ってしまったら・・・

これ、tarコマンドでディレクトリをアーカイブしていた時
「あ！スペース入れちまった！」って実際に私がやってしまったことです。



スペース付きのファイル名なんて聞いたことないし、あったとしても絶対扱いづらい。まずそもそもそんなミス（？）を皆様しないと思いますが。

消そうと思っても普通に

```
#rm fi le
```

なんてやってももちろん削除されません。そりゃ「fiファイル」と「leファイル」
って認識されるので当たり前ですね。



##削除の仕方！

```
#rm "fi le"
```

これだけです！
ダブルクォーテーションで囲むだけ！

””で囲ったら文字列として認識されちゃうのかな〜と思いながらもやってみたら出来ました。真相はわかりませんが、rmコマンド自体がファイルとディレクトリを対象としているから””で囲ってもファイル名などとして認識してくれるのですかね。


##ちなみに

```
#rm "fi le"
```

で削除出来たってことなので

```
#touch "fi le"
```

でも「fi le」ファイルが作れますw
ちゃんとcatコマンドで「fi le」名として作られているか確認しました。

いや、絶対使わなーーーい。


はい、以上！！
[ubuntu20.04]電源ボタンでPCをシャットダウン

# 手順
bashを開いて
`hostnamectl set-chassis vm`
でOK。コマンド実行直後より、PCの電源ボタンを押すとOSのシャットダウンが始まる。

# 環境
- Ubuntu20.04LTS
- OS起動後にPC筐体の電源ボタンを押すと、電源OFF確認のダイアログが表示される。マウスでクリックしないと電源OFFできず不便である。 

# その他
- hostnamectlコマンドを他で使用したことがない。。。電源ボタンの挙動以外にどんな影響が出ているかわからないです。。。

# 参考サイト
[power button on ubuntu20.04LTS](https://nmori1984.net/2020/11/03/power-button-on-ubuntu20-04lts/)
scssの導入の仕方

まずscssを使うにはrubyをインストールする必要があります。
rubyをまだ導入していない場合はまずはそちらから導入していきましょう！
導入が終わったという体で進めていきます👍

#scssフォルダを作りましょう！
私はVSコードを使っているのでそちらを使って進めていきます👍

#①saccフォルダを作る
vsコードをダウンロード終わったら、フォルダを作成していきます。
作成が終わったら、index.htmlファイルを作り、cssフォルダ、scssフォルダを作ればとりあえず終わりです👌

#②ターミナル
次にターミナルを使っていきます。

```
% cd Documents
% ls
% cd Sass
```
この状態にしておきましょう。（scssフォルダの中にいる感じ）

#③cssファイルの中に記載して行きます！

```style.scss
main {
  width: 90%;
  p {
    font-size: 14px;
  }
}
```
前回の記事でも説明したように、index.html の親要素と子要素の関係のようにそれに伴って、入れ子のように記述していきます。
ちなみに拡張子はstyle.scssです。

#④再びターミナル

ではではターミナルをいじっていきます！前回のターミナルですでにsassファイルの中にいますのでそのまま進めていきます！！

```
% sass scss/main.scss:css/main.css #scssをcssに変換する
% less css/main.css #main.cssに展開されていく
% sass ---style expanted scss/main.scss:css/main.css  #構造がわかりにくい場合に使うようです。
% less css/main.css #再び展開
```
*less~を行うとターミナル上にend文字出てきてうち込みできなくなるので、[;qw]を押すと画面がまた入力状態に戻ります！！
ただこのやり方なかなかめんどくさいなと思ったかた、省略しちゃいましょうか👍

```
% sass --style expanted --watch scss:css

```
これで完了です！
終了する場合はコントロール＋cです！！👍
AWS環境で分析基盤構築のちょっとした話

#はじめに#
エキサイトのL&C事業部ではオンプレ環境からクラウド環境に順次に移行しております。その中にオンプレOracleのデータベース移行は最も難易度が高いです。ここで２つの選択肢があります
- ①オンプレOracle → AWS Oracle
- ②オンプレOracle → AWS PosgreSQL

表題通り分析基盤についてお話ししたいので、AWS環境のRDS（Oracle/PostgreSQL）からどうやって分析基盤を構築するのか紹介したいと思います。

#実現したいモデル#

![okr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536217/e01d1a19-52e6-f019-5934-133531b5e782.png)

ゴールは、RDSからRedshiftにデータ転送の際に、個人情報が含まれるデータをハッシュ化したり、不要なデータを削除したりします。また、面倒なバッチを書きたくないので、フルマネージド型のETLサービスのGlueを選択しました。

#実際に検証してみる#

##AWS PostgreSQL → Redshiftへデータ転送##

結論から話せれば、Glueで結構簡単に実現できまました。場合によって若干Glueジョブのスクリプトに手を加えることもありますが、以下のようにほぼほぼいけます。

- STEP1：AWS PostgreSQL上に分析用のユーザーとViewを作成します。
- STEP2：AWS Glue上にCrawlerがPostgreSQLのViewを参照して、Data Catalogテーブルを作成できます。
- STEP3：AWS Glue上にジョブを作成して、データソースにPostgreSQLのData Catalogテーブルを指定、ターゲットにRedshiftを指定すれば、自動でRedshift側にテーブルが作成され、データが転送されます。

##AWS Oracle → Redshiftへデータ転送##

このケースの大きな問題は、AWS Glue上にCrawlerがOracleのViewを参照できないのです。公式ドキュメント上にはっきりとできないと書いていないが、AWS担当者に問い合わせしたところ、実現ができないと回答していただきました。ここで２つの選択肢があります。

- AWS Glueのジョブから直接にOracleのViewを参照するように実装
- OracleのViewを経由せずに、直接にOracleのテーブルを参照する。不要なデータ削除や個人情報のハッシュ化などは、Glueのジョブで実装します。

#結論#

AWS Oracle → Redshiftへデータ転送のケースは、OracleのViewを経由せずに直接にGlueジョブのスクリプトに手を加えた方が幸せだと考えます。
AWS SAMテンプレートでAPI Gatewayに独自ドメインを使う

SAMテンプレートを使って、API Gateway + Lambda(Python3.8) で作成したAPIに、独自ドメインを使ってアクセスできるようにしたい、ということでカスタムドメインとパスマッピングの設定をしました。


公式ドキュメント
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-api-domainconfiguration.html

前提
- ドメインをRoute53で管理している（HostedZonIdがある）
- SSL証明書をACMで管理している（ARNを持っている）


```template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: custom domain api

Parameters:
  Stage:
    Type: String
    Default: Prod
  BasePath:
    Type: String
    Default: v1
  DomainName:
    Type: String
  HostedZoneId:
    Type: String
  CertificateArn:
    Type: String

Resources:
  MyApiRole:
    Type: AWS::IAM::Role
    Properties: # 省略

  GetConvertFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/get_hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Role: !GetAtt MyApiRole.Arn
      Events:
        HttpGet:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref MyApi
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Stage
      Domain:
        DomainName: !Ref DomainName
        CertificateArn: !Ref CertificateArn
        EndpointConfiguration: EDGE
        Route53:
          HostedZoneId: !Ref HostedZoneId
        BasePath:
          - !Ref BasePath
```
Capybara::ElementNotFound:エラーの解決【結合テスト】

#結論
デベロッパーツール（検証モード）を使って、対象となるfieldのname属性の値を調べ、その値をfill inの要素にする。

（変更前）

```spec/system/users_spec.rb
fill_in 'メールアドレス', with: @user.email
```
↓
（変更後）

```spec/system/users_spec.rb
fill_in 'user[email]', with: @user.email', with: @user.email
```


**検証画像**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/8705dd2c-b07a-f701-58a4-8a746830b2e4.png)



#この記事の内容
system Specを用いて結合テストコードをする際、テスト実行コマンドを実行すると、Capybara::ElementNotFound:エラーが出ました。

そのエラーを解決する方法とプロセスを記事にしています。

#エラーの概要

**エラー画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/8b0f032a-fc8d-d15d-f7ca-a11b8a2b81e8.png)

**エラーの和訳**
"Email"は無効となっている。というのも、使用できないものであるから。

#テストコードの内容

```spec/system/users_spec.rb
require 'rails_helper'

RSpec.describe 'ユーザー新規登録', type: :system do
  before do
    @user = FactoryBot.build(:user)
  end
  context 'ユーザー新規登録ができるとき' do 
    it '正しい情報を入力すればユーザー新規登録ができてトップページに移動する' do
      visit root_path
      expect(page).to have_content('新規登録')
      visit new_user_registration_path
      fill_in 'メールアドレス', with: @user.email #←問題の箇所
#〜省略〜
```

#エラー解決までのプロセス
##①エラーを見る

**エラー画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/8b0f032a-fc8d-d15d-f7ca-a11b8a2b81e8.png)

"Email"が無効となっているので、使用できない。
ということはfieldの名称が異なるものをテストコードで記述していることがわかる。

##②検証ツールで確認

**検証画像**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/97444ecd-60c9-ff14-9d3e-90e7ea699abc.png)


やっぱり違うものになっている。

##③テストコードの記述を変更する。

（変更前）

```spec/system/users_spec.rb
fill_in 'メールアドレス', with: @user.email
```
↓
（変更後）

```spec/system/users_spec.rb
fill_in 'user_email', with: @user.email
```

無事エラー解決がしました。

#エラーを超えて、完成したテスト
完成したテストコードについて以下記事にしています！
よろしければご覧ください！

https://qiita.com/narimiya/items/22d52976ee848c6952c4

以上です。
Goで自作のパッケージをインポートする

自分用にメモ

「スターティングGo言語」を進めていましたが、Goモジュールのサポートを使って自作パッケージをインポートしてみたかったのでやってみました。
Goのバージョンは1.13以上にしてください
###go env
```bash:terminal
$ go env GO111MODULE
on
```
###ディレクトリ構成
```
zoo
├── animals
│   ├── elephant.go
│   ├── monkey.go
│   └── rabbit.go
└── main.go
```

###animalsパッケージ
呼び出すと食べ物を返す

```elephant.go

package animals

func ElephantFeed() string {
	return "Grass"
}
```

```monkey.go

package animals

func MonkeyFeed() string {
	return "Banana"
}
```

```rabbit.go

package animals

func RabbitFeed() string {
	return "Carrot"
}
```

###mainパッケージ
```main.go
package main

import (
	"fmt"
	"go_mod/animals"
)

func main()  {
	fmt.Println(animals.ElephantFeed())
	fmt.Println(animals.MonkeyFeed())
	fmt.Println(animals.RabbitFeed())
}
```

###go.modの作成
```bash:terminal
zooディレクトリで
$ go mod init go_mod
go: creating new go.mod: module go_mod

確認
$ cat go.mod
module go_mod

go 1.15
```

###go buildの実行
```bash:terminal
$ go build /hoge/zoo/main.go
```

###go run main.go
```bash:terminal
$ go run main.go
Grass
Banana
Carrot
```
CSVHelper ver 25.0 -> 26.1 チェンジログ

[CSVHelper](https://joshclose.github.io/CsvHelper/) の情報共有です。

CSVHelper 26.1 が出ました。26.0 が主なリリース版で、26.1 で軽微な修正が行われています。
修正点は次の通りです。

* config クラスで ExceptionMessagesContainRawData がデフォルトで true になりました。
* 全てのクラスで init プロパティが削除されました。
* ヘッダレコードに含まれる例外メッセージが改善されました。

また、前バージョンとの互換性に影響がでる変更があります。

1. IParserConfiguration に bool ExceptionMessagesContainRawData { get; } が追加されました。
* IWriterConfiguration に bool ExceptionMessagesContainRawData { get; } が追加されました。
* 全てのデリゲートオブジェクトから init メソッドが削除され、パラメータを指定できるコンストラクタが追加されました。対象は次の通りです。
 1. BadDataFound
 * ConvertFromString
 * GetConstructor
 * GetDynamicPropertyName
 * HeaderValidated
 * MissingFieldFound
 * PrepareHeaderForMatch
 * ReadingExceptionOccurred
 * ReferenceHeaderPrefix
 * ShouldQuote
 * ShouldSkipRecord
 * ShouldUseConstructorParameter
 * Validate

コンストラクタでパラメータ指定してインスタンス化出来る方が、コードが直感的になっていいと思います。
開発者の方々に感謝です。

なお、オリジナルはこちらから参照できます。
https://joshclose.github.io/CsvHelper/change-log/


**26.0.1**
**Bug Fixes**

 * Fixed issue with constant not working when the field is missing.

**26.0.0**

**Features**

* Added configuration for ExceptionMessagesContainRawData that defaults to true.

**Bug Fixes**

* Removed all init properties. These were causing people too many problems.
* Fixed issue with exception message not containing the header record.

**Breaking Changes**

* Added bool IParserConfiguration.ExceptionMessagesContainRawData { get; }.
* Added bool IWriterConfiguration.ExceptionMessagesContainRawData { get; }.
* All delegate args objects have init removed and now have constructors with parameters.
 * BadDataFound
 * ConvertFromString
 * GetConstructor
 * GetDynamicPropertyName
 * HeaderValidated
 * MissingFieldFound
 * PrepareHeaderForMatch
 * ReadingExceptionOccurred
 * ReferenceHeaderPrefix
 * ShouldQuote
 * ShouldSkipRecord
 * ShouldUseConstructorParameter
 * Validate
RailsのDockerイメージの作り方

## 0. はじめに

以下のようなディレクトリ構成にします。

```console
.
├── app/       # Railsアプリ
└── docker/    # Dockerfile置き場
    └── app/
        └── Dockerfile
```

## 1. ローカル環境にRailsをインストール

```console
% rails new app
```

## 2. Dockerfileの作成

```dockerfile:docker/app/Dockerfile
# syntax=docker/dockerfile:1.2

# base
FROM ruby:3.0.0-alpine3.13 AS base
WORKDIR /app
RUN \
  --mount=type=cache,target=/var/cache/apk \
  apk add -U \
    build-base \
    git \
    nodejs \
    sqlite-dev \
    tzdata \
    yarn \
    ;

# bundle
FROM base AS bundle
COPY Gemfile Gemfile.lock /app/
RUN \
  --mount=type=cache,target=/app/vendor/cache \
  bundle install && \
  bundle cache

# yarn
FROM base AS node_modules
COPY package.json yarn.lock /app/
RUN \
  --mount=type=cache,target=/usr/local/share/.cache/yarn/v4 \
  yarn install

# main
FROM base
ARG RAILS_MASTER_KEY
ENV RAILS_MASTER_KEY $RAILS_MASTER_KEY
COPY --from=bundle /usr/local/bundle/ /usr/local/bundle/
COPY --from=node_modules /app/node_modules/ /app/node_modules/
COPY . /app/
EXPOSE 3000
CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
```

## 3. .dockerignoreの用意

不要なファイルをイメージに含めないために.dockerignoreを作成します

```:app/.dockerignore
/.bundle/
/.dockerignore
/.git/
/.git*
/.ruby-version
/README.md
/config/master.key
/log/
/node_modules/
/storage/
/tmp/
/vendor/bundle/
```

## 4. Dockerイメージのビルド

```console
% DOCKER_BUILDKIT=1 docker image build --build-arg RAILS_MASTER_KEY=<RAILS_MASTER_KEY> -t boccifarm/rails:6.1.3-ruby3.0.0-alpine3.13 -f docker/app/Dockerfile app
```

## 5. Dockerイメージのプッシュ

```
% docker login
% docker image push boccifarm/rails:6.1.3-ruby3.0.0-alpine3.13
```
gcalcliでの表示カレンダーの同期方法

googleカレンダーでカレンダーを追加・削除・非表示を行ってもgcalcliの方で同期が自動で行われず，調べても出てこなかったので備忘録として残しておきます．

## 環境
- Ubuntu 20.10
- gcalcli v4.3.0

## 解決方法
$HOME/.gcalcli_cache を削除するだけでした．
ここに同期するカレンダーの情報が書かれていて，作成時以降更新されないみたいです．
git checkout -bについて

git checkoutのオプション-bについて忘れないように。

#git checkout -b
ブランチ作成とブランチに移動を一つにまとめたコマンド

```bash
git checkout -b test 
```
つまり

```bash

git branch test
```
```bash

git checkout test
```
と等価

#ブランチ系のコマンドを一応整理

リポジトリ内のブランチの確認

```bash
git branch
```

ブランチ作成

```bash
git branch {ブランチ名}
```
ブランチ削除

```bash
git branch -D {ブランチ名}
```
ブランチに移動

```bash
git checkout {ブランチ名}
```
amplifyの作法 その23

#概要

amplifyの作法、調べてみた。
練習問題やってみた。

#練習問題

aさん、bさん、cさん、は、仲が良いので、同じことをすると気分が良い。
みんなが、気分が良くなる、組み合わせを選べ。

#評価関数を組み立てる。

求める組み合わせを考える。

|aさん|	bさん|	cさん|	評価|
|:--|:--|:--|:--|
|歩く|	歩く|	歩く|	ok|
|歩く|	走る|	歩く|	NG|
|走る|	歩く|	歩く|	NG|
|走る|	走る|	歩く|	NG|
|歩く|	歩く|	走る|	NG|
|歩く|	走る|	走る|	NG|
|走る|	歩く|	走る|	NG|
|走る|	走る|	走る|	ok|

評価関数

H = (a - b) ** 2 + (b - c) ** 2

a,b,cは、[1,0]をとる。
a=1,b=1,c=0の場合は、1
a=1,b=1,c=1の場合は、0

#式を展開して、イジングモデルをつくる。

sympyを使う。

```
from sympy import *

a, b, c = symbols("a,b,c")
f = (a - b) ** 2 + (b - c) ** 2
print(f)
f4 = str(expand(f))
print(f4)
f5 = f4.replace('**2', '')
print(f5)
f6 = str(simplify(f5))
print(f6)
f7 = f6.replace('a', 'q[0]').replace('b', 'q[1]').replace('c', 'q[2]')
print(f7)
```

求めた、イジングモデル。

-2*q[0]*q[1] + q[0] - 2*q[1]*q[2] + 2*q[1] + q[2]

#amplifyに投入。

```
from amplify import (BinaryPoly, BinaryQuadraticModel, gen_symbols, Solver, decode_solution, )

q = gen_symbols(BinaryPoly, 3)
f = -2*q[0]*q[1] + q[0] - 2*q[1]*q[2] + 2*q[1] + q[2]
print(f.asdict())
model = BinaryQuadraticModel(f)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}") 
```


以上。
Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code

こんなエラーが出たときには、

```elixir

defmodule Sample.Sample.Sample do

+ alias __MODULE__

end
```

を追加してみる。

参考：
https://elixirforum.com/t/compilation-error-in-file/29351
Bitwarden on AWS 環境構築

# 概要 Outline(TL;DR)
パスワード管理ツール`Bitwarden`のサーバー機能をCloudFormationでAWS上に構築する。

## 目的 Purpose
- いつも利用しているパスワード管理ツール`Bitwarden`の機能理解のため。
- 現在勉強中のAWSの各種サービス群の中でも、個人的に重要視している`CloudFormation`のサービス理解のため。

## 前提条件 Requirements
- 利用者は自分自身のみの想定。
- どのAWSアカウントにおいても再現性高く環境再構築が出来るようにIaC化する。
- 何かあった場合を考慮してすぐに環境を破棄できるようにする。
- Githubに成果物を登録する。
- コンテナ型仮想化技術を取り入れる。
- スクラム開発の手法を取り入れて進める。
- AWS請求料金を低額に抑える。1000円/月までを目安とする。
- セキュリティ対策のWAF導入は別途。

## 環境 Environments
- AWS
  - AWSアカウント
  - Amazon Virtual Private Cloud
  - AWS Identity and Access Management
  - AWS CloudFormation
  - Amazon Elastic Container Service
  - Amazon Simple Storage Service
  - Amazon CloudWatch
  - AWS Auto Scaling

## 段取り Steps
1. 計画
    1. Trelloサインアップ
    2. [Trelloボード新規作成](https://trello.com/b/AKvmN4q5/bitwarden-on-aws "Bitwarden on AWS")
    3. スクラム開発用のリスト構成
    4. プロダクトバックログ作成
    5. スプリントバックログ選定
1. 実施
    1. AWS構成要素の洗い出し
    2. [AWS構成図作成](https://app.diagrams.net/?splash=0&libs=aws4#Hmo1022%2Faws-cloudformation-bitwarden-portfolio%2Fmain%2Fdocuments%2Faws_diagram.drawio "draw.io")
    3. CloudFormationのAWS公式ページにて開始手順の確認
    4. [CloudFormationテンプレート(ECS, YAML形式)](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-ecs.html "template snippets")の検索
    5. GitHubにテンプレートYAMLファイルコミット
    6. AWSアカウントにてテンプレートからスタック作成できるかプレビュー(IAM権限確認)
    7. BitwardenのDockerコンテナが無いか検索
    8. YAMLテンプレートを構成図に合わせて改修
    9. __Work In Progress__

## 参考 Reference
- [Bitwardenインストール版 システム要求仕様](https://bitwarden.com/help/article/install-on-premise/#system-specifications "Bitwardenインストール版 システム要求仕様")
- [【無料】bitwardenをawsにserverlessでセットアップする](https://qiita.com/ycrack/items/436e07b69cd92c6be565 "【無料】bitwardenをawsにserverlessでセットアップする")
- [Amazon Virtual Private Cloud](https://aws.amazon.com/jp/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc "VPC")
- [AWS Identity and Access Management](https://aws.amazon.com/jp/iam/ "IAM")
- [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/ "CloudFormation")
- [Amazon Elastic Container Service](https://aws.amazon.com/jp/ecs/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc&ecs-blogs.sort-by=item.additionalFields.createdDate&ecs-blogs.sort-order=desc "ECS")
- [Amazon CloudWatch](https://aws.amazon.com/jp/cloudwatch/ "CloudWatch")
- [Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/ "S3")
git pushしたら、! [rejected] main -> main (fetch first) error: failed to push some refs to "リモートリポジトリ名" で怒られた。

# 原因
下の流れで作業したため怒られました。

### ①mainからブランチを切って作業

```terminal
$ git checkout -b 作業ブランチ
```
のち、色々実装して、push

### ②　①と並行して、githubのmainブランチのreadmeの内容を変更
※ここが不味かった

### ③mainチェックアウト

```terminal
$ git checkout main
```
### ④作業ブランチをマージ

```
$ git merge 作業ブランチ
```

### ⑤mainブランチをpush
```
$ git push
```
ここで```! [rejected] main -> main (fetch first) error: failed to push some refs to "リモートリポジトリ名"```と怒られる。


# 対処法
$ git pull すれば、解決はするのですが、そもそもgitの構造を理解していなかった。

### 追跡ブランチの存在
リモートのmainとローカルのorigin/mainは別物ということを知らず、全く意識していませんでした。

ローカルのorigin/mainは、追跡ブランチと呼ばれているそうで、リモートのmainブランチを追跡しています。
pushする際に、リモートブランチをローカルの追跡ブランチに差分があると、（共通のコミット上に異なるコミットが追加されている状態)、pushできない。
今回、push出来なかったのは、リモート側のブランチに余計なコミットがあったため、push出来なかった。

### git pullするとどうなるのか
git pullすると、リモートのブランチの内容が追跡ブランチに反映されます。そうすることで、差分がなくなり、pushできるようになります。

### おまけ
git pullだけでもいいですが、省略せずに書くと、このようになります。

```
$ git pull origin main:main
# git pull <ローカルのブランチ名>:<リモートのブランチ名>
```
OpenCVで画像を回転＋保存

# 概要
PythonのOpenCVで画像を回転させ，保存するプログラムを作ってみました．
CNNの学習で，データ拡張に使いました．

# 開発環境
- Windows10
- Python ver3.7.7
- OpenCV ver3.4.1

# コード
~~~python
import cv2
import os
import glob

def main():
    
    img_files = glob.glob('*.jpg')

    for f in img_files:
        img = cv2.imread(f)
        fname, fext = os.path.splitext(f)

        height, width, channels = img.shape
        center = (int(width/2), int(height/2))
        
        #回転のテンプレ
        #trans = cv2.getRotationMatrix2D(center, angle , scale)
        #90度回転
        trans1 = cv2.getRotationMatrix2D(center, 90 , 1.0)
        #アフィン変換
        image_1 = cv2.warpAffine(img, trans1, (width,height))
        cv2.imwrite(fname+"_90.jpg", image_1)
        
        #180度回転
        trans2 = cv2.getRotationMatrix2D(center, 180 , 1.0)
        #アフィン変換
        image_2 = cv2.warpAffine(img, trans2, (width,height))
        cv2.imwrite(fname+"_180.jpg", image_2)

        #270度回転
        trans3 = cv2.getRotationMatrix2D(center, 270 , 1.0)
        #アフィン変換
        image_3 = cv2.warpAffine(img, trans3, (width,height))
        cv2.imwrite(fname+"_270.jpg", image_3)        
        

if __name__ == "__main__":
    main()
~~~
10行目あたり（for f ～のところ）のコードは，同じフォルダー内の画像（このコードではjpg）を全部読み込むものです．
transは画像の回転です．image_は，回転を画像に反映させて，cv2.imwriteで画像の保存をします．
このコードでは，画像を90度，180度，270度回転させてます．
最後の2行のif文は，画像の読み込みでforがエラーした時のものらしいです（自分はあんまりわかってません）．

# 出力される画像
入力した画像はこちらです．
<img width="200" alt="kakuseiki_businesswoman_smile.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177046/004cbaa2-d71e-61fc-ffef-78d6fc9b5665.jpeg">
出力された画像はこちらです．
<img width="200" alt="kakuseiki_businesswoman_smile_90.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177046/7f8ca3ef-d187-d796-81bf-6d951735df78.jpeg">　　<img width="200" alt="kakuseiki_businesswoman_smile_180.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177046/e49494be-28c7-84ca-9947-aa66249b5ed8.jpeg">　　<img width="200" alt="kakuseiki_businesswoman_smile_270.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177046/09cc9be8-f699-b3a9-c653-7ea8599359ad.jpeg">

画像が正方形ではない場合は，黒い部分が発生してしまうので，縦横の大きさが等しいものにしか使えないです．

#おまけ
読み込ませる画像のファイル名に全角の文字が含まれているとエラーが出ます．
(OpenCVは全角文字を含むファイルは読み込めないんですかね？)
amplifyの作法 その22

#概要

amplifyの作法、調べてみた。
練習問題やってみた。

#練習問題

aさん、bさん、cさん、は、0を選んだ。

#評価関数を組み立てる。

評価関数

H = (a + b + c) ** 2

a,b,cは、[1,0]をとる。
a=1,b=1,c=0の場合は、1
a=0,b=0,c=0の場合は、0

#式を展開して、イジングモデルをつくる。

sympyを使う。

```
from sympy import *

a, b, c = symbols("a,b,c")
f = (a + b + c) ** 2
print(f)
f4 = str(expand(f))
print(f4)
f5 = f4.replace('**2', '')
print(f5)
f6 = str(simplify(f5))
print(f6)
f7 = f6.replace('a', 'q[0]').replace('b', 'q[1]').replace('c', 'q[2]')
print(f7)
```


求めた、イジングモデル。

2*q[0]*q[1] + 2*q[0]*q[2] + q[0] + 2*q[1]*q[2] + q[1] + q[2]


#amplifyに投入。

```
from amplify import (BinaryPoly, BinaryQuadraticModel, gen_symbols, Solver, decode_solution, )

q = gen_symbols(BinaryPoly, 3)
f = 2*q[0]*q[1] + 2*q[0]*q[2] + q[0] + 2*q[1]*q[2] + q[1] + q[2]
print(f.asdict())
model = BinaryQuadraticModel(f)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}") 
```


以上。
typescriptでクリーンアーキテクチャする

typescriptと相性がいいです。
type句書かないのでスッキリします。
難しいことするとtype句は必要ですがrepositoryに隠蔽してしまえばアプリケーション層では全く書かないはずです。

## Enterprise Business Rules

```typescript
class ValueObject {
  constructor(private value: any) {}
  get() {
    return this.value;
  }
  eq(valueObject: this) {
    return this.value === valueObject.get();
  }
}

class Entity {
  constructor(
    private props: {
      id: ValueObject;
      name: string;
    }
  ) {}
  get id() {
    return this.props.id;
  }
  set name(value: string) {
    this.props.name = value;
  }
}

interface StreageInterface {
  save(entity: Entity): void;
  find(id: ValueObject): Entity;
}

```

## Application Business Rules

```typescript
/**
 * ユースケース: Entityを取得して名前を書き換え上書き永続化
 */
class Usecase {
  constructor(private repository: StreageInterface) {}
  invoke(id: ValueObject) {
    const entity = this.repository.find(id);
    entity.name = "山田 太郎";
    this.repository.save(entity);
  }
}

```

## Interface Adapters

```typescript

const storeage = [
  new Entity({
    id: new ValueObject(1),
    name: "unknown",
  }),
];

class Repository implements StreageInterface {
  save(entity: Entity) {
    storeage.push(entity);
  }
  find(id: ValueObject) {
    const entity = storeage.find((item) => item.id.eq(id));
    if (entity) {
      return entity;
    } else {
      throw new Error("entityが存在しない");
    }
  }
}

class Controller {
  patch(param: string) {
    new Usecase(new Repository()).invoke(new ValueObject(param));
  }
}

```
amplifyの作法 その21

#概要

amplifyの作法、調べてみた。
練習問題やってみた。

#練習問題
aさん、bさん、cさん、は、1を選んだ。

#評価関数を組み立てる。
評価関数

H = (a + b + c - 3) ** 2

a,b,cは、[1,0]をとる。
a=1,b=1,c=0の場合は、1
a=1,b=1,c=1の場合は、0

#式を展開して、イジングモデルをつくる。

sympyを使う。

```
from sympy import *

a, b, c = symbols("a,b,c")
f = (a + b + c - 3) ** 2
print(f)
f4 = str(expand(f))
print(f4)
f5 = f4.replace('**2', '')
print(f5)
f6 = str(simplify(f5))
print(f6)
f7 = f6.replace('a', 'q[0]').replace('b', 'q[1]').replace('c', 'q[2]')
print(f7)

```

求めた、イジングモデル。

2*q[0]*q[1] + 2*q[0]*q[2] - 5*q[0] + 2*q[1]*q[2] - 5*q[1] - 5*q[2] + 9

#amplifyに投入。

```
from amplify import (BinaryPoly, BinaryQuadraticModel, gen_symbols, Solver, decode_solution, )

q = gen_symbols(BinaryPoly, 3)
f = 2*q[0]*q[1] + 2*q[0]*q[2] - 5*q[0] + 2*q[1]*q[2] - 5*q[1] - 5*q[2] + 9
print(f.asdict())
model = BinaryQuadraticModel(f)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}") 

```

以上。
presentとかpopとかpushの違い

超ざっくりまとめます

present

ビューの上にもう一つビューが乗るイメージ

pop

次の画面に遷移

push

複数回画面遷移した後に、いくつか前の画面に一気に戻りたい場面で使う

時間があるときに更新します。
Google Cloud Functions × Cloud FirestoreをPythonで実装する

# Cloud Functions × Cloud Firestore 連携

#### Firebaseプロジェクト > 「プロジェクトを設定」を選択

[![Image from Gyazo](https://i.gyazo.com/301500d603a073bc149eb8a586a4ecab.png)](https://gyazo.com/301500d603a073bc149eb8a586a4ecab)

#### サービスアカウントを選択

[![Image from Gyazo](https://i.gyazo.com/b79247d41584b725731d768891105ef2.png)](https://gyazo.com/b79247d41584b725731d768891105ef2)

#### 新しい秘密鍵の生成をクリック

[![Image from Gyazo](https://i.gyazo.com/212fe370751c8810b04eadaf64428f25.png)](https://gyazo.com/212fe370751c8810b04eadaf64428f25)

#### Cloud Firestore データ生成

[![Image from Gyazo](https://i.gyazo.com/4f1466c5551824da222b9d69e68faadc.png)](https://gyazo.com/4f1466c5551824da222b9d69e68faadc)

#### GCPコンソール > Cloud Functions > 「Create function」 選択

[![Image from Gyazo](https://i.gyazo.com/0cd58b2579b7b339bad9637d35b3ddf4.png)](https://gyazo.com/0cd58b2579b7b339bad9637d35b3ddf4)


# Cloud Functions 実装  ※HTTPトリガー

#### Cloud Firestore 秘密鍵インポート

```main.py
import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials


def sample_functions(request):
    cred = credentials.Certificate("path/to/serviceAccountKey.json")  # 秘密鍵

    firebase_admin.initialize_app(cred)
```


#### Cloud Firestore データやり取り

```main.py
import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials

def sample_functions(request):
    cred = credentials.Certificate("path/to/serviceAccountKey.json")  # 秘密鍵

    firebase_admin.initialize_app(cred)

    ## Firestore アクセス
    db = firestore.client()

    ## document指定
    doc_ref = db.collection('users').document('user')

    ## データ取得
    doc = doc_ref.get()

    sample = json.dumps(doc.to_dict())
    
    return sample
```

#### パッケージ指定

```requirements.txt
# Function dependencies, for example:
# package>=version
firebase-admin
google-cloud-firestore
```

#### デプロイ実施

[![Image from Gyazo](https://i.gyazo.com/8ad95a45ac97db5dde82718e74524f46.png)](https://gyazo.com/8ad95a45ac97db5dde82718e74524f46)


# Cloud Firestore トリガーの場合

#### トリガー設定

[![Image from Gyazo](https://i.gyazo.com/956bd42c10b78eb2515f7e3cdfa096c3.png)](https://gyazo.com/956bd42c10b78eb2515f7e3cdfa096c3)

#### Function 設定

```main.py
import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials


def sample_functions(data, context):
    cred = credentials.Certificate("path/to/serviceAccountKey.json")  # 秘密鍵

    firebase_admin.initialize_app(cred)

    ## トリガー呼び出し
    trigger_resource = context.resource
    
    ## Firestore アクセス
    db = firestore.client()

    ## document指定
    doc_ref = db.collection('users').document('user')

    ## データ取得
    doc = doc_ref.get()

    sample = json.dumps(doc.to_dict())
    
    return sample
```

#### デプロイ実施

[![Image from Gyazo](https://i.gyazo.com/6b1147d9a777f9a769e0f3e6ede75806.png)](https://gyazo.com/6b1147d9a777f9a769e0f3e6ede75806)



## 参考文献
 - [python×Cloud Functions×FirestoreでAPIを簡単に作ってみる Pt1](https://qiita.com/ny7760/items/9cdc3407dfda99c21ae1)
 - [Cloud FirestoreのデータをPythonで取得する](https://qiita.com/yusukeito58/items/c77feaa25fbbe37e9953)
【FileMaker】FileMaker Go 18,19でClaris IDからのサインアウトできない場合

# この記事の対象
Claris FileMaker Go 18及び19バージョン上から、Claris FileMaker Cloudを利用している方

# 困ったこと
FileMaker Cloudからサインアウトしようとした時、
![IMG_0741.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/0c5e4dc0-a135-c072-b09d-8f34f54f04a8.png)


こんな画面になってませんか？
![IMG_0740.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/6b330f83-ac81-ad55-db92-eef81070e2c1.png)

# 対処方法
これは、FileMaker Cloudの既知の問題として、以下に「まずはこれで対処して、、、」とあります。
[FileMaker Go: Claris ID からサインアウトできない](https://support.claris.com/s/article/Unable-to-sign-out-from-Claris-ID-on-FileMaker-Go?language=ja)

要は、歯車アイコンの設定からClaris IDを強制的に抜けるんですが、設定画面からサインアウトするというは一般ユーザ的には敷居が高いので、早期解決を願ってます。
論文PDFから表やテキストをコピーするときはスクリーンショットを使わない

知っている人は知っていると思うのですが，意外と記事を見かけないので…

論文紹介や学会発表のスライドで，論文PDFの図表や段落をコピペしたいときがよくあると思います．
Macだとスクリーンショットはお手軽にできるので，ついパシャリと図表を撮りたくなるかもしれませんが，結果はpngのラスタ画像となり，拡大縮小することで画像がぼやけてしまいます．

Mac標準のPDFビューワであるPreview.app (プレビュー.app) を使うと，PDFの一部をPDFのまま（ベクター画像として）コピーできるので，Powerpoint や Keynote といったプレゼンアプリ上で拡大縮小しても綺麗に描画されます．

方法は簡単で，Previewの範囲選択ツールを使ってコピーしたい部分を選択し，ショートカットキーでコピー (`command + C`) して，プレゼンアプリにペーストするだけです．

Mac (Preview.app)のバージョンにもよりますが，Big Sur ではここらへんをクリックすると範囲選択できます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33331/2ef65765-e730-d19e-03a1-19f39137374b.png)

スクリーンショットの貼り付けと，PDFからのコピペの比較をするとこんな感じ．

![Screenshot 2021-03-05 at 10.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33331/9a85095a-2cdf-8152-9e47-4607f2a5364e.png)
お名前ドットコムの独自メールアドレスをFirebaseで使用する方法

最近めっちゃ風強いんすよね。

僕雨と風強いの本当に嫌いなんです。

まぁこんな話はさておき、今回はお名前ドットコムで登録した独自ドメインのメールアドレスをFirebaseで使用する方法を書いていきます！

Firebaseでメールを送信する時って送信アドレスが``noreply@project-auth.firebaseapp.com``になっていると思うんですけど、これって知らない人からしたらもしかしたら怪しいと感じて信頼されない場合もありますよね。

せっかく会員登録したのにメールアドレスで信頼されなかったら勿体ない！

ってことで独自ドメインで送信しちゃいましょう！

#はじめに#

まず、下記の条件を満たしている前提で話します。

・お名前ドットコムで独自ドメインのメールアドレスを設定済み

メールアドレスを設定していない方は下記の記事にやり方が書いてあるので是非ご覧ください！

[お名前ドットコムで登録したメールサーバーと「nodeemailer」を連携させてみた](https://qiita.com/akki-memo/items/95f552ce29e43ac83f63)

以下、説明用のメールアドレスを``info@example.com``とします。

#FirebaseでDNSレコードの取得#

まず初めに、独自のアドレスを使うにはFirebaseが発行したDNSレコードをお名前ドットコムで登録する必要があります。

では、DNSレコードを発行しましょう！

「Firebase コンソール」→「Authentication」→「Templates」→「テンプレートを編集」→「ドメインをカスタマイズ」

するとこのような画面になります。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/b7995f11-6d0b-8012-6b98-54eda6fec7b9.png)


そしたら、サイトに使うアドレスを入力します。（例：example.com）

すると、このようにDNSレコードが発行されます。

![無題.2png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/c97912d2-bf3a-9a81-8744-bd1fc6aadae0.png)


#DNSレコードの設定#

先ほど発行したDNSレコードをお名前ドットコムで設定してあげましょう！



#FirebaseのSMTP設定#

そしたらFirebaseで**SMTP設定**をして独自のメールアドレスを使えるようにしましょう！

「Firebase コンソール」→「Authentication」→「Templates」→「SMTP設定」

以下のように設定してください。

|SMTP設定||
|---|---|
|送信者のアドレス|info@example.com|
|SMTPサーバーホスト|mail**.onamae.ne.jp|
|SMTPサーバーポート|465|
|SMTP アカウントのユーザー名|info@example.com|
|SMTP アカウントのパスワード|設定したパスワードを入力|
|SMTPセキュリティモード|SSL|

SMTPサーバーホストの情報は、まず「レンタルサーバー一覧」から登録したドメインでログインしてください。



「保存」してください。

これで独自のメールアドレスでFirebaseのメールを送信することができます。

お名前ドットコムってGmailみたいにメールのアイコンを設定することができないのかな。。。

やり方を知っている方はぜひ教えて下さると幸いです。

以上、「お名前ドットコムの独自メールアドレスをFirebaseで使用する方法」でした！

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

あと、最近「ココナラ」で環境構築のお手伝いをするサービスを始めました。

気になる方はぜひ一度ご相談ください！

Thank you for reading
Twilio Videoのサンプルコードで無料プランGoを使う方法

# はじめに
Twilio社は高クオリティなビデオアプリケーションのサンプルコードを公開しています。
https://github.com/twilio/twilio-video-app-react

何もせずに、このサンプルコードを利用すると、Twilio Videoの一番高額なプラン`Group`でルームが作られます。
ちょっと試すときは、`Go`というTwilio Videoの無料プランで試したいと思う方もいらっしゃるのではないでしょうか。

そこで本記事では、上記ビデオアプリケーションで`Go`へプラン変更する方法をご紹介いたします。

# 修正箇所
twilioビデオのサンプルコードは、[twilio cliのコマンド](https://github.com/twilio-labs/plugin-rtc#commands)を使ってデプロイしています。
そのコマンドにVideoのプランを設定するオプションがあるのですが、そのオプションのデフォルトが`Group`になっているのが、原因です。

なので、プランを変更するためには、オプションの`--room-type`に`go`を指定してあげます。

**修正箇所**
https://github.com/twilio/twilio-video-app-react/blob/ed63721c4c71bdf97a12a423103a21c2e81d1af8/package.json#L76

```package.json
修正前
"deploy:twilio-cli": "cross-env REACT_APP_SET_AUTH=passcode npm run build && twilio rtc:apps:video:deploy --authentication=passcode --app-directory ./build"

修正後
"deploy:twilio-cli": "cross-env REACT_APP_SET_AUTH=passcode npm run build && twilio rtc:apps:video:deploy --authentication=passcode --room-type=go --app-directory ./build"
```

# おまけ
修正しても反映されないときは下記コマンドを使って、一度ビデオアプリケーションを削除してから、再度デプロイしてみてください。

```
twilio rtc:apps:video:delete
```
【Material-ui】makeStylesを使った子要素のcss変更のやり方

##やりたかったこと
hover時に子コンポーネントのcssを変更する
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/c711340e-1d5d-3d70-8594-e07927388304.gif)

##結論
通常はopacityを0にしておいて、hover時に1に変更する。
makeStylesを使った場合はちょっと特殊な書き方だったので、makeStylesを使いたい人は参考にしてください。

```js
const useStyles = makeStyles({
  ...
  image_item_bar: {
    opacity: 0,
  },
  image_item: {
    '&:hover': {
      cursor: 'pointer',
      "& $image_item_bar": {
        opacity: 1.0,
      }
    }
  },
});

export default function GridImageList() {
  const classes = useStyles()

  return (
    <div className={classes.root}>
      <ImageList variant="masonry" cols={3} gap={8}>
        {itemData.map((item) => (
          <ImageListItem key={item.img} className={classes.image_item} >
            <img
              srcSet={`${item.img}?w=161&fit=crop&auto=format 1x,
                ${item.img}?w=161&fit=crop&auto=format&dpr=2 2x`}
              alt={item.title}
              className={classes.img}
            />
            <ImageListItemBar
              title={item.title}
              actionIcon={
                <IconButton
                  aria-label={`info about ${item.title}`}
                  className={classes.icon}
                >
                  <DeleteIcon />
                </IconButton>
              }
              className={classes.image_item_bar}
            />
          </ImageListItem>
        ))}
      </ImageList>
    </div>
  );
}
```
ext-zipのバージョンを確認する

# 目的

- ext-zipのバージョンを確認する方法をメモ的にまとめる

# 方法

1. 下記コマンドを実行する。

    ```
    $ php --ri 'zip'
    >
    >zip
    >
    >Zip => enabled
    >Zip version => 1.15.6
    >Libzip headers version => 1.7.3
    >Libzip library version => 1.7.3
    ```

1. 「Zip version =>」の後に記載されている値がバージョンである。

# 参考文献

- [https://www.php.net/manual/ja/features.commandline.options.php](https://www.php.net/manual/ja/features.commandline.options.php)
獣医師が必死にバイオインフォマティクスPythonによる実践レシピをwin10で動かす（その3）

# rpy2によるRの実行(つづき)
ようやく本題に入れる。
Jupyter notebookのマジックコマンドを使ってRを実行する。

```
from rpy2.robjects import r
from rpy2.robjects.packages import importr
import rpy2.robjects as robjects
import rpy2.robjects.lib.ggplot2 as ggplot2

%load_ext rpy2.ipython

%R seq.data <- read.delim('sequence.index', header=TRUE, stringsAsFactors=FALSE)
%R seq.data$READ_COUNT <- as.integer(seq.data$READ_COUNT)
%R seq.data$BASE_COUNT <- as.integer(seq.data$BASE_COUNT)

my_col = list(seq_data.columns).index("CENTER_NAME")
seq_data['CENTER_NAME'] = seq_data['CENTER_NAME'].apply(lambda x: x.upper())
```

`%load_ext rpy2.ipython`でなんか怒られる
`C:\Users\mokim\anaconda3\envs\win_bioinfo\lib\site-packages\rpy2-2.9.0-py3.6-win-amd64.egg\rpy2\robjects\pandas2ri.py:14: FutureWarning: pandas.core.index is deprecated and will be removed in a future version.  The public classes are available in the top-level namespace.
  from pandas.core.index import Index as PandasIndex`
要約するとこのpandasの使い方は良くないから、良い方にしたらというサジェストらしい
知らんがな、執筆者に言ってくれと思いながら華麗にスルー
この`%load_ext rpy2.ipython`を宣言することで`%R`と記載するとその一行はR側のコードして解釈されるみたい

続いて実行。

```
%R -i seq_data
%R print(colnames(seq_data))
```

ここの`-i`はマジックシステムにPython側の変数をR側にコピーすることを示しているらしい

本格的にデータをグラフィック化していく

```
%%R
seq_data <- seq_data[seq_data$WITHDRAWN==0, ]
seq_data$POPULATION <- as.factor(seq_data$POPULATION)

bar <- ggplot(seq_data) +  aes(factor(CENTER_NAME)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, hjust = 1))

seq_data$POPULATION <- as.factor(seq_data$POPULATION)
yri_ceu <- seq_data[seq_data$POPULATION %in% c("YRI", "CEU") & seq_data$BASE_COUNT < 2E9 & seq_data$READ_COUNT < 3E7, ]

scatter <- ggplot(yri_ceu, aes(x=BASE_COUNT, y=READ_COUNT, col=factor(ANALYSIS_GROUP), shape=POPULATION)) + geom_point()

library(gridExtra)
library(grid)
g <- grid.arrange(bar, scatter, ncol=1)
png('fig.png')
plot(g)
dev.off()
```

毎回`%R`と書くのしんどいと思っていたら、最初に`%%R`と宣言するとそこの終わりまでRコードとして認識されるらしい
ただし、`%load_ext rpy2.ipython`の宣言後には`%%R`は効力を持たなかった
Jupyter notebookの仕様？
宣言が同一空間内にあることによる記述の混乱を避けるため？
ちなみにここで画像の出力をするための原著のコードは

```
png('fig.png')
g
dev.off()
```

となっているが、おかしい
グラフィックエリアに記述しないと画像がpngの中に保存されないはず。
もしかしてMac, Linuxでは記述されるのだろうか？
誰か知っている人教えてください
Laravelについての認識

<h3>Laravelのインストール場所</h3>
今まではPC本体にLaravelをインストールするものだと考えていましたが、Laravelinstallerを用いて作成したプロジェクト自体にLaravelが存在するらしい。

つまりWord等のソフトウェアとしてインストールするわけではない。
<br/>

Laravelを利用する　＝　Laravelinstallerを用いてLaravelの組み込まれたプロジェクトを作る

Laravelinstaller　≒　Laravel
<br/>

的な感じ？
Cucumberのチュートリアルを日本語シナリオで試した



[10 Minute Tutorial](https://cucumber.io/docs/guides/10-minute-tutorial/)を日本語のシナリオで書き直してみたので記録。
言語はrubyです。

https://github.com/adebadayo/hellocucumber

#### 日本語のシナリオ

```:is_it_friday_yet_ja.feature
# language: ja
機能: 今日は金曜?
  皆が金曜かどうか知りたがっている

  シナリオアウトライン: 今日が金曜かどうか
    前提 今日が "<曜日>"
    もし 金曜と訪ねたら
    ならば  "<返答>"と返答する

  例:
    | 曜日            | 返答 |
    | 金曜            | 華金！ |
    | 日曜         　 | ちがうよ |
    | それ以外の曜日  | ちがうよ |
```

#### 日本語への設定
.featureファイルに`# language: ja`を追加すれば日本語でかける。
[Gherkin Reference(Spoken Languages)](https://cucumber.io/docs/gherkin/reference/#spoken-languages)


#### 対応した識別子に変更
Given -> 前提
When -> もし
Then -> ならば

[Localisation](https://cucumber.io/docs/gherkin/languages/)





# 参考

[Cucumber](https://cucumber.io/)
[10 Minute Tutorial](https://cucumber.io/docs/guides/10-minute-tutorial/)
[Gherkin Reference(Spoken Languages)](https://cucumber.io/docs/gherkin/reference/#spoken-languages)
[Localisation](https://cucumber.io/docs/gherkin/languages/)
Anaconda Jupyter-notebook インストール手順 

目的
1.windows10においてAnaconda3をインストールしてJupyter-notebookを使えるようにしようとしたがすんなりといかなかったので備忘録として行ったことを残す

問題点
1.「Just Me」が選択できなくて「All User」を選択した。
2.Anaconda navigatorからJupyter-notebookを起動できなかった。

やったこと
1.「Just Me」選択できなかったときのエラーメッセージでなんとなくユーザー名フォルダが日本語が入っているからエラー出ていた？と思ったのでユーザー名フォルダの名前の変更を試みた。「ユーザー名フォルダ　変更」と検索したら参考ページが出てきたので見ながら色々やってみた。

2.ユーザー名フォルダの名前を変更したため、Anacondaも再インストールし直したらJupyter-notebookが問題なく起動できた。ただしブラウザーの設定とかが変わってしまった。使えなくなったソフトもあったので再インストールし直した。