Skip to main content
ALPHA    This is new software undergoing tests! Thank you for your patience.

Candidate: Khadija Khadija Assessed by: Nicholas Tollervey ntoll

Python (2023) ~ Grade 2 (Elementary)

Roman Number To Integer Calculator

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II. Roman numerals are usually written from largest to smallest and from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given a roman numeral, convert it to an integer.

Attached files
Filename (click to download) Size Uploaded by
Screen_Shot_2022-12-05_at_11.13.47.png 911.8 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-05/11-15-35/Screen_Shot_2022-12-05_at_11.13.47.png "...")
roman_error.png 49.0 KB ntoll
Markdown code
![roman_error.png](/media/assessment/9619ad05/2022-12-06/11-31-50/roman_error.png "roman_error.png")
numerals.png 17.8 KB ntoll
Markdown code
![numerals.png](/media/assessment/9619ad05/2022-12-06/11-46-43/numerals.png "numerals.png")
probem_number.png 17.7 KB ntoll
Markdown code
![probem_number.png](/media/assessment/9619ad05/2022-12-06/11-48-02/probem_number.png "probem_number.png")
Screen_Shot_2022-12-07_at_11.31.58.png 1.4 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-07/11-34-25/Screen_Shot_2022-12-07_at_11.31.58.png "...")
Screen_Shot_2022-12-09_at_12.06.07.png 545.7 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-09/12-07-22/Screen_Shot_2022-12-09_at_12.06.07.png "...")
Screen_Shot_2022-12-09_at_13.44.03.png 1.0 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-09/13-44-40/Screen_Shot_2022-12-09_at_13.44.03.png "...")
Screen_Shot_2022-12-09_at_13.44.03.png 1.0 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-09/13-45-11/Screen_Shot_2022-12-09_at_13.44.03.png "...")
Screen_Shot_2022-12-09_at_13.46.57.png 963.5 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-09/13-47-30/Screen_Shot_2022-12-09_at_13.46.57.png "...")
newline_bug.gif 191.1 KB ntoll
Markdown code
![newline_bug.gif](/media/assessment/9619ad05/2022-12-14/10-52-35/newline_bug.gif "newline_bug.gif") 9.2 MB Khadija
Markdown code
Demo_gradio_copy.mkv 9.2 MB Khadija
Markdown code
Screen_Shot_2022-12-16_at_12.01.11.png 575.8 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-16/12-02-08/Screen_Shot_2022-12-16_at_12.01.11.png "...")
Screen_Shot_2022-12-16_at_12.09.55.png 540.7 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-16/12-11-44/Screen_Shot_2022-12-16_at_12.09.55.png "...")
roman_numeral_calculator.gif 145.1 KB ntoll
Markdown code
![roman_numeral_calculator.gif](/media/assessment/9619ad05/2022-12-17/17-09-04/roman_numeral_calculator.gif "roman_numeral_calculator.gif")
Screen_Shot_2022-12-22_at_09.17.26.png 552.4 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-22/09-19-41/Screen_Shot_2022-12-22_at_09.17.26.png "...")
Screen_Shot_2022-12-22_at_01.36.33.png 1.3 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-22/09-23-02/Screen_Shot_2022-12-22_at_01.36.33.png "...")
Screen_Shot_2022-12-22_at_09.24.36.png 2.3 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-22/09-25-08/Screen_Shot_2022-12-22_at_09.24.36.png "...") 13.5 MB Khadija
Markdown code
Screen_Shot_2022-12-26_at_15.58.12.png 849.3 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2022-12-26/15-58-45/Screen_Shot_2022-12-26_at_15.58.12.png "...")
oops_gradio.png 10.6 KB ntoll
Markdown code
![oops_gradio.png](/media/assessment/9619ad05/2023-01-03/16-18-36/oops_gradio.png "oops_gradio.png")
Screen_Shot_2023-01-03_at_20.38.33.png 357.6 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2023-01-03/20-39-09/Screen_Shot_2023-01-03_at_20.38.33.png "...")
Screen_Shot_2023-01-03_at_20.38.33.png 357.6 KB Khadija
Markdown code
![...](/media/assessment/9619ad05/2023-01-03/20-52-25/Screen_Shot_2023-01-03_at_20.38.33.png "...")
Screen_Shot_2023-01-04_at_13.47.22.png 2.7 MB Khadija
Markdown code
![...](/media/assessment/9619ad05/2023-01-04/13-48-23/Screen_Shot_2023-01-04_at_13.47.22.png "...")

