问:
How to reduce amount of Boolean statements when programming
So the current language I am using is flutter, although I believe this applies to any programming language. I am creating an app where I have a requirement to have an implemented custom keypad. The keypad has three configurations for three different text fields used in pipette.dart, I added part of the code for ASPIRATE SPEED and DISPENSE SPEED, althogh the same logic applies to volume shown in the image below.

When each text field is pressed the current highlight is switched to the container where the text field is ( The blue highlight below the text field). The keypad is also switched to control the text field which is pressed, shown in toggleKeyPad(). So for example when you click Aspirate Speed, isAspirate is true and isAspirateText is true, isAspirate is then passed to blueHighlightSpeed() (shown at the bottom of pipette.dart), which then highlights the container. when IsAspirateText is true it sets the keypad to use aspirateController which is the text editing controller for the text field in Aspirate Speed, the same logic applies to Dispense speed and Volume. Hopefully this helps anyone understand what my code is doing, I will update if I missed anything.

The question that I have is I would like to know if there is a way to minimize the amount of Boolean statements that I am using. Currently every time I click a new text field I have to change 8 different Booleans which can become very tedious and for other programmers will probably make the code harder to read and understand. I have only been programming for a few years now and would just like to know if there is a way to create this same logic without as many Booleans.

Is it maybe possible to use a switch statement here?

functions.dart

```<code>
import 'package:flutter/material.dart';
import '../keyboard/text_key.dart';
import '../keyboard/textkey_functions.dart';

bool keypadUp = false;
bool isTextFieldShown = false;
bool isVolume = false;
bool isVolumeText = false;
bool isAspirate = false;
bool isAspirateText = true;
bool isDispense = false;
bool isDispenseText = false;
bool depthMemoryTop = false;
bool depthMemoryBottom = false;

TextEditingController aspirateController = TextEditingController();
TextEditingController dispenseController = TextEditingController();
TextEditingController volumeController = TextEditingController();
TextEditingController machController = TextEditingController();

Widget toggleKeyPad() {
  if (isAspirateText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, aspirateController); //Accepts and inputs text into aspirateController
      },
      onBackspace: () {
        backspace(aspirateController);
      },
    );
  }
  if (isVolumeText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, volumeController); //Accepts and inputs text into volumeController
      },
      onBackspace: () {
        backspace(volumeController);
      },
    );
  }
  if (isDispenseText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, dispenseController); //Accepts and inputs text into dispenseController
      },
      onBackspace: () {
        backspace(dispenseController);
      },
    );
  } else {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, machController); // I didn't need the else statement so I created a fake controller which takes no input.
      },
      onBackspace: () {
        backspace(machController);
      },
    );
  }
}

Padding blueHighlightVolume (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 190),
      child: Container(
        width: 140,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 190),
      child: Container(
        width: 140,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightSpeed (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 1),
      child: Container(
        width: 140,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 1),
      child: Container(
        width: 140,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightDepthTop (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 89, left: 15),
      child: Container(
        width: 350,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightDepthBottom (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
      ),
    );
  }
}

</code>```

part of pipette.dart

```<code>                                 Column(
                                children: [
                                  Stack(
                                    children: [
                                      Padding(
                                        padding: const EdgeInsets.all(8.0),
                                        child: Text(
                                          'ASPIRATE SPEED',
                                          style: TextStyle(
                                            fontFamily: 'Droid Sans',
                                            color: Color.fromRGBO(2, 58, 107, 1),
                                            fontSize: 12.0,
                                          ),
                                        ),
                                      ),
                                      Container(
                                        decoration: BoxDecoration(
                                          border: Border(
                                            left: BorderSide(width: 1, color: Colors.grey),
                                          ),
                                        ),
                                        width: 140,
                                        height: 100,
                                        //color: Colors.red,
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.only(left: 20.0, top: 36.0),
                                        child: Container(
                                          width: 75,
                                          height: 40,
                                          child: TextField(
                                            controller: aspirateController,
                                            textAlign: TextAlign.center,
                                            readOnly: true,
                                            onTap: () {
                                              setState(() {
                                                /*
                                                * set isAspirate and isAspirateText to true, highlights aspirate speed container and
                                                * changes aspirateController to accept input from the keypad.
                                                *
                                                */
                                                isAspirateText = true;
                                                isDispenseText = false;
                                                isVolumeText = false;
                                                isAspirate = true;
                                                isDispense = false;
                                                isVolume = false;
                                                depthMemoryTop = false;
                                                depthMemoryBottom = false;
                                                print(isAspirate);
                                              });
                                            },
                                            decoration: InputDecoration(
                                              border: OutlineInputBorder(),
                                            ),
                                          ),
                                        ),
                                      ),
                                      blueHighlightSpeed(isAspirate),
                                    ],
                                  ),
                                  Stack(
                                    children: [
                                      Padding(
                                        padding: const EdgeInsets.all(8.0),
                                        child: Text(
                                            'DISPENSE SPEED',
                                            style: TextStyle(
                                            fontFamily: 'Droid Sans',
                                            color: Color.fromRGBO(2, 58, 107, 1),
                                            fontSize: 12.0,
                                          ),
                                        ),
                                      ),
                                      Container(
                                        decoration: BoxDecoration(
                                          border: Border(
                                            left: BorderSide(width: 1, color: Colors.grey),
                                          ),
                                        ),
                                        width: 140,
                                        height: 100,
                                        //color: Colors.red,
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.only(left: 20.0, top: 36.0),
                                        child: Container(
                                          width: 75,
                                          height: 40,
                                          child: TextField(
                                            controller: dispenseController,
                                            textAlign: TextAlign.center,
                                            readOnly: true,
                                            onTap: () {
                                              setState(() {
                                                isVolumeText = false;
                                                isAspirateText = false;
                                                isDispenseText = true;
                                                isAspirate = false;
                                                isDispense = true;
                                                isVolume = false;
                                                depthMemoryTop = false;
                                                depthMemoryBottom = false;
                                                print(isAspirate);
                                              });
                                            },
                                            decoration: InputDecoration(
                                              border: OutlineInputBorder(),
                                            ),
                                          ),
                                        ),
                                      ),
                                      blueHighlightSpeed(isDispense),
                                    ],
                                  ),
                                ],
                              ),

</code>```

keypad.dart

```<code>
class KeyPad extends StatelessWidget
{

  KeyPad({
    required this.onTextInput,
    required this.onBackspace,
  });

  final double width = 275;
  final double height = 90;

  final ValueSetter<String> onTextInput;
  final VoidCallback onBackspace;

  void _textInputHandler(String text) => onTextInput.call(text);

  void _backspaceHandler() => onBackspace.call();

  Container buildRowOne()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '7',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '8',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '9',
            onTextInput: _textInputHandler,
          ),

        ],
      ),
    );
  }

  Container buildRowTwo()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '4',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '5',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '6',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Container buildRowThree()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '1',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '2',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '3',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Container buildRowFour()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          BackspaceKey(
            onBackspace: _backspaceHandler,
          ),
          TextKey(
            text: '0',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '.',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Padding buildRowFive()
  {
    return Padding(
      padding: const EdgeInsets.only(top: 35),
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Color.fromRGBO(92, 103, 148, 1)),
              borderRadius: BorderRadius.circular(45.0),
        ),
        width: 175,
        height: 60,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: Image.asset('assets/text_key/done.png'),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context)
  {
    return SafeArea(
      child: Container(
        child: Column(
          children: [
            buildRowOne(),
            buildRowTwo(),
            buildRowThree(),
            buildRowFour(),
            buildRowFive(),
          ],
        ),
      ),
    );
  }
}

</code>```

答:
The first change I believe you should do is to get rid of the isSomethingText variables. The isSomethingText variables on your code are true if isSomething is true, which means that you could use only one of those variables for everything.

The problem

