OmniAICreator/Qiita-1.07M huggingface dataset:
VPSを借りる [PHP] #3

#PHP
[※How to Install PHP on CentOS 8](https://linuxize.com/post/how-to-install-php-on-centos-8/)

```sh
DOMAIN=yourdomain

sudo dnf install @php php-opcache php-gd

php -v

sudo systemctl enable --now php-fpm

sudo cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.origin
sudo sed -i -e "s/^user = apache/user = nginx/g" /etc/php-fpm.d/www.conf
sudo sed -i -e "s/^group = apache/group = nginx/g" /etc/php-fpm.d/www.conf
diff -u /etc/php-fpm.d/www.conf.origin /etc/php-fpm.d/www.conf

sudo chown -R root:nginx /var/lib/php
sudo systemctl restart php-fpm

sudo tee /var/www/$DOMAIN/public_html/index.php << EOF
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Welcome to $DOMAIN</title>
  </head>
  <body>
    
    <?php echo '<h1>Success! $DOMAIN home page! written in PHP!</h1>'; ?> 
  </body>
</html>
EOF

sudo tee /var/www/$DOMAIN/public_html/phpinfo.php << EOF
<?php
    phpinfo();
?>
EOF

sudo tee /var/www/$DOMAIN/public_html/mbinfo.php << EOF
<?php
    print_r(mb_get_info());
?>
EOF

sudo chown -R nginx: /var/www/$DOMAIN
sudo restorecon -RF /var/www/$DOMAIN/public_html/

sudo tee /etc/nginx/conf.d/$DOMAIN.conf << EOF
server {
    listen 80;
    listen [::]:80;

    server_name www.$DOMAIN $DOMAIN;

    include snippets/letsencrypt.conf;

    location / {
        return 301 https://\$host\$request_uri;
    }
}

server {
    listen 443 ssl http2;

    server_name www.$DOMAIN $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/$DOMAIN/chain.pem;

    include snippets/ssl.conf;

    root /var/www/$DOMAIN/public_html;

    index index.php;

    access_log /var/log/nginx/$DOMAIN.access.log;
    error_log /var/log/nginx/$DOMAIN.error.log;

    location ~ \.php\$ {
        try_files \$uri =404;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
    }
}
EOF

sudo nginx -t

sudo systemctl reload nginx
systemctl status nginx
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662099/5210e650-5d9a-f7f4-756f-e3b7f81c4cbd.png)
[VPSを借りる [VPS、SSH、Nginx] #1](https://qiita.com/u4xi/items/850b98f56d058b552ab0)
[VPSを借りる [HTTPS] #2](https://qiita.com/u4xi/items/f373f21cb7e1b670eaff)
ARCoachingOverlayView の日本語化

ARKit3 で追加された`ARCoachingOverlayView`のローカライズに手間取ったのでその記録です。

# 問題の現象
文言が英語になっている。
![en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71605/8007fcd0-49bf-883d-7ca5-d19491dbea67.png)

# 解決策
projectの設定で`Localications`に`Japanese`を追加する。
![setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71605/b57247f7-104d-7ae2-f28f-049dc2f7a6b5.png)

# 結果
日本語でも表示される。
![ja.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71605/a4cabc97-adfe-8026-291e-c52f5dae8f50.png)
k8s でクラスターに新しいノードをジョインしようとしたときのエラー解決備忘録



## 出たエラー

```
root@mypc:~# kubeadm join 192.168.100.26:6443 --token g3s13m.9qvsa9soy0rmbsbs \
>     --discovery-token-ca-cert-hash 
```

を実行した際の、

```
sha256:45185204ceb8ad96044814da5c60d2021d85c029d251757215dfd059421bc9f6
[preflight] Running pre-flight checks
	[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
	[ERROR Port-10250]: Port 10250 is in use
	[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists

```

のエラー

## 解決策

単純に、kubeadm を使ってcontrol plane などの全ての設定をリセットしたのち、もう一度ジョインをする。

```
kubeadm reset
```
2020/10/4朝アウトプット

#Rails ライブラリ導入　復習
- ライブラリとは複雑なプログラムを1つのセットにしたもの。複雑な機能実装でも、ライブラリをアプリに読み込ませることで簡単に実装できる
- RubyGemsとはRubyのライブラリを管理するシステム
- GemとはRubyGemsの中の一つ一つのライブラリ
- Gemfileとは、アプリケーションで使用するGemのGem名とバージョンを記載し、管理するファイル
- Gemfile.lockとは、bundle install済みのGemを記録するファイルのこと

#ツイートの表示　復習
- モデルの作成、rails g model ~
- マイグレーションの編集、マイグレーションの実行、rails db:migrate
- ローカルサーバー再起動、rails s
- コンソール起動、rails c,コンソールでデータ追加、シークエルで確認
- indexアクションのルーティングを設定する
- CRUDとはCreate生成、Read読み取り、Update更新、Delete削除の頭文字
- 7つのアクション→index,show,new,create,edit,update,destroy
- resourceメソッドとは７つのアクションへのルーティングを自動生成するメソッド
- 引数に:tweetsというシンボルを指定すると/tweetsのパスに対応するルーティングが生成される
- onlyオプションとはresourcesにオプションとしてonlyを加えると、指定したアクションのみのルーティングを自動生成してくれる
- コントローラー作成rails g controller ~　→indexアクションをコントローラーに定義
- ツイート内容をeachメゾットでビューに表示する
OpencvとPythonで監視カメラ(SecurityCamera)を作る方法

#0.最初に
今回作るものがどういう感じで動くのか見てみたい方は、[こちら](https://youtu.be/jzBMxd5ZTeI)(youtubeの動画)でどうぞ。
#1.処理を書く
```security_cam.py
import cv2
from datetime import datetime
import requests
import time

token = 'Your Token'

cap = cv2.VideoCapture(0)
lastframe = None

def send_msg():
    url = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization':'Bearer '+token}
    data = {"message":"Someone in your room."}
    image = '/home/igor-bond/image.jpg'
    file = {'imageFile': open(image, 'rb')}
    r = requests.post(url, headers=headers, params=data, files=file,)
    
while cap.isOpened():
    ret,frame = cap.read()
    if ret == True:
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

        if lastframe is None:
            lastframe = gray.astype("float")
        
        cv2.accumulateWeighted(gray,lastframe,0.6)
        frame_diff = cv2.absdiff(gray,cv2.convertScaleAbs(lastframe))
        thresh = cv2.threshold(frame_diff,3,255,cv2.THRESH_BINARY)[1]
        contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

        for c in contours:
            if cv2.contourArea(c) > 30:
                time.sleep(0.2)
                now = datetime.now()
                img = cv2.resize(frame,(int(frame.shape[1]*0.5),int(frame.shape[0]*0.5)))
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(img,f'{now}',(100,350),font,1,(0,0,255),4,cv2.LINE_AA)
                cv2.imwrite('/home/igor-bond/image.jpg',img)
                send_msg()
                lastframe = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY).astype("float")
                break

        cv2.imshow('frame',frame)  
           
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cv2.destroyAllWindows()
cap.release()
```
最初の関数はラインに画像を送るやつで以前も紹介したことがあるのでここでは割愛します。[ここ](https://youtu.be/k0Y0jSMC4ZM)(youtubeの動画)でも紹介しています。そして今回はフレーム間の違いを求めてそこで画素値が3以上のものはそれを255にしてそこで輪郭を求めてある一定の面積をこえた輪郭があれば動いたとみなす。これはとても小さな変化も検出してしまうのでそれを防ぐためです。そして、監視カメラっぽくなるように右下に時刻を付け加えて画像として保存します。画像の名前を変えていないのは変えると画像がたくさんたまってしまい、今回は保存したあとすぐにラインに送る関数を発動して送信しているのでこうしても問題がないためです。最後にその時のフレームを一番最後のものとしてこれを繰り返します。
#最後に
この監視カメラの作り方は[Youtube](https://youtu.be/jzBMxd5ZTeI)でも解説しているのでぜひそちらもご覧ください。質問やアドバイスなどがあればぜひコメントしてください。
nginxでBASIC認証をかけてみる

# 概要

さくらVPSでWebアプリケーション開発をしようかと準備しておりまして、
誰でもアクセスできる状態だと困るな〜ということで、BASIC認証をかけることにしました。

# BASIC認証の設定

BASIC認証をかけるには、`htpasswd`コマンドで`.htpasswd`ファイルを作成する必要があります。
なので、まずはそのコマンドが使えるように`httpd-tools`をインストールします。

```shell-session
# yum -y install httpd-tools
```

次に、以下のコマンドを実行して`.htpasswd`ファイルを作成します。
一応、今回はnginxを利用するため、nginxっぽいディレクトリ内にファイルを配置します。

```shell-session
# htpasswd -c -b /etc/nginx/.htpasswd {username} {password}
```

最後にnginxの設定ファイルに上記で作成した.htpasswdファイルを利用するBASIC認証の設定を追加して、
nginxのサービスを再起動すればBASIC認証の設定が完了です。

```conf:/etc/nginx/conf.d/default.conf
    location / {
      # 指定された順序でfileやdirの存在を確認し、最初に見つかったものを返却する。
      # いずれも無かった場合は、最後に指定されたパスに遷移する。
      try_files $uri $uri/ /index.php$is_args$args;

      # 以下２行の設定を追加します。
      auth_basic "Restricted";
      auth_basic_user_file /etc/nginx/.htpasswd;
    }
```

サイトにアクセスするとBASIC認証がかかっていることが確認できます。

![スクリーンショット 2020-10-04 7.05.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/052bee56-3717-3cdf-f981-5e0a1c399211.png)
Railsの環境構築でつまづいたのでメモ

Rails girlsでrailsの環境構築していところ
3-4. rbenvを使ってRubyをインストール:
でつまづいたのでメモ

``` ターミナル 
$rbenv install 2.7.0
```
とコマンドを打つと

```ターミナル 
The following versions contain `2.7.0' in the name:
  2.7.0-dev
  jruby-9.2.7.0
See all available versions with `rbenv install --list'.
If the version you need is missing, try upgrading ruby-build:
  cd /Users/ユーザー名/.rbenv/plugins/ruby-build && git pull && cd -
```
そんなのねーよとでてしまう。

```ターミナル 
rbenv install --list
```
で確認すると

 ```ターミナル
  2.6.0
  2.6.1
  2.6.2
  2.6.3
  2.7.0-dev
  jruby-1.5.6
  jruby-1.6.3
 ```

確かにない

```ターミナル
brew upgrade ruby-build
```

をしてみても同じエラーが出る。
最初のエラー文をよくみると

 ```ターミナル
 cd /Users/ユーザー名/.rbenv/plugins/ruby-build && git pull && cd -
```

わざわざするべきことを書いていてくれた。
なので

```ターミナル
 cd /Users/ユーザー名/.rbenv/plugins/ruby-build
git pul
rbenv install 2.7.0
```

と打つと

```ターミナル
Installed ruby-2.7.0 to /Users/ユーザー名/.rbenv/versions/2.7.0
 ```

できた。
flutter run - 起動ができない

# ある日突然"flutter run"が出来なくなった。。。
なんでなにもしてないのに起動ができないんだ！！
（パソコンを使用してるいるので、何かしてエラーがでています・・・w）

## 利用環境
Mac OS
vs code

## 該当エラーコード
```エラー.log
ihone X

Could not build the application for the simulator.
Error launching application on iPhone X.

flutter-project/build/ios/Debug-iphonesimulator/path_provider/path_provider.framework: 
resource fork, Finder information, 
or 
similar detritus not allowed
Command CodeSign failed with a nonzero exit code
note: Using new build system
note: Planning build
note: Constructing build description
```
## 書くのが面倒くさくなったので解決方法のみ書きます。。
以下のエラーコードが重要です
### resource fork, Finder information,
↑finder info? resource fork ?
なんだろう・・・？

similar detritus not allowed
ゴミ・・・？

Command CodeSign failed with a nonzero exit code
とりあえず、認証でこけてますよー。エラー

```エラー.log
resource fork, Finder information, or 
similar detritus not allowed
Command CodeSign failed with a nonzero exit code
```

## 認証 and 環境確認

再び環境確認したところ、flutterプロジェクトがクラウド(i cloudなど)と同期されてしまい、認証系のところでこけていたみたいです。

解決策としては、同期を消すか同期外の所でプロジェクトを作るのがいいです。

## この経緯に至った方法

1.エラーログを読みまくる
2.英語で検索
3.内容を理解
4.同じ事をしていて出ていない人の環境と自分の環境のディフチェックをする
ASP.NET Core 3.1 のコントローラーを別プロジェクトの .NET Core クラス ライブラリで定義する 

# はじめに

ASP.NET Core で、複数の Web サイトで共通的に使用する Web API を別の .NET Core クラス ライブラリ プロジェクトで定義して、再利用できるようしたいことがあります。

ASP.NET Core 2 系では、Nuget に、Microsoft.AspNetCore.Mvc.Controller を含むパッケージがあったので、これを追加して、参照して、継承して、MVC のコントローラーを定義できました。

ASP.NET Core 3.1 では、やり方がことなるので、これを説明します。

# Microsoft.AspNetCore.App の参照設定

[クラス ライブラリ(.NET Core)] を選択して、プロジェクトを作成します。
![クラス ライブラリ(.NET Core)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/90221c97-b361-e592-e4a9-8c601e836c98.png)

当然、この時点だと、Microsoft.AspNetCore.App への参照がありません。
![ソリューション エクスプローラー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/f7e66756-b7b2-3d45-488c-54cbea3206fe.png)

Nuget パッケージ マネジャーで、Microsoft.AspNetCore を追加しようとしてみましたが、、、Version 3.1 系が見つかりません。
![NuGet](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/72c9e1f2-cbc5-f21c-2710-d922f8ae1f58.png)

色々と調べて、以下のサイトにたどり着きました。

- [Reference IEndpointRouteBuilder in a class library (ASP.NET Core 3.1) #19481
](https://github.com/dotnet/aspnetcore/issues/19481)

このサイトのやり取りによると、.csproj に直接、フレームワークへの参照として Microsoft.AspNetCore.App を追加するとあります。

```xml:.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
  
</Project>
```

すると、[ソリューション エクスプローラー] - [依存関係] - [フレームワーク] に、Microsoft.AspNetCore.App が追加されます。
![ソリューション エクスプローラー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/8a159e4a-f3b0-5f14-f7a3-637091758e24.png)

これで、.NET Core クラス ライブラリプロジェクトで、Microsoft.AspNetCore.Mvc.Controller が参照できるようになり、継承して、MVC のコントローラーが定義できるようになります。

```SharedController.cs

using Microsoft.AspNetCore.Mvc;

namespace AspNetCoreClassLibrary001
{
    public class SharedController : Controller
    {
        [HttpGet("api/Hello/{yourName}")]
        public ActionResult Hello(string yourName)
        {
            return Content($"Hello, {yourName}!!");
        }
    }
}
```
このコードを実行した結果は以下となります。
![Hello](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/e228316f-a099-4320-7447-acb319207c47.png)
CentOS 8でmod_auth_casを使う

# イントロ
CAS認証をほどよく愛する私としては、CentOS 8（およびRHEL 8）環境で、これまでCentOS 6、CentOS 7ではEPELリポジトリで提供されていた**mod_auth_cas**が無くなっているそうで悲しんでます。

現時点ではrpmを拾ってきてインストールすることは無理そうなので、仕方ないので自前ビルドすることにします。

# やりかた
以下のサイトにある説明をベースに、CentOS 7で ``# yum install mod_auth_cas`` した時の環境に合わせて変更しています。
https://iam.uconn.edu/mod_auth_cas-installation-and-configuration/

## 下準備
```
# yum install httpd httpd-devel
# yum install gcc libcurl-devel openssl-devel pcre-devel
# yum install autoconf automake make libtool redhat-rpm-config
# yum install wget tar
```

## ビルド
```
# cd /usr/local/src
# wget https://github.com/apereo/mod_auth_cas/archive/v1.2.tar.gz
# tar xvzf v1.2.tar.gz
# cd mod_auth_cas-1.2
# autoreconf -iv
# ./configure --with-apxs=/usr/bin/apxs
# make
# make check
# make install
```

## httpd用設定
```
# mkdir /var/cache/httpd/mod_auth_cas
# chown apache:apache /var/cache/httpd/mod_auth_cas

# vi /etc/httpd/conf.d/auth_cas.conf
LoadModule auth_cas_module modules/mod_auth_cas.so
CASCookiePath /var/cache/httpd/mod_auth_cas/
CASCertificatePath /etc/pki/tls/certs/ca-bundle.crt
CASLoginURL https://sso.yourdomain/cas/login
CASValidateURL https://sso.yourdomain/cas/serviceValidate

# systemctl restart httpd
```

## .htaccessの設置
```
# vi /var/www/html/.htaccess
AuthType CAS
Require valid-user
```

## SELinuxへの対応
SELinuxが有効な場合は、CAS認証後に401エラーになるため、 SELinuxをEnforcingで利用する場合は、一度エラー画面を確認した後で以下を実行します。

```
# yum install policycoreutils-python-utils
# grep "httpd" /var/log/audit/audit.log | audit2allow --module=mod_auth_cas -all

module mod_auth_cas 1.0;

require {
        type http_port_t;
        type httpd_t;
        class tcp_socket name_connect;
}

#============= httpd_t ==============

#!!!! This avc can be allowed using one of the these booleans:
#     httpd_can_network_connect, httpd_graceful_shutdown, httpd_can_network_relay, nis_enabled
allow httpd_t http_port_t:tcp_socket name_connect;


# grep "httpd" /var/log/audit/audit.log | audit2allow --module=mod_auth_cas -all
# semodule -i mod_auth_cas.pp
```
[Swiftui]A画面→B画面でA画面のメソッドをコールする

タイトルの通り、呼び出し元A画面からB画面をNavigationLinkで遷移してB画面を開いているところから、A画面のメソッドを呼びたいときの方法です。
ここら辺はinterfaceの概念でlistenerの仕組みを使うと呼び出すことができます。
この考え方はjavaなどのレガシー言語と考え方は同じ。
もしこの考えを知らない人は勉強しなおしてください。

要点がわかるように最小限のコードサンプルです。

```
protocol Listener {
    func method()
}

struct ContentView: View, Listener {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: NextView(listener: self)) {
                    Text("next view")
                }
            }
        }
    }
    
    func method {
        // do-something
    }
}

