OmniAICreator/Qiita-1.07M huggingface dataset:
WinMergeはもう使いたくないというお気持ち表明をツールに


前回の
[Diff＋Historyコマンド＝hifferで快適なターミナル作業しようぜ](https://qiita.com/ykato/items/ebbebf4a80181bc3841a)
からの派生ツールです。
もっとニッチに機能を絞り込んで軽くした方が良いのかな？なんて思い作ってみました。

# あらまし

リポジトリや、ファイルサーバーを使わない古典的なファイル管理だと
hostsみたいなファイルに.origとか.bak付けたりして同じフォルダに放置されてたりしますね。
~~Excelのなんちゃら_20200605(修正2).xlsxみたいなだめだめファイル管理で普段から癖になってるクソ運用~~

んで、運用で追加依頼が来たりすると日付だけじゃ最新かどうか判断できない、中身を見るしかない場合。
一個ずつ開いて比較してくのはメンドイ＆シンドイ。

WinMergeにコピペを繰り返したりしません？で**コピーミスって同じの張り付けてミスったり。。**
で、差分がわかったとこで反映するのもめんどい。
せっかくLinuxのターミナル上でやってるんだから他のツールあれこれ使いたくない。

そんな要望をコンカチしてツール化してみました。

# どですか？

複数ファイルを読み込んでlessぽく比較してくれるツールです。
ブラウザのタブみたいに表示、比較する対象を切り替えられます。
![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/396ca454-aadf-241a-2abd-4c8132592557.gif)

**差分を反映したければコミットして部分的、または全体に変更かけれます。
部分的てのがミソで一部分だけ書き換えたいときにわざわざviから開かないでも操作一発で反映できるのでとても楽です。**

単語検索の機能もつけてみました。

Windowsだけじゃなくて、Linux版もクロスプラットフォームであります。
[バイナリも作っておきましたので拾ってくださいな。](https://github.com/yasutakatou/mdiff/releases)

![pi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/40477f36-e5a5-20c4-68f3-45587033cd0d.png)

ラズパイでもこいつ・・・動くぞ！

# どこだい？

[ここにおいときますんで、詳しくはリポジトリ側を見てくださいな。](https://github.com/yasutakatou/mdiff)

# さいなら

最初はviやlessみたいに画面の最下部に入力プロンプトを出す実装だったけど、
WindowsとLinuxでエスケープシーケンスの動作が違うのでWindowsで完成させてから
Linuxで動確したら画面が崩れまくって表示部分をだいぶ弄る事になった。。

スマホアプリで同じようにAndroidでいいかんじなのにiOSではガタガタって
ありそうだな。なんて思いつつ

# 追記

ライセンスが書いてなかったのと、インストール方法も十分でなかったので追記しました。
MITライセンスなのでご自由にどうぞ！
と
go getでgo/binの下にバイナリが配置されるよう手順を追加しました。

# 追記2

Windows上で設定する場合でも使えるようにShift JISをサポートしてみました。
一旦、内部でUTF-8に変換して変更するときに元のShift JISに戻す動きをします。
あと改行コードも揃えるのでShift JISとUTF-8の比較でも中身が同じなら差分が
無いようになりました！
Lalavel Eloquentの使用

#Laravel Eloquentの記述


#modelファイルの作成

```
$ php artisan make:model Hoge

Model created successfully.
```

`class Hoge` は DBテーブルの `hoges` とバインドされる
（DBテーブルは、最初が小文字で複数形）


```php:app/Hoge.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Hoge extends Model
{
    protected $table = '{テーブル名}'; //DBテーブルとclass名が違う場合、テーブル名を指定する
}
```

#Controller を編集
insertの記述(1)

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        $hoge = new Hoge();  //インスタンスの作成
        $hoge->last_name = $request->imput('last_name');
        $hoge->first_name = $request->imput('first_name');
        $result = $hoge->save();      //insert実行

        return ;
    }
}
```

insertの記述(2)

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        Hoge::create($request->all());  //入力値全てを取得

        return ;
    }
}
```

```php:app/app/Hoge.php
class Hoge extends Model
{
    protected $fillable = [    //DBに登録するname属性を記載
        'last_name',
        'first_name',
    ];
}
```



updateの記述

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        $hoge = Hoge::where('id', 1)->frist();  
        $hoge->last_name = '田中';
        $hoge->first_name = '太朗';
        $result = $hoge->save();      //update実行

        return ;
    }
}
```

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        $result = Hoge::where('id', 1)->updata([
            'age' => '20'
        ]);

        return ;
    }
}
```

deleteの記述（論理削除）

```php:app/Hoge.php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; //追記

class Hoge extends Model
{
   use SoftDeletes; //追記

   protected $dates = ['deleted_at']; //追記
}
```

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        $result = Hoge::where('id', 1)->delete();

        return ;
    }
}
```

deleteの記述（物理削除）

```php:app/Http/Controllers
use DB;
use App\Hoge

class HogeController extends Controller
{
    public function index(){
        $hoge = Hoge::where('id', 1)->frist();  
        $result = $hoge->delete();      //delete実行
        return ;
    }
}
```


#DBから取得した返すカラムを指定する
```php:
class Title extends Model
{
  protected $visible = ['id','title','url'];
}

```
未定義値(undefined) ってなに？

## はじめに

undefinedってなんだろう…　　

中身がない？ってことなんだろうけど…どういうこと？　　

そんな基本的な知識ない自身の疑問を調べてメモしました。


## 未定義値(undefined) ってなに？

JavaScriptでは初期化されていない変数には全て「undefined」という値が入っています。

(値が入る前の初期値ってことか…？)  

未定義値(undefined)とは、ある変数の値が定義されていないことを表す値で以下のようなケースで返されます。

- ある変数が宣言済みであるものの値を与えられていない
- 未定義のプロパティを参照しようとした
- 関数で値が返されなかった

```
const x;
const obj = { a:12345 };

console.log(x); //結果:undefined (値が設定されていない)
console.log(obj);　//結果:undefined (プロパティが設定されていない) 

```

単純に書くとこんな感じにundefinedになります。

これを利用して変数が定義済みかどうかを判別することが可能です。


# undefinedと比較する
```

if (x === undefined) {
  console.log( 'xは未定義' );
}  
```
グローバル変数として、そのままundefinedという名前の変数が用意されているのでそれと比較するやり方。
一番素直なやり方ですがJavaScriptにおいてはよくない書き方とされています。

undefinedは予約語ではなく、単なる変数です。なので上書きもできるし関数スコープ内で同名のローカル変数を作ることもできます。（ただし最近はconst扱いになって上書きできなくなっているようです）
なので文脈によらず、必ず確実にundefined判定するためにはこの書き方は適さないと言えます。

 # typeof x === "undefined"
そこでよく使われるのがtypeofを使うやり方です。
undefined値にtypeof演算子を作用させると必ず"undefined"という文字列が返るためそれと比較することで判定を行います。

```
if(typeof x === "undefined") {
  console.log( 'xは未定義' );
}  
```

# void 0 と比較する
void 0はあらゆる値に作用し、常にundefiedを返す演算子です。文脈によらずundefinedを受け取れるので、安全確実です。

```
if(x === void 0) {
  console.log( 'xは未定義' );
}

```

# !で代用する
undefined値に「！」を作用させるとtrueが返るため、これを利用するやり方もあります。
しかし,falseや０もundefined扱いになってしまうので注意が必要です。
undefinedを厳密に判別する必要がある場合は使えないが、理解して使うのであればマル。

```

if(!x) {
  console.log( 'xはfalseか０かundefinedかnull' );
}

```

# ==nullで代用する
nullはundefinedと違って予約語です。どの文脈でも確実にnullが入っているので安心して使えます。
「===」を使わず「==」を使っているのがポイントですね。
これも「！」と同じく完全な判定には使えませんがより厳密になります。

```
if(x == null){
  console.log( 'xはundefinedかnull' );
}
```


他にも判定の仕方は色々あるようなので参考までに
…
GatsbyJSのIE 11対処方法

# GatsbyJS の IE11 対応

GatsbyJS で IE11 対応するにはどうすればいいか調べました。
かなり簡単に対応できるのでまだしてない方は是非どうぞ。

## 1. npm の追加

`yarn add babel-preset-gatsby`で babel の設定をまとめたものをプロジェクトに追加します。

## 2. .babelrc の作成

プロジェクトルートに`.babelrc`ファイルを作成します。
↓ のコードをそのままコピー&ペーストします。

```.babelrc
{
  "presets": [
    [
      "babel-preset-gatsby",
      {
        "target": {
          "browsers": [
            ">0.25%",
            "not dead",
            "IE 11"
          ]
        }
      }
    ]
   ]
 }
