OmniAICreator/Qiita-1.07M huggingface dataset:
新卒デザイナーがターミナルで初めてgitコマンドを打ってみた

# はじめに

初めてターミナルを使用するデザイナーの方は、「この暗号は何だろう？」と感じますよね。

実際に私が初めてターミナルでコマンドを打ったとき、「意味わからない、何これ」でした。

そのため、ここではデザイナーがまず最初に覚えておくべきコマンドと簡単に意味のご説明します。

# 作業する前によく使うコマンド

`git branch`：自分の今いるブランチを確認する

`git branch ブランチ名` : 作業用ブランチを作成する

`git checkout ブランチ名 or master ` : ブランチ名/マスターに移動する

`git pull` :  リモートのリポジトリ内容を取り込む

`git pull origin master` : マスターを最新にする

# 作業が終わった際によく使うコマンド

`git diff`：作業した変更内容を確認する

`git status`：作業したファイルの確認

`git add -a`：コミット(確定)する前の準備

`git commit -m 'コミットのメッセージ（変更箇所の説明など）'`：コミット(確定)する

`git push origin ブランチ名`：プッシュする

# まとめ

今回ご紹介したコマンドはほんの一部ですが、これらを最低限覚えておけばターミナルを使えるかと思います...!

実際に入社半年目の私ですが、仕事上でほぼ上記のものしか使っていません。時と場合によって、違うコマンドも使用しますが、それはまたの機会でご紹介いたします。

ターミナルを恐れているデザイナーの皆さん！これだけでも抑えておけばある程度大丈夫ですので、恐れずに頑張りましょう！
Xcode 12 で自作 framework ビルド時に lipo コマンドがエラーを吐くようになった

# 現象

