I have Python code that pulls info from a sqlite database and then write to a html file. I'm trying to write as preformatted text and the code below places the text in columns like I am try to accomplish, but (obviously) the link is the entire length of the string, including the whitespace to the right from the .ljust.
How can I get it to only link the text of item.title instead of the entire string, plus whitespace?
content += '%s %s' % (item.slug, str(item.title).ljust(25), item.date.ljust(10)
Edit
title = str(item.title)
spaces = ' '*(25-len(title)) if len(title) <= 25 else ''
'%s%s %s' % (item.slug, title, spaces, item.date.ljust(10))
If you must do it on one line, the following should work for you:
content += '%s %s %s' % tuple(itertools.chain((item.slug,),
str(item.title).ljust(25).split(" ", 1), (item.date.ljust(10),)))
However the following should be a little easier to read
values = [item.slug]
values += str(item.title).ljust(25).split(" ", 1)
values.append(item.date.ljust(10))
content += '%s %s %s' % values
Notice I've added one extra space to your formatting string to make up for the one lost to the string split operation.
EDIT: The above code fails when item.title is greater than 25 characters. A revised version is below.
title, spaces = (str(item.title).ljust(25)+" ").split(" ", 1)
content += '%s%s %s' % (item.slug, title,
spaces, item.date.ljust(10))
This version adds a space to the end of the justified title, so the split operation is guaranteed to return a tuple of length 2.
Related
Hey I have the following code:
#node.route('/txions')
def transactions():
txions_str = ""
for txion in this_nodes_transactions:
txions_str + "FROM: %s \n TO: %s \n AMOUNT: %d \n" % (txion['from'], txion['to'], txion['amount'])
return txions_str
I get my Python linter complaining that the line is too long for txions_str, what is the correct way to format this line for when using mulitple parameters?
First, it's worth pointing out that you are returning an empty string there...
Anyways, you already have line breaks.
So, break your code to accommodate them
#node.route('/txions')
def transactions():
txions = []
for txion in this_nodes_transactions:
txions.append("FROM: {} ".format(txion['from']))
txions.append(" TO: {} ".format(txion['to']))
txions.append(" AMOUNT: {} ".format(txion['amount']))
return '\n'.join(txions)
Python also supports multi-line strings and line-continuation characters, but those dont seem needed here.
I'm trying to display values in HTML that have a "$" at the beginning, but the way I print out the values in HTML makes it so that with the justification I can only add it at the end of the previous value or at the end of the value.
I'm thinking I have to somehow incorporate the "$" into the for loop, but I'm not sure how to do that.
BODY['html'] += '<br>Total shipped this month:..............Orders........Qty...........Value<br>'
SQL5 = '''
select count(*) as CNT, sum(A.USER_SHIPPED_QTY) as QTY, sum(( A.USER_SHIPPED_QTY) * A.UNIT_PRICE) as VALUE
from SHIPPER_LINE A, SHIPPER B
where B.PACKLIST_ID = A.PACKLIST_ID
and A.CUST_ORDER_ID like ('CO%')
and B.SHIPPED_DATE between ('{}') and ('{}')
'''.format(RP.get_first_of_cur_month_ora(), RP.get_rep_date_ora())
## {} and .format get around the issue of using %s with CO%
print SQL5
curs.execute(SQL5)
for line in curs: ##used to print database lines in HTML
print line
i=0
for c in line:
if i==0:
BODY['html'] += '<pre>' + str(c).rjust(60,' ')
elif i == 1:
BODY['html'] += str(c).rjust(15,' ')
else:
BODY['html'] += str(c).rjust(22,' ') + '</pre>'
i+=1
The "pre" in HTML is used to keep the whitespace and the ' ' after rjust is used to space the numbers properly to go under the column headings. The values that are printed out are generated from the database using the SQL.
Here is what displays in HTML for this code:
Total shipped this month:..............Orders........Qty...........Value
3968 16996 1153525.96
This is what I want it to look like:
Total shipped this month:..............Orders........Qty...........Value
3968 16996 $1153525.96
You could apply the format in the DB by wrapping your sum with a to_char and a currency/numeric format model ...
select to_char(12345.67, 'FML999,999.99') FROM DUAL;
Trying to write to a file with variables, but that is returning error:
template = """1st header line
second header line
There are people in rooms
and the %s
"""
with open('test','w') as myfile:
myfile.write(template.format()) % (variable)
The .format method expects you to template the blanks to be filled in your string with the {}-style, not %s. It also expects the interpolated values to be given as its arguments.
template = """1st header line
second header line
There are people in rooms
and the {}
"""
myfile.write(template.format(variable))
The given string literal is printf-style string. Use str % arg:
with open('test', 'w') as myfile:
myfile.write(template % variable)
To use str.format, you should use placeholder {} or {0} instead of %s.
The Error
myfile.write(template.format()) returns nothing to which you are using % operator to concatenate
Minimal Edit
You can perfectly use %s .The problem is you mismatched parenthesis and the parenthesis i.e. ) should be after your variable as in myfile.write(template.format() % (variable)). But as template.format() is redundant, it can be ignored. Thus the correct way is
myfile.write(template % (variable))
Note:- Any string with an empty format() and no {} in the string returns the string itself
I'm trying to format a dictionary variable to use as a report. I want to recurse through the dictionary and concatenate the items from the dictionary into a formatted string that will be printed/emailed out to users. I'm having issues getting with the string variable (text) losing some of the text concatenated to it.
What I want is:
first \n
\t status: first did not have any updates to apply \n
second \n
\t status: first did not have any updates to apply \n
My function is:
def formatReport(report, text = ""):
for x in report:
if isinstance(report[x], dict):
text += "{0} \n".format(x)
formatReport(report[x], text)
else:
text += "\t{0}: {1} \n".format(x, report[x])
return text
When I call:
report = {'first': {'status': 'first did not have any updates to apply'}, 'second': {'status': 'second did not have any updates to apply'}}
formatReport(report)
I get (note the order of the output is not important to me):
'second \nfirst \n'
After adding a ton of debugging:
def formatReport(report, text = ""):
for x in report:
print "before if: " + text
if isinstance(report[x], dict):
text += "{0} \n".format(x)
print "if: " + text
formatReport(report[x], text)
else:
text += "\t{0} : {1} \n".format(x, report[x])
print "else: " + text
return text
I have narrowed the issue to down to the fact that the text variable is losing the string appended after the else. ie on this line:
text += "\t{0} : {1} \n".format(x, report[x])
So the output of the debugging code after the else is run the first time in the first for loop looks like:
else: second
status : first did not have any updates to apply
When it loops back to the top of the for loop is looks like:
before if: second
From what I have read for loops and if/else statements do not have their own scope as Python does not have block level scoping. I'm at a lose here I have tried all kinds of different combinations or variable names, parameters, etc.... It's worth noting I want to run this code on dictionaries that are 3+ levels deep, hence the need for the recursive call in the if statement.
I show below part of a working script to verify twitter accounts that is giving me the results I want one besides the other, while I want to have them one per line including the title of the find
Example, the first three result are for followers, then how many others are being followed, and in how many lists the user is in, and its giving me the results all in one line something like this:
1350 257 27 and I want it to be as follows
Followers:1,350
Following: 257
Number of lists present: 27
I tried to use " ; " commas, "/n " ; but either it does not work or gives me a 500 Error
Here is the script
All help will be nice
Thank you
................
details = twitter.show_user(screen_name='xxxxxx')
print "content-type: text/html;charset=utf-8"
print
print"<html><head></head><body>"
print (details['followers_count']) #followers
print (details['friends_count'])# following
print (details['listed_count'])# In how many lists
... ....
Instead of the last three print lines, use string formatting to pass in the values.
print "Followers:{}\nFollowing: {}\nNumber of lists present: {}".format(
details['followers_count'], details['friends_count'], details['listed_count']
)
Take a look at the print function. You can write multiple arguments in a tab-separated line like:
print details['followers_count'], details['friends_count'], details['listed_count']
If you want more control over what you print use the join function:
# Add the parts you want to show
stringParts = []
for part in ['followers_count','friends_count','listed_count']:
stringParts.append( part + " = " + str(details[part]) )
seperator = "," # This will give you a comma seperated string
print seperator.join( stringParts )
You can use the % operator
print 'Followers: %s \nFollowing: %s \nNumber of lists present: %s' % (
details['followers_count'], details['friends_count'],
details['listed_count'])