Your code is quite complex, making it harder for me to understand your question, so I will try to simplify the situation a bit:
Let's say we have an app that will display a color, and in order to do so, it asks the user to mark some sort of radio button selection, but in order to do that we have the following booleans:

```<code>bool isRed;
bool isGreen;
bool isBlue;
bool isOrange;
bool isYellow;
bool isPurple;
</code>```

Then when the user presses, for example, the purple button:

```<code>// set purple
onPressed: () => {
  isRed = false;
  isGreen = false;
  isBlue = false;
  isOrange = false;
  isYellow = false;
  isPurple = true;
}
</code>```

And so on and so forth for every color, then when displaying the color:

```<code>late Color color;

if (isRed) {
  color = Color('#ff0000');
} else if (isGreen) {
  color = Color('#00ff00');
} else ...

return ColorDisplay(color: color);
</code>```

You get the idea.

Now the key to this is that each of these booleans are blocking each other, if isRed is true, the other booleans should always, always, be false.

That's the most important part. we could have coded this in such a way that you could select both red and blue, and then purple would be displayed, but for this solution to work, each of the booleans must be only true when the rest are false.

If you want to make the other interpretation, you should actually make enough booleans for each combination, like this:

```<code>bool isRed;
bool isGreen;
bool isBlue;
bool isRedAndBlue;
bool isRedAndGreen;
bool isGreenAndBlue;
</code>```

Anyway, just remember you can do this any time your booleans are dependent from each other.

The solution

To solve the above problem, we can use an enumerator.

An enumerator is basically a type that can have one of a number of values, they look like this:

```<code>enum PossibleColors {
  Red,
  Green,
  Blue,
  Orange,
  Yellow,
  Purple,
}
</code>```

With the above, we can now make a PossibleColors variable and store the current selected color there:

OLD:

```<code>bool isRed;
bool isGreen;
bool isBlue;
bool isOrange;
bool isYellow;
bool isPurple;
</code>```

NEW:

```<code>PossibleColors? currentColor = PossibleColors.Red; // default red.
</code>```

Then when setting the color:

OLD:

```<code>// set purple
onPressed: () => {
  isRed = false;
  isGreen = false;
  isBlue = false;
  isOrange = false;
  isYellow = false;
  isPurple = true;
}
</code>```

NEW:

```<code>// set purple
onPressed: () => currentColor = PossibleColors.Purple;
</code>```

finally, to display:

OLD:

```<code>late Color color;

if (isRed) {
  color = Color('#ff0000');
} else if (isGreen) {
  color = Color('#00ff00');
} else ...

return ColorDisplay(color: color);
</code>```

NEW:

```<code>late Color color;

switch (currentColor) {
  case PossibleColors.Red:
    color  = Color('#ff0000');
    break;
  case PossibleColors.Green:
    color = Color('#00ff00');
    break;
  default:
    throw UnimplementedError('no color yet...');
}

return ColorDisplay(color: color);
</code>```

Body:
So the current language I am using is flutter, although I believe this applies to any programming language. I am creating an app where I have a requirement to have an implemented custom keypad. The keypad has three configurations for three different text fields used in pipette.dart, I added part of the code for ASPIRATE SPEED and DISPENSE SPEED, althogh the same logic applies to volume shown in the image below.

When each text field is pressed the current highlight is switched to the container where the text field is ( The blue highlight below the text field). The keypad is also switched to control the text field which is pressed, shown in toggleKeyPad(). So for example when you click Aspirate Speed, isAspirate is true and isAspirateText is true, isAspirate is then passed to blueHighlightSpeed() (shown at the bottom of pipette.dart), which then highlights the container. when IsAspirateText is true it sets the keypad to use aspirateController which is the text editing controller for the text field in Aspirate Speed, the same logic applies to Dispense speed and Volume. Hopefully this helps anyone understand what my code is doing, I will update if I missed anything.

The question that I have is I would like to know if there is a way to minimize the amount of Boolean statements that I am using. Currently every time I click a new text field I have to change 8 different Booleans which can become very tedious and for other programmers will probably make the code harder to read and understand. I have only been programming for a few years now and would just like to know if there is a way to create this same logic without as many Booleans.

Is it maybe possible to use a switch statement here?

functions.dart

import 'package:flutter/material.dart';
import '../keyboard/text_key.dart';
import '../keyboard/textkey_functions.dart';

bool keypadUp = false;
bool isTextFieldShown = false;
bool isVolume = false;
bool isVolumeText = false;
bool isAspirate = false;
bool isAspirateText = true;
bool isDispense = false;
bool isDispenseText = false;
bool depthMemoryTop = false;
bool depthMemoryBottom = false;

TextEditingController aspirateController = TextEditingController();
TextEditingController dispenseController = TextEditingController();
TextEditingController volumeController = TextEditingController();
TextEditingController machController = TextEditingController();

Widget toggleKeyPad() {
  if (isAspirateText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, aspirateController); //Accepts and inputs text into aspirateController
      },
      onBackspace: () {
        backspace(aspirateController);
      },
    );
  }
  if (isVolumeText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, volumeController); //Accepts and inputs text into volumeController
      },
      onBackspace: () {
        backspace(volumeController);
      },
    );
  }
  if (isDispenseText == true) {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, dispenseController); //Accepts and inputs text into dispenseController
      },
      onBackspace: () {
        backspace(dispenseController);
      },
    );
  } else {
    return KeyPad(
      onTextInput: (myText) {
        insertText(myText, machController); // I didn't need the else statement so I created a fake controller which takes no input.
      },
      onBackspace: () {
        backspace(machController);
      },
    );
  }
}

Padding blueHighlightVolume (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 190),
      child: Container(
        width: 140,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 190),
      child: Container(
        width: 140,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightSpeed (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 1),
      child: Container(
        width: 140,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 1),
      child: Container(
        width: 140,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightDepthTop (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 89, left: 15),
      child: Container(
        width: 350,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
      ),
    );
  }
}

Padding blueHighlightDepthBottom (bool isSelect) {
  if (isSelect == true) {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
        color: Color.fromRGBO(2, 58, 107, 1),
      ),
    );
  } else {
    return Padding(
      padding: const EdgeInsets.only(top: 90, left: 15),
      child: Container(
        width: 350,
        height: 10,
      ),
    );
  }
}

part of pipette.dart

                                 Column(
                                children: [
                                  Stack(
                                    children: [
                                      Padding(
                                        padding: const EdgeInsets.all(8.0),
                                        child: Text(
                                          'ASPIRATE SPEED',
                                          style: TextStyle(
                                            fontFamily: 'Droid Sans',
                                            color: Color.fromRGBO(2, 58, 107, 1),
                                            fontSize: 12.0,
                                          ),
                                        ),
                                      ),
                                      Container(
                                        decoration: BoxDecoration(
                                          border: Border(
                                            left: BorderSide(width: 1, color: Colors.grey),
                                          ),
                                        ),
                                        width: 140,
                                        height: 100,
                                        //color: Colors.red,
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.only(left: 20.0, top: 36.0),
                                        child: Container(
                                          width: 75,
                                          height: 40,
                                          child: TextField(
                                            controller: aspirateController,
                                            textAlign: TextAlign.center,
                                            readOnly: true,
                                            onTap: () {
                                              setState(() {
                                                /*
                                                * set isAspirate and isAspirateText to true, highlights aspirate speed container and
                                                * changes aspirateController to accept input from the keypad.
                                                *
                                                */
                                                isAspirateText = true;
                                                isDispenseText = false;
                                                isVolumeText = false;
                                                isAspirate = true;
                                                isDispense = false;
                                                isVolume = false;
                                                depthMemoryTop = false;
                                                depthMemoryBottom = false;
                                                print(isAspirate);
                                              });
                                            },
                                            decoration: InputDecoration(
                                              border: OutlineInputBorder(),
                                            ),
                                          ),
                                        ),
                                      ),
                                      blueHighlightSpeed(isAspirate),
                                    ],
                                  ),
                                  Stack(
                                    children: [
                                      Padding(
                                        padding: const EdgeInsets.all(8.0),
                                        child: Text(
                                            'DISPENSE SPEED',
                                            style: TextStyle(
                                            fontFamily: 'Droid Sans',
                                            color: Color.fromRGBO(2, 58, 107, 1),
                                            fontSize: 12.0,
                                          ),
                                        ),
                                      ),
                                      Container(
                                        decoration: BoxDecoration(
                                          border: Border(
                                            left: BorderSide(width: 1, color: Colors.grey),
                                          ),
                                        ),
                                        width: 140,
                                        height: 100,
                                        //color: Colors.red,
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.only(left: 20.0, top: 36.0),
                                        child: Container(
                                          width: 75,
                                          height: 40,
                                          child: TextField(
                                            controller: dispenseController,
                                            textAlign: TextAlign.center,
                                            readOnly: true,
                                            onTap: () {
                                              setState(() {
                                                isVolumeText = false;
                                                isAspirateText = false;
                                                isDispenseText = true;
                                                isAspirate = false;
                                                isDispense = true;
                                                isVolume = false;
                                                depthMemoryTop = false;
                                                depthMemoryBottom = false;
                                                print(isAspirate);
                                              });
                                            },
                                            decoration: InputDecoration(
                                              border: OutlineInputBorder(),
                                            ),
                                          ),
                                        ),
                                      ),
                                      blueHighlightSpeed(isDispense),
                                    ],
                                  ),
                                ],
                              ),

