OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】モジュール

# モジュール

- 「インスタンス化できないクラス」のようなもの。
    - `Class` クラスは `Module` クラスのサブクラス。
    - 「クラス = モジュール + インスタンス化能力」

## Mix-in

- 制限された多重継承

- Rubyは、クラスは1つしか継承できない。
- Rubyは、モジュールという「クラスのようだがクラスではない」ものならば何個でも継承できる。
    - クラスがモジュールを継承することを `include` すると呼ぶ。

### モジュールと継承

- `include` したモジュールはクラスの `ancestors` メソッドに現れる。

- **クラスがモジュールを `include` すると、モジュールのインスタンスメソッドが手に入る**。

### インスタンス化不能性

- モジュールをインスタンス化することはできない。
- Mix-inはあくまでも「トッピング」。主となるクラスに従として実装を提供するための「機能の集まり」(module)であり、具体的なもの(object)ではない。

## 名前空間

- 異なる名前空間に属する同じ名前のクラスは、たまたま名前が同じでも別物として扱われる。
- Rubyでは名前空間を提供するためにもモジュールを利用する習慣がある。

# 参照

- [初めてのRuby](https://www.oreilly.co.jp/books/9784873113678/)
iOS標準のショートカットアプリで、色々なアクションを効率化してみよう

# この記事について
この記事は、[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html)の開発チーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu)」にて行っているアウトプット企画である
「[チーム「オキザリス」Advent Calendar](https://qiita.com/advent-calendar/2020/oxalis)」の24日目の記事です。

# あるハッカソンでのできごと
先日、同期と一緒にあるハッカソンに出ました。
開発テーマはなんでもOK！の自由度高いハッカソンだったので
「食欲旺盛な同期 Pくん が彼女の外出中に冷蔵庫を開けると、その場で彼女のお叱りの音声が響き渡り、
彼女に『あいつ冷蔵庫開けてんぞ！』と告げ口LINEが飛ぶ **つまみぐい防止のための冷蔵庫監視システム** 」なるものを作りました。
システム構成を超ざっくり説明すると、Raspberry Piでセンサデータを取得して、冷蔵庫の開閉を検知する、というものです。
検知した時に彼女のお叱り音声を流したり、LINEのAPIをたたいて、LINE Botでメッセージを送信したりします。

で、今回お話ししたいのはこの監視システムではなく、
彼女の在宅状況次第で、システムをオン・オフできるリモコンを作った方法 です。
このリモコンを実現する時に、 iOSのショートカット機能 を利用しました。

# ショートカットとは
![Screenshot 2020-12-23 22.35.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696809/3a52e426-6089-0d5b-87a9-54a7008cc093.png)

iOS13以降で標準アプリとなった、iPhoneのアプリです。
このアプリ、単にメールや電話などのアプリの起動を楽にするアクションが選べますよ〜、とかそういう機能だけではなく、色々なアクションのフローを構築できます。

今回のハッカソンでは、「起動用のアプリをわざわざ構築したり、物理的なスイッチを用意するより手軽にやりたいよね」ということで、このショートカットの利用を決めました。

# 何ができるの？
ショートカットを使ったことがなくても、
「〇〇さんにLINE」「アラームを設定」をみたことはあるような... という方も多いと思います。
ですが、実はただ特定の条件で一つのアプリを実行するための機能ではないんです。

## 複数のアクションを繋げられる
iPhoneの標準アプリ、自分でインストールしたアプリの色んなアプリのアクションが用意されています。
例えば撮った写真をすぐにインスタに投稿できるショートカット。

<img width="50%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696809/d80cb30d-70f3-45c5-d7f8-adb321606b11.png">

このショートカットを実行すると

<img width="50%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696809/a892688a-787e-f318-58c2-71818664a2b3.png">

インスタのアプリが開いて、この画像をストーリーにあげるか、フィードにあげるか選べるようになります。

## アクションを繋げる時に条件分岐もできる
ただ順番に繋げるだけではないんです。
アクションの結果次第で条件分岐することもできます。

例えば、前述のハッカソンの監視システム起動ショートカットはこんな条件分岐を設定してました。
<img width="50%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696809/96f871cb-165c-e217-7014-8b7377811fdf.png">
最初のスクリプト実行で、今監視用システムのプロセスが開始しているか確認します。
開始してなかった場合（＝シェルスクリプトの結果が値がない、のとき）は起動用のスクリプトを実行し、
開始していた場合（＝その他の場合、のとき）は何もしない、という仕組みでした。

## アクションがすごく充実してる
先程のSSH経由のスクリプト実行のように、
iPhoneにインストールされているアプリの操作以外にも様々なアクションがあります。

- URLエンコード
- Base64エンコード
- ハッシュ生成
- 変数設定
- WebページでのJavaScript実行

などなど、実は色々なアクションが用意されています。



# おわりに
iOSの標準アプリ、ショートカットのご紹介でした。
あまり標準アプリを使わない方も多いかもしれませんが、ショートカットは実は色々な組み合わせを楽しめるアプリだったりします。
この機会にぜひつかってみてはいかがでしょうか？
Xが起動したらアプリを自動起動する

#1.はじめに

RaspberryPiのXにログインしたときに、自動的にGUIアプリを起動する方法をまとめました。

#2.設定手順

>前提として、自作のアプリは、`/home/pi/app/hoge.py`にあるものとします。

####(2)設定ファイルの準備

ここでは、lxsessionの設定ファイルを活用します。

ホームディレクトリの`.config`の下に、lxsessionの設定フォルダを準備

```bash
$ mkdir -p ~/.config/lxsession/LXDE-pi
```

lxsessionのautostartファイルのひな形をコピー

```bash
$ cp /etc/xdg/lxsession/LXDE-pi/autostart ~/.config/lxsession/LXDE-pi
```

####(2)autostartファイルの編集

```bash
$ cd ~/.config/lxsession/LXDE-pi
$ nano autostart
```

```sh:autostart（修正前）
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
```

ここでは、以下の設定を追加しています。

 - スクリーンセーバーをOFFにする
 - 画面をスリープさせない
 - パネルもOFFにする
 - 自作のアプリ`hoge.py`起動する（パスの指定は、インストール先に合わせて修正のこと。`hoge.py`に実行属性を付加していれば、先頭のpthon3のコマンドは不要です）

```sh:autostart（修正後）
#@lxpanel --profile LXDE-pi
#@pcmanfm --desktop --profile LXDE-pi
#@xscreensaver -no-splash
@xset s off
@xset s noblank
/usr/bin/python3 /home/pi/app/hoge.py
```

Xを再起動すると、自動的に自作のアプリが起動するようになります。

#3.ログの出力先

自作のアプリ`/home/pi/app/hoge.py`が出力するログは、下記に出力されます。

```bash
$  cat /home/pi/.cache/lxsession/LXDE-pi/run.log
```

# 参考資料

- http://klee-arc.hatenablog.com/entry/2015/04/20/002157
- https://wiki.archlinux.jp/index.php/Display_Power_Management_Signaling
- https://www.atmarkit.co.jp/flinux/rensai/linuxtips/285offx.html
irb でサクっとパフォーマンスを調べる

irb の進化が止まらない。最も先進的な REPL は Ruby の irb かもしれない[^b]。複数行編集，シンタックスハイライト，オートインデント，メソッド名補完は衝撃的だった。

[^b]: 他の言語の REPL を知らずに書いてますので各言語愛好者のマサカリ・オシカリを歓迎します。

さて，2020 年 12 月 20 日リリースの irb 1.2.8 で measure という機能が追加された。
これは式の評価にかかる時間を計測してくれるもの。

Ruby で 100 万番目の素数を表示するのは

```rb
require "prime"
p Prime.lazy.drop(999999).first
```

と書けばいい。答えは 15485863。
これがどのくらいの時間で実行されるのか知りたいとする。計測手段はいくつもあるが irb 上でサクッとできるなら，それはそれで嬉しい。

ではまず

```rb
gem update irb
```

で最新の irb をインストールしておこう。記事執筆時点（2020/12/23）での最新は 1.2.9 だ。

そして，

```shell
irb -r prime
```

で irb を起動する。
いや，もちろん

```shell
irb
```

で起動しておいて，

```irb
irb(main):001:0> require "prime"
```

とやってもいいのだが，面倒なので，使うライブラリーは `-r` オプションに渡したほうがいいだろう。

そして，

```irb
irb(main):001:0> measure
```

と打つと，式の評価時間を計測するモード[^mode]になる・・・はずなのだが，実はバージョン 1.2.8, 1.2.9 では何らかの手違いにより，LoadError が出るようになっている[^le]。
幸い，[measure コマンドが使えるようにするためのプルリクエスト](https://github.com/ruby/irb/pull/150) が @elim さんにより出され，既に取り込まれている。

（2020-12-25 追記）irb 1.3.0（2020-12-24 リリース）にめでたく反映された。これで `measure` が使える。

[^mode]: 本家では「モード」という用語は使われていない。私がこの記事で仮にそう呼ぶだけ。

[^le]: よく分からないけど，gem としてインストールした場合にこの問題が起こるようだ。（2020-12-25 追記）Ruby 3.0.0 にバンドルされる irb は問題ないらしい。

現状では，仕方ないので

```irb
irb(main):001:0> IRB.conf[:MEASURE] = true
```

と打とう。こんなの覚えられないけど，覚えなくていい。次のバージョンでは `measure` でいけるようになるはずだ。（→ 追記：なった）

こうすると，irb 上で式を評価するたび，いちいち時間を測ってくれる。
ではさっそく：

```irb
irb(main):002:0> Prime.lazy.drop(999999).first
processing time: 7.395823s
=> 15485863
```

7.4 秒くらいだった。

計測モードをやめるには

```irb
irb(main):003:0> IRB.conf[:MEASURE] = false
```

とする。
`measure` コマンドが使えるようになったら，

```irb
irb(main):003:0> measure :off
```

でいけるようになるはずだ。

ところで，この手の速度（実行時間）計測では気をつけないといけないことがいろいろある。

irb の measure 機能は，デフォルトでは処理前後の時刻の差を取っているだけのようなので，CPU が他のことで忙しいときに計測すると大きめの値が出そう。
実行時間はさまざまな要因で揺れ動く。実際，さきの 100 万番目の素数は，もう一度測ったら 6.5 秒程度であった。
（2020-12-25 追記）なお，Prime はメモ化を使っているのか，irb を終了せずにもう一度やるとずっと短い時間で終了する。

計測結果が `7.395823s` などと出ていても，有効数字はそんなに無い。表示される桁数が多いのは単に Float をそのまんま表示しているだけ。
まあおそらく小数第二位の桁（0.01 の桁）には意味が無いだろう。

だから，

```irb
irb(main):004:0> 1+1
processing time: 0.000282s
=> 2
```

とやって出てくる「0.000282s」という数字には全く意味が無い。「ホトンドゼロデスネー」としか言えない。
このような〈軽すぎる式評価〉の実行時間は，多数回実行させた時間を繰り返し数で割って求める必要がある。そうなるとベンチマークテストライブラリーの出番なわけで，irb なんかでやることではなくなってしまうだろう。

なお，筆者は試してないが，計測・表示の処理はカスタマイズできるようだ。
ユーザーのホームディレクトリーの .irbrc というファイルに，

```rb
IRB.conf[:MEASURE_PROC][:CUSTOM] = proc { |context, code, line_no, &block|
  # 云々
}
```

てな感じで記述すればいいらしい。
これで，例えば「結果表示は小数第一位までにするぞ」とかが可能になる。

具体的なことは irb のコミットメッセージをどうぞ：
https://github.com/ruby/irb/commit/3899eaf2e21fcb8b6c1ba3fdb1ac4ec8c9b4798f
メモ：RaspberryPiにAzure IoTEdge ランタイムをインストール

Azure IoT Edge ランタイムのインストールを何回か行ったので忘れないようにメモ

#インストール編

詳しい手順は[ここ](https://docs.microsoft.com/ja-jp/azure/iot-edge/how-to-install-iot-edge?view=iotedge-2018-06&tabs=linux)を見るのが確実です。（トラブルシューティングも書いてる）

必要なのはRaspberrypi（Arm32v7以上の機種 zeroはダメでした。）

とりあえず順番にコマンドを実行すればOK



```1.
curl https://packages.microsoft.com/config/debian/stretch/multiarch/prod.list > ./microsoft-prod.list
```
リポジトリがStretchになっているけれども、Busterでもそのままで大丈夫です。

```2.
sudo cp ./microsoft-prod.list /etc/apt/sources.list.d/
```
```3.
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
```
```4.
sudo cp ./microsoft.gpg /etc/apt/trusted.gpg.d/
```
```5.
sudo apt-get update
```
```6.
sudo apt-get install moby-engine
```
コンテナエンジンのインストール

```7.
sudo apt-get install iotedge
```
IoTEdgeランタイム本体のインストール

　
以上でインストールは完了です。

次は設定編です。
WordをPDFに変換

📚WordをPDFに変換する方法。
Word文書をPDF形式に変換する方法を見てください\
http://eezzee.io/blog/word-to-pdf?utm_source=serg

「ファイルを選択」ボタンをクリックして、変換する必要のあるWordファイルをコンピューターからアップロードするか、ファイル選択フィールドにドラッグします。または、クラウドストレージ（ドライブ、Dropbox、またはOneDrive）からファイルを直接インポートします。
アップロードが完了したら、「生成」をクリックします。 WordからPDFへの変換には約数秒かかります。
変換が完了したら、PDF形式でファイルをダウンロードします。
「ダウンロード」ボタンをクリックして、変換されたファイルをコンピュータに保存します
💻ドライブ、Dropbox、OneDrive。
クラウドストレージからファイルを変換する必要がありますか？ Googleドライブ、Dropbox、またはOneDriveから直接インポートし、WordからPDFへの変換を実行します。

💲無料のコンバーター。
このツールを使用して、WordをPDFに完全に無料で変換してください！ファイルサイズと変換数に制限はありません。それは良くなることはできませんね？

📧メールはありません。
電子メールやその他の識別可能なデータを提供する必要はありません。このWordからPDFへのコンバーターを使用するためにレジスターは必要ありません。

📑Word.doc形式。
このWordからPDFへのコンバーターは、.doc、.docm、.dot、.docx、.dotm、.dotx、.odt、.xml、.txt、.xpsWord拡張子と互換性があります。このツールはプラットフォームに依存しないため、使用しているOSに関係なく、WordをPDFファイルに変換できます。

🚂すばやく簡単。
WordからのPDF変換が可能な限り簡単かつ迅速になりました！オンラインでWordをPDFに変換するのに必要な手順は4つだけです。変換速度は、ファイルサイズとサーバーの過負荷によって異なります。
ワンオクに学ぶテックリードのマインドセット

ロックバンド「[ONE OK ROCK](https://ja.wikipedia.org/wiki/ONE_OK_ROCK)」の曲「[アンサイズニア](https://www.youtube.com/watch?v=WgjgACnHuWQ)」の歌詞が
テックリードに求められるマインドセットを学ぶ貴重な題材になることに気づいたので
その歌詞を紹介しつつ解説したい。

> I think this way
> いく通りもある その問いの答えはもうただ
> 原理や理論に従って導き出す
> 何の変哲もないアンサー

外からは分からないことだが、この業界で技術的に新規性のある開発というのは驚くほど少ない。
この業界の仕事のほとんどは既に誰かがやったことの後追いや焼き直し、ほんの少しディテールを変えただけのイミテーションだ。
複雑な要求や非機能要件も知ってさえいれば定石に従って必然的に答えが出る。
エンジニア自身のオリジナルが入り込む余地はほとんどない。

> Hello, hello! なぁきっと
> この世には正解もハズレも 本当は無いハズだから

現代のプログラミング言語はどれを選んでも大抵のことはできる。
特定の言語でなければ実現できないことはほとんどない。
そういう意味で言えばどんな言語を選んでも正解もハズレも無い。
銀の弾丸を求めてHello Worldし続けること無意味なのだ。

> 今を生きるコトは簡単じゃなくて
> ただ楽しけりゃいいってもんでもなくて
> 明日明後日の自分に何が起ころうと
> 責任を持てるかどうかさ

とはいえ日々の業務をこなし続けることは簡単では無い。
技術選定においてどれを選んでも大きな差が無いような選択肢ばかりが並んでいたとしても
自分の興味関心のみで好きに選んでいいというものでも無い
選択した結果として何(仕様変更・障害・教育)が起ころうと
責任を持てるかどうか自分に問い続けなければならない。

> 僕の思う当たり前は 君にとって当たり前かな？
> 君の思う当たり前は 僕にとって当たり前かな？

どんな選択肢も前提が違えば結論が変わる。
自分の前提は相手にとっても同じ前提足り得るか、
逆に相手の前提を自分は理解できているか、
議論の際は確認する必要がある。

> どう思う?さあどうだろう？
> これ自体がもうナンセンスすぎるかな？
> 答えはない。じゃあなんだろう？
> (中略)
> The answer is inside of me.
[ServiceNow]MID Server経由でREST APIを実行してみた

# 概要
MID Server経由でRESTを実行してみました。
色々調べてみたのですがServiceNowから便利な機能が用意されていたわけではなく、
下記の手順で実施
①MID ServerにBATCHファイルを作成
②BATCHファイル実行するQueueを登録
③BATCHファイルに記載してあるCURLコマンドを実行

# 詳細
### ①MID Serverにスクリプト（BATCHファイル）を作成
MID Serverで実行するBATCHファイルを作成します。
ServiceNowで作成後、MID Serverのagent/scriptsフォルダに作成したBATCHファイルが自動で格納されます。

　1.MID Server – Script Filesを実行する。
　2.NameにBATCHファイル名を入力する。
　3.ScriptにCURLコマンドを入力する。
　4.Submitを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/91520202-fe22-d5cc-5f47-01cfd07ba170.png)

### ②BATCHファイル実行するQueueを登録
MID ServerへBATCHファイルの実行依頼を行うQueueを作成します。
MID ServerにてQueueを検知するとBATCHファイルが実行されます。

　1.ECC - Queueを実行する。
　2.NEWを実行する。
　3.Agent欄にMID Server名を入力する。
　4.Topic欄に”Command”を入力する。
　5.Name欄に実行するBATCHファイルのフルパスを入力する。
　6.Queue欄にoutputを選択する。
　7.State欄がreadyであることを確認する。
　8.Submitを実行する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/333b917e-22bc-e91f-0b34-e649631fa259.png)

### BATCHファイルに記載してあるCURLコマンドを実行

　1.QueueはMIDサーバにて処理されるとStateがreadyから変更される。
　（成功の場合はprocessed、失敗の場合はerror)
　2.MID ServerでBATCHファイルが実行されるとQueue欄がinput、payload欄に実行結果が設定された応答Queueが作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/b6ab1134-0c39-9c94-7e00-ead889bf93bc.png)