Status: Closed (results delivered). 91/100 ~ Pass with DISTINCTION (11/01/2023).

Khadija Khadija ~ 05 Dec 2022 11:15 a.m.

This project uses a python program to convert roman numerals to integers. As seen in the demo, a user enters roman numerals and they are being converted into an integer ...

Khadija Khadija ~ 05 Dec 2022 11:17 a.m. (updated: 07 Dec 2022 11:35 a.m.)

This project was executed with a google colab notebook. This allows our code to be saved in google drive for easy retrieval later. If you are new to colab notebooks, this quick intro might be of help.


Next, lets install gradio, an online platform that can help us demonstrate models for interactive user experience beyond codes. We can install gradio with the command below.

!pip install gradio

Next, we build the python source code for the project as seen below

import gradio as gr

def Roman_To_Integer(Roman_number):
    :type Roman_number: str
    :rtype: int

    #initialising our output
    result = 0

    Given a roman numeral which is a string, we want to split this string into individual 
    letters and save it into a list to enable us loop through a given roman numeral
    list_elements = [element for element in Roman_number]

    #We save all known roman symbols with their corresponding integers in a dictionary 
    dict_rom = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000} 

    #initialise j to 0 for comaprism of numerals
    j = 0

    #We loop through the indexes of the roman numeral which has been converted into a list
    for i in range(len(list_elements)-1):
        j = i+1

        For roman numerals with more than one character, we compared the first and second character
        if the first is greater than next, the resulting integer is added by the first then 
        retrieved from the dictionary and added  to the initial result, we compare and add till 
        the final symbol in the roman numeral

        if dict_rom[list_elements[i]]>= dict_rom[list_elements[j]]:
            result += dict_rom[list_elements[i]]

            otherwise if the first is lesser than the next, we subtract 1 from the result and add
            the next element, for example, for IV, we subtact 1 from 0, and add 5 giving us 4


        elif dict_rom[list_elements[i]]<dict_rom[list_elements[j]]: 
            result -= dict_rom[list_elements[i]]
    result += dict_rom[list_elements[j]]  
    return result

#We provided a web interface demo with gradio
demo = gr.Interface(fn=Roman_To_Integer, inputs="text", outputs="text")

#To launch the demo

Khadija Khadija ~ 05 Dec 2022 11:18 a.m. (updated: 05 Dec 2022 12:18 p.m.)

To reproduce the result and demo, kindly refer to this colab notebook

Roman To Integer Converter

ntoll Nicholas Tollervey ~ 06 Dec 2022 1:42 p.m.

Hi Khadija,

Veni, vidi, numeravi.

~ Gaius Julius Caesar 😉

Congratulations on getting your project ready for assessment. 👏

I'm going to work with you as your mentor. This means two things:

  1. I'll act as the assessor for your grade, and,
  2. I'm here to help, support and encourage you to reflect, refine and develop your project further, so your final mark truly reflects your level of attainment.

Please don't hesitate to ask questions, seek guidance or add your thoughts via more comments here, on the CodeGrades website. Such engagement is a good sign and further evidence of your attainment. It also shows others, who may look at your project, the story of how it was built, how you work as a developer and the lessons you learned along the way.

I have some initial feedback.

The first thing I tried to do was run your code, and I followed the link you kindly supplied. Luckily, I'm familiar with notebooks so clicked the "play" icon in the first cell. Sadly, I was met with an error:


Clearly, I didn't have gradio installed, and easily fixed the situation with the command !pip install gradio. But the only reason I knew to do this was because of my familiarity with notebooks. What would happen if I were someone interested in Roman numerals (but not computers) who wanted to use your code to read a value? I don't think they would be able recover in such a situation. Therefore, I have two requests:

  1. Can you update the notebook so gradio is automatically installed..?
  2. Please update this comment to include some "user documentation". Imagine you're writing for a non-technical user, how would you explain what to do? What other problems or confusions may a non-technical Roman numeral user encounter, and how do you help them avoid or overcome them? Perhaps include screen-shots along with your instructions.

