larry and jen do roman numerals in c++

Post on 25-Jun-2015

7.494 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Larry and Jen from the popular Deep C (and C++) slide-deck are back. This time they practice C++ by doing do the Roman Numeral conversion problem.

TRANSCRIPT

Larry and Jen do Roman Numerals

in C++

by Jon Jagger and Olve Maudal

http://www.slideshare.net/olvemaudal/deep-c

Larry and Jen first appeared in the popular Deep C (and C++) presentation

Jen, will you help me do some C++ practice?

Jen, will you help me do some C++ practice?

Sure Larry.

Given a positive integer number (eg 42) determineits Roman numeral representation as a String (eg "XLII").The Roman 'letters' are:

1 -> "I" | 10 -> "X" | 100 -> "C" | 1000 -> "M"2 -> "II" | 20 -> "XX" | 200 -> "CC" | 2000 -> "MM"3 -> "III" | 30 -> "XXX" | 300 -> "CCC" | 3000 -> "MMM"4 -> "IV" | 40 -> "XL" | 400 -> "CD" | 4000 -> "MMMM"5 -> "V" | 50 -> "L" | 500 -> "D"6 -> "VI" | 60 -> "LX" | 600 -> "DC" 7 -> "VII" | 70 -> "LXX" | 700 -> "DCC" 8 -> "VIII" | 80 -> "LXXX" | 800 -> "DCCC" 9 -> "IX" | 90 -> "XC" | 900 -> "CM"

You cannot write numerals like IM for 999.Wikipedia states "Modern Roman numerals are written byexpressing each digit separately starting with theleftmost digit and skipping any digit with a value of zero."

Examples:o) 1990 -> "MCMXC" (1000 -> "M" + 900 -> "CM" + 90 -> "XC")o) 2008 -> "MMVIII" (2000 -> "MM" + 8 -> "VIII")o) 99 -> "XCIX" ( 90 -> "XC" + 9 -> "IX")o) 47 -> "XLVII" ( 40 -> "XL" + 7 -> "VII")

How about the roman numerals kata?

Given a positive integer number (eg 42) determineits Roman numeral representation as a String (eg "XLII").The Roman 'letters' are:

1 -> "I" | 10 -> "X" | 100 -> "C" | 1000 -> "M"2 -> "II" | 20 -> "XX" | 200 -> "CC" | 2000 -> "MM"3 -> "III" | 30 -> "XXX" | 300 -> "CCC" | 3000 -> "MMM"4 -> "IV" | 40 -> "XL" | 400 -> "CD" | 4000 -> "MMMM"5 -> "V" | 50 -> "L" | 500 -> "D"6 -> "VI" | 60 -> "LX" | 600 -> "DC" 7 -> "VII" | 70 -> "LXX" | 700 -> "DCC" 8 -> "VIII" | 80 -> "LXXX" | 800 -> "DCCC" 9 -> "IX" | 90 -> "XC" | 900 -> "CM"

You cannot write numerals like IM for 999.Wikipedia states "Modern Roman numerals are written byexpressing each digit separately starting with theleftmost digit and skipping any digit with a value of zero."

Examples:o) 1990 -> "MCMXC" (1000 -> "M" + 900 -> "CM" + 90 -> "XC")o) 2008 -> "MMVIII" (2000 -> "MM" + 8 -> "VIII")o) 99 -> "XCIX" ( 90 -> "XC" + 9 -> "IX")o) 47 -> "XLVII" ( 40 -> "XL" + 7 -> "VII")

How about the roman numerals kata?

ok

#include "to_roman.hpp"#include <cassert>#include <iostream>

int main(){ std::cout << "All tests passed" << std::endl;}

to_roman.tests.cppI'll start with a test.1 should be I.

#include "to_roman.hpp"#include <cassert>#include <iostream>

int main(){ std::cout << "All tests passed" << std::endl;}

to_roman.tests.cppI'll start with a test.1 should be I.#include "to_roman.hpp"

#include <cassert>#include <iostream>

int main(){ std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

int main(){ std::cout << "All tests passed" << std::endl;}

to_roman.tests.cppI'll start with a test.1 should be I.#include "to_roman.hpp"

#include <cassert>#include <iostream>

int main(){ std::cout << "All tests passed" << std::endl;}

static void test_1_is_I(){ assert(to_roman(1) == "I");}

Here's my header file, to_roman.hpp

#ifndef TO_ROMAN_INCLUDED#define TO_ROMAN_INCLUDED

#include <string>

std::string to_roman(int number);

#endif

Here's my header file, to_roman.hpp

#ifndef TO_ROMAN_INCLUDED#define TO_ROMAN_INCLUDED

#include <string>

std::string to_roman(int number);

#endif

Here's my header file, to_roman.hpp

Here's my source file, to_roman.cpp

#ifndef TO_ROMAN_INCLUDED#define TO_ROMAN_INCLUDED

#include <string>

std::string to_roman(int number);

#endif

Here's my header file, to_roman.hpp

Here's my source file, to_roman.cpp

#include "to_roman.hpp"

std::string to_roman(int number){ return "";}

#ifndef TO_ROMAN_INCLUDED#define TO_ROMAN_INCLUDED

#include <string>

std::string to_roman(int number);

#endif

Here's my header file, to_roman.hpp

ok

Here's my source file, to_roman.cpp

#include "to_roman.hpp"

std::string to_roman(int number){ return "";}

How are you building and running?

How are you building and running?

With this.

How are you building and running?

$ cc *.cpp && ./a.out

With this.

How are you building and running?

$ cc *.cpp && ./a.out

With this.

Try it.

How are you building and running?

$ cc *.cpp && ./a.out

With this.

Try it.

$ cc *.cpp && ./a.outAll tests passed

How are you building and running?

$ cc *.cpp && ./a.out

With this.

Try it.

$ cc *.cpp && ./a.outAll tests passed

Eh? That's not right. It should have failed!

How are you building and running?

$ cc *.cpp && ./a.out

With this.

Try it.

$ cc *.cpp && ./a.outAll tests passed

Eh? That's not right. It should have failed!

Let's see the tests again.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

That's easy to fix.

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

That's easy to fix.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){

std::cout << "All tests passed" << std::endl;}

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

