How do I calculate a percentage based on a List of booleans? - flutter

I have a list of booleans here:
List<bool> list = [false, false, false, false];
Using that as an example, if I were to find the percentage of values that are true, it would be 0%.
Using another example:
List<bool> list = [true, true, false, false];
The percentage of values that are true would be 50%.
I was able to find something similar to what I need here: Flutter - Count List with bool which works.
However, the calculations to percentages are a little lost on me.

It's basically just the number of true elements divided by the total number of elements.
void main() {
List<bool> list = [true, true, false, false];
double percent = list.where((v) => v).length / list.length;
String percentString = '${(percent * 100).round()}%';
print(percent);
print(percentString);
}

You should probably do something like :
int trueValues = list.fold(0, (acc, val) => val ? ++acc : acc);
double truePercent = trueValues / list.length;
count the number of 'true' value and divide it by the list size (total number of values)

Related

How to keep the current option in group button flutter

I was used group_button package from flutter to make user can select many options. After upgrading the library to version 5.0.0 or above, the selectedButtons property has been deprecated. I was save options of user by it but no I can't use it now. I was use it as:
GroupButton(
selectedButtons: setSelectedBtn(index),
isRadio: false,
spacing: 10,
onSelected: (i, isSelected) =>
onFilterSelect(index, i, isSelected),
buttons: widget.filters[index].value
.map((e) => e.value)
.toList())),
setSelectedBtn(index) {
List<int> result = [];
var valueSet = widget.filters[index].value;
bool isSelected = valueSet
.firstWhere((element) => element.isSelected,
orElse: () => CategoryFilterValues("", false))
.isSelected;
if (!isSelected) {
return result;
}
for (int index = 0; index < valueSet.length; index++) {
if (valueSet.elementAt(index).isSelected) {
result.add(index);
}
}
return result;
}
group_button
How I can save the options now in new version? Anyone can help me to do it.
thank you
Use GroupButtonController.
Controller have list of methods to interact with options.
selectIndex(int i) - Select button by index in radio type
unselectIndex(int i) - Unselect button by index in checkbox and radio type
... etc.
More docs and examples you can find here

How to create a function that randomly selects a string?

I have a function that adds the string "add" to the list every 5 seconds. How can I make a function so that it randomly selects one of 3 rows and adds it? And every 5 seconds chose another.
Strings: 'add', 'delete', 'remove'.
My code:
class EventNotifier extends ValueNotifier<List<String>> {
EventNotifier(List<String> value) : super(value);
final stream = Stream.periodic(const Duration(seconds: 5));
late final streamSub = stream.listen((event) {
value.add('add');
});
}
Random is indeed the way to go. Since this is Dart, and not JS, Math.random() specifically won't work, but you can use Random in dart:math instead ;)
final List<String> options = ["add", "delete", "remove"];
...
value.add(options[Random().nextInt(4)]); // max of 4 to get a random index in [0, 1, 2]
Same as the other answer, it's pseudo-random, but definitely good enough

