2019年11月18日月曜日

Ex13ProcessPoolExecutor.py

# https://docs.python.org/ja/3/library/concurrent.futures.html?highlight=processpoolexecutor
# https://qiita.com/__init__/items/91e5841ed53d55a7895e
import concurrent.futures
import logging
# import math
import math
import os
import time
from logging import getLogger, StreamHandler, FileHandler, Formatter

PRIMES = [
    0,
    10000,
    1,
    20000,
    30000,
    2,
    40000,
    50000,
    60000,
    3,
    4,
    5,
    6,
]

def mkLogger(type, n):
    # 1.loggerの設定
    # loggerオブジェクトの宣言
    logger = getLogger(type)

    # loggerのログレベル設定(ハンドラに渡すエラーメッセージのレベル)
    logger.setLevel(logging.DEBUG)

    # 2.handlerの設定
    # ログ出力フォーマット設定
    handler_format = Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # 2-1.標準出力のhandler
    # handlerの生成
    stream_handler = StreamHandler()

    # handlerのログレベル設定(ハンドラが出力するエラーメッセージのレベル)
    stream_handler.setLevel(logging.DEBUG)

    # ログ出力フォーマット設定
    stream_handler.setFormatter(handler_format)

    # 2-2.テキスト出力のhandler
    # handlerの生成
    file_handler = FileHandler('Ex13ProcessPoolExecutor.' + type + '.log', 'a')

    # handlerのログレベル設定(ハンドラが出力するエラーメッセージのレベル)
    file_handler.setLevel(logging.DEBUG)

    # ログ出力フォーマット設定
    file_handler.setFormatter(handler_format)

    # 3.loggerにhandlerをセット
    # 標準出力のhandlerをセット
    logger.addHandler(stream_handler)
    # テキスト出力のhandlerをセット
    logger.addHandler(file_handler)

    return logger

def is_prime(n):
    print("# %s %s %s\n" % (str(os.getpid()), str(n), "start"))
    logger = mkLogger(str(n), n)
    logger.debug(str(os.getpid()) + " " + str(n) + " Start Hello World!")
    print("# %s %s %s\n" % (str(os.getpid()), str(n), "logger.debug"))

    # sqrt_n = int(math.floor(math.sqrt(n))) * 1
    print("# %s %s %s\n" % (str(os.getpid()), str(n), "exec " + str(n)))
    # time.sleep(n)
    for i in range(0, n, 1):
        None
        logger.debug(str(os.getpid()) + " " + str(n) + " Hello World! " + str(i))

    print("# %s %s %s\n" % (str(os.getpid()), str(n), "end"))
    logger.debug(str(os.getpid()) + " " + str(n) + " End Hello World!")
    return [[True, os.getpid()]]

def main():
    logger = mkLogger("Main", 999)
    logger.debug(str(os.getpid()) + " " + "Main" + " Hello World!")
    for n in PRIMES:
        # print("#n=", n, nlf[str(n)])
        lf = "Ex13ProcessPoolExecutorA." + str(n) + ".log"
    with concurrent.futures.ProcessPoolExecutor(max_workers=15) as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))
            logger.debug('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()

2019年10月20日日曜日

tterm-aws01.bat

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set "PATH=C:\Program Files (x86)\teraterm;%PATH%"

set "host=hhhhhhhhhh.amazonaws.com"

start "" "ttermpro.exe" "ec2-user@!host!" ^
/nosecuritywarning /auth=publickey /user=uuuuuuuuuu ^
/keyfile="%~dp0\\kkkkkkkkkk.pem"

tf.aws.sh.tf

# aws_dynamodb_table.tbl01_tf:
resource "aws_dynamodb_table" "tbl01_tf" {
  # arn            = "arn:aws:dynamodb:ap-northeast-1:751075880470:table/tbl01"
  billing_mode = "PROVISIONED"
  hash_key     = "fld01"
  # id             = "tbl01"
  name           = "tbl01"
  read_capacity  = 5
  stream_enabled = false
  tags           = {}
  write_capacity = 5
  attribute {
    name = "fld01"
    type = "N"
  }
  point_in_time_recovery {
    enabled = false
  }
  timeouts {}
  ttl {
    attribute_name = "fld00"
    enabled        = true
  }
}
# aws_dynamodb_table.tbl11_tf:
resource "aws_dynamodb_table" "tbl11_tf" {
  # arn            = "arn:aws:dynamodb:ap-northeast-1:751075880470:table/tbl11"
  billing_mode = "PROVISIONED"
  hash_key     = "fld11"
  # id             = "tbl11"
  name           = "tbl11"
  read_capacity  = 5
  stream_enabled = false
  tags           = {}
  write_capacity = 5
  attribute {
    name = "fld11"
    type = "S"
  }
  point_in_time_recovery {
    enabled = false
  }
  timeouts {}
  ttl {
    attribute_name = "fld11"
    enabled        = true
  }
}
# aws_s3_bucket.awss3bkt001_tf:
resource "aws_s3_bucket" "awss3bkt001_tf" {
  # arn                         = "arn:aws:s3:::awss3bkt001"
  bucket = "awss3bkt001"
  # bucket_domain_name          = "awss3bkt001.s3.amazonaws.com"
  # bucket_regional_domain_name = "awss3bkt001.s3.ap-northeast-1.amazonaws.com"
  hosted_zone_id = "Z2M4EHUR26P7ZW"
  # id                          = "awss3bkt001"
  region        = "ap-northeast-1"
  request_payer = "BucketOwner"
  tags          = {}
  versioning {
    enabled    = false
    mfa_delete = false
  }
}
# aws_s3_bucket.awss3bkt002_tf:
resource "aws_s3_bucket" "awss3bkt002_tf" {
  # arn                         = "arn:aws:s3:::awss3bkt002"
  bucket = "awss3bkt002"
  # bucket_domain_name          = "awss3bkt002.s3.amazonaws.com"
  # bucket_regional_domain_name = "awss3bkt002.s3.ap-northeast-1.amazonaws.com"
  hosted_zone_id = "Z2M4EHUR26P7ZW"
  # id                          = "awss3bkt002"
  region        = "ap-northeast-1"
  request_payer = "BucketOwner"
  tags          = {}
  versioning {
    enabled    = false
    mfa_delete = false
  }
}

2019年10月18日金曜日

tf.provider.tf

provider "aws" {
  #access_key = "aaaaaaaaaa"
  #secret_key = "ssssssssss"
  region  = "ap-northeast-1"
  version = "2.30"
}

tf.aws.sh

#!/usr/bin/sh

cmd_filename=${0##*/}

export AWS_ACCESS_KEY_ID="aaaaaaaaaa"
export AWS_SECRET_ACCESS_KEY="ssssssssss"
export AWS_DEFAULT_REGION="ap-northeast-1"

# export TF_LOG="DEBUG"
export CHECKPOINT_DISABLE="true"

TerraformCmd="./terraform"
TerraformCmd_apply_opt="-auto-approve"
TerraformCmd_fmt_opt="-recursive ."

file_resource_list_txt="${cmd_filename}.resource.list.txt"
file_txt="${cmd_filename}.txt"
file_tf="${cmd_filename}.tf"
file_tmp_tf="${cmd_filename}.tmp.tf"


# ================
# main.
# ================
main() {
  if [ "$1" = "" ]; then
    printUsage
  elif [ "$1" = "apply" ]; then
    TerraformCmd_apply
  elif [ "$1" = "fmt" ]; then
    TerraformCmd_fmt
  elif [ "$1" = "import" ]; then
    TerraformCmd_import
  elif [ "$1" = "plan" ]; then
    TerraformCmd_plan
  elif [ "$1" = "init" ]; then
    TerraformCmd_init
  elif [ "$1" = "remove" ]; then
    TerraformCmd_remove
  elif [ "$1" = "showInfo" ]; then
    TerraformCmd_showInfo
  else
    printUsage
  fi
}


# ================
# Print usage.
# ================
printUsage() {
  cat <<__EOF__
Usage:
  ${cmd_filename} import
  ${cmd_filename} apply
  ${cmd_filename} fmt
  ${cmd_filename} plan
  ${cmd_filename} init
  ${cmd_filename} remove
  ${cmd_filename} showInfo
__EOF__
}


# ================
# Filesystem delete files.
# ================
Filesystem_deleteFiles() {
  for filePath in \
    "$@"
  do
    if [ -f "${filePath}" ]; then
      echo "#" \
        rm "${filePath}"
        rm "${filePath}"
    fi
    if [ -f "${filePath}" ]; then
      echo Did not delete file "${filePath}".
      exit 11
    fi
  done
}


# ================
# TerraformFile Make empty file_tmp_tf.
# ================
TerraformFile_makeEmptyTf() {
  if [ ! -f "${file_resource_list_txt}" ]; then
    echo Does not exist file ${file_resource_list_txt}.
    exit 21
  fi
  Filesystem_deleteFiles \
    "${file_tmp_tf}"
  cat "$file_resource_list_txt" | \
  while read aws_resource_type aws_resource_name; do
    TerraformFile_printEmptyTf \
      "${aws_resource_type}" \
      "${aws_resource_name}" \
      >> "${file_tmp_tf}"
  done
}


# ================
# MakeTerraformFile Make one empty resource tf.
# ================
TerraformFile_printEmptyTf() {
  aws_resource_type="$1"
  aws_resource_name="$2"
  tf_resource_name="${aws_resource_name}_tf"
  cat <<__EOF__
resource "${aws_resource_type}" "${tf_resource_name}" {
}
__EOF__
}


# ================
# Terraform cmd.
# ================
TerraformCmd() {
  for tf_commamd in \
    "$@"
  do
    echo "#" \
      "${TerraformCmd}" ${tf_commamd}
      "${TerraformCmd}" ${tf_commamd}
    if [ $? -ne 0 ]; then
      echo Exit code is $?.
      exit 22
    fi
  done
}


# ================
# Terraform Show info.
# ================
TerraformCmd_showInfo() {
  echo "#" \
    cat "${file_resource_list_txt}"
    cat "${file_resource_list_txt}"
  TerraformCmd \
    "version" \
    "providers" \
    "validate -json"
}


# ================
# Terraform apply.
# ================
TerraformCmd_apply() {
  Filesystem_deleteFiles \
    "${file_txt}" \
    "${file_tmp_tf}"
  TerraformCmd_showInfo
  TerraformCmd_init
  TerraformCmd_plan
  TerraformCmd "apply ${TerraformCmd_apply_opt}"
}


# ================
# Terraform fmt.
# ================
TerraformCmd_fmt() {
  TerraformCmd "fmt ${TerraformCmd_fmt_opt}"
}


# ================
# Terraform init.
# ================
TerraformCmd_init() {
  TerraformCmd_fmt
  TerraformCmd "init"
}


# ================
# Terraform plan.
# ================
TerraformCmd_plan() {
  TerraformCmd "plan"
}


# ================
# Terraform remove.
# ================
TerraformCmd_remove() {
  if [ ! -f "${file_tf}" ]; then
    echo Does not exist file "${file_tf}".
    exit 23
  fi
  mv "${file_tf}" "${file_tf}.tmp"
  TerraformCmd_apply
  mv "${file_tf}.tmp" "${file_tf}"
}


# ================
# Terraform import.
# ================
TerraformCmd_import() {
  Filesystem_deleteFiles \
    "terraform.tfstate" \
    "${file_txt}" \
    "${file_tf}" \
    "${file_tmp_tf}"
  TerraformCmd_showInfo

  TerraformFile_makeEmptyTf
  echo "#" \
    cat "${file_tmp_tf}"
    cat "${file_tmp_tf}"
  TerraformCmd_init

  # Make file_txt.
  cat "$file_resource_list_txt" | \
  while read aws_resource_type aws_resource_name; do
    tf_resource_name="${aws_resource_name}_tf"
    TerraformCmd \
      "import ${aws_resource_type}.${tf_resource_name} ${aws_resource_name}"
    TerraformCmd \
      "state show -no-color ${aws_resource_type}.${tf_resource_name}" \
      >> "${file_txt}"
  done
  Filesystem_deleteFiles \
    "${file_tmp_tf}"

  # Make file_tf.
  sed \
    -e "s/\( arn \)/ #\1/g" \
    -e "s/\( id \)/ #\1/g" \
    -e "s/\( bucket_domain_name \)/ #\1/g" \
    -e "s/\( bucket_regional_domain_name \)/ #\1/g" \
    "${file_txt}" \
    >> "${file_tf}"

  TerraformCmd_fmt

  echo "#" \
    cat "${file_tf}"
    cat "${file_tf}"

  TerraformCmd_plan
}


main $@

exit 0

tf.aws.sh.resource.list.txt

aws_dynamodb_table  tbl01
aws_dynamodb_table  tbl11
aws_s3_bucket       awss3bkt001
aws_s3_bucket       awss3bkt002

tf.aws.bat

@rem
@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

set "cmd_filename=%~nx0"

set "AWS_ACCESS_KEY_ID=aaaaaaaaaa"
set "AWS_SECRET_ACCESS_KEY=ssssssssss"
set "AWS_DEFAULT_REGION=ap-northeast-1"

@rem set "TF_LOG=DEBUG"
set "CHECKPOINT_DISABLE=true"

set "TerraformCmd=.\terraform.exe"
set "TerraformCmd_apply_opt=-auto-approve"
set "TerraformCmd_fmt_opt=-recursive ."

set "dot_cmd=uuuuuuuuuu\PlantUML\graphviz\release\bin\dot.exe"

set "file_resource_list_txt=!cmd_filename!.resource.list.txt"
set "file_txt=!cmd_filename!.txt"
set "file_tf=!cmd_filename!.tf"
set "file_tmp_tf=!cmd_filename!.tmp.tf"
set "file_png=!cmd_filename!.png"


@rem ================
@rem main.
@rem ================
:main
if "%1"=="" (
  goto :printUsage
) else if "%1"=="apply" (
  goto :TerraformCmd_apply
) else if "%1"=="fmt" (
  goto :TerraformCmd_fmt
) else if "%1"=="import" (
  goto :TerraformCmd_import
) else if "%1"=="plan" (
  goto :TerraformCmd_plan
) else if "%1"=="init" (
  goto :TerraformCmd_init
) else if "%1"=="remove" (
  goto :TerraformCmd_remove
) else if "%1"=="showInfo" (
  goto :TerraformCmd_showInfo
) else (
  goto :printUsage
)
goto :eof


@rem ================
@rem Print usage.
@rem ================
:printUsage
  echo Usage:
  echo   !cmd_filename! import
  echo   !cmd_filename! apply
  echo   !cmd_filename! fmt
  echo   !cmd_filename! plan
  echo   !cmd_filename! init
  echo   !cmd_filename! remove
  echo   !cmd_filename! showInfo
goto :eof


@rem ================
@rem Filesystem delete files.
@rem ================
:Filesystem_deleteFiles
  for %%z in (
    %*
  ) do (
    set "filePath=%%z"
    if exist "!filePath!" (
      echo ^
        del "!filePath!"
        del "!filePath!"
    )
    if exist "!filePath!" (
      echo Did not delete file "${filePath}".
      exit /b 11
    )
  )
goto :eof


@rem ================
@rem TerraformFile Make empty file_tmp_tf.
@rem ================
:TerraformFile_makeEmptyTf
  if not exist "!file_resource_list_txt!" (
    echo Does not exist file "!file_resource_list_txt!".
    exit /b 21
  )
  for /f "usebackq tokens=1,2 delims= " %%y in (
    `type "!file_resource_list_txt!"`
  ) do (
    set "aws_resource_type=%%y"
    set "aws_resource_name=%%z"
    call :TerraformFile_printEmptyTf ^
      "!aws_resource_type!" ^
      "!aws_resource_name!" ^
      >> "!file_tmp_tf!"
  )
goto :eof


@rem ================
@rem TerraformFile Make one empty resource tf.
@rem ================
:TerraformFile_printEmptyTf
  set "aws_resource_type=%~1"
  set "aws_resource_name=%~2"
  set "tf_resource_name=!aws_resource_name!_tf"
  echo resource "!aws_resource_type!" "%!tf_resource_name!" {
  echo }
goto :eof


@rem ================
@rem Terraform cmd.
@rem ================
:TerraformCmd
  for %%z in (
    %*
  ) do (
    set "tf_commamd=%%z"
    set "tf_commamd=!tf_commamd:"=!"
    @rem "
    echo # ^
      "!TerraformCmd!" !tf_commamd!
      "!TerraformCmd!" !tf_commamd!
    if not !errorlevel!==0 (
      echo Exit code is !errorlevel!.
      exit /b 22
    )
  )
goto :eof


@rem ================
@rem Terraform Show info.
@rem ================
:TerraformCmd_showInfo
  echo # ^
    type "!file_resource_list_txt!"
    type "!file_resource_list_txt!"
  call :TerraformCmd ^
    "version" ^
    "providers" ^
    "validate -json"
goto :eof


@rem ================
@rem Terraform apply.
@rem ================
:TerraformCmd_apply
  call :Filesystem_deleteFiles ^
    "!file_txt!" ^
    "!file_tmp_tf!" ^
    "!file_png!"
  call :TerraformCmd_showInfo
  call :TerraformCmd_init
  call :TerraformCmd_plan
  call :TerraformCmd "apply !TerraformCmd_apply_opt!"
goto :eof


@rem ================
@rem Terraform fmt.
@rem ================
:TerraformCmd_fmt
  call :TerraformCmd "fmt !TerraformCmd_fmt_opt!"
goto :eof


@rem ================
@rem Terraform init.
@rem ================
:TerraformCmd_init
  call :TerraformCmd_fmt
  call :TerraformCmd "init"
goto :eof


@rem ================
@rem Terraform plan.
@rem ================
:TerraformCmd_plan
  call :TerraformCmd "plan"
goto :eof


@rem ================
@rem Terraform remove.
@rem ================
:TerraformCmd_remove
  if not exist "!file_tf!" (
    echo Does not exist file "!file_tf!".
    exit /b 23
  )
  ren "!file_tf!" "!file_tf!.tmp"
  call :TerraformCmd_apply
  ren "!file_tf!.tmp" "!file_tf!"
goto :eof


@rem ================
@rem Terraform import.
@rem ================
:TerraformCmd_import
  call :Filesystem_deleteFiles ^
    "terraform.tfstate" ^
    "!file_txt!" ^
    "!file_tf!" ^
    "!file_tmp_tf!" ^
    "!file_png!"
  call :TerraformCmd_showInfo

  call :TerraformFile_makeEmptyTf
  echo # ^
    type "!file_tmp_tf!"
    type "!file_tmp_tf!"
  call :TerraformCmd_init

  @rem Make file_txt.
  echo # ^
    type "!file_resource_list_txt!"
    type "!file_resource_list_txt!"

  for /f "usebackq tokens=1,2 delims= " %%i in (
    `type "!file_resource_list_txt!"`
  ) do (
    set "aws_resource_type=%%i"
    set "aws_resource_name=%%j"
    set "tf_resource_name=!aws_resource_name!_tf"
    echo # ^
      aws_resource_type=!aws_resource_type! ^
      aws_resource_name=!aws_resource_name! ^
      tf_resource_name=!tf_resource_name!

    echo # ^
      "!TerraformCmd!" import "!aws_resource_type!.!tf_resource_name!" !aws_resource_name!
      "!TerraformCmd!" import "!aws_resource_type!.!tf_resource_name!" !aws_resource_name!
    if not !errorlevel!==0 exit /b 1

    echo # ^
      "!TerraformCmd!" state show -no-color "!aws_resource_type!.!tf_resource_name!"
      "!TerraformCmd!" state show -no-color "!aws_resource_type!.!tf_resource_name!" >> "!file_txt!"
    if not !errorlevel!==0 exit /b 2

  )
  call :Filesystem_deleteFiles ^
    "!file_tmp_tf!"
  ren "!file_txt!" "!file_tf!"
  call :TerraformCmd_fmt
  ren "!file_tf!" "!file_txt!"

  @rem Make file_tf.
  for /f "usebackq tokens=1* delims=" %%i in (
    `type "!file_txt!"`
  ) do (
    set "line=%%i"

    set "line=!line: arn = # arn !"
    set "line=!line: id = # id !"
    set "line=!line: bucket_domain_name = # bucket_domain_name !"
    set "line=!line: bucket_regional_domain_name = # bucket_regional_domain_name !"
    (echo !line!) >> "!file_tf!"
  )

  call :TerraformCmd_fmt

  echo # ^
    type "!file_tf!"
    type "!file_tf!"

  call :TerraformCmd_plan

  @rem Make file_png.
  call :L_mkPng

  @rem pause

goto :eof


@rem ================
@rem Make file_png.
@rem ================
:L_mkPng
if exist "!dot_cmd!" (
  echo # ^
    "!TerraformCmd!" graph ^| "!dot_cmd!" -Tpng ^> "!file_png!"
    "!TerraformCmd!" graph | "!dot_cmd!" -Tpng > "!file_png!"
)
goto :eof

terraform.exe-h.txt

Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    0.12upgrade        Rewrites pre-0.12 module source code for v0.12
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    push               Obsolete command for Terraform Enterprise legacy (v1)
    state              Advanced state management

2019年8月12日月曜日

mkCascadeDetect.bat

call .\venv\Scripts\activate
python mkCascadeDetect.py
deactivate

cvtIcon.py

import cv2
import glob
import os
import os.path
import re
import numpy as np

ocvIcoDirPath="data/ico-96"
# def binary_threshold(path):def binary_threshold(img):
    # img = cv2.imread(path)    # grayed = cv2.cvtColor(img, cv2.IMREAD_GRAYSCALE)    grayed = img
    under_thresh = 105    upper_thresh = 145    maxValue = 255    th, drop_back = cv2.threshold(grayed, under_thresh, maxValue, cv2.THRESH_BINARY)
    th, clarify_born = cv2.threshold(grayed, upper_thresh, maxValue, cv2.THRESH_BINARY_INV)
    merged = np.minimum(drop_back, clarify_born)
    merged = drop_back
    return merged

def mask_blue(path):
    img = cv2.imread(path)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    blue_min = np.array([210*180/240, 170*100/240, 200*100/240], np.uint8)
    blue_max = np.array([230*180/240, 190*100/240, 230*100/240], np.uint8)

    blue_region = cv2.inRange(hsv, blue_min, blue_max)
    white = np.full(img.shape, 255, dtype=img.dtype)
    background = cv2.bitwise_and(white, white, mask=blue_region)  # detected blue area becomes white
    inv_mask = cv2.bitwise_not(blue_region)  # make mask for not-blue area    extracted = cv2.bitwise_and(img, img, mask=inv_mask)

    masked = cv2.add(extracted, background)

    return masked

def morph(img):
    kernel = np.ones((3, 3),np.uint8)
    opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=2)
    # opened = cv2.morphologyEx(img, cv2.MORPH_ERODE, kernel, iterations=2)    return opened

def morph_and_blur(img):
    kernel = np.ones((3, 3),np.uint8)
    m = cv2.GaussianBlur(img, (3, 3), 0)
    m = cv2.morphologyEx(m, cv2.MORPH_OPEN, kernel, iterations=2)
    m = cv2.GaussianBlur(m, (5, 5), 0)
    return m

def icoFile(icoFilePath):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)    # gray = cv2.cvtColor(img, cv2.IMREAD_COLOR)    # gray = mask_blue(gray)    gray = morph(gray)
    # gray = binary_threshold(icoFilePath)    # cv2.imwrite(detectedFilePath, gray)    return gray

