Plotting the output using python Matplotlib in Sconstruct - scons

I have a SConstruct file which compiles a C code and generates some binary files. Currently I am manually running the python script which generates the plot after the SConstruct file. I want to run the executable file and plot the output automatically every time I run the SConstruct. Does any one have any idea how it could be done ?
Here is the sample code.The C code requires an input which is generated by model.py and finally SConstruct generates main.exe (C executable file). main.exe generates another binary files which need to be plotted .Currently I am running a separate python script 'output.py' which generates plot. Also I want model.py to run only when I made some changes in it.The sequence is model.py -> main.c -> output.py (plots) . How can I incorporate this into a single Scons ?
import os
import numpy as np
import matplotlib.pyplot as plt
execfile('model.py')
env = Environment(ENV = os.environ,CC='gcc')
env.Append(CCFLAGS=['-fopenmp'])
env.Prepend(LIBS=['m'])
ldflags='-fopenmp'
env.Program('main.exe','main.c',LINKFLAGS=ldflags)

Related

What's the best way to import large python modules into a ROS package? - import errors python ROS

I want to include a large python package: Yolov7-https://github.com/WongKinYiu/yolov7.git into my already existing ROS package. The large python package consists of many files which depend on each other. I want this to be included and available for use in my main program scripts/main.py, which runs as a ROS node.
File structure: https://imgur.com/a/THP5WvP
PROBLEM: Files in yolov7 importing other files in yolov7 need to have the pathname package.yolov7.file_name, while the whole package is actually written on the form: from file_name import ...
How can I make sure files in yolov7 actually can import other files in yolov7 without having to add the extra path to every import?
Example: instead of having to write: from package.yolov7.utils.datasets import letterbox
I want to be able to have: from utils.datasets import letterbox
I have tried editing CMakeLists.txt, setup.py, and package.xml, but for now they are unchanged in regards to yolov7.
I'm using ROS Noetic, running Ubuntu 5.4.123.

Where can i find the pyc file?

The python3 version is Python 3.5.3 in my os.
mkdir workspace
cd workspace
vim print.py
print("i am learning")
Saved and exit.
python3 print.py
i am learning
As far as i knew, python source file was parsed and compiled into pyc file when to execute it.
ls
print.py
There is no pyc file in workspace directory,where is the complied print.py file then?
sudo find / -name ".pyc"
The find command still can't search pyc file such as print.pyc .
python3 -m compileall can create the compiled file for print.py manually,where is the compiled file for print.py created by python itself?
Does python3 delete the print.pyc after executing python3 print.py?
Ok this is one big of a problem I ever had when I'm started to learn python few years back. Python is just like any other oop programming languages which does compilation before program execution. When python compiles its program, it creates the bite code which is you can see by standard library called dis.
import dis
print(dis.dis(your_program))
Sometimes (not always) python creates .pyc file for the running programs to improve the speed up the loading of import modules but not to improve the execution time. So hope you get intuition behind .pyc, furthermore .pyc only creates when your module is import by another module.
As an example, Imagine you have this print.py (Let's modify it shall we)
def return_print_statment(statement):
print('Printed version: ', statement)
Suppose this module imported by another custom module called views.py. In views.py there is a module_view which will use the return_print_statment
from print import return_print_statment
def module_view():
...
return_print_statment(output)
So in the compilation, since you have imported the print.py python will generate print.pyc file for it. In python 2.0 python will put the .pyc to right next to your program in the same folder, but in python3 instead of creating in the same folder python will create separate folder called __pycache__ in the same directory to put these byte codes.
python3 -m compileall .
To compile all .py files in your current directory.
http://effbot.org/pyfaq/how-do-i-create-a-pyc-file.htm

Imports using PyCharm don't work on command line

I'm a bit new to Python and I'm building a project in PyCharm since I'm used to IntelliJ, and have a problem with my file structure. When I need to import a file in the same subdirectory-- directory c, I have to type
from a.b.c import y where a is the project's home directory b.c is the sub directory I'm in.
So I'm not able to import y directory. Which this then causes a problem if I want to run this file via command line, it uses the current directory as the path, meaning the import doesn't know anything about x.xx. What can I do to fix this issue?
Thanks!
For the purposes of this answer I'm assuming y is a Python module in the c directory. In other words there is a file called y.py in a/b/c.
import y works in a Python module in directory c if the current working directory is also c.
In Intellij IDEA with the Python plugin (much the same as PyCharm most of the time) the current working directory is called the "Working Directory" in each Run/Debug configuration you set up to run your script.
import y will also work if c is on the PYTHONPATH.
The other way to make y available to the import statement is to turn a and b directories into Python packages. That means at least putting an empty __init__.py file in both the a and b directories.
You can then use a as the root directory for the project, and use:
from a.b.c import y
It's worth reading The Definitive Guide to Python import Statements if you're not sure how Python resolves imports.

How to get absolute pyc file path with python 3.x?

How can we get the compiled python pyc file path with python 3.x in the current environment? I know it's in the __pycache__ direcotry, but I couldn't find a way to find the file path. Because the names of pyc files of python 3 changes by the environment.
Given that you know the path to the source (ie .py) file, there's a function importlib.util.cache_from_source that does exactly what you want. For example, to get the .pyc file corresponding to the numpy package, you would do:
import importlib
import numpy
importlib.util.cache_from_source(numpy.__file__)
For me (on OS X), this prints out something along the lines of:
/<absolute path to site-packages>/numpy/__pycache__/__init__.cpython-36.pyc

Importing submodules

I am new to python and i m having a really bad time to overcome a problem with the importing system.
Lets say i have the file system presented below:
/src
/src/main.py
/src/submodules/
/src/submodules/submodule.py
/src/submodules/subsubmodules
/src/submodules/subsubmodules/subsubmodule.py
All the folders (src, submodules, subsubmodules) have and empty __init__.py file.
In submodule.py i have:
from subsubmodules import subsubmodule
In main.py i have:
from submodules import submodule
When i run submodule.py python accepts the import. But when i run main.py python raises error for the import of subsubmodule.py because /src/submodules/subsubmodules/ folder is not in the path.
Only solution is to change the import of submodule.py to
from submodules.subsubmodules import subsubmodule
This seems to me as an awful solution because after that i cannot run submodule.py and i m sure that something else is the key to that.
An other solution is to add the following code to the __init__.py file:
import os
import sys
import inspect
cmd_subfolder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
Is there any way to do this using just the importing system of python and not other methods that do it manually using, for example sys.path or other modules like os, inspect etc..?
How can i import modules without caring about the modules they import?
You can run subsubmodule.py as
python3 -m submodule.subsubmodules.subsubmodule
If you want a shorter way to invoke it, you're free to add a shell or Python script for that on the top level of your package.
This is how imports work in Python 3; there are reasons for that.
You can avoid this issue by using sys.path in your program.
sys.path.insert(0, './lib')
import subsubmodule
For this code, you can put all your imports to a lib folder.
You can read the official documentation on Python packages where this is explained in depth.

Resources