output_ptr Assertion Error in Main - Cairo-lang - blockchain

I am going through the official Cairo language tutorial. When I get to the build_dict function for the 15-puzzle, I am a bit confused so would like to print out some things to see.
struct Location:
member row : felt
member col : felt
end
...
func finalize_state(dict : DictAccess*, idx) -> (
dict : DictAccess*):
if idx == 0:
return (dict=dict)
end
assert dict.key = idx
assert dict.prev_value = idx - 1
assert dict.new_value = idx - 1
return finalize_state(
dict=dict + DictAccess.SIZE, idx=idx - 1)
end
##### I added the {} along with context in it for output #####
func main{output_ptr : felt*}():
alloc_locals
local loc_tuple : (Location, Location, Location, Location, Location) = (
Location(row=0, col=2),
Location(row=1, col=2),
Location(row=1, col=3),
Location(row=2, col=3),
Location(row=3, col=3),
)
# Get the value of the frame pointer register (fp) so that
# we can use the address of loc_tuple.
let (__fp__, _) = get_fp_and_pc()
# Since the tuple elements are next to each other we can use the
# address of loc_tuple as a pointer to the 5 locations.
verify_location_list(
loc_list=cast(&loc_tuple, Location*), n_steps=4)
##### Here is what I added #####
local locs : Location* = cast(&loc_tuple, Location*)
tempvar loc = [locs]
tempvar row = loc.row
serialize_word(row)
################################
return ()
end
I added the lines for printing the first row in loc_tuple. However, the Cairo compiler is giving me the following errors:
Traceback (most recent call last):
File "/Users/yijiachen/cairo_venv/bin/cairo-compile", line 10, in <module>
sys.exit(main())
File "/Users/yijiachen/cairo_venv/lib/python3.8/site-packages/starkware/cairo/lang/compiler/cairo_compile.py", line 397, in main
cairo_compile_common(
File "/Users/yijiachen/cairo_venv/lib/python3.8/site-packages/starkware/cairo/lang/compiler/cairo_compile.py", line 121, in cairo_compile_common
assembled_program = assemble_func(
File "/Users/yijiachen/cairo_venv/lib/python3.8/site-packages/starkware/cairo/lang/compiler/cairo_compile.py", line 367, in
cairo_assemble_program
check_main_args(program)
File "/Users/yijiachen/cairo_venv/lib/python3.8/site-packages/starkware/cairo/lang/compiler/cairo_compile.py", line 296, in check_main_args
assert main_args == expected_builtin_ptrs, (
AssertionError: Expected main to contain the following arguments (in this order): []. Found: ['output_ptr'].
I have tried with various serialize_word statements and none seem to work. This issue never arose before with other serialize_word statements, including in earlier parts of the tutorial.

Declare %builtins output at the top of your code so that the compiler will know that you use an implicit argument (output_ptr) in your main function and expect it.
The Cairo compiler is able to process implicit arguments only if you declare that you are going to use them. See here.

Related

Reading in TSP file Python

I need to figure out how to read in this data of the filename 'berlin52.tsp'
This is the format I'm using
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION : 52
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
And this is my current code
# Open input file
infile = open('berlin52.tsp', 'r')
# Read instance header
Name = infile.readline().strip().split()[1] # NAME
FileType = infile.readline().strip().split()[1] # TYPE
Comment = infile.readline().strip().split()[1] # COMMENT
Dimension = infile.readline().strip().split()[1] # DIMENSION
EdgeWeightType = infile.readline().strip().split()[1] # EDGE_WEIGHT_TYPE
infile.readline()
# Read node list
nodelist = []
N = int(intDimension)
for i in range(0, int(intDimension)):
x,y = infile.readline().strip().split()[1:]
nodelist.append([int(x), int(y)])
# Close input file
infile.close()
The code should read in the file, output out a list of tours with the values "1, 2, 3..." and more while the x and y values are stored to be calculated for distances. It can collect the headers, at least. The problem arises when creating a list of nodes.
This is the error I get though
ValueError: invalid literal for int() with base 10: '565.0'
What am I doing wrong here?
This is a file in TSPLIB format. To load it in python, take a look at the python package tsplib95, available through PyPi or on Github
Documentation is available on https://tsplib95.readthedocs.io/
You can convert the TSPLIB file to a networkx graph and retrieve the necessary information from there.
You are feeding the string "565.0" into nodelist.append([int(x), int(y)]).
It is telling you it doesn't like that because that string is not an integer. The .0 at the end makes it a float.
So if you change that to nodelist.append([float(x), float(y)]), as just one possible solution, then you'll see that your problem goes away.
Alternatively, you can try removing or separating the '.0' from your string input.
There are two problem with the code above.I have run the code and found the following problem in lines below:
Dimension = infile.readline().strip().split()[1]
This line should be like this
`Dimension = infile.readline().strip().split()[2]`
instead of 1 it will be 2 because for 1 Dimension = : and for 2 Dimension = 52.
Both are of string type.
Second problem is with line
N = int(intDimension)
It will be
N = int(Dimension)
And lastly in line
for i in range(0, int(intDimension)):
Just simply use
for i in range(0, N):
Now everything will be alright I think.
nodelist.append([int(x), int(y)])
int(x)
function int() cant convert x(string(565.0)) to int because of "."
add
x=x[:len(x)-2]
y=y[:len(y)-2]
to remove ".0"

Gets ¨IndexError: list index out of range¨ Is this a bug?

I can't seem to find the error in my Python 2.7.13 code. When I try to run it, the following shows up:
"IndexError: list index out of range"
for d in dopant[1:]:
for s in xrange(1,3,2):
for k in xrange(0,1):
# creates folder
try:
os.makedirs("path")
except OSError:
if not os.path.isdir("path"):
raise
# enters that folder
os.chdir("path")
file2 = open("atomicXYZ","a+")
stdin=subprocess.PIPE, stdout = file2).stdin
subprocess.Popen(['cat', '/path/file'], stdout = cmd1)
file2.seek(0)
# The following reads atomicXYZ and converts its contents to tuples
result = []
with file2 as fp:
for i in fp.readlines():
tmp = i.split()
try:
result.append((float(tmp[0]), float(tmp[1]), float(tmp[2])))
except:pass
# As a check, I access the last line of the tuple
x,y,z = result[len(result)-1]
os.chdir("..")
That is when the error shows up. This is surprising because atomicXYZ is NOT empty, as you can see here:
atomicXYZ
0.309595018 0.070879924 0.041045030
0.600985479 0.103996517 0.130482163
0.982347083 -0.008801119 -0.088718291
0.266923601 0.125720284 -0.038070136
0.520845390 0.163282973 0.061118496
0.812787033 0.194089924 0.131124240
0.398054509 0.270533816 -0.097226923
0.673016094 0.332428625 0.006571612
0.968473946 0.356972107 0.087712083
0.896549601 0.449435057 0.027658530
0.602586223 0.391867525 -0.070503370
0.732266134 0.576057624 -0.111890811
1.018201372 0.643127004 -0.009288985
0.914029765 0.703744085 -0.066356115
And what is even stranger is that when I split this entire code into two codes-- one for writing the atomic coordinates, and one for reading the coordinates-- it works.
What is it that I'm doing wrong?

Ternary operator in Python raises TypeError when using * operator on empty list?

I want to print the contents of a list a if len(a) > 0, but otherwise I want to print -1. This seems to be pretty simple, but it's raising a TypeError, stating that a is an int, not a sequence, only when a is an empty list:
>>> a = [2]
>>> print(*a if len(a) > 0 else -1)
2 # as expected
>>> a = []
>>> print(*a)
>>> # It has no trouble evaluating *a when a is empty
... ### HERE IS THE ERROR:
...
>>> print(*a if len(a) > 0 else -1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int
>>> ### But this works fine:
...
>>> if len(a) > 0:
... print(*a)
... else:
... print(-1)
...
-1
Why is this the case?
According to the Python Documentation:
The expression x if C else y first evaluates the condition, C rather
than x. If C is true, x is evaluated and its value is returned;
otherwise, y is evaluated and its value is returned.
So *a shouldn't be getting evaluated at all, and yet it's causing a TypeError?
I'm using Python 3.5
I'm not an expert, but looking at PEP 448 it looks like this * syntax isn't part of the general expression syntax, but it's specific to function callsites (and other things like tuple and dictionary displays). (It's a bit of a hack.)
The PEP explicitly calls out some similar syntax that they've forbidden because they didn't know what it should do. It doesn't look like your code has been particularly considered though.
Unbracketed comprehensions in function calls, such as f(x for x in it), are already valid. These could be extended to:
f(*x for x in it) == f((*x for x in it))
f(**x for x in it) == f({**x for x in it})
However, it wasn't clear if this was the best behaviour
or if it should unpack into the arguments of the call to f. Since
this is likely to be confusing and is of only very marginal utility,
it is not included in this PEP. Instead, these will throw a
SyntaxError and comprehensions with explicit brackets should be used
instead.
I think your code is effectively parsing as print(*(a if len(a) > 0 else -1)), which is why you then get the error TypeError: print() argument after * must be a sequence, not int. By comparison, this works:
>>> print(*a if len(a) > 0 else ['nothing'])
nothing

How to find global static initializations

I just read this excellent article: http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html
and then I tried: https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
What it says about finding initializers does not work for me though. The .ctors section is not available, but I could find .init_array (see also Can't find .dtors and .ctors in binary). But how do I interpret the output? I mean, summing up the size of the pages can also be handled by the size command and its .bss column - or am I missing something?
Furthermore, nm does not report any *_GLOBAL__I_* symbols, only *_GLOBAL__N_* functions, and - more interesting - _GLOBAL__sub_I_somefile.cpp entries. The latter probably indicates files with global initialization. But can I somehow get a list of constructors that are being run? Ideally, a tool would give me a list of
Foo::Foo in file1.cpp:12
Bar::Bar in file2.cpp:45
...
(assuming I have debug symbols available). Is there such a tool? If not, how could one write it? Does the .init_array section contain pointers to code which could be translated via some DWARF magic to the above?
As you already observed, the implementation details of contructors/initialization functions are highly compiler (version) dependent. While I am not aware of a tool for this, what current GCC/clang versions do is simple enough to let a small script do the job: .init_array is just a list of entry points. objdump -s can be used to load the list, and nm to lookup the symbol names. Here's a Python script that does that. It should work for any binary that was generated by the said compilers:
#!/usr/bin/env python
import os
import sys
# Load .init_array section
objdump_output = os.popen("objdump -s '%s' -j .init_array" % (sys.argv[1].replace("'", r"\'"),)).read()
is_64bit = "x86-64" in objdump_output
init_array = objdump_output[objdump_output.find("Contents of section .init_array:") + 33:]
initializers = []
for line in init_array.split("\n"):
parts = line.split()
if not parts:
continue
parts.pop(0) # Remove offset
parts.pop(-1) # Remove ascii representation
if is_64bit:
# 64bit pointers are 8 bytes long
parts = [ "".join(parts[i:i+2]) for i in range(0, len(parts), 2) ]
# Fix endianess
parts = [ "".join(reversed([ x[i:i+2] for i in range(0, len(x), 2) ])) for x in parts ]
initializers += parts
# Load disassembly for c++ constructors
dis_output = os.popen("objdump -d '%s' | c++filt" % (sys.argv[1].replace("'", r"\'"), )).read()
def find_associated_constructor(disassembly, symbol):
# Find associated __static_initialization function
loc = disassembly.find("<%s>" % symbol)
if loc < 0:
return False
loc = disassembly.find(" <", loc)
if loc < 0:
return False
symbol = disassembly[loc+2:disassembly.find("\n", loc)][:-1]
if symbol[:23] != "__static_initialization":
return False
address = disassembly[disassembly.rfind(" ", 0, loc)+1:loc]
loc = disassembly.find("%s <%s>" % (address, symbol))
if loc < 0:
return False
# Find all callq's in that function
end_of_function = disassembly.find("\n\n", loc)
symbols = []
while loc < end_of_function:
loc = disassembly.find("callq", loc)
if loc < 0 or loc > end_of_function:
break
loc = disassembly.find("<", loc)
symbols.append(disassembly[loc+1:disassembly.find("\n", loc)][:-1])
return symbols
# Load symbol names, if available
nm_output = os.popen("nm '%s'" % (sys.argv[1].replace("'", r"\'"), )).read()
nm_symbols = {}
for line in nm_output.split("\n"):
parts = line.split()
if not parts:
continue
nm_symbols[parts[0]] = parts[-1]
# Output a list of initializers
print("Initializers:")
for initializer in initializers:
symbol = nm_symbols[initializer] if initializer in nm_symbols else "???"
constructor = find_associated_constructor(dis_output, symbol)
if constructor:
for function in constructor:
print("%s %s -> %s" % (initializer, symbol, function))
else:
print("%s %s" % (initializer, symbol))
C++ static initializers are not called directly, but through two generated functions, _GLOBAL__sub_I_.. and __static_initialization... The script uses the disassembly of those functions to get the name of the actual constructor. You'll need the c++filt tool to unmangle the names, or remove the call from the script to see the raw symbol name.
Shared libraries can have their own initializer lists, which would not be displayed by this script. The situation is slightly more complicated there: For non-static initializers, the .init_array gets an all-zero entry that is overwritten with the final address of the initializer when loading the library. So this script would output an address with all zeros.
There are multiple things executed when loading an ELF object, not just .init_array. To get an overview, I suggest looking at the sources of libc's loader, especially _dl_init() and call_init().

JasperReports: Converting String into array and populating List with it

What I have is this String [125, 154, 749, 215, 785, 1556, 3214, 7985]
(string can have anything from 1 to 15 ID's in it and the reason it is a string and not a List is that, its being sent through a URL)
I need to populate a List called campusAndFaculty with it
I am using iReport 5.0.0
I've tried entering this in the campusAndFaculty default value Expression field
Array.asList(($P{campusAndFacultyString}.substring( 1, ($P{campusAndFacultyString}.length() -2 ))).split("\\s*,\\s*"))
But it does not populate the campusAndFaculty List
Any idea how I can populate the List campusAndFaculty using that String ("campusAndFacultyString")?
======================
UPDATE
I have these variables in iReport (5.0.0)
String campusAndFacultyFromBack = "[111, 125, 126, 4587, 1235, 1259]"
String noBrackets = $P{campusAndFacultyFromBack}.substring(1 ($P{campusAndFacultyFromBack}.length() -1 ))
List campusAndFacultyVar = java.util.Arrays.asList(($V{noBrackets}).split("\\s*,\\s*"))
When I print campusAndFacultyVar It returns "[111, 125, 126, 4587, 1235, 1259]"
but when I use it in a Filter I get the "Cannot evaluate the following expression: org_organisation.org_be_id in null"
This works for me:
String something = "[125, 154, 749, 215, 785, 1556, 3214, 7985]";
Arrays.asList((something.substring(1, (something.length() -1 ))).split("\\s*,\\s*"));
Which means you can do this in iReport:
java.util.Arrays.asList(($P{campusAndFacultyString}.substring(1, (something.length() -1 ))).split("\\s*,\\s*"));
Differences with your snippet:
It's Arrays, not Array
You should take 1, not 2 from the length
Fully qualified reference to Arrays class (which may or may not matter depending on how your iReport is configured)