Dealing with multiple condition if statement in Dart - flutter

Hi I need help simplifying this if statement with multiple conditions but I'm not sure how to as every attempt I've had cluttered my code even more :
if (isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingAirplane;
if (isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingAirplane;
if (isAirplane(element) && !isFlying(element) && isRed(element)) return redGroundedAirplane;
if (isAirplane(element) && !isFlying(element) && !isRed(element)) return greenGroundedAirplane;
if (!isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingHelicopter;
if (!isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingHelicopter;
if (!isAirplane(element) && !isFlying(element) && isRed(element)) return redGroundedHelicopter;
if (!isAirplane(element) && !isFlying(element) && !isRed(element)) return greenGroundedHelicopter;
EDIT :
Adding some extra context in which I'm using this :
late BitmapDescriptor redFlyingAirplane;
late BitmapDescriptor greenFlyingAirplane;
...
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_initMarkers();
});
}
void _initMarkers() async {
redFlyingAirplane = await LoadBitmaps.redFlyingAirplane;
greenFlyingAirplane = await LoadBitmaps.greenFlyingAirplane;
...
}
BitmapDescriptor resolveBitmap(Something element) {
if (isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingAirplane;
if (isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingAirplane;
...
}

You have 3 booleans, so 8 possible outcomes, and these can be represented in 3 bits with values 0 to 7.
First define a function that turns 3 booleans into that integer, such as:
int bitmapIndex(bool isAirplane, bool isRedColor, bool isFlyingNow) =>
(isAirplane ? 4 : 0) + (isRedColor ? 2 : 0) + (isFlyingNow ? 1 : 0);
Then store your bitmaps in a map, indexed by integer, for example:
final bitmaps = <int, BitmapDescriptor>{};
When you come to load the bitmaps store them in the map:
bitmaps[bitmapIndex(true, true, true)] = await LoadBitmaps.redFlyingAirplane;
bitmaps[bitmapIndex(true, true, false)] = await LoadBitmaps.redGroundedAirplane;
Finally, to access any bitmap, simply look it up:
return bitmaps[bitmapIndex(isAirplane(element), isFlying(element), isRed(element))];

I've taken a similar approach as BBK, but extracted variables for the methods that are called > 1 times, not knowing how "costly" those operations are, and added the use of ternary operator to make it more compact:
var isRedColor = isRed(element);
var isFlyingNow = isFlying(element);
if (isAirplane(element)) {
if (isFlyingNow) {
return isRedColor ? redFlyingAirplane : greenFlyingAirplane;
}
return isRedColor ? redGroundedAirplane : greenGroundedAirplane;
}
if (isFlyingNow) {
return isRedColor ? redFlyingHelicopter : greenFlyingHelicopter;
}
return isRedColor ? redGroundedHelicopter : greenGroundedHelicopter;

Nested If Statements may be used in this case. There is no need to use else conditions since you return a value for every case. The rest of the code won't run in any way if the condition is met.
if (isAirplane(element)) {
if (isFlying(element)) {
if (isRed(element)) return redFlyingAirplane;
return greenFlyingAirplane;
}
if (isRed(element)) return redGroundedAirplane;
return greenGroundedAirplane;
}
if (isFlying(element)) {
if (isRed(element)) return redFlyingHelicopter;
return greenFlyingHelicopter;
}
if (isRed(element)) return redGroundedHelicopter;
return greenGroundedHelicopter;

Related

Flutter: freezed custom operator == does not work as I accept

I am using freezed and I have list of object, I override my freezer class like this:
#override
bool operator ==(Object other) =>
other is _ServiceItemModel &&
id == other.id &&
product.id == other.product.id &&
product.externalId == other.product.externalId &&
internalId == other.internalId &&
identical(other, this);
#override
int get hashCode => [id, product.id, product.externalId, internalId].hashCode;
my question is why the value of bool iseq = identical(servicesItem, oldService ); return false !
servicesItem and oldService are List of ServiceItemModel.
you should remove this line
identical(other, this);

Solidity method taking in bytes32 and hashing but values with previous hash don't match

Here's the code:
function playGame(bytes32 hashedMove) public returns (bool) {
require(
playerOne != address(0x0) && playerTwo != address(0x0),
"Game needs more players to join first"
);
require(
msg.sender == playerOne || msg.sender == playerTwo,
"You did not join the game as a player"
);
if (msg.sender == playerOne && hashedPlayerOneMove == "") {
hashedPlayerOneMove = hashedMove;
emit PlayerMadeMove(playerOne);
} else if (msg.sender == playerTwo && hashedPlayerTwoMove == "") {
hashedPlayerTwoMove = hashedMove;
emit PlayerMadeMove(playerTwo);
} else {
return false;
}
return true;
}
The above method takes in a hashedMove argument which I am using the following site to get: https://emn178.github.io/online-tools/keccak_256.html
I send a value of 2test2 hashed which is 0x0698472c4668bddd0c694601ca101551bd7b5cfe6dc780ab37bccfc99ad22e4c
Now another method takes in the constituents of the hash which are 2 and test2 to compare it with the stored hash:
function revealPlayerChoice(uint256 move, bytes32 password)
public
returns (uint256)
{
require(
hashedPlayerOneMove != bytes32(0x0) &&
hashedPlayerTwoMove != bytes32(0x0),
"The game is still running!"
);
bytes32 hashedAnswer = getSaltedHash(move, password);
console.logBytes32(hashedAnswer);
console.logBytes32(hashedPlayerOneMove);
if (msg.sender == playerOne && hashedAnswer == hashedPlayerOneMove) {
playerOneMove = move;
} else if (
msg.sender == playerTwo && hashedAnswer == hashedPlayerTwoMove
) {
playerTwoMove = move;
}
if (playerOneMove != 0 && playerTwoMove != 0) {
getGameOutcome();
}
}
I'm sending 2 as uint and 0x0000000000000000000000000000000000000000000000000000007465737432 (test2 in bytes) to the revealPlayerChoice method. However the values I'm getting from the console log are different. hashedAnswer is the hash I'm calculating in the method and hashedPlayerOneMove is the hash stored in playGame method.
for example, The console log outputs are
0x566d7dd4e9dc72e9beef887f2982703a0d0f9dd1b6505ee3ff5310c7383637bd
0x0698472c4668bddd0c694601ca101551bd7b5cfe6dc780ab37bccfc99ad22e4c
I would like to understand why the values are different? I'm using keccak256 to hash in solidity (pragma solidity ^0.8.0;) as well:
function getSaltedHash(uint answer, bytes32 salt) pure returns (bytes32) {
return keccak256(abi.encodePacked(answer, salt));
}
The key to your problem might be what abi.encodePacked(answer, salt) is returning.
When you pass the following arguments:
uint256 answer = 2
bytes32 salt = 0x0000000000000000000000000000000000000000000000000000007465737432
abi.encodePacked(answer, salt) returns:
0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000007465737432
And then, if you run the keccak256(bytes) with the previous value, it returns:
0x566d7dd4e9dc72e9beef887f2982703a0d0f9dd1b6505ee3ff5310c7383637bd

why the filter does not work as expected?

how can I make the logic so when I press vegan and lactose it will show me a meal that contains at least one of them or both?
in the current state it shows only meals that contains both.
Map<String, bool> _filters = {
'gluten': false,
'lactose': false,
'vegan': false,
'vegetarian': false,
};
//above is a switchTile so the values change
_availableMeals = DUMMY_MEALS.where((meal) {
if (_filters['gluten']! && !meal.isGlutenFree) {
return false;
}
if (_filters['lactose']! && !meal.isLactoseFree) {
return false;
}
if (_filters['vegan']! && !meal.isVegan) {
return false;
}
if (_filters['vegetarian']! && !meal.isVegetarian) {
return false;
}
return true;
}).toList();
Here you go. Part of the problem was that you were using ! to mean == false
_availableMeals = DUMMY_MEALS.where((meal) {
// actually i'm not sure about this part, try removing it if it doesn't make sense in your UI
if (_filters['gluten'] == false &&
_filters['lactose'] == false &&
_filters['vegan'] == false &&
_filters['vegatarian'] == false) {
return true;
}
if (_filters['gluten'] == true && meal.isGlutenFree) {
return true;
}
if (_filters['lactose'] == true && meal.isLactoseFree) {
return true;
}
if (_filters['vegan'] == true && meal.isVegan) {
return true;
}
if (_filters['vegetarian'] == true && meal.isVegetarian) {
return true;
}
return false;
}).toList();

Expected a value of type 'string' but got one of type 'int' - Flutter

I have a function that returns a String, but when I call this function, the app screen goes red and I get this error: Expected a value of type 'string' but got one of type 'int'.
Here is my function that returns a String:
checkProportion(String predominantGamete, String resultado) {
var countBrown = 0;
var countBlack = 0;
var countWhite = 0;
var proportionCamundongo =
'Proporção: ${countBrown}:${countBlack}:${countWhite}';
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
return countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
return countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
return countWhite += 1;
}
return proportionCamundongo;
}
Here is how I call the function:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
checkProportion(widget.predominant, widget.result),
),
),
How to solve this error?
Here is an image that shows the colors of each result:
The issue here is that you are returning early, not breaking the if statement, when you do something like return countBrown += 1;;
Try incrementing the counters, then using string interpolation to display the value:
String checkProportion(String predominantGamete, String resultado) {
int countBrown = 0;
int countBlack = 0;
int countWhite = 0;
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
countWhite += 1;
}
return 'Proporção: ${countBrown}:${countBlack}:${countWhite}';
}
I'd also recommend specifing the return type of the function (String), using the correct types for counters (int). That will help your compiler catch the issues as well.
It isn't my best work, and there is probably a better way to check for if a string contains all occurrence of multiple substrings, but here you go:
bool isColorContained(String resultado, Set<String> requirements) {
for(String requirement in requirements) {
if (!resultado.contains(requirement)) {
return false;
}
}
return true;
}
 
