OmniAICreator/Qiita-1.07M huggingface dataset:
Jetson nanoでLEDテープ（WS2812）を動かす

Jetson nanoでLEDテープを動かすことができたので共有します。
https://github.com/seitomatsubara/Jetson-nano-WS2812-LED-

## 準備
### Jetson-IO tool でSPI設定
```
$ sudo /opt/nvidia/jetson-io/jetson-io.py
```

Configure 40-pin expansion headerを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738677/4340eb5f-c924-9ced-3fbf-1512e06c3696.png)

spiを選択し、*を付けて再起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738677/dfb64e96-0a5b-3973-c96c-302afbf29649.png)

## 接続
spi1なら19ピン、spi2なら13ピンにLEDテープのシグナルピンをつなぐ。
spi通信のプロトコルを用いる関係上、spi通信で使うピン（spi1なら21,23,24,26）は使用不能。
GNDも接続する必要あり。
電源は適宜供給する。

## spidevをpipでインストールする

```
$ sudo pip install spidev
```

## コード

```
import spidev
import sys
 
class SPItoWS():
    def __init__(self, ledc):
        self.led_count = ledc
        self.X = '' # X is signal of WS281x
        for i in range(self.led_count):
            self.X = self.X + "100100100100100100100100100100100100100100100100100100100100100100100100"
        self.spi = spidev.SpiDev()
        self.spi.open(0, 0)
        self.spi.max_speed_hz = 2400000

    def __del__(self):
        self.spi.close()
        
    def _Bytesto3Bytes(self, num, RGB): # num is number of signal, RGB is 8 bits (1 byte) str
        for i in range(8):
            if RGB[i] == '0':
                self.X = self.X[:num * 3 * 8 + i * 3] + '100' + self.X[num * 3 * 8 + i * 3 + 3:]
            elif RGB[i] == '1':
                self.X = self.X[:num * 3 * 8 + i * 3] + '110' + self.X[num * 3 * 8 + i * 3 + 3:]
    
    def _BytesToHex(self, Bytes):
        return ''.join(["0x%02X " % x for x in Bytes]).strip()
    
    def LED_show(self):
            Y = []
            for i in range(self.led_count * 9):
                Y.append(int(self.X[i*8:(i+1)*8],2))
            WS = self._BytesToHex(Y)
            self.spi.xfer3(Y, 2400000,0,8)

    def RGBto3Bytes(self, led_num, R, G, B):
        if (R > 255 or G > 255 or B > 255):
            print("Invalid Value: RGB is over 255\n")
            sys.exit(1)
        if (led_num > self.led_count - 1):
            print("Invalid Value: The number is over the number of LED")
            sys.exit(1)
        RR = format(R, '08b')
        GG = format(G, '08b')
        BB = format(B, '08b')
        self._Bytesto3Bytes(led_num * 3, GG)
        self._Bytesto3Bytes(led_num * 3 + 1, RR)
        self._Bytesto3Bytes(led_num * 3 + 2, BB)

    def LED_OFF_ALL(self):
        self.X = ''
        for i in range(self.led_count):
            self.X = self.X + "100100100100100100100100100100100100100100100100100100100100100100100100"
        self.LED_show()
```

## 使い方
```
SPItoWS(<LEDの個数>)
```
### LEDの指定

```
SPItoWS.RGBto3Bytes(i, R, G, B)
```
i: LEDの位置
R, G, B: LEDの強さ。0-255で指定

### LEDを光らせる

```
SPItoWS.LED_show()
```
RGBto3Bytes関数を使って指定したLEDを光らせる。

### すべてオフにする
```
SPItoWS.LED_OFF_ALL()
```
全てのLEDをオフにする。

## 使用例

```
if __name__ == "__main__":
    import time
    LED_COUNT = 3
    sig = SPItoWS(LED_COUNT)
    sig.RGBto3Bytes(0, 255, 0, 0)
    sig.RGBto3Bytes(1, 0, 255, 0)
    sig.RGBto3Bytes(2, 0, 0, 255)
    sig.LED_show()
    time.sleep(1)
    sig.LED_OFF_ALL()
```

1秒間LEDが赤、緑、青に点灯した後、消えます。
php ファイルのアップロード

```php:up.php
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>img_upload</title>
</head>

<body>

  <?php
  var_dump($_FILES['file']);
  
  $filename =  './img/'.date('Y-m-d H:m:s') . '.jpg';

  if ($_FILES['file']) {
    move_uploaded_file($_FILES['file']['tmp_name'], $filename);
    
  }
  echo "<img src = '$filename'>"
  ?>
//enctypeは決まり文句
  <form action="up2.php" method="POST" enctype="multipart/form-data">
    <input type="file" name="file" accept="image/*">
    <input type="submit" value="ファイルをアップロードする">
  </form>

  


</body>

</html>
```
TinyGo + `VSCode or Vim (もしくはそれ以外の LSP 対応エディタ)` で gopls 連携する方法

TinyGo 0.15 がリリースされて、 gopls との連携が簡単になりました。
逆に言うと今までは [設定がそれなりに面倒](https://qiita.com/sago35/items/f0b058ed5c32b6446834) でした。

このページでは、 TinyGo 0.15 以降での gopls 連携の方法を `VSCode` および `Vim (もしくはそれ以外の LSP 対応エディタ)` に対して記載します。

注意)
以降、 `wioterminal` というターゲットを例として記載します。
適宜、使いたいターゲットに読み替えてください。

## VSCode

まずは、 `VSCode の Extensions ＞ TinyGo 0.2.0` をインストールします。

![Screenshot from 2020-09-23 21-28-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/584cbb02-0d00-288b-2f44-22a2b7e2f9b1.png)

次に tinygo のソースコード (*.go) を開いている状態で `Command palette ＞ TinyGo targets` を実行します。

![Screenshot from 2020-09-23 21-22-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/9c5a4bd4-9831-3110-e466-25bc9d70d7da.png)

`pick a target...` と表示されるので `wioterminal` を選択します。

![Screenshot from 2020-09-23 21-21-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/0601cff9-f81c-8d94-1b08-06f13866b6b7.png)

Reload を促されるので Reload します。

![Screenshot from 2020-09-23 21-21-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/42dca705-4014-deb8-cc7a-1a9f8bf4d425.png)

この時点で `machine.LED` の定義が表示されていれば gols 連携は OK です。  

![Screenshot from 2020-09-23 21-23-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/2c7b9d2e-592d-6436-296d-1f425615ec96.png)

ターゲットを切り替えたい場合は、 `Command palette ＞ TinyGo targets` を再度実行してください。

## Vim (もしくはそれ以外の LSP 対応エディタ)

↓↓↓ 2021/06/14 追記 ↓↓↓
Vim + vim-lsp を使っている人は以下の記事を参照してください。