def resize_image(img, size):
    # size is enough to img    img_size = img.shape[:2]
    if img_size[0] > size[1] or img_size[1] > size[0]:
        raise Exception("img is larger than size")

    # centering    row = (size[1] - img_size[0]) // 2    col = (size[0] - img_size[1]) // 2    resized = np.zeros(list(size) + [img.shape[2]], dtype=np.uint8)
    resized[row:(row + img.shape[0]), col:(col + img.shape[1])] = img

    # filling    mask = np.full(size, 255, dtype=np.uint8)
    mask[row:(row + img.shape[0]), col:(col + img.shape[1])] = 0    filled = cv2.inpaint(resized, mask, 3, cv2.INPAINT_TELEA)

    return filled

icoFilePaths = glob.glob(str(ocvIcoDirPath) + "/*")
pathname = ocvIcoDirPath + "-2"os.makedirs(pathname,  exist_ok=True)
for icoFilePath in icoFilePaths:
    basename = os.path.basename(icoFilePath)
    icoFilePath = re.sub('[/\\\\]', "/", icoFilePath)
    img = cv2.imread(icoFilePath)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = binary_threshold(gray)
    # gray = morph(gray)    # gray = morph_and_blur(gray)    # gray = resize_image(gray, (210, 210))    cv2.imwrite(pathname + "/" + basename, gray)
    gray = gray

2019年8月5日月曜日

getSitImg.py

import os
import re
import requests
import time
from bs4 import BeautifulSoup

staSitLst = {
    # jreast    #    # https://www.jreast.co.jp/estation/stations/    #     </td><td style="width:99px;"><A href="http://www.jreast.co.jp/estation/stations/1039.html" target = "_blank" onclick="openMap('1039');return false;">東京</A>    #    # https://www.jreast.co.jp/estation/stations/1039.html    #                  <img src="img/floormap/1039_1f.png" alt="東京駅 1F構内図">    #    # https://www.jreast.co.jp/estation/stations/img/floormap/1039_1f.png    "jreast": {
        "itemEnable": False,        "ocvSitUrl": "https://www.jreast.co.jp/",        "staLstUrl": "https://www.jreast.co.jp/estation/stations",        "reImgLstUrl": "^(http://www\.jreast\.co\.jp/estation/stations/[0-9]+\..+)$",        "reImgLstId": "\\1",        "fmtImgLstUrl": "{}",        "reStaImgUrl": "^(img/floormap/.+\..+)$",        "reStaImgId": "\\1",        "fmtStaImgUrl": "https://www.jreast.co.jp/estation/stations/{}",        "reStaImgUrlFilBas": "^.*img/floormap/([^.]+)\.[^.]+.*$",        "reStaImgUrlFilExt": "^.*img/floormap/[^.]+\.([^.]+)$",        "regStaImgUrlFilBas": "\\1",        "regStaImgUrlFilExt": "\\1",        "imgUrl": "{}/{}",        "z": "z"    },    # keikyu    #    # https://www.keikyu.co.jp/train-info/kakueki/index.html    #     <area coords="206,48,426,88" href="/train-info/kakueki/KK01.html" alt="品川" data-imagemap-rollover-url="/assets/image/train-info/kakueki/index_img_route_KK01.png">    #    # https://www.keikyu.co.jp/train-info/kakueki/KK01.html    #     <img src="/assets/image/train-info/kakueki/KK01/img_03.png" alt="品川駅の設備図です">    #    # https://www.keikyu.co.jp/assets/image/train-info/kakueki/KK01/img_03.png    "keikyu": {
        "itemEnable": False,        "ocvSitUrl": "https://www.keikyu.co.jp/",        "staLstUrl": "https://www.keikyu.co.jp/train-info/kakueki/index.html",        "reImgLstUrl": "^(/train-info/kakueki/KK[0-9][0-9]\.htm.*)",        "reImgLstId": "\\1",        "fmtImgLstUrl": "https://www.keikyu.co.jp{}",        "reStaImgUrl": "^(/assets/image/train-info/kakueki/KK[0-9][0-9]/img_03\..+)$",        "reStaImgId": "\\1",        "fmtStaImgUrl": "https://www.keikyu.co.jp{}",        "reStaImgUrlFilBas": "^.*/assets/image/train-info/kakueki/(KK[0-9][0-9])/img_03.[^.]+.*$",        "reStaImgUrlFilExt": "^.*/assets/image/train-info/kakueki/KK[0-9][0-9]/img_03.([^.]+).*$",        "regStaImgUrlFilBas": "\\1",        "regStaImgUrlFilExt": "\\1",        "imgUrl": "{}/{}",        "z": "z"    },    # tokyometro    #    # https://www.tokyometro.jp/station/index03.html    #                   <a href="./akihabara/index.html">    #    # https://www.tokyometro.jp/station/akihabara/yardmap/index.html#adjacent    #               <p class="v2_yardmapImg"><img src="../../yardmap_img/_station_%E7%A7%8B%E8%91%89%E5%8E%9F_yardmap_images_yardmap.jpg" alt="" class="v2_js-yardmapImg"></p>    #               <p class="v2_yardmapImg"><img src="../../yardmap_img/figure_yardmap_ayase.gif" alt="" class="v2_js-yardmapImg"></p>    #    # https://www.tokyometro.jp/station/yardmap_img/_station_%E7%A7%8B%E8%91%89%E5%8E%9F_yardmap_images_yardmap.jpg    # https://www.tokyometro.jp/station/yardmap_img/figure_yardmap_ayase.gif    "tokyometro": {
        "itemEnable": False,        "ocvSitUrl": "https://www.tokyometro.jp/",        "staLstUrl": "https://www.tokyometro.jp/station/index03.html",        "reImgLstUrl": "^\./(.+)/index\.html$",        "reImgLstId": "\\1",        "fmtImgLstUrl": "https://www.tokyometro.jp/station/{}/yardmap/index.html",        "reStaImgUrl": "^\.\./\.\./(yardmap_img/.+\..+)$",        "reStaImgId": "\\1",        "fmtStaImgUrl": "https://www.tokyometro.jp/station/{}",        "reStaImgUrlFilBas": "^.*https://www.tokyometro.jp/station/([^/]+)/yardmap/index.html.*$",        "reStaImgUrlFilExt": "^.*/yardmap_img/.+\.([^.]+).*$",        "regStaImgUrlFilBas": "\\1",        "regStaImgUrlFilExt": "\\1",        "imgUrl": "{}/{}",        "z": "z"    }

}

ocvItvlt = 10
def getStaImg(ocvSit, imgLstUrl, staImgUrl):
    reStaImgUrlFilBas = staSitLst[ocvSit]["reStaImgUrlFilBas"]
    regStaImgUrlFilBas = staSitLst[ocvSit]["regStaImgUrlFilBas"]
    reStaImgUrlFilExt = staSitLst[ocvSit]["reStaImgUrlFilExt"]
    regStaImgUrlFilExt = staSitLst[ocvSit]["regStaImgUrlFilExt"]
    imgFilBas = re.sub(reStaImgUrlFilBas, regStaImgUrlFilBas, imgLstUrl + "," + staImgUrl)
    imgFilExt = re.sub(reStaImgUrlFilExt, regStaImgUrlFilExt, imgLstUrl + "," + staImgUrl)
    fmtImgDirPth = "/".join(["data", "_img", "{}", "floormap"])
    fmtImgFilPth = "/".join([fmtImgDirPth, "{}.{}"])
    imgDirPth = fmtImgDirPth.format(ocvSit)
    imgFilPth = fmtImgFilPth.format(ocvSit, imgFilBas, imgFilExt)
    print("# staImgUrl=" + staImgUrl)
    print("# imgFilPth=" + imgFilPth)
    os.makedirs(imgDirPth, exist_ok=True)
    staImg = requests.get(staImgUrl)
    with open(imgFilPth, "wb") as file:
            file.write(staImg.content)
    time.sleep(ocvItvlt)

def getImgLst(ocvSit, imgLstUrl):
    reStaImgUrl = staSitLst[ocvSit]["reStaImgUrl"]
    reStaImgId = staSitLst[ocvSit]["reStaImgId"]
    fmtStaImgUrl = staSitLst[ocvSit]["fmtStaImgUrl"]
    staImgPag = requests.get(imgLstUrl)
    soup = BeautifulSoup(staImgPag.text, "lxml")
    staImgImgTags = soup.find_all("img", src=re.compile(reStaImgUrl))
    for staImgImgTag in staImgImgTags:
        staImgId = re.sub(reStaImgUrl, reStaImgId, staImgImgTag["src"])
        staImgUrl = fmtStaImgUrl.format(staImgId)
        print("# staImgId=" + staImgId + ", staImgUrl=" + staImgUrl)
        getStaImg(ocvSit, imgLstUrl, staImgUrl)

def getStaLst(ocvSit, staLstUrl):
    reImgLstUrl = staSitLst[ocvSit]["reImgLstUrl"]
    reImgLstId = staSitLst[ocvSit]["reImgLstId"]
    fmtImgLstUrl = staSitLst[ocvSit]["fmtImgLstUrl"]
    staLstPag = requests.get(staLstUrl)
    soup = BeautifulSoup(staLstPag.text, "lxml")
    staPagATags = soup.find_all("a", href=re.compile(reImgLstUrl))
    for staPagATag in staPagATags:
        staPagId = re.sub(reImgLstUrl, reImgLstId, staPagATag["href"])
        imgLstUrl = fmtImgLstUrl.format(staPagId)
        print("# staPagId=" + staPagId + ", imgLstUrl=" + imgLstUrl)
        getImgLst(ocvSit, imgLstUrl)

def getSitLst(staSitLst):
    for staSitNam in staSitLst.keys():
        if staSitLst[staSitNam]["itemEnable"] == True:
            staLstUrl = staSitLst[staSitNam]["staLstUrl"]
            print("# staSitNam=" + staSitNam + ", staLstUrl=" + staLstUrl)
            getStaLst(staSitNam, staLstUrl)

def getSit():
    getSitLst(staSitLst)

getSit()

2019年7月17日水曜日

mkCascadeDetect.py

import cv2
import glob
import os
import os.path
import re
import numpy as np

ocvIcoDirPath="data/ico"ocvMdlDirPath="data/mdl"ocvRstDirPath="result"ocvTgtDirPath="data/_img/tokyometro/floormap"# ocvTgtDirPath="data/pos/atm.jpg.d"# ocvTgtDirPath="data/pos/baby.jpg.d"# ocvTgtDirPath="data/pos/elv.jpg.d"# ocvTgtDirPath="data/pos/esc.jpg.d"# ocvTgtDirPath="data/pos/001275320-baby.jpg.d"
ocvTgtDirPaths = [
    "data/_img/jreast/floormap",    "data/_img/keikyu/floormap",    "data/_img/tokyometro/floormap",]

