OmniAICreator/Qiita-1.07M huggingface dataset:
Rubyのsendメソッドを使用するメリットと注意点

Qiita初投稿です。よろしくお願いします。

# はじめに
Rubyのsendメソッドを仕事中に使用する機会があり、便利！と思ったものの、慎重に使う必要があることがわかったのでまとめました。

# 参考文献
[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/現場で使える-Ruby-Rails-5速習実践ガイド-大場寧子/dp/4839962227)

# sendメソッドとは
レシーバーが持っているメソッドを、文字列（またはシンボル）で指定して呼び出します。
つまり、メソッドを動的に呼び出すことができます。

# どんなときに使えるか
以下のように、caseの値によって呼び出すメソッドが異なる場合、caseが増えれば増えるほどコードが膨らんでいき、可読性が下がります。

```ruby
# 値によって実行するメソッドを分岐させる
class Shape
  def create_shape(shape_type)
    case shape_type
    when "circle" then
      create_shape_circle
    when "square" then
      create_shape_square
    when "triangle" then
      create_shape_triangle
    end
  end

  def create_shape_circle
    ...
  end

  def create_shape_square
    ...
  end

  def create_shape_triangle
    ...
  end
end

shape = Shape.new
shape.create_shape("circle")
```

上記のコードをsendメソッドを使って書き直すとこうなります。

```ruby

class Shape
  attr_accessor :shape_type

  def initialize(shape_type)
    @shape_type = shape_type
  end

  def create_shape_circle
    ...
  end

  def create_shape_square
    ...
  end

  def create_shape_triangle
    ...
  end
end

shape = Shape.new("circle")
shape.send("create_shape_#{shape.shape_type}")
```

メソッドを動的に呼び出せるため、caseでの分岐が不要になりました！
ただし、sendに渡す値によっては、sendを使用せずにメソッドを固定的にコーディングした方が良い場合があります。

# sendメソッドに渡してはいけない値
sendメソッドは動的にプログラムの動作を変えられる反面、使い方を誤ると深刻なセキュリティ問題を引き起こす恐れがあります。

特に、ユーザーからの入力をそのままsendに引き渡すと、意図せぬ範囲のデータやプライベートメソッドにまで影響が及ぶ可能性があります。

例）悪意のあるユーザーが「exit」と入力した場合、それがsendに渡されるとアプリケーションが終了してしまう。
※exitはKernelモジュールに定義されているメソッド。KernelモジュールはBasicObject以外のすべてのクラスで使用可能。

そのため、外部から入力された値によって呼び出すメソッドを分岐させる場合は、最初のcase文の例のように、ユーザーの入力を切り分けて個々のメソッドの呼び出しを固定的にコーディングした方が安全です。

# まとめ
sendメソッドは動的なメソッド呼び出しができて便利だが、セキュリティ面を考慮し、外部の入力に依存する値は渡さないようにする。
【初心者向け】EclipseでJUnit5を使ってみた

__※すべての情報は記事作成当時のものです.__

# JUnitとは
>Javaプログラムの単体テストを自動で行うためのフレームワーク[1]

# 動作環境
ハードウェア: MacBook Pro (Retina, 13-inch, Mid 2014)
OS: MacOS Mojave 10.14.3
IDE: Eclipse 2019-03 （日本語化済）

# EclipseでJUnit5を動かせるようにする
といってもEclipseはJUnitを標準で導入しているので, 新しくinstallするものはない. 
<br>
1. 「プロジェクト・エクスプローラー」にて, JUnitを使うプロジェクトを右クリック.
2. 「プロパティ」をクリック. 
3. 「Javaのビルド・パス」を選択し, 「ライブラリー」をクリック. 
4. 「ライブラリーの追加」をクリック. <img width="766" alt="スクリーンショット 2019-06-16 15.36.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210617/a1de5c8a-6e7f-3801-8e45-83b36b98d989.png"><br>
5. 「JUnit」を選択し, 「次へ」をクリック. <img width="525" alt="スクリーンショット 2019-06-16 15.36.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210617/5611a9dc-96b1-00af-ddf2-636ab1a90d72.png"><br>
6. 「JUnit ライブラリー・バージョン」で「JUnit 5」を選択し, 「完了」をクリック. <img width="545" alt="スクリーンショット 2019-06-16 15.37.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210617/e91086cb-38f9-6a31-d569-791d2c1cefc8.png">


# 次は
テスト対象クラスをJUnit5でテストしてみる（そのうち記事作成）

# 参考
[1] <a href="https://ja.wikipedia.org/wiki/JUnit">JUnit - ウィキペディア</a>
モバイルファーストインデックスがデフォルトで有効になります

## 概要
2019/07/01より、新しく公開されるサイトは、モバイルファーストインデックス(Mobile-First Indexing: MFI) がデフォルトで有効になることが発表されました。 [^1]

