How to make a comprehensive composition table efficiently

Question:

I am trying to make a comprehensive compositon table for composite development (in chemistry field) based on the specific rules.

The rules are

  • The numbers in a table mean the weight percentage of each raw material in the ccomposite
  • There are three raw materials(A, B, C), and I can use up to two materials to make a composite
  • Each number in a table must be a multiple of x and the sum of each row must be less than or equal to y
  • I have to write every possible combination which meets the rules above.

For example, if x=1 and y=2, I can make a table shown below.

            Material A  Material B  Material C
Composite1          0           0           0
Composite2          1           0           0
Composite3          0           1           0
Composite4          0           0           1
Composite5          1           1           0
Composite6          1           0           1
Composite7          0           1           1
Composite8          2           0           0
Composite9          0           2           0
Composite10         0           0           2

(Actually, the weight percentage of Material D is omitted, so it’s unnecessary to think that the sum of a row is not 100.)

When x and y are small numbers I can make the table manually (using Excel), but if x and y are big numbers I can’t.
Thus, I would like to know python codes which make the table efficiently regardless of x and y.

Asked By: hiro

||

Answers:

You could use itertools.product and then filter out the compositions that exceed the limit with list comprehension.

import itertools

def get_compositions(raw_materials:list, factor_x:int,lim_y:int,col_prefix='Material '):
    multiples = [factor_x*i for i in range(int(lim_y/factor_x)+1)]
    cart_prod = itertools.product(multiples, repeat=len(raw_materials))
    composites = [c for c in cart_prod if sum(c)<=lim_y] ## filter

    composite_labels = [f'Composite{i}' for i in range(1, len(composites)+1)]
    material_labels = [f'{col_prefix}{m}' for m in raw_materials]

    return pd.DataFrame(composites, index=composite_labels, columns=material_labels)

get_compositions(['A', 'B','C'], 1, 2) should return

opdf

Answered By: Driftr95
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.