Difficult-Rocket/bin/tools.py

260 lines
6.5 KiB
Python
Raw Normal View History

2021-02-14 20:22:29 +08:00
'''
2020-12-16 06:33:33 +08:00
writen by shenjackyuanjie
mail: 3695888@qq.com
2021-02-14 20:22:29 +08:00
'''
2020-12-16 06:33:33 +08:00
2021-02-14 23:15:54 +08:00
import re
2021-03-20 10:52:40 +08:00
import math
2021-01-25 17:01:54 +08:00
import json5
2021-01-25 17:24:00 +08:00
import decimal
2021-02-06 16:41:54 +08:00
import logging
2021-02-14 19:03:36 +08:00
from xml.dom.minidom import parse
2021-01-23 19:55:35 +08:00
2021-02-03 22:04:34 +08:00
try:
import configs
except ModuleNotFoundError:
from bin import configs
2021-02-06 16:41:54 +08:00
# logger
tools_logger = logging.getLogger('tools')
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
some tools
2021-02-14 20:22:29 +08:00
'''
2020-12-23 23:19:16 +08:00
2020-12-16 06:33:33 +08:00
2021-02-06 16:41:54 +08:00
def c_b(thing): # stand for my bool
yes = ['True', 'TRUE', 'true', '1', 1, True]
no = ['False', 'FALSE', 'false', '0', 0, False]
2021-02-03 22:04:34 +08:00
if thing in yes:
2020-12-16 06:33:33 +08:00
return True
2021-02-03 22:04:34 +08:00
elif thing in no:
2020-12-16 06:33:33 +08:00
return False
else:
raise ValueError("Need a 'like bool' not anything else")
2020-12-22 18:13:59 +08:00
2020-12-23 23:19:16 +08:00
2021-02-14 23:15:54 +08:00
def log_level(level):
level_ = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', logging.DEBUG,
logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL]
if level in level_:
if (level == 'DEBUG') or (level == logging.DEBUG):
return logging.DEBUG
if (level == 'INFO') or (level == logging.INFO):
return logging.INFO
if (level == 'WARNING') or (level == logging.WARNING):
return logging.WARNING
if (level == 'ERROR') or (level == logging.ERROR):
return logging.ERROR
if (level == 'CRITICAL') or (level == logging.CRITICAL):
return logging.CRITICAL
else:
raise ValueError('Need a like level thing not anything else')
2021-03-20 10:52:40 +08:00
# linear_algebra
2021-02-14 23:15:54 +08:00
2021-03-20 10:52:40 +08:00
def C_R_P(position, degrees): # stand for calculation
"""
very thanks for lenny from pyglet delvoper
2021-03-20 10:56:08 +08:00
https://github.com/LennyPhoenix
2021-03-20 10:52:40 +08:00
this part of code is write by him
"""
radians = degrees * (math.pi / 180)
cos = math.cos(radians)
sin = math.sin(radians)
rotated_pos = (position[0] * cos - position[1] * sin, position[0] * sin + position[1] * cos)
return rotated_pos
"""
2021-01-23 19:55:35 +08:00
Physics calculation
2021-03-20 10:52:40 +08:00
"""
2021-01-23 19:55:35 +08:00
2021-01-25 19:23:16 +08:00
def is_decimal(A: any) -> bool:
2021-02-03 22:04:34 +08:00
if type(A) is not type(decimal.Decimal):
2021-01-25 17:24:00 +08:00
return False
2021-01-27 10:32:25 +08:00
else:
return True
2021-01-25 17:24:00 +08:00
2021-01-25 19:23:16 +08:00
def F_D(A: decimal, B: decimal) -> decimal:
2021-01-25 17:24:00 +08:00
if is_decimal(A) and is_decimal(B):
return A / B
2021-01-25 17:11:16 +08:00
2021-01-27 10:32:25 +08:00
def F_Mu(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A * B
def F_Mi(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A - B
def F_A(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A + B
2021-01-25 17:11:16 +08:00
2021-01-25 19:23:16 +08:00
def D_C(listA: list, listB: list) -> '1': # stand for Duplicate check
2021-02-14 20:22:29 +08:00
'''
2020-12-22 18:13:59 +08:00
usage:\n
input two list\n
the fun will do duplicate check and sort then\n
the fun won't return any thing just change the list now
2021-02-14 20:22:29 +08:00
'''
2020-12-22 18:13:59 +08:00
for unit in listB:
if unit in listA:
listA.remove(unit)
listB.remove(unit)
else:
continue
listA.sort()
listB.sort()
2021-01-25 19:23:16 +08:00
return 1
2020-12-23 23:19:16 +08:00
2021-01-23 19:55:35 +08:00
2021-02-14 19:03:36 +08:00
def S_C_float_check(SC): # stand for Scientific notation's float check
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
2021-02-14 20:22:29 +08:00
SC list format:docs.basic_config.json:basic_number'''
2021-01-23 19:55:35 +08:00
while SC[0] >= 10:
SC[0] = F_D(SC[0], 10)
SC[1] += 1
while SC[0] < 1:
SC[0] = F_Mu(SC[0], 10)
SC[1] -= 1
def S_N_M(*SN): # stand for Scientific notation multiple
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
2021-02-14 20:22:29 +08:00
A & B & C list format:docs.basic_config.json:basic_number'''
2021-01-23 19:55:35 +08:00
if len(SN) < 2:
2021-02-14 20:22:29 +08:00
raise TypeError('it need more than 2!')
2021-01-23 19:55:35 +08:00
elif len(SN) == 2:
return __S_N_M(SN[0], SN[1])
else:
R = __S_N_M(SN[0], SN[1])
for A in SN[2:]:
R = __S_N_M(R, A)
return R
def __S_N_M(A, B):
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
2021-02-14 20:22:29 +08:00
A & B list format:docs.basic_config.json:basic_number'''
2021-01-23 19:55:35 +08:00
R = [F_Mu(A[0], B[0]), A[1] + B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[2], A[3] + B[3]
2021-01-27 10:32:25 +08:00
if Unit1 is None:
2021-01-23 19:55:35 +08:00
Unit1 = []
2021-01-25 17:01:54 +08:00
D_C(Unit1, Unit2)
2021-01-23 19:55:35 +08:00
R += [Unit1, Unit2]
return R
def S_N_D(A, B): # stand for Scientific notation divided
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
2021-02-14 20:22:29 +08:00
A & B list format:docs.basic_config:basic_number'''
2021-01-23 19:55:35 +08:00
R = [F_D(A[0], B[0]), A[1] - B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[3], A[3] + B[2]
2021-02-03 22:04:34 +08:00
if Unit1 is None:
2021-01-23 19:55:35 +08:00
Unit1 = []
2021-01-25 17:01:54 +08:00
D_C(Unit1, Unit2)
2021-01-23 19:55:35 +08:00
R += [Unit1, Unit2]
return R
def G_C(M, m, R, G): # stand for gravity calculation
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
M : ship's mass
m : planet's mass
R : distance to the planet
G : Gravitational constant
M & m & R format: docs.basic_config:basic_number
2021-02-14 20:22:29 +08:00
'''
2021-02-03 22:04:34 +08:00
g = configs.basic_force()
2021-01-23 19:55:35 +08:00
A = S_N_M(M, m, G)
g = S_N_D(A, S_N_M(R, R))
return g
2021-02-14 19:03:36 +08:00
def distance(A, B):
2021-02-14 20:22:29 +08:00
'''
2021-01-23 19:55:35 +08:00
formats:
A & B format: docs.basic_config:basic_poi
2021-02-14 20:22:29 +08:00
'''
2021-02-03 22:04:34 +08:00
poi_dis = configs.basic_poi()
2021-02-07 13:50:19 +08:00
for x in A, B:
x = decimal.Decimal(str(x))
2021-02-03 22:04:34 +08:00
xd = A[0] - B[0]
yd = A[1] - B[1]
poi_dis[0] = xd
poi_dis[1] = yd
# 勾股定理
poi_dis[0] **= 2
poi_dis[1] **= 2
poi_dis.append(poi_dis[0] + poi_dis[1])
poi_dis[2] **= 0.5
return poi_dis[2]
2021-01-23 19:55:35 +08:00
2021-02-14 19:03:36 +08:00
# loads
2021-01-23 19:55:35 +08:00
def config(file_name, stack=None):
2021-02-14 23:15:54 +08:00
type = file_name[file_name.rfind('.') + 1:] # 从最后一个.到末尾 (截取文件格式)
2021-02-14 19:03:36 +08:00
if (type == 'json5') or (type == 'json'):
try:
with open(file_name, 'r', encoding='utf-8') as jf: # jf -> json file
2021-02-14 19:03:36 +08:00
rd = json5.load(jf)
except FileNotFoundError as exp:
2021-02-14 23:15:54 +08:00
log = 'no config json(5) file \n file name : %s \n stack : %s' % (
file_name, stack)
2021-02-14 19:03:36 +08:00
tools_logger.exception(log)
raise FileNotFoundError(log)
if stack is not None:
rd = rd[stack]
return rd
elif type == 'xml':
try:
xml_load = parse(file_name)
except FileNotFoundError as exp:
2021-02-22 21:32:13 +08:00
log = 'no config xml file \n file name : %s \n stack : %s' % (
2021-02-14 23:15:54 +08:00
file_name, stack)
2021-02-14 19:03:36 +08:00
tools_logger.exception(log)
raise FileNotFoundError(log)
if stack is not None:
xml_get = xml_load.getElementsByTagName(stack)
return xml_get
else:
return xml_load
def get_At(name, in_xml, need_type=str):
name_type = type(name)
if name_type == list:
At_list = []
for need_name in name:
if in_xml.hasAttribute(need_name):
get = in_xml.getAttribute(need_name)
At_list.append(need_type(get))
else:
continue
return At_list
elif name_type == str:
if in_xml.hasAttribute(name):
At = in_xml.getAttribute(name)
else:
return None
else:
raise TypeError('only str and list type is ok but you give me a' + name_type + 'type')
return need_type(At)