OmniAICreator/Qiita-1.07M huggingface dataset:
axiosでAPIを叩く処理を外部関数化し、Vueコンポーネントからjsonを取得する方法

#概要
axios.get.thenでAPIを呼びjsonを取得する関数を作成しようとしたが、
axiosは非同期処理のためreturnでjsonを返すことができなかった。
callback関数を用いることでjsonを取得できる。

#やり方
以下のjsファイルを作成

```js:Api.js
import axios from "axios"

function callApi(url, callback) {
  console.log()
  axios
    .get(url, { /*オプションがあれば書く*/ })
    .then(response => {
      callback(response)
    })
    .catch(e => {
      console.log("Error occurred in API")
      console.log(e)
    });
}

export default {callFreadApi}
```

Vueコンポーネントからの呼び出しは以下

```vue:component.vue
<template>
  <p>{{ info }}</p>
</template>

<script>
import Api from "./Api"

export default {
  name: "Component",
  components: { Api },
  data() {
    return {
      info: ""
    }
  },
  methods: {
    setInfo: function(info){
      this.info = info
    },
    callApi(url){
      Api.callApi(url, this.setInfo)
    }
  },
  mounted() {
    this.callApi("呼びたいAPIのURL")
  }
};
</script>

<style>
</style>
```
上記コンポーネントからcallApiを呼ぶことでjson結果を取得できる。
流れとしては
1. コンポーネントにApi.jsをインポートする。
2. Api.jsからcallApiを呼び出す。
3. callApiのなかでjson結果を取得し、コールバック関数（上記例ではsetInfo）に渡す。
4. setInfoでVueコンポーネントのdataにjson結果を代入する。
5. コンポーネントでjson結果が扱える。
ラズベリーパイにcentos7をインストール

#### 目的
自宅の踏み台サーバーにラズパイを使えば便利かなと思った。
tmuxサーバで使うのが主な目的。
慣れているCentOS7を使用する

micro sdにイメージ書き込み、centos起動〜IP固定設定〜無線LAN設定までは下の記事を参考にしたらスムーズに進みました。
https://blog.k-san.info/centos7-on-raspberrypi3

#####問題
pingがラズパイ自身のIP(192.168.11.10)しかパケットが来ない現象になりました。
でもインターネットにはアクセスできる。
ルーターにpingを飛ばしてもパケットが返らない。。
`Destination Host Unreachable`と表示される

