2

I'm trying to style a simple multiplication table. I have the following rule, and if a cell doesn't satisfy it, I must colorize it in a different color.


Example 1: Given numbers 10 and 11, the rule is broken since -798010 != 110, so the color is red:

  • Combine (100-(100-10)-(100-11)) = -79 and (100-10)*(100-11) = 8010 as strings: -798010
  • Multiply 10*11: 110

Example 2: Given numbers 10 and 99, the rule is satisfied since 990 == 990, so the color is green.

  • Combine (100-(100-10)-(100-99)) = 9 and (100-10)*(100-99) = 90 as strings: 990
  • Multiply 10*90: 990

Currently I'm checking if numbers are in the rule or not. Either way I colorize cells, all I get is all cells in one color:

import pandas as pd

l = []
for i in range(10, 100):
     for j in range(10, 100):
        l.append(f'{i}*{j}')
        result = [l[idx:idx+90] for idx in range(0, len(l), 90)]
        df = pd.DataFrame(result)

def style_dataframe(s):
    for row_index, row in df.iterrows():
        for col_name, cell in row.items():
            if int(cell[:2])*int(cell[3:5]) == int(str(100 - ((100 - (int(cell[:2])))-(100-(int(cell[3:5])))))+str((100-(int(cell[:2])))*int(int(cell[3:5])))):
                return 'background-color: green'
            elif int(cell[:2])*int(cell[3:5]) != int(str(100 - ((100 - (int(cell[:2])))-(100-(int(cell[3:5])))))+str((100-(int(cell[:2])))*int(int(cell[3:5])))):
                return 'background-color: red'
  
s = df.style.applymap(style_dataframe)

1 Answer 1

1
  • df.style.applymap operates elementwise, so the styling function expects only 1 cell (not a dataframe)
  • 100-(100-a)-(100-b) can be simplified to just a+b-100

So the styling function should look something like this:

def rule(cell):
    a, b = map(int, cell.split('*'))                  # split 'a*b' into [a, b]
    cond1 = str(a+b-100) + str((100-a)*(100-b))       # string version
    cond2 = a * b                                     # multiplication version
    color = 'green' if int(cond1) == cond2 else 'red' # check rule
    return f'background-color: {color}'               # return css style

df.style.applymap(rule)


As a side note, it's much simpler to create the original df with numpy broadcasting:

a = np.arange(10, 100).astype(str)
df = pd.DataFrame(np.char.add(np.char.add(a[:, None], '*'), a))

#         0      1      2  ...     87     88     89
# 0   10*10  10*11  10*12  ...  10*97  10*98  10*99
# 1   11*10  11*11  11*12  ...  11*97  11*98  11*99
# 2   12*10  12*11  12*12  ...  12*97  12*98  12*99
# ..    ...    ...    ...  ...    ...    ...    ...
# 87  97*10  97*11  97*12  ...  97*97  97*98  97*99
# 88  98*10  98*11  98*12  ...  98*97  98*98  98*99
# 89  99*10  99*11  99*12  ...  99*97  99*98  99*99
# 
# [90 rows x 90 columns]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.