OmniAICreator/Qiita-1.07M huggingface dataset:
csh(tcsh)で気をつけるべきこと

csh(tcsh)はあまり評判が良くないと言われていますが、それでもcsh(tcsh)を使うという時に役立てればと思います。よく忘れがちなことを並べました。これから書き足すかもしれません。

##set文
1.setのすぐ後ろはスペースを入れる
2.=の前後もスペースを入れる
3.宣言する変数はアルファベットから始める(「_」など、一部の記号は最初でも大丈夫)

*エラーメッセージ*
`set: Variable name must begin with a letter`
=の前後にスペースが空いていない。
変数名がアルファベットから始まっていない。

##if文
1.論理演算子(==や&&など)の前後はスペースを入れる
2.条件の次はthenが付き、最後にendif
3.ifのネスト(入れ子)はしない方がいい(2019.3.7追記)
　＊ifの後ろとthenの前にスペースを入れると正常に動作することが多いようだ。環境次第だが、筆者のネストが正常に処理されない環境でも正常に処理された。(2019.5.19追記、Twitterにて提案があり、確認しました。ありがとうございました。)
　＊cshではブロックがはっきりしないせいか、最初のifがfalseで処理されなくても、次の入れ子のifの中が処理されてしまうようだ。奇妙な書き方になるがswitchを用いるとネストができる。trueかfalseかを判定させる条件分岐の時は、先にそれをifで変数にしてswitchを導入する。

```
#!/bin/csh
#ifを入れ子にしたときの例
set year = 2019
if($year % 4 == 0)then
    echo "#"
    if($year % 100 == 0 && $year % 400 != 0)then
        echo "##"
        echo "うるう年ではありません。100の倍数は例外的です。"
    else
        echo "###"
        echo "うるう年です。"
    endif
else
    echo "####"
    echo "うるう年ではありません。"
endif

```
これだと、実行した時に次の結果が出る。

```
###
うるう年です。
```
回避法は例えば以下のようにできる。

```
#!/bin/csh
#ifを入れ子にしないようにした時の例
set year = 2019
if($year % 4 == 0)then
    echo "#"
    set four = 1
else
    echo "##"
    set four = 0
endif

switch($four)
case 1:
    if($year % 100 == 0 && $year % 400 != 0)then
        echo "###"
	echo "うるう年ではありません。100の倍数は例外的です。"
    else
        echo "####"
	echo "うるう年です。"
    endif
    breaksw
case 0:
    echo "#####"
    echo "うるう年ではありません。"
    breaksw
endsw
```
これならば、結果は以下の通りとなる。

```
##
#####
うるう年ではありません。
```

*エラーメッセージ*
`if: Badly formed number.`
`if: Expression Syntax.`
条件で論理演算子の前後にスペースが入っていない。

これは、条件で論理演算子の前後にスペースを入れていないために出ることがある。


##while文
1.if文と同じく、論理演算子の前後はスペースを入れる
2.終端はend
3.終端の前に条件に使う変数の演算を入れる(時々忘れる)

*エラーメッセージ*
`Directory stack not that deep.`
条件式で論理演算子の前後にスペースが空いていない。(知らないとどハマりしそうなエラー)

##switch文
1.項目ごとの終端はbreaksw(独特な終端)
2.終端はendsw(これまた独特な終端)

##awkコマンド
1.条件や処理は' 'でくくる。
2.変数は' 'の外側になるようにする(↓例)
`awk '('$number'==1){print $1}' data.txt`
＊コマンドの条件に関しては論理演算子の前後にスペースを入れなくても良い

#その他#
1.最初に#!/bin/cshと書く
pythonでコンフィグ情報からネットワーク図を書くために



Interface Descriptionがプロジェクトの財産になる日
https://www.janog.gr.jp/meeting/janog41/application/files/3615/1723/1065/janog41-sp06if-miyazaki-04.pdf

プログラミングの勉強として成果物を出したかったので
↑を作ってみたかった。


#前提
　・the初心者な内容ですがあしからず
　・pythonの勉強として作りました
　・コンフィグからホスト名と対向先を取るだけの内容
　・コンフィグは事前にあるものとします
　・もっと簡単にできる。ってのがあれば教えてほしいです。


#環境
　・Mac sierra
　・python3.6

#内容
機能としては
　コンフィグのテキストを読み込んで
　ホスト名と対向先ホスト名を抽出→リストへ格納
　リストをJSON形式で書き出す
というイメージです。

　正規表現のところはアレがそれなのでお察しください。
 　 色々いじってできたので変数は雑です・・・


```python

#! python
import re,json

# 格納先を用意
node_list = []
link_list = []

#フォルダのログをすべて読み込む
for log_read in os.listdir('.'):
    if not log_read.endswith('.txt'):
        continue
    print ("コンフィグ" + log_read +"を読み込んでいます")
#１行ずつリストに格納する
    with open(log_read) as f:
        lines = f.readlines()
#端末名とDescriptionを探す
        host = [line for line in lines if "hostname" in line]
        des = [line for line in lines if "description" in line]
#正規表現化
        x = str(des)
        host = str(host)
        des_name = re.findall(r"description (正規表現）",x)
        host_name = re.findall(r"hostname (正規表現）",host)
        #ホスト名だけ弄る
        host_rename = ",".join(host_name)
        host_name2 = {"name":host_rename}
        node_list.append(host_name2)
        #対向先をリストに格納
        for DC in des_name:
            node = {"name":DC}
            link = {"source":host_name2,"target":DC}
            node_list.append(node)
            link_list.append(link)
            node = sorted(node)
            full = {"nodes":node_list,"links":link_list}
            
#JSONファイルへ書き出す
    with open('show-net.json', 'w') as u:
        json.dump(full,u, indent=4, separators=(',', ': '))
    f.close()
print ( "完了")

```

あとはJSONファイルを読み込ませてブラウザで確認するだけ。

#結果
　きちんと動いていたけどDescriptionの記載の有無とパターンがバラバラで
　整理されていなかった（プログラム以前の問題）
　
　→よって、　全く線が引けてなかった・・・という残念なオチ

　でも思ったとおり動く物ができるといいですね。
　すごく勉強になりました。

#参考
inet-henge で、好みのネットワーク図を描くヒント
https://codeout.hatenablog.com/entry/2018/04/02/232327

Pythonでファイルの読み込み、書き込み（作成・追記）
https://note.nkmk.me/python-file-io-open-with/

オンラインで正規表現をテスト
https://qiita.com/ken1ma/items/85d9a35e9a4f18587eeb
これからスクラムをやる・参考にするというときに確認しておきたいこと

社内で大きなチーム再編などがあり、表題の内容で需要がありそうだったので、自分のこれまでのスクラムマスター（あるいはそれに近いロール）をやってきての経験を踏まえて、「初めてスクラムを取り入れる（あるいは参考にして開発サイクルを組み立てる）」というフェーズで確認したいことをまとめてみようと思いました


# 始める理由を確認する

当たり前のようで大切なことですが、「どんな課題を解決したくてプラクティスを取り入れるのか」を **関係者全員で** 確認し、それを記録に残しておきましょう

要は、「**なぜこれからスクラムをやるのか**」です

大切なのは、「解決したい課題」と「そのための手段」を全員がきちんと認識していることです
この認識がそろっていないと、メンバーの納得感がないまま始まってしまって不満につながったり、スクラムなどのフレームワークをキャッチアップするのにも前向きになれないリスクに繋がります

実際に自分がメンバー、またはスクラムマスターとしてスクラムをやったプロダクトでは、そこを上手くやれていなかった結果として、一定数のスクラムへの苦手意識を持った人が出てきてしまったと感じています（これは自分の反省点）


他にも、例えば「スクラムを取り入れてみたけどうまくいっていない気がする」という状態になったときに、取り入れたタイミングに立ち返って考えることができなくなってしまうこともあり得ます


きちんと関係者が何故やるのかをはっきりさせた状態で始めましょう

# これまでのやり方の背景を確認する

これはチームのメンバーが発足からずっと同じでない場合に特に大事なことですが、これまでこうなっていた背景・理由を確認し、それを記録に残しておきましょう

これは、「**なぜ今こうなっているのか**」です

今こうなっているというのにも必ず理由があるはずです。
今までやっていたことは、どんなことを解決しようとした結果今の姿になったのか？
今のチーム・プロダクトはどんな風にモノを作っていきたいのか？

それをしっかり認識した上で、「それでもやる」という判断をしたのだ、という意識を持てるようにしましょう
過去にこういう失敗があったから止めとこう、というのも有りだと思います

また、過去を振り返ることは、古くからいるメンバーが納得感を持つことにも繋がります
これまでのことを無視して新しいことをやるんだ、と持ちかけても「あのときこういうことがあったから今こうなってるんだけどなあ・・・」と思っていては腹落ちはしにくいものです
（もちろんそう思ったのならぜひ声を上げて議論すべきだと思います。が、それが出来る人ばかりではない）

今までこうなっていた理由をきちんと把握しておきましょう

# 振り返る

言うまでもないことですが、**振り返りましょう**　（これは始まったあとの話になっちゃいますが）

何故やるか？そして、これまでどうだったか？を記録に残してあるはずです
この情報と、実際に回したスプリントの実績を元に、「最初に持っていた課題感は解決したか？」を確認しましょう

当然、課題感が解決しそうにないのであればやり方を変えていくべき、という話になりますし、上手くいっているのであればKEEPする、となるでしょう
解決したい課題を元に取り入れた「手段」が上手くいったかを振り返って次に活かしましょう


---

以上、これからスクラムをやる・参考にするというときに確認しておきたいことでした
これからスクラムを取り入れたりする際に参考になればこれ幸いです
アルゴリズムの基礎1

