OmniAICreator/Qiita-1.07M huggingface dataset:
複雑な計算があるならCalcRuleクラスを作ろう


計算処理があると関連するActiveRecordモデルにメソッドを作りますよね[^1]。

```ruby:product.rb
class Product < ApplicationRecord
  def billing_price
    price * consumption_tax_rate
  end

  def consumption_tax_rate
    # 消費税率を返す
  end
end
```

[^1]: 本題ではないので省略してるけど、浮動小数点数の計算はちゃんとやろう！=>[[Ruby]消費税計算にはBigDecimalを使いましょう](https://qiita.com/jnchito/items/d0ef71b25732ad5a881c)

税込金額を計算するぐらいなら、そこまで問題を感じません。ただ、キャンペーンで値引きするようになったり、値引き条件が複雑になってくると、商品クラスが金額計算クラスのように思えてきます。

```ruby:product.rb
class Product < ApplicationRecord
  def billing_price
    campaign_discounted_price * consumption_tax_rate
  end

  def consumption_tax_rate
    # 消費税率を返す
  end

  def campaign_discounted_price
    # キャンペーンを適用した値段を返す
    # キャンペーンが複雑になるとこのメソッドが複雑になったり、
    # このメソッドからしか呼ばれないメソッドが増えていってしまう！
  end
end
```

このままではFat Modelになってしまいます。

# 計算のためのクラスを作ろう
消費税の計算をするクラスとキャンペーン値引きの計算をするクラスを作ります。

```ruby:consumption_tax_calc_rule.rb
class ConsumptionTaxCalcRule
  attr_accessor :price, :product_type
  # product_typeは軽減税率を適用するか判断する情報（ということにしておいてください）
  def initialize(price, product_type)
    self.price = price
    self.product_type = product_type
  end

  def tax_included_price
    price * tax_rate
  end

  def tax_rate
    # 消費税率を返す
  end
end
```

```ruby:campaign_discount_calc_rule.rb
class CampaignDiscountCalcRule
  attr_accessor :price, :campaigns
  # campaignsはキャンペーン値引きのための情報（ということにしておいてください）
  def initialize(price, campaigns)
    self.price = price
    self.campaigns = campaigns
  end

  def discounted_price
    # このメソッドからしか呼ばれないメソッドが増えても、
    # キャンペーン値引き計算クラスに
    # キャンペーン値引きのためのメソッドが増えるだけだから何もおかしくない！
  end
end
```
商品クラスは、CalcRuleクラスを使うだけです。

```ruby:product.rb
class Product < ApplicationRecord
  def billing_price
    discount_rule = CampaignDiscountCalcRule.new(price, campaigns)
    tax_rule = ConsumptionTaxCalcRule.new(discount_rule.discounted_price, product_type)
    tax_rule.tax_included_price
  end
end
```
これで、消費税が変わったり、キャンペーンが変更になってもCalcRuleクラスだけ確認すればよくなりました！
***
このエントリは[要求分析駆動設計](https://linyclar.github.io/software_development/requirements_analysis_driven_desgin/)の[ビジネスルール](https://linyclar.github.io/software_development/requirements_analysis_driven_desgin/#%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%AB%E3%83%BC%E3%83%AB)の計算について具体例を示し汎用的な内容に書き換えたものです。
めっちゃ長いけど、RailsでDDDっぽいことする話です。
【Laravel】【PHP】【初心者】Laravelでのトレイトの使い方


違う階層の複数のクラスで、共通化できる処理が存在した場合、トレイトに共通処理を書き出しましょう。

##メリット
・クラスの継承と違って1つのクラスで複数のトレイトを使用できる
・上記も含め継承よりも簡単に共通処理をまとめられる＋修正できる

トレイトに書き出してあることで、修正する際も共通処理の意識を持って(他に影響がないか確認して)、修正できるという面もあるかと思います。

##使い方

たとえば、下記のようなメソッドがあっちのサービスにもこっちのサービスにもあった場合。

```php5:HogeHogeService.php

private function sendMailForUser(int $id)
{
	$user = User::findUser($id);
	$address = $user->mail_address;

	Mail::send(['text' => 'mail'], '', function($email) use ($address) {
        $email
            ->from('hoge@hogehoge.jp')
            ->to($address)
            ->subject('あれの件について');
    });
}
```

下記のようなトレイトを作成し、

```php5:App\Traits\SendMailTrait.php

<?php

namespace App\Traits;

use Illuminate\Support\Facades\Mail;

Trait SendMailTrait
{
    public function sendMailForUser(int $id)
	{
		$user = User::findUser($id);
		$address = $user->mail_address;

		Mail::send(['text' => 'mail'], '', function($email) use ($address) {
	        $email
	            ->from('hoge@hogehoge.jp')
	            ->to($address)
	            ->subject('あれの件について');
	    });
	}
}
```

```php5:HogeHogeService.php
use App\Traits\SendMailTrait;

class HogeHoge
{
	use SendMailTrait;
}

```

これをメソッドを使用していたクラスでuseしてしまえば、あとは

```php5

$this->sendMailForUser($id)
```

で使用できます。とっても簡単。

共通処理化したら、元あったメソッドは忘れず消しましょう。
クラスに同名のメソッドがあると、クラスのメソッドが優先されます。
ちなみにトレイトを複数useしていて、同名のメソッドがあるとエラーが出ます。
状態遷移があるならStateクラスを作ろう

状態遷移するデータがあるとこんなコードが頻発しますよね。

```erb:view.html.erb
<%# reportのstateが1か2だったら承認ができないみたいだけど、1と2ってどういう状態なの？ %>
<%= button_tag('承認', disabled: (report.state == 1 || report.state == 2)) %>
```

```ruby:reports_controller.rb
def accept
  report = Report.find(params[:id])
  # ハンドリングのためにviewと同じ条件文が必要になる！
  if report.state == 1 || report.state == 2
    flash[:error] = '承認できません'
    redirect_to root_url
  end
  report.state = 3 # 承認の値！
  report.save!
end
```

定数を使えば少し改善するけど・・・

```erb:view.html.erb
<%= button_tag('承認', disabled: (report.state == Report::STATE_DRAFT || report.state == Report::STATE_TRASH)) %>
```

```ruby:reports_controller.rb
def accept
  report = Report.find(params[:id])
  # 結局viewと同じ条件文が必要になる！
  if report.state == Report::STATE_DRAFT || report.state == Report::STATE_TRASH
    flash[:error] = '承認できません'
    redirect_to root_url
  end
  report.state = Report::STATE_APPROBAL
  report.save!
end
```

```ruby:report.rb
class Report < ApplicationRecord
  # 定数が必要なカラムが多いと定数がたくさん必要になる
  # それにスコープが広すぎて用途が見えづらい
  STATE_DRAFT = 1
  STATE_TRASH = 2
  STATE_APPROBAL = 3
end
```
定数ではなく、ActiveRecord::Enumを使う方法もあるけど、同じ条件文がいろいろな場所で必要なことは解決しない・・・。ActiveRecordモデルにメソッドを追加すれば一応解決できる。

```ruby:report.rb
class Report < ApplicationRecord
  STATE_DRAFT = 1
  STATE_TRASH = 2
  STATE_APPROBAL = 3

  def can_accept?
    state != STATE_DRAFT && state != STATE_TRASH
  end
end
```
でも、これはFat Modelへ続く道だ・・・。
なので・・・

# 状態遷移を管理するクラスを作ろう
ActiveRecordモデルのFat Model化を回避して、責務が明確な状態遷移のクラスを作りましょう。
条件文は`report_state.approval_in_next?`[^1]（承認状態にできるか）という感じにして、`report_state.to_approval`という状態変更のメソッドもあると嬉しい。

[^1]: 「次の状態の中に承認はあるか」というつもりのメソッド名なのだけど、英語クソ雑魚なので他によいメソッド名があるかも

```ruby:reports_controller.rb
def accept
  report = Report.find(params[:id])
  report_state = report.state_object
  # すっきり
  unless report_state.approval_in_next?
    flash[:error] = '承認できません'
    redirect_to root_url
  end
  # これはカラムが1つだけの単純な例だけど、状態遷移の処理が複雑でもto_*メソッドに隠蔽できる！
  new_report_state = report_state.to_approval
  report.state = new_report_state.state
  report.save!
end
```

```ruby:report.rb
class Report < ApplicationRecord
  # state_object=メソッドも作ると便利かも
  def state_object
    ReportState.new(state)
  end
end
```
実際のReportStateクラスはこんな感じ。

```ruby:report_state.rb
class ReportState
  attr_accessor :state
  # Reportクラスから定数を引越し。ずっと納まりが良くなってる
  DRAFT = 1
  TRASH = 2
  APPROBAL = 3

  def initialize(state)
    self.state = state
  end

  def approval_in_next?
    state != DRAFT && state != TRASH
  end

  def to_approval
    raise '不正な状態遷移！' unless approval_in_next?

    self.class.new(APPROBAL)
  end
end
```
これで、承認できる条件が複雑になったり、承認ステータスへの状態遷移処理が複雑化してもここを変更するだけでよくなりました！
***
このエントリは[要求分析駆動設計](https://linyclar.github.io/software_development/requirements_analysis_driven_desgin/)の[状態遷移図、状態遷移表](https://linyclar.github.io/software_development/requirements_analysis_driven_desgin/#%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E5%9B%B3%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E8%A1%A8)を再編し汎用的な内容に書き換えたものです。
めっちゃ長いけど、RailsでDDDっぽいことする話です。
tarコマンドでアーカイブファイル内から指定した個数のファイルを取り出す

# tarコマンドでアーカイブファイル内から指定した個数のファイルを取り出す

##100件取り出す
###アーカイブファイル内にディレクトリがない場合

```bash
tar tf logfile.tar
hoge1.txt
hoge2.txt
hoge3.txt
hoge4.txt
....
```
```bash
$ tar xvf logfile.tar $(tar tf logfile.tar | head -100 )
```

###アーカイブファイル内でディレクトリ分けされている場合
```bash
tar tf logfile.tar
log/
log/hoge1.txt
log/hoge2.txt
....
data/
data/foo1.txt
data/foo2.txt
...
```
```bash
$ tar xvf logfile.tar $(tar tf logfile.tar log/ | head -100 |sed '1d' )
```

sortなどを組み合わせて、サイズが大きい順に取り出したりもできる
【iOS】画像が一色に塗りつぶされてしまうときの対処法

NavigationBarにオリジナルの画像を置いて、少しリッチにしたいこと、ありますよね？
そのとき、いつものやり方でやろうとすると青一色で表示されてしまいます。


・理想
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318427/848e33f6-c483-5337-a79a-57e98aaa2f50.png" width=25%>

・現実
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318427/cb41e095-b584-cf29-f8f1-37cd31c0e07c.png" width=25%>

こうなることを回避するためにどうすればいいのか、備忘録的に残しておきたいと思います。

## いつものやり方

まずはいつもどおりにやってみます。コードで書くとこんな感じでしょうか

```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupNavigationBar()
    }

    private func setupNavigationBar() {
        navigationItem.title = "メインページ"
        
        let button = UIButton(type: .system)
        button.setImage(UIImage(named: "button_refresh"), for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        
        let rightItem = UIBarButtonItem(customView: button)
        navigationItem.rightBarButtonItem = rightItem
    }
    
    @objc private func buttonAction() {
        print("ボタンの色がおかしいよ！！！")
    }
```

本当はStoryboardで追加したほうが早いんですが、このあたりはコードで書く派なので、だいたいこうしてます（鉄の意志）。

とりあえずこんなふうに書いちゃうと、ボタンのアイコンが青一色で塗りつぶされてしまい、悲しい気持ちになっちゃうわけですね。

## 対処法その１（コードで書く場合）

コードで書く場合は、buttonにsetImageしているところをちょっと書き換えるだけでOKです。
具体的にはこんな感じ。

```swift
button.setImage(UIImage(named: "button_refresh")?.withRenderingMode(.alwaysOriginal), for: .normal)
```

UIImageにはRenderingModeが存在し、

| | |
|:---|:---|
|automatic|デフォルト。画像を使うタイミングでよしなにモードを選んでくれる|
|alwaysOriginal|常にオリジナルの画像を表示する|
|alwaysTemplate|ボタン等のtintColorに左右される|

の３つが指定できます。
今回はNavigationBarにオリジナルの画像を表示させたいので`alwaysOriginal`を指定しました。
逆にtintColorに合わせたい場合は`alwaysTemplate`を指定すればいいわけですね。

## 対処法その２（Assets.xcassetsで直接指定する場合）
とはいえ、いちいちコードで書くのは面倒だと思ったあなたのために、Assets.xcassetsで直接できる方法があります。
まずは、Assets.xcassetsを開いて目的の画像を選択して、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318427/6e699642-9114-0d93-952d-fe0284d6a623.png" width=50%>

右側のImage Setの項目のうち、上から２番めの`Renser As`を見ます。特に何も指定していなければ`Default`になってるはずです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318427/6f5f44bb-73ea-acb6-b7c8-235ab4f1c7db.png" width=25%>

あとはもうお解りですね。`Renser As`の値を`Original Image`に変更すると、コードで`withRenderingMode`を使わなくても自動で`alwaysOriginal`になってくれます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318427/824025c7-2f60-4fdd-176e-1b417267dccf.png" width=25%>

## まとめ

というわけでUIImageのRenderingModeについての設定方法でした。
意外と使う機能なのに、ふとしたことで思い出せなくなることがあるので（4敗）、みなさんも気をつけてくださいね。
getElementsByNameで取得したラジオボタンでイベントが発生しない

#ラジオボタンが複数ある時、onchangeが発生しない場合の対処法

先日、JavaScriptを使って、ラジオボタンにonchangeイベントを設定しようとしたのですが、上手く実装できませんでした。ラジオボタンが一つだけであれば、idを取得すればよいのですが、今回は複数あったのでidだとコードが冗長になってしまう．．．。ここでメモ程度に記録しておきます。

今回用意するHTMLは以下の通りです。

```html
/*ラジオボタン群*/
<input type="radio" name="r" id="r_1" value="1" checked="checked" /><label for="r_1">ラジオ１</label>
<input type="radio" name="r" id="r_2" value="2" /><label for="r_2">ラジオ２</label>
<input type="radio" name="r" id="r_3" value="3" /><label for="r_3">ラジオ３</label>
<input type="radio" name="r" id="r_4" value="4" /><label for="r_4">ラジオ４</label>
```


JavaScriptはこちら

```js

//ラジオボタン群を取得
var r = document.getElementsByName('r');

r.onchange = function() {
	//これだとonchangeは発生しない
}
```

こんな感じで、別のラジオボタンをクリックしたらonchangeが発生して...といった具合に
処理を書いていたのですが、いざ実行すると何も動かない。デバックしてみるとonchangeがそもそも発生していない。

選択リストであれば、nameを取得して、これでできるはずなのになぜだ．．．。

原因はラジオボタンをnameで取得した場合は、ラジオボタンの各情報が配列で格納されていたからでした。
なので、配列を一つ一つ取り出してから、それぞれにonchangeを設定していく必要があったみたいです。

修正したのがこちら。

```js
//ラジオボタン群を取得
var r = document.getElementsByName('r');

for (var i = 0; i < r.length; i++) {
		r[i].onchange = function() { //配列を取り出し一つ一つにonchangeを設定
			for (var j = 0; j < r.length; j++) {
				if (r[j].checked == true) {
					//j+1番目のラジオボタンがチェック状態になった時の処理
			}
		}
	}
}
```

といった感じで無事問題は解決しました。


ちなみにjQueryを使えばこんなことをしなくても．．．

```js

$('input[name="r"]').change(function() { //←これだけでいい。
        /*ちなみにチェックされたラジオボタンの情報はthisに入っている。
        下記はチェックされたラジオボタンのvalue値を取得できる。*/
		$(this).val();
});
```

上記のような具合で、配列なんか使わなくても、たった1行でonchangeが設定できてしまいます。

##まとめ
選択リストは、選択リストで一つのもので、ラジオボタンはそれぞれ独立しているイメージ。
だから選択リストはnameを取得してもonchangeを設定できるけど、ラジオボタンでnameを設定してもonchangeは効かない。独立しているから、それぞれに設定する必要がある。
（言葉にするのが難しい．．．）

以上。
python学習(補足)

先に記載したpythonのCSVモジュールについての補足である

正直ドキュメントやググれば分かる内容だが、
備忘録として残しておく

CSVファイルを開いて別ファイルにそのまま書き出したい場合
リスト形式で渡すにはreaderメソッドを使う

この時readerメソッドの返り値はもちろんリスト形式となる

```
import csv

data=[]

#CSVをリスト形式で読み込む
with open('data.csv' , 'r', newline='' , encoding='utf-8') as f:

    r = csv.reader(f)
    data = [ i for i in r ]

#CSVをリスト形式で書き込む
with open('data.csv' , 'w', newline='' , encoding='utf-8') as f:

    w = csv.writer(f)
    w.writerows(data)
```

この時dataに入るのは以下のような多重リストとなる

```
[['python', '1'], ['php', '1']]
```

writerowで書き込む時は引数としてはリストが渡されるのだが、
上記のような多重リストの場合はwriterowsとしなければいけないところが注意

試しにwriterowとやった場合は以下のような返り値となる(一行のリストとして返ってくる)

```
"['python', '1']","['php', '1']"
```

writerowsとやった場合はきちんと以下のような返り値となる

```
python,2
php,2
```

辞書形式で渡すにはDictReaderメソッドを使う

この時DictReaderメソッドの返り値はもちろん辞書形式となる

```
from collections import defaultdict
import csv

data = defaultdict(int)

with open('data.csv' , 'r', newline='' , encoding='utf-8') as f:

    r = csv.DictReader(f)
    data = [ i for i in r ]    #リスト内に辞書を格納

with open('data.csv' , 'w', newline='' , encoding='utf-8') as f:
    fieldnames =['Name', 'Count']
    w = csv.DictWriter(f, fieldnames= fieldnames)
    w.writerows(data)
```

リストの時と同様に変数の中を見ていくとdata変数に入るのは以下の通り

```
[{'Name': 'python', 'Count': '1'}, {'Name': 'php', 'Count': '1'}]
```

今度は辞書としてキーとバリューが入ってくる

書き込む際はwriterowメソッドには引数としてリストが渡されるので、
実際はリストで辞書の中身を渡すイメージとなる

リストの時と同様にwriterowで書き込もうとすると以下の通りAttributeErrorとなる
リストオブジェクトにはkeyという属性はありませんと怒られる

```
AttributeError: 'list' object has no attribute 'keys'
```

writerowsを使えばリストの時と同様に以下のように書き込める

```
python,1
php,1
```

基本リストも辞書も多重で渡す場合はwriterowsメソッドを使うという理解をした。
WPF 開発が捗る 神７

## はじめに

独学で習得してきた WPF ですが、決定的な指針が無く、開発が手探りになりがちでした。日本語の文献は少なく、ブログ等で有識者の手法を真似て実装しますが、流行り廃りが早いためなかなか環境が固まらない状況が続いていました。
それでも徐々に実務で WPF を活かせる機会が増え、これに伴い使用するフレームワークやサードパーティー類が定まってきています。ここでは 2020 年現在で自分が思う開発が捗るライブラリをいくつかご紹介します。

## 本文

1. [Prism (Unity)](https://www.nuget.org/packages/Prism.Unity/) + [Livet (Messaging)](https://www.nuget.org/packages/LivetCask.Messaging/)
言わずと知れた MVVM インフラ 兼 DI コンテナです。
疎結合の土台として Prism と Unity がアプリケーション全体を支えます。
破棄された InteractionRequest の代わりは、新設された DialogService と、Livet の InteractionMessenger で補います。

1. [ReactiveProperty](https://www.nuget.org/packages/ReactiveProperty/)
プロパティの変更通知は Prism でも出せますが、変更の購読や合体、コマンドへの変換まで ReactiveProperty は何でもやってくれます。
ViewModel 側の処理の起点は、ほとんどこれで記述できそうです。
    
1. [MahApps.Metro](https://www.nuget.org/packages/MahApps.Metro/)
いわゆるデザインテンプレートになります。
デザインに自信が無くても、それっぽい見た目に仕上げてくれます。
このデザインと調和する多数の[アイコン](https://www.nuget.org/packages/MahApps.Metro.IconPacks/)も提供されています。

1. [QuickConverter](https://www.nuget.org/packages/quickconverter/)
これが無いと Xaml が書けないほど頼り切ってしまっている汎用コンバーター。
Xaml 上で C# を書けるため、複雑な変換やイベントのハンドリングまでこなしてくれます。
ただし、これに浸かり過ぎると本来の Xaml って何だっけ？となります。

1. [GridExtra](https://www.nuget.org/packages/GridExtra/)
レイアウトに頻出する Grid の面倒な行列定義を、一行でスッキリと記述できるようになります。
一つ一つは僅か数行の差ですが、プログラム全体で見ると結構節約できています。
そのほか、まるで Bootstrap のようなレスポンシブな Grid も作れます。

1. [System.Interactive](https://www.nuget.org/packages/System.Interactive/)
標準の LINQ には無いメソッドやサポートされていないコレクションへの拡張メソッドが豊富にあります。
あらゆるコレクションに対して、その違いを意識せず、共通ロジックで様々な操作を実行できるようになります。

1. [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/)
WebAPI や設定ファイルなどでスタンダードな JSON 形式との相互変換をサポートします。
とても手軽で特に何も書かずともイメージ通りに変換してくれるほか、業務ロジック的なゴリゴリの変換にも対応できる拡張性を持ち合わせています。

##### 悩んだもの

- [MethodDecorator.Fody](https://www.nuget.org/packages/MethodDecorator.Fody/)
アスペクト指向的に横断処理を挟んでいける黒魔導書です。
メソッドを通過した際のログ出力などに使っていますが、私が使いこなせていないため今回は入れられませんでした。

- [Vanara.PInvoke (User32, etc.)](https://www.nuget.org/packages/Vanara.PInvoke.User32/)
これだけフレームワークが発展していても、際どい処理にはまだまだ現役な Win32 です。
``` public static extern ... ``` のあの記述がたくさん入っています。
ただ、どこまで Win32 に頼って良いものか、モヤモヤが晴れずにいます。

## おわりに

Windows Forms の後継として登場した WPF ですが、圧倒的な知的資産を持つ Forms からの移行は、現場レベルではなかなか進まず、さらには同様の開発手法を受け継いだ UWP も登場し、WPF の今後にヤキモキしていました。

そんな中、.NET Core 3 に Windows Forms, WPF が仲間入りしたことで、再び注目が集まっています。これまでは UWP か Desktop Bridge によるパッケージ化が必要だったストアアプリ開発にもこれらが使えるようになり、開発の幅が広がっています。また、オープンソース化されたことで、有志によるフレームワークの強化にも期待が持てます。

業務アプリの開発は得てして複雑化するものです。最近では直感的に操作できるユーザビリティも求められ、単に機能を提供するだけでは済まなくなっています。強力で自由度が高い画面描画による視認性に加え、Windows の奥深くまで操作できることによるビジネスロジックの実現性も兼ね備えた WPF は、引き続き有力な選択肢の一つだと考えています。
vue cliとは

## vue-cliとは

>cliはCommnad Line Interfaceの略で、コマンドラインを使ってvue.jsで開発を行うための前準備を支援してくれるツールです。開発はプロジェクトという単位で行います。vue-cliを使ってプロジェクトの作成を行う際、プロジェクトで利用する機能のインストールも一緒に行うことができます。webpackも一緒にインストールされるでプロジェクトを作成すればすぐに開発を開始することができます。
https://reffect.co.jp/vue

vueで開発するための道具ってことか。

##　インストール方法(node.jsがインストールされている必要がある。)

```
$ npm install -g @vue/cli
```

## プロジェクトの作成

```
$ vue create vue-application
```
このコマンドを実行した後に、こういう選択画面が表示される。

```
Vue CLI v4.4.6
? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to t
oggle all, <i> to invert selection)
 ◉ Babel
 ◯ TypeScript
❯◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

```

選択後は、localhostをひらけば、ok。railsみたいに、事前にファイルが作成されている。

vueconfig.jsの設定をするらしい(、、、詳しくはわからない)

## ちょっと疑問

Vue-cliとVuetifyの関係性？
vue-cliをダウンロードした後に、vuetifyをダウンロードする。
vuetifyについては、この記事がわかりやすいです。
https://techblog.kayac.com/2018/12/12/080000
限定共有のGoogle SitesのRSSをドライブに出してみた

2022/12/26現在、実行するとエラーになります

社内限定公開のサイトに対して（更新があるかどうか見に行くのめんどくさい。RSS欲しいな）って思って書いてみた。

RSSを読む部分はまた今度書く。

```code.gs
function myFunction() {
  // URLがhttps://sites.google.com/a/examples.com/example-site/なら
  // Feed URLはhttps://sites.google.com/feeds/content/examples.com/example-site  
  var url="https://sites.google.com/feeds/content/(ドメイン名)（サイト名）"

  // 自分の認証トークンを取得してHTTPヘッダーに入れる
  var Token=ScriptApp.getOAuthToken()
  var headers = {
    "GData-Version" : "1.4",
    "Authorization" : "Bearer "+Token
  };

  // HTTPSで取得
  var params = {"headers": headers, 'method':'get', 'muteHttpExceptions':true};     
  var response = UrlFetchApp.fetch(url, params);

  // GoogleドライブのフォルダIDを取得
  // ルート以外ならgetFolderbyId()とかになるはず
  var folder = DriveApp.getRootFolder();

  //xmlファイル作成
  var contentType = 'text/plain';
  var charset = 'utf-8';
  var blob = Utilities.newBlob('', contentType, "sites.xml").setDataFromString(response, charset);
  folder.createFile(blob);
}
```
Local by Flywheelの紹介

#WordPress
![スクリーンショット 2020-10-30 11.11.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/addea5e1-c1b2-dfb5-45c6-a234e5602663.png)

[Local by Flywheel](https://localwp.com/)を使って、自分の手元のPCで作った仮想的なサーバー（ローカル環境）を作りました。
![スクリーンショット 2020-10-30 11.02.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/45a91870-d640-776d-ca95-a607b1d30075.png)

WordPressのテーマは「Vandana Lite」です。
【Xcode】初学者が出会ったエラー 虎の巻  "Cannot use instance member 'hoge' ~~"

iOS開発の学習を始めた初学者が、学習をしていく道中で出会ったエラーなどを備忘録的に残していきます。

※この記事は初学者のアウトプットを目的としており、個人的な理解によるものなので、誤った解釈を招く可能性がありますことをご承知下さい。誤りがある場合はご指摘いただければ都度修正させて頂きます。

## なぜ残すのか？
入門書にて学習をしている際、それなりの数のエラーに遭遇しました。しかし入門書では「エラーが出ますがページを進めると解消しますので問題ありません」といった文言によりスルーされるケースが多いように見受けられました。

エラー表示なんてそんなもの、と言われたらそれで終わりなのですが、放置しているみたいで何となく気持ち悪かったので以下をノートしていくことにしました。

- なぜエラーが表示されているのか？ 
- 解消方法
- 上記が分からない場合は、せめて直訳だけでも

これらを残して、同じエラーに出会った時にイチから調べ直す労力を少しでも減らせればと考えています。
学習初めは単なる日本語訳だけが多くなるとは思いますが、理解していくたびに内容更新していきたいと思います。

## `Cannot use instance member 'hoge' within property initializer; property initializers run before 'self' is available`

### 直訳
エラー文をざっくり直訳してみると、"プロパティが初期化されていなくてインスタンスのメンバが使用できないよ。"という感じ。

### 原因
クラスの定義をしていないのにインスタンスにアクセスしようとしていること。

### 解説
menberは値に紐づく定数や変数のことで、インスタンスが持つプロパティにあたるといえます。
クラスを定義することによってインスタンスのプロパティやメソッドにアクセスできるようになるので、クラスの定義をせずにアクセスしようとするとエラーが出てしまう。

#### 参考書籍等　
swift実践入門(P34, 2章メンバー式)
python学習

pythonの学習をするにあたって開発エンジニアではない私のようなインフラエンジニアでも
すごくわかりやすく説明してくれるudemyのpython講座をお勧めしたい
特に講師の酒井潤さんは話し方も聞き取りやすく内容もかなり広い部分を網羅しているので、
実際にコードスタイルにも言及していたり実務的なナレッジも学べるのでありがたい
(※個人的にはこういうのはあまり市販の本を読んでもわからないとことだと思う)

https://www.udemy.com/course/python-beginner/

その課題の中にQ&Aでロボットがお勧めのレストランを聞いてきてその答えをCSVに書き出して答えの数をカウントアップしていくという課題があるのだがこれが難しい。。。

正直ここで一度挫折して投げたのだが最近また別件でPythonを触れる機会がありまた勉強意欲が再燃した

まだ先の課題の完成には程遠いがCSVにカウントアップされる処理について根底の部分はできたので、
自分がハマったところについて備忘録として残しておく。

【はまった部分】
まずCSV上で入力した内容のカウントアップという処理ができない。
ググってみたところ色々な人が同じ内容で悩んでいて世界は狭いんだなあと実感した

具体的にはCSVでファイルを読みだした時にそのままファイルに書き込もうとしてもできない
よく考えれば読み出す時点でreadモードでopenメソッドを呼び出しているので
そのまま書き込めるわけがないのだが、ここら辺は同じことではまっている人が何人かいた。

なので読み出した時点で読み出した内容を変数に書き出して
その書き出した変数を処理の最後にまとめてCSVへ書き込むということをしないといけない。

よって具体的な処理の流れは以下の通りとなる

- 1. 出力するCSVファイルが存在するかしないか？

    - 1-1. 存在する場合
最初に存在するCSVファイルを全行読み込む
        - 1-1-1. もし既にキーが存在したらそのキーのバリューをカウントアップして変数に格納して最後にまとめてCSVへ書き出し
        - 1-1-2. キーが存在しなかったら新規にキーとバリューをCSVへ書き出し

    - 1-2. 存在しない場合
新規にCSVを作成する→この処理は上記のudemyのpython講座で説明されているため簡単

以上を踏まえて以下のようなコードを書いてみた

```
import csv
import os

from termcolor import colored

while True:
    print(colored('=' * 20, 'green'))
    print(colored('どこのレストランが好きですか？', 'green'))
    print(colored('=' * 20, 'green'))
    name = input()
    name = name.title()
    if name:
        break

#CSVを新規に作成するためのメソッド
def new_csv():
    with open('data.csv', 'w', newline='', encoding='utf-8') as csv_file:
        fieldnames = ['Name', 'Count']
        writer = csv.DictWriter(csv_file,fieldnames=fieldnames)
        writer.writeheader()
        writer.writerow({'Name': name,'Count': 1})

#data変数を最後にCSVへ書き出すためのメソッド
def csv_output():
    with open('data.csv', 'w', newline='', encoding='utf-8') as csv_file:
        fieldnames = ['Name', 'Count']
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        writer.writeheader()
        data_sorted = sorted(data, key=lambda x: int(x['Count']),reverse=True)
        writer.writerows(data_sorted)

#CSVへ新しいデータを追記するためのメソッド
def csv_appending():
    with open('data.csv', 'a', newline='', encoding='utf-8') as csv_file:
        fieldnames = ['Name', 'Count']
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        writer.writerow({'Name': name,'Count': 1})

"""
data.csvが存在すればdata変数にCSVの内容を読み込み
存在しなければnew_csvメソッドをcall
"""
if os.path.exists('data.csv'):
    with open('data.csv', 'r', newline='', encoding='utf-8') as csv_file:
        reader =csv.DictReader(csv_file)
        data = [row for row in reader]

        # 既にキーが存在すればカウントアップ、一通りループを回して存在しなければcsv_appendingメソッドを呼び出し
        for row in data:
            if row['Name'] == name:
                row['Count'] = int(row['Count']) + 1
                csv_output()
                break
        else:
            csv_appending()
else:
    new_csv()
```

一旦これでやりたいことはできているが、多分もっといい書き方があると思う。
あとオブジェクト指向？MVCフレームワーク？って感じなのでもう少しなれたらもっと洗練されたかっこいいコードが書けると思うが一旦ベースのロジックの部分はできているのであとは如何に拡張性とか視認性とかを上げていくかという部分かなと思う。
他には作成したCSVファイルを最終的に集計するなんて処理を追加しても面白いかも。。。

個人的にはこうするとコードもっと良くなりますよってアドバイスが欲しいです！！

ありがとうございました。
AWSコンソールへのログインに、IP制限とMFA制限をかける

# マネジメントコンソールの運用

よくあるポリシーとして、多要素認証の設定強制＆IP制限をかけることがあります。

今回はそのポリシーと私自身が注意していることを記載します。


# 概要

マネジメントコンソールはIAMユーザを使用する。

IAMは**AWSの各種リソースへのアクセス許可**を管理するサービスであり
結構細かい権限まで、**コードベース(JSON, IaCならYAML定義も可)**で管理できる。

各権限は**IAMポリシー**と呼ばれる単位で定義ができ、作成した後**IAMユーザ**に割り当てる。
通常は同様権限のユーザが複数存在するため、**IAMグループ**を使用して管理する。

例；
インフラチーム；Admin権限
開発チームA；全基本サービスの読み書き権限
開発チームB；EC2,Code系サービスのみ読み書き権限
テストチーム；Read権限のみ
監査チーム；セキュリティサービスのみRead権限
など

運用方法によるが、基本**IP制限、MFA強制のポリシーは全員に対して有効にさせる**必要があるので、
IAMグループにそれぞれ割り当てるか、共通に属する専用のグループを作成して、全ユーザに属させることで実現。


# 使用するIAMポリシー

## IP制限
※適当なプライベートIPアドレスに変えてる

```
{
  "Version": "2012-10-17",
  "Statement": [
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "10.20.20.20/28",
            "10.10.10.10/32"
          ]
        }
      }
    }
  ]
}
```

**「指定IPからのアクセス以外は、全てのアクションを拒否する」**


前提として、このポリシーに加えて必要な権限のみをアタッチする運用。

単純にこのポリシーのみだと
指定したCIDRの範囲でアクセスすれば、全リソースへのアクセスを許可する。

例えばS3の権限のみポリシーがアタッチされているユーザであれば、
指定IPからのアクセスであればその権限が使用可能。

IAMのポリシーは、どんな場合でも**Denyが最優先**となる。
他のポリシーで拒否がかかればそのDenyポリシーが優先される。


## MFA強制

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice",
                "iam:DeactivateMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ListUsers"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": false
                }
            }
        }
    ]
}
```

「MFAが有効でない場合は、MFA関連以外の全てのアクションを拒否する」

ちなみに拒否状態だとこういったコンソール画面になります。
![スクリーンショット 2020-10-27 11.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/e66e4dba-5d95-f757-3864-ecc56073ba13.png)


# Tips

IAMの権限を設定したけど適切かどうか検証するのが大変ですが
IAM Policy Simulatorを使用すると便利です。

IAMのグループ画面 > アクセス許可 > ポリシーのシミュレート　等から使用できます。


![スクリーンショット 2020-10-28 14.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/fb1e8cc4-ebb0-ed67-dcb4-2313dd6368a2.png)


また、注意点として、Adminユーザが自身のアクセス権限を変更する際は
もう一人のAdminユーザを**別に用意**しておきましょう。。

間違うと自分の権限をロックしてしまってrootを引っ張ってくる事態になりかねないです。


# まとめ

IAMは絞ろうと思えば極限まで絞れます。
ただ、はじめは検証を重ねて時間がかかること多いです。

開発段階では無理せず**AWSマネージドポリシー**を使用しつつ、
余裕があるときに絞っていく方針が良いのではと思います。
3分アジャイル KPT

## 連絡事項

- 11:00 〜 Insomnia勉強会 Googleドキュメントでドキュメンテーション
- 16:00 〜 スプリントレビュー
- 上記終わり次第 レトロスペクティブ（1時間）

---

## 連絡事項

- KPT用Miroのアカウント作成
- もし時間があれば書いてもらえるとありがたいです

---


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/074dd17f-2660-c744-9c82-bd3a42c8f67f.png)


---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/88165e5b-843b-2844-9ff5-6a459deeea3a.png)

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/4a6c952b-d502-e245-84d5-d1a6ab930d25.png)


---

## デイリー

- 昨日やったこと
- 今日やったこと
- 個人、チームが困っていること

---
【Java・Intellij】統合開発環境の基本(Intellij)・ショートカット

#統合開発環境（IDE）の基本
* Eclipse:ワークスペース以下にプロジェクトがある
* **Intellij**:プロジェクトの中にモジュールがある
    * **パッケージエクスプローラ**：全体の構成（`Com+1`）
    * **アウトライン**：ストラクチャー(`Com+7`)

#Intellijの機能
* Preferenceの設定
    * `PreferenceのEditorTab - left` ：たくさんコードを開いたときに見やすい
    * `Tab limit 20`

* ショートカット
    * **ediitorを中心に各ビューに行って戻ってくる動作をしよう**
    * できるだけキーボードから手を離さないようにする
    * `Com+数字`でビューに飛んで(`Com＋1`でProjectなど)`esc`でeditorに戻る
        * 例えば、タブに”7 Structure” のような表示がある→ショートカット`Com+7`で飛べる
        * `Com+7`：メソッド登録確認。大量のコードの場合に便利

![ショートカット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/50a9a3ba-3337-cbfa-61a4-dc244a0f315f.png)


* Favorite機能
    * 1000行くらいのコードで編集ポイントが分割してしまう
    * →`Fn3`でブックマーク、レ点が入る
    * `Com+2`でFavoriteにとび、ブックマークに登録、確認できる

* 実行時標準出力
    * Run、Debugモード
    * 右上のEditor Configurations からの実行構成を編集できる
    * 三角▶︎は普通に実行、虫🕷はDebug実行
    * Debug実行はstepごとに確認できるので基本この機能で開発

* Debug実行で5タブにDebugが出てくる
    * `Com+5`でDebug windowへ、`Com+R`で再実行
    * Build viewはこのPJの構成依存で変わる(Mavenなど使うビルドシステムで表示違う)


###便利なショートカット例 (Mac)
* 選択行を上下に移動:`Option + Shift + ↑／↓`
* 選択行を他の行と入れ替える:`Command + Shift + ↑／↓`
* 現在の行を複製:`Command + D`
*  現在の行を削除 `Command + Delete`
* 新しい行を追加:`Shift + Enter`
* マルチカーソル:`Ctrl + G`
* パッケージを作成：`Command + N + p `
* コード補完:`Shift＋ Command ＋ Enter`
*  選択箇所をタグ、if、while、forなどで囲む:`Command + Option + T`
* 選択範囲の型を表示:`Ctrl + Shift + P`
* 宣言へジャンプ(return先など): `Command + B`
* 実装クラスへジャンプ(Post元など):`Command + Option + B`
* 変数が使われている箇所へジャンプ:`Command + Option + F7`
* 継承関係をクラス図(下図参考)で表示:`Command + Option + U`
* リネーム(Rename):`Shift + F6`
* テキスト検索(ファイル横断):`Command + Shift + F`
* なんでも検索(クラス、ファイル、シンボルetc):`Shift 2回`
* 不足するimport文追加:該当行で`Option + Enter`

クラス図:`Command + Option + U`
![クラス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/873f1e5a-f515-d994-8a7d-8051745653da.png)

####※Touch Bar搭載Macはファンクションキーを常に表示がおすすめです
* システム環境設定→キーボード→ショートカット→「+」をクリックして、App を探してIntellij選択
* https://support.apple.com/ja-jp/HT207240
AWS EC2 AmazonLinux2インスタンスにPhpRedisをインストールする

# 目的

- AWS EC2 AmazonLinux2インスタンスにPhpRedisをインストールする方法をまとめる

# 実施環境

- 下記の方法を用いてインスタンスにLaravelの実行環境を構築した。
    - [AWS EC2 AmazonLinux2だけでLaravelのアプリをデプロイする](https://qiita.com/miriwo/items/b39d1ac6289c54cc2cfd)

# 前提条件

- AmazonLinux2インスタンスが起動し、皆さんのお手持ちのPCからsshで当該インスタンスに入る事ができること。
- 実施環境と同一もしくは近い方法でPHPの環境構築がされいること。`$ php`コマンドがインスタンスのターミナルで実行できればおそらく大丈夫なはずである。

# 前提情報

- 本記事て実行しているコマンドは特筆しない限りインスタンスにssh接続して実行するものとする。

# 詳細

1. 下記コマンドを実行してインスタンスのyumでインストールしたパッケージを最新にアップデートする。

    ```terminal
    $ sudo yum update
    ```
1. 下記コマンドを実行してPhpRedis拡張のインストールを実施する。

    ```terminal
    $ sudo yum install php-pecl-redis
    ```
1. yumインストールの確認画面で下記のように表示されパッケージ「php-pecl-redis」と「php-pecl-igbinary」がリポジトリ「amzn2extra-phpX.X」からインストールされることを確認する。

    ![AWS_EC2_AmazonLinux2インスタンスにPhpRedisをインストールする_md_—_miriwo_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/db70b6f6-cbce-0724-e3aa-8af69e905af4.png)

1. 同一リポジトリからインストールされることを確認できたら「y」を入力しEnterを押下する。「完了しました！」の文字が出力されることを確認する。
1. 下記コマンドを実行してパッケージがインストールされていることを確認する。

    ```terminal
    $ yum list | grep php-pecl-redis
    ```
1. 下記コマンドを実行してphp.iniの場所を出力する。`Loaded Configuration File =>`のあとに出力されているパスをコピーする。

    ```terminal
    $ php --ini | grep "php.ini"
    ```
1. 下記コマンドを実行してphp.iniファイルを開く。

    ```terminal
    $ sudo vi 先の手順でコピーしたパス
    ```
1. 下記の一行を追記して保存する。

    ```php.ini
    extension=redis.so
    ```
1. 下記コマンドを実行してApacheを再起動する。

    ```terminal
    $ sudo service httpd restart
    ```

# 参考文献

- [https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown](https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown)
Word VBAでVBA-JSONを使う

## はじめに
VBAでサーバーと通信しようとすると、JSON文字列をパースしたいことが多々あると思います。
そこで「[VBA-JSON](https://codeload.github.com/VBA-tools/VBA-JSON/zip/master)」を使おうと思い立ちましたが、
Wordならではのトラップがありました……

## インポート～使ってみる
まずはReadmeのインストールの項目を見てみます。

>Download the latest release
Import JsonConverter.bas into your project (Open VBA Editor, Alt + F11; File > Import File)
Add Dictionary reference/class
For Windows-only, include a reference to "Microsoft Scripting Runtime"
For Windows and Mac, include VBA-Dictionary

VBAはパッケージ管理等がないので、直接インポートですね。
”Microsoft Scripting Runtime”を参照設定に加え、いざ実行してみます。

```vb
Sub json_conv_test()

    Dim jsonStr As String
    jsonStr = "{" & _
            Chr(34) & "abc" & Chr(34) & ":" & Chr(34) & "ABC" & Chr(34) & "," & _
            Chr(34) & "def" & Chr(34) & ":" & Chr(34) & "DEF" & Chr(34) & _
            "}"
    '{"abc":"ABC","def":"DEF"}
    JsonConverter.ParseJson (jsonStr)
    
End Sub
```

ところが……

![JsonDictionaryError.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758865/98103b42-8455-e482-d2c9-1a7904f152f5.png)


**「Newキーワードの使用法が不正です」**と、コンパイルエラーが出ました。

## Dictionaryの検証

Word VBAは情報が非常に少ないです。宿命ですね。

まずは落ち着いて "Dictionary" のドキュメントを読みに行きます。
エディタでDictionaryを選択して F1 を押すと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758865/ceb6df7d-98d9-bc1d-a778-8f7118b5d0cb.png)

なんと、WordからもDictionaryオブジェクトがはえていました。

WordにもDictionaryオブジェクトがあるのですね（カスタム辞書機能）。
それでScripting.Dictionaryを呼び出したいのに、Word.Dictionaryが呼び出されていたことがエラーの原因でした。

## 解決

そこで、ソースの一部を修正します。

```vb
Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Scripting.Dictionary
    Dim json_Key As String
    Dim json_NextChar As String

    Set json_ParseObject = New Scripting.Dictionary
   '（以下省略）
```

上記のように"Dictionary"を"Scripting.Dictionary"に変更したところ、
無事、エラーなくパースすることができました。

## もう一つのつまづき
あと、この方法でJSONをパースしたら配列はArrayではなくCollectionになるようです。
なので要素数の取得には **UBoud** ではなく **.Count**を使う必要がありました。
また、要素は **1** から始まるのも忘れかけていました……
converting argument $1 type: unsupported type []string, a slice of stringに悩まされた話

#概要
エンジニア1年目の初投稿です。
sqlxを使ってDB操作をしていたら、下記のエラーに悩まされたので記録します。
コメント、ダメ出しなど頂けると嬉しいです。

```
converting argument $1 type: unsupported type []string, a slice of string
```

# シナリオ

SELECT文のWHERE句にIN条件を使った操作を行おうとしていたところ、エラーに嵌まりました。
今回は,以下のUSERテーブルからgoとpythonを使えるUSERを抽出する操作を書いていきます。

| Name | Skill |
| ---  | --- |
|Ichiro|  C  |
| Jiro | C# |
|Saburo| Java |
|Shiro | python|
|Goro | go|
|Rokuro| Ruby|
|Shichiro|go|

## 各種ツール

- go 1.14
- github.com/jmoiron/sqlx v1.2.0
- github.com/go-sql-driver/mysql v1.5.0
- mysql:5.7
- VSCode（1.50.1）


#ダメだったコード

 ``` go
	query := "SELECT Name,Skill  FROM USER WHERE Skill IN (?,?);"
	searchSkills := []string{"go", "python"}

	var records []User
	err := db.Select(&records, query, searchSkills)
	if err != nil {
		log.Fatal(err)
	}

	//converting argument $1 type: unsupported type []string, a slice of string
```
db.Selectにパラメータとして、[ ]stringを渡します。
コンパイルが通るのでうまくいくかと思いきや,掲題のエラーが発生します。
ちなみに、第三引数を`searchSkills...`にするとコンパイルが通りません。

#どうしたか
エラーメッセージ的に引数で渡している型が良くないってのはなんとなく分かります。
とりあえず、ドキュメントを読んでみる。
[https://godoc.org/github.com/jmoiron/sqlx#DB.Select](https://godoc.org/github.com/jmoiron/sqlx#DB.Select)

第三引数が`interface{}`の可変長引数だったため、`[]interface{}`を展開して投げてみます。

```go
	query := "SELECT Name,Skill FROM USER WHERE Skill IN (?,?)"
	// searchSkills := []string{"go", "python"}
	searchSkills := []interface{}{"go", "python"}

	var records []User
	err := db.Select(&records, query, searchSkills...)
	if err != nil {
		log.Fatal(err)
	}

	// Name:Jiro,Skill:go
	// Name:Saburo,Skill:go
	// Name:Goro,Skill:python
```
エラーの発生は抑えられてやりたいことも出来てます。
でも、あんまりスマートじゃないですね...。
抽出条件によって`?`の数変えなきゃいけないってのがよろしくない。
[ ]interface{}で定義しているのもなんとなく違和感...。

# sqlx.In
便利なのがありました。
sqlxに用意されているIn( )関数を使うともっとスマートに出来ます。
>func In(query string, args ...interface{}) (string, []interface{}, error)
[https://godoc.org/github.com/jmoiron/sqlx#In](https://godoc.org/github.com/jmoiron/sqlx#In)

```go
	queryBase := "SELECT Name,Skill FROM USER WHERE Skill IN (?)"
	searchSkills := []string{"go", "python"}

	query, param, err := sqlx.In(queryBase, searchSkills)
	if err != nil {
		log.Fatal(err)
	}
	var records []User
	err = db.Select(&records, query, param...)
	if err != nil {
		log.Fatal(err)
	}

	// Name:Jiro,Skill:go
	// Name:Saburo,Skill:go
	// Name:Goro,Skill:python
```
In( )関数に土台となるSQL文とパラメータに使いたいスライスを渡すことで,スライスの要素数に合わせて、プレースホルダの数を調節したクエリを作ってくれます。
あとは、`[]interface{}`になった`param`と一緒に`db.Select()`に渡せば、In条件を使った検索ができます。
これなら、抽出条件の数もパラメータの型も気にする必要がなくなりそうです。
素晴らしい。

ちなみに、In( )関数に要素数が0のスライスを渡すと、下記のエラーが発生するので注意が必要です。

```
empty slice passed to 'in' query
```


#参考

[golang: sql: converting argument $1 type: unsupported type []int32, a slice of int32](http://forum.k0d.biz/index.php?/topic/142-golang-sql-converting-argument-1-type-unsupported-type-int32-a-slice-of-int32/)
Android エミュレーターがネットワークに繋がらないときに一瞬で繋げる方法

# やりたいこと

自分の環境では、Android エミュレーターを使っているとネットワークに繋がらなくなることが多々あります。ほとんどの場合、DNS の設定に問題があるらしく、[こちら](https://qiita.com/maaaaaiiiisan/items/fdcf1c370fc381bb9dd2)の記事を参考にすれば問題は解決します。

**しかし...**

エミュレーターを起動するたびにこの記事どおりにコマンドを打つのが面倒くさい...。

ということで、これらの処理を 1 発で済ませるためのシェルを作ってみました。

# ソースコード

普段シェルを使うことがなく、何かおかしな点があればご指摘ください。

```run-avd.sh
#!/bin/bash

me=$(whoami) # ユーザー名を取得
path=/Users/${me}/Library/Android/sdk # ここは環境に合わせて変更してください

command=${path}/emulator/emulator
avds=$(${command} -list-avds) # インストールされているデバイスを取得

# インストールされているデバイスから起動するデバイスを選択
select AVD in ${avds}
do
  if [ -z $AVD ] ; then
    continue
  else
    break
  fi
done

# DNS サーバーを指定して起動
$(${command} -avd ${AVD} -dns-server 8.8.8.8)
```

こちらを適当なファイル名でコピペ保存して下記のコマンドを叩けば使えるようになるかと思います。

```
$ sh run-avd.sh
```

Android SDK へのパスは自分の環境に合わせて設定していますので、必ずパスを確認して必要であれば変更してください。
エラー：Error response from daemon: No such container:


# 前提

`docker-compose down`でコンテナを止めようとしたところ、謎のコンテナが謎のネットワークと接続させれていて止めることができす時間を使ったので備忘録程度に書いておきます。

## 環境
・docker-compose version 1.25.5

# 解決方法

順番としては下記のような流れになります。
1. `docker-compose down`をしてみる
2. ネットワークを調べてコンテナに接続されてないかを確認する
3. コンテナをネットワークを切断する


### 1. `docker-compose down`をしてみる

自分の場合`docker-compose down`してみると、`rails_api_default`というネットワークがアクティブと出てきました。

```
$ docker-compose down
Removing network rails_api_default
ERROR: error while removing network: network rails_api_default id ... has active endpoints
```

### 2. ネットワークを調べてコンテナに接続されてないかを確認する

`rails_api_default`を調べてみると、`966766894bfb_rails_api_app_1`というコンテナに接続されている事がわかりました。

ただ、ここで`docker-compose ps -a`をしてみても、このコンテナが表示されなかったので、一体何者なのかわかりませんでした。

もし、同様の経験をしていて原因をご存知の方がいましたら、教えていただけると幸いです。

```
$ docker network inspect rails_api_default
[
    {
        "Name": "rails_api_default",
        "Id": "e22a339dc85a3d7ce7c60bcab218bd939ff9f5578addb6b1d937b5e9ba1f2e7e",
        ....
        "Containers": {
            "966766894bfb110d4a66963f5af423d9f8e2e33a8259e1cca0ced238e5980196": {
                "Name": "966766894bfb_rails_api_app_1",
                ....
            }
        },
    }
]
```

### 3. コンテナをネットワークを切断する

あとは謎のコンテナと謎のネットワークを切断するだけです。
いろんなサイトを調べると、`rm`で切断する方法が出てきたのですが、自分の場合はうまくいかず、
`docker network disconnect -f <networkName> <containerName>`でうまくいきました。

```
docker network disconnect -f rails_api_default 966766894bfb_rails_api_app_1
```
Linux版Firefoxで、動画コンテンツを再生できない問題の解決手法


# はじめに
Ubuntuインストール時に標準でインストールされているFirefoxにて、Twitterなどの動画コンテンツを再生できない問題に遭遇した。そこで、今回はその問題に対しての解決法を記載する。

# 環境
OS: Ubuntu 20.04.1 LTS x86_64 
DE: GNOME

# 結論
結論から言うと、標準に入ってるFirefoxを削除して、公式からインストールをすると解決できた。


# 手法
## Step1: FlatPakのセットアップ

```
sudo apt install flatpak
```
今回flatpakを初めて使ったが、これはLinuxの新しいパッケージフォーマットだそう。これを使って新しいFirefoxをダウンロードする。

## Step2: Firefoxのflatpakrefをダウンロード


https://flathub.org/apps/details/org.mozilla.firefox



上記のURLにアクセスして、INSTALLを押して
org.mozilla.firefox.flatpakrefというファイルをダウンロード。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298716/d2714667-919c-1996-74b2-3070e05d9957.png)


## Step3: 標準のFirefoxをアンインストール
```
sudo apt remove firefox
```

## Step4: Flatpakを使ってFirefoxをインストール

```
flatpak install ./org.mozilla.firefox.flatpakref

cd /var/lib/flatpak/exports/share/applications

sudo desktop-file-install org.mozilla.firefox.desktop
```

これでインストールが完了した。
もし、firefoxがGUI上から表示されない場合
一旦ログアウトをし再度ログインすると、表示が確認された。


# 参考文献
https://support.mozilla.org/ja/kb/install-firefox-linux
Prometheus vs. CloudWatch　監視ツールの比較

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/6bbef157-bcfe-bf57-2e47-9eaf4a19745b.png)

# 1. Prometheus（プロメテウス）とは
![5dce65b4646791625e9e0cb8_90Q_11ed3EL5FwRIdEZ6ayRiOLh4vuyiHDC7mQv1gW81WjKf3hA8fhzqKH7lkeHN9y2RXeUrxakDgh8AHeoiXVyyvBfCQrJsc-Pd0fdD2XxHuz3cUa3WIXDLcq5DjcROJuFn0rq4 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/5cd33664-e558-b780-fd48-f2ba1cb0604a.png)
Prometheusは、時系列データベースを中心に構築されたオープンソースのサービス監視システムで、クエリ、グラフ、組み込みのアラートのサポートに加えて、データを受信して保存できます。 ターゲットエンドポイントに接続してHTTP経由でメトリクスをリクエストするPrometheusは、メトリクスを一意の時系列の一部として識別する名前やタグでメトリックを定義できる多次元データモデルを提供します。 [Hosted Prometheus by MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Prometheus%20vs.%20CloudWatch)では、データを最大2年間保存できますが、オープンソースのPrometheusメトリクスのデフォルトの保持期間は15日です。 その後、Prometheusクエリ言語（PromQL）を使用して、メメトリクスを探索し、単純なグラフを描画できます。
 
 Prometheusの使用が適しているかを確認したい場合、またはご不明な点がございましたら、いつでも[デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Prometheus%20vs.%20CloudWatch)して直接[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Prometheus%20vs.%20CloudWatch)お問い合わせください。

#CloudWatchとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/3ce10ba3-86b6-383f-0d99-ef09d29891cc.png)

CloudWatchは、インフラストラクチャシステムまたはアプリケーションのパフォーマンスを監視および管理するためのAWSサービスです。 リソースは、AWS、オンプレミス、または両方の組み合わせにすることができます。 アプリケーションパフォーマンスデータとインフラストラクチャ監視情報は、ログまたはメトリックとして、同じダッシュボードに同時に表示できます。 CloudWatchは、メトリクスとログの収集からモニタリング、アラート、分析まですべてを行います。 また、アラーム機能とイベント機能の両方があり、特定の条件が実現した場合に通知します。 CloudWatchの料金体制ですが、メトリックごとに課金されます。この場合、大量のメトリックを処理するためのコストは、競合するモニタリングソリューションよりも大幅に高くなる可能性があります。

#MetricFire の Hosted Prometheusの利用が適しているケース
以下の要件を満たしたい場合、Hosted Prometheusの利用が適しています

- 時系列データベースの監視ソリューションが必要
- Prometheusメトリクスの長期保存がしたい
- メトリクスにはタグ/ラベルを使用したい
- 異なるデータソース間でアラートを実行したい同じサービスの一部として、GramanaからPrometheusとGraphiteの両方を使用してクエリを実行したい

#CloudWatchの利用が適しているケース？
次の場合はCloudWatchの利用が適しています

- すでに他のAWSサービスを使用しており、Lambdaなどのサービスを監視する必要がある
- さまざまな分野をカバーするプレミアムサービスの恩恵を受けることができる大企業である
- 多種多様な視覚化ツールは必要ない

#価格の比較

- Prometheusはオープンソースであり、無料です。
- Hosted Prometheus、Hosted Graphite、GrafanaなどのMetricFireによるビジネス対応のPrometheus as a Serviceは、月額99米ドルからです。
- CloudWatchは独自仕様であり、無料枠から始まり、データ量により課金されていくシステムです。
- 大量のメトリクスの場合、CloudWatchは競合他社よりも大幅に高価になります。

#重要なポイント

- Prometheusは、メトリックが組み込みのストレージ、グラフ化、およびアラートを備えたメトリック名とタグによって識別されるディメンションデータモデルを提供できます。
- Prometheusはオープンソースであり、無料です。
- AWS CloudWatchは、コストがかかりますが、AWSユーザーには優れたサービスです。

Hosted Prometheusをよりよく理解し、[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Prometheus%20vs.%20CloudWatch)が監視環境にどのように適合するかを確認してください。 Prometheusで何ができるかやMetricFireの性能について質問がある場合は、[デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Prometheus%20vs.%20CloudWatch)してください。
Android Studioショートカット


#個人的によく使うショートカットまとめ

| \ | Android Studio | Visual Studio |
|:-:|:-:|:-:|
|  定義に移動 | F4  | F12  |
| 前画面  | Ctrl+Alt　と　 ← | Ctrl と -  |
| 次画面  | Ctrl+Alt　と　 →  | Ctrl+Shift と -  |
|  コメントアウト | Ctrl と　/  |  Ctrl+K と　C |
|  コメントアウト外す | Ctrl と　/  | Ctrl+K と　U  |
|  ビルドデバック | Shift + F9  | - |
|  ビルド次に進める | F8  | F10 |
|  ビルドブレイクまで進める | F9  | F5 |
|  ビルドstepイン | F7  | F11 |
|  ブックマーク一覧表示 | Shift + F11  | Ctrl+K と W  |
| ブックマークon/off  | F11  | Ctrl+K と K  |
| ブックマーク前移動  | -  |  Ctrl+K と P |
| ブックマーク後移動  | -  |  Ctrl+K と N |
| 検索  | Shift２回  |  Ctrl+F |
| *.hと*.cpp切替  | -  |  Ctrl+K と O |


以上
AWS SAA合格までの軌跡

AWS SAA(アマゾンウェブサービス ソリューションアーキテクトアソシエイト)試験に**一発合格**しました〜🎉
決して平らな道ではありませんでした😅(運が良かった)

試験の内容などは、**秘密保持契約違反**になってしまうので書けないですが、
書ける範囲で赤裸々に書いていきます。

## そもそもAWS SAAとは
AWS における分散システムの可用性、コスト効率、高耐障害性およびスケーラビリティの設計に関する 1 年以上の実務経験を持つソリューションアーキテクト担当者を対象とした試験です。

## 前提としての知識量
業務的にAWSを触ることはありましたが、設計をするというより、AWSを使って開発をする方がメインだったので、どの場面でどのリソースを使用すべきか、みたいなところはあまり経験値として多くありませんでした。
AWSを利用した開発においては、**実務6ヶ月くらい**のイメージです。

## 📆 申込〜試験まで、残り15日までの間
#### AWS SAAの黒本を読む
大枠つかむのにはよかったです。
じっくり読むより、さらーっと何周か読んだ方が良いと思います。

徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書 徹底攻略シリーズ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116236/1200c447-07ab-ca59-acbc-fc16cccb4888.png)

## 📆 試験まで、残り15日〜5日までの間
#### とにかく模擬試験を受けて、復習

Udemyの講座：「【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116236/ec846908-2a6d-8c65-e351-b841748a712b.png)

最初に受けた模擬試験がなんと、**64%**！合格に必要な割合は72%以上。
「これは、やばい、、、想像以上に問題が難しいぞ。。。！」という印象でした。

そこから、模擬試験をとにかく受けまくりました。
すると、以下のポイントがなんとなくつかめました。
- 時間の配分 → 個人的には、割と余裕があるな🤔
- どういう形態の問題が出るのか


#### Udemyの講座を移動時間、昼休み、寝る前にひたすら見る

Udemyの講座：「これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116236/3fcc8daf-c89b-dab7-99dc-ac80669c5287.png)

理想は手を動かしながら見ることをお勧めしますが、移動時間見ておくだけでも十分意味があると思います。

#### 自分自身のスキル分析
とにかく絶望的に時間がなかったので、効率よく勉強をするために苦手分野と頻出する分野を整理して、
適切な勉強の時間配分をまとめました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116236/00938f7b-4240-c751-b383-8efd194a9a9a.png)

## 📆 試験前日!


#### 試験の場所や時間、持っていくものなどの確認
もっと早くやっとけよって話ですね😂

#### 分析した結果を元に苦手分野を復習
スプレッドシートでまとめた苦手分野をもとに最後、Udemyの講座で復習しました。
個人的には、DB、ストレージ、コンピューティング周りを一通り見なおしました。

## 📝 試験当日
直前に受けた模擬試験がなんと**53%**！(72%以上が合格範囲) 内心終わった、、、。と思いましたが、復習すると問題文をしっかりと読んでないせいで誤っている選択をしていることが多かったので、落ち着いて問題文をしっかり読もう！と思いました。



## ポイント
| タイトル | 意味があったか |
|:---:|:---:|
| 徹底攻略 AWS認定 ソリューションアーキテクト<br>アソシエイト教科書 徹底攻略シリーズ | ◯ |
| 【Udemy】AWS 認定ソリューションアーキテクト アソシエイト<br>模擬試験問題集（6回分390問） | ◎ |
| 【Udemy】これだけでOK！ AWS 認定ソリューションアーキテクト<br>アソシエイト試験突破講座（SAA-C02試験対応版） | ◎ |
| AWS SAAのアプリ | △<br>解答が違うことがある |
| AWS Black Belt | 見なかった |

## 🔖 結果
![IMG_6677.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116236/e5b6d673-c8bd-33f4-a1f8-8240c83e5857.jpeg)

761/1000でした。おそらく720以上で合格なので、結構ギリでした・・・。😅

ちなみに合格かどうかは試験終わったらすぐに結果が出ます。
具体的な得点は、数日後に発表されます。

## 最後に

正直、模擬試験を受けていたら、心が折れそうでした。
試験を受けるのに、金銭的なリスクもあるし、日程のキャンセルもすぐにできてしまうし、やめておこうと思ったらやめれるからこそ、諦めそうになりました。
結果としては受けてよかったですが、しっかりと準備しておいた方が身のためです。(当日めっちゃ緊張したので😂)

少しでもこの記事が不安を取り除くのに役立つと嬉しいです。

最後に、**マジで試験時間、最後まで諦めない方が良い**です。

読んでいただきありがとうございます😌
メモ：無限精度の整数判定

$x$ が実数のとき

```math
y = \left( \cos^2{\pi x} \right)^\infty \\
\begin{cases}
y = 0 \cdots \left( x は整数ではない実数 \right) \\
y = 1 \cdots \left( x は整数 \right)
\end{cases}
```

となる。
K8s namespaceを削除できず、待機中まま

時々namespaceを削除できず、待機中ままの問題が発生するでしょうか？
解決方法をご紹介致します。

```
$ kubectl delete namespaces argo-events
namespace "argo-events" deleted
...
(待機中状態ままとなっています)
```

まず、namespaceの現状をJsonに出力します。この例は、`argo-events`のnamespaceとなります。

```
kubectl get namespace argo-events -o json > ~/argo-events.json
```

argo-events.jsonファイルを開いて、`finalizers`の中に`kubernetes`を削除します。

```
    "spec": {
        "finalizers": [
            "kubernetes"
        ]
    },

↓（kubernetesを削除します）

    "spec": {
        "finalizers": [
        ]
    },
```

それから、namespaceに反映します。

```
kubectl replace --raw "/api/v1/namespaces/argo-events/finalize" -f ~/argo-events.json
```

これを実行したら、最初のnamespace削除コマンドが進まれて、削除できるようになります。
jupyter notebookでcsvファイルからsql操作する方法（sqlite3) mshmura

備忘録

全体の流れ

１　csvファイルをpandasで取り込みデータフレームにする。

２　そのデータフレームを一時的にsqlに書き込む。

３　sql処理する。

４　sql処理したものを再度、pandasでデータフレームに変換して中身を確認。

５　pandasに変換したものエクセルで保存する。

```
import sqlite3
import pandas as pd
from sqlalchemy import create_engine


file = "2019全開催.csv"

output = "output.xlsx"

# dbに保存する場合はcreate_engine('sqlite:///データベース名
engine = create_engine('sqlite://',echo=False)

# excelの場足は　pd.reade_excel(file, sheet_name='シート名')
df = pd.read_csv(file,encoding="shift_jis")


df.to_sql('testing', engine, if_exists='replace',index=False)

#騎手がルメールのデータのみ抽出
results = engine.execute("select * from testing where 騎手='ルメール' ")

final = pd.DataFrame(results, columns=df.columns)

final.to_excel(output, index=False)


```
リッチテキスト項目を入力していて文字がぼやける現象

きっと、Salesforceだけではないと思いますが、質問に挙がっていました。

![image.png](https://trailblazers.salesforce.com/servlet/rtaImage?eid=9064S000000DGpH&feoid=Body&refid=0EM4S000000UFM9)

結論的にはブラウザの問題だったようです。

Blurry font
https://support.google.com/chrome/thread/9548011?hl=en

ハードウェアアクセラレーションスイッチをオフにすることも私にとってはうまくいきました。興味深いことに、この問題は最近のChromeアップデートで発生しました。それ以前は、テキストは問題ありませんでした。

また、Chrome UI /テーマをデフォルトのものにリセットしてみてください。この問題は、新しいマテリアルデザインの更新UIが原因である可能性があります。したがって、デフォルトのUIに戻ってみてください。

Fix blurry fonts in Safari
https://developer.salesforce.com/blogs/developer-relations/2010/09/fix-blurry-fonts-in-safari.html


思ったよりブラウザは色々大変だ。
【解決】Windows10 + ATOK 2017 でJavaをインストールできない

Qiitaに書いて良い内容なのか？と思いつつも、びっくりしたので書く。

# 環境
  * Windows10 Home
  * Windows版64ビットJava(8 Update 271 )
  * ATOK 2017（30.0.8)

https://www.java.com/ja/download/

でダウンロードしたjre-8u271-windows-x64.exeを実行するも、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/59abd86a-8aa8-c453-7758-85b683cbf705.png)

「インストール」を押すと、ダイアログがスン・・と消えて終わる。

えっ？？と思い、いろいろ調べるとこんなサイトを発見。

**[JREがインストールできない。ATOKからMS-IMEに変更して回避できた。](https://note.com/951/n/n40d9817c7fdc)**

いやいやいや、そうはならんやろ！と思い、試す。

インストーラをダブルクリックして、上記ダイアログがでているときに「Windows + Space」で、IMを切り替える。（私はGoogle 入力にしてみた）
（※IMの状態は、ウィンドウごとに切り替わるようなのでエクスプローラー上でIMEを切り替えていても、上記ダイアログ中にATOKに戻ることがある。というか戻った。なので、ダイアログが表示されている状態でWindows + Spaceを押して切り替える）

すると、先程、スン・・と消えていたダイアログの処理が続行され、インストール中になった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/6cb84f18-11f0-eb04-4d40-8538ccd61745.png)

このあと、インストール完了が表示され、無事、WindowsメニューにもJavaが入ったのでインストール完了しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/42543d98-b73a-a59d-b098-1173d8696c7b.png)

# 思い出

まさか、今のこの令和の時代に、Javaのインストールが、ATOKで引っかかるとは。。

（大昔）Niftyのフォーラムで、Macユーザーに対し(漢字TalkやMac OS8～9あたりで)ATOKを使ってるというだけでボロカスに叩いてくるV氏を思い出して苦笑してしまった。