keypad.dart

class KeyPad extends StatelessWidget
{

  KeyPad({
    required this.onTextInput,
    required this.onBackspace,
  });

  final double width = 275;
  final double height = 90;

  final ValueSetter<String> onTextInput;
  final VoidCallback onBackspace;

  void _textInputHandler(String text) => onTextInput.call(text);

  void _backspaceHandler() => onBackspace.call();

  Container buildRowOne()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '7',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '8',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '9',
            onTextInput: _textInputHandler,
          ),

        ],
      ),
    );
  }

  Container buildRowTwo()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '4',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '5',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '6',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Container buildRowThree()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          TextKey(
            text: '1',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '2',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '3',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Container buildRowFour()
  {
    return Container(
      width: width,
      height: height,
      child: Row(
        children: [
          BackspaceKey(
            onBackspace: _backspaceHandler,
          ),
          TextKey(
            text: '0',
            onTextInput: _textInputHandler,
          ),
          TextKey(
            text: '.',
            onTextInput: _textInputHandler,
          ),
        ],
      ),
    );
  }

  Padding buildRowFive()
  {
    return Padding(
      padding: const EdgeInsets.only(top: 35),
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Color.fromRGBO(92, 103, 148, 1)),
              borderRadius: BorderRadius.circular(45.0),
        ),
        width: 175,
        height: 60,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: Image.asset('assets/text_key/done.png'),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context)
  {
    return SafeArea(
      child: Container(
        child: Column(
          children: [
            buildRowOne(),
            buildRowTwo(),
            buildRowThree(),
            buildRowFour(),
            buildRowFive(),
          ],
        ),
      ),
    );
  }
}

Body:
The first change I believe you should do is to get rid of the isSomethingText variables. The isSomethingText variables on your code are true if isSomething is true, which means that you could use only one of those variables for everything.

The problem

Your code is quite complex, making it harder for me to understand your question, so I will try to simplify the situation a bit:
Let's say we have an app that will display a color, and in order to do so, it asks the user to mark some sort of radio button selection, but in order to do that we have the following booleans:

bool isRed;
bool isGreen;
bool isBlue;
bool isOrange;
bool isYellow;
bool isPurple;

Then when the user presses, for example, the purple button:

// set purple
onPressed: () => {
  isRed = false;
  isGreen = false;
  isBlue = false;
  isOrange = false;
  isYellow = false;
  isPurple = true;
}

And so on and so forth for every color, then when displaying the color:

late Color color;

if (isRed) {
  color = Color('#ff0000');
} else if (isGreen) {
  color = Color('#00ff00');
} else ...

return ColorDisplay(color: color);

You get the idea.

Now the key to this is that each of these booleans are blocking each other, if isRed is true, the other booleans should always, always, be false.

That's the most important part. we could have coded this in such a way that you could select both red and blue, and then purple would be displayed, but for this solution to work, each of the booleans must be only true when the rest are false.

If you want to make the other interpretation, you should actually make enough booleans for each combination, like this:

bool isRed;
bool isGreen;
bool isBlue;
bool isRedAndBlue;
bool isRedAndGreen;
bool isGreenAndBlue;

Anyway, just remember you can do this any time your booleans are dependent from each other.

The solution

To solve the above problem, we can use an enumerator.

An enumerator is basically a type that can have one of a number of values, they look like this:

enum PossibleColors {
  Red,
  Green,
  Blue,
  Orange,
  Yellow,
  Purple,
}

With the above, we can now make a PossibleColors variable and store the current selected color there:

OLD:

bool isRed;
bool isGreen;
bool isBlue;
bool isOrange;
bool isYellow;
bool isPurple;

NEW:

PossibleColors? currentColor = PossibleColors.Red; // default red.

Then when setting the color:

OLD:

// set purple
onPressed: () => {
  isRed = false;
  isGreen = false;
  isBlue = false;
  isOrange = false;
  isYellow = false;
  isPurple = true;
}

NEW:

// set purple
onPressed: () => currentColor = PossibleColors.Purple;

finally, to display:

OLD:

late Color color;

if (isRed) {
  color = Color('#ff0000');
} else if (isGreen) {
  color = Color('#00ff00');
} else ...

return ColorDisplay(color: color);

NEW:

late Color color;

switch (currentColor) {
  case PossibleColors.Red:
    color  = Color('#ff0000');
    break;
  case PossibleColors.Green:
    color = Color('#00ff00');
    break;
  default:
    throw UnimplementedError('no color yet...');
}

return ColorDisplay(color: color);


来源: stackexchange

问:
How do I add characters in dates to make them look normal without affecting the rest of the line?
I have a file with tons of lines using a semicolon (;) as a delimiter. I have about 5 fields and need to change the format of only the first 2 fields without affecting the remainder of each line

20211119000751;20211119000759;IDNumber;Code;THings;SomeStuff

I want the end result to look like

2021-11-19 00:07:51;2021-11-19 00:07:59;IDNumber;Code;THings;SomeStuff

I have tried the solution How Do I add Multiple characters using SED? (My first Poorly Made question) and change date format from DD/MM/YYYY to YYYY-MM-DD with sed doesn't make sense to me.

```<code>sed -e 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\);\(.*\)/\1-\2-\3 \4:\5:\6;\7/' \
    -e 's/\(.*\);\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1;\2-\3-\4 \5:\6:\7/' \
    < input > output
</code>```

This solution makes sense, but affects the rest of the line.