# 概要

大学時代に受けた"データ構造とアルゴリズム"という講義を元に執筆しようと思う。誤字脱字や間違いなどあれば指摘いただければありがたい。

# 用語の定義

直近で使う用語の定義をする。

## 問題とは

問題とは、入力と(入力を処理して望まれる)出力のペアである。入力となるパラメータは有限長とする。各パラメータに対して問題例が一つ定まる。

**例1: GCD (最大公約数)**
入力: 2つの非負整数 $x, y$
出力: $gcd(x, y)$

問題例: $(x, y) = (5, 12)$

**例2: 最小値**
入力: 非負整数 $n$ および $n$ 個の非負整数 $a_1, a_2, \cdots, a_n$
出力: $a_1, a_2, \cdots, a_n$ の最小値

問題例: $(n, a_1, a_2, \cdots, a_n) = (3, 4, 6, 1)$

## アルゴリズムとは

アルゴリズムとは、有限ステップで停止することが保証(証明)され、任意の問題例に対して常に正しい答えを出力していることが保証(証明)されている計算手続きである。
※前者だけをアルゴリズムの要件とし、後者をアルゴリズムの正当性と呼ぶこともあるが、ここでは両方を満たす時とする。

**例1: GCD**
最大公約数の問題を解くアルゴリズムとして、世界最古のアルゴリズムと呼ばれているユークリッドの互除法がある。

問題例: $(x, y) = (5, 12)$ に対する動作
12 を 5 で割った余りは 2
5 を 2 で割った余りは 1
2 を 1 で割った余りは 0
余りが 0 になったら終了でその前の余り 1 が 5 と 12 の最大公約数となる。

PHP でのコードは下記のようになる。

```php
function gcd($x, $y){
    return $y === 0 ? $x : gcd($y, $x % $y);
}
```

**例2: 最小値**
与えられた数値の中から最小値を求めるというよくある問題。
色々と解き方があるが、一例として下記のように解ける。

```php
function min(array $elements){
    $last_element = array_pop($elements);
    if (empty($elements)) {
        return $last_element;
    }
    
    $min_tmp = min($elements);
    return $min_tmp < $last_element ? $min_tmp : $last_element;
}
```

それらがアルゴリズムであることの証明は次回する。
Twitter自動フォローツール

Twitter自動フォローツールを作成しました

特定分野のユーザをたくさんフォローしたかったのですが、一日のフォロー制限はフォロワーの3倍といわれているため、フォロワーの少ない僕は凍結を恐れました。なのでフォロワーを増やす必要がありました（フォロワー3倍説はうわさです）

まずはTwitter名に"相互"と記載されているユーザを片っ端からフォローしてやろうと思ったのですが、手動だと疲れるためスクリプトを書きました

起動条件としてはPC限定でスマホでは使用できません

またとりあえず動かすことを優先したためバグだらけです。誰か直してください

以下、手順です
>
1. 以下のautofollow.jsをブックマークに保存する
2. Twitter検索欄で"相互フォロー"と検索する
3. "相互フォロー"と名前のついたユーザのフォロワーページにいく
4. ブックマークをクリック
5. アラートが表示されたら、閉じて再度ブックマークをクリック（何度かやらないとフォローできません）

詳しくはブックマークレットでググってください

