OmniAICreator/Qiita-1.07M huggingface dataset:
python ためになったリンク集

###概要
はい、自分用のメモです。

###thinkerにおいて、ボタンが押された状態を戻す方法
https://suzutaka-programming.com/tkinter-ttk-button-bind/
コールバック関数の終わりをreturn "break"にする。
こんなん思いつかん。

別ファイルのクラスを継承するには
https://www.sejuku.net/blog/68040


### pythonの関数ポインタ（というかコールバック関数）
pythonには「関数ポインタ」はなくて、関数だろうとインスタンスだろうと数値だろうとすべてオブジェクトで「オブジェクトID」が割り当てられていて、オブジェクトIDが辞書に登録されます。
https://qiita.com/moroku0519/items/315cd25d3eaae3217103のコメント欄より


###tkinter を使ってPythonのフォームが表示されるプログラムをpyinstallerでexe化する場合
--noconsole オプションを付けないとフォームが表示されないことに注意する
よって、testForm.pyをexe化する場合は、以下のようなコマンドを実行する

```
pyinstaller testForm.py --onefile --noconsole
```

###cv2で画像を表示したあとに、Tkinterで表示しようとした際にぶつかる壁
「PIL.ImageTk.PhotoImage ndarray 変換」で検索
その結果、できたメンバ関数↓

```
    def whenUseTkinter(self):
        # BGRからRGBへ変換
        CV_im_RGB = self.img_resized[:, :, ::-1].copy()
        # 変換
        self.img2 = Image.fromarray(CV_im_RGB)
        self.imgTk = ImageTk.PhotoImage(self.img2)
        #print("img2・・・{}".format(type(self.img2)))      # <class 'PIL.Image.Image'>
        #print("imgTk・・・{}".format(type(self.imgTk)))     # <class 'PIL.ImageTk.PhotoImage'>
```
結局、ndarray型をPIL.ImageTk.PhotoImage型に変換するということですが、画像のリサイズとか、補助矩形の追加しているうちに、なんかもう大変になる。


###テストでimageを表示したあとに、Tkinterにimageを表示させようとすると色がおかしくなる対策
http://tatabox.hatenablog.com/entry/2013/07/21/231751
BGRからRGBへ変換する
OpenSSLを利用して自己証明書を作成する

# 自己証明書の作成
検証環境等でHTTPS通信を利用するために自己証明書(オレオレ証明書)を作成する。

## 秘密鍵の作成

```
openssl genrsa 2048 > server.key
```

## CSRの作成

```
openssl req -new -key server.key > server.csr
```
入力する情報は必要に応じて変更する。

```
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:<Enter> 
Locality Name (eg, city) [Default City]:<Enter>
Organization Name (eg, company) [Default Company Ltd]:<Enter>
Organizational Unit Name (eg, section) []:<Enter>
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:<Enter>
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:<Enter>
An optional company name []:<Enter>
```

## SSLサーバー証明書の作成
CSRを使ってサーバー証明書(crt)を作成する。

```
openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
```

## 秘密鍵とSSL証明書を移動
作成した秘密鍵と証明書を任意のディレクトリに移動する。

```
mv server.key /etc/pki/tls/private/
mv server.crt /etc/pki/tls/certs/
chmod 600 /etc/pki/tls/private/server.key
chmod 600 /etc/pki/tls/certs/server.crt
```

## CSRを削除
CSRは不要ならば削除する。

```
rm server.csr
```

## 秘密鍵とSSL証明書の設定
ssl.confやhttpd.confなどに必要に応じて設定を追記する。

```
  SSLEngine on
  SSLCertificateFile /etc/pki/tls/certs/server.crt
  SSLCertificateKeyFile /etc/pki/tls/private/server.key
```
ISOからyumを実行する

# はじめに
RHELは評価期間内かライセンスがないとyumの実行ができないが、RHELのISOファイルをマウントすることでyumの実行ができるようになる。
また、オフライン環境時でもyumが実行できるようになるため、場合によってはCentOSなどでも役立つ。

# ISOをマウントする。
インストールに使用したISOファイルをRHELへマウントする。
OS側でISOを認識してない場合は仮想マシン側のホスト側などでマウントできているか確認しましょう。

```
mount /dev/cdrom /mnt/
cp /mnt/media.repo /etc/yum.repos.d/rhel7dvd.repo
chmod 644 /etc/yum.repos.d/rhel7dvd.repo
```
コピーしたrepoファイルを編集する。

```
vi /etc/yum.repos.d/rhel7dvd.repo
```
以下の設定を追記する。

```
[InstallMedia]
enabled=1
baseurl=file:///mnt/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
```

## yumの動作確認
パッケージの一覧が取得できれば成功。

```
yum clean all
yum list --noplugin
```
Linuxでのダミーファイルの作成

# fallocate コマンド
システム領域を予約してダミーファイルを作成する。
## 実行コマンド
1GBの「dummy」というダミーファイルを作成する。

```
fallocate -l 1G dummy
```

# dd コマンド
実際にファイルを作成してダミーファイルを作成する。
コマンド実行完了にまで時間かかる場合もあるかも。

## 実行コマンド
dummyというダミーファイルを作成する。

```
dd if=/dev/zero of=dummy bs=1M count=1
```

- bs 
ブロックサイズ指定

- count
ファイル容量指定

- 「bs=1M count=1」で1MB×1=1MBのファイルが作成できる

# おわりに
fallocateコマンドのシステム領域に予約されるというのはどういうことかとダミーファイルをviで開くと空白の状態になっていたが、ddコマンドで作成したファイルをviで開くと実際に文字列がひたすら羅列されていた。
今のところ、fallocateコマンドの動作も早くてコマンドも覚えやすいので使いやすい気がする。
PHPの　グローバル空間 ＝名前空間の定義がない場合、すべてのクラスや関数の定義はグローバル空間に配置されます

`名前空間の定義がない場合、すべてのクラスや関数の定義はグローバル空間に配置されます。 これは、名前空間に対応する前の PHP がサポートしていた空間です。 名前の先頭に  \ をつけると、 名前空間の内部からであってもグローバル空間の名前を指定することができます。
`

```php

<?php
namespace A\B\C;

/* この関数は A\B\C\fopen です */
function fopen() { 
     /* ... */
     $f = \fopen(...); // グローバルな fopen をコールします
     return $f;
} 
?>
```

#名前空間内のクラス、関数あるいは定数へのアクセス

```php
<?php
namespace foo;

class MyClass {}

// 現在の名前空間のクラスをタイプヒントに使用する方法
function test(MyClass $typehintexample = null) {}
// 現在の名前空間のクラスをタイプヒントに使用するもうひとつの方法
function test(\foo\MyClass $typehintexample = null) {}

// 現在の名前空間のクラスの継承
class Extended extends MyClass {}

// グローバル関数へのアクセス
$a = \globalfunc();

// グローバル定数へのアクセス
$b = \INI_ALL;
?>
```

# \ から始まる名前は常に見た目のままに解釈されます。 つまり \my\name は my\name であり、 \Exception は Exception となります。

```php

<?php
namespace foo;
$a = new \my\name(); // "my\name" クラスのインスタンスを作成します
echo \strlen('hi'); // "strlen" 関数をコールします
$a = \INI_ALL; // $a に定数 "INI_ALL" の値を設定します
?>

```

# 名前にバックスラッシュを含むが先頭はバックスラッシュでない名前、たとえば my\name のような名前は 2 通りの方法で解釈されます。
別の名前に my というエイリアスを指定する import 文がある場合は、そのエイリアスが my\name の my 部分に適用されます。

それ以外の場合は、現在の名前空間が my\name の先頭に付け加えられます。

```php

<?php
namespace foo;
use blah\blah as foo;

$a = new my\name(); // "foo\my\name" クラスのインスタンスを作成します
foo\bar::name(); // "blah\blah\bar" の静的メソッド "name" をコールします
my\bar(); // "foo\my\bar" 関数をコールします
$a = my\BAR; // $a に定数 "foo\my\BAR" の値を設定します
?>

```

```php

<?php
namespace foo;
use blah\blah as foo;

$a = new name(); // "foo\name" クラスのインスタンスを作成します
foo::name(); // "blah\blah" クラスの静的メソッド "name" をコールします
?>

```

# 修飾されていない name のような関数名/定数名はどのように解決される? ¶

