pythonlistinsertg-code

Insert Item into line on text file with Python


I have a large gcode/text file. I want to search the file and if a line contains the word 'layer' like:

; layer 1, Z = 0.500

Then I want to add this below it once every x amount of layers:

;Clean Nozzle
G0 X30 Y-47 F10000
G0 X70 Y-47
G0 X30 Y-47

This will tell the nozzle of a 3D printer to pass over a fixed wire brush to clean the nozzle. I don't want it to do this every layer, just once every X amount of layers.

My Python Script so far looks very confusing and doesn't work, so I think I should re-start from scratch. My plan was:

Code so far:

#!/usr/bin/env python3
import mmap

LayerCount = 1                                                           #Start layer counter at 1,  this will get increased every time a line includes the word 'layer' (later in this script)
index = 0
#open gcode file
with open('C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\TestSmall.gcode', 'rb', 0) as file, \
    mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s:      #weird mmap stuff is aparently better for large files
    contents = file.readlines()                                     #Makes a list called 'contents' containing each value in the gcode
    print('List:')
    print(contents)                                                 #Prints to terminal for sense checking

    #Create new gcode file containing the info.
    with open(r'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\New.gcode', 'w') as fp:
        for item in contents:                                       #I think this takes each item in the list 'contents' and makes 'item' = it
            itemSTR=str(item, 'utf-8')                              #Convert item into a utf-8 string
            print('----------------------------------------')
            print('index of item:')
            print(index)
            print('Item in list:')
            print(itemSTR)
            print('Layer:')
            print(LayerCount)
            index = index + 1
            if 'layer' in itemSTR:
                print('Layer Change')
                contents.insert(index,'Clean Nozzle')
                LayerCount = LayerCount + 1
            fp.write("%s\n" % item) # write each item on a new line



print('done')               #Prints done to terminalDone'

Thanks


Solution

  • I think you should be okay reading a 78MB file. I don't usually think about "good for handling large" until I'm sure I'm going over 2GB. (I'm a data scientist and over 2GB is a daily thing for me.) My suggestion would be to use the modulus operator, %, to determine whether to insert text. Modulus returns the remainder of division, so if x % 10 == 0 is true, you are on an iteration divisible by ten.

    
    # LayerCount = 1                                                           
    index = 0
    acc_lines = ''  # short for accumulated lines.
    frequency = 10
    path = 'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\TestSmall.gcode'
    new_path = r'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\New.gcode'
    
    # use triple " for handy preformatted text.
    clean_cmd = """ ;Clean Nozzle
    G0 X30 Y-47 F10000
    G0 X70 Y-47
    G0 X30 Y-47
    """
    
    
    #open gcode file
    with open(path, 'rb') as file:
        for line in file.readlines():
            acc_lines = acc_lines + line
            if line.contains('layer'):
                index += 1
                if index % frequency == 0:
                    acc_lines = acc_lines + clean_cmd
    
    # you are reading bytes but writing plain text in your code above.
    # Not sure why that is. No cause for alarm, but it something is amiss
    # when reading the new_path file later, check on this. 
    
    with open(new_path, 'w') as file:
        file.write(acc_lines)