Convert string to double in csv loader (flutter) - flutter

I have a csv dataset which contains numerical data.
eg:
76.21203492,30.86714946,0
76.23332579,30.86005251,1
76.14016701,30.85789648,2
I am reading this data using the following function:
loadAsset() async {
final myData = await rootBundle
.loadString("assets/data.csv");
List<List<dynamic>> csvTable = CsvToListConverter().convert(myData);
data = csvTable;
}
Now, I want to read the values.
Future<void> _onMapCreated(GoogleMapController controller) async {
await loadAsset();
setState(() {
_markers.clear();
int k = 0;
for (final loc in data) {
final marker = Marker(
markerId: MarkerId(loc[2]),
position: LatLng(double.parse(loc[0]), double.parse(loc[1])),
infoWindow: InfoWindow(
title: loc[2],
snippet: loc[2],
),
);
_markers[k.toString()] = marker;
k++;
}
});
But I am unable to do so.
It gives an error in line
LatLng(double.parse(loc[0]), double.parse(loc[1]))
quoting:
type 'double' is not a subtype of type 'String'
I also tried using the following function:
double convertion(String number) {
double value = 0;
int i = 0;
List<int> list = number.codeUnits.toList();
String zero = '0';
List<int> zeros = zero.codeUnits.toList();
while (number[i] != '.') {
value *= 10;
value += list[i].toDouble() - zeros[0].toDouble();
i++;
}
i++;
double decimal = 0;
int k = 0;
while (i < list.length) {
k++;
decimal *= 10;
decimal += list[i].toDouble() - zeros[0].toDouble();
i++;
}
decimal *= (pow(10, (k * (-1))));
value += decimal;
return value;
}
But I get the same error.

CsvToListConverter automatically parses all ints and doubles into the correct type, so double.parse(loc[0]) gives you an error because loc[0] is already a double, and you obviously can't parse a double from a double.
To fix this, change the line as follows:
From:
LatLng(double.parse(loc[0]), double.parse(loc[1]))
To:
LatLng(loc[0], loc[1])

Related

split the string into equal parts flutter

There is a string with random numbers and letters. I need to divide this string into 5 parts. And get List. How to do it? Thanks.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
Should work:
List<String> list = [
'05b37ffe',
'4973959c',
'4d4f2d5c',
'a0c14357',
'49f8cc66',
];
I know there'a already a working answer but I had already started this so here's a different solution.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
List<String> list = [];
final divisionIndex = str.length ~/ 5;
for (int i = 0; i < str.length; i++) {
if (i % divisionIndex == 0) {
final tempString = str.substring(i, i + divisionIndex);
list.add(tempString);
}
}
log(list.toString()); // [05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d=1
; try{
d = (str.length/5).toInt();
print(d);
}catch(e){
d=1;
}
List datas=[];
for(int i=0;i<d;i++){
var c=i+1;
try {
datas.add(str.substring(i * d, d*c));
} catch (e) {
print(e);
}
}
print(datas);
}
OR
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d = (str.length / 5).toInt();
var data = List.generate(d - 3, (i) => (d * (i + 1)) <= str.length ? str.substring(i * d, d * (i + 1)) : "");
print(data);//[05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
If you're into one liners, with dynamic parts.
Make sure to import dart:math for min function.
This is modular, i.e. you can pass whichever number of parts you want (default 5). If you string is 3 char long, and you want 5 parts, then it'll return 3 parts with 1 char in each.
List<String> splitIntoEqualParts(String str, [int parts = 5]) {
int _parts = min(str.length, parts);
int _sublength = (str.length / _parts).ceil();
return Iterable<int>
//Initialize empty list
.generate(_parts)
.toList()
// Apply the access logic
.map((index) => str.substring(_sublength * index, min(_sublength * index + _sublength, str.length)))
.toList();
}
You can then use it such as print(splitIntoEqualParts('05b37ffe4973959c4d4f2d5ca0c1435749f8cc66', 5));
splitWithCount(String string,int splitCount)
{
var array = [];
for(var i =0 ;i<=(string.length-splitCount);i+=splitCount)
{
var start = i;
var temp = string.substring(start,start+splitCount);
array.add(temp);
}
print(array);
}

ethereum solidity: from concatenated hexadecimal strings to uint64[]

