OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby と Perl と Java で解く AtCoder ARC 081 C ハッシュ

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder Problems さん、ありがとうございます。
# 今回のお題
*[AtCoder Regular Contest  C - Make a Rectangle](https://atcoder.jp/contests/arc081/tasks/arc081_a)*
<font color="brown">Difficulty: 538</font>

今回のテーマ、ハッシュ
# Ruby
```ruby.rb
n = gets.to_i
c = gets.split.map(&:to_i)
h = {}
n.times do |i|
  if h[c[i]]
    h[c[i]] += 1
  else
    h[c[i]] = 1
  end
end
s = h.select{|k, v| v >= 4}.keys.sort{|a, b| b<=>a}
t = h.select{|k, v| v >= 2}.keys.sort{|a, b| b<=>a}
ans = 0
ans = s[0] * s[0] if s.size > 0
ans = [ans, t[0] * t[1]].max if t.size > 1
puts ans
```
ハッシュを利用して、出現回数を調べます。
俺環 Ruby (2.7.1) では filter メソッドが使用可能なのですが、AtCoder の旧環境 Ruby (2.3.3) では <font color="orange">**`RE`**</font> になりますので、select メソッドを使用しています。
# Perl
```perl.pl
use v5.18; # strict say state
use warnings;
use List::Util qw(max);

chomp (my $n = <STDIN>);
chomp (my @a = split / /, <STDIN>);
my %h;
$h{$_}++ for @a;
my @s = sort {$b <=> $a} grep {$h{$_} >= 4} keys %h;
my @t = sort {$b <=> $a} grep {$h{$_} >= 2} keys %h;
my $ans = 0;
$ans = $s[0] * $s[0] if @s > 0;
$ans = max($ans, $t[0] * $t[1]) if @t > 1;
say $ans;
```
Perl の常套句を使用しています。

```hash.pl
$h{$_}++ for @a;
```
# Java
```java.java
import java.util.*;
import java.util.stream.Collectors;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.next());
        int a[] = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(sc.next());
        }
        sc.close();
        Map<Integer, Integer> h = new TreeMap<>(Comparator.reverseOrder());
        for (int i = 0; i < n; i++) {
            if (h.containsKey(a[i])) {
                h.put(a[i], h.get(a[i]) + 1);
            } else {
                h.put(a[i], 1);
            }
        }
        List<Integer> s = h.entrySet().stream()
                .filter(x -> x.getValue() >= 4)
                .map(x -> x.getKey())
                .collect(Collectors.toList());
        List<Integer> t = h.entrySet().stream()
                .filter(x -> x.getValue() >= 2)
                .map(x -> x.getKey())
                .collect(Collectors.toList());
        long ans = 0;
        if (s.size() > 0) {
            ans = (long) s.get(0) * s.get(0);
        }
        if (t.size() > 1) {
            ans = Math.max(ans, (long) t.get(0) * t.get(1));
        }
        System.out.println(ans);
    }
}
```
Java のラムダ式を使用しています。
TreeMap はハッシュですが、Comparator.reverseOrder() により Key を自動的に降順に並び替えることができます。
整数のオーバーフロー対策として long に変換する必要があります。

||Ruby|Perl|Java|
|:--:|:--:|:--:|:--:|
|コード長|336 Byte|370 Byte|1199 Byte|
|実行時間|140 ms|135 ms|664 ms|
|メモリ|14988 KB|28196 KB|48532 KB|
# まとめ
+ ARC 081 C を解いた
+ Ruby に詳しくなった
+ Perl に詳しくなった
+ Java に詳しくなった

参照したサイト
*[サンプルコードでわかる！Ruby 2.6の主な新機能と変更点](https://qiita.com/jnchito/items/ce11cb7fccdf4b66af24)*
LAN内で使用されている機器のIPアドレスを簡単に調べる方法

# IPアドレス調査

## はじめに

LAN 内で使われている IP アドレスを調べたいときがありますよね？
[NetEnum](https://forest.watch.impress.co.jp/library/software/netenum/) などのツールを使えばできますが、ダウンロードしなきゃいけないし、サブネットマスク（/16とか）によっては時間がかかったりします。そこで Windows 標準機能だけで簡単に調べる方法がありますので紹介致します。

<img width="300" alt="computer_server_based.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83224/d3accd49-0fb7-3a45-c271-b64dd0200ac6.png">

## ipconfig

まずコマンドプロンプトを開き自身のIPアドレスとサブネットマスクを ipconfig コマンドで確認します。

```
C:\Users\fukuchan-senpai>ipconfig
Windows IP 構成
イーサネット アダプター イーサネット:
   接続固有の DNS サフィックス . . . . .:
   IPv4 アドレス . . . . . . . . . . . .: 192.168.5.67　←　ここです！
   サブネット マスク . . . . . . . . . .: 255.255.255.0　←　ここです！
   デフォルト ゲートウェイ . . . . . . .: 192.168.5.1
```

## ブロードキャストアドレス

IPアドレスとサブネットマスクからブロードキャストアドレスを求めます。
上記の例ですとブロードキャストアドレスは **192.168.5.255** になります。

計算しにくいサブネットマスクの場合は『[サブネットマスク計算](https://note.cman.jp/network/subnetmask.cgi)』などを使ってください。

## ping

調べたブロードキャストアドレスに ping します。

```
C:\Users\fukuchan-senpai>ping 192.168.5.255
192.168.5.255 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。
192.168.5.255 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、
Ctrl+C
　↑
数秒待って Ctrl+C キーを押して止めます。
応答なくてタイムアウトしてても大丈夫です。
```

## arp

arp コマンドで IP アドレスと MAC アドレスの一覧を表示します。

```
C:\Users\fukuchan-senpai>arp -a
インターフェイス: 192.168.5.67--- 0xx
  インターネット アドレス 物理アドレス           種類
  192.168.5.1           xx-xx-xx-xx-xx-xx     動的
  192.168.5.123         xx-xx-xx-xx-xx-xx     動的
  192.168.5.124         xx-xx-xx-xx-xx-xx     動的
  192.168.5.255         ff-ff-ff-ff-ff-ff     静的
```

以上の方法で LAN 内で使用されている IP アドレスを確認することができました。

<img width="200" alt="pose_happy_businessman_guts.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83224/ec1a0cf8-2372-03c7-7c6e-355a53e82d84.png">

ただしブロードキャストが使えない AWS などのクラウド環境では不可となります。
MLIR のメモ(主に Vulkan で推論実行をターゲット)

https://mlir.llvm.org/

## 背景

* Vulkan グラフィックスアプリに, 機械学習を取り込みたい
* Android や, エッジデバイスで Production で機械学習推論をしたい(主に音声認識, image processing, 3D reconstruction)

現状では MLIR 自体はリリースに近いようですが, Vulkan backend は開発中です.

## なぜ MLIR か

* LLVM のプロジェクトに取り込まれ, 活発な開発とメンテがされると想定できる
* IR なので, 高級開発言語(C/C++, Python など)のライブラリ依存性を下げることができる
  * Vulkan(SPIR-V) or CPU 実行の場合, 実行環境をミニマムにできる
    * ビルド時も, OpenCL/CUDA SDK をインストールして... などの問題が減る 
  * 高級言語では指定しづらいものでも, IR レベルでは指定しやすいものがあったりする
    * quantize とか

### SPIR-V ではダメなのか?

SPIR-V の中間言語はいじるのめんどい(SSA ではあるが, スタックマシン的な記述)
テンソルなどの概念が無い.

### 懸念点, 制約事項

* 上位のインターフェースは自前なりで作る必要がある
* モデルデータのロードなども, 別途書く必要がある
  * IREE などは, この辺りも含んでの対応のようですね. 

とはいえ, だいたい production で使いたいときは, 利用したい機能(ドメイン)が確定していると思いますので, 一般化された onnx, torchscript などに振り回されず開発専念 & デバッグできて楽かもしれません.

## MLIR 関連

* IREE : SPIR-V -> Vulkan 実行環境 https://github.com/google/iree
  * まだ出始め. **プロジェクトキャンセルのリスクあり**
* PlaidML : https://github.com/plaidml/plaidml
  * 元々は OpenCL だったと思うが, Stripe -> MLIR -> GPU 実行に移行中?
* TVM
  * 同様の取組として Relay IR を考案している. https://docs.tvm.ai/dev/relay_intro.html
      
### 情報

https://mlir.llvm.org/talks/

まずはこのあたりがよいでしょうか.

https://llvm.org/devmtg/2019-04/slides/Keynote-ShpeismanLattner-MLIR.pdf

### MLIR 開発

バイナリや C API あたり叩いてだと面倒なので, まずは ASCII 形式でいろいろためしてみるのがよいでしょう.

Python で MLIR ascii を読み書きできるライブラリ, pymlir があります.

https://github.com/spcl/pymlir

自前でパーサを用意しているので, LLVM ライブラリに依存しないのがいいですね!
AacondaでPythonをダウングレード（その２）

# 前回までのあらすじ
[前回](https://qiita.com/kmtk49/items/d9860f29acb97a1ef2e4) 、Aanconda上の仮想環境で昔作ったRNN（2号機UbuntuはTf1.14で正常に稼働中。しかも業務で）が1号機のPythonアップデートで動かなくなってしまい、2号機が存命のうちに対策を施したい。
初心者がごちゃごちゃにした環境でツギハギの対策は厳しいと思い、OSから再インストールを考えている。その最後の悪あがき。

# 今回のテーマ
- 現在（2020/4）RNNはどうやらTf2系でいろいろ不具合があるみたい。
- そこでBase環境のPython、Tensorflowをダウングレード
- 
```
$ python -V
python 3.7.6
```
前回でとおった`conda install python=3.6`がとおらず
`conda install python=3.6.6`を実行
無事終了。

```
conda install python=3.6.6
```
そして次の試練

```
ImportError: Something is wrong with the numpy installation. While importing we detected an older version of numpy in ['/home/lcj01/.local/lib/python3.6/site-packages/numpy']. One method of fixing this is to repeatedly uninstall numpy until none is found, then reinstall this version.
```

どうやらNumpyの複数のバージョンが混在した。仮にNumpyを削除しても他のライブラリも同じことになってるかも。。

```
conda uninstall numpy
```
numpy 1.18.1 -> 1.14.5

やはりOSからクリーンナップしよう。。

### numpyの対処法を紹介されているサイト
https://qiita.com/INQUIRER_LAB/items/aa5466c2370b62dd5f64
ベジェ曲線を描いてみる

# はじめに
形状処理の勉強をしていたが、本を読むだけではあまりピンとこなかったのでプログラミングしてみようと思い立ちやってみました。

# ベジェ曲線とは

ベジェ曲線は制御点$P_i$を結んでできる制御ポリゴン内に作られる曲線形状のこと。
制御点とパラメータによってベジェ曲線を構成する1点が定義され、それらを繋ぐと下図のようなベジェ曲線が描ける。
青点が制御点です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536019/5f09b11c-1ff3-456d-dbeb-e96f7bef7555.png)

# ベジェ曲線の計算

今回は2次元空間に描かれるベジェ曲線を対象にしています。
なので、座標値の成分は$(X_i, Y_i)$です。

まず、ベジェ曲線は以下の数式で定義されます。
この数式では、$t$が決まるとベジェ曲線上の点$P(t)$を計算することができます。
0～1の範囲で$t$を変化させて点$P(t)$を計算し、それぞれを繋ぐとベジェ曲線になります。

```math
P(t) = \sum_{i=0}^{N}B_{N,i}(t)Q_i \tag{1}
```
```math
B_{n,i}(t) = \begin{pmatrix}n\\i\end{pmatrix}t^i(1-t)^{n-i}　\tag{2}
```

$t$とか、$N$とか、色々記号が出てきますが、それぞれの意味は以下の通りです。

- $t$
媒介変数とかパラメータと呼ばれます。
とりうる範囲は$0 \leq t \leq 1$です。

- $N$ <br>
次数のことです
例えば次数3だと3次ベジェ曲線が描けます。
次数を上げていくと複雑な形状になっていきます。

- $Q_i$
制御点です。
上図で言うと青点のことです。

- 二項係数
$B_{n,i}(t)$ の右辺で計算される係数部分は二項係数といい、以下の式で計算されます。

```math
\begin{pmatrix} n\\i \end{pmatrix} = {_n\mathrm{C}_k=\frac{n!}{k!(n-k)!} } \tag{3}
```
また、$(2)$はバーンスタイン多項式と呼ばれています。

# プログラム
実装したpythonスクリプトは以下の通りです。

- ベジェ曲線計算部分

```python
# 2項係数計算
def BiCoe(n, k):
    if n < k :
        return -1
    return math.factorial(n) / (math.factorial(k) * math.factorial((n - k)))

# Bernstein多項式
def Bernstein(n, i, t):
    return BiCoe(n, i) * np.power((1-t), (n-i)) * np.power(t, i)

# ベジェ曲線
def BezierCurve(points, t):
    Gt = 0
    n = len(points) - 1
    for k, point in enumerate(points):
        Gt += point * Bernstein(n, k, t)
            
    return Gt
```

- ベジェ曲線描画部分

```python
# ベジェ曲線を描画
def DrawBezierCurve(points):
    x = np.arange(0, 1, 0.01, dtype=np.float32)
    x = np.append(x, 1.0)
    gt = [BezierCurve(points, t) for t in x]
    gt_x = [g[0] for g in gt]
    gt_y = [g[1] for g in gt]
    ct_x = [ct[0] for ct in points]
    ct_y = [ct[1] for ct in points]
    
    plt.plot(ct_x, ct_y, linestyle='dashed', linewidth=1)
    plt.plot(gt_x, gt_y, linewidth = 3)
    plt.scatter(ct_x, ct_y)
```

# おわりに

本読んでいるときは、「この数式で曲線が書けるの～？」なんて愚かなことを思ってましたが、実際に実装してベジェ曲線を描いてみると理論と実装が結びついて理解がより深まったと思います。
数学ヨワヨワな私はちょっとしたことで調べまくり、理解するまでにやたらと時間がかかりました。。。
例えば、$(2)$の式を見て係数部分が二項係数だって知るのに30分くらいかかりました。（爆）
今後も頑張って勉強します。

# 参考文献
- [3次元形状処理入門](https://www.amazon.co.jp/3%E6%AC%A1%E5%85%83%E5%BD%A2%E7%8A%B6%E5%87%A6%E7%90%86%E5%85%A5%E9%96%80%E2%80%953%E6%AC%A1%E5%85%83CG%E3%81%A8CAD%E3%81%B8%E3%81%AE%E5%9F%BA%E7%A4%8E-Information-Computing-%E4%BB%8A%E9%87%8E-%E6%99%83%E5%B8%82/dp/4781910483)
SlackのSlashCommandをAWS LambdaのPythonで実装したときにタイムアウトで困っている場合

こんな風にすればレスポンスを即時で返して2度めの呼び出しで後続処理をできるのでタイムアウトが出づらくなる。
呼び出し回数は倍になるけど。

```python
def lambda_handler(event, context):

    if "hoge" not in event:
        event["hoge"] = "fuga"
        boto3.client("lambda").invoke(
            FunctionName=context.function_name,
            InvocationType="Event",
            Payload=json.dumps(event),
        )

        return {}

    # 以下本当にやりたい処理
```

Pythonのは探しても見つからなかったので書いとく

LambdaからLambda呼ぶアクセス権限は別途設定する必要がある
Slack のダブルクオーテーション変換にハマったお話

## 先に結論
slack でダブルクオーテーションを含む文字列を投稿する時、コードブロックで囲まれてない場合、変なダブルクオーテーションになってしまう

すごく見ずらいですが、下記の１行目のダブルクオーテーション記号はアルファベットのダブルクオーテーション記号ではないことを分かりますか。

コマンドラインに貼り付けてみるとすぐ分かると思います〜

```shell
# コードブロックなしで slack に投稿した内容
COLOR_CLASS=“navbar-dark navbar-gray-dark”

# コードブロックで囲んで slack に投稿した内容
COLOR_CLASS="navbar-dark navbar-gray-dark"
```

## 経緯
- Rails の画面にアクセスしたら、珍しい下記のエラーになりました

  ```
  ActionView::Template::Error (incompatible character encodings: ASCII-8BIT and UTF-8)
  ```

- いろいろ調べたら、 `.env` ファイルに上記変なダブルクオーテーション記号を発見しました
- `.env` ファイル内容は、slack 経由でもらった内容を貼り付けたものなので、スレッドを遡って確認したら、問題ある投稿は、コードブロックで囲んでないことに気づきました
- それより以前の投稿は、コードブロックで囲んでいるので、問題ありませんでした

## まとめ
slack の投稿は、ダブルクオーテーションに対して変換処理があるので、ハマらないためには、コードブロックで囲みましょう
Visio初期設定メモ

# Visio2010用初期設定
インストール直後よくわからなくなるのでメモ
ドキュメント貼り付け用の図を書くための設定

## 開発タブを表示
リボンのユーザー設定を開いてメインタブの開発にチェックを入れる

## グリッドの設定
表示タブを選択
表示グループ右下矢印をクリック
####ルーラーとグリッドの設定
グリッド間隔 両方 固定
最小間隔　両方 1

## 用紙設定
デザインタブを選択
ページ設定グループの右下矢印をクリック
#### プリンターの設定
横
#### ページサイズ
カスタムサイズ
Github Packages に Docker イメージを Push/Pull した時のメモ


[Github Packages](https://github.com/features/packages)に Docker イメージを Push/Pull した時のメモ。

# トークン情報を取得する

`docker login` の時のトークン情報を以下のドキュメントに従い、取得します

[Creating a personal access token for the command line](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line)

厳密な確認をしていませんが、以下の権限を付与

+ write:packages(Upload packages to github package registry)
+  read:packages(Download packages from github package registry)

# Docker イメージの Push/Pull をする

以下の通りやっていきます

[Configuring Docker for use with GitHub Packages](https://help.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-docker-for-use-with-github-packages)

まずは先程の認証情報を利用して `docker login` します。

```bash
$cat ~/TOKEN.txt | docker login docker.pkg.github.com -u USERNAME --password-stdin
```

次に適当に Github のリポジトリを作ります。
今回 **package-test-nginx** というリポジトリを作成。

[toshihirock/package-test-nginx](https://github.com/toshihirock/package-test-nginx)

上記前提で以降の内容を進めます。
検証される際は toshihirock の部分はご自身のオーナー名、package-test-nginx はリポジトリ名に置き換えて実施下さい。

```bash
# 適当に Dockerfile を作る
$vi Dockerfile

# タグを付けてビルド
$docker build -t docker.pkg.github.com/toshihirock/package-test-nginx/nginx .

# Push　する
$ docker push docker.pkg.github.com/toshihirock/package-test-nginx/nginx

```

これで成功です。
同じように Pull してみます。

```bash
$docker pull docker.pkg.github.com/toshihirock/package-test-nginx/nginx
```

Pull も成功しました
docker上でbinding.pryを実行する

# 開発環境
ruby `2.6.3`　　
rails `6.0.2`

# gemのインストール

```:gemflie
group :development do
  gem 'pry-byebug'
end
```

# docker上で動かすためにdocker-composeに下記を追加
* [Docker環境でByebugを使う方法](https://logicoffee.hatenablog.com/entry/2018/06/27/094027)

```
stdin_open: true
tty: true
```

* `この2文を追加でコンテナ内の標準入出力をローカルマシンのターミナルにアタッチする準備が整います。`
* 
```docker-compose.yml
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    /////↓この2文を追加
    stdin_open: true
    tty: true
    ///////////////
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

* `stdin_open`:標準入力への接続を表す。
* `tty`:標準出力の接続を表す。

# pry-byebugの使い方

* 検証したいところに`binding.pry`を書く。

# docker上で動かす

```:ターミナル
# バックグラウンドで動かす
$ docker-compose up -d
```
```:ターミナル
# Railsが動いているコンテナのIDもしくはコンテナ名を調べます.
$ docker ps
```

```:ターミナル
#railsが動いてるコンテナのidをみる
$ docker attach コンテナのIDもしくはコンテナ名_1
```
これで`binding.pry`が記述している場所になるとデバッグモードが起動します。

# デバックモードを終了する
```:ターミナル
exit
```
# Attach したコンテナから抜ける場合(デタッチする)
```:ターミナル
Ctrl+P, Ctrl+Q
```

# より手短にアタッチする

```:ターミナル
docker-compose up -d && docker attach コンテナ名_1
```
Azure Cloud Shellでフォント表示がおかしい場合の対処法

Microsoft Azureを使用する際にブラウザ上でシェルを使用する機能があります。
ただ，自分の環境で最初に起動した際に，フォントの設定がおかしく，綺麗に表示されなかったので，その対処法についてメモします。

[Azure Cloud Shell の概要](https://docs.microsoft.com/ja-jp/azure/cloud-shell/overview)

## 症状
[Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/)でAzureのトレーニングをしようとしていたが，Cloud SHellを使う演習ががあった際に，フォントが明らかに変な表示となってしまう..。
<img width="1435" alt="スクリーンショット 2020-04-16 12.10.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/4498674e-834b-76f5-7cf2-d7d88ad2e40e.png">

## 対処法
ブラウザの**固定幅フォント**設定を変更します。
<img width="911" alt="スクリーンショット 2020-04-16 12.20.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/df099a58-a4ba-0eda-9a76-ca7950163d0e.png">
こちらをプログラミング向けの固定幅フォントへ変更します。

自分は`Ricty Discord`を選択しました。
参考：[プログラミング用フォント Ricty](https://rictyfonts.github.io/)
<img width="853" alt="スクリーンショット 2020-04-16 12.27.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/82b3ff78-b39d-a038-9fb8-423199dc2440.png">
※画面はChromium版のMicrosoft Edgeのものですが，Google Chrome含め他のブラウザでも同様の設定が可能です。

## 結果
文字のズレ等なく綺麗なフォント表示になりました！
<img width="916" alt="スクリーンショット 2020-04-15 23.18.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/809d5871-3f84-f19a-9c5e-892d91158323.png">
シェルスクリプトでYes/Noのpromptを作成する

## Code

```bash:sample
while true; do
    read -p "Do you wish to install this program? (y/n)" yn
    case $yn in
        [Yy]* ) break;;
        [Nn]* ) exit 0;;
        * ) echo "Please answer yes or no.";;
    esac
done

echo 'done'
```

実行権限を付与

```shell-session
$ chmod u+x sample
```

## Usage
### Yes

```shell-session
$ ./sample
Do you wish to install this program? (y/n)y
done
$ ./sample
Do you wish to install this program? (y/n)Y
done
$ ./sample
Do you wish to install this program? (y/n)yes
done
$ ./sample
Do you wish to install this program? (y/n)Yes
done
$ ./sample
Do you wish to install this program? (y/n)YES
done
```

### No

```shell-session
$ ./sample
Do you wish to install this program? (y/n)n
$ ./sample
Do you wish to install this program? (y/n)N
$ ./sample
Do you wish to install this program? (y/n)no
$ ./sample
Do you wish to install this program? (y/n)No
$ ./sample
Do you wish to install this program? (y/n)NO
```

### その他

```shell-session
$ ./sample
Do you wish to install this program? (y/n)x
Please answer yes or no.
Do you wish to install this program? (y/n)
Please answer yes or no.
Do you wish to install this program? (y/n)y
done
```
「みずほ銀行システム統合、苦闘の19年史」を読んだ 

## はじめに
IT界のサグラダファミリアとして有名なみずほのシステムについて書かれた本です。
基幹系刷新案件が増えてきているので、身を守るために読んでみました。
技術的には浅い話ですが、PJの成功・失敗事例としては教科書に載せるネタかと思いますので興味がある方は読んでみると良いです。

## お題
- ポイント
- 開発手法の考察
- 障害の考察(2011)
- 障害の考察(1999)
- まとめ
- 過去のPJ経験から補足

## 概要
- 1980年代から使用されている勘定システムの老朽化
- 法改正やサービス追加でブラックボックス化
- 経営体制ネックでシステム開発に投資できていない
- 勘定系のメイン業務であるリテール業務（預金）は利益が下がり投資意欲が低い
- 2度の規模システム障害とPJ延伸を経て完成
- 4000億を超える投資、35万人月の動員、参加ベンダー、スカイツリー７本分の費用
- ファイルベースのバッチおばけをオンライン化
- SOAで面作り直した
- シナリオ制御系でメインフレームとCOBOLが残ってるが大半はオープン化

## 開発手法の考察
- As Isの要件定義を全面禁止
- ユーザ部門に 業務フローやデータモデルを考えさせる（Xupper使用）
- 用語の統一（ユビキタス言語）
- コードの自動生成により属人性を排除（超高速開発ツール）
- 主要４ベンダーとNDA締結しアーキテクチャや実装方針を検討
- 開発１６社でトップマネジメント定例
- 仕様変更・改善要望などは１件ずつコスト・期間・インパクトを判断して可否を決定
- 横断PTを作り事業部同士が対立した場合は横断PTが軍配を持った
- 横断PTの傘下にテスト部会を配置してテスト計画を作成
- 四重のリスクチェック
	- 第1線  ステム開発エンジニア
	- 第1.5線　プログラムの品質チェック
	- 第2線　システムリスク管理室　システム視点
	- 第3線　業務監査部  業務視点
- プレユーザ受け入れテストの工程を追加、テスト工数が見積もりより肥大化
- システム移行の期間は１年間、ATM停止９回、移行は３連休を使用

## 障害の考察(2011)
- 三十の不手際
	- システムの仕様や設定
	- システム運用
	- リスク管理
	- 緊急体制
- 根本原因・・・経営陣のIT軽視、IT理解不足

## 障害の考察(1999)
- 根本原因・・・現場任せが諸悪の根源。CIO不在。３行がバラバラに対応
- ベンダーの覇権争い。できるはずのない工数を提示。

## まとめ
- 他人事ではない。2025年の崖が待っている。
	- 2025には20年以上稼働し続けている基幹系システムの比率が6割
	- システムの老朽化によるリスクに伴う経済損失12兆
- 困難を乗り越えた結果人が育った
- ステークホルダーを集めて横断チームを作ることが必要
- 利害の対立があるなかで経営層がリーダーシップを発揮して横断チームに決定権を委譲しないと破綻する
- 要件定義で「As IsはNG」ユーザ部門に業務フローやデータフローを作らせる
- 移行や検証に莫大な工数がかかる。
- 一括処理は高リスク。オンライン化推奨
- サービス化して疎結合にしよう

## 過去の経験から補足
- 業務フローをエンジニアに任せてはいけない
	- フロー作成の主体・責任はユーザ部門
	- ユーザ部門も自らの業務フローを理解していないので絶対完成しない
	- テストの工程でイレギュラーなケースが露呈する
- 業務の仕組みを根本的に見直すビジネス・プロセス・リエンジニアリングが目的にないといけない
- 要件も見えないのに○○人月でやれますとか時代錯誤な提案をしてはいけない
- 莫大な工数がかかることを自覚し、ビジネス面でどうペイするのか経営判断が必要
- 検証や移行の工程が逼迫するとリリース後爆発してコストや期間が余計にかかる
- 会議のための会議、報告のための報告は無駄
- 進捗会議は無駄。リカバリ案とか無駄。遅延している場合課題が発生しているのでステークホルダーが集まって課題を解消していく方に注力したほうがいい。進捗は健康チェックに使う
Tomcat 无文件回显执行命令

## 前言
先知最近出了一批关于tomcat回显的文章，仔细研究了一下，发现可以用来实现“无文件webshell”以及“反序列化执行命令拿到回显”，本文是总结、搬砖。

各位师傅的文章画一下时间线：
1. [《基于内存 Webshell 的无文件攻击技术研究》](https://www.anquanke.com/post/id/198886) 主要应用于Spring
2. [《linux下java反序列化通杀回显方法的低配版实现》](https://xz.aliyun.com/t/7307) 将回显结果写入文件操作符
3. [《Tomcat中一种半通用回显方法》](https://xz.aliyun.com/t/7348) 将执行命令的结果存入tomcat的response返回 shiro无法回显
4. [《基于tomcat的内存 Webshell 无文件攻击技术》](https://xz.aliyun.com/t/7388) 动态注册filter实现回显 shiro无法回显
5. [《基于全局储存的新思路 | Tomcat的一种通用回显方法研究》](https://mp.weixin.qq.com/s?__biz=MzIwNDA2NDk5OQ==&mid=2651374294&idx=3&sn=82d050ca7268bdb7bcf7ff7ff293d7b3) 通过Thread.currentThread.getContextClassLoader() 拿到request、response回显 tomcat7中获取不到StandardContext
6. [《tomcat不出网回显连续剧第六集》](https://xz.aliyun.com/t/7535) 直接从Register拿到process对应的req


```java
Registry.getRegistry(null,null).getMBeanServer().mbsInterceptor.repository.domainTb.get("Catalina").get("name=\"http-nio-8080\",type=GlobalRequestProcessor").object.resource.processors.get(0).req;
```
tomcat版本不同，会有nio bio的区别，建议都遍历。
ブラウザ上で動くSchemeインタプリタ

# ブラウザ上で動くSchemeインタプリタ
ブラウザ上で動くSchemeインタプリタを開発した。
https://flamboyant-johnson-39e0b8.netlify.app/

## Scheme
SchemeとはLispと呼ばれるプログラミング言語のある方言です。プログラミング言語の中で最も文法が簡単な言語で、有名なプログラミング言語の教科書「計算機プログラムの構造と解釈」(Structure and Interpretation of Computer Programs)で教材として使われている、プログラミング言語である。

## 計算機プログラムの構造と解釈(Structure and Interpretation of Computer Programs)
MITでプログラミングについて何も知らない新入生向けに書かれたプログラミングの教科書である。
古典的名著として有名で、米国の新聞、ボストングローブ紙のMITの創立150周年記念企画にて作成されたMITでの最も重要な発明リストにもこのSICPは選ばれている。


http://archive.boston.com/news/education/higher/specials/mit150/mitlist/?page=20

> Number 127: Big important book
> Harold Abelson and Gerald Jay Sussman, a pair of MIT computer science professors, wrote “Structure and Interpretation of Computer Programs,” which remains a classic for encouraging the teaching of not one specific programming language, but big-picture themes students could apply across a range of programming scenarios.


> MITの計算機科学の二人の教授、Harold AbelsonとGerald Jay Sussmanは"SICP"を出版しました。
これは1つの特定のプログラミング言語を教えるのではなく、学生が様々なプログラミングの
計画に応用できる全体像を教えることを促す古典としてあり続けています。

英語版は無料で公開されているし、日本語訳も出版されているが、訳がわかりづらいのが難点であった。
しかし、真鍋宏史氏がわかりやすい日本語訳を作成してくれた上に、無料で公開してくださったので、誰でも読むことができる。

http://vocrf.net/docs_ja/jsicp.pdf


## 最後に
この本と開発したSchemeインタプリタがあれ誰でも無料でプログラミングの基礎知識を学ぶことができる。





## 謝辞
SICPのわかりやすい日本語訳を作成してくださった真鍋宏史氏には、厚く御礼を申し上げ、心より感謝致します。
ローカルリポジトリがコミットされるまで【Git初心者向け】

# はじめに
ローカルリポジトリがコミットされる際にたたいているコマンドがそれぞれ何を意味しているのか、よく分からずに使っている部分があったので、復習も兼ねて記事を書きました。

# ローカルリポジトリがコミットされるまで
ローカルリポジトリをコミットし、ファイルを保存するためには

- ワークツリー
- ステージングエリア
- Gitディレクトリ

と呼ばれる３つの場所を経由する必要があります。
これらは全てローカルリポジトリ内に存在しています！

<img width="640" alt="隠しファイル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602172/a53df8c6-54c3-3817-699b-bf745d965c82.png">

フォルダをGitの管理対象にするとフォルダ内に「.git」という隠しフォルダが作られます。（画像の黄色枠部分）
この中に、上の３つの場所が含まれています。
なのでファイルの変更からコミットに至るまでの流れは、全てGitの管理対象としたフォルダ内で行われていることになります。

それぞれの場所がどのように機能しているか、おおまかに説明するとこんな感じ
![ローカルリポジトリ漫画.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602172/c7a8f3fb-2902-86e6-b12f-5e9fa66c104a.png)

# 「ワークツリー」には変更したファイルがある
Gitのコミットにおいて、スタート地点になるのが「ワークツリー」です。
ここで編集したファイルを含むフォルダが、Gitのコミット対象になります。

# 「ステージングエリア」でコミットを記録
基本的に一度コミットされたファイルは変更や削除ができません。
あとからコミットを取り消したい！と思ってもその前後の状態が記録されるので、コミット自体がなかったことにはならないのです。

そのためコミットの扱いには気をつけなければいけません。
例えば間違ってファイル内の個人情報に関わる部分もコミットしてしまったらどうしますか？
そのまま公開してしまえば、全世界に個人情報をみられてしまう危険性があります。
なのでコミットする前に一度、コミット対象のファイルを確認できる必要があります！

そのための保険として機能するのが、２つめの「ステージングエリア」です。
ワークツリーで変更したファイルをコミットするには、一旦このステージングエリアに変更内容を登録します。

登録した内容は確認することができ、「このファイルはコミットしたいけど、逆にこれはしたくない」というような操作も可能です。

# 「Gitディレクトリ」でコミットを保管する
ステージングエリアに追加されたファイルがコミットされると、「Gitディレクトリ」に送られます。
ここまでが一連のコミットの流れです。
ちなみに先ほども言いましたが、Gitディレクトリに一旦コミットが入ると変更ができません。
npm install でエラー。gyp: No Xcode or CLT version detected!　

#npmを使ってみる
今回初めて、Node.jsを使うためにセットアップ！
と思っていたのですが、いきなりエラー続きで意味も分からず苦戦していたので共有します。
皆様が同じ目に合いませんように。

```
$ cd work/01-webpack 
```
まずは、フォルダを作成

```
$ npm init -y
```
そして、package.jsonファイルを作成を作成しました。
ここまでは、良かったのですが。。。
アプリケーションで使用するモジュールをインストールするために、webpackをインストールする時に

```
$ npm install webpack webpack-cli --save-dev
```
を行ったあと、エラーが。

```
No receipt for 'com.apple.pkg.CLTools_Executables' found at '/'.

No receipt for 'com.apple.pkg.DeveloperToolsCLILeo' found at '/'.

No receipt for 'com.apple.pkg.DeveloperToolsCLI' found at '/'.

gyp: No Xcode or CLT version detected!　←「ココ」
gyp ERR! configure error 
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/Users/mac/.nodebrew/node/v12.16.2/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:351:16)
gyp ERR! stack     at ChildProcess.emit (events.js:310:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Darwin 19.3.0
gyp ERR! command "/Users/mac/.nodebrew/node/v12.16.2/bin/node" "/Users/mac/.nodebrew/node/v12.16.2/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/mac/Desktop/work/01-webpack/node_modules/fsevents
gyp ERR! node -v v12.16.2
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok 
```

そして気になった場所はココですね。

```
gyp: No Xcode or CLT version detected!
```
XcodeとCLTのバージョンがおかしい？

Xcodeは以前にインストールしていたので確認してみました。
すると、久しくみていなかったので、アップデートしていませんでした。
それが、原因かもと思いアップデート！！
そしてもう一度```$ npm install webpack webpack-cli --save-dev```

しかし、エラーは変わらず。。

※インストールしていない方はこれで

```
$ xcode-select --install
```

#解決策
https://github.com/nodejs/node-gyp/blob/master/macOS_Catalina.md#i-did-all-that-and-the-acid-test-still-does-not-pass--
上記のGitHubを参考に進めました（I did all that and the acid test still does not pass :-以下）

```
$ sudo rm -rf $(xcode-select -print-path)
$ sudo rm -rf /Library/Developer/CommandLineTools
$ xcode-select --install
```

コマンドの説明をすると、

```sudo rm -rf /Library/Developer/CommandLineTools```：Xcode Command Line Toolsのあるディレクトリを削除することでアンインストールしています

```xcode-select --install```:コマンド上でXcode Command Line Toolsを再インストール。


この後もう一度

```
$ npm install あなたのインストールしたいもの
```
を行う。

無事エラーは出ず、進めることができました！

#参考記事
https://qiita.com/dmrt/items/90ad12850c0ed29758a2

https://github.com/nodejs/node-gyp/blob/master/macOS_Catalina.md#i-did-all-that-and-the-acid-test-still-does-not-pass--
CircleCIでCannot find module '@babel/compat-data/corejs3-shipped-proposals'

yarn.lockを全く修正していないのに、2020/04/16にwebpackでbuildしたら以下のエラーが発生した

```
ERROR in ./src/javascript/something.ts
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/compat-data/corejs3-shipped-proposals'
Require stack:
- /home/circleci/project/node_modules/@babel/preset-env/lib/polyfills/corejs3/usage-plugin.js
- /home/circleci/project/node_modules/@babel/preset-env/lib/index.js
- /home/circleci/project/node_modules/@babel/core/lib/config/files/plugins.js
- /home/circleci/project/node_modules/@babel/core/lib/config/files/index.js
- /home/circleci/project/node_modules/@babel/core/lib/index.js
- /home/circleci/project/node_modules/babel-loader/lib/index.js
- /home/circleci/project/node_modules/loader-runner/lib/loadLoader.js
- /home/circleci/project/node_modules/loader-runner/lib/LoaderRunner.js
- /home/circleci/project/node_modules/webpack/lib/NormalModule.js
- /home/circleci/project/node_modules/webpack/lib/NormalModuleFactory.js
- /home/circleci/project/node_modules/webpack/lib/Compiler.js
```

原因は不明だが、package.jsonを7.9.0に固定したらうまく動いた

```json
"@babel/preset-env": "=7.9.0"
```

### 参考
- https://stackoverflow.com/questions/61238650/i-am-having-an-issue-with-babel-building-angular-app-for-production
ステータスコードを正しく使う

#はじめに
サイトを開発する上で「200・401・404」などのステータスコードは頻繁に遭遇すると思います。

新人の頃はステータスコードの重要性について無知でして、200でも201でもどっちでもいいじゃないか！！って思っていました。

しかし、ステータスコードはクライアントが仕様について詳しくなくても適切なコードを返すことで、おおよその問題を把握できることに役立ちますので疎かにしてはいけません。

今回は私自身ステータスコードを丸覚えしているわけではなく、実装中に調査する工数が発生していることを踏まえ備忘録として整理します。

#200番台は成功
200番台はリクエストが成功したことを示します。

200 リクエスト成功
201 リクエストが成功し、新規リソースが作成
202 リクエスト成功
204 コンテンツなし

ステータスコード200番台はデータの取得に成功した場合やリクエスト処理が成功した場合に表示します。

##ステータスコード200番台の詳細について
200と202はどちらのリクエスト成功した場合のステータスコードですが両者の違いはCreateかAcceptかです。

200(Create)は言葉の通りリクエストの処理が成功した場合ですが、202(Accept)はリクエスト処理が非同期で行われ、処理は受け付けたけど完了していない場合に表示されます。

201は新規投稿が完了した場合に表示します。
例えばコメント投稿画面でコメントが作成された場合などに表示されます。

204は処理は成功したが、レスポンスが空の場合に使用します。
例えば、削除リクエストに成功した場合です。

#400番台はクライアントのリクエストに問題あり
400番台はクライアントに起因するエラーを示します。

400 リクエストが正しくない
401 認証が必要
403 アクセスが禁止されている
404 指定したリソースが見つからない
405 指定したメソッドを使うことができない
406 Accept関連のヘッダに受理できない内容が含まれる
408 リクエストが時間内に完了しなかった
409 リソースが矛盾した
410 指定したリソースは消滅した
413 リクエストボディが大きすぎる
414 リクエストされたURIが長すぎる
415 サポートしていないメディアタイプが指定された
429 リクエスト回数が多すぎる

ステータスコード４００番代は種類が多いですね。
経験の浅い私ですが400番台の全てをみたわけではありません。笑

ですので、よく見るな〜てステータスコードだけ書いていきたいと思います。

##ステータスコード400番台の詳細について

400はリクエストされてきたパラメーターに間違いがある場合に表示します。

401は言葉の通り認証が通っていないときに表示します。

403は特定のユーザーに対して、ある操作の権限を禁止することです。
例えば、ID：1のユーザーがID：2のユーザーのデータ取得を禁止するなどです。

404は最もポピュラーなエラーですよね。パソコンに触れた人は必ずみたことあるはずです。

405はメソッドのエラーです。データを取得(get)したいのに、postを指定している場合です。

409はコンフリクトエラーです。例えば、一意のIDを持つデータを作成するときにIDが重複すれば作成できないとエラーになります。

上記に書いていないステータスコードは見た記憶がありませんので割愛します。笑


今回は以上になります。
Ubuntu２号機の稼働状況（俺の）

いつもながら備忘録ですみません。
# Base環境
- GTX1070
- phython 3.7.3
- tensorflow なし
- `nvidia-smi　nvcc -V`がとおらない。要確認


# 仮想環境
- python 3.7.4
- tensorflow 1.14.0

```
(TRF) lcj02@lcj02:~$ pip list
Package               Version  
--------------------- ---------
absl-py               0.7.1    
astor                 0.8.0    
attrs                 19.1.0   
backcall              0.1.0    
bleach                3.1.0    
certifi               2019.6.16
cycler                0.10.0   
decorator             4.4.0    
defusedxml            0.6.0    
entrypoints           0.3      
gast                  0.2.2    
google-pasta          0.1.7    
grpcio                1.16.1   
h5py                  2.9.0    
ipykernel             5.1.2    
ipython               7.7.0    
ipython-genutils      0.2.0    
jedi                  0.15.1   
Jinja2                2.10.1   
jsonschema            3.0.2    
jupyter-client        5.3.1    
jupyter-core          4.5.0    
jupyterthemes         0.20.0   
Keras                 2.2.4    
Keras-Applications    1.0.8    
Keras-Preprocessing   1.1.0    
keras-rectified-adam  0.17.0   
kiwisolver            1.1.0    
lesscpy               0.13.0   
Markdown              3.1.1    
MarkupSafe            1.1.1    
matplotlib            3.1.1    
mistune               0.8.4    
mkl-fft               1.0.12   
mkl-random            1.0.2    
mkl-service           2.0.2    
nbconvert             5.6.0    
nbformat              4.4.0    
notebook              6.0.0    
numpy                 1.17.0   
opencv-contrib-python 4.1.0.25 
opencv-python         4.1.0.25 
pandocfilters         1.4.2    
parso                 0.5.1    
pdf2image             1.6.0    
pexpect               4.7.0    
pickleshare           0.7.5    
Pillow                6.1.0    
pip                   20.0.2   
ply                   3.11     
prometheus-client     0.7.1    
prompt-toolkit        2.0.9    
protobuf              3.8.0    
ptyprocess            0.6.0    
Pygments              2.4.2    
pyocr                 0.7.2    
pyparsing             2.4.2    
pyrsistent            0.15.4   
python-dateutil       2.8.0    
PyYAML                5.1.1    
pyzmq                 18.1.0   
scipy                 1.3.0    
Send2Trash            1.5.0    
setuptools            41.0.1   
six                   1.12.0   
tensorboard           1.14.0   
tensorflow            1.14.0   
tensorflow-estimator  1.14.0   
termcolor             1.1.0    
terminado             0.8.2    
testpath              0.4.2    
tornado               6.0.3    
traitlets             4.3.2    
wcwidth               0.1.7    
webencodings          0.5.1    
Werkzeug              0.15.4   
wheel                 0.33.4   
wrapt                 1.11.2   

```
Gitとは？〜コミットまでを説明してみた【Git初心者用】

# はじめに
プログラミングの学習を進めるにあたり、分からないことはたくさんあったがそのうちのひとつが「Git」でした。
復習も兼ねて、初めてGitの概念を知る人がわかりやすく理解できるように、イラストを交えて記事を作成しました。
理解の補助になれば幸いです。

# まずGitとは？
Gitとは「ソースコードをバージョン管理するためのツール」です。
なんじゃそれ？って思いますよねw

具体例で説明してみます。

例えば仕事であるお店のHPを作ることになったとします。
クライアントといろいろ調整しながら進めていく過程で、ソースコードもどんどん更新されていきます。
こうした変化していくファイルの状態のことを<font color="red">「バージョン」</font>といいます。
後から「間違ったから一回データを戻したい！」って思ったときのために、ファイルの変更履歴は残しておきたいですよね？
こういう時に「ファイル名を変えてコピーしバックアップをとる」という方法があります。
似たような方法を試したことがある人も多いのではないでしょうか？
イメージとしてはこんな感じ
![個別で保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602172/f73a2fd0-106b-9c36-46a5-b7edb7130957.png)

確かにこうすれば過去のデータを残しておくことはできるのですが、

- 統一的な管理が難しい
- １回１回のバックアップに手間がかかる

などの問題があります。
またこの方法では【完成版】と【最終版】があり、<font color="red">結局どれが最新データなのか分からない</font>のも困りますよね。

Gitという概念が出てくるまではこのような方法でしかバージョン管理はできませんでしたが、Gitの登場によっていちいちファイルを別で保存する必要がなくなりました。（スゴいね！）
Gitは、いつでも記録したバージョンに戻ってデータを参照することができます。

![Gitを使うと-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602172/f6fb3656-8416-63a6-d358-9c9bb7608309.png)

# Gitを使えば複数人で同一ファイルの共有ができる
バージョン管理が確実にできるということは、ファイルの最新状態や変更履歴の把握が容易になるということです。
そのため複数人で１つのファイルを共有し、共同でプロジェクトに取り組むことが可能になります。

これがおおまかなGitの概念です。

<font color="red">GitHubというのは、こうしたGitの仕組みを利用したwebサービスのこと</font>です。

# コミット＝バージョンのこと
Gitについて調べていると<font color="red">「コミット」</font>という言葉がよく出てきます。
上でバージョンという言葉について説明しましたが、コミットとはまさにこのバージョンのことを指します。

ソースコードは自動的に保存されていくわけではないので、それぞれのユーザーがそれぞれのタイミングで保存していかなくてはなりません。
その保存操作によって作られたバージョンのことを「コミット」といいます。

このコミットのおかげで、いつでも過去の状態に戻したりコミット間を行き来したりすることができるようになります！
ゲームでいう「セーブ機能」のようなものですね。

ここで記録されるのはファイルの状態だけではなく

- いつ変更されたか？（when）
- 誰が変更したか？（who）
- どんな変更だったか？（How）

などの情報についても記録されます。

なのでいちいち「AとBをこのように変更しました！」と口頭で説明しなくても、コミットを見れば詳しい変更内容が分かるようになるということです。

![コミットとは？.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602172/bbe55301-046e-29a2-b4bf-c5d008377bb9.png)
【Swift】Firebase Cloud Messaging(FCM)で画像付きのプッシュ通知を受信

一応公式の説明はこちらですが、
https://firebase.google.com/docs/cloud-messaging/ios/send-image?hl=ja
イマイチ分かりにくいです。

以下の通り設定し、普通のプッシュ通知は受信できる前提です。
https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ja

## Notification Service ExtensionのTargetを追加する

Xcode -> File -> New -> Target... -> Notification Service Extension

Product Nameは適宜決めてください。
今回はLanguageはSwiftに設定します。

Finishで作成。

## NotificationService.swiftの編集

上記の操作で作成されたNotificationService.swiftを編集します。
Firebaseをインポートして、
サンプルで入っていたコードを消して、
didReceiveのcontentHandlerをFirebaseへ引き渡してください。
以下のようになればOKです。

```swift:NotificationService.swift
import UserNotifications
import Firebase

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent = bestAttemptContent {
            Messaging.serviceExtension().populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}
```


## CocoaPodsの設定

以下を追記

```ruby:Podfile
...
target *ProductName* do
    pod 'Firebase'
    pod 'Firebase/Messaging'
end
...
```

編集完了後`pod install`してください。

## Provisioningの設定

Apple Developer -> Certificates, Identifiers & Profiles -> Identifiers -> + -> App IDs

Bundle IDは元のアプリのBundle IDに先程のProductNameをドットでつなげたもの
Push Notificationsにチェック

Xcodeで作成したプロビジョニングをインポートしてください。

## テスト

Firebaseの管理画面でこちらに画像のURLを入力してください。

<img width="463" alt="スクリーンショット 2020-04-16 11.41.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532546/ebcaf405-0887-b7c7-7793-d0730b818d49.png">
Amazon Chimeでオンラインカンファレンスを開催するときの手順 (主催者編)

Amazon Chimeでオンラインカンファレンスを開催するときの手順メモです。

- Amazon Chime: https://aws.amazon.com/jp/chime/
- Amazon Chimeの料金: https://aws.amazon.com/jp/chime/pricing/

参考: Amazon Chimeで開催されるオンラインカンファレンスに参加するときの手順 (参加者編): https://qiita.com/tcsh/items/5ae3203f6b1e40c2ca72




# 事前準備

カンファレンスを主催するには、amazon.comのアカウントが必要です。(ChimeのPro機能を利用)

1. amazon.comのアカウントを用意する。(以下のいずれか)
  - amazon.comのアカウントを新規に作成する。
  - AWSアカウントを作成したときに自動的に作成されるamazon.comのアカウントを利用する。(無料期間終了後も継続利用するならこちら)
2. developper potal 登録 (不要かも)
  - https://developer.amazon.com/ja/apps-and-games/login-with-amazon
  - 1のamazon.comアカウントで登録する。
  - amazon.comアカウントの登録メールアドレスに'新しいAmazonアカウントを確認します'というタイトルのメールが認証コード(6桁の数字)届く。
  - ブラウザ画面上で認証コードを入力するとdevelopper potalのダッシュボードが表示される。(この画面は、以下の手順では使いません。)
3. Amazon Chimeアプリをインストールする。(ウェブアプリケーションを利用してもOK)
  - https://aws.amazon.com/jp/chime/download-chime/
4. Amazon Chimeアプリを起動する。
  - amazon.comアカウントでログインする。(メール承認待ち画面になる)
5. amazon.comアカウントの登録メールアドレスに' [Action Required] Verify your email address'というタイトルのメールが届くので、リンクをクリックする。
6. 4の画面がChimeホーム画面に切り替わる。


# カンファレンスの開催 (Webアプリの場合)

## 1. ログイン

1. https://app.chime.aws/ にアクセスする。
    * "Email address used for calendar meetings"にAmazon.comの登録アドレスを入力する。
    * "SingIn/SingUP"をクリックする。
2. "Login with Amazon"ボタンが表示される。
    * "Login with Amazon"ボタンをクリックする。
3. "Sign-In"画面が表示される。
    * "Email (phone for mobile accounts)"にAmazon.comの登録アドレスを入力する。
    * "Password"にAmazon.comの登録アドレスのパスワードを入力する。
    * "Sign-In"ボタンをクリックする。
4. Amazon Chimeのホームページが表示される。

## 2. ミーティングの作成

instance meetingの場合、Dial-Inでの接続を拒否できないため、不測の費用が発生する可能性があります。(自分は$70請求されました。)
Scheduled meetingを利用することをおすすめします。

``更新予定です。
1. "Quick actions"の"Start an instant meeting"をクリックする。
  * Meeting画面が開く
```

2. Meeting画面の"More"メニューから"Enable event mode"を選択する。
  * "Enable event mode"ポップアップが開くので、"Enable event mode"ボタンをクリックする。(参加者のマイクがデフォルトでミュートになります。) 
```

## 3. ミーティングの告知

* Meeting画面のURLを参加者に通知する。
  * MeetingのURLを知っていれば誰でも参加できるので取り扱いに注意が必要です。

Meetingの通知方法には、URL(Meeting IDが含まれている)での伝達と、Meeting IDの通知の2つの方法が取れますが、URLで伝えると参加者は自分のチャットネームを入力するだけで参加できるので若干操作が減るのでわかりやすい&楽です。


# カンファレンスの開催 (MacOSアプリの場合)

1. Amazon Chimeアプリを起動する。
2. "Quick actions"の"Start an instant meeting"をクリックする。
  - Meeting画面が開く
3. Meeting画面左上のMeeting IDを参加者に伝える。
  - Meeting IDを知っていれば誰でも参加できるので取り扱い注意


# 無料期間経過後の利用

無料期間(最大30日)を過ぎた後に継続利用する場合は、AWSマネジメントコンソールやCLI/SDKを利用してChimeアカウント(チーム)を作成して、主催者となるChimeユーザ(課金単位)をChimeアカウントに登録する必要があるようです。
(ChimeユーザがChimeチームからの招待を承認した時点で、無料枠は終了します。)

* Amazon Chime管理者ガイド 開始方法: https://docs.aws.amazon.com/ja_jp/chime/latest/ag/getting-started.html

# 参考

* AWSJ沼口さんのnote
  * Amazon Chimeを使う（開催者編）: https://note.com/s_numaguchi/n/n4dd460fc0bb9
  * Amazon Chimeを使う（スピーカー編）: https://note.com/s_numaguchi/n/n5c5deefc9984
  * Amazon Chimeの機能拡張を使いこなそう: https://note.com/s_numaguchi/n/na4808c0dbfeb
削除した仮想環境の表示をJupyter LabのLauncherから消す


# やりたいこと
JupyterLabのLauncher画面に表示されるアイコンを消したい．

削除した仮想環境も表示されてしまうので表示されないようにします．

<img width="500" alt="jupyterlab.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526723/d18c8a88-fc39-0e2c-7340-61aeaf1dc39e.png">

## 方法１
次のコマンド を打ち込んでカーネル(仮想環境)の名前一覧を確認します。

```
jupyter kernelspec list
```
次のコマンドを打ち込めばカーネルの表示を削除できます.仮想環境名には上で確認したカーネルの名前を打ち込みます.

```
jupyter kernelspec uninstall 仮想環境名
```

### 参考
- Using jupyter notebooks with a virtual environment  
<https://anbasile.github.io/posts/2017-06-25-jupyter-venv/>
- Using Virtual Environments in Jupyter Notebook and Python  
<https://janakiev.com/blog/jupyter-virtual-envs/>  

## 方法２

`C:\Users\{ユーザ名}\AppData\Roaming\jupyter\kernels`を開きます．

削除したい仮想環境に対応するフォルダを削除します．

そうするとJupyterLabのLauncher画面からアイコンも消えます．

フォルダの名前を見れば対応するフォルダ名は分かります．


### 追記
ホワイトリストを作成する方法もあるようです

Remove environments from the Jupyter Lab Launcher
<https://discourse.jupyter.org/t/remove-environments-from-the-jupyter-lab-launcher/762/4>
「oracle」と「sqlserver」NULLと空文字の判別の違い

# 初めに
oracleからsqlswrverへ移行した際にはまった空文字とNULLの違いについて

# 結論
oracleは空文字とNULLを
NULLとするが。

sqlserverは空文字は空文字、NULLはNULlとして判別する。

そうです。

oralceとaccess
sqlserverとaccess

作業用のデータベースにaccessデータベースを挟んでいますが
そのaccessDBにはoracleに合わせて空文字やNULLの許可の設定を行なっていましたが
sqlserverに移行したことでNULLと空文字の区別が行われaccessDBの設定との不一致が起こり
エラーの温床になりました。

僕が見ているデータベースの違いはほんとに表面上しか見れていませんが
DBの移行を行うと全てに影響が起こるのですね。

とりあえず今回はプログラムを書く上でDBにおけるNULLと空文字の違いでやられたので
2度と忘れないように記録します。

以上。
JUnitとは【詳細な技術というより概要的なお話】

# ユニットテストとは

### 小さな単位(ユニット)の動作を確認するテスト  
ユニットテスト(別名:単体テスト)とは、クラスやメソッドが、プログラマの想定通りに動作することを確認するテストである。

### ユニットテストの限界  
ユニットテストは万能ではない。ソフトウェアは複数クラスの相互作用、品質、セキュリティなど様々な要素を持っているが、ユニットテストのみでそれらを保証することはできない。

# JUnitとは

### Javaのテスティングフレームワーク
JUnitに限らず、多くのテスティングフレームワークは以下を提供する。

- テストの記述方法(コードの見た目を揃える)
- テストの検証方法(テスト結果の見た目を揃える)
- テストの実行方法(テスト実施の際の操作を揃える)

簡単に言ってしまえば、「誰が書いても同じようなテストコードになり、誰の書いたテストであっても検証結果がすぐ理解でき、誰でもテストの実施が可能になる」機能を提供するのがJUnitである。

### JUnitのバージョン
JUnitは、Java5のアノテーションの導入前後で大きくバージョンが異なっており、アノテーション対応前のJUnit3と対応後のJUnit4に分かれる。

# チュートリアル

### JUnitテストの作成〜実施
JUnitの作成〜実施は、おおまかに以下の手順で行う。

<b>最初だけ行う手順</b>

1. 環境構築
以下の環境のセットアップを行う。
・JDK
・Eclipse
・JUnit用プラグイン(必要な場合のみ)

2. プロジェクトの作成とライブラリの追加
Eclipseでプロジェクトを作成し、下記のいずれかのjarファイルを追加する。
・junit-4.x.jar
JUnitとHamcrestの一部の機能をパッケージしたライブラリ。
・junit-dep-4.x.jar
junit-4.x.jarからHamcrestを除いたもの。Hamcrestのより多くの機能を使用したい場合はこちらを使用し、別途、Hamcrestのライブラリを追加する。

<b>テスト対象ごとに行う手順</b>
3. テスト対象クラスの作成
4. テストクラスの作成
5. テストの実施と結果の検証
※上記手順の詳細な内容は後続の章を参照

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [JUnit実践入門 ── 体系的に学ぶユニットテストの技法](https://www.amazon.co.jp/JUnit%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E6%8A%80%E6%B3%95-WEB-PRESS-plus-ebook/dp/B07JL78S95)
n進数という名前が出てくると「うっ頭が…」ってなる人のn進数講座（１）〜n進数の基本変換について〜

基本情報技術を学んだ事がある人、学んでいる最中の人がいずれも悩んだ事があるだろうn進数の計算。
自分もその一人でした…。ですが、その状態から脱却すべく必死になって勉強した結果ある程度はわかる様になったので自分なりにわかりやすく解釈したものをここに残そうと思います。

#■n進数とは

ではまずn進数とはなんぞ？ってかたのために説明します。
ただ、あーだこーだと長ったらしく説明したくないので簡単すると、

「**コンピュータが我々人間の言葉を理解できるようにした言語のようなもの**」です。

ああ…。専門の人たちに怒られそう…。笑

コンピュータは今も昔も同じく電源のON/OFF（１と０）でしか認識する事ができません。
そのため我々人間がコンピュータにも理解できるように仕方な〜く用意したのが２進数という考え方でした。

２進数というのは数字の１と０だけで表現する考え方で例えば１０進数から２進数に置き換える例を挙げると

６（１０進数）＝１１０（２進数）　、４（１０進数）＝１００（２進数）

のような書き方をします。

基本的にはこの２進数だけでコンピュータの世界は表現されます。

がしかし…。現代になるとそれ以外の考え方が存在します（これがまたややこしいんだよ…。）。それが８進数、１６進数という考え方です。

８進数、１６進数という考え方は実は２進数ありきで作られたものになります。
数字が変わっても結局考え方は２進数同じで１０進数を８、１６で表現したものになるだけです。

ではなんで全部２進数で表現しないの？無駄じゃん？って思うかもしれません。
はい。その通りです。なんでややこしくなるだけのものを作ったのだ…。（すいませんちゃんと必要です。）

これも説明するとややこしくなりそうなので簡単に説明しますと、

「**８進数→２進数の３桁まで、１６進数→2進数の４桁までを表現するのにぴったりだから！**」

以上です…。（詳しく知りたい人はググってね♡）

#■n進数の基本変換について



では次にそれら２、８、１６進数をそれぞれ置き換えるための考え方について説明していきます。

先ほどの説明からも１０進数をかくn進数別に表現すると言いましたが、この置き換えを**基本変換**と呼んでいます。

基本変換にはやり方があります。それぞれ紹介します。

##【格桁の重みを使う方法】

例）　１３.３５７（１０進数）を置き換える場合

|格桁の重み| … | n^3 | n^2 | n^1 | n^0 | . | n^-1 |n^-2 |n^-3 |…|
|:--------:|:--:|:--:|:--:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|2進数|  …  |  １  | １  |０| １  | .  | 0  |1　| 1  | …  | 
|８進数|  …  |  -| - |1　| 5  | .  | 3  |-　| -  | …  | 
|１６進数|  …  |  -  | -  |-　| D  | .  | 6  |　-|  - | …  | 

やり方は１０進数の数値を「格桁の重み」で割った値を入力していく形になる

ただこのやり方は現実的じゃないので別の簡単な方法を使うと良い

##【割り算と掛け算を使う方法】

例）　１３.３５７（１０進数）を置き換える場合

手順１・・・整数部分と少数部分に分ける

この場合　　

整数部分・・・１３　　
少数部分・・・０.３７５　　

となる

手順２・・・置き換えたいn進数で整数部分を割り算、少数部分を掛け算する。
　整数部分は割った時の余りの数値を小さい順に並べ替える
　少数部分は掛けた時の繰り上げした数値

この場合


■２進数
　整数部分・・・１３→６（１）→３（０）→１（１）、０（１）
　　結果１１０１となる
　少数部分・・・０.３７５→０.７５→１.５→１.０
　　結果０１１となる

答え　**1101.011**

※（）は割ったあまりの数

手順３・・・８進数と１６進数においては２進数からの変換が簡単なため、一度２進数に置き換えて考える

■８進数・・・８＝2^3より２進数の３桁を表現するため３桁毎に区切る
 
１１０１.０１１
↓　３桁毎に置き換えると
｜１｜１０１｜.｜０１１｜
↓それぞれを１０進数に戻すと
｜１｜５｜.｜３｜
↓
結果**15.3**となる

■１６進数・・・１６＝2^3より２進数の４桁を表現するため４桁毎に区切る
 
１１０１.０１１
↓　４桁毎に置き換えると
｜１１０１｜.｜０１１０｜
↓それぞれを１０進数に戻すと
｜１３｜.｜４｜
↓１６表記だと
｜D｜.｜4｜
↓
結果**D.4**となる



#次回は…

以上がn進数における基本変換の方法です。

現在基本情報技術を勉強している者としてこのn進数を理解するのはある意味一つの障壁なのかなと思っています…。
正直自分はこれを実務に生かせる気がしません…。笑

でも資格取得に向けては必要な知識なのは確かなので、覚えておいて損はないかなと…。

今回少しでも理解しやすく噛み砕いて要点のみを紹介したつもりでしたが、もし至らない点などありましたらコメントいただけたら嬉しいです。

次回はこのn進数を使った計算方法について説明していきたいと思いますのでよろしくお願いいたします。

では！！
Chrome拡張でajax通信時にクロスドメインのエラーの対処

【コメントで質問OKです】
Chrome拡張で下記の様にajaxでgetを実施すると
『CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.』
が発生

```
    $.ajax({type: 'GET',url: TGVC.sru + "/api/room/event_and_support?room_id=" + roomID, async: false})
    .done(function(re) {
        console.log(re);
    })
    .fail(function() {
    });
```

[<Chrome extension>クロスドメインで怒られたら（XMLHttpRequest）](https://qiita.com/5a3i/items/a031427727e4923005d0)
上記を参照しマニフェストのpermissionsにURLを追加

```
    "permissions": ["tabs","https://www.showroom-live.com/"],
```
Laravel 新規テーブル作成時にモデルファイルと一緒にマイグレーションファイルも作成する

# 目的

- 新規テーブル作成時にマイグレーションファイル作成時に一緒にモデルファイルを作成する方法をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 実施方法

- アプリ名ディレクトリで下記を実行する。

    ```terminal
    $ php artisan make:model テーブル名のキャメルケースの単数形 --migration
    ```

# 実行時の例

- モデルを作成するコマンドにオプションを付けて実行しているので、ファイル名の指定時はモデル作成時と同じで単数形、アッパーキャメルケースで指定する。

1. contentsテーブル作成のマイグレーションファイルとContentモデルファイルを作成した場合
    - アプリ名ディレクトリで下記を実行する。

        ```terminal
        $ php artisan make:model Content --migration
        ```
    - 作成されるファイルを下記に記載する。
        - `アプリ名ディレクトリ/app/`直下
            - Content.php
        - `アプリ名ディレクトリ/database/migrations/`直下
            - YYYY_MM_DD_XXXXXX_create_contents_table.php
1. notice_contentsテーブル作成マイグレーションファイルとNoticeContentモデルファイルを作成したい場合
    - アプリ名ディレクトリで下記を実行する。

        ```terminal
        $ php artisan make:model NoticeContent --migration
        ```
    - 作成されるファイルを下記に記載する。
        - `アプリ名ディレクトリ/app/`直下
            - NoticeContent.php
        - `アプリ名ディレクトリ/database/migrations/`直下
            - YYYY_MM_DD_XXXXXX_create_notice_contents_table.php
git pushでemail privacy restrict エラーが出た場合

GitHubにメールアドレスを複数登録している場合に、以下のようなメッセージが出る。

```bash
remote: error: GH007: Your push would publish a private email address.
remote: You can make your email public or disable this protection by visiting:
remote: http://github.com/settings/emails
To github.com:user/repository.git
 ! [remote rejected] branch_name -> branch_name (push declined due to email privacy restrictions)
```


https://github.com/settings/emails
<img width="738" alt="スクリーンショット 2020-04-16 10.29.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4064/d4829aa7-aec5-a66c-04bf-2d2b693438bc.png">

ここにチェックがついてるはずなので、外す or メッセージにあるアドレスにAuthorを変更する。
SFDXからJSforceのコネクションを取得&Puppeteerでログイン

書き捨てのスクリプトなどでSFDXからjsforceのコネクションを持ってくる方法。

## 調査

`sfdx plugins:generate`が吐くクラスが `@salesforce/command` の SfdxCommand クラスを継承し、
`this.org.getConnection()` でコネクションを取得してるのでそこから追った。

- @salesforce/command
    - npm: https://www.npmjs.com/package/@salesforce/command
    - GitHub: https://github.com/forcedotcom/cli-packages

https://github.com/forcedotcom/cli-packages/blob/%40salesforce/command%403.0.0/packages/command/src/sfdxCommand.ts#L208-L211
ここで

```ts
      this.org = await Org.create({
        aliasOrUsername: this.flags.targetusername,
        aggregator: this.configAggregator
      });
      if (this.flags.apiversion) {
        this.org.getConnection().setApiVersion(this.flags.apiversion);
      }
```

となっているのでこれがOrgオブジェクトの生成して、その直後にコネクションは取得可能っぽい。

ファイルの先頭で

```ts
import { ConfigAggregator, Global, Logger, Messages, Mode, Org, SfdxError, SfdxProject } from '@salesforce/core';
```

してるので`@salesforce/core`をインポートして Org.create().getConnection()で取得できる。

- @salesforce/core
    - npm: https://www.npmjs.com/package/@salesforce/core
    - GitHub: https://github.com/forcedotcom/sfdx-core

## 取得

$`npm i -D jsforce @types/jsforce @salesforce/core @salesforce/ts-types`

```ts
import { Connection } from "jsforce";
import { Org } from "@salesforce/core";

(async () => {
  const org = await Org.create({
    aliasOrUsername: null,
    aggregator: null
  });
  const conn = org.getConnection() as any as Connection;
})();
```

## 取得したアクセストークンでPuppeteerからログイン

```ts
import * as puppeteer from "puppeteer";
import { Org } from "@salesforce/core";

(async () => {
    const org = await Org.create({});
    const conn = org.getConnection();
    //   const browser = await puppeteer.launch();
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    const retURL = encodeURIComponent(`/lightning/o/Account/new`);
    const url = `${conn.instanceUrl}/secur/frontdoor.jsp?sid=${conn.accessToken}&retURL=${retURL}`;
    await page.goto(url);
    await page.waitFor(5e3);
    await page.screenshot({ path: "screenshot.png" });
    await browser.close();
})();
```
Anaconda仮想環境でPythonをダウングレード

備忘録です。
昔のプログラム（RNN）が動かなくなったのでAnaconda再インストールしたりしてたが今も沼にハマってます。
そのうちTensorflowも動かなくなり（2020/4/15時点）、きちんとログをつけようと思った次第です

つづきはこちら[リンクへ](https://qiita.com/kmtk49/items/1413c39ca1965985bab5)

# Base環境：
- Ubuntu 18.04
- Python 3.7.7
- Tensorflow　2.1.0

# 現状
Tensoflow1.10系で作成したプログラムが動かない。1.13と2系で動くようにしたい。（2系は2020/4時点でいろいろ大変そうなので1.13系でもいいということで）
Anaconda でTensorflowのインストールは何故かTerminalからでないとインストールできなかった。Navigatorでは表示さない。
その後KerasとTensorflow2系とならNavigatorからインストール出来た。
Tensorflow2系はPython3.6系にダウングレードすると動くらしい。とのことなのでTF2系の環境を複製し、ダウングレードをこころみる。


# やったこと
## Python3.7->3.6, tensorflow 2.1 ->1.10.1
Anacondaの仮想環境に
Python 3.6　をインストール

```
conda install python=3.6
```
終了したらTensorflow 1.10　をインストール

```
pip3 install --upgrade tensorflow==1.10.1
```
Anaconda上では2系の表示のまま。とりあえずTf1.10系のプログラムをそのまま動かす。

```
ModuleNotFoundError: No module named 'tensorflow'
```

うまく動かず。そんな気はしていたが、、
## Python3.7->3.6, tensorflow 2.1 ->1.13.1
2系の環境をクローンし、1.13載せ換えににチャレンジしてみる

```
pip3 install --upgrade tensorflow==1.13.1
```
1.13.2系も同様にするもうまく動かず。そんな気はしていたが、、
未だ沼から抜け出せず。。

つづきはこちら[リンクへ](https://qiita.com/kmtk49/items/1413c39ca1965985bab5)

# 参考にさせていただいた方
ありがとうございます。

Python3.7ではTensorFlowを利用できない..?
https://pycarnival.com/tensorflow_python37/

Python 3.7でTensorflow 2.xを動かす
https://qiita.com/ytooyama/items/76f5bff6fa101d1a660c