Sparrow
Sparrow

Reputation: 1

How do I make my Python 3 code more compact

I'm obviously quite new to python. So the code I wrote for my assignment gives me the right output, however, it just hurts your eyes to look at. So I was wondering if there is a way to make the code more compact?

Here's my code:

import sys

period_count = 0
excl_count = 0
quest_count = 0
colon_count = 0
dquote_count = 0
comma_count = 0
scolon_count = 0
slash_count = 0
bslash_count = 0
lparen_count = 0
rparen_count = 0
quote_count = 0

for line in sys.stdin:
    for char in line:
        if char == ".":
            period_count = period_count + 1
        if char == "!":
            excl_count = excl_count +1
        if char == "?":
            quest_count = quest_count +1
        if char == ":":
            colon_count = colon_count +1
        if char == "\"":
            dquote_count = dquote_count +1
        if char == ",":
            comma_count = comma_count +1
        if char == ";":
            scolon_count = scolon_count +1
        if char == "/":
            slash_count = slash_count +1
        if char == "\\":
            bslash_count = bslash_count +1
        if char == "(":
            lparen_count = lparen_count +1
        if char == "(":
            rparen_count = rparen_count +1  
        if char == "'":
            quote_count = quote_count +1    

print("{0} {1:>3} {0:>4} {2:>5} {0:>4}".format("|", "mark", "number"))
print("{0} {1} {0} {2} {0}".format("|", "_______", "_________"))                

print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", ".", period_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "!", excl_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "?", quest_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", ":", colon_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "\"", dquote_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", ",", comma_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", ";", scolon_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "/", slash_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "\\", bslash_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "(", lparen_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", ")", rparen_count))
print("{0} {1:>3} {0:>5} {2:>5} {0:>5}".format("|", "'", quote_count))

And the assignment was to count each punctuation mark individually and print that mark plus the results in a table.

Any help will be much appreciated!

Upvotes: 0

Views: 108

Answers (2)

Tamas Hegedus
Tamas Hegedus

Reputation: 29916

This shorter version will count all character frequencies, using the builtin class collections.Counter, and print the desired ones (including original table formatting):

import sys, collections
freqs = collections.Counter(char for line in sys.stdin.readlines() for char in line)
print("|  mark | count |")
print("|_______|_______|")
for char in ".!?:\",;/\\()'":
  print("| {:>5} | {:>5} |".format(char, freqs.get(char, 0)))

Or the same idea in one line, just for fun:

(lambda freqs=__import__('collections').Counter(char for line in __import__('sys').stdin.readlines() for char in line):print("|  mark | count |\n|_______|_______|\n"+"".join("| {:>5} | {:>5} |\n".format(char, freqs.get(char, 0)) for char in ".!?:\",;/\\()'")))()

Upvotes: 0

Jared Smith
Jared Smith

Reputation: 21926

You can hash on strings, and credit to tobias_k for the comprehension:

dictionary = {c: 0 for c in ".!?:\",;/\\()'"}

for line in sys.stdin:
   for char in line:
      if char in dictionary:
          dictionary[char] += 1

for char, counter in dictionary.items():
    print(...) # formatted string goes here

Edit

Per conversation with Chris_Rands in the comments, if the assignment was to simply count all punctuation marks then I recommend changing the above slightly:

import string
dictionary = {c: 0 for c in string.punctuation}

Rest follows as above. string.punctuation is '!"#$%&'()*+,-./:;<=>?@[\]^_{|}~' on my machine (the set is locale-based according to the docs).

Final Update

Credit to Muposat for reminding me of defaultdict: no need to initialize the keys and counters when 0 is the default value for the int constructor:

import sys
import string

dictionary = defaultdict(int)
for line in sys.stdin:
    for char in line:
        if char in string.punctuation:
            dictionary[char] += 1


for char, counter in dictionary.items():
    print(...) # formatted string goes here

Upvotes: 3

Related Questions