```php

<?php
namespace foo;
use blah\blah as foo;

const FOO = 1;

function my() {}
function foo() {}
function sort(&$a)
{
    \sort($a); // グローバル関数 "sort" をコールします
    $a = array_flip($a);
    return $a;
}

my(); // "foo\my" をコールします
$a = strlen('hi'); // "foo\strlen" が存在しないので、グローバル関数 "strlen" をコールします
$arr = array(1,3,2);
$b = sort($arr); // "foo\sort" 関数をコールします
$c = foo(); // calls function "foo\foo" - import is not applied

$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied
$b = INI_ALL; // sets $b to value of global constant "INI_ALL"
?>

```


参考
https://www.php.net/manual/ja/language.namespaces.faq.php#language.namespaces.faq.globalclass
https://www.php.net/manual/ja/language.namespaces.global.php
RHEL ユーザ設定方法

#ユーザの確認方法とは？
##catコマンドの利用

```
# cat /etc/passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
:
:
test:x:1001:1001::/home/test:/bin/bash
```
上記のようにただcatでファイルの中身を見ると無数のユーザーが表示されてしまうので、表示したいユーザーのみ表示して確認します。
ピンポイントで確認するときは、パイプ「 | 」でつなぎ、grepコマンドを利用します。
※/etc/passwdファイルは参照するのみで書き込みはしません。

```
# cat /etc/passwd | grep test
test:x:1001:1001::/home/test:/bin/bash
```
以上が確認コマンドです

##ユーザーの追加方法
useraddコマンドを利用し、catコマンドで追加されたことを確認します。

```
[定型文]
# useradd 追加するユーザー名

[使用例]
# useradd test

# cat /etc/passwd | grep 追加したユーザー名
```

##ユーザーの削除方法
-rオプションによりhomeディレクトリごとまとめて削除できます。
削除した後、catコマンドにて削除されたことを確認してください。

```
# userdel -r ユーザー名
# cat /etc/passwd | grep 削除したユーザー名
```

##パスワードの設定をしたい場合

```
[定型文]
# passwd 設定したいユーザー名

[使用例]
# passwd test
ユーザー testのパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
```

##ユーザーの設定変更をしたい場合

```
[定型文]
# usermod オプション ユーザー名

[使用例]
# usermod -L test
```
オプションの例は下記の通りです。

| オプション  |  説明　　　　                     |
|:-----------|:---------------------------------|
| -a         | 副グループを変更する　             |
| -c         | コメントを変更する                 |
| -g         | 主グループまたはグループ番号（GID）を変更する  |
| -G         | 副グループを変更する    |
| -u         | ユーザー IDを変更する         |
| -o         | 既存のユーザー番号（UID）と同じ番号にユーザーを変更する                        |
| -d         | ユーザーの作業用ディレクトリを変更する　　　   |
| -m         | ホームディレクトリの内容を移動する　　　   |
| -e         | ユーザーの有効期限を変更する　　　   |
| -f         | パスワードの有効期限が切れた後のユーザーのアカウントの有効期限を変更する　　　   |
| -L         | ユーザーをロックする　　　   |
| -U         | ユーザーのロックを解除する　　　   |


##引用

Linuxユーザー一覧の確認と、/etc/passwdファイル項目
>https://kazmax.zpp.jp/linux_beginner/etc_passwd.html

usermodコマンド
>https://eng-entrance.com/linux-command-usermod

以上がユーザ設定方法です。
最後までお読みいただきありがとうございました！
「Gitってadd,commit,pushとかするやつでしょ？」 このレベルだった人がGitについて勉強し始めた、勉強&成長記録です。



#とりあえずやったこと
Main
・サルでもわかるGit入門（書籍）を読む
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=pikacho01-22&language=en_US&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=4295004839&linkId=159cfb40e7765b32ad0e5bd7c77558c0"></iframe>

Sub
・ググる
・その辺のGitの入門書を読む
・dotinstallのGit入門
https://dotinstall.com/lessons/basic_git
.ググってどうしてもわからなかったら聞く

「わかばちゃんと学ぶ Git使い方入門」もウェブ関連の知り合いにおすすめされたが、もうすでにサルわかgitの本を買っていたし、サルわかならウェブでも見られるし、今までサルにお世話になってきたし、また本を買うとお金がかかると言うことで購入はしなかった。
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=pikacho01-22&language=en_US&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=4863542178&linkId=3b9512ebf54c94419aa9dcc9436a3ea0"></iframe>

MainとSubを分けたのは、Mainが土台であとはSubで土台以外のかけているところを埋めていくイメージにしたかったため、分けました。


##主に強化して覚えたことをざらっと
```:git
git rebase
git merge
git stash
git cherry-pick
git blame
git commit --amend
```


###強化して覚えたことを細かく説明
```:git
git rebase
```
git rebase つなぐ元にするブランチ名
git rebase -i の「-i」は、「--interactive」の略式オプション.

```:git
git merge
```
rebaseとmergeはややこしいので、こちらにうまくまとまっている。
https://backlog.com/ja/git-tutorial/stepup/04/

```:git
git stash
```
開発に集中していたのに、急遽対応しなければならない別の修正が上がってくることもある。しかし集中し開発していた内容が、まだコミットするほどに、まとまっていない状況だったら…。そう言う時に使うのはこちら。

```:git
git stash save “任意のメッセージ”
git stash list
git stash apply 復旧したいstash名
git stash drop 削除したいstash名
```


```:git
git cherry-pick
```
cherry-pick意味　いいところどり。
git cherry-pick 取り込むコミットID

```:git
git blame
```
言い方は悪いけれど、誰が間違えたか悪い人探しの時に使うよう・・・・・。
例
$ git blame src/bug.js

```:git

git commit --amend
```
amendは改正という意味
例
$ git commit -m “1st commit”
↓
$ git commit --amend -m “second commit”
とても参考になったサイト
http://ism1000ch.hatenablog.com/entry/2014/03/26/190939


####なんでこの記事を書いたのか？
色々調べたり、本読んだりしてけれど、いざ使う場面になったら使えるか不安なのでこの記事を書いて振り返れるようにしました。
もしそれをしてもわからなかったら、ググってみる。
そうすれば大丈夫だと自分に言い聞かせています。
Xcodeでフォントの追加

フォントを追加すれば選択できると見たけど、Fonts provided by applicationで
<img width="898" alt="スクリーンショット 2019-11-20 17.17.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8433/23bc3720-81ad-d948-bbc9-50bc3d310c04.png">
使うフォントを指定していないと選択できないことを初めて理解した。

自分だけかもしれないけど。記録として残しておく。
その[カッコ]、本当に必要？

# イントロダクション

👇のような巨大なリストがあったとする。

```py
big_list = [
    {"name": "John", "age": 20},
    {"name": "Mary", "age": 17},
    {"name": "Tom", "age": 16},
    {"name": "Michael", "age": 11},
    # ...
]
```

`name`をすべて結合したいとき、👇のようなコードを書く人が少なくないだろう。

```py
#       ↓                               ↓
names = [per["name"] for per in big_list] # list comprehension
all_names = ", ".join(names)
```

この`[ ]`は実は不要である。不要なだけではなく、`big_list`と同じサイズのリストが作られ、メモリを無駄に消費することになる。本来の目的は`name`をすべて結合することなので、このような中間的なリストは必要ない。

単に👇のように`[ ]`を外すだけで(シンタックスの都合上`( )`が必要)、無駄なリストは作られなくなる。

```py
names = (per["name"] for per in big_list) # generator expression
all_names = ", ".join(names)
```

# list comprehension

list comprehension は、**実行された時点でリストが作成される**。

```py
[i * i for i in [1, 2, 3]]
```

# generator expression

generator expression は generator オブジェクト(**iterator**) を返す。実行された時点では元のリストに対しては**要素へのアクセスも何もされない**。

```py
(i * i for i in [1, 2, 3])
```

iterator とは `next` 関数で一つづつ値を取り出すことができるオブジェクトである。この generator オブジェクトに関しては、`next` で次の値をリクエストされたときに**はじめて**元のリストの要素を一つ取り出し、必要な処理を行って返すようになっている。そのため、元のリストがいくら巨大でも generator が消費するメモリサイズは一定である。このような処理の仕方は lazy evaluation と呼ばれる。

