Created
May 25, 2022 02:12
-
-
Save henriquebastos/a2297e049fe224ac2d779c96b2b2c350 to your computer and use it in GitHub Desktop.
Simple exercise to introduce the concept of FSM.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
def symbols(input_str: str) -> bool: | |
"""Fill your code bellow to make all tests pass.""" | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
def symbols(input_str: str) -> bool: | |
"""Almost done version 1 submitted by student.""" | |
plus = False | |
foundalpha = False | |
validInput = True | |
for i, l in enumerate(input_str): | |
if l == "+": | |
if plus and foundalpha: | |
foundalpha = False | |
validInput = True | |
plus = True | |
elif l.isalpha(): | |
validInput = False | |
foundalpha = True | |
elif l != "+" and foundalpha: | |
return False | |
return validInput | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
def symbols(input_str: str) -> bool: | |
"""Working version 2 submitted by student.""" | |
onValidation = False | |
if len(input_str) < 3: | |
for l in input_str: | |
if l.isalpha(): | |
return False | |
return True | |
for i, l in enumerate(input_str): | |
if onValidation: | |
if l.isalpha(): | |
continue | |
elif l == "+": | |
onValidation = False | |
continue | |
return False | |
if l.isalpha(): | |
if i == len(input_str) - 1: | |
return False | |
elif input_str[i - 1] == "+": | |
onValidation = True | |
else: | |
return False | |
return True | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha input_str[idx]acters in a string are surrounded | |
(the input_str[idx]acters immediately before and after) by a plus sign. | |
Function should return false if any alpha input_str[idx]acter present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
def symbols(input_str: str) -> bool: | |
"""Working version 3 submitted by student.""" | |
idx = 0 | |
while idx < len(input_str): | |
if input_str[idx].isalpha(): | |
if len(input_str) < 3: | |
return False | |
# Check the set of alphas start with plus | |
if not input_str[idx - 1] == "+": | |
return False | |
idx += 1 | |
if idx >= len(input_str): | |
return False | |
# Verify with a set of alphas are surround by plus | |
while idx < len(input_str): | |
# Check the set of alphas end with plus | |
if input_str[idx] == "+": | |
break | |
if input_str[idx].isalpha(): | |
idx += 1 | |
continue | |
return False | |
idx += 1 | |
return True | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
ZERO, ONE, TWO = 0, 1, 2 | |
def symbols(s: str) -> bool: | |
"""Version 4 introducing the concept of states with explicit exits.""" | |
state = ZERO | |
for char in s: | |
if state == ZERO: | |
if char == "+": | |
state = ONE | |
elif not char.isalpha(): | |
continue | |
else: | |
return False | |
elif state == ONE: | |
if char == "+": | |
continue | |
elif char.isalpha(): | |
state = TWO | |
else: | |
state = ZERO | |
elif state == TWO: | |
if char == "+": | |
state = ONE | |
elif char.isalpha(): | |
continue | |
else: | |
return False | |
if state == TWO: | |
return False | |
return True | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
NORMAL, PLUS, ALPHA, ERROR = 0, 1, 2, 3 | |
# Truth table: | |
# NORMAL, TESTE, PLUS | |
# NORMAL, TESTE, NORMAL | |
# NORMAL, TESTE, RAISE | |
# PLUS, TESTE, PLUS | |
# PLUS, TESTE, ALPHA | |
# PLUS, TESTE, NORMAL | |
# ALPHA, TESTE, PLUS | |
# ALPHA, TESTE, ALPHA | |
# ALPHA, TESTE, RAISE | |
def symbols(s: str) -> bool: | |
"""Version 5 introducing the concept of error state.""" | |
state = NORMAL | |
for char in s: | |
if state == NORMAL: | |
if char == "+": | |
state = PLUS | |
elif not char.isalpha(): | |
continue | |
else: | |
state = ERROR | |
elif state == PLUS: | |
if char == "+": | |
continue | |
elif char.isalpha(): | |
state = ALPHA | |
else: | |
state = NORMAL | |
elif state == ALPHA: | |
if char == "+": | |
state = PLUS | |
elif char.isalpha(): | |
continue | |
else: | |
state = ERROR | |
elif state == "ERROR": | |
break | |
return state not in (ALPHA, ERROR) | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
NORMAL, PLUS, ALPHA, ERROR = 0, 1, 2, 3 | |
def symbols(s: str) -> bool: | |
"""Version 5 removing redundant exits to enforce the transition to error | |
state.""" | |
state = NORMAL | |
for char in s: | |
if state == NORMAL: | |
if char == "+": | |
state = PLUS | |
elif char.isalpha(): | |
state = ERROR | |
elif state == PLUS: | |
if char.isalpha(): | |
state = ALPHA | |
elif char != "+": | |
state = NORMAL | |
elif state == ALPHA: | |
if char == "+": | |
state = PLUS | |
elif not char.isalpha(): | |
state = ERROR | |
elif state == "ERROR": | |
break | |
return state not in (ALPHA, ERROR) | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Write a function that determines if all alpha characters in a string | |
are surrounded (the characters immediately before and after) by a plus sign. | |
Function should return false if any alpha character present in the string isn't | |
surrounded by a plus sign. Otherwise the function should return true. | |
""" | |
NORMAL, PLUS, ALPHA, ERROR = 0, 1, 2, 3 | |
is_plus = lambda char: char == "+" | |
not_plus = lambda char: char != "+" | |
not_alpha = lambda char: not char.isalpha() | |
is_alpha = lambda char: char.isalpha() | |
FSM = { | |
NORMAL: ( | |
(is_plus, PLUS), | |
(is_alpha, ERROR), | |
), | |
PLUS: ( | |
(is_alpha, ALPHA), | |
(not_plus, NORMAL), | |
), | |
ALPHA: ( | |
(is_plus, PLUS), | |
(not_alpha, ERROR), | |
), | |
ERROR: (), | |
} | |
def symbols(s: str) -> bool: | |
"""Version 6 refactoring to a declarative approach.""" | |
state = NORMAL | |
for char in s: | |
for condition, new_state in FSM.get(state): | |
if condition(char): | |
state = new_state | |
break | |
return state not in (ALPHA, ERROR) | |
def test_main(): | |
assert symbols("") is True | |
assert symbols("0") is True | |
assert symbols("123") is True | |
assert symbols("01%2-@") is True | |
assert symbols("+1+") is True | |
assert symbols("+a+") is True | |
assert symbols("+ab+") is True | |
assert symbols("+ab++") is True | |
assert symbols("+Z+Y+") is True | |
assert symbols("+ab+a+") is True | |
assert symbols("+a+b+7") is True | |
assert symbols("+a+=5=+d+") is True | |
assert symbols("12+ab+a+12") is True | |
assert symbols("a") is False | |
assert symbols("a+") is False | |
assert symbols("+a") is False | |
assert symbols("-a+") is False | |
assert symbols("+a-") is False | |
assert symbols("-a-") is False | |
assert symbols("+ab1+") is False | |
assert symbols("+a1b+") is False | |
assert symbols("+1ab+") is False | |
assert symbols("+ab+a") is False | |
assert symbols("+a+b=") is False | |
if __name__ == "__main__": | |
import pytest | |
pytest.main(["-s", __file__]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment