OmniAICreator/Qiita-1.07M huggingface dataset:
初心者のためのpandas基礎matplotlibでヒストグラム作成

#pandasとは
Pythonにて、構造化データ（テーブル型のデータ）を扱うためのライブラリです。ファイルの読み込みやその後の加工・抽出処理などを簡単に行うことができ（SQL的な感覚で行うことができ）、機械学習などのデータの前処理で必須となるライブラリです。
他項目への目次は[こちら](https://qiita.com/Yanagawa_Yoshihisa/items/e1d7d0e939f58e7301ea)になります。

#1.ヒストグラム
ヒストグラムは前準備の段階のデータ確認で多く使用します。今回はmatplotlibとうライブラリを使用します。Excelでやると面倒なヒストグラムが簡単に作成できます。データはおなじみのタイタニックのデータを利用しました。

#1.0.ライブラリインポート&データ読み込み
pandasにpdという名前をつけてimportする。今回は、matplotlib.pyplotもpltという名前をつけてインポート。サンプルデータがタイタニックのもの利用

```python:
import pandas as pd
import matplotlib.pyplot as plt
dataframe = pd.read_csv('train.csv')
dataframe.head()
```

#1.1.ヒストグラム作成
年齢（column｢Age｣）にてヒストグラム作成します。dropna()にて欠損値をドロップします。

```python:
plt.hist(dataframe['Age'].dropna(),bins = 10, range = (0,100),color = 'Blue')
plt.show()
```
![スクリーンショット 2020-07-09 14.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/8cd13133-c0b5-f1c2-8329-8903db491736.png)

bins(表示する瓶の数)、range(データの幅)、clor(色)を指定します。

#1.2.ヒストグラム作成（正規化）
正規化し全体の合計が1になるようにします。

```python:
plt.hist(dataframe['Age'].dropna(),bins = 20, range = (0,100),color = 'Blue', normed = 'true')
plt.show()
```
![スクリーンショット 2020-07-09 14.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/1f490e8c-f94b-88b7-335b-eb90e72e2e16.png)

#1.3.タイトル等追加
見やすい様にタイトル等を追加します。

```python:
plt.title('Age Histogram', fontsize=14)
plt.xlabel('Age', fontsize=14)
plt.grid(True) 
plt.hist(dataframe['Age'].dropna(),bins = 20, range = (0,100),color = 'Blue')
plt.show()
```
![スクリーンショット 2020-07-09 14.57.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/af2c2c99-ab44-c1b3-74ff-1a37e0f0ae0b.png)

.title（タイトル）、.xlabel(X軸ラベル)、.grid(グリッド)を追加します。

#＜応用＞積み上げ表示
男性（male）と女性（femal）の内訳表示を積み上げ表示を使って表示します。プロットの準備として、malelist_mとmalelist_fをそれぞれ定義します。

```python:
malelist_m = dataframe['Sex'] == 'male'
malelist_f = dataframe['Sex'] == 'female'

plt.title('Age Histogram', fontsize=14)
plt.xlabel('Age', fontsize=14)
plt.grid(True) 
plt.hist([dataframe[malelist_m]['Age'],dataframe[malelist_f]['Age']],bins = 20, range = (0,100), color = ['Blue', 'Red'], label = ['male','femal'], stacked=True)
plt.legend(loc="upper right", fontsize=14) 
plt.show()
```
![スクリーンショット 2020-07-09 15.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/9f5fa4e2-7744-1bf2-6028-453a445b2d19.png)

複数積み上げたい場合は、hist([X1,X2])のように表記します。stackedをTrueにすると積み上げます。（Falseだと併記）labelにて凡例を定義します。.legendにて凡例を追加します。

#最後に
初心者にもわかるように、Pythonで機械学習を実施する際の必要な知識を簡便に記事としてまとめております。
目次は[こちら](https://qiita.com/Yanagawa_Yoshihisa/items/a3fa521d89c471b3e71f)になりますので、他の記事も参考にして頂けると幸いです。
CKEditorで余計な<ul>タグが出てくるのを防ぐ

# ハマったこと
記事のコンテンツをCKEditorを使って管理しているのですが、以下のタグを保存したときに悲劇は起こりました...

```
<li>ほげほげ</li>
<li>ふがふが</li>
<li>なむなむ</li>
```

CKEditor君 :「`<ul>`タグなかったから追加しといたわ~ 感謝してや」

わい :「いや、テンプレート側に`<ul>`書いてあるんだけど余計なことしないで(# ﾟДﾟ)」


CKEditorの仕様で保存すると `<ul>` タグが消えてしまうらしい。


# 原因
[ドキュメント](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_dtd.html#property-S-intermediate)を見てみると `CKEDITOR.dtd.$intermediate` なるものがありました。

>List of elements that are not to exist standalone that must live under it's parent element.


これだ...


# 解決策
CKEditorの `config.js` に以下の設定を追加し、CKEditorの `<li>` に対する振る舞いを強制的に削除しました。

```
delete CKEDITOR.dtd.$listItem['li'];
delete CKEDITOR.dtd.$intermediate['li'];
```


`delete CKEDITOR.dtd.$intermediate['li'];`

これだけで、行けそうな気がしたんですがうまくいかなかったので `$listItem` を削除することでうまくいきました。


# 備考
私はCKEditorをGCSの画像をいい感じに扱いたいために使っていて基本的にHTMLタグを直書きなので問題ないのですが、エディタを使っている人は多分この設定を入れるだけだと、リストを挿入するときに `<dt>` や `<dd>` になっちゃうだけだと思うので注意が必要です(多分)
【EMMET 記法】　基本　よく使うやつ　エメット記法　まとめ

##【メリット】
■　コーディングが早くなります。
■　ミスが少なくなります。


##【開発環境】
■ Mac OS catalina
■ **VS code**

##【やっていきましょう】

##HTML版
#### div.hoge

```html:hoge.html
<div class="hoge"></div>
```

#### div#hoge
```html:hoge.html
<div id="hoge"></div>
```

#### div*3
```html:hoge.html
<div></div>
<div></div>
<div></div>
```

#### div>h2
```html:hoge.html
<div>
  <h2></h2>
</div>
```


##CSS版

#### h100
```css:hoge.css
heigh: 100px;
```

#### w100
```css:hoge.css
width: 100px;
```

#### bc
```css:hoge.css
background-color: #fff;
```

#### c
```css:hoge.css
color: #fff;
```

#### ta
```css:hoge.css
text-align: center;
```

#### m10
```css:hoge.css
margin: 10px;
```

#### p10
```css:hoge.css
padding: 10px;
```

##【まとめ】
■基本的に使うやつなので、他にもたくさんあります。
■実装５倍くらいのスピードになるので、是非


##【合わせて読みたい】

■ **【メソッド集】　rails メソッド　まとめ　基礎　随時追加**
https://qiita.com/tanaka-yu3/items/89abad875187494bec53

■ **【Javascript】 メソッド　まとめ　基礎基本コード　メモ**
https://qiita.com/tanaka-yu3/items/2438798d159fa402b1d5

■ **【Rails new】Ruby on rails アプリケーション作成**
https://qiita.com/tanaka-yu3/items/3fe1ed2852c6513d3583

■参考　emmet記法
https://tracpath.com/works/development/emmet-for-web-developers/
WebStorageで1回目のアクセス時のみモーダルを表示する WebStorageで1回目のアクセス時のみモーダルを表示する

###HTML
```html
<div id="c-modal_bg"></div>
<div id="c-modal">
    <p>モーダルの中身です。<br />
    モーダルの中身です。<br />
    モーダルの中身です。</p>
    <p><input type="checkbox" name="acs_next" value="" />次回以降表示しない</p>
    <div id="c-modal_close">閉じる</div>
</div>
```
###Javascript

```javascript
// モーダルの処理
var bg = document.getElementById('c-modal_bg');
bg.addEventListener('click', modal_close, false);
 
var close = document.getElementById('c-modal_close');
close.addEventListener('click', modal_close, false);
 
function modal_close() {
    var modal = document.getElementById('c-modal');
    modal.style.display = 'none';
    bg.style.display = 'none';
 
    // チェックボックスにチェックが入っている場合は、次回以降表示しないようにする
    if(document.getElementsByName('acs_next')[0].checked) {
        sessionStorage.setItem('acs2', 'on');
    }
}
 
// 「次回以降表示しない」にチェックを入れていない場合
if(sessionStorage.getItem('acs2') === null) {
 
} else {
    // チェックを入れている場合はモーダルを削除
    modal_close();
}
```
---
 ソース
[http://cly7796.net/wp/javascript/display-modal-only-on-first-access-using-webstorage/](http://cly7796.net/wp/javascript/display-modal-only-on-first-access-using-webstorage/)
結局【rails db:migrate】は何をやっているのか？

Railsで当たり前のように使っている**rails db:migrate**ですが実は何となく使っていて実際に何をしているか分かっていない方もいらっしゃるのではないでしょうか？

自分もつい最近までは何となく、**あーmigrationファイルをデータベースに反映してるのね～**程度にしか理解していませんでした。

しかし深くまで勉強し行くうちに、「あれ、結局Railsのそれぞれのコマンドって何をしてるんだろう」と思ったので今回記事にまとめました。

## migrateはmigrationファイルの内容をDBに反映する行為

結論から言うと
**migrateはmigrationファイルの内容をDBに反映する行為**
になります。

しかしこれだけでは弱いのでのでもう少し深堀していこうと思います。

## MVCモデルについて

まずは基礎認識の部分ですが、Ruby on RailsはというフレームワークはMVCというモデルを使用しております。

![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536448/f22d39e1-f274-a387-5617-229b5d47597b.jpeg)

ここでは詳細を省かせていただきますが、

- サーバーからのリクエストに応じてアクションを実行する**Controller**
- データベース(DB)とのやり取りを行う**Model**
## rails g model
- ブラウザ表示を担う**View**

という3つの部分から構成されます。

## rails g model

migration(マイグレーション)を理解する前にまずはモデルの作成コマンドから紐解いていきましょう。

rails g modelコマンドを実行すると大きく分けてmodelファイルとmigrationファイルの2種類が作成されます(厳密にいうとさらにtestファイルなども自動作成されます)。

これらのファイルはそれぞれ

- migrationファイル→DBに変更を加える内容
- modelファイル→DBとRailsのアプリケーションを繋ぐ

といった役割があります。

![Untitled Diagram.3png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536448/edd9ff8a-a8f4-d688-3710-106be91c1a2f.png)


特にここで作成されるモデルは全てApplicationRecordというクラスを継承しております。


```ruby:models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
end

```

さらにこのApplicationRecordクラスの親クラスはActiveRecord::Baseを継承しています。

```ruby:models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

```

このActiveRecordクラスはDBとやり取りする際に必要なSQL構文を翻訳する機能を持っています。

そのため**いちいちSQL構文を書かずとも簡単にDBにアクセスしデータをいじくることができる**のです。

Railsから入るとあまりなじみがないかもしれませんが、通常DBにアクセスしデータを操作するためには**SQLという別の言語を使って指示を飛ばさなくてはなりません**。

```SQL:SQL文の例
-- テーブルを作成
CREATE TABLE USERS (
    ID    INT NOT NULL PRIMARY KEY,
    NAME  VARCHAR NOT NULL 
    AGE INT NOT NULL
);

-- データを作成(railsではtable.create(value1, value2…))
INSERT INTO USERS VALUES (1,'イチハラ','');

-- データをすべて選択(railsではmodel.all)
SELECT * FROM USERS
```

しかしRailsではこの**ActiveRecord**を使用することで自動でSQLに翻訳し、**より直感的で簡単な構文でDBを操作**することができるのです。

またこのActiveRecord::Baseクラスでは自動的にゲッターとセッターが定義されているため、意図的に**attr_accessorなどを定義せずともインスタンスの値を参照**することができます。

なるほど…
確かに便利だけどこれがゲッターとセッターを理解するのに苦しんだ訳か…

[>> セッターとゲッターってそもそも何？](https://qiita.com/ichihara-development/items/50739bad9b75a78a8153)

## rails db:migrate

rails db:migrateを実行すると作成されたmigrationファイルを基にDBに変更を加えます。今回の場合はmodel作成時のmigrateの為、DB上に新たにテーブルを作成します。

```xxxxxxxx_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :name
      t.timestamps
    end
  end
end

```

ActiveRecordによって作成されたテーブルは以下のような特徴を持ちます。

- テーブル名はmodelの複数形(Post → posts)
- id,created_atが自動作成

ちなみに**rails g migration**によってmigrationファイルを作成した場合は自動的にchangeメソッドが定義されており、すでに作成されたテーブルに変更を加えることができます。

```xxxxxxxx_oooo.rb
class PasswordDigestToUsers < ActiveRecord::Migration[5.1]
  def change
    add_column :users, :password_digest, :string
  end
end

```

## 終わり

以上がマイグレーションについてです。


あまり自信があるわけではないので、間違っていた李解説がおかしい部分があればご指摘いただけると幸いです！
DatePickerカレンダー表示中のスクロールを止める

## 問題

カレンダーを表示しているときにバックグラウンドにスクロール可能なエリアがあると、マウスホイールにてスクロールできてしまいます。
カレンダー表示中はスクロールを止めたい。

![スクリーンショット 2020-07-09 15.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/50723cb5-7f6f-dc97-42f9-db8b56990caa.png)


## 対処方法

下記のようにProviderを登録するとスクロールしなくなるようです。

```
import {MAT_DATEPICKER_SCROLL_STRATEGY} from '@angular/material/datepicker';
import {Overlay, BlockScrollStrategy} from '@angular/cdk/overlay';

export function scrollFactory(overlay: Overlay): () => BlockScrollStrategy {
  return () => overlay.scrollStrategies.block();
}

@Component({
    selector: 'app-xxxx',
    templateUrl: './xxx.html',
    styleUrls: ['./xxx.scss],
    providers: [
        { provide: MAT_DATEPICKER_SCROLL_STRATEGY, useFactory: scrollFactory, deps: [Overlay] }
    ]
})
```
時間経過とパフォーマンスの変化　集中力への気づき

私が支援したチームのメンバーが同じ背景の作業（ホワイトカラーの頭脳労働）をしている**時間経過（最大120分）とパフォーマンスの変化**を測定しました。

これによって、パフォーマンスが維持できる時間、一定時間経過後に休憩をとることで、パフォーマンスが改善されるかがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621379/e81c0941-081a-8faa-1702-88d88c7f7941.png)

このグラフから、**高いパフォーマンスが維持できているのが、60分弱**であることです。
一方で60分以降は10～15分の休憩を二回とっても元の高いパフォーマンスに戻るのが一瞬だけであり、60分を超えると**パフォーマンスが下がる**ことが分かりました。

以前、タスク粒度について1時間を目標にする事を述べましたが、このデータからも1時間程度を推奨することが分かります。
Java SE11 Silver 取得にかかった時間、使った教材

# 試験概要
Oracle Certified Java Programmer, Silver SE 11 認定資格は、Javaアプリケーション開発に必要とされる基本的なプログラミング知識を有し、上級者の指導のもとで開発作業を行うことができる開発初心者向け資格です。日常的なプログラミング・スキルだけでなく、さまざまなプロジェクトで発生する状況への対応能力も評価することを目的としています。Oracle Certified Java Programmer, Silver SE 11 認定資格を取得するためには、Java SE 11 Programmer I (1Z0-815-JPN) 試験の合格が必要です (認定パス)。
引用：[リンク](https://www.oracle.com/jp/education/certification/jse11-5570635-ja.html)
# 受験までのあらすじ
大学院卒業後、某大手メーカーに就職し、安定した人生を送れそうではあったが仕事に楽しみを見出すことができず退職。前から興味のあったプログラミングの学習を始めてみたところ時間を忘れて没頭してしまう。そしてエンジニアに転職することを決意し、本格的にJavaの勉強を開始。転職活動である程度評価されるオラクルOracle Certified Java Programmer, Silver SE 11を受験することを決意した。
# 使用した教材
1. すっきりわかるJava入門：
　言わずと知れた入門書。まずはこれを3周読みました。実際にコードを書いたほうがいいといいますが私はほとんど書いていません。読むだけ勉強法でした。
2. 紫本：
silver受験対策1冊目に購入。正直わかりずらいが頑張って2週通読。今振り返るといらなかった気がするが使える表などがあり部分によっては重宝した。黒本でどうしてもわからないところは紫本でしっかりやりこんだ。
3. 黒本：
　こちらも言わずと知れた名著。2周行い2周目に間違えたところのみ3周行った。試験には本書と同じ内容の問題が半分ほどあったイメージ。これをやりこんでおけば合格点はさほど難しくないと思う。なお、最後の総仕上げ問題は絶対にやるべきである。私は模試はいいやと思って直前までやらなかったが、そもそもこの総仕上げ問題、それまでの各章に書いてないことも山ほど載っているので、仕上げという概念でとらえるべきではなかった。各章と同じくこちらも3周行うべきである。

# 勉強時間
　正確に測ってないがだらだらとJavaの学習を3か月ほど行っていた。資格のことは頭になく暇つぶし程度に行っていたがこの期間でスッキリわかるを2週行っていた。そのあと資格取得に向けて本格的に勉強開始。1日2時間ほどの学習を2カ月ほど続けたため60時間ぐらい学習したことになる。

# 試験結果
合格。合格点は64％であったが78％で合格。これがいい結果かと言われればそうでもない気がする。
# 最後に
基本の勉強をして、Javaを体系的にある程度理解したらひたすら黒本をやりこめばより短い時間での合格が可能と思われる。ただ、試験合格を目的とするのかJavaを使えるようになるのを目的にするのかでも変わってくると思う。なお、私個人の意見としては一旦資格取得を目的にしていいと思う。なぜなら私はどちらかと言うと途中から資格取得を目的に学習していたが、資格取得後個人的にちょっとしたコードを書いているが割とすらすら学んだことをアウトプットできている。まずは資格取っちゃおうぐらいの気持ちで問題ないと思われる。
CircleCIとSlack連携時のsuccess_messageの罠

# 概要
CircleCI のorbの ```circleci/slack@3.4.2``` の
```slack/status```を使って、```success_message```, ```failure_message```を
指定するときは、スペース使うとメッセージが表示されない。

スペースを取り除いた状態にすると表示される。

# 問題
CircleCI のorbの ```circleci/slack@3.4.2``` の
```slack/status``` を使って、```success_message```, ```failure_message```を下記のように指定すると何故かメッセージが表示されない。

.circleci/config.yml

```yml

version: 2.1

orbs:
  slack: circleci/slack@3.4.2

executors:
  default:
    docker:
      - image: circleci/python:3.5-stretch-node-browsers-legacy

jobs:
  notification:
    executor: default
      - slack/status:
          # これだとSlackにメッセージが送信されない
          
          success_message: "${CIRCLE_PROJECT_REPONAME} のビルドが成功しました\n http://example.com/artifact_path"
          failure_message: "${CIRCLE_PROJECT_REPONAME} のビルドが失敗しました"
          webhook: ${SLACK_WEBHOOK} # CircleCIの環境変数にWebhookのURLを設定済み


workflows:
  version: 2
  test :
    jobs:
      - notification
```

# 解決策
半角スペースを取り除くとメッセージが表示される。

```yaml
  success_message: "${CIRCLE_PROJECT_REPONAME}のビルドが成功しました\nhttp://example.com/artifact_path"
  failure_message: "${CIRCLE_PROJECT_REPONAME}のビルドが失敗しました"
```


# 関連ドキュメント
https://circleci.com/orbs/registry/orb/circleci/slack#commands-status  success_message, failure_message には特に注意がない。
【Swift】ナビゲーションバーの戻るボタンの処理をカスタマイズしたい

## はじめに

ナビゲーションバーの戻るボタンをタップ時に、「ダイアログを表示 -> キャンセルの場合、遷移させない」という処理を実装したかったのですが、デフォルトで実装されている戻るボタン （`backBarButtonItem`) をカスタマイズする方法ではうまくいきませんでした。

<details><summary>ダメだった方法</summary><div>

```swift:SomeViewController.swift
// MARK: onTapBackButton は呼ばれない
let backButton = UIBarButtonItem(image: chevronLeftImage, style: .plain, target: self, action: #selector(onTapBackButton(_:)))
navigationItem.backBarButtonItem = backButton
```
</div></details>

そこでデフォルトの戻るボタンは使わず、新たにボタンを作成し `leftBarButtonItem` として配置するという方法で実装しました。

## 環境

- Xcode 11.5
- Swift 5.2.4

## デフォルトの戻るボタンを置き換える

特定の ViewController のみボタンを置き換えた場合、デフォルトの戻るボタンと見た目が変わってしまうため、今回は全てのボタンを置き換えます。
すべての画面で読み込む親クラスとして `CommonViewController` を生成し実装していきます。

<details><summary>コード全体</summary><div>

```swift:CommonViewController.swift
class CommonViewController: UIViewController {
	override func viewDidLoad() {
        super.viewDidLoad()
  
        backButton()
    }
 
    private func backButton() {
        let currentViewController = String(describing: type(of: self))
        guard !currentViewController == "FirstViewController" else {
            return
        }
	
        let chevronLeftImage: UIImage? = UIImage(systemName: "chevron.left")
        let backButton = UIBarButtonItem(image: chevronLeftImage, style: .plain, target: self, action: #selector(onTapBackButton(_:)))
        navigationItem.leftBarButtonItem = backButton
    }
 	
    @objc
    func onTapBackButton(_ sender: UIBarButtonItem) {
  	    navigationController?.popViewController(animated: true)
    }
}
```
</div></details>

最初の画面 (`FirstViewController`) では戻るボタンを非表示にします。

```swift:CommonViewController.swift
// 現在の ViewController 名を取得
let currentViewController = String(describing: type(of: self))
guard !currentViewController == "FirstViewController" else {
	return
}
```

新たにボタンを生成し `leftBarButtonItem` に登録します。
`leftBarButtonItem` が表示されている場合、デフォルトの戻るボタンは非表示になります。

```swift:CommonViewController.swift
let chevronLeftImage: UIImage? = UIImage(systemName: "chevron.left")
let backButton = UIBarButtonItem(image: chevronLeftImage, style: .plain, target: self, action: #selector(onTapBackButton(_:)))
navigationItem.leftBarButtonItem = backButton
```

タップ時に呼び出されるアクションに、前画面へ遷移する処理を記述します。

```swift:CommonViewController.swift
@objc
func onTapBackButton(_ sender: UIBarButtonItem) {
	navigationController?.popViewController(animated: true)
}
```

## 特定の ViewController で処理をカスタマイズする


処理をカスタマイズしたい ViewController で `onTapBackButton` を override します。

```swift:SomeViewController.swift
@objc
override func onTapBackButton(_ sender: UIBarButtonItem) {
	// TODO: ここに処理を記述
 	navigationController?.popViewController(animated: true)
}
```

## 参考

- [Xcode - navigationBarの戻るボタンでの画面遷移をキャンセルしたい｜teratail] (https://teratail.com/questions/274061)
- [ios - Execute action when back bar button of UINavigationController is pressed - Stack Overflow] (https://stackoverflow.com/questions/27713747/execute-action-when-back-bar-button-of-uinavigationcontroller-is-pressed/37230710)
カメラから指定した矩形領域の差分を取り、変化率が一定率以上になったときに音をならすPGM

<h3>
カメラから指定した矩形領域の差分を取り、変化率が一定率以上になったときに音をならすPGM
</h3>
<hr>
予めカメラから差分を検出する矩形領域(2カ所)を登録し、別PGMでカメラからその矩形領域の差分が一定率
以上になったときに音をならすPGMです。(これを改良すると目や口を動かすだけで
太鼓の達人もどきのことができそうw...)

<hr>
本PGMのgithubURL: https://github.com/NanjoMiyako/ImageDiffAndSound
<hr>
使い方
1.まず、registCaribRect.pyを実行し、差分を取る矩形領域を2カ所登録します。
(ドラッグで矩形領域をドラッグ、その後’a'キーで矩形領域Aを変数に保存、'b'キーで矩形領域Bを変数に保存、その後's'キーでそれぞれの矩形領域を'caribRects.txt'としてファイルに保存します。)
2.次にplaySoundByImageDiff.pyを以下のコマンドライン引数付きで呼び出します。
コマンドライン引数1:登録した矩形領域のファイル(caribRects.txtのファイルパス)
コマンドライン引数2:矩形領域Aの差分で音を鳴らす基準の変化率
コマンドライン引数3:矩形領域Bの差分で音を鳴らす基準の変化率
コマンドライン引数4:矩形領域Aの差分をとる間隔の秒数(浮動小数点)
コマンドライン引数5:矩形領域Bの差分をとる間隔の秒数(浮動小数点)

コマンドライン引数の例：
python playSoundByImageDiff.py C:\hogehoge\caribRects.txt 1.5 3.0 0.2 0.5

3.実行後矩形領域がそれぞれカメラ上の画面から矩形の線分として描画されるので、
その部分を瞬き等で差分が検出されると音を出します。

<hr>
参考にしたサイト
<a href="https://qiita.com/teraken_/items/c8ac4c0ff60d8856a15c">opencv（python）のマウスイベントでカメラのライブ映像に線を描く - Qiita</a>
<a href="https://docs.pyq.jp/python/library/file.html">ファイル入出力 — Pythonオンライン学習サービス PyQ（パイキュー）ドキュメント</a>
<a href="https://note.nkmk.me/python-split-rsplit-splitlines-re/">Pythonで文字列を分割（区切り文字、改行、正規表現、文字数） | note.nkmk.me</a>
<a href="https://www.javadrive.jp/python/num/index6.html">文字列を数値に変換して数値と演算する | Python入門</a>
<a href="https://note.nkmk.me/python-str-num-conversion/">Pythonで数字の文字列strを数値int, floatに変換 | note.nkmk.me</a>

<hr>
使用したサンプル音源サイト
<a href="https://pocket-se.info/">ポケットサウンド – フリー効果音素材・BGMダウンロード【mp3】</a>
Google Cloud Dataprepによるデータ加工

データ分析の実務では、体裁が整っていないデータを扱うことも多く、データクレンジングは重要な工程と言えるでしょう。エクセルやPythonなどでもこうした処理は可能ですが、今回はGoogle Cloud Dataprepを使ったデータクレンジングを試してみたいと思います。

最初にダミーデータ作成ツールを使い、顧客名や電話番号、住所などが入ったリストを作成しました（クレンジングの練習用に、数字にハイフン等を加えています）。ここからDataprepを使いデータを処理します。手順は以下の通りです。

①GCPのホームより、画面左側のメニューからDataprepを選択します。

![Capture000.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/cb201a32-0212-117e-46a7-524c72f0281e.png)

②遷移後、画面右上からデータをインポートし、ライブラリに対象データが追加されたことを確認します。

![Capture22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/9545cb05-e9c7-b00d-fd26-c9c5c9661ef0.png)

![Capture333.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/e61d595a-0af1-78cd-e91a-ee5edd903747.png)

③一度ホーム画面に戻り、「Import Data」ボタンの下にある「Create Flow」をクリック、「Add Datasets」から先程追加したデータセットを追加し、遷移後のフロー図に表示される「Add New Recipe」より処理内容を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/2f6d4f44-3250-875e-d88a-c616f26f2b4c.png)

![Capture444.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/170257f8-57f1-df34-069a-6e37e333bfe1.png)

④レシピを追加後、画面右側の「Edit Recipe」から以下の画面に遷移します。データについて、文字列か数値かなどのデータ型は自動的に判定され、表記ゆれのある場合、列名の下が赤く表示されるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/78f18404-bb37-b876-b7e6-14287e3d4f44.png)

⑤「携帯電話」の列を見てみましょう。列名をクリックすると、ユニークな値の種類や入力パターン、さらには改善案が表示されます。この場合、電話番号の一部にハイフンが入ってしまっており、表記が統一されていないことが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/0e076ecf-e9e9-488b-23c4-38dbaf3fde4b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/c73d157a-70b1-da35-201b-aa6caff116b0.png)

⑥ハイフンを削除しましょう。この場合、まず「Replace」→「Text or pattern」を選択します。

![Capture66.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/76e07599-8f67-c758-7429-5a28a1a3c033.png)

次に「Find」欄に「`{delim}`」を入力、「Replace with」を空欄にすることでハイフンを削除できます。さらに「Advanced options」→「Match all occurences」ボックスにチェックを入れることで、列内のすべてのハイフンを削除できます。処理後のプレビューは、当該の列の右側に表示されるので、内容を確認しながら作業できます。問題なければ、画面右下の「Add」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/9e953648-865b-1532-1347-d878a18890a2.png)

⑦レシピを追加したら、画面右上の「Run job」をクリックします。デフォルトでは、処理後のデータはCSV形式で出力されますが、BigQueryに格納することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/ed538338-a217-9ee7-3d2d-a54b446b9dbd.png)

Dataprepを使えば、大容量のデータもGUI操作で手早くクレンジングしデータベースに格納できます。このほかにも、データのルックアップや結合などさまざまな機能があり、実務で役立つことも多いのではないでしょうか。Dataprepの機能については以下の公式ガイドも参考になります。

https://cloud.google.com/dataprep/docs?hl=ja
【JavaScript】クラス概念編

今回はクラス、インスタンス、継承といった概念の復習です。（自分用の備忘録）

#0.クラスとインスタンス
クラスとは雛形や設計図と例えるのが一般的です。
インスタンスはクラスを元に作られるデータのことです。

車の製造で例えるなら、
クラスは、車を製造する設計図で、
インスタンスは設計図を元にして作られた販売している車のことになります。

#1.クラス作成〜出力まで（完成）

簡単なクラス、インスタンス、継承の一連を作成しました。
細かく解説入れていきます。

```js
// ーーーーー　親クラス　ーーーーー

class Book {
  constructor(title, content) {
    this.title = title;
    this.content = content;
  }

  show() {
    console.log(`本のタイトルは ${this.title}`)
    console.log(`本の感想は ${this.content}`)
  }
}

// ーーーーー　子クラス　ーーーーー

class AuthorBook extends Book {
  constructor(title, content, author) {
    super(title, content);
    this.author = author
  }
  show() {
    super.show();
    console.log(`本の著者は ${this.author}`)
  }
}

// ーーーーー　インスタンス　ーーーーー

const books = [
  new Book("メモの魔力", "メモの重要性がわかる")
  new Book("多動力", "ノリの良さが大切")

  new AuthorBook("革命のファンファーレ", "広告戦略の鏡", "西野亮廣")
]

// ーーーーー　結果出力　ーーーーー

books[0].show();
books[1].show();
books[2].show();
```

#2.クラスの作成

```js

class Book {  // クラス名の頭文字は大文字
  constructor(title, content) {  // constructor（）メソッドを作ってプロパティの初期値を設定
    this.title = title;  // このクラスから作られるインスタンスはthisで表現する
    this.content = content;
  }
  
  show() {
    console.log(`本のタイトルは ${this.title}`)
    console.log(`本の感想は ${this.content}`)
  }
}
```

#3.インスタンスの作成

```js

const books = [
  // new クラス名()でインスタンスを生成
  // constructor()の引数に沿って出力したい値を入力する
  new Book("メモの魔力", "メモの重要性がわかる")
  new Book("多動力", "ノリの良さが大切")
]
```

#4.継承

```js

class AuthorBook extends Book {  // extends 親クラス名と記述することで、子クラスで親クラスの内容を継承できます
  constructor(title, content, author) {
    super(title, content);  // super()を使用すれば、親クラスのconstructorを継承でき、親クラスのthisを併用できる
    this.author = author
  }
  show() {
    super.show();  // super.show()を使用すれば、親クラスのshowメソッドを子クラスで継承できます
    console.log(`本の著者は ${this.author}`)
  }
}
```

#5.結果の出力

子クラスで作成したauthorの情報が入った、インスタンスも新しく生成します。

```js

const books = [
  // new クラス名()でインスタンスを生成
  // constructor()の引数に沿って出力したい値を入力する
  new Book("メモの魔力", "メモの重要性がわかる")
  new Book("多動力", "ノリの良さが大切")

  new AuthorBook("革命のファンファーレ", "広告戦略の鏡", "西野亮廣")
]
```

```js
books[0].show();
books[1].show();
books[2].show();
```

#6.補足

######静的メソッドについて
インスタンスを生成しなくても、クラスからメソッドを呼び出すことができるstaticの使い方を紹介します。

```js

class Book {
  constructor(title, content) {
    this.title = title;
    this.content = content;
  }
  
  show() {
    console.log(`本のタイトルは ${this.title}`)
    console.log(`本の感想は ${this.content}`)
  }

  static showInfo() {  // メソッド名の前にstaticと記述することでインスタンスを生成しなくてもメソッドを呼び出すことができる
    console.log("OK")
  }
}

Book.showInfo();  // クラス名.メソッド名()で呼び出すことができる

-> 注意点：インスタンスを作成していないので静的メソッドでthisを扱うことはできません <-
```

以上
Matlabのsoundscで音がスロー再生になってしまったとき

# 問題

Audioreadで読み込んだオーディオファイルが異常に遅く再生される問題。
なぜ…


```problem.m
[x1,fs] = audioread('sample.wav');

soundsc(x1);
```


#解決法

Soundsc()に「サンプルレートfsで再生する」ためのパラメータを書く必要があった。
以下のように書き換える。

```answer.m
[x1,fs] = audioread('sample.wav');

soundsc(x1,fs);
```

#おわりに

デフォルトでは、違うサンプルレートみたい。
そりゃうまく再生されないわ…。
パラメータがめちゃくちゃ重要だと分かった。

MATLABのQiita少ないので詰まったときにとことん詰まってしまうのが難点。
Watson StudioでYOLO v5物体検出モデルを動かす

YOLO v5による物体検出モデルを試してみました。以下リンク先から、学習済みモデルによるテスト、自前のデータによる学習を実行可能です。

https://github.com/schiyoda/ws-yolov5/blob/master/ws-yolov5.ipynb

Watson StudioでGPUを指定してNotebookを作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/fd767249-30cc-a2a5-d3fe-45069fe67d2f.png)

以下ポイントを解説します。

# 1. セットアップ
Notebookの中では以下リポジトリーよりYOLO v5のコードをダウンロードしています。

https://github.com/ultralytics/yolov5

基本的にはここにあるチュートリアルの手順に従っています。


# 2. 学習済みモデルでテスト
学習済みモデルによるテストはコマンド一つで実行可能です。
実行すると以下のように結果を参照可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/ae0fd580-1c5c-6a22-7ba2-ffe2088228a3.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/16b563b3-d50b-c9b1-a6ee-a044fa6b5c0a.png)

# 3. 自前のデータで学習
自前のデータで学習する場合は、画像とアノテーションのデータが必要です。今回は[こちら](https://qiita.com/schiyoda/items/571fc968d08737fb55d9)で紹介している、Watsonのロゴマーク（現行のロゴ/その他のロゴの２種類）の検出を試します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/8aa40bc8-eb69-bec9-2e86-793dae2dc076.png)


アノテーションは各画像毎に対象の物体のクラス(class),中心座標(center_x,center_y)幅(width)および高さ(height)を0.0〜1.0で以下のフォーマットで指定します。（画像の幅および高さが1.0）

```
class center_x center_y width height
```
例えば以下のようになります。

画像(img_37.jpg)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/ec4deead-9f84-7053-9251-93f9e803a48c.png)

アノテーション

```text:img_37.txt
1 0.249 0.5024038461538461 0.27 0.6538461538461539
0 0.7495 0.5036057692307693 0.295 0.6610576923076923
```

各画像とアノテーションの結果は各々以下のような階層で保存します。

```
watson_logos
├ images
│  ├ img_00.jpg
│  ├ img_01.jpg
│  ├    :
│  
├ labels
│  ├ img_00.txt
│  ├ img_00.txt
│  ├   :

```

また、学習時の設定ファイルを以下のように作成します。今回はtrainとvalに同じデータを使用しています。

```yaml:watson.yaml
# train and val datasets (image directory or *.txt file with image paths)
train: ./watson_logos/images/
val: ./watson_logos/images/

# number of classes
nc: 2

# class names
names: ["watson","watson_others"]
```

必要なデータがそろったら、以下のコマンドで学習を開始します。

```console
python train.py --img 512 --batch 2 --epochs 100 --data ./data/watson.yaml --cfg ./models/yolov5s.yaml --weights yolov5s.pt
```

また、TensorBoardの実行はWatson Studioではチュートリアルと同じ方法ではできませんでしたが、別の方法による実装をNotebookに載せています。Notebookでの学習のグラフをリアルタイムに参照できて便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/aa4b267a-6f69-f39e-6c1d-17948c9c21bb.png)