When I input valid Roman numerals, it works..! 🎉



However, if I enter a value that is not a valid Roman numeral (in this case, the Latin, NUMERAVI) the code just hangs with no result produced:


I was hoping for an error message to point out my mistake (and my mistake, while deliberate in this case, could have been something as simple as a typo... e.g. MCNLXXIII with a mis-typed N instead of M). I had to restart the cell in order to recover, something a non-technical user may not know how to do.

Could you do two things please?

  1. investigate why your code hangs, and explain what happened, and,
  2. add some way of validating user input and returning a friendly error message.

I really appreciated that your code was well commented. It helped me understand what was going on, and figure out what it was you were trying to do. Well done..!

Some feedback about your code:

# initialising our output
result = 0
result = 0
roman_number = "MCMLXXIII"
for position, character in enumerate(roman_number[:-1]):
    ... do things ...
result += dict_rom[roman_number[-1]]

Finally, this feels more like a grade 2 level project, rather than grade 1 (i.e. you've created a project more advanced than that required for the grade you've entered). It would be very easy for me to re-assign this as a grade 2 project. What do you think? Grade 2 is definitely more of an achievement than grade 1.

I think this project is shaping up really well, and I'm looking forward to seeing how you develop it further, fix things up and refine your solution. Once again, please don't hesitate to reach out on here if you have questions, need advice or simply have a new version to show.

I look forward to hearing from you soon. 🚀

Khadija Khadija ~ 07 Dec 2022 1:47 p.m.

Hello Nicholas,

Thank you for the feedback.

  1. I have updated the code to include a quick installation and user documentaion of gradio as well as intro to colab notebooks for people who are unfamiliar. Hope this answers your question
#Run this cell to install gradio
!pip install gradio

ntoll Nicholas Tollervey ~ 07 Dec 2022 2:59 p.m.

Hi Khadija,

That's great. I look forward to seeing how the project develops further. 👍


Khadija Khadija ~ 09 Dec 2022 12:09 p.m. (updated: 09 Dec 2022 12:11 p.m.)

Hello Nick,

With regards to comment 2, I have added a simple if statement to check if the given input is a valid roman numeral, it then returns a simple error message as seen below.

The source code for this is shown here:

if not all(char in 'ivxlcdm' for char in Roman_number):
    return 'Please enter a valid Roman numeral'

As a result, when a user enters "NUMERAVI" for instance, it is no longer left hanging but it returns an error message



Khadija Khadija ~ 09 Dec 2022 1:38 p.m. (updated: 09 Dec 2022 1:54 p.m.)

Again for the additional feedback, they have been really helpful and has helped explore new ways of optimizing my code.



The full implementation in codes can be found in this Colab Notebook. I tried pasting the codes directly but it did not appear well. I hope this works


ntoll Nicholas Tollervey ~ 14 Dec 2022 11:29 a.m.


Thank you for your updates. I've enjoyed looking over the changes and have some feedback for you.