I want my API to return an array of uint64 to my on-chain contract.
I tried 2 response formats for my API:
The array of uint64 itself (BN string here, but I need it in true uint64 not strings in my contract):
{"data":["629343835796877311","629343835797458943","629343835797471231"]}
concatenated hexadecimal strings (a new value every 16 chars):
{"data":"08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff"}
I discarded using the first approach because having ["629343835796877311","629343835797458943","629343835797471231"] as bytes is actually difficult to extract. I might be wrong! Maybe there is a base64 approach to encode and decode the data back into solidity data types, maybe?
I will use the second approach bellow.
Chainlink will pass the response as bytes memory _data:
function fulfill(bytes32 _requestId, bytes memory _data)
public
recordChainlinkFulfillment(_requestId)
{
data = string(_data);
}
Those bytes memory _data are successfully received and converted to a string (in storage data). The string value looks like this
08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff ...
In this example each 16 chars represent a uint64 number.
The first one: 08bbe0e25e412fff is 629343835796877311 for instance.
In solidity, I need to split the string each 16 chars and then convert it into their uint64 value.
I could use the bytes memory _data instead of the string(_data) if the code would be simpler or consume less gas. I am not sure
Please I need help with this I have been struggling.
Thanks
I got this contract working
COMMENTS:
the method hexBytesToInt is going to get a string representing hexa value like ffa0 for instance and return it's decimal value.
the method getSlice is just going to slice a string. In my case I have a new hexa value every 16 chars so I need to slice (0,16) than (16,32) etc...
the method hexStringToIntArray is managing the increments to slice every 16 chars and call the hexBytesToInt to transform the hex string in uint.
If you really want to dig into this solution, you are better off starting by understanding the test cases.
pragma solidity >=0.4.22 <0.8.11;
contract Serializer {
function hexStringToIntArray(string memory s) public pure returns (uint64[] memory) {
uint size = bytes(s).length / 16;
uint64[] memory result = new uint64[](size);
for (uint i = 0; i< size; i++) {
string memory strSlice = getSlice(i*16, (i+1)*16, s);
result[i] = hexStringToInt(strSlice);
}
return result;
}
function getSlice(uint startIndex, uint endIndex, string memory str) public pure returns (string memory) {
bytes memory strBytes = bytes(str);
bytes memory result = new bytes(endIndex-startIndex);
for(uint i = startIndex; i < endIndex; i++) {
result[i-startIndex] = strBytes[i];
}
return string(result);
}
function hexBytesToInt(bytes memory ss) public pure returns (uint64){
uint64 val = 0;
uint8 a = uint8(97); // a
uint8 zero = uint8(48); //0
uint8 nine = uint8(57); //9
uint8 A = uint8(65); //A
uint8 F = uint8(70); //F
uint8 f = uint8(102); //f
for (uint i=0; i<ss.length; ++i) {
uint8 byt = uint8(ss[i]);
if (byt >= zero && byt <= nine) byt = byt - zero;
else if (byt >= a && byt <= f) byt = byt - a + 10;
else if (byt >= A && byt <= F) byt = byt - A + 10;
val = (val << 4) | (byt & 0xF);
}
return val;
}
function hexStringToInt(string memory s) public pure returns (uint64) {
bytes memory ss = bytes(s);
uint64 val = hexBytesToInt(ss);
return val;
}
}
the tests:
const Serializer = artifacts.require("Serializer");
const truffleAssert = require("truffle-assertions");
const fs = require("fs");
const { readLines } = require("./utils.js");
const BN = web3.utils.BN;
contract("Serializer", (accounts) => {
const [deployerAddress, tokenHolderOneAddress, tokenHolderTwoAddress] = accounts;
it("hexStringToInt", async () => {
let s = await Serializer.deployed();
let result = await s.hexStringToInt.call("08bbe0e25e412fff");
let expected = new BN("629343835796877311");
assert.equal(result.toString(10), expected.toString(10));
result = await s.hexStringToInt.call("08bbe0e25e4a0fff");
expected = new BN("629343835797458943");
assert.equal(result.toString(10), expected.toString(10));
result = await s.hexStringToInt.call("08bbe0e25e4a3fff");
expected = new BN("629343835797471231");
assert.equal(result.toString(10), expected.toString(10));
});
it("getSlice1", async () => {
let s = await Serializer.deployed();
let result = await s.getSlice.call(0, 16, "08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff");
let expected = "08bbe0e25e412fff";
assert.equal(result, expected);
});
it("getSlice2", async () => {
let s = await Serializer.deployed();
const result = await s.getSlice.call(16, 32, "08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff");
const expected = "08bbe0e25e4a0fff";
assert.equal(result, expected);
});
it("getSlice3", async () => {
let s = await Serializer.deployed();
const result = await s.getSlice.call(32, 48, "08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff");
const expected = "08bbe0e25e4a3fff";
assert.equal(result, expected);
});
it("hexStringToIntArray", async () => {
let s = await Serializer.deployed();
let result = await s.hexStringToIntArray.call("08bbe0e25e412fff08bbe0e25e4a0fff08bbe0e25e4a3fff");
console.log(result);
let expected = [
new BN("629343835796877311").toString(),
new BN("629343835797458943").toString(),
new BN("629343835797471231").toString(),
];
const resultS = result.map((x) => x.toString());
assert.deepEqual(resultS, expected);
});
});