```py
def f(x):
    print(f"x={x}")
    return x

gen = (f(i) for i in [1, 2, 3])

next(gen)  # x=1
next(gen)  # x=2
next(gen)  # x=3
next(gen)  # Exception has occurred: StopIteration
```

上の例ではリストから generator を作ったが、generator から generator を作ることもできる。

```py
gen1 = (i * i for i in range(10))
gen2 = (i for i in gen1 if i > 10)
```

注意すべき点として、iterator は**一度しか反復できない**ということである。一度最後まで読んでしまうと、空のリスト同然になる。

```py
gen = (i * i for i in [1, 2, 3])
print(sum(gen))  # 14
print(sum(gen))  # 0
```

そのため、複数回反復する必要がある場合は 毎回 generator を作るか list comprehension を使うなどする必要がある。

# generator(iterable) が使える場所

iterator は iterable なので(iterable は必ずしも iterator ではない)、iterable が使える場所ならばどこでも generator expression が使えるということである。Python の構文やビルトイン関数では iterable が使える場所は意外なほど多い。

- ビルトイン関数
    - `all`, `any`
    - `enumerate`, `zip`, `filter`, `map`
    - `sum`, `max`, `min`, `sorted`
    - `list`, `dict`, `set`, `tuple`

- for-loop

```py
for x in iterable:
    print(x)
```

- comprehensions

```py
# list
[i for i in iterable]
# set
{i for i in iterable}
# dict
{i : i for i in iterable}
```

- unpacking

```py
# list
[1, 2, *iterable1, *iterable2]
# set
{*iterable, 3}
# 引数
print(*iterable)
# 代入
a, b, c = iterable
ls[3:6] = iterable
```

- `in` 演算子

```py
3 in iterable
```

- ビルトイン型のメソッド

```py
# str
"".join(iterable)
# set
{1, 2, 3}.union(iterable)  # intersection, difference などもOK
# dict
{"name": "John"}.update(iterable)
```

他にも、標準ライブラリ itertools が `iterable` から `iterator` を生成する関数を豊富に揃えている。
Power Automate（旧:Microsoft Flow）を使ってカウントダウンタイマーを作ってTeamsに通知する

#作った経緯
大事なイベントまで**どれぐらいの日数が残っているのかを簡単に把握したい**のと、
それによって**自分を追い込む**というのが理由です。（もれなく、他の人も追い込めます！）

#最終的にTeamsに通知されるイメージ
Teamsにはこんな感じで通知されます
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/e8899eec-feec-dee1-4828-d83e216f8581.png)

#全体の流れ
全体の流れは以下のようになります。

1. 毎日の8:00に実行する
1. データ操作：イベントの日付(yyyy-MM-dd)を入れる
1. データ操作：今日の日付を取得して入れる
1. 変数(今日の日付)を初期化して、今日の日付を代入する
1. 変数(残り日数)を初期化する
1. 変数(今日の日付)とデータ操作(イベント)の出力と日付が一致するまで、変数をインクリメントして比較する
1. 変数(残り日数)を1日分減らす
1. Teamsに通知する

![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/faa6abca-b2fa-2225-d280-954c0cd05da0.png)

#詳細設計
それぞれの詳細設定は以下のようになります。

・毎日の8:00に実行する
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/b89ad28f-3b8d-9e64-5225-4e678d91dea8.png)

・データ操作
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/4ed54a85-07be-0840-6ce4-e918e0255f61.png)

・変数の初期化
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/77afabc2-1d04-56d4-1adf-7250c6e2bfc7.png)

・日付が一致するまでインクリメント
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/bd2a3ec9-60b1-1e2f-d17b-6e730602ab04.png)

・変数(残り日数)を1日分減らす
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/4ad16e19-1a81-e72f-ce5c-c9b43a2c99a2.png)

・Teamsに通知する
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475457/40cca0f6-6228-62a2-7c9d-7db803f42cef.png)


#まとめ
Teamsを使うことが多いので、カウントダウンタイマーで大雑把な工程管理が出来るのでとても便利。
RHEL subscription登録方法

##経緯
目的：RHEL(仮想OS)のsubscription登録
試作　①コマンドにて登録を試みましたが登録失敗
　　　→外部ネットワークと疎通出来ないサーバ(仮想基盤)にいると上手く疎通出来ない模様
　　　②外部ネットワークと疎通出来るサーバ(仮想基盤)に移動してからvirt-whoを再起動し、登録しました

##subscription登録方法

```
# subscription-manager register
# subscription-manager attach --auto
```

上記のやり方で登録を試みましたがうまくいきませんでした。
そこで下記手順に変えました。


①RHEL(仮想OS)の移動：外部ネットワークと疎通出来る仮想基盤に移動します
②移動先で下記コマンドの実行

```
# subscription-manager register
```
③virt-whoの再起動

```
# systemctl restart virt-who
```

④登録の実行

```
# subscription-manager attach --auto
```

因みにvirt-whoとはハイパーバイザーとゲストとの対応関係を登録するところのようです。
再起動をする理由としては、virt-who自体が移動先の情報を取得することが出来ていないからです。
再起動することにより、移動した仮想OSの情報を取得することが出来ます。

今回は外部ネットワークに疎通出来ない仮想基盤で登録を実施した結果、このような事態に遭遇した為
仮想基盤を移動しvirt-whoを再起動させることで解決しました。



##引用

赤帽エンジニアブログ
>https://rheb.hatenablog.com/entry/virtwho

以上がsubscription登録方法でした。
最後までお読みいただきありがとうございました！
Next.jsでenvファイルを使用する

# 背景
Next.jsでfirebaseを使ったユーザー認証を作成したときにenvファイル使ったのでそのメモです。

