I am having an issue where my “all_possible_cuts” array is changing when I append another cut to it.
The specific sections of my code with the issue is:
def append_to_all_possible_cuts(next_cuts):
"""Appends the next possible way to cut the material to the array \"all_possible_cuts\" """
Order.all_possible_cuts.append(next_cuts[:])
previous_cuts = next_cuts
return(previous_cuts)
...
Print(Order.all_possible_cuts)
Output: [[[19.125, 0], [16.125, 0]], [[19.125, 0], [16.125, 0]], ...[[19.125, 0], [16.125, 0]]]
Expected Output: [[19.125, 6], [16.125, 1]], [[19.125, 6], [16.125, 0]], [[19.125, 5], [16.125, 3]],...[[19.125, 0], [16.125, 0]]
I have found articles with people having the same issue, but I tried their solutions and it doesn’t seem to help.
Enter the inputs 144, 2, 19, 15, 16, 30
Here is my full code:
class Order:
purchase_lines = []
all_possible_cuts = []
def get_order_information():
"""Gathers all the starting bar length and cutting information from the order and sorts from largest cut to smallest cut."""
Order.get_starting_material_length()
Order.get_purchase_lines()
Order.purchase_lines = sorted(Order.purchase_lines, reverse=True)
def get_starting_material_length():
"""Gathers the length of the stock bar for the order. Returns starting lenght of the stock material."""
starting_material_length = int(input("What is the length of the stock (in inches)? "))
Order.starting_material_length = starting_material_length
def get_purchase_lines():
"""Gathers all the cut lengths and the quantities needed for each cut length. Adds a tolerance of 0.125 inches to each cutting length. Appends length + quantity needed to """
tolerance = 0.125
num_of_cut_lengths = int(input("How many different cut lengths are there? "))
for cut_length in range(num_of_cut_lengths):
length = float(input("What is the length of the cut (in inches)? "))
qty = int(input("How many " + str(length) + " in. cuts are needed? "))
Order.purchase_lines.append([(length + tolerance), qty])
def generate_all_possible_cuts():
"""Generates an array of every possible way to cut a single piece of stock material"""
first_possible_cut = Order.generate_first_possible_cut(Order.purchase_lines)
another_cut_possible = Order.determine_if_another_cut_possible(first_possible_cut)
previous_cuts = first_possible_cut
while another_cut_possible:
next_cuts = Order.generate_next_possible_cut(previous_cuts)
previous_cuts = Order.append_to_all_possible_cuts(next_cuts)
another_cut_possible = Order.determine_if_another_cut_possible(previous_cuts)
def generate_first_possible_cut(purchase_lines):
"""Using the cut lengths and quantities need, cutting the most pieces possible out of the stock material, starting with the first cut length entered, until the material has remainder of 0 or all cutting lengths have been attempted."""
possible_cut_length_and_qtys = []
remaining_material_length = Order.starting_material_length
for line in purchase_lines:
possible_cut_length = line[0]
max_qty = line[1]
possible_qty = int(remaining_material_length // possible_cut_length)
if possible_qty >= 0 and remaining_material_length - (possible_cut_length * possible_qty) >= 0:
if possible_qty > max_qty:
possible_cut_length_and_qtys.append([possible_cut_length, max_qty])
remaining_material_length -= possible_cut_length * max_qty
else:
possible_cut_length_and_qtys.append([possible_cut_length, possible_qty])
remaining_material_length -= possible_cut_length * possible_qty
Order.remaining_material_length = remaining_material_length
return(possible_cut_length_and_qtys)
def determine_if_another_cut_possible(previous_cuts):
"""Determines if another cut is possible. Returns True if possible, False if not possible."""
for cut in previous_cuts:
cut_qty = cut[1]
if cut_qty > 0:
return(True)
break
else:
return(False)
def generate_next_possible_cut(previous_cuts):
"""Using the previous counts, generates the next possible cut."""
index_of_lowered_digit, lowered_cuts = Order.lower_smallest_digit_possible(previous_cuts)
Order.increase_remaining_material_length(index_of_lowered_digit)
next_cuts = Order.use_remaining_stock(index_of_lowered_digit, lowered_cuts)
return(next_cuts)
def append_to_all_possible_cuts(next_cuts):
"""Appends the next possible way to cut the material to the array \"all_possible_cuts\" """
Order.all_possible_cuts.append(next_cuts[:])
previous_cuts = next_cuts
return(previous_cuts)
def lower_smallest_digit_possible(previous_cuts):
"""Using the previous counts, generates the next possible cut."""
current_cut_index = len(previous_cuts) - 1
while current_cut_index >= 0:
if previous_cuts[current_cut_index][1] > 0:
previous_cuts[current_cut_index][1] -= 1
break
else:
current_cut_index -= 1
return(current_cut_index, previous_cuts)
def increase_remaining_material_length(index_of_lowered_digit):
"""Using the previous counts, generates the next possible cut."""
Order.remaining_material_length += Order.purchase_lines[index_of_lowered_digit][0]
def use_remaining_stock(index_of_lowered_digit, lowered_cuts):
"""Using the previous counts, generates the next possible cut."""
current_index = index_of_lowered_digit + 1
while current_index < len(lowered_cuts):
if Order.remaining_material_length >= lowered_cuts[current_index][0]:
qty = int(Order.remaining_material_length // lowered_cuts[current_index][0])
lowered_cuts[current_index][1] += qty
Order.remaining_material_length -= lowered_cuts[current_index][0] * qty
current_index += 1
return(lowered_cuts)
Order.get_order_information()
Order.generate_all_possible_cuts()