motopy


Namemotopy JSON
Version 2.1.0 PyPI version JSON
download
home_page
SummaryThe tool of converting Matlab/Octave code TO PYthon.
upload_time2023-02-06 06:25:46
maintainer
docs_urlNone
author
requires_python>=3.7
license
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Motopy

`Motopy` is a tool used to translate Matlab/Octave code TO PYthon.

[点此查看中文说明](https://github.com/falwat/motopy/blob/main/readme_zh.md).

## Introduce

`Motopy` is a powerful tool used to translate `Matlab`/`Octave` code to `PYthon`. In the process of translation, the python statement generated by `mopy` will be executed to ensure the translated correctness of subsequent code. For example, the following `Matlab`/`Octave` code:

```m
a = ones(1, 3);
b = a';
c = a * b;
```
will be translated to `python` code:

```py
import numpy as np
a = np.ones((1, 3))
b = a.T
c = a @ b
```

The type of the variables `a` and `b` are array. So the third statement `c = a * b` will be translate to: `c = a @ b`.

## install

Please use `pip` install `motopy`:

```bash
pip install motopy
```

## Quick Start

`Motopy` is very easy to use. First please prepare your `Matlab`/`Octave` files, put the script file and the function files with extetion ".m" in a folder, and ensure that your `Matlab`/`Octave` script can be run without exception. And meet [Code Preprocessing](#Code_Preprocessing).Here's a simple example:
- Create a folder named "demo".
- In the "demo" folder, create two ".m" files whose names are "fun.m" and "func_test.m". Input the folowing text:
	```m
	% file: func.m
	function s = func(a, b)
	    s = sqrt(a.^2 + b.^2);
	end
	```

	```m
	% file: func_test.m
	a = 3;
	b = 4;
	s = func(a, b);
	disp(s)
	```
- In the "demo" folder, create a `python` script file. Import `motopy` and use `motopy.make()` translate your mfile:
  ```py
  import motopy
  motopy.make(entry_basename='func_test')
  ```
  The `entryfile` parameter specifies the mfile script to be translated(***!!Note that there is no extension!! ***).
  >  You can also execute the above code directly from the python command line. Ensure that the current directory is the "demo" folder.

### Specify the input/output folder

The `python` script file may not be placed in the same folder as the mfile, and the input mfile and the output `python` file may be in a different folder. You can use the `input_path` parameter to specify the location of the input mfile and the `output_path` parameter to specify the output path of the generated `python` file.
```py
import motopy

motopy.make(
    entry_basename='<the script filename without extension(*.m)>',
    input_path='<the input path of *.m files>', 
    output_path='<the output path of *.py files>' 
)
```

### Specify replaced function

If you have already translated a function, you can specify an replaced function to that function using the `replaced_functions` argument in the `motopy.make()` function.

```py
import motopy
motopy.make(
    entry_basename='func_test', # no extension
    input_path='The path that input ".m" files loaded', 
    output_path='The path that output ".py" files stored',
    replaced_functions={
        'func': ('func', 'func') # 
    }
)
```

The `replaced_functions` parameter is a dictionary, the key is the function name that appears in the mfile, and the value is a tuple (`module_name`, `function_name`). In the example above, the `func` function file will not be translated again.

When do you use `replaced_functions`:

- The `.py` file generated by `motopy` has been modified manually, and do not want `motopy` to regenerate it.

- The `.m` function that `motpy` does not support translated yet. You can implement it by yourself.

### Code Annotation

The code line started with "`%%>`" in mfile is a python statment. And will be inserted to generated `python` file. And the next statment will be skiped. For example, the mfile:

```m
%%> print('this is a code annotation.')
disp('this statment will be skiped.')
```
will be translated to:
```py
print('this is a code annotation.')
```



### Output Log

By default, `motopy` generate a log file named "motopy.log" under the `output_path` folder. You can use the 'logging_file' parameter to specify the output location and name of the log file. Using `logging_level` set log level: `WARN|INFO|DEBUG`

```py
import motopy
motopy.make(.., logging_level=motopy.DEBUG, ..)
```

### Indent

By default, the generated `.py` file uses 4 Spaces for indentation. You can use `indent` parameter specifies the number of Spaces required for indentation.

## Code Preprocessing

The translation will failed if your `Matlab`/`Octave` code don't satisfy the folowing requirements:

- Do not use blank spaces to separate elements in arrays and cells. The following code will make failed:

    ```m
    a = [1 2 3; 4 5 6];
    c = {1 2 'abc'};
    ```

- The first function name in a function file must be same as the filename.

- Arrays and cells should be defined before used and allocated enough space. The following code will make failed:

    ```m
    for k=1:5
        A(k) = 2*k; % The variable A is not defined before used.
    end
    ```

    ```m
    A = []; % The variable A has not enough space.
    for k=1:5
        A(k) = 2*k; % the size of variable A will grow in iteration.
    end
    ```

- Do not use "`[]`" to define empty array. The folowing mcode will translate failed:
    ```m
    A = [];
    for k=1:5
        B= rand(2,2);
        A = [A;B];
    end
    disp(A)
    ```
    The expression `[A;B]` translate failed. because the empty array A with size of `0x0` cannot concatenate with array B with size of `2x2`.

    An easy way to resolve this problem is to define the array `A` as an empty array with size of `0x2`:

    ```m
    A = zeros(0,2);
    for k=1:5
        B= rand(2,2);
        A = [A;B];
    end
    disp(A)
    ```

## Implemented Translation

### Creation of Array, Matrix and Cell 

Matlab/Octave|Python|Note
-|-|-
`a = [1,2,3,4]` | `a = np.array([1, 2, 3, 4])` | The array in `matlab` will be translated to `np.array`
`a = [1,2;3,4]` | `a = np.array([[1, 2], [3, 4]])`
`a = [1;2;3;4]` | `a = np.array([[1], [2], [3], [4]])`
`C = {1,2,3;'4',[5,6],{7,8,9}}` | `C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]]` | The cell in `matlab` will be translated to `list`
`r1 = 1:10;` | `r1 = arange(1, 11)` | `low_bound:high_bound` in `matlab` will be translated to `arange(low_bound, high_boud + 1)`
`N = 10;`<br>`r2 = 1:N;` | `N = 10`<br>`r2 = arange(1, N + 1)`
`zeros(3)` | `np.zeros((3, 3))`
`zeros(2,3)` | `np.zeros((2, 3))`
`ones(3)` | `np.ones((3, 3))`
`ones((2, 3))` | `np.ones((2, 3))`
`C = cell(2,3)` | `C = [[None for _c in range(3)] for _r in range(2)]`

### Slice of Array, Matrix and Cell 
Matlab/Octave|Python|Note
-|-|-
`a(1,1)` | `a[0, 0]` |  The value of `index` will decrease 1, if the `index` is a number.
`a(1,:)` | `a[0, :]`
`a(:,1)` | `a[:, 0]`
`a(1, 1:2)` | `a[0, 0:2]`
`a(1:2, 1)` | `a[0:2, 0]`
`a(1,2:end)` | `a[0, 1:]`
`m = 1;`<br>`n = 1;`<br>`a(m, n*2)` | `m = 1`<br>`n = 1`<br>`a[m - 1, n * 2 - 1]` | The `index` will be replaced with `index - 1`, if `index` is a variable.

### Functions

Matlab/Octave|Python|Note
-|-|-
`abs` | `np.abs`
`acos` | `np.arccos`
`asin` | `np.arcsin`
`atan` | `np.arctan`
`[y,Fs] = audioread(filename)` | `Fs, y = wavfile.read(filename)`
`ceil` | `np.ceil`
`cos` | `np.cos`
`diag` | `np.diag`
`d = dir(name)` | `d = [{'name':e.name, 'folder':e.path, 'isdir':e.is_dir()} for e in scandir(name)]`
`disp` | `print`
`eye` | `np.eye`
`exp` | `np.exp`
`fft` | `np.fft`
`fix` | `np.fix`
`floor` | `np.floor`
`fprintf` | 
`ifft` | `np.ifft`
`inv` | `linalg.inv`
`linspace` | `np.linspace`
`S = load('data.mat')`| `S = loadmat('data.mat')` | the Variable `S` is a dict 
`A = load('data.txt')` | `A = np.loadtxt('data.txt')` | the file "data.txt" is a ASCII data.
`load('data.mat')` | `_mat = loadmat('data.mat');`<br>`a = _mat['a'];`<br>`b = _mat['b']` | assume there are two variable `a` and `b` in "data.mat"
`load('data.txt')` | `data = np.loadtxt('data.txt')` | the file "data.txt" is a ASCII data.
`log` | `np.log`
`log10` | `np.log10`
`log2` | `np.log2`
`mod` | `np.mod`
`ndims` | `np.ndim`
`numel` | `np.size`
`pinv` | `linalg.pinv`
`rand` | `random.rand`
`rank` | `linalg.matrix_rank`
`round` | `np.round`
`sin` | `np.sin`
`sort` | `np.sort`
`sprintf('%d%s',a, b)` | `f'{a}{b}'`
`sqrt` | `np.sqrt`
`s = strcat(s1,...,sN)` | `s = ''.join([s1,...,sN])`
`unique` | `np.unique`

## Change Log

See [changelog.md](https://github.com/falwat/motopy/blob/main/changelog.md) for more information.

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "motopy",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "",
    "author": "",
    "author_email": "Jackie Wang <falwat@163.com>",
    "download_url": "https://files.pythonhosted.org/packages/06/6a/915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7/motopy-2.1.0.tar.gz",
    "platform": null,
    "description": "# Motopy\n\n`Motopy` is a tool used to translate Matlab/Octave code TO PYthon.\n\n[\u70b9\u6b64\u67e5\u770b\u4e2d\u6587\u8bf4\u660e](https://github.com/falwat/motopy/blob/main/readme_zh.md).\n\n## Introduce\n\n`Motopy` is a powerful tool used to translate `Matlab`/`Octave` code to `PYthon`. In the process of translation, the python statement generated by `mopy` will be executed to ensure the translated correctness of subsequent code. For example, the following `Matlab`/`Octave` code:\n\n```m\na = ones(1, 3);\nb = a';\nc = a * b;\n```\nwill be translated to `python` code:\n\n```py\nimport numpy as np\na = np.ones((1, 3))\nb = a.T\nc = a @ b\n```\n\nThe type of the variables `a` and `b` are array. So the third statement `c = a * b` will be translate to: `c = a @ b`.\n\n## install\n\nPlease use `pip` install `motopy`:\n\n```bash\npip install motopy\n```\n\n## Quick Start\n\n`Motopy` is very easy to use. First please prepare your `Matlab`/`Octave` files, put the script file and the function files with extetion \".m\" in a folder, and ensure that your `Matlab`/`Octave` script can be run without exception. And meet [Code Preprocessing](#Code_Preprocessing).Here's a simple example:\n- Create a folder named \"demo\".\n- In the \"demo\" folder, create two \".m\" files whose names are \"fun.m\" and \"func_test.m\". Input the folowing text:\n\t```m\n\t% file: func.m\n\tfunction s = func(a, b)\n\t    s = sqrt(a.^2 + b.^2);\n\tend\n\t```\n\n\t```m\n\t% file: func_test.m\n\ta = 3;\n\tb = 4;\n\ts = func(a, b);\n\tdisp(s)\n\t```\n- In the \"demo\" folder, create a `python` script file. Import `motopy` and use `motopy.make()` translate your mfile:\n  ```py\n  import motopy\n  motopy.make(entry_basename='func_test')\n  ```\n  The `entryfile` parameter specifies the mfile script to be translated(***!!Note that there is no extension!! ***).\n  >  You can also execute the above code directly from the python command line. Ensure that the current directory is the \"demo\" folder.\n\n### Specify the input/output folder\n\nThe `python` script file may not be placed in the same folder as the mfile, and the input mfile and the output `python` file may be in a different folder. You can use the `input_path` parameter to specify the location of the input mfile and the `output_path` parameter to specify the output path of the generated `python` file.\n```py\nimport motopy\n\nmotopy.make(\n    entry_basename='<the script filename without extension(*.m)>',\n    input_path='<the input path of *.m files>', \n    output_path='<the output path of *.py files>' \n)\n```\n\n### Specify replaced function\n\nIf you have already translated a function, you can specify an replaced function to that function using the `replaced_functions` argument in the `motopy.make()` function.\n\n```py\nimport motopy\nmotopy.make(\n    entry_basename='func_test', # no extension\n    input_path='The path that input \".m\" files loaded', \n    output_path='The path that output \".py\" files stored',\n    replaced_functions={\n        'func': ('func', 'func') # \n    }\n)\n```\n\nThe `replaced_functions` parameter is a dictionary, the key is the function name that appears in the mfile, and the value is a tuple (`module_name`, `function_name`). In the example above, the `func` function file will not be translated again.\n\nWhen do you use `replaced_functions`:\n\n- The `.py` file generated by `motopy` has been modified manually, and do not want `motopy` to regenerate it.\n\n- The `.m` function that `motpy` does not support translated yet. You can implement it by yourself.\n\n### Code Annotation\n\nThe code line started with \"`%%>`\" in mfile is a python statment. And will be inserted to generated `python` file. And the next statment will be skiped. For example, the mfile:\n\n```m\n%%> print('this is a code annotation.')\ndisp('this statment will be skiped.')\n```\nwill be translated to:\n```py\nprint('this is a code annotation.')\n```\n\n\n\n### Output Log\n\nBy default, `motopy` generate a log file named \"motopy.log\" under the `output_path` folder. You can use the 'logging_file' parameter to specify the output location and name of the log file. Using `logging_level` set log level: `WARN|INFO|DEBUG`\n\n```py\nimport motopy\nmotopy.make(.., logging_level=motopy.DEBUG, ..)\n```\n\n### Indent\n\nBy default, the generated `.py` file uses 4 Spaces for indentation. You can use `indent` parameter specifies the number of Spaces required for indentation.\n\n## Code Preprocessing\n\nThe translation will failed if your `Matlab`/`Octave` code don't satisfy the folowing requirements:\n\n- Do not use blank spaces to separate elements in arrays and cells. The following code will make failed:\n\n    ```m\n    a = [1 2 3; 4 5 6];\n    c = {1 2 'abc'};\n    ```\n\n- The first function name in a function file must be same as the filename.\n\n- Arrays and cells should be defined before used and allocated enough space. The following code will make failed:\n\n    ```m\n    for k=1:5\n        A(k) = 2*k; % The variable A is not defined before used.\n    end\n    ```\n\n    ```m\n    A = []; % The variable A has not enough space.\n    for k=1:5\n        A(k) = 2*k; % the size of variable A will grow in iteration.\n    end\n    ```\n\n- Do not use \"`[]`\" to define empty array. The folowing mcode will translate failed:\n    ```m\n    A = [];\n    for k=1:5\n        B= rand(2,2);\n        A = [A;B];\n    end\n    disp(A)\n    ```\n    The expression `[A;B]` translate failed. because the empty array A with size of `0x0` cannot concatenate with array B with size of `2x2`.\n\n    An easy way to resolve this problem is to define the array `A` as an empty array with size of `0x2`:\n\n    ```m\n    A = zeros(0,2);\n    for k=1:5\n        B= rand(2,2);\n        A = [A;B];\n    end\n    disp(A)\n    ```\n\n## Implemented Translation\n\n### Creation of Array, Matrix and Cell \n\nMatlab/Octave|Python|Note\n-|-|-\n`a = [1,2,3,4]` | `a = np.array([1, 2, 3, 4])` | The array in `matlab` will be translated to `np.array`\n`a = [1,2;3,4]` | `a = np.array([[1, 2], [3, 4]])`\n`a = [1;2;3;4]` | `a = np.array([[1], [2], [3], [4]])`\n`C = {1,2,3;'4',[5,6],{7,8,9}}` | `C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]]` | The cell in `matlab` will be translated to `list`\n`r1 = 1:10;` | `r1 = arange(1, 11)` | `low_bound:high_bound` in `matlab` will be translated to `arange(low_bound, high_boud + 1)`\n`N = 10;`<br>`r2 = 1:N;` | `N = 10`<br>`r2 = arange(1, N + 1)`\n`zeros(3)` | `np.zeros((3, 3))`\n`zeros(2,3)` | `np.zeros((2, 3))`\n`ones(3)` | `np.ones((3, 3))`\n`ones((2, 3))` | `np.ones((2, 3))`\n`C = cell(2,3)` | `C = [[None for _c in range(3)] for _r in range(2)]`\n\n### Slice of Array, Matrix and Cell \nMatlab/Octave|Python|Note\n-|-|-\n`a(1,1)` | `a[0, 0]` |  The value of `index` will decrease 1, if the `index` is a number.\n`a(1,:)` | `a[0, :]`\n`a(:,1)` | `a[:, 0]`\n`a(1, 1:2)` | `a[0, 0:2]`\n`a(1:2, 1)` | `a[0:2, 0]`\n`a(1,2:end)` | `a[0, 1:]`\n`m = 1;`<br>`n = 1;`<br>`a(m, n*2)` | `m = 1`<br>`n = 1`<br>`a[m - 1, n * 2 - 1]` | The `index` will be replaced with `index - 1`, if `index` is a variable.\n\n### Functions\n\nMatlab/Octave|Python|Note\n-|-|-\n`abs` | `np.abs`\n`acos` | `np.arccos`\n`asin` | `np.arcsin`\n`atan` | `np.arctan`\n`[y,Fs] = audioread(filename)` | `Fs, y = wavfile.read(filename)`\n`ceil` | `np.ceil`\n`cos` | `np.cos`\n`diag` | `np.diag`\n`d = dir(name)` | `d = [{'name':e.name, 'folder':e.path, 'isdir':e.is_dir()} for e in scandir(name)]`\n`disp` | `print`\n`eye` | `np.eye`\n`exp` | `np.exp`\n`fft` | `np.fft`\n`fix` | `np.fix`\n`floor` | `np.floor`\n`fprintf` | \n`ifft` | `np.ifft`\n`inv` | `linalg.inv`\n`linspace` | `np.linspace`\n`S = load('data.mat')`| `S = loadmat('data.mat')` | the Variable `S` is a dict \n`A = load('data.txt')` | `A = np.loadtxt('data.txt')` | the file \"data.txt\" is a ASCII data.\n`load('data.mat')` | `_mat = loadmat('data.mat');`<br>`a = _mat['a'];`<br>`b = _mat['b']` | assume there are two variable `a` and `b` in \"data.mat\"\n`load('data.txt')` | `data = np.loadtxt('data.txt')` | the file \"data.txt\" is a ASCII data.\n`log` | `np.log`\n`log10` | `np.log10`\n`log2` | `np.log2`\n`mod` | `np.mod`\n`ndims` | `np.ndim`\n`numel` | `np.size`\n`pinv` | `linalg.pinv`\n`rand` | `random.rand`\n`rank` | `linalg.matrix_rank`\n`round` | `np.round`\n`sin` | `np.sin`\n`sort` | `np.sort`\n`sprintf('%d%s',a, b)` | `f'{a}{b}'`\n`sqrt` | `np.sqrt`\n`s = strcat(s1,...,sN)` | `s = ''.join([s1,...,sN])`\n`unique` | `np.unique`\n\n## Change Log\n\nSee [changelog.md](https://github.com/falwat/motopy/blob/main/changelog.md) for more information.\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "The tool of converting Matlab/Octave code TO PYthon.",
    "version": "2.1.0",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "beb64ef65d94ca145481fde756bf9baa863d183854f7d82d4ba81ae72484e783",
                "md5": "e5fcbc07ff6a27ba64c00f630b3e4277",
                "sha256": "786ff1a012186e53e746eab98b4d09a7665f9d30434e45279aa3ec13b34dac95"
            },
            "downloads": -1,
            "filename": "motopy-2.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e5fcbc07ff6a27ba64c00f630b3e4277",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 24839,
            "upload_time": "2023-02-06T06:25:44",
            "upload_time_iso_8601": "2023-02-06T06:25:44.268388Z",
            "url": "https://files.pythonhosted.org/packages/be/b6/4ef65d94ca145481fde756bf9baa863d183854f7d82d4ba81ae72484e783/motopy-2.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "066a915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7",
                "md5": "44e2fafd2ff6492d923c7a1dfd3449c9",
                "sha256": "2009fcb6c7a786cc39cc47acbc6c86c0ec8b7a7ac3cb64f020131970c568487a"
            },
            "downloads": -1,
            "filename": "motopy-2.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "44e2fafd2ff6492d923c7a1dfd3449c9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 31803,
            "upload_time": "2023-02-06T06:25:46",
            "upload_time_iso_8601": "2023-02-06T06:25:46.342899Z",
            "url": "https://files.pythonhosted.org/packages/06/6a/915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7/motopy-2.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-06 06:25:46",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "motopy"
}
        
Elapsed time: 0.03853s