OmniAICreator/Qiita-1.07M huggingface dataset:
[Python, unittest] 標準入出力のテストをする [競プロとかコーディングテストとか]

この記事は[Python Advent Calendar 2020](https://qiita.com/advent-calendar/2020/python)の10日目の記事です。

# 標準入出力でのテストケースってどう書くの？
コーディングテストでアルゴリズムを解く問題に出会ったんですけど，やっぱunittest使ってしゅばっとテストしたいじゃないですか．10行とかある入力を打ちこんで出力n行見比べるとか地獄ですし．けどunittestで標準入力->標準出力のテストの書き方が調べても出てこなかったので作りました．また，標準エラー出力も拾います．

では，みていきましょう！
急いでいる方は一番最後へどうぞ．
また，ツッコミや修正などありましたら，コメントいただければと思います．

# 想定
同一ディレクトリ内に，
- main.py: 実行したいPythonファイル
- test.py: テストのためのPythonファイル
があるものとします．

また，テストには標準ライブラリであるunittestを使います．実行環境はPython3.7ですがおそらくだいたい動くでしょう．あまりに古いとsubprocessの中身が違って `subprocess.Popen` がないとかはあるかもしれません．

# やりかた
結局はいかに標準入力をして，標準出力・標準エラー出力を回収するか，だと思います．しかも，競プロとかコーディングテストだとやっぱり

```bash
python main.py
```
って呼び出した結果をテストしたいですよね．そこで，`subprocess`の出番です．子プロセスを作ってしまいます．

そのために使うのが `p = subprocess.Popen` と `p.communicate`です．

1つ目のポイントはプロセスを作るときに標準入力・標準出力・標準エラー出力をパイプを用いてこの`test.py`とつなげてしまうことです．`['python', 'main.py']`みたいな代わりに`shell=True`を使うかとかはご自身の方針や用途に合わせてご決定なさってください．

2つ目のポイントは`o, e = p.communicate(input=param[0].encode())`の部分でしょう．標準入力をテストのパラメータを利用し(`input=param[0].encode()`)，標準出力(`o`: outputのつもり)・標準エラー出力(`e`: errorのつもり)を回収します．標準入力・標準出力・標準エラー出力に関してはすべてエンコードやデコードが必要なことに注意が必要です．つまりこの段階の`o, e`はデコードする必要があります．

# テストしよう
個人的にはこれでいいかな，となりました．

```python
self.assertEqual(e.decode(), "")
self.assertEqual(o.decode().strip(), str(param[1]))
```

つまり，
- エラーがない，つまり標準エラー出力が空っぽ: `self.assertEqual(e.decode(), "")`
- 答えが正しい: `self.assertEqual(o.decode().strip(), str(param[1]))`
標準出力・標準エラー出力はデコードが必要なことと，標準出力は問答無用で`str`なのでそこに気を付ければいいかなと思います．

# 完成
最終的にはこんな感じになりました．
こうしてやれば，入出力が複数行あっても楽ちんです．改行文字いれてやればいいですもんね．


```python:test.py
import subprocess
from unittest import TestCase, main


class MyTestClass(TestCase):
    def _std_test(self, param):
        p = subprocess.Popen(
            ['python', 'main.py'],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        o, e = p.communicate(input=param[0].encode())
        if o.decode().strip() != str(param[1]):
            print(o.decode())
        self.assertEqual(e.decode(), "")
        self.assertEqual(o.decode().strip(), str(param[1]))

    def test_case(self):
        """
        標準入力するものや期待される標準出力はダミーデータです
        """
        params = (
             ("input_1", "answer_1"),
             ("input_2\ninput_2_2", "answer_2\nanswer_2_second"),
        )

        for param in params:
            with self.subTest(param=param):
                self._std_test(param)
```

参考になれば幸いです！
jupyter の出力のみを pdf にエクスポートする方法

# 概要

jupyter のノートブックの出力のみ（すなわちコード以外）をpdfに出力します．

jupyter notebook, jupyter lab どちらも同じ手順です．

# 手順

１．pdfに変換したいノートブックを作る

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193401/0028549a-d3e7-1b85-85c0-7a7ba541bdc5.png" width=600>

２．`File` > `Download as` > `HTML` で.htmlファイルをダウンロード
（Jupyter Labの場合，`File` > `Export Notebook As` > `Export Notebook to HTML`）
３．ダウンロードしたhtmlファイルをブラウザで開く（以下, ChromeかFirefoxを想定します）
４．`F12`で開発ツール（デベロッパーツール）を開く
５．コンソール（Consoleタブから開ける）で以下のコードを実行する

```
document.querySelectorAll("div.input").forEach(function(a){a.remove()})
```

![Screenshot from 2020-12-02 18-04-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193401/b8db77cc-21a3-ec51-8efb-f5d35a9ecbd5.png)

６．ブラウザの印刷機能でpdfを出力する．

以上です．

# 参照

- [export notebook to pdf without code [duplicate]](https://stackoverflow.com/questions/34818723/export-notebook-to-pdf-without-code)
なでしこ3で「ここまで」で書くのだるいよね

現在、日本語プログラミング言語「なでしこ」にはWindows版のなでしこv1と、Webブラウザ/Node.jsに対応しているなでしこv3があります。なでしこはv3とv1で文法が大きく違う点があります。それが、v3ではインデントによるブロック構文を使わないことです。

それで条件分岐などブロックの末尾には「ここまで」と書くことになります。しかし、「ここまで」と書くことがだるいという声も多く、先日のバージョンアップで省略できるようになりました。その詳細を紹介します。

- 2022/09/05: v3.3.66 でインラインインデント構文に磨きをかけました。
- 2020/12/24: v3.1.11 でインデント構文を微修正しました。

# なでしこv1/v3で条件分岐の書き方の違い

なでしこv1で条件分岐を書くには以下のように書きます。ブロックはインデントで表現します。

```挨拶v1.nako
もし、今＞「12:00:00」ならば
　　「こんにちは」と表示。
違えば
　　「おはよう」と表示。
```

これを、なでしこv3で書くと以下のようになります。ブロックはインデントではなく「ここまで」と書くことで表現します。

```挨拶v3.nako3
もし、今＞「12:00:00」ならば
　　「こんにちは」と表示。
違えば
　　「おはよう」と表示。
ここまで。
```

ほとんど同じなのですが、違うのはブロックの末尾に「ここまで」があることです。

最近の日本語入力は、途中まで入力すると、予測入力が可能なので、なでしこv3のプログラムを数回書くと「ここ」とタイプすると「ここまで。」と補完してくれることでしょう。

## インデント廃止の経緯

実際、なでしこのプログラムを掲示板などに貼り付けた時やWeb媒体のコラムでプログラムが紹介された時、ただしくインデントが保持されず、エラーで動かないという事が多かったのです。それで、Webを対象にした「なでしこ3」ではインデント構文を廃止したという経緯があります。


# でも「ここまで」と打つのがだるい

それでも、なでしこv1のエレガントなインデント表現になれてしまっている方には「ここまで」と入力するのが苦痛である、とてもだるいという声もありました。（これ、Pythonに慣れると、Rubyのendを入力するのがだるくなるのに近い感覚でしょうか？？？）確かに「ここまで」がない方がプログラムはスリムです。


## 「ここまで」と打たなくても良くなった？！

そこで、なでしこv3.1.5(v3.1.11で修正)では、プリプロセス処理で、インデント構文をエミュレートするように修正しました。「ここまでだるい」と言い続けてきた皆さんに朗報です！（そして貴重なご意見に感謝です。）

それで、プログラムの冒頭に「!ここまでだるい」あるいは「!インデント構文」と書くと、インデントによるブロック表現が可能になります。なでしこv3の[『簡易エディタ』](https://nadesi.com/doc3/go.php?10)でも試すことができます。

```挨拶(v3.1.11以降).nako3
!インデント構文
もし、今＞「12:00:00」ならば
　　　　「こんにちは」と表示。
違えば
　　　　「おはよう」と表示。
```

あるいは、末尾にコロン「：」を書くと、インラインインデント構文が適用され、字下げをやめたところに、自動的に「ここまで」が挿入されます。

```挨拶(インラインインデント構文).nako3
もし、今＞「12:00:00」ならば:
　　　　「こんにちは」と表示。
違えば:
　　　　　　「おはよう」と表示。
```

単純な場合だけでなく構文を入れ子にした場合も正しく動きます。

マイナビニュースに掲載されている[「うるう年判定のプログラム」](https://news.mynavi.jp/article/nadeshiko-41/)もエレガントに記述できます。

```閏年判定.nako3
!ここまでだるい
西暦年は2019。
結果は「平年」
もし、(西暦年を4で割った余り)が0ならば
　　結果は「うるう年」
　　もし、(西暦年を100で割った余り)が0ならば
　　　　結果は「平年」
　　　　もし、(西暦年を400で割った余り)が0ならば
　　　　　　結果は「うるう年」
結果を表示。
```

ただし、基本的になでしこ3はインデント構文を採用しているわけではないので、内部では単純な置換処理によってエミュレートされているという点を忘れないようにする必要があります。もし、うまく変換されていなければ、[GitHubのIssue](https://github.com/kujirahand/nadesiko3/issues)か、あるいは、[各種SNSなどで](https://kujirahand.com/wiki/go.php?10)にてご報告ください。また、v3.1.5ではエラーがあったときの行番号が「ここまで」が自動挿入された分だけずれてしまいます。この問題は既に修正済みです(2020/12/05のv3.1.8にて修正)。

# まとめ

なでしこv3.1.5(v3.1.11で修正)以降、なでしこv1との文法互換性が向上しました。もし世の中に「!ここまでだるい」が溢れるようになれば、今後のなでしこのバージョンではインデント構文を復活させる可能性もあります。


今後とも、なでしこの開発を頑張りますので、応援よろしくお願いします。

# 参考

なお、インデント構文やその他の文法については、マニュアルにまとまっています。

- [なでしこ3 - 文法/インラインインデント構文](https://nadesi.com/v3/doc/go.php?1178)
- [なでしこ3 - 文法/インデント構文](https://nadesi.com/v3/doc/go.php?949)
- [なでしこ3 - 変数について](https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E5%A4%89%E6%95%B0&show#:~:text=https%3A//nadesi.com/v3/doc/go.php%3F930)
Rubyの基礎[1]



# rubyのStringsの表示

| method | 使用状況                            |
|:-------|:------------------------------------|
| print  | 普通に使う．要改行                  |
| puts   | 次に普通に使う. 自動改行            |
| p      | codingの最中にdebugがわりに打ち出すとき|
| pp     | pのpretty print, require 'pp'が必要 |
| printf | cのがあります．formatを整えるときに便利|

ect

文字列を囲む' 'と" "のわかりやすい違いは，
" "だと特殊文字の機能(改行\nみたいな)を使えるけど,' 'だと使えない.
他にも表示に違いがあるらしい.

**ダブルクォーテーション**

```ruby
$ puts "改\n行"
改
行
```

**シングルクォーテーション**

```ruby
$ puts '改\n行'
改\n行
```


# hello\_worldを表示する

    Hello world.

と表示するプログラムから


### 解説

まずは，emacsでプログラムを書くファイルを開く，

    $ emacs hello_world.rb                                               

表示したい文字列(Hello world.)を''で囲って，

```ruby
puts 'hello world'
```

を書けたら，C-x,C-s(保存)してC-x,C-c(終了)

    $ ruby puts_hello_world.rb

と打ち込み実行．


# ARGV[0]を使う


## お題

    $ ruby hello_name.rb Rudy

と打ち込んだ時に，

    Hello Rudy.

と返すプログラムを書いてみる.


## 簡単な解説

putsしたら普通はgetsだが，目的の一つであるshell環境ではcommand line interfaceで作業をするためにARGV[0]というのを使って行く．*hello\_name.rb* に書き込む．

```ruby
puts ARGV[0]
```

実行してみる．

    $ ruby hello_name.rb Rudy
    Ruby


### Hello Rubyとするために

これらが方法としてあるらしい

| puts  | puts "Hello " + ARGV[0]         |
|:------|:--------------------------------|
| puts  | puts "Hello #{ARGV[0]}"         |
| print | print "Hello #{ARGV[0]}\n"      |
| print | print "Hello " + ARGV[0] + "\n" |


## 解説

*hello\_name.rb* を書き換えて

```ruby
puts "Hello #{ARGV[0]}"
```

実行してみる.

    $ ruby hello_name.rb Rudy                                                   
    Hello Ruby                                                                        


# redirect


### txtへ出力させる

    ruby hello_name.rb Ruby > hello_name.txt

としてhello\_name.txtに結果を出力させることができる.実行する度に内容は上書きされる．

**'>'は，出力先を指定したtxtに変更(re-direct)するshellの機能**

    : cat hello_name.txt

で中身をcat(con-cat-inate)できる．


# よく使うやつ復習


### emacs

|         |                                     |
|:--------|:------------------------------------|
| C-x,C-s | 保存                                |
| C-x,C-c | 終了                                |
| C-z     | 一時中断                            |
| fg      | 一度中断したprocessを再度起動させる |
| ps      | processの状況を確認                 |


### shell

|       |                          |
|:------|:-------------------------|
| mkdir | ディレクトリ作成\\       |
| cd    | カレントディレクトリ変更 |
| cat   | ファイルの内容を表示     |


# 参考

-   [シングルクォーテーションとダブルクォーテーションの違い（Rubyの文字列）](https://qiita.com/ryosuketter/items/ddad508cb0124e4fe378)



------
 - **source** ~/Desktop/grad_members_20f/members/mm-cell/post_org/c1_puts.org
【Swift】型のキャストについて

#キャスト とは

キャストとは、値の型を確認し、可能であれば別の型として扱う操作のことです。
型のキャストは、**階層関係にある型どうし**で行います。

プログラミングにおける階層関係とは、上の階層にあるものほど抽象的で、
下の階層にあるほど具体的な内容になります。

例えば、一番上の階層に料理があったとすると、
料理
　|ーイタリアン
　|　　|ーパスタ
　|　　|　　|ーペペロンチーノ
　|　　|　　|ーミートソース
　|　　|
　|　　|ーピザ
　|　　　　|ーマルゲリータ
　|　　　　|ーペスカトーレ
　|
　|ー和食
　　　|ーうどん
　　　|　　|ー讃岐うどん
　　　|　　|ー稲庭うどん
　　　|
　　　|ー蕎麦

といった感じに、下の階層に行けば行くほど具体的なものになります。
そして、**階層関係にあるものどうしをキャストすることができます。**

なので、うどんは料理として扱うことができますし、
イタリアンをミートソースとして扱うこともできます。

**しかし、階層関係にないものはキャストできません。**

先ほどの例でいうと、
稲庭うどんをピザとして扱うことは階層が違うのでできないということです。

##アップキャスト
アップキャストは、階層関係がある型どうしにおいて、
階層の下位となる具体的な型を階層の上位の抽象的な型に変換することができます。

アップキャストを行う際には**as演算子**を使用します。
as演算子の左側には下位の型を指定し、右側には上位の型を指定します。

階層関係にない型どうしはコンパイルエラーになります。

```swift

let hello: String = "こんにちは"   // String
let a = hello as Any   // こんにちは
let b = hello as Int   // コンパイルエラー
```
Any型は全ての型が暗黙的に準拠しているプロトコルなので、
全ての型はAny型にアップキャストすることが可能です。

また、重要なのが、
`let hello: String = "こんにちは"`にて、定数helloはString型なので、
String型に備わっている機能を使用することができますが、

`let a = hello as Any`の定数aはAny型として扱われるので、
String型に備わっている機能を使用することができません。

##ダウンキャスト
ダウンキャストとは、階層関係のある型どうしにおいて、
階層の上位となる抽象的な型を下位の具体的な型として扱う操作になります。

アップキャストにおいては、具体的な型を抽象的な型として扱うので、
コンパイル可能な（= 階層関係にある）アップキャストは常に成功する操作でした。

**しかし、ダウンキャストはコンパイル可能でも失敗する可能性があります。**

ダウンキャストに使用する演算子は、**as!演算子**と、**as?演算子**の２種類があります。
また！と？だよ・・・。ややこしい！と思うかもしれませんが違いは簡単で、
それぞれの演算子の違いは失敗時の動作にあります。


###as?演算子
as?演算子は失敗した時にnilを返します。
as?演算子の結果は、キャスト先の型の値かnilになる可能性があるため、
Optional\<Wrapped>型になります。

```swift

let a = 1 as Any   
let b = a as? Int   // Optional(1)
let c = a as? String   // nil
```
Any型にアップキャストする前の型がInt型であるため、
Int型にダウンキャストする際はキャストに成功します。

しかし、String型にダウンキャストする場合は、
Int型とString型で階層関係にないのでキャストが失敗しnilが渡されます。

###as!演算子

as!演算子は強制キャストとも言われるダウンキャストです。
as?演算子と違い、失敗した際にはnilを返さずにエラーが発生します。


```swift

let a = 1 as Any
let b = a as! Int
let c = a as! String   // 実行時エラー
```

エラー内容：`error: Execution was interrupted, reason: signal SIGABRT.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.`

ダウンキャストに失敗した場合はプログラムの実行が継続されないので、
**Optional\<Wrapped>型ではなくWrapped型になります。**

つまり、通常のInt型やString型と同じ扱いです。

```swift

let a = 1 as Any
let b = a as? Int   // Optional(1)
let c = 1 + b   // コンパイルエラー

let a = 1 as Any
let b = a as! Int   // 1
let c = 1 + b   // 2
```

as?演算子は、値がない時にnilを返すので実行時エラーが発生しないため比較的に安全ですが、
nilが関わる以上は、オプショナルバインディングや？？演算子などの
nilを考慮した処理を記述する必要があるかもしれません。

一方、as!演算子は実行時エラーは発生しますが、nilを考慮する必要がありません。

失敗しないことが保証されている場合はas!演算子でいいと思いますが、
基本的にはas?演算子を使用した方が安全かもしれませんね。

以上、最後までご覧いただきありがとうございました。
Angularをゼロから勉強してみる

Angularをゼロから勉強してみます。

AngularとAngular.jsは別物なんですね。

##そもそもAngularの役割とは

主な役割は４つです。

-　ビューをレンダリングする
-　変更検知
-　ルーティング
-　Ajaxの機能


それぞれ見ていきましょう。

###ビューをレンダリングする
データをHTML化する

###変更検知
データ変更時のMODELとDOM連携がGOOD

###ルーティング
ビューを変更する

###Ajaxの機能
サーバーへのアクセスが優れている


##公式を読む

公式を読みます。
[公式ドキュメント](https://angular.jp/docs)


……んんん？？わ、わからん……！！
テンプレートとコンポーネントあたりはなんかわかる気がするが……。なるほど

SSRをしたりできるわけね、ふむふむ……。

ツアー・オブ・ヒーローズ アプリケーションとチュートリアルはスキップ！！

[用語集](https://angular.jp/guide/glossary)も読もう。

いや多すぎる、全部はむりだ。

###まずはモジュールについて

NgModuleとはなんぞ？
なんか色々とライブラリと連携が取れる機能みたいですな。
これぞAngularの特色と言ってもいいみたい。
ライブラリをnpmでインストールし、JavaScriptのimportステートメントでそれらの一部をインポートして使っていくみたい。
NgModuleはインジェクターとコンパイラを設定し関連するものをまとメルものでもあるらしい。ふむふむ。

フィーチャーモジュールとは？
わからん。

フィーチャーモジュールの遅延ロードとは？
わからん。

モジュールに依存オブジェクトを提供する？？
わからん。

シングルトンサービス？？
わからないなあ。

ツリーシェイキング可能なプロバイダー??
わからないなあ。

すべてのアプリケーションには、少なくとも1つのAngularモジュール（rootモジュール）があり、 起動時にアプリケーションをブートストラップするために存在する必要があります。 慣例により、それは通常AppModuleといわれるみたいです。

###コンポーネント

コンポーネントの部分も読んでみます。
Angularテンプレート構文要素（{{hero.name}}、(click)、[hero]、<app-hero-detail>）というのがあるらしい、なるほど……。Vueでいうv-ifとかに該当するものかな？

すべてのAngularアプリケーションには、少なくとも1つのコンポーネントがある……とのことです。ふうん。

このコンポーネントでテンプレートおよび関連するコンポーネント固有のメタデータを提供しています。ちなみにテンプレートにはHTMLと、HTML要素を表示する前に変更できるAngularマークアップがあります。

###ルーティング

こんな感じ↓のことをルーティングはやります。

- アドレスバーにURLを入力するとブラウザが対応するページに移動
- ページ上のリンクをクリックするとブラウザが新しいページに移動
- ブラウザの前後のボタンをクリックするとブラウザはあなたが見たページの履歴を前後にナビゲート

###ディレクティブ
Angularがレンダリングすると、ディレクティブの指示にしたがってDOMが変換されます。つまり「データ変更時のMODELとDOM連携がGOOD」なAngularの特製の一つを実現するために必要な機能ですね。


###パイプ
テンプレートHTMLの表示値変換を宣言。
なんのことかわからん……。

##YouTubeを見てみる

以下のユーチューブを見てみます。

[これからはじめるAngular](https://www.youtube.com/watch?v=l4x8b0LdkUk)

いや〜やっぱりYouTubeはわかりやすい。
先にYouTube見ればよかった。

##Angular After Tutorial

次は以下のサイトを見ます。

[Angular After Tutorial](https://gitbook.lacolaco.net/angular-after-tutorial/)

ふむふむ……。勉強になるな……。
単一責任原則にのっとって「コンポーネントは１機能を持つ状態までに分割される」べきだそうな。

RxJSというライブラリの説明で、Observable……というのが出てきたけど、これなんだ？有限と無限のものがあるそうな。

インターセプターというのも登場。
うーん、わからない。

アプリケーションコンフィグの管理という項目もありました！！これはAngularの特色である「データ変更時のMODELとDOM連携がGOOD」ですね！これを実現するために抽象クラスなどを使用。プロバイダーは、アプリケーションのエントリポイントにおくべき。プロバイダの種類は提供したいものが何かによって変わります。オブジェクトなら値プロバイダー、などなど……。
##結論

理論だけ見てもなんのこっちゃですね。
YouTubeいいよ、YouTube。
Laravelのモデルのリレーション先のモデル(親/子)までまとめて削除する

<h3>モデルとコントローラーの編集</h3>

```Model.php

class Artist extends Model
{
    //このアーティストが所有するタグ(子1へのリレーション)
    public function tags()
    {
        return $this->hasMany(Tag::class);
    }
    //このアーティストが所有する作品(子2へのリレーション)
    public function works()
    {
        return $this->hasMany(Work::class);
    }
}
```

```Controller.php
    public function destroy($id)
    {
        $artistEdit = Artist::findOrFail($id);

            if (\Auth::id() === $artistEdit->user_id) {
                
                //子供1リレーション（タグ）を削除
                $artistEdit->tags()->each(function ($tag) {
                    $tag->delete();
                });
                
                //子供2リレーション（作品）を削除
                $artistEdit->works()->each(function ($work) {
                    $work->delete();
                });

                //アーティスト（親）を削除
                $artistEdit->delete();
        
                return redirect('/');
            }
            else{    
                return redirect('/');
            }
    }
```
<h3>解説</h3>

each は Illuminate\Database\Eloquent\Collection ではなく、Illuminate\Support\Collection クラスのメソッドです。

多対多の場合は、リレーション先のモデルというよりも、 中間テーブルのモデルの操作 となりますので今回のケースが当てはまらない場合もあるかと思います。
ハーフ・レディング算出用の SCSS の mixin

## line-height による余白
「セクション間は 50px 空けたい」という場合、`margin-top: 50px;`という指定をすると50px以上空いてしまいます。

これは `line-height` の仕様により、以下のように行の上下に `line-height - font-size` から算出された値が割り当てられるからです。

![half-leading.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298406/b74d23a7-1cc4-4241-e7b3-a1d13dd78519.png)

この例の7pxの部分をハーフ・レディングと呼びます。
そのため、50px に 7px が加わり、57px の余白になってしまいます。

## 解消方法

厳密に余白を設定したい場合は、以下の設定をする必要があります。

- `margin-top: 43px;` を設定する
- `margin-top: -7px;` を見出しに設定する

しかし、どちらにしても毎回計算をするのは面倒なため、ハーフ・レディング用の mixin を作成し、計算を自動化しておくと効率が上がります。

## mixin の作成

```scss:_mixin.scss
@mixin lineHeightCrop($fontsize:16, $lineFeed:24) {
  $lineheight: $lineFeed / $fontsize;

  &::before,
  &::after {
    display: block;
    width: 0;
    height: 0;
    content: "";
  }

  &::before {
    margin-top: calc((1 - #{$lineheight}) * 0.5em);
  }

  &::after {
    margin-bottom: calc((1 - #{$lineheight}) * 0.5em);
  }
}
```
```scss:hoge.scss
.hoge {
  font-size: 1.5rem; // 24px
  @include lineHeightCrop(24, 38);
}
```

![スクリーンショット 2020-12-02 17.31.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298406/e8f25a1d-9dee-bcd5-5e0f-5454325d92b2.png)

Photoshop からコーディングを行う場合は、フォントサイズの 24px を第一引数に、行送りの 38px を第二引数に入れます。

## 最後に
厳密には、前のセクションがテキストで終わっている場合はそのテキストと、次のセクションの見出し等のテキストに設定する必要がありますが、前のセクションのテキストは影響が小さい場合などは割愛してもよいかと思います。

また、Windows10 / IE11 及び Edge では正常に動作しました。

尚、この minin は以下の記事を参考にしています。
上記 mixin では、line-height の計算をするのを省きたいので、Photoshop の数字を直接入力できるように変更しています。
mixin を作るメリットなども詳細にまとめてあり参考になります。

参考：[line-heightの不要な上下の余白を打ち消して、デザインデータに沿ったコーディングを効率化する方法](https://yuyakinoshita.com/blog/2020/01/20/line-height-crop/)
bind()でエラーが出はります (Xcode for Mac )


## どないしたん
Mac用で作ったのUDPのCプログラムなのですが
ソケット通信で　bind()関数でエラーが返ってきてダメだとおっしゃる。

### どんな環境でしたん
OS : macOS Catalina
Xcode : 12.2

### エラーは、なんでしたん
errnoは、１　で　"Operation not permitted"
"操作は許可されてません"

### どないすんのん？
ググりまくって
見つけたのは、”Entitlements”に資格を設定するんだとかなんとかで
どうも　Xcodeの PROJECTのTARGETSのタブにある　Signing & Capabilities のようです。

![スクリーンショット 2020-12-02 17.10.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75082/fa2ee2eb-c1ff-533d-a8c6-4b77c98a068b.png)

ここの　App Sandboxの　Network で　
Incoming Connections(Server) のチェックをするとエラーがでなくなりました。
このチェックの下に
Outgoing Connections(Client) のチェックがないと送信が遮断されるようです。

忘れないうちに残しておきます。
[OpenCV]動画を表示する方法

#はじめに
OpenCVによる画像処理の基礎を整理します。
100本ノックのように、毎日追加していきたいと思います。

#やりたいこと
mp4の動画ファイル、WebCamからの映像をパソコン画面上に表示したいと思います。

#プログラム構造

cv2.VideoCapture()を利用します。

```Python
#動画ファイル
cap = cv2.VideoCapture('video.mp4')
#内臓カメラ
cap = cv2.VideoCapture(0)
#USBカメラ
cap = cv2.VideoCapture(1)
```

そして、cap.read()から動画のフレームをimgに入れ、それをimshow()で表示します。
このプロセスをWhile文を利用して繰り返し実行します。←ここがみそ。

```Python
while True :
    ret, img = cap.read()
    cv2.imshow('Video', img)
```

#実行結果

![bandicam-2020-12-02-17-27-43-031.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/85897748-f716-6a35-ecd2-54f4da5bc4fa.gif)

#まとめ
1. cv2.videoCapture(), while文でビデオ映像を画面に表示する方法を確認しました。

#全体コード
```Python
import cv2

# Video
frameWidth = 640
frameHeight = 480

#Video Source
#cap = cv2.VideoCapture('videos/traffic.mp4') #自分のmp4のpathを入力
cap = cv2.VideoCapture(0)



while True:
    ret, img = cap.read()
    img = cv2.resize(img, (frameWidth, frameHeight))
    cv2.imshow('Video', img)
    print('ret=', ret)

    # qを押すと止まる。
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break


```
#おまけ
cv2.imshow()で表示されたウィンドウを拡大すると画素のRGB値が確認可能です。
![Video_screenshot_02.12.2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/f4b7231d-7c40-4a65-7c18-326ce46b5320.png)
Zealous System to Support Businesses Across India and the World | Zealous System

![facebook-Banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278252/252a46d7-ed3e-4127-5c74-fc31114365c8.png)

Unfortunately, small businesses throughout the world and also in India are striving as a result of the COVID 19 pandemic, lockdown, and ensuing economic distress. Here at Zealous System, we have been assisting small businesses with all sorts of technological development solutions in order to rise from this time stronger than ever.

Zealous System is globally renowned for work to serve businesses with web and mobile app development. We’re distinguished for our exemplary customer satisfaction, acknowledged on sites like The Manifest! Although we help businesses of all aspects and sizes from across a variety of industries, over half of our satisfied clients are small businesses! As a small business ourselves, we aspire to take the time to boost small businesses.

We’re incredibly appreciative to all of our satisfied customers! If you want to join their ranks, feel free to contact us today! https://bit.ly/2ZN1X93
[Ranorex] Tips : How to set global parameter by excel data 

# Back Ground
RanorexはWebのE2Eテスト自動化ツールである。
１プロジェクトに対して、統一したグローバルパラメータを定義している。
環境の情報や、共通のユーザー情報などを定義することに主に使われる。

複数のテスト環境条件で実行することになると、テストの都度、このグローバルパラメータを編集する必要が発生する。
そのため、パラメータの変更作業が発生する。特に、テスト自動化のファイルを複数のJENKINSにて実行するように配置していると、それぞれの実行定義ファイル（rxtstファイル）を編集しなければならず、大変に工数が発生する。

今回、この課題を解決するために、このグローバルパラメータをexcelで定義し、excelの設定値でグローバルパラメータを修正するtipsを説明する

global parametersの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/b50342c0-0e67-c500-dae9-527dabc61a04.png)


# How

1. Prepare Data Source

以下の図のように、グローバルパラメータ名のparameter_name と、設定とする値parameter_valueをエクセル等でdata sourceで定義する。
そして test case folderを作成し（図では、SetGlobalParameter）、data source を指定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/c214a1e0-57d1-6d8b-f2f7-0a1670f593ce.png)

2. modify parameter script

上図のレコードモジュールCommon_SetGrobalParameterを作成する

このレコードモジュールは以下のように１つのuser codeを呼び出すだけの処理である

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/e08ff1e5-2d1a-5eb0-0cdf-e9329392af91.png)

また、このレコードモジュールのVALIABLESは以下の図の通り、先ほどのdata sourceで定義した、parameter_name と parameter_value である。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/c54f9e2c-1816-f547-a569-b4d5fe69aabc.png)


このユーザー関数setUpGlobalParametersは以下のとおりである。
グローバルパラメータの変数名にparameter_name が定義されていたら、parameter_value に置き換える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/206b25c2-99ee-3c85-5be5-11e2a5c4c273.png)



これにより、グローバルパラメータをファイルに外だしすることができる！
【超単純】SwiftのTimerクラスで、カウントダウンを実装してみた。

みやこです。
swiftでタイマーを利用したかったが、便利そうなライブラリが見つけられなかったので、
標準のTimerクラスを利用して実装してみました。

アプリの実際の様子　→　https://youtu.be/4K0OmSMkfDU

主に次のn個のメソッドで作られています。
1. startTimer・・・タイマーをスタートさせる
2. updateTimer・・・タイマーが回っている途中、変数の内容を更新させたり、ラベルに反映させたりする。
3. setUpTimer・・・タイマーの最初の設定を行う。変数の初期化とラベルへの反映
4. resetTimer・・・タイマーをリセットするメソッド。


<h1>ソースコード</h1>

```swift:変数の定義
//Timerクラスを利用する
    var timer = Timer()
    
    //秒と分の変数を用意
    var seconds:Int = 0
    var minutes:Int = 0
    var limit = 25 //これは制限時間です。
    
    //分のタイマーラベル。
    @IBOutlet weak var minuteLabel: UILabel!
    //秒のタイマーラベル。
    @IBOutlet weak var secondLabel: UILabel!
```

```swift:1.startTimer()
//タイマーをスタートさせるメソッド
    @IBAction func startTimer(_ sender: Any) {
        setUpTimer()
        timer.invalidate() //timer = nilのイメージ。
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.updateTimer), userInfo: nil, repeats: true) 
        //↑1秒毎に自分のupdateTimerメソッドを繰り返し呼び出す。
    }
```

```swift:2.updateTimer()
//startTimerメソッドで、繰り返し呼ばれるメソッド
    @objc func updateTimer() {
        seconds -= 1
        if seconds <= -1{
            minutes -= 1
            seconds = 59
        }
        if minutes == 0 && seconds == 0{ //タイマーが終わったら・・
            resetTimer((Any).self)
        }
        if seconds < 10 { //10秒未満だったら、09, 08という風に表示する。
            secondLabel.text = String("0\(seconds)")
        } else {
            secondLabel.text = String(seconds)
        }
        minuteLabel.text = String(minutes)
        
    }
```

```swift:3.setUpTimer()
func setUpTimer() {
        seconds = 0
        minutes = limit
        if seconds < 10 {
            secondLabel.text = String("0\(seconds)")
        } else {
            secondLabel.text = String(seconds)
        }
        minuteLabel.text = String(minutes)
}
```

```swift:4.resetTimer()
//リセットボタン
    @IBAction func resetTimer(_ sender: Any) {
        timer.invalidate()
        setUpTimer()
    }
```


<h1>さいごに</h1>
limitの値ををユーザーが指定できるようにすれば、自由に時間を計ることが可能ですし、
タイマーが終わった時になんらかの処理を書けば、通知を入れることも可能なので、
いろいろ応用ができると思います。ひよっこのコードですが、参考にしてみてください！！！

みれくれてありがとうございました。
阿部寛のホームページ的開発エッセンス

## 社内託児所の授乳室の話

昔、弊社の社内託児所を利用していて、娘（第一子）、息子（第二子）を勤務中授乳しながら通勤していた。

託児所の授乳室には「使用中」「空いてます」の札がかかっていた。

授乳室の定員は２名。混雑していると３人かぶる可能性がある。

つまり「使用中」の札がかかっているときに、「満員」なのか「１人は入れます」なのかの区別がつかない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/c5d5b275-54f1-9de8-433a-b115ff6d2e98.png)


## システム的に考えると

作りたい屋さんは「使用中」の `true/false` に加えて「定員」にたいする残量、「満員です」の判定が必要だしもしかしたら５分待てば終わるのか１０分待つのか勤務中もしかしたらわかったほうが嬉しいなんてことを考え出す（皆同じオフィスのワーキングマザーなのだ）

だがシンプルな解決策って「札でどうこうする」というより「今、はいっても大丈夫～？の一声をユーザー側で発してその場で判断してもらう」だったりする。

その会話により「あ、もう終わるよ～」かもしれないし「ごめんもう少し～」かもしれない。

いやまて、そもそもカーテンが締まっている時点で誰かが使用中なのだから、「使用中」「空いてます」の札は要らないのである。システム自体要らなかったのかもしれない。


## 阿部寛のホームページ

 [なぜ阿部寛のホームページはベストを尽くさないのか。](https://qiita.com/mackey0022/items/0258ceddc7acd8626332)

のエッセンス

- 阿部寛のホームページはWebサイト界のらくらくホンなのかもしれない
- 本質的ニーズを捉えておく
- エゴに消費者を巻き込んではいけない

と開発物の目的の考え方。開発者の「つくりたかっただけ」では問題を解決しないこともあるという話を思い出したので書いておく。

### 2022年追記

[海外のガチHTMLコーダーに阿部寛のホームページを見てもらった - Qiita](https://qiita.com/NagayamaToshiaki/items/b56380aecf55803f52a5)
[「阿部寛のホームページ」はHTML界のシーラカンスである - Qiita](https://qiita.com/NagayamaToshiaki/items/dd36acb2658220c04b94)


以上です～
クリック時にブラウザのアラートを表示させる【blade】

<h3></h3>

```script.js
function delete_alert(e){
   if(!window.confirm('本当に削除しますか？')){
      window.alert('キャンセルされました'); 
      return false;
   }
   document.deleteform.submit();
};
```

<h3></h3>

```blade.php
@if($roletype_id <= ($item->roletype_id))
  <form action="/users/{{$item->id}}" method='post'>
       {{ csrf_field() }}
       {{ method_field('DELETE') }}
           <input type="submit" name="delete" value="削除" onClick="delete_alert(event);return false;">
  </form>

----------------------------------------------------------------------------------------------------------

{!! Form::model($workEdit, ['route' => ['artist.destroy', $workEdit->id], 'method' => 'delete']) !!}
{!! Form::submit('作品を削除', ['class' => 'btn btn-danger','onclick' => 'delete_alert(event);return false;']) !!}
{!! Form::close() !!} 


@endif
```

<h3>解説</h3>
app.js にDeleteボタンをクリックしたときに呼び出すファンクションを記載します。

window.confirmはメッセージと、OK と キャンセルの 2 つのボタンを持つモーダルダイアログを表示します。
if(!window.confirm() で【キャンセル が選択された時】という意味になります。※！で否定しているから

つまりは『キャンセルされたら[キャンセルされました]を表示。そうじゃなかったらsubmitしてね』となります。
Anaconda Navigatorが起動しないとき

# Anacondaとは？  
[Anaconda](https://www.anaconda.com/) 「データサイエンス」や「機械学習関連アプリケーション」のためのPythonおよびR言語用のディストリビューションであり、科学計算に重点を置くオールインワンのインストラーです。  

# Anaconda Navigatorアイコンをクリックしても起動しないとき  
Anacondaのアイコンを押しても、通常出るはずの「Initializing」の表示が出ず、無反応になってしまいました。Anaconda内の設定を若干変更したことが影響したかもしれません。（※原因は不明です） 

## 解決策
Anaconda Promptを開いて、Anaconda Navigatorのアップデートを行ってください。

```bash
conda update anaconda-navigator
```

次にanaconda-navigatorのリセットを行います。

```bash
anaconda-navigator --reset
```

再度、Anaconda Navigatorのアイコンをクリックしてみてください。起動できるようになっているはずです！
IntelliJの画面からmavenコマンドを実行する

一番上のタブからView→ToolWindows→Mavenを選択すると別ウィンドウが現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/ea3d15f1-62fc-5fed-972e-cd7a681b2324.png)


そこに表示されている自身で開いているMavenプロジェクトを展開するとLifecycleというフォルダがありそれを更に展開するとinstallなどmaven操作があり実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/6efe7338-b814-4382-3305-a24be1cef144.png)
bladeで自作関数を使う方法

<h3>クラスの作成</h3>
モデル.phpに定義する

```app/Model.php
    public function 自作関数()
    {
        
    $artists = $this->artist()->get();
    foreach ($artists as $artist){}
        
    return $artist->user_id;
        
    }
```


<h3>bladeテンプレートで使う</h3>

```blade.php
@if(Auth::id() === $workEdit->自作関数())

{!! Form::model($workEdit, ['route' => ['artist.destroy', $workEdit->id], 'method' => 'delete']) !!}
    {!! Form::submit('作品を削除', ['class' => 'btn btn-danger','onclick' => 'delete_alert(event);return false;']) !!}
{!! Form::close() !!} 
            
@endif
```

モデルのphpに関数を指定しておけば、blade上でそのモデルを操作する時は、そのまま関数を呼び出して使える。
quot: command not foundって言われたら

## エラー内容
コマンドを打った結果、以下のようになっていたと想定

```
quot: command not found
```

## まず結論から
コマンドをどこからかコピペしたときに変にコピペされたことによるもの。
実行されたコマンドとコピペ元の文字をよく見比べてみると元の部分に「quot」みたいな文字は無いはず

## 原因
コマンドが載っている資料からコピペしたときに、コマンドの中に
「$@&quot;」みたいに含まれてると思います。
この文字は本来含まれていないはずの文字で、この正体は「ダブルクォーテーション」だった。

例えば、gitをインストールしてからの設定のコマンドだとしたら、
以下のように「&quot;」が含まれてしまっている。
よくある手順書を見たら分かるが、ここは文字列をダブルクォーテーションで囲うべきところ。

```
git config --global user.email &quot;メールアドレス&quot;
```

## 解決方法
以下のような文字列になっているところを、全部ダブルクォーテーションにしたらいい。

```
&quot;
```
【個人開発】月間100万PVゲームアプリの超手抜きインフラ構成の話

# インフラ管理よりも価値を生み出すことに時間を

まず大前提として、ユーザーはバックエンドのインフラがEC2で手動でデプロイされていようと、Lambdaで実行されていようと**「どうでもいい」**ということ。インフラの技術自慢はユーザー視点・ビジネス視点からは乖離している。
未経験駆け出しエンジニア転職界隈では「Herokuにデプロイしているポートフォリオ」を揶揄されているらしいが、その面接官全員に説教したい。「ラクできることって素晴らしいじゃん！」と思っている。エンジニアは手抜きできる人の方が優秀なのだ。
その上で理解してほしい価値観として、
> **インフラ管理は要求を満たした上で最小限にし、アプリケーション(ユーザーが体験できる価値)を充実させることに時間を集中しよう**

というのがサービス開発者の価値観であるべき。と思っています。
PaaSもKubernetesもCI/CDもトータルでプロダクト開発を"ラクするため"のツールなんだよ。みんなインフラ管理でラクしてもっと価値あるコードいっぱい書こうぜ！


# 自己紹介とアプリ紹介
## 職歴
* コナミでゲーム(C/C++)作ってた。
* ヤフーで数千台規模のIaaSサービスの運用＆それをKubernetesに移管するプロジェクトやってた
* スタートアップでリードエンジニアしてた
* 副業で作ってたアプリで稼げるようになって独立 - [株式会社GENIT](https://www.genit.jp)

## ピアノあそび
子供向けの音楽アプリ(子供向けの超簡単な音ゲーのイメージ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82563/12220998-2570-b2d5-3caa-aa3252b1b6b6.png)

[AppStore](https://apps.apple.com/jp/app/%E3%83%94%E3%82%A2%E3%83%8E%E3%81%82%E3%81%9D%E3%81%B3/id1035118577)
[Google Play Store](https://play.google.com/store/apps/details?id=info.lotusblossom.firstpiano&hl=ja)

↓くらい遊んでもらえています。

|パラメータ|概数|
|---|---|---|
|累計DL数|50万DL|
|DAU|1万人|
|月間遊ばれる回数|100万プレー|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82563/f5ce8656-1aac-7eda-4b6a-5f25ab3d089f.png)

# インフラ構成の考え方

まず、そもそも考えることは、そのサービスにサーバーいるの？というところから。
その判断基準は単純で

> ***UGCがあるか？***

これ。要はユーザーが何かを入力して保存して、それを"他の誰か"が見る必要があるのか？
"他の誰か"が見る必要がないなら、ローカルストレージで事足りる(体重管理アプリとか)

ピアノあそびに関しては、ユーザーが入力したデータを他の人が見ることはない。(ランキング機能とか)

が、以下の2点でクラウド化する必要がある

1. JASRACの契約上ストリーミング方式(都度楽曲データをクラウドから取得)する形にしたい。音楽データをローカルに保存すると「複製権」というのがかかるらしく、支払額がバク上がりする。
2. 季節の曲の追加など(クリスマス曲等)をアプリのアプデなしでやりたい。

ということ。

なので「ピアノあそび」の要件は

> UGCはない。でもデータはクラウドから取得したい。

# ピアノあそびのインフラ構成

オチはとてもシンプルで、クラウドからクライアントへのデータが一方通行なんだから、サーバーなんて用意しなくて、s3に置いて配信するだけでいいじゃん。ということ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82563/88810943-4d78-6c92-bb3f-eeb83f008bed.png)

* 開発PCでRails+sqliteのアプリを起動してデータの管理はそこでやっている(.sqliteはGitの管理対象にしている)
* ボタンをポチって押すと、DBからjsonを生成して、s3に保存
* クライアントからはCloudFront経由でGETリクエストで取得。GETリクエストでJSONが返るので、それはもうWebAPI

s3 + CloudFrontなので、普通にサーバーで運用しているより可用性が圧倒的に高い＆サーバー障害が…とか気にしなくていい(s3が落ちたらそれはもうしょうがない)


## 管理ツール

ローカルで超シンプルなRailsアプリ+sqlite

* ローカルで実行するからログイン機能必要ない
* sqliteのファイルを.gitignoreから外してGitで管理してしちゃう 
* もちろんサーバー代かからない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82563/43350b50-a911-56e1-6ba1-29def39d68ef.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82563/4c494cac-a50e-86ca-2ad1-a23e6e4a3755.png)

viewのh1、scaffoldした時に作られたやつのままだな…

# 最後に

もう一度言うけど、やっぱりエンジニアは**要件の範囲で手抜きできる人が優秀**だと思う。
[プログラマになること#9 三大美徳](https://qiita.com/ggggnonaka/items/7ea0e6c545bea9ce22ee)

会社もお客さんも、結局のところユーザーに喜んでもらって"なんぼ"なので、よりユーザーに喜んでもらえる価値を提供できるエンジニアに僕はなりたいです。

Twitterよかったらフォローしてください[@ryohorie3](https://twitter.com/ryohorie3)
(フォローしてくれたら自動でフォロバするボットが走ってます)
Android StudioでA problem occurred configuring project ':app'.が出た時の対処法

#経緯

Android Studioで他の誰かから受け取ったプロジェクトを開いてみると、

A problem occurred configuring project ':app'.

というエラーが表示されることがある。

すごい簡単に解決できるエラーなのに、全然解決方法が出てこなかった。


#解決方法

「local.properties」を開いて、
ndk.dirのパスを直す。

これだけ。


sdk.dirのパスは既になっており、「Sdk」で終わっているはずなので、
ndk.dirはSdk/ndk-bundleにする

もっと具体的に書くと、
ndk.dir = "hogehoge/Local/Android/Sdk/ndk-bundle"
sdk.dir = "hogehoge/Local/Android/Sdk

とするだけ。


sdkのパスはAndroid Studioでプロジェクトを開いた際に自動で変更してくれるが、ndkのパスは変更してくれない。

だからややこしかった。時間がかかった。

どうせなら両方直してくれればいいのに。
configMapを用いて、Podに複数のconfigをマウントする

# configMapを用いて、Podに複数のconfigをマウントする
ディレクトリ配下にある複数のconfigファイルから、configMap のyamlを作成し、それをPodからマウントする。

## configファイルの確認
```
$ ls config
amfcfg.conf   free5GC.conf
```
## ディレクトリ名を指定して、f5gcs3-configという名前で、ConfigMapを作成する。
```
$ kubectl create configmap f5gcs3-config --from-file=config
$ kubectl get configmap
NAME            DATA   AGE
f5gcs3-config   16     33s
```

## yaml ファイルを作成する
```
$ kubectl get configmap f5gcs3-config -o yaml >> configmap.yaml
```

## Podから、configmapの複数のkeyを参照する設定を行う
```
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: configmap-cnt
      image: ubuntu:latest
      volumeMounts:
        - name: config-vol
          mountPath: /home
      command: ["tail",  "-f", "/dev/null"]
  volumes:
    - name: config-vol
      projected:
        sources:
        - configMap:
            name: f5gcs3-config
            items:
            - key: amfcfg.conf
              path: amfcfg.conf
        - configMap:
            name: f5gcs3-config
            items:
            - key: free5GC.conf
              path: free5GC.conf
EOF
```

## configMap, Pod をデプロイし、確認する
```
$ kubectl create -f configmap.yaml
$ kubectl create -f pod.yaml

$ kubectl exec -it configmap-pod -- ls /home/
amfcfg.conf  free5GC.conf
```
VS code ショートカットチートシート


| 1 | 2 |
|:-:|:-:|
| ターミナルと統合   |  ctrl+Shift+` / ctrl+shift+@ |
| オートフォーマット  | Shift + Alt(option) + F  |
|  エディタ内の検索 |  Ctrl + F |
| エディタ内の置換  |  Ctrl + H　 |
|   |   |
|   |   |
|   |   |
|   |   |
|   |   |
|   |   |


歯車＞設定＞intelephenseで検索> undifined functionsのチェックを外す
[自動化]今日の予定を自動でメールに書く方法[Python]

# 概要

- いちいち、予定表をコピペしてメールに張り付ける作業がだるいので、メールに今日の予定を自動で書く方法を考えました。

# 実行結果

-  今日の予定

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/ce4e85e6-9a7e-f585-2483-d0e5f0cd9054.png)

---


### メール
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/04868a84-c6d3-85d0-8da4-1bb579da134e.png)

---

- 今日の予定をメールに自動で書くことができた！！

# コード
```Python
import win32com.client
import datetime

# 予定を取得
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
calendar = outlook.GetDefaultFolder(9) # 「9」というのがOutlookの予定表のこと

# 予定を抜き出したい期間を指定
today = datetime.datetime.now()
start_date = datetime.date(today.year, today.month, today.day) 

select_items = [item for item in calendar.Items if start_date == item.start.date()] # 今日の予定を入れるリスト

plans = "" # 今日の予定

# 抜き出した予定を入れる
for select_item in select_items:
    plans = plans + select_item.subject + "\n"
   

# メール作成
object = win32com.client.Dispatch("Outlook.Application")
mail = object.CreateItem(0) 
mail.BodyFormat = 1

# メールの本文
mail.Body = plans

# 作成したメールの表示
mail.Display(True)

  # メール送信
# mail.Send()
```

# 参考
[【自動化】PythonでOutlookの予定を抜き出す](https://qiita.com/konitech913/items/2ec831863ad84db23558)
JS 変数(const let var) (JSアウトプット)

##あいさつ
初めての人は初めまして！知っている人はこんにちは！
中学生バックエンドPGのAtieです！
今回はJSの「変数」についてアウトプットしていきます

##そもそも変数とは？
変数とはデータを保存することができる「箱」のようなものとイメージしてください
例として変数の箱を「シャンプー」としてみましょう
シャンプーという箱にはもちろんシャンプーが入っていますよね？
そのようなものとイメージしていただくとわかりやすいと思います

これでも「ん？」となる方のために図を用意しました

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920666/fde6b0c9-6d5b-a63c-2c1d-32ca98a6605c.png)

このような感じで変数を宣言することで「箱」ができ
データを代入することで中身ができます

##変数の定義と代入方法

変数を使うには定義が必要です
定義の方法は

```main.js
let 変数名;  //変数定義
```
このように宣言します
変数名は基本自由ですがいくつかルールがあります

- 変数名の最初の文字はアルファベットか_か$のどれからしか始めることができない
- 数字から始めてはいけない
- 予約語を使ってはいけない

この三つです
予約語とは「if」などのプログラミング言語があらかじめ定義した名前のことです
なので

```main.js
let if;
```
のようなことをするとエラーが出てプログラムが動きません

次に変数の代入方法です
注意ですがプログラミングにいての代入は「左辺と右辺が等しい」という意味ではなく「右辺のデータを左辺に入れる」ことを意味しますので気を付けてください

```main.js
let number;
number = 200;
```
このように代入します
ほかにも
```main.js
let number = 100;
```
のように宣言と同時に値を代入可能です
一部書き換えることができないものもありますが変数なので
値を書き換えることができます

```main.js
let number = 100;
number = 200;
```

もちろん数字以外にも文字を入れることが可能です

```mian.js
let message = "hello!";
let jp_message = "こんにちは！"
```
のようにもできます

##const,let,var
JSで変数を定義するには三つの方法があります

```main.js
const 変数名 = 100; //constを使った方法
let 変数名 = 100; //letを使う方法
var 変数名 = 100; //varを使う方法
```
それぞれの宣言によって特徴が異なります

###const
再代入ができずなおかつ再定義もできない
「定数」とも呼ばれるがオブジェクトを代入したときにオブジェクト内のプロパティを書き換えることができるので厳密には定数ではない

基本的にこのconstを使う
再代入禁止などプログラムのバグを増やさないために使う

###let
再代入できるが再定義はできない

constでは再代入ができないが「書き換える必要がある！！」というときはこのletを使う
再代入ができるのでバグが生まれる可能性がある

###var
再代入もできなおかつ再定義もできる

再代入や再定義ができるためバグが生まれやすくさらにはこのvar自体にもバグを生む可能性がある

つかったら負け

##さいごに
ここまで読んでいただきありがとうございました！
今回はJSの変数について学習したのでアウトプットさせていただきました！
基本的にはconstを使ってくださいね！
では！また次回！

[AtieのTwitter](https://twitter.com/Atie_BackendPG)
[しまぶーのIT大学さんのTwitter](https://twitter.com/shimabu_it)

##学習、参考資料
[【JavaScript入門 #5】変数を理解しよう！var, let, constの使い分けまで解説！【ヤフー出身エンジニアの初心者向けプログラミング講座】](https://www.youtube.com/watch?v=4NPrR_szrUM&list=PLwM1-TnN_NN7-zdRV8YsGUB82VVhfYiWW&index=5)
LaravelでS3にアップする画像のリサイズ

## 目的
AWSの経費削減の為に画像品質を保証する前提でS3にアップする画像の圧縮をして欲しいと言うデイレクターからの要望を実現

## 必要条件
[１]  ライブラリであるGDのインストール

```
$ yum install php-gd

# GD ライブラリの情報を確認
php -r 'print_r(gd_info());'
```
[2] Intervention Imageのインストール

```
$ composer require intervention/image

あるいはcomposer.jsonファイルに下記を追加
"intervention/image": "^2.5",
```
## Laravelの設定
app\config\app.phpファイルに下記を追加
[1]  Intervention Imageのサービスプロバイダの追加

```
'providers' => [
        Intervention\Image\ImageServiceProvider::class,
],
```
[2]  Intervention Imageのファサードの追加

```
'aliases' => [
        'Image' => Intervention\Image\Facades\Image::class,
],
```

## Controller作成
```
namespace App\Http\Controllers\User;

use Intervention\Image\Facades\Image as Image;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;

class UploaderController extends Controller
{
    public function putImageTmp()
    {
        $file = request()->file('file');

        $image = Image::make($file);
        $image->resize(70, 50);

        $path = request()->file('file')
                ->store(config('const.file_tmp_dir'));

        return response()->success([
            'url' => Storage::url($path),
            'path' => $path,
        ]);
    }
```
高さのみ指定し横は同じ比率でリサイズしたい場合

```
        $image->resize(null, 50, function ($constraint) {
            $constraint->aspectRatio();
        });
```

## ちょっとだけハマったところ
[1]  ライブラリであるGDのインストールされていないと下記のエラーが発生

```
local.ERROR: Call to undefined function Intervention\Image\Gd\imagecreatefromjpeg() {"userId":11,"exception":"[object] (Error(code: 0): Call to undefined function Intervention\\Image\\Gd\\imagecreatefromjpeg() at /var/www/html/projdir/vendor/intervention/image/src/Intervention/Image/Gd/Decoder.php:38)
```
[2]   GD ライブラリの情報を確認

```
$ php -r 'print_r(gd_info());'

Array
(
    [GD Version] => bundled (2.1.0 compatible)
    [FreeType Support] => 1
    [FreeType Linkage] => with freetype
    [GIF Read Support] => 1
    [GIF Create Support] => 1
    [JPEG Support] =>      ←「JPEG Support」が有効になっていない
    [PNG Support] => 1
    [WBMP Support] => 1
    [XPM Support] => 1
    [XBM Support] => 1
    [WebP Support] =>
    [BMP Support] => 1
    [JIS-mapped Japanese Font Support] =>
)
```

[3]ライブラリであるGDのインストール

```
$ yum install php-gd
```
 GD ライブラリの情報を確認

```
$ php -r 'print_r(gd_info());'
```
下記のようにJPEG Support」が「1」有効になればOK

```
[GIF Create Support] => 1
```
## 画像リサイズ結果
リサイズ前
![スクリーンショット 2020-12-02 17.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/dca0380b-4fb3-4ca8-b941-8cc4123492d6.png)

リサイズ後
![スクリーンショット 2020-12-02 17.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/c4b212c5-916b-9d2d-1009-1f7c8f9f46a9.png)
## 　画像リサイズ以外色々遊べます
モザイク

```
$img->pixelate(50);
```
グレースケール

```
$img->greyscale();
```
shopify チュートリアルで発生するReferenceError: React is not defined

shopifyのアプリ開発を学ぼうとshopify developersにあるチュートリアルを進めていると、[Step.4 Polarisでユーザーフェイスを構築](https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-react/build-your-user-interface-with-polaris)で翻訳プロップを追加した後の`npm run dev`実行後に画像のようなエラーが出ました。
![スクリーンショット 2020-11-25 17.00.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459539/e117afc2-110f-5ee8-dd5e-e715481cbcbc.png)

# 原因
**ReferenceError: React is not defined**と書いてあるとおり、Reactが定義されていないというエラーが発生しています。
ターミナルにも同様のエラーメッセージが表示されており、ターミナルのエラーメッセージを読んでいくと、_app.jsでエラーが発生していることが分かります。![スクリーンショット 2020-11-25 17.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459539/e8e5976f-02d5-29cd-44a3-5d7dce191a2b.png)

# 解決方法
_app.jsに以下2行を追加します。

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
```

この時点で_app.jsのは以下のようになります。

```javascript:_app.js
import App from 'next/app';
import Head from 'next/head';
import { AppProvider } from '@shopify/polaris';
import '@shopify/polaris/dist/styles.css';
import translations from '@shopify/polaris/locales/en.json';
import React from 'react'; //追加
import ReactDOM from 'react-dom'; //追加

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;
    return (
      <React.Fragment>
        <Head>
          <title>Sample App</title>
          <meta charSet="utf-8" />
        </Head>
        <AppProvider i18n={translations}>
          <Component {...pageProps} />
        </AppProvider>
      </React.Fragment>
    );
  }
}

export default MyApp;
```

これで改めて`npm run dev`を実行すると正常に動作し、チュートリアルを進めることが可能です。

## 参考
https://community.shopify.com/c/Shopify-APIs-SDKs/ReferenceError-React-is-not-defined/td-p/937873
自作関数の作り方

<h3>クラスの作成</h3>
app以下にLibraryディレクトリを作ってFunctions.phpを作成。(ディレクトリの場所はどこでもいいです。）このファイルの中に自作メソッドを保管していきます。
staticメソッドのfunctionを作ります。

```app/Library/Functions.php
class MyFunctions
{
    public static function xxxx()
    {
        //処理内容
    }
}
```

<h3>エイリアスの登録</h3>

```config/app.php
config/app.php のaliasesに作成したクラスを追加します。

'aliases' => [
    'MyFunctions' => App\Library\Functions::class,
   ],
```

<h3>コントローラーで使う</h3>
コントローラーにuse MyFunctionsで使用可能。呼び出すときは MyFunctions::xxxx()で。
エイリアスの登録を行わなかった場合はuse App\Lib\MyFunctions

```Controller.php
use MyFunctions で使用可能。
MyFunctions::xxxx() で呼び出して使います。
```

<h3>bladeテンプレートで使う</h3>

```blade.php
{{ MyFunctions::hoge() }} で呼び出して使えます。
@foreach (MyFunctions::xxxx() as $zzz) ... {{$zzz}} @endforeach

```
TPUでの学習を高速化できる'experimental_steps_per_execution'について

# はじめに

TPU環境のTensorFlow/Kerasのfit時間を短縮できる、'experimental_steps_per_execution'についての調査報告をする。

## 環境
 * Google Colab TPU
 * TensorFlow 2.3.0
 * tf.keras 2.4.3

記事作成後にColabのTensorFlowが2.4.0になったが、'steps_per_execution'の名前で正式採用となり、'experimental_'なしで記述できるようになった。

# experimental_steps_per_executionとはなにか

TensorFlow2.3.0の[ReleaseNote](https://github.com/tensorflow/tensorflow/releases/tag/v2.3.0)によると、下記の通り。

>Added experimental_steps_per_execution
arg to model.compile to indicate the number of batches to run per tf.function call. This can speed up Keras Models on TPUs up to 3x.

tf.kerasのmodel.compileに引数指定することで、一回のcallで実行するバッチの個数を指定できるもので、TPUでは最高３倍速くなる、とある。

[TensorFlowのTPU使用ガイド](https://www.tensorflow.org/guide/tpu)によると、

>To reduce python overhead, and maximize the performance of your TPU, try out the experimental experimental_steps_per_execution argument to Model.compile. Here it increases throughput by about 50%:

pythonのオーバーヘッドを減らして高速化するようだ。ここでは50%高速化される例がかいてある。

GPUでは高速化の効果が無いが、のちに述べる制限&副作用は適用される。つまり「機能として無効ではないがメリットがない」ということになる。

筆者がこの機能を知ったのは、TPUの謎のWanrningの解決法を探していた際に、これを設定すればよい、とどこかに書いてあったため。
当該のエラーはこちら。同様のWarningで悩んでいる方は、設定することをお勧めする。

>WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time

## 制限&副作用
* 入力データは最低でも'steps_per_epoch * epochs'でなければならない
 * ちなみに切りのいい数値にしなくても切り捨てられることは無いようだ。
* tf.keras.callbacks.Callbackのon_batch_begin/on_batch_endの呼び出し回数が減る
 * 通常はバッチ処理毎にこれらの関数が呼び出されるが、experimental_steps_per_executionを設定すると、その設定回数を処理し終わった時点で呼び出されるので結果的に回数が減る。
* fit時に最終的に表示される処理時間が不当に短くなることがある
 * 必ずではないので何らかの条件があるようだ
* verbose=1の時に情報が更新される頻度が減る

# 効果確認

## 実験条件
* Google ColabのTPUで実施
 * TPUでは初回のfitに異常に時間がかかるので、初回は捨て２回目のfitの時間を測定する。
* データはCIFAR10(32,32,3)
* ネットワークはパラメータ数の違うCNNを２つ
 * High Model Total params: 10,165,578
 * Low Model Total params: 2,187,434
* fitの設定
 * steps_per_epoch = 1000
 * batch_size = 256 と 32
 * verbose = 0
 * validationなし

experimental_steps_per_executionを6種類選んで実験している(0は無指定を意味する)。
verbose=1にしても同じような結果なのだが、無指定でのWarning表示のために正確な比較ができない可能があるので、verbose=0で実験している。

## 実験結果

batch_size=32の結果はこちら。
![batch_size=32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824193/67821dd2-1989-d596-9b84-4f141c33b704.png)

batch_size=256の結果はこちら。
![batch_size=256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824193/4dda9cf8-b30d-f22e-4fa8-39a7bef3e8f2.png)


全ての条件で500にした場合が一番結果が良かった。こちらの数値と無指定を基準とした比率を載せておく。

|batch_size|parameters|duration(sec)|%|
|---|---|---|---|
|32|2M|13.5|91.2|
|32|10M|17.7|84.2|
|256|2M|18.0|83.7|
|256|10M|33.9|94.1|

微妙な結果だが、高速化できることは事実である。
この実験では20とした場合には、逆に時間がかかってしまった。小さな数値を設定することは避けたほうがよさそうだ。

ちなみに前述のTensorFlowのガイドどおりの学習では11秒が6秒になって50%程度の高速化は嘘ではない。
この辺は条件次第のようだ。
【コマンド集】docker-composeでコマンド簡略化&複数のコンテナを管理

<br>
## はじめに
`Docker` を使用していると、複数のコンテナを作成、起動させる事があると思います、そんな時に便利なのが、`Docker-compose` になります。また、通常の `docker runコマンド` は、オプションをふんだんに付け加えて、長いコマンドになる事が多いと思いますが、それも `docker-compose` を使用する事によって、解決する事ができます。

と言うことで、今回はこの `Docker-compose` でよく使用するコマンドと、`docker-compose.yml` ファイルの解説していきます。
<br>
<br>

## docker-compose.yml
簡単に言うと、`docker-compose.yml` ファイルとは、`docker-composeコマンド` を使用する際に必要なファイルで、ここにコマンドを実行した際の挙動を記述していくと言う感じです。

下記は実際の `ymlファイル` になります。

```yml
version: '3'

services:
  app:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/application'
    tty: true
    stdin_open: true
```
<br>

上記で重要なのは、下記の部分になります。

```yml
# docker-compose buildのbuild先
build: . # .はカレントディレクトリ

# docker-compose upの際のポート番号
ports:
  - '3000:3000'

# docker-compose upの際のマウント先
volumes:
  - '.:/application'

# docker-compose upの際に-itを指定
tty: true
stdin_open: true
```
このファイルのおかげで、通常の `dockerコマンド` ではつらつらと長かったコマンドが、短いコマンドの入力で済ませる事ができるようになります。

次からは実際のコマンドを解説していきます。
<br>
<br>

## build
まず `$ docker build` と同じく、`docker-composeコマンド` でのbuildする方法です。
コマンドはこちら。

```html
$ docker-compose build
```
特徴は、通常のコマンドではbuild先のパスが必要だったのが、`ymlファイル` によって記載されているbuildの指定によって、必要なくなったと言う点と、それにより指定したディレクトリ配下で複数の `docker image` を作成する事ができると言う点です。
<br>
<br>

## up
次に`$ docker run` と同じく、`docker-composeコマンド` でのrunする方法です。
コマンドはこちら。

```html
$ docker-compose up
```
こちらのコマンドは、`Dockerfile` がまだ build されていなければ、run と同じく自動的に build してくれ、かつコンテナを `ymlファイル` に記載されている情報に合わせて、複数起動してくれます。
<br>

言葉だけだとわかりにくいと思うので、上記のコマンドをもし `dockerコマンド` で実行した際は、次のようなコマンドになります。

```html
$ docker run -it -v ~/Desktop/application:/application -p 3000:3000 a483e21f5839 
```
見たらわかりますが、長いですよね。しかもこれで起動できるコンテナは一つです。実際の開発現場において、何度もこのようなコマンドを実行するのは、ミスも増えて非効率です。

しかし、`$ docker-compose up` を使えば、効率的に開発を進める事も可能になります。
<br>
<br>

## exec
上記ではコンテナを作成するコマンドでしたが、今度はコンテナに入る時の、`docker-composeコマンド` で実行する方法です。
コマンドはこちら。

```html
$ docker-compose exec app bash
```
<br>

こちらも通常の `dockerコマンド` なら次のようなコマンドになります。

```html
$ docker exec -it -v ~/Desktop/application:/application -p 3000:3000 a483e21f5839 bash
```
比べてみると一目瞭然ですね。`docker-composeコマンド` の場合は、予め `ymlファイル` に記載がありますので、それを利用して効率的にコマンドを実行する事ができます。
<br>
<br>

## down
最後にコンテナを除去する際に、`$ docker stop` と `$ docker rm` を同時に実行してくれる、便利なコマンドがこちら。

```html
$ docker-compose down
```
こちらは、`ymlファイル` を利用して作成された複数のup状態のコンテナを、exited状態にさせて、さらに削除までしてくれます。

dockerを利用していると、不必要なコンテナが溜まっていくことは多々あります。そこで管理のしにくさが問題になるのですが、 `docker-composeコマンド` を利用すれば、プロダクト単位で管理が可能になるので、こちらもかなり効率がよくなります。
<br>
<br>

## まとめ
 `Docker` を利用するだけでも、開発環境の共有が容易にできるので便利ですが、さらに `Docker-compose` を利用することで、効率的な開発ができるので、導入している企業も多いと思われます。

そこまで難しい内容でも無いので、空いてる時間に `docker-compose` も使えるようになるのはオススメです。

最後まで読んでくださり、ありがとうございました。
<br>
<br>
<br>

筆者：yuki｜IT業界のリアルな転職事情など発信｜元トップ営業マン(訪販)→未経験からエンジニア転職へ
Qiita：https://qiita.com/yuki4839
Twitter：https://twitter.com/yuki35522891
コレクションや、配列の中身を取得する

<h3>連想配列のキーを取得</h3>
連想配列のキーを取得するためには、array_keys関数を使用します。

```sample.php
<?php
$fruits = array("apple" => "リンゴ", "orange" => "ミカン", "lemon" => "レモン");
// 連想配列のキーと値を出力
foreach ($fruits as $key => $value) {
 echo $key;  // $keyにキーの文字が入っている
 echo "'s value is ";
 echo $value;  // $valueにデータが入っている
 echo "
";
}
```
```
[0]=>"apple",[1]=>"orange",[2]=>"lemon"
```
array_keys関数は連想配列のキーの文字だけを取得する関数です。取得したキーの文字は配列として格納されます。
<h3>連想配列の値を取得</h3>

```sample.php
<?php
$fruits = array("apple" => "リンゴ", "orange" => "ミカン", "lemon" => "レモン");
$value1 = $fruits["apple"];
$value2 = $fruits["orange"];
$value3 = $fruits["lemon"];
```
連想配列の値を取得するためには連想配列の変数に対して[]を使用し、[]の中にキーの文字を入れることで、指定したキーに対する値を取得できます。

<h3>連想配列のキーと値を出力する</h3>

```sample.php
<?php
$fruits = array("apple" => "リンゴ", "orange" => "ミカン", "lemon" => "レモン");
// 連想配列のキーと値を出力
foreach ($fruits as $key => $value) {
 echo $key;  // $keyにキーの文字が入っている
 echo "'s value is ";
 echo $value;  // $valueにデータが入っている
 echo "
";
}
```
```
apple's value is リンゴ
orange's value is ミカン
lemon's value is レモン
```
foreach制御文に連想配列を設定した$fruits設定しasキーワードの後に「$key => $value」とすることで、$keyにはキーに設定した文字が、$valueには$keyに設定されたキーに対する値が入っています。

foreach制御文を使用することで、連想配列に設定したキーと値をインデックスの最初から最後まで出力できます。
 
<h3>コレクションを配列に変換する</h3>

```sample.php
$collection = collect([
    ['title' => 'ベニスの商人', 'author' => 'シェイクスピア', 'price' => 2000],
    ['title' => '罪と罰', 'author' => 'ドストエフスキー', 'price' => 1500],
]);

print_r($collection->toArray()); 

/* 実行結果 */
Array ( [0] => Array ( [title] => ベニスの商人 [author] => シェイクスピア [price] => 2000 ) [1] => Array ( [title] => 罪と罰 [author] => ドストエフスキー [price] => 1500 ) )
```
Linux系コマンド備忘録

##vim
###すべての行の先頭に同じ文字列を入力
1. Ctrl + v　で矩形選択モードに移行し、入力対象範囲を選択する。
2. Shift + i　で挿入モードに移行し、文字を入力する。
3. Esc で挿入モードを抜けると、文字が挿入される。


##grep
###・grepで取得した最後を取得
```
grep PATTERN FILE | tail -1