# 補足
### payloadの文字化け
payload欄は文字コードUTF-8となっているBATCHファイルは
そのまま実行すると文字コードがSJISになる。
そのためpayloadにメッセージを表示したい場合は
BATCHファイルの先頭に`chcp 65001`と記載し文字コードをUTF-8に変更する必要があります。

### BATCHファイルの定期実行
Scheduled jobsを利用し定期的にQueueにレコードを作成するようにすることで実現できます。

```例
var queue = new GlideRecord(‘ecc_queue’); //Queueテーブル
queue.initialize(); //初期化
queue.agent = ‘mid.server.XXXXXXXX’; //MIDサーバ
queue.topic = 'Command';
queue.name = 'c:\\agent\\scripts\\import.bat'; //BATCHファイル
queue.queue = 'output';
queue.state = 'ready';
queue.payload='<parameters><parameter name="skip_sensor" value="true"/></parameters>'
queue.insert();
```
### Queue実行時にエラーになる場合の対処
Queueのpayload項目に下記文言を追加するとエラーがスキップされる。
```例
<parameters><parameter name="skip_sensor" value="true"/></parameters>
```
# 最後に
この方法でREST実行することが出来たがあっているかは不安です。
もっと良い方法がありましたら共有いただけますと幸いです。
【Androidアプリ開発】WebViewのJavaScriptからネイティブのメソッドを呼ぶ