```

## 3. 足りない polyfill を追加

`fetch`と`Promise`が不足しているので`gatsby-browser.js`等で import します。
私は全ページで読み込む`Layout.jsx`に polyfill.io への script タグを追加しました。

```.html
<Helmet>
  <script defer src="https://polyfill.io/v3/polyfill.min.js?features=fetch%2CPromise"></script>
</Helmet>
```

## 4. 注意点

1 ～ 3 の設定をしても開発環境では画面が白くなります
`gatsby build && gatsby serve`で本番用モジュールを作成して動作確認してください。

私は最後の注意点に気が付かなくてかなり迷いました。

この記事は自分で書いてる[ブログ](https://myblog-by-mako-tos.netlify.app/post/2020-06-05-gatsbyjs-and-ie11)から転載しました。
DockerでrailsでpostgreSQL

#手順（2020/6/5時点） ※10分レシピ

Docker公式のやり方でやってもエラーが出ちゃう・・・
そのために作成しました。
自分の備忘録目的ですが、どうぞお役立て下さい。

## １：必要ファイル準備
```ruby:Dockerfile
FROM ruby:2.6.5   #希望のバージョンでOK
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000   #localhost:3000で接続する設定

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```


```ruby:Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5.2.4'   #希望のバージョンでOK。
# 上記以外の主要gemは、この後自動で書き込まれる。
```

```ruby:Gemfile.lock
# 空ファイル
```

```ruby:entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

```ruby:Gemfile.lock
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:  #この行がDocker公式に載ってない。
      - POSTGRES_PASSWORD=password    #この行がDocker公式に載ってない。
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

## ２：プロジェクトをビルドする
```ruby:ターミナル
$ docker-compose run web rails new . --force --no-deps --database=postgresql
```
※4分程度かかります。

## ２：プロジェクトをビルドする
```ruby:ターミナル
$ docker-compose run web rails new . --force --no-deps --database=postgresql
```
※4分程度かかります。


## ３：権限変更
```ruby:ターミナル
$ sudo chown -R $USER:$USER .
```
※LinuxでDockerを実行している場合、作成rails newされたファイルはrootが所有します。これは、コンテナーがrootユーザーとして実行されるために発生します。この場合は、新しいファイルの所有権を変更してください。

## ４：Gemfile更新のための再ビルド
```ruby:ターミナル
$ docker-compose build
```
※1分程度かかります。コンテナのGemfile更新のため。

## ５：データベースの設定
```ruby:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password  #この行がDocker公式に載ってない。
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
```

## ６：コンテナの更新のための再ビルド
```ruby:ターミナル
$ docker-compose build
```
※1分程度かかります。コンテナのdatabase.ymlの更新のため。

## ７：コンテナの起動
```ruby:ターミナル
$ docker-compose up
```
※データベース未作成の為、localhost接続でエラーが出る。

## ８：コンテナのデータベースの作成
```ruby:ターミナル
$ docker-compose run web rails db:create
```
※ローカルから設定可能。

## ９：設定完了
![images.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580629/288c1167-2207-b35e-bc65-c6303d11a36f.jpeg)
※localhost:3000で接続
※ここからアプリ開発開始〜！！


## 備考：参考動画・サイト
[Masara Oshimaさん](https://www.youtube.com/watch?v=M9vIBIoPznE)
※youtubeで15分程度の簡潔な動画です。助かりました！

[Farstepさん](https://www.youtube.com/watch?v=Fq1PH0Gwi8I&t=1033s)
※Dockerfileやdocker-compose.ymlの記述説明もあり。わかりやすい！

[Docker公式サイト](https://docs.docker.com/compose/rails/)
※一部修正が必要だった為、上記１〜８まで実行すれば開発環境構築まで可能です。
Rubyのメモ化における「||=」と「instance_variable_defined?」の違い

# これはなに？

Rubyのメモ化の際の「||=」と「instance_variable_defined?」の違いをまとめた記事です。

Rubyのメモ化を調べると以下の２通りの書き方があることを知りました。

```ruby
# ||=のメモ化
def current_user
  @current_user ||= find_by(id: 1)
end
```

```ruby
# instance_variable_defined?のメモ化
def current_user
  return @current_user if instance_variable_defined? :@current_user
  @current_user = find_by(id: 1)
end
```

↓こちらの記事によると挙動に違いがあるようです。
[Rubyでメモ化するときの話 - yuji.developer's graffiti blog](https://blog.yujigraffiti.com/2018/09/ruby-memorization.html)

> 右辺が偽を返さない場合は2度目以降は左辺の評価が真となりますので右辺が評価されることなく終わりますが、右辺が偽の値を返していた場合は2度目以降でも左辺の評価が偽となり右辺の評価が行われてしまいます。

最初読んだ時は「？？」ってなりました。
どうやらメモ化したい式の右辺の値(上記の例だと`find_by(id: 1)`の部分)にnilが返ってくる時に挙動に差分が出るようです。
というわけで検証して差分をまとめてみます。

## そもそもメモ化ってなに

プログラムの高速化、最適化のための手法です。
Rubyにおけるメモ化は一度評価した値を以降再評価せずに参照したい時に使われるようです。

下の例だと一度`current_user`を呼んで`@current_user`を定義していれば、以降また呼ばれた際は`find_by(id: 1)`の部分を実行せずに`@current_user`を取得できます。
都度検索を行なわないので高速化に繋がります。

```ruby
# 一回呼んでたら以降同じ値を返し続ける。
def current_user
  return @current_user if instance_variable_defined? :@current_user
  @current_user = find_by(id: 1) 
end
```

## 検証

冒頭にものせた例で2パターン試してみました。

1. find_by(id: 1)の結果がnilだった時
2. find_by(id: 1)の結果nilじゃなかった時

```ruby
# ||=のメモ化
def current_user
  @current_user ||= find_by(id: 1)
end
```

```ruby
# instance_variable_defined?のメモ化
def current_user
  return @current_user if instance_variable_defined? :@current_user
  @current_user = find_by(id: 1)
end
```

## 結果

以下のようになりました。

| | find_by(id: 1)の結果がnilだった時 | find_by(id: 1)の結果nilじゃなかった時　|
| ---- | ---- | ---- |
| &#124;&#124;= | ・find_byが呼ばれ、取得した結果を返す。(nilだった場合はメモ化されない) | 一度find_byで見つかった値を返す。再度find_byは呼ばれない |
| instance_variable_defined? | find_byは呼ばれず、メモ化したnilを返す | 一度find_byで見つかった値を返す。再度find_byは呼ばれない |

上の検証をした後で冒頭で紹介した記事の以下を読み返したら納得できました。
[Rubyでメモ化するときの話 - yuji.developer's graffiti blog](https://blog.yujigraffiti.com/2018/09/ruby-memorization.html)

> 検索処理でnilが返る場合、accountメソッドが呼ばれるたびに検索処理を行ってしまうのです。
それもそのはず、Rubyの||=演算子は左辺が偽の場合に右辺の処理行い左辺に代入する演算子だからです。
Rubyで偽の場合というのはnilかfalseの場合です。
Rubyのインスタンス変数は未初期化であればnilとして扱われます。

## まとめ

* `||=`でメモ化する場合
    * 右辺がnilじゃなくなるまで右辺は呼ばれ続ける。つまりnilじゃなくなるまで値が固定化しない＝メモ化されない。
* `instance_variable_defined?`でメモ化する場合
    * 右辺がnilの場合はnilでメモ化され、以降右辺は評価されなくなる。

* 右辺にnilが返ってくる可能性がある式でメモ化を行う場合、定義済みのnilをメモ化したければ`instance_variable_defined?`を使う。
【python】対角線上の合計数値の差分を求めるプログラム

#【python】対角線上の合計数値の差分を求めるプログラム

自分用のメモです。


▼設問

- n × n の表が与えられる。
- 左上から右下までの合計値と右上から左下までの差分の絶対値を求める。


[URL](https://www.hackerrank.com/challenges/diagonal-difference/problem)


▼sample input

```:matrix
11 2 4
4 5 6
10 8 -12
```
```python:
arr = [[11,2,4],[4,5,6],[10,8,-12]]
```


▼sample output

```python:
15
```

▼my answer

```python:
def diagonalDifference(arr):
    n = len(arr[0])-1
    xrr=[]
    yrr=[]

    i=0
    for ar in arr:
        xrr.append(ar[i])
        yrr.append(ar[n-i])
        i += 1
    ans = abs(sum(xrr)-sum(yrr))
    return ans

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    n = int(input().strip())
    arr = []
    for _ in range(n):
        arr.append(list(map(int, input().rstrip().split())))
    result = diagonalDifference(arr)
    fptr.write(str(result) + '\n')
    fptr.close()