struct NextView: View {
    var listener: Listener
    var body: some View {
        Button(action: {
            self.listener.method()
        }) {
            Text("first view method call")
        }
    }
}

```
binding.pry中にメソッドの定義されているソース位置を知りたい時にやること

### 序

rubyのコードを読んでいるときに

- implicitな部分についての知識が足りなさすぎる
- 複雑すぎてよくわからない

ときはデバッガを使います。

しかし、メソッドにstep inしたいのに、そのメソッドの引数だと思っていた記述が実はまたべつのメソッド呼び出しで、コールツリーがよくわからなくなったりすることがまれによくありました。

そんなときに、`class Method` に生えている [source_location](https://docs.ruby-lang.org/en/2.7.0/Method.html#method-i-source_location
) メソッドを使えば良いことにようやく思い至ったのでメモしておきます。

### 破

rspec 実行時、 `ActiveSupport::Cache::RedisCacheStore` で使われるredis clientをモックに差し替えようとしたが、`with`というメソッドが無くて落ちてしまう原因を調査する例。

[345行目](https://github.com/rails/rails/blob/fbe2433be6e052a1acac63c7faf287c52ed3c5ba/activesupport/lib/active_support/cache/redis_cache_store.rb#L344)の redis.with で method_missing になる。
redis の gem を見ても `with` は定義されていないっぽい。
なんだろう。

```
From: /bundle/gems/activesupport-6.0.3.2/lib/active_support/cache/redis_cache_store.rb:344 ActiveSupport::Cache::Strategy::LocalCache#read_entry:

    339:         # Store provider interface:
    340:         # Read an entry from the cache.
    341:         def read_entry(key, **options)
    342:           failsafe :read_entry do
    343:             binding.pry
 => 344:             raw = options&.fetch(:raw, false)
    345:             deserialize_entry(redis.with { |c| c.get(key) }, raw: raw)
    346:           end
    347:         end
    348:
    349:         def read_multi_entries(names, **options)
