Find the path of an executable in Python

A good way to use executables on the system Path, auto-adding the .exe extension on Windows is by Python shutil.which

import shutil
import subprocess

# None if executable not found
exe = shutil.which('ls') 

cmd = [exe, '-l']  
print(cmd)

subprocess.run(cmd) 

The fact that shutil.which() returns None for non-found executables makes it convenient for use with Pytest

Free 2-D CAD overview

Related: Install DraftSight on Linux


From 2010 to 2019, Draftsight was a top choice for “free” Linux / Mac / Windows AutoCAD 2D-compatible CAD users. DraftSight 2019 brought a chill by requiring paid licenses for Windows, while introducing substantial 3-D functionality to DraftSight. It’s important to note that DraftSight must peroidically reregister and the DraftSight “free” license can in effect be remotely terminated.

This article focuses on drop-in replacements for 2-D AutoCAD. Numerous even more powerful free CAD programs exist, but they generally require retraining for users coming from AutoCAD.

Libre 2-D AutoCAD-like choices include:

  • QCAD
  • LibreCAD with native DXF.

DWG from QCAD and LibreCAD is via the free Teigha DWG ↔ DXF converter.

I didn’t include FreeCAD here as it’s for 3D / Solidworks (and also cannot open DWG at this time).

Free 2-D CAD comparison

itemDraftsightQCADLibreCAD
Licensefree, NOT libreGPLv3GPLv2
RegistrationperiodicNONO
Download64-bit .debsource or binarysource or PPA
DWGR2018Teigha DXF ↔ DWGread: yes. Write: Teigha DXF ↔ DWG
DXFR2018nativenative

Draftsight

Draftsight is free (but non-libre) and typically “just works” with DWG / DXF files from AutoCAD and other software. DraftSight “free” license can be remotely terminated, so be mindful if doing large deployments where “free” is counted on. Windows is no longer “free”.

  • DXF: native read/write
  • DWG: native read/write

QCAD

QCAD:

  • DXF: native read/write
  • DWG: non-free (paid) library OR use free Teigha DXF ↔ DWG converter.

QCAD paid vs. Community Edition features

LibreCAD

LibreCAD:

DWG ↔ DXF

Free, non-libre Teigha File Converter supports through R2017 DWG/DXF.
Teigha File Converter may be used to convert from DXF to DWG en masse as a first/last step. The OpenDesignAlliance is the same organization where QCad gets its non-free non-libre converter from.

Install DraftSight 2019 CAD on Linux

3DS DraftSight 2019 has 2-D and new for 2019 3-D functionality. DraftSight 2019 requires a paid license for Windows. DraftSight 2019 is available in yearly no-charge license for MacOS and Linux. DraftSight 2018 and earlier cease functioning on 31 DEC 2019.

DraftSight 2019 works on:

  • Linux (Ubuntu, Fedora) [no-charge beta]
  • Mac [no-charge beta]
  • Windows [paid license].

DraftSight:

  • is natively compatible with AutoCAD DWG/DXF formats through R2018 (used by AutoCAD 2019).
  • works remotely using X11-Forwarding or VNC/RDP.
  • is free but not libre
  • has been growing and well supported since DraftSight’s initial 2010 release

Install

  1. on Ubuntu:

    apt install gdebi
    
  2. Download DraftSight for Linux

  3. In Terminal:

    gdebi draftSight.deb
    
  4. Complete registration with an email address–they only ask for verification once per install.

Hi-DPI

If you have a high resolution screen and the GUI icons look too small, try Tools → Options → System Options → Display → Screen Options → Use Large Icons.

Notes

Usually DraftSight “just works” on native Ubuntu Linux.

It doesn’t seem like one can use WSL to workaround the Windows license limitation. Installing DraftSight into WSL took half an hour, and would just hang WSL until reboot. Perhaps someone will figure that one out….

DraftSight won’t start

Try command

/opt/dassault-systemes/DraftSight/Linux/DraftSight

