SPOJ: runtime error (NZEC) - python

I tried to do this problem at spoj.com, but I keep getting the error runtime error (NZEC). I code in python. I don't know why. Here is my code,
import sys
def unique(lines, exact=True):
for L in lines:
if L.count('#') != 1 and exact:
return False
if L.count('#') > 1 and not exact:
return False
return True
def resolve(N, lines):
diags = [
[lines[i][i+j] for i in range(max(0, -j), min(N, N-j))]
for j in range(-N+1, N)]
anti_diags = [
[lines[i][N-1 -(i+j)] for i in range(max(0, -j), min(N, N-j))]
for j in range(-N+1, N)]
if unique(lines) and unique(zip(*lines)) and unique(diags, False) and unique(anti_diags, False):
return "YES"
return "NO"
input_file = sys.stdin
output_file = sys.stdout
T = int(raw_input())
for i in range(1, T + 1):
n = int(raw_input())
lines = []
for _ in range(n):
line = raw_input().strip()
lines.append(list(line))
print resolve(n, lines)
It works fine locally with input like:
2
3
..#
#..
.#.
4
.#..
...#
#...
..#.

When I run your code, I get the following:
$ python spoj.py < input
Traceback (most recent call last):
File "spoj.py", line 38, in <module>
print resolve(n, lines)
File "spoj.py", line 15, in resolve
for j in range(-N+1, N)]
IndexError: list index out of range
That's the runtime error you're getting. But the problem is actually in this part:
for _ in range(n):
line = raw_input().strip()
lines.append(list(line))
print resolve(n, lines)
Since the print statement is indented, your program reads a single line, appends to line and calls resolve before reading the following lines. After removing the extra indent, it works fine on my computer.
There's plenty of room to further improve this program, both in style and logic. Let me know if you would like some further advice.
EDIT:
You mentioned in the comments that this indentation problem was a copypasting error. In that case, as sp1r pointed out in his comment, it's most likely that, as a comment in the problem's page suggests, the input used by the online judge is malformed.
In that case, you have to do more rigorous parsing of the input, as it may not be formatted as the example input suggests. That is, instead of:
2
3
..#
#..
.#.
(etc)
you could have something more like:
2 3
..#
#.. .#.
(etc)
That might break your code because it assumes whoever posted the problem was competent enough to make an input that looks like the example. That is not always the case in SPOJ, a lot of the input files is malformed and you can find other cases where malformed input causes otherwise correct programs to fail.

Spoj does not use sys and sys.stdin and sys.stdout. use raw_input() and print.
"I am on windows not on linux. I simply change this line to switch to console modes for tests."
In any language and in any os, these works fine.
#for Python
spoj.py < input.txt > output.txt
#If you are using C/C++, for any EXE file
spoj.exe < input.txt > output.txt
Spoj will nether test this in your computer nor using any UI. They will test your code, in a "console" and it might be a linux / any-OS machine. Use this input / output to Test your code.

Related

Python - index out of range

Trying to adapt a basic profiler for bash scripts, block of code below.
Can't figure out why profiling code with a "if branch" throws exception (for example when running this code with a duplicate file). From what I've traced, it somewhere creates an extra index value. My apologies if this is trivial as I'm new to Python, but any suggestions on where could be the issue or how to remedy it would be greatly appreciated
def collect_timings(profiled_line, i):
if i == len(results) - 1:
return [0] + profiled_line
timing = float(results[i+1][1].replace(".N", "")) - float(profiled_line[1].replace(".N", ""))
return [timing] + profiled_line
Error:
Traceback (most recent call last):
File "./profile", line 67, in <module>
main(sys.argv)
File "./profile", line 51, in main
profiling_time = map(collect_timings, results, range(len(results)))
File "./profile", line 24, in collect_timings
timing = float(results[i+1][1].replace(".N", "")) - float(profiled_line[1].replace(".N", ""))
IndexError: list index out of range
Found the answer, posting in case it proves useful for someone.
The issues was a with a output redirection:
echo "Found '$file' is a duplicate of '${filecksums[$cksum]}'" >&2
That got passed as a separate entry to results:
["Found 'txt2/0122file.bck' is a duplicate of 'txt2/0113file.txt'\n"]
No idea how to make the code run with redirects, but it's not necessary, so I'll just avoid it.
you say:
if i == len(results) - 1:
below you say :
timing = float(results[i+1][1].replace(".N", ""))
so you check if "i" show the last element of results array (i.e. results has 5 cells from 0 to 4 and you check if i == 4( len(results) == 5 in this case AND NOT 4) ) and then you say results[i+1] which in the example above is equal to results[5] which is out of bounds.
Maybe you meant results[i]?

