How to return two value from a function in dart? - dart

here is my code
import 'dart:io';
import 'dart:math';
void main() {
bool flag = false;
for (int i = 0; i < 100; i++) {
gameCode();
if (userNumber == computerNumber) {
flag = true;
break;
}
}
}
int randomNumber(number) {
Random randNumber = Random();
int random = randNumber.nextInt(number);
return random;
}
gameCode() {
int computerNumber = randomNumber(9);
print("start guessing the number : ");
int userNumber = int.parse(stdin.readLineSync()!);
if (userNumber == computerNumber) {
print("You got it");
}
}
in this code you can see gameCode function. in that function there is two value that i need to use in main function.so how do i return those two keyword from that function ?
//userNumber // computerNumber
this is the variable that i want to return from that code

Dart not support return multiple values in function, you can return it with array, map, or you can use third lib tuple

Dart does not support returning multiple values in the current latest version. I would in your case recommend creating a class for the specific purpose of define the result from gameCode(). So something like this:
class GameCodeResult {
int userNumber;
int computerNumber;
GameCodeResult({
required this.userNumber,
required this.computerNumber,
});
}
Which we can then use like this in your program:
import 'dart:io';
import 'dart:math';
void main() {
bool flag = false;
for (int i = 0; i < 100; i++) {
GameCodeResult result = gameCode();
if (result.userNumber == result.computerNumber) {
flag = true;
break;
}
}
}
final _random = Random();
int randomNumber(int maxNumber) => _random.nextInt(maxNumber);
GameCodeResult gameCode() {
int computerNumber = randomNumber(9);
print("start guessing the number : ");
int userNumber = int.parse(stdin.readLineSync()!);
if (userNumber == computerNumber) {
print("You got it");
}
return GameCodeResult(userNumber: userNumber, computerNumber: computerNumber);
}
Note, I also fixed your randomNumber() method since it is not recommended to generate a new Random() object for each new random number you want. We should instead reuse an instance of Random in our program.

Please refer to below code
import 'dart:io';
import 'dart:math';
void main() {
bool flag = false;
for (int i = 0; i < 100; i++) {
Map<String, dynamic> res = gameCode();
print(res);
if (res['user_number'] == res['computer_number']) {
flag = true;
break;
}
}
}
int randomNumber(number) {
Random randNumber = Random();
int random = randNumber.nextInt(number);
return random;
}
Map<String, dynamic> gameCode() {
int computerNumber = randomNumber(9);
print("start guessing the number : ");
int userNumber =
int.parse(stdin.readLineSync()!);
if (userNumber == computerNumber) {
print("You got it");
}
return {
"computer_number": computerNumber,
"user_number": userNumber,
};
}

Related

Can I use class methods inside factory constructor via Dart

