OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで効率が悪いコードを書いてしまう

# なかなか難しい
もともとライブラリすらないようなピュアな組み込み系からITに転職したこともあり、どうしても高級言語に感覚がついていってないことがある。というより、ついつい楽にコードがかけることから、あまり深く考えずに書いて失敗することがある。そんな一例を自分への戒めを含めて書いてみたいと思う。

## こんなコードを書いてみた。
実際には違うコードだが、簡略化すると以下のような感じ。※実際は追加する文字がループごとに変わります。

```python
a = "hogehoge\r\n"

count = 10000000
for i in range(0, count):
    a += "hogehoge\r\n"
```
Pythonに詳しいおっちゃんに、「こりゃいかんよ」、と教えていただいた。
さて何がいけないのか。まずは、実際に時間を計ってみる。

```python
import time

a = "hogehoge\r\n"

count = 10000000

start = time.time()

for i in range(0, count):
    a += "hogehoge\r\n"

elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```

自分の環境では、2.499990940093994秒かかった。以下のように書き換えてみる。

```python

a = ["hogehoge"]

count = 10000000

start = time.time()

for i in range(0, count):
    a.append("hogehoge")

b = '\r\n'.join(a)

elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```

0.9330928325653076秒になった。ぜんぜんちゃうやん。なんだこれ。

## str型はimmutable、list型はmutable
str型に対して+=をすると、新規にメモリを確保してコピーするので時間がかかるようだ。listはmutableなので、新しいメモリ領域だけを追加する。そりゃ速度に違いが出るよね。

## もう少し調べてみる

ループ数が少ないと、+=の方が早いようだ。自分の環境では100ループくらいまでおおむね+=の方が早かった。しかし、200ループ超えたあたりからlistを使った方が早くなった。なんで？？

## 反省点
Pythonは楽にプログラミングできるし、初心者でもとっつきやすい。しかし、一つ一つ理解していないと結構痛い目にあうようだ。まだまだ勉強が必要です。

他にもよいアイデアがある方、どしどしコメント下さい！！お待ちしております！
PHPのいろんな機能でFizzBuzz

この記事はPHPカンファンス北海道2019の懇親会LTのために用意したスライドです。

----

## 本日アンカンファレンスで話をしました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4121/79532bd8-fc68-a6ab-814e-673495362ebd.png)

----

## PHPには何だってありますよ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4121/c090c2c2-b478-2e06-722e-48b70151573a.png)

----

## PHP言語機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4121/13ff66d6-1dc8-2913-4927-9cb46dd4b6b5.png)

----

## PHPの制御構造

<img width="825" alt="スクリーンショット 2019-09-21 17.22.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4121/c9544c83-0edf-6187-8c50-ef8097cc7faf.png">

----

## アンカンファレンスではPHPの機能をフル活用したい層と、PHPの進歩を特に望んでいない層の溝が存在する、ということがP++事件の元凶だったという話をしました

----

## とはいえいろんな機能を使えるとコードの表現力の幅は拡がる

----

# PHPのいろんな機能でFizzBuzz

----

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4121/6a74f1d3-60e2-716f-78e3-f5e9fe9cdcd5.png)

----

# 注意

この発表で仕事で許されうるPHPコードは1行もありません

----

## とはいえまあ、重箱の隅をつつくようなPHPコードが役立つこともありうるかもしれない

----

# `for` / `foreach`

----

## FizzBuzzの定番ですね

----

## せっかくなので混ぜちゃいましょう

----

```php
<?php
foreach (call_user_func(function() {
  $a = [];
  for ($i = 0; $i <= 100; $i++)
    $a[]=$i%3?($i%5?$i:@Fizz):($i%5?@Buzz:@FizzBuzz);
  return$a;
}) as $i) {
  echo $i, PHP_EOL;;
}
```

----

# `class`

----

```php
<?php
trait Fizz { function __toString() { return "Fizz"; } }
trait Buzz { function __toString() { return "Buzz"; } }
trait FizzBuzz { function __toString() { return "FizzBuzz"; } }
trait N { function __toString() { return ltrim(__CLASS__, @_); } }
spl_autoload_register(function ($class) {
    $n = ltrim($class, @_);
    $trait = null;
    if ($n % 3 === 0) $trait .= "Fizz";
    if ($n % 5 === 0) $trait .= "Buzz";
    $trait = $trait ?? 'N';
    eval("final class $class { use $trait; }");
});
foreach (range(1, 100) as $n) {
    $class = "_$n";
    echo new $class, PHP_EOL;
}
```

----



----


# `require`

----

```fizzbuzz.php
<?php global $i ?>
<?= ['FizzBuzz',null,null,'Fizz',null,'Buzz','Fizz',null,
null,'Fizz','Buzz',null,'Buzz',null,null][++$i%15] 
?? $i, PHP_EOL ?>
```

```php
<?php require 'fizzbuzz.php' ?>
<?php require 'fizzbuzz.php' ?>
... (100回書く)
```
----

# `include`

----

```php
<?php set_error_handler(function ($_, $msg) {
    if (preg_match('/include\((?<n>\d+)\.php\)/', $msg, $m)) {
        if ($m['n'] % 3 === 0): ?>Fizz<?php endif;
        if ($m['n'] % 5 === 0): ?>Buzz<?php endif;
        if ($m['n'] % 3 !== 0 && $m['n'] % 5 !== 0) echo $m['n'];
        ?>

<?php
    };
});

foreach (range(1, 100) as $i) include "$i.php";
```
[gem "active_hash"]データベースに依存させず、プルダウンメニューを作成する方法。

# gem "active_hash"
都道府県やカテゴリーなど、将来的に増える見込みのないデータは
active_hashで作ることが可能です。

実際に私が作った都道府県のプルダウンメニューについて
順序に沿って説明させていただきます。

まずは、active_hashを使えるようにgemをインストールします。

```ruby:Gemfile
gem 'active_hash'
```


```ruby:コンソール
$ bundle install
```

続いてモデルを作成します。
カラムも一緒に作成。

```ruby:コンソール
$ rails g model Address prefecture_id:integer city:string
```
続いて

```ruby:コンソール
$ rake db:create
$ rake db:migreate
```

すでにデータベースを作って入れば
rake db:createする必要はありません。


"rake db:migreate"　によって作られたファイルを
以下のように記述する。

後に作るPrefectureモデルに
ActiveHash::Baseを継承させるための記述。
belongs_to_active_hashメソッドでアソシエーションも組みます。


```ruby:app/models/address.rb
class Address < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end
```

続いて、Prefectureモデルを作ります。
modelを作るときは "rails g model ~"を用いますが
active_hashで作るときは手動で作りましょう。

modelフォルダを右クリックしてprefecture.rbを作ります。

そして以下の記述を書きましょう。
ActiveHash::Baseを継承しているので
ActiveRecordのメソッドを使用して情報を引き出すことが出来ますね。

```ruby:app/models/prefecture.rb
class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end
```

以上でデータベースを用いずに都道府県のデータを引き出すことができます。

プルダウンメニューをviewで表現するには
以下のような記述になります。

prefecture.rbで定義したものを、Prefecture.allで一括表示したということですね。

```ruby:app/views/〇〇.html.haml
= f.collection_select :prefecture_id, Prefecture.all, :id, :name, prompt: "---", class: 'クラス名'
```

