Setting up basic pararrayfun in GNU Octave - multithreading

I have a file testPowr.m
function testPowr(x)
printf(x^2)
end
I am trying the following in another file main.m in the same folder as testPowr.m:
clear; clc;
pkg load parallel;
vector = 1:10;
fun = #(x) x^2;
pararrayfun(nproc, #(n) testPowr(n), vector)
%a2 = pararrayfun(nproc, fun, vector)
But testPowr seems not visible to pararrayfun as the commented line above works. I have tried multiple different syntax but I am unable to get it right.
I am getting the following error in one of the syntax:
execution error
error: __parcellfun_get_next_result__: could not receive result
error: called from
parcellfun at line 201 column 16
pararrayfun at line 85 column 28
main at line 5 column 1

The problem is that testPowr does not return a value.
pararrayfun collects the return value of each function call but all your function does is print the result to stdout. You can fix this by returning something, like so:
function xp = testPowr (x)
xp = x^2;
endfunction
Your script will then work fine:
octave> pkg load parallel;
octave> rv = pararrayfun (nproc, #(n) testPowr(n), 1:10)
parcellfun: 10/10 jobs done
rv =
1 4 9 16 25 36 49 64 81 100

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

How to use Fortran to read the face information from a *.obj file

Problem
How can modern Fortran navigate a file with double forward slashes between entries, as in the *.obj format? The goal is to extract the vertex index (first entry) and ignore the vertex normal index (second entry).
Example
For example, for this snippet,
f 297//763 298//763 296//763
f 296//764 298//764 295//764
f 384//765 385//765 382//765
f 384//766 382//766 383//766
the goal is to create an array like this:
face ( 1 ) = [297, 298, 296]
face ( 2 ) = [296, 298, 295]
face ( 3 ) = [384, 385, 382]
face ( 4 ) = [384, 382, 383]
Extra points for an answer which would adopt to a richer format like
f a//b//c d//e//f g//h//i j//k//l
Other posts
The answer for [How to get Wavefront .obj file with 3 faces (traingle) points to a deleted blog. This post [How to read numeric data from a string in FORTRAN was not relevant.
References
Three references on the *.obj format:
Object Files (.obj), B1. Object Files (.obj), Wavefront .obj file
As suggested in the comments, we can replace / by a space using sed etc. We can also scan each character one by one in Fortran (see below). We then read in all integers into vals and select the desired part as vals( 1:6:2 ). A similar approach can be used for f a//b//c d//e//f ... etc by changing 1:6:2 to 1:12:3 etc.
[test.f90]
program main
implicit none
character(100) buf
integer vals(10), ios, i
open(10, file="test.dat", status="old")
do
read(10, "(a)", iostat=ios) buf
if (ios /= 0) exit
do i = 1, len(buf)
if (buf(i:i) == "/") buf(i:i) = " " !! replace "/" by " "
enddo
read(buf(2:), *) vals( 1:6 ) !! read all items
print *, vals( 1:6:2 ) !! select items 1, 3, 5
enddo
close(10)
end
[test.dat]
f 297//763 298//763 296//763
f 296//764 298//764 295//764
f 384//765 385//765 382//765
f 384//766 382//766 383//766
$ gfortran test.f90 && ./a.out
297 298 296
296 298 295
384 385 382
384 382 383
Just for fun, here is a similar code in Python, which is shorter thanks to replace() and split(). If we have some similar routines, I guess the above code may also become shorter.
dat = []
for line in open("test.dat").readlines():
dat.append( line[1:] .replace("/", " ") .split() [::2] )
import numpy as np
face = np.array(dat, dtype=int)
print(face)
$ python test.py
[[297 298 296]
[296 298 295]
[384 385 382]
[384 382 383]]

How to write function that returns a list of strings

Have some problems about the code below line 20.
Question:
The function returns a list of 50 strings that are at
the center of the file.
A file has n lines, then n/2 is the center. A list of length 50 is returned, where the first line is n/2 -25 and the last line is n/2 + 25.
If the file has n < 50 lines, then only those lines are returned.
If there are no lines in the file, an empty list object is returned.
If the file cannot be opened because it does not exist, you must catch the FileNotFoundError object and throw a new exception FileNotFoundError with the contents of the exception being the filename. Any other exception for failure to open a file is not caught.
If the parameter filename is not a string type, then a TypeError exception is thrown with the contents of the exception being a string "parameter filename is not a string".
Examples:
the file has 200 lines. lines 75 - 124 are returned
the file has 201 lines. lines 75 - 124 are returned (n is an odd number)
the file has 202 lines. lines 76 - 125 are returned
the file has 700 lines. lines 325 - 374 are returned
the file has 10 lines. lines 1 - 10 are returned
See appendix for open(), close(), readlines() and isinstance() to support this question.
Restrictions:
Only Allowed: while loops, if statements, function len(), type(), isinstance(), list method append(),
string method split(), format(). keywords elif, else, return, break, continue, def, self, None, try,
raise, except, is, import sys, and any arithmetic or boolean comparison operators
def get_first_and_last_24(filename):
if type(filename)!=str:
raise TypeError('parameter filename is not a string')
try:
f=open(filename)
except FileNotFoundError:
raise FileNotFoundError(filename)
lines=f.readlines()
len(lines)=length
f.close()
if len(lines)==0:
return []
n=[]
index=0
while index<len(lines):
if len(lines)<50:
n.append(lines[index])
index+=1
elif len(lines)>=50
if length%2==0:
if (index/2-25)<index and index < (index/2+25):
n.append(lines[index])
index+=1
elif length%2!=0:
if ((index-1)/2-25)<index and index<((index-1)/2+25):
n.append(lines[index])
index+=1
return n
print(get_first_and_last_24('tfre.tx'))
actual results:
File "3beater.py", line 20
elif len(lines)>=50
^
SyntaxError: invalid syntax
The error message is pointing you to look at the validity of your syntax. In this case you are missing a a colon. It should be elif len(lines)>=50:

How can i deobfuscate this text?

I've recently found some lua code and what I found inside was some obfuscated string. That made me wonder what sort of obfuscation technique was used there. Does anybody have an idea?
240.06230.0575240.06240.06270.0675250.0625265.06625270.0675250.0625285.07125260.065260.065260.065250.0625265...
https://pastebin.com/raw/7RkxjWQw
If this string is splitted into xxx.yyyy... chunks (exactly three digits before decimal point), then multiply each number by 800/4001 (the results will be integer!), then convert these integer numbers to ASCII, the hidden sequence of 16 floating point numbers would be revealed:
0.0062562944425795
0.036286507766961
0.02127140110477
0.047547837763604
0.041291543321025
0.0025025177770318
0.011261329996643
0.018768883327738
0.017517624439223
0.042542802209541
0.037537766655477
0.016266365550707
0.0087588122196113
0.057557908871731
0.025025177770318
0.026276436658834
Is the puzzle stops here?
Or should we try to decipher it further?
Ok, we could multiply them all by 32767/41 (the results will be integer!)
5
29
17
38
33
2
9
15
14
34
30
13
7
46
20
21
Hmm, the puzzle seems to be really interesting...
Is it the end?
Just googled it.
That's the passwords encrypted, something Roblox-related
So, OP surely doesn't have decoder script :-)
Ok, finally did it.
function decode_password(encoded_password)
local result = ""
local buffer = ""
for x in encoded_password:gsub("%d%d%d%.", "\0%0"):gmatch"%Z+" do
x = math.floor(tonumber(x) / 5.00125 + 0.5)
if x ~= 95 then
buffer = buffer..string.char(x)
elseif buffer ~= "" then
x = math.floor(tonumber(buffer) * 799.195122 + 0.5)
result = result..("qazwsxedcrfjmik,o0 23456-=\\vtgbyhnul.p;;;/[']1789"):sub(x, x)
buffer = ""
end
end
return result
end
Example 1:
local p = '240.06230.0575240.06240.06270.0675250.0625265.06625270.0675250.0625285.07125260.065260.065260.065250.0625265.06625275.06875285.07125265.06625475.11875240.06230.0575240.06255.06375270.0675250.0625280.07270.0675265.06625240.06275.06875275.06875270.0675270.0675285.07125270.0675245.06125475.11875240.06230.0575240.06250.0625245.06125250.0625275.06875245.06125260.065240.06245.06125245.06125240.06260.065275.06875275.06875475.11875240.06230.0575240.06260.065275.06875265.06625260.065275.06875280.07255.06375275.06875275.06875270.0675255.06375270.0675240.06260.065475.11875240.06230.0575240.06260.065245.06125250.0625285.07125245.06125265.06625260.065255.06375255.06375250.0625245.06125240.06250.0625265.06625475.11875240.06230.0575240.06240.06250.0625265.06625240.06250.0625265.06625245.06125275.06875275.06875275.06875275.06875240.06255.06375245.06125280.07475.11875240.06230.0575240.06245.06125245.06125250.0625270.0675245.06125255.06375250.0625285.07125285.07125285.07125270.0675270.0675260.065255.06375475.11875240.06230.0575240.06245.06125280.07275.06875270.0675280.07280.07280.07255.06375255.06375250.0625275.06875275.06875255.06375280.07475.11875240.06230.0575240.06245.06125275.06875265.06625245.06125275.06875270.0675250.0625260.065260.065255.06375285.07125250.0625250.0625255.06375475.11875240.06230.0575240.06260.065250.0625265.06625260.065250.0625280.07240.06250.0625250.0625240.06285.07125265.06625260.065245.06125475.11875240.06230.0575240.06255.06375275.06875265.06625255.06375275.06875275.06875270.0675270.0675270.0675265.06625265.06625260.065275.06875275.06875475.11875240.06230.0575240.06245.06125270.0675250.0625270.0675270.0675255.06375270.0675265.06625265.06625265.06625240.06275.06875240.06275.06875475.11875240.06230.0575240.06240.06280.07275.06875265.06625280.07280.07245.06125250.0625250.0625245.06125285.07125270.0675245.06125245.06125255.06375475.11875240.06230.0575240.06265.06625275.06875265.06625265.06625275.06875285.07125240.06280.07280.07275.06875245.06125275.06875255.06375245.06125475.11875240.06230.0575240.06250.0625265.06625240.06250.0625265.06625245.06125275.06875275.06875275.06875275.06875240.06255.06375245.06125280.07475.11875240.06230.0575240.06250.0625270.0675250.0625275.06875270.0675260.065255.06375270.0675270.0675265.06625280.07280.07255.06375260.065475.11875'
print(decode_password(p)) --> stophackingme123
Example 2:
for _, info in ipairs(loginDatabase) do
print(info.username, decode_password(info.password))
end

Sweeping backward through formatted stream file

More problems with formatted stream I/O. This time I scan a file opened for formatted stream access for the starts of the lines. This is completely successful. However, when I try to copy the file backwards using these markers, problems are encountered both on ifort and gfortran. The program:
program testpos2
implicit none
character(80) halfline
character(:), allocatable :: line
integer iunit
integer junit
integer i
integer, parameter :: N = 4
integer pos(N)
integer size
integer current
open(newunit=iunit,file='testpos2.txt',status='replace')
do i = 1, N
write(halfline,'(*(g0))') i,' 2nd half ',i
write(iunit,'(*(g0))') trim(halfline)
end do
close(iunit)
allocate(character(len_trim(halfline)) :: line)
open(newunit=iunit,file='testpos2.txt',status='old',access='stream',form='formatted')
do i = 1, N
inquire(iunit,pos=pos(i))
read(iunit,'()')
end do
open(newunit=junit,file='testpos3.txt',status='replace')
do i = N, 1, -1
read(iunit,'(a)',pos=pos(i),advance='no',eor=10,size=size) line
inquire(iunit,pos=current)
write(*,'(*(g0))') 'pos(i) = ',pos(i),', current = ',current
write(junit,'(*(g0))',advance='no') line
do
read(iunit,'(a)',advance='no',eor=10,size=size) line
inquire(iunit,pos=current)
write(*,'(*(g0))') 'pos(i) = ',pos(i),', current = ',current
write(junit,'(*(g0))',advance='no') line
end do
10 continue
write(junit,'(*(g0))') line(1:size)
end do
end program testpos2
Run-time output with gfortran 8.1.0:
pos(i) = 43, current = 55
pos(i) = 29, current = 41
pos(i) = 15, current = 27
pos(i) = 1, current = 13
Perfect! but the output file is:
4 2nd half 4
3 2nd half 3
4 2nd half 4
1 2nd half 1
Observe that the third line is the wrong one!
Run-time output with ifort 16.0.2:
pos(i) = 43, current = 55
pos(i) = 29, current = 69
forrtl: severe (24): end-of-file during read, unit -130, file C:\testpos2.txt
And the output file is binary junk after the first line.
This looks much like the result of corrupted memory, but the program seems simple enough that I can't see where corruption could occur, not to mention that both ifort and gfortran produce the expected results when the file is scanned in the forward direction. So could it be that the I/O libraries of both compilers are the ones causing corruption or is it me?

Resources