OmniAICreator/Qiita-1.07M huggingface dataset:
crypticoでPure JavaScriptによる公開鍵暗号を用いるメモ

ブラウザ上で公開鍵を用いて暗号化してから送信、そのままDBに保存、サーバー側で参照するときに復号というシチュエーションで使えるJavaScriptのライブラリを調査しました。

メモとして手順や注意点を残します。

# cryptico

クライアントとサーバーの両方で使えるライブラリとなると、このcryptico以外見つけられませんでした。
最後の更新が6年前となかなかの枯れ具合です。

http://wwwtyro.github.io/cryptico/

NPM版がこちらで、構成が少し違っています。

https://www.npmjs.com/package/cryptico

オリジナルの方は、秘密鍵の永続化の手段がありませんでしたが、NPM版にはその手段が補われています。


# キーの生成

OpenSSH形式を使えたらよかったのですが、秘密鍵を独自のJSON形式で永続化するのが楽でした。

```javascript:gen.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// ビット数とパスフレーズ
const bits = 2048;
const passphrase = 'the-passphrase';

// キーの生成
console.log('generating...');
const key = Cryptico.generateRSAKey(passphrase, bits);

// 公開鍵の保存
Fs.writeFileSync('./public.key', Cryptico.publicKeyString(key));

// 秘密鍵の保存
Fs.writeFileSync('./private.json', JSON.stringify(key.toJSON()));
console.log('complete');
```

秘密鍵はいわばパスフレーズ込みの状態で永続化されるようで、この後パスフレーズを使うことはありませんｗ

# 暗号化

Node.js向けのプログラムですが、公開鍵をテキストで用意してあげて、`crypt.cipher`を参照すれば暗号文を取得できます。この部分はブラウザでも容易に実行可能です。

`miyanaga`という平文を暗号化します。

```javascript:encrypt.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// 公開鍵
const key = Fs.readFileSync('./public.key').toString();

// 平文
const plain = 'miyanag';

// 暗号化
const crypt = Cryptico.encrypt(plain, key);

// 暗号文
Fs.writeFileSync('./cipher.txt', crypt.cipher);
console.log(crypt.cipher);
```

このような暗号文が取得できました。

> UbV1xXLUzISZBUF9ZkqwBPXtYbueCTeLfxVuNcQldlgz304vHddZjcBX2df/D2t2dANVyZPgDLugAablFy5YMhepwlDS+i1blJ8OPKOCSN7WSP8k3uRc0XKgeISvzayynbgwmv0rR8dXtI752hJk/mXnY8dcYhQqlgDkjs1nWbXrRl4py5Te1qxGs+kpHHWr7ySYsnBmRkkW1WErgB8peh5EH2/bhLH/OzVh6yoUrghS57ErtLz/OoIZCwLiTHU2JU6t5fnSoqxIKwnpX+ET8YWdDn4R4sepC176X5OmYF+hUD7QXDijT4GaZfKhvQ0zt8AUyGtvHboGnz5xKLtQGg==?AtqooM9ANbOhW/XxANySb+Sp2uwiUIonJx3qsTouZRw=

# 復号

`RSAKey.parse`で秘密鍵を復元できます。

```javascript:decrypt.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// JSON形式の秘密鍵を復元
const keyJson = Fs.readFileSync('./private.json').toString();
const key = Cryptico.RSAKey.parse(keyJson);

// 暗号文
const cipher = Fs.readFileSync('./cipher.txt').toString();

// 復号
const decrypt = Cryptico.decrypt(cipher, key);

// 平文
console.log(decrypt.plaintext);
```

無事、平文`miyanaga`を取得できました。
ライブラリの古さは感じましたが、容易に目的は達成できました。
Adsense広告ブロックをブロックするスクリプトを考えた。

#概要
個人的に広告ブロックが気に食わないので、どうすれば広告ブロックブロックをできるか考えました。

#対象
Adsenseを使われてる方。(手法を真似れば応用できます)

#実態

[Chromeのアドオン](https://chrome.google.com/webstore/detail/adblock/gighmmpiobklfepjocnamgkkbiglidom)を使うと、広告が見えなくなります。
Devtoolsでは何が起こったのでしょうか。window.adsbygoogleの中身を見てみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/7d0f3ed0-72f6-533a-ed48-1b9abe46533a.png)

下の画像は正常時。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/9af65bdf-fcf0-65e9-5685-1d372b731ccb.png)

ここに存在する関数の中身で広告ブロックを判断してやろうと思いました。

#コード
```javascript
		<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
		<script>
                (adsbygoogle = window.adsbygoogle || []).push({
                    google_ad_client: "うんぬんかんぬん",
                    enable_page_level_ads: true
                });
                //adcheck
                if((window.adsbygoogle.loaded)){
                   	console.log("adisloaed");
                }else{
                    alert("広告を読み込んでいませんね！");
                }
		</script>
```
割と単純なコードで済みました。どこにも載ってなかった。載っけるべきじゃなかったかしら？

#まとめ
様々なアプローチを試みましたが、これが一番確実でした。
iosのsafariのadblockプラグインでも有効だったし（詳しくは知らない、人に試させた）、[Chromeのアドオン](https://chrome.google.com/webstore/detail/adblock/gighmmpiobklfepjocnamgkkbiglidom)でも区別付いたし、Androidの「無料の広告ブロック　ブラウザ」や「Tenta browser」でもいけました。

これに関して評価が分かれるのは自明ですけども、手法として参考として頂ければと思います。アフェリエイトで飯を食べている人だっているだろうに、広告ブロックする人が増加してしまえば、その人のことを餓死させるも同然なことだと思いますけどね。
ゴミ記事についての書き込み自体全てゴミ記事でウザいよ!!


皆さん、
もうここら辺でゴミ記事やゴミ記事に関する記事は止めましょう。
これ以上続けてもただゴミが増えてQiitaさんに迷惑がかかるだけです。

はい!!
気持ちを切り替えて、
ゴミ記事ネタは今からもう一切止めて、
皆さんの才能の開花に繋がる記事の書き込みをしましょう。

新参者が失礼致しましたm(__)m


水城シャロ＠天才マリー
error: IB Designables: Failed to render and update auto layout status for GameController (azN-DG-Dld): dlopen(SwiftyButton.framework, 1): no suitable image found.  Did find: -bash: syntax error near unexpected token `(

# error: IB Designables: Failed to render and update auto layout status for GameController (azN-DG-Dld): dlopen(SwiftyButton.framework, 1): no suitable image found.  Did find: -bash: syntax error near unexpected token `(

## Overview

IB Designables でエラーがでますた。

困りますた。

表示されなくて、泣いてしまいますた。

ので、

解決してみた。

## 参考資料

https://github.com/evgenyneu/Cosmos/issues/105

下記をPodfileへ追加して、

```bash
$ vi Podfile
```

```ruby
post_install do |installer|
    installer.pods_project.build_configurations.each do |config|
        config.build_settings.delete('CODE_SIGNING_ALLOWED')
        config.build_settings.delete('CODE_SIGNING_REQUIRED')
    end
end
```

```
$ pod install
```

下記フォルダーごと削除し
~/Library/Developer/Xcode/DerivedData

Xcodeをcleanするとうまくいきます。

以上
LC_CTYPE: ロケールを変更できません (UTF-8)

Amazon Linuxへのsshログインにおいて以下のエラーが表示される。

```
-bash: 警告: setlocale: LC_CTYPE: ロケールを変更できません (UTF-8): そのようなファイルやディレクトリはありません
```

# 解決策

/etc/sysconfig/i18nにLC_CTYPEを追加する

## /etc/sysconfig/i18nの例

```
LANG=ja_JP.UTF-8
LC_CTYPE=ja_JP.UTF-8
```
Androidのアニメーション(ボール落下)

アニメーション効果

![ボール落下アニメーション効果.gif](https://qiita-image-store.s3.amazonaws.com/0/296847/22cf90a4-c4a5-07b6-dcb0-8988f564bc1d.gif)

１、アニメーションの設定定数、時間と回数とモード

    //時間
    private final int DURATION_TIME = 2000;
    //回数
    private final int REPEAT_COUNT = Animation.INFINITE;
    //２回以降の開始位置、
    //RESTART：初回の開始位置
    //REVERSE：終了位置
    private final int REPEAT_MODE = Animation.RESTART; //REVERSE RESTART

２、アニメーションの初期化

    //大きさアニメーション
    private ScaleAnimation scaleAnimation;
    {
        scaleAnimation = new ScaleAnimation(
                1f,0.5f,                                 //Xの開始大きさ
                1f,0.5f,                                 //Yの開始大きさ
                Animation.RELATIVE_TO_SELF,0.5f,       //開始位置の位置X
                Animation.RELATIVE_TO_SELF,0.5f        //開始位置の位置Y
        );
        scaleAnimation.setDuration(DURATION_TIME);
        scaleAnimation.setRepeatCount(REPEAT_COUNT);
        scaleAnimation.setRepeatMode(REPEAT_MODE);
    }

    //移動アニメーション初期化
    private TranslateAnimation translateAnimation;
    {
        //Animation.RELATIVE_TO_PARENT　　親のViewに対して
        //Animation.RELATIVE_TO_SELF      自分のViewに対して
        translateAnimation = new TranslateAnimation(
                Animation.RELATIVE_TO_PARENT,0, //"X"開始位置のタイプとValue
                Animation.RELATIVE_TO_PARENT,0f, //"X"終了位置のタイプとValue
                Animation.RELATIVE_TO_PARENT,0, // "Y"開始位置のタイプとValue　
                Animation.RELATIVE_TO_PARENT,0.9f //　"Y"終了位置のタイプとValue
        );
        //アニメーションの時間
        translateAnimation.setDuration(DURATION_TIME);
        //アニメーションの回数数字または　Animation.INFINITE（無限回）
        translateAnimation.setRepeatCount(REPEAT_COUNT);
        //アニメーションのMode
        translateAnimation.setRepeatMode(REPEAT_MODE);
    }

３、アニメーションセットの設定

        //ボール跳ね返す効果
        animationSet.setInterpolator(new BounceInterpolator());
        //アニメーション設定
        animationSet.addAnimation(scaleAnimation);
        animationSet.addAnimation(translateAnimation);

４、アニメーション開始


        btn_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                img_ball.startAnimation(animationSet);
            }
        });


