pythonpython-3.xcs50

Python IPv4 Validation Only Checking First Byte Instead of All Four Bytes


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.


Solution

  • 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.