# テスト
学習が終わったら、テスト用のデータでテストしてみます。以下のように物体検出できていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/5955783f-fbb4-e0d3-8e4b-0259b5c36f24.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/03a8b7b6-6008-97a1-fb28-d454acf6d5a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/5b4bb06c-e751-291f-e110-81200f0f119d.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/7126f18e-904b-d5c9-402f-36f3ecc403f3.png)
【C#】LINQ

★LINQ(統合言語クエリ)とは
>--Wikipedia引用--
統合言語クエリ(Language INtegrated Query)とは.NET Framework 3.5において、様々な種類のデータ集合に対して**標準化された方法**でデータを問い合わせること（クエリ）を可能にするために、言語に統合された機能のことである。
**統合言語問合せ**とも表記される


★LINQの使い方
・LINQには標準でIEnumerable<T>、IEnumerator<T>が実装されている

<br>**LINQの記述方法**
◇クエリ構文　
・from句が必要で、from句から始める
・終わりがselect句かgroup句で終了
・ループ処理は発生しない


```C#:QueryLinq.cs
var test1 =
    from a in test
    where a * 2 == 0
    select a;
```
<br>◆メソッド構文
・from句が不要
・メソッドベースの構文

```C#:MethodLinq.cs
var test1 = test.where(a => a * 2 == 0)
                .select(a => a);
```

