Why does the following python code throw a Memory error? - python

Here is the code:
import itertools
num_cases = int(input())
answer_list = []
while num_cases>0:
live_ans = []
question_list = []
nums = int(input())
d1 = int(input())
d2 = int(input())
sample_space= {d1, d2}
temp = []
no_cases = 2**(nums-1)
combs = itertools.product(sample_space, repeat = nums-1)
for i in combs:
temp.append(i)
for i in temp:
if sum(i) not in live_ans:
live_ans.append(sum(i))
else:
pass
live_ans.sort()
answer_list.append(live_ans)
num_cases -= 1
for i in answer_list:
finalans = " ".join(map(str, i))
print(finalans)
For small inputs like:
1
3
1
2
The program works just fine. Where as for a relatively larger input like:
1
58
69
24
It gives a memory error. I dont cite any reason for this as the code doesn't look memory consuming at all. Isn't it?

Look at your following lines:
no_cases = 2**(nums-1)
combs = itertools.product(sample_space, repeat = nums-1)
for i in combs:
temp.append(i)
2**58 = 2.8823038e+17
You do the math on why it gets a memory error from here

Related

USACO Code Submission Problem - Output File Missing

I've started practicing for the USACO contest tomorrow, I'm relativly new so I'm not too familiar with their input/output methods. Here's the code I submitted to the website
n = int(input())
a = input()
b = input()
swap_number = 0
a_list = []
b_list = []
for i in range(n):
if a[i] != b[i]:
a_list.append(a[i])
b_list.append(b[i])
one_value = 0
two_value = 0
for x in range(len(a_list)):
if a_list[x] == "H":
one_value += 1
else:
two_value += 1
list = [one_value,two_value]
list.sort()
swap_number = list[0] + (list[1]-list[0])
print(swap_number)
after loading for a couple minutes, it displayed:
Your output file breedflip.out:
[File missing!]
I rewrote, retested every problem using this simple code, but still receive the same error
Would this code not create an output file and how can I put the outputted answer in the file
Try to add these two lines in your beginning of codes: (just test and it passed with my revised code) Your code might not be working!
import sys
sys.stdin = open('breedflip.in', 'r')
sys.stdout = open('breedflip.out', 'w')
n = int(input())
a = list(input()) # list
b = list(input())
...........

Problem with reading data from file in Python

EDIT:
Thanks for fixing it! Unfortunatelly, it messed up the logic. I'll explain what this program does. It's a solution to a task about playing cards trick. There are N cards on the table. First and Second are numbers on the front and back of the cards. The trick can only be done, if the visible numbers are in non-decreasing order. Someone from audience can come and swap places of cards. M represents how many cards will be swapped places. A and B represent which cards will be swapped. Magician can flip any number of cards to see the other side. The program must tell, if the magician can do the trick.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
for _ in range(n):
first, second = (int(x) for x in data.readline().split(':'))
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # add to the list by appending
m = data.readline()
m = int(m)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
data:
4
2:5
3:4
6:3
2:7
2
3-4
1-3
results:
YES
YES
YES
YES
YES
YES
YES
What should be in results:
NO
YES
The code is full of bugs: you should write and test it incrementally instead of all at once. It seems that you started using readlines (which is a good way of managing this kind of work) but you kept the rest of the code in a reading one by one style. If you used readlines, the line for i, line in enumerate(data): should be changed to for i, line in enumerate(lines):.
Anyway, here is a corrected version with some explanation. I hope I did not mess with the logic.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
# The following line created a huge list of "Pairs" types, not instances
# pairs = [Pair] * (2*200*1000+1)
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
# removing the reading of all data...
# lines = data.readlines()
# m = lines[n]
# removed bad for: for i, line in enumerate(data):
for _ in range(n): # you don't need the index
first, second = (int(x) for x in data.readline().split(':'))
# removed unnecessary recasting to int
# first = int(first)
# second = int(second)
# changed the swapping to a more elegant way
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # we add to the list by appending
# removed unnecessary for: once you read all the first and seconds,
# you reached M
m = data.readline()
m = int(m)
# you don't need the index... indeed you don't need to count (you can read
# to the end of file, unless it is malformed)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
# removed unnecessary recasting to int
# a = int(a)
# b = int(b)
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
Response previous to edition
range(1, 1) is empty, so this part of the code:
for i in range (1, 1):
n = data.readline()
n = int(n)
does not define n, at when execution gets to line 12 you get an error.
You can remove the for statement, changing those three lines to:
n = data.readline()
n = int(n)

