#!/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())