OmniAICreator/Qiita-1.07M huggingface dataset:
mongo起動できない時の解消方法

## エラー内容
```
$ sudo service mongod start
```
あれ、、mongoが起動しない。


## 解消方法
```
### mongod.lock削除
sudo rm /var/lib/mongodb/mongod.lock

### 修復コマンド
mongod —repair

### mongoを起動
sudo service mongodb start
```


### 役に立ったコマンド

```
### システムログ表示
tail -f /var/log/syslog

### mongoのログ
tail -f　/var/log/mongodb/mongod.log
```


#### 参考サイト
[[EC2]MongoDBが起動出来なくなって四苦八苦した話](https://qiita.com/momota10/items/cbe5c7e20b6f8d27e391)
[Mongo can't start service](https://superuser.com/questions/1397079/mongo-cant-start-service)
EC2 Host IPが解決できないエラー解消方法

# ubuntu sudo: unable to resolve host ip-x-x-x-xエラー

## エラー内容
```
$ sudo service apache2 graceful
sudo: unable to resolve host HOSTNAME
:
: [ok]
```
apache再起動しているのに何か気になるメッセージ
`sudo: unable to resolve host HOSTNAME`が表示される。


## 解消方法
```
$ sudo vim /etc/hosts
...
...
127.0.1.0 localhost
127.0.1.1 HOSTNAME # ここに追加 HOSTNAMEはエラーで出ているhost名を入れる
```


## メモ
　[Ubuntuで sudo: unable to resolve host ip-x-x-x-x が出たら](https://tech.librastudio.co.jp/entry/index.php/2017/03/09/post-1322/)
まさにこの記事でした。
Leetcode #572: Subtree of Another Tree

```swift
func isSubtree(_ s: TreeNode?, _ t: TreeNode?) -> Bool {
    if s == nil && t == nil {
        return true
    } else if s == nil || t == nil {
        return false
    }
    return isSubtree(s?.left, t) || isSubtree(s?.right, t) || isSameTree(s, t)
}

func isSameTree(_ s: TreeNode?, _ t: TreeNode?) -> Bool {
    if s == nil && t == nil {
        return true
    } else if s == nil || t == nil {
        return false
    }
    if s!.val != t!.val {
        return false
    }
    return isSameTree(s?.left, t?.left) && isSameTree(s?.right, t?.right)
}
```
EC2名前解決できない時の解消方法

# Could not resolve hostname ~~~.com: Temporary failure in name resolution の解消方法

## エラー内容
```
ubuntu@~~~ $ git pull origin development
:
:
Could not resolve hostname ~~~.com: Temporary failure in name resolution
```

とりあえず、「名前解決できないよ」といったエラー。


## 解決法方
Resolve.confにnameserverを追加する。

````
ubuntu@~~$ sudo vi /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 8.8.8.8　#name serverを追加
```

ひとまずgoogleのname serverを設定したら名前解決してくれました。
ちなみにEC2のデフォルトのname serverってどこなんだろう。

### メモ
[EC2インスタンスから名前解決ができない問題](http://txclr.hatenablog.com/entry/2015/05/12/135848)

`ping` `nslookup` コマンドを試しても、EC2はデフォルトでpingコマンドを叩けなかったので、少し解消まで時間かかってしまった。。
javaの有効期限付きコレクション

たとえばRedisだとエントリに有効期限を指定できる。おおむねそれで事足りるのだが、Java内でそういうこと出来るコレクションのライブラリが無いかを探す。

# ソースコード

```xml:pom.xml
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-collections4</artifactId>
			<version>4.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>28.0-jre</version>
		</dependency>

	</dependencies>
```

## Apache Commons CollectionsのPassiveExpiringMap

```java
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections4.map.PassiveExpiringMap;

public class App {
    public static void main(String[] args) throws InterruptedException {

        Map<String, String> map = new PassiveExpiringMap<String, String>(3000, TimeUnit.MILLISECONDS);
        map.put("key1", "value1");

        while (true) {
            TimeUnit.MILLISECONDS.sleep(1000);
            System.out.println(map.size());
        }
    }
}

```

上記を実行すると以下のようになる。

```
1
1
0
```

有効期限3秒。```Passive```とあるとおりmapに特定の操作を行わない限り、期限切れのチェックは行わない。特定の操作とは https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/PassiveExpiringMap.html にあるとおり```All expired entries are removed from ...```とかなんとか書いてあるヤツのこと。

```Note that PassiveExpiringMap is not synchronized and is not thread-safe```と書いてあるんでそこは注意が必要。

## GuavaのCacheBuilder

```java
import java.util.concurrent.TimeUnit;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

public class GuavaCaamain {

    public static void main(String[] args) throws InterruptedException {        
        Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(3000, TimeUnit.MILLISECONDS).build();
        cache.put("key1", "value1");
        
        while (true) {
            TimeUnit.MILLISECONDS.sleep(1000);
            cache.put("key2", "value2");
            System.out.println(cache.size());
        }

    }

}
```

上記を実行すると以下のようになる。

```
2
2
1
```

<code>expireAfterWrite</code>のとおり書き込み時に有効期限切れをチェックする。なので上記コードからputの行を消すとずっとキャッシュの内容は変わらない。

逆に読み込み時にチェックするには以下の通り。

```java
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(3000, TimeUnit.MILLISECONDS).build();
```

# 参考
https://stackoverflow.com/questions/3802370/java-time-based-map-cache-with-expiring-keys
Leetcode #345: Reverse Vowels of a String

```swift
func reverseVowels(_ s: String) -> String {
    let vowel: Set<Character> = ["a", "e", "i", "o", "u", "A", "E", "I", "O", "U"]
    var start = 0
    var end = s.count - 1
    var str = Array(s)
    while start < end {
        let isStartCharVowel = vowel.contains(str[start])
        let isEndCharVowel = vowel.contains(str[end])
        if isStartCharVowel && isEndCharVowel {
            str.swapAt(start, end)
            start += 1
            end -= 1
        } else if isStartCharVowel {
            end -= 1
        } else if isEndCharVowel {
            start += 1
        } else {
            start += 1
            end -= 1
        }
    }
    return String(str)
}
```
Buster で kodi を動かす

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/fb8fdfb6-b5fe-c238-1016-d177e2279148.png" width=75%>

## 【前提】
- Pi は 3B+
- Raspbian は Buster with desktop

Buster では kodi がまともに動かないという話は Buster 発表直後から出ている問題。 
https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=244069
https://www.raspberrypi.org/blog/buster-the-new-version-of-raspbian/

OpenGLドライバが原因らしい。
解決方法は Stretch に戻すこと。
で結論は出ているけど、何とかならないかという試みのメモ。

ライブラリをダウングレードして云々という方法もあるようだけど、初心者には敷居が高い。
GUI で操作する手軽な範囲での対応を目標とする。

## 【手順】
### 1. GLドライバの変更
以下コマンドで raspi-config 起動。

	    sudo raspi-config

以下手順で「G2 GL (Fake KMS) ～」に変更。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/b614e557-7d9d-4828-f333-9d1876af03a3.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/1c3e337e-ba2f-9318-8ecb-55d816309a1d.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/6ef6effc-7cd2-6680-473d-a3f926155540.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/660251fe-0e67-d2b3-d886-94eb27cb9f8d.png" width=80%>
再起動を求められた場合は再起動する。

デフォルトの設定は「G1 Legacy」で、この状態で kodi を起動すると、重くてまともに操作できない。
「G2 GL (Fake KMS) ～」に変更するだけで劇的に軽くなる。
「G3 GL (Full KMS) ～」に変更した場合は、kodi を起動して数十秒後に画面がブラックアウトしてしまう。
そんな訳で「G2 GL (Fake KMS) ～」一択。

因みに画面解像度の変更ができなくなるのは仕様？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/4d651201-411c-410b-2041-50282ad560cb.png" width=80%>

### 2. kodi 画面解像度の変更
kodi がまともに動くようになったところで、以下手順で kodi の画面解像度を最小(640×480)に変更する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/ed83cf96-c973-a551-f310-2c8cf86b0753.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/c0bd4363-27c2-caae-b3c7-cb5227551bf9.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/335a4867-d0ad-d2fc-fce7-e714d63043fb.png" width=80%>

手順 1. 程の大きな効果はないが、多少はマシになる。
但し、出力するモニタ（TV）にもよるだろうけど、画面の端が少し見切れるようになってしまう。

以上の設定で 4K等の高解像度の動画でなければ一応再生できるようになる。

## 【その他（効果が薄かった設定）】
- **GPUメモリ**  
デフォルトから増やすと良いとされていたけど、今回のケースに限っては変化は感じられなかった。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/f405593b-ffe6-9cd1-9c77-3dee377230e1.png" width=80%>

- **governor動作ポリシー設定変更**  
以下コマンドで現在の設定を確認。

	    cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

	初期設定から変更していなければ「ondemand」。
モードの意味は以下参照。
http://my-web-site.iobb.net/~yuki/2017-12/raspberry-pi/cpufreq/
「performance」に変更してみるも効果は感じられず。

- **オーバークロック**  
公式にはサポートされていないので未確認。
試してみる場合は以下参照。勿論自己責任で。
https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md

## 【問題点】
そもそも無理があるようで、以下の問題を確認している。

- **リモコンに反応しない場合がある**
起動時にリモコン制御のサービス開始にコケてる？

- **終了が重い**
最悪クラッシュする。

- **時々クラッシュする**
homeディレクトリにクラッシュログが溜まっていく・・・。

やっぱダメですかねぇ。

## 【関連投稿】
[Busterヘッドレスセットアップ](https://qiita.com/god19/items/c1cefcd71e8bae9b986e "Busterヘッドレスセットアップ")
Leetcode #246: Strobogrammatic Number

```swift
func isStrobogrammatic(_ num: String) -> Bool {
    let str = Array(num)
    var start = 0
    var end = str.count - 1
    while start <= end {
        if (str[start] == "6" && str[end] == "9") || (str[start] == "9" && str[end] == "6") {
            start += 1
            end -= 1
        } else if str[start] == str[end] {
            if str[start] == "0" || str[start] == "1" || str[start] == "8" {
                start += 1
                end -= 1
            } else {
                return false
            }
        } else {
            return false
        }
    }
    return true
}
```
.phpenvでPHPインストール時にpgsql・pdo-pgsqlを有効にする方法

## default_configure_optionsを編集する。

以下の設定ファイルを編集します。

```
$ vim ~/.phpenv/plugins/php-build/share/php-build/default_configure_options
```


追加する内容は以下です。

```
--with-pgsql
--with-pdo-pgsql
```

この状態でphpをインストールすれば、postgresのエクステンションが有効の状態でインストールされます。


```
$ php -m
pdo_pgsql
pgsql
```


## 参考

https://blog.hypermkt.jp/install-pdo-pgsql-for-phpenv/
Leetcode #994: Rotting Oranges

```swift
func orangesRotting(_ grid: [[Int]]) -> Int {
    var freshOranges = 0
    var rottenOranges = [(Int, Int)]()
    for i in stride(from: 0, to: grid.count, by: 1) {
        for j in stride(from: 0, to: grid[0].count, by: 1) {
            if grid[i][j] == 1 {
                freshOranges += 1
            } else if grid[i][j] == 2 {
                rottenOranges.append((i,j))
            }
        }
    }
    if freshOranges == 0 {
        return 0
    }
    var minutes = 0
    var grid = grid
    while !rottenOranges.isEmpty && freshOranges != 0 {
        minutes += 1
        let number = rottenOranges.count
        for i in stride(from: 0, to: number, by: 1) {
            let (x, y) = rottenOranges.removeFirst()
            grid[x][y] = 0
            if x-1 >= 0 && grid[x-1][y] == 1 {
                freshOranges -= 1
                rottenOranges.append((x-1,y))
                grid[x-1][y] = 0
            }
            if x+1 < grid.count && grid[x+1][y] == 1 {
                freshOranges -= 1
                rottenOranges.append((x+1,y))
                grid[x+1][y] = 0
            }
            if y-1 >= 0 && grid[x][y-1] == 1 {
                freshOranges -= 1
                rottenOranges.append((x,y-1))
                grid[x][y-1] = 0
            }
            if y+1 < grid[0].count && grid[x][y+1] == 1 {
                freshOranges -= 1
                rottenOranges.append((x,y+1))
                grid[x][y+1] = 0
            }
        }
    }
    return freshOranges == 0 ? minutes : -1
}
```
githubにファイルサイズを直してもremote rejectされ続けた時の対処法

## エラー
`$ git push` で `Githubでは100MB以上は容量オーバーだよ！` て言われた．
該当ファイルを削除しても，エラーが消えなくて困った．

```terminal:terminal
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: {commit-id-1}
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File {ファイルパス} is {大きい} MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/{リポジトリ}.git
 ! [remote rejected] {ブランチ} -> {ブランチ} (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/{リポジトリ}.git'
```

## 対処法

`commit-id` というのかわからないが，それを使って重量オーバーなファイルをコミットする前の状態に戻す．
ステージングは変更されないのでご安心を．
その後，add/commitし直せばpushができるようになる．

```terminal:terminal
$ git log
...
commit {commit-id-0} (xxx)
Author: {ooo}
Date:   {日付}
...
$ git reset {commit-id-0}
```
pythonを使ってTwitterの投稿urlから投稿時間を計算しよう

##動機
前にこんな記事を書いて、ツイッターの投稿IDを取得してみました。
https://qiita.com/Tokyo/items/de206d3e3a6a1997f257

調べてみたらこんなのがありました。
面白そうだと思ったのですが、Rubyで書かれていて困りました。
https://qiita.com/Tokyo/items/de206d3e3a6a1997f257

なので解決してみました。

投稿URLから投稿時間がドンピシャで取れてびっくりしました。

##コード

```calculate.py
from datetime import datetime 

def caluculation(_id):
    unix_time = (_id >> 22) + 1288834974657) / 1000.0
    date_time = datetime.fromtimestamp(unix_time)
    return date_time
```

##試してみた
IDは1106193069945176064でした。
![スクリーンショット (353).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247925/1057d0e9-b3f2-79b8-8ef7-a085379607b7.png)

成功しました～。
![スクリーンショット (356).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247925/bdee3626-04be-542a-2394-ea667fd4abcb.png)
LaravelでControllerをサブディレクトリに作成する方法

##やりたいこと

Controllers
├Example-ExampleController.php
このようにサブディレクトリにControllerを作成します。
Exampleディレクトリは無くても自動生成されます。


##環境
php -7.3.8
laravel -5.8.30

##コマンド
```php:コマンドライン
//例文
php artisan make:controller Example/ExampleController
```

##コード
web.phpにルーティングの設定を記述します。

```php:web.php
Route::resource('/examples', 'Example\ExampleController');
```
あるいは名前空間を指定することもできます。

```php:web.php
Route::namespace('Example')->group(function() {
    Route::resource('/examples', 'ExampleController');
}
```
pythonで自分のツイッターのTweetIDを爆速で集計しよう

## 不純な動機
私は、データを分析して仮説を立てて実験していくのが好きなんですが、一次データって取得するの難しいなって思いまして、そんな時にSNSって簡単にデータが取れるのはって気づいたので、Twitterを戦略的にバズらせたいなと思いました。

##技術的なproblem
API取ってみたんですが、pythonで使えるTweepyっていうライブラリがめちゃくちゃ使いにくくてびっくりしました。困ったこと下にまとめました。

- 投稿数が200件しか取れなくて、これじゃあツイ廃の人絶対困るだろうなと思いました。
-　
- Tweepy経由だと誰がいいねしたのかが取れない。restAPIぶん回したら、いいねをしたアカウントのユーザーIDは取れるみたいでした。ちなみにユーザーIDはユーザー名じゃないです。見ても誰のアカウントなのか分かりません。気になる人のためにリンクを貼っておきます。
[これです。](https://ja.stackoverflow.com/questions/41339/python%E3%81%AEtweepy%E3%81%A7%E8%87%AA%E5%88%86%E3%81%AE%E3%83%84%E3%82%A4%E3%83%BC%E3%83%88%E3%81%AB%E3%81%84%E3%81%84%E3%81%AD%E3%81%97%E3%81%A6%E3%81%8D%E3%81%9F%E4%BA%BA%E3%82%92%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%97%E3%81%9F%E3%81%84)

- **Tweepy経由で取得したツイートに、Twitter Developerに登録されているツイートが混じる。マジで理由がわかりませんが、高校生の時のツイートとか混じってて恥ずかしいし、ノイズ過ぎて困りました。**
この問題が謎すぎるので、解決した経験のある方は教えていただけると幸いです。

ということでAPI作戦は諦めました。
最近は、InstagramのAPIで遊べることも減ったみたいで寂しいですね。阿保みたいにスクレイピング食らってサーバーに負担掛かるくらいならAPI公開してほしいと思うのですが、、、

残された手段としてSeleniumを使うことにしました。


##技術的なproblemの解決
Twitterの投稿URLを見ていただければ、気づくと思うんですが
![スクリーンショット (353).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247925/713ea089-bc8c-5db7-1340-b992499a0e52.png)

https://twitter.com/otnk23/status/1106193069945176064

このtwitter.comの後ろが、アカウント名になっていてstatusの後ろがTweetIDになっているので、一旦TweetIDだけを取り切ってファイルに保存しておきます。

そのあとに、それぞれのTweetIDからURLを合成してrequestsとかで各投稿ごとに詳細情報を取ってデータレイクにでもぶっこんでおこうという魂胆です。

MongoDBにでも突っ込んでおきます。

でどうやって取ってくるのかいうと、Seleniumと無限スクロールで取れました。

```twitter.py
import selenium
from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome('C:/selenium/chromedriver.exe')
driver.get('http://twitter.com/otnk23')

#無限スクロールの部分
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

soup = driver.page_source
text = BeautifulSoup(soup,'html.parser')

#IDを抜く部分
_id_list = []
for tweet in text.select("div.tweet"):
　　　　_id_list.append(tweet['data-tweet-id'])
#リツイートによる重複を無くす
new_list = list(set(_id_list))


#ファイルに書き込み
for tweet in new_list:
    with open ('otnk23_id.txt','a',encoding='utf-8') as f:
        f.write(tweet+'\n')
f.close()
```
こんな感じで取れました。
自分のアカウントのURLと合成するので、多分リツイートが除外される、はず。。。

API経由だとパラメータで指定していた気がします。
![スクリーンショット (355).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247925/188b6e38-a4a1-263a-8b36-abe4ebc0dfa7.png)



jupyter上で回したので、無限スクロール一回しか書いていないけど、本格運用するならwhileとtime.sleepかけてあげてください。

[無限スクロールで参考にした記事](https://qiita.com/tsawa/items/9f4998e92ed564b2fc4d)
[BeautifulSoupのとこで参考にした記事](https://stackoverflow.com/questions/10804507/how-to-get-tweet-ids-since-id-max-id-in-tweepy-python)
[seleniumで参考にした記事](https://qiita.com/mochio/items/dc9935ee607895420186)


後は、詳細情報を取ってCSVにでも吐き出しますだけですがが、お腹が減ったので次の記事に書きます。

次の記事
https://qiita.com/Tokyo/items/a12ef262268c48be8ff1
cloudfunctionsで、firestoreからの取得データを用いて、firestoreへの書き込み


#ハマったところ
cloud functionsでfirestoreから取得したデータを用いて、Firestoreへさらに書き込み更新をしたかったのですが少しハマりました。

単純に内部ではreactのようにawaitが使えないこと(自分の知識不足で似たことはできるかも？)を忘れていたことが原因でした。



##ダメだった例

```javascript

exports.detectFavCreate = functions.firestore.document('tweets/{tweetId}/liker/{likerId}').onCreate((change, context) => {
    var tweetRef = fireStore.collection('tweets').doc(context.params.tweetId)
    var author_id = null;
    tweetRef.get().then(function(doc) {
        if (doc.exists) {
            author_id = doc.data().author_id
        } else {
        }
    }).catch(function(error) {
        console.log("Error getting document:", error);
    })
    var userRef = fireStore.collection('users').doc(author_id)
    userRef.update({
        contribution: admin.firestore.FieldValue.increment(1.0),
    });
    return tweetRef.update({
        like_count: admin.firestore.FieldValue.increment(1.0),
        likers: admin.firestore.FieldValue.arrayUnion(context.params.likerId)
    });
})

```
ログを見て見ると、ドキュメントの参照先がないとのエラーが出てここで気づく。
reactみたいにawaitがないので、そりゃあそうなるかっていう。。笑



##うまくいったコード

```javascript
exports.detectFavCreate = functions.firestore.document('tweets/{tweetId}/liker/{likerId}').onCreate((change, context) => {
    console.log(context.params.tweetId)
    var tweetRef = fireStore.collection('tweets').doc(context.params.tweetId)
    tweetRef.get().then(function(doc) {
        if (doc.exists) {
            console.log('doc.data()')
            console.log(doc.data())
            var userRef = fireStore.collection('users').doc(doc.data().author_id)
            userRef.update({
                contribution: admin.firestore.FieldValue.increment(1.0),
            });
        } else {
        }
    }).catch(function(error) {
        console.log("Error getting document:", error);
    });

    return tweetRef.update({
        like_count: admin.firestore.FieldValue.increment(1.0),
        likers: admin.firestore.FieldValue.arrayUnion(context.params.likerId)
    });
})
```

#結論
１つのcloudfunctionsで複数の書き込み等の処理をしたい場合は
普通に入れ子でいけるってことがわかりました。
退屈なことはPythonにやらせよう　勉強記録  【正規表現】

正規表現を使うと検索するパターンを指定することができる！
正規表現を使うとどれくらい短縮できるのか比較検討する。

※isdecimal():1文字以上の数字で構成されているときににTrueを返す。

##正規表現を使わない場合
```python:qiita.py
def is_phone_number(text):
    if len(text)!=12:　#👈文字数が12文字になっているかどうか
        return False
    for i in range(0,3):
        if not text[i].isdecimal(): #👈最初の3桁が数字で構成されているか
            return False
    if text[3]!='-': #👈最初の3桁の後は"‐(ハイフン)"かどうか
        return False
    for i in range(4,7):#👈3桁の数字で構成されているか
        if not text[i].isdecimal():
            return False
    if text[7]!='-':#👈"‐(ハイフン)"かどうか
        return False
    for i in range(8,12):#👈4桁の数字で構成されているか
        if not text[i].isdecimal():
            return false
    return True　#👈全て一致すればTrueを返す
print('415-555-4242は電話番号:')
print(is_phone_number('415-555-4242'))
print('Moshi moshiは電話番号')
print(is_phone_number('Moshi moshi'))
```

これを実行すると
415-555-4242は電話番号:
True
Moshi moshiは電話番号
False
と表示される

※欠点：000-1111-222という表示の電話番号しか探せない。


##正規表現を使う場合

正規表現では\dは数字1文字を表す。
電話番号は
\d\d\d-\d\d\d-\d\d\d\dもしくは　\d{3}-\d{3}-\d{4}と表せる

正規表現関数は reモジュールの中にあるので
import re　をする
re.compile()で正規表現オブジェクトを生成できる。

```
import re
phone_num_regex=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
mo = phone_num_regex.search('電話番号は415-555-4242')
print('電話番号がみつかりました:' + mo.group())
```

search()メソッドに検索対象の文字列を記入するとMatchオブジェクトを返す。
検索結果がなければNoneと表示される
Matchオブジェクトのgroup()メソッドを呼び出すと実際にマッチした文字列を取得する。
gnuplotをmacOSにインストールする

こちらは，[gnuplotのインストール法 (macOS)](https://home.hiroshima-u.ac.jp/rgdlab/rgdl_html/programming/gnuplot_install_mac.htm)を見ながらgnuplotのmacOSへのインストールを進めている途中，エラーを吐いてしまったのでその解決策と，インストールまでの備忘録になります．


#・ Error: invalid option: –with-aquaterm

[gnuplotのインストール法 (macOS)](https://home.hiroshima-u.ac.jp/rgdlab/rgdl_html/programming/gnuplot_install_mac.htm)の5. gnuplotのインストールにて，

```
brew install gnuplot --with-aquaterm --with-x11
```
を実行したところ．
Error: invalid option: –with-aquaterm
というエラーを吐きました．

検索したところオプション無しで実行すればよいようで，

```
brew install gnuplot

```
を実行したところ，正常にインストールが完了しました．

##・ 参考にさせていただいたサイト
・[gnuplotのインストール法 (macOS)](https://home.hiroshima-u.ac.jp/rgdlab/rgdl_html/programming/gnuplot_install_mac.htm)
・[【環境構築】超簡単！Macにgnuplotをインストールする方法](https://katuo-ai.com/2019/04/24/gnuplot/)
Leetcode #836: Rectangle Overlap

```swift
func isRectangleOverlap(_ rec1: [Int], _ rec2: [Int]) -> Bool {
    if rec2[0] >= rec1[2] || rec2[2] <= rec1[0] || rec2[1] >= rec1[3] || rec2[3] <= rec1[1] {
        return false
    }
    return true
}
```
デザインパターン色々

ものわかりの悪い自分でも理解できるように、なるべくシンプルな言葉で説明したデザインパターンの忘備録です。
デザインパターン勉強中のため気づいたときに追加していこうと思います。

#####ストラテジーパターン

アルゴリズムが変化する部分をクラス化して交換できるようにするパターン

たとえば、switch文で、挙動を切り替えるようなとき、コード量が多いとき、シンプルにすることができる。
イメージとしては、ゲームでいうと　[呼び出す側]は、むずかしい・かんたん　モード選択画面、アルゴA、アルゴBがそれぞれ、むずかしい・かんたんの処理。

![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/60b924e1-05ff-6722-5d62-14f9a6cb3d8d.png)



#####テンプレートメソッドパターン

共通部分を炙り出してテンプレート（型）にする。多分以前投稿したような気がする。

共通部分を抽象クラスにして、異なる部分は違うインスタンスを生成し挙動を変える。
焼き鳥で表現すると、しお味のもも　とたれのもも　があったとき、共通の鶏肉[もも]や焼くという動作を抽象クラスにして
最後やきあがったときに、'塩'か'たれ'か味付けの処理をわけるような実装のパターン。　
デザインパターンという大々的なものでなく、一般的なオブジェクト指向では必ず使われてるものな気がします。

#####シングルトンパターン

恐らく一番最初に聞く有名なやつ。オブジェクトのインスタンス化を１つに限定し、複数作らせないようにする。実装方法はいろいろある。
（複数できたようみえていても、結局は同じところを参照しているものを含む）

|  シングルトンクラス|
| ---- |  
| - メンバ変数 | 
| + インスタンス獲得 |  
| - 処理 |

最も基本的な実装方法
//直接Qiitaのエディタに書いただけなので後日確認します。。。

```C++
public class Singleton {
public:
//staticによってクラス初期化時に唯一のインスタンスが生成
static Singleton& getInstance(){
static Singleton myself;
return　myself;
}
    //外部からは生成できないようにprivate
    private:
    Singleton(){} 
}
```
【信号処理】Pythonを使って方形波をフーリエ変換してみた！

#概要
フーリエ変換を離散化したものが離散フーリエ変換(DFT)であり、
計算機ではこのDFTを高速化した高速フーリエ変換(FFT)を用いて、
フーリエ変換をしています。

DFTの練習問題としてよく出てくるのが，
(1)方形波
(2)正弦波
の2つです．
正直フーリ変換と違ってDFTは手計算できるものがかなり限られてくるので
この2つを押さえておくだけでもだいぶ違うかなと思います．

今回は(1)方形波を扱います．(2)正弦波は次回扱おうと思います．

[【信号処理】Pythonを使って三角波をフーリエ変換してみた！]
(https://qiita.com/trami/items/f228b476e12578656560)

DFTを実際に手計算で計算し，それをPythonでFFTしたものと一致するかを確かめてみたいと思います．

#動作環境
- Windows10(64bit)
- Python 3.7.2

# DFTの復習
入力信号をx(n)とすると，そのDFTであるX(k)は以下のようになります．ただし，$W_N = exp(-j\frac{2\pi}{N})$.

```math

X(k) = \sum_{n=0}^{N-1}{x(n)W_{N}^{kn}}
```

#問題

```math

x(n) = \begin{cases}
1 & (0 \le n \le 3)\\
0 & (4 \le n \le 7)
\end{cases}
```

のDFTを求めなさい．ただし，サンプル数$N=8$とする．

#解答
それでは上記の問題を，まずは手計算で計算していきます．

まずは，回転子を導入する．

```math

W_8 = exp(-j\frac{2\pi}{8})
```

DFTの定義より

```math

\begin{align}
X(k) & = \sum_{n=0}^{7}x(n)W_8^{kn}\\
& = \sum_{n=0}^{3}W_8^{kn}\\
& = W_8^0 + W_8^k + W_8^{2k} + W_8^{3k}
\end{align}
```

$k\neq 0$ のとき

```math

\begin{align}
X(k) & = \frac{1-W_8^{4k}}{1-W_8^k}\\
& = \frac{W_8^{2k}}{W_8^{\frac{k}{2}}}\frac{W_8^{-2k}-W_8^{2k}}{W_8^{-\frac{k}{2}}-W_8^{\frac{k}{2}}}\\
& = exp(-j\frac{3\pi}{8}k)\frac{sin(\frac{k\pi}{2})}{sin(\frac{k\pi}{8})}
\end{align}
```

$k = 0$ のとき

```math

X(k) = \sum_{n=0}^{3}1 = 4
```

#実装
では，早速実装していきましょう．

```py:square_wave.py

import numpy as np
import matplotlib.pyplot as plt

N = 64            
n = np.array(range(0,N))
f = np.zeros(n.shape)
f[0:4] = 1
F = np.fft.fft(f)

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

ax1.stem(n, f)
ax2.stem(n, np.abs(F))
ax1.set_xlabel('t')
ax2.set_xlabel('k')
ax1.set_ylabel('f')
ax2.set_ylabel('abs(F)')
fig.tight_layout()
plt.show()
```

#解説
特に難しいところはないと思います．
高速フーリエ変換はnp.fft.fft()でできます．
グラフ描画は離散データなのでstemで描画するためnp.stem()となります．

#実行結果
以上のプログラムを実行すると以下のような画像が得られます．

![square_wave(N=8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433790/b0999f6e-1f84-5513-236d-138f9f4737df.png)

$k = 7, 5$の成分は$k = -1, -3$の成分と解釈することもできますね．
ただ$N=8$だと計算は手計算でもできますが，なかなかFFT後の画像から定性的に理解するのが難しいと思います．
サンプル数を増やして$N=64$として実行した結果が以下になります．

![square_wave(N=64).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433790/dc312f0f-89b9-c788-a5e6-1c6ff83d921b.png)

これを見ると，(ふつうの)フーリ変換で得られる，方形波をフーリ変換すると，
sinc関数になるということが若干わかるのではないでしょうか？

#まとめ
今回は，DFTで頻出の方形波のDFTに挑戦してみました．いかがだったでしょうか？
計算に関してはほぼお決まりのパターンなので，たくさん練習をして慣れていくといいと思います．
サンプル数を変えたり，入力信号を変えたりして遊んでみると面白いのではないかなと思います．
次回は，DFTで方形波と並んで頻出の正弦波について扱っていきたいと思います．
今回のプログラムに関して何か改善点や建設的な意見等あればコメントしてもらえると助かります！
C言語のStringポインタからSwiftのString型に変換する

```c:code
const char* hoge() {
    char* var = "HELLO WORLD";
    return var;
}
```
こういうポインタを返す関数の戻り値をswift内でStringに変換したい(ブリッジ前提)


```swift:code
String(cString: UnsafePointer<CChar>(hoge())!)
```
SwiftのStringはcStringを扱えるので
CChar型のポインタを取得->cStringにする->Stringに変換する

もっといい方法あったらご教授お願いします。
Pythonの関数におけるキーワード引数の動きをおさらいする(**もあるよ！)

8ヶ月ぶりのQiita投稿。
最近は「この条件のときどう動くんだっけ？」といった疑問と検証で手が止まることが多い月歩人です。

今回はその中から「Pythonのキーワード引数」に焦点を当てたいと思います。

## Pythonのキーワード引数とは

```python
>>> def f(a, b):
...   print(a, b)
... 
>>> f(a=1, b=2)  <------ コレ
1 2
```
関数に指定されている引数名を、関数呼び出し時に指定することで引数を明示するものです。
この辺りは使用することが多いので割愛します。

今回の記事はよくキーワード引数のところで見る`**`(アスタリスク2つ)について焦点を当てましょう

## よく見る**kwargsの正体

(私はkwargsを`ケーワーグス`と読んでいますが、この辺は論争が起きそうなのであまり触れないようにします)

Pythonのワイルドなキーワード引数にはよく`kwargs`が出てきますが、この引数名自体に意味はありません。
`**`が2つついた引数は、キーワード引数を何でも受け入れるという引数になるので、`**hoge`や`**huga`でも良いのです。
分かりやすいようにパターン別のコードを用意しました。

### 関数の引数に`**`が指定してある場合

```python
>>> def f(**kwargs):
...   print(kwargs)
... 
>>> f(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
```
このように、関数に`**`を用いた引数を用意した場合、呼び出し元のキーワード引数に制限がなくなり、関数へ送った引数は辞書で格納されます。
しかし`**`の動きはこれだけではありません。

### 関数呼び出し時に`**`を指定する場合

```python
>>> def f(a, b):
...   print(a, b)
... 
>>> f(a=1, b=2)
1 2
>>> f(**{'a': 1, 'b': 2}) <------- 等価
1 2
```
辞書に`**`をつけて渡すことで、関数で指定されたキーワード引数に展開することができます。

### 関数呼び出し時と関数の引数に`**`を指定している場合

```python
>>> def f(**kwargs):
...    print(kwargs)
... 
>>> f(**{'a': 1, 'b': 2})
{'a': 1, 'b': 2}
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
```

動きとしては
1. `{'a': 1, 'b': 2}がキーワード引数に展開された！`
2. `**kwargs`がキーワード引数を辞書に収束した！
3. kwargsという辞書が出来上がった！
という感じでしょうか。

他に番外として安易に`**`を使って失敗したor`**kwargs`がゲシュタルト崩壊する例を以下に記載します。

### 関数呼び出し時に`**`を指定したのに関数の引数に`**`がなかった場合

```python
>>> def f(kwargs):
...    print(kwargs)
... 
>>> f(**{'a': 1, 'b': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'a'
```

### 関数呼び出し時に`**`を指定していないが関数の引数に`**`を指定した場合

```python
>>> def f(**kwargs):
...    print(kwargs)
... 
>>> f({'a': 1, 'b': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
```

いかがでしたか？
`**kwargs`がゲシュタルト崩壊したあなたは正解。

とはいえ`**`はPythonの開発でとてもお世話になるので混乱しない程度に動きを理解しておきましょう！
忘れた場合はこちらの記事へ。忘れないようにストックといいねとお願いします。
androidのwebviewについてのまとめ

webview事情について苦悩したので、処方箋を残す。

# 用語集
- Android標準ブラウザ
    - まぎらわしいが、and0.9~4.4まで、androidOSにデフォで搭載されていたブラウザ
    - android5.0以降はごく一部を除いてchromemに入れ替わった

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/f1c2e0e9-8760-96c4-c4ee-71fa80b206dd.jpeg)


- Android System WebView
    - サードパーティのAndroidアプリでWEBコンテンツをレンダリングするためのアプリ
    - Android5.0からアプリとして独立
    - 最新のWebViewはGooglePlayで更新できるようになった

![WebView-Featured-800x400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/b403b2a3-46ad-7aad-a0fa-1294bcec72c0.jpeg)

# ポイント
- Chrome51&Android7以上の場合はChromeがwebviewとして動く
- Android7以上ではデフォルトでAndroid System WebViewは無効化される（Chromeと競合するため）
- 一部に端末ではAndroid System WebViewが入ってないこともある


# まとめ

## android0.9~4.4
- Android標準ブラウザを使用
- OSと同梱
- 個別のアップデート不可能

## android5.0~6.0
- Android System WebViewを使用
- OSと分離
- 個別アップデート可能

## android7.0~
- 基本的にはChromeを使用
- Android System WebViewも入ってはいるが無効化されている


これであなたもハッピー
jsoupによるWebサイトのスクレイピング

#この記事について
Javaのjsoupというライブラリを使って、Webサイトのスクレイピングをする機会があったのでメモ。
詳細に分かりやすく説明している記事は既にたくさんあるが、メモ書きということで。
公式：https://jsoup.org/

#導入方法
[公式サイトのダウンロードページ](https://jsoup.org/download)からjarを入手して、ライブラリに追加するのみ。
Mavenのリポジトリからでも導入できる。
gradleだったら、build.gradleに以下の定義を追加するだけでよい（バージョンは執筆時の最新のもの）

```groovy:build.gradle
dependencies {
	compile('org.jsoup:jsoup:1.12.1')
}
```

#使用例
以下のページから「お知らせ」の日付・タイトル・URLを抽出する場合を例に挙げる。

```
<body> 
 <div class="section"> 
  <div class="block"> 
   <dl>
    <dt>2019.08.04</dt> 
    <dd>
     <a href="http://www.example.com/notice/0003.html">お知らせ その3</a>
    </dd> 
    <dt>2019.08.03</dt> 
    <dd>
     <a href="http://www.example.com/notice/0002.html">お知らせ その2</a>
    </dd> 
    <dt>2019.08.02</dt> 
    <dd>
     <a href="http://www.example.com/notice/0001.html">お知らせ その1</a>
    </dd> 
   </dl>
  </div>
 </div>
</body>
```

以下のコードで抽出する。

```java:Example.java
import java.io.IOException;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

public class Example {

	public static void main(String[] args) throws IOException {

		// 指定のURLに対してGETでリクエスト送信して取得（post()メソッドならPOSTも可）
		Document document = Jsoup.connect("http://www.example.com").get();

		// 取得したdocumentからCSSセレクタで要素を抽出。
		// このelementsが前述のHTMLにおける<div class="block">の要素にあたる、sizeが1のList
		Elements elements = document.select(".section .block");

		// elementsの0番目の要素を取得し、さらにその子要素を取得していく。
		// elements.get(0).childNode(0) ＝ 前述のHTMLにおける<dl>の要素
		// elements.get(0).childNode(0).childNodes() ＝ <dl>の子の、<dt>と<dd>の要素のList
		List<Node> nodeList = elements.get(0).childNode(0).childNodes();

		// nodeListから、forループでお知らせの日付・タイトル・URLを取り出していく
		for (int i = 0; i < nodeList.size() / 2; i++) {
			String newsDate = nodeList.get(i * 2).toString();
			String newsTitle = nodeList.get(i * 2 + 1).childNode(0).toString();
			String newsUrl = nodeList.get(i * 2 + 1).childNode(0).attr("href");

			System.out.println(newsDate);
			System.out.println(newsTitle);
			System.out.println(newsUrl);
		}
	}
}
```

このコード内で使用しているクラスのドキュメントは以下。
使用の際には目を通しておくべきだろう。

[Document(jsoup Java HTML Parser 1.12.1 API)](https://jsoup.org/apidocs/org/jsoup/nodes/Document.html)
[Elements(jsoup Java HTML Parser 1.12.1 API)](https://jsoup.org/apidocs/org/jsoup/select/Elements.html)
[Element(jsoup Java HTML Parser 1.12.1 API)](https://jsoup.org/apidocs/org/jsoup/nodes/Element.html)
[Node(jsoup Java HTML Parser 1.12.1 API)](https://jsoup.org/apidocs/org/jsoup/nodes/Node.html)

#実際の活用について

私の身内が在籍している大学院のWebサイトのお知らせページをスクレイピングするのに活用している。

大学のWebサイト内の「大学からのお知らせ」ページ、基本的に自分と関係のないお知らせしか掲載されないが
数ヶ月に一度程度の頻度で重要なお知らせが掲載されるので、頻繁に見なければならず手間なのだそう。
そこで、以下の処理を行うバッチを組んで、1時間に1回cronで動かしてあげることにした。

* 本記事で説明した方法で、お知らせページをスクレイピングしてお知らせを取得
* ローカルDBに記録している過去のお知らせと比較し、新しく掲載されたもののみ抽出
* 新しく掲載されたお知らせをメールで通知

Javaでメールを送信するのにも、多少苦労した。
これについても後日、記事にする予定。

#参考記事
jsoup使い方メモ：https://qiita.com/opengl-8080/items/d4864bbc335d1e99a2d7
AR Foundationのカメラから静止画を取得する

この記事は @nkjzm さん主催の [Unityゆるふわサマーアドベントカレンダー2019](https://qiita.com/nkjzm/items/7c933bb5c772a0b75512) の8/6の記事です！

## AR Foundationとは

UnityPackageで提供されているARのPackageで、PackagerManagerからインストールすることができます。詳しくは以前下記のブログに書きました。

独立型戦闘支援ブログ : [AR Foundationを使ってみた](https://torikasyu.com/?p=1384)

Appleが発表したARKit 3（現状ベータ版）の機能を使うには、以前から提供されていたARKit Pluginではなく、AR Foundationを使用する必要があります。現状でも、ARKit 2の範囲の機能をAR Foundationを使って作成することができます（ただ、AR FoundationはARKitの全ての機能に対応しているわけではありませんので注意が必要です）

ARKitとARCoreの双方にある代表的な機能（SLAMや平面認識など）はAR Foundationで使うことができますので、新規プロジェクトは積極的にAR Foundationを採用していく方針がいいのではないかと思います。

## AR Foundationのバージョンについて

ARKit 3の機能を使用するには、Packageのバージョンが2.2以上のものを使用する必要があります。ただしその場合、Xcode 11とiOS/iPadOS 13以上の機種を用意する必要があり、アプリの公開も正式版が出るまではできません。なので、公開したいものを作成するには、AR FoudationおよびARKit XR Pluginのバージョンは2.1番台のものを使用しましょう。

<img width="935" alt="スクリーンショット 2019-08-01 17.42.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31032/e610bcbf-9289-60ea-0045-a7c8908018be.png">

## AR Foundationのサンプルを動かしてみる

AR Foundationのサンプルについても、インストールしたAR Foundationのバージョンに合わせたものを使用しましょう。（下記は2.1のリンクです）

GitHub : [arfoundation-samples](https://github.com/Unity-Technologies/arfoundation-samples/tree/2.1)

## AR Foundationのカメラから静止画を取得する

AR Foundationは、ARCameraコンポーネントによってカメラからの画像を処理して表示しています。カメラの画像はARの機能を提供するために特徴点の抽出やSLAM（デバイスの自己位置推定など）に使用されるため、WebCamTextureなどで横からカメラを奪い取ることができません。なので、ARCameraから画像を取得する必要があります。

取得方法についてはAR Foundationのマニュアルに記載されています。

https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@2.1/manual/cpu-camera-image.html

Exampleに記載されているCameraImageExampleクラスを、CameraImageExample.csとして保存して、シーンに置いて実行すると、Texture2D m_Texture にカメラの画像が入ります。
あとは、m_TextureのEncodeToPNG()を実行してバイト列を取得し、ファイルとして保存すればPNGファイルになりますし、外部の画像認識AIのAPI（[Azure Cognitive Services](https://azure.microsoft.com/ja-jp/services/cognitive-services/)など）に送って解析させれば、ARとAIを組み合わせたアプリを作成することができます。

マニュアル類も充実してきているので、AR Foundation使っていきたいですね！
HTML5 のinput-type="datetime-local"で秒を扱う時は色々注意

# HTML5 のinput-type="datetime-local"で秒を扱う時は色々注意
ちょっと嵌ったので備忘も兼ねて

## TL;DR;
* HTML5で日付時刻の推奨input-typeはdatetime-local
* datetime-localはデフォルトでは分刻みで秒は扱えない
* 秒まで扱いたい場合はstepをセットする
* ただし、ブラウザ間で差異がありすぎるのであまり信用してはいけない

## 内容
[MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/datetime-local)の記述を見る限り、
HTML5での日付時刻を入力させたい場合は、input-type="datetime-local"が推奨値のようです。
(ただし、PC版FireFoxとSafariが未対応なのでそこは注意。モバイル版は大丈夫
また、古いinputype="datetime"は使ってはいけないとのこと。)
ただ、このdatetime-local、デフォルトでは秒入力に対応していません。

秒を利用したい場合、step属性に何秒刻みで入力するかを指定する必要があります。

ただ、この部分の挙動はブラウザ間でかなり異なるのであまり信用出来なさそうです。

すぐ私の手元で試すことの出来た3ブラウザだけでも以下のような差異がありました。

|  | Chrome(PC) | Chrome(android) | Edge |
|:-:|:-:|:-:|:-:|
|stepなし(valueで秒まで含む値指定)  |秒は表示されるが入力できない|秒は表示されない|秒が表示され入力できる|
|valueなし stepなし   | 秒は表示されない  |秒は表示されない   |秒は表示されない   |
|valueなし stepあり(1)  |秒が表示され入力できる(1刻み)   |秒は表示されない   | 秒が表示され入力できる(1刻み)  |
|valueなし stepあり(60の倍数)  | 秒は表示されない  | 秒は表示されない  | 秒は表示されない  |
|valueなし stepあり(60を超える60の倍数ではない値)   |秒が表示され入力できる(1刻み)   |秒は表示されない   | 秒が表示され入力できる(1刻み)  |
|valueなし stepあり(2) |秒が表示され入力できる(2刻み)   |秒は表示されない   | 秒が表示され入力できる(1刻み)  |

正直、差がありすぎて全然信用ならないですね。
複数ブラウザ対応しなければいけないアプリの場合、秒入力は別に手動で欄を設けた方が無難かも知れません。
[Ruby][FactoryBot] オリジナルのヘルパメソッドを定義する

# 方法

[FactoryBot::DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/v5.0.2/lib/factory_bot/definition_proxy.rb) を拡張する。

```spec/support/factory_helpers.rb
module FactoryHelpers
  def random_name
    name { %w[ゆの 宮子 沙英 ヒロ].sample }
  end
end

FactoryBot::DefinitionProxy.include(FactoryHelpers)
```

```spec/factories/girls.rb
FactoryBot.define do
  factory :girl do
    random_name
    age 16
  end
end
```

# 参考

* [Add possibility to include helper methods into FactoryGirl to be able to use them on factory definition](https://github.com/thoughtbot/factory_bot/issues/564)
* [How to include a module in a factory_girl factory?](https://stackoverflow.com/questions/7907737/how-to-include-a-module-in-a-factory-girl-factory)
ActiveRecord::Base.connected? と ActiveRecord::Base.connection.active? の違いをソースコードからざっくり把握

# ActiveRecord::Base.connected?

https://github.com/rails/rails/blob/ac7c9381f02446bb4e1681ad66cd69d8abe23594/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L469

```ruby
# Returns true if a connection has already been opened.
def connected?
  synchronize { @connections.any? }
end
```

コメントとソースコードから、ファイルディスクリプタがひとつでも割り当てられていれば true が返りそう。


# ActiveRecord::Base.connection.active?

mysql を例に。

https://github.com/rails/rails/blob/3fd5bf81c033eb2110533c8a713f38c0245356fb/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L101

```ruby
def active?
  @connection.ping
end
```

`@connection` が nil かどうかはチェックしておらず、実際に ping を打った結果を返しているので、ファイルディスクリプタが存在するだけではなく死活もチェックしているように見える。
UnityでTSVファイルをTextAssetとして読み込む方法

## TextAssetとして読み込み可能なファイル形式

[テキストアセット - Unity マニュアル](https://docs.unity3d.com/ja/540/Manual/class-TextAsset.html)

- .txt
- .html
- .xml
- .bytes
- .json
- .csv
- .yaml
- .fnt

ふつう、tsvは読み込めません。

## 解決

- .tsvを.txtにリネームして再インポートする
- 以上
Automation Anywhere でExcelを開き、ソートして保存したい

Automation Anywhere でExcel Bookを開き、ソートして保存したいと思います。
Excelファイルをデータベース的に開く方法の詳細は、以下を参照させて貰いました。
[Automation Anywhereでデータベース操作を行う方法(Excel版)]
(https://qiita.com/satosea/items/ba37a1dffc53ad86ed2a)

ExcelファイルをOLE DB形式で呼び出した後、Commandの[Database/SQL Query]で、OrderBy句をつけたSQL文でデータを取得します。
![001Database.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/dcb1157f-9512-ab67-b7e8-4f8d2f81c9b9.png)

取得した結果をCommandの[Loop/Each row in a SQL query dataset]で取得できます。

問題は、どこにどうやって書き戻すかです。既存のシートにDelete/Insertを実行しても良いのですが、新しいシートを作成して書き戻したい時は、もはやAutomation AnywhereのCommandだけではできません。
Excelに新しいシートを追加する時はShift+F11なので、Commandの[Inert Keystrokes]を使います。

![002InsertKey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/122da11a-fee0-8681-170b-7aa9c705e616.png)

Select Window は書込み先のExcelシートを指定し、Keystrokesには[SHIFT DOWN][F11][SHIFT UP]と記載します。
なお、DOWNだけ書いてUPせずに保存しようとすると、
`Invalid sequence of 'Shift' Key. Are you sure you want to save?`
と叱られます。

セルの位置を指定するために変数を用意しましょう。
画面右の[VARIABLE MANAGER]を開き、[Add]を押し、変数名と初期値をセットします。

![003Variable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/ab0312d1-b5c1-4e86-95d6-c3cc02b3398e.png)

今回は変数としての`$Cell$`と定数のつもりの`$Col$`を宣言しました。

![005Variable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/9a71d752-f9c0-d7c0-da35-ce183c65c5fe.png)
![004Variable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/efcb6059-9670-4c6b-a753-b5683430523b.png)

Loopのたびに初期位置に移動出来るように、変数`$Cell$`にセル名をセットします。

![006Variable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/1f3b0832-4b3a-fcdf-f414-5794d488d027.png)

`$Col$$Counter$`と書いています。`$Col$`には「A」が入っていて、`$Counter$`には行カウンタが入るので、Loopの中で「A1」「A2」「A3」...と値が変わります。
また、読み取った行は`$Dataset Column(n)$`で取得できます。nは1から始まる列番号です。

面倒になって列の数だけCommandを用意しましたが、ここもLoopにした方が格好良いですね。

最後に保存して閉じれば終わりです。

以下、Action Listです。
![007ActionList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417890/f32e341d-3ee6-13e1-f0af-45a288f7cb47.png)

なお、ヘッダを転記できていませんが、元のシートから取得すればよいでしょう。

出来ましたけど、なんだか面倒ですね...

ここまでいろいろやってみましたが、Excelに対してマクロを発行した方が簡単な様な気がします。
Commandに[Excel/Run Excel Macro]があるので、ここからマクロを呼び出せますね。

環境 Automation Anywhere Community Edition 11.0.0.0 + Office365
UISearchController表示時にコンテンツ側がアニメーションされない問題

## 問題

UISearchControllerを利用した検索機能を実装したとき、下記動画のようにコンテンツ部分（UITableView）のY座標がナビゲーションバーに追従してアニメーションされない問題が発生しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">UISearchController表示時のコンテンツ側がアニメーションされない動画 <a href="https://t.co/ahVlh7igPT">pic.twitter.com/ahVlh7igPT</a></p>&mdash; なかん@D128 (@mn_D128) <a href="https://twitter.com/mn_D128/status/1158298397436104705?ref_src=twsrc%5Etfw">August 5, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 原因

UITableViewのTopをSafeAreaのTopにつけていたことが原因でした

<img width="955" alt="スクリーンショット 2019-08-05 17.52.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/9347e608-225f-cc21-00c5-9a69b6f3c1ef.png">

## 解決

SafeAreaのTopではなく、SuperviewのTopにつけることで追従してアニメーションしてくれ、下記の動画のようになります。

<img width="956" alt="スクリーンショット 2019-08-05 17.52.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/41bd5f0b-ac89-56e9-dde1-ccbd55001f97.png">

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">UISearchController表示時のコンテンツ側がアニメーションされる動画 <a href="https://t.co/ZT9wfynJRG">pic.twitter.com/ZT9wfynJRG</a></p>&mdash; なかん@D128 (@mn_D128) <a href="https://twitter.com/mn_D128/status/1158298537873956865?ref_src=twsrc%5Etfw">August 5, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
そもそもAWSとはどんなサービスなのか？

#はじめに
初学者ですが、使ってみたがそもそもAWSとはなんなのかと言われると答えられなかったので調べてみました。
**初学者なので、間違った情報を載せているかもしれません。間違いが有りましたらコメントで教えて頂けると幸いです**

#AWSとは
アマゾンウェブサービス、略してAWSですがあまりに大きすぎて細かい所まではわからないのでとりあえず、大枠を捉える所までは行きたいと思っています
まずは、安定の公式ホームページを見てみます
以下、引用

>Amazon 社内のビジネス課題を解決するために生まれた IT インフラストラクチャのノウハウをもとに、2006 年、アマゾン ウェブ サービス（AWS）はウェブサービスという形態で、企業を対象に IT インフラストラクチャサービスの提供を開始しました。
クラウドコンピューティングの主なメリットの1つは、必要な時に、必要なだけ、低価格で IT リソースを提供することができることです。クラウドを使用することで、企業はもはや数週間・数ヵ月も前から、サーバーや他の IT インフラストラクチャを計画・調達する必要がなくなります。クラウドなら、即座に何百・何千ものサーバーを数分で起動し、迅速に結果を出すことができます。

成程、わからない。
とりあえずわからない横文字を調べていきます。

#考察
###IT インフラストラクチャ
インフラの正式名称だった様です。（無知でした）
インフラと言うと、電気、ガスなど生活の基盤となる物を指す言葉ですが、ITインフラも似た様な意味を持っています。
ざっくりPCやOSなど多くの物が該当しますが、ハードウェアとソフトウェアの２種類に入る様です。
『Webアプリケーションを動かすために必要な要素』という認識で如何でしょうか。
インフラもかなり広い領域になるので色々な意見はあると思いますが、現状webアプリケーションを作る為に勉強しているので、これが一番私はしっくりきました。

###クラウドコンピューティング
こちらもアマゾンさんが解説していました。
>「クラウド（クラウドコンピューティング）」とは、クラウドサービスプラットフォームからインターネット経由でコンピューティング、データベース、ストレージ、アプリケーションをはじめとした、さまざまな IT リソースをオンデマンドで利用することができるサービスの総称です。

これはわかりやすいですね。
従来、データセンターをはじめとするハードウェアを利用する事で発生するデメリットを解消できています。
多額の初期投資と減価償却、必要に応じて規模を変えられる為、初期のキャパシティ予測の必要が無くなるなど私でも感覚的にわかるメリットがありそうです。

#結果
この二つを調べたら最初の引用文が非常にわかりやすいものになりました。
**AWSとはアマゾン社内で使われていたITインフラの技術を広めたもので、従来ハードウェアに起因する初期投資や、キャパシティ予想などのデメリットをクラウドコンピューティングによって解決し、更に大規模に運営しているスケールメリットも生かし、安く使えるサービスだよ！**
といった感じでしょうか。

#まとめ
AWSのざっくりとした認識が、出来ました。が、アマゾンの理念体現しているサービスなので数があまりに多く、個々のサービス内容までを把握するにはいたりませんでした。
今はwebサービスを作る側の勉強をしているので、余裕が出来たら更に個々のサービスにも目を向けて行きたいと思っています
#リンク
https://aws.amazon.com/jp/about-aws/
https://www.pleon.co.jp/fan_contents_02/
https://aws.amazon.com/jp/cloud/
webflux POSTのbodyを @RequestBody で受けると Only one connection receive subscriber allowed になる問題の回避方法

webfluxで`@PostMapping`に来るリクエストのbodyを`@RequestBody`で受けようとするとエラーになる。

https://github.com/spring-projects/spring-framework/issues/22284
この辺

`HiddenHttpMethodFilter` でリクエストの中身を見ているのがダメっぽい。
POSTで他のHTTP Methodを再現できる機能があり、使っていないのであれば回避すれば問題は解決できる。

方法は自分で無効なHiddenHttpMethodFilterのBeanを登録する。
（リクエストのContent−Typeを`text/plain`とかにしても行けるが、こんな御事情のためにわざわざリクエストに手を加えて対応というのはかなり厳しい感じがする）

```
@Component
public class AvoidHiddenHttpMethodFilter extends HiddenHttpMethodFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // just do it
        return chain.filter(exchange);
    }
}
```
Python3入門　コース紹介、環境設定

# コース紹介
今人工知能をはじめとするものが流行っています。その代表とも言えるPythonをやっていこうと思います。やっている中で間違っているところやもっと簡単にかけるみたいなことがありましたら教えてください。また環境はMacでやっておりますのでご了承ください
# 環境設定
##Python３をインストールしよう
１ まずPythonのバージョンを見てみましょう
　　ターミナルを開いてみよう。
　　　　Finder>アプリケーション>ユーティリティ>ターミナル　で開いてみてください。そうすると<img width="564" alt="スクリーンショット 2019-08-05 12.27.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477641/c7d5b5cc-2e4b-f940-207b-65480b716259.png">
このようなものが出てくると思います。ここからいろんなものをインストールしていきます。
ここに「python --version」をやってみてください。そうすると「Python 2. . 」になっているはずです。これを「Python 3.6.0」になって行くようにやっていきます。
２Homebrewをインストールしよう。
Homebrewとはパソコン内に機能を追加したり変更できたりします。

```
/usr/bin/ruby -e "$(curl -fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/install)"
```

でインストールすることができます。<img width="564" alt="スクリーンショット 2019-08-05 17.17.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477641/7e0b8b66-2a3c-e0ca-c8dc-b14e14bac998.png">

２Homebrew内にあるpyenvをインストールする。

```
brew install pyenv
```

でインストールします。そのあとにpyenvに必要なものをインストールしていきましょう。

```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
```
でインストールできます。

３Python３をインストール

```
pyenv install 3.6.5
```
とやってみてください。こうするとパソコンにはインスとるされています。しかし、実際に実行しようとする時にはPython２のバージョンになってしまいます。ですのでそれも変更してみましょう。

４バージョンをPython３にする

```py
pyenv global 3.6.5
```
これで完了しました。次にバージョンをチェックしてみましょう。

```py
python --version
# 実行結果
3.7.3
```
これで完了です。次にテキストエディタを紹介していきます。

# テキストエディタ
みなさんが今使われているのはターミナルというものです。これだと検証はできるのですが、一回一回実行しなければいけません。これだとエラーは防げるかもしれませんが、生産性が悪いです。こんな時に使われるのがテキストエディタです！！これからオススメのテキストエディタについて説明していきます。それはPyCharmです！！PyCharmはものすごくPythonのコードを書くのに適していると思います。しかしテキストエディタは好きなものを選んでください。テキストエディタがプログラムを書く上で大事なものの一つです！
##PyCharm
これからはインストール方法について説明していきます。PyCharmには種類が二つあります。それは有料版(Proffesional)と無料版(Community)です。もちろん有料版の方がいいのですが今回は無料のものを使っていきたいと思います。
このサイトに移動してください。https://www.jetbrains.com/pycharm/download/#section=mac
そしてCommunityをタップしてください。それで完了です。次の回はPyCharmの使い方とPythonの基礎知識について少し触れていきます。
モジュールが import されたのが Jupyter notebook か否かを調べる

tqdm など Jupyter Notebook で使っているのか判定したい場合がある. [^1] Jupyter notebook に書いたコードで直接判定するのではなく、Jupyter notebook から import されたモジュールの中からも判別できてほしい.

方法は Stack overflow を見ると判定方法が百花繚乱でわからん. [^2] import される場合でも使えるものもあれば使えないものもある. ねえ、Zen of Python ってあったよね？[^3]

> There should be one-- and preferably only one --obvious way to do it.


## 問題

`'get_ipython' in globals()` は Jupyter Notebook から直接呼ぶ場合は `True`、Jupyter Notebook から import された場合は `False` なので使えない。


## 結論


```python
'ipykernel' in sys.modules
```

Jupyter Notebook なら `True`, python script などその他は `False`. ipython のターミナル環境でも `False`.

```python3
if 'ipykernel' in sys.modules:
   # Jupyter Notebook
   from tqdm import tqdm_notebook as tqdm
else:
   # ipython, python script, ...
   from tqdm import tqdm
```

## 別解

環境や将来の変更によって使えない場合にもうひとつ候補を。`get_ipython` が `globals()` になくても呼べることを利用して、もみじあめさんバージョン[^1]をちょっと変える

```python3
def is_env_notebook():
    """Determine wheather is the environment Jupyter Notebook"""

    try:
        env_name = get_ipython().__class__.__name__
    except NameError:
        return False

    if env_name == 'TerminalInteractiveShell':
        # IPython shell
        return False
    # Jupyter Notebook (env_name == 'ZMQInteractiveShell')
    return True
```

なんで `globals()` にない `get_ipython()` が呼べるの？？


## 実験

### Jupyter Notebook

Jupyter Notebook に直接書いた場合

```python
'get_ipython' in globals()  # => True
get_ipython().__class__.__name__  # => ZMQInteractiveShell
```

### Import from Jupyter Notebook

```python
'get_ipython' in globals()  # => False
get_ipython().__class__.__name__  # => ZMQInteractiveShell
```

なんで `get_ipython()` は globals() に無いに呼べるの？？

### IPython

```python
In [1]: 'get_ipython' in globals()
Out[1]: True

In [2]: get_ipython().__class__.__name__
Out[2]: 'TerminalInteractiveShell'
```

### Script

スクリプトで import して python3 で実行:

```python
'get_ipython' in globals()  # => False
get_ipython().__class__.__name__  # => NameError: name 'get_ipython' is not defined
```

`>>>` って出る python のインタラクティブモードも同じ.




[^1]: Python: 実行環境が Jupyter Notebook か判定する https://blog.amedama.jp/entry/detect-jupyter-env

[^2]: How can I check if code is executed in the IPython notebook? https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook

[^3]: PEP 20 -- The Zen of Python https://www.python.org/dev/peps/pep-0020/ 


### 環境

```text
$ python3 --version
Python 3.7.1

$ jupyter --version
jupyter core     : 4.5.0
jupyter-notebook : 5.7.8
ipython          : 7.6.0
```