OmniAICreator/Qiita-1.07M huggingface dataset:
nginxとphp-fpmを使ってLaravelのhome画面を表示する


# 前書き
初めての投稿ですので、わかりにくい箇所があるかもしれません。改善案などございましたら、教えてください。

##nginxとphpのインストール
自分はMacを使っているので、今回はHomebrewを利用してインストールしていきます。

[Homebrew](https://brew.sh/index_ja)

```
brew install php＠(バージョンは各自指定してください)
brew install nginx
```
php-fpmはbrewでphpをインストールすると同時にインストールされます。

##インストールできたか確認
```
php -v
nginx -v
```

#nginxとはなにか
nginxとはフリーでオープンなウェブサーバーで、主に静的なコンテンツを高速に配信するように設計されている

#php-fpmとは
php-fpmとは、phpのFastCGI 実装のひとつで、主に高負荷のサイトで用意されている機能です。
そもそも、CGIとはwebサーバーで、PHPなどのプログラムを動かすための仕組みです。


#なぜnginxを使う時にphp-fpmが必要か？
上記にも書いた通り、nginxは静的ファイル(html/css/js)処理できません。なのでphp-fpmを利用します。


#nginxを起動する
```
nginx (起動)
nginx -s stop (停止)
nginx -s reload (再読み込み)
```
https://localhost:8080
にアクセスしてみて




こんな画面がでたら成功です。
![Welcome-to-nginx-Mozilla-Firefox_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527269/8bc2e78c-d7cc-3c5f-200e-6e7a3eef9645.png)


#nginxの設定
nginxの編集は基本的にnginx.confに記述していきます。
nginx.confはどこにあるのか、/usr/local/etc/nginxにあリます。
nginx.confを開いて

```
location / {
            root   html;
            index  index.html index.htm;
        }



 #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
```

主にlocationというところを編集していきます。
自分の場合はDesktopに新たにindexディレクトリを作成し、その中にindex.phpを作成し、それを表示させました。

```
nginx -t
```
このコマンドで、編集したnginx.confのシンタックスチェックしてみてください。
nginx.confの中身を編集した場合は、必ずnginxを再起動してください。



```
location / {
            root   /Users/username/Desktop/index/;
            index  index.php index.html index.htm;
        }

location ~ \.php$ {
           root          /Users/username/Desktop/index/;
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME /Users/username/Desktop/index/index.php$fastcgi_script_name;
           include        fastcgi_params;
        }

```

こんな感じで編集しました。
困ったことはnginxとDesktopの管理者権限が異なり、中々表示できませんでした。

```
$chown 
```
このコマンドでnginxのerror.logとaccess.logの実行者を変更しました。


#php-fpmの編集
```
＄brew info php@(自分のバージョン)
```
これで、brewでインストールした、phpの情報が分かります。
php-fpmの編集ファイルはwww.confなので、その中身を

```
user = nginx
group = nginx
```

このように編集しました。

```
＄brew services start php
```

このコマンドも忘れずに実行してください。

ちなみにDesktopのindexディレクトリのindex.phpの中身は

```
<?php phpinfo(); ?>
```

としておきました。


こんな画面が表示されたら成功です。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527269/fbd31a7e-241f-0977-9c70-9461f175b328.png)



#Laravelを表示するには
nginx.confのrootを編集するだけです。
Laravelの処理の起点となるのは、publicディレクトリです。
Laravelで扱うWebページのルート部分はpublic/ディレクトリになります。このことを理解していれば簡単です。

```
root          /Users/username/Desktop/projectname/public/;
```


あとは
https://localhost:8080

![download-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527269/d7c8efcb-fc66-81c0-5d33-4f3e8f4165b6.png)

この画面が出れば完了です。
undefined は void 型の値である

`undefined` は `void` 型の値である。

```ts
function myFunction<T>(t: T): void { } 
```

という関数があるとき、

```ts
myFunction<void>(undefined);
```

とできる。

また、次のように `void` 型の返値として `undefined` を指定できる。

```ts
const myVariable: () => void
    = () => undefined;
```
テーブルのクリップボードをマークダウンにするコマンドを作った

