263 lines
7.3 KiB
Python
Executable File
263 lines
7.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""\
|
|
Material database.
|
|
"""
|
|
import sys
|
|
import os
|
|
|
|
__author__ = "Daniel Weschke"
|
|
__copyright__ = "Copyright 2019 Daniel Weschke"
|
|
__credits__ = ["Daniel Weschke"]
|
|
__license__ = "MIT"
|
|
__version__ = "2019.02.03"
|
|
__maintainer__ = "Daniel Weschke"
|
|
__email__ = "daniel.weschke@directbox.de"
|
|
__status__ = "Production" # "Prototype", "Development", "Production"
|
|
|
|
VERSION = """\
|
|
%(prog)s version {version} {copyright}
|
|
""".format(
|
|
version=__version__, copyright=__copyright__)
|
|
|
|
EPILOG = """\
|
|
"""
|
|
|
|
|
|
def absolute_path(filename):
|
|
"""\
|
|
Get full path.
|
|
"""
|
|
return os.path.join(os.path.abspath(os.path.dirname(__file__)), filename)
|
|
|
|
|
|
def read_dir(directory, exclude=None, fullpath=False, extension=True):
|
|
"""\
|
|
Read all files in directory as list
|
|
"""
|
|
result = []
|
|
for file_name in os.listdir(directory):
|
|
if not extension:
|
|
file_name = file_name.split('.')[0]
|
|
if exclude is not None and file_name not in exclude:
|
|
if fullpath:
|
|
file_name = absolute_path(os.path.join(directory, file_name))
|
|
result.append(file_name)
|
|
return result
|
|
|
|
|
|
def print_list(data_list):
|
|
"""\
|
|
Print list
|
|
"""
|
|
for data in data_list:
|
|
print(data)
|
|
|
|
|
|
def read_file(filename):
|
|
"""\
|
|
Read file as string
|
|
"""
|
|
with open(filename) as data_file:
|
|
return data_file.read()
|
|
|
|
|
|
def read_material(materialname, fullpath=True):
|
|
"""\
|
|
Read material file as string
|
|
"""
|
|
filename = os.path.join('data', materialname + '.json')
|
|
if fullpath:
|
|
filename = absolute_path(filename)
|
|
try:
|
|
return read_file(filename)
|
|
except (OSError, IOError) as err:
|
|
print("Error: Material '%s' not found" % materialname, file=sys.stderr)
|
|
print(str(err), file=sys.stderr)
|
|
sys.exit(2)
|
|
|
|
|
|
def load_material(materialname):
|
|
"""\
|
|
Read material file and convert it to a Python object.
|
|
"""
|
|
import json
|
|
|
|
return json.loads(read_material(materialname))
|
|
|
|
|
|
def print_material(data):
|
|
"""\
|
|
Print material data (Python object).
|
|
"""
|
|
import pprint
|
|
|
|
#print(data)
|
|
pprint.pprint(data)
|
|
|
|
|
|
def search_keys(data, keys):
|
|
"""\
|
|
Search for json keys in string data
|
|
"""
|
|
from json import loads
|
|
|
|
def find_values(key, json_repr):
|
|
"""\
|
|
Find values inside json string
|
|
"""
|
|
results = []
|
|
def _decode_dict(a_dict):
|
|
try:
|
|
results.append(a_dict[key])
|
|
except KeyError:
|
|
pass
|
|
return a_dict
|
|
|
|
loads(json_repr, object_hook=_decode_dict) # return value ignored
|
|
return results
|
|
|
|
results = {}
|
|
if keys is not None:
|
|
if isinstance(keys, str):
|
|
keys = [keys]
|
|
for key in keys:
|
|
found_values = find_values(key, data)
|
|
results[key] = found_values
|
|
return results
|
|
|
|
|
|
def print_dict(data_dict, print_keys=True, prespaces=0):
|
|
"""\
|
|
Print one dimensional dict data.
|
|
"""
|
|
for key, values in data_dict.items():
|
|
for value in values:
|
|
if print_keys:
|
|
print(key + ' = ', end='')
|
|
print_quantity(value, prespaces)
|
|
|
|
|
|
def print_quantity(quantity, prespaces=0):
|
|
"""\
|
|
Print quantity.
|
|
Either a number or a list of two elements, the first the magnitude and the second the unit
|
|
"""
|
|
if isinstance(quantity, list) and len(quantity) == 2:
|
|
print(prespaces*' ' + '%s' % quantity[0] + ' ' + quantity[1])
|
|
else:
|
|
print(prespaces*' ' + '%s' % quantity)
|
|
|
|
|
|
def get_value(data, element):
|
|
"""\
|
|
Get value of nested dictionary.
|
|
If element is itself a list of length one, the element of the list is returned
|
|
"""
|
|
keys = element.split('/')
|
|
for key in keys:
|
|
data = data.get(key)
|
|
if isinstance(data, dict) and data and len(data) == 1:
|
|
data = next(iter(data.values()))
|
|
return data
|
|
|
|
|
|
def main():
|
|
"""\
|
|
Main function
|
|
"""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__, prefix_chars='-', epilog=EPILOG,
|
|
#usage="%(prog)s [OPTION]... NAME",
|
|
formatter_class=argparse.RawTextHelpFormatter,
|
|
)
|
|
parser.add_argument('-v', '--verbose', action="store_true", help="Verbose output")
|
|
parser.add_argument('-V', '--version', action='version', version=VERSION)
|
|
parser.add_argument('-D', '--debug', dest='debug', action='store_true', help=argparse.SUPPRESS)
|
|
|
|
subparsers = parser.add_subparsers(help='commands', dest='command')
|
|
|
|
# list materials
|
|
parser_list = subparsers.add_parser('list',
|
|
description='List materials.',
|
|
help='list all available materials')
|
|
|
|
# get material
|
|
parser_get = subparsers.add_parser('get',
|
|
description='Get material information.',
|
|
help='get material information')
|
|
parser_get.add_argument('materialname', action='store',
|
|
help='list available material information')
|
|
parser_get.add_argument('-r', '--rho', dest='const_collection',
|
|
action='append_const', const="rho",
|
|
help='get density rho')
|
|
parser_get.add_argument('-E', '--E', dest='const_collection',
|
|
action='append_const', const="E",
|
|
help='get Young\'s modulus E, module of elasticity')
|
|
parser_get.add_argument('-n', '--nu', dest='const_collection',
|
|
action='append_const', const="nu",
|
|
help='get Poisson ratio nu')
|
|
parser_get.add_argument('-R', '--R_p', dest='const_collection',
|
|
action='append_const', const="R_p",
|
|
help='get yield strength R_p')
|
|
parser_get.add_argument('--R_m', dest='const_collection',
|
|
action='append_const', const="R_m",
|
|
help='get ultimate tensile strength R_m')
|
|
parser_get.add_argument('--search', action='store',
|
|
help='search for material information, comma delimited keys')
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.debug:
|
|
print(args)
|
|
|
|
if args.command == 'list':
|
|
file_list = read_dir(absolute_path("data"), ["INFO.json", "example.json"], True)
|
|
file_list.sort()
|
|
for filename in file_list:
|
|
file, _ = os.path.splitext(os.path.basename(filename))
|
|
data = read_file(filename)
|
|
data_dict = search_keys(data, ['Name', 'ISO', 'EN-AW', 'WERKSTOFFNUMMER', 'SAE'])
|
|
#print(file)
|
|
#print_dict(data_dict, False, 2)
|
|
print(file, end='')
|
|
aka = [i[0] for i in list(data_dict.values()) if i and file not in i]
|
|
print(" (" + ", ".join(aka) + ")")
|
|
|
|
elif args.command == 'get':
|
|
if args.const_collection:
|
|
data = load_material(args.materialname)
|
|
if args.debug:
|
|
print("data:")
|
|
print_material(data)
|
|
mat_index = {
|
|
"rho": "Mechanical Properties/rho",
|
|
"E": "Mechanical Properties/E",
|
|
"nu": "Mechanical Properties/nu",
|
|
"R_p": "Mechanical Properties/Yield strength",
|
|
"R_m": "Mechanical Properties/R_m"
|
|
}
|
|
for element in args.const_collection: # iter the way it is been entered as args
|
|
print_quantity(get_value(data, mat_index[element]))
|
|
|
|
elif args.search:
|
|
search_list = [element for element in args.search.split(',')]
|
|
data = read_material(args.materialname)
|
|
if args.debug:
|
|
print("search_list: " + str(search_list))
|
|
print("data: " + data)
|
|
data_dict = search_keys(data, keys=search_list)
|
|
print_dict(data_dict)
|
|
|
|
else:
|
|
data = load_material(args.materialname)
|
|
print_material(data)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|