HackerRank Dynamic Array Problem - Runtime Error in the code

I am trying to solve this Dynamic Array problem on HackerRank. This is my code:
#!/bin/python3
import math
import os
import random
import re
import sys
#
# Complete the 'dynamicArray' function below.
#
# The function is expected to return an INTEGER_ARRAY.
# The function accepts following parameters:
# 1. INTEGER n
# 2. 2D_INTEGER_ARRAY queries
#
def dynamicArray(n, queries):
lastAnswer = 0
a = []
array_result = []
for k in range(n):
a.append([])
for i in queries:
x = i[1]
y = i[2]
if i[0] == 1:
seq = ((x ^ lastAnswer) % n)
a[seq].append(y)
elif i[0] == 2:
seq = ((x ^ lastAnswer) % n)
lastAnswer = a[seq][y]
array_result.append(lastAnswer)
return array_result
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
first_multiple_input = input().rstrip().split()
n = int(first_multiple_input[0])
q = int(first_multiple_input[1])
queries = [] # 1 0 5, 1 1 7, 1 0 3, ...
for _ in range(q):
queries.append(list(map(int, input().rstrip().split())))
result = dynamicArray(n, queries)
fptr.write('\n'.join(map(str, result)))
fptr.write('\n')
fptr.close()
I am getting a runtime error:
Traceback (most recent call last):
File "Solution.py", line 50, in
fptr.write('\n'.join(map(str, result)))
TypeError: 'NoneType' object is not iterable
Can anyone help me with this, I can't seem to find a solution.
This is the input:
2 5
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
Thanks.
Update: It seems like this input is working now, thanks to #cireo but the code is not working for other test cases. What the problem with this code?
you can try this, it works totally fine.(no runtime error)
Replace your dynamicArray function with this code. Hopefully this will be helpful for you (^_^).
def dynamicArray(n, queries):
col = [[] for i in range(n)]
res = []
lastanswer = 0
for q in queries:
data = (q[1]^lastanswer)%n
if q[0] == 1:
col[data].append(q[2])
elif q[0] == 2:
ind_x = q[2]%len(col[data])
lastanswer = col[data][ind_x]
res.append(lastanswer)
return res
The answer to your question lies in the boilerplate provided by hackerrank.
# The function is expected to return an INTEGER_ARRAY.
You can also see that result = dynamicArray(n, queries) is expected to return a list of integers from map(str, result), which throws the exception.
In your code you do print(lastAnswer), but you probably want
+ ret = []
...
- print(lastAnswer)
+ ret.append(lastAnswer)
+ return ret
instead.
Since you do not return anything, the function returns None by default, which cannot be iterated over by map.
def dynamicArray(n, queries):
# Write your code here
arr=[[]for i in range(0,n)]
lastAnswer=0
answers=[]
for query in queries:
if query[0]==1:
idx= (query[1]^lastAnswer)%n
arr[idx].append(query[2])
if query[0]==2:
idx= (query[1]^lastAnswer)%n
lastAnswer= arr[idx][query[2]% len(arr[idx])]
answers.append(lastAnswer)
return answers

Replace for loop? This function works but it takes to long time. I'm looking for ways to impove it