# 概要
Webやスプレッドシートなどのテーブルをクリップボードにコピーして、[Backlog](https://backlog.com/ja/)などのマークダウンに記録したい時、地味に面倒だったのでコマンドを作った話です。

[PyPI](https://pypi.org/project/clipable/)にも上げています。
こちらは[ソースコード](https://github.com/yujikawa/clipable)です。

下記のようなものです。
![clipable](https://user-images.githubusercontent.com/14313351/76307902-0baf8b80-630d-11ea-9d01-337d8da9b448.gif)


# インストール方法

```python
pip install clipable
```

# ツールの概要
こちら何も難しいことはしておらず、下記の2つのライブラリがあれば誰でも瞬殺で作れるやつです。

- pandas（クリップボードからテーブルを作成し、マークダウン出力するため）
- pyperclip（クリップボードにコピーするため）

# poetryが凄かった
今回依存関係の管理に[poetry](https://python-poetry.org/)を使いました。

```
poetry new パッケージ名
```
で新しいプロジェクトを作成し

```
poetry add パッケージ名
```
で依存するパッケージを追加します。

新規作成したパッケージ名と同名のフォルダの下にcli.pyというファイルを作ります。
そこにmain関数を作成します。そしてその後にtomlでコマンドを実行できるようにscriptの設定を追加します。

```toml:pyproject.toml
[tool.poetry.scripts]
clipable = "clipable.cli:main"
```

基本的に重要なのはこれぐらいでした。

あとは

```
poetry build
```
でビルドして

```
poetry publish
```

とするとPyPIに登録できます。

# 感想
Poetryを使うとパッケージの公開までが簡単すぎて感動した。

# 参考
- [Poetryを使ったPythonパッケージ開発からPyPI公開まで](http://kk6.hateblo.jp/entry/2018/12/20/124151)
Homebrewでコーディングに適したフォント「Source Han Code JP」をインストールする

表題の通り、下記ページを参考にSource Han Code JP（源ノ角ゴシック JP）をインストールしようとした。
https://qiita.com/okzk/items/ee8145ef3b56d5b31851
指示通り`brew tap caskroom/fonts`したら、「Error: caskroom/fonts was moved. Tap homebrew/cask-fonts instead.」と言われてしまった。

そこで`brew tap homebrew/cask-fonts`としたら問題なくOK
続いて*`brew cask install font-source-han-code-jp`でフォントのインストール完了。

最後にターミナルでフォント設定する際にSource Han Code JPを探して全てのフォント→Sのあたりを探しても全然出てこくて「？？？」となっていたけど、日本語→源ノ角ゴシック JPの部分にあったので、地味に注意。
（こんなのでミスるのは自分だけか・・・）

#参考サイト
- https://qiita.com/ucan-lab/items/c1a12c20c878d6fb1e21
- https://qiita.com/okzk/items/ee8145ef3b56d5b31851
docker-composeのコマンドをよく使う順にまとめる

##めっちゃ使う
###コンテナの起動
```terminal
$ docker-compose up -d
```

###コンテナの停止
```
$ docker-compose stop
```

###コンテナ内でコマンドを実行
```zsh:terminal
# コンテナが起動している場合
$ docker-compose exec {サービス名} {コマンド}
$ docker-compose exec web rails db:migrate
$ docker-compose exec web /bin/bash

# 起動していない場合
$ docker-compose run  {サービス名} {コマンド}
```

##けっこう使う
###削除
コンテナ・ネットワークを停止して削除します。ボリュームを設定していないとDBとか全部消える。

```terminal
$ docker-compose down
$ docker-compose down --rmi all #イメージも全部消す
$ docker-compose down --volumes #ボリュームも消す
```

###ビルド
Dockerイメージからコンテナを作ります。Dockerfileを編集した後とかにやる。

```terminal
$ docker-compose build
```

###再起動
たぶん`stop`→`start`と同じ

```terminal
$ docker-compose restart
```

###ログの確認
```terminal
$ docker-compose logs
$ docker-compose logs -ft #ログをリアルタイムで垂れ流す
```

##たまに使う
###コンテナの一覧を表示
```terminal
$ docker-compose ps
```

###イメージの一覧を表示
```terminal
$ docker-compose images
```

##参考
- [docker-composeでよく使うコマンド](https://qiita.com/ryuichi1208/items/8b5adc88a93319cb76a2)
- [docker compose run とdocker compose execの違い ( #docker )](https://qiita.com/YumaInaura/items/39abf610dc322e83d5b3)
よく使うけどちょっとニッチなcss

よく使うけど、いつもググってるので、まとめました。



###pタグの直後にulがある時のみ適応(隣接セレクタ)

```style.scss
p + ul {
  margin-top: 50px;
}
```
pタグの直後にある要素がulタグじゃなかった場合はstyleが指定されない

###親要素の直接の子要素のみに適応(親子セレクタ)

```style.scss
p > ul {
  margin-top: 50px;
}
```

###ある要素と同じ親要素に属し、後続に出現する要素にのみ適応(間接セレクタ)

```style.scss
.list ~ .item {
  margin-top: 50px;
}
```
.listの後続に出現する、全ての.itemに反映される。

###.main と .textどっちのclassも持ってる要素を指定

```style.scss
.main {
 &.text {
   margin-top: 50px;
 }
}

//↓コンパイル後

.main.text {
  margin-top: 50px;
}
```
###単純にclass名の追加→.main_textを指定
```style.scss
.main {
 &_text {
   margin-top: 50px;
 }
}

//↓コンパイル後

.main_text {
  margin-top: 50px;
}
```

###target="_blank"のついた要素にstyleを指定
```style.scss
.button a[target="_blank"]::after {
 
}
```
ちなみに、<a>タグに「target=”_blank”」を付与する場合「rel=”noopener”」を付けた方がいいらしい。

###classを持ってないpタグを指定
```style.scss
 p:not([class]) {
}
```

###特定のclassを持ってないpタグを指定
```style.scss
 p:not(.hoge) {
}
```

###classとidを持ってないpタグを指定
```style.scss
p:not([class]):not([id]) {
}
```

###divタグ配下の全ての要素にstyleを適応
```style.scss
 div * {
 margin: 10px;
}
```

###&を組み合わせる-その１
```style.scss
.sample {
    & + & {
        margin-top: 1em;
    }

    &,
    &--hoge {
        margin-top: 1em;
    }
}

↓  コンパイル後

.sample + .sample {
  margin-top: 1em;
}

.sample, .sample--hoge {
  margin-left: 1em;
}

```

使用例

```style.scss

.page-top {
  &,
   a {
   margin-right: 10px;
}

↓  コンパイル後

.page-top,
.page-top a {
  margin-right: 10px;
}

```
classがpage-topのaタグに反映させたい時にも使用できる


###&を組み合わせる-その２

```style.scss
.hoge { 
    &__sample {
    margin:0 auto; 
        .test & {
        padding :10px; 
        }
    }
}

↓  コンパイル後

.hoge__sample {
  margin: 0 auto;
}
.test .hoge__sample {
  padding: 10px;
}
```

.hoge__sampleの要素を使用しながら親のクラス名を別で指定し、特定の要素を追加したい時に便利

###3番目のみ

```style.scss
li:nth-child(3){
  margin-bottom: 20px;
}
```
###2の倍数のみ

```style.scss
:nth-child(2n)
```
###奇数

```style.scss
:nth-child(odd)
:nth-child(2n+1)
```
###偶数

```style.scss
:nth-child(even)
:nth-child(2n)
```
###最後以外

```style.scss
li:not(:last-child) {
    margin-bottom: 20px;
}
```
###最初と最後のみ

```style.scss
.wrap > li:first-of-type,
.wrap > li:last-of-type {
   margin-bottom: 20px;
}
```
###最初と最後以外

```style.scss
.wrap > li:nth-child(n+2):nth-last-child(n+2)  {
   margin-bottom: 20px;
}
```
###最後の要素以外に擬似要素

```style.scss
div > span:not(:last-child):after{
  content:",";
}
```
###aタグの_blankだけにcssを当てる

```style.scss
a[target="_blank"] {
    background:#0099FF;
    color:#FFFFFF;
}
```


##参考リンク
https://qiita.com/noqua/items/adc24c28c13e9b74d3ad
GitHubでマージ先を間違えてしまった時の対処

Githubでプロジェクト管理をしていていつものようにマージを行おうとした時…。
マージ先を本来マージしたかったブランチと別のブランチにマージを行なってしまった…。
今回はその戒めとしてその時行なった手順をまとめていこうと思います…。
行なった手順は全てWeb上で行いました。

## 事の経緯
developからAブランチを伸ばし、さらにBブランチを伸ばした。
A,B共にPRを作成。
Aブランチはdevelopに、BブランチはAブランチをそれぞれマージ先に指定していた。
Aブランチを先にマージし、Bブランチのマージ作業を行う時、マージ先をAブランチにしたまま作業してしまった…。

## 解決まで…
### BブランチのマージをRevert
とりあえずBブランチのマージをRevertしてみた。
マージした場所にある「Revert」を押下し、マージした。
するとPR作成の催促表示がA,B共に出た…。
先にマージしたはずのAブランチまで表示が…。

### Bブランチで再度PRを作成
developをマージ先にしてBブランチのPRを作成…。
するとコンフリクトを起こしており、AブランチのPR作成の催促表示は出たまま…。


### BブランチPRのコンフリクトを解決
「Resolve conflicts」を押下。
コンフリクトを全て解決したのち、「Commit merge」を押下…。
するとAブランチのPR作成の催促表示が消えた！

### Bブランチを正しい先にマージ
マージ先をよくよく確認してマージを行なった。
無事に元の予定通りA,B共にdevelopへのマージを終えることができた…。

## まとめ
マージ先をミスると手間がかかる。
１番はマージ先を間違えないこと、もし間違えてしまっても落ち着いて、冷静に対処を行うことはとても大事。
ミスをしてしまったときこそ落ち着いた対処が必要ですね…。

参考
<a href="https://qiita.com/ponsuke0531/items/5e15f74f9d5dfca4e7b2">GitHubで誤って違うブランチにマージしてしまった時にWeb上だけで戻す方法</a>
<a href="https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github">GitHub でのマージ コンフリクトを解決する</a>
RailsのViewからVue.jsのModalを表示させてみた

画像のように、一覧画面で`詳細を開く`ボタンで詳細画面を開くときに、Railsのviewは使用せずVue.jsのModalで表示することを試みた。
何とか実装出来たが、JSはjQueryから入門したこともあり結構大変だったのでメモとして残しておく。
<img width="960" alt="スクリーンショット 2020-03-10 19.41.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202390/12f9ae65-74db-e139-8ccb-ad8a777dc319.png">

# 環境
Ruby 2.6.5
Ruby on Rails 6.0.0
Vue.js 2.6.11

ここではRailsやVueの設定は省略し、Railsのwebpackerでvueのインストール、セットアップが完了していることを前提として書いていく。

# やりたい事
冒頭の通り、`詳細を開く`ボタンをクリックしたときに詳細画面をVue.jsのModalで開きたい。
しかし、今までRailsの中でVueを使った事はあっても、Vueインスタンスがどのタイミングで生成されるかなど無知であったため、最初はどうやるのかイメージがつかなかった。
jQueryからJavascriptに入門したので、なかなか生のJSを書く機会がなかった。

# Rails側
Modalを開く部分はBootstrapを使うことにした。
参照: https://getbootstrap.com/docs/4.0/components/modal/

上記のURLを参考にして、BootstrapだけでModalを開けるようにしていく。

```slim
view/users/index.html.slim

thead
  tr
    th id
    th 名前
    th email
    th tell
    th
tbody
  - @users.each do |user|
    tr
      th = user.id
      td = user.name
      td = user.email
      td = user.tell
      td 
        / Vue側にuser_idを渡すために、data属性にuser_idを持たせている
        button.btn.btn-info.btn-modal data-target="#full-width-modal" data-toggle="modal" data-user_id="#{user.id}" 詳細を開く

/ Modalのコンポーネント部分。ここにVueのtemplateをマウントさせる。
#full-width-modal.modal.fade tabindex="-1" role="dialog" aria-hidden="true" aria-labelledby="full-width-modalLabel" data-keyboard="false" data-backdrop="static"
  #showUser
    = javascript_pack_tag 'users'
```

# Vue.js側
次にvueインスタンスを生成させていく。
javascript/packs配下に`users.js`を作成し、コードを記述

```javascript

javascript/packs/users.js

import Vue from 'vue'
// packs配下にcomponentsディレクトリを作成し、その中にcomponentを格納している
import ShowUser from './components/ShowUser.vue'

// ボタン要素をgetElementsByClassNameで配列として取得
const btnModals = document.getElementsByClassName('btn-modal')

// for文で各ボタン要素を取り出し
for(let btnModal of btnModals) {
  // 取り出したボタン要素に対し、addEventListenerでボタンクリックされた時にvueインスタンスを生成させる
  btnModal.addEventListener('click', () => {
    new Vue({
      el: '#showUser',
      render: h => h(
        ShowUser, {
          // componentにpropsでuser_idを渡している
          props: {
            userId: Number(btnModal.getAttribute('data-user_id'))
          } 
        }
      )
    })
  })
}
```

ここまで出来たら、あとは`ShowUser.vue`を書いていけば終わり。
Modalを閉じるときはどうすればいいの？となりそうだが、単純に閉じるボタンのアクションに`this.$destroy()`を仕込んであげれば大丈夫。
modalを閉じる処理をbootstrapのjQueryではなく、Vue側で書いてあげないといけないので、そこも含めて次回の記事で頑張って書いていく。
Illustrator「アセットの書き出し」で保存したPNG画像の色がくすんでしまった原因


既存Webサイトの画像を差し替えるため、制作当時のIllustratorファイルを入手して編集作業をしていた時のことです。新しい画像のPhotoshopファイルをIllustratorにリンク配置して、アートボードを「アセットの書き出し」パネルからPNG(PNG24)形式で書き出してブラウザで表示したところ、なんだか画像の色がおかしい。イラレのプレビュー表示の画像と比べて全体的に色がくすんでる！  自分で新規に作成したイラレファイルで実行した場合は再現しないため、解決するのに丸１日潰してしまいました。何が原因だったか、ここに書きます。

**動作環境**
Adobe Illustrator 2019 ver.23.1.1, macOS Mojave 10.14

##現象
下図は簡単なサンプルで現象を再現させた様子です。

1. `sample.ai`（図の上段）のアートボードに、`sample_CMYK.psd`（右下）をリンク配置する。
2. 配置したオブジェクトをアートボードに切り出して「アセットの書き出し」パネルからPNG形式のファイル（左下）に書き出す。

**結果**
PNG画像の色が、元の画像(`sample.ai`のそれ）よりもくすんでいます。
![fig1_w600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/5199d9f7-c3b3-162e-2010-d99768fb4c91.png)
サンプルではリンク先の`sample_CMYK.psd`のカラースペースがCMYKになっていますが、PSDファイルのカラーモードをRGBに変換しても結果は変わらず。PNG画像に出力すると色がくすんでしまいました。PSDファイルの設定が原因ではなさそうです。

## JPEG形式や「Web用に保存（従来）」では発生しない
問題の切り分けのため、他の形式や方法で画像に書き出して比較してみました。
![output_menu_w500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/86aadabb-e0b0-8909-5e45-793f338d7441.png)
下図は２つの方法、「アセットの書き出し」と、「ファイル」メニューの「**書き出し** / **Web用に保存（従来）**」を使ってPNG形式とJPEG形式に書き出した結果です。
（上段：アセットの書き出し / 下段：Web用に保存、左: PNG / 右: JPEG）
![before_w400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/9944ac3d-4041-3ce6-72f3-57b12af837cb.png)
ご覧のとおり、

* JPEG形式で出力した場合は、どちらの方法でも色はくすまない
* **Web用に保存（従来）**でPNG形式に出力した場合も色はくすまない

この４パターンの中では、**アセットの書き出し**を使ってPNG画像を書き出した場合のみ色がくすむということが判りました。**アセットの書き出し**に絡むイラレ側の設定に原因がありそうです。

## これが原因だった！
イラレファイルを新規に作った場合は問題ないのに、入手したファイルで編集した場合は発生するため、２つのファイルについて画像変換時のカラーに関する設定を比べてみたところ、違いがありました！

「編集」メニューの「**プロファイルの指定**」の項目です。入手したイラレファイル（色がくすむ方）を開いた場合、「プロファイル」に**Adobe RGB (1998)**が選択されていました。
![profile_before_w500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/930bfcf1-a3e6-2700-a27c-6f3debd6b268.png)
一方、自分で新規作成したイラレファイルを開いた場合、「プロファイル」は**作業用RGB：sRGB IEC61966-2.1**になっていました。
![profile_after_w500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/7ab63232-2a9b-6a87-7149-1571751e2900.png)
入手したイラレファイルの「プロファイル」を**作業用RGB：sRGB IEC61966-2.1**に変更して**アセットの書き出し**を実行したところ、PNG画像の色もくすまなくなり解決です（下図）。
![after_w400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/5c5908ed-64cf-c9e2-75fa-d60c6b5c680c.png)
今回のように、普段と違う所から入手したイラレファイルを使う場合は特に、**プロファイルの指定**が自分の作業環境と異なっているケースがあるのでこれからは必ずチェックしてから作業することにしました。
退職者・卒業生アカウントに対する bounce mail により、spam 送信サーバであると誤判定される

## 概要

3000人程度の利用者に対するメールシステムを、かれこれ12年間、オンプレミスで運用してきたのですけれど、ついに G Suite に移転することになりました。その間に得たノウハウを、このままロストテクノロジーにするのも惜しいので、過去の作業ログの中から、ある程度汎用性がありそうなトピックを取り出して、公開しようと思います。

利用者が10人〜30人くらいまでのメールサーバであればともかく、利用者が1000人を超えるメールサーバを運用している場合、受信アドレスの正当性検査は大変重要です。一言で言えば、**できる限りメールを受け取らないように努力しなければなりません** 。

メールシステムの運用開始当時、まだ上記の認識が不十分だった筆者は、退職者・卒業生アカウントに対する bounce mail により、管理しているメールシステムが spam 送信元であると誤判定されるというトラブルに遭遇しました。

1. spam 送信者が `From: victim-notexist@yahoo.co.uk` と非実在の送信者を騙って、退職者・卒業生アカウントに大量の spam を送ってくる。
2. 当方のメールサーバは `victim-nonexist@yahoo.co.uk` に対して、メールボックスが存在しないという bounce mail を大量に送信する。
3. yahoo.co.uk のメールサーバから見ると、当方のメールサーバは「非実在のメールボックスに mass mailing を行っている」「つまり、spam 送信者である」と誤判定される。
4. `alice@yahoo.co.uk` にメールを転送している、現役の利用者 alice のメールが転送を拒否される．

特に、当時はまだ LDAP に慣れていなかったので、プライマリメールサーバでは LDAP を参照して、受信アドレスの正当性検査を正しく行なっていたのですが、セカンダリメールサーバでは LDAP を参照することなく、ドメインだけを検査してメールを受け取ってしまっていたのです。

## 対策方法

bounce mail を発生させないためには、メールを受け取らないことが肝心です。つまり、SMTP セッションで `RCPT TO` により受信者アドレスが指定された時点で、受信者アドレスの正当性を検査し、正当ではない受信者アドレスの場合は受取を拒否します。そのためには、local_recipient_maps パラメータを正しく設定し、かつ、smtpd_reject_unlisted_recipient パラメータをデフォルトのまま yes に設定しておけば良いです。

しかし、筆者が管理しているシステムでは、学内の他のシステムの都合もあり、単純に受け取らないという設定ができませんでした。そのため、退職者・卒業生アカウントに対するメールは、[転送のみを行い、転送できない場合は破棄するように設定](https://qiita.com/tsuchm/items/e64389a0c8aa80a19fd9)して対応しました。また、LDAP の登録内容がそのまま使えない場合は、[任意のスクリプトを使って読み替える設定](https://qiita.com/tsuchm/items/a0b7a0b6615d283f9813)が応用できます。

利用者が増えてくると、正当な受信者アドレスのリストの管理が難しくなってくるため、どうしても bounce mail を発生させてしまうことがあります。bounce mail をまったく送信しないという設定も可能ですが、そのように設定すると正規利用者がメールアドレス誤りに気付けなくなり、それはそれで問題です。折衷案として、筆者は bounce_queue_lifetime パラメータを 0 に設定して運用しています。

```conf:/etc/postfix/main.cf
bounce_queue_lifetime = 0
```

このパラメータを設定すると、postfix は、bounce mail の送信を1回だけ試行して、失敗した場合はそのまま破棄します。bounce_queue_lifetime のデフォルト値は 5d （5日間）なので、失敗した場合は5日間 bounce mail の再送を試みます。そのデフォルト設定に比べて、bounce_queue_lifetime パラメータを 0 に設定しておくと、bounce mail を送信しようとする SMTP セッションは 1/100 以下になりますから、その分だけ spam 送信者と誤判定される危険性が減ります。
[漏洞通告]CVE-2020-1947/Apache ShardingSphere UI YAML解析远程代码执行漏洞

### 漏洞描述
近日,亚信安全网络攻防实验室跟踪到`Apache ShardingSphere`存在`YAML`解析远程代码执行漏洞,该漏洞由奇安信云影实验室安全研究员`maoge`提交给`Apache`官方.`Apache ShardingSphere UI`是`Apache ShardingSphere`的图形界面版产品.攻击者利用此漏洞可以实现代码执行,直接接管服务器.

### 漏洞编号
CVE-2020-1947

### 漏洞威胁等级
高危

### 影响范围
 Apache ShardingSphere&&UI <= 4.0.1

### 漏洞验证
选用`Apache ShardingSphere UI 4.0`复现漏洞

`Apache ShardingSphere UI`默认的后台密码均为`admin`.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/a9c0766f-b4b8-9ea7-8a64-45340b6773aa.png)

登陆以后,在相应漏洞触发点输入payload即可完成攻击.该payload主要借助于`SnakeYAML`方法和`YAML`语法构造.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/8adfd7a0-4106-c5c8-351b-b2fecbd0225f.png)


### 修复建议
升级到最新版本即可
https://github.com/apache/incubator-shardingsphere/releases

### 时间轴
[0] 2020/03/10 奇安信CERT发布漏洞通告
[1] 2020/03/10 亚信安全网络攻防实验室分析&复现该漏洞并发布漏洞通告

### 鸣谢
感谢`Qianxin-Ateam r00t4dm`小伙伴一起研究该漏洞

### Reference
https://mp.weixin.qq.com/s/c5apSZQEDgN3rfbAjNQqhA
[solidity]コントラクトにバグが見つかった場合にコントラクトの実行を止めるデザインパターン（Emergency Stop）

# 記事の内容
コントラクトは一度デプロイされると修正が出来ないので、バグが見つかった場合に安全に実行出来なくする必要があります。
この記事ではそのデザインパターンをメモ

# 参考
[solidity-patterns Emergency Stop](https://fravoll.github.io/solidity-patterns/emergency_stop.html)

# 想定するユースケース
コントラクトをパブリック型で使用する場合　かつ　送金処理などの不正利用による被害に繋がる可能性がある場合

# サンプルコード

~~~
pragma solidity ^0.5.16;

contract EmergencyStop {

    bool isStopped = false;

    modifier stoppedInEmergency {
        require(!isStopped);
        _;
    }

    modifier onlyWhenStopped {
        require(isStopped);
        _;
    }

    modifier onlyAuthorized {
        // Check for authorization of msg.sender here
        _;
    }

    function stopContract() public onlyAuthorized {
        isStopped = true;
    }

    function resumeContract() public onlyAuthorized {
        isStopped = false;
    }

    function deposit() public payable stoppedInEmergency {
        // Deposit logic happening here
    }

    function emergencyWithdraw() public onlyWhenStopped {
        // Emergency withdraw happening here
    }
}
~~~
ざっくりコード解説

~~~
    modifier stoppedInEmergency {
        require(!isStopped);
        _;
    }

    modifier onlyWhenStopped {
        require(isStopped);
        _;
    }
~~~
内部変数を見て処理を実施するか判断を行う修飾子の定義

~~~
    function stopContract() public onlyAuthorized {
        isStopped = true;
    }

    function resumeContract() public onlyAuthorized {
        isStopped = false;
    }
~~~
処理実行判定用の内部変数切り替え関数

~~~
    function deposit() public payable stoppedInEmergency {
        // Deposit logic happening here
    }

    function emergencyWithdraw() public onlyWhenStopped {
        // Emergency withdraw happening here
    }
~~~
内部変数がTrueの時、Falseの時それぞれで動作する関数

簡単な作りですが、この作りでコントラクト内にバグが見つかった場合、安全に動作を止めることが出来ます。

# Emergency Stopパターンが使われているコード
[OpenZeppelin Pausable.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/lifecycle/Pausable.sol)
AWS IoT embedded c SDK 向けThing作成スクリプト

Embedded C SDK 向けに、コードのクローン、Thingの作成、ポリシーの作成、証明書の作成、ポリシーのアタッチなど、諸々を行うスクリプトです。
[以前書いた記事](https://qiita.com/tatsuhiroiida/items/b458ffe3df6df565b56e)の手順２〜5を一発で行います。

注意：
エラーケースやスクリプト実行の冪等性等は一切考慮してません。
Policyはセキュリティを考慮した設定が必要です。

ポリシーは、予め以下を作成し保存しておく。

```json:policy.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action":["iot:*"],
    "Resource": ["*"]
  }]
}
```
``` sh:setup.sh

# thing name は適宜変更
THING_NAME=samplething
POLICY_NAME=${THING_NAME}_Policy

aws iot create-thing --thing-name ${THING_NAME}

git clone https://github.com/aws/aws-iot-device-sdk-embedded-C.git
git clone -b mbedtls-2.16 --recursive https://github.com/ARMmbed/mbedtls.git aws-iot-device-sdk-embedded-C/external_libs/mbedTLS/.

cd aws-iot-device-sdk-embedded-C/certs

wget -O rootca.pem \
    https://www.amazontrust.com/repository/AmazonRootCA1.pem

aws iot create-keys-and-certificate --set-as-active \
    --certificate-pem-outfile    ${THING_NAME}_certificate.pem \
    --public-key-outfile         ${THING_NAME}_public_key.pem  \
    --private-key-outfile        ${THING_NAME}_private_key.pem \
    --query certificateArn

cd ../..

echo -n CERTIFICATE_ARN: 
read str 
CERTIFICATE_ARN=$str

aws iot create-policy                     \
        --policy-name ${POLICY_NAME}      \
        --policy-document file://policy.json
        
aws iot attach-thing-principal             \
        --thing-name $THING_NAME           \
        --principal $CERTIFICATE_ARN
        
aws iot attach-principal-policy            \
        --policy-name $POLICY_NAME         \
        --principal $CERTIFICATE_ARN
        
```
rsyslogでのTCPによる送受信

# はじめに
　この記事は、rsyslogによるログのTCP転送について記載しています。
　[rsyslogでのTLS(SSL)によるセキュアな送受信](https://qiita.com/saeki4n/items/b30e619d9371f7808657)に関連している記事になります。

　検証環境は CentOS8 と Ubuntu(18.04)です。

- syslog送信側（クライアント）：CentOS(rsyslog version 8.37.0)
- syslog受信側（サーバー）：Ubuntu(rsyslog version 8.32.0)

# 受信側（サーバー）の設定
　受信側であるUbuntuのrsyslogの設定を行います。

```
$ sudo nano /etc/rsyslog.conf
```
```
module(load="imtcp")
input(type="imtcp" port="514")
```

　TCPで受信するために、"imtcp"というモジュールを読み込み、input で使用可能にします。ポートはデフォルトのままの514を使用します。（コメントを外すだけ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/a744059c-31de-890c-9bad-042bccf482ea.png)

### 旧設定の場合
　こちらの設定でも受信は可能ですが、現時点では~~選ぶメリットはあまり無いでしょう。~~
**2020年04月01日追記**：
　この旧設定ですが、obsolete legacy ということで使用しないよう推奨されています。
　詳しくはこちらをご覧ください。
Configuration Formats
https://www.rsyslog.com/doc/v8-stable/configuration/conf_formats.html

```
$ModLoad imtcp
$InputTCPServerRun 514
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/6e6e4cc2-8740-ad27-d6c7-29f6ac36796f.png)

---
　設定を保存後、rsyslogサービスを再起動します。

```
$ sudo systemctl restart rsyslog.service
```
　再起動後は問題が発生していないか確認しておきましょう。

```
$ sudo systemctl status rsyslog.service
```

# 送信側（クライアント）の設定
　送信側であるCentOSのrsyslogの設定を行います。

```
$ sudo nano /etc/rsyslog.conf
```
  \*.* とすることで全てのログを転送対象とします。ドット[.] の前がFacility(ファシリティ)、後のことをSeverity（シビアリティ）と言い、転送する対象を限定したい場合は適宜設定してください。
　受信側のIPやホスト名に@@ を二つ付けることでTCP転送になります。@が一つだとUDP転送です。
　ポート番号を変更した場合は、:(コロン) で設定できます。

```
*.*    @@[受信側のIPアドレスやホスト名]
*.*    @@[受信側のIPアドレスやホスト名]:[ポート番号]
```
　検証環境では、UbuntuのIPは 192.168.0.13 でポート番号をデフォルトなので、次のように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/c54ebc99-30a2-4ae0-aa40-4bebbe210f02.png)

　設定を保存後、rsyslogサービスを再起動します。

```
$ sudo systemctl restart rsyslog.service
```
# syslog転送が出来ていることの確認
　送信側でログを発生させて無事に転送されることを確認します。

```:送信側
$ logger Hello
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/1e20829f-8d13-2a9d-7817-6759474f5c18.png)

　Ubuntuの場合、デフォルトでは /var/log/syslog にログが保存される設定になっているので、そちらを確認します。

```:受信側
$ tail /var/log/syslog | grep Hello
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/09c356b9-05df-4017-ce1d-7b7de5cca6a0.png)

　無事に転送できていることが確認できれば成功です。

　余談ですが、デフォルトでUbuntuのログが /var/log/syslog に保存されるのは、rsyslogのconfigファイル"50-default.conf"にその設定があるからです。同じくCentOSでは /var/log/messages になるのもrsyslogで設定されているからです。
　転送ログが確認できない時は、こちらの設定の確認もしてみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/5c230e45-d2ba-eeff-7e43-364a72982c29.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/72eae1b2-069c-f9dc-004c-484d1a4a5879.png)

# セキュリティ対策が必要
　現状はただログを転送している状態ですから、経路のパケットを覗かれると中身が確認できる状態になっています。これは良くない状況です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430322/8341dbbf-c2e1-f207-bec8-2eeaf379550c.png)
　次は、暗号化をしていきたいと思います。

# 参考
Syslog について。ファシリティ/シビアリティ/プライオリティの違い
　https://turningp.jp/network_and_security/syslog-introduction

Configuration Formats
　https://www.rsyslog.com/doc/v8stable/configuration/conf_formats.html
【Laravel】知らず知らず地雷踏んで死んだ話。

#なんの地雷？？？
```
php artisan config:cache
```
キャッシュクリア系のコマンドでよく見るこれ。
これを実行してしまったことによって、***env()でnull***しか返さなくなってしまった。

#いつ気づいた？
元々、***config/app.php***に記述している内容が反映されてなかったので、上記のコマンドを使用して反映させるために使った。しかし、使用後すぐローカルのサーバーを落として、再度立ち上げようとすると問題発生。

```
php artisan serve


PHP Warning:  A non-numeric value encountered in /Users/shiga1/git/training_customer_app/config/app.php on line 16

Warning: A non-numeric value encountered in /Users/shiga1/git/training_customer_app/config/app.php on line 16

In ProviderRepository.php line 208:

  Class name must be a valid object or a string

```

はじめは全く意味がわからなかったので、調べてみると使用したコマンドがおかしく、実行する前の状態に戻したかったがよく分からず。。。

#今後
実行前に軽く、どんなコマンドなのか調べておく。
幸い、ローカルだったので新しいプロジェクト立ててそこに移動させる。
rsyslogでのTLS(SSL)によるセキュアな送受信

# はじめに
　最近のsyslogサービスといえばrsyslogですが、盗聴防止のために、これをTLS(SSL)を使って暗号化メッセージを送受信しようとしたようとしたところ、かなり難儀したのでまとめておこうと思ったのが発端です。
　各項目で長くなったのでこの記事はインデックスになりました。
　とりあえず一区切り付きましたが、今後さらに記事が出来たら更新するつもりです。

　検証環境として CentOS8 と Ubuntu(18.04)を使用します。
rsyslogは既にインストールしている前提です。rsyslogバージョン8になります。

- syslog送信側（クライアント）：CentOS(rsyslog version 8.37.0)
- syslog受信側（サーバー）：Ubuntu(rsyslog version 8.32.0)

### 主に参考にしている情報
　公式ドキュメント：[RSyslog Documentation](https://www.rsyslog.com/doc/master/index.html)
　またこちらの書籍を参考にしました。：[鶴長 鎮一(著) rsyslog 実践 ログ管理入門 ](https://www.amazon.co.jp/dp/B072PL7CR5)

　この書籍は、rsyslogのコンセプトや全体像を把握するのに非常に参考になりました。トラブルシューティングには全体像の把握がかかせません。公式ドキュメントは英語であるためお恥ずかしながら読むのがしんどいので…。
　ただこの書籍は残念ながらやや古いため、新しい設定の仕方には対応していません。そのためその辺りは公式ドキュメントを確認する必要があるでしょう。

# Syslogを TCP転送ができるように設定（暗号化なし）
　https://qiita.com/saeki4n/items/83aa3c3b215afffde041
# セキュアな送受信（認証なし、暗号化のみ）
　https://qiita.com/saeki4n/items/198407c8710d769dfa55
# セキュアな送受信（認証あり）
　https://qiita.com/saeki4n/items/f7de2c948316c0d021dd
# rsyslogでのキューを使った確実な送受信
　https://qiita.com/saeki4n/items/cb8a957d19763037b2e6

# 参考
- 公式ドキュメント：[RSyslog Documentation](https://www.rsyslog.com/doc/master/index.html)
- [鶴長 鎮一(著) rsyslog 実践 ログ管理入門 ](https://www.amazon.co.jp/dp/B072PL7CR5)
- [Syslog について。ファシリティ/シビアリティ/プライオリティの違い](https://turningp.jp/network_and_security/syslog-introduction)
- [Server World:Rsyslog : リモートホストにログを転送する](https://www.server-world.info/query?os=CentOS_8&p=rsyslog&f=2)
- [RED HAT ENTERPRISE LINUX 7 システム管理者のガイド: 23.4. RSYSLOG でのキュー (QUEUE) を使った操作](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/s1-working_with_queues_in_rsyslog)
- [SELinuxを無効にするには](http://park1.wakwak.com/~ima/centos4_selinux0001.html)
[ITパスポート]　6章 自分用メモ　

自分用にメモとして投稿しました。わかりにくかったらごめんなさい泣

#サービスマネジメント
###ITILとは
- ITサービスにおける総括的なガイドラインであり*デファクトスタンダード*として活用されている

##サービスレベル管理
###サービスレベル管理はＩＴサービスの提供者と利用者の合意に基づいたサービスレベルを維持・改善するプロセス

- サービスレベル合意書(SLA)
 - 提供するITサービスの品質と範囲を明文化し、双方の合意に基づき運用管理するための**品質保証契約**

- サービスレベル管理(SLM)
 - 契約したサービスレベルが守られているかどうか管理、維持、向上を測る**管理方法**
 - PDCAサイクルでは
 - Plan・・計測の計画
 - Do　・・ITサービスの提供
 - Check・・計測結果の評価
 - Act ・・改善の検討・実施

###ITサービス可用性管理
- 利用者が必要な時に、いつでも利用できるよう、ＩＴサービスを構成する個々の機能の維持・管理を行うこと

##インシデント管理
- ITサービスにインシデント（問題）が発生した場合に、可能な限り迅速に通常のサービス運用の回復に努める

###インシデント管理の流れ
- 検知　→　評価と初期サポート　→　調査　→　解決

###変更管理
- 問題管理によって明らかになった解決策に応じて必要になった変更を変更要求として受けつけ、評価・実施をする活動

###リリース管理
- 変更管理で決定した変更作業を行うこと

###ファシリティマネジメント
- 企業が保有するコンピュータやネットワーク、施設、設備を維持、保全しよりよい状態を保つための考え方


##システム監査
- 独立した**第三者**である**システム監査人**によって情報システムを総合的に検証・評価し、その関係者に助言や勧告を行うこと

###システム監査の意味
- 障害に対する信頼性を確保しているか
- 災害や不正アクセスに対する安全性を確保しているか
- 企業の経営方針や戦略に効率的に情報システムが貢献しているか

###システム監査のプロセス
1. 監査計画書を作成　（数年度単位の中長期計画書、年度単位の基本計画書、監査項目単位の個別計画書）
2. 予備調査　（システムの概念を把握するために行う）
3. 本調査　（具体的な調査・分析・検討を行う）
4. システム監査報告書の作成　（**総括・優良点・指摘事項・改善事項**を記載）
5. 意見交換会（**被監査部門の代表者と意見交換をする。**システム監査報告書を追加・修正して完成させる）
6. 監査報告会　（経営者に監査結果を説明する）
7. フォローアップ (改善の状況を確認し、改善の実現を支援する)

##内部統制
- 業務を適正に行うための体制を構築すること

###内部統制の意味
- 業務の有効性、効率性
- 財務報告の信頼性
- 事業活動に関わる法令等の遵守
- 資産の保全

###統制活動とは
- 内部統制を業務活動に取り込むための方針や手続き。
- 統制活動の注意点
 - 違法行為や不正行為が発生するリスクを明確にする
 - 担当者間で相互に不正な行動を防止できるように、職務分掌を図る
 - リスクに対応するルールを設定し、適切に実施されているかチェックする体制を確立する

### ITガバナンス
- 情報システムを活用するためのＩＴ戦略を策定し、実行を統治する仕組み
C#のLINQで何気なく使っているラムダ式について。

# まずはLINQのサンプルをどうぞ

こちらをご覧ください。C#のソースコードで、LINQの**Selectメソッド**のサンプルです。

```C#
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] a = { 1, 2, 3, 4, 5 };
        var result = a.Select(c => c + 3);

        foreach (var item in result) Console.WriteLine(item);

        Console.Read();
    }
}
```
実行結果はこちら。配列のアイテムすべてに 3 が足されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/595baf74-b86a-4678-f8a9-c70d79b4f765.png)
さてさて、`c => c + 3`はラムダ式による書き方ですね。

この`c => c + 3`はいったい何者なのか？
少しずつ書き換えながら考えていきます。
#ラムダ式を書き換えていくよ

```C#
        var result = a.Select(c => c + 3);
```
この`c => c + 3`って、`c`を渡すと`c + 3`という結果を返す、**まるでひとつの関数みたい**な働きをしてますね。
`c`が引数で、`c + 3`が返り値、みたいな。

実はこれ、下記のように書き換えてもまったく同じ結果となります。

```C#
        var result = a.Select((int c) => c + 3 );
```
さっきの書き方だと```c```がいきなり出てきてビックリでしたが、```(int c)```と書けばちゃんと引数の宣言に見える！
```int```が省略されていたのです。
だって```c + 3;```とかやってるし、どう見てもint型でしょ。型推論というやつです。型推論可能なときは型指定を省略できるんですねえ。

さらにここから、下記のように書き換えも可能です。

```C#
        var result = a.Select((int c) => { return c + 3; });
```
さっきまでは```c + 3```がポツンと書いてあったけど、```{ return c + 3; }```と書けばちゃんと値を返しているように見える！
```return```も省略可能なんですねえ。

ちなみに```{```と```}```の中、何行も書くことができるよ。

```C#
        var result = a.Select((int c) => { int tmp = c + 3; return tmp; });
```
まぁ何行も書くんだったらちゃんと改行すべきだと思うけど…。

```C#
        var result = a.Select(
            (int c) =>
            {
                int tmp = c + 3;
                return tmp;
            }
        );
```
ここまで書き換えると、なんかもう完全に関数っぽい見た目ですね。
# ラムダ式は「匿名関数」の書き方のひとつ！

ラムダ式で省略されていたところを丁寧に書いていくと、関数っぽい見た目になりました。
それもそのはず、**匿名関数**を書くための手段のひとつがラムダ式なんです！

さっき`Select`メソッドに渡していた、

```C#
            (int c) =>
            {
                int tmp = c + 3;
                return tmp;
            }
```
を、あえてラムダ式を使わずに書くと、

```C#
            delegate(int c)
            {
                int tmp = c + 3;
                return tmp;
            }
```
はい、どう見ても関数です。

よく見るとdelegateというキーワードが出現していますね。
匿名関数は通常、**デリゲート（delegate）**という特別な変数に入れて扱うものなのです。
デリゲートはいわば「関数の定義への参照」みたいなものだと筆者は思っておりますが、詳細が気になる方は各自ググってください！（丸投げ）
# まとめ

```C#
        var result = a.Select(c => c + 3);
```
C#のLINQをしっかり理解したい場合、
**デリゲートを勉強して、匿名関数を勉強して、ラムダ式を勉強して、LINQを勉強する、**
という手順を踏むのが正攻法ですかね。

でも筆者のように「いきなり仕事でLINQのプログラムをやることになったゾ…」という人は、
この手順を知らないまま、検索ワード「LINQ　入門」とかでググってしまい、
ラムダ式って何？匿名関数って何？デリゲートって何？となってしまいがちな気がする…だって自分がそうだったから…。

勉強は積み重ねが大切ってよく言うけど、何を積み重ねればいいのかを明確にするのも大切ですな。
# 参考文献
- Qiita記事
 - [C# 今更ですが、ラムダ式](https://qiita.com/rawr/items/11790e9ea08a29d028a4)
 - [【LINQの前に】ラムダ式？デリゲート？Func<T, TResult>？な人へのまとめ【知ってほしい】](https://qiita.com/RyotaMurohoshi/items/740151bd772889cf07de)
- 書籍
 - 【省エネ対応】 C#プログラムの効率的な書き方（ISBN:978-4774149752）
環境変数設定メモ

完全に個人的めも

# 基本的にrails アプリケーションにおいて環境変数を設定する際はターミナル上で.bash_profileを作成して管理をして行くのが一般的である。

```
vim ~/.bash_profile コマンドで展開
```
i でinsertモード
ESCキー　
：wq　保存
：q！ 保存せずに閉じる

環境変数の記述は

```
export KEY = '*******************'
export SECRET_KEY ='***********************'
```
の形で定義

ここに記載した、環境変数を

ENV['KEY']
ENV['SECRET_KEY']
の形で使用する。

```
source ~/.bash_profile　コマンドにて.bash_fileを読み込み
```

---

もう一つの環境編すの構成方法
Dotenvという.envファイルに記述する方法。

rails  ではGEMをインストール
gem 'dotenv-rails'

gemfileなどが存在するrootディレクトリに.envファイルを作成
作成した.envファイルがgithubにアップされないように.gitgnoreを編集する。


/.env
を追加

これで環境変数をgithubにアップすることなく使用できる。
環境変数の使用方法は同じ
チェコで人気のPHPフレームワーク「Nette」の紹介

# Netteとは

PHPのWebアプリケーションフレームワークというと、日本ではLaravelやCakePHP、Symfony, CodeIgniterなどが人気を集めています。しかし、世界を見渡してみると、さまざまなフレームワークが利用されています。
その中でも日本ではあまり知られていませんが、チェコ共和国では人気のPHPフレームワーク「Nette」を紹介します。
以下の文章は、Netteの公式サイトにあるドキュメントからポイントをかいつまんで紹介し、解説を追記したものです。

最新の内容は公式サイトをご覧ください。
https://nette.org/en/

## 3番目？の人気を誇るPHP7向けのフレームワーク

Webアプリケーションを開発するとき、スクラッチで開発することもできますが、多くの人にとってフレームワークを使うと効率よく開発できます。

NetteはPHP7向けに開発されたスタンドアロンのフレームワークで、オープンソースで公開されています。
また、雑誌「SitePoint」による調査「[2015年のベストPHPフレームワーク](https://www.sitepoint.com/best-php-framework-2015-sitepoint-survey-results/)」では、フレームワークの人気ランキングで第3位を獲得しています。

## セキュリティが最優先

Webアプリケーションを開発するとき、セキュリティは非常に重要です。
Netteは安全なPHPフレームワークとして開発されており、XSSやCSRF、セッションハイジャックなどを防ぐため、さまざまな方法が用意されています。
例えば、他のフレームワークでは、開発者が明示的にエスケープを宣言する必要がありますが、Netteでは[Context-Aware Escaping](https://latte.nette.org/en/#toc-context-aware-escaping)などが用意されており、指定されたコンテキストに基づいてすべての入力を自動的にエスケープされます。

## 10年以上続いている開発体制とライブラリ

Netteは最近できたものではなく、すでに10年以上にわたって開発が続けられています。
このため、成熟したライブラリがあり、安定しているため、[多くのWebサイト](https://builtwith.nette.org)で広く使用されています。

Zdrojákが実施した世論調査では、チェコ共和国で最も人気があり、広く使用されているフレームワークと 位置付けられています。

Netteはスタンドアロンのライブラリで構成されているため、WordPressや他のフレームワークと組み合わせて使うこともできます。
また、テンプレートシステムやAjaxのサポートがあるだけでなく、ドキュメントが豊富に用意されています。

## 高速かつ洗練されたコード

NetteはPHP 7.1の新機能を使用し、オブジェクト指向に基づいて設計されています。
洗練された高品質なコードで、将来の拡張性に重点を置いているだけでなく、高速なフレームワークの1つです。
Netteを使うと、システムの本質に集中して効率的に作業できるようになるだけでなく、ソースコードを適切に構造化できるので読みやすくなります。

## サンプル

- [PHPフレームワーク「Nette」で最初のアプリ(簡易ブログ)を作成する(1)](https://qiita.com/masuipeo/items/90220bfa4751c780a8a7)

順次、追記していきます。
SQLファイルを読みBigQueryを実行しcsvを保存してくれるPythonスクリプト

python 3.6.1 にて動作。

```bq_runnner.py
import argparse
import pandas as pd


def run_query(sql_file):
    with open(sql_file, 'r') as f:
        query = f.read()
    
    project_id = 'YOUR_PROJECT_ID'
    df = pd.read_gbq(query, project_id=project_id, dialect='standard')
    return df


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('sql_file')
    parser.add_argument('--output_csv', default='output.csv')

    args = parser.parse_args()

    df = run_query(args.sql_file)
    df.to_csv(args.output_csv, index=False)
```


使い方

```
$ python bq_runnner.py YOUR_QUERY.sql
```

csvファイル名はお好みで。


必要ライブラリ

```requirements.txt
pandas==0.25.3
pandas-gbq==0.13.0
```
基本情報技術者　テクノロジ系　第10章　表計算の基礎、複雑な関数、マクロ

[基本情報技術者試験](https://qiita.com/savaniased/items/d3f94da4f087e178cb69)
こちらより

# 表計算の基礎

## 表とセル
excelに置いて、マス目のことをセルといいます。
基本的に個々のデータか数式(関数など)を入れて使います。

後は他のセルとの連携でデータを抽出します。

## セルの範囲指定
:(セミコロン)を用いて範囲を指定します。

"(左上):(右下)"

excelを例に出すと
C2 :  E4

## 計算式
セルの番号を指定して書きます。

### 別のワークシート指定
"!"を使用して指定します。

例
ワークシート"売上集計"

愛知店売上!C4 を使うことで
愛知店のデータを拾うことができる。


## 関数
SUM(合計),AVE(平均)などあり
先の範囲指定を応用して範囲の計算をします。

### 切り上げ、切り捨て、四捨五入

例
切り上げ(-314.123,2) = -314.13
切り上げ(314.123,-2) = 400
切り上げ(314.123,0) = 315

## IF関数
条件の成立によって値を返します。

IF(条件、条件成立時の値、条件不成立時の値)
論理積("かつ")や論理和("もしくは")なども用いることができる

## セルの複写(相対参照)
複写(コピー)することもできます。
式も複写することができ、セルの場所も自動調整されるので便利です。

## セルの複写(絶対参照)
セルの場所を変えたくない場合
$を使うことで、固定することはできます。

例
B1　→ B$1

# 複雑な関数

## 垂直照合
IDから名前や成績などのデータだけを取り出すイメージもてばいいかと

垂直照合(探す値、セル範囲、検索範囲から取出す列の位置、検索指定(一致 or 探す値以下))

例
垂直照合(1000,A2:E10,5,0)

指定した範囲より
ID(指定範囲の左端の列)が1000の行を指定
Aから5番目の列(仮に名前とする)から
名前を取り出します

ID(指定範囲の左端の列)はセルによる指定もできます。

### 検索の指定
4番目に検索の指定をしていますが

* 0のとき: 一致する物
* 1のとき: 一致する値以下

## 水平照合
垂直照合が行から列指定しますが
水平照合は列から何行目か指定します。

書き方は垂直を水平に変えて
取出すのを列でなく行に変えただけです。

例
水平照合(15,A1:G6,5,1)

## 照合検索
検索範囲から、抽出に指定した範囲より
同位置の値を取出す方法です、

照合検索(探す値、検索セル範囲、抽出セル範囲)

例
照合検索('りんご',C1:C5,B1:B5)

仮にりんごが
C3(検索範囲の左上から3番目)にあった場合
B3(抽出範囲の左上から3番目)の値が取り出されます。

## 照合一致
探す値がどの列(行)にあるか調べます。

照合一致(式、セル範囲、検索の指定)

* 検索の指定  0のとき: 一致する値
* 検索の指定  1のとき: 最大値
* 検索の指定 -1のとき: 最小値

例
照合一致(15,B2:B8,-1)
この場合、15以上の値で最小値があるのがB6の時
5が返されます。
(B2から始まって上から5番目なので)

## 条件付き合計
照合検索の応用です。
同じようにデータを抽出してデータの合計を出します。

条件付合計(検索セル範囲、探す条件、合計セル範囲)

例
条件付合計(A1:B10,>E1,C1:D20)

これでE1を超える値を検索範囲から検索
合計セル範囲から同位置にあるデータを取り出し合計値を出します。

# マクロ
表計算ソフトないで独自の関数やシステムを作る方法です。

## セルの絶対表現
セル番地を置くことで、特定セルの指定します。

## セルの相対表現
基準セルから相対的な位置で、セルを指定することができます。

書式は以下の通りです。

相対(基準セル、行変位、列変位)

表計算ソフトでは左上が基準となるので
下方向、右歩行が正
上方向、左方向が負となります。
他シェルへの変数が共有されない問題について


## 概要

CI/CD対応でシェルスクリプトを書くことは必然ですよね。
あまり意識していなかった変数のスコープでハマったことと対策についてのまてめです。


## 問題

タイトルにもある通り、**他シェルを呼び出した際に呼び出し元で作った変数は共有されない**問題にハマりました。


* main_script.sh

```shell
#!/bin/bash -ex

APP_NAME='World'

echo "Hello ${APP_NAME}!!"

sh ./sub_shell.sh
```

* sub_script.sh

```shell
#!/bin/bash -ex

echo "Hello ${APP_NAME}2!!"
```

理想は、`Hello World2!!`と表示されるはずと思い込んでましたが実際は次の結果です。

```shell
$ sh main_shell.sh 
Hello World!!
Hello 2!!
```


## 対策: `main_script.sh`に変数を依存させない

原因は、`変数が特定のシェルスクリプト内に依存してしまっている`ため他のシェルに共有できないのです。

CI/CDツールでは、前もってビルドオプションから変数を作ることができるので、Jenkinsであれば設定から`ビルドのパラメータ化`で対応し、CircleCIであれば設定から`Environment Variables`に変数を作るなど、ツール内のなんらかの設定関連から変数作りが対応できると思います。

または、[exportとsourceでCI/CDが動いているマシンに変数を作って共有する](https://www.ppoohh.info/post-794/)方法もあります。
一見するとこの対応でも良さそうですが、例えばJenkinsの場合、共有PCで起動させている際は全ジョブに対して共有されるので注意が必要です。

CI/CD対応ではなくこの問題を解決する場合は、[テキストファイルに環境変数をまとめてそのファイルを各シェル内で読み込んで変数をを利用する方法](https://orebibou.com/2014/11/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%E5%A4%96%E9%83%A8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E8%A8%98%E8%BF%B0%E3%81%95%E3%82%8C%E3%81%9F%E5%A4%89/)があります。
LaravelでCookieのSameSite属性を設定する

#chromeアップデートでcookieに新しくSameSite属性が追加

###SameSite属性の目的
 今開いているページのドメインから、別のドメインにリクエストを送る際に、cookieをセットするかどうかを制御。

###SameSite属性の種類
##### Strict
* cookieをセットしない

##### Lax （デフォルト）
* SameSite属性の指定がない場合、扱われる。
* サーバーとCookieのドメインが同じでもcookieをセットしない場合がある。（POSTメソッド、imgタグ、XMLHttpRequests等）  
* トップレベルナビゲーションであるもの、かつ、getリクエストであるものにcookieをセットする。
    * トップレベルナビゲーションとは・・・　ナビゲーションのためにアドレスバーのURLが変更されること。
     
##### None
* cookieをセットする（secure属性を有効する必要がある。）

###SameSite属性のポイント

* SameSite 属性が指定されていない場合、デフォルトでcookieを「SameSite = Lax」として扱うようになる
* SameSite = Noneが指定されてる場合、secure属性を有効にしていないとエラーを返す

###多くの人がLux設定にするだろうからもう少しわかりやすく
調べてみたら、リクエストタイプ別にCookie送信の可否を書いている人がいたので引用させてもらいます
[引用元の記事](https://www.sjoerdlangkemper.nl/2016/04/14/preventing-csrf-with-samesite-cookie-attribute/)

|  リクエストタイプ | コード | Cookie送信 |
| :--- | :--- | --- |
|  Link | a href="…" | ◯ |
|  Pererender | link rel="prerender" href="…" | ◯ |
|  Form GET | form method="get" action="…" | ◯ |
|  Form POST | form method="post" action="…" | × |
|  iframe | iframe src="…" | × |
|  AJAX | $.get('…') | × |
|  Image | img src="…" | × |

   
##設定方法

src/config/session.phpを修正

```php:src/config/session.php
'same_site' => null,
```
インターセプタークラスでkeycloakの認証情報を取得する方法

keycloak認証からユーザーの認証情報を持った状態でAPIにリクエストを投げた際、
controllerクラスのメソッド呼び出される前にintercepter(インターセプター)から
ユーザー情報を取得するのにgetUserPrincipal()メソッドがあることを知らず手こずったのでメモ。

```intercepterTestClass.java

  @Autowired
  private UserDto userDto;

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    //

    //認証情報を持っていない場合は
    if (request.getUserPrincipal() == null) {
      System.out.println("認証情報なしの為、ダミー設定");
      userDto.setUserid("U0001");
      userDto.setUserName("guest");
      return true;
    }

    //
    final KeycloakSecurityContext context = KeycloakPrincipal.class.cast(request.getUserPrincipal()).getKeycloakSecurityContext();
  
    userDto.setUserName(context.getToken().getPreferredUsername());
    userDto.setUserId(String.valueOf(context.getToken().getOtherClaims().get("user_id")));

    //
    return true;
```

keycloak認証の実装については別記事参照。インターセプターで認証情報を取得することで
各Controllerクラスに記述する必要がなくなって汎用性はよくなった。
今まで認証機能はSpringSecurityしか使って来なかったけど、
APIの実装だとSpringSecurityはあんまり適さないみたい。

※ちなみにintercepterTestClass下部でtoString()ではなく、String.valueOfでユーザーIDを
取得しているのは、nullだった時にtoString()だとヌルポで落ちる為。
javascriptで一定時間処理を停止する

## はじめに

初学者による初学者向けの記事となります。

```
筆者が初学者のため、正しくない記述も含まれているかもしれません。
また、１つ１つの説明を省略しています。
本記事を読んで、その場を乗り切った後、
しっかりと Promise, async / await について勉強することを推奨します。
末尾の参考記事を参照してください。
```

javascript の Promise, async / await を勉強し始めました。

await の記述方法が直感的でとても気に入ったので、
いつも await で記述したかったのですが、
記述できるときと記述できないときがあります。

本記事では、「一定時間処理を停止する」という具体例をもとに、
知見を共有したいと思います。

※javascriptで処理の停止はできないため、
　正しくは、 **一定時間後にコールバックする** という表現になります。

## まとめ

await を使って一定時間処理を停止したい場合は、 
**一定時間処理を停止したい場所がasyncの関数内かどうか**
を確認する。


- [asyncの関数内なら、awaitを使って記述する。](#asyncの関数内のsleep処理)
- [asyncの関数内でないなら、awaitを使わず記述する。](#asyncの関数内ではないsleep処理)
  - [asyncの即時関数内を定義して、即時関数内でawaitを使って記述する。（別解）](#asyncの関数内ではないsleep処理の別解)
  - もしくは、一定時間処理を停止したい処理をasyncの関数内に移動する。

await は async の関数内でしか使用することができません。

## 一定時間処理停止（疑似）

### サンプル

CodePenにサンプルを作成しました。
https://codepen.io/sonoshou/pen/RwPxyVB

### asyncの関数内かどうか

本記事では、以下のように定義しています。

#### asyncの関数内

```js
async function () {
  /* asyncの関数内 */
}
```

#### asyncの関数内ではない

```js
function () {
  /* asyncの関数内ではない */
}
```

### asyncの関数内のsleep処理

```js
function mySleep(time) {
  return new Promise( (resolve) => {
    setTimeout(resolve, time)
  })
}

async function asyncMyFunc() {
  console.log("asyncMyFunc:1")
  /* ここで一定時間処理を停止することを考える。 */
  /* asyncの関数内なので、awaitを使う。 */
  await mySleep(2000)  // 2000ミリ秒停止
  /* 停止した以降の処理を記述する。 */
  console.log("asyncMyFunc:2")
}
```

`asyncMyFunc()`を実行すると、以下の通り出力される。

```
asyncMyFunc:1
asyncMyFunc:2
```

### asyncの関数内ではないsleep処理

```js
function mySleep(time) {
  return new Promise( (resolve) => {
    setTimeout(resolve, time)
  })
}

function myFunc() {
  console.log("myFunc:1")
  /* ここで一定時間処理を停止することを考える。 */
  /* asyncの関数内ではないので、awaitを使わず記述する。 */
  mySleep(2000).then( () => {
    /* 停止した以降の処理を記述する。 */
    console.log("myFunc:2")
  })
  console.log("continue...")
}
```

`myFunc()`を実行すると、以下の通り出力される。

```
myFunc:1
continue...
myFunc:2
```

一定時間処理を停止したい方にとっては、
`continue...` は処理されてほしくないですね。

したがって、

```js
  mySleep(2000).then( () => {
    /* 停止した以降の処理を記述する。 */
    console.log("myFunc:2")
  })
```

こちらに記述する必要があります。

### asyncの関数内ではないsleep処理の別解

asyncの即時関数を使えば、awaitは使えます。
こちらの使用も検討しましょう。
しかし、結局、ネストは増えてしまいます。

```js
function mySleep(time) {
  return new Promise( (resolve) => {
    setTimeout(resolve, time)
  })
}

function myFuncAsync() {
  console.log("myFuncAsync:1");
  /* ここで一定時間処理を停止することを考える。 */
  (async () => {
    await mySleep(2000)
    /* 停止した以降の処理を記述する。 */
    console.log("myFuncAsync:2")
  })();
  console.log("continue...")
}
```

`myFuncAsync()`を実行すると、以下の通り出力される。

```
myFunc:1
continue...
myFunc:2
```

## 参考記事
- [async/await 入門（JavaScript）](https://qiita.com/soarflat/items/1a9613e023200bbebcb3)
- [JavaScriptの非同期処理を並列処理と勘違いしていませんか？](https://qiita.com/klme_u6/items/ea155f82cbe44d6f5d88)
- [Promise, async, await がやっていること (Promise と async は書き換え可能？)](https://qiita.com/kerupani129/items/2619316d6ba0ccd7be6a)
Athenaでクエリを発行しようとすると「no viable alternative at input」となる

## 事象

Amazon Athenaのクエリエディタでクエリ（`SHOW PARTITION <table_name>`）を実行すると以下のようなエラーとなる。

- ` line 1:6: no viable alternative at input 'show partition' (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: b8ec4813-f216-4767-88e4-da44da2b223e)`

![image.png](https://image.docbase.io/uploads/638f7f23-5302-45bd-a7cf-6478c44f7292.png)

## 解決

文法の正しくないクエリを実行しようとしていたからだった。

- 誤：`SHOW PARTITION <table_name>`
- 正：`SHOW PARTITIONS <table_name>`

正しいクエリであればエラーなく実行できた。
![image.png](https://image.docbase.io/uploads/09c67984-0473-4b19-8c08-57afca895c9e.png)

以上
UIScreenEdgePanGestureRecognizer が Simulator で反応しない件

# 今回解決したいこと

iOS 7 から追加された `UIScreenEdgePanGestureRecognizer` を使えば、通常のパンジェスチャー(ドラッグジェスチャー)と違って、画面の左端からパンしたときだけに反応するエッジパンジェスチャーを実装することができます。
しかし、なぜかシミュレーターで実行していると、[本当は反応するはず](https://stackoverflow.com/questions/19127383/is-it-possible-to-do-an-edge-swipe-in-ios-simulator) が、反応しない！！！という罠にはまりました。

# 解決法

シミュレーターで、 **ベゼル表示をオン** にすれば画面端からパンすることができます！！！


こう👇（ベゼル表示オフ）
<img width="200" alt="Screen Shot 2020-03-10 at 18.10.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25254/170686f9-1d83-bb96-3d31-a3315c9999e4.png">

ではなくて、
こう👇するってことですね！！（ベゼル表示をオン）
<img width="200" alt="Screen Shot 2020-03-10 at 18.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25254/93e01f4a-bdfc-7f17-dc99-d5d928bb74a0.png">


ベゼル表示は、シミュレーターのメニューからオンにできます👇

`Simulator > Window > Show Device Bezels`

# 関連

- https://stackoverflow.com/questions/19127383/is-it-possible-to-do-an-edge-swipe-in-ios-simulator
- https://developer.apple.com/documentation/uikit/uiscreenedgepangesturerecognizer
全ユーザのcronを綺麗に表示するワンライナー

いつも https://qiita.com/ironsand/items/fb05869080f6ed724816 にお世話になってました(ありがとうございます)

ユーザが多いと `no crontab` なユーザが多くて見難かったので、見やすく表示できるようにしました。

```
for user in $(cut -f1 -d: /etc/passwd); do echo -n :kaigyo1:[${user}]:kaigyo2:;\
 crontab -u $user -l 2>&1 ; done  | grep -v "no crontab" | sed s/:kaigyo1:/\\n\\n/ \
 | sed s/:kaigyo2:/\\n/
```

1行版

```
for user in $(cut -f1 -d: /etc/passwd); do echo -n :kaigyo1:[${user}]:kaigyo2:; crontab -u $user -l 2>&1 ; done  | grep -v "no crontab" | sed s/:kaigyo1:/\\n\\n/  | sed s/:kaigyo2:/\\n/
```

`root` ユーザ限定です。

### 出力イメージ

```
[root@myserver ~]# for user in $(cut -f1 -d: /etc/passwd); do echo -n :kaigyo1:[${user}]:kaigyo2:; crontab -u $user -l 2>&1 ; done  | grep -v "no crontab" | sed s/:kaigyo1:/\\n\\n/ | sed s/:kaigyo2:/\\n/


[a_san]
#Ansible: kirei ni suru
0 6 * * * /bin/bash /home/a_san/hamigaki.sh >> /tmp/hamigaki.log
#Ansible: energy hokyu
10 6 * * * /bin/bash /home/a_san/asa_gohan.sh >> /tmp/asa_gohan.log


[c_san]
#Ansible: miharasi ii
1 10 * * 0 /usr/bin/yamanobori --config /etc/yamanobori.yml /etc/yamanobori_action_file.yml
```
(b_sanは no crontab なイメージ)
C言語のビルドエラー「Undefined external symbol "~"」の自分なり解決法

#イントロダクション
　こんにちは。新米組込みソフトエンジニアのまえぷーです。

　本記事は表題の通り、「**Undefined external symbol "~"**」のエラーが発生した時のデバッグ方法をまとめてみました。

#エラーが発生した時に確認する事
　
- 実態が存在する事を確認
- 参照先ファイルをインクルー―ドしているか確認
- インクルードパスの確認
- リンク順の確認
- プロジェクトに参照先ファイルが追加されているか確認
- プリプロセッサのif文で参照先を選択している場合は、条件式を確認する

#おわりに
　そもそも実態がなかったり、定義し忘れは簡単に見つけることができると思います。しかし、メーカが提供しているライブラリやgithubのコードなど、自作でないライブラリを使用する場合、面倒な参照エラーが発生しやすくなると思います。
　この場合しっかりライブラリのマニュアルを読むことが大切です！
（使い方まで丁寧にかいてあれば...。）
【Udemy Python3入門+応用】　50. 位置引数とキーワード引数とデフォルト引数

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■位置引数
```python:positional_argument
def menu(food, drink, dessert):
    print('food =', food)
    print('drink =', drink)
    print('dessert = ', dessert)

menu('beef', 'wine', 'ice cream')
```
```:result
food = beef
drink = wine
dessert =  ice cream
```
今回はきちんと入力されているが、
`drink`に`ice cream`、
`dessert`に`wine`とあえて間違えみる。

```python:argument
def menu(food, drink, dessert):
    print('food =', food)
    print('drink =', drink)
    print('dessert =', dessert)

menu('beef', 'ice cream', 'wine')
```
```:result
food = beef
drink = ice cream
dessert = wine
```
このような間違いを防ぎたい。

##■キーワード引数
```python:keyword_argument
def menu(food, drink, dessert):
    print('food =', food)
    print('drink =', drink)
    print('dessert =', dessert)

menu(food='beef', dessert='ice cream', drink='wine')
```
```:result
food = beef
drink = wine
dessert = ice cream
```
キーワード引数を設定したことで、順番どおりに書かなくてもきちんとprintされた。

##■デフォルト引数
```python:default_argument
def menu(food='beef', drink='wine', dessert='ice cream'):
    print('food =', food)
    print('drink =', drink)
    print('dessert =', dessert)

menu()
```
```:result
food = beef
drink = wine
dessert = ice cream
```
デフォルト引数を設定した上で、引数を何も渡さないと
設定したデフォルト引数が返ってくる。

```python:default_argument
def menu(food='beef', drink='wine', dessert='ice cream'):
    print('food =', food)
    print('drink =', drink)
    print('dessert =', dessert)

menu(food='chicken', drink='orange juice')
```
```:result
food = chicken
drink = orange juice
dessert = ice cream
```
デフォルト引数を設定した上で、
デフォルト引数から変更したいものだけキーワード引数を渡してやると、
その部分だけ変更されて返ってくる。
pythonコードをコミットする時にflake8で自動リントチェックする仕組み

# 背景
git commit時にリントチェックし、チェックが通らなかったらcommitできないようにしたい。今回は自動フォーマットはしたくなかったので、リントチェックだけするようにした。ちなみに、リントチェック + 自動フォーマットしたい場合はこの辺り → [pre-commit時にformatterを実行する](https://qiita.com/ikura1/items/c104a0a19c8097ac757e)


# やり方

pre-commit + flake8をインストール

```sh
cd $GIT_PROJECT
pipenv install pre-commit
pipenv install flake8
```

pre-commit用のconfigファイルを作成 `.pre-commit-config.yaml`

```sh
repos:
  - repo: https://gitlab.com/PyCQA/flake8
    rev: master
    hooks:
    - id: flake8
```

.flake8用のconfigファイルを作成 `.flake8`

```sh
[flake8]
ignore = E501 # 1行の文字数チェックをignoreにする
; exclude = tests/*
max-complexity = 10
```

`.git/hook/pre-commit` のスクリプトを生成

```
pre-commit install
```

これでpre-commitの設定完了。ここまでくれば各開発者がそれぞれフォーマットできる仕組みを入れればいい。

例えば、VSCodeの場合は以下の記事が参考になる↓
[VSCodeのPython開発環境でpylintの代わりにflake8を導入し自動整形を設定する](https://qiita.com/psychoroid/items/2c2acc06c900d2c0c8cb)