0

I'm writing a Python function to validate IPv4 addresses. for a Task of CS50 Python. My function should:

Ensure the format is X.X.X.X, where each X is a number between 0-255. Return True for valid IPv4 addresses and False otherwise.

However, my test case is failing with this error message:

:( test_numb3rs.py catches numb3rs.py only checking if first byte of IPv4 address is in range**

check50 error

my main code is:

import re

def main():
    print(validate(input("IPv4 Address: ")))

def validate(ip):
    match = re.fullmatch(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", ip)
    return bool(match) and all(0 <= int(octet) <= 255 for octet in match.groups())

if __name__ == "__main__":
    main()

and my Test Code is:

from numb3rs import validate
def test_validate():
    # Valid cases
    assert validate("127.0.0.1") == True
    assert validate("255.255.255.255") == True

    # Invalid cases
    assert validate("512.512.512.512") == False
    assert validate("1.2.3.1000") == False
    assert validate("cat") == False

I have tried following multiple solutions available but still could not understand the issue. I Tried using exit(1) in a different version of my code, but that also did not solve the issue. Instead, it made the cases where any one octet goes above 255 fail.

1
  • Why not use the built in ipaddress module? Commented Mar 21 at 12:14

2 Answers 2

0

All of your tests are accurate checks. However, check50 is very picky about how it expects you to test the validate() function. There are at least 2 issues you need to address. I will describe each below.

This line has invalid numbers for all 4 bytes of the address:

assert validate("512.512.512.512") == False

So, after it fails on the 1st byte, the others aren't considered. Change it to these 2 lines to resolve that issue:

assert validate("512.5.5.5") == False
assert validate("5.5.5.512") == False

This line has a 4 digit value at the 4th byte and that is considered a different error.

assert validate("1.2.3.1000") == False

Change it to this line to resolve that issue:

assert validate("1.2.3.999") == False

Note: Once you modify the 1st test, you really don't need the 2nd test.

Sign up to request clarification or add additional context in comments.

2 Comments

that fixed it. Thanks
Great. Your problem demonstrates a key issue when designing tests: each test for invalid input should only test a single input error. Your example with 512.512.512.512 had 4 incorrect values. The test with 1.2.3.1000 had 2 errors: 1) value > 256, AND 2) a 4 digit byte value.
0
import re
def validate(ip):
    match = re.fullmatch(r"^(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)$", ip)
    return True if match else False

ip = "127.0.0.1"
r = validate(ip)
print(r) # Output : True

ip = "255.255.255.255"
r = validate(ip)
print(r) # Output : True

ip = "512.512.512.512"
r = validate(ip)
print(r) # Output : False

ip = "1.2.3.1000"
r = validate(ip)
print(r) # Output : False

ip = "cat"
r = validate(ip)
print(r) # Output : False

Idea Behind:

25[0-5] Matches numbers from 250 to 255

2[0-4][0-9] Matches numbers from 200 to 249

1?[0-9][0-9]? Matches numbers from 0 to 199

\. Matches the literal dot (.) between octets

^ and $ Ensure the entire string is an IPv4 address

1 Comment

This solution has the same tests as the original post, so doesn't address the check50 issues. Read my answer to see how to correctly test the validate() function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.