Skip to content

Instantly share code, notes, and snippets.

@Louis-Saglio
Created May 15, 2019 09:27
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 Louis-Saglio/729f0a8e05d597eb06a867f1042d8d1a to your computer and use it in GitHub Desktop.
Save Louis-Saglio/729f0a8e05d597eb06a867f1042d8d1a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
def read_stdin() -> list:
"""
Returns a list of str read from stdin.
Use whitespaces as word separator.
"""
# 0 is the file descriptor of stdin.
# A more clever way would have been to use sys.stdin, but it is forbidden for pedagogic reasons
with open(0) as stdin:
# Cannot use readline because stdin is stored in live memory and is forgotten once it is read.
# So if you use readline against it, you will read only the first line
return stdin.read().split()
def count_word_number(words: list) -> dict:
"""
Compute number of word occurrence in a list.
Returns a dict with a word as key and its occurrence number as value
"""
count = {}
for word in words:
if word in count:
count[word] += 1
else:
count[word] = 1
return count
def repr_ordered_word_count(word_count: dict) -> str:
"""
Build a string with a word and its occurrence number per line
Lines are ordered by descending occurrence number
"""
return "\n".join(
f"{occurrence_nbr} {word}"
for word, occurrence_nbr in sorted(word_count.items(), key=lambda key_value: key_value[1], reverse=True)
)
def main():
print(repr_ordered_word_count(count_word_number(read_stdin())))
def test():
assert count_word_number(["foo", "bar", "foo", "eggs", "bar", "", "bar"]) == {"foo": 2, "bar": 3, "eggs": 1, "": 1}
assert repr_ordered_word_count({"foo": 1, "bar": 3}) == "3 bar\n1 foo"
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment