OmniAICreator/Qiita-1.07M huggingface dataset:
direx から quick-preview でプレビューする


[direx](https://github.com/m2ym/direx-el) はとても便利ですが、例えば画像ファイルをプリビューしようとするとかなり残念な気分になります。

ところで ELPA には [quick-preview](https://github.com/myuhe/quick-preview.el) という素敵なパッケージがあって、OS ごとに用意されたチラ見プログラムを起動できます。例えば macOS では QuickLook を起動しています。なのでそれらチラ見プログラムで表示できるものは何でも表示できるようになります。画像でも動画でも音声でもエクセルでもワードでも (対応していれば)。


direx から quick-preview にファイルを渡してやればかなり幸せになりそうだったのですが一筋縄ではいきませんでした。でもまあなんとかできるようになったのでここに記しておきます。

direx と quick-preview の内部構造をカンニングしてでっち上げたものなのでバージョンが変われば動かなくなる可能性があります。

前提条件として direx と quick-preview が **パッケージシステムを使ってインストールされている** 必要があります。`package-installed-p` なんて関数使ってるので…。でもいまどきこんな条件普通クリアしてますよね?

```emacs-lisp:init.el
(when (package-installed-p 'quick-preview)
  (global-set-key (kbd "C-c C-p") 'quick-preview-at-point)

  ;; direx において [SPACE] でプレビュー
  (with-eval-after-load "direx"
    (define-key direx:direx-mode-map (kbd "SPC") 'quick-preview-at-point)
    (defun my-advice-quick-preview---get-file-name-for-direx (f &rest args)
      (if (eq major-mode 'direx:direx-mode)
          (direx:file-full-name (direx:item-tree (direx:item-at-point)))
        (apply f args)))
    (advice-add 'quick-preview--get-filename :around #'my-advice-quick-preview---get-file-name-for-direx)))
```

direx では <kbd>SPACE</kbd> を押すとプリビューです (他のメジャーモードでは <kbd>C-c C-p</kbd> でプリビューです)。もともとはスペースにページを送る関数をバインドしてあったようですがそんなのは <kbd>C-v</kbd> でいいので潰しました。
Rails5でlink_toの中にfont_awesomeを埋め込む方法

この書き方をすると、font-awesomeのアイコンが後ろにくる。

```haml:show.html.haml

= link_to novel.url do
  .novel-title-link
    #{novel.title}
    .fa.fa-external-link
```

target blank（新規タブで開く）はこう

```haml:show.html.haml

= link_to novel.url, target: "_blank" do
  .novel-title-link
    #{novel.title}
    .fa.fa-external-link
```

こうするとアイコンは前に来る。

```haml:show.html.haml

= link_to novel.url do
  .novel-title-link.fa.fa-external-link
    #{novel.title}
```


###参考
[Rails4でlink_toの中にFont Awesomeのアイコンを埋め込む方法](https://qiita.com/knt45/items/c76b246ad448f3814ae4)
OSSソフトについて

※記載内容はメモとして作成しているため、修正が必要な部分があるかもしれません。

####**OSSについて調べたことをメモします**

**①ユニークな立ち上げ理由**

OSSを立ち上げた人に面白い立ち上げ理由があったのでご紹介します。
海外の有名エンジニアですが、作ったプログラムのロジックが全部会社
に権利化されることに焦燥し、OSSを立ち上げたという人がいました。

ちなみに日本ではプログラムは汎用性があるかないかで権利化できるか
どうかが変わってきます。ユニーク性が重要です。
誰にでも思いつく内容なら権利になりません。
優れたプログラムは複雑なユニーク性が必要だということです。
そもそも難しい処理用ですね。

ちなみに私の好みはすべて汎用性のあるものを考えることです。
なんでもシンプルが一番です。
プログラマではありませんが。。。。。。

**②だいたいのプロジェクトの立ち上げ理由**

・エラー調査ですね。実験として公布し意見交換をし、その後商品に生かす場合が多いです。

・一部OSS化の高度な機能を有償化するパターン。
　結構多いです。広告としてOSS部分による知名度を上げることを狙って
　いる様子です。

・社内勉強プロジェクトや社内選抜もれプログラムをフリーから育てる。
　こういう場合もあるようです。

**③ビジネスになる場合**

Zabbixが有名ですが、ソフトをフリーにし、サポートをビジネスにするという手法です。
今も同じかはわかりませんが。。。調べたときはそのように書いてました。


**【まとめ】**
フリーの権利は最近多くなりましたね。
ソフトだけではなく、アプリやキャラクターなども参戦しています。
初音ミクは自動広報を狙ったものでしたね。
あの規模の広がり方は誰かが協力しているとしか言えないので真似は禁物だと思います。有名商品の地道な営業は数年を使った全国行脚が一般です。
インターネットに無料サイトが多いのも広告収入を狙ったものが多いです。
昔見ていたサイトにいきなりスポンサーがつくことはありませんか。
新しい広告枠ですね。
フリー化によるビジネスの形態変化は結構見ていると興味深いです。
ポチエス(EsExt)からコンパイル済みAutoHotKeyスクリプトを実行する場合のパラメータに関する問題


## 使用するアプリ
- [ポチエス置き場](http://www.raythebm.net/room_fu/pochi_s/index.html)
    - esExt5146
- [AutoHotkey](https://autohotkey.com/)
    - 1.1.29

コマンドラインパラメータとして、フォルダを含む複数のパスを渡したい場合。

## ポチエスが生成するコマンドライン
esExt5.iniでのコマンドラインの指定は、例えば以下のようになる。
test.exeは、Ahk2Exe.exeでコンパイル済みのAutoHotKeyスクリプトだとする。

```txt:esExt5.ini
C:\Apps\test.exe | AHK test
    > "%-M"
```

`%M`は、ポチエス自体に複数のファイル/フォルダが渡された場合、それをまとめて展開するマクロ。
`-`を付けた場合、フォルダパスが渡された場合に末尾の`\`を削除して渡す。
`%M`をクォート（シングル`''`でもダブル`""`でも）で囲むと、ファイル/フォルダのパスそれぞれをクォートする。

つまり、↑の設定の場合、AutoHotKeyスクリプトに渡されるコマンドラインは以下のようになる。

```
C:\Apps\test.exe "c:\dev\1.txt" "c:\dev\2.txt" "c:\dev\3.txt"
```

**パスにスペースが含まれる場合だけクォートしてくれ**、ということはできない。
よっぽど使用範囲が限定されていない限り、常にクォートしたファイル/フォルダのパスを次のアプリに渡すことになる。
この点に、ちょっとだけ注意が必要。

## AutoHotKey側パラメータ解釈
以下、AutoHotKeyでのパラメータへのアクセスは`A_Args`オブジェクトを用いることとする。

- [Passing Command Line Parameters to a Script](https://autohotkey.com/docs/Scripts.htm#cmd)

どっちかっていうとコイツのほうが悪いんだけど。

どうもコイツ、いったんパラメータ全体を単一の文字列として受け取った後、分割して`A_Args`オブジェクトに格納する、といった処理をやっているっぽい。

どういうことか。さきほどのコマンドラインを見てみよう。

```
C:\Apps\test.exe "c:\dev\1.txt" "c:\dev\2.txt" "c:\dev\3.txt"
```

test.exeは、`"c:\dev\1.txt" "c:\dev\2.txt" "c:\dev\3.txt"`という**文字列**をパラメータとして受け取る。

次に、「ダブルクォートで囲まれた部分は一つのパラメータ」「空白文字はパラメータの区切り」であるとして文字列を分割する。

- c:\dev\1.txt
- c:\dev\2.txt
- c:\dev\3.txt

これが、`A_Args`オブジェクトにそれぞれ格納される。

- A_Args[1] -> c:\dev\1.txt
- A_Args[2] -> c:\dev\2.txt
- A_Args[3] -> c:\dev\3.txt

と、いうのがまあ、想定される動作だよね。

問題は、個々のパラメータの**末尾に`\`（バックスラッシュ）が含まれる場合**。

AutoHotKeyにおいては、デフォルトのエスケープ文字は `` ` `` （バッククォート）なのだが、パラメータの解釈においては`\`（バックスラッシュ）もエスケープに使われてしまうようなのだ。たぶん。

ここで、test.exeの中身を、以下のようなループでパラメータを表示するスクリプトにしてみる。

```txt:test.exe
For index, Target in A_Args
{
    MsgBox, , %A_scriptname%, %Target%
}
```

これを、以下のようなコマンドラインで実行したとする。

```
C:\Apps\test.exe "c:\dev1\" "c:\dev2\a.txt"
C:\Apps\test.exe "c:\dev1\" "c:\dev2\"
```

前者だと、パラメータに相当する文字列は`"c:\dev1\" "c:\dev2\a.txt"`。
すると、「c:\dev1" c:\dev2\a.txt」という謎の文字列を吐いてくる。

後者だと、パラメータが`"c:\dev1\" "c:\dev2\"`で、表示が「c:\dev1" c:\dev2"」になる。

`\"`はリテラルなダブルクォートだよ、というのはまだわからんではないが、エスケープされてないダブルクォートを消すわりに`c:\dev1" `で一つのパラメータとして解釈しない感じなんなの？
先に分割してから両端のダブルクォートを削除すりゃいいだろうが！

んで、パラメータの末尾が`\`でない、つまり、以下のようなコマンドラインであれば、期待通りに各パラメータを表示してくれる。

```
C:\Apps\test.exe "c:\dev1" "c:\dev2\a.txt"
C:\Apps\test.exe "c:\dev1" "c:\dev2"
```

いちおう、パラメータが複数の`"`とスペースを含み、かつ末尾が`"`である場合に、分割して`A_Args`に格納し直す……といった処理がAutoHotKey側で書けなくもないが、ちょっとやってらんない。

要するに、ことコンパイル済みのAutoHotKeyスクリプトをポチエスから実行する場合、パラメータとして渡すマクロは**`%M`ではなく`%-M`でなければならない**ということ。

言うまでもないが、コマンドプロンプト等のコンソール上から実行する場合も、末尾に`\`を含むフォルダパスを渡してしまわないよう留意せねばならない。
【初心者備忘録】TextViewやテキスト入りButtonを回転させる時のお話

縦に90度回転したテキストを描画したい時、とりあえずrotationを使ってこう書く事を考えると思う。

```xml:rotation_bad.xml
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/sampleTextView"
    android:text="@string/sampleText"
    android:rotation="90"
    android:gravity="center" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/sampleButton"
    android:text="@string/sampleText"
    android:rotation="90"
    android:gravity="center" />
```

実行するとすぐにわかるが、思った通りにならない。layout_widthとlayout_heightでViewの大きさを定義した後、rotationは中身のTextに対してのみ実行されるため。縦書き用にクラスを継承して作り直しているようなものもあったが、とりあえず簡単な解決策のひとつとしてこんなものを。

###ConstraintLayoutを使って上手い位置にTextViewを持って来ればいいじゃん


```xml:rotation_good.xml
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Space
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/textSpace" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1"
        android:id="@+id/sampleTextView"
        android:text="@string/sampleText"
        android:rotation="90"
        android:gravity="center"
        app:layout_constraintTop_toTopOf="@+id/textSpace"
        app:layout_constraintBottom_toBottomOf="@+id/textSpace"
        app:layout_constraintStart_toStartOf="@+id/textSpace"
        app:layout_constraintEnd_toEndOf="@+id/textSpace"
        android:translationZ="10dp" />

</android.support.constraint.ConstraintLayout>
```

下に置くViewでスペースだけ確保した上で、それを無視して新しく上からTextViewを被せる。正方形のViewであれば回転させても問題は起こらないのがポイントで、中央揃えであればこれで上手くいく。左揃え、右揃えも被せるTextViewの位置をずらせば可能だし、Spaceの部分をButtonにすればボタンでも同じことが可能。
translationZを正の値にしているのは、下に置いているViewの種類によっては逆にTextViewが被ってしまってテキストが表示されないため。

クラスを作って回転TextViewを実装できると楽なので時間がある時に考えておこうかなー。
Oculus Goで「デスクトップをリクエスト」してるのにAmazon Prime Videoが見れない時の対処法

# よく紹介されている手順

1. Oculus Goのホームより、ナビゲーション > ブラウザを選択します
2. 検索窓で「Amazon Prime Video」のページを表示します
3. ログインします
4. **右上の「デスクトップをリクエスト」ボタンをクリックしてから再生ボタンを押します**
5. 動画が再生されます

# 自分の場合

上記の方法を試すと、「デジタル権利エラー」というメッセージが表示され、再生されませんでした。

「Oculus Go Prime 見れない」とかでググると、「デスクトップをリクエスト」を確認しろというページしか出なくて途方にくれていました。

しかし、有志のツイートを頼りに解決することができました。
ぜひ一度下記の手順も試してみてください！

# 解決方法

1. ブラウザの右のタブの設定より、「閲覧データのクリア」を選択
2. 「サイト設定」にチェックをいれ、「データを削除」をクリック
3. 任意のPrime Videoを再生
4. **動画再生前に画面下部にアクセスの許可を求めるメッセージが表示されるため、「許可」をクリック**
    - この手順ですが、選択する前に次の状態に進んでしまうと上記のエラーが発生してしまいます。
    - この手順がうまく行かなかった場合は1からやり直してみてください。
5. 動画が再生されます


# 謝辞

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">一番過去まで遡って履歴系をクリアしたら見れるようになりました</p>&mdash; Az (@AzMini777) <a href="https://twitter.com/AzMini777/status/996394669633228801?ref_src=twsrc%5Etfw">2018年5月15日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

非常に参考になりました、ありがとうございました！
viewDidLoadで画面遷移をしてないのに、「Unbalanced calls to begin/end appearance transitions」エラーが出る時

# エラー状況
`Unbalanced calls to begin/end appearance transitions`エラーでぐぐると、「`viewDidLoad`や`viewWillAppear`内で画面遷移をしているのが原因」なパターンが多くヒットする。
が、それをしていないのに起きる時のはなし。

## エラーが発生したコード
簡略版。こんな感じのコードで起きた。

```swift
class ViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        getTimeline() // サーバーから取得したデータをもとに、非同期でViewをreloadする
    }

    // 子のViewControllerを返す処理。
    // XLPagerTabStripというライブラリを使用してます。
    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        return [hogeVC(),fugaVC()]
    }
}
```
ポイントは2つ。
- **ViewController内に、ContainerViewでViewControllerの子供を持つ**
- **`viewDidLoad`内で通信処理を呼び出し、その中でViewを更新している**

# そもそもこのエラーの原因は?
`Unbalanced calls to begin/end appearance transitions`は、<font color="ORANGE">**親のViewControllerの表示が確定していない状態**で、子のViewControllerを扱うことで生じる</font> ことがほとんど。

よって、先の例で言えば**`getTimeline()`**が元凶である。
なぜなら、viewDidLoadを抜けた後にViewのreloadが走り、それが終わることで初めて表示が確定する仕様になっており、その確定の前に`viewControllers`が呼ばれてしまうから。

# 解決策
*非同期でViewを更新する処理*を、`viewDidAppear`に移す。
先の例で言えば、こうすれば解決する。

```swift
class ViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        getTimeline() // サーバーから取得したデータをもとに、非同期でViewをreloadする
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        return [hogeVC(),fugaVC()]
    }
}
```

ただし、Appear後に非同期処理を開始するのが不満な場合は、異なる策をとる必要がある。
Railsのactive_model_serializerについて学ぶ_100DaysOfCodeチャレンジ10日目(Day_10:#100DaysOfCode)

## はじめに

この記事はTwitterで人気のハッシュタグ`#100DaysOfCode`をつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した10日目の記録です。