```

モック差し替えをやめ、再実行して、ソースを表示してみる。

```
[1] pry(#<ActiveSupport::Cache::RedisCacheStore>)> redis.method(:with).source
=> "      def with\n        yield self\n      end\n"
```

なんだこのメソッド。
そんなとき `source_location`！

```
[2] pry(#<ActiveSupport::Cache::RedisCacheStore>)> redis.method(:with).source_location
=> ["/bundle/gems/activesupport-6.0.3.2/lib/active_support/cache/redis_cache_store.rb", 24]
```

ここか。
https://github.com/rails/rails/blob/fbe2433be6e052a1acac63c7faf287c52ed3c5ba/activesupport/lib/active_support/cache/redis_cache_store.rb#L24-L26

`ConnectionPoolLike` をincludeして`Redis`にパッチをあてることで、使い勝手を揃えているのかぁ。
モックで差し込むredis clientにも `ConnectionPoolLike` をincludeしないとだめかなぁ。
ActiveSupportの実装が変わったら、ちゃんと追従できるかなぁ。

みたいな。

### Q

いろんなところでクラスが開かれて動作を変えられちゃうと、ソースを読むだけだと気が付きにくいこともありますよね。
完。
real-time-Personal-estimation（システム導入編）

## はじめに
基本的には,https://github.com/S-mishina/Personal-estimation
の続きのプログラムを書いていきます.
## 環境について

未定

windows10
python v3.8.3
virtualenv
yolov5 https://github.com/ultralytics/yolov5

anaconda

## システム導入について（Yolo5導入について）
pythonの仮想環境
いろいろ吟味して今のところvirtualenvを使う予定です.
⓵virtualenvの導入
```pip install virtualenv
```
⓶仮想環境の導入
(1)適当なディレクトリに行く
```python -m virtualenv py3env
```
(2)PowerShellでの切り替え
```cd hogehoge/py3env/Scripts/
```
```./activate.ps1
```
これで仮想環境に入れます.
参考にしたサイト
https://www.python.jp/install/windows/virtualenv.html
⓷Yoloの導入
yolo5を導入するためにはPyTorchが必要らしい.
自分が入れたコマンドを下記に示すが,各自の環境を以下のURLを参考に
入れたほうが良い
https://pytorch.org/get-started/locally/#mac-anaconda
(1)PyTorchの導入
```pip install torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
```
(2)yolov5の導入
ついにきましたyolo.yoloを導入していきます.
```pip install -qr requirements.txt
```
導入について参考にしたサイト
https://konchangakita.hatenablog.com/entry/2020/08/17/220000
## 動作の確認
webカメラで動作を確認しました.
実行コマンド
```python detect.py --source 0
```
プログラムの編集で下記を直すと動きます.
```            cap = cv2.VideoCapture(1 if s == '0' else s)#変更後
              #cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)#元のコード
```
参考にしたサイト
https://qiita.com/SatoshiGachiFujimoto/items/cb586b255eb220fdd8aa

## 最後に
次は学習フェイズに移ります.
ありがとうございました.
sql union

UNION ALL:  結果に重複行が含まれる場合、重複行は除外されず、条件を満たすすべての行が戻されます。

UNION [DISTINCT]: 結果に重複行が含まれる場合、重複行は除外されます

基本
https://www.sejuku.net/blog/74750

列(カラムがなければasで出力させればok)
union 使いところ
https://note.com/junmaeda/n/n1386f6ea3f61

union
https://sql.analytics-and-intelligence.net/sql-union/
機械学習で自分の歌声を色々な楽器音に変換できるTone Transfer

Googleの機械学習音楽プロジェクトMagentaから新しいウェブアプリの登場です。



**Tone Transfer**
https://sites.research.google/tonetransfer

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/cae1b15a-74c8-89cd-99a1-aa69e9708cfb.png)

##Tone Transferとは
Tone Transferは、歌声や楽器音、その他あらゆるオーディオデータを他の楽器の音に変えるという、機械学習だかこそ実現できる新しいコンセプトの高度なプログラムとなっています。
文字で解説するよりもまずは動画でどんな事が行えるのか見てみましょう。
自分の歌を、フルート、サックス、トランペット、ヴァイオリンという４つの楽器音に変換してみます。

歌って変換実践してみたYouTube動画のリンクです
https://youtu.be/VILpOU5wJFI

録音はPCのマイクから行っていますが問題なく変換可能でした。
標準で用意されている入力用のサンプルでもわかりますが、歌声や楽器音だけでなく、手拍子や雑音など、音程のない音でも変換でき、それらしくもユニークな演奏になる様です。
注意点としては、入力オーディオは単音のみ認識で和音は不可です。
単音の歌などは問題ないですが、ピアノやギターで和音演奏は意図した通りの変換が行われません。
それでは実践方法を簡単に解説していきます。


##１・まずは用意されているサンプルで視聴
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/eb3b72fc-fbce-0802-c470-799d66a33125.png)
サンプルは入力（変換元）が６種類、変換用楽器が上述したフルート、サックス、トランペット、ヴァイオリンの４種類用意されています。
どんな事ができるのか？まずは視聴をしてみてください。
自分の歌声など新たなレコーディングは入力の最下列にあるAdd your inputをクリックします。


##２・自分の歌をレコーディング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/dffda9dc-4ea0-c4e0-4f8b-fd29e1f9950a.png)
Recordボタンで録音開始です。
他に既存のオーディオファイルをUploadボタンでアップロードし使用する事もできます。
気に入ったメロディー以外に、ドラムループや特殊音などをアップするのもあり得ない効果が出て面白いかもしれません。

##３・変換
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/c8edc529-50e0-3185-9e27-21d30796d124.png)
録音またはアップロードが完了するとTransformボタンが現れますのでクリックして変換を行います。
少し待つと変換が完了しますので左側のTransformationから楽器を選んで視聴する事ができます。
再生ボタンの脇にコントロール機能もあり、原音、変換のミックス量やオクターブなどを調整できるので色々試すと新たな楽器音を作る事などもできるかもしれません。

##Pythonで希望の楽器音を使用した独自モデルの作成も可能です
今回のTone Transferはウェブアプリのため、TensorFlowおよびMagentaのjs（JavaScript）版です。
それ以外にTone Transferの元となったDDSP: Differentiable Digital Signal ProcessingというPython版プログラムのコードも公開されており、これを使用すると希望の楽器音を使用した独自モデルの作成も可能です。



**DDSP: Differentiable Digital Signal Processing**
https://github.com/magenta/ddsp
　

**インストールのコード**

```
sudo apt-get install libsndfile-dev
pip install --upgrade pip
pip install --upgrade ddsp
```

 　
**Process実践コード**

```
import ddsp

# Get synthesizer parameters from the input audio.
outputs = network(audio_input)

# Initialize signal processors.
additive = ddsp.synths.Additive()
filtered_noise = ddsp.synths.FilteredNoise()
reverb = ddsp.effects.TrainableReverb()
spectral_loss = ddsp.losses.SpectralLoss()

# Generate audio.
audio_additive = additive(outputs['amplitudes'],
                          outputs['harmonic_distribution'],
                          outputs['f0_hz'])
audio_noise = filtered_noise(outputs['magnitudes'])
audio = audio_additive + audio_noise
audio = reverb(audio)

# Multi-scale spectrogram reconstruction loss.
loss = spectral_loss(audio, audio_input)
```

この辺りのコードの詳細は運営している音楽AIアカデミーでいずれ解説できればと思っています。
筆者は元（現役？）のギタリストでもあるのでギターに変換できるモデルの作成がまず思いつきますが、各種シンセ音などを使用し、電子音楽に実践的に使用するなども面白いと思いかもしれません。

##最後に
GoogleのMagentaチームは長い時間をかけた待望のリリースである事、や、今後さらなる進化を匂わせる様なコメントをしています。
力を入れて行きたいという意思の現れでしょうか。
筆者も機械学習の音楽活用は単純な音楽生成よりも音響関連、あるいは両方の融合の方が可能性があると感じており、今後の展開を非常に楽しみにしています。
Oculus Questからスクリーンショット画像や録画動画を取り出す方法

[公式サイトのFAQ](https://support.oculus.com/2255729571307786/?locale=ja_JP) にやり方は書いてある。USB2.0ポートを利用するなら USB 2.0/USB-Cケーブル、これを用意しておく。USB-Cポートが利用しているマシンにあれば、同梱のUSB-Cケーブルでも大丈夫。そしてもちろんOculus Link対応のものでもOK。

自分が動作確認済みのものとして、

- [Rampow USB Type C ケーブル【3m/黒/保証付き】Oculus Link対応 USB3.0規格 usb-c タイプc ケーブル 急速充電 QuickCharge3.0対応 Sony Xperia XZ/XZ2,Samsung Galaxy S9/S8/A3/A7/A9/C5/7pro/C9,iQOS(アイコス),Nexus 5X/6P,GoPro Hero 5/6 アンドロイド多機種対応 3A急速充電 5Gbps高速データ転送](https://www.amazon.co.jp/gp/product/B081N1W39Y/)
- [Newzerol For Oculus Link ケープル 総計8メートル Oculus Quest PC接続用 3A 5Gbps 【3.2 Gen 1 A to C 3M + 5M 延長用 リレーアンプチップ付き】コンピュータ対応 steam オキュラス クエスト VR用](https://www.amazon.co.jp/gp/product/B083JV8SY3/)

3メートル、8メートルそれぞれこれらがオススメ。Ouclus Linkの対応は対応を謳ってても偽物や動作しないものも沢山あるので要注意。

まず **Oculusアプリで開発者モードをオフにしておく！** これが一番重要。デフォルトではオフになっている。設定タブ > Oculus Quest > その他の設定 > 開発モード、で設定可能。 

![スクリーンショット 2020-10-04 021404.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382/4f735b48-e68b-92e8-a292-a49357939ad3.jpeg)


Windowsの場合、PCとOculus Questをケーブルでつなぎ、一旦ゴーグルをかぶってデータアクセスを許可するとデバイスとして認識される。動画なら `Quest\内部共有ストレージ\Oculus\VideoShots` 画像なら、 `Quest\内部共有ストレージ\Oculus\Screenshots` にアクセスするだけで良い。

![スクリーンショット 2020-10-04 021758.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382/6c711e13-df03-6ce2-07fa-bd65b5d6e96a.jpeg)

Macの場合、[Android File Transfer](https://www.android.com/filetransfer/) をインストールする必要がある。ケーブルでつないだあとアプリを起動することで利用できる。パスはWindowsと同様、 動画なら`Quest\内部共有ストレージ\Oculus\VideoShots` 画像なら、 `Quest\内部共有ストレージ\Oculus\Screenshots` にアクセス。

![スクリーンショット 2020-10-04 021509.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382/a08b56d1-f142-9d21-9ddc-34d5bd458db7.jpeg)


ちなみにルートフォルダはこんな感じになっているが、いろいろなアプリのセーブデータやリソースデータも触れる。ただこれをいじるとといろいろぶっ壊れそうなので要注意。

![スクリーンショット 2020-10-04 021659.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382/4e829994-85e0-c907-3d8b-0b96f19298c9.jpeg)

では良いOculus Questライフを！

### トラブルシューティング

- うまくフォルダがエクスプローラーなどに表示されないときは、スマホで開発者モードがオンになってしまってないかチェック
- USBを接続した際に、USB接続確認ダイアログが出なくなってしまった際には、「設定」→「システム」→「開発者」のUSB接続ダイアログをオンにするとまたダイアログが出るようなる
- ケーブルが断線していたり、ケーブルの転送スピードがでないとエクスプローラーがうまく表示されないことがあるので、Oculusソフトウェアの接続テストで2.5Gbps以上出ているかを確かめるのも手。もし転送スピードが出ない際には違うケーブルを試した方が良い。
PythonでHMACをBase64にする

# 目的

PythonでメッセージをHMACで暗号化して、それをBase64形式にする方法です。
Rest通信でHMACをBase64にする必要があったので試した。

# サンプル

今回はHMACsha256形式で暗号化しました。
暗号化形式を変えたい場合は、```hmac.new```の引数```digestmod=hashlib.sha256```を変更します。

```python

import hashlib
import hmac

SECRET_KEY = "abcdefghijklnmopqrstuvwxyz0123456789" # 任意のシークレットキー
message = "Hello World!!!!!"  # 任意のメッセージ

hmac_message = hmac.new(key=bytes(SECRET_KEY, 'UTF-8'), msg=message.encode('utf-8'), digestmod=hashlib.sha256).digest()
hmac_message_base64 = base64.b64encode(hmac_message).decode()
```
ArgumentError in TasksController#updateの解決

## まずはgiven0,expected1の部分が引数の数があっていないエラーだと言うことを認識する

### その上で結論、（task_params）と言う記述が必要でした
### じゃあそれって何だっけってなって、ちゃんと見てみることに


![889bc80b3c184bbcc434429245f79351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743908/b3a7b55c-b510-e95b-4d6f-6d07abe87f8b.png)

## まずは赤くチェックされているのを確認
見てみると51行目が怪しい。
50行目はタスクテーブルから特定のレコードを取得し@taskに代入している。
そして51行目でもしそれが更新されたらと言うif文がある。ここの@taskに注目。
updateは更新したデータに置き換えるアクションなので、またモデルを通してテーブルに保存するので必要なものがあります。
意図しないデータの登録・更新を防ぐためにストロングパラメーターです。
ストロングパラメーターてどこ？

## ストロングパラメーターを確認


```

private
def task_params
  params.require(:task).permit(:content, :point_id).merge(user_id: current_user.id)
end
```
private下に既に用意してあるもので、createの時も必要です。ここで定義したたtask_paramsを引数として渡す必要があったのです。
したがって引数の数があっていないと叱られエラーを引き起こしていました。

## 正解
```
def update
    @task = Task.find(params[:id])
    if @task.update(task_params) 　←ここに追記
      redirect_to root_path
    end
```

これによってエラーを解消することができました。
gitコマンド_備忘録(自分用)

LINEbot作成時にゴリゴリ躓いたので('ω')
自分なりにgitコマンドを理解する。。
(備忘録程度に残すだけ)

~~モジュール作成後にgit init → git add . → git commit -m ~ → git push heroku master~~
~~みたいな呪文を唱えなければアプリケーションがデプロイできないらしく~~
~~自分自身、gitを殆ど理解しないまま何となくで作業を進めてしまっていた....~~

<font color="blue">**◇前提**</font>
Git→リポジトリのこと(ソースコードのデータベース)


<font color="red">**◇構造**</font>
編集者
↓
ワークツリー
↓↑
インデックス
↓↑
ローカルリポジトリ(各PC上にあるDB)
↓↑
リモートリポジトリ(サーバ上のバックアップDB)(Github)


<font color="green">**◇コマンド一覧**</font>
`git commit -m "コメント"` #インデックスの内容をコミットログとして保存
`git remote add リモートリポジトリ名 url` #リモートリポジトリの作成
`git push` #ローカルリポジトリの内容をリモートリポジトリに持っていく
`git pull` #上記の逆
`git clone` #リモートリポジトリの内容をすべてローカルリポジトリにコピーする
`git init` #カレントディレクトリに.gitディレクトリが作成される。(gitに関するデータ(※)が保存されている)
※...blob,tree,commitオブジェクト

`git add` #ワークツリーのファイルを.git/objects内のblobオブジェクトにコピーして圧縮する。


これで大まかなgitの流れは理解した(初心者になれた)...つもり( ;∀;)
ド・モルガンの法則は大事！大事！超大事！

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/de_morgans_laws) とのマルチポストです）

「ド・モルガンの法則」ってなにそれ？おいしいの？って聞かれたことがあります。
おいしくはないのですが、プログラムを書く上では超大事！です。

ここでは、プログラムを読み書きするうえでド・モルガンの法則をどのように使えばいいかを紹介します。

# ド・モルガンの法則とは？

（知っている人は、次の章まで読み飛ばして構いません）

ド・モルガンの法則とは、以下の規則性のことです。

```
!(A || B) は (!A && !B) に等しい
!(A && B) は (!A || !B) に等しい

（ここで、|| は OR, && は AND, ! は NOT ）
```

確認してみましょう。

```
!(A || B) は (!A && !B) に等しい
 +-------+-------+-------+
 |       | True  | False |
 +-------+-------+-------+
 | True  | False | False |
 | False | False | True  |
 +-------+-------+-------+
```


```
!(A && B) は (!A || !B) に等しい
 +-------+-------+-------+
 |       | True  | False |
 +-------+-------+-------+
 | True  | False | True  |
 | False | True  | True  |
 +-------+-------+-------+
```

簡単ですね。

# プログラミングで役立つ場面
## その1: if-else

例えば、以下の処理を考えてみます。

```java
private void logic(boolean a, boolean b){
    if (a && b) {
        // 処理1
    } else {
        // 処理2
    }
}
```

ここで、処理1が実行される条件が何かというと**「a が true、かつ b が true のとき」**。
では、処理2が実行される条件は？

`else` は `if` が成立しないときに実行されます。
つまり、 「NOT（`if` 条件）」のときです。
**「（a が true、かつ b が true のとき）ではないとき」**

よくわかりませんね。
そこで、ド・モルガンの法則を使います。

```
!(a && b)
→ !a || !b
```

つまり、**「a が false、または b が false のとき」**。

これならわかりやすいですね。

## その2: if - else if

続いて、次の処理を考えてみます。

```java
private void logic(boolean a, boolean b){
    if (a && b) {
        // 処理1
    } else if (b) {
        // 処理2
    }
}
```

ここで、処理2が実行される条件は？

**「b が true のとき」ではないです。**
`else if` はそれまでの `if` 条件が成立しないときに実行されるからです。

つまり、「NOT（if条件）かつ（else if 条件）」のときに実行されます。
**「（a が true、かつ b が true のとき）ではないとき、かつ b が true のとき」**


よくわかりませんね。
そこで、再びド・モルガンの法則を使います。

```
!(a && b) && b
→ (!a || !b) && b
```

さらに論理を展開します。

```
(!a || !b) && b
→ (!a && b) || (!b && b)
→ (!a && b) || false
→ !a && b
```

つまり、**「a が false かつ b が true のとき」**。

最初から、以下のように書いてくれていればわかりやすかったのですが…。[^1]

[^1]: 最初は `if` だけがあって、あとから仕様変更で `else if` を継ぎ足すという経緯があると、最初に提示したようなコードになりがちです。

```java
private void logic(boolean a, boolean b){
    if (b) {
        if (a) {
           // 処理1
        } else {
            // 処理2
        }
    }
}
```

## その3: while

ループを考えています。


```java
boolean a = true;
boolean b = true;
while (a && b) {
    // 処理（この中で、a, b を変更）
}
```

このループの継続条件は、 `while` 式の通り**「a が true、かつ b が true のとき」**。

では終了条件は？
継続条件が満たされないとき、つまり NOT（継続条件）です。

```
!(a && b)
→ !a || !b
```

つまり、終了条件は**「a が false、または b が false のとき」**。
`else` のときと、考え方は同じですね。

#　まとめ

ソースコードには、「`else` の実行条件」や「 `while` の終了条件」など、直接書かれていない条件が存在します。
特に、いいコードほどこうした論理的に導きだせることは書かれていません。冗長になるからです。

それらを明確に理解しながら読むには、論理演算の法則を適用して処理をひとつづつ読み解いていくことが大事です。

その中でも、ド・モルガンの法則は役に立つことが多い法則です。
覚えておいて損はないと思います。

--
え、ド・モルガンの法則なんて知らなくてもコードは読めるし書ける？
そういう人は、天才です。たまにいます。
Docker DesktopでAmazon ECR Credential Helperを使用する

Docker Desktop for Windows/Mac 2.4.0.0 以降、[Amazon ECR Credential Helper](https://github.com/awslabs/amazon-ecr-credential-helper) が
同梱されるようになりました。

**Docker for Mac Stable release notes - Docker Desktop Community 2.4.0.0**
https://docs.docker.com/docker-for-windows/release-notes/#docker-desktop-community-2400

都度、以下のようなコマンドで ECR へログインする一手間が減ります。

```shell-session
$ aws ecr get-login-password | docker login --username AWS --password-stdin https://<aws_account_id>.dkr.ecr.<region>.amazonaws.com
```

Docker Desktop 固有の設定などは特に無いため、`~/.docker/config.json` に以下を追加するだけです。

```config.json
	"credHelpers": {
		"<aws_account_id>.dkr.ecr.<region>.amazonaws.com": "ecr-login"
	}
```

AWS の認証情報は `~/.aws/credentials` または 環境変数を参照しますが、
credentials で特定の名前付きプロファイルを使用したい場合は、
環境変数 `AWS_PROFILE` を設定します。

Credential Helper のログは `~/.ecr/log/ecr-login.log` に出力されます。



簡単ですが、以上です。
参考になれば幸いです。
AWS Chalice使ってみた

# 概要

AWS Lambdaを起点にAWSGatewayの設定や、IAMロールを自動デプロイできるフレームワークです。

:thought_balloon: Lambdaを使ったWebアプリケーションを爆速で作れるフレームワークを求めて利用してみました。

# 使ってみた

### １．インストール

```bash
$ pip install chalice
```

### ２．AWS の認証情報を設定

`~/.aws/config` `~/.aws/credentials` の設定を行う必要があります。（他記事参照お願いします）

### ３．プロジェクトの新規作成

```bash
$ chalice new-project handson
$ cd handson
```

### ４．作成されたプロジェクトの確認

```bash
$ ls -1a
./
../
.chalice/
.gitignore
app.py
requirements.txt
```

app.py　がメインのプログラムになります。

※以下新規作成時のコード

```python
from chalice import Chalice

app = Chalice(app_name='handson')

@app.route('/')
def index():
    return {'hello': 'world'}
```

メソッドにデコーダをつけて、引数に設定したpathがAPI Gatewayの設定になる。

```python
@app.route('/XXX')
```

### ５．ローカル起動

```bash

$ chalice local
Serving on http://127.0.0.1:8000
Restarting local dev server.
Serving on http://127.0.0.1:8000
```

別のターミナルで、リクエストを送信するとapp.py のreturnで設定されている文字列がレスポンスされます。

```bash
$ curl http://127.0.0.1:8000/     
{"hello":"world"}
```

### ６．AWSへデプロイ

```bash
$ chalice deploy
Creating deployment package.
Creating IAM role: handson-dev
Creating lambda function: handson-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:012345678900:function:handson-dev
  - Rest API URL: https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/
```

デプロイすると、①IAMロール②lambda③API Gatewayが作成されてアタッチされた状態になります。

※初期設定のままだと、ステージ環境がdevになり、API Gatawayの末尾にapiは自動的に付与されるようです。

stage設定を変更したい場合は、.chalice/config.json に追記する必要がある

```.chalice/config.json
{
  "version": "2.0",
  "app_name": "chalicehandson",
  "stages": {
    "dev": {
      "api_gateway_stage": "api"
    },
    "prod": {
      "api_gateway_stage": "api-prod"
    }
  }
}
```

stageを指定してデプロイ

```bash
$ chalice deploy --stage prod
Creating deployment package.
Reusing existing deployment package.
Creating IAM role: handson-prod
Creating lambda function: handson-prod
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:01234567890000:function:handson-prod
  - Rest API URL: https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api-prod/
```

### ７．デプロイしたものを削除

```bash
$ chalice delete
$ chalice delete --stage prod
```

デプロイで作成されたものを削除します（今回だとこの３つIAMロール、lambda、API Gateway)

Stageがdev,prodの２つをデプロイしているので、２つを削除するコマンドを実行しています。

# 所感

aws＋python の場合、すごい便利ですね。また対応するサービスがどんどん増えるので、楽しみですね。
あとは、chaliceのメソッドがいろいろあって丸め込まれているので、serverless frameworkより学習コストが低そうです。

### 気になった点
- local起動したとき、保存するとリスタートが自動でかかる
- serverless framework とは違ってcloudformationのスタックを作られない。
- Stage設定をしても、API Gatewayは別URLで作成する
- API Gatewayのパスが切られるが、接続するlambdaは１個　

### 参考

[https://qiita.com/takeh/items/e52ad1c541a435e2b2e3](https://qiita.com/takeh/items/e52ad1c541a435e2b2e3)
[https://programmagick.com/blogs/aws_chalice_intro/](https://programmagick.com/blogs/aws_chalice_intro/)
[https://www.youtube.com/watch?v=u4LKbQZawaQ](https://www.youtube.com/watch?v=u4LKbQZawaQ)
[https://aws.github.io/chalice/index.html](https://aws.github.io/chalice/index.html)
Herokuのターミナルでの更新


gitを使ってHerokuの更新をしようとしたら
気になる点があったので、投稿しようと思います。


# 更新方法

1,まずherokuにログイン

```bash
heroku login
```

2,対象のアプリのところで
gitを使って変更履歴を保存

```bash
git commit -am "メッセージ"
# commitは変更履歴をGitのリポジトリーに記録します

# -am は -aと-mのオプションを合わせたもの
# -a 変更があったものを指定
# メッセージを追加する
```

3,最終的にこれで更新します。

```bash
git push heroku master
```
Swift WebKitを持つViewControllerへの遷移

##ある条件（例えばボタンを押したら）で遷移
```swift
@IBAction func btnClick(_ sender: Any) {
    self.performSegue(withIdentifier: "segueで指定したIdentify", sender: nil)
}
```


##指定したURLをWebKitで開く

```swift

@IBOutlet weak var webPage: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let homeUrl="https://google.com"
        openUrl(urlString: homeUrl)
        webPage.navigationDelegate = self
    }
    
    // 文字列で指定されたURLをWeb Viewを開く
        func openUrl(urlString: String) {
            let url = URL(string: urlString)
            let request = NSURLRequest(url: url!)
            webPage.load(request as URLRequest)
        }

```

##前のページに戻るボタンのアクション
```swift
@IBAction func goBack(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
```


##WebKitのフルスクリーン
Segueの下記の2つを設定する
![スクリーンショット 2020-10-04 22.47.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658283/6cb3cf33-2cde-b17f-e7a8-4530aaa9476c.png)

iPhoneX等の場合、上記だけだと画面上の時刻などが出っぱなしになるのでコレも必要
![スクリーンショット 2020-10-05 13.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658283/e9112c9a-870a-88de-07f7-dda8c3e27204.png)

##デバイスの向きを得る
デバイスのモーションセンサを得るためには下記の設定が必要

```swift
    var rcvURL=""
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.uiDelegate = self //これが必要
        webView.navigationDelegate = self
        openUrl(urlString: rcvURL)
    }
```

##MediaPlaerPlaybackのエラー？
画面にMediaPlayerの白い箱と動画再生のコントローラが出る。Web Viewのプロパティ（？）にすべてチェック入れるとこの問題が解決できた。原因不明。
![スクリーンショット 2020-10-05 16.29.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658283/996b1505-7425-469a-b038-aaa8743c86de.png)


----
参考
[https://fuuno.net/swift/bo_bi_1/bo_bi_1.html](https://fuuno.net/swift/bo_bi_1/bo_bi_1.html)
[https://yuu.1000quu.com/how_to_use_segue](https://yuu.1000quu.com/how_to_use_segue)
[https://qiita.com/zlia_7/items/e99b77372d8c0f38d98b](https://qiita.com/zlia_7/items/e99b77372d8c0f38d98b)
[https://qiita.com/Sab_swiftlin/items/4f184c66477e291d4a0a](https://qiita.com/Sab_swiftlin/items/4f184c66477e291d4a0a)
Raspbianにfzfをインストールする

## tr;dr

Raspbian向けにはaptで 提供されていないので、インストールスクリプトを使うか、手動でbinaryを配置する。
インストールスクリプトに任せてしまったほうがkey bindingや`.bashrc`の設定なども行ってくれてすぐに使える状態になるので楽。

## インストールスクリプトを使う場合

[公式にインストール スクリプトが用意されている](https://github.com/junegunn/fzf#using-git)ので、これを使う。

## 手動でbinaryを配置する場合

CPU アーキテクチャを確認する。

```sh
$ uname -m
armv7l # (Raspberry Pi 3 Model B+ の場合)
```

[junegunn/fzf-binのリリースページ](https://github.com/junegunn/fzf-bin/releases)から、CPUアーキテクチャに対応したtgzをダウンロードして展開して、`/usr/local/bin` に配置する。

```sh
# 以下は最新リリースが0.22.0、CPUアーキテクチャが`armv7l`だった場合の例
$ curl -OL https://github.com/junegunn/fzf-bin/releases/download/0.22.0/fzf-0.22.0-linux_arm7.tgz
$ tar xvfz ./fzf-0.22.0-linux_arm7.tgz
$ cp -p ./fzf /usr/local/bin/.
$ which fzf
```
IndexOutOfBoundsExceptionとArrayIndexOutOfBoundsExceptionの違いについて

#IndexOutOfBoundsExceptionの違いについて

[IndexOutOfBoundsException](https://docs.oracle.com/javase/jp/7/api/java/lang/IndexOutOfBoundsException.html)

> ある種のインデックス (配列、文字列、ベクトルなど) が範囲外であることを示すためにスローされます。

**List, ArrayList**などに対して、不正なインデックスを使ってアクセスした時に発生する例外

##※ArrayListの特徴
**初期化**

```java
import java.util.ArrayList; //パッケージのインポートが必要
import java.util.List;

ArrayList <参照型> list名 = new ArrayList<>();
List <参照型> list名 = new ArrayList<>();　
//ArrayListが実装しているList型のインターフェースで宣言することも可能
```

- オブジェクトであれば**どのような型でも**扱える。**型の混在**も可能
- 必要に応じて**要素数を自動的に増やす(可変長)**
- **追加した順**で並ぶ
- **null**も値として追加できる
- **重複**を許す
- スレッドセーフではない。読み出し中に要素を変更すると例外（ConcurrentModificationException）が発生する



#ArrayIndexOutOfBoundsExceptionとは

[ArrayIndexOutOfBoundsException](https://docs.oracle.com/javase/jp/7/api/java/lang/ArrayIndexOutOfBoundsException.html)

IndexOutOfBoundsExceptionのサブクラス。
> 不正なインデックスを使って配列がアクセスされたことを示すためにスローされます。つまり、インデックスが負または、配列のサイズ以上の場合です。

**配列**に対して、不正なインデックスを使ってアクセスした時に発生する例外

##※配列の特徴
**・初期化**

```java
int a = new int[3]; //要素数３の配列としてメモリを確保

int b [] = {1,2}; //newを使わず初期化子だけで初期化できる

int[]c = new int []{1,2}; //newと初期化子、両方使うなら[]の中は空

int[] d;
d = new int[]{2,3};
```
- **同じ型**、もしくは互換性のある型しか扱えない
- 扱う**要素数を最初に決める**必要がある
- 要素アクセスには添字を使わなければならない
- 要素アクセスの際は要素数を超えないようにする必要がある


##ポイント
ArrayList, Listは配列ではない！

##参考サイト
[【Java】ArrayIndexOutOfBoundsExceptionとIndexOutOfBoundsExceptionの違いについて](https://teratail.com/questions/295663)
actionview::syntaxerrorintemplate in [コントローラ名]controller#indexエラーについて

###actionview::syntaxerrorintemplateエラーについて
![エラー文.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/ca229506-aeba-7db3-e1f7-f7fc080f609e.png)
###このようにビューが乱れに乱れている時は
<font color="Red">「ビューをコメントアウトした時に余分な%や,を消してしまった」</font>
###という事が考えられますのでまずは該当のビューが正しいかどうかを見るのがポイント！
###次に考えられるのはController#indexアクションの定義が合っているのかどうか。
###要するに「Controller#index」⇄「indexのビュー」間で<font color="blue">「読み込めないよ〜😭」</font>と怒られている状況です。![MVC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/c31641df-417b-958e-a51c-491031a0cbc3.png)
　　　　　　　　　　　　　　　　　　　　　　<font color="Red">⬆️</font>

![2fa33af89e7d40798ff996ca953346f9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/db8277ec-d5c8-de72-cbba-4ac06a83aa75.png)
###上記の画像のエラー内容は<font color="orange">「indexアクションでビューに飛んだけど、23行目の構文が間違っているからこの後のコードを読み込めなかったよ😠」</font>と怒られています。
##before
```java:◯◯.html.erb
<%= link_to '新規登録', new_user_registration_path  class: "sign-up" %>
```
##after
```java:◯◯.html.erb
<%= link_to '新規登録', new_user_registration_path,  class: "sign-up" %>
```
###という事で　「,」　が抜けているだけでした、、、

#まとめ
##エラー文は意味をなんとなくな日本語に変換する事がポイントです！直訳をしろ！とか正確に！ではなく、<font color="red">「なんとなくここかここだろうな」</font>という考察力を養って、エラー文に慣れればへっちゃらですし、エラー文が次から次へと出る😭ではなく、１つずつコンピュータがコードを読み込んでくれている証なので前向きに考えましょう！！
開発中にFlutterでios14の実機での起動時にクラッシュする問題について

## 結論
iOS14からは、デバッグモードではPCと繋がずに（Android StudioやXcodeからRunせずに）アプリを起動することができなくなったようでした。
最近Flutterをアップグレードしたからか急にこの画面が出るようになったので分かりましたが、しばらくずっとただ何も出ずクラッシュするのでずっと不明のままでした。

ちなみに調べてみるとちゃんと公式に書いてありました。。（ちゃんと読めということですね...）
https://flutter.dev/docs/development/ios-14#launching-debug-flutter-without-a-host-computer
<img width="400" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/591d5e44-021e-f876-2df1-c45c995cc822.png">


## 解決した方法
ProfileモードorReleaseモードでビルドすると起動できました:smiley:
<img width="400" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/9492d905-9908-268d-b4dd-5d2c9f04d344.png">


※Xcodeの場合はこちらを参照しました↓
https://qiita.com/nakamurau1@github/items/d12a63c4f06d1a70a53d
iOSでシャッター音を変更する方法

AVFoundationのシャッター音の代わりに、好きな音を鳴らすことができます。
#手順

１、再生したい音声でオーディオプレイヤーを初期化します。

```swift
// mp3ファイルのパス
guard let path = Bundle.main.path(forResource: "customSound", ofType: "mp3") else { print("音源ファイルが見つかりません") ; return }

// プレイヤーの初期化
do {
    try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
} catch {
    print("playerError")
}
```

２、写真をキャプチャする直前に呼ばれるデリゲートメソッド内で、１、を再生します。

```swift
func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
    AudioServicesDisposeSystemSoundID(1108) // ここだけ実装すると、無音シャッターになる
    audioPlayer?.play()
}
```

（カスタム音声でも自作アプリでApp Storeの審査通りました。写真撮影時には、ユーザーに「キャプチャしたよ」ということを何らかの形で伝える必要があります。App Storeに公開するときは、その点に留意しないと却下になることがあります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ab231bcd-3f18-c54e-aea9-ccf33cc2ffa7.png)

🐣

****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
ogr2ogrでベクタータイルをつくる・変換する

## TL;DR

- 以下のコマンドでogr2ogrでも任意形式のファイルからz/x/y.pbf形式のベクタータイルを生成出来る

```
ogr2ogr -f "MVT" target_dir source.gpkg -dsco MINZOOM=7 -dsco MAXZOOM=16 -dsco COMPRESS=NO
```

- 以下のコマンドでz/x/y.pbf形式のベクタータイルを任意形式にデコード出来る（以下はtarget_dir内のズームレベル16のタイルを対象とする例）

```
ogr2ogr -f "GPKG" decoded.gpkg ./target_dir/16
```

## はじめに

ベクタータイルをつくるなら普通ならtippecanoeを使うと思いますが、QGISでもベクタータイルが出力出来るくらいだし多分GDALで対応してるんだろうなと思って調べたらやっぱり対応していたので、試してみました

## ogr2ogrで変換

GDALでベクターを扱うためのコマンドはogr2ogrですね、いつものように変換してみます。

```
ogr2ogr -f "MVT" target_dir source.shp -dsco MINZOOM=7 -dsco MAXZOOM=14
```

するとtarget_dirフォルダが生成され、中にはz/x/y.pbf形式でファイルが出力されていきます。
ひとつ試しにQGISに突っ込んでみたら、ちゃんと読み込めたので変換は成功したと思いきや、していませんでした。ローカルでサーバーを立ててからQGISやMapbox GL JSで読もうとしても、表示されません。

## gzipに変換されてしまう件
MVTへの変換時、明示しないとgzipで圧縮されてしまうようです。これにより適切に表示出来ていなかったよう。ちゃんと配信するにはサーバーの設定が必要らしいですがよくわからないしめんどうなので、そもそも圧縮を無効化します（ちなみに圧縮率は非圧縮比8割強でした）。

```
ogr2ogr -f "MVT" target_dir source.shp -dsco MINZOOM=7 -dsco MAXZOOM=14 -dsco COMPRESS=NO
```

これで変換したらQGISやブラウザでも表示されました。

## 複数レイヤー対応
ベクタータイルは複数のレイヤーをひとまとめにして、必要なレイヤーだけ表示したり個別にスタイリング出来ます。しかし、ogr2ogrはひとつの入力ファイルをひとつの形式で出力します。すなわち、複数ファイルを同時に変換する事は出来ないので、複数のレイヤーをベクタータイルに格納するには、事前に複数のレイヤーをひとつのファイルにまとめておく必要があります（GeoPackage推奨）。

```
ogr2ogr -f "GPKG" -update -append sources.gpkg source1.shp
ogr2ogr -f "GPKG" -update -append sources.gpkg source2.shp
```

そして改めて

```
ogr2ogr -f "MVT" target_dir sources.gpkg -dsco MINZOOM=7 -dsco MAXZOOM=14 -dsco COMPRESS=NO
```

で複数レイヤーからなるベクタータイルが生成されます。
このケースだと、source-layerは"source1", "source2"になります。

## ベクタータイルからの変換

z/x/y.pbf形式のベクタータイルを任意形式に変換出来ます。その場合、"z"のディレクトリをogr2ogrの引数とします、以下例。

```
ogr2ogr -f "GPKG" decoded.gpkg ./target_dir/16
```

## 参考文献
- https://qiita.com/tohka383/items/d3d1bf80db2cfb416330
- https://gdal.org/drivers/vector/mvt.html
- https://gis.stackexchange.com/questions/353851/using-gdal-ogr2ogr-correctly-to-generate-vector-mvt-tiles
- https://github.com/hfu/tomogala/issues/19
【Rails】ストロングパラメータの中身を取得する方法

# 概要
Railsで、ストロングパラメータの中身を取り出す処理の書き方

# この方法を使うシチュエーション
編集画面
↓
編集内容確認画面
↓
完了画面

という画面遷移で、何らかの理由により、
編集内容確認画面に、ストロングパラメータの値を表示したい時　など

# 事前知識
ストロングパラメータとは何か？
https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8

# 実装例

## 編集画面
```Ruby:user_edit.html.erb
<!--nameとemailが、入力フォームから確認画面へsubmitされる-->
<!--作成済みのユーザーについての編集であり、そのID値は別途、URLパラメータで渡すものとする-->
<%= form_with(model:@user, url: confirm_user_path) do |f| %>
<div class="field">
  <%= f.text_field :name, placeholder: "ユーザ名を入力してね！" %>
