"""General utilities for UXsim."""importwarningsimportfunctoolsimporttracebackimportsys
[docs]defcatch_exceptions_and_warn(warning_msg=""):""" A decorator that catches exceptions in the decorated function and raises a warning with the specified message. Parameters ---------- warning_msg : str, optional A custom message to be displayed along with the exception details. Default is an empty string. Returns ------- decorator A decorator that wraps the decorated function to catch exceptions and raise warnings. Notes ----- When an exception occurs in the decorated function, the decorator will raise a warning that includes: - The name of the function. - A custom message, if provided. - The type of the exception. - The exception message. - The filename and line number where the decorated function was called. This decorator is for inessential functions where random exceptions are expected (especially due to file I/O or something), but you want to avoid crashing the entire program and instead receive a warning. Mainly written by ChatGPT. """warnings.simplefilter('default',category=UserWarning)warnings.formatwarning=lambdamessage,category,filename,lineno,line:f"{category.__name__}: {message}\n"defdecorator(func):@functools.wraps(func)defwrapper(*args,**kwargs):try:returnfunc(*args,**kwargs)exceptExceptionase:#warnings.warn(f"{func.__name__}(){warning_msg}: {type(e).__name__}: {str(e)}")current_frame=sys._getframe()caller_frame=traceback.extract_stack(current_frame,limit=2)[0]filename=caller_frame.filenamelineno=caller_frame.linenowarnings.warn(f"{filename}:{lineno}:{func.__name__}(){warning_msg}: {type(e).__name__}: {str(e)}")returnwrapperreturndecorator
[docs]deflange(l):""" Super lazy function for abbreviating range(len(l)) Parameters ---- l : list """returnrange(len(l))
[docs]defprinttry(*args,**kwargs):""" Print messages safely, evaluating any callable arguments and catching exceptions. Mainly written by GPT-4 Parameters ---------- *args : any The contents to print wrapped by lambda. E.g., lambda: (x, y, z) **kwargs : any Arbitrary keyword arguments. These are passed directly to the built-in print function. Examples -------- >>> printtry(lambda: (mylist[100], mylist[1000], mylist[10000])) >>> printtry(lambda: (mylist[100], mylist[1000], mylist[10000]), sep=";", end="!") """try:# Evaluate each argument and print themevaluated_args=[arg()ifcallable(arg)elseargforarginargs][0]print(*evaluated_args,**kwargs)exceptExceptionase:# Print the exception if it occursprint("EXCEPTION:",e)
[docs]defget_font_for_matplotlib(fname=None):""" Get a multi-language (currently Japanese only) font for matplotlib. TODO: check if it works on different OS. It is only checked on Japanese Windows. TODO: explore if it can be extended for other languages. Returns ------- str The name of a Japanese font that is available on the system. If no Japanese font is found, "monospace" is returned. """frommatplotlibimportfont_managerfont_list=font_manager.findSystemFonts()iffnameisnotNone:font=fnameelifany("Noto Sans Mono CJK JP"infont.lower()forfontinfont_list):font="Noto Sans Mono CJK JP"elifany("msgothic"infont.lower()forfontinfont_list):font="MS Gothic"else:font="monospace"returnfont
[docs]defprint_columns(*lists):""" Convinient function to check contents of 1d lists. For debug. """# Determine the maximum length of the listsmax_length=max(len(lst)forlstinlists)# Iterate through the maximum number of rowsforiinrange(max_length):# For each list, print the element at the current row or space if out of rangeforlstinlists:ifi<len(lst):try:print(f"{lst[i]:<10}",end=" ")# Adjust the width as necessaryexceptTypeError:print(f"{str(lst[i]):<10}",end=" ")else:print(" "*10,end=" ")# Adjust spacing to match the above widthprint()# Newline after each row
[docs]defdisplay_image_in_notebook(image_path):""" Display an image in Jupyter Notebook. Parameters ---------- image_path : str The path to the image file to display. """fromIPython.displayimportdisplay,Imagewithopen(image_path,"rb")asf:display(Image(data=f.read(),format='png'))
[docs]classLoggingWarning(UserWarning):""" This warns that when vehicle_logging_timestep_interval is not 1 but called vehicle logging-related functions. """pass