Halcon - Variable iconic variable name - variables

I have follwoing code:
for i:=0 to num_stripes by 1
R := Row1 + 5*i
gen_rectangle1(TransStripe, R,Column1,R+4, Column2)
intersection(TransStripe, LabelSelcted, RegionIntersection)
smallest_rectangle1(RegionIntersection, dummy, BeginCol, dummy, EndCol)
inizio := BeginCol - 5
fine := EndCol + 5
area_center(RegionIntersection, dummy, centro_row, centro_col)
gen_rectangle1(Str, R, inizio, R+4, fine)
dev_set_color('red')
dev_display(Str)
endfor
In the last few lines, I create a rectangle named Str. Is there a way to create names on the fly, so that i have a variable for each rectangle? Str1, Str2 ...

Unfortunately, there isn't a direct way to do this. There are a few workarounds:
Concatenating objects:
gen_empty_obj (EmptyObject)
for Index := 1 to 5 by 1
gen_rectangle1 (Rectangle, 30, 20, 100, 200*Index)
concat_obj (EmptyObject, Rectangle, EmptyObject)
endfor
** Selecting
select_obj (EmptyObject, ObjectSelected, 3)
Using vectors (Halcon 12+ version required)
for Index := 0 to 4 by 1
gen_rectangle1 (Rectangle.at(Index), 30, 20, 100, 200*(Index+1))
endfor
** Selecting
Object := Rectangle.at(2)
It is also possible to use vectors as structures and adding multiple levels, where one level would be the names and other objects or values. If you'd like to read more about it, I wrote an article: https://subpixel.hr/halcon-is-like-a-box-of-chocolates/

Related

Sorting/Optimization problem with rows in a pandas dataframe [duplicate]

