Quantcast
Channel: プログラム の個人的なメモ
Viewing all 860 articles
Browse latest View live

【Raspberry PI】ラズパイ に関する音量に関するあれこれ


【MySQL】 MySQLのインデックスあれこれ ~ MySQL’s index ~

$
0
0

■ インデックス種類

[1] インデックス
[2] ユニークインデックス
[3] 複合インデックス
[4] 部分インデックス ... 何バイト目までをインデックス対象とするかを指定。最大「255」まで指定。

■ インデックス作成

[A]はテーブル作成時にインデックス作成。[B]-[C]はテーブル作成後にインデックス追加。
[A] CREATE TABLE テーブル名(カラム名1 型1,カラム名2 型2, ... INDEX(カラム名1);
[B] CREATE INDEX インデックス名 ON テーブル名(カラム名1, カラム名2, ...);
[C] ALTER TABLE テーブル名 ADD INDEX(カラム名);

サンプル

[A] CREATE TABLE テーブル名(カラム名1 型1,カラム名2 型2, ... INDEX(カラム名1);
CREATE TABLE `employee` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `employee_no` VARCHAR(10) NOT NULL,
  `first_name` VARCHAR(50) NULL DEFAULT NULL,
  `family_name` VARCHAR(50) NULL DEFAULT NULL,
  `sex` CHAR(1) NULL DEFAULT NULL,
  `birth_date` DATE NOT NULL,
  `position_type` CHAR(1) NOT NULL,
  `remarks` VARCHAR(200) NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX(`birth_date`) -- ★
)
COMMENT='従業員'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
[B] CREATE INDEX インデックス名 ON テーブル名(カラム名1, カラム名2, ...);
CREATE INDEX `position_type_INDEX` ON `employee`(`position_type`);

-- ★複合インデックス★
CREATE INDEX `full_name_INDEX` ON `employee`(`first_name`, `family_name`);
[C] ALTER TABLE テーブル名 ADD INDEX(カラム名);
-- ★ユニークインデックス★
ALTER TABLE `employee` ADD UNIQUE INDEX(`employee_no`);

-- ★部分インデックス★(指定したカラムの20バイト目までをインデックス対象とする)
ALTER TABLE `employee` ADD INDEX(`remarks`(20));

■ インデックス削除

[a] DROP INDEX インデックス名 ON テーブル名;

サンプル

-- [a] DROP INDEX インデックス名 ON テーブル名;
DROP INDEX `birth_date_INDEX` ON `employee`;

■ インデックス情報表示

[i]  SHOW INDEX FROM [データベース名.]テーブル名;
[ii] SHOW INDEX FROM テーブル名 FROM データベース名;

サンプル

-- [i] SHOW INDEX FROM [データベース名.]テーブル名;
SHOW INDEX FROM employee;

-- [ii] SHOW INDEX FROM テーブル名 FROM データベース名;
SHOW INDEX FROM employee FROM sampledb;

■ インデックスが使用しているか確認

 * EXPLAINステートメントを使用する

EXPLAINステートメント

 * SQLの実行計画に関する情報を取得するためのステートメント
 * 見方は、以下のサイトを参照のこと。
https://qiita.com/joji/items/35ba09cf2bf2fecb2269

サンプル

EXPLAIN SELECT * FROM employee AS e
 WHERE e.birth_date BETWEEN '1980-01-01' AND '1989-12-31';


関連記事

【SQL】インデックス

https://blogs.yahoo.co.jp/dk521123/11921582.html

【SQL Server】インデックス構造 ~ SQL Server's index ~

https://blogs.yahoo.co.jp/dk521123/29346513.html

【Raspberry PI】音声認識 ~ Julius / 文法ファイル作成編 ~ [2]

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37449064.html
の続き。

 今回は、音声認識の精度を上げるために、
音声認識キットを使って、ルールベースの認識を行う。

■ 全体の流れ

yomiファイル == 変換(yomi2voca.pl) ==> vocaファイル
                                         |                             dfaファイル
                                         | == コンパイル(mkdfa.pl) ==> term ファイル
                                         |                             dict ファイル
                                       grammar ファイル

■ 作成手順

【1】読みファイル作成 (yomi ファイル)
【2】読みファイルを語彙ファイル (voca ファイル)に変換
【3】文法ファイル作成(grammar ファイル)
【4】コンパイル

【1】 読みファイル作成

sample.yomi
ねぇ     ねぇ
ハロー   はろー
ラズパイ らずぱい

【2】読みファイルを語彙ファイルに変換

読みファイルから語彙ファイルに変換するyomi2voca.pl は EUC-JP しか認識しないので、iconvで変化
iconv -f utf8 -t eucjp ~/sample.yomi | yomi2voca.pl | iconv -f eucjp -t utf8 | ~/sample.voca

【3】文法ファイル作成

 * 構文制約を行うための grammar ファイルを作成
sample.grammar
S      : NS_B CALL NAME NS_E

【4】コンパイル



関連記事

【Raspberry PI】音声認識 ~ Julius / 初期設定編 ~ [1]

https://blogs.yahoo.co.jp/dk521123/37449064.html

【Java】DB Connection Pool ~ HikariCP / 複数DB編 ~

$
0
0
まだ未完成。。。ソースも滅茶苦茶。。。

■ サンプル

サンプルデータ

-- DB
CREATE DATABASE sampledb01;
CREATE DATABASE sampledb02;
CREATE DATABASE sampledb03;

-- Table
CREATE TABLE sampledb01.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`));
CREATE TABLE sampledb02.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`));
CREATE TABLE sampledb03.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`));

-- Sample Data
INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Mike', '2018-01-01');
INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Tom', '2018-01-02');
INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Kevin', '2018-01-03');

INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Kim', '2018-02-01');
INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Ken', '2018-02-02');
INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Chan', '2018-02-03');

INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Ichiro', '2018-03-01');
INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Giro', '2018-03-02');
INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Taro', '2018-03-03');
INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Saburo', '2018-03-04');

サンプル

MultiDataSource.java
import java.io.Closeable;

import com.zaxxer.hikari.HikariDataSource;

public class MultiDataSource implements Closeable {
  private HikariDataSource dataSource;

  public MultiDataSource(String dbUrl) {
    // 接続
    this.dataSource = new HikariDataSource();
  }

  public void setDbDataSource(HikariDataSource dataSource) {
    this.dataSource.setDataSource(dataSource);
  }
  
  @Override
  public void close() {
    if (this.dataSource != null) {
      this.dataSource.close();
    }
  }

  public HikariDataSource getDataSource() {
    return this.dataSource;
  }
}
DbDataSourceFactory.java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class DbDataSourceFactory {
  public static HikariDataSource createDbConfig(String dbUrl) {
    HikariConfig config = new HikariConfig();

    // MySQL用ドライバを設定
    config.setDriverClassName("com.mysql.jdbc.Driver");

    // URL指定
    config.setJdbcUrl(dbUrl);
    
    // ユーザ名、パスワード指定
    config.addDataSourceProperty("user", "root");
    config.addDataSourceProperty("password", "password");

    // キャッシュ系の設定(任意)
    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    // サーバサイドプリペアードステートメントを使用する(任意)
    config.addDataSourceProperty("useServerPrepStmts", "true");

    // 接続をテストするためのクエリ
    config.setConnectionInitSql("SELECT 1");
    
    return new HikariDataSource(config);
  }
}
MaltiDbDemo.java
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.zaxxer.hikari.HikariDataSource;

public class MaltiDbDemo {

  public static void main(String[] args) {
    try (MultiDataSource dataSource = new MultiDataSource("jdbc:mysql://localhost:3306/sampledb01?useSSL=false");) {

      String[] dbUrls = new String[] { "jdbc:mysql://localhost:3306/sampledb01?useSSL=false",
          "jdbc:mysql://localhost:3306/sampledb02?useSSL=false",
          "jdbc:mysql://localhost:3306/sampledb03?useSSL=false" };

      for (String dbUrl : dbUrls) {
        System.out.println("DB Url : " + dbUrl);
        HikariDataSource dbDataSource = DbDataSourceFactory.createDbConfig(dbUrl);
        dataSource.setDbDataSource(dbDataSource);
        try (Connection connection = dataSource.getDataSource().getConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("select * from person");) {
          while (resultSet.next()) {
            System.out.println("Id:" + resultSet.getString("id") + " Name:" + resultSet.getString("name")
                + resultSet.getString("birthdate"));
          }
          System.out.println("***************");
        } catch (SQLException ex) {
          ex.printStackTrace();
        }
      }
    }
  }
}
出力結果
DB Url : jdbc:mysql://localhost:3306/sampledb01?useSSL=false
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-1 - Driver does not support get/set network timeout for connections. (com.mysql.jdbc.JDBC4Connection.getNetworkTimeout()I)
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Starting...
[main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-2 - Driver does not support get/set network timeout for connections. (com.mysql.jdbc.JDBC4Connection.getNetworkTimeout()I)
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Start completed.
Id:1 Name:Mike2018-01-01
Id:2 Name:Tom2018-01-02
Id:3 Name:Kevin2018-01-03
***************
DB Url : jdbc:mysql://localhost:3306/sampledb02?useSSL=false
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Starting...
[main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-3 - Driver does not support get/set network timeout for connections. (null)
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Start completed.
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown initiated...
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown completed.
Exception in thread "main" java.lang.IllegalStateException: The configuration of the pool is sealed once started.  Use HikariConfigMXBean for runtime changes.
	at com.zaxxer.hikari.HikariConfig.setDataSource(HikariConfig.java:426)
	at com.sample.db.dbpool.MultiDataSource.setDbDataSource(MultiDataSource.java:16)
	at com.sample.db.dbpool.MaltiDbDemo.main(MaltiDbDemo.java:22)

関連記事

【Java】DB Connection Pool ~ HikariCP / 導入編 ~

https://blogs.yahoo.co.jp/dk521123/37397210.html

【Raspberry PI】Julius + Open JTalkで非ネット環境でのなんちゃってAIスピーカー

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37449064.html
https://blogs.yahoo.co.jp/dk521123/37451114.html
の続き。
更に、以下の関連記事で行ったOpen JTalkを組み合わせて
非ネット環境でのなんちゃってAIスピーカー的なことをやってみる。
https://blogs.yahoo.co.jp/dk521123/37367963.html

■ 文法ファイル作成

 * 環境作成や作り方は、以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37451114.html

hello_raspi.yomi

% CALL
ねぇ     ねぇ
ハロー   はろー
% NAME
ラズパイ らずぱい
% ASK
何時     なんじ
何日     なんにち
% NS_B
[s]     silB
% NS_E
[s]     silE

hello_raspi.grammar

S      : NS_B CALL NAME NS_E
S      : NS_B ASK NS_E

■ サンプル

openJTalk.py

 * 以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37367963.html

start-julius.sh

#!/bin/sh

# -module : juliusをモジュールモードで実行
julius -C ~/julius-4.4.2/julius-kits/grammar-kit-4.3.1/hmm_mono.jconf -input mic -gram hello_raspi -module > /dev/null &

#プロセスIDを出力
echo $!

sleep 2

hello_raspi.py

# coding:utf-8
#! /usr/bin/env phython3

import os
import socket
import subprocess
import time
import datetime
import openJTalk 

julius_host = '127.0.0.1'
julius_port = 10500

has_recongized = False

def process_query(sentence):
   global has_recongized

   if has_recongized == False:
      if sentence in ["ねぇラズパイ", "ハローラズパイ"]:
         print ("Tell me, Ras-pi")
         openJTalk.openJTalk("御用でしょうか?")
         has_recongized = True
   else:
      if sentence in ["ねぇラズパイ", "ハローラズパイ"]:
         print ("Hey Ras-pi")
         openJTalk.openJTalk("はい")
      elif sentence == "何時":
         print ("What time?")
         openJTalk.openJTalk(datetime.datetime.strptime(datetime.datetime.today(), '%H時%M分') + "です")
      elif sentence == "何日":
         print ("What date?")
         openJTalk.openJTalk(datetime.datetime.strptime(datetime.datetime.today(), '%Y年%m月%d日') + "です")
      else:
         print ("do not understand...")
         openJTalk.openJTalk("すみません。良く分かりません。")

# Main関数
def main():
    # julius起動スクリプトを実行
    process = subprocess.Popen(["./start-julius.sh"], stdout=subprocess.PIPE, shell=True)
    # juliusのプロセスIDを取得
    pid = str(process.stdout.read().decode('utf-8'))
    # 3秒間スリープ
    time.sleep(3)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # サーバモードで起動したjuliusに接続
    client.connect((julius_host, julius_port))

    try:
        data = ''
        sentence =''

        while 1:
            if '</RECOGOUT>\n.' in data:
               word = ""
               for line in data.split('\n'):
                 index = line.find('WORD="')
                 if index != -1:
                     line = line[index + 6:line.find('"', index + 6)]
                     word += str(line)
                 if word == '[s]':
                    sentence += word

               print ('"' + sentence + '"')
               process_query(sentence)
               sentence =''
               data = ''
               print ("<<<please speak>>>")
            else:
               data += str(client.recv(1024).decode('utf-8'))
    except KeyboardInterrupt:
        # 起動スクリプトのプロセスを終了
        process.kill()
        subprocess.call(["kill " + pid], shell=True)# juliusのプロセスを終了する。
        client.close()

if __name__ == "__main__":
    main()


関連記事

【Raspberry PI】音声認識 ~ Julius / 初期設定編 ~ [1]

https://blogs.yahoo.co.jp/dk521123/37449064.html

【Raspberry PI】音声認識 ~ Julius / 文法ファイル作成編 ~ [2]

https://blogs.yahoo.co.jp/dk521123/37451114.html

【Raspberry PI】音声合成 ~ Open JTalk ~

https://blogs.yahoo.co.jp/dk521123/37367963.html

【Java】JDBC URLをJavaでパースする

$
0
0

■ はじめに

JDBC URL(例えば「jdbc:mysql://localhost:3306/sampledb」)を、
ホスト、ポート、DB名などのようにパースしたい。

はじめ、以下の関連記事にある正規表現でパースすることを考えた。
https://blogs.yahoo.co.jp/dk521123/36604177.html
しかし、以下のサイトの回答をみたところ、もっと楽に実装できそうなので、
実装を試みる
https://stackoverflow.com/questions/9287052/how-to-parse-a-jdbc-url-to-get-hostname-port-etc?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

アイディア

import java.net.URI;

public class Main {
  public static void main(String[] args) {
    try {
      String url = "jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8";
      String cleanURI = url.substring(5); // 「jdbc:」を差っ引く

      URI uri = URI.create(cleanURI);
      System.out.println("Scheme : " + uri.getScheme());
      System.out.println("Host : " + uri.getHost());
      System.out.println("Port : " + uri.getPort());
      System.out.println("Authority : " + uri.getAuthority());
      System.out.println("RawAuthority : " + uri.getRawAuthority());
      System.out.println("Fragment : " + uri.getFragment());
      System.out.println("RawFragment : " + uri.getRawFragment());
      System.out.println("Path : " + uri.getPath());
      System.out.println("RawPath : " + uri.getRawPath());
      System.out.println("Query : " + uri.getQuery());
      System.out.println("RawQuery : " + uri.getRawQuery());
      System.out.println("SchemeSpecificPart : " + uri.getSchemeSpecificPart());
      System.out.println("RawSchemeSpecificPart : " + uri.getRawSchemeSpecificPart());
      System.out.println("UserInfo : " + uri.getUserInfo());
      System.out.println("RawUserInfo : " + uri.getRawUserInfo());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
出力結果
Scheme : mysql
Host : localhost
Port : 3306
Authority : localhost:3306
RawAuthority : localhost:3306
Fragment : null
RawFragment : null
Path : /sampledb01
RawPath : /sampledb01
Query : useSSL=false&characterEncoding=UTF-8
RawQuery : useSSL=false&characterEncoding=UTF-8
SchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
RawSchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
UserInfo : null
RawUserInfo : null

■ サンプル

 * MySQL用のパースを作成
 * その他のDBは、自分でカスタマイズする必要がありそう
http://www.codejava.net/java-se/jdbc/jdbc-database-connection-url-for-common-databases

JdbcUrl.java

import java.net.URI;
import java.text.MessageFormat;

public class JdbcUrl {
  private static int DEFAULT_PORT = 3306;

  private String db;
  private String dbHost;
  private int dbPort;
  private String dbName;
  private String dbQuery;

  private JdbcUrl(String db, String dbHost, int dbPort, String dbName, String dbQuery) {
    this.db = db;
    this.dbHost = dbHost;
    this.dbPort = dbPort;
    this.dbName = dbName;
    this.dbQuery = dbQuery;
  }

  public static JdbcUrl parse(String url) {
    if (url == null) {
      throw new IllegalArgumentException("null");
    }
    String cleanUri = url.substring(5);
    URI uri = URI.create(cleanUri);
    return new JdbcUrl(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath().replaceAll("/", ""),
        uri.getQuery());
  }

  public String getDb() {
    return this.db;
  }

  public String getDbHost() {
    return this.dbHost;
  }

  public int getDbPort() {
    if (this.dbPort == -1) {
      return DEFAULT_PORT;
    }
    return this.dbPort;
  }

  public String getDbPortString() {
    return String.valueOf(this.getDbPort());
  }

  public String getDbName() {
    return this.dbName;
  }

  public String getDbQuery() {
    return this.dbQuery;
  }

  @Override
  public String toString() {
    if (this.getDbQuery() == null) {
      return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}", this.getDb(), this.getDbHost(), this.getDbPortString(),
          this.getDbName());
    } else {
      return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}?{4}", this.getDb(), this.getDbHost(), this.getDbPortString(),
          this.getDbName(), this.getDbQuery());
    }
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    try {
      JdbcUrl jdbcUrl1 = JdbcUrl.parse("jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8");
      print(jdbcUrl1);
      JdbcUrl jdbcUrl2 = JdbcUrl.parse("jdbc:mysql://127.0.0.1:13306/sampledb02");
      print(jdbcUrl2);
      JdbcUrl jdbcUrl3 = JdbcUrl.parse("jdbc:mysql://sample.co.jp/sampledb03");
      print(jdbcUrl3);
      
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  
  private static void print(JdbcUrl jdbcUrl) {
    System.out.println(jdbcUrl.getDbHost());
    System.out.println(jdbcUrl.getDbPort());
    System.out.println(jdbcUrl.getDbName());
    System.out.println(jdbcUrl.getDbQuery());
    System.out.println(jdbcUrl.toString());
    System.out.println("**************************");
  }
}
出力結果
localhost
3306
sampledb01
useSSL=false&characterEncoding=UTF-8
jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
**************************
127.0.0.1
13306
sampledb02
null
jdbc:mysql://127.0.0.1:13306/sampledb02
**************************
sample.co.jp
3306
sampledb03
null
jdbc:mysql://sample.co.jp:3306/sampledb03
**************************

関連記事

【Java】正規表現 [4] 文字列の抽出 ~Matcher.group() ~

https://blogs.yahoo.co.jp/dk521123/36604177.html

【トラブル】 Julius でのトラブルシューティング

$
0
0

■ はじめに

 * 以下の関連記事などで発生した時のトラブルシューティング
https://blogs.yahoo.co.jp/dk521123/37454369.html

■ エラー「Error: failed to bind socket」が表示される

 * python実行後、以下「エラー内容」が表示される

エラー内容

Error: failed to bind socket
failed to begin input stream

原因

 * ポート「10500」を掴んでいるプロセスがいる
解決案
# ポート10500のPIDを探す
sudo netstat -anp | grep 10500
tcp        0      0 0.0.0.0:10500           0.0.0.0:*               LISTEN      1821/julius 

# kill -9 【PID】でプロセスをキルする
kill -9 1821

■ エラー「UnicodeEncodeError: 'ascii' codec can't encode characters」が表示される

 * str(client.recv(1024).decode('utf-8'))で読み取り時に、以下のエラー内容が表示される

エラー内容

Traceback (most recent call last):
  File "hello_raspi.py", line 99, in <module>
    main()
  File "hello_raspi.py", line 89, in main
    data += str(client.recv(1024).decode('utf-8'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 360-362: ordinal not in range(128)

解決案

 * Pythonの文字コードを utf-8 に設定する。
  => sitecustomize.py に  utf-8 を設定
確認方法
$ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170124] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'ascii' << これを utf-8 に変更する必要がある
>>> exit();

具体的に行ったこと

# 念のため、バックアップ
sudo cp /usr/lib/python2.7/sitecustomize.py /usr/lib/python2.7/sitecustomize.py.orig

sudo vi /usr/lib/python2.7/sitecustomize.py
-=[全面的に書き換え]-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import sys
sys.setdefaultencoding('utf-8')
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

$ python
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'  << utf-8 に変更されたことを確認
>>> exit();

参考文献

http://kenzo0107.hatenablog.com/entry/2016/02/16/110854
http://d.hatena.ne.jp/omiyan/20110105/p1

関連記事

【Raspberry PI】Julius + Open JTalkで非ネット環境でのなんちゃってAIスピーカー

https://blogs.yahoo.co.jp/dk521123/37454369.html

【Python】文字列

$
0
0

■ upper

 * 大文字にする

サンプル

city="Tokyo"
big_city=city.upper()
print(big_city)

■ format

 * 可変部を{}にする

サンプル

# 「日本の首都は東京です」と出力
print("{}の首都は{}です".format("日本", "東京"))

関連記事

Python ~ 基本文法編 ~

https://blogs.yahoo.co.jp/dk521123/37404174.html

【Python】 NumPy ~ 数値計算ライブラリ ~

$
0
0

■ NumPy

ナムパイ
 * Pythonでベクトルや行列計算を高速に行うための数値計算ライブラリ

■ サンプル

# NumPyをimport()
import numpy as np

# np.array(リスト)で配列を高速に扱うためのndarrayクラスを生成
np_numbers = np.array([0,1,2,3,4,5,6,7])

print(np_numbers)

# <class 'numpy.ndarray'>が表示
print(type(np_numbers))

# arr[start:end]で、startから(end-1)までのリストが作成(変数arrの要素の内3, 4, 5が表示)
print(arr[3:6])

【MySQL】 LIMIT ~ 出力する行数を制限する ~

$
0
0

■ LIMIT

 * 出力する行数を制限する
 * PostgreSQLでも使えるみたい

■ 構文

SELECT [項目1] (, ...)
FROM [テーブル名]
LIMIT ([開始位置(行数],) 取得する行数

■ サンプル

SELECT * FROM user LIMIT 5
出力結果
"1"	"1"	"Kim"	"1983-12-11"
"2"	"1"	"Mike"	"2018-02-02"
"3"	"1"	"Sam"	"1922-12-30"
"4"	"1"	"Smith"	"2006-07-14"
"5"	"1"	"Nancy"	"2003-08-19"

テストデータ

-- テーブル作成
CREATE TABLE IF NOT EXISTS `user` (
  `id` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `user_category` INT(11) DEFAULT 1,
  `name` VARCHAR(20) NULL DEFAULT NULL,
  `birthdate` DATE NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

-- テストデータ(REPLACE構文:ユニーク値が重複した場合、古いレコードを削除し、新しいレコードを挿入)
REPLACE INTO `user` (`id`, `user_category`, `name`, `birthdate`) VALUES
	(1, 1, 'Kim', '1983-12-11'),
	(2, 1, 'Mike', '2018-02-02'),
	(3, 1, 'Sam', '1922-12-30'),
	(4, 1, 'Smith', '2006-07-14'),
	(5, 1, 'Nancy', '2003-08-19'),
	(6, 1, 'Kachy', '2001-12-01'),
	(7, 2, 'Ken', '1936-05-10'),
	(8, 2, 'Coco', '1979-04-02'),
	(9, 2, 'Tom', '1999-03-17'),
	(10, 2, 'Son', '2000-09-22'),
	(11, 2, 'Tommy', '1929-05-02'),
	(12, 3, 'Carry', '1892-11-23'),
	(13, 3, 'Chan', '1977-11-03');

■ LIMITあれこれ

行数を制限したいが総行数を知りたい

 * 「SQL_CALC_FOUND_ROWS」と「FOUND_ROWS()」を使う
公式サイト
https://dev.mysql.com/doc/refman/5.6/ja/information-functions.html#function_found-rows
サンプル
SELECT SQL_CALC_FOUND_ROWS * FROM user LIMIT 5;
5行データが出力(略)

SELECT FOUND_ROWS();
13

【Java】Java で 複数 INSERT を実行する

$
0
0

■ はじめに

 * Java で 複数 INSERT を実行することを考える

  => 色々な方法があるが、パフォーマンスがよく、実装しやすいものがいい

■ 実行環境

 * OS : Windows10
 * DB : MySQL5.7

■ テストデータ

CREATE TABLE `person` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(50) NULL DEFAULT NULL,
  `sex` CHAR(1) NULL DEFAULT 'f',
  `birth_date` DATE NOT NULL,
  `createdate` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
  `updatedate` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX(`name`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

■ サンプル

 * PreparedStatement.addBatch() / executeBatch() を使う
  => PreparedStatement.addBatch() で貯めて、PreparedStatement.executeBatch()で実行する
https://docs.oracle.com/javase/jp/8/docs/api/java/sql/PreparedStatement.html

InsertDemo.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class InsertDemo {

  private final static String URL = "jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8";
  private final static String USERNAME = "root";
  private final static String PASSWORD = "password";
  private final static String SQL = "INSERT INTO person(name, sex, birth_date) VALUES (?, ?, ?);";

  public static void main(String[] args) {
    String[][] samplePeople = { { "Mike", "m", "2001-01-09" }, { "Tom", "m", "1982-11-29" },
        { "Smith", "m", "1976-03-14" }, { "Ken", "m", "1982-11-29" }, { "Naomi", "f", "1962-06-11" },
        { "Sam", "m", "1982-01-30" }, { "Amy", "f", "1933-09-23" }, { "Cathy", "f", "1921-07-12" },
        { "Bob", "m", "1956-12-29" }, { "Tommy", "m", "1999-02-21" }, };

    System.out.println("Start");
    long start = System.currentTimeMillis();
    try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);) {
      try (PreparedStatement preparedStatement = connection.prepareStatement(SQL);) {
        connection.setAutoCommit(false);

        for (int i = 0; i < samplePeople.length; i++) {
          preparedStatement.setString(1, samplePeople[i][0]);
          preparedStatement.setString(2, samplePeople[i][1]);
          preparedStatement.setString(3, samplePeople[i][2]);
          preparedStatement.addBatch();
          System.out.println(preparedStatement.toString());
        }
        int[] result = preparedStatement.executeBatch();
        System.out.println("Count : " + result.length);

        connection.commit();
      } catch (SQLException ex) {
        ex.printStackTrace();
        connection.rollback();
      }
    } catch (SQLException ex) {
      ex.printStackTrace();
    } finally {
      long end = System.currentTimeMillis();
      System.out.println("[Done]" + (end - start));
    }
  }
}
出力結果
Start
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Mike', 'm', '2001-01-09');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Tom', 'm', '1982-11-29');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Smith', 'm', '1976-03-14');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Ken', 'm', '1982-11-29');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Naomi', 'f', '1962-06-11');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Sam', 'm', '1982-01-30');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Amy', 'f', '1933-09-23');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Cathy', 'f', '1921-07-12');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Bob', 'm', '1956-12-29');
com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Tommy', 'm', '1999-02-21');
Count : 10
[Done]431

【JUnit】 JUnit で環境変数を変更するテストを行うには...

$
0
0

■ JUnit で環境変数を変更するテストを行うには...

 * 以下の「System Rules」を使うと実現可能。
http://stefanbirkner.github.io/system-rules/

■ 設定

http://stefanbirkner.github.io/system-rules/download.html
に記載。今回は、Gradleを使う。

build.gradle

dependencies {
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
    
    // System Rules
    testCompile 'com.github.stefanbirkner:system-rules:1.17.0'
}

■ サンプル

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.EnvironmentVariables;

public class SampleTest {
  @Rule
  public final EnvironmentVariables environmentVariables = new EnvironmentVariables();

  @Test
  public void test() {
    environmentVariables.set("ENV_KEY", "dummy01");

    assertEquals("dummy01", System.getenv("ENV_KEY"));
  }
}

■ 使用上の注意

 * 環境変数を設定したら、別のテストメソッドにも反映される(以下の「サンプル」参照)

サンプル

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.contrib.java.lang.system.EnvironmentVariables;

public class SampleTest {

  @Test
  public void test1() {
    EnvironmentVariables environmentVariables = new EnvironmentVariables();
    environmentVariables.set("ENV_KEY", "dummy01");

    assertEquals("dummy01", System.getenv("ENV_KEY"));
  }

  @Test
  public void test2() {
    assertNull(System.getenv("ENV_KEY")); // ★エラー★(test1()で設定した値「dummy01」が返ってくる)
  }
}

■ 補足 : PowerMockito の使用について

 * PowerMockito で行うことができることもネットでは書いてあるが、
   エラー「MissingMethodInvocationException」になった

行ったこと

 * 以下の通り。(足りない点があるかもしれないが...)
build.gradle
dependencies {
    // PowerMockito
    testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.3'
    testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.3'
}
JUnitコード
import static org.junit.Assert.*;

import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;

public class SampleTest {

  @Test
  public void test() {
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01");

    assertEquals("dummy01", System.getenv("ENV_KEY"));
  }
}
エラー内容
org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

	at com.sample.db.SampleTest.test(SampleTest.java:13)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
https://stackoverflow.com/questions/8168884/how-to-test-code-dependent-on-environment-variables-using-junit?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
より抜粋
~~~~~
when(System.getenv("FOO_VAR_1")).thenReturn("test-foo-var-1") causes org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. error – Andremoniy Oct 24 '17 at 13:14
~~~~~

同じ現象...


関連記事

【JUnit】 DBにまつわる単体試験 [3] ~ AssertJ / AssertJ-DB ~

https://blogs.yahoo.co.jp/dk521123/36157721.html

【JUnit】【Mail】 Email送信に関する単体試験について ~ SubEthaMail編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/36257589.html
の続き。
今回は、「SubEthaMail」を試す。

■ 設定

 * Gradleを使う

build.gradle

dependencies {
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    // SubEthaMail
    testCompile group: 'org.subethamail', name: 'subethasmtp', version: '3.1.7'

    // JavaMail(以下の「サンプル」を実行したい場合は、以下のコメントを外す)
    //compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.1'
}

■ サンプル

EmailHandlerTest.java

import static org.junit.Assert.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.mail.MessagingException;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;

import com.sample.mails.EmailHandler;

public class SampleTest {
  private static Wiser wiser;
  private final static String HOSTNAME = "localhost";
  private final static Integer PORT = 12500;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    // メールサーバを立てる
    wiser = new Wiser();
    wiser.setPort(PORT);
    wiser.setHostname(HOSTNAME);
    wiser.start();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    // メールサーバを落とす
    wiser.stop();
  }

  @Test
  public void test() throws MessagingException {
    final String expectTo = "to@sample.co.jp";
    final String expectFrom = "from@sample.co.jp";
    final String expectSubject = "タイトルです。";
    final String expectBody = "メール本文です。\\r\\n以上です。";

    EmailHandler target = new EmailHandler();
    target.setHost(HOSTNAME);
    target.setPort(PORT.toString());
    target.setToAddresses(Arrays.asList(expectTo));
    target.setFromAddress(expectFrom);
    target.setMailSubject(expectSubject);
    target.setMailBody(expectBody);
    target.send();

    // メール内容を検査
    List<WiserMessage> messages = wiser.getMessages();
    for (WiserMessage wiserMessage : messages) {
      assertEquals(expectFrom, wiserMessage.getEnvelopeSender());
      assertEquals(expectTo, wiserMessage.getEnvelopeReceiver());
      try {
        assertEquals(expectSubject, wiserMessage.getMimeMessage().getSubject());
      } catch (MessagingException e) {
        fail("題名が取得できない");
      }
      try {
        assertEquals(expectBody, wiserMessage.getMimeMessage().getContent());
      } catch (MessagingException | IOException e) {
        fail("本文が取得できない");
      }
    }
  }
}

EmailHandler.java

https://blogs.yahoo.co.jp/dk521123/36230453.html
を修正(ポート部分)
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class EmailHandler {
  private final static String DEFAULT_TIMEOUT = "10000";
  private final static String DEFAULT_HOST = "localhost";
  private final static String DEFAULT_POST = "25";
  private String fromAddress;
  private List<String> toAddresses;
  private String mailSubject;
  private String mailBody;
  private String host;
  private String port;
  private String timeout;
  private boolean isOnDebugMode;

  /**
   * Default Contractor.
   */
  public EmailHandler() {
    this.fromAddress = null;
    this.toAddresses = new ArrayList<>();
    this.mailSubject = null;
    this.mailBody = null;
    this.host = DEFAULT_HOST;
    this.port = DEFAULT_POST;
    this.timeout = DEFAULT_TIMEOUT;
    this.isOnDebugMode = false;
  }

  public void setFromAddress(String fromAddress) {
    this.fromAddress = fromAddress;
  }

  public void setToAddresses(List<String> toAddresses) {
    this.toAddresses = toAddresses;
  }

  public void addToAddress(String toAddress) {
    this.toAddresses.add(toAddress);
  }

  public void setMailSubject(String mailSubject) {
    this.mailSubject = mailSubject;
  }

  public void setMailBody(String mailBody) {
    this.mailBody = mailBody;
  }

  public void setHost(String host) {
    this.host = host;
  }

  public void setPort(String port) {
    this.port = port;
  }

  public void setOnDebugMode(boolean isOnDebugMode) {
    this.isOnDebugMode = isOnDebugMode;
  }

  public void send() throws MessagingException {
    if (this.toAddresses == null || this.host == null) {
      throw new InvalidParameterException();
    }

    Properties props = new Properties();
    props.put("mail.smtp.host", this.host);
    props.put("mail.smtp.port", this.port);
    props.put("mail.debug", this.isOnDebugMode);
    props.put("mail.smtp.connectiontimeout", this.timeout);
    props.put("mail.smtp.timeout", this.timeout);

    Session session = Session.getInstance(props, null);

    Message mimeMessage = new MimeMessage(session);
    mimeMessage.setFrom(this.toInternetAddress(this.fromAddress));
    InternetAddress[] addresses = this.toInternetAddresses(this.toAddresses);
    mimeMessage.setRecipients(Message.RecipientType.TO, addresses);
    mimeMessage.setSubject(this.mailSubject);
    mimeMessage.setSentDate(new Date());
    mimeMessage.setText(this.mailBody);

    Transport.send(mimeMessage);
  }

  private InternetAddress[] toInternetAddresses(List<String> addresses) throws AddressException {
    InternetAddress[] returnValues = new InternetAddress[addresses.size()];

    int index = 0;
    for (String address : addresses) {
      returnValues[index] = this.toInternetAddress(address);
      index++;
    }

    return returnValues;
  }

  private InternetAddress toInternetAddress(String address) throws AddressException {
    return new InternetAddress(address);
  }

  /**
   * 【使用例】
   * 
   * @param args
   */
  public static void main(String[] args) {
    try {
      EmailHandler email = new EmailHandler();
      email.setFromAddress("sample@yahoo.com");
      email.addToAddress("sample@gmail.com");
      email.setMailSubject("タイトルです。");
      email.setMailBody("メール本文です。\r\n以上です。");
      email.setOnDebugMode(true);
      email.send();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}


関連記事

Email送信に関する単体試験について ~ Dumbster編 ~

https://blogs.yahoo.co.jp/dk521123/36257589.html

【トラブル】【Java】JBDC ドライバのunregister 絡みのトラブル

$
0
0

【1】「SEVERE: A web application registered the JBDC driver...」が表示される

 * Tomcatのログを見たら、Tomcat終了時に以下の「エラー内容」が表示された

エラー内容

SEVERE: A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

発生環境

 * OS : CentOS7
 * Tomcat : Tomcat8.5
 * Java :JDK1.8

解決案

 * システム終了後(※)に、以下の「サンプル」の処理(DriverManager.deregisterDriver())を行う
サンプル
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
    Driver driver = drivers.nextElement();
    try {
        DriverManager.deregisterDriver(driver);
        System.out.println(String.format("deregistering jdbc driver: %s", driver));
    } catch (SQLException ex) {
        System.out.println(String.format("Error deregistering driver %s", driver));
        ex.printStackTrace();
    }

}

※補足:システム終了後について

Tomcatであれば、ServletContextListener.contextDestroyed 内で行う。
Webサービスのシステム終了のイベントについては、以下の関連記事を参照のこと。
JAX-WS / Metro
https://blogs.yahoo.co.jp/dk521123/36238319.html
Axis2
https://blogs.yahoo.co.jp/dk521123/34600183.html

参考文献

https://stackoverflow.com/questions/3320400/to-prevent-a-memory-leak-the-jdbc-driver-has-been-forcibly-unregistered
http://d.hatena.ne.jp/muimy/20100918/1284812424

【2】「SQLException: No suitable driver found for...」が表示される

 * 【1】とは、別のシステムの単体試験時に、以下の「エラー内容」が表示された
 * 単体テストクラスには、3つのテストメソッドがあり、結果は以下の通り。
  + 1つ目は、問題なし
  + 2・3つ目のメソッドは、以下の「エラー内容」
 * ネットにある「JDBCドライバがない」「Class.forName()を呼び出す」「DBのURLの指定が誤っている」は
   調査した結果、問題なかった(仮にこれらが原因の場合、1つのメソッドが問題なかった説明ができない)
 ~~~~~~~
  // ダメだった
  @Before
  public void setUp() throws Exception {
      Class.forName("com.mysql.jdbc.Driver");
  }
 ~~~~~~~

エラー内容

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/dbname

発生環境

 * OS : CentOS7
 * Java :JDK1.8
 * JUnit : JUnit4

原因

 * 【1】の「解決案」のコードを1つ目の最後に呼び出され、
    以降の単体試験に影響してしまっていた。

解決案

 * JUnitの場合、@AfterClassのタイミングで、【1】の「解決案」のコードを呼び出すようにする
 ~~~~~~~
  @AfterClass
  public static void tearDownAfterClass() throws Exception {
     // このタイミングで、【1】の「解決案」のコードを呼び出すようにする
  }
 ~~~~~~~

【Ansible】Ansible ~ 初期構築編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37419935.html
で扱った ansible の続き。

おおよその流れは、以下の通り。

[1] ゲストOS(管理マシン) から ゲストOS(構築サーバ) にssh通信できるようにする
[2] ゲストOS(管理マシン)にansible をインストールする
[3] (Hello World的なこととして)ゲストOS(構築サーバ)にApacheをインストール

■ 構築環境

あくまで練習用の環境
 * 作業OS               : Windows10
 * 仮想環境             : VirtualBox v5.2.8
 * ゲストOS(管理マシン) : CentOS7 (IP : 192.168.56.1)
 * ゲストOS(構築サーバ) : CentOS7 (IP : 192.168.56.2) <= 管理対象

前提条件

 * VirtualBoxおよびゲストOS(CentOS7)のインストールは行っているものとする
  => それぞれの作業自体は、以下の関連記事を参照のこと。
VirtualBox
https://blogs.yahoo.co.jp/dk521123/31186721.html
CentOS7
https://blogs.yahoo.co.jp/dk521123/36252928.html

■ 構成図

  +--------------+ +--------------+
  | 管理マシン   | | 構築サーバ   |
  |  CentOS7     | |  CentOS7     |
  | 192.168.56.1 | | 192.168.56.2 |
  |              | |              |
  |  Ansible     | |    Apache    |
  +--------------+ +--------------+
  +-------------------------------+
  |           VirtualBox          |
  +-------------------------------+
  |           Windows10           |
  +-------------------------------+

ディレクトリ構成

管理マシン
/home/【ユーザ名】
 + helloworld
   + hosts     ... インベントリファイル(管理対象(構築サーバ)のネットワーク情報を定義)
   + main.yml  ... プレイブック(設定内容(ここではApache)を定義)
main.yml の内容
1) yumでlibselinux-pythonのインストール(SELinux対策)
2) yumでApacheのインストール
3) Apache起動と自動起動化
4) ファイアウォールでHTTP/SSLをあける
5) Apacheの起動確認

■ 手順詳細

[1] 管理マシンから構築サーバにssh通信できるようにする

[1-1] VirtualBox のネットワーク設定
[a] 「Oracle VM VirtualBox マネージャー」を立ち上げて、
  「ゲストOS(管理マシン)」を右クリックし、「設定」を選択
[b] 設定画面において、[ネットワーク]-[アダプター2]を選択し、
     以下を設定し、「OK」ボタン押下
 + ネットワークアダプターを有効化:チェック入れる
 + 割り当て:内部ネットワーク
 + 名前:intnet
[1-2] ゲストOS のネットワーク設定
http://anything.hatenadiary.com/entry/2017/08/13/161328
を参考。

[a] 以下のコマンドで、 NetworkManager Text User Interfaceを立ち上げる
~~~~~~
sudo nmtui
~~~~~~

[b] [Edit a connection]-[enp0s8(文字化けしている可能性あり)]を選択
[c] 以下を設定し、<OK>押下。。
 + IPv4 CONFIGURATION : <Manual>
 + Addresses : 192.168.56.【1~255の任意値】/24(ここでは、「192.168.56.1/24」)
[d] <Back>押下。<Quit>押下。
[e] 以下のコマンドで、 NetworkManager Text User Interfaceを再起動
~~~~~~
sudo systemctl restart NetworkManager
~~~~~~
[1-3] 「ゲストOS(構築サーバ)」に対しても、[1-1]~[1-2]を行う
 IPアドレスは、ここでは、「192.168.56.2/24」にする。

[2] 管理マシンにansible をインストール

[2-1] 管理マシンにansible をインストール
sudo yum install epel-release -y

sudo yum install ansible -y

# 確認1:バージョン確認
ansible --version

# 確認2:[WARNING]が2つほどでるが、エラーがでなければOK
ansible localhost -m ping

[3] 構築サーバを設定する

 * [3-1]は必須ではないが、
[3-1] 構築サーバから、以下のコマンドで、ansible用の実行ユーザ作成
# sudo useradd 【任意のユーザ名】で、ansible用の実行ユーザ作成
sudo useradd ansible

# sudo passwd 【任意のユーザ名】で、ansible用の実行ユーザのパスワードを設定
sudo passwd ansible
# パスワードを設定

# 実行ユーザのsudo権限付与(「 #!!ADD!!」を追記)
sudo visudo
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Defaults specification
Defaults:ansible !requiretty #!!ADD!!

root    ALL=(ALL)       ALL
ansible ALL=(ALL)       NOPASSWD:ALL #!!ADD!!
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[3-2] 管理サーバから、以下のコマンドでSSH接続できるか確認する
sudo ssh -l ansible 192.168.56.2

[4] 構築サーバにApacheをインストール

[4-1] インベントリファイル「hosts」を作成する
mkdir -p ~/helloworld
cd ~/helloworld
vi hosts
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[localhost]
192.168.56.12

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_pass=password
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[4-2] プレイブック「main.yml」を作成する
vi main.yml
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- hosts: all
  become: yes
  tasks:
  - name: Install libselinux-python
    yum: name=libselinux-python state=present
  - name: Install Apache
    yum: name=httpd state=latest
  - name: Start Apache
    service: name=httpd state=started enabled=yes
  - name: firewall-cmd allow Apachei(HTTP)
    firewalld: service=http permanent=true state=enabled immediate=true
  - name: firewall-cmd allow Apache(SSL)
    firewalld: service=https permanent=true state=enabled immediate=true
  - name: Check to start Apache
    shell: ps aux | grep httpd
    register: ps_result
    changed_when: false
  - debug: var=ps_result.stdout_lines
    when: ps_result | success
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[4-3] プレイブックを実行
ansible-playbook -i hosts main.yml

[5] 動作確認

[5-1] 構築サーバ内で以下のコマンドを実行する
# Apacheサービスの状態確認
sudo systemctl status httpd

# curlでの確認 (GUIであればブラウザからアクセスでもいい)
curl http://localhost
[5-2] 管理サーバから、以下のコマンドを実行する
# curlでの確認 (GUIであればブラウザからアクセスでもいい)
curl hhttp://192.168.56.12


関連記事

Ansible ~ 基礎知識編 ~

https://blogs.yahoo.co.jp/dk521123/37419935.html

Vagrant ~ 入門編 ~

https://blogs.yahoo.co.jp/dk521123/37431398.html

ssh コマンド / scp コマンド

https://blogs.yahoo.co.jp/dk521123/37291685.html

Apache の設定 ~ CentOS編 ~

https://blogs.yahoo.co.jp/dk521123/36300671.html

【トラブル】PowerMock に関するトラブルシューティング

$
0
0

■ エラー「MissingMethodInvocationException」が表示される

 * テストを実行した際に、以下の「エラー内容」が表示される

エラー内容

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

	at com.sample.SampleTest.test(SampleTest.java:12)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)

JUnitコード

「powermock-module-junit4」「powermock-api-mockito2」を Gradleでダウンロード済
import static org.junit.Assert.*;

import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;

public class SampleTest {
  @Test
  public void test() {
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01");

    assertEquals("dummy01", System.getenv("ENV_KEY"));
  }
}

解決案

 * クラスの頭に「@RunWith」「@PrepareForTest」を追記する
~~~~
@RunWith(PowerMockRunner.class) // ★重要★
@PrepareForTest({System.class}) // ★重要★
public class SampleTest {
   // ...略...
~~~~

詳細のサンプルは、以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37484564.html

関連記事

PowerMock ~ 入門編 ~

https://blogs.yahoo.co.jp/dk521123/37484564.html

【JUnit】【Mock】 PowerMock ~ 入門編 ~

$
0
0

■ 設定

 * Gradleを使う

build.gradle

dependencies {
    // PowerMock
    testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.3'
    testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.3'
}

■ サンプル1:Calendar.getInstance()のモック化

 * Calendar.getInstance()をモック化する

DateUtil.java

テスト対象
import java.util.Calendar;
import java.util.Date;

public class DateUtil {
  public static Date getCurrentDate() {
    // 内部で、Calendar.getInstance()を呼んでいる
    Calendar calendar = Calendar.getInstance();
    return calendar.getTime();
  }
}

DateUtilTest.java

テストコード
import static org.junit.Assert.*;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) // ★重要★
@PrepareForTest({Calendar.class, DateUtil.class}) // ★重要★
public class DateUtilTest {

  @Test
  public void getCurrentDateTest() {
    Calendar mockCalendar = Calendar.getInstance();
    mockCalendar.set(2018, 1, 9, 22, 20, 9);
    mockCalendar.set(Calendar.MILLISECOND, 0);
    PowerMockito.mockStatic(Calendar.class);
    PowerMockito.when(Calendar.getInstance()).thenReturn(mockCalendar);

    Date result = DateUtil.getCurrentDate();

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    System.out.println("Date : " + simpleDateFormat.format(result));
    assertEquals("2018/02/09 22:20:09", simpleDateFormat.format(result));
  }
}

■ サンプル2:System.getenv()のモック化

 * 環境変数の取得 System.getenv()をモック化する
 * 以下の関連記事「JUnit で環境変数を変更するテストを行うには...」で行ったことを
   PowerMock を使って行う
https://blogs.yahoo.co.jp/dk521123/37474828.html

SampleTest.java

テストコード
import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) // ★重要★
@PrepareForTest({System.class}) // ★重要★
public class SampleTest {

  @Test
  public void test() {
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01");

    assertEquals("dummy01", System.getenv("ENV_KEY"));
  }
}

■ トラブル

 * 以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37484598.html

関連記事

PowerMock に関するトラブルシューティング

https://blogs.yahoo.co.jp/dk521123/37484598.html

EasyMock ~入門編~

https://blogs.yahoo.co.jp/dk521123/7674982.html

Mockito ~入門編~

https://blogs.yahoo.co.jp/dk521123/33767685.html

Mockito ~構文編~

https://blogs.yahoo.co.jp/dk521123/33769274.html

JMockit ~入門編~

https://blogs.yahoo.co.jp/dk521123/33763863.html

JUnit で環境変数を変更するテストを行うには...

https://blogs.yahoo.co.jp/dk521123/37474828.html

【Docker】 Docker ~ Linux / 入門編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37128692.html
の続き。今回は、Linux。

■ 設定環境

 * OS : CentOS7

■ 構築手順

[1] Docker のインストール
[2] Docker の起動及び自動起動 

[1] Docker のインストール

sudo yum -y update

sudo yum -y install docker

docker --version
# 「Docker version 1.13.1, build 774336d/1.13.1」が表示

[2] Docker の起動及び自動起動

# ★起動
sudo systemctl start docker

# 確認1
sudo systemctl status docker

# 確認2
sudo docker search centos | more

# ★自動起動
sudo systemctl enable docker

# 確認1
sudo systemctl is-enabled docker

■ Dockerコマンド

imageに関するコマンド

# image検索
sudo docker search centos | more

# image取得
sudo docker pull centos

# 取得したimage一覧表示
sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    latest              e934aafc2206        3 days ago          199 MB

# imageの詳細設定表示
sudo docker inspect e934aafc2206

# image削除(rmi = remove image)
sudo docker rmi e934aafc2206

Containerに関するコマンド

# Container作成 (Container上で「echo "Hello World"」を実行)
sudo docker run centos echo "Hello World"

# 実行中のContainer一覧表示
sudo docker ps

# Container一覧表示(実行完了後を表示。「Exited (0)」は正常終了)
sudo docker ps -a

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
3c38d46e852d        centos              "echo 'Hello World'"   5 minutes ago       Exited (0) 5 minutes ago                       gallant_yonath

# Container一覧表示(実行完了後の最新3履歴を表示)
sudo docker ps -a -n=3

# Container削除(「sudo docker ps -a」で確認するとなくなっているはず)
sudo docker rm 3c38d46e852d


関連記事

Docker ~ Windows / 入門編 ~

https://blogs.yahoo.co.jp/dk521123/37128692.html

【SQL】初めの数文字が一致してたら同一データと見なすSQL文

$
0
0

■ はじめに

 初めの数文字が一致してたら同一データと見なし、重複を排除するSQL文を考える

解決案

以下を使えば可能。

 * サブクエリ
 * LEFT()
 * GROUP BY

■ 実行環境

 * DB : MySQL5.7

■ サンプルデータ

テーブル

CREATE TABLE `message` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `message_text` TEXT NULL,
  PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

データ

INSERT INTO `message` (`id`, `message_text`) VALUES (1, 'Thank you for your attention.');
INSERT INTO `message` (`id`, `message_text`) VALUES (2, 'Thank you for asking');
INSERT INTO `message` (`id`, `message_text`) VALUES (3, 'Sorry to be late.');
INSERT INTO `message` (`id`, `message_text`) VALUES (4, 'Thank you for your advise.');
INSERT INTO `message` (`id`, `message_text`) VALUES (5, 'Sorry...');

■ サンプル

SQL文

SELECT
 * 
FROM
 message AS m
WHERE
 m.id IN (
 SELECT
  MIN(id)
 FROM
  message AS sub_m
 GROUP BY
  LEFT(sub_m.message_text, 5)
 )

出力結果

id | message_text
---+------------------------------
1  | Thank you for your attention.
3  | Sorry to be late.

【MySQL】 GROUP BY句での論理演算 ~ BIT_OR() 等 ~

$
0
0

■ はじめに

 * テーブルのBOOL(BIT)項目に対して、GROUP BYした後に論理演算 OR をしたかったので調べてみた

【MySQL】解決案

 * BIT_OR() ってのがある
公式サイト
https://dev.mysql.com/doc/refman/5.6/ja/group-by-functions.html

■ 実行環境

 * DB : MySQL5.7

■ サンプルデータ

 * トイレ掃除チェックリストで考える。
  => 一日中のうち、一回でもダメ(NG=true)だったらアウト

テーブル

-- トイレ掃除チェックリスト
CREATE TABLE `toilet_clean_checklist` (
	`check_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'チェック日時',
	`ng` BIT(1) NOT NULL DEFAULT b'0' COMMENT 'NG:ダメだったら 1(true)',
	`inspector` VARCHAR(10) NULL DEFAULT NULL COMMENT 'チェックした人'
)
ENGINE=InnoDB
;

