Is there a way to `return`, `break`, `cycle`, or `stop` on GNUPLOT? - gnuplot

I am writing a script that is creating multiple plots and movies from a very big bunch of data. However, sometimes I don't need the whole analysis and I want to limit myself to parts of the analysis. Just to know,
Is there a way to return, break, cycle, or stop on gnuplot?

The exit statement is straightforward and can be used anywhere in the code.
#!/bin/bash
nmin = 1
nmax = 10
nmiddle = (nmin + nmax)/2
isexit = 0
print "---------------------------------"
print "--------- REGULAR OUTPUTS -------"
do for[i=nmin:nmax]{
print sprintf("Running No %4d", i)
}
# if (isexit==1){
# print "here"
# exit
# }
print ""
print "---------------------------------"
print "--------- EXIT OUTPUTS -------"
do for[i=nmin:nmax]{
print sprintf("Running No %4d", i);
if (i == nmiddle){
exit
}
}
For break and continue, it seems they are new features on GNUPLOT 5.2 and above as you can see in Page 21 (see memo), and are explained on page 71 and 73 (see memo).
I have GNUPLOT 5.0 right now. I will just have to upgrade it to version 5.2 and that's it.
Thanks Ethan and EWCZ.

Related

Horizotal print of a complex string block

Once again I'm asking for you advice. I'm trying to print a complex string block, it should look like this:
32 1 9999 523
+ 8 - 3801 + 9999 - 49
---- ------ ------ -----
40 -3800 19998 474
I wrote the function arrange_printer() for the characters arrangement in the correct format that could be reutilized for printing the list. This is how my code looks by now:
import operator
import sys
def arithmetic_arranger(problems, boolean: bool):
arranged_problems = []
if len(problems) <= 5:
for num in range(len(problems)):
arranged_problems += arrange_printer(problems[num], boolean)
else:
sys.exit("Error: Too many problems")
return print(*arranged_problems, end=' ')
def arrange_printer(oper: str, boolean: bool):
oper = oper.split()
ops = {"+": operator.add, "-": operator.sub}
a = int(oper[0])
b = int(oper[2])
if len(oper[0]) > len(oper[2]):
size = len(oper[0])
elif len(oper[0]) < len(oper[2]):
size = len(oper[2])
else:
size = len(oper[0])
line = '------'
ope = ' %*i\n%s %*i\n%s' % (size,a,oper[1],size,b,'------'[0:size+2])
try:
res = ops[oper[1]](a,b)
except:
sys.exit("Error: Operator must be '+' or '-'.")
if boolean == True:
ope = '%s\n%*i' % (ope,size+2, res)
return ope
arithmetic_arranger(['20 + 300', '1563 - 465 '], True)
#arrange_printer(' 20 + 334 ', True)
Sadly, I'm getting this format:
2 0
+ 3 0 0
- - - - -
3 2 0 1 5 6 3
- 4 6 5
- - - - - -
1 0 9 8
If you try printing the return of arrange_printer() as in the last commented line the format is the desired.
Any suggestion for improving my code or adopt good coding practices are well received, I'm starting to get a feel for programming in Python.
Thank you by your help!
The first problem I see is that you use += to add an item to the arranged_problems list. Strings are iterable. somelist += someiterable iterates over the someiterable, and appends each element to somelist. To append, use somelist.append()
Now once you fix this, it still won't work like you expect it to, because print() works by printing what you give it at the location of the cursor. Once you're on a new line, you can't go back to a previous line, because your cursor is already on the new line. Anything you print after that will go to the new line at the location of the cursor, so you need to arrange multiple problems such that their first lines all print first, then their second lines, and so on. Just fixing append(), you'd get this output:
20
+ 300
-----
320 1563
- 465
------
1098
You get a string with \n denoting the start of the new line from each call to arrange_printer(). You can split this output into lines, and then process each row separately.
For example:
def arithmetic_arranger(problems, boolean:bool):
arranged_problems = []
if len(problems) > 5:
print("Too many problems")
return
for problem in problems:
# Arrange and split into individual lines
lines = arrange_printer(problem, boolean).split('\n')
# Append the list of lines to our main list
arranged_problems.append(lines)
# Now, arranged_problems contains one list for each problem.
# Each list contains individual lines we want to print
# Use zip() to iterate over all the lists inside arranged_problems simultaneously
for problems_lines in zip(*arranged_problems):
# problems_lines is e.g.
# (' 20', ' 1563')
# ('+ 300', '- 465') etc
# Unpack this tuple and print it, separated by spaces.
print(*problems_lines, sep=" ")
Which gives the output:
20 1563
+ 300 - 465
----- ------
320 1098
If you expect each problem to have a different number of lines, then you can use the itertools.zip_longest() function instead of zip()
To collect all my other comments in one place:
return print(...) is pretty useless. print() doesn't return anything. return print(...) will always cause your function to return None.
Instead of iterating over range(len(problems)) and accessing problems[num], just do for problem in problems and then use problem instead of problems[num]
Debugging is an important skill, and the sooner into your programming career you learn it, the better off you will be.
Stepping through your program with a debugger allows you to see how each statement affects your program and is an invaluable debugging tool

