Handling null-safety Exceptions in Dart - dart

In this simple dart exercise, I was trying to handle the exception for the null safety in Dart.
However, I think the code below is not following DRY principles. Will be glad if anyone can correct me.
void Exercise1() {
/// declared these as global variables for availability to all blocks.
int? age;
String? name;
stdout.write('What is your name? ');
name = stdin.readLineSync();
/// This do-while block will validate: name is not empty or less than 3 char.
do {
stdout.write('What is your name? ');
name = stdin.readLineSync();
} while (name == null || name.isEmpty);
/// This de-while block will validate that age is entered and not -ve value.
do {
stdout.write('Hello $name, What is your age? ');
age = int.tryParse(stdin.readLineSync().toString());
} while (age == null || age.isNegative);
/// This expression computes the age left till 100 years.
int? yearsToHundred = 100 - age;
/// This prints out the results.
print(
'\nHey $name, your are $age year of age now. \nYou will be 100 years in another $yearsToHundred years time. \nEnjoy your life to the fullest, Cheers!');
}
What I want here is to validate and check if the number is null, the length is not zero, and only numbers are entered at the prompt. Otherwise, keep looping the input statement till valid input is provided.
void Exercise2() {
String? number;
do {
stdout.write('Enter a number: ');
number = stdin.readLineSync();
} while (number == null || number.length == 0);
int? num = int.parse(number.toString());
if (num.isEven) {
print('Even');
} else {
print('Odd');
}
}

Related

Calculating dart maths using conditional statements

I am trying to build a basic quiz app to improve my, so I was able to use if and else statement to know when they entered the right answer or not then I will print out their score, I was able to achieve this, so the main issue is that I want to add all the sores together and tell them the total they have scored. my code is below. thanks in advance.
import 'dart:io';
import 'dart:math';
void main() {
print("Hi, welcome to quize app");
print("what is your name?");
String? username = stdin.readLineSync();
print("welcome ${username}");
print("Who is Christiano ronaldo?");
List? answers1 = [26, 30, 37, 36];
List? answers2 = ['Musician', 'Footballer', 'Swimmer'];
List? answers3 = [3, 5, 7, 17];
List? answers4 = ['Yes', 'No'];
int? ans1 = 36;
String? ans2 = 'Footballer';
int? ans3 = 17;
String? ans4 = 'no';
int? num1 = (0 + 10);
int? num2 = (0 + 0);
int? num3 = (10 + 10 + 20);
print(answers1);
int? userans1 = int.parse(stdin.readLineSync()!);
print("Who the next president of Nigeria?");
print(answers2);
String? userans2 = stdin.readLineSync();
print(
"How many times did national Grid collaps in 2022 alone? please type in numbers:");
print(answers3);
int? userans3 = int.parse(stdin.readLineSync()!);
print('Is Nigerian air still functioning?');
print(answers4);
String? userans4 = stdin.readLineSync();
print('end of quize');
print('calculating answers...');
if (userans1 == ans1) {
String? cal = "$num1";
print("In question number one (1) you got $cal");
} else {
String? cal1 = "$num2";
print("In question number one (1) you got $cal1");
}
if (userans2 == ans2) {
String? cal = "$num1";
print("In question Number two (2) you got $cal");
} else {
String? cal1 = "$num2";
print("In question Number two (2) you got $cal1");
}
if (userans3 == ans3) {
String? cal = "$num1";
print("In question Number three (3) you got $cal");
} else {
String? cal1 = "$num2";
print("In question Number three (3) you got $cal1");
}
if (userans4 == ans4) {
String? cal = "$num1";
print("In question Number four (4) you got $cal");
} else {
String? cal1 = "$num2";
print("In question Number four (4) you got $cal1");
}
}
It is not just about Dart, it is a general programming logic question.
You can declare a variable of type int to hold the total score and start it with value of 0 like the following:
int totalScore = 0;
then every time the user answers a question correctly, just add the score of the question to the answer, for example:
if (userans1 == ans1) {
String? cal = "$num1";
print("In question number one (1) you got $cal");
totalScore += 10; // 10 is the score user received, replace it with the correct score.
}
Note: totalScore += 10 is equivalent to totalScore = totalScore + 10
At the end, you will have the Total Score in our variable, do whatever you want with it.
That's it!

