end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

autocadの autolispマクロの練習 - その3

Help Help

AutoCADの PUBLISHコマンドで、複数のdwgを連続してpdf化する為、 予めdir内にあるdwgファイル群の印刷スタイルを白黒 & A3横化

; SETPLOTCFG command
; Set plot configuration for DWG files
; - Printer: AutoCAD PDF (General Documentation).pc3
; - Style table: monochrome.ctb
(defun c:setplotcfg ( / dwgdir files f fullpath )
  (princ "\nSTART SETPLOTCFG()")
  (vl-load-com)

  (setq dwgdir "c:/Users/end0t/dev/AUTOLISP/DWG")

  (setq files (vl-directory-files dwgdir "*.dwg" 1))
  (foreach f files
    (setq fullpath (strcat dwgdir "/" f))
    (set-plot-config fullpath)
  )

  (princ "\nDONE SETPLOTCFG()")
  (princ)
)

; Open DWG and set plot config for non-Model layouts
(defun set-plot-config ( dwgpath / acad docs doc layouts lay lay-name dwgname changed )
  (vl-load-com)

  (setq acad (vlax-get-acad-object))
  (setq docs (vla-get-Documents acad))

  (setq doc (vla-open docs dwgpath))
  (setq dwgname (vla-get-Name doc))
  (setq changed nil)

  (princ (strcat "\n\nDWG: " dwgname))

  (setq layouts (vla-get-Layouts doc))

  (vlax-for lay layouts
    (setq lay-name (vla-get-Name lay))

    (if (/= lay-name "Model")
      (progn
        (princ (strcat "\n  Layout: " lay-name))

        ; Printer/Plotter
        (vla-put-ConfigName lay "AutoCAD PDF (General Documentation).pc3")
        (princ "\n    ConfigName: AutoCAD PDF (General Documentation).pc3")

        ; Paper size: ISO full bleed A3 (420 x 297 mm)
        (vla-put-CanonicalMediaName lay "ISO_full_bleed_A3_(420.00_x_297.00_MM)")
        (princ "\n    PaperSize: ISO full bleed A3 (420 x 297 MM)")

        ; Plot area: Extents (1=Extents)
        (vla-put-PlotType lay 1)
        (princ "\n    PlotType: Extents")

        ; Scale 1:1
        (vla-put-UseStandardScale lay :vlax-true)
        (vla-put-StandardScale lay 16)
        (princ "\n    Scale: 1:1")

        ; Center plot
        (vla-put-CenterPlot lay :vlax-true)
        (princ "\n    CenterPlot: TRUE")

        ; Plot rotation: Landscape (0=0, 1=90, 2=180, 3=270)
        (vla-put-PlotRotation lay 0)
        (princ "\n    PlotRotation: Landscape")

        ; Style table
        (vla-put-StyleSheet lay "monochrome.ctb")
        (princ "\n    StyleSheet: monochrome.ctb")

        ; Use plot styles
        (vla-put-PlotWithPlotStyles lay :vlax-true)
        (princ "\n    PlotWithPlotStyles: TRUE")

        ; Plot lineweights
        (vla-put-PlotWithLineweights lay :vlax-true)
        (princ "\n    PlotWithLineweights: TRUE")

        ; Plot paper space last
        (vla-put-PlotViewportBorders lay :vlax-false)
        (princ "\n    PlotViewportBorders: FALSE")

        (setq changed T)
      )
    )
  )

  (if changed
    (progn
      (vla-save doc)
      (princ "\n  -> Saved.")
    )
  )

  (vla-close doc :vlax-false)
)

autocadの autolispマクロの練習 - その2

Help Help

modelレイヤにある直径18の円を17へ変更。

更に付随する寸法線や、円の直情にある断面を表す破線も移動

(defun c:chgcircle ( / dwgdir files f fullpath )
  (princ "\nSTART CHGCIRCLE()")
  ; ActiveX のサポートに関連がある拡張 AutoLISP 関数を読込み
  (vl-load-com)

  (setq dwgdir "c:/Users/end0t/dev/AUTOLISP/DWG2")

  (setq files (vl-directory-files dwgdir "*.dwg" 1))
  (foreach f files
    (setq fullpath (strcat dwgdir "/" f))
    (change-circle-diameter fullpath)
  )

  (princ "\nDONE CHGCIRCLE()")
  (princ)
)

