Skip to content

Commit

Permalink
Merge pull request #40 from alopezrivera/dev
Browse files Browse the repository at this point in the history
Low-thrust porkchop example, radiation pressure update, some other fixes
  • Loading branch information
DominicDirkx committed Feb 23, 2024
2 parents 5600165 + 9e36105 commit ac56a32
Show file tree
Hide file tree
Showing 34 changed files with 3,110 additions and 1,240 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -49,4 +49,5 @@ __pycache__*
*/jupyter-lab.log
jupyter-lab.log

**/*.pkl
*.dat
72 changes: 0 additions & 72 deletions clean_py_notebooks.py

This file was deleted.

41 changes: 0 additions & 41 deletions convert_py_to_ipynb.py

This file was deleted.

164 changes: 164 additions & 0 deletions create_scripts.py
@@ -0,0 +1,164 @@
"""
Copyright (c) 2010-2022, Delft University of Technology. All rights reserved. This file is part of the Tudat. Redistribution and use in source and
binary forms, with or without modification, are permitted exclusively
under the terms of the Modified BSD license. You should have received
a copy of the license with this file. If not, please or visit:
http://tudat.tudelft.nl/LICENSE.
"""
# PLEASE NOTE:
# This script is NOT a tudatpy example.
# It is a script to clean the .py files that are generated from Jupyter notebooks, using the following option: File > Download as > Python (.py)
# Running it will automatically edit all the .py example files (please check the changes made before pushing them to the repository).

# Standard library imports
import re
import glob
import subprocess

# Other imports
from tqdm import tqdm

# Utilities
def request_confirmation(message):
message = f'{message} [y/N]'
width = max(60, len(message)+20)
return input(
f'{"="*width}\n{message:^{width}}\n{"="*width}\n'
).strip().lower() == 'y'

"""
Use the find command line utility to find the paths of all
notebooks in this repository and store them in a list
"""
example_notebooks = glob.glob('**/*.ipynb', recursive=True)
example_scripts = [notebook.replace('.ipynb', '.py') for notebook in example_notebooks]
all_python_files = glob.glob('**/*.py', recursive=True)

"""
Transform each notebook into a python script using
the jupyter nbconvert command line utility
"""

def generate_script(notebook):
subprocess.run(['jupyter', 'nbconvert', '--to', 'script', notebook])

if request_confirmation('Regenerate Python scripts from Jupyter notebooks?'):
# Generate the python scripts
for notebook in tqdm(example_notebooks): generate_script(notebook)
# Assert that all the notebooks were converted to python scripts
assert all([script in all_python_files for script in example_scripts]), \
f'Unsuccessful: not all notebooks were converted to python scripts. Failed conversions:\n' + \
'\n'.join([script for script in example_scripts if script not in all_python_files])
else:
# If there are missing scripts
if not all([script in all_python_files for script in example_scripts]):
# Generate the missing python scripts
for script in [script for script in example_scripts if script not in all_python_files]:
generate_script(script)

"""
Clean up the python scripts
"""

for example_python_script in example_scripts:

print(f'Cleaning example: {example_python_script}')

with open(example_python_script, "r+") as file:

# Read example
example_content = file.readlines()

# Remove file type and encoding
if "!/usr/bin/env python" in example_content[0]:
example_content = example_content[3:]

# State
checking_comment_end = False
skip_next = False

# Indentation
indentation = ''

# Go trough each line in the example
for i, line in enumerate(example_content):

if skip_next:
skip_next = False
continue

# --> Remove the "In[x]" notebook inputs
if "In[" in line:
# Also remove the two lines after
[example_content.pop(i) for _ in range(3)]

# --> End of MD cell
elif checking_comment_end:
# --> End of cell: if the line is empty, the markdown cell is finished
if line == "\n":
# Add """ to close the string comment, then an empty line
example_content[i] = "\"\"\"\n"
example_content.insert(i+1, "\n")
checking_comment_end = False
# --> Second title: detect if we have a second title in the same markdown cell, and mark the separation
elif "##" in line:
example_content[i] = line.replace("# ", "", 1)
example_content.insert(i, "\"\"\"\n\n")
example_content.insert(i+2, "\"\"\"\n")
skip_next = True
# If we are still in the markdown cell, remove the simple # that indicates a comment line
else:
example_content[i] = line.replace("# ", "", 1)

# --> Start of MD cell: if the line starts with # #, we are in a markdown cell that starts with a title
elif "# #" in line:
# Replace the first line to keep the title with a comment #
example_content[i] = line.replace("# ", "", 1)
example_content.insert(i+1, "\"\"\"\n")
if example_content[i+2] == "\n":
example_content.pop(i+2)
checking_comment_end = True # Start looking for the end of the cell

# --> Remove the lines that made the plots interactive
elif "# make plots interactive" in line:
[example_content.pop(i) for _ in range(2)]

# We're in a code cell, so we record the indentation level
else:

# Retrieve the last non-empty line
last_nonempty_line = next(line for line in example_content[i-1::-1] if re.match(r'^( {4}){0,2}\S', line))

# Keep track of current indentation
indentation = ' ' * (len(last_nonempty_line) - len(last_nonempty_line.lstrip()))

file.seek(0)
file.writelines(example_content)
file.truncate()

"""
Check Python scripts for syntax errors
"""
print('\nChecking Python scripts for syntax errors\n')
for example_python_script in example_scripts:

# Test the example
result = subprocess.run(['python', '-m', 'py_compile', example_python_script],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)

if result.returncode != 0:
print(f'Unsuccessful: syntax error in example: {example_python_script}')
example_scripts.remove(example_python_script)
print('')

"""
Test python scripts
"""
if request_confirmation('Test generated Python scripts?'):
for example_python_script in example_scripts:

print(f'Testing example: {example_python_script}')

# Test the example
subprocess.run(['python', example_python_script])

0 comments on commit ac56a32

Please sign in to comment.