★遅延評価
・LINQの特徴に遅延評価というのが存在する。
・基本的にはクエリ式は即時評価されない。[^1]
・クエリ変数がforeachなどの反復処理によって評価されるまでクエリの実行は遅延する


[^1]: 遅延評価の逆は正格評価(先行評価)といい、即時評価される
RaspberryPi4 を5GHz対応のWiFiアクセスポイントにする

# はじめに
RaspberryPi4のWiFiアクセスポイント化でかなりハマったので、いつもお世話になっているQiitaへ忘備録として残します。

基本的には公式サイトを参照すれば問題ありません。
[Setting up a Raspberry Pi as a routed wireless access point](https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md)

ローカルでラズパイとPCを直接通信できるようにしたかっただけなので、ルーティングとIPマスカレード設定は行いませんでした。

# 手順
**インストール**

```
sudo apt install hostapd
sudo systemctl unmask hostapd
sudo systemctl enable hostapd

sudo apt install dnsmasq

sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
```


**ラズパイ自身のIPアドレス設定**

```
sudo nano /etc/dhcpcd.conf
```

```dhcpcd.conf
interface wlan0
    static ip_address=192.168.4.1/24
    nohook wpa_supplicant
```

**クライアント　IPアドレス設定**

```
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo nano /etc/dnsmasq.conf
```