The operator '[]=' isn't defined for the type 'String'

I'm getting an error in this code:
void main() {
List<String> wave(String str) {
List<String> results = [];
String newStr;
int i = 0;
for (String ltr in str.split('')) {
newStr = str;
if (ltr != ' ') {
newStr[i] = ltr.toUpperCase();
results.add(newStr);
}
i++;
}
return results;
}
print(wave(' gap '));
}
the error is at the line:
newStr[i] = ltr.toUpperCase;
Despite when I try print(newStr[i]); I don't get an error and the code is executed correctly!
In Dart String operation, operator[] returns a string. Which means, array[index] is used for getting the string in the index position. That is why you're getting that error, because you can't set at specific index using this operator[] in dart. See the documentation for details.
To replace at the specific index in dart, you can use replaceFirst(Pattern from, String to, [int startIndex = 0]) as the other answer mentioned. Or, you can use substring(int start, [int? end]) as follows:
if (ltr != ' ' && i < newStr.length) {
newStr = newStr.substring(0, i) + ltr.toUpperCase() + newStr.substring(i+1);
results.add(newStr);
}
To make the code bug free, I've added the checking of the value of i in it. You should add the checking to avoid out of bound access.
try to replace
newStr[i] = ltr.toUpperCase();
to
newStr = newStr.replaceFirst(ltr,ltr.toUpperCase(),i);
So the result will be [ Gap , gAp , gaP ]
Honestly, I don't know how char is defined in Dart, but I think accessing index of String is kind of getter, thus cannot be set to a new value.

Flutter/Dart: Split string by first occurrence

Is there a way to split a string by some symbol but only at first occurrence?
Example: date: '2019:04:01' should be split into date and '2019:04:01'
It could also look like this date:'2019:04:01' or this date : '2019:04:01' and should still be split into date and '2019:04:01'
string.split(':');
I tried using the split() method. But it doesn't have a limit attribute or something like that.
You were never going to be able to do all of that, including trimming whitespace, with the split command. You will have to do it yourself. Here's one way:
String s = "date : '2019:04:01'";
int idx = s.indexOf(":");
List parts = [s.substring(0,idx).trim(), s.substring(idx+1).trim()];
You can split the string, skip the first item of the list created and re-join them to a string.
In your case it would be something like:
var str = "date: '2019:04:01'";
var parts = str.split(':');
var prefix = parts[0].trim(); // prefix: "date"
var date = parts.sublist(1).join(':').trim(); // date: "'2019:04:01'"
The trim methods remove any unneccessary whitespaces around the first colon.
Just use the split method on the string. It accepts a delimiter/separator/pattern to split the text by. It returns a list of values separated by the provided delimiter/separator/pattern.
Usage:
const str = 'date: 2019:04:01';
final values = string.split(': '); // Notice the whitespace after colon
Output:
Inspired by python, I've wrote this utility function to support string split with an optionally maximum number of splits. Usage:
split("a=b=c", "="); // ["a", "b", "c"]
split("a=b=c", "=", max: 1); // ["a", "b=c"]
split("",""); // [""] (edge case where separator is empty)
split("a=", "="); // ["a", ""]
split("=", "="); // ["", ""]
split("date: '2019:04:01'", ":", max: 1) // ["date", " '2019:04:01'"] (as asked in question)
Define this function in your code:
List<String> split(String string, String separator, {int max = 0}) {
var result = List<String>();
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
string = string.substring(index + separator.length);
}
return result;
}
Online demo: https://dartpad.dev/e9a5a8a5ff803092c76a26d6721bfaf4
I found that very simple by removing the first item and "join" the rest of the List
String date = "date:'2019:04:01'";
List<String> dateParts = date.split(":");
List<String> wantedParts = [dateParts.removeAt(0),dateParts.join(":")];
Use RegExp
string.split(RegExp(r":\s*(?=')"));
Note the use of a raw string (a string prefixed with r)
\s* matches zero or more whitespace character
(?=') matches ' without including itself
You can use extensions and use this one for separating text for the RichText/TextSpan use cases:
extension StringExtension on String {
List<String> controlledSplit(
String separator, {
int max = 1,
bool includeSeparator = false,
}) {
String string = this;
List<String> result = [];
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
print(index);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
if (includeSeparator) {
result.add(separator);
}
string = string.substring(index + separator.length);
}
return result;
}
}
Then you can just reference this as a method for any string through that extension:
void main() {
String mainString = 'Here was john and john was here';
print(mainString.controlledSplit('john', max:1, includeSeparator:true));
}
Just convert list to string and search
productModel.tagsList.toString().contains(filterText.toLowerCase())

