OmniAICreator/Qiita-1.07M huggingface dataset:
AndroidのMediaPlayerについての備忘録

MediaPlayerについて調べたり触ったりしたので、いろいろとざっくりまとめてみた。

#MediaPlayeを使う
参考：[MediaPlayer overview](https://developer.android.com/guide/topics/media/mediaplayer)

公式ドキュメントには3つの使用例が記載されてる
・リソースファイルを再生する場合
・URIから再生する場合
・ストリーミング再生する場合
これに沿って3つの使用例を記載しておく

## リソースファイルを再生する場合
 
```java:リソースファイルを再生
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.hoge);
mediaPlayer.start();
```
## URIから再生する場合

```java:URIから再生
Uri myUri = ....; 
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
``` 

## URLからストリーミング再生をする場合

```java:URLからストリーミング再生
String url = "http://........";
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); 
mediaPlayer.start();
```

```xml:AndroidManifest.xml
<!--ネットワークにアクセスするための権限を設定-->
<uses-permission android:name="android.permission.INTERNET" />
```

# よく使うかもしれないMediaPlayerのメソッド

参考：[MediaPlayer](https://developer.android.com/reference/android/media/MediaPlayer)

| 戻り値 | メソッド | 説明|
|:-----------------|------------------:|:------------------:|
| void | start() | 再生 |
| 〃|           pause() | 一時停止 |
| 〃|              stop() | 停止 |
| 〃|                prepare()|         準備(同期)|
| 〃|             release()|       リソースを開放する|
| 〃|           reset()|      プレイヤーをリセットする|
| 〃| setVolume(float leftVolume,float rightVolume)|左右の音量設定する|
| 〃| seekTo(int msec)| 再生位置を指定する|
| boolean|           isPlaying()|      再生中かどうか返す|
| 〃|            	isLooping(boolean looping) |ループ再生の設定をする。trueはループ、falseはループなし|
| int|           getDuration()|      ファイルの再生時間を返す|

# ストレージから音声ファイルのURIを取得する
端末毎にある、標準のPickerUIを通じてファイルにアクセスする
参考：[一般的なインテント](https://developer.android.com/guide/components/intents-common?hl=ja#Storage)
　　　[ACTION_OPEN_DOCUMENT](https://developer.android.com/reference/android/content/Intent.html?hl=ja#ACTION_OPEN_DOCUMENT)
　　　[ストレージ アクセス フレームワーク](https://developer.android.com/guide/topics/providers/document-provider.html?hl=ja)
　　　[[Android] Storage Access Framework で画像を取り出す](https://akira-watson.com/android/gallery.html)


```java:MainActivity.java

static final int CHOSE_FILE_CODE = 1;//任意の整数
Uri uri;

public void selectAudio() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("audio/*");
    startActivityForResult(intent, CHOSE_FILE_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CHOSE_FILE_CODE && resultCode == RESULT_OK) {
        uri = data.getData();
        //やりたいこと
        ...
        ...
    }
}

```
徐々にLinux操作に慣れるTips    

# 目的
Linux操作に慣れるべく、役立つコマンドを順次記載していきます。

# バイナリファイルのダウンロードと展開

```
$ curl -PL http://url-to-binary-file
$ sudo tar -xzvf binray-file 
```

# ユーザー関連

## ユーザーのみ一覧表示

```
$ cut -d: -f1 /etc/passwd
```

## ユーザー一覧表示

```
$ cat /etc/passwd 
```

## グループ一覧

```
$ cat/etc/group
```

## グループ追加

```
$ groupadd [option] GROUPNAME
```

### オプション

- -g
    - 任意のGIDのグループを追加する
- -p
    - パスワード付きのグループを追加する
   

## ユーザ追加

```
$ useradd [option] USERNAME /bin/bash
```

### オプション
- -g
    - グループを指定する
- -u 
    - ユーザーIDを指定する
- -s
    - ログインシェルを指定する
- -c
    - コメント登録する
    

## ユーザー設定変更

```
$ usermod [option] USERNAME
```

### オプション
- -c
    - コメントを登録する
   
## ログイン中ユーザー表示

```
$ who 
```

## ユーザーパスワード変更

``` 
$ vi pass.txt
testuser:password
$ chpasswd < pass.txt
```

# ディレクトリ関連

## ディレクトリ作成、なかったら作る

```
$ mkdir -p /dir/to/make
```


## ディレクトリのコピー

```
$ cp -r /path/to/dir /path/for/dir
```

## ディレクトリ権限の確認

```
$ ls -l 
```

|1文字目  | 2~4文字目  |  5~7文字目  | 8~10文字目   |
|---------|----------|---------|---------|
|ファイル種別  |所有者に対する権限  |所有グループに対する権限  | その他に対する権限  |
port is in use でサーバーが使えない場合の対処

# 実行環境
* macOS Mojave 10.14.5
* ruby 2.6.3
* sinatra 2.0.5
* VSCode2 1.37.1

## エラー文言と状況
*プログラミング初学者のため、誤りがあればご指摘いただけますと幸いです。


誤って複数回やらかしたのでメモに残します。
sinatraで作ったwebアプリ「app.rb(仮)」をブラウザ上で見ようとサーバーを起動するも、なぜかエラーを吐かれました。

```console
$ ruby app.rb
== Sinatra (v2.0.5) has taken the stage on 4567 for development with backup from Thin
Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop
Stopping ...
== Sinatra has ended his set (crowd applauds)
Traceback (most recent call last):/Users/shinya/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:531:in `start_server'
/Users/shinya/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:531:in `start_tcp_server': no acceptor (port i
s in use or requires root privileges) (RuntimeError)
```

エラー文の最後に ```port is in use``` と出ているので
Chromeから`localhost:4567`へ接続すると、すでに他のアプリ「alt.rb(仮)」でサーバーに接続中。
しかしターミナルでは通常利用する`ctrl + c`では当該サーバーを停止できませんでした。

##プロセスを調べてkill
使用中のポートを確認し閉じる必要があるので、以下を入力。
```ps aux | grep ruby```

```console
$ ps aux | grep ruby
shinya            5348   0.6  1.6  4559084 135328   ??  S    10:34PM   0:24.32 /Users/shinya/.rbenv/versions/2.6.3/bin/ruby /Users/shinya/.rbenv/versions/2.6.3/bin/solargraph socket --port 0
shinya            5197   0.0  0.3  4387360  21360   ??  S    10:33PM   0:00.63 ruby alt.rb
shinya            6229   0.0  0.0  4277256    804 s002  S+   11:20PM   0:00.00 grep ruby
```
alt.rbがポート番号(PID)「5197」を使用中と出ています。
次に`kill -9 当該PID`と入力してポートをkillします。

```console
$　kill -9 5197 ←「5197」にはご自身のターミナルに表示されたポート番号(PID)を入力してください
```
killできた場合は特にレスポンスがないはず。
今回は割と簡単に解決できて良かったです。

##参考にしたサイト
[port in use when not using a port](https://stackoverflow.com/questions/14049765/port-in-use-when-not-using-a-port)
BMI計算：JavaScript学習

#経緯
今までノリで書いていたjsを基本から勉強しようと思ったから。
復習にもなると思ったのでQiitaに投稿してみました。

#コード内容

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <style>
        #yase {
            color: blue;
            font-size: 30px;
            border-bottom: solid 3px;
        }
        #himan {
            color: red;
            font-size: 30px;
            border-bottom: solid 3px;
        }
        #hyojyun {
            color: green;
            font-size: 30px;
            border-bottom: solid 3px;
        }
    </style>
    <script>
        function calcBMI() {
            var a = document.getElementById("i0").value;
            var b = document.getElementById("i1").value;
            var num1 = parseFloat(b / (a * a));
            var num2 = num1 * 10;
            var bmi = Math.ceil(num2) / 10;

            if (bmi < 18.5) {
                document.getElementById("yase").textContent = "痩せ";
            } else if (bmi >= 25) {
                document.getElementById("himan").textContent = "肥満";
            } else if (bmi >= 18.6 && bmi < 25) {
                document.getElementById("hyojyun").textContent = "標準";
            }

            document.getElementById("bmi").textContent = bmi;
        }
    </script>
</head>

<body>
    <h2>BMI計算機</h2>
    身長(m)⇒<input id="i0" value="" /><br>
    体重(㎏)⇒<input id="i1" value="" /><br><br>
    <button onclick="calcBMI()">check</button><br><br>
    <span>あなたのBMIは</span><span id="bmi"></span><span>です。</span>
    <p><span>判定は・・・</span><span id="yase"><span id="himan"><span id="hyojyun"></span></p>
</body>

</html>
```
#苦労したところ
◆小数点の位置と切り上げ

```js
//小数点数に変換
var num1 = parseFloat(b / (a * a));

//小数点第1位を基準にするための処理
var num2 = num1 * 10;

// 切り上げのceilメソッドを使う
var bmi = Math.ceil(num2) / 10;
```

#実際の画面
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/3ca5bd0c-021f-1cf2-8356-5ea8d1b92321.png)
以下、ボタン押下後。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/05518664-df88-74f9-df78-a47d94846fac.png)



#これから
DOM操作、コールバック関数について学習を進めていきたい。

#参考文献・サイト
- 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで
- ゲームで学ぶJavaScript入門 HTML5&CSSも身につく！
- https://www.pazru.net/js/number/3.html
- https://qiita.com/nagito25/items/0293bc317067d9e6c560
TypeScript + styled-components で Theme に型をつける

# 概要
styled-components では `<ThemeProvider>` を用いることで、プロジェクト全体で使用するカラーコードの Theme を取り扱うことができます。
https://www.styled-components.com/docs/advanced#theming
この記事ではこの Theme に対して独自の型を定義する方法を紹介します。

# 環境
- `react@16.9.0`
- `typescript@3.5.3`
- `styled-components@4.3.2`
- `@types/styled-components@4.1.18`

# リポジトリ
https://github.com/odan-sandbox/typescript-styled-components-sandbox

# 方法
`styled-components` モジュール内部の `DefaultTheme` という interface に対して型をつけることで目的を達成できます。
この方法は `@types/styled-components` のコメントで言及されているやり方です。
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5ce56f22065bc465282b94b0537743d342be3fa7/types/styled-components/index.d.ts#L407-L414

## [src/types/styled-components.d.ts](https://github.com/odan-sandbox/typescript-styled-components-sandbox/blob/master/src/types/styled-components.d.ts)
次のような感じで `.d.ts` ファイル内で `styled-components` の型定義を拡張してやります。

```ts
export interface Theme {
  black: string,
  white: string,
}

declare module "styled-components" {
  interface DefaultTheme extends Theme {}
}
```

## [src/Hello.tsx](https://github.com/odan-sandbox/typescript-styled-components-sandbox/blob/master/src/Hello.tsx)
使用する側はこのような感じです。コメントにある通り、 `theme.black` のところで型の補完が効きます。

```ts
import * as React from "react";
import { ThemeContext } from 'styled-components';

const Hello: React.FC = () => {
  const theme = React.useContext(ThemeContext);
  theme.black // <= 補完が効く
  return <div>Hello!</div>
}

export default Hello;
```
Railsチュートリアル（第11章）

# はじめに
Railsチュートリアルの第11章が終わりました。
この章では、アカウントの有効化のためにメールの送信を行います。
ポイントだけメモしておきます。

# アカウントの有効化
基本的なやり方は、9章のログインの考え方と似ています。

・ユーザーの有効化状態をfalseとする
・ユーザー登録時に、有効化トークンとそれをハッシュ化したダイジェストを作成する
・ダイジェストは、ユーザーと紐づけてデータベースに保存する
・トークンは、ユーザーにアクセスしてもらうリンクにパラメータとして仕込み、メールで送信する
・メールのリンクにアクセスし、リンクに含まれるトークンとデータベースのダイジェストを比較し、一致すれば有効化する

# AccountActivationsコントローラー
有効化用のコントローラーを作成します。

```
 rails generate controller AccountActivations
```
以下のようにルートを追加します。リンクからアクセスする場合、GETメソッドになってしまうため、updateではなくeditアクションを使用します。

```rb:config/routes.rb
Rails.application.routes.draw do
 ...
 resources :account_activations, only: [:edit]
end
```

# メーラーの作成
以下のコマンドでメール送信のためのテンプレートを生成できます。

```
rails generate mailer UserMailer account_activation
```
以下の２つのテンプレートが生成されます。
テキストメール用とHTML用メールです。
・app/views/user_mailer/account_activation.text.erb
・app/views/user_mailer/account_activation.html.erb

また、以下のファイルに設定を記述します。
以下はfromメールアドレスです。

```erb:app/views/user_mailer/account_activation.text.erb
class ApplicationMailer < ActionMailer::Base
  default from: "from@example.com"
  layout 'mailer'
end
```
メーラーファイルには、テンプレートへ渡す変数や、送信先メールアドレス、件名を記述します。

```rb:app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  def account_activation(user)
    @user = user
    mail to: user.email, subject: "Account activation"
  end
end
```

# sendメソッド
sendメソッドを使用することで、呼び出すメソッドを動的に決めることができます。これにより、メソッドの名前に変数を使用したりできます。

以下のように、`attribute`の引数に与えられた内容によって、呼び出すメソッドを変更しています。
`authenticated?(:remember, '')`で呼び出すと、`remember_digest`メソッドを呼び、`authenticated?(:activation, '')`で呼び出すと、`activation_digest`メソッドを呼び出します。

```rb
def authenticated?(attribute, token)
  digest = self.send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end
```
Python3.4で最大公約数（GCD）と最小公倍数（LCM）


## なぜPython3.4
AtCoderの現在のPythonのバージョンが3.4だから。
また、使用するモジュールが最新の3.7と異なるため。

## 最大公約数（GCD）

```python
>>> from fractions import gcd
>>> gcd(4,6)
2
>>> gcd(8,12)
4
```

ちなみに、Python3.7では、mathモジュールに移行されている。


## 最小公倍数（LCM）

GCDを使って求められる。

```python
>>> from fractions import gcd
>>> x, y = 2, 4; (x * y) // gcd(x, y)
4
>>> x, y = 8, 12; (x * y) // gcd(x, y)
24
```

### リストのLCMを求める

```python
def lcm(a):
    from fractions import gcd
    x = a[0]
    for i in range(1, len(a)):
        x = (x * a[i]) // gcd(x, a[i])
    return x

a = [3,4,6]
print(lcm(a))  # 実行結果: 12
```
Webアプリを Macアプリにする

epichrome というアプリを使用して、ChromeのタブをMacアプリ化します。
また、Chrome Extension に対応しています。

# 1. dmg をインストール

以下の リンクから .dmg をダウンロード
https://github.com/dmarmor/epichrome/releases

# 2.  Epichrome でアプリ作成

Epichrome.app を起動します。


## 2.1 OK をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/41303b8c-8c8d-fbe7-b10f-d11611e30b73.png)
![](media/15664793365361/15668245248128.jpg)

## 2.2 ファイル名を決めて、保存をクリック（これはアプリ名ではないです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/d876afe9-db3e-7561-4f7d-523c0043aac9.png)
![](media/15664793365361/15668247135803.jpg)

## 2.3 アプリ名を決めて、OKをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/ec4efa7e-aa04-510b-444e-f39189d4e4c7.png)
![](media/15664793365361/15668248227144.jpg)

## 2.4 アプリの起動スタイルを設定

- **App Window** : 単一ウィンドウ
- **Browser Tabs** :  Chromeと同じようにタブを表示できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/35c6856e-8d0f-01c5-b821-c16f5fa970a1.png)
![](media/15664793365361/15668249950066.jpg)

## 2.5 起動時の初期ページURLを登録

### **App Window** の場合

初期表示のURLを入力して OK をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/e95fcfff-8099-4c8e-8dfc-ca009d340f82.png)
![](media/15664793365361/15668252372229.jpg)

### **Browser Tabs** の場合

- **Add** : 初回ページは常に入力したURLを開く
- **Done(Don't Add)** :  入力を終了する（URLを１つもAddしていない場合は、Chromeの設定に合わせる）

Add を押すと２つ目のタブの初回ページURLの入力画面が表示されます。
（以降、複数のタブ毎に初回ページのURLを設定できます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/c55f4f79-4e81-67c9-3ae7-fddba1c31a7c.png)
![](media/15664793365361/15668254877254.jpg)

## 2.6 デフォルトのブラウザとするかを選択

**Yes** を選択すると 「システム環境設定」->「一般」->「デフォルトのWebブラウザ」に表示されます。
（デフォルトブラウザに設定すると htmlファイルなどを開いたとき本アプリが起動します）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/be7af030-ecb8-ecad-da58-277e7fbaa6c8.png)


## 2.7 カスタムアイコン設定

オリジナルのアイコンを設定する場合は **Yes**
好みの画像ファイルを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/24f6b852-db40-642c-a1fa-b95ef3156f63.png)
![](media/15664793365361/15668283112691.jpg)


## 2.8 Launch Now でアプリ起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/8eea750f-e0fb-ed12-c185-1baab714376f.png)
![](media/15664793365361/15668270480603.jpg)

## 2.9 Epichrome Helper の有効化

アプリを起動すると以下の画面が表示されるので、
画面の指示に従って Epichrome Helper を有効にします。
Epichrome Helper を有効にしたら、一度アプリを再起動してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/91e0e16d-34a7-271c-c247-f5aaf6b57519.png)
![](media/15664793365361/15668264417082.jpg)
VeeValidate の blur が vuejs-datepicker で機能しない

プロパティ `:typeable="true"` を設定することで解決する。
ただし、ユーザーによる自由入力が可能となってしまう為、適宜入力制御処理を実装する。

# 例

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Sample</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossorigin="anonymous">
</head>
<body>
<div class="container">
    <div id="app">
        <form>
            <label>date</label>
            <vuejs-datepicker
                    :format="DatePickerFormat"
                    :typeable="true"
                    wrapper-class="form-group"
                    :input-class="{'form-control': !errors.has('inputDate'), 'form-control is-invalid': errors.has('inputDate')}"
                    name="inputDate"
                    v-model="inputDate"
                    v-validate="'required'"
            ></vuejs-datepicker>
            <small class="form-text text-danger" v-show="errors.has('inputDate')">
                {{ errors.first('inputDate') }}
            </small>
        </form>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vuejs-datepicker@1.6.2/dist/vuejs-datepicker.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/vee-validate.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/locale/ja.js"></script>
<script>
    Vue.use(VeeValidate, {
        events: 'input|blur',
    });
    new Vue({
        el: '#app',
        data: function () {
            return this.initialState()
        },
        components: {
            vuejsDatepicker
        },
        methods: {
            initialState: function () {
                return {
                    inputDate: '',
                    DatePickerFormat: 'yyyy-MM-dd',
                }
            }
        }
    });
</script>
</body>
</html>
```
tensorflow-rocmでimport時にSegmentation fault (コアダンプ)になった話

# 環境
OS：ubuntu 19.04
Python version：3.7.3
tensorflow version：1.14.1

# 状況
Pythonに入ってtensorflowをimportすると以下のようになってPythonが落ちる。

```python
python3: Relink `/lib/x86_64-linux-gnu/libsystemd.so.0' with `/lib/x86_64-linux-gnu/librt.so.1' for IFUNC symbol `clock_gettime'
python3: Relink `/lib/x86_64-linux-gnu/libudev.so.1' with `/lib/x86_64-linux-gnu/librt.so.1' for IFUNC symbol `clock_gettime'
Segmentation fault (コアダンプ)
```

# 対処
libtinfo5をインストールすることで正常にimportできるようになった。

```terminal
sudo apt install libtinfo5
```
なんでかは分からん。

# ちょっと気になったこと
どうやってlibtinfo5が足りないと思ったのかの話。

Pythonでtensorflowをimportしたときにはlibtinfo5が足りないよみたいなことは言われなかったけど、

```terminal
python3 -import tensorflow
```
ってやって、そのなかでimportすると

```python

ImportError: libtinfo.so.5: cannot open shared object file: No such file or directory
```
のようにlibinfo5が足りないよって言われた。
んでそれを入れればいいのかなと思って入れてあげたら動くようになったんだけれども、

```terminal
python3 -import tensorflow
```
って何をやっているのだろうか。
最後のtensorflowは意味なさそうで、

```terminal
python3 -import
```
でも同じことのようだけれどもこのコマンドの意味がよくわからない...
Rails6.0にVuetifyの環境(CDN無し)を整えてみた

## Rails6.0にVuetify環境を構築しました

CDN無しでVuetifyを使えるようにしました。
これにより、オフライン環境でもVuetifyを利用した開発が可能になると思われます。

## 記事内容は[こちら](https://www.imanau-blog.site/posts/2019/09/10/rails-4.html)に設置しました。
Nginx IPアドレスでのアクセスを拒否

#はじめに
Nginxを初期状態でインストールするとドメイン名でもIPアドレスでもアクセスができます。
しかしIPアドレスでアクセスができる状態で放置しておくと、
IPアドレスで総当りで「なにか」を調べようとしているのか、
ありえないような国からのアクセスがやたらきます。
まあ、サーバを公開している人なら誰しもが経験するかと思います。
ロ○アとか中○人民共和国とかはザラで、ブ○ジル、ウ○ライナなどなど。
Seychelles(セーシェルと呼ぶらしい)という聞いたことないところのアクセスログもありました。
踏み台にでもされているんですかね。単にIPがそこのというだけでしょうか。

```
cat /var/log/nginx/access.log
xx.yy.77.139 - - [25/Aug/2019:14:59:58 +0900] "GET /robots.txt HTTP/1.1" 404 169 "-" "-" "-"
xx.yy.77.139 - - [25/Aug/2019:14:59:58 +0900] "GET /sitemap.xml HTTP/1.1" 404 169 "-" "-" "-"
xx.yy.77.139 - - [25/Aug/2019:14:59:59 +0900] "GET /.well-known/security.txt HTTP/1.1" 404 169 "-" "-" "-"
xx.yy.77.139 - - [25/Aug/2019:15:00:00 +0900] "GET /favicon.ico HTTP/1.1" 404 169 "-" "python-requests/2.13.0" "-"
xx.yy.53.14 - - [25/Aug/2019:15:29:33 +0900] "GET / HTTP/1.1" 403 571 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" "-"
```
Google先生に聞いてみるといくつか方法が出てきますが、
私が実際に使って動いたものをメモしておきます。



#方法1
よくあるシンプルなやつ(だと思う)
/etc/nginx/nginx.confの最後に

```
server {
        listen 80 default_server;
        server_name 8.8.8.8;
        return 444;
}
```
を追加する。
`8.8.8.8`はNginxを起動しているサーバのIPアドレス。
これが一番シンプル(と思う)


#方法2
参考:http://beniyama.hatenablog.jp/entry/2015/04/05/100000
IF文でドメイン以外を444へ (例:google.com以外へのアクセス拒否)

```
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name google.com;
        if ($host != "google.com"){
                return 444;
        }
```
とあるプロジェクトに関わったときに使用されていたのはこれに近かった。
こちらのほうがわかりやすかったので参考元のを記載。
参考元の方も言及されていますが
>server_name を指定しているのにもう一度チェックしていて若干冗長な感じ

が否めないですね。
Vue.js初心者お勉強-その2- firebase編

## 前回までのおさらい

[Vue.js初心者お勉強-その1- - Qiita](https://qiita.com/teraco/items/3dafff7b99065c81303e)

firebaseのHelloWorldと、Vue.jsのHelloWorld + 構成を軽く勉強しました。今回はVue.jsをfirebaseにデプロイします。

## 写経する記事

こちらです。

[【Firebase】Vue.jsで作ったWebアプリを公開する方法を解説【初心者向け】 | Public Constructor](https://public-constructor.com/firebase-hosting-vuejs-for-beginners/)

## 手順と図解

…といっても本当に簡単であった。

### 1. [Firebaseコンソール](https://console.firebase.google.com/)にログインし、画面の指示に従ってプロジェクトを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/75983ed3-963c-4fe9-47c9-1f56bcd21eb8.png)

### 2. 作成されたプロジェクトのSDKを、vue.jsのルートのindex.htmlに張り付け

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/6060b08e-42f4-e83c-cac1-0ff3fbccf496.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/50aa7017-3c7e-95b4-e3ff-2b3ee266e2a2.png)

### 3. firebase initコマンドで、vue.jsのプロジェクトをfirebase化

注意点として、ここで指定するfirebaseの公開ディレクトリ名は、次でビルドするvue.jsの公開ディレクトリ名と一致させる必要がある。規定だとpublicとなるが、変更する場合は別の名前を入力する。

### 4. npm run buildでvue.jsのプロジェクトをビルド

前回のエントリで実施した通り&言及した通りだが、config/index.jsの設定を変更することで、公開ディレクトリ名を設定することができる。今回はpublicに設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/b2b6a41b-7824-de8f-59ab-c5a6bda2e0bd.png)

### 5. firebase deployコマンドで、firebase化されたvue.jsのプロジェクトをfirebaseにデプロイ

終わり。

正直、非常に簡単にWebアプリがデプロイ出来て驚いている。これなら、簡単なアプリを手元でサクッと開発して、サクっとWebに公開できるなと思った(もちろん、深堀するとお作法などあるかもしれないが)

## 今後の計画

vue.js と firebaseの関係はこれまでとして、次はいよいよvue.jsでやりたいことをやっていくことにします。
Git で複数 branch による開発

add-a, add-b ブランチを作成

```terminal
$ git branch
* master
$ git branch add-a
$ git branch add-b
$ git branch
  add-a
  add-b
* master
```

master -> add-a ブランチへ切り替える

```terminal
$ git checkout add-a
Switched to branch 'add-a'
```

add-a ブランチで a.txt を追加

```a.txt
a
```

差分(a.txt)をリモートリポジトリへ push

```terminal
$ git add .
$ git commit -m "add a.txt"
$ git push --set-upstream origin add-a
```

add-a -> add-b ブランチへ切り替える

```terminal
$ git branch
* add-a
  add-b
  master
$ git checkout master-b
Switched to branch 'add-b'
```

add-b ブランチで b.txt を追加

```b.txt
b
```

GitHub で base:master <- compare:add-a の pull request を作成、マージ

master ブランチの差分を add-b ブランチに反映

```terminal
$ git pull origin master
```

差分(b.txt)をリモートリポジトリへ push

```terminal
$ git add .
$ git commit -m "add b.txt"
$ git push --set-upstream origin add-b
```

GitHub で base:master <- compare:add-b の pull request を作成、マージ

リモートの master ブランチに a.txt, b.txt が追加されているため、ローカルに反映

```terminal
$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
$ git pull
```
Pythonのいろいろな関数やメソッド

#はじめに
未来電子テクノロジーでインターンをしている宮﨑です。
今回は、Pythonを学習していくうちに学んだ関数をいくつか書いてきます！
もし誤りがあれば修正するのでどんどん指摘してください。


#join
文字列や数値などを連結させます。

```py

test = ['ab','c','de']
result = ''.join(test)
print(result)
# abcde　が出力される
```
' 'の間に好きな文字を入れることによって、その文字で区切れます。

#map
リストなどのすべての要素に同じ演算を適用します。
使い方の一例として、数値と文字列を結合することもできます。

```py
date = [2019, "年", 8, "月", 26, "日"]

# map()を使ってすべての要素を文字列に変換
date = map(str, date)
```
#split
文字列をスペースや' , 'で区切ります。

```py
test = orange,apple,banana
print(test.split(','))
# ['orange', 'apple', 'banana']
```


#まとめ

初心者なので、関数やメソッドは未知のものだらけです。
知らない関数に出会って調べてみると、世界が広がります。
見たことのない関数があったら、どんどん調べていきましょう。


#参考
join
https://www.sejuku.net/blog/41752
map
https://python.atelierkobato.com/map/
split
https://qiita.com/Morio/items/38701038ad098dd5dc3d
[Confluence] CQLでContent Propertyをまとめて取得する

ConfluenceはContent(ページ、コメントなどいろいろ)に、メタデータを保存することができる「Content Property」という機能がある。埋め込んだメタデータはREST APIから操作できるだけでなく、CQLで条件に該当する全部のメタデータを取得することも可能となっている。

この機能を使えば、各ページに埋め込んだ情報の統計データをすぐに収集できるので、WikiをただのWebサイトとしてではなく、情報収集にも活用することができるようになる。

もし、集計の実現を`?expand=body.storage`で内部保存形式を取得、解析してから行おうなんて考えているなら、ページごとにJavascriptを仕込んで、Content Propertyに保存することを考えた方が処理負荷的に賢明だと思う。

# Content Propertyの取得方法
Content Propertyでキーが`key`の物を取得する方法は以下の3通りある。一括で複数取得できるのは、Content(Search)だけの模様。

|API| 対象    | リクエストURI |
|:----------|---------|-------------------------------------------------------|
|[Property](https://docs.atlassian.com/ConfluenceServer/rest/6.15.7/#api/content/{id}/property-findByKey)   | 単一    | /rest/api/content/{id}/property/**{key}**|
|[Content(GetById)](https://docs.atlassian.com/ConfluenceServer/rest/6.15.7/#api/content-getContentById)| 単一    | /rest/api/content/**{id}**?expand=metadata.properties.**{key}**|
|[Content(Search)](https://docs.atlassian.com/ConfluenceServer/rest/6.15.7/#api/content-search)| 複数    | /rest/api/content/search?cql=**{cql}**&expand=metadata.properties.**{key}**  |

> 備考: `/rest/api/content/**{id}**?expand=metadata.properties`を実行すると、`metadata.properties._expandable`に、利用可能な`key`が列挙される。

# CQL
`cql`に指定できる文字列は、「[Advanced Searching using CQL](https://developer.atlassian.com/server/confluence/advanced-searching-using-cql/)」で書かれている条件式となる。「[Content properties in the REST API](https://developer.atlassian.com/server/confluence/content-properties-in-the-rest-api/)」によると、CQLでContent Propertyの値に対して`content.property[<KEY>].<PATH> <OPERATOR> value`という式で条件を設定することができるようだった。いくつかサンプルを作ってみて試してみようと思う。
【slick.js】スマホでautoplayが止まる現象の対策

slickでautoplay設定をしていたが、スマホで見たときに画像をタッチしながらスクロールしたらautoplayが止まる現象が起きた。そんな時の対策をメモ。

ちなみに今回、スライドアニメーションは「fade」にしていた。

```html
<div class="mv_sp">
      <img src="images/mv1_sp.jpg" alt="">
      <img src="images/mv2_sp.jpg" alt="">
      <img src="images/mv3_sp.jpg" alt="">
</div>
```

#対策１. autoplay止まる系オプションを無効に
何らかのアクションでautoplayが止まるのを有効にしてしまうオプションがある。
とりあえず下記オプション全てをfalseに設定

- **pauseOnFocus**：フォーカスで一時停止
- **pauseOnHover**：マウスホバーで一時停止
- **pauseOnDotsHover**：ドットナビをマウスホバーで一時停止

```js
$('.mv_sp').slick({
    arrows: false,
    autoplay: true,
    autoplaySpeed: 5000,
    speed: 1500,
    fade: true,
    pauseOnFocus: false,
    pauseOnHover: false,
    pauseOnDotsHover: false,
    waitForAnimate: false
  });
```

→ 解決ならず・・・

#対策2. タッチ操作イベントにautoplayを動かす処理を追加
・スマホでタッチしながらスクロールする操作は、**touchmove**イベントで制御できそうとみる。
・イベントに対してautoplayをスタートする**slickPlay**メソッドを設定。

```js
$('.mv_sp').on('touchmove', function(event, slick, currentSlide, nextSlide){
    $('.mv_sp').slick('slickPlay');
  });
```

→ 無事解決！
Project Euler 58をPythonでやってみる

# 問題58
英語
https://projecteuler.net/problem=58
日本語
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2058

# 解答58
正直そこまで工夫はしていません。
4つ進むごとに増加する値が2増える数列になっているのでその通りに進めていき、1周ごとに10%未満になるか調べるだけです。

コードは次のようになります。

```python:ProjectEuler51.py
import math

def is_prime(n):
    for k in range(3, int(math.sqrt(n)) + 1):
        if n % k == 0:
            return False
    return True


dist = 4
num_of_prime = 3
num_of_all =5
num = 9
while 10*num_of_prime >= num_of_all:
    for i in range(0,3):
        num += dist
        if is_prime(num):
            num_of_prime += 1
    num += dist
    num_of_all += 4
    dist += 2

print(dist-1)
```

8.469 seconds
AWS Certified Alexa Skill Builder - Specialtyを受けてきた

AWS Certified Alexa Skill Builder - Specialtyを受けてきました。
取得を考えている方の参考になれば幸いです。

# 試験概要
https://aws.amazon.com/jp/certification/certified-alexa-skill-builder-specialty/

- 時間：170分
- 問題数：65問[^1]

[^1]: 試験ガイドに記載が無いので、問題数は変わるかもしれません

# 事前準備

1. [Alexa道場](https://developer.amazon.com/ja/alexa-skills-kit/webinars)をみながらハンズオン
2. 模擬試験を受ける
3. [Alexa Skills Kitのドキュメント](https://developer.amazon.com/ja/docs/ask-overviews/build-skills-with-the-alexa-skills-kit.html)を読む

# 結果

受験者スコア: 757 !?
>The AWS Certified Alexa Skill Builder - Specialty (AXS-C01) の試験結果は、100 から 1000 の
間の値で示されます。合格に必要な最低スコアは 750 です。

何とかギリギリ合格出来ました。

# 受験者のスペック
参考になるかわかりませんが。。。

- クラウド歴：5年半
- クラウド関連の保有資格
    - AWS: アソシエイト×３＋プロフェッショナル×２＋Big Data＋Security＋Network＋ML
    - GCP: クラウドアーキテクト＋データエンジニア＋デベロッパー
- 外観：メガネぼーず

# 感想
出題範囲は、思っていたより広く感じました。また考える要素がなく純粋に知識を問う問題がほとんどでした。
丸２周見直してもかなり時間は余りましたが、準備・知識不足でこれ以上時間があっても点数は上がらない感じでした。
音声対話以外の部分も含めスキルの開発・デバッグ・テスト・公開・課金まで、スコープを絞らず万遍なくハンズオン等で準備しておけば良かったと反省。
10分でできるCodeigniter導入

#概要
CodeIgniter(コードイグナイター)は、複数あるPHPのWeb開発フレームワークの一つです。
特徴として、「高速」・「軽量」・「シンプル」を実現しており、
PHPの基礎を学んだ方が初めて触るフレームワークとして紹介されることも多いようです。

実は、導入が10分レベルで簡単です。
そこで、今回は実際の利用法をご紹介いたします！

#その１．Codeigniter本体を落としてアップ

https://codeigniter.com/
からダウンロード。
![code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/3ccf5e5b-ea19-8248-58ca-01a02a77ab4f.png)


展開したファイルをサーバにアップロード。
![files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/875dc90d-4a20-cfd0-0f06-666d072fcd5e.png)


#その2．基本設定ファイル（config.php）を編集
application/config/config.php内
”base_url”についての設定をする。
初期設定では、
$config[‘base_url’] = ‘http://example.com/’;

これを環境によって設定します。
サーバーの環境変数を使う場合はこんな感じ。↓
```
$config['base_url'] = "http://" . $_SERVER["HTTP_HOST"] . "/";
```
#その3．DB設定(DB使わなければ不要)
application/config/config.php内

```
$db['default'] = array(
        'dsn'   => '',
        'hostname' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'database_name',
        'dbdriver' => 'mysqli',
        'dbprefix' => '',
        'pconnect' => TRUE,
        'db_debug' => TRUE,
        'cache_on' => FALSE,
        'cachedir' => '',
        'char_set' => 'utf8',
        'dbcollat' => 'utf8_general_ci',
        'swap_pre' => '',
        'encrypt' => FALSE,
        'compress' => FALSE,
        'stricton' => FALSE,
        'failover' => array()
);
```
大体の場合以下を編集すればＯ.Ｋ.

hostname： DBサーバのホスト名
username： DBベースのユーザ名
password： DBのパスワード
database： DB名
dbdriver：DBのタイプ（mysqli（MySQLの場合）, postgre（PostgreSQLの場合））

これだけでもう開発がスタートできます！お手軽ですね。

#URLについて

さて、カンタンに始められるCodeigniterですが、慣れないとちょっとややこしい（？）点があります。

初期設定のままだと
http://test.com/index.php/[Controller]/[Action]/[Parameter1]/[Parameter2]/
のような奇妙なURLになってしまいます。
これではちょっと人には見せられませんね……（泣）

解決するためには、以下の設定が必要です。

①.htaccess
```
RewriteEngine on
RewriteCond $1 !^index\.php
RewriteRule ^(.*)$ /index.php/$1 [L]
```

②httpd.confの設定
```
RewriteEngine on
RewriteCond $1 !^/index\.php
RewriteRule ^(.*)$ /index.php/$1 [L]
```

↑それぞれ上から
・mod_rewriteを有効に
・URIの書き換えルールからindex.phpを除外
・RewriteCondで指定したものを除く全てをindex.phpの後ろにつづけたURIに書き換えたものとして処理

#おわりに
Codeigniterは、認証機能が標準で付いていないのがネックという意見も一部ではあるようです。（ライブラリやプラグインの追加で可能です。）
しかし、Laravelなど新たな人気フレームワークが台頭してきた今でも、高速性と自由度の高さから採用され続けています。2006年から使われていることからその信頼性も十分です。
未経験の方は、この機会に是非一度は触ってみてはいかがでしょうか。

参考：
[CodeIgniter 3入門（インストールから設定まで）]
(http://onocom.net/blog/codeigniter-3%E5%85%A5%E9%96%80%EF%BC%88%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%8B%E3%82%89%E8%A8%AD%E5%AE%9A%E3%81%BE%E3%81%A7%EF%BC%89/)
[Codeigniter 徹底ガイド](http://www.ci-guide.info/)
FileServer移行（AD有り） W2012R2 → W2016

適当なメモ

シャドウコピーの設定を手で移す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/7b7c0089-a085-95ac-21d8-f06d88624338.png)



クオーターの設定はExport/Import
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/eab58c55-e902-9377-6c15-a46ea6272c75.png)
※ハマりどころ
Exportは選択されたものだけExportされるので注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/ac3f6a9e-cefd-402b-7a81-7dec415384cd.png)

ここは移行されないので手で移す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/a1d36dfa-2e2a-46ec-0239-647e6c71ba7d.png)




ファイルを移す
`ROBOCOPY コピー元 コピー先 /MIR /COPYALL /R:0 /W:0 /NP /V /LOG+:ログファイル`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/98d13c1c-06ad-f2b0-043f-bd0814bad511.png)


共有設定を移す
移行元
`Get-SmbShare -Special $false  | ? { $_.Path -like "D:\*" }| Export-Clixml -Path D:\SmbShare.xml`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/5e2e2391-e22b-ddbe-29f7-f79e93aa8fb9.png)
↓
移行先（出力したSmbShare.xmlをインポートする）※共有をすでに設定しているとエラーになるので注意
`Import-Clixml -Path D:\SmbShare.xml | New-SmbShare`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/2e0427d4-19f1-f5cf-1f4e-009f0087a9a0.png)
Firebase Test Labのcloudtestingscreenshotter_libで意図したスクリーンショットが撮れているかをローカルで確認する

Firebase Test Labでスクリーンショットを撮るために `cloudtestingscreenshotter_lib` というライブラリが提供されています。（ライブラリのDL、導入方法などは下記公式ページへ→ [Firebase Test Lab インストゥルメンテーション テストのスクリーンショットを作成する](https://firebase.google.com/docs/test-lab/android/test-screenshots)）

このライブラリを使用することで、Firebase Test Labでスクリーンショットを撮ることができますが、テストコードを作成する過程で **意図したスクリーンショットが撮れているか** を毎回Test Labで試すのはちょっとイケておりません。（無料枠だと尚更）

ということで、 `cloudtestingscreenshotter_lib` で意図したスクリーンショットが撮れているかをローカルで確認する方法をご紹介。(※ここでのローカルとは、Firebase Test Labではなく、PCに繋いだ実機やエミュレーターのことを指します。)



# スクリーンショットは `/sdcard/screenshots/` に保存されている
はい、これが全てですが、 `cloudtestingscreenshotter_lib` の `ScreenShotter.takeScreenshot` で撮影したスクリーンショットは `/sdcard/screenshots/` に保存されます。

ですので、スクリーンショットを撮影した後に `/sdcard/screenshots/` に保存された画像を見て、意図したスクリーンショットかどうかを確認すればOK。

↓ のようなテストコードの場合

```kotlin

package com.example

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun testIsIntendedScreenshot() {
        // ・・・
        
        // スクリーンショットを撮る
        ScreenShotter.takeScreenshot("s", activity)
    }
}
```

↓ のような感じに、スクリーンショット画像が `/sdcard/screenshots/` に保存される。
<img width="668" alt="スクリーンショット 2019-08-24 11.20.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/29a7a7aa-621c-0f37-d9bc-f2a06b53d3eb.png">

これで無駄にTest Labを走らせることなく、意図したスクリーンショットが撮れているか確認することができますね。

## ちなみに
スクリーンショットを保存するためには `WRITE_EXTERNAL_STORAGE` のパーミッションが付与されてないといけないため、 `GrantPermissionRule` などを使用して、適宜パーミッションが付与される必要があったりします。（Firebase Test Labでは無くても問題ないようだった :thinking: ）

```kotlin
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {

    @get:Rule
    var grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
```
PostgreSQLとpostgresql-clientのバージョンが合ってないと怒られた

`Rails`で、データベースのダンプの取り方には2種類あるということで、
ダンプを`SQL`で設定して、マイグレーションした際に、下記のように怒られました。

```:error
pg_dump: server version: 12beta2 (Debian 12~beta2-1.pgdg100+1); pg_dump version: 11.4 (Debian 11.4-1)
pg_dump: aborting because of server version mismatch
```

なんか、バージョンがあっていないらしい

確認してみると、`PostgreSQL`のバージョンは`12beta2`で、

```
# psql --version

psql (PostgreSQL) 12beta2 (Debian 12~beta2-1.pgdg100+1)
```

`postgresql-client`のバージョンは`11.4`だった

```
# pg_config

VERSION = PostgreSQL 11.4 (Debian 11.4-1)
```

クライアントのバージョンを上げようと、色々調べたけど、
現在`latest`のバージョンは`11`らしく、
僕の力では、できませんでした...

# `PostgreSQL`のバージョンを`11`に下げることにした

`PostgreSQL`は`docker-compose.yml`で構築しているので、
`image: postgres:11`にして、

`postgresql-client`は`postgresql-client-11`とバージョンを指定してインストールするようにした。

マイグレーションを実行すると...

```:rails/db/structure.sql
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_with_oids = false;

--
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.ar_internal_metadata (
    key character varying NOT NULL,
    value character varying,
    created_at timestamp without time zone NOT NULL,
    updated_at timestamp without time zone NOT NULL
);
```

できた〜

# 終わり

DBを構築する上で、クライアントのバージョンも気にしないといけないんだな〜
PythonでAtCoderが解きたいメモ

最近ずっとやりたかったPythonを本格的（？）に始めることにした。AtCoderをPythonで解きたいのでよくでてきそうなやつをあくまで自分で見る用にまとめていきたいと思う。
※Python以外もロクにやったことがないのでそんなの知ってて当たり前だろ！という関数ばっかりです。。

```python:入力
a,b=map(int,input().split())
```
複数の変数を一気に入力するときに使う。

```python:切り捨て割り算
print(a//b)
```
割られる数`//`割る数で小数点以下切り捨て。

```python:絶対値
print(abs(a-b))
```
abs関数。

```python:1番大きい値を取得
print(max(a,b,c))
```
簡単。minもある。かっこの中の要素は幾つでもよい。

```python:置き換え
replace("water","agua")
```
文字列中の`water`を`agua`に置き換える。後者を空欄`""`にすれば、前者の文字列の部分をカットすることもできる！（aguaはスペ語で水）

```python:べき乗
print(a**b)
print(pow(a,b))
```
`**`でべき乗（a^b）。pow関数もある。`*`より優先で計算される。
                                                                          
```python:入力をリストに入れ、ソート
num = list(map(int, input().split()))
num.sort()
```
小さい順になる。リストの1個目は[0]であることに注意。

```python:文字列aの長さぶん作業する
for i in range(len(a)):
```
`len()`で文字列の長さを取得できる。ここでは`range`で長さ`len(a)`のリストが作られていることになる。

```python:文字列に含まれるか？
rtn = 'p' in 'python'
print(rtn)
#[結果] True
```
`not in`もある。if文で使うことが多そう

```python:文字の位置
a = 'あいうabcあいう'
print(a.find('b')) # 4
```
`rfind`で後ろからサーチ。

```python:for
A = ["1","2","3"]
for i in A:
    print(i) #1 2 3
```

```python:特定の文字の数を数える
str = 'aAaAAbAccdd'

# "A"を数える
str.count('A')
4
```

```python:文字列の一部の文字を変える

# 元の文字列
str = "abcdefghi"

# リストにする
str_list = list(str)
print(str_list)

# リストの3番目の要素を'z'に
str_list[2] = 'z'

# リストから文字列へ戻す
str_changed = "".join(str_list)
print(str_changed)
```

```python:文字列を分割しint型にする
s=input()
s_1=int("".join(s[0:2])) #1文字目、2文字目
s_2=int("".join(s[2:4])) #3文字目、4文字目
```

```python:配列aをカンマ区切りで出力
print(",".join(a))
```

```python:配列ansをヨコ一行に出力
for i in ans:
    print(i,end=" ")
```
これ知らなかった。これは知っとくべき

```python:deque
from collections import deque
a=deque()
a.append(3)
a.appendleft(5)
print(a)

# deque([5, 3])
```
listでは先頭の要素に対する削除や追加（挿入）は処理が遅く、dequeのほうが効率が良い！
実際にdequeでTLEが大幅に改善した〜（ABC 066）

毎回大事そうなのを見つけるたびに更新していく予定of予定です。
人のコードを見て学ぶのって大事だね。（Pythonってやっぱ読みやすいからそれがすごくしやすいね）
「10」を「ten」という文字に変換する



例えばこのテキストを

```
I have 2 apples.
```

これに変換したいとする

```
I have two apples.
```
そういう場合こちらのライブラリが便利だった
[Github - num2words](https://github.com/savoirfairelinux/num2words)

こんな感じ

```python
from num2words import num2words

text = "I have 2 apples."
print(text)
# I have 2 apples.
new_text = ""
split_words = [num2words(word) if word.isdecimal() else word for word in text.split()]
print(" ".join(split_words))
# I have two apples.
```
上記コードは下記GoogleColabratoryで再現できるようにしておいた。
[GoogleColabratory - num2words.ipynb](https://colab.research.google.com/drive/1k9VtZr4-vRYKWwyG89xJHcDSwiRwQhYW)


# 参考
- [Github - num2words](https://github.com/savoirfairelinux/num2words)
- [pypi - num2words](https://pypi.org/project/num2words/)
- [note.nkmk.me - Pythonで文字列が数字か英字か英数字か判定・確認](https://note.nkmk.me/python-str-num-determine/)
アノテーションのインスタンスはDynamic Proxy

アノテーションのインスタンスはDynamic Proxyです。

## 確認してみる

こんな感じのアノテーションを定義して、

```java
package com.example;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface FooBar {
}
```

こんな感じでアノテーションのインスタンスから`Class`を書き出すコードを書いて、

```java
package com.example;

@FooBar
public class Main {

    public static void main(final String[] args) {
        final FooBar a = Main.class.getAnnotation(FooBar.class);
        System.out.println(a.getClass());
    }
}
```

実行すると次の出力を得られました。

```console:出力
class com.sun.proxy.$Proxy1
```

ご覧の通り（？）Dynamic Proxyですね。

## Dynamic Proxyはどこで作られているのか

`Class.getAnnotation`を辿ると`AnnotationParser.annotationForMap`へ行き着きます。

コードを見るとアノテーションの`Class`を使ってDynamic Proxyが作られていることが分かります。

```java
    /**
     * Returns an annotation of the given type backed by the given
     * member {@literal ->} value map.
     */
    public static Annotation annotationForMap(final Class<? extends Annotation> type,
                                              final Map<String, Object> memberValues)
    {
        return AccessController.doPrivileged(new PrivilegedAction<Annotation>() {
            public Annotation run() {
                return (Annotation) Proxy.newProxyInstance(
                    type.getClassLoader(), new Class<?>[] { type },
                    new AnnotationInvocationHandler(type, memberValues));
            }});
    }
```

- [AnnotationParser.annotationForMap](https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java#l301)

Dynamic Proxyを作るときに渡される`InvocationHandler`実装は`AnnotationInvocationHandler`です。
アノテーションに対するメソッド呼び出しは全て`AnnotationInvocationHandler`によって処理されます。

- [AnnotationInvocationHandler](https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java)

アノテーションのインスタンスから`AnnotationInvocationHandler`を取得したくなったら`Proxy.getInvocationHandler`を使います。

```java
final FooBar a = ...
final InvocationHandler h = Proxy.getInvocationHandler(a);
System.out.println(h.getClass());
```

```console:出力
class sun.reflect.annotation.AnnotationInvocationHandler
```

## 補足情報

そもそもDynamic Proxyってなんや？という方は`Proxy`と`InvocationHandler`のJavadocをご参照ください。

- [Proxy (Java SE 11 &amp; JDK 11 )](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/lang/reflect/Proxy.html)
- [InvocationHandler (Java SE 11 &amp; JDK 11 )](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/lang/reflect/InvocationHandler.html)
なんとなくわかるRAID。

記念すべき1記事目はRAID〜！ᐠ( ᐛ )ᐟᐠ( ᐖ )ᐟ


↓まずはエンジニア向けの説明。↓

RAID（Redundant Arrays of Inexpensive Disks、または Redundant Arrays of Independent Disks、レイド）[1]は、複数台のハードディスクを組み合わせることで仮想的な1台のハードディスクとして運用し冗長性を向上させる技術[2]。ディスクアレイの代表的な実装形態で、主に信頼性・可用性の向上を目的として用いられるものである。
![60658133-C97F-4689-BBA0-F723E78A6ED9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482793/f4afabf2-fc5a-64a6-94fe-5b6dbd330a17.png)

https://ja.m.wikipedia.org/wiki/RAID


うん。まったくわからん(^o^)👌(^o^)👌(^o^)👌

では具体的に。

今回は
**RAID1 RAID0 RAID10**
について説明していきます！


**RAID1**
ディスク2個。ミラーリング
データを順番通りに二つのディスクに書き込む。
冗長化のための技術。


**RAID0**
ディスク4個。ストレイピング
データを順番は気にせずに書き込む。
処理を速くするための技術。


**RAID10**
ディスク最低4個 読み方はRAIDイチゼロ。
データの順番を気にせずに二つのディスクに書き込む。
冗長化と速さを両立した技術。


というのがエンジニア向けです。
(※これでもまだざっくりしています。書き込み中の障害とかそういう込み入った要素は省いています。)

これで分かる人はここから下読まなくていいとおもいます。(T＿T)むしろわたしに教えてください


**↓以下IT無関係および何も知らない人向け↓**

ここからが本命！
トランプで例えます！
わからなかったらごめん！！！

**RAID1**
散らばったトランプを7並べみたいに順番通りにケースにしまう。
これを2セット用意する。
1セットなくしても予備がある状態。


**RAID0**
散らばったトランプをテキトーにケースにしまう。
順番に並べる作業がない分しまうのが速くなる。


**RAID10**
散らばったトランプを順番は気にせずにケースにしまう。
これを2セット作る。
綺麗に並べない分作業が速く、2セットあれば1つなくなってもまだ1つ残っている。


以上〜！！！
「あー、なんか想像ついた気がする。」
って思ってもらえたら幸いです:clap:



・・・・・

**【おまけ】**ぼんやりふんわり専門用語解説。

**【冗長化 信頼性 可用性】**
障害対策。データが消し飛ぶ不安を減らすこと。


**【ディスクアレイ】**
「外部記憶装置」「ストレージ」の違う言い方。
「味噌汁」も「御御御付け」も言い方違うだけで実物は同じだよねみたいな感じ。


**【ストレージ】**
身近な例はテレビの外付けHDDとかかな？？
データを蓄えておく機械のこと。
(ストレージって何？って聞かれてパッと説明できる人って意外と少ないとおもう。)


、、、おしまい🤗🤗🤗今度気が向いたらRAID6とか書きます！
【jq】JSON と ndjson の変換

# JSON から ndjson への変換

```json:data.json
[
  {
    "id": 111,
    "value1": "aaa"
  },
  {
    "id": 222,
    "value1": "bbb"
  }
]
```
```sh:変換
jq -c '.[]' data.json
```
```json:結果
{"id":111,"value1":"aaa"}
{"id":222,"value1":"bbb"}
```

# ndjson から JSON への変換

```json:data.ndjson
{"id":111,"value1":"aaa"}
{"id":222,"value1":"bbb"}
```
```sh:変換
jq -s '.' data.ndjson
```
```json:結果
[
  {
    "id": 111,
    "value1": "aaa"
  },
  {
    "id": 222,
    "value1": "bbb"
  }
]
```

# 参考

jq Manual (development version)
https://stedolan.github.io/jq/manual/#Invokingjq
テキストマイニングにおけるattention風の可視化は、もっと評価されるべき

attention風の可視化は、もっと評価されるべきと考えたので共有します。
オリジナルの実装は、以下のリンク先にあります。

【 self attention 】簡単に予測理由を可視化できる文書分類モデルを実装する
Qiita記事：
https://qiita.com/itok_msi/items/ad95425b6773985ef959
Github：
https://github.com/nn116003/self-attention-classification/blob/master/view_attn.py

また、この実装は、以下の本より発見しました。

つくりながら学ぶ！PyTorchによる発展ディープラーニング
https://www.amazon.co.jp/dp/B07VPDVNKW/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

# attention風の可視化

オリジナルを参考に、私のほうで多少、関数に修正を加えています。

```python

def highlight(word, attn):
    "Attentionの値が大きいと文字の背景が濃い赤になるhtmlを出力させる関数"

    html_color = '#%02X%02X%02X' % (
        255, int(255*(1 - attn)), int(255*(1 - attn)))
    return '<span style="background-color: {}"> {}</span>'.format(html_color, word)

def mk_html(words, attns):
    html = ""
    for word, attn in zip(words, attns):
        html += ' ' + highlight(word,attn)
    return html + "<br><br>"
```

mk_htmlの関数に、単語列とスコア列を入力すると、attention風の可視化結果が出力されます。
今回は、サンプルデータをルールベースで作成します。

```python

from janome.tokenizer import Tokenizer

t = Tokenizer()

# 対象文章
sentence = "すもももももももものうち"

# ルールベースでのスコア計算
import random 

words = []
attns = []

for token in t.tokenize(sentence):
    words.append(token.surface)
    if token.part_of_speech.startswith('名詞'):
        attns.append(0.6 + 0.2 * random.random())  # 0～1。1に近いほど赤くなる
    else:
        attns.append(0.2 + 0.2 * random.random())  # 0～1。1に近いほど赤くなる
        
print(words)
print(attns)

```
出力：
['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']
[0.7397653917795854, 0.38089028798835384, 0.7423692670794249, 0.27461082771113776, 0.6142608833129594, 0.21088886758561579, 0.7646013231487092]

---

この結果を用いて、attention風に、テキスト解析結果を可視化します。

```python
from IPython.display import HTML
display(HTML(mk_html(words, attns)))
```

出力：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/3f35519e-aeb4-3ebc-7ad8-5203af1c8821.png)

こんな感じの結果が出力されます。

テキストの試解析結果の可視化では、WordCloudなどを用いていましたが、
attention風の可視化も、注目すべき単語が分かりやすく、個人的には一押しです。

通常、transformerや、BERTなどで用いられる可視化表現ですが、単語列とスコア列さえ作成できれば適用できるので、かなり応用範囲は広いと感じました。

皆様も是非試してみてください。
配列（リスト）を文字列に変換する方法、どれがが好き？


配列をコンマ区切りで連結した文字列に変換するいくつかの方法。

## 配列に対してメソッドを呼び出す
### JavaScript

```javascript
> ['a','b','c'].join(',')
'a,b,c'
```

### Ruby

```ruby
> ['a','b','c'].join(',')
=> "a,b,c"
```

## 文字列に対してメソッドを呼び出す
### Python

```python
>>> ",".join(['a','b','c'])
'a,b,c'
```

## その他
### Java

```java
List<String> list = Arrays.asList("a","b","c");
String result = String.join(",", list);
```
自力One-Hotエンコーディング

某所の【練習問題】Jリーグの観客動員数予測を試してみていたのですが、対戦相手のデータをOne-Hotエンコーディングしようとした時、訓練データにあって検証用データにないチームがありました。それだと便利な関数一発でのOne-Hotエンコーディングではカラム数が違って上手くいかず…
なので自力でOne-Hotエンコーディングしようしたのですが割と苦戦してw
もっといい方法があるかも知れませんが、ひとまずこの力尽く技は割と汎用性有りそうですし折角成功したのでメモも兼ねて。

```
import numpy as np
import pandas as pd

df1 = pd.read_csv('train.csv') #CSVをDataFrame化
df2 = pd.read_csv('train_add.csv') #CSVをDataFrame化
orgdata = pd.concat([df1,df2]) #CSVデータのDataFrameを結合
orgdata.reset_index(inplace=True) #インデックス振り直し(これで少しハマった)
orgdata.drop(['index'],axis=1,inplace=True) #「index」というカラムで前のインデックス値が残るので落とす

temp = orgdata['away'] #対象データとして今はこれだけで

tmp = orgdata['away'].unique() #One-Hotエンコーディングを施したい列の値一覧、つまりユニークな値一覧を変数に作成

awaylist = pd.DataFrame(tmp,columns={'list'}) #カラム名を「list」とし、値一覧をDataFrame化


for r in range(len(temp)): #列数分回す
    name = 'away_oh_' + str(awaylist[awaylist.list==temp['away'][r]].index[0]) #値一覧のインデックス値を使ってカラム名を作成
    if not name in temp.columns: #対象DataFrameに対して当該カラムの存在確認
        temp[name]=0 #無ければ作成しゼロで初期化
    temp[name][r] = 1 #目的のカラムののデータ行に1を立てる。
```

ただこのままだと結局訓練データ、検証データそれぞれに存在する値(ここではチーム名)のカラムしか作成されないので結局合わないですね。
実際にやるときの前処理としては先にユニークな値一覧(ここではawaylist)に存在する値分のカラムを訓練データと検証データ双方に作る必要がありますね。
Swiftのreturnが要らなくなってる？

なんかSwiftの使用がいつの間に変わってたので情報共有
`func`や`get`でも1行であれば`return`が要らなくなってる。

## 以前
```swift

// 昔からこれはOKだった
let hello:() -> String = {
    "Hello"
}


func hello() -> String {
    return "Hello" // 関数ではreturn必須だった
}

var value:Int {
    return 10 + 10 // getterでも必須だった
}

var _hiddenValue = 0
var value:Int { // getterでも必須だった
    get {return _hiddenValue}
    set {_hiddenValue = newValue}
}

```

## 今回

いつの間にか関数などのブロックの動きがクロージャと同じになってました。

```swift
let hello:() -> String = {
    "Hello"
}


func hello() -> String {
   "Hello"
}

var value:Int {
   10 + 10
}

var _hiddenValue = 0
var value:Int {
    get {_hiddenValue}
    set {_hiddenValue = newValue}
}

```

特に`getter`なんかはいつも`return`を書く必要性に疑問を感じていたので嬉しいです。

いつからこうなったんだろう...?
PLCとRaspberryPi間をC言語でソケット通信　MCプロトコル編2

# 前回の課題
[PLCとRaspberryPi間をC言語でソケット通信　MCプロトコル編](https://qiita.com/kiki0817/items/343ee28a7cf73a14ebca#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)で紹介したプログラムを改良します．

# sprintfが便利

request関数部分を以下に置き換えてください．

```c:word_read
int word_read(char *buffer,unsigned char reg,int start_num,int num) {

    char sub_h[]="5000";
    char net_num[]="00";
    char pc_num[]="FF";
    char unit_io[]="03FF";
    char unit_ch[]="00";
    char nlen[]="0018";
    char cputimer[]="0020";
    char command[]="0401";
    char subcommand[]="0000"; 
    sprintf(buffer,"%s%s%s%s%s%s%s%s%s%c*%06d%04d",sub_h,net_num,pc_num,unit_io,unit_ch,nlen,cputimer,command,subcommand,reg,start_num,num);
    return strlen(buffer);
}

```

例えばD1から5つ分の値を受け取りたいときはこのように指定します．

```c
word_read(send_buffer,'D',1,5);//(伝文配列,読み取りたいレジスタ,開始場所,個数)
```

# 実行結果

![関数か.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333756/93703716-6fa4-b04e-b0e3-5d5fb8f7733a.png)

日付の年以下の値も返ってきました．

このプログラムは1回読み取れば終了ですが、無限ループとして常時監視したり(できれば割り込みの方がよい)GPIOを使ったりとまだまだ改善の余地はあると思います。


# おまけ

弊社のご紹介になります。
生産設備向けのPLC､PCソフトの設計･開発を行っております｡
未経験からの採用もしております。
弊社メンバーは学習した内容を、日々Qiitaの記事にアウトプットしております。
弊社にご興味のある方、まずはLINEで気軽に問い合わせしてみてください！
ご応募お待ちしておりますー！

https://lin.ee/PEI7SJf

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333756/6c44e226-e65f-fdc9-a8cf-54ac0bec504c.png)