```dnsmasq.conf
interface=wlan0 # Listening interface
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h
                # Pool of IP addresses served via DHCP
domain=wlan     # Local wireless DNS domain
address=/gw.wlan/192.168.4.1
                # Alias for this router
```

**ロケーション設定**
raspi-config -> 4 Localisation Options -> I4 Change Wi-fi Country -> JP Japanを選択。

```
sudo raspi-config
```

**Wi-Fi設定**
`country_code`は日本。
`ssid`と`wpa_passphrase`は自由に変更する。
（ただし、8文字以上かつハイフンとアンダーバー以外の記号は使わないこと。）

キーポイントは`hw_mode`と`channel`。
5GHz対応にしたいので a=IEEE 802.11a (5 GHz)を設定し、チャンネルを36とする。
通信規格とチャンネルがアンマッチだと起動しないので注意。

```
sudo nano /etc/hostapd/hostapd.conf
```

```hostapd.conf
country_code=JP
interface=wlan0
ssid=NameOfNetwork
hw_mode=a
channel=36
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=AardvarkBadgerHedgehog
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
```


**再起動**

```
sudo systemctl reboot
```

再起動後に5GHz対応のWiFiアクセスポイントになる
cshで文字列操作（日付・数値）

Cシェルで数値計算の開始日と終了日を計算するのに
どの形がよいのか見当してみました。