```


<br>
**・abs()**
絶対値を返す

**・listの定義はまとめられない**
初期値で i = x = 0とする感覚で、listは定義できない。
☓xrr = yrr = []　※同じ一つのオブジェクトを参照してしまう。
◯xrr=[] yrr=[]
git diffしたら変な文字がでてきて困ったのでなんとかしたい

# 困っていること
```bash:
git diff
```
その結果がこちら。
色々な事情あって一部分だけです。
![カラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72763/22c6027d-120d-fb05-4d91-ba8960c0038e.png)
とか
<img width="152" alt="スクリーンショット 2020-05-26 11.37.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72763/8816276a-2b48-fb9f-83a0-982cbc46c161.png">

この`ESC[m`や行末の`^M`ってなんだ？

ずっと出てて気にしないようにはしてましたが、数が増えてくると邪魔で仕方がない。


# 解決策
消す方法を探しました。

コメント受けて追記：
改行コードについては本来はそもそも改行コードが途中で変わってしまった状態でcommitすることがおかしいのですが、既に起きてしまっているので、見にくさを軽減できればという方向性の妥協策です。


```bash:
git config --global core.pager "less -R"
git config --global core.whitespace cr-at-eol
```
これだけ。
`global`なところは自身の状況に合わせて`local`にしたりしてください。
1つ目は、ANSI Color Escape Sequenceがそのまま表示されているので、これを正しく解釈してカラー表示するため、
2つ目は、CRも改行コードの一部なんだよっていう設定です。

# 解説
そもそも`ESC[m`や`^M`って何なんだというところからですが、
`ESC[m`はANSI Color Escape Sequenceです。`[`と`m`の間に色コードが入ります。
次に`^M`は改行コード、具体的には`CR`（キャリッジリターン）を余分な空白として認識し、それを表現するために出てきているものです。
（CRはgitのデフォルトでは改行コードではなく空白として扱われるため）

ANSI Color Escape Sequenceがあるのは、`git diff`がいい感じに色をつけて表示しようとしてくれているからで簡単に納得がいきます。
ところが問題は改行コードです。これはWindows環境とmacやlinux環境では通常扱う改行コードが異なってることに起因します。
そのため、ファイル内の改行コードを見て自動的に改行コードの定義を変えてくれるようなエディタを使っていない場合は
OS既定（場合によってはエディタの設定による）の改行コードが使われてしまい、ファイル内の本来の改行コードとは異なる改行コードが設定される場合があります。

本来改行コードの違いは起きないようにすべきですが、起きてしまっていると冒頭の例のように`^M`と意味のわからない文字が表示されてしまいます。
そこで、`core.whitespace`の設定を変更し、`CR`も改行コードの一部であると定義しておけば`CR`が差`^M`と表示されてしまう現象は解消されます。

妥協策ですが、これで改行コードが記号化されて表示されることがなくなり、完成。

文字エンコーディングや制御コード類、特に改行コードは忘れられ／見落とされがちだと思いますが、正しく設定しておきましょう。

起きた後の対処も大事ですが、何よりも変な/意図しない差分を生まないことが一番大事。
AndroidStudioでiOSのinfo.plistを編集する

わざわざXcodeを起動して編集するの面倒だなと思っていたら、AndroidStudioの以下ファイルを編集することで設定を反映させることができた。

ios/Runner/Info.plist

```Info.plist.yaml 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...略

<key>io.flutter.embedded_views_preview</key>
<true/>
</dict>
</plist>

```
今回はwebViewの設定を追加
keyの下に設定する値を記述。書き方はファイル内を参考すればわかるので割愛
Railsでフロント実装練習したい時の最速手順 (Haml、Sass）7/12訂正



### こんな人に読んで欲しい

#### Railsで、HamlとSassのコーディング練習をしたい。取り急ぎビューの表示まで行ってさっさと練習したい。
<br>



早速行きましょう

### 1:任意のディレクトリ以下で（保存したいフォルダにて）rails new実行してアプリフォルダ作成
7/12訂正：任意のディレクトリへ移動する（私が間違えてホームディレクトリでやってしまいがちなので追加笑）

```ruby:ターミナル
% cd projects     ※projectとしましたが、ディレクトリ名はなんでもいいです
```

```ruby:ターミナル
$ rails _5.2.3_ new xxxx -d mysql
```
任意指定：railsのバージョン、ファイル名（アプリ名、ここではxxxxとしています）

### 2:アプリのディレクトリに移動

*以下、ターミナルコマンドは全てアプリのディレクトリ以下とします。*

```ruby:ターミナル
$ cd xxxx
```

### 3:関連ファイルが読み込まれていることを確認する
```ruby:ターミナル
$ bundle install
```

### 4:データベースの作成
(単純にコーディングするだけなら不要だと思われます)

```ruby:ターミナル
$ rails db:create  
```

### 5:VS Codeでアプリ開く

### 6:ルーティングする

```config/routes.rb

Rails.application.routes.draw do
  root "posts#index"
  resources :posts do
  end
end
```
ルーティング名は任意でいい（ここではposts)

# 7:コントローラー作る

```ruby:ターミナル
$ rails g controller posts
```


### 8:indexアクション定義
```app/controllers/posts_controller.rb
class ApplicationController < ActionController::Base

  def index
  end

end
```

### 9:ビューファイルを作る
　app/views/postsディレクトリに「index.html.erb」ファイルを作る

#### 10:scssファイル用意する
  app/assets/stylesheets以下の「application.css」を「application.scss」へファイル名変更して、以下のの記述を追加

```app/assets/stylesheets/application.scss
 @import "posts";
```



### 10:hamlを使えるようにする


### 11:hamlのGemファイル入れる（最下部に記述すればOK)
```ruby:Gemfile
gem 'haml-rails'
```


### 12:gemファイル入れたんで、関連ファイルを再度読み込む

```ruby:ターミナル
$ bundle install
```

### 13:erbファイルをhamlに変換する

```ruby:ターミナル
$ rails haml:erb2haml　
```

途中の

```ruby:ターミナル
Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n)
```
にはyで回答
すべてのerbファイルがhamlに変換されているはずです。




### 14：ローカルサーバーを起動

```ruby:ターミナル
$ rails s
```
http://localhost:3000/　
開く

#### あとは「app/views/posts/index.html.haml」と、「app/assets/stylesheets/posts.scss」にコーディングしていくだけです！


### その他
- リセットcssやFont Awesomeなんかは適宜入れてください。
- エラーが出た場合は、一度rails sをcontrol+Cで切ってもう一度rails sしてみてください
- VS Codeの拡張ファイル「Better Haml」入れておくと便利です。（拡張機能がインストールされるとHamlで記述したコードに色がつくようになります。）


### 参考リンク
[YUI（リセットcss）](https://github.com/yui/yui3/releases)
[Font Awesome] (https://github.com/FortAwesome/font-awesome-sass)

### 記事書き終えて
hamlでコード書きたいのに、立ち上げで詰まってる人結構いるかな？と思いまして記事にしようと思い立ちましたが、実際は書いている時にエラーが出まくりまして、
「結局自分が全然わかってなかった」と思い知らされ大変勉強になりました笑

不備などあれば教えていただけると幸いです。
AtCoder ARC002 C-コマンド入力 の嘘解法について

# はじめに
　嘘解法がある問題について、古い問題ということもあり解説が少ないため解説記事を書きます。
　特に、自分が用いているPython言語での解説がネット上に見当たらず苦労したので、
　Python言語でのソースコードともに解説します。
# 問題
　問題文
　　[ARC002 C-コマンド入力](https://atcoder.jp/contests/arc002/tasks/arc002_3)
　解説
　　[公式解説](https://www.slideshare.net/chokudai/arc002)
#嘘解法
　L,Rを列挙し、L,Rどちらかから順に貪欲に置換する、を全通り試す。
　この解法では入力が

  ```
  8
  ABABBABA
  ```
　のようなケースで誤りになることが公式解説において説明されています。
　正解はL=AB,R=BAとすればLLRRと出来るので「4」ですが、
　嘘解法ですと、LLBLAあるいはARBRRとなって「5」となってしまいます。
　ただしこのようなケースがテスト項目に入っていないため、嘘解法でもACになります。

#正しい解法
　公式解説にある通り、動的計画法を用います。
　自分は、i文字目を
　・(j=0) L,Rで置き換えない場合の文字数
　・(j=1) Lで置き換えられて、置き換えた場合の文字数
　・(j=2) Rで置き換えられて、置き換えた場合の文字数
　という3状態を作って解きました。
　このdp表を dp[j][i]と書いています。

　dp[0][i]は、1文字前の時点での文字数の最小値に+1した値です。

  ```
dp[0][i]= min(dp[0][i-1],dp[1][i-1],dp[2][i-1])+1
  ```

　dp[1][i]およびdp[2][i]は、i-1文字目とi文字目をLあるいはRで置き換えるわけですから、i-2文字目までの文字数の最小値に+1した文字数となります。

  ```
if c[i-2:i]==L:
  dp[1][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
  ```
  ```
if c[i-2:i]==R:
  dp[2][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
  ```
　i-1文字目とi文字目がL,Rでなく置き換えられない場合は
　・dp[0][i]をコピーしておく
　か
　・答えよりも大きい値を入れておく(Nとかfloat("inf")とか)
　としておきましょう。
　動的計画法によって最小値を取っていくので、dp[0][i]以上の値が何か入っていれば問題ありません。


#サンプルコード(Python)

```
N=int(input())
c=input()

L_list=["AA","AB","AX","AY","BA","BB","BX","BY","XA","XB","XX","XY","YA","YB","YX","YY"]
R_list=["AA","AB","AX","AY","BA","BB","BX","BY","XA","XB","XX","XY","YA","YB","YX","YY"]

ans=N
for L in L_list:
  for R in R_list:
    dp= [[0]*(N+1) for _ in range(3)]  #初期値として0を代入していますが、本当は大きい値や文字数(i)を代入した方がこの後簡単に書けます

    for i in range(1,N+1):
      dp[0][i]= min(dp[0][i-1],dp[1][i-1],dp[2][i-1])+1
      if i==1:
        dp[1][i]= 1
        dp[2][i]= 1
      else:
        if c[i-2:i]==L:
          dp[1][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
          dp[2][i]=N
        elif c[i-2:i]==R:
          dp[1][i]=N
          dp[2][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
        else:
          dp[1][i]=N
          dp[2][i]=N

    tmp=min(dp[0][-1],dp[1][-1],dp[2][-1])
    ans=min(ans,tmp)

print(ans)

```

#関連リンク
　C++での解説記事を書かれている方
　　[忘れても大丈夫](http://kyopro.hateblo.jp/entry/2019/05/25/120112)
スマホ（iPhone iOS/Android）からワンアクションでTeamsへテレワーク開始連絡

###IFTTT & Teams(Incoming Webhook)
###スマホ操作
####ワンアクション　IFTTTの「テレワーク開始」を押す
![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/2e9b1c67-40ba-80d5-0cf1-42c07afb8849.png)
###実行結果
![12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/7c288cb0-c0cf-0d45-6a74-2496857df2f5.png)
###Teamsで「Incoming Webhook」設定
![00.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/c3827264-e0c3-42c8-f691-abd715785270.png)
###IFTTT設定
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/bb93e934-4442-2d6a-de7b-4bc2b96655dc.png)
![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/59e5b907-79c5-c201-cf8f-a1ff57019d7f.png)
![03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/0155c9a1-271d-8baa-2e8c-6068e839110e.png)
![04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/c3dad788-d202-7db1-ce69-b49706eb069c.png)
![05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/e05289b7-8af1-861d-605a-d7acc83e40f1.png)
![06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/328dc43b-09d2-3bc8-87b7-2d56f5736966.png)
###Body指定
    {"text": "テレワーク開始しました。"}
ダブルクォーテーションが全角の場合エラー
ifttt Unable to make web request. Your server returned a 400
![07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/6ea6614b-42a6-b82d-6c6a-4ccfcd8b4731.png)
![08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/842a79cf-abfc-41c2-c3d4-154bcf722369.png)
###スマホにIFTTTをインストールしてウィジェットを追加
![10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/11721798-dabd-638d-dde8-02049bf26ba8.png)
wsl2のDocker runでexited(139)が起きた場合の回避策

# TL;DR
- CentOS6など、古いベースイメージの起動に失敗（エラーコード：139）が発生することへの回避策

# 動作環境
- Windows 10 Home 64bit (2004)
- Ubuntu 18.04 LTS
- WSL2
- Docker 19.03.08

# 回避策 
まずは、ホストの%USERPROFILE%/.wslconfigに、以下を追記した上で、WSL2を再起動する
:point_up: wsl -t だけではダメそうだったのでPCごと再起動が無難だと思います

```shell
[wsl2]
kernelCommandLine=vsyscall=emulate
```

# 確認
WSL2にログインし、以下のコマンドを実行し、**vsyscall=emulate** が追記されていればOK

```shell
cat /proc/cmdline
-> initrd=\initrd.img panic=-1 pty.legacy_count=0 nr_cpus=4 vsyscall=emulate
```

試しに、centosイメージを起動してみて、Exited(139)になっていなければ解決

```shell
docker pull centos:6
docker run -dti centos:6 /bin/bash
docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6fe6f93cf876        centos:6            "/bin/bash"         4 seconds ago       Up 2 seconds                            dreamy_burnell
```

# 参考URL
[Enable vsyscall=emulate in the kernel config to run older base images such as Centos 6 #4694](https://github.com/microsoft/WSL/issues/4694#issuecomment-556095344)
【alias】よく使うコマンドは省略して登録しよう

##はじめに
コマンドを打つ時に面倒だなとか覚えられないなと思ったことはありませんか。
今回は長いコマンドを覚えなくてもいいように自作のコマンドを登録する方法をまとめます。

##aliasコマンドについて知る
###aliasコマンドとはなにか
>「alias」は、コマンドの別名（エイリアス）を登録したり、表示したりするコマンドです。

引用：[コマンドの別名（エイリアス）を登録する／削除する](https://www.atmarkit.co.jp/ait/articles/1703/24/news012.html)

###すでに登録されているaliasを一覧で表示する

```
$ alias
```

###aliasを追加する
####①.bashrcにエイリアスを定義する
~/.bashrcを開きます。

```
$ vim ~/.bashrc
```

~/.bashrcを開いたら`alias alias 登録名='登録するコマンド'`で追加します。
改行すればまとめて複数のコマンドを追加することができます。

```
alias ll='ls -al'
```

また複数のコマンドを1つに集約したい場合はセミコロンでつなげば登録することが可能です。

```
alias mkdf='mkdir data;touch data/test01.txt'
```

####②.bash_profileに.bashrcを読み込ませる設定をする
.bashrcの設定を反映するためには.bash_profileというファイルに.bashrcを読み込ませてあげる設定が必要です。
すでにこの設定をされていれば以下不要です。
またこの設定は1度のみで大丈夫です。
##

```
$ vi ~/.bash_profile
```

.bash_profileを開いたらファイルの一番下に以下のコマンドを記述します。

```
source ~/.bashrc
```
ここまで完了したら一度ターミナルを閉じて再起動させましょう。

##おわりに
いかがでしたでしょうか。
効率良く開発行うために工夫していくと便利かなと思います。
【python】指定回数繰り返す文字列のaの数を求めるプログラミング。

#【python】指定回数繰り返す文字列のaの数を求めるプログラミング

▼設問

- listで任意の長さの文字列が与えられる（s）
- 文字数が与えられる。(n)
- sを文字数(n)を満たすまで繰り返した中に含まれるaの数を求める。


[URL](https://www.hackerrank.com/challenges/repeated-string/problem)


▼sample input

```python:
s ="aba"
n =10
```

▼sample output

```python:
7
```

```:image
abaabaabaa <- aが7個
```

▼my answer

```python:
def repeatedString(s, n):
    a = s.count("a")
    ans=i=0    
    
    #余った文字に含まれるaの数を求める
    r = n%len(s)
    if r!=0:
        while i<r:
            if s[i]=="a":
                ans += 1
            i+=1
            
    ans += a*int(n/len(s)) 
    return ans    
            

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    s = input()
    n = int(input())
    result = repeatedString(s, n)
    fptr.write(str(result) + '\n')
    fptr.close()
```

- 決められたオブジェクトから要素を抜き出す場合はfor
- 指定条件になるまで繰り返す場合はwhile

<br>
上記while文は「for i in range(r)」で置き換え可能。

```python:whileをforに置き換え
def repeatedString(s, n):
    a = s.count("a")
    ans=0    
    
    #繰り返しの数を求める(math.floorは使わない)
    r = n%len(s)
    if r!=0:
        for i in range(r):
            if s[i]=="a":
                ans += 1
            
    ans += a*int(n/len(s)) 
    return ans    
            
repeatedString(s, n)
```

<br>
####if文を一文にし、内包表記に書き換える。

▼処理

- 余りの文字数文list sから要素を抜き出し、aなら１、それ以外なら0を格納したlistを作る。
- sum(list)で1を足し上げる。

```python:内包表記
def repeatedString(s, n):
    a = s.count("a")
    ans=0    
    
    #繰り返しの数を求める(math.floorは使わない)
    r = n%len(s)
    if r!=0:
        ans =  sum([(1 if s[i]=="a" else 0) for i in range(r)])
             
    ans += a*int(n/len(s)) 
    return ans    
            
repeatedString(s, n)
```

<br>

##補足：MemoryError

指定文字数分の繰り返した文字列を作成し、そこからaの数をカウントしたが、数が大きい場合にMemoryErrorになってしまう。

```python:
s ="babbaabbabaababaaabbbbbbbababbbabbbababaabbbbaaaaabbaababaaabaabbabababaabaabbbababaabbabbbababbaabb"
n = 860622337747
```

▼文字列を求める処理は重い。

```python:
def repeatedString(s, n):
    #繰り上げ（math.floorは使わない）
    if float(n/len(s)):
        r = int(n/len(s)) +1
    else:
        r = n/len(s)
    
    #文字列を求める
    ans = x = 0
    ss = s*r
    for letter in ss:
        x += 1
        if x>n:
            break
        elif letter == "a":
            ans += 1
    return ans
            
repeatedString(s, n)

#MemoryError:
```
PowerShell で Markdown を HTML に変換する（CSS カスタマイズ可能！）

PowerShell 6 以降に追加された `ConvertFrom-Markdown` を使います。

## 環境
```
Name                           Value
----                           -----
PSVersion                      7.0.1
PSEdition                      Core
GitCommitId                    7.0.1
OS                             Microsoft Windows 10.0.18362
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
```

## コード

```PowerShell
function mdPreview {
    param (
        [string]$path,
        [string]$cssUri = ""
    )
    if ((-not (Test-Path $path)) -or ($path -notmatch "\.md$")) {
        return
    }
    $markup = ConvertTo-Html -Head '<base target="_blank">' -Body (ConvertFrom-Markdown -Path $path).Html -CssUri $cssUri
    $outPath = $path -replace "\.md$", ".html"
    $markup | Out-File -FilePath $outPath
    Invoke-Item $outPath
}
```

css へのパス（ローカルも可）を指定してやることで見た目をカスタマイズできます（※ ShiftJIS ファイルを渡すと文字化けするので要注意）。


`ConvertTo-Html` の `-Head` で `<base target="_blank">` としているのはリンクをすべて新規タブで開くためのおまじないです。なお、本来の使い方はオブジェクトをパイプして表形式で綺麗に表示するものらしく、生成される HTML には空の Table タグが含まれますが、実際には表示されないので問題ないかと思います。




`$Profile` などに上記の関数を登録しておき、 VSCode 上で <kbd>Ctrl+K</kbd> + <kbd>P</kbd> でファイルのフルパスをコピーして実行すると便利です。  
ソフトの追加インストール不要で手軽に HTML に変換できるのが強みではないでしょうか。
Homebrewから入れてなさそうなPowerShell Core 6.0.1をアンインストールした話

# はじめに
どうも‪✋(´･ᴗ･\` )‬
今日は素手でPowerShell CoreをMacからアンインストールしたお話です。

どうやってインストールしたのかまるで記憶がないんですが, Microsoftの公式ドキュメント([macOS への PowerShell のインストール - PowerShell | Microsoft Docs](https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7))を確認すると

```zsh
brew cask install powershell
```

と書いてあるので

```zsh
brew cask remove powershell
```

とでも入れてやれば良いだろうと思ったんですが, 

<img width="397" alt="スクリーンショット 2020-06-06 11.34.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/e6fed81d-5f8d-cb86-06f9-7b0b1361598c.png">

Homebrewで入れていないらしい。。(スクショはないですが `brew cask list` でインストール済みパッケージを確認してもありませんでした。)
今はこういう作業するとWiki(Atlassian Confuluence)に記録してるんですが, これをインストールした時はそういう習慣はなく…
Homebrewを使わずにインストールする方法を探してみたものの私は見つけられませんでした。

でも

```zsh
$ which pwsh
/usr/local/bin/pwsh

$ ls /usr/local/bin/pwsh
lrwxr-xr-x  1 root  wheel    42B  2  3  2018 /usr/local/bin/pwsh -> /usr/local/microsoft/powershell/6.0.1/pwsh
```

という感じですしこれは素手でアンインストールできそうだなぁということでやってみたのでその実践記録です。

# 環境
|項目|値|
|:---|:---|
|OS|macOS Mojave 10.14.6|
|PowerShell version|6.0.1|
|Homebrew version|2.3.0|

# 手順
① まず上記の通り, `pwsh` のバイナリの場所を探す

```zsh
$ which pwsh
/usr/local/bin/pwsh

$ ls /usr/local/bin/pwsh
lrwxr-xr-x  1 root  wheel    42B  2  3  2018 /usr/local/bin/pwsh -> /usr/local/microsoft/powershell/6.0.1/pwsh
```

② `/usr/local/microsoft/` 配下にはPowerShell Core 6.0.1関連のファイルしかないようなので `/usr/local/microsoft/` ごと削除する(もしこの方法をお試しいただく方で `/usr/local/microsoft/` 配下にPowerShell Core以外のファイル等がある場合はご注意ください)

```zsh
$ sudo rm -rf /usr/local/microsoft 
```

③ `/user/local/bin` にあったシンボリックリンクを削除する

```zsh
$ rm /usr/local/bin/pwsh
```

④ なくなったことを確認

```zsh
$ which pwsh
pwsh not found
```

以上です。

# さいごに
簡単な手順でしたが書き起こしてみるとあまりにも簡単で記事にしなくても良かったのでは…という感じですがまぁ忘備録として…

ちなみにこの手順は2020年3月にリリースされたPowerShell 7を入れたくて実施しました。
HomebrewでPowerShellを入れている場合は

```zsh
$ brew cask upgrade powershell
```

で簡単にアップデートできますので是非お試しください。

私の環境も無事HomebrewでPowerShellのパッケージを管理するようになりましたので, 早速PowerShell 7を入れて使っています:tada:

<img width="395" alt="スクリーンショット 2020-06-06 12.12.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/85d4b53d-49a6-bea4-fba9-25dc680808d8.png">
縦書きで文字を書きたい人のためのCSS

# 概要
CSSで文字を縦書きにしたい！

# 実装
こんなHTMLがあるとします。この3つを縦書きにしたい場合を考えてみます。

```html:html
<div class="japanText">縦書きで文字を書きたい</div>
<div class="japanText">縦書きで文字を書きたい</div>
<div class="japanText">縦書きで文字を書きたい</div>
```

以下のCSSを足すだけで完成です。

```css:css
.japanText{
    writing-mode: vertical-rl;
    display: inline-block;
    font-size: 20px;
    padding: 5px;
}
```

`writing-mode: vertical-rl;`を指定することで縦書きになります。

あと、divはブロック要素なので、inline-blockに変更してあげるといい感じになります。
ただ、古いバージョンのブラウザの場合動かない可能性ありです。お気をつけてください〜

<img width="274" alt="スクリーンショット 2020-06-06 12.13.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486805/2a3e0534-965e-1286-2503-26c2f3dd0d24.png">
DenoでEJSをレンダリングする

#概要
Denoでビューエンジンを使用してテンプレートエンジン「EJS」をレンダリングします。
テンプレートエンジン「EJS」は、HTMLをサーバー処理するために使用します。

**ディレクトリ構成**

```shell
/
├──public
　  ├──index.ejs
app.ts
```

##モジュールをインポート
以下、２つのモジュールをインポートします。
・サーバーレイヤーを作成するために```oak```
　https://deno.land/x/oak
・HTML（レイアウト）を提供するビューエンジン
　https://deno.land/x/view_engine

```typescript:app.ts
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
import { viewEngine, engineFactory, adapterFactory } from "https://deno.land/x/view_engine/mod.ts";
```

ポートをリッスンするために```Application```クラスとルートレイヤーを提供するために```Router```をインポートしています。

##アプリケーションの初期化
インポート後に```Application```と```Router```を初期化します。

```typescript:app.ts
const app = new Application();
const router = new Router();
```

アプリケーションを初期化した後、ビューエンジンを使用するようにアプリケーションを構成します。

```typescript:app.ts
const ejsEngine = await engineFactory.getEjsEngine();
const oakAdapter = await adapterFactory.getOakAdapter();
```
　

ビューエンジンのボイラープレート（定型書式）の準備ができましたら、
次のコードでビューエンジンをミドルウェアとしてアプリケーションに渡します。

```typescript:app.ts
app.use(viewEngine(oakAdapter, ejsEngine));
```

##ルート作成
次にルートを作成します。
レンダリングするejsファイルを指定して、任意のdataを渡す設定をします。

```typescript:app.ts
router.get('/', (ctx: any) => {
  ctx.render('./public/index.ejs', { data: { message: 'Hello' } })
});
```

ルーターを必要とするミドルウェアを追加します。

```typescript:app.ts
app.use(router.routes());
app.use(router.allowedMethods());
```

##アプリケーションを提供
これで```app.ts```ファイルが完成したので、
リッスンしてアプリケーションを提供します。

```typescript:app.ts
console.log('http://localhost:8000/');
await app.listen({ port: 8000 });
```
　

###完成イメージ

```typescript:app.ts
import { Application, Router } from 'https://deno.land/x/oak/mod.ts';
import { viewEngine, engineFactory, adapterFactory } from 'https://deno.land/x/view_engine/mod.ts';

const app = new Application();
const router = new Router();

const ejsEngine = await engineFactory.getEjsEngine();
const oakAdapter = await adapterFactory.getOakAdapter();

app.use(viewEngine(oakAdapter, ejsEngine));

router.get('/', (ctx: any) => {
  ctx.render('./public/index.ejs', { data: { message: 'Hello' } })
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log('http://localhost:8000/');
await app.listen({ port: 8000 });
```

##EJS構文のHTMLタグ追加
最後に次のようにEJS構文のHTMLタグを追加します。
そうすることで、```app.ts```から渡された```message```を受け取ることができます。

```html:index.ejs
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
	</head>
	<body>
		<p><%= data.message %></p>
	</body>
</html>
```
　

##動作確認
次のコマンドを実行します。

```shell
$ deno run --allow-net --allow-read app.ts
```

以下にアクセスして```Hello```と表示されればOKです。
http://localhost:8000/
試験 MS-900: Microsoft 365 Fundamentals 自宅から受けてみた

# はじめに
Microsoftの資格　「MS-900:Microsoft 365 Fundamentals」を
2020年4月に自宅から受験し合格したので、所感を述べます。
https://www.pearsonvue.co.jp/microsoft/onvue

※2020年4月現在の情報です
※AWS認定資格もオンライン試験ができるようになった模様！ 
https://aws.amazon.com/jp/blogs/training-and-certification/aws-certification-exams-now-available-virtually-for-added-convenience-and-flexibility/
https://www.pearsonvue.co.jp/Clients/Amazon-Web-Services/Online-Proctored.aspx

#MS-900について
- Microsoft 365に関する基礎的な試験です

- 公式サイト参照
https://docs.microsoft.com/ja-jp/learn/certifications/exams/ms-900?wt.mc_id=learningredirect_certs-web-wwl


#試験勉強
- Microsoft Leran
おおよその概要や各種コンソールの操作方法が学べます
https://docs.microsoft.com/ja-jp/learn/paths/m365-fundamentals/
Microsoft 365に限らず、勉強用のドキュメントが充実しており知識習得にとても役立ちます


- Microsoft 365公式ドキュメントなど
AzureやAWSは問題集やUdemyなどの試験問題コンテンツが充実していますが、M365は情報が少なく苦労しました
製品説明のページや公式ドキュメントをみて各製品の知識を得る必要があると思います
https://www.microsoft.com/ja-jp/microsoft-365/compare-microsoft-365-enterprise-plans 
https://docs.microsoft.com/ja-jp/microsoft-365/?view=o365-worldwide

#自宅からのPearson VUE試験を受ける
- @maco-san　様の記事がとても参考になりました
https://qiita.com/maco-san/items/011d96cc213ee1e165f4

- 公式ドキュメントも要参照
https://www.microsoft.com/ja-jp/learning/online-exams.aspx

- 試験の開始時間に注意
24時間？受験可能なようです。
実は不注意でPM2時開始のテストを申し込んだはずがAM2時で申し込んでおり、受験できなかった苦い記憶があります

- 試験の開始方法がわかりづらい
    - 試験開始時間の30分前くらいにmicrosoftの試験予約サイトにアクセスし、OnVUEにログインしておきます。
    - ログイン状態で試験開始時間を待っている必要があります
https://www.microsoft.com/ja-jp/learning/dashboard.aspx

    - 開始時間を過ぎたら試験監督官とチャットでやり取りしたのち、試験開始となります

#所感
- MS-900の所感
    - 会社のIT部門の方が、Microsft365を導入する際の最適解をこたえる。というような印象をうけました。ライセンスによりできることの違い、オンプレとM365の機能の違い、M365の各種サービスでできる内容など
    - 知っていないと解けない問題が多い印象でした(受かったのは運がよかったと思っている)。公式ドキュメントをしっかり学習する(理解して覚える)必要がありそうです
- オンライン受験の印象
    - 試験会場に行かなくてよいのはとても楽！
    - 試験開始時間も選択肢が増え(枠が空いていれば深夜や早朝受験も可能)、受験のハードルが下がった印象です
    - 試験会場についたときは、独特の緊張感があると思いますが、家だと緊張感も何もないので、「よし試験うけるぞー」という緊張感を出すのは少し難しいかも
『知識ゼロから学ぶソフトウェアテスト』を読んで知った「テストの種類」と「テストに大事なこと」

「[知識ゼロから学ぶソフトウェアテスト 【改訂版】](https://www.amazon.co.jp/dp/B00HQ7S5CA)」という本が良書と聞き、最近読みました。読んで、各種テスト手法とテスト手法にかかわらず大事なことについてまとめています。


## テストで大事なこと

- テストで大事なのは、どの部分にバグが出やすいか、そこをどのようにテストすれば十分な品質が得られるかを知ること
    - バグは平均的に散らばっているものではない。バグの出やすい箇所、出にくい箇所がある。(80%のバグが20%のコードに含まれているというデータもある)
- テストは限られた時間で行う最大公約数的な仕事。時間がないからテストしないという選択肢はない
- ソフトウェアは4つの仕事しかしない。その4つの振る舞いに対して適切にテストすれば、ほとんどのバグが発見できる。その4つとは
    - `入力を処理する`
    - `出力を処理する`
    - `計算を行う`
    - `データを保存する`
    

- テストケースを省略するのはやむを得ないが、その省略されたテストケースでバグを出してはいけない
- テストするのに「良いデータ」と「悪いデータ」が存在する
    - 良いデータ例
        - ユーザーがよく使いそうなデータ
        - プログラムが許す最小のデータ
        - プログラムが許す最大のデータ
        - ゼロ
    - 悪いデータ例
        - 非常に小さなデータ(-99999,0.0000001など)
        - 非常に大きいデータ(999999,1099999など)
        - 長いデータ(abdajohadamklmdklamombamoaなど)
        - 無効なデータ
- とっとと楽して60%のバグを見つけ、そのほかのバグがなぜ発生したか、どうやって防止するかに時間を費やすかが、より建設的なテスト担当者の役割
- 品質を目に見えるものにするには
    - なるべく誤差がなく人間の市場や恣意に左右されないものを選ぶ
    - 開発するソフトウェアの品質を十分代表するものを選ぶ
- Googleのバグ予測システムでは、いつ何回修正されたかしか見ていない。修正された回数が多いほど、修正が最近ほどバグが潜んでいるということ。

# テスト手法

## ホワイトボックステスト

- プログラムの論理構造が正しいかを解析するテスト
- 人間の時間をたくさん使って内部構造を解析しテストする
- 論理構造の正しさのみをテストするため、 `ソフトウェアの仕様が間違っていることから起こるバグは発見できない。`

### 制御パステスト

- プログラムがどのような振る舞いをして、どのように制御されていくかをテストする手法
- 命令や条件分岐、繰り返しなどの処理(=制御パス)に対するテスト。
- テストの網羅率をカバレッジと呼ぶ。
- 制御パステストによるコードカバジテストの本質は、フローチャートをちゃんとカバーすることにある

### ステートメントカバレッジ(=命令網羅率)

- 制御パステストの一部
- プログラムコード内部の命令文（=ステートメント）の結果を少なくとも1回ずつ持つようにテストケースを書く
- ステートメントカバレッジだけでテストを終了することは危険
- 分岐条件がカバーしきれないなど、非常に弱いテスト手法

### ブランチカバレッジ

- `分岐コードに対してそれぞれの判定条件がTrue/Falseの結果を少なくとも1回ずつ持つようにテストケースを書く`
- 分岐を網羅するため、テストケースの数がかなり増える点が問題点
- バグの発生状況を見てから、バグがたくさん出る部分に対してブランチカバレッジを実行するのは悪くないアイデア

## ブラックボックステスト

- ブラックボックステストは、プログラムをブラックボックスと見立てて、 `様々な入力を行うことによって、ソースコード利用せずテストを行う手法`

### 同値分割法

- 同値分割とは、入力領域を「同値クラス」という部分集合に分割し、その部分集合に入る入力値を透過とみなす作業
- つまり、可能な入力値のうち同等の入力値は等価とみなしてテストする手法
- 同値クラスの分け方は
    - 有効同値：プログラムが期待する入力値
    - 無効同値：有効同値以外の入力値
- 実践的な同値クラスの選び方は、 `ポイントは代表する同値が全てのエレメントを網羅しているか`

### 境界値分析法

- 同値分割法とセットで使われる手法
- プログラムで「境界(=条件分岐の分岐点)」と呼ばれる場所は常にバグが潜んでいるので、境界値近くは詳しくテストする必要がある

## ランダムテスト/アドホックテスト

- テストケースを考えず、行き当たりばったり、なんら考えなしに入力や操作を行う手法


## 探索的テスト

- ソフトウェアの理解と、テスト設計と、テスト実行を同時に行うテスト
- すべてのテストを実施するのは時間的に無理、できてもすべてのバグは見つからない。
- ならば`テストケースを書く代わりに、製品を学習ながらテスト設計して、実行して、バグ報告を並行すれば手っ取り早い`というスタイル
- 探索的テストの唯一のデメリットは、非機能要求(=品質特定)のテストにあまり向かない

## 非機能要求のテスト

- 非機能要求(=品質特定)とは、「ソフトウェアが持つべき特性」で、機能的な側面と非機能的な側面の両方の属性を示したもの。
- とくに大事なのは、`機密性(セキュリティ)、信頼性、パフォーマンス`
GitHubはどれくらい使われているのか？



# ソースコードコラボレーションしたい

私が所属する企業では至るところでソフトウェア開発が行われているのですが、現場によってソースコードの管理方法もまちまちという状況です。開発に関する責任は現場で取ればよいのですが、ソースコードの管理ツールを統合することで権限管理も適切に運用できますし、ツールの利用ライセンスも安くできるので折角なら統合したいと考えてます、というのが前提です。

# GitHub ってどれくらい使われてるの？

なんとなく、バージョン管理ツールはGitHub/GitHub Enterprise一択のような気がしますが、導入した際の経済的なメリット（ROI）と合わせて、現在の市場シェアも知りたくなりました。元エンジニアの端くれとしては今後Gitを使わない開発はありえないし、エンジニアを採用する際はGitをきちんと理解しているエンジニアを採用したい、またそういったエンジニアはGitHubが使えないと離れていってしまう（私見）。Gitを使うだけならGitLabという選択肢もあるが、なんとなくGitHubのほうがデファクトスタンダードのようにも感じる。では実際にどれくらいGitHubが使われているか調べてみました。

# 情報ソース
IntelliJを開発しているJETBRAINSが2019年にエンジニア約19000人を対象にアンケートを実施しており、その生データがあるのでここから集計しています。

（但し、アンケートの設計上「ソースコードコラボレーションをやっているけど、何を使っているかわからない」みたいな回答が可能になっているので、データの信憑性はそこそこと判断していただきたい）

# 結果
## 普段使っているツールは？
- ソースコードコラボレーションツールを使っている(GitHub, GitLab, Bitbucket)... 84.3%

既に多くの開発者がソースコードコラボレーションツールを使っているとのこと

## ソースコードはどこで管理している？
- クラウド上(GitHub.com, Bitbacket) ... 27.4%
- デプロイされた場所(GitHub Enterprise, GitLab) ... 18.2%
- その他 ... 1.2%

なんか数字が合わない…アンケートデータを確認すると、「ソースコードは管理されているのは知っているが、何を使っているかを答えていない人」が結構な割合（半数程度）いる。

余談だが、以前、採用面談で「ソースコード管理はSourceTree使ってます！」って元気よく答えてきたエンジニアを思い出した。

## バージョン管理ツールとして使っているものは？
- Git ... 38.19%
- SVN ... 3.93%
- Visual Studio Team Service ... 1.9%
- Microsoft TFS ... 1.7%
- 使ってない 1.9%

回答は重複を許すため、アンケート総数から割合を算出した。数字が小さいツールは割愛している。やはりGitが圧倒的。

## ソースコードは何で管理している？
- GitHub ... 24.5%
- GitLab ... 13.7%
- Bitbacket ... 12.1%

こちらも回答は重複を許すので厳密ではないが、全エンジニアの約1/4はGitHubを（GitHubであると認知した上で）使っている模様

# まとめ
ランチェスター戦略において、業界トップとなるための市場占有率の下限目標値は26.1%ということなので、GitHubは現時点でほぼ業界トップ・強者の地位であると言えます。一方で、GitLab・Bitbacketとはシェアは10ポイント差がついていますが、まだ完全に抜け出せているとは言い難いです。

まあこんな分析をしても、結局はOctocatが可愛いという理由でGitHubを使うんですけどね。


データ出典：https://www.jetbrains.com/lp/devecosystem-2019/
（JetBrains公式の数字とは違いますが、母数の計算方法が公式と異なるためです。ご承知ください。）
【IntelliJ IDEA】メモリ使用率を画面上に表示させる方法

IntelliJのメモリ使用率を画面上に表示させる方法が[以前](https://intellij-support.jetbrains.com/hc/en-us/articles/206558169-Performance-and-memory-problems)と変わっていたので忘備録としてまとめておきます。

## 環境
- MacOS Catalina 10.15.4
- IntelliJ IDEA 2020.1.2 (Ultimate Edition)

## やり方
画面右下を右クリック→「Memory Indicator」をチェック
<img width="317" alt="スクリーンショット 2020-06-06 11.52.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/f9d3138e-99af-2063-ea5d-c33a1c50d264.png">

下の図のように画面右下にメモリ使用率が表示されていればOK
<img width="219" alt="memory_indicator.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/10ae3eba-8198-6915-0167-23d53efd7e0d.png">

ちなみに以下でも設定できる。
「View」->「Appearance」->「Status Bar Widgets」->「Memory Indicator」をチェック
<img width="766" alt="setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/2c3d89a4-557d-a4fc-4b1e-56dbfd2d8550.png">

## 参考
https://www.jetbrains.com/help/idea/increasing-memory-heap.html#enable-memory-indicator
AWS Lightsail でSSHを切った後もプロセスを続けて欲しい

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) ログアウトした後もプログラムを実行し続けて欲しい。最小手数でやりたい。

##やること
AWSのLightsailにSSHから入ってpythonなどを実行すると、SSHを切った途端、プロセスも終了してしまいます。
そこでSSHを切っても内部的にはプロセスをやり続けてもらうように一工夫します。調べた中で一番簡単と感じた方法です。
データ処理などの重い計算をやってもらう時に便利です。

##環境

- AWS Lightsail
- ubuntu(wordpress入り)

##ポイント
- nohupという方法があるようだが、うまくいかなかった。
- tmuxという方法もあるようだが、インストールが必要だしよくわからない。
- screenで解決できるらしい。

##参考
https://qiita.com/IshitaTakeshi/items/531e4c9c1782a7549a62

##やり方
```sh:
$ screen ＜実行したいコマンド＞
```
$ screen python sample.py のような感じで実行するだけです。
実行後はCtrl + A のあと Ctrl + D とするとシェル画面に戻れます。

仮想スクリーンを立ち上げてそのシェル上でコマンド実行を行うので、仮想スクリーンを離れても、つまりターミナルからSSHを切ってもプロセスが中断されない、という仕組みのようです。

##プロセス確認や復帰の方法
再ログインした後などに、

```sh:
$ ps r
```
とすると、実行中プロセスのPID（プロセスID）が表示されるので稼働状態を確認できます。

プロセスを止めたい場合には

```sh:
$ kill ＜PID＞
```
で停止できます。

プロセスを実行したシェルに戻りたい時は、

```sh:
$ screen -ls
```
でリストを表示し、PID（行の冒頭の数字）を確認してから

```sh:
$ screen -r ＜該当のPID＞
```
とすると、プロセスを実行したシェル画面に入れます。

##わからないところ
この方法でプロセスを何日でも永遠に続けてくれるのかどうかはまだわかりません。
ScrollReveal()を簡単に使う！要素・文字・画像にアクションを。

#はじめに
スクロールをした時に指定の要素やテキストなどにアクションを加えて動かすことができるScrollReveal()です。hpやportfolioなどの作成する時簡単にできてしまうので実践してみて下さい。

#方法
まず、プロジェクト中のディレクトリにファイルをインストールします。

https://github.com/jlmakes/scrollreveal
githubからインストールすることが可能です↑

```terminal
npm install scrollreveal
```
今回使用するhtmlなどが入ったディレクトリにターミナルもしくはコマンドにてインストールします。

以下がサンプルの関数です。
各機能の説明を軽く載せています。
数値は適当なので自分の目的に合わせて下さい！

```javascript:sample.js
ScrollReveal().reveal('class名',{
      origin:'right', <!--//アニメーションの始まりの場所、top,right,bottom,leftで指定ます-->
      distance: '100px', <!--//要素が表示するときに公式の場所まで移動する距離、pxやem、％、vwで指定します-->
      scale:'0.5', <!--//表示される前の要素のサイズ、1で100%の大きさです-->
      rotate:{x:0, y:0, z:0}, <!--//-->
      duration: 1200, <!--//アニメーションがどのように遷移するか（ease or ease-in等）-->
      delay:500, <!--//アニメーションが実行されるまでの時間（ミリ秒単位）-->
      opacity:0.5, <!--//０〜１で指定。数が小さくなるにつれて透明になります。-->
      mobile:true or false <!--//携帯端末でも対応させるかどうか-->
    }); <!--//その他に沢山あります。scrollrevealで検索してみて下さい。-->
```


今回わかりやすくするためにhtmlにjavascriptを記入しています。
以下を実行してみると、文字が右から流れて来るようになっています。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>How to use ScrolleReveal.</title>
    <script src="./js/scrollreveal.min.js"></script>
  </head>

  <body>
    <div class="lesson">
      <p>Hello World</p>
    </div>

    <script type="text/javascript">
    ScrollReveal().reveal('.lesson',{
      origin:'right',
      distance: '100px', 
      scale:'0.5',
      rotate:{x:0, y:0, z:0},
      duration: 1200, 
      delay:500
    });
    </script>
  </body>
</html>
```

とっても簡単にできましたね。
覚えるためにはとにかく手を動かし、実行するのみですね。
頑張っていきましょう！


参考文献は以下のhpです。
参考させていただきありがとうございます。
https://github.com/jlmakes/scrollreveal
ttps://scrollrevealjs.org/
ep2c5t144ボード

#概要

ep2c5t144ボード、買ってみた。

#写真
![CIMG2949.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/25a4c8a3-f0c3-f4bf-2f45-1f5607083f3d.jpeg)


#回路図
![CIMG2954.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f22ff271-9264-bdaa-e868-24867483ce51.jpeg)

#動作

5v投入すると、3個のLEDが同時に点滅する。1秒間隔？

#I/O

LED2    pin_3
LED4    pin_7
LED5    pin_9
key     pin_144
osc_50m pin_17

#fpga

EP2C5T144C8N

以上。
Selenium＋Pythonでスクレイピングその２

# 前回のおさらい

Chromeのプロファイルパスに事前にセッションを持つことで無事に画像認証を突破してSelenium＋Pythonでのスクレイピングができるようになりました。
https://qiita.com/shioharu_/items/225f38c23a652459962f

質問で「ログインを事前に行ってセッションをあらかじめ持っておく方法でしたっけ？」と確認があったので、
今回は事前にログインせず画像認証のところだけのみ手動ログインして行う待機処理の方法でスクレイピングを実施します。

## 待機処理

「5. 待機 - Selenium Python Bindings 2 ドキュメント」

https://kurozumi.github.io/selenium-python/waits.html

## 明示的な待機

> 5.1. 明示的な待機
明示的待機とは、特定の条件が発生するのを待ってからコードを進めるコードです。これの最悪の場合は、time.sleep()であり、条件を待機する正確な時間に設定します。必要な時間だけ待つコードを書くのに役立つ便利なメソッドがいくつか用意されています。WebDriverWaitとExpectedConditionを組み合わせることで、これを実現できます。

ふむふむ。ではまず最悪の場合をやってみましょう。

## 明示的な待機サンプルソース

```wait_test.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,1024')

driver = webdriver.Chrome(options=options)
driver.get('https://p.eagate.573.jp/game/2dx/27/ranking/weekly.html')
time.sleep(120) # この間にログインを行う
driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[2]/form/div[2]/ul[1]/li[3]/input").click()
time.sleep(3)

driver.execute_script("window.scrollTo(0, 800)")
time.sleep(3)

driver.save_screenshot('sample.png')
driver.quit()
```

確かに実現できました。
しかし、当たり前ですが早くログイン出来たら待ち時間がありますし、もし時間内にログインできなかったら不発になります。
効率が悪くなってしまいますね(-_-;)

## 暗黙の待機

>5.2. 暗黙の待機
暗黙の待機はすぐに利用できない要素(または複数要素)を見つけようとする時、WebDriverにDOMを一定時間ポーリングするように指示します。デフォルトの設定は0です。一度設定されると、暗黙の待機がWebDriverオブジェクトの有効期間に設定されます。

```
from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
```

というものがありました。

つまるところ、

1. 暗黙の待機を利用したスクレイピングを行う。
2. ログインが必要な画面は、まだログインされてないのでログインしてください画面に飛ぶ。
3. 暗黙の待機により待機時間中はログインしない限りログイン後の要素を探し続ける。
4. 待機されている画面でログインを行う。
5. ログイン後の要素を発見し後続の動作を実行する。

といった具合になるはず、ということです。
やってみましょう。

## 暗黙の待機サンプルソース

```wait_test2.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,1024')

driver = webdriver.Chrome(options=options)
driver.implicitly_wait(120)
driver.get('https://p.eagate.573.jp/game/2dx/27/ranking/weekly.html')
driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[2]/form/div[2]/ul[1]/li[3]/input").click()

driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[7]/table/tbody/tr[201]/td[8]")
driver.execute_script("window.scrollTo(0, 800)")

driver.save_screenshot('sample.png')
driver.quit()

```

実現できました！！！

## 総評

* 無事、事前ログインせずとも画像認証を突破することができました。
* 思ったよりもお手軽にできたのでSelenium Python Bindings のドキュメントはよく読もうと思いました。