ウェブページをネイティブで包んだアプリを作る際などに、Web側からネイティブアプリ側に情報を渡したいことがある。
普通にJavascriptInterfaceを使えばよいのだが、少しハマった部分があったのでメモしておく。

# 実装方法
基本的には公式の下記のページが参考になる。
https://developer.android.com/guide/webapps/webview?hl=ja#BindingJavaScript

* 呼び出されるメソッドの定義

```kotlin:MainActivity.kt
/** Instantiate the interface and set the context  */
    class WebAppInterface(private val mContext: Context) {

        /** Show a toast from the web page  */
        @JavascriptInterface
        fun showToast(toast: String) {
            Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show()
        }
    }
```


* WebViewにインターフェースを追加

```kotlin:MainActivity.kt
val webView: WebView = findViewById(R.id.webview)
    webView.addJavascriptInterface(WebAppInterface(this), "Android")
```

* 呼び出すJS

```html:test.html
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />

    <script type="text/javascript">
        function showAndroidToast(toast) {
            Android.showToast(toast);
        }
    </script>
```
ネイティブアプリ以外でも表示するサイトであれば、tryでくくってエラーが出ないようにしてあげた方がよさそう。

## 必要な記述
上記に従って実装してみたのだが動かない。
WebViewではデフォルトでJavaScriptが無効になっているようだ。
下記で有効にしてあげる必要があった。

``` kotlin:MainActivity.kt
myWebView.getSettings().setJavaScriptEnabled(true)
```

## おまけ
WebViewではストレージも無効になっていたので、必要な場合はオンにする。

``` kotlin:MainActivity.kt
myWebView.getSettings().setDomStorageEnabled(true)
```
IchigoJamでデデンネする