**1.awkを使用する**

```sh:test1.csh
set start_date = 20150423
set end_date = 20190627

set start_year   = `echo $start_date | awk '$0 = substr($0, 1, 4)'`
set start_month  = `echo $start_date | awk '$0 = substr($0, 5, 2)'`
set start_day    = `echo $start_date | awk '$0 = substr($0, 7, 2)'`
set end_year     = `echo $end_date | awk '$0 = substr($0, 1, 4)'`
set end_month    = `echo $end_date | awk '$0 = substr($0, 5, 2)'`
set end_day      = `echo $end_date | awk '$0 = substr($0, 7, 2)'`
echo "start_date = ${start_year}/${start_month}/${start_day}"
echo "  end_date = ${end_year}/${end_month}/${end_day}"

```
> time test1.csh

|1.awk |  1回目   |    2回目  |  3回目   |
|:----:|:--------:|:--------:|:--------:|
| real | 0m0.056s | 0m0.058s | 0m0.057s |
| user | 0m0.020s | 0m0.026s | 0m0.021s |
| sys  | 0m0.039s | 0m0.035s | 0m0.039s |


**2.cutを使用する**

```sh:test2.csh
set start_date = 20150423
set end_date = 20190627

set start_year   = `echo $start_date | cut -c 1-4`
set start_month  = `echo $start_date | cut -c 5-6`
set start_day    = `echo $start_date | cut -c 7-8`
set end_year     = `echo $end_date | cut -c 1-4`
set end_month    = `echo $end_date | cut -c 5-6`
set end_day      = `echo $end_date | cut -c 7-8`
echo "start_date = ${start_year}/${start_month}/${start_day}"
echo "  end_date = ${end_year}/${end_month}/${end_day}"

```
> time test2.csh