Difference resulting from position of print in loops

First question here.
I am picking up Python and have a question that may be quite basic.
I am trying to create this pattern with a nested loop:
x
x
x
xxx
With the code:
numbers = [1,1,1,3]
for count_x in numbers:
output = ""
for count in range(count_x):
output +=x
print(output)
My question is - why does my output change when I move the position of print(output).
The code above works but when I align print(output) with the for count_x in numbers:, I only get "xxx", when I align print(output) to output +=x, I get the following:
x
x
x
x
xx
xxx
which is very odd because there are only 4 items in the list and it shows me 6 lines of output.
Could someone please help? Really puzzled. Thank yall very much.
There's a difference between these two bits of code (fixing the x/"x" problem along the way - your code won't actually work as is unless you have a variable x):
# First:
numbers = [1,1,1,3]
for count_x in numbers:
output = ""
for count in range(count_x):
output += "x"
print(output)
# Second:
numbers = [1,1,1,3]
for count_x in numbers:
output = ""
for count in range(count_x):
output += "x"
print(output)
In the second, the print is done inside the loop that creates the string, meaning you print it out multiple times while building it. That's where your final three lines come from: *, ** and ***. This doesn't matter for all the previous lines since there's no functional difference. Printing a one character string at the end or after adding each of the one characters has the same effect.
In the first, you only print the string after fully constructing it.
You can see this effect by using a slightly modified version that outputs different things for each outer loop:
numbers = [1,1,1,3]
x = 1
for count_x in numbers:
output = ""
for count in range(count_x):
output += str(x)
print(output)
x += 1
This shows that the final three lines are part of a single string construction (comments added):
1 \
2 >- | Each is one outer/inner loop.
3 /
4 \ | A single outer loop, printing
44 >- | string under construction for
444 / | each inner loop.
In any case, there are better ways to do what you want, such as:
numbers = [1,1,1,3]
for count_x in numbers:
print('x' * count_x)
You could probably also do it on one line with a list comprehension but that's probably overkill.

for loop with changed iterator