It works but takes 40 seconds to work 1 stock 1 simple moving average. I'm a beginner, Is there any ways to replace those for loops or more efficient way to run this? I'm reading about numpy but I don't understand how it could replace a loop.
I'm trying to make a csv to store all the indicatorvalues from current period to the start of my dataframe.
I currently only have one moving average but with this speed its pointless to add anything else :)
def runcheck(df,adress):
row_count = int(0)
row_count=len(df)
print(row_count)
lastp = row_count-1
row_count2 = int(0)
mabuild = int(0)
ma445_count = int(0)
ma_count2 = int(0)
row_count5 = int(0)
row_count3 = int(0)
row_count4 = int(0)
resultat = int(0)
timside_count = int(0)
slott_count = int(0)
sick_count = int(0)
rad_data = []
startT = time.time()
## denna kollar hela vägen till baka t.ex idag. sen igår i förrgår
for row in df.index:
row_count2 += 1
timside_count = row_count-row_count2
if timside_count >= 445:
for row in df.index:
row_count5 = row_count-row_count2
slott_count = row_count5-row_count3
mabuild = mabuild+df.iloc[slott_count,5]
row_count3 += 1
row_count4 += 1
if row_count4 == 445:
resultat = mabuild/row_count4
rad_data.append(resultat)
row_count3 = int(0)
row_count4 = int(0)
mabuild = int(0)
resultat = 0
break
## sparar till csv innan loop börjar om
with open(adress, "a") as fp:
wr = csv.writer(fp,)
wr.writerow(rad_data)
rad_data.clear()
print('Time was :', time.time()-startT)
stop=input('')
Try this:
import numpy as np
from functools import reduce
def runcheck(df,adress):
startT = time.time()
rad_data = map(lambda i: reduce(lambda x, y: x + y, map(lambda z: df.iloc[z, 5], np.arange(i-445, i)))/445, np.arange(445, len(df.index)))
'''
Explanation
list_1 = np.arange(445, len(def.index) -> Create a list of integers from 445 to len(def.index)
rad_data = map(lambda i: function, list_1) -> Apply function (see below) to each value (i) in the generated list_1
function = reduce(lambda x, y: x + y, list_2)/445 -> Take 2 consecutive values (x, y) in list_2 (see below) and sum them, repeat until one value left (i.e. sum of list_2), then divide by 445
list_2 = map(lambda z: df.iloc[z, 5], list_3) -> Map each value (z) in list_3 (see below) to df.iloc[z, 5]
list_3 = np.arange(i-445, i) -> Create a list of integers from i-445 to i (value i from list_1)
'''
# writing to your csv file outside the loop once you have all the values is better, as you remove the overhead of re-opening the file each time
with open(adress, "a") as fp:
wr = csv.writer(fp,)
for data in rad_data:
wr.writerow([data])
print('Time was :', time.time()-startT)
stop=input('')
Not sure it works, as I don't have sample data. Let me know if there are errors and I'll try to debug!

Copy an array of floats to array of Strings