ソースコード

https://github.com/YanHengGo/android/tree/master/animation3


いいねも忘れずに:point_up:
Xcode10でiOS実機ビルド時に"A valid provisioning profile for this executable was not found."エラーになる場合の対処法

# エラー
Xcode10で実機ビルド時に

```
A valid provisioning profile for this executable was not found.
```
というエラーが出た。

# 対処法
Mac上部メニューで
File→Project Settings...→Build SystemをLegacy Build System
にすると実機ビルドできた
AWS Session Manager (cli)におけるネットワーク切断時の挙動

# 動機

AWS Session Manager を使うと、踏み台サーバが不要になる。
踏み台サーバを利用する場合は、不意に ssh 接続が切断されてしまった場合に備えて踏み台サーバ上で tmux や screen などのターミナルマルチプレクサを利用することが多かったと思うが、Session Manager の場合は不意にネットワークが切断されてしまった場合にどのような状態になるのか気になった。

# 結論

自動的に再接続され、ネットワークが切断されていた間の出力も失われない。

## 実験結果

以下は、手元の Mac から `aws ssm start-session --target i-xxxxxxxx` した直後の画面。
そこで、`while sleep 1; do date ; done` というワンライナーを実行した。(1 秒毎に `date` を実行)
その途中で、意図的に Wi-Fi を切断すると出力が止まる。
数秒後に、Wi-Fi に再接続すると、その間に実行されていた `date` の結果もごそっと出力される。