String checkProportion(String predominantGamete, String resultado) {
Map<ColorType, Set<String>> colorType = {
ColorType.brown: {'A', 'P'},
ColorType.black: {'A', 'pp'},
ColorType.white: {'aa'},
};
Map<ColorType, int> colorTypeCount = {
ColorType.brown: 0,
ColorType.black: 0,
ColorType.white: 0,
};
for(MapEntry<ColorType, Set<String>> entry in colorType.entries ) {
if(predominantGamete != 'recessiva_aa') continue;
bool contained = isColorContained(resultado, entry.value);
if(contained) {
int count = colorTypeCount[entry.key] ?? 0;
colorTypeCount[entry.key] = count + 1;
}
}
return 'Proporção: ${colorTypeCount[ColorType.brown]}:${colorTypeCount[ColorType.black]}:${colorTypeCount[ColorType.white]}';
}
 
Also, declare the ColorType enum:
enum ColorType {
brown, black, white
}
This will scale with as many colors and requirements you have, by adding to the ColorType enum, the colorType map, and the colorTypeCount map.

Passing parameters for methods in Scala (alternatives to change variables values)

I need translate a Java code to Scala, but the compiler show me error. I understand that parameter input on methods are val type. Which alternative i can adopt if i need transform these values? I think to apply case class or class... Below the snippet code (in Scala):
def pmerge_FA(x: Pennant,y: Pennant): Pennant={
if(x == null && y == null && this.root == null){
return null
}else if(x == null && y == null){
return this
}else if(this.root == null && x == null){
return y
}else if(this.root == null && y == null){
return x
}else if(x == null){
y = y.pmerge(this) //error
null
}else if(this.root == null){
y = y.pmerge(x) //error
null
}else if (y == null){
y = this.pmerge(x) // error
null
}else{
y = y.pmerge(x)
this
}
}
Note that error is showed where y parameter is updated.
Thanks
Yes, the error is shown because you cannot reassign something to val, and parameters to methods in Scala are only sent as vals (immutables).
Because you don't provide the full definition of this, it's difficult to suggest an alternative solution, but:
In general, instead of if-else "Java" style, in Scala you can use pattern matching, and instead of null you can use Option, which is very powerful.
For Example, I suggest refactoring your method in this "Scala" Style (partial implementation)
def pmerge_FA(x: Pennant, y: Pennant): Option[Pennant] = {
(Option(x),Option(y), Option(this.root)) match {
case (None, None, None) => None
case (None, None, _) => Option("")
case (None, _, None) => Option(y)
case (_, None, None) => Option(x)
case (None, _, _) =>
....
}
}
Such that you will return the x, y as their new values, or create a case class like:
case class PennantCaseClass (x:Pennant, y:Pennant)
And returning it when needed.
Again, If you will provide some more info about Pennant class it will be easier to give a better alternative implementation for this method.
New values of y (namely y.pmerge(...)) are never used after assignments. So I guess all assignments y = y.pmerge(...) can be replaced with just invocations y.pmerge(...).
Does y.pmerge(...) do any side effects? Just in case, if not then values y.pmerge(...) are never used (only null or this is returned), so in such case lines y = y.pmerge(...) can be removed at all.
So the code can be either (if there are side effects)
def pmerge_FA(x: Pennant,y: Pennant): Pennant={
if(x == null && y == null && this.root == null){
null
}else if(x == null && y == null){
this
}else if(this.root == null && x == null){
y
}else if(this.root == null && y == null){
x
}else if(x == null){
y.pmerge(this)
null
}else if(this.root == null){
y.pmerge(x)
null
}else if (y == null){
this.pmerge(x)
null
}else{
y.pmerge(x)
this
}
}
or (if there are no side effects)
def pmerge_FA(x: Pennant,y: Pennant): Pennant={
if(x == null && y == null && this.root == null){
null
}else if(x == null && y == null){
this
}else if(this.root == null && x == null){
y
}else if(this.root == null && y == null){
x
}else if(x == null){
null
}else if(this.root == null){
null
}else if (y == null){
null
}else{
this
}
}
Oh, right! There are three classes to build a Bag data structure object, with nodes added in perfectly balanced tree. These methods works in that one. Below the complete code (in Java). The Pennant class build a forest using the node of graph object.
Node Class:
public class Node {
private Node left;
private Node right;
private int item;
public Node() {
left = null;
right = null;
item = 0;
}
public Node(int value) {
left = null;
right = null;
item = value;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public int getItem() {
return this.item;
}
public void setItem(int item) {
this.item = item;
}
}
public class Pennant{
private Node root;
public Pennant() {
this.root = null;
}
public Pennant(int value) {
this.root = new Node(value);
}
public void setRoot(Node root) {
this.root = root;
}
public Node getRoot() {
return this.root;
}
public Pennant pmerge(Pennant y) {
if(this.getRoot() == null) {
return y;
}else {
this.getRoot().setRight(y.getRoot().getLeft());
y.getRoot().setLeft(this.getRoot());
}
return y;
}
public Pennant pmerge_FA(Pennant x, Pennant y) {
if(x == null && y == null && this.getRoot() == null) {
return null;
}else if(x == null && y == null) {
return this;
}else if(this.getRoot() == null && x == null) {
return y;
}else if(this.getRoot() == null && y == null) {
return x;
}else if(x == null) {
y = y.pmerge(this);
return null;
}else if(this.getRoot() == null) {
y = y.pmerge(x);
return null;
}else if (y == null) {
y = this.pmerge(x);
return null;
}else {
y = y.pmerge(x);
return this;
}
}
public Pennant psplit() {
if(this.getRoot() != null && this.getRoot().getLeft() != null) {
Pennant y = new Pennant();
y.setRoot(this.getRoot().getLeft());
this.getRoot().setLeft(y.getRoot().getRight());
y.getRoot().setRight(null);
return y;
}
return null;
}
public void remove_all(Node node) {
if (node.getLeft() != null) {
remove_all(node.getLeft());
}
if(node.getRight() != null) {
remove_all(node.getRight());
}
node = null;
}
}