3のフォロワーページはココです
![スクリーンショット 2019-01-09 23.38.47.png](https://qiita-image-store.s3.amazonaws.com/0/340410/9065bcaf-efbc-92e0-023e-7a25a7b659d4.png)

以下、スクリプトです

```autofollow.js
javascript: (function() {
    var $accountElem = $('.ProfileCard-content');
    var $username = $('.ProfileCard-content .fullname');
	var accountElemCount = $accountElem.length;
	var index = 0;
	var followCount = 0;
	var protectedCount = 0;
    var followedCount = 0;
        
    var manager = function() {
		if (index < accountElemCount) {
			if (notFollowing($accountElem.eq(index))
                    && protectedCheck($accountElem.eq(index))
                    && followCount < 300
                    && $username.eq(index).text().indexOf('相互') != -1) {
				performer($accountElem.eq(index));
			} else {
				index++;
				manager();
			}
		} else {
			alert('フォロー処理が完了しました。\n■実行結果\n-----------------------------------------\n表示件数：'
					+ index
					+ '\n新規フォロー：'
					+ followCount
					+ '\n鍵（フォローしない）：'
					+ protectedCount
					+ '\nフォロー済み：'
					+ followedCount
					+ '\n-----------------------------------------\n');
		}
	};
	var performer = function($elem) {
		var rand = (Math.floor(Math.random() * 2000)) + 100;
		setTimeout(function() {

			$('.UserActions .not-following button.follow-text', $elem).trigger(
                    'click');
                    
			followCount++;
			index++;
			manager();
		}, rand);
	};
	var protectedCheck = function($elem) {

		if (!$('.UserBadges .Icon--protected', $elem).length) {
			return true;
		}
		protectedCount++;

		return false;
	};
	var notFollowing = function($elem) {

		if ($('.UserActions .not-following', $elem).length) {
			return true;
		}
		followedCount++;

		return false;
    };
    id = setInterval(function(s){scrollBy(0,s||100)},1);
    setTimeout(function(){
        clearInterval(id);
        manager();
    },10000);
})();
```


とにかくやりたいことは"相互"と名前のついたユーザを指定ユーザの数だけフォローすることです

スクロール型の仕様は詳しくないのですが、↓スクロールすると内部的には↑に流れていくTLは消え↓から出現するTLのソースが生成されると聞いたことがあります

setTimeoutやsetIntervalで適当な時間を定めていますが、スクロール幅とフォローのタイミングがポイントのはずです

あとは任せました！
Lightning Web Components（イベント）

###コンポーネント作成時のイベント
コンポーネント作成時に呼び出されるイベントは次の4つ。

| イベント|説明 |   
|:--|:--|
| constructor        | コンポーネントが作成された直後に発生する。通常は使用しない      
| connectedCallback  | 標準的な初期化処理はここで行う。    
| renderedCallback   | コンポーネントへの描画（DOM操作）が終わったタイミングで呼び出される
| errorCallback   | コンポーネント処理中にエラーが発生した場合に呼び出される
#### connectedCallback() コンポーネントの初期化イベント

通常の初期化処理はconnectedCallback()メソッドに実装する。constructor()メソッド呼出時点では属性に値がセットされていないことに注意する。

```js
import { LightningElement } from 'lwc';
export default class aSampleComponent extends LightningElement {
    /*
     * 初期化処理
     */
    connectedCallback() {
        // 初期化用のコードを実装
    }
}
```

#### errorCallback エラー処理用のイベント
コンポーネント処理中にエラーが発生した場合に呼び出される。オプションなので、必要に応じて実装する。

```js
import { LightningElement } from 'lwc';
export default class aSampleComponent extends LightningElement {
    /*
     * エラー処理
     */
    errorCallback(error, stack) {
        // エラー処理のコードを実装
    }
}
```
npx create-nuxt-app でエラー

Nuxt.jsのcreate-nuxt-appをインストールする際、 ``` npx create-nuxt-app ``` を実行するとエラーがおきてしまったので、対策方法を忘れないうちに。

## 環境
- windows 10
- git Bash
- node.js v10.15.0
- npm v6.4.1

## 原因
↓エラーコード　※一部抜粋

```
Error: EPERM: operation not permitted, mkdir 'C:\Users\User'
```
npxのGitを確認。
同じようなエラーがおきてる人が質問してました！ 
[Error: EPERM: operation not permitted, mkdir 'C:\Users\Foo'](https://github.com/zkat/npx/issues/100)

どうやらディレクトリ名にスペースがあることでエラーになっているっぽい。
なぜ空白があるとエラーになるかは不明です・・・

```
C:\Users\User Name\ ←　「User Name」に空白あるのでエラーになった
``` 

## 解決方法
[Error: EPERM: operation not permitted, mkdir 'C:\Users\Foo'](https://github.com/zkat/npx/issues/100)
この質問に対して、解決策を提案してくれてましたー

> I was able to fix this in Windows by creating a directory junction to my users folder that didn't have a space in it. You can run a command like this in an administrative powershell:
> 
```
> cmd /c mklink /J "C:\Users\myname" "C:\Users\My Name"
> You can then use this junction as if it were your real user directory:
> 
> npm config set cache C:\Users\myname\AppData\Roaming\npm-cache
> npm config set prefix C:\Users\myname\AppData\Roaming\npm
```
> (the above should update your user .npmrc file)

実際に同じように、シンボリックリンクを作成。
npmのパスを変更して``` npx create-nuxt-app ``` を実行するとインストールしてくれました！

ただ、その後に「\Users\myname」までのパスがディレクトリ名になった謎のディレクトリが生成されてました…

## 2019/01/10 追記
謎ディレクトリ問題が解決しないので、npxをあきらめてyarnでパッケージをインストールし直しました。
DynamoDBで"The provided starting key does not match the range key predicate"とエラーが出た

なんかphpでaws-sdk-php経由でDynamoDBを叩くと"The provided starting key does not match the range key predicate"とエラーが出る。
条件式の「ExclusiveStartKey」が間違っていたのが原因だった。
ループで回してる箇所で初期化されてないために前回の条件を引き継いでしまっていた。
ムシャクシャしてunset()してやった。
正規表現

#ポート番号
## 数字(0～65535)で先頭の0は許可しない
^([0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$

## 数字(000000～65535)で先頭の0を許可する
^([0-9]|[0-9]{1,4}|[0-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
Angular で作った Web サイトをリロードすると 404 (Not Found) エラーになる時の対策

## 概要

Angular 6 で作った Web サイト、サーバにデプロイして外部からアクセスし、リロードボタンを押したら「Not Found」と 404 エラーが返ってきた時に、どう対応すればいいかの備忘録。
※ ごく簡単な対応のため。全ての対策が書かれているわけではありません。より良い対策があればそちらを共有ください。

## 事象

Angular6 でサクッと構築した Web アプリを、[GCP](https://cloud.google.com/) の [GCE](https://cloud.google.com/compute/) で立てたサーバにデプロイした。

`http://独自ドメイン/` でアプリのトップページに飛びページリロードしたら「Not Found」と表示されて画面遷移できなくなった。（もちろん、トップページに遷移し直せば、通常通り使用できる。）
また、リロードだけでなく、URLのルート以降のパスを追加・変更し Enter キーを押した時も「Not Found」になる。

しかし、ローカルで `ng serve` で動かしているときは、リロードしても同じ事象は発生しない。。。

## 原因

結論から言えば、Angular で作った Web アプリは、ルートにしか index.html が存在しないため。

つまり、ルート以外のパスを直接指定されても、そんな HTML ファイルは存在しないので、存在しない Web ページをリクエストされたら、当然 404 (Not Found) となる。

Angular は、トップページの時点で、ルート以降に何かしらのパスが存在しているはずである（`/home` など）。
この状態でページリロードしたときは、　前述の理由通り、HTML がそのパスには実在しないので、「Not Found」となる。URLを直指定した場合も同様の理由である。

##### そもそも Angular はルートに index.html しかないのに、なぜURLが変わるのか？

Angular がデフォルトで HTML5 の「History API」という機能をしようしているためである。

そもそも、History API とは、以下の様な機能を持った API である。

- 画面を遷移せず、履歴に新たなURLを発行・追加する。
- 現在のページの履歴を変更する。
- ブラウザの戻る・進むボタンをクリックしたときにイベントを検知する。

Angular は、表示するコンポーネントを切り替えながら、この History API を使ってURLを変更しているのだけなので、実際に HTML を移動しているわけではない。

ちなみに、構成によるが、通常の構成であれば、React や Vue でも同様の事象は発生する。

## 対処法

### 対策１： URL にハッシュ（#）を導入する（アプリ側での対応）

ハッシュ付きURLを有効にする。
有効化すると、アドレスが `http://独自ドメイン/#/home` → `http://独自ドメイン/#/home` の様に変化する。

Angular の場合、Angular Router の Use Hash オプションを有効にするだけ。

```ts:app-routing.module.ts
@NgModule({
  imports: [RouterModule.forRoot(routes, {
    useHash: true, // 追加
  })],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```

### 対策2： Web　サーバのルート修正で対応する（Web　サーバ側での対応）

単純な catch-all フォールバックのためのルートをサーバー側で追加し、もし URL がどの静的なアセットにもマッチしなかった時は、アプリケーションが動作しているのと同じ index.html ページで受け付けるように設定あを行うだけ。

`ng serve` でリロードしても大丈夫なのは、`ng serve` 実行時にこの方式が採用されているから。

各 Web サービスの設定変更内容は以下のとおり。

##### Apache 設定

```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
```

##### Nginx 設定

```nginx
location / {
  try_files $uri $uri/ /index.html;
}
```
##### Native Node.js　設定

```js
const http = require('http')
const fs = require('fs')
const httpPort = 80

http.createServer((req, res) => {
  fs.readFile('index.htm', 'utf-8', (err, content) => {
    if (err) {
      console.log('We cannot open "index.htm" file.')
    }

    res.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8'
    })

    res.end(content)
  })
}).listen(httpPort, () => {
  console.log('Server listening on: http://localhost:%s', httpPort)
})
```

##### Firebase ホスティング

以下を、`firebase.json` に追加。

```json-doc
{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

### 対策3： SSR を導入する

[日本語公式ドキュメントのサーバサイドレンダリングの記事](https://angular.jp/guide/universal) などを参考に Universal にする。

以上。
STM32シリーズでSWDから操作できなくなった時の対処法

# 概要
STM32シリーズにはDFUがあり、Boot0/1に対応するピンを適切な入力に設定する事で強制的にDFUから起動させる事ができます。一方で、Option Bytesの設定によりBoot0/1の値を上書きし、DFUを殺すこともできます。この場合SWDから接続しない限り今後一切のデータ変更ができなくなります。この状況でSWDが動かなかった場合の確認事項・対処方法などをまとめてみました。

# 原因と対策
## SWDIO/SWCLKピンが外部から制御不能
回路的な問題でSWDIO/SWCLKに該当するピンが他のICなどによりドライブされていると、プログラマーからのSWDIO/SWCLK信号が正しく伝わらないためにターゲットデバイスが認識できなくなります。Pull-up/downなら問題ありません。

ドライブ元のチップをリセットなりでハイインピーダンス状態を出すようにしてやるか、最悪チップを外すか配線をカットするなどの対処が必要です。

そもそもこれらのピンを別の用途で利用しているとSWDIO/SWCLK経由でのステップ実行やメッセージ出力ができないので、このような問題が起きるのはGPIOが致命的に足りていない状況に限られるでしょう。

## リセットがうまく入っていない
SWDIO/SWCLKピンが別の用途で利用されているなら、当然これらのピンは起動直後にGPIOとして再アサインされているはず。この状態ではSWDからの制御はききません。ハードウェアリセットを併用してGPIOに切り替わる前にSWDからの制御を開始する必要があります。正規のプログラマーを使っていればリセットも適宜制御してくれるので問題ありませんが、安価なST-LINK互換機やリセット信号のないプログラマーなどを使っていると問題になります。

対策としては、STM32CubeProgrammerでMode: Normal, Reset mode: Hardware resetの設定にし、ターゲットデバイスを手動でリセット開始、Connectボタンを押して接続を開始しデバイス待ち状態に入ってから手動でリセット解除する事で制御を奪う事ができました。緊急回避には良いかもしれませんが開発中の手順としてはいささか面倒です。

# それでもSWDIO/SWCLKピンを使いたい場合
## 初期状態でピンを開放する
入力になっている場合には外部のドライブしているICをリセットするなり無効化するなりの対処が必要。出力になっている場合には、起動直後しばらく待ってからGPIOを有効にする、アイドル状態ではSWDIO/SWCLKに戻す、などの対処が有効。

## DFUを強制起動するための口を用意しておく
特定の操作をした際にDFUにジャンプするようなコードを用意しておくと安心。デバイス毎のDFUのアドレスは公式資料「AN2606: STM32 microcontroller system memory boot mode」に書かれています。直接ジャンプするのではなく、メモリになんらかの印をつけてソフトウェアリセット、初期化シーケンスの最初期に印を見つけたらDFUに飛ぶような処理を書きます。初期化シーケンスはweak referenceで用意されている__initialize_hardware_earlyという関数を上書きすればよく、例えばSTM32F04系なら

```c
int boot_to_dfu = 0;

void __initialize_hardware_early(void)
{
  if (boot_to_dfu) {
    boot_to_dfu = 0;
    ((void (*)(void))0x1fffc400)();  // STM32F04系固有のアドレス
  } else {
    SystemInit();
  }
}

...
  // DFUを起動したい箇所にて
  boot_to_dfu = 1;
  NVIC_SystemReset();
...
```

として置けばソフトウェアリセットからDFUモードへの移行を実装できます。他にもDFUへリセットするかわりにSWDピンの設定を元に戻す、あるいは特定の操作を定義するのが難しい時は起動時にboot_to_dfuを常時flipするようにして外からリセットをかけたらDFUモードへ移行する、などの工夫があるかと思います。USBとして動作しているならDFUモードへ移行するバックドアを仕掛けることは比較的簡単かと思います。

# おまけ
## そもそもBoot0/1ピンを無効化するには
SWD用のピンを再利用するよりはまずBoot0/1だけを再利用した方が安全だし引き続きデバッグ機能も使えます。Pull-up/downさえ適切に設定できるならそのままBoot0/1ピンを再利用できますが、外部Pull-upが必要だが最終的にはDFUを起動させたくない、といった場合にはOption Bytesというフラッシュメモリ上のデータ書き換えてピンを無効化できます。プログラム中から書き換える事もできるようですが、通常はプロテクトがかかっており特定の手順を守らないと上書きできません。STM32CubeProgrammerから書き換えるのが楽かと思います。

STM32CubeProgrammerを起動したら左側の上下にアイコンがならんでいると思いますが「OB」と書かれたアイコンがOption Bytesを書き換える機能へのリンクです。User Confugurationの中に

- nBOOT0
- nBOOT1
- BOOT_SEL（またはnSWBOOT0/1）

といった項目があるはず。詳しくは説明が書かれているはずですが、STM32F04系を例にすると、BOOT_SELのチェックを外すと、BOOT0ピンを殺してnBOOT0の設定値を使うようになります。nから始まる設定項目は極性がピンとは反対なので注意。このあたりもAN2606にデバイスごとの説明があります。

## SWDからprintf
プロジェクト設定「C/C++ Build > Settings > Tool Settings > MCU GCC Linker」以下の

 - 「Libraries > Libraries (-l)」に「rdimon」を追加
 - 「Miscellaneous > Linker flags」に「 -specs=rdimon.specs」を追記

デバッグ設定「Startup > Initialization Commsnds」に「monitor arm semihosting enable」を追加

mainの最初に以下の初期化コードを入れる。

```c
extern void initialise_monitor_handles();

int main(void)
{
  initialise_monitor_handles();
  ...
}
```

以上でprintf系の関数の出口がSWD経由になるはず。リリースビルドからは消さないとSWDにメッセージを送るタイミングでハードウェア例外に捕まって死ぬと思う。

# まとめ
以上、SWDが機能しなかった場合の対処方法についてまとめつつ、問題のBoot0/1ピンの無効化方法やprintf周りの設定についてもおまけで紹介しました。
Lightning Web Components（HTML）

####変数の参照
jsファイル内に定義した変数やgetterを参照可能。
Auraコンポーネントのように{}の中に式を使用することはできない。
**注意：{}と変数の間にスペースを含めないこと**

```js
{recordId}  //! は不要
data={records.data}  //ダブルクォテーションを付けない
data={ records.data }  //スペースを含めるのはダメ 
```

下記のようにjs内に定義した関数を参照することもできる。

```html
<div if:true={condition}>Conditional Code</div>
```

```js
export default class MyComponentName {
    get condition() {
        return something ? true : false;
    }
}
```

####イベントハンドラの紐付け
{}内に関数名を記述する。'{' + 関数名 + '}'

```js
//HTML
<lightning-input label="Name" value={greeting} onchange={handleChange}></lightning-input>

//JS
handleChange(event) {
    this.greeting = event.target.value;
}

```
####繰り返し
for:each, for:item, for:index を使用する。繰り返し要素には識別のためにkey属性を付ける必要がある。

```html
<template for:each={items} for:item="item" for:index="idx">
    <p key={item.id}>{idx}:{item}</p>
</template>

1:要素1
2:要素2
3:要素3
・・・・
```

iteratorを使うやり方もある。この方法だと最初と最後の要素を識別することが可能。

```html
<template iterator:it={contacts}>
  <li key={it.value.Id}>
    <div if:true={it.first} class="list-first"></div>
      {it.value.Name}, {it.value.Title}
    <div if:true={it.last} class="list-last"></div>
  </li>
</template>

//it.value: 値
//it.index: インデックス
//it.first: 最初の要素でtrue
//it.last:  最後の要素でtrue
```

####IF文
if:true と if:falseを使う。

```html
<div if:true={something}>Conditional Code</div>
<div if:false={something}>Conditional Code</div>

<!-- templateタグを使うと、タグ自体は非表示になる -->
<template if:true={something}> ***  </template>
```

####タグ要素の取得
auraコンポーネントでの実装で aura:id と cmp.find() を使っていたタグ要素の取得は data-id と querySelector() を使用する。

```html
<!-- data-idを使ってidを指定する -->
<div data-id="body" class="slds-modal__content slds-p-around_medium">
```

```js
//querySelectorを使って検索する
var body = this.template.querySelector('[data-id="body"]')
```

#### classのadd/remove/toggle
auraコンポーネントで、$A.util.addClass等のユーティリティで実装していたスタイルclassの切り替えは classListを使用する。

```js
//xx はquerySelectorで取得したDOMノード
xx.classList.add('slds-hide');
xx.classList.remove('slds-hide');
xx.classList.toggle('content_scrolly');
```

#### cssクラスの指定
コンポーネント独自のcssクラスを使用したい場合は、コンポーネントフォルダ内にcssファイル（コンポーネント名.css）を追加して、CSSファイルにクラスを定義する。

```css
.dropzone {
    width:100%;
    height:100px
}
```

HTML内から普通にクラス指定すれば参照される。

```html
 <div class="dropzone slds-file-selector slds-file-selector_files">
   <div class="slds-file-selector>
```


####静的リソースの参照
静的リソースとして登録した画像を使用したい場合は、JS側でimportした静的リソース名を属性として指定する。

```js
import trailheadLogoUrl from '@salesforce/resourceUrl/trailheadLogo';

get trailheadLogoUrl {
    return trailheadLogoUrl;
}
```
```html
<!-- trailheadLogoUrlにはURLパスがセットされている -->
<div class="slds-m-around_medium">
    <img src={trailheadLogoUrl}>
</div>
```

#### Lightningコンポーネントの利用
属性名の区切りが - （ハイフン）になっていることに注意。またAuraコンポーネントの時に使用できたコンポーネントタグの末尾に / を付ける記述方法はできなくなっている。必ず閉じタグが必要。

```html
<lightning-icon icon-name="standard:opportunity" size="small" ></lightning-icon>
```
apacheのmod_proxyを使ってリバースプロキシに別のホストへプロキシリクエストさせた話

# TL;DR;

仕事中にapacheのmod_proxyを利用して別サイトのリソースをあたかも自サイトのコンテンツのように見せるような設定をした際にモジュールの使い方に苦戦したため備忘録。
以下のモジュールについて記述する。

* mod_proxy

※記述が複雑にならないよう今回は全て`http`通信を前提とする(https通信の場合は上記に加えてmod_sslも必要となり補足が必要となってしまうため)

# 前提

以下のような構成とする

* 自サーバホスト名 : `dondon.co.jp`
* リバプロ経由でリクエストする別サーバのホスト名 : `ponpon.co.jp`

※自サーバのapacheの設定で`mod_proxy`をロードし、リバースプロキシとして動作させるための設定が完了していること

# やりたいこと

今回の例は以下のようなケースとする

* クライアントから`http://dondon.co.jp/pon/`というURLでリクエストを投げられた場合に`http://ponpon.co.jp/`へプロキシリクエストを送信し、そこからコンテンツを取得したい
* でもクライアントからは`http://dondon.co.jp/pon/`にリクエストをしているように見せて、`ponpon.co.jp`ホストの存在は認識させないようにしたい
* ponpon.co.jpからponpon.co.jpのいずれかのコンテンツへのリダイレクト要求が返って来た時に`Locationヘッダ`のURLにponpon.co.jpへのURLが表示されないように隠蔽したい(`http://dondon.co.jp/pon/~~`へリクエストし直すようにしたい)

特定のURLでリクエストされた場合にクライアントに認識させたくないホストのコンテンツをレスポンスしたい！
加えて、認識させたくないホストから同ホストのいずれかのコンテンツへのリダイレクト要求が返ってきた場合にもクライアントに認識させたくないホストのURLが出ないようにしたい！
なんていうケースがあった場合に参考になると嬉しい

# httpd.confの編集

別にhttpd.confじゃなくても`/conf.d/`配下に切り出してもいい。そこは状況次第。
**やりたいこと**で書いたようなことをやるために必要な設定は以下となる。

```conf:httpd.conf
ServerName dondon.co.jp
ProxyPass /pon/ http://ponpon.co.jp/
ProxyPassReverse /pon/ http://ponpon.co.jp/
```

各行について1つずつ解説。

* **ServerName**
自サーバのホスト名を定義しておく

* **ProxyPass**
`(ServerName)/pon/`へのアクセスが内部的に`http://ponpon.co.jp/`へのプロキシリクエストに変換される

* **ProxyPassReverse**
プロキシリクエスト先のホストからリダイレクト要求が返ってきた場合にLocationヘッダに記載されているリダイレクト先のURLに、`http://ponpon.co.jp/`が含まれている場合、当該箇所を`(ServerName)/pon/`に書き換える
※例えば、プロキシリクエスト先から`http://ponpon.co.jp/hogehoge/`にリダイレクトしてくれって要求が来たら、WEBサーバはクライアントに対して`(ServerName)/pon/hogehoge/`でリダイレクトしてくれという風にLocationヘッダを書き換える
こうすることによってクライアントからは`ponpon.co.jp`のホストを認知することができなくなる

# 備考

ProxyPassの代わりに`mod_rewrite`のRewriteRuleを使うとリライト対象とするURLを正規表現のような条件で指定することができ、より詳細な設定をすることができる。
git rebase

#【コミットがごちゃごちゃなので整理したい】

```$ git log --oneline```
でコミットを確認。

```$ git rebase -i HEAD~3```

上記コマンドだとで上から３つまでのコミットが表示される。

```
pick コミットid commit 1
pick コミットid commit 2
pick コミットid commit 3
```

みたいに出るので、以下のように書き換えてまとめる。

```
pick コミットid commit 1
fixup コミットid commit 2
fixup コミットid commit 3
```

:wq　で保存。

これでコミットがまとまった。
```$ git log --oneline```　で確認できる

###補足
コミットメッセージを入れたい場合は
fixupじゃなく***squash***コマンドを使う（sだけでもOK）。
参考
https://liginc.co.jp/web/tool/79390
1:https://qiita.com/KTakata/items/d33185fc0457c08654a5
https://qiita.com/takke/items/3400b55becfd72769214
https://qiita.com/tsuuuuu_san/items/f708a9f7ea8ab8eb6945
https://dev.classmethod.jp/tool/git/git-rebase-fixup/
configファイルの作成


これだと、configファイルが外出しになっていない。
外出しについては、また別途

```golang:main.go
package main

import (
	"fmt"
	"gopkg.in/ini.v1"
)

type ConfigList struct {
	DefaultValue int
	DbName       string
	SQLDriver    string
}

var Config ConfigList

func init() {
	cfg, _ := ini.Load("config/config.ini")
	Config = ConfigList{
		DefaultValue:      cfg.Section("web").Key("defaultvalue ").MustInt(),
		DbName:    cfg.Section("db").Key("name").MustString("example.sql"), // MustStringはデフォルトあり
		SQLDriver: cfg.Section("db").Key("driver").String(),                // Stringはデフォルトなし、
	}
}

func main() {
	fmt.Printf("%T %v\n", Config.DefaultValue, Config.DefaultValue)           // int 1000
	fmt.Printf("%T %v\n", Config.DbName, Config.DbName)       // string stockdata.sql
	fmt.Printf("%T %v\n", Config.SQLDriver, Config.SQLDriver) // string sqlite3
}

```

```golang:config/config.ini
[web]
defaultvalue = 1000

[db]
name = stockdata.sql
driver = sqlite3
```
コーディングなしでスマートスピーカーのアプリを開発しました

#何を作ったのか？&この記事の目的

[罵りフレーズ](https://assistant.google.com/services/a/uid/0000009c1844d1c8?hl=ja)というスマートスピーカー向けのアプリをリリースしました。

![スクリーンショット 2019-01-09 22.21.27.png](https://qiita-image-store.s3.amazonaws.com/0/339830/692a2d57-6bca-8634-6ff3-d2ee22eadbc1.png)

コーディングなしで、なるべく手抜きで作りたいと思い、色々な知見を参考にして作成したのですが、後々の審査で痛い目にあったので、リジェクト理由とその対応結果を記録としてまとめていきたいと思います。

開発のモチベーションとしてはスマートスピーカーに汚い言葉を喋らせたいというふざけた気持ちで取り組みました。
*例えば、「罵りワードを教えて」と話しかけると、「口くせえな、豚のア●ルでも舐めたのか？」と返答してくれます*

#どうやったのか？

サーバーを立てたりせず、dialogflowのみで実装しました。
基本的にはdialogflowのIntentにて、1つのTraining phrasesに対して、Responseをひたすら追加していく方法で実施しました（他のIntentは一切触らず）。
基本的に、[Google Homeアプリ開発と申請方法～Actions on GoogleとDialogflowの使い方](http://www.kagua.biz/tool/jisaku/action-on-google-dialogflow.html)を見よう見まねで構築していきました。

# レビュー審査でハマったこと

### レビュー審査落ち１回目
1回目のレビューでは、以下の3つの理由でリジェクトとなりました。
おそらく、実機を動かす以前の問題だったので、夜中に申請して、翌朝にはリジェクトの回答を拝受しました。

##### ■App violates impersonation
>アプリのアイコンはGoogle Homeという言葉を使用しているように見受けられます。
アプリに関係した画像をご用意いただけますようお願いいたします。

アプリのアイコンで、「Google Homeが汚い言葉を！？」と煽り文を記入したら、上記の理由でリジェクトされました。
「Google Home」を「スマートスピーカー」に置換して解決しました。

ちなみに審査落ちしたアイコンはこちら
![nonosiri_long.001.png](https://qiita-image-store.s3.amazonaws.com/0/339830/0d977c51-5576-d140-0d81-00e2de5ebc55.png)


##### ■Privacy Policy URL missing or invalid
>Actions on Googleのポリシーでは各言語に合わせてのPrivacy policyを作成する必要がございます。
従いまして、日本語で作成したPrivacy policyを追加して頂けますでしょうか。
プライバシーポリシーの詳細（英語）につきましては以下よりご確認いただけます。
https://developers.google.com/actions/policies/privacy-policy-guide

完全に手抜きしたことが原因です。
プライバシーポリシーの作成をしたことがなかったので、[プライバシーポリシージェネレーター](https://app-privacy-policy-generator.firebaseapp.com/)を利用し作成しました。
そして、生成されたプライバシーポリシーをそのままGoogle Docsにコピペして、共有リンクを取得して申請をした結果、「日本語で書かれていない」という理由でリジェクトとなりました。

そこで、[Google Homeアプリをリリースしてみた(申請編)](https://qiita.com/miso_develop/items/c56fd334f333160a9130) を参考にして書き直しをしたら無事、審査が通りました。
プライバシーポリシーそのものは、Google Docsだけで問題ないことを確認できたのは、今後、本格的にアプリを開発していく上で、個人的には有用な情報となりました。

##### ■Mic is open without prompt
>ユーザが何を回答すればわからない（会話内容が終了したと思われる）場合、
アプリ側がマイクをオープンにすることはActions on Googleのポリシーに反します。
この場合、アプリ側は新たに問いかけを作成し会話を継続するか、会話を終了しなければなりません。

上記の指摘により、発言が終わるたびに続けるか終了するかを問いかけるようにしました。
本当にちゃんと作るなら、x秒ユーザーから応答がなかったら、終了するみたいなのを作るべきかなと思いますが、ここはリリースを優先して（面倒なため）妥協しました。


### レビュー審査落ち2回目
##### ■App misleads user
>ALCOHOL_TOBACCOを利用するように設定されていますが、その機能を確認することができませんでした。
混乱を招きますので、Actions Consoleにて正しい設定を行っていただけますでしょうか。

初回のレビューでは指摘されなかったのですが、2回目のレビューで指摘されました。
おそらく、１回目のレビューは登録情報だけで審査落ちして、2回目では実機を動かしたのだと思いいます。
コンテンツがやや過激な部分があったので、ALCOHOL_TOBACCOをYesで設定していたのが原因だったようです。
設定変更を戻したら審査が通りました。

##### ■Mature content warning missing or invalid
>成人コンテンツに関する内容のアプリの場合、アプリ起動後、Descriptionと会話冒頭に内容についての注意を促す警告を入れていただく必要がございます。
Descriptionでは確認できましたが、会話内では確認することができませんでした。
成人コンテンツに関する内容のアプリについては、以下のポリシーをご一読ください。

やや過激なコンテンツの場合は、アプリを起動した際に、注意喚起をしないといけないようです。
メッセージがやや冗長になるので嫌ですが、注意喚起文をアプリの冒頭で述べるようにしました。
ちなみに、差し込んだ注意喚起の文言は、
*「不適切あるいは不快な発言が含まれているので、ご利用は成人に限ります。」*
という文言をアプリ起動時に喋ってもらうようにすれば、申請が通りました。
どくしょかんそうぶん＃孫子ー計篇ー

# 孫子　計篇
## 概要
戦争は始める前にしっかりと考えてから行うように述べている。
五事七計の事柄で考えて、優れた結果だった場合のみ戦争するとのべる。

## 五事
- 道　人々が上の立場の人と同じ思いでいるか
- 天　時期や気温は適切か
- 地　距離など場所はいいところか
- 将　将軍が優秀か
- 法　軍制が整っているか

## 七計
- 君主は敵と味方でどちらが人心を掌握しているか
- 将軍は敵と味方でどちらが優秀か
- 自然や距離はどちらに優勢か
- 法制はどちらが遵守しているか
- 軍隊はどちらが強いか
- 兵はどちらが訓練しているか
- 賞罰はどちらが公明か
Tyrano関連でこれまでのアレコレをまとめてみる。

#はじめまして。
というわけで、Qiitaに初投稿です。
Newfrontia Softwareの城雅音 武です。
かれこれ１０年ちょっと同人ゲームをつくっております。
しかもノベルゲーばかり作ってきたのでQiitaに投稿なんて出来るわけ無いと思っていたのですが……
ちょっとだけユーザ操作が入るゲーム要素があるゲームを作ってしまいました。
ようやく、時間が取れたので自分のためにも技術情報をまとめていこうかと思います。

##で、ノベルゲーム作者が何を作ったの？
というわけで、本題ですが。
ノベルゲームエンジンを使ってノベルゲームを作ってきました。
まあ、ノベルゲームエンジンですからノベルゲームを作ってきたのですが…

TyranoBuilderやTyranoScriptがとても色々と拡張性が高かったので…

**審査バトルゲーム**
![battler_nozomi.png](https://qiita-image-store.s3.amazonaws.com/0/340395/9737f56b-11fb-37e5-3e1f-b1fb0c116be0.png)
（ゲーム画面）

を作ってしまいました。
ノベルゲームエンジンで作ってますと言うと、かなり違和感を持たれるIFです。
各種ボタンはちゃんと有効で各種アクションが連動して動くようになっています。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/340395/e1417738-050c-345f-0441-220186567b8c.png)

ノベルパートももちろんあります。
ここも普通の使い方はしていません。
メッセージウインドウが３つと、かなり特殊なことをしています。

とりあえず、このあたりの技術的なことを書けたらいいなと思って至ります。
【gzip】ファイルの圧縮/解凍 ~圧縮したからといってサイズが小さくなるとは限らない？~[Linux]

#はじめに
USBなどの外部メモリにデータを移行する際、データを圧縮して渡せると、よりたくさんのデータを一度に移すことができますよね。特に、普段は見返さない写真や動画などは、普段使っているPCから移行しておきたかったりします。
そこで、データを圧縮するコマンド`gzip`について勉強したので簡単にまとめておきます。

#**圧縮・解凍**
圧縮する際には、`gzip`コマンドを使用し、
解凍する際には、`gunzip`コマンド、もしくは`dオプション`つきの`gzip`コマンドを使用します。

#**1. 流れで確認**
中身が`aaaaaaaaaaaaaaaaaaaa`の文字列であるa.txtファイルに対して処理をしていきます。
###**ファイルを圧縮**

```
$ gzip a.txt
```
###**サイズを確認**
`lオプション`で圧縮されたファイルの情報(**サイズ、圧縮率、ファイル名**)を表示することができます。

```
$ gzip -l a.txt
  compressed uncompressed  ratio uncompressed_name
          30           21 -42.9% a.txt 
```
結果をテーブルで表すと次のようになります。

|  | |
|:-----------------|:-----------------:|
| サイズ(圧縮後)     |              30 |
| サイズ(圧縮前)     |            21 |
| 圧縮率    |            -42.9% |
| ファイル名(圧縮前)  |                a.txt |

逆にファイルサイズが大きくなってしまっています。圧縮率もマイナスとなっています。こちらに関しては、後ほど確認します。

###**ファイルを解凍**
圧縮後のファイルはファイル名に.gz拡張子がついています。

```
$ gzip -d a.txt.gz
```

#**2. 圧縮ファイルのサイズが小さくなっていない件**
画像ファイルと動画ファイルに関しても圧縮を行い、サイズについて確認してみました。

###**画像ファイルに関して**
```
$ gzip a.jpeg

$ gzip -l a.jpeg.gz
  compressed uncompressed  ratio uncompressed_name
     6329598      6347555   0.2% a.jpeg
```

###**動画ファイルに関して**
```
$ gzip a.mov

$ gzip -l a.mov
  compressed uncompressed  ratio uncompressed_name
  2014167723   2014467159   0.0% a.mov
```

わずかにファイルサイズが小さくなっていますが、これでは圧縮する意味はあるのかと考えものです。。

###**結論**
圧縮に向かないファイルがあるため、対象ファイルを圧縮するかどうかは見極める必要があります。
また、ペイントなどのBMP(ビットマップ)ファイルなどが圧縮には適している（圧縮効率が良い）ようです。

#**補足**
ファイルのサイズはバイト単位で出力されますが、容量が大きいファイルはサイズが掴みにくいということがあります。その際、`hオプション`と`lオプション`とつけることで、単位をつけてわかりやすく出力することができるので、確認します。

```
$ ls -hl a.txt
-rw-r--r--  1 takuyanin  staff    21B Jan  9 21:50 a.txt
```

```
$ ls -hl a.jpeg
-rw-r--r--  1 takuyanin  staff   6.1M Sep  9 15:55 a.jpeg
```

```
$ ls -hl a.MP4
-rw-r--r--@ 1 takuyanin  staff   1.9G Sep  9 16:24 a.mov
```

このように、`B(バイト)`、`M(メガ)`、`G(ギガ)`といった単位とともにファイルサイズが確認できます。

便利ですね。

#**おわりに**
個人的に、もっとも外部メモリに移したかった画像ファイル、動画ファイルに関してはあまり効果がないということがわかりました。
少し残念な結果となりましたが勉強になったのでよしとします。笑

こちらの記事が役に立ったという方は、いいね、よろしくお願いします(^^)
また、[takuyaninのマイページ](https://qiita.com/takuyanin)にlinuxコマンドなどに関していくつか記事をまとめてますので、よければご参考ください。
swiftで自分がよく忘れるやつまとめとく（基本中の基本）

## 最初に
これは基本中の基本なのでこんなの常識すぎやろばかじゃねーのと思う人は嘲笑いながらこの記事にいいねを押しましょう。
## なんかたまに見る??
```swift
let a: Int? = 1
let b = a ?? 5
```
この二つの?は最初なんのことかさっぱりだったが、この場合aの値が仮にnilだった場合bにはnilではなく5が代入されるという感じらしい。

## 謎のasとas?
結論から言うとasはアップキャストas?はダウンキャストらしい。
具体例を出すとまずasの場合

```swift
let a = "a" as Any
```
このようにすることで"a"(string型)をAny型として扱うことができる。これにより型アノテーションも書かなくてよくなる。
ただアップキャストの名前の通り階層的に下位の型を上位の型にすることはできるがその逆はできない。
例えばany型をstringにすることは出来ない。
string型をint型にするなども出来ない(二つとも継承し合ってないため)
ダウンキャストはas?とas!がある。as?の場合

```swift
let any = 1 as Any
let a = any as? Int // Optional(1)
let a = any as? String //nil
```
ダウンキャストができる型関係の場合Optional型で返されるが、ダウンキャストできない場合nilが返される。
一方as!の場合ダウンキャストできるとwrapped型ダウンキャストできない場合はエラーになります。
基本的にはas?を使うのがいい？
## まとめ
とりあえずこんだけにしときます。またなんか合ったら追加していくかもしれないし追加しないかもしれない。
ラズパイでGoogleドライブに写真を送る方法

Qiitaってこんな感じなんですね・

# 導入
　研究室レタス栽培は見事に停止し、もはや続けるか微妙な空気が流れています。その時にラズパイでとった写真をGoogleドライブに放り投げるっていうのやったのですが、今後のために残しておこうと思います。

# 先に参照先
[ドライブに送る方法](https://qiita.com/aviscaerulea/items/53123ce5b79c80e31a71)
[ドライブに送る方法2:こっちを参考に](https://www.nextdoorwith.info/wp/se/linux-gdrive/)
[gdrive](https://github.com/prasmussen/gdrive)
[写真撮るやつ](http://nn-hokuson.hatenablog.com/entry/2017/10/11/205438)

# 方法
らずぱいでドライブと連携させたディレクトリを作る

gdriveのダウンロード

```
$curl -L -o gdrive "https://docs.google.com/uc?id=0B3X9GlR6EmbnVXNLanp4ZFRRbzg&export=download"
```

権限を持たせて認証をする
URLが出てくるから、ブラウザに張り付けて。出てくるコードを戻って張り付ける

```
$chmod 755 gdrive
$./gdrive list
```

これでおしまい、あとはサイトを見てください
送信に使うコマンドはこれ
16hdGM15SrN4TCwZ4_nmg3K1crUczは送りたいフォルダURL後ろの部分で、test.txtが送りたいもの。これで、送ることが出来る

```
$./gdrive upload --parent '16hdGM1SrtN4TCwZ4_nmg3KRcrUcz' test.txt
```
## 定期的に送り付ける
　詳しいことは上の「写真撮るやつ」で参考にさせて頂いた人のをみるといいです。丁寧に書いてくれています。物凄い面倒なことをしてるので、もっといい方法があるっていうか、ほぼコマンドだし、コマンドが動くPythonがいけない

```python:pic.py
import commands
from datetime import datetime

time = datetime.now().isoformat()
gdrive = "./gdrive upload --parent 'ドライブのURLの最後の部分' "+ time + ".jpeg"

commands.getoutput("fswebcam pfarm.jpeg")
commands.getoutput("cp ./pfarm.jpeg ./" + time + ".jpeg")
commands.getoutput(gdrive)
commands.getoutput("rm " + time + ".jpeg")
```
Golangをdocker-composeで動かすdocker-compose.yml

メモ用

go mod initでファイルつくる
go mod downloadでいろいろダウンロードする
go buildで勝手にごにょごにょしてコンパイルする

```bash.sh
go mod init
go build
```

```docker-compose.yml
version: '2'

services:
  app:
    image: 'golang:1.11'
    ports:
    - '8585:8585'
    volumes:
    - '.:/root/go/src/github.com/{YOU-USER-NAME}/{APP-NAME}/'
    working_dir: '/root/go/src/github.com/{YOU-USER-NAME}/{APP-NAME}/'
    command: bash -c 'go mod download && go run main.go'
    environment:
    - 'GO111MODULE=on'

volumes:
  data:
    driver: 'local'
```
Github DesktopとSourcetree の比較

# GitのGUIの比較
* Github DesktopとSourcetree はどちらも有名なGitのGUIですが、
両方を利用した感想を書いてみたいと思います。

* 初学者には何かととっつき辛いGitですが、同じ境遇の方の参考になればと思います。
* **あくまで個人の感想です**

# メリット

個人的感想を書きにまとめてみました。

* Github Desktop
    * 導入がすぐできる　つまづくところはほぼない
    * 当然のことながらGithubとの連携を前提に作られているため、利用開始までもわかりやすい
    * コミットするまでの流れもシンプル
* Sourcetree
    * UIが親切でわかりやすい
    * GUIから行える機能が多い
    * **変更差分が視覚化されている**

# 結論→Sourcetree をおすすめしたい

この記事でなにを書きたかったかと言うと

### **変更差分が視覚化されている**

です。

<img width="66" alt="スクリーンショット 2019-01-09 21.55.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/324477/876dfe56-bcc9-6e49-0f75-def8eb64413f.png">


初心者にはかなりわかりやすい。
Gitの仕組みの理解にも役立ちました。
なんども書きますが個人的意見です。いままではGithub Desktop使ってました！
apt build-dep がエラーになるときの対処方法

新しく立てた仮想マシンなどで `apt build-dep` を実行すると以下のようなエラーになることがあります。

```
$ sudo apt build-dep ffmpeg
[sudo] password for koba: 
Reading package lists... Done
E: You must put some 'source' URIs in your sources.list
```

エラーメッセージの通り、source.listにsourceを取得する先のURIが無いためです。
実際には、source.listの中に書いてはあるのですが、コメントアウトされています。なので、それをアンコメントすればよいです。

```
$ sudo vi /etc/apt/sources.list
```
このようにviを開いて、置換します。

```
:%s/# deb-src/deb-src/
:wq
```

これで、`apt update`を実行してから再度 `apt build-dep`を実行すればエラーにならずに完了します。

```
$ sudo apt update
$ sudo apt build-dep ffmpeg
```

# 関連
[ffmpeg 4.0 をlibsrtを有効にしてビルドする](https://qiita.com/tetsu_koba/items/92c398abd96c651f4035)
[gstreamer をソースからビルドする](https://qiita.com/tetsu_koba/items/30971369ef6f91fced4c)
NetlifyでHugoのextendedバージョンが暫定対応されたので試してみた


# はじめに

~~NetlifyでHugoのextendedバージョンが暫定対応されたので導入してみました。~~

Netlify が Ubuntu 16.04 の環境を用意してくれたので、普通に Hugo extended が使えるようになりました。

https://twitter.com/GoHugoIO/status/1106282569161687042?s=20

> Great news for Hugo users on Netlify -- you can now finally use the full set of Hugo Pipes, including SASS/SCSS, without having to commit any build product to source control.

正式対応の適用手順は最下部に記載します。

# Hugoのextendedバージョンとは

リリースページにあるファイルで、 `hugo_extended_0.52_Linux-64bit.tar.gz` のように　`extended` がついているファイルのことです。

- [Releases · gohugoio/hugo](https://github.com/gohugoio/hugo/releases)

この `extended` が何を意味しているのかと言うと、Hugo 0.43からサポートされた [Hugo Pipes][] で、SCSS/SASSをサポートしているバイナリです。

- [And Now: Hugo Pipes! | Hugo](https://gohugo.io/news/0.43-relnotes/)

> Hugo is now released with two binary version: One with and one without SCSS/SASS support. At the time of writing, this is only available in the binaries on the GitHub release page. Brew, Snap builds etc. will come. But note that you **only need the extended version if you want to edit SCSS.** For your CI server, or if you don’t use SCSS, you will most likely want the non-extended version.

# Netlifyでextendedバージョンが動かない理由とこれまでの対応

しかしこれまでNetlifyではこのバイナリは動きませんでした。その理由は、NetlifyのビルドイメージのベースがUbuntu 14.04と古く(2019/04にサポートが切れる)、libstdc++のバージョンが古く、そのままでは動かないためです。

- [Support extended Hugo version · Issue #182 · netlify/build-image](https://github.com/netlify/build-image/issues/182#issuecomment-444958931)

> I was told by Netlify several times that this issue is hanging on a upgrade of their build environments from Ubuntu 14.04 (which has an EOL date in April next year).

これまでは、手元でビルドしてできた、以下のディレクトリにあるファイルをリポジトリにコミットする必要がありました。

- `resources/_gen/assets/scss/`

# 暫定対応の内容

先程のチケットの最後に、以下のように書かれています。
PR #197の内容を見ると、Ubuntu 16.04からlibstdc++を取得して展開しているようです。

- pull request [#197](https://github.com/netlify/build-image/pull/197)をデプロイしたよ。でも問題があったので一部差し戻ししたよ。
- 開発バージョンはUbuntu 16.04(原文はubuntu 16)にしたよ。もう少ししたらユーザでイメージを選べるようにするよ。

# 暫定内容を試す

このコメントに書かれている暫定対応を試してみました。この暫定対応の使い方は、チケットで以下のように書かれていました。

```sh
LD_LIBRARY_PATH=$HOME/stdc++6/usr/lib/x86_64-linux-gnu ./hugo
```

要は自分でバイナリを持ってきて、LD_LIBRARY_PATHを指定すればいいみたいです。

具体的には以下の手順で動きました。

1. [Releases · gohugoio/hugo](https://github.com/gohugoio/hugo/releases)から `hugo_extended_0.XX_Linux-64bit.tar.gz` を取得して展開
2. hugoバイナリをリポジトリに入れ、 `resources/_gen/assets/scss/sass/custom.scss_*` を削除
3. netlify.toml(または画面から)で、以下のようにコマンドを変更してpush

変更前

```toml
[build]
command = "hugo"
```

変更後

```toml
[build]
command = "LD_LIBRARY_PATH=$HOME/stdc++6/usr/lib/x86_64-linux-gnu ./hugo"
```

問題なく動きました。

# ~~正式対応待ち~~

~~暫定対応はしたのですが、SCSSのコンパイルを頻繁に行うことはないので、無理に対応する必要はなかったかもしれません。正式版を待ったほうが良さそうです。~~

# 正式対応の適用手順

1. Netlifyにログインし、サイトを選択
2. 上部のメニュー(横並び)から「Settings」を選択
3. 左側のメニューから「Build & deploy」を選択
4. 中ほどにある「Build image selection」にある、「Edit settings」ボタンを選択
5. 「Ubuntu Trusty 14.04」となっているので、「Ubuntu Xenial 16.04 (default)」を選択して保存
   - `(default)` と書いているように、新規サイトはデフォルトで新しいイメージが使われるようです。

[Hugo Pipes]: https://gohugo.io/hugo-pipes/
create-react-appのプロジェクトで環境変数を.envから読み込めない原因と解決策

# はじめに
`create-react-app`で作成したプロジェクトで`.env`から環境変数を読み込めないときは下記のTipsを確認してみてください。

- Viewが多いのでまとめ直しました。（2020/05/05）

## `.env`を読み込めなかった原因と解決策

### 1. `.env`を設定後にコンパイルしていない
- `.env`に環境変数を書き込んだ後は一度`Ctrl +C`で終了した後に、`npm start`で再コンパイルしましょう。

### 2. 環境変数のKEYが`REACT_APP_`から始まっていない
- 環境変数のKEYには`REACT_APP_`prefixを付ける必要があります。
  - https://create-react-app.dev/docs/adding-custom-environment-variables/

``` .env:.env
REACT_APP_APP_ID="YOUR_APP_ID"
```

### 3. `.env`がプロジェクト直下に作成されていない
- `node_modules`などが配置されているrootディレクトリに`.env`を作成する必要があります。

```
.
├── .env
├── .eslintrc
├── .git
├── .gitignore
├── .node-version
├── .prettierrc
├── .storybook
├── README.md
├── build
├── node_modules
├── package-lock.json
├── package.json
├── paths.json
├── public
├── src
├── tsconfig.json
└── yarn.lock

```
@vue/cli-plugin-unit-mochaでHTMLをパースする

HTMLをパースするW3C標準のAPIとして[DOMParser](https://w3c.github.io/DOM-Parsing/#the-domparser-interface)（仕様策定中）がある。Node.jsからこのようなブラウザでサポートされるAPIを使うためには、[jsdom](https://github.com/jsdom/jsdom)（グローバル変数を注入するのであれば[jsdom-global](https://github.com/rstacruz/jsdom-global)）がよく使われる。

Javascriptで[jsdom](https://github.com/jsdom/jsdom)を使う場合は以下のように読み込めばよい。

```javascript
// JSDOMインスタンスからwindowオブジェクトを参照する。
const DOMParser = new (require('jsdom').JSDOM)().window.DOMParser;

// jsdom-globalを使う場合はwindowオブジェクトが注入される。
require('jsdom-global')();
const DOMParser = window.DOMParser;
```

[@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha)にも[jsdom-global](https://github.com/rstacruz/jsdom-global)が組み込まれているが、TypeScriptを使うとwindowの型がWindow型となり、DOMParserを参照できない。

```
ERROR in ... Property 'DOMParser' does not exist on type 'Window'.
```

おそらく型定義ファイルを整理すれば参照できるようになると推測するが、今回はHTMLのパースができればよかったため、`Element.innerHTML`で代用した。

```typescript
const html = "<p>test</p>";
const div = document.createElement('body');
div.innerHTML = html;
const doc = div.querySelector('body > *');
```

#### 参考

* https://stackoverflow.com/questions/42649700/using-domparser-in-javascript-testing-with-mocha-and-jsdom
Ruby on Rails チュートリアル全まとめ(解説・単語・演習)

#近況報告

エンジニア転職成功しました。YouTubeもはじめました。

https://www.youtube.com/channel/UCcXQG8lu_EdyP2Cbhtz1bcA


#はじめに
Rails勉強中の[YUUKI](https://twitter.com/bitcoinjpnnet)と申します。


ProgateのRuby on Railsレッスンを終わらせて、Rails Tutorialを一周後、ポートフォリオを制作。

[プログラミング学習本紹介サイト Pooks](https://pooks.herokuapp.com/)
<a href="https://pooks.herokuapp.com/"><img src="https://yuukitetsuya.github.io/Pooks/image/topimage.png"></a>

これからRailsを用いた会員制サイトの開発を行う為、その前段階として2周目となるRails Tutorialに取り組んでいます。
しかし、ただ読んだだけでは理解も進まないと思い、今回Qiitaにメモを投稿することにしました。
私自身のアウトプットと共に、これからRails Tutorialに取り組む方の参考になれば幸いです。

##サンプルアプリはこちら

新規登録できない場合は以下でログインしてください。

- email:example-2@railstutorial.org
- pass:password

[サンプルアプリ](https://yuuki-heroku-sample.herokuapp.com/)
<a href="https://yuuki-heroku-sample.herokuapp.com/"><img src="https://qiita-image-store.s3.amazonaws.com/0/244639/82e90271-a5b4-cdc2-0fea-db4812565a8b.png"></a>


#学習メモのまとめ

- [第1章 MVCモデルからGit・Herokuの使い方](https://qiita.com/yuuki_netb/items/67b83fc298f4940cf4a7)

- [第2章 ユーザー・マイクロポストのモデル設計からデプロイ](https://qiita.com/yuuki_netb/items/47e6e9b8c4c2c19fd917)

- [第3章 テストの概念から使い方]
(https://qiita.com/yuuki_netb/items/55ed4740f12994a42a00)

- [第4章 Rubyの基礎(文字列出力からClass)]
(https://qiita.com/yuuki_netb/items/b59eb87aa64a2315b4ed)

- [第5章 HTML/CSSからSCSS・Bootstrapの使い方・埋め込みRuby]
(https://qiita.com/yuuki_netb/items/0ca33d0e70413551986a)

- [第6章 Validation・DB(SQLite)・パーシャルやヘルパーの使い方]
(https://qiita.com/yuuki_netb/items/bf7197631a4a221d9fad)

- [第7章 ユーザー登録機能・flash・統合テスト・通信のSSL化]
(https://qiita.com/yuuki_netb/items/914c2d2b4ff2c08b2f5b)

- [第8章 ログイン機能・HTTPリクエスト・セッション]
(https://qiita.com/yuuki_netb/items/44771ece529ab9c92d64)

- [第9章 Cookiesメソッド・記憶トークンの暗号化・Remember meチェックボックス]
(https://qiita.com/yuuki_netb/items/639cbace7cb806379452)

- [第10章 ユーザー更新 beforeフィルター フレンドリーフォワーディング adminまで](https://qiita.com/yuuki_netb/items/e2a12fac11e9ff344528) 

- [第11章 アカウント有効化(AcctionMailer Activation)やSendGridの使い方など](https://qiita.com/yuuki_netb/items/3a544d9183f4008f6aa2#_reference-e112db6877db9c86e8c8) 

- [第12章 パスワードの再設定 PasswordResetsリソース](https://qiita.com/yuuki_netb/items/04f3b87aac87ee359ed5#_reference-4cf68e1dc8255c4593ef)

- [第13章 モデルの関連付け マイクロポストの表示 画像投稿機能の実装](https://qiita.com/yuuki_netb/items/bd51658712345807c741#_reference-bc53f5a02beec782ec14) 

- [第14章 データモデルの関連付け(フォロー フォロー解除)フィードの実装など](https://qiita.com/yuuki_netb/items/07ba89a6d329bd2893e5#_reference-679cebb93f61e5a83978)
RailsへのBootstrap導入について

#　 はじめに
 勉強中のメモ兼アウトプットとして投稿します。


* Railsにbootstrapを導入する際に動作がうまくいかなかった
* バージョンによって導入方法が異なるようなので備忘録として記載します。


#開発環境

* Rails 5.2.2
* ruby 2.5.1
* gem bootstrap 4.1.3
* jquery-rails 4.3.3

# 内容

まずはマニュフェストファイル

```scss:application.scss
@import "bootstrap";
```

* bootstrapなのでデフォルトのcssファイルをscssに変更
デフォルトで記載されていたコードはすべて削除して１行追加しました。
* require　tree　を消してしまっているのでアセットパイプラインでCSSを読み込む場合には
別途記載が必要です。

また、JavaScriptの方は

```javascript:application.ja
//= require rails-ujs
//= require jquery
//= require bootstrap-sprockets
```

* jquery-ujsとかpopperを入れる必要があるという記事もありましたが
  これだけでもうまくいきました。まだ不要な部分があるような気がしなくもないです。

```ruby:Gemfile
gem 'bootstrap'
gem 'jquery-rails'
```

* 念の為gemも記載しました。


# 最後に

* ネットで調べてみた情報ではうまく動かなかったので記載してみました。
* 勉強中のため間違いはご容赦ください。
シェルスクリプトからmemcachedを使う

シェルスクリプトの中でmemcachedを使うためのライブラリ的なものを作りました。シェルスクリプトにincludeして使うことを想定しています。エラー処理とかテストとか不十分なので、まだPoCレベルなことをご了承ください。

## 前提条件

telnetが無ければインストールしておいてください。あと、もちろんmemcachedを起動しておいてください。

## ソースコード

```bash:memcached.sh
MC_HOST="localhost"
MC_PORT="11211"

mc_open() {
  coproc mc { telnet ${MC_HOST} ${MC_PORT}; } 2>/dev/null
  # telnet接続時の出力を3行分読み飛ばす
  read <&"${mc[0]}"    # Trying ::1...
  read <&"${mc[0]}"    # Connected to localhost.
  read <&"${mc[0]}"    # Escape character is '^]'.
}

mc_set() {
  local r
  echo "set ${1} 0 ${2} ${#3}" >&"${mc[1]}"
  echo "${3}" >&"${mc[1]}"
  read r <&"${mc[0]}"
  if [ "${r}" = "STORED" ]; then
    return 0
  else
    echo ${r} >&2
    return 1
  fi
}

mc_get() {
  local i r v
  echo "get ${1}" >&"${mc[1]}"
  for i in {0..2}      # 値があれば3行目、無ければ1行目が"END"
  do
    read r <&"${mc[0]}"
    if [ "${r}" = "END" ]; then
      echo -n ${v}
      break
    else
      v=${r}
    fi
  done
  return 0
}

mc_close() {
  echo "quit" >&"${mc[1]}"
}
```
## 使い方

```bash:sample.sh
#!/bin/sh
. ./memcached.sh

# 接続開始
mc_open

# 値のsetは キー 有効期間 値 を指定
mc_set mykey1 10 myvalue1

# 値のgetは キー を指定
v1=$(mc_get mykey1)
echo "Value of mykey1 is ${v1}."

# 値をsetしてないキーでgetすると、結果は空文字
v2=$(mc_get mykey2)
if [ "${v2}" = "" ]; then
  echo "Value of mykey2 is empty."
else
  echo ${v2}
fi

# 接続終了
mc_close
```
## 今後

memcachedが使えると、分散処理、並列処理などへの応用が可能になります。今後、使ってみながらブラッシュアップしていきます。
VC++開発の覚え書き①

#概要
　「Visual Studio」のCLRコンソールアプリケーションで作成したフォームのコントロールから値を取得し、C言語でよく使うint型やchar型に変換して利用可能にする。

#内容
- [System::String^ -> char型](#systemstring---char型)
- [char型 -> System::String^](#char型---systemstring)
- [System::String^ -> int型](#systemstring---int型)
- [int型 -> System::String^](#int型---systemstring)

#System::String^ -> char型
```C++
// テキストボックス「TextBox1」から
// データを取得して「char* str」に格納する

using namespace System::Runtime::InteropServices;

// 中略

    char* str = (char*)Marshal::StringToHGlobalAnsi(textBox1->Text).ToPointer();
```

#char型 -> System::String^
```C++
char* cStr = "abcde";
String^ sStr = gcnew String(cStr);
```

#System::String^ -> int型
```C++
String^ data = "12345";
int intData = int::Parse(data);
```

#int型 -> System::String^
```C++
int source = 12345;
String^ text = source.ToString();
```

#最後に
　C言語でしか開発できないので型を変換するしかなく、そのための覚え書きです。
　もっとスマートなやり方等ご存知の方はご教授いただけると助かります。
マックブックから音声入力でQiitaの記事を書いてみるテスト

マックブックから音声入力でQiitaの記事を書いてみるテスト

# Setting

![image](https://user-images.githubusercontent.com/13635059/50897531-bb5e4480-144f-11e9-8f71-693968b5a0bf.png)

Function キーダブルタップで音声入力モード

# 音声で語った文章、編集済み。

- マックブックからQiitaの記事を書いてみるテスト。
- 音声で改行できないんですか？改行してくれよ。お願いだよこれはMacBookでEnter押せってことか。
- IPhoneに比べて精度が悪いわけではないと思うんだけどなぁ
- なぜ僕が音声入力で語っているかと言うと、IPhoneの音声入力が心地よすぎて、ハンズフリー過ぎて、やばくて、MacBookでも音声でしゃべれないことがも信じられないレベルだったからなんだな。
- IPhoneとMacBookの音声入力の感じは全く同じではないけどかなり似ている気がするな。
- 音声入力モードになるとなんか文章を一気に判別してくれるのかな(?
- ある程度解析にしてからなんか適切な文章を見つけてくれてる気がするな
- このMacBookというかこれ奇跡的な日じゃないですか素晴らしいですね
- ただ日本語入力モードだと英語は聞き取りにくいみたいでFeatureか言うとか日本語として解釈しようとしてしまうところが玉に瑕かな。
- 皆音声入力素晴らしいからいちど試してみるといいよ。
- 無料の心理セラピー的な効果もあると僕の時間で実証済みです。

# 未編集のテキスト

マックブックからきたの記事を書いてみるテスト。カイギョウカイギョウ改行

改行カイギョウできないんですか改行してくれお声お願いだよこれはMacBook連タオセってことか

れんたおおせってどういうことだenterをおせ

IPhoneに比べて精度が悪いわけではないと思うんだけどなぁカイギョウカイギョウ改行

Enter エンターえんたー

なぜ僕が音声入力で語っているかと言うと、IPhoneの音声入力が心地よすぎて、ハンズフリー過ぎて、やばくて、MacBookでも音声でしゃべれないことがも信じられないレベルだったからなんだな。

IPhoneとMacBookの音声入力の感じは全く同じではないけどかなり似ている気がするな。

それで1導入音声入力モードになるとなんか文章を一気に判別してくれるのかな(?

ある程度解析にしてからなんか適切な文章を見つけてくれてる気がするなこのMacBookというかこれ奇跡的な日じゃないですか素晴らしいですね

ただ日本語入力モードだと英語は聞き取りにくいみたいで来ちゃっとか言うとか日本語として開拓しようとしてしまうところが玉に瑕かな。

今は編集せずにしゃべっていけるあとから手直しをしようかと思っている。たら長くなると手直し自体も大変だよなぁ。

みな音声入力素晴らしいからいちど試してみるといいよ。無料の心理セラピー的な効果もあると僕の時間で実証済みです。


---

https://twitter.com/yumainaura

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

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ベクトルタイル生産の前処理に入れたバックプレッシャーのコード

これは、Node.js での[バックプレッシャー](https://www.sophia-it.com/content/バックプレッシャー)のコードの書き方についてのメモです。

ベクトルタイル生産を効率的に行うには、要はいかに効率の良いデータフローを設計・実装できるかということが鍵になってきます。行うことはデータ変換なので、データフローの下流のほうが常に帯域が広いことを、必ずしも保証できないはずです。

そこで、Node.js では一般的に行われていることですが、バックプレッシャーの手法で流量制御をすることが必要になってきます。そのためのコードを [modularize.js](https://github.com/hfu/namero/blob/master/modularize.js#L37-L45) に書く機会があったので紹介します。

このコードでは、上流から来たデータを 256 個くらいある下流により分けており、また、下流には gzip 圧縮が置いてあるので、上流の流量のほうが下流の容量を追い越す場合が多く、バックプレッシャーを書く必要がありました。

```javascript:modularize.js
if (streams[key].write(s)) {
  resolve()
} else {
  input.pause()
  streams[key].once('drain', () => {
    input.resume()
    resolve()
  })
}
```

Node.js の書き込み可能ストリームに write した時、false が戻ってくるようであれば下流が詰まっているということなのだそうです。その場合には、書き込んだストリームから drain イベントが戻ってくるまでは、上流側のストリームを休止させる、ということを上のコードでは行っています。

書いてみれば簡単ですが、問題の特定から解決までに少し手間取ったので、ここにメモしておきます。