6
\$\begingroup\$

I made a program that converts between Celsius and Fahrenheit. Is there any way that I could make this code more efficient and cleaner?

use std::io;

// C to F: F = C*(9/5) + 32
// F to C: C = (F-32)*(5/9)

/**********Converts between Fahrenheit and Celsius*********/

fn main() -> () {
    println!("Do you want to convert to Celsius or Fahrenheit? Input C or F");
    let mut convert_type = String::new();

    io::stdin().read_line(&mut convert_type)
        .expect("Failed to conversion type.");

    let t = String::from(convert_type);

    println!("You want to convert to: {}", t);
    println!("What temperature would you like to convert?");
    let mut temp = String::new();

    io::stdin().read_line(&mut temp)
        .expect("Failed to read temperature.");

    let temp: i32 = match temp.trim().parse() {
        Ok(temp) => temp,
        Err(_e) => {
            -1
        }
    };

    match t.as_str() {
        "C\n" => println!("{}", ftoc(temp)),
        "F\n" => println!("{}", ctof(temp)),
        _ => println!("t = {:?}", t),
}
}

// Celsius to Fahrenheit
fn ctof(c: i32) -> i32 {
    (c * (9 / 5)) + 32

}

//Fahrenheit to Celsius
fn ftoc(f: i32) -> i32 {
    (f-32) * (5 / 9)
}

Output:

    cargo run
   Compiling ftoc v0.1.0 (/Users/roberthayek/rustprojects/ftoc)
    Finished dev [unoptimized + debuginfo] target(s) in 2.64s
     Running `target/debug/ftoc`
Do you want to convert to Celsius or Fahrenheit? Input C or F
F
You want to convert to: F

What temperature would you like to convert?
0
32
\$\endgroup\$
  • 3
    \$\begingroup\$ Please use rustfmt the next time before pasting your code here so it fulfills the rust style guidelines which helps us reading your code. \$\endgroup\$ – hellow Nov 12 '18 at 15:53
10
\$\begingroup\$

The first thing I always do is running clippy.

You will catch some things that are not neccessary, e.g.

  • fn main() -> () can be reduced to fn main()
  • let t = String::from(convert_type); is simply let t = convert_type

The bad things are

  • c * (9 / 5) which is always c because of integer arithmetic. You probably want f64::from(c) * (9.0 / 5.0)
  • same for (f - 32) * (5 / 9) should be (f64::from(f) - 32.0) * (5.0 / 9.0)) as i32

You may want to add some unit-tests to your program to verify that ctof and ftoc actually work.

\$\endgroup\$
5
\$\begingroup\$

Hellow got most of the good parts, but, I'd also recommend figuring out how you might want to signal the user so that an invalid input isn't accepted, since -1 is a temperature someone might want to convert.

In this case I would do something like replacing

let temp: i32 = match temp.trim().parse() {
    Ok(temp) => temp,
    Err(_e) => {
        -1
    }
};

with

let temp= match temp.trim().parse() {
    Err(_e) =>{
        panic!("That wasn't valid input! Temperatures can only be integers!");
    }
    Ok(i)=>i
};

If I knew this program were to be used solely interactively, then I'd consider adding a loop to give the user another attempt should their input fail.

\$\endgroup\$
  • \$\begingroup\$ Also, if you aren't planning on using the destructured error, you might as well just use just a _ for it. \$\endgroup\$ – Arnav Borborah Nov 26 '18 at 11:37
  • 1
    \$\begingroup\$ You can write it: let temp = temp.trim().parse().expect("Your message"); \$\endgroup\$ – French Boiethios Jan 7 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.