OmniAICreator/Qiita-1.07M huggingface dataset:
Unity 2Dにおける壁と坂道の判定を簡単に制御する

![rectangle_large_type_2_915f01b77fbffc4c3e523dfce94e3371.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643517/3803cb98-6887-4f78-dfd3-1db7bc5e8e81.png)

どうもマカロンです。今回は「2Dにおける壁と坂道の判定を簡単に制御する」という記事をnoteの方で書かせていただいたのでその紹介です。

▼Unity 2Dにおける壁と坂道の判定を簡単に制御するための準備
https://note.com/08_14/n/na76e9194f221

▼Unity 2Dにおける壁と坂道の判定を簡単に制御する方法
https://note.com/08_14/n/n2aba06e02ae6

この記事では2Dゲームの基本、壁と坂道における当たり判定を難しいプログラムを組まずに
作成する方法を紹介しています！
divの配置ミスにおける表示ミス

今回は自分がしようとしていたことの
顛末を簡潔に書こうと思い違った書き方にします！

❶何をしようとしていたのか（理想と発生している表記）
dispaly:flex; align-items:center; justfy-content:center;を使用し、
div要素を真ん中に持って行きたかったが、要素が縦になってしまいうまくいかない。


❷自分で調べて仮説
検証ツールを見たところ、CSSはうまく反映されている。
なので、問題はHTMLの該当class要素、ないしはそのタグ部分に問題があると推測。

❸検証と結果
誤字脱字を探したが、見当たらなかった。
そもそも誤字脱字があればCSSがうまく反映されないので見当違い。
であれば、ブロック要素がおかしいと判断し、div要素にフォーカス。

その結果、

誤）
div class="****"　/div
　ul****
   li****/li
  /ul****

正）
div class="****"
　ul****
   li****/li
  /ul****
/div

