Printing a dict in python3 when python2 statement no longer works - python-3.x

I had the following print statement in my python2 program (after '-' sign) and replaced it with some more elaborate python3 code (after '+' sign). Is there a better i.e. more elegant way to do this?
- print("%(txn_processed)8d %(txn_skip)5d %(txn_ctr)5d")%accounts[account]
+ acc_ctrs = accounts[account]
+ processed = accounts[account]['txn_processed']
+ skipped = accounts[account]['txn_skip']
+ ctr = accounts[account]['txn_ctr']
+ print('%8d %5d %5d'%(processed, skipped, ctr))
The dictionary accounts has one entry per account with 3 counters in a sub dictionary. So I process the accounts in a for account in accounts: loop and separate the 3 counters into processed, skipped and sum. This is what the output looks like (specifically the last 2 lines):
Output to ofx (GnuCash version)
TRANSACTIONS: 248
IN: 2018-008-transactions-30-12-to-26-09.csv
OUT: 2018-008-transactions-30-12-to-26-09.ofx
accountnumber processed skip sum
NL89RABO0000000000 231 0 231
NL71RABO1111111111 1 16 17
My knowledge of python3 is limited. Hope you guys can help me out.
P.S. the python2 line returned an error message about NoneType and Dict.
Kind regards, Guus.

print is a function in python 3, but you have confusing parentheses:
Python 2 interpretation is as follows:
print ("%(txn_processed)8d %(txn_skip)5d %(txn_ctr)5d") % accounts[account]
# ^----------------------- argument to print ---------------------------------------^
In fact, these parens around a string were entirely unnecessary in python 2.
Python 3 interpretation is to treat parentheses as arguments, as any regular function/method:
print ("%(txn_processed)8d %(txn_skip)5d %(txn_ctr)5d") % accounts[account]
# ^------------- argument to print --------------^
And print returns None, and you are trying to call __rem__ on it. That's why you have an error.
All you need to do to fix it for Python 3 is to wrap everything in parentheses instead of just the string you'll be formatting:
print("%(txn_processed)8d %(txn_skip)5d %(txn_ctr)5d" % accounts[account])
# ^------------- argument to print ---------------------------------^

acc_ctrs = accounts[account]
print('%8d %5d %5d'%(
acc_ctrs['txn_processed'],
acc_ctrs['txn_skipped'],
acc_ctrs['txn_ctr']
))

To print dict in elegant way, use this:
import pprint
pprint.pprint(dict)
You'll get the output in readable way.

Related

What's x for x in input()?

I am new to coding and is trying to solve this python question
Question:
Write a program that calculates and prints the value according to the given formula:
Q = Square root of [(2 * C * D)/H]
Following are the fixed values of C and H:
C is 50. H is 30.
D is the variable whose values should be input to your program in a comma-separated sequence.
Example
Let us assume the following comma separated input sequence is given to the program:
100,150,180
The output of the program should be:
18,22,24
Hints:
If the output received is in decimal form, it should be rounded off to its nearest value (for example, if the output received is 26.0, it should be printed as 26)
In case of input data being supplied to the question, it should be assumed to be a console input.
This is the solution given. I have not seen 'x for x in input()'expression, may I know what does this expression do ?
import math
c=50
h=30
value = []
items=[x for x in input().split(',')]
for d in items:
value.append(str(int(round(math.sqrt(2*c*float(d)/h)))))
print (','.join(value))
This is my own solution but somehow I got a syntax error.
def sr(D):
For item in D:
return ((2*50*D)/30)**0.5
try:
a=int(input())
j=a.split(",")
print(sr(j))
except:
print('Please enter an integers or intergers seperated by comma')
The x is just a variable that gets assigned to the input that comes in via the input() function.
If you're aware of C style language (or Java), it's similar to
for(int i=0;<some_condition>;<some_operation>){}
This is just a condensed, pythonic and easy to read way to do this.
You can read more Python loops here
https://wiki.python.org/moin/ForLoop

How to count number of substrings in python, if substrings overlap?

The count() function returns the number of times a substring occurs in a string, but it fails in case of overlapping strings.
Let's say my input is:
^_^_^-_-
I want to find how many times ^_^ occurs in the string.
mystr=input()
happy=mystr.count('^_^')
sad=mystr.count('-_-')
print(happy)
print(sad)
Output is:
1
1
I am expecting:
2
1
How can I achieve the desired result?
New Version
You can solve this problem without writing any explicit loops using regex. As #abhijith-pk's answer cleverly suggests, you can search for the first character only, with the remainder being placed in a positive lookahead, which will allow you to make the match with overlaps:
def count_overlapping(string, pattern):
regex = '{}(?={})'.format(re.escape(pattern[:1]), re.escape(pattern[1:]))
# Consume iterator, get count with minimal memory usage
return sum(1 for _ in re.finditer(regex, string))
[IDEOne Link]
Using [:1] and [1:] for the indices allows the function to handle the empty string without special processing, while using [0] and [1:] for the indices would not.
Old Version
You can always write your own routine using the fact that str.find allows you to specify a starting index. This routine will not be very efficient, but it should work:
def count_overlapping(string, pattern):
count = 0
start = -1
while True:
start = string.find(pattern, start + 1)
if start < 0:
return count
count += 1
[IDEOne Link]
Usage
Both versions return identical results. A sample usage would be:
>>> mystr = '^_^_^-_-'
>>> count_overlapping(mystr, '^_^')
2
>>> count_overlapping(mystr, '-_-')
1
>>> count_overlapping(mystr, '')
9
>>> count_overlapping(mystr, 'x')
0
Notice that the empty string is found len(mystr) + 1 times. I consider this to be intuitively correct because it is effectively between and around every character.
you can use regex for a quick and dirty solution :
import re
mystr='^_^_^-_-'
print(len(re.findall('\^(?=_\^)',mystr)))
You need something like this
def count_substr(string,substr):
n=len(substr)
count=0
for i in range(len(string)-len(substr)+1):
if(string[i:i+len(substr)] == substr):
count+=1
return count
mystr=input()
print(count_substr(mystr,'121'))
Input: 12121990
Output: 2

