#!/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): 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 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') parser_get.add_argument('-E', '--E', dest='const_collection', action='append_const', const="E", help='get Young\'s modulus, module of elasticity') parser_get.add_argument('-R', '--R_p02', dest='const_collection', action='append_const', const="R_p02", help='get yield strength R_e, R_{p0.2}') 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", True) for filename in file_list: file, _ = os.path.splitext(os.path.basename(filename)) print(file) data = read_file(filename) data_dict = search_keys(data, 'Name') print_dict(data_dict, False, 2) elif args.command == 'get': if args.const_collection: data = load_material(args.materialname) if args.debug: print("data: " + data) if "rho" in args.const_collection: #args.const_collection.append("rho(T)") #f args.debug: # print(args) print_quantity(data['Mechanical Properties']['rho']) if "E" in args.const_collection: print_quantity(data['Mechanical Properties']['E']) if "R_p02" in args.const_collection: print_quantity(data['Mechanical Properties']['R_p02']) if "R_m" in args.const_collection: print_quantity(data['Mechanical Properties']['R_m']) elif args.search: search_list = [element for element in args.search.split(',')] if args.debug: print("search_list: " + str(search_list)) data = read_material(args.materialname) if args.debug: print("data: " + data) data_dict = search_keys(data, keys=search_list) print_dict(data_dict) else: print_material(data) return 0 if __name__ == "__main__": sys.exit(main())