#ADD STRING MATRIX AND NUM MATRIX Fraction(3).limit_denominator(10)from fractions import Fraction
#ONLY WORKS FOR SQUARE ONES RIGHT NOW!
from fractions import Fraction
def make1(nm,x):
if nm[x][x]!=1:
print("Divide R1 by ",Fraction(nm[x][x]).limit_denominator(10))
tempr = multiply(nm[x],1/nm[x][x])
nm[x] = tempr
return nm
def convert(n):
try:
return float(n)
except ValueError:
num, denom = n.split('/')
return float(num) / float(denom)
def convertm(m):
lm = len(m)
lx = len(m[0])
tempn = [0]*lx
temps = [[]]*lm
print(temps)
cnt = 0
for x in m:
tempn = x
for n in x:
temps[cnt].append(str(Fraction(n).limit_denominator(10)))
print(n)
cnt+=1
print(temps)
def mprint(matrix):
s = [[str(e) for e in row] for row in matrix]
lens = [max(map(len, col)) for col in zip(*s)]
fmt = '\t'.join('{{:{}}}'.format(x) for x in lens)
table = [fmt.format(*row) for row in s]
print('\n'.join(table))
def subtract(r1,r2): #r1-r2
tempr = [0]*len(r1)
for x in range (0,len(r1)):
tempr[x] = r1[x]-r2[x]
return tempr
def multiply(r1,n):
tempr = [0]*len(r1)
for x in range (0,len(r1)):
tempr[x] = r1[x]*n
return tempr
def ans(nm):
end = len(nm[0])
cnt = 0
for x in nm:
cnt+=1
print("X",cnt,"=",x[end-1])
equ = int(input("How many equasions are in the linear system? "))
#unk = int(input("How many unkowns are in the linear system? "))
nm = [0] * equ
sm = [0] * equ
for x in range (0,equ):
tempinput = input("Please enter line "+str(x+1)+" of the matrix: ")
templist = [convert(n) for n in tempinput.split()]
nm[x] = templist
sm[x] = tempinput.split()
mprint(nm)
nm = make1(nm,0)
mprint(nm)
for p in range (0,equ-1):
for x in range (p,equ-1):
print("Subtract ",Fraction(nm[x+1][p]).limit_denominator(10),"*",p+1,"by",p+2)
tempr = multiply(nm[p],nm[x+1][p])
nm[x+1] = subtract(tempr,nm[x+1])
print("FIRST X: ",x,"P",x)
mprint(nm)
nm = make1(nm,p+1)
mprint(nm)
#GOIN BACK
for p in range (0,equ-1):
for x in range (0,equ-(p+1)):
print("Subtract ",x,"by",Fraction(nm[x][2-p]).limit_denominator(10),"*",3)
tempr = multiply(nm[2-p],nm[x][2-p])
nm[x]= subtract(nm[x],tempr)
print("SECOND X: ",x,"P",x)
mprint(nm)
ans(nm)
##or x in range (0,equ):
# print()
#g = nm[1][0]-1
#print("")
#tempr = multiply(nm[0],g/nm[0][0])
#nm[0]=tempr
#tempr = subtract(nm[1],nm[0])
#nm[0] = tempr
Pastebin of my code
Ok so where my actual problem is in the unimplemented (because I couldn't get it working) def convertm. What this is supposed to do is take the matrix with numbers (nm) and take every value and convert it into a string as fractions (x/x) if needed and store it in the matrix of strings (sm).
Here is that segment of code I am referencing...
def convertm(m):
lm = len(m)
lx = len(m[0])
tempn = [0]*lx
temps = [[]]*lm
print(temps)
cnt = 0
for x in m:
tempn = x
for n in x:
temps[cnt].append(str(Fraction(n).limit_denominator(10)))
print(n)
cnt+=1
print(temps)
I added some prints in order to try and test what the heck was going on during it. I am getting an output of just the last row being repeated through all rows. I think I don't have a return statement currently just because I have been trying get this to work. Ok so for an example if an array is imported that is...
[ [1,2,3],
[4,5,6],
[7,8,9] ]
It will output (set temps to)
[ ['7','8','9'],
['7','8','9'],
['7','8','9'] ]
I want it to output (set temps to)
[ ['1','2','3'],
['4','5','6'],
['7','8','9'] ]
Also I am using Python 3.3.1
(probably should upgrade to 3.3.3 but that is not what we are discussing!)
I have absolutely no idea why it is doing this and any little bit of help would very appreciated!
THANK YOU
I also apologize if this formatting is horrible I am new to this and I copy/pasted this from another forum I am very desperate to know what is going on here.
The line
temps = [[]]*lm
makes a list of list, where each sublist points to the same list in memory. So, if you modify one, you modify them all. This is why you are seeing the behavior you are seeing.
Change it to
temps = [[] for _ in range(lm)] # xrange on python2
to get different sublists.

Categories

Resources