## 動作環境

* ruby 2.4.1
* Rails 5.0.1

## 現在学習している内容のリポジトリ

https://github.com/yuta-ushijima/notebook-api-on-rails

## 本日学んだこと

* active_model_serializer(アクティブ・モデル・シリアライザー)

## active_model_serializer(アクティブ・モデル・シリアライザー)とは？

RailsをAPIサーバーとして使う際に事実上必須となるライブラリ。JSONを作成する際に色々と便利な機能を提供してくれる。

カスタマイズ性が高いので使いこなせればかなり心強い味方に。


## 公式リポジトリ

https://github.com/rails-api/active_model_serializers/tree/0-10-stable

## 実行コマンド

```
bundle exec rails g serializer モデル名

(例)
bundle exec rails g serializer contact

# 実行結果
Running via Spring preloader in process 3267
create  app/serializers/contact_serializer.rb
```

上記のコマンドを実行することで、appディレクトリ配下にserializersディレクトリが自動で作成され、指定したモデル名のファイル(ここでは`contact_serializer.rb`)が作成される。

なお、serializer生成時のデフォルトは以下のような中身になっています。

```
class ContactSerializer < ActiveModel::Serializer
  attributes :id
end
```

## ファイルの中身について

ここでもう一度デフォルトのファイルを表示します。