; modelレイヤにある直径18の円を17へ変更.
; 付随する寸法線も 17へ変更
; 円周上部のDASHED垂直線も中心方向へ0.5移動
(defun change-circle-diameter
       ( dwgpath
         / acad docs doc layouts lay blk obj dwgname
           diameter changed-count circle-centers )

  (vl-load-com)
  ; AutoCAD objectと dwg一覧 objectの取得
  (setq acad (vlax-get-acad-object))
  (setq docs (vla-get-Documents acad))

  (setq doc (vla-open docs dwgpath))
  (setq dwgname (vla-get-Name doc))
  (setq changed-count 0)
  (setq circle-centers nil)

  (princ (strcat "\n\nDWG: " dwgname))

  (setq layouts (vla-get-Layouts doc))

  (vlax-for lay layouts
    (if (= (vla-get-Name lay) "Model")
      (progn
        (princ (strcat "\n Layout: " (vla-get-Name lay)))
        (setq blk (vla-get-Block lay))

        (if blk
          (progn
            ; 直径18の円を探して変更し、中心座標を記録
            (vlax-for obj blk
              (if (= (vla-get-ObjectName obj) "AcDbCircle")
                (progn
                  (setq diameter (* 2.0 (vla-get-Radius obj)))
                  (if (< (abs (- diameter 18.0)) 0.001)
                    (progn
                      ; 中心座標を記録し、sizeを17へ変更
                      (setq circle-centers
                        (cons (vlax-get obj 'Center) circle-centers))
                      (vla-put-Radius obj 8.5)
                      (vla-Update obj)
                      (princ "\n    -> Changed to diameter=17")
                      (setq changed-count (1+ changed-count))
                    )
                  )
                )
              )
            )

            ; 円周上部のDASHED垂直線を移動
            (if circle-centers
              (move-dashed-lines-toward-center blk circle-centers 9.0 0.5)
            )
          )
        )
      )
    )
  )

  (princ (strcat "\n  Changed " (itoa changed-count) " circle(s)"))
  (if (> changed-count 0)
    (progn
      (update-dimension-text blk 18.0 "17")

      (vla-save doc)
      (princ "\n  Saved.")
    )
  )

  (vla-close doc :vlax-false)
)

; 円周上部のDASHED垂直線を中心方向へ移動
; blk: ブロック
; circle-centers: 円の中心座標リスト
; radius: 元の半径(円周上のY座標判定用)
; move-dist: 移動距離
(defun move-dashed-lines-toward-center
       ( blk circle-centers radius move-dist
         / obj center cx cy start-pt end-pt sx sy ex ey
           linetype-name is-vertical is-on-circle-top new-x )

  (vlax-for obj blk
    (if (= (vla-get-ObjectName obj) "AcDbLine")
      (progn
        ; 線種名を取得(DASHEDかどうか)
        (setq linetype-name (strcase (vla-get-Linetype obj)))

        (if (wcmatch linetype-name "*DASHED*")
          (progn
            (setq start-pt (vlax-get obj 'StartPoint))
            (setq end-pt (vlax-get obj 'EndPoint))
            (setq sx (car start-pt))
            (setq sy (cadr start-pt))
            (setq ex (car end-pt))
            (setq ey (cadr end-pt))

            ; 垂直線かどうか判定(X座標がほぼ同じ)
            (setq is-vertical (< (abs (- sx ex)) 0.001))

            (if is-vertical
              (progn
                ; 各円の中心に対してチェック
                (foreach center circle-centers
                  (setq cx (car center))
                  (setq cy (cadr center))

                  ; 円周上部にあるかどうか(Y座標が中心+半径付近)
                  (setq is-on-circle-top
                    (and
                      ; 線のX座標が円周上(中心からradius離れている)
                      (< (abs (- (abs (- sx cx)) radius)) 0.5)
                      ; 線のY座標が円の上部(中心より上)
                      (> sy cy)
                    )
                  )

                  (if is-on-circle-top
                    (progn
                      ; 中心方向へ移動(X座標を中心に近づける)
                      (if (> sx cx)
                        ; 線が中心より右にある場合、左へ移動
                        (setq new-x (- sx move-dist))
                        ; 線が中心より左にある場合、右へ移動
                        (setq new-x (+ sx move-dist))
                      )
                      (vla-put-StartPoint obj
                        (vlax-3d-point new-x sy (caddr start-pt)))
                      (vla-put-EndPoint obj
                        (vlax-3d-point new-x ey (caddr end-pt)))
                      (vla-Update obj)
                      (princ (strcat "\n    -> Moved DASHED line toward center by " (rtos move-dist 2 1)))
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  )
)

; 直径を変更しても、付随する寸法値が、なぜか変更されない為、強制的に置換
(defun update-dimension-text
       ( blk old-meas new-val-str
         / obj meas override new-override )

  (vlax-for obj blk
    (if (wcmatch (vla-get-ObjectName obj) "AcDb*Dimension*")
        (progn
        (setq meas (vla-get-Measurement obj))
        (if (< (abs (- meas old-meas)) 0.001)
          (progn
            (setq override (vla-get-TextOverride obj))
            (princ (strcat "\n  DIM: Measurement=" (rtos meas 2 3)
                           " TextOverride=" override))
            (if (/= override "")
              (progn
                (setq new-override
                  (vl-string-subst
                    (strcat "%%c" new-val-str)
                    "<>"
                    override))
                (vla-put-TextOverride obj new-override)
                (princ (strcat "\n    -> TextOverride=" new-override))
              )
              (progn
                (vla-put-TextOverride obj (strcat "%%c" new-val-str))
                (princ (strcat "\n    -> TextOverride=%%c" new-val-str))
              )
            )
          )
        )
      )
    )
  )
)

windows bat の練習

UAC 無効化の練習

rem @echo off は、コマンド自体を画面に表示しません
@echo off

echo 処理を開始します
rem echo; は、空白行の表示
echo;

rem openfiles は 管理者権限が必要な為、これを利用し、権限確認
openfiles > NUL 2>&1 
if NOT %ERRORLEVEL% EQU 0 (
  echo 管理者権限で実行してください
  pause
  goto EXIT
)

rem EnableLUAは、UAC の設定が入っているレジストリキー
set REGKEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
set REGNAME=EnableLUA

rem 現在のレジストリ値の参照
FOR /F "TOKENS=1,2,*" %%I IN (
     'REG QUERY "%REGKEY%" /v "%REGNAME%"'
  ) DO IF "%%I"=="%REGNAME%" SET VAL1=%%K
  
if "%VAL1%" EQU "0x0" (
  echo 既にUACは無効の為、処理不要です
  echo;
  pause
  goto EXIT
)

pause
echo UACを無効化します。
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
echo UACを無効化しました。
echo;

echo PCを再起動してください
pause

:EXIT

各種インストーラ実行の練習

@echo off
rem 「echo.」は空白行の表示
echo.
echo 標準ソフトのバージョンアップを開始します。
echo.

rem AdobeReaderインストール
rem  このbatがあるdir(%~dp0)を再帰探索(/r)
rem 「START /WAIT」で、インストール完了まで待つ

for /r %~dp0 %%A in (AcroRdrDC*.exe) do (
START /WAIT %%A  /sAll /rs /norestart EULA_ACCEPT=YES
)

rem CubeICE
for /r %~dp0 %%A in (cubeice-*.exe) do (
START /WAIT %%A  /s /lang=japanese /verysilent /sp- /nocancel /norestart /suppressmsgboxes /nolaunch
)

rem CubePDF
:for /r %~dp0 %%A in (cubepdf-*.exe) do (
:START /WAIT %%A  /s /lang=japanese /verysilent /sp- /nocancel /norestart /suppressmsgboxes /nolaunch
:)

rem CubePDF Utiluity
for /r %~dp0 %%A in (cubepdf-utility*.exe) do (
START /WAIT %%A  /s /lang=japanese /verysilent /sp- /nocancel /norestart /suppressmsgboxes /nolaunch
)

rem java
for /r %~dp0 %%A in (jre-*-i586.exe) do (
START /WAIT %%A /s SPONSORS=0 REMOVEOUTOFDATEJRES=1
)

rem firefox
for /r %~dp0 %%A in (Firefox_Setup*.exe) do (
START /WAIT %%A /silent /install
)

rem ThunderBird
for /r %~dp0 %%A in (Thunderbird_Setup*.exe) do (
START /WAIT %%A /silent /install
)

echo 全てのインストールが完了しました
echo 何かキーを押して、画面を閉じてください
pause
exit

autocadの autolispマクロの練習

modelレイヤ以外にあるブロック図の表の属性を空欄化。 属性を用いず、TEXTやMTEXTは、座標で検索し、削除

; AutoCADから CONVDWGS というコマンドで実行
(defun c:convdwgs ( / dwgdir files f fullpath logfh logfile )
  (princ "START CONVDWGS()\n")
  (vl-load-com)

  (setq dwgdir "c:/Users/end0t/dev/AUTOLISP/DWG")
  (setq logfile (strcat dwgdir "/convdwg.log"))
  (setq logfh (open logfile "a"))

  ; dwgdir にある 各 *.dwgファイルを処理
  (setq files (vl-directory-files dwgdir "*.dwg" 1))
  (foreach f files
    (setq fullpath (strcat dwgdir "/" f))
    (conv-dwg fullpath logfh)
  )
  (close logfh)

  (princ "DONE CONVDWG()\n")
  (princ)
)

(defun sleep-ms (ms / t0)
  (setq t0 (getvar "DATE"))
  (while (< (* 86400000.0 (- (getvar "DATE") t0)) ms))
)

(defun log-write (fh msg)
  (write-line msg fh)
)

(defun point-in-range (pt min-x min-y max-x max-y / x y)
  (setq x (car pt))
  (setq y (cadr pt))
  (and (>= x min-x)
       (<= x max-x)
       (>= y min-y)
       (<= y max-y))
)

(defun process-shiyoukousei-block (obj logfh / result atts-variant atts-list att)
  (log-write logfh "  Block: FOUND")
  (log-write logfh
    (strcat "   Name: " (vla-get-Name obj))
  )

  (log-write logfh
    (strcat
      "   Position: "
      (rtos (car  (vlax-get obj 'InsertionPoint)) 2 3) ", "
      (rtos (cadr (vlax-get obj 'InsertionPoint)) 2 3) ", "
      (rtos (caddr(vlax-get obj 'InsertionPoint)) 2 3)
    )
  )

  ; 属性を持つ ブロック図があれば、属性値を削除
  (if (= :vlax-True (vla-get-HasAttributes obj))
    (progn
      (setq atts-variant (vla-GetAttributes obj))
      (setq atts-list
        (vlax-safearray->list
          (vlax-variant-value atts-variant)))
      (foreach att atts-list
        (log-write logfh
          (strcat
            "   ATTR "
            (vla-get-TagString att)
            " = "
            (vla-get-TextString att)
          )
        )
        (vla-put-TextString att "")
      )
    )
    (log-write logfh "   ATTR: No attributes")
  )
)

; ある座標の範囲に TEXTや MTEXTがあれば、削除
(defun find-and-delete-texts-in-range (blk logfh / obj txt-pos texts-to-delete)
  (log-write logfh "  TEXT objects in range (256.9,283)-(408,287.5):")

  (vlax-for obj blk
    (if (or (= (vla-get-ObjectName obj) "AcDbText")
            (= (vla-get-ObjectName obj) "AcDbMText"))
      (progn
        (setq txt-pos (vlax-get obj 'InsertionPoint))
        (if (point-in-range txt-pos 256.9 283.0 408.0 287.5)
          (progn
            (log-write logfh
              (strcat
                "   TEXT: "
                (vla-get-TextString obj)
              )
            )
            (log-write logfh
              (strcat
                "    Position: "
                (rtos (car  txt-pos) 2 3) ", "
                (rtos (cadr txt-pos) 2 3) ", "
                (rtos (caddr txt-pos) 2 3)
              )
            )
            (log-write logfh
              (strcat
                "    Layer: " (vla-get-Layer obj)
              )
            )
            (setq texts-to-delete (cons obj texts-to-delete))
          )
        )
      )
    )
  )

  (if texts-to-delete
    (progn
      (foreach txt texts-to-delete
        (vla-delete txt)
      )
      (log-write logfh
        (strcat "  Deleted "
                (itoa (length texts-to-delete))
                " TEXT object(s)")
      )
    )
    (log-write logfh "  No TEXT objects found in range")
  )

  (length texts-to-delete)
)

(defun conv-dwg
       ( dwgpath logfh
         / acad docs doc layouts lay blk
           obj att dwgname atts-variant atts-list result
           txt-pos texts-to-delete )

  (vl-load-com)

  (setq acad (vlax-get-acad-object))
  (setq docs (vla-get-Documents acad))

  (setq doc (vla-open docs dwgpath))
  (setq dwgname (vla-get-Name doc))

  (log-write logfh (strcat "DWG: " dwgname))

  (setq layouts (vla-get-Layouts doc))

  (vlax-for lay layouts
    (if (/= (vla-get-Name lay) "Model")
      (progn
        (setq texts-to-delete nil)
        (setq blk (vla-get-Block lay))

        (if blk
          (vlax-for obj blk
            (if (= (vla-get-ObjectName obj) "AcDbBlockReference")
              (if (= (vla-get-Name obj) "NS_ShiyouKousei_01")
                (progn
                  (process-shiyoukousei-block obj logfh)
                  (find-and-delete-texts-in-range blk logfh)
                )
              )
            )
          )
        )
      )
    )
  )

  (log-write logfh "----")
  (sleep-ms 1000)

  (vla-save doc)
  (vla-close doc :vlax-false)
)

pywinauto for python で visioを操作し、svgへ変換

pywinauto for python で AutoCADを操作し、DWGをDXFへ変換 - end0tknr's kipple - web写経開発

上記 entryのvisio版です

#!/usr/local/python3/bin/python3
# -*- coding: utf-8 -*-
import glob
import os
import pywinauto
import time
import subprocess
import psutil

def main():
    visio_paths = glob.glob( "VISIO/**/*", recursive=True)
    
    for i, visio_path in enumerate( visio_paths ) :
        ext = visio_path.split(".")[-1]
        if ext != "vsd" and ext != "vsdx":
            continue

        svg_path = visio_path.replace("."+ext, ".svg")
        if os.path.isfile( svg_path ):
            continue # svg作成済の場合、skip
        
        print(i, visio_path )
        subprocess.Popen([visio_path], shell=True)

        visio_win = find_app_win( "VISIO.EXE", ".* Visio Standard")
        if visio_win == None:
            print("ERROR fail find_app_win()" )
            continue
        # TODO - visioの起動完了を確認した上で、set_focus()したい
        time.sleep( 10 )
        visio_win.set_focus()

        # F12 = 名前を付けて保存
        pywinauto.keyboard.send_keys("{F12}")
        time.sleep(3)
        pywinauto.keyboard.send_keys("{TAB}")
        time.sleep(1)
        pywinauto.keyboard.send_keys("{DOWN 10}") # 保存形式: SVG選択
        time.sleep(1)
        pywinauto.keyboard.send_keys("{ENTER}")
        time.sleep(1)
        # 保存後にSVGを表示しない設定をon
        pywinauto.keyboard.send_keys("{TAB 3}")
        pywinauto.keyboard.send_keys("{SPACE}")
        # 保存実行
        pywinauto.keyboard.send_keys("{ENTER}")
        time.sleep(3)
        # TODO - visioの保存完了を確認した上で、終了したい
        pywinauto.keyboard.send_keys("%{F4}") # visio終了
        time.sleep(3)
        

def find_app_win( proc_name, win_name ):
    app_pid = None
    for i in range(20):
        for proc in psutil.process_iter(attrs=['pid', 'name']):
            if proc_name in proc.info['name']:
                app_pid = proc.info['pid']
                break
        if app_pid != None:
            break
        # 探索対象のアプリが、起動前の可能性もある為
        time.sleep(1)

    if app_pid == None:
        return
    app = pywinauto.Application().connect(process=app_pid)
    app_win = app.window( title_re=win_name )
    return app_win
        
if __name__ == '__main__':
    main()

「公用文作成の考え方」について(建議) by 文化庁

先日、entryに記載した「理科系の作文技術」と同様、文章の記載方法をまとめたもの。

記載内容は同様ですが、こちらは、令和4年(2022年)作成のためでしょうか、 読みやすい印象を受けます。

以下は p.8の抜粋

opencv for python で画像を比較し、pillow for python で結果をマルチページtiffにまとめる

import cv2
from PIL import Image

def highlight_differences(image1_path, image2_path, output_path):
    # 画像を読み込む
    image1 = cv2.imread(image1_path)
    image2 = cv2.imread(image2_path)

    # 画像をグレースケールに変換
    gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

    # 画像の差分を計算
    diff = cv2.absdiff(gray1, gray2)

    # 差分を二値化
    _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)

    # 輪郭を検出
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 差分をハイライト
    for contour in contours:
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(image1, (x, y), (x + w, y + h), (0, 0, 255), 2)

    # ハイライトされた画像を保存
    cv2.imwrite(output_path, image1)

    # ハイライトされた画像を表示
    # cv2.imshow('Differences', image1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # 2ページ目にimg_2を追加して保存
    add_image_to_tiff(output_path, image2_path)

def add_image_to_tiff(tiff_path, image_path):
    # 既存のTIFFファイルを読み込む
    tiff_image = Image.open(tiff_path)
    # 追加する画像を読み込む
    new_image = Image.open(image_path)

    # 既存のTIFFファイルのページをリストに追加
    images = [tiff_image]
    try:
        while True:
            tiff_image.seek(tiff_image.tell() + 1)
            images.append(tiff_image.copy())
    except EOFError:
        pass

    # 新しい画像をリストに追加
    images.append(new_image)

    # すべての画像を新しいTIFFファイルとして保存
    images[0].save(tiff_path, save_all=True, append_images=images[1:], compression="tiff_deflate")

img_1 = "IMAGE_01.tif"
img_2 = "IMAGE_02.tif"
diff_2 = "IMAGE_diff.tif"

# 使用例
highlight_differences(img_1, img_2, diff_2)

括弧などの英語名 (メモ)

記号 英語名
. period
, comma
; semicolon
: colon
- hyphen
dash (En dash、Em dash)
leader
( ) (round) brackets、parentheses
[ ] (square) brackets
{ } (curl) brackets、braces
< > (angle) brackets
“ ” single quotation
‘ ’ double quotation

理科系の作文技術 - オレオレ要約

https://www.amazon.co.jp/dp/4121006240

(要約というより) 久しぶりに読み返したので、 押さえておきたいポイントを目次単位で記載しておきます。

序章

  • 必要なことは洩れなく記述し、必要ないことは書かない
  • 事実と意見を区別する
  • あいまいな表現を避け、普通の用語を用いる
  • 短い文で文章を構成する

2章 準備作業 (立案)

  • 自分の書こうとする文書の役割を確認する
  • 一つの文書は一つの主題に集中する

3章 文章の組立て

  • 重点先行主義 (世の中が忙しくなった為)
  • 概観から細部へ

4章 パラグラフ(段落)

  • パラグラフは一つのトピックについて記述・明言・主張する
  • パラグラフの趣旨を述べたトピックセンテンスを先頭に書く
  • 各パラグラフのトピックセンテンスで、文章全体の要約ができる

5章 文の構造と文章の流れ

  • 文も文章も、逆茂木型(さかもぎ)を避ける (重点先行主義)

6章 はっきり言い切る姿勢

  • ほぼ、約、ほど、ぐらい、たぶん、ような、らしいの類を削る

7章 事実と意見

  • 事実と意見を明確に区別する

8章 わかりやすく簡潔な表現

  • 文は短く (不要な言葉を削る。主語を意識する)
  • 能動態で書くと,読みやすく、文も短くなる(例: 思われる→思う)
  • 読点(、)のルール (受けることばが,離れているとき等 ※1)

※1 句点「。」と読点「、」の決まりを知る | 日経クロステック(xTECH)

9章 執筆メモ

省略

10章 手紙・説明書・原著論文

省略

11章 学会講演の要領

省略

DWG to SVG Converter by AnyDWG Software のコマンドライン版で、DWG →SVG 変換

AutoCAD自体には、SVGへのexport機能がありません。 触ってみた範囲では「DWG to SVG Converter」のコマンドライン版がよいです。

変換元のDWGの描き方によっては、正しくSVGへ変換できない場合もあると思いますが

コマンドライン版の実行例は以下

DOS> "C:\Program Files\WindowsApps\24512AnyDWGSoftware.DWGtoSVGConverter_2027.0.0.0_x64__b1tgcyechd9ap\VFS\ProgramFilesX86\DWG to SVG Converter\ds_10.exe"
    /InFile .\CAD_DWG\AUTOCAD-01-015-cad-.dwg
    /OutFile .\CAD_SVG\AUTOCAD-01-015-cad-.svg /Hide /Overwrite /OutLayout Paper /BGColor 0,0,0

import from utf-8 csv to SQL Server 2025 for Windows

目次

bcp import from utf-8 csv to SQL Server 2022 for Linux - end0tknr's kipple - web写経開発

以前のentryに対しての SQL Server 2025 express edition for Windows

step1 - export from SAP ASE for Linux

SAP ASE ≒ SQL Server で、sqlbcpコマンドも、ほぼ同様に利用できます。

SAP Help Portal | SAP Online Help

bcpコマンドでtableの全recordをexportする場合

$ bcp xerial..kousei  out kousei.csv -Uxsuser -Pxerial -Sxerial -c -t,

bcpコマンドでtableの特定のrecordをexportする場合

$ bcp "SELECT * FROM xerial..kousei WHERE body_mark='A' and ms in('F','M')" \
    queryout kousei.csv -Uxsuser -Pxerial -Sxerial -c -t,

step2 - import by strawberry perl

SQL Server 2025 express にも bcpコマンドは付属しますが、 なぜか、エラーになった為、今回はperl scriptでimport しています。

#!c:/Strawberry/perl/bin/perl
use utf8;
use strict;
use warnings;
use DBI;
use Data::Dumper;
use Encode;
use IO::Uncompress::Unzip qw/$UnzipError/;
use Text::CSV;

my $BCP_DIR = "c:/Users/????/dev/BCP";
my $BULK_INSERT_SIZE = 20;

main();

sub main {
    my $dbh = connect_db();

    my $tbl_names = [
        "plan_attr",
        "arrange_kmatrix",
        "arrange_oya",
        "arrange_rlkousei",
        "arrange_skousei"
        ];
    for my $tbl_name ( @$tbl_names ){
        print "TABLE : $tbl_name\n";
        my $zip_path = "$BCP_DIR/$tbl_name.zip";
        my $org_rows = load_zip_csv( $tbl_name, $zip_path );

        import_csv($dbh, $tbl_name, $org_rows);
    }

    $dbh->disconnect;
}

sub import_csv {
    my ($dbh, $tbl_name, $org_rows) = @_;

    my $col_size = scalar(@{$org_rows->[0]});
    my $sql_head = "INSERT INTO $tbl_name VALUES";
    my $values   = "(". join(",",("?")x scalar($col_size)) .")";
    my $sql = $sql_head . $values;
    my $sth = $dbh->prepare($sql);

    my $i = 0;
    my @buffer;

    for my $csv_cols ( @$org_rows ){
        $i++;
        if( $i % 5000 == 0 ){
            print "import_csv() for $tbl_name $i / ",
                scalar(@$org_rows) , "\n";
        }

        if ( scalar(@$csv_cols) < $col_size ){
            next;
        }

        push @buffer, $csv_cols;

        if (@buffer >= $BULK_INSERT_SIZE) {
            bulk_insert($sth, \@buffer);
            $dbh->commit;
            @buffer = ();
        }
    }

    bulk_insert($sth, \@buffer) if @buffer;
    $dbh->commit;
    print "DONE import_csv() for $tbl_name\n";
    return $i;
}

sub bulk_insert {
    my ($sth, $rows) = @_;
    return unless @$rows;

    my $col_count = @{ $rows->[0] };
    my @bind;

    for my $col (0 .. $col_count - 1) {
        push @bind, [ map { $_->[$col] } @$rows ];
    }
    $sth->execute_array({}, @bind);
}

sub load_zip_csv {
    my ($tbl_name, $zip_path) = @_;
    my $unzip = IO::Uncompress::Unzip->new( $zip_path )
        or die "$zip_path $UnzipError $!";
    my $csv = Text::CSV->new({binary=>1, auto_diag=>1, decode_utf8 =>1});

    my $ret_datas = [];
    while (1) {
        my $csv_name = $unzip->getHeaderInfo->{Name};
        #next unless $csv_name =~ /\.csv$/io;

        my $i = 0;
        while(my $row = $csv->getline($unzip)) {
            $i++;
            if( $i % 5000 == 0 ){
                print "load_zip_csv() for $tbl_name $i\n";
            }

            if( scalar(@$row) < 1 ){
                last;
            }

            if( $tbl_name eq "plan_attr" ) {
                shift( @$row );
                pop( @$row );
            }

            my $cols = [];
            for my $col ( @$row ){
                push( @$cols, trim($col) );
            }
            push(@$ret_datas, $cols);
        }

        my $status = $unzip->nextStream();
        last unless $status;
    }
    return $ret_datas;
}

sub connect_db {
    my $dsn = 'dbi:ODBC:nserial';
    my $dbh = DBI->connect(
        $dsn,
        undef,   # Windows 認証なので不要
        undef, {RaiseError=>1, AutoCommit=>0}) or die $DBI::errstr;

    my $sth = $dbh->prepare("use nserial");
    unless( $sth->execute() ){
        print STDERR $sth->errstr, "\n";
        return undef;
    }
    return $dbh;
}

sub trim {
    my ($val) = @_;
    $val =~ s/^[\s ]*(.*?)[\s ]*$/$1/go;
    if( length($val)==0){
        $val = "";
    }
    return $val;
}
__END__
1;

Document AI yomitoku for python で png画像を html化

oss版と商用版があるようですが、oss版で十分すごいです

https://github.com/kotaro-kinoshita/yomitoku

# -*- coding: utf-8 -*-
import yomitoku
import glob
import logging
import os
import torch
from tensorflow.python.client import device_lib;

logger = None
device = None
src_png_dir = "ns_png"
src_html_dir = "ns_html"


def main():
    # GPU接続確認 https://end0tknr.hateblo.jp/entry/20240814/1723617124
    chk_gpu()

    # logger初期化 - yomitokuが既にloggerを設定している為
    loggers = init_loggers()
    global logger
    logger = loggers[0]

    # --- GPU設定 ---
    global device
    device = "cuda" # cpu or cuda

    # --- PDFのmarkdown化 ---
    conv_png_to_html(src_png_dir, device)

def chk_gpu():
    print( "torch.cuda.is_available() :", torch.cuda.is_available() )
    print( "torch.version.cuda :", torch.version.cuda )
    print( "torch.cuda.device_count() :", torch.cuda.device_count() )
    print( "torch.cuda.get_device_name() :", torch.cuda.get_device_name() )
    print( "device_lib.list_local_devices() :", device_lib.list_local_devices() )
    

def conv_png_to_html(src_png_dir, device):
    doc_analyzer = yomitoku.DocumentAnalyzer(device=device )
    ret_base_dir = src_html_dir

    for i, src_png_path in enumerate(glob.glob(src_png_dir + "/**/*.png",
                                               recursive=True)):
        print(i, src_png_path)
        (src_dir, src_filename) = os.path.split(src_png_path)

        md_dir = src_dir.replace(src_png_dir, src_html_dir)
        if not os.path.exists(md_dir):
            os.makedirs(md_dir)

        basename = os.path.splitext(src_filename)[0]
        html_path = src_html_dir + "/" + basename + ".html"

        imgs = yomitoku.data.functions.load_image(src_png_path)
        for j, img in enumerate(imgs):
            results, ocr_vis, layout_vis = doc_analyzer(img)
            results.to_html(html_path, img=img )
    return ret_base_dir

def init_loggers():
    """ yomitokuが内部に持つloggerを設定変更 """
    ret_datas = []
    for logger_name in ['yomitoku', 'yomitoku.base']:
        tmp_logger = logging.getLogger(logger_name)
        tmp_logger.setLevel(logging.INFO) # 出力levelをINFOへ

        for handler in tmp_logger.handlers:
            if isinstance(handler, logging.StreamHandler):
                tmp_logger.removeHandler(handler)

        fh = logging.FileHandler(logger_name + ".log", encoding='utf-8')
        formatter = logging.Formatter(
            '%(asctime)s %(name)s %(levelname)s %(message)s')
        fh.setFormatter(formatter)

        tmp_logger.addHandler(fh)
        ret_datas.append(tmp_logger)

    return ret_datas

if __name__ == '__main__':
    main()

sqlcmd for SQL Server で CREATE DATABASEやCREATE TABLE等の練習

目次

sqlcmd から SQL serverへ接続

DOS> sqlcmd -S tcp:localhost,1433 -E

version表示

1> SELECT @@VERSION;
2> GO
------------------------------------------------------------
Microsoft SQL Server 2025 (RTM) - 17.0.1000.7 (X64)
【省略】

CREATE DATABASE、DB一覧表示

1> CREATE DATABASE nstest;
2> GO

1> sp_helpdb
2> GO
name     db_size  owner  dbid  created     status                    
------------------------------------------------------------------------------
master   8.50 MB  sa        1  04  8 2003 【略】Collation=Japanese_CI_AS,【略】
tempdb  16.00 MB  sa        2  12 27 2025 【略】Collation=Japanese_CI_AS,【略】
model   16.00 MB  sa        3  04  8 2003 【略】Collation=Japanese_CI_AS,【略】
msdb    24.44 MB  sa        4  10 21 2025 【略】Collation=Japanese_CI_AS,【略】
nstest  16.00 MB  a64\end0t 5  12 28 2025 【略】Collation=Japanese_CI_AS,【略】

LOGIN USER & DB USER追加、ユーザ一覧表示

1> use master
2> go

1> sp_addlogin nsuser, nsuser
2> go

1> sp_addlogin nsuser_r, nsuser_r
2> go

1> use nstest
2> go
データベース コンテキストが 'nstest' に変更されました。

1> sp_adduser nsuser
2> go

1> sp_adduser nsuser_r
2> go

1> sp_helpuser
2> go

UserName            RoleName  LoginName  DefDBName  DefSchemaName  UserID SID
-------------------------------------------------------------------------------
dbo                 db_owner  a64\end0t  master     dbo            1     【略】
guest               public    NULL       NULL       guest          2      0x00
INFORMATION_SCHEMA  public    NULL       NULL       NULL           3      0xNULL
sys                 public    NULL       NULL       NULL           4      0xNULL
nsuser              public    nsuser     master     nsuser         5     【略】
nsuser_r            public    nsuser_r   master     nsuser_r       6     【略】

CREATE TABLE、GRANT

USE nstest
GO
--
IF EXISTS (select name from sysobjects where name="arrange_3mps")
 BEGIN
  DROP TABLE arrange_3mps
 END
GO

CREATE TABLE arrange_3mps (
  plan_num      char(9) DEFAULT ' '  NOT NULL,
  edition       char(3) DEFAULT ' '  NOT NULL,
  addition_num  char(2) DEFAULT ' '  NOT NULL,
  parent_flag   tinyint              NOT NULL,    
  lin_pos       tinyint              NOT NULL,    
  col_pos       tinyint              NOT NULL,    
  part_num      char(15) DEFAULT ' ' NOT NULL,
  use_division  char(1)  DEFAULT ' ' NOT NULL,
/* create primary key */
constraint arrange_3mps_uidx
 primary key clustered
  (plan_num,addition_num,edition,parent_flag,lin_pos,col_pos)
)
GO
GRANT SELECT, INSERT, DELETE, UPDATE ON arrange_3mps TO public
GRANT SELECT, INSERT, DELETE, UPDATE ON arrange_3mps TO nsuser
GRANT SELECT ON arrange_3mps TO nsuser_r
GO

ユーザTABLE一覧表示

SELECT name
FROM sysobjects
WHERE type = 'U'
ORDER BYname
GO

name
------------
arrange_3mps

TABLE定義表示

1> sp_help arrange_3mps
2> go

Name          Owner  Type        Created_datetime
--------------------------------------------------------
arrange_3mps  dbo    user table  2025-12-28 17:50:23.027

Column_name   Type    Computed  Length【略】 Collation
-----------------------------------------------------------
plan_num      char    no        9            Japanese_CI_AS
edition       char    no        3            Japanese_CI_AS
addition_num  char    no        2            Japanese_CI_AS
parent_flag   tinyint no        1 3
lin_pos       tinyint no        1 3
col_pos       tinyint no        1 3
part_num      char    no        15           Japanese_CI_AS
use_division  char    no        1            Japanese_CI_AS

Identity  Seed  Increment  Not For Replication
----------------------------------------------
No identity column defined.

RowGuidCol                                                                                                          
-----------------------------
No rowguidcol column defined.                                                                                       

Data_located_on_filegroup                                                                                           
-----------------------------
PRIMARY                                                                                                             

index_name         index_description                                  index_keys
-------------------------------------------------------------------------------------------------------------------------------
arrange_3mps_uidx  clustered, unique, primary key located on PRIMARY  plan_num,addition_num,edition,parent_flag,lin_pos,col_pos

constraint_type                constraint_name           【略】constraint_keys
------------------------------------------------------------------------------------------------------------------------
PRIMARY KEY (clustered)        arrange_3mps_uidx               plan_num,addition_num,edition,parent_flag,lin_pos,col_pos
DEFAULT on column addition_num DF__arrange_3__addit__5EBF139D  (' ')
DEFAULT on column edition      DF__arrange_3__editi__5DCAEF64  (' ')
DEFAULT on column part_num     DF__arrange_3__part___5FB337D6  (' ')
DEFAULT on column plan_num     DF__arrange_3__plan___5CD6CB2B  (' ')
DEFAULT on column use_division DF__arrange_3__use_d__60A75C0F  (' ')

u