Femapのウィンドウ内に別のアプリを埋め込むAPI

以下は、Femapの「モデル情報」ウィンドウの下方にWindowsのメモアプリを埋め込む例です。

import sys
import subprocess
import ctypes
import time
import pythoncom
import Pyfemap
from Pyfemap import constants

existObj = pythoncom.connect(Pyfemap.model.CLSID)
app = Pyfemap.model(existObj)

subprocess.Popen("notepad.exe")
time.sleep(2)
    
handle = ctypes.windll.user32.FindWindowW(0, "無題 - メモ帳")
app.feAppRegisterAddInPaneWithFrame(True, int(handle), int(handle), False, True, 4, 2)

Femapのウィンドウ内にメモアプリを表示しても無意味ですし、モデル情報ウィンドウの下方はスペースも狭いので、ここに埋め込んで有益なアプリは限られます。

しかし、自社開発のプログラムへの引き渡しのインタフェースや、ビューに表示されている解析結果を分析するようなアプリを埋め込むことは便利なカスタマイズと思います。

Pandasの各列を引数で渡し、行ごとに処理する

よく忘れるので自分的なメモです。

import pandas as pd

def my_func(row):
	d = row['A'] + row['B'] + row['C']
	if row['A'] > 6:
		d = 10
	return d

df = pd.read_excel('Book1.xlsx')
print(df)

df['D'] = df.apply( my_func, axis=1)
print(df)
    A       B   C
0   1   100.0   9
1   2   500.0  67
2   3    40.0  45
3   4     5.0  34
4   5     5.4   2
5   6     7.0   1
6   7    90.0   4
7   8    74.0   5
8   9  1000.0   6
9  10    40.0   7
    A       B   C      D
0   1   100.0   9  110.0
1   2   500.0  67  569.0
2   3    40.0  45   88.0
3   4     5.0  34   43.0
4   5     5.4   2   12.4
5   6     7.0   1   14.0
6   7    90.0   4   10.0
7   8    74.0   5   10.0
8   9  1000.0   6   10.0
9  10    40.0   7   10.0

python-docxでtableを結合する

以下では書類の向きを横向きにして2行2列の表を作成し、2行目を結合してそれぞれに画像を貼り付けています。

from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.section import WD_ORIENT

doc = Document()

section = doc.sections[-1]
new_width, new_height = section.page_height, section.page_width
section.orientation = WD_ORIENT.LANDSCAPE
section.page_width = new_width
section.page_height = new_height

tables = doc.add_table(2, 2)
tables.alignment = WD_TABLE_ALIGNMENT.CENTER

a = tables.cell(1, 0)
b = tables.cell(1, 1)
A = a.merge(b)

p = doc.tables[0].rows[0].cells[0].paragraphs[0]
p.alignment=WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run()
r.add_picture('1.jpg',width=Cm(8.0), height=Cm(6.0))
r.add_break()
r.add_text('風景1')

p = doc.tables[0].rows[0].cells[1].paragraphs[0]
p.alignment=WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run()
r.add_picture('2.jpg',width=Cm(8.0), height=Cm(6.0))
r.add_break()
r.add_text('風景2')

p = doc.tables[0].rows[1].cells[1].paragraphs[0]
p.alignment=WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run()
r.add_picture('3.jpg',width=Cm(8.0), height=Cm(6.0))
r.add_break()
r.add_text('風景3')

doc.add_page_break()

doc.save('test.docx')
結合された表を含むWord文章
結合された表を含むWord文章

結合したセルにアクセスするには、

p = doc.tables[0].rows[1].cells[0].paragraphs[0]

としても良いし、

p = doc.tables[0].rows[1].cells[1].paragraphs[0]

としても良いようです。

また、書類を横向きにするためには

section.orientation = WD_ORIENT.LANDSCAPE

とするだけではダメで、

section.page_width
section.page_height

を書き換えてサイズを変更する必要があります。

python-docxでWORD文章に表を作成して画像とテキストを貼り付ける

以下、サンプルです。

from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT

doc = Document()

tables = doc.add_table(rows=3, cols=2)
tables.alignment = WD_TABLE_ALIGNMENT.CENTER