</div>
<div class="field">
  <%= f.text_field :email, placeholder: "e-mailアドレスを入力してね！" %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

```

## コントローラー内、ストロングパラメータ
```Ruby:UsersController.php


//ストロングパラメータを定義
private
 def user_params
            params.require(:user).permit(:name, :email)
 end

```

## コントローラー内、確認画面表示用変数定義

```Ruby:UsersController.php

def edit_confirm
    @user = User.find(params[:id])  #URLパラメータから取得したIDでユーザーデータ取得(例：users/3/edit_confirm)
    @user.name = user_params[:name] #ストロングパラメータの値取り出し＆変数への代入
    @user.email = user_params[:email] #同上
end

```

## 確認画面
```Ruby:edit_confirm.html.erb
    <h2>編集内容確認</h2>
    <p>氏名：<%= @user.name %>さん</p>
    <p>メールアドレス:<%= @user.email %></p>

```

# なぜこの記事を書いたか
「確認画面」の作成方法について、Qiita記事などでは、よく、

```Ruby:UsersController.erb
@user = User.new(user_params)
```
と設定し、テンプレート側で

```Ruby:edit_confirm.html.erb
    <h2>編集内容確認</h2>
    <p>氏名：<%= @user.name %>さん</p>
    <p>メールアドレス:<%= @user.email %></p>