How to replace n occurrence of a substring in a string in dart?

I want to replace n occurrence of a substring in a string.
myString = "I have a mobile. I have a cat.";
How I can replace the second have of myString
hope this simple function helps. You can also extract the function contents if you don't wish a function. It's just two lines with some
Dart magic
void main() {
String myString = 'I have a mobile. I have a cat.';
String searchFor='have';
int replaceOn = 2;
String replaceText = 'newhave';
String result = customReplace(myString,searchFor,replaceOn,replaceText);
print(result);
}
String customReplace(String text,String searchText, int replaceOn, String replaceText){
Match result = searchText.allMatches(text).elementAt(replaceOn - 1);
return text.replaceRange(result.start,result.end,replaceText);
}
Something like that should work:
String replaceNthOccurrence(String input, int n, String from, String to) {
var index = -1;
while (--n >= 0) {
index = input.indexOf(from, ++index);
if (index == -1) {
break;
}
}
if (index != -1) {
var result = input.replaceFirst(from, to, index);
return result;
}
return input;
}
void main() {
var myString = "I have a mobile. I have a cat.";
var replacedString = replaceNthOccurrence(myString, 2, "have", "had");
print(replacedString); // prints "I have a mobile. I had a cat."
}
This would be a better solution to undertake as it check the fallbacks also. Let me list down all the scenarios:
If position is 0 then it will replace all occurrence.
If position is correct then it will replace at same location.
If position is wrong then it will send back input string.
If substring does not exist in input then it will send back input string.
void main() {
String input = "I have a mobile. I have a cat.";
print(replacenth(input, 'have', 'need', 1));
}
/// Computes the nth string replace.
String replacenth(String input, String substr, String replstr,int position) {
if(input.contains(substr))
{
var splittedStr = input.split(substr);
if(splittedStr.length == 0)
return input;
String finalStr = "";
for(int i = 0; i < splittedStr.length; i++)
{
finalStr += splittedStr[i];
if(i == (position - 1))
finalStr += replstr;
else if(i < (splittedStr.length - 1))
finalStr += substr;
}
return finalStr;
}
return input;
}
let's try with this
void main() {
var myString = "I have a mobile. I have a cat.I have a cat";
print(replaceInNthOccurrence(myString, "have", "test", 1));
}
String replaceInNthOccurrence(
String stringToChange, String searchingWord, String replacingWord, int n) {
if(n==1){
return stringToChange.replaceFirst(searchingWord, replacingWord);
}
final String separator = "#######";
String splittingString =
stringToChange.replaceAll(searchingWord, separator + searchingWord);
var splitArray = splittingString.split(separator);
print(splitArray);
String result = "";
for (int i = 0; i < splitArray.length; i++) {
if (i % n == 0) {
splitArray[i] = splitArray[i].replaceAll(searchingWord, replacingWord);
}
result += splitArray[i];
}
return result;
}
here the regex
void main() {
var myString = "I have a mobile. I have a cat. I have a cat. I have a cat.";
final newString =
myString.replaceAllMapped(new RegExp(r'^(.*?(have.*?){3})have'), (match) {
return '${match.group(1)}';
});
print(newString.replaceAll(" "," had "));
}
Demo link
Here it is one more variant which allows to replace any occurrence in subject string.
void main() {
const subject = 'I have a dog. I have a cat. I have a bird.';
final result = replaceStringByOccurrence(subject, 'have', '*have no*', 0);
print(result);
}
/// Looks for `occurrence` of `search` in `subject` and replace it with `replace`.
///
/// The occurrence index is started from 0.
String replaceStringByOccurrence(
String subject, String search, String replace, int occurence) {
if (occurence.isNegative) {
throw ArgumentError.value(occurence, 'occurrence', 'Cannot be negative');
}
final regex = RegExp(r'have');
final matches = regex.allMatches(subject);
if (occurence >= matches.length) {
throw IndexError(occurence, matches, 'occurrence',
'Cannot be more than count of matches');
}
int index = -1;
return subject.replaceAllMapped(regex, (match) {
index += 1;
return index == occurence ? replace : match.group(0)!;
});
}
Tested on dartpad.