If statement inside a For loop - (If null don't add)

I'm working on a project with Firestore, I'm gathering Button data to create each button with a For loop. I could manage to get this data and store it to a List and create the buttons. Now I'm attempting to let the User Add or Delete his own buttons inside the App.
This is an ExampleIf I have 5 buttons in my App, I'm gathering info from firestore to know if these buttons are OFF or ON. I'm storing this bool states into a List, so if I have 5 buttons, I would have a list that you be:
List<bool> cardsValue = [false, false, true, false, true];
But when I delete one of these buttons, so Let's say I deleted the middle one, I would get an array, like this:
List<bool> cardsValue = [false, false, null, false, true];
I would need to Add an If statement so when I receive null as response, It won't add that null into my List. So my list would be:
List<bool> cardsValue = [false, false, false, true];
End of example
Actual code:
This is how my List actually looks:
List<bool> cardsValue = [for (int i = 0; i < cardamount; i++) snapshot.data[devices[i]]];
What I though on doing but unfortunatly didn`t work was:
List<bool> cardsValue = [for (int i = 0; i < cardamount; i++) if (snapshot.data[devices[i]] == null){}else{snapshot.data[devices[i]]}];
You can use where method of List class to filter out null values
List<bool> cardsValue = [for (int i = 0; i < cardamount; i++) snapshot.data[devices[i]]]
.where((v) => v != null)
.toList()
.cast<bool>()
Output
[false, false, false, true]
Your initial approach was close, but Dart's collection-for and collection-if constructs cannot use braces; they must be used with expressions, not statements.
List<bool> cardsValue = [
for (int i = 0; i < cardamount; i++)
if (snapshot.data[devices[i]] != null)
snapshot.data[devices[i]]
];

Dart Not understanding how forEach is supposed to work

I simply wanted to use forEach to set all values in a List to false, but I don't understand why it doesn't work. I created a filled list with fixed length like this:
List<bool> myList = List<bool>.filled(6, false);
Then I set one value to true:
setState(() => myList[3] = true);
Then I try to reset all values to false again, but as you can see from the print output it does not work:
setState(() {
myList.forEach((val) => val = false);
print(myList);
});
I/flutter (29049): [false, false, false, true, false, false]
You can check the answer why you can't update the values inside forEach here: List.forEach unable to modify element?
Dart does not have variable references, all elements are passed as a reference to an object, not to a variable. (In other words, Dart is purely "call-by-sharing" like both Java and JavaScript).
That means that the e parameter to the forEach callback is just a normal local variable, and assigning to it has no effect outside the callback. The same goes for iterators: they return the value in the iterable, but it has no reference back to the iterable after that.
You can do what you want using filled method like you used to create the list.
setState(() {
myList = List<bool>.filled(myList.length, false);
print(myList);
});
forEach element can not modify the actual element in the list. Assume this code:
var list = [false, true, false, false];
list.forEach((item) {
item = false;
});
print("List: $list");
The output is still:
List: [false, true, false, false]
So what you can do is using an indexed for:
for (int i=0; i < list.length; i++) {
list[i] = false;
}
Or map it and reassign it:
var list = [true, true, false];
list = list.map((item) {
return false;
}).toList();
You'll get:
List: [false, false, false, false]
As pointed out above, the forEach function does not give you write access to the list, it just provides you with the value. Changing the parameter of the forEach callback function has no effect outside of that function call, it's just changing a local variable.
To change the list, you must store to its element slots directly. Either:
for (int i = 0; i < list.length; i++) list[i] = false;
or
list.fillRange(0, list.length, false);
should do the job.

Recognize a sequence of elements with minimum and maximum duration

Given a IObservable<bool>,and two TimeSpan thresholds, minDuration and maxDuration, I need to transform the sequence so that:
A sequence of true values that spans a time between minDuration and maxDuration transforms to "x"
A sequence of true values that spans more than maxDuration transforms to "y"; "y" should be emitted after maxDuration time passed since the first true value was emitted
To make things clearer, assuming minDuration = 3, maxDuration = 6, and assuming items are emitted at the speed of one per second:
fffttffttfftttttttttttffftttffffttttf
------------------y--------x-------x-
My guess is that I need to implement a custom operator, but as a RX newbie I don't know how, and I'm having a hard time finding examples that go beyond composing the existing operator with an extension method.
Links to tutorials and examples on implementing custom operators are welcome.
If I understand this right:
When you get consecutive true values for more than the minDuration but less than the maxDuration, you want to emit x.
When you get consecutive true values for more than the maxDuration, you want to emit y.
In any other scenario, emit nothing.
If that's the case, your marble diagram should look more like this:
fffttffttfftttttttttttffftttffffttttf
1234567 123 1234 (numbers for counting guidance)
-----------------y----------x-------x (mine)
------------------y--------x-------x- (yours)
The x can only come out on the false. You can't emit it on the true, because you don't know what a future value will be! No custom operator can solve that for you.
The rest could be solved with this:
var values = new List<bool> // matches fffttffttfftttttttttttffftttffffttttf
{
false,
false,
false,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
true,
true,
true,
false,
false,
false,
false,
true,
true,
true,
true,
false,
};
var original = Observable.Interval(TimeSpan.FromSeconds(1))
.Where(i => i < values.Count)
.Select(i => values[(int)i]);
TimeSpan minDuration = TimeSpan.FromSeconds(3);
TimeSpan maxDuration = TimeSpan.FromSeconds(6);
var trueWindows = original
.TimeInterval()
.Scan(TimeSpan.Zero, (a, t) => t.Value
? a + t.Interval
: TimeSpan.Zero);
var coupledWindows = trueWindows.Scan(new {Previous = TimeSpan.Zero, Current = TimeSpan.Zero},
(o, t) => new {Previous = o.Current, Current = t})
.Publish()
.RefCount();
var xS = coupledWindows.Where(o => o.Previous < maxDuration && o.Previous >= minDuration && o.Current == TimeSpan.Zero).Select(t => "X");
var yS = coupledWindows.Where(o => o.Current >= maxDuration && o.Previous < maxDuration).Select(t => "Y");
As for tutorials, the best resource is http://introtorx.com/. Another somewhat good one is http://rxmarbles.com, though it uses non-.NET function names.