see if the splash screen AND the second window requesting your registration pops up.

The registration window can be hidden under other app windows you have open.

Add DraftSight icon

If the Ubuntu desktop icon doesn’t show up for DraftSight, create ~/.local/share/applications/draftsight.desktop containing:

[Desktop Entry]
Name=DraftSight
Comment=Editing CAD images
GenericName=DraftSight
Exec="/opt/dassault-systemes/DraftSight/Linux/DraftSight"
Path=/opt/dassault-systemes/DraftSight/Linux
Type=Application
Terminal=false
Icon=dassault-systemes.draftsight
MimeType=image/vnd.dwg;image/vnd.dwt;image/vnd.dxf;application-vnd.dassault-systemes.draftsight-dwg;application-vnd.dassault-systemes.draftsight-dwt;application-vnd.dassault-systemes.draftsight-dxf
Categories=Application;Graphics;2DGraphics;RasterGraphics;

running Matlab from Pytest

A software package may have Matlab and Python functions. To test the Matlab functions from Pytest, create a test_matlab.py file like:

from pathlib import Path
import subprocess
import pytest
import shutil

R = Path(__file__).parent

OCTAVE = shutil.which('octave-cli')
MATLAB = shutil.which('matlab')


@pytest.mark.skipif(not MATLAB, reason="Matlab not available")
def test_matlab_api():
    subprocess.check_call([MATLAB, '-batch', 'test_myscript'],
                          cwd=R, timeout=60)


@pytest.mark.skipif(not OCTAVE, reason='octave not found')
def test_octave_api():
    subprocess.check_call([OCTAVE, 'test_myscript.m'],
                          cwd=R, timeout=60)


if __name__ == '__main__':
    pytest.main(['-xrsv', __file__])

This assumes the Matlab test script resides in the same directory as the test_matlab.py file, and is named like test_api.m.

Get user home directory in Matlab

GNU Octave understands that ~ tilde is the user’s home directory on any operating system, even Windows. Matlab, even though R2019a is not that smart. Matlab does not consistently understand ~, and I have been complaining to the Mathworks about this for over a decade, and still the Mathworks is saying WONTFIX.

For our work, we create a homepath.m that works for GNU Octave and Matlab on Linux, Mac and Windows. It returns the absolute path of the user home directory, for example:

  • Linux: /home/username
  • MacOS: /Users/username
  • Windows: C:\Users\Username

file “homepath.m” contains:

function hdir = homepath()

persistent h;

if isempty(h)
    if ispc % windows
        h = [getenv('HOMEDRIVE'),getenv('HOMEPATH')];
    else %linux,mac
        h = getenv('HOME');
    end
end

hdir = h;  % for Matlab

end

Import Python user modules in Matlab

This page shows how to setup Matlab with user Python install (e.g. Anaconda Python) on Linux, Mac or Windows.

Install Python for Matlab

Matlab is designed to work with specific Python versions for each Matlab version. Matlab will not specifically tell you when you’re using an incompatible Python version, but you may get unstable operation or errors.

In general, we recommend for Python ↔ Matlab interfacing:

  • Matlab ≥ R2018b, as R2018b made exchanging arrays with Python much more efficient and easy.
  • Python 3.6 or 3.7 for significant new functionality and performance
Matlab versionPython version
R2019a3.5, 3.6, 3.7
R2018b3.5, 3.6

You can just type in Matlab

pyversion

If you don’t see your desired Python version or install, here’s how to select a specific Python version.

select Python version to run from Matlab