How to prevent f.write to output the number of characters written?

I use Python3 and write result into a file like this:
with open(output,'w') as f:
f.write('Line count of the log files is: ' + str(line_count) + '. \n')
f.write() automatically returns # of characters written, is there a way to do not output it? I ask this because I do not want it output.
Thanks.
This is not unique to file.write(). The interactive interpreter prints the result of any evaluated expression that does not result in None.
>>> for i in range(3):
... i # expression evaluates to the value of i
...
0
1
2
>>>
Two things to note. First, these won't be displayed when you are not using the interactive interpreter, so it's safe to ignore.
Second, you can make the display go away by assigning the result. That turns the expression into a statement.
>>> for i in range(3):
... _ = i # underscore is a nice meaningless variable name
...
>>>

I want to remove the last end sign from the end of the list

>>> for i in range(4):
... print(i, end=" :-) ")
...
0 :-) 1 :-) 2 :-) 3 :-) >>>
I want to remove the last :-) after 3.
I can think of three reasonable ways to do this.
The first is to explicitly examine the values you're iterating on to decide what kind of end you want to pass to print. Since you're iterating directly on a range, this is pretty easy, just test for the last value:
for i in range(4):
print(i, end=" :-) " if i < 3 else "\n")
I used a "ternary" expression (x if c else y) to switch the smiley for a newline to follow the last value. If your range was not always the same size (e.g. it was range(x)), you could test i < x-1 in the conditional expression.
The second approach is to use str.join to combine your items into a single string with the separators already baked in, then pass the single string to print with no special end argument:
print(" :-) ".join(str(i) for i in range(4)))
The last option is available in Python 3 (and in the later versions of Python 2 if you use from __future__ import print_function to get the Python 3 version of print). It is to use argument unpacking to pass the whole range of numbers to the print function at once, and pass the smiley as the sep argument rather than end:
print(*range(4), sep=" :-) ")
This is probably the nicest solution. Enabling this kind of code was one of the main reasons that print became a function in Python 3 (you couldn't unpack a sequence as arguments to the Python 2 print statement).

Interpreter-style output in Python 3 (maybe about sys.displayhook?)

I'm making a little toy command window with Tk, and currently trying to make it copy some interpreter behavior.
I'd never scrutinized the interpreter before, but it's decisions on when to print a value are a little mystifying.
>>> 3 + 4 # implied print(...)
7
>>> 3 # implied print(...)
3
>>> a = 3 # no output, no implied print(...), bc result is None maybe?
>>> None # no output, no print(...) implied... doesn't like None?
>>> print(None) # but it doesn't just ban all Nones, allows explicit print()
None
>>> str(None) # unsurprising, the string 'None' is just a string, and echoed
'None'
The goal is to mimic this behavior, printing some Nones, not others (made slightly more complicated because I'm not entirely sure what the rules are).
So, turning to my program, I have history_text and entry_text, which are StringVar()s that control a label above an entry box in the Tk window. Then the following event is bound to the Return key, to process commands and update the history with the result.
def to_history(event):
print("command entered") # note to debugging window
last_history = history_text.get()
# hijack stdout
buffer = io.StringIO('')
sys.stdout = buffer
# run command, output to buffer
exec(entry_text.get())
# buffered output to a simple string
buffer.seek(0)
buffer_str = ''
for line in buffer.readlines():
# maybe some rule goes here to decide if an implied 'print(...)' is needed
buffer_str = buffer_str + line + '\n'
# append typed command for echo
new_history = entry_text.get() + '\n' + buffer_str
# cleanup (let stdout go home)
sys.stdout = sys.__stdout__
buffer.close()
history_text.set(last_history + "\n" + new_history)
entry_text.set('')
As is, it does not provide any output for a simple entry of '3' or 'None' or even '3 + 4'. Adding an implied print() statement all the time seems to print too often, I don't skip the print for 'None' or 'a = 3' type statements.
I found some documentation for sys.displayhook, which seems to govern when the interpreter will actually display a result, but I'm not sure how to use it here. I thought I could just wrap sys.displayhook() around my exec() call, and have it do all this work for me... but found that it does not imply print() statements for statements like '3 + 4' or '3'.
Any suggestions? Am I on the right track with sys.displayhook?
The interpreter prints out repr(result) only if result is not None.
There are no "implied prints" like you thought.
3 + 4 results to 7, so repr(7) is printed
a = 3 is an assignment, I think nothing is printed because it does not work with eval
None results to None, so nothing is printed
print(None) results to None (because the print function returns nothing), so nothing is printed. However, the print function itself printed the None.
I honestly didn't read your code, but here's a function that takes a string with code and produces the same output as the interpreter would:
def interactive(code):
try:
result = eval(code)
if result is not None:
print(repr(result))
except SyntaxError:
exec(code)

Resources