OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでアルファベット文字列をN文字分ずらす

AtCoderの[ABC146 B問題](https://atcoder.jp/contests/abc146/tasks/abc146_b)で、Unicodeに慣れ親しむ機会がありました。

アルファベット文字列を「N文字分ずらす」とは「アルファベット順でN文字後ろのものに変換する」動作を表し、'Z'の次は'A'に戻るとします。上述のB問題でも同様の定義です。

# 組み込み関数```ord()```と```chr()```

Python3には組み込み関数```ord()```と```chr()```が実装されており、文字とそのUnicodeコードポイントを互いに変換して返してくれます。
参考：[Python3.8公式ドキュメント#ord]
(https://docs.python.org/ja/3/library/functions.html#ord)

```python:sample
>>> ord('A')
65
>>> ord('D')
68

>>> chr(65)
'A'
>>> chr(70)
'F'
```

分かったように「Unicodeコードポイント」とか言ってますが、「いろんな文字記号を数字と1対1対応させて表してる世界なんやな」ぐらいの認識で突破です。
日本語が、とかいろんな表し方が、とかは奥が深い世界なので[良さそうな本](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80-WEB-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4297102919/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89&qid=1585548181&sr=8-1)に丸投げします。

どうやら大文字のアルファベットに関しては'A'がコード65で、そこから10進数の連番になっていますね。
ちなみに大文字と小文字の間には

```python:sample

>>> ord('Z')
90
>>> chr(91)
'['
>>> chr(92)
'\\'
>>> chr(93)
']'
>>> chr(94)
'^'
>>> chr(95)
'_'
>>> chr(96)
'`'
>>> chr(97)
'a'
```

と、いくつか記号が挟まってました。へー。

# 実装の注意点

引数でお気づきかもしれませんが```ord()```も```chr()```も一文字の変換を想定しています。
文字列Sを変換する際には空文字列```''```に、```for```文で一文字づつ変換しては結合してを繰り返します。

そして'Z'から'A'に戻る時も考慮するため、```元の文字コードポイントにN加えた整数を26で割った余り```を、'A'のコードポイントに足し合わせることで変換後の文字コードポイントを算出します。

```python:rot_n.py

def rot_n(s, n):
    answer = ''
    for letter in s:
        answer += chr(ord('A') + (ord(letter)-ord('A')+n) % 26)

    return answer
```

確認してみます。

```python:test_rot

>>> rot_n('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 13)
'NOPQRSTUVWXYZABCDEFGHIJKLM'
```


AtCoder B問題での提出はコチラ↓

```python:b.py

def rot_n():
    n = int(input())
    s = input()

    answer = ''
    for letter in s:
        answer += chr(ord('A') + (ord(letter)-ord('A')+n) % 26)

    print(answer)


if __name__ == '__main__':
    rot_n()
```

ちなみに変換後の文字列Sを元に戻す(N文字前にずらす)関数は

```python:derot_n.py

def derot_n(s, n):
    answer = ''
    for letter in s:
        answer += chr(ord('Z') - (ord('Z')-ord(letter)+n) % 26)
        
    return answer
```

となります。

```python:test_derot

>>> derot_n('NOPQRSTUVWXYZABCDEFGHIJKLM', 13)
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
```



# 雑記：ROT N？


冒頭で書いたAtCoderの問題で知りました。
13文字後ろにずらす簡単な暗号である[ROT13](https://ja.wikipedia.org/wiki/ROT13)を一般化してたんですね。
Python はじめから勉強 Hour7：クラスの使い方

# Python はじめから勉強 Hour7：クラスの使い方

* Pythonで何かしようとしたときに、まずサンプルスクリプトを探してなんとなく実行してた私が、
* 自動実行でREST API叩いて、結果の確認、VM操作までやってみたいと思う7時間
* 既にクラスを「使う」ことはできましたが「設計」についても考え見ましょう



## 学習資料

* たった 1日で基本が身に付く！ Python超入門 
  * https://a.r10.to/hbHMiv



## 過去の投稿

* [Python はじめから勉強 Hour1：Hello World](https://qiita.com/matsumo2019/items/5a69381f44456e6e6a5d)
* [Python はじめから勉強 Hour2：制御文](https://qiita.com/matsumo2019/items/6daa862fd34c8929fb65)
* [Python はじめから勉強 Hour3：関数](https://qiita.com/matsumo2019/items/6c63c737c27e51000f79)
* [Python はじめから勉強 Hour4：オブジェクト指向①](https://qiita.com/matsumo2019/items/b4e083b804590fcdf0d1)
* [Python はじめから勉強 Hour5：オブジェクト指向②](https://qiita.com/matsumo2019/items/5d429147ae44d81a69da)
* [Python はじめから勉強 Hour6：よく使うデータ型：タプル型・セット型・辞書型](https://qiita.com/matsumo2019/items/378009f0d65521c083df)



## 環境

* Windows
* Python Ver3系



## クラスを使う目的

* クラスは複雑な処理をきれいにまとめることで、より分かりやすいプログラムを書くための文法です。
* より分かりやすい＝可読性が高い、メンテナンスしやすい、再利用しやすい
* クラスを使わなくてもコーディングできますが大量の変数と大量の関数が必要になり、努力のわりに報われないことになります。
* 変数についても「emp_name」を最初は一般社員向けの変数として作っていた（暗黙的に）。そのため役員用に使うと後々のコードでエラーになる場合もあり、開発者が意図しない使い方をされるケースがあります。クラスを使うとプログラムの文法を使って強制的に守らせることができます。



## クラスの文法について

* クラスは以下のような形で作られます。
  * クラスとメソッドの定義
  * データ（インスタンス変数）の定義
* クラスはインスタンスを作るための設計図で、インスタンスはそこから作られる実体です。そのため、インスタンスにどういう内部データやメソッドをもたせるかをクラスで定義します。
* ひとまずクラスはこんな感じです（オブジェクト指向な記述方法ではありません）
* スクリプト内にクラスを定義することはできますが、小さなスクリプトでは良いですが、別ファイルとして作成してメインのスクリプトファイルと分けることをお勧めします。

### Importされるファイル（読み込まれる側のファイル）mymodule.py

```python
class MyClass:
	def plus(self, a, b):
		return a + b

	def minus(self, a, b):
		return a - b
```

### Importするファイル（実行される側のファイル ) sample.py

```python
import mymodule				# 読み込むファイルを宣言（拡張子はいらない）

my_ins = mymodule.MyClass()	 # MyClassのインスタンス化
a = my_ins.plus(5, 3)		 # MyClassのメソッドを使う
print(a)

b = my_ins.minus(5, 3)
print(b)
```

### 実行結果

	C:\script>sample.py
	8
	2
	
	C:\script>



## クラスを使うプログラム

* ビンゴゲームのプログラム
* 1~99の数字をランダムに取り出す（もちろん重複なし）

### ビンゴクラス bingo.py

```python
import random
class Bingo:
	def __init__(self):
		self.balls = list(range(1, 100))

	def get_ball(self):
		random.shuffle(self.balls)
		return self.balls.pop()
    
	def has_ball(self):
		return len(self.balls) !=0
```

### Importするファイル（実行される側のファイル ) bingo_go.py

```python
import bingo

bingo = bingo.Bingo()
while bingo.has_ball():
	print(bingo.get_ball())
```

### 実行結果

	C:\script>bingo_go.py
	71
	15
	69
	5
	27
	76
	・
	・
	・
	# 0~99の値がランダムに取り出される

* かなりスッキリしたコードになったのではないでしょうか？
* クラスを作成することで変数やデータの受け渡しが明確になっていると思いますので、余計な変数の値の確認が不要でデバッグも楽だと思います。



## 今回のまとめ

* クラスの作成を簡単ですが、整理しました。

* クラスからインスタンス化することでデータが扱いやすくなりました。

* オブジェクト指向型のコーディングには程遠いですが、再利用しやすいクラスを作ることができました。

* どういう動きをしたいかを考えながら設計することで良いクラスができるのかなと

  

## 名言・ライトニングトーク用

* 使い方は分かってきたけど、何かを作るには程遠いような。。。。。。
Windows 10からmDNSでIPアドレスを引いてみる

このご時世、弊社でもテレワークを積極的に実施。家からVPNで会社のネットワークに繋いでみて、Jetson Nanoにつなごうと思って詰み。
普段mDNSを使って、 `hostname.local` からアクセスしてて、TeraTerm SSHからもその名前でいつもアクセスしてたんで、VPNからはアクセス不可。仕方ないので、リモートログインできるWindows PCに入ったけどnslookupでは検索できず。ちょっと調べてたら `Resolve-DnsName` というPowerShellのコマンドがあるとのこと。さっそく試してみた。

```
PS C:\Users\user1> Resolve-DnsName jetson.local

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
jetson.local                                   AAAA   120   Answer     xxxx:xxxx:xxxx:xxxx:xxxx
jetson.local                                   A      120   Answer     192.168.xxx.xxx


PS C:\Users\user1> Resolve-DnsName jetson.local
```

便利。これで家からアクセスできる。まぁ、固定アドレス振れって話もあるけど。。 :)

追記 2020.3.30）
nslookupでもホスト名のみ、もしくは `ホスト名.lan` とすることで拾えました。でも、IPv6は拾えないんですね。
SSHで踏み台経由でアクセスするLinuxでインターネットアクセスするために

# 環境
踏み台(Windows Server) → Linux(CentOS)

踏み台はインターネットアクセス可(プロキシ経由)
Linuxはインターネットアクセス不可

※踏み台がWinなのは、開発しているアプリがWinServerで動作し、Linux(CentOS)はそんな使わないし、
インターネットアクセスするためには、IP振って貰わないといけないのが面倒なので、
プライベートIPを設定しているため。

# 何故SSH経由でインターネットアクセスしたいか

Linuxにyumでパッケージを簡単にインストールしたかったから!


# 設定手順

## リバースポートフォワーディングの設定
　踏み台で下記コマンドを実行する。

```bash
ssh -R <任意のポート>:HTTPプロキシサーバアドレス:HTTPプロキシサーバポート LinuxログインユーザID@Linuxアドレス
```

## yumのプロキシの設定
　Linuxで下記コマンドでyum.confを開き、proxyの設定を追加して保存する。

```bash
sudo vi /etc/yum.conf
proxy=http://127.0.0.1:<1.で実行したコマンドの任意のポート>
```

## yumの動作確認
　Linuxで下記コマンドし、yumの動作確認を行う。

```bash
yum info wget
```

エラーが返らなければOK!
Axiosでrequest/responseの情報をログに出力

[Axios](https://github.com/axios/axios)のinterceptorsを使ったrequest/responseの情報をログに出力する場合のコード例です。
ログの部分をクラウドやログファイルへの出力に書き換えることで、request/responseの記録を残すことが可能です。

``` client.ts
const client = axios.create({
    baseURL: "https://xxx.yyy",
});

client.interceptors.request.use((config: AxiosRequestConfig) => {
    const url = `${config.baseURL}${config.url}`;
    console.log(`Method=${config.method} Url=${url} Body=${JSON.stringify(config.data)}`);
    return config;
});

client.interceptors.response.use(
    (response: AxiosResponse) => {
        const status = response.status;
        console.log(`Success: Status=${status}`);
        return response;
    },
    (error: AxiosError) => {
        const status = error.response!.status;
        const message = error.response!.data.messages[0] || "No message.";
        console.log(`Error: Status=${status} Message=${message}`);
        throw new HttpRequestError(status, message);
    }
);
```

実際のログでは日時とRequestIdを加えて以下のように出力しています。

```
2020-03-24 05:31:49 +0000 [716de8c0-78a6-4387-881c-17a2ca903f55]: Method=get Url=https://xxx.yyy/zzz Body=undefined
2020-03-24 05:31:49 +0000 [716de8c0-78a6-4387-881c-17a2ca903f55]: Error: Status=404 Message=xxx does not exist.
2020-03-24 05:31:49 +0000 [716de8c0-78a6-4387-881c-17a2ca903f55]: Method=get Url=https://xxx.yyy/zzz Body=undefined
2020-03-24 05:31:49 +0000 [716de8c0-78a6-4387-881c-17a2ca903f55]: Success: Status 200
```

より詳細な情報を出力したい場合はAxiosの型定義ファイルを参照してください。
出力したい情報が見つかるかもしれませんね。

``` index.d.ts
export interface AxiosResponse<T = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: any;
  config: AxiosRequestConfig;
  request?: any;
}

export interface AxiosError<T = any> extends Error {
  config: AxiosRequestConfig;
  code?: string;
  request?: any;
  response?: AxiosResponse<T>;
  isAxiosError: boolean;
  toJSON: () => object;
}
```
Dockerやりたい！と思ったらプロキシにボコボコにされた。

#0.なぜDocker？
興味はあったのですが、なかなか手が出せていませんでした。
そんななか社内で検証をやってみる機会があったので今回学んだ内容を備忘録にしておこうと思います。
まあ、ほとんどの失敗が社内Proxyの壁なんですけどね…　

#1.まずはサクっとDockerインストールのつもりが…


こちら2つを参考にさせていただきました。
[Docker入門（第二回）～Dockerセットアップ、コンテナ起動～](https://knowledge.sakura.ad.jp/13795/)
[Docker超入門①〜Dockerってなに？〜【初心者向け】](https://datawokagaku.com/whatisdocker/)

社内プロキシがあることは知っていたのでdockerのインストールは
yum.confに情報を記載してインストールに成功していました。

ですが、docker pullにはdockerのプロキシ認証設定が必要らしく、
[こちら](http://blackwhitebear.hateblo.jp/entry/2018/01/09/233749)　を参考に/etc/systemd/system/docker.service.dに認証情報を記入
おかげさまで無事docker pullできました。

#2.Dockerfileにも必要！proxy設定
dockerfileを作成していて、さあ、buildしようと思ったら盛大にエラーが発生。
そんな時にはdockerfile自体にproxy設定をしておかなければいけないみたいです。
参考は(https://maku77.github.io/docker/proxy.html)

```ruby:qiita.rb
ENV http_proxy http://proxy.example.com:8888/
```

（ずっと RUN export http_proxy http://proxy.example.com:8888/  とかふざけたことしていたから繋がらなかった…）
ちゃんとRUNやENVといったDockerfileの書き方も学んでおくべきでした。

#3.さあ、立ち上がったサーバをブラウザから確認しよう！と思ったら
[データサイエンスのためのPython入門①〜DockerでJupyter Labを使う〜](https://datawokagaku.com/startjupyternote/)
dockerfileの練習にこちらを参考にさせて頂いていたのですが、localhost:8888につながらない。
dockerfileの社内proxyは通ったし、docker statusで調べてみてもサーバは動いている。
はい？ってなりましたが、よくよく考えると私、VMware ESXiで仮想マシンを立てて動かしていたのです。
なのでlocalhostを自分の仮想マシンのIPアドレスにしなければいけませんでした。
参考は[https://ichizaki.com/en/81/]

#4.やってみて
社内proxyがあったり、仮想マシンだったり、環境が違えば参考通りにいかないものです。
それでこそ成長できると信じて社内検証がんばります！
:
Windows10の黒モードを使用するとElectronが起動しなくなる

# 環境
- Windows 10
- Node 10.15.3 (Nodist 0.9.1)
- Electron 7.1.1
- yarn 1.12.1

https://github.com/electron/electron/issues/14402

Windowsを再インストールするところだった。
どうしても動かないと思ったら、バグだったのか・・・。

ちなみに開発ビルドではなく、製品ビルドから起動すると正しく動作する。
自分の考えていたUnitTestはUnitTestじゃなかった

# はじめに

下記記事において、factoryが動かないので `PHPUnit\Framework\TestCase` を `Tests\TestCase` にすればひとまず動くよって書きました。

https://qiita.com/kawagashira/items/7a2fa6550403944f793b

そこで湧いた疑問

* そもそもこの2つの違いは？
    * `Tests\TestCase` はLaravelフレームワーク外の `PHPUnit\Framework\TestCase` を継承し、フレームワークのテストとしている(※表現要確認)
* `PHPUnit\Framework\TestCase` でfactory呼べるようにならないのか
    * 上記理由(フレームワーク外)と後述より、自然には呼べないし、呼ぶべきでない
* そもそもどういう経緯で `Tests\TestCase` から `PHPUnit\Framework\TestCase` を利用するようになったのか
    * 本題

# 調べてみた

https://github.com/laravel/framework/commit/e30a0c979d98f2f1f7b6c565e4002734237a280b#diff-2af5293bd425fda750632a8ba4fab87a
https://github.com/laravel/laravel/pull/5169

# 要約

* `PHPUnit\Framework\TestCase` は単体テスト `Tests\TestCase` は結合テストで使ってね
    * 確かにFeatureテストをmakeすると `Tests\TestCase` がデフォルトで継承される
* factory使うようなのはその時点で結合テストです

# つまり

自分が書いたテストは結合テストだった。

認識としては、「モデルの1メソッドを動かして保存されてるかどうかをテストするのは単体テストやろ！」って感じだった。

とはいえ、プロジェクト的なUnitテストの認識がもうそうなっているので、しばらくは `Tests\TestCase` の書き換えで対応しそう。

# 感想

* 認識を誤っていてすみませんでした。
* そこ変えたときにドキュメントに差を書いてくれればよかったのに。
    * 読んでいるつもりですが書いていたら重ねてお詫び申し上げます

# あとがき

友人が「Qiitaは翻訳サイト」って書いていて、まさにそうなったなぁと。
Python3の演算子メモ



| 記号 | 意味 |
|:--- | --- |
| + | 足し算 |
| - | 引き算 |
| * | 掛け算 |
| ** | べき乗 |
| / | 割り算 |
| // | 小数点以下切り捨ての割り算 |
| % | 割り算の余り |
[Shell]任意の文字列以降の行をすべて出力する

## 目的
以下の出力で、`ccc`以降を表示したい。

```hoge.txt
aaa
bbb
ccc
ddd
eee
```

## grepのAオプションを使う
以下のコマンドで`ccc`出現以降の100行を表示できます。

```bash
cat hoge.txt | grep -A 100 ccc
```

```:出力
ccc
ddd
eee
```
また、BSD系のgrepに限りAオプションに`-1`を指定することが可能です。`-1`を指定すると、`ccc`の出現から行末まで出力されます。

## sedを使用する
以下の記事の通りsedを使用しても実現可能です。
こちらは、行数を指定が不要のため、出力が何行になっても使用可能です。
[今日のsed: 任意の文字列以降の行をすべて出力したい
](https://qiita.com/tohta/items/d779d29d035c1b4f9518)

```bash
cat hoge.txt | sed -n '/ccc/,$p'
```
初めてのBitbucket

railsで作成したアプリをBitbucketに一番初めに保存するときにわからないことがあったためメモしておきます。

・cloud9(aws)環境で実施
・アカウント作成は省略
##公開鍵の作成
```sh:console
cat ~/.ssh/id_rsa.pub
```
上記のコマンド入力で公開鍵を所持しているか確認できます。所持していない場合には`No such file or directory`と表示されます。
鍵を所持していない場合は

```sh:console
cd ~/.ssh　#sshフォルダに移動
ssh-keygen -t rsa -C saber@example.com  # 自分のメールアドレス入力
```
Entキー押すと色々と出てくるが特にいじる必要ないのでそのままEntキー何回か押して鍵を作成。鍵を作成した後に先ほどの

```sh:console
cat ~/.ssh/id_rsa.pub
```
を実行して鍵を表示させます。
##公開鍵の追加
bitbucketにログイン後、
ユーザーアイコン
　　↓
Bitbucket setting
　　↓
セキュリティー
　　↓
SSH鍵
　　↓
鍵追加
　　↓
さきほど表示した鍵をコピペ
　　↓
作成
これで完了です。
##bitbucketへリポジトリ作成
＋アイコンを押し、空のリポジトリを作成します。リポジトリ名はなんでも大丈夫せす（わかりやすくするなら自身のアプリケーション名が良いかと）。
bitbucketにリポジトリを作成すると**バケツに何かを入れましょう**というページに移動し`git remote add origin git@bitbucket.org:ユーザー名/先ほど作成したリポジトリ名.git`と`git push -u origin master`いうコマンドが表示されます。このコードそのまま入力してもいいのですが、まだ自身の環境にリポジトリを作成していない場合は

```sh:console
git init （自身の環境の新しいリポジトリの初期化）
```
ちなみにawsのcloud9の場合はgit導入済みのためこのコマンドが最初から使用できます。

```sh:console
git add -A
git commit -m "メッセージ"
```
上記のコマンド実行し、自身のgitにリポジトリを作成したあとは先ほどの`git remote add origin git@bitbucket.org:ユーザー名/作成したリポジトリ名.git`と`git push -u origin master`いうコマンドを実行します。

```sh:console
git remote add origin git@bitbucket.org:ユーザー名/先ほど作成したリポジトリ名.git
git push -u origin master
```
これでBitbucketに内容が反映されます。

##あとがき
自分なりにわかりやすいよう書いてみましたがわかりにくかったらすみません。
参考になれば幸いです。
PowerShellでログクラスの作成

PowerShell初心者。勉強用メモ。

#環境
Windows10 Home
PSVersion 5.1

# ログクラス

```Logger.ps1
# =============================================================
# Class    : Logger
# -------------------------------------------------------------
# Sunmmary : ログ出力クラス
# =============================================================
class Logger
{
  # -------------------------------
  # Member
  # -------------------------------
  [Bool]   $bInit = $false;
  [String] $strLogPath;
  [String] $strFileName;
  
  # =============================================================
  # Method   : Initialize
  # -------------------------------------------------------------
  # Summary : 初期化処理
  # =============================================================
  Initialize()
  {
    $this.strLogPath  = $PSScriptRoot;
    $this.strFileName = (Get-Date -Format "yyyyMMdd") + ".log";
    $this.bInit       = $true;
  }

  # =============================================================
  # Method   : Initialize
  # -------------------------------------------------------------
  # Summary  : 初期化処理
  # Param1   : ログ出力パス
  # Param2   : ログファイル名称
  # =============================================================
  Initialize([string]$strPath, [string]$strName)
  {
    $this.strLogPath  = $strPath;
    $this.strFileName = $strName;
    $this.bInit       = $true;
  }

  # =============================================================
  # Method   : WriteLog
  # -------------------------------------------------------------
  # Summary  : ログ出力
  # Param1   : 出力する文字列
  # =============================================================
  WriteLog([string]$strText) 
  {
    # 初期化されてなければ初期化
    if(-not ($this.bInit))
    {
        $this.Initialize();
    }

    # 出力日取得
    [string]$strDate     = Get-Date -Format "yyyy/MM/dd HH:mm:ss fff";

　　# パスの生成
　  [string]$strFilePath = Join-Path $this.strLogPath $this.strFileName;
    
    # 出力ログの設定
    $strText = "{0}: {1}" -f $strDate.PadRight(30," "), $strText;    

　　# ログ出力
　　Write-Output $strText | Out-File -FilePath $strFilePath -Encoding Default -append;

    # 画面出力(しない)
    # Write-Host $strText;
  }
}
```


#使用例
Loggerクラスを読みこみ、ログを記載する。

```Test.ps1
# Loggerクラスの読み込み
# ⇒ 同一ディレクトリに存在する、Logger.ps1を実行させる
. (Join-Path $MyInvocation.MyCommand.Path ../Logger.ps1);

# Loggerクラスのインスタンス作成
$clsLogger = [Logger]::New();

# 初期化処理
$clsLogger.Initialize();

# ログ記載
$clsLogger.WriteLog("ログクラスのテスト。");

# エラーログの記載 
try 
{
    1 / 0
} catch 
{
     # エラー時はArrayList『$error』に情報が記載される
　　 # 直近のエラーは$error[0]に格納される
      $clsLogger.WriteLog(($error[0] | Out-String));
}


```



結果は下記の通り。

```20200303.log
2020/03/30 14:09:50 223       : ログクラスのテスト。
2020/03/30 14:09:50 673       : 0 で除算しようとしました。
発生場所 C:\Users\xxx\Desktop\powershell\Test.ps1:17 文字:5
+     1 / 0
+     ~~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException
 
```
【HelloAR】Unity 2019でARCore SDK for Unity v1.16.0 を実装する

# はじめに
久々にARを実装してみようと思いました。[Google公式 Quickstart for Android](https://developers.google.com/ar/develop/unity/quickstart-android)を見れば簡単に作れますね。

環境

- Unity 2019.3.7f1
- ARCore SDK for Unity v1.16.0
- Google Pixel 3a


# Unityの環境を確認し、必要なパッケージをダウンロードする

モジュールはUnity Hubからダウンロードする
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/18376c87-92e8-0680-901a-e8341dc6f89c.png)


Unity 2019を使う場合は`Multiplayer HLAPI`と`XR Legacy Input Helper`のパッケージが必要なのでダウウンロードしましょう。

`Window`→`Package Manager`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/8979442b-51c6-609f-766d-2722d47c35e5.png)

`Multiplayer HLAPI`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/08009a0d-ba69-17c0-630b-c3ee5b364438.png)

`XR Legacy Input Helpers`
![dimage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/0408df4f-5575-5eb7-b66a-a3964b279f22.png)


# ARCore SDK for Unity v1.16.0をダウンロードする

[こちら](https://github.com/google-ar/arcore-unity-sdk/releases)からダウンロードしてください。自動的にインポートされない場合は、ダウンロードしたUnityパッケージを`Assets`→`Import Package`→`Custom Package`で選択してインポートしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/e6c6ad96-28e1-56e4-99e6-755441ca9e85.png)


# ビルド準備
今回実装するのはHelloARなのでダブルクリックしてシーンを合わせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/46c6d09e-c8f6-58c0-790d-c3d070841c7f.png)


`File`→`Build Settings`から`Android`に`Switch Platform`しましょう。少し時間がかかります。終わったら`Scenes in Build`を`HelloAR`にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/a45693d2-f3f1-f883-e522-4bed62f80f1e.png)

`Build Settings`の状態から左したの`Player Settings`をクリックしてみましょう。以下のような画面が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/7beeaa50-8f2d-e86b-1b28-2941feaae2e6.png)

以下の設定通りに変えましょう。`Vulkan`は必要ないので消しましょう。`Package Name`は何でも大丈夫です。`Minimum API Level`は`Android 7.0`以上に設定しましょう。`ARCore Supported`にはチェックを入れましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/37f10e15-2d52-b3b8-6fca-dfdca48e8aae.png)

# ビルドしよう！

ビルドできるようにした状態のAndroidをしっかりUSBで接続しましょう。そして`Build And Run`で実行！ビルドに成功したら、自動的にアプリが立ち上がります。少し時間がかかりますが、その間は何も触れないようにしましょう。

あれれ…ドロイド君じゃなくなった…！？

![93664.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556110/ce534a26-49e7-c515-35b9-c10537ede1a2.jpeg)


上手くビルドできない場合はAndroidの`開発者向けオプション`が`on`になっているか。`USBデバッグ`が`on`になっているか。これらを確認しましょう。詳しくは参考文献を見てください。

# 参考文献

- [Google公式 Quickstart for Android](https://developers.google.com/ar/develop/unity/quickstart-android)
- [デバイスの開発者向けオプションを設定する](https://developer.android.com/studio/debug/dev-options?hl=ja)
IAPを掛けたGoogle App Engineにプリフライトリクエストが届かないときの対処法

IAPを掛けたGAEにプリフライトリクエストを飛ばしたが、GAEにリクエストが届かなかった際の対処法

# 解決策
1. OPTIONSリクエストに応答するコードを追記する。

2. 下記の様にyamlを書く

```bash:iap.yaml
accessSettings:
  corsSettings:
    allowHttpOptions: true
```

3. 下記のコマンドを叩く

```
 gcloud beta iap settings set backend-iap.yaml --project=hoge
```

# 感想
IAPのカスタマイズについて公式で日本語翻訳もあるものの、
英語でないとコマンドがあることが書いてないので、読むべきは英語ドキュメントだなと思いました

# 参考文献
https://cloud.google.com/iap/docs/customizing
C#でPDFファイルにパスワードがかかっているかどうかを確認したい

# 概要
タイトルの通り、C#でパスワードがかかっているかを判断したい！のメモ

[empira/PDFsharp: A .NET library for processing PDF](https://github.com/empira/PDFsharp)

# 環境
Visual Studio 2017
PDFsharp 12.0.1

# 準備
PDFsharpをnugetでインストールします。

# パスワードがかかっているかチェックする

```c#
try
{
  // パスワードのチェックのみなので、ReadOnlyモードで開きます。
  PdfReader.Open(path, PdfDocumentOpenMode.ReadOnly).Dispose();
}
catch (PdfReaderException e)
{
  return e.Message;
}
```
swagger-json(or yaml)を単一のhtmlに変換する

ニッチかもしれませんが、
「Swagger形式のドキュメントをhtmlファイルに出力したい！」
というケースに対応する方法をまとめます。
自分のケースだと、

- リッチなエディタとかツールとか不要でとりあえず今のAPI仕様をサクッと関係者に共有したい
- ネットワーク的な問題で自分らのswagger-uiを先方に公開することはできない

というケースで必要になりました。

## 注意点

結果として生成されるhtmlは、swagger-uiから直接見るドキュメントよりもUX的にだいぶイケて**ません。**
例）POSTとかPUTとかのアコーディオンが全部展開された状態で固定されていたり、など・・・

## 前提条件

- swagger.jsonもしくはswagger.yamlはある
- npmがローカルPCにインストールされている

## ゴール

- swagger.jsonもしくはswagger.yamlを単一のhtmlファイル（cssなし）にする

## 手順

```bash
# 必要なツール群をインストールする
npm install -g bootprint
npm install -g bootpring-openapi # openapi(swagger)のjson、yamlファイルをhtml、cssに変換するツール
npm install -g html-inline # html、cssファイル群を単一のhtmlファイルに変換するツール

# swagger.jsonをhtmlおよびcssファイルに変換する
bootprint openapi swagger.json ./bootprint_output_dir

# htmlファイルおよびcssファイルを、単一htmlに変換する
html-inline ./bootprint_output_dir/index.html > index.html
```

出力が成功したら、最後のコマンドで生成したindex.htmlをブラウザから開いて確認してください。
takes 0 positional arguments but 1 was given

# 原因
pythonはクラスメソッドの引数1つ目に必ず self を取らなければならない。というルールがある。

クラス外から任意のクラスメソッドを呼び出す場合は暗黙的に引数 self　が渡される。
そのため、受け側で self を第1引数に取るように作っていない場合、こういうエラーになる。

```
class Sample:
  def test():
    print('x')

Sample().test()

>>実行結果
TypeError: create_dtl_list() takes 0 positional arguments but 1 was given
```
呼び出し側は引数を渡していないのに、渡したことになっている。（暗黙的にselfを渡している。）

# 対処法
クラスメソッド定義時には必ず、self を第1引数に入れるようにする。
envファイル管理はこれ一択！

# 環境変数管理

## 背景
秘密鍵を使うこともあり,
sample用の`.env.sample`と開発用の`.env`ファイルを分けている

`.env.sample` をコミットに残すため、こちらを正として`.env`を管理したい

## インストール方法

```
go get github.com/locona/envdef/cmd/envdef
```

## 使い方

### テストデータ準備
プロジェクトのルートにある.envファイルにアプリケーション構成を追加します。

```
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
```

プロジェクトのルートにある`.env.sample`ファイル

```
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
REGION=REGION
```
### 実行

次に実行します

```
envdef
```

その結果、`.env.new`ファイルが作成されます

```
REGION=REGION
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
```

console にも変更点が表示されます

## まとめ

envdef を使うことにより、不要になった環境変数や追加された環境変数の管理が楽になりました
NativeScript iOSのreleaseビルドでログ出力する裏技

NativeScriptでは `console.log('hogehoge');` でログを出力することができます。

ただ、iOSでは releaseビルド(本番のストア用ビルド)すると、ログが表示されなくなる仕様です。
(なおAndroidではreleaseビルドでも表示されます。この辺統一して欲しいものです）

そんなときは以下の`__nslog`という隠しメソッドを使うとログが表示できます。

```typescript
import { isIOS } from 'tns-core-modules/platform';

if (isIOS) {
	__nslog('XZ LOG! hogeeee!');
}
```

さて実行してみると...以下のように「コンソール」アプリにログが表示されます！
![コンソール__1_メッセージ_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170712/6710f2a0-94f8-572d-8bbe-ad57585c4c6f.png)


通常リリースビルドでログが出なくても困らないのですが、たまーにreleaseビルドでのみ再現するバグとかがあるときに、原因調査で役立ちます。

このメソッド、内部的には iOSの NSLog をコールしているだけのメソッドです。NSLogがマクロで、直接NativeScriptから呼べないという仕様上の問題があり、NativeScriptコアチームも困って、このような内部メソッドを作ったのだと思います。**非公開メソッドなので今後使えなくなる可能性があるため、productionレベルでの利用は推奨しません**。というか、このメソッド、普通に公開してほしいですよね^^;
Zoom以外でもバーチャル背景を使いたい！

在宅勤務が増えている中で、どうしても顔を出して会議をしないといけない事がありますよね。そんな時に気になるのが、女性だとメイク、そして、男性でも気になるのが部屋の汚さをどうやってごまかすかです。(世の男性の方のおうちをみんな仲間にしてごめんなさい)

Zoomにはバーチャル背景があるので、これまで選択できるときはZoomを使ってきました。

しかし、もうその必要はなくなりました。今日は、Snap Cameraを使う方法を紹介します。

Snap Cameraは、Snapchatというスマホで面白動画を撮れるアプリから派生したプロダクトです。無料で使う事が出来、パソコンのカメラの映像を面白く加工してくれるアプリケーションです。

もう一つ、DingTalkの美肌機能についても紹介します。

# Snap Cameraの仕組み


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/ec90c6b0-25fc-55ed-872a-0dc66d7c3d17.png)


会議ツールからSnap Cameraを利用する仕組みはこのようになっています。

カメラからの映像を加工して、 **Snap Camera自身が仮想的なカメラになりすまします**。そうすることで、これまで会議をしていたツールからは、カメラがPCのカメラとSnap Cameraの2つが見えて居ることになります。

**ビデオ会議ツールはだいたい何でもOK！** Googleハングアウト、DingTalk、それこそZoomでもOK。エフェクトはたくさんありますからね。

# Step1 Snap CameraでLensを指定する

以下のサイトから Snap Camera をインストールします。安心してください。Windows版もMac版もあります。そして**無料です！**

https://snapcamera.snapchat.com/

# Step2 Snap CameraでLensを指定する

Snap Cameraにはいろんな効果を設定した物がラインアップされています。これらをLensと呼びます。このLensはたくさんありますが、オフィスっぽい物はそんなに多くありません。

[VIRTUAL OFFICE 3](https://www.snapchat.com/unlock/?type=SNAPCODE&uuid=799236e786a7411e83a6b8b03d942760&metadata=01) というのがとてもオフィスっぽく、無駄なエフェクトも無く良い感じです。これを選択します。見つからない場合は検索ウィンドウに「VIRTUAL OFFICE」と入れて見てください。他にもいくつかあるので気に入った物を試してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/a05f8dff-3c44-d0a0-985d-44484e1b5d0e.png)

# Step 3 ビデオ会議ツールでカメラを選択する

ここでは[DingTalk](https://www.dingtalk.com/ja-jp)というチャットツールで会議を始めて見ます。なんかデフォルトでSnap Cameraが選択されていましたが、選択されていない場合は、下のカメラメニューから選択が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/9d275b66-b38e-a789-e21b-155ddfe77d22.png)

# Step 4 Ding Talkなら美顔機能がある

会議ツールには珍しく、[DingTalk](https://www.dingtalk.com/ja-jp) のビデオ会議には**美肌機能**があります。この機能のためにDingTalkを使っているところも多いそうです。

右下の「Settings」を選ぶと、「Enable face beauty」という項目があるのでここをONにしましょう。お肌がすべすべになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/8900e839-9bc0-955e-e93c-260cfd5da929.png)


# まとめ

- とにかく、Snap Cameraが有れば殆どのビデオ会議ツールでバーチャル背景が利用可能
- 普段使っているビデオ会議ツールでSnap Cameraを選択するだけ！
- DingTalkを使うと美肌機能がある！

Snap Cameraを起動せずにはじめると下のように黄色い画面になります。Snap Cameraを起動するか、普段のカメラを選び直しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/34edc727-d62b-afe6-48dc-c0af50a7c612.png)


課題は、背景がまだ少ないことと、自分で好きな画像に設定するカスタム背景が使えないことですね。


とはいえ、これでバーチャル背景が使えるようになったので大満足です！
【cluster】アバターが小さかったから、Blenderのobjファイルでどのくらい拡大した？

Blenderでアバターのobjファイルを編集している際、
アバターの大きさがイメージできなかったので、
爆速メモ作成時のアバターは数のように小さくできました。

<img width="423" alt="b01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/1fb74cce-8106-e219-3de3-65e9ccb082cc.png">

その後、Blenderでサイズ変更を行い、アバターのサイズを調整することができました。

<img width="586" alt="b03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/9739baf7-1e6a-eb32-c6c3-b2ed26a15987.png">

<img width="420" alt="b02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/8fb9730c-1829-7e3f-c9b8-e052c55d6a9d.png">
初心者がチーム開発で周りに迷惑かけない為のプルリクエストまでのチェックリスト

こんにちは、フロントエンドエンジニアの[てりー](https://twitter.com/teriteri_code)です。
僕の詳しいプロフィールは[こちら](https://terrblog.com/about/)

個人的には2024年現在は未経験・独学からプログラミングで稼ぐにはフロントエンド開発が1番手っ取り早いと考えています！

https://terrblog.com/programming-first-front-end/

興味があればご覧ください。

# はじめに
20xx年3月30日。
僕はプルリクを出した際に、本来の修正箇所と全く関係ない

「インデント直してー」
「ここのスペースいらないよー」
「console.log消しといてー」

などのミスを連発してしまいレビュアーの方に大変負担をかけてしまいました。
そこで原因を探って行った所、本来みんなが踏んでいるプルリクを出すまでのチェック項目を踏んでいなかった為、ミスを連発していることが発覚しました。

**本記事は今後、僕がケアレスなミスをなくす為にプルリクを出す前に確認するチェックリストです。**
「自分はこうやってるよー」などのより良いやり方があったら教えていただけると幸いです。

# 前提
「チーム単位でフォーマッターなどを導入して仕組みで解決する」事が優先されるべきです。
可能であればチームに対して進言し、より良い仕組みの導入を検討してください。
フォーマッターについて知る上で、個人的にはこちらの記事が参考になりました。
https://wemo.tech/3307

その上で、フォーマッターを導入していないチームの中で、個人の裁量での対処法が本記事になります。


# 1 作業が終わったらdiff(変更差分)を開く！

これは大前提でやりましょう。
これやってないと、「絶対やろうね😅」的な反応になります。

自分はvscodeを使っているので、その方法を。



<img width="874" alt="スクリーンショット 2020-03-30 12.37.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397606/f2c0ef8e-cab4-4ab2-c585-26987f27a736.png">

①左端のバーからソース管理を選択
②差分があるファイルが表示されるので、1つずつクリックしてdiffを開く
③diffが表示されるので確認する

<img width="894" alt="スクリーンショット 2020-03-30 12.43.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397606/b598d53e-b4f7-2373-420c-42ed52d2fde4.png">

左の赤いラインが変更前の箇所
右の緑の箇所が変更後の箇所　になってます。


# 2 diffファイルと睨めっこしてケアレスミスをなくす
diffファイルを開けたら左右で睨めっこしてミスがないか、確認していきます。
この段階で意識してチェックする事柄をまとめておきます。

## ①まずインデントはズレていないか
インデントがズレていると、それだけでプルリクのレビューが終了してしまう恐れがあります。
フォーマッターを入れていると、自動補完で気づかない間にズラしてしまう、なんてこともあり得るので個人的にはフォーマッターは切っておくことをお薦めします。

また、**コピペしたときにもインデントがよくズレます！**
先輩等にslackで相談して、ソースをそのまま持ってきている時などは、気をつけましょう。

## ②変なところにスペースが入っていないか
スペースはdiffファイルで半透明で表示されるので、検知は難しくないです。
これまた自動補完なのか、コードをいじった挙句の弊害なのか、よく残ってしまう事があります。

多くの場合、スペースは必要ないので、いらないと思ったら消しましょう。

## ③そのconsole.log必要？？
console.logやvar_dumpなどは手元で開発しているときによく使うと思います。
テスト用に書いたものの消し忘れに注意しましょう。

## ④その改行必要？？
改行も個人でやっている時に色々いじってしまっている事があります。
必要な改行なのか、コードをごっそり消した際に残った物なのかを判断して要らなければ消しましょう。

ここまでやって問題なければ、プルリクを出しましょう

# 3 プルリクを出したら、レビュアーを指定せず最終チェックしよう

プルリクを出した後にすぐにレビュアーを指定してレビューしてもらうのではなく、
自分がレビュアー1人目になった感覚で最終チェックしましょう。

githubで見ると、さっき気が付けなかったミスが見つかるかも知れません！！
これで問題ない！って思ったらレビュアーを指定してレビューを受けましょう。


# まとめ
今回の記事は「ケアレスミスに対して全く対処していない→最低限これだけはやろう！」までをまとめた内容になっているので、ほとんどの人にとっては当たり前すぎる内容かと思います。

「もっとここを意識すると良いよー」的な内容があれば教えていただけると幸いです。

## 独学でエンジニアを目指している人へ

フロントエンドの仕事を得るまでにどんな勉強をしたら良いのかをまとめました！！

興味ある方は是非ご覧ください。

https://terrblog.com/how-to-get-front-end-job/
【備忘メモ】elastic search 入門メモ

## サンプルコードURL

まず、[こちら](https://github.com/Yu-s/elasticsearch-kibana)からソースをダウンロード。

docker-compose.ymlのあるディレクトリで以下のコマンドでelasticsearchとkibanaが立ち上がる

```
docker-compose up -d
```

立ち上がったら 、、 

## elastic search へのアクセス
http://localhost:9200/   

## kibana へのアクセス
http://localhost:5601/

## 参考URL

https://medium.com/eureka-engineering/%E5%9F%BA%E7%A4%8E%E7%B7%A8-elasticsearch%E3%81%AE%E6%A4%9C%E7%B4%A2%E3%82%AF%E3%82%A8%E3%83%AA%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%9D%E3%81%86-ace3e18c2174

https://dev.classmethod.jp/articles/elasticsearch-getting-started-07/

https://dev.classmethod.jp/articles/elasticsearch-getting-started-08/

## コマンドメモ

リソース作成・変更

```
curl -XPUT "http://localhost:9200/customer/external/1" \
-H "Content-Type: application/json" \
-d '{
  "query": {
    "terms": {
      "name": "taro", "cook_time_min": [10, 15, 20]
    }
  }
}'
```

```
# リソース作成にあたってURLのID指定がない場合は自動でIDが割り当てられる
curl -XPOST "http://localhost:9200/customer/external" \
-H "Content-Type: application/json" \
-d '{
  "query": {
    "terms": {
      "name": "taro3", "cook_time_min": [10, 15, 20]
    }
  }
}'
```

```
curl -XPOST "http://localhost:9200/test/recipes/2" \
-H "Content-Type: application/json" \
-d @./data/recipes/basil-and-pesto-hummus.json
```

リソース削除

```
curl -XDELETE "http://localhost:9200/customer/external/2"
```

## バッチプロセッシング

```
curl -XPOST "http://localhost:9200/customer/external/_bulk" \
-H "Content-Type: application/json" \
-d '
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe2" }
{"index":{"_id":"3"}}
{"name": "Jane Doe3" }
'
```

```
curl -XPOST "http://localhost:9200/customer/external/_bulk" \
-H "Content-Type: application/json" \
-d '
{"update":{"_id":"1"}}
{"doc": {"name": "John Doe becomes Jane Doe"}}
{"delete":{"_id":"2"}}
'
```

## 検索 

データ挿入

```
curl -XPOST 'localhost:9200/classmethod/employees/_bulk?pretty' \
-H "Content-Type: application/json" \
--data-binary "@./data/employees/employees.jsonl"

curl 'localhost:9200/_cat/indices?v&index=classmethod'
```

全件

```
curl 'localhost:9200/classmethod/employees/_search' \
-H "Content-Type: application/json" \
-d '
{
    "_source": {
        "exclude": ["joined_date", "friends"]
    },
    "query": {
        "match_all": {}
    }
}
'
```

ページング

```

curl 'localhost:9200/classmethod/employees/_search' \
-H "Content-Type: application/json" \
-d '
{
    "query": {
        "match_all": {}
    },
    "size": 10,
    "from": 0
}
'

```

フィルタリング

```
curl 'localhost:9200/classmethod/employees/_search' \
-H "Content-Type: application/json" \
-d '
{
    "_source": {
        "include": ["employee_id", "firstname"]
    },
    "query": {
        "match" : {
            "firstname": "tammy"
        }
    }
}
'
```
JTAppleCalendar(v8.0.3)をもう少しさわってみる

# はじめに
以前に書いた記事の続きです。
https://qiita.com/ta9yamakawa/items/850aada73153ba860ad9

カレンダーの表示をとりあえず表示するとこまで行ったので、さらにカスタマイズしてよりカレンダーっぽくしてみます。
公式チュートリアルからよく使いそうなところを掻い摘んでやってみます。
※ 以前のカレンダーでは5行表示をしていますが、6行表示に変更しています。

# 実装
## 別月の日にちを区別する
例えば4月の表示をしたいとき、月初の週に3月の31日が入ったり、月末の週に4月の1日が入ったりすることがあります。
この時、別月の日にちだと見ただけでわかるようにします。

```Swift:MyCalendarViewCell.swift
    func configure(cellState: CellState) {
        
        self.titleLabel.text = cellState.text
        configureTextColor(cellState: cellState) // 追加
    }
    
    /// セルの文字色を設定
    func configureTextColor(cellState: CellState) {
       if cellState.dateBelongsTo == .thisMonth {
          titleLabel.textColor = UIColor.black
       } else {
          titleLabel.textColor = UIColor.gray
       }
    }
```

こうすると、下記画像の青色の枠のようになります。
<img width="350" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550560/39c65383-4d2d-11d5-7e53-edea85bbda59.png">

ちなみに消すこともできます。

```swift
if cellState.dateBelongsTo == .thisMonth {
   isHidden = false
} else {
   isHidden = true
}
```

<img width="350" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550560/a7db9c9a-3029-dedd-0f7f-8e6ce81697f2.png">

## スクロールの制御をする
デフォルトの設定だと縦にスクロールされるので横にスクロールされるようにします。
また、カレンダーが連続してスクロールされるので、スクロールするときにひと月単位で見たいときは下記の設定をします。

```swift:MyCalendarView.swift
    override func awakeFromNib() {
        /*
        省略
        */
        calendarView.scrollDirection = .horizontal // 横向きにスクロール
        calendarView.scrollingMode = .stopAtEachCalendarFrame // 月単位でのスクロール
        /*
        省略
        */
    }
```

## 日付を選択した時のアクションを追加する
選択状態によって、その日にちのセルを表示/非表示を切り替えるようにしてみます。下記メソッドを作成し、configureメソッドの中で呼び出します。

```Swift:MyCalendarViewCell.swift
    func handleCellSelected(cellState: CellState) {
        if cellState.isSelected {
            isHidden = true
        } else {
            isHidden = false
        }
    }
```

日付セルが選択されたときと選択解除されたときにもConfigureの処理を呼ぶようにします。

```swift:MyCalendarView.swift
    func calendar(_ calendar: JTACMonthView, didSelectDate date: Date, cell: JTACDayCell?, cellState: CellState, indexPath: IndexPath) {
        guard let cell = cell as? MyCalendarViewCell else {
            return
        }
        cell.configure(cellState: cellState)
    }
    
    func calendar(_ calendar: JTACMonthView, didDeselectDate date: Date, cell: JTACDayCell?, cellState: CellState, indexPath: IndexPath) {
        guard let cell = cell as? MyCalendarViewCell else {
            return
        }
        cell.configure(cellState: cellState)
    }
```

成功すると以下の画像のようになります。選択した日にちの部分が非表示になりましたね。
<img width="350" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550560/18b69ee1-eb41-4624-6dae-ed314f6e028b.png">

# おわりに
公式チュートリアル（7.1.7）の4までを8系に書き換えながら進めてみましたが、日付の選択やスクロールの設定は比較的簡単にできました。


# 参照
1. [JTAppleCalendar(v8.0.3)を簡単にさわってみる](https://qiita.com/ta9yamakawa/items/850aada73153ba860ad9)
2. https://patchthecode.com/
2. [Cell not selected right away on tap](https://github.com/patchthecode/JTAppleCalendar/issues/1211)
#Rails ActiveModelSerializer で has_many に別の名前をつける例 ( Model class にはエイリアスを作らない )

- User#books というメソッドがあるが items という名前でシリアライズしたい
- User に alias を作れば可能だが model を汚したくない
- Serializer に items メソッドを作ってエイリアスする

```rb
class User < ApplicationRecord
  has_many :books
end

class UserSerializer < ActiveModel::Serializer
  attributes :id,
             :items

  has_many :items

  def items
    object.books
  end
end
```


- ActiveModel::Serializer 自体のオプション等でも出来るかどうかは不明


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Railsのコールバッククラス(callback class)について調べたこと

# 狙い

本文は、前人の知見（[@joker1007](https://qiita.com/joker1007)の[記事](https://qiita.com/joker1007/items/2a03500017766bdb0234)、[@k5trismegistus](https://qiita.com/k5trismegistus)の[記事](https://qiita.com/k5trismegistus/items/3e7339a602f46e9f9087)）踏まえて、コールバッククラスのメリットとデメリットを述べて、さらに実践において、どのような状況で、それを使ったほうが良いのかについて論じてみる。

# 利弊

## メリット

- モデルから、**コールバックの処理**（[Railsガイド](https://railsguides.jp/active_record_callbacks.html)では、「Active Recordオブジェクトが作成/保存/更新/削除/検証/データベースからの読み込み、などのイベント発生時に常に実行されるコード」と定義）といった責務を切り離れる。
    - 異なるモデルでのコールバック処理の中から、汎用性の高い部分を抽出さして、カプセル化することで、メンテナンスしやすくなり、テストもしやすくなる。

## デメリット

- いくつのモデルに使われた共通のコールバッククラスでの処理を変更したい時に、特定のモデルに対してその変更がいい、特定のモデルに対してその変更が悪いのようなケースが生じる可能性がある。
    - 各モデルにコードバックを書くことと比べて、他のモデルにも影響が出るため、変更の際の確認・検証のコストが高くなる。
    - 「他のモデルにも影響が出る」を見落としてしまった状況とつなぎやすくなり、ビジネスロジックの非意図的な変更やサービスの障害が起きる恐れがある。

# 適用条件

1. コールバックの処理のコードの量が異常に多くて、かつ処理の複雑度が高くて、コードを**メンテナンスしにくい**場合
    - メンテナンスをしやすくなることを目的として、コールバックの処理を切り離れる
    - 切り離れたコールバックの処理をカプセル化する時に、他の人がそれを非意図的に使わないように、「明確な名前と境界」を付けることは重要である。
2. 複数のモデルの中にある特に注力したい大事なコールバックの処理があり、それを**ドメイン知識として表現したい**場合
    - 上記の1と同じく、「明確な名前と境界」を付けることは重要である。（これはドメイン知識として成立する前提条件であるので、特に大事）
    - 将来的に仕様の変更によって、その処理を修正する必要な時に、既存の「ドメイン知識」を修正したら十分なので、あるいは新たなドメイン知識が生まれることで、それらを再整理しないとけいないのかを考えることは重要である。
【gitignore】githubのPRで、Files changedが膨大な数になっていた時の対処について

#問題
 githubでPull Requestをする際に、差分ファイルを確認すると、2982と表示されていた。明らかに管理するべきではないものがpushされてしまっている。

　<img width="237" alt="スクリーンショット 2020-03-30 12.35.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/71aabc2a-dfe2-fa10-b2ac-95d088b59a0b.png">


#原因
こちらのFilterFileTypesで確認すると、jpgが多いことがわかった。
<img width="690" alt="スクリーンショット 2020-03-30 12.36.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/ab560f8a-0c49-c9a6-a0b8-524ef3549ef5.png">

ディレクトリから確認していくと、

>　public/uploads/

の内容が原因であることがわかった。


#解決

>$ git rm --force -r public/uploads/*


こちらで、削除することができ、

.gitignoreに
>　public/uploads/*

を追加すると、以降addされなくなった。

結果、
<img width="521" alt="スクリーンショット 2020-03-30 12.43.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/7d109a05-a409-ca9e-ca97-95c07ebb3faf.png">

と差分を一気に少なくすることができた。


# 終わりに
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございます。
vim: dein.vim で ディレクトリツリーを表示させる方法  ~ 0から始めるvim ~


# vim: dein.vim で ディレクトリツリーを表示させる方法


まだインストールされていない方はこちらを参考にしてみてください。
[dein.vimインストール方法] (http://qiita.com/ymiyamae/items/e14059b77ba1cf0b344c)

# インストール
１行追加すれば, インストールされるようになります。

```diff:.vimrc
call dein#begin(expand(プラグインの元のディレクトリパス))

#省略
+ call dein#add('scrooloose/nerdtree')

call dein#end()

if dein#check_install()
  call dein#install()
endif
```

# デフォルトでツリー表示

デフォルトだとvimでファイルを開いたときにツリーが表示されないので,

次のコードを記述してあげると, 開いたときにツリーが表示されるようになります。

```diff:.vimrc
+ autocmd VimEnter * execute 'NERDTree'
```

上記は何をやっているかというと，
autocmd: 指定したイベントが発生したときに自動的に実行するコマンドを指定するコマンドです。
VimEnter: vimの全ての起動処理が終わった後に発生するイベントです。
* の部分: パターン ※今回は全ファイルに適用させる為*を使っています。 他) .txt (txtファイルのみに適用)
execute 'NERDTree' : NERDTree コマンドを実行

[イベント一覧はこちらを参考にさせていただきました。](http://vim-jp.org/vimdoc-ja/autocmd.html)


このような感じになります。
<img width="1625" alt="スクリーンショット 2016-07-19 11.35.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/74135/da833f71-0827-53bc-f85c-f19a856fa06b.png">
【Swift】CAGradientLayer の透過が濁る

下記ブログの転載です！
https://rc-code.info/ios/post-305/

iOSにて、**`CAGradientLayer`** を使って透過を含むグラデーションを行った際、濁る現象があったので対応の備忘録。
&nbsp;


## CAGradientLayer の使い方

*CAGradientLayer* の基本的な使い方については、[こちら](https://developer.apple.com/documentation/quartzcore/cagradientlayer) を参照のこと。
　

## CAGradientLayer に透過を利用すると色が濁る

当然のことながら `CAGradientLayer` はグラデーションを作成するレイヤーです。
「そこで、透過から赤へのグラデーションを作ろう！」と思った時、グラデーションが濁る（中間色がグレーになる）ことに気がつきました。
下記がその時の画像です。

![汚い透過グラデーション](https://rc-code.info/wp-content/uploads/2019/06/alphaGradient_before.png)

この時僕が作成したコードは下記のようなものでした。

```swift
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [UIColor.clear.cgColor, UIColor.red.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
        gradientLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        view.layer.addSublayer(gradientLayer)
```
　
一見、コード上はあっているように思えますが、実は `UIColor.clear.cgColor` が正しくありませんでした！

先に結論を申し上げると、この部分を `UIColor.red.withAlphaComponent(0).cgColor` に修正すると綺麗に透過グラデーションがかかります。

![綺麗な透過グラデーション](https://rc-code.info/wp-content/uploads/2019/06/alphaGradient_after.png)

全体コードでは下記です。

```swift
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [UIColor.red.withAlphaComponent(0).cgColor, UIColor.red.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
        gradientLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        view.layer.addSublayer(gradientLayer)
```

考えてみれば当然で、プログラム上には何色の透過から赤に向かえば良いかが明記されていません。
つまり `UIColor.clear.cgColor` は黒の透過 （おそらくマスクをかけた際のアルファ計算の基準色だから） として扱われているので、赤へのグラデーションにグレーが混じるということだと思います。

「なんか透明のグラデーション作ったけど綺麗じゃないなぁ」と思ったら参考にしてみてください。

## 検証Playground

[検証Playground Git](https://github.com/rickeycode/UINSamplePlaygrounds/tree/master/CAGradientLayer/AlphaGradiant)
&nbsp;

## 検証環境
**Mac:** 10.14.4
**XCode:** 10.2
**Swift:** 5.0
&nbsp;

## 参考ドキュメント
[公式 CAGradientLayer ドキュメント](https://developer.apple.com/documentation/quartzcore/cagradientlayer)
&nbsp;
&nbsp;
jetson-nano のセットアップ

デスクトップを止める

```
sudo systemctl set-default multi-user.target
```

#TensorFlow
https://docs.nvidia.com/deeplearning/frameworks/install-tf-jetson-platform/index.html
に従って

```
sudo apt-get update
sudo apt-get -y install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev liblapack-dev libblas-dev gfortran python3-pip libatlas-base-dev
sudo -H pip3 install -U pip cython
sudo -H pip3 install --pre --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v44 tensorflow
```

#keras
```
sudo -H pip3 install keras
```

https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py

#その他
```
sudo -H pip3 install sklearn pandas matplotlib setuptools
```

#tensorboard
```
tensorboard --bind_all --logdir ./mylog
```

--bind_all　をつけると、localhost以外からでも見れる



#OpenCV

```
import cv2
cv2.__version__
```
4.1.1が入ってた


#cudaのサンプル

```
cp -r /usr/local/cuda-**/sample ~/
cd ~/sample
make -j4
```

#参考
https://qiita.com/karaage0703/items/b14c249aa33112669ee4
RaspberryPiにdietpiをインストールしたあとに


#swapファイルの設定

dietpi-config > advanced > swapfile


vim /boot/dietpi.txt


#webカメラとかマイクとか
```
apt-get -y install fswebcam alsa-utils v4l-utils
```

#カメラのリスト
```
v4l2-ctl --list-devices
```

#撮影
```
fswebcam -d /dev/video0 a.jpg
fswebcam -d /dev/video2 b.jpg
```

#録音デバイスのリスト

```
aplay -l
```

#録音
```
arecord -D plughw:1 -f cd test.wav
```

##音量を調整して再生
```
amixer -c0 sset PCM 100%
aplay --duration=5 test.wav 
amixer -c0 sset PCM 80%
aplay --duration=5 test.wav
```


#kioskで起動する
diet-configでautostartをkioskにして
vim /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh
における、CHROMIUM_OPTSの部分に```--incognito```を追加する


#motion

```
apt-get -y install motion
vim /etc/motion/motion.conf
vim /etc/default/motion 
systemctl enable motion
systemctl start motion
systemctl status motion
systemctl status motion
systemctl disable motion
```


#tensorflow

```
apt install libatlas-base-dev libhdf5-dev python3-pip
pip3 install --upgrade tensorflow
```

#sdカードのバックアップ
```
diskutil list
diskutil unmountDisk /dev/disk2
sudo dd if=/dev/disk2 of=~/Downloads/bk_file.img bs=1m
```
CentOS7 php + Composerインストール

# PHP + Composerインストールメモ

環境用意する際によく忘れてしまうので覚書

# GCP Centosインスタンス

GCPデフォルトインスタンスシリーズで　CentOSインスタンスを作成するとSELinuxはOnの状態になっているので無効化

~~~
# vi /etc/selinux/config

SELINUX=enforcing
↓↓↓↓
SELINUX=disabled

# reboot
~~~



# phpインストール

~~~
# yum update -y

# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

# yum -y install --enablerepo=remi,remi-php73 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql

# php -v
PHP 7.3.16 (cli) (built: Mar 17 2020 10:18:38) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.16, Copyright (c) 1998-2018 Zend Technologies
~~~


## AWS Amazon Linuxの場合

- Amazon Linuxが持っているリポジトリにはバージョン5.4のPHPのみなので、remiリポジトリを使えるようにする必要がある

~~~
amazon-linux-extras install epel
yum install epel-release
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
~~~




# Composerインストール
~~~
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

# php composer-setup.php

All settings correct for using Composer
Downloading...

Composer (version 1.10.1) successfully installed to: /var/www/html/ga/composer.phar
Use it: php composer.phar

#rm composer-setup.php
rm: remove regular file ‘composer-setup.php’? y

# mv composer.phar /usr/local/bin/composer

# composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.10.1 2020-03-13 20:34:27
~~~
marginなどの指定方法、ショートハンド（省略方法）

#上、右、下、左の順に指定する方法
```css
.block {
  margin: 50px 20px 50px 20px;
}
```

#四方同じ数値で指定する方法
```css
.block {
  margin: 50px;
}
```

#上下、左右の順に指定する方法
```css
.block {
  magin: 50px 20px;
}
```


#上、左右、下の順に指定する方法
```css
.block {
  margin: 50px 20px 80px;
}
```
Rails6 のちょい足しな新機能を試す 126（upsert_all bug fix編)

# はじめに

Rails 6 に追加された新機能を試す第126段。 今回は、`upsert_all bug fix` 編です。
Rails 6.0.0 では、 query のキャッシュが有効になっている状態で、 `upsert_all` を実行した後、キャッシュがクリアされないというバグがありました。

Rails 6.0.1 以降では修正されています。

Ruby 2.6.5, Rails 6.0.2.2, Rails 6.0.1, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.2.2
```

今回は、 スクリプトを作成して確認していきます。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# User モデルを作成する

User モデルを作成します。

```shell
$ bin/rails g model User name
```

# スクリプトを作成する

スクリプトを作成します。スクリプトは以下の処理を実行します。

1. Andy という`name` を持つ User を1つ登録する。
2. キャッシュを有効にする。
3. 登録したUserを `User.first` で検索して、`name` を出力する。
4. `User.upsert_all` を実行して、 Andy から Bob に `name` を更新する。
5. `User.first` を使って `name` を出力する。

```ruby:scripts/cache_clear.rb
User.delete_all
ActiveRecord::Base.connection.enable_query_cache!

User.create(name: 'Andy')
user = User.first
p user.name

User.upsert_all(
  [
    {
      id: user.id,
      name: 'Bob',
      created_at: user.created_at,
      updated_at: Time.now
    }
  ]
)

user = User.first
p user.name
```

# Rails 6.0.0 では

Rails 6.0.0 では、 キャッシュがクリアされないため、名前が変わりません。、

```shell
$ bin/rails -v
Rails 6.0.0
$ bin/rails runner scripts/cache_clear.rb
Running via Spring preloader in process 369
"Andy"
"Andy"
```

# Rails 6.0.1 以降では

キャッシュがクリアされるため、名前が期待通りに変化します。

```shell
$ bin/rails -v
Rails 6.0.1
$ bin/rails runner scripts/cache_clear.rb
Running via Spring preloader in process 447
"Andy"
"Bob"
```

# 試したソース

https://github.com/suketa/rails_sandbox/tree/try126_clear_cache_in_upsert
# 参考情報

* [Clear query cache when insert all is used](https://github.com/rails/rails/pull/37154)
CSVデータをPythonでまとめて全角半角処理

カタカナや記号、アルファベットや数字の全角や半角がまじったデータを、統一したい...となったときにする方法。

参考：

https://qiita.com/shakechi/items/d12641d6cad01479785f


面倒なので、CSVをpandasで開いたときに、カラムごとに全角半角処理できるよう関数化しました。
columns = [] のリストにカラム名を入れるだけでOKなようにしています。

処理するもの：
カタカナ、記号（スペースとか）、数字をすべて半角にする。

```python

#pip install jaconvを予めターミナルやコマンドラインツールでしておく。
import jaconv


def shori(column):
    list=  df[column].values.tolist()
    new_list = []
    
    for li in list:
        li = jaconv.z2h(li,digit=True, ascii=True,kana=True)
        new_list.append(li)
        
    df[column] = new_list
    
    return df[column]

##処理したいしたいカラム名をリストに入れます。
columns = []

#forで回します。
for column in columns:
    shori(column)

#strじゃないとエラーが出るときも。そんなときは
df = df.astype(str)

```
rails newで良く使うオプション


# はじめに

rails newで（個人的に）よく使うオプションについてのまとめです。

# よく使うオプション

rails newのタイミングで、一緒に、**bundle install**を実行しない場合、**-B**を付けます。
**Gemfile**を触る事が分かっていて、マシンのスペック上、同じ事を２回行わずに、無駄な待ち時間を短縮させたい時に有効です。

```cmd
rails new project_name -B
rails new project_name --skip-bundle  # こっちでもOK
```

データベースにデフォルトの**SqLite3**を最初から使わない場合は、使用するデータベースを指定します。herokuにデプロイする予定であれば、最初から、**PostgreSQL**を指定しておいた方が無難でしょう。

```cmd
rails new project_name -d postgresql
```

テストには**RSpec**を利用して、デフォルトで用意されている**minitest**は、はなから利用しない場合は、minitestの設定をスキップする事ができます。
後から、minitest関連のディレクトリをrmしてもOK。

```cmd
rails new project_name --skip-test
```

# おまけ

プロジェクト名を指定せずに、**.**を指定すると、プロジェクトディレクトリを作成する事なく、rails関連のファイルが作成されます。整理がつかなくなるため、この使い方もあまりお薦めではないでしょう。

```cmd
rails new .
```

プロジェクト名には、単数でも複数でもこだわる必要はありません。
prototype.js IE7でセレクタでのDOM取得ができない場合の対処法

# 現象
prototype.js(1.7)にてDOM取得を行おうとした際、
IE11(7互換モード)にてjavascriptエラーが発生した。

具体的には、formタグ内のhiddenをCSSセレクタにて取得しようとしてエラーになった。

# 前提
・prototype.js ver.1.7
・1ページ内に同じidの要素が複数ある
　（本当はidが重複してはいけないんだけど、大人の事情で回避できず）

# 書いたコード
``` html:html
<form name="form">
    <input type="hidden" id="hidden">
</form>
```

``` js:js
var submitElem = $$('form[name=form] #hidden')[0];
submitElem.value = 'execute';
```

# IEから吐かれたエラー
`未定義または NULL 参照のプロパティ 'value' は設定できません`
jsの1行目でエレメントが取れていないので、2行目でnull参照となっている

# 対処法
\#hidden → input[id=hidden] に変更することで解決する。

``` js:js
var submitElem = $$('form[name=form] input[id=hidden]')[0];
submitElem.value = 'execute';
```
これでhiddenのvalueに値が入った。

#備考
document.getElementsBySelectorでも発生するか確認したが
IE7互換モードにおいては、上記functionはそもそも非対応であった。