This section is optional, for example if Matlab pyversion doesn’t find the desired Python version.

  1. Create and activate Python virtual environment (assuming Miniconda Python). This example is for Python 3.7.

    conda create -n py37 python==3.7
    
    conda activate py37
    
  2. the exact location of the Python executable to put in Matlab pyversion() command is determined by:

    python -c "import sys; print(sys.executable)"
    

    This examples assumes a Python 3.7 executable is at ~/miniconda3/envs/py37/bin/python. Setup Matlab to use Python 3.7 by adding to ~/Documents/MATLAB/startup.m

    pyversion('~/miniconda3/envs/py37/bin/python')
    
  3. verify Matlab → Python config by typing pyversion from within Matlab:

    version: '3.7'
    executable: '~/miniconda3/envs/py37/bin/python'
    library: '~/miniconda3/envs/py37/lib/libpython3.7m.so'
      home: '~/miniconda3/envs/py37'
    isloaded: 0
    

Install Python user programs

This example is for the “FindSSH” Python program, which concurrently searches out SSH servers on an IPv4 subnet. It’s useful to find IoT or Raspberry Pi etc. IP addresses quickly.

  1. setup Python user module, from Terminal or Command Prompt:

    git clone https://github.com/scivision/findssh
        
    cd findssh
    
    python -m pip install -e .[tests]   
    
  2. Check the Python code is working by itself from Terminal:

    python -m pytest   
    

    If this makes errors, they will need to be resolved before a Python user library will work in Matlab!

Notes

  • Python module import is implicit in the Matlab → Python module function call. There is no need to import numpy etc. from Matlab
  • Python executable choice persists across Matlab sessions–Matlab “remembers” even after you restart Matlab or reboot the computer.
  • editing imported Python module code requires restarting Matlab to take effect.

reference

Older versions of Matlab back to R2014b can also call Python from Matlab, but is more difficult to use, particularly for arrays / matrices:

Matlab versionPython version
R2018a3.5, 3.6
R2017b3.4, 3.5, 3.6
R2017a3.4, 3.5
R2016b3.3, 3.4, 3.5
R2016a3.3, 3.4
R2015b3.3, 3.4
R2015a3.3, 3.4
R2014b3.3

Troubleshooting

If you get

Error using pyversion Path argument does not specify a valid executable.

Ensure the Python executable path in file matlab.settings matches the desired Python executable. On Linux, this file is at ~/.matlab/R2018b/matlab.settings.

matlab.settings must have a section like:

<settings name="external">
    <settings name="interfaces">
        <settings name="python">
            <key name="Version">
                <string minArraySize="4" maxArraySize="4">
                    <value><![CDATA[3.6]]></value>
                    <value><![CDATA[/home/username/anaconda3/bin/python]]></value>
                    <value><![CDATA[/home/username/anaconda3]]></value>
                    <value><![CDATA[/home/username/anaconda3/lib/libpython3.6m.so]]></value>
                </string>
            </key>
        </settings>
    </settings>
</settings>

reference

Install Matlab integrated OpenCV C++/CUDA/MEX support

To use OpenCV from Matlab as integrated by the Mathworks, you will need to write your OpenCV calls in C++ and/or CUDA, using MEX. This works on Linux, Mac and Windows.

Install

  1. type in Matlab:

    visionSupportPackages
    
  2. select “Computer Vision System Toolbox OpenCV Interface by MathWorks Computer Vision System Toolbox Team” and install.

Note: the examples require particular compilers depending on Matlab version and operating system.

Examples

This directory contains Computer Vision Toolbox examples from the Mathworks. Find the Matlab OpenCV example directory, in Matlab:

fileparts(which('mexOpenCV'))

on Windows, Matlab OpenCV examples are under something like:

C:\ProgramData\MATLAB\SupportPackages\R2019a\toolbox\vision\supportpackages\visionopencv\example

The examples below assume you’re starting from this directory. See the README.txt in each directory for compilation details. Some examples require a CUDA GPU.

Foreground Detector

Compile example

cd ForegroundDetector

mexOpenCV backgroundSubtractorOCV.cpp

If the example fails to compile due to compiler mismatch, follow the instructions given in the error message. For example, on Windows with Matlab R2019a, Visual Studio C++ 2015 compiler is required. This can be obtained by downloading the Visual Studio compiler, and adding under the Visual Studio installer options “Individual Components” → VC++2015 toolset for desktop. This consumes an additional 3 GB of hard drive space!