# def binary_threshold(img):#     # img = cv2.imread(path)#     grayed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#     # grayed = img#     under_thresh = 105#     upper_thresh = 145#     maxValue = 255#     th, drop_back = cv2.threshold(grayed, under_thresh, maxValue, cv2.THRESH_BINARY)#     th, clarify_born = cv2.threshold(grayed, upper_thresh, maxValue, cv2.THRESH_BINARY_INV)#     merged = np.minimum(drop_back, clarify_born)#     return merged
# def mask_blue(img):#     # img = cv2.imread(path)#     hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)##     blue_min = np.array([210*180/240, 170*100/240, 200*100/240], np.uint8)#     blue_max = np.array([230*180/240, 190*100/240, 230*100/240], np.uint8)##     blue_region = cv2.inRange(hsv, blue_min, blue_max)#     white = np.full(img.shape, 255, dtype=img.dtype)#     background = cv2.bitwise_and(white, white, mask=blue_region)  # detected blue area becomes white##     inv_mask = cv2.bitwise_not(blue_region)  # make mask for not-blue area#     extracted = cv2.bitwise_and(img, img, mask=inv_mask)##     masked = cv2.add(extracted, background)##     return masked
# def morph(img):#     kernel = np.ones((3, 3),np.uint8)#     opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=2)#     return opened
def detectTgtIco(tgtFilePath, icoFilePath):
    if os.name == 'nt':
        os.system("title " + tgtFilePath + " " + icoFilePath)
    icoFileName = re.sub('^.*[/\\\\]', "", icoFilePath)
    tgtFileName = re.sub('^.*[/\\\\]', "", tgtFilePath)
    cascadeXml = str(ocvMdlDirPath) + '/' + icoFileName + '.d/cascade.xml'    detectedFilePath = ocvRstDirPath + "/" + str(tgtFileName) + "." + str(icoFileName) + "." + "jpg"    if os.path.isfile(cascadeXml):
        print("# " + detectedFilePath)
        Cascade = cv2.CascadeClassifier(cascadeXml)
        root, ext = os.path.splitext(tgtFilePath)
        if ext == "gif":
            return        else:
            img = cv2.imread(tgtFilePath, cv2.IMREAD_COLOR)
        # gray = img        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)        # gray = cv2.cvtColor(img, cv2.IMREAD_COLOR)        # gray = mask_blue(gray)        # gray = morph(gray)        # gray = binary_threshold(img)        # cv2.imwrite(detectedFilePath, gray)        point = Cascade.detectMultiScale(gray, 1.1, 3)
        if len(point) > 0:
            print("points: " + str(len(point)))
            for rect in point:
                print(rect)
                (x, y, w, h) = rect
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
            cv2.imwrite(detectedFilePath, img)
        # else:        #     print("no detect")
# def icoFile(ocvTgtDirPath, icoFilePath):#     tgtFilePaths = glob.glob(str(ocvTgtDirPath) + "/*")#     for tgtFilePath in tgtFilePaths:#         tgtFilePath = re.sub('[/\\\\]', "/", tgtFilePath)#         tgtFileFile(tgtFilePath, icoFilePath)
# def icoFiles(ocvTgtDirPath):#     icoFilePaths = glob.glob(str(ocvIcoDirPath) + "/*")#     for icoFilePath in icoFilePaths:#         ocvTgtDirPaths.append(icoFilePath)#         icoFilePath = re.sub('[/\\\\]', "/", icoFilePath)#         icoFile(ocvTgtDirPath, icoFilePath)
# def icoFilePaths(ocvTgtFilePath, ocvIcoFilePath):#     icoFilePaths = glob.glob(str(ocvIcoDirPath) + "/*")#     for icoFilePath in icoFilePaths:#         detectTgtIco(tgtFilePath, icoFilePath)
def tgtFilePath(ocvTgtFilePath):
    ocvIcoFilePaths = glob.glob(str(ocvIcoDirPath) + "/*")
    for ocvIcoFilePath in ocvIcoFilePaths:
        detectTgtIco(ocvTgtFilePath, ocvIcoFilePath)

    # for ocvTgtDirPath in tgtFilePaths:    #     icoFiles(ocvTgtFilePath)

# def tgtFilePath(ocvTgtFilePath):#     for ocvTgtDirPath in tgtFilePaths:#         icoFiles(ocvTgtDirPath)
# for tgtFilePath in ocvTgtDirPaths:#     tgtFilePath = re.sub('[/\\\\]', "/", tgtFilePath)#     icoDir(tgtFilePath)

def tgtDirPath(ocvTgtDirPath):
    ocvTgtFilePaths = glob.glob(str(ocvTgtDirPath) + "/*")
    for ocvTgtFilePath in ocvTgtFilePaths:
            tgtFilePath(ocvTgtFilePath)

def tgtDirPaths(ocvTgtDirPaths):
    for ocvTgtDirPath in ocvTgtDirPaths:
        tgtDirPath(ocvTgtDirPath)

tgtDirPaths(ocvTgtDirPaths)

mkCascadeXml.cmd

@echo off
@rem Make cascade.xml
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set "PATH=%PATH%;!cd!\opencv\build\x64\vc15\bin"

set "ocvThisName=%~nx0"
set "ocvSrcDirPath=src"
set "ocvIcoDirPath=data\ico"
set "ocvPosDirPath=data\pos"
set "ocvNegDirPath=data\neg"
set "ocvVecDirPath=data\pos"
set "ocvMdlDirPath=data\mdl"

set "ocvIcoHeight=20"
set "ocvIcoWidth=20"
set "ocvIcoBgColor=111"
set "ocvIcoBgThresh=1.0"
set "ocvMaxxangle=0.1"
set "ocvMaxyangle=0.0"
set "ocvMaxzangle=0.5"
set "ocvMinHitRate=0.97"
set "ocvMaxFalseAlarmRate=0.1"
set "ocvStage=3"

set "ocvIcoHeight=20"
set "ocvIcoWidth=20"
set "ocvIcoBgColor=111"
set "ocvIcoBgThresh=1.0"
set "ocvMaxxangle=0.1"
set "ocvMaxyangle=0.1"
set "ocvMaxzangle=0.1"
set "ocvMinHitRate=0.97"
set "ocvMaxFalseAlarmRate=0.1"
set "ocvStage=8"

set "ocvParams="
set "ocvParams=!ocvParams!;ocvIcoHeight=!ocvIcoHeight!"
set "ocvParams=!ocvParams!;ocvIcoWidth=!ocvIcoWidth!"
set "ocvParams=!ocvParams!;ocvIcoBgColor=!ocvIcoBgColor!"
set "ocvParams=!ocvParams!;ocvIcoBgThresh=!ocvIcoBgThresh!"
set "ocvParams=!ocvParams!;ocvMaxxangle=!ocvMaxxangle!"
set "ocvParams=!ocvParams!;ocvMaxyangle=!ocvMaxyangle!"
set "ocvParams=!ocvParams!;ocvMaxzangle=!ocvMaxzangle!"
set "ocvParams=!ocvParams!;ocvMinHitRate=!ocvMinHitRate!"
set "ocvParams=!ocvParams!;ocvMaxFalseAlarmRate=!ocvMaxFalseAlarmRate!"
set "ocvParams=!ocvParams!;ocvStage=!ocvStage!"
set "ocvParams=!ocvParams:~1!"

set /a ocvIcoImgNum=0
for %%z in (
  "!ocvIcoDirPath!\*"
) do (
  set /a "ocvIcoImgNum=!ocvIcoImgNum!+1"
  echo.>nul
)

set /a ocvNegImgNum=0
for %%z in (
  "!ocvNegDirPath!\*"
) do (
  set /a "ocvNegImgNum=!ocvNegImgNum!+1"
  echo.>nul
)

call :L_rmNegativeDat

@rem
call :L_mkNegativeDat

set /a ocvIcoImgCnt=0
for %%z in (
  "!ocvIcoDirPath!\*"
) do (
  set /a "ocvIcoImgCnt=!ocvIcoImgCnt!+1"
  set "ocvIcoFileName=%%~nxz"
  set "ocvIcoNameDirName=!ocvIcoFileName!.d"
  set "ocvPosDatFleName=!ocvIcoFileName!.positive.dat"
  set "ocvVecFleName=!ocvIcoFileName!.positive.vec"
  echo # !date! !time! %0 !ocvIcoFileName! **************************************** 1>&2
  title コマンドプロンプト - !ocvThisName! ico=!ocvIcoImgCnt!/!ocvIcoImgNum! stgN=!ocvStage! ^
    negN=!ocvNegImgNum! !ocvIcoFileName!

  call :L_rmPositiveDat
  call :L_rmPositiveVec
  call :L_rmModelXml

  @rem
  call :L_mkPositiveDat

  set /a ocvPosImgCnt=0
  for %%z in (
    "!ocvPosDirPath!\!ocvIcoNameDirName!\*"
  ) do (
    set /a "ocvPosImgCnt=!ocvPosImgCnt!+1"
    echo.>nul
  )

  echo # !date! !time! ocvPosImgCnt=!ocvPosImgCnt! ocvNegImgNum=!ocvNegImgNum!
  if 1 equ 1 (

    @rem
    call :L_mkPositiveVec
    title コマンドプロンプト - !ocvThisName! ico=!ocvIcoImgCnt!/!ocvIcoImgNum! stgN=!ocvStage! ^
      negN=!ocvNegImgNum! !ocvIcoFileName! posN=!ocvPosImgCnt!

    @rem
    call :L_mkModelXml

    echo.>nul
  )

  echo.>nul
)

call :L_mkCascadeDetect

title コマンドプロンプト

goto :eof


:L_mkNegativeDat
(
  echo.
  echo # !date! !time! %0 ========================================
) 1>&2
:echo cd=!cd!
set "ocvWorkDir=."
set ocv
if not exist "!ocvSrcDirPath!" mkdir "!ocvSrcDirPath!"
(
  for %%z in (
    "!ocvNegDirPath!\*"
  ) do (
    set "ovcNegFilePath=%%~z"
    set "ovcNegFilePath=!ovcNegFilePath:\=/!"
    echo ../!ovcNegFilePath!
    echo.>nul
  )
  echo.>nul
) > "!ocvSrcDirPath!/negative.dat"
type "!ocvSrcDirPath!\negative.dat" | sort > "!ocvSrcDirPath!/negative.dat2"
type "!ocvSrcDirPath!\negative.dat2" > "!ocvSrcDirPath!/negative.dat"
if exist "!ocvSrcDirPath!/negative.dat2" del /f /q "!ocvSrcDirPath!\negative.dat2"
set "ocvWorkDir="
goto :eof


:L_rmNegativeDat
(
  echo.
  echo # !date! !time! %0 ========================================
) 1>&2
:echo cd=!cd!
set "ocvWorkDir=."
if exist "!ocvSrcDirPath!/negative.dat" del /f /q "!ocvSrcDirPath!\negative.dat"
goto :eof


:L_mkPositiveDat
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
if not exist "!ocvPosDirPath!/!ocvIcoNameDirName!" mkdir "!ocvPosDirPath!/!ocvIcoNameDirName!"
pushd "!ocvPosDirPath!/!ocvIcoNameDirName!"
:echo cd=!cd!
set "ocvWorkDir=../../.."
set ocv
echo # !date! !time! ^
  opencv_createsamples.exe ^
    -info "!ocvPosDatFleName!" ^
    -img "!ocvWorkDir!/!ocvIcoDirPath:\=/!/!ocvIcoFileName!" ^
    -bg "!ocvWorkDir!/!ocvSrcDirPath:\=/!/negative.dat" ^
    -num !ocvNegImgNum! -maxxangle !ocvMaxxangle! -maxyangle !ocvMaxyangle! -maxzangle !ocvMaxzangle! ^
    -bgcolor !ocvIcoBgColor! -bgthresh !ocvIcoBgThresh! -w !ocvIcoWidth! -h !ocvIcoHeight!