#####原因
ラズパイのルートテーブル設定が間違っていました。
![IMG_0165.jpg](https://qiita-image-store.s3.amazonaws.com/0/12294/b87c8876-5a04-d19f-eb6d-e67753bcb24e.jpeg)
Destination　`192.168.11.0`は存在しないので間違った値でした。


#####解決
ルートテーブルにルーターのネットワークアドレス`192.168.11.0`を追加
`wlan0`としているので無線LANのみの設定
`sudo route add -net 192.168.11.0 netmask 255.255.255.0 dev wlan0`

Destination , Gateway Genmaskが意図した値になりました。
![IMG_0165 (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/12294/fcd55d33-2d20-975a-2432-addb27417b63.jpeg)
Pingも無事通るようになりました！

追記　2019/04/07
またpingが通らなくなったのでrouteのeth0を削除し、wlan0のみにしたらpingが通るようになりました。
原因はeth0のMetricの値がwlan0より低いのでeth0でルーティングを行おうとしていたと思います。


参考　https://qiita.com/kooohei/items/b0931ae210911cc52adc#%E6%B0%B8%E7%B6%9A%E7%9A%84%E3%81%AA%E5%89%8A%E9%99%A4

ついでにip address固定方法
https://orebibou.com/2014/07/centos-7%E3%81%A7%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E8%A8%AD%E5%AE%9A/
GR-Citrusで近接センサーとServoをつなげたよ

GR-Citrusシリーズですが合成してみましょう

近接センサーで近づいてきたらサーボモーターが動くようにしましょう。

![GR-Citrus-WIre-HC-SR-servo.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/a4974baa-c45e-5528-64fa-6f6b60fefdd0.jpeg)

```
/* GR-CITRUS Sketch Template V2.20 */
#include <Arduino.h>
#include <Servo.h> //Servoモーターを動かすよ
#define trigPin 8
#define echoPin 9
#define INTERVAL 500
unsigned char g_pos = 0;
Servo servo0;
Servo servo1;


void setup(){
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(PIN_LED0, OUTPUT);
 servo0.attach(7);
 servo1.attach(6);
}

void loop(){
 int duration, distance;
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance <= 50 || distance == 0){  //ここで距離を設定できるよ
   Serial.println("Near");
  servo0.write(g_pos);
  servo1.write(g_pos);
    g_pos+=10;}
    if(g_pos > 180){
            g_pos = 0;
    }
 if (distance >= 200 || distance <= 0){
   Serial.println("Out of range");
 }
 else {
   Serial.print(distance);
   Serial.println(" cm");
 }
 delay(500);
}
scaffoldで生成した画面にCSSフレームワークを適用すると、レイアウトが崩れる

## 現象
scaffoldで生成した画面に対して、bootstrapやmaterializeを適用すると、
レイアウトの一部が崩れる。

## 原因
scaffoldで自動生成したcssが残っており、余計なスタイルが適用されていたため。

```
├── app
│   ├── assets
│   │   └── stylesheets
│   │       └── scaffolds.scss
```

## 対策
scaffolds.scssを削除する。

```
$ rm app/assets/stylesheets/scaffolds.scss
```
grpc_tools_node_protoc_tsを使って.protoファイルからTypeScriptの型定義ファイルを生成する

## 概要

[grpc-toolsを使って.protoファイルからNode.jsのgRPC clientコードを生成する](https://qiita.com/daikiojm/items/3944f529dcb7a43ec90d)では、javascriptのmessage定義とclient実装を自動生成しましたが、今回は、これらのjavascriptに対応する型定義ファイル(.d.ts)を自動生成してみたいと思います。


## 前提

[grpc-toolsを使って.protoファイルからNode.jsのgRPC clientコードを生成する](https://qiita.com/daikiojm/items/3944f529dcb7a43ec90d#%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B)の [生成する](https://qiita.com/daikiojm/items/3944f529dcb7a43ec90d#%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B)までを手元で動作させていることが前提です。

また、プロジェクトディレクトリに今回使用するプラグイン `grpc_tools_node_protoc_t` をインストールしておく必要があります。

```bash
npm i --save-dev grpc_tools_node_protoc_ts
```

## 型定義ファイルを生成する

次のコマンドを実行して型定義ファイルを生成する。

```bash
grpc_tools_node_protoc \
--plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \
--ts_out=. \
hero/hero.proto
```

## 生成されるファイルの確認

- hero_grpc_pb.d.ts
    - hero_grpc_pb.jsに対する型定義ファイル
- hero_pb.d.ts
    - hero_pb.jsに対する型定義ファイル

## おまけ

生成されたjs/.d.tsを使って実際にクライアントコードを動かしてみます。
今回サンプルで使用している.protoファイルのserver実装は [sample/04-grpc](https://github.com/nestjs/nest/blob/master/sample/04-grpc/src/hero/hero.proto) にあるので、事前にこのリポジトリを取得してserverを立ち上げておきます。

クライアントの実装は次のようになりました。

```ts:client.ts
import * as grpc from 'grpc';
import * as hero_grpc_pb from './hero/hero_grpc_pb';
import * as hero_pb from './hero/hero_pb';

const client = new hero_grpc_pb.HeroServiceClient(
  '127.0.0.1:5001',
  grpc.credentials.createInsecure(),
);

const req = new hero_pb.HeroById();
req.setId(1);

client.findOne(req, (error, res) => {
  if (error) {
    console.log(error);
  }
  console.log(res.toObject());
});
```

実際に実行してみます。

```bash
$ ts-node client.ts
{ id: 1, name: 'John' }
```

## 参考

- https://qiita.com/daisaru11/items/67366061f7244378639c
- https://github.com/agreatfool/grpc_tools_node_protoc_ts
- https://github.com/nestjs/nest/tree/master/sample/04-grpc
GR-CitrusでServoを動かすよ

GR-CitrusでServoを動かすよ。

Servoモーターは百円で手に入るSG90を使います 

![GR-Citrus-WIre-Servo.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/696e9d4e-3947-3b93-1d20-d09ea3d84c63.jpeg)

元にしたのはこれです。
http://gadget.renesas.com/ja/reference/citrus/library_servo.html

```
#include <Arduino.h>
#include <Servo.h> 
 
#define INTERVAL 500
unsigned char g_pos = 0;
Servo servo0;
Servo servo1;

void setup() 
{ 
    servo0.attach(7);
    servo1.attach(6);
} 
  
void loop() {
    servo0.write(g_pos);
    servo1.write(g_pos);
    g_pos+=10;
    if(g_pos > 180){
            g_pos = 0;
    }
    delay(INTERVAL);
}
【RaspberryPi/ラズパイ】"cmdline.txt"の変更でパスワードリセットが出来なかった場合にどうしたらよいか

## tl;dr
- なぜパスワードリセットする必要があったのか
- RaspberryPi（以下、ラズパイ）のパスワードリセットの方法
※ラズパイについての説明は省略する

## なぜパスワードリセットする必要があったのか
　ラズパイはRaspbian OSというLinuxがベースになっているOSがインストールされているため、モニターやキーボードを用意すれば、PCのように使用することができる。筆者がよく読んでいる、日経BP社が出版している[ラズパイマガジン](https://trendy.nikkeibp.co.jp/rasmag/)では、リモート接続するための環境説明が必ず掲載されており、便利ではあるため筆者も同様にリモート接続による電子工作等を行っていた。

　また、初期パスワードは全てのラズパイで共通しているようなのだが、パスワードを変更しないままSSHクライアントソフトを利用した場合、そのラズパイをターゲットにしたウイルスが2017年時点で確認されているため注意する必要がある。

　なお、リモート接続は”TeraTerm”を利用して行うのだが、接続のためにはパスワードが必要になる。しかし、最近は手をつけなかったため忘れてしまった（メモはあったが、認証しなかった...）。ここに時間を費やしてしまったたため、同じ経験をする可能性のある方へ少しでも手助けになればと思い、手順をまとめる。

## ラズパイのパスワードリセットの方法
　パスワードリセットの要望は少なくはなく、様々な方が試しているようだった。基本的には、ラズパイが起動時に参照するconfigファイルを変更し、コマンドを入力するだけ・・・のはずだった。

　なお、この時点で以下のブログを参考にさせていただいた。
- [そうだ!研究しよう](https://kenyu-life.com/2018/11/09/raspberry_pi_password/)
- [いろいろ試してみる](http://imamachi-n.hatenablog.com/entry/2018/06/17/104419)

　ここですべて解決すれば良かったのだが、以下メッセージが起動時に表示され、手順通りにパスワードリセットが出来なかった。

```
"can't access tty; job control turned off"
```

　そこで、素直に上記エラーをGoogle大先生に問い合わせると、日本で同じことに困っている人は（おそらく）いなかったが、以下サイトで同様のケースが確認できた。
- [Kll engineering](http://kll.engineering-news.org/kllfusion01/articles.php?article_id=126)

　以下コマンドを実行し、新しいパスワードを入力後に再度ログインできること、WindowsPCからSSH接続ができることを確認することができた。めでたしめでたし（長かった...）。

```
sudo passwd pi
```
herokuにMySQLのRailsアプリをデプロイしたときに発生したエラーについて

今回、Herokuにデプロイする際に、「PostgreSQL」というデーターベースに変更しました。
すると、キーワードを入れて検索をしたときに以下のようなエラーが発生しました。

```
ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR:  operator does not exist: integer

LINE 1: ...ame FROM "products" WHERE (name like '%72%' or price like '%72%...

HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
```

このアプリでは　フォームに文字を入力すると、その値がkeywordという変数に入るようになります。
フォームに入力された値はString型として扱われます。
そしてModelで定義したscope内のwhereで条件を指定し、それにあったレコードを抽出します。
ここではあいまい検索をしており、nameカラムまたはpriceカラムの中にkeywordが含まれるレコードを取り出すという条件となります。

```
scope :search_by_keyword, -> (keyword) {
   where("name like ? or price like ?","%#{keyword}%","%#{keyword}%") if keyword.present?
}
```

このアプリのデータベースではpriceというカラムはinteger型で設定していました。
まず、```keyword.to_i```でinteger型に変換してから入れてみましたが、エラーの解消はできませんでした。
検索するとどうもPostgreSQLのバージョンによるものだということがわかりました。
```%72%```という書き方をすると、keywordがString型かinteger型であるかは関係なく文字列となってしまうようです。
PostgreSQL8.3以前では自動型変換されていたのですが、それ以降は変換機能がなくなり、型を明示してあげる必要があります。
そこで以下のように訂正しました。

```
scope :search_by_keyword, -> (keyword) {
   where("name like ? or price::text like ?","%#{keyword}%","%#{keyword}%") if keyword.present?
}
```
priceというところをprice::textと変更しました。
こうすることによってpriceはStringと認識され、検索の際に型の不一致によるエラーが出ないようになりました。
WSL(Ubuntu18.04)環境で何とかしてGUIのChromeを起動したい

Windows 10のWSL(Ubuntu 18.04)環境では、XLaunchなどのソフトウェアをWindows側に導入することでGUIアプリケーションも（一応）動かすことができるのですが、<b>2019年3月</b>現在のChromeやChromiumの最新版はそのままでは起動できないようです。

# 症状
XLaunchを起動した状態でgoogle-chromeコマンドをWSLに切り替えたPowerShell上で実行しても正常に動作しません。数秒ウィンドウが表示されますが、エラーと共に落ちます。

```console
user@Computer:/mnt/c/Windows/System32$ google-chrome
shared memfd open() failed: Function not implemented
[22133:22162:0331/172546.479349:ERROR:data_store_impl.cc(131)] Failed to open Data Reduction Proxy DB: 3
[22133:22254:0331/172546.483061:ERROR:bus.cc(396)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
[22133:22133:0331/172546.720572:ERROR:desktop_window_tree_host_x11.cc(1120)] Not implemented reached in virtual void views::DesktopWindowTreeHostX11::InitModalType(ui::ModalType)

(google-chrome:22133): LIBDBUSMENU-GLIB-WARNING **: 17:25:46.873: Unable to get session bus: Unknown or unsupported transport “disabled” for address “disabled:”
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
[22133:22154:0331/172550.561709:FATAL:gpu_data_manager_impl_private.cc(892)] The display compositor is frequently crashing. Goodbye.
Trace/breakpoint trap (core dumped)
```

GPUなんとかかんとかって書いてあるので、適当に--disable-gpuしましたが無理です。

```console
user@Computer:/mnt/f/Programs/React/blog$ google-chrome --disable-gpu
shared memfd open() failed: Function not implemented
[23200:23319:0331/172707.978487:ERROR:bus.cc(396)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[23200:23219:0331/172707.985159:ERROR:data_store_impl.cc(131)] Failed to open Data Reduction Proxy DB: 3
[23200:23200:0331/172708.201839:ERROR:desktop_window_tree_host_x11.cc(1120)] Not implemented reached in virtual void views::DesktopWindowTreeHostX11::InitModalType(ui::ModalType)

(google-chrome:23200): LIBDBUSMENU-GLIB-WARNING **: 17:27:08.361: Unable to get session bus: Unknown or unsupported transport “disabled” for address “disabled:”
[23200:23220:0331/172710.443843:FATAL:gpu_data_manager_impl_private.cc(892)] The display compositor is frequently crashing. Goodbye.
Trace/breakpoint trap (core dumped)
```

# 解決方法
以下の条件を満たしているか確認します。

* XLaunchをMultiple windows以外にしている（One large windowなどが手頃だと思います）
* PowerShellを管理者権限で起動している
* Openboxなど手頃なウィンドウマネージャを起動している

![xlaunch_displaysettings.PNG](https://qiita-image-store.s3.amazonaws.com/0/192467/c07be677-09dc-a8de-ef17-979e7dbd6c70.png)

自分の環境では上記手順を行うことでGoogle Chrome、Chromiumともに起動できました。
安定動作はしてなさそうですか、とりあえず起動できたので良し。
GR-Citrusで近接センサーを使うよ　HC-SR04

GR-Citrusで近接センサーを使うよ

ソースは、がじぇっとルネサスコミュニティの「超音波センサ（ping、HC-SR04）について」で試しています。

https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-sakura/553/ping-hc-sr04

![GR-Citrus-WIre-HC-SR05.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/2118c4fa-2ba1-02b8-efa7-870facd0be76.jpeg)

気を付けないといけないことは、HC-SR04には不良品が紛れています。
https://mag.switch-science.com/2015/07/23/hc-sr04_failure/
これには要注意です。

```
#include<rxduino.h>
#define trigPin 8
#define echoPin 9

void setup() {
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
}

void loop() {
 int duration, distance;
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance >= 200 || distance <= 0){
   Serial.println("Out of range");
 }
 else {
   Serial.print(distance);
   Serial.println(" cm");
 }
 delay(500);
}
ブレークポイントとは

#ブレイクポイントとは
デバイスによって、表示解像度が違う。臨機応変に、デザインを変える必要があって、その基準のことをブレイクポイントという。
##従来ブレイクポイント
ずばり、768px。これは、タブレットとパソコンの境界である。デメリットとしては、デバイスの解像度変化についてけない。
##新ブレイクポイント
480px、600px、960px、1280px。
それぞれ、縦スマホ、横スマホ、タブレット、パソコン小、パソコン大、の境界である。メリットとしては、端末に依存しない、コーディングしやすい、8の倍数（デザインが美しい）。
##インナーを知る
レイアウトがおかしくなるのは、大体インナー幅の境界で起こる。そこをブレイクポイントにすればうまくいく。
新しいROMを入れて動かせるようになるまで

OEM boatloaderのロックを解除
QFILでTWRPを書き込み(windows側のドライバーの制限を弄るのを忘れないこと)
systemやdata領域が暗号化されていてアクスできないのでwipeからフォーマットする
EUIやMIUIのROMをインストール（これでTWRPは削除されて標準のブートローダーに戻る，ディスクが暗号化される，rootが外れる）
TWRPを導入
wipeからフォーマットして暗号化を外す
google play storeのpicoをzipでインストール
ReactNativeのStyleSheetの中で変数を使う。

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
## StyleSheetで変数を使うには
style自体をアロー関数にすればいい。
少し記述量は増えるし、本当に少しだけアプリが遅くなるが、今の所これで満足している。

```js
const  SMALL = 10
...

<Text style={S.text(SMALL)}>Text</Text>

...

const S = StyleSheet.create({
  text: (SMALL) => ({
    fontSize: SMALL,
    color: 'white'
  }),
  container: {
    flex: 1
  }
}

```

## 追記
なお、sytleとして、StyleSheet.createを使う代わりに、plain objctを渡す人もいるが、以下の二点の理由によりやめた方がいい。

###1 可読性の低下
  単純に、StyleSheetを使わないと、styleが、コードの中に分散しがち。
###2 パフォーマンスの低下
StyleSheetは、styleをIDにマッピングする。このことにより、毎回のオブジェクトの生成が必要なくなるため、パフォーマンスが上がる。
CSSセレクタでclass名の部分一致かつ複数条件をAND条件で指定する

# やりたかったこと
class名「fooを含む」かつ「barを含む」要素を選択する。
# 正解
`[class*=foo][class*=bar]`
# 補足
* このような場合に、「.*foo.*bar.*」のように、正規表現を書くことはできず、[class*=foo]と、属性セレクタを使って中間一致を指定するしか無いらしい。
* [][]と、属性セレクタを続けることで、複数の属性セレクタをAND条件で指定できる。
* class以外にid名等でも、同様に書けるでしょう。

# 私について
CSSセレクタ、まだまだ不勉強です。
的外れなことを言ってたら、コメントで優しく教えてくださるとうれしいです。
rails serverの再起動が必要なとき

ゼロからrailsを初めてはや3週間、エラー対処に苦労。。笑
rails serverを再起動したらすんなり消えたエラーがあってなんじゃこりゃ！となったので備忘録として書いておく。

再起動が不必要→ **appディレクトリ以下を変更したとき**
再起動が必要　→**それ以外を変更したとき**

初心者すぎて恥ずかしいけど少しづつスキルアップしていきたい。
Sense'it関連の備忘録

# Sens'it関連の備忘録
Sens'itをごにょごにょ弄ったのでそのメモ
基本的に https://qiita.com/ghibi/items/220719f348d522b02a8d に書いてあった
が、うまくいかなかったこと(Macをつかってます)

- gcc-arm-embeddedはbrewでは、インストールできず、本家のページ( https://developer.arm.com/tools-and-software/open-source-software/gnu-toolchain/gnu-rm/downloads )の通りインストールした
- dfu-utilのインストールがエラーとなった、ファイルが競合している旨のメッセージだったので、そのファイルを削除(大丈夫か？)
- ブートローダーモードになかなか入らない、ボタンの接触が悪いのかも？、しっかり素早く４回押しましょう
- Sens'itへの書込みがエラーとなる、USBをはずした状態で、「sudo make prog」を実行してから、ブートローダーモードのSensns'itを接続する

### Sens'itマニュアル
- https://docid81hrs3j1.cloudfront.net/medialibrary/2018/09/manual-sensitv3.pdf

### SDKソース
- ここからダウンロード、APIマニュアルもその中にある
  - https://build.sigfox.com/sensit-for-developers/#sensit-sdk
- githubもあるけどライブラリやマニュアルはない見たい
  - https://github.com/sigfox/sensit-sdk
  - ここ( https://github.com/sigfox )には、他にもSens'it関連のソースがありそう

### 通信ログの確認
- https://backend.sigfox.com/device/list を開く
- 該当デバイスのidをクリック
- 左ペインのMESSAGEをクリック

### WebHookの設定
- https://backend.sigfox.com/devicetype/list を開く
- 該当デバイスのnameをクリック
- 左ペインのCALLBACKをクリック
- ヘルプは下記
    - https://backend.sigfox.com/apidocs/callback

### その他
- Sens'it app
  - https://www.sensit.io/
- sigfox build
    - https://build.sigfox.com
getParameterメソッド

Java初学者です。
今回はgetParameterメソッドについてアウトプットさせていただきます。
#Q1: getParameterメソッドとは？
A:「HttpServletRequest」インターフェースのオブジェクトの中から、**クライアント側のformから送られてきたデータを取得するメソッド**です。
`上記の太字の部分のことをリクエストパラメーターと呼びます`
#getParameterメソッドの使い方は？
**リクエストパラメータは「名前」と「値」のペアで送られてきます**

```java:sample.java
request.getParameter("HTMLのname属性の値");

```
HTMLのname属性値を設定することで、name属性とセットで書いているvalue属性の値を取得することができます。
#getParameter()の注意点
getParameterで取得してきた値は全て**String**になります。

int型とか、他の方が欲しい場合はどうするの？と思う方がいるかもしれません。
int型にしたい場合は
`Integer.parseInt()`で数値にできます。
`(例)Integer.parseInt(request.getParameter("HTMLのname属性の値"));`
上記のように、他の型への変換も可能なので場面に応じて必要な型に変換してください。

※内容に間違いがあった場合、恐れ入りますがコメント欄から教えていただけると幸いです。
初学者の方はコメント欄までみていただけると、この記事より濃い内容の話が展開されている可能性がありますのでコメントまで見ていただくことをオススメします。
クロック周波数とは？

参考サイト:
http://urx2.nu/RBe9
https://121ware.com/navigate/enjoy/prevent/useful/20090804/index.html

#そもそも、クロックとは？
回路が処理の歩調をあわせるために用いる信号

#クロック周波数とは？
クロックが、1秒間に何回発生するかを示す値のこと
クロック周波数を単にクロックと呼ぶ場合もある。

#クロック周波数の単位
クロック周波数の単位はHz
1秒間にクロックが1000個あれば動作周波数は1kHzとなる

#自分の端末のクロック周波数を調べるには？
基本は、コントロールパネルの一覧から「システム」を選択し、プロセッサの末尾(下の画像の赤い四角で囲まれた部分)を確認すればわかる。
Windows10の場合はそうだけど、他のOSでは確認できない場合もあるかも。
![aaa.png](https://qiita-image-store.s3.amazonaws.com/0/368574/6112c4ac-928f-0b10-20df-dd6040dc15cb.png)
Railsで外部APIを使用する

今回はRailsでぐるなびのAPIを使用してみようと思います。
すでにぐるなびAPIのKeyを取得している、という前提で話をすすめます。
下記のコードでは「ラーメン」で検索すると、それに対する店のデータ１０件が返ってきます。

```
require 'json'
require 'net/https'
require "uri"

word="ラーメン"

data={
  "keyid": "あなたのAPI-Key",
  "freeword": word
}

query=data.to_query
uri = URI("https://api.gnavi.co.jp/RestSearchAPI/20150630/?"+query)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
res = http.request(req)
res_data=Hash.from_xml(res.body)
```
いくつかポイントとなるところを説明します。
まず、以下の箇所ですが、

```
data={
  "keyid": "あなたのAPI-Key",
  "freeword": word
}
```

こちらのハッシュでkeyに指定した文字列、keyidやfreewordは適当につけた名前ではなく、
リクエストパラメータで指定された文字列です。
どのようなパラメータがあるかは、各APIの仕様で確認してください。
次に、この箇所、

```
query=data.to_query
uri = URI("https://api.gnavi.co.jp/RestSearchAPI/20150630/?"+query)
```
この２行ではdataのハッシュをURL文字列に変換します。
ハッシュがURLパラメータ用に変換されます。
例 ： ``` {c: 3, b: 2, a: 1}.to_query # => "a=1&b=2&c=3" ```
そして文字列のダブルクォーテーション（""）の最後に?を入れて+queryを付け加えると、
変数のqueryが""のURLの文字列の最後に追加されるようになっています。

最後に、この部分のコードですが、

```
res_data=Hash.from_xml(res.body)
```

ぐるなびAPIの場合レスポンスはjsonファイルではなくXML形式ですので、xmlでデコードしなければなりません。
res_dataの中にはハッシュ型に変換されたデータが入っています。

ちなみにレスポンスがjsonファイルの場合、
```res_data=JSON.parse(res)```
というように変更します。

Net::HTTPクラスについては公式にあります。
[class Net::HTTP (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/latest/class/Net=3a=3aHTTP.html)
ガチャマクロ

```
import pyautogui
import cv2

def kinsure(x):
    pyautogui.screenshot('filename.png')
    img = cv2.imread("filename.png", 0)
    temp = cv2.imread(x, 0)
    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= 0.95:
        pyautogui.click(max_loc)
    
pyautogui.FAILSAFE = True
pyautogui.PAUSE = 2

while 1:
    kinsure("test7.png")
    
    pyautogui.screenshot('filename.png')
    img = cv2.imread("filename.png", 0)
    temp = cv2.imread("test8.png", 0)
    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= 0.95:
        pyautogui.PAUSE = 10
        pyautogui.click(max_loc)
        kinsure("test9.png")
        kinsure("test10.png")
        kinsure("test11.png")
        kinsure("test12.png")
        kinsure("test13.png")
        kinsure("test14.png")
        
    pyautogui.PAUSE = 2
```
2秒ごとにtest7.pngかtest8.pngを探す
test7.pngが見つかったらそこをクリックしてまた2秒ごとの監視を続ける
test8.pngが見つかったら(つまりカバンがいっぱいになったら)、10秒間隔でtest9~14.pngをクリックする
以下test7.png〜test14.png

![test7.png](https://qiita-image-store.s3.amazonaws.com/0/380994/48016055-314e-5ffe-fc4d-d28341d337aa.png)
![test8.png](https://qiita-image-store.s3.amazonaws.com/0/380994/6fbdc445-4cb3-1b08-4ac6-8f3c3ebe4174.png)
![test9.png](https://qiita-image-store.s3.amazonaws.com/0/380994/7ac8a2e4-aa11-2880-a194-7dffcfb8a8b3.png)
![test10.png](https://qiita-image-store.s3.amazonaws.com/0/380994/08d89297-2357-4fc8-dda7-6007e3c7c81d.png)
![test11.png](https://qiita-image-store.s3.amazonaws.com/0/380994/07f6ee33-15a3-55f5-cf2b-183b323ca07e.png)
![test12.png](https://qiita-image-store.s3.amazonaws.com/0/380994/8d3cc2c4-9386-be8e-fe05-ce4d7a85b763.png)
![test13.png](https://qiita-image-store.s3.amazonaws.com/0/380994/68ef7588-cc16-1085-3407-02b835f2d93c.png)
![test14.png](https://qiita-image-store.s3.amazonaws.com/0/380994/53995ce8-8362-604d-e0f6-ff68a3a1b432.png)

カバンがいっぱいになるまでガチャを回して、カバンがいっぱいになったら一括分解して、またガチャを回してくれる、というマクロがこれで出来る
while文の中を書き換えて自分だけのマクロを作ろう！
Reactアップデート作業記録

Reactを15.4.2から16.8.3へアップデートしました。その際に行ったことを時系列順で書いておきます。

# reactをアップデート

```diff
-    "react": "^15.4.2",
+    "react": "^16.8.3",
-    "react-dom": "^15.4.2",
+    "react-dom": "^16.8.3",
``` 

↓実行してみると、

```js
Uncaught TypeError: Cannot read property 'shape' of undefined
    at Module../node_modules/react-redux/es/utils/storeShape.js
    ...
```

reduxもアップデートしないとダメそう。

# reduxをアップデート

```diff
-    "react-redux": "^5.0.2",
+    "react-redux": "^6.0.1",
```

↓

```js
InternalPropTypes.js:3 Uncaught TypeError: Cannot read property 'func' of undefined
    at Module../node_modules/react-router/es/InternalPropTypes.js (InternalPropTypes.js:3)
```

今度はrouter。

# routerをアップデート

```diff
-    "react-router": "^3.0.2",
-    "react-router-redux": "^4.0.7",
+    "react-router": "^3.0.5",
+    "react-router-redux": "^4.0.8",
```

↓

```js
Form.js:41 Uncaught TypeError: Cannot read property 'func' of undefined
    at Module../node_modules/redux-form/es/Form.js (Form.js:41)
```

formも。

# redux-formをアップデート

```diff
-    "redux-form": "^6.4.3",
+    "redux-form": "^8.1.0",
```

↓

```js
Uncaught TypeError: Cannot read property 'string' of undefined
    at Object.<anonymous>
    ...
```

typeエラー。

# PropsTypesのimportを修正

React v15.5でproptypesが別パッケージに分離されてdeprecatedになり、v16で廃止されていました。

参考：
- [React v15.5.0 – React Blog](https://reactjs.org/blog/2017/04/07/react-v15.5.0.html)
- [React v15.5(6) and v16 - blog.koba04.com](http://blog.koba04.com/post/2017/04/14/react-dot-js-v155-and-v16/)

```diff
-import React, { PropTypes } from 'react';
+import React from 'react';
+import PropTypes from 'prop-types';
```
 
↓

```js
Align.js:53 Uncaught TypeError: Cannot read property 'object' of undefined
    at Object../node_modules/rc-align/lib/Align.js (Align.js:53)
    ...
```

rc-alignはrc-sliderで使っていそう。

# rc-sliderをアップデート

```diff
-    "rc-slider": "^5.4.3",
+    "rc-slider": "^8.6.6",
```

↓

```js
AnimateChild.js:37 Uncaught TypeError: Cannot read property 'any' of undefined
    at Object../node_modules/rc-animate/lib/AnimateChild.js (AnimateChild.js:37)
```

css-animationをアップデートしないとダメそうなので `yarn upgrade rc-slider`

↓

```js
Bar.js:12 Uncaught TypeError: Cannot read property 'string' of undefined
    at Object../node_modules/rd3/build/cjs/barchart/Bar.js (Bar.js:12)
```

今度はrd3。

# rd3をアップデート

```diff
-    "rd3": "^0.7.4",
+    "rd3": "^0.8.1",
```

やっとエラーがなくなりました🎉

# 最後にflowを確認

```js
Error:
  4: import type { SyntheticKeyboardEvent } from 'react-dom/lib/SyntheticKeyboardEvent';
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ react-dom/lib/SyntheticKeyboardEvent. Required module not found
```

Event Handling変わったのかなぁ。

参考：
- [Event Handling | Flow](https://flow.org/en/docs/react/events/)

```diff
-import type { SyntheticKeyboardEvent } from 'react-dom/lib/SyntheticKeyboardEvent';

...

-  onKeyDown = (e: SyntheticKeyboardEvent) => {
+  onKeyDown = (e: SyntheticKeyboardEvent<*>) => {
```

これでflowもパスするようになりました。
バージョンを一気にジャンプするのは大変なので、こまめにアップデートしていきたいですね…
Gitでタグを使う

# Gitでタグを使う

普段からGitを使って開発をしているが、`git tag`を使ったことがなかったので備忘録としてメモ。

## タグ付け

以下のコマンドでタグ付けができます。チェックサムを省くとカレントブランチの最新がタグづけされます。

```shell
$ git tag タグ名 チェックサムのハッシュ値
```

## タグ一覧

以下のコマンドでタグ一覧の確認できます。

```shell
$ git tag
```

## リモートリポジトリと共有

ブランチのプッシュト操作は同様です。

```shell
$ git push origin タグ名
```

## タグの付け直し

タグを付け直すには一旦タグを削除する必要があります。

```shell
$ git tag -d タグ名
```

また、タグをリモートリポジトリに共有してしまっている場合は、リモートリポジトリのタグも削除する必要があります。

```shell
$ git push origin :refs/tags/タグ名
```

あとはタグ付けの最初からやり直しです。
ExpoのdetachでAndroidのreact-native-videoやFast-imageが動かない件について

### まえおき

これは、ExpoでMVPを作ったはいいものの、物足りない部分(バックグラウンド再生とかその他ものもの)でハマる件です。

react-nativeでもかなり人気のあるreact-native-videoやreact-native-fast-imageは現状detachするとAndroidだと動きません。 (Expo ver32まで前提)

### 原因について

ExpoはOkHttpのOverride処理をしてるらしく、それがトラップになる現象が多発してる模様。

https://github.com/react-native-community/react-native-video/issues/1236#issuecomment-429709273

対応しようと思えばできるのですが、後々メンテナンスとかダルくなりそうなのでやりたくないところですね。

### 今後の動向について

iOSだとdetachしてもそれほど問題が起きるケースは少ないので、恐らくExpoのAndroid側の実装、特にdetachした後に問題がある実装がそれなりにありそうです。 

そもそもAV関連の実装はreact-native-video準拠の実装だとかなり便利だったんですけどね。

それにしても、react-native-videoとかはreact-native界隈でもトップの人気のライブラリなのでそれの対応に不都合があるとなるとやや危うい感じがしますね。。。

Expo Ver33ではOkHttp関連の修正をしてるらしいのでそれに期待。

Expoはdetach案件で結構知られてない罠が多そうなので、iOSやAndroidのネイティブ経験者がいないような会社で、割と凝ったことをアプリで実現したい場合はオススメできないかもしれませんね。

まあそもそもネイティブ経験ない会社だと、後々ハマることが続出しそうなので、軽めのアプリ開発以外は正直オススメはしませんけど。
JSON Web Token + DataStore で期限付き、無効化可能なトークンを実装する方法

# JSON Web Token + DataStore で期限付き、無効化可能なトークンを実装する方法

ritou です。

結構前に JSON Web Signature の署名生成/検証あたりの考え方をまとめた投稿をしました。
[JSON Web Signature導入における鍵周りの基本的な考え方](https://qiita.com/ritou/items/a861e952ccea8ba9e68c)

これはいろんなところで JWT(JWS) を使ってる中で署名の鍵をちゃんと整理しないといかんというところから出てきたお話でした。
今回はその "いろんな用途" の中の一つで、"有効期限付き" で "無効化可能" なトークンの実装例を文章化しておきます。

## 用途
 
* 何かの処理を始めるときに作成
* 処理をしている中でデータを積んだりする
* 処理が終わったら無効化

みたいな処理を "できるだけ DataStore の利用容量を抑えつつ" 実装するイメージです。

この "処理" の部分が1つであれば "ワンタイム" と言えますが、複数の処理を連動させたりも考慮して "無効化可能" として紹介します。
一般的なWebアプリケーションであればセッション機構を用いて値を積んだり消したりすれば済む程度のことを API ベースでやろうと思った時などに使えると思います。

## DataStore

RDB とか NoSQL 、あとはキャッシュのみの利用などの細かいことを意識しないで済むように、ここでは一連の処理の識別子について

* get
* put
* delete

ぐらいしか使わないような実装を意識しています。

## 関連する仕様

なるべく [RFC7519 JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) [日本語訳](https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html) で定義されている標準的な `Header` / `Payload` を使おうぐらいです。 

## 実装例 : CSRF Tokenみたいなやつ

特別なコンテンツを含まず、自分で生成、検証、無効化する例です。

### 1. JWT生成

下記のようなHeader / Payloadを作成して JWS を作成します。
鍵周りは上述の記事を参考にしてもらえばと思います。

* Header
  * `typ` : (必須)このJWTの種別
  * `alg` : (任意)
  * `kid` : (任意)
* Payload
  * `usage` : (任意)JWTの用途を入れたりする。Header の `typ` を使っても良さそう。
  * `jti` : (必須)識別子。UUID だったり bigint とか。
  * `exp` : (必須)有効期限を設定することで、以前発行したトークンの検証をスキップできる。
  * `iss` : (任意)発行元
  * `aud` : (任意)発行先

似たような処理でJWTを使いまくりたくなると思うので(任意)とある部分もなるべく利用するのが良さそうです。

ここで DataStore をどう使うかというあたりで、2種類ぐらいの使い方があるかなと思います。

* 有効な識別子を保存している場合 : `jti` の値を put
* 無効化された識別子を保存している場合 : 何もしない

識別子に bigint 的なのを使って生成時に衝突の可能性もある場合、前者のように `jti` の値を保存しておきます。
UUID やちょっと前に話題になってた ULID みたいな、識別子がぶつからない仕組みになっている場合は、後者でやると DataStore の容量を節約できそうです。
最後に書いてある "DataStore に残るゴミデータ" についても見ておいてください。 

### 2. JWT検証

1. JWTの種別、署名の検証 : 用途の異なる JWT や不正な JWT を除外できる
2. `iss`, `aud`, `exp` の検証 : 古い JWT などを除外できる
3. `jti` の検証 : 無効化された JWT を除外できる

3 の検証時は、DataStore で以下の処理が行われます。

* 有効な識別子を保存している場合 : `jti` の値で get して値が*ある*ことを確認
* 無効化された識別子を保存している場合 : `jti` の値で get して値が*ない*ことを確認

### 3. JWT無効化

処理が終わったらこの JWT を無効化する必要があります。

* 有効な識別子を保存している場合 : `jti` の値のデータを delete する
* 無効化された識別子を保存している場合 : `jti` の値を put する

これで再度 "2. JWT検証" で `jti` の検証が走っても除外することができます。 

## ちょっと複雑な処理への応用

このやり方は、例えばアカウント新規登録時のようにいくつかのデータを1つずつ受け取って検証、最後にガーッと登録処理を行うような場合にも DataStore 側を拡張せずに利用できます。
センシティブなデータを扱うだったら JWE 使ってもいいと思いますが、お金とかになったらそもそもこんなやり方できないと思うのでその辺はよしなに判断してください。

例えば

1. SMS送信による電話番号確認
2. ニックネーム設定
3. パスワード設定

といった処理を複数のAPIリクエストを用いて行う場合、

* 確認対象(完了前後の)電話番号
* ニックネーム
* パスワード

あたりを JWT の Payload に含んで署名を再生成して引回すことで、最後の本登録の処理の部分までデータを引回すことができます。
ちょっと JWT 関連の処理は増えるものの、DataStoreの方に仮登録状態のようなデータを持たずに識別子の管理だけで実装可能なため、登録処理に必要な情報が増えても割と簡単に対応可能です。たぶん。

## DataStore に残るゴミデータ

このような実装は、当然 DataStore にゴミデータみたいなのが残ります。

* 有効な識別子を保存している場合 : JWTの有効期限が切れても無効化されなかった `jti` の値
* 無効化された識別子を保存している場合 : 無効化された `jti` の値

`put` する際に JWT の `exp` に指定した値をうまく使って定期的に削除を試みるなど、ゴミデータが残りにくい仕組みにしておく必要があるでしょう。

## まとめ

* JWTを使った有効期限つき、無効化可能なトークンの作り方を紹介した
* DataStoreの種類にもあんまり影響しない書き方したつもりだけど実際はよしなにやってくれ
* CSRFトークンみたいな使い方や、登録処理のような複数のデータを持ちたい場合にも使えそう

以上です。
ではまた。
ABC - 058- A&B&C

#AtCoder ABC 058 A&B&C
[AtCoder - 058](https://atcoder.jp/contests/abc058)

#A問題

 - $A-B=B-C$

```java
	private void solveA() {
		int numA = nextInt();
		int numB = nextInt();
		int numC = nextInt();

		if (numB - numA == numC - numB) {
			out.println("YES");
		} else {
			out.println("NO");
		}

		out.println("");
	}
```

#B問題

 - 文字列Oと文字列Eを結合する
    - 偶数の時は文字列Oから、奇数の時は文字列Eから1文字ずつ取り出して結合する（実装だと逆になってるけど気にしない）

```java
	private void solveB() {
		String strO = next();
		String strE = next();

		StringBuilder builder = new StringBuilder();
		IntStream.range(0, strO.length() + strE.length()).reduce(0, (sum, i) -> {
			if (i % 2 == 0) {
				builder.append(strO.charAt(sum));
			} else {
				builder.append(strE.charAt(sum));
				sum++;
			}
			return sum;
		});

		//		int cnt = 0;
		//		for (int i = 0; i < strO.length() + strE.length(); i++) {
		//			if (i % 2 == 0) {
		//				builder.append(strO.charAt(cnt));
		//			} else {
		//				builder.append(strE.charAt(cnt));
		//				cnt++;
		//			}
		//		}
		out.println(builder.toString());
	}
```

#C問題

 - 全ての$文字列_i$に出現する文字を抽出
    - その文字の最小出現数を取得
        - 全ての$文字列_i$に共通している文字数は最小出現数
    - 文字を結合して、文字コード順にソートすればよい
 - 文字を抽出する際に、文字列ごとに'a'-'z'の配列を生成し、それぞれいくつあるのかを数えればよい
    - 存在しないcharは0となるので、最小出現数を数えた時に0をカウントできる

**配列の生成サンプル**

|文字列|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|cbaa|2|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
|daacc|2|0|2|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
|acacac|3|0|3|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|

```java
	private void solveC() {
		int numN = nextInt();
		/**
		 * 読み込みをStreamを使ってみてる
		 */
		String[] wk = IntStream.range(0, numN).mapToObj(i -> next()).toArray(String[]::new);

		int[][] array = new int[numN][26];

		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < wk[i].length(); j++) {
				int alphaIndex = wk[i].charAt(j) - 'a';
				array[i][alphaIndex] += 1;
			}
		}

		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < 26; i++) {
			int res = Integer.MAX_VALUE;
			for (int j = 0; j < array.length; j++) {
				res = Math.min(res, array[j][i]);
			}
			for (int j = 0; j < res; j++) {
				builder.append((char) (i + (int) 'a'));
			}
		}

		out.println(builder.toString());
	}
```
ガチャマクロ

```
import pyautogui
import cv2

def kinsure(x):
    pyautogui.screenshot('filename.png')
    img = cv2.imread("filename.png", 0)
    temp = cv2.imread(x, 0)
    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= 0.95:
        pyautogui.click(max_loc)
    
pyautogui.FAILSAFE = True
pyautogui.PAUSE = 2

while 1:
    kinsure("test.png")
```

kinsure("画像の名前")でその画像の左上のマスを何秒かごとにクリックしてくれる

クリックしたいボタンのこんな感じのスクリーンショットを切り抜くといい
![test.png.png](https://qiita-image-store.s3.amazonaws.com/0/380994/aecb683a-c77f-98fa-4c55-1c727051abcc.png)

while文の中を書き換えて自分だけのマクロを作ろう！
Pythonでディープラーニングを実装した話

# Pythonでディープラーニングを実装した話

## このドキュメントを書く理由

* 個人的な興味から簡単なディープラーニングを実装しました。入力データは、3 * 4 マスで数字の0か1のどちらかを表現するという本当に小さなものです。
* 実用上ではディープラーニングを自分で実装する必要などないでしょう。チュートリアルのしっかりしてるTensorflowなどを使えば問題ないはずです。しかし私はどうしてもディープラーニングの中身を理解したくて、そのためにPythonで実装しました。
* 本来であれば実装が済み、動くことが確認したところでこの作業は終わりになります。しかしながら私は自分がそういうことをしたのだ！ ということをどこかに残したくて(誰かに知ってほしくて)この記事を書くことにした次第です。

## 得られたもの

* 自分でディープラーニングを実装してみて得られたものは以下だと思います。

* ディープラーニングの基本的な仕組みは難しくない! という実感。
   * ディープラーニングは、行列の計算と偏微分から成り立っています。つまり、大学初年度に習うレベルの知識でしかないのです。実際に実装してみると、そのことがよくわかります。
   * もちろんディープラーニングを実用に耐えるものにするには計算上の様々な工夫が必要ですし、あくまで基本的なものはそう難しいものではない、ということです。

* 行列や微分に対する苦手意識が減ったこと
   * ディープラーニングの本を読むと、行列や微分の計算が必ず出てきます。これまで私は本にそういった内容が出てくるだけで身構えてしまうところがありました。また数式が表現することを実装レベルで理解しているとは、これまで言えない状態でした。
   * そんな私も行列の計算や微分を自分の手で行い、Python(numpy)を使って実装することができるようになりました。

* Tensorflowなどのライブラリを使う際の自信になる
   * 実務でディープラーニングを使うとなると、Tensorflowなどのライブラリを使うことになると思います。このとき「中身を知っている」という感覚があるのとないのとでは、心理的に大きく違うと思います。簡単なものでも自分で実装した経験があれば、自身を持ってチュートリアルに取りかかれるはずです。わからない設定が出てきても「調べればわかるだろう」と思えます。

## 参考文献

1. [ゼロから作るDeep Learning](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0&qid=1554016417&s=gateway&sr=8-1)
   * 基本の一冊かな、と思います。
   * ただ筆者の数学知識が微妙なのかひどいレベルの誤植があります。また誤差逆伝播法の説明も合成関数の微分の説明がなく不十分です。

1. [ディープラーニングがわかる数学入門](https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%B0%E5%AD%A6%E5%85%A5%E9%96%80-%E6%B6%8C%E4%BA%95-%E8%89%AF%E5%B9%B8/dp/477418814X/ref=sr_1_37?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0&qid=1554016417&s=gateway&sr=8-37)
   * ディープラーニングの基本的な仕組みをコンパクトにまとめている良書です。元教師の方が書かれただけあって、内容は正確で、また前提知識なしに読めます。
   * 参考文献1で、包括的な内容を、こちらで基本的な部分を理解したという感じになります。

## どのようにやったか？

* 私がディープラーニングを実装するまでの経緯です。

1. 参考文献1を読み込む
   * 時間があったので熟読しました。
   * ただ誤差逆伝播法の計算の説明が中途半端で、その部分を理解できずモヤモヤすることになりました。
1. 電車の中で参考文献2を読む
   * この本は参考文献1に比べて数学的な説明が正しく厳密で、これを読むことで誤差逆伝播法を理解できるようになりました。
   * この本では、Excelによるディープラーニングの実装方法が説明されています。
1. しばらく放置
   * しばらく他の本を読んだりして、手を付けませんでした。
1. ディープラーニングの中身を理解したい！ そのために実装しよう、と決意。
   * Tensorflowのチュートリアルに着手した際、この際だから基本的なところから復習しようと思い、ちゃんと理解するために自分で実装することにしました。
1. 参考文献2を読み直す
   * 参考文献2を読み直し、数式を整理したりしました。
   * 参考文献2には行列の演算で実装する方法が記載されていません。このあたりは参考文献1を読んだ際の記憶をたどりながら自分で考えました。
1. Pythonで実装
   * 間違いを繰り返しながらも、最後にはできました。

## 苦労したこと

* 苦労したのは誤差逆伝播法です。
* 合成関数の微分や偏微分、行列の計算を復習し、実装レベルで理解できるようになるまで大変でした。

## 実装したもの

* [実装したもの](https://github.com/9ryuuuuu/ZeroOneNN)は一応githubに上がっています。
* とりあえず動くというレベルのものです。ほかに学びたいことがあるので、今のところ完成度を上げる予定はないです。
* 簡単なディープラーニングはこの程度のコードで書けるんだ～というくらいは参考にはなると思います。

## 終わりに

* 以上。この記事を読んで頂き誠にありがとうございます。
【基本情報技術者試験対策】ハフマン符号化に関する問題の注意点

参考サイト:https://www.fe-siken.com/kakomon/30_aki/q4.html

#そもそもハフマン符号化って？
可変長の符号化方式。
出現確率が高いデータには短い符号を、低いデータには長い符号を与えることで圧縮を効率よく行う方法。

#問題の注意点
平成30年度秋期の問題を例に見ていく。
![20190317_CentOS7ダウンロード_043.JPG](https://qiita-image-store.s3.amazonaws.com/0/368574/d5cdc60e-2176-3ae2-97f9-7903395c75d5.jpeg)
符号表は出現頻度をキーに、上から降順に記載されている。
Dよりも一つ出現頻度の高いCの符号は 10であり、10進数に直すと2になる。
Dよりも一つ出現頻度の低いEの符号は111であり、10進数に直すと7になる。
そのため解答は10進数に直したとき、3~6になるものを解答すれば良いように思われるかもしれない。
しかし、実際に選択肢を10進数に直すと次のようになる。
>(ア)001 → 1
>(イ)010 → 2
>(ウ)101 → 5
>(エ)110 → 6

先ほどの考え方でいくと、(ア)と(イ)は範囲に入ってないから良いとして、(ウ)と(エ)がどちらも範囲に入ってしまっている。
つまり、この問題を解答するための観点として、範囲だけでは足りないということだ。
では、何が足りないのか。
それは、(ウ)と(エ)の符号を左から「展開」しようとしてみればわかる。
下記にその結果を示す。
>(ウ)101 → <font color="Red">24</font>1
>(エ)110 → 110

上にある通り、(ウ)を D の符号として割り当ててしまうと、実際に圧縮された文字を展開した時に、「101」の接頭辞「10」が C として展開されてしまうのだ。

#まとめ
ハフマン符号化に関する問題が出題された時は、下記のことに注意する。
・解答しようとしている符号が、出現頻度の高い文字に対して割り当てられている符号よりも大きいこと。
・解答しようとしている符号が、出現頻度の低い文字に対して割り当てられている符号よりも小さいこと。 
・解答しようとしている符号が、符号表を基に展開できないこと。
AWSでDeep Voice 3を訓練しました

AWSで音声合成した時の記録(初心者視点)です。

# 音声合成に関して
Deep Voice 3
[Wei Ping, Kainan Peng, Andrew Gibiansky, et al, “Deep Voice 3: 2000-Speaker Neural Text-to-Speech”, arXiv:1710.07654, Oct. 2017.](https://arxiv.org/abs/1710.07654)

Deep Voice 3は音声合成システムです。声の再現性、訓練速度の速さが特徴です。
https://www.atmarkit.co.jp/ait/articles/1712/22/news020.html

ここではr9y9さんの実装を使用しました。 
今回は利用していませんが、話者適応可能、日本語にも対応可能らしいです。 
https://github.com/r9y9/deepvoice3_pytorch
 
使ったデータセットはKeith ItoさんのLJSpeech-1.1です。 
https://keithito.com/LJ-Speech-Dataset/
  
# 環境  
AWS(Deep Learning AMI) 
OSはUbuntuを選びました。
ボリュームはデータセットに応じて、今回は35GiB増やして110GiBにしました。  
  
インスタンスの接続までの手順は下記を参考にしました。 
インスタンスによっては上限緩和申請が必要になります。 
https://aws.amazon.com/jp/getting-started/tutorials/get-started-dlami/  
  
# インスタンス接続後の操作
## パッケージの更新  
```
$ sudo apt-get update 
$ sudo apt-get upgrade 
$ pip install --upgrade pip  
```

[CUDAのバージョン変えたい場合はこちらへ](https://docs.aws.amazon.com/ja_jp/dlami/latest/devguide/tutorial-base.html) 
   
## 訓練の準備  
```
$ git clone https://github.com/r9y9/deepvoice3_pytorch && cd deepvoice3_pytorch 
$ pip install -e ".[bin]" 
$ python 
> import nltk 
> nltk.download('cmudict')  
```

PyTorchからGPUが使えそうか確認 

```
$ python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0));" 
True 
'Tesla K80'  
```
  
  
### データセットの取得(S3経由)  
必要なポリシー(ListBucket, GetObject)を持つユーザーをAWSマネジメントコンソールで作っておきます。


```
$ aws configure 
```
  
S3へのアップロードをした前提で

``` 
$ aws s3 cp s3://examplebucket/LJSpeech-1.1  ./LJSpeech-1.1  --recursive 
	  
$ python preprocess.py --preset=presets/deepvoice3_ljspeech.json ljspeech ./LJSpeech-1.1 ./data/ljspeech  
```
 
## 訓練  
sshの接続を切ってもいいようにバックグラウンドで訓練を開始する。  

```
$ mkdir ~/output_log  
$ nohup python train.py --preset=presets/deepvoice3_ljspeech.json --data-root=./data/ljspeech  > ~/output_log/out.log &   
```

期待通りGPUを使っているか確認  

```
$ watch -n 2 nvidia-smi
```
【機械学習】過学習の回避方法

#概要
機械学習を行う際に、問題となる過学習について、取り上げてみます。

#機械学習とは
- 人工知能のうちの一つで、機械に任意のデータ（画像データ、売上高、天気など）をINPUTして、分類、予測を学習します。その学習結果を使用する事で、テストデータをINPUTすると、分類結果、予測結果をOutputすることが出来ます。
- この際、機械にプログラミングで分類、予測させるのではなく、機械が学習アルゴリズムを使用して、機械自らが分類、予測アルゴリズムを学習します。

#過学習とは
- 機械学習で学習させすぎた際に弊害が発生します。
- 任意のデータをINPUTして学習させますが、学習させすぎるとその学習データに特化しすぎてしまい、幅を持たせたデータの分類結果、予測結果が間違ったものとなってしまいます。
- 例えば、「犬」のテストデータを与えて、画像解析させたケースを考えて見ます。
    - このケースで、テストデータを学習させすぎると「犬」の細かい特徴まで捉えてしまいます。（過学習）
    - 結果、何かのテストデータをINPUTして判定させたときに、細かい特徴の差異を判断してしまい、正しい結果を出せなくなってしまいます。
- よって、機械学習させるときに、過学習を防ぐ考慮が必要となります。

#過学習の回避方法

##回避方法①　ホールドアウト法
- 学習用データを7:3くらいの割合で訓練データと評価データに分けて学習させる事によって、精度をチェックする。

##回避方法②　K-分割交差検証
- 学習用データをk個に分割して交互に訓練データ、評価データに分けて学習させる事によって、精度をチェックする。
- 例えば、kを10とした場合
    - 1,2,...10とデータを分割。
    - 1を検証データ。1以外を訓練データとして学習
    - 2を検証データ。2以外を訓練データとして学習
    - ...
    - 10を検証データ。10以外を訓練データとして学習

##回避方法③　正則化
- 学習用データの内、複雑なデータ、滑らかでないモデルに罰則を与えて、重みを下げる事です。言い換えると、学習用データの内、他と余りにもかけ離れたデータは無視、または重要度を下げて学習モデルを複雑にしない、滑らかにするという事です。
- 機械学習においては、主にL1正則化、L2正則化が使用されているようです。

###L1正則化(Lasso回帰)
- 他と余りにもかけ離れたデータの重みを0にする事で、学習用データから削除するものです。

###L2正則化(Ridge回帰)
- 他と余りにもかけ離れたデータの大きさに応じて0に近づけて、学習結果を滑らかにするものです。
Slackの過去ログをSlackっぽいUIで閲覧できる slack-patron を heroku で動かす（大概無料）

なんとなくherokuで動かそうと思って苦労したので、インターネッツに貢献する意味で記録しておきます。

# 事例
kaggler-ja さんとかが使ってますね。
[kagger-jaさんの過去ログサイト](https://kaggler-ja-slack-archive.appspot.com/)
[kaggle slackの過去ログ閲覧アプリをGAEで構築した話](http://yutori-datascience.hatenablog.com/entry/2018/07/05/115919)

と思ったら、別者でした・・・。

まあ、見た目と機能性はおおむね同じだと思います（python製 vs Ruby製という違いはある）。

# 前提
- heroku cli が導入済み
- git が導入済み
- rubyが導入済み (bundler は無ければ rubygems で入れて下さい)
- Herokuにアカウントを作成済み
- 対象のSlackの過去ログをエクスポート (zipファイルでダウンロードできるやつ) してある
- npm が導入済み
- パスワード認証とかをかける仕組みを slack-patronはもたないので、万が一にも第三者に見られてはまずいということであれば、自前でベーシック認証などやる必要があると思いますが、heroku でできるのかは知りません（私は予測不可能なアプリ名にして、チャット参加者だけでそのアドレスを共有するという方法で、十分かと考えています）。

# 手順
はい、やっていきますよー。

私がちょこちょこと修正入れたりデプロイ用のファイルを追加したリポジトリをcloneしてくる

```bash
https://github.com/ryogrid/slack-patron.git
```

公式の 1.Setup をやる。これで config.yml が生成されるので、ローカルリポジトリに登録して下さい。

```bash
heroku create 好きなアプリ名
```

で、heroku上に今回使うアプリを空の状態で作成します。
これにより、ローカルリポジトリの remotes に heroku が追加されます。

続いて、herokuのダッシュボードから上記で作成したアプリを選択して、Resourcesのタブを選択し、アドオンの検索フォームから "mLab MongoDB" を選択し、アプリのアドオンとして登録してください。
これで MongoDBが使えるようになりました。

MongoDBにアプリケーションからアクセスするためにはユーザID、パスワード、データベース名が必要ですが、それらを丸っと含んだURIが、

```bash
heroku config:get MONGODB_URI
```

で読み取れます。
その内容をconfig.yml の database - uri のところに転記しておいて下さい。
(環境変数でアクセスするのが一番セキュアだとは思うのですが、なぜかうまくいかなかったので、私はこのようにしました。）

続いて、あまり大きいと微妙・・・・ではあるのですが、取得しておいたSlackの過去ログのアーカイブを gitリポジトリに登録して下さい。
これは、MongoDBに取得しておいたデータをインポートするために行います。

そして、インポートは、

```bash
heroku run bundle exec ruby ./bin/import.rb エクスポートしたファイル.zip
```

ってな感じでheroku上のDynoでコマンド実行する形で行います。
過去ログの量が多いとすごく時間がかかるかもなので気長に待ってください（herokuは何でも一定時間で打ち切っちゃうんだっけな・・・。だとしたら面倒ですね）

あとは気づくまでにしばらく時間がかかったのですが、配信用のフロントエンド(JS)をローカル環境でビルドしておく必要あります。

```bash
cd viewer
npm install
npm build
```

これで、viewer/public/buildに app.js が生成されます。
このファイル一つでWebフロントエンドになっています。
ちなみに、この記事を書いた時点で私がビルドしたものをリポジトリに入れてあるので、slack-patron最新との乖離が大きくなったりするのが嫌でなければ、これを使っていただいても構いません。

あとは、以下のようにデプロイすればOK、のはずです。

```bash
git push heroku master
```

できたサイトは **https://あなたがつけたアプリ名.herokuapp.com** でアクセスできます。

なお、slack-patron は 最新の投稿も自動で取り込んでくれるようにできていて、そこの機能を担う、logger.rbというのも Worker dynoでデプロイされます。

こいつは、冒頭で取得した Slackのトークンを使って、ひたすら最新の情報を取得し、MongoDBに追加していく、というような処理をしているようです。
　
なお、worker dyno は外部からアクセスを受けない（起こせない）ので、どの程度の時間でスリープしたりするのかはちゃんと把握していません。
そこは私もこれからどうするか考えよう、という感じです。
(管理画面から見ると、最初からのような気もするのですが、loggerの方の dyno がOFFになっていたりするので、ONにするようにしてあげて下さい。もしかしたら、時間制限の話も同様に対応するしかないのかもしれません。

以上、誰かの助けになれば幸いです。

追記:
Worker dyno はそもそも sleep しないそうです。
なので、一か月でざっくり 744 dyno時間を消費するので注意して下さい。
(クレジットカードを登録していれば月に1000 dyno時間まで使えるはずなので、大抵は大丈夫だと思いますが）
ABC - 060- A&B&C

#AtCoder ABC 060 A&B&C
[AtCoder - 060](https://atcoder.jp/contests/abc060)

#A問題

 - 文字Aの最後と文字B最初、文字Bの最後と文字Cの最後が同じならしりとりができる
 - 最初と最後はString#charAt()を使う

```java
	private void solveA() {
		String strA = next();
		String strB = next();
		String strC = next();

		out.println(strA.charAt(strA.length() - 1) == strB.charAt(0)
				&& strB.charAt(strB.length() - 1) == strC.charAt(0) ? "YES" : "NO");

		out.println("");
	}
```

#B問題

 - 余りには周期がある
 - 周期はBの数（割る数）分
 - $A*1$ から $A*B$ まで $mod5$ を繰り返す。

**周期を表で記載**

 - 余りは　{$3,1,4,2,0$}　を繰り返す
 - 余りの個数はB個 （割る数）


|index|A(の倍数)|B|C(の候補)|
|:-:|:-:|:-:|:-:|
|1|3|5|3|
|2|6|5|1|
|3|9|5|4|
|4|12|5|2|
|5|15|5|0|
|6|18|5|3|
|7|21|5|1|
|8|24|5|4|
|9|27|5|2|

```java

	private void solveB() {
		int numA = nextInt();
		int numB = nextInt();
		int numC = nextInt();

		if (numA == 1) {
			out.println("YES");
			return;
		}
		boolean res = false;
		for (int i = 1; i <= numB; i++) {
			res = (i * numA) % numB == numC;
			if (res) {
				break;
			}
		}

		out.println(res ? "YES" : "NO");
	}
```

#C問題

 - 次の人がボタンを押下するまでの間の時間を調べる
    - シャワーの出る時間より長い場合
        - シャワーは最後まで出る
    - シャワーの出る時間より短い場合
        - シャワーは途中までで終わる（次のシャワーの時間が始まる）
    - 最後のシャワーは次の人がいないので時間いっぱい出る

```java
	private void solveC2() {
		int numN = nextInt();
		long numT = nextInt();

		long[] wk = LongStream.range(0, numN).map(i -> nextLong()).toArray();

		//		long res = 0;
		//
		//		for (int i = 0; i < numN; i++) {
		//			if (i == numN - 1) {
		//				res += numT;
		//			} else {
		//
		//				if (wk[i + 1] - wk[i] >= numT) {
		//					res += numT;
		//				} else {
		//					res += wk[i + 1] - wk[i];
		//				}
		//
		//			}
		//		}
		long res = IntStream.range(0, numN).reduce(0, (sum, i) -> {
			if (i == numN - 1) {
				sum += numT;
				return sum;
			}
			if (wk[i + 1] - wk[i] > numT) {
				sum += numT;
			} else {
				sum += wk[i + 1] - wk[i];
			}
			return sum;
		});
		out.println(res);
	}
```

#C問題:for版

```java
	private void solveC() {
		int numN = nextInt();
		long numT = nextInt();

		long[][] wk = new long[numN][2];
		for (int i = 0; i < numN; i++) {
			wk[i][0] = nextInt();
			wk[i][1] = 0;
		}

		if (numN == 1) {
			out.println(numT);
			return;
		}

		wk[0][1] = wk[0][0] + numT > wk[1][0] ? wk[1][0] : numT;
		for (int i = 1; i < wk.length; i++) {
			if (i == wk.length - 1) {
				wk[i][1] = wk[i - 1][1] + numT;
				continue;
			}

			if (wk[i][0] + numT > wk[i + 1][0]) {
				wk[i][1] = (wk[i + 1][0] - wk[i][0]) + wk[i - 1][1];
			} else {
				wk[i][1] = numT + wk[i - 1][1];
			}

		}
		out.println(wk[numN - 1][1]);
	}
```
Raspberry Pi の標準エディタ「nano」のメモ

# はじめに
自分用の"nano"に関するメモ。随時更新していきます。

# 環境
Raspberry Pi3
Raspberry Pi ZeroWH

# 行番号表示
"nano"はデフォでは行番号を表示しない。
/etc/nanorcのコメントアウトされている「set linenumbers」をコメントアウト解除すればOK。

```file:/etc/nanorc
set linenumbers
```

# 操作
| 操作 |ショートカットキー|
|:--|:--|
| 検索 | Ctrl + w|
| 保存 | Ctrl + o|
| 終了 | Ctrl + x|
忙しい人の為にRails Developers Mettup 2019 発表資料を分類 Day2

# アーキテクチャ

* Introduction of scalable microservice for video editing/transcoding 
Sudekiqのアーキテクチャ
https://speakerdeck.com/_atsushisakai/transcoder?slide=58

* Architecture Evolution in Repro 
https://speakerdeck.com/joker1007/architecture-evolution-in-repro

* 操作履歴/時点指定アクセスの実現 - BiTemporal Data Model の実践
データ履歴管理としてBiTemporal Data Modelを採用
https://speakerdeck.com/f440/implementing-command-history-and-temporal-access?slide=97

* Ruby on Railsの正体と向き合い方 What is Ruby on Rails and how to deal with it?
https://speakerdeck.com/yasaichi/what-is-ruby-on-rails-and-how-to-deal-with-it

* 巨大なモノリシック Rails アプリケーションのマイクロサービス化戦略 
https://speakerdeck.com/hokaccha/2019-microservices-in-cookpad



# プロダクト、チーム

* 全体がいい感じになるために、私たちRailsをホームにするWeb技術者ができること
https://speakerdeck.com/moro/let-our-whole-system-grow?slide=67

* サービス開発初期の「時間を金で買う」技術 
https://speakerdeck.com/mstshiwasaki/sabisukai-fa-chu-qi-false-shi-jian-wojin-demai-u-ji-shu?slide=65

* エンジニアリングマネジメントの孤独と向き合う 
https://speakerdeck.com/koichiro/railsdm2019-on-the-lonely-rail-of-engineering-management?slide=45

* ログを解析し続けてわかった、会社で眠っているアクセスログを活用する5つのプラクティス 
https://speakerdeck.com/ikedaosushi/practices-to-utilize-access-logs?slide=65

# 開発手法

* Clean Test Code, Revised 
https://speakerdeck.com/willnet/clean-test-code-revised?slide=110

* 入門 名前 
https://speakerdeck.com/fujimura/ru-men-ming-qian?slide=41

* Misocaにおけるビジュアルテストへの取り組み
https://slides.com/kokuyouwind/railsdm2019#/

* コードレビューしない 
https://speakerdeck.com/hanachin/kodorebiyusinai?slide=94

* 自分たちを信じられるチームが作りたくて私はこうした 
https://speakerdeck.com/katsumataryo/railsdm-katsumata?slide=65

# 技術紹介

* Roda and Rails 
https://docs.google.com/presentation/d/1DYs4sNFBPVCqwE6FpE8_DK6ENrQNii7zHFbMqYf_dhA/edit#slide=id.4eda6b81-4c2c-11e9-97e2-a3f217c9afd3

* Webアプリケーションの開発運用で当たり前に必要とされる画像変換の中身 
https://speakerdeck.com/unak/internal-of-the-image-processing-required-on-the-developing-of-web-applications?slide=43

* Evolution of Enumerator 
https://speakerdeck.com/knu/evolution-of-enumerator?slide=63

* Charty on Rails 
https://speakerdeck.com/284km/charty-on-rails-railsdm-2019?slide=41

* 自己修復的なインフラ 
https://www.slideshare.net/sinsoku/self-healing-infrastructure

# キャリア

* みんながやりたがらない仕事をやって食っていく 
https://www.youtube.com/watch?v=SEedFiUouwQ&feature=youtu.be

* Ruby コミュニティの歩き方
https://speakerdeck.com/koic/somebody-to-ruby?slide=127

* ガチスタートアップ1人目のバックエンドエンジニアのリアルな戦略と奮闘 
https://speakerdeck.com/sinamon129/gatisutatoatupu1ren-mu-falsebatukuendoenziniafalseriarunazhan-lue-tofen-dou-number-railsdm2019-number-railsdm2019b-at-sinamon129?slide=59
python3の高機能な関数

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているryota_miraidenshiです。
今回は、HackerRankのpython編で多く登場している高機能な関数についてまとめておきます。

#map
```index.py
original_list = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
mapped_list = map(lambda x: x**2, original_list)
 
print(list(mapped_list))
```

実行結果は

```index.py
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

上記のようになります。
このようにmap関数を使うことで**一つの要素に対する処理をリスト全体に**してくれます。
ただし注意しておきたいのが、Python3ではmap関数の返り値はmap型のオブジェクトになるので、list型に変換してあげないといけません。
map関数では第一引数に処理内容、第二引数に処理対象のリストを記述します。


#lambda
map関数でサラッと書いていましたが、lambdaは**関数に名前を付けずに定義するもの**です。
改まって関数とする必要でもないものに対してこれを使うと効率よくシンプルにプログラミングができます。
###for文を実装する場合
いつも通りだと

```index.py
prices = [3000,2500,10500,4300]
paymentList = []
for price in prices:
    paymentList.append(price * 1.08)
 
print(paymentList)
```

lambda式を使うと、

```index.py
prices = [3000,2500,10500,4300]
paymentList = list(map(lambda price:price * 1.08 , prices))
 
print(paymentList)
```

ここで先ほどのmap関数が使われます。
lambda式の基本的な書き方は以下の通りです。

```index.py
#lambda式の形式
lambda 引数:処理内容
```

###for文内にif文で処理する場合
普通の場合には

```index.py
prices = [3000,2500,10500,4300]
paymentList = []
for price in prices:
    if price > 3500:
        paymentList.append(price)
 
paymentList.sort()
 
print(paymentList)
```

lambda式を利用すると、

```index.py
prices = [3000,2500,10500,4300]
priceList = list(filter(lambda price:price > 3500, prices))
priceList.sort()
 
print(priceList)
```
どちらもシンプルになっているのがわかるはずです。
ここで登場したのがfilter関数です。
これについては次で説明します。

#filter
filter関数は第二引数のリストの各要素に対して第一引数の処理を行い、**Trueとなるものだけを抽出**します。
使い方はmap関数とほとんど同じで、返り値も同じですので気をつけましょう。

#おわりに
噛み砕くと、forの代わりがmap()とlambda、forの中でif処理を行う代わりがfilter()とlambdaということでしょう。

プログラム初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正しますのでどんどん指摘してください。