0

I'm scaling the Gcode for my CNC laser power output. The laser's "S" value maxes at 225 and the current file scale is 1000. I need to multiply only/all S values by .225, omit S values of 0, and replace in the string for each line. There are pre-designated "M", "G", "X", "Y", "Z", "F", and "S" in the Gcode for axis movement and machine functions.

Note: I can't do this manually as there's like 7.5k lines of code.

Hoping for .py with an outcome like (top 3 lines):

Old> G1Y0.1S0     New> G1Y0.1S0
Old> G1X0.1S248   New> G1X0.1S55.8
Old> G1X0.1S795.3 New> G1X0.1S178.9

Example file Code:

G1Y0.1S0
G1X0.1S248
G1X0.1S795.3
G1X0.2S909.4
G1X0.1S874
G1X0.1S374
G1X1.1S0
G1X0.1S610.2
G1X0.1S893.7
G1X0.6S909.4
G1X0.1S893.7
G1X0.1S661.4
G1X0.1S157.5
G1X0.1Y0.1S0
G1X-0.1S66.9
G1X-0.1S539.4
G1X-0.2S909.4
G1X-0.1S897.6
G1X-0.1S811
G1X-0.1S515.7
G1X-0.1S633.9
G1X-0.1S874
G1X-0.3S909.4
G1X-0.1S326.8
G1X-0.8S0

Tried this:

import os
import sys
import fileinput

print("Text to Search For:")
textToSearch = input("> ")

print("Set Max Power Output:")
valueMult = input("> ")

print("File to work:")
fileToWork = input("> ")

tempFile = open(fileToWork, 'r+')

sValue = int

for line in fileinput.input (fileToWork):
    if textToSearch in line:
        c = str(textToSearch,(sValue)) #This is where I'm stuck.
        print("Match Found >> ", sValue)
    else:
        print("Match Not Found")
        
    tempFile.write(line.replace(textToSearch, (sValue,"(sValue * (int(valueMult)/1000))")))
    
tempFile.close()

#input("\n\n Press Enter to Exit")

Output:

Text to Search For:
> S
Set Max Power Output:
> 225
File to work:
> test.rtf
Match Not Found
Traceback (most recent call last):
  File "/Users/iamme/Desktop/ConvertGcode.py", line 25, in <module>
    tempFile.write(line.replace(textToSearch, (sValue,"(sValue * (int(valueMult)/1000))")))
TypeError: replace() argument 2 must be str, not tuple
>>> 

test.rtf file:

Hello World

X-095Y15S434.5

That is Solid!

1 Answers1

0

Your code has a couple of issues that need to be addressed:

  • first, you declare the sValue variable but never assign it the value from every line in your loop,
  • second, said variable is an int, but should be a float or you'll lose the decimal part seen in the file,
  • and third, since you're not getting the corresponding values, you're not multiplying the aforementioned values by the new scale factor to then replace the old with this.

Additionally, you're opening the original file in read/write mode (r+), but I would recommend you write to a new file instead.

Now, here is your code with fixes and changes (I'm taking the liberty to write variable names in Python style):

multiplier = input("New max power output for S: ")
input_file = input("Input file: ")
output_file = input("Output file: ")

with open(input_file, 'r') as source, open(output_file, 'w') as target:
    for line in source:
        if 'S' in line:
            line = line.removesuffix('\n')
            split_line = line.split('S', -1)
            new_value = float(split_line[1]) * float(multiplier)
            new_line = f'{split_line[0]}S{new_value:.1f}\n'
            print(f'Old> {line:25s}New> {new_line}', end='')
            target.write(new_line)
        else:
            target.write(line)

As you can see, we open both source and target files at the same time. By using the with statement, the files are closed at the end of that block.

The code assumes the text to search will appear no more than once per line.

When a match is found, we need to remove the newline from the line (\n) so it's easy to work with the number after the S. We split the line in two parts (stored in the list split_line), and convert the second element (S's value) to a float and multiply it by the entered multiplier. Then we construct the new line with its new value, print the old and new lines, and write it to the target file. We also write the line to the target file when a match isn't found so we don't lose them.

IMPORTANT: this code also assumes no additional values appear after S{value} in the lines, as per your sample. If that is not the case, this code will fail when reaching those lines.