Go Down

Topic: How can I share constants between Python and C++? (Read 1 time) previous topic - next topic

Coding Badly


The language tries to make it so you, the developer, normally do not have to care.  But there is a difference between 17 (exact) and 17.0 (estimate).  That difference can sometimes be important; even in Python.


westfw

You can run code through the C pre-processor to generate python-compatible include files (essentially defining a meta-language for defining your constants.)
Code: [Select]
#ifdef PYTHON
#define COMMAND(name, string) name=string
#else // C, C++, etc
#define COMMAND(name, string) const char name[] = string;
#endif
COMMAND(dial, "ATDT")
COMMAND(hangup, "ATH")
COMMAND(answer, "ATA")




Quote
BillW-MacOSX-2<4993> avr-cpp -P -DPYTHON constants.h
dial="ATDT"
hangup="ATH"
answer="ATA"

BillW-MacOSX-2<4994> avr-cpp constants.h
# 1 "constants.h"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "constants.h"

const char dial[] = "ATDT";
const char hangup[] = "ATH";
const char answer[] = "ATA";
Note that cpp won't preserve indentation, so you'll be somewhat limited as to where the pre-processed output can be included in a python program...


Coding Badly


Clever.  I like it.  That can just be an extra step in building the C++ image.

(I wonder what it means that I've used a very similar technique ... uh ... more than a year ago and had completely forgotten about it.)


wvmarle

It does when parsing variables and some are character strings and others are numerical values... You can parse them all as string, but doing maths with strings doesn't really work well, even in Python.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Robin2

You can run code through the C pre-processor to generate python-compatible include files (essentially defining a meta-language for defining your constants.)
What advantage would that have compared to getting the Python code to read a .h file?

What might the output of the pre-processor look like, in comparison to what would be in the .h file?

To quote Reply #10
Quote
Cause the Arduino won't run Python and it's much easier to write the Pc side that way
why go to the trouble of using C pre-processor stuff to do something when it is easier to do the same thing in Python?

IMHO C pre-processor stuff is even more opaque than C/C++  :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

westfw

Quote
What advantage would that have compared to getting the Python code to read a .h file?
Because the processed file would be read by the (presumably well optimized) compiler, rather than needing to be parsed by user-written code.  You could (at least theoretically) do more complex pre-processor operations.
Quote
What might the output of the pre-processor look like, in comparison to what would be in the .h file?
I did give an example; I just had it come out to a bunch of python assignment statements.
Quote
IMHO C pre-processor stuff is even more opaque than C/C++  :)
Well; yeah.  But it's native to the C program, AND that is what would make it difficult for python to parse correctly without pre-processing.

Robin2

I did give an example;
I had a hunch that that was what the second piece in Reply #16 was. But it seems even more abstruse than the first piece :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Delta_G

Revisiting this idea and when I get to googling it my same old thread is the thing at the top of the screen. 

Well, unless someone else jumps up and hollers that they already have the code for this, I'm about to go on and write something in python that can read my shared constants .h file and make me a dictionary of all the #define terms. 

I'll share once I get it to work. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Delta_G

Oh, that got deep really quick.  I started thinking of the anatomy of a #define statement.  For the simple ones it's easy.  And that's what I need and what I'm about to write. 

You look for a line that startsWith "#define", break it at the first space, take everything from there to the second space and that's the key, then everything from there all the way to a newline or "//" goes as the value. 

That sounds easy.  But what about macros with arguments?  It could get really deep really quick.
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Delta_G

#24
Sep 18, 2019, 06:48 am Last Edit: Sep 18, 2019, 06:49 am by Delta_G
My crude first approach:

Code: [Select]
def readDoth():
   
    retDict = {}
   
    with open('/home/Delta_G/Arduino/libraries/RobotSharedDefines/RobotSharedDefines.h', 'r') as f:
       
        contentList = f.readlines()
       
   
    length = len(contentList)
   
    i=0
   
    while i < length:
       
        line = contentList[i]
       
        isDef = line.startswith('#define')
       
        if isDef:
            line.replace('\t', ' ')           
            split = line.split(' ', 2)
            if len(split) >= 3:
                retDict[split[1]] = split[2].strip()
           
        i += 1
         
    return retDict 



it works kind of.  It chokes for some reason if there are only tabs between the name and the value. 

for something like:
Code: [Select]
#define SOME_NAME\t\t\tsomething
it doesn't replace the tabs.  It's a shame, because I use tabs a lot to keep things lined up neatly. 

I'll figure it out tomorrow.  Bed for me now. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Robin2

#25
Sep 18, 2019, 09:14 am Last Edit: Sep 18, 2019, 09:15 am by Robin2
Why not create a special .h file for the items that you want Python to use? And only put in it #defines in a style that is easy to parse in Python.

An Arduino program could read several .h files of which one is the file with the shared Python data.

Another option might be to get Python to write the .h file in the first place. That way you could have any level of C++ complexity you want because Python would not have to parse it.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Delta_G

#26
Sep 18, 2019, 11:28 pm Last Edit: Sep 18, 2019, 11:30 pm by Delta_G
Hi Robin,

The reason I want to go C++ to python is just the architecture of the project.  This is for my robot and most of the development is happening in Arduino.  The python program is just a monitor of sorts that allows me to send and receive data from the bot.  The code on the bot is what it is and requires some effort to change.  The python code can change on a whim since it is running on the same machine it's written on.  So somehow having it read what is already in use on the other boards makes more sense to me. 

The real quest is to be able to go to one place to add or change one of these constant strings.  And that's something that will be happening while I'm developing on the Arduino side before I load code onto the boards. 

What I posted up there is enough to get me going now.  All I have to do is make sure there is at least one space behind the define name.  That's easy enough to do. 

When I started playing with this yesterday I thought I might write something useful.  But after thinking about it for a bit, it would be way more involved to try to write than I had originally thought.  So I'll just keep it at the hack level for now. 


I do agree that it sounds a lot easier to get python to write C++ code than to read it. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Delta_G

#27
Sep 19, 2019, 04:59 am Last Edit: Sep 19, 2019, 05:00 am by Delta_G
Oh, I see why the tabs weren't coming out.  It was strip that was getting the ones that it was getting.


Gee this one was just dumb.

Code: [Select]
line.replace('\t', ' ')

should be:

Code: [Select]
line = line.replace('\t', ' ')

|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Go Up