Welcome to Synthiam!

Program robots using technologies created from industry experts. ARC is our free-to-use robot programming software that makes features like vision recognition, navigation and artificial intelligence easy.
Get Started

France
Asked — Edited
Resolved Resolved by ptp!

I Need Help For A Python Script (Conversion Of An Old EZ Script)

Hi,

I try to convert an old EZ scripts into a python scripts
It is a script that reads a number from a txt file, makes a calculation, then rewrite the file with the new value.

The following EZ scripts works fine:

Code:


# Close the text file to make it accessible
FileReadClose("C:\Users\FredWin\Documents\ARC\Scripts\Calc.txt")

# Obtain a number from the text files and use it as variable
$calc = FileReadAll("C:\Users\FredWin\Documents\ARC\Scripts\Calc.txt")

# Show the number in the debug window<br />Print("old value:")
Print($calc)

# Calculation
$calc = $calc + 1
Print("---")
Print("new value:")
Print($calc)
FileDelete("C:\Users\FredWin\Documents\ARC\Scripts\Calc.txt")
FileWrite("C:\Users\FredWin\Documents\ARC\Scripts\Calc.txt", $calc)

But the following python script does not:

Code:


# Close the text file to make it accessible
File.ReadClose("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt")

# Obtain a number from the text files and use it as variable
setVar("$calc2", File.ReadAllText("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt") )
calc2 = (getVar( "$calc2" ))

# Show the number in the debug window
print("old value")
print(calc2, type(calc2))

# Calculation
calc2 = ( calc2 + 1)
print("---")
print("new value")
print(calc2, type(calc2))
File.Delete("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt")
File.Append("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt", calc2)

The problem seems to be with the "File.Append" function. Instead of putting a number for the new calc2 value in the txt file, it writes a special character. So after that, calc2 is considered as a string, and the scripts cannot make the calculation anymore.

Any idea ?
Thanks


Related Hardware EZ-Robot EZ-B v4
Related Control Script
AI Support Bot
Related Content
Synthiam
Based on your post activity, we found some content that may be interesting to you. Explore these other tutorials and community conversations.
#2   — Edited

Code:

path = ("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt")
def calc():
with open(path,'r+') as file:
calc2 = int(file.read())
print('old value')
print(calc2)
calc2 = (calc2 + 1)
print('new value')
print(calc2)
file.truncate(0) # to remove content in your file
file.seek(0)
file.write(str(calc2))

calc()
Hey there, I hope I understood correctly what you are trying to achieve...this code should work!:D
#3  
Short mode:

@Fredbec and others:
You are mixing different environments, so is important to understand each and the limitations.

@DJ:
There is a bug 

Next I'll breakdown in multiple posts.
#4  
Python World:
There is Python 2 and Python 3, and they are not the same there are significant changes, Python 2 is deprecated.

ARC Python support is build on top of IronPython https://ironpython.net/
I've crossed paths a few years ago and we gave up due to lack of support, IronPython is on life support. Microsoft gave up, the main architect left to google and is being supported by volunteers. 

IronPython is (Python 2).

The reason why Python is growing is due to the use on scientific, robotic and ITOps areas, also there are a lot of good libraries to do impressive stuff scipy https://www.scipy.org/ is one of them.

There is another player CPython: https://en.wikipedia.org/wiki/CPython, allows calling native methods from C, is used also to compile Python to C.
That is the reason why some ROS scripts work well in embedded computers, the Python libraries are calling native code (c++).

When Microsoft released the IronPython, the community look to integrate different libraries with IronPython, but, there is a problem IronPython works on top of .NET so is managed not native code.

Anything with components written in C (for example NumPy, which is a component of SciPy) will not work on IronPython as the external language interface works differently. Any C language component will probably not work unless it has been explicitly ported to work with IronPython.

So basically all the python super powerful libraries are not available to IronPython.

Is important to understand there are a few different types in Python:
bytes, bytearray, list and tuples, they look the same but they are different.

Python2 script:

Code:

def PrintType(arg):
print "{} {}".format(type(arg), arg)

str1 = 'this is a string'
PrintType(str1)

bytes1 = bytes(str1)
PrintType(bytes1)

bytearray1 = bytearray(str1)
PrintType(bytearray1)

list1 = [1,2,3,4,5]
PrintType(list1)

tuple1 = (1,2,3,4,5)
PrintType(tuple1)
Python 2 execution:
User-inserted image


ARC (IronPython):
User-inserted image


One of differences between Python 2 and Python 3 is the bytes type.

In Pyton2 bytes type is an alias to str type.

But that is not true in IronPython, bytes is not an alias. There are other differences between Python 2 and IronPython, and sometimes they can be relevant when using Python 2 code.

