#Calculator!!!

76 messages · Page 1 of 1 (latest)

wild cosmos
vernal zodiac
#

well to get some easy stuff out of the way, have you ran cargo fmt and cargo clippy?

#

these two are the formatter and linter respectively

wild cosmos
#

I already ran cargo clippy before asking

#

but is changing vec.get(0) to vec.first() important?

vernal zodiac
#

it's more idiomatic, but in this situation doesnt really matter

#

anyways

#
    let val1 = vec.get(0).unwrap().parse::<f64>();
    let val2 = vec.get(2).unwrap().parse::<f64>();

these should be just

    let val1 = vec[0].parse::<f64>();
    let val2 = vec[2].parse::<f64>();
#

since these are functionally equivalent

wild cosmos
#

oh
ok ill change that

vernal zodiac
#

then

#
    if val1.is_err() || val2.is_err() {

        return Err(NotAnOperationError::InvalidValue)

    }

    let val1 = val1.unwrap();
    let val2 = val2.unwrap();

this would be unidiomatic. i would do

let Some((val1, val2)) = val1.ok().zip(val2.ok()) else {
    return Err(NotAnOperationError::InvalidValue);
} 

or other variations

#

up to you whether to use match or what

#

match *vec.get(1).unwrap() { could be using the index syntax, as i stated above

wild cosmos
#

mhm

vernal zodiac
#
    let input_iter = user_input.split_whitespace();

    let mut input_vec: Vec<&str> = Vec::new();

    for str in input_iter {

        input_vec.push(str);

    }

a lot of these parts are unnecessary. you can just do

let input_vec: Vec<&str> = user_input.split_whitespace().collect();
#

for those if statements at the end i would use the "early returns" idiom

#

why are you using thread::park

wild cosmos
#

so
I just called park();
to prevent that

vernal zodiac
#

you have not implemented Error on the struct, yes

wild cosmos
#

oh wait

#

lol

#

brb

wild cosmos
vernal zodiac
#

you have to implement Display and Debug, then impl Error

wild cosmos
#

this works

#

is it the correct way to do that?

vernal zodiac
#

Display is not really correct

#

you should, you know, actually display something. have you read the docs on Display

wild cosmos
#

I replaced the Err(fmtError);

#

with

#

write!(f, "Provide a valid input.");

#

ignore the ; s

#

but it doesnt display it

vernal zodiac
#

not that really helpful of an error message, but sure

#

usually you'd match on the enum and display the appropriate message

wild cosmos
#

well, it doesnt even display that rn

#

it returns this

vernal zodiac
#

how are you displaying that

#

thru the :? fmt

#

?

wild cosmos
#

uh
im probably doing something wrong

#
use std::thread::park;
use std::io;
use std::error::Error;
use std::fmt::{Display, Error as fmtError, Formatter};

#[derive(Debug)]
enum NotAnOperationError {
    InvalidSign,
    InvalidValue,
}

impl Display for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        write!(f, "Provide a valid input.")
    }
}

impl Error for NotAnOperationError {}

fn eval_calc(vec: Vec<&str>) -> Result<f64, NotAnOperationError> {
    let val1 = vec[0].parse::<f64>();
    let val2 = vec[2].parse::<f64>();

    let Some((val1, val2)) = val1.ok().zip(val2.ok())
        else {
        return Err(NotAnOperationError::InvalidValue);
    };

    match vec[1] {
        "+" => Ok(val1 + val2),
        "-" => Ok(val1 - val2),
        "*" => Ok(val1 * val2),
        "/" => Ok(val1 / val2),
        "log" => Ok(val2.log(val1)),
        "^" => Ok(val1.powf(val2)),
        &_ => Err(NotAnOperationError::InvalidSign),
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    println!(
        "Supported operations:
    value + value
    value - value
    value * value
    value / value
    base log exponent
    base ^ power"
    );

    let mut user_input = String::new();
    io::stdin().read_line(&mut user_input)?;

    let input_vec: Vec<&str> = user_input.split_whitespace().collect();

    if input_vec.len() == 3 {
        println!("{}", eval_calc(input_vec)?);
    } else {
        println!("Provide a valid input.");
    }

    park();
    Ok(())
}
#

couldnt I just use unwrap_or_else

vernal zodiac
#

park is useless since you arent looping anything here btw

#

and its better to actually not do that and just run the program in the terminal anyway

#

also why have those error enum at all? if you don't use its enumness properly

wild cosmos
#

I will but I want to get it working first

wild cosmos
#

I am like
really new

#

to rust

#

:)

vernal zodiac
#

in Display, you aren't really differentiating InvalidSign from InvalidValue. you just print out "Provide a valid input." and call it a day

vernal zodiac
wild cosmos
wild cosmos
#

I did read the enums part

#

but rn it isnt even printing the "provide a valid input"

#

it just prints the error enum

wild cosmos
#
use std::error::Error;
use std::fmt::{Display, Error as fmtError, Formatter};
use std::io;
use std::thread::park;

#[derive(Debug)]
enum NotAnOperationError {
    InvalidSign,
    InvalidValue,
}

impl Display for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        match self {
            NotAnOperationError::InvalidSign => write!(f, "Couldn't recognize the operation."),
            NotAnOperationError::InvalidValue => write!(f, "Couldn't parse the input to f64."),
        }
    }
}

