Last active
December 12, 2019 22:13
-
-
Save P403n1x87/0641e1c17571243830ef4058b7fd05d7 to your computer and use it in GitHub Desktop.
CodeKata 13 (http://codekata.com/kata/kata13-counting-code-lines/)
This file contains hidden or 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
class FiniteAutomaton: | |
def __init__(self): | |
self._states = {} | |
self._initial = None | |
self._current = None | |
def add_state(self, name, handler, initial=False): | |
if initial: | |
if self._initial: | |
raise RuntimeError("Initial state already added!") | |
self._initial = name | |
self._current = self._initial | |
self._states[name] = handler | |
def run(self, actions): | |
for action in actions: | |
self._current = self._states[self._current](action) | |
return self._current |
This file contains hidden or 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
from thirteen import Thirteen | |
SOURCE_3 = r"""// This file contains 3 lines of code | |
public interface Dave { | |
/** | |
* count the number of lines in a file | |
*/ | |
int countLines(File inFile); // not the real signature! | |
}""" | |
SOURCE_5 = r"""/***** | |
* This is a test program with 5 lines of code | |
* \/* no nesting allowed! | |
//*****//***/// Slightly pathological comment ending... | |
public class Hello { | |
public static final void main(String [] args) { // gotta love Java | |
// Say hello | |
System./*wait*/out./*for*/println/*it*/("Hello/*"); | |
} | |
}""" | |
SOURCE_7 = """class Main { | |
public static void main(String[] args) { | |
double test = 1. | |
/ | |
5; | |
} | |
}""" | |
def test_thirteen(): | |
t = Thirteen() | |
assert t.count_lines(SOURCE_3) == 3 | |
assert t.count_lines(SOURCE_5) == 5 | |
assert t.count_lines(SOURCE_7) == 7 |
This file contains hidden or 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
from fsm import FiniteAutomaton as FA | |
class Thirteen(FA): | |
def __init__(self): | |
super().__init__() | |
# Configure the machine | |
self.add_state( | |
"N", | |
lambda a: {'"': "S", "/": "C?", " ": "B", "\t": "B", "\n": "N",}.get( | |
a, "C" | |
), | |
initial=True, | |
) | |
self.add_state("C", lambda a: {'"': "S", "/": "C?", "\n": "N"}.get(a, "C")) | |
self.add_state("S", lambda a: {"\\": "E", '"': "C"}.get(a, "S")) | |
self.add_state( | |
"B", | |
lambda a: {" ": "B", "\t": "B", "\n": "N", "/": "C?", '"': "S"}.get(a, "C"), | |
) | |
self.add_state("C?", lambda a: {"/": "SL", "*": "ML", "\n": "N"}.get(a, "C")) | |
self.add_state("E", lambda a: "S") | |
self.add_state("ML", lambda a: "?C" if a == "*" else "ML") | |
self.add_state("SL", lambda a: "N" if a == "\n" else "SL") | |
self.add_state("?C", lambda a: {"/": "B", "*": "?C"}.get(a, "ML")) | |
def count_lines(self, source): | |
seq = ["N"] | |
for char in source: | |
state = self.run(char) | |
if state in ["N", "C", "C?", "ML", "SL"] and state != seq[-1]: | |
seq.append(state) | |
return len( | |
[ | |
line | |
for line in "".join(seq) | |
.replace("C?ML", "") | |
.replace("C?SL", "") | |
.split("N") | |
if line | |
] | |
) | |
if __name__ == "__main__": | |
t = Thirteen() | |
print( | |
t.count_lines( | |
""" | |
class HelloWorld { | |
public static void main(String[] args) { | |
System.out.println("Hello World"); | |
} | |
} | |
""" | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment