Skip to content

Instantly share code, notes, and snippets.

@henriquebastos
Created May 25, 2022 02:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henriquebastos/a2297e049fe224ac2d779c96b2b2c350 to your computer and use it in GitHub Desktop.
Save henriquebastos/a2297e049fe224ac2d779c96b2b2c350 to your computer and use it in GitHub Desktop.
Simple exercise to introduce the concept of FSM.
"""
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__])
"""
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__])
"""
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__])
"""
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__])
"""
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__])
"""
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__])
"""
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__])
"""
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