// use std::str::FromStr;
use rev_lines::RevLines;
use std::io::BufReader;
use std::fs::File;
fn main() {
// Haal de laatste regel uit invoer bestand
let log_file = File::open("/mnt/Data/Coins/Bittrex_invoer_rs.txt").unwrap();
let rev_lines = RevLines::new(BufReader::new(log_file)).unwrap();
let n_last_lines = 1; // We want to display the last line (5 = the last 5 lines)
let mut lines: Vec<String> = Vec::new();
let mut counter = 0;
for line in rev_lines {
if counter >= n_last_lines {
break;
}
counter = counter + 1;
lines.push(line);
// lines.push(String::from_str(&line));
}
for line in lines.iter().rev() {
println!("Row 23: {}", line);
/*
This prints: Row 23: [("USD",45.11545346),("USD-ETH",2.0),("USD-DGB",1000.0),("InlegEURO",220.42)]
*/
// let ar = line; //.to_string().iter();
// let ar = &line;
let ar = [("USD",45.11545346),("USD-ETH",2.0),("USD-DGB",1000.0),("InlegEURO",220.42)];
println!("Eerste tuple; eerste item {}", ar[0].0);
println!("Eerste tuple; tweede item {}", ar[0].1);
let mut bs = std::collections::BTreeMap::<&str, f64>::new();
for &(key, value) in ar.iter() {
bs.insert(key, value);
}
println!("BTreeMap:");
for (key, value) in bs.iter() {
print!(" {}: {},", key, value);
}
// println!("\n {:?}", hs);
println!();
println!("Alle keys:");
for key in bs.keys() {
print!(" {}", key);
}
println!();
println!("Sommige keys:");
println!(" USD: {:>15}", bs.get("USD").unwrap());
println!(" USD:(x2) {:>15}", bs.get("USD").unwrap()*2.);
println!(" USD-ETH: {:>15}", bs.get("USD-ETH").unwrap());
println!(" InlegEuro: {:>15}", bs.get("InlegEURO").unwrap());
}
}
The problem is that I can print the row from the txt-file, but I cannot use that for filling the BtreeMap. If I put the printed line in ar (literal) it works fine.
So my question is: How do I get a BTreemap from the read line?
For real Rustaceans this should be easy, but for me, a 69 year old dutch python hobbyist starting with rust, its rather difficult.
Thanks in advance for helping me out!
Please elaborate. In what specific way can't you do that? Are you getting a compile time error? Or does your code run but fails to produce the expected output? In either case, what exactly happens?
Yes I do. When I comment out the line ar = [("USD",45.11545346), etc and remove the slashes from the line before that I get the following:
Compiling coinrs v0.1.0 (/mnt/Data/RustProjects/coinrs)
error[E0277]: the type String
cannot be indexed by {integer}
--> src/main.rs:33:50
|
33 | println!("Eerste tuple; eerste item {}", ar[0].0);
| ^^^^^ String
cannot be indexed by {integer}
|
= help: the trait Index<{integer}>
is not implemented for String
error[E0277]: the type String
cannot be indexed by {integer}
--> src/main.rs:34:50
|
34 | println!("Eerste tuple; tweede item {}", ar[0].1);
| ^^^^^ String
cannot be indexed by {integer}
|
= help: the trait Index<{integer}>
is not implemented for String
error[E0599]: no method named iter
found for reference &&String
in the current scope
--> src/main.rs:37:33
|
37 | for &(key, value) in ar.iter() {
| ^^^^ method not found in &&String
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try rustc --explain E0277
.
error: could not compile coinrs
due to 3 previous errors
And I have tried a lot the last few days. Probably too much.
Well, a line is a String
. It's not an array, much less of an array of tuples, so you can't just treat it like that. Does the file have some structure? Are you trying to parse each line into a key-value pair? What is the expected contents of the map after you have read the file?
Iḿ just reading the last line of a simple txt-file (the same file I use for python). No special stucture. Indeed I'm trying to parse it into a key-value pair and be able to get the value by key with i.e. bs.get("USD").unwrap()) and do some calculations.
The result (in python is now):
20220223 22:30:58 Inleg Euro: 220.42
USD/EURO koers: 0.88454616 Inleg USD : 249.19
Naam Koers USD/BTC Aantal $$ €€
USD 1.00000 45.11545346 45.12 39.91
USD-DGB 0.01986 1000.00 19.86 17.57
USD-ETH 2633.43600 2.00000000 5266.87 4658.79
---------------------
Totalen 5331.85 4716.27
Winst/Verlies 2039.67 % 4495.85
--------------------------------------=====================
and that what I want to make in rust.
And then iterate over the splits? Can you give an example?
Yes. You seem to be trying to get the first and third fields, so you could just ask repeatedly for the next item of the iterator returned by split()
, like this.
Thanks a lot. I will try it tomorrow!
Sorry, but I don't have the solution yet. I have:
let lines = [
("USD",45.11545346),("USD-ETH",2.0),("USD-DGB",1000.0),("InlegEURO",220.42)
];
When I remove the "()" and the "fields.next()," and put the values into "" it works almost. I get the following:
thread 'main' panicked at 'called Option::unwrap()
on a None
value', src/main.rs:16:67
note: run with RUST_BACKTRACE=1
environment variable to display a backtrace.
Line 16 is: let (key, value) = (fields.next().unwrap(), fields.next().unwrap());
I thought it would just stop when there are no more key value pairs in the given string.
Sorry, I have no idea what you are talking about. My demonstrative code example linked above works. It tries to show you how to split up a line once you have some lines. Those lines are supposed to be strings, which your mock data isn't (that's the whole point).
If you have a runtime error to debug in your own code, please post actual code, not a diff described in words (and nothing to diff against).
Sorry, here it is
use std::collections::BTreeMap;
fn main() {
let lines = [
// "USD",45.11545346,"USD-ETH",2.0,"USD-DGB",1000.0,"InlegEURO",220.42
"USD","45.11545346","USD-ETH","2.0","USD-DGB","1000.0","InlegEURO","220.42"
];
// "USD 1.00000 45.11545346 45.12 39.91",
// "USD-DGB 0.01986 1000.00 19.86 17.57",
// "USD-ETH 2633.43600 2.00000000 5266.87 4658.79",
// ];
let mut map = BTreeMap::new();
for line in lines {
let mut fields = line.split(',');
let (key, value) = (fields.next().unwrap(), fields.next().unwrap());
let value = value.parse::<f64>().unwrap();
map.insert(key, value);
}
println!("{:#?}", map);
}
You are trying to split on a comma, but your individual lines don't contain commas.
The red line (just one line) is used! ```
"USD","45.11545346","USD-ETH","2.0","USD-DGB","1000.0","InlegEURO","220.42"
Commas all over!
The commas are not part of the strings. Did you want this?
let lines = [
"USD,45.11545346","USD-ETH,2.0","USD-DGB,1000.0","InlegEURO,220.42"
];
YES! Thanks again! I knew I had to learn a lot, and I am learning from you. Thanks again.
And now the next problem:
I have the red string (of strings) in a txt file. I'm trying to read it from that file and put it in the var 'lines' and use in for filling a BTreemap. And that's my problem now. Have been very busy reading, but no solution yet.
Here is my main.rs:
// use std::io::*;
// use std::str::FromStr;
use std::fs::File;
use rev_lines::RevLines;
use std::io::BufReader;
use std::collections::BTreeMap;
fn main() {
// Haal de laatste regel uit invoer bestand
let invoer = File::open("/mnt/Data/Coins/Bittrex_invoer_rs.txt").unwrap();
let rev_lines = RevLines::new(BufReader::new(invoer)).unwrap();
let n_last_lines = 1; // We want to display the last line (5 = the last 5 lines)
let mut lines: Vec<String> = Vec::new();
let mut counter = 0;
for line in rev_lines {
if counter >= n_last_lines {
break;
}
counter = counter + 1;
lines.push(line);
for line in lines.iter().rev() {
// line = line.split(" ");
println!("Row 23: {}", line);
// println!("Line split: {:?}", line.to_string().split(" "));
// let line = &line.split(",");
println!("\nEerste element in array lines : {:?}", lines[0]);
println!("Laatste element in array lines : {:?}", lines[lines.len()-1]);
// let mut fields = lines.split(',');
// println!("Fields: {:?}", fields);
}
}
let lines = [
"USD,45.11545346","USD-ETH,2.0","USD-DGB,1000.0","InlegEURO,220.42"
];
// See:https://www.educative.io/courses/learn-rust-from-scratch/N8JjPkwrK8v
println!("\nHardcoded array:");
println!("Eerste element in array lines : {:?}", lines[0]);
println!("Laatste element in array lines : {:?}", lines[lines.len()-1]);
let mut bm = BTreeMap::new();
for line in lines {
let mut fields = line.split(',');
let (key, value) = (fields.next().unwrap(), fields.next().unwrap());
let value = value.parse::<f64>().unwrap();
bm.insert(key, value);
}
println!("{:#?}", bm);
println!();
println!("Sommige keys:");
println!(" USD: {:>15}", bm.get("USD").unwrap());
println!(" USD:(x2) {:>15}", bm.get("USD").unwrap()*2.);
println!(" USD-DGB: {:>15}", bm.get("USD-DGB").unwrap());
println!(" InlegEuro: {:>15}", bm.get("InlegEURO").unwrap());
}
In cargo.toml:
[dependencies]
rev_lines = "0.2.1"
Thanks in advance for helping a newbie!
Bauke
Try doing this:
bm.insert(key.to_string(), value);
This is the output:
Row 23: "USD,45.11545346" "USD-ETH,2.0" "USD-DGB,1000.0" "InlegEURO,220.42"
Eerste element in array lines : "\"USD,45.11545346\" \"USD-ETH,2.0\" \"USD-DGB,1000.0\" \"InlegEURO,220.42\""
Laatste element in array lines : "\"USD,45.11545346\" \"USD-ETH,2.0\" \"USD-DGB,1000.0\" \"InlegEURO,220.42\""
Hardcoded array:
Eerste element in array lines : "USD,45.11545346"
Laatste element in array lines : "InlegEURO,220.42"
{
"InlegEURO": 220.42,
"USD": 45.11545346,
"USD-DGB": 1000.0,
"USD-ETH": 2.0,
}
Sommige keys:
USD: 45.11545346
USD:(x2) 90.23090692
USD-DGB: 1000
InlegEuro: 220.42
Row 23 is a print from the read line in the txt file. Then Iḿ trying to get the first an d last array elem. Doesn't work (get everything).
After that i use the hardcoded string and with that everything works as you can see in the output above.
Bauke
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.