Well done on the validation of Roman numerals. I'm intrigued, while I can see how the if statement works, I'd love to hear your explanation of what not all(char in 'ivxlcdm' for char in Roman_number) is doing. However (and I promise I'm not doing this on purpose 😆) I've found a bug. Out of habit, when I entered a Roman numeral I pressed RETURN before hitting the submit button and it tells me the numerals are not valid. Here's a screen capture of this bug:


Could you fix this please..? By pressing RETURN I add a "whitespace" character to the input string. I'm interested to see how you fix this. Do let me know how you get on, and as always, please don't hesitate to ask questions or seek guidance.

Now that your code following Python naming conventions it looks much better (to my engineer's eyes). Good job..! I also really enjoyed following along with your code in the integer_to_roman function. It's nice and simple.

I have a further request: can you add a gradio interface for the integer_to_roman function..? It feels like it's a friendly thing to do for "users" (especially those not used to typing in code into notebooks).

One final thing to ponder... I think you have enough code (to copy into a new notebook?) to create a Roman numeral calculator! I imagine, with two gradio input boxes for Roman numerals, and some way to select the arithmetical operation (addition +, subtraction -, multiplication * and floor division //) you'd be able to generate a result as a Roman numeral. The interesting challenge would be to deal with numbers less than 1 or greater than 3999.

What do you think? 😁

While you've already created a project that allows me to form an opinion for assessment, I think plugging it all together into a Roman numeral calculator would put your project into the realm of "epic". Adding user instructions and a description of the project into the notebook would be icing on the cake. 🍰 Just so you know, this is how I will conduct the assessment and these are the assessment criteria I'll be using. It feels like the project is very close to being in a state for assessment, and I want to give you as much opportunity to refine things before I start the assessment process.

In conclusion, I feel you're doing a great job with this project, but I can see potential for you to turn it into something quite special for grade 2. 👍

If you have any questions or if there's something you're not sure about, just ask. Remember, I'm here to help (as well as assess). 🚀

Khadija Khadija ~ 15 Dec 2022 5:08 p.m. (updated: 16 Dec 2022 1 p.m.)

Hi Nick,

Thank you for your awesome feedback once again.

To begin with, The goal of not all(char in 'ivxlcdm' for char in Roman_number) is to produce an error statement if the input values are not valid roman numerals as per your last comments. The python all checks if all items of a given iterable evaluates to true. In our case, we would like to check if all characters in a given input is part of the valid list of roman characters ('ivxlcdm'). If this is true, we will have no issues but otherwise, we will like to perform an action and thus the inclusion of the negation keyword (not) before the all() statement. Hence if this statement evaluates to true, the error message is returned.

I am really intrigued about the various way you explored the code, I would have never thought of the bug with white spaces. I believe one way of fixing this is to include a key and value for white spaces in the values dictionary:

values = {' ':0, 'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}

Then updating the list of valid characters to include white spaces

    if not all(char in 'IVXLCDM '  for char in roman_number):
        return 'Please enter a valid Roman Numeral'

This actually works but for just a single or at most 3 white spaces in the input string. This is because we included the rule that no roman character should be more than 4, hence I believe pressing return adds more than 3 white spaces to the input string.

I have also tried to change the gradio interface to accept only a single line, hence we cannot move to the next line by pressing enter. I doubt if this is any change though. It would be great to learn from you if there is a better way to do this


As seen above, pressing enter will not move to the next line and create a bug. So far this two methods is what I have tried.

Next, I have added the gradio interface for integer_to_roman as shown below ...

For your final suggestions, I am not quite clear on what the task is: I would appreciate it if you could elaborate further on what needs to be done. However, I copied the code into a new notebook and organized into a class with both functions as methods and additional methods for the various arithmetic operations. I am not quite sure if that is what you mean but I will just leave it here for the meantime.

Roman Calculator

And for the assesment, I would be glad if we can start after I have made all neccesary edits.

Best, Khadija

ntoll Nicholas Tollervey ~ 17 Dec 2022 5:26 p.m. (updated: 17 Dec 2022 5:27 p.m.)

Hi Khadija,

Well done on the updates. To answer your specific questions:


As the screen grab explains (in shonky Latin), "this is a Roman numeral calculator". 😄

So, imagine I put ML (1050) into "Numeri Romani A" and LIX (59) into "Numeri Romani B", then when I click on the "COMPUTARE" button I should see the correct answer as the Roman numerals: MCIX (1109).

As I understand it, the gradio toolkit has text entry, buttons and drop downs - and kudos if you use Latin for the user interface. Do you need to use a class for this?

Perhaps all you need to do is a bit of code-plumbing to turn the Roman numerals into modern numerals, do the specified calculation, and then convert the answer back into Roman numerals and display it. Just remember to use floor division so you only get whole number (integer) results.

Remember, you may also need to write a user-guide for Roman citizens who don't know how to use a computer (or modern citizens who don't understand Roman numerals). 👍 📖 😱

Does this make sense..? Happy to answer any questions you may have.

I think once this is done, I'll be ready to write up the assessment. 🚀

Khadija Khadija ~ 20 Dec 2022 12:03 p.m. (updated: 20 Dec 2022 3:30 p.m.)

Hello Nick,

Thank you for your feedback. I have read about the strip method and applied it to fix the bug. Now we can add as much whitespace to the without encountering a bug.

I do understand the calculator task now thanks to the mock-up provided. I have made adjustments to the code and explored how to adjust the gradio interface accordingly. Please confirm below is this is what is required. If the general task is well demonstrated, I will then make the adjustments with user documentation.

Also find the source code I added to the two functions to generate the calculator:

def calculator(roman_num1,operation,roman_num2):
  if operation == "add":
    output =  roman_to_integer(roman_num1) + roman_to_integer(roman_num2)
    return integer_to_roman(output)

  elif operation == "subtract":
    output = roman_to_integer(roman_num1) - roman_to_integer(roman_num2)
    return integer_to_roman(output)

  elif operation == "multiply":
    output = roman_to_integer(roman_num1) * roman_to_integer(roman_num2)
    return integer_to_roman(output)

  elif operation == "divide":
        output = roman_to_integer(roman_num1) // roman_to_integer(roman_num2)
        return integer_to_roman(output)

I created a new notebook for the calculator here: Looking forward to your feedback.


ntoll Nicholas Tollervey ~ 21 Dec 2022 5:35 p.m.


This has brought a huge Cheshire Cat smile to my face and your video demonstrations effectively show the changes and progress you have made. Really great work. I can also confirm that your version of the calculator is a great response to my mock-up, and I look forward to user documentation.

I've tested the calculator in your most recent notebook and have some feedback:

Please remember to test your app with boundary conditions and strange use cases, and ensure your code accounts for them in the simplest and most helpful manner.

Once you've fixed up these aspects of the code and provided a user guide, I think I have enough evidence and will have observed enough activity and growth to be able to write up the assessment for your grade. This is generally a three step process:

  1. I write up my assessment.
  2. A third party checks it, points out corrections or advises on ways I can improve my feedback to you.
  3. Once the review is approved in step 2, you get your results.

If you're quick, assessment might even be done before this year's Christmas celebrations! 🎄

Khadija Khadija ~ 22 Dec 2022 10:23 a.m.

Hello Nick,

Thank you for the feedback. I have made some adjustments based on you most recent feedback


Setting flagging to never removes the flag button and I have maintained that setting now since it may not be useful for this project.


I have realized that sometimes there are boundary conditions that may not occur to me. I would like to share the interface with a few of my friends who may think of interesting test cases, if their inputs are flagged, I could access them later and use that to improve the code. I would therefore like to keep working on improving it during or after assessment. Looking forward to your feedback and next steps


ntoll Nicholas Tollervey ~ 22 Dec 2022 5:47 p.m.

Hi Khadija,

Thank you for the updates. As far as I can tell there's just two things I'm waiting for in order to fulfill the assessment:

Many thanks in advance.

Khadija Khadija ~ 26 Dec 2022 4:03 p.m.

Hello Nick,

Thank you once again for your feedback.


I hope that this is enough for you to begin the assessment now. Looking forward to your feedback. I wish you a joyful Merry Christmas.


ntoll Nicholas Tollervey ~ 03 Jan 2023 4:21 p.m.


Happy new year 🎉, and thank you for your update. I hope you had a good Christmas holiday.

Just a couple of things, when I click on the public version of the project I see this:


I don't think this is correct. Could you look into this please..?

It would also be really helpful as part of the grading process (put simply, I need to see evidence for assessment purposes) if you could share the user feedback from your friends.

This project is SO close to a final grading score and feedback.

As always, if you have any questions, just ask.

Khadija Khadija ~ 03 Jan 2023 8:54 p.m. (updated: 04 Jan 2023 1:59 p.m.)

Hello Nick,

Thank you for your feedback once again. I noticed that the public link was available for only 72 hours. I have therefore hosted it as an application on hugging faces as a space via gradio. Please find the new version which can be accessed at any time. This is how it should appear to a user just like the colab gradio interface:


I have also created a google drive folder where I have added screenshots of some of the feedback from my friends.


So far I have received some useful feedback and made adjustments to the code:

I have fixed this issues and more and I am still exploring how to stretch beyond 3999. I hope this is enough for you to begin assessment. I am available to make more adjustments and provide more information if needed.


ntoll Nicholas Tollervey ~ 07 Jan 2023 5:22 p.m.


Thank you for your update. You have some lovely and helpful friends. Please pass on my thanks for helping you with your grading.

I think I have all the evidence I need to be able to make the assessment, award marks and (most importantly) give you your written feedback. It should be with you by the middle of next week.

Finally, really well done and huge congratulations at getting the project this far. 🎉

Back to top