I can't make the iterator shorter while I'm running on it.
I want to write a function which gets a string and deletes repeating sequences in it.
for example:
if a have the string aaaaabbbbbbbcccccccDDDDDDaaaaa
I should get in return abcDa.
I tried to run over the string with a for loop and every time I see a new letter I will save the letter in a variable which adds up to be the fixed string.
def string_sequence_fixing(string):
c = ''
for char in my_str:
if c != char:
c = char
else:
my_str = my_str.replace(c, '', my_str.count(c) - 1)
return my_str
The problem I want to avoid is too many iterations.
When I see a new character I want to delete all the other sequences of it,
but the second line from the end does not update the "condition" in the for a loop.
Short Answer: loops don't work that way.
Longer answer:
Here is some simple pseudo code, for your perusal:
j=99
print "J is " j
for j=0;20;5
print j \t
end
print "Now J is " j
The output may surprise you.
run
J is 99
0 5 10 15 20
Now J is 99
The reason is: the variable j in the loop is NOT the as the j variable outside the loop.
I like to use the term "stack" (some languages claim they don't use a stack. In those cases I call it a "not-stack stack). The stack simple means a temporary storage space in memory.
The initial variable "j" goes into the "program data space". The loop variable "j" goes into the "stack data space."
Using a variable doesn't 'really' mean you are using a variable, it's just a mnemonic to a memory space. Let's have another look at that sample code:
pointer-to-program-space-variable-named-j = 99 (poke into memory location 1:4500)
pointer-to-stack-space-variable-named-j = 0 (poke into memory location 87:300)
print pointer-to-stack-space-variable-named-j followed by tab
increment pointer-to-stack-space-variable-named-j by 5
repeat until pointer-to-stack-space-variable-named-j = 20
print pointer-to-program-space-variable-named-j
With this knowledge, let's look at your code to see what is going on:
def string_sequence_fixing(string):
c = ''
for char in *STACK*.my_str:
if c != char:
c = char
else:
my_str = my_str.replace(c, '', *PROGRAM*.my_str.count(c) - 1)
return my_str
See how they are different variables? NEVER assume that a loop variable and a program variable are the same. You need to redo you algorithm to accomplish what you want to do.
Also, see the link provided by #David Cullen.
You can use groupby() from itertools. Code is like:
data = 'aaabbbcccDDDDDEfggghiij'
from itertools import groupby
dataN = ''
for d in groupby(data):
dataN += d[0]
print(dataN)
output:
abcDEfghij

Python Counting the exchanges in a selection sort

I apologize as this is my first question on this site and it is extremely basic, but I am somewhat lost in a current lab I am trying to complete.
Currently I am attempting to count the amount of exchanges(Or swaps? Not sure on the right word there!) during a selection sort throughout the passes.
Now according to my current understanding, the replacement section of our formula is traversing my list. However, it doubles the amount of swaps it is actually supposed to be spitting back at me. Now this would lead me to believe an if statement might need to be operating in the outer loop, but that doesn't seem quite right to me.
An example of what I have done to cause this problem below. I am curious if I am on the right path or should I slash and burn or go back to the drawing board.
The reason I am counting them independently is I am displaying when there is a swap then a grand total of all the swaps. Which I find to be a bit ironic as with a selection sort you can only have 1 swap per pass?
Any case, I apologize for the rather basic question, but I seem to be missing something so I was hoping someone could point me in the right direction of if I should be focusing on the outer loop to determine the exchanges?
print( "Original list:" , a_list, "\n" )
count =1
n = len(a_list)
comp = n -1
exchanges=1
comp_total=0
exch_total=0
for end in range(n, 1, -1): # Each pass starts here
#Setting our running total to adjust for previous value.
comp_total +=comp-(count-1)
print("Pass", count, ":", "Comparisons:",comp-(count-1), "\tExchanges:", exchanges,"\n", end="\t ")
count += 1
# --- Search for Largest ---
min_position = 0
for i in range(1, end):
if a_list[i] > a_list[min_position]: # Perform n
min_position = i
exchanges = 0
exch_total +=1
else:
exchanges = 1
# --------------------------
temp = a_list [end - 1] # Perform exchange
a_list [end - 1] = a_list [min_position]
a_list [min_position] = temp
print(a_list)
print()
print("\tTotal Comparisons:",comp_total, "Total Exchanges:", exch_total)
selection_sort(a_list)
In this case,
My issue was the the fact my print statement was before the actual loop, this was throwing off my count, by placing the if statement past this point, I was able to get an accurate running total!
Cheers!

Beginner Python: Where to "while"?

tl;dr: My code "works", in that it gives me the answer I need. I just can't get it to stop running when it reaches that answer. I'm stuck with scrolling back through the output.
I'm a complete novice at programming/Python. In order to hone my skills, I decided to see if I could program my own "solver" for Implied Equity Risk Premium from Prof. Damodaran's Valuation class. Essentially, the code takes some inputs and "guesses and tests" a series of interest rates until it gets a "close" value to the input.
Right now my code spits out an output list, and I can scroll back through it to find the answer. It's correct. However, I cannot for the life of me get the code to "stop" at the correct value with the while function.
I have the following code:
per = int(input("Enter the # of periods forecast ->"))
divbb = float(input("Enter the initial dividend + buyback value ->"))
divgr = float(input("Enter the div + buyback growth rate ->"))
tbondr = float(input("Enter the T-Bond rate ->"))+0.000001
sp = int(input("Enter the S&P value->"))
total=0
pv=0
for i in range(1,10000):
erp = float(i/10000)
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for i in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),i)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
From his example, with the inputs:
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
By scrolling back through the output, I can see my code produces the correct minimum at epr=0.0755.
My question is: where do I stick the while to stop this code at that minimum? I've tried a lot of variations, but can't get it. What I'm looking for is, basically:
while (sp-total) > |1|, keep running the code.
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
total=0
pv=0
i = 1
while(abs(sp-total)) > 1:
erp = i/10000.
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for j in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),j)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
i += 1
should work. Obviously, there are a million ways to do this. But the general gist here is that the while loop will stop as soon as it meets the condition. You could also test every time in the for loop and include a break statement, but because you don't know when it will stop, I think a while loop is better in this case.
Let me give you a quick rundown of two different ways you could solve a problem like this:
Using a while loop:
iterator = start value
while condition(iterator):
do some stuff
increment iterator
Using a for loop:
for i in xrange(startvalue, maxvalue):
do some stuff
if condition:
break
Two more thing: if you're doing large ranges, use the generator xrange. Also, it's probably a bad idea to reuse i inside your for loop.
I recommend CS101 from Udacity.com for learning Python. Also, if you're interested in algorithms, work through the problems at projecteuler.com

Resources