答:
Using awk:</p>
```<code>$ awk -v FS=";" '

function process_date(date)
{
        # 20211119000751 -> 2021-11-19 00:07:51
        new_date = substr(date, 1, 4) \
        "-" \
        substr(date, 5, 2) \
        "-" \
        substr(date, 7, 2) \
        " " \
        substr(date, 9, 2) \
        ":" substr(date, 11, 2) \
        ":" substr(date, 13, 2)

        return new_date
}
BEGIN { OFS=FS }
{ $1 = process_date($1); $2 = process_date($2); print $0}' input
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a file with tons of lines using a semicolon (;) as a delimiter. I have about 5 fields and need to change the format of only the first 2 fields without affecting the remainder of each line

20211119000751;20211119000759;IDNumber;Code;THings;SomeStuff

I want the end result to look like

2021-11-19 00:07:51;2021-11-19 00:07:59;IDNumber;Code;THings;SomeStuff

I have tried the solution How Do I add Multiple characters using SED? (My first Poorly Made question) and change date format from DD/MM/YYYY to YYYY-MM-DD with sed doesn't make sense to me.

sed -e 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\);\(.*\)/\1-\2-\3 \4:\5:\6;\7/' \
    -e 's/\(.*\);\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1;\2-\3-\4 \5:\6:\7/' \
    < input > output

This solution makes sense, but affects the rest of the line.

Body:
Using awk:

$ awk -v FS=";" '

function process_date(date)
{
        # 20211119000751 -> 2021-11-19 00:07:51
        new_date = substr(date, 1, 4) \
        "-" \
        substr(date, 5, 2) \
        "-" \
        substr(date, 7, 2) \
        " " \
        substr(date, 9, 2) \
        ":" substr(date, 11, 2) \
        ":" substr(date, 13, 2)

        return new_date
}
BEGIN { OFS=FS }
{ $1 = process_date($1); $2 = process_date($2); print $0}' input


问:
JQUERY Sorting an Array of Objects
I have an array that is holding a number of  objects.

Array:

```<code> var activeMembers=[];
</code>```

The DIV objects in the above array look like as follows - each was added one at a time:

```<code> <div id="mary" class="chatmember 1011"></div>
 <div id="steven" class="chatmember 1051"></div>
 <div id="adam" class="chatmember 1701"></div>
 <div id="bob" class="chatmember 1099"></div>
 <div id="peter" class="chatmember 1123"></div>
</code>```

Is there a quick way to sort theses DIV objects in the array by the ID from A-Z?

thx

答:
There is no quick way.  You can use generic sorter that allow you to provide comparator, or you can write a custom sorter.

See here for an example.

ContentLicense: CC BY-SA 3.0

Title: JQUERY Sorting an Array of Objects

Body:
I have an array that is holding a number of  objects.

Array:

 var activeMembers=[];

The DIV objects in the above array look like as follows - each was added one at a time:

Is there a quick way to sort theses DIV objects in the array by the ID from A-Z?

thx


问:
Simple CSV to XML Conversion - Python
I am looking for a way to automate the conversion of CSV to XML.

Here is an example of a CSV file, containing a list of movies:

Here is the file in XML format:

```<code><collection shelf="New Arrivals">
<movietitle="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movietitle="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
<movietitle="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movietitle="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>
</code>```

I've tried a few examples where I am able to read the csv and XML format using Python using DOM and SAX but yet am to find a simple example of the conversion. So far I have:

```<code>import csv
f = open('movies2.csv')
csv_f = csv.reader(f)

def convert_row(row):
   return """<movietitle="%s">
   <type>%s</type>
   <format>%s</format>
   <year>%s</year>
   <rating>%s</rating>
   <stars>%s</stars>
   <description>%s</description>
</movie>""" % (
   row.Title, row.Type, row.Format, row.Year, row.Rating, row.Stars, row.Description)

print ('\n'.join(csv_f.apply(convert_row, axis=1)))
</code>```

But I get the error:

```<code> File "moviesxml.py", line 16, in module
   print ('\n'.join(csv_f.apply(convert_row, axis=1)))
AttributeError: '_csv.reader' object has no attribute 'apply'
</code>```

I am pretty new to Python, so any help would be much appreciated!

I am using Python 3.5.2.

Thanks!

Lisa

答:
I tried to generalize robertoia's function convert_row for any header instead of writing it by hand.

```<code>import csv
import pandas as pd

f = open('movies2.csv')
csv_f = csv.reader(f)
data = []

for row in csv_f:
   data.append(row)
f.close()

df = pd.read_csv('movies2.csv')
header= list(df.columns)

def convert_row(row):
     str_row = """<%s>%s</%s> \n"""*(len(header)-1)
     str_row = """<%s>%s""" +"\n"+ str_row + """</%s>"""
     var_values = [list_of_elments[k] for k in range(1,len(header)) for list_of_elments in [header,row,header]]
     var_values = [header[0],row[0]]+var_values+[header[0]]
     var_values =tuple(var_values)
     return str_row % var_values

text ="""<collection shelf="New Arrivals">"""+"\n"+'\n'.join([convert_row(row) for row in data[1:]])+"\n" +"</collection >"
print(text)
with open('output.xml', 'w') as myfile:
  myfile.write(text)

</code>```

Of course with pandas now, it is simpler to just use
to_xml() :

```<code>df= pd.read_csv('movies2.csv')
with open('outputf.xml', 'w') as myfile:
  myfile.write(df.to_xml())

</code>```

Title: Simple CSV to XML Conversion - Python

Body:
I am looking for a way to automate the conversion of CSV to XML.

Here is an example of a CSV file, containing a list of movies:

Here is the file in XML format:

<collection shelf="New Arrivals">
<movietitle="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movietitle="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
<movietitle="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movietitle="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>

I've tried a few examples where I am able to read the csv and XML format using Python using DOM and SAX but yet am to find a simple example of the conversion. So far I have:

import csv
f = open('movies2.csv')
csv_f = csv.reader(f)

def convert_row(row):
   return """<movietitle="%s">
   <type>%s</type>
   <format>%s</format>
   <year>%s</year>
   <rating>%s</rating>
   <stars>%s</stars>
   <description>%s</description>
</movie>""" % (
   row.Title, row.Type, row.Format, row.Year, row.Rating, row.Stars, row.Description)

print ('\n'.join(csv_f.apply(convert_row, axis=1)))

But I get the error:

 File "moviesxml.py", line 16, in module
   print ('\n'.join(csv_f.apply(convert_row, axis=1)))
AttributeError: '_csv.reader' object has no attribute 'apply'

I am pretty new to Python, so any help would be much appreciated!

I am using Python 3.5.2.

Thanks!

Lisa

Body:
I tried to generalize robertoia's function convert_row for any header instead of writing it by hand.

import csv
import pandas as pd

f = open('movies2.csv')
csv_f = csv.reader(f)
data = []

for row in csv_f:
   data.append(row)
f.close()

df = pd.read_csv('movies2.csv')
header= list(df.columns)

def convert_row(row):
     str_row = """<%s>%s</%s> \n"""*(len(header)-1)
     str_row = """<%s>%s""" +"\n"+ str_row + """</%s>"""
     var_values = [list_of_elments[k] for k in range(1,len(header)) for list_of_elments in [header,row,header]]
     var_values = [header[0],row[0]]+var_values+[header[0]]
     var_values =tuple(var_values)
     return str_row % var_values

text ="""<collection shelf="New Arrivals">"""+"\n"+'\n'.join([convert_row(row) for row in data[1:]])+"\n" +"</collection >"
print(text)
with open('output.xml', 'w') as myfile:
  myfile.write(text)

Of course with pandas now, it is simpler to just use
to_xml() :

df= pd.read_csv('movies2.csv')
with open('outputf.xml', 'w') as myfile:
  myfile.write(df.to_xml())


问:
rspec: ActionController::UrlGenerationError, No route matches
After moving the download_qr link outside of this current_user.admin? from this:

```<code>#plots.show.html.haml (excerpt)
- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  - if current_user&.admin?
    = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"
</code>```

to this:

```<code>- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
  - if current_user&.admin?
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"
</code>```

I get this error in rspec

```<code>plots/show displaying inoculation inoculated displays 'Yes'
     Failure/Error: = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"

     ActionView::Template::Error:
       No route matches {:action=>"download_qr", :controller=>"plots"}
     # ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./app/views/plots/show.html.haml:2:in `_app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./spec/views/plots/show.html.erb_spec.rb:10:in `block (4 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # ActionController::UrlGenerationError:
     #   No route matches {:action=>"download_qr", :controller=>"plots"}
     #   ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'