opencv_createsamples.exe ^
    -info "!ocvPosDatFleName!" ^
    -img "!ocvWorkDir!/!ocvIcoDirPath:\=/!/!ocvIcoFileName!" ^
    -bg "!ocvWorkDir!/!ocvSrcDirPath:\=/!/negative.dat" ^
    -num !ocvNegImgNum! -maxxangle !ocvMaxxangle! -maxyangle !ocvMaxyangle! -maxzangle !ocvMaxzangle! ^
    -bgcolor !ocvIcoBgColor! -bgthresh !ocvIcoBgThresh! -w !ocvIcoWidth! -h !ocvIcoHeight!
echo # !date! !time! %0 errorlevel=!errorlevel! 1>&2
(
  for /f "usebackq tokens=*" %%y in (
    `type "!ocvPosDatFleName!"`
  ) do (
    echo !ocvIcoNameDirName!/%%y
    echo.>nul
  )
  echo.>nul
) > "../!ocvPosDatFleName!"
if exist "!ocvPosDatFleName!" del /f /q "!ocvPosDatFleName!"
popd
:echo cd=!cd!
set "ocvWorkDir="
goto :eof


:L_rmPositiveDat
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
:echo cd=!cd!
@rem if exist "!ocvPosDirPath!/!ocvIcoNameDirName!" rmdir /s /q "!ocvPosDirPath!/!ocvIcoNameDirName!"
if exist "!ocvPosDirPath!/!ocvPosDatFleName!" del /f /q "!ocvPosDirPath!\!ocvPosDatFleName!"
goto :eof


:L_mkPositiveVec
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
if not exist "!ocvVecDirPath!/!ocvIcoNameDirName!" mkdir "!ocvVecDirPath!/!ocvIcoNameDirName!"
pushd "!ocvPosDirPath!"
echo cd=!cd!
set "ocvWorkDir=../.."
:set "ocvWorkDir=.."
set ocv
echo # !date! !time! ^
  opencv_createsamples.exe ^
    -info "!ocvPosDatFleName!" ^
    -vec "!ocvVecFleName!" ^
    -num !ocvPosImgCnt! -w !ocvIcoWidth! -h !ocvIcoHeight!
opencv_createsamples.exe ^
    -info "!ocvPosDatFleName!" ^
    -vec "!ocvVecFleName!" ^
    -num !ocvPosImgCnt! -w !ocvIcoWidth! -h !ocvIcoHeight!
echo # !date! !time! %0 errorlevel=!errorlevel! 1>&2
popd
:echo cd=!cd!
set "ocvWorkDir="
goto :eof


:L_rmPositiveVec
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
:echo cd=!cd!
if exist "!ocvVecDirPath!/!ocvVecFleName!" del /f /q "!ocvVecDirPath!\!ocvVecFleName!"
goto :eof


:L_mkModelXml
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
if not exist "!ocvMdlDirPath!/!ocvIcoNameDirName!" mkdir "!ocvMdlDirPath!/!ocvIcoNameDirName!"
pushd "data"
:echo cd=!cd!
set "ocvWorkDir=.."
set /a ocvPosImgCnt8=!ocvPosImgCnt!*80/100
set ocv
echo # !date! !time! ^
  opencv_traincascade.exe ^
    -data "!ocvWorkDir!/!ocvMdlDirPath:\=/!/!ocvIcoNameDirName!" ^
    -vec "!ocvWorkDir!/!ocvVecDirPath:\=/!/!ocvVecFleName!" ^
    -bg "!ocvWorkDir!/!ocvSrcDirPath:\=/!/negative.dat" ^
    -numPos !ocvPosImgCnt8! -numNeg !ocvNegImgNum! -featureType LBP ^
    -maxFalseAlarmRate !ocvMaxFalseAlarmRate! -minHitRate !ocvMinHitRate! ^
    -w !ocvIcoWidth! -h !ocvIcoHeight! -numStages !ocvStage!
start /b /high /wait ^
  opencv_traincascade.exe ^
    -data "!ocvWorkDir!/!ocvMdlDirPath:\=/!/!ocvIcoNameDirName!" ^
    -vec "!ocvWorkDir!/!ocvVecDirPath:\=/!/!ocvVecFleName!" ^
    -bg "!ocvWorkDir!/!ocvSrcDirPath:\=/!/negative.dat" ^
    -numPos !ocvPosImgCnt8! -numNeg !ocvNegImgNum! -featureType LBP ^
    -maxFalseAlarmRate !ocvMaxFalseAlarmRate! -minHitRate !ocvMinHitRate! ^
    -w !ocvIcoWidth! -h !ocvIcoHeight! -numStages !ocvStage!
echo # !date! !time! %0 errorlevel=!errorlevel! 1>&2
popd
:echo cd=!cd!
set "ocvWorkDir="
goto :eof


:L_rmModelXml
(
  echo.
  echo # !date! !time! %0 !ocvIcoFileName! ========================================
) 1>&2
:echo cd=!cd!
@rem if exist "!ocvMdlDirPath!/!ocvIcoNameDirName!" rmdir /s /q "!ocvMdlDirPath!/!ocvIcoNameDirName!"
goto :eof

:L_mkCascadeDetect
title コマンドプロンプト - !ocvThisName! mkCascadeDetect.py
call .\venv\Scripts\activate
@rem python mkCascadeDetect.py
deactivate
goto :eof

2019年6月6日木曜日

arrowsTest.bat

@if(0)==(0) echo off
@rem http://computer-technology.hateblo.jp/entry/20131025/p1
setlocal
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

@rem Description:
@rem Test the message arrow of PlantUML sequence diagram.

@rem Usage:
@rem arrowsTest.bat <arrowGroupNumber>

@rem Options:
@rem   arrowGroupNumber
@rem     1 : "->" group.
@rem     2 : "-/" group.
@rem     3 : "-\" group.

@rem ####################
@rem Batch.
@rem ####################

set "DebugPrint=false"

@rem ....................
@rem Batch main.
@rem ....................
set rv=11
if "!DebugPrint!"=="true" call :L_BAT_Output_Args %*
call :Lc_JS %*

@rem ....................
@rem Exit.
@rem ....................
@rem echo.
@rem pause
@rem echo Press any key to exit.
@rem pause>nul
exit /b !rv!
goto :eof


@rem ....................
@rem Output Args.
@rem ....................
:L_BAT_Output_Args
@rem echo BAT %0 %* ....................
set /a y=0
for %%z in (
  %*
) do (
  set /a y=!y!+1
  echo BAT %%!y!=%%~z.
)
set /a rv=0
goto :eof


@rem ....................
@rem Call JScript.
@rem ....................
:Lc_JS
if "!DebugPrint!"=="true" echo BAT %0 %* ....................j
set "jsargs=%*"
if "!jsargs!"=="" (
  cscript.exe //nologo //e:JScript "%~f0"
) else (
  cscript.exe //nologo //e:JScript "%~f0" !jsargs!
)
if "!DebugPrint!"=="true" call :L_echoErrorLevel
goto :eof


@rem ....................
@rem Echo ErrorLevel.
@rem ....................
:L_echoErrorLevel
@rem echo BAT L_echoErrorLevel ....................
echo BAT %0 errorlevel=!errorlevel!
@rem echo.
goto :eof


@end


// ####################
// JScript.
// ####################


var DebugPrint = false;

var fso = new ActiveXObject("Scripting.FileSystemObject");


// ....................
// Output Args.
// ....................
function Output_Args(jsargs) {
//  WScript.Echo("JS Output_Args ....................");
  WScript.Echo("JS [" + jsargs.length + "]" + jsargs + ".");
  for (var idx = 0; idx < jsargs.length; ++idx) {
    WScript.Echo("JS Args[" + idx + "]=" + jsargs[idx] + ".");
  }
  return 0;
}


// ....................
// Unknown arg.
// ....................
function UnknownArg(jsargs) {
  WScript.Echo("JS UnknownArg ....................");
  Output_Args(jsargs);
  return 1;
}


// ....................
// arrowsTest : Test the message arrow of PlantUML sequence diagram.
// ....................
function arrowsTest(jsargs) {
  if (DebugPrint == true) {
    WScript.Echo("JS arrowsTest ....................");
    Output_Args(jsargs);
  }

  // message arrow shape pattern.
  var arrowGroups = [
    [],
    [ // arrowGroup 1.
      [ // arrowType
        "->",
        "<-",
        "<->",
      ],
      [
        "->>",
        "<<-",
        "<<->>",
      ],
    ],
    [ // arrowGroup 2.
      [
        "-/",
        "/-",
        "/-/",
      ],
      [
        "-//",
        "//-",
        "//-//",
      ],
    ],
    [ // arrowGroup 3.
      [
        "-\\",
        "\\-",
        "\\-\\",
      ],
      [
        "-\\\\",
        "\\\\-",
        "\\\\-\\\\",
      ],
    ],
  ];

  // message arrow symbol pattern.
  var symbols = [
    ["",  "" ],
    ["o", "" ],
    ["",  "o"],
    ["o", "o"],
    ["x", "" ],
    ["",  "x"],
    ["x", "x"],
    ["o", "x"],
    ["x", "o"],
  ];

  // Classes at both ends of the arrow.
  var classes = {
    ""  : ["Bob",   "Alice"  ],
    "o" : ["Bob_o", "Alice_o"],
    "x" : ["Bob_x", "Alice_x"]
  };


//   Start definition of sequence diagram.
  WScript.Echo("@startuml");

  WScript.Echo("participant Bob_x");
  WScript.Echo("participant Bob_o");
  WScript.Echo("participant Bob");
  WScript.Echo("participant Alice");
  WScript.Echo("participant Alice_o");
  WScript.Echo("participant Alice_x");
  WScript.Echo("");

  WScript.Echo("note over Bob_x, Alice_x");
  WScript.Echo("  There are no arrows starting with x in the sequence diagram.");
  WScript.Echo("  PlantUML will follow the instructions.");
  WScript.Echo("end note");
  WScript.Echo("");

//   for (var arrowGroupNumber in arrowGroups) {
  var arrowGroupNumber = jsargs[0];
    for (var arrowTypeIdx in arrowGroups[arrowGroupNumber]) {
      WScript.Echo("== " + arrowGroups[arrowGroupNumber][arrowTypeIdx][0].replace(/\\/g, "\\\\") + " ==");
      for (var symbolIdx in symbols) {
        for (var arrowShapeIdx in arrowGroups[arrowGroupNumber][arrowTypeIdx]) {
          var arrowShape = ""
              + symbols[symbolIdx][0]
              + arrowGroups[arrowGroupNumber][arrowTypeIdx][arrowShapeIdx]
              + symbols[symbolIdx][1]
              ;

          var msgCmd = sprintf("%-9s %-9s %-9s",
              classes[symbols[symbolIdx][0]][0],
              arrowShape,
              classes[symbols[symbolIdx][1]][1]);
          var msgTxt = msgCmd.replace(/ +/g, " ").replace(/ +$/g, "");

          WScript.Echo(sprintf("%s : %d-%d-%d : %s()",
              msgCmd,
              (parseInt(arrowGroupNumber) - 1) * 2 + 1 + parseInt(arrowTypeIdx),
              symbolIdx, arrowShapeIdx, msgTxt));
        }
      }
//     }
        WScript.Echo("|||");
        WScript.Echo("");
  }

  WScript.Echo("note over Bob_x, Alice_x");
  WScript.Echo("Drawn by PlantUML version:");
  WScript.Echo(getPlantUmlVersion());
  WScript.Echo("end note");
  WScript.Echo("");

//   Finish defining the sequence diagram.
  WScript.Echo("@enduml");

  return 0;
}


// https://kujirahand.com/blog/index.php?JScript%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C
function getPlantUmlVersion() {
  var shell = new ActiveXObject("WScript.Shell");
  // コマンドを実行
  var oe = shell.Exec("java -jar plantuml.jar -v");
  var r = oe.StdErr.ReadAll();
  return r;
}