To summarize:
Use Python 2 code
Some Python 2 code may not work as expected on top of IronPython (ARC)
#5   — Edited
EZ-Script:
EZ-Script has a few of limitations, and is easy to understand why DJ is pushing and motivating people to move to Javascript (Interpreted), Python2 (.NET Managed = .NET C# code).

One of the issues with EZ-Script is the lack of data types, initially everything was handled as string, and converted on demand (when needed) to integers (32 bits), later DJ changed the conversion to big ints (64 bits).

So basically when you set a variable in ARC, there is no type, so if you send a typed value from Javascript, Pyhon, plugin (C#)  to EZ-Script and you try to get the value back you will lose the original type.

One example:
User-inserted image


So if you send a string to ARC, and if that is string is similar to number ARC will return a float.
So is important to understand you need to convert back to the original type and or validate if the value is not changed in between your calls.
In my example I sent a string "10" and i got back a float, the script will fail if i use the value to concat with another string.

Code:

import datetime

def printType(arg, org=''):
print "{} {} {}".format(org, arg, type(arg))

print "---"

var1=10
printType(var1)
setVar("$arc1", var1)
printType(getVar("$arc1"), 'arc=>')
print "---"

var1=10.1
printType(var1)
setVar("$arc1", var1)
printType(getVar("$arc1"), 'arc=>')
print "---"

var1="10"
printType(var1)
setVar("$arc1", var1)
printType(getVar("$arc1"), 'arc=>')
print "---"

var1 = datetime.datetime.now()
printType(var1)
setVar("$arc1", var1)
printType(getVar("$arc1"), 'arc=>')
print "---"
To summarize:
Keep your calculations in one side (Python), and if you exchange values with EZ-Script pay attention to the types, don't assume the value data  type is the same, validate and use conversion functions: str(x), int(x), float(x)  
#6  
@DJ:
There is a bug you can't call:

Code:

File.Append(filename, byteArray) 
from python.
I believe your implementation does not take in consideration the different Python types: bytes, bytearray, list, tuple

Python script:

Code:

def PrintType(arg):
print 'pythonType={} value={}'.format(type(arg), arg)


str1 = 'this is a string'
PrintType(str1)

bytes1 = bytes(str1)
PrintType(bytes1)

byteArray1 = bytearray(str1)
PrintType(byteArray1)

list1=[1, 2, 3, 4, 5]
PrintType(list1)

tuple1 = (1, 2, 3, 4, 5)
PrintType(tuple1)

filename="c:\temp\test1.txt"
File.ReadClose(filename);
File.Append(filename, byteArray1)
User-inserted image


None of the "array types" will work with File.Append

I did a small implementation here:
https://github.com/ppedro74/Utils/blob/master/IronPythonTests/IronPythonTests.Common/PythonEngine.cs

User-inserted image

you will need different method signatures on File.Append to support the different Python types.
#7  
@Fredebec:

I fixed your Python script:

Code:

fileName="c:\\temp\\calc.txt"
File.ReadClose(fileName)

str1=File.ReadAllText(fileName)
int1=int(str1)
int1=int1+1

setVar("$value1", int1)

str1 = str(int1)
File.Delete(fileName)
File.AppendString(fileName, str1)

#get value from ARC
var1=getVar("$value1")
int1=int(var1)
int1=int1+1

str1 = str(int1)
File.Delete(fileName)
File.AppendString(fileName, str1)
I prefixed the variables with type to be clear the data type being used.
Synthiam
#8   — Edited
Right on - i fixed the file append and other byte array references for the next beta channel release
England
#9  
Also note the filename from PTP's solution. You cannot use a single backslash "\" as this is used to denote a special character.
Most python variations will allow you to use the forward slash "/" instead without any problems ie

'c:/folder/subfolder/filename'

Another option is :-

import os
myfile = os.path.normpath('c:/folder/subfolder/filename')
open(myfile)

I'll have to test how these work with ARC python.

    skidroe
England
#10   — Edited
Using the forward slash it will work on Windows and Linux.
Tested with ARC and this works fine :-

myfile = "C:/temp/Calc.txt"

f = open(myfile)
val = int(f.read())
f.close()

print "Old Value is ", val
val = val + 1
setVar("$calc", val)

print "New Value is ", val

f = open(myfile,"w")
f.write(str(val))
f.close()
#11  
Thank you all for your help and all the information.
Some is a little beyond my actual knowledge, but I will learn... :-)

I have to admit I am a little lost between what is specific to Python and what is related to ARC.
For example, to open and write into a file, I don't know if I should use "File.Read..." and "File.Append..." or some command suggested by @skidroe ("open(myfile)", "...write",...) and what's the difference...
#12  

Quote:

I have to admit I am a little lost between what is specific to Python and what is related to ARC.
EZ-Script does not support object model, so ARC created specific objects to group similar functionalities:

JS:
User-inserted image


Python
User-inserted image


So you can see there are consistency between languages and features.

Returning to your Python code: File.* is a ARC object not a native Python2 object.
#13   — Edited
@Mickey script post #2:

Code:

path = ("C:\Users\FredWin\Documents\ARC\Scripts\Calc2.txt")
def calc():
with open(path,'r+') as file:
calc2 = int(file.read())
print('old value')
print(calc2)
calc2 = (calc2 + 1)
print('new value')
print(calc2)
file.truncate(0) # to remove content in your file
file.seek(0)
file.write(str(calc2))

calc()
or
@skidroe script post #10

Code:

myfile = "C:/temp/Calc.txt"

f = open(myfile)
val = int(f.read())
f.close()

print "Old Value is ", val
val = val + 1
setVar("$calc", val)

print "New Value is ", val

f = open(myfile,"w")
f.write(str(val))
f.close()
They use Python 2, and btw Python3 file APIs are slightly different, but, you need to stick with Python 2.
The exception is the ARC: setVar function.

ARC Javascript uses a .NET JS interpreter https://github.com/sebastienros/jint and has Full support for ECMAScript 5.1:
http://www.ecma-international.org/ecma-262/5.1/
The component only supports the language so File access requires the ARC File object.

ARC Python uses IronPython a .net dynamic language, and supports Python 2 standard lib which includes different modules like file access, networking, serial etc.
So if you want to access the file system, or even the .NET classes you can do it from Python, you don't need to use File ARC object. 

other objects like: Audio, ADC, Ping etc,  are specific to ARC features.
 
IronPython detailed documentation:
https://ironpython-test.readthedocs.io/en/latest/contents.html
#14  
@ptp, thanks a lot for your explanations. It is really helpful !

I am now going to play a little bit with everything I have learned in this thread...
#15  
Hey guys, I also learned a lot here...I did not really pay attention how Python is being implemented within ARC, and just used Python 3 out of habit!
Ups!!:D