[デデンネする](http://kutachu.web.fc2.com/dedenne.htm) は、「デデンネ」「エモンガ」もしくは自分で設定した文字列の中の文字を
ランダムで1文字ずつ出力し、設定した文字列が出る(または3万回出力する)まで続ける、というものである。

今回は、これを [こどもパソコン IchigoJam](https://ichigojam.net/) で実装してみた。

※IchigoJamはjig.jpの登録商標です。

# 今回の仕様

まず、「デデンネ」「エモンガ」の中から使う文字列を選ばせる。
任意の文字列を設定する機能の実装は、今回は

* 文字数(と文字種)が同じなら、文字列の変更は本質ではない
* 文字数を増やすことを考えた場合、
  全ての文字が違う5文字の文字列を使うと2千回程度、6文字の文字列を使うと数万回程度の出力が高確率で発生し、
  IchigoJamで実行するには適さない
* 文字数を減らすと、つまんなそう
* ~~以上からあまり意味がなさそうなわりに、めんどくさそう~~

という理由から、見送ることにした。

文字列を選んだら、その文字列の中の文字をランダムで出力していく。
このとき、判定用にどの文字を出力したかの情報を記録していく。
各文字を出力する確率は等確率とするが、「デデンネ」には「デ」が2個含まれるので、
その分「デ」を出力する確率は「ン」「ネ」を出力する確率の2倍とする。
また、IchigoJamでは濁点は別の文字として出力されるため、本体と濁点が別の行にならないように制御する。

指定した文字列が出力されたら、何回出力したかを出力して終了する。

# 実装

以下に今回実装したプログラムを示す。

```
10 ' ﾃﾞﾃﾞﾝﾈ ｽﾙ
20 ?"ﾃﾞﾃﾞﾝﾈ ｽﾙ(1)? ｴﾓﾝｶﾞ ｽﾙ(2)?":S=#FF:P=0:C=0
30 X=INKEY()
40 IF X=#31 GOTO 80
50 IF X=#32 GOTO 140
60 GOTO 30
70 IF S=#0B:?CHR$(10);"ﾃﾞﾃﾞﾝﾈ ｼﾀ ｶｲｽｳ ﾊ ";C;" ﾃﾞｽ":END
80 R=RND(4):S=(S<<2)&#FF:C=C+1:P=(P+1)&#1F
90 IF R=2:?"ﾝ";:S=S|2:GOTO 70
100 IF R=3:?"ﾈ";:S=S|3:GOTO 70
110 IF P=0:?" ";:P=1
120 ?"ﾃﾞ";:P=P+1:GOTO 70
130 IF S=#1B:?CHR$(10);"ｴﾓﾝｶﾞ ｼﾀ ｶｲｽｳ ﾊ ";C;" ﾃﾞｽ":END
140 R=RND(4):S=(S<<2)&#FF:C=C+1:P=(P+1)&#1F
150 IF R=0:?"ｴ";:GOTO 130
160 IF R=1:?"ﾓ";:S=S|1:GOTO 130
170 IF R=2:?"ﾝ";:S=S|2:GOTO 130
180 IF P=0:?" ";:P=1
190 ?"ｶﾞ";:S=S|3:P=P+1:GOTO 130
```

10行目は、`FILES`用のタイトルである。
20行目は、プロンプトを出力し、ついでに出力と判定用の情報を初期化する。
30行目～60行目は、選択を入力させる。
70行目～120行目は、「デデンネ」に関して処理を行う。
130行目～190行目は、「エモンガ」に関して処理を行う。

70行目・130行目は、直近に出力した文字の情報を確認し、指定の文字列を出力していたら出力回数を出力して終了する。
80行目・140行目は、乱数によって次に出力する文字を選ぶ。
また、直近に出力した文字の情報の更新の一部を行うとともに、出力回数・出力位置の情報を更新する。
90行目～120行目・150行目～190行目は、乱数に基づき文字を出力し、直近に出力した文字の情報を更新する。
特に、110行目・180行目は、文字の本体と濁点が別の行にならないようにする制御を行う。

# 実行結果例

YouTube動画 (1:59)
[![IchigoJamでデデンネする - YouTube](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/fdedd966-cd05-d7cd-a443-bc17d8dc0150.png)
](https://www.youtube.com/watch?v=T43hUs_5fN8)

# 結論

IchigoJamで、指定の文字列を出力するまでその中の文字をランダムで出力する「デデンネする」を実装することができた。

なお、この記事とは直接関係ないが、本家「[デデンネする](http://kutachu.web.fc2.com/dedenne.htm)」には

* 判定処理の効率が悪い
* 一部の文字を入力すると誤動作する
* 出力結果をシェア出来ない (出力回数しかシェアできない)

という欠点がある。
これらの欠点を克服した「[ごちうさ見る](https://mikecat.usamimi.info/gotiusamiru/)」を、以前作成・公開した。
VScodeでPHPのコードユニペットを登録・追加する方法

開発に必須で何回も打つこいつ。

```php:qiita.php
var_dump($qiita);
```

簡単に予測変換してくれないから登録した！

#コードユニペットに登録する

##PHP.jsonファイルを見つけ出す

Code > Preferences > User Snippets
検索窓に「PHP」と入力して

```
PHP.json(PHP)
```

を開く。

そしたらこんな内容のファイルが開かれる。

```php:php.json
{
	// Place your snippets for php here. Each snippet is defined under a snippet name and has a prefix, body and
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
}

```

##記述開始

```php:php.json
{
	// Place your snippets for php here. Each snippet is defined under a snippet name and has a prefix, body and
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
	"var_dump": {
    "prefix": "vd",
    "body": [
      "var_dump($1);"
    ],
    "description": "var_dump"
    }
}
```

これで、「vd」→「Enter」キーで、「var_dump( );」を入力できるようになった！

##参照記事

https://jobtech.jp/php/3747/
〜テーブル設計基礎の「キ」　命名規則〜

## 取り返しのつかないことに…
テーブルの命名規則の理解が曖昧なまま、DB設計をしてしまい、アプリがいよいよ完成という頃にミスが発覚しました。大変恥ずかしいですが、初期のテーブル設計は下記のようになっていました。（まさに地獄）
<img width="200" alt="テーブル画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/df97e12d-4bbc-a5e9-f6fd-27600f7c996a.png">
皆様には同じような過ちをして欲しくないため、記録を残すことにいたしました。
内容は初学者向けになりますが、簡単にまとめましたので是非理解度チェックしてみてください！

## 命名規則チェックリスト
### 🔶 テーブル名

#### ①複数形で表記する "〜s"
❌：fruitテーブル
🙆‍♂️：fruitsテーブル
#### ②スネークケースで表記する
❌：fruitBasketテーブル 　(キャメルケース）
🙆‍♂️：fruit_basketテーブル
#### ③英語で表記する。ローマ字は好ましくない
❌：furuutsuテーブル　　　<br>~~(あまり良い例が浮かびませんでした。)~~
🙆‍♂️：fruitsテーブル
#### ④大文字を使用しない
❌：FRUITSテーブル
❌：Fruitsテーブル
🙆‍♂️：fruitsテーブル

### 🔶 カラム名
<font color="Red">カラム名でも基本的にテーブル名と同様な規則が適用されます。</font>

#### ①テーブル名から分かることは書かない
 fruitsテーブルの場合、
❌：fruit_name
🙆‍♂️：name

#### ②１対多の関係で他テーブルのidを参照する場合は単数形を利用する
❌：fruits_id
🙆‍♂️：fruit_id
（補足：他のテーブルの主キーをjoinする場合という意味です。）

#### ③DATE型のカラムは「受動態_on」
❌：opened
🙆‍♂️：opened_on

#### ④TIMESTAMP型のカラムは「受動態_at」
❌：updated
🙆‍♂️：updated_at

おおよそはこれで網羅できているのではないでしょうか。これらの他にも注意すべきことはあるようなので今後の課題とします。
初学者の方は是非調べてみてください。
参考：[【初心者、必見】こんなのあるんだ！データベースの命名規約](https://kimulog.com/2019/12/31/database-naming/)

## 最後に
これらをきちんと理解しておらず、開発の終盤で気付きました。（エンジニア転職を目指す初学者です。）
終盤で気づいたとしても、ORMを用いて開発を行っているため被害は甚大で修正は困難でした…
今回の件で、初期の設計の重要性を身にしみて感じました。もう二度と間違えないと誓います。
そう考えると大変良い勉強になりました。
（もしこの記事に誤りがありましたらご教授いただけると幸いです。）
【FileMaker】事例紹介：家事を見える化するのだ！

今回は、事例紹介です。
私、家事というか、掃除が苦手です。
できれば自分の好きなことしかしたくないです。
でも、家は汚しっぱなしにするわけにはいかないので、「仕方なく」掃除をしています。
でもでも、いつやったか忘れちゃうんです。

だから、作りました。
やった家事を記録するアプリを。
![IMG_3515.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/369b918c-90e0-9dcb-8d1b-1eabc0b82e3c.png)
いや、これ以上にやってるんですが、記録し忘れてる時もありますが。。。（言い訳）

この画面は記録をする画面なので、
1.やったお掃除を選択して、
2.「＋」をタップするとタップした当日の日付で追加されます。
基本は、これだけ。
![IMG_3516.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/805c6edc-cff5-7237-dd09-a9fa0e1857b9.png)

リストもでます。
リストを眺めながら、自分で自分を褒めています。
しっかり掃除をする人からすると、たかだかこんな掃除で褒めるなんて、、、と思うかもしれませんが、重い腰を上げて黙々とやるので、やっぱり褒めたいです。
![IMG_3517.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/772e0ebb-8c0c-ae94-4a3f-7b0dec7c3949.png)

自分で使っているだけなので、ポイントゲットして何かに交換できるとかないのですが、自分の好きなことをやっているとついつい忘れがちなので、何気にずーっと使ってます。
まだFileMaker 17までの機能で動いているので、何かのタイミングで最新のFileMaker 19に合わせた機能を追加してみたいです。
DjangoでCORSカスタムミドルウェアをつくった

この記事は、 [岩手大学 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/iwate-u) の24日目の記事です。

# はじめに
個人開発でDjangoを使ったAPIをつくるときがありました。
そのとき、APIの実装でCORS問題にぶち当たり、CORSの対応をする必要がありました。

Djangoには [django-cors-headers](https://github.com/adamchainz/django-cors-headers) というものがあります。しかし、django-cors-headersを使って実装をしてみましたが、どうも`Access-Control-Allow-Origin`がうまく指定できず、他のサイトからでもリクエストを送れるようになってしまっていました。
そこで、Djangoのミドルウェアを作成しCORS対応をしましたのでご紹介します。

Django初心者なので、間違いなどがありましたらご指摘していただけると勉強になります。

# 実装

実装は以下のようになりました。

```py:custom_middlewares/custom_cors_middleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin


class CustomCorsMiddleware(MiddlewareMixin):
    def process_request(self, request):
        if request.method == 'OPTIONS':
            response = HttpResponse()
            response['Access-Control-Allow-Origin'] = 'http://localhost:3000' # クライアントのオリジン
            response['Access-Control-Allow-Headers'] = ', '.join([ # 許可するHeaderを追加
                'Content-Type',
            ])
            response['Access-Control-Allow-Methods'] = ', '.join([ # 許可するリクエストメソッドを追加
                'DELETE',
                'GET',
                'OPTIONS',
                'PATCH',
                'POST',
                'PUT',
            ])
            return response
        else:
            return None

    def process_response(self, request, response):
        response['Access-Control-Allow-Origin'] = 'http://localhost:3000' # レスポンスを読み取ることができるオリジン
        response['Content-Type'] = 'application/json' # レスポンスタイプ
        return response
```

`process_request`メソッドは、リクエストが来たときに実行され、`None`が返り値の場合はルーティングされている`view`が実行されます。

```
リクエスト
↓
process_request が実行 → 返り値がある場合はその返り値を返す
↓
返り値が None の場合は、リクエストのルーティングに対応する`view`が実行される
```

上記のコードでは、プリフライトリクエストに備えて、`OPTIONS`メソッドの場合は、許可するオリジン・ヘッダー・リクエストメソッドをヘッダーに付与したレスポンスを返すようにしています。

次に、`process_response`メソッドは、レスポンスをするときの最後に実行されます。

```
view を実行
↓
process_request が view から返されたレスポンスを受け取り、レスポンスに処理を行う
↓
レスポンス
```

上記のコードでは、CORSでよく見る

`Access to XMLHttpRequest at 'http://locahost:8000' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.`

のためにレスポンスを読み取ることができるオリジンを指定し、またレスポンスタイプに`application/json`を指定しています。

あとは、このカスタムミドルウェアを`settings.py`に追加してあげれば完了です。

```py:your_application_name/settings.py
MIDDLEWARE = [
    'custom_middlewares.custom_cors_middleware.CustomCorsMiddleware', # 追加
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```

# おわりに
Djangoを触ってみて思ったのは、日本語のドキュメントが少ないことです。
英語のドキュメントでも日本語のように読めると苦労が減るのかもしれませんね。
Rails の credentials.yml.enc と master.key の関係性について（undefined method `[]' for nil:NilClass (NoMethodError)）

職場で運用している Rails で作成した、顧客と収益アプリの公開用 clone を作成する際に、題名のところでハマったのでメモ用として残しておきます。

## 経緯

1. GitHub のプライベートリポジトリからローカルにソースコードを clone
2. プライバシー情報を削除後、`.git`ファイルを削除して、アプリ名（folder 名）を`_v2`へと変更
3. `git init`して、リモートリポジトリへプッシュ
4. CircleCi と連携させて、master に merge されたタイミングで自動テストを組む
5. RDS を本番環境の db にしたいので、ローカルで`credentials.yml`に、RDS の情報を打ち込む設定を行う(このとき、`credentials:edit`コマンドを一度使用して、なぜか一度 credential ファイルを削除、`credeitials:edit`コマンドで再作成という謎の手順を踏んでいます)
6. ECR にコンテナデプロイして、ECS のタスクを実行しようとしたところ、ECR のコンテナが起動していない
7. 開発用の Dockerfile を push していたため、`rails s`コマンドを起動しておらず追記
8. 一度、開発環境で動作確認しようと思い、`docker build`すると、サーバーが起動しないエラー発生（undefined method `[]' for nil:NilClass (NoMethodError)）

ここまでが経緯です。

AWS は一度お試しアプリで、本番環境として自動デプロイを組んだことがあるという程度で、サービスに関してよく理解しないまま進めていました。

## 何が問題だったのか

問題は、普通に 5 番目の項目ですね。笑

少し詳しくみると、

- credential.yml.enc は、master.key を使用して暗号化、復号される
- `git push`時に、master.key はプッシュされない（.gitignore に記載されているため）

つまり、clone してきた時点で master.key は無かった。 そして、一回目の`credentials:edit`コマンド時に master.key が作成された。

しかも、一度 credentials.yml ファイルを削除して、再度`credentials:edit`コマンドを行っていたので、master.key との整合性が取れていない credentials.yml が作成されていた。

そのため暗号化も復号もできておらず、一度作成していた RDS の設定も消えていた。という感じですかね？多分

## どう解決したか

この場合は、

- 一度、master.key と credentials.yml を削除
- `credentials.edit`コマンドで 2 つのファイルを再作成

という工程でいけました！

結構ありがちなエラーみたいで調べたらたくさん情報が出てきたけど、いい勉強になった。  
同じようなケースの方は私の屍を超えていってください！！
rpycモジュールを使って外部のPythonインタプリタからMayaを操作する

この記事は[Takumi Akashiro ひとり Advent Calendar 2020](https://qiita.com/advent-calendar/2020/takumi_akashiro "ひとり Advent Calendar 2020")の23日目の記事です。

## 始めに

以前Houdiniを触った際、外部のPythonからHoudiniの`hou`オブジェクトを操作する`hrpyc`モジュールが凄いなあ……[^1]とおもったので、
`hrpyc`を参考にして、Mayaで同じようなものが書けないかなあと思ったので作ってみました。

[^1]: 凄いなあって思うだけで実際に使ったことは無いですが。

## rpycモジュールとは
**R**emote **Py**thon **C**all、すなわち別のプロセスのPythonのオブジェクトを使うためのモジュールです。[^2]

呼び出し元はサーバーを立て、呼び出し先にネットワーク経由でオブジェクトのプロキシを提供することで別セッションのPythonのオブジェクトを使えます。
詳細は[rpyc · PyPI](https://pypi.org/project/rpyc/)に任せますが、Houdiniで使うhrpycはrpycを非常に簡素にしたラッパーです。

[^2]: 諸説ある

## 使い方

1. `pip install rpyc -t <mayaのScriptフォルダ>` でrpycをインストールする。<br>バイナリは無いのでpython2系なら何でも大丈夫……なはず。
2. 以下のファイルをMayaのScriptフォルダを保存。

```python:mrpyc.py
#! python2
# encoding: utf-8

import threading

from rpyc.utils import classic
from rpyc.core import SlaveService
from rpyc.utils.server import ThreadedServer

PORT = 18812

def _start_server(port=PORT):
    t = ThreadedServer(
        SlaveService,
        hostname = '0.0.0.0', port = int(port),
        reuse_addr = True, authenticator = None,
        registrar = None, auto_register = False
        )
    t.start()


def start_server(port=PORT):
    thread = threading.Thread(target=lambda: _start_server(port))
    thread.start()
    return thread


def import_remote_maya_module(server="127.0.0.1", port=PORT):
    return classic.connect(server, port).modules['maya']

```

3.MayaのScriptEditorなどで以下を実行してMayaのサーバーを立てる。

```python
import mrpyc
mrpyc.start_server()
```

4.外部のインタプリタで以下を実行して、mayaモジュールを取得して、polyCubeを作ってみます。

```python
import mrpyc
maya = mrpyc.import_remote_maya_module()

maya.cmds.polyCube()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294868/1a95e01a-71b6-78fd-4cec-d81ec6fd8416.png)

![23_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294868/a6da272f-724b-ba7d-bb6c-ffa652655062.gif)


## 締め

以外と簡単[^3]にできましたね!

ただ実験した感じ、数分経つと接続が死んだり、Mayaがクラッシュしたりするので、
もうちょっと`hrpyc`の`_RemoteHouAttrWrapper`を参考にして実装すると安全にできるのかもしれないです。


[^3]: 自分が触った感じだとhrpyc.pyから余分な部分を削ってつくることで、3時間程度で出来た。
性のクリスマスイブに彼女が居ないひとへ ◯ぎ声キーボード

みなさんこんにちは限界開発鯖のやばい人やFascodeNetworkの広報やブログでデブ活などなどをやっているくもことなおこです。
Qiitaで投稿したのが初めてなので若干至らない点があるかもしれませんがご了承ください

## 作った経緯

早速自分が使いたいがために作った◯ぎ声キーボード、キーを押すたびに◯ぎ声がなるという恐ろしく世紀末的なPythonとVLCを使ったツール？です。




まずは自分が多少わかる言語でバックグラウンド上で動作するキー検知いわゆるキーロガーですね、、、を作らなくちゃいけません

その条件で色々探したところ
Pythonのpyxhookライブラリを使うのが一番楽そう
使い方に関してはここがわかりやすい
https://qiita.com/kaitaku/items/5c327ddd779260c63036


## コード

と言っても上の方のソースコードコピーしてちょいといじった感じですね。
キー入力検知したらサウンド鳴らすだけのコードです。


GitHubのコード
https://gist.github.com/naoko1010hh/77d15c8658a4fadfc7e945da80446e22
![Screenshot_20201223-210734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867281/f8c96f43-b2c1-405c-023a-8c62aa9b4c24.png)



実際に動かしてみた動画をTwitterに上げているのでもしよければ見てね。ボリューム小さくしてから見たほうがいいかも
https://twitter.com/naoko1010hh/status/1322766477649453057?s=19

動画内で使用した音声はみじんこさんの音声有料素材を使用させていただきました。https://www.dlsite.com/maniax/work/=/product_id/RJ287819.html

## 最後に

後つけ感はありますが今後の目標はキーごとに音を割り振って支援が必要な方がキー配置を覚えられるようにしたいですね
【初心者】三項演算子を使用してみる

# if文が良いのか三項演算子が良いのか…
if文を使う以外に条件式を使える三項演算子を使ってみた。

```php
// 条件式 ? 条件式がtrueの式 : falseの式；
$a = -7;
$judge = $a > 5 ? "High" : "Low";
echo($judge)
// 以下出力結果です
Low
```
このように、条件式の結果が true の時と false の時での結果を処理することができる。
この条件式をif文を使って記述すると…

```php
$a = -7;
if ($a > 5) {
   echo "High";
}else {
   echo "Low";
}
// 以下出力結果です
Low
```
これを比べると一見、if文より三項演算子の方が行数が少ないので良いのかなぁと思う。
ただし、if文を使うと以下のようなことができる。

```php
$a = -7;
if ($a > 5) {
   echo "High";
}elseif ($a < 5) {
   echo "Low";
}elseif ($a == 5) {
   echo "equal";
}
// 以下出力結果です
Low
```
このような、条件式が複数になったりするものに関しては、if文が良いのではないかと思う。
やはり色々はパターンを勉強することは非常に面白いと思う。
授業11回目：クラス



# 参考サイト

[チャート式ruby-VI(hello class)](https://qiita.com/daddygongon/items/969ad5112878f6dab844)


# クラスとは

オブジェクト（プログラム内で使う変数であるデータ、振る舞いであるメソッドを束ね、1つのまとまりにしたもの）を生成する為のひな形にあたるもの

[wikipedia:クラス](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%B9_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)) と[wikipedia:オブジェクト指向プログラミング](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)　を参考に


# 1:クラス化

```ruby
class Greeter
  def initialize
    @name = gets_name
    puts_hello
  end

  def puts_hello
    puts "Hello #{@name}."
  end

  def gets_name
    name = ARGV[0] || 'world'
    return name
  end
end

Greeter.new
```

class内の関数はmethod(メソッド：オブジェクトの振る舞い)になる

今回鍵となるのは以下の4つ

・Greeter.new：class外でmethodを呼び出す

・class Greeter：クラスの宣言

・initialize method：class内データの初期化を行う

・@name：インスタンス変数 initialize method の初期化対象となる


# 2:クラス継承

```ruby
# 継承される側のクラス
class Greeter < String
  def hello
    "Hello #{self}."
  end
end

# 継承する側のクラス
class String
  def hello
    "Hello #{self}."
  end
end
```

クラスは、別のクラスに持っているデータやメソッドを受け渡すことができる（継承）

上記サンプルプログラムでは、StringからGreeterを渡している


# 小ネタ：ダブルクォーテーション

Q：ダブルクォーテーションって？

A：" ←こいつ

emacsでは文字列の処理を行う際には"文字列"のようにダブルクォーテーションで囲む.

emacsでは色でどこが文字列なのかを判別する機能が備わっている.書き損じてダブルクォーテーションで囲えていなくても色を見ればミスに一発で気づけるという寸法.



------
 - **source** ~/grad_members_20f/members/batamon-427/task11.org
SpreadSheetのビジター共有がかゆいところに微妙に届かなかった話

# SpreadSheet + GASの盲点
ってほど大げさじゃないんですが、両方を組み合わせて不特定多数の人をターゲットにしたシステムなどを考えた時に一つのネックになるのが、「Googleアカウント」を持っていることが前提になる点です。
SpreadSheet自体は全体公開（リンクを知ってる人は全員見れる）にしちゃえば閲覧も編集もまあできるんですが、SpreadSheetからのGAS実行は権限が必要になるため、実行ができないのです。
ただ、これを回避する方法は少しだけあって、GASをWebアプリケーションとして公開すれば、（権限が必要な処理以外は）実行できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/88039e53-2460-a48d-bb58-3289168f8e8f.png)

# ビジター共有というものができたらしい
G Suite限定なので今まで気づかなかったんですが、どうも今年になってビジター共有というものができたらしいですね。
これは、今までSpreadSheetの公開範囲を、Googleアカウント持ってる人向けか全体公開かしか選べなかったものが、Googleアカウントでないメアドに限定して公開を行えるという機能です。
注意としては、メールからの一時的な認可なので一定時間たつと権限が消えることです（この場合でも元のメールから再認証行える）

# ビジター共有ならGAS動くのか？
はい。これが本稿における本題です。
ちょっと気になったので、やってみました。

## SpreadSheetからGASキックする
ボタン配置して、押されたらhtmlを表示するという単純なものです。
内容は、入力フォーム的な利用をしたかったのですが、権限の問題があり確認の必要があったためなんか変な内容ですが、気にしないでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/f095060f-6a00-73d4-6c7e-d7fc6c33c954.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/b9983cfe-24ee-8727-fa0d-4372ec405969.png)

んで、これをビジター共有したアカウントから見てみましょう。
ビジター共有としてメアドを入力した場合、こういうメールが届きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/c1e15bad-c473-b4a4-fae8-91e147f74ff7.png)
「Open in Sheets」をクリックするとブラウザが開き、SSが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/895c58e0-30c6-11bd-48f9-dd7ad16ea4e3.png)

ちなみに認証が切れるとこういう風になります。この場合は元のメールから再度「Open in sheets」をクリックすることになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/eb201a1c-38a3-40e4-2fa3-ea4a9970bc0d.png)

さて、実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/b5b54ea5-0bca-7bc2-b340-9ee8df24160f.png)
お、行けるか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/1a233382-fcdb-1b84-3c3c-c1a05dfcded0.png)
...無念orz

ちなみに、どんなスクリプトでもダメなわけではなく、権限が不要なもの（例：ダイアログ表示）などは実行できるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/54105571-607e-b3df-0ffc-5b0f7d6f9e1a.png)

まあ、ここまではやっぱりな・・・という感じなんですが。
冒頭で、権限なしでGAS実行するためのもう一つの手段としてWebアプリケーションとして公開するという手があることを書きました。これだと作成者の権限で実行できたりするので本来行けるはずなんですが・・・
先ほどのフォームをgetで公開する世にして、まずは完全なるゲスト状態（アカウント招待なし）でdoGetをたたいてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/4127938f-19c8-1598-50bf-d0b0fe30eac6.png)

ちゃんといけます。
が、ビジター共有された状態でこのURL開くと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221091/5cf988b0-b789-fa24-3d1f-599c62f2826c.png)
ガーン・・・むしろ劣化してるじゃねえか・・・

# 結論
ビジター共有はGASの実行権限周りではまだ微妙なようです。修正されるのをお待ちしております。
文字化け出てきた！文字コードとかよくわからんって人向けの初歩的な記事

## 注意

新卒未経験1年目ぐらいの人向けの記事です。特にテクニカルなことは書いてない表面的な記事です。直近業務で文字化け対応したのでとりあえずまとめます。

## 文字化けってなぜ起こる？

あまり意識しませんが、今これを書いているだけでも

`キーボードで文字を入力 -> データがどこかに保存される -> 読み出し -> 対応フォント検索 -> ディスプレイに表示`

というようにInputとOutputを行っています。
普通なら1つのソフト上で瞬時に↑をやるため、INとOUTは「形式」は揃い、"普通に文字が打てる"はずです。

が、例えばDBに文字列を保存・取り出しするとINとOUTの「形式」が合わなくなって
`縺翫▽縺九ｌ縺輔∪縺ｧ縺励◆`
とかなる時があります。
このIN/OUTされる文字をどうするか決める「形式」が文字コードです。
UTF8とかSJISとか色々あるやつです。

文字コードには

- どうやって0と1のデータを並べるか（ビッグエンディアン、リトルエンディアンとか言う）
- 連続した0と1のデータのどこを区切って1文字分のデータとするか
- 区切ったデータをどの文字に当てはめるか

といったルールが決められています（が、そこまで仕様知らなくてもおｋ）。
なので、文字コードを間違えると変な文字が出てきてしまうというわけです。

また、データのIN/OUTは問題ないけど、対応するフォントが無いと「�」とかトーフが出きたりもします。

なので、もし文字化けが発生した場合、I/Oに着目すると問題がわかりやすいです。

## エンコード・デコード

で、文字コードの話と一緒によく出てくるのがエンコード・デコードの話で、base64とかURLエンコードとかがあります。

これらはなにかというと、UTF8やSJISなどでは日本語がかけますが、ASCIIは英語ぐらいしかかけません。
（UTF8は2バイト以上にすれば日本語が使えますが、ASCIIは1バイトしか使えない）
そのため、ASCIIとしてデータをやり取りする時などに、データを変換・元に戻すために使われます。
データ圧縮では無いので、基本データ量は増えます。

「じゃあ全部UTF8とかにすればいいじゃん」って思うかもしれません。
はい、その通りです。
なんか色々あってまだそういうのが必要なんだなって思っててください。
そろそろもうUTF8前提で開発してもいいんじゃないかなーって思ってます。

メールではMIMEっていうルールがあって、その中でbase64とかquated-printableというエンコードをしろよってなってます。

URLも世界のすごい人達が「%使っていい感じにエンコードしようよ」ってルールを決めてます。
「え、俺のブラウザだと日本語がURLバーに表示されてるんだけど」と思う人がいるかも知れませんが、
それはブラウザがわかりやすいように表示だけ変換して見せてくれてるだけで、コピペすると%%してると思います。

## 暗号化との違い

といったように、エンコード・デコードは「〇〇をXXで使えるようにするための変換」なので問題ないと思いますが、
自分は「データを変換してるのだし、暗号化とどう違うんだ？」と思ってた時期がありました。

結果的にデータを可逆的に変換していることに変わりはないのですが、目的が違います。あと堅牢性とか変換効率とかも。

base64でできた文字列はbase64で出来てるとわかればすぐに解読できてしまいますが、暗号化はそう簡単に行きません。
更に共通鍵や秘密鍵のように「データ本体とは別に認証に必要なもの」があるのも暗号化の特徴です。

## アプリケーションが変換をするかどうか

と、わかっていても実際に文字化けが発生した時に何故か原因がよくわからんって場合がほとんどです。（ほんとに）
そういう場合はI/Oに着目するだけでなく「ソフトウェアが余計なことしてくれちゃってないか」も見ると良いと思います。

例えばmySQLでは
`SHOW VARIABLES LIKE '%character%';`
とすると、接続する時、実際にデータを送る時、内部で扱う時、出力する時、などタイミングごとにどう文字コードを扱うか決められて、
`character-set-client-handshake`を設定してると勝手に変換したり、
逆に`skip-character-set-client-handshake`だと100%送られてくる文字コードを信じたりします。

メールの送受信をするsendmailでは、オプションによって勝手にメールヘッダやボディを変換したりします。

ほとんどの文字化けの原因がこれだと思います。
が、稀にPHP5.3.6未満のPDOはcharsetしても意味ないですよーとか言われるので辛いです。

このあたりに興味ある人はぜひ文字コードマスターになって僕を助けてください。
【React】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

## 1 位: [もう手書きは不要！？React開発にStorybookとCopilotを導入して、爆速でUIを編集・確認する方法](https://qiita.com/yu_720/items/62769dd4e5e12e022b63)

[`UI`](https://qiita.com/tags/UI) [`AI`](https://qiita.com/tags/AI) [`React`](https://qiita.com/tags/React) [`storybook`](https://qiita.com/tags/storybook) [`copilot`](https://qiita.com/tags/copilot) 
**46** いいね　**34** ストック
[@yu_720](https://qiita.com/yu_720) さん ( 2025-06-20 11:59 に投稿 )

## 2 位: [【個人開発】対義語・派生語まで&#34;ついで覚え&#34;ができるAI単語帳アプリを作成しました](https://qiita.com/kikotkk/items/c2a0a9050d60413da850)

[`AI`](https://qiita.com/tags/AI) [`React`](https://qiita.com/tags/React) [`個人開発`](https://qiita.com/tags/個人開発) 
**20** いいね　**4** ストック
[@kikotkk](https://qiita.com/kikotkk) さん ( 2025-06-22 17:21 に投稿 )
インフラ基礎〜クラウドとオンプレミス〜

クラウドとオンプレミスについてのメモ

システムの利用形態は大きく分けて３つ

# オンプレミス

・企業システムで非常に多く採用されていた

・自社でデータセンターを保有してシステム構築から運用までを行う形態

・サーバやネットワーク機器を自社で調達して、システム要件に応じてインフラを構築し、自社で運用する

・ハードウェアだけでなくOS、ミドルウェアもすべて自社で購入しライセンスの管理・バージョンアップも自前で行う

・初期のシステム投資にかかる費用負担が大きい

・稼働後の運用費用もシステムの利用量に関わらず一定額負担する必要あり

# パブリッククラウド

・インターネットを介して不特定多数に提供されるクラウドサービス

・自社でデータセンターを保有しないため、サーバ・ネットワークなどのインフラ関連の初期投資が不要

・IaaS/PaaS/SaaSなどがある

・IaaSはシステム基盤部分を利用するサービス

・利用したいスペックの仮想マシンやストレージを選び、利用時間やデータ量に応じて料金を支払う形態

# プライベートクラウド

・特定の企業グループ飲みに提供されるクラウドサービス
　→イメージとしては企業内でデータセンターを共同保有するようなイメージ

・パプリッククラウドが不特定多数に対して、プライベートクラウドは利用者を限定できる

・セキュリティが担保しやすかったり、独自の機能・サービスを追加しやすい

## まとめ

・システムの要件によってどの形態を選ぶか決まる

・クラウド利用だと短期間でインフラを構築することができる

・パプリッククラウドを利用すると、利用量が増加した時に簡単にインフラ基盤を増強できる（オートスケールと呼ぶ）
【備忘録】TvtestとEDCB設定方法

###はじめに
この記事は新しいPCを購入した際に、もう一度調べるのは面倒なので自分用の備忘録として書き留めておこうと書いているものです。
調べたらたくさん記事でてきますが古いものも多く、僕がやった手順を残しときます。
僕にしかわからないような表現あるかもですがご容赦ください。

####0. Windows環境の準備
以下のやつをいい感じにインストール

Visual C++ 2015 再頒布可能パッケージ Update 3
https://www.microsoft.com/ja-jp/download/details.aspx?id=53840
Visual C++ 2005 Service Pack 1 再頒布可能パッケージ MFC のセキュリティ更新プログラム
https://www.microsoft.com/ja-jp/download/details.aspx?id=26347
Visual C++ 2008 Service Pack 1 再頒布可能パッケージ MFC のセキュリティ更新プログラム
https://www.microsoft.com/ja-jp/download/details.aspx?id=26368
Visual Studio 2012 更新プログラム 4 の Visual C++ 再頒布可能パッケージ
https://www.microsoft.com/ja-jp/download/details.aspx?id=30679
Visual Studio 2013 の Visual C++ 再頒布可能パッケージ
https://www.microsoft.com/ja-jp/download/details.aspx?id=40784

参考：https://ryo-japan.jp/retirement/archives/2408


####1. ドライバのインストール
事前に自分のチューナーにあったものを下記からインストール
http://www.plex-net.co.jp/download/
チューナーに電源やカードもろもろを接続しPCに接続
このとき、電源ランプがついているか確認
（最初なぜかつながってなくてつまった）

つなげたらデバイスマネージャーの「ほかのデバイス」にチューナーがあるはずなので
右クリックして「ドライバの更新」からさっきいれたドライバを選択

####2. BonDriverのインストール
BonDriverは地デジ用のものとBS用のものが必要になる。
後々使うのでBonDriver_32bitとBonDriver_64bitのフォルダ作っておくといいかも

以下から最新のものをインストール
現在(2020.12.23)はBonDriver_BDA-2019-02-02.zipが最新でした
https://github.com/radi-sh/BonDriver_BDA/releases

解凍してx64¥ReleaseのBonDriver_BDA.dllを、作成したBonDriver_64bitフォルダ内に４つ複製し、名前を以下にリネーム。
BonDriver_PX_W3U4_S0.dll
BonDriver_PX_W3U4_S1.dll
BonDriver_PX_W3U4_T0.dll
BonDriver_PX_W3U4_T1.dll
同じようにx86¥ReleaseのBonDriver_BDA.dllを作成したBonDriver_32bitフォルダ内に４つ複製しリネーム。
T0が地デジの一つ目、T1が地デジの２つめ。S0,S1もそれぞれBSのやつ。

####3. 別のなんかをインストール
必要なものみたい。カードリーダーがなんとかみたいなこと書いてあったきがする。知らんけど。

以下から最新のものをインストール
現在(2020.12.23)はBDASpecial-IT35-2019-02-02a.zipが最新でした
https://github.com/radi-sh/BDASpecial-IT35/releases

解凍してBonDriver_PX_x3U4_S.iniとBonDriver_PX_x3U4_T.iniを
BonDriver_32bitとBonDriver_64bitにそれぞれコピーし以下のようにリネーム。

BonDriver_PX_x3U4_S.iniから
BonDriver_PX_W3U4_S0.ini
BonDriver_PX_W3U4_S1.ini

BonDriver_PX_x3U4_T.iniから
BonDriver_PX_W3U4_T0.ini
BonDriver_PX_W3U4_T1.ini

また、WinSCard.iniもそれぞれのフォルダにコピー。
最後にx64¥Release内のIT35.dllとWinSCard.dllをBonDriver_64bitに、
x86¥Release内のIT35.dllとWinSCard.dllをBonDriver_32bitにコピー。

すごいややこしいけど、ちゃんとできてれば
こんな感じになるはず
![BonDrivere](https://i.imgur.com/VASVgxk.png)

####4. Tvtestのインストール
Tvtestは実際にテレビみるやつ。
以下から最新のものをインストール
現在(2020.12.23)はTVTest-0.10.0-190203.zipが最新でした
https://github.com/tsukumijima/DTV-Built

解凍して32bit or 64bitのTvtestフォルダ内にそれぞれのbitにあったBonDriverフォルダをコピー。

これでTvtestは起動できるはず。
設定は[こちら](https://blog.tsukumijima.net/article/tvtest-usage/)を参考にしました。

####5. EDCBインストール
EDCB（EpgDataCap_Bon）は録画するソフト。

以下から最新のものをインストール
現在(2020.12.23)はEDCB-190623.zipが最新でした
https://github.com/tsukumijima/DTV-Built

解凍してBonDriverフォルダ内にそれぞれのbitにあったBonDriverフォルダをコピー。

これで起動できるようになったはず。
設定は[こちら](http://terrasshotel.net/?p=53)を参考にしました。

以上です。
がんばってください。
Pardot のスコアリングとグレーディング (Pardot Lightning アプリケーション) ⇒ リード評価の使用開始

１．リード評価とは何ですか?
２．Pardot における、プロスペクトのスコアの測定値は何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/b5edb961-6609-f9da-dd55-c9f1a584c3f2.png)
Pardot Lightning アプリケーションの基本 ⇒ Pardot の管理の基本について

１．Pardot の 4 つのデフォルトのユーザロールは何ですか?
２．あなたの会社では Salesforce に好みの製品を収集する項目を設定しており、その情報を Pardot で使用したいと考えています。実行すべき操作はどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/e761bcd8-869a-4fbc-474a-6143065fc050.png)
AWS CLIのコマンド補完設定時の戒め

# 戒め
将来の自分に向けて残します。
文章はちゃんと読みましょうという話です。

ちなみに環境はmacOS,シェルは`zsh`です。

# AWS CLIコマンド補完設定方法（AWSドキュメントのとおり）
本来はこちらのAWS公式ドキュメントのとおりにコマンド補完の設定を行えば何も問題はありませんでした。
はい、私はなぜかドキュメントどおりに行いませんでした。。。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-configure

上のリンクのAWS日本語版は少し古い上に分かりにくいので、英語版を見てください。
私は英語が得意ではないので、該当部分を一文ずつ選択してgoogle翻訳で確認しました。

ドキュメントどおりに`~/.zshrc`の末尾に以下のコマンドを入力し、`. ~/.zshrc`を実行。

```:~/.zshrc
autoload bashcompinit && bashcompinit
```

そして、上記を実行した後、またもドキュメントどおりに`~/.zshrc`の末尾に以下のコマンドを入力し、`. ~/.zshrc`を実行。

```:~/.zshrc
complete -C '/usr/local/bin/aws_completer' aws
```

これでコマンド補完ができるようになっています。
二つのコマンドを一度に入力して`. ~/.zshrc`を実行しないのは、コマンドが見つからないとエラーが出てコマンド補完が行えないからだと思います。

実際に一度にやってみると、`. ~/.zshrc`実行の際に`complete:13: command not found: compdef`と出ました。その後、コマンド補完機能を試しても補完されなかったので、設定ができていないことが分かります。

# なぜドキュメントどおりにしなかったか

日本語訳が若干おかしくなっており意図が理解できなかったことと、ドキュメントどおりに`. ~/.zshrc`を２回に分けて実行していないが、一度に済ませても結果は変わらないだろうと勝手に判断したからです。
そのため検索してコマンド補完した解決策がこちら。

```:~/.zshrc
autoload -U compinit
compinit
complete -C '/usr/local/bin/aws_completer' aws
```

こちらでもできましたが、どうせならAWS公式の言うとおりにしようと思い、最初のやり方に直りました。
ドキュメントどおりにやっていたら2〜3分で終わっていたと思うので、原文が英語のものはしっかりと原文を読もうと思います。
Azure Synapse Analytics Pipelineで失敗アラートを設定する方法

## はじめに

Azure Synapse Analytics ではPipelineのメトリックの種類がDataFactoryと異なり、Monitor統合がまだまだなのか、Pipelineの失敗アラート設定がdocsにも見当たらなかったので実装方法を案内します。

(2020/12時点の情報)


## メトリクスと設定内容について

以下のリンクから取得できるメトリックの情報を確認します。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/metrics-supported#microsoftsynapseworkspaces

OrchestrationTriggersEnded　からはトリガーの終了数と、ディメンション項目が取得可能です。

Resultには成功と失敗の内容が記録されますので、Result = Faildとなっているパイプライン実行の終了数が1より大きい場合にアラートが飛ぶようにしてみます。

今回は、さくっとテストするためにOrchestrationPipelineRunsEndedでやってみます。

## 手順
手順の概要

1. アラートの設定
2. 失敗するパイプラインの構成と実行
3. 確認

### 前提

事前にSynapse Analytics Workspaceをデプロイしておきましょう。




### 1. アラートの設定

はじめにメトリック画面で、「新しいアラートルール」をクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/33107186-fc77-dc44-eb76-dfe04a466974.png)



リソースが選択されていることを確認して、「条件の選択」をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a9e8166e-64b0-ff5e-ca09-ce3ac66780f0.png)



Pipeline runs endedを選択します。  
※Trigger実行に対してのアラートを設定するときはTrigger Runs Endedを選択してください

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/45607523-8d0c-c299-6f5f-0d76d8658d70.png)

ディメンションで「Result」を選択して、ディメンションの値にはFailedを入力します。

![スクリーンショット 2020-12-23 211358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0dd0e5ec-0b44-9036-5454-3bcc31eef841.png)


しきい値を設定します。(1より大きいになってますが、0より大きいが正しいです

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/3a6efcf6-a4f2-c505-4b9d-d1d8358fb015.png)


次に「アクショングループの追加」選択します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8432e9dd-04a9-c756-bb0d-ffc1bf4952dc.png)



アクショングループの名前と、

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/b67121d6-2eb2-0267-349e-ada9cd0e7628.png)


通知設定を行います。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/36d3663a-8c7c-2e17-40bd-c5e2946f2b4f.png)


確認と作成をクリックして、アラートルール名を設定後、アラートの設定を完了します。

### 2. 失敗するパイプラインの構成と実行

今回はでたらめなurlにgetをおこなうwebアクティビティを配置しました。
どうやっても失敗します。
作成後、publishしてtrigger nowを実行します。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/3d20c964-7354-eab8-e3e3-ae81cbded749.png)


### 3. 確認

こんなメールが飛んできます。
カスタマイズするならwebhookやlogic appsなどと連携したほうがよいでしょう
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/7a0b080b-0fae-0374-69d1-45f18c820c58.png)
Flash Advent Calendar 23日目 - セキュリティーと脆弱性の解決 -

FlashPlayerで一番問題になっていた事
それは`脆弱性の問題`だと思います。

swf2jsは安全ですか？

そういった質問や疑問があると思います。
今日はFlashPlayerとswf2jsがどう違うのか書こうと思います。


# マルウェアの感染

インストールが必要か不要か、ここがマルウェアに感染するかしないかの大きな切り分けになります。
FlashPlayerを利用するにはインストールが必要です。

このインストールするという行為がマルウェアの侵入経路になっています。
インストールしようとしているインストーラーは本当にAdobeが配布している安全なインストーラーですか？

・・・分かりません。

専門知識があれば、判断できるかもしれません。
ですが、専門知識がなければ、そういった判断は難しいと思います。

ですが、FlashPlayerはインストールしないと利用できません。。。
そして「インストールする」というボタンを押下すれば
安全でも安全でなくとも、問答無用で利用中のPCにインストールされます。


では、次にswf2jsです。
swf2jsはインストールが不要です。

なぜならば、swf2jsはJavaScriptファイルだからです。
もし、swf2jsに問題があるとすれば
それは全世界のJavaScriptと同じ問題を抱えている事と同義になると思います。


# 脆弱性の問題

ここでも先に記載した、インストールの有無が関連してきます。
FlashPlayerをインストールすると、PC(OS)からFlashPlayerに対してある程度のアクセス権限が付与されます。
この権限があればPCの内部に直接アクセスする事が可能になります。

悪意のあるコードはこの権限を利用して利用中のPCへ攻撃を行います。
これもインストールが必要という点が大きいところです。


次にswf2jsです。

先にの述べた通り、swf2jsはJavaScriptファイルです。
ブラウザが許可した権限しかありません。
また、ブラウザが定めた基準(使用方法)に準拠しないと正しく動作しません。
勝手にPCの内部にアクセスしたり、バックドアの起動などできません。

このような事から、インストールする事による
`FlashPlayerが抱えていた脆弱性の問題`を解決したと言い切れます。

ですが、次に出てくる疑問「JavaScriptは安全なの？」っという疑問が出てきます。




 JavaScriptは安全なの？



JavaScriptも万能ではありません。


セキュリティの脆弱性があります。



クロスサイトスクリプティング（XSS）


クロスサイトリクエストフォージェリ（CSRF）


サーバーサイドJavaScriptインジェクション



などが有名な問題かと思います。


ですが、これらの脆弱性は実装手法で回避が可能です。


また、これらの脆弱性の回避方法も広く知られています。


2020/12/25 追記
今回の記事はFlashPlayerでおきうる問題に関しての記事なので
ここの内容はどこかで改めて記事にできればと思います。


# 今後はどうなるの？

度々になるのですが、swf2jsはJavaScriptファイルです。
つまり、ブラウザの成長と共に機能の拡張や進化が可能です。
今後の進化に是非ご期待頂ければと思います。

いかがだったでしょうか？

明日は紀平さんの記事「Acquiring について」です。
[メモ] ?で終わるメソッド

勉強用のメモ代わりとして記事にさせていただきます。

#?で終わるメソッド
Rubyのメソッド名は?で終わらせることができる。?で終わるメソッドは慣習として真偽値を返すメソッドになっている。

```ruby
# 空文字列ならtrue、そうでもなければfalse
''.empty?   #=> true
'abc'.empty?   #=> false

# 引数の文字列が含まれていればtrue、そうでもなければfalse
'movie'.include?('mo')   #=> true
'movie'.include?('at')   #=> false

# 奇数ならtrue、そうでもなければfalse
3.odd?   #=> true
4.odd?   #=> false
```

?で終わるメソッドは自分で定義することができる。

```ruby
# 2の倍数ならtrue、それ以外はfalseを返す
def multiple_of_two?(n)
  n % 2 == 0
end
multiple_of_two(1) #=> false
multiple_of_two(2) #=> true
multiple_of_two(3) #=> false
```

#まとめ
真偽値を返す目的のメソッドであれば、?で終わらせるようにした方が良い。
授業7回目：if,else



# 参考サイト

[チャート式ruby-III(if, case, Array.each by leap year)](https://qiita.com/daddygongon/items/a550bde1ed6bff5217d8)


# if-else文

Rubyだけでなくいろんな言語で使われる条件分岐　基本はPythonとかと一緒

```ruby
if 式 [then] 
  式 ...
[elsif 式 [then]
  式 ... ]
...
[else
  式 ... ]
end
```

[]内の動作はあっても無くても動く

else if をelsifと書くことだけ注意

書き方例：

```ruby
if a=20
 b true
elsif c=30
 b true
else
 b false
end
```


# お題：うるう年か？

入力された数がうるう年かを表示するプログラム

    ・ 4で割り切れる数の年はうるう年
    ・ ただし、100で割り切れる年はうるう年でない
    ・ 加えて、400で割り切れる年はうるう年

まずは4で割り切れるか否か

```ruby
[2004, 1999].each do |year|
  p year
  if year % 4 == 0
    p true # 4で割り切れるなら真(うるう年)
  else
    p false # 4で割り切れないなら偽(うるう年じゃない)
  end
end
```

1行目は2004、1999をそれぞれyearに入れている

次に、100で割り切れるかの処理を入れる

```ruby
[1900, 2004, 1999].each do |year|
  p year
  if year % 100 == 0
    p false # 100で割り切れるなら偽
    next
  end
  if year % 4 == 0
    p true
  else
    p false
  end
end
```

next が実行されると、next以降の処理が実行されずに次の繰り返しに移行する.繰り返しそのものを中断してしまう break とはちょっと違う

最後に、400で割り切れるかの処理を入れる

```ruby
def leap?(year)
  if year % 400 == 0
    p true # 400 で割り切れるなら真
  elsif year % 100 == 0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end
end
[2000, 1900, 2004, 1999].each do |year|
  p year
  leap?(year)
end
```

ついでに関数leap?として実装した


# EX

if の代わりに case を使って綺麗に書くとこうなる

```ruby
def leap?(year)
  case
  when year % 400 ==0 ; p true
  when year % 100 ==0 ; p false
  when year % 4 ==0 ;   p true
  else ;                p false
  end
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  leap?(year)
end
```


# note

条件分岐をあらかじめ考えて実装するのは大変だが、順を追って実装すると良いかも？



------
 - **source** ~/grad_members_20f/members/batamon-427/task7.org