count = 0
for i in range(3):
	for j in range(2):
		count += 1
		fname = str(count) + '.jpg'
		s = '風景' + str(count)
		p = doc.tables[0].rows[i].cells[j].paragraphs[0]
		p.alignment=WD_ALIGN_PARAGRAPH.CENTER
		r = p.add_run()
		r.add_picture(fname,width=Cm(8.0), height=Cm(6.0))
		r.add_break()
		r.add_text(s)

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run()
r.add_text('6つの風景')

doc.save('test.docx')
test.docx

Pyfemap(Python版、FEMAPのAPI)でグループ毎のリナンバー

以下、サンプルです。

existObj = pythoncom.connect(Pyfemap.model.CLSID)
app = Pyfemap.model(existObj)
xyz = list()
xyz.append(6)
xyz.append(2)
xyz.append(4)

elemSET = app.feSet
gr = app.feGroup
gr.Get(1) #グループ番号1
rc = gr.GetList(constants.FGR_ELEM, elemSET.ID)
rc =  app.feRenumberOpt2(constants.FT_ELEM, elemSET.ID, 1001, 6, 0, False, False, False, xyz) # 1001を先頭にして要素番号をリナンバー
rc = app.feSetFree(elemSET.ID)

点のポリゴン内外判定

必要に応じて、様々の言語で作ったことがあります。

しかし、Pythonのsympyを使えば簡単。

from sympy.geometry import Point, Polygon

x = list()
y = list()

px = 0.5
py = 0.5

x.append(0.0)
x.append(1.0)
x.append(1.0)
x.append(0.0)

y.append(0.0)
y.append(0.0)
y.append(1.0)
y.append(1.0)

points = list()
for i,X in enumerate(x):
	p = Point(X, y[i])
	points.append(p)

poly = Polygon(*points)
point = Point(px, py)

print(poly.encloses_point(point))
True

ポリゴンを構成する線上や構成ポイント上はFalseになります。

Python版AEiで二分探査法

Python版のAEiを作成しました。
手始めに、Calculixの接触問題で入力荷重を変化させ、二分探査法により歪が特定の値となる荷重値を求めるデモを作成しました。

解析を実行するスクリプトは以下のとおり。

import sys
import AEpy as AEI

pmax = 1.0
pmin = 0.1
target = 2.0e-5

while (pmax - pmin) > 1.0e-6:
	pmid = (pmax + pmin) / 2.0
	BASE = 'case_test'
	INP = BASE + '.inp'
	DAT = BASE + '.dat'
	FRD = BASE + '.frd'
	AEI.a('FRDNAME', FRD)
	AEI.a('MYLOAD',pmid, 'L')
	AEI.b('bolt_tmp.txt', INP)
	AEI.b('cgx.txt', 'my.frd')
	AEI.c('ccx ' + BASE)
	AEI.c('cgx -b my.frd')
	AEI.c('python my_max.py ' + DAT + ' result.csv')
	M = AEI.d('result.csv')
	eps = float(M[0][0])
	print('LOAD=', pmid, 'eps=', eps, 'target=', target)
	if eps > target:
		pmax = pmid
	else:
		pmin = pmid

Pythonデータ解析最強パッケージpandas

先の、AEiで連続SR解析を実行する解析コントロールのExcelファイルの全シートを読み込むプログラムです。

コメントや空白行を除けばたった4行。
最強です。

import pandas as pd

# pandas でExcelの全シートを読み込む(ヘッダ行、インデクス列の指定なし)
df_sheet_all = pd.read_excel('analysis.xlsx', sheet_name=None, header=None, index_col=None)

# 全シートの総ての内容を表示する
for df in df_sheet_all:
    print(df, '\n', df_sheet_all[df])

出力は以下です。
numpyの機能ですが、大量のデータが記載されたシート(WAVE)の出力が逸品です。

case 
      0     1             2      3         4     5
