ipython - force executing of expression in any cursor position - python

I have ipython 5.3.0 and when i am in the middle of expression (cursor is marked as <cursor>), for example:
In [69]: x = np.arange(<cursor>1, 21, 2).reshape(2, 5)
Than pressing enter causes split this line into two lines.
In [69]: x = np.arange(
...: 1, 21, 2).reshape(2, 5)
But when i have cursor in other place for example:
In [69]: x = np.<cursor>arange(1, 21, 2).reshape(2, 5)
It executes expression.
Which keyboard shortcut forces execution of expression without taking care of cursor position?
I tried CTRL + ENTER or SHIFT + ENTER but no one of them working for first example.

This was fixed in IPython 5.4. Earlier, there's no way short of patching/monkey-patching at startup, but there's an easy workaround.
Here's the relevant logic from 5.4.1, in IPython/terminal/shortcuts.py. The fragment with a comment referring to the issue on the first link is the fix.
def newline_or_execute_outer(shell):
def newline_or_execute(event):
"""When the user presses return, insert a newline or execute the code."""
b = event.current_buffer
d = b.document
if b.complete_state:
cc = b.complete_state.current_completion
if cc:
b.apply_completion(cc)
else:
b.cancel_completion()
return
# If there's only one line, treat it as if the cursor is at the end.
# See https://github.com/ipython/ipython/issues/10425
if d.line_count == 1:
check_text = d.text
else:
check_text = d.text[:d.cursor_position]
status, indent = shell.input_splitter.check_complete(check_text + '\n')
if not (d.on_last_line or
d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
):
b.insert_text('\n' + (' ' * (indent or 0)))
return
if (status != 'incomplete') and b.accept_action.is_returnable:
b.accept_action.validate_and_handle(event.cli, b)
else:
b.insert_text('\n' + (' ' * (indent or 0)))
return newline_or_execute
As you can see, the action depends on the cursor's position relevant to a code's token.
So, if you have a complete statement, you can force execution by simply pressing End before Enter.

Related

How can I change my output in this scenario? [duplicate]

