 # Problem in code

``````
###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

while num >= value:

if num // value >= 1:

#Concatenate the letter for the first division

# get the remainder of the division

remainder = num - value

print("the remainder is", remainder)

# Find the roman for the remainder

if remainder // value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

else:

num = remainder

print("number for the next iteration", remainder)

print("roman_num is", roman_num)

count += 1

print(count)

return roman_num

print(py_solution().int_roman(1100))

``````

After finding the value of the remainder variable in the code the rest of the code after that is not being executed, so just creating an infinite loop, cause the rest of the code is to make the while loop condition false, as it solves the problem, Please help

Thanks

here’s a walkthrough:

Starts with a while loop, followed with an if statment.

num // value = 1100 // 1000 = 1

this is outside the if statement, so it happens regardless of whether it executed.
remainder = 1100 - 1000 = 100

This is an if/else statement, if one happens the other does not

remainder // value = 100 // 1000 = 0

The if statement is satisfied and that code block is chosen over the else.
This ends the while loop block with num = 1100

Here instead of floor division, l wanted modulo operator

I have tried to correct it abit, but the next iterations seems to have problem with the logic of the code, it doesn’t work out

``````
###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

while num >= value:

if num // value >= 1:

#Concatenate the letter for the first division

# get the remainder of the division

remainder = num - value

print("the remainder is", remainder)

# Find the roman for the remainder

if remainder % value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

else:

num = remainder

print("number for the next iteration", remainder)

count += 1

print(count)

print(py_solution().int_roman(1100))

``````

`return answer` is being executed inside the while loop ending the entire function.
To help you troubleshoot, replace `while num >= value:` with `while num >= value and count < 10:` to prevent infinite loops.

What are you trying to accomplish with this piece of code, it looks redundant in conception.
edit: Perhaps the better question is what happens if you don’t find the roman numeral for the remainder and always run the else statement.

1 Like

I changed the code again and now it juts stops at the first iteration

``````
###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

if num >= value:

if num // value >= 1:

#Concatenate the letter for the first division

# get the remainder of the division

remainder = num - value

print("the remainder is", remainder)

if num or remainder <= value:

# Find the roman for the remainder

if remainder % value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

else:

num = remainder

print("number for the next iteration", remainder)

if num or remainder == 0:

count += 1

print(count)

print(py_solution().int_roman(1100))

``````

Thanks

Having the while loop was a good idea, it just wasn’t really compatible with the remainder idea you’re working with. The if remainder statement I pointed out isn’t really different than the first if statement and the while loop instructs your program to repeat that first statement until it can’t remove another value from num.

To help with your code as written:

In an and/or if statement you have to define each statement, python reads that as these two statements:
`if num:`
or
`if remainder == 0:`

If number is truthy or remainder is 0, return out of the function
In this case the truthiness of number would mean non 0

so your function sees that num is 100 on the first iteration and returns ‘m’.

Something else to look at for efficiency:
What’s the difference between these statements?

``````if num >= value:
if num // value >= 1:
``````

so what is the problem?

you are right it can be combined

thanks

Doing a return means the entire function ends, thus it doesn’t continue iterating
`for key,value in roman_num.items():`

You haven’t run into a problem with this yet, but remainder is only defined in the first if statement:

Once you get your code to iterate, try running the function with 900

But it only returns when the condition is met, which is when I want it to stop iterating

thanks

In that bit of code to end the function, if num is greater than 0 the code ends, that’s why it’s only doing one iteration.

if num = 1100 to start, at the end num will = 100 and it will return “M”

I think what you want is:

``````if num == 0 or remainder == 0:
``````

which is not the same as

``````if num or remainder == 0:
``````
``````
###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

if num >= value and num // value >= 1:

remainder = num - value

# get the remainder of the division

# ensure that remainder is non negative

num = remainder

print("the remainder is", remainder)

if num == 0 or remainder == 0:

if num < value or remainder < value:

# Find the roman for the remainder

if remainder % value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

else:

num = remainder

print("number for the next iteration", remainder)

count += 1

print(count)

print(py_solution().int_roman(900))

``````

The program now works for 1100 but with 900, it shows the error below:

Traceback (most recent call last):
File “c:\Users\simmy.vscode\app.py”, line 50, in
print(py_solution().int_roman(900))
File “c:\Users\simmy.vscode\app.py”, line 28, in int_roman
num = remainder
UnboundLocalError: local variable ‘remainder’ referenced before assignment
PS C:\Users\simmy.vscode>

Thanks

This means that you’re trying to assign a variable name to an object that doesn’t exist. When you plug in 900, it’s less that your first iteration of the dictionary (“M”:1000) so your first if block doesn’t run.

Also, what I pointed out earlier about `if num >= value and num // value >= 1:` wasn’t that they could be combined. They’re mathmatically identical, `if num >= value` then `num // value >=1`, just pick one or the other.

Does that mean l need to define remainder, not sure how to Solve it

Thanks

You could start your code by setting remainder = num, but there isn’t really any point in using the extra variable. You can change num. Whenever you add a roman numeral, subtract that value from num.

1 Like
``````
###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

if num >= value:

if num % value != 0:

num = num - value

elif num % value == 0:

roman_needed = num // value

print("the roman needed is", roman_needed)

num = num - (roman_needed * value)

print(f'the elif num is {num}')

# get the remainder of the division

# ensure that remainder is non negative

print("the remainder is", num)

if num == 0:

if num < value:

# Find the roman for the remainder

if num % value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

else:

print("number for the next iteration", num)

count += 1

print(count)

print(py_solution().int_roman(900))

``````
1 Like

Good job! Now, just have a look at this mod on your code and run it.

``````###  converting an integer number to a roman number

class py_solution:

def int_roman(self,num):

# count iterations

count = 0

# create a string to store the result

# create a dictionary to store the roman numbers

roman_num = {"M":1000,"D":500,"C":100,"L":50,"XX":20,"X":10,"V":5,"IV":4,"I":1}

# get floor division of num by the highest number

for key,value in roman_num.items():

#Ensure that divisor is greater than value to pick the highest letter going down

if num >= value:

#if num % value != 0:

#        num = num - value

#elif num % value == 0:

roman_needed = num // value

print("the roman needed is", roman_needed)

num = num - (roman_needed * value)

print(f'the elif num is {num}')

# get the remainder of the division

# ensure that remainder is non negative

#print("the remainder is", num)

if num == 0:

#if num < value:

# Find the roman for the remainder

#        if num % value == 0:

#If remainder is not wholly divisible send the num in the next iteration to check against the next value

#        else:

#                print("number for the next iteration", num)

count += 1

print(count)

print(py_solution().int_roman(900))
``````

sorry bavarcarus for the late reply, what do you mean by mod

thanks

You got the right code in there to work, but there was a lot of repetition. I commented out the code that doesn’t need to be there.

Are you returning `CM`?

And what about `XL` and `IX` (40 and 9, respectively)?

1 Like

oh that is actually the correct way of writing it

1 Like