```
class ContactSerializer < ActiveModel::Serializer
  attributes :id
end
```

ファイルに記述されているattributesですが、このメソッドにシンボルを渡すと、`render json`などでJSONオブジェクトを表示させた際にレスポンスされるkeyとvalueを絞り込むことができます。

現在の状態でGETにより一覧取得のAPIを叩くと、idとその値だけがレスポンスとして返ってきます。

```
# localhost:3000/contactsをGETで叩く
# 以下は実行結果

[
    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    },
    {
        "id": 4
]
```

## レスポンスされるJSONのアダプタを設定

ActiveModelSerializerには、アダプター(JSONの表示形式)を3種類用意しています。

* `:attributes (default)`
* `:json`
* `:json_api`

先ほど紹介したattributesはデフォルトで設定されているアダプタです。

残りの`:json`と`:json_api`をデフォルトで使いたい場合には、initializersディレクトリに別途`ams.rb`というような(名前はなんでもいいです)ファイルを作成し、そこに以下のようなコードを書く必要があります。

```
# config/initializers/ams.rb
ActiveModel::Serializer.config.adapter = :json_api
```

こうすることで、JSONAPIという、JSONの仕様を決めている組織が制定している表示形式に沿ったレスポンスが返ってきます。

2018年6月現在、最新の仕様バージョンはv1.0。

アダプタをjson_apiにした時と、デフォルトのattributesにした時の違いは以下の通り。

### attributes

```
[
    {
        "id": 1,
        "name": "中島 光",
        "email": "rhianna_walsh@maggio.net",
        "birthdate": "2016-05-02",
        "birthday": "2016/05/02"
    }
  ]
}
```

### json_api
```


{
    "data": [
        {
            "id": "1",
            "type": "contacts",
            "attributes": {
                "name": "中島 光",
                "email": "rhianna_walsh@maggio.net",
                "birthdate": "2016-05-02",
                "birthday": "2016/05/02"
            }
        }
   ]
}
```

`:json_api`形式だと、より構造が明示的になっているのがわかります。

`type`の値として書かれているのがモデル名で、attributesに記載されているのが、initializerのファイルでattributesメソッドに渡したシンボルがkeyとvalueでそれぞれレスポンスとして返ってきていますね。


## 参考リンク

https://qiita.com/romukey/items/b78906e91a0355e1e77a

https://techracho.bpsinc.jp/hachi8833/2017_09_28/45536

https://sandragon.hatenablog.com/entry/2018/02/03/180018
Sceneの視点が右クリックで変えられないバグ【Unity】

はじめまして、ますみです！