[Official Google Webmaster Central Blog: Mobile-First Indexing by default for new domains](https://webmasters.googleblog.com/2019/05/mobile-first-indexing-by-default-for.html)

これを踏まえて、そもそもモバイルファーストインデックスとは何か、どういう対応をすれば良いのかを軽くおさらいします。

## モバイルファーストインデックスとは
モバイルファーストインデックスとは、スマートフォン用Googlebotでクロールを行うことによって、モバイル版のページをインデックスに使用することを指します。
それにより、主にモバイルユーザーが、探している情報を見つけやすくすることになります。

従来であればデスクトップ版のコンテンツがインデックスされていたところが、モバイル版のコンテンツがインデックスされるように変わるため、使用されるインデックスが1つという点に変わりはありません。
また、検索結果には、デスクトップ版URLでもモバイル版URLでも、ユーザーに最適なURLが引き続き表示されます。

### SEOへの影響
モバイルファーストインデックスは、モバイルフレンドリーの評価とは異なりランキングの方法ではないため、従来の方法でインデックスされたコンテンツと比較して優位性があるわけではありません。

## 対応
以下のサイトでは対応は**不要**です。

* レスポンシブウェブデザイン
* Canonical AMP
* デスクトップ版サイトしか存在しない

上記を満たさない、**動的配信を行う場合やURLが異なる場合**は以下の対応が**必要**です。  

* モバイルサイトにはデスクトップ版サイトと同じコンテンツを含める
* 構造化データをサイトの両方のバージョンで指定する
* メタデータをモバイルとデスクトップ版のどちらのサイトにも設定する


## 参考にしたリンク
[ウェブマスター向け公式ブログ: モバイル ファースト インデックスを開始します](https://webmaster-ja.googleblog.com/2018/03/rolling-out-mobile-first-indexing.html)
[Google Developers: モバイル ファースト インデックスに向けて準備する](https://developers.google.com/search/mobile-sites/mobile-first-indexing)

[^1]: 2019/07/01以前は、モバイルファーストインデックス対応が完了したサイトから順次有効になっていました。
Vagrant -> Ansible -> ruby_その２（Vagrantfile）

# 概要
今更ながらにVagrant+Ansibleの環境構築を初めてやってみました。
満足できる環境が出来上がるまでおおよそ１ヶ月。
せっかく苦労して書いたのに何もかも忘れていくのも寂しいので、
こちらに記述しておくことにしました。

今回はVagrantで環境構築するにあたり、すぐAnsibleが使えるようになるまでを
Vagrantfileに書きました。

本記事は連載シリーズです。全３回です。
[Vagrant -> Ansible -> ruby_その１（概要）](https://qiita.com/drafts/608aa74ed458ec628f4d)
[Vagrant -> Ansible -> ruby_その２（Vagrantfile）]
[Vagrant -> Ansible -> ruby_その３（Ansible - playbook）](https://qiita.com/KurokoSin/items/5c940ce860df5b7f5fef)

# ソース
[Vagrantfile 全文](https://github.com/kurokoSin/Burgessochaeta/blob/master/Vagrantfile)

# プロビジョニング作成中に思ったこと
## その１　日本語化しない
日本語化するにあたり、[Ubuntu Japanese Teamのページ](https://www.ubuntulinux.jp/japanese)を参考にして実装してみましたが、多岐に渡るパッケージをダウンロードしてきました。
使い始める際には大変たすかるのですが、環境構築の段階ではクラッシュ＆ビルドを繰り返す場合、
時間がかかってしまいますので、はずすことにしました。

## その２　プロビジョニングは最低限に。Ansibleのplaybookで出来るだけ構築する。
プロビジョニング機能は強力で、Ansibleでやりたい事は全部できてしまいそうでしたが、
そうすると本番環境の構築で使いまわせなさそうなので、vagrantで行う範囲を
最小限（Ansibleインストールまで）にすることにしました。
 
## その３　プロビジョニングは分けて書く。
最初は一気通貫に書いていましたが、rootでやりたいコマンドとユーザでやりたいコマンドが
出てきてしまい、分けてかけることがわかりました。
それからは（自分ルールの)意味単位で分けて書くようにするとVagrantfileが見やすくなりました。

## その４　DNSの参照先はGoogleに設定
拾ってきたboxが外国仕様のせいなのかaptの更新がタイムアウトしてしまいます。
最初はなぜ繋がらないのか分からず、ドメイン名でpingすると繋がらないけど、
インターネット上のアドレスをIPアドレスでpingすると応答を得られたことから、
名前解決に失敗していたことがわかりました。
で、/etc/resolve.confを編集するのではなく、`/etc/systemd/resolved.conf`を
編集しました。

```text:Vagrantfile(抜粋）
control.vm.provision "shell", inline: <<-SHELL
  # DNS config
  sed -i.bak -e "s/^DNS=.*$/DNS=8.8.8.8 8.8.4.4/g" /etc/systemd/resolved.conf
  systemctl restart systemd-resolved.service
  
SHELL
```
Google社にはいつもお世話になってて、さらにお世話になるのも心苦しいですが、
DNSの参照先にさせて頂きました。（8.8.8.8, 8.8.8.4）
（jpドメインのDNSサーバも試してみましたが、安定しませんでした。）
ちなみにDNSの参照先を確認する場合`systemd-resolve --status`です。


## その５　インストールコマンドは公式を確認する  
英語を読むのは苦手なので、日本語ページを参考にしていましたが
OSの問題なのか鮮度の問題なのかわかりませんが、
Ansibleのインストール方法にばらつきがあり、なかなかしっくりインストールできませんでした。
で、諦めて[Ansible公式サイト](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)を真似ればすんなりできたので、
他のソフトでも面倒をかけてでも公式サイトの
インストール方法をまず最初に探すようになりました。
その方がトータル的に見て手間が少ないように思います。

## その６　sshの鍵認証はed25519
他サイトを参考にしていく中でよくrsaの鍵をみかけるのがほとんどですが、
暗号強度が高いed25519 で鍵を生成するようにしました。

```
control.vm.provision "shell", name: "Setup ssh", privileged: false, inline: <<-SHELL
  # ssh
  mkdir -p ~/.ssh
  ssh-keygen -N "" -t ed25519 -f ~/.ssh/id_ed25519
  rm -f ~/.ssh/known_hosts
SHELL
```

## その７　sshの鍵生成はユーザ自身でやること  
ここがユーザで実行する必要があります。
その３とも関連していますが、`apt install`と`ssh-keygen`をまとめて
一つのプロビジョニングで済ませようとしてrootユーザで実行していたら、
rootユーザのssh鍵を生成してしまってました。ssh鍵の生成は
接続ユーザ（vagrantユーザ）の鍵を作るためにも
`privileged: false`必須です。



以上、とりまとめなく書きましたが、見てくださった皆様の何かの参考になれば幸いです。
【2019年6月版】Erlang OPT 17 が Mac に入ってたので駆逐した

## Mac で `brew install erlang` したらエラー

手元の対象環境は以下です。

- OS : macOS High Sierra 10.13.6

かくかくしかじかありまして、`brew install erlang` してみたらエラーが出てしまいました。

```
```console
$ brew update
$ brew install erlang
...
<</usr/bin/erl にシンボリックリンクが貼れないエラー>>
...
$  erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell
17
$ brew uninstall erlang
...
<<そんなもん知らんってエラー>>
...
```

あら？と思って一応 `erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell` でバージョン確認してみたところ、`17` という衝撃のアンサーが帰ってきました。

**OPT 17** ！！

~~OPT 17 入れたの誰だよ!!(自分しかいないけど。)~~

ダメ元で `brew uninstall erlang` してみましたが、**そんなの知らないけど？**っていうご回答。わかってましたよ。。。

## インストーラーから入れたみたい？

たぶん、どっかのインストーラーで入れたんでしょう・・・以下のサイトのような・・・

https://www.erlang-solutions.com/resources/download.html

今回も一旦、上記サイトからインストーラパッケージが含まれた `.dmg` をダウンロードしてきました。

この中に含まれる `uninstall.tool` を実行すればOKのようです。

ですが念のために、**本当にこのインストーラーでインストールしたのか？**が気になるので、`uninstall.tool` をちょっとのぞいて見たところ、以下のようなコードを発見しました。

```shell
for  p in "com.erlang-solutions.Erlang" "com.erlang-solutions.MacUpdaterSwift"; do

    FILES=`/usr/sbin/pkgutil --files ${p} 2>/dev/null`
...
``` 

おー、`/usr/sbin/pkgutil --files {p}` でここのインストーラーからインストールされたファイルのリストが取れるのね！

というわけで以下のコマンドを実行し、本当にこのインストーラーからインストールされたファイルが存在するのか確認して見ました。

```
$ /usr/sbin/pkgutil --files "com.erlang-solutions.Erlang"
...
<<大量のファイルリスト>>
...
```

あ〜出るわ出るわ大量のファイルが。。。はい、確定です！

## アンインストール実行

というわけで `uninstall.tool` を実行します。

```console
$ sudo /Volumes/Erlang/uninstall.tool
Password:
Do you wish to uninstall EslErlang (Yes/No)?
yes

Removing files
Cleaning up
Forgot package 'com.erlang-solutions.Erlang' on '/'.
Cleaning up
Uninstallation completed
$  erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell
-bash: /usr/local/bin/erl: No such file or directory
```
はい、アンインストール完了です。
念のため、`erl` がちゃんと消えているかどうか先ほどのバージョン確認コマンドを叩いて見ましたが、しっかりと `/usr/local/bin/erl: No such file or directory` でエラーが出てので `PATH` で見えている範囲に `erl` はなくなっているのが確認できました。

気を取り直して、 `brew install erlang` いってみたいと思います！

## まとめ

手順をまとめると以下のようになります。

1. https://www.erlang-solutions.com/resources/download.html からインストーラーを含む `.dmg` をダウンロード
2. ダウンロード完了後、ダブルクリックか`開く`などで `/Volumes/Erlang` にマウントされるはず。(`Erlang` はバージョンによって変わるかもしれない？)
3. 念のため `/usr/sbin/pkgutil --files "com.erlang-solutions.Erlang"` コマンドでインストールファイルの有無を確認
4. `$ sudo /Volumes/Erlang/uninstall.tool` でアンインストーラーを実行

以上です。
Railsでchartkickを使ってグラフ表示

仕事でchartkickを使うことになったので導入手順メモ。

<h2>Gemfileに以下のgemを追加してbundle install</h2>

 
```
gem "chartkick"
```


<h2>ライブラリの読込</h2>
ライブラリのhelperを呼び出す前にライブラリを読み込まなきゃならんので必要箇所に以下を追記
例: layouts/application.html.erb


```
<%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %>
```

<h2>config/initializers/assets.rbに以下を追記</h2>
(Rails.application.config.assets.paths << Rails.root.join('node_modules')
の前に追記しないと動かないっぽい

```
Rails.application.config.assets.precompile += %w( chartkick.js )
```

<h2>app/assets/javascripts/application.jsに以下を追記</h2>
Rails5はこれでいけるが6だと違うらしい

```
//= require chartkick
//= require Chart.bundle
```

<h2>グラフ生成に必要なデータをcontrollerからviewへhash形式で渡す</h2>
keyが縦軸、valueが横軸となる。

```
 @sample = {'2019-06-01' => 60, '2019-06-02' => 65, '2019-06-03' => 64}
```

<h2>viewで受け取った値を引数としてヘルパーを使用する</h2>

```
<%= line_chart @sample %>
```

で、グラフ表示されるはず。

公式リファレンス：https://chartkick.com/
VSCode Remote-Containersを使ってサクッとNode.jsの環境を構築

## 概要
insiders版でベータ版としてリリースされていた「Remote Development with VS Code」が正式版としてリリースされました。
今回はこの中の一つ、「Remote-Containers」を使用してNode.jsの開発環境を構築していきたいと思います。

「Remote Development with VS Code」についてはこちらから
> [Remote Development with VS Code](https://code.visualstudio.com/blogs/2019/05/02/remote-development)

## 準備するもの
- Docker(Mac/Windows/Linux)
- VScode

各インストール手順については、OSによって異なるので、割愛します。

## VSCodeに拡張機能をインストール
1. サイドバーから拡張機能を選択します。
2. 検索フォームに「remote」と入力します。これで大体トップの方に出てくると思います。
3. 検索結果から「Remote Development」を選択しインストールします。
![スクリーンショット 2019-06-16 時刻 15.31.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205586/cb2c0f4e-cdd6-1a4f-c135-054059d66d3c.png)
インストールが完了すると、再読み込みを指示されるので再読み込みを行ってください。

## Node.js環境の設定ファイルを作成
※Dockerについては起動した状態にしておいてください。
VSCodeの再読み込みが完了したら、任意のフォルダを開いておきます。
次にコマンドパレットを開き「remote-containers」と入力します。
コマンド一覧から「Create Container Configuration File...」を選択します。
<img width="953" alt="スクリーンショット 2019-06-16 15.44.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205586/47b0fa77-2c9a-4eaf-735c-b9a3682b798a.png">
選択すると、どの環境を作成するか問われるので、Node.js(今回はlatest LTSを使用)を選択します。

現在開いているフォルダに「devcontainer.json」と「Dockerfile」が作成されたことを確認したら、再びコマンドパレットを開き、「remote-containers」と入力します。
上の画像にも表示されている「Reopen Folder in Container」を選択します。するとVSCodeが再読み込みを行います。

## Node.js開発環境立ち上げ
再読み込みが終われば、自動的に上記の手順で作成したファイルを基にコンテナを作成して、起動してくれます。（コンテナの作成状況は右下に「detail」と表示されているところをクリックすると見ることができます。）

無事コンテナが立ち上がると、以下の画面のようになります。
![スクリーンショット 2019-06-16 時刻 16.02.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205586/9a5bbf29-2320-c07c-b462-1f1921957082.png)
これでNode.jsの開発環境は構築完了です。コンテナ側で「npm init」などを入力し、遊びましょう。

## 終わりに
前までは、ローカルにNodeやnpmなどをインストールする必要があり、ローカルにはできるだけ実行環境は入れておきたくない自分からするとこの技術は非常に便利なものだと思いました。
コンテナに開発環境を構築するので、チーム開発などの時でもDockerfileを配布するだけで同じ環境が作れちゃうのも魅力の一つかと思います。
チーム開発の際は積極的に取り入れたい技術の一つですね。
C#という言語について簡単に纏めてみる

# C\#という言語について簡単に纏めてみる

## 背景
転職先でC\#を使うことになったのですが、私はC\#の経験がほぼ無いので簡単に纏めてみます。
（学生の頃、研究で少し利用しましたが、当時はJavaメインだったので忘れました）

## C\#の歴史や特徴など
C\#は、米マイクロソフトが開発したプログラミング言語。主にアプリ開発言語として利用される。
かつてはWindows用フレームワークである".NET Framework"専用言語というイメージだったらしいが、現在は様々なプラットホームで利用される。
具体的には、"Mano"というフレームワークを利用することでMacOS,Linux,PlayStation VitaでもC\#のプログラムを動作させることが出来る。
ゲームエンジンのUnityでも採用される事で有名。
同様のフレームワークとして、".NET Core"もある。

C\#のソースコードは、コンパイラにより共通言語基盤で動作する共通中間言語に変換される。そして仮想マシンの共通言語ランタイムで実行される。
C\#は2002年にバージョン1.0がリリースされ、2019/6月現在は7.3が最新。

## 開発環境

マイクロソフトの[Visual Studio](https://visualstudio.microsoft.com/ja/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2019&rr=https%3A%2F%2Fdocs.microsoft.com%2Fja-jp%2Fvisualstudio%2Finstall%2Finstall-visual-studio%3Fview%3Dvs-2019) 
を利用するのが簡単。

macの場合、MONOをインストールすることでコンパイルと実行が可能。

```Terminal 
# brew install mono 
# mcs Program.cs
# mono Program.exe 
```
JavaScriptにおけるthisの値を操作する3つのメソッドについて

# はじめに
JavaScriptにはthisの値を変更できる3つのメソッドがある。call()、apply()、bind()である。それぞれ3つのメソッドについてメモ程度にまとめておく。

# JavaScriptにおけるthis概要
JavaScriptにおけるthisの値は関数が実際に呼び出される際に設定される。つまり呼び出された場所によって、その値が変化する。
詳細はここで説明するよりも以下の記事が分かりやすい。
(https://qiita.com/mtoyopet/items/2fceef61b250e3917cb3)
(https://qiita.com/takkyun/items/c6e2f2cf25327299cf03)

# call()メソッド概要
callはthisの値と引数を指定して関数を実行する。2つパラメータを渡す。
1つ目のパラメータには関数が実行される際のthisの値を渡す。
２つ目のパラメータには関数に渡す引数を渡す。

```JavaScript
function callFrom(idNumber){
  console.log(idNumber + ":" + this.name);
}
var person1={
  name:"Tanaka"
};
var person2={
  name:"Sato"
};
var name="Kudo";

callFrom.call(this,"global");
//=> global:Kudoと出力
callFrom.call(person1,"person1");
//=> person1:Tanakaと出力
callFrom.call(person2,"person2");
//=> person2:Satoと出力
```
 １つ目のcallでは関数callFromが実行される際のthisの値である1つ目のパラメータにグローバルなthisオブジェクト、関数に渡す引数に"global"を渡している。
グローバルオブジェクトはグローバル変数をプロパティとして扱うためグローバル変数として宣言されているためthis.nameは"Kudo"となる。
2つ目、3つ目ではそれぞれ実行時のthisの値としてperson1,person2を指定しているため、それぞれのnameプロパティの値が出力される。
# apply()メソッド概要
call()メソッドとほぼ同様。違いは2つ目のパラメータの関数に渡す引数が配列であることだけである。



```JavaScript
function callFrom(idNumber){
  console.log(idNumber + ":" + this.name);
}
var person1={
  name:"Tanaka"
};
var person2={
  name:"Sato"
};

var name="Kudo";

callFrom.apply(this,["global"]);
// global:Kudoと出力
callFrom.apply(person1,["person1"]);
// person1:Tanakaと出力
callFrom.apply(person2,["person2"]);
// person2:Satoと出力
```
ご覧の通りcall()メソッドとの違いは「２つ目のパラメータが配列であるか、配列でないか」のみである。



# bind()メソッド概要
call()メソッドやapplyメソッドとは異なる機能を持っていて、bind()メソッドはthisの値を固定した新しい関数を生成する。新しく生成した関数の中身のロジックに関しては元となる関数と同じである。
1つ目のパラメータには新しい関数のthisとして固定される値を渡す。
2つ目のパラメータは任意指定で、指定する場合は新しい関数に渡す引数を渡す。

```JavaScript
function callFrom(idNumber){
  console.log(idNumber + ":" + this.name);
}

var person1={
  name:"Tanaka"
};
var person2={
  name:"Sato"
};

var name="Kudo";

// 新しい関数を生成する
var callFromPerson1 = callFrom.bind(person1);

callFromPerson1("person1");
// => person1:Tanaka と出力

// 新しい関数を生成する
var callFromPerson2 = callFrom.bind(person2, "person2");

callFromPerson2();
// => person2:Sato と出力
```
上記ではbind()メソッドによって2つの新しい関数を生成している。
新しく生成した1つ目の関数callFromPerson1ではthisの値をperson1に固定している。したがってthis.nameではperson1オブジェクトのnameを参照する。
2つ目の関数、callFromPerson2ではthisの値をperson2に固定している。また任意指定である2つ目の引数で関数に渡す引数"person2"を指定している。したがって関数呼び出し時にパラメータを指定することなく"person2"を出力することができている。


# おわりに
JavaScriptのthisに関する挙動は、初心者や他の言語からやってきた方々にとっては、少しとっつきにくいものではないかと思う。（自分もいまだに苦戦中）
上記3つのメソッドを使いこなしてthisを自由に操れるようになりたいところ。
超絶初心者。ブロックチェーンとはなんぞや？ってセミナーに行ってみた感想

[FLOC](https://floc.jp/)というブロックチェーンの学校を運営している会社で
無料セミナーが開催されていたので興味本位に行ってきたので簡単にまとめて見る。


#ブロックチェーンとは？
*ブロックチェーンとは変更、削除、改ざんが限りなく不可能でシステムダウンが起きないネットワーク共有型のデータベースのこと*

将来的にデータベースというのは中央集中化型から分散管理型に移行すると言われている。
これは各々のデータを共有している状態であるから、そこで管理することによって**管理者＝使用者**という形になるのではないかと予想されている。

企業の導入事例として

- BMW
これはBMWの車で走行距離やカーナビ情報、などをデータベース化して管理している。
これをブロックチェーンで活用することは「正規品である証明となる」部分が大きい。
ブロックチェーンの技術を使っているから、正規品でない情報については収集されない。かつ中古市場の価値を一定価値に保てる。

- Enection2.0
個人間での電気の販売を可能にするような取り組み。個人間での電気というインフラを売買するにあたり、証明書を発行して、正規の電気です。改ざん問いはしていませんという証明することが可能となる。

ちなみに
######イーサリアムもブロックチェーンの技術


#そもそもブロックチェーンって仕組みって？
ビックデータとAI、ブロックチェーンと別々で考える人もいるが、本来の違う。
考え方として下記の通り。

**ビックデータ** と **AI**　を支えている
**ブロックチェーン**

EX）ビットコイン＝OS、ブロックチェーン＝アプリケーション
このように相関関係として成り立っている。

#簡単なブロックチェーンの仕組み

まずブロックとは大理石のような物であると。
容量は1MB。
およそ10分で新しいブロックが生成される。
このブロックに対して、取引データ（*トランザクション*）を書き込んでいく。
この書き込んでいく作業のことを*マイニング*という。
マイニングすることの利点として、報酬を得ることが可能。金額は12.5BTC。

マイニングする人は*ノード*と呼ばれる、ブロックに書き込む候補の人がいる。
ノードの中からマイニング人を選出するわけだが、これがおよそ10分に1回選出される。

**つまり、10分間作業することでかなりの大金が得られるチャンスがある。**

このチャンスを得たい人はいるが、このマイニングするためにはかなりのスキルが必要とされる。
その前にそもそも、取引データを書き込みをするとはどのようなことなのか？

仮想通貨を取引した場合、その取引データが取引所に送信される。
この時のいくら？誰が？何を？購入or売却したのか個人のパーソナルな情報が開示されている。

セキュリティの問題は？と疑問にもつ。

**ここでブロックチェーンを支える重要な技術。**
1. 公開鍵と秘密鍵

公開鍵と秘密鍵が同一で扱われることがなく、セキュリティを担保することが可能。
送信者と受信者で考えると、送信者から受信者へ送るのは公開鍵。受信者から送信者にデータを返す時は公開鍵。
しかし、そのデータを復号するのは秘密鍵と公開鍵によって複合される仕組みとなっている。
簡単にいうと、セットになっていないとデータとして扱えないよということ。

2. ハッシュ化

ハッシュとは256形式に置換すること。
任意のハッシュ形式にデータを置換することで簡単に外部からデータを改ざんしたり、盗んだりすることが不可能となる。

この2つの技術があることでセキュリティの担保ができ、みんなが安心して取引ができるようになる。

#複合型テクノロジーで変わる未来

1. マイクロペイメント

1円以下の単位での取引をすることが可能になる。電子通貨として扱うため、通貨として世の中に存在しない額でも取引をすることが可能となる。
EX)
・新聞とマイクロペイメント
→新聞というパッケージ化された商品をマイクロレベルで分別することが可能となり、ユーザーが欲しい情報のみ取得することが可能となる。

・電化製品とマイクロペイメント
→冷蔵庫を無料提供して、使用回数に応じて支払うことで利用代金を取る方法。これによって高額の金額を今の段階持っていなくても商品を使うことができる。これによってビジネスモデルが変わることが予想される。

2. スマートコントラクト

自動的な契約や効率的に契約ごとを進めることが可能になる技術。
EX)
・自販機
→お金を入れる→商品を選ぶ→商品が出てくるという簡単な契約をしていると。これを様々な分野でも応用できるようになる。
お金ではなく、商品を選ぶ契約を交わす、これをスマトーコントラクトの技術を使って簡単に行うことが可能になる。

・メルペイ
→メルカリ内で使用される通貨を独自のポイントから算出して使えるようにする仕組み。信用をためて、その中で取引できるようにする仕組み。

#最後はFLOCのカリキュラムとかの紹介があった
エンジニアコースだと50万くらいで講座とweb講座が受けられる。
ブロックチェーンについて単純に学ぶコースだと2o万くらいだった。

エンジニアコースにも2コースあり
1.webアプリケーションを制作する
2.ブロックチェーンをDBとしてアプリケーションの開発

簡単にまとめるとこんな感じのコースだった気がする。
詳細は企業のHPに記載されている。

#総括

ブロックチェーンの本当の触りの部分に触れることができた。
この技術を転用することで、様々なビジネスモデルが変わってくると思う。
データを一つの場所で保管する必要はなくなり、全員で共有することで安全性と自動バックアップが取られている状態になるのではないかと思う。

そう考えたら、Githubの考え方もある種似ているのかなと感じた。
集約されているからブロックチェーンとは違うが
公開されている情報に関しては誰でも見ることが可能という点は。

このデータベースが個人にあれば、ブロックチェーンの技術が必要になってくると。
そうなった時にブロックチェーンエンジニアの市場価値はかなり高まることになると。

これを機にブロックチェーンがどのように成り立ち、触れてみようと思ったが
自分の場合はまずプログラミング言語を使って開発することが大切かなと思ったので
優先順位が１位ではなかった。

けど、国単位で動いているプロジェクトもあるし
ブロックチェーンエンジニアの求人倍率は516%くらい上昇しているらしい。（正しいか不明）

年俸もエンジニアと比較して、1.5倍〜２倍と言っていたが
どこまで本当かは不明。

極めたら希少価値の高いエンジニアになれる見込みは十分にあるなと感じた。
以上
Windows 10で英字キーボードを使用しているときに，入力を【Ctrl+Space】で切り替える方法

はじめまして．こんにちは．
初めてQiitaに投稿します．
ukyと申します．

初めての記事なので，技術に関係ない緩く，かつ自分にしか役に立たない内容を投稿します．

タイトルにもある通り，初投稿の内容はWindows 10で英字キーボードを使用しているときに，【Ctrl+Space】で半角英数 ⇔ ひらがなと入力方式を切り替える方法です．
個人的に最近Windows 10のPCを購入し，キーボードとしてREALFORCEの英字キーボードを使用しているのですが，自分好みの設定にするのに苦労したので備忘録です．
これを設定すると，「E/J」というキーがない英字キーボードであっても入力を切り替えられます．私はこの設定を自分の私用PCすべてに適用しています．

やり方は以下の通りです：
※「」は，実際の操作の中で表示される言葉をそのまま使用しています．

#1. IMEのプロパティを選択する
右下の「あ」もしくは「A」のアイコンのうえで右クリックしてメニューを表示させて，「プロパティ」をクリックする．
<img width="226" alt="スクリーンショット (7).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/cfda7c2b-a674-f4c3-6a61-6c41ed900a9a.png">

#2. 「Microsoft IMEの設定」から「詳細設定」を選択する
以下の画像のように「Microsoft IMEの設定」から「詳細設定」をクリックする．
<img width="324" alt="スクリーンショット (8).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/c58007c0-cb75-d117-b888-788a4808ab62.png">

#3. 「編集操作」の「キー設定」の「変更」を選択する
以下の画像のように「変更」をクリックする．
<img width="363" alt="スクリーンショット (10).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/614cce21-5cd7-846b-ef61-941bab8aac68.png">

#4. 「Ctrl+SPACE」の定義を「IME-オン/オフ」に設定する
以下の画像のように「Ctrl+SPACE」の入力/変...の部分をダブルクリックする．
<b>※画像は既に設定後の状態</b>
<img width="376" alt="スクリーンショット (11).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/be5785c3-2607-75bd-a10f-d07efc52348c.png">
すると，以下のウィンドウが表示されるので，「機能選択」の一覧から「IME-オン/オフ」を
選択して，「OK」をクリックする．
<img width="343" alt="スクリーンショット (12).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/34bfd6ff-55a1-c4fa-ca18-ed51994fa7c2.png">

これでIMEがタイトル通り【Ctrl+Space】で切り替わるようになった．
次に，日本語入力ができる状態で英字キーボードの配列を使えるように設定する．

#5. Windowsの設定から「時刻と言語」を選択する
スタートボタンをクリックすると，以下のウィンドウが表示されるので，
そのアイコンの中から「時刻と言語」をクリックする．
<img width="900" alt="スクリーンショット (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/e4855f6b-6271-a00b-8654-62ee4e2c30aa.png">

#6. 左側のメニューから「言語」を選択する
以下の画像のように「言語」をクリックする．
<img width="898" alt="スクリーンショット (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/8d112e6f-d2ba-f5b3-fc6e-b991130c451c.png">

#7. 「日本語」の「オプション」を選択する
以下の画像のように「日本語」から，「オプション」をクリックする．
<img width="898" alt="スクリーンショット (5).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/acbb4576-96da-9edb-3d4e-5d333cbf1903.png">

#8. 「ハードウェア キーボード レイアウトの変更」からキーボード設定を「英字キーボード (101/102 キー)」に変更する
キーボードが最初は日本語キーボードになっているので，プルダウンから「英字キーボード (101/102 キー)」に変更して「OK」をクリックする．
<img width="896" alt="スクリーンショット (6).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/b3e2dc36-b0a1-69cd-6dc6-cc2ce27683d0.png">

上記の設定をすることで，日本語を入力できる状態で英字キーボードの配列を利用できます．
次に，【Ctrl+Space】で入力を切り替えるように設定します．


これで，英字キーボードを使用しているときに【Ctrl+Space】を同時に押すことで，半角英数 ⇔ ひらがなと切り替えることができます！

もし英字キーボードこれから使いたいなぁと思った人にとって，参考になれば幸いです．
hexo-all-minifierプラグインでのエラーを解決方法

# hexo-all-minifierプラグインでのエラーを解決方法

## 画像自動圧縮plugin minifier 

画像を自動的に圧縮してdeployしてくれるpluginプログラムminifierを見つけたので、下記のコマンドで早速インストールしてみました。

```
npm install hexo-all-minifier --save
```

## しかし、エラーが発生

しかし、、、インストール時に下記のエラーが発生されました。

```
> mozjpeg@5.0.0 postinstall /Users/xxx/Sites/white-label/node_modules/gulp-imagemin/node_modules/imagemin-mozjpeg/node_modules/mozjpeg
> node lib/install.js
  ⚠ The `/Users/xxx/Sites/white-label/node_modules/gulp-imagemin/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor/cjpeg` binary doesn't seem to work correctly
  ⚠ mozjpeg pre-build test failed
  ℹ compiling from source
  ✖ Error: autoreconf -fiv && ./configure --disable-shared --prefix="/Users/xxx/Sites/white-label/node_modules/gulp-imagemin/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor" --bindir="/Users/xxx/Sites/white-label/node_modules/gulp-imagemin/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor" --libdir="/Users/xxx/Sites/white-label/node_modules/gulp-imagemin/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor" && make --jobs=8 && make install --jobs=8
  Command failed: /bin/sh -c autoreconf -fiv
 /bin/sh: autoreconf: command not found
```

Hexo generatorを実行すると下記のエラーが出力されました。

```
Error: write EPIPE 
　at exports._errnoException (util.js:1020:11)
```

## 原因
nasmのライブラリがインストールされてないのが原因でした。

## 解決方法

```
sudo apt-get update
sudo apt-get install nasm
```

hexo-all-minifierをアンインストールする

```
npm uninstall hexo-all-minifier --save
```

hexo-all-minifiertをインストールする

```
npm install hexo-all-minifier --save
```

エラーも出力されず無事インストールできました。

次回記事もよろしくお願いします。
ARKit3 新機能まとめ


[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/SgAnnwl2VB8/0.jpg)](http://www.youtube.com/watch?v=SgAnnwl2VB8)
[http://www.youtube.com/watch?v=SgAnnwl2VB8](http://www.youtube.com/watch?v=SgAnnwl2VB8)

## 目次
- [**People Occlusion**](#1people-occlusion)
- [**Motion Capture**](#2motion-capture)
- [Simultaneous Front and Back Camera](#3simultaneous-front-and-back-camera)
- [Multiple Face Tracking](#4multiple-face-tracking)
- [**Collaborative Sessions**](#5collaborative-sessions)
- Additional Improvements(省略)

## 1.People Occlusion

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/vkS-VqAss4s/0.jpg)](http://www.youtube.com/watch?v=vkS-VqAss4s)
[http://www.youtube.com/watch?v=vkS-VqAss4s](http://www.youtube.com/watch?v=vkS-VqAss4s)

### 説明

AR空間のなかにいる人間を認識し、3Dオブジェクトを隠してくれる

### 何が変わる？

人間と3Dオブジェクトが重なる不自然さが無くなり、より臨場感のあるAR体験が可能になる


## 2.Motion Capture

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/VKSFVLO_qaI/0.jpg)](http://www.youtube.com/watch?v=VKSFVLO_qaI)
[http://www.youtube.com/watch?v=VKSFVLO_qaI](http://www.youtube.com/watch?v=VKSFVLO_qaI)

### 説明

カメラで人間の動きを映し出すと、リアルタイムでその動きをキャプチャしてくれる(リアルタイムトラッキング)

### 何が変わる？

人の動きをアプリケーションに統合することができるようになる


## 3.Simultaneous Front and Back Camera

### 説明

前面カメラと背面カメラでフェイストラッキングとワールドトラッキングを同時に使用できる

### 何が変わる？

例えば、ユーザーは自分の顔だけを使用して、バックカメラビューでARコンテンツと対話できるようになる


## 4.Multiple Face Tracking

### 説明

Memojiなどの正面カメラで一度にできるフェイストラッキングの数が1から3つまで増えた

### 何が変わる？

例えば、１つのカメラで３人の演者がいれば、３人のキャラ
クターの顔を動かせるようになる


## 5.Collaborative Sessions

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/zir7zDI9fVM/0.jpg)](http://www.youtube.com/watch?v=zir7zDI9fVM)
[<https://www.youtube.com/watch?v=zir7zDI9fVM>](https://www.youtube.com/watch?v=zir7zDI9fVM)

### 説明

複数の人がライブコラボレーションセッションを行うことができる

### 何が変わる？

マルチゲームなど複数のユーザー間で共有したAR体験ができるようになる 


## 参考サイト

[<https://developer.apple.com/augmented-reality/arkit/>](https://developer.apple.com/augmented-reality/arkit/)
Sublime Text 童貞卒業のために(Mac) Part.1 導入

# はじめに
本記事は、Sublime童貞（初心者）をターゲットにしています。
非Sublime童貞は、適宜飛ばしてお読みください。
尚、 MacOS で進めていきます。 Win版は、[こちら](https://qiita.com/puru_pue/items/46f615843b9df4fc6eb9)。
所要時間は、10分程度です。

## こんな方に
- テキストエディタ童貞
- 初心者 or 文系の方

## 環境
- MacOS Mojave
- Sublime Text 3 (3.2.1) 

# Sublime Text とは
- 「恋に落ちるテキストエディター」とも言われるテキストエディタ
- かなり**軽い**方です。ここは意外と大事な要素。
- **無料**。たまに課金ポップアップが出ますが、気にならない程度です。知らんけど。
- プラグインが多く、自分色に染められる。
- 無印良品かってくらいシンプルでかっこいい（カスタマイズ可）

## Sublime Text があると何がうれしいのか？
- 効率よく文章を仕上げられる（メモとか課題レポートとか、プログラムとか）
- 文字の検索、置換、補完、マクロ
- 要は、めっちゃ優秀なメモ帳です。

# インストール
まずは、公式HPからダウンロードしましょう。(http://www.sublimetext.com)
![01_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/9f3817a6-7010-3757-f742-6a5b55c24022.png)
Sublime Text の dmg （圧縮）ファイルがダウンロードされます。
dmg ファイルを解凍すると、Applications フォルダと Sublime のアプリケーションが表示されます。
（ここでは、アプリケーションの保存ディレクトリを Applications としていますが、人によって名前が違います。その場合も慌てずに手順通り進めてください。）
下図のように、ドラッグ&ドロップで Applications フォルダに sublime Text をぶち込みましょう。
![02_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/f2ab1290-42e1-d7b3-9747-a71537b84181.png)
Finderから Applications を開き、sublime Text がインストールされていれば成功です。
さっそく Sublime Text を開いてみましょう。
アイコンをダブルクリックで開いても、command+spaceで Spotlight検索 してもいいです。

これが Sublime Text です。
シンプルなのがいいですよね。
![03_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/780c9b64-847d-a718-2367-8aa15639db5b.png)

本日はここまで。
次は、実際に使いながらやっていきましょう。

お疲れ様です。

# 今後の展望
- Sublime Text を自分色に染めてもらう（プラグインの紹介）
- Markdown エディタとしての環境構築（メモに重宝）
- プログラマ向けに
- 自作プラグインの作り方 

# 参考文献
- IT用語辞典e-Words(http://e-words.jp/w/テキストエディタ.html)
グラフの探索と迷路

# グラフの探索
- グラフの各頂点や辺を二回以上調べることなく，しかも必ず一回は調べる手順
- 単純に考えれば，全部の頂点を番号順に調べればいい
- けど，それはグラフの構造をガン無視しているので，グラフの構造に関係のない計算にしか使えない
- グラフの構造自体を考慮した手順の方が応用が効く

# 深さ優先探索
- 分かれ道に遭遇したときに，**「いけるところまで行ってから引き返そう」**という立場を取るのが深さ優先探索
- 分かれ道に来たら，行かなかった道をスタックに記録しておくことで深さ優先探索は実現できる

# 幅優先探索
- 分かれ道に遭遇したときに，**「とりあえず全部の分かれ道にちょっとだけ首突っ込んでみる」**という立場を取るのが幅優先探索
- 分かれ道に来たら，行き先候補をキューに突っ込んでおくことで幅優先探索が実現できる

# 迷路を解く
- 迷路を与えられて，ゴールすることができるかとかゴールするまでの手数はいくらかとかを計算しろという問題はグラフ探索の要領で解くことができる
- 迷路では全探索することよりもゴールに到達することが求められるので，幅優先探索の方が有利
- 幅優先探索では，（もしかしたらゴールするかもしれない）いろんな経路に手を付けるので，より少ない手間でゴールに到達する可能性が高まる
- 深さ優先探索だと，絶対にゴールしない経路に入ってしまったら，行き止まりに遭遇するまで（絶対にゴールすることないのに）突き進んでしまうので不利

## 迷路
```
7 8       // 行数 列数
2 2       // スタートの座標
4 5       // ゴールの座標
########  // `#`は壁，`.`は道 
#......#
#.######
#..#...#
#..##..#
##.....#
########
```

## 深さ優先探索
- スタックに分かれ道を記録しておく

```go
package main

import (
	"fmt"
)

type pos struct {
	x int
	y int
}

func dfs(maze []string, start, goal pos) int {
	row := len(maze)
	col := len(maze[0])

	dist := make([][]int, row)
	for i := 0; i < row; i++ {
		dist[i] = make([]int, col)
		for j := 0; j < col; j++ {
			dist[i][j] = -1
		}
	}

	q := make([]pos, 0)
	dist[start.y][start.x] = 0
	q = append(q, start)

	for len(q) > 0 {
		p := q[len(q)-1]
		q = q[:len(q)-1]

		for _, d := range []pos{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {
			y := p.y + d.y
			x := p.x + d.x
			if 0 <= y && y < row && 0 <= x && x < col && dist[y][x] == -1 && string(maze[y][x]) == "." {
				dist[y][x] = dist[p.y][p.x] + 1
				q = append(q, pos{x, y})
			}
		}
	}

	return dist[goal.y][goal.x]
}

func main() {
	var R, C int
	fmt.Scan(&R, &C)

	var start, goal pos
	fmt.Scan(&start.y, &start.x)
	fmt.Scan(&goal.y, &goal.x)
	start.x--
	start.y--
	goal.x--
	goal.y--

	maze := make([]string, R)

	for i := 0; i < R; i++ {
		fmt.Scan(&maze[i])
	}

	fmt.Println(wfs(maze, start, goal))
}
```

## 幅優先探索
- キューに分かれ道を記録しておく

```go
package main

import (
	"fmt"
)

type pos struct {
	x int
	y int
}

func wfs(maze []string, start, goal pos) int {
	row := len(maze)
	col := len(maze[0])

	dist := make([][]int, row)
	for i := 0; i < row; i++ {
		dist[i] = make([]int, col)
		for j := 0; j < col; j++ {
			dist[i][j] = -1
		}
	}

	q := make([]pos, 0)
	dist[start.y][start.x] = 0
	q = append(q, start)

	for len(q) > 0 {
		p := q[0]
		q = q[1:]

		for _, d := range []pos{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {
			y := p.y + d.y
			x := p.x + d.x
			if 0 <= y && y < row && 0 <= x && x < col && dist[y][x] == -1 && string(maze[y][x]) == "." {
				dist[y][x] = dist[p.y][p.x] + 1
				q = append(q, pos{x, y})
			}
		}
	}

	return dist[goal.y][goal.x]
}

func main() {
	var R, C int
	fmt.Scan(&R, &C)

	var start, goal pos
	fmt.Scan(&start.y, &start.x)
	fmt.Scan(&goal.y, &goal.x)
	start.x--
	start.y--
	goal.x--
	goal.y--

	maze := make([]string, R)

	for i := 0; i < R; i++ {
		fmt.Scan(&maze[i])
	}

	fmt.Println(wfs(maze, start, goal))
}
```
データファイルが存在するか確認する方法  ShellScript

ファイルの存在をshellで確認する方法です！
![19-06-16-09-23-03-041_deco.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433296/1df0ff20-959a-4703-b369-5fd1170b1baa.gif)
##作業手順
###①ファイルが入っているディレクトリの存在チェック
　・ディレクトリが存在する→作業を続行、存在確認表示
　・ディレクトリが存在しない→作業を中断、存在未確認表示

###②ファイルの存在チェック
　・ファイルが存在する→存在確認表示
　・ファイルが存在しない→存在未確認表示

###確認するファイル
・/AAA/BBB/CCC/D1/ディレクトリ中の**”akari.prm”**ファイル
・/AAA/BBB/CCC/D2/ディレクトリ中の**”kaori.prm”**ファイル

```shell
#初期設定
#格納ディレクトリ
DIR_1='/AAA/BBB/CCC/D1/'
DIR_2='/AAA/BBB/CCC/D2/'

#検索したいファイルの名前定義
CHECK_f1='akari.prm'
CHECK_f2='kaori.prm'
```
変数定義をしておく理由は、後から変更がしやすくなるからです。

##①ディレクトリの存在チェック
まずはファイルが入っているD1、D2ディレクトリの存在チェックから始めます。
if文のオプションで **-d** を使うと、対象がディレクトリの場合、真を返してくれます。
また、elseを使うことによって、処理を終了してくれます。

```shell
#ディレクトリ存在チェック
  #/AAA/BBB/CCC/D1/ディレクトリ
　if [ -d ${DIR_1} ]; then
    echo "$DIR_1 found."
  else
    echo "$DIR_1 NOT found."
    exit
  fi
 
  #/AAA/BBB/CCC/D2/ディレクトリ
  if [ -d ${DIR_2} ]; then
    echo "$DIR_2 found."
  else
    echo "$DIR_2 NOT found."
    exit
  fi
```
##②ファイルの存在チェック
次に、ファイル名で検索して、存在するか？のチェックをします。
if文のオプションで **-f** を使うと、対象がファイルの場合、真を返してくれます。

```shell
#ファイルの存在チェック
  #akari.prmファイル
  if [ -f ${DIR_1}${CHECK_f1} ]; then
    echo "${CHECK_f1} found."
  else
    echo "${CHECK_f1} Not found."
  fi

  #kaori.prmファイル
  if [ -f ${DIR_2}${CHECK_f2} ]; then
    echo "${CHECK_f2} found."
  else
    echo "${CHECK_f2} Not found."
  fi
```
[a-z]と^[a-z]$の違い

##[a-z]と^[a-z]$の違い

[a-z]と^[a-z]$の違いについて書いてみる。

^, $の意味は以下の通り。

| 記号       |       意味 |    
|:-----------------|------------------:|:------------------:|
| ^             |              行頭 |        This        |
| $           |            行末 |       column       |

[a-z]に^, $を加えると、どう変化するかコードで試してみよう。

```sample.rb 
p "ruby" =~ /[a-z]/
# => 0

p "ruby" =~ /^[a-z]$/
# => nil 
```

^[a-z]$を使うと、nilが出力されてしまう。しかし、

```sample.rb 
p "a" =~ /^[a-z]$/
# => 0
```

^, $をつけることで一文字だけの検証を行うことができる。
MAMPでPHPのtimezoneを設定した時のまとめ


PHPの勉強をするため、MAMPの設定をしていた時に陥ったミスをメモに残します。

# date関数

date関数を使って、下記を出力します。
```php:
print(date( 'G時 i分 s秒'））;
```

通常は下記のように出力されます。

[●●時 ●●分 ●●秒]

実行した際に出力された時間が現時刻と違ったため、
timezoneの設定を行いました。

# php.iniファイル
php.iniファイルに下記の箇所があります。
<img width="441" alt="スクリーンショット 2019-06-16 15.00.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371958/0bc2e28d-84c9-55b3-464f-688ddb6f34cc.png">

date.timezone = "Europe/Berlin" →　"Asia/Tokyo"
に変更。

apacheを再起動して一件落着！と思ったら、反映されない…

# パスが違った…
よくよく見るといじっていたファイルが違うようでした。
誤：/Applications/MAMP/conf/php(バージョン番号)
正：/Applications/MAMP/bin/php/php(バージョン番号)/conf/

参照：[MAMPでデフォルトのタイムゾーンが変更出来ないとき](https://qiita.com/y-natsui/items/c1b7fa56a0e0af52b24a)

# それでも反映されない
設定するファイルは間違っていないようでしたが、何故かtimezoneがno valueとなっていました。
<img width="325" alt="スクリーンショット 2019-06-16 15.11.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371958/797d6ade-ff44-b586-3479-65f578b95c7a.png">

apacheの再起動ができておらず、反映できていないといった凡ミスもなし。
この時点ではもうわけがわからなくなっていました。

# 「そういうオチ！？」

１時間くらいググって調べていましたが、ある記事であっけなく解決しました。

参照：[php.ini のタイムゾーン設定を忘れるな！](https://serverlog.jp/php-date-timezone/)

>php.ini の ;date.timezone がコメントアウトされているので、date.timezone = Asia/Tokyo のように設定するだけです。php.iniは、複数存在している場合があるので、locate php.ini などで検索して、すべてにタイムゾーンを設定してください。

つまり、
`[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone = "Asia/Tokyo"`
↓
`[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Asia/Tokyo"`

「 **;** 」これだけ！


初学者らしいいいミスだったなぁと思い、投稿します。
ご査収のほどよろしくお願いいたします。
Dropbox にPDF ファイルがアップロードされたら Twilio で FAX 送信

Dropbox の特定のフォルダーに PDF ファイルがアップロードされたら、Twilio の API で FAX 送信します。

##Twilio の API
API で FAX 送信できます。

TITLE: プログラマブルFax REST API
URL: https://jp.twilio.com/docs/fax/api

##Microsoft Flow
Microsoft Flow で一連の動作を実行します。

Dropbox の特定フォルダーへのファイル アップロードをトリガーにします。
https://docs.microsoft.com/ja-jp/connectors/dropbox/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/92f0d74d-8dec-e7d6-90e3-eb39a5aba53e.png)

Twilio の API で FAX 送信できるファイルは、URL でアクセス可能な場所におかれた PDF のみです。そのため Dropbox 以外の場所にいったんコピーします。ここでは別の Web サーバーに FTP 転送しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/4b90b2cf-a76f-2b1f-9b01-41a402b0c4ed.png)


##Azure Automation の Runbook で Twilio の API 操作

PowerShell の Invoke-RestMethod コマンドレットで Twilio の API を実行します。
Dropbox にアップロードされたファイル名をパラメータで渡す想定です。

```
Param
(
  [Parameter (Mandatory= $true)]
  [string] $filename
)

$USER = <Twilio の アカウントSID>
$PASS = <Twilio の AUTHTOKEN>
$secpasswd = ConvertTo-SecureString $PASS -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($USER, $secpasswd)

Invoke-RestMethod -Uri "https://fax.twilio.com/v1/Faxes/" -Credential $cred -Method POST -Body @{To=<宛先番号>; From=<Twilio で取得した番号>; MediaUrl="http://example.com/$filename"}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/82c4df1f-b1b0-2ed9-a6f2-2a17215e84e3.png)

##動作確認
Dropbox のフォルダーに PDF をアップロードすることで、宛先の番号宛にファックス送信されることを確認します。
ホームページにinstagramの写真を埋め込む。


表示部分

```html:index.html
<div class="instagram"></div>
```

js部分

```js:instagram.js
$(function(){
    var $container = $(".instagram");
    var html = "";
    $.ajax({
        url: "instagram.php",//PHPファイルURL
        type:"POST",
        dataType: "json"
    }).done(function(data){
		//通信成功時の処理
		var counter = 0;
        $.each(data.data,function(i,item){
			if(counter === 6) {
			    return false;
  			}
			var imgurl = item.images.low_resolution.url; //低解像度の画像のURLを取得
            var link = item.link; //リンクを取得
			html += "<div><a href='" + link + "' target='_blank'><img src='" + imgurl + "'></a></div>";
			counter++;
		});
    }).fail(function(){
        //通信失敗時の処理
        html = "<li>画像が取得できませんでした。</li>";
    }).always(function(){
        //通信完了時の処理
        $container.html(html);
    });
});
```

PHP部分

```php:instagram.php
<?php
//POSTリクエストの場合のみ受付
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    //アクセストークン
    $access_token = "アクセストークンを入れる";
    //JSONデータを取得して出力
    echo @file_get_contents("https://api.instagram.com/v1/users/self/media/recent/?access_token={$access_token}");
    //終了
    exit;
}
?>
```

これで無事に出来た。
法線マッピングのメモ

## LEAN Mapping

https://www.csee.umbc.edu/~olano/papers/lean/

## Frequency Domain Normal Map Filtering

http://www.cs.columbia.edu/cg/normalmap/index.html

## Normal map filtering using vMF (part 3)

http://graphicrants.blogspot.com/2018/05/normal-map-filtering-using-vmf-part-3.html

## Filtering Distributions of Normals for Shading Antialiasing

https://research.nvidia.com/sites/default/files/publications/NDFFiltering.pdf

## Consistent Normal Interpolation

GGX transmission を扱うときに geometric normal と shading normal が大きく異なると問題がある. それを低減する手法のひとつ.

https://www.researchgate.net/publication/220184585_Consistent_Normal_Interpolation
UE4で丸みのある矩形ボタンが欲しい

#画像なしで丸みのあるボタンが欲しい。

##追記。もっとスマートな方法がありました。
https://www.youtube.com/watch?v=xC1UqBJVJQY&t=1s

ただの丸のマテリアルを作って、
![thumb1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/3ce64555-b193-5b12-ef23-13403cf34410.jpeg)

BorderやImageなどのWidgetで
DrawAsをBoxにして、Marginを調整します。

![thumb2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/707048b7-9f20-423f-5a62-a42bb7e3bfd6.jpeg)

圧倒的に楽ですね爆

![thumb3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/978fab09-aff5-dfff-d249-343f2d462d46.jpeg)

TextureCoordinateを使わないでGetUserInterfaceUVのNormalizedUVを使うとBoxで歪んだUV座標もうまく表示されるみたいです。

![thumb4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/439eca68-c8fd-e328-eca0-c47cc88a4895.jpeg)


##以下の方法はイマイチかもしれません。

DiamondGradientを使ってコントラストを調整すれば、
丸みのある矩形ができるみたい。

![gradient1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/dd4d729c-5603-7439-9c91-27cd74d8f0d8.png)
![gradient2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/939b89dd-7a81-51da-259e-93eadc240480.png)
適当なsrec形式のデータを作る

S9合ってるか

```python:make_srec_and_eep_random_data.py
#coding: utf-8

import random
import sys

def make_eep_data():
	for i in range(256):
		print format(i, "02X")

# make_eep_data()

# sys.exit()

#データの合計値からチェックサム値を計算する
def calc_hosu(data_sum):
	tmp=int("0x"+format(data_sum,"02x"), 16)
	ret = 0xFF-tmp
	return hex(ret)[-2:]

#あるレコードタイプのsrecデータを適当に作る
def show_each_data_type(record_type):
	if record_type == "0":
		record_byte_len = 1
		address_byte_len = 2
		data_byte_len = 14
		checksum_byte_len = 1
		byte_len = address_byte_len + data_byte_len + checksum_byte_len
		aline_record = format(byte_len, "02X")
		aline_add = "0000"
		aline_data = "746573745f646174612e73726563"
		aline_checksum = byte_len + 0 + 0x74+0x65+0x73+0x74+0x5f+0x64+0x61+0x74+0x61+0x2e+0x73+0x72+0x65+0x63
		str_aline_checksum = calc_hosu(aline_checksum)
		print "S" + record_type + aline_record + aline_add + aline_data + str_aline_checksum
		return
	elif record_type == "1":
		byte_len = 0x13
		address_byte_len = 2
		area_start_address = 0x0
		area_end_address = 0x10000
	elif record_type == "2":
		byte_len = 0x14
		record_type = "2"
		address_byte_len = 3
		area_start_address = 0x10000
		area_end_address = 0x40000
	elif record_type == "9":
		byte_len = 0x1	#最後のチェックサム以外の2byte何か解らんからなくしてチェックサムの1byteだけにする
		aline_add = ""
		aline_data = ""
		aline_checksum = byte_len
		str_aline_checksum = calc_hosu(aline_checksum)
		print "S" + record_type + format(byte_len, "02X") + aline_add + aline_data + str_aline_checksum
		return
	else:
		sys.exit()

	checksum_byte_len = 1
	data_byte_len = byte_len - address_byte_len - checksum_byte_len
	for i in range(area_start_address,area_end_address,0x10):
		#byte数 = address(2)+data(16)+checksum(1)	(byte_len値の1byteは含まない。checksumの計算には含む)
		#タイプ	byte数	address				data					checksum
		#"S1"+	"13"+	"xxXX"+	"xxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXX"+	"xx"

		aline_checksum = byte_len

		#address
		aline_add = format(i, "0"+str(address_byte_len*2)+"X")
		aline_checksum += i
		#data
		aline_data = ""
		for j in range(data_byte_len):
			adata = random.randint(0,0xF)
			aline_data = aline_data + format(adata, "02X")
			aline_checksum += adata

		#checksum
		str_aline_checksum = calc_hosu(aline_checksum)

		print "S" + record_type + format(byte_len, "02X") + aline_add + aline_data + str_aline_checksum

record_type = "0"
show_each_data_type(record_type)
record_type = "1"
show_each_data_type(record_type)
record_type = "2"
show_each_data_type(record_type)
record_type = "9"
show_each_data_type(record_type)

# import binascii
# print binascii.hexlify("test_data.srec")


```
Essential Phone(PH-1)にカスタムROMのLineageOS 16.0を焼く話。

PH-1がLineageOSの正式サポートを受けられるようになったらしいので焼いてみたいと思う。

LineageOS 16 now available for the Xiaomi Mi 6, Xiaomi Mi Mix 2, and Essential Phone 
( https://www.xda-developers.com/lineageos-16-xiaomi-mi-6-xiaomi-mi-mix-2-essential-phone/ )

LineageOS 16.0 appears to be live for the Essential Phone.  Anybody try it yet? 
( https://forum.xda-developers.com/essential-phone/development/lineageos-16-0-appears-to-live-t3939150 )

Installation instructions
( https://wiki.lineageos.org/devices/mata/install )

Essential Phone(PH-1)にMagiskを導入した話。TWRP/ROM...etc
( https://qiita.com/Blank71/items/53e163356fd69cb27228 )

#環境
`Android 10.0 - Beta 4 - QP1A.190502.046`からの`LineageOS 16.0`への移行です。

#必読
これさえ読めれば、弊記事など読まなくても大丈夫。
Post: Steps that I followed to get it up and running 
( https://forum.xda-developers.com/essential-phone/development/lineageos-16-0-appears-to-live-t3939150/post79723223 )

#必要なもの
`lineage-16.0-<date>-nightly-mata-signed.zip`
( https://download.lineageos.org/mata )


`twrp-installer-mata-<ver.>.zip`
`twrp-<ver.>-mata.img`
( https://twrp.me/Devices/Essential/ )

（お好み）
`open_gapps-<Platform>-<Android>-<Variant>-<Date>.zip`
( https://opengapps.org/ )

#手順
以下からは実際にやったときの手順。
ブートローダーをアンロック。
ブートローダを起動し、twrp.imgをインストール。aとbのどちらのスロットにもインストールしたほうがトラブらない（と思う。）

```
$ fastboot flash boot_a twrp-3.2.3-0-mata.img

$ fastboot flash boot_b twrp-3.2.3-0-mata.img

$ fastboot reboot
```

データ領域とシステム領域の消去をする。自分の使っているTWRPはタッチが効かないから全部コマンドラインでやる。

```
$ adb shell twrp wipe data

$ adb shell twrp wipe system
```

まず、LineageOSのROMを焼く。そのあとtwrp.zipのインストールをする。

```
$ adb shell twrp sideload

$ adb sideload lineage-16.0-20190614-nightly-mata-signed.zip


$ adb shell twrp sideload

$ adb sideload twrp-installer-mata-3.2.3-0.zip
```

一度、リカバリーから脱してリカバリーに再度戻る。でないとGappsのインストールに失敗する。

```
$ adb reboot recovery


$ adb shell twrp sideload

$ adb sideload open_gapps-arm64-9.0-pico-20190614.zip
```

#感想
twrp.zipを焼いておかないと、リカバリーに入っても、LineageOSのカスタムリカバリーが起動される。このカスタムリカバリー上でGappsを焼こうとしても失敗した。また、ROMを焼くのと同時にGappsを焼いても、起動してみると焼けていなかった。上記の手順を踏めば成功すると思う。
UWPでMarkdownしよう！

# はじめに
UWPでマークダウン、どう書いてますか？  

* MarkdownSharpでHTML化してWebViewに投げる
* Markdown部分だけWEB系の言語で書いてWebViewで表示する  
* 
などなどあると思います。

**それ、公式のコントロール使って楽に実装しませんか?**

# どうするのか
**[MarkdownTextBlock](https://docs.microsoft.com/en-us/windows/communitytoolkit/controls/markdowntextblock)**を使いましょう。

# 使い方
1. 空のUWPアプリケーションを作成します。  
    **作成する際に、最小バージョンを[Windows 10 Fall Creators Update]にしてください**
1. NuGetから[Microsoft.Toolkit.Uwp.UI.Controls](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.Ui.Controls/)をプロジェクトに入れます。
1. XAML名前空間の宣言部分で  
`xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"`と記述。
1. Markdownテキストを表示したいところに  
`<controls:MarkdownTextBlock Text="**Sample**"/>`
と記述するだけ。  

TextBlockコントロールのようにBindingも使えます。  

# サンプル
Prismを絡めたBindingサンプル作りました。
公式サンプルなどと合わせて参考にして頂ければ幸いです。  

* [MarkdownSample](https://github.com/AntiquePendulam/MarkdownSample)
* [公式のサンプル](https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/MarkdownTextBlock)
ラムダ式でもっと便利になるabstract

# はじめに
本記事はabstract関連の実装の仕方について便利だと感じたことをまとめたものです。
学習前の理解度は以下の通りでした。

* abstract自体は知っているけどあまり便利さを感じなかった
* ラムダ式を知っていてもStream叩くときしか使ってなかった

抽象クラスやラムダ式の解説はいろんな方が記事を書いてくださっているため割愛いたします。

## 結論だけ知りたい

この記事で言いたいことは、「中間処理はラムダ式で渡そう」ということだけです。

## abstractで不便に感じていたところ
abstractを使うと、クラスごとで異なるロジックだけ実装して、共通で用いるロジックは使いまわせるのがいいですよね。

```java:メソッドをoverride例1
@Override 
public void execute(){
 なにか固有でやること
 super.excecute();
}
```

前処理や後処理を楽々書けちゃいますね。
ですが、中処理のロジックだけ変えたい時はどうしましょうか？
パッと思い浮かんだのはこんなコード。

```java:メソッドをoverride例2
@Override 
public void execute(){
 //前処理
 super.checkParam();

 //中間処理
 中間処理のロジック

 //後処理だけ共通ロジック
 super.excecute();
}
```
これなら中間処理だけ書き換えられますね。
しかし、これだと前処理や後処理を呼び忘れるかもしれませんし、必ず前処理が行われるのに各実装クラスで毎回定義させるのはナンセンスですね。

## ラムダ式で中間処理を書こう

本記事で言いたいことはこれだけです。

以下にサンプルコードを示します。

```java:Main.java
public class Main {
    public static void main(String[] args){
        Hoge hoge = new Hoge();
        hoge.printlnSum(20,10);
        hoge.printlnSum(10,20);
    }
}
```

```java:Hoge.java
import java.util.function.BiFunction;

public class Hoge extends AbstractHoge {

    //足し算
    public void printlnSum(Integer x, Integer y){
        BiFunction<Integer, Integer, Integer> cal = (a, b) -> a + b;
        super.execute(x, y, cal);
    }

    @Override
    protected void checkParam(Integer x, Integer y) throws FailedCheckException {
        if(x < y){
            throw new FailedCheckException("第一引数は第二引数以上を入力してください。");
        }
    }
}
```

```java:FailedCheckException.java
public class FailedCheckException extends Exception {
    public FailedCheckException(String message){
        super(message);
    }
}
```

```java:AbstractHoge.java
import java.util.function.BiFunction;

abstract public class AbstractHoge {
    void execute(Integer x, Integer y, BiFunction<Integer, Integer, Integer> cal){
        try{
            //前処理
            checkParam(x, y);
            //中間処理
            Integer result = cal.apply(x, y);
            //後処理
            System.out.println("計算結果:" + result);
        }
        catch (FailedCheckException e){
            //入力値チェックで例外出たらエラーメッセージ
            System.out.println(e.getMessage());
        }
    }

    abstract protected void checkParam(Integer x, Integer y) throws FailedCheckException;
}
```

一言で言うと、
「xがy以上のとき、足し算して出力する」です。
この「xがy以上のとき」が前処理(入力チェック)、「足し算して」が中間処理、「出力する」が後処理です。

出力結果は以下の通りです。

>計算結果:30
>第一引数は第二引数以上を入力してください。


「足し算して」の中間処理は、以下のように定義しています。

```java:Hoge.java
 BiFunction<Integer, Integer, Integer> cal = (a, b) -> a + b;
```

説明用に一度変数に入れていますが、引数にそのままラムダ式を入れることも可能です。

```java:Hoge.java変更例
public void printlnSum(Integer x, Integer y){
        super.execute(x, y, (a, b) -> a + b);
}
```

このように、ラムダ式を用いることで中間処理を渡すことが出来ます。

# さいごに
コードはGitHubに上げてます。
TypeScriptでグローバル関数を定義して使う

TypeScriptでグローバル関数を定義する方法、使う方法が意外とすぐわからなかったのでメモ。

## グローバル関数を定義する
クラス定義の外側で以下のように記述。（この例はブラウザで実行されるのが前提。）

```TypeScript
function foobar() {
    console.log("invoked foobar!");
}

(window as any).foobar = foobar;
```


## グローバル関数を使う

無いと怒られないように `declare var ...` を記述すれば、普通に呼び出せる。

```TypeScript
declare var foobar;

export class MyClass {
    public static callFooBar() {
        foobar();
    }
}
```
Docker で ubuntu18.04 を使ってみた

## はじめに
ubuntuはよく使うので備忘録がてら投稿(重要な点のみ記載してます)

## 環境
本記事は以下の環境等を使用しております。

| 環境 | Version |
|:-----|:--------|
| Windows | 10(64bit) |
| Ubuntu | 18.04(64bit) |

## 前準備 
[Windows：Docker環境が使用可能であること](https://qiita.com/osugizmo/items/81cc3581e8b40189c470)

## ubuntu18.04コンテナを起動する
```shell:terminal
# 簡略版
# コンテナの起動
docker run --name temp_ubuntu1804 -itd ubuntu:18.04 /bin/bash
```

```shell:terminal
# 通常版
# コンテナイメージの取得
docker pull ubuntu:18.04
# 取得したイメージの一覧表示
docker images
# コンテナの起動
docker run -itd <image id> /bin/bash
```

## コンテナに接続
```shell:terminal
# 簡略版
# コンテナに接続
docker exec -it temp_ubuntu1804 /bin/bash
```

```shell:terminal
# 通常版
# コンテナの確認
docker ps -a
# コンテナに接続
docker exec -it <container id | container name> /bin/sh

※docker attach <container id | container name> を
　使用することも可能ですがattachした場合exitで
　コンテナ終了してしまう＋接続は別プロセスが好ましいと考えるので
　私はexecを使います
```

## インストール済みのパッケージを更新、表示
```shell:terminal
apt -y update
apt -y upgrade
apt list
```

## 最後に
とりあえずubuntuの起動まで。