// https://qiita.com/akinomyoga/items/ccd58731743aa37e0538
// agh.sprintf.js
/* ----------------------------------------------------------------------------

 Author: K. Murase (akinomyoga)

 Changes

 * 2015-05-29 KM created git repository
 * 2014-12-25 KM 様々な言語での実装を確認
 * 2013-09-05 KM added descriptions
 * 2013-09-01 KM first version
 * 2013-09-01 KM created

 ------------------------------------------------------------------------------

 License: The MIT License (MIT)

 Copyright (c) 2013-2015 K. Murase (akinomyoga)

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

 ----------------------------------------------------------------------------*/

/**
 *  @section sprintf.format 書式指定
 *    書式は以下の形式で指定する。
 *    '%' \<pos\>? \<flag\> \<width\> \<precision\>? \<type\>? \<conv\>
 *
 *    位置指定子   \<pos\>       は引数の番号を指定する。
 *    フラグ       \<flag\>      は出力の見た目を細かく指定する。
 *    幅           \<width\>     は出力時の最小文字数を指定する。
 *    精度         \<precision\> は内容をどれだけ詳しく出力するかを指定する。
 *    サイズ指定子 \<type\>      は引数のサイズ・型を指定する。
 *    変換指定子   \<conv\>      は出力する形式を指定する。
 *
 *  @subsection sprintf.format.pos 位置指定子 (POSIX)
 *    位置指定子は以下の形式を持つ。
 *    \<pos\> := /\d+\$/
 *    整数で引数の番号を指定する。書式指定文字列の次に指定した引数の番号が 1 である。
 *
 *  @subsection sprintf.format.flag フラグ
 *    フラグは以下の形式を持つ。
 *    \<flag\> := ( /[-+ 0#']/ | /\=./ ) +
 *
 *    '-'  (標準)    左寄せを意味する。既定では右寄せである。
 *    '+'  (標準)    非負の数値に正号を付ける事を意味する。
 *    '#'  (標準)    整数の場合、リテラルの基数を示す接頭辞を付ける。
 *                   但し、値が 0 の時は接頭辞を付けない。
 *                   conv = o, x, X のそれぞれに対して "0", "0x", "0X" が接頭辞となる。
 *
 *                   浮動小数点数 conv = f, F, e, E, g, G, a, A の場合は、
 *                   整数 (precision = 0) に対しても小数点を付ける (例 "123.") 事を意味する。
 *                   conv = g, G については小数末尾の 0 の連続を省略せずに全て出力する。
 *    ' '  (標準)    非負の数値の前に空白を付ける事を意味する。
 *                   これは出力幅が width で指定した幅を超えても必ず出力される空白である。
 *    '0'  (標準)    左側の余白を埋めるのに 0 を用いる。但し、空白と異なり 0 は符号や基数接頭辞の右側に追加される。
 *    "'"  (SUSv2)   conv = d, i, f, F, g, G の整数部で桁区切 (3桁毎の ",") を出力する事を意味する。
 *                   但し、flag 0 で指定される zero padding の部分には区切は入れない。
 *
 *    参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
 *    '=?' (strfmon) 余白に使う文字の指定
 *    ','  (Python)  桁区切。→ "'" (SUSv2) に同じ
 *                   (+ Java, Python-3.1)
 *    '<'  (Python)  左寄せ。'?<' として余白文字を指定できる。
 *                   → '-' (標準) に同じ
 *    '>'  (Python)  右寄せ。'?>' として余白文字を指定できる。
 *                   → 既定 (標準)
 *    '^'  (Python)  中央揃え。'?^' として余白文字を指定できる。
 *    '='  (Python)  整数型において、符号の後に padding を挿入する
 *                   →これは %.3d 等とする事に等価である。
 *    '-'  (Python)  負号のみ表示 → 既定 (標準)
 *    "'?" (PHP)     余白文字の指定。
 *    '('  (Java)    負の数を "()" で括る。
 *
 *  @subsection sprintf.format.width 幅指定子
 *    幅指定子は以下の形式を持つ。
 *    \<width\> := /\d+/ | '*' | '*' /\d+/ '$'
 *
 *    /\d+/         (標準)  最小幅を整数で指定する。
 *    '*'           (標準)  次の引数を読み取って最小幅とする。
 *    '*' /\d+/ '$' (POSIX) 指定した番号の引数を最小幅とする。
 *
 *  @subsection sprintf.format.precision 精度指定子
 *    精度指定子は以下の形式を持つ。
 *    \<precision\> := /\d+/ | '*' | '*' /\d+/ '$'
 *
 *    /\d+/         (標準)  精度を整数で指定する。
 *    '*'           (標準)  次の引数を読み取って精度とする。
 *    '*' /\d+/ '$' (POSIX) 指定した番号の引数を精度とする。
 *
 *    整数の場合は精度で指定した桁だけ必ず整数を出力する。例えば、精度 4 の場合は "0001" など。
 *    精度を指定した時はフラグで指定した '0' は無視される。
 *
 *    浮動小数点数 conv = f, F, e, E, a, A の場合は小数点以下の桁数を指定する。
 *    浮動小数点数 conv = g, G の場合は有効桁数を指定する。
 *    conv = f, F, e, E, g, G に対しては既定値は 6 である。
 *    conv = a, A については倍精度浮動小数点数の16進桁数である 13 が既定値である。
 *
 *    文字列の場合は最大出力文字数を指定する。この文字数に収まらない部分は出力されずに無視される。
 *
 *  @subsection sprintf.format.type サイズ指定子
 *    サイズ指定子は以下の何れかである。
 *
 *          + --------- 整数 ---------- + ------- 浮動小数点数 ------- + -------- 文字 ---------- +
 *          | 本来      (規格)  実装 註 | 本来        (規格)   実装 註 | 本来    (規格)   実装 註 |
 *    ----- + ------------------------- + ---------------------------- + ------------------------ +
 *    既定  | int       (標準) double#1 | 既定        (標準) double    | 既定    (標準) unicode   |
 *    'hh'  | char      (C99)    8bit   | float       (agh)   float#4  | char    (agh)    ascii   |
 *    'h'   | short     (標準)  16bit   | float       (agh)   float#4  | char    (MSVC)   ascii   |
 *    'l'   | long      (標準)  32bit   | double      (C99)  double    | wint_t  (C99)  unicode#6 |
 *    'll'  | long long (C99)   32bit   | long double (agh)  double#5  | --      --          --   |
 *    't'   | ptrdiff_t (C99)   32bit#2 | --          --         --    | --      --          --   |
 *    'z'   | size_t    (C99)   32bit#2 | --          --         --    | --      --          --   |
 *    'I'   | ptrdiff_t (MSVC)  32bit#2 | --          --         --    | --      --          --   |
 *          | size_t                    | --          --         --    | --      --          --   |
 *    'I32' | 32bit     (MSVC)  32bit   | --          --         --    | --      --          --   |
 *    'q'   | 64bit     (BSD)   64bit#3 | --          --         --    | --      --          --   |
 *    'I64' | 64bit     (MSVC)  64bit#3 | --          --         --    | --      --          --   |
 *    'j'   | intmax_t  (C99)  double#1 | --          --         --    | --      --          --   |
 *    'L'   | --        --         --   | long double (標準) double#5  | --      --          --   |
 *    'w'   | --        --         --   | long double (agh)  double#5  | wchar_t (MSVC) unicode   |
 *    ----- + ------------------------- + ---------------------------- + ------------------------ +
 *
 *    #1 JavaScript の数値は内部的には double なので、
 *       サイズ指定子を省略した場合はこの double で表現される整数として変換を行う。
 *    #2 JavaScript で 64bit 整数は厳密に取り扱う事が出来ないので、32bit を native な整数とする。
 *    #3 JavaScript では 64bit 整数は厳密に取り扱う事が出来ない。
 *       取り敢えず 64bit 整数として出力はするものの、巨大な整数では下の方の桁が正確ではない。
 *
 *    #4 規格にないが独自拡張で、h/hh が指定された時は float の精度に落としてから出力する。
 *       (C 言語では float の可変長引数は double に変換されるからそもそも float で指定できない)。
 *    #5 規格上は long double だが JavaScript では long double は取り扱えないので、
 *       double と同じ取扱とする。
 *
 *    #6 POSIX を見ると %lc の引数は wchar_t[2] { wint_t(), null } と書かれている気がする? [要確認]
 *
 *    参考: 以下の様な野良サイズ指定子もある。
 *    'n'  (Ocaml)    native int
 *
 *  @subsection sprintf.format.conv 変換指定子
 *    引数の型及び出力の形式を指定する。以下の何れかの値を取る。
 *
 *    'd', 'i' (標準) 10進符号付き整数
 *    'o'      (標準)  8進符号無し整数
 *    'u'      (標準) 10進符号無し整数
 *    'x', 'X' (標準) 16進符号無し整数     (lower/upper case, 0xa/0XA など)
 *    'f', 'F' (標準) 浮動小数点数         (lower/upper case, inf/INF など)
 *    'e', 'E' (標準) 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
 *    'g', 'G' (標準) 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
 *    'a', 'A' (C99)  浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
 *    'c'      (標準) 文字
 *         'C' (XSI)  文字   (本来 wchar_t 用だがこの実装では c と区別しない)
 *    's'      (標準) 文字列
 *         'S' (XSI)  文字列 (本来 wchar_t 用だがこの実装では s と区別しない)
 *    'p'      (標準) ポインタ値。この実装では upper hexadecimal number で出力。
 *    'n'      (標準) 今迄の出力文字数を value[0] に格納
 *    '%'      (標準) "%" を出力
 *
 *    参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
 *    'b'      (Ruby)   2進符号付き整数。(+ Python, Perl, PHP, D, Haskell)
 *                      (Go) では浮動小数点数に対して decimalless scientific notation with 2進指数
 *    'B'      (Ruby)   2進符号付き整数。(+ Python, Perl)
 *    'n'      (Python) 数値。ロカールに従った出力を行う(桁区切など)。
 *    '%'      (Python) 百分率。数値を百倍して解釈し 'f' 変換指定子で出力する。
 *    'D'      (Perl)   'ld' に同じ。
 *    'U'      (Perl)   'lu' に同じ。
 *    'O'      (Perl)   'lo' に同じ。
 *    'U'      (Go)     'U+%04d' に同じ。Unicode code point の為。
 *    't'      (Go)     true/false
 *    'b', 'B' (Java)   true/false (+ OCaml)
 *    'h', 'H' (Java)   null/'%x'
 *
 *    'q'      (Bash)   文字/文字列をリテラル (quoted string) として出力。 (+ Go Lua)
 *                      Go では文字(整数)は '' で、文字列は "" で囲む。Lua では '' で囲む。
 *    'C'      (OCaml)  文字リテラル '' として出力
 *    'S'      (OCaml)  文字列リテラル "" として出力
 *    'T'      (Go)     typename
 *    'v'      (Go)     default format (+ Haskell)
 *    'p'      (Ruby)   Object#inspect の結果を載せる。
 *
 *    'n'      (Java)   改行
 *    'a', 't' (OCaml)  ? (二つ引数を取って、引数2を引数1に対し出力?)
 *    ','      (OCaml)  何も出力しない
 *    '@'      (OCaml)  '@' を出力。
 *    '!'      (OCaml)  出力先を flush する。
 *
 *  @subsection sprintf.format.ref References
 *    Wikipedia en    <a href="https://en.wikipedia.org/wiki/Printf_format_string">printf format string - Wikipedia</a>
 *    POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html">printf</a>
 *    POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html#tag_05">File Format Notation</a>
 *    POSIX printf(3) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html">fprintf</a>
 *    MSC   位置指定子 <a href="http://msdn.microsoft.com/ja-jp/library/bt7tawza(v=vs.90).aspx">printf_p の位置指定パラメータ</a>
 *    MSC   サイズ指定子 <a href="http://msdn.microsoft.com/ja-jp/library/vstudio/tcxf1dw6.aspx">サイズ指定</a>
 *
 *    Python   [[6.1. string ? 一般的な文字列操作 ? Python 3.4.2 ドキュメント>http://docs.python.jp/3/library/string.html#format-specification-mini-language]]
 *    PHP      [[PHP: sprintf - Manual>http://php.net/manual/ja/function.sprintf.php]]
 *    Perl     [[sprintf - perldoc.perl.org>http://perldoc.perl.org/functions/sprintf.html]]
 *    D言語    [[std.format - D Programming Language - Digital Mars>http://dlang.org/phobos/std_format.html#format-string]]
 *    Lua      [[Lua 5.1 Reference Manual>http://www.lua.org/manual/5.1/manual.html#pdf-string.format]]
 *    Haskell  [[Text.Printf>http://hackage.haskell.org/package/base-4.7.0.2/docs/Text-Printf.html]]
 *    Go       [[fmt - The Go Programming Language>http://golang.org/pkg/fmt/]]
 *    Java     [[Formatter (Java Platform SE 7 )>http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax]]
 *    R (wrapper for C printf) [[sprintf {base} | inside-R | A Community Site for R>http://www.inside-r.org/r-doc/base/sprintf]]
 *    OCaml    [[Printf>http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html]]
 */