</code>```

Here's the output for rails routes:

```<code>plots#index
                                         POST     /plots(.:format)                                                                                plots#create
                                new_plot GET      /plots/new(.:format)                                                                              plots#new
                               edit_plot GET      /plots/:id/edit(.:format)                                                                         plots#edit
                                    plot GET      /plots/:id(.:format)                                                                              plots#show
                                         PATCH    /plots/:id(.:format)                                                                              plots#update
                                         PUT      /plots/:id(.:format)                                                                              plots#update
                                         DELETE   /plots/:id(.:format)                                                                              plots#destroy
                                         GET      /plots/:id/download_qr(.:format)                                                                  plots#download_qr
</code>```

the test itself:

```<code>#show.html.erb_spec(excerpt)
require 'rails_helper'

RSpec.describe "plots/show", type: :view do

  describe "displaying inoculation" do

    context "inoculated" do
      it "displays 'Yes'" do
        assign(:plot, create(:plot))
        render
        expect(rendered).to have_content("Yes")
      end
    end
</code>```

and the spec controller:

```<code>#plots_controller_spec(excerpt)
RSpec.describe PlotsController, type: :controller do
  let(:general_user) { FactoryBot.build(:user) }
  let(:admin_user) { FactoryBot.build(:user, :admin) }
  let(:plot) { FactoryBot.create(:plot) }
  let(:plant) { create(:plant) }
  let(:invalid_plot) { FactoryBot.build(:invalid_plot) }

  before do
    allow(controller).to receive(:current_user).and_return(admin_user)
  end

  describe '#index' do
    it 'returns http success' do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

  describe '#show' do
    it 'returns http success' do
      get :show, params: { id: plot.id }
      expect(response).to have_http_status(:success)
    end
  end
</code>```

The route works fine on the actual application, and the tests pass when I move the link back within the current_user.admin? block. I think it must have something to do with the way the test is routed but I can't seem to figure it out.

答:
You have the member download_qr action based on your output from rails routes. It means that you need to specify the plot instance :id for which you want to download the QR code /plots/:id/download_qr; see Rails guides for more information about member and collection routes.

Taking this into account, you need to add the :id parameter to your link_to as

```<code>= link_to 'Download QR Code', { controller: 'plots', action: 'download_qr', id: @plot }, class: 'btn btn-primary' ...
</code>```

You can find more valuable examples on link_to options here

I can suppose that your test passed, and the application worked okay when the link was within the scope of the current_user&.admin? block because you checked this with no current user or the non-admin user. The condition is evaluated as false; the respective part of the view will not be rendered/called at all.

Body:
After moving the download_qr link outside of this current_user.admin? from this:

#plots.show.html.haml (excerpt)
- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  - if current_user&.admin?
    = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"

to this:

- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
  - if current_user&.admin?
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"

I get this error in rspec

plots/show displaying inoculation inoculated displays 'Yes'
     Failure/Error: = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"

     ActionView::Template::Error:
       No route matches {:action=>"download_qr", :controller=>"plots"}
     # ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./app/views/plots/show.html.haml:2:in `_app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./spec/views/plots/show.html.erb_spec.rb:10:in `block (4 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # ActionController::UrlGenerationError:
     #   No route matches {:action=>"download_qr", :controller=>"plots"}
     #   ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'

Here's the output for rails routes:

plots#index
                                         POST     /plots(.:format)                                                                                plots#create
                                new_plot GET      /plots/new(.:format)                                                                              plots#new
                               edit_plot GET      /plots/:id/edit(.:format)                                                                         plots#edit
                                    plot GET      /plots/:id(.:format)                                                                              plots#show
                                         PATCH    /plots/:id(.:format)                                                                              plots#update
                                         PUT      /plots/:id(.:format)                                                                              plots#update
                                         DELETE   /plots/:id(.:format)                                                                              plots#destroy
                                         GET      /plots/:id/download_qr(.:format)                                                                  plots#download_qr

the test itself:

#show.html.erb_spec(excerpt)
require 'rails_helper'

RSpec.describe "plots/show", type: :view do

  describe "displaying inoculation" do

    context "inoculated" do
      it "displays 'Yes'" do
        assign(:plot, create(:plot))
        render
        expect(rendered).to have_content("Yes")
      end
    end

and the spec controller:

#plots_controller_spec(excerpt)
RSpec.describe PlotsController, type: :controller do
  let(:general_user) { FactoryBot.build(:user) }
  let(:admin_user) { FactoryBot.build(:user, :admin) }
  let(:plot) { FactoryBot.create(:plot) }
  let(:plant) { create(:plant) }
  let(:invalid_plot) { FactoryBot.build(:invalid_plot) }

  before do
    allow(controller).to receive(:current_user).and_return(admin_user)
  end

  describe '#index' do
    it 'returns http success' do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

  describe '#show' do
    it 'returns http success' do
      get :show, params: { id: plot.id }
      expect(response).to have_http_status(:success)
    end
  end

The route works fine on the actual application, and the tests pass when I move the link back within the current_user.admin? block. I think it must have something to do with the way the test is routed but I can't seem to figure it out.

Body:
You have the member download_qr action based on your output from rails routes. It means that you need to specify the plot instance :id for which you want to download the QR code /plots/:id/download_qr; see Rails guides for more information about member and collection routes.

Taking this into account, you need to add the :id parameter to your link_to as

= link_to 'Download QR Code', { controller: 'plots', action: 'download_qr', id: @plot }, class: 'btn btn-primary' ...

You can find more valuable examples on link_to options here

I can suppose that your test passed, and the application worked okay when the link was within the scope of the current_user&.admin? block because you checked this with no current user or the non-admin user. The condition is evaluated as false; the respective part of the view will not be rendered/called at all.


问:
Optimize a PowerBI data load containing a Nearest Neighbor calculation
I have a PowerBI report that shows metrics and visuals for a large amount of quote data extracted by an API, roughly 400k records a week. These quotes only contain latitude and longitude points for location, but shareholders need to slice views by our service areas. We have a fact table of areas with IDs and geography polygons that I am able to reference.

Currently, the report uses a gnarly custom SQL query that pulls this data from the transactional database, transforms it, and finds the nearest area through a cross apply method.

Here's an example of the code:

```<code>-- step 1 : get quotes from the first table

SELECT Col1, Col2...
INTO #AllQuotes
FROM Quotes1
LEFT JOIN (FactTables)
INNER JOIN([filtering self join])
WHERE expression

-- Step 2 : insert quotes from a separate table into our first temp table to get a table with all quote data

INSERT INTO #AllQuotes
SELECT Col1, Col2
FROM Quotes2
LEFT JOIN(Fact Tables)
INNER JOIN([filtering self join])
WHERE expression

-- Step 3 : Use CROSS APPLY to check the distance of every quote from every area, only selecting the shortest distance
SELECT *
FROM (SELECT *
      FROM  #AllQuotes as t
      CROSS APPLY (SELECT TOP 1 a.AreaName,
                                a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) AS 'DistanceToZone'
                    FROM Area as a
                    WHERE (a.AreaPoly.STIsValid() = 1)
                    AND (a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) IS NOT NULL)
                    ORDER BY a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) ASC) AS t2 ) AS llz;
