[newb] Working through exercise on exercism.io and have a bug I don't understand

#1

The exercise is thus:

Bob is a lackadaisical teenager. In conversation, his responses are very limited.
Bob answers ‘Sure.’ if you ask him a question.
He answers ‘Whoa, chill out!’ if you yell at him.
He answers ‘Calm down, I know what I’m doing!’ if you yell a question at him.
He says ‘Fine. Be that way!’ if you address him without actually saying anything.
He answers ‘Whatever.’ to anything else.
Bob’s conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English.

These are the tests that are run:

use bob;

fn process_response_case(phrase: &str, expected_response: &str) {
    assert_eq!(bob::reply(phrase), expected_response);
}

#[test]
fn test_stating_something() {
    process_response_case("Tom-ay-to, tom-aaaah-to.", "Whatever.");
}

#[test]
#[ignore]
fn test_shouting() {
    process_response_case("WATCH OUT!", "Whoa, chill out!");
}

#[test]
#[ignore]
fn test_shouting_gibberish() {
    process_response_case("FCECDFCAAB", "Whoa, chill out!");
}

#[test]
#[ignore]
fn test_asking_a_question() {
    process_response_case("Does this cryogenic chamber make me look fat?", "Sure.");
}

#[test]
#[ignore]
fn test_asking_a_numeric_question() {
    process_response_case("You are, what, like 15?", "Sure.");
}

#[test]
#[ignore]
fn test_asking_gibberish() {
    process_response_case("fffbbcbeab?", "Sure.");
}

#[test]
#[ignore]
fn test_talking_forcefully() {
    process_response_case("Let's go make out behind the gym!", "Whatever.");
}

#[test]
#[ignore]
fn test_using_acronyms_in_regular_speech() {
    process_response_case("It's OK if you don't want to go to the DMV.", "Whatever.");
}

#[test]
#[ignore]
fn test_forceful_question() {
    process_response_case(
        "WHAT THE HELL WERE YOU THINKING?",
        "Calm down, I know what I'm doing!",
    );
}

#[test]
#[ignore]
fn test_shouting_numbers() {
    process_response_case("1, 2, 3 GO!", "Whoa, chill out!");
}

#[test]
#[ignore]
fn test_no_letters() {
    process_response_case("1, 2, 3", "Whatever.");
}

#[test]
#[ignore]
fn test_question_with_no_letters() {
    process_response_case("4?", "Sure.");
}

#[test]
#[ignore]
fn test_shouting_with_special_characters() {
    process_response_case(
        "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
        "Whoa, chill out!",
    );
}

#[test]
#[ignore]
fn test_shouting_with_no_exclamation_mark() {
    process_response_case("I HATE THE DMV", "Whoa, chill out!");
}

#[test]
#[ignore]
fn test_statement_containing_question_mark() {
    process_response_case("Ending with ? means a question.", "Whatever.");
}

#[test]
#[ignore]
fn test_nonletters_with_question() {
    process_response_case(":) ?", "Sure.");
}

#[test]
#[ignore]
fn test_prattling_on() {
    process_response_case("Wait! Hang on. Are you going to be OK?", "Sure.");
}

#[test]
#[ignore]
fn test_silence() {
    process_response_case("", "Fine. Be that way!");
}

#[test]
#[ignore]
fn test_prolonged_silence() {
    process_response_case("          ", "Fine. Be that way!");
}

#[test]
#[ignore]
fn test_alternate_silence() {
    process_response_case("\t\t\t\t\t\t\t\t\t\t", "Fine. Be that way!");
}

#[test]
#[ignore]
fn test_multiple_line_question() {
    process_response_case(
        "\nDoes this cryogenic chamber make me look fat?\nNo.",
        "Whatever.",
    );
}

#[test]
#[ignore]
fn test_starting_with_whitespace() {
    process_response_case("         hmmmmmmm...", "Whatever.");
}

#[test]
#[ignore]
fn test_ending_with_whitespace() {
    process_response_case("Okay if like my  spacebar  quite a bit?   ", "Sure.");
}

#[test]
#[ignore]
fn test_other_whitespace() {
    process_response_case("\n\r \t", "Fine. Be that way!");
}

#[test]
#[ignore]
fn test_nonquestion_ending_with_whitespace() {
    process_response_case(
        "This is a statement ending with whitespace      ",
        "Whatever.",
    );
}

I’ve written this code and put it in src/bob/lib.rs

extern crate regex;
use regex::RegexSet;

pub fn reply(message: &str) -> &str {
    let replies = ["Whoa, chill out!", //yell\
                   "Calm down, I know what I'm doing!", //yell a question
                   "Sure", //question                   
                   "Fine. Be that way!", //address him without actually saying anything
                   "Whatever"]; //anything else

    let rgx = RegexSet::new(&[r"[A-Z,-]*!", //yell
                              r"[A-Z,-]*\?", //yell a question
                              r"[A-Za-z,-]*\?", //question               
                              r"[\t\s]*|[A-Za-z,-]*\.*",     //without actually saying anything
                              r".*"          //anything else
                            ]).unwrap(); 

    let matches: Vec<_> = rgx.matches(message).into_iter().collect();    
    let mtch = matches[0];       

    println!("{}", replies[mtch]);

    replies[mtch]
}

(I know it doesn’t work exactly just yet but that’s not the problem.) The problem is that what is returned from the function isn’t correct. If I print out mtch or replies[mtch] in this function, it will indicate a reply different from what’s being returned. I put the code into Rust playground just to see what would happen and it returned what I expected it would return. Any ideas?

0 Likes

#2

A regex like [A-Z,-]*! will match a ! anywhere in the input, preceded by zero or more capital letters, commas, and dashes. In other words, it will match any string containing a !.

If you want to match strings that consist entirely of capital letters followed by an exclamation point, use a regex that matches from the beginning of the input to the end, such as "^[A-Z,-]*!$".

By the way, your playground link is broken. Use the “share” button and then copy the permalink in order to share a playground.

1 Like

#3

Just a side note, I think that using regex for this problem is not really optimal for learning the specificities of Rust. This exercise is a blast for learning iterators and their methods (filter, map, etc). Also, it’s a good exercise to use the match keyword.

1 Like

#4

So, I’m less interested in what I should or shouldn’t be doing to solve the problem. I’m mostly experimenting with various things in Rust at the moment. What I’m concerned about is why these two things I’ve highlighted here are different when they shouldn’t be.
Screenshot_1

0 Likes

#5

The test code contains this assertion:

assert_eq!(bob::reply(phrase), expected_response);

The return value from your code is on the left side, and the expected response is on the right.

The output that you pasted shows that "Fine. Be that way!" is the value printed and returned by your function, while "Whatever." is the expected result. This comes from test_stating_something, the first of the test functions:

#[test]
fn test_stating_something() {
    process_response_case("Tom-ay-to, tom-aaaah-to.", "Whatever.");
}

Here’s a playground link for easier experimentation.

0 Likes

#6

Ugh, life would be better if I weren’t stupid.

0 Likes