iOS用に自作の framework を fat でビルドしていました。（おそらく[ここ](https://gist.github.com/cromandini/1a9c4aeab27ca84f5d79)をコピペ。）
Xcode 12 に上げたところ、下記のようなエラーが出るようになってしまいました。

```
fatal error: lipo:
 ***/Debug-iphonesimulator/***.framework/***
 and
 ***/Debug-iphoneos/***.framework/*** 
 have the same architectures (arm64) and can't be in the same fat output file
```
※ 見やすいように伏字と改行を入れています。

# 原因

Xcode 12 から、iPhoneシミュレーターも arm64 向けにビルドするようになったようで、従来実機にのみ含まれていたのが両方に含まれるようになり、コンフリクトしてしまったようです。

参考： [Stackoverflow: iOS 14, lipo error while creating library for both device and simulator](https://stackoverflow.com/questions/64022291/ios-14-lipo-error-while-creating-library-for-both-device-and-simulator)

# 解決策

以下は、とりあえず従来と同じように、シミュレーターに arm64 向けビルドが含まれないようにする方法です。 **Apple Silicon 搭載の mac だと動作しない可能性があります。**

(1) ビルドスクリプトの中から `lipo -create ...` の行を探す。
（自分の場合、 Build Phase の Run Script に lipo コマンドを含んだビルドスクリプトを記述しています。）

```text:例（見やすさのために改行）
lipo -create -output \
"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" \
"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" \
"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
```

(2) その上の行に、`iphonesimulator`のビルドから arm64 を除去する記述を追加。

```text:例（見やすさのために改行）
lipo \
-remove arm64 \
"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" \
-output \
"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}"
```

# 最後に
上述しましたが、おそらく将来の Apple Silicon 搭載の mac では動作しません。Xcode 11 から使える XCFramework を検討する必要がありそうです。
ヘルパーで部分テンプレート（パーシャル)を返す

##ヘルパーで部分テンプレート（パーシャル)を返す方法

if文を使って条件ごとに異なるパーシャルを返したい場合があると思います。

しかし"html.erb"ファイルの中でif文を書くとどうしてもコードが長くなってしまいますよね。
例えばこんな風に、、、

```erb:sample.html.erb
<% if A == A %>
　<%= render 'follow_button' %>
<% else %>
　<%= render 'unfollow_button' %>
<% end %>
```

こんな時はヘルパーメソッドに処理をまとめるとスッキリします。⬇︎

```ruby:users_helper.rb
module UsersHelper

  def follow_unfollow_button(user)
    if A == A 
     render 'follow_button' 
    else 
     render 'unfollow_button' 
    end 
  end

end
```

ビューでhelperメソッドを使うと、、

```erb:sample.html.erb
<%= follow_unfollow_button(@user) %>
```
１行でスッキリしました。



####まとめ
slimやhamlを使用していればif文も多少は短くなるのですが、いずれにせよビューの中にロジックが書かれているとやはりコードの可読性が下がってしまいます。
できるだけif文などのロジックやhelperやdecoratorにまとめた方が良いと思いました。
MySQLでミリ秒のUNIX時間を日時に変更してタイムゾーンも変更

## 目的
MySQLに保存しているミリ秒のUNIX時間のデータを日時の書式に変更したい。
ついでにタイムゾーンも変更したい。

## 例
AppStore 領収書の `Latest_receipt_info` 内の `expires_date_ms` のようなデータなど。
※UNIXエポック(1970年1月1日午前0時0分0秒)からの経過ミリ秒で表現されている

### 想定テーブル
|id  |user_id  |expires_date_ms|
|---|---|---|
|1  |1  |1601371107000  |
|4  |2  |1601379940000|

### SQL例

```sql
SELECT 
  id, user_id,
  CONVERT_TZ(FROM_UNIXTIME(expires_date_ms / 1000, '%Y-%m-%d %H:%i:%s'), '+00:00', '+09:00') AS expires_date_ms
FROM
  hogehoges;
```

### 解説
|項目  |説明|
|---|---|
|expires_date_ms / 1000|ミリ秒を秒に変更|
|FROM_UNIXTIME(unix_timestamp, format)|UNIX時間を所定の書式に変更する|
|CONVERT_TZ(dt, from_tz , to_tz)|タイムゾーンを変更|


## その他
Latest_receipt_info 内にはちゃんと日時で表現されている expires_date がある。

## 参考
[MySQLでUNIXタイムスタンプと日付を相互変換するメモ](https://qiita.com/reneice/items/b385e143fcbb144f4f3e)
[MySQLでミリ秒をDATE型に変換するSQL文](https://ameblo.jp/hihihihiroki/entry-11117706865.html)
[レスポンスボディ.Latest _receipt _info](https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info)
macOSのTerminalで小文字のUUIDを生成する


小文字のUUIDを生成したかったのでメモとして残します。
zshです。

`uuidegen` コマンドでUUIDを生成できますが大文字なので `tr` コマンドで変換。

```zsh
uuidgen | tr "[:upper:]" "[:lower:]"
```

```:結果
ce20d9ba-38bf-45a1-ab4b-fc97472d44d8
```
Azure TrafficManager SSL化

AzureでTrafficManagerを構成すること自体は簡単ですが、SSL化が大変だったので、事前知識としてあったほうがいいことは書いておきます。

# TrafficManagerのSSL化に必要なもの
先ず前提としてTrafficManagerへのアクセスをSSL化するためには以下3点が必要です。
1.WebAppsPlan ~~S1~~ Basic以上(カスタムドメインが設定できるようになる)
2.カスタムドメイン
3.署名付きの証明書

2と3もAzureのポータル上で購入でき、有料ですがAzureで購入した場合は非常に設定が楽です(自動更新付き)

無料のものを使おうとして、何日もかけたのでもう買います。（いろいろ試して挫折）

# 今回SSL化するにあたって使うもの
ただAzureで証明書を買うとAzure Key Vaultサービスも使う必要があります。(いろいろ買わされてもうやる気が。。)
・カスタムドメインの購入(約1,300円/年)
・証明書の購入(約8,000円/年)
・Azure Key Vault(西日本 約3.3円/10000リクエスト)←まあまあ高い
※価格は執筆時点のものです

# 手順
（既にトラフィックマネージャーが構成されていること前提）
1.[カスタムドメインの購入](https://docs.microsoft.com/ja-jp/azure/app-service/manage-custom-dns-buy-domain)
2.[カスタムドメインを有効にする](https://docs.microsoft.com/ja-jp/azure/app-service/configure-domain-traffic-manager#enable-custom-domain)
3.[Azure証明書を購入・Key Vaultにインポート]
(https://docs.microsoft.com/ja-jp/azure/app-service/configure-ssl-certificate#import-an-app-service-certificate)
最後の証明書のバインディングはTrafficManagerにぶら下がっているWebAppsすべてに適用する必要があります。
DockerのlogをAWS CloudWatchに紐付けしVSCodeでリアルタイムに監視する

# はじめに
AWS EC2内のDockerコンテナ上で動くサービス(docker-composeで管理)のログをCloudWatchLogsに投げ、VSCodeでリアルタイム監視ができるまでの手順をまとめる。

- Dockerのlog driverについて
- CloudWatchLogsへの登録
- VSCodeのAWS拡張についてとログの閲覧

## Dockerのlog driverについて
Dockerの標準機能で`/var/lib/docker/containers/`にコンテナ内のログを出力するようになっている。そのため、Linuxの`logrotate`等を使用する必要はない。
docker-composeでの実装例は以下の通り。

```yaml:docker-compose.yml
version: "3"
services:
  hello:
    image: "busybox:latest"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
```

## CloudWatchLogsへの登録
上記で解説した、Dockerのlog driverを使用してログの出力先をCloudWatchLogsに変更することができる。
docker-composeでの実装例は以下の通り。

```yaml:docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
      dockerfile: prod/Dockerfile
    restart: always
    expose:
      - 8000
    environment:
      - TZ=Asia/Tokyo
    logging:
      driver: awslogs
      options:
        awslogs-region: ap-northeast-1
        awslogs-group: log-group-name
        tag: "{{.ImageName}}.{{.Name}}.{{.FullID}}"
  nginx:
    build:
      context: .
      dockerfile: nginx/Dockerfile
    restart: always
    ports:
      - 8080:80
    depends_on:
      - app
    logging:
      driver: awslogs
      options:
        awslogs-region: ap-northeast-1
        awslogs-group: log-group-name
        tag: "{{.ImageName}}.{{.Name}}.{{.FullID}}"
```

docker-composeではサービスごとにlog driverの設定を記述する。
`awslogs-group`にはマネジメントコンソールで作成したロググループ名を書く。

## VSCodeのAWS拡張についてとログの閲覧
VSCodeの拡張機能の検索窓に`aws`と打ち込めば、下の画像のような`AWS Toolkit`が表示されるので、それをインストールする。
![スクリーンショット 2020-09-29 17.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/119b647e-3f2d-dfce-2dbf-b29f4b21ee8c.png)
リージョンとアクセスキーを指示に従って設定する。
![スクリーンショット 2020-09-29 17.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/7995c13c-603c-71e7-f043-e0061c564a40.png)
上の画像の`CloudWatch Logs`のタブを開くとロググループが表示されるので、右クリックし`view log stream`を選択する。
[Output Colorizer](https://marketplace.visualstudio.com/items?itemName=IBM.output-colorizer)拡張をインストールしておくと、ログをハイライト付きで見ることができるので入れるとよい。

## 参考
- https://qiita.com/hidekuro/items/b1c7ce58c9d9fe342907
- https://qiita.com/charon/items/7e2328e5abf7340d32b6
- https://note.com/funmylife/n/nc3210727e11f
- https://docs.docker.jp/config/container/logging/local.html
【Ruby on Rails】便利なヘルパーメソッド

# はじめに
ヘルパーメソッドについて、[パーフェクトRuby on Rails 【増補改訂版】](https://gihyo.jp/book/2020/978-4-297-11462-6)を読んで個人的に学んだ内容をまとめます。

# ヘルパーメソッドとは
ビューテンプレートで開発の手助けとなる便利なメソッド。HTML生成を行うものやURL生成するものなどがある。

# パスとURLヘルパーメソッド
ルーティングを表示する際のPrefixの値＋`_path`でドメインやポートなどを除いた`/`から始まるパスを、Prefixの値＋`_url`とするとドメインなども含んだ完全なURLを返す。
パスに「:id」といった変動する値がある場合、引数にハッシュ形式で値を指定する。
url_forやlink_to、redirect_toでパスやURLを指定する際に使う。

以下のルーティングの場合、次のようなパスやURLが返る。

**ルーティング**

```
    users GET    /users(.:format)             users#index
     user GET    /users/:id(.:format)         users#show
edit_user GET    /users/:id/edit(.:format)    users#edit
```

**返るパスやURL**

 - users_path → `/users`
 - user_path(id: 1) → `/users/1`
 - edit_user_url(id: 1) → `http://www.example.com/users/1/edit`

# url_for
Webアプリケーションのパスを構築するためのヘルパーメソッド。文字列を直接書かずにルーティング上の定義を活用できる。
単にURLを取得したいときに使用する。

```
url_for(users_path)
#=> /users
```

# link_to
link_toはaタグを生成するヘルパーメソッド。
`_path`や`_url`でルーティング上の定義を活用して、画面にリンクを設置したいときに使用する。

```
link_to('編集', edit_user_path(id: 1))
#=> <a href="/users/1/edit">編集</a>
```

# time_ago_in_words
ある時刻と現在時間のあいだにどの程度空きがあるかを、人間にとってわかりやすく表示するヘルパーメソッド。
最終ログイン日時などを表示するサービスで活用できそう。

```
time_ago_in_words(Time.current)
#=> less than a minute
```

```
time_ago_in_words(Time.current + 3.days)
#=> 3 days
```

# number_with_delimiter
長い数字をカンマ区切りするヘルパーメソッド。オプションで区切り文字を変更することもできる。

```
number_with_delimiter 1234567890
#=> 1,234,567,890
```

```
number_with_delimiter 1234567890, delimiter: '@'
#=> 1@234@567@890
```

その他にも様々なヘルパーメソッドがRailsには用意されているので、自分で実装する前に[Railsガイド](https://railsguides.jp/action_view_overview.html#action-view%E3%81%AE%E3%83%98%E3%83%AB%E3%83%91%E3%83%BC%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E6%A6%82%E8%A6%81)を参考にすると良さそう。

# 独自ヘルパーメソッド
Rails組み込みのヘルパーメソッドでは用途に合わない場合は自分でヘルパーメソッドを実装する。
ヘルパーメソッドを定義するためのモジュールは「app/helpers」というディレクトリの配下に定義する。
アプリケーション全体で使うものであれば「app/helpers/application_helper.rb」に、コントローラ毎に使うようなものであれば「app/helpers/users_helper.rb」のようにコントローラに対応するhelper用のファイルを用意する。

## 例1） 全角の英文字を半角に変換するヘルパーメソッド

```rb:app/helper/application_helper.rb
module ApplicationHelper
  def to_hankaku(str)
    str.tr('Ａ-Ｚａ-ｚ', 'A-Za-z')
  end
end
```

```
to_hankaku('Ｒｕｂｙ')
#=> Ruby
```

## 例2） ユーザーエージェントからアクセス元がiPhone／Androidか判定するメソッド

```rb:app/helper/application_helper.rb
module ApplicationHelper
    def iphone?
      request.user_agent.include?('iPhone')
    end

    def android?
      request.user_agent.include?('Android')
    end
end
```
```slim:sample.html.slim
  p.button
    - if iphone?
      a href="https://itunes.apple.com/jp/app/（略）" target="_blank"
        | App Storeでダウンロードする
    - if android?
      a href="https://play.google.com/store/apps/details?（略）" target="_blank"
        | Google Playでダウンロードする
```
アクセス元のスマホの種類を判別して、App StoreまたはGoogle Playに遷移させるボタンを切り替えられる。

# 参考
[パーフェクトRuby on Rails 【増補改訂版】](https://gihyo.jp/book/2020/978-4-297-11462-6)
XP祭り2020に「初」参加してきた

こんにちは島田です。
9/19(土)に開催されたXP祭り2020に参加しました。
自分の頭を整理するとともに備忘的に記載していきます。
＃あくまで参加してみての一個人が理解した／感じたことと捉えてください。

# XP祭り2020って？？
日本XPユーザグループ（XPJUG）が開催するXP（エクストリームプログラミング）の祭典で、スピーカーの過去の経験を得た知見やプラクティスを吸収できる素敵な会です。


# きっかけ
現在仕事でスクラム開発を実践しています。
コロナ禍の状況もあり、６月のチーム発足後ずっとフルモブ・フルリモートで活動してきました。
そんな状況において、よりよく活動するためにエクストリームプログラミング（XP）についてノウハウを得ようと思ったのがきっかけです。


# 参加セッション
参加したセッションは以下のとおりです。

- 10:30-12:00 エンジニアの創造力を解き放て！ XPと歩んだ17年・技術・現場・仲間
- 13:00-13:20 開発チームの納得感をあげるためのモブ設計への取り組み
- 13:25-13:45 テスターがアジャイルプラクティスをチームにこっそり導入した話
- 14:00-14:20 チームの透明性と心理的安全性
- 14:25-14:45 "群れる"アジャイル
- 15:00-16:40 モブパターンライティングで神輿を担ごうぜ
- 16:00-16:20 やらされスクラムからの卒業！ 『アジャイルコーチと歩んだ独自スクラムからの脱却とNewNormalへの対応』
- 17:00-18:00 LT

参加したセッションについていくつかピックアップして内容に触れていきます。

# 10:30-12:00 エンジニアの創造力を解き放て！ XPと歩んだ17年・技術・現場・仲間

大手SIerで17年XPと関わってきたKambeさんのお話。
アジャイルのプラクティスはたくさんあるものの、理解したつもりでもそううまくはいかず、現場では

- 要件が終息せず、デスマーチ
- 結合したらI/F周りで問題発生

といった問題が起こることもしばしば。

**そもそも日本型のSIにアジャイルの考え方をそのまま当てはめることは適切ではないのではないか？** という考えから、日本型SI（SI）とアジャイルの原則とを照らし合わせながら独自の視点でギャップをを考察されていました。

そんな中個人的に印象に残っているのは、
WFはスペシャリストが能力を最大限発揮できるようにする
Agileは失敗から学び高速に成長できるチームづくり
に焦点を当てていると比較されている点でした。
初心者ながらスクラムを実践している身として、”チーム”が中心となる感覚には非常に共感しました。



# 13:25-13:45 テスターがアジャイルプラクティスをチームにこっそり導入した話
「競合会社がどこもスクラム開発をしていて焦りがある」「アジャイルかっこいい」といった動機で
アジャイルのプラクティスをこっそりチームに持ち込んだという内容でした。

具体的には、以下の３つを実践してみたとのこと。

- モブで設計書作成
- ペアで問い合わせ対応
- 新人研修で探索テスト

それぞれの試みについてきっかけとなった課題や実践したことについて触れていきます。

**モブで設計書作成**

- 直面した課題
    - 特定担当者に作業が集中しドキュメントがかけない
- やってみたこと
    - 主要メンバーが大まかに書く
    - 必要なアイコンは予め準備しておく


**ペアで問い合わせ対応**

- 直面した課題
    - メンバーによって対応にばらつきがある
    - 暗黙知の共有がうまくできていない
- やってみたこと
    - 回答をペアで対応
    - ドライバーが回答を考える
    - ナビゲータが回答の意味の確認や言葉遣いを調べる
    - 上級者×初級者でペアを組む


**新人研修で探索テスト**

- 直面した課題
    - 急にチームに新人が配属
    - 新人はプログラミング、インフラの知識はあるがテストの知識がない。
- やってみたこと
    - 座学
    - 参考書での学習
    - ふりかえり

個人的にはペアでの問い合わせ対応が面白く効果がありそうだなと感じました。
「運用ノウハウは暗黙知になりがち」というのは身に覚えがあり、暗黙知を持っている側は暗黙知と認識していないこともしばしば。
ペアワークでうまくコミュニケーションする際には、そんな暗黙知をきちんと言葉にしないと伝えられないため、「暗黙知を暗黙知だと認識する」「暗黙知を言葉にして共有するすることで理解が深まる」といった効果が期待できそうです。


# 14:00-14:20 チームの透明性と心理的安全性
スクラムにおける３つのポイント「透明性」「検査」「適応」において、
「透明性」は適切に「検査」「適応」するためのスタート地点であるという考えから、
チームでの会議時に起きがちな「特にありません問題」について実践されていることを発表されていました。

**特にありません問題**・・・チームでの状況確認の場において、（本当の状況はさておき）「特にありません」とだけ報告される。
正直に状況を報告できない／報告された側が突っ込んで聞けないといった問題。

この起きがちな「特にありません問題」については、**ファイブフィンガー**というプラクティスを用いて対応を試みたとのことでした。
「問題がある」とはなかなか口にしづらいもの。そこに対して指の本数という意思表示の方法を使うだけで少しでもハードルを下げられる点が面白いなと感じました。
さらに面白い点として、指の本数が3本以下（5段階評価で3以下）の場合、その場でペアプロ・モブプロでチームで問題を解決する「祭り」状態に入るとのこと。
チームの一体感を高めつつ問題もすぐに解決できる方法だと思いました。
また、**「チームに問題を打ち明けるとすぐに解決できる」** といった安心感も作れそうです。


# まとめ
すぐに取り込めるような取り組みから、普段の自分の振る舞いを省みる機会となるような取り組みまで、様々な話を聞くことができました。
私自身はこのようなイベントに参加するようになったのは最近ですが、
最近は良くも悪くもオンライン開催のイベントが多いので、みなさんも気軽に参加されてはいかがでしょうか。
Djangoでmysqlの曖昧検索を行う

## mysqlの曖昧検索について
https://www.softel.co.jp/blogs/tech/archives/1877
クエリについてはこちらを参考にさせていただきました

## Djangoでどう書くか

特殊なクエリは`filter`では無理なので`extra`を使います

```python
    def get_ambiguous_queryset(self, queryset, value, columns):
        """
        曖昧検索用のquerysetを返す
        :param queryset:
        :param value:
        :param columns:
        :return:
        """

        query_text = ''
        count = 0
        for column in columns:
            if query_text != '':
                query_text += ' OR '
            temp_value = value
            if isinstance(value, list):
                if len(value) > count:
                    temp_value = value[count]
                else:
                    temp_value = value[0]
            query_text += f"CONVERT({column} USING utf8) COLLATE utf8_unicode_ci LIKE %s"
            temp_value = temp_value.replace('%', r'\%%').replace('_', r'\_')
            params.append(f'%{temp_value}%')
            count += 1
        if query_add:
            query_text += query_add
        return queryset.extra(where=[query_text], params=params)
```

### 使い方

```python
# queryset、検索したい値、検索対象のカラムを渡す
self.get_ambiguous_queryset(queryset, value, ['name', 'code', 'description'])

# 検索したい値は配列でも渡せます(検索対象のカラムと連動してます)
self.get_ambiguous_queryset(queryset, [value, self.convert_tel(value)], ['name', 'tel'])
```

### joinが必要な場合には注意

```python
# NGのパターン（shopがjoinされずエラーになります）
self.get_ambiguous_queryset(queryset, value, ['shop.name', 'shop.code'])

# OKのパターン（filterにshopを書いておくとjoinされる）
self.get_ambiguous_queryset(queryset, value, ['shop.name', 'shop.code']).filter(shop__name__isnull=False)
```


## 所感

クエリでの書き方がわかっていても、それをDjangoでどう書いたらいいかはいつも悩みます
.NET 5 から Windows Runtime API を呼ぶのが凄い楽になってる

.NET 5 Preview 8 かららしいのですが、Windows 10 の API に .NET 5 からアクセスするのが凄く楽になってました。言及のある記事は以下になります。

- [Announcing .NET 5.0 Preview 8](https://devblogs.microsoft.com/dotnet/announcing-net-5-0-preview-8/)
- [Calling Windows APIs in .NET5](https://blogs.windows.com/windowsdeveloper/2020/09/03/calling-windows-apis-in-net5/)

どれくらい簡単になったかというと、今回のこの記事がすぐ終ってしまうレベルで簡単です。すぐ終わると悲しいので、ちょっとだけ昔と比べてどれくらい簡単なのか？というのも書いておこうと思います。

## 昔

Windows 10 SDK の特定のフォルダにある DLL や winmd ファイルを手動で参照追加したうえで、配布時に含まれてほしくないファイルはコピーされないように手動で設定する。
そんなに数は多くないのですがめんどくさかったです。

## 今

`Microsoft.Windows.SDK.Contracts` という名前の NuGet パッケージが追加されているので、それを参照することで呼べるようになります。まじ天国。

## .NET 5 以降

Target Framework Moniker を設定するだけでよくなります。具体的にはプロジェクトファイルの TargetFramework タグに `net5.0-windows10.0.17763.0` のように Windows であることと対象のバージョン番号をつけるだけで良くなります。

やってみましょう。

VS 2019 Preview を起動して WPF プロジェクトをサクッと作ります。

プロジェクトファイルの TargetFramework を `net5.0-windows` から `net5.0-windows10.0.19041.0` にします。以下のような感じですね。

```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>
</Project>
```

英語のブログのほうにもあるカメラからの写真撮影をやってみましょう。

```csharp:MainWindow.xaml
// Windows 名前空間で始まるクラスが使える！？
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using System;
using System.Windows;
using System.Windows.Media.Imaging;
using System.IO;

namespace WpfApp8
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            // カメラから画像取り込んで表示
            using var c = new MediaCapture();
            await c.InitializeAsync();

            var format = ImageEncodingProperties.CreatePng();
            using var s = new MemoryStream();
            using var randomAccessStream = s.AsRandomAccessStream();
            await c.CapturePhotoToStreamAsync(format, randomAccessStream);
            await randomAccessStream.FlushAsync();
            s.Position = 0;
            var source = new BitmapImage();
            source.BeginInit();
            source.CacheOption = BitmapCacheOption.OnLoad;
            source.StreamSource = s;
            source.EndInit();

            image.Source = source;
        }
    }
}
```

動かしてみるとちゃんと動きます。（仮想カメラの画像を取り込んでる感じです）

![cap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/a5e36eff-2f43-3bce-f970-169d61b4175c.gif)

昔 WPF でカメラ映像を取り込むのが凄く大変だった記憶があるので、こういう OS に紐づく API として提供されているものがさくっと呼べるのは心強いですね。

## まとめ

ということで、NuGet パッケージを追加するだけというのでも簡単だったのですが .NET 5 から、さらに拍車をかけて簡単に Windows 10 の API が呼べるようになりました。便利～～～。
VCCWで生成される.gitignoreが邪魔に感じた時の備忘録

VCCWを使って、複数人でローカル環境を合わせたいけど、WP本体は各自でビルドが必要だし、アップロードメディアやプラグインはgit管理したくないっていう状況。

こういうときにビルド時に生成されるデフォルトの.gitignoreは邪魔。
だけど、ビルド後に各自で消すのは、絶対消し忘れてめんどくさいことになるのが目に見えてる。
そういうときのための備忘録です。

# 使いたいやつと使いたくないやつ
* site.ymlとかそういうのはgit管理したい
* メディアファイルやプラグインは更新やアップデートとかあるからgit管理したくない
* ビルドしたときにWPのディレクトリに生成される.gitignoreで意図しない管理になる
* ビルド後に適宜削除などは混乱の元

```
├── .gitignore ←これを使いたい(A)
├── htdocs
│   ├── .gitignore ←これは使いたくない(B)
│   ├── index.php
│   ├── wp-admin
│   ├── wp-content
│   ├── wp-includes
│   ...
├── provision
├── site.yml
├── Vagrantfile
...
```  

# .gitignoreが生成されるディレクトリに先に置いておく
.gitignoreが生成されるディレクトリに、事前に.gitignoreを置いておけば、ビルドの時にスキップしてくれました。
↑↑↑の場合は(B)の位置に置いておきます。

site.ymlにfalseって書いたりとか試してうまくいかなかったけど、destroy後に再度ビルドしたときのログに.gitignoreをスキップしてるっぽいのを発見、先にファイル置いておけばいいんじゃない？って思ってやってみました。
割と当たり前のことなんだろうか。
【C#】WPFでUserControlのLoadedイベントに対してEventTriggerが起動しない

UserControlの初期表示時に1度だけ実行したい処理があったので
EventTrigger経由でLoadedイベントを発行しようと思ったのに
実行されなかった。

記述は以下のような感じで特に問題無さそう。

```C#
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding GetItemCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
```

で、色々調べた結果としてオチはシンプルな話だった。

```C#
        public HogeView()
        {
            InitializeComponent();
            _vm = new HogeViewModel();
            DataContext = _vm;
        }
```
InitializeComponent実行後にDataContextを設定していたので
画面初期設定時には関連付けされたコマンドが無いので実行されないというオチ。

```C#
        public HogeView()
        {
            _vm = new HogeViewModel();
            DataContext = _vm;
            InitializeComponent();
        }
```
DataContext設定後に初期化するようにすればいけた。
30分くらい無駄に…。
一緒に覚えるとわかりやすい「Dependency Injection」と「継承」について

#はじめに
DreamHanksの松下です。今回は「Dependency Injection」と「継承（extends)」について解説していきます。


[連載記事まとめ](https://qiita.com/DreamHanks/items/7df703a509ef22f64d2c)

#「Dependency Injection」と「継承」とは

###Dependency Injectionとは
他のクラスやインターフェースのオブジェクトを実装したいクラス内で生成することによって、
他のクラスのメソッドを使えるようにするもの。


###継承（extends)とは
実装しているクラスをサブクラス（子クラス）だとして、スーパークラス（親クラス）を継承（extends)
することによって親のクラスのメソッドを使えるようにすること


**要するに両者とも実装したいJavaクラスに他のクラスのメソッドを使えるようにしたいというものです。**
他にも「コンストラクタインジェクション」、「setter/getterインジェクション」
CloudWatchEventsのインプットでBatchのジョブ定義をオーバライドする

CloudWathEventsru-ルール で AWS Batchでバッチ処理を実行する構成では、CloudWatchEventのルール設定の「input」パラメータで、入力パラメータを設定できます。
さらに、入力パラメータ以外に、ジョブ定義のvcpuや環境変数などのパラメータのオーバーライドも可能ですのでその方法を紹介したいと思います。

# TL:DR;

- CloudWatchEventルールのターゲット`Input`に`ContainerOverrides`を追加する
    - ex)パラメータ`Env`の定義および、ジョブ定義のVcpuを4,メモリを2048に上書きする場合の`Input`
        - `{"Parameters" : {"Env":"Prod" },"ContainerOverrides": { "Vcpus":4, "Memory":2048}}`

# 利用用途

- 一つのジョブ定義を使いまわしたいが、条件によっては環境変数やvcpuなどの一部のパラメータを変更したい場合
    - 一部の環境変数の変更やvcpuの変更程度あればジョブ定義を複数用意せずに済む


# 設定方法

## コンソール

- CloudWatchEventルール ＞ ターゲット ＞ 入力の設定 ＞ 定数（JSONテキスト）
    - ここに`ContainerOverrides`を記述する
    - 画像ではvcpuを4、memoryを2048に上書きする例
![ルールのinput項目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203410/22c853e4-1c92-1867-1668-1b4cca096666.png)


## aws-cli

- コマンド
    - `aws events put-targets --rule [ルール名] --cli-input-json file://target.json`
- target.json

```target.json
{
  "Targets": [
    {
      "Id": "1",
      "Arn": "jobQueueArn",
      "RoleArn": "roleArn",
      "Input": "{\"Parameters\" : {\"Env\":\"Prod\" },\"ContainerOverrides\": { \"Vcpus\":4, \"Memory\":2048}}",
      "BatchParameters": {
        "JobDefinition": "jobDefinitionArn",
        "JobName": "jobName"
      }
    }
  ]
}
```

# 設定できるプロパティ

以下のJSONのプロパティであればすべてオーバーライドしてBatchを実行することができると思います

- Command
    - ジョブ実行時のコマンド
- Environment
    - 環境変数
- InstanceType
    - マルチノード並列ジョブに使用するインスタンスタイプ
- Memory
    - ジョブに使用するメモリ
- Vcpus
    - ジョブに使用するvcpu数
- ResourceRequirements
    - GPUの利用設定

```json

{
  "ContainerOverrides": {
    "Command": "echo 'hello world'",
    "Environment": [
      {
        "Name": "env",
        "Value": "prod"
      }
    ],
    "InstanceType": "m5.large",
    "Memory": 2048,
    "Vcpus": 2,
    "ResourceRequirements": {
      "Type": "GPU",
      "Value": "2"
    }
  }
}
```
長すぎるURLのWikipedia記事を、簡潔なpageID形式のURLで読み込み直すブックマークレット【2020年版】

## はじめに
長いURLは引用する時、ちょっと厄介です。
そこで今回はウィキペディアのURLをシンプルにするやつを作りました。
このコード自体が、拍子抜けするぐらいシンプルです。

```js
javascript:location.href=location.origin+'/?curid='+RLCONF.wgArticleId;
```

## 説明
Wikipediaのscriptタグを覗くと、`RLCONF` というobjectの中に、それらしきIDが見つかったので拝借しました。
ページ情報については、開発者ツールのコンソールで次のように入力すると確認できます。

```js
console.log(RLCONF);
```

## あとがき

```js
javascript:location.href=location.origin+'/?curid='+wgArticleId;
```

`RLCONF.` の部分を省略しても動くという噂がありますが検証していません。
試してみる価値はありそうです。よろしくお願いします。


本日もありがとうございました。

## 参考
https://qiita.com/yubessy/items/16d2a074be84ee67c01f
https://ja.wikipedia.org/wiki/Category:長大な項目名
https://developer.mozilla.org/en-US/docs/Web/API/Location/origin
Pythonによる画像処理100本ノック#10 メディアンフィルタ

## はじめに
どうも、らむです。
今回は画像中のノイズを除去するメディアンフィルタを実装します。

## 10本目：メディアンフィルタ
メディアンフィルタとは画像の平滑化・ノイズ除去を行うフィルタです。このフィルタを適用することによって画像全体をぼやかしたような加工ができます。

このフィルタでは注目画素を周辺画素の中央値で置き換えます。

また、前回同様、画像の端部分はフィルタリング処理が行えないので存在しない画素は0を用いる０パディング処理を行います。

## ソースコード

```medianFilter.py
import numpy as np
import cv2
import matplotlib.pyplot as plt


def medianFilter(img,k):
  w,h,c = img.shape
  size = k // 2

  # ０パディング処理
  _img = np.zeros((w+2*size,h+2*size,c), dtype=np.float)
  _img[size:size+w,size:size+h] = img.copy().astype(np.float)
  dst = _img.copy()

  # フィルタリング処理
  for x in range(w):
    for y in range(h):
      for z in range(c):
        dst[x+size,y+size,z] = np.median(_img[x:x+k,y:y+k,z])

  dst = dst[size:size+w,size:size+h].astype(np.uint8)

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# メディアンフィルタ
# 第２引数：フィルタサイズ
img = medianFilter(img,15)

# 画像保存
cv2.imwrite('result.jpg', img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/535cf161-acd9-81c5-d9f6-f9f5ae2bcf33.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/b3005982-4ebf-098d-d23b-28c889a49863.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/d818ad96-d539-cede-1db9-2367f2fa568f.jpeg">


画像左は入力画像、画像中央は前回のガウシアンフィルタによる出力画像、画像右は今回の出力画像です。
メディアンフィルタでは点状のノイズがきれいさっぱり除去できていることが分かります。
引数が違うのであまりいい比較にはなっていないですが、メディアンフィルタの方が点状のノイズをきれいに除去できています。


## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_6.py)に公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。
UnityPluginのデバッグ


# windows
[UnityでWindows向けNative Pluginをデバッグする](https://blog.cfm-art.net/archives/194)

UnityネイティブプラグインをVisual Studio でステップ実行デバッグする
http://satoshi-maemoto.hatenablog.com/entry/2019/07/30/155847

# Unity/Android

[Unity + Visual Studio環境のAndroid実機デバッグ方法](https://qiita.com/yagamian_sobaya/items/1aeb70ff81ce22ca092f)


[Unity-[Build Settings]のオプションはここを参照する](https://docs.unity3d.com/ja/2018.4/Manual/BuildSettings.html)

・Export Project : AndroidStudio用のprojectを出力する
・Symlink sources : 

・Wait For Managed Debuggerにチェックを入れておくと、デバッガーが起動するまでアプリの開始を待ってくれるので、アプリ起動直後の挙動を実機で確認することができる。

・Scripts Only Build : 現在のプロジェクトのスクリプトだけをビルドします。



# AndroidStudio : 別モジュールのC++のステップ実行
デフォルトでは非対応

# [UnityでGradleを使ったAndroidプラグイン開発](https://qiita.com/seachicken/items/d882c780d880f70e58e1)
Firebase AnalyticsをiOSに組み込む

#自分用メモ
Google Analyticsが終了し、FirebaseにAnalyticsが移ったので
そっち経由でアプリに導入する。

##手順
概要をこの記事を読んで同じことする
https://apps-gcp.com/introduction-of-firebase-analytics/

##つまった
Xcode側のコンソールには表示されるのに、なぜかFirebaseのDebug Viewに表示されない

##解決策
Product->Edit Schemaから以下のタグを追加
-FIRAnalyticsDebugEnabled
-FIRAnalyticsDebugEnabled

無事表示される。
Ruby on rails の導入

手始めにrailsの導入から

※なおmacosの使用前提で書きますのでご容赦ください

# rubyバージョン確認

まずターミナルを開いていただき
下記のコマンドを打ち込んでエンターします。

ターミナルはどこというかたはcommand+spaceで
検索機能が出るのでそこで打ち込んでください

```
rbenv versions
```

最新バージョンが確認できたでしょうか

# railsのインストール

待ちに待った、railsのインストールです
下記のコマンドを打ち込んでください

```
gem install rails -v "5.2.4.1"
```

バージョンは私が以前使って今ものです。

下記のコマンドで問題なく確認できれば完了です。

```
rails -v
```
コマンドのパス

コマンドを実行した時に「コマンドが見つからない」と表示されてエラーになることがある。
その時は、コマンドにパスを通すか、コマンドを絶対パスで指定して実行する。

コマンドが存在する場所を調べる方法

```
# whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz

# whereis ifconfig
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
　　→ ifconfig でエラーになっても、 /sbin/ifconfig を実行すれば良い。
```
コマンドにパスが通っているか確認する

```
# echo $PATH
/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin　　　※左のほうが優先される
```
一時的にパスを通す方法（/usr/local/pgsql/bin をパスに追加したい場合）

```
# PATH=$PATH:/usr/local/pgsql/bin　　★これまでの環境変数PATH に追加する
# export PATH　　　　　★環境変数PATHをエクスポートする（反映する）
```
ログインした時点で指定したコマンドへのパスが通るように設定するには、
ユーザーのホームディレクトリの下にある .bash_profile の中の PATH= に追記してやればOK

.bash_profileの中身はこんな感じ（/home/user1/.bash_profile）

```
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin　　　★ここにパスを追記してやる

export PATH
```
Pythonによる画像処理100本ノック#9 ガウシアンフィルタ

## はじめに
どうも、らむです。
今回は画像中のノイズを除去するガウシアンフィルタを実装します。

## 9本目：ガウシアンフィルタ
ガウシアンフィルタとは画像の平滑化を行うフィルタです。このフィルタを適用することによって画像全体をぼやかしたような加工ができます。

このフィルタでは注目画素の周辺画素をガウス分布によって重み付けし、フィルタの中心画素に近いほど大きな重みを付けます。ガウス分布による重み付けは以下のように定義されます。

```math
g(x,y) = \frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}
```

例えば、3×3や5×5のガウシアンフィルタは以下のフィルタがよく用いられます。おそらく引数のsに$σ=0.85$あたりを指定するとこの値になるかと思います。

| $\frac{1}{16}$ | $\frac{2}{16}$ | $\frac{1}{16}$ |
 ---- | ---- | ---- 
| $\frac{2}{16}$ | $\frac{4}{16}$ | $\frac{2}{16}$ |
| $\frac{1}{16}$ | $\frac{2}{16}$ | $\frac{1}{16}$ |

| $\frac{1}{256}$ | $\frac{4}{256}$ | $\frac{6}{256}$ | $\frac{4}{256}$ | $\frac{1}{256}$ |
 ---- | ---- | ---- | ---- | ----
| $\frac{4}{256}$ | $\frac{16}{256}$ | $\frac{24}{256}$ | $\frac{16}{256}$ | $\frac{4}{256}$ |
| $\frac{6}{256}$ | $\frac{24}{256}$ | $\frac{36}{256}$ | $\frac{24}{256}$ | $\frac{6}{256}$ |
| $\frac{4}{256}$ | $\frac{16}{256}$ | $\frac{24}{256}$ | $\frac{16}{256}$ | $\frac{4}{256}$ |
| $\frac{1}{256}$ | $\frac{4}{256}$ | $\frac{6}{256}$ | $\frac{4}{256}$ | $\frac{1}{256}$ |


注目画素が中心だとすると、周辺画素と対応するフィルタ値の積の総和を注目画素に代入すれば良いですね。
3×3フィルタであれば$I(x_0,y_0)×\frac{1}{16} + I(x_0,y_1)×\frac{2}{16} + ... I(x_2,y_2)×\frac{1}{16}$の値を注目画素に代入します。

また、画像の端部分はフィルタリング処理が行えないので存在しない画素は0を用います。これを０パディングといいます。

## ソースコード

```gaussianFilter.py
import numpy as np
import cv2
import matplotlib.pyplot as plt


def gaussianFilter(img,k,s):
  w,h,c = img.shape
  size = k // 2

  # ０パディング処理
  _img = np.zeros((w+2*size,h+2*size,c), dtype=np.uint8)
  _img[size:size+w,size:size+h] = img.copy().astype(np.uint8)
  dst = _img.copy()

  # フィルタ作成
  ker = np.zeros((k,k), dtype=np.float)
  for x in range(-1*size,k-size):
    for y in range(-1*size,k-size):
      ker[x+size,y+size] = (1/(2*np.pi*(s**2)))*np.exp(-1*(x**2+y**2)/(2*(s**2)))

  ker /= ker.sum()

  # フィルタリング処理
  for x in range(w):
    for y in range(h):
      for z in range(c):
        dst[x+size,y+size,z] = np.sum(ker*_img[x:x+k,y:y+k,z])

  dst = dst[size:size+w,size:size+h].astype(np.uint8)

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# ガウシアンフィルタ
# 第2引数：フィルタサイズ、第3引数：標準偏差(σ)
img = gaussianFilter(img,21,2)

# 画像保存
cv2.imwrite('result.jpg', img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/535cf161-acd9-81c5-d9f6-f9f5ae2bcf33.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/b3005982-4ebf-098d-d23b-28c889a49863.jpeg">


画像左は入力画像、画像右は出力画像です。
点状のノイズが低減されていることが分かります。


## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_6.py)に公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。
Bitbucket Pipelines (CI) で PHP7.4・Laravel 7・MySQL 8.0環境のテスト実行

## 手順
### 1. Pipelinesの有効化
Bitbucketの画面左のナビゲーションバーのPipelinesをクリックして、画面下のボタンを押してbitbucket-pipelines.ymlファイルをコミットする。
デフォルトの内容でさっそくパイプラインが動くがどうせ失敗するのでストップをクリックして止める。
この操作はリポジトリに対してadmin権限がないとできないので、持っていない場合は管理者等に言って権限をつけてもらう。

### 2. bitbucket-pipelines.ymlの内容を修正
コミットされたbitbucket-pipelines.ymlを以下のように修正する。

```yaml:bitbucket-pipelines.yml
image: php:7.4-fpm

pipelines:
  default:
    - step:
        script:
          - apt-get update && apt-get install -qy git curl libmcrypt-dev mariadb-client unzip
          - yes | pecl install mcrypt-1.0.3
          - docker-php-ext-install pdo_mysql
          - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
          - composer install
          - ln -f -s .env.pipelines .env
          - php artisan migrate
          - php artisan serve &
          - sleep 5
          - ./vendor/bin/phpunit
          - curl -vk http://localhost:8000
        services:
          - mysql

definitions:
  services:
    mysql:
      image: mysql:8.0
      environment:
        MYSQL_DATABASE: 'test_db'
        MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
        MYSQL_USER: 'homestead'
        MYSQL_PASSWORD: 'secret'
```

**注意点**
PHPUnitは、テストを実行するときの環境変数をphpunit.xmlで上書きできる。
次の手順の.env.pipelinesで環境変数を定義してもphpunit.xmlで上書きされてしまうので、mysqlの環境変数はphpunit.xmlの値に優先して合わせる必要がある。
例えばphpunit.xmlに以下のような記載がある場合はテスト実行時にDB名はtest_dbでアクセスする。.env.pipelinesでDB_DATABASEにいくら他の値を定義してもtest_dbでアクセスする。

```xml:phpunit.xml
    <server name="DB_DATABASE" value="test_db"/>
```

### 3. .env.pipelinesファイルを作成
ローカルで使ってる `.env` をコピーして `.env.pipelines` を作成し、以下の環境変数を更新する。
scriptを見て分かる通りこのファイルで定義されている環境変数でテストを実行することになる。

```.env.pipelines
DB_HOST=127.0.0.1
DB_USERNAME=homestead
DB_PASSWORD=secret
```

`bitbucket-pipelines.yml` と `.env.pipelines` をCommitしてPushすればテストが実行され、Pipelinesの画面でログが見れる。

## 上記手順に至るまでにやったこと
公式Bitbucket Supportの[Laravel with Bitbucket Pipelines](https://support.atlassian.com/bitbucket-cloud/docs/laravel-with-bitbucket-pipelines/)に書いてある通りにやってみるもエラーが出て出来ず。
1個ずつエラーを解消していった結果、以下の変更が必要だった。

- phpのバージョンを7.4に変更
- `mysql-client` を `mariadb-client` に変更
- `mcrypt-1.0.2` を `mcrypt-1.0.3` に変更
- `unzip` のinstallを追加

### エラー解消のデバッグ方法
ローカルで `bitbucket-pipelines.yml` を修正してPushしてPipelinesで実行ログを見て、、、を繰り返してデバッグしても良いが時間がかかってしまうので、ローカルで `docker run --rm -it -v $PWD:/var/www/html php:7.4-fpm bash` のようにしてコンテナに入り、scriptの内容を順番に実行していってエラーになったら調べて新たなコマンドを入力して、、、という方法が早い。

### CI/CDの辛いところ
このように時が経つとエラーが発生してしまうようになり、実行できなくなることがある。
実際、デプロイをCI/CDで実行しているシステムがあってしばらく改修の必要もなく1年くらいデプロイしてなかったが、プログラム改修することになり、簡単な修正だったので１日もかからずに修正が終わっていざデプロイしようとしたら、CIがコケてデプロイできないという事象に遭遇。結局それを解消するのにすごく時間がかかってしまった。。。
定期的にデプロイできるかどうかを確認してメンテしていくことが必要。

記事投稿日：2020/9/29
最新バージョン 2.1！最近のNoodl事情は？（2020.09.29時点）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526082/dbcb61da-1a1e-68fb-71c5-ea2292b1847c.png" width="100%">
現在、Noodl のバージョン 2.1 が β 版としてリリースされています。この記事では、最近のNoodl事情について書いています。

バージョン 2.1の特徴やインストール方法については、Noodl コミュニティの @macole さんが記事（[Noodl2.1β版レビュー Build21対応](https://qiita.com/macole/items/2d5550f222308b335997)）でまとめてくださっているのでそちらをご参照ください。

#Noodl とは🍜
[Noodl](https://www.noodl.net/) は、スウェーデンのデザインイノベーションエージェンシー [TOPP（トップ）](https://www.topp.se/)から生まれた **Low-code 開発プラットフォーム** です。現在は、開発チームが TOPP からスピンアウトし、Noodl の開発にさらに注力しています。

Noodl では、web 技術を使ったアプリケーションの開発ができます。つまり、HTML / CSS / JavaScript / React で構築され、ブラウザで動く web アプリケーションが **少ないコード記述 or コード記述なし** で開発できます。

既に Noodl を知っている方からすれば「Noodl といえばプロトタイピングツール」という認識かと思いますが、最近 Noodl の開発はどんどん進んでおり、コンセプトからリリースまでをシームレスに担える開発プラットフォームへと現在進行形で成長しています。プロトタイプをブラッシュアップした後にそのままリリースできるように開発を進めているようです。



#Low-code（ローコード）とは
「最近、No-code って言葉はよく聞くけど、Low-code ってなんだ...？」と思いまして、調べてみました。Wikipedia「[No-code development platform: No-Code vs. Low-Code](https://en.wikipedia.org/wiki/No-code_development_platform#No-Code_vs._Low-Code)」の一部を引用して、２つの違いを紐解きます。


>App Creator - No-code platforms are accessible to any end-business user while low-code platforms require developers with knowledge of coding languages who can work within a platform's constraints to streamline the development process.
>訳：アプリを作る人 - ノーコードプラットフォームはあらゆるエンドビジネスユーザーがアクセスできるのに対し、ローコードプラットフォームは開発プロセスを合理化するためにプラットフォームの制約の中で作業できるコーディング言語の知識を持つ開発者を必要とします。

ふむふむ...

>User Interface - No-code platforms most often rely on a preset User Interface layer which simplifies and streamlines an app's design. Low-code platforms may provide greater flexibility in UI options at the cost of additional coding requirements.
>ユーザーインターフェイス - ノーコードプラットフォームの多くは、アプリのデザインを簡素化して合理化するプリセットのユーザーインターフェイスレイヤーに依存しています。ローコードプラットフォームは、追加のコーディング要件のコストという点でUIの柔軟性を高めることができます。

なるほど。

###No-code と Low-code の違いをざっくりまとめると...

|  | アプリを作る人 | コーディングの知識 | UIの柔軟性 |
|:-:|:-:|:-:|:-:|
| **No-code**<br>ノーコード | 全てのユーザー | 必要ない | 低い |
| **Low-code**<br>ローコード | 主に開発者 | 必要あり<br>（必要ない場合もある） | 高い |

Noodl は標準的な JavaSctipt のコードを記述することができるので、Low-code に分類されると思います。

ここで、コードの記述量について考えてみます。作りたいアプリのレベルによってコードの記述量が変わってくるというのは通常のコーディングで言えることだと思いますが、Noodl での web アプリ開発でも同じことが言えます。ただし、Noodl では以下の点が通常のアプリ開発と異なります。

- 簡単なアプリケーションを作る場合は、コードを書く必要がない
- ちょっとレベルの高いアプリケーションを作りたい場合は、通常よりも少ないコード記述量で開発ができる

また、Noodl は UI の柔軟性が高く、ゼロから自由にデザインを構築することはもちろんのこと、これからはデザインツールの Figma や Sketch から UIデザインデータをインポートすることができるようになっていくという情報もリリースされています。
情報元：[Where we're going with Noodl](https://www.noodl.net/post/where-were-going-with-noodl)

#まとめ
最近の Noodl 事情について書いてきました🍜

Low-code 開発プラットフォームとして、プロトタイプを作成するだけじゃなく本番のアプリケーションまでをカバーできるようになっていくと、さらに開発プロセスの効率アップや質の高いアプリケーションを開発することができるようになるのではないでしょうか。

今後の Noodl に目が離せません...！
Raspberry Pi で uart 通信のテスト

２台の Raspberry Pi をつないで uart 通信のテストをします。

結線は次の３箇所です。

GND --- GND (6 --- 6)
TxD --- RxD (8 --- 10)
RxD --- TxD  (10 --- 8)
![raspberry_sep30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e67bf4ed-50cd-c831-00a4-cb4be19b9161.png)


送信のプログラム

```py:serialTest.py
#! /usr/bin/python3
#
import serial
#
ser = serial.Serial('/dev/ttyS0', '115200', timeout=0.1)
#
ser.write(str.encode('Hello, World!\r\n'))
print(repr(ser.readline()))
ser.close()
```

受信側で、cu を起動

```bash
sudo cu -s 115200 -l /dev/ttyS0
```

送信側で serialTest.py を起動

```bash
sudo ./serialTest.py
```

受信側の結果

```text
$ sudo cu -s 115200 -l /dev/ttyS0
Connected.
Hello, World!
```

cu を停止させるには

```text
~.
```

/dev/ttyS0 のグループも root にする必要があります。

```bash
sudo chgrp root /dev/ttyS0
```

次のページを参考にしました。
[Raspberry PiでUARTの有効化＋シリアル通信](https://qiita.com/s_fujii/items/466d455ca19fb4c20744)
「npm does not support Node.js」エラーの解消法

# はじめに
npmの実行ができず、調べても中々解消できなかったため、参考までに解消方法を記載しておきます。

# 事象
### エラーメッセージ
npm startを実行すると以下のようなメッセージが出てきました。

```
npm does not support Node.js v12.18.3
```


### 原因
npmとNode.jsのバージョンが合っていない。
npmが古いようです。

# 試したこと
#### Node.jsをアンインストールして再インストール
1. コントロールパネル > すべてのコントロールパネル > プログラムと機能<br>
「Node.js」を右クリックしてアンインストール
2. Node.jsのサイトからインストーラーを落としてきて再インストール。

### npmをアンインストールして再インストール
1. 以下のコマンドでnpmをアンインストール

    ```
    npm uninstall -g npm
    ```
2. 以下のコマンドで最新版をインストール

    ```
    npm install -g npm@latest
    ```
    →最新版のインストールで同じくnot supportのエラーが発生。

# 解決方法
1. ```C:\Users\<ユーザー名>\AppData\Roaming\```に移動
2. npm関連フォルダ削除（安全のため、フォルダ名変更するだけでも可）<br>
    削除対象：「npm」フォルダ、「npm-cache」フォルダ
3. npm最新バージョンをインストール

    ```
    npm install-g npn@latest
    ```

これで最新版のnpmがインストールされ、```npm start```も実行できました。
@nuxtjs/markdownit + プラグインを入れたら、IE11がエラーを吐くようになって困った話

## Nuxt.JS + Headless CMS で快適ネットショップ開発。

現在、とあるネットショップのリニューアル案件を進めています。
一般的な通販用CMSですと、思ったようなレイアウトが作りにくかったり、カートの見せ方や遷移の自由度が小さくて妥協せざるを得ないことが多いのですが、Headless CMS + Nuxtで構築することによって、思った通りのネットショップを作ることが出来てとても楽しいです。

## IEを切り捨てたいけど、まだ無理か…。

さすがにIE11対応はもういいだろうと思いつつ、現状調査をしたところ、IE11経由での売上は無視できるレベルの金額ではなく、まだしばらく対応が必要という結論に。

しかし、そこはNuxt.JS。「Polyfill追加してやれば楽勝や！」と開発を進めていたところ、いつの間にかIE11がエラーを吐くようになっていました。最初の内はIEでも順調に動いていたのですが、どこかの時点から不具合が生じたようです。

## Nuxt.JSの出力するコードにアロー関数が混ざる。

出力されたソース眺めていると、ところどころにアロー関数が混ざっていることに気づきました。
Nuxtの設定で、ブラウザのバージョン指定を調整しても変わらず、modernバンドルを試してもなぜかアロー関数が混ざります。

## markdownit のプラグインが怪しい？

minifyされて訳の分からないコードを眺めていると、使われているメソッドなどから、なんとなくmarkdownitのプラグインではないかという気がしてきました。

「@nuxtjs/markdownit」を使用する場合、nuxt.config.jsに、以下のように記述してプラグインを読み込ませます。

```
  modules: [
    '@nuxtjs/markdownit',
  ],

  markdownit: {
    injected: true,
    html: true,
    use: ['markdown-it-attrs', 'markdown-it-div'],
  },
```

もしや use で読み込ませるプラグインのコードは、トランスパイルをすり抜けるのでは？

そこで、強制的にトランスパイルされるよう、以下の設定をnuxt.config.jsに追加してみました。

```
  build: {
    transpile: ['markdown-it-attrs', 'markdown-it-div'],
  },
```

その結果、無事にIE11でもエラーを吐かなくなりました！（ぜえぜえ）

IEと戦い始めて20年。いつまでIEとの戦いは続くのか…。
ABテストってなあに？

##ABテストとは
ABテストは、WEBマーケティングにおける手法の一つで、toC向けのサービスなどを運用しているとよく耳にします。
WEBサイトや広告のバナー等の画像をAパターン(元ページ)とBパターン(テストパターン)の2パターンを用意して「どちらがより良い成果を出せるのか」ということを検証するものです。

##ABテストの主な目的

###広告、バナー
「CVR（コンバージョン率）」と「CTR（クリック率）」の向上

###LP(ランディングページ)
インターネット広告のランディング先ページを複数用意し、ランディング先を振り分けることで、ランディングページ“A”と“B”のどちらがより成果を上げるかを比較し、採用するランディングページを判断する。

###WEBサイト
WEBサイト内の一部分を変更することで、比較したWEBイト内のパーツ“A”と“B”のどちらがよりユーザビリティの観点から優れているかを検討する。

- ファーストビューの画像

- ボタンの文言

- 訴求文言

- フォーム画面、アクションボタン

- など

##まとめ
WEBサイト内のパーツ改善することで、サイト内での訪問者の行動も関わってきます。
また、広告を配信するには費用がかかります。
ABテストを使ってこれらを効率よく改善していきましょう！
"Web"と付く様々な名称説明

【概要】
----------------------------------------
<b>①web</b>

<b>②webページ</b>

<b>③webサイト</b>

<b>④webアプリケーション</b>

<b>⑤webシステム</b>


<br>
①web
----------------------------------------
WWW(Wolrd Wide Web)の略称で、インターネット上にある様々な文章（文字）や画像、動画をクライアントに表示して閲覧できる仕組みのことです。

<br>
②webページ
----------------------------------------
web上にある文章１枚のことです。
<br>
③webサイト
----------------------------------------
特定のドメイン下にある①webページの集まりのことです。最初に表示されるページを”トップページ”、広告から飛んで最初に表示されるページを”LP（ランディングページ”と言ったり、トップページでスクロールせずに表示される部分を”FV（ファーストビュー）”といいます。webサイトを見るためのソフトウェアを”webブラウザ”といい、ここでいう”ソフトウェア”はブラウザを動かすためのプログラムということになります。本来はハイパーテキスト(.html)を表示するためのプログラムでしたが、今では”cookie”保存や”webクライアント”として利用されています。

ex:
GoogleChrome(Google),
Firefox(Mozilla),
InternetExplorer(MicroSoft),
Safari(Apple)etc...
<br>
④webアプリケーション
----------------------------------------
webを介して人が利用するサービスを提供しているものです（無形）。
<br>
⑤webシステム
----------------------------------------
”webサイト”や”webアプリケーション”、webサービスを提供するための仕組みです。webサーバー、APサーバー、DBサーバーなどがあります。”webサービス”は、プログラムが利用するサービスを提供していることを指します。
<br>

"webサーバー"と"アプリケーションサーバー"の違い
"web"と"インターネット"の違いは後日自分の確認用も兼ねて簡単にまとめます！
PlatformException(unregistered_view_type, trying to create a view with an unregistered type, unregistered view type: 'plugins.flutter.io/google_maps')

flutterにgoogle map apiを入れたらタイトルのエラーが発生

```
# アプリをuninstallした後に実行
flutter clean
```


これで直りました

### 参考記事
[google maps Trying to create a platform view of unregistered type](https://stackoverflow.com/questions/59511692/google-maps-trying-to-create-a-platform-view-of-unregistered-type)
ISUCON10予選に参加してきました!

# ISUCON 初参加！

ISUCON10に参加してきました！
こういったコンテスト(競技プログラミング)自体初めての参加だったのでとても有意義な体験でした！
この記事では自身の体験とともに、 ISUCONって一体何なのかについてもご紹介できればなと思います。


### [ISUCON](http://isucon.net/) とは :thinking: 

 いい感じにスピードアップするコンテスト (**I**ikanjini **S**peed **U**p **CON**test)
の略で、**お題のWebサービスを、決められたレギュレーションの中で限界まで高速化を図るチューニングバトル**です。


参加者はただひたすらにお題として与えられたWebシステムを高速化するのみ、 限られた時間 (**8時間!!**)
を使って、**いかにそのシステム全体を読み解き、理解し、パフォーマンスを上昇させるか**に尽力します。

予選と本戦に別れており、前哨戦である予選を勝ち抜けるのは **全体のうち 30チームのみ！**
最近では学生さんの参加があることもあり, 一般枠と学生枠に更に別れており
**一般は25チーム**、**学生さんは5チーム**が選出されます。

 **優勝賞金は100万円！** という太っ腹な大会です。

これまで 計10回開催されており、今回参加したのが記念すべき第10回でした :clap: 


#### 構成

* 基本的に 複数の言語でシステムが実装されているのでそのうちのどれかを選んでチューニングしていきます。
    *  実装言語は 最新のISUCON10では以下のような言語で実装されていました
        *  Go,Ruby,Python,NodeJs,PHP,Rust,Perl,Elixir,Deno
            *  [今回の実際の利用は以下のとおり](http://isucon.net/archives/55008738.html)

```
オンライン予選 利用言語比率
利用率の全体ランキングは以下の通りです。

Go 　 　 　276組　59.0%
Ruby 　 　 81組 　17.3%
Python 　　47組 　10.0%
Nodejs 　　29組 　6.2%
PHP 　 　　18組 　3.8%
Rust 　 　 　8組 　1.7%
Perl 　 　 　 7組 　1.5%
Elixir 　 　　1組 　0.2%
original-ruby 1組 　0.2%
```


        
* 1~3人までのチームを組み、問題に取り組んでいきます。
    * アプリ、インフラ、分析&司令 といったような構成がオーソドックス
    
* スコアの測定には独自のベンチマークを使用
    * どんな手段でもよいので、以下に高得点のスコアをベンチマークで算出するかがカギ ※ ベンチマークはいじっちゃだめ



### 今回の問題

issumo という **イスと物件を検索し、購入＆資料請求できるWebサイト**が今回の問題として与えられました。
機能としては以下が主でした。

* イスの条件検索 && 物件の条件検索
    * (様々なパラメータを設定でき、それに一致した物件を検索できる)
* なぞって検索 (地図上にマウスでドラッグした指定範囲で物件を検索できる)
* イス、物件のそれぞれの最低価格の一覧表示
* 物件のレコメンド

etc... 

今回はログインなどの状態での処理などがなかった為、
純粋にシステムのボトルネックが何なのかを突き止めていくような問題だったと思います。
個人的には 特になぞって検索がすごかった！ なぞった範囲の緯度経度をから範囲内の物件情報を表示するUIがよかった...!


# 当日やったこと

* アプリ初期動作確認
    * 僕の担当はアプリ部分だったので競技が始まってから、まずアプリの動作確認
    * 今回は踏み台サーバー経由でのアクセスしかできず うまく接続できなかったため足踏みすることに...。

* その後
  * インフラのチームメイトがソースコードバックアップとgit管理してくれたので、sshはお任せ
  * ソースコード読み込み,関数ごとのコメント付け, エンドポイントの書き出しをしていました。

* DB（mysql周り)
    * DBがボトルネックっぽいことがわかったので、index貼ってexplainで計測を繰り返したりいました。
    * ただ、indexを貼っても特に結果が変わらず、どうしたものかと頭を抱えたりしてもいました :expressionless: 
    * チームで相談しもともとはmysql5.7で動いていたものをmysql8に換装 >> 初期スコアから半減するという結果に :scream: 
    * ベンチマーカー回すとデータが初期化され、indexも消えると悩んでいたので schema.sql のテーブル定義に追加するよう提案

* SQL＆レスポンス改善
    * 雑に `COUNT(*)` になっているSQLや `SELECT *`になってるSQLを改善
    * ランディングページで毎回読み込んでいるクエリをRedisに投入してそこから取得するように変更していたりしました。
    * OR条件を5連結していたクエリを union で書き直していましたが、結果的にベンチが通らず断念...

## まとめ

こうしてまとめてみると当日全然動けてなかったな、というのが顕著にわかります。
自身が普段ほぼフロントエンド専任なのもありますが、圧倒的にバックエンド関連の知識と経験が欠如しているなと実感しました。正直めっちゃ悔しい。


### 反省点＆感想
あとから振り返ると**Like検索があった部分**や **N+1っぽい部分**(なぞって検索)をコメントつけている途中で見つけていたのに
**他の作業で埋没してしまった**なぁというのが反省点としてあります。
また、**クエリの改善策がこれといって思いつかず、呆然としてしまった時間があった**のでそこがなければ
もう少し手を動かせたのではないか思います。
普段Go触ってないからGoでバックエンドサーバ作ってみるのもいいかもしれません。
何れにせよ実力不足を痛感したISUCONでした...。でもめっちゃ楽しかった！普段触れない言語だったり、いろんな知識を取得できるいい機会でした。
[Deno](https://deno.land/)での実装もあったので typescriptをバックエンドで使用するのもアリだなと思った次第です。

今回DBが物件とイスしかない上、お互いをJOINしているSQLもなかったため、それぞれDBを割り当てるという荒業を行っているチームもありました！思いつくアイデアが既にすごい。。。！

普段土日で開催するものを土曜に集約し、５００組もの参加者を捌いた運営さんほんとすごいなと思いました。本当にありがとうございました :smile: 
 


## 予選問題の解説

http://isucon.net/archives/55025156.html にて公開されています！
Rack::Timeout でパスごとにタイムアウトを指定する

[rack-timeout](https://github.com/sharpstone/rack-timeout) を使用しておりパスごとにタイムアウトの指定を変更するため以前（rails 5.2.3、 rack-timeout 0.5.1 まで）は以下のように指定していました（多少簡略化してあります）。

```Gemfile:Gemfile
gem 'rack-timeout', require: 'rack/timeout/base'
```

```ruby:config/initializers/rack_timeout.rb
module Rack
  class DynamicTimeout < Rack::Timeout
    def call(env)
      # URL が /admin から始まる場合は 30 秒、それ以外は 10 秒となるように
      @service_timeout = env['REQUEST_URI'].start_with?('/admin') ? 30 : 10

      super(env)
    end
  end
end

timeout_params = {
  service_timeout: 10,
  wait_timeout: 5.minutes.to_i,
  wait_overtime: 5.minutes.to_i,
  service_past_wait: false,
}

Rails.application.config.middleware.insert_before Rack::Runtime, Rack::DynamicTimeout, timeout_params
```

ところが Rails 6、あるいは rack-timeout 0.6.0 からタイムアウトが動的に指定した `service_timeout` の値よりも短くなっていました。
以下のようにログに出力されている値（30秒）よりも実際は短かった（10秒）です。

```
severity:ERROR	message:source=rack-timeout id=0284947e-c24c-4024-a9ba-c542b3eb58f9 timeout=30000ms service=10000ms state=timed_out
```

色々ログを仕込んだりして原因を調べたところ、どうやら `Rack::DynamicTimeout` の `call` とは別に `Rack::Timeout` 自体の `call` が呼ばれているようでした。

都合2回 `call` メソッドが実行されて最初は `Rack::DynamicTimeout` で次が `Rack::Timeout` になっており、最終的にタイムアウトの値は `Rack::Timeout` で指定された値が使われるという状態です。
どこで呼ばれているか、それを変更できるかというところまで調べていくとちょっと時間がかかりそうだったので、今回は `Rack::Timeout` を上書きするパッチで対応することにしました。


```Gemfile:Gemfile
gem 'rack-timeout'
```

```ruby:config/initializers/rack_timeout.rb
module Rack
  module DynamicTimeout
    def call(env)
      # URL が /admin から始まる場合は 30 秒、それ以外は 10 秒となるように
      @service_timeout = env['REQUEST_URI'].start_with?('/admin') ? 30 : 10

      super(env)
    end
  end
end

Rack::Timeout.prepend Rack::DynamicTimeout
```

`Module#prepend` でモジュールを差し込んで `Rack::Timeout` の `call` が呼ばれても対応できるようにしました。
ひとまずこれで。
Firebaseでdeploy時にError: 400, Billing account for project...と出た場合の回避方法

# FirebaseでReact+TypeScriptアプリをdeployしようとした際に、発生したエラーの話

デプロイした際のエラー文（ターミナル）

```
Error: HTTP Error: 400, Billing account for project 'ここはプロジェクト番号' is not found. Billing must be enabled for activation of service(s) 'cloudbuild.googleapis.com,containerregistry.googleapis.com' to proceed.
```

# 原因はNode.jsのバージョンが10になっていたため

functionsのpackage.jsonの"engines"のnodeを10ではなく8に修正する

こちらを

```

"engines": {
    "node": "10"
  },
```

```
"engines": {
    "node": "8"
  },
```

にするだけ。
https://firebase.google.com/docs/functions/manage-functions#upgrade-node10

>
Node.js 8（2020 年 6 月 8 日に非推奨） Node.js 8 関数は、2020 年 2 月 15 日以降はデプロイできなくなります。すでにデプロイされている Node.js 8 関数は、2021 年 3 月 15 日をもって実行できなくなります。Node.js 8 ランタイムに関数をデプロイしている場合は、Node.js 10 ランタイムにアップグレードすることをおすすめします。
```

一部抜粋しました。
ん、

2020年2月15日以降はデプロイできないって書いてたけどできました・・・・
でも最終的に、2021年3月15日以降は確実に実行できなさそうですね。


詳しい方、心優しい方、教えて下さい・・・。

ここは違う？ここはこうしたほうが？等々ございましたら、ご指摘いただけますと幸いです。
最後までみていただき、ありがとうございます。