Take error on wlst console when work with statements or loops

Not able to make loop and statement after it.
Example:
wls:/ADMIN_server/serverConfig> serverRuntime()
Location changed to serverRuntime tree. This is a read-only tree with ServerRuntimeMBean as the root.
For more help, use help(serverRuntime)
wls:/ADMIN_server/serverRuntime> dsMBeans = cmo.getJDBCServiceRuntime().getJDBCDataSourceRuntimeMBeans()
wls:/ADMIN_server/serverRuntime> ds_name = "ADMIN_DB"
wls:/ADMIN_server/serverRuntime> for ds in dsMBeans:
...
Traceback (innermost last):
(no code object) at line 0
File "<console>", line 2
SyntaxError: invalid syntax
Not sure is it need to import something before that options like and for that reason not able to make loop with statement:
import time
import sys
You shouldn't need to import anything specific to have access to the looping mechanism in WLST. For instance, try the following:
slist=range(1,4)
for i in slist: print 'i = ' + str(i);
The result should be:
i = 1
i = 2
i = 3
The syntax of your statements after the for loop are probably causing a problem in your python script OR if you are manually typing the commands in, you need to make sure you put a space after ... for it to interpret the next line like:
wls:/offline> j = 0
wls:/offline> while j<4:
... print 'j = ' + str(j)
... j = j + 1
...
jms 0
jms 1
jms 2
jms 3
Notice it is very important to type in a space character after ... or you will have the invalid syntax error.

sage 5.0 confusing syntax error

