Hi. I am asking help for something that I have already done. However, I believe there is a much better way to do it. I am pretty novice to python and I don't know (yet xD) all of its capabilities and I am sure some of you will find this my attempt ridiculous.

The goal of this piece of code is simply to display two 'rows' of values aligned to the right.

Here's the code:

# -*- coding: cp1252 -*-

import math

def n_algs(n):
    """
    Returns the number of numbers a number has
    """
    return int(math.floor(math.log(n, 10)) + 1)
  
n_matriculas            = 500
n_matriculas_com_seguro = 412
n_matriculas_sem_seguro = 8
n_matriculas_invalidas  = 7

n_max = max(n_matriculas_com_seguro, n_matriculas_sem_seguro, n_matriculas_invalidas)
n_max_algs = n_algs(n_max)

n_matriculas_com_seguro_pad = str(n_matriculas_com_seguro).rjust(n_max_algs)
n_matriculas_sem_seguro_pad = str(n_matriculas_sem_seguro).rjust(n_max_algs)
n_matriculas_invalidas_pad = str(n_matriculas_invalidas).rjust(n_max_algs)

perc_matriculas_com_seguro = float(n_matriculas_com_seguro)/n_matriculas*100
perc_matriculas_sem_seguro = float(n_matriculas_sem_seguro)/n_matriculas*100
perc_matriculas_invalidas = float(n_matriculas_invalidas)/n_matriculas*100

perc_max = max(perc_matriculas_com_seguro, perc_matriculas_sem_seguro, perc_matriculas_invalidas)
n_max_algs_perc = len(str(perc_max)) + 3 # por causa de '(' '%' ')'

perc_matriculas_com_seguro = "(" + str(perc_matriculas_com_seguro) + "%)"
perc_matriculas_sem_seguro = "(" + str(perc_matriculas_sem_seguro) + "%)"
perc_matriculas_invalidas = "(" + str(perc_matriculas_invalidas) + "%)"

perc_matriculas_com_seguro_pad = perc_matriculas_com_seguro.rjust(n_max_algs_perc)
perc_matriculas_sem_seguro_pad = perc_matriculas_sem_seguro.rjust(n_max_algs_perc)
perc_matriculas_invalidas_pad = perc_matriculas_invalidas.rjust(n_max_algs_perc)

print "numero de matriculas: %d" % n_matriculas
print "- com seguro: %s %s" % (n_matriculas_com_seguro_pad, perc_matriculas_com_seguro_pad)
print "- sem seguro: %s %s" % (n_matriculas_sem_seguro_pad, perc_matriculas_sem_seguro_pad)
print "- invalidas : %s %s" % (n_matriculas_invalidas_pad, perc_matriculas_invalidas_pad)

Lines 11-14 contain example values for values. This values will not be constant. I just did it like so in order to make tests easier.

The variable names are in my own language (portuguese), sorry about that. But that won't be a problem I hope.

I messed around with a lot of possibilities for this, (.format), but never managed to do it like I wanted too. As I said the code does what it is supposed to do, but I am pretty sure there's a much better way to accomplish this.

Thanks. Cheers.

Recommended Answers

All 2 Replies

Here is a solution which uses a class Record . The problem with your implementation is that you repeat lines of code which look almost the same, which is a sure sign that the code must be improved.

class Record(object):
	def __init__(self, number, desc=""):
		self.number = number
		self.desc = desc
		self.items = list()

	def banner(self):
		return "%s: %d" % (self.desc, self.number)

	def append(self, item):
		self.items.append(item)

	def extend(self, items):
		self.items.extend(items)

	def column(self, k):
		return [ item[k] for item in self.items ]

	def percentages(self):
		p = 100.0 / self.number
		return [ x * p for x in self.column(1) ]

	def lines(self):
		strings = [
			tuple(self.column(0)),
			tuple(str(x) for x in self.column(1)),
			tuple("(%.1f%s)" % (p,"%") for p in self.percentages()),
		]
		sizes = [max(len(s) for s in t) for t in strings]
		just = ["ljust", "rjust", "rjust"]
		for i, t in enumerate(strings):
			attr, size  = just[i], sizes[i]
			strings[i] = tuple(getattr(x, attr)(size) for x in t)
		strings = zip(*strings)
		return ["- %s: %s %s" % s for s in strings ]

record = Record(500, desc="numero de matriculas")
record.extend([
	("com seguro", 412),
	("sem seguro", 8),
	("invalidas", 7),
])

print record.banner()
print("\n".join(record.lines()))

Thanks a lot for your reply. I imagine that it should have taken some time to write it and I appreciate it. Your solution is obviously clever and better than mine, however, I must say that I was looking for a more simpler piece of code.

I am relatively new to python and I am not aware of lots of its capabilities as can been seen from my code in the first post. Certainly there are more ways to do this. Maybe someone else will have other suggestion. Anyway, once again thanks a lot for your post.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.