# Issue

I am doing a CodeWars kata (Strings mix) and am getting an error. I have written the following code:

```
def mix(s1, s2):
whitelist = set('abcdefghijklmnopqrstuvwxyz')
out = []
s1 = ''.join(sorted((c for c in s1 if c in whitelist), key = lambda c: (-s1.count(c), c)))
s2 = ''.join(sorted((c for c in s2 if c in whitelist), key = lambda c: (-s2.count(c), c)))
groups = sorted(list(set(s1) | set(s2)), key = lambda c: (-max([s1.count(c), s2.count(c)]), lambda v: 1 if (s1.count(v) > s2.count(v)) else 2, c))
for i in groups:
if max([s1.count(i), s2.count(i)]) <= 1:
continue
if s1.count(i) == s2.count(i):
out.append('=:' + i * s1.count(i))
continue
if s1.count(i) > s2.count(i):
out.append('1:' + i * s1.count(i))
continue
else:
out.append('2:' + i * s2.count(i))
return '/'.join(out)
```

The goal of line 6 (`groups = sorted`

...)is to order the different individual letters correctly according the the kata's description. I am using a lambda function to create keys for the `sorted()`

method which return a tuple of three values:

- the max number of letters (
`c`

) of the two strings, negated for reverse order *trying*to prioritize`s1`

over`s2`

if they have equal count of letters- and finally alphabetical order if all else fails

I suggest reading the kata description if that didn't make sense. I am getting the error:

```
Traceback (most recent call last):
File "/workspace/default/tests.py", line 5, in <module>
test.assert_equals(mix("Are they here", "yes, they are here"), "2:eeeee/2:yy/=:hh/=:rr")
File "/workspace/default/solution.py", line 6, in mix
groups = sorted(list(set(s1) | set(s2)), key = lambda c: (-max([s1.count(c), s2.count(c)]), lambda v: 1 if (s1.count(v) > s2.count(v)) else 2, c))
TypeError: '<' not supported between instances of 'function' and 'function'
```

I am kinda confused why this is happening since I don't see how `s1.count(v)`

and `s2.count(v)`

could be functions?

If the way I am trying to order the letters is completely wrong I wouldn't mind some help btw.

# Solution

As mentioned by Barmar in the comments, the `sorted`

function's second criteria for sorting when the first criteria does not distinguish between elements is to compare lambda functions to each other, not letters. The `>`

sign in the Traceback is not referring to `s1.count(v) > s2.count(v)`

, but instead to the `sorted`

function's attempt to compare the two based on this second criteria, which is by comparing one lambda function to another lambda function.

To properly distinguish between `s1`

and `s2`

and give priority to `s2`

, your way does indeed work (while retaining only the ternary if statement without the lambda, and replacing `v`

with `c`

). We could prove it mathematically by splitting things up into cases, but I suspect that's not what you are looking for. But intuitively, it works since you are basically checking if the count of the current letter in `s1`

is the max count of that letter, and if it is, then you give it priority over those in s2 with the same count, since in those cases `s2.count(c) > s1.count(c)`

, so the letters that have max counts in `s2`

are given lower priority. For example, given `s1 = "ttt"`

and `s2="sss"`

, both have the same count, so they are sorted by the second criteria. `s1.count("t")>s2.count("t")`

is `True`

so it gets a value of `1`

(higher priority), while `s1.count("s")>s2.count("s")`

is `False`

so it gets a value of `2`

(lower priority, since `sorted`

sorts from smallest to largest by default).

Another way you could code line 6 with somewhat greater clarity I think (although its arguable), would be as follows:

```
groups = sorted(list(set(s1) | set(s2)), key=lambda letter: (max(s1.count(letter),s2.count(letter)),s1.count(letter)>s2.count(letter), -ord(letter.lower())),reverse=True)
```

The `ord`

function is used to convert the letter to its ascii value and then take the negative of it, to basically get the alphabetical order criteria back which was ruined by setting `reverse=True`

.

Answered By - Jake Korman Answer Checked By - Pedro (PHPFixing Volunteer)

## 0 Comments:

## Post a Comment

Note: Only a member of this blog may post a comment.