My OS doesn't support Sage 5.4 so I'm stuck with 5.0 for now.
Defining this function registers no syntax errors in python, and I don't think it makes errors in Sage 5.4 (I'd appreciate confirmation if possible.) I'd like to know why it is failing in 5.0.
def num_matchings(G):
if min(G.degree_sequence())== 0 or G.num_edges()==0:
return 0
elif G.num_edges()==1:
if G.edges()[0][2] ==None:
return 1
else:
return G.edges()[0][2]
else:
H = copy(G)
K = copy(G)
e = G.edges()[0]
if e[2] ==None:
w=1
else:
w = e[2]
H.delete_edge(e)
K.delete_vertices([e[0],e[1]])
return num_matchings(H) + w*num_matchings(K)
The first error I get when I try to define is
File "<ipython console>", line 4
==Integer(1):
^
SyntaxError: invalid syntax
and they pile on after that. To my eye, the syntax looks fine.
I'm on Mac OS 10.5 with GCC 4.0.1.
Any help much appreciated.
[Aside: typo in .delete_vertives().]
Your syntax itself is fine. From the error message, though, it looks like you've simply copied and pasted code into the console. That will only work in certain very simple cases. You're also using tabs for indentation, which can cause a whole other set of headaches too. You should really switch to 4-space tabs instead.
If you want to insert code into a live console, you can use %paste (which copies from the clipboard if it can), or %cpaste instead.
For example, if I copy and paste your code, I get:
sage: def num_matchings(G):
....: if min(G.degree_sequence())== 0 or G.num_edges()==0:
....: return 0
....: elif G.num_edges()==1:
------------------------------------------------------------
File "<ipython console>", line 4
==Integer(1):
^
SyntaxError: invalid syntax
sage: if G.edges()[0][2] ==None:
....: return 1
------------------------------------------------------------
File "<ipython console>", line 2
SyntaxError: 'return' outside function (<ipython console>, line 2)
but if I use %cpaste with the 4-space equivalent (unfortunately %paste isn't working on my 5.4.1 install at the moment):
sage: %cpaste
Pasting code; enter '--' alone on the line to stop.
:
:def num_matchings(G):
: if min(G.degree_sequence())== 0 or G.num_edges()==0:
: return 0
[etc.]
: K.delete_vertices([e[0],e[1]])
: return num_matchings(H) + w*num_matchings(K)
:--
sage: num_matchings(graphs.LadderGraph(5))
8

python doctest: expected result is the same as the "got" result but the test failed

I am on a learning stage of using python as a tool for software QA.
I wrote the next simple test in order to find the letter 'a' in a text file number matrix.
problem is that the test fails even though the expect equals to what i got.
Why is that? Can you tell me what am I doing wrong?
test script:
fin = open("abc.txt", "r")
arr_fin = []
for line in fin:
arr_fin.append(line.split())
print arr_fin
for row in arr_fin:
arr_fin_1 = " ".join('{0:4}'.format(i or " ") for i in row)
print arr_fin_1
def find_letter(x, arr_fin_1):
"""
>>> find_letter('a', arr_fin_1)
97
"""
t=ord(x) #exchange to letter's ASCII value
for i in arr_fin_1:
if i==x:
print t
return;
def _test():
import doctest
doctest.testmod()
if __name__ == "__main__":
_test()
error message:
Expected:
97
Got:
97
**********************************************************************
1 items had failures:
1 of 1 in __main__.find_letter
***Test Failed*** 1 failures.
You've got an extra space after the 97 - if you remove it, your test should run fine.
This:
return;
Makes your function return None.
Did you mean return t?
Besides that, IMHO doctest tests are meant to be self-contained. This is something the user should see in your documentation and understand without context. In your example, you're using a module-local arr_fin_1 object which is completely opaque to the user. It's better to define it in the doctest before the find_letter call to provide a self-contained example.

Unable to have a command line parameter in Python

I run
import sys
print "x \tx^3\tx^3+x^3\t(x+1)^3\tcube+cube=cube+1"
for i in range(sys.argv[2]): // mistake here
cube=i*i*i
cube2=cube+cube
cube3=(i+1)*(i+1)*(i+1)
truth=(cube2==cube3)
print i, "\t", cube, "\t", cube + cube, "\t", cube3, "\t", truth
I get
Traceback (most recent call last):
File "cube.py", line 5, in <module>
for i in range(sys.argv[2]):
IndexError: list index out of range
How can you use command line parameter as follows in the code?
Example of the use
python cube.py 100
It should give
x x^3 x^3+x^3 (x+1)^3 cube+cube=cube+1
0 0 0 1 False
1 1 2 8 False
2 8 16 27 False
--- cut ---
97 912673 1825346 941192 False
98 941192 1882384 970299 False
99 970299 1940598 1000000 False
Use:
sys.argv[1]
also note that arguments are always strings, and range expects an integer.
So the correct code would be:
for i in range(int(sys.argv[1])):
You want int(sys.argv[1]) not 2.
Ideally you would check the length of sys.argv first and print a useful error message if the user doesn't provide the proper arguments.
Edit: See http://www.faqs.org/docs/diveintopython/kgp_commandline.html
Here are some tips on how you can often solve this type of problem yourself:
Read what the error message is telling you: "list index out of range".
What list? Two choices (1) the list returned by range (2) sys.argv
In this case, it can't be (1); it's impossible to get that error out of
for i in range(some_integer) ... but you may not know that, so in general, if there are multiple choices within a line for the source of an error, and you can't see which is the cause, split the line into two or more statements:
num_things = sys.argv[2]
for i in range(num_things):
and run the code again.
By now we know that sys.argv is the list. What index? Must be 2. How come that's out of range? Knowledge-based answer: Because Python counts list indexes from 0. Experiment-based answer: Insert this line before the failing line:
print list(enumerate(sys.argv))
So you need to change the [2] to [1]. Then you will get another error, because in range(n) the n must be an integer, not a string ... and you can work through this new problem in a similar fashion -- extra tip: look up range() in the docs.
I'd like to suggest having a look at Python's argparse module, which is a giant improvement in parsing commandline parameters - it can also do the conversion to int for you including type-checking and error-reporting / generation of help messages.
Its sys.argv[1] instead of 2. You also want to makes sure that you convert that to an integer if you're doing math with it.
so instead of
for i in range(sys.argv[2]):
you want
for i in range(int(sys.argv[1])):

Categories