データ

REPLACE INTO `toilet_clean_checklist` (`check_datetime`, `ng`, `inspector`) VALUES
	('2018-04-10 09:30:37', b'0', 'Mike'),
	('2018-04-10 17:31:08', b'0', 'Tom'),
	('2018-04-10 21:31:29', b'0', 'Sam'),
	('2018-04-11 08:21:52', b'0', 'Mike'),
	('2018-04-11 11:12:34', b'0', 'Tom'),
	('2018-04-11 21:33:35', b'1', 'Sam'),
	('2018-04-12 08:33:48', b'1', 'Tom'),
	('2018-04-12 11:12:17', b'1', 'Mike');
データ表示
check_datetime     | ng | inspector
-------------------+----+-----------
2018-04-10 09:30:37|  0 |      Mike
2018-04-10 17:31:08|  0 |       Tom
2018-04-10 21:31:29|  0 |       Sam
-------------------------------------
2018-04-11 08:21:52|  0 |      Mike
2018-04-11 11:12:34|  0 |       Tom
2018-04-11 21:33:35|  1 |       Sam
-------------------------------------
2018-04-12 08:33:48|  1 |       Tom
2018-04-12 11:12:17|  1 |      Mike

■ サンプル

SQL文

SELECT
 DATE_FORMAT(tcc.check_datetime, '%Y-%m-%d') AS date,
 BIT_OR(tcc.ng) AS result
FROM
 toilet_clean_checklist AS tcc
GROUP BY
 DATE_FORMAT(tcc.check_datetime, '%Y-%m-%d')

出力結果

date       | result
-----------+--------
2018-04-10 |     0
2018-04-11 |     1
2018-04-12 |     1
Viewing all 860 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>