|2.cut |  1回目   |    2回目  |  3回目   |
|:----:|:--------:|:--------:|:--------:|
| real   |   0m0.053s | 0m0.055s |   0m0.055s | 
| user   |   0m0.016s |  0m0.025s |  0m0.028s | 
| sys    |   0m0.039s |  0m0.033s |  0m0.030s | 


**3.それぞれ手入力する**

```sh:test3.csh

set start_year  = 2015
set start_month =    4
set start_day   =   23
set end_year    = 2019
set end_month   =    6
set end_day     =   27
@ start_date = ${start_year} * 10000 + ${start_month} * 100 + ${start_day}
@ end_date = $end_year * 10000 + $end_month * 100 + $end_day

echo "start_date = ${start_year}/${start_month}/${start_day}"
echo "  end_date = ${end_year}/${end_month}/${end_day}"

```
> time test3.csh

| 3.手入力 |  1回目   |    2回目  |  3回目   |
|:----:|:--------:|:--------:|:--------:|
| real |    0m0.038s |  0m0.039s |  0m0.038s | 
| user |    0m0.014s |  0m0.019s |  0m0.016s | 
| sys  |    0m0.026s |  0m0.023s |   0m0.023s | 

<BR>

**どれを採用するか**


一番処理が速いのは3の手入力でした。
しかし、この先私が行う数値計算では期間の条件を変えて数多くの計算をする必要があります。
そのたびに計算開始日と終了日をわざわざ6行にわたって編集するのは面倒だと感じました。

多少処理が遅くとも、8桁のタイピングを2行で済ませられる方が楽なので、
2のcutコマンドを使う方法を採用しました。

<BR>

なお、この先うるう年の判定をする予定で、
年、月、日のループの際は+1をしていかなければなりません。
今の時点で月は文字列で、$start_monthの値は"04"となっておりますが、

```
@  start_month ++
```
をしたところ、値は5になっており、きちんと加算ができておりました。
小数計算はできませんでしたが、整数の加算であれば問題なさそうです。

<BR><BR>

start_dateの日付は私の大好きな「CLOCK ZERO ~終焉の一秒~ Extime」の、
end_dateの日付は「CLOCK ZERO ~終焉の一秒~ Devote」の発売日でした。
レーティング行列のための前処理

レーティング行列は、行がユーザー、列がアイテムになっている行列。
要素は、ユーザーがアイテムに対してつけた点数などを想定している。

それを作る前の前処理のメモ。

実際のデータというのはデータサイエンティストが入手した場合、レーティング行列担ってるわけではなく、下の「サンプルデータ」の段落にあるように、

`ユーザー, アイテム, 点数`
の行になったものが大量にあるものを指す。（例えばMovielens）

この記事では

- ある回数以上のユーザーやアイテムに絞りたい
- ユーザー、アイテムにindexをつける

をやるときのコードを示す。

# データの読み込み

```python
import pandas as pd

df = pd.read_csv('./rating.csv')
df.head()
```

出力


|  | user | item | rating |
|--:|:--|:--|--:|
| 0 | A | a | 1 |
| 1 | A | b | 2 |
| 2 | B | a | 1 |
| 3 | B | b | 3 |
| 4 | B | d | 4 |

# 特定の出現回数以上のデータのみに絞る方法

```python
users = df['user'].value_counts() # user別に集計
items = df['item'].value_counts() # item別に集計
```

usersの中身

```
C    5
D    5
B    4
A    2
Name: user, dtype: int64
```

itemsの中身

```
a    4
b    3
d    3
e    2
c    2
g    1
f    1
Name: item, dtype: int64
```

# 出現頻度の下限をもうける

```python
min_user = 5
min_item = 2
users_filtered = users[users >= min_user] # 2
items_filtered = items[items >= min_item] # 5

reduced_df = df.merge(pd.DataFrame({'user': users_filtered.index})).merge(pd.DataFrame({'item': items_filtered.index}))
```

`reduced_df`には、元のデータから

「5回以上評価したユーザーまたは2回以上登場したアイテム」

のみを抽出した。

# ユーザーとアイテムにindexをつける

```python
users = reduced_df['user'].value_counts()
items = reduced_df['item'].value_counts()

import numpy as np
user_index = pd.DataFrame({'user': users.index, 'user_id': np.arange(users.shape[0])})
item_index = pd.DataFrame({'item': items.index, 
                              'item_id': np.arange(items.shape[0])})

reduced_df2 = reduced_df.merge(user_index).merge(item_index)
print(reduced_df2.shape)
reduced_df2.head(10)
```

出力

![スクリーンショット 2020-07-09 15.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/f5528d50-15a0-f2d6-ac69-788673ce7f08.png)

indexをつけるというのは、元のユーザー、アイテムを

ユーザー
- user C -> 0
- user D -> 1  

アイテム

- item a -> 0
- item b -> 4
- item c -> 1
- item d -> 2
- item e -> 3

という対応させる操作にあたる。

# おまけ

```python
n
table = pd.pivot_table(reduced_df, values='rating', index=['user'],
                    columns=['item'])
```

![スクリーンショット 2020-07-09 15.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/3cba53a6-99ec-9147-b539-5283afbcd9e3.png)

レーティング行列で、要素がある部分の割合を計算

```python
reduced_df.shape[0]/(len(reduced_df.user.unique()) * len(reduced_df.item.unique()))
```

=> 0.8

# サンプルデータ

```csv
user,item,rating
A,a,1
A,b,2
B,a,1
B,b,3
B,d,4
B,e,4
C,a,1
C,b,1
C,c,1
C,d,1
C,e,1
D,a,5
D,c,4
D,d,2
D,f,3
D,g,4
```
[iOS]実機ビルドはできるのに、fastlaneでdeploygateに配信したアプリはクラッシュする時の対処法

割と丸一日程度時間溶かしたたのでメモ。

実機ビルドはできるのに、fastlaneでdeploygateに配信したアプリは起動時にクラッシュする。:frowning2::frowning2::frowning2:

クラッシュ前後のコミットで特に悪いことはしてないように見えるのになぜかクラッシュする。

Firebaseの`Crashlytics` のクラッシュログをみても環境変数jsonをDocodeするところの強制アンラップでこけていることはわかったがなぜこれが起きるかがわからなかった。

```setting.swift
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}))): file /Users/vagrant/git/hogehoge.swift, line 283

```

チームメンバーの助けで解決。

結論： `fastalneをupdate`したら治った。

```
bundle update fastlane
```