# 実施
[dotenv-webpack](https://github.com/mrsteele/dotenv-webpack#readme)パッケージを使用します。

```
yarn add dotenv-webpack
```

`.env`にはfirebaseのapiKeyとmessagingSenderIdを記述しました。

```text:.env
REACT_APP_FIREBASE_APIKEY=""
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=""
```

```javascript:firebase.js
import firebase from 'firebase/app'
import 'firebase/auth'

  // Your web app's Firebase configuration
const firebaseConfig = {
    apiKey: process.env.REACT_APP_FIREBASE_APIKEY,
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
    appId: "",
    measurementId: ""
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

export default firebase
```

### next.config.jsの設定

```javascript:next.config.js
const path = require('path')
const Dotenv = require('dotenv-webpack')

module.exports = {
  webpack: config => {
    config.plugins = config.plugins || []
    config.plugins = [
      ...config.plugins,

    // 設定を記述
    new Dotenv({
        path: path.join(__dirname, '.env'),
        systemvars: true
      })
    ]

    config.node = {
      fs: 'empty'
    }

    return config
  }
}
```

# 終わりに
Next.jsの記事がもっと増えていってほしいですね！
Rviz2が動かない時

次のエラーが出る場合、

```
dyld: Library not loaded: /usr/local/opt/assimp/lib/libassimp.4.dylib
  Referenced from: /Users/yamamoto2072/ros2/dashing/bin/rviz2
  Reason: image not found
```

これを実行するとOK。

```
ln -s /usr/local/lib/libassimp.5.dylib /usr/local/lib/libassimp.4.dylib 
```
Firebase Cloud storageへBase64形式で画像をアップロードしようとしてハマった話

#前置き
Firebase Cloud storageは、Blob、Base64等の形式でのアップロードにも対応している。
参考:[ウェブでファイルをアップロードする]:(https://firebase.google.com/docs/storage/web/upload-files?hl=ja)
#エラー
ただしBase64形式でそのままputString()の引数に取るとエラーとなる。
>FirebaseStorageError {code_: "storage/invalid-format", message_: "Firebase Storage: String does not match format 'base64': Invalid character found", serverResponse_: null, name_: "FirebaseError"}

#原因
base64形式の文字列の先頭についている"data:image/jpeg;base64,"が原因。これを取り除いてアップロードすればおｋ。

```javascript

<script>
firebase.storage().ref().child(kani)putString(base64.substring(23), "base64");

</script>
```

調べていると「blobでやれ」という話があったけど備忘録代わりに書いておく。
RHEL resolv.confの設定方法

#resolv.confとは？
・DNSサーバの情報が書いてあるファイル
・リゾルバ＝IPアドレスからドメイン名を探すソフトウェア

#resolv.confを設定するには？
##viコマンドの利用
設定するにはviコマンドを利用し、catコマンドで確認します。

```
# vi /etc/resolv.conf
# cat /etc/resolv.conf
```


##書き方

```
[書くもの]
nameserver ネームサーバのIPアドレス
domain　　　ドメイン名
search　　　検索リスト

```

##確認するには？
###catコマンド、nslookupコマンドの利用

```
# cat /etc/resolv.conf
# nslookup IPアドレス
```
catコマンドはファイルを参照するときに使用します。
nslookupコマンドは名前解決出来ているのかどうかを確かめるコマンドです。



##引用

Linux初心者の基礎知識
>http://linux-beginner.com/linux_setei2.html

Linuxのリゾルバとは何か？
>https://www.itmedia.co.jp/help/tips/linux/l0351.html

今すぐ実践！Linuxシステム管理
>http://www.usupi.org/sysad/021.html

以上がresolv.confの設定方法でした。
最後までご覧いただきありがとうございました！
curlコマンドで配列の中のハッシュを渡す方法

名前はなんでも良いですが、このようにvaluesの中に詰めて送ります。

```console

curl -H POST 'http://localhost:3000/XXXX/XXXX' -H 'Content-Type: application/json;charset=utf-8' -d '{"values":[{"name":"XXX", "status":"1"}, {"name":"XXX","status":"2"}]}' -H 'Authorization: Bearer XXXX' | jq .
```
Go言語*(ポインタ)を使う必要性の簡単な例

##背景

- Go言語のプロジェクトでよく*(ポインタ)を見かける。

例1

```golang
func setName(user *User,name string){
	user.username = name
}
```

例2

```golang
type (
	Users []*User
)
```

- ではなぜそうなるでしょうか?


##結論
*(ポインタ)を使わないと構造体(struct)の値が編集できない ***


###例1 *(ポインタ)を使わず、structを編集する

```golang

type User struct {
	username string
	password string
}

type (
	Users []User
)

func setName(user User,name string){
	user.username = name
}

func (user User) setName(name string){
	user.username = name
}

func main(){
	changeTheValue()
}

func changeTheValue(){

	user := User{
		username:"syoui",
		password:"pass",
	}

	log.Printf("before change the value of the user %s",user.username)

	user.username = "villa"

	log.Printf("after changing the value of the user %s",user.username)


	setName(user,"kelr")
	log.Printf("after changing the value of the user %s",user.username)

	user.setName("syoui")

	log.Printf("after changing the value of the user %s",user.username)
}

```


```sh

before changing the value of the user syoui
after changing the value of the user villa
after changing the value of the user villa
after changing the value of the user villa

```

### 結果
- user.username = "villa" ->  編集できた
- setName(user,"kelr")　  ->  編集できませんでした
- user.setName("syoui")   ->  編集できませんでした





###例2 *(ポインタ)を使う、structを編集する

```golang

type User struct {
	username string
	password string
}

type (
	Users []User
)

func setNameUserByPoint(user *User,name string){
	user.username = name
}

func (user *User) setNameByPoint(name string){
	user.username = name
}

func main(){
	changeTheValue2()
}



func changeTheValue2(){
	user := &User{
		username:"syoui",
		password:"pass",
	}

	log.Printf("before change the value of the user %s",user.username)

	user.username = "villa"

	log.Printf("after change the value of the user %s",user.username)


	setNameUserByPoint(user,"kelr")
	log.Printf("Adter change the value of the user %s",user.username)

	user.setNameByPoint("syoui")

	log.Printf("Adter change the value of the user %s",user.username)
}

```


```sh
before change the value of the user syoui
after change the value of the user villa
Adter change the value of the user kelr
Adter change the value of the user syoui
```

### 結果

- user.username = "villa" ->  編集できた
- setName(user,"kelr")　  ->  編集できた
- user.setName("syoui")   ->  編集できた
Firebase Authenticationで「[vuex] Do not mutate vuex store state outside mutation handlers.」エラー

直接VuexのStateを変更しているつもりはないにも関わらず、タイトルのエラーが出てしまった。

具体的には以下のようなコードだった。

```JavaScript
 firebase.auth().onAuthStateChanged(user => {
      this.$store.dispatch("mutateUserData", user);
  });
```

## :bomb: 原因
Googleアカウントでのログイン状態が変化したとき、Stateを変更するActionを発行するというものだ。  

一見問題なさそうに見えるが、この user は色々プロパティがあってログイン状態の変化により勝手に色々と書き換わるらしい。
    
上記のやり方だと参照渡し（っぽい奴）なので、その時に直接Stateが書き換えられたと見なされてしまうんだと思う。

## :star: 解決策

```JavaScript
 firebase.auth().onAuthStateChanged(user => {
      const { uid, displayName } = user;
      this.$store.dispatch("mutateUserData", { uid, displayName });
  });
```
こんな感じで、オブジェクトを直接渡さないようにすれば良い。  
自分の場合はついでに必要なプロパティだけ取得するようにした。
RHEL hostsファイル設定方法

#Linux RedHat hostsファイル設定する方法

##hostsファイルって何？
hostsファイルを設定する前に、そもそもhostsファイルとは何かを自分なりにまとめました。

hostsファイルとは、IPアドレスとマシン名を関連付けるファイルです。
　　　　　　　　　　　　　↓
「そのホスト名に対してアクセスしたとき、対象のIPアドレスへアクセス出来るようになる為のファイル」です。

##設定するには？
###viコマンドを利用

```
# vi /etc/hosts
```

##確認するには？
###catコマンドの利用

```
# cat /etc/hosts
```


##引用

システム設定ファイルを知ろう
>https://www.itmedia.co.jp/help/tips/linux/l0351.html

以上がhostsファイルの設定方法でした。
最後までご覧いただきありがとうございました！
Chrome ヘッドレスモードエラーの対処法

#はじめに
pythonでスクレイピングツールを作成後、別ネットワークで起動させたところエラー発生。
（ヘッドレスモードがエラー、ブラウザが立ち上がるモードは正常）
その時の対処を記載します。

#エラー発生はPROXYサーバによるもの
ツール作成時はインターネットへの接続はWiFiから直（たぶん）、ツールを移動させた場所は社内ネットワークに接続された端末で、PROXYサーバの設定がされていた。

#端末からPROXYサーバの確認
###  WINDOWS10
「設定」→「プロキシ」→「プロキシサーバーを使う」が「オン」になっている。
アドレスを控えておきましょう。
### MAC
「システム環境設定」→「ネットワーク」→「詳細」→「プロキシ」→「Webプロキシ(HTTP)」にチェックが入っている。
「Webプロキシサーバ」のアドレスを控えておきましょう。

#コード追加

```python:
option.add_argument('--headless')	                  #←ヘッドレスモード指定されている
option.add_argument('--proxy-server=http://※※※')   #これ追加！
```
※※※は控えたアドレス
GitHubのiOSモバイルアプリのベータ版が試せるよ

https://github.blog/changelog/2019-11-12-github-for-mobile-ios-beta/
2019年11月12日にモバイルでのiOSベータ版GitHubが始まりました。

https://github.com/mobile/beta

現在こちらのページからAppleIDを登録すると
TestFlight版の招待が届くようです。


通知のトリアージや作業がどこからでもできるようになるみたいなので
正式版のモバイルが楽しみです。

私はまだwaitlistに載っただけで使えていないので、
招待がきたら軽く使ってみてレビューしたいと思います。
User ID 検索大、小文字区別方法



例：1S999  OK    1s999  NG

```
★
QLで変更する場合
テーブル作成時
CREATE TABLE `posts` (
	`id` INT(11) PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(100) BINARY,
	...
);
```

★変更のケース
```
ALTER TABLE `posts` MODIFY `name` VARCHAR(100) BINARY;
```

```
検索時に、フィールドにBINARY演算子を加える

これは一時的な設定です。
SELECT * FROM `posts` WHERE `user_id` = BINARY 'Hoge';    hogeなら、通らない。Hogeの大文字idのみ通る。


```
Nuxt.js + Firebase + Ongaq.jsを使ってドラムのフィルインを自動生成するWebサービスを作った

## :star: 概要
![Drum Fills   Chops Generater by oimo23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55603/9bd76007-f30c-ec04-382e-027da4b9f282.png)
[Drum Fills & Chops Generator](https://drumfills-c209e.firebaseapp.com/)  
[ソースコード](https://github.com/oimo23/Drum_Fill_Generator)

一部のマニアックなドラマーにしか需用の無さそうなサービスを作ってしまった。
ドラムにはフィルインというものがある。

***「ドツタツドツタツ」***

というのが普通のビートとすると、フィルインというのは

***「タカトン」***

みたいな奴だ。

そのフィルインの中でも1小節、2小節という長めのフィルインを無限に自動生成できるというものだ。

## :tools: 使った技術
***Nuxt.js、Firebase、Ongaq.js***

Ongaq.jsは最近出てきたライブラリなので聞いたことが無い人が多いと思う。

## Ongaq.jsの簡単な説明
![Ongaq JS   A JavaScript library for making music    CodeNinth Ltd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55603/4800be15-8d4b-6d2d-b035-45cb4efadd7d.png)
https://www.ongaqjs.com/

API経由で呼び出して、無料でもなかなか良い音色の楽器を使用して音楽をJSで作成出来る。 
簡単に音が鳴るところまで作ることが出来る。

SetInterval()は実は精度が低かったり、シーケンサーみたいのをJSで一から実装するのは結構メンドイのだ。  

```JavaScript
const ongaq = new Ongaq ({
	api_key: "YOUR API KEY",
	volume: 40,
	bpm: 130,
	onReady: ()=>{
           ongaq.start();
	}
})

const my_drums = new Part ({
	sound: "small_cube_drums"
})

my_drums.add( new Filter ({
	key: "kick",
	active: beat => beat % 8 === 0
}))

ongaq.add( my_drums )
```

API KEYの取得とアクセス制限の解除、ongaq.jsのインポートは要りますが、ほぼ上記のような感じで簡単にドラムが鳴ります。

[詳しくは公式のチュートリアル](https://www.ongaqjs.com/tutorial/)

## :tools: Nuxt.jsとFirebase
SSRをしなくてもNuxtは十分恩恵があると思っているので、使うようにしている。  
初期の環境構築の手間を省けるし、規約に乗っかるので破綻しにくいのも良い。  

Googleアカウントでログインし、作ったフィルインを保存できる機能を実装したかったので、Firebase AuthenticationとFirestoreを使って実現した。  
     
もはや個人開発ではFirebase一択では無いかと思う。  
唯一AuthenticationとVuexの連携でハマってしまった。
[別記事：Firebase Authenticationで「[vuex] Do not mutate vuex store state outside mutation handlers.」エラー](https://qiita.com/oimo23/items/b815c7d212525fe56722)

## :star: 良いところ
生成されたフィルのアイデアを貰ったり、保存して練習したり出来る。    
奇数割のパターンを4/4の16分音符に当てはめたり、現代のドラムっぽいフィルの作り方が出来るのがポイントだと思っている。  

## :baby: 課題
といってもまだまだ課題有

・3連符に対応していない（結構痛い）  
・パターンを再生成した時に音楽の再生を止めてしまう（シームレスに変わればもっと良い）  
・スマホだと結構見づらい  
・Googleアカウントでしかログイン対応してない

## :airplane_small: まとめ
今後は上の課題を解決したり、一回パターンが演奏された毎に別のパターンが生成されて無限に人間とドラムバトルが出来たりようになると面白いと思っているのでいつかやりたいですね。  
    
類似のサービスはほぼ無かったか、あっても少し不便なものでした。

個人開発をするときは、***「自分以外誰も使わなかったとしても自分は使いたい」***と思えるようなものを作れれば良いと思います。

そういう意味では今回は成功です！
JavaScript でスマホのバイブを鳴らす

OSやブラウザによって鳴ったり鳴らなかったり、でした。

window.navigator.*vibrate の引数の配列は、奇数番目が鳴らす時間、偶数番目が停止時間。
window.navigator.vibrate([200,200,200,200,200]); →ブルブルブル
window.navigator.mozVibrate([200,200,200]); →ブルブル
window.navigator.webkitVibrate([200]); →ブル
と、鳴らす回数を変えて、どの行で鳴っているか判断するつもり。

・Android(Xperia) + Chrome ではブルブルブルと3回鳴った。
・Android(Xperia) + FireFox でもブルブルブルと3回鳴った。
・Android(Xperia) + Opera でもブルブルブルと3回鳴った。
・Androidタブレット(Asus ZenPad) + Chrome では無反応。
・iOS + Chrome では「sorry (T-T)」。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="initial-scale=1.0" />
    <title>スマホバイブ</title>
    <script>
      window.addEventListener("load", function(){
        document.getElementById("vibrate").addEventListener("click", function(){
          if(window.navigator.vibrate){
            window.navigator.vibrate([200,200,200,200,200]);
          }else if(window.navigator.mozVibrate){
            window.navigator.mozVibrate([200,200,200]);
          }else if(window.navigator.webkitVibrate){
            window.navigator.webkitVibrate([200]);
          }else{
            alert("sorry (T-T)");
          }
        }, true);
      }, true);
    </script>
  </head>
   
  <body>
    <form>
      <input type="button" id="vibrate" value="ぶるぶる">
    </form>
  </body>
</html>

```
[Flutter] iOS で WebView の Scrollbar の位置がずれる問題を修正する

# Flutter で Web ページを表示する

[webview_flutter](https://pub.dev/packages/webview_flutter) を使いますが iOS デバイスで表示すると Scrollbar の位置が変なところに出るという報告があります。

https://github.com/flutter/flutter/issues/41592

普通に WebView を表示すると、

```
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: WebView(
            initialUrl: "https://www.google.com/",
            javascriptMode: JavascriptMode.unrestricted,
          )
       );
  }
```

![test2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27210/b0adcb0a-abef-89e3-8fc5-4b82160f9692.gif)

確かに位置がずれます。

スレッドをみてみたら「`ClipRect` で包むととりあえず回避できる」とコメントがあったので試してみました。

```
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: ClipRect(
          child: WebView(
            initialUrl: "https://www.google.com/",
            javascriptMode: JavascriptMode.unrestricted,
          ),
        ));
  }
```
![test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27210/13a80a20-a01b-bae4-9a0d-a861007f896d.gif)

確かに直ってますね。

元の原因を追ってはいないのですが WebView を使う場合はとりあえずこの方法で回避できそうです。
JavaScriptの非同期処理を触ってみよう

今日は非同期処理について復習をしたので、まとめてみることにします！
通常上から下へ処理が実行されるのが、プログラミングのルールですが、意図的に順番を変えたり、実行を遅延させることが出来、それらを総称して**「非同期処理」**と言います！

利用するケースの一例は下記の通りです。
・ネットワークを経由したリクエスト全般
・意図的に遅延させた処理
・ファイルの読み込みや書き込み

**複数の処理を同時並行的に行えることが最大のメリット**です！

簡単な例を以て実験してみましょう。

```js:非同期処理とは
console.log("最初の処理");
function callback() {
  console.log("一番最後の処理");
}
setTimeout(callback, 3 * 1000);
//3秒後に関数callbacl()を呼び出す処理
console.log("次の処理");

//結果は下記になります。
//最初の処理
//次の処理
//一番最後の処理
```
以上のように、本来上から下へ行われるはずのプログラムの処理の順番を変えることが出来ました！

####ちなみに処理を遅らせるときによく使う文法はこちら
・**setTimeout** →　引数で指定した時間後に一度だけ実行。
・**setInterval** →　因数で指定した間隔で、処理を繰り返し実行する。繰り返しを止めるときはclearIntervalを使用。

```js:setIntervalの例
let count = 0;
function timeCount() {
  count++;
  console.log(count);
}

let sum = setInterval(function() {
  timeCount();
  if (count === 10) {
    // 10になったら処理をストップする。
    clearInterval(sum);
  }
}, 1 * 1000); //1秒ごとに数字をカウント。

// 結果
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10

```

##プロミスを使ってみよう
**Promise**とは非同期処理をシンプルに記述する方法です。（階層と処理が複雑になっていくいわゆるコールバック地獄を防ぐことが可能）
先ず新しいPromiseのインスタンスを生成し、関数呼び出しの際に**thenメゾット**を用いることで処理を分岐させたり、処理の終了を指定することが出来ます。

```js:Promiseの例
function eatApple(apple) {
  return new Promise(function(onFulfilled, onRejected) {
    //成功（onFulfilled）と失敗（onRejected）で処理を分ける
    for (let i = apple; i >= 0; i--) {
      setTimeout(function() {
        //setTimeoutをここで利用。時間差を生み出します。
        if (i > 0) console.log(i);
        else onFulfilled("お腹いっぱい！");
      }, (apple - i) * 1000); //処理する間隔の時間を指定
    }
  });
}
eatApple(5).then(
  function() {
    //成功(onFulfilled)した時の処理
    console.log("ごちそうさまでした！");
  },
  function(err) {
    //失敗(onRejected)した時の処理
    console.log("もう食えんわ・・・");
  }
);
//結果 1秒ごとに表示されます
// 5
// 4
// 3
// 2
// 1
// ごちそうさまでした!
```

##async/awaitを使ってみよう
非常に便利なPromiseですが、ES2017以降さらに便利にさらに短く書くことが出来ます。
**async**　→　関数の前に付けることで、必ずPromiseを返すようになる。
**await**　→　async関数の中でのみ実行。thenメソットのような働きをする。


```js:async/awaitの例
async function eatApple(apple) {
  await new Promise((onFulfilled, onRejected) => {
    //成功（onFulfilled）と失敗（onRejected）で処理を分ける
    for (let i = apple; i >= 0; i--) {
      setTimeout(function() {
        //setTimeoutをここで利用。時間差を生み出します。
        if (i > 0) console.log(i);
        else onFulfilled("お腹いっぱい！");
      }, (apple - i) * 1000); //処理する間隔の時間を指定
    }
  });
  //awaitで囲んだnew Promise内の処理が完了したら実行
  try {
    console.log("ごちそうさまでした！");
  } catch {
    console.log("もう食えんわ・・・");
  }
}
//async関数を呼び出し
eatApple(5);

//結果 1秒ごとに表示されます
// 5
// 4
// 3
// 2
// 1
// ごちそうさまでした!
```


以上が非同期処理のまとめでした。

どんどん書いて慣れていきたいと思います！
それでは、また。
左寄せのまま中央寄せにするやつに終止符を打つ[fit-content]

左寄せのまま中央寄せにしたいやつよくあるよね

だいたいは入れ子にして、外をcenterにして中をleftにすることが多いと思う


でもあれいろいろダサイんですよね　htmlが複雑化してくるに従ってなんかいろいろ面倒なことになる、text-align が要素以下に全部影響したりとか　幅を指定したいときとか可変だったりとか　入れ子なのもださいし　とにかくいろいろ面倒になる

そこでこう

```html
<style>
p {
  margin: 0 auto;
  width: fit-content;
}
</style>
<p>案内文とか長ったらしくなったとき途中で改行したい、<br>
文中は左寄せしたいけど<br>
全体をセンターリングしたい</p>
```

![css_left_fenter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38400/568d2f0c-bfab-2c52-44f8-4b02a16b3afc.png)

なんかこの見慣れない fit-content とかいうやつは、widthをいいかんじにしてくれる。

ブロックレベル要素はデフォでwidth:100%なので色々困ってしまうわけだけど、この見慣れない fit-content とかいうやつがいいかんじにしてくれるので、伝家の宝刀 margin:0 auto; が使えるようになる。

かくしてネストなしで左寄せの中央寄せを実現できた！　やったね！

ところでこの fit-content とかいう見慣れないやつ、引数を与えることで、なんかいろいろなものをいいかんじにしてくれるらしい。くわしくは適当にぐぐって↓のような記事をよんでくれ

https://developer.mozilla.org/ja/docs/Web/CSS/fit-content
MT5のヒストリカルデータで直面した問題



#M1データでバックテストしようとしたらエラー続出
操作ログのメッセージごとの対処法。
エンジニアのみんな、もっと対処法残していこうぜ。
調べても見つからなかったから自分で地道に調べたぜ。

| メッセージ | 原因|
|----|----|
| corrupt history detected | スプレッドがマイナス |
| invalid tick after extend | スプレッド低すぎ（4ポイント以下） |
| wrong generated bid price| #VALUEが入ってる（安値で確認）|

#FXCMの[TickDataDownloader](https://www.fxcmapps.com/apps/tick-data-downloader/)を買えない問題

> この問題はすでに古く、２０１９年１１月２５日の週にはなにか別の問題が更に出てきています。Webサイトそのものに問題があると思われるため、以下のものも無視できるかもしれません。

国に日本を指定してアカウント作ろうとするとダメ。
住所を海外に指定すればアカウント自体は作れる。
海外と言っても、日本と同じように取引できない国もあるっぽい（韓国とか）

ただ、日本のクレジットカードじゃ払えない。
ついでにVISAカードでないとダメ。
![payment.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447423/ae65ca36-89f1-9879-4424-81dabddd281b.jpeg)
[GCP]Cloud FunctionsからプライベートIPアドレスを持つCloud SQLへのアクセス方法

# はじめに
Cloud FunctionsからプライベートIPアドレスを持つCloud SQLへのアクセス方法を記載しています。

**手順**
1. VPCネットワークの作成
2. ファイアウォールルールの作成
3. Cloud SQLの作成
4. Serverless VPC Access コネクタの作成
5. Cloud Functions サービス アカウントに適切な権限を付与
6. コネクタを使用するように関数を構成（デプロイ）

**手順1〜3について**
以下の記事にまとめております。
[GCP]プライベートIPアドレスを持つCloud SQL(MySQL)作成方法と、VPCネットワーク割り当て方法
https://qiita.com/hanzawak/items/84ad707ca9596eb98bcc

**手順4〜6について**
本記事にまとめています。
なお以下のサイトを参考に作成しております。
https://cloud.google.com/functions/docs/connecting-vpc?hl=ja

# 手順
## Serverless VPC Access コネクタの作成
### Serverless VPC Access API を有効化

```shell
gcloud services enable vpcaccess.googleapis.com
```

### コネクタを作成

```shell
gcloud beta compute networks vpc-access connectors create CONNECTOR_NAME \
--network VPC_NETWORK \
--region REGION \
--range IP_RANGE
```

|入力値|内容|
|:-----------------|:------------------|
|CONNECTOR_NAME|コネクタの名前。なんでも良いです|
|VPC_NETWORK|作成済みのVPCネットワーク名|
|REGION|Cloud FunctionsとCloud SQLが配置されているリージョン|
|IP_RANGE|未使用の CIDR /28 IP 範囲。VPC ネットワーク内の既存の IP アドレス予約と重複してはならないたとえば`10.1.0.0/28`といったように指定する|

Cloud Functionsの配置先リージョンの指定は、デプロイ時に`--region asia-northeast1`のようにフラグを追加するだけです。

### コネクタの状態を確認

```shell
gcloud beta compute networks vpc-access connectors describe CONNECTOR_NAME --region REGION
```

出力に`state: READY`が含まれていたらOKです。

## Cloud Functions サービス アカウントに適切な権限を付与
### プロジェクト番号の確認

```shell
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
```

### Cloud Functions サービス エージェントにviewerの役割を付与

```shell
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:service-PROJECT_NUM@gcf-admin-robot.iam.gserviceaccount.com \
--role=roles/viewer
```

### Cloud Functions サービス エージェントに compute.networkUser の役割を付与

```shell
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:service-PROJECT_NUM@gcf-admin-robot.iam.gserviceaccount.com \
--role=roles/compute.networkUser
```

## コネクタを使用するように関数を構成（デプロイ）
### 関数をデプロイ

```shell
gcloud beta functions deploy FUNCTION_NAME \
--vpc-connector projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME \
FLAGS...
```

FLAGS... は、関数のデプロイ時に渡す他のフラグです。
これでCloud FunctionsからCloud SQLへ通信できるはずです。

# 備考
Stackdriverのログで以下のようなものが出力されている場合は、Cloud FunctionsとCloud SQLの通信が取れていないものと思われます。
本記事の内容を実施しても以下のログが出力される場合は、以下を確認してください。

* Cloud FunctionsとCloud SQLのリージョンが同じであるか
* Cloud FunctionsとCloud SQLはVPCネットワークに追加しているか


```shell
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
```

```shell
Aborted connection 79914 to db: 'unconnected' user: 'root' host: 'localhost' (Got an error reading communication packets)" 
```
Macの画面切り替え操作用ショートカット（備忘録）

# 前段
運用作業等で手動でブラウザを操作する場合に楽になるショートカットを備忘録＆共有用に残そうかと思います。
マウスポインタを使っての操作は目視しやすくて安心しますが、やっぱりキーボードから手を離さないで色々できるのは楽ですね。

前提として、Mac環境の利用で利用するブラウザはChromeとします。
また、Macでは、各キーを下記のように表記するようですが、記号とか書かれてすぐにキー結びつかないと思うので、名称（command等）を使います。

|名称  |別表記  |記号  |読み方  |
|---|---|---|---|
|command  |cmd  |⌘  |  コマンド|
|shift  | |⇧  |  シフト|
|option  |alt  |⌥  |  オプション|
|control  |ctrl  |⌃  |  コントロール|
|caps lock  | |⇪  |  キャプスロック|
|fn  | | |  ファンクション|


# Mac操作
Mac自体のショートカットの中で画面切り替え等によく使うのが下記です。

### 操作スペース切り替え
右選択：```control``` + ```→```
左選択：```control``` + ```←```

![movie_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/c9c8acc7-a5c8-8e33-ad77-ba73aab39c30.gif)


### アプリ切り替え
次選択：```command``` + ```tab```
前選択：```command``` + ```shift``` + ```tab```

![movie_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/03cbe589-8a8b-663a-71f0-0c83f55ea81c.gif)


# Chrome操作
Google Chromeを用いて画面操作をしたいときに使えるショートカットが下記です。

### 1ページ分画面スクロール
下スクロール：```option``` + ```↓```
上スクロール：```option``` + ```↑```

![movie_4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/9d2709d3-7cbc-460e-be8d-adce40c9092b.gif)


### タブ切り替え
右選択：```option``` + ```command``` + ```→```
左選択：```option``` + ```command``` + ```←```

![movie_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/d8fa88bc-7a4f-6529-e138-707e0b6eea7f.gif)


### アドレスバーを選択
```command``` + ```L```

![movie_5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/b5cfbfa2-83ae-e6f2-f126-63827e1de276.gif)


### カーソルを指定

次選択：```tab```
前選択：```shift``` + ```tab```

![movie_6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/385b0f97-3f8d-4884-d1af-58ed83c1139b.gif)


### タブで開く
リンクにカーソルを当てて
```command``` + ```return```

またはマウスポインタを利用して
```command``` + ```クリック```

![movie_7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/a906772e-a6f7-73e4-028e-77818b0371e8.gif)

### タブを閉じる
```command``` + ```W```

![movie_8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/3e720f0d-673d-22f5-8f85-c595c8c42a63.gif)

# むすび
本当はもう少しプログラムのこととか技術的なこと書こうかと思ってたんですけど、今回は備忘録的な感じで。

ショートカット楽っすね。
加えてコマンドラインも結構使う人はiTerm2を入れてショートカットで切り替えできるようにしておくと幸せになりますので是非に。
#Rails の validation で model のレコード・キーに関連しないエラーメッセージを自由に設定する

`:base` にエラーを追加すれば良さげ。


```rb
class User < ApplicationRecord
  validate :heart

    def heart
      if heart.evil?
        errors.add :base, 'Be gentle'
      end
    end
end

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【速報】Raspberry Pi 4 Model B の国内発売は 2019/11/26(火) から

# この記事は？
タイトルのとおりです

#本題
RSコンポーネント（ラズパイの日本輸入代理店）のツイッターに以下のように書かれておりました。
https://twitter.com/RSJapanMK/status/1197011224858247168
![RSコンポーネンツ　-ET展出展：A-42-さんはTwitterを使っています- 「【特報】ラズパイ4 ET-IoT展 で展示してます！ https---t-co-QIEyx14c91」 - Twitter 2019-11-20 15-18-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169018/471f70e6-916e-d8df-c37c-3bdc649ef805.png)
(写真は画面キャプチャ)

ということで、wktk(古っw)しながら 11/26 を待ちましょう。

#おわりに
内容が無い記事でごめんなさい。
指定した文字列（拡張子）から後の文字列を削除するPython版（PHPからPython）

#はじめに
PHPで記述したサーバのプログラムをPythonで作ったらどうなるか、気になる部分から開始しようと前の日に書いた機能のPython版をと調べだしたら、あまりも簡単でしたがメモを残します。少しでもPythonを書いている方には簡単過ぎる話かもしれませんが、PHPをPythonに移行する場合はこの程度から開始した方が気持ちが楽になります。
######まず、WEBのリンクを特定の文字列で分割

``` 01.py
string = "http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn.pdf?productId=SJ-D23D&_ga=2.1612.1531209133-1752366186.1522914385"
# 文字列の位置を検索
s = string.find('.pdf')
print (s)
# 57 が返って来ます
# ここで少し実験。
s = string.find('doc')
# 44 が返って来ます。
s = string.find('.doc')
# -1 が返って来ます。特殊文字を識別してくれます。（この程度で感動）
```
######少し調べて使えそうな関数 split() を発見。やってみましょう。
正直言って、簡単過ぎます（笑）

``` 02.py
string = "http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn.pdf?productId=SJ-D23D&_ga=2.1612.1531209133-1752366186.1522914385"
print (string.split('.pdf'))
# 以下が返って来ます。これは .pdf で分けた左右なんですね。
# ['http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn', '?productId=SJ-D23D&_ga=2.1612.1531209133-1752366186.1522914385']
print (string.split('.pdf')[0])
# http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn これではぼ欲しい文字列になります。
string = string.split('.pdf')[0] + '.pdf'
print (string)
# http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn.pdf これだけで済みます。
```
######次条件で分岐ですが、特殊文字の挙動は find() で問題ないので楽ですね。
実にシンプルに書けました。

``` 03.py
string = "http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn.pdf?productId=SJ-D23D&_ga=2.1612.1531209133-1752366186.1522914385"
if string.find('.docx') > 0:
	    string = string.split('.docx')[0] + '.docx'
elif string.find('.doc') > 0:
	    string = string.split('.doc')[0] + '.doc'
elif string.find('.xlsx') > 0:
	    string = string.split('.xlsx')[0] + '.xlsx'
elif string.find('.xls') > 0:
	    string = string.split('.xls')[0] + '.xls'
elif string.find('.pptx') > 0:
	    string = string.split('.pptx')[0] + '.pptx'
elif string.find('.ppt') > 0:
	    string = string.split('.ppt')[0] + '.ppt'
elif string.find('.pdf') > 0:
	    string = string.split('.pdf')[0] + '.pdf'
print (string)
# http://www.sharp.co.jp/support/refrigerator/doc/sjd23d_mn.pdf 問題なく返って来ます。
```
PHPでは少し悩んだ事がこれだけで出来てしまいます。Pythonの人気はこの手軽さでしょう。最近の方はあまりご存知無いと思いますが、30年程前に流行した「xBase言語」とPyhtonは似ていると感じ出しています。PHPからPythonの移行は一時期コンバートのサイトがあったようですが、無いようですので、自分の為に移行のメモを続けて書こうかと思っています。
IntelliJでGitHubのSSHキーのパスワードを定期的に求められた時の対処法

## 起きた現象
IntelliJを使用していると何十分かおきに下の画像が出てきて、GitHubのSSHキーのパスワードを求められました。

![スクリーンショット 2019-11-18 19.20.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298182/51b8f39d-3317-d3d7-6e8c-eb9c0139188a.png)

## 対処法
環境設定→その他の設定→Git ToolBox Project
を開いてください。

Autofetchにチェックマークがついています。
これをチェックしていると指定した分数おきにfetchしようとするため、パスワードを求められていました。
このチェックを外し、適用させれば定期的にGitHubのSSHキーのパスワードを求められることはなくなります！

![スクリーンショット 2019-11-18 19.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298182/00ddb3aa-a1d9-972b-b6f6-4cb7b8554801.png)
CVXPYを使ってみたという個人的なメモ書き

CVXPYとは？
---
CVXPYとは線形計画問題を解くプログラムということらしい。
macではpipでインストールできる
```terminal
pip install cvxpy
```
解きたい問題は以下の最適化問題を例に考える
---
線形計画問題
Maximize 70x1 + 30x2
subject to 5x1 + 2x2 ≤ 80,
2x1 + 3x2 ≤ 40,
3x1 + 7x2 ≤ 70,
x1≥0, x2≥0 
___
これをコード化すると以下になる

```python:cvxpy.py
import cvxpy as cp
x1, x2 = cp.Variable(), cp.Variable()
obj = cp.Maximize( (70 * x1) + (30 * x2) )
cons = [(5 * x1) + (2 * x2) <= 80,
               (2 * x1) + (3 * x2) <= 40,
               (3 * x1) + (7 * x2) <= 70,
                x1 >= 0,
                x2 >= 0]
P = cp.Problem(obj, cons)
P.solve(verbose=True)
print("x1 = ", x1.value)
print("x2 = ", x2.value)
```

実行結果
---
```
-----------------------------------------------------------------
           OSQP v0.6.0  -  Operator Splitting QP Solver
              (c) Bartolomeo Stellato,  Goran Banjac
        University of Oxford  -  Stanford University 2019
-----------------------------------------------------------------
problem:  variables n = 2, constraints m = 5
          nnz(P) + nnz(A) = 8
settings: linear system solver = qdldl,
          eps_abs = 1.0e-05, eps_rel = 1.0e-05,
          eps_prim_inf = 1.0e-04, eps_dual_inf = 1.0e-04,
          rho = 1.00e-01 (adaptive),
          sigma = 1.00e-06, alpha = 1.60, max_iter = 10000
          check_termination: on (interval 25),
          scaling: on, scaled_termination: off
          warm start: on, polish: on, time_limit: off

iter   objective    pri res    dua res    rho        time
   1  -1.8391e+02   5.70e-01   7.00e+01   1.00e-01   1.43e-04s
 200  -1.1273e+03   6.31e-04   6.57e-04   2.69e-02   5.30e-04s
plsh  -1.1273e+03   0.00e+00   3.57e-13   --------   8.38e-04s

status:               solved
solution polish:      successful
number of iterations: 200
optimal objective:    -1127.2727
run time:             8.38e-04s
optimal rho estimate: 2.73e-02

x1 =  14.545454545454547
x2 =  3.6363636363636362
```
解が出た。

まとめ
---
記述はめんどいけど線形計画問題を一発で解いてくれるのは嬉しいね。
(Qiitaの練習としてこの記事を書いています)
Windows7で拡張子(.exe)とアプリケーションの紐づけを誤って変更してしまったので修復した話。

とてもしんどい、、、、

# 事象
タイトルの通り、.exeファイルを開く際に紐づけるアプリケーションを誤って「VSCode」に変えてしまった。
そのせいで、.exe系のファイルが全て使えなくなってしまった。

- 原因調査するために「chrome.exe」を開こうとすると、VSCodeが立ち上がる
- コマンドプロンプトから設定変更するために「cmd.exe」を開こうとすると、VSCodeが立ち上がる

かなしい、、、、、

# やった事

## 1. 既定のプログラムから変更

以下の手順を参考に「既定のプログラム」から変更を試みる。

https://121ware.com/qasearch/1007/app/servlet/relatedqa?QID=012111

結果として、拡張子「exe」はこの機能からだと変更ができなかった。


## 2. assocコマンドで紐づけを変更

以下の手順を参考に「assocコマンド」を使って変更を試みる。

https://answers.microsoft.com/ja-jp/windows/forum/windows_xp-windows_programs/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%8c/a036900d-911d-4262-bb1a-27fa9440d63a?messageId=102c709d-1883-4abc-905e-5ad569493029

結果として、事象にも書いた通りコマンドプロンプトすら使えないので変更できなかった。

幸いにもVSCodeは使用できるので、VSCodeのターミナルから変更を試みたが、以下のエラーとなり変更できなかった。

```cmd
> assoc .exe=exefile
アクセスが拒否されました。
処理中にエラーが発生しました: .exe
```


## 3. レジストリから紐づけを変更(失敗パターン)

以下の手順を参考に「regedit」を使って変更を試みる。

https://www.pasoble.jp/windows/7/08843.html

結果として、「regedit」も実体は「regedit.exe」なので使う事ができず、変更できなかった。


## 4. レジストリから紐づけを変更(成功パターン)


以下の手順を参考にレジストリを書き換えてみる。

https://support.microsoft.com/ja-jp/help/950505/when-you-run-an-exe-file-on-a-windows-xp-windows-vista-or-windows-7-ba

結果として、**一部手順を修正する事で上手くいった！！！！！！！！！！！！！！！！！！！**

- コマンドプロンプトから「notepad」を起動する手順になっているが、コマンドプロンプトが使えない
- 幸いにもVSCodeは使えるので、VSCodeを起動し、以下のファイルを作成

```reg:Exe.reg


Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\OpenWithList]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\OpenWithProgids]
"exefile"=hex(0):
```

- 「Exe.reg」をダブルクリックで実行したが、「指定されたファイルはレジストリスクリプトではありません。レジストリエディタの中でインポートできるのは、バイナリレジストリファイルだけです。」というエラーが表示され実行できない
- ファイルの先頭に**空行**がある事が原因と判明したため、「Exe.reg」を以下に修正

```reg:Exe.reg
Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\OpenWithList]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\OpenWithProgids]
"exefile"=hex(0):
```
- 再度実行すると正常終了したので、ログオフ→ログインして、exeが使える事を確認


# まとめ

Windows7は2020年1月にサポートが切れるというのに、今更こんなハマり方をしてしまった、、、

みなさん、Windows7からWindows10に切り替えましょう、、、、、、、。
[ Android ]　ダイアログ

今回はAndroidでのダイアログの実装方法について記す。

##ダイアログとは
例えばエラーが発生したときに以下のようなものが表示されると思う。
 ![スクリーンショット (156).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/a32e43a6-3ba2-992f-b405-ca2241a6ebf1.png)
これがダイアログである。

##実装方法
上記の例で紹介したダイアログの実装方法は以下のとおりである。
~~~java
new AlertDialog.Builder(this)
        .setTitle(null)
        .setMessage("予期せぬエラーが発生しました。タイトルに戻ります。")
        .setPositiveButton("OK", null)
        .show();
~~~

setTitleはnullにしているが、タイトルを付けたい場合、文字列を入れればよい。
setTitle(“通信エラー”);とすると以下の通りになる。
 ![スクリーンショット (158).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/0265e6b6-5461-24e8-26e5-a5a619dba4c9.png)


上記ではsetPositiveButtonのみであるが、ほかにも作成できる。例えば次の実装をしてみる。

~~~java
new AlertDialog.Builder(this)
        .setTitle("通信エラー")
        .setMessage("エラーが発生しました。タイトルに戻ります。")
        .setPositiveButton("OK", null)
        .setNeutralButton("later",null)
        .setNegativeButton("NO", null)
        .show();
~~~

すると以下の通りになる。
![スクリーンショット (159).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/ffed6426-a49d-c6da-3ecb-b64ad79bd650.png)
 

##まとめ
ダイアログの実装方法については以下のサイトがとても参考になるので、是非参考にして頂きたい。
https://qiita.com/suzukihr/items/8973527ebb8bb35f6bb8
インデックスに登録されない-search console

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475525/23c3242e-0c6b-e5f4-442d-477c83fe2563.png)

事象：
サブドメインのホームページを公開したが
何度もインデックス登録リクエストに失敗する


原因：
FTPにrobots.txtファイルを置いてなかった

改善：
robots.txtファイルをアップロード
中身は
User-agent: *
Disallow:
のみ記述。

再びインデックス登録リクエストを送ると
画像認証→登録リクエストを送信しました　に。

５分後
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475525/99b7cb6c-26e9-d86b-ec15-f98f843e7663.png)

結果が変わりました。

無事インデックス完了です

感想：
robots.txtだいじ！！！

参考https://www.allegro-inc.com/seo/robots-txt-setting
curlコマンドでBearer認証のトークンを送る方法

curlコマンドでBearer認証のトークンを送る時のメモ

##GET
```console
curl -H GET 'http://localhost:3000/XXXX/XXXX?name=hello&id=100' -H 'Content-Type:application/json;charset=utf-8' -H 'Authorization: Bearer XXXX' | jq .
```

#POST
```console
curl -H POST 'http://localhost:3000/XXXX/XXXX' -H 'Content-Type: application/json;charset=utf-8' -d '{"name":"hello", "id":"100"}' -H 'Authorization: Bearer XXXX' | jq .
```