```

と呼び出していますが、私の場合、
createアクションについてとあるバリデーションを設定したため、
User.newを実行すると、それがcreateアクションと認識され、バリデーションエラーが発生していました。
それを回避しつつ、入力内容を確認画面で表示するのにストロングパラメータは使えないのかな、
と試してみたところ、上記の方法で取得＆変数への代入ができました。

参考になれば幸いです。
【Python】UnitTestをするためにやったこと


## 目次
* 前提条件
* そもそもUnitTestって何？
* テストするためにやることどんなことが必要？
* メソッド呼び出せない？
* 入力する情報って何？
* テストで正しいって証明するためにはどんなことが必要？

## 前提条件
* Python: Python3.6 (3系であれば可)
* エディタ: VSCode
* OS: MacOS (Linux系OS、Windowsの場合はWSLなどを利用すると良い)

黒い画面で操作がちょっとだけできる人
スペックはPythonが動けば何でも良い

## そもそもUnitTestって何？
[単体テスト(ユニットテスト)とは | ソフトウェアの検証の種類 | テクマトリックス株式会社](https://www.techmatrix.co.jp/t/quality/unittest.html)

プログラムのメソッドなど、プログラムを構成する一番小さい粒度できちんとプログラムが機能しているかをテストすることを指します。
IT業界では単体テストなんて言われ方もする。

それぞれの言語で単体テストを行ってくれるライブラリが存在しています。
以下は例

* Java言語 …… JUnit
* C/C++言語 …… CppUnit
* .NET言語 …… NUnit

余談ですがRubyなどではMinitestやRspecなどが単体テストの機構としてがあります。


## テストするためにやることどんなことが必要？

PythonでUnitTestを実施するためには、テストコードを書いておくためのPyファイルを記述します。

詳しいテストを記述については日本語の公式ドキュメントがあるので参照してください。

[unittest — ユニットテストフレームワーク — Python 3.8.6 ドキュメント](https://docs.python.org/ja/3/library/unittest.html#unittest.TestCase.assertEqual)

VSCodeなどを利用して次のようなファイルを作成していきます。

このケースでは意図的に失敗するテストケースを記載しています。

sample.py

```python 
import unittest