![session_manager.gif](https://qiita-image-store.s3.amazonaws.com/0/29/7ef57faf-fb09-2e11-4f2c-cbdacc9101e3.gif)

# 調査メモ

## resume-session という API が存在する

aws-cli で、`aws ssm resume-session --session-id xxxxxxx` などとするとレジュームできるのかと思って試してみた。
出力のひとつの `StreamUrl` は `wss://` で始まる URL となっており WebSocket で実現されている様子。

https://dev.classmethod.jp/cloud/aws/ssm-session-manager-release/

> 一言で言えば､｢EC2インスタンスにSSH・RDPで接続せずにブラウザ上からCLI操作ができる機能｣です｡ブラウザがSSHクライアントとして動作している訳でなく､制御はSSMによって実現されています｡

SSM が WebSocket を扱っているイメージでしょうか。

https://docs.aws.amazon.com/cli/latest/reference/ssm/resume-session.html

ドキュメントには、Note として以下のような記載があった。

> This command is primarily for use by client machines to automatically reconnect during intermittent network issues. It is not intended for any other use.
Packerを使ってBoxイメージファイルを作成してみた。

# はじめに
Vagrantについて色々と調べてみて、業務で活用できそうだなと感じたのですが、いざ業務で使おうとなると、
Boxイメージファイルが必要になります。Boxイメージファイルはダウンロードすればいいのですが、ブラックボックのBoxイメージファイルを使うのは、業務的にまずいので、自分で作成出来ないかどうか調べていたら、Packerを見つけたので、試しに今回作成してみようと思います。

# Packerとは
Packerとは簡単に言うとコンフィグファイルをベースにマシンのイメージファイルを作成するツールです。
公式ページにおいてPackerのメリットが述べられています。

## Super fast infrastructure deployment. 
Packerイメージを使用することで、数分または数時間だけでなく、数秒でプロビジョニングされたマシンを起動できる。

## Multi-provider portability.
Packerは複数のプラットフォームで同一のイメージを作成することが可能。

## Improved stability.
Packerは、イメージが作成されるときマシンの全てのソフトウェアをインストールし設定する。

## Greater testability. 
マシンイメージを構築後にマシンイメージを早急に起動し、スモークテストをして動作しているように見せることができる。(ここはイマイチ意味が分かりませんでした。)

# Boxイメージファイルを作成してみる
早速、Packerをインストールしてみます。

```
$ brew install packer	
```

公式ページ([Build an Image](https://www.packer.io/intro/getting-started/build-image.html))眺めてましたが、AWS向けのイメージファイルの作成について述べられていました。
VirtualBoxのイメージファイルを作成したいので[Packerをつかって3ステップでVagrantのBoxを作る](https://qiita.com/ryurock/items/e3635221e4717f2addfe)を参考にやってみます。

上記のページでは、[boxcutter](https://github.com/boxcutter)にあるテンプレートを使用していたので、同じようにテンプレートを使用します。

CentOSのテンプレートをCloneします。

```
$ git clone https://github.com/boxcutter/centos.git
```

centos7.jsonのISOファイルのURLを変更

```
"iso_url": "http://ftp.tsukuba.wide.ad.jp/Linux/centos/7.5.1804/isos/x86_64/CentOS-7-x86_64-DVD-1804.iso"
```

kickstart/centos7/ks.cfgのタイムゾーンをAsia/Tokyoに変更

```
timezone Asia/Tokyo
```

あとは、boxイメージファイルの作成を実行。

```
$ packer build -only=virtualbox-iso -var-file=centos7.json centos.json
virtualbox-iso output will be in this color.

==> virtualbox-iso: Retrieving Guest additions
・・・・・
＜省略＞
・・・・・
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-iso: 'virtualbox' provider box: box/virtualbox/centos7-0.0.99.box
```

Boxファイルが作成されたので、vagrantに追加して起動してみます。

```
$ vagrant box add localcentos centos7-0.0.99.box
$ vagrant init localcentos
$ vagrant up
$ vagrant ssh
$ vagrant ssh
----------------------------------------------------------------
  CentOS 7.5.1804                             built 2018-10-13
----------------------------------------------------------------
[vagrant@localhost ~]$ 
```

とりあえず、起動確認はできました。

# まとめ
- １からpackerを実行するためのjsonファイルを作成するとなるとかなり大変。
-  テンプレートが用意されているので、テンプレートを活用したほうがいい。
-  とりあえず動かしたので、次回から詳細を確認して行く。

# 参考
[Packer](https://www.packer.io)
[Packerをつかって3ステップでVagrantのBoxを作る](https://qiita.com/ryurock/items/e3635221e4717f2addfe)
each_sliceメソッド  挙動の違い

この記事では、異なるversionでRubyの**each_sliceメソッド**を実行したところ挙動が違いましたので、それを紹介したいと思います。

実行環境は、**Ruby:2.3.1**と**Ruby:2.5.1**です。



まず簡単に**each_sliceメソッド**について解説します。
**each_sliceメソッド**とは、配列を任意の要素数に分割するメソッドです。

例えば、
[1,2,3,4,5,6,7,8,9,10]を
[1,2,3][4,5,6][7,8,9][10]のように
ある配列を３つずつ分割したいとき

```ruby

array =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

array.each_slice(3) { |a| p a }

#=>
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]
```
これを前提としてRuby:2.3.1で、以下のコードを実行します。

```ruby
post = [1,2,3,4,5,6,7,8,9,10]


post.each_slice(3) do |p, p2, p3|
    p "===="
    puts p
    p p2
    p p3
end
```
実行結果は以下のようになります。

```terminal
"===="
1
2
3
"===="
4
5
6
"===="
7
8
9
"===="
10
```
Ruby:2.3.1では、配列で返ってこないので、このような実行結果となります。私は、versionの挙動の違いを知らず、少し戸惑ってしまったので共有させていただきました。以上です。
elementary osで4Kディスプレイの解像度を設定


elementary osを入れたlaptopに4Kディスプレイを接続した際に4Kサイズの解像度を設定することに苦労したのでメモ。


- OS: elementary OS 0.4.1 Loki
- Laptop: Mi notebook air 13.3 2018
- display: Iiyama ProLite GB2888UHSU
- 接続方法: HDMI


## うまく設定できた方法

```sh
$ wget https://raw.githubusercontent.com/kevinlekiller/cvt_modeline_calculator_12/master/cvt12.c 
$ gcc cvt12.c -O2 -lm -Wall -o cvt12
$ ./cvt12 3840 2160 34.16 -b
$ xrandr --newmode "3840x2160_34.16_rb"  299.92  3840 3888 3920 4000  2160 2183 2188 2195 +hsync -vsync 
$ xrandr --addmode HDMI-2 3840x2160_34.16_rb
$ xrandr --output HDMI-2 --mode 3840x2160_34.16_rb 
```

`/etc/X11/xorg.conf.d/10-monitor.conf`に追加して永続化

```
Section "Monitor"
Identifier     "HDMI-2"
Modeline "3840x2160_34.16_rb"  299.92  3840 3888 3920 4000  2160 2183 2188 2195 +hsync -vsync
EndSection
```


参照: https://forums.gentoo.org/viewtopic-t-1065770-start-0.html

## 症状

[ここ](https://wiki.archlinux.jp/index.php/Xrandr)に書かれているように、おそらくlinuxでは一般的な`cvt`, `xrandr`を使って解像度を設定しようとしたが、うまくいかない。

```sh
cvt -r 3840 2160
xrandr --newmode "3840x2160R"  533.00  3840 3888 3920 4000  2160 2163 2168 2222 +hsync -vsync
xrandr --addmode HDMI-2 3840x2160R
xrandr --output HDMI-2 --mode 3840x2160R
```

HDMIケーブルを疑って確実に4K/60p対応のものを購入してみたが、それでもうまくいかず。

`/var/log/Xorg.0.log`のログによると、 `modeset(0): failed to set mode: Invalid argument`というエラーログで失敗していそう。

```
[   499.724] (--) modeset(0): HDMI max TMDS frequency 300000KHz
[   522.227] (II) modeset(0): Allocate new frame buffer 5760x2160 stride
[   522.408] (EE) modeset(0): failed to set mode: Invalid argument
[   522.693] (II) modeset(0): Allocate new frame buffer 3968x1152 stride
[   523.645] (II) modeset(0): EDID vendor "BOE", prod id 1719
[   523.645] (II) modeset(0): Printing DDC gathered Modelines:
```

## 解決策

このforumを見て解決した。
[4k screen Samsung U28E590 stuck at 1080p on Lenovo W540](https://forums.gentoo.org/viewtopic-t-1065770-start-0.html)

ログに、`HDMI max TMDS frequency 300000KHz`と出ているように、[TMDS](https://en.wikipedia.org/wiki/Transition-minimized_differential_signaling) frequencyというものが300MHzに制限されていることが原因っぽい。

どうやらcvt12というツールを使用してかつ、TMDS Frequencyが300MHzを超えないようにrefresh rateを調整してmodelineをジェネることが必要なよう。

なぜ300MHzのlimitが設定されてしまっているかはforum上ではわかっていない。
学習メモ：【AWS Black Belt Online Seminar】 Amazon EC2

【AWS Black Belt Online Seminar】
Amazon EC2
スライド１～２９

//メモ

「管理者権限(root / Administrator) で利用可能 」
　なんで明記するんだろう
　かつては管理者権限を付与しない前提？
　　ホスト（あまぞん）が管理者権限、
　　ゲスト（ユーザ）が限定された権限、”じゃないよ”と言いたいのかなあ

「最新のC5、M5インスタ ンスは、
EC2ソフトウェ アスタック全体をハード ウェアオフロード」
　C5、M5の役割をしりたい
　→EC2インスタンスのネーミングポリシー
　　各インスタンスの詳細は下記を参照、とのこと
https://aws.amazon.com/jp/ec2/instance-types

ネーミングポリシーは以下の通り

例：
c5.xlarge

C インスタンスファミリー
5 インスタンス世代
.xlatrge インスタンスサイズ

・汎用
M,T
・ストレージ最適化
H,D,I
・メモリ最適化
R,X
・GPU・FPGAアクセラレーテッド
F,P,G


「世代が新しい方が高性能でコストパフォーマンスも高いため、
極力最新世代のインスタンス利用が推奨」


「CPU、メモリ、ネットワークのキャパシティによって、インスタンス
サイズが分類されている。」

バースト前提のインスタンスもあり。便利そう。
公式
https://aws.amazon.com/jp/ec2/instance-types/#burst


ハードウェアオフロードってなんだ
→独自に開発したASICで実現。Nitro（ナイトロ）と読む

”Amazon EC2の最新基盤として「VMware Cloud on AWS」や「EC2ベアメタル」の実現にもつながったAWSの「Nitro System」とは？”
https://www.publickey1.jp/blog/18/aws_nitro_system.html

　
「最適化されたバージョン のLinux KVM をベースに した完全に新しいEC2 Hypervisor (C5,M5より前はXenベースの Hypervisorを使用)」
　XENってなんだ
　→ググった
　　https://www.ossnews.jp/oss_info/Xen
　　https://www.designet.co.jp/faq/term/?id=WGVu
　　http://e-words.jp/w/Xen.html
　　https://www.ibm.com/developerworks/jp/cloud/library/cl-hypervisorcompare-xen/index.html

　Linux KVMではなにが違うんだ
　→ググってそれらしい比較の連載　　http://www.hitachi.co.jp/Prod/comp/linux/doc/serial/no1.html


物理ホストの専有が可能
手段は２つ
　• ハードウェア専有インスタンス (Dedicated Instance) (2011/3〜)
　• Amazon EC2 Dedicated Host (2015/11〜)
　

コンプライアンス＆ライセンス対応のため。
オンプレ環境のリプレイス案件などで考慮に入るか

公式
https://aws.amazon.com/jp/ec2/purchasing-options/dedicated-instances/
https://aws.amazon.com/jp/ec2/dedicated-hosts/


Amazon EC2 Bare Metal

あまりピンとこず。。。
ユースケースはなんだ

公式
https://aws.amazon.com/jp/blogs/news/new-amazon-ec2-bare-metal-instances-with-direct-access-to-hardware/

→ググった
　https://www.publickey1.jp/blog/18/awsi3metal.html

EC2機能（というかAWS）がすべて使用できるIaaS、というイメージを持った。
いや、逆でAWS上に限定的にIaaSな個所がある感じか。
前述の物理ホスト占有と組み合わせて、オンプレのレガシーな環境をまるっとAWS上に移行できたりするのだろうか。

本日ここまで。
EC2のインスタンスまでなのに多い。。。
しかしながら知れば知るほど今までクラウド上でどう実現すればいいんだろうとぼんやりと思っていたところがクリアになっていい感じ。
（当方オンプレNWエンジニアにつき、目線がオンプレのクラウド移行or新規作成前提）
vs codeで日本語をprintしたらUnicodeEncodeError: 'charmap' codec can't encode characters

# どうやって出したエラーか
UnicodeEncodeError: 'charmap' codec can't encode characters は読んだ通り、文字コードに関連するエラーです。
このエラーを出した人は、自分のようにVS code のファイルエクスプローラーから対象のファイルを右クリック → 'Run Code'で実行したのではないでしょうか。
![run code.PNG](https://qiita-image-store.s3.amazonaws.com/0/145181/83fafc1f-bd88-1728-030f-1698a85412a4.png)

自分は当初Pythonコード上で文字コードの設定か何かでミスったのではないかと四苦八苦していたのですが、ふとあることに気づいたんです。
デバッグしてみたら変数の中には正しく日本語が代入されている。。。
試しにファイル出力したら問題なく出力されてる。。。
ということは、PythonではなくVS Codeの問題！

# 解決方法
Run Codeで'OUTPUT'に出力するのではなく、'TERMINAL'で直接```>python main.py```のようにして実行すれば大丈夫です。
![terminal.PNG](https://qiita-image-store.s3.amazonaws.com/0/145181/3cc3f571-18d1-d04c-14d8-a61a78381ccb.png)
Rancherでホスト追加しようとしたがagentでエラーが出ていた件

# 環境
Ubuntu 18.04
Rancher server v1.6.23
Rancher agent v1.2.11


# Agentでdocker run rancher/agent:v1.2.11(パラメータ省略)したあとに出力されていたエラー

```
$ docker logs <コンテナID>
＊＊＊＊ いろいろログ（略） ＊＊＊＊
ERROR: DNS Checking loopback IP address 127.0.0.0/8, localhost or ::1 configured as the DNS server on the host file /etc/resolv.conf, can’t accept it
```


# 解決方法
https://docs.docker.com/install/linux/linux-postinstall/#specify-dns-servers-for-docker

```
sudo nano /etc/docker/daemon.json
```

```json:/etc/docker/daemon.json
{
	"dns": ["8.8.8.8", "8.8.4.4"]
}
```

```
sudo systemctl restart docker
```
Cordovaでinfo.plistもしくはxcarchiveがないって言われた時の対処法

#エラー

Cordova開発でiOSエミュレーター起動時に

```
~ios/build/emulator/--appname.app--/Info.plist file not found.
```
もしくは、build ios、run ios時に

```
error: archive not found at path '/Users/~/platforms/ios/appname.xcarchive'
```
みたいなエラーがでる

# 対処法

エミュレーターの場合は実行時に

```
cordova emulate ios --target="--device--" --buildFlag="-UseModernBuildSystem=0"
```

ビルド、もしくは実機テストする場合も実行時に

```
cordova run ios --buildFlag='-UseModernBuildSystem=0'
cordova build ios --buildFlag='-UseModernBuildSystem=0'
```

###とにかく

```
--buildFlag='-UseModernBuildSystem=0'
```
これがミソらしい
ruby デザインパターン

## メモGoF (Gang of Four; 四人組)
https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)

このような条件分岐

```
# 自動車と飛行機を扱う
if is_car
  my_car = Car.new
  my_car.drive(200)
else
  my_plane = Plane.new
  my_plany.fly(200)
end
```
数が増えると
```

if is_car
  my_car = Car.new
  my_car.drive(200)
elsif
  my_plane = Plane.new
  my_plany.fly(200)
elsif
  my_bus = Bus.new
  my_bus.fly(200)
else

end

```
簡単に

```
my_vehicle = get_vehicle
my_vehicle.travel(200)

```
会社で使うのは
下記のように前ページから変数を渡す
```
render paratil rcalassain[:name]
```

## 継承 < 集約

継承
```
class Vehicle
  # 乗り物に関するたくさんのコード...

  def start_engine
    # エンジンをスタート
  end

  def stop_engine
    # エンジンをストップ
  end
end

class Car < Vehicle # 継承
  def sunday_drive
    start_engine
    # 地方に出かけて、戻ってくる
    stop_engine
  end
end

```
### 課題

エンジンに関するコードを共通の基底クラスであるVehicleとして抽象化し、色んな乗り物クラスで継承出来るようにしている。
しかし、この設計だとまず全ての乗り物がエンジンを持っていることが必要になってしまう。
また

集約

```
class Engine
  # エンジンに関するたくさんのコード...

  def start
    # エンジンをスタート
  end

  def stop
    # エンジンをストップ
  end
end

class Car
  def initialize
    @engine = Engine.new # 集約
  end

  def sunday_drive
    @engine.start
    # 地方に出かけて、戻ってくる
    @engine.stop
  end
end
```
磁力線や電気力線(のようなもの)を可視化する

# 風の可視化に触発されて
![qupom-dbxrd.gif](https://qiita-image-store.s3.amazonaws.com/0/22001/8165f08c-06af-5eee-dcd4-a7258616fc09.gif)


最近こういう風速を可視化したCGを目にする事はありませんか？

[東京風速](https://air.nullschool.net/)
[Earth](https://earth.nullschool.net/jp/)
[Windy](https://www.windy.com/)

風の動きが良くわかりますよね。台風が近づくと見入ってしまいます。
どうやって描画しているのかなかなかわからなかったのですが
先日 Generative Design の p5.jsのサイトを見ていてわかったのです

[Generative Design with p5.js](http://www.bnn.co.jp/support/generativedesign_p5js/)

風の可視化は　この中の　M_1_5_02　の例とほぼ同様で描画できる事に気がつきました
風速のデータ（とその取り扱い）を用意するには　ちょっと手間がかかるので
とりあえず磁力線のようなものを描いてみる事にしました

# アルゴリズム
1. 点オブジェクトを乱数の座標で多数（例えば5000ぐらい)発生させる
2. それぞれの点オブジェクトはベクトル場によって移動する。この時、軌跡を描く
3. 画面を更新する時にアルファつき(5〜10%ぐらい)で画面をクリアする
4. 画面をはみ出した点の座標を乱数で初期化する
5. 点オブジェクトに寿命(TTL)をもたせて寿命が切れたら乱数の座標で初期化する

電荷を二つ（＋）と（−）を用意して　そのまわりの電場・・・のようなものを
風速のように流れるイメージで可視化してみました
物理的、数学的に厳密なものではありません

# ソースコード
スケッチ(p5js web editor)
https://editor.p5js.org/wittyfool/sketches/r1nvkxAcQ

　# おまけ
同様の方法で Van der Polの微分方程式の解を可視化してみました
![h658e-qqh4w.gif](https://qiita-image-store.s3.amazonaws.com/0/22001/071097a7-6c07-b22c-8921-6c4b573b61f0.gif)
ステータスコードとバグの種類

ステータスコードについて学ぶ機会があったので、メモ。
サーバーいじってる時とかによく出るので、覚えて置いて損はないかも？

#よく使われる主なステータスコード

さらにこれより深くすることもできますが、一旦これで。。。。

##200系
正常系のステータスコード。何も問題がないときに出てきます。

##300系
リダイレクトされたときに出てくるステータスコード。
既存のURLが変更されたときとかに起こります。

##400系
ユーザー側でのミスがあったときに出てくるステータスコードになります。
タイプミスや必要な項目が埋められていないときになどに、エラーが出されると思いますが、
その時のステータスコードです。

##500系
サーバー側の問題が起きた時のステータスコードです。
サービスを作っているとこれがよく出てくると思います。

#バグの種類
上記のような種類のステータスコードがありますが、バグの種類にも当然当てはめることができます。

本当にざっくりですが、バグは下のように切り分けることができます。一応その対応も。

- ユーザーのミス
=> ミスをユーザーに教えてあげて、直してもらいましょう。
- システムを作る人のバグ
=> こっちのミスなので、ユーザー側には何もさせないようにします（エラー画面見せるとか）。
ちゃんとこちらのミスであることをユーザーに教えてあげます。
- システム外で起こっている外部APIのバグ
=> 例えばAWSとかtwitterとかです。ユーザー側からしたら確かに作っている人が悪いように見えますが、
これは外部システムが悪いんですよとユーザーに伝えるべき。外部が直ればokのはずだから、あとでお試しください。
とかでいいような気がします。
- 致命的なエラー
=> これは完全にこちらが悪いです。DBにつながらないとかですね。ユーザーに何かアクションさせてしまうと、
エラーに拍車がかかるかもしれないので、エラーページに飛ばして何もアクションできないようにします。


これらのバグの内、ユーザーのミスは400系、それ以外は500系になります。


ちなみに。。。。
googleの検証を使えばリアルタイムでステータスを見ることができます。
[検証] => [Network]です。Statusというカラムですね。
その状態でブラウザをいじれば、ステータスがはかれるので見ていて楽しいです。
![スクリーンショット 2018-10-13 22.31.12.gif](https://qiita-image-store.s3.amazonaws.com/0/147990/0c7e8ac8-0d77-9a2f-3e6a-4ee96e9c07d8.gif)


あまり暗記系は好きじゃないですが、これぐらいは覚えていてもいいかもです。
Twitter API で 画像投稿時にエラー

Twitter API を使った画像投稿に[tmhOAuth](https://github.com/themattharris/tmhOAuth) を使っており、以前（2013年頃）までは以下のコードで投稿出来ていました。

```php
	$filename = 'image.jpg';
	$image_path = '/path/to/' . $filename;

	$code = $tmhOAuth->request('POST', 'https://api.twitter.com/1.1/statuses/update_with_media.json',
				array(
					'media[]'  => "@{$image_path}", 
					'status'   => $str,
				),
				true, 
				true  
			);
```

ところが、最近実装すると、それだとエラーが返って来ました。

```php
	// var_dump($tmhOAuth->response);
	{"errors":[{"code":189,"message":"Error creating status."}]}
```

頑張ってググった結果、以下のように修正すると解消し、投稿できました。

```php
	$filename = 'image.jpg';
	$image_path = '/path/to/' . $filename;

	$handle = fopen($filename, "rb");
	$image = fread($handle, filesize($filename));
	fclose($handle);

	$media = "{$image};type=image/jpeg;filename={$filename}";

	$code = $tmhOAuth->request('POST', 'https://api.twitter.com/1.1/statuses/update_with_media.json',
			array(
				'media[]'  => "@{$media}", 
				'status'   => $str,
			),
			true,
			true
		);
```

どうも、media[] に渡すパラメータがいつの間にか変わったようです。

以前は、単にファイルのパスを渡すだけで良かったけど、http headerのような形式の文字列を渡す必要があると。
brew install mecab-ipadicでsyntax error

2018/10/13版でbrewインストールを行ったところエラーが発生した。
環境はmacOS Sierra。

```
$ brew install mecab-ipadic
Error: mecab-ipadic: /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/mecab-ipadic.rb:39: syntax error, unexpected <<
    <<~EOS
      ^
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/mecab-ipadic.rb:40: syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('
... enable mecab-ipadic dictionary, add to #{HOMEBREW_PREFIX}/e...
...                               ^
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/mecab-ipadic.rb:40: syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('
...mecab-ipadic dictionary, add to #{HOMEBREW_PREFIX}/etc/mecab...
...                               ^
```

syntax errorを以下のように修正。

```
$ diff mecab-ipadic.rb.old mecab-ipadic.rb.new 
39c39
<     <<~EOS
---
>     <<-EOS
```

再度実行でインストール完了。

```
$ brew install mecab-ipadic                                                         
==> Downloading https://homebrew.bintray.com/bottles/mecab-ipadic-2.7.0-20070801.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring mecab-ipadic-2.7.0-20070801.sierra.bottle.tar.gz
==> Using the sandbox
==> Caveats
      To enable mecab-ipadic dictionary, add to /usr/local/etc/mecabrc:
        dicdir = /usr/local/lib/mecab/dic/ipadic
==> Summary
🍺  /usr/local/Cellar/mecab-ipadic/2.7.0-20070801: 15 files, 50.6MB
```
React+ReduxFormでdispatchの中からredux-formに対してエラーを登録したい

みなさんはフロントエンドを実装する時ってどうしてますか？

reactだったり、vueだったり、あるいはElmだったり、そこまで使う規模じゃないのでjQueryっていうパターンも。みんな違ってみんな良いとは思います。:blush:

なんですが、今回はreact+redux-formを使っていて、
サーバーからのエラー表示で困ったということがあったりするので、備忘録も兼ねてエラー表示の方法でも。

以前に書いた[この記事](https://qiita.com/fumihiko-hidaka/items/c1de3a3044ad671e7912)の派生的な

# tutorial通りにエラーを表示する！

はい、タイトルの通りです。

```tutorial.jsx
<form onSubmit={handleSubmit(submit)}>

// 略

function submit(values) {
  return sleep(1000) // simulate server latency
    .then(() => {
      if (![ 'john', 'paul', 'george', 'ringo' ].includes(values.username)) {
        throw new SubmissionError({ username: 'User does not exist', _error: 'Login failed!' })
      } else if (values.password !== 'redux-form') {
        throw new SubmissionError({ password: 'Wrong password', _error: 'Login failed!' })
      } else {
        window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
      }
    })
}
```

[tutorial](https://redux-form.com/6.0.1/examples/submitvalidation/)的にはこんな感じで書いてあげれば良さそうです。

# dispatchの中からredux-formにエラーを渡したい！

なんですが、今回はこのタイトルのパターンなんですね。

```dame.jsx
import { SubmissionError } from 'redux-form';

export const hogeAction = (value) = dispatch => {
  console.log(value);
  const error = nanikaSugoiShori();

  // エラーが帰ってきたとして……
  throw new SubmissionError(error);
};
```

これだとOKなんですね。
正しくredux-formにerrorを渡せてあげられます！

ただ、サーバ側の処理する……ということになると、どうしても非同期処理になってしまって。
特に何も考えずに実装してしまうと……

```dame.jsx
export const hogeAction = (value) = dispatch => {
  console.log(value);

  nanikaSugoiHidoukiShori().catch(error => {
    throw new SubmissionError(error);
  });
};

// Uncaught (in promise) 
```

みたいなのだと、エラーが出てきてしまいます

```ok.jsx
import { stopSubmit } from 'redux-form';

export const hogeAction = (value) = dispatch => {
  console.log(value);

  // 何かAPIを実行してエラーが帰ってきた！
  nanikaSugoiHidoukiShori().catch(error => {
    // エラーが帰ってきた時の処理
    dispatch(stopSubmit('対象のformの名前', error));
  });
};
```

これで正しくエラーが出るようになりました！
なんですけど、stopSubmitを実行するのが気持ち悪い感じなので、もうちょっと他の方法がないか調べてみる感じ……
なぜGPUがディープラーニングに向いているのか

# CPUとは
Central Processing Unitの略でコンピュータ内で演算や制御を行う。
連続的な処理に向いている。

# GPUとは
Graphics Processing Unitの略。言葉自体はNVIDIAが作った。
単純な処理に特化した装置で高速なグラフィック処理が主な用途。

# マルチコア
従来は一つのプロセッサ内に、中核となる処理ユニット(コア)を一つ置くのが一般的だったが、最近は高性能化、省電力化によって複数のコアを配置して並列に処理を進める手法ができてきた。CPUのコアは多くても数十ぐらい。GPUの場合コアの数は数千。

# CPUとGPUの違い
複雑な逐次処理用に最適化された2～3個のコアから成るCPUに対して、GPUは複数のタスクに同時に対応できるよう設計された何千ものより小さく、より効率的なコアで構成されてる。
下記の表現がよくわかりやすい。
- GPU  『for』が得意
- CPU 『if～else～』が得意

## GPUがディープラーニングに向いている理由
ディープラーニングの学習は、、重みの行列に別の行列をかけて足し合わせる「行列の積和演算」という処理。この処理が三次元のグラフィックスのポリゴンを移動させたり回転させたりするときの行列演算(グラフィック描写)と同じなため。
そのため、ディープラーニングの学習については、GPUはCPUの何十倍、場合によっては何百倍もの速度で計算が完了する、GPUにむいているタスクである。

# 参考
- [Mythbusters Demo GPU versus CPU](https://youtu.be/-P28LKWTzrI)
- [GPUコンピューティングとは何か?  ](https://www.nvidia.co.jp/object/what-is-gpu-computing-jp.html)
- [説明できますか？CPUとGPUの違い](https://blog.aidemy.net/entry/2017/10/29/005803)
- [なぜGPUはディープラーニング・AI開発に向いているの？選び方は？NVIDIAさんに聞いてきました](https://www.kagoya.jp/howto/rentalserver/gpu_deeplearning_ai/)
Macの辞書ツールに「英辞郎」をいれる

先日「[Mouse Dictionary][92c281cf]」という大変素晴らしいChrome拡張ツールを拝見しまして，かなり使い勝手がいいなーと感じました．

  [92c281cf]: https://qiita.com/wtetsu/items/c43232c6c44918e977c9 "Mouse Dictionary"

  僕はAcrobatでよく英語pdfを見るんで，macの辞書ツールを多用してるんですが，こっちにも英辞郎いれれたらいいなと思ってしらべてたら
  やっぱやってる人いるんですね

- [  OS Xの「辞書」アプリで「英辞郎」を使う](http://www.binword.com/blog/archives/000569.html)
- [辞書アプリ「Dictionary.app」で「英辞郎」を使えるようにしてみる](http://rakkyoo.net/?p=828)
- [Eijiro text convert script for OS X Dictionary.app](https://github.com/watermint/eijiro)

でもこれらのサイトは少々情報が古いようで，，今回の買った辞書テキストファイルでどうにかこうにかしたらうまくできたので忘れないうちに書いときます．

# 環境と必要なもの
- Mac OS High Sierra
- ruby 2.3.7
- iconv

```install:sh
# なかったらインストールしといてください
$ brew install ruby@2.3
$ sudo gem install iconv
```

- [英辞郎辞書データ Ver.144.5](https://booth.pm/ja/items/777563)(古いのでも大丈夫だと思います．）
- [eiji_conv009.zip](http://www.binword.com/wp/wp-content/uploads/2007/11/eiji_conv009.zip)（[binWord/blog](http://www.binword.com/blog/)で公開されていた変換ツール）
- Xcode
- Auxiliary Tools for Xcode 7
  - [ここ](https://developer.apple.com/download/more/)からダウンロードしてdmgをマウントして中のDictionary Dvelopment Kitを適当なとこにコピーしておく．
  - あと，/Developer/Extras/Dictionary Development Kit/にもコピーしておく

# 手順
まずはproject_templateをコピーした適当なところにeiji_conv.zipの中身をコピーしておく
ついでに英辞郎テキストデータもコピー

```tejun:sh
# project_templateをコピーした適当なところに移動
$ cd temp/project_template

#XMLファイルを作成するため既存のXMLを削除
$ rm MyDictionary.xml
```

- eiji_conv.rbを使用して変換して行くのですが，今回の環境(rubyが2.0以上)ですと，エンコードエラーだったり，いろいろでるので以下のように編集してください．
  - ちなみに私はrubyに関しては素人なので，行き当たりばったりで試しました．ご了承ください．

```eiji_conv.rb:rb
##### １行目冒頭から####

#! ruby -Ku
# -*- mode:ruby; coding:utf-8 -*
# 英辞郎の英和辞書をMac OS X v10.5 "Leopard"の辞書アプリケーション（Dictionary.app）用に変換
# v0.09 by Tats_y (http://www.binword.com/blog/)
# 2011/04/10

require 'iconv'
require 'cgi'
```

こんな感じにしておきます．
完了したら

```project_template:sh
# 以下を実行して３０分くらい待ちましょう．
$ ruby eiji_conv.rb < EIJIRO-1445.txt > MyDictionary.xml

# 終わったら以下を実行して１０時間くらい待ちましょう
$ make; make install
```

これでインストール完了です．
# 辞書ツールの設定
完了したら辞書ツールで設定を行いましょう．
辞書->環境設定->英辞郎をチェック

これで完了です．お疲れ様です．
Pay.jpでカード情報非通過対応を実装してみた

# 経緯

CakePHP3で構築され、既にPay.jpを使った決済システムを使っているサイトに対し
Pay.jpから「カード情報非通過対応のお願い」が届きました。
http://payjp-announce.hatenablog.com/entry/2017/11/10/182738

これまでもカード情報をデータベースでは保持しておらず非通過対応は施していたのですが
サーバーサイドでの処理もやめてね。とのことでしたので、対応した内容を記録していきます。


# やること

Pay.jp側でいくつかやり方を用意してくれています。
今回は「チェックアウト」処理で進めます。

# Viewの編集

これまではカード情報を入力するフォームを用意していたのですが、これを消しました。
新たにPay.jpで用意されている以下のソースに置き換えます。

```payment.ctp
<form action="/pay" method="post">
  <script src="https://checkout.pay.jp/" class="payjp-button" data-key=""></script>
</form>
```

これだけで画面にはクレジットカードを入力するボタンが表示され、クリックすると
カード情報ダイアログが表示、入力をして送信までしてくれます。

非常に便利ですね！！

# カスタマイズ

リファレンスに書いてある通りにやればできるようになります笑
https://pay.jp/docs/checkout

```payment.ctp
<form action="/payment" method="post">
    <script src="https://checkout.pay.jp/" 
            class="payjp-button" 
            data-text="カード情報を追加する" 
            data-submit-text="カード情報を追加する" 
            data-key="<?= $payjp_publickey ?>">
    </script>
</form>                    
```

このような感じで必要なパラメータを追加してください。
data-keyは必須項目になります。

上記の状態ではダイアログでsubmit処理が走ることになります。
(/paymentにpostされます)

もし、ダイアログ入力後に元の画面に戻って他の項目の入力などを続ける場合や
一括でsubmit処理を行う場合はパラメータに以下を追加します。

`data-partial=true`

カード情報のトークンを使用する場合、input type="hidden" name="payjp-token"に
トークン情報が入っているのでそれを使用します。

# 最後に

ここで送信されるカード情報のレスポンスはカード情報のトークン情報ということです。
これだけでは顧客情報や決済情報とは紐づかないことに注意してください。

カード情報トークンを使った決済処理のやり方も紹介できるといいですかね。
以上、リファレンスを見てわかることをダラダラと書いてみました笑
2系のPythonのListにはclear関数が無い(辞書にはある)


Pythonの２系のリストにはclear関数が無い。
当たり前のようにあるだろうと
`list.clear()`
と書いてエラーになってから調べてみたのでまた調べなくていいようにメモっておく。

https://docs.python.jp/2.7/tutorial/datastructures.html#the-del-statement

	del a[:]

何がややこしいかっていうと辞書はClear関数を持ってるんだよね。
https://docs.python.jp/2.7/library/stdtypes.html#mapping-types-dict

割と同じような感覚で使うことが多いのに、片方はClearを持っているくせに片方は持ってないというのが悩ましい。
fortran+MPIコーディング入門(1) プロセス並列の基本

前回までで環境構築は済んだものとして、今回からコーディングに入っていきます。

目次（予定）

1. [並列処理とは](https://qiita.com/Bluepost59/items/58e111fe486c4aeb48bf)
1. プロセス並列の基本 ←今ココ
2. [集団通信](https://qiita.com/Bluepost59/items/f1871b37669b38352a7c)
3. [1対1通信](https://qiita.com/Bluepost59/items/f1426e8cb098d6632402) 
4. [オブジェクト指向コードの並列化](https://qiita.com/Bluepost59/items/1e0953c82b633a9d7602)

# プロセスとランク
**プロセス**とはMPIで並列化する処理の単位です。MPIプログラムではプロセスが複数並行して動作します。プロセスは共通の処理を行いますがそれぞれのメモリを持ち、**それぞれの変数で同じ処理を行います**。

プロセスには通し番号が振られており、その番号を**ランク**と言います。またプロセスの個数を**サイズ**と言います。

たとえば以下の画像のようなコードを書くと、各プロセスが各プロセスの変数xx、yyを持ちます。（ここでmyrankはランクを格納しているとします。）これらの変数は通信しないと同期されたりはしません。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/107045/7476e33d-2c94-98ae-5a3f-e3310da8a2c0.png)

# 基本的なコマンド
## mpif.hのインクルード
mpiを用いるために、まず```mpif.h```（fortranの場合）をincludeします [^1] 。場所は```implicit none```の後です。

## 起動処理と終了処理
mpiを用いるためには、コードの最初に```mpi_init(ierr)```を呼び出します。```ierr```はエラー番号を受けるためのinteger型変数で、事前に宣言する必要があります。

またコードの最後には終了処理として```mpi_finalize(ierr)```を呼び出します。

## ランク、サイズの取得
ランク、サイズを取得するためには、それぞれサブルーチン```mpi_comm_rank```、```mpi_comm_size```を使います。

fortranでは配列などの機能は1から始まるのに対し、**ランクは0から始まる**ので注意が必要です。

# mpiプログラムのコンパイルと実行
mpiコードをコンパイルする場合は```mpif90```を用います。

```
mpif90 -o smp01 smp01.f90
```

実行する場合も通常と異なり、openmpiを自前で実装した場合は```mpiexec```もしくは```mpirun```を用います。このとき-npオプションで並列数、つまりサイズを指定します。

```
mpiexec -np 4 smp01
```

# サンプルコード
``` fortran:smp01.f90
program main
  implicit none

  include 'mpif.h'

  integer :: nnn
  integer :: me
  integer :: ierr

  call mpi_init(ierr)
  call mpi_comm_size(mpi_comm_world,nnn,ierr)
  call mpi_comm_rank(mpi_comm_world,me,ierr)

  write(6,*) "I am ",me,"/",nnn

  call mpi_finalize(ierr)

end program main
```

このコードでは、それぞれのプロセスが自分のランクが何プロセス中の何番目なのかを取得して出力します。

各プロセスはnnnにサイズを、meにランクを書き込みます。そのため当然のように、**各プロセスは各プロセスの変数nnn、meを持ちます**。ですがnnn、meを出力するという**処理はまったく同じです**。

ここで```mpi_comm_world```はmpiコミュニケータと呼ばれるもので、プロセスの集合の名前のようなものです。基本的にはこの名前で使う場合が多いです。

## 結果
4並列で実行した場合の結果例は、以下のようになります。

```
 I am            1 /           4
 I am            3 /           4
 I am            0 /           4
 I am            2 /           4
```

おのおののプロセスは自分が準備できたタイミングでwriteするため、必ずしもランクが小さい順に並んだりはしません。

そのため1つのファイルにログを書き込んだりすると、どの内容がどのプロセスが書き込んだものかわからなくなります。そのためファイルに出す場合は別ファイルに出すようにしたほうがいいでしょう。

# 参考文献
http://www.cv.titech.ac.jp/~hiro-lab/study/mpi_reference/index.html#chapter2

[^1]: 基本的にinclude文はコードを内容結合にしてしまい可読性を著しく落とすため、用いるべきではありません。今回のように一般的な信頼できる外部ライブラリを用いる場合は例外ですが、自作のコードをincludeするようなことはやめましょう。
fortran+MPIコーディング入門(0) 並列処理とは

MPIはプロセス並列のライブラリとして並列計算業界でデファクトスタンダードになっています。特に理論シミュレーション業界では、数百ノードに及ぶ並列化されたスパコンでfortran+MPIで書かれたコードがスタンダードになっています。

僕は大学院までfortranとMPIでプラズマの粒子シミュレーションをやっていました。いろいろ経緯があってほぼ独学でMPIを習得したということもあって、個人的に思い入れもあるので、まとめてみようと思います。

本シリーズ記事について

* 対象とする人
    * fortranの基本文法がわかる人
    * 並列計算を初めてやる人
* 目標
    * fortranでMPIコードが読み書きできる

目次（予定）

1. 並列処理とは ←今ココ
1. [プロセス並列の基本](https://qiita.com/Bluepost59/items/5cce1174ac48367948bc)
2. [集団通信](https://qiita.com/Bluepost59/items/f1871b37669b38352a7c)
3. [1対1通信](https://qiita.com/Bluepost59/items/f1426e8cb098d6632402) 
4. [オブジェクト指向コードの並列化](https://qiita.com/Bluepost59/items/1e0953c82b633a9d7602)

# MPIとは
並列計算手法には、メモリを共有する**スレッド並列**と、メモリを共有しないがノード（≒端末）をまたいで並列化できる**プロセス並列**があります。前者の代表例はopenMPで、後者が本記事のテーマであるMPIです。

スレッド並列には並列化分割数に上限があり、かつ1ノード内で完結する処理しかできません。それに対して、MPIによるプロセス並列では**その上限を大きく超えた数**（例えば1000コア以上）で、かつ**複数ノードにまたがる**規模で並列計算を行うことができます。

スパコンでは大量のブレードサーバを並列化させて計算するので、大規模な理論シミュレーションではMPIはほぼ必須となっています。例えば、代表的なスパコンである京では、スペック上は最大で82944ノード*8コア＝663,552個ものプロセスを並列に処理することができます（そのような処理が現実に実行できるかはわかりませんが）。

#MPIを使う下準備
## 一般的なスパコンの実装
学生でスパコンを使う理論シミュレーションを行う研究室にいる人なら、スパコンに用意されているはずなので、詳しくはそれぞれのマニュアルを見てください。

スパコンは共用利用となっているので、SSH接続を受け付けるログインノードと、計算を実行する計算ノードに分かれています。ログインノードのキューにジョブを投入し、順番にジョブが計算ノードに渡されて実行されるというシステムになっています。

## 自前で環境を構築する
スパコンにアクセスできない普通の人でも、オープンソースの実装があるのでインストールできます。

実装には、有名なものにOpenMPIとMPICHがあります。端末が1つしかなくても1ノード内で並列化したり、仮想端末と通信させるなどもできます。

本シリーズ記事での動作確認はWSL（Windows Subsystem for Linux）上にaptで構築した環境を使っています。openMPIの場合、次の4つを入れれば環境はできます。

```apt install openmpi openmpi-dev libopenmpi libopenmpi-bin```

ノード間で通信を行うには、sshや、nfsやsshfsなどのファイル共有の設定をしなければなりません。

おまけ：nfsやsshfsはFUSEという機能を用いる必要がありますが、残念なことにWSLのような仮想環境ではFUSEを使えないためにノードを並列化させることができません。orz
WSLのUbuntu 18.04にRをインストールする

# Rのインストール

[公式の手順](https://cran.r-project.org/bin/linux/ubuntu/README.html)に従うと、GPGキーを追加しようとするところで以下のようなエラーになる。

```sh
user@machine: $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
Executing: /tmp/apt-key-gpghome.9mHVAuakLR/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
gpg: connecting dirmngr at '/tmp/apt-key-gpghome.9mHVAuakLR/S.dirmngr' failed: IPC connect call failed
gpg: keyserver receive failed: No dirmngr
```

これはどうやら、`dirmngr`というデーモンが立ってるはずだけどWSLでは立ってない、ということらしい。

https://github.com/Microsoft/WSL/issues/3286#issuecomment-396653804

さしあたり、公式の手順の「If the first gpg command fails, you may want to try」っていう方をやればいける。

```sh
gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
gpg -a --export E298A3A825C0D65DFD57CBB651716619E084DAB9 | sudo apt-key add -
```

あとはふつうの手順にどおり。

```sh
echo "deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/" | sudo tee /etc/apt/sources.list.d/r.list
sudo apt update
sudo apt-get install r-base-dev
```

# パッケージのインストール

Rのパッケージをインストールするのは、ソースからビルドするのは時間がかかりすぎるので[c2d4u3.5](https://launchpad.net/~marutter/+archive/ubuntu/c2d4u3.5)を使う。Ubuntu 18.04は[要求されてるバージョン](https://github.com/r-spatial/sf#linux)を満たしているのでubuntugis-unstableのPPAを使わなくてもいけるはず。

```sh
sudo add-apt-repository ppa:marutter/c2d4u3.5
sudo apt install r-cran-tidyverse r-cran-devtools r-cran-sf r-cran-rstan
```

もちろん、c2d4u3.5にないやつもあるので、そこは`install.packages()`でインストールする。

# RStudio Serverのインストール

ついでにRStudio Serverもインストールする（Emacsを使うつもりなので使わないけど）。[公式の手順](https://www.rstudio.com/products/rstudio/download-server/)通り。

```sh
sudo apt-get install gdebi-core
wget https://download2.rstudio.org/rstudio-server-1.1.456-amd64.deb
sudo gdebi rstudio-server-1.1.456-amd64.deb
```

インストール直後はそのまま起動するので http://localhost:8787 にアクセスするとRStudio Serverの画面が見えるはずだ。WSLを閉じてもバックグラウンドで動き続ける。起動や停止は、systemdは動いていないので`service`コマンドで制御することになる。

```sh
# 起動
sudo service rstudio-server start
# 停止
sudo service rstudio-server stop
```
[Elm]elm-formatでexposeする関数を整理する

module documentを書いておくとelm-formatさんはいい感じにexposeする関数を並べてくれる

__つまりこう！__
![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/16af6cd9-8f9b-a904-4e5a-b2273e84c5fd.png)

> elm 0.19.0
elm-format-0.19 0.8.0

## 前置き
elm-formatはElmの楽しいフォーマッターです。フォーマッターがなければ開発環境ではない世の中ですので当然ほとんどの人はフォーマッターを使用していろいろな言語を書いていると思いますが、中でもかなーり書き換えてきます（他言語の経験があまりないので当社比です）

![](https://i.gyazo.com/572872804952eced43fa6fdcf209b723.gif)

> exposing allは許されないの図

ちなみにElm自体の作者は使ってないことでも有名です（要出典）

## 問題
elm-formatは勝手に**module exposingをアルファベット順に並び替える**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/60449b3c-1a50-b925-ea59-ee29894d1720.png)
> multi line

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/e7f84860-adeb-04a5-5c19-d3b57c21c628.png)
> single line

どっちにしろみにくいですね。強制的にアルファベット順になるのでいくら並び替えようとelm-formatかけた時点で無意味です

## 解決策
module documentを書きます

```elm
module Select exposing
    ( beforeIf, afterIf
    , by, head, last
    , all, allBefore, allAfter
    )

{-| module documentはmodule文とimport文の間に書けるmulti line commentのこと

@docs beforeIf, afterIf
@docs by, head, last
@docs all, allBefore, allAfter

-}

import Types exposing (SelectList(..), reverseAppend, toList)
```

`@docs`ごとに改行して並び替えてくれるようになります。

## 追加TIPS

gif撮ってて気づいたんですがdocsある状態でexposing allを書き換えるとdocsあるやつだけexposing内に展開してくれるようになってます。ました。書き得じゃん

### 追記
docsに追加するだけでexpose追加されるようになってました

![](https://i.gyazo.com/df04cce87a2262bb206c0d5c98c7836c.gif)

## 宣伝
[elm-jpコミュニティでは公式ガイドの翻訳活動してます](https://github.com/elm-jp/guide)

進捗的に半分いってて、レビューしてくれる人がわたしとヤギの人だけで辛いし見落としがあるのでレビュアー募集してます

Elmのことわかんなくて大丈夫です。
sha256 の計算（macOS）

こんにちは。
macOS 上で sha256 値などを計算させてみました。

```console
$ echo -n '' | gzip > empty.gz
$ md5 empty.gz
MD5 (empty.gz) = 14248b891e6bb3dd955f1c53be538f39
$ openssl sha1 empty.gz 
SHA1(empty.gz)= 3bf5e0a5f1b2a8f0a8826a3c0a0d0c16502953fe
$ shasum -a 1 empty.gz
3bf5e0a5f1b2a8f0a8826a3c0a0d0c16502953fe  empty.gz
$ shasum -a 256 empty.gz
ecfd46aa0435a3a9b1c5d6d5e29c0e92bbfd75ee2f5894196e0028574b35136f  empty.gz
$ brew install md5sha1sum
$ md5sum empty.gz
14248b891e6bb3dd955f1c53be538f39  empty.gz
```
JupyterlabでRとJavascriptを使う

#JupyterLabの短い紹介

JupyterLabは新しいデータサイエンスのためにアプリケーションです。Jupyter Notebookの後任です。JupyterLabをインストールするとPythonだけ使えます。Pythonは悪くないけど、ほかの言語も使えるようにできます。この記事にJupyterLabをインストール仕方、またはJupyterLabでRとJavascriptを使え方について書きます。

私はUbuntu 16.04を使えるからほかのシステムの仕方はたぶん違います。

####JupyterLabをインストールしましょう
まずは、JupyterLabの自体をインストールしなければならない。Pythonのpipかcondaでインストールできます。
condaを使ったら：`conda install -c conda-forge jupyterlab`
pipを使ったら：`pip install jupyterlab`

よし。今JupyterLabにPythonでコーディングをできます。インストールの確認ためにこののコードを入力しましょう：`jupyter lab`
新しいタブでJupyterLabは開くはずです。

####Rを可能にしましょう

まず、devtoolsというRパケージをインストールします：
`install.packages("devtools")`

そして新しいdevtoolsでGithubからIRkernelをインストールします：
`devtools::install_github("IRkernel/IRkernel")`


最後にIRkernelとJupyterLabがつながるために：
`IRkernel::installspec()`

おめでとう。今JupyterLabにRを使えます。

####Javascriptを可能にしましょう

[npm](http://liberty-technology.biz/PublicItems/npm/npm.html)と[node](https://nodejs.jp/)は必要です。

npmからijavascriptをインストールします：
`npm install -g ijavascript`

そして：`ijsinstall`

####確認

`jupyter lab`をターミナルを入力して、ブラウザでこんなことを見るといい：

![Screenshot from 2018-10-13 23-43-16.png](https://qiita-image-store.s3.amazonaws.com/0/282576/f851838b-1170-674c-e0ed-930283eacb26.png)
VSSからGitにリポジトリ移行


#Microsoft Visual SourceSafeからGitへ移行

たまたまそうするタイミングがあったので、その備忘録。

#使用したツール

Git for Windows
https://gitforwindows.org/

vss2git
https://github.com/trevorr/vss2git
　Release　v1.0.11
　※ソースからビルドしたものを使用したらエラーが増えたので、とりあえずリリース版を選択

　他にも Rubyを使用した vss2git.rb なものが存在。こちらの方が細かく設定できそうです
　（今回は使用していない）
　https://github.com/hanaguro8/vss2git

TortoiseGit
https://tortoisegit.org/

# 変換開始
- vss2git起動

　変換元と変換先のパスを指定するだけ。変換するだけなら後はそのままでもOK。

　VSS Settings
　- Directory -> VSSリポジトリがあるパスを指定

　Output Settings
　- Directory -> 変換後の出力先
　- Log file -> 変換ログの出力先ファイル指定

　Goボタンを押して変換開始。簡単。
　規模にもよるけど、そこそこの時間は待つ。

# 結果
　途中、mvでpermissionエラーが発生
　ExplorerのプロセスをKillすると直るとの情報があったので、それを実行してみるも改善せず。

　ログを調べた結果、履歴で名前変更した後に同じ名前で新規作成していたため、移動できずエラー？
　結局そのまま無視して実行。
　ただ上記の部分で、リポジトリ上残骸が残っていたので手動でgit操作して削除

# 感想
　今回はこれでもよかったものの、他の環境だとそうはいかないかもしれない・・・
　しかし、最近はGithubに何かしらツールがあったりするので便利な時代になりましたね。
Microsoft COCOデータセットを使うためのCOCO APIをWindows 10にインストールするメモ

# はじめに
COCO APIは、Microsoft COCOデータセットを容易に扱うためのAPIです。COCOは、オブジェクトの検出、セグメンテーション、人のキーポイントの検出、物のセグメンテーション、およびキャプションの生成用に設計された大規模な画像データセットです。 
- COCOについて
 - http://cocodataset.org/
- COCO APIについて
 - https://github.com/cocodataset/cocoapi
今回は、Python3.6 の COCO API を Windows 10 の Anaconda環境にインストールするときの方法を紹介します。（LinuxやmacOSならそのままインストールできます）

# 環境構築
COCO APIのパッケージをインストールする際、C/C++コードのビルドが発生します。ここでは Visual Studio 2017 のインストールとPythonのインストールを行います。

## Visual Studio 2017 のインストール
まずは、Visual Studio 2017のビルド環境を整えます。cythonなどを利用するPythonパッケージのインストールで使用するため、Windows環境でPyhtonを使う場合は整えておいたほうが良いでしょう。

Visual Studio 2017のどのエディションでも大丈夫だとおもいますが、注意点としては、インストール時に、「C++ ワークロードを使用したデスクトップ開発」を選択することです。以下のページを参考にしてください。

- Visual Studio での C++ のサポートをインストール
 - https://docs.microsoft.com/ja-jp/cpp/build/vscpp-step-0-installation?view=vs-2017

- Visual Studio のダウンロードサイト
 - https://www.visualstudio.com/downloads/

## Pythonのインストール
Python環境はAnacondaを使用します。Anacondaは分析や機械学習を行うためのライブラリも問題なく利用できます。また、パッケージのインストールや環境作成が非常に簡単に実行できるのが特徴です。Anacondaは下記のサイトよりダウンロードします。利用しているOSに合わせて適切なパッケージをインストールしてください。次をクリックしていくような感じで、標準の設定で大丈夫です。あと、PATHもそのまま登録するようにしてください。

- Anaconda
 - https://www.continuum.io/downloads

# COCO API利用環境の作成

スタートメニューからAnaconda Promptを実行して、Python 3.6の環境を作成します。condaコマンドで環境を作成してからactivateコマンドで作成した環境を使用しています。

``` powershell
conda create -n py36 python=3.6
activate py36
conda install setuptools
conda install cython
conda install matplotlib
```
次にCOCO APIをGithubから取得します。

``` powershell
git clone https://github.com/cocodataset/cocoapi.git
```

コンパイラのオプションを変更します。cocoapi/PythonAPI/setup.py の extra_compile_args を以下に変更します。引っかかるのはワーニングのオプションなので

``` python
ext_modules = [
    Extension(
        'pycocotools._mask',
        sources=['../common/maskApi.c', 'pycocotools/_mask.pyx'],
        include_dirs = [np.get_include(), '../common'],
        extra_compile_args=[],
    )
]
```
COCO APIのインストールを実行します。

``` python
python setup.py build_ext install
```

# COCO APIのモジュール読み込み確認
以下のようにパッケージをインポートしてエラーが出ないことを確認します。

``` python
from pycocotools.coco import COCO
```

以上です。
アタック25を再現してみた【Python3】

新入生歓迎会の企画で，アタック25（早押しクイズ）をやることになったため，そこそこハイクオリティなアタック25プログラムを作成しました．（下の画像は実際に動作している様子）
![IMG_1595.JPG](https://qiita-image-store.s3.amazonaws.com/0/227432/5e8ab332-c02a-c978-aea3-40cc78aac4d7.jpeg)


> [アタック25パネル管理システム【GitHub】](https://github.com/kuboyoo/Attack25)
[![ss.gif](https://qiita-image-store.s3.amazonaws.com/0/227432/dbdb5bd6-cd37-b347-3656-984d6cb057a3.gif)](https://github.com/kuboyoo/Attack25)

# 実行環境
- Python3が動作するPC5台(メインPC1台+枚数表示用PC4台)
- ルータ
- Python 3.7.0

# 必要なパッケージ（for BGM）
メインPC，獲得枚数表示用PC共に音声出力には`pygame`を用いている．
`pip install pygame`

# 注意事項
このプログラムは４台のPCのIPアドレスを固定し，メインPCからルーターを経由し，獲得枚数が変化するたびにソケット通信で枚数を送信することで，リアルタイムに獲得枚数を管理しています．
そのため，PCのIPアドレスと実行するプログラムの対応に注意する必要あり．以下が対応表です．

|デバイス  |ルータ              |メインPC   |赤PC    |緑PC    |白PC    |青PC   |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|IPアドレス  |192.168.0.1  |192.168.0.2  |192.168.0.3  |192.168.0.4  |192.168.0.5  |192.168.0.6|
|実行プログラム名| |main.py |sub.py | sub.py | sub.py | sub.py |
IPアドレスは適宜自分の環境に合わせて変更してください．その際にソースのアドレスも変更してください．
通信機能が不要で，手軽に実行したい人のために，デフォルトでは通信は行わないようになっているため，はじめは`main.py`だけで動作します．通信も行いたい人はGitHubの`README.md`の通りソースコード内のコメントを変更してください．

# やりたいこと
1. アタック25のパネルを管理する
2. 各色の現在の獲得枚数をリアルタイムで表示
3. アタックチャンス（別の回答者が任意のパネルを再度獲得できるようにするチャンス）
4. 2.とは別に色ごとに計4台のモニターで獲得枚数を表示
5. 4台のPCのEnterキーを押すと効果音がなり，ディスプレイを各チームの色で塗りつぶす
6. パネルを獲得した際に，効果音を鳴らす
7. 各色ごとに取れるパネルを点滅させる（サジェスト機能）
8. 獲得枚数が最多の解答者が海外旅行を賭けた最終問題に挑戦

#main.py
## GitHubにて類似プログラムを発見．
> [アタック25アプリ【GitHub】](https://github.com/ktair/attackXX)

やりたいことの1〜3までは実現されていたため，このコードをベースにして作成することにしました．
しかし，このコード，実行してみるとパネルを左下から右上に２枚のパネルを挟むとパネルの色が変化しないというバグを発見したため，実際にはパネルの色変更を行うプログラムも書き換えました．

## 色ごとに計4台のモニターで獲得枚数を表示
これに関してはGPUを使えば１台のPCだけで実現可能かもしれないが，空きのGPUがなかったため，PCを4台用意し，メインPCから4台のPCへ各色の枚数をそれぞれ送信し，それを各PCで表示するという方法をとりました．Pythonには`socket`というパッケージがあるため比較的簡単に実装することができました．

## 効果音を鳴らす
効果音は，ゲーム開発用のパッケージ`pygame`を用いることで，音声の再生・停止などを実装しました．

## 各色ごとに取れるパネルを点滅させる（サジェスト機能）
サジェスト機能は，以下の（おそらく競プロ用の）記事を参考に実装しました．
> [CodeIQ挑戦の記録：今週のアルゴリズム：第86回アタック25に挑戦！](http://ibeckuu.hatenablog.com/entry/2016/03/31/011830)

記事通りでは，言語がRubyであったのと，アタックチャンス時の例外処理がされていなかったため，追加で記述する必要がありました．また再帰で実装されていたが，個人的に再帰の実装が苦手なので，再帰を用いずに書いたため，コードが汚くなってしまいました．

#sub.py
4台のPCのIPアドレスを取得し，そのアドレスが，
`192.168.0.3` => 赤の枚数を表示
`192.168.0.4` => 緑の枚数を表示
`192.168.0.5` => 白の枚数を表示
`192.168.0.6` => 青の枚数を表示
となるように実装しているため，違うIPアドレスを使う場合は，適宜ソースコード変更してください．

#film_quiz.py
アタック25を再現するのには欠かせない最終問題．このプログラムは，
1. 指定したフォルダにある複数枚の静止画を読み込み，上にパネルを重ね，（音源の長さ）/（枚数）[秒]ずつ静止画を切り替える処理
2. 音声を再生する処理
の二つの処理を同時に行わないといけないため，PythonのThreadingパッケージを用いて実装しました．また，上に重ねるパネルの情報は`main.py`をEscキーで終了するときにtxtファイルで保存されるようにしているため，そのtxtファイルから読み込まれます．

# 最後に
以上，Pythonとネットワークの勉強がてら作ってみたアタック25プログラムでした．
皆さんもぜひ使ってみてください．結構盛り上がります．
ちなみに，優勝景品はラズパイ3モデルBでした．
![IMG_5775.JPG](https://qiita-image-store.s3.amazonaws.com/0/227432/adb93337-5c2b-33f7-4272-d3a9b6caddf8.jpeg)
オブジェクト指向についてまとめてみた！

ソフトウェア開発では、欠かせないオブジェクト指向ですが、

今回そのオブジェクト指向についてまとめてみました。

<h2>オブジェクト指向とは</h2>

オブジェクト指向は、オブジェクト（Object）つまり、物という意味から

ネット上では、現実世界の物を例えて説明するサイトが多いです。

しかし、オブジェクト指向は、現実世界の物に例えると

むしろこんがらがります。

では、ソフトウェア開発の全体をカバーするオブジェクト指向はどのように捉えれば

いいのかというと、あくまでデジタル、プログラミングの世界で成り立つ規則と捉えれば

わかりやすいです。

オブジェクト指向を一言でいうと

>「業務分析から要求定義、設計、プログラミング、開発プロセスまでをカバーする
ソフトウェア開発の総合的な技術である」
[1]より引用

ということになります。


<h2>プログラミングにおけるオブジェクト指向とは</h2>

オブジェクト指向プログラミング（Object Oriented Programming）、略してOOPは、

「クラス」、「ポリモーフィズム」、「継承」の3つの仕組みを利用することで

今までのプログラミングをさらに使いやすくした仕組みと言えます。

そこで、これらの3つの便利な仕組みを順にみていきたいと思います。

<h2>1. クラス</h2>

クラスには、便利な仕組みが3つあります。

関数と変数をまとめる仕組み。クラスの内部だけで使う変数や関数を隠す仕組み。

一つのクラスからインスタンスをたくさん作る仕組み。

まず、関数と変数をまとめる仕組みですが、OOPでは、クラスにまとめられた関数を「メソッド」、グローバル変数を「インスタンス変数」といいます。

メソッドとインスタンス変数にまとめることで複数の関数とグローバル変数をまとめることが

できるのでより簡素なコードを書くことができます。

次に、クラスの内部だけで使う変数や関数を隠す仕組みですが、クラス内の変数にprivateと

指定することでクラス内のメソッドのみしかアクセスできない変数を定義することができます。

同様に、メソッドも他のクラスから隠すことができます。また、publicと他のクラスからでも

呼び出せる変数、メソッドを定義することも可能です。このように、変数やメソッドにアクセスできる

範囲を限定することでよりわかりやすいコードを書くことができます。

最後に一つのクラスからインスタンスをたくさん作る仕組みですが、一つのクラスを定義するだけで

同種の情報を同時に扱えるようになります。

つまり、OOPでは配列などを使って変数領域を複数用意することなくインスタンスを生成させることが

できるのです。これもまた、コードの解読性を高めることができます！

<h2>2. ポリモーフィズム</h2>

ポリモーフィズムは、関数における概念の逆で、呼び出される側が増えても呼び出す側を変更

しなくて良い仕組みです。つまり、ポリモーフィズムを使うことにより多種の関数に対応した

コードを書くことができます。

<h2>3. 継承</h2>

継承とは、
>「変数とメソッドをまとめた共通クラスを作って、その定義を丸ごと拝借できる仕組み」という。
[1]より引用

継承を使うとき、共通に使いたいメソッドとインスタンス変数をスーパークラスと定義し、

利用したいクラスはそのスーパークラスを継承します。この時利用したいクラスは、

サブクラスと呼びます。よって、継承はクラス定義の共通部分を別クラスにまとめることで

コードの重複を排除できる仕組みです。


<h2>まとめ</h2>

オブジェクト指向は、プログラミングに置いて3つの要素（クラス、ポリモーフィズム、

、継承）に分かれることがわかりました。これらは、かつての関数とグローバル変数のみを

使用したコードの複雑性を解消することに貢献しています。より簡素なコーディングを

目指す上で必須の知識と言えるでしょう！


<h2>参考資料</h2>
[1]「オブジェクト指向でなぜつくるのか」、平澤章