That's easy to fix.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){

std::cout << "All tests passed" << std::endl;}

test_1_is_I();

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

$ cc *.cpp && ./a.out

That's easy to fix.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){

std::cout << "All tests passed" << std::endl;}

test_1_is_I();

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

$ cc *.cpp && ./a.out$ cc *.cpp && ./a.outAssertion failed: (to_roman(1) == "I")

That's easy to fix.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){

std::cout << "All tests passed" << std::endl;}

test_1_is_I();

Of course. We're not calling the test! #include "to_roman.hpp"

#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ std::cout << "All tests passed" << std::endl;}

Hmmmm.

$ cc *.cpp && ./a.out$ cc *.cpp && ./a.outAssertion failed: (to_roman(1) == "I")

That's easy to fix.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){

std::cout << "All tests passed" << std::endl;}

test_1_is_I();

Now it fails.

I can simply change the the return value to

make it pass.

#include "to_roman.hpp"

std::string to_roman(int number){ return "";}

I can simply change the the return value to

make it pass.

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

I can simply change the the return value to

make it pass.

$ cc *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

I can simply change the the return value to

make it pass.

$ cc *.cpp && ./a.out$ cc *.cpp && ./a.out All tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

I can simply change the the return value to

make it pass.

$ cc *.cpp && ./a.out$ cc *.cpp && ./a.out All tests passed

ok

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

Let's write another test. 2 should be II

I think there is a problem we should fix first.

Let's write another test. 2 should be II

I think there is a problem we should fix first.

Let's write another test. 2 should be II

What problem?

I think there is a problem we should fix first.

Let's write another test. 2 should be II

What problem?

We've fixed the immediate issue by calling the function. But what happens the next

time we forget?

I think there is a problem we should fix first.

Let's write another test. 2 should be II

What problem?

We've fixed the immediate issue by calling the function. But what happens the next

time we forget?

What do you suggest?

Could the compiler detect when we have a function that is defined

but not used?

Could the compiler detect when we have a function that is defined

but not used?

A command line option?

Yes. It's one of the smells the compiler can detect with the

-Wall flag.

Could the compiler detect when we have a function that is defined

but not used?

A command line option?

Yes. It's one of the smells the compiler can detect with the

-Wall flag.

ok. Let me try that.

Could the compiler detect when we have a function that is defined

but not used?

A command line option?

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call #include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call #include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

and add the -Wall flag

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

$ cc *.cpp && ./a.out

and add the -Wall flag

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

$ cc *.cpp && ./a.out

and add the -Wall flag

$ cc *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

$ cc *.cpp && ./a.out

and add the -Wall flag

$ cc *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

-Wall

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

$ cc *.cpp && ./a.out

and add the -Wall flag

$ cc *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

-Wall$ cc -Wall *.cpp && ./a.outwarning: 'void test_1_is_I()' is defined but not usedAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll comment out the call

$ cc *.cpp && ./a.out

and add the -Wall flag

$ cc *.cpp && ./a.out

now I get the warning

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

-Wall$ cc -Wall *.cpp && ./a.outwarning: 'void test_1_is_I()' is defined but not usedAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

Turning the warning into an error would be even better.

We can do that with the -Werror flag

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

Turning the warning into an error would be even better.

We can do that with the -Werror flag

Agreed.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall *.cpp && ./a.out

Turning the warning into an error would be even better.

We can do that with the -Werror flag

Agreed.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall *.cpp && ./a.out

Turning the warning into an error would be even better.

We can do that with the -Werror flag

$ cc -Wall *.cpp && ./a.out

Agreed.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall *.cpp && ./a.out

Turning the warning into an error would be even better.

We can do that with the -Werror flag

$ cc -Wall *.cpp && ./a.out-Werror

Agreed.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall *.cpp && ./a.out

Turning the warning into an error would be even better.

We can do that with the -Werror flag

$ cc -Wall *.cpp && ./a.out-Werror$ cc -Wall -Werror *.cpp && ./a.outerror: 'void test_1_is_I()' is defined but not used

Agreed.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ //test_1_is_I(); std::cout << "All tests passed" << std::endl;}

I'll uncomment the comment so the test passes again.

