OmniAICreator/Qiita-1.07M huggingface dataset:
【Django2.2】テンプレートフィルタを利用して日付の新しい投稿にNewバッジをつける

# 概要
ブログのようなサイトの記事一覧ページにて、**新しい記事にNew!というバッジをつけたい** というのはよくあるケースだと思います。
Djangoでこれを実現するには、Contextにnewかどうかのboolを追加する、というやり方が考えられますが、ListViewでこれを行うのはあまり良い方法とは思えません。
今回はテンプレートフィルタを自作して、テンプレート内で新しい記事かどうかを判定する方法を紹介します。

## 環境
- Python 3.7.4
- MacOS Mojave 10.14.6
- Django 2.2.8

# ファイル作成
`<プロジェクトフォルダ>/<アプリケーションフォルダ>/` 内に`templatetags/`ディレクトリを作成します。
このアプリケーションは`settings.py`のINSTALLED_APPに記述する必要があります。

作成したディレクトリに、`<任意の名前>.py`のファイルを作成します。
ここでの<任意の名前>はtemplate内で`{% load <任意の名前> %}`とするので、命名に気をつけます。

# フィルタを作成
今回は、datetime型の値を受け取って、それが直近一週間かどうかを判定するフィルタを作成します。
このフィルタを用いてif文を分岐させるので、返り値はboolにします。

```python:.../templatetags/sample_filter.py
"""
dateが直近一週間かどうか判別するテンプレートタグ
"""
import datetime

from django import template
from django.utils import timezone

register = template.Library()


@register.filter(expects_localtime=True)
def is_new(dt: datetime.datetime):
    # newかどうかの基準日
    criteria_date = timezone.now() - datetime.timedelta(weeks=1)
    return dt >= criteria_date
```
#### `expects_localtime=True`について  
公式Docより

> If you write a custom filter that operates on datetime objects, you'll usually register it with the expects_localtime flag set to True:
>> 日時オブジェクトを操作するカスタムフィルターを作成する場合、通常は、expects_localtimeフラグをTrueに設定して登録します。

> When this flag is set, if the first argument to your filter is a time zone aware datetime, Django will convert it to the current time zone before passing it to your filter when appropriate, according to rules for time zones conversions in templates.
>> このフラグが設定されている場合、フィルターの最初の引数がタイムゾーン対応の日時である場合、Djangoはテンプレートのタイムゾーン変換の規則に従って、適切なときにフィルターに渡す前に現在のタイムゾーンに変換します。

つまり、タイムゾーンを考慮して計算を行う場合に必要な引数です。
フィルタ関数に渡されるdatetimeがタイムゾーンを考慮した値になります。

#### 命名
`@register.filter(name='foo')`としてやると、template内ではfooという名前でフィルタが利用出来ます。 
name引数を渡さない場合、関数名がそのままフィルタの名前になります。
今回はname引数を渡していないので、`is_new`という名前でフィルタを利用します。

# template
template内では以下のように利用します。
以下はお知らせ一覧を表示し、一週間以内であればnew!バッジをつける例です。bootstrapを使用しています。
contextにnewかどうかを判断したboolを渡すより、かなりすっきりします。

```html:template
{% load sample_filter %}
    ...
    {% for news in news_list %}
    <a href="{% url 'news:detail' news.pk %}" class="list-group-item list-group-item-action">
    <span>{{ news.publish_time |date:"Y年m月d日 H:i" }}</span>
    <span class="badge badge-primary">{{ news.category }}</span>
    {{ news.subject }}
    <!-- newバッジをつけるか判定 -->
    {% if news.publish_time|is_new %}
    <span class="badge badge-info badge-new">new!</span>
    {% endif %}
    </a>
    {% empty %}
    <p>お知らせはありません。</p>
    {% endfor %}
    ...
```

# 他
上のコード中で利用しているdateフィルタのように、フィルタは引数をとることもできます。
公式Docの引用になりますが、

```python
def cut(value, arg):
    """Removes all values of arg from the given string"""
    return value.replace(arg, '')
```

```html
{{ somevariable|cut:"0" }}
```

として使えます。get_context_dataなどが肥大化していく際は、テンプレートフィルタを利用するのも一つの手でしょう。


# 参考
独自のテンプレートタグとフィルタ | Django ドキュメント | Django
https://docs.djangoproject.com/ja/2.2/howto/custom-template-tags/
Xcode 11とiOS 13により本番環境でやらかした話

<h4><font color="red">この物語は現実で起こった物語を120%くらい脚色したフィクションです。</font><br>
<font color="red">もう1度いいます、フィクションです。現実の人物や組織、アプリ等とは一切関係がありません。</font></h4>

## 要約
* チームで使うXcodeのversionを揃えよう
* macOSのversionによって使用できるXcodeのversionは左右されるので、OS updateは慎重に
* Mac App StoreからXcodeをインストールするのは止めよう
* AppleはSDKのダウングレードであれば審査は許容してくれる

## 序
Xcode 11及iOS 13がリリースされたことにより、世界はDark Mode Sideに堕ちた。

そんな世界の中の日本という国の東京/新宿と呼ばれる場所で事件は起きた。

「なんじゃぁぁぁぁぁーーーーー！！こりゃあああああぁぁぁぁーーーーーー！！！」

オフィスにこだまするKWTBの声。
腹でも撃たれて血を出したのだろうかと思いつつ、僕には関係ないことと思って日課のTwitterを眺める。

「くぁwせdrftgyふじこlぱqwせdrftgyふじこlp」

KWTBがなおも何か言っているが、自分には関係ないことだろうと気にも止めない。
そんなさなかSlackで僕宛にメンションで開発部のリーダーIHJRから話が飛んでくる。
氏、曰く「さきほどリリースしたiOSアプリの見た目がおかしい。至急調査されたし。」

「なるほど。やれやれ、短い平和な日常だったぜ」とぼやきつつも、
即座に頭を切り替えて起こっている自体の把握に取り掛かった。

## 破
事象をまとめるとこうだ。

問題は…

* アプリを起動すると本来であれば白色で表示される背景が黒く表示されている
* 黒くなっている背景は全体ではなく、画面のコンポーネント単位程度で発生している
* WebViewを除くほぼ全ての画面で発生している

該当端末は…

* iPhone
* iOS 13系

(なんてこった。こんなことが起こり得るのか…)
起きている事象の原因と理由に想像を巡らせ思考の波の中でため息をついた。
そしてこんなことが起こる理由は1つしかない。

アプリの申請を行ったNZKGに確認を取りたかったが、遅刻をしており連絡がまだ取ることができなかった。
ひとまずSlackにメッセージだけ残し、推測を検証する作業にとりかかった。

……

検証内容は至極簡単だ。

1. Xcode 11の最新版を起動する
2. iOS 13の実機端末で実行する
3. iPhoneのDark ModeをONにする

なるほど、Q.E.D.

想像の通りXcode 11で実機実行したアプリが、今App Storeでリリースされたものと完全に一致し、
Dark Modeが意図せず適用されていることが確定した。

ひとまず、KWTBに説明すべくSlackで原因と思われる内容を含め記載。
そして次に思考をシフトする……今回のこの事象をどう決着つけるかだ。

取りうる手は、

* 直前まで開発に使用していたXcode 10の最新版で再度申請
* Xcode 11の最新版でDark Mode対応を行う

前者は、iPad対応しているprojectから対応を外すことを許さないAppleが認めるのか怪しが賭けだ
後者は、Dark Mode対応すると工数が今からどれだけかかるかもわからない上、modal表示もdefaultが変わっており、進行していた機能改修を止めて対応しなければいけない。

開発部のSlackで、このことを伝えどうするか相談する形を取ったが、
前者をやりつつ、前者がダメだったときに備え、後者の最低ラインを実装する方向しかもはや選択肢はなかった。

そんな折にGoogleのCEOサンダー・ピチャイに似たO0CHが、慧眼で本質を射抜く。

「Dark ModeがOnでも背景を今までと同じ色で表示することはできないんですか？」

どんな時も沈着冷静で頭脳は大人身体も大人な名探偵ばりの推理をいつも披露する私だが、どうもこの時は珍しく焦っていて正常に判断できていなかったようだ。そうだ、Dark Modeに無理に対応する必要はないのだ。
(サンキュー！ピチャイ！)

ポーカーフェイスを装いつつ心の中でピチャイに感謝し、即座にDark Mode Onでも背景が変わらずに済む方法を調べた。

> If you need extra time to work on your app's Dark Mode support, you can temporarily opt out by including the UIUserInterfaceStyle key (with a value of Light) in your app’s Info.plist file. 
>
> (意訳：Dark Modeを回避するなら`Info.plist`に`UIUserInterfaceStyle`のキーに`Light`の値を設定しなさい)
> 
>[知恵の実の聖書](https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface/choosing_a_specific_interface_style_for_your_ios_app/)より引用

そして何食わぬ顔で言う。

「設定でDark Mode余裕で回避できるわ〜めっちゃ余裕っすわ」

何故かチャラい言い方になってしまった。

## 離
後日談というか今回のオチ

Dark Modeを回避や対応するなんてことはなく、

> * 直前まで開発に使用していたXcode 10の最新版で再度申請