コミットが悪いわけでないのにクラッシュする時は、ライブラリだったり証明書だったりを疑うのが良さそうですね。
俺のGodot 2020/07/09 ノード、シーン＆インスタンス

#ノード、シーン＆インスタンスは何？

Godotのマニュアルはめっちゃ読みやすいもの。マニュアルの中で、スタータープロジェクトが用意していますので、「プロジェクトを開いて、これを見て」のものがいっぱいあります。　すごく役に立ちます！

今日ノード、シーン、インスタンスのことを読みました。

https://docs.godotengine.org/ja/stable/getting_started/step_by_step/instancing.html

Node: ノードは君のゲームの中であるものです。　以下のGifの中なら、「ヴォール」と「玉」、
Scene：シーンはノードの集めです。　シーンは、とりあえず「レベル」、「メニュー」と考えてもいいだと思います。
Instance：インスタンスは同じオブジェクトのコピーです。例えば、このゲームの中で、各「玉」は玉のインスタンスです。　

![aaaa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393501/acb218bb-d348-d665-f454-5855d2d525dd.gif)

赤い球はめっちゃバウンスしているでしょ。　全てのボールはボールのインスタンスですが、一つ玉のインスタンスをユニークして、バウンスの項目は１にしました。こうすると、すごく活躍しているでしょ。
ユニークにしないと、この玉は他の玉と同じ色、同じパタンと落ちるはずです。

なんかめっちゃちっちゃいの記事になっちゃったですけど、とりあえず今日はここまでだｗ

明日は「はじめのゲーム」のチュートリアルを読みまーす

https://docs.godotengine.org/ja/stable/getting_started/step_by_step/your_first_game.html
EC-CUBE4のDockerホスト側でのログ確認

## 目的
EC-CUBE4のログをDockerコンテナにいちいち入って確認するのはめんどくさい。
ログディレクトリを同期対象にして、ホスト側で確認できるようにする。

## 方法
`docker-compose.yml`に下記のように行を追加し、`docker-compose up -d`する。

```docker-compose.yml
services:
  ec-cube:
    volumes:
      - ".:/var/www/html:cached"
      - "./var/log:/var/www/html/var/log" # この行を追加すれば、同期除外対象の内、ログディレクトリだけが同期される
      ### 同期対象からコストの重いフォルダを除外 #####################
      - "var:/var/www/html/var" # この行のせいでログディレクトリも同期から除外されている
```

## 参考
- https://qiita.com/okazy/items/aab56f30812e2d92fd9f
BIM RevitでDynamoを使って違う階にコピーを行う

# BIM Revitでコピーしたい
大学の授業でrevitを使った演習をしているのですが、その課題として出されたのが全く同じ構造を２階分作るというものです。
しかし、僕は課題などさっさと終わらせてYouTubeを見たいので、下階を作って上階にコピーしようと考えました。~~先生はこのようなやり方で課題をやってほしいとは考えていないと思いますが~~...

しかし、ただ単にコピーペーストするだけではつまらないので、以前の授業で行ったDynamoを用いてコピーしたいと思います。
今回は課題のものではなく僕が作ったサンプルモデルを使います。
また今回使用したバージョンは以下の通りです。
> BIM Revit 2019 (学生版)
> Dynamo 2.0.2

では、やっていきましょう！

# 使用モデルの紹介
適当なモデルを用意してください。

<img width="1338" alt="model01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/212e0ab8-3538-8282-4187-eeeae64ac37b.png">



これは、僕が~~3分で~~作った床と梁と柱を使ったモデルです。
では、これを用いて実際にDynamoで上階にコピーしていきます！

# コピーを行う
## 事前準備
まず、Dynamoを起動します。バージョンはなんでも大丈夫です。
Dynamoとはビジュアルプロブラミングのことですが、これはノードと呼ばれる命令文のようなものをパズルのように組み合わせて自分でプログラムを組んで実行していきます。また、このノードは自作することができるのですが、その作ったものを他の人と共有することができます。今回はその共有されたパッケージも使っていきます。

Dynamoを開いたら新規作成を押して、新しいファイルを作ります。

<img width="1022" alt="dynamo_open_page.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/79f7ea5f-7dcb-8ad2-f79a-3ad9007fa01d.png">
＜dynamo_open_page＞

そしてページ上部にある`パッケージ`というところから`パッケージの検索`を選択し、`ClockWork`と検索します。
検索結果からご自身の使用するDynamoのバージョンに合わせて`Clockwork`というものをダウンロードしてください。

<img width="410" alt="package_search.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/7bd41a86-7623-72fd-9b12-aa05dafec478.png">
<img width="716" alt="program02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/10e4321c-92a7-2d6f-3912-dae46d6e4fac.png">


## レベルによるコピー
ノードを検索しそれらを組み合わせて、次のようなプログラムを組みましょう。

<img width="779" alt="program01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/84431fd3-bdfc-8c66-65d2-0427ae50ee35.png">


このプログラムは、下階のelementsをすべて選択した後上階にコピーしています。

## 実行してみる

実行ボタンを押して実行してみましょう！

<img width="1403" alt="practice01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/6cf26117-69b0-db0d-bee9-4c6d400934c5.png">


<img width="1396" alt="practice02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/51c64740-b959-ea4a-4a39-2a511c637b55.png">


完成しました！
...
...
...
あれ...??

<img width="538" alt="not_beam.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/f1abe06f-d395-a09d-c328-c75d5ea2cbd9.png">


梁が入っていない！？

そうなんです。なぜか梁がコピーされないんです。
理由は捜索中ですが、理由がわかる方はコメントお願いします...

では仕方がないので、個別に梁のみをコピーするプログラムをつくりましょう!

## カテゴリによるコピー

再度ノードを検索しそれらを組み合わせて、次のようなプログラムを組みましょう。

<img width="716" alt="program02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/2e5ef241-0f79-4e7b-d4c0-d786b3cebd57.png">


そして、実行します

## 完成

<img width="1369" alt="practice04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/098c0d38-be97-6bbc-8688-7875489b95ce.png">


<img width="1340" alt="practice03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/3b236fde-de06-9bf5-6714-cafee175d337.png">