/*
 * その他の書式指定の文法について
 * - terminfo の setaf 等で使われている文法について
 *   %? %t %e %; 条件分岐
 *   %| %! %- %< 演算子
 *   %{ ... } リテラル
 * - date コマンド
 * - strfmod
 * - zsh PS1
 * - GNU screen
 */

// 実装:
// * 解析は正規表現を使えば良い。
// * 出力結果の構成
//   <左余白> <符号> <ゼロ> <中身> <右余白>
//   計算の順番としては、<符号>+<中身> のペアを決定してから、<ゼロ> または <余白> を付加すれば良い。

(function(__exports) {
  // 本来 this にグローバルオブジェクトが入るはず。
  // もし空だった場合はこのスクリプトを呼び出したときの this を入れる。
  var __global = this || __exports || {};
  if (typeof __global.agh !== 'undefined')
    __exports = __global.agh;
  else if (typeof __global.module !== 'undefined' && typeof __global.module.exports != 'undefined')
    __exports = __global.module.exports;
  else if (__exports == null)
    __exports = __global.agh = {};

  function repeatString(s, len) {
    if (len <= 0) return "";
    var ret = "";
    do if (len & 1) ret += s; while ((len >>= 1) >= 1 && (s += s));
    return ret;
  }

  //---------------------------------------------------------------------------
  // サイズ指定子達

  var INT32_MOD = 0x100000000;
  var INT32_MIN = -0x80000000;
  var INT32_MAX = +0x7FFFFFFF;
  var INT64_MOD = INT32_MOD * INT32_MOD;
  var INT64_MIN = -INT64_MOD / 2.0;
  var INT64_MAX = -INT64_MIN - 1;

  function roundTowardZero(value) {
    return value < 0 ? Math.ceil(value) : Math.floor(value);
  }

  function getIntegerValue(value, type) {
    // 整数は内部的には double で表現されている。
    // ビット演算は 32bit 符号付整数として実行される。
    value = roundTowardZero(value);
    switch (type) {
    case 'hh': // C99 char (8bit signed)
      value &= 0xFF;
      return value >= 0x80 ? value - 0x100 : value;
    case 'h': // short (16bit signed)
      value &= 0xFFFF;
      return value >= 0x8000 ? value - 0x10000 : value;
    case 'l':   // C89  long (32bit signed) (ビット演算を使うと変になる)
    case 'z':   // C99  size_t
    case 't':   // C99  ptrdiff_t
    case 'I32': // MSVC __int32
    case 'I':   // MSVC ptrdiff_t/size_t
      value %= INT32_MOD;
      if (value < INT32_MIN)
        value += INT32_MOD;
      else if (value > INT32_MAX)
        value -= INT32_MOD;
      return value;
    case 'll':  // C99 long long (64bit signed)
    case 'I64': // MSVC __int32
    case 'q':   // BSD  quad word
    case 'L':   // agh exntesion
      value %= INT64_MOD;
      if (value < INT64_MIN)
        value += INT64_MOD;
      else if (value > INT64_MAX)
        value -= INT64_MOD;
      return value;
    case 'j': default: // 変換無し (double の整数)
      return value;
    }
  }

  function getUnsignedValue(value, type) {
    // 整数は内部的には double で表現されている。
    // ビット演算は 32bit 符号付整数として実行される。
    value = roundTowardZero(value);
    switch (type) {
    case 'hh': // 8bit unsigned
      value &= 0xFF;
      return value;
    case 'h': // 16bit unsigned
      value &= 0xFFFF;
      return value;
    case 'l':   // C89  long (32bit unsigned) (ビット演算を使うと変になる)
    case 'z':   // C99  size_t
    case 't':   // C99  ptrdiff_t
    case 'I32': // MSVC __int32
    case 'I':   // MSVC ptrdiff_t/size_t
      value %= INT32_MOD;
      return value < 0 ? value + INT32_MOD : value;
    case 'll':  // C99 long long (64bit unsigned)
    case 'I64': // MSVC __int32
    case 'q':   // BSD  quad word
    case 'L':   // agh exntesion
      value %= INT64_MOD;
      return value < 0 ? value + INT64_MOD : value;
    case 'j': default: // double の整数の 2 の補数??
      if (value < 0) {
        // 例 -0x80 ~ -0x41 → 7 ~ 6+epsilon → nbits = 8, mod = 0x100
        var nbits = value < INT32_MIN ? 1 + Math.ceil(Math.LOG2E * Math.log(-value)) : 32;
        var mod = Math.pow(2, nbits);
        value += mod;
      }
      return value;
    }
  }

  function getFloatValue(value, type) {
    if (type === 'h' || type === 'hh') {
      var sgn = value < 0 ? -1 : 1;
      var exp = Math.floor(Math.LOG2E * Math.log(sgn * value));
      var scale = Math.pow(2, exp - 23); // float (exp = 0) は小数点以下2進23桁まで有効
      value = (0 | value / scale) * scale;
    }

    return value;
  }

  function getCharValue(value, type) {
    value |= 0;
    if (type === 'h' || type === 'hh') {
      value &= 0xFF;
    }
    return value;
  }

  //---------------------------------------------------------------------------
  // 変換指定子達

  /**
   * @section \<conv\>
   *   引数の型及び出力の形式を指定します。
   * - 'd', 'i' 10進符号付き整数
   * - 'o'       8進符号無し整数
   * - 'u'      10進符号無し整数
   * - 'x', 'X' 16進符号無し整数
   */

  var groupIntegerRegs = [
    /(...)(?!$)/g,
    /(^.|...)(?!$)/g,
    /(^..|...)(?!$)/g
  ];
  function groupInteger(text, flag) {
    if (text.length < 4 || !/\'/.test(flag))
      return text;
    else
      return text.replace(groupIntegerRegs[text.length % 3], "$1,");
  }

  var xdigits = "0123456789abcdef";
  function convertInteger(value, flag, precision, base) {
    var out = '';
    do {
      out = xdigits.charAt(value % base) + out;
      value = Math.floor(value / base);
    } while (value > 0);

    if (precision != null)
      out = repeatString('0', precision - out.length) + out;

    return out;
  }
  function convertDecimal(value, flag, precision, type) {
    return groupInteger(convertInteger(value, flag, precision, 10), flag);
  }
  function convertOctal(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 8);
  }
  function convertLowerHex(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 16);
  }
  function convertUpperHex(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 16).toUpperCase();
  }

  /**
   * - 'f', 'F' 浮動小数点数         (lower/upper case, inf/INF など)
   * - 'e', 'E' 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
   * - 'g', 'G' 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
   * - 'a', 'A' 浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
   */

  var logTable = [];
  logTable[ 2] = Math.LOG2E;
  logTable[10] = Math.LOG10E;
  logTable[16] = Math.LOG2E / 4;
  function frexp(value, base) {
    if (value === 0) return [0, 0];

    var exp = 1 + Math.floor(logTable[base] * Math.log(value));
    value = value * Math.pow(base, -exp);

    // 際どいずれが起きるので補正
    if (value * base < 1) {
      value *= base;
      exp--;
    } else if (value >= 1) {
      value /= base;
      exp++;
    }

    return [value, exp];
  }

  var regCarryReach = []; // 末尾の 9 の並び, 繰上到達距離測定用
  regCarryReach[10] = /9*$/;
  regCarryReach[16] = /f*$/;
  function generateFloatingSequence(value, precision, base) {
    // value [0, 1) の数値
    var seq = '';
    while (--precision > 0)
      seq += xdigits.charAt(0 | (value = value * base % base));

    // 最後の数字は四捨五入
    // (0-10 の整数になるので繰り上がり処理が必要)
    var last = Math.round(value * base % base);
    if (last == base) {
      var cd = regCarryReach[base].exec(seq)[0].length;
      if (cd < seq.length) {
        // 繰り上がり
        var iinc = seq.length - cd - 1;
        seq = seq.slice(0, iinc) + xdigits.charAt(1 + (0 | seq.charAt(iinc))) + repeatString('0', cd + 1);
      } else {
        // 全て 9 の時 → exp更新, seq = 1000...
        seq = '1' + repeatString('0', cd + 1);
      }
    } else {
      seq += xdigits.charAt(last);
    }
    return seq;
  }

  function omitTrailingZero(text, flag) {
    return text.replace(/(\.[\da-f]*?)0+$/, function($0, $1) {
      if ($1 && $1.length > 1)
        return $1;
      else
        return /#/.test(flag) ? '.' : '';
    });
  }
  function omitTrailingZeroE(text, flag) {
    return text.replace(/(\.\d*?)0+e/, function($0, $1) {
      if ($1 && $1.length > 1)
        return $1 + 'e';
      else
        return /#/.test(flag) ? '.e' : 'e';
    });
  }

  function convertScientific(value, flag, precision, type) { // conv = e E
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null) precision = 6;

    var buff = frexp(value, 10);
    var fr = buff[0], exp = buff[1] - 1;
    var man = generateFloatingSequence(fr, 1 + precision, 10);
    if (man.length > precision + 1) {
      // 99..99 から 100..00 に繰り上がった時
      man = man.slice(0, -1);
      exp++;
    }

    if (precision > 0 || /#/.test(flag))
      man = man.slice(0, 1) + '.' + man.slice(1);

    if (exp < 0)
      exp = 'e-' + (1000 - exp).toString().slice(1);
    else
      exp = 'e+' + (1000 + exp).toString().slice(1);
    return man + exp;
  }
  function convertScientificHex(value, flag, precision, type) { // conv = a A
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null)
      precision = type === 'h' || type === 'hh' ? 6 : 13;

    var buff = frexp(value, 2);
    var fr = buff[0], exp = buff[1] - 1;
    var man = generateFloatingSequence((1 / 8) * fr, precision + 1, 16);
    if (man.length > precision + 1) {
      man = man.slice(0, -1);
      exp++;
    }

    if (man.length > 1 || /#/.test(flag))
      man = man.slice(0, 1) + '.' + man.slice(1);

    man = omitTrailingZero(man, flag);

    if (exp < 0)
      exp = 'p-' + (1000 - exp).toString().slice(1);
    else
      exp = 'p+' + (1000 + exp).toString().slice(1);
    return man + exp;
  }
  function convertFloating(value, flag, precision, type) { // conv = f F
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null) precision = 6;

    if (value >= 1.0) {
      var buff = frexp(value, 10);
      var fr = buff[0], exp = buff[1];
    } else {
      var fr = value / 10, exp = 1;
    }

    var man = generateFloatingSequence(fr, exp + precision, 10);
    if (precision > 0 || /#/.test(flag)) {
      var point = man.length - precision;
      man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point);
    } else
      man = groupInteger(man, flag);

    return man;
  }
  function convertCompact(value, flag, precision, type) { // conv = g G
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null)
      precision = 6;
    else if (precision < 1)
      precision = 1;

    if (value < 1e-4 || Math.pow(10, precision) <= value + 0.5) {
      // scientific
      var result = convertScientific(value, flag, precision - 1, type);
      if (/#/.test(flag))
        return result;
      else
        return omitTrailingZeroE(result, flag);
    } else {
      // floating point
      var buff = frexp(value, 10);
      var fr = buff[0], exp = buff[1];

      if (precision < 1) precision = 1;
      var man = generateFloatingSequence(fr, precision, 10);
      var point = man.length - (precision - exp); // 小数点挿入位置。末端からの位置が繰り上がり不変。
      // assert(exp <= precision);
      // assert(man.length == precision || man.length == precision + 1)
      // assert(point <= man.length);
      if (point > 0) {
        if (point < man.length || /#/.test(flag))
          man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point, precision);
      } else {
        man = '0.' + repeatString('0', -point) + man.slice(0, precision);
      }

      if (/#/.test(flag))
        return man;
      else
        return omitTrailingZero(man, flag);
    }
  }

  function convertCompactU      (value, flag, precision, type) { return convertCompact      (value, flag, precision, type).toUpperCase(); }
  function convertFloatingU     (value, flag, precision, type) { return convertFloating     (value, flag, precision, type).toUpperCase(); }
  function convertScientificU   (value, flag, precision, type) { return convertScientific   (value, flag, precision, type).toUpperCase(); }
  function convertScientificHexU(value, flag, precision, type) { return convertScientificHex(value, flag, precision, type).toUpperCase(); }

  /**
   * - 'c', 'C' 文字
   * - 's', 'S' 文字列
   * - 'n' 今迄の出力文字数を value[0] に格納
   * - '%' % を出力
   */

  function convertChar(value, flag, precision, type) {
    return String.fromCharCode(value);
  }
  function convertString(value, flag, precision, type) {
    if (value == null)
      value = value === undefined ? '(undefined)' : '(null)';
    else
      value = value.toString();

    if (precision != null)
      value = value.slice(0, precision);

    return value;
  }
  function convertOutputLength(value, flag, precision, type, outputLength) { // conv = n
    value[0] = getIntegerValue(outputLength, type);
    return '';
  }
  function convertEscaped(value, flag, precision, type) { return '%'; }

  //---------------------------------------------------------------------------

  function prefixOctal(flag)      { return /#/.test(flag) ? '0'  : ''; }
  function prefixLHex(flag)       { return /#/.test(flag) ? '0x' : ''; }
  function prefixUHex(flag)       { return /#/.test(flag) ? '0X' : ''; }
  function prefixFloatLHex(flag)  { return '0x'; }
  function prefixFloatUHex(flag)  { return '0X'; }
  function prefixPointerHex(flag) { return '0x'; }

  var conversions = {
    d: {getv: getIntegerValue , integral: true , signed: true , prefix: null            , conv: convertDecimal       },
    i: {getv: getIntegerValue , integral: true , signed: true , prefix: null            , conv: convertDecimal       },
    u: {getv: getUnsignedValue, integral: true , signed: false, prefix: null            , conv: convertDecimal       },
    o: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixOctal     , conv: convertOctal         },
    x: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixLHex      , conv: convertLowerHex      },
    X: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixUHex      , conv: convertUpperHex      },
    e: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertScientific    },
    E: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertScientificU   },
    f: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertFloating      },
    F: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertFloatingU     },
    g: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertCompact       },
    G: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertCompactU      },
    a: {getv: getFloatValue   , integral: false, signed: true , prefix: prefixFloatLHex , conv: convertScientificHex },
    A: {getv: getFloatValue   , integral: false, signed: true , prefix: prefixFloatUHex , conv: convertScientificHexU},
    c: {getv: getCharValue    , integral: false, signed: false, prefix: null            , conv: convertChar          },
    C: {getv: getCharValue    , integral: false, signed: false, prefix: null            , conv: convertChar          },
    s: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertString        },
    S: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertString        },
    p: {getv: getUnsignedValue, integral: false, signed: false, prefix: prefixPointerHex, conv: convertUpperHex      },
    n: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertOutputLength  },
    '%': {noValue: true       , integral: false, signed: false, prefix: null            , conv: convertEscaped       }
  };

  function printf_impl(fmt) {
    // ※arguments の fmt を除いた部分の番号は 1 から始まり、
    //   位置指定子も 1 から始まるので、位置番号はそのまま arguments の添字に指定して良い。

    var args = arguments;
    var aindex = 1;
    var lastIndex = 0;
    var outputLength = 0;
    var output = fmt.replace(/%(?:(\d+)\$)?([-+ 0#']*)(\d+|\*(?:\d+\$)?)?(\.(?:\d+|\*(?:\d+\$)?)?)?(hh|ll|I(?:32|64)?|[hlLjztqw])?(.|$)/g, function($0, pos, flag, width, precision, type, conv, index) {
      outputLength += index - lastIndex;
      lastIndex = index + $0.length;

      if ((conv = conversions[conv]) == null) {
        var ret = '(sprintf:error:' + $0 + ')';
        outputLength += ret.length;
        return ret;
      }

      pos =
        (pos == null || pos === "") ? null :
        pos === '*' ? 0 | args[aindex++] :
        0 | pos;

      width =
        (width == null || width === "") ? 0 :
        width === '*' ? 0 | args[aindex++]:
        width.charAt(0) === '*' ? args[0 | width.slice(1, -1)] :
        0 | width;

      precision =
        (precision == null || precision === "") ? null:
        precision === '.*' ? 0 | args[aindex++]:
        precision.charAt(1) === '*' ? args[0 | precision.slice(2, -1)] :
        0 | precision.slice(1);

      var value = conv.noValue ? null: pos === null ? args[aindex++] : args[pos];
      if (conv.getv) value = conv.getv(value, type);

      var prefix = '';
      if (conv.signed) {
        if (value < 0) {
          prefix = '-';
          value = -value;
        } else if (/\+/.test(flag))
          prefix = '+';
        else if (/ /.test(flag))
          prefix = ' ';
      }
      if (conv.prefix && value != 0)
        prefix += conv.prefix(flag);

      var body = conv.conv(value, flag, precision, type, outputLength);

      var lpad = '', zero = '', rpad = '';
      width -= prefix.length + body.length;
      if (width >= 1) {
        if (/-/.test(flag)) {
          // POSIX に従うと - の方が優先
          rpad = repeatString(' ', width);
        } else if (/0/.test(flag) && (!conv.integral || precision == null)) {
          zero = repeatString('0', width);
        } else
          lpad = repeatString(' ', width);
      }

      var ret = lpad + prefix + zero + body + rpad;
      outputLength += ret.length;
      return ret;
    });
    outputLength += fmt.length - lastIndex;

    return [outputLength, output];
  }

  __exports.sprintf = function sprintf() {
    var result = printf_impl.apply(this, arguments);
    return result[1];
  };

  __exports.vsprintf = function vsprintf(fmt, args) {
    var result = printf_impl.apply(this, [fmt].concat(args));
    return result[1];
  };

  var stdout = null;
  if (__global.agh && __global.printh)
    stdout = function(text) { printh(agh.Text.Escape(text, 'html')); };
  else if (__global.process && __global.process.stdout)
    stdout = function(text) { process.stdout.write(text); };
  else if (__global.console && __global.console.log)
    stdout = function(text) { console.log(text); };
  else
    stdout = function(text) { document.write(text); };

  __exports.printf = function printf() {
    var result = printf_impl.apply(this, arguments);
    stdout(result[1]);
    return result[0];
  };

  if (__global.agh && __global.agh.scripts)
    __global.agh.scripts.register("agh.sprintf.js");

})(this);