In Flutter and if the number after decimal point is equal 0 convert the number to int

This is a function if the endValueFixed is equal for example 12.0 I want to print the number without zero so I want it to be 12.
void calculateIncrease() {
setState(() {
primerResult = (startingValue * percentage) / 100;
endValue = startingValue + primerResult;
endValueFixe`enter code here`d = roundDouble(endValue, 2);
});
}
This may be an overkill but it works exactly as you wish:
void main() {
// This is your double value
final end = 98.04;
String intPart = "";
String doublePart = "";
int j = 0;
for (int i = 0; i < end.toString().length; i++) {
if (end.toString()[i] != '.') {
intPart += end.toString()[i];
} else {
j = i + 1;
break;
}
}
for (int l = j; l < end.toString().length; l++) {
doublePart += end.toString()[l];
}
if (doublePart[0] == "0" && doublePart[1] != "0") {
print(end);
} else {
print(end.toString());
}
}
You may use this code as a function and send whatever value to end.
if (endValueFixed==12) {
print('${endValueFixed.toInt()}');
}
conditionally cast it to an int and print it then :)

Convert an arbitrarily long hexadecimal string to a number in Dart?

I need to convert a string of 8-character hexadecimal substrings into a list of integers.
For example, I might have the string
001479B70054DB6E001475B3
which consists of the following substrings
001479B7 // 1341879 decimal
0054DB6E // 5561198 decimal
001475B3 // 1340851 decimal
I'm currently using convert.hex to first convert the strings into a list of 4 integers (because convert.hex only handles parsing 2-character hex strings) and then adding/multiplying those up:
String tmp;
for(int i=0; i<=myHexString.length-8; i+=8){
tmp = myHexString.substring(i, i+8);
List<int> ints = hex.decode(tmp);
int dec = ints[3]+(ints[2]*256+(ints[1]*65536)+(ints[0]*16777216));
}
Is there a more efficient way to do this?
You can use int.parse('001479B7', radix: 16);
https://api.dartlang.org/stable/2.4.1/dart-core/int/parse.html
so your code will look like this :
void main() {
final fullString = '001479B70054DB6E001475B3';
for (int i = 0; i <= fullString.length - 8; i += 8) {
final hex = fullString.substring(i, i + 8);
final number = int.parse(hex, radix: 16);
print(number);
}
}
Since my Hex string came smaller than 8 elements of Byte, I did this.
String dumpHexToString(List<int> data) {
StringBuffer sb = StringBuffer();
data.forEach((f) {
sb.write(f.toRadixString(16).padLeft(2, '0'));
sb.write(" ");
});
return sb.toString();
}
String conertHexDecimal(String str1) {
final fullString = str1;
int number = 0;
for (int i = 0; i <= fullString.length - 8; i += 8) {
final hex = fullString.substring(i, i + 8);
number = int.parse(hex, radix: 16);
print(number);
}
return number.toString();
}
void executarConersao(Uint8List data){
String conersorHexDeVar = dumpHexToString(data);
conersorHexDeVar = conersorHexDeVar
.substring(3, conersorHexDeVar.length)
.replaceAll(' ', '')
.padLeft(8, '0');
conersorHexDeVar = conertHexDecimal(conersorHexDeVar);
print('data $conersorHexDeVar');
}
For anyone who wants to convert hexadecimal numbers to 2's component, Dart / Flutter has a builtin method - .toSigned(int):
var testConversion = 0xC1.toSigned(8);
print("This is the result: " + testConversion.toString()); // prints -63