This question already has an answer here:
Unexpected None in python print statement
(1 answer)
Closed 1 year ago.
So I made this code and its great, but once again the problem is that my output has a 'none' under it. How do I change it. btw, my code is this..
def up_and_down(k):
return (*range(1, k), *range(k, 0, -1))
def diamond(k):
pad = '#'
fill = '*'
w = (2 * k) - 1
for i in up_and_down(k):
print(f'{fill * len(up_and_down(i)):{pad}^{w}}')
print(diamond(k))
def triangle(k):
w = (2 * k) - 1
pad = '#'
fill = '*'
for i in range(1, k+1):
print(f'{fill * len(up_and_down(i)):{pad}^{w}}')
print(triangle(k))
and my output prints out...
######*######
#####***#####
####*****####
###*******###
##*********##
#***********#
*************
#***********#
##*********##
###*******###
####*****####
#####***#####
######*######
None
######*######
#####***#####
####*****####
###*******###
##*********##
#***********#
*************
None
How can I make sure that the image is RETURNED and 'none' doesn't appear under when I use the PRINT statement either??
Btw, I need to use print because its a requirement placed by my professor.
Based on what you described (i.e., need to use print), you need to return a string, and then print that string outside the function.
def up_and_down(k):
return (*range(1, k), *range(k, 0, -1))
def diamond(k):
pad = '#'
fill = '*'
w = (2 * k) - 1
return '\n'.join(f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in up_and_down(k))
def triangle(k):
w = (2 * k) - 1
pad = '#'
fill = '*'
return '\n'.join(f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in range(1, k+1))
k = 10
print(diamond(k))
print(triangle(k))
Without an explicit return, a function returns None. So in your original code, print(diamond(k)) would be like print(None), which is the reason why you see None.
If you can't use \n for a reason I can't understand (but apparently due to your instructor's preference), use the following returns instead (to return a generator of lines, instead of one single multi-line string):
return (f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in up_and_down(k))
return (f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in range(1, k+1))
respectively, and then print the output using
for line in diamond(k):
print(line)
for line in triangle(k):
print(line)

dynamic format the string from tuples of tuple using python

In the below, Scenario 1 is working fine in both (Code 1 & Code 2). But Scenario 2 is not working in Code 1.
My requirement is Tuple should keep on repeating itself until it fills all the formatting string in the Query dynamically. Because where clauses are not constant for all the queries.
Scenario 1#
query = SELECT * FROM test.order where total_price in {}
Tuple:
finTup=((125, 125, 125, 125),)
SELECT * FROM test.order where total_price in (125, 125, 125, 125)
Scenario 2#
query = SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}
Tuple:
finTup=((101, 105, 106, 107), (2, 2, 2, 2))
Code 1:
frt = 'finTup[{}]'
half = ''
val = ''
i = 0
le = len(finTup)
for i in range(le):
print(i)
print(eval(frt.format(i)))
if i == le -1:
half = half + frt.format(i)
val = val + " " + frt.format(i)
else:
half = half + frt.format(i)+', '
val = val + " " + frt.format(i)+', '
temp2 = query.format(eval(val))
Code 2:
if le == 1:
query = query.format(finTup[0])
elif le == 2:
query = query.format(finTup[0], finTup[1])
elif le == 3:
query = query.format(finTup[0], finTup[1], finTup[2])
elif le == 4:
query = query.format(finTup[0], finTup[1], finTup[2], finTup[3])
Error:
temp2 = query.format(eval(val))
IndexError: tuple index out of range
Please help me to fix this.
TL;DR
Hello, you have this error because you are trying to provide a single argument to the format function which expects two parameters (since you have 2 {}).
Note: Avoid using the eval function... That's pretty not recommended, even less in the current situation that you are. Everything can be done without having to evaluate a str.
In what follows, I only run the code for Scenario #2, i.e.
query2 = """SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}"""
finTup = ((101, 105, 106, 107), (2, 2, 2, 2))
Step 1: Debugging
Let's imagine you update your code for debugging as follows:
frt = 'finTup[{}]'
half = ''
val = ''
i = 0 # btw, you don't need to initialize i here
le = len(finTup)
for i in range(le):
if i == le -1:
half = half + frt.format(i)
val = val + " " + frt.format(i)
else:
half = half + frt.format(i)+', '
val = val + " " + frt.format(i)+', '
print val
print eval(val)
temp2 = query.format(eval(val))
Your output should be:
vars[0], vars[1]
((101, 105, 106, 107), (2, 2, 2, 2))
So, imagine you write python code from the above output, what you would do is:
query.format(((101, 105, 106, 107), (2, 2, 2, 2)))
You are actually providing a single parameter of type tuple with a two elements. But what's important here is that you provide format with a single parameter. The format function will try to access the second parameter, which you don't provide. It breaks.
Step 2: Fixing the code
Have a look at this SO article. It shows you how to use the * operator. It basically transforms a list or tuple into a sequence of items. Perfect for functions parameters and so forth.
So, applied to your current case:
temp2 = query.format(*eval(val))
And the trick is done.
Step 3: Optimization
Now, let's trash the Code 1 and use what we've learn with Code 2. We need to unpack the tuple of tuple into parameters to feed in to format. So, why not just do:
# I renamed `finTup` to `vars` since I don't know what it means
def get_query(query, vars):
return query.format(*vars)
It basically combines the logic of Code 1 and Code 2 into a single line.

How to print out a string of a '&', equal to the length of a list

I want to print out a list of the character '&' as many times as there are in a given number. So if the number is 10, I want the result to be '&&&&&&&&&&&'
What I have done is turned the int into a list so I can better visualize what I want to perform.
def print_list_&(size):
"""super serious docstring"""
result_1 = 1
result_2 = size + 1
result = list(range(result_1, result_2))
return result
I'm stuck on where I go from here. This is university work so I'm better off with a push in the right direction than a straight answer.
'&' * 10 will give you '&&&&&&&&&&'. Therefore it seems you just need '&' * size.
Python 2:
N = int(raw_input())
print '&' * N
Python 3:
N = int(input())
print ('&' * N)

