0

I have a many QRadioButton I had already grouped in an array

self.bounc1 = [self.bounc1_no, self.bounc1_1, self.bounc1_2, self.bounc1_3, self.bounc1_4, self.bounc1_5, self.bounc1_6]
self.bounc2 = [self.bounc2_no, self.bounc1_2, self.bounc2_2, self.bounc2_3, self.bounc2_4, self.bounc2_5, self.bounc2_6]

I have to return a list with [40, index of checked radio 1, index of checked radio 2], I can use a code like

ret = [40, 0, 0]
for i in range(7):
    if self.bounc1[i].isChecked():  ret[1] = i
for i in range(7):
    if self.bounc2[i].isChecked():  ret[2] = i
self.sendSerial.emit(ret)

Is there a way to make it in a single line like

self.sendSerial.emit([40, ...... , ......])

Thanks

PS: I've grouped QRadioButton in Qt creator, it seems there is not a simple way to set ID.

brazoayeye
  • 329
  • 1
  • 2
  • 14
  • 2
    Wouldn't it make sense to initialise `ret` as `[40, -1, -1]`? 0 is a valid index and you don't want to return it if no condition is satisfied... – cs95 Oct 25 '18 at 19:55
  • 2
    You could use `next(i for i,r in enumerate(self.bounc1) if r.isChecked())` instead of the for loop. it also avoids iterating over the first radio button that is checked – Bakuriu Oct 25 '18 at 20:00
  • 1
    Possible duplicate of [Get the first item from an iterable that matches a condition](https://stackoverflow.com/questions/2361426/get-the-first-item-from-an-iterable-that-matches-a-condition) – Domino Oct 25 '18 at 20:01
  • 1
    are you trying to return the LAST index, or all indices? – MrE Oct 25 '18 at 20:02
  • your code returns the last index. – MrE Oct 25 '18 at 20:03
  • @MrE Being radio buttons I believe only one will be checked so it does not matter... however yes, the OP forgot a `break` probably – Bakuriu Oct 25 '18 at 20:03
  • all this seems like a crazy work around to get the value. a HTML button should have an ID, and a Value, and you should just be able to get the value from the click. All this code looks totally overkill to figure out a radio status. – MrE Oct 25 '18 at 20:07
  • @coldspeed: i'm sending unsigned char, it's easier to send 0 – brazoayeye Oct 26 '18 at 17:52
  • @MrE: as explained I cannot do that with QT creator, adding 15 rows of code to skip 3 it's not useful – brazoayeye Oct 26 '18 at 17:56

1 Answers1

1

One line...:

self.sendSerial.emit([40, [i for i, x in enumerate(self.bounc1) if x.isChecked()][0], [i for i, x in enumerate(self.bounc2) if x.isChecked()][0]])

But honestly this is way less readable.

Incorporating @Bakuriu's comment, one way to shorten this would be:

self.sendSerial.emit([40] + list(map(lambda x: next(i for i, r in enumerate(x) if r.isChecked() if any(r.isChecked() for r in x) else 0, (self.bounc1, self.bounc2)))

Again, you can see how contrived it is, especially with the default to 0.

r.ook
  • 13,466
  • 2
  • 22
  • 39
  • what is the zero index for in your list comprehensions ? – LeKhan9 Oct 25 '18 at 20:02
  • @LeKhan9 This answer builds the whole list of radio buttons checked and then takes the first element. – Bakuriu Oct 25 '18 at 20:02
  • The list comprehension returns a `list`, and since he only wants the first True result, we slice to the first element only. – r.ook Oct 25 '18 at 20:03
  • original code returns the last index, so it should be [-1], but even then that doesn't account for the case where none is checked – MrE Oct 25 '18 at 20:04
  • @MrE, good point on both ends. The question asks one thing but the code does another. The default can also be handled but honestly I just think making this line any longer is diminishing return. – r.ook Oct 25 '18 at 20:06
  • Not a fan of one liners, especially if you require horizontal scrolling to see them. Readability counts. – cs95 Oct 26 '18 at 18:40
  • @coldspeed I completely agree. I just answered the question in spirit of "Can I", but doesn't necessarily translate to "Should I". You can see my comment to demonstrate the solution, while it exists, is contrived and less readable. – r.ook Oct 26 '18 at 18:42