Now we can write the next test.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ /test_1_is_I(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>

static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

It should fail because to_roman still always

returns "I"

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

$ cc -Wall -Werror *.cpp && ./a.out

It should fail because to_roman still always

returns "I"

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outvoid test_2_is_II(): Assertion `to_roman(2) == "II"' failed.

It should fail because to_roman still always

returns "I"

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); std::cout << "All tests passed" << std::endl;}

2 should be II

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outvoid test_2_is_II(): Assertion `to_roman(2) == "II"' failed.

Let's make it pass.

It should fail because to_roman still always

returns "I"

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I();

std::cout << "All tests passed" << std::endl;}

test_2_is_II();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

}

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

}

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outerror: control reaches end of non-void function

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outerror: control reaches end of non-void function

Eh?

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outerror: control reaches end of non-void function

Eh?

Ah! It's saying that if number doesn't equal one or two then there is no

return statement.

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outerror: control reaches end of non-void function

Eh?

Exactly.

Ah! It's saying that if number doesn't equal one or two then there is no

return statement.

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

#include "to_roman.hpp"

std::string to_roman(int number){ return "I";}

How about this?

Try it!

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outerror: control reaches end of non-void function

Eh?

Exactly.

That's easy to fix.

Ah! It's saying that if number doesn't equal one or two then there is no

return statement.

#include "to_roman.hpp"

std::string to_roman(int number){

return "I";}

if (number == 1)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";}

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I";

} if (number == 2)

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2)

} return "II";

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

}

How about this?#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

Now another test.

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

How about this?

Looks good.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

Now another test.

ok

#include "to_roman.hpp"

std::string to_roman(int number){ if (number == 1) return "I"; if (number == 2) return "II";}

#include "to_roman.hpp"

std::string to_roman(int number){

if (number == 1) return "I"; if (number == 2) return "II";}

std::string roman = "";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) if (number == 2) return "II";}

roman = "I";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2)

} roman = "II";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

} return roman;

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

$ cc -Wall -Werror *.cpp && ./a.out

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outvoid test_3_is_III(): Assertion `to_roman(3) == "III"' failed...Aborted

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outvoid test_3_is_III(): Assertion `to_roman(3) == "III"' failed...Aborted

Now I'll make it pass.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); std::cout << "All tests passed" << std::endl;}

I'll add a test for 3 being III. That should fail.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outvoid test_3_is_III(): Assertion `to_roman(3) == "III"' failed...Aborted

Now I'll make it pass.

ok

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II();

std::cout << "All tests passed" << std::endl;}

test_3_is_III();

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

Aha...

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

Aha...

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

Aha...

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

Aha...

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

Now another test.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; return roman;}

How about this?

Aha...

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yessss.

Now another test.

Hmmmm.....

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II";

return roman;}

if (number == 3) roman = "III";

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

Are you thinking we should refactor first?

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

Are you thinking we should refactor first?

Yes.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

Are you thinking we should refactor first?

Yes.

I'd start with the tests.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

What about the tests?

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

What about the tests?

The name of each test repeats its body. In this case the test name adds

nothing. How about collapsing them all into a

single test.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

What about the tests?

The name of each test repeats its body. In this case the test name adds

nothing. How about collapsing them all into a

single test.

Can you show me?

How about this.

...static void test_1_is_I(){ assert(to_roman(1) == "I");}

static void test_2_is_II(){ assert(to_roman(2) == "II");}

static void test_3_is_III(){ assert(to_roman(3) == "III");}

int main(){ test_1_is_I(); test_2_is_II(); test_3_is_III(); std::cout << "All tests passed" << std::endl;}

How about this.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

How about this.

$ cc -Wall -Werror *.cpp && ./a.out

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

How about this.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

How about this.

Everything still passes.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

Next I'd refactor the code.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

Next I'd refactor the code.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

Yeah. An endless sequence of if statements isn't going to

be much of a solution.

Next I'd refactor the code.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

Yeah. An endless sequence of if statements isn't going to

be much of a solution.

Can I show you something neat?

Next I'd refactor the code.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

Yeah. An endless sequence of if statements isn't going to

be much of a solution.

Can I show you something neat?

Sure

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

First I'll refactor the code so that each if statement concatenates a single I.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number == 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman = "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number == 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "II"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman = "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number == 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "III"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "II"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman = "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

I add braces to the if statements.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

I add braces to the if statements.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

I add braces to the if statements.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) roman += "I"; return roman;}

I add braces to the if statements.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

I add braces to the if statements.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

I add braces to the if statements.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) roman += "I"; if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) roman += "I"; if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) roman += "I"; return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 3) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } return roman;}

Now I make the three ifs exactly the same.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } return roman;}

Now I make the three ifs exactly the same.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } return roman;}

Now I make the three ifs exactly the same.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 2) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 3) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } if (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; if (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

Finally I can collapse the three identical if statements into a single while statement.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

Cool. The repeated if statements are just like an unrolled while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

Cool. The repeated if statements are just like an unrolled while statement.

Exactly.

Any more refactoring?

What do you think?

Any more refactoring?

What do you think?

Any more refactoring?

I can't see anything.

What do you think?

Any more refactoring?

I can't see anything.

ok. Let's move on.

What do you think?

Any more refactoring?

I can't see anything.

ok. Let's move on.

Let's add a test for 4 being IV

What do you think?

Any more refactoring?

I can't see anything.

ok. Let's move on.

Let's add a test for 4 being IV

I'd do 10 being X next.

What do you think?

Any more refactoring?

I can't see anything.

ok. Let's move on.

Let's add a test for 4 being IV

I'd do 10 being X next.

ok

I'll add the test for 10 being X

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");}

I'll add the test for 10 being X

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");

}

I'll add the test for 10 being X

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");

} assert(to_roman(10) == "X");