Trying to extract values from a PyQt4 QSqlQuery

I keep getting an error saying my value is not positioned on a valid record. I've executed my query successfully in MySQL, but I think I'm overlooking something in my code.
query = QtSql.QSqlQuery("select patient_id," +
"(SUM(IF(uom_id = 1, value, 0)) / SUM(IF(uom_id = 1, 1, 0))) AS `Average radius`," +
"(SUM(IF(uom_id = 2, value, 0)) / SUM(IF(uom_id = 2, 1, 0))) AS `Average Volume`," +
"(SUM(IF(uom_id = 3, value, 0)) / SUM(IF(uom_id = 3, 1, 0))) AS `Average SA`" +
"from measurements" +
"WHERE image_id = " + self.dbImage.id.toString() +
"AND status = 'A'" +
"GROUP BY patient_id", self.db)
query.next()
radius_acc = query.value(1).toDouble()
volume_acc = query.value(2).toDouble()
SA_acc = query.value(3).toDouble()
print('average of previously accepted measurements includes ' +
'radius = ' + str(radius_acc) +
'volume = ' + str(volume_acc) +
'SA = ' + str(SA_acc))
Specifically I want to know if there is something wrong with the way I input the query to QSqlQuery? Or maybe I am trying to use the value(n) method incorrectly?
If neither of those appear to be the case I'll bet I'm using the wrong parameter for self.dbImage.id.toString() in my query, in which case I'll just ask a coworker tomorrow.
To iterate over the result set you usually use a while loop:
while(query.next()){
// do whatever you need with query.value()
}
If you're interested only in the first row, you can use first(), again with a while loop:
while(query.first()){
// do whatever you need with query.value()
}
Edit: Sorry, misunderstood your problem. Now I see that you possibly forgot to put some spaces in some strings:
"from measurements"
to
" from measurements "
#^ Here and here ^^
Without these spaces, your query will look something like
"...d = 3, 1, 0))) AS `Average SA`from measurementsWHERE image_id = ..."
which of course it's not a valid query.

Replace console output in Python