0   No    地盤           入力波  入力波番号  入力波ステップ数  建屋減衰
1   01   std  EL_CENTRO_NS      1      2201  0.05
2   02   std     BASE_WAVE      2      6000  0.05
3   03   std  HACHINOHE_NS      3      3600  0.05
4   04  psig  EL_CENTRO_NS      1      2201  0.05
5   05  psig     BASE_WAVE      2      6000  0.05
6   06  psig  HACHINOHE_NS      3      3600  0.05
7   07  msig  EL_CENTRO_NS      1      2201  0.05
8   08  msig     BASE_WAVE      2      6000  0.05
9   09  msig  HACHINOHE_NS      3      3600  0.05
10  10   std  EL_CENTRO_NS      1      2201  0.03
11  11   std     BASE_WAVE      2      6000  0.03
12  12   std  HACHINOHE_NS      3      3600  0.03
13  13  psig  EL_CENTRO_NS      1      2201  0.03
14  14  psig     BASE_WAVE      2      6000  0.03
15  15  psig  HACHINOHE_NS      3      3600  0.03
16  16  msig  EL_CENTRO_NS      1      2201  0.03
17  17  msig     BASE_WAVE      2      6000  0.03
18  18  msig  HACHINOHE_NS      3      3600  0.03
WAVE 
             0             1          2             3
0     time(s)  EL-CENTRO-NS  BASE_WAVE  HACHINOHE_NS
1        0.01       0.01689          0       -0.3047
2        0.02     -0.006061          0       -0.3287
3        0.03      -0.02901          0       -0.3389
4        0.04      -0.05195          0       -0.3417
5        0.05      -0.07489          0        -0.336
6        0.06      -0.05591     0.0001        -0.331
7        0.07      -0.02954     0.0001        -0.336
8        0.08     -0.003163     0.0002       -0.3482
9        0.09       0.02322     0.0003       -0.3476
10        0.1       0.04959     0.0005        -0.324
11       0.11       0.06019     0.0007       -0.2741
12       0.12       0.03569     0.0009       -0.2038
13       0.13       0.01116     0.0011       -0.1215
14       0.14      -0.01336     0.0011       -0.0418
15       0.15      -0.03789     0.0011        0.0193
16       0.16       -0.0624     0.0009        0.0576
17       0.17      -0.08694     0.0007        0.0764
18       0.18      -0.05936     0.0004        0.0584
19       0.19      -0.02848     0.0001        0.0141
20        0.2      0.002398    -0.0003       -0.0124
21       0.21       0.03329    -0.0008       -0.0356
22       0.22       0.06416    -0.0014       -0.0394
23       0.23       0.09505    -0.0022       -0.0212
24       0.24       0.06195    -0.0029        0.0238
25       0.25       0.01758    -0.0036          0.06
26       0.26      -0.02679    -0.0042        0.0952
27       0.27      -0.07115    -0.0047        0.1139
28       0.28      -0.07003    -0.0052        0.0944
29       0.29      -0.04939    -0.0056        0.0467
...       ...           ...        ...           ...
5971    59.71             0    -0.0942             0
5972    59.72             0    -0.0969             0
5973    59.73             0    -0.0764             0
5974    59.74             0    -0.0399             0
5975    59.75             0     0.0037             0
5976    59.76             0      0.039             0
5977    59.77             0     0.0619             0
5978    59.78             0     0.0718             0
5979    59.79             0     0.0776             0
5980     59.8             0     0.0832             0
5981    59.81             0     0.0894             0
5982    59.82             0     0.0926             0
5983    59.83             0     0.0887             0
5984    59.84             0     0.0756             0
5985    59.85             0     0.0596             0
5986    59.86             0     0.0448             0
5987    59.87             0     0.0341             0
5988    59.88             0     0.0265             0
5989    59.89             0     0.0189             0
5990     59.9             0     0.0125             0
5991    59.91             0     0.0132             0
5992    59.92             0      0.024             0
5993    59.93             0     0.0429             0
5994    59.94             0     0.0637             0
5995    59.95             0     0.0845             0
5996    59.96             0     0.0961             0
5997    59.97             0     0.1022             0
5998    59.98             0     0.1007             0
5999    59.99             0     0.0939             0
6000       60             0     0.0847             0