I'll add the test for 10 being X

$ cc -Wall -Werror *.cpp && ./a.out

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");

} assert(to_roman(10) == "X");

I'll add the test for 10 being X

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");

} assert(to_roman(10) == "X");

I'll add the test for 10 being X

It fails as expected.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III");

} assert(to_roman(10) == "X");

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } return roman;}

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; }

return roman;}

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; }

return roman;}

while (number >= 10) { roman += "X"; number -= 10; }

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; }

return roman;}

while (number >= 10) { roman += "X"; number -= 10; }

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; }

return roman;}

while (number >= 10) { roman += "X"; number -= 10; }

I can make it pass by repeating the same while statement but using 10 and X instead

of 1 and I.

Eh? It still fails.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; }

return roman;}

while (number >= 10) { roman += "X"; number -= 10; }

It would really help if the console output told us what to_roman is actually returning.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

It would really help if the console output told us what to_roman is actually returning.

Yes it would.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

It would really help if the console output told us what to_roman is actually returning.

Yes it would.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's rework the test to do that.

$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

It would really help if the console output told us what to_roman is actually returning.

Yes it would.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's rework the test to do that.

ok

$ cc -Wall -Werror *.cpp && ./a.outAssertion `to_roman(10) == "X"' failed.Aborted

Let's make a function called assert_to_roman.

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's make a function called assert_to_roman.

ok

...static void test_to_roman(){ assert(to_roman(1) == "I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's make a function called assert_to_roman.

ok

...static void test_to_roman(){ assert_to_roman(1,"I"); assert(to_roman(2) == "II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's make a function called assert_to_roman.

ok

...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert(to_roman(3) == "III"); assert(to_roman(10) == "X");}

Let's make a function called assert_to_roman.

ok

...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert(to_roman(10) == "X");}

Let's make a function called assert_to_roman.

ok

...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");}

Now we write assert_to_roman

static void assert_to_roman(int arabic, const std::string & expected){ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}...

Now we write assert_to_roman

static void assert_to_roman(int arabic, const std::string & expected){ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}...

Now we write assert_to_roman

$ cc -Wall -Werror *.cpp && ./a.out

static void assert_to_roman(int arabic, const std::string & expected){ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}...

Now we write assert_to_roman

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(10) == "X" actual: to_roman(10) == "IIIIIIIIII"Assertion `false' failed.Aborted

static void assert_to_roman(int arabic, const std::string & expected){ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}...

Now we write assert_to_roman

$ cc -Wall -Werror *.cpp && ./a.out

That's a much more helpful message.

$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(10) == "X" actual: to_roman(10) == "IIIIIIIIII"Assertion `false' failed.Aborted

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } while (number >= 10) { roman += "X"; number -= 10; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(10) == "X" actual: to_roman(10) == "IIIIIIIIII"Assertion `false' failed.Aborted

So why isn't to_roman working for X?

Ah of course. The while statements are the wrong way round.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 1) { roman += "I"; number--; } while (number >= 10) { roman += "X"; number -= 10; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(10) == "X" actual: to_roman(10) == "IIIIIIIIII"Assertion `false' failed.Aborted

So why isn't to_roman working for X?

That's easy to fix.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

return roman;}

while (number >= 1) { roman += "I"; number--; } while (number >= 10) { roman += "X"; number -= 10; }

That's easy to fix.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

return roman;}

while (number >= 1) { roman += "I"; number--; }

while (number >= 10) { roman += "X"; number -= 10; }

That's easy to fix.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

return roman;}

$ cc -Wall -Werror *.cpp && ./a.out

while (number >= 1) { roman += "I"; number--; }

while (number >= 10) { roman += "X"; number -= 10; }

That's easy to fix.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

return roman;}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

while (number >= 1) { roman += "I"; number--; }

while (number >= 10) { roman += "X"; number -= 10; }

That's easy to fix.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

return roman;}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Yes. We're green again.

while (number >= 1) { roman += "I"; number--; }

while (number >= 10) { roman += "X"; number -= 10; }

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");}

I think tests for 20 and 30 should pass straight away.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");}

I agree.

I think tests for 20 and 30 should pass straight away.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");

}

I agree.

I think tests for 20 and 30 should pass straight away.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");

}

assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

I agree.

I think tests for 20 and 30 should pass straight away.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");

}

assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

I agree.

I think tests for 20 and 30 should pass straight away.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman(1,"I"); assert_to_roman(2,"II"); assert_to_roman(3,"III"); assert_to_roman(10,"X");

}

assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

I agree.

I think tests for 20 and 30 should pass straight away.

I think 33 should pass already.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");}

I think 33 should pass already.

I do too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");}

I think 33 should pass already.

I do too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

}

I think 33 should pass already.

I do too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

} assert_to_roman(33,"XXXIII");

I think 33 should pass already.

$ cc -Wall -Werror *.cpp && ./a.out

I do too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

} assert_to_roman(33,"XXXIII");

I think 33 should pass already.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

I do too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX");

} assert_to_roman(33,"XXXIII");

What next?

What next?

How about 100 ?

What next?

How about 100 ?

That should be C

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");}

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

}

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

} assert_to_roman(100,"C");

This will fail with 10 X's

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

} assert_to_roman(100,"C");

This will fail with 10 X's

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

} assert_to_roman(100,"C");

This will fail with 10 X's

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(100) == "C" actual: to_roman(100) == "XXXXXXXXXX"....int main(): Assertion `false' failed.Aborted

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

} assert_to_roman(100,"C");