I'm wondering how I could create one of those nifty console counters in Python as in certain C/C++-programs.
I've got a loop doing things and the current output is along the lines of:
Doing thing 0
Doing thing 1
Doing thing 2
...
what would be neater would be to just have the last line update;
X things done.
I've seen this in a number of console programs and am wondering if/how I'd do this in Python.
An easy solution is just writing "\r" before the string and not adding a newline; if the string never gets shorter this is sufficient...
sys.stdout.write("\rDoing thing %i" % i)
sys.stdout.flush()
Slightly more sophisticated is a progress bar... this is something I am using:
def start_progress(title):
global progress_x
sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41)
sys.stdout.flush()
progress_x = 0
def progress(x):
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * (x - progress_x))
sys.stdout.flush()
progress_x = x
def end_progress():
sys.stdout.write("#" * (40 - progress_x) + "]\n")
sys.stdout.flush()
You call start_progress passing the description of the operation, then progress(x) where x is the percentage and finally end_progress()
A more elegant solution could be:
def progress_bar(current, total, bar_length=20):
fraction = current / total
arrow = int(fraction * bar_length - 1) * '-' + '>'
padding = int(bar_length - len(arrow)) * ' '
ending = '\n' if current == total else '\r'
print(f'Progress: [{arrow}{padding}] {int(fraction*100)}%', end=ending)
Call this function with current and total:
progress_bar(69, 100)
The result should be
Progress: [-------------> ] 69%
Note:
For Python 3.6 and below
For Python 2.x.
In python 3 you can do this to print on the same line:
print('', end='\r')
Especially useful to keep track of the latest update and progress.
I would also recommend tqdm from here if one wants to see the progress of a loop. It prints the current iteration and total iterations as a progression bar with an expected time of finishing. Super useful and quick. Works for python2 and python3.
I wrote this a while ago and really happy with it. Feel free to use it.
It takes an index and total and optionally title or bar_length. Once done, replaces the hour glass with a check-mark.
⏳ Calculating: [████░░░░░░░░░░░░░░░░░░░░░] 18.0% done
✅ Calculating: [█████████████████████████] 100.0% done
I included an example that can be run to test it.
import sys
import time
def print_percent_done(index, total, bar_len=50, title='Please wait'):
'''
index is expected to be 0 based index.
0 <= index < total
'''
percent_done = (index+1)/total*100
percent_done = round(percent_done, 1)
done = round(percent_done/(100/bar_len))
togo = bar_len-done
done_str = '█'*int(done)
togo_str = '░'*int(togo)
print(f'\t⏳{title}: [{done_str}{togo_str}] {percent_done}% done', end='\r')
if round(percent_done) == 100:
print('\t✅')
r = 50
for i in range(r):
print_percent_done(i,r)
time.sleep(.02)
I also have a version with responsive progress bar depending on the terminal width using shutil.get_terminal_size() if that is of interest.
It can be done without using the sys library if we look at the print() function
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Here is my code:
def update(n):
for i in range(n):
print("i:",i,sep='',end="\r",flush=True)
time.sleep(1)
For anyone who stumbles upon this years later (like I did), I tweaked 6502's methods a little bit to allow the progress bar to decrease as well as increase. Useful in slightly more cases. Thanks 6502 for a great tool!
Basically, the only difference is that the whole line of #s and -s is written each time progress(x) is called, and the cursor is always returned to the start of the bar.
def startprogress(title):
"""Creates a progress bar 40 chars long on the console
and moves cursor back to beginning with BS character"""
global progress_x
sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = 0
def progress(x):
"""Sets progress bar to a certain percentage x.
Progress is given as whole percentage, i.e. 50% done
is given by x = 50"""
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = x
def endprogress():
"""End of progress bar;
Write full bar, then move to next line"""
sys.stdout.write("#" * 40 + "]\n")
sys.stdout.flush()
The other answer may be better, but here's what I was doing. First, I made a function called progress which prints off the backspace character:
def progress(x):
out = '%s things done' % x # The output
bs = '\b' * 1000 # The backspace
print bs,
print out,
Then I called it in a loop in my main function like so:
def main():
for x in range(20):
progress(x)
return
This will of course erase the entire line, but you can mess with it to do exactly what you want. I ended up make a progress bar using this method.
If I understood well (not sure) you want to print using <CR> and not <LR>?
If so this is possible, as long the console terminal allows this (it will break when output si redirected to a file).
from __future__ import print_function
print("count x\r", file=sys.stdout, end=" ")
Added a little bit more functionality to the example of Aravind Voggu:
def progressBar(name, value, endvalue, bar_length = 50, width = 20):
percent = float(value) / endvalue
arrow = '-' * int(round(percent*bar_length) - 1) + '>'
spaces = ' ' * (bar_length - len(arrow))
sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\
name, width, arrow + spaces, int(round(percent*100))))
sys.stdout.flush()
if value == endvalue:
sys.stdout.write('\n\n')
Now you are able to generate multiple progressbars without replacing the previous one.
I've also added name as a value with a fixed width.
For two loops and two times the use of progressBar() the result will look like:
from time import sleep
max_val = 40
for done in range(max_val):
sleep(0.05)
undone = max_val - 1 - done
proc = (100 * done) // (max_val - 1)
print(f"\rProgress: [{('#' * done) + ('_' * undone)}] ({proc}%)", end='\r')
print("\nDone!")
Progress: [###################_____________________] (47%)
Progress: [########################################] (100%)
Done!
Below code will count Message from 0 to 137 each 0.3 second replacing previous number.
Number of symbol to backstage = number of digits.
stream = sys.stdout
for i in range(137):
stream.write('\b' * (len(str(i)) + 10))
stream.write("Message : " + str(i))
stream.flush()
time.sleep(0.3)
Had the same problem and tried many solutions.
import sys
sys.stdout.write('\r Blablabla')
worked like a charm!

Categories