今度こそ完成です。
おつかれさまでした。
競技プログラミング練習記 No.38【ABC123練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC123](https://atcoder.jp/contests/abc123)を解きました。
3完です！
D問題は解説をみて解きました。

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  4min |-| 8ms|
| B | 10min |-| 6ms|
| C |  9min |-| 10ms|
| D | - |ヒープ|13ms|



## A - Five Antennas
```c++
  int a, b, c, d, e, k;
  cin >> a >> b >> c >> d >> e >> k;
  cout << ((e - a > k) ? ":(" : "Yay!");
```
5本のアンテナから2つ選ぶ場合は、10通りありますね。
これらすべてを試してもいいのですが、短縮できます。
`a < b < c < d < e`の制約より、アンテナの距離で一番大きくなるのは`e - a`であることがわかりますね。
つまり、`e - a`を調べれば答えがわかります。

## B - 	Five Dishes
``` c++
  vector<int> dish(5);
  for(int i = 0; i < 5; ++i)
  {
    cin >> dish[i];
  }
  sort(dish.begin(), dish.end(), [](auto const& l, auto const& r){
    return (l-1) % 10 > (r-1) % 10;
  });

  ll ans = 0;
  for(int i = 0; i < 4; ++i)
  {
    ans += dish[i] + (10 - (dish[i] % 10)) % 10;
  }
  ans += dish[4];
  cout << ans;
```
全ての料理を注文する時間を最小化する問題ですね。
料理が来てから注文までのタイムロスを少なくすることを考えます。

とはいってもどの順番で頼んでも途中の時間経過は変わらないので、最後に注文した方がいいものを探します。
この場合は、かかる時間を10で割った余りが最も小さいものを最後に注文すればいいですね。
10の倍数の場合は最速で注文できるので、除外することに注意です。


## C - 	Five Transportations
``` c++
  ll n, a, b, c, d, e;
  cin >> n >> a >> b >> c >> d >> e;
  ll min_flow = min({a,b,c,d,e});
  ll ans = 4LL + (n - 1) / min_flow + 1LL;
  cout << ans;
```
最大流問題かと思ったのですが、もっと単純な問題でした。
始点から終点へのルートが1通りなのでボトルネックになっている箇所を探します。
つまり、乗せられる乗客が一番少ない箇所を探します。

するとボトルネックの箇所に乗せられる乗客数を`R`として、答えは`4 + ceil(N / R)`になります。
`4`はボトルネック以外の箇所で使う時間で、`ceil(N / R)`はボトルネックの箇所で使う時間です。


## D - Cake 123


``` c++
struct Cake{
  ll sum, i, j, k;
  bool operator < (const Cake& other) const
  {
    return sum < other.sum;
  }
};

void solve()
{
  int x, y, z, k;
  cin >> x >> y >> z >> k;
  vector<ll> a(x), b(y), c(z);
  for(int i = 0; i < x; ++i) cin >> a[i];
  for(int i = 0; i < y; ++i) cin >> b[i];
  for(int i = 0; i < z; ++i) cin >> c[i];
  sort(a.begin(), a.end(), greater<ll>());
  sort(b.begin(), b.end(), greater<ll>());
  sort(c.begin(), c.end(), greater<ll>());

  int cnt = 0;
  set< tuple<ll, ll, ll> > seen;

  priority_queue<Cake> que;
  que.push( Cake{a[0] + b[0] + c[0], 0, 0, 0} );
  while(cnt++, cnt <= k)
  {
    Cake now = que.top();
    que.pop();
    cout << now.sum << endl;

    if (now.i + 1 < x && seen.find(make_tuple(now.i + 1, now.j, now.k)) == seen.end())
    {
      que.push( Cake{a[now.i + 1] + b[now.j] + c[now.k], now.i + 1, now.j, now.k} );
      seen.insert( make_tuple(now.i + 1, now.j, now.k) );
    }

    if (now.j + 1 < y && seen.find(make_tuple(now.i, now.j + 1, now.k)) == seen.end())
    {
      que.push( Cake{a[now.i] + b[now.j + 1] + c[now.k], now.i, now.j + 1, now.k} );
      seen.insert( make_tuple(now.i, now.j + 1, now.k) );
    }

    if (now.k + 1 < z && seen.find(make_tuple(now.i, now.j, now.k + 1)) == seen.end())
    {
      que.push( Cake{a[now.i] + b[now.j] + c[now.k + 1], now.i, now.j, now.k + 1} );
      seen.insert( make_tuple(now.i, now.j, now.k + 1) );
    }
  }
}
```
難しかった。。解けそうで全く解けませんでした。

どうやったらちゃんと解けたんだろう。
こういう、データ構造を使って計算量を抑える系の問題はしっかり解けるようになりたいです。

解説の解法#3の解き方で解きました。

以上です。ありがとうございました。
go修行18日目 構造化されたWebサーバ


## 構造化されたWebサーバ

### メイン

```main.go

package main

import (
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
)

type Page struct {
	Title string
	Body  []byte
}

func (p *Page) save() error {
	filename := p.Title + ".txt"
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}

// htmlファイルのテンプレートを指定できる
// 直接書いてもいいけれどソースがわかりにくくなる
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	// ローカルのhtmlファイルを指定
	t, _ := template.ParseFiles(tmpl + ".html")
	t.Execute(w, p)
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/view/"):]
	p, err := loadPage(title)

	// もしエラー（ページがなかったら）editページへリダイレクトされる
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/edit/"):]
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/save/"):]
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	// saveに失敗したら、500エラー
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

func main() {
	http.HandleFunc("/view/", viewHandler)
	http.HandleFunc("/edit/", editHandler)
	http.HandleFunc("/save/", saveHandler)
	// /にアクセスしたり/view以外にアクセスすると404NOTFOUND
	log.Fatal(http.ListenAndServe(":8080", nil))
}


```

### /editとなるhtmlファイル

```edit.html

<h1>Editing {{.Title}}</h1>

<form action="/save/{{.Title}}" method="POST">
    <div>
        <textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea>
    </div>
    <div>
        <input type="submit" value="Save">
    </div>
</form>
```

### /viewとなるhmtlファイル

```view.html
<h1>{{.Title}}</h1>

<p>[<a href="/edit/{{.Title}}">Edit</a>]</p>

<div>{{printf "%s" .Body}}</div>
```

### 動作確認

#### editページでhtmlファイル生成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/ae9019ac-6458-7185-a2a5-5e39ad17d76d.png)

#### /viewが一覧ページ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/fb03921c-b842-55bf-d4e1-98a919b7c2d1.png)

#### /view/test1などでアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/08f0b952-13fb-c1a3-a90a-eff34650e14f.png)

### 教材
https://www.udemy.com/course/go-fintech/learn/lecture/12088980
vistaでquartus その20

#概要

vistaでquartusやってみた。
polyphonyで俺CPU書いてみた。
fizzbuzzやってみた。

#環境

windows vista 32bit
quartus ii v13.0
polyphony v0.3.6
ep2c5t144ボード

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/471fe3b2-9896-fe18-cbed-f4a35670a4ca.png)

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a28e2724-497c-c037-8382-9f16089fa5dd.png)

#verilogコード


```
module test2(input clk, input rst, output tx);
	wire [7:0] data;
	wire start;
	tx2 tx2(.clk(clk), .rst(rst), .start(start), .data(data), .tx(tx), .busy(busy), .get(get));
	mpu2_m m(.clk(clk), .rst(rst), .data(data), .start(start));
endmodule

```

以上。
（初心者向け）【Rails】時短テク！slimの導入方法と使い方

# はじめに
Rubyのテンプレートエンジン`slim`の導入方法と使い方をご説明します:relaxed:
Railsでは、`html.erb`というファイルでhtmlを書きますが、`<h1></h1>`や`<% %>`を毎回記入するのが少し面倒です。
`slim`を利用すると、htmlをより簡潔に書けるため、開発にかかる手間を減らすことができます。

※ **erbとは**
embedded Rubyのこと。Viewファイルの中の好きな場所でRubyのコードを実行できるようになります。

# 1. slim 導入方法
* railsのディレクトリにある`gemfile`に、2つのgemを追加します。

```ruby
gem 'slim-rails'
#　railsでslimを利用するためのgem

gem 'html2slim'
#　html.erbをhtmle.slimに変換するためのgem
```
* ターミナルで`bundle install`と打ち、gemの追加を反映させます。

```
bundle install
```

* 以下のコマンドをターミナルに打ち、app/viewsディレクトリにある既存のhtml.erbファイルをhtml.slimに切り替えます。

```ruby

bundle exec erb2slim app/views app/views
```

* slimファイルが追加されたことを確認したら、既存のerbファイルは邪魔なので削除します。

```ruby

bundle exec erb2slim app/views app/views -d
```

※ **念の為、`git commit`を使ってファイルの状態を記録することをオススメします。**ファイルを削除して問題が生じても、`git commit`前の状態に戻すことができます。

```
git log
#ハッシュ値を調べる
```

```
git reset --hard ハッシュ値
#出てきたハッシュ値を--hardの後に入力すると、指定したコミットまで戻ります。
```

# 2. slim 書き方
基本的なslimの使い方を列挙します。

### <% %>の書き方

* html

```ruby

<% if %>
```

* slim `-`

```ruby

- if
```


### <%= %>の書き方

* html

```ruby

<%= puts hoge %>
```

* slim `=`

```ruby

= puts hoge
```


###テキストの書き方

* html

```ruby

<p>hoge<p>
```

* slim `|`

```

p 
 | hoge
```

### 見出しタグの書き方

* html

```ruby
<h2>hogehoge</h2>
```

* slim `<>は必要なし`

```ruby

h2 hogehoge
```


### idの書き方

* html

```ruby

<div id = id></div>
```

* slim `#`

```

#　id
```


### クラスの書き方

* html

```ruby
<div class = hoge></div>
```

* slim `.`

```ruby

.hoge
```




### コメントの書き方

* html

```ruby

<!-- hoge -->
```

* slim `/ `

```ruby

/hoge
```


htmlとslimを見比べると、非常にシンプルに書けることが分かります。

# 参考記事
より詳しい情報について知りたい方は、以下のURLをご参照ください。

* 【爆速で習得】Railsでslimを使う方法から基本文法まで

https://qiita.com/ngron/items/c03e68642c2ab77e7283


* git commitを使って変更内容をコミットする方法【初心者向け】

https://techacademy.jp/magazine/10172