// test
//
// printf("%2$d行目のコマンド %1$sは不正です", "hoge", 20);
// printf("%d(1234) %o(2322) %x(4d2)\n", 1234, 1234, 1234);
// printf("%s(abc) %c(x)\n", "abc", 'x'.charCodeAt(0));
// printf("%*d(   10)", 5, 10);
// printf("%.*s(3)", 3, "abcdef");
// printf("%2d( 3) %02d(03)", 3, 3);
// printf("%1$d:%2$.*3$d:%4$.*3$d(15:035:045)\n", 15, 35, 3, 45);
//
// printf("%%d: [%+10d][%+ 10d][% +10d][%d]", 10, 10, 10, 1e10);
// printf("%%u: [%u][%u][%+u][% u][%-u][%+10u][%-10u]", -1, 10, 10, 10, 10, 10, 10);
// printf("%%x,%%u: %x %o", -1, -1);
// printf("%%a: %a %a %a %a %a %a %a %a %a", 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9);
// printf("%%A: %A %.3A %#.3A", 1e10, 1e10, 1e10);
// printf("%%A: %A %A %A %A", 4096, 2048, 1024, 512);
//
// printf("%%e: %#.3e %#.3e %#.3e", 1e1000, 1e100, 1e10);
// printf("%%e: %#.3e %#.6e %#.10e %#.20e\n", 1.234, 1.234, 1.234, 1.234);
// printf("%%e: %#.1e %#.5e %#.10e %#.100e", 9.999, 9.999, 9.999, 9.999);
// printf("%%f: %f %#g %#f %#.g %f %'f", 1, 1, 1, 1, 1e100, 1e100);
// printf("%%g: %.15g %.15g %#.15g", 1, 1.2, 1.2);
// printf("%%g: %g %.g %#g %#.g", 15, 15, 15, 15);
// printf("%%g: %g %g %g %g %g", 1e-1, 1e-3, 1e-4, 1e-5, 9e-5, 9e-4, 1e10);
// printf("%%#g: %#g %#g %#g %#2g %#6g", 0.1, 1e-5, 1e-4, 1e-4, 1e-4);
// printf("%%#.g: %#.2g %#.2g", 1e-4, 1e-5);
// printf("%%.g: %.g %.g %.g; %.1g %.1g %.1g; %.2g %.3g", 0.1, 0.999, 9.999, 9, 9.9, 9.999, 9.999, 9.999)
//
// printf("%%c: [%c][%c][%c]\n", 1e100, 65, 8);
// printf("%05s %05s\n", 123, "aaa");
// printf("%%p: %p", 512);
// printf("pi: [%1$a][%1$g][%1$'20.9g][%1$020.9g][%1$'020.9g][%2$'020.9g]", Math.PI, Math.PI * 1e3);


// --------------------
// JScript main.
// --------------------
var rv = 0;
var jsargs = new Array();
for (var idx = 0; idx < WScript.Arguments.length; ++idx) {
  jsargs[idx] = WScript.Arguments(idx);
}
var ary = new Array();
ary = jsargs.slice(0, jsargs.length);
if (0 == 1) {
  rv = rv + 1;
} else if (WScript.Arguments.length == 1) {
  rv = rv + arrowsTest(ary);
} else {
  rv = rv + UnknownArg(ary);
}

WScript.quit(rv);