* [TinyGo + Vim で gopls するための設定 - Qiita](https://qiita.com/sago35/items/f0b058ed5c32b6446834)

↑↑↑ 2021/06/14 追記 ↑↑↑

まずは `tinygo-edit` をインストールします。
以下から実行体を DL し PATH の通った場所に置いてください。

* https://github.com/sago35/tinygo-edit/releases

もしくは、以下のコマンドでもインストールすることが出来ます。  

```
$ go get github.com/sago35/tinygo-edit
```

その後、以下をソースコードのあるディレクトリで実行します。
エディタに合わせて少し設定が必要です。

```
# Vim
$ tinygo-edit --target xiao --editor vim --wait

# gVim
$ tinygo-edit --target xiao --editor gvim

# VSCode (VSCode は上記の TinyGo extensions を使ったほうが良い)
$ tinygo-edit --target xiao --editor code
```

この時点で `machine.LED` の定義が表示されていれば gopls 連携は」 OK です。

![Screenshot from 2020-09-23 21-27-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/c2b6d272-825c-f84f-dd2f-d4d1acae2034.png)

なお、この方法で開いた vim から立ち上げた terminal では `tinygo build` や `tinygo flash` が出来ません。
環境変数 GOROOT が設定されているためです。

![Screenshot from 2020-09-23 21-32-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/9a1d4257-56cb-85a5-7165-3437a6ebcfcf.png)

以下のようにして GOROOT の設定を削除すると `tinygo build` 等を実施出来るようになります。

```
# windows / cmd.exe の場合
$ set GOROOT=

# bash の場合
$ unset GOROOT
```

![Screenshot from 2020-09-23 21-35-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63649/f96bb644-2701-e0f3-f2c3-b850eefcd545.png)

ターゲットを切り替えたい場合は、 `tinygo-edit` を再度実行してください。

## Link


* https://tinygo.org/ide-integration/
* https://www.thushanfernando.com/posts/2020/tinygo-big-things/#setup-vscode-for-tinygo
* https://github.com/sago35/tinygo-edit
Railsアプリケーションで投稿検索機能を実装する(whereメソッド)

アプリ: ラーメン屋の写真や情報を友達と共有できるSNS
Ruby: 2.6.5
Rails: 5.2.0

# viewに検索フォームを設置する

form_withを使って、検索ワードをposts_controllerのsearchアクションに渡します。

```erb:app/views/layouts/_header.html.erb
・
・
・
<div class="post_search">
  <%= form_with url: search_posts_path, method: :get, local: true do |f| %>
    <%= f.text_field :search, class: 'form-control', placeholder: "キーワード検索"  %>
    <%= f.button :type => "submit" do %>
      <i class="fas fa-search"></i>
    <% end %>
  <% end %>
</div>
・
・
・
```

![スクリーンショット 2020-09-23 18.54.03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589400/741a8981-684f-076d-42bc-f53392cd0491.jpeg)

# ルーティング
routes.rb を下記のようにすることで、
/posts/searchというURL(search_posts_path)にgetリクエストを送ることでposts_controllerのsearchアクションにルーティングされます。

```config/routes.rb
~
~
resources :posts, only: [:new, :create, :edit, :show, :update, :destroy] do
  get :search, on: :collection
end
~
~
```

# posts_controller
検索ワードに合致する投稿を@postsで定義。

```app/controllers/posts_controller.rb
~
~
def search
  @section_title = "「#{params[:search]}」の検索結果"
  @posts = if params[:search].present?
             Post.where(['shop_name LIKE ? OR nearest LIKE ?',
                        "%#{params[:search]}%", "%#{params[:search]}%"])
                 .paginate(page: params[:page], per_page: 12).recent
           else
             Post.none
           end
end
~
~
```
params[:search]でform_withから渡された検索ワードを受け取ります。
whereメソッドはテーブル内から条件に一致したレコードをすべて返します。
(検索ワードがない場合はPost.noneとし、投稿を取得しないようにしました。)

### whereメソッド
whereメソッドでは下記のように

```
モデル名.where('カラム名 = ?', "値")
```

第一引数に ? を(プレースホルダーと呼ぶ)、第二引数に条件の値を入れることがあります。
このような書き方をすることで、SQLインジェクションというデータベースのデータを不正に操作する攻撃を防ぐことができるそうです。

whereの第二引数には下記のように

```
"%#{params[:search]}%"
```

検索ワードの前後に % を置いています。
こうすることで、「空白文字を含む任意の複数文字列」が検索ワードの前後に含まれても
その文字列を持つレコードを返すことができます。

#### 例
```
%二郎%
→ 「二郎」「ラーメン二郎」「つけ麺二郎」「ラーメン二郎八王子店」「二郎歌舞伎町店」
　どれも該当する。

%二郎
→ 「二郎」「ラーメン二郎」「つけ麺二郎」は該当するが、
　「ラーメン二郎八王子店」「二郎歌舞伎町店」は該当しない。
```

下記のように書くことでshop_nameとnearestという2つのカラムから
検索ワードに該当する文字列を検索し、レコードを返します。

```
Post.where(['shop_name LIKE ? OR nearest LIKE ?',
            "%#{params[:search]}%", "%#{params[:search]}%"])
```

あとは@postsをapp/views/posts/search.html.erbで表示させるようにしてください。

# こんな感じ
![スクリーンショット 2020-09-23 21.33.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589400/7c73dac9-7489-49a0-749d-cc3e25008805.jpeg)

↓

![スクリーンショット 2020-09-23 21.34.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589400/2d7867bb-74f5-a277-004c-8d0bff715cb1.jpeg)


# 参考
[【Rails】１つの検索フォームで複数カラムをまたいで検索する方法](https://qiita.com/bSRATulen2N90kL/items/6a7c99bf3641ac6838fb)
[【Rails】whereメソッドを使って欲しいデータの取得をしよう！](https://pikawaka.com/rails/where#where%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9)
勉強日誌18日目

今日からテレワーク
私はテレワークよりか出社したいタイプなのですが、2時間半くらい余裕時間増えるから良い。
その分有効活用できる。

ようやく正答率が70％付近に・・。
いくら記述形式で回答するものだとは言え6週目でこれは正答率悪い気がする。

それでも継続は力


正答率　70%　(65)

unknown
接続状態が見つからない

nmcli device status
デバイスの状態

none
どのネットワークにも接続していない

/etc/hosts
IPアドレス　ホスト名

networking
ネットワークの接続状態を表示、ネットワークを有効化・無効化

hostnamectl
ホスト名の表示・設定

up
down
conncectionの接続有効・無効

limited
ネットワークに接続してるが、ネットにアクセスできない

正答率　76% (62)

ifconfig
ネットワークインターフェースの情報表示や設定（1コマンド）

ifconfig eth0
インターフェースのうちeth0の情報を表示する

ip addr add IPアドレス/サブネットマスク dev インターフェース
アドレスの設定

ip -s
送受信バイト数などの統計情報

netstat -i
ネットワークインターフェースの統計情報

ip addr show
IPアドレスの設定状況

ip route show
IPアドレス/サブネットマスク dev インターフェースなどの表示

netstat
有効なネットワーク接続や開いているソケットの情報

nc -u tsetsv 50000
ncコマンドでtestsvのポート50000にUDPで接続するコマンド

正答率　62% (69)

dig
DNSサーバーへ直接問い合わせ、指定したホスト名のDNSサーバへの登録情報を表示する

host
DNSサーバに問い合わせて名前解決する際に、問い合わせた名前に対応する回答だけを得られるコマンド

dig co.jp any
DNSに登録されてる全ての情報

/etc/resolv.conf
DNSサーバを指定するファイル名をフルパスで

dig -t soa
DNSサーバに登録されているドメインのゾーンに関する情報
Unity ML-Agents でアルゴリズム、行動、観察を変えて学習時間を比較してみた

![bandicam 2020-09-23 20-54-03-158.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/340d0b52-ad9e-38e8-c25b-6992fae4e03c.jpeg)

学習アルゴリズム、行動、観察を変更しながら時間測定してみました。
プログラムは[RollerBall](https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Learning-Environment-Create-New.md)を参考につくっていて、[こちら](https://github.com/machidyo/RollerBall)に挙げてあります。

# 環境
* Windows10
* Python 3.7.9
* TensorFlow 2.3.0
* Unity 2019.4.10f1
* ML-Agent Release6

# 結果
一番上のグラフを表にしたものです。
時間、ステップ数は Mean Reward が 1.000 になるまで計測したものになります。
（1回しか測定していないので、数秒は誤差だと思ってください。）

アルゴリズム | 行動       | 観察                | 時間(s) | ステップ数(k) | 備考
------------|------------|---------------------|---------|--------------|------------
PPO         | Continuous | Vector Observation  |   68    | 13           |
SAC         | Continuous | Vector Observation  |  191    | 121          |
PPO         | Discrete   | Vector Observation  |  159    | 31           |
SAC         | Continuous | Visual Observation  | 1177    | 138          |
PPO         | Discrete   | Raycast Observation | 1318    | 236          | ※1

※1 学習に時間がかかりすぎたので、途中で止めました
PHP Laravel 6 おすすめ映画投稿サイト作成過程 4:投稿機能作成編

#ルーティング

登録画面にはcreateを使用します。

```
| GET|HEAD  | recommends/create           | recommends.create  | App\Http\Controllers\RecommendController@create                        | web          |
```


DBへの登録にはstoreを使用します。

```
| POST      | recommends                  | recommends.store   | App\Http\Controllers\RecommendController@store                         | web          |
```


#viewファイルの作成
![Screen Shot 2020-09-23 at 20.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736153/ec320312-9260-8621-3073-4ceff47640a0.png)
登録が必要な内容をビューファイルに設定しましょう。
今回は、以下の内容を登録対象とします。
※画像のアップロードに関しては、後日編集します

| 登録する内容 |
|:--|
| 映画タイトル|
| 映画URL|
| 映画概要|
| 感想|

#formタグで入力データをrecommends.store へ送る
@csrfを忘れないようにしましょう。※不正な動作を防ぐために記載します。詳細はGoogleで検索してください。

```recommend/resources/views/recommends/create.blade.php
<form method="POST" action="{{route('recommends.store')}}">
@csrf
 <table>
   <thead>
     <tr>
       <th>タイトル</th>
       <th>映画URL</th>
       <th>概要</th>
       <th>感想</th>
     </tr>
     <tr>
       <th><input type="text" name='title'></th>
       <th><input type="URL" name='url'></th>
       <th><textarea name="description" id="" cols="30" rows="10"></textarea></th>
       <th><textarea name="Impressions" id="" cols="30" rows="10"></textarea></th>
       </tr>
  </thead>
 </table>
 <button type="submit">登録</button>
 <a href="{{route('recommends.index')}}">一覧に戻る</a>
</form>
```
#レコードの保存処理
レコードの保存には、Modelのクリエイトメソッドを使用します。
登録後はindexページにリダイレクトさせました。

```recommend/app/Http/Controllers/RecommendController.php
public function store(Request $request)
    {
        Recommend::create($request->all());
        return redirect()->route('recommends.index');
    }
```

一方、allで情報を取得した場合、そこには全ての情報が含まれているため、どの情報を登録するかModelで指定する必要があります。

```recommend/app/Models/Recommend.php
class Recommend extends Model
{
    protected $fillable = [
      'title',
      'image_file_name',
      'image_title',
      'url',
      'description',
      'Impressions'
    ];
}
```
RPAとは、あと少しAIについて

#RPAとは
RPA（Robotic Process Automation）とは、バックオフィス業務などをはじめとするホワイトカラー業務をソフトウェアに組み込まれたロボットが代行する取り組みを指します。
間接業務を自動化するテクノロジーともいえます。

構造化されたデータを収集・統合し、システムへ入力する、単純業務を自動化します。たとえばExcelのデータ入力やネットのデータ収集などに活用されています。

RPAを活用すると、定型的で反復性の高い業務において大きな効果を期待できるでしょう。企業の変革に欠かせないツールとして注目が高まっています。

#RPAには3段階ある

RPAを利用した業務には3段階あり、それぞれRPA、EPA、CAと呼びます。それぞれできる業務の内容や範囲などに違いがあり、クラスが上がるほど複雑な機能に対応できます。

class1：RPA（Robotic Process Automation）
class1と呼ばれるRPAは、定型業務をミスなく的確に遂行する、またいくつかのアプリケーション連携が必要とされる単純作業に対応します。人事・経理・総務・情報システムなどのバックオフィスの事務・管理業務や、販売管理や経費処理などに使われています。

class2：EPA（Enhanced Process Automation）
class2と呼ばれるEPAは、データの収集や分析に対応できます。自由記述式アンケートの集計やログ解析、複数要因を加味した売上予測など、様々なデータを基にした分析を自動化する処理に用いられます。

class3：CA（Cognitive Automation）
class3であるCAはRPAにAIのような自律的な判断力を備えたもので、プロセスの分析や改善、意思決定までを自動化するとともに、ディープラーニングや自然言語処理まで対応できるものもあります。膨大なデータの整理・分析だけでなく、得られたデータを生かした経営改善などにも活用できます。

#RPAとAIの違い
RPAとAIはよく混同されますが定義が厳密には異なります。狭義のRPAは3段階のうちClass1をさします。ルールに沿って、単純に作業をこなすのが特徴です。導入はAIほど難しくありません。

他方、AIとはClass2およびClass3をさします。大量のデータをもとに分析し結果を出力するのが特徴です。出力する結果はClass2とClass3で異なりますが、どちらもビッグデータにもとづいてアウトプットします。

RPAは単純な作業を繰り返し実施する一方、AIはビッグデータを分析し結果を出力します。これらの点でRPAとAIを区別されます。

#RPAの種類
オンプレミス
オンプレミスとは、サーバーを自社に設置して運用する形態を指します。カスタマイズさせ他のシステムと連携できる点がメリットです。反対にデメリットは初期費用が高いこと、災害時の復旧に時間やコストを要することといえるでしょう。

クラウド
クラウドとは、自社でサーバーを持たずインターネットにて操作したり管理したりする形態をいいます。メリットは初期費用が安いことや、インターネットさえあればどこでも利用できることにあります。一方、企業規模が大きいとコストかさんだり、カスタマイズしづらかったりする点はデメリットだと言えるでしょう。

RPAのメリット
RPAを導入すると、ロボットが代わりに稼働するため人ではなしえなかった精度や速度で作業を完了できます。人が苦手とする単純な繰り返し作業を請け負わなくて良い点はRPAのメリットです。

クオリティーの安定化
RPAは人為的なミスを防げるのがメリットの一つです。まったく同じ業務であっても24時間連続して勧めてくれます。人員を割かずにすむ点も強みです。

作業の高速化
プログラミングされた内容であれば人間以上のスピードで作業を進めてくれます。RPAは決められたルールに従って動くため、予想しない挙動で問題になることは少ないです。

コストの削減
従業員の労働力を確保したまま効率化するため、人件費の削減に貢献します。業務のクオリティを下げずに速度のみが上がります。作業に必要だった人員が減るため、重要な業務に集中できます。

#AIについて簡単に
補足としてAIについて掘り下げていくと、機械学習、ディープラーニングの内容を抑えておく必要があります。

AI・・・人間のような知的な機械をつくる科学や技術。最も色々な意味を含んでいるのがAI（人工知能）

機械学習・・・特定のタスクをトレーニングにより実行できるようになるAI。人が特徴を定義。

ディープラーニング・・・多層のニューラルネットワークを組み合わせて作成される機械学習モデル。特徴量を自動的に抽出できる。
デープラーニング(深層学習)は機械が特徴を自動定義する。

今までの機械で画像認識を行う場合、その画像の中でどの点に注目すればいいのかなどを、人間が指定しなくてはいけませんでした。猫であれば、ひげの数や耳の形などを明確に定義しなくては機械が猫を猫と判別することはできません。

しかし、ディープラーニングの登場によって大量のデータさえ用意できれば、そのデータの特徴を自動的に取り出し、新しいデータが入力されたときに、そのデータが何なのかを判定することができます。

#ディープラーニングの実用例
Google傘下のDeepMind社が開発した囲碁AI “Alpha Go”は人類最強と言われていた柯潔（カ・ケツ）棋士に全勝した話です。ニュースでも大きく報じられ、ディープラーニングの能力の高さを象徴した事例となっています。
ボードゲームで最も難しいと言われている囲碁には約10の360乗通りという天文学数的な組み合わせが考えられるため、人間最強の棋士に勝つには今までの機械学習方法では到底不可能でした。
しかし、ディープラーニングと強化学習などの既存の技術の組み合わせによってそれを可能にしたのです。
C/C++で書いたループを高速化する(その2) openACC

###目次
[C/C++で書いたループを高速化する(その1)](https://qiita.com/ki073/items/4510684e79cb9254882b) ベクトル化
C/C++で書いたループを高速化する(その2) openACC <- ここ

###はじめに
NvidiaコパイラでopenACCを使ってみました。コンパイラの入手方法はその1を見てください。そこそこの計算量がないと差が出にくいので、XYZの3次元座標1024点の相互距離の平均値を計算するプログラムを作ってみました。average_distance1とaverage_distance2の二つの関数を下に書いてあります。データの並びが違うだけです。その1に触れていますが、後者はCPUで実行するとSIMDを使える並びです。

CPUで実行する場合には
nvc++ -fast -Minfo=all distance1.cpp average_distance1.cpp
でコンパイルしています。関数の中にpragmaを記入していますがここでは無視されます。SIMDの使用の有無で速度の違いがでています。

次にGPUで実行する場合です。
nvc++ -acc -Minfo=all distance1.cpp average_distance1.cpp
両関数とものGPUが使われます。
CPUもGPUもだいぶ古いものですが、速くなっていることがわかります。データの並び方で差はほとんどないようです。
このようにループの直前に#pragma~の1行加えただけでGPUが使えるようになります。

###結果

|  |CPU SIMD|CPU 実行時間(ms)|GPU(ms)|
|:-----------|:-----------:|------------:|------------:|
|average_distance1|X|2.909| 0.907|
|average_distance2|O|1.458| 0.963|

(実行時間はループ一回分に換算しています)

CPU Intel Core i7-2600 CPU 3.40GHz
GPU GTX 750
CentOS 8.2

###使用したプログラム

```c++:average_distance1.cpp
#include <cmath>

inline double distance(double x1, double y1, double z1, double x2, double y2, double z2){
    return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
}

double average_distance1(int n, const double xyz[][3]){
    double sum=0.0;
    #pragma acc kernels
    for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
            sum+=distance(xyz[i][0], xyz[i][1], xyz[i][2], xyz[j][0], xyz[j][1], xyz[j][2]);
    return(sum/(n*(n-1.0)/2.0));
}

double average_distance2(int n, const double xyz2[][1024]){
    double sum=0.0;
    #pragma acc kernels
    for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
            sum+=distance(xyz2[0][i], xyz2[1][i], xyz2[2][i], xyz2[0][j], xyz2[1][j], xyz2[2][j]);
    return(sum/(n*(n-1.0)/2.0));
}
```

```c++:distance1.cpp
#include <iostream>
#include <chrono>
#include <random>

using namespace std;

double average_distance1(int n, const double xyz[][3]);
double average_distance2(int n, const double xyz2[][1024]);

int main(){
    std::mt19937 mt(123);
    std::uniform_real_distribution<double> u_rand(-10.0, 10.0);
    
    double data1[1024][3];
    for(int i=0; i<1024; i++){
         data1[i][0]=u_rand(mt);
         data1[i][1]=u_rand(mt);
         data1[i][2]=u_rand(mt);
    }
    
    double data2[3][1024];
    for(int i=0; i<1024; i++){
         data2[0][i]=data1[i][0];
         data2[1][i]=data1[i][1];
         data2[2][i]=data1[i][2];
    }
    
    chrono::system_clock::time_point start, end;
    double time;
    volatile double result;
    
    start=chrono::system_clock::now();
    for(int i=0; i<1000; i++){
        result=average_distance1(1024, data1);
    }
    end=chrono::system_clock::now();
    time=static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count()/1000.0);
    cout << result << endl;
    cout << time << endl;
    
    start=chrono::system_clock::now();
    for(int i=0; i<1000; i++){
        result=average_distance2(1024, data2);
    }
    end=chrono::system_clock::now();
    time=static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count()/1000.0);
    cout << result << endl;
    cout << time << endl;
}
ふりかえり手法って感情を軸にしたアプローチが意外とないよね。

# はじめに
某大手メーカのプロジェクトリーダに影響され、アジャイルにはまっているよっこんです。
現在進行形で、10人規模のアジャイル開発を進めていますが、スプリント毎ににふりかえりを行っています。
ふりかえりでは、YWT,KPT,FDLなどを行っていましたが、意外と感情を軸にしたふりかえりがないよねと考え、ネーミングセンスは別にして、**FUNを探す旅**なるものを考案しました。

# FUNを探す旅
FUNだった出来事を挙げる手法は、いくつかあるのですが、これ楽しかったねと終わってしまう感があり、ふりかえりで全員がFUNと思える方向に修正できたらいいなと思いました。そこで、チームメンバーが各タスクで抱いた感情(FUN　or BLUE)をあぶり出し、次のスプリントでタスクを交換すれば、全員がFUNに近づくはずと考え、以下のアプローチを考案しました。
以下に、テンプレートと、手順を記載します。

**テンプレート**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614384/15e8fe89-e117-ccf0-35bc-63be455575fb.png)


**手順**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614384/33b640d9-e24d-12c4-6ca9-5b2746bf7d9f.png)



**事例1**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614384/a9fd2e7f-ebe5-8392-ec13-4d20394497c8.png)
上記の事例では、以下のような会話が発生しました。
1.**A君(ベテラン)＞**基本設計、文章ばっかりで実装がしたいなあ。D君基本設計やりたいの？？
- **D君(若手)＞>**自分、文章や絵を書くの好きみたいです。上流を経験して技術も磨きたいです。
- **A君(ベテラン)＞** よし。設計教えるよ。D君、基本設計担当しよう。
2.**Cさん(中堅)＞**Bさん、画面作るのあんなに速いのに、つまらないの？？
- **B君(中堅)＞** もう、飽き飽きしてるよ。いつも画面ばっかり作って、別のことしたいよ。
- **C君(中堅)＞** じゃあ、画面作るの興味あるから、僕やるよ。
3.**Bさん(中堅)＞** Dさん、Junitでテストデータ作るの楽しい？？信じられん。
- **Dさん(若手)＞**実は、共通化して、テストデータ作る手続きを簡略したんです。作るのが速くなって楽しくなりました。
- **Bさん(中堅)＞**その共通化のメソッド使ってみたいな。残りもたくさんあるからは、引き継ぐよ。

**事例1でわかったこと**

- オレンジのマークが上にいけばいくほど、チームはいい状態。 そのようにタスクを交換していこう。  
- その人のスキルや振る舞いから見えない、FUN/BLUEが引き出せる。
- 人は、飽きる生き物。タスクを交換し、スキルを平坦化できる。
    - だれが抜けても回る強いチームに繋がる。

**事例2**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614384/ba8b9a52-f507-ac4d-b214-0000ff0a93cd.png)
上記の事例では、以下のような会話が発生しました。
1.**A君(ベテラン)＞**みんな試験きらいだね。
- **B君(若手)＞** いろいろな画面を操作して、運用が難しいんですよね。なかなかスムーズに試験が進まないです。
- **C君(中堅)＞** **モブテスト**をやってみませんか。一人で試験をやっていると息がつまる。みんなで集まって試験をしたら、不具合が見つかっただけで、笑いが起きたりしますよ。画面操作も、細かなテクニックがあったりして、それが共有できたら効率も上がるしね。 

**事例2でわかったこと**

- やはり、全員が面白くないとおもう作業が集中することはあるが、グループワークで進めると孤独感が薄れ、協調性が増し、楽しく進められる。テクニックの共有、ケアレスミスの回避、レビューも済んだ状態になり、逆に効率が良くなることもある。

# まとめ
**みんなが楽しく仕事を進めらたら、チームとして大きな価値を生み出せる**と信じています。
単純なPDCAサイクルでは、無機質さを感じ、決して楽しいものとはいえません。
是非、感情を軸にしたふりかえり**FUNを探す旅**を試してみてはいかがでしょうか？
各メンバーの感情の意外な発見があり、盛り上がること間違いなしです。
InfoQの"Product Owner Is a Bad Bad Idea" 翻訳記事があまりに酷いのでコメントする

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">若干マシでは有るけど相変わらずInfoQの日本語訳は酷いな、、、 <a href="https://t.co/Hjm3o5gpKj">https://t.co/Hjm3o5gpKj</a></p>&mdash; dairappa (@dairappa) <a href="https://twitter.com/dairappa/status/1308583918786863104?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


言いっぱなしになるのもあれだと思うので、InfoQ訳へのコメントと改訳案を、とくに酷いセンテンスに入れておきたい。

まずは冒頭から。

> *原文*
> Mary Poppendieck posits that the product owner role is a proxy in between people doing the work and people needing the job done, and this causes delays, misunderstandings and bloat in our software engineering process.

> *InfoQ日本語訳*
> プロダクトオーナという役割は、仕事をしている人たちと仕事を終わらせる必要のある人たちの中間に立つ仲介者で、これが我々のソフトウェアエンジニアリングプロセスに遅延、誤解、膨張を生み出している、とMary Poppendieck氏は断じている。

もう冒頭から酷い。

- 原文では"work"と"Job"を明確に使い分けているのに、日本語は両方仕事になっている。特にアジャイル文脈ではこの2つは確実に異なることで、Workは技術的な作業、Jobはビジネス的な仕事を指す。
- 「中間に立つ仲介者」ってお前は小泉環境大臣か。proxyは、この文脈だと違う目標のもとで動いている人たちを取り持つような意味に捉えるべき
- プロセスの膨張って何が言いたい。アジャイル文脈での膨張とは、仕様が無駄に膨れること。

> 改訳案
> プロダクトオーナーの役割は、作業者と終わらせるべき仕事（ビジネス課題）がある人の間を取り持つことだが、それこそがソフトウェア開発プロセスにおける遅延や齟齬、（仕様）追加をもたらせている。Mary Poppendieck氏はこのように断じている。

次は多分一番ひどいところ。

> *原文*
> Cohn and Poppendieck appear to agree that we should be distributing the responsibility for product decisions back into software engineering teams as a joint responsibility, like we already do for testing and architecture is a preferred way to improve our ability to build software and respond to change faster.

> *InfoQ日本語訳*
> 我々がすでにテストで行っているように、プロダクト判断の責任は協同責任としてソフトウェアエンジニアリングチーム内で分散するべきであるという点と、ソフトウェアを構築し、変化に迅速に対応する能力を向上するためには、アーキテクチャが望ましい方法であるという点で、Cohn氏とPoppendieck氏の意見は一致しているようだ。

日本語として意味をなしていないことに誰も文句を言わないのだろうか？

- 「我々がすでにテストで行っているように...アーキテクチャが」ってちょっとまてどこで英語区切っているんだ。確かに原文にコンマがほしいところだろうけれど、どう考えたって 「the responsibility for product decisions / back into software engineering teams / as a joint responsibility / like we already do for testing and architecture / is a preferred way to improve... 」にしないと意味が通らないでしょ意味が。

> 改訳案
> Cohn氏とPoppendieck氏は、プロダクトに関する決定についても、テストや設計について既に行っているように、チームが全体として責任が終えるように分散していくべきである、という点で一致しているようだ。

最後は翻訳という役割を放棄したかのような投げやりの一文。

> *原文*
> Cohn says this would require developers to "move beyond thinking of themselves as code monkeys." 

> *InfoQ日本語訳*
> これには開発者が、"コードモンキー(code monkey)という自らの思考から抜け出す"必要がある、とCohn氏は言う。

- 「コードモンキー」をどう日本語話者に伝わる言葉にするかが腕の見せ所でしょう。なんでそのまま訳すの。せめて訳注つけようよ。
- そもそも「thinking of themselves as」すなわち「自分自身を〜とみなしている」というのを「思考」という言葉を当てるのもどうかと思う

> 改訳案
> これには開発者が「自分たちはコードを書く猿でいい（コードだけ書いていればよい）、という思考から抜け出す」必要がある、とCohn氏は言う。


いや、ほんとに、酷いと言うか、本当にソフトウェア開発の文脈をわかった人が翻訳をしているのかを疑うレベル。翻訳者も監訳者も酷いと思う。無料で文句言うな、と怒られるのかもしれないけれど、こんなレベルの記事だったら無料でも出すべきではないと思いますよ、InfoQさん。
Automation Anywhere Enterprise - A2019 Credential Vault

A2019で開発するうえで非常に重要だけど、分りづらいCredential Vaultの設定を自分用にまとめ。

#A2019 Credential Vaultとは
自動化を行う上で各種システムへのアクセスは切っても切れません。
そんな時、作成するロボットのコードにユーザー名やパスワードが生で記載されているとセキュリティ的に問題があります。

そこで、ロボットのコードにはそれらの情報を記載しないで使えるようにという仕組みがCredential Vault。
この仕組みがあれば、ロボットを開発する人にユーザー名やパスワードを教える必要がなくなります。

##Credential Vaultの仕組み
[NISTのIA-2](https://nvd.nist.gov/800-53/Rev4/control/IA-2)という仕組みで認証しているらしい。

暗号化には、[こちら](https://docs.automationanywhere.com/bundle/enterprise-v2019/page/enterprise-cloud/topics/security-architecture/cloud-list-of-cryptographic-providers.html)の仕組みを利用しているとの事。

##ロール①
デフォルトで管理者用のAAE_Locker Adminというロールが作成されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/a1d553be-940d-1a2d-be1a-b6d18c2704cd.png)
設定されている権限はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/2b89feb1-1bc9-2ad6-941b-aec1f5645b38.png)

##オブジェクト
ここで、見慣れない用語が出てきたので、ひとまず整理。

+ 資格情報属性値
    + 具体的な値。ユーザーIDとかパスワードの文字列そのもの。
+ 属性
    + 資格情報属性値を入れる変数の様なもの
    + 標準とユーザー指定が可能であり、標準は皆が同じ値を使う場合。ユーザー指定はそれぞれのユーザーが指定する。
    + また、パスワードなどはマスクすることも可能
+ 資格情報
    + 複数の属性をまとめ上げたもの。例えば、ユーザー名とパスワード。
+ マイロッカー、全てのロッカーロッカーは資格情報を纏めて入れて置く場所。
    + 製品では”ロッカー”になってますが、”キャビネット”の方が近い気がする・・・

##ロール②
デフォルトのAAE_Locker Adminで設定されている内容を見ると、
「全ての」ロッカーに対するアクセスが付与されることが分かります。つまり、他の人が作ったロッカーもアクセスできるという事ですね。

あと、この管理者ロールでも選択されていない「すべての資格情報属性値を表示および編集」。
API経由の様ですが、全ての設定した値の表示と更新が可能とのことですので、
使うときは要注意です。

##資格情報のセットアップ
下記の様な流れになるかと思います。

1. まずは「マイロッカーを管理」と「資格情報の標準属性を作成」をロールとして持ったユーザーの作成。
2. ロッカーの作成
    + １のユーザーでログインし、入れ物を作り、誰がアクセスできるのかを指定します。設定可能なアクセス権としては下記があります。
        + 所有者
            + ロッカーの機能が利用でき、他の所有者の追加・削除が可能
        + マネージャー
            + 他の所有者の追加・削除は出来ないけど、ロッカーの機能は利用可能
        + 参加者
            + ロッカーを表示出来て、自分の資格情報を追加可能（削除は不可）
            + 他の人の資格情報は表示できない。
        + コンシューマー
            + ユーザー指定の属性に対して設定が可能。
            + Bot実行時に利用可能。
3. 資格情報の作成
    + あとは、どんな資格情報が必要かを設定して、ロッカーと紐づけて完成。
4. ユーザー属性の資格情報設定
    + コンシューマーに割り当てられると下記の様なメールが送られてきますので、値を設定します。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/d74deaac-66d1-8e4d-e2d6-cad515682adb.png)
Auto Scaling で追加したEC2 インスタンスにパブリックIP を割り振る

小ネタです。AWSコンソールから設定する方法について書きます。

# 困っていたこと
Auto Scaling で追加したEC2 インスタンスに`パブリック IPv4 アドレス`が割り振られない。

いろいろ調べたところ、Auto Scaling > [高度な詳細] > [IPアドレスタイプ] で設定できそうなのに、AWSコンソール上に見当たらなくて困っていました。
![https___qiita-image-store.s3.amazonaws.com_0_256859_ab5b9840-0761-3887-b7e6-9f5864e65079.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/c0fc0ed4-ab89-3090-831c-a3721f602a1c.png)
画像引用：[AWS勉強会(3) / Auto Scalingチュートリアル - Qiita](https://qiita.com/zaki-lknr/items/cea4885f04853d3f8878)

# 解決策
Auto Scaling グループに紐づくサブネットの`パブリック IPv4 アドレスの自動割り当て`を`はい`にする
![Screenshot 2020-09-23 16.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/4cc6adf8-2b74-bc05-5456-9d624bd5ec3a.png)

**▼ 詳細**

**① Auto Scaling グループに紐づくサブネットがなんなのか確認する**
　1. [EC2] > [Auto Scaling グループ] で対象のAuto Scaling グループの名前をクリック
　2. ネットワークのサブネットIDを控える
![Screenshot 2020-09-23 17.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/b5fea6e9-2d1f-1207-e2ba-8012e0b47717.png)

**② サブネットの`パブリック IPv4 アドレスの自動割り当て`を変更する**
　1. [VPC] > [サブネット] をクリック
　2. 対象のサブネットIDを選択し、[アクション] > [自動割り当てIP設定の変更] をクリック
　3. `パブリック IPv4 アドレスの自動割り当てを有効にする` にチェックを入れ、[保存] をクリック
![Screenshot 2020-09-23 17.10.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/47000227-0290-0d50-f2c3-bf0eb16d845f.png)

# 余談 (なぜこれを解決したかったのか)
Auto Scaling で追加したEC2 インスタンスに自動でEIPを割り当てる、ということをやりたかったです。
上記を実施するためには、パブリックIPが付与されている必要がありました。

以下の記事のおかげでEIPの自動割り当てをすることができました。圧倒的感謝:bow_tone2:

- [Auto Scalingで起動したインスタンスにEIPを自動で設定する方法 | Ryuzee.com](https://www.ryuzee.com/contents/blog/7023)
- [オートヒーリングでゆるーくEIPもヒーリングしてみた | Developers.IO](https://dev.classmethod.jp/articles/autohealing-with-eip/)
VS CodeでFortranをデバッグ設定までやってみる。【Win10】


#初めに
FortranをWindowsでビルド・デバッグする場合は、どういうツールを組み合わせればいいのか調べた。
デバッグでブレークポイントに止まらない問題でやや詰まったが解決。
必要最小限の構成で考えている。

#使用するツールや環境
・Windows 10
・Visual Studio Code
　※エクステンションは2つ：Modern Fortran、C/C++
・gfortran（フリーのコンパイラ）

#1.Fortranコンパイラの準備
・[TDM-GCC](https://jmeubank.github.io/tdm-gcc/)から、「tdm64-gcc-***.exe」をダウンロード
　※gccだけど、gfortranも入っている。
・インストールする。fortranのチェックを忘れずに。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/2af4a9fb-25ce-f643-6f1f-8022bd31caf0.png)
・インストールされたか確認。以下2つのファイルが重要。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/6965af9d-d4b6-a4c8-f4c0-1ca20ab1c07d.png)



#2.VS Codeの準備
※VS Codeインストールは割愛。
・画面一番左の「拡張機能」から「Modern Fortran」を検索してインストール。
　※自動的に「C/C++」もインストールされる。
・インストールされた「Modern Fortran」を右クリック→拡張機能の設定
・gfortranの場所を指定
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/34cb7949-964b-9784-e11f-ac5ec51dcd06.png)
・実行→構成を開く→C++(GDB/LLDB）
　※Fortranだけど、C++を選ぶ。というか、そもそもFortranがない。
　下のように、"program"と"miDebuggerPath"を自分の環境に合わせて設定。他はそのままでいいかな。

~~~
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 起動",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/a.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:/TDM-GCC-64/bin/gdb.exe",
            "setupCommands": [
                {
                    "description": "gdb の再フォーマットを有効にする",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
~~~

#3.Fortranのビルド
・ビルド作業はVS Code上ではなく、コマンドプロンプトで実行。
・今回はデバッグをするためには、必ずオプション 「-g」を付ける。

~~~
C:\Temp>gfortran -g fortran_program.f90
~~~

・exeファイルが作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/981525f7-8b7b-2b18-4260-11e606e62bc2.png)

#4.VS Codeによるデバッグ
・VS Codeでフォートランファイルを開き、行数の左にデバッグポイントを打つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/18c90a8e-1cdd-8990-92b7-aa8badedd7ff.png)
・実行→デバッグの実行。
　すると、ちゃんとデバッグポイントで止まる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/733028/a1835259-9694-b3a8-abc3-92de237df193.png)


#終わり
ビルド時にオプション必要というのがやや詰まりましたが、できて良かった。
学生時代はprint文によるデバッグしかできなかったから、Fortranでもデバッグできるんだなぁと感慨深いです。
宜しければお使いください。

「gfortran -g」がVS Codeから実行できるかどうかは、わからないです。どうやるんだろ、多分簡単だろうけどここまでにしておきます。
Vueで著作権ページを表示したいときどうするか

## 前提
- 以下記載のコードはそのままコピペしても動作は保証していません

## 環境
- macOS 10.15.6
- OnsenUI

## 検討
- nodeライブラリを使用しているということで、すべての著作権はnode_modules配下にある
- そこからライセンスを抜き出し表示すれば良い

## 手順
### jsonファイルを作成する
- このシェルを使用し、jsonファイルを作成する
    - ※生成されたjsonファイルは完璧ではございません
    - 生成されたjsonファイルから以下を行う
        - 一番下の`,`を削除する
        - 外枠の `{}`を追加する
        - 改行を全て削除する

```sh:generateJson.sh
#!/bin/bash
for i in `ls node_modules/*/LICENSE node_modules/*/LICENCE`;
do
    license_name=$(echo $i|sed 's/node_modules\///g'|sed 's/\/LICENSE//g'|sed 's/\/LICENCE//g');
    license_text=$(cat ${i}|sed -e 's/\"/\\\"/g');
    json=$(printf '
    "%s": {
        "license_name": "%s",
        "license_text": "%s"
        },' "${license_name}" "${license_name}" "${license_text}")
    echo ${json}
done > ./licenses.json
```

### 著作権をリストで表示するページを作成する
- 上記で作成したjsonファイルをimportし、ライセンスの名前をリストで表示する

```vue:Copyright.vue
<template>
  <v-ons-page>
    <v-ons-list class="scroll_erea">
      <v-ons-list-item
        v-for="(license, key) in licenses"
        :key="key"
        class="copyright__item"
        @click="onLicenseClick(license, key)">
        <div class="copyright__item__title">
          {{ key }}
        </div>
      </v-ons-list-item>
    </v-ons-list>
  </v-ons-page>
</template>
​
<script>
import CopyrightDetail from '@/components/pages/CopyrightDetail'
import licensesJson from '@licenses'
​
export default {
  name: 'Copyright',
  data () {
    return {
     licenses: licensesJson
  {
  methods: {
    onLicenseClick (license, key) {
      const props = {
        licenseName: license.license_name,
        licenseText: license.license_text
      }
      // ここにCopyrightDetailページにpropsを渡して遷移する処理を入れてください
    }
  }
}
</script>
<style lang="scss" scoped>
.scroll_erea {
  position: absolute;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  overflow-y: scroll;
}
</style>

```

### 著作権の詳細を表示するページを作成する
- propsで受け取った著作権の詳細テキストを表示する

```vue:CopyrightDetail.vue
<template>
  <v-ons-page>
    {{ licenseText }}
  </v-ons-page>
</template>
​
<script>
import { mapMutations } from 'vuex'
​
export default {
  name: 'CopyrightDetail',
  props: {
    licenseName: {
      type: String,
      required: true
    },
    licenseText: {
      type: String,
      required: true
    }
  }
}
</script>
```

## こうなったらいいのにと思うこと
- シェル一髪で著作権のjsonファイルを作成できる
- nodeのライブラリが多すぎるとDOMレンダリングのforループでかなり時間がかかるため、そこを短縮する処理を入れる

## おわりに
- こうすればnodeライブラリの著作権情報をVueで簡単に表示できるよ、などあれば教えてください
There was a problem loading the requested app...というexpoエラー

# エラーが発生した理由
![スクリーンショット 2020-09-23 20.04.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669290/8841955d-9bc8-2ba3-e185-a2535b86c68c.png)
今回の場合では、下のメッセージを確認すると「The experience you requested requires a newer version of the Expo Client app.」と書かれており、Expo Clientアプリの新しいバージョンに更新する必要がある。

#解決方法
・iOSシュミレーターからExpoアプリ長押しで選択し、削除
・ターミナルにiを入力してiOS simulatorを起動
・iOS simulator内に自動でExpoがインストールされる

#あとがき
おそらくExpoの更新をする度にこの作業をする必要があるため、頭の片隅に置いておきたい
【自分用メモ】Dockerでつまったことを振り返る...Linuxの知識も含む

#目的
docker pushを拒否されたので、それを回避しようとしたことを振り返ります。

#結論
docker tagでイメージ名を変更したところ、docker pushできた。


docker pushしようとしてもdocker tagでイメージ名を変更しても同事象でした。
「docker ps -a」で確認すると、COMMAND欄が"python3"となっているものが複数ありました。
docker push できないのはこれが原因なのかもと思いました。
「docker ps -a」でCOMMAND欄に表示されるのはdockerコンテナのプロセス名ということが[こちら](https://qiita.com/shuntaro_tamura/items/4016868bda604baeac3c)を参考にさせて頂き、わかりました。
下記の記事を参考にプロセスをkillすればpython3から変えられるかもしれないと考えました。
[プロセスを終了するkillコマンドの使い方まとめ！【Linux ...](https://eng-entrance.com/linux-command-kill)
[【ps・kill】実行中のプロセス表示と強制終了 - Qiita](https://qiita.com/shuntaro_tamura/items/4016868bda604baeac3c)
dokcerのshell接続するとpython3になっているのは「ps -a」とコマンドを打つとPID1であることがわかりました。
PID1に対して、pkill1としてもプロセスをkillできませんでした。
[Docker で node.js を動かすときは PID 1 にしてはいけない ...](https://ngzm.hateblo.jp/entry/2017/08/22/185224)
[Docker/Kubernetes で PID 1 問題を回避する | text ...](https://text.superbrothers.dev/200328-how-to-avoid-pid-1-problem-in-kubernetes/)
上記の記事を参考にさせて頂き、PID 1 問題ということがわかり「docker run --rm -d --init」コマンドでpython3がPID 28とかPID 1 以外で起動させることができました。
「pkill 28(PID)」とかコマンドを打つと、python3のプロセスを終了させることができました。
ここで、「docker ps -a」のコマンドでCOMMAND欄を確認しましたが、"python3"の表記は消えませんでした。
[【備忘録】docker pushしたら拒否された - Qiita](https://qiita.com/shundayo/items/4ae35930fe9f85f535b0)
上記の記事を参考にさせて頂き、「docker commit」コマンドでansible-baseをインストールしたイメージを作成しました。
[コンテナイメージをDockerHubにpushして共有する ...](https://gray-code.com/blog/container-image-push-for-dockerhub/)
上記の記事を参考にさせて頂き、「docker tag」コマンドで「ユーザ名/ansible-base」という名前のイメージを作成し「docker push」することができました。
java データ型


基本データ型（※基本データ型以外は参照型）

| 型分類 |データ型  | サイズ | 表現できる範囲値 |
|:-:|:-:|:-:|:-:|
|整数|byte|8bit|-128～127|
|整数   |short|16bit|-32,768～32,767|
|整数   |int|32bit|-2,147,483,648～2,147,483,647
|整数|long|64bit|-9,147,483,648,808～9,223,372,036,854,775,807|


|浮動小数点数 |データ型   | サイズ | 表現できる範囲値 |
|:-:|:-:|:-:|:-:|
|浮動小数点数|float|32bit|IEEE754にもどづく浮動小数点表現|
|浮動小数点数|double|64bit|IEEE754にもとづく浮動小数点表現|
|文字|char|16bit|UNICODE表現1文字
|真偽値|boolean|-|ture,false|※booleanクラス型は参照型に含まれます。
booleanクラスはラッパークラスと呼ばれます。

参照型の種類
クラス型
インターフェース型
配列型
列挙型
PDOを接続とプリペアドステートメント説明

#PDOの接続方法
僕はmysqliに比べて、分かりづらかったので、PDOの接続の仕方を書いてみました。

```
<?php
try {
    $pdo = new PDO("mysql:dbname=データベース名; host=localhost; charset=utf8mb4", "ユーザー名", "パスワード");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "接続完了";
} catch (PDOException $e) {
    exit();
    echo "接続失敗";
}
?>
```
#プリペアドステートメントについて
プリペアドステートメントって、初めは分かりづらいですよね。
プリペアドステートメントとは、SQL文を最初に用意しておいて、その後はクエリ内のパラメータの値だけを変更してクエリを実行できる機能のことです。
この機能を利用することでクエリの解析やコンパイル等にかかる時間は最初の一回だけで良くなり、より高速に実行することができます。
また、SQLインジェクション対策に必要なパラメータのエスケープ処理も自動で行ってくれるため、安全かつ効率の良い開発が出来ます。

#プリペアドステートメントを利用してクエリを実行する流れ
PDOオブジェクトの作成
↓
prepareメソッドでSQL文をセット
↓
bindValue or bindParamでパラメータに値をセット
↓
executeメソッドでクエリを実行
↓
fetch or fetchAllメソッドで結果を配列で取得

#INSERTだとこんな感じで使います。
```
$stmt = $pdo -> prepare("INSERT INTO blog (title, text) VALUES (:title, :text)");
    $stmt->bindParam(":title", $_POST['title'], PDO::PARAM_STR);
    $stmt->bindParam(":text", $_POST['text'], PDO::PARAM_STR);
    $stmt->execute();
```

参考にしたサイト
[PDO prepare プリペアドステートメントの使い方](https://bituse.info/php/35)
クラス名.Classインスタンスを取得する

クラス名.Class　
と記述して、リフレクションを使うことで、実際の型がわららなくてもメソッドの読み出しやフィールドへのアクセス、インスタンスの生成などを行うことができる。


```java:Classインスタンスを取得
Class<Exception> A = Exception.class;
```


```java:インスタンスからClassインスタンスを取得する場合は、getClass()メソッドを使う
Exception instance = new Exception();
Class<? extends Exception> e = instance.getClass();
```

```java:インスタンスからClassインスタンスを取得する場合は、getClass()メソッドを使う
Class<?> e = Class.forName("java.lang.Exception");
```
取得したClassインスタンスからは、次のようにして該当クラスに関する情報を取得します。

```java:クラス情報を取得する
//Runnableインターフェイスのclassインスタンスを取得
Class<Runable> c = Runable.calss;
//インターフェイスはどうか
System.out.println(c.isInterFace()); // => true;
//アノテーションはどうか
System.out.println(c.isAnnotation()); // =>false
//配列かどうか
System.out.println(c.isArray()); // => false
//列挙型かどうか
System.out.println(c.isEnum()); // => false
//引数のインスタンスがRunnable型かどうか。
System.out.println(c.isInstance(new Thread())); // => true
//引数のクラスがRunnableのサブクラス/実装クラスかかどうか。
System.out.println(c.isAssignableFrom(Thread.class)); // => true
```

リフレクション
Classオブジェクトからフィールドやメソッドなどの情報を取得でき、
さらにそれらのフィールドやメソッドを動的に呼び出すことができる。
これをリフレクションと呼ぶ。

```java:リフレクション例
//Classオブジェクトを取得
class<?> clazz = obj.getClass();

//メソッド名と引数の型を指定してMethodオブジェクトを取得
Method method = clazz.getMethod("setName",String.class);

//setName()メソッドを呼び出し
method.invoke(obj, "taro sato");
```

参考：
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html
https://docs.oracle.com/javase/jp/7/api/java/lang/ClassLoader.html
macOS上にpydicomをセットアップするためのメモ

[公式のセットアップ手順](https://pydicom.github.io/pydicom/stable/tutorials/installation.html) はDebian系のLinux環境を前提としている部分があるため、macOS上でセットアップした際の手順を残しておく

## 環境情報

* macOS Catalina 10.15.6
* Python 3.8.5 on pyenv 1.2.20

※Anacondaは利用しない

## セットアップ手順

### pydicom

```
$ pip install pydicom
```

### Optional libraries

```
$ pip install numpy
$ pip install pillow
```

### CharPyLS

```
$ pip install cython
$ pip install git+https://github.com/Who8MyLunch/CharPyLS
```

### GDCM

Anacondaなしでは少々手間のかかる部分
[Installing the Python GDCM bindings without Conda](https://github.com/pydicom/pydicom/wiki/Installing-the-Python-GDCM-bindings-without-Conda) を参考に、Ubuntu/Debian向けの記述をmacOS向けにアレンジする

```shell
$ brew install gdcm

# インストールされた関連ファイルの場所を確認する
$ find /usr -name gdcm.py
/usr/local/lib/python3.8/site-packages/gdcm.py
/usr/local/Cellar/gdcm/3.0.7_1/lib/python3.8/site-packages/gdcm.py

$ find /usr -name "libgdcmCommon.*"
/usr/local/lib/libgdcmCommon.3.0.dylib
/usr/local/lib/libgdcmCommon.3.0.7.dylib
/usr/local/lib/libgdcmCommon.dylib
/usr/local/Cellar/gdcm/3.0.7_1/lib/libgdcmCommon.3.0.dylib
/usr/local/Cellar/gdcm/3.0.7_1/lib/libgdcmCommon.3.0.7.dylib
/usr/local/Cellar/gdcm/3.0.7_1/lib/libgdcmCommon.dylib

# pyenv環境へ関連ファイルをコピー
$ cd ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/
$ cp /usr/local/lib/python3.8/site-packages/gdcm.py .
$ cp /usr/local/lib/python3.8/site-packages/gdcmswig.py .
$ cp /usr/local/lib/python3.8/site-packages/_gdcmswig* .
$ cp /usr/local/lib/libgd* .
```

Pythonのプロンプト上で `import gdcm` してエラーが出なければOK
[JavaScript] 破壊的メソッドと非破壊的メソッド

JavaScriptの破壊的メソッドと非破壊的メソッドとはなにか、簡単にまとめようと思います。

# 破壊的メソッド（非破壊的メソッド）とは

> 破壊的メソッドとは レシーバであるオブジェクトそのものに変更を加えるメソッドのことです。
 非破壊的メソッドは、その場の実行結果のみに影響しますが、破壊的メソッドは自分自身に変更を加えてしまいます。 

以下具体例

# 破壊的メソッド①
### push() の場合

以下の例は、配列に対し直接要素を追加しています。
結果変数の値がどうなったのかがわかりにくく、バグの温床となりかねないので注意が必要です 


```js:例１
const test = ["foo", "bar"];
const result = test.push("baz");

console.log(test); // ["foo", "bar", "baz"]
```

# 非破壊的メソッド① 

### concat()
上記のpush()で行ったことを、非破壊的メソッドを使って行います

```js:例２
const test = ["foo", "bar"];
const result = [].concat(test, "baz");

console.log(test); // ["foo", "bar"]
console.log(result); // ["foo", "bar", "baz"]
```

非破壊的メソッドは元の配列 test を変更しないため、安全かつ直感的に理解がしやすいです
　　


# 破壊的メソッド②
### sort() の場合

以下の例は、配列の並び順を直接変更しています。

```js:例３
const test = [3, 2, 1];
const result = test.sort();

console.log(test); // [1, 2, 3]
console.log(result); // [1, 2, 3]
```

# 非破壊的メソッド②

上記のsort()で行ったことを、スプレッド構文を利用して非破壊的に実装できます

```js:例４
const test = [3, 2, 1];
const result = [...test].sort();

console.log(test); // [3, 2, 1]
console.log(result); // [1, 2, 3]
```

スプレッド構文で新たな配列を生成し、それに対してsort()をしているため
元の配列は変更せず、非破壊的にsort()を使用できます。


# まとめ
　
破壊的メソッドは元の変数を変更してしまうものであり、変数が今どうなっているのかをわかりにくくします。
結果的にバグの温床やコードの可読性を下げる恐れがあるため、
なるべく意識的に非破壊的メソッドを使用するのが良いでしょう。
Linuxのno_proxyでネットワークアドレスを指定する

## はじめに
Proxy環境下で検証を行っていると、特定の宛先への通信はProxyを経由して欲しくないと言う場面があります。
通信先が一意に決まっていれば良いのですが、特定のネットワーク宛の通信はProxyを通したくないと言うケースも発生するかと思います。
調べてみたところLinuxの環境変数`no_proxy`でネットワークアドレスを指定する方法が見当たらなかったので記事にさせていただきました。
※あまりに見つからなすぎて不安なので、間違い等あればコメントいただけると有難いです。

### 2020/09/23_補足（twitterで親切な方が教えてくれました）
Linuxに設定する`no_proxy`はあくまで環境変数でしかありません。
実際にはcurlやyumなどLinux上で動作するソフトウェアが`no_proxy`と言う環境変数を読み込んで動作する形になります。
なので書き方次第であるソフトウェアでは意図した通り認識してくれたけど別のソフトウェアでは意図した通り認識してくれない、なんてことも起こりえます。
以下の例で試したのはcurlによるHTTPリクエスト時に`no_proxy`設定をネットワークアドレスで読み込ませるケースなので使用するソフトウェアによっては意図した通りに読み込まないかもしれません。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">no_proxyはOSではなくソフトウェアレベルでCIDR形式を解釈してくれるかが異なるので鬼門ですね</p>&mdash; ぐるっと🔁 (@grugrut) <a href="https://twitter.com/grugrut/status/1308739768016973825?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 環境

Ubuntu 18.04.4 LTS
（CentOS 7でも同様の動きでした）

## 設定方法

自身の環境では環境変数`no_proxy`で以下のようにネットワークアドレスを指定（`192.168.2.0/24`）することで、
そのネットワーク宛通信はProxyを経由せずに行うことができているように見えました。

~/.bashrc

~~~
export http_proxy=http://proxy.example.com:8080/
export https_proxy=http://proxy.example.com:8080/
export no_proxy=127.0.0.1,localhost,192.168.2.0/24
~~~


### 参考
自身が最初に見つけた以下の記事では上記とは異なる方法でネットワークアドレスを指定していました。
ただこのやり方だと対象が多くなった場合に引数が長すぎてvimなどが起動できなくなる問題が発生してしまいます。

no_proxy にネットワークアドレスとかワイルドカードを指定しても期待通りに動かない、でどうするかというお話
https://sechiro.hatenablog.com/entry/2013/08/06/no_proxy_%E3%81%AB%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%A8%E3%81%8B%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E3%82%92
Visual Studio Codeの環境をサクッと整えるためのスクリプトを作ってみた

## Visual Studio Codeとは

Visual Studio Codeとは、Microsoftが出している高機能テキストエディタで、
無料で使うことができます。

また、拡張機能を駆使することで自分好みにできるのも強みのひとつです。

### たくさんの拡張機能

とにかくたくさんの拡張機能がたくさんあるので、
環境を作るたびにインストールするのが面倒だし、他の人に展開するのも一苦労。

### スクリプト化しよう

というわけで、自分のVSCodeに入っている拡張機能を取りまとめてスクリプト化してみた。

## Visual Studio Codeのインストール

以下から、利用中のプラットフォームに合わせてインストーラを実行する。
https://code.visualstudio.com/download

## スクリプトのダウンロードと実行

### Mac/Linuxの場合

```
$ git clone https://github.com/hikaruright/install-extensions-for-vscode.git
$ cd install-extensions-for-vscode
$ ./install_extensions.sh
```

### Windowsの場合

```
> git clone https://github.com/hikaruright/install-extensions-for-vscode.git
> cd install-extensions-for-vscode
> install_extensions.ps1
```

もし実行エラーが出る場合には、デジタル署名の設定を変更してから実施してください。

```
> Set-ExecutionPolicy RemoteSigned
```

ここで[Y]を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/2879f284-a732-0631-0009-8fa339c8a1ad.png)


## インストールされる拡張機能たち

### コード補完サポート

- Visual Studio IntelliCode
- Path Autocomplete
- Code Spell Checker

### ビジュアライズサポート

ファイルツリーにアイコンや色をつけることでわかりやすくする

- vscode-icons
- zenkaku
- Trailing Spaces
- indent-rainbow
- Output Colorizer
- Log File Highlighter
- Rainbow Brackets

簡易的なDiffツール

- Partial Diff

### Pretter

自動フォーマットツール

- Prettier - Code formatter

### Bookmark Tool

Visual Studioのブックマークツールに相当する拡張機能

- Bookmarks
- Numbered Bookmarks

### Todo

//TODO を検知してツリー化してくれる

- Todo Tree
- TODO Highlight

### Git Support

SourceTreeでできていたようなことをするための各拡張機能

- GitLens
- Git History
- Git Graph
- gitignore

### Markdown Support

Markdownを書くための拡張機能群
MarkdownPDFを利用すると簡単にPDF化できるので便利。

- Markdown All in One
- markdownlint
- Markdown PDF

### CSV Editor

CSVをExcelっぽいテーブルで編集できる神拡張機能

- Edit csv

### Remote Development

Docker/SSH/WSLへのリモート開発がセットになった便利な拡張機能。

- Remote Development

### Live Share

Visual StudioおよびVisual Studio Codeで使える最強の拡張機能であるLive Share。
これは入れないわけにはいかない

- Live Share Extension Pack

### その他言語・FWサポート

その他、各言語や環境に関する拡張機能を追加しています。

- C#
- C++
- Java
- Spring Boot
- Kotlin
- Python
- Nim
- Dart
- HTML(CSS)
- TypeScript
- Angular
- Re:VIEW
- API
    - Rest Client
    - Swagger
- SQL


不要なら相当する部分をスクリプトから外した方がいいかもしれませんね。

## さいごに

Visual Studio Codeを使いたいけど何入れたらいいのか分からない人はぜひご参考にしてみてください。


Have a nice Developer Life!

## Special Thanks

色々と参考にさせていただきました。

https://qiita.com/Kosen-amai/items/03632dee2e1694652f06
https://qiita.com/Midoliy/items/d19dc8c1c97078b1e640
YOLOを利用した物体検出（python）（【高等学校情報科 情報Ⅱ】教員研修用教材）

# はじめに

YOLO(You Only Look Once)とは、その名の通り人間のように一度見ただけで物体の認識・検出をしてしまうという画期的なアルゴリズムです。
従来の手法に比べて、処理が高速であり物体と背景の認識の区別に強く、汎用化しやすいという特徴を持っています。
今回は、教材内でTiny YOLOとRを使って物体検出を行っている個所を、YOLOとpythonを使用して写真上の物体の検出を行っていきます。

# 教材

[高等学校情報科「情報Ⅱ」教員研修用教材(本編)：文部科学省](https://www.mext.go.jp/a_menu/shotou/zyouhou/detail/mext_00742.html "高等学校情報科「情報Ⅱ」教員研修用教材(本編)：文部科学省")
[第3章 情報とデータサイエンス 後半 (PDF:7.6MB)](https://www.mext.go.jp/content/20200609-mxt_jogai01-000007843_007.pdf "第3章 情報とデータサイエンス 後半 (PDF:7.6MB)")

# 環境

- ipython
- [Colaboratory - Google Colab](https://colab.research.google.com/notebooks/welcome.ipynb "Colaboratory - Google Colab")

# 教材内で取り上げる箇所

> 学習18 テキストマイニングと画像認識：「3.TinyYOLOを利用した物体検出」

# pythonでの実装例と結果

今回は、darknetをgithubのリポジトリからclone（コピー）し、YOLOv3の学習済み重みデータyolov3.weightsを使用して、画像認識を行います。
今回はpythonでの実装例と書いてありますが、darknetでYOLOv3を動かすためコマンドの実行を中心に行い、なるべく自前でコーディングしないような形で物体検出できるようにしていきたいと思います。

```python
!git clone https://github.com/pjreddie/darknet
```

実行結果は以下のようになりました


```console
Cloning into 'darknet'...
remote: Enumerating objects: 5913, done.
remote: Total 5913 (delta 0), reused 0 (delta 0), pack-reused 5913
Receiving objects: 100% (5913/5913), 6.34 MiB | 9.93 MiB/s, done.
Resolving deltas: 100% (3918/3918), done.
```

git cloneできたので、darknetディレクトリ配下に移動し、makeを実行します。

```python
import os

os.chdir('darknet')
!make
```

makeが完了したら、YOLOv3の学習済み重みデータyolov3.weightsを同じディレクトリにダウンロードしておきます。今回はwgetコマンドを使用しました。

```python
!wget https://pjreddie.com/media/files/yolov3.weights
```

本題の、YOLOで物体検出をさせたいと思いますが、今回はdataディレクトリ内のgiraffe.jpgを使用して、物体検出をしてみたいと思います。

```python
!./darknet detect cfg/yolov3.cfg yolov3.weights data/giraffe.jpg
```

```console
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 conv     64  3 x 3 / 2   608 x 608 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    2 conv     32  1 x 1 / 1   304 x 304 x  64   ->   304 x 304 x  32  0.379 BFLOPs
    3 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64  3.407 BFLOPs
：
  103 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
  104 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  105 conv    255  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 255  0.754 BFLOPs
  106 yolo
Loading weights from yolov3.weights...Done!
data/giraffe.jpg: Predicted in 19.677707 seconds.
giraffe: 98%
zebra: 98%
```

キリン(giraffe)とシマウマ(zebra)が検出できました。
実際の検出された画像を見てみましょう。

```python
from IPython.display import Image

Image("predictions.jpg")

```
![無題01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677025/a26fe899-052e-3fef-5c98-c9c009f7e33c.png)

うまく検出できました。

#ソースコード

https://gist.github.com/ereyester/46a25e70c866c581320a66a77153aa2d