OmniAICreator/Qiita-1.07M huggingface dataset:
Nginxのリーバスプロキシ化（Apacheと共存）

#やりたいこと
Nginxでリーバスプロキシを動かして、Apacheに処理を任せる

①アクセス → ②Nginx → ③Apache → ④処理を返す

#リバースプロキシとは？
一言で言うと、サーバー側のプロキシ
使うメリットとして、
**・** 本来のサーバーを隠蔽できる
**・** 複数台のサーバーを使う事によって負荷分散ができる
以上の事がメリットとして上げられる。

###なぜNginxなのか
>Apacheでもリバースプロキシの機能はありますが、単純なリクエストを大量に捌くのが得意というNginxの特徴をうまく活かせる点から、Nginxを採用する事例が多いようです。

>今回はWebサーバにもNginxを使用しますが、複雑なアプリケーション処理はApacheで行い、NginxによるリバースプロキシがApacheにリクエストを転送するという構成が用いられることもあります。
[引用URL](http://tech.respect-pal.jp/reverse_proxy_cooking/)

#Nginxのインストール
CentOs7にApacheがインストールされている事を前提に、Nginxをインストールします。

Nginxとポートが被るのでApacheを止めておく
`systemctl stop httpd` 

###リポジトリの設定ファイルを記述
まずリポジトリの設定をするためにファイルを作成

```text:ファイルを作る
# vi /etc/yum.repos.d/nginx.repo
```
ファイルの中に下記を記述

```conf:設定ファイル
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```
<details><summary>サンプルコード</summary><div>
使用されているディストリビューションに応じて、 "OS"を "rhel"または "centos"に、 "6."または "7.x"では "OSRELEASE"を "6"または "7"に置き換えます。

```conf:文法
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/{OS}/{OSRELEASE}/$basearch/
gpgcheck=0
enabled=1
```
</div></details>

###Nginxのインストール
```text:インストールコマンド
# yum install nginx
```

###Nginxの起動と停止
```sh:コマンド
#自動起動
 systemctl enable nginx

#起動
 systemctl start nginx

#停止
 systemctl stop nginx
```
###起動確認
http://localhost
にアクセスしてNginxの画面が出たらインストール完了
![スクリーンショット 2018-06-06 11.48.25.png](https://qiita-image-store.s3.amazonaws.com/0/164811/659c663a-ef45-6114-165f-8ff4bd39796f.png)


#リバースプロキシの設定
###Apacheのポートを変更
Nginxとポートが被るので、Apacheのポート番号を80から8080へ変更

```conf:/etc/httpd/conf/httpd.conf
Listen 80
    ↓         #変更
Listen 8080
```
###Apache再起動

```
# systemctl restart httpd
```

###リーバスプロキシを設定
`/etc/nginx/conf.d/`に`reverse_proxy.conf`ファイルを作成
ファイル名はなんでもよい、ただし拡張子はconfを付けてください

```nginx:/etc/nginx/conf.d/reverse_proxy.conf
server {
  listen 80;               # ポート番号80番でアクセスされたら
  server_name localhost;   # http://localhost でアクセスされたら

  location / {
    proxy_pass http://127.0.0.1:8080; # どこにアクセスさせるか
    proxy_redirect                          off;
    proxy_set_header Host                   $host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-Proto      $scheme;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
  }
}
```

###サーバーのバージョンを隠す

```nginx:/etc/nginx/nginx.conf
http {
  # ↓これを追加
  server_tokens off;
}
```

###Nginxの再起動
`systemctl restart nginx`

[http://localhost](http://localhost)にアクセスすると、Apacheの画面が表示されます。
これでリバースプロキシの設定が完了しました。

<!--
#X-Forwarded-For
リバースプロキシを使うと、Apache側でアクセス元のIPアドレスではなくリバースプロキシ側のIPアドレスが取れてしまう。
解決策として、mod_rpafを使う。

###mod_rpafのインストール
-->


<br>メモ

```text:Nginxの設定ファイル場所
/etc/nginx/nginx.conf
```
#参考
[Nginx公式](http://nginx.org/en/linux_packages.html)
[リバースプロキシ](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
Rails + webpacker + Vue.jsプロジェクトにESLintを導入

今回はVue.js用の公式ESLintプラグインを使用します。

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

```
$ yarn add -D eslint eslint-loader eslint-plugin-vue
```

## Loaderの設定

config/webpack/loaders/eslint.jsを作成します。

```

module.exports = {
  test: /\.(js|vue)$/,
  loader: 'eslint-loader',
  enforce: 'pre',
  options: {}
}

```

さらにenvironment.jsを編集します。

```
const { environment } = require('@rails/webpacker')
const vue =  require('./loaders/vue')
const eslint =  require('./loaders/eslint')

environment.loaders.append('vue', vue)
environment.loaders.append('eslint', eslint)
module.exports = environment

```

## ESLintルールを作成

.eslintrc.jsonをプロジェクト直下に作成します。
ここは自由にカスタマイズしてください。

```
{
  "extends": [
    "eslint:recommended",
    "plugin:vue/recommended"
  ],
  "rules": {
    "semi": "error",
    "indent": ["error", 2],
    "quotes": ["error", "single"]
  }
}

```

## 開発サーバーの起動

```
$ bin/webpack-dev-server
```

でコンパイルされ、その時にESLintも走るようになります。


## 実行スクリプトの用意
ESLint単体で動かしたい時用に設定します。
package.jsonに実行スクリプトを記述します。

```
{
  .
  .
  .
  "scripts": {
    "lint": "yarn run eslint --ext .vue --ext .js app/javascript"
  }
}
```

以下コマンドでESLintを実行できます。

```
$ yarn run lint
```

## 参考

[eslint-plugin-vue を作っている話](https://qiita.com/mysticatea/items/860ce3bf0ff387f166ac)
[Add eslint to rails 5.1 • Christoph Lipautz](https://unused.github.io/blog/posts/eslint-rails/)
Ubuntuの環境を設定する_3

#はじめに
授業で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#環境構築する内容
SSH
Apache Ver2.4.18
MySQL Ver5.7.13
PHP Ver7.0
Samba

#インストール

###MySQL Ver5.7.13

~$ [sudo apt-get -y install mysql-server]
MySQLサーバのインストール
![0606_17.png](https://qiita-image-store.s3.amazonaws.com/0/249280/c7a5178a-b5a4-0150-2a41-6dc2fc060984.png)
※インストール中、MySQLのrootパスワードの設定を求められるので、設定する

~$ [mysqld -V]
Version確認

~$ [mysql -u root -p]
MySQLにログイン
[Enter password:]と出てくるので、Mysqlのrootユーザに設定したパスワードを入力

mysql> [create database test;]
データベース作成
※今回は[test]にしているが、任意で変更ができる

mysql> [exit;]
MySQLを切断

~$ [sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf]
外部から接続させるための設定編集
![0606_18.png](https://qiita-image-store.s3.amazonaws.com/0/249280/504977a9-4638-402d-61f4-55f3a806abdc.png)
この画面になるので、[/bind-address]と入力する
![0606_19.png](https://qiita-image-store.s3.amazonaws.com/0/249280/0ce24e5e-c2e6-6239-b062-238dc9dd2aae.png)
この赤枠の所を[i]で挿入モードにしてからコメントアウトする
bind-address = 127.0.0.1
↓
[#]bind-address = 127.0.0.1
![0606_20.png](https://qiita-image-store.s3.amazonaws.com/0/249280/e37f8347-4343-aefe-4236-3c6a509eb0ec.png)
※[:wq]で上書き保存を忘れずに

~$ [sudo /etc/init.d/mysql restart]
MySQLの再起動
※restartの所を[start]にすると起動、[stop]にすると停止する

###Samba
~$ [sudo apt-get -y install samba]
Sambaのインストール

~$ [sudo chmod 777 /var/www/html/]
Sambaで共有するフォルダのパーミッションを変更
※パーミッションとは、ファイル一つ一つまたはディレクトリに対するアクセス権のこと。

~$ [sudo vi /etc/samba/smb.conf]
Sambaの設定
![0606_21.png](https://qiita-image-store.s3.amazonaws.com/0/249280/1fcfbcfa-f00d-b8bd-d2e0-3c548490a2df.png)

25行目付近の[global]の下に下記を追加する。
unix charset = UTF-8
dos charset = CP932
![0606_22.png](https://qiita-image-store.s3.amazonaws.com/0/249280/46bde2e6-271e-a3b9-00aa-e377b48c05cc.png)

50行目付近：コメント解除しアクセス許可IP追記

![0606_23.png](https://qiita-image-store.s3.amazonaws.com/0/249280/e877c69c-9b6d-4c99-7308-d243fd99defb.png)

interfaces = 127.0.0.0/8 192.168.0.0/24 192.168.11.0/24 192.168.23.0/24 eth0

![0606_24.png](https://qiita-image-store.s3.amazonaws.com/0/249280/0fbea07f-8590-263a-7cf1-920176b7a7f8.png)

58行目：コメント解除
![0606_25.png](https://qiita-image-store.s3.amazonaws.com/0/249280/0398a3b5-a080-35ff-a1dc-2ff657f02aac.png)

bind interfaces only = yes

![0606_26.png](https://qiita-image-store.s3.amazonaws.com/0/249280/87374974-1e7b-7733-7302-7c239932f6d5.png)

最終行に下記を追加する
[html]
path = /var/www/html
writable = yes
browseable = yes
guest ok = yes
guest only = yes
create mode = 0777
directory mode = 0777
![0606_28.png](https://qiita-image-store.s3.amazonaws.com/0/249280/74988703-38f0-a3b3-ee1c-d5fb396edec7.png)

~$ [sudo service smbd restart]
Sambaの再起動

SambaをGUI画面から設定する場合は、下記コマンド
~$ sudo apt-get install system-config-samba
~$ sudo system-config-samba

![0606_29.png](https://qiita-image-store.s3.amazonaws.com/0/249280/13b3380b-a951-9819-a81e-82e328a127d0.png)
※[SystemError: could not open configuration file `/etc/libuser.conf’: そのようなファイルやディレクトリはありません]と表示される場合は、下記をコマンドを実行する
~$ sudo touch /etc/libuser.conf
~$ sudo chmod 777 /etc/libuser.conf
~$ sudo system-config-samba

#セキュリティ関連の無効化
###ファイアウォールを無効にする
~$ [sudo ufw disable]

###apparmor無効化(SELinuxのようなもの)
~$ [sudo service apparmor stop]
Ubuntuの環境を設定する_2

#はじめに
学校で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#環境構築する内容
SSH
Apache Ver2.4.18
MySQL Ver5.7.13
PHP Ver7.0
Samba

#インストール
起動したターミナルでコマンドを打つ
###apt-get
~$ [sudo apt-get update]
パッケージのアップデート

###vim
~$ [sudo apt-get -y install vim]
初期状態ではvi(vim)の動作がおかしいため、コマンドでvi(vim)を最新の状態にする

###SSH
~$ [sudo apt-get -y install ssh]
このコマンドでインストール後、SSH接続ができるようになる

###Apache Ver2.4.18
~$ [sudo apt-get -y install apache2]
Apacheのインストール

~$ [apache2 -v]
Version確認

~$ [sudo /etc/init.d/apache2 start]
Apacheサーバの起動

###PHP Ver7.0
~$ [sudo apt-get -y install php php-mysql libapache2-mod-php libapache2-mpm-itk]
PHPのインストール

~$ [sudo vi /etc/php/7.0/apache2/php.ini]
PHPの設定
[extension=msql.so]のコメントアウト「;」を削除し、有効化する
![0606_9.png](https://qiita-image-store.s3.amazonaws.com/0/249280/415d2a4e-d3d1-e13c-ea9e-802c66c5acbe.png)
この画面が表示されたら、まずはEscキーを押してコマンドモードにしておく

![0606_10.png](https://qiita-image-store.s3.amazonaws.com/0/249280/dcfaa394-080d-c6cf-85da-8c9b040b312d.png)
コマンドモードにした状態で、[:set number]と入力すると、行番号が表示される

![0606_11.png](https://qiita-image-store.s3.amazonaws.com/0/249280/563bd173-be72-0aa7-e7ca-02371c5cef4c.png)
[/extension=msql.so]と入力する
※/(スラッシュ)を先頭に付けるとキーワード検索ができる

![0606_12.png](https://qiita-image-store.s3.amazonaws.com/0/249280/73f1c545-bf85-8517-f385-596d2fd94dd9.png)

![0606_13.png](https://qiita-image-store.s3.amazonaws.com/0/249280/8252a9f0-cd14-97f3-b28c-7549bec58f0f.png)
キーボードの[i]を押すと挿入モードになるので、編集ができるようになる

![0606_14.png](https://qiita-image-store.s3.amazonaws.com/0/249280/aa4694ff-36d4-e8d8-ca22-406baf6539f8.png)
先頭にある[;]を消した後、Escキーを押して挿入モードを解除しておく

![0606_15.png](https://qiita-image-store.s3.amazonaws.com/0/249280/cfca46cf-c6b4-c107-5351-3d9e316a3721.png)
[:wq]を入力する
※[:wq]は上書き保存

![0606_16.png](https://qiita-image-store.s3.amazonaws.com/0/249280/6b6c3841-e45e-2db4-0fd0-5c04e7dce78e.png)
Enterを押すと、この画面に戻ってくる

~$ [php -v]
Version確認

~$ [sudo /etc/init.d/apache2 restart]
apacheの再起動
※パスワードを求められるので、入力

-----
次に続きます
Ubuntuの環境を設定する

#はじめに
授業で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#環境構築する内容
SSH
Apache Ver2.4.18
MySQL Ver5.7.13
PHP Ver7.0
Samba

#準備
まずはGuest Additionsをインストールする
![0606_1.png](https://qiita-image-store.s3.amazonaws.com/0/249280/ff19f60c-64a2-9e03-67cf-660b1da77160.png)
デバイスの[Guest AdditionsCDイメージの挿入]を選択

![0606_2.png](https://qiita-image-store.s3.amazonaws.com/0/249280/6eb81ffe-4d14-8953-b56a-6c562e7e3081.png)
[実行する]を選択

![0606_3.png](https://qiita-image-store.s3.amazonaws.com/0/249280/9b4293a5-d6f7-7f49-9521-520f27e6f120.png)
自分で設定したパスワードを入力する

![0606_4.png](https://qiita-image-store.s3.amazonaws.com/0/249280/d7853039-6269-79d2-016c-97ad476a3610.png)
インストールが完了すると、[Press Return to close this window...]と出るのでEnterキーを押す

![0606_5.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b1df18d6-4e34-84a0-30cd-cd37983bee5a.png)
[取り出す]を選択して取り出しておく

![0606_6.png](https://qiita-image-store.s3.amazonaws.com/0/249280/3cbdfdcc-2764-5327-1d26-0ccc12cf98c9.png)
アプリケーションのシステムツールから、MATE端末を選択

![0606_7.png](https://qiita-image-store.s3.amazonaws.com/0/249280/4da70a14-3508-d77f-390f-315755aaf213.png)
これでターミナルが起動できる

-----
次に続きます
Ubuntuのインストール

#はじめに
授業で学んだ事のメモとして使います。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#Ubuntuの起動、初期設定
VirtualBoxを起動し、作成したUbuntuのVirtualBox仮想HDイメージファイルを選択、起動する

![Ubuntu.png](https://qiita-image-store.s3.amazonaws.com/0/249280/600ad567-1492-b283-05e8-8dd2dcad51fa.png)
起動したら日本語を選択し、インストールを選択

![Ubuntu2.png](https://qiita-image-store.s3.amazonaws.com/0/249280/96dc2402-2bce-8439-c5d9-41baed6d301b.png)
インターネットの回線が早いなら、[Ubuntuのインストール中にアップデートをダウンロードする]を選択し、続ける

![Ubuntu3.png](https://qiita-image-store.s3.amazonaws.com/0/249280/537333a6-98a0-d3ef-1d7d-10d8b72a479f.png)
[ディスクを削除してUbuntuをインストール]を選択し、インストールする

![Ubuntu4.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b302d43f-491d-1148-2bc3-66292158980e.png)
このようなホップアップが出るので、続ける

![Ubuntu5.png](https://qiita-image-store.s3.amazonaws.com/0/249280/027d21dc-e8ad-c099-8ee0-965a3ddef046.png)
[Tokyo]のまま、続ける

![Ubuntu6.png](https://qiita-image-store.s3.amazonaws.com/0/249280/a315e79f-1582-3e4f-0c34-066e57ff88fb.png)
どちらも日本語と選択されているか確認し、続ける

![ubuntu_1.png](https://qiita-image-store.s3.amazonaws.com/0/249280/0bd3b2ea-033f-e1ab-c904-1a4970458094.png)
自分で付けたいユーザー名とパスワードを入力する
※[自動的にログインする]を選択していれば、起動時に自動的にログインしてくれる

![Ubuntu8.png](https://qiita-image-store.s3.amazonaws.com/0/249280/978b80d8-1daf-fb64-d875-ad2b6b840d30.png)
インストールが開始されるので、しばらく待つ

![Ubuntu9.png](https://qiita-image-store.s3.amazonaws.com/0/249280/ef1c88b4-3960-15ef-aca9-8649e6ec1dbd.png)
インストールが終わると、このようなポップアップが出るので[今すぐ再起動する]を選択

![Ubuntu10.png](https://qiita-image-store.s3.amazonaws.com/0/249280/a4a48cba-748f-f996-0b53-287822b96088.png)
これでVirtualBoxにUbuntuがインストールが完了
多態性

#多態性
多態性とは複数のデータ型として表現できる概念です。
#多態性の基本
多態性は「多様性」や「ポリーモフィズム」とよばれることもあります。
#多態性の仕組み
多態性に概念を実現しているのは「型変換」という、オブジェクトのデータ型を変換する機能です。型変換には、暗黙のうちに実行できるものと明示的に実行しなければならないものがあります。暗黙のうち実行できるもの場合は、単に代入演算子を使用することができる。明示的に変換しなければならない場合は、キャスト演算子かaｓ演算子を使用して変化した結果を代入する必要があります。
#as演算子とキャスト演算子
as演算子は参照型の変数のみ使用することができ、型変換に失敗するとnullを変換します。キャスト演算子は、値型、参照型のどちらにも使用することができ、型変換に失敗すると例外エラーが発生します。
#ボックス化
ボックス化とは、値型を参照型にすることです。逆に参照型から値型を抽出することをボックス化解除と呼びます。
```C#
int i = 1;・・・・1
Object o = i;・・2
int j = (int)o;・3
```
1は、int型変数「i」に1という定数を代入しています。

2は、ボックス化の例です。int型からObject型に暗黙の型変換を行った結果を変数「j」に代入しています。

3は、ボックス化解除です。キャスト演算子を使用してObject型からint型に明示的な型変換を行った結果を変数「j」に代入しています。
WPFとは

#1-WPF
私は今までWPFがどういった物なのかを知らなかったので調べてみました。
調べた結果、「前身のWindowsフォームを使いやすくしてくれたような物」みたいな曖昧な理解でそれ以上知ろうとしませんでした。
しかし最近授業が難しくなってきて少し詰まってしまう事が増えてきたのでこれを機にそもそもWPFがどういった物なのか理解を深めようと思って調べてみた結果を書いていきます。
#2-WPFについて調べてみた
WPFとは何かGoogleで検索して出てきた結果がこれでした。
　> 
>> 
WPFはコアの部分にグラフィックス・ハードウェアを活用したベクター・ベースのレンダリング・エンジンを採用している。ベクター・ベースであるため、UI要素にスムーズな拡大・縮小／回転を掛けることができる。また、ハードウェア・アクセラレーションにより、CPUへの負担を最小限に抑えている。

*わかりませんでした*
なので実際にどのようにしてUI設計をするのか試してみました。
![xaml画面.PNG](https://qiita-image-store.s3.amazonaws.com/0/249276/591d2f35-48aa-9756-0929-2955e95574bc.png)
xamlっていうファイルの中に設置したボタンや各項目のサイズや位置をクリック操作で簡単に変更できました。
前述の引用文に書いてあることは多分こういうことだと思います。
こういう基礎の動作の部分を上手く使えて初めて難しい操作ができるようになっていくと思ったのでもう少し基礎を固めていこうと思いました。
Windows10 をアップデートしたら VirtualBox のゲストが起動しなくなった

## TL;DR
ホストオンリーアダプタが消えていたので、新しく作成して、ゲストに再度割り当てる。

![virtualbox_エラー画像](https://qiita-image-store.s3.amazonaws.com/0/71497/3495d808-ff1d-81ce-d46c-e94b929f2335.jpeg)

## ホスト
* OS: Windows10
* 当たったパッチ: Windows10 April 2018 Update (バージョン1803)
* VirtualBox のバージョン: 5.2.6

## ゲスト
* ネットワーク1: NAT
* ネットワーク2: ホストオンリーアダプタ
* OS: CentOS 6.9

## 対策
一番上に書いた通りだけど、少し詳しく書いてみる。

まず `グローバルツール` から `ホストネットワークマネージャ` を開いて `作成` し、ゲストがデフォルトゲートウェイとして指定している IPアドレスを追加する。
作成時や編集時に管理者権限を求められる。

次に `マシンツール` でゲスト一覧に戻り、ゲストを選択して `設定` を押し、 `ネットワーク` で `ホストオンリーアダプター` を `割り当て` ているタブ開き、先ほど作ったネットワークを選択して保存する。

起動させてエラーが出なければおしまい。
ワイヤレスジャパン2018 Androidセッション Android ThingsとKotlinで作るIoT

[ワイヤレスジャパン2018](http://www8.ric.co.jp/expo/wj/)に参加してきましたのでその結果をまとめています。

内容の間違い、誤字脱字等はご了承ください。正確なところは、本家のサイトを参照いただければと思います。

# タイトル等

## タイトル
ワイヤレスジャパン2018 Androidセッション Android ThingsとKotlinで作るIoT

## 演者
* 金田浩明さん　ブリリアントサービス

## 日時
2018/05/24 11:00-12:20のうち1回目

## 関連リソース
[金田さんスライド](https://www.slideshare.net/hiroakikaneda/android-things-kotliniot-98378490)
[Android Thingsの概要とKotlinでのLチカ(別の方の記事)](https://qiita.com/akimach/items/07cc61b16068336be86a)

# 概要

Androidを利用したIoT開発を行う上での概要や、実例について知ることができました。

# Android Thingsとはなにか

Androidの開発経験をそのまま生かして、IoTを操作することができる。

Android SDKのサブセットとなる。カーネルやファームウェアはGoogleが開発し、ユーザードライバーは機器メーカー、またはユーザーが開発する。

# ハードウェアの知識がなくてもよい

周辺機器のインタフェースとして、IoT物理にアクセスするため、ハードウェアの知識がなくてもよい。例えば、ソフトウエアのボタンを制御する感覚でハードウェアのボタンを制御できる。

つまり、スマートフォンの開発経験を生かして、IoTの開発を行うことができる。

# JavaからKotinへ

AndroidではJavaからKotinへ開発言語が移行するという方向になる。

## 特徴

* 文脈から型推論を行う。
* オブジェクト指向言語である。
* 先進的なコーディングスタイルを、関数型プログラミング。Javaよりも安全に（Nullチェック、クラスの型チェック）などが厳格になっている

# クラウドコンピューティングから、エッジコンピューティング

ディープラーニングは、クラウドコンピューティングでも行えるが、IoT側でも行えるようになっているので、クラウドコンピューティングから、エッジコンピューティングという方向性がある。

# Demo

## テレビ付け防止強制OFFガジェット

誰が何時間テレビを見たのかというのを管理し、警告してくれるガジェットを自作した。

内部的な処理としては、画像をOpenCVで抜き出した、Android ThingsとTensorFlowで学習モデルを作って、人を区別している。このガジェットをAndroidで簡単に作ることができた。

1. OpenCVで顔認識
2. FireBaseに画像転送
3. Tensorflowで顔認識。転移学習で1～2分
4. Android ThingsでTensorflow Liteに変換

[ソースコード](https://github.com/googlecodelabs/tensorflow-for-poets-2/)
[TFLite Android](https://codelabs.developers.google.com/codelabs/tensorflow-for-poets-2-tflite/#3)

# GoogleのIot

[Google Cloud IoT](IoTサービス用の PaaS の位置付けです)は、IoTサービス用の PaaS の位置付けとなる。

Azure IoT Hubみたいなもの。デバイスとクラウドをつなくことがクラウド上で全部できる。AIや機械学習もできる。GoogleのIoTに関する本気度というものが見えてくる
【c#】foreachを使って、配列の値をすべて表示する

```c#

using System;

namespace foreach_sample
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            //foreachを使って、配列の値をすべて表示する

            // 1. 配列を初期化
            float[] weights = { 61.2f, 62.5f, 64.9f, 63.2f, 65.1f, 63.6f, 67.9f };

            // 2. foreachを回す
            //foreach (型名 変数名 in 配列名)
            foreach (float w in weights)
            {
                Console.WriteLine(w);
            }
        }
    }
}

```
MobX 4 から flow という紛らわしい名前の API が加わりました

MobX 3 系では、今まで非同期処理を書くのが若干冗長でした。

こう書いていたのが

```js
import { observable, runInAction } from 'mobx'
import { someApi } from '../api'

class SomeStore {
    @observable someState = ''

    async someAction() {
        const res = await someApi.fetch()
        runInAction(() => {
            this.someState = res.data
        })
    }
}
```

MobX 4 からは、 `flow` という紛らわしい名前の API を使ってこう書けます。

```js
import { observable, flow } from 'mobx'
import { someApi } from '../api'

class SomeStore {
    @observable someState = ''

    someAction = flow(function * () {
        this.someState = yield someApi.fetch()
    })
}
```

中身でどうやっているか分からないですが、すっきりしました。
ジェネレーターとクラスプロパティを使っててかっこいいです。

ただ、エラー処理まで入れると、従来のPromiseの方がシンプルな気もします。

```js
import { observable, action } from 'mobx'
import { someApi } from '../api'

class SomeStore {
    @observable someState = ''
    @observable error = null

    someAction() {
        someApi.fetch().then(
            action(res => this.someState = res.data),
            action(err => this.err = err),
        )
    }
}
```
【c#】Dictionaryを使い日付と体重データを保持する例

```c#

using System;
//以下の名前空間を追加
using System.Collections.Generic;

namespace dictionary_weights
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            // Dictionaryを使い日付と体重データを保持する例

            // 1. Dictionary型の変数を作る
            Dictionary<string, float> weights = new Dictionary<string, float>();

            // 2. Dictionaryに要素を追加
            weights.Add("2017/12/10", 62.6f);
            weights.Add("2017/12/11", 21.9f);
            weights.Add("2017/12/12", 41.8f);
            weights.Add("2017/12/13", 62.1f);
            weights.Add("2017/12/14", 42.7f);
            weights.Add("2017/12/15", 82.1f);
            weights.Add("2017/12/16", 63.8f);
            weights.Add("2017/12/17", 23.8f);

            // 3. 2017/12/13の体重を表示
            Console.WriteLine(weights["2017/12/13"]);
        }
    }
}

```
Excel の「選択範囲内で中央」を ON／OFF するマクロ

あらゆる業務で活用されているであろう ~~憎き~~  Excel。
ちょっと込み入った表を作成するときに「セルを結合して中央揃え」をすると
セルのコピー＆貼り付けやソートの際に

「この操作は結合したセルには行えません。」
「この操作には、同じサイズの結合セルが必要です。」
「コピー領域と貼り付け領域のサイズが違うため、貼り付けることができません。」
というエラーが出ることがある。

その場合におすすめな「選択範囲内で中央」という書式設定。
セルの書式設定 ＞ 「配置」タブ ＞ 横位置 から「選択範囲内で中央」を選択すると、 
言葉の通り、複数セルの中央に値を配置することができる。

B～F列を選択して「選択範囲内で中央」を設定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229637/b89091fd-d628-0a88-1a0e-4f9e59095602.png)

以下のように、まるで結合しているように見えるが、セルは独立したままになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229637/27278ce4-ba75-2ad4-3fd6-c632f97881ad.png)

残念ながら、この書式設定にはショートカットが無く、
わざわざ「セルの書式設定」を開かないといけない。

というわけでマクロの出番。
以下のマクロを作成し、 Ctrl+Shift+C あたりに割り当てればOK。

```visualbasic
Sub CenterAcrossSelection()
'
' CentarAcrossSelection Macro
' 選択範囲内で中央 ON/OFF
'
' Keyboard Shortcut: Ctrl+Shift+C
'
    If Selection.HorizontalAlignment = xlCenterAcrossSelection Then
        Selection.HorizontalAlignment = xlGeneral
    Else
        Selection.HorizontalAlignment = xlCenterAcrossSelection
    End If
    
End Sub
```

使い方は以下の通り。
1. 「選択範囲内で中央」の設定を（したい／外したい）セルを起点に、複数の範囲を選択
2. マクロを実行
fuelphp1.8  routerメソッドをつかってURLを動的にする


DBに登録したショップデータを表示するコントローラーで、actionの引数でなく、メソッド部分を動的にして表示する

通常
http://example.jp/コントローラ/メソッド/（ショップID）/
↓
したい事
http://example.jp/コントローラ/（ショップID）/


```php:controller_shop.php
	public function router($method, $params){

		$shop = Model_Shop::query()->where('shop_id','=',$method)->get_one();

		if($shop){
            //DB登録されているショップデータの要求があった場合.
			return $this->view($shop);
		}else if(method_exists($this,'action_'.$method)){
            //actionメソッドでの要求があった場合.
			return $this->{'action_'.$method}($params);
		}else{
            //ページが存在しないURLの場合.
			return Request::forge('_404_')->execute();
		}

	}
```
Ubuntu18.04にdocker-compose 1.19以降をインストールしたい


## 背景

2018年6月6日現在、`apt`では`docker-compose 1.17.1`しかインストール出来ません。

```
$ sudo apt install apt-show-versions
```

```
$ apt-show-versions -a -p docker-compose
docker-compose:all 1.17.1-2 bionic jp.archive.ubuntu.com
No stable version
docker-compose:all not installed
```

しかし`docker-compose`で`nvidia-docker`のコンテナを管理するためには、`docker-compose 1.19.0`以降が必要です。

参照: https://github.com/docker/compose/releases/tag/1.19.0

そこで、aptを使わずに`docker-compose`をインストールします。

## 環境

* OS: Ubuntu 18.04

docker 17.12とnvidia-docker2がインストール済み。
この手順で入れました: https://qiita.com/sabaku2017/items/f7cc8fd614ea7c15034e

## docker-compose 1.21.2のインストール

せっかくなので、現時点で最新の1.21.2をインストールします。
手順は、公式で解説されている通りの手順です。

参照: https://docs.docker.com/compose/install/

### githubから実行ファイルをダウンロード

```shell
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
```

### 実行権限付ける

```shell
sudo chmod +x /usr/local/bin/docker-compose
```

### インストールされたバージョンの確認

```shell
$ sudo docker-compose --version
docker-compose version 1.21.2, build a133471
```

version 1.21.2が入りました。

## 動作確認

nvidia-docker2などで使う`runtime`オプションが動作するか確認してみましょう。
前提として、この手順はnvidia-docker2が使える状態になっていないと動かないです。

### docker-compose.ymlの準備

nvidia-docker上でコンテナを起動し、`nvidia-smi`を実行するように指定します。

```shell
$ cat docker-compose.yml 
version: '2.3'
services:
  nvidia:
    image: nvidia/cuda
    runtime: nvidia
    command: nvidia-smi
```

`up`してみます。

```shell
$ sudo docker-compose up
Starting temp_nvidia_1 ... done
Attaching to temp_nvidia_1
nvidia_1  | Wed Jun  6 04:56:28 2018       
nvidia_1  | +-----------------------------------------------------------------------------+
nvidia_1  | | NVIDIA-SMI 390.48                 Driver Version: 390.48                    |
nvidia_1  | |-------------------------------+----------------------+----------------------+
nvidia_1  | | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
nvidia_1  | | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
nvidia_1  | |===============================+======================+======================|
nvidia_1  | |   0  GeForce GTX 1080    Off  | 00000000:01:00.0  On |                  N/A |
nvidia_1  | | 28%   42C    P8     7W / 180W |    838MiB /  8118MiB |      1%      Default |
nvidia_1  | +-------------------------------+----------------------+----------------------+
nvidia_1  |                                                                                
nvidia_1  | +-----------------------------------------------------------------------------+
nvidia_1  | | Processes:                                                       GPU Memory |
nvidia_1  | |  GPU       PID   Type   Process name                             Usage      |
nvidia_1  | |=============================================================================|
nvidia_1  | +-----------------------------------------------------------------------------+
temp_nvidia_1 exited with code 0

```

動きました。完成です。
Swiftで文字を任意の数繰り返した文字列にしたいときはそれ用のメソッドがある

# 結論

Xcode8（Swift3ぐらい？）からStringに文字列を繰り返すメソッドがあったのでこれが使える

```swift
let s = String(repeating: "ab", count: 10)
print(s)
// Prints "abababababababababab"
```

Appleのリファレンス Documentation > Swift > String > init(repeating:count:)
https://developer.apple.com/documentation/swift/string/2427723-init

# はじめに

文字列を規定以上に増やしてエラーになるような処理のテストコードを書きたかった。

rubyだと次のように書ける。

```ruby
"a" * 2 # => "aa"
```

そのため、Swift 4.1でも同じようなことをやろうと、何も考えずにオペレータオーバーライドでのそれっぽい考えとして次のようなのがあると思う

```swift
import Foundation

func * (left: String, right: Int) -> String {
    var total = ""
    (0..<right).forEach { _ in
        total += left
    }
    return total
}

print("a" * 2)         // => "aa"
print(("a" * 2).count) // => 2
```

しかし、これだとStringオブジェクトをループごとに`+=`で作成してしまっていて無駄な気がする（例えば`* 2000`にすると2,000のStringが作られてる気がする）。テストで使いたい、無駄なコピーしてでも手に入れたいわけだけど、なんだか気になる。

ここで、Appleのリファレンスを調べていると`String(repeating: "ab", count: 10)`があることがわかった。

Swiftのコードは設計図共有サイトにあるので見てみる。まず、swift4.1のブランチ

https://github.com/apple/swift/blob/swift-4.1-branch/stdlib/public/core/StringLegacy.swift#L31-L44

```swift
  public init(repeating repeatedValue: String, count: Int) {
    if count == 0 {
      self = ""
      return
    }
    precondition(count > 0, "Negative count not allowed")
    let s = repeatedValue
    self = String(_storage: _StringBuffer(
        capacity: s._core.count * count,
        initialSize: 0,
        elementWidth: s._core.elementWidth))
    for _ in 0..<count {
      self += s
}
```

なるほどねー、たしかにcountが0のときとかマイナスのときの処理は必要だよねーと思ったものの、最後に結局`+=`で文字列を生成している様子。

ただ、swiftの最新2018-06-06のtag（swift-DEVELOPMENT-SNAPSHOT-2018-06-05-a）に切り替えてみると、ループで文字列を結合しているわけではないみたい🤔

https://github.com/apple/swift/blob/swift-DEVELOPMENT-SNAPSHOT-2018-06-05-a/stdlib/public/core/StringVariant.swift#L55-L65
TypeScript Sampleをやってみる目次

# はじめに
`TypeScript SampleをやってみるそのＸ` の目次を投稿します。
それぞれの記事を一覧で見られるようにします。
サンプルのお試の備忘録をアップしています。
説明がブランクは未投稿記事となります。目次を都度更新していきます。
お試しの投稿はランダムになります。
目次の「そのｘ」以下の列にある数字をクリックすると記事にジャンプします。
TypeScriptをやってみようという奇特なチャレンジャーでかつ初学者向けかな。
# Microsoft TypeScript Samples Contents
サンプルファイル : https://github.com/Microsoft/TypeScriptSamples/archive/master.zip

|No|サンプル|説明|そのＸ|最終更新日|
|:--|:--|:--|:-:|:-:|
|01|amd|Asynchronous Module Definitionサンプル|[その１](https://qiita.com/pooshikin/items/fc620ee9591fa633cb9b)|20180518|
|02|angular1||||
|03|angular2||||
|04|async||||
|05|browserify|Browserifyサンプル|[その２](https://qiita.com/pooshikin/items/230214db280e5f3e54ec)|20180606|
|06|d3|Data-Driven Documentsサンプル|[その３](https://qiita.com/pooshikin/items/68a5a3c7a3c98768a52a)|20180522|
||d3|Data-Driven Documents付録|[その３＋](https://qiita.com/pooshikin/items/4eec9c849bf1fb5cb27f)|20180528|
|07|greeter|Hello world!サンプル|[その７](https://qiita.com/pooshikin/items/364c1033487422eacc75)|20180604|
|08|imageboard||||
|09|interfaces|interfaceサンプル|[その４](https://qiita.com/pooshikin/items/663641738987b1e485a8)|20180528|
|10|jquery|jQueryサンプル|[その５](https://qiita.com/pooshikin/items/c7dc6a2bcafd55412a09)|20180529|
|11|jspm||||
|12|jsx||||
|13|mankala||||
|14|node|tcpとhttpサーバサンプル|[その８](https://qiita.com/pooshikin/items/48ceff02e5a8227f52df)|20180607|
|15|raytracer||||
|16|react-flux-babel-karma||||
|17|simple|派生クラスのスーパーコールサンプル|[その９](https://qiita.com/pooshikin/items/7aa046d8316f7fb2aa9c)|20180611|
|18|systemjs||||
|19|todomvc|Backbone.jsを使用したToDoサンプル|[その１０](https://qiita.com/pooshikin/items/7bbe3f672e0ea138f035)|20180614|
|20|umd||||
|21|warship|海戦ゲームサンプル|[その６](https://qiita.com/pooshikin/items/cbcdd57e362899638a3d)|20180531|
|22|Twitter|[番外編]Twitterあいさつツイートサンプル|[その１１](https://qiita.com/pooshikin/items/5aedc1a1d214f2f2e345)|20180626|

# 脚注
* 引用はすべてフリーです。この投稿もQitta等の記事を参考にしています。
* TypeScriptの技術は日進月歩どころか、数日で劇的な変化さえありえます。昨日の技術は今日はすでに過去のものになっています。　記事を投稿した時点で使い物にならない場合もあるかもしれません、その場合はご容赦ください。
【c#】1週間分の体重データから最大値を求める例(float配列の最大値を求める)

```c#

﻿﻿using System;

namespace maxweights
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            // 1週間分の体重データから最大値を求める例

            // 1. 配列を初期化
            float[] weights = { 61.2f, 62.5f, 64.9f, 63.2f, 65.1f, 63.2f, 65.1f, 63.2f, 62.7f };

            // 2. 最も重い体重を記憶する変数"max"を用意
            float max = 0.0f;
            // 3. 1週間の体重を順に参照
            for (int i = 0; i < weights.Length; i++)
            {
                // 4. maxの値が現在記録している体重よりも重ければ更新
                if (weights[i] > max)
                {
                    max = weights[i];
                }
            }
            // 5. 出力
            Console.WriteLine("最大値は" + max + "です");
        }
    }
}

```
C#の値と変数

<h4>● 文・値・リテラル</h4>
今回は、C#のもっとも基本的な文法についてまとめて説明をしましょう。今回の内容がざっと頭に入れば、次回から簡単なプログラムを書きながら説明をしていけるようにしたいと考えています。

<h4>● 「文」について</h4>
プログラムのソースコードというのは、「文」でできています。「文」というのは、実行される１まとまりの処理となるものです。プログラムは１つ１つの命令のようなものを実行しながら動いていきますが、この１つ１つが「文」だと考えると良いでしょう。

C#では、文は「セミコロン（；記号）」で区切られます。改行ではありません。文法的におかしくならなければ文の途中で改行しても構いませんし、文の最後にセミコロンが付いているなら複数の文を１行に書いても構いません。


※コメント文について

C#のソースコードでは、プログラムとは関係のない説明などを「コメント」として記述できます。これは、冒頭に//（スラッシュ２つ）をつけるか、あるいはコメントの前後に/*～*/をつけます。//は、それ以降、改行されるまでをコメントとみなします。/* ～ */は、その間に書かれたテキストをコメントとします。こちらは何行書いてあってもOKです。

<h4>● リテラルについて</h4>
ソースコードの中に直接記述される値のことを「リテラル」といいます。主な値のリテラルの書き方は以下のようになります。

・数値
整数――そのまま数字を書くだけです。（例： 123）
実数――小数点をつけると実数と判断されます。（例： 1.23）
16進数――「0x」で始まる英数字（数字＋A～Fの組み合わせ）は16進数と判断されます。（例： 0x1A）
10のn乗――実数の後にEをつけて整数を指定します。（例： 1.23E5）
10進数――内部的に10進数として扱う特殊な数です。このリテラルは、数字の後にMまたはmをつけます。（例： 123m）

・文字／文字列
文字――１文字の値（キャラクタ）は、文字の前後にシングルクオートをつけて記述します。（例： 'A'）
文字列――複数の文字からなる値（テキスト）は、文字列の前後にダブルクォートをつけて記述します。（例： "ABC"）

・真偽値
真か偽か（正しいか、正しくないか）といった二者択一の状態を示すのが真偽値です。これは「true」「false」といった予約語で表します。これはあらかじめ用意されている値なので、"true"のようにテキストとして書いたりしてはいけません。
Rustでイテレート可能なタプル

Rustでイテレート可能なタプルを作ってみた。
これを使えば可変個引数とか出来るかもしれない。

```Rust

//型宣言用 (型1, (型2, (型3, ()))) こんなタプルになる
#[macro_export]
macro_rules! variadic_type {
    { $t:ty } => { ($t,()) };
    { $t:ty,$($u:ty),+ } => { ($t, variadic_type!($($u),+)) };
}

//インスタンス用 (値1, (値2, (値3, ()))) こんなタプルになる
#[macro_export]
macro_rules! variadic {
    { $e:expr } => { ($e,()) };
    { $e:expr,$($f:expr),+ } => { ($e, variadic!($($f),+)) };
}

//◯番目の値を取得
//力技にせざるを得なかった
#[macro_export]
macro_rules! variadic_get {
    { $e:expr,0 } => { &$e.0 };
    { $e:expr,1 } => { &($e.1).0 };
    { $e:expr,2 } => { &(($e.1).1).0 };
    { $e:expr,3 } => { &((($e.1).1).1).0 };
    { $e:expr,4 } => { &(((($e.1).1).1).1).0 };
//たくさん増やしておこう
}

//variadic_getのmutable版
#[macro_export]
macro_rules! variadic_get_mut {
    { $e:expr,0 } => { &mut $e.0 };
    { $e:expr,1 } => { &mut ($e.1).0 };
    { $e:expr,2 } => { &mut (($e.1).1).0 };
    { $e:expr,3 } => { &mut ((($e.1).1).1).0 };
    { $e:expr,4 } => { &mut (((($e.1).1).1).1).0 };
}

//各要素に対して、順次同じメソッドを呼ぶためのimplを定義する
#[macro_export]
macro_rules! variadic_impl {
    { $p:path,$i:ident } => { 
        impl $p for (()) {
            fn $i(&mut self) {
            }
        }
        impl<T,U> $p for (T,U) where T:$p, U:$p {
            fn $i(&mut self) {
                (self.0).$i();
                (self.1).$i();
            }
        }
    }
}
```

使い方はこんな感じ

```Rust
pub trait Update {
    fn update(&mut self);
}

struct Test1 {
    
}
impl Update for Test1 {
    fn update(&mut self) {
        println!("test1");
    }
}
struct Test2 {
    
}
impl Update for Test2 {
    fn update(&mut self) {
        println!("test2");
    }
}
struct Test3 {
    i: i32,
}
impl Update for Test3 {
    fn update(&mut self) {
        println!("test3 {}", self.i);
    }
}

fn main() {

    //型宣言したいならこう（使わなくてもOK）
    type TTT = variadic_type!(Test1,Test2,Test3);

    //インスタンスつくる
    let mut v:TTT = variadic!(Test1{}, Test2{},Test3{i:1});

    //Update::updateが呼べるように準備
    variadic_impl!(Update,update);

    //呼ぶ！
    v.update();

    {
				//中身を変更してみる
        let a = variadic_get_mut!(v, 2);
        a.i = 10;
    }
		
    //呼ぶ！
    v.update();
}
```

実行結果

```
test1
test2
test3 1
test1
test2
test3 10
````

こちらで試せます。
https://play.rust-lang.org/?gist=0e08f1648251d02a016d6d3d4e75185e&version=stable&mode=debug
授業課題　１

##オブジェクト指向とは
・アプリケーションを開発するための手法のひとつです
　関連性の高いデータや処理をオブジェクト（単位）に分けて、それぞれの相互作用によって
　アプリケーション全体の振舞い方を考える。

・疎結合・・・オブジェクトの結びつきが少ない（何かあったときに他への影響　小）
・蜜結合・・・オブジェクトの結びつきが多い（影響　大）
　※疎結合を意識した設計・開発することでオブジェクトの独立性を高めれる

##オブジェクト指向の基本用語
・オブジェクト（object）
　オブジェクトとは「物」、「対象」
　プログラムではデータと処理の集まり意味している。
　現実世界で例えたらスマホ、PCなんかそれに該当するんじゃないかな？
クラス（class）
クラスとはオブジェクトの設計書のようなもので、オブジェクトの中のプロパティやメソッドをひとまとめにしたものだ。

・クラス（class）
　クラスとはオブジェクトの設計書
　オブジェクトの中のプロパティやメソッドをひとまとめにしたもの

・プロパティ（property）
　オブジェクトが持っているデータのことをプロパティ（属性）言う

・メソッド（method）
　メソッド（操作）とは、オブジェクトが持っている処理のことで
　「走る」「曲がる」「止まる」などの、アクションを起こす処理
・インスタンス化
　設計図からオブジェクトを作ることをインスタンス化と呼ぶ

次に続く…
個人用メモ１ - サーバーサイドエンジニア

個人的に調べた内容を自分のメモとして書き残します。

---

〇 サーバーエンジニアに必要な技術的スキル

■ UNIX OS

Windows OS と比較
・ セキュリティが高い
・ 低スペックサーバーでも動作しやすく、処理速度が速い

**扱える人材があまりいないため、需要がそれなりに高い！！！**


■ LAMP

多種多様な作業環境の中のひとつ
ゲーム、Webアプリケーション構築の要となるもの

L … Linux
A … Apache
M … MySQL
P … PHP、Perl、Python

それぞれの頭文字を取って「 LAMP 」と呼ばれる


■ SQL

データベース言語のひとつ
SQL ( Strustured English Query Language )


■ パケット通信についてのしくみ

データを分割（ このひとまとまりをパケットと呼ばれる ）し、送受信することを「 パケット通信 」という
回線の利用効率が良く、幅広く利用されている

サーバーとクライアントのデータのやりとりを円滑に行うため、必要になる知識である


〇 サーバーエンジニアに必要なヒューマンスキル

■ 正確性、柔軟性

**絶対的な正確さ**
臨機応変に対応できる心
常に見守り、何かあればすぐに軌道修正できる心構え


■ 職人気質

一人で作業することがほとんどであるため、
自分の技術や知識を最大限に発揮し、任務を粛々とこなす事が好きな人


〇 サーバーエンジニア向けの資格

**MCP**

「 マイクロソフト認定プロフェッショナル 」の略

ITプロフェッショナルとデベロッパーの技術的な専門知識を検証する資格
知識やスキルのレベルにより、2 階層に区分される

MCSA …… 主要な技術スキルがあることを証明する、ベーシックな資格

MCSE …… 要件に従い、システム設計やアプリケーション設計を行うことが可能な技術スキルがあることを証明する資格
MCSD …… 指示された機能を使用し、システム構築やアプリケーション開発を行うことが可能な技術スキルがあることを証明する資格

MCSE、MCSD を取得していれば、サーバーエンジニアとして大きくアピールできる


**LPIC**

Linux 技術者認定資格のこと
知識やスキルにより、3 段階ある

Lv1 …… Linux の基本操作、システム管理の基本を中心とし、Linux ディストリビューションを利用するために必要な知識を幅広く問う
Lv2 …… Linux の応用的なシステム管理やサーバ構築ができるために必要な知識を問う
Lv3 …… Lv2 を習得していることが条件である、高難度

企業アピールするには、Lv2 は必要である


**Cisco Career Certifications**

シスコ技術者認定プログラムのこと（ ベンダー資格 ）

ネットワーク機器の多くはシスコシステムズが手掛けているため、そこの製品の知識や扱い方を心得ていることは、ネットワーク関連の仕事に就く人には重要なことである
サーバーエンジニアとしても取得しておくべき資格

全部で 5 つのレベルがある

エントリー …… ネットワーク関連のキャリア構築を目指す人向け入門資格
アソシエイト …… 中規模ネットワークの導入や決定、運用に必要なスキルを証明する基礎資格
プロフェッショナル …… シスコ技術者認定の中級レベル
エキスパート …… 世界各国で通用する、業界においての上級のネットワーク認定
アーキテクト …… 最高水準の認定資格

業界内で知名度も高いため、転職に有利になる資格であるだろう


---

最後までお読みいただきありがとうございました。
【C#】1週間分の体重で3日目の体重データを削除してから表示する例

```c#

using System;
// Listを使う際には以下を宣言する
using System.Linq;
using System.Collections.Generic;

namespace weightsRemove
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            // 1週間分の体重で3日目の体重データを削除してから表示する例

            // 1. List型の変数を作る
            List<float> weights = new List<float>();

            // 2. Listに要素を追加する
            weights.Add(61.2f);
            weights.Add(51.2f);
            weights.Add(71.2f);
            weights.Add(54.2f);
            weights.Add(68.2f);
            weights.Add(61.3f);
            weights.Add(68.1f);
            weights.Add(64.3f);
            weights.Add(65.4f);
            // 例：weights[1] = 61.2f

            // 3. Listの先頭から3番目を削除する
            weights.RemoveAt(2);

            // List<T>.Count -> List<T> に格納されている要素の数を取得
            for (int i = 0; i < weights.Count; i++)
            {
                Console.WriteLine(weights[i]);
                // weights.Add(71.2f);が消えている！
            }
        }
    }
}

```
【C#】1週間分の体重データで軽い順にベスト3を表示する例

```c#

using System;
// Listを使う際には以下を宣言する
using System.Linq;
using System.Collections.Generic;

namespace array_sample
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            //Listは簡単に並び替えができる
            //リスト名.Sort();で並び替えができる

            // 1週間分の体重データで軽い順にベスト3を表示する例

            // 1. List型の変数を作る
            //ここでは、リスト名：weights
            List<float> weights = new List<float>();

            // 2. Listに要素を追加する
            weights.Add(61.2f);
            weights.Add(51.2f);
            weights.Add(71.2f);
            weights.Add(54.2f);
            weights.Add(68.2f);
            weights.Add(61.3f);
            weights.Add(68.1f);
            weights.Add(64.3f);
            weights.Add(65.4f);
            // 例：weights[1] = 61.2f

            // 3. 小さい順に並び替える
            weights.Sort();

            // 4. for文で回す
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine(weights[i]);
            }
        }
    }
}


```
XAMPP：session_start(): Session data file is not created by your uid の解決策

# phpMyAdminを起動したんだけどつながらなかった話
表題にもしているが、なぜかセッションファイルにアクセスできなくなってしまう事例が発生し、ローカル環境のphpMyAdminにつながらなくなった。

エラー：　`session_start(): Session data file is not created by your uid`

# 解決方法
### ①php.iniを開く
### ②以下の記述を見つける
<pre>
session.save_path="/Applications/XAMPP/xamppfiles/temp/"
</pre>

### ③指定されているパスを開く
<pre>[terminal]

$ open /Applications/XAMPP/xamppfiles/temp/
</pre>
こうすると、一発で指定パスのディレクトリのfinderが開くんです！

### ④指定パスのディレクトリ内部のファイルを移動or削除
データ飛んだら嫌だな。。。って方はファイルを避難させておく方が吉。

### ⑤一応apacheを再起動しておき、動作を確認する。

これでうまくいきました！
ColdFusionでJSONを整形したい

JavaのJSONObjectというクラスを使います。

```html
<CFSET objJson = createObject("java", "org.json.JSONObject")>
<CFSET str = '{"aaa":"整形テスト","bbb":[1,2,3],"ccc":{"key1":"いか","key2":"たこ","key3":"かに"}}'>
<CFSET objJson.init(str)>
<CFOUTPUT>
<pre>
#objJson.toString(4)#
</pre>
</CFOUTPUT>
```

こんな感じに出力されます。
<pre>
{
    "aaa": "整形テスト",
    "bbb": [
        1,
        2,
        3
    ],
    "ccc": {
        "key1": "いか",
        "key2": "たこ",
        "key3": "かに"
    }
}
</pre>
CをPythonでラップする方法

CをPythonでラップする方法にはいくつかあり，どれを使って良いのかわからないのでまとめてみました．ですが調べただけで実際にやってみたわけではないので，正しいかどうかは保証できません．cppだと他の方法もあるみたいです．

# 方法
- Python/C API
- SWIG
- SIP
- Boost.Python
- ctypes
- cffi
- Cython

# Python/C API
- 長所
    - CPythonのみで完結させることができる
    - よく使われている

- 短所
    - PythonやC，Python/C APIに対する深い理解が必要
    - Cのように書くのでコード量が多くなる

# SWIG
- 長所
    - 自動でラップしてくれる

- 短所
    - 複雑なコードは自動でラップできない

# SIP
- 長所
    - 不明
 
- 短所
    - 日本語の情報がほとんど無い

# Boost.Python
- 長所
    - 自動でラップしてくれる

- 短所
    - c側のコードをいじる必要がある

# ctypes
- 長所
    - 自動でラップしてくれる
    - Pythonの標準の機能である

- 短所
    - 複雑なコードは自動でラップできない

# cffi
- 長所
    - 自動でラップしてくれる

- 短所
    - 複雑になると自動でラップできない
    - 日本語の情報があまりない

# Cython
- 長所
    - 他のラップツールより高速である
    - インタフェイスを改良，単純化しやすい

- 短所
    - 自動でラップしてくれない

# まとめ
Cythonがよさそう
Windows > VMWare Workstation Pro 14.1.2 > ゲストOSが起動しないバグの対処 > 再インストールが必要

```txt:動作環境
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
VMWare Workstation Pro 14.1.2 (以下VMWare)
```

### 症状

VMWareをv14.1.2にアップデートしてから、ゲストOSが起動しなくなった。
下記のリンク先と同じ状態。

https://communities.vmware.com/thread/588996


### 復旧

以下を実施したが、下記の手順3では実質何もしていない。
シリアルを入力することになる。

1. VMWareをアンインストール
    - (Win10の) 設定 > アプリ > アプリと機能 > VMWare Workstation > 変更 > 次へ、削除、から
2. vmx86.sysを停止
    - 参考: [Windows 10 > vmx86を停止する > net stop vmx86](https://qiita.com/7of9/items/3d8c04fe5799a1ea24a9)
3. VMWareのインストールで`/clean`付実行
    - 参考: https://kb.vmware.com/s/article/1308
    - ダイアログ
        - セットアップは強制的にこのマシンからVMWare Workstationインストーラの登録情報を削除します。...
        - [OK]を選択
        - セットアップでVMware Workstationのインストール登録情報が見つかりません。
4. PC再起動
5. VMWareインストール (14.0.0 build-6661328)
6. PC再起動
   - >> ゲストOSの起動を確認した

### 再インストール後にソフトウェア更新 (v14.0.0 -> v14.1.2)

以下でVMWareをv14.0.0からv14.1.2に更新してみた。
シリアルを入力することになる。

1. VMWareにてソフトウェアの更新 (v14.1.2へ)
2. PC再起動
   - >> ゲストOPSの起動を確認した
3. PCシャットダウンし、PC起動
   - >> ゲストOPSの起動を確認した
4. PCシャットダウンし、PC起動
   - >> ゲストOPSの起動を確認した

v14.1.2でゲストOSが起動している状態ではある。

### VMWare Toolsのアップデート

各ゲストOSにてVMWare Toolsのアップデートをする必要があるようだ。

### 問題発生までの履歴 (うろ覚え)

- 14.0.0をインストール
- 14.X.Xにアップデート (Xは覚えてない)
- 14.Y.Yにアップデート (Yは覚えてない)
- 14.1.2にアップデート
    - >> 今回の問題発生
アルファベットが含まれない文字列を判定

Google Homeアプリを作成中のこと。医薬品マスタからクレストール錠5ミリをヒットさせたい。そこで「クレストールの錠剤、5ミリ」とGoogle Homeを話しかけたが、「クレストール錠5ミリ」と「クレストールOD錠5ミリ」の2つがヒットしてしまう。OD錠じゃない方だけを返してもらいたいので、いろいろ調べてみた。

# 最初にやったこと
単に名前が短い方を選ぶようにした。

```python
medicine_names = [u'クレストール錠5ミリ', u'クレストールOD錠5ミリ']
shorter_name = min(medicine_names, key=len)
```

このコードだとなにが流れてきても短いほうが選ばれてしまう。例えば`medicine_names = [u'クレストール錠2.5ミリ', u'クレストール錠5ミリ']`の場合、クレストール錠5ミリがヒットすることになり、アルファベットが含まれない文字列を判定したいという意図を反映しない。

# どうするか？
やることは2つ。文字列の差分をとること。その差分がアルファベットかどうかを判定すること。
## 文字列の差分を取得する
`list(set(list_a) - set(list_b))`とすると、list_aのうちlist_bに含まれないものだけがリストで返ってくる。具体的には・・・

```python
medicine_names = [u'クレストール錠5ミリ', u'クレストールOD錠5ミリ']
medicine_a, medicine_b = [list(m) for m in medicine_names].sort(key=len)
diff = ('').join(list(set(medicine_b) - set(medicine_a)))
```

## アルファベットかどうかを判定する
正規表現に手を出したくなるが、文字列メソッドの`.isalpha()`で一撃。

```python
diff = ('').join(list(set(medicine_b) - set(medicine_a)))
print diff
# u'OD'
diff.isalpha()
# True
```

# おまけ
文字コードや全角半角でTrue/Falseが変わるかを検証。python2.7.10。

```python
a = u'OD' # 半角
b = 'OD' # 半角
a.isalpha() # True
b.isalpha() # True

c = u'ＯＤ' # 全角
d = 'ＯＤ' # 全角
c.isalpha() # True
d.isalpha() # False

e = d.decode('utf-8') # utf-8 -> unicode
e.isalpha() # True

f = e.encode('utf-8') # unicode -> utf-8
f.isalpha() # False
```
半角だと文字コードにかかわらずTrue判定。全角はunicodeのみTrue判定。理屈はわかりませんが、[[修正] Python 文字列の英数字判定でハマった](https://qiita.com/fujiy/items/f738aa9d0bb7427e07a4)のコメントが参考になるかもしれない。

# 参考
[文字列処理メソッドのまとめ](http://motw.mods.jp/Python/str_methods.html#check_format)
[Python で差分リストを取得する](http://xwave.exblog.jp/11309038/)
[[修正] Python 文字列の英数字判定でハマった](https://qiita.com/fujiy/items/f738aa9d0bb7427e07a4)
pythonで3ヶ月前の1日を取得・改

2018-06-17追記: ライブラリは使わないという制約のもと書いてます。

だいぶ前に3ヶ月前の1日を`datetime.datetime(today.year, today.month - 3, 1)`でいいんじゃないか？と[書いた](https://qiita.com/yousuke_yamaguchi/items/8b2738bd5f6d73212e5a)けど、よく考えたら1〜3月が前年に繰り下がらない。どうするか？

# ifつかうか。。。
<pre class="lang:default decode:true">
import datetime

today = datetime.datetime.today()

if today.month < 4:
    year = today.year - 1
    month = today.month - 3 + 12
else:
    year = today.year
    month = today.month - 3

three_month_ago = datetime.datetime(year, month, 1)

</pre>

三項演算子つかえばサラッと書けるか試してみる。
<pre class="lang:default decode:true">
import datetime

today = datetime.datetime.today()

year = today.year - 1 if today.month < 4 else today.year
month = today.month - 9 if today.month < 4 else today.month - 3

three_month_ago = datetime.datetime(year, month, 1)

</pre>

・・・微妙だな。他に、うまいやり方あるのかな？
RaspbianをSDカードに書き込んでHeadless Bootさせよう

最近ラズパイを購入しました。<ー正確には購入してもらいましたww
小さくて可愛いですね(笑)

ラズパイはサーバ用途で使用する予定なので、デスクトップバージョンではないraspbianのliteの方のイメージをSDカードに書き込みました。そして、SSH接続できるように事前設定してからヘッドレスブートさせました。
その手順を紹介しようと思います。

# 環境
- Ubuntu 18.04 LTS (作業するOS）
- raspberry pi 3　(ラズパイ本体)
- raspbian stretch lite (ブートさせるOS)
- micro SDカード

ここでは、Ubuntuに認識されるSDカードのデバイス名は`/dev/sdb`、パーティション名は`/dev/sdbx`(x=1,2,3...)、マウント先は`/mnt/sd`とします。
実際に行うときは適宜自分の環境に合わせてください。

# ブートまでの手順
## イメージのダウンロード
まずは[こちら](https://www.raspberrypi.org/downloads/raspbian/)からイメージのダウンロードをします。
ファイルタイプはZIPとTorrentのに種類ありますが、今回はZIPファイルをダウンロードしました。
ダウンロードが完了したら、解凍します。

```
$ unzip 2018-04-18-raspbian-stretch-lite.zip
```
解凍されたら、拡張子が`img`となっているファイルが出てくると思います。
それがOSのイメージファイルとなります。

## いざ、書き込み！
書き込みを行う際は、SDカードはアンマウントさせておいてください。マウントしたままだと、書き込みが正常にされない場合があります。

```
$ sudo umount /mnt/sd
```

書き込みは`dd`コマンドによって行います。

```
$ sudo dd bs=4M if=2018-04-18-raspbian-stretch.img of=/dev/sdb status=progress conv=fsync
```

`if`はイメージファイルのパスを、`of`には書き込み先となるデバイスのパスを設定します。書き込み先を間違えないようにしてください。少し時間がかかるので、しばらく待ちましょう。
書き込みが完了したら、`lsblk`コマンドでパーティションの確認をしましょう。/dev/sdb下に/dev/sdb1と/dev/sdb2の2つのパーティションが作成されていればOKです。前者はbootパーティションで、後者はrootパーティションとなります。

## SSH接続設定
まずは、SDカードをマウントさせましょう。

```
$ sudo mount -t ext4 /dev/sd1 /mnt/sd/boot
$ sudo mount -t ext4 /dev/sdb2 /mnt/sd/rootfs
```
マウントさせたら、/mnt/sd/bootに***ssh***という名前のファイルを作成します。これだけで、ssh接続が有効化されます。

## IPアドレスの設定
IPアドレスの設定方法は主に３つあります。
他に設定方法があったり、間違っている場合は教えてください。よろしくお願いしますm(_ _)m

### ①DHCPで取得
/mnt/sd/rootfs/etc下に***dhcpcd.conf***ファイルがあるのを確認してください。
デフォルトのままでDHCPによってアドレスを取得しますので、特に編集の必要はありません。

### ②静的アドレスを設定(/etc/dhcpcd.confを編集)
/mnt/sd/rootfs/etc/dhcpcd.confに以下のように書き込みます。

```
interface eth0
static ip_address=192.168.0.1
static routers=192.168.0.254
static domain_name_servers=8.8.8.8 1.1.1.1
```

### ③静的アドレスを設定(/etc/network/interfacesを編集)
ubuntuやdebianに慣れている人は、見慣れている設定方法です。ラズパイの設定方法においては邪道ですが...
/mnt/sd/rootfs/etc/network/interfacesに以下の設定例のように書き込みます。

```
auto eth0
iface eth0 inet static
 address 192.168.0.1
 netmask 24
 gateway 192.168.0.254
```
その後、/mnt/sd/rootfs/etc/systemd/system/dhcpcd.service.d/dhcpcd.service を削除しましょう。これでブート時に余計なデーモンが起動しません。

# Bootさせよう！
SDカードをラズパイのスロットに差し込んで、ブートさせましょう。インターフェースのランプが点灯したら、設定した静的IPアドレス、またはDHCPで取得したアドレスにSSHしてみます。
デフォルトのユーザ名は`pi`、パスワードは`raspberry`です。
接続が成功したら、OKです！！！

以上で、ヘッドレスブートさせてSSH接続できるようになりました。非常に簡単ですので、みなさんも試してみてください。

# 参考文献
- https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
Pythonの辞書のリストを並び替える

リストの並び替えは`sort`や`sorted`でサクッと書けるが、辞書のリストの並び替えをすぐ忘れてしまうのでメモ。lambdaを使うのはわかっているのだが、なかなか記憶に定着しないので書いてみる。
**2021/01/05追記**：
Python3.8.5で動作したことを確認したとともに、`print`の記述をPython3系の書き方に修正しました。

# まずは基本のsortとsorted
## sort()は破壊的。
降順にしたいときは`sort(reverse=True)`。

```python:
nums = [3, 1, 9, 6]

nums.sort()
print(nums) # [1, 3, 6, 9]

nums.sort(reverse=True)
print(nums) # [9, 6, 3, 1]
```
## sorted()は非破壊的。
降順にしたいときは`sorted(hoge_list, reverse=True)`。

```python:
nums_1 = [3, 1, 9, 6]

nums_2 = sorted(nums_1)
print(nums_1) # [3, 1, 9, 6]
print(nums_2) # [1, 3, 6, 9]

nums_3 = sorted(nums_1, reverse=True)
print(nums_3) # [9, 6, 3, 1]
```

# 辞書の並び替えはlambdaを使う
`items()`を使うのでタプルになる。`sort()`は使えない。

## keyで並び替えたいとき

```python:
score = {'kokugo': 33, 'sansuu': 85, 'eigo': 60}

score.sort() # AttributeError: 'dict' object has no attribute 'sort'

score_sorted = sorted(score.items(), key=lambda x:x[0])

print(score_sorted) # [('eigo', 60), ('kokugo', 33), ('sansuu', 85)]
```
## valueで並び替えたいとき

```python:
score = {'kokugo': 33, 'sansuu': 85, 'eigo': 60}

score_sorted = sorted(score.items(), key=lambda x:x[1])

print(score_sorted) # [('kokugo', 33), ('eigo', 60), ('sansuu', 85)]
```

# ここから本題。辞書のリスト
lambdaのreturn部分のindex指定を、ソートしたいkeyにするだけ。

```python:
scores = [
    {'kokugo': 33, 'sansuu': 85},
    {'kokugo': 77, 'sansuu': 23},
    {'kokugo': 55, 'sansuu': 100}
]

scores_sorted = sorted(scores, key=lambda x:x['kokugo'])

print(scores_sorted)
# [
#     {'kokugo': 33, 'sansuu': 85},
#     {'kokugo': 55, 'sansuu': 100},
#     {'kokugo': 77, 'sansuu': 23}
# ]
```

# 参考
[Python Tips：dict（辞書）型の中身をソートしたい](http://www.lifewithpython.com/2013/01/python-sort-dicts.html)
[Pythonのリストを辞書型のvalue値でソートする方法メモ](http://nwpct1.hatenablog.com/entry/python-lambda)
AWS Summit 2018 Tokyo AWS のコンテナ入門 のメモ

基本的に [他のサイト] (https://dev.classmethod.jp/cloud/aws/aws-container-introduction/) のほうが詳しいので、個人的に注目したポイントだけ記載。

## コンテナ全般の利点
- 軽量、分離性、可搬性が高い
- カーネルを持たないためリソース効率が高い

## 設計のポイント
- 「1 タスク = 1 コンテナ」とする
- 複数のホスト上でコンテナを構築するようにしないと実運用では使えない

## Amazon ECS, EKSを支えるマネージド・サービス
- Amazon ECR(コンテナレジストリ)
- AWS Fargate(土台となるインスタンス部分)
CMakeでLaTeXファイルをコンパイルするマクロ

# はじめに
## 背景
 - LatexのコンパイルをCMakeでしたい。
 - UseLATEX.cmakeというのがあるらしいが、うまくいかない。
 - 中身をみても解析する気が起きず、CMakeの勉強がてら自作した。
 - 元々Makefileのスケルトンはあったので、それをCMakeに移植してみた。
 
## 特徴
 - add_executable()と似たような書き方でかける．
 - プログラムと一緒にコンパイル可能
 - out-of-source ビルドが可能
 - bibファイルが入っていれば、bibtexを自動的に実行してくれる
 - 同じ仕組みで他のコンパイルにもつかえる（と思う）
 - 50行程度でかけたので，比較的読みやすい

# 実装
 - https://github.com/tmichi/cmake_latex
  - miLATEX.cmakeにマクロを定義しています。includeしてご利用ください．
  - 予期せぬエラーが起こるかもしれませんので自己責任でご利用ください。
  - pdflatex-> (bibtex) ->pdflatex -> pdflatexの順番に実行しています．


## 文法
```cmake 
add_tex_files ( target_name main.tex sample.bib ... ) 
# 引数は最低２個は必須
# target_name ターゲット名
# main.tex メインのファイル
# 第3引数以降 その他のファイル
```
## CMakeLists.txtの例
```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
set(CMAKE_VERBOSE_MAKEFILE 0) #未定義，or 0の場合は，余分なコンソール出力がなくなる(CMakeの変数）．1にするとLaTexのログも出す．
project(exmaple NONE)
include (miLATEX.cmake) #ファイルのインクルード

set(MI_LATEX_COMMAND  "pdflatex") # latex のコマンドを変えたい場合はこの変数に値を入れる．デフォルトはpdflatex
set(MI_BIBTEX_COMMAND "bibtex") # 上のbibtex版．デフォルトはbibtex
add_subdirectory(sample1)
add_subdirectory(sample2)
```

```cmake:sample1/CMakeLists.txt
add_tex_files (sample1 main.tex) #第1,2引数は必須（ターゲット名とメインのtexファイル)
```

```cmake:sample2/CMakeLists.txt
file(GLOB MI_TEX_IMG_FILES2 images/*) # images/以下の全ファイル
add_tex_files (sample2 main.tex main.bib sub0.tex ${MI_TEX_IMG_FILES2}) #画像，分割したtexファイルなどは後ろに並べておく．
```

## コンパイル
 - 通常のcmakeと同じです。

```bash
$ mkdir build
$ cd build/
$ cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/michi/latex_cmake/build
$ make
(ログ略)
$ ls sample1/main.pdf sample2/main.pdf
sample1/main.pdf        sample2/main.pdf
$
```

# 課題
 - cross-referenceが解消される最小回数コンパイルするようにする。

# 参考にしたページ
## CMakeLists.txtの書き方
 - https://qiita.com/mrk_21/items/5e7ca775b463a4141a58
 - https://qiita.com/koara-local/items/a9b8324551a467d86765
 - https://qiita.com/mrk_21/items/49d8802dc63a2791bcc3
 - https://qiita.com/mrk_21/items/9de14590d6c3a2473284
 - https://stackoverflow.com/questions/35029277/how-to-modify-environment-variables-passed-to-custom-cmake-target/35032051?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa 
 
## LaTeX関連
 - https://qiita.com/termoshtt/items/7f7090f9d0c52bcd2630
Google Apps Scriptのウェブアプリケーションとして公開でハマった

ちょっと備忘録的に。GASをAPIとして使いたくて、公開からウェブアプリケーションとして公開を試していたところ、保存したコードが反映されない。
「現在のウェブアプリケーションのURL」も変わってないし、、、とあーだこーだやっていたら、エンジニアから一言。
プロジェクトバージョンを新規作成してから更新しないとコードが反映しないとのこと。どうやらプロジェクトバージョンを新規作成することがいわゆるデプロイにあたるらしい。
そんなこんなで解決。
Floatでも実質的に整数ならIntegerにする方法

JSONを受け入れるとき、Floatで指定していたら整数で投げても`.0`がついてしまって、Integerで欲しいのにFloatになってしまう。なので、Floatが整数かどうかを判定して、整数ならInt型に、そうでないならFloat型のままにする方法を調べた。

# 汚い方法

Stringにして後ろ2文字が`.0`なら、整数としてみた。

```python
num = 46.0
if str(num)[-2:] == '.0':
    num = int(num)    
```

汚いので、別の方法を検討。

# たぶんまっとうな方法

`a = 10`で`b = 10.0`のとき、`a == int(b)`は`true`になることを利用した。

```python
num = 46.0
if num == int(num):
    num = int(num)
```

なるほど。

# 一行で書こうぜ

```python
num = int(num) if num == int(num) else num
```

# オブジェクトに聞いてみよう
@shiracamus 様、コメントありがとうございます！

```python
num = int(num) if num.is_integer() else num
```

# ちなみに・・・

`a = 10`と`b = 10.0`を比較して、`false`にしたいときは、、、

```python
a == b # true
a is b # false
```