Run the OpenCV Matlab demo:

testBackgroundSubtractor

You will see a Video Player window pop up with cars driving by, with the cars detected outlined in white rectangles.

mexopencv

The mexopencv package is user-friendly. Use it much like any other Matlab toolbox, with regular Matlab code. No need to code in C++ as with the Mathworks Matlab OpenCV support built-in from the factory. It also adds OpenCV to GNU Octave.

Matlab Fortran MEX selftest

These commands are all from within Matlab. They demonstrate that Matlab (or GNU Octave) MEX Fortran compiler wrapper is working on your system.

  1. using homepath.m, copy over an example Fortran program.

    copyfile(fullfile(matlabroot,'extern','examples','refbook','timestwo.F'), homepath) 
    copyfile(fullfile(matlabroot,'extern','include','fintrf.h'), homepath) 
    
  2. in Matlab or Octave:

    mex timestwo.F
    

    Building with ‘gfortran’. MEX completed successfully

  3. in Matlab or Octave:

    timestwo(3)
    

    ans = 6.0

Matlab MEX Fortran issues

mex -setup -v FORTRAN

mex.getCompilerConfigurations('FORTRAN')

If you get error

… Looking for folder ‘libgfortranbegin.a’ …No. Did not find installed compiler ‘gfortran’. Error using mex No supported compiler or SDK was found. For options, visit https://www.mathworks.com/support/compilers/current_release/.

For Windows, even through R2019a, MinGW Gfortran is not supported. The solution for Matlab and Fortran on Windows is to use Intel Fortran compiler, which is not free.

Consider using GNU Octave and Gfortran on Windows and Mac. Gfortran and Matlab MEX are fine on Linux.

Matlab MinGW compiler setup

Matlab requires C / C++ / Fortran compilers for numerous operations such as mex, loadlibrary and more. Matlab ≥ R2015b can use MinGW GNU compilers for Windows.

If Matlab doesn’t detect your MinGW compiler location, you may get an error like

Error in loadlibrary>getLoadLibraryCompilerConfiguration

or

Error using mex No supported compiler was found.

Fix

This fix is for Windows using MinGW compilers. Tell Matlab the MinGW compiler path via Windows environment variable MW_MINGW_LOC.

  1. Find the MinGW compiler location:

    where gcc
    
  2. in Matlab, assuming MinGW is under C:\mingw64\bin (don’t include “bin” below)

    setenv('MW_MINGW64_LOC', 'c:\mingw64')
    
  3. Setup MEX permanently

    mex -setup -v
        
    mex -setup -v C++
    

Note: Sadly, even through Matlab R2019a, Matlab cannot using MinGW Gfortran. Intel Fortran must be used on Windows and Mac with Matlab. On Linux, Gfortran is fine with MEX Matlab via

mex -setup -v Fortran

or consider using GNU Octave and Gfortran on Windows and Mac.

Verify

Matlab MEX parameters can be discovered from in Matlab by:

mex.getCompilerConfigurations('C')

mex.getCompilerConfigurations('C++')

mex.getCompilerConfigurations('FORTRAN')

Test Matlab C and C++ MEX

These commands are all from within Matlab. They demonstrate that Matlab (or GNU Octave) MEX C / C++ compiler wrapper is working on your system.

  1. Using the Matlab example to your home directory with homepath.m

    copyfile(fullfile(matlabroot,'extern','examples','mex','yprime.c'), homepath)
    
  2. in Matlab or GNU Octave compile the callable C-code by:

    mex([homepath,filesep,'yprime.c'])
    
  3. use the compiled C-code function from Matlab or Octave by:

    yprime(3,[4,2,7,1])
    

    which returns

    ans = 2.0000 5.9924 1.0000 2.986

Fix

if you get missing compiler errors, do Mex setup