1. シルバーストーン曲線 ビジュアライズゼーション
マクシー・シルバーストーン曲線 を pythonで ビジュアライズゼーションするコードです.
JupyterNotebook で動作確認済みです.
なお,現在入っているパラメタは超適当に置いてるので,各自で変更して使ってください.
fix_cost_simulator
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
%matplotlib inline
# set investigation cost
PLANT_COST = 9_999_999_999 # set plant cost [!]
LINE_COST = 99_999_999 # set line cost [!]
TOOLING_COST = 69_999_999 # set tooling cost [!]
# set how much lines a plant will have [!]
PLANNED_NUM_OF_LINE = 8
# set each condition of the capacity. (pcs/yr = pcs/day * day/mo * mo/yr)
LINE_DAILY_CAPA = 999 # set daily line production capacity [!]
TOOLING_DAILY_CAPA = 599 # set daily tooling production capacity [!]
DAYS_PER_MONTH = 22 # set working days [!]
MONTHS_PER_YEAR = 12 # how many months in a year
LINE_CAPA = LINE_DAILY_CAPA * DAYS_PER_MONTH * MONTHS_PER_YEAR # calc line capacity per year
TOOLING_CAPA = TOOLING_DAILY_CAPA * DAYS_PER_MONTH * MONTHS_PER_YEAR # calc tooling capacity per year
# set the condition for this simulation
START_QTY = 100_000 # starting point(production number) for this simulation
PLOT_WIDTH = 1_000 # plotting width
MARGIN_RATIO = 0.9 # set safety margin (consider a risk of sales) [!]
PLANT_DEP_YEAR = 9 # set plant depreciation year [!]
LINE_DEP_YEAR = 9 # set line depreciation year [!]
TOOLING_DEP_YEAR = 2.2 # set tooling depreciation year [!]
END_QTY = PLANNED_NUM_OF_LINE * LINE_CAPA # calc the end of this simulation
# initialize number of line/tooling
line_num = math.ceil(START_QTY / LINE_CAPA) # initialize number of line
tooling_num = math.ceil(START_QTY / TOOLING_CAPA) # initialize number of tooling
plant_dep_qty = END_QTY * PLANT_DEP_YEAR * MARGIN_RATIO # calc plant depreciation quantity
# generate data for simulation
x_range = np.arange(START_QTY, END_QTY, PLOT_WIDTH)
Y = []
p_line_capa = line_num * LINE_CAPA # calc initial line production capacity
p_tooling_capa = tooling_num * TOOLING_CAPA # calc initial tooling production capacity
for x in x_range:
if x > p_line_capa: # if production qty is over line capa, add a new line
line_num += 1
p_line_capa = line_num * LINE_CAPA
if x > p_tooling_capa: # if production qty is over tooling capa, add a new tooling
tooling_num += 1
p_tooling_capa = tooling_num * TOOLING_CAPA
plant_alloc = PLANT_COST / plant_dep_qty # calc allocated cost of plant building cost
line_alloc = line_num * LINE_COST / x / LINE_DEP_YEAR # calc allocated cost of line cost
tooling_alloc = tooling_num * TOOLING_COST / x / TOOLING_DEP_YEAR # calc allocated cost of tooling cost
all_alloc = plant_alloc + line_alloc + tooling_alloc
if line_num > PLANNED_NUM_OF_LINE: # if line_num is over planned num of line, cause error.
print('Error: line_num is over PLANNED_NUM_OF_LINE.')
break
Y.append(all_alloc)
# show the precondition of this simulation
precondition_dict = {}
precondition_dict['plant_building_cost [工場建屋費用]'] = f'{PLANT_COST:,}'
precondition_dict['line_building_cost [ライン敷設費用]'] = f'{LINE_COST:,}'
precondition_dict['tooling_cost [金型費用]'] = f'{TOOLING_COST:,}'
precondition_dict['max_line_num_per_a_plant [1工場あたり最大ライン敷設計画数(pcs/day)]'] = PLANNED_NUM_OF_LINE
precondition_dict['max_production_daily_capa [1日あたりライン生産能力(pcs/day)]'] = LINE_DAILY_CAPA
precondition_dict['max_tooling_daily_capa [1日あたり金型生産能力]'] = TOOLING_DAILY_CAPA
precondition_dict['plant_depreciation_year [工場建屋の償却設定年数]'] = PLANT_DEP_YEAR
precondition_dict['line_depreciation_year [ラインの償却設定年数]'] = LINE_DEP_YEAR
precondition_dict['tooling_depreciation_year [金型の償却設定年数]'] = TOOLING_DEP_YEAR
precondition_dict['max_line_num [最大ライン敷設数]'] = line_num
precondition_dict['max_tooling_num [最大金型数]'] = tooling_num
precondition_dict['plant_production_capa [工場の生産能力(pcs/yr)]'] = f'{END_QTY:,}'
df = pd.DataFrame(precondition_dict.values(), index=precondition_dict.keys(), columns=['precondition [前提条件]'])
display(df)
# set your plan
yourX = 1_000_000 # set your sales plan [!]
yourY = 999_999_999
for x, y in zip(x_range, Y):
if x > yourX:
yourY = y
break
# show simulation result
plt.rcParams["font.size"] = 15
fig, ax = plt.subplots(1, 1, facecolor='#F5FBFF', figsize=(15,10))
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.plot(x_range, Y, c='green')
ax.vlines(x=yourX, ymin=min(Y), ymax=max(Y), color='red')
ax.text(x=yourX*1.03, y=max(Y)*0.995, s=f'{yourY:,.2f} @ ( line_num:{np.ceil(yourX/LINE_CAPA):.0f}, tooling_num:{np.ceil(yourX/TOOLING_CAPA):.0f} )', color='red', fontsize=20)
fig.savefig('./data/img/FixedCostSim.png')
plt.show()
-
Maxcy et al.[1965]silver stone
でググると,自動車製造企業の財務戦略 -トヨタを素材として-が引っ掛かった.興味深い. - 1965年っていうと,当然ながら,EXCELもない時代.マクシーさんは手書きでプロットしていったのでしょう.python でこれだけ楽に描画できるのは本当に有難い.
2. バナナの叩き売り ビジュアライゼーション
banana_sim
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def make_and_plot_data(p1, p2, b):
X = np.arange(p1, p2, 1)
Y = []
for x in X:
Y.append(b)
ax.plot(X,Y,c='green')
X0 = 0
X1 = 50 # [!]
X2 = 100 # [!]
X3 = 200 # [!]
C0 = 2000 # 購入量 X0 以上,X1 未満の売り値 [!]
C1 = 1000 # 購入量 X1 以上,X2 未満の売り値 [!]
C2 = 500 # 購入量 X2 以上,X3 未満の売り値 [!]
yourX = 120 # [!]
yourY = 500 # [!]
plt.rcParams["font.size"] = 15
fig = plt.figure(facecolor='#F5FBFF', figsize=(15,10))
ax = fig.subplots(1,1)
make_and_plot_data(X0, X1, C0)
make_and_plot_data(X1, X2, C1)
make_and_plot_data(X2, X3, C2)
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.vlines(x=yourX, ymin=0, ymax=C0, color='red')
ax.text(x=yourX*1.03, y=yourY*1.1, s=f'{yourY} @ {yourX:,}', color='red', fontsize=20)
fig.savefig('./data/img/bananaCostSim.png')
plt.show()