OmniAICreator/Qiita-1.07M huggingface dataset:
Vulkan TutorialのRust版をやってみた 〜描画編〜

Vulkanの入門をRustでやっていきます。[目次はこちら](https://qiita.com/kbone/items/1f8bc5d571dcc3ddaac3)。今回までの実装をした[GitHubはこちら](https://github.com/KBone12/vulkan-tutorial/tree/draw_triangle)。

# Vulkanでの描画
ついに今回は三角形を描画します。描画には今までのrender pass等に加えバッファが必要になります。

## framebufferの作成
framebufferはswap chainの各image毎に作るもので、render passで設定したとおりに各attachmentにデータを渡す、文字通りバッファとして働くようです。

```rust
let _framebuffers: Vec<_> = spwapchain_image
    .iter()
    .map(|image| {
        Arc::new(
            Framebuffer::start(render_pass.clone())
                .add(image.clone())
                .unwrap()
                .build()
                .expect("Could not create a framebuffer"),
        )
    })
    .collect();
```

## command bufferの作成
そのまんま、commandのバッファです。Vulkanoの場合は`AutoCommandBufferBuilder`でcommand bufferとcommand poolを作成します。また、各framebuffer毎に作るので以下を各framebuffer毎に行います。

```rust
AutoCommandBufferBuilder::primary_simultaneous_use(
    device.clone(),
    graphics_queue.family()
).unwrap()
.begin_render_pass(
    framebuffer.clone(),
    false,
    vec![[0.0, 0.0, 0.0, 1.0].into()],
).unwrap()
.draw(
    graphics_pipeline.clone(),
    &DynamicState::none(),
    vertices,
    (),
    (),
).unwrap()
.end_render_pass().unwrap()
.build().unwrap()
```

ここで怒涛の`.unwrap()`となっており、本当は独自の`Result`を定義して`.and_then()`等をする方が良いのだと思うのですが、簡単のため`.unwrap()`にしています(ビルダーパターンなんだから本当はVulkano側でなんとかしてほしい。)

## 描画
ここまでの用意でようやく三角形が描画できます。なお、Vulkanoでは`acquire_next_image`という関数が用意されているため、semaphoreは不要です。
まず描画するための関数を呼び出す場所ですが、`winit = "0.22.0"`では

```rust
match event {
    Event::MainEventsCleared => {
        surface.window().request_redraw(); // イベント消化後に描画要求
    }
    Event::RedrawRequested(_) => {
        /* ここで描画 */
    }
    _ => {}
}
```

となっています。この中で描画用のimageを要求し、commandを実行させ、それを画面上に反映するという流れです。

```rust
if let Ok((image_index, _, acquire_future)) =
    acquire_next_image(swapchain.clone(), None)
{
    let command_buffer = command_buffers[image_index].clone();
    if let Ok(future) =
        acquire_future.then_execute(graphics_queue.clone(), command_buffer)
    {
        let _ = future
            .then_swapchain_present(
                present_queue.clone(),
                swapchain.clone(),
                image_index,
            )
            .then_signal_fence_and_flush()
            .and_then(|future| future.wait(None));
    }
}
```

なお今回は描画ループ内なので`.unwrap()`を避けて書いてみました。

# まとめと感想
ついに三角形を描画できました。まだ理解しきれていないところも多く、OpenGLと比較してもやはり難しくなっていると感じました。
【Java】JavaでMethod/ConstructorからKFunctionを取得する【Kotlin】

# やること
`Java`の`Method`/`Constructor`から`KFunction`を取り出します。

# やり方
下記の`Method.kotlinFunction`/`Constructor<T>.kotlinFunction`を`Java`から呼び出せばできます。

- [kotlin/ReflectJvmMapping\.kt at master · JetBrains/kotlin](https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt)

具体的には以下のようになります。

```java
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(Foo.class.getConstructors()[0]);
```

## 注意点
`Class`からの`Method`/`Constructor`取得にはジェネリクスの型パラメータが設定されていない場合が多いため、型パラメータを入れたい場合は`Java`内でキャストする必要があります。

```java
KFunction<Foo> function = ReflectJvmMapping.getKotlinFunction((Constructor<Foo>) Foo.class.getConstructors()[0]);
```

# 参考にさせて頂いた記事
- [kotlin\.reflect\.KFunction java code examples \| Codota](https://www.codota.com/code/java/classes/kotlin.reflect.KFunction?snippet=5ce6f21f37d9ff00042a75bb)
UnityのTextMeshProで日本語を使いたい

UnityでTextMeshProに日本語を利用したいメモ
日本語フォントがないと駄目のようでしたので

### 日本語フォントをダウンロード
https://www.google.com/get/noto/#sans-jpan
![NoName_2020-3-23_15-48-29_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/8dfae1d2-53d5-2378-79ec-e61578a5947b.png)

### Unityへフォントのファイル設置
![NoName_2020-3-23_16-8-55_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/e9be7a76-59bc-5785-b12a-037c7459001c.png)


### Font Asset Createrでフォント生成

Font Settingは添付画像のようにしました

Custum Charactor Listには下記フォントデータの文字列をコピペ
https://gist.github.com/kgsi/ed2f1c5696a2211c1fd1e1e198c96ee4

![NoName_2020-3-23_15-54-10_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/90a2645c-0f12-193e-2dea-e576352dd265.png)

### 生成したデータを別名保存（めっちゃ時間かかった）

生成終了後の画面
![NoName_2020-3-23_16-5-53_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/421aebe1-ede1-c5c6-92e7-1380f54a8205.png)

別名保存後
![NoName_2020-3-23_16-9-4_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/176f9752-ca09-a868-6084-fb4581aedb89.png)



### TextMeshProで指定

![NoName_2020-3-23_16-6-52_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/5d4a415f-b074-c4cd-23f2-15daa707a77f.png)


### 参考サイト

UnityのText Mesh Proでほぼ全ての日本語を表示させる
https://qiita.com/kgsi/items/08a1c78b3bee71136156

kgsi/japanese_full.txt
https://gist.github.com/kgsi/ed2f1c5696a2211c1fd1e1e198c96ee4

Noto Sans CJK JP
https://www.google.com/get/noto/#sans-jpan
Kubernetes上にhelmでKeycloakをデプロイする

シングルサインオンのKeycloakをデプロイしてみます。
helmはv2.14.3を使用します。
https://github.com/codecentric/helm-charts/tree/master/charts/keycloak


※minikube上で検証した内容になります。minikube.devドメインを用いてアクセスできるようにするため
superbrothers様の記事を参考に事前設定をしています。必要に応じて作業をしてください。
https://qiita.com/superbrothers/items/13d8ce012ef23e22cb74

## 1. values.yamlファイルを作成する
管理者ユーザとingressの有効化の設定をします。

```yaml:values.yaml
keycloak:
  username: admin
  password: Passw0rd
  ingress:
    enabled: true
    path: /
    hosts:
      - keycloak.minikube.dev
```

## 2. デプロイする
```
helm repo add codecentric https://codecentric.github.io/helm-charts
helm upgrade --install keycloak codecentric/keycloak --namespace keycloak --values ./values.yaml
```

## 3. Keycloakが動作していることを確認
http://keycloak.minikube.dev にアクセスすることでKeyclaokのトップページが表示されることを確認します。
Administration Consoleから先ほど指定した管理者ユーザの情報でログインし、Keyclaokの管理などを行うことができます。
![スクリーンショット 2020-03-23 15.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58803/79cf090c-3949-02e1-1b97-a2f2fb824e6d.png)


## その他
### DBの設定について 
デフォルトではH2というデータベースが使われるようになっていますが、Keycloakをシャットダウンした際にデータが消えてしまいます。
データを永続化するために外部データベースに保存することが可能です。
https://github.com/codecentric/helm-charts/tree/master/charts/keycloak#database-setup

#### 外部データベースにPostgreSQLを指定した場合の設定例
```yaml:values.yaml
keycloak:
  username: admin
  password: Passw0rd
  ingress:
    enabled: true
    path: /
    hosts:
      - keycloak.minikube.dev
persistence:
  dbVendor: postgres
  dbName: keycloak
  dbHost: mykeycloak
  dbPort: 5432
  dbUser: keycloak
  dbPassword: keycloakPassword
```

### ingressの前段にL7LBが存在する場合の設定について
今回の環境ではminikubeを利用していますが、自分がkeycloakを使っている環境ではL7LBがKubernetesクラスタの前段にいます。
その場合、Keycloakのログイン画面に遷移すると `Invalid parameter: redirect_uri` と表示されログインができません。
このような構成の場合、 `PROXY_ADDRESS_FORWARDING=true` という値を別途設定する必要があります。
ハマりどころです。
https://github.com/keycloak/keycloak-containers/blob/master/server/README.md#enabling-proxy-address-forwarding


#### ingress(k8sクラスタ)の前段にL7LBが存在する場合の設定例
```yaml:values.yaml
keycloak:
  username: admin
  password: Passw0rd
  ingress:
    enabled: true
    path: /
    hosts:
      - keycloak.minikube.dev
  extraEnv: |
    - name: PROXY_ADDRESS_FORWARDING
      value: "true"
```
【エラー】D8: Program type already present: android.support.v4.os.ResultReceiverの解決方法

#はじめに
いつも通りionic5で開発したアプリを`ionic cordova run android`でビルドしてAndroid端末にインストールしようとしたのですが、`D8: Program type already present: android.support.v4.os.ResultReceiver`というエラーが発生しました。
解決方法を記載します。

#解決方法
1. `ionic cordova plugin add cordova-plugin-androidx`を実行
2. `ionic cordova plugin add cordova-plugin-androidx-adapter`を実行

#cordova-plugin-androidxとは
CordovaプロジェクトでAndroidサポートライブラリの後継であるAndroidXを有効にします。
https://github.com/dpa99c/cordova-plugin-androidx

#cordova-plugin-androidx-adapterとは
CordovaプロジェクトにAndroidサポートライブラリとAndroidXの両方を参照するプラグイン/ライブラリが含まれている場合に必要。
Androidサポートライブラリへの参照をAndroidXにマッピングしてくれる。
https://github.com/dpa99c/cordova-plugin-androidx-adapter

#おわりに
開発中にインストールしたプラグインでAndroidXが必要だったため、エラーが起きていたようです。

#参考
https://forum.ionicframework.com/t/d8-program-type-already-present/166812/4
#New coronavirus infection, COVID-19, Osaka

#Chronological map of the starting point of the new coronavirus infection, COVID-19, Osaka
I visualized where coronavirus infections are occurring in Osaka in chronological order from the Osaka website [`"About new coronavirus infections"`](http://www.pref.osaka.lg.jp/iryo/osakakansensho/corona.html).

#Contents.
1. What did you make?
2. What we have learned from the process of creation
3. Finally

#1. What did you make?
![20200323_covid19_osaka.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352611/df78f927-5b73-71c2-f475-399d8545988c.gif)
・New coronavirus infection "COVID-19" time series map of Osaka

#2. What we have learned from the process of creation

###2-1 Background of creation
 When I learned of [`"latest infection trend in Tokyo"`](https://stopcovid19.metro.tokyo.lg.jp/) I wondered why there were no maps. By the way, who will make it even if you comment on twitter? I was told that because I can see it, I thought of making it by myself.

###2-2 Progress of preparation
When you look at the Osaka website  [`"About new coronavirus infections"`](http://www.pref.osaka.lg.jp/iryo/osakakansensho/corona.html), the first thing you can't find is where to find the first case...

In addition, the format has been changed from HTML to Word, PDF to Excel, PDF.

What I thought here is that we know the data until we make it open source, but we don't make it with the expectation that it will be used.

For the time being, it was about 130, so I input it manually and converted it to csv.

###2-3 Through the creation of
In Osaka, we can see that it is spreading from the live venue. When I looked at it, the word cluster has been used recently, so I thought it would be good to have a root for what the nodes are doing.

Recently, for some reason, there are students who went abroad at this time and came back and imported COVID-19.

3: Finally.
After creating it, I thought

1. Location and date of occurrence
2. Place and schedule for follow-up
3. Full recovery location, schedule

I thought it would be more useful to have the above.

##reason
###1.Location and schedule of the outbreak
Because we know it's a cluster infection, we can visualize it on a map.

###2.Place and schedule for observation
This is also a cluster infection. A point that can be ascertained on a map unless there is a need to go to the place.

###3.Location and schedule of complete recovery
In the case of complete recovery, It's possible to grasp the process of recovery, which leads to sharing of treatment information.

There are a lot of other things, but it looks like I'm going to have a dark side, so this is it.
Also, as this is my first post, I think there are a lot of inadequacies, but if you have any suggestions, please let me know.
(競技プログラミング)複数の入力と出力をまとめて確認するバッチを作った

#あいさつ
最近AtCoderで競技プログラミングに参加しています。
でえもん木村と申します。
私と同じ競技プログラミング初心者の役に立てばよいと思ったので公開します。

#内容
競技プログラミングをする際、
複数の入力例を実行し、その結果を出力するバッチファイルを作成しました。
#環境
Windows 10、コマンドプロンプト

#ディレクトリ構成
>CodeTest(作業ディレクトリ)
┣ Test.bat (実行ファイル)
┠ imp1 (入力ファイル)
┠ imp2
┠ imp3・・・・
┠ Q1.rb (プログラミング本体)
┠ Q1.rb
┠ Q3.rb・・・・
┠ Result.txt (結果ファイル：自動生成)

#バッチファイル
```bat:test.bat
@echo off
REM 実行ファイル
set FileName=Q4.rb
REM 出力ファイル
set ResultFile=Result.txt
REM 繰り返し回数
set num=4
echo -----Start----- > %ResultFile%
for /l %%n in (1,1,%num%) do (
    echo -----imp%%n-------------- >> %ResultFile%
    REM　実行コマンド
    ruby %FileName% < imp%%n   >> %ResultFile%
)
type %ResultFile%
```
#入力ファイル(例)
```txt:imp1
5
1 1 2 1 2
```

#実行方法
```cmd:コマンドプロンプト
C:\CodeTest>Test.bat
-----Start-----
-----imp1--------------
10
-----imp2--------------
20
-----imp3--------------
30
C:\CodeTest>
```
#使い方
問題に応じてバッチファイルの「実行ファイル名」や「繰り返し回数」「実行コマンド」を編集すれば、C言語などでも使えます。

事前にこのようなバッチファイルを用意しておくことで問題に集中できるのでみなさんぜひ使ってみてください

ありがとうございました。
Xojo  + MySQL(MariaDB) で日本語カラム名

日本語カラム名や日本語テーブル名を用いた MySQL(MariaDB) を Xojo で使うやり方。


# 環境

- Ubuntu 18.04 AMD64
- Xojo 2019 r3.1
- (MySQL) 10.1.44-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04


なお、MS-Windows でも同様にテストしたが、 Xojo に組み込まれている MySQL のドライバだと解決できない感じ。

# 接続

```

self.db = New MySQLCommunityServer
self.db.Host = "127.0.0.1"    // "localhost" ではNG
self.db.UserName = "xojodb"
self.db.Password = "password"
self.db.DatabaseName = "test"
Try
  self.db.Connect
  // proceed with database operations here..
Catch error As DatabaseException
  MessageBox("The database couldn't be opened. Error: " + error.Message)
  Return
End Try
try
  self.db.SQLExecute("set names utf8 collate utf8_general_ci")
  self.db.SQLExecute("set character set utf8")
  self.db.SQLExecute("use test")
Catch error as DatabaseException
  MessageBox error.Message
end try
```

set names utf8 collate utf8_general_ci
と
set character set utf8
を実行しておく必要がある。

# 試したSQL

この設定で、以下のSQLが正常に動作した。

INSERT文

```

app.db.ExecuteSQL("INSERT INTO sensorJP ( センサ,温度,湿度,memo) VALUES (2,"+temp+","+hemi+",'換気中');")
```

Select文

```

rsJP =app.db.SelectSQL("SELECT id,温度,湿度,memo FROM sensorJP")

```
TableViewCellに配置したImageViewがタップされた時にindexPathを取得して処理をする


なんかこれでいけた。
senderはImageViewであるはずだが、`form`にCell自身を渡してあげるとそれがsenderになるのか？

ちなみに`sender: ImageView`のsuperViewはCellではなく`Cell.contentView`とかになるらしいので、`sender.superView as? Cell`とかしてもCell自身は取得できなかった。

```Cell.swift

   var indexPath: IndexPath!

   override func awakeFromNib() {
        super.awakeFromNib()
        buyerProfileImageView.isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(buyerProfileImageViewTapped))
        buyerProfileImageView.addGestureRecognizer(tapGesture)
    }

    @objc func buyerProfileImageViewTapped(_ sender: AnyObject) {
        UIApplication.shared.sendAction(#selector(ViewController.buyerProfileImageViewTapped(_:)), to: nil, from: self, for: nil)
    }
```

```ViewController.swift
@objc func buyerProfileImageViewTapped(_ sender: OrderCell) {
        guard let indexPath = sender.indexPath else { return }
        // indexPath.rowなどを使ってした処理
    }
```

##参考
https://qiita.com/sl2/items/6c3241577f0f72850f97
https://teratail.com/questions/74243
ポートフォリオ

#記事の概要
PHP,MySQLを使って作った掲示板アプリです。
レスポンシブ対応してあります。
#作った背景
自分の母親がピアノ教室の先生をやっていて、生徒同士や先生と生徒が気軽に情報を交換したり、質問ができるようなものを作りたいと思ったからです。
#機能
会員登録していなくても掲示板を見ることができ、会員登録することでメッセージを投稿できるようになるといった感じです。

##会員登録
会員のお名前、メールアドレス、パスワードを入力します。
会員登録する際に、空欄があったり、既に登録されている会員だったり、パスワードが3文字以下だった場合は、エラーメッセージを表示するようにしました。
![sampleapp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606851/1c4d647a-d384-662d-b7cc-4726b9729e86.gif)


##ログイン機能
メールアドレスとパスワードでログインができるといったシステムです。
ログインでも空欄があったり、登録されていない場合などはエラーメッセージを表示します。
![sampleapp2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606851/52168c07-9f9b-1797-982b-5f90b6bd849f.gif)


##メッセージ送信機能
自由にメッセージを投稿することができます。
また、返信することもできます。
![sampleapp3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606851/3ce22bfa-c366-cbba-2a00-cfe3136bbee6.gif)


##削除機能
自分が投稿したメッセージだけを削除できるようにしました。
![sampleapp4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606851/224f877b-d9e0-fb50-fba2-f224410d37dc.gif)


##ログアウト機能
ログアウトができます。
![sampleapp5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606851/f3e07ff2-b609-7ec1-09d6-f3e42b8ec154.gif)
redisで特定のデータを一括で削除、操作をするスクリプト

# redisで有効期限が設定されていないセッションデータを一括削除するスクリプト
今回は有効期限が設定されていないデータを削除するscriptを作りました。

シンプルに検索して、eachして、ifでチェックして該当すれば削除を行ってます。

```lua:session-delete.lua
redis.call('select', '1') --[[ DBの数字を選んでください ]]
local expresion = 'session*' --[[ 精査対象を正規表現で捉えてください ]]

local delete_count = 0
for _,session_key_id in ipairs(redis.call('keys', expresion))
do
  if redis.call('TTL', session_key_id) == -1 then --[[ 有効期限が -1 （未設定）のものを削除します ]]
    redis.call('DEL', session_key_id)
    delete_count = delete_count + 1
  end
end
return 'deleted:'..delete_count
```

実行方法は簡単

```bash:bash
redis-cli eval "$(cat search.lua)" 0
```

docker環境ならこんな感じで

```bash:bash
dc exec imdb redis-cli eval "$(cat search.lua)" 0
```
電子工作をする人にお勧めしたいサイト~Hackster.io~

最近[Hackster.io](https://www.hackster.io)というサイトを見つけたのですが、これがとても良いサイトだと思ったので共有したいと思い、記事を書きました。  

# このサイトに触れたきっかけ
[Arduinoの公式サイト](https://www.arduino.cc)を見て回っていたときに、[Arduino Project Hub](https://create.arduino.cc/projecthub)というサイトにたどりつきました。
<img width="1440" alt="スクリーンショット 2020-03-23 14.51.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/f7ed1f1f-63eb-866a-26c9-88baa760dd47.png">

これは、Arduinoで作ったものを公開するサイトのようなのですが、いろいろな人が作ったものをみることができてとても面白いと思いました。そしてこのサイトを見て行って下の方に行ってみると、
<img width="1440" alt="スクリーンショット 2020-03-23 14.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/2fa42d84-9381-48b3-9f5e-9cb82d81b5e7.png">
「Powered by hackster.io」と書いてあったので、そのリンクに飛んでみると、そこではArduinoだけではなく、Raspberry PiやNVIDIA、Microchipなど色々な会社のマイコンを使ったプロジェクトがたくさんあり、役に立ちそうだと思いました。Hackster.ioの利点についてはこの後詳しく述べたいと思います。

# Hackster.ioとは
[Hackster.io](https://www.hackster.io)は、先ほども少し述べましたが、様々な電子工作のプロジェクトが公開されているサイトです。かなり多くのプロジェクトが公開されていて、新型コロナウイルスに関するプロジェクトまでありました。  
いいねやブックマーク、コメント機能などもあるのですが、個人的に特に注目している点が、

- プラットフォームごとに分かれている
- 初心者、中級者、上級者、達人でタグ分けされている
- 見やすい

です。  
プラットフォームごとに分かれているので、Arduinoで何かを作りたいと思った時にArduinoのプロジェクトだけをみるようなことができます。  
また、初心者、中級者、上級者、達人(Beginner, Intermediate, Advanced, Expert)と分けられていることで、そのプロジェクトが自分にも作れそうかどうかわかります。  

写真付きの材料一覧があり、コードがシンタックスハイライト付きでコードが書いてあり、配線の図や実際の写真、動画なども載っています。もちろん記事によって情報量などに差はあるのですが、どの記事を見てもとても情報量が多くて品質が高いように思いました。  

ここまで良い点を述べてきましたが、[Hackster.io](https://www.hackster.io)には一つ大きな欠点があります。それは英語しかないことです。これは海外のサイトなので仕方がないのですが、英語しかないととても読みにくいです。

# 使い道
僕が考えた[Hackster.io](https://www.hackster.io)の使い道です。

## アイディア探し
学生であれば文化祭などで何か面白いものを作りたいと思った時に参考になると思います。また、大人の方でも何かイベントや普段の電子工作でも参考になると思います。  
## モチベーション維持
色々な面白そうなアイディアが出ているのをみると、自分も何か作りたくなるような気がします。そういった意味で電子工作を続けるモチベーション維持になるかもしれません。
## 新しいものを探す
僕は[Hackster.io](https://www.hackster.io)にアクセスしてみて自分の知らないマイコンやソフトウェアが大量に出てきたので、何か新しいもので電子工作をしたいと思った時に参考にできると思います。

# 最後に
あまりまとまってない拙い文章となってしまいましたが、最後まで読んでくださりありがとうございました。  
電子工作をする人の参考になれば幸いです。  
何か間違いや不備を見つけましたらコメントや編集リクエストなど、よろしくお願いします。
【rails】seedデータからファイルを読み込んで、ファイル内のimageを一括で保存する

###railsのseedデータからファイルにあるイメージを一括で保存する方法を、説明します。

準備) 
①carrierwaveを使います。
②db/imagesを作成します。

以下のコードでイメージを保存できます。

```seeds.rb
Image.create!([
  (1..20).map do |n|
    [ 
      id: n,
      image: open("#{Rails.root}/db/images/#{n}.jpg")
    ]
  end
])
```
しかし、この場合、イメージ名を1.jpgとかにしないといけないから、めんどくさい。。。

なので、このコードで楽にいけます！

```seeds.rb
images = Dir.open("#{Rails.root}/db/images")
images.each.with_index(-1) do |image, i|
  next if image =~ /^\.+$/
  Image.create!(
    id: i,
    name: image,
    image: open("#{Rails.root}/db/images/#{image}")
  )
end
```

説明します。

`images = Dir.open("#{Rails.root}/db/images")`
ここで、ディレクトリー内の全ての画像を並べることができます。

もし、以下のコードで計算すると、、

```
images.each do |image|
  puts image
end

（結果）
.
..
XXX.jpg
XXX.png
XXX.jpg
```
こんな感じになり、「.」[..]が邪魔です。

なので、`next if image =~ /^\.+$/`を入れることで、「.」[..]がスキップされるようになります。

今回は、idも入れたかったので、`each_with_indexメゾット`を使いましたが、「0」から始まるし、「.」[..]をスキップするので、逆に２から始まってしまいます。

なので、「1」から始めるために、`each.with_index(-1)`を使っいました。

これで、簡単にseedで画像を保存できるようになりました。めでたし。

ご指摘の点があれば、ぜひツッコンでください！
よろしくお願いします！
#新型コロナウイルス感染症「COVID-19」起点時系列地図大阪版

#新型コロナウイルス感染症「COVID-19」起点時系列地図大阪版
大阪のどこでコロナウイルス感染が起こっているのか大阪のサイト[`「新型コロナウイルス感染症について」`](http://www.pref.osaka.lg.jp/iryo/osakakansensho/corona.html)より時系列で可視化してみました。
#目次
1. 何を作ったのか
2. 作成経緯から作成してわかったこと
3. 最後に

##1：何を作ったのか
![20200323_covid19_osaka.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352611/d197ed8a-42ae-f591-0b09-d30bd70816f1.gif)
・新型コロナウイルス感染症「COVID-19」起点時系列地図大阪版


##2：作成経緯から作成してわかったこと
###2-1 作成経緯
　作成経緯は[`「都内の最新感染動向」`](https://stopcovid19.metro.tokyo.lg.jp/)を知って、なんで地図がないんだろうって思ったからです。かといって、それをtwitterとかで意見しても誰が作るの？って言われるのは目に見えているので自分で作ろうと思ったのがきっかけです。

###2-2 作成経過
大阪のサイト[`「新型コロナウイルス感染症について」`](http://www.pref.osaka.lg.jp/iryo/osakakansensho/corona.html)のサイトを見ているとまず１例目がどこにあるのか見たらない…って所から始まります。

更に見ていると最初はHTMLで文章化されていたのがWORD,PDF→Excel,PDFとフォーマットも変わっていきます。

ここで思ったのは、細かい指摘点は色々ありますが、公務員の方々は`データをオープンソースにするまでは把握しているけれど、使われることを想定して作っているのではない`と思いました。

とりあえず130件位だったので手入力でcsv化していきました。

余談ですが、テンプレート化してないんだ…と思って、議員誰なのだろうと思ったらハンコ大臣が大阪府議員さんでしたか。納得と思います。

###2-3 作成を経て
大阪だとライブ会場を起点に拡散しているのがわかります。それを見るとクラスターという言葉が最近使われているので、ノードがどういう動きをしているのかのルートもあったほうがいいかなと思いました。

最近では何故かこの時期に海外に行って、戻ってきてCOVID-19を輸入している学生さん等もいて、案の定家族にばらまいています。

#3：最後に
作成してみて思ったのですが、

1. 発生場所、日程
2. 経過観察場所、日程
3. 完治場所、日程

上記があるともっと便利かなと思いました。

###理由
####1.発生場所、日程
クラスター感染ということはわかっているので、そこにいたのかというのを地図上で可視化できるという点
####2.経過観察場所、日程
これもクラスター感染です。その場所に行く必要性がない限り、地図上で確かめることができる点
####3.完治場所、日程
完治した場合、どういう経緯で治ったのかが把握出来る為、治療情報シェアに繋がる。

ほかにも色々ありますが、暗黒面が出そうなので此処まで。
また、初投稿のため所作至らないところ多々あると思いますが、ご先輩方の指摘等ありましたら、よろしくお願いします。
Db2目線で見た Oracle NUMBERの謎の解明

#NUMBERって何？

##Db2のDECIMALとOracleのNUMBERは、似て非なるもの？
OracleのNUMBERでは「マイナスの位取り」や、「精度以上の位取り」が指定できる。
Db2畑で育った私にとって、これは非常な驚きでした。
しかし、規則立てて考察すると「なるほど」と理解ができたので、それをまとめておこうと思います。

###NUMBERの指定方法###
***NUMBER(p,s)
　　精度p(1〜38桁)、位取りs(-84〜127桁:省略時 0)***

これを見た私の衝撃。
「位取りがマイナスって何！」
「精度が38までなのに、127桁まで位取りが指定できるって、どういうこと?」

Db2のDECIMALの位取りは0か正数であり、指定できるのは最大でも精度と同じ値までなので理解しやすいけど、いったいこれらはどういう範囲の数字を意味するのか？

##■マイナスの位取り

Oracleのマニュアルには、マイナスの位取りに関して以下の説明があります。
「位取りが負の場合、小数点の左側にある桁数です。この場合は最下位有効桁を含みません。位取りが負の場合、実際のデータは整数部分の右から指定された桁数のみ丸められるため、最下位有効桁は小数点の左側になります。たとえば、(10,-2)と指定すると100の位まで丸められます。」

説明だけ読んでも全くピンとこないので、NUMBER(6,-3)を例に実際にOracleで値を入れて試してみました。

**[1] マイナスの位取りのOracleでのテスト結果**
![[1] マイナスの位取りのOracleでのテスト結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/14368d78-f23f-dd18-19fe-410d769a92df.png)

説明にはマイナスの数字は「小数点の左側にある桁数」とありましたが、[1]の結果を見ると、なるほど、整数部分の0の数ということですね！
つまり、マイナス3の位取り指定の場合は“下3桁を000にする整数、即ち1000の単位になるように四捨五入する”という意味で、1000未満の数は四捨五入され、0か1000になる事が分かりました。

では、なぜマイナスの位取りだとそうなるのか？

最初はNUMBERの独自の決め事かと思っていたのですが、ある法則を作成して当てはめてみた結果、「そうか、そうなるのか」と納得できました。

その法則とは、ちょっと数学的な話になってしまいますが、以下のようになります。

まず前提として、精度(p)と位取り(s)を指定するということは、
・精度は有効数字の桁数なので、使用できる数字は1～最大は9がp個分までという意味。
・位取りは小数点以下の位なので、10のs乗分の1の小数まで位取りがあるという意味。
であり、これはDb2のDECIMALでも同じです。

そして、(p,s)で表される数の0を除く正の最小値と最大値は、
***最小値         1×((10のs乗)分の1)　
最大値  (9がp個)×((10のs乗)分の1)***  　
という計算ルールで表現できます。

具体例でいうと、(4,1)の指定であればp=4、s=1なので、
***最小値　     1×((10の1乗)分の1)　=　1　×（1/10）=  0.1
最大値　(9999)×((10の1乗)分の1)  =　9999　×（1/10）=  999.9***
となります。

このルールに則して、いくつかの例をEXCELで計算させてみました。

**[2] 精度(p)と位取り(s)による、表現できる正の最小値と最大値の範囲**
![[2] 精度(p)と位取り(s)による、表現できる正の最小値と最大値の範囲.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/b7c5cb68-84a6-5194-7157-2f1ff2606223.png)

そこで、このEXCELに位取り(s)がマイナスの(6,-3)を指定してみると、その結果は。

**[3] マイナスの位取りの結果**
![[3] マイナスの位取りの結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/9a06172f-f12d-859e-f7f7-f6395ca25f56.png)
あら、最小値が1000になった。

つまり(10^B7)の部分は10のマイナス3乗となるので（10の3乗）分の1=1000分の1、
とすると、1/(10^B7) は1÷(1000分の1) となり、答えは1000で単に10の3乗となる！

なるほど、位取りがマイナス値(ここでは-sとします)ということは、逆に10のs乗を有効数字に掛けるということだったのか、と納得。
（子どもの頃の数学の知識が、少し役立った気がします。）

では、精度(p)より大きい位取り(s)の場合を、このルールに当てはめてみたらどうなるでしょうか？

##■精度(p)より大きい位取り(s)
いくつかの例を当てはめてみました。

**[4] 精度(p)と同じかそれより大きい位取り(s)を指定した結果（精度(p)≦位取り(s)の例）**
![[4] 精度(p)と同じかそれより大きい位取り(s)を指定した結果（精度(p)≦位取り(s)の例）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/3948e4b5-1225-0c78-c299-9903997b9e69.png)

この結果から、sがpと同じかそれ以上の場合、表現できる正の数は必ず1未満、即ち 0.xxx であること、また最大値は小数点以下の9の前にs - pの差分の数だけ先行0が増えるということが分ります。

例えば、NUMBER(4,6)の場合は小数点以下の桁数は6桁だが、有効数字は4桁までなので、小数点以下は右から4桁の9999までしか埋められず、残りの2桁は00となり、 0.009999が最大値となります。よって0.009999より1つ上の位になる0.01以上の数字は範囲外になるという制約が加わるということになります。

では実際はということで、OracleのNUMBER(4,6)に値を挿入してみました。

**[5] Oracleでの確認**
![[5] Oracleでの確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/4eb4846f-64a1-7b4a-2b10-d91cc19d0443.png)
この結果から、精度(p)より大きい位取り(s)の場合も同じルールに則っていることが確認できました。

以上が、Db2のDECIMALにはないNUMBERの精度(p)と位取り(s)の指定について調べてみた結果です。

結局、これらはNUMBER独自のルールということではなく、DECIMALと同じ規則に則ったものだった！
という事で、私にとっては目からウロコの発見でしたので、ご紹介させていただきました。

以上
Flutterの共有プリファレンスプラグイン使用時にMissingPluginExceptionが表示された際の対処

# Flutterの共有プリファレンスプラグイン使用時にMissingPluginExceptionが表示される

Flutterでの開発において、共有プリファレンスプラグイン([shared_preferences](https://pub.dev/packages/shared_preferences) plugin)を使用することで、キー・バリュー型の小さなデータを保存することができる。

## pubspec.yamlファイルに追加

[公式ドキュメント](https://flutter.dev/docs/cookbook/persistence/key-value)にしたがって、shared_preferencesプラグインをpubspec.yamlファイルに追加し、Packages getをクリック。

```
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.5.6+3 # 執筆時点
```

## Dartファイルに追加

Dartファイルにshared_preferencesプラグインを追加。

```
import 'package:shared_preferences/shared_preferences.dart';
```

## 共有プリファレンスに書き込み

ログイン時にAPIから返されるJSONファイルに含まれるトークンを共有プリファレンスに書き込むため、Dartファイルに下記のコードを追加。

```
final prefs = await SharedPreferences.getInstance();
prefs.setString('token', token);
```

## MissingPluginExceptionが表示される

ホットリスタートしてエミュレータからログイン処理を行い、トークンが書き込めているか確認したところ、下記のエラーが発生。

```
flutter: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
```

# MissingPluginExceptionの対処方法

コールドリスタート（停止して再起動）したところ、エラーが解消し、共有プリファレンスへの書き込みを確認できた。

## 参考リンク

[Stack Overflow](https://stackoverflow.com/questions/50687801/flutter-unhandled-exception-missingpluginexceptionno-implementation-found-for)
補助記憶装置

現在勉強している基本情報技術者試験についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# ハードディスク
**ディスク（プラッタ）**
表面に磁性体が塗布もしくは蒸着されており、この磁性体を磁化させることによってデータの読み書きを行う金属やガラス製の円盤。

**磁気ヘッド**
ディスク表面の磁性体を磁化させたり読み取ったりする装置。

**アクセスアーム**
先端に付いた磁気ヘッドを、目的位置の同心円状まで運ぶ装置。

**セクタ**
ハードディスクに作成された記憶領域の最小範囲。
セクタを複数集めた1週分の領域を**トラック**といい、同心円状のトラックを複数まとめると**シリンダ**という。

**クラスタ**
OSがファイルを読み書きする際の、複数のセクタを1ブロックとみなした単位。

**アクセス時間**
データにアクセスするのにかかる時間で、下記の3つを合計した数値のこと。

- シーク（位置決め）･･･アクセスアームを動かして目的の位置まで運ぶ。
- サーチ（回転待ち）･･･目的のデータが磁気ヘッドの位置まで回ってくるのを待つ。
- データ転送･･･セクタに書かれたデータを読み込む。

例えば、次のハードディスクから5,000バイトのデータを読み出す場合、アクセス時間は下記のように求める。

回転速度：5,000回転/分
平均シーク時間：20ミリ秒
1トラック当たりの記憶容量：15,000バイト

計算に用いるシーク時間とサーチ時間は平均値を使うため、まずは平均サーチ時間を求める。
平均サーチ時間は、磁気ヘッドの真下に読み込み位置があった場合（待ち時間0）と、磁気ヘッドを読み込み位置が通過した直後の場合（1回転するのを待つ）を考えればいいので、回転数は1/2回転となる。

ディスクが1回転するのにかかる時間は、
[$1分(60,000ミリ秒) / 5,000回転 = 12ミリ秒$]で、平均サーチ時間は1/2回転なので半分の6ミリ秒となる。

ハードディスクが1トラックのデータを転送するのに必要な時間はディスクが1回転する時間と同じなので、1ミリ秒あたりに転送できるデータ量は
[$15,000バイト / 12ミリ秒 = 1,250バイト/ミリ秒$]となる。
この速さで5,000バイトのデータを読み出すには、
[$5,000バイト / 1,250バイト = 4ミリ秒$]となる。

最後に、3つの時間を合わせると、
[$20ミリ秒（シーク時間） + 6ミリ秒（サーチ時間） + 4ミリ秒（データ転送時間） = 30ミリ秒$]となる。

**フラグメンテーション（断片化）**
ファイルを書いたり消したりすることで空き容量が分散化してしまい、新しくファイルを書き込むときにあちこちに分かれて断片化してしまうこと。
これにより無駄なシーク時間やサーチ時間が発生してしまい、動作が遅くなる。

**デフラグメンテーション（デフラグ）**
断片化したファイルのデータを連続した領域に並べ直すこと。

**RAID**
複数のハードディスクを仮想的に1つにまとめて運用する技術の代表的な実装手段で、RAID0~RAID6までの7種類に分かれている。

**RAID0（ストライピング）**
1つのデータを複数のディスクに分散させて書き込むので高速化が図れるが、1台でも故障すると全ファイルが失われるため信頼性は低い。

**RAID1（ミラーリング）**
1つのデータを複数のディスクに書き込むため、使えるディスク容量は半分以下になるがいずれか1台が故障してもそのまま使えるので信頼性は高い。

**RAID5**
3台以上のディスクに分散させてデータを書くとともに、それらのバリティ情報（誤り訂正符号）を別のディスクに保存するので、いずれか1台が故障しても他のディスクにあるバリティ情報を使ってデータが復元できる。

# ハードディスク以外の補助記憶装置
**リムーバブルメディア**
駆動装置から記憶媒体を簡単に取り出せるもののこと。

**光ディスク**
CDやDVDなどのレーザー光線によってデータの読み書きを行うディスク。
それぞれ以下のような種類があり、ROMはRead Only Memory、RはRecordable、RWはReWritableの略。

- CD･･･安価で大容量なことからソフトウェアの配布媒体としても広く使われている。
- CD-ROM･･･読み込み専用のCD
- CD-R･･･一度だけ書き込めるCD
- CD-RW･･･何度でも書き換えができるCD
- DVD･･･CDよりも波長の短い赤色レーザーで記録する為ビットの高密度化が可能になり、より容量が大きい。
- DVD-ROM･･･再生専用型のDVD
- DVD-R･･･追記型のDVD
- DVD-RW･･･書き換え可能型のDVD
- DVD-RAM･･･　　　　〃

**光磁気ディスク**
レーザー光線と磁気によってデータの読み書きを行うディスク。

**磁気テープ**
磁性体が塗布されたテープ状のフィルムに、磁気を使って読み書きを行うカセット型の記憶媒体。
連続してデータの読み書きを行うものを**ストリーマ**という。

**フラッシュメモリ**
EEPROMの1種を補助記憶媒体に転用したもので、代表的なものは**メモリーカード**や**USBメモリ**など。

**SSD(Solid State Drive)**
フラッシュメモリを記憶媒体として内蔵する装置で、機械的な駆動がないため省電力で衝撃にも強く、シークやサーチといった待ち時間もないため高速に読み書きを行うことができる。
ただし、書き込み回数に上限があり、ハードディスクに比べてビット当たりの単価も高い。
Pythonとyieldとreturnと時々yield from

# Pythonでのyield
Pythonでは関数内で`yield`を使うとGeneratorとして使える。
例えば

```python
def foo():
    for i in range(10):
       yield i
```

として書いて、

```python
for k in foo():
   print(k)
```

と書くと0から9までの値が表示される。

# Pythonでのyieldとreturnの併用
例えば、

```python
def hoge():
   for i in range(10):
      yield i
   return i+1
```

みたいに書いた時、これを実行した場合には **yield の結果のみが帰ってくる。**
これはPythonの仕様であって、Generator内におけるreturnは`StopIteration`として扱われているのが理由。
なので、基本的にyieldとreturnの併用というのは難しい、と考えても差し支えはない。
むしろ、yieldがGenerator内においてはreturnとしての機能を果たすので、基本的には
yieldかreturnのどちらかに絞るのが良い。

# 無理してでも併用する
何か理由があってreturnと併用したい場合には、`yield from`を使えばreturnに設定した値を取得する
ことが出来るようになる。
例えば、

```python
def buzz():
  i = 0
  for j in range(10):
     i += j
     yield j
  return i
```

のような関数を書いたとして、returnまで欲しい場合には別個に新たな関数を用意して次のように
書いてあげるとreturnの値まで取得ができる。

```python
def getter():
  x = yield from buzz()
  yield x
```

ただし、 `yield from` は関数内でしか記述できない手法なのでそこは注意しなければならない。

# まとめ
- yield を使えばGeneratorを生成できる
- yield と return の併用は厳しい
- yield fromを使えばreturnの値までを取得が出来る。
- yield fromは関数内でしか使えない
- 結局はyieldかreturnに絞ったほうが良い。
【エラー】An unhandled exception occurred: [BABEL]... Could not find plugin "proposal-numeric-separator"の解決方法

#はじめに
いつも通りionic5で開発したアプリを`ionic cordova run android`でビルドしてAndroid端末にインストールしようとしたのですが、`An unhandled exception occurred: [BABEL]... Could not find plugin "proposal-numeric-separator"`とエラーが発生しました。
解決方法を記載します。

#解決方法
1. package-lock.jsonを削除
2. `"resolutions": { "@babel/preset-env": "^7.9.0" }`をpackage.jsonに追記
   (最新のバージョンを確認してください。[@babel/preset-env · Babel](https://babeljs.io/docs/en/babel-preset-env))
3. `npm install npm-force-resolutions --save-dev`を実行
4. `npm install`を実行
5. `npx npm-force-resolutions`を実行
6. 再度`npm install`を実行
7. `ionic cordova run android`

#Babelとは
JavaScriptの新しい機能を使って書いたコードを、以前のバージョンの書き方に変換してくれるツールです。
https://babeljs.io/

#proposal-numeric-separatorとは
桁数の多い数字を読みやすくするために、_を使えるようにするものです。
[@babel/plugin-proposal-numeric-separator · Babel](https://babeljs.io/docs/en/babel-plugin-proposal-numeric-separator)

#参考
https://forum.ionicframework.com/t/could-not-find-plugin-proposal-numeric-separator/185556/5
https://qiita.com/Shagamii/items/a87181c22ea777ee2acc
https://blog.tagbangers.co.jp/ja/2019/11/11/js-next
任意のボタンからの訪問はお問い合わせフォームのselectboxでその選択肢が選択済のまま表示されるようにする

やりたいことを日本語で表現するのはﾑｽﾞｲﾃﾞｽﾞﾈ...

# やりたいこと
任意のページのボタンからのお問い合わせフォームへの訪問は、あらかじめその項目が選択済となってお問い合わせフォームが表示されるようにしてほしいとの要望があったので初心者ながらも調べてみました。
（これが最適かどうかもわかりませんのでより良い方法があれば教えてください）

## 流れ
1. 元のaタグにURLパラメーターを設置しておく
2. 訪問先であるお問い合わせフォームにて、そのURLパラメーターの取得
3. もしそのパラメーターのidとselectbox の選択肢(option)のidが一致すればその選択肢が選択済になるようにする

という流れにしようと思いました

### 1. 元のaタグにURLパラメーターを設置

```php

<a href="hogehoge/contact/?id=lecture">
```


### 2. 訪問先であるお問い合わせフォームにて、そのURLパラメーターの取得


```javascript

// URLのパラメータを取得
var urlParam = location.search.substring(1);
```

- `location.search`は**現在のページのクエリ情報（URLの末尾にある「?〜」）の文字を取得**
▼参考サイト
[JavaScriptのlocation.searchでクエリ情報を取得してみる](https://bl6.jp/web/javascript/location-search-query/)

- `substring()`の使い方は

```
var str = '文字列';
str.substring(開始位置, 終了位置);
```
で、引数が一つなので、**一文字目から最後までを抽出**という意味です

▼参考サイト
[substringで文字の切り出し](https://www.sejuku.net/blog/25730)



### 3.もしそのパラメーターのidとselectbox の選択肢(option)のidが一致すればその選択肢が選択済になるようにする


#### もしそのパラメーターのidとselectbox の選択肢(option)のidが一致すれば

```JavaScript
var urlParam = location.search.substring(1);
 
// URLにパラメータが存在する場合
if(urlParam) {
    //処理
}
```

#### 選択肢が選択済になるようにする
```javascript

document.getElementById('lecture').selected = true;
```


## ということで1、2、3を合わせると、

```javascript

var urlParam = location.search.substring(1);
 
// URLにパラメータが存在する場合
if(urlParam) {
  document.getElementById('lecture').selected = true;
}
```
出来上がりですね

`selectbox`にidをつけて、
その子要素の何番目`option[2]`とかで要素を取得してもできまする。
table系タグは２種類にグループ分けすると覚えやすい

#table系タグは２種類にグループ分けすると覚えやすい

#### (1)エリア系タグ...表自体のエリアごとの意味を表す

- `<table>`...「このエリアは表」
- `<thead>`...「このエリアは表の見出し」
- `<tfoot>`...「このエリアは表のフッター」
- `<tbody>`...「このエリアは表のメイン」
- `<tr>`...「ここからここまでが１行」（`<th>`や`<td>`を囲います）

#### (2)コンテンツ系タグ...表の中身を表す

- `<th>`...「これが見出しの文字」
- `<td>`...「これが見出し以外(データ等)の文字」


```html:example
<table> <!-- 開始：表エリア -->
　<thead> <!-- 開始：見出しエリア -->

   <tr> 
     <th>見出しA</th> <!-- コンテンツ系タグ：見出し -->
     <th>見出しB</th>
   </tr>

 </thead>　<!-- 終了：見出しエリア -->
 <tbody>　<!-- 開始：メインエリア -->

   <tr>
     <td>AA</td> <!-- コンテンツ系タグ：見出し以外（データ等） -->
     <td>BB</td>
   </tr>
   <tr> <!-- 開始：１行 -->
     <td>AAA</td>
     <td>BBB</td>
   </tr> <!-- 終了：１行 -->
   <tr>
     <td>AaAa</td>
     <td>BbBb</td>
   </tr>

　</tbody> <!-- 終了：メインエリア -->
</table>　<!-- 終了：表エリア -->

```

##### この記事を作った経緯：
テーブルを作るとき、よく基本構造やそれぞれのタグの意味を忘れてしまうので自分なりの覚え方を考えました。その備忘録がこの記事です。
EC-CUBE4のQueryCustomizerでOR条件を追加したい場合



EC-CUBE4のリポジトリのカスタマイズについてはまず[こちら](https://doc4.ec-cube.net/customize_repository)の公式ドキュメントをご確認ください。

AND条件であればEC-CUBE4自体が提供しているカスタマイズ機構で簡単にカスタマイズが可能です。

例えば `note` が空の商品のみ検索結果に表示したい場合は以下のように `WhereCustomizer` を拡張してやることで検索条件を追加できます。

```php
<?php

namespace Customize\Repository;

use Eccube\Doctrine\Query\WhereClause;
use Eccube\Doctrine\Query\WhereCustomizer;
use Eccube\Repository\QueryKey;

class ProductListWhereCustomizer extends WhereCustomizer
{
    /**
     * @inheritDoc
     */
    public function getQueryKey()
    {
        return QueryKey::PRODUCT_SEARCH;
    }

    /**
     * @inheritDoc
     */
    protected function createStatements($params, $queryKey)
    {
        // noteが空の商品のみ検索結果に表示
        return [WhereClause::isNull('p.note')];
    }
}
```

さて、問題はOR条件をどうやってしているするかですが、 `WhereCustomizer` に AND, OR のメソッドが用意されていないので、 `QueryCustomizer` を直接実装してやる必要があります。

例えば「 `note` が空またはログイン中の会員番号」の商品のみ検索結果に表示したい場合は以下のように `QueryCustomizer` を実装します。

```php
<?php

namespace Customize\Repository;

use Doctrine\ORM\QueryBuilder;
use Eccube\Doctrine\Query\QueryCustomizer;
use Eccube\Repository\QueryKey;
use Eccube\Request\Context;

class ProductListWhereCustomizer implements QueryCustomizer
{
    /**
     * @var Context
     */
    private $context;

    /**
     * ProductListWhereCustomizer constructor.
     *
     * @param Context $context
     */
    public function __construct(Context $context)
    {
        $this->context = $context;
    }

    /**
     * {@inheritdoc}
     */
    public function customize(QueryBuilder $builder, $params, $queryKey)
    {
        // noteが空またはログイン中の会員番号の商品のみ検索結果に表示
        $Customer = $this->context->getCurrentUser();
        if (is_null($Customer)) {
            $builder
                ->andWhere('p.note IS NULL');
        } else {
            $builder
                ->andWhere('p.note = :Note OR p.note IS NULL')
                ->setParameter('Note', $Customer->getId());
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getQueryKey()
    {
        return QueryKey::PRODUCT_SEARCH;
    }
}

```

間違い、もっといい方法があればコメントいただけますと助かります。
日時表示を日本時間に修正

##タイムゾーンの設定
application.rbに、タイムゾーンの設定を追記します。
【例】

```application.rb
〜省略〜
    # Initialize configuration defaults for originally generated Rails version.
    config.time_zone = 'Tokyo'   #追記

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
〜省略〜
```
ActiveRecord で unscoped を呼ぶとその前のクエリが消える

[ブログ記事](http://secret-garden.hatenablog.com/entry/2020/03/18/194551)からの転載です。


## `unscoped` を使うことで `default_scope` を取り除くことができる

さて、皆さん大好き `default_scope` ですが、モデルで `default_scope` を定義すると次のように暗黙的にクエリが追加されます。

```ruby
class User < ActiveRecord::Base
  default_scope { order(:updated_at) }
end

# 暗黙的に ORDER BY のクエリが追加れる
puts User.all.to_sql
# => SELECT "users".* FROM "users" ORDER BY "users"."updated_at" ASC
puts User.where(name: "Tom").to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'Tom' ORDER BY "users"."updated_at" ASC
```

毎回 `order(:updated_at)` する必要がないので便利ですね。
でも『あ〜今日は `default_scope` のクエリ追加してほしくないな〜〜〜』って思うときがあると思うんですよ。
そういう時に `unscoped` を使うと `default_scope` のクエリを取り除く事ができます。

```ruby
# unscoped を付けると default_scope はつかなくなる
puts User.unscoped.all.to_sql
# => SELECT "users".* FROM "users"
puts User.unscoped.where(name: "Tom").to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'Tom'
```

これで `default_scope` をつかっていてもシュッと取り除く事ができて便利ですね！


## `default_scope` 以外のクエリも取り除かれる

`unscoped` を使うことで `default_scope` を取り除く事ができるようになります。
しかし `unscoped` はめちゃくちゃ強くて『呼び出すよりも前のリレーション』も取り除いてしまします。

```ruby
# unscoped よりも前に付けた where のクエリも消してしまう
puts User.where(name: "Tom").unscoped.to_sql
# => SELECT "users".* FROM "users"
```

`unscoped` で `default_scope` を消したい場合は必ず『一番最初』に `unscoped` を呼び出しましょう。
逆に『レシーバのクエリを全部消したい』場合は `unscoped` を呼び出すと一括で消すことができるので便利です。
grepのHIT行数の合算を出す

##grepのHIT行数の合算を出す

```sh
grep -c "a" *.fbk | awk -F ":" '{sum += $2 } END {print sum}'
6
```


```sh
grep -c "a" *.fbk
a.fbk:4
b.fbk:2
```


##入力ファイル例
```txt:a.fbk
sadada
aaaaa
a872
テスト配信でーす
aaa
```

```txt:b.fbk
茶葉が生えますね！
aaa
bbb
gfs
3245
dda
```
メッセージを送信したらメッセージの最下部まで自動でスクロールするようにする

##animateメソッド
メッセージを送信したらメッセージの最下部まで自動でスクロールするようにするために使うメソッドです。
animateメソッドは、メソッドを利用したオブジェクト(レシーバ)が持つプロパティなどを、指定した値まで徐々に変化させることができるメソッドです。
【例】縦横50pxのdiv要素を用意し、これに対して以下のようにanimateメソッドを使用しました。

```
$('.box').animate({'height' : '200px'});
```
heightプロパティを指定して、200pxまで増えるように指定しています。
これを応用して、メッセージが投稿されたら必ず一番下までスクロールするようにします。
【例】

```message.js
〜省略〜
$('.messages').append(html);      
$('form')[0].reset();
〜省略〜
```
【例】

```
$('.messages').animate({ scrollTop: $('.messages')[0].scrollHeight});
```
scrollTopはjQueryのメソッドで、指定した値の分だけanimateメソッドを利用した要素をスクロールします。
$('.messages')[0].scrollHeightの部分は、メッセージが入ったdiv要素のスクロールできる高さの数字を取得しています。
このように書くことによってスクロールすべき分メッセージが入ったdiv要素をスクロールできます。
また、投稿した際に、テキストボックスの中の文字列や、選択した画像は空にする必要があります。jQueryの.reset()を用いて、画像とテキストを空にするような実装を行います。
Python、例外処理について

###例外処理についてメモ
例外処理とは途中でエラーが発生してプログラムが中断しないようにする処理
例えば以下を実行してみる。


```.py
list = [1,2,3,4,'a',5,6]
for i in list:
   print(i/10)
```

とすると、

```.py
0.1
0.2
0.3
0.4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-78c5fd70e082> in <module>
      2 
      3 for i in list:
----> 4     print(i/10)

TypeError: unsupported operand type(s) for /: 'str' and 'int'
```

"a"表記のためエラーが発生し、プログラムが中断してしまう。
そこで、エラー表記をする。


```.py
for i in list:
    try:
        print(i/10)
    except:
        print("Error")
```

```.py
0.1
0.2
0.3
0.4
Error
0.5
0.6
```

うまくいった。
Ajaxとjbuilderの参考リファレンスなど

##Ajax
[【jQuery日本語リファレンス 】Ajax](http://semooh.jp/jquery/api/ajax/jQuery.ajax/options/)
Ajaxのリファレンスになります。オプションも含めて説明しています。
[【js STUDIO】$.ajax()](http://js.studio-kingdom.com/jquery/ajax/ajax)
オプションや動作を含めて説明されています。
[Ruby on RailsのAjax処理](https://qiita.com/ka215/items/dfa602f1ccc652cf2888)
RailsでのAjaxの流れを図解つきで説明されています。
##jbuilder
[【GitHub】jbuilder](https://github.com/rails/jbuilder)
jbuilderのドキュメントです。
[Rails4でJSONを作るならto_jsonよりjbuilder](https://llcc.hatenablog.com/entry/2015/03/07/103121)
jbuilderの使い方を丁寧に説明した記事になります。
Macでanyenvでインストールしたpyenvなど（**env）のパスが通らない時の解決法

#はじめに

もうすぐ新年度ということで、新しいPCに買い替えたりすることも多いと思います。
僕もその一人で、新規Macで環境構築してた時にanyenvでインストールしたpyenvなどでパスが通らない問題に面しました。

その解決方法をシェアします。

# 原因&解決策
最近のMacは買った時のOSはcatalinaのはずです。

https://support.apple.com/ja-jp/HT208050

したがって、
~/.bash_profile
に環境変数などを書いていても反映されません。

よって
~/.zshrc
に書くことによって解決できます。

# e.g.)
https://github.com/anyenv/anyenv
のreadmeにもありますが
manualだったらzshの場合の記載に従えばいいでしょう。



brewでインストールした場合、

```
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
```
を

```
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
```

に変えれば良さそうです。
Python、for〜(range)について

###for文のrange関数についてメモ

・range(n)は、0からn−１の整数列
・range(n,m)は、nからm-1の整数列
・range(n,m,k)は、nからm-1の公差p

```
for i in range(10):
    print(i)
```

```
0
1
2
3
4
5
6
7
8
9
```

iに１から９の値を代入している。

```
for i in range(4,10):
    print(i) 
```

```
4
5
6
7
8
9
```

iに４から９までの値を代入している。

```
for i in range(4,10,2):
    print(i)
```

```
4
6
8
```

iに４から９までの値で２空けて代入している
Ethereumの保有ETHをZabbixで監視

# はじめに
Ethereumのアカウントが保有しているETHが不足すると
コントラクトの実行ができなくなります。
そこで、アカウントが保有しているETH量をZabbixで監視するようにしました。

自前でEthereumノードを立てていることを想定しています。
gethのバージョンは1.8.13-stableです。

# 作業内容
## ETH量の取得
保有しているETH量を知るには
gethで接続して `eth.getBalance()` でwei単位で取得し、
それを`web3.fromWei()` でETH単位に変換することで知ることができます。

gethコマンドのオプションで`--exec`をつけると非対話的に実行できます。
コマンドで書くと以下のような感じです。

```bash
$ geth atacch ipc:/どこか/geth.ipc --exec 'web3.fromWei(eth.getBalance("0xアドレス"),"ether")'
9999.99999
$
```

この値を返すスクリプトを作り、それをZabbixエージェントに実行させれば監視ができそうです。
早速作ってみましょう。

## スクリプト

### zabbix-eth-getBalance.py
/usr/local/bin/に作成し、Ethereumユーザで実行できるようにしておきます。

```bash
cd /usr/local/bin/
vi zabbix-eth-getBalance.py
chmod 755 zabbix-eth-getBalance.py
```

中身は以下の通りです。

```python:/usr/local/bin/zabbix-eth-getBalance.py
#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
"""指定したアカウントのETH量を表示
Zabbixで監視してETHが一定量以下になったらトリガー検知など
エラー発生時には-1が返る
account_nameは呼び出し元での区別用につけているだけで、実際には使っていない

Args:
    $1 account_name
    $2 account_address

"""

import sys
import subprocess

# 設定
IPC_FILE = '/どこか/geth.ipc'
GETH = '/bin/geth'


def getBalance(account_address):
    """指定アカウントの保有ETH残高を返す
    Args:
        param1(str): 指定アカウントのアドレス
    Returns: 
        long: ETH残高　エラー時は-1
    """
    try:
        cmd = f'web3.fromWei(eth.getBalance("{account_address}"), "ether")'
        proc = subprocess.run([GETH, 'attach', f'ipc:{IPC_FILE}', '--exec', cmd], \
            stdout=subprocess.PIPE, \
            stderr=subprocess.PIPE, \
            universal_newlines=True)
        return proc.stdout.strip()

    except Exception as e:
        return -1


###############################################################################
account_name = sys.argv[1]
account_address = sys.argv[2]
print(getBalance(account_address))
```

`subprocess.run`でgethコマンドを実行しています。
戻ってきた値を文字列で受け取るために`universal_newlines=True`を指定しています。
Pythonが3.7以上の場合は非推奨になっているので同オプションの代わりに`text=True`を使いましょう。

## 権限設定
zabbis_agentdはzabbixユーザで動いています。
geth.ipcファイルはEthereumユーザしか触れない権限になっているので、
zabbixユーザがEthereumユーザでたたけるようにsudoersを編集します。

`visudo`で以下を追記します。

```bash
zabbix ALL=(Ethereumユーザ) NOPASSWD: /usr/local/bin/zabbix-eth-getBalance.py
```

実際に動くかテストするにはrootユーザから以下のようにたたきます。

```bash
sudo -u zabbix sudo -u Ethereumユーザ /usr/local/bin/zabbix-eth-getBalance.py アカウント名 0xアドレス
```

`sudo: 残念ですが、sudo を実行するには tty が必要です` というメッセージが返ってきた場合は、
再度`visudo`でsudoersを編集します。

変更前

```bash
Defaults    requiretty
```

変更後

```bash
#Defaults    requiretty
Defaults:Ethereumユーザ !requiretty
```
参考：[[Sy] cronでsudoが必要なコマンドを実行しようとしたらTTYないとダメだよとエラーになる場合の設定方法](https://utano.jp/entry/2016/04/cron-sudo-require-tty/)

## Zabbixエージェントの設定
ユーザパラメータの設定ファイルを作成します。

```bash:/etc/zabbix/zabbix_agentd.d/userparameter_ethereum.conf
UserParameter=ethereum.balance[*], sudo -u Ethereumユーザ /usr/local/bin/zabbix-eth-getBalance.py $1 $2
```
作成したら読み込ませるためzabbix-agentを再起動しましょう。

## Zabbixサーバの設定
### アプリケーション
アプリケーションとして`Ethereum`を作成します。

### アイテム
アイテムを作成します。

|項目|値|
|---|---|
|名前|balance __アカウント名__ |
|タイプ|Zabbixエージェント|
|キー|ethereum.balance[__アカウント名__, __0xアドレス__ ]|
|ホストインターフェース|監視対象のもの|
|データ型|数値（浮動小数）|
|単位|ETH|
|アプリケーション|Ethereum|

上記以外の項目はそれぞれの環境に合わせて適当に設定します。
値が取れれば成功です！

テンプレートとして作ったりトリガー設定などは適当に。。。
基本情報3月23日(２３週目)

##目標と結果##

##目標##
•過去問1回分を午前、午後共に150分計測し、取り組む。
•自分の苦手な分野の部分をピックアップし、集中的に取り組む。(アルゴリズム、表計算を重視)
•学習時間14時間確保する。

##振り返り##

__KEEP__

__TRY__

__PROBLEM__

##次週 and more...##
[3/16](https://qiita.com/Comitakato0515/items/93f54b3f7a0166cb9fc6)
APIとは

##API
Railsは必要なHTMLを組み立てて返すのが仕事ですが、JavaScriptから便利に扱えるようにJSON形式でデータを返すようにすることもできます。
HTMLだけではなく、必要なデータだけをJSONなどの形式で返すサーバの仕組みのことをAPIと呼びます。
##APIの作り方
元々あるコントローラに対して非同期通信の場合には非同期通信用のデータを返す実装を付け加えます。
コントローラーの1つのアクションの中でHTMLとJSONなどのフォーマット毎に条件分岐できる仕組みがあります。
フォーマットごとに処理を分けるには、respond_toを使用します。
##respond_to
respond_toメソッドを使うと、リクエストに含まれているレスポンスのフォーマットを指定する記述を元に条件分岐ができます。
【例】

```xxxx.rb
respond_to do |format|
  format.html { render ... } # この中はHTMLリクエストの場合に呼ばれる
  format.json { render ... } # この中はJSONリクエストの場合に呼ばれる
end
```
HTMLを返す場合は、該当するビューを呼びその中データを生成していましたが、JSONを返す場合はRubyのハッシュの状態のままrenderメソッドに渡すだけでJSONに変換してくれるので、コントローラーから直接データを返すことができます。
【例】

```xxxx.rb
respond_to do |format|
  format.json { 
    render json: { id: @user.id, name: @user.name }
  }
end
```
上記のように記述することでcontrollerだけでレスポンスを完結させることもできますが、jbuilderを使用する、つまりファイルを分割することで、よりわかりやすい形でJSON形式のデータを作ることができます。
【例】

```app/views/messages/show.json.jbuilder
json.content @message.content

=> { content: "@messageのcontent" }
```
jbuilderは左がキー・右がバリューのようなハッシュの形になっています。
上記の例だと、json.contentがkeyで、@message.contentがvalueとなります。
githubに別アカウントでプッシュする方法 - 間違えて他のgithubアカウントでpushしたとき

間違えて会社のアドレスで作ったGitHubアカウントじゃなくて私用のアカウントでcommitしpushしたとき、見ず知らずのアカウンが、チーム開発のリポジトリのcommitに乗ってしまうことがあります。

そんなときは、ローカルで、下記のように実行して直して


```
% git config user.name ryosuke.fujisawa 
% git config user.email ryosuke.fujisawa@社用アドレス.com
```
んで、確認して

```
% git config user.name   
% git config user.email 
```
上記のコミットは間違って私用アカウントでpushしたものですよとチームに伝わればok

```
 % git commit --allow-empty -m "gitユーザーの変更"
 % git push
```
基本情報3月16日(２２週目)

##目標と結果##

##目標##

•参考書の理解。
•アルゴリズムへの理解度を深める。
•平成過去問道場午後問題を解く。
##振り返り##
過去問の試験を1度150分で受けました。結果は半分以下、1/3しか取れていない状況です。原因としてはアルゴリズム依然に言語の理解を深められていない。言語を理解するため勉強時間を増やしつつ、自分がどのように理解できるかを再計画していきたいと思います。
__TRY__
1日1時間言語などを復讐すること。
__KEEP__
勉強時間の確保。
アルゴリズム、言語への理解度を深めつつ、午前問題も両立させる。
__PROBLEM__
勉強の再計画立て直すこと。
次週 and more...

3/9
Cordovaのチュートリアルをやってみる

公式チュートリアル：http://ccoenraets.github.io/cordova-tutorial/index.html


## Cordovaプロシェクトの作成
Node.jsの最新バージョンをインストール

Cordova CLIのインストール

```
[windows]
npm install -g cordova

すでにインストール済みの場合は最新バージョンにアップデート
npm update -g cordova

[mac]
sudo npm install -g cordova

すでにインストール済みの場合は最新バージョンにアップデート
sudo npm update -g cordova
```

プロジェクトを保存するディレクトリに移動し、workshopという名前のディレクトリにWorkshopというCordovaプロジェクトを作成。

```
cordova create workshop com.yourname.workshop Workshop
```

プロジェクトディレクトリに移動。

```
cd workshop
```

SDKのインストール
workshopディレクトリにて
[iOS]

```
cordova platforms add ios
```
[Android]
https://developer.android.com/studio　からインストール後

```
cordova platforms add android
```

workshopディレクトリにて、基本的なプラグインを追加

```
cordova plugin add org.apache.cordova.device
cordova plugin add org.apache.cordova.console

上記は旧式らしくエラー出る。

cordova plugin add cordova-plugin-splashscreen
cordova plugin add https://github.com/apache/cordova-plugin-console.git#1.0.0

上記で対応可？
詳細は未調査なので後ほど探ります。
```
エラー対応の参考：https://qiita.com/konyavic/items/ca6bec224ddd6abeb0ac


ディレクトリ構成

wwwが、コーディングファイル保存場所

platformsは、iOS/Androidなど異なるプラットフォームのためのアプリケーションをビルドする場所。
いじらない。

プラグインはpluginsにインストールされる。

アプリケーションパラメータ（名前、作成者など）はconfig.xmlに保存される。
クラスにアクセスする

##ごり押し
クラスの変数を取得したければ`○○.class.getDeclaredFields()`
Fieldクラスの配列として取得できます

メソッド取得したければ`○○.class.getDeclaredMethods()`
Methodクラスの配列として取得できます

名前取得するくらいならExceptionにもならないのでぜひ覚えておきたいところ
汎用性につながりそうですね

外部でメソッド`invoke`は怖いので非推奨

```クラスにアクセス.java
	/**
	 * 指定されたクラス内の、指定された変数を取得し、その変数のクラス内のメンバ変数を全件取得する.
	 * 
	 * <pre>
	 * たとえば.
	 * 
	 * MyModelクラスの中に
	 * 
	 * private MyModel2 model;
	 * private String str;
	 * 
	 * とあり、
	 * MyModelクラスの中に
	 * 
	 * private String id;
	 * private String name;
	 * 
	 * とあった場合に
	 * 
	 * idとnameの文字列を取得する
	 * </pre>
	 * 
	 * @param clazz 指定クラス
	 * @param fieldName 全メンバを取得したい型の変数
	 */
	public static List<String> get2(Class<? extends Object> clazz, String fieldName) {
		return Stream.of(clazz.getDeclaredFields())
				// ↑クラス内の全メンバ変数を取得(modelとstr)
				.filter(v -> fieldName.equals(v.getName()))
				// ↑指定された変数と一致するメンバ変数に絞る(MyModel2型のmodelになる)
				.map(Field::getType)
				// ↑その変数の型クラスに変換(MyModel2クラスになる)
				.map(Class::getDeclaredFields)
				// ↑クラス内の全メンバ変数を取得(idとname) 配列です
				.map(Arrays::asList)
				// ↑配列をリストに
				.flatMap(Collection::stream)
				// リストならして、streamに
				.map(Field::getName)
				// 変数名に変換(idとnameという文字列になる)
				.collect(Collectors.toList());
				// リストにして返却
	}
```

##アノテーションを持つものを取得とかもできる
なんならアノテーション文字列を取得とかもできたりする

```.java
	/**
	 * 指定された変数名を取得する.
	 * 
	 * <pre>
	 * 例えば
	 * MyModelっていうクラスの中で
	 * 「@Id」 アノテーションを持っている変数が欲しいなら
	 * get(MyModel.class, Id.class)として使う
	 * </pre>
	 * 
	 * @param clazz 検索対象のクラス
	 * @param annotation 指定アノテーションクラス
	 */
	public static List<String> get(Class<? extends Object> clazz, Class<? extends Annotation> annotation) {
		return Stream.of(clazz.getDeclaredFields())
				// ↑クラスの持つメンバ変数を取得
				.filter(v -> Stream.of(v.getAnnotations())
						// ↑メンバ変数に付与されているアノテーション一覧を取得
						.map(Annotation::annotationType)
						// ↑アノテーションクラスに変換
						.anyMatch(annotation::equals))
				// ↑引数で指定されたアノテーションクラスと一致するものに絞る
				.map(Field::getName)
				// ↑その変数名を取得
				.collect(Collectors.toList());
	}
```

アノテーション文字列取得
`@Column(name = "annotation", value = "aaaa")`
とかの文字列そのものを取得できます
実際に読み込まれるときは
`@Column(name="annotation", value="aaaa")`
というように`name="`と、しっかり空白詰まってたりします
細かいことは実際に実行してログで確認してください

```.java
		List<String> annotation = Stream.of(引数.class.getDeclaredMethods())
				.map(Method::getAnnotations)
				.map(Arrays::asList)
				.flatMap(Collection::stream)
				.map(Annotation::toString)
				.collect(Collectors.toList());
```

##何に使えるか
クラス名や変数名が欲しくなる時すなわち
entity名やカラム名
そう、SQL生成できそうですね
キャメルケース、スネークケース変換や
上手いこと正規表現を使いまくって
汎用的にSQL生成できるメソッド作れます