I have the below code that is creating the PriortyQueue structure using Dart. But since I cannot use heapify function inside the Constructor or factory constructor I cannot initialize PQ with an existing set of List. Can somebody guide me and show me how I can use heapify while creating PQ instance so I can initialize it with an existing List? Also If you have any other suggestions against doing something like this please also help me as well. thank you
class PriorityQueue<T extends Comparable<T>> {
List<T?> _tree;
PriorityQueue._(List<T?> tree) : _tree = tree;
factory PriorityQueue([List<T>? array]) {
List<T?> newArray = [null, ...array ?? []];
// ignore: todo
//TODO: missing heapify
return PriorityQueue._(newArray);
}
void insert(T node) {
_tree.add(node);
_swim(_tree.length - 1);
}
T getTop() {
_swap(1, _tree.length - 1);
T top = _tree.removeLast() as T;
_sink(1);
return top;
}
List<T> _heapify(List<T> array) {
int sinkNodeIndex = (array.length - 1) ~/ 2;
while (sinkNodeIndex >= 1) {
_sink(sinkNodeIndex);
sinkNodeIndex--;
}
}
void _sink(int nodeIndex) {
int leftChildIndex = nodeIndex * 2;
int rightChildIndex = leftChildIndex + 1;
int minNodeIndex = leftChildIndex;
// index can be unreachable
T? leftChild =
leftChildIndex >= _tree.length ? null : _tree[leftChildIndex];
T? rightChild =
rightChildIndex >= _tree.length ? null : _tree[rightChildIndex];
if (leftChild == null) {
return;
}
if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
minNodeIndex = rightChildIndex;
}
if ((_tree[minNodeIndex] as T).compareTo(_tree[nodeIndex] as T) < 0) {
_swap(nodeIndex, minNodeIndex);
_sink(minNodeIndex);
}
}
void _swim(int nodeIndex) {
if (nodeIndex <= 1) return;
int parentIndex = nodeIndex ~/ 2;
if ((_tree[nodeIndex] as T).compareTo(_tree[parentIndex] as T) < 0) {
_swap(nodeIndex, parentIndex);
_swim(parentIndex);
}
}
void _swap(int i, int j) {
T temp = _tree[i] as T;
_tree[i] = _tree[j];
_tree[j] = temp;
}
#override
String toString() {
return _tree.toString();
}
}
I would make all the helper functions. _heapify, _sink/_swim, even _swap, be static functions which take the list as argument.
Then you can use them from anywhere, including inside the factory constructor.
Alternatively, you can change the constructor to returning:
return PriorityQueue._(newArray).._heapify();
This creates the PriorityQueue object, and then calls the _heapify method on it, before returning the value.
(I'd also make _tree have type List<T> and not insert the extra null at the beginning. It's more efficient to add/subtract 1 from indices than it is to cast to T.)
I ended up doing like Irn's first suggestion. But when I do functions static they lost Type of the class so I needed to specify for each function. Also, making List<T?> instead of List ended up with me fighting against the compiler.
class PriorityQueue<T extends Comparable<T>> {
List<T?> _tree;
PriorityQueue._(List<T?> tree) : _tree = tree;
factory PriorityQueue([List<T>? array]) {
List<T?> newArray = [null, ...array ?? []];
_heapify(newArray);
return PriorityQueue._(newArray);
}
bool get isNotEmpty {
return _tree.isNotEmpty;
}
void insert(T node) {
_tree.add(node);
_swim(_tree, _tree.length - 1);
}
void insertMultiple(List<T> array) {
for (var element in array) {
insert(element);
}
}
T? removeTop() {
if (_tree.length == 1) return null;
_swap(_tree, 1, _tree.length - 1);
T top = _tree.removeLast() as T;
_sink(_tree, 1);
return top;
}
void removeAll() {
_tree = [null];
}
static void _heapify<T extends Comparable<T>>(List<T?> array) {
int sinkNodeIndex = (array.length - 1) ~/ 2;
while (sinkNodeIndex >= 1) {
_sink(array, sinkNodeIndex);
sinkNodeIndex--;
}
}
static void _sink<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
int leftChildIndex = nodeIndex * 2;
int rightChildIndex = leftChildIndex + 1;
int minNodeIndex = leftChildIndex;
T? leftChild = leftChildIndex >= tree.length ? null : tree[leftChildIndex];
T? rightChild =
rightChildIndex >= tree.length ? null : tree[rightChildIndex];
if (leftChild == null) {
return;
}
if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
minNodeIndex = rightChildIndex;
}
if ((tree[minNodeIndex] as T).compareTo(tree[nodeIndex] as T) < 0) {
_swap(tree, nodeIndex, minNodeIndex);
_sink(tree, minNodeIndex);
}
}
static void _swim<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
if (nodeIndex <= 1) return;
int parentIndex = nodeIndex ~/ 2;
if ((tree[nodeIndex] as T).compareTo(tree[parentIndex] as T) < 0) {
_swap(tree, nodeIndex, parentIndex);
_swim(tree, parentIndex);
}
}
static void _swap<T extends Comparable<T>>(List<T?> tree, int i, int j) {
T temp = tree[i] as T;
tree[i] = tree[j];
tree[j] = temp;
}
#override
String toString() {
return _tree.toString();
}
}