[![自己紹介.png](https://www.umi-mori.jp/wp-content/uploads/2023/02/introduction_banner_2-2048x533.png)](https://bit.ly/banner_intro_masumi_creator_qiita)


# \#バグの内容
- 「`Sceneにおいて、視点を回転させようとしても回転しないバグ`」

別の言い方をすると、

- 右クリックで視点を移動したいけど、手のマークになってしまう。
- 目玉が出てこないバグ

\>> バグの動き （右クリックで動かすと手のマークになってしまう）
![unity2.gif](https://qiita-image-store.s3.amazonaws.com/0/240280/3a66e301-a709-fa92-b6c3-7ae851bf55e9.gif)

\>> 目的とする動き　（右クリックすると、目玉が出てきて、視点を移動できる）
![unity1.gif](https://qiita-image-store.s3.amazonaws.com/0/240280/fb066a53-9208-9874-7289-306adecc7ac3.gif)

# \#バグの原因
端的にいうと、「`視点が固定されてしまっているから`」です。

Sceneの右上を見ると次のようなマークがついています。
ここの鍵マークによって、Sceneでの視点の回転が固定されます。

\>>鍵が解除された状態 （自由に回転する状態）
<img width="120" alt="unity.png" src="https://qiita-image-store.s3.amazonaws.com/0/240280/a36bbd30-2b83-8cf5-3228-815b5f18808e.png">

\>>鍵がロックされた状態 （回転が固定された状態）
<img width="120" alt="unity2.png" src="https://qiita-image-store.s3.amazonaws.com/0/240280/eee5e3b7-36fc-4623-a778-1ce935740a06.png">


# \#デバッグ方法
## 方法①
「`鍵をアンロックする`」ことによって、自由に動くようになります。

## 方法②
その他に、右上のレイアウトを"2 by 3"などにレイアウトを変更する方法もあります。


# 最後に
最後まで読んでくださり、ありがとうございました！
いかがだったでしょうか？

この記事を通して、少しでもあなたの学びに役立てば幸いです！

:::note info
【仕事の相談はこちら】
お仕事の相談のある方は、下記のフォームよりお気軽にご相談ください。

[問い合わせフォームはこちら](https://forms.gle/G5g1SJ7BBZw7oXYA7)

もしもメールでの問い合わせの方がよろしければ、下記のメールアドレスへご連絡ください。

info*galirage.com（*を@に変えてご送付ください）

🎁 「生成AI活用の無料相談券」もしくは「生成AIの社内ガイドライン（無料PDF）」を『公式LINE』で配布中 🎁
『生成AIを業務に活用したいけど、どうしたらいいかわからない』といった声を多くいただきます。

Galirageでは公式LINEにて、チャットやオンライン会議で「完全個別の生成AI活用無料相談会」を実施しております！
（期間限定で実施しているため、ご興味ある方はお早めに以下のLINE公式アカウントをご登録ください^^）
https://lin.ee/rvz6lMN

※ 予告なく、キャンペーンを終了する可能性がございますが、ご了承ください。

【業務内容】
具体的には、以下のお仕事を中心に受け付けております！（[詳しくはこちら](https://galirage.notion.site/Galirage-AI-c2f3945fafb0433d8d2fd03e56927fd8)）
1. 受託開発（例：生成AIを使った社内システムの開発）
2. コンサルティング（例：技術戦略のアドバイス）
3. 講演（例：社内研修、イベント登壇）

※ 特に「生成AIを使ったシステム開発のご依頼」が多く、ご好評いただいております。

【これまでの相談事例】
以下のようなご相談が多くあります。

🔑 機密情報を漏洩させないための、生成AIのシステム構築をお願いしたい。
🤖 自社データを用いたFAQチャットボットの作り方を知りたい。
💡 ChatGPTを、自分たちの事業にどのように活かせるか、アドバイスやアイデアが欲しい。
:::
# おまけ
エンジニアの仲間（データサイエンティストも含む）を増やしたいため、公式LINEを始めました🎉

「**一緒に仕事をしてくれる方**」「**友だちとして仲良くしてくれる方**」は、友だち追加をしていただけますと嬉しいです！（仲良くなった人たちを集めて、「ボードゲーム会」や「ハッカソン」や「もくもく会」もやりたいなと考えています😆）

とはいえ、みなさんにもメリットがないと申し訳ないので、特典を用意しました！

友だち追加後に、アンケートに回答してくれた方へ「**エンジニア図鑑（職種20選）**」のPDFをお送りします◎

https://lin.ee/hFUN4TL

[![](https://www.umi-mori.jp/wp-content/uploads/2023/10/line_banner_v2.png)](https://lin.ee/hFUN4TL)
Python3でTwitter API

##1.準備##
下記のサイトを参考にしてください。
https://cre8cre8.com/python/twitter-api.htm

##2.APIの認証設定##
設定ファイル

```config.py
CONSUMER_KEY = ""
CONSUMER_SECRET = ""
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""
```
それぞれに**1.準備**で作成した値を入れる。

##3.Code1##
まずは自分ツイートした内容を任意の数表示。

```python:show_twi.py
# -*- coding:utf-8 -*-
import json, config
from requests_oauthlib import OAuth1Session
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK,CS,AT,ATS)
url = "https://api.twitter.com/1.1/statuses/user_timeline.json"
num = input(str("何件のツイートを表示しますか？"))
params ={'count' : num}
req = twitter.get(url, params = params)

if req.status_code == 200:
    timeline = json.loads(req.text)
    for tweet in timeline:
        print(tweet['user']['name']+'::'+tweet['text'])
        print(tweet['created_at'])
        print('----------------------------------------------------')
else:
    print("ERROR: %d" % req.status_code)
```

##4.Code2##
次にキーワードを入れて検索し、任意の数表示。

```python:search_twi.py
# -*- coding:utf-8 -*-
import json, config
from requests_oauthlib import OAuth1Session

#API認証情報
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK,CS,AT,ATS)

#API取得
url = "https://api.twitter.com/1.1/search/tweets.json"

#検索情報と検索件数の入力
print("何を調べますか?")
keyword = input(">> ")
print("何件表示しますか?")
num = input()
print("---------------------------------------")

#検索情報と検索件数
params = {'q' : keyword, 'count' : num}

req = twitter.get(url, params = params)

if req.status_code == 200:
    #正常に接続できたら処理をする
    search_timeline = json.loads(req.text)
    for tweet in search_timeline['statuses']:
      print(tweet['user']['name'] + '::' + tweet['text'])
      print(tweet['created_at'])
      print('------------------------------------')
else:
    print("ERROR: %d" % req.status_code)  
```

##5.Code3##
最後にツイートしてみる。

```python:post_twi.py
# -*- coding:utf-8 -*-
import json, config
from requests_oauthlib import OAuth1Session

CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK,CS,AT,ATS)

url = "https://api.twitter.com/1.1/statuses/update.json"

#投稿内容入力
print("呟く内容は？")
tweet = input('>> ')
print('-------------------------------')

#パラメータのセット
params = {"status" : tweet}

req = twitter.post(url, params = params)

if req.status_code == 200:
    #正常に処理できたら
    print("Success!")
else:
    print("ERROR : %d" % req.status_code)

```

##6.メモ##
API初めて使ったけど、便利だし、Pythonだとスッキリ書ける。
Dockerコンテナにssh接続してAnsibleを試す

良い子はコンテナにssh接続なんてしてはいけないヨ。実験だからね。


コンテナを起動してsshサーバー入れる。rootパスワードも変えておく。

```bash
$ docker run --rm -i -t docker.io/centos:7.3.1611 /bin/bash
# yum install openssh-server
# useradd ymko
# passwd ymko
# passwd root
```

sshサーバーが起動しないのは暗号キーが生成されていないため

```bash
# /usr/sbin/sshd -D
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
# ssh-keygen -A
# /usr/sbin/sshd -D
```

ssh-copy-idでsshが通るように公開鍵を登録
できないのはホストの`.ssh/known_hosts`に既に書かれているので削る

```bash
$ ssh-copy-id 172.17.0.2
/usr/bin/ssh-copy-id: ERROR: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ERROR: @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
ERROR: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ERROR: IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
ERROR: Someone could be eavesdropping on you right now (man-in-the-middle attack)!
ERROR: It is also possible that a host key has just been changed.
ERROR: The fingerprint for the RSA key sent by the remote host is
ERROR: SHA256:
ERROR: Please contact your system administrator.
ERROR: Add correct host key in /home/ymko/.ssh/known_hosts to get rid of this message.
ERROR: Offending RSA key in /home/ymko/.ssh/known_hosts:6
ERROR: RSA host key for 172.17.0.2 has changed and you have requested strict checking.
ERROR: Host key verification failed.

```

接続OK。rootも通す。

```bash
$ ssh-copy-id 172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is SHA256:
ECDSA key fingerprint is MD5:40:
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ymko@172.17.0.2's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '172.17.0.2'"
and check to make sure that only the key(s) you wanted were added.

$ ssh 172.17.0.2
[ymko@fc8b90a03429 ~]$ logout
Connection to 172.17.0.2 closed.

$ ssh-copy-id root@172.17.0.2
```

ansibleをセットアップ

```bash
$ python36 -m venv venv
(venv) $ source venv/bin/activate
(venv) $ pip install ansible
```

hostファイルを作る

```bash
$ cat hosts
[container]
172.17.0.2
```

`-u root`とすればrootで実行される

```bash
$ ansible -i hosts all -m ping
172.17.0.2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
$ ansible  -i hosts all -a "id"
172.17.0.2 | SUCCESS | rc=0 >>
uid=1000(ymko) gid=1000(ymko) groups=1000(ymko)
$ ansible -u root -i hosts all -a "id"
172.17.0.2 | SUCCESS | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
```


# 参考

Dockerで立てたコンテナにsshで接続する - $shibayu36->blog;
https://blog.shibayu36.org/entry/2013/12/07/233510
Ubuntu 16.04 LTS ServerでSSHのホストキーが自動生成されない - Qiita
https://qiita.com/xeres/items/6a32729916b07b37ea68
ansibleを使ってみる — そこはかとなく書くよん。 
http://tdoc.info/blog/2013/04/20/ansible.html
CVPR2017 tracking



利用するアルゴリズムを選択する際には、ベンチマークが必要です。著者が新規のアルゴリズムを発表する場合には、従来のアルゴリズムに比べて、どのように優れているのかを比較しています。有名な学会で採択されているような論文では、新規のアルゴリズムを学べるだけではなく、そのような人が既存のアルゴリズムをどのように評価しているのかがわかります。トップ　カンファレンスでは、採択されるまえに十分なレビューが入るので、そのような点でもぜひ読むべきでしょう。


### Action-Decision Networks for Visual Tracking with Deep Reinforcement Learning

http://openaccess.thecvf.com/content_cvpr_2017/papers/Yun_Action-Decision_Networks_for_CVPR_2017_paper.pdf

その論文中の
Table 1: Summary of experiments on OTB-50
では、いくつかの手法の比較のされています。non-realtimeとrealtimeとしてアルゴリズムが分類されています。

![Table1.png](https://qiita-image-store.s3.amazonaws.com/0/83761/d4ba967f-d852-0e75-b655-fd1c88449c1d.png)


では、自分の用途にどのアルゴリズムを選択すべきなのか。
次の論文は組み込みのための追跡についての視点で述べている。

### Action-Decision Networks for Visual Tracking with Deep Reinforcement Learning

https://www.researchgate.net/publication/317803149_Evaluation_of_Visual_Tracking_Algorithms_for_Embedded_Devices

上記の中に次のグラフがある。　Fig. 1. Box plot illustrating averages and distributions of frame rates. Four (4) outliers
above 50 FPS between Median Flow and KCF are missing to make the y axis scale
better.


![Fig1.png](https://qiita-image-store.s3.amazonaws.com/0/83761/73fc0425-9da2-8ae7-9870-8d93e2c28533.png)

median flow
KCF がフレームレートが出るアルゴリズムであることがわかる。


Fig. 4. Success plots of the five tested trackers showing the fraction of frames success-
fully tracked as a function of required Jaccard index.

![fig4.png](https://qiita-image-store.s3.amazonaws.com/0/83761/1b53a1c8-b1f1-4881-ed8f-76a1f7ec9955.png)

Overlap threshold に対する追跡の成功率を示しています。


### Online Object Tracking: A Benchmark

http://faculty.ucmerced.edu/mhyang/papers/cvpr13_benchmark.pdf

https://www.cv-foundation.org/openaccess/content_cvpr_2013/papers/Wu_Online_Object_Tracking_2013_CVPR_paper.pdf

### ベンチマークのgithub
CVPR2018も含まれている。
https://github.com/foolwood/benchmark_results


### 使用するアルゴリズムを選択するにはどうしよう

追跡アルゴリズムによる追跡の計算時間の違いを集計する。
追跡中のobjectの個数によって追跡の計算時間を集計する。

それによって、選ぶべきアルゴリズムを明らかにする。
BitbucketのPRのdescriptionの入力形式を従来のマークダウンに戻す

2018年6月中旬くらいからBitbucketのPRのdescription欄の入力方式がマークダウン形式からWYSIWYGの入力に切り替わってドキュメントの記述効率が著しく低下しました。従来のマークダウン形式に戻すための手順の共有になります。

**※これは2018年6月26日時点の状況なので `Atlassian Editor` も後日改善されるかもしれません。**

### 新入力方式
![PR sample.png](https://qiita-image-store.s3.amazonaws.com/0/106217/44d635b8-46cc-80c7-6d9a-eb4b5d506f4d.png)

#### ツライところ
* インラインコードで日本語入力できない
* インラインコードから通常の入力に切り替えるのが面倒
* URLリンクの入力が謎の仕様
* テーブル表記が使いものにならない
* 他のエディタで入力したマークダウン記述をコピペできない
* etc.

### 設定変更方法
![profile.png](https://qiita-image-store.s3.amazonaws.com/0/106217/e431bbb1-468e-ae26-44da-853598f789c3.png)

アカウントメニューから `Bitbucket Labs` を選択します。

#### Bitbucket Labs
![Atlassian Editor.png](https://qiita-image-store.s3.amazonaws.com/0/106217/e4cdd58a-030d-db34-ce50-c595e8446c96.png)

`Atlassian Editor` をOFFにしましょう。

#### Atlassian Editor OFF
![Atlassian Editor OFF.png](https://qiita-image-store.s3.amazonaws.com/0/106217/25984ab3-a397-d1f9-dba5-b09da69cd709.png)

PRのdescription欄が従来のマークダウン入力に戻ります。

![PR standard.png](https://qiita-image-store.s3.amazonaws.com/0/106217/3a84c940-f5fe-2b63-417f-85afa21a849b.png)
pm2でマインクラフトのサーバーをデーモン化

# 動作環境
- ubuntu16.04

# pm2って何
- Nodejsアプリを動かすための仕組みの一つ
- インスタンスと一緒にNodejsアプリを自動起動(デーモン化)したり、pm2コマンドから停止したりできる
- Nodejsはシングルスレッドだけど、pm2で起動する事でCPUのクラスタリングもできる
- Nodejsアプリのログの保存も勝手にやってくれる
- アプリが落ちたら１０回までは再起動してくれる
- 似た用途の物では forever というのがある

個人的にはNodejsのウェブサーバの負荷テストをする事があったので、
ログを保存してくれる　＆　再起動を勝手にやってくれる
の２つの特徴にかなり助けられました・・・

# pm2で自動起動するメリット
- pm2から起動、停止する事が出来る(もしcrontabでやってたら一々面倒です)
- コマンドから起動できるものは大体なんでもこの手順で自動起動出来る

# 自動起動手順
### 1.npmをインストールする
npmっていうのはNodejsのパッケージマネージャです。
nodejsとnpmをインストールします。
```
$ apt update
$ apt install nodejs npm
```

### 2.pm2をインストールする
```
$ npm install -g pm2
```

### 3.Nodejsで外部コマンドを実行するプログラムを書く
```
$ cd [server.jarのあるディレクトリ]
$ echo 'console.log(require('child_process').execSync('java -jar server.jar').toString())' > main.js
```

### 4.pm2で実行する
必ずserver.jarのあるディレクトリに移動してからおこなってください、そうしないと / にワールドデータが作成されてしまいます。
```
$ pm2 start main.js --name="minecraftserver"
```

### 5.起動できている事を確認する
```
$ pm2 list
```
### 6.pm2の状態を保存する
```
$ pm2 startup
$ pm2 save
```
pm2 saveをすると、その時の起動状態をインスタンス起動時に復元してくれます。
試しにrebootして、しばらく時間が経った後にサーバーに接続できるか確認してみてください。

# 停止するには
サーバーのコマンドを入力したいときはpm2での起動はしたくないですよね。
### 停止する時
```
$ pm2　stop minecraftserver  
```
### 再起動後も自動起動しないで欲しい時
```
$ pm2 delete minecraftserver
$ pm2 save
```

以上の手順でマインクラフト以外の様々なプログラムを自動起動したり起動/停止管理する事も可能です。
画像が重なっている場合のフェードインとフェードアウトへの対策。RenderTextureとui::ImageView

cocos2d-x 3.x系です。

#### 画像を前後に重ねた状態でフェードイン・フェードアウト処理をすると、背面にある画像が透けて見えます。
今回は両方同時にフェードイン・フェードアウトさせるのでマスクする事にしました。

前面の画像に合わせたマスク画像を作りそれを使って背面の画像をクリッピングする物です。

__ClippingNode__を使う
ただ、これには問題があったらしい。
それでも今なら大丈夫でしょうと思ってやります。
http://ringworks.jp/blog/tech-blog/%E3%80%90cocos2d-x%E3%80%91%E3%83%9E%E3%82%B9%E3%82%AF%E5%87%A6%E7%90%86%E3%81%AE%E6%82%A9%E3%81%BE%E3%81%97%E3%81%84%E5%95%8F%E9%A1%8C


問題：
　この前面に配置した画像はサイズが可変になる仕様だが、Spriteクラスはサイズ変更ができない。
　ui::ImageViewにすると矩形でマスクされてしまって、これも使えなかった。

解決
　RenderTextureクラスを使用する
　（ClippingNodeでマスクに使うTextureを用意できればよく、このRenderTextureが使える）
　ui::ImageViewでサイズ変更させた物を描画して、それをマスク画像として利用する。
　サイズ変更の仕様に対応できた。
（サイズ変更してステンシル用のtextureに再描画する必要がある。）

### ClippingNode生成

//マスク用のテクスチャ生成のパート
//任意のサイズで、適切なPositionに

```C++
RenderTexture* tex = RenderTexture::create(width, height);
target−>addChild(tex);//retainで良いのだが、寿命が同じなのでaddChildeした
```

//マスク用の画像をImageViewで生成

```
auto mask_s9s_node = ui::ImageView::create("mask.png");
```

//テクスチャに、マスクする画像を描画。 適宜画像サイズを変更させていく。

``` c++
//textureへの描画開始
tex->beginWithClear(1, 1, 1, 1);

mask_s9s_node->setContentSize(Size(100, 100));
mask_s9s_node->cocos2d::Node::visit();

//textureへの描画終了
tex->end();
```

---

##### その他
1. RenderTextureの位置合わせ方法、
SetPosition()を行う。
ただし、
　AnchorPoint指定は機能しない
　ContentSizeも機能しない

2. visit()命令のタイミングに注意すること。詳細は別途余裕があれば、
Raspberry Pi 3BにPHP7.2とnode.jsとcloud9をインストール

# はじめに

RaspberryPi 3B+でLaravel 5.5を使った開発をするために環境(php7.2 + node.js 8.11系)を構築したい。

---
[20180717 Update] `2018-06-27-raspbian-stretch.img`を使ってDebian Buster)のリポジトリを追加したところ、怒涛のパッケージ更新がかかります。新しいRaspbianのイメージを使うことを推奨したいです。

**[20180719 Update]** Raspberry Piの次世代(Debian Buster)のリポジトリを追加して、`apt update & upgrade`を実行して再起動すると、Raspbian OSが壊れるらしく**起動しなくなりました。**回避策を探してます。

[20180719 Update] 別のリポジトリを参照することで、とりあえず回避可能。

# 手順
## php7.2が含まれているリポジトリを追加
### 【プランA】aptのソースにRaspberry Piの次世代(Debian Buster)のリポジトリを追加

raspbianの元になっている現在のDebianは`stretch`。`stretch`ではphpは7.1までサポートするらしく、php7.2が必要ならば`Buster`のリポジトリを指定する必要があるらしい。

```diff:/etc/apt/sources.list
  deb http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi
  # Uncomment line below then 'apt-get update' to enable 'apt-get source'
  #deb-src http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi

+ deb http://mirrordirector.raspbian.org/raspbian/ buster main contrib non-free rpi
```

`apt update & upgrade`を実行すると、800近いパッケージ(合計600MBくらい)がアップデートされます。。


### 【プランB】aptのソースに https://packages.sury.org/php/ のリポジトリを追加

```shell
$ sudo apt-get -y install apt-transport-https lsb-release ca-certificates
$ sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
$ sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
```

## aptのデータを更新 [20180717 Update] 

```
$ sudo apt update
$ sudo apt upgrade
```

## aptでphp7.2をインストール

```shell
$ sudo apt install php7.2 php7.2-common php7.2-cli php7.2-fpm php7.2-mbstring php7.2-sqlite3 php7.2-pdo-sqlite php7.2-json php7.2-xml
```

## composerをインストール
```shell
$ sudo apt install composer

$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer 1.6.5 2018-05-04 11:44:59
```
## aptでnode.jsをインストール
```shell
$ sudo apt install nodejs npm

$ node -v
v8.11.2

$ npm -v
1.4.21

$ sudo /usr/local/bin/npm install -g npm
$ npm -v
6.1.0
```

## cloud9(WEB-IDE)をインストールと実行
```shell
$ sudo apt install openssl
$ sudo apt install tmux
$ git clone https://github.com/c9/core.git c9sdk
$ cd c9sdk
$ scripts/install-sdk.sh
$ node server.js -p 8080 -a :
```
【重要更新】termuxのPATHの設定が出来た

私は、Termuxの設定が分からずに、困っていました。
色々調べて、ようやく分かりました。

```
termux-exec
```
上記のコマンドをインストールしてから、必要なものをインストールすると、普通のLinuxのパッチで使うことが出来ます。
詳しい使い方は、こちらを読んでください。
https://wiki.termux.com/wiki/Termux-exec

このコマンドをインストールする前にパッケージをインストールしている場合は、このコマンドをインストールしても、反映されません。
もし、インストールしていたら、上記のコマンドをインストールしてから、再度目的のパッケージを再度インストールしてください。

#nodebrewのインストールできました
今回nodebrewをTremuxで、使う必要が出たので、今回インストール出来て助かりました。
こちらの記事を参考にしました。
https://qiita.com/sawapi/items/adfc11465d034f4f2cf9

記事に書かれている一行でインストールしようとすると、パッケージが２つ足りないと言われます。
それをインストールすると、インストールを完了できます。

#nodejsが動いていない
バージョン管理できるようになりました。
でも、バージョン指定しても、動いていないことが分かりました。
npmのバージョン管理のnをインストールしても、使えないです。
termuxは、PAHTの管理がLinuxと違うので、新しくコマンドを追加する形で使うソフトやパッケージは使えないのではと思っています。

#パッケージ管理は無理か？
パッケージ管理のnやnvmを試しました。
いずれも駄目でした。


PATHで見に行った先に、ファイルがないと言う感じのエラーになります。

Termuxでもシェルが使えるので、設定で何とかできそうに思います。
実際、パッケージ管理は、インストールできます。
でも、ネットの記事を読むとnodejsは、termux専用のようです。
そのため、パッケージ管理でnodejsのバージョン指定をしてインストールしても、termuxに反映されないような感じです。
Termuxは、複数のシェルがプリインストールされているので、設定ファイルの書き方が分かると解決できるかも知れません。
Sourcetree透明バグ(Windows10)

## はじめに
Windows UpdateをしたところSourcetreeが起動しなくなったので色々やったことをまとめる。

## 症状
Sourcetreeを起動すると透明なウィンドウが表示される。
感で操作したところ表示がされてないだけで機能は生きていた。

## やったこと
透明ウィンドウが表示されるが機能はそのままだったのでおそらくグラフィック系がおかしくなっていると推測。
とりあえず設定ファイルを消したり再インストールをしてみたが改善しなかったのでドライバやDirectX等グラフィック関係をひたすら見るもわからず、ググったところ[AtlassianのQ&A][atlassian]にあったレジストリの追加をしたところ正常に表示されるようになった。

Windows10pro版のアップデートでなってしまうらしい。

[atlassian]:https://community.atlassian.com/t5/Sourcetree-questions/Source-Tree-%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E3%81%A8%E9%80%8F%E6%98%8E%E3%81%AA%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%81%8C%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%8C%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86/qaq-p/812676
ビルド・エラー："error: stray '\302' in program"について


error: stray '\302' in program
error: stray '\240' in program
コード中に非ASCII文字が含まれていたため発生。

原因は無効な文字が含まれていたせいだった。
'\302'は全角スペースでいいのですが、
'\204'は分からなかったんですが何かの制御文字だったと思います。

その他、全角スペースへの対応について少し。

- 可能ならエディタの設定で全角スペースを可視化する。

- 全角スペースが含まれている場所を探す方法
ソースファイルをgrep

```shell
find ./directry -type f | xargs grep "　"
```
- sed で全角スペースを半角スペースに置換する。

```shell
sed -i 's/　/ /g' filepath
```

悩み、全角スペースに限らず、非ASCII文字を検索する方法はないのだろうか、、、
コマンドラインで名取さなを再生する

Nodeが入っていれば、

```
$ npx sana-voice てね
$ npx sana-voice エッチ
```

はい。という感じで再生されます。

もちろんインストールした方がいいでしょう。

```
$ npm i -g sana-voice
```

[さなボタン](http://sanabutton.ojaru.jp/) から引数なしならランダムもしくはキーワード付きで再生します。また一度再生したものはキャッシュされます。

[GitHub: akameco/sana-voice: さなボタンからランダムに再生するCLI](https://github.com/akameco/sana-voice)

## コマンドラインでmp3を再生するには

さて、`sana-voice`を作るに当たりそれぞれのOSのmp3プレイヤーをラップしたmp3プレイヤーのCLIツールである`symphogear`を書きました。

[GitHub: akameco/symphogear: cacheable mp3 player from files and url for CLI](https://github.com/akameco/symphogear)

```
npm install --global symphogear
```

でインストールできます。

それぞれのOSにはコマンドラインで動作するシンプルなmp3プレイヤーがあります。
例えば、MacOSならデフォルトで`afplay`が使えます。

mplayer等について以下の記事が役立つと思います。

[mplayerというソフトが素晴らしすぎて困る - プログラムモグモグ](https://itchyny.hatenablog.com/entry/20121009/1349793583)

`symphogear`は以下のプレイヤーのラッパーです。

- mplayer
- afplay
- mpg123
- mpg321
- play
- omxplayer
- aplay
- cmdmp3

ヒットしたプレイヤーによってmp3を再生します。
これによって、環境の差異を考えずに済みます。

Node.jsでこのようなコマンドを実行したいときは、Promiseベースで`child_process`を扱える[execa](https://github.com/sindresorhus/execa)が便利です。`await execa(player, [await fetch(link)])`みたいな感じで書けます。

また、afplayなどはurl形式を直接再生できず、ローカルにファイルを保存する必要がありますが、symphogearはurlを指定して直接再生することが可能です。
また一度再生したファイルをキャッシュされるので同じurlが指定されてもhttpリクエストが飛ぶことはありません。

## 関連

さなボタン http://sanabutton.ojaru.jp/ は一言でいうと努力が素晴らしいので、一度その情熱を確認すべきだと思います。

名取さな関連でいうと、24時間名取さなのことを考えているオタクが作ったttene.nvimがオススメです。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">改行する度に(InsertModeでEnterする度)に名取さなの「ってね」が再生されるプラグインです。<a href="https://t.co/JdmmOXw8Qv">https://t.co/JdmmOXw8Qv</a></p>&mdash; ひまのあ🍆🍆🍆@1日目 西め07a (@h1manoa) <a href="https://twitter.com/h1manoa/status/1008785980986462208?ref_src=twsrc%5Etfw">June 18, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Heroku ではじめる IoT

2018/6/25 に行われた Heroku Meetup #21 の LT で発表した内容となります。
https://herokujp.doorkeeper.jp/events/75593

Node.js の IoT フレームワークである zetta を Heroku にデプロイして、 L チカ（ LED を点滅させること）を実行するまでをまとめました。

#Zetta を Heroku にデプロイする

https://github.com/zettajs/zetta-cloud-sample

上記のページに deploy to heroku button があるので、こちらを利用して Zetta を Heroku にデプロイします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215729/88aad2f0-fb26-a306-d354-2ab425cbd5d7.png)

#Heroku にデプロイした Zetta サーバーのURLを確認する

http://{your-app-name}.herokuapp.com

ブラウザに「{"class":["root"],」ではじまるJSONが表示されていれば、デプロイ成功です。

```json
{"class":["root"],
"links":[{"rel":["self"],"href":"http://xxx.herokuapp.com/"},
{"title":"cloud","rel":["http://rels.zettajs.io/server"],
"href":"http://xxx.herokuapp.com/servers/cloud"},
{"rel":["http://rels.zettajs.io/events"],
"href":"ws://xxx.herokuapp.com/events"},
{"title":"Device Tutorial","rel":["http://rels.zettajs.io/peer",
"http://rels.zettajs.io/server"],
"href":"http://xxx.herokuapp.com/servers/Device%20Tutorial"},
{"rel":["http://rels.zettajs.io/peer-management"],
"href":"http://xxx.herokuapp.com/peer-management"}],
"actions":[{"name":"query-devices",
"method":"GET",
"href":"http://xxx.herokuapp.com/",
"type":"application/x-www-form-urlencoded",
"fields":[{"name":"server","type":"text"},
{"name":"ql","type":"text"}]}]}
```

#ローカル PC にモックデバイスを作成する

https://github.com/zettajs/zetta/wiki/LED-Device

上記のページの説明にしたがってモックデバイスを作成します。
Heroku の Zetta サーバーと通信するため、 link を追記する必要があります。

```js
.link('http://{your-app-name}.herokuapp.com/’)
```

```index.js
process.EventEmitter = require('events').EventEmitter
var zetta = require("zetta");
var led = require("zetta-led-mock-driver");
var DEVICE = require("./device.js");

zetta()
 .name("Device Tutorial")   
 .use(DEVICE)
 .link('http://{your-app-name}.herokuapp.com/')
 .listen(1337, function(err) {
   console.log("Zetta server is running on port 1337");
 });
```

#モックデバイスを起動する

node.js v8 では正常に通信できないため、node.js v6 でモックデバイスを起動してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215729/bb7cd1d5-0b93-a3fe-6522-0d944971e98d.png)

#Browser でモックデバイスを操作する

https://github.com/zettajs/zetta-browser

上記のページの zetta-browser を Heroku にデプロイして、 Zetta サーバーの URL を指定するとモックデバイスを操作することができます。

http://{your-app-name}.herokuapp.com/#/device?url=http:%2F%2F{your-app-name}.herokuapp.com%2Fservers%2FDevice%2520Tutorial%2Fdevices%2Fb7427fa5-7f75-4d7b-89bc-aab1bcd2b788

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215729/fcd857fb-6f4b-f894-4d5d-2d43ae14bd94.png)



ブラウザで turn-on 、 turn-off をクリックすると、モックデバイスを起動したコンソールに turn-on 、 turn-off が表示されることを確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215729/02b549a4-23ce-d685-e387-b8a94d6a5b30.png)


#Zetta とは

http://zettajs.org/

詳細は上記ページで確認できます。

・Node.js で開発されたIoT 用途のフレームワーク。OSS。
・ラズベリーパイなどのハードウェア側のハブとして利用できる。
・デバイスを検索して識別することが可能。
・リアルタイムに通信可能。
・エンドポイントとして REST API を利用できる。
com.sforce.soap.enterprise.SaveResultのエラーメッセージ取得

```java
SaveResult[] sr = binding.create((new SObject[] {c}));
// ログを出力
for (int j = 0; j < sr.length; j++) {
    System.out.println("\nItem: " + j);
    if (sr[j].isSuccess()) {	                            
        System.out.println("Contact with an ID of " + sr[j].getId() + " was updated.");
    } else {                        
        // There were errors during the update call,
        // go through the errors array and write
        // them to the console.
        for (int i1 = 0; i1 < sr[j].getErrors().length; i1++) {
            com.sforce.soap.enterprise.Error err = sr[j].getErrors()[i1];  
            System.out.println("Errors were found on item " + j);
            System.out.println("Error code: " + err.getStatusCode().toString());
            System.out.println("Error message: " + err.getMessage());
        }
    }      
}  
```
rustとscalaとkotilnの勉強 数当てゲーム(scala) 2回目

TRPLの数当てゲーム
scalaがあんまりだったので書き直した

とりあえずBreaksは使わなくなったが・・・
scalaの省略ルールが難しすぎて覚えられない

```scala
import scala.util.Random
import java.security.SecureRandom
import scala.util.{Try, Success, Failure}
object Main{
	def main(args:Array[String]){
		val secret_number = new Random(new SecureRandom()).nextInt(99)+1
		println(s"秘密の数字は次の通り：$secret_number")
		println("数をあててごらん")
		println("ほら、予想を入力してね")
		gen().map(t=>t.map(s=>s.toInt))
			.filter(_.isSuccess)
			.map(s=>s.get)
			.map(i=>
				i match{
					case i if i == secret_number => i
					case i if i < secret_number => println("ちいさすぎる"); i
					case i if i > secret_number => println("おおきすぎる"); i
					})
			.filter(_==secret_number)
			.head
		println("正解")
	}

	def gen():Stream[Try[String]]={
		import scala.io.StdIn
		import scala.collection.immutable.Stream
		return Stream.cons(Try(StdIn.readLine),gen)
	}
}
```
JavaScriptで標準入力を扱う方法

JavaScriptではNode.jsを使うことで標準入力を扱うことができる。
##例として簡単なAOJの問題を解いてみる

[AIZU ONLINE JUDGE](http://judge.u-aizu.ac.jp/onlinejudge/)

>たて a cm よこ b cm の長方形の面積と周の長さを求めるプログラムを作成して下さい。

input

>a と b が１つの空白で区切られて与えられます。

output

>面積と周の長さを１つの空白で区切って１行に出力して下さい。

Sample input

```
3 5
```

Sample output

```
15 16
```

##実際に解いてみる
```JavaScript:main.js
const main = (standardInput) => {
    const lengthList = standardInput.split(' ');
    const varticalLength = Number.parseInt(lengthList[0]);
    const horizonLength = Number.parseInt(lengthList[1]);

    console.log(`${varticalLength * horizonLength} ${2 * (varticalLength + horizonLength)}`);
}

main(require('fs').readFileSync('/dev/stdin', 'UTF-8'));
```

ポイントは`/dev/stdin`を使うこと。

##まとめ
Node.jsを使うことでJavaScriptで標準入力と標準出力が扱えるようになりました。以上。
Flutterで2つのFloatingActionButtonを表示する方法

Flutterで2つのFloatingActionButtonを表示する方法を紹介します。

Scaffoldのコンストラクタにある`floatingActionButton`を使用します。

名前からはFloatingActionButtonのインスタンスしか設定できなそうですが、実はWidgetで宣言されています。
つまりColumnで2つのFabをラップして1つのウィジェットにして渡すことで2つのFloatingActionButtonを持つScaffoldを作成することができます。

コード例は次の通り。

```dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: Column(
        verticalDirection: VerticalDirection.up, // childrenの先頭を下に配置
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          FloatingActionButton(
            backgroundColor: Colors.redAccent,
            onPressed: () {
              print("pressed");
            },
          ),
          Container( // 余白のためContainerでラップ
            margin: EdgeInsets.only(bottom: 16.0), 
            child: FloatingActionButton(
              backgroundColor: Colors.amberAccent,
              onPressed: () {
                print("pressed");
              },
            ),
          ),
        ],
      ),
      appBar: AppBar(
        title: Text("Hoge"),
      ),
      body: Text("Hoge")
    );
  }
```

こんな感じになります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/18273/d0c0ec53-0f0d-b0ca-691c-6e9aa2a3ada8.png" width="300px">
Apex Visualforceの出力内容を取得

### PDFとして出力内容を取得

```java
PageReference pg = Page.user_page;
pg.getParameters().put('key', value);
pg.setRedirect(true);
Blob bl = pg.getContentAsPDF();
```
visualforceではヘッダ apex:page 内に記述： renderAs="pdf"

### Apex+VisualForceでPDFをダウンロードする場合

出力メソッドの最後でヘッダを指定する

```java
Apexpages.currentPage().getHeaders().put('content-disposition', 'attachment; filename=' + 'file_name.pdf’);
```
GitHub入門

##　gitの設定

1. `git config --global user.email [mail address]`でGitHubに登録しているメールアドレスを入力(--globalをつけるとPCで保存される？)
2. `git config --global user.name [username]`でGitHubのユーザーネームを入力(--globalは上記と同じ)
3. `git config --list`で設定の確認(`git config --unset [settings name]`で設定の削除)
3. `cd hogehoge`でgitをインストールするディレクトリまで移動する
4. `git init`でgitリポジトリとして初期化

* ".gitignore"ファイルにgit管理したくないファイルを記述する
* "~/.gitconfig"にusernameとemailが記述されてるか見る
* ディレクトリごとに設定した場合は"./git/config"

## ファイルをローカルリポジトリへコミット
### ステージングエリアへ移動

* `git add hogehoge` :特定のファイルを移動
* `git add --all` :コミットされていないすべてのファイルを移動
* `git status` :状態を確認

### リポジトリへコミット

* `git commit` :コミットを行うが、コミットメッセージの入力を求められる
* `git commit -m "hogehoge"` :メッセージ付きでコミットを行う
* `git log` :変更履歴の確認

## GitHubの登録
###リモートリポジトリの作成

1. リポジトリ一覧にある"New repository"から新規リポジトリを作成
2. "Repository name"・"Description"を入力
3. "Initialize this repository with a README"の項目にチェックを入れる
4. "Create repository"ボタンを押して作成

### リモートリポジトリの登録

1. 対象リポジトリページの"Clone or download"からリポジトリのURIをコピーする
2. `git remote add origin [repository URI]`でURIの登録
3. `git remote -v`で確認

### リモートリポジトリの編集など

* `git remote set-url [repository name] [repository url]` :URIの変更
* `git remote rm [repository name]` :削除

## コミットの流れ

1. `git add hogehoge` or `git add --all`
2. `git commit -m "commit message"`
3. `git push [remote repository name] [branch name]`

* 初回コミット時にリジェクトされた場合は`git merge --allow-unrelated-histories origin/master`を実行すると良い

## 

## ブランチ操作
### ブランチ一覧表示

1. `git branch`

### ブランチ作成

1. `git branch [branch name]`

### ブランチ名の変更

1. `git branch -m [old name] [new name]`

### ブランチ削除

1. `git branch -d [branch name]`

### ブランチの切り替え

1. `git branch [branch name]`
 * `[branch name]`は異動先のブランチ

### ブランチのマージ

1. `git merge [branch name]`
 * `[branch name]`はマージ内容の反映元であることに注意

### ブランチ操作を見やすい形で表示する呪文

1. `git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- 
*%an%C(reset)%C(bold yellow)%d%C(reset)' --all`

## クローン

1. `git clone [GitHub repository url] [local directory]`

## プル

1. `git checkout [local branch name]` :変更をもってきたいブランチに移動
2. `git pull [remote repository name] [branch name]` :どこから変更をもってくるか
cursesで絵を描く

ちょっとCLI上で描画したくてcurses使おうとしたら、なんかエラって怒られた。
これって自分で入れなきゃいけないんだっけ...（汗） ってなったので、そのメモ

```shell

fatal error: curses.h: No such file or directory
 #include <curses.h>
          ^~~~~~~~~~
```

aptを使ってインストール。ちなみにncursesはnew cursesの略。

```shell
apt-get install libncurses5-dev
```

とりあえず、テスト用に作ったプログラムを走らせる。というか車を走らせる。

```shell
gcc car.c -o car -l curses
./car
```

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/204926/75a3b439-8283-38ce-ea24-b1c3d65a4f18.gif)


一応、コードも載せておく。

```c:car.c
#include <unistd.h>
#include <curses.h>
#include <string.h>

int main(void){
  char *car_up= "  ___  ";
  char *car_mp= "_|[ ]|_";
  char *car_dp= "-O---O-";
  char *blank = " ";
  int car_len = strlen(car_dp);
  int dir = +1;
  int pos = 1;
  int ground = 20;

  initscr();
  clear();

  while(1){
    move(ground-2, pos);
    addstr(car_up);
    move(ground-1, pos);
    addstr(car_mp);
    move(ground, pos);
    addstr(car_dp);
    refresh();
    if(pos >= (COLS-car_len))
      break;
    usleep(50000);
    move(18, pos);
    addstr(blank);
    move(19, pos);
    addstr(blank);
    move(20, pos);
    addstr(blank);
    pos += dir;
  }

  endwin();
}

```
Parcel v1.9.xで Cannot destructure property `parser` of 'undefined' or 'null'. が出るときは

# tl;dr

`parcel-plugin-typescript`のバージョンを`1.0.0`まで上げましょう

# 環境

* Parcel: v1.9.0以降
* TypeScript

# 状況

Parcel v1.8.xのプロジェクトでParcelのバージョンを上げると以下のようなエラーが発生しました

```
🚨  /my/project/src/index.pug: Cannot destructure property `parser` of 'undefined' or 'null'.
    at Object.MakeTranspileAsset (/my/project/node_modules/parcel-plugin-typescript/build/frontend/assets/classes/transpile.js:7:24)
    at new module.exports (/my/project/node_modules/parcel-plugin-typescript/build/frontend/assets/forked.js:6:43)
    at Parser.getAsset (/my/project/node_modules/parcel-bundler/src/Parser.js:81:12)
    at HTMLAsset.addURLDependency (/my/project/node_modules/parcel-bundler/src/Asset.js:115:8)
    at HTMLAsset.processSingleDependency (/my/project/node_modules/parcel-bundler/src/assets/HTMLAsset.js:89:26)
    at ast.walk.node (/my/project/node_modules/parcel-bundler/src/assets/HTMLAsset.js:138:43)
    at traverse (/my/project/node_modules/posthtml/lib/api.js:105:26)
    at traverse (/my/project/node_modules/posthtml/lib/api.js:111:5)
    at traverse (/my/project/node_modules/posthtml/lib/api.js:105:17)
    at traverse (/my/project/node_modules/posthtml/lib/api.js:111:5)
```

PugであろうがHTMLであろうがこのエラーが発生してしまいます

# 原因

このプロジェクトで使用していた`parcel-plugin-typescript`が`v0.7.1`と少し古いのが原因だったようです

# 対応

```
$ yarn add -D parcel-plugin-typescript
```

でプラグインのバージョンを`v1.0.0`まで上げたらエラーは解消されました
kotlinでandroid入門 メッセージ表示

kotlinでアンドロイドの小技


### Toast
下部への一時的なメッセージ
時間で自動的にきえまます
![Toast.png](https://qiita-image-store.s3.amazonaws.com/0/258658/c4e949a8-904d-f3db-f364-0c5194dafdf2.png)

こんなのです

```
    Toast.makeText(applicationContext, message, Toast.LENGTH_SHORT).show()
```
これで表示されます。

### Snackbar
Toastと同じように下部へのメッセージ表示
違いは、時間ではなく、次の操作をすると消えます
![Snackbar1.png](https://qiita-image-store.s3.amazonaws.com/0/258658/40e1ea67-f848-6f4d-ea49-39827c538ca2.png)

```
    Snackbar.make(v, "Snackbarの表示", Snackbar.LENGTH_LONG).show()
```


単純にメッセージ表示するだけでなく、細かく、設定もできます

![Snackbar2.png](https://qiita-image-store.s3.amazonaws.com/0/258658/3f8e4f00-ec49-552f-8bcb-2dff2be2a214.png)


```
    // Snackbar 下部へのメッセージ表示　（表示内容を調整して)
    val snackbar = Snackbar.make(v, "画面下部へ", Snackbar.LENGTH_SHORT)
    snackbar.view.setBackgroundColor(Color.RED)
    snackbar.setActionTextColor(Color.WHITE)
    snackbar.setAction("更新") {
        // 更新の処理
        tmpLowDisp("更新")
    }
    snackbar.show()
```

コード[ここ](https://github.com/bokufolivora/hinagata)置きました
他にも色々やってるのでごちゃごちゃしてます
CUDDの簡単な利用例: Graphvizを用いた可視化

思いついたものから更新中。インストールについては過去記事参照で、Mac上のg++ 6.4.0を利用して、ネット上から拾ってきたCUDDのver3.0を利用: [Binary Decision Diagramを扱うためにCUDDをインストール](https://qiita.com/takilog/items/c5e8cc9daaebf29dd53e)

# 使用例: BDDの可視化(graphviz経由)

- C++の理解度がイマイチなので文字列渡すところが少し悩んだけど実装読んだらOKだった。
- 使っている論理関数はインストール記事で動作させた関数の例
- 第一引数のinameは、BDDのrootからのレベル（index）の順番で文字列を与えると、dotに反映される
- 第二引数のonameは、描画するvector<BDD>の1番目から順番に文字列を与えると、関数の名前としてdotに反映される

```C++
#include <iostream>
#include <vector>
#include "cuddObj.hh"

using namespace std;

int main() {
  Cudd mgr;
  BDD x = mgr.bddVar();
  BDD y = mgr.bddVar();
  BDD f = x * y;
  BDD g = y +!x;
  cout << "f is" << (f <= g ? "" : " not")
       << " less than or equal to g" << endl;

  // dump
  const vector<BDD> vec1 = {f};
  const vector<BDD> vec2 = {f, g};
  auto fp1 = fopen("dot/output1.dot", "w");
  auto fp2 = fopen("dot/output2.dot", "w");
  const char* iname[2] = {"x", "y"};
  const char* oname[2] = {"f", "g"};
  mgr.DumpDot(vec1, iname, oname, fp1);
  mgr.DumpDot(vec2, iname, oname, fp2);
  return 0;
}
```

- 出力したf/gの例

![output2.png](https://qiita-image-store.s3.amazonaws.com/0/7181/4c642e2d-6abc-074e-b316-b72402b6638a.png)


- CUDDのdotファイルはうまく簡素化されていて、よく見ると点線に種類があることが分かる
  - 細い点線と中ぐらいの点線

- これを見慣れた二分決定図に直すには、簡単にはBDDをADDに変換すると良い（中身がどう違うかは知らない）

```cpp
const vector<ADD> vec3 = {f.Add(), g.Add()};
auto fp3 = fopen("dot/output3.dot", "w");
mgr.DumpDot(vec3, iname, oname, fp3);
```

![output3.png](https://qiita-image-store.s3.amazonaws.com/0/7181/790adb5c-6489-5e03-4b6b-c9816bb9ae98.png)
react native render メソッド　延々に呼ばれる

# react native 開発中にさっきまで普通に画面が読み込まれていたのにプログラム書き足してから実行すると真っ白な画面で肝心なcomponentが映し出されない。。。

consoleを見てみるとどうやらrenderメソッドがひたすら呼ばれている。

renderメソッドを確認してみると

```js

 onPress={this.setState({isModalVisible: true})}
```

このような記述をしていた！ setStateがひたすら呼ばれそれと同時にrenderメソッドが呼ばれていた模様。



```js

 onPress={() =>  {this.setState({isModalVisible: true})}}
```

これに直したら映るようになった、

しかし、なぜこれでうまくいったかは謎である。。。。。。。。

そもそも何でひたすらsetStateされるのだろうか。