[6001 rows x 4 columns]
std 
     0            1     2      3     4     5  6
0  No            G    VS      ρ     ν    層厚  h
1   1  1.12487e+08   250  17650  0.45  4.55  2
2   2  1.12487e+08   250  17650  0.45  4.55  2
3   3  1.12487e+08   250  17650  0.45   4.2  2
4   4  1.12487e+08   250  17650  0.45   4.2  2
5   5  1.12487e+08   250  17650  0.45   0.9  2
6   6  1.12487e+08   250  17650  0.45   0.9  2
7   7  5.17608e+09  1500  22560  0.37   100  2
psig 
     0            1     2      3     4     5  6
0  No            G    VS      ρ     ν    層厚  h
1   1   1.3611e+08   275  17650  0.45  4.55  2
2   2   1.3611e+08   275  17650  0.45  4.55  2
3   3   1.3611e+08   275  17650  0.45   4.2  2
4   4   1.3611e+08   275  17650  0.45   4.2  2
5   5   1.3611e+08   275  17650  0.45   0.9  2
6   6   1.3611e+08   275  17650  0.45   0.9  2
7   7  6.26306e+09  1650  22560  0.37   100  2
msig 
     0            1     2      3     4     5  6
0  No            G    VS      ρ     ν    層厚  h
1   1  9.11148e+07   225  17650  0.45  4.55  2
2   2  9.11148e+07   225  17650  0.45  4.55  2
3   3  9.11148e+07   225  17650  0.45   4.2  2
4   4  9.11148e+07   225  17650  0.45   4.2  2
5   5  9.11148e+07   225  17650  0.45   0.9  2
6   6  9.11148e+07   225  17650  0.45   0.9  2
7   7  4.19262e+09  1350  22560  0.37   100  2

Tensorflowの環境を構築して線形回帰を試す

年齢と点数の関係

GoogleやMicrosoft、IBMが提供する機械学習済みのデータを使うのであれば、自身で環境を構築する必要はありません。

しかし、独自の学習をさせるのであれば自身のコンピュータに環境を構築するか、或いはGoogleなどが提供するクラウド上の機械学習の環境が必要です。

以下のサイトを参考にさせていただき、MacOSにTensorflowをインストールして環境を構築しました。
https://qiita.com/junichiro/items/8886f3976fc20f73335f

上記のサイトでは、予め線形関数の係数を定めて、この関数からデータを作成して学習データとしています。

今回は、下記のサイトのデータを使わせていただき、線形回帰の機械学習を試してみました。
https://kyoto-edu.sakura.ne.jp/?&course=statistics&content=correl

実行結果は以下のとおり。

python tensorflow-test.py

0 [8.540184] [0.9793252]
200 [6.1199374] [-0.58089983]
400 [6.234987] [-1.5768614]
600 [6.325655] [-2.3617592]
800 [6.3971086] [-2.9803212]
1000 [6.4534197] [-3.467797]
1200 [6.4977975] [-3.8519664]
1400 [6.5327706] [-4.1547227]
1600 [6.560332] [-4.3933163]
1800 [6.582052] [-4.581347]
2000 [6.5991697] [-4.7295313]

0歳の得点がマイナスというのも変なモデルですが、そこはそういうデータだったということで良しとします。

Pythonのソースファイルは以下です。

import tensorflow as tf
import numpy as np

x_data = np.loadtxt('exam-result.csv', delimiter=',', usecols=[3], skiprows=1)
y_data = np.loadtxt('exam-result.csv', delimiter=',', usecols=[1], skiprows=1)

# Try to find values for W and b that compute y_data = W * x_data + b
# (We know that W should be 0.1 and b 0.3, but TensorFlow will
# figure that out for us.)
W = tf.Variable(tf.zeros([1]))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b

# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

# Before starting, initialize the variables.  We will 'run' this first.
init = tf.global_variables_initializer()

# Launch the graph.
sess = tf.Session()
sess.run(init)

# Fit the line.
for step in range(2001):
    sess.run(train)
    if step % 200 == 0:
        print(step, sess.run(W), sess.run(b))

# Close the Session when we're done.
sess.close()