class TestStringMethods(unittest.TestCase):

    def test_false(self): 
        self.assertFalse("hoge", "hoge")

if __name__ == '__main__':
    unittest.main()

```

次にコンソール上でプログラムを実行してみます。

CLI上で実行する場合は、以下のようなコマンドでUnitTestを実行することができます。

`python3 -m unittest sample.py`

```bash
======================================================================
FAIL: test_false (test.sample.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/pcuser/Documents/GitHub/pysecret/test/sample.py", line 6, in test_false
    self.assertFalse("hoge", "hoge")
AssertionError: 'hoge' is not false : hoge

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)
```


こんな感じに、FAILDが表示されて失敗していればOK
もしERRORの表示が出ている場合はPythonの文法上の問題だったりするので、ググって見てください。

Pythonでよくあるエラーはこんなものがあったりします。
【参考のエラメッセージを入れる】


## メソッド呼び出せない？
この後は実際にテストケースを記載していきます。

なるべく実践的なテストにするため、テスト対象となるプログラムを作成しておきます。

hello.py

```python

def helloMethod(str):
    msg = str
    return msg

if __name__ == '__main__':
    main()

```

その後、test.pyに`inport hello`を追加し、helloMethodが呼び出せるようにしましょう。

```
import unittest
import hello <-こんな感じ