</code>```

This is obviously very computationally expensive and is making the PowerBI mashup engine work in overdrive. We are starting to have issues with CPU load on our database due to poor data load optimization. PowerBI rebuilds its data model every refresh and its query engine is not the strongest at using complex queries. Compounding this with the large amount of data, it quickly becomes a real issue with our stability.

Our database doesn't have a schema that is conducive to making efficient analytics queries, there is no transformation happening as it's loaded, and a process to hit a maps API to associate addresses with lat/longs. In order to produce reports with any value, I need to perform a lot of transformations within the query or within the loading process. This isn't the best thing to do, I know, but its what I got working and that could provide value.

I decided to try to move the query into something server side so that PowerBI only needed to load an already transformed and prepped dataset. With views I was able to get a dataset of all of my quotes and their lat/longs.

Now how would I go about running step 3? I have a few ideas:

Use a nested view

Refactor every temp table into a monolith of CTEs that then get transformed by a final view

Research a new method for solving a Lat/Long to Polygon matching problem.

I would like to have a final table that PowerBI can import with a simple SELECT * FROM #AllQuotes so that the mashup engine has to do less work constructing the data model. This would also allow me to implement incremental refresh and be able to only import a day's worth of data as time goes on rather than the full dataset.

Any solutions or ideas on how to match Lat/Long points to a list of geography Polygons in a PBI friendly way would be greatly appreciated.

答:
Can't say I'm a spatial expert, but I don't think you are really using your index. STDistance has to run against every combo of quote/area then sort to find the smallest distance. So you need to reduce the number of areas each quote is compared against

If you review your data, I'd guess you find something like 30% of quotes are within 5,000 meters of your quote location. And 80% are within 10,000 meters.

With that in mind, I think we can add some queries to find those close matches first. This should be able use you spatial indexes efficiently as it can first filter down to only close matches, reducing the number of times you have to calculate the distance of a quote to each area.

Conceptual Code Approach: First Find Quick Matches within Predefined Distance(s)

```<code>/*First identify matches with in small distance like 5,000 meters*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            /*STBuffer creates circle of 5000 meters around Quote location
            STIntersects matches only on data that intersects with that point*/
            WHERE B.QuoteGeogPoint.STBuffer(5000).STIntersects(DTA.AreaPoly)
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C

/*Could run above query again for a medium distance say 10,000 meters*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            WHERE B.QuoteGeogPoint.STBuffer(10000).STIntersects(DTA.AreaPoly)
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C
WHERE A.NearestAreaID IS NULL /*No matches found*/