impl Error for NotAnOperationError {}

fn eval_calc(vec: Vec<&str>) -> Result<f64, NotAnOperationError> {
    let val1 = vec[0].parse::<f64>();
    let val2 = vec[2].parse::<f64>();

    let Some((val1, val2)) = val1.ok().zip(val2.ok())
        else {
        return Err(NotAnOperationError::InvalidValue);
    };

    match vec[1] {
        "+" => Ok(val1 + val2),
        "-" => Ok(val1 - val2),
        "*" => Ok(val1 * val2),
        "/" => Ok(val1 / val2),
        "log" => Ok(val2.log(val1)),
        "^" => Ok(val1.powf(val2)),
        &_ => Err(NotAnOperationError::InvalidSign),
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    println!(
        "Supported operations:
    value + value
    value - value
    value * value
    value / value
    base log exponent
    base ^ power"
    );

    let mut user_input = String::new();
    io::stdin().read_line(&mut user_input)?;

    let input_vec: Vec<&str> = user_input.split_whitespace().collect();

    if input_vec.len() == 3 {
        println!("{}", eval_calc(input_vec)?);
    } else {
        println!("Provide a valid input.");
    }

    park();
    Ok(())
}
#

I dont know why but it doesnt display the messages in the display impl

#

maybe I could try implementing Debug instead of just deriving it?

#

yeah

#

it works now

#
use std::error::Error;
use std::fmt::{Debug, Display, Error as fmtError, Formatter};
use std::io;
use std::thread::park;

enum NotAnOperationError {
    InvalidSign,
    InvalidValue,
}

impl Debug for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        match self {
            NotAnOperationError::InvalidSign => write!(f, "Couldn't recognize the operation."),
            NotAnOperationError::InvalidValue => write!(f, "Couldn't parse the input to f64."),
        }
    }
}

impl Display for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        match self {
            NotAnOperationError::InvalidSign => write!(f, "Couldn't recognize the operation."),
            NotAnOperationError::InvalidValue => write!(f, "Couldn't parse the input to f64."),
        }
    }
}

impl Error for NotAnOperationError {}

fn eval_calc(vec: Vec<&str>) -> Result<f64, NotAnOperationError> {
    let val1 = vec[0].parse::<f64>();
    let val2 = vec[2].parse::<f64>();

    let Some((val1, val2)) = val1.ok().zip(val2.ok())
        else {
        return Err(NotAnOperationError::InvalidValue);
    };

    match vec[1] {
        "+" => Ok(val1 + val2),
        "-" => Ok(val1 - val2),
        "*" => Ok(val1 * val2),
        "/" => Ok(val1 / val2),
        "log" => Ok(val2.log(val1)),
        "^" => Ok(val1.powf(val2)),
        &_ => Err(NotAnOperationError::InvalidSign),
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    println!(
        "Supported operations:
    value + value
    value - value
    value * value
    value / value
    base log exponent
    base ^ power"
    );

    let mut user_input = String::new();
    io::stdin().read_line(&mut user_input)?;

    let input_vec: Vec<&str> = user_input.split_whitespace().collect();

    if input_vec.len() == 3 {
        println!("{}", eval_calc(input_vec)?);
    } else {
        println!("Provide a valid input.");
    }

    park();
    Ok(())
}
#

oh

#

I forgot the park();

#
use std::error::Error;
use std::fmt::{Debug, Display, Error as fmtError, Formatter};
use std::io;

enum NotAnOperationError {
    InvalidSign,
    InvalidValue,
}

impl Debug for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        match self {
            NotAnOperationError::InvalidSign => write!(f, "Couldn't recognize the operation."),
            NotAnOperationError::InvalidValue => write!(f, "Couldn't parse the input to f64."),
        }
    }
}

impl Display for NotAnOperationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmtError> {
        match self {
            NotAnOperationError::InvalidSign => write!(f, "Couldn't recognize the operation."),
            NotAnOperationError::InvalidValue => write!(f, "Couldn't parse the input to f64."),
        }
    }
}

impl Error for NotAnOperationError {}

fn eval_calc(vec: Vec<&str>) -> Result<f64, NotAnOperationError> {
    let val1 = vec[0].parse::<f64>();
    let val2 = vec[2].parse::<f64>();

    let Some((val1, val2)) = val1.ok().zip(val2.ok())
        else {
        return Err(NotAnOperationError::InvalidValue);
    };

    match vec[1] {
        "+" => Ok(val1 + val2),
        "-" => Ok(val1 - val2),
        "*" => Ok(val1 * val2),
        "/" => Ok(val1 / val2),
        "log" => Ok(val2.log(val1)),
        "^" => Ok(val1.powf(val2)),
        &_ => Err(NotAnOperationError::InvalidSign),
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    println!(
        "Supported operations:
    value + value
    value - value
    value * value
    value / value
    base log exponent
    base ^ power"
    );

    let mut user_input = String::new();
    io::stdin().read_line(&mut user_input)?;

    let input_vec: Vec<&str> = user_input.split_whitespace().collect();

    if input_vec.len() == 3 {
        println!("{}", eval_calc(input_vec)?);
    } else {
        println!("Provide a valid input.");
    }

    Ok(())
}
#

does this look fine? @vernal zodiac

vernal zodiac
#

looks good to me