OmniAICreator/Qiita-1.07M huggingface dataset:
phpについて

#この記事について
phpの学んでいくにあたって、phpについてどのようなものなのかまとめたので参考にしていただけたらありがたいです。
#phpとは？
大まかに説明すると、動的にWebページを生成することのできるサーバーサイドのスクリプト言語です。**動的？サーバーサイド？スクリプト言語？**とわからない言葉が出てきたので各々説明していきます。

* 動的なWebページ

アクセスした状況、タイミングに応じて内容の表示が異なるWebページのことである。
例えばユーザーが書き込み、内容が増えていく掲示板やGoggleなどの検索結果などが挙げられる。

* サーバーサイド

プログラムを実行した際に処理される場所がサーバー側であることを言います。詳細は自身が記事で公開しているのでこちらをご覧ください。
[サーバーサイドの詳細](https://qiita.com/reo-827/items/cb372066253ed6a98609)

* スクリプト言語

可読性が高く、習得を容易にしたプログラミング言語の総称のことを言います。PHPやRuby、Pythonがこれにあたります。
#主な特徴
PHPの最大の特徴は、**HTMLと組み合わせて使うことができるということです。**HTMLは基本的に静的サイトを作成するのもなので、記事の更新などのタイミングに応じて表示の変わる動的サイトを作ることができません。そこでHTMLで生成されたコードの一部をPHPに変更することによって動的サイトを作ることができます。
#終わりに
以上が私がPHPの学習を通してPHPとは？を学んだ概要です。至らない部分があると思います。新しく学んだ際は随時追加していきますので見ていただけたら幸いです。
型・ポインタ・参照 覚書？

※この文章はベータ版です。

# C/C++

C/C++は、型ありき(type first)で設計されています。
型は前置です。

変数宣言時に必ず変数と型を紐付けし、変数の初期化時に型に合わせて、メモリを
確保します。

Cは、設計段階で、型をつけた変数を定義して、変数間で値をコピーして渡す「値渡し」
が先ずあり、「値渡し」だけでは常に値のコピーが発生し、パフォーマンスが
でないので、値がある場所(アドレス)を指し、値の直接操作の可能な「ポインタ」が
導入された、感じがします。

Cはポインタに独自の型(ポインタ型)を用意せず、型に対して\*を後置することで
ポインタ型を表現しています。
(ポインタ変数は、アドレスの入れ物なので、ポインタ変数間で「値渡し」できます。
ポインタ変数に「\*」を付けることで、ポインタ変数に格納したアドレスにある値を
直接操作できます。)
(ポインタはアドレスの入れ物なので、ポインタ自体は格納されているアドレスに
ある変数の型の情報を必要とはしていませんが、実装上、ポインタの指すアドレスに
ある変数の型がわからないと、その変数内にある値にアクセスできないため、変数自体
には自分の型の情報を持たせず、ポインタ変数の宣言時にポインタ変数にポインタの
指す変数の型を紐付けるか、変数自体に自分の型の情報を持たせておき、ポインタで
アクセスするとポインタの指す変数から取得できるようにするか、する必要があります。
静的型付言語であるCでは前者を採用しています。)

ポインタの説明で、ポインタ型のロジックでの説明はあまり見かけず、
(値)型とポインタ型の区別がつきにくく、ポインタの理解がしにくく
なってしまってきた気がします。

[ポインタ型変数とは](https://qiita.com/kazuooooo/items/3fd14ca5b8827c60a4fe)  
(ポインタ変数・通常変数モードというロジックでの説明は。。。)  
[ポインタ](https://ja.m.wikipedia.org/wiki/ポインタ)

(ポインタ変数は、宣言が「型\* 変数名;」だけでなく「型 \*変数名;」とも
書けることで、変数名に\*をつけて宣言する変数で、変数名でアドレスを
格納できる、風の誤解を誘発してしまっている気がします。)

C++では、ポインタに加えて、制約はあるものの値を参照して直接操作できる「参照」が
新たに導入されました。

参照も、独自の型(参照型)を用意せず、型に対して＆を後置することで参照型を
表現しています。

参照の説明でも、参照型のロジックで説明したほうが、理解しやすいのではないか
と思います。

C/C++には関数ポインタがあるので、変数経由で関数・メソッドを操作することが
できます。

(関数ポインタ(変数)の宣言は、変数風の「(返値の型 (引数の型))\* 変数名;」の
ようには書けず、関数風に「返値の型 (\*変数名)(引数);」と書きます。)

c++はポインタと参照の2つがあるので、ややこしいです。

# Swift

Objective-Cの影響を強く受け、設計されています。  
型は後置です。

変更宣言時の変数への型付けはしてもしなくてもよく、していない場合、変数の
初期化時に代入した値の型により、メモリが確保されると共に、変数の型が
決まります。(但し、初期化時に代入値がnilの変数は宣言時の型付が
必須です。)

ポインタはあります。が、C言語との互換性などでどうしても必要な場合だけに
利用すべきモノです。

C/C++のようなポインタありきの言語、ではありません。

ポインタを表すポインタ型が数種あります。
(ポインタはARC対象外なので、メモリ管理する必要があります。)

構造体と列挙型は値型で値渡し、
クラスは参照型で参照渡しです。

(関数・メソッドの引数はデフォルトでは定数なので、引数として代入した変数を
変更するには、型の前にinoutキーワードをつけなくてはなりません。
(値型の変数であっても、inoutが付いた引数に代入すると、関数内で元の変数を変更
できます?)
クラス・構造体の値型のプロパティをインスタンスメソッドから変更するには、
メソッド定義の際にfuncキーワードの前にmutatingキーワードをつけなくては
なりません。)

関数型があるので、関数・メソッドは変数経由で呼び出すことができます。
(Swiftの参照渡しには、C++の参照にあるような制約はありません。)

# Java

C/C++の影響を強く受け、型ありき(type first)で設計されています。
型は前置です。

変数宣言時に必ず変数と型を紐付けし、変数の初期化時に型に合わせて、
メモリが確保されます。

ポインタはありません。

プリミティブな型(int、float etc)は値渡し、
それ以外の型は参照渡しです。

関数型がない(メソッド(関数)はオブジェクトではない)ので、メソッド(関数)を
変数経由で呼び出すことはできません。

(Javaの参照渡しには、C++の参照にあるような制約はありません。)


# JavaScript

動的型付けを採用しています。

変数は型を付けずに定義し、いかなる型も代入できます。  
(型がないわけではなく、代入する値の型で変数の型が決まります。)

プリミティブな型(int、float etc)は値渡し、
それ以外の(オブジェクト)型は参照渡しです。

関数(クロージャ含む)・メソッドはオブジェクトなので((関数型Functionが
あるので)、関数・メソッドも変数経由で呼び出すことができます。

# Ruby

Rubyは動的型付けを採用しています。

変数は型を付けずに定義し、いかなる型も代入できます。  
(型がないわけではなく、代入する値の型で変数の型が決まります。)

全ての型は参照の値渡しです。  
変更不能(immutable)な型の場合は値渡し(ライクな挙動)です。

変更不可（immutable）な型
* 数値型
* シンボル型

関数・メソッドはオブジェクトではない(関数型もない)ので、関数・メソッドを
変数経由で呼び出すことはできません。

クロージャ(proc、lambda)はオブジェクトなので(Proc型であるので)、変数
経由で呼び出すことができます。(クロージャは関数の一種です。)


# Python

Pythonは動的型付けを採用しています。

変数は型を付けずに定義し、いかなる型も代入できます。
(型がないわけではなく、代入する値の型で変数の型が決まります。)

全ての型は参照渡しです。

(関数・メソッドの引数は、変更可能(mutable)な型の場合、参照渡し、
変更不能(immutable)な型の場合は値渡し(ライクな挙動)です。)

変更不可（immutable）な型
* int, float, complexといった数値型
* 文字列型（string）
* タプル型（tuple）
* bytes
* Frozen Set型
変更可能（mutable）な型
* リスト型（list）
* バイト配列（bytearray）
* 集合型（set）
* 辞書型（dictionary）

関数・メソッドはオブジェクトなので(関数型Functionがあるので)、関数・メソッド
を変数経由で呼び出すことができます。

# 最後に
　今後、他の言語を追加するかもしれません。
【Ruby】インスタンスの生成について

<h3>問題：クラスFruitsを以下の仕様で定義してください。</h3>

**クラス変数**
・sum

**インスタンス変数**
・name
・price

**クラスメソッド**
・get_sum
↪️"合計の価格は「クラス変数sum」円です"と表示

**インスタンスメソッド**
・initialize
↪️引数で名前、価格を渡し、インスタンス変数nameとpriceに代入する
　sumにpriceを足し合わせる


定義したら、クラスFruitsから以下の３つのインスタンスを生成しましょう

**インスタンス**

|インスタンス名|名前|価格|
|:---------:|:---:|:---:|
|apple|リンゴ|120|
|orange|オレンジ|200|
|strawberry|イチゴ|60|


**雛形**
作ってもらうプログラムのひな形は以下です。

```
class Fruits
    # ここにクラスの定義を書き加えてください
  end

  # 以下で3つのインスタンスを生成してください

  # 生成したらクラスメソッドget_sumを呼んで合計価格を表示しましょう
```


①まずクラスFruitsの定義し、クラス変数**sum**とクラスメソッド**get_sum**を定義。

②次にインスタンス変数nameとpriceをinitializeメソッドの中で定義。
initializeメソッドはnewメソッドの引数を受け取ることが可能。
名前と価格をnewメソッドから受け取ってインスタンス変数に代入する。
そしてinitializeメソッドで受け取った価格の引数priceをクラス変数「**@@sum**」に足し合わせる。

③newメソッドでインスタンス生成時に引数として名前と価格を渡す。

④**get_sum**を呼び出して完了。

<h3>解答</h3>

```
 class Fruits
    @@sum = 0

    def self.get_sum
      puts "合計の価格は#{@@sum}円です"
    end

    def initialize(name, price)
      @name = name
      @price = price
      @@sum = @@sum + price
    end
  end

  apple = Fruits.new("リンゴ", 120)
  orange = Fruits.new("オレンジ", 200)
  strawberry = Fruits.new("イチゴ", 60)

  Fruits.get_sum

```
react基礎について

reactはUI構築のためのライブラリである。
そもそもライブラリ・フレームワーク・UIとは何か？

##ライブラリ
一言で言うと「様々なプログラムを保存しているところ」
プログラムを組んでいく中で何度も目にするコードがある。
それらを一部修正をして汎用性の高いコードや関数をまとめておく。
けど、便利なコードや関数をまとめてるだけで、ライブラリだけ動かすことは出来ない

メリット
・プログラムの動作が軽くなる
・プログラムの開発スピードが上がる
・開発者の勉強になる

##フレームワーク
端的にアプリやシステム開発のために必要な機能を用意した枠組み
経験が浅くてもプログラムを作成することが出来る。

メリット
・開発コストを抑える。
・バグを減らす
・コードがシンプルになる

フレームワークは、必要なものをまとめた枠組のこと
ライブラリは、便利なソースや関数の部品の集まり

>https://xtech.nikkei.com/it/article/lecture/20070205/260697/

##ユーザーインターフェース
窓口みたいなもの
何か２つのものの間で情報などのやりとりを行うときの方法や方式

https://techacademy.jp/magazine/8364
アジャイル開発（スクラム）について学んだことまとめ

#はじめに
アジャイル開発の現場にアサインすることになったので、事前に勉強したアジャイル関係の知識を整理しました。
雰囲気を掴む事が目的なので大雑把に書いていきます。

#用語
__プロダクトバックログ__・・・プロダクトに追加する要求のリスト
__スプリントバックログ__・・・バックログ項目の1つを要求、実装、テストに切り出す。
__テスト駆動開発__・・・開発手法の1つ。テストコードを作成　→　テストでエラーになる事を確認　→　実装　→　エラーを排除　→　ビルド　→リファクタリング　→　テスト成功
__デイリースクラム__・・・毎日決まった時間に15分で行うミーティング。1人ずつ「昨日やった事」「今日やる事」「障害になっている事」の順に話す。スクラムマスターはメンバーの障害になっている事を取り除くのが役目。すべての状況はPOに報告する。
__スコープ__・・・プロジェクトで行う作業の範囲と成果に何を含めるかを定めたもの。
__フィーチャ__・・・ソフトウェアの機能、特徴、性能目標、見た目や使い勝手などを総称する言葉として使っている。ユーザにとっての価値を表すので非機能要件も含まれる。
__職能横断型チーム__・・・顧客の要望に最初から最後まで応えられるチームのこと。
__インセプションデッキ__・・・手ごわい質問と課題を10つ揃えたもの。プロジェクト開始前に解決しておく。
__バーンダウンチャート__・・・チームがどのくらいの速度でストーリーを実装しているかを一目でわかるようにした図。


#心得等
・ドキュメントより動くソフトウェアを届ける。
・計画が変化するのは日常茶飯事。柔軟に対応する事が求められる。
・やる事が多すぎる場合やることを減らす。
・テストをたくさん書く。
・プロジェクトの進行中にもアーキテクチャの設計と改善を継続的に行う。
・コードベースをいつでもリリースできるようにしておく。
・やらないことリストを作る。
・プロジェクト開始時にすべての要求を集めることはできない。
・やるべきことはいつだって、与えられた資金や時間より多い。
・自分が作成しているプロダクトを自分で使ってみる（触る）。
・アジャイルのやり方は一つじゃないので、自身で工夫してやり方を模索する。
・役割がはっきりと別れていない。
・分析、設計、実装、テストの工程が独立して行われることはない。途切れることなく連続して行われる。
・チームが一丸となって成果責任を果たす。バグが見つかった際、「自分の担当じゃないから」という文言は通用しない。
・プロジェクトが始まる前にメンバーで集まってコミュニケーションを取ることは大切。
・POが積極的にプロジェクトに参加することでプロダクトの質は上がる。参加してもらえないのであれば、信頼を得るため期待に応え続ける。
・自分で考え、自分で判断し、自分で正しいと思ったことをする事ができる権限を開発メンバーに与えるべき。
・当事者意識や前向きな姿勢が求められる。
・当事者意識や前向きな姿勢が感じられない場合、POに対してデモをさせる事で「自分たちの成果に確信を持つために必要な権限」を要求してくるようになる。そこから当事者意識や前向きな姿勢に繋がる。
・職能横断型チームを構成する人材は基本的にゼネラリストが望ましい。
・アジャイルで正確な見積もりを行うのは不可能。相対的に見積もる。



#参考文献
[アジャイルザムライ--達人開発者への道](https://www.amazon.co.jp/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%B5%E3%83%A0%E3%83%A9%E3%82%A4%E2%80%95%E2%80%95%E9%81%94%E4%BA%BA%E9%96%8B%E7%99%BA%E8%80%85%E3%81%B8%E3%81%AE%E9%81%93-%EF%BC%AA%EF%BD%8F%EF%BD%8E%EF%BD%81%EF%BD%94%EF%BD%88%EF%BD%81%EF%BD%8E%EF%BC%B2%EF%BD%81%EF%BD%93%EF%BD%8D%EF%BD%95%EF%BD%93%EF%BD%93%EF%BD%8F%EF%BD%8E-ebook/dp/B00J1XKB6K/ref=sr_1_1?adgrpid=60123465984&dchild=1&gclid=CjwKCAiAq8f-BRBtEiwAGr3DgWUoH29SnJje0epItIHAnuKt-KDxOxRGCnhK1jq89BaFKIGzqqkAjBoCRgQQAvD_BwE&hvadid=338571457652&hvdev=c&hvlocphy=1009307&hvnetw=g&hvqmt=e&hvrand=15007343650940063018&hvtargid=kwd-334256426361&hydadcr=27298_11561624&jp-ad-ap=0&keywords=%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%B5%E3%83%A0%E3%83%A9%E3%82%A4&qid=1607663186&sr=8-1&tag=googhydr-22)
【初心者】PHPで文字列の頭文字を取得する

# 文字列の頭文字を取得する
文字列の頭文字を取得したい時は…

```php
echo mb_substr("文字列", 取得開始位置, 取得したい文字数);
```
取得開始位置を指定する時、頭文字から取得したい時は0を指定する。（※配列の1番目が0から始まる事と似ている）
取得したい文字数は、そのまま何文字取得したいのかを指定する。

使いどころがわかってはいないが、自分のために覚えておこう。
Enterキーが押されたらSubmit

##Enterキーが押されたらSubmitしたい


AngularでEnterキーが押されたらSubmitする関数を作ります。

なんかのような内容を見つけました。

```
<script>
  function enter(){
    if( window.event.keyCode == 13 ){
      document.form1.submit();
    }
  }
</script>
```


そしてinputタグからこの関数を呼べば、Enterを押した瞬間Submitになる!!
……とのこと。

```
<form name="form1">
  <input type="text" onkeypress="enter();">
</form>
```

最近は`onkeypress`ではなく`onkeydown`が主流みたい。

[GlobalEventHandlers.onkeydown]
(https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onkeydown)


【参考】
[[JavaScript] Enterキーで直接Submitする方法と無効化する方法]
(https://vertys.net/javascript-enter/)


Angularだと以下のものが該当するみたいです。

[イベントバインディング]
(https://angular.jp/guide/event-binding)
[@Input() と @Output() プロパティ]
(https://angular.jp/guide/inputs-outputs)
[ユーザー入力]
(https://angular.jp/guide/user-input)

つまり`<input>`内に`(keyup.enter)="update(box.value)`と書き込めばいいのか……?


うん、つまりそういうことらしい。
ウィキペディア記事で{{Wikidatabox}}と{{Cite Q}}を使ってみた

けっこうドキドキしながら『[通俗水滸伝豪傑百八人之一個](https://ja.wikipedia.org/wiki/%E9%80%9A%E4%BF%97%E6%B0%B4%E6%BB%B8%E4%BC%9D%E8%B1%AA%E5%82%91%E7%99%BE%E5%85%AB%E4%BA%BA%E4%B9%8B%E4%B8%80%E5%80%8B)』という記事をウィキペディアに書きました。
![](https://i.imgur.com/UeJL2Td.png)
この記事ではウィキデータを参照するテンプレートを2つ使っています。他の言語版では既に使われているのですが、ウィキペディア日本語版での使用状況やウィキペディアンのみなさんがどう考えておられるのかよく分かっていないため、ご意見などありましたらウィキペディア上でツッコミ頂けますと幸いです。

## [{{Wikidatabox}}](https://ja.wikipedia.org/wiki/Template:Wikidatabox)
[ウィキペディアの記事](https://ja.wikipedia.org/wiki/%E9%80%9A%E4%BF%97%E6%B0%B4%E6%BB%B8%E4%BC%9D%E8%B1%AA%E5%82%91%E7%99%BE%E5%85%AB%E4%BA%BA%E4%B9%8B%E4%B8%80%E5%80%8B)と[ウィキデータの項目](https://www.wikidata.org/wiki/Q70738658)がリンクされていれば、
```{{Wikidatabox}}```
と記述するだけで分類（この記事であれば「版画のシリーズ」）に応じてウィキデータの内容を元に適当な情報ボックスを自動的に表示するものです。
このテンプレートを使用する主な目的は、事実に関わる値はウィキデータ側に登録してウィキペディア側ではそれを参照する形にすることで事実情報を一元管理しやすくすることです。
他方、各国語で共通に使うものであり記事ごとに表現を変えられないため、日本語での表現が微妙に翻訳っぽかったり必要と考える情報が食い違っていたりして人により気になる点があるかもしれません。
いずれにしても始めてみないことにはわからないことも多いと思い、まずは分野ごとの情報ボックスのテンプレートがあまり使われていない、浮世絵の分野で使ってみました。
![](https://i.imgur.com/LRd5g77.png)
値を修正したり、詳細を確認したい場合は鉛筆アイコンを選ぶとウィキデータの画面に遷移します。見出しに相当する部分（プロパティ）の表記（例：ジャンル）をウィキデータ側で変えることもできますが、様々な文脈で使われることを考慮しあえて広い意味に取れる汎用的な見出しにしていることが多いため、その修正にあたっては注意してください。値の方は間違っていれば修正なり、悩ましいものは追加で両論併記したりすることは普通に行われます。
なお、このテンプレートは元々[{{Databox}}](https://www.wikidata.org/wiki/Template:Databox)という名前で開発されているのですが、日本語版ウィキペディアでは既に同名で別内容のテンプレートがあったため、[{{Wikidatabox}}](https://ja.wikipedia.org/wiki/Template:Wikidatabox)という名前で移植されています。この点に気をつければ、例えば本記事の英語版を作成する際にはテンプレート部分は自動的に各国語に切り替わるため、訳者は本文だけを翻訳すればよいはずです。次の{{Cite Q}}も同じです。

## [{{Cite Q}}](https://en.wikipedia.org/wiki/Template:Cite_Q)
ウィキデータに登録された書籍のデータを元に出典表記を行うものです。
![](https://i.imgur.com/8NQzSzY.png)
こちらも情報ボックスと同様に、出典に関わる事実情報をウィキデータから参照する形です。
```<ref name="a27">{{Cite Q|Q69389278|page=27}}</ref>```
のようにrefタグと併せてウィキデータに登録されている書籍の項目番号（ここでは[Q69389278](https://www.wikidata.org/wiki/Q69389278)）と必要な情報（ここではページ番号）を指定して出典用の表記を行います。
ウィキデータ側でいちど書名、著者名、出版社、出版日付などを登録しておけば、どの記事からでも上記のような記述をするだけで出典表記ができることになります。

画像は全てウィキペディア日本語版より(CC BY-SA 3.0)
## 関連情報
- [{{Wikidatabox}}の説明](https://ja.wikipedia.org/wiki/Template:Wikidatabox)
- [WikidataCon 2019における{{Databox}}発表ビデオ（英語）](https://media.ccc.de/v/wikidatacon2019-12-infoboxes_panel)
- [{{Cite Q}}の説明（英語）](https://en.wikipedia.org/wiki/Template:Cite_Q)
- [通俗水滸伝豪傑百八人之一個（ウィキペディア記事）](https://ja.wikipedia.org/wiki/%E9%80%9A%E4%BF%97%E6%B0%B4%E6%BB%B8%E4%BC%9D%E8%B1%AA%E5%82%91%E7%99%BE%E5%85%AB%E4%BA%BA%E4%B9%8B%E4%B8%80%E5%80%8B)
- [通俗水滸伝豪傑百八人之一個（ウィキデータ項目）](https://www.wikidata.org/wiki/Q70738658)
- [The 108 Heroes of the Popular Suikoden（コモンズのカテゴリ）](https://commons.wikimedia.org/wiki/Category:The_108_Heroes_of_the_Popular_Suikoden)
- [カラー版 国芳（出典を参照している書籍のウィキデータ項目）](https://www.wikidata.org/wiki/Q69389278)
【kintone】チェックボックスで特定の値だけが選択されているとき～をベン図とIF関数とCONTAINS関数を使ってやってみる

2020年12月のアップデートで、新しい関数「CONTAINS関数」が計算式の関数として仲間入りしました！
ヒューヒュー！

というわけで、CONTAINS関数を試しに使ってみたいと思います！
※というかCONTAINS関数に無理させてしまった感

# CONTAINS関数とは

[kintoneヘルプサイト](https://jp.cybozu.help/k/ja/user/app_settings/form/autocalc/multichoice_contains.html#)をご確認ください。

`CONTAINS(チェックボックス, "A")`

という計算式で、
チェックボックスのAが選択されていれば`true`、選択されていなければ`false`となります。

* 複数選択やチェックボックスで、指定の値が選択されているか？
* テーブル内の特定のフィールドに指定の値があるか？

がわかります。

「選択されているかどうか？」や「あるかどうか！？」が分かるだけです。

特定の値「だけ」が選ばれている時～というのは計算式をゴニョゴニョ書かないといけません（＞＜）


というわけで、CONTAINS関数で「とある選択肢だけ」が選択されている時～の計算式を考えてみたいと思います。

# アプリの準備

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/f237ef9c-4f57-6a49-326e-571cc6836a2f.png)

|フィールド種類 | フィールドコード | 
|:-:|:-:|:-:|
|チェックボックス   |チェックボックス  （R, G, B) |
|文字列(1行)   | 色  |

こんなフォームを準備しておきます。


## IF関数を使って、「赤」か「黄」か「空白」を表示する方法を考える


今回は練習のためにも（練習になるのかは、？）

**「R」だけが選ばれている時は「赤」と表示して
「R」と「G」だけが選ばれている時は「黄」と表示して
その他のときは空白**

という謎仕様としてみたいと思います。


そこでまずは、CONTAINS関数について考える前に、まIF関数でどう表したら良さそうか考えてみます。

IF関数の使い方はヘルプを参考にしましょう。
[[IF関数]条件によって表示する値を変える](https://jp.cybozu.help/k/ja/user/app_settings/form/autocalc/if_function.html)

IF関数だけで考えてみると・・・

```
IF(Rだけが選ばれている時, "赤", IF(RとGだけが選ばれている時, "黄", ""))
```

となる気がしますが、長くなりそうな予感がしますね（´-`）
Rだけが選ばれている時というのは
**Rが選ばれている　かつ　Gが選ばれていない　かつ　Bがえらばれていない**
ですもんね。

というわけで、今回はこういうのを考える時に便利な図、ベン図という図を使って考えてみたいと思います。

参考：[ベン図 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%99%E3%83%B3%E5%9B%B3)

## 「Rチェックがある」かつ「Bチェックがない」世界

下図をごらんください・・・。

今回はこのような謎仕様を満たしたいです。

**「R」だけが選ばれている時は「赤」と表示して
「R」と「G」だけが選ばれている時は「黄」と表示して
その他のときは空白**

図を見た感じ、

**Rチェックがある　かつ　Bチェックがない**という世界をまず作ってからIF関数に落とし込むと楽そうです。

図をごらんください。
黒く囲まれた部分が**Rチェックがある　かつ　Bチェックがない**世界です。
**赤か黄色か**という話は「**Rチェックがある　かつ　Bチェックがない**世界」での話で、
この黒く囲まれた世界以外は**空白**になります。

![20201215_013352645_iOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/03cd1d79-5a50-0a31-60b3-0cdb4b88b05d.png)

図から、IF関数は
`IF(Rあり かつ Bなし, IF(Gあり, 黄, 赤), 空白)`
という感じにすると良さそうです。

## IF関数とCONTAINS関数で書いていく

CONTAINS関数ではAがチェックされている時
`CONTAINS(チェックボックス, "A")`
のように書くと`true`が返ってくると最初の方に書きました。

これを先程のIF関数に埋め込んでみたいと思います。

AND関数、NOT関数を使うのでヘルプで確認しておきましょう。
[AND、OR、NOT関数の使いかた](https://jp.cybozu.help/k/ja/user/app_settings/form/autocalc/and_or.html)


`IF(Rあり かつ Bなし, IF(Gあり, 黄, 赤), 空白)`
↓

```
IF(
    AND(CONTAINS(チェックボックス,"R"), NOT(CONTAINS(チェックボックス,"B"))),
    IF(CONTAINS(チェックボックス,"G"),"黄", "赤"),
    ""
)
```

これでIF関数ができました。（長い）

※こんな感じで対応しています
`AND(CONTAINS(チェックボックス,"R"), NOT(CONTAINS(チェックボックス,"B")))`・・・Rあり かつ Bなし
`IF(CONTAINS(チェックボックス,"G"),"黄", "赤")`・・・IF(Gあり, 黄, 赤)

# 動作確認
![223_02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/b62651c3-3bb8-aec7-e11c-55bc832633ef.gif)

良さそう！ですね！？
完成です。

# まとめ

今回は「XXがある」しか分からないCONTAINS関数を、IF文やAND,NOT関数も使って
「XXだけがある」などチェック項目が特定できるような計算式を組み立ててみました。
しかし、これは計算式のわかりやすさが失われてしまう原因になってしまっているかも知れません（＞＜）

IF文やAND,OR,NOT文、さらにネストネスト～となるとさらに可読性が低くなってしまうので考えものです（´-`）.｡oO
JavaScriptでえいやっとやってしまったほうが早いかもしれないですね。

ではこのへんで(・ω・)ﾉｼﾉｼ
ベトナムとのオフショア開発、スクラム開発をふりかえってみる

この記事は、[iRidge Advent Calendar 2020](https://qiita.com/advent-calendar/2020/iridge) 15日目の記事です。

## はじめに

弊社ではオフショア開発としてベトナムに拠点を構える会社と共同でのシステム開発を行なっています。
私がベトナムメンバーとの開発に携わるようになってからそれなりの期間が経ったので、この機会にふりかえってみたいと思います。

## 現在の開発の進め方

タイトルの通り、スクラム開発をベースとしています。1スプリントを1週間として、朝会、スプリント計画ミーティング、レトロスペクティブなど、基本的なアクティビティを行いながら、開発を進めています。
メンバー構成は以下の通りです。

* 日本側
    * スクラムマスター兼エンジニア（私）
    * エンジニア
    * ブリッジSE（主担当）
* ベトナム側
    * エンジニア 2名
    * ブリッジSE（副担当）

これまで、ベトナムメンバーにはコーディング、テストを中心に開発タスクを担当してもらっており、要件定義、設計などのタスクは、日本メンバーで進めていました。ただ、日本メンバーのエンジニアは最近チームにジョインしたばかりなので、設計タスクはおおむね私が担当する体制となっていました。

## よかったこと

新機能開発よりも既存システムの改修を行うことが多いのですが、ベトナムメンバーの入れ替わりはそれほど多くなく、同じメンバーが同じシステムに長く携わってくれていることで、以前に比べてコミュニケーションコストが下がったように感じています。
以前であればスプリント計画ミーティングで詳細に作業内容を伝えていたところ、共有できている前提が増えてきていることから日本側からの説明量は減ってきている感覚があります。
ベトナムメンバーのシステム理解が進んできて頼もしく感じるとともに、一方で日本側メンバーのこれまでのタスクを通じた教育が身を結びつつあると実感しています。

## 改善したいこと

コーディングやテストについては高い生産性を発揮してくれるベトナムメンバーですが、一方で設計についてはまだ日本メンバーから多くの支援を必要とする状態で、ベトナムに依頼しなくとも日本メンバーでやってしまったほうが早い、となるケースが多いのが正直なところです。Web上の記事を見てみるとこれはオフショア開発としてどこでも抱える課題のようで、コーディング、テスト工程の要員としてオフショア開発を活用すべし！といった主張をされている記事も見受けられます。

私の実体験としても、オフショアのベトナムメンバーを最大限活用するならコーディング、テストをお願いすることがよいと考えています。
しかしながら、我々は日本とベトナムの合同スクラムチームとして活動しているので、コーディング、テストはベトナム、設計は日本といった分業体制で進めていくことは望ましくないと思っています。

そのため、現在はベトナムメンバーにも設計工程を担当してもらえるよう、いくつか取り組みをしている段階です。

#### システム調査タスクを割り当てる

設計の前段階として現行の仕様調査を行う経験を積んでもらうことを目的にしています。
調査結果を整理してもらい日本側でレビューしますがシーケンス図などUMLを用いてまとめるよう指示しています。（この指示がないと、適当なフォーマットでまとめられたりしてレビューが大変でした）
「調査の目的を詳細に伝える」ことに注意すれば、今の所それなりの品質の成果物が上がってきています。

#### 設計タスクを割り当て、ミーティングで方針をコントロールしながら進める

要件のみを事前に説明し、簡単な設計タスクを担当してもらいました。
簡単な設計と思い割り当てたのですが、いざ日本側でレビューする段階になると不自然な設計や考慮漏れが散見されたため、日本側である程度進め方をコントロールする必要があることに後から気づきました。
設計検討中に悩む部分があったとき気軽に相談をすることが出来ないことが一因のようだったので、朝会の他に時間を確保して設計相談の時間を確保することで何とか形になりましたが、今後も設計を依頼する際には日本側のフォローの仕方として頭に入れて置く必要性を感じました。
この進め方は日本側の工数もかなり取られてしまうので、余裕があるときでないと破綻してしまうので要注意です。

いずれの取り組みもベトナムとのオフショア開発特有の手段をとっているわけではないですが、これまでの経験から時間をかけて取り組むことでベトナムメンバーのスキルアップに繋がり、より開発に貢献してもらえると考えています。ブリッジSEを介したコミュニケーションが肝で、こちらの意図を正確にベトナムメンバーへ伝えてもらえるように丁寧に話すことを普段のコミュニケーションから意識することが大事だと思います。

## まとめ

ふりかえってみると、きちんと時間をかけてチャレンジすること、教えることでメンバーのレベルアップを図ることはベトナムであろうと日本であろうと変わりないと思います。スクラムチームとして成長をするために何をすべきか、という観点で今後も取り組んでいきます。（気が向いたら続編を書きます。）
Python3 | numpy入門

**開発環境：Jupyter Notebook**

まずは、読み込み。

```python
import numpy as np
```
「numpyというライブラリをnpとして読み込む」という意味となる。これを宣言することで、メソッドをnpとして参照することができる。

## 配列
![qiita_header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716184/90f95cc3-ed99-b543-4fe3-3dd1964a32e8.png)

### 1次元配列

```python
a = np.array([0, 1, 2])

print(a)
#array([0, 1, 2])

a[2]
#2
```
np.arrayで配列を作成する。１次元配列の場合、array([ ])で作成することができる。a[ ] で任意の値を呼び出すことができる。


### 2次元配列

```python
a = np.array([[0, 1, 2], [3, 4, 5]])

print(a)
#array([[0, 1, 2],
#       [3, 4, 5]])

a[0]
#array([0, 1, 2])
a[1]
#array([3, 4, 5])

a[0][0]
#0
a[1][2]
#5
```
2次元配列の場合、array([ ], [ ])で作成することができる。ここで、a[ ] とすると、行ごとの値を呼び出す。a[ ][ ]では、行と列を指定して、1つの値を取り出すことができる。



##配列の操作
![qiita_header (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716184/c9ed7ff3-a743-5eed-e293-7ba4b6faccbd.png)

###shape, ndim, dtype, size

```python
a.shape
#(2, 3)
a.ndim
#2
a.dtype
#'int64'
a.size
#6
```
**a.shape**で行と列の数を取り出すことができる。**a.ndim**は次元数を表している。今回の場合、2次元行列のため、2が取り出される。**a.dtype**はビット数を表している。今回は、2×3の行列なので、1つの値を2ビットとすると、2の6乗でint64と求められる。**a.size**は2×3の行列より、6と表示される。


###arange, linspace

```python
np.arange(6)
#array([0, 1, 2, 3, 4, 5])

np.arange(0, 20, 5)
#array([0, 5, 10, 15])

np.linspace(0, 20, 5)
#array([0., 5., 10., 15., 20.])
```
**np.arange**は等差で配列を作ることができる。上の例では、単に6と書くと、0から6つの要素を取り出すことができる。または、0から始まり、20未満まで、5ずつ増える配列として表されている。**np.linspace**は等分して配列を作ることができる。上の例では、0から始まり、20まで、5等分して配列を作成している。

###zeros, ones

```python
np.zeros((2, 3))
#array([[0., 0., 0.],
#       [0., 0., 0.]])

np.ones((2, 3))
#array([[1., 1., 1.],
#       [1., 1., 1.]])
```
**np.zeros**は0を要素とする配列を作成することができる。同様に、**np.ones**は1を要素とする。


###append, vstack, hstack

```python
a = np.arange(5)
b = np.arange(0, 10, 2)
c = np.arange(0, 100, 20)

a
#array([0, 1, 2, 3, 4])
b
#array([0, 2, 4, 6, 8])
c
#array([0, 20, 40, 60, 80])

np.append(a, b)
#array([0, 1, 2, 3, 4, 0, 2, 4, 6, 8])

np.vstack([a, b, c])
#array([[0,  1,  2,  3,  4],
#       [0,  2,  4,  6,  8],
#       [0, 20, 40, 60, 80]])

np.hstack([a, b, c])
#array([0,  1,  2,  3,  4,  0,  2,  4,  6,  8,  0, 20, 40, 60, 80])
```
**np.append**は配列の値を後に続けて加えることができる。**np.vstack**は配列を行ごとに、つまり、鉛直(vertical)に並べる事ができる。加えて、**np.hstack**は配列を水平(horizontal)に並べることができる。


###random, sum, min, max, mean

```python
a = np.random.rand((2, 3))

a
#array([[0.3026967 , 0.7533224 , 0.26057491],
#       [0.91502592, 0.54166851, 0.60867887]])

a.sum()
# 3.381967315194162

a.min()
# 0.26057491207931693

a.max()
# 0.9150259161906477

a.mean()
# 0.563661219199027
```
**np.random.rand**は0以上1未満の数をランダムに記述することができる。**a.sum**ですべての値の合計、**a.min**で配列の最小値、**a.max**で配列の最大値、**a.mean**で配列の平均値を表す。
AndroidライブラリでBill of Materials (BOM) を使ってみよう

## Bill of Materials (BOM) とは？

プロジェクトで利用するライブラリーのバージョンを指定して同期させるMavenの仕組み

#### つまり？
BOMを使うと、**最適な依存ライブラリのバージョンを自動指定してくれる！**

#### なにがお得？

- バージョンを個別に指定する記載が不要になり、build.gradleがスッキリする
- **ライブラリの特定バージョンの組み合わせによる不具合がなくなる**

※ ちなみに、Bill of Materials を直訳すると「**部品表**」という意味

MavenのBOMドキュメント
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms

## BOM List

Android開発で使えそうなBOMを集めてみた

### Android

**Firebase-BOM**
https://mvnrepository.com/artifact/com.google.firebase/firebase-bom

**Kotlin Libraries Bill of Materials**
https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-bom

**Kotlinx Coroutines BOM**
https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-bom

**Squareup.okhttp3**
https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp-bom

### オマケ

**Spring Framework BOM**
https://mvnrepository.com/artifact/org.springframework/spring-framework-bom

**AWS SDK For Java**
https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-pom

**JUnit 5**
https://mvnrepository.com/artifact/org.junit/junit-bom

# 依存関係を実際に確認してみよう

空のAndroidプロジェクトを作成
BOMライブラリをdependenciesに追加
dependencies tree を眺めて差分を確認してみる

```
./gradlew app:dependencies --configuration debugCompileClasspath | grep coroutine
```

今回は coroutin を使用する
https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-bom


```gradle:app/build.gradle
dependencies {

    // Before : 個々にバージョン管理する必要がある
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'

    // After : BOM化するとバージョン指定は１つだけ
    implementation platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.2")
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test'
```

使用コード
https://github.com/ikemura23/Android-BOM-Sample/blob/main/app/build.gradle#L44-L48

## BOMを有効活用しよう

BOMについてある程度理解はできた

さっそく、プロジェクトに導入いきましょう！

## ここから妄想

社内専用のBOMを作ってみてはどうだろう？

例えば新規Androidプロジェクトを作る時に
「okhttpとretrofitとcoroutineを追加して〜」
これが「このBOM１つで解決やで！」
と、ならないだろうか

### メリット

- ライブラリ選定が楽（同じライブラリしか使わない場合）
- プロジェクトの初期構築がスピードアップする

### デメリット

- 社内にBOM環境を作る必要がある（GitHubのみでOK？）
- BOMバージョンのメンテナンスが大変そう

うーん、ちょっと考えてみたけど、長く使うとなればメンテのコストが大きい。

毎週のように新規プロジェクトが作成される状況や、自社でライブラリを作成/配布している場合には有効かも！
UXチームをアジャイルなDevOpsカルチャーに統合する方法

この記事では、UXチームをアジャイルなDevOpsカルチャーに統合し、UXが開発のペースを維持できるようにする方法について説明します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-integrate-ux-into-your-devops-culture_595194)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

優れたユーザーエクスペリエンス（UX）には意味があります。ユーザーファーストのデジタル体験を設計・開発する上での確固たる基盤がなければ、組織は競争に勝てず、顧客は最終的に別の場所に移動することになります。

これに加えて、世界のITリーダーたちは、もう一つの文化的な変化に気付いています。私たちは、付加価値の高い製品を提供し、エンドユーザーに改善されたサービスを提供するために、DevOps戦略とアジャイル開発を採用している組織を見てきました。

しかし、アジャイルなDevOpsプラクティスのペースが速いため、UXチームが取り残される危険性があります。これは、このようなプロセスが一連のスプリントに依存しており、製品またはサービスに繰り返し変更が加えられるためです。

これは、UXチームにとっては、定期的かつ漸進的な変更を分析し、それに対応する必要があります。

では、UX チームをアジャイル DevOps カルチャーに統合し、UX が開発のペースを維持できるようにするにはどうすればよいのでしょうか？

#プロアクティブな監視
スプリントごとに、UXチームは変更内容を検証し、適切なフィードバックを得て、適切な修正を確実に実装する必要があります。

インフラストラクチャをクラウド上で実行することは、UXチームの俊敏性を維持するのに役立ちます。たとえば、Alibaba Cloudの[Kubernetesコンテナサービス](https://www.alibabacloud.com/product/kubernetes?spm=a2c65.11461447.0.0.1d3c5caacsKh82)を使用することで、UXチームは、各統合や配信について即座にフィードバックを得ることができ、問題を積極的に特定して分析することができます。

また、[アプリケーション・リアルタイム・モニタリング・サービス（ARMS）](https://www.alibabacloud.com/product/arms?spm=a2c65.11461447.0.0.1d3c5caacsKh82)を導入することもできます。

ARMSのフロントエンド監視機能は、ユーザーエクスペリエンスの観点から特に有用です。地理的な地域、ISP、URLなどのディメンションを使用して、ユーザーのウェブページの閲覧行動をリアルタイムで確認することができます。また、非同期API操作呼び出しのパフォーマンスと成功率を監視して診断することもできます。

また、フロントエンドで問題が発生したときにアラートを出すための一連のカスタムアラームを設定して、問題を事前に軽減することもできます。

#ユーザーデータの理解
スプリント中であっても、UXチームは継続的にリサーチを行い、市場でのブランドのポジションを維持するための基本的な戦略を立案しなければなりません。そのため、UXチームは、ユーザーデータにシームレスにアクセスして分析し、その情報から真の価値を抽出するために、ますます短縮されていく時間枠の中で、ユーザーデータから真の価値を引き出すことができなければなりません。

クラウドコンピューティングは、さまざまなツールやサービスを使って、このような反復的で柔軟な方法で作業できるようにチームをサポートします。例えば、ユーザーが作成した膨大な量のコンテンツを[オブジェクトストレージサービス](https://www.alibabacloud.com/product/oss?spm=a2c65.11461447.0.0.1d3c5caacsKh82)（OSS）を使ってクラウド上に保存し、UXチームはインターネットを介していつでもどこからでもその情報にアクセスすることができます。

また、当社のコンソールにはさまざまなデータ移行ツールが付属しているので、UXチームはユーザーデータを簡単にアップロード、ダウンロード、管理することができます。また、[Elastic MapReduce (EMR)](https://www.alibabacloud.com/products/emapreduce?spm=a2c65.11461447.0.0.1d3c5caacsKh82)プラットフォームなどの強力なビッグデータおよび分析ツールを統合することで、この情報を簡単に処理することができ、[DataV](https://www.alibabacloud.com/product/datav?spm=a2c65.11461447.0.0.1d3c5caacsKh82)で可視化することで強力な洞察を得ることができます。

#結論
Alibaba Cloudの製品およびサービスのユーザビリティとスケーラビリティにより、すべてのスプリントの中心にUXを置くことができます。その結果、アジャイルなDevOpsプロセス全体でユーザーの声を聞くことができ、組織はエンドユーザーへの真の価値の提供に集中することができます。

DevOpsでユーザー・エクスペリエンスを最適化する方法の詳細については、電子書籍[『How to use DevOps to Better Serve Customers』](https://resource.alibabacloud.com/whitepaper/how-to-use-devops-to-better-serve-customers_925?spm=a2c65.11461447.0.0.1d3c5caacsKh82)をダウンロードしてください。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*
node.jsを自分のMacにインストールした

備忘録として。
node.jsを自宅のMacにインストールしようと思う

Homebrewから今回はやってみた
HomebrewとはMacOSで広く使われるパッケージ管理システム。。らしい

Homebrewを下記URLからまずインストール
https://brew.sh/index_ja

ターミナルで
brew -v
とコマンドを入力したら下記のようにバージョンが表記されたらインストール完了

```
Homebrew 2.6.1
Homebrew/homebrew-core (git revision dfe59; last commit 2020-12-14)
```

そしたらいよいよnode.jsのインストールへ。

```
brew install nodebrew
```
インストールが完了したら下記コマンドで確認

```
nodebrew -v
```

nodebrew 1.0.1~~
上記のようなばーじょんから始まる長ったらしい文が表示されたらOK

続いて下記コマンドを入力

```
nodebrew ls-remote
```

したら、ズラーっとvX.XX.Xのような表記でバージョンが並べられる
どのバージョンでもいいが推奨のバージョンをインストールする方がいいと思われるので、
今回は推奨バージョンをインストールすることに。
調べたら下記コマンドで推奨バージョンをインストールできるらしい


```
nodebrew install-binary stable
```

僕の場合ここでエラーが出てしまった
調べたところフォルダを作ってあげなきゃいけないみたいで
こちらのコマンドで作成。。。

```
mkdir -p ~/.nodebrew/src
```
インストール完了したらバージョンを確認


```
nodebrew ls
```

下記のように表示されればOK
現在インストールされてるバージョンが羅列される
ちなみにcurrentの部分には現在使用中のバージョンが入る

```
v14.15.1

current: none
```

useの後に使用するバージョンを選択

```
nodebrew use v14.15.1
```

もう一度nodebrew lsを試したら

```
v14.15.1

current: v14.15.1
```

上記のようにcurrentに入る
次は環境パスの設定
環境パスとはフルパスを指定せずソフト名のみを指定するだけで
プログラムを起動できるようにシステムに予め設定しているパス。
'>>'の後には各SHELLごとに合わせたファイルを指定
自分はzshだったので~/.zprofileを指定

```
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile
```

そしたらnodeコマンドを実行

```
node -v
```
インストールしたバージョンが表示されたらOK
以上でnode.jsインストール完了
JSX etcの問題点

※この文章はベータ版です。

JSXの問題はロジックの中にHTMLなどのレイアウト用言語のコード片
(orそのコード片を生成するコード)が埋め込まれてしまうことに
あります。 

::: note info
JSXはトランスパイラにより、JS的に問題のない専用の関数で
HTMLなどのレイアウト用コードを組み立てるコードに変換
されます。
:::

昔からロジック中でHTMLを生成できるライブラリ・フレームワークが
多数、作成されてきました。

現在もRails etcのWEBアプリケーションフレームワーク(WAF)の
コントローラにおいて、用意された関数(orメソッド)群を用いてHTMLを
組み立てるコードを書くことが可能になっています。

しかし、メジャーWAFでは、ロジックの中にHTMLなどのレイアウト用言語の
コード片(orそれを組み立てるコード)を埋め込むことはメンテナンスetcの
観点から、特定のケースを除いて回避することが推奨されてきました。

ロジックの中にHTMLなどのレイアウト用言語のコード片(orそれを組み立て
るコード)を埋め込むことを、何の制限もなく、許可してしまうと、コード中
にレイアウト用言語のコード片が散逸し、コードの見通しが悪く、
レイアウトの変更が発生した場合etcに、ロジックを追いかけなければ
ならない事態になります。

ほとんどの言語やフレームワークで、ロジックの中にHTMLなどの
レイアウト用言語のコード片を埋め込むことは推奨されず、HTMLなどの
レイアウト用言語で記述するテンプレートにロジック・コードを埋め込む
スタイルが採用されてきました。

ロジックの中に埋め込むよりは、テンプレートとして切り出し、ロジックの
埋め込みを可能にするほうが問題が少ないと判断されてきたからだと思います。

ロジック中に埋め込む場合に比べ、テンプレートにロジックを埋め込む場合
は多少のオーバーヘッドがあることが多いですが、パフォーマンスに対する
要求がハイレベルな場合を除き、ロジック中に埋め込む場合におこり得る
問題の前では有意なオーバーヘッドではありません。

::: note info
PHPはレイアウト言語にロジック・コードを埋め込むスタイルの仕様
でありながら、ロジックの中にレイアウト用コード片を埋め込むこむ
こともできてしまいます、が、PHPのモダンなフレームワークでは、
view用テンプレートでレイアウト用言語にロジック・コードを
埋め込み、ロジック中にレイアウト用コード片を埋め込まないスタイルを
採用しています。
:::

::: note info
HamlやSlimなど、HTMLタグを対応した関数に置き換え、
テンプレート自体をレイアウト組み立てロジックとして記述し、
実行時にHTMLに変換するテンプレート・エンジンもありますが、
エンジニア視点のみで作成されているもので、汎用性も乏しい
ので、個人的には邪道だと思っています。
:::

HTML仕様においては、scriptタグにロジックのJSコードを集約し、script
タグ外では、タグのイベント用属性でJSコード片を埋め込める以外は
JSコードを埋め込むことはできません。

HTML仕様自体が、デザイン(レイアウト)とロジックを分離する形で
設計されています。

::: note info
HTMLは元々、デザイン(レイアウト)用の言語であり、
プログラマブルではありませんでした。デザイン(レイアウト)を
動的に変更・制御したいというニーズが発生し、それに応える形で
JavaScriptが誕生、scriptタグが実装され、イベント用の属性が
追加され、HTMLは後付けでプログラマブルになったのです。
:::

JSXの信奉者?による文章には、Vue.jsやAngularのコード例として、
入門記事では見かけるものの実際はVueやAngularにおいてバッドな
コード例とされているようなコードを引用して、JSXの優位性を主張
しているモノがありますが、

VueやAngularにおいてHTMLorHTMLテンプレート用にビルトインで
用意されているディレクティブは、それぞれのグッドなコード例のように
書けば、見通しのよいスマートなHTMLテンプレートを記述できます。

::: note info
VueやAngularに用意されているディレクティブはHTMLのタグに
属性を追加する形でHTMLを拡張して、デフォルトのHTMLにはない
機能を擬似的にHTMLに追加しています。
:::

HTMLテンプレートによるデザインとロジックの分離は、デザイナーと
エンジニアの協業だけでなく、コード全体の見通しも良く、してくれます。

HTMLなどのレイアウト用言語のコードはHTMLファイルorテンプレートに
集約し、ロジック内に埋め込まないスタイルが望ましいと個人的には
思います。

JSX etcでレイアウト用言語のコードをロジックに埋め込む際には、規約で
埋め込み可能な箇所を限定し、レイアウト用言語のコード片がロジック中に
散らばらないようにすべきです。
入力した整数がある整数と近いか判断するプログラム

本日はこの問題を解いていきます。

問題.1
正の整数を入力します。その整数が、
10の倍数（10,20,30...）からの差が2以内であるときはTrue
それ以外はFalse
と出力するメソッドを作りましょう。

出力例：
near_ten(12)→True
near_ten(17)→False
near_ten(19)→True


模範回答

```ruby
def near_ten(num)
  quotient = num % 10
  if quotient <= 2 || quotient >= 8
    puts "True"
  else
    puts "False"
  end
end
```

解説
10の倍数からの差」を考えるためには、一の位の値に着目します。すなわち、一の位が「0,1,2,8,9」のどれかであれば「10の倍数からの差が2以内」と判断することができます。

したがって、変数quotientに一の位の値を代入し、quotient <= 2 || quotient >= 8で「0,1,2,8,9」のどれかに当てはまるかどうかを確認しています。
WordPressでページネーションを実装する

ワードプレスのテーマtwentytwentyを基盤に、アーカイブページにページネーション機能を持たせる実装をしたので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

ページネーションの実装には、色々な方法があると思うが、今回は折角なのでWordPressの関数を使った方法を試したいと思います。
今回編集するのはfunctions.phpとページネーションを取り入れたいページのphpファイルです。

```functions.php
// ページネーション
function pagenation( $pages = '', $range = 2 ) { // $pagesは総ページ数、$rangeは前または後ろに出したい数字の数
    $showitems = ( $range * 2 ) + 1;
    global $paged; // $pagedは現在のページ番号
    if ( empty( $paged ) ) $paged = 1;
    if ( $pages == '' ) {
        global $wp_query;
        $pages = $wp_query->max_num_pages;
        if ( !$pages ) {
            $pages = 1;
        }
    }
    if ( 1 != $pages ) {
        // 画像を使う時用に、テーマのパスを取得
        $img_pass = get_template_directory_uri();
        echo "<div class=\"m-pagenation\">";
        // 「1/2」表示 現在のページ数 / 総ページ数
        echo "<div class=\"m-pagenation__result\">". $paged."/". $pages."</div>";
        // 「前へ」を表示
        if ( $paged > 1 ) echo "<div class=\"m-pagenation__prev\"><a href='".get_pagenum_link($paged - 1)."'>前へ</a></div>";
        // ページ番号を出力
        echo "<ol class=\"m-pagenation__body\">\n";
        for ( $i=1; $i <= $pages; $i++ ) {
            if ( 1 != $pages && ( ! ( $i >= $paged+$range+1 || $i <= $paged-$range-1 ) ) ) {
                echo ( $paged == $i ) ? "<li class=\"-current\">".$i."</li>": // 現在のページの数字はリンク無し
                    "<li><a href='".get_pagenum_link($i)."'>".$i."</a></li>";
            }
        }
        // [...] 表示
        if ( ( $paged + 4 ) < $pages) {
            echo "<li class=\"notNumbering\">...</li>";
            echo "<li><a href='".get_pagenum_link($pages)."'>".$pages."</a></li>";
        }
        echo "</ol>\n";
        // 「次へ」を表示
        if ( $paged < $pages ) echo "<div class=\"m-pagenation__next\"><a href='".get_pagenum_link( $paged + 1 )."'>次へ</a></div>";
        echo "</div>\n";
    }
}

// pre_get_posts を使ってメインクエリーを書き換える
function change_posts_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() || is_preview() )
        return;
    // カスタム投稿アーカイブ
    if ( $query->is_main_query() && $query->is_post_type_archive( 'blog' ) ) {
        $query->set( 'posts_per_page', 10 ); // 10件ずつ表示
        return;
    }
}
add_action( 'pre_get_posts', 'change_posts_query' );
```

今回はpagesを可変に、rangeを2に、posts_per_pageを10件に設定しています。
お使いの際は適宜使用に沿った変更を加えてください。

```php
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
?>
<li>
  <!-- 詳細ページへのリンク -->
  <a href="<?php the_permalink(); ?>">
  .
  . <!-- ループ内の処理を記述 -->
  .
  </a>
</li>
<?php
endwhile;
if( function_exists( 'pagenation' ) ) : // 関数が定義されていたらtrueになる
pagenation();
endif;
else : // 記事がない場合
?>
<li>
  まだ投稿がありません。
</li>
<?php
endif;
?>
```

表示側の記述です。liタグ内は適宜変更ください。
【python3】関数のキーワード引数を動的に指定して呼び出す

# 0. 結論
```python:f(arg1,arg2)に対しては次のようにするとよい
f(**{"arg1":hoge, "arg2":fuga})
```

# 1. やりたいこと

関数`f`があり、`f`の仮引数は`arg1`および`arg2`だとする。
どちらか一方のみを指定して呼ぶ場合、`f(arg1="hoge")`とか`f(arg2="fuga")`のように呼ぶことが出来る。

このとき`arg1`を指定するか、それとも`arg2`を指定して呼ぶかを動的に決定したい。

# 2. やり方
例えば「`arg1`を呼ぶか`arg2`を呼ぶかを確率的に決めたい場合」は次のようにできる。

```python:python
import numpy as np
確率的に決まる引数 = lambda: "arg1" if np.random.rand()> 0.5 else "arg2"

def f(arg1="(empty)", arg2="(empty)"):
    print("arg1 = "+str(arg1)+"\narg2 = "+str(arg2))

f(**{確率的に決まる引数():"fuga"})
# 半分の確率で
#
# arg1 = fuga
# arg2 = (empty)
#
# と表示され,もう半分の確率で
#
# arg1 = (empty)
# arg2 = fuga
#
# と表示される
```
Vue.js Vuex編(シンプルなカウンターアプリケーション)

## 実行環境
macOS Catalina バージョン 10.15.7
MacBook Pro 13インチ
Vue 2.6.12

## カウンターアプリケーション
vuexを用いてカウンターアプリケーションを作成する。まず、プロジェクト内でvuexをインストールする。

```
npm install vuex
```

その後、srcディレクトリの直下にstore.jsを作成する。シンプルなVuexStoreを記述する。(main.js内でstoreをインポートしてvueインスタンス内に記述しないとvuexを使うことができないので注意。)


```javascript:store.js

// vue,vuexをインポート
import Vue from 'vue'
import Vuex from 'vuex'

// vuexプラグインの使用の宣言
Vue.use(Vuex)

// シンプルなVuexStore
const store = new Vuex.Store({
    state: {
        count: 0,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    }
})

// storeをエクスポート
export default store

```

stateに格納されているデータは直接変更することはできない。ミューテーションをコミットすることによって値の更新をすることができる。ミューテーションの中で定義する関数の引数にはstateが必要となる。
次にApp.vueの子コンポーネントとしてCount.vueを作成する。

```vue:Count.vue
<template>
    <div>
        <h3>カウンターアプリケーション</h3>
        <button @click="increment">+1</button>
        <p>{{ count }}</p>
    </div>
</template>

<script>
export default {
    computed: {
        count() {
            return this.$store.state.count
        },
    },
    methods: {
        increment() {
            this.$store.commit('increment')
        },
    }
}
</script>
```

コンポーネントから値を更新する際、this.$store.commit('increment')のようにしている部分がミューテーションをコミットしている部分である。

![スクリーンショット 2020-12-15 10.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/6d8d30d7-1d58-6616-9a9b-126f5fce53b0.png)

## 最後に
今回は非常にシンプルなカウンターアプリケーションを作成した。次の記事でgetters,mutations,actionsについてまとめようと思う。
マークダウン記法

# マークダウン記法基礎
## 見出しの作成方法 
 見出しを作成するのは#を使用し、htmlのh要素と同じく１〜６までの大きさを選ぶことができる。（#の数で調整する）
 '### 試し書き'のように記述する。

##箇条書きリストの作成
先頭にハイフン、アスタリスク、プラス記号を使用する。
半角スペースを用いることに注意する。
例）

- 試し書き
* 試し書き２
+ 試し書き３

1. 試し書き
2. 試し書き
 3. 試し書き 

※数字を使用してのリストの作成においては自動で数字が割り振られる。
　上記においては以下のように記述している。
　'1.試し書き
　 2.試し書き
　　　3.試し書き'

##引用文
'>を使用する。'
以下参照

>こんにちは
>>試し書き


## pre記法
    def challenge
     スペース４個かtabキーを使用することでコードを記述することができる
    end

##code記法
　文章の一部の背景色をつけて記入することができる記法。
　コマンドは`Shift+@キー`である。
## 強調（斜体）
　アスタリスクかアンダーバーで文字列を囲むことで強調できる。
　こん*にちは*
　_こん_にちは
## 太字表示
　アスタリスク2つかアンダーバー2つで強調箇所を囲む。
　こん**にちは**
　__こん__にちは
## 斜体＋太字
　アスタリスク3つかアンダーバー3つで強調箇所を囲む。
　こん***にちは***
　___こん___にちは
## 水平線
　アンダーバーアスタリスク、ハイフンを三つ以上連続で記述すると以下のような表記ができる。
***
## リンク先
　[表示文字](リンクURL)
　[Yahoo! JAPAN](https://www.yahoo.co.jp/)
## 取り消し線
　〜〜で対象を囲む。
　~~試し書き~~
 '〜〜試し書き〜〜'
　※↑本当は半角で入力すること。

##参照元
Markdown記法 サンプル集
https://qiita.com/tbpgr/items/989c6badefff69377da7
Markdown記法/書き方（見出し・表・リンク・画像・文字色など）
https://notepm.jp/help/how-to-markdown
生産現場でのenebularの典型的なユースケース

## 中小規模の工場でのenebularの使われ方

enebularは生産現場でもよく使われます。以下の優先順位で対応することが多いです（個人的見解且つ中小規模）

1. 既存の生産管理システムからアラートを飛ばしたい
1. ハカリやノギスを直接システム連携して人によるキーパンチを減らしたい
1. OT側のプロトコルとIT側のプロトコルを変換したい
1. 既存の生産設備の周辺にセンサーを設置して稼働状況を監視したい
1. 既存の生産設備から直接クラウドにデータを送りたい

![Screen Shot 2020-12-15 at 15.20.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21109/59ed20a4-ec56-7169-d0a2-3795eab7811e.png)

生産現場を良く知らないうちは優先順位が全く逆だと思っていましたが、実際は既存設備やシステムを現状維持したままで改善していく「レトロフィット」の方が求められます。

## 現場は今困っているところから改善してほしい

生産現場ってITの人に言われなくても以前から「自動化」に取り組んでいました。そんな生産現場の人に足元の課題を聞くと生産管理システムの愚痴が多いです。

* 既存の生産管理システムがWindowsのデスクトップアプリ
* メールアラートからリンクを踏んで必要な処理をする画面を開くというようなWebでは当たり前の体験がない
* アラートがないので何か監視が必要なデータは毎回アプリケーション画面を開いて確認する
* アラートがないのでプロセス遷移は作業指示書などの紙を発行して次の担当に渡す
* 重量や寸法を測って用紙に記入してシステムに手入力する
...

これってUXの問題ですよね...

## 現場が最も困っているところから改善すると話を聞いてくれる

現場の全員が困っていることから改善すると話を聞いてくれるようになります。

これまで遭遇したセンターピンは大概 enebular ですぐに解決するようなものばかりでした。課題を聞いて1週間くらいで「こんな感じですかね？」とプロトタイプ見せるとメッチャ喜ばれます。

ちょっとニーズを汲み取り違っていたとしてもプロトタイプがあれば何がどう違うのか具体的に議論できるので課題に対して前向きになれます。

そう、人は実際に見たり触れたりすることで初めて実感が湧くんですよね。

そうすると enebular や我々のことを認めていただき、アレもコレも改善事項が噴出してきて優先順位の議論を始めたりします。非常に前向きに。

まさに「センターピン理論」です。

DXって技術の問題よりも「組織や人が変化を受け入れられるかどうか」の問題の方が遥かに大きいと思います。

## 実際どうやったの？

この記事ではここまでですが今後以下について詳しく書いていきたいと思います！

1. [既存の生産管理システムからアラートを飛ばしたい](https://qiita.com/joeartsea/items/8a7bb8237d6bf1530893)
1. ハカリやノギスを直接システム連携して人によるキーパンチを減らしたい
1. OT側のプロトコルとIT側のプロトコルを変換したい
1. 既存の生産設備の周辺にセンサーを設置して稼働状況を監視したい
1. 既存の生産設備から直接クラウドにデータを送りたい
Vue.jsでパンくずリスト(手動でページ設定)

### はじめに
Vue.jsでパンくずリストを実装すべく調べながら進めたので、メモ書きとして残しておきます。
自動でリストを作成する内容ではありませんので、よろしくお願いします。

### 仕様について
TOPページから一覧ページを挟んでとあるページに遷移します。


### 実装

##### 呼び出し側の中身

```Example.vue
<div>
    <BreadCrumb :breadcrumbs="breadcrumbs"/>
</div>

<script>

import BreadCrumb from "/components/BreadCrumb";

export default {
  components: {
    BreadCrumb
  },
  data () {
    return {
      breadcrumbs: [
       {
          name: 'TOP',
          path: '/'
        },
        {
          name: 'Category', // 中間ページ
          path: '/category',
        },
        {
          name: 'ExamplePage' // とあるページ
        }
      ]
    }
};
<script>
```


##### パンくずリストのコンポーネント中身

```BreadCrumb.vue
<div class="breadcrumb-area">
    <div class="breadcrumb-item">
      <div v-for="v in breadcrumbs">
        <div v-if="v.path">
          <router-link :to="v.path">
            <span class="link">{{v.name}}</span>
          </router-link>
          <span class="space">></span>
        </div>
        <div v-else>
          {{v.name}}
        </div>
      </div>
    </div>
  </div>
```

##### 解説
例として最後のとあるページで記載しています。
子コンポーネントに渡すデータにそのページまでのnameとpathをdataに配列型に持たせることで、パンくずが増えていくイメージです。
とあるページでは、nameは保持させますが、pathを保持させないことで、v-ifを使ってリンクかただの文字を表示させるかを切り分けています。

↓こんな感じ
![スクリーンショット 2020-12-15 10.16.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422294/709f70fc-9653-4e27-e801-0a5c6020b6ea.png)

### 最後に
手動でページ設定をする方法でパンくずリストを作成してみました。
ちなみに、自動でページ毎に設定をさせる方法もあるみたいですので、大量のページに使う方などはそちらを参考にして頂いた方がいいかもしれません。

https://hirakublog.com/code/218/
参考にさせていただきました。ありがとうございます。
bundle installで起きたnokogiriエラーからの、Gem::FilePermissionErrorを解決する



#環境
・Ruby 2.5.7
・Rails 5.2.4.4
・macOS Catalina 10.15.7
・rbenv 1.1.2 

#起きたエラー
Herokuへのデプロイ用にGemfileを修正後、
$ bundle install したところ下記エラーが発生しました。

```
An error occurred while installing nokogiri (1.10.10), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.10.10' --source 'https://rubygems.org/'` succeeds before bundling.
```
言われた通りnokogiriをinstallしようとすると、更に下記エラーが出て詰まっていました。

```
$ gem install nokogiri -v '1.10.10' --source 'https://rubygems.org/'
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
```
#解決過程 

解決過程は参考にさせていただいた下記記事をほぼなぞっています。
[bundle installしてもpermissionsエラーが起きるときの対処法](https://qiita.com/edasan/items/288604b78e5cf6407d0e)
また、自分はそもそもpathってなんぞ？って感じだったので以下記事が勉強になりました。
[PATHを通すとは？ (Mac OS X)](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)


####＄ which rubyで確認したところ、Rubyを通しているpathが違う。
/Users/ユーザー名/.rbenv/shims/rubyとなっていなければいけないところが
下記の様になっている。

```
＄ which ruby
/usr/bin/ruby
```
こちらを正しく修正するためにechoコマンドで.bash_profile修正し、
 exec $SHELL -l　で再起動。

```
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```
＄ which rubyで確認すると

```
＄ which ruby
/usr/bin/ruby
```
####変わってない！！

vi操作 $ vi ~/.bash_profile で.bash_profileの中身を確認すると、下記の通り正しく編集されている　

```
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```          
シェルが反映されていないだけの様なので、.bash_profileを編集した内容を反映させる下記コマンドを打つ。 

``` 
$ source .bash_profile　        
```
＄ which rubyで確認すると

```
＄ which ruby
/Users/ユーザー名/.rbenv/shims/ruby
```
####変わった！
その後、下記の流れで無事、$ bundle install出来ました。

```
$ gem install nokogiri -v '1.10.10' --source 'https://rubygems.org/'
$ gem install bundler
$ bundle install
```
**※補足**
$ gem install bundlerを行った理由は、nokogiriインストール後、bundle install しましたが、下記のエラーが出てしまった為です。

```
rbenv: bundle: command not found
The `bundle' command exists in these Ruby versions:
2.7.2
```
以上です、解決のためお世話になったメンターさん等々ありがとうございました。

#参考サイト
https://qiita.com/ginokinh/items/45ac4cd16f766a426532
リモートワークの中チームで働くために必要だと思ったこと

## チームで働く際にいいなと思ったことメモ
今のチーム体制はすごくいいなと思っている。
気晴らしで会社に行くなどはあるが特にチームとして出社する日を設けてはいない中チームとして高いアウトプット出せていると思う

## なので、なぜこのように高いアウトプットが出せているのかを考えてみた。
そして1つの結果にたどり着いた。

##今のチームはとても雑談が多い気がする。
もちろん開発の中でこれをどのように開発をしていくか、
お互い詰まったとこはないかなどの情報共有をするのはもちろんだがそれ以外にも「最近、寒い…」「美味しいものを食べに行きたいですね！」みたいな話もする。
そのようなことを行うことでメンバー同士の関係値が上がり、
結果としてチームの生産性向上につながっているのではないかと思った。
ただ、まだまだどんな要素でチームの生産性が向上するかの要素を検討、模索段階なので他にもこんな施策を行っていますよ！
という情報は随時募集中です！！
よろしくお願いいたします。
KtLint + Spotless + GitHub ActionsでPRにsuggested changeさせる

ちょっと30分ぐらいで書いた小ネタで申し訳ないんですが、すごく簡単で、便利なので、アドベントカレンダーで紹介します。

Android Studioの自動フォーマットだとKtLintで指摘されるものを修正できず、Formatterをコミット前やビルド時に走らせるのもコード量に比例して遅くなりそうで、また変更したところだけフォーマットさせたいですがうまくできません。コミットのたびに時間かかりそうで微妙で、なにか解決策を探していました。
これを調べ始めて30分程度でできちゃったので、すごく簡単に機械的にレビューさせられるので、ちょっと試してみてください。

インデントを直すsuggested changeの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/c67bbb76-f2b0-12a2-035d-7649f631c2bf.png)

# 使うツール

Spotless
変更したファイルを検出してFormatterを呼び出してくれたり、いろいろな機能があります。(JetNewsなどGoogleのOSSなどでも使われています。)

KtLint
Kotlinでよく使われるFormatterです。Spotlessと連携して動作させることができます。

reviewdog
PRにレビューコメントをしてくれるツールです。最近、git diffで変更が出ている部分をSuggested Changeでレビューできる機能が追加されました。


この3つを連携させて変更したファイルをフォーマットさせ、変更をsugggested changeさせることができます。


# 手順
まずSpotless + KtLintを導入します。

```groovy
plugins {
    id 'com.diffplug.spotless' version '5.7.0'
}

allprojects {
    repositories {
...
    }
}

subprojects {
    repositories {
        google()
        jcenter()
    }

    apply plugin: 'com.diffplug.spotless'
    spotless {
        kotlin {
            target '**/*.kt'
            targetExclude("$buildDir/**/*.kt")
            targetExclude('bin/**/*.kt')

            ktlint("0.39.0")
        }
    }
}
```

あとは以下を `.github/workflows/review-suggest.yml` などに保存します。
GITHUB_TOKENは勝手にGitHub Actionsが提供しているので、他にすることはないです。
ここではreviewdog/action-suggesterを使っています。


```yml
name: reviewdog-suggester
on: [pull_request]
jobs:
  kotlin:
    name: runner / suggester / spotless
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1 # JDK 11が必要なければ消してください
        with:
          java-version: '11'
      - run: ./gradlew spotlessKotlinApply
      - uses: reviewdog/action-suggester@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          tool_name: spotless
```


以下でフォーマットをかけて

```
./gradlew spotlessKotlinApply
```

以下でreviewdogを使って差分をコメントさせるだけです。つまり差分さえあればレビューさせられるので、いろんなフォーマッターに使えて便利です。

```yml
uses: reviewdog/action-suggester@v1
```

これでコメントさせていくことができました。 GitHub Actionsでreviewdogを使うことに対してセキュリティなど少し気になるところはあるのですが、reviewdogの作者の方は以前にGoogleにはいるブログなどを書いていたりして、割と身元が分かっている方なので安心して使うことができます。

# ローカルでコミット前にフォーマットするには？

何も考えずに `./gradlew spotlessApply`だけだと全部のソースコードをフォーマットかけてしまいます。

spotlessにはratchetという便利機能があり、以下のようにratchetFromでブランチを指定しておいて、 `./gradlew spotlessApply`　すると、masterブランチからの差分だけフォーマットをかけることができます。便利です。

```groovy
spotless {
    ratchetFrom 'origin/master'
```

ただしこの機能をGitHub Actionsでも使う形になるので、yamlファイルにcheckoutを追加して一度masterをチェックアウトしてから必要なブランチにチェックアウトして利用してく必要があります。これをしないとorigin/masterが存在しないという形でビルドが失敗します。

```yml
      - uses: actions/checkout@v2
        with:
          ref: master # 一度masterでcheckoutする
      - uses: actions/checkout@v2 # 目的のブランチでcheckoutする
```
ターミナルのよく使うコマンド（備忘録）

##cdコマンド

ディレクトリを移動

##lsコマンド

ディレクトリの内容を表示。

ls -a コマンドで、隠しファイルを含めたディレクトリ全内容を表示

##mkdirコマンド

ディレクトリを新規作成

##rmコマンド

ファイルを削除

rm -r コマンドで、ディレクトリの削除

##cpコマンド

ファイルをコピー

cp -r コマンドで、ディレクトごとコピー

##mvコマンド

ファイルの移動とファイル名の変更

##catコマンド

ファイルの中身を表示
【Stereo Depth】ML-ArgMaxの提案

<h1>On the Importance of Stereo for Accurate Depth Estimation:
An Efficient Semi-Supervised Deep Neural Network Approach</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/85ee7a86-f082-bcc1-be53-78855ab300bf.png)

従来手法を比較する論文となっていった。
さらにML-ArgMaxを新たに提案した。




<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/eb5cbec2-ba1f-c968-a08e-a97742cfa003.png)
GC-Net(2017年のモデル)と比べて同程度の精度って、あんまり精度よくないな~


<h1>参考文献</h1>
On the Importance of Stereo for Accurate Depth Estimation:An Efficient Semi-Supervised Deep Neural Network Approach
https://arxiv.org/pdf/1803.09719.pdf
閏年じゃない年も2月29日生まれの人をお祝いする

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E9%96%8F%E5%B9%B4%E3%81%98%E3%82%83%E3%81%AA%E3%81%84%E5%B9%B4%E3%82%822%E6%9C%8829%E6%97%A5%E7%94%9F%E3%81%BE%E3%82%8C%E3%81%AE%E4%BA%BA%E3%82%92%E3%81%8A%E7%A5%9D%E3%81%84%E3%81%99%E3%82%8B/)をご覧ください😀


これは[SOUSEI Technology アドベントカレンダー2020](https://qiita.com/advent-calendar/2020/st) 15日目の記事です。

## 2/28と3/1どちらで祝うべきなのか

2/29生まれの人、閏年なら当日お祝いしてあげればいいのですが、閏年じゃないときはどうすればいいの？
ググってみました。

> 例年については、男女共に「2月28に祝う」という声が圧倒的。
> https://cocoloni.jp/love/232234/

> あとで祝われると「忘れてたでしょ？」ってなりそう
> https://teratail.com/questions/145109

ということで2/28にお祝いします！🎉🎂
あとはデータを取得するだけ！

## 今日が誕生日の人を取得する

当日が2/28かつ閏年でないときに、追加で2/29のデータを取得してあげればOK！

```php
$today = Carbon::now()->toDateString();
$users = User::whereDay('birthday', date('d', strtotime($today)))
    ->whereMonth('birthday', date('m', strtotime($today)))
    ->get();
if(date('m-d', strtotime($today)) == '02-28' && !date('L', strtotime($today))) {
    $users->merge(
        User::whereDay('birthday', 29)
        ->whereMonth('birthday', 2)
        ->get();
    );
}
return $users;
```

## 範囲指定（from〜to）で誕生日の人を取得する

これは指定された日付が閏年かどうか気にする必要はなく、toが2/28のときだけ考慮すればOK！

```php
/**
 * 月日が日付範囲に含まれるスコープ
 *
 * @param Builder $query クエリ
 * @param string $column 対象カラム
 * @param Carbon $from 開始日
 * @param Carbon $to 終了日
 * @return Builder
 */
private function scopeWhereBetweenMonthAndDays($query, $column, $from, $to)
{
    // fromとtoの差が1年以上あるときはすべての日が対象になるのでクエリ追加不要（全データ取得する）
    if (!$to->diffInYears($from)) {
        $from_without_year = $from->format('m-d');
        // 閏年対応。2/28が指定された場合は2/29として、2/29のデータも取得対象とする
        $to_without_year = $to->format('m-d') == '02-28' ? '02-29' : $to->format('m-d');

        if ($from->year == $to->year) {
            $query = $query->whereRaw('DATE_FORMAT(' . $column . ',"%m-%d") >= "' . $from_without_year . '"')
                ->whereRaw('DATE_FORMAT(' . $column . ',"%m-%d") <= "' . $to_without_year . '"');
        } else {
            $query = $query->where(function ($q1) use ($from_without_year, $to_without_year) {
                $q1->orWhereRaw('DATE_FORMAT(' . $column . ',"%m-%d") >= "' . $from_without_year . '"')
                    ->orWhereRaw('DATE_FORMAT(' . $column . ',"%m-%d") <= "' . $to_without_year . '"');
            });
        }
    }
    return $query;
}
```

## さいごに

僕の誕生日は3/3です！
プレゼント待ってます！