と直すことができました！(<>を入れると反映されて要素の文字が消えてしまうので、あえて入れてません＞＜）
初心者にありがちなミスと言われました笑
今後もよく発生すると思われ、この直後にもう一度やらかしていますが、
すぐに見つけることができました。

ミスの結果表示は同じでも
中身のミスは十人十色の世界なんだなと
勉強になりました。
ABC173Cによる学び（bit全探索、多次元リストのコピー、多次元リストの一次元化）

ABC173Cは非常に学びが多く、今後の参考になりそうなので個人的な備忘録代わりに。

```python:ABC173C
import copy  # 多次元リストの値渡し/深いコピー(Deep Copy): copy.deepcopy()のため

h, w, k = map(int, input().split())
grd = [list(i for i in input()) for _ in range(h)]
ans = 0
for i in range(2**h):  # 行の選び方が2**h通りで、そのうちi番目
    grd1 = copy.deepcopy(grd)  # grdの値渡し/深いコピー(Deep Copy)
    for i1 in range(h):  # 2**h通りは２進数にしたときh桁で、そのうちi1桁目
        if i >> i1 & 1:  # 「2**h通りのうちi番目」のiを２進数にしたとき、どの桁が1になっているか
            grd1[i1] = ['r'] * w
    for j in range(2**w):  # 列の選び方が2**w通りで、そのうちj番目
        grd2 = copy.deepcopy(grd1)  # grd1の値渡し/深いコピー(Deep Copy)
        for j1 in range(w):  # 2**w通りは２進数にしたときw桁で、そのうちj1桁目
            if j >> j1 & 1:  # 「2**w通りのうちj番目」のjを２進数にしたとき、どの桁が1になっているか
                for n in range(h):
                    grd2[n][j1] = 'r'
        if sum(grd2,[]).count('#') == k:  # sum()で2次元リストを一次元に平坦化
            ans += 1
print(ans)
```

###bit全探索
bit全探索に関してはいろいろな記事があるが、概して初心者かつPythonしか使えない人には難しい。以下はそんな人にもわかりやすく、まずbit全探索って何をするのかを掴むのにはちょうどよい。
[Python de アルゴリズム（bit全探索）](https://qiita.com/gogotealove/items/11f9e83218926211083a)

###多次元リストのコピー
`リスト.copy()`や`リスト[:]`を使って、オブジェクトの破壊・非破壊など意識して書いたつもりではあったが、思ったとおりに動いてくれなくて（上のコードでは`grd`が意図せずに書き換わって）困った。
コピーには参照渡し/浅いコピー(Shallow Copy)と値渡し/深いコピー(Deep Copy)があり、copyライブラリの`copy.copy()`と`copy.deepcopy()`では特に多次元リストで挙動が異なる。
[Python - リストを複製する](https://murashun.jp/blog/20200113-22.html)
[【Python】多次元リストのコピー](https://qiita.com/somolyot/items/b0c8a97d05637ea2b13d)

###多次元リストの一次元化
この問題のように多次元のリストを一元的に集計したいようなときに便利。いくつかやり方はあるようだが、`sum()`の意外な使い方も。
[Pythonでflatten（多次元リストを一次元に平坦化）](https://note.nkmk.me/python-list-flatten/)
データベース管理システム(RDBMS)　権限付与、テーブル制約定義

平成31年春期 午前問題27

関係データベース管理システム(RDBMS)の表へのアクセスにおいて，特定の利用者だけにアクセス権を与える方法として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6aef20e9-55ff-b47f-348d-12a8b23d6e8e.png)

答えは、簡単ですね。
でも、知らないことがあった！！

１、CONNECT文は
データベースへの接続を確立するSQL文です。

２、参照制約は、
表間の整合性を確保するために設定される制約です。

３、GRANT文は
1人または複数のユーザに表に関する特定の権限を付与するSQL文です。


４、CREATE ASSERTION文は
複数のテーブルに対して制約をかける「宣言」を定義するSQL文です。

・SQL92で標準化された。1つ以上、複数のテーブルに対して制約をかける「表明」を定義する。
実装しているDBMSが少ないため知名度は低いが、DB側で複雑な制限をかけれるため処理速度の改善に繋がるらしい。

設定した条件が偽の場合にエラーを発生させることができ、SELECT文を使った複雑な制約を定義することができる。

例：
CREATE ASSERTION 入力値チェック CHECK (NOT EXIST(SELECT * FROM 価格票,限界値 WHERE 価格表.商品コード = 限界値.商品コード AND 価格票.価格 <= 限界値.上限価格))

※表明名が「入力値チェック」、CHECK以降の文が条件である。上記例だと価格票テーブルと限界値テーブルを商品コードで結合して価格が上限価格以下であることを判定している。上限価格以上の価格が設定された場合はエラーを投げる。

・CREATE DOMAIN
SQL92で標準化された。ユーザ定義のデータ型を作成する。
実装しているDBMSが少ないため知名度は低いが、DB側で入力値チェックを行えるため処理速度の改善に繋がるらしい。
ASSERTIONと合わせてリファクタリングに使えそう。
CREATE DOMAINをコールしたユーザがそのドメインの管理を行うが、使用に関しては全ユーザが行える。(場合が多い模様。DBMS依存。)

例：
CREATE DOMAIN AGE AS CHECK (VALUE >= 18) AND (VALUE <= 99)

※18〜99までしか値を取らないユーザデータ型「AGE」を作成する。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
補足

DBMSにおいて，複数のトランザクション処理プログラムが同一データベースを同時に更新する場合，論理的な矛盾を生じさせないために用いる技法はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/424223f5-439f-3d4d-1b91-03a5440a3080.png)

１、排他制御は、トランザクションの整合性を保つために、1つのタスクがデータ更新のトランザクションを実行している間は、その処理が終わるまで同じデータに対する他のトランザクション要求を待機させる仕組みです。
複数のトランザクションが同じデータを更新しようとしたときに、データを「ロック」することで同時更新による更新消失を防ぎます。

２、再編成
再編成は、データを適切に再配置することで、データベースのアクセス効率を回復させる処理です。

３、正規化
正規化は、関係データベースを構築するに当たり、データの冗長性の排除、整合性の確保、及び保守性の向上などを目的として行われる処理です。

４、整合性制約
整合性制約は、データベースの整合性を保つために表や列に設定される制約です。


参考：
https://www.ap-siken.com/kakomon/24_haru/q28.html

マイナーなCREATE文
https://spinoza-2.hatenadiary.org/entry/20090329/1238308362

https://www.fe-siken.com/kakomon/28_haru/q30.html
AtCoder Beginner Contest 174 A問題「Air Conditioner」解説(C++,Python,Java)

AtCoder Beginner Contest 174 A問題「Air Conditioner」の解説を行います。
<q>問題URL : https://atcoder.jp/contests/abc174/tasks/abc174_a</q>
<index>

#問題概要:
現在の室温$X$[単位:度]が与えられる。<br>
室温が$30$度以上ならば冷房の電源を入れる。
冷房を入れるかどうかを判定せよ。

##制約:
・$-40 \leq X \leq 40$
・$X$は整数

#解説:
プログラミングの中で利用頻度がかなり多い、<font color = "#FF0000">「条件分岐」</font>の問題です。

今回は$30 \leq X $であるかの条件分岐を行う問題でした。

さて、問題に取り組む前に、
制約が小さいため、以下のようなコードを考えた方はいますか？？

```A.py
X = int(input())
if (X == -40):
  print("No")
elif (X == -39):
  print("No")
elif (X == -38):
  print("No")
#この後X == 40まで条件分岐を行う
```

制約上、$-40 \leq \ X \leq 40$というものがあるのでおよそ160行書くことでACすることも出来るのですが、競技プログラミングでは<b>「コードを正確に書くまでの速さ」</b>も求められるのでこの書き方ではあまりよくありません。

```A2.py
X = int(input())
if (30<=X):
  print("Yes")
else:
#(X < 30)
  print("No")
```

このように書くと
・$30 \leq X$であるときに"Yes"と出力
・$X < 30 ( X \leq 29)$であるときに"No"と出力 
という、<b>2条件のみの条件分岐</b>によって、A.pyのようなコードと同じ処理を行うプログラムを書くことが出来ます。

以下、C++14, Javaでの解答例です。(上のコードはPythonでの解答例です)
<details><summary>C++での解答例</summary><div>

```{A.cpp}
#include<bits/stdc++.h>
using namespace std;
int main(){
  int x;
  cin >> x;
  if (30 <= x){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
}
```
(改行を忘れないこと！！)
</div></details>
<details><summary>Javaでの解答例</summary><div>

```{A.java}
import java.util.Scanner;
public class main(){
  public static void (String[] args){
    Scanner scan = new Scanner(System.in);
    int x = scan.nextInt();
    if (30 <= x){
      System.out.println("Yes");
    }else{
      System.out.println("No");
    }
  }
}
```
</div></details>
Day.jsでよく使う機能の覚書

JavaScriptの日付操作ライブラリである[Day.js](https://github.com/iamkun/dayjs)でよく利用する使い方について書き残しておきます。

[公式ドキュメント](https://day.js.org/docs/en/installation/installation)が充実しているので、網羅的に知りたい方はそちらを見ていただいた方が早いでしょう。

## 基本

### インストール

```
npm install dayjs --save

// or 

yarn add dayjs
```

### import

```javascript
import dayjs from 'dayjs';

const now  = dayjs() // 現在の日付情報を取得
```

## 日付情報の取得

例として現在の日時から各種情報を取得します。

月が0から始まる値で取得されることに注意しましょう。

```javascript
dayjs().year() // 年
dayjs().month() // 月 (0~11)
dayjs().date() // 日
dayjs().day() // 曜日 0(日曜日)~6(土曜日)
dayjs().format('YYYY/MM/DD') // フォーマットして表示
```

## 日付情報の設定

```javascript
dayjs().year(2020) // 日付情報の年を2020に更新
dayjs().month(8) // 日付情報の月を9月に更新
dayjs().date(12) // 日付情報の日を12日に更新
dayjs('2020-08-12') // 文字列をパースして更新
```

## その他

### 日付情報の加算

```javascript
dayjs().add(3, 'year') // 年に3を加算
dayjs().add(3, 'month') // 月に3を加算
dayjs().add(3, 'week') // 週に3を加算
```

### 日付情報の減算

```javascript
dayjs().subtract(3, 'year') // 年に3を減算
dayjs().subtract(3, 'month') // 月に3を減算
dayjs().subtract(3, 'week') // 週に3を減算
```

### unixtimeで出力

```javascript
dayjs().unix()
dayjs().valueOf() // ミリ秒unixtime
```

### unixtimeで日付情報の更新

```javascript
dayjs.unix(1596836857)
dayjs(1596869215397)
```

### Dateからの変換

```javascript
const d = new Date(2020,8,12)
const day = dayjs(d)
```
データベースの概念スキーマ、外部スキーマ、内部スキーマ


平成31年春期 午前問題26

データベースを記録媒体にどのように格納するかを記述したものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6062f9dc-ae2c-64b2-50bb-af46a7f1c6c7.png)

ANSI/X3/SPARCの3層スキーマ構造は、概念スキーマ、外部スキーマ、内部スキーマの３つのグループに分けてデータ定義を行うデータベースモデルです。

１、概念スキーマは、
内部スキーマと外部スキーマの間に位置し、エンティティやデータ項目相互の関係に関する情報をもつ。**テーブルやリレーション**などが該当する。
データベース化対象の業務とデータの内容を論理的な構造として記述したもの。テーブルの正規化やCREATE TABLEによる表定義が概念スキーマに相当する。


２、外部スキーマは、
個々のプログラム又はユーザの立場から見たデータベースの記述である。**ビュー**などが該当する。
データの利用者からの見方を記述したもの。SQLのビューが外部スキーマに該当する。

・サブスキーマは、外部スキーマの別名である。


３、内部スキーマは、
概念スキーマをコンピュータ上に具体的に実現させるための記述である。**データファイルの配置やインデックス**などが該当する。
データを記憶装置上にどのような形式で格納するかを記述したものです。ファイル編成やインデックスの設定などが内部スキーマに相当する。


ーーーーーーーーーーーーーーーーーーーーーー
補足

データベースの3層スキーマ構造に関する記述のうち，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d8353cda-38e8-2812-20ff-db63e627d51a.png)


１、ANSI/X3/SPARCの3層スキーマ構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/69663292-d7b0-5df6-8a42-73253fc8fdda.png)

概念スキーマ：データの倫理的な構造　Table
外部スキーマ：データの利用者の見方　View
内部スキーマ：データの記憶装置上にどのような形式で格納する　ファイル、Indexの設定


２、
・概念スキーマは，データの物理的関係を表現する。
⇒×。概念スキーマは、データベース化対象の業務とデータの内容を論理的な構造として表現したものです。テーブルの正規化やCREATE TABLEによる表定義が概念スキーマに相当します。

・外部スキーマは，データの利用者からの見方を表現する。
⇒○。外部スキーマは、データの利用者からの見方を表現したものです。SQLのビューが外部スキーマに相当します。

・内部スキーマは，データの論理的関係を表現する。
⇒×。内部スキーマは、データを記憶装置上にどのような形式で格納するかを表現したものです。ファイル編成やインデックスの設定などが内部スキーマに相当します。

・物理スキーマは，データの物理的関係を表現する。
⇒×。ANSI/X3/SPARCの3層スキーマ構造には、物理スキーマという名称のスキーマは存在しません。


参照：

http://fast-macro.com/Johosyori/h31HaruOuyou/h31HaruOuyou-26.html

https://www.fe-siken.com/kakomon/18_aki/q58.html

https://www.ap-siken.com/kakomon/28_aki/q26.html
日本語の発音を取得する【Python】【MeCab】

#やったこと
MeCabとPythonで日本語の発音をカナで取得する関数を作りました。
例えば、「今日はよく寝ました」と入力したら「キョーワヨクネマシタ」と返すようなものです。
#環境
- macOS Catalina 10.15.4
- python3.8.0

下記を参考にMeCab、mecab-ipadic-neologd、mecab-python3をインストールしました。
https://qiita.com/taroc/items/b9afd914432da08dafc8

下記を参考にpythonからimportするMeCabのデフォルト辞書をmecab-ipadic-neologdにしておきました。
https://qiita.com/shimajiroxyz/items/3b475da3b6cd850d2c22

辞書はneologdでなくても構いません。

またひらがなをカタカナに変換する'jaconv'をインストールしておきます。

```
pip install jaconv
```
#方針
MeCabの出力結果はデフォルトでは下記のようになっています。

```
表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音
```
このため、入力日本語をMeCabで形態素解析して、「発音」の部分を取得すればよいです。
ただし発音が取得できない未知語はどうしようもないので、「表層形」を可能な範囲でカタカナに変換したもので、代用することとします。

なお、今回の実装では発音を取得するため「今日は」は「キョーワ」と変換されます。もし「キョウハ」のようにルビを取得したい場合は「読み」の部分を取得するようにしてください。
#コード

```Python
import MeCab
import jaconv

#記号を削除する関数
#(以下
#http://prpr.hatenablog.jp/entry/2016/11/23/Python%E3%81%A7%E5%85%A8%E8%A7%92%E3%83%BB%E5%8D%8A%E8%A7%92%E8%A8%98%E5%8F%B7%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E6%B6%88%E3%81%97%E5%8E%BB%E3%82%8B
#よりそのまま引用)
import unicodedata
import string

def format_text(text):
    text = unicodedata.normalize("NFKC", text)  # 全角記号をざっくり半角へ置換（でも不完全）

    # 記号を消し去るための魔法のテーブル作成
    table = str.maketrans("", "", string.punctuation  + "「」、。・")
    text = text.translate(table)

    return text
#(引用ここまで)

m = MeCab.Tagger() #形態素解析用objectの宣言

def getPronunciation(text):
    m_result = m.parse(text).splitlines() #mecabの解析結果の取得
    m_result = m_result[:-1] #最後の1行は不要な行なので除く

    pro = '' #発音文字列全体を格納する変数
    for v in m_result:
        if '\t' not in v: continue
        surface = v.split('\t')[0] #表層形
        p = v.split('\t')[1].split(',')[-1] #発音を取得したいとき
        #p = v.split('\t')[1].split(',')[-2] #ルビを取得したいとき
        #発音が取得できていないときsurfaceで代用
        if p == '*': p = surface
        pro += p
    
    pro = jaconv.hira2kata(pro) #ひらがなをカタカナに変換
    pro = format_text(pro) #余計な記号を削除

    return pro
 
#出力確認
text = '今日はよく寝ました'
print(text)
print(getPronunciation(text))
```

出力は下記です。

```
今日はよく寝ました
キョーワヨクネマシタ
```

#参考
(https://qiita.com/shimajiroxyz/items/3b475da3b6cd850d2c22)
[意味悲鳴: Pythonで全角・半角記号をまとめて消し去る](http://prpr.hatenablog.jp/entry/2016/11/23/Python%E3%81%A7%E5%85%A8%E8%A7%92%E3%83%BB%E5%8D%8A%E8%A7%92%E8%A8%98%E5%8F%B7%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E6%B6%88%E3%81%97%E5%8E%BB%E3%82%8B)
RTX1200をセットアップする(CUI編)Part4

##目的
このページではRTX1200を初期化してからipv4で通信できるようにするところまでを目的とする。[前回](https://qiita.com/yunimisaka/items/6b176b7262ad1cdac760)はユーザの作成とユーザ権限の設定までやったので今回はipv4を行っていきたい。
例のごとく筆者がCUIが好きなので使いやすいGUIが用意されているがガン無視していく。
いつものことながら筆者が環境作りなおすときに見るためのメモ書きなのでわかりにくいところが多い気がする。

##使用機材・ソフトウェア
このあたりは前回と一緒だが今回も記載をしておく。
・RTX1200([リンク](https://network.yamaha.com/products/routers/rtx1200/index))
・PC(Ubuntu16.0.4)
・GTKTerm 0.99.7-rc1
・telnet
・ifconfig
・USBシリアルケーブル(クロス)([amazonで筆者が買った物](https://www.amazon.co.jp/dp/B01N0F91GH/ref=cm_sw_r_tw_dp_x_IiNgFb4TCTWJ8))

##ログイン
前回ログインまでは行ったので前回と同じ手順でログインをする。
今回も例のごとくシリアルケーブルを買ったのでシリアル通信で行っていく。

##IPv4の設定
私がnuroを利用しているので今回やりたい設定としては2重ルータとなる。
nuroのルータの下にyamahaのルータがいる状態だ。nurobizさんの[nuroアクセスルータ設定例](https://biz.nuro.jp/archive/manual/yamaha_routersetting.pdf)のプレミアム構成例1が参考になるだろう。
ということで下記のコンフィグを書いた。

```
ip routing on
ip route default gateway 192.168.100.1
ip lan1 address 192.168.200.1/24
ip lan2 address 192.168.100.2/24
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.200.2-192.168.200.253/24
dns server 192.168.100.1
dns private address spoof on
```

さて、通信ということでRTX1200の下に配置したPCから下記コマンドでgoogleさんにpingを飛ばしてみた。

```
ping 8.8.8.8
```

**あれ！？**帰ってこない……。
ならば上位ルータまでは行けてるのか……？

```
ping 192.168.100.1
```

**あれ！？**これも帰ってこない……じゃあRTX1200までは行けてるよな？


```
ping 192.168.200.1
```

これは流石に帰ってくるか……。

RTX1200から飛ばすとどうなるのか……。

```
ping 192.168.100.1
```

これは帰ってくるのか……ならば……。

```
ping 8.8.8.8
```

お？帰ってきた？

つまり192.168.100.2と192.168.200.1の間の通信がうまくいってない？

と数時間悩んだが解決せず……。

結論からいえばNATが足りてなかったです。
そういえば確かに上位ルータにルーティング追加した覚えがなかった。
というか上位ルータにそんな設定項目が見つからない。クソかよ。

というわけで最終的な設定は次のとおり。

```
ip routing on
ip route default gateway 192.168.100.1
ip lan1 address 192.168.200.1/24
ip lan2 address 192.168.100.2/24
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.200.2-192.168.200.253/24
dns server 192.168.100.1
dns private address spoof on
nat descriptor type 200 nat
nat descriptor address outer 200 192.168.100.129-192.168.100.253
ip lan2 nat descriptor 200
```

##IPv4の設定の意味
`ip routing on`はルーティングをするという意味。

`ip route default gateway 192.168.100.1`はデフォルトゲートウェイの設定。上位ルータのIPアドレスをいれる。

`ip lan1 address 192.168.200.1/24`についてはlan1のIPアドレスの設定。RTX1200の下にどんなIPが振られるかが決まる。

`ip lan2 address 192.168.100.2/24`についてはlan2のIPアドレスの設定。RTX1200のIPアドレス。上位ネットワークから振られるIPと同じものにする。

`dhcp service server`DHCPをする。

`dhcp server rfc2131 compliant except remain-silent`DHCPの方式を決定。

`dhcp scope 1 192.168.200.2-192.168.200.253/24`DHCPの範囲を設定。

`dns server 192.168.100.1`DNSサーバを設定。ここでは上位サーバに依頼している。

`dns private address spoof on`プライベートアドレスに対する問い合わせを処理するか否かの設定。

`nat descriptor type 200 nat`NATのタイプを設定。

`nat descriptor address outer 200 192.168.100.129-192.168.100.253`ナットで使用する上位ネットワークのIP範囲を設定。

`ip lan2 nat descriptor 200`LAN2にNATを適用。

NATは通信時にプライベートアドレスとネットワークアドレスを変換する機能。
例えば`192.168.200.2`を`192.168.100.5`に変換して通信するなど。
実際のPCのアドレスは`192.168.200.2`だけれど外(上位ネット)から見ると`192.168.100.5`に見える。
Jetson nano 初期セットアップメモ 

# Swap領域確保
```
git clone https://github.com/JetsonHacksNano/installSwapfile
cd installSwapfile
./installSwapfile.sh
```

# メインのディレクトリを英語化
```
env LANGUAGE=C LC_MESSAGES=C xdg-user-dirs-gtk-update
```

# 適当にエディタ入れる
```
sudo apt install nano
```

# python環境の構築
## virtualenvの導入
```
sudo apt install virtualenv virtualenvwrapper
mkvirtualenv --python=/usr/bin/python3 my_py
```

## プリインストールのOpenCVをvirtualenv下に引っ張る
```
ln -s /usr/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-aarch64-linux-gnu.so .virtualenvs/my_py/lib/python3.6/site-packages/cv2.cpython-36m-aarch64-linux-gnu.so
```
[参考](https://www.robotech-note.com/entry/2016/09/24/222729)
## 各ライブラリの導入
### numpy, ipython
```
workon my_py #virtualenv環境に入る
pip install -U pip
pip install numpy
pip install ipython
```

### scipy(何故かvirtualenv下でpip install失敗)
```
apt install libatlas-base-dev gfortran python3-pip
pip install h5py
sudo apt install python3-scipy 
ln -s /usr/lib/python3/dist-packages/scipy/ .virtualenvs/my_py/lib/python3.6/site-packages/
```

### もろもろ
```
pip install cython
pip install matplotlib
pip install pytz

ln -s /usr/lib/python3/dist-packages/Jetson/ .virtualenvs/my_py/lib/python3.6/site-packages/
ln -s /usr/lib/python3/dist-packages/pandas/ .virtualenvs/my_py/lib/python3.6/site-packages/
```
### cupy
```
pip install fastrlock
sudo pip3 install cupy #systemのpythonに入る

ln -s  /usr/local/lib/python3.6/dist-packages/cupy/ .virtualenvs/my_py/lib/python3.6/site-packages/
ln -s  /usr/local/lib/python3.6/dist-packages/cupyx/ .virtualenvs/my_py/lib/python3.6/site-packages/
```
###何故かうまくいかなかったやつら
```
sudo apt-get install -y python3-sklearn
ln -s /usr/lib/python3/dist-packages/sklearn/ .virtualenvs/my_py/lib/python3.6/site-packages/
```
https://forums.developer.nvidia.com/t/pytorch-for-jetson-nano-version-1-6-0-now-available/72048
から.whl引っ張ってきてからの
```
pip install torch-1.6.0-cp36-cp36m-linux_aarch64.whl
```

# vscodeの導入
https://github.com/toolboc/vscode/releases/ からビルド済みのやつを引っ張ってくる  
```
sudo dpkg -i code-oss_1.32.3-arm64.deb
```
# リモートデスクトップで繋げる
```
sudo apt-get update
sudo apt-get install xrdp

sudo apt-get install xfce4 
echo xfce4-session >~/.xsession
sudo nano /etc/xrdp/startwm.sh
```
```
#test -x /etc/X11/Xsession && exec /etc/X11/Xsession      #コメントアウト
#exec /bin/sh /etc/X11/Xsession                           #コメントアウト
startxfce4  #追加
```
```
sudo service xrdp restart
```
【python】スクレイピングメモ1~ジュラシックワールドの恐竜のサイズを取得~

###スクレイピングとは
ウェブサイトから情報を取得し、その情報を加工して新たな情報を生成すること。



###１．指定したwebページの情報を表示

```python3
import requests
from bs4 import BeautifulSoup
# Webページを取得して解析する

load_url = "https://www.jurassicworld.jp/books/"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# HTML全体を表示する
print(soup)
```


####実行結果
![python_scraping_jwa1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/cc24170c-813f-37c2-56d2-7b6805b5e822.jpeg)

![python_scraping_jwa2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/ebf6bbd5-95dd-6ce8-61a0-0a0b9466ef02.jpeg)



###２．タグから情報取得

`指定のタグなどの情報を表示するには`

+ find(文字列)
+ find(タグ名)
+ find(id="id名")
+ find(class_="class名")　※classは予約語のため、class_とかく

`aタグのリンクを取得する場合やimgタグのsrcを取得する場合`

+ find("a").get("href")
+ find("img").get("src")


###３．特定のクラスの情報を取得

```python3
dino_ttl = soup.find(class_="archive__item")   # classが「archive__item」の範囲の要素を検索

# dino_ttl内でclass="archive__ttl"の情報を表示
print(dino_ttl.find(class_="archive__ttl").text)
#dino_ttlでaタグ内のリンクを表示
print(dino_ttl.find("a").get("href"))
```
__実行結果__

![python_scraping_part.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/869cfe10-f5ca-bf1e-59b0-396206d00575.jpeg)




+ リンクが相対アドレスになっている
+ 条件(classが"archive__ttl")を満たす最初の1つ目のデータしか表示できない

###４．取得したいウェブページの構成


####①恐竜図鑑
![python_scraping3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/39bbf1a2-9842-aad9-ee3e-89706da304fb.jpeg)

![python_scraping4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/f5202409-5d76-e4b9-9b27-1eca8d5e8195.jpeg)

####②個々の恐竜をクリックして情報が表示
![python_scraping5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/fbe45734-909f-cb6b-dcc8-7204725ea628.jpeg)



###５．恐竜図鑑から、各恐竜の個人情報(サイズ、画像のバス)を抜き出そう

`find_all :全てのタグの情報を検索`
`urllib.parse.urljoin(ベースURL,調べるURL):相対URL(調べるURL)を絶対URLに変換`
`strip():前後の空白文字を削除`


```python3

# idがcontentで検索し、その中のすべてのarchive__ttlを検索して表示する
con_ttl = soup.find(id="content")    # idが「content」を検索
for element in con_ttl.find_all(class_="archive__item"):
    # その中のarchive__ttlの文字列を表示
    dino_name=element.find(class_="archive__ttl").text.strip()
    print('★'+dino_name+'★')
    #恐竜の画像のパス
    dino_img=element.find("img").get("src")
    #恐竜の画像の絶対パス
    dino_img=urllib.parse.urljoin(load_url,dino_img)
    print(dino_img)
    #archive__item内のリンク先を取得
    link_dino=element.find("a").get("href")
    #リンクの絶対パスを取得する
    link_dinolng=urllib.parse.urljoin(load_url,link_dino)
    #個別の恐竜ページに飛ぶ
    dino_html = requests.get(link_dinolng)
    print(link_dinolng)
    soup2 = BeautifulSoup(dino_html.content, "html.parser")
    idx0=link_dino.find(".html")
    #id=link_dinoから.htmlを除いたものを検索
    soup2_uniq=soup2.find(id=link_dino[0:idx0])
    #最初のclass=profile__txtにサイズの情報があるのでここを検索
    dino_size=soup2_uniq.find(class_="profile__txt").text.strip()
    print(dino_size)

```
###実行結果

![python_scraping_jwa23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/49db39ea-cfbf-79cb-23dc-b21e4904b7b1.jpeg)
TypeScript 型エイリアス vs インターフェース


## 基本の違い
**型エイリアス** ・・・　クラスやオブジェクトの規格を定義
**インターフェース**　・・・　型や型の組み合わせに別名を付ける

```typescript:型エイリアス
type Enemy = {
  hp: number
  mp: number
}
```

上記型エイリアスをインターフェースにすると、下記のようになります。
**インターフェース**

```typescript:インターフェース
interface Enemy = {
   hp: number
   mp: number
}
```

クラスやオブジェクトの規格はどちらでも定義可能ですが、
両者の違いは一体なんなのでしょうか？

## 【違いその1】 型エイリアスは任意の型を指定できる!

型エイリアスは型の式( `|` や `&`)を指定することができます。
インターフェースでは下記の記述はできません。

```typescript:型エイリアス
type A = number
type B = A | string
```
##【違いその2】 拡張の記述法が異なる

正確に言うと、`extends`による拡張はinterfaceのみで使用でき、型エイリアスは【違いその1】の型の式を使用することでextendsと同じ機能を表現可能です。

```typescript:型エイリアス
type Animal = {
   name: string
}
type Dog = Animal & {
   bark: string
}
```

```typescript:インターフェース
interface Animal = {
  name: string
}

interface Dog extends Animal {
   bark: string
}
```

## 【違いその3】 拡張の割り当てチェックの違い
【違いその2】に付随するものになりますが、 インターフェースの拡張は拡張元のインターフェースが、拡張先のインターフェースに割り当て可能かを確認します。

```typescript:インターフェース
interface Base {
  ok: number | string
  ng: number
}
interface Ex extends Base {
  ok: number
  ng: string  // 拡張元に割り当て不可能なのでここでエラーになる
}
```

型エイリアスでの交差`&`では、拡張元の型と拡張先の型を結合してくれます。

```typescript:型エイリアス
type Base = {
  ok: number
}
type Ex = Base & {
  ok: string | number
}

let Test: Ex = {
  ok: 333 // 結合され、 okは numberなので333が代入できる
}

```


## 【違いその4】 同名を複数宣言した場合にインターフェースはマージする
同じスコープ内で同名でinterfaceを宣言するとマージされます。
これは**宣言のマージ**と言う機能で、型エイリアスにはない機能です。

```typescript:宣言のマージ
interface Dog {
  name: string
}

interface Dog {
  bark: string
}

let dog: Dog = {
  name: 'ポチ',
  bark: 'ワンヌ'
}
```


## 参考
・[TypeScriptのInterfaceとTypeの比較](https://qiita.com/tkrkt/items/d01b96363e58a7df830e#class%E3%81%B8%E3%81%AEimplement)

・Boris Cherny著『プログラミングTypeScript』(オライリー・ジャパン発行」
コンピュータグラフィックスにおける，レンダリング、アンチエイリアシング、デジタルアニメーション、モデリングの記述

平成31年春期 午前問題25

コンピュータグラフィックスにおける，レンダリングに関する記述として，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/3fe8ef25-9f6b-c589-28d1-d447dc318c31.png)


１、レンダリングとは、情報を基にディスプレイに描画可能な形式の画像に変換する処理です。3DCGでは、与えられた3Dモデルの形状や光源のデータから、計算によって画像を生成します。

・３DCG：
3次元コンピュータグラフィックス（さんじげんコンピュータグラフィックス、英: three-dimensional computer graphics）は、コンピュータの演算によって3次元空間内の仮想的な立体物を2次元である平面上の情報に変換することで奥行き感（立体感）のある画像を作る手法である。

・レンダリング　rendering とは、
何らかの抽象的なデータ集合を元に、一定の処理や演算を行って画像や映像、音声などを生成すること。

・3Dレンダリング
単にレンダリングといった場合には、3次元グラフィックス（3DCG）において数値データとして与えられた物体や図形に関する情報を計算によって画像化することを指すことが多い。


２、アンチエイリアシング
異なる色のピクセルを混ぜて配置することによって，中間色を表現すること

・アンチエイリアス  【 anti-aliasing 】  スムージング　別名： smoothing
アンチエイリアスとは、コンピュータで文字や図形を描画・表示する際に、斜線や曲線などに発生する微細な階段状のギザギザした部分（ジャギー）を目立たなくする手法。輪郭の色と背景色の中間色を段階的に配置する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/9e16ca28-96b8-17a4-6184-4088c6b6497c.png)


３、デジタルアニメーション又はスライドショー
複数の静止画を1枚ずつ連続表示することによって，動画を作ること

・スライドショー（英: slideshow）は、選択した一連の画像を順次表示するもので、芸術的目的や実用的目的に利用される。


４、モデリング
物体をワイヤフレーム，ポリゴンなどを用いて，モデル化すること

・ワイヤーフレーム
とは「ホームページのレイアウトやコンテンツの配置を決めるための設計図」のようなものです。

引っ越しなどの際に、下記のような住宅の間取り図を見たことがあるという方も多いと思います。
ワイヤーフレームはいわば、「ホームページ版 間取り図」の役割を果たします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d1c574bb-0395-d069-253c-8f9b2ed83096.png)


・ポリゴン（英: polygon）とは、多角形のことであるが、この記事ではサーフェスモデルなど、コンピュータグラフィックス特に3次元コンピュータグラフィックスにおける応用について述べる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/21b36c56-acd9-8fd4-c3c4-b49162b4572a.png)


ーーーーーーーーーーーーーーーーーーーーーー
補足

コンピュータグラフィックスの要素技術に関する記述のうち，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/734c24d4-3197-a30e-c5f6-69a390809c02.png)

１、
・アンチエイリアシングは，周囲の画素との平均値演算などを施すことによって，斜め線や曲線のギザギザを目立たなくする。
　→○。

・メタボールは，光の相互反射を利用して物体表面の光エネルギーを算出することによって，表面の明るさを決定する。
　→×。ラジオシティの説明です。

・ラジオシティは，光源からの光線の経路を計算することによって，光の反射や透過などを表現し，物体の形状を描画する。
　→×。レイトレーシングの説明です。

・レイトレーシングは，物体を球や楕円体の集合として擬似的にモデル化する。
　→×。メタボールの説明です。


参考：

https://www.ap-siken.com/kakomon/28_haru/q26.html

https://www.ap-siken.com/kakomon/31_haru/q25.html

３DCG
https://ja.wikipedia.org/wiki/3%E6%AC%A1%E5%85%83%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9

レンダリング
http://e-words.jp/w/%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0.html

アンチエイリアシング
http://e-words.jp/w/%E3%82%A2%E3%83%B3%E3%83%81%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9.html

スライドショー
https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC

ワイヤーフレーム
https://web-kanji.com/posts/making-wireframe#:~:text=%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%81%A8%E3%81%AF%E3%80%8C%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%9A%E3%83%BC%E3%82%B8,%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E3%82%82%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82

ポリゴン
https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%AA%E3%82%B4%E3%83%B3
Goで画像をクリップボードに保存、読み取るライブラリを作った

こんにちわ
ゴリラです

画像をクリップボードにコピー、コピーした画像をクリップボードから読み取るGoのライブラリ [clipboard-image](https://github.com/skanehira/clipboard-image) をつくったので紹介します。
このライブラリはMac、Linux、Windowsで動作します。

先日 [Goでソースコードを画像化するCLIを作った](https://qiita.com/gorilla0513/items/013aea9060bca1455137) で紹介したCLIではこのライブラリを使っています。

## 使い方
関数は2つのみ

- `CopyToClipboard`
- `ReadFromClipboard`

画像ファイルをクリップボードにコピーするときは `CopyToClipboard`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66178/598e7a39-59fc-fc35-9982-9093fefde5ff.png)

クリップボードから画像ファイルを読み取るときは `ReadFromClipboard`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66178/5c676cb6-5a69-70d6-4af2-0c5cc9e93178.png)

## 仕組み
クリップボードへのアクセスは外部コマンドを用いています。
それらをGoでラップしてライブラリとして提供しています。それぞれ次になっています。

| OS      | コマンド   |
|---------|------------|
| Mac OS  | osascript  |
| Windows | PowerShell |
| Linux   | xclip      |

Mac OSではApple Scriptを使えばクリップボードにアクセスできます。
Apple Scriptは標準でMac OSに入っているのでライブラリ意外は特に不要です。

```sh
# copy to clipboard
osascript -e 'set the clipboard to (read "/path/to/file.png" as TIFF picture)'

# write file from clipboard
osascript -e 'write (the clipboard as «class PNGf») to (open for access "/tmp/file.png" with write permission)'
```

WindowsではPowershellでクリップボードにアクセスできます。

```sh
# copy to clipboard
PowerShell -Command Add-Type -AssemblyName System.Windows.Forms;[Windows.Forms.Clipboard]::SetImage([System.Drawing.Image]::FromFile('/path/to/file.png'));

# write file from clipboard
PowerShell -Command Add-Type -AssemblyName System.Windows.Forms;$clip=[Windows.Forms.Clipboard]::GetImage();if ($clip -ne $null) { $clip.Save('/path/to/file.png') };
```

Linuxでは`xclip`というコマンドをインストールことでクリップボードにアクセスできます。

```sh
# copy to clipboard
xclip -selection clipboard -t image/png < /path/to/file.png

# write file from clipboard
xclip -selection clipboard -o > /path/to/file.png
```

これらのコマンドをGoの`exec.Command`で実行することで、Goでクリップボードにアクセスできます。

## 詰まったポイント
`xclip`を使う時、標準入力でファイルの中身を渡すのですが、次のように書いても標準入力に渡っていかないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66178/3a94a766-6962-8f61-181b-01500522f5e1.png)

標準入力に渡すには`StdinPipe`でpipeを取得してファイルの中身を書き込んだ後に stdin を閉じる必要あります。
`xclip`の実装は[atotto/clipboard](https://github.com/atotto/clipboard)を参考にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66178/14aae070-760d-9abb-af14-0ac5c9313aaf.png)

## さいごに
クリップボード周りは結構苦戦して、いろいろな方に質問してなんとか作れました。
ライブラリとしてはまだ完成形とは考えていなくて、今後も拡張していきたいと考えています。

ちなみに、この記事の画像はVimで書いたコードを[code2img.vim](https://github.com/skanehira/code2img.vim)でクリップボードにコピーしてサクッとQiitaにアップロードしたものです。
当初手軽にVimでコードを画像化したいという目的を達成できて、実際使って便利ので満足しています。

コードブロックが使えないチャットやTwitterといったSNSでコード貼りたいときにぜひCLIを使ってみてください。
Flutter×Firebase Timestampの日時情報を表示

#Flutter×Firebase　Timestampの時間表示

流れとしては、
①Firestoreのtimestampで時間取得
②そのtimestampをdatetimeに変更
③テキストとして表示



*①以下のコードでtimestampというフィールド名で時間取得*

```dart
Firestore.instance.collection('コレクション名').add({'timestamp': FieldValue.serverTimestamp()});
```

<img width="302" alt="スクリーンショット 2020-08-08 15.08.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536744/5bfd6f3c-880e-98f5-d474-18ed09d75371.png">


*②datetimeに変更*

```dart
final timeStamp = snapshot.data.documents[index]['timestamp'];
final d = timeStamp.toDate();
```
*③テキストとして表示*

```dart

Text(d.year.toString() + '/' + d.month.toString() + '/' + d.day.toString() + ':' + d.hour.toString() + ':' + d.minute.toString + ':' + d.second.toString())
```

<img width="113" alt="スクリーンショット 2020-08-08 15.10.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536744/8b13a2bc-e63f-5e05-e6d3-7628bb333501.png">
Rustで相互参照: ノーガード戦法編

RustはトレースGCを持たずRAIIと所有権に基づくメモリ管理を行います。これには様々な利点がある一方、**相互参照**をもつデータの扱いが他のプログラミング言語より難しいという困難があります。本記事では、あまり一般的ではないが**特定の限られた用途**では有用と思われる方法を紹介します。

## 標準的な方法

まずは相互参照が起きないように設計を再考するのがいいでしょう。特に「子データから親データを参照する」といったユースケースでは、必ずしも子データ自体が親データへの参照を持たなくてもいいことがあります。以下ではこれに当てはまらない例、典型的には**グラフ**の表現を念頭に置いて記述します。

Rustで相互参照を扱う最も標準的な方法は、[`typed_arena`](https://crates.io/crates/typed-arena)などの**アリーナアロケーター**と [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html)などの**内部可変性コンテナ**を組み合わせる方法です。これについては[私のブログ記事](https://qnighy.hatenablog.com/entry/2017/04/28/070000)などを参考にしてください。

また[Rustの `Arc` を読む (1)](https://qiita.com/qnighy/items/4bbbb20e71cf4ae527b9#%E5%AF%BE%E7%A7%B0%E3%81%AA%E5%BE%AA%E7%92%B0%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E8%A1%A8%E7%8F%BE%E3%81%99%E3%82%8B)ではArcとWeakを使った方法も説明しました。

## ノーガード戦法

Rustにおける相互参照が難しいのは、結局のところ**メモリやリソースの解放**の順番の問題に由来しています。たとえばアリーナアロケータは**個別に確保し、一括で解放する**ことによってこの問題を解決しています。

では、そもそも**メモリやリソースを解放しなくていい状況**であればどうでしょうか？「1プロセスでは1つの問題しか解かなくてよい」という割り切りが可能なのであれば、自身でリソースの解放処理を行わなくても、単にプロセスを終了まで持っていったほうが簡単です。その場合は単に**メモリリークを許容**することで簡単に相互参照を実現できます。

```rust
// ノーガード戦法による相互参照
// 意図的にメモリリークを行っているので、通常の用途では使ってはいけない

use std::cell::RefCell;

struct Node {
    id: i32,
    edges: RefCell<Vec<&'static Node>>,
}

impl Node {
    fn new(id: i32) -> &'static Self {
        // Box::leak を使うことで意図的にメモリリークを起こしている
        Box::leak(Box::new(Node {
            id,
            edges: RefCell::new(vec![]),
        }))
    }
}

fn main() {
    let node1 = Node::new(1);
    let node2 = Node::new(2);
    let node3 = Node::new(3);
    node1.edges.borrow_mut().push(node2);
    node2.edges.borrow_mut().push(node1);
    node2.edges.borrow_mut().push(node3);
    node3.edges.borrow_mut().push(node2);
    
    eprintln!("node1 has {} edges", node1.edges.borrow().len());
    eprintln!("node2 has {} edges", node2.edges.borrow().len());
    eprintln!("node3 has {} edges", node3.edges.borrow().len());
}
```

## FAQ

- メモリリークして大丈夫か？
  - 一般的には大丈夫じゃないです。が特定の場面では有用かもしれない、というのが本記事の意図です。
  - 「メモリリークを厳密に防ぐのは難しい」ということがLeakpocalypseと呼ばれる議論によってわかって以来、Rustではメモリリークは許容することになっています。メモリリークが起きても、それ以上の深刻な事象 (境界外参照やデータ競合などの未定義動作) は発生しないように設計されています。この意味で、メモリリークは「安全」という扱いになっています。
  - とはいえ、メモリリークは良いことではないので、意図しないメモリリークはできるだけ防ぐように設計されています。たとえば上記のプログラムでは `Box::leak` というメソッドを呼ぶことで明示的にメモリリークを起こしていますが、このようにプログラマーがメモリリークを意図しているとはっきりわかる方法をとらずにメモリリークを起こすのは簡単ではありません。
- `RefCell` は回避できないのか？
  - 理想の選択肢はないです。
  - [`Cell`](https://doc.rust-lang.org/std/cell/struct.Cell.html)を使えばランタイム検査を回避できますが、借用が使えなくなるのでトリッキーな操作が要求されるようになります。
  - RefCellで起こりがちな、意図しない二重借用によるパニックは[`qcell`](https://crates.io/crates/qcell)を使えば防げますが、ランタイム検査は依然として存在します。また、オーナーハンドルを持ち回す分コードが若干冗長になるかもしれません。
  - スレッド安全性が必要なら上記の `qcell` か、 [`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)/[`RwLock`](https://doc.rust-lang.org/std/sync/struct.RwLock.html) を使うことができます。
MQTTでPub/Subしてみる

今回はタイトルの通りMQTTを使ってみて、動作を確認するまでを行います。

### 目的
covid-19の影響で、イベントに参加する顧客が非接触で楽しめるコンテンツが無いか？という相談が増えています。弊社のインタラクティブコンテンツは、壁を触ったりガジェットを共有したりすることが多いのですが、各人のスマホを操作して何かを行う形であれば、体験共有型のコンテンツがより安全に楽しめるのでは？と考えました。その方法を模索する一環として、IoTの通信プロトコルとしてよく使用されているMQTTを使ってみようと思います。MQTTを使用して、例えば不特定多数の人がスマホからイベント会場の照明演出を任意に変更する、というように、スマホを操作デバイス化して面白い演出ができそうです。

---

### MQTTとは？
MQTT(Message Queueing Telemetry Transport)は、短いメッセージを複数のユーザー(publisher, subscriber)が頻繁に送受信することを想定して作られています([参照](https://kfep.jp/solution/iot-mqtt/mqtt))。その軽量さから、IoT実現に適していると言われています。

MQTTはPublish-Subscribe方式でメッセージを送受信します。Publisher(出版者)がBrokerにメッセージを送ると、購読登録をしているSubscriber(購読者)はこのメッセージを受け取ることができます。図にするとこんな感じです。
![mqtt_sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626158/924c743d-3e26-ec63-3211-cf355cbf8084.jpeg)
購読者は特定のトピックのみに購読登録することで、任意のトピックに限定してメッセージを受信することができます。

実際にMQTTブローカー(mosquitto)をインストールしてpub/subしてみます。

---

### 環境
PC: macOS Mojave ver.10.14.6

---
### mosquittoをインストールして動作確認

まずはmosquittoをインストールして動作確認まで行います。mosquittoは、MQTTプロトコルを実装したオープンソースのソフトウェアです([参照](https://mosquitto.org/))
ターミナルで以下のコマンドを実行します。

```
brew install mosquitto
```
インストールが完了したら、
以下のディレクトリにパスを通します(環境によって違うかもしれません)。
/usr/local/opt/mosquitto/sbin
/usr/local/opt/mosquitto/bin

ブローカーを立ち上げます。以下のコマンドのみで起動します。

```
mosquitto
```

#### Subscribeする
新しいウィンドウでターミナルを起動して、subscribeします。
🔔コマンドオプション： -d = バックグラウンドでブローカーを実行。 -t = topicの指定

```
mosquitto_sub -d -t topic/test
```

#### Publishする
さらに別のウィンドウでターミナルを起動してpublishします。
コマンド引数-mの後にメッセージを入れます(今回はkumaʕ •ᴥ• ʔkumaです)。

```
mosquitto_pub -d -t topic/test -m "kumaʕ •ᴥ• ʔkuma"
```
先ほどsubscribeした方のターミナルに「kumaʕ •ᴥ• ʔkuma」と表示されていれば正常に動作しています。

とっても簡単に使えるようになりました。
今回はMacの中で通信してみましたが、今後は別のデバイス間でメッセージのやりとりをしてみようと思います。
CentOS5でのTLS1.2対応（2020年7月版）

## Chromeで急にhttpsのWebサイトがブロックされた！
Chromeがアップデートされたのは気づいていたけれど、何気なく自分で保守しているサイトが、ブロックされることにきづいた。  
最初は意味が分からなくて、なんで！？となったが、画面に表示されるメッセージを読んでようやく理解した。
あ、TLS１.0で動いてるわ…。

## 対処方法を探す
原因はわかったので、対処方法を探す旅に。
該当サイトがCentOS5.10で動いているVPSなので、OpenSSLを上げないといけないことは調べてわかった。
が、OpenSSLって影響範囲デカくね？後、SSHも絡んでるんじゃない？
あれ？rpm入れ替える時にリモート繋がらなくなるんでは？
管理画面のコンソールはコピペできないからめんどいなぁ。

## 神はいた！
とりあえず、　rpm見つけてきてアップデートする対処法は見つけたので、
ついでにVirtualBoxで仮想環境作って、検証環境も整えておいたところで、
一旦１日置くことに。
明けて次の日、ある記事に目が止まる。

[CENTOS5のAPACHEをTLS1.2に対応させてみた](https://blog.denet.co.jp/centos5apachetls12/)

OpenSSLをソースからコンパイルして、既存のApacheの設定を変えるだって！？
これなら、影響範囲はApacheだけやん！
これですよ、欲しかった情報は！
神だ。神がいた！

というわけで、早速、仮想環境で試験。
作っててよかった検証環境。
[事前の調べ](http://dokuwiki.fl8.jp/01_linux/02_www/31_centos5_tls)で、
gccとgnutls-develのインストールがいることがわかったので、

```
yum install gcc gnutls-devel
```

するも、
2020年なんで、CentOS5の公式リポジトリはすでにEOLで繋がらない。
変更しないといけないことがわかった。（ここは流石にわかってたけどね。）

で、
[サポート切れの CentOS5 で yum を使えるようにする](https://qiita.com/Targityen/items/30f7ce886a396cfe46dd)
を読んで対応する。

これで、検証環境ではうまくいった。
よしよし。
いよいよ本番環境だ！

## 問題発生

リポジトリも変えて、

```
yum insall gcc
```
すると、

```
gcc-4.1.2-55.el5.x86_64.rpm
```
がないという
そんなばかな。

https://archive.kernel.org/centos-vault/5.10/os/x86_64/CentOS/
を直接見に行くと、

```
gcc-4.1.2-54.el5.x86_64.rpm
```
があった。
バージョン違うぞ⁉︎
少し悩んで、閃いた。
もしかして、と思って、
https://archive.kernel.org/centos-vault/5.11/os/x86_64/CentOS/
見に行くと、あった！

ということで、物は試し、
リポジトリを5.10から5.11に変更してみた。
※yumだから依存性解消しないとエラーになると信じてた。

```
yum install gcc gnutls-devel
```

で無事インストールできた。
そして、
OpenSSLも無事にmake installできました。
http.confも変更し、
ドキドキしながらの

```bash
/etc/init.d/httpd restart
```
何事もなく、起動した。

ブラウザで確認。
Chromeで警告が出ない！

念のため、Developer ToolsのSecurityタブで確認する。

```
Connection - secure connection settings
The connection to this site is encrypted and authenticated using TLS 1.2
```
やったね！


## 終わりに

```
cat /etc/redhat-release
```
で確認したディストリビューションとなぜかズレてるということで焦りましたが、なんとかなりました。
早くこのサーバを捨てれるように頑張ります。
手動テストのボリュームが多すぎつらい→急遽Seleniumにすがって半自動テストでしのいだ

自動テストのない自社サービスのメンテナンスやテストをしてます・・・

後輩「機能追加の実装完了しますた！」
ワイ「ご苦労！」
後輩「テストオネシャッス！」
ワイ「お、おう！」
ワイ「どれどれ、テスト仕様書見てみっか・・・」
テスト仕様書「100項目×4言語分あるやで」
ワイ「死あるのみ・・・」

さあどうする！？

ワイ「自動テストするやで」

とはいえ、納期もあることだし、すぐすぐに完全に自動テストはムリでしたが、
手動で値を入力してやるより、ずっと効率よくテストを消化することができました、という話です。
正直、時代遅れ過ぎてqiitaに投稿するのもおこがましいのですが、恥をしのんで恥をさらします。
pythonもほとんど初めてなのでもろもろヤヴァイと思いますがご容赦ください・・・

[operations-selenium](https://github.com/atchy/operations-selenium)

selenium経由でブラウザ上での一連の操作を`Opration`クラスのコレクションで保持して、順次実行していきます。結果は目視で確認、ということでどうかひとつ・・・

そうです、すでにもう、テスティングフレームワーク使えよ、って話です。

[webdriverio](https://webdriver.io/)

`PageObjetPattern`は強そう
自社サービスに是非とりいれよう、頑張れワイ！！！

以上です
日本語（カタカナ）をモーラ単位で分かち書き【Python】

#はじめに
日本語（カタカナ文字列）をモーラ単位で分かち書き（モーラ分かち書き）するpythonの関数を作りました。

|元文|モーラ分かち書き|音節分かち書き|
|---|---|---|
|ガッキューシンブン|ガ/ッ/キュ/ー/シ/ン/ブ/ン|ガッ/キュー/シン/ブン|
|アウトバーン|ア/ウ/ト/バ/ー/ン|ア/ウ/ト/バーン|

日本語の音韻の代表的な分割単位としてモーラと音節があります。モーラはいわゆる俳句の「５・７・５」を数えるときの区切り方で、長音（ー）、促音（ッ）、撥音（ン）も１拍と数えます。それに対し、音節では長音、促音、撥音は単体で数えられず、直前の単一で音節となれるカナと合わせてひとつの拍と見なされます。詳細は[モーラ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%A9)を御覧ください。

本稿ではモーラ単位での分かち書きのやり方を説明します。
音節単位での分かち書きについては下記で説明しています。
[日本語（カタカナ）を音節単位で分かち書き【Python】](https://qiita.com/shimajiroxyz/items/9580f185217fc9738f33)

#環境
- macOS Catalina 10.15.4
- python3.8.0

#方針
考えやすくするために、入力は記号を含まない全角カタカナの文字列とします。また、長音で表せるところは長音に変換されているものとします。これは例えば「ガッキュウ」は「ガッキュー」のように表現されているという意味です。

なお、漢字仮名交じり文を発音のカタカナ文字列に変換する方法は[別記事](https://qiita.com/shimajiroxyz/items/81452afdedaed767f436)にまとめましたので、もしよければ御覧ください。ただし、MeCabを使っていますので、辞書にない言葉は変換できません。

このとき、モーラの構成条件を下記のいずれかと定義します。

1. ウ段＋「ァ/ィ/ェ/ォ」
2. イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」
3.  「テ/デ」＋「ャ/ィ/ュ/ョ」
4.  上記以外のカタカナ１文字

これは

||正規表現|意味|
|---|---|---|
|①|[ウクスツヌフムユルグズヅブプヴ][ァィェォ]|ウ段＋「ァ/ィ/ェ/ォ」|
|②|[イキシチニヒミリギジヂビピ][ャュェョ]|イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」|
|③|[テデ][ャィュョ]|「テ/デ」＋「ャ/ィ/ュ/ョ」|
|④|[ァ-ヴー]|カタカナ１文字|

としたとき、`'(①|②|③|④)'`のように書けます。

#コード
```Python
import re

#各条件を正規表現で表す
c1 = '[ウクスツヌフムユルグズヅブプヴ][ァィェォ]' #ウ段＋「ァ/ィ/ェ/ォ」
c2 = '[イキシチニヒミリギジヂビピ][ャュェョ]' #イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」
c3 = '[テデ][ィュ]' #「テ/デ」＋「ャ/ィ/ュ/ョ」
c4 = '[ァ-ヴー]' #カタカナ１文字（長音含む）

cond = '('+c1+'|'+c2+'|'+c3+'|'+c4+')'
re_mora = re.compile(cond)

def moraWakachi(kana_text):
    return re_mora.findall(kana_text)

text = 'シンシュンシャンソンショー'
print(text)
print(moraWakachi(text))
print('')

text = 'トーキョートッキョキョカキョク'
print(text)
print(moraWakachi(text))
print('')

text = 'アウトバーン'
print(text)
print(moraWakachi(text))
print('')

text = 'ガッキュウホウカイ'
print(text)
print(moraWakachi(text))
```

出力は下記です。

```
シンシュンシャンソンショー
['シ', 'ン', 'シュ', 'ン', 'シャ', 'ン', 'ソ', 'ン', 'ショ', 'ー']

トーキョートッキョキョカキョク
['ト', 'ー', 'キョ', 'ー', 'ト', 'ッ', 'キョ', 'キョ', 'カ', 'キョ', 'ク']

アウトバーン
['ア', 'ウ', 'ト', 'バ', 'ー', 'ン']

ガッキュウホウカイ
['ガ', 'ッ', 'キュ', 'ウ', 'ホ', 'ウ', 'カ', 'イ']
```
日本語（カタカナ）を音節単位で分かち書き【Python】

#はじめに
日本語（カタカナ文字列）を音節単位で分かち書き（音節分かち書き）するpythonの関数を作りました。

|元文|モーラ分かち書き|音節分かち書き|
|---|---|---|
|ガッキューシンブン|ガ/ッ/キュ/ー/シ/ン/ブ/ン|ガッ/キュー/シン/ブン|
|アウトバーン|ア/ウ/ト/バ/ー/ン|ア/ウ/ト/バーン|

日本語の音韻の代表的な分割単位としてモーラと音節があります。モーラはいわゆる俳句の「５・７・５」を数えるときの区切り方で、長音（ー）、促音（ッ）、撥音（ン）も１拍と数えます。それに対し、音節では長音、促音、撥音は単体で数えられず、直前の単一で音節となれるカナと合わせてひとつの拍と見なされます。「バーン」のように長音、促音、撥音が連続した場合は３以上のモーラ数で１音節となります。詳細は[モーラ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%A9)を御覧ください。

本稿では音節単位での分かち書きについて説明します。
モーラ単位での分割については下記で説明しています。
[日本語（カタカナ）をモーラ単位で分かち書き【Python】](https://qiita.com/shimajiroxyz/items/a133d990df2bc3affc12)
#環境
- macOS Catalina 10.15.4
- python3.8.0

#方針
考えやすくするために、入力は記号を含まない全角カタカナの文字列とします。また、長音で表せるところは長音に変換されているものとします。これは例えば「ガッキュウ」は「ガッキュー」のように表現されているという意味です。
なお、漢字仮名交じり文を発音のカタカナ文字列に変換する方法は[別記事](https://qiita.com/shimajiroxyz/items/81452afdedaed767f436)にまとめましたので、もしよければ御覧ください。ただし、MeCabを使っていますので、辞書にない言葉は変換できません。

このとき、音節の構成条件を下記のように定義します。

【下記1-4と「ー/ッ/ン」の連続(0文字含む)文字列】
1. ウ段＋「ァ/ィ/ェ/ォ」
2. イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」
3.  「テ/デ」＋「ィ/ュ」
4.  上記以外の大文字カナ１文字

これは

||正規表現|意味|
|---|---|---|
|①|[ウクスツヌフムユルグズヅブプヴ][ァィェォ]|ウ段＋「ァ/ィ/ェ/ォ」|
|②|[イキシシニヒミリギジヂビピ][ャュェョ]|イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」|
|③|[テデ][ィュ]|「テ/デ」＋「ィ/ュ」|
|④|[アイウエオカ-ヂツ-モヤユヨ-ヲヴ]|①②③以外の大文字カナ１文字|
|⑤|[ーッン]*|「ー/ッ/ン」の連続文字列（０文字含む）|

としたとき、`'(①|②|③|④)⑤'`のように書けます。

#コード
```Python
import re

#「((ウ段＋「ァ/ィ/ェ/ォ」)|(イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」)|( 「テ/デ」＋「ィ/ュ」)|(大文字カナ))(「ー/ッ/ン」の連続文字列（０文字含む）)」の正規表現
c1 = '[ウクスツヌフムユルグズヅブプヴ][ァィェォ]' #ウ段＋「ァ/ィ/ェ/ォ」
c2 = '[イキシシニヒミリギジヂビピ][ャュェョ]' #イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」
c3 = '[テデ][ィュ]' #「テ/デ」＋「ィ/ュ」
c4 = '[アイウエオカ-ヂツ-モヤユヨ-ヲヴ]' #大文字カナ
c5 = '[ーッン]*' #「ー/ッ/ン」の連続文字列（０文字含む）

cond = '(?:'+c1+'|'+c2+'|'+c3+'|'+c4+')'+c5 #(?:)はサブパターンの参照を避けるカッコ
cond = '('+cond+')'
re_syllable = re.compile(cond)

def syllableWakachi(kana_text):
    return re_syllable.findall(kana_text)

text = 'シンシュンシャンソンショー'
print(text)
print(syllableWakachi(text))
print('')

text = 'トーキョートッキョキョカキョク'
print(text)
print(syllableWakachi(text))
print('')

text = 'アウトバーン'
print(text)
print(syllableWakachi(text))
print('')

text = 'ガッキュウホウカイ'
print(text)
print(syllableWakachi(text))
```

出力は下記です。

```
シンシュンシャンソンショー
['シン', 'シュン', 'シャン', 'ソン', 'ショー']

トーキョートッキョキョカキョク
['トー', 'キョー', 'トッ', 'キョ', 'キョ', 'カ', 'キョ', 'ク']

アウトバーン
['ア', 'ウ', 'ト', 'バーン']

ガッキュウホウカイ
['ガッ', 'キュ', 'ウ', 'ホ', 'ウ', 'カ', 'イ']
```
Relative Joint2Dの解説

今回はRelative Joint2Dの解説をします。
先に言っておくと、Fixed Joint2Dとは全然違う代物でした。

#Relative Joint2Dとは
Relative Joint2Dとは、オブジェクトどうしの相対位置や相対角度を**保とうとする**ジョイントのようです。相対関係を保とうと頑張りますが、常に保つことはできない感じです。
また、このジョイントの継承元はAnchored Joint2Dではなく`Joint2D`なので、Distance Joint2DやFixed Joint2Dとは違い、アンカーがありません。

#Relative Joint2Dの各パラメータ
![RelativeJoint2D_param.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/1f57ab46-02e4-8ffc-2ba4-803657f22ddd.png)
今回も多少省いて解説していきます。

###・Max Force
このオブジェクトに与えることができる最大の力を決めるパラメータです。相対位置を保とうとする力でもあるので、ここの値が高くなるとオブジェクトが動きにくくなります。
ちなみにBreak Forceがこのパラメータより高い値だと、破壊することができなくなるので注意してください。

###・Max Torque
このオブジェクトに与えることができる最大の回転力を決めるパラメータです。相対角度を保とうとする力でもあるので、ここの値が高くなるとオブジェクトが回りにくくなります。
ちなみにBreak Torqueがこのパラメータより高い値だと、破壊することができなくなるので注意してください。

###・Correction Scale
この値はよく分かりませんが、挙動がおかしいときにここの値をいじってみると改善されるのかもしれません。
Unityマニュアルには、Max ForceとMax Torqueと何らかの関係性があるような感じで説明されていました。

###・Auto Configure Offset
ここのチェックボックスにチェックを入れると下の２つのOffsetに自動的に値が入ります。
下の２つのOffsetの値を決めるのが面倒であれば使うことをオススメします。

###・Linear Offset
アタッチされたオブジェクトとの相対位置を決めるパラメータです。
値はアタッチされたオブジェクトのローカル座標になります。
何もアタッチしていなければワールド座標になります。

###・Angular Offset
アタッチされたオブジェクトとの相対角度を決めるパラメータです。
ここの角度の表し方は**`弧度法`**という一般ではあまり使われない表し方をするので注意してください。
一般的によく使われる「360°」で表されるアレは**`六十分法`**という表し方です。
ここに六十分法と弧度法の関係をいくつか紹介します。

*1°=π/180≒0.01745334*

*2°=π/90≒0.03490667*

*45°=π/4≒0.7853981*

*90°=π/2≒1.570796*

*180°=π≒3.141593*

*360°=2π=0*

よく見ると、弧度法も角度が倍になれば数値も倍になっていることが分かるでしょうか。
弧度法も六十分法と同じく直線的に大きくなっていくので、そこまで難しい表し方ではありません。
一番最後の*`360°=2π=0`*は、360°が0°なのと同じく2πも0と同じ、つまり一周したということです。
ちなみにこのパラメータは時計回りなので、実際には*`90°=-π/2≒-1.570796`*という風になります。

#使い道
Unityマニュアルにはアイテムやカメラを追従させる等に使えると書いていました。
このジョイントの最大の利点は`決められた位置から離れられる`ことであり、それによってより自然な動きでプレイヤーなどの動くものを追いかけられるところです。
なので、そういう追いかけさせたいものに使うといいかと思います。
注意点として、オブジェクトが決められた位置から離れると、両方のオブジェクトが引っぱり合うので、追いかけさせたいオブジェクトの質量は`軽くしておく`方がいいかと思います。

#おわりに
はじめはPhisics2Dについて勉強したくて、記事はついでのつもりだったんですが、最近は記事を書くために勉強してる感じになっています。でも記事を書くのは割と楽しいし、前よりPhisics2Dの魅力をより感じられるようになった気がするので結果オーライって感じですね。
次回はFriction Joint2Dについての記事を書きます。
matplotlibとcartopyでEarth風の流れのアニメーションを描く

次のようなEarth風(https://earth.nullschool.net/)
の流れのアニメーションをつくる。
![wind.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77672/646124e9-dda0-f15f-3a43-2ebbff5f5019.gif)

元の流れをベクトル(quiver)でプロットすると
![quiver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77672/372c4b9b-f3dc-6b9f-b5a7-a6456f789710.png)

元のプログラムは
https://github.com/rougier/windmap
から得て、それをCartopy(https://scitools.org.uk/cartopy/docs/latest/)
で地図上に落とせるようにした(ついでながら元のプログラムではアニメーションの動きが期待とは逆向きだったので符号などを逆転させた)。
作ったPythonコードのJupyter Notebookはgithubに置いた。
https://github.com/tmiyama/windmap

アニメーションの肝はカラーで、それがなければ一本の流跡線になる。カラーで白から黒に色を変える事で、点線のようにし、それを少しずつずらすことで流れていくようなアニメーションにしている。
revel(go)のアプリケーション環境を構築

goのアプリ開発するためのフレームワークがいくつかあります。
その中でも、revelがMVCの思想を深く取り入れているものの一つとされています。
本記事では、goをインストールしていない状態からrevelのアプリ起動までを行った際の手順を残していきます。

# 前提
brew がインストールされていることが前提です。

# brewをアップデートする
まず初めにbrewを最新のものにアップデートしましょう。

```
$ brew update
```

# goenvをインストールする
```
# goenvをインストール
$ git clone https://github.com/syndbg/goenv.git ~/.goenv
```

利用しているシェルに環境変数を設定する。

```~/.zshrc

export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
eval "$(goenv init -)"
```

設定が完了したら、シェルに反映させ、
goenvが利用できる状態になっているか確認します。

```
$ source ~/.zshrc
$ goenv -v
goenv 2.0.0beta11
```

## goをインストールする
goのインストールを進めましょう。
インストールするバージョンを確認しましょう。

```
$ goenv install -l
Available versions:
  1.2.2
  1.3.0
  1.3.1
　・
　・
  1.14.5
  1.14.6
  1.15beta1
```

今回は1.14.6をインストールし、インストールしたバージョンを反映させます。

```
$ goenv install 1.14.6
$ goenv global 1.14.6
$ goenv rehash
$ go version
go version go1.14.6 darwin/amd64
```

最後にgoをどこからでも利用できるようにパスを通します。

```~/.zshrc
export GOPATH=$HOME/go
PATH=$PATH:$GOPATH/bin
```

設定が完了したら、シェルに反映させましょう。

```
$ source ~/.zshrc
```

# revelをインストール
goのパッケージは次のコマンドでインストールすることができます。

```
$ go get [package name]
```

今回はrevelをインストールするので、次のコマンドを叩きます。

```
$ go get github.com/revel/revel
$ go get github.com/revel/cmd/revel
```

どこからでもコマンドを叩けるようにパスを通しましょう。

```~/.zshrc
export PATH="$PATH:$GOPATH/bin"
```

設定が完了したら、シェルに反映させ、コマンドが利用できることを確認しましょう。

```
$ source ~/.zshrc
$ revel --help
Usage:
  revel [OPTIONS] <command>

Application Options:
  -v, --debug                If set the logger is set to verbose
      --historic-run-mode    If set the runmode is passed a string not json
      --historic-build-mode  If set the code is scanned using the original parsers, not the go.1.11+
  -X, --build-flags=         These flags will be used when building the application. May be specified multiple times, only applicable for Build, Run, Package, Test commands
      --gomod-flags=         These flags will execute go mod commands for each flag, this happens during the build process

Help Options:
  -h, --help                 Show this help message

Available commands:
  build
  clean
  new
  package
  run
  test
  version
```

# アプリケーションを作成
フレームワークのインストールができたので、
アプリケーションの作成を行い、起動まで試してみましょう。

アプリ開発をする好きなフォルダーまで移動してください。
それからアプリ作成のコマンドを叩きます。

```
$ revel new -a myapp
Revel executing: create a skeleton Revel application
Your application has been created in:
   /Users/hoge/work/myapp

You can run it with:
   revel run -a  myapp
```

フォルダが作成されれば、そのフォルダまで移動し、起動してみましょう。

```
$ cd myapp
$ revel run -a myapp
```

起動できれば、`http://localhost:9000/`にアクセスし、次の画面が表示されれば完了です！
![スクリーンショット 2020-08-08 13.57.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348684/893de17d-93e1-a213-25b4-41a68f8cd1b7.png)

# 参考
https://revel.github.io/tutorial/gettingstarted.html
ラズパイのX端末化【大幅改訂版】

ラズパイを[X端末](https://ja.wikipedia.org/wiki/X%E7%AB%AF%E6%9C%AB) (`gnome-terminal` のような[端末エミュレータ](https://ja.wikipedia.org/wiki/%E7%AB%AF%E6%9C%AB%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF) ではなくてXサーバーだけが動作するコンピュータ)化する手順です。ラズパイ社が配るSDカードイメージを改造して作ります。昔と違って、サウンドもpulseaudio経由でちゃんと出ます。

# ラズパイ側準備
## ラスパイSDカードの下準備

1. https://www.raspberrypi.org/downloads/ からSDカードイメージをダウンロードし起動する。デスクトップ環境が含まれるSDカードイメージを選択すること。32bit版でも64ビット版でもどちらでもよい。
2. ネットワークへの接続（有線でも無線でもよい）とキーボードの設定などを行い普通に使えるようにする
3. ターミナル（など）から `sudo apt-get install pulseaudio` で PulseAudioパッケージをインストールする
4. 音を鳴らしたいなら、以下の作業に進む前に音が鳴ることを確認する。USB接続マイクスピーカーなども使え、録音もできます。

## XとPulseaudio自動起動ファイル作成

下記の２つのファイルを作る

```config:/mnt/etc/systemd/system/Xserver.service
[Unit]
Description=X server
After=network-online.target
Wants=network-online.target

[Service]
Type=exec
ExecStart=/usr/bin/Xorg -broadcast -keeptty -retro -listen tcp dpms vt7 v -allowMouseOpenFail -allowNonLocalXvidtune 
#Restart=always
Restart=no

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

次の`auth-ip-acl` にはウェブブラウザなどを実行する計算機のIPアドレスが含まれるように書く

```config:/mnt/etc/systemd/system/pulseaudio.service
[Unit]
Description=PulseAudio system server
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/pulseaudio --load="module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24" --daemonize=no --system --disallow-exit --disallow-module-loading=no

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

ラズパイのターミナルから `sudo systemctl set-default multi-user.target;` `sudo systemctl enable Xserver pulseaudio` を実行する

## IPv6 の禁止

[RaspberryPI のブートローダ読込時点で IPv6 を無効化する](https://qiita.com/p_cub/items/5c6bce6725c17aa17b9b) に従って、 `/boot/cmdline.txt` に`ipv6.disable=1` を追加する。ディスプレイマネージャにgdmを使うときはこれをやるとうまく動作しないかも知れない…

# ウェブブラウザなどのXクライアントを実行する計算機の設定
GDM や LightDM の設定は [gdm, lightdm の XDMCP 設定](https://qiita.com/kakinaguru_zo/items/9503b6f7c8b868a50e77) を参照。

## リモート PulseAudio サーバーの設定

これだけだと音が出ないので、ウェブブラウザなどを実行する計算機から音声をラズパイに送るように、を下記のファイルを設置することで指示する。ラズパイがいるネットワークアドレスが `192.168.1.0/24` ではない場合は以下の当該部分を適切に変更する

```shell:/etc/X11/Xsession.d/10remote-pulseaudio
if echo $DISPLAY | grep -q "^192.168.1.[0-9]*:[0-9]"; then
  #unset DBUS_SESSION_BUS_ADDRESS
  PULSE_SERVER=`echo $DISPLAY | sed 's/:.*$//'`
  export PULSE_SERVER
fi
```

# Could not acquire name on session bus
というメッセージがMATEで出るときには上記の`/etc/X11/Xsession.d/10remote-pulseaudio` のように`unset DBUS_SESSION_BUS_ADDRESS` する。このメッセージは、キーボードとリモートホストの両方から同時にログインしようとしたときに生じるが、そういう使い方は基本的にサポート外だと思われる…

[OpenBox](https://packages.debian.org/sid/openbox) はキーボードとXDMCPからの同時ログインで一応動作する。

# ラズパイX端末の電源の切り方など

`CTRL + ALT + ファンクションキー` でログインプロンプトが出てくるので、ユーザー `pi` でログインして `sudo systemctl poweroff` などとする。`sudo apt-get update; sudo apt-get dist-upgrade` でインストール済みのラズパイLinuxカーネルやXサーバーなどの更新もできる。