OmniAICreator/Qiita-1.07M huggingface dataset:
初心者によるプログラミング学習ログ 204日目

#100日チャレンジの204日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

204日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>204日目<br><br>udemyでwebサイトコーディング<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1213568934856687616?ref_src=twsrc%5Etfw">January 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
styled componentsのcss prop

## 概要
[styled components](https://github.com/styled-components/styled-components)の[css prop](https://www.styled-components.com/docs/api#css-prop)がv4から使えます。

今までこのようにちょっとしたstyleの変更をするのにcomponentを作っていたのが

```react
import styled from 'styled-components';

<StyledDiv />

const StyledButton = styled(Button)`
  padding: 0.5em 1em;
`
```

`css prop`を使うとこのように書くことができるようになります。

```react
<Button
  css="padding: 0.5em 1em;"
/>
```

importすら必要ありません。

### css propの仕組み
なぜかというと、以下のようにcss propが含まれていた場合に、

```react
<Button
  css="padding: 0.5em 1em;"
/>
```

[babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components)が以下のように変換しているからです

```react
import styled from 'styled-components';

const StyledButton = styled(Button)`
  padding: 0.5em 1em;
`

<StyledDiv />
```

そのため、基本的にstyled componentsでできることはcss propsでもできるはずです。

## css propを使うためのセットアップ
`css prop`は上記で説明したようにbabel-plugin-styled-componentsの力によって動いているのでこれを入れないとエラーになってしまいます。

### babel-plugin-styled-componentsのインストール

```
npm install --save-dev babel-plugin-styled-components@latest
```

`.babelrc`のpluginsのところに`babel-plugin-styled-components`を記述します。

```json
/// .babelrc
{
    "plugins": ["babel-plugin-styled-components"]
}
```

#### TypeScriptの場合

JavaScriptの場合はbabel-plugin-styled-componentsのセットアップだけでよいのですが、2020年1月4日時点ではTypeScriptの場合css propを使うと以下のようなエラーがでてしまいます。

```
Property 'css' does not exist on type 'DetailedHTMLProps'
```

これに対応するにはこのようにTypeScriptの定義ファイルを用意してやる必要があります。

```typescript
/// styled.d.ts
import { CSSProp } from "styled-components";

...

declare module "react" {
  interface Attributes {
    css?: CSSProp;
  }
}
```

そのうちこちらの[PullRequest](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31245)がマージされればDefinitelyTyped側に反映されるのでエラーは出なくなると思われます。

## 参考にしたもの

- [Announcing native support for the css prop in styled-components 🎉](https://medium.com/styled-components/announcing-native-support-for-the-css-prop-in-styled-components-245ca5252feb)
- [styled-components issue 2528](https://github.com/styled-components/styled-components/issues/2528)
はじめてのGit奮闘記

**この記事はtipというより日記です。**

**背景**
PythonやらCの勉強をしていて、ぼいとぼちなんか作りたい気持ちになってくる。
しかし、完成図が見えない状況で何かを作りだすのはしんどそう。何か完成図を軽く見たい。
そうだ、オープンソースというものは、ソースを見れるらしい。素晴らしい。
調べていくと、どうやらGitを入れるとソースを見るのに便利だそうだ。

**この記事の結論**
GitHubは公式ドキュメントが充実している。日本語も。Gitで躓いたときはまずは公式を参照しよう。


**参照した記事と手順**
A:OSSのソースを読む手順とあると便利な機能
https://qiita.com/shitake4/items/ee99edc37b272e5cdee3
→次の記事に遷移する

B:今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説
https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000
→ssh の生成のところがどうやらうまく行かない。

C:GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~
https://qiita.com/shizuma/items/2b2f873a0034839e47ce
→できた！Bの記事では細かいカスタム設定をしていたが、それがブロック要因だったと思われる。細かいことはおいておいて、先に進む。Bの記事に戻る。
→cloneはできなかったが、なんとなくAに戻る。
→なんか良さげなOSSの部分をを探すことにする。Dの記事を発見。

D:C言語1000行以下で開発されたエディタ「Kilo」
https://news.mynavi.jp/article/20160720-a073/
→やっぱりclone できないので、cloneできないエラーを調べることに。

E：git clone 出来ない( ﾉД`)…おぉー！出来たー( ;∀;)!!!
https://qiita.com/tedkuma/items/3b539e79010a4808337c
→この記事からGitHubの公式ヘルプに飛んで、そこで解決。

F:GitHub に SSH で接続する
https://help.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh
→これで最初からやり直してcloneまでできた。なぜだ。。。。まぁここはおいておいて、Aに一度戻る。

clone できたはいいけど、どうやってソースコード見るのかわからない。
なんかしらないけど、VS codeでソースファイルを開いたら読めた！OK!
ColabolaboratoryでTensorBoardを使う

## TensorBoard extensionの読み込みなど

```
%load_ext tensorboard
import datetime
```

TensorBoardで使用するデータは`./logs/`に格納されます
logsディレクトリ不要なデータが無いように一度ディレクトリを削除します

```
!rm -rf ./logs/ 
```
Kerasにはcallbackと呼ばれるものが用意されており，Tensorboard用のlogを出力するときには、この仕組みを使用する。Callbackは決まったタイミングで呼ばれ、そのタイミングは、Tensorboard用のCallbackの場合は、学習の直前と毎epochの終了時に呼び出されlogが保存されます。

次の例ではlogファイルは`./logs/fit/`ディレクトリに作成(log_dir)

```
log_dir="logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
```

作成した`callback`は、`Model.fit()`関数の中に登録。これにより`logs/fit/`ディレクトリ内にログが保存される

```
model.fit(x=x_train, 
          y=y_train, 
          epochs=5, 
          validation_data=(x_test, y_test), 
          callbacks=[tensorboard_callback]) #作成したcallbackの指定
```

## TensorBoardの起動
```
%tensorboard --logdir logs/fit
```
toimage (from PIL.Image import fromarray as toimage)で出たエラーを解消する方法

```
for i in range(100):
  img = toimage(X_test[i])
  label = results[i].argmax()
  plt.subplot(10, 10, pos)
  plt.imshow(img)
  plt.axis('off')
  plt.title(cifar10_labels[label])
  pos += 1        
plt.show()
```
を実行してイメージをJupyter notebookに表示させようとしたら、以下のようなエラーが出た。

KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/PIL/Image.py in fromarray(obj, mode)
   2415             typekey = (1, 1) + shape[2:], arr['typestr']
-> 2416             mode, rawmode = _fromarray_typemap[typekey]
   2417         except KeyError:

KeyError: ((1, 1, 3), '<f4')

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
1 frames
/usr/local/lib/python3.6/dist-packages/PIL/Image.py in fromarray(obj, mode)
   2417         except KeyError:
   2418             # print(typekey)
-> 2419             raise TypeError("Cannot handle this data type")
   2420     else:
   2421         rawmode = mode

TypeError: Cannot handle this data type


コードを以下のように変えると問題が解決した。

```
for i in range(100):
  scale = 255.0 / np.max(X_test[i])
  img = toimage(np.uint8(X_test[i]*scale))
  label = results[i].argmax()
  plt.subplot(10, 10, pos)
  plt.imshow(img)
  plt.axis('off')
  plt.title(cifar10_labels[label])
  pos += 1        
plt.show()
```
Sambaで共有設定(Centos7)

当方がCentOS7で立ち上げたときの備忘録

###1.sambaのインストール

```
yum install samba samba-client samba-common -y
```

###2.共有フォルダの作成

```
mkdir /home/hoge
```

###3.sambaの設定ファイルの編集

```/etc/samba/smb.conf
# Global parameters
[global]
        dns proxy = No
        dos charset = CP932(文字化け防止)
        netbios name = CENTOS7(windowsで表示される名前)
        security = USER
        server string = Samba Server %v
        idmap config * : backend = tdb
        cups options = raw

[homes]
        browseable = No
        comment = Home Directories
        inherit acls = Yes
        read only = No
        valid users = %S %D%w%S

[share_samba] (最後に追加)
        guest ok = Yes
        guest only = Yes
        path = /home/share_samba(作成した共有フォルダ)
        read only = No
```

###4.共有フォルダのパーミッションの変更

```
sudo chmod -R 0777 /共有フォルダ
sudo chown -R nobody:nobody /共有フォルダ
```

###5.ファイアウォールの設定

```
sudo firewall-cmd --add-service=samba --permanent
sudo firewall-cmd --reload
```

###6.SELinuxの設定

```
setsebool -P samba_enable_home_dirs on
restorecon -R /共有フォルダ
```

###7.共有ユーザーをサーバー(Linux)側で作成

```
sudo useradd hoge
sudo passwd hoge

#Windows側のユーザー属性追加
sudo pdbedit -a -u hoge -f "hoge(任意)"
#パスワードはuseraddのときと同じやつ

#ユーザー作成の確認
sudo pdbedit -L
```

###8.sambaのサービスを再起動

```
sudo systemctl restart smb
sudo systemctl restart nmb

#samba起動を自動化
sudo systemctl enable smb
sudo systemctl enable nmb

###9.Windows側でアクセス

エクスプローラーで\\(鯖IP)\共有フォルダを検索
ユーザー名とパスワードを入力

###参考文献
https://www.rem-system.com/centos-samba/
初心者が classify_image.py を使おうとしてハマった話


IMAGENETの
https://github.com/tensorflow/models/blob/master/tutorials/image/imagenet/classify_image.py
を使おうとしてハマった話です。

# 環境
・ Ubuntu 18.04

# ハマったことと、 対応したこと

```
$ python classify_image.py
```

として、そのまま使おうとしても、

```
AttributeError: module 'tensorflow' has no attribute 'app'
```

のようなエラーが出て、使えませんでした。
私の環境では、tensorflow の バージョンが 2.0 だったので、以下を実施して、
一旦バージョンを下げました。

```
$ pip install --upgrade tensorflow==1.13.1
```

TensorFlow 1.10 では python 3.7 が使えないという話を見かけましたが、
TensorFlow 1.13.1 であれば、一応インストール出来ました。

```
$ python --version
Python 3.7.0
```

その後、実行し直してみると、以下のような出力結果が得られました。

```
giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89107)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00779)
lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00296)
custard apple (score = 0.00147)
earthstar (score = 0.00117)
```

# 参考にさせて頂いた URL 

https://qiita.com/FukuharaYohei/items/3bc6d83f0e24110534b2

https://book.mynavi.jp/manatee/detail/id=77514

https://pycarnival.com/tensorflow_python37/

https://qiita.com/supersaiakujin/items/50def6f33b79f9a61b18
WSL2内で立ち上げたサーバにWindows側からlocalhostで接続する

:::note warn
**2022-09-01現在、最新の WSL2 ではこのような設定は不要と思われます (多分)**
:::


[WSL2 では localhost でサーバを公開するのが簡単になった](https://devblogs.microsoft.com/commandline/whats-new-for-wsl-in-insiders-preview-build-18945/) らしいというので設定してみたメモ。

## 環境

* Windows10 Pro Insider Preview (バージョン: `2004`, OSビルド: `19536.1000`)
* WSL2(`Ubuntu-18.04`)
* Docker
    * Desktop `2.1.7.0(41536)` (Channel `edge`)
    * Engine `19.03.5`

## 手順

Windows 側に `c:\Users\<ユーザ名>\.wslconfig` というファイルを用意し以下のように記述する。

```ini:.wslconfig
localhostForwarding=True
```

以上

## 試してみる

Docker で nginx を起動

```
$ docker run --name hogehoge -p 8080:80 nginx
```

Windows 側から `http://localhost:8080` でアクセスして以下のように表示されたらOK

[![Image from Gyazo](https://i.gyazo.com/b1001402367ba325be262e4d4bc91f90.png)](https://gyazo.com/b1001402367ba325be262e4d4bc91f90)

# localhost につながらなくなる場合がある? (追記:2021.05.07) 

原因はよくわかっていないですが､ Windows のシャットダウンして起動し直した後､ localhost につながらなくなる現象が発生することがわかりました｡

その場合は｢再起動｣すると問題が解決します｡(｢シャットダウン｣の後電源ONではなく｢再起動｣であることに注意)

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8219/d145fe24-7a17-ed7d-bf71-cbb12004b027.png width=500>

ググると｢高速スタートアップ機能をオフにすれば良い｣的な記事が見つかったりしますが、機能をオフにするまでもなく｢再起動｣の操作では｢高速スタートアップ｣は行われないため｢再起動｣で問題を解消することができます｡

MSの公式アカウントも Tweet しているように Windows10 において｢再起動｣と｢シャットダウンからの起動し直し｣は異なる動作であり、トラブルシュートの手段として｢再起動｣を勧めています｡

https://twitter.com/MSHelpsJP/status/1030008766757044224?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1030008766757044224%7Ctwgr%5E%7Ctwcon%5Es1_c10&ref_url=https%3A%2F%2Fwww.itmedia.co.jp%2Fpcuser%2Farticles%2F1808%2F20%2Fnews095.html

この問題に関する Github Issue は以下のようですが､すでに close されているように見えます｡
スレッドを読みきれてなくて、この問題が根本解決したのかどうかパッチがリリースされるのかどうか読み取れていません｡

- [Local sites running in WSL2 not accessible in browser #5298](https://github.com/microsoft/WSL/issues/5298)

## 参考

* [What’s new for WSL in Insiders Preview Build 18945 | Windows Command Line](https://devblogs.microsoft.com/commandline/whats-new-for-wsl-in-insiders-preview-build-18945/)
* [WSL2のWEBサーバにlocalhostでアクセスできる新機能を設定する！｜かえるのほんだな](https://yukituna.com/2284/)
* [Local sites running in WSL2 not accessible in browser #5298](https://github.com/microsoft/WSL/issues/5298)
【Rails】Mongoidでembeds_manyの子要素の数を取得する

## 概要
RailsでMongoDBを使用する際、埋め込み型のリレーション（embeds_many）の子要素の数を取得する方法を記載します。

## サンプル例題
親要素はブログ記事、子要素はコメントとして、ブログ記事にコメントの配列を持たせるようなイメージになります。

```article.rb
class Article
  include Mongoid::Document
  field :_id, type: String
  field :title, type: String
  field :contents, type: String
  embeds_many :comments
end
```

```comment.rb
class Comment
  include Mongoid::Document
  field :user_id, type: String
  field :post_comment, type: String
  embedded_in :article
end
```

## 対応方法
対象のドキュメントについて、全子要素を取得して数をカウントする方法も考えられますが、今回は子要素の配列を取得せず、数のみを取得する方法を紹介します。
MongoDBのAggregation Pipelineの[$project (aggregation)](https://docs.mongodb.com/manual/reference/operator/aggregation/project/)を使って、データ取得を行います。Program QAの[mongoidを使用して、配列サイズを集計でカウントします](https://ja.programqa.com/question/44565933/)の記事を参考にしました。

## 実装サンプル

```sample.rb
# コレクションの取得
db = Mongoid::Clients.default
articleCollection= db[:article]
# aggregateの実行
articleCollection.aggregate([
  {
    "$project" => {
      _id: 1,
      title: 1,
      contents: 1,
      comments_count: {"$size": "$comments"}
    }
  }
]).to_a
```
ansibleのget_urlでCRF++とcabochaのtarballを取得する

### 動作したコード

```task/main.yml
- name: Download CRF++ from google drive
  get_url:
    url: "https://drive.google.com/uc?export=download&id={{ crf_file_id }}"
    dest: "{{ project_path }}/server/lib/CRF++-0.58.tar.gz"
    mode: u=r,g=r,o=r
- name: Download Cabocha from google drive
  get_url:
    url: "https://drive.google.com/uc?export=download&confirm=ABCD&id={{ cabocha_file_id }}"
    dest: "{{ project_path }}/server/lib/cabocha-0.69.tar.bz2"
    headers: "Cookie:'download_warning_16768239309833604394_0B4y35FiV1wh7SDd1Q1dUQkZQaUU=ABCD;'"
    mode: u=r,g=r,o=r
  # 以下のコードでも動作する
  # shell: |
    # curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id={{ cabocha_file_id }}" > /dev/null
    # CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"
    # curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id={{ cabocha_file_id }}" -o "{{ project_path }}/server/lib/cabocha-0.69.tar.bz2"

```

```vars.yml
project_path: /srv/http/myapp
crf_file_id: 0B4y35FiV1wh7QVR6VXJ5dWExSTQ
cabocha_file_id: 0B4y35FiV1wh7SDd1Q1dUQkZQaUU
```

### 怪しい箇所
cabochaのcookieのkey名がこれであっているのか怪しい

ファイルNumber_ファイルID => 16768239309833604394_0B4y35FiV1wh7SDd1Q1dUQkZQaUU
という命名規則に見えるが、このkeyの命名が保証されていないのでいつ壊れるのかわからない...

value自体はランダムに設定されているようでしたが、手元で指定してしまってもエラーにはならなかったのでABCDと適当な文字列を入れています(大きな問題はないはず)

※ cabochaのtarballを配布するミラーリングサイト他にないのかなぁ

### 参考

- [curlやwgetで公開済みGoogle Driveデータをダウンロードする - Qiita](https://qiita.com/namakemono/items/c963e75e0af3f7eed732)
- [get_url – Downloads files from HTTP, HTTPS, or FTP to node — Ansible Documentation](https://docs.ansible.com/ansible/latest/modules/get_url_module.html)
ビット演算による、与えられた文字列の中の全ての文字列（順序入れ替えなし）を出力するコード（Python）

ビット演算によって、与えられた文字列の中の全ての文字列を出力するコードです。Cで書いていましたが、日本語に対応させるため、pythonで書き直しました。

```alice.py
#!/usr/bin/python3

import sys
word=sys.argv[1]
K=1
N=len(word)
t=1

def nextset(x):
  smallest=x & -x
  ripple = x + smallest
  new_smallest = ripple & - ripple
  ones =((new_smallest // smallest) >>1)-1
  return ripple | ones

def printset(s):
  for i in range(N):
    if (s & 1):
      print( word[i] , end="")
    s=s>>1
  print("")

def conv(k):
  global t
  x= (1 << (k)) -1
  while True:
    if (x&~((1<<(N))-1)):
      break
    print(str(t)+" : ",end="")
    printset(x)
    x=nextset(x)
    t=t+1

t=1
for K in range(N):
  conv(K+1)
```

実行例

```
$ alice.py たんすいかぶつ
1 : た
2 : ん
3 : す
4 : い
5 : か
6 : ぶ
7 : つ
8 : たん
9 : たす
10 : んす
11 : たい
12 : んい
13 : すい
14 : たか
15 : んか
16 : すか
17 : いか
18 : たぶ
19 : んぶ
20 : すぶ
21 : いぶ
22 : かぶ
23 : たつ
24 : んつ
25 : すつ
26 : いつ
27 : かつ
28 : ぶつ
29 : たんす
30 : たんい
31 : たすい
32 : んすい
33 : たんか
34 : たすか
35 : んすか
36 : たいか
37 : んいか
38 : すいか
39 : たんぶ
40 : たすぶ
41 : んすぶ
42 : たいぶ
43 : んいぶ
44 : すいぶ
45 : たかぶ
46 : んかぶ
47 : すかぶ
48 : いかぶ
49 : たんつ
50 : たすつ
51 : んすつ
52 : たいつ
53 : んいつ
54 : すいつ
55 : たかつ
56 : んかつ
57 : すかつ
58 : いかつ
59 : たぶつ
60 : んぶつ
61 : すぶつ
62 : いぶつ
63 : かぶつ
64 : たんすい
65 : たんすか
66 : たんいか
67 : たすいか
68 : んすいか
69 : たんすぶ
70 : たんいぶ
71 : たすいぶ
72 : んすいぶ
73 : たんかぶ
74 : たすかぶ
75 : んすかぶ
76 : たいかぶ
77 : んいかぶ
78 : すいかぶ
79 : たんすつ
80 : たんいつ
81 : たすいつ
82 : んすいつ
83 : たんかつ
84 : たすかつ
85 : んすかつ
86 : たいかつ
87 : んいかつ
88 : すいかつ
89 : たんぶつ
90 : たすぶつ
91 : んすぶつ
92 : たいぶつ
93 : んいぶつ
94 : すいぶつ
95 : たかぶつ
96 : んかぶつ
97 : すかぶつ
98 : いかぶつ
99 : たんすいか
100 : たんすいぶ
101 : たんすかぶ
102 : たんいかぶ
103 : たすいかぶ
104 : んすいかぶ
105 : たんすいつ
106 : たんすかつ
107 : たんいかつ
108 : たすいかつ
109 : んすいかつ
110 : たんすぶつ
111 : たんいぶつ
112 : たすいぶつ
113 : んすいぶつ
114 : たんかぶつ
115 : たすかぶつ
116 : んすかぶつ
117 : たいかぶつ
118 : んいかぶつ
119 : すいかぶつ
120 : たんすいかぶ
121 : たんすいかつ
122 : たんすいぶつ
123 : たんすかぶつ
124 : たんいかぶつ
125 : たすいかぶつ
126 : んすいかぶつ
127 : たんすいかぶつ
$
```
docker上でjupyter-notebookを使用する方法

dockerコンテナ上でjupyter-notebookを起動させてローカルPCのブラウザで動かすための方法。

# 1. ポートの接続
コンテナ上のポートとローカルのポートを接続する。

```
docker run -p [ローカルのポート]:[コンテナのポート]
```
とすれば接続できる。

# 2. notebook起動時にオプションをつける
コンテナ上で`jupyter notebook`とコマンドしても

```
OSError: [Errno 99] Cannot assign requested address
```
と出る。
以下のようにipとallow-rootオプションをつければ解決。

```
jupyter notebook --ip=0.0.0.0 --allow-root
```

※もし、1.のポートの接続時のコンテナのポートがnotebookのデフォルト値の8888以外にした場合は以下のようにしてポートも設定する必要がある。

```
jupyter notebook --port [コンテナ側の接続ポート] --ip=0.0.0.0 --allow-root
```

# 3. ブラウザでnotebookにアクセス
ローカルPCのブラウザでコンテナで起動したnotebookにアクセスする。
ブラウザに下記URLを打ち込む。

```
localhost:[ローカル側の接続ポート]
```
するとJupyter Notebookの画面に遷移して`Password or token:`と入力が求められる。

入力するためのtokenはコンテナ上でnotebookを起動したときに以下のようなURLが出るのでそこから取得する。

```
    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://5217807fea51:8888/?token=601c330c097e59cd7b69dcaa6ea336218583a492e4684bde&token=601c330c097e59cd7b69dcaa6ea336218583a492e4684bde
```
上の場合、`601c330c097e59cd7b69dcaa6ea336218583a492e4684bde`を`Password or token:`に入力すればいつものnotebookの画面に遷移する。

# 4. notebookの設定を変更する（オプション）
notebook起動時に`--port`とか`--ip=0.0.0.0`とか`--allow-root`とかをいちいち打ち込むのが面倒くさい人用。
これらの設定をconfigに書き込んでおく。
まず下記コマンドでconfigファイルを作成。

```
jupyter notebook --generate-config
```

`/root/.jupyter/jupyter_notebook_config.py`にconfigファイルが作成されるので以下を書き加える。

```
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.port = [コンテナ側の接続ポート]
c.NotebookApp.token = ''
c.NotebookApp.allow_root = True
c.NotebookApp.open_browser = False
```
以後は`jupyter notebook`とコマンドするだけで良い。
CloudFormationのJSONにコメントを記述する

# TL;DR
- Metadata Attributeを使う
- 詳細は AWS DevOps Blog を参照
    - https://aws.amazon.com/jp/blogs/devops/adding-comments-inside-aws-cloudformation-templates/

# 書き方
AWS DevOps Blogのサンプルそのまま。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-metadata.html

```json
{
   "Description" : "This is a sample template.",
   "Resources" : {
      "Bucket98004" : {
         "Type" : "AWS::S3::Bucket",
         "Metadata" : {
            "Comment" : "ここにコメントを書く。",  
            "Version" : "1.2.1_1"
...

}
```

# 解説
AWS DevOps Blogに書いてあることの要約。

- CFn はすべてのResourceで`Metadata` attributeをサポートしている
- `Metadata` Attribute には任意のオブジェクトを含めることができる
    - ので、`Comment`といった独自オブジェクトを記載できるらしい
- とはいえ、`AWS::CloudFormation::Interface`といったオブジェクトもあるようなので、`AWS`で始まるオブジェクトは避けたほうが良さそう。

# 背景
AWS CloudFormationはJSONとYAMLの2形式で記述できるが、YAMLと違い、JSONにはコメントを記述することができない。

自分でゼロから書くのであればYAMLを使えばいいが、既存のCFnテンプレート、パラメータにはJSONで書かれたものが多い。

YAMLへ変換するとオリジナルのJSONが更新されたときに面倒なのでJSONのまま使いたいが、何が書いてあるのか分からなくなるのでコメントは追記したい。

バッドノウハウ(？)として、今後使われないと思われるKeyを使って
 `"Comment": "This is comment hogehoge."` のように書く手法があると思うけど、将来(?)CFnの予約語と衝突するリスクは避けたい。

CFnのJSONに安全にコメントを書けるような日本語記事が無かったので書いてみた。
スプレッド演算子について

大きなデータを扱ってみると配列の階層の深いところに必要なデータがあったりし、使いにくい場合があります。
スプレッド演算子を使うと、配列や配列ライクなオブジェクトを個々の値として展開することが出来ます。

## スプレッド演算子
```js
const arr = [1, 2, 3, 4, 5];
console.log(arr);

// スプレッド演算子
console.log(...arr);  //配列の値が展開されて表示されます
```


**やってみた** 
<img width="614" alt="スクリーンショット 2020-01-05 3.21.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/5d815fe8-52dd-e5d1-9b88-d1e2ee7e068c.png">


##　こんな時に便利
Reactからの観点からみるとpropsが増えれば増えるほどかなり面倒なので、スプレッド演算子を使います。
必要な値だけ渡すこともできるので、全てのデータを渡すよりエラーになる可能性も少なく便利です。
Windows .NET の OCR を使ってビルドするまでの手順 (2020年版)

何年か前にミクミンPのtweet https://twitter.com/ksasao/status/928643759822086144 によりWindows OCR (`Windows.Media.Ocr`) の存在を知り、今年になって突然思い出したので試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12150/fb9ec429-6a99-cb20-256b-b75b6ec75a19.png)

ビルドできるようになるまでに無用な手間が多かったので、それの記録です。コードは参考コードそのまま動かしただけなので、この記事内に独自の情報はありません。

# 手順概要
- .csproj ファイルに主導で TargetPlatformVersion を追加
- Windowsのアセンブリ情報がVisual Studioから参照できるように細工
- C#プロジェクトの参照設定で Windows → コア から WinRT 関係のアセンブリを参照
- 必要なdllを参照
- 非同期周りをどうにかするコードを用意
- (準備完了。あとはコードを書くだけ)

## 参考にした資料
- [1]ミクミンPのGist https://gist.github.com/ksasao/43879bfead8d4308290b95d84effa693
- [2]そこにあるリンク http://www.moonmile.net/blog/archives/8584
- [3]さらにその先 https://blog.xin9le.net/entry/2012/11/12/123231
- [4]dll周りの問題解決 https://kakusuke98.hatenablog.com/entry/2019/09/26/125207

# 手順詳細
## .csproj ファイルに主導で TargetPlatformVersion を追加
資料[2] より。
C#プロジェクトファイルをテキストエディタで開いて、それっぽい数値で追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12150/e81e1d1a-0653-9a5b-0338-7748e6ac8313.png)

## Windowsのアセンブリ情報がVisual Studioから参照できるように細工
Windows 10 の 1903 で起きた問題らしいので、いずれ解決されて不要な手順になりそう。
資料[4] ではコピーしているけど、重複するのも微妙なので手元では `system32/WinMetadata` へのシンボリックリンクを `SysWOW64/WinMetaqdata` として作成。

## C#プロジェクトの参照設定で Windows → コア から WinRT 関係のアセンブリを参照
ここまでの手順で参照できるようになっているはずなので、資料[2] そのままの手順でいけるはず。

## 必要なdllを参照
これも 資料[2] そのまま。参照マネージャーでなぜか「OK」の左にある「参照」ボタンから `System.Runtime.WindowsRuntime.dll` を探して選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12150/2cfd801c-4058-f584-e98e-41aeb30c9593.png)
`C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETCore/(.NETのバージョン)/System.Runtime.WindowsRuntime.dll` みたいな場所にあるはず。

## 非同期周りをどうにかするコードを用意
資料[3] を見ると `System.WindowsRuntimeSystemExtensions` がうまくやってくれそうなことを書いてあるけど、これはどうやって使うのか謎で検索しても全然情報がありません。資料[2] でも 「うまくいかないので自前で作る」 とあるので、そういうものなのでしょうか。資料[2] 「GetAwaiter メソッドを自作で拡張する」にある TaskEx クラスと同等のものを作りましょう。

これでようやく資料[1]のサンプルコード、 `await ocrEngine.RecognizeAsync(bitmap)` あたりがコンパイル、ビルドできるようになります。スタート地点です。
React PropsとStateとstoreの使い分けについて

Reactでコードを書いている中で、情報の管理をするPropsとStateをよく使っていますが、それ以外に**store**もあると知り調べてみました。


##PropsとState
ReactのコンポーネントではPropsとStateと呼ばれる値でUIの状態や情報を管理しています。

**Props** 
コンポーネント利用時に属性として設定できる値

**state** 
コンポーネントが持っている状態
stateはclass componentだと**setState**でデータを更新することができる。注意しなければいけないのは、Stateの値を更新するとコンポーネントのrender()メソッドが実行され再描画でされます。
(stateはcomponentだけが持つ値。)
他のcomponentに値をわたす必要がない、そのcomponentだけで利用する値に関してはstateを使って値の管理をする。

##store
storeはreduxが管理してる値です。アプリケーションの状態(state)を保持します。



##使い分け
app全体で管理したい値はstore管理、コンポーネント毎に管理したい値はprops or stateで管理する。
stateの値を呼び出したcomponentに渡して、その値をまた別のcomponentに渡してを続けること(バケツリレー)が不毛だからstoreが生まれて、バケツリレーしなくても値を取得できるようになりました。

参考
http://yucatio.hatenablog.com/entry/2018/09/21/225716
Unityオンラインマルチプレイゲームテストのための複数Unityエディタ起動

# 概要
PUN2を使ったオンラインマルチプレイゲームの学習をしていて、複数のUnityエディタ上での実行でちゃんとネットワーク上で同期がとれているか確認したくなった。そのやり方をまとめておく。

ざっくりいうと、
1. 開発中のプロジェクトディレクトリ(A)とは異なるパスにダミーのプロジェクトディレクトリ(B)を作成
2. ディレクトリ(A)配下の以下のディレクトリへのシンボリックリンクをディレクトリ(B)直下に用意
  - Assets
  - UnityPackageManager
  - ProjectSettings
3. プロジェクトA,BともUnityエディタで開いてやってそれぞれで再生ボタンを押す

1,2 についてはシェルスクリプト化すると以下のような感じ(Mac前提)。

```
#!/bin/sh
# --設定--
# 開発中のプロジェクトのパス
PROJECT_PATH_ORG=<開発中のプロジェクトのパス>
# ダミーのプロジェクトのパス
PROJECT_PATH=<ダミーのプロジェクトのパス>

# ダミーのプロジェクトディレクトリを作成
rm -rf $PROJECT_PATH
mkdir $PROJECT_PATH

# ProjectSettingsディレクトリ以下のシンボリックリンクを貼る
mkdir $PROJECT_PATH/ProjectSettings
ln -s $PROJECT_PATH_ORG/ProjectSettings/* $PROJECT_PATH/ProjectSettings/

# Assetsディレクトリ以下のシンボリックリンクを貼る
mkdir $PROJECT_PATH/Assets
ln -s $PROJECT_PATH_ORG/Assets/* $PROJECT_PATH/Assets/

# UnityPackageManagerディレクトリ以下のシンボリックリンクを貼る
mkdir $PROJECT_PATH/UnityPackageManager
ln -s $PROJECT_PATH_ORG/UnityPackageManager/* $PROJECT_PATH/UnityPackageManager/
```
上のシェルスクリプトでCUIからプロジェクトBをUnityエディタで開くところまでやっとくともっと便利かもしれない。下を参考にしていずれやろうかな。

- https://docs.unity3d.com/jp/460/Manual/CommandLineArguments.html

3.について同時に複数のプロジェクト開くには、UnityHub起動してからプロジェクト開けばOK。だけど上のシェルスクリプトでCUIからプロジェクトBをUnityエディタで開くところまでやっとくともっと楽かもしれない。下を参考にしていずれやろうかな。
- https://docs.unity3d.com/jp/460/Manual/CommandLineArguments.html

# 実際に試してみた
以下のスクリーンショットは、[PUN2で始めるオンラインゲーム開発入門【その１】](https://connect.unity.com/p/pun2deshi-meruonraingemukai-fa-ru-men-sono1)の動作を確認してみたときのやつ。

プロジェクトAでシーンを再生
![スクリーンショット 2020-01-05 2.42.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/1c5419e7-690d-e7bd-373e-c7c4e53e88c7.png)

プロジェクトBでシーンを再生
![スクリーンショット 2020-01-05 2.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/52c68656-6f5c-8650-2281-56c812752111.png)

プロジェクトAでシーンの再生を停止
![スクリーンショット 2020-01-05 2.47.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/7bdbde01-05e7-b557-605f-b2a2215ed57a.png)


ちゃんと同期取れてることがわかる。


# 余談
やっててあれ？ってなったのが、元のプロジェクトでいじってたシーンがシンボリックリンク貼ってる側のプロジェクトを開いたときにデフォルトで表示されていなかったこと。
これはシーンファイルをダブルクリックすればいいだけ。デフォルトで表示されるものと勘違いしてた。

![スクリーンショット 2020-01-05 2.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/32d78190-aa0c-d43f-8513-8cd42a023b49.png)




# 参考
http://tsubakit1.hateblo.jp/entry/2015/01/10/233000
http://reyloffice.blog.fc2.com/blog-entry-13.html
wikipediaガチャBotをつくってみた

## はじめに
ノンプログラマですが，自分でも何かつくってみたくてTwitterBotをつくりました．
初学者がBot作成する際のご参考になれば幸いです．

##できたもの
wikipediaに登録されている単語から，2つの単語をランダムに取得してTweetするBotです．
https://twitter.com/Sosaku_Tango
![スクリーンショット 2020-01-05 0.19.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310632/9ec00595-35e1-e74e-a40c-2bc69f5bf9d6.png)

##つくりかた
まず完成したコードがこちらです．

```python
import tweepy, random
import schedule
import time

# 取得した各keyを代入
CK=""
CS=""
AT=""
AS=""

# インスタンス作成
auth = tweepy.OAuthHandler(CK, CS)
auth.set_access_token(AT, AS)
api = tweepy.API(auth)

#ダウンロードしたwikipedia単語リストファイルから2つの単語をツイート
def bot():
    wiki_titles = open("jawiki-latest-all-titles-in-ns0.txt", "r")
    line = wiki_titles.readlines()
    random_word = random.sample(line, 1)
    first_word = ''.join(random_word)
    random_word = random.sample(line, 1)
    second_word = ''.join(random_word)

    api.update_status('1.' + first_word + '2.' + second_word + '\nで創作できますか？出来上がりを楽しみにしています. #創作単語 ')

#定期的な実行
def main():
    schedule.every().day.at("10:00").do(bot)
    while True:
        schedule.run_pending()
        time.sleep(1)
main()
```

1. Tweepyを使用したTwitterBotの基本的な作成方法は，こちらを参考にしました．
https://qiita.com/tsc343/items/e51f412480ea8bf5619a

2. Wikipediaの単語データ(.txt)はこちらからダウンロードしました．
https://dumps.wikimedia.org/jawiki/

3. txtファイルからランダムに行を抽出するコードはこちらを参考にしました．
http://tksmd.hatenablog.com/entry/20090122/p1

4. 定期的な自動実行はこちらを参考にしました．
https://qiita.com/Kai-Suzuki/items/0c5c0e5cbdb4075fe482

5. 完成です．お疲れ様でした．

##しょかん
最近まで手動で毎日実行していたのですが，忘れることがたびたびあったので自動実行のコードを入れました．
それを機にQiitaで初投稿してみた次第です．
フォローもいいねも0なので誰にも認識されていないのですが，興味があれば一度見てもらえると嬉しいです．
なにかお気付きの点があればコメントいただけると幸いです．
Microsoft Learn 35日目

2019年12月に Advent Calendar を使って [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) で学んでいく...と試みてなんとか完遂した([記事はこちら](https://qiita.com/advent-calendar/2019/d01tsumath_learn))。
しかし、スローペースだったのもあり25日間毎日受講しているとは言え、コースの半分しか終わってない。
そこで、「Azure の基礎」コースが終わるまで続けていこうと思う。毎日できるかは不明、でもがんばる。

と、いうことで。以下、受講記録のはじまりはじまり～。

1/4は
Azure Policy でインフラストラクチャの標準を適用して監視する
 - 企業のガバナンス管理
を受講した。

# Azure Policy でインフラストラクチャの標準を適用して監視する
## 企業のガバナンス管理
アクセス管理は Azure サブスクリプションレベルで行われる。
Azure 管理グループは、複数の Azure サブスクリプション全体のアクセス、ポリシー、コンプライアンスを管理するためのコンテナー。
管理グループを使用することによって、Azure リソースを階層的にコレクションへと並べ替えることができ、サブスクリプションのレベルよりもさらに高度な分類が可能になる。
管理グループ内のすべてのサブスクリプションは、管理グループに適用された条件を自動的に継承する。
階層を作成するとポリシーを適用でき、その管理グループ下の両方の EA サブスクリプションに継承され、それらのサブスクリプションの下にあるすべての VM に適用される。
cytanb.luaのススメ 3.同一VCIのtable転送

#使用方法について
[cytanb.luaのススメ 1.導入編](https://qiita.com/feath/items/dd15a9e8c57d67f26d02)
こちらにあります。

#messageで転送できるデータについて
VCIのメッセージの仕様についてははちらに記載があります。
[vci.message(VCI間の通信)](https://virtualcast.jp/wiki/doku.php?id=vci:script:reference:message)

送ることのできるデータは

- boolean
- number
- string

の３つになります。

この内の、stringを用いてtableデータを転送することが今回の記事になります。

#つまりはこうやればいい

```lua:temp.lua
---@class F_SendStateMessage
---@field State string
---@field FixedPos Vector3

local VCIsState = "none"
local FixedPos = Vector3.zero
local F_SEND_STATE = "F_SendState"

---@param state string
---@param fixedPos Vector3
local function SendState(state,fixedPos)
    VCIsState = state
    local fixedPosition = fixedPos or Vector3.zero
    vci.state.Set(F_SEND_STATE,VCIsState)
    ---@type F_SendStateMessage
    local message = {}
    message.State = state
    message.FixedPos = cytanb.Vector3ToTable(fixedPosition)
    cytanb.EmitMessage(F_SEND_STATE,message)
end

---@param message F_SendStateMessage
local function F_SendState(sender,name,message)
    FixedPos  = message.FixedPos
    VCIsState = message.State
end
cytanb.OnInstanceMessage(F_SEND_STATE,F_SendState)
```
細かい技とかは無視して、メッセージを送る時に何をするのかという話をやります。

##messageの内容を事前に決める。
```lua:
---@class F_SendStateMessage
---@field State string
---@field FixedPos Vector3
```
ただのコメントですが、こちらを事前に記載することで、アノテーション・インテリセンスが効くようになります。
前後の行を空白にするのが重要です。

##messageの内容を作って送る
```lua:
    ---@type F_SendStateMessage
    local message = {}
    message.State = state
    message.FixedPos = cytanb.Vector3ToTable(fixedPosition)
    cytanb.EmitMessage(F_SEND_STATE,message)
```
messageというTableを作成して、その中に各種パラメータを格納します。今回は、stateとFixedPosの中身を代入していきます。
string,number,boolean以外の値をmessageで送りたい場合は、`cytanb.Vector3ToTable`のようにcytanb謹製の関数を用いて変換をかけます。これを行うことで、転送先でVector3として使用することができるようになります。
使用できる関数では、

- ColorToTable
- Vector2ToTable
- Vector3ToTable
- Vector4ToTable
- QuaternionToTable

の５つがあります。

##受信したメッセージを使う
```lua:
---@param message F_SendStateMessage
local function F_SendState(sender,name,message)
    FixedPos  = message.FixedPos
    VCIsState = message.State
end
cytanb.OnInstanceMessage(F_SEND_STATE,F_SendState)
```
`cytanb.OnInstanceMessage`の解説については[こちら](https://qiita.com/feath/items/039883f6b576640d34f2)。
`cytanb.OnMessage`は、自身のvci以外にもMessageを送りたい場合に使用します。

`cytanb.OnInstanceMessage`及び`cytanb.OnMessage`を用いてメッセージ受信関数を作成すると、ToTable関数で格納したVector3等がVector3の形で使用できるようになります。
あとは、そのままVector3等のデータをそのまま利用すればよいです。
RasPi4によるホームサーバー構築　その７ Serviioの設定

# Serviioの設定

## 1. パッケージのインストール
```bash
sudo apt-get install -y galternatives openjdk-8-jdk
sudo apt-get install -y ffmpeg x264
```

## 2. Serviioのインストール
```bash
wget http://download.serviio.org/releases/serviio-1.10.1-linux.tar.gz
sudo tar -xvzf serviio-1.10.1-linux.tar.gz -C /opt
```

## 3. Serviio自動起動設定
```bash
sudo vim /etc/systemd/system/serviio.service
```

```bash
[Unit]
Description=Serviio media Server
After=syslog.target network.target

[Service]
User=serviio
ExecStart=/opt/serviio-1.10.1/bin/serviio.sh
ExecStop=/opt/serviio-1.10.1/bin/serviio.sh -stop

[Install]
WantedBy=multi-user.target
```

```bash
sudo useradd -r -U -s /sbin/nologin serviio
sudo chown -R serviio:serviio /opt/serviio-1.10.1

sudo systemctl enable serviio.service
```

## 4. Serviioの設定
http://サーバーのIPアドレス:23423/console

右上の「English」を「日本語」

`ライブラリ` - `共有フォルダ`

から共有フォルダを指定する

`メタデータ` - `いくつかのメタデータ展開プログラムでは言語を特定してメタデータを取り出すことが可能です。言語を選択してください`
から
`日本語`
を選択

`表示` - `Video`
`Folders` は `コンテンツだけを表示する`
`Folders` 以外は `無効`

`表示` - `Audio`
`Folders` は `コンテンツだけを表示する`
`Folders` 以外は `無効`

`表示` - `Image`
`Folders` は `コンテンツだけを表示する`
`Folders` 以外は `無効`

`表示` - `メニューの表示言語を選択してください。`
`日本語` を選択
RasPi4によるホームサーバー構築　その６ SAMBAのセットアップ

# Sambaの設定

## 1. インストール
```bash
sudo apt-get install -y samba
```

## 2. samba設定
```bash
sudo mv /etc/samba/smb.conf /etc/samba/smb.~conf
sudo vim /etc/samba/smb.conf
```

[global] に以下を追記

```bash
server min protocol = SMB2
server max protocol = SMB2
server multi channel support = yes
socket options = IPTOS_THROUGHPUT SO_KEEPALIVE
deadtime = 30
use sendfile = Yes
load printers = no
interfaces 192.168.251. 127.0.0.1/8 eth0（IPアドレスは自分の環境に応じて変更のこと）
bind interfaces only = yes
hosts allow = 192.168.251. fe80::/10（IPアドレスは自分の環境に応じて変更のこと）
security = user
```

最後に以下を追記

```bash
[data]
  comment = data
  path = /mnt/hdd/DATA（共有するパスを指定）
  public = yes
  read only = no
  writable = yes
  browsable = yes
  create mask = 0777
  directory mask = 0777
  force user = ユーザー名
```

## 3. samba起動
```bash
sudo systemctl restart smbd
sudo systemctl restart nmbd
```
RasPi4によるホームサーバー構築　その５ USB HDD

# USB HDD

## 1. NTFSのインストール
```bash
sudo apt-get -y install ntfs-3g
```

## 2. USB HDDをマウント
USB HDDを接続して起動

マウントされているデバイスを確認

```bash
sudo fdisk -l
```

UUIDを確認

```bash
sudo blkid /dev/sda2
```
以下の様な表示があるので、UUIDをメモ

```bash
/dev/sda2: LABEL="DATA" UUID="48169C8E169C7E9E" TYPE="ntfs" PARTLABEL="Basic data partition" PARTUUID="5c682c83-342c-4436-b671-82f61c0d35e9"
```

マウントを追加

```bash
sudo vim /etc/fstab
```

以下を追記

```bash
UUID="48169C8E169C7E9E" /mnt/hdd ntfs-3g defaults,iocharset=UTF-8 0 2    
```
RasPi4によるホームサーバー構築　その４ OSの日本語化

# OSの日本語化

## 1. 日本語化
```bash
sudo raspi-config
```

`4 Localisation Options` を選択
`I1 Change Locale` を選択
`en_GB.UTF-8 UTF-8` を選択
`ja_JP.EUC-JP EUC-JP` を選択
`ja_JP.UTF-8 UTF-8` を選択

`OK`

Default locale として、
`ja_JP.UTF-8` を選択

`Finish` で再起動

## 2. タイムゾーン設定
```
sudo raspi-config
```

`4 Localisation Options` を選択
`I2 Change Timezone` を選択
`Asia` を選択
`Tokyo` を選択

`Finish` で再起動

## 3. キーボード設定
```bash
sudo raspi-config
```

`4 Localisation Options` を選択
`I3 Change Keyboard Layout` を選択
`Generic 105-Key(Intel)` を選択
`Other` を選択
`Japanese` を選択
`Japanese ‐ Japanese (OADG 109A)` を選択
`The default for the keyboard layout` を選択
`no compose key` を選択

`Finish` で再起動

## 4. 日本語フォントのインストール
```bash
sudo apt-get install -y fonts-ipaexfont
sudo apt-get install -y ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfonts-kaname
```

## 5. 日本語IMEのインストール
```bash
sudo apt-get install -y uim uim-anthy
```

## 6. 日本語対応ターミナルのインストール
```bash
sudo apt-get install -y fbterm gpm
sudo chmod u+s /usr/bin/fbterm
sudo systemctl enable gpm
sudo reboot
```

```bash
vim .bashrc 
```

```bash
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
	PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
	;;
*)
	;;
	esac
```

以下の用に変更

```bash
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
	PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
	;;
linux)
	if [ -c /dev/fb0 ]; then
		fbterm uim-fep
	fi
	;;
*)
	;;
esac
```

フォントサイズの調整
```bash
vim .fbtermrc 
```

以下を変更

```bash
font-size=16 
```
RasPi4によるホームサーバー構築　その３ OSのセットアップ

# OSのセットアップ

## 1. ログイン

login : pi
password : raspberry

## 2. アップデート
```bash
sudo apt-get -y update
sudo apt-get -y upgrade
sudo rpi-update
sudo reboot
```

## 3. vimのインストール
```bash
sudo apt-get --purge remove vim-common vim-tiny
sudo apt-get -y install vim
```

## 4. /tmp, /var/tmp, /var/log をRAMへ
SDカードのRead/Write回数を減らすために、/tmp, /var/tmp, /var/log をRAMへ
/var/log は任意で！

```bash                                                                                                                                                                                        
sudo vim /etc/fstab
```

以下を追記

```bash                                                                                                                                                                                        
tmpfs  /tmp           tmpfs defaults,size=32m,noatime,mode=1777 0 0
tmpfs  /var/tmp       tmpfs defaults,size=16m,noatime,mode=1777 0 0
tmpfs  /var/log       tmpfs defaults,size=16m,noatime,mode=0755 0 0
```

## 5. SSHの有効化
```bash
sudo raspi-config
```
	
`5 Interfacing Options` を選択
`P2 SSH` を選択

`Finish` で再起動
RasPi4によるホームサーバー構築　その２（Raspbian Buster Lite）

# Raspberry Piのセットアップ

## 1. SDカードのフォーマット
FAT32でのフォーマットが必要だが、OSの標準ツールでは64GBのSDカードに対応していない為、
以下のフォーマットツールで行う。

http://www.ridgecrop.demon.co.uk/index.htm?guiformat.htm
アプリ画像をクリックでダウンロード

`guiformat.exe`
を起動し、
`Allocation unit size`
`65536`（64GBなので！）
を選択し
`Start`
をクリック。

## 2. OSのダウンロード
https://www.raspberrypi.org/downloads/

```
Raspbian Buster Lite
	Minimal image based on Debian Buster
	Version:September 2019
	Release date:2019-09-26
	Kernel version:4.19
	Size:435 MB
```
	
をダウンロード。
7zで展開。


## 3．Win32 Disk Imagerをダウンロードし、インストール
https://sourceforge.net/projects/win32diskimager/
https://forest.watch.impress.co.jp/docs/review/1067836.html


## 4. OSのインストール
Win32 Disk Imagerを利用して、
OSのimgファイル（2019-09-26-raspbian-buster-lite.img）をSDカードにインストール


## 5. 完了したらSDカードをRasPiに挿して電源ON
RasPi4によるホームサーバー構築　その２（NOOBS）

# Raspberry Piのセットアップ

## 1. SDカードのフォーマット

FAT32でのフォーマットが必要だが、OSの標準ツールでは64GBのSDカードに対応していない為、
以下のフォーマットツールで行う。

http://www.ridgecrop.demon.co.uk/index.htm?guiformat.htm
アプリ画像をクリックでダウンロード

`guiformat.exe`
を起動し、
`Allocation unit size`
`65536`（64GBなので！）
を選択し
`Start`
をクリック。


## 2. OSのダウンロード

https://www.raspberrypi.org/downloads/

```
NOOBS
    Offline and network install
    Version:3.2.1
    Release date:2019-09-30
```
	
をダウンロード。
7zで展開し、展開したファイルをSDカードにコピー


## 3. 起動

RaspiにSDカードを挿す。
電源を入れる。


## 4. OSの選択

OSの選択画面が表示されるので、
`Rasbian Lite`
を選択。
RasPi4によるホームサーバー構築　その１ 概要

1. ゴール
RasPi4を利用して、ファイルサーバー＆DLNAサーバーを構築。

2. 概要
ファイルサーバーは、SAMBA。
HDDは、USB HDD。
ファイルシステムはNTFS。
有線LANのみ。（無線LANは使用しない）
DLNAサーバーは、Serviioを利用。
SDカードは、64GB。（特に意味は無い。16GBでもOK）
Github の Pull Request がマージされたときに CodePipeline を発火させる

# やりたいこと
Github の Pull Request がマージされたときに Webhook を使って CodePipeline を発火させる。

# 経緯
CodePipeline のコンソールで、pipeline を構築した。
このとき、Github の指定したブランチが変更された際に Webhook を使って最新のコードをデプロイするようにしたかった。しかし、コードの変更をマージしても何も起こらない。。。

# 解決
調べてみると、github のほうでも設定が必要らしい。
デフォルトでは、 `push` イベントをサブスクライブすることになってるため。
https://developer.github.com/webhooks/#events
> By default, webhooks are only subscribed to the push event.


Github の該当のレポジトリに移動し、Settings > Webhooks の画像の箇所を選択すると詳細な webhook event の設定が可能。

<img width="726" alt="スクリーンショット 2020-01-04 23.27.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561730/a18bb55b-7885-9f3b-e95f-58182b3c1660.png">

今回は Pull requests を選択。

<img width="809" alt="スクリーンショット 2020-01-05 0.06.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561730/6c1c9a3a-9ebb-7607-0c26-ec89f936465f.png">

実際に PurllRequest → マージしてみたが反応なし。。。

イベントは発火してるようだが、どうも CodePipeline 側で弾かれているらしい。
この記事がとてもとても参考になった。
https://qiita.com/yuukive/items/cff3e76301006f42c78f


`aws codepipeline list-webhooks --region [region]`とすると、codepipeline に設定されているフィルターが確認できる。

対象の pipeline の以下の箇所を発火したいイベントに合わせて修正すれば良い。（詳細は上記の記事を参照）

```
                "filters": [
                    {
                        "jsonPath": "$.ref",
                        "matchEquals": "refs/heads/{Branch}"
                    }
                ]
```

このへんのドキュメントを参考にしつつ、
https://developer.github.com/v3/activity/events/types/#pullrequestevent

今回は PullRequest が指定したブランチにマージされたときに CodePipeline を発火したいので、以下のように修正した。


```
                "filters": [
                    {
                        "jsonPath": "$.action",
                        "matchEquals": "closed"
                    }
                ]
```

webhook_config.json という設定ファイルを作成。
`aws codepipeline list-webhooks --region [region]`の結果の "definition"以下をコピーし、"filter"の部分を書き換える。


そして、`aws codepipeline put-webhook --cli-input-json file://webhook_config.json`
というコマンドで CodePipeline を設定し直す。


改めて、PullRequest をマージしてみると、CodePipeline がちゃんと動いた！
githubのシェルスクリプトを実行するときに出る「/dev/fd/63: line 1: 404:: command not found」の対処法

#はじめに
だいぶ局所的なエラーですが、過去に何度もこのエラーに遭遇してはググるの繰り返しだったので、自分の備忘録として投稿しました。

#問題
githubのリポジトリにあるシェルスクリプトを実行しようとしたらこのエラーに遭遇。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/1c730b46-3896-625e-8a71-a1d72d631952.png)
#解決
原因: githubリポジトリのURLが正しくなかった。

###解決方法
1.　githubリポジトリのページ内にある「raw」をクリック
![dev2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/45992709-a7ae-574f-d1c4-10723c5645d0.png)


2.　正しいURLをコピー
![aaaaaa.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/8cae728f-35b5-a11c-00c0-8efe32b8688f.png)

3.　成功!
![dfbdfbdf.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/ff717d42-59c4-4ae5-2afd-3ab09d40b1e2.png)
PythonのConfigParserで配列を読み込む方法

# はじめに

調べてみて、へぇ～と思ったのと、日本語の記事が見当たらなかったので。

# ConfigParserで配列を読み込む方法
## 1. config.iniへの記述

ベタに配列で書いてしまう。

~~~
[Foo]
fibs: [1,1,2,3,5,8,13]
~~~

以下も可。

~~~
[Foo]
fibs = [1,1,2,3,5,8,13]
~~~

## 2. pythonプログラムでの読み込み

ConfigParserで読んでそのままjson.loadsで処理すると、配列になってくれる。

~~~
import configparser
import json

config_ini = configparser.ConfigParser()
config_ini.read("config.ini", encoding='utf-8')

arr = json.loads(config.get("Foo","fibs"))
print(arr)  # [1, 1, 2, 3, 5, 8, 13]
~~~

# その他
数値だけじゃなく、文字列でも出来ました。

# 参考

- [python - Lists in ConfigParser - Stack Overflow](https://stackoverflow.com/questions/335695/lists-in-configparser)
ubuntuサーバーにフォントを追加し，matplotlibで描画する．

## 想定する状況
例えばサーバー(ubuntu)上のjupyterlab+matplotlibで，デフォルトで入っていないフォントで図を作る場合など，
自分がやった時の環境は


- macOS (local): 10.14.6
- ubuntu (server): 16.04
- jupiterlab: 0.33.12
- matplotlib 2.2.4

だけど，後述するFontsディレクトリなどの場所は，OSバージョンによっては異なるかも．

## やり方
 
やり方はいくつかあると思うが，自分はローカルのフォントファイル(.ttf)をサーバーにSCPした．

0. (目当てのフォントがローカルにも入っていない場合) ローカルでフォントをダウンロード．
1. サーバー上の"/usr/share/fonts/truetype"以下に，適当なディレクトリを作成．
2. ローカルの"/Library/Fonts"にあるフォントファイルを，上記で作成したディレクトリにscp
3. "~/.cache/matplotlib/fontList.json"をmv or rm．
4. サーバーのjupyterlab上で，```plt.rcParams['font.family'] = 'Times New Roman'```でフォントを指定．この例だとTimes New Roman．
5. あとは```plt.show()```すれば，figureのフォントが反映されているはず．
Laravelのルートグループにルート名プリフィックスを指定する方法

## はじめに

今回は自分のための備忘録なのであまり細かい解説は省略させていただきます。

## ルート名プリフィックスとは

ルートグループ内の各ルートのルート名を付けるときグループ共通のプレフィックスを指定することができます。
指定するため```name```メソッドを利用します。

公式ドキュメントを参考に以下のように指定すれば、```http://localhost/hoge/test/```にアクセスすると```hoge.test```と表示されます。

```php:routes/web.php
Route::prefix('hoge')->name('hoge.')->group(function () {
    Route::get('test', 'TestController@index')->name('test');
});
```

```php:app\Http\Controllers\TestController.php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class TestController extends Controller
{
    public function index () {
        // ルート名を表示
        echo \Route::current()->getName();
    }
}
```

## 今回やりたかったこと

ルートグループの属性の指定方法は```name```や```prefix```といったメソッドを使う以外に、```group```メソッドの第一引数に配列で渡すことでまとめて指定することもできます。
（こっちが一般的？）

しかし、以下のように```name```をキーとして属性を指定してもルート名プリフィックスは適応されません。

```php:routes/web.php
Route::group([
    'prefix' => 'hoge',
    'name' => 'hoge.',
], function () {
    Route::get('test', 'TestController@index')->name('test');
});
```

そこで処理をたどってみると```RouteRegistrar.php```に以下のような記述を見つけました。
つまり```name```は```as```のエイリアスなのです。

```php:vendor/laravel/framework/src/Illuminate/Routing/RouteRegistrar.php

    /**
     * The attributes that are aliased.
     *
     * @var array
     */
    protected $aliases = [
        'name' => 'as',
    ];

```

よってルートグループの指定をこうやって書き換えることでルート名プリフィックスが想定通りに指定できました。

```php:routes/web.php
Route::group([
    'prefix' => 'hoge',
    'as' => 'hoge.',
], function () {
    Route::get('test', 'TestController@index')->name('test');
});
```

## ちなみに

```name``` は```as```のエイリアスなのでこうやって書き換えることもできます。

```php:routes/web.php
Route::prefix('hoge')->as('hoge.')->group(function () {
    Route::get('test', 'TestController@index')->name('test');
});
```

## 参照

[ルート名プリフィックス - Laravel 6.x](https://readouble.com/laravel/6.x/ja/routing.html#route-group-name-prefixes)
Vue.jsでユーザーのEnter入力時にformをsubmitさせない方法

## 結論
対象のformタグに以下のv-on属性を設定する。

```vue

@submit.prevent
```

## 説明
formのsubmitという動作が発生する事を防ぐ（prevent）。
formのsubmitはブラウザ自体の挙動です。formの各要素（テキストエリアなど）でエンターキーを入力すると、submitが発火します。上記コードでそれを防ぐ事ができます。ちなみに、ブラウザのデフォルトの挙動ではなく、お好きな関数（ここではcustomFunction）を実行したい場合は以下のとおり書きます。

```vue

@submit.prevent="customFunction"
```

## 同様の事例
たとえば何らかのファイルのドラッグドロップで発火する処理（ここではdropFunction）を設定したい場合、デフォルトだと、ドロップされたファイルがブラウザで開かれてしまいます。それを回避するには以下のとおり書きます。

```vue

@dragover.prevent
@drop.prevent="dropFunction"
```

dropイベントのみ必要であっても、dragoverのpreventも併記してください（技術的理由はわかりませんが、dropだけpreventしても適切に動作しません）。
【GAS】「カスタムの改ページ」に合わせてPDF化させたい。

こんにちは。当方グーグルスプレッドシートは比較的触れますが、GAS素人です。
どうぞ有識者の方、お力をお貸しください。

#【やりたいこと】と【やったこと】
1. シートにPDF化ボタンを追加する →できた。
2. PDF化したものをセル指定のフォルダに格納する　→できた。
3. PDFの範囲をカスタムの改ページに合わせたい　→できない。

##具体的なコードと困っていること
以下のサイト様のコードを流用して、「 var folderid = ss.getRange("X1").getValue();」のみ変更してPDF化ボタンの設置、セル参照できました。
https://www.virment.com/create-pdf-google-apps-script/
（ボタンは図形で挿入）

しかし、このコードでは「カスタムの改ページ」に合わせてPDF化することはできず、横幅で見るしかありません。

##このような改ページをしたい
以下の画像のような改ページにしたいです。
![2020-01-04_23h40_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560983/db02425b-f639-59ff-4764-23b7ec5c0f10.png)

##このページがどのように変動するか、どのようにページをPDF化したいか
画像では３データのみですが、場合によって増えます。
１ページに３データずつ入ったページのPDFを作りたいです。

##お願い
以上のような要求にこたえられるようなGASは作れるのでしょうか？
「カスタムの改ページ」に合わせられなくても、場合によっては３データずつPDF化できれば問題ありません。
※セル数を見て改ページ・PDF化、など。１データの縦セル数はすべて同じです。

初心者丸出しで申し訳ございませんが、どなたか有識者の方、参考URLをお持ちの方などいらっしゃいましたらご教授ください。

##自己解決方法
一緒に考えて下さった方、ありがとうございます！
コメントを参考にする前に自己解決してしまいましたが、以下のように解決いたしました。

###解決方法
ごり押しですが、optionに以下を追記して調整しました。

    top_margin:"2.2",              //TOPの調整
    bottom_margin:"2.07",           //BOTTOMの調整
    left_margin:"0.25",             //左側の調整
    right_margin:"0.25"            //右側の調整

こちらで余白を調整して、ごり押し調整しました…（笑）
横幅は自動で見る設定になっていますので、レコードを入れ込んだ形になります。
ちなみに３レコードはサイズの関係で無理そうだったので２レコードずつの入れ込みとなりました。
余白のことがすっぽり頭から抜け落ちていたのでこの解決方法にたどり着けて良かったです。

##もっといい方法あるよ！という方
他にも同様なことで困っている方がいるかもしれません。
ので、もっと簡単な方法あるのにーという方がいらっしゃったらコメントお願いします。
もしかしたら私もバージョンアップで採用させていただくかもしれません！
npm コマンドでグローバルインストールされたパッケージを表示する

次のコマンドを実行することで、グローバルインストールされたパッケージが表示される。

```sh
npm ls -g --depth=0
```

- `npm ls` : インストールされているパッケージを表示する
- `npm ls -g` : グローバルインストールされているパッケージをする
- `npm ls --depth=0` : トップレベルのパッケージのみを表示する
ミルクボーイ風「Internet Explorer」

はじめまして。まつと申します。
ミルクボーイ風の漫才ネタを書いてみたくなって、Qiita初投稿しました。
*注）以下、本家ミルクボーイと同じく個人的な偏見で書いてます*

##「Internet Explorer」
**「オカンがね、好きなブラウザがあるらしいんやけど、名前忘れたって言うててね」**
「ほならね、俺がオカンの気に入っているブラウザを一緒に考えてあげるからどんな特徴言うてたかって教えてみてよ」

**「オカンが言うにはな、Windowsのパソコンには必ず入ってて `インターネットなんとか` って名前らしいねん」**
「ほー、IEやないか！その特徴はもう完全にIEやがな！Windows標準で使えて、いまだに日本のブラウザシェア第2位(12%)やからな！世界シェアで言うたら第6位(3%)やで。どうみても日本人だけが使うてるブラウザやがな」

**「でもオカンが言うには生涯使い続けたいブラウザらしいねん」**
「ほなIE違うかぁ。IEをずっと使い続けたいわけないもんね。IEはね「生涯使い続けたい」やなくて、「何も気づかん人が`知らん間に生涯使い続けてしまう`」ブラウザなのよ。開発元のマイクロソフトですらIE11は危険やからEdgeへの移行しろって言うてるしね。大企業や役所なんかはパソコン自体古くてOSのアップデートもできへんから騙し騙しIE使ってるんやで。それはIE違うわ、もうちょっと詳しい特徴教えてくれる？」

**「アイコンがアルファベットの「e」の形らしいねん」**
「IEやないか！パソコンに最初から入っていてインターネットが見られるソフトでおなじみの`青い"e"`やがな。インターネットの`「e」`やと思ってるおっさんいるけど、インターネットは**`「i」`**やからな。ちなみに`Edge`も`「e」`の形してるけど、あれはずっと同じもん使い続けるIT素人のオトンオカンを`知らん間のIEからEdgeに移行させるためのマイクロソフトの策略`やからな！俺は騙されへんよ。俺を騙したら大したもんや。俺はなんでもお見通しや！」

**「俺もIEと思ったんやけどな、でもオカンが言うには Web開発でめっちゃ活躍するらしいねん」**
「ほなIEちゃうやないか！今どきのWeb開発ならChrome一択やからな。開発後のテストで Chrome, Firefox, Safari, Edge と来て、最後にIEで画面見てみたら、真っ白になっててフロントエンドエンジニアに絶望感を与えるってだけのブラウザやからね。今となっては開発者ツールも使いにくいし。IEなんてわざわざ使わへんよ。他になんか言うてなかった？」

**「パソコンのプロキシ設定を変えるときにいつも使ってるって」**
「ほなIEやないか！パソコン全体に影響するインターネットオプションの設定をなぜか１ブラウザが牛耳ってるんやから！その設定を変えるためだけにIEを起動することもあるんやから。これ以上、パソコンの設定をIEが牛耳るようなら俺は動くよ！」

**「でもES6準拠でJavaScriptのアロー関数も動くらしいねん」**
「ほなIEちゃうがな！IEはES6に準拠してへんからほとんどの機能が使えへんねん。 [このサイト](http://kangax.github.io/compat-table/es6/) みても、IE11は全部真っ赤で非対応ばかりやからな。そもそもモダンなWebサイトはスマホやChromeやSafariをターゲットに作られてて、レガシーなIEは対象外やねん。それでもIEでちゃんと見えているのは polyfillとか Babelとか PostCSSとか駆使して頑張ってくれているフロントエンドエンジニアさん達の**血と涙の賜物**なんやで！」

**「ツールバーが知らん間に増えて、画面の半分くらい占領するらしいねん」**
「それはIEやがな！！フリーソフトをインストールしているとなんか知らん間にツールバーも追加されて、最終的にオカンのブラウザは[だいたいいつもこんな風に] (https://t.co/cQ32mwTwLM)なってもうてるんやから！」

**「でもオトンが言うにはな、`iモードブラウザ`ちゃうかって」**

「絶対ちゃうやろ！！もうええわ」

------

**M-1グランプリ2019 ミルクボーイ優勝おめでとうございます！めっちゃ面白かった！**

でもQiita初投稿がこんなつまらない内容でええのか・・・
よかったらこのネタで漫才コンビ組んでもらえませんか笑