</code>```

Match Quotes Regardless of Area Distance

Once you've found the easy matches, use this script (your current step 3) to clean up any stragglers

```<code>/*Find matches for any didn't have a match in defined distances*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C
WHERE NearestAreaID IS NULL /*No matches already found*/
</code>```

Body:
I have a PowerBI report that shows metrics and visuals for a large amount of quote data extracted by an API, roughly 400k records a week. These quotes only contain latitude and longitude points for location, but shareholders need to slice views by our service areas. We have a fact table of areas with IDs and geography polygons that I am able to reference.

Currently, the report uses a gnarly custom SQL query that pulls this data from the transactional database, transforms it, and finds the nearest area through a cross apply method.

Here's an example of the code:

-- step 1 : get quotes from the first table

SELECT Col1, Col2...
INTO #AllQuotes
FROM Quotes1
LEFT JOIN (FactTables)
INNER JOIN([filtering self join])
WHERE expression

-- Step 2 : insert quotes from a separate table into our first temp table to get a table with all quote data

INSERT INTO #AllQuotes
SELECT Col1, Col2
FROM Quotes2
LEFT JOIN(Fact Tables)
INNER JOIN([filtering self join])
WHERE expression

-- Step 3 : Use CROSS APPLY to check the distance of every quote from every area, only selecting the shortest distance
SELECT *
FROM (SELECT *
      FROM  #AllQuotes as t
      CROSS APPLY (SELECT TOP 1 a.AreaName,
                                a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) AS 'DistanceToZone'
                    FROM Area as a
                    WHERE (a.AreaPoly.STIsValid() = 1)
                    AND (a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) IS NOT NULL)
                    ORDER BY a.AreaPoly.STDistance(geography::STGeomFromText('POINT('+ cast(t.PickLongitudeTemp as VARCHAR(20)) +' '+ cast(t.PickLatitudeTemp as VARCHAR(20)) +')', 4326).MakeValid()) ASC) AS t2 ) AS llz;

This is obviously very computationally expensive and is making the PowerBI mashup engine work in overdrive. We are starting to have issues with CPU load on our database due to poor data load optimization. PowerBI rebuilds its data model every refresh and its query engine is not the strongest at using complex queries. Compounding this with the large amount of data, it quickly becomes a real issue with our stability.

Our database doesn't have a schema that is conducive to making efficient analytics queries, there is no transformation happening as it's loaded, and a process to hit a maps API to associate addresses with lat/longs. In order to produce reports with any value, I need to perform a lot of transformations within the query or within the loading process. This isn't the best thing to do, I know, but its what I got working and that could provide value.

I decided to try to move the query into something server side so that PowerBI only needed to load an already transformed and prepped dataset. With views I was able to get a dataset of all of my quotes and their lat/longs.

Now how would I go about running step 3? I have a few ideas:

Use a nested view

Refactor every temp table into a monolith of CTEs that then get transformed by a final view

Research a new method for solving a Lat/Long to Polygon matching problem.

I would like to have a final table that PowerBI can import with a simple SELECT * FROM #AllQuotes so that the mashup engine has to do less work constructing the data model. This would also allow me to implement incremental refresh and be able to only import a day's worth of data as time goes on rather than the full dataset.

Any solutions or ideas on how to match Lat/Long points to a list of geography Polygons in a PBI friendly way would be greatly appreciated.

Body:
Can't say I'm a spatial expert, but I don't think you are really using your index. STDistance has to run against every combo of quote/area then sort to find the smallest distance. So you need to reduce the number of areas each quote is compared against

If you review your data, I'd guess you find something like 30% of quotes are within 5,000 meters of your quote location. And 80% are within 10,000 meters.

With that in mind, I think we can add some queries to find those close matches first. This should be able use you spatial indexes efficiently as it can first filter down to only close matches, reducing the number of times you have to calculate the distance of a quote to each area.

Conceptual Code Approach: First Find Quick Matches within Predefined Distance(s)

/*First identify matches with in small distance like 5,000 meters*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            /*STBuffer creates circle of 5000 meters around Quote location
            STIntersects matches only on data that intersects with that point*/
            WHERE B.QuoteGeogPoint.STBuffer(5000).STIntersects(DTA.AreaPoly)
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C

/*Could run above query again for a medium distance say 10,000 meters*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            WHERE B.QuoteGeogPoint.STBuffer(10000).STIntersects(DTA.AreaPoly)
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C
WHERE A.NearestAreaID IS NULL /*No matches found*/

Match Quotes Regardless of Area Distance

Once you've found the easy matches, use this script (your current step 3) to clean up any stragglers

/*Find matches for any didn't have a match in defined distances*/
UPDATE #Quote
SET NearestAreaID = C.AreaID
FROM #Quote AS A
CROSS APPLY (SELECT QuoteGeogPoint = geography::Point(A.PickLatitudeTemp, A.PickLongitudeTemp, 4326)) AS B
CROSS APPLY ( SELECT TOP(1) B.AreaID
            FROM Area AS DTA
            ORDER BY DTA.AreaPoly.STDistance(Q.QuoteGeogPoint)
            ) AS C
WHERE NearestAreaID IS NULL /*No matches already found*/


答:
```<code>$('.chatmember').sort(function(a,b){ return a.id > b.id; })...
</code>```

Returns (in Firebug):

```<code>[div#adam.chatmember, div#bob.chatmember, div#mary.chatmember, div#peter.chatmember, div#steven.chatmember]
</code>```

Title: JQUERY Sorting an Array of Objects

Body:
$('.chatmember').sort(function(a,b){ return a.id > b.id; })...

Returns (in Firebug):

[div#adam.chatmember, div#bob.chatmember, div#mary.chatmember, div#peter.chatmember, div#steven.chatmember]


问:
Trying to create bulk read job for Zoho_Books but getting "Module not Available" from Postman
When trying to make a post request to {{api-domain}}/crm/bulk/v2/read with a body of

```<code>{
  "callback": {
    "url": "https://www.personalcalbackurl.com",
    "method": "post"
  },
  "query": {
    "module": "Zoho_Books",
    "page": 1
  }
}
</code>```

I get an error in Postman of

{"status":"error","code":"MODULE_NOT_AVAILABLE","message":"Requested module Zoho_Books is not available.","details":{"api_name":"Zoho_Books","module":"Zoho_Books"}}

Is a bulk read not available for the Zoho Books module? The Postman request creates a bulk read job for the Contacts module so that's odd that Zoho Finance wouldn't allow a bulk read. I know this is Zoho CRM, but Zoho_Books shows up as Zoho Finance's API name and every time I search for "Bulk Read Zoho Finance" the CRM docs only show up. Am I missing something obvious?

答: You can create custom modules based on Zoho Finance inside of Zoho CRM and they'll come back with an API name of "CustomModule###" and you can use that custom module name to create a bulk read job. Worked perfectly!</p>

Body:
When trying to make a post request to {{api-domain}}/crm/bulk/v2/read with a body of

{
  "callback": {
    "url": "https://www.personalcalbackurl.com",
    "method": "post"
  },
  "query": {
    "module": "Zoho_Books",
    "page": 1
  }
}

I get an error in Postman of

{"status":"error","code":"MODULE_NOT_AVAILABLE","message":"Requested module Zoho_Books is not available.","details":{"api_name":"Zoho_Books","module":"Zoho_Books"}}

Is a bulk read not available for the Zoho Books module? The Postman request creates a bulk read job for the Contacts module so that's odd that Zoho Finance wouldn't allow a bulk read. I know this is Zoho CRM, but Zoho_Books shows up as Zoho Finance's API name and every time I search for "Bulk Read Zoho Finance" the CRM docs only show up. Am I missing something obvious?


问:
Strange query by oracle_fdw
I am using oracle_fdw 2.2.0devel, PostgreSQL 10.13, Oracle client 18.3.0.0.0

We have a foreign table in Postgres defined as this:

```<code>CREATE FOREIGN TABLE public.tickers
(
   ticker_id         INTEGER,
   ticker            VARCHAR,
)
SERVER oracle
OPTIONS (table 'TICKERS', schema 'COMMENTARY', readonly 'true');
</code>```

This is connecting to as 12c SE database.   This works fine, however, I've noticed that the query in Oracle is actually looking like this:

```<code>SELECT
   /*618157932326e692807010156f98ddac*/
   r2."TICKER_ID",
   r2."TICKER"
FROM "COMMENTARY"."TICKERS" r2
WHERE (upper(r2."TICKER") = upper(:p1))
</code>```

Why would it automatically be adding the "UPPER" clause?  This slows the Oracle query and does not use an index, unless I create a FBI using "upper".

Was wondering if there was some option I'm supposed to disable.......

答: The only way that oracle_fdw will generate an Oracle query that uses the upper function is if the original PostgreSQL query already had upper in it.

Title: Strange query by oracle_fdw

Body:
I am using oracle_fdw 2.2.0devel, PostgreSQL 10.13, Oracle client 18.3.0.0.0

We have a foreign table in Postgres defined as this:

CREATE FOREIGN TABLE public.tickers
(
   ticker_id         INTEGER,
   ticker            VARCHAR,
)
SERVER oracle
OPTIONS (table 'TICKERS', schema 'COMMENTARY', readonly 'true');

This is connecting to as 12c SE database.   This works fine, however, I've noticed that the query in Oracle is actually looking like this:

SELECT
   /*618157932326e692807010156f98ddac*/
   r2."TICKER_ID",
   r2."TICKER"
FROM "COMMENTARY"."TICKERS" r2
WHERE (upper(r2."TICKER") = upper(:p1))

Why would it automatically be adding the "UPPER" clause?  This slows the Oracle query and does not use an index, unless I create a FBI using "upper".

Was wondering if there was some option I'm supposed to disable.......


问:
Error on fetch data, function instead of value
Hi guys I am trying to fetch data using get, and I want the data to be displayed after  I click on the button, as a normal crud
I am new in programming if there is someone that can help me. I APPRECIATE THANKS
everything in my backend is ok, I try in postman and console.log is everything good. My problem is only in this part thanks</p>
```<code>
import { useState, useEffect } from "react";
import axios from "axios";

 function Usuarios() {
    const [users, setUsers] = useState([]);

     useEffect(()=> {
        const todosUsers = async () => {
            const res= await axios.get("/users");
            console.log(res)
            setUsers(res.data);
        }
        todosUsers()
    },[])

    return (
        <>
        <button onClick=
        {users.map((users) => (
            <h1>{users.username}</h1>
            ))}></button>
        </>

        )
}

export default Usuarios;

</code>```

答:
use Effect hook runs every time the component is rendered but as I understand, you want to display users when the button is clicked, so you can fetch users once the button is clicked and display them using the code below</p>
```<code>import { useState, useEffect } from "react";
import axios from "axios";

 function Usuarios() {
    const [users, setUsers] = useState([]);

    const fetchUsers= async () => {
            const res= await axios.get("/users");
            setUsers(res.data);
    }

    return (
        <>
          <button onClick={() => fetchUsers()}></button>
          {
             users.length && users.map(user => <h2>{user.username}</h2>)
          }
        </>

        )
}

</code>```

Body:
Hi guys I am trying to fetch data using get, and I want the data to be displayed after  I click on the button, as a normal crud
I am new in programming if there is someone that can help me. I APPRECIATE THANKS
everything in my backend is ok, I try in postman and console.log is everything good. My problem is only in this part thanks

import { useState, useEffect } from "react";
import axios from "axios";

 function Usuarios() {
    const [users, setUsers] = useState([]);

     useEffect(()=> {
        const todosUsers = async () => {
            const res= await axios.get("/users");
            console.log(res)
            setUsers(res.data);
        }
        todosUsers()
    },[])

    return (
        <>
        <button onClick=
        {users.map((users) => (

{users.username}

            ))}></button>
        </>

        )
}

export default Usuarios;

Body:
use Effect hook runs every time the component is rendered but as I understand, you want to display users when the button is clicked, so you can fetch users once the button is clicked and display them using the code below

import { useState, useEffect } from "react";
import axios from "axios";

 function Usuarios() {
    const [users, setUsers] = useState([]);

    const fetchUsers= async () => {
            const res= await axios.get("/users");
            setUsers(res.data);
    }

    return (
        <>
          <button onClick={() => fetchUsers()}></button>
          {
             users.length && users.map(user => <h2>{user.username}</h2>)
          }
        </>

        )
}


问:
tkinter Creating a new window
there I am fairly new with python and object-oriented programming. Most of my experience is from C programming. However, for a personal project, I am using python and its Tkinter libraries to create a GUI on my computer. I was able to build the GUI and created different menu buttons for my project. However, for one of the menu buttons, I would like to open a new window with text and maybe images for the user.

Here is a snippet of the GUI

The location of my error is one of the classes that are in charge of creating the windows menu bars. With its public function named "read_me_exit"

Here is the snippet of my function and its properties

def read_me_exit(self):

    win = tk()

    window_width = 400
    window_height = 200

    # get screen dimension
    screen_width = win.winfo_screenwidth()
    screen_height = win.winfo_screenheight()

    # find the center point
    center_x = int(screen_width / 2 - window_width / 2)
    center_y = int(screen_height / 2 - window_height / 2)

    # create the screen on window console
    win.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')

    win.title('Read Me')
    win.resizable(False, False)
    win.iconbitmap('./msoe.ico')
```
<p>This function gets called in my menubar command line as shown below:</p>
```class Window(tk.Frame):

    # Define settings upon initialization. Here you can specify
    def __init__(self, master):
        super().__init__(master)
        # field options

        # with that, we want to then run init_window, which doesn't yet exist
        self.init_window()

    # Creation of init_window
    def init_window(self):
        # creating a menu instance
        menu = Menu(self.master)
        self.master.config(menu=menu)

        # create the file object
        file = Menu(menu)

        # adds a command to the menu option, calling it exit, and the
        # command it runs on event is client_exit
        file.add_command(label="Read Me", command=self.read_me_exit)
        file.add_command(label="Exit", command=self.user_exit)........
```
<p>When trying to click the Read Me button on my file menubar I receive this error:</p>
```Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\jurado-garciaj\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "C:\Users\jurado-garciaj\Documents\EKG\GUI.py", line 196, in read_me_exit
    win = tk()
TypeError: 'module' object is not callable
```

答:
You could try instead using the win = Toplevel() command to create a new window instead of win = tk()

The Toplevel() acts almost exactly like the Tk() object, so you probably won't have to change any extra code.

Title: tkinter Creating a new window

Body:
there I am fairly new with python and object-oriented programming. Most of my experience is from C programming. However, for a personal project, I am using python and its Tkinter libraries to create a GUI on my computer. I was able to build the GUI and created different menu buttons for my project. However, for one of the menu buttons, I would like to open a new window with text and maybe images for the user.

Here is a snippet of the GUI

The location of my error is one of the classes that are in charge of creating the windows menu bars. With its public function named "read_me_exit"

Here is the snippet of my function and its properties

def read_me_exit(self):

    win = tk()

    window_width = 400
    window_height = 200

    # get screen dimension
    screen_width = win.winfo_screenwidth()
    screen_height = win.winfo_screenheight()

    # find the center point
    center_x = int(screen_width / 2 - window_width / 2)
    center_y = int(screen_height / 2 - window_height / 2)

    # create the screen on window console
    win.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')

    win.title('Read Me')
    win.resizable(False, False)
    win.iconbitmap('./msoe.ico')

This function gets called in my menubar command line as shown below:

class Window(tk.Frame):

    # Define settings upon initialization. Here you can specify
    def __init__(self, master):
        super().__init__(master)
        # field options

        # with that, we want to then run init_window, which doesn't yet exist
        self.init_window()

    # Creation of init_window
    def init_window(self):
        # creating a menu instance
        menu = Menu(self.master)
        self.master.config(menu=menu)

        # create the file object
        file = Menu(menu)

        # adds a command to the menu option, calling it exit, and the
        # command it runs on event is client_exit
        file.add_command(label="Read Me", command=self.read_me_exit)
        file.add_command(label="Exit", command=self.user_exit)........

When trying to click the Read Me button on my file menubar I receive this error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\jurado-garciaj\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "C:\Users\jurado-garciaj\Documents\EKG\GUI.py", line 196, in read_me_exit
    win = tk()
TypeError: 'module' object is not callable


问:
VSCode - Setup a monorepo with a Deno (backend) folder and a Vite (frontend) folder
I'm trying to configure a monorepo with a back (or "api") folder that uses Deno and a front (or "webapp") folder that is a react app (or actually, any framework, configured with Vite).

So the project actually mixes Deno and Node (if it's a bad idea, you can stop me right now).
I'm might also consider using the Deno Linter and Formatter for the whole project.

The file structure would look something like that:

```<code>my-monorepo/
├── .vscode/
│   └── settings.json
├── back/
│   └── index.ts
├── front/
│   ├── src/
│   │   └── index.tsx
│   ├── index.html
│   └── vite.config.ts
├── .gitignore
├── deno.jsonc
└── package.json
</code>```

It pretty much works but the main issue I encounters right now is with the VSCode Deno Extension.

Would it be possible to use the built-in VSCode JS and TS language services for the front/ folder and the Deno Language Server (deno lsp) for the back/ folder?
Otherwise TS gets mad (for instance the imports in back/ must include .ts but in font they most no include .ts).

Finally, if I can make it work, I would like it to be easy for anyone who clones the repo to work with it.

Alo, here is the .vscode/settings.json file for the reference:

{
  "deno.enable": true,
  "deno.config": "./deno.jsonc",

  "[typescript]": {
    "editor.defaultFormatter": "denoland.vscode-deno",
  }
}
```

答:
You are going to run into issues with this setup. See these related GitHub issues 1, 2.

Instead, use Deno's LSP in one workspace (your backend) and the vanilla TS LSP in the other workspace (your frontend), using exclusive VS Code settings files in each. (If you do repo top-level scripting with Deno, then it's fine to duplicate that VS Code config for the top-level, too.)

Then, open a separate VS Code window for each workspace in your monorepo so that they can use their own LSPs without conflict.

Body:
I'm trying to configure a monorepo with a back (or "api") folder that uses Deno and a front (or "webapp") folder that is a react app (or actually, any framework, configured with Vite).

So the project actually mixes Deno and Node (if it's a bad idea, you can stop me right now).
I'm might also consider using the Deno Linter and Formatter for the whole project.

The file structure would look something like that:

my-monorepo/
├── .vscode/
│   └── settings.json
├── back/
│   └── index.ts
├── front/
│   ├── src/
│   │   └── index.tsx
│   ├── index.html
│   └── vite.config.ts
├── .gitignore
├── deno.jsonc
└── package.json

It pretty much works but the main issue I encounters right now is with the VSCode Deno Extension.

Would it be possible to use the built-in VSCode JS and TS language services for the front/ folder and the Deno Language Server (deno lsp) for the back/ folder?
Otherwise TS gets mad (for instance the imports in back/ must include .ts but in font they most no include .ts).

Finally, if I can make it work, I would like it to be easy for anyone who clones the repo to work with it.

Alo, here is the .vscode/settings.json file for the reference:

{
  "deno.enable": true,
  "deno.config": "./deno.jsonc",

  "[typescript]": {
    "editor.defaultFormatter": "denoland.vscode-deno",
  }
}


问:
How to manage a button with disabled attribute using Python Selenium?
Having this button:

```<code><button id="btn-login-5" type="button" class="m-1 btn btn-warning" disabled="">Update</button>
</code>```

I want to remove the disable attribute in order to click the button.

This is the code i see everytime:

```<code>button = self.driver.find_element(
        By.XPATH, "/html/body/div/div/button")
self.driver.execute_script(
        'arguments[0].removeAttribute("disabled");', button)
</code>```

But I can't figure me out how that can work for anyone, I mean, if the element is disabled, selenium cannot run that very first line, is not able to asign the var "button" because he can't find that element.

Am I missing something? I am getting this error if a run that:

```<code>selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/button"}
</code>```

Update

I just realized this is related to selenium grid, I tried to click the button in a lot of ways, and no one works, but if instead of using selenium grid I use a local webdriver all of them works! So I have no idea what to do now.

答:
The disabled attribute can be set to keep a user from clicking on the button until some other condition has been met (like selecting a checkbox, etc.). Then, a JavaScript could remove the disabled value, and make the button clickable again.

You were close enough. To remove the disabled attribute, the Update element can be still identified for it's presence using the following Locator Strategy:

```<code>button = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.XPATH, "//button[@class='m-1 btn btn-warning' and text()='Update']")))
self.driver.execute_script('arguments[0].removeAttribute("disabled");', button)
</code>```

Body:
Having this button:

<button id="btn-login-5" type="button" class="m-1 btn btn-warning" disabled="">Update</button>

I want to remove the disable attribute in order to click the button.

This is the code i see everytime:

button = self.driver.find_element(
        By.XPATH, "/html/body/div/div/button")
self.driver.execute_script(
        'arguments[0].removeAttribute("disabled");', button)

But I can't figure me out how that can work for anyone, I mean, if the element is disabled, selenium cannot run that very first line, is not able to asign the var "button" because he can't find that element.

Am I missing something? I am getting this error if a run that:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/button"}

Update

I just realized this is related to selenium grid, I tried to click the button in a lot of ways, and no one works, but if instead of using selenium grid I use a local webdriver all of them works! So I have no idea what to do now.

Body:
The disabled attribute can be set to keep a user from clicking on the button until some other condition has been met (like selecting a checkbox, etc.). Then, a JavaScript could remove the disabled value, and make the button clickable again.

You were close enough. To remove the disabled attribute, the Update element can be still identified for it's presence using the following Locator Strategy:

button = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.XPATH, "//button[@class='m-1 btn btn-warning' and text()='Update']")))
self.driver.execute_script('arguments[0].removeAttribute("disabled");', button)