What is the best way to trim a trailing character in Dart?

In Dart the trim(), trimLeft() and trimRight() string methods do not take a parameter to specify unwanted non-whitespace characters.
What is the best way to trim a specific character from the ends of a string in Dart?
I am using this for now, but it feels hard to remember and not very generic:
final trailing = RegExp(r"/+$");
final trimmed = "test///".replaceAll(trailing, "");
assert(trimmed == "test");
There is no specific functionality to trim non-whitespace from the end of a string.
Your RegExp based approach is reasonable, but can be dangerous when the character you want to remove is meaningful in a RegExp.
I'd just make my own function:
String removeTrailing(String pattern, String from) {
if (pattern.isEmpty) return from;
var i = from.length;
while (from.startsWith(pattern, i - pattern.length)) i -= pattern.length;
return from.substring(0, i);
}
Then you can use it as:
final trimmed = removeTrailing("/", "test///")
assert(trimmed == "test");
The corresponding trimLeading function would be:
String trimLeading(String pattern, String from) {
if (pattern.isEmpty) return from;
var i = 0;
while (from.startsWith(pattern, i)) i += pattern.length;
return from.substring(i);
}
Since the existing answer by lrn has a lot of problems - including infinite loop scenarios - I thought I'd post my version.
String trimLeft(String from, String pattern){
if( (from??'').isEmpty || (pattern??'').isEmpty || pattern.length>from.length ) return from;
while( from.startsWith(pattern) ){
from = from.substring(pattern.length);
}
return from;
}
String trimRight(String from, String pattern){
if( (from??'').isEmpty || (pattern??'').isEmpty || pattern.length>from.length ) return from;
while( from.endsWith(pattern) ){
from = from.substring(0, from.length-pattern.length);
}
return from;
}
String trim(String from, String pattern){
return trimLeft(trimRight(from, pattern), pattern);
}
To trim all trailing/right characters by specified characters, use the method:
class StringUtil {
static String trimLastCharacters(String srcStr, String pattern) {
if (srcStr.length > 0) {
if (srcStr.endsWith(pattern)) {
final v = srcStr.substring(0, srcStr.length - 1 - pattern.length);
return trimLastCharacters(v, pattern);
}
return srcStr;
}
return srcStr;
}
}
For example, you want to remove all 0 behind the decimals
$23.67890000
then, invoke the method
StringUtil.trimLastCharacters("$23.67890000", "0")
finally, got the output:
$23.6789

Ordered sequential text matching

I want to match the strings and get a score in the following manner,
string 1: 4556677, string 2: 2556677, score: 0
string 1: 123345873009, string 2: 123345873112, score: 9
string 1: 22334567, string 2: 22334500, score: 6
So the score represents common first n digits, from left to right.
I have a list of 100K string 1 and 30M string 2, I would like to filter down all the pairs (string 1 and 2) with a score greater than 'x'.
Is there an algorithm available to do this task instead of brutal force sequential matching? I have tables stored in apache hive/hbase and would like to implement the approach either in spark or java mapreduce. Any help is much appreciated.
I conclude that your "score" represents the leftmost character position at which the strings differed.
Never mind "mapreduce," plain-Jane Java can do this very easily.
**
public int score( String string1, String string2 ) {
char sbuf1[] = string1.toCharArray();
char sbuf2[] = string2.toCharArray();
int complen = sbuf1.length;
if( sbuf2.length < complen ) {
complen = sbuf2.length;
}
for(
int i = 0; i < complen; i++ ) {
if( sbuf1[ i ] !=
sbuf2[ i ] ) {
return
i;
}
}
return -1; //
indicates no mismatch detected before one string exhausted
}
**

Resources