[![Image from Gyazo](https://i.gyazo.com/3d23f150daa6569ea6322341fe8347bd.gif)](https://gyazo.com/3d23f150daa6569ea6322341fe8347bd)

このようなプルダウンメニューができます！

ここは違うよ、ということがあれば
是非コメントお願いします！
Webで突然メモリオーバーした場合の調査方法

# 突然サービスでエラーが出始めた

## とりあえずログを見る
### メモリオーバーでエラーが出ている
```
[21-Sep-2019 04:30:40] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 71 bytes) in /var/www/xxxxRedisUtil.php on line 60
[21-Sep-2019 04:34:42] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 6 bytes) in /var/www/xxxxDaoUtil.php on line 314
```
* データストアのUtilクラスでメモリオーバーしているのは把握できたが、どのページか判断できない

## アクセスログで500エラーを探せばだいたい見つかる
```
[root@xxxWeb01 ~]# cat /var/log/httpd/xxxx.com.access_log.20190920 | grep " 500 "
100.100.xxx.17 - - [20/Sep/2019:00:00:01 +0900] "GET /xxxxx HTTP/1.1" 500 20 "-" "Mozilla/5.0 (Linux; Android 7.0; WAS-LX2J Build/HUAWEIWAS-LX2J; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.132 Mobile Safari/537.36 Sleipnir/3.5.16" "-" "-" "-" 1590957 "-" "-" "64" "/xxxx/" "1684366134" "-" "-"
100.100.xxx.19 - - [20/Sep/2019:00:10:02 +0900] "POST /xxxx HTTP/1.1" 500 20 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1" "-" "-" "-" 2221272 "-" "-" "32" "/xxxxx" "1667523941" "-" "-"
100.100.xxx.40 - - [20/Sep/2019:02:10:01 +0900] "GET /xxxx HTTP/1.1" 500 20 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1" "-" "-" "-" 803358 "-" "-" "32" "/xxxx" "1697658468" "-" "-"
```

## あとは対応するだけ

* ini_setでメモリ増やすなり
* リファクタしてメモリ消費をへらすなり
Project Euler 023を解いてみる。「非過剰数和」

# Project Euler 023
[023](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2023)
>完全数とは, その数の真の約数の和がそれ自身と一致する数のことである.
たとえば, 28の真の約数の和は, 1 + 2 + 4 + 7 + 14 = 28 であるので, 28は完全数である.
真の約数の和がその数よりも少ないものを不足数といい, 真の約数の和がその数よりも大きいものを過剰数と呼ぶ.
12は, 1 + 2 + 3 + 4 + 6 = 16 となるので, 最小の過剰数である.
よって2つの過剰数の和で書ける最少の数は24である.
数学的な解析により, 28123より大きい任意の整数は2つの過剰数の和で書けることが知られている.
2つの過剰数の和で表せない最大の数がこの上限よりも小さいことは分かっているのだが, この上限を減らすことが出来ていない.
2つの過剰数の和で書き表せない正の整数の総和を求めよ.


->[次の問題](https://qiita.com/radiol/items/e02d8a5dea9aa6489c8b)

## 考え方
`[1~28123までの過剰数]`を列挙、ループを使って`[2つの過剰数の和の集合]`を作成します。
`[1~28123の自然数の集合]`から`[過剰数の和の集合]`を減算することで`[非過剰数和の集合]`を得ます。

## コード
```Python:euler023.py
def main():
    limit = 28123
    # 1~28123の自然数のset
    all_num_set = set(range(1, limit + 1))
    # 過剰数のlist
    excess_numbers = [i for i in range(1, limit + 1) if is_excess_number(i)]

    # 過剰数の和のsetを作成。重複する要素はsetによって自動で除去される。
    excess_sum_set = set()
    for excessA in excess_numbers:
        # 12+20と20+12のように入れ替えてもは結果は同じなので、
        # 重複しないようにexcessA以上の数字のみループに使用。
        for excessB in excess_numbers[excess_numbers.index(excessA):]:
            sum_num = excessA + excessB
            # 和が28123より大きければループを抜ける
            if sum_num > limit:
                break
            excess_sum_set.add(sum_num)

    # setの差分で[全ての数字の集合]から[過剰数の和の集合]を除外
    answer_set = all_num_set - excess_sum_set
    # 合計して答え
    print(sum(answer_set))


def is_excess_number(n):
    """
    過剰数か否かを判定する関数
    Args:
        n: 自然数
    Returns:
        bool: 過剰数ならTrue,それ以外ならFalse
    """
    # 約数1は必ず含まれる
    sum_divisors = 1
    # 探索範囲は2~√n
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            sum_divisors += i
            # nが2乗数でなければn/iも約数の和に追加
            if i ** 2 != n:
                sum_divisors += n // I
        # 約数の和がnより大きければ過剰数
        # ループの中でも外でも時間はあまり変わらなかった
        if sum_divisors > n:
            return True
    return False


if __name__ == '__main__':
    from time import time as t
    st = t()
    main()
    print(t() - st, 'sec')
```
[paiza](https://paiza.io/projects/new)にて実行
`結果
4179871
1.5287187099456787 sec
`
ラズパイでアンドロイド9動作するのですね。

ラズパイにアンドロイドをインストールしたくてググっていたらありました。

- [参考にしたサイト：感謝！](https://qiita.com/msegawa200x/items/bf4cb6376b30be6ea15e)
- [本家の情報元](https://lb.raspberrypi.org/forums/viewtopic.php?f=73&t=232234&sid=ff871a56c9963b6ab666a2a5c53077ed)
- [情報元にあるデモ動画]（https://www.youtube.com/watch?v=tJJetgz53OI&feature=youtu.be）
- 手順１：情報元にあるイメージデータ(2019_01_25_rpi3_a586f2b.bin.bin.gz)をダウンロードしました。
- 手順２：ダウンロードしたイメージファイルをbalenaEtcherでSDカード（16GB)に焼きました。
- 手順３：ラズパイ3B+に差し込んで電源を入れたら動きました。
- 備考
- なかなか見つからなかったので、ここにメモとして残します。
- 残念ながらラズパイZEROでは起動しませんでした。
UnboundLocalErrorについて考察してみた



# まずはおさらい
とりあえず表示してみる

```python
global_variable = "This is a global."

def func():
    print(global_variable)

func()  # This is a globalと表示される
```

関数内で値を操作するなら、globalを使う。

```python
global_variable = "This is a global."

def func():
    global global_variable  # これ重要
    global_variable = "Change the value"
    print(global_variable)

func()  # Change the valueと表示される
print(global_variable)  # Change the valueと表示される
```

# UnboundLocalErrorになるパターン

```python
global_variable = 0

def func_error():
    global_variable += 1
   
func_error() # UnboundLocalError: local variable 'global_variable' referenced before assignment
```
これはglobal_variableがローカル変数として宣言される前に、いきなり加算しようとしているのだ。だからPythonさんからしたら、「誰だ君は」となるのである。これは上記のようにglobal宣言しておくと回避できる。


# よく分からんがエラーになるパターン
以下のパターンもダメ。


```python
global_variable = 0

def func_error():
    print(global_variable)
    global_variable = 1

func_error() # UnboundLocalError: local variable 'global_variable' referenced before assignment
```
面白いのがエラーが出ている個所がprint(global_variable)なのだ。Pythonさんはどうやら、global_variableをローカル変数とみなしたようだ。しかし、print(global_variable)を読みだした時はまだ宣言されてないので、先に「宣言してちょうだい」と促しているのだ。

# あれ？ちょっとまった。
ここで一つ疑問が出てくる。以下の場合はどんなエラーになるのか。(ご指摘を受けたので修正しました。)

```python
def func_error_local():
    print(hogehoge)
    hogehoge= 1

func_error_local() # UnboundLocalError: local variable 'global_variable' referenced beford
```

これも同様に、UnboundLocalErrorになった。

# 正直分かりにくい
これらの挙動は個人的には違和感を感じている。globalという概念を導入した結果なのだろうか。そもそも、関数内ではglobal宣言をしないと一切アクセスできないようにすればよかったのでは？と正直思う。もしくはその逆で、完全フリーにグローバル変数へアクセスできるようにするとか。~~あとは、エラーの内容を「global宣言してちょうだい」にするとか。~~ そもそも変数が宣言されてないと、UnboundLocalErrorが出るようだが、やっぱりエラーが分かりにくい。

この挙動が意図したものか、それとも歴史がそうさせたのか、もしくは海より深い理由があるのか。正直よく分からんので知っている人がいたら教えて欲しいです。

でわでわ。
【備忘録】Swiftで機種に応じてデザインを変える

#機種に応じてデザインを変更する
機種ごとの画面サイズに応じたことをしたい時に、どうぞ。viewDidLoadの時点でも動くよ。(一応、どうしても身近に愛用している人がいなかったiPhone XS Maxを除き、実機テストで確認済み)

あ、機種ごとの**性能の違い**を考えて機種に応じた動作をさせたい時はこの方法はやめたほうがいい。あくまでも画面サイズに応じた対応をしたいときだけね(デザインとか)。

```swift
        //画面の高さ(ピクセル)で分けた
print(UIScreen.main.nativeBounds.height)

switch(UIScreen.main.nativeBounds.height) {
 
        case 1136:
            // iPhone 5, iPhone 5s, iPhone 5c, iPhone SE
            break

        case 1334:
            // iPhone 6, iPhone 6s, iPhone 7, iPhone 8
            break

        case 1920:
            // iPhone 6 Plus, iPhone 6s Plus, iPhone 7 Plus, iPhone 8 Plus
            break
            
        case 2436:
            //iPhone X,iPhone XS
            break
            
        case 1792:
            //iPhone XR
            break
            
        case 2688:
            //iPhone XS Max
            break
            
        default:
            break

        }
```
【Swift】StatusBarを半透明にする

# 概要
StatusBarを半透明にする方法についての記事です。
下記画像のApple純正アプリMapのようにStatusBar半透明にしたくて調べたんですが、ダイレクトな記事があまり出てこなかったのでまとめてみました。
半透明StatusBarを実現したい方の助けになれば幸いです。

![IMG_1718.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347128/37210606-4f64-2623-1f40-62791ff0923f.png)

# 実行環境
【Xcode】 11.0
【Swift】 5.0
【iOS】 13.0

# 実装
実装はすごく簡単です。
まず、`MapをView`いっぱいに広げて配置し、その上に`Visual Effect View`を置き、それぞれに対してAutoLayoutを貼っていきます。
ここで`Visual Effect View`の高さをStatusBarに合わせるために、`Visual Effect View`に`height=44`の制約を貼ります。

<img width="738" alt="スクリーンショット 2019-09-21 18.12.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347128/c6e04cf9-7be4-2ca8-ecdd-d6d9e6733586.png">

以上です！！

# 完成
<img width="390" alt="スクリーンショット 2019-09-21 18.14.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347128/ce444d79-52d8-4bc1-31d2-9a52d95a350f.png">
SF Symbols を便利に使う

昨日の [ダークモード対応で便利なやつ](https://qiita.com/funnything/items/fd737053b2c0bbe5e50a) に引き続き、今度は SF Symbols の便利なやつです
SF Symbols を使いたおせる (= iOS 13 以降をターゲットにできる) のはまだ先かもしれませんが、メモとして置いておきます

## 便利なやつ

- SFSafeSymbols を使う前提のコードですが、ちょっと変えれば使わない版でもいけます
- SymbolScale は使い所がわからないので対応していない

```swift
extension UIImage {
    class func create(
        symbol: SFSymbol,
        color: UIColor? = nil,
        pointSize: CGFloat? = nil,
        weight: UIImage.SymbolWeight? = nil
    ) -> UIImage {
        let image: UIImage
        if let pointSize = pointSize, let weight = weight {
            image = UIImage(
                systemSymbol: symbol,
                withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize, weight: weight)
            )
        } else if let pointSize = pointSize {
            image = UIImage(
                systemSymbol: symbol,
                withConfiguration: UIImage.SymbolConfiguration(pointSize: pointSize)
            )
        } else if let weight = weight {
            image = UIImage(
                systemSymbol: symbol,
                withConfiguration: UIImage.SymbolConfiguration(weight: weight)
            )
        } else {
            image = UIImage(systemSymbol: symbol)
        }

        if let color = color {
            return image.withTintColor(color, renderingMode: .alwaysOriginal)
        } else {
            return image
        }
    }
}
```

```swift
let image = UIImage(
    systemSymbol: symbol,
    withConfiguration: UIImage.SymbolConfiguration(pointSize: size, weight: .black)
).withTintColor(color, renderingMode: .alwaysOriginal)
```

が

```swift
let image = UIImage.create(symbol: symbol, color: color, pointSize: size, weight: .black)
```

ってなるノリです

## SF Symbols 使ってみて思ったこと

- UIImage or Image でしか使えない (ですよね？) なので、FontAwesome より使い勝手が劣る部分がある
    - NSAttributedString の中で使うときとか、FontAwesome なら font を指定するノリで使えるけど、SF Symbols は NSTextAttachment を使う必要があったり
- SF Symbols 生成される画像のサイズ感がいまいちわからない
    - 狙った幅と高さの画像を作るのが面倒
- weight を指定できるのは良いところ
    - とはいえ default or black ぐらいしか使わなそうかもだけど
Google API でパラメータなしのアナリティクスデータを集計する

あまり目にする機会のないケースなのですが、
・WordPress で人気記事ランキングを表示するために Google API を利用する
・サイト内には流入経路計測用のパラメータだらけ
・記事ごとの PV はパラメータを無視したい
という場面がありました。

要は Google API から PV 順の記事を取得したいけど、
Google アナリティクスは同一ページでもパラメータごとに集計されてしまうため
純粋な記事ごとの PV 計測が難しい状況でした。
（パラメータは運用の都合上外せない）
<br>


下記のような状況ですね。
<img width="783" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/d5a79d97-c151-2a25-eb0a-89cf2a1dd15b.png">
※ 実際のデータではありません

## 解決方法

Google アナリティクスにはパラメータで PV が分散してしまうのを防ぐために
「パラメータの除外」という機能があります。
この機能を使いつつ、運用のためのパラメータつき集計データを分けるには
**新規ビュー** を追加すれば解決できました。

<br>
アナリティクスの管理画面から新規ビューの追加を行います。
<img width="1268" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/241d204a-9eb5-4df7-9067-3b034819c1c3.png">

<br>
追加した計測用の新規ビューの除外パラメータを設定します。
<img width="721" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/50ceebf6-c007-5dce-ed80-a82a389caa78.png">

<br>
上記ビューに対して、Google APIs で登録したサービスアカウントの
メールアドレスに「表示と分析」の権限を追加します。
<img width="1096" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/deba5e64-dbfb-08ee-1368-b5305aec9622.png">

<br>
[Google Analytics Demos & Tools](https://ga-dev-tools.appspot.com/) で API を確認してみると、
パラメータがない、ページごとのデータが問題なく取得できました。
<img width="822" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/59ded7f6-a067-7ed0-c31b-35a2459b78c1.png">

今回、ビューで分けているだけなので、
Google アナリティクスのトラッキング ID も同一のものになります。
集計元となるデータも全く同じです。

実はこのビューで分けるという技は
弊社でアクセス解析などを行なっている UX デザインチームの方に教えてもらいました:pray:
感謝...！

ちなみに Google API のデータの取得方法だけで解決できないか試したところ、
・正規表現でパラメータを除外する
　└ 単純にパラメータが付いていないページしか取得できなかった
・ページタイトルで取得する
　└ WordPress の記事タイトルに改行タグが入る可能性が高かったため、
　　記事ページ=記事タイトルにならない恐れがあった
などの理由でうまくいきませんでした。
chrome拡張機能の開発でgetUserMediaを使う際、新しいウィンドウを表示したら「このサイトにアクセスできません」と表示されてしまう場合

##やってしまっていたこと
getUserMediaはChrome 47以降のhttpsでのみ機能するため、
urlがlocalhostやhttpsではない場合には、httpsにリダクレクトするようにしていた。

自作のchrome拡張を開くと、一瞬うまく表示されるが、そのあとに「このサイトにアクセスできません」と表示されてしまう。

urlを変えるようにしてしまうのが原因だった。

##解決方法
それをやめる(小並感)
matplotlibでTimes New Romanが意図せずボールド体になってしまうときの対処法

# はじめに
matplotlibのアップデートをしたところ，フォントをTimes New Romanに設定すると意図せずボールド体になってしまう問題が生じました．


# 環境
Anaconda 3
Python 3.7.4
jupyter lab 1.1.3
matplotlib 3.1.1

# 対処法
以下のパスにあるfont_manger.pyの1272行目を書き直します．

```Path
\Users\username\Anaconda3\pkgs\matplotlib\Lib\site-packages\matplotlib\font_manger.py
```

```Python
if score < best_score:
                best_score = score
                best_font = font
```

```Python
if score <= best_score:
                best_score = score
                best_font = font
```

# 結果
グラフの書式を設定します．何故かこの設定のセルを2度実行しないとフォントサイズが適用されなくなってしまいましたが，他の環境でもなるかはわかりません．

```python
%matplotlib inline
import matplotlib.pyplot as plt

#グラフの書式設定
plt.rcParams["font.family"] = "Times New Roman"      #全体のフォントを設定
plt.rcParams["xtick.direction"] = "in"               #x軸の目盛線が内向き('in')か外向き('out')か双方向か('inout')
plt.rcParams["ytick.direction"] = "in"               #y軸の目盛線が内向き('in')か外向き('out')か双方向か('inout')
plt.rcParams["xtick.minor.visible"] = True          #x軸補助目盛りの追加
plt.rcParams["ytick.minor.visible"] = True          #y軸補助目盛りの追加
plt.rcParams["xtick.major.width"] = 1.5              #x軸主目盛り線の線幅
plt.rcParams["ytick.major.width"] = 1.5              #y軸主目盛り線の線幅
plt.rcParams["xtick.minor.width"] = 1.0              #x軸補助目盛り線の線幅
plt.rcParams["ytick.minor.width"] = 1.0              #y軸補助目盛り線の線幅
plt.rcParams["xtick.major.size"] = 10                #x軸主目盛り線の長さ
plt.rcParams["ytick.major.size"] = 10                #y軸主目盛り線の長さ
plt.rcParams["xtick.minor.size"] = 5                #x軸補助目盛り線の長さ
plt.rcParams["ytick.minor.size"] = 5                #y軸補助目盛り線の長さ
plt.rcParams["font.size"] = 14                       #フォントの大きさ
plt.rcParams["axes.linewidth"] = 1.5                 #囲みの太さ
```
修正前
![TimesNewRoman_bold.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/a495ed06-7e82-3e81-2e65-435b9864b8a0.png)

修正後
![TimesNewRoman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/53a35c5a-1ac8-adf1-555c-bf599fa90b55.png)

# 参考
以下のサイトを参考にしました．
[Stack Overflow : Times New Roman appears bold
](https://stackoverflow.com/questions/33955900/matplotlib-times-new-roman-appears-bold)
Go言語のnet/httpでWebサーバを作る時に心配したこと

##概要

二つの心配事
・Webサーバが複数リクエストを捌けるか
・ハンドラーに依存性注入しているクラスのインスタンスが毎回作られるか

##Webサーバを建てる

以下のコードを実行する

<details>
<summary>Webサーバのコード</summary>
<div>

``` go
package main

import (
	"fmt"
	"net/http"
)

type hoge struct {
	count int
}

func NewHoge() hoge {
	return hoge{count: 0}
}

func (h hoge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.count++
	fmt.Printf("hoge %dth\n", h.count)
}

func main() {
	http.Handle("/hoge", NewHoge())
	http.ListenAndServe(":8080", nil)
}

```

</div>
</details>

/hogeでリクエストが来たらハンドラの処理が走る
リクエストが来た時に、ハンドラがどのように生成されるかを把握するために
ハンドラにはcount変数を持たせて、ServeHTTPが呼ばれるたびに+1している


##一つ目の心配: 複数リクエストを捌けるか

まず結論：　net/httpを使うとリクエストごとにハンドラが生成されて捌かれる

apachebenchを使って調べる
以下のコマンドでは５０リクエストをサーバに一斉に投げる
`ab -n 50 -c 50 localhost:8080/hoge`

その結果は
hoge 1th
という標準出力が５０行羅列される

これはハンドラのcount変数を出力したものだが
**1thから50thではない事から
リクエストの度にハンドラが生成されている事が分かった**

どうやらリクエストの度にgoroutineが起動しているようで
その中でハンドラが毎回生成されているからだと考えられる

## ハンドラに依存性注入する

モックを使えるようにするために、ハンドラにロジッククラスを注入したい

<details>
<summary>Webサーバのコード</summary>
<div>

``` go
package main

import (
	"fmt"
	"net/http"
)

type logic struct {
	count int
}

func NewLogic() logic {
	return logic{
		count: 0,
	}
}

func (l logic) increment() {
	l.count++
	fmt.Printf("logic %dth\n", l.count)
}

type hoge struct {
	l logic
}

func NewHoge(l logic) hoge {
	return hoge{
		l,
	}
}

func (h hoge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.l.increment()
}

func main() {
	logic := NewLogic()
	http.Handle("/hoge", NewHoge(logic))
	http.ListenAndServe(":8080", nil)
}


```

</div>
</details>

上のコードでは注入したlogicというクラスをカウントしている

##２つ目の心配事：　注入したインスタンスが毎回作られるか

まず結論：　ハンドラがリクエストごとに作られるので、注入したやつも毎回作られる

以下のコマンドでは５０リクエストをサーバに一斉に投げる
`ab -n 50 -c 50 localhost:8080/hoge`

その結果は
logic 1th
という標準出力が５０行羅列される

ちゃんと注入したインスタンスも毎回作られるので
処理時間のかかるlogic部分でも、待ち時間が発生することは無さそう
#AWS Lambda の実行ロールを作成する  ( SQSの実行権限を与える例 )

# 実行ロールとは

AWS Lambda 「が」AWSの他のサービス「を」使うときの許可、ポリシーみたいだ。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-intro-execution-role.html

![image](https://user-images.githubusercontent.com/13635059/65368625-89f47480-dc7e-11e9-8b17-4d62429cb5bb.png)

# ロールの作成

エンティティとして「AWSサービス」を、サービスとして「Lambda」を選んで次のステップに進む。

https://console.aws.amazon.com/iam/home?#/roles$new?step=type

![image](https://user-images.githubusercontent.com/13635059/65368611-6a5d4c00-dc7e-11e9-9ece-a0bc0444848f.png)

# 今回必要な権限

SQSとの連携をしたいので、次の3項目を許可したい。

```
sqs:ReceiveMessage
sqs:DeleteMessage
sqs:GetQueueAttributes
```

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-sqs.html

# ポリシーのフィルタを使って、SQSというキーワードで検索する


![image](https://user-images.githubusercontent.com/13635059/65368664-5b2ace00-dc7f-11e9-825c-6ffeae888c84.png)

# ポリシーの中身を見る

(操作しづらい、なにこれ…！)

![image](https://user-images.githubusercontent.com/13635059/65369033-35072d00-dc83-11e9-863d-7d5f10060402.png)

*AWSLambdaSQSQueueExecutionRole* 項目を開いて JSON  表示を選ぶと、必要な Action が入っていそうなことがわかる。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sqs:ReceiveMessage",
                "sqs:DeleteMessage",
                "sqs:GetQueueAttributes",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
```

# ポリシーを選んで次のステップに進む

# タグの選択は飛ばす

# てきとうな名前をつけてロールを作成する

![image](https://user-images.githubusercontent.com/13635059/65369053-6f70ca00-dc83-11e9-91a6-7814619765e5.png)



# 作成完了

![image](https://user-images.githubusercontent.com/13635059/65369063-88797b00-dc83-11e9-962e-fe5ebc271908.png)

# Lamdaの設定

これでlambda関数の「実行ロール」から、新しいロールが選べるようになった。

![image](https://user-images.githubusercontent.com/13635059/65369076-c080be00-dc83-11e9-87a3-df51a69385ff.png)

# これで動くかな？

よし、試そう。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2496








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
iOS 13でCore Bluetoothパケットキャプチャ

みなさん、iOS 13の新機能といえば何を思い浮かべるでしょうか？
そうですね、Bluetoothのパケットキャプチャですね。

iOS 13からLive Captureというものが使えるようになり、
Macに繋いだiPhoneのCore Bluetoothパケットキャプチャができるようになりましたので、
その設定方法です。

# Live Captureを始めるにあたり必要なもの

- Xcode 11以上
- iOS 13以上の端末
- 開発者アカウント

# Live Captureを始める手順

## Additional Toolsをダウンロード

XcodeのバージョンにあったAdditional Toolsをダウンロードしてください
https://developer.apple.com/download/more/

## Additional Tools for Macを解凍し、Hardwareフォルダ内にあるPacketLoggerを取り出す

自分はアプリケーションフォルダに入れてしまいます

## iOS 13の端末に、Bluetooth developer logging profileをインストール

iOS 13の端末から、Profiles and Logsのサイトにアクセスして、
Bluetooth for iOSのProfileをダウンロードしてください。
ダウンロード後、設定アプリで改めてインストールする必要があります。
https://developer.apple.com/bug-reporting/profiles-and-logs/

## PacketLoggerを起動し、ツールバーのFile→New iOS Traceを選択し、パケットキャプチャしたいデバイスを選択

もう、その瞬間に、パケットキャプチャが始まります。
スクリーンショットは、Android(Central)からiOS(Peripheral)へ断続的にPrepare Write Requestを送っているところです。
もう何から何まで覗けるようになってますね。

![スクリーンショット 2019-09-21 17.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62305/93fbb1f1-1a0e-dbc9-f687-afc0633eb38f.png)

iPhoneの画面にも、現在パケットキャプチャされていることが上部バーに表示されます。
<img width="414" alt="IMG_CF9F117F74F8-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62305/23a7b1ab-fb3c-be58-a2ca-12dda39b6d8e.jpeg">


# 感想
パケットキャプチャ、めちゃめちゃ楽になりましたね。
んで、AndroidはPrepare Write Requestを送れるんですね。
ONNXでMLPを作る

Python APIを使ってMLPのONNXファイルを作れるようになりました。

onnx.checker.check_modelは次元の情報をチェックしていないようで、適当にshapeの値を変更してもcheckがOKになります。だいぶ怪しいのですが、とりあえずそれっぽいのができました。

## 今までのまとめ

初めてのONNX
https://qiita.com/natsutan/items/6670bd518005152f654a

ONNX Nodes in a graph must be topologically sorted対策
https://qiita.com/natsutan/items/9233a65db4cc90fb4c3a

ONNXのValueInfoProtoにinitializerで値を設定する
https://qiita.com/natsutan/items/e77e977e26c75c9159e4

## ソース

node間のつなぎが、名前（文字列）のみというのにだいぶ驚きました。
同僚がshapeの推論が・・・と言っていた意味がようやくわかりました。

```python
import numpy

import onnx
from onnx import TensorProto
from onnx import helper, numpy_helper

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [28, 28])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [10])
input_shape = helper.make_tensor_value_info('input_shape', TensorProto.INT64, [1])

# numpy array から TensorProtoを作る
input_shape_init = numpy_helper.from_array(numpy.array([784], dtype=numpy.int64))
input_shape_init.name = 'input_shape'

W0 = numpy_helper.from_array(numpy.zeros((784, 512), dtype=numpy.float))
B0 = numpy_helper.from_array(numpy.zeros(512, dtype=numpy.float))
W0.name = 'W0'
B0.name = 'B0'

W1 = numpy_helper.from_array(numpy.zeros((512, 512), dtype=numpy.float))
B1 = numpy_helper.from_array(numpy.zeros(512, dtype=numpy.float))
W1.name = 'W1'
B1.name = 'B1'

W2 = numpy_helper.from_array(numpy.zeros((512, 10), dtype=numpy.float))
B2 = numpy_helper.from_array(numpy.zeros(10, dtype=numpy.float))
W2.name = 'W2'
B2.name = 'B2'


flat_op = helper.make_node(
    'Reshape',
    inputs=['X', 'input_shape'],
    outputs=['reshape_out'],
    name="reshape_node"
)

matmul0_op = helper.make_node(
    'MatMul',
    inputs = ['reshape_out', 'W0'],
    outputs = ['matmul0_out']
)

add0_op = helper.make_node(
    'Add',
    inputs = ['matmul0_out', 'B0'],
    outputs= ['add0_out']
)

relu0_op = helper.make_node(
    'Relu',
    inputs = ['add0_out'],
    outputs = ['relu0_out']
)

matmul1_op = helper.make_node(
    'MatMul',
    inputs = ['relu0_out', 'W1'],
    outputs = ['matmul1_out']
)

add1_op = helper.make_node(
    'Add',
    inputs = ['matmul1_out', 'B1'],
    outputs= ['add1_out']
)

relu1_op = helper.make_node(
    'Relu',
    inputs = ['add1_out'],
    outputs = ['relu1_out']
)

matmul2_op = helper.make_node(
    'MatMul',
    inputs = ['relu1_out', 'W2'],
    outputs = ['matmul2_out']
)

add2_op = helper.make_node(
    'Add',
    inputs = ['matmul2_out', 'B2'],
    outputs= ['add2_out']
)

softmax_op = helper.make_node(
    'Softmax',
    axis = -1,
    inputs=['add2_out'],
    outputs = ['Y']
)

graph_def = helper.make_graph(
    [flat_op, matmul0_op, add0_op, relu0_op, matmul1_op, add1_op, relu1_op, matmul2_op, add2_op,
     softmax_op],
    'my-mlp',
    [X],
    [Y],
    initializer = [input_shape_init, W0, B0, W1, B1, W2, B2]
)

model_def = helper.make_model(
    graph_def,
    producer_name='natsutan'
)

onnx.save(model_def, 'onnx/my_mlp.onnx')
onnx.checker.check_model(model_def)
print('The model is checked!')
```


## 可視化
netronの出力

![my_mlp.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/5043ba59-9fe2-ba7c-e168-32f58e35bdad.png)
東南アジアウェブエンジニアスクール ~環境準備編~

この記事は、自分の身近にいる特定のブログラミング初学者を対象としています。
そのため、それおかしくない？やそれ必要ある？といったことがあるかと思いますが、自分が教えやすくするための内容も含まれています。
どうか優しく見過ごしてもらえればと思います。とは言え、やはりそれおかしい、古いなどありましたらぜひコメントに書いていただければと思います。

API編

* [東南アジアウェブエンジニアスクール ~API編①~ - Qiita](https://qiita.com/taishikato/items/78a87265cf6a8a584745)

# ターミナル環境
## [iTerm2](https://www.iterm2.com/)
デフォルトのターミナルアプリじゃなくてこっちでお願いします。
選択するだけでコピーできるの最強。

## フォント
iTerm2のフォントは[Ricty Diminished](https://www.rs.tus.ac.jp/yyusa/ricty_diminished.html)に設定お願いします。
しょぼいフォントを見るとやる気が無くなるので。
<img width="588" alt="Screen_Shot_2019-09-21_at_12_36_26_AM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/9c0a104c-51e9-74e7-6e3d-7970562ea179.png">

## zsh
zshに設定お願いします。

## .zshrc
.zshrcに以下を追記設定お願いします。
最低限以下があれば教えやすいです。

```bash

PROMPT='[%F{green}%T%f %F{white}%n@%M%f %F{3}%~%f ]
-> $ '
# git theming
autoload -Uz vcs_info
zstyle ':vcs_info:*' formats '(%s)-[%b]'
zstyle ':vcs_info:*' actionformats '(%s)-[%b|%a]'
precmd () {
        psvar=()
        LANG=en_US.UFT-8 vcs_info
        [[ -n "$vcs_info_msg_0_" ]] && psvar[1]="$vcs_info_msg_0_"
}
RPROMPT="%1(v|%F{green}%1v%f|)"

## alias設定
alias gs='git status'
alias gc='git checkout'
alias gcb='git checkout -b'
alias gd='git diff'
alias la='ls -la'
alias ll="ls -l"
alias gga="git log --graph --all --abbrev-commit --date=relative --pretty=format:'%C(red)%h %C(reset)-%C(yellow)%d%Creset %s %Cgreen(%cr) %C(blue)[%an] %C(bold blue)'"
```

# エディタ

## [VSCode](https://code.visualstudio.com/)
VSCode使おう

# Node

[nodebrew](https://qiita.com/Alex_mht_code/items/422f5ce10d9c9d5729b7)をインストールして、パソコンのnode環境をnode v10系にしておいてください。

# その他

## [Postman](https://www.getpostman.com/)
インストールよろしく

## [Alfred](https://www.alfredapp.com/)

Alfredで使いたいアプリをすぐに起動できるように設定しておいてください。

## Macの操作
スワイプしたときの移動方向を自分と同じにしておいてください。
VirtualBoxでUbuntuの共有フォルダを作成する方法

## 1.事前知識!

- [【超簡単】WindowsにVirtualBoxをインストールする方法](https://qiita.com/ryome/items/519fd7e50fb0b951fd7f)
- [【2019年最新】VirtualBoxでUbuntuの仮想環境を作る方法](https://qiita.com/ryome/items/56e8ee3d5e27bf514e60)

事前知識として、上記リンクの内容が必要です。

## 2.Ubuntuの共有フォルダを作成する方法

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/ca91ca64-7870-089c-48f1-d7ac8e4ca7a9.png)

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/a71e183d-f72c-f218-672d-2a027380f17a.png)

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/f3cae330-7e9a-255b-541f-82b26e122981.png)

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/8565f625-2a8b-bddf-fa95-36559179f42d.png)

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/04995805-536a-d9d6-44ee-c5f74ca1b7e5.png)

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/e8f8c9d1-e10e-297b-d882-ee2de6f856e0.png)

![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/21278f9c-ad44-f4fe-51e3-cfcf95dc0389.png)

![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/e175d0bf-8610-0a4c-b855-a8a0a4f7152d.png)

![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9d5653e5-c215-e9ea-1c6d-cadae0456caf.png)

![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/49f8ecde-9516-9bed-33a9-56eca6274781.png)

1. `Oracle VM VirtulaBox` を起動し、 `仮想マシン` を起動。
2. `仮想マシン` メニューから `設定` をクリック。
3. `共有フォルダ` を選択し、 `右上のアイコン` をクリックします。
4. `共有フォルダの追加` が開いたら、 `フォルダーのパス` と `フォルダ名` を入力し、 `自動マウント` にチェックをつけ、 `OKボタン` をクリック。
5. `共有フォルダ` が作成されていることを確認したら、 `OKボタン` をクリック。
6. `デスクトップ` から `共有フォルダ` をクリックし、認証を行う。
7. `共有フォルダ` が開いたら、 `右クリック` し、`新しいフォルダー` をクリックする。
8. `フォルダー名` を入力し、 `作成ボタン` をクリック。
9. フォルダが作成されたら、ホスト側でもフォルダが作成されていることを確認する。
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/d9b27094-0b35-88e9-3db7-41b031bdc5d1.png)

10. 画像のようにフォルダが作成されていれば成功。

## 3.一緒に変更すると便利な設定

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/71ff02d1-69ec-2732-1ee4-428d2f7d431b.png)

- 設定を変更する際、 `クリップボードの共有` と `ドラッグ＆ドロップ` の設定を `双方向` にしておくと便利。
様々なユニーク対応


ユニーク対応時の色々なパターンでよく詰まるのでメモします。

#通常のユニーク

```user.rb
class User < ApplicationRecord

# 省略

  validates :code, uniqueness: true

end
```

```user.schema
　# 省略
  t.string 'code'

  t.index ["code"], name: "code", unique: true
end
```

これが一般的によく記事にあるような書き方ですが、
これだとうまく行かないことが多いと思います。


#論理削除は見ないユニーク

```user.rb
class User < ApplicationRecord

# 省略

  validates :code, allow_blank: true,
                 uniqueness: { scope: :deleted_at }

end
```

```user.schema
　# 省略
  t.string 'code'

  t.index ["code", "deleted_at"], name: "code", unique: true
end
```

複合ユニークにすることによって、
`code`カラムと`deleted_at`カラム両方を見て
データが全く同じものがあればバリデーションが発生。

`deleted_at`は年月日から秒数まで見るので、
`deleted_at`カラムにデータが入っている時点で被ることは無いです。


つまり、
**「(論理)削除してないけど`codeが被った」**データがあった時に
`code`カラムが同じ、`deleted_at`カラムが同じ（nil同士）となって
バリデーションが発生します。


#nilだけ見ないユニーク

```user.rb
class User < ApplicationRecord

# 省略

  validates :code, uniqueness: { allow_blank: true, conditions: -> { with_deleted } }
  before_save :code_to_empty

  private

    # ""(空文字)をnilに
    def code_to_empty
      self.code = nil if code.blank?
    end

end
```

```user.schema
　# 省略
  t.string "code", null: true

  t.index ["code"], name: "code", unique: true
end
```
**nilを見ない場合**はこちらです。
１番上のやり方に近いですが、
実装時にバリデーションがうまく通りませんでした。

原因としては、
nilがどこかで""(空文字)になってしまい、
「ユニークはnilを見ない」という性質をうまく適用できず、
モデル側のバリデーションがうまく使えなかったです。

そのためメソッドを作って
""(空文字)を無理矢理nilに変更しています。

これで通るようになりました。
作業する際の準備

# 目的
作業する際に、様々な検討事項や対応項目があり、経験上最大限必要と考えられる内容を記載する
作業内容や状況に応じて、取捨選択し活用いただければありがたい

# 作業前の準備
## 手順書の作成
* 事前作業
* 本作業
* 正常性確認
* 事後作業
* 切り戻し判定及び手順
 * 切り戻し発生時は混乱が予想されるため、明確な判定基準が望ましい、例えば"5分以上の断が継続している場合、即時切り戻しを行う"
* チェック項目
* タイムテーブル
 * 作業前意識合わせ
 * 休憩時間
 * サービス影響発生時間
 * 切り戻し判定時間
 * 切り戻し作業時間
* 体制表/連絡先
 * 責任者
 * 作業者
 * 確認者
 * 緊急時のエスカレーション関係者
  * 監視部門
  * ユーザ部門
  * 上位責任者
  * 関係部署

## 手順書レビュー
* 関係者レビュー
* 有識者レビュー
* 上長レビュー

## 日程調整
* 作業人員確保の観点
* その他関連業務への影響観点
* 作業重複の観点
* 日勤/夜間の実施観点
* 週明け/週末/連休前の観点

## 作業承認
* 上位者による作業実施の承認

## 事前通知
* 関係者/ユーザ周知
 * 作業日時
 * 作業内容
 * 作業対象
 * 影響内容
 * 影響時間
 * 作業凍結

# 作業当日
## 作業開始前の意識合わせ
* 作業体制の確認
* 作業内容
* 危険ポイントの確認
* サービス影響の確認
* 切り戻しポイントの確認

## 作業環境の準備
* 作業の周りに危険な物品や異常が無いか確認
* 想定外の異常が即時確認できる準備
 * アラーム及びサービス状態の画面表示等
* 作業対象へのマーキング
* 養生

## 開始連絡
* 関係者への開始連絡
* 作業管理システムへの開始設定

## 事前作業
* 作業アラームの抑止やラベル設定等
* バックアップ取得
* ログ取得

## 本作業
* 作業者は手順書の内容を理解したものが実施する
* 手順書に記載していないコマンドは基本実行しない
* 確認者の確認をもってコマンドを実行する
* 指差し確認を行う
 * 対象機器/ホスト/IP/丸タグ等
* 危険コマンドは声を出して読み上げ、対象と確認者の確認を徹底する
* 確認項目で異常があった場合、確認が取れるまで作業を止める

## 事後作業
* 作業アラームの抑止やラベル設定等の解除
* バックアップ取得
* ログ取得
* 事後正常性確認
* 事後ミーティング
  * 作業手順の誤記
  * 作業時に問題点/改善項目
  * 関係者への追加周知事項

## 終了連絡
* 関係者への終了連絡
* 作業管理システムへの終了設定

## 作業後
* 体制維持
  * 作業経過後に問題があった場合の体制維持

# 以上
windows on ubuntu に itunes を入れて同期するまで

素人ですが、やってできたことをまとめます。

##目標
* UbuntuにVirtualBoxでWindowsを入れて、その中のitunesで音楽管理をする。

    具体的に
    - iphoneと音楽同期ができる。
    - 既存のitunesライブラリ、音楽フォルダを移行したい。

を満たすことを目標として、その際に注意するポイントをまとめる。

##環境
* Ubuntu 18.04
* VirtualBox 5.2.32
* windows10 32bit

##ubuntu,VirtualBoxのインストール
これについては、日本語のドキュメントがいっぱいあったので割愛します。

##Ubuntuの設定
* VirtualBoxのアカウントにユーザーを追加

    `$ sudo gpasswd -a USERNAME vboxusers`

で追加できます。

##VirtualBoxの設定
* VirtualBoxにwindows32bitをインストールする.
    * isoファイルを[こちら](https://www.microsoft.com/ja-jp/software-download/windows10)から事前にダウンロードしておく。  
    ※linuxPCでリンクに飛ばないと、isoファイルはダウンロードできません。
    * 書き込みDiscなどの作成はしなくてよい。

* USBコントローラーの設定
    具体的には
    * Extension packの導入
        * https://www.virtualbox.org/wiki/Downloadsからダウンロード
        * virtualBoxとversionは合わせましょう。
    * USBデバイスフィルターの設定  
       - virtualBoxのSettings->USB->Enable USB Contorollerにチェック
       - USB2.0でも3.0でもどちらでもよいと思う
       - USB Device Filtersに右側の＋のマークからデバイスを追加
       
[こちら](https://qiita.com/civic/items/684c4b82428feb0c4ae1)の記事を参考にしました。

##Itunesの設定
* ItunesをMicroSoft Storeからインストール
* ライブラリファイル(.itl)ファイルを同期
    * 事前にxmlファイルを出力しておくと便利
    * 「ファイル」->「ライブラリの読み込み」でxmlファイルを読み込む

##最後に
ubuntuでitunesを動かすにはwineを使う、みたいな話もよく聞きますが、私は失敗したので上記のような方法をとりました。
不十分な点があれば、質問またはご指摘お願いします。
はてなブログからテキストを抜きだしてテキストファイルに保存してみた


[【php】webサイトから、欲しい情報を3行で取得する方法
](https://qiita.com/dia/items/3cf963fa89b08b87e8ef "【php】webサイトから、欲しい情報を3行で取得する方法
")

を参考にしてはてなブログからテキストを抜き出してテキストファイルに保存してみました。
はてなブログAtomPubという便利なものもあるみたいですね(他人のブログには使えない？)。

```PHP
<?php

require('phpQuery-onefile.php');

//記事のエントリの日付部分を配列に格納(中身は例です)
$ary = [
  '20200101',
  '20200102',
  '20200103',
];

for($i = 0; $i < count($ary); $i++){

  $url = "https://テキストを抜き出したいブログのURL".$ary[$i];

  $html = file_get_contents($url);

  $doc = phpQuery::newDocument($html);

  $html = $doc->find(".entry-content")->html();

  //今回は<br>と<p>タグ以外いらなかった
  $article = strip_tags($html, '<br><p>');

  //テキストファイルに書き込む
  file_put_contents("text.txt", $article, FILE_APPEND);
  sleep(10);
}

?>

```

もっといい方法があったらコメントでお教えください。
[Mac] Sublime Text3 簡単にインデントを揃える方法（プラグインとか面倒なの無し）

#俺のSublime Textは何かがおかしい

sublimeでサクッとインデントを揃える方法を探していた。

なぜならインデントを揃えるプラグインがなぜか動作しなかったからだ。。。

https://packagecontrol.io/packages/HTML-CSS-JS%20Prettify

HTML-CSS-JS Prettifyが一番有名なのかな？
でもこいつが動作しなかった。。。

**俺のSublime Textは少しおかしい**


[Package Controlがインストールできなかったり、、、](https://qiita.com/kokogento/items/96f33778f52759b2ea85)

#今すぐできる、サクッとインデントを揃える方法

コードがこんな状態だとする。

<img width="623" alt="スクリーンショット 2019-09-21 19.04.45.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/ad5993dd-e30f-10bf-c9ae-b2a9ad4d74d6.jpeg">

別のファイルからコピペしてきたりしたら、起こりがちな事。

そんな時は
**①移動させたい行を範囲選択**
**②その状態でcommand + [ もしくは ]**

enterキーの左にある[ ] の事！！
ブラウザならタブの左右切り替えに使える。

<img width="505" alt="スクリーンショット 2019-09-21 19.15.16.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/51092b83-d004-f593-6753-a1a78b161fb9.jpeg">

綺麗になったね。

ほとんどのエディタでできるんだろうけど、一番使ってるエディタは勝手に揃える能力が高かったようで、使った事がなかったんよな〜。
CakePHP3 にマークダウンライブラリ（TOAST UI Editor）を組み込む手順


### 概要
 - マークダウンを既存アプリ（CakePHP3.6）に組み込みたい。
 - マークダウンのライブラリとして「TOAST UI Editor」を使ってみる。
 - TOAST UI Editor を使うにはNode.jsのインストールが必要。
 - ちなみにNodeJsは今まで使ったことありません。

### 環境
 - CentOS 7.6
 - CakePHP 3.6.14

### 手順
####１．nodejs npmのインストール
　　→[こちらに記載](https://qiita.com/remioromen/items/1fa9ffd6a62797e85e10)

####２．TOAST UI Editorのインストール
```console:プロジェクトをカレントにしてからインストール 
# cd /var/www/html/sample_app
# npm install --save tui-editor
```

####３．ライブラリのシンボリックリンクを張る
webroot配下でライブラリを参照したいため、node_modulesにシンボリックリンクを張る

```console 
# ln -s /var/www/html/sample_app/node_modules /var/www/html/sample_app/webroot/lib
```

### 思ったこと
目的は達成しました。だがしかし！NodeJsのライブラリを参照するのはこの方法でよいのか！？
docker で mysql を使う

mysql の docker image を使いたかった。
https://hub.docker.com/_/mysql

# docker run

docker image の取得と container 起動。

```sh
# docker image
$ docker run --name sql-for-programmer \
    -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.17
```


# docker start

container が停止していた場合は実行が必要。
docker run の直後なら必要なし。

```sh
$ docker start sql-for-programmer
```

# docker exec

mysql cli を経由して接続する。

```sh
$ docker exec -it sql-for-programmer \
    mysql -uroot -p -h 127.0.0.1

Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.17 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

docker で mysql が使えるようになった。
Googleスプレッドシートのアドオン「ProjectSheet Plannning」でサイドバー（各種設定）が出せないときの対応

久々にプロジェクトのタスク洗い出しとスケジューリングを行うことになり、ガントチャート作れるいいツールないかなーと探していたら、Googleスプレッドシートのアドオン「ProjectSheet Plannning」がいいよということで試してみたけど導入に少し詰まった話。

ProjectSheet Plannningの使い方は、検索すればたくさん記事があるので割愛。
アドオン入れて、さぁ設定するぞというところで手間取った。


## 翻訳とか日時フォーマットとか設定する

英語だと見難いので日本語にする。
```アドオン＞ProjectSheet Plannning＞Open sidebar```
とすればサイドバー出てきて設定できるはず。

### エラー出てサイドバー表示できない場合

私は下記のエラーが出てきてサイドバーを出せなかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231781/08f885ab-ea91-cc90-d78a-9b81232a2208.png)

エラー内容
>Open ProjectSheet in Add-ons menu and choose Open sidebar. With authorization error, use incognito window once, see also FAQ.

FAQ見てねということなので、FAQ見に行く。
https://www.forscale.nl/en/support/projectsheet/faq/faq.html#toc-authorization-required

>This message keeps appearing when you open the sidebar due to a Google issue with multiple accounts in the browser. A workaround is opening ProjectSheet in the incognito window in the Chrome browser. After authorization you can continue in the normal browser window.

googleアカウント複数設定してるのがよくないっぽい。
というわけで、引用文中にリンクはってある通り「incognito window」＝シークレット モードでプライベート ブラウジングする。
https://support.google.com/chrome/answer/95464

で、上記手順を試すと解決！

（結局やりたいことが実現できそうになくアドオン使わず自作した。そのスプシを公開できたらいいな、そのうち・・・）
VirtualBox上のUbuntuの画面サイズを変更する方法

## 1.事前知識
- [【超簡単】WindowsにVirtualBoxをインストールする方法](https://qiita.com/ryome/items/519fd7e50fb0b951fd7f)
- [【2019年最新】VirtualBoxでUbuntuの仮想環境を作る方法](https://qiita.com/ryome/items/56e8ee3d5e27bf514e60)

事前知識として、上記リンクの内容が必要です。

## 2.Ubuntuの画面サイズを変更する方法
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4b86182b-2e78-61fc-fbe4-58489e91fbbe.png)

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/c2c21748-0d0d-e23e-a6d4-f8a68d2a36cf.png)

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/a7945b8d-3ed7-a48e-1f86-b02347a98d40.png)


1. `Oracle VM VirtulaBox` を起動し、 `仮想マシン` を起動。
2. `デバイス` メニューから `Guest Additions CD イメージの挿入...` をクリック。
3. `コマンドライン` の処理が終わったら、 `デスクトップ` を確認。
4. `デスクトップ` にある `ディスクアイコン` を右クリックし、 `取り出す` をクリック。

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9e42d4b5-31c2-e8f9-3441-ffeb2371e917.png)
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/e19e9ab1-fcf0-63c3-b409-5e8fefbb573f.png)

5.画像のように画面サイズを自由に変更できれば成功。
GolangとC++を比較してみた１： for文 

## なにこれ？
C++を勉強していく過程で、私にとって既知であるGolangと、その実行速度を比較してみようという企画の第１弾です。
早速、ソースコードと実行結果の抜粋を見てみましょう。

## Golangのソースコード

```main.go
package main

import (
   "fmt"
   "time"
)

func main() {
   start := time.Now()

   for i:=1; i<=100000; i++ {
     if(i % 5000 == 0) {
       fmt.Println(i)
     }
   }

   end := time.Now()

   fmt.Printf("time %f[ms]\n", (end.Sub(start)).Seconds()*1000.0)
}
```


## C++のソースコード

```main.cpp
#include <iostream>
#include <time.h>

using namespace std;

int main() {
     clock_t start = clock();

     for(int i=1; i<=100000; i++){
       if(i % 5000 == 0){
         cout << i << endl;
       }
     }

     clock_t end = clock();

     const double time = static_cast<double>(end - start) / CLOCKS_PER_SEC * 1000.0;
     printf("time %lf[ms]\n", time);

     return 0;
 }
```

## 実行結果比較
```sh

# Golang
time 0.275946[ms]

#C++
time 0.869000[ms]
```

## 終わりに
意外でしょうか？妥当でしょうか？
私自身としては、思ったより差がついたと思いました。
今回は単にfor文を回しただけですので、次回はもっと複雑な処理を実行させて比較したいと思います。
VCIのキーボード入力について

# はじめに
この記事ではバーチャルキャスト1.7.3aで追加された
**vci.me.GetAxisInput()**
**vci.me.GetButtonInput()**
について、キーボード入力の練習に[ポン出しボード](https://seed.online/items/8ed006c1cb97756438d3027ff7c14af6c477c02516873aae538b63667060f7a3)を作った際に得られた情報を記載します。

# キーの設定
バーチャルキャストの以下から設定します。
![コントロール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407114/7d11f8b5-936e-cf2e-cbc2-e58f97f29ed8.png)


# API
##vci.me.GetAxisInput()
Right,Left,Up,Down,Forward,Backwardのキー入力を検出する。
**引数 : なし**
**返り値 : Vector3**

### キー入力と戻り値の一覧
| キー     | 返り値      |
| :-:      | :-:        |
| 入力なし  | (0, 0, 0)  |
| Right    | (1, 0, 0)  |
| Left     | (-1, 0, 0) |
| Up       | (0, 1, 0)  |
| Down     | (0, -1, 0) |
| Forward  | (0, 0, 1)  |
| Backward | (0, 0, -1) |
　キーを押している間、押したキーに応じた値が取得できます。
　複数のキーを同時に押した場合、返り値は足し算した結果となります。
例)
　"Right"と"Up"を同時に押した場合、(1, 1, 0)が返ります。
　"Right"と"Left"を同時に押した場合、(0, 0, 0)が返り、キーが入力されていないのと同じ状態になります。

### 使用方法
```
---アイテムを生成したユーザーで毎フレーム呼ばれる
function update()
    local axis = vci.me.GetAxisInput()

    if axis.x == 1 then
        print("Right")
    end
    if axis.x == -1 then
        print("Left")
    end
    if axis.y == 1 then
        print("Up")
    end
    if axis.y == -1 then
        print("Down")
    end
    if axis.z == 1 then
        print("Forward")
    end
    if axis.z == -1 then
        print("Backward")
    end
end
```
### 備考
vci.me.GetAxisInput()はキーを押している間、押したキーに応じた値が返却されます。
そのため、キー入力に応じてなにか処理をする場合、グローバル変数で最後のキー入力を覚えておき、前回のキー入力と同じ場合なにもしない等の対応が必要です。
また、誤操作やチャタリング対策に、特定フレーム数や特定秒数同じキーが入力された場合、キーが入力されたと判定すると安全かもしれません。(ポン出しボードでは0.1秒間押しつづけた場合としていす)

##vci.me.GetButtonInput()
指定されたボタンが押されているか判定する。
**引数 : number(1-4)**
**返り値 : bool**

| 状態          | 返り値 |
| :-:           | :-:   |
| 押されている   | true  |
| 押されていない | false |

### 使用方法
```
---アイテムを生成したユーザーで毎フレーム呼ばれる
function update()
    if vci.me.GetButtonInput(1) == true then
        print("ボタン1が押されました")
    end
    if vci.me.GetButtonInput(2) == true then
        print("ボタン2が押されました")
    end
    if vci.me.GetButtonInput(3) == true then
        print("ボタン3が押されました")
    end
    if vci.me.GetButtonInput(4) == true then
        print("ボタン4が押されました")
    end
end
```
### 備考
update()やupdateAll()でボタンが押されたことを検出する場合、ボタンが押された1フレームのみtrueが返却されます。

以上
【Unity】コンパスの値がとれない

オフラインで使用できるARKitのiOSアプリを作ろうとUnity 2019.1.14fでコンパスを使用したのですが、なぜかコンパスの値を取得できない問題が起こったため、その原因と解決策を記します。

#UnityEngine.Compass
Unityには端末のコンパスを使用するための関数 `Input.compass` が用意されています。

[Unity コンパスリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/Compass.html)

今回はデバイスのコンパスの値をとる関数 `Input.compass.magneticHeading` を使いました。

通常の使い方は以下の通りです。

```cs
using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        Input.compass.enabled = true; //コンパス有効化
    }
    void Update()
    {
        // Orient an object to point to magnetic north.
        transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
    }
}
```

## 問題発生
しかし、上のようなコードで実行すると `Input.compass.magneticHeading` が値を取得してくれませんでした。

原因を探しているとvoid Start()内で `Input.location.Start()` を呼ぶと正常に動作することがわかりました。

似たような関数の `Input.compass.trueHeading`（北極点からの方角）では位置情報を使用するのですが、 `Input.compass.magneticHeading` では位置情報を必要としないため、なぜ位置情報を有効にしなければならないのかは謎です。（実際ネット上の記事やAndroidでは有効にしなくても取得できていた）

これでは、位置情報を取得する関数であるため通信が必要となってしまいます。位置情報のパーミッションをOFFにしても正常に値が取得できたので結局位置データは使ってないようです。

結局 `Input.location.Start()` を呼んで、位置情報のパーミッションを切ることでオフライン対応しました。

```cs
using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        Input.compass.enabled = true;
        Input.location.Start(); //位置情報有効化
    }
    void Update()
    {
        // Orient an object to point to magnetic north.
        transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
    }
}
```