3 ms·
I feel like python provides a more readable solution. #!/usr/bin/env python3 with open('data.txt', 'r') as f: data = dict(x.split() for x in f
by Skunkleton 12y ago
I feel like python provides a more readable solution.
#!/usr/bin/env python3
with open('data.txt', 'r') as f:
data = dict(x.split() for x in f if x.strip())
print("Zsófia's grade:", data["Zsófia"])
print("List of students with a failing grade:\n ",end="")
print(*[x for x in data.keys() if data[x] == 'F'], sep=", ")
print("Distribution of grades by letter:")
for k,g in groupby(sorted(data.values()), lambda x: x[0]):
print(" {}:".format(k), sum(1 for _ in g))
- viraptor 12y agoA working version with some stuff improved - groupby implemented, len() instead of sum(), a less squished version of printing, "student(s)" added: #!/usr/bin/env python3 from collections import defaultdict def invert_dict(data): res = defaultdict(list) for k, v in data.items(): res[v[0]].append(k) return res with open('data.txt', 'r') as f: data = dict(x.split() for x in f if x.strip()) print("Zsófia's grade:", data["Zsófia"]) print("List of students with a failing grade:") print(" " ,end="") print(*[x for x in data.keys() if data[x] == 'F'], sep=", ") print("Distribution of grades by letter:") grouped = invert_dict(data) for k, g in sorted(grouped.items()): print(" {}: {} student{}".format(k, len(g), 's' if len(g) > 1 else ''))
- Veedrac 12y agoNo need for `invert_dict`; you're just counting so `collections.Counter` would work fine: from collections import Counter with open('data.txt', 'r') as datafile: students = dict(line.rsplit(maxsplit=1) for line in datafile) failing = [name for name, grade in students.items() if grade >= 'E'] grade_counts = Counter(grade[0] for grade in students.values()) print("Zsófia's grade:", students["Zsófia"]) print("List of students with a failing grade:") print(" " + ", ".join(failing)) print("Distribution of grades by letter:") for grade, count in sorted(grade_counts.items()): print(" {}: {} student{}".format(grade, count, 's' * (count != 1)))
- codygman 12y agoA Haskell solution, though I'm sure someone can do better ;) Perhaps I'll clean it up using printf/format[0] later. {-# LANGUAGE OverloadedStrings #-} import Control.Monad (liftM) import qualified Data.HashMap.Lazy as H import Data.List (sort) import Data.Maybe (fromMaybe) import Data.Monoid ((<>)) import qualified Data.Text as T import qualified Data.Text.IO as TIO import Prelude main :: IO () main = do gradesMap <- liftM (H.fromList . map ((\(x:y:_) -> (x,y)) . T.splitOn "\t") . T.lines) (TIO.readFile "example.txt") let failingNames = H.keys $ H.filter ((== F) . T.take 1) gradesMap gradeTotals = foldl (\m k -> H.insertWith (+) (T.take 1 k) 1 m) H.empty (H.elems gradesMap) TIO.putStrLn $ "Zsófia's grades: " <> fromMaybe "N/A" (H.lookup "Zsófia" gradesMap) TIO.putStrLn "List of students with a failing grade:" TIO.putStrLn $ " " <> T.intercalate ", " failingNames TIO.putStrLn "Distribution of grades by letter:" mapM_ (\(k,v) -> TIO.putStrLn $ " " <> k <> ": " <> (T.pack . show $ v) <> " students") (sort . H.toList $ gradeTotals) 0: http://hackage.haskell.org/package/formatting http://hackage.haskell.org/package/formatting