Is Dart/Flutter has a listener function?

The listener function can listen to any parameter type(not only listener type). This has nothing related to widgets (this should work successfully in https://dartpad.dev without using the flutter).
ex.
int a = 0;
listener((a>0)=>print("A = $a"));
a= 1; //A = 1
a= -1; //
a= 2; //A = 2
You can use ValueNotifier for this. It's a ChangeNotifier that is triggered when the value is replaced with something that is not equal to the old value as evaluated by the equality operator ==.
Here is a nice tutorial about this approach.
The basic method is to create the function for updating the parameter that you want to add to the listener.
void test() {
int a = 0;
void updateA(newA) {
if(newA is! int) return;
a = newA;
if (a > 0) print("A = $a");
}
updateA(1);
updateA(-1);
updateA(2);
}
A better way is to create parameters with class.
void main() {
ParameterWithListener a = ParameterWithListener(data: 0);
a.listener = () {
if (a.data is int && a.data > 0) print("A = ${a.data}");
};
a.update(1);
a.update(-1);
a.update(2);
}
class ParameterWithListener {
ParameterWithListener({this.data, this.listener});
dynamic data;
Function()? listener;
Future update(data) async {
this.data = data;
if (listener is Function()) await listener!();
}
}
result:
A = 1
A = 2

dart: access function from list

Edit: i know, always call the first element on list, it isnt the point. i want to call numbers[0] func. and it regenerate new int.actually codes are not same which mine, i have a custom class which based on functions with random int and i need to use list of my custom class , so if i use func in list it will be awesome, how can i make new numbers list each time. when app start list regenerated, but i want when i call the list, it will regenerated
i want to print new int for each print but it prints same int , i tried so many thing and i cant figure out
void main{
int ramdomint(){
final _random = new Random();
int _num = _random.nextInt(100);
return _num;
}
List<int> numbers=[ramdomint(),ramdomint(),ramdomint()];
void printNums(){
for(var i=0;i<3;i++){
List<int> newNumbers =new List.from(numbers); //what can i use for this?
print(newNumbers[0]); //edit:i dont want [i], iwant to use ewNumbers[0] for new int for each time
}
}
printNums();
// expected new int for each but same one
}
solution from a friend:
import 'dart:math';
int get ramdomint => Random().nextInt(100);
List<int> get numbers => [ramdomint, ramdomint, ramdomint];
void main() {
for (var i = 0; i < 3; i++) {
print(numbers[0]);
}
}
Do not nest functions. Move ramdomint and printNums outside main function.
Add an empty list of arguments to the main function.
printNums: pass list of numbers as an argument.
printNums: you don't need to copy the list to the newNumbers if you want only to display the content of the list.
printNums: the problem is, you access only first element of the list (with 0 index).
import 'dart:math';
void main() {
List<int> numbers = [ramdomint(), ramdomint(), ramdomint()];
printNums(numbers);
}
int ramdomint() => Random().nextInt(100);
void printNums(List<int> numbers) {
// Easier way:
for (int item in numbers) {
print(item);
}
// Your way:
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
}
EDIT:
According to #jamesdlin's comment, you can extend list class to randomize unique values in the list:
import 'dart:math';
void main() {
var numbers = <int>[]..randomize();
printNums(numbers);
}
void printNums(List<int> numbers) {
// Easier way:
for (int item in numbers) {
print(item);
}
// Your way:
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
}
extension on List<int> {
void randomize({
int length = 3,
int maxValue = 100,
}) {
final generator = Random();
for (var i = 0; i < length; i++) {
add(generator.nextInt(maxValue));
}
}
}
The Problem here is that you are creating a list from the numbers list and accessing only the first element.
So it always prints the first element.
import 'dart:math';
void main() {
int ramdomint(){
final _random = new Random();
int _num = _random.nextInt(100);
return _num;
}
List<int> numbers=[ramdomint(),ramdomint(),ramdomint()];
void printNums(){
for(var i=0;i<3;i++){
print(numbers[i]);
}
}
printNums();
}
Don't want newNumbers, because it is already in List.
and the usage of List.from() - Documentation
Hope that works!

Dart: Accessing function from list

I want to have a new random number every time to print it, but it prints the same on. I tried so many thing, but I can't figure out what's wrong. Help me, please!
import 'dart:math';
int next_int() { return new Random().nextInt(100); }
void main()
{
List<int> list = [next_int(), next_int(), next_int()];
// expected new int each time but got the same one
for (var i = 0; i < 3; i++)
{
List<int> cur_list = new List.from(list);
print(cur_list[0]);
}
}
This code will work as you expect:
import 'dart:math';
int next_int() { return new Random().nextInt(100); }
void main()
{
List<int> list = [next_int(), next_int(), next_int()];
// expected new int each time but got the same one
for (var i = 0; i < 3; i++)
{
List<int> cur_list = new List.from(list);
print(cur_list[i]); // <= Use the index value stored in "i" instead of 0
}
}

keeping track of a series of simple multiple choice web form answers

This is the code I'm trying to use, which seems logical. But doesn't seem to be working.
MyAsFileName.prototype.getTotalScore = function() {
var totalScore = 0;
for (var i = 0; i < allQuestions.length; i++) {
totalScore += allQuestions[i].getCalculatedScore();
if (currentModule.allQuestions[i].parent.questionCorrect == true) {
knowledgePoints++;
} else {
knowledgePoints--;
}
}
debugLog("Total score: " + totalScore);
debugLog(knowledgePoints);
return totalScore;
}
I have allQuestions defined as below:
var allQuestions = Array();
I have knowledgePoints defined as:
this.knowledgePoints = 10;
I have questionCorrect defined as:
this.questionCorrect = false;
Second fresh attempt made with new class as answer below suggested (commented out for now until I figure out how to get working):
// package
// {
/*public class Quiz {
//public
var knowledgePoints: int = 10;
//public
var allQuestions: Array = new Array;
//public
var questionCorrect: Boolean = false;
//public
function getTotalScore(): int {
var totalScore: int = 0;
for (var i = 0; i < allQuestions.length; i++) {
totalScore += allQuestions[i].getCalculatedScore();
if (currentModule.allQuestions[i].parent.questionCorrect) {
knowledgePoints++;
} else {
knowledgePoints--;
}
}
debugLog("Total score: " + totalScore);
debugLog(knowledgePoints);
return totalScore;
}
}*/
//}
This code above outputs two errors in flash console:
Error 1. Attribute used outside of class.
Error 2. 'Int' could not be loaded.
It's a weird (and actually non-AS3 way) way to do this. Instead of creating a unnamed closure which refers weird variables from who-knows where, you should make it a normal AS3 class, something like that (in a file named Quiz.as):
package
{
public class Quiz
{
public var knowledgePoints:int = 10;
public var allQuestions:Array = new Array;
public var questionCorrect:Boolean = false;
public function getTotalScore():int
{
var totalScore:int = 0;
// Your code does not explain how you will that Array.
// It is initially an empty Array of length 0.
for (var i = 0; i < allQuestions.length; i++)
{
totalScore += allQuestions[i].getCalculatedScore();
if (currentModule.allQuestions[i].parent.questionCorrect)
{
knowledgePoints++;
}
else
{
knowledgePoints--;
}
}
// Not sure what it is.
debugLog("Total score: " + totalScore);
debugLog(knowledgePoints);
return totalScore;
}
}
}

Resources