```

## 入力する情報出力する情報って何？

今回は単純なオウム返しをするメソッドを作成しました。
入力として渡すものはメソッドの引数で渡す文字列のstr変数になります。
そして期待値としてはメソッドを実行したらstrが出力として返却されるという想定です。

```python
import unittest
import hello

class TestStringMethods(unittest.TestCase):

    # def test_false(self):
    #     self.assertFalse("hoge", "hoge")
    
    def test_hello(self):
        input_str =  "Hello"
        msg = hello.helloMethod(input_str)
        self.assertEqual(msg, input_str)

if __name__ == '__main__':
    unittest.main()

```



## テストをクリアするにはどんなことが必要？

結果が正しいかの検証にはAssertメソッドを使ってmsg変数に格納された値と
input_strの値が同一であるということを確認します。

書き方としてはUnitTestクラスが持つAssertメソッドを使うので`self.assertEqual`を使います。

ソース上ではすでに先程書いてあるのでUnitTest自体の起動を確認したコマンドと同じものを再度実行します。

`python3 -m unittest sample.py`

```

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
```

コンソール上でOKの文字が表示されていればテストが成功しています。
第２第３のプログラム言語を学び始める際に役立つ「とほほのWWW入門」というサイト

# とほほのWWW入門

http://www.tohoho-web.com/www.htm

第２第３の言語を本格的に勉強を始める前にさらっと学習したい際にかなりおすすめのサイトです。

入門書でよくみる「条件分岐とは」みたいな、多くの言語に共通している部分は省略してあったり、言語の特徴がまとめられている欄とかもあって、控えめに言って最高です。しかも広告もないです(むしろつけて)

言語の解説は、現在（投稿時）`JavaScript` `TypeScript` `Java` `perl` `PHP` `Ruby` `Python` `Go` `C#` `Rust` `shell` `FORTRAN 77` `C言語` が存在します。

知る人ぞ知る老舗のサイトみたいですが、是非多くの人にみてもらいたいということで共有させていただきます！
他にも多種多様の技術についての解説があるので、是非目を通してみてください。