これをNZKGが出勤後に特急申請を行い、そして問題なく承認された。
ただそれだけだ。

審査承認後に即座にリリースされ、見てくれがイカれたアプリは短期間でApp Storeから消え去った。
iOS 13かつ常時Dark ModeをOnにしている人しか遭遇しなかったので、影響は大きくなかったと思う。

## 教訓
今回この事件が起きたことの理由の1つとしてアプリの申請を行うNZKGのMacBook Proでは、Mac App StoreからXcodeをインストールし、updateをボタン1つで行えてしまったことだ。

私の中ではProjectで使用するXcodeのversionは統一されるものだと思っていたし、
iOSに関わる人なら誰しもが知っている常識、暗黙の了解だと思っていた。
しかし、そんなことはなく、知っているかどうかはどこかで誰かから知識を共有される前提が必要となる。

そしてProjectのREADMEにXcodeのversionが指定されていても、誰もが目を通してその通りにするわけではないし、READMEも読まれなければ意味がないことを思い知った。

このProjectのXcodeの環境回りを整えていたのは私なのだが、整えた際にXcodeのversionについて周知しなかった瑕疵が大きく今回のことを深く反省しなければならない。

## 格言 
かの有名なKSKW氏もこう仰っていた。
「XcodeはApple DeveloperからDLして入れるべし」と。

もしくはXcodeGen使うべきよね。
リーダブルコード　メモ　＃1

# 名前に情報を詰める

- sizeなどでは何のsizeかわからないから高さなどの情報を入れる変数にはheightなどとする。
- getも同じ。
- tmpは一時的な保管に使う。

# 名前に情報を追加する

- htmlの文字コードをUTF-8に変えたというときなどに html → html_utf8とかく。
- ただし、バグが起こりそうなところなどだけでok

# 名前の長さを決める

- その名前が見えるコードの行数が小さければ名前は短くてもok
- 長くてもok（補完機能があるから）
- 見える行数が長ければ長い名前を付ける
GPUのメモリ使い果たし対策(tensorflow version2.0)

<h1> GPUのメモリ節約法(tensorflow)</h1>

こんにちは、にわかです。


テーマは、タイトル通りなのですが、GPUのメモリ(VRAM)使い果たし対策です。


<h3>初期化時のGPUのメモリ確保を制限する。</h3>


```
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True) 
  except RuntimeError as e:
    print(e)

```

バッチサイズを1つにしたのに、画像の縦横の大きさを小さくしたのに、メモリの使い果たしをした人は上の方法で解決できるはずです。

※プログラムの開始時に、GPUのメモリを確保できるだけ確保するため(何かしらのプロセス用に)、後から学習データをGPUにロードする際にメモリの使い果たしで、ランタイムエラーを起こす場合があります。上のコードを書けば、必要になった分だけGPUのメモリ確保を行います。

ちなみに、CPUには上のコード使えないので注意してください。
AngularJS だけど Storybook が使いたい

