Files
material/src/materials.py

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())