This will fail with 10 X's

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(100) == "C" actual: to_roman(100) == "XXXXXXXXXX"....int main(): Assertion `false' failed.Aborted

Excellent!

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1,"I"); assert_to_roman( 2,"II"); assert_to_roman( 3,"III"); assert_to_roman(10,"X"); assert_to_roman(20,"XX"); assert_to_roman(30,"XXX"); assert_to_roman(33,"XXXIII");

} assert_to_roman(100,"C");

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

To make it pass I just need to add another while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

To make it pass I just need to add another while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

To make it pass I just need to add another while statement.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

while (number >= 100) { roman += "C"; number -= 100; }

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

To make it pass I just need to add another while statement.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

while (number >= 100) { roman += "C"; number -= 100; }

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

To make it pass I just need to add another while statement.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = "";

while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

while (number >= 100) { roman += "C"; number -= 100; }

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

And now?

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

The three while statements are duplicating each other. So let's

refactor those.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

And now?

First I'll introduce a simple struct to

represent a roman digit.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

First I'll introduce a simple struct to

represent a roman digit.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

First I'll introduce a simple struct to

represent a roman digit.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

struct digit{ int arabic; std::string roman;};

$ cc -Wall -Werror *.cpp && ./a.out

First I'll introduce a simple struct to

represent a roman digit.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

struct digit{ int arabic; std::string roman;};

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

First I'll introduce a simple struct to

represent a roman digit.

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

#include "to_roman.hpp"

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

struct digit{ int arabic; std::string roman;};

Now I introduce 100 and "C" as a digit.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I introduce 100 and "C" as a digit.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I introduce 100 and "C" as a digit.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

const digit digits[] = { { 100, "C" },};

$ cc -Wall -Werror *.cpp && ./a.out

Now I introduce 100 and "C" as a digit.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

const digit digits[] = { { 100, "C" },};

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I introduce 100 and "C" as a digit.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

const digit digits[] = { { 100, "C" },};

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= 100) { roman += "C"; number -= 100; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= { roman += number -= } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= { roman += number -= } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[0].arabic)

digits[0].roman; digits[0].arabic;

$ cc -Wall -Werror *.cpp && ./a.out

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= { roman += number -= } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[0].arabic)

digits[0].roman; digits[0].arabic;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= { roman += number -= } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[0].arabic)

digits[0].roman; digits[0].arabic;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I use the first digit instead of 100

and "C".

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= { roman += number -= } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[0].arabic)

digits[0].roman; digits[0].arabic;

Nice.

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 10, "X" },

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 10, "X" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= { roman += number -= } while (number >= 1) { roman += "I"; number--; } return roman;}

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 10, "X" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= { roman += number -= } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[1].arabic)

digits[1].roman;digits[1].arabic;

$ cc -Wall -Werror *.cpp && ./a.out

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 10, "X" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= { roman += number -= } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[1].arabic)

digits[1].roman;digits[1].arabic;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I repeat for the next digit, 10

and "X".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= 10) { roman += "X"; number -= 10; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 10, "X" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= { roman += number -= } while (number >= 1) { roman += "I"; number--; } return roman;}

digits[1].arabic)

digits[1].roman;digits[1].arabic;

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, };

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 1, "I" },

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 1, "I" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= { roman += number } return roman;}

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 1, "I" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= { roman += number } return roman;}

digits[2].arabic)

-= digits[2].arabic;digits[2].roman;

$ cc -Wall -Werror *.cpp && ./a.out

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 1, "I" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= { roman += number } return roman;}

digits[2].arabic)

-= digits[2].arabic;digits[2].roman;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

I repeat again for the next

digit, 1 and "I".

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" },

};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= 1) { roman += "I"; number--; } return roman;}

{ 1, "I" },

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" },};

std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= { roman += number } return roman;}

digits[2].arabic)

-= digits[2].arabic;digits[2].roman;

Now I can replace each use of 0 with

an introduced variable.

...std::string to_roman(int number){ std::string roman = ""; while (number >= digits[0].arabic) { roman += digits[0].roman; number -= digits[0].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

Now I can replace each use of 0 with

an introduced variable.

...std::string to_roman(int number){ std::string roman = "";

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

Now I can replace each use of 0 with

an introduced variable.

...std::string to_roman(int number){ std::string roman = "";

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

std::size_t i = 0;i

ii

$ cc -Wall -Werror *.cpp && ./a.out

Now I can replace each use of 0 with

an introduced variable.

...std::string to_roman(int number){ std::string roman = "";

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

std::size_t i = 0;i

ii

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I can replace each use of 0 with

an introduced variable.

...std::string to_roman(int number){ std::string roman = "";

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

std::size_t i = 0;i

ii

And replace 1 with the introduced

variable....std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

And replace 1 with the introduced

variable....std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

And replace 1 with the introduced

variable....std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

i++i;

ii

$ cc -Wall -Werror *.cpp && ./a.out

And replace 1 with the introduced

variable....std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

i++i;

ii

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

And replace 1 with the introduced

variable....std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[1].arabic) { roman += digits[1].roman; number -= digits[1].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

i++i;

ii

And replace 2 with the introduced

variable.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

And replace 2 with the introduced

variable.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } return roman;}

And replace 2 with the introduced

variable.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } return roman;}

++i;i

ii

$ cc -Wall -Werror *.cpp && ./a.out

And replace 2 with the introduced

variable.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } return roman;}

++i;i

ii

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

And replace 2 with the introduced

variable.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } while (number >= digits[2].arabic) { roman += digits[2].roman; number -= digits[2].arabic; } return roman;}

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

while (number >= digits[ ].arabic) { roman += digits[ ].roman; number -= digits[ ].arabic; } return roman;}

++i;i

ii

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; std::size_t i = 0; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

for ( i != 3; ++i)

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } ++i; while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; }

return roman;}

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.out

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I can collapse the duplication into

a for statement.

...std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != 3; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

const std::size_t n = sizeof digits / sizeof digits[0];

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != ; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != ; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

n

$ cc -Wall -Werror *.cpp && ./a.out

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != ; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

n

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != ; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

n

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Now I can replace 3 with the size of the

array.

#include "to_roman.hpp"...const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != ; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

n

Excellent.

Done.#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Done.#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Anything else?

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

What do you see?

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

What do you see?

digits and n have internal linkage

because they are const, but the digit type has external

linkage.

How can I give a type internal

linkage?

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

How can I give a type internal

linkage?

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

With an anonymous namespace.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...

Can you Show me?

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...

Like this.

Can you Show me?

Like this.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...

Can you Show me?

Like this.

#include "to_roman.hpp"

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...

namespace {

Can you Show me?

Like this.

#include "to_roman.hpp"

namespace{ struct digit { int arabic; std::string roman; };

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...

Can you Show me?

Like this.

#include "to_roman.hpp"

namespace{ struct digit { int arabic; std::string roman; };

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...}

Can you Show me?

Like this.

#include "to_roman.hpp"

namespace{ struct digit { int arabic; std::string roman; };

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...}

$ cc -Wall -Werror *.cpp && ./a.out

Can you Show me?

Like this.

#include "to_roman.hpp"

namespace{ struct digit { int arabic; std::string roman; };

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

...}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Can you Show me?

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Anything else?

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Anything else?

roman += roman statement suggests renaming number

to arabic.

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Anything else?

roman += roman statement suggests renaming number

to arabic.

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int ){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while ( >= digits[i].arabic) { roman += digits[i].roman; -= digits[i].arabic; } return roman;}

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

Anything else?

roman += roman statement suggests renaming number

to arabic.

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int ){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while ( >= digits[i].arabic) { roman += digits[i].roman; -= digits[i].arabic; } return roman;}

arabic

arabic

arabic

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.out

Anything else?

roman += roman statement suggests renaming number

to arabic.

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int ){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while ( >= digits[i].arabic) { roman += digits[i].roman; -= digits[i].arabic; } return roman;}

arabic

arabic

arabic

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int number){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (number >= digits[i].arabic) { roman += digits[i].roman; number -= digits[i].arabic; } return roman;}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Anything else?

roman += roman statement suggests renaming number

to arabic.

#include "to_roman.hpp"

namespace{...}

std::string to_roman(int ){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while ( >= digits[i].arabic) { roman += digits[i].roman; -= digits[i].arabic; } return roman;}

arabic

arabic

arabic

Here's our tests. #include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

Here's our tests. #include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");

}

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");

}

assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");

}

assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");

}

assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");

Here's our tests.

333 too.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");}

I think 200 and 300 should pass.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C");

}

assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");Excellent.

We've got duplication in our tests. Let's refactor them.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

We've got duplication in our tests. Let's refactor them.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

I think it's questionable whether

the duplication in these tests is worth

refactoring.

We've got duplication in our tests. Let's refactor them.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

I think it's questionable whether

the duplication in these tests is worth

refactoring.

Let's try it and see if we think it's better.

I'll create an int string struct just like before...

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

I'll create an int string struct just like before...

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

#include "to_roman.hpp"#include <cassert>#include <iostream>...

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

I'll create an int string struct just like before...

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

#include "to_roman.hpp"#include <cassert>#include <iostream>...

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

struct test_data{ int arabic; std::string roman;};

Now I'll create an array of them. I'll just

do two to start.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

Now I'll create an array of them. I'll just

do two to start.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

Now I'll create an array of them. I'll just

do two to start.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

Now I'll use the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

Now I'll use the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

test_to_roman(); std::cout << "All tests passed" << std::endl;}

Now I'll use the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

test_to_roman(); std::cout << "All tests passed" << std::endl;}

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

Now I'll use the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

test_to_roman(); std::cout << "All tests passed" << std::endl;}

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

$ cc -Wall -Werror *.cpp && ./a.out

Now I'll use the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

test_to_roman(); std::cout << "All tests passed" << std::endl;}

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

const size_t n = sizeof tests / sizeof tests[0];

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

const size_t n = sizeof tests / sizeof tests[0];

n;

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

const size_t n = sizeof tests / sizeof tests[0];

n;

I'll get rid of the magic number 2.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){ for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};

int main(){

for (size_t i = 0; i != 2; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

const size_t n = sizeof tests / sizeof tests[0];

n;

I'll fill in the rest of the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};...

I'll fill in the rest of the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};...

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },

};...

I'll fill in the rest of the array.

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};...

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },

};...

{ 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

I'll fill in the rest of the array.

$ cc -Wall -Werror *.cpp && ./a.out

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};...

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },

};...

{ 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

I'll fill in the rest of the array.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },};...

#include "to_roman.hpp"#include <cassert>#include <iostream>...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" },

};...

{ 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

Now I can delete test_to_roman() and

its call.

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

static void test_to_roman(){ assert_to_roman( 1, "I"); ... assert_to_roman(333, "CCCXXXIII");}

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

Now I can delete test_to_roman() and

its call.

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

test_to_roman(); std::cout << "All tests passed" << std::endl;}

Now I can delete test_to_roman() and

its call.

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

Now I can delete test_to_roman() and

its call.

$ cc -Wall -Werror *.cpp && ./a.out

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

Now I can delete test_to_roman() and

its call.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

Now I can delete test_to_roman() and

its call.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

ok

Can you see anything else?

...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

Can you see anything else?

...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) assert_to_roman( tests[i].arabic, tests[i].roman);

std::cout << "All tests passed" << std::endl;}

Perhaps make assert_to_roman()

a method of test_data?

I agree. I'll change the call first.

...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i)

std::cout << "All tests passed" << std::endl;}

assert_to_roman( tests[i].arabic, tests[i].roman);

I agree. I'll change the call first.

...struct test_data{ int arabic; std::string roman;};

const test_data tests[] ={ { 1, "I" }, ... { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i)

std::cout << "All tests passed" << std::endl;}

tests[i].assert_equal();

Now I'll add a declaration.

...struct test_data{ int arabic; std::string roman;};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Now I'll add a declaration.

...struct test_data{ int arabic; std::string roman;

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Now I'll add a declaration.

...struct test_data{ int arabic; std::string roman;

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

void assert_equal() const;

Now I'll rework the definition.

...struct test_data{ int arabic; std::string roman; void assert_equal() const;};

{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

static void assert_to_roman(int arabic, const std::string & expected)

Now I'll rework the definition.

...struct test_data{ int arabic; std::string roman; void assert_equal() const;};

{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

Now I'll rework the definition.

...struct test_data{ int arabic; std::string roman; void assert_equal() const;};

{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

void test_data::assert_equal() const

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

roman;

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

expected;

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

expected;

$ cc -Wall -Werror *.cpp && ./a.out

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

expected;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

I need to rename

roman to expected.

...struct test_data{ int arabic; std::string void assert_equal() const;};

void test_data::assert_equal() const{ const std::string actual = to_roman(arabic); if (expected != actual) { std::cerr << "expected: to_roman" << '(' << arabic << ") == " << '"' << expected << '"' << std::endl; std::cerr << " actual: to_roman" << '(' << arabic << ") == " << '"' << actual << '"' << std::endl; assert(false); }}

expected;

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

ok

Anything else?

Anything else?

The name test_data is a bit weak.

Anything else?

The name test_data is a bit weak.

And it should not have external linkage.

Anything else?

The name test_data is a bit weak.

Agreed.

And it should not have external linkage.

Anything else?

The name test_data is a bit weak.

Agreed.

And it should not have external linkage.

But we can come back to that later.

Let's compare the tests before and after the

refactoring

Let's compare the tests before and after the

refactoring

Yeah! I forgot about that.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

Here's the tests before we

refactored them.

#include "to_roman.hpp"#include <cassert>#include <iostream>...static void test_to_roman(){ assert_to_roman( 1, "I"); assert_to_roman( 2, "II"); assert_to_roman( 3, "III"); assert_to_roman( 10, "X"); assert_to_roman( 20, "XX"); assert_to_roman( 30, "XXX"); assert_to_roman( 33, "XXXIII"); assert_to_roman(100, "C"); assert_to_roman(200, "CC"); assert_to_roman(300, "CCC"); assert_to_roman(333, "CCCXXXIII");}

int main(){ test_to_roman(); std::cout << "All tests passed" << std::endl;}

Its directness is quite elegant.

Here's the tests before we

refactored them.

...struct test_data{ int arabic; std::string expected; void assert_equal() const;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Here's the tests after we refactored

them.

It feels quite different. And

there's more lines of code! I'm not sure

which I prefer.

...struct test_data{ int arabic; std::string expected; void assert_equal() const;};

const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Here's the tests after we refactored

them.

What now?

What now?

How about adding a test for 5 being V.

What now?

How about adding a test for 5 being V.

ok

I just have to add one more entry to the

tests array.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

I just have to add one more entry to the

tests array.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

I just have to add one more entry to the

tests array.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 5, "V" },

I just have to add one more entry to the

tests array.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.out

I just have to add one more entry to the

tests array.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(5) == "V" actual: to_roman(5) == "IIIII"Assertion failed: (false), ...

I just have to add one more entry to the

tests array.

It fails as expected.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(5) == "V" actual: to_roman(5) == "IIIII"Assertion failed: (false), ...

Now to make it pass.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

Now to make it pass.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

I just need to say the digit

5 is V.

Now to make it pass.

I just need to say the digit

5 is V.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

Now to make it pass.

I just need to say the digit

5 is V.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

I just need to say the digit

5 is V.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

I just need to say the digit

5 is V.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

Excellent

I just need to say the digit

5 is V.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 5, "V" },

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

Numbers like 6 and 338 should now pass.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Numbers like 6 and 338 should now pass.

Agreed.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Numbers like 6 and 338 should now pass.

Agreed.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

Numbers like 6 and 338 should now pass.

Agreed.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 6, "VI" },

{ 338, "CCCXXXVIII" },

Numbers like 6 and 338 should now pass.

Agreed.

$ cc -Wall -Werror *.cpp && ./a.out

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 6, "VI" },

{ 338, "CCCXXXVIII" },

Numbers like 6 and 338 should now pass.

Agreed.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" },

{ 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" },

};

int main(){ const size_t n = sizeof tests / sizeof tests[0];

for (size_t i = 0; i != n; ++i) tests[i].assert_equal();

std::cout << "All tests passed" << std::endl;}

{ 6, "VI" },

{ 338, "CCCXXXVIII" },

Let's do 4 is IV now.

Let's do 4 is IV now.

ok

Let's do 4 is IV now.

ok

We already have 1 is I and 5 is V. Perhaps we could

somehow combine them to make IV.

Let's do 4 is IV now.

ok

We already have 1 is I and 5 is V. Perhaps we could

somehow combine them to make IV.

Hmmm...

Let's do 4 is IV now.

ok

We already have 1 is I and 5 is V. Perhaps we could

somehow combine them to make IV.

Hmmm...

I think it will get quite tricky.

Let's do 4 is IV now.

ok

We already have 1 is I and 5 is V. Perhaps we could

somehow combine them to make IV.

Hmmm...

I think it will get quite tricky.

Yes...

What are you thinking?

What are you thinking?

I'm thinking that when things get difficult it can be a sign that

you're doing it wrong.

What are you thinking?

I'm thinking that when things get difficult it can be a sign that

you're doing it wrong.

We could just add a new 4 is IV entry in the digits array! It

seems like a hack though.

What are you thinking?

I'm thinking that when things get difficult it can be a sign that

you're doing it wrong.

We could just add a new 4 is IV entry in the digits array! It

seems like a hack though.

I think that's a great idea. I don't think it's a hack at all! It's the simplest thing that works.

What are you thinking?

I'm thinking that when things get difficult it can be a sign that

you're doing it wrong.

We could just add a new 4 is IV entry in the digits array! It

seems like a hack though.

I think that's a great idea. I don't think it's a hack at all! It's the simplest thing that works.

ok!

Here's the 4 is IV test.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" }, { 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

Here's the 4 is IV test.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

Here's the 4 is IV test.

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

{ 4, "IV" },

Here's the 4 is IV test.

$ cc -Wall -Werror *.cpp && ./a.out

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

{ 4, "IV" },

Here's the 4 is IV test.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(4) == "IV" actual: to_roman(4) == "IIII"Assertion failed: (false), ...

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

{ 4, "IV" },

Here's the 4 is IV test.

$ cc -Wall -Werror *.cpp && ./a.out$ cc -Wall -Werror *.cpp && ./a.outexpected: to_roman(4) == "IV" actual: to_roman(4) == "IIII"Assertion failed: (false), ...

...const test_data tests[] ={ { 1, "I" }, { 2, "II" }, { 3, "III" },

{ 5, "V" }, { 6, "VI" }, { 10, "X" }, { 20, "XX" }, { 30, "XXX" }, { 33, "XXXIII" }, { 100, "C" }, { 200, "CC" }, { 300, "CCC" }, { 333, "CCCXXXIII" }, { 338, "CCCXXXVIII" },};

{ 4, "IV" },

It fails as expected.

Now to make it pass.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

Now to make it pass.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" }, { 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

I just need to say the digit

4 is IV.

Now to make it pass.

I just need to say the digit

4 is IV.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

Now to make it pass.

I just need to say the digit

4 is IV.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 4, "IV" },

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

I just need to say the digit

4 is IV.

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 4, "IV" },

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

I just need to say the digit

4 is IV.

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 4, "IV" },

$ cc -Wall -Werror *.cpp && ./a.out

Now to make it pass.

Excellent

I just need to say the digit

4 is IV.

$ cc -Wall -Werror *.cpp && ./a.outAll tests passed

...namespace{

struct digit{ int arabic; std::string roman;};

const digit digits[] = { { 100, "C" }, { 10, "X" }, { 5, "V" },

{ 1, "I" }, };

const std::size_t n = sizeof digits / sizeof digits[0];

}

std::string to_roman(int arabic){ std::string roman = ""; for (std::size_t i = 0; i != n; ++i) while (arabic >= digits[i].arabic) { roman += digits[i].roman; arabic -= digits[i].arabic; } return roman;}

{ 4, "IV" },

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

Agreed.

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

Agreed.

So we've done it. It's just more of the same now.

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

Agreed.

So we've done it. It's just more of the same now.

Yes. I'm sure there'll be a few more small refactorings though. And we've an external linkage

todo from earlier.

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

Agreed.

So we've done it. It's just more of the same now.

Yes. I'm sure there'll be a few more small refactorings though. And we've an external linkage

todo from earlier.

Thanks for your help.

We can repeat that idea for all the digits such as 9 being IX and 40 being XL.

Agreed.

So we've done it. It's just more of the same now.

Yes. I'm sure there'll be a few more small refactorings though. And we've an external linkage

todo from earlier.

Thanks for your help.

Any time.

top related