この記事は [Angular Advent Calendar 2019](https://qiita.com/advent-calendar/2019/angular) の20日目の記事です。空きが出ちゃったとのことなので代打で書きました。:baseball:

この記事では AngularJS で Storybook を使い始めてみたことについて書きます。

## 使い始めた背景
ここ最近、AngularJS を Angular に移行するプロジェクトに取り組んでいました（まだ終わってない :sweat_smile: ）。AngularJS からの移行作業というのは既存のコードベースがどの程度モダンな環境になっているかによって難易度は変わってくるかと思います。自分がいるチームのプロダクトの場合はこんな状況でした。

- モジュールローダーは使っていないので移行と共に対応させる必要がある。
- ES5 で書かれているので移行と共に TypeScript 化を行う必要がある。
- [AngularJS老化チェック](その使い方はもう古いかも？AngularJS老化チェック（ディレクティブ篇）) でいう"化石"や"論外"ケースもまあまあある。
- ユニットテスト・E2Eテスト・仕様書はほぼない

特に、老化チェックに引っかかるような項目についてはそもそも同等の API が Angular になかったりするため、必然的にリファクタをしなければいけません。その際に怖いのがデグレです。デグレを防ぐために有効な手段の１つがユニットテストですが、UIが微妙にずれてしまったりとかはなかなか気づきづらく、E2Eテストも正直メンテナンスコストもかかるし、どうしたもんかという感じでした。そんな時、他のチーム（React を使っていた）が Storybook の出力を PR に通知させてレビュー用に使っていたのが目に入りました。

## AngularJS には公式のサポートはなかった
ここはひとつ真似してみるかと思い、Storybook のドキュメントを読んでみたものの、どうも AngularJS は Storybook の公式サポートはなさそうでした（参考：[Storybook with Angularjs (1.x)? #3508](https://github.com/storybookjs/storybook/issues/3508)）。何か方法がないか調べていたら、サードパーティのアドオンが公開されているのを見つけました。

- [Storybook Addon AngularJS (1.x) - DEV Community ‍ ‍ - Dev.to](https://dev.to/titonobre/storybook-addon-angularjs-5c71)

実装を見ていくと、基本的には `@storybook/html` をベースに、story 中で定義したエレメントを良い感じにコンパイルしてくれるラッパーみたいな感じのシンプルなものでした。とはいえ、基本的な用途としては普通に使えそうで、すでに今のプロジェクトでもこのアドオンを利用していくつか story を書いたりしています。

## PRで通知する仕組みを作ってみた
インフラ担当の人にも手伝ってもらい、こんな仕組みを作りました。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27079/bc02da2d-ff77-ead5-58af-72e09b5f306b.png)

1. 開発では Backlog 使っているので、PRもBacklog上で出します。
2. PRを作ると、Jenkins のジョブが動き始めます。([JenkinsのBacklogプラグイン](https://wiki.jenkins.io/display/JENKINS/Backlog+Plugin) を使用）
3. テストが通ったら、`build-storybook` が実行されて、成果物がS3にアップロードされます。
4. テスト〜アップロードまでジョブが完了したら、BacklogのPR画面にS3上のURLが通知されます。
5. レビュワーはStorybookの出力を参照しつつ、レビューを行います（ここまだフローとしてあまり確立できていない）。

## やってみてよかったこと
正直まだ仕組みを作っただけで使い始めたばかりですが、いくつかメリットを感じました

- UIの変更が見やすい（そもそもこれがしたかった）
- story を書くにあたり、コンポーネント的な書き方を意識させられる。（ng-controller じゃなくて component API 使った方が明らかに親和性高い）
- そのコンポーネントをどのように使うのか、わかりやすくなる。
- UIの実装とロジックの実装を分業しやすくなる。
RaspberryPiに公開鍵でSSH接続する際に、.sshの誤った所有者設定のせいでエラー

サーバーの勉強のためにRaspberryPiを触っています。

## 公開鍵を用いたSSH接続ができない

公開鍵を用いてSSH接続する方法は様々なサイト ([ここ](https://mattintosh.hatenablog.com/entry/20150201/1422798304)とか参考にしました) で解説されています。
しかし自分がそれらの設定を模倣してみても、Windows10のコマンドラインからSSH接続を試みようとすると

```
pi@raspberrypi3b.local: Permission denied (publickey).
```

といったエラーが出て失敗してしまいました。

SSH接続を試みた際のエラーは /var/log/auth.log に出力されるようですが、そこを確認しても

```
Connection reset by authenticating user pi
```


といったログが失敗した回数分だけ残っているばかり。
このログはSSH接続に失敗した際に残る汎用的なもののようで、このメッセージだけで検索しても不具合の原因は特定できませんでした。

## .sshフォルダの所有者はrootではなく対象のユーザーに

そんなこんなで数日間唸ってたのですが、色々と弄っていたらふと上記のエラーが解決しました。

自分は.sshフォルダを作成する際にsudoコマンドでmkdirを実行していたのですが、その場合はフォルダの所有者がrootとなり、これが不具合の原因となっていたようです。
最終的に**chownコマンドを用いて、.sshフォルダの所有者をpi (SSHの設定をしているユーザー) に変更したら正常にSSH接続できるようになりました。**

```
chown pi:pi .ssh
```

(ちなみに、.ssh/authorized_keys も所有者をpiからrootに変えたら接続できなくなりました)

## 検索しても出てこなかった

.ssh と authorized_keys の permission のことは色々なサイトで注意するように言われていたけど、誰も owner のことなんて言及していなかったじゃないですか…

自分はLinuxもRaspberryPiも初心者でして、この記事の内容も初歩的なものかもしれませんが、同じ症状で悩んで検索している人の助けになればと思い投稿しました。
obnizOS 3.0.0でobniz-nobleを使って周囲のBLEデバイスを探してみる


#obnizOS 3.0.0がリリースされました。
新バージョンではBLE機能が強化されている印象を受けました。

##手持ちのobnizBoardで新機能を試してみたい。
Node.jsでobniz-nobleを使ってをobnizで周辺にあるBLEデバイスを検索してみる

```
npm i obniz-noble
```

``` server.js
'use strict';
const express = require('express');
const PORT = process.env.PORT || 3000;
const app = express();

var obnizNoble = require('obniz-noble')
var noble = obnizNoble("OBNIZ_ID_HERE")

noble.startScanning(); // any service UUID, no duplicates

noble.on('discover', function(peripheral) {
    console.log('発見したデバイス: ' + peripheral.advertisement.localName);
    console.log('デバイスのUUID: ' + peripheral.advertisement.serviceUuids);
    console.log();

});

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

こんな感じに検索されてくる。
ちょうど良いところにmicrobitが上がってきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399986/cf03c9c8-f760-16bc-667f-3e03c218ae14.png)

とりあえずここまで！
次はNode.jsでobnizとmicrobitを繋げるところの記事を書く予定です。
IISでASP.NETを動かすには

# ASP.NETをIISで動かすための環境構築
【GOAL】Web技術の仕組みを理解するために、自分でWebサーバーについて調べ環境構築してみる！

##目次

1．構築環境
2．そもそもIISとは？
3．IISの設定手順
4．VisualStudio2019でプロジェクト公開手順


## 環境
・Windows10
・VisualStudio2019

## そもそもIISとは？

IISはWebサーバーソフトウェアである
クライアントのリクエストに対してレスポンスを返す役割を担う

クラインアントがサーバーにリクエス(URL)を送り
サーバーがクライアントにレスポンス(HTMLや画像など)を返す
クライアントはChromやEdgeなどのWebブラウザからWebサーバーに見に行っている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479885/f10325f1-5927-fada-b2a5-c27d69fa6ff8.png)

参考サイト：https://www.kagoya.jp/howto/rentalserver/iis/

## IISの設定手順

以下のサイトを参考に設定を行った
参考サイト：https://www.kagoya.jp/howto/rentalserver/iis/

>(引用)
Windows10の設定の場合
・「Windowsシステムツール」を選択
・「コントロールパネル」を選択
・「プログラム」を選択
・「Windowsの機能の有効化または無効化」を選択
・「インターネットインフォメーションサービス」にチェックを入れてOKボタンをクリック
・IISのインストール開始(画面上は「変更を適用しています」)
・インストール終了
・ブラウザでhttp\://localhost/と入力して以下の画面が出たら、インストールが無事終了

## VisualStudio2019でプロジェクト公開手順

1．Cドライブ配下のフォルダに、リリースモジュールを公開。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479885/8837a693-daf7-c26b-2c11-f4a2f7a951a9.png)

2．IISマネージャーでアプリケーションの追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479885/e6be5788-da72-c69c-6cfe-54423c2a81a5.png)

3．http\://localhost/エイリアス名＋1で作成したプロジェクトのaspxファイル名を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479885/a262764e-e563-a166-8c04-944b43b08a64.png)


## つまづいたこと
・IISにWebアプリケーションを配置したとき、設定値が足りず405エラーが発生
解決策：https://qiita.com/RollSystems/items/2b5c8d0f5f9c6da7fc57

・IISマネージャーでアプリケーションの追加ではなく、仮想ディレクトリの追加を選択
解決策：https://qiita.com/wcathy007/items/2eb108c55cb57f926dc7

(おまけ)
仮想ディレクトリを追加して、WEBブラウザ上でフォルダを表示するには設定が必要
・機能ビュータブのディレクトリ参照をクリック
・右側の「有効にする」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479885/be426298-0d3f-2849-dd7a-6b8e5e97e6e9.png)

## 感想
・IISの設定自体は簡単
・調べる過程でシステムによって使う技術が違うためサーバーの構成が違うことがわかった
・システムの目的に沿ったサーバーの構成・選定が難しいのではないかと感じた
Linux mint が突然起動しなくなる unable to launch 'cinamon-session-cinmamon'

何が原因か不明だがログイン画面でログイン後 `unable to launch "cinamon-session-cinnamon"` とでてCinamonが起動してこない事があります。

対処

```
sudo apt install mint-meta-cinamon
```

で復旧できます。 
このパッケージはデスクトップ環境を導入するものなので本来は入っているはずのものだと思うのですが何らかの理由で削除されてしまったのかなと推測。
Issueをランダムに取得するGitHub Actionsを作ってみた

[LGTMすると現場猫が「ヨシ!」してくれるGitHub Actionsをつくった + Tips - Qiita](https://qiita.com/redshoga/items/986c07abb6d38766588b)を見てGitHub Actionsに興味が湧いたので、簡単なアクションを作成してみました。

## 今回作ったアクション

ラベルを引数にランダムなIssueのタイトルとURLを返します。
溜まるIssueを消費するためのIssueガチャとしてお使いください。

[GitHub - matometaru/issue-gacha-action: Get a random issue action](https://github.com/matometaru/issue-gacha-action)

<details><summary>毎週月曜に実行してスラックに通知するアクション例</summary><div>

``` .github/workflows/xxx.yml
name: Get a random issue and slack notification
on:
  schedule:
  # UTC
  - cron: '0 0 * * 1'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Get random issue gacha
        uses: matometaru/issue-gacha-action@v1.0.0
        with:
          labels: "test"
        id: gacha
      - name: Slack Notification
        uses: rtCamp/action-slack-notify@master
        env:
          SLACK_CHANNEL: self
          SLACK_ICON: https://github.com/rtCamp.png?size=48
          SLACK_MESSAGE: 'Result: ${{ steps.gacha.outputs.htmlUrl }}'
          SLACK_TITLE: ${{ steps.gacha.outputs.title }}
          SLACK_USERNAME: rtCamp
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
```
</div></details>



## 使ったテンプレート

[GitHub - actions/javascript-action: Create a JavaScript Action with tests, linting, workflow, publishing, and versioning](https://github.com/actions/javascript-action)

### Octkit（ライブラリ）

JavaScript用GitHub REST APIクライアントライブラリ

[octkit/restのドキュメント](https://octokit.github.io/rest.js/)

### inputsで入力を受け取るコード例

https://github.com/matometaru/issue-gacha-action/blob/master/action.yml#L3-L9

``` action.yml
inputs:
  token:
    description: 'GitHub Token(scope: repo)'
    required: false
  label:
    description: 'issue labels `lable1,label2,label3`'
    required: false
```

https://github.com/matometaru/issue-gacha-action/blob/master/index.js#L6-L7

``` index.js
const labels = core.getInput('labels');
const token = core.getInput('token');
```

### outputsで変数を出力するコード例

https://github.com/matometaru/issue-gacha-action/blob/master/action.yml#L10-L14

``` action.yml
outputs:
  title:
    description: 'Issue title'
  htmlUrl:
    description: 'Issue html url'
```

https://github.com/matometaru/issue-gacha-action/blob/master/index.js#L27-L28

``` index.js
core.setOutput('title', randomIssue.title);
core.setOutput('htmlUrl', randomIssue.html_url);
```

## さいごに

labelsを受け取って、IssueのタイトルとURLを返すだけのアクションですが、アクションの作り方を理解するには十分でした。まだまだ便利な機能や、[Marketplace](https://github.com/marketplace)に素晴らしいアクションがあると思うので引き続き調査を続けたいと思います。
Squidでwebsocket通信をプロキシする

# はじめに
[⁠B.7. Squid プロキシ](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Virtualization/3.3/html/Installation_Guide/sect-Squid_Proxy.html)
`Squid プロキシサーバーは webSocket プロトコルをサポートしていません。`


[[squid-users] Squid Websocket Issue](http://lists.squid-cache.org/pipermail/squid-users/2017-January/013953.html)
`Both the Upgrade and WebSockets support requirements are not existing in Squid.`

[Squid Websocket Issue](http://squid-web-proxy-cache.1019090.n4.nabble.com/Squid-Websocket-Issue-td4680870.html)
`Squid does not yet support using Upgrade for "websocket" protocol,`

__Squidでwebsocket通信ができない！？__
まじかよ……
チャットとかGoogleスプレッドシートの共同編集とかできないってことか…？

と思ったのでSquidでwebsocket通信をプロキシする方法を調べてみました。

# TL;DR
デフォルトのSquidの設定で__443/tcp__に向けた通信はwebsocketでも__プロキシすることができます。__
443/tcp以外のポートでwebsocket通信をプロキシしたい場合は、下記設定を追加すればOKです。

※443/tcp以外のポートもSSL通信とみなすようになるため注意

```sh:/etc/squid/squid.conf
acl SSL_ports port 【任意のポート番号】
acl Safe_ports port 【任意のポート番号】
```

# ざっくり説明
Squidはwebsocketプロトコル自体はサポートしていないようです。websocket通信時のヘッダーをSquidがサポートしていないことが直接の原因っぽい[^1]。
[^1]: [[squid-users] Squid Websocket Issue](http://lists.squid-cache.org/pipermail/squid-users/2017-January/013953.html) 

しかし、SSL/TLS通信をプロキシする場合、Squidはパケットの中身を（基本的には）見ることなく、接続先サーバまでただ転送するようになります。E2Eのセキュア通信なので、Squidは中身を気にしません。
つまり、websocketのパケットだろうと、Squidはクライアントからサーバまで通信を転送するようになり、その結果として対応していないwebsocket通信でもプロキシできるようになります。
SquidがSSL/TLS通信をみなすポートは、squid.confの`SSL_ports`で定義されており、デフォルト設定だと`443/tcp`になります。
そのため、デフォルト設定であれば443/tcpに向けた通信であればSquidは問答無用でプロキシします。
もちろん設定を変更すれば443/tcp以外のポートでもSSLプロキシできるようになります。（例は上記の通り）
プロトコルではなく、ポート番号で識別しているというところがミソですね。


#### 補足
上記の説明と矛盾しますが、SquidはSSL/TLS通信の中身も確認することができます（ssl-bump）。
Man-in-the-Middleと同じ原理で、クライアントはSquidとHTTPS通信し、SquidがさらにサーバとHTTPS通信します。
この設定を入れている場合に、Squidがwebsocket通信を正しくプロキシできるかは未確認です。


# 参考にした記事
[Websockets not connected behind proxy - stackoverflow](https://stackoverflow.com/questions/38974731/websockets-not-connected-behind-proxy/38976420)
WindowsでPythonのマイナーバージョン管理(仮想環境構築)する方法(PyenvやWSL無し)

# Windowsでもバージョン管理がしたい！
誰でも思いつく方法かもしれませんが、一度Pythonのバージョンを、仮想環境用のバージョンに戻して仮想環境を作成し、もとに戻すという方法です。
仮想環境で検索すると、pyenvが出てきて余計混乱してしまった経験と、venvで昔のバージョンのPythonの仮想環境構築をする方法が分からなかったことから、この記事を作りました。

「AnacondaのAnaconda Navigatorを使えば良いじゃないか」と思われる人が多いと思いますが、僕のanaconda環境では、jupyterを起動すると「_Contextvarsフォルダ」が無いというエラーが発生し、どれだけ調べても解決方法が出てこなかったので、今回紹介する方法(Anacondaを使わない方法)でマイナーバージョンを管理することにしました。

#### 経緯
筆者がいつも使用しているPCにインストールされたpythonは、バージョンが3.8.1であった。しかし、実務作業を始めるにあたり、バージョン3.6.6の仮想環境構築が必要になった。

`py -3 <実行したいこと>`で、python3系と
`py -2 <実行したいこと>`で、python2系のバージョン管理が出来ることは知っていた。

しかし、上記の様に、3.6や3.8といったマイナーバージョンの管理までは、(筆者が調べる限り)pyenvを使うほかなかった。

そこで、WSLを用い、pyenvでバージョン管理してみたが、Ubuntsの起動が面倒だった。また、筆者が愛用しているIDE:Pycharmでpyenvによって管理されたPythonを使うには、デーモンサーバへのssh接続確保をUbunts起動の度に行う等、やはり工程が多かった[(参考:PyCharm + WSLを導入したWindows10でのDjango開発)](https://qiita.com/Ningensei848/items/b313e440444bbdf65876)

なるべく面倒な操作無しで、かつ簡単にpythonのバージョン管理が出来ないか考えた。
# 方法
## Python3.8と3.6のダウンロード
説明は省きます。少なくとも3.8と3.6なら一緒にインストールしてしまって問題は無かったです。2回目にインストールするバージョンは、pathを通す設定がoffになっていることをキチンと確認してください。

## Python3.6でvenvする
### 1:Pathを仮想環境構築したいバージョンに変える
スタートボタン
↓
「システムの詳細設定の表示」で検索、実行
↓
環境変数(N...)
↓
上の欄（ユーザー環境変数）のPathをダブルクリック
↓
pythonのデフォルトのインストール先（筆者の場合は以下）である、
`C:\Users\{{ユーザー名}}\AppData\Local\Programs\Python\Python38\Scripts\`
と
`C:\Users\{{ユーザー名}}\AppData\Local\Programs\Python\Python38\`
がpathに入っていると思うので、この`Python38`を`Python<構築したい仮想環境のバージョン>`に変える。私の場合は、`Python36`に変えた。
↓
決定連打
### 2:venvで仮想環境構築
一応コマンドプロンプトで`Python`と入力。バージョン確認して合ってることを確認
↓
`cd <目的のPath>`で、仮想環境構築したい場所へ移動
↓

```bash:コマンドプロンプト
Python -m venv <仮想環境名>
```

で仮想環境作成
↓

```bash:コマンドプロンプト
仮想環境名/Scripts/activate
```

で仮想環境起動、確認してください

### 3:Pathを戻す
省略します。1と同じ方法でpathを編集し、自分の使いたいバージョンに戻してください。

## Pycharmを使ってる人向け
File
↓
Settings
↓
Project Interpreter
から、プロジェクトのインタープリターのパスを、構築した仮想環境のパスにすると、そのプロジェクト起動時に、自動的にその仮想環境にアクセスしてくれます。
こうしてプロジェクトごとにインタープリターを設定すれば、よりマイナーバージョン管理が楽になると思うので、Pycharmを使っている人はぜひ設定してみてください。
UbuntuのProxy設定備忘録

Ubuntuのインストール後、プロキシ環境下で使用するために設定すること一覧
（aptを除いてユーザー毎の設定となっています）

## 環境設定
まずプロキシ設定の調べ方

```sh
printenv http_proxy https_proxy
```
もし何も出なかった場合`~/.bashrc`に設定を追記するため、以下を実行

```sh
echo -e "\n## proxy setting"  >> ~/.bashrc
echo 'export http_proxy="http://proxy_server:port/"' >> ~/.bashrc
echo 'export https_proxy=$http_proxy' >> ~/.bashrc
```

## aptの設定
apt.confファイルにProxy設定を追加する
シェルにて以下を実行

```sh
sudo nano /etc/apt/apt.conf
```
これにより開いたapt.confファイルに以下を記述し、保存（保存はCtrl+O、終了はCtrl+X）

```sh:/etc/apt/apt.conf
Acquire::http::Proxy "http://proxy_server:port";
Acquire::https::Proxy "http://proxy_server:port";
```

## gitの設定
git用のProxy設定
###httpsを使う場合

```sh
git config --global http.proxy http://proxy_server:port
git config --global https.proxy http://proxy_server:port
```

###sshを使う場合
`~/.ssh/config`にて以下のような設定をする
鍵の生成等は以下などを参考に設定する
[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

```sh:~/.ssh/config
Host github
  User git
  HostName ssh.github.com
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand nc -X connect -x proxy_server:port %h %p
```

接続テスト

```sh
ssh -T github
```

## Dockerの設定
`sudo systemctl edit docker`を実行し、以下のように環境変数の設定を行う

```
[Service]
Environment = 'http_proxy=http://proxy_server:port' 'https_proxy=http://proxy_server:port'
```
次に、クライアントの設定のため、`~/.docker/config.json`ファイルで以下を記述する

```json
{
  "proxies": {
    "default": {
      "httpProxy": "http://proxy_server:port",
      "httpsProxy": "http://proxy_server:port"
    }
  }
}
```
参考: [プロキシのある環境でDockerを動かす方法](https://qiita.com/dkoide/items/ca1f4549dc426eaf3735)


## wgetの設定
~/.wgetrcファイルで以下を記述

```sh:~/.wgetrc
http_proxy=http://proxy_server:port/
https_proxy=http://proxy_server:port/
```

## add-apt-repositoryでのプロキシの適用
`sudo`にて`-E`オプションを用いることで環境変数を引き継ぐ
参考 [【Proxyの外に出れない僕達のために】Proxy 環境下で sudo add-apt-repository する方法【と、sudoとhttp_proxyのなんやかんや】](https://qiita.com/katoken-0215/items/18f9b8553f8ad4117d79#%E4%BB%96%E3%81%AE%E4%BA%BA%E3%81%AE%E8%A7%A3)
以下gitの例

```sh
sudo -E add-apt-repository ppa:git-core/ppa
```

## apt-keyでのプロキシ適用
cuda toolkit等のインストールでは`apt-key`を用いることがある
その際、ネットワークエラーが出ることがあるので、以下の様に`--keyserver-option`を追加してプロキシ設定をする必要がある

```sh
sudo apt-key adv --keyserver-option http-proxy=http://proxy_server:port
```

オプションの順序として、**--keyserver-optionがオプションの先頭に来る必要がある**ことに注意
webpack4/html-webpack-pluginでhtmlに変数値を挿入する

## TL;DR

- html-webpack-pluginを使ってdistにhtmlファイルを吐かせていた
- 設定情報はJSONに記述するようにしたのでHTMLの`<title>`を動的にしてbundleさせたくなった
- プラグイン公式にexampleがあったのでそのままやって解決

## 何をしたか

### 現状

SPAをマウントさせる静的なhtmlをHTTPサーバに置きたかったのでhtml-webpack-pluginをつかって、テンプレートのhtmlファイルを用意して、デプロイディレクトリにhtmlを出力していた。
その他の生成されるCSS/js(SPA)はhtmlにhash付きファイル名でinjectされるようになっている。

pluginの指定

```typescript
// webpack config抜粋
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
```

src/index.html

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ブログタイトル</title>
</head>
<body>
  <div id="main"></div>
</body>
</html>
```


### やりたいこと

SPAで使用する設定値周りをStatic Site generator のそれのようにJSONで持たせることにしたので、htmlの<title>をJSONファイルを参照して合成するようにしたい

### 解決策

html-webpack-pluginにexampleがあった
https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters

- templateをejsファイルにする
- templateParametersを指定するとejsと結合してくれる

とのこと


```typescript
    new HtmlWebpackPlugin({
      template: './src/index.ejs',
      templateParameters: { title: 'ここにjsonをimportしたりして変数を指定できる' },
    }),
```

src/index.html -> src/index.ejs

```php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title><%= title %></title>
</head>
<body>
  <div id="main"></div>
</body>
</html>
```

これでOK。

__ちなみに、拡張子が.ejsじゃなくて.htmlでもできんじゃね？って思ってrenameせずにやってみたけど変数挿入リテラルが文字として識別されるだけだった__


## おまけ

`templateParameters` の型定義

```ts
templateParameters?:
	false
	| ((compilation: compilation.Compilation, assets: TemplateParametersAssets, options: Options) => any)
	| { [key: string]: any };
```

サンプルには `{ [key: string]: any }` しかないっぽいけど、bundleするときのinput/outputを引数とした関数も指定できるっぽい。
Goで祝日を判定するライブラリまとめ

# はじめに
[Yahoo!ファイナンスの更新が停止　12月23日が「天皇誕生日」のまま、運営元が設定ミス](https://www.itmedia.co.jp/news/articles/1912/23/news079.html)

関係者の皆様、対応おつかれさまでした。記事を見ているだけで胃が痛いです。
祝日や営業日を扱うサービスでは誰にでも起こりうるインシデントではないでしょうか。
というわけで、Goで祝日を扱うライブラリをまとめました。

# 祝日が判定できるライブラリ
## najeira/jpholiday
https://github.com/najeira/jpholiday
2019年4月1日に天皇誕生日の修正がされていました。

## holiday-jp/holiday_jp-go
https://github.com/holiday-jp/holiday_jp-go

## kokardy/jpholiday
https://github.com/kokardy/jpholiday

## pinzolo/flagday
https://github.com/pinzolo/flagday

## yut-kt/goholiday
https://github.com/yut-kt/goholiday
【Linuxコマンド】tail -f でリアルタイムでログを見る

# tail -f

```
tail -f
```

最後の方の行を表示するtailコマンド。
tailコマンドの-fオプション、
これを使えばリアルタイムで最新のログを見ることができます。

# 実用例

## apacheのアクセスログ確認

```
tail -f /var/log/httpd/ssl_access_log | grep seeurl
```

tail -f でリアルタイムのログを取得して、
且つgrepで任意の文字が含まれるものだけ拾って表示。

## RoRプロジェクトのログ確認

```
tail -f /var/www/projects/project_name/current/log/test.log
```

```
tail -f /var/www/projects/project_name/current/log/production.log
```

RoRのlogファイルがある場所を指定すると当たり前ですが、
プロジェクトのエラーログをリアルタイムで表示できます。
割とよく使う。
EloquentのJOINで結合テーブルに論理削除を効かせる

EloquentでModelに論理削除（SoftDeletes）を設定しておくと、デフォルトで`deleted_at is null`をWHERE条件に入れてSQLを発行してくれます。

しかし、テーブル結合（JOIN）をした場合、結合したテーブルに対して論理削除の抽出条件が効きません。

```php
$users = User::join('deptments', 'users.deptment_id', '=', 'deptments.id')->get();
```

```sql
select
  * 
from
  `users` 
  inner join `deptments` 
    on `users`.`deptment_id` = `deptments`.`id` 
where
  `users`.`deleted_at` is null
```

それならとwhereを設定してみるも、これだとLEFT JOINの場合に結合しなかったusersテーブルのレコードが抽出されなくなってしまいます。

```php
$users = User::join('deptments', 'users.deptment_id', '=', 'deptments.id')
             ->where('deptments.deleted_at', null)->get();
```

```sql
select
  * 
from
  `users` 
  inner join `deptments` 
    on `users`.`deptment_id` = `deptments`.`id` 
where
  `deptments`.`deleted_at` is null 
  and `users`.`deleted_at` is null
```

第二引数にクロージャを渡すとJOIN句の中で複数の抽出条件を使えるようになります。

```php
$users = User::join('deptments', function ($join) {
            $join->on('users.deptment_id', '=', 'deptments.id')
                 ->where('deptments.deleted_at', null);
         })->get();
```

```sql
select
  * 
from
  `users` 
  inner join `deptments` 
    on `users`.`deptment_id` = `deptments`.`id` 
    and `deptments`.`deleted_at` is null 
where
  `users`.`deleted_at` is null
```

意図したSQLを発行することができました。
はじめてMySQLを使ってみた話

[MySQL Advent Calendar 2019](https://qiita.com/advent-calendar/2019/mysql)の23日目エントリです。

初めてAdvent Calendarに参加してみました。

OracleメインでSQL使ってきたひとが、
ひょんなことからMySQLを使った際の気付きをまとめました。

# MySQLを使うことになったきっかけ

知人にSQLを教えてと言われたのがきっかけです。
SQLのなかでもMySQLなのは、特別な理由はなかったみたいです。

ちなみに、そのときのわたしは、
「Oracle SQLできるなら、MySQLもなんとか大丈夫だろう」
とか思って、軽く了承してしまいました。

ただ、そんなのは間違いでした。
バージョンまわりで3つのつまづきポイントがありましたので紹介してみます。

# 前提
- MySQL5がインストールだけしてた。
- OSはWindows10
- MySQL8だと、WITH句、WINDOW関数が使える

# MySQL5では、WITH句、WINDOW関数が使えない
OracleではおなじみのWTIH句、WINDOW関数が使えないことに驚きました。

データの構成比をだすのに、累積和の出し方をWINDOW関数を使って教えられたらいいなと思ったのです。
しかし、WINDOW関数は使えないので別のロジックを探してみました。
以下のリンクの方法でできました。

[MySQL で累積和を求める方法](https://gist.github.com/utgwkk/25703647ad9001b34f68e6c4dee84e47)

ただ、リンク先のページの最後のほうに以下のようなことが書いてあり笑ってしまうとともに、
WITH句、WINDOW関数が使えるMySQL8を使う方針に切り替えました。

>同じことをPostgreSQLでする場合
>もっと簡単に取得できる
> https://www.postgresql.jp/document/9.6/html/tutorial-window.html
>PostgreSQLを使いましょう

# オンライン実行環境は、MySQL5の環境しかみつからない

そこで、MySQLの環境を自分のPC上に作る前に、オンラインで公開されている
MySQLの環境から本当にWITH句やWINDOW関数が使えるか確認したくなりました。

結論から言うと、WITH句もWINDOW関数は使えませんでした。
私が探した限り、MySQL５の環境しかなかったからです。
よくばりすぎました。

ちなみに、確認してみたサイトは以下の通りです。
WITH句やWINDOW関数を使うとか欲張らなければとても便利です。

- [dokoQL](https://dokoql.com/)
- [paiza.io](https://paiza.io/projects/DWXTioc9KWczHHKNnyEBNQ?locale=ja-jp)
- [SQL Fiddle](http://sqlfiddle.com/) 

個人的には、SQL Fiddleが使いやすいように感じました。
サンプルコードが充実しており、実行結果の表示が見やすいなと思います。

# MySQL8インストールしたら、MySQL5の残骸があったのかDB接続できない
MySQLに限らずな気がしますが、これも困りました。
今までインストールしていたMySQL5を「アプリケーションの追加と削除」で
アンインストール後に、MySQL8をインストールしました。
しかし、その後にテスト接続をしてみるもののエラーになってしまいました。

安易に「アプリケーションの追加と削除」でアンインストールしただけなのが原因だったようです。
以下の手順でやり直したらうまくいきました。

[MySQL 5.7 for Windowsのアンインストール方法](https://programmingnavi.com/1468/)

# おわりに
以上、MySQLバージョンまわりのつまづきポイント3つでした。
安請け合いはしてはいけませんね。

MySQLを始めたばかりなので考慮漏れ等あるかもしれません。
変更したほうがよさそうな場所があれば教えてくれると嬉しいです。

つぎの24日目は、[@knktknk](https://qiita.com/knktknk)さんです。
Prisma2で環境変数に応じてデータソースを切り替える

**12/23時点での内容です。Prisma2はアクティブに開発されているのでここの内容はすぐに古くなる可能性があります**
**2020/3/10: :warning: 現時点の最新版ではenabledオプションが削除されており下記の方法は使えません！[issue](https://github.com/prisma/prisma2/issues/1512)が立てられておりhigh priorityとのことなのでそう遠くないうちに実装されるのではないでしょうか**

Prisma2でデータソースを環境変数に応じて切り替える方法は[公式ドキュメント](https://github.com/prisma/prisma2/blob/master/docs/prisma-schema-file.md#switching-data-sources-based-on-environments)にかかれている。

以下のようにschemaファイルを書くことで、ローカルで開発するときはsqliteで、productionはmysqlをデータソースとして使うようにすることができる。

```prisma.schema
datasource development {
  provider = "sqlite"
  url      = env("DEVELOPMENT_DB_URL")
  enabled  = env("DEVELOPMENT_DB_URL")
}

datasource production {
  provider = "mysql"
  url      = env("PRODUCTION_DB_URL")
  enabled  = env("PRODUCTION_DB_URL")
}
```

この状態で`npx prisma2 generate`をしてクエリエンジンを生成しようとすると環境変数が定義されていないと怒られる。

```console
$ npx prisma2 generate
Error: Schema parsing
error: Environment variable not found: DEVELOPMENT_DB_URL.
  -->  schema.prisma:3
   |
 2 |   provider = "sqlite"
 3 |   url      = env("DEVELOPMENT_DB_URL")
   |
error: Environment variable not found: PRODUCTION_DB_URL.
  -->  schema.prisma:9
   |
 8 |   provider = "mysql"
 9 |   url      = env("PRODUCTION_DB_URL")
```

現状だとprisma2 generateする際も、環境変数を空でもいいので全て定義してあげる必要があるみたい。
以下のような形にするとうまく行く。

```bash:.envrc
export DEVELOPMENT_DB_URL="file:dev.db"
export PRODUCTION_DB_URL=
```


そもそもPhotonエンジンを生成するときに環境変数知ってる必要はないよねみたいな話は[issueで議論](https://github.com/prisma/specs/issues/364)されているが、
現状は空でもいいので指定する必要がある。
generate時にも必要なのはschemaファイルをパースするのに必要だからだそう。

実行時に必要な方だけ環境変数で与えてあげればデータソースを切り替えることができる。
このとき、**使わないデータソースの方の環境変数は定義する必要はない。**
開発環境を整える

# 開発環境のインストール
基本的には前項（https://qiita.com/NayutaOno/items/b2589dffd60a684f4484 ）で紹介した書籍について従ってやりました。
基本動作は本にもネットにもゴロゴロしているので、自分が少しでもつまずいた部分をPick up

## Flutter
悲しいかな、いきなりPATHの設定でつまずいて調べました。ターミナルの設定がzshに変わっているので、そこで何度か苦戦。
しかし、以下のページで一発解決。（こんなんでつまずいてて大丈夫なのか）
https://qiita.com/akatsukaha/items/3b8a5a6d94a3cdb1e047

## Android Studio
基本的には問題なく準備完了。
Windowsでも一回準備したので慣れていた。
しかし、エミュレータを準備する時、
`flutter emulator`
で実行できないのは何の呪いなのか、、、調べます。
いっつもAVD Manager でやっちゃいます。

## Xcode
こちらに関しては本当に困ることなかったので割愛

## 確認
最後にFlutter doctorをして確認。これがあるから初心者にも安心

```terminal
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57,
    locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.3)
[✓] Android Studio (version 3.5)
[✓] VS Code (version 1.41.1)
[✓] Connected device (1 available)

• No issues found!
```

# その他開発周りの準備
使ったことのある物を片っ端から使えるように。
半分脳死だけどとりあえず準備しておく。

## jira
https://www.atlassian.com/ja/software/jira/pricing
カンバンボード形式のタスク管理ツール。
仕事で使ってみて最高に便利だったので導入。
自分がやることを可視化して、スケジュール管理とかに役立てたい。
10人までなら無料なのも魅力。

## Gitlab
https://gitlab.com/
そもそもGitをあまり使ってこなかったので、使って慣れたい。（一人での開発だけど）
自分の分身アカウントを２つ作って、それにMRをあげる運用をしようかな。
最終的にはCIを使うためにも必要なので

## Slack
https://slack.com/intl/ja-jp/
本当はMattermostを使いたかったんだけど、無料がなさそうなのでこちらで代用。
GitlabCIの結果をこれで通知できるのが最高なんだけど、、、一応構想だけはあります（先輩の受け売り）
もし、複数人で開発するようになったらちゃんと使おう。

# 次の動き
無事に開発環境が整ったので、次回からは実際にコーディングをしていこうと思う。
内容としては、上述した参考書をそのまま写経する形で一旦回していこうと思う。
もし、途中でUTを入れれそうな項目やセクションがあったらその時に入れてみよう。
プロンプトをカスタマイズしてターミナルを楽しく使おう💻

この記事は、[サイバーウェーブ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/cyberwave) の23日目の記事です。

最近、ちょっと気分を変えたいと思いターミナルのプロンプトを更新したので、その時にやったことを小ネタとしてまとめます。
僕の現在のターミナルはこんな感じになっています。
<img width="619" alt="スクリーンショット 2019-11-22 21.21.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174052/c7dadb3e-44b8-4d97-3132-fa9ce69959dc.png">
今このプロンプトを使っていて、

* 2行プロンプトかつ、出力の後に1行空く
* 普通は`$`となる部分がスタイリッシュ
* 自分が今いるディレクトリや入力したコマンドによって絵文字表示が変わる

なところが気に入っています。
それぞれについて、どのように設定ファイルを書くか解説していきます。
使用しているシェルは`zsh`です。

また、今回解説するスクリプトは全て [dotfiles/.zshrc at master · guri3/dotfiles](https://github.com/guri3/dotfiles/blob/master/.zshrc) にあります。

まず、2行プロンプトについてです。

```sh:.zshrc
PROMPT='$(emoji) %~ ${vcs_info_msg_0_}
%{%F{202}%}❯%{%f%}%{%F{221}%}❯%{%f%}%{%F{027}%}❯%{%f%} '
```

プロンプトの定義はこのようになっています。
実は、プロンプトの途中で改行すれば簡単に２行プロンプトにすることができます。

また、出力後の改行については、`add_line`という関数を定義し、`precmd`で呼び出すことで実現しています。

```sh:.zshrc
function add_line {
  if [[ -z $PS1_NEWLINE_LOGIN ]]; then
    PS1_NEWLINE_LOGIN=true
  else
    printf '\n'
  fi
}

precmd() { add_line }
```

`add_line`関数の中では、`PS1_NEWLINE_LOGIN`環境変数に中身が存在しなければ`PS_NEW_LINE_LOGIN`環境変数にtrueを代入し、そうでなければ改行コードを出力しています。これを`precmd`で呼び出すことでプロンプトを表示する直前に毎回実行されるため、出力の後に改行をうまく挟むことができます。(ググればこの書き方がたくさん出てくるので、慣習みたいなものなのかも？)

次に、`$`部分の変更についてです。
実際のコードではプロンプト2行目の部分です。

```sh:.zshrc
%{%F{202}%}❯%{%f%}%{%F{221}%}❯%{%f%}%{%F{027}%}❯%{%f%} '
```

ポイントは`%F{}`と`%f`で、`%F{}`で色を指定し`%f`で色をリセットします。
この時に指定する色は、[dotfiles/colcheck.sh at master · guri3/dotfiles](https://github.com/guri3/dotfiles/blob/master/scripts/colcheck.sh) などを使って調べることができます。(このスクリプト拾い物のはずなのですが、出典がわかりませんでした...すみません)
また、全てを`%{%}`で囲っているのは、こうしないとなぜかプロンプトがずれてしまう現象が起きるからです。スマートな解決方法を知っていたら教えてください。

最後に、絵文字部分についてです。
これも、関数を実装して呼び出しています。

```sh:.zshrc
function emoji {
  if [[ $? != 0 ]]; then
    echo -n '\U1F914'
  elif [[ $(pwd) = $HOME ]]; then
    echo -n '\U1F3E0'
  elif [[ $(pwd) =~ "$HOME/projects" ]]; then
    echo -n '\U1F4BB'
  elif [[ $(pwd) =~ "$HOME/dotfiles" ]]; then
    echo -n '\U1F527'
  else
    echo -n '\U1F4C2'
  fi
}
```

プロンプトの１行目部分で呼び出しています。

```
PROMPT='$(emoji) %~ ${vcs_info_msg_0_}
```

僕はカレントディレクトリの状況に応じて

* home🏠
* projects💻(コード管理用ディレクトリ)
* dotfiles🔧
* それ以外📂

にそれぞれ絵文字を登録しているのと、
何か間違ったコマンドを入力した際に🤔が表示されるようになっています。

今回紹介するものは以上になります。
ぜひいつも使うターミナル環境を自分好みにカスタマイズしてみてはいかがでしょうか？
10. 行数のカウント

## 10. 行数のカウント
行数をカウントせよ．確認にはwcコマンドを用いよ．

###Go
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	//	読み込みファイルを指定
	name := "../hightemp.txt"
	line := 0

	//	読み込むファイルを開く
	f, err := os.Open(name)
	if err != nil {
		fmt.Printf("os.Open: %#v\n",err)
		return
	}
	defer f.Close() //	終了時にクリーズ

	//	スキャナライブラリを作成
	scanner := bufio.NewScanner(f)

	//	データを１行読み込み
	for scanner.Scan() {
		line++;
	}

	//	エラーが有ったかチェック
	if err = scanner.Err(); err != nil {
		fmt.Printf("scanner.Err: %#v\n",err)
		return
	}

	//	行数を表示
	fmt.Println("Line",line)
}
```


###python
```python
import sys

line = 0

# ファイルを開く
with open("../hightemp.txt", "r") as f:
    # 一行ずつ読み込む
    for data in f:
        # 行数を加算
        line += 1

# 行数を表示
print("Line",line)
```


###Javascript
```Javascript
// モジュールの読み込み
var fs = require("fs");
var readline = require("readline");

var line = 0;

//  ストリームを作成
var stream = fs.createReadStream("../hightemp.txt", "utf8");

//  readlineにStreamを渡す
var reader = readline.createInterface({ input: stream });

//  行読み込みコールバック
reader.on("line", (data) => {
    line = line + 1
});

//  クローズコールバック
reader.on("close", function () {
    console.log("Line",line);
});
```

## まとめ

やっと 「第2章: UNIXコマンドの基礎」 へ突入！！。

２章に入ったとのことで、Pythonのバージョン設定をやっと 3.7 へ変更しました。
IDEの設定だけですけど・・・。設定がどこにあるか探すのが・・・。と言い訳。

ファイルの読み込みをそれぞれの言語調べながら。
Go,Python はそれほど困らなかったが、
Javascirpt は。おぉおぉ。なんか面白い。非同期との事もあり考え方は注意が必要か。

## 補足
Go 言語で変数名を fname としていたが、IDE(Golang) が typo? と言ってくる。
有り難いのかなぁ。とりあえず name へ変更し回避。

[トップ](https://qiita.com/naoshin1984/items/3d7814e2f8eb01eea8dd)
Yahoo! Hack Day 2019 で感じた、ハッカソン前に準備しておいたら開発しやすくなったもの

# はじめに

初めて [Yahoo! Hack Day 2019](https://hackday.jp/) に参加してきました。

流石に24時間ぶっ続けでの開発はしんどかったけど、
あのわくわくさんから[wakuwaku賞（審査員特別賞）](https://about.yahoo.co.jp/pr/release/2019/12/16b/)をいただけて、いい思い出になりました。

## Hack Day 2019 で作ったもの

### MOGbee

スマホ依存症の現代人からスマホを引き剥がし、家族団欒の邪魔を通知するかわいい充電器、**MOGbee** を作りました。

<img width="353" alt="File (1).jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275279/d1e9e16c-a951-471e-7ded-be567ecfd2dc.jpeg">

90秒プレゼンの動画は[こちら](https://youtu.be/HNjXZwRTybU?t=11594) 

### MOGbeeの構成図

MOGbeeは、スマホがwifiを介してラズパイにつながることで、LEDやサーボモータが動作する仕組みになっています。

![mogbee_constract.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275279/efa51d66-932b-b7f3-243f-cde600fd9ce0.png)

この記事は、ハッカソンでラズパイ工作をしようと思っている方（と未来の僕）に向けて、ハッカソンに行く前に準備して良かったことと、今後準備したほうがいいものについてまとめました。


# ⭐ 準備しておいて良かったと思ったもの

## タコ足コンセント

ラズパイ工作には電気が必要。一人でも **6台** （Mac, ラズパイ, スマホ×２, wifi, ディスプレイ）の電源が必要だったので、多いに越したことはなさそう。
今回はタコ足コンセントに加えて最近買ったUSB電源分配器も持っていったので、盤石だった。

![](https://images-na.ssl-images-amazon.com/images/I/71pQQxtK%2ByL._SL1500_.jpg)

## wifiルータ

ハッカソンではwifiが用意されている場合が多いが、参加者が多いと繋がりにくいし、最悪自分の端末が複数のネットワークに別れてしまいうことも・・・

特にラズパイを使う人にとっては ssh で繋げないことは死活問題になってしまうため、確実につながるルータがあることは通信的にも精神的にも非常に安心できた。

最近契約した [どんなときもwifi](https://donnatokimo-wifi.jp) が思わぬところで活躍してくれました。（ステマじゃないよ）

# ☔ 準備しておけば良かったと反省したもの

## PCからラズパイへのリモートデバッグ環境

GPIOを使ってLEDを光らせるのはラズパイ上で動かさないとできない。しかし、開発はいつものなれたPCでIDE使いながらやったほうが圧倒的に効率が良い。
今回は、PCで開発→GitHubにpush→ラズパイの前まで移動→ラズパイでpullコマンドを打つ、という無駄極まりない方法で開発してしまった・・・

ってことで、visual studio code の[remote Development](https://code.visualstudio.com/docs/remote/remote-overview)の設定をしとけばよかったと反省。（愛用しているpycharmにはお布施してないので、remote developできない orz）
もしくは、sshがつながらないことを考えて、ラズパイが自動的にpullしてくれるツールを作っときたいな、と思った。年末暇なら、オープンソースを作ろうかな〜？

### [2020/01/18追記]

ラズパイ向けCDツールってのを作りました！
~~（年末年始に作ったのに記事書いたのが1/18ってさぼりすぎ）~~
https://qiita.com/tiwasa/items/bba672f65d1ded116dbe

## 定期的なラズパイのimgバックアップ

２４時間の開発時間は長く疲労が貯まるものだった。そんな中、残り４時間でラズパイの中身をぶっ壊すと、チームメイトが頑張ってきた時間と、返上した睡眠時間がすべて水の泡になります。どのタイミングでバックアップと取るかは、予め計画を立てといたほうが良いと思いました。

サーバを自動起動させたいと思って、開発終了直前に /etc/rc.local にコマンド書いて再起動したときのヒヤヒヤ感は精神安定上よろしくなかった。

# さいごに

Hack Dayに参加できて、すごく良かった！
70組以上の参加者がいたにもかかわらず、アイディアがかぶらない独創的なハッカー達が作り上げる発表を聞いているだけで、楽しくなれました。

特に、Happy Hacking賞をとった「ポピポポピピプピリロピロリププププピーポ」さんのプレゼンはめっちゃ笑えて印象に残りました。僕も理系ギャグを入れたプレゼンをいつかやってみたいです。
「とりそば弁当」さんのブースに伺った時には、人の顔にジャガイモが追従する精度へのこだわりを全力で語っていただきました。最高にハッカソンやってるなーって感じて、嬉しくなりました。

また来年も参加したいな！！
MATLAB の環境設定ファイルにグラフ設定を書いておく

## はじめに - なぜ設定ファイルを作成するのか
グラフ作成時に，「同じようなコードを書いている/コピー＆ペーストしている」ということがたびたび起こります．毎回同じグラフを書くわけではないので「別にコード書けばええやん」と思われるかもしれません．

でもきれいなグラフを描きたい．
ドキュメントや色んな人の記事を調べつつ．．．
だんだん凝りだして．．．
気づいたら．．．
ということがよくあります．

グラフに限らず，「素早くある程度の質の出力を得る」テンプレートに当てはめた結果を最初に得て，そこから微調節をして改善して進めていく流れを作れると分析もシミュレーションもスムーズに進めるなと思っています．
（今回はグラフだけなのでそれほど大した話ではないのですが，塵も積もればということで）

## こんなグラフがでてきてしまう
グラフを描きました．
<img width="265" alt="original.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/b1b35189-9689-07b7-6c41-0783214dd12f.png">

文字ちっちゃいね．
色もなんだかよくわからない．
グラフをきれいに出力する関数を誰かが作ったらしいけど，どこにあるんだっけ．．．？
（[ここですね: MATLABでLaTeX論文用の図を整形する](https://qiita.com/larking95/items/7ed862f743a3e661e6da#%E5%85%B1%E9%80%9A%E3%81%AE%E7%B7%A8%E9%9B%86)）

## 好みなグラフが表示されるようにしたい
きれいなグラフといえば，R の [ggplot2](https://ggplot2.tidyverse.org/) や Python の [seaborn](https://seaborn.pydata.org/) でしょうか．
グレーの背景は色が映えますね．
文字を大きくしつつ，まずはグラフを描いてみましょう．


```matlab
fig = figure;
h = plot(rand(5,5), 'o', 'MarkerSize', 10);
title('たいとる')
xlabel('x軸のらべる')
ylabel('y軸のらべる')

grid on

# 軸のオブジェクトを取得
ax = fig.Children;

# 軸のプロパティを設定
ax.GridColor = [0 0 0];
ax.Color = [.9 .9 .9];
ax.Title.FontSize = 16;
ax.XLabel.FontSize = 16;
ax.YLabel.FontSize = 16;
ax.FontSize = 16;

# 軸の下にある線のオブジェクトのプロパティ LineWidth を設定
ax.Children(1).LineWidth = 2;
ax.Children(2).LineWidth = 2;
ax.Children(3).LineWidth = 2;
ax.Children(4).LineWidth = 2;
ax.Children(5).LineWidth = 2;
```

この汚いコードで，こんなグラフが出力されます．
<img width="291" alt="revised.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/0621d7d2-dada-4b53-40df-2ad427fe8cc5.png">
先程から文字サイズなどは改善されていますが，線の太さ LineWidth のところなんて，Children が100個あったら書くだけで大変です．

#### 補足
グラフは[グラフィックスオブジェクトのページ](https://jp.mathworks.com/help/matlab/graphics-objects.html)にあるように階層的なオブジェクトで構成されています．以下の2点がグラフ描画に大きく関わる点です．
- Figure の下に Axes (軸)，Axes の下にグラフ内の線や点の情報が含まれている
- Figure, Axes のプロパティを変更することでグラフを変更できる

## デフォルト値を設定しよう
毎回プロパティを設定するのは面倒なので，グラフのデフォルト値を設定しておきます．
デフォルト値は MATLAB 起動時に実行される startup.m ファイルに書いておきます．
startup.m が存在するかどうかは

```matlab
which -all startup.m
```
で確認できます．なければ適当に作ってパスを通しておきましょう．
パスは Home タブの Environment 内にある **パスの設定/Set Path** で startup.m ファイルのあるフォルダを追加すればが設定できます．
<img width="282" alt="Screen Shot 2019-12-23 at 23.31.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/a6025065-3b10-9335-9f8b-0dd6001306b2.png">

startup.m ファイルはこんな感じ．

```matlab
% グリッドの設定
set(0, 'DefaultAxesXGrid', 'on');
set(0, 'DefaultAxesYGrid', 'on');
set(0, 'DefaultAxesZGrid', 'on');

% グラフの軸 (axes) の背景
set(0, 'DefaultAxesColor', [.9 .9 .9]);

% テキスト類のフォントサイズ
set(0, 'DefaultAxesFontSize', 16);
set(0, 'DefaultTextFontSize', 16);

% 線の太さとマーカーサイズ
set(0, 'DefaultLineLineWidth', 2);
set(0, 'DefaultLineMarkerSize', 10);
```
スタートアップファイルを保存したあと，再起動もお忘れなく．（起動時に実行されるファイルであるため）

デフォルト値を定義しておくことで，グラフ調節に手こずることが減るので，だいぶ時間を短縮できています．
他の言語でも設定ファイル書いておきたいな．
GitHub ActionsでmasterにpushしたときにPHP-CS-Fixerを動かしてcommit&pushする

GitHubのmasterにpushしたらPHP-CS-Fixer動けば楽だなぁと思い、GitHub Actionsで実装
やり方は色々ありそうだが、自分がやったのは

```
composer require --dev friendsofphp/php-cs-fixer
```
でcomposerでインストールされるようにする

```yaml:.github/php-cs-fixer.yml
name: PHP-CS-Fixer

on:
  push:
    branches:
      - master

jobs:
  php-cs-fixer:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@master
    # ↓これはcomposer installの際にextensionが必要なときにのみ必要な部分
    - name: Installing PHP Extension
      uses: shivammathur/setup-php@master
      with:
        php-version: 7.4
        extension-csv: gd, xdebug
    - name: Install Dependencies
      run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
    - name: Execute PHP-CS-Fixer
      run: vendor/bin/php-cs-fixer fix .
    - name: Commit files
      uses: stefanzweifel/git-auto-commit-action@v4
      with:
        commit_message: "PHP-CS-Fixerによる修正:${{github.sha}}"
    - name: GitHub Push
      uses: ad-m/github-push-action@master
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
```
ad-m/github-push-actionは得体のしれなさもあるけど、GitHubActionsの中で星がたくさんついてたから大丈夫でしょうという感じ
master以外にプッシュするとかもad-m/github-push-actionの説明を見るとできる。PRに対して行う場合などは変える必要がある。
https://github.com/ad-m/github-push-action
secrets.GITHUB_TOKENは勝手に入ります

PHP-CS-Fixerによる変更ファイルが無いと失敗するとか、色々課題があったので修正しています。
`stefanzweifel/git-auto-commit-action` を使うと変更がなくてもエラーにはならないはずです

### 追記

.gitignoreに

```text:.gitignore
.php_cs.cache
```
を追加する
JavaScript の日付処理は luxon が便利

# はじめに
JavaScript で日付処理といえば [moment.js](https://momentjs.com/) が有名かと思います。
そんな中、私の関わるプロジェクトでは使用するライブラリを、 moment.js -> [date-fns](https://date-fns.org/) -> [luxon](https://moment.github.io/luxon/) と変更してきました。
そして今現在は luxon を使っています。

luxon は使っていて便利だな、と感じるライブラリです。
ここでは、これまで使用した処理の中で、私が便利だと思った機能をいくつか紹介します。
（基本的なものは割愛します。下記の参考リンクにもまとめられています。）

# 実際に使っている処理

#### DateTime 型を作成

これは基本的なものですが、これがないと始まらないので記載しておきました。

```javascript
import { DateTime } from 'luxon';

// ISO format
DateTime.fromISO('2019-12-23T12:00:00.000000');
// JavaScript Date format
DateTime.fromJSDate(new Date());
// SQL format
DateTime.fromSQL('2017-05-15 09:12:34');
```

#### 表示用に出力

`toLocalString` が個人的に好きです。
ローカライズにも対応しているのがありがたい。

```javascript
const dateTime = DateTime.fromISO( ... );

// ISO 形式で出力
dateTime.toISO();
// 指定したフォーマット形式で出力
dateTime.toFormat('h:mma, dd-MM-yyyy');
// 定められたフォーマットで出力（ローカライズ対応）
dateTime.toLocaleString({ ...DateTime.DATE_MED });
/*
 * DATETIME_FULL
 * DATETIME_FULL_WITH_SECONDS
 * DATETIME_HUGE
 * DATETIME_HUGE_WITH_SECONDS
 * DATETIME_MED
 * DATETIME_MED_WITH_SECONDS
 * DATETIME_SHORT
 * DATETIME_SHORT_WITH_SECONDS
 * DATE_FULL
 * DATE_HUGE
 * DATE_MED
 * DATE_SHORT
 * TIME_24_SIMPLE
 * TIME_24_WITH_LONG_OFFSET
 * TIME_24_WITH_SECONDS
 * TIME_24_WITH_SHORT_OFFSET
 * TIME_SIMPLE
 * TIME_WITH_LONG_OFFSET
 * TIME_WITH_SECONDS
 * TIME_WITH_SHORT_OFFSET
 */

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
dateTime.toLocaleString({ year: 'numeric', month: 'short', day: 'numeric' }),
```

#### ○○分以内に発生したイベントの判断

現在時刻との比較はよく使うので `diffNow` は便利ですね。

```javascript
if (DateTime.fromISO(...).diffNow('minutes').minutes >= -3) { ... }
if (DateTime.fromISO(...).diff(..., 'minutes').minutes >= 60) { ... }

// DateTime.fromISO(...).diffNow().minutes とした場合、返り値が 0 になりました。
// これは DateTime オブジェクトは millisecond がデフォルトのためです。
// 単位を分にする場合は diffNow('minutes') と記載する必要があります。
```

#### 祝日の判断

営業日判断などで利用します。

```javascript
holidays.find((holiday) => {
  return holiday.hasSame(DateTime.local(), 'day');
} !== undefined
```

#### ○○年後の開始月/日を取得

`startOf` と `endOf` は非常に便利だと思います。
応用すれば、今月の初日や、現在時刻から00分や00秒の取得、といったこともできます。 

```javascript
// 15年後の同月一日を取得（現在が2019年12月なら2034/12/1）
DateTime.utc().plus({ years: 15 }).startOf('month');
// 15年後の開始日を取得（現在が2019年12月なら2034/1/1）
DateTime.utc().plus({ years: 15 }).startOf('year');
```

# ハマったところ
#### `diff`/`diffNow`

フォーマットを指定しないと、milliseconds 以外の値が返ってこない、という状況で最初ハマりました。
差分を取得しているつもりなのに、if文が正しく動いてくれません。
分で評価したい場合は、`diffNow('minutes').minutes` とする必要があります。

#### ユニットテスト
我々のプロジェクトでは、サーバサイドでも日付時刻計算に luxon を使っています。
ローカルでテストコードを実行してユニットテスト成功していたものが、CI/CD環境ではエラーとなるケースに直面しました。
どの環境でも同じように動くように実装する必要性を強く感じました。

# 参考
[逆引きLuxon集　〜moment.jsから乗り換えるために〜](https://qiita.com/bobu_web/items/2cecc3fdb7d2b0942ef1)
developやmasterへの直commitを禁止する

たまにブランチを切り忘れて、developブランチにcommitしてしまうことがあります。
gitのhooksを利用して、指定のブランチへのcommitを禁止することができます。

```
$ cd <リポジトリパス>
$ mkdir .githooks
$ cp .git/hooks/pre-commit.sample .githooks/pre-commit
$ git config core.hooksPath .githooks
$ chmod +x .githooks/pre-commit
```

`.git/hooks`内のファイルを利用することもできますが、チームで開発している場合は設定を共有するため、リポジトリへ含められるようにフォルダを作成します。
`.git/hooks/pre-commit.sample`がない場合もありますので、その場合は、`.githooks/pre-commit`ファイルを新規作成してください。
`.githooks/pre-commit`を編集します。

```
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

##### ↓↓↓↓追加↓↓↓↓ #####
if test "`git symbolic-ref HEAD | sed -e 's:^refs/heads/::'`" = master; then
	echo "<masterへコミットできない文言>"
	exit 1
fi

if test "`git symbolic-ref HEAD | sed -e 's:^refs/heads/::'`" = develop; then
	echo "<developへコミットできない文言>"
	exit 1
fi
##### ↑↑↑↑追加↑↑↑↑ #####

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --
```

以上で、developやmasterへcommitしたときに警告が表示され、commitできないようになります。