So if I was given a sorted list/array i.e. [1,6,8,15,40], the size of the array, and the requested number..
How would you find the minimum number of values required from that list to sum to the requested number?
For example given the array [1,6,8,15,40], I requested the number 23, it would take 2 values from the list (8 and 15) to equal 23. The function would then return 2 (# of values). Furthermore, there are an unlimited number of 1s in the array (so you the function will always return a value)
Any help is appreciated
The NP-complete subset-sum problem trivially reduces to your problem: given a set S of integers and a target value s, we construct set S' having values (n+1) xk for each xk in S and set the target equal to (n+1) s. If there's a subset of the original set S summing to s, then there will be a subset of size at most n in the new set summing to (n+1) s, and such a set cannot involve extra 1s. If there is no such subset, then the subset produced as an answer must contain at least n+1 elements since it needs enough 1s to get to a multiple of n+1.
So, the problem will not admit any polynomial-time solution without a revolution in computing. With that disclaimer out of the way, you can consider some pseudopolynomial-time solutions to the problem which work well in practice if the maximum size of the set is small.
Here's a Python algorithm that will do this:
import functools
S = [1, 6, 8, 15, 40] # must contain only positive integers
#functools.lru_cache(maxsize=None) # memoizing decorator
def min_subset(k, s):
# returns the minimum size of a subset of S[:k] summing to s, including any extra 1s needed to get there
best = s # use all ones
for i, j in enumerate(S[:k]):
if j <= s:
sz = min_subset(i, s-j)+1
if sz < best: best = sz
return best
print min_subset(len(S), 23) # prints 2
This is tractable even for fairly large lists (I tested a random list of n=50 elements), provided their values are bounded. With S = [random.randint(1, 500) for _ in xrange(50)], min_subset(len(S), 8489) takes less than 10 seconds to run.
There may be a simpler solution, but if your lists are sufficiently short, you can just try every set of values, i.e.:
1 --> Not 23
6 --> Not 23
...
1 + 6 = 7 --> Not 23
1 + 8 = 9 --> Not 23
...
1 + 40 = 41 --> Not 23
6 + 8 = 14 --> Not 23
...
8 + 15 = 23 --> Oh look, it's 23, and we added 2 values
If you know your list is sorted, you can skip some tests, since if 6 + 20 > 23, then there's no need to test 6 + 40.

How do I return the sum of array with exceptions by using a while loop in a function?

Python beginner here.
I already have the solution to the question but I'm not understanding why the "add" variable in the solution plays a role of creating exceptions to remove numbers between 6 and 9. I already tried Python Tutor but still not understanding. Many thanks in advance!
QUESTION: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.
Sample Solution code
def summer_69(arr):
total = 0
add = True
for num in arr:
while add:
if num != 6:
total += num
break
else:
add = False
while not add:
if num != 9:
break
else:
add = True
break
return total
Sample answers:
summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14
You can think of the variable "add" as a flag. I think that might be a better name for this variable in this instance.
It is only being used to tell if you have run into a 6 within the sequence of numbers in the array, then once it has been set it goes through an arbitrary amount of numbers in the array until it gets a 9 and then it resets the flag.
It may help to rename the variable "add" as "flag". Have your new variable "flag" default to False and then if you run into a 6 set "flag" to true. Once the flag is on do not add any trailing numbers in the sequence until you run into the number 9 then reset to false.
Perhaps that will help the readability. Naming variables is the hardest part of programming.

FIle handling in Eiffel

Given a file input.txt, which consists of a number of elements in arrays and elements in the arrays, I should read the data and copy it to arrays in Eiffel. For example, for
3
3 4 5
2 3 1
I should get len = 3, a1 = {3,4,5}, a2 = {2,3,1}.
I have tried the following but it was not successful
take_input
-- Read user's input.
local
input: PLAIN_TEXT_FILE
output: PLAIN_TEXT_FILE
itr: INTEGER
do
create input.make_open_read ("input.txt")
input.read_integer
len := input.last_integer
create output.make_open_write ("output.txt")
create num.make_filled (0, 1, len)
create rem.make_filled (0, 1, len)
from
input.start
input.read_integer
itr := 0
until
input.off
loop
itr := itr + 1
if itr <= len then
num [itr] := input.last_integer
input.read_integer
else
rem [itr - len] := input.last_integer
input.read_integer
end
end
input.close
end
Here Is there any way I can continously read the inputs rather than again starting from the Begginning of the file?
There is no need to go to the beginning of the file after reading the number of elements. Therefore, removing input.start right after from will do the trick.
As a sanity check (in case it matters for your program), it makes sense to test whether len is positive before starting the loop.

Why does Perl 6 try to evaluate an infinite list only in one of two similar situations?

Suppose I define a lazy, infinite array using a triangular reduction at the REPL, with a single element pasted onto the front:
> my #s = 0, |[\+] (1, 2 ... *)
[...]
I can print out the first few elements:
> #s[^10]
(0 1 3 6 10 15 21 28 36 45)
I'd like to move the zero element inside the reduction like so:
> my #s = [\+] (0, |(1, 2 ... *))
However, in response to this, the REPL hangs, presumably by trying to evaluate the infinite list.
If I do it in separate steps, it works:
> my #s = 0, |(1, 2 ... *)
[...]
> ([\+] #s)[^10]
(0 1 3 6 10 15 21 28 36 45)
Why doesn't the way that doesn't work...work?
Short answer:
It is probably a bug.
Long answer:
(1, 2 ... *) produces a lazy sequence because it is obviously infinite, but somehow that is not making the resulting sequence from being marked as lazy.
Putting a sequence into an array #s causes it to be eagerly evaluated unless it is marked as being lazy.
Quick fix:
Append lazy to the front.
> my #s = [\+] lazy 0, |(1, 2 ... *)
[...]
> #s[^10]
(0 1 3 6 10 15 21 28 36 45)

Crystal Formula field - Splitting a string array of numbers, summing them, and returning the total returns a boolean instead of a number

This is in Crystal reports 2008, all service packs installed.
I'm trying to use a formula field to take a string field of space delimited numbers, sum them and return the total.
Code below. Always displays true on the report in preview and printed. Not entirely sure if I'm formatting the field box on the report wrong or if the output is wrong but I'm sure it's something silly.
Any pointer in the right direction would be super appreciated!
//Sample Field Values
//4.00 12.00 13.5 1 1 1 1
//3.00 12.50 13.5 1 1.5 1.5 1.5
Numbervar LabourHrsINT;
Local Numbervar i;
Stringvar Array output:= Split({CR_VEH_HIST_.LABHRS}," ");
LabourHrsINT := 0;
for i := 1 to ubound(output) do (
LabourHrsINT := LabourHrsINT + (if NumericText(output[i]) then
Val(output[i]))
);
Your formula is not evaluating to the value of the sum. The last thing in your formula should be the final value of LabourHrsINT.
Numbervar LabourHrsINT:=0;
Local Numbervar i;
Stringvar Array output:= Split({CR_VEH_HIST_.LABHRS}," ");
for i := 1 to ubound(output) do (
if NumericText(output[i]) then
LabourHrsINT := LabourHrsINT + Val(output[i])
);
LabourHrsINT
I would suggest doing the numeric check first and then doing the addition.
(if NumericText(output[i]) then
LabourHrsINT := LabourHrsINT + Val(output[i]))