colab keeps on crashing after using the 'GLOBAL' keyword - python

I copied this program from stackoverflow and added the global keyword to know the length of the list and it crashed because the ram is full.Why?If I removed the Global key word it works fine.I just wanted to know why it keeps on crashing
def permutation(s):
if len(s) == 1:
return [s]
global per_list
per_list = []
for i in s:
rm = [x for x in s if x != i]
ff = permutation(rm)
for j in ff:
per_list.append([i] + j)
return per_list
s = [3,4,5]
permutation(s)
print(len(per_list))

Declare it as empty list outside the function first and try again.
// like this
per_list = []
def permutation(s):
//body
s = [3,4,5]
permutation(s)
print(len(per_list))

Related

Why can I print this list of lists, but only append all up to and not including the last element of each iteration?

I can print the following list of lists fine, but when I append to an empty list, it skips the last on each iteration or gives me an index out of range error when I add one more.
This works:
ordered_results = []
temp = []
A = len(results[1])-2
i = 1
while i < len(results):
x = 0
y = 1
while x < A:
temp = [results[i][0], results[0][x], results[i][y]]
print(temp)
x+=1
y+=1
temp = [results[i][0], results[0][x], results[i][y]]
print(temp)
i+=1
ordered_results
Note: len(results[0]) = 240 and len(results[1] = 241
If you replace "print" with ordered_results.append(temp) it skips:
results[i][0], results[0][239], results[i][240]
each iteration.
(Note the code was expanded as I am messing around trying to figure this out, it was more compact before).

python functions work sometimes and fail to work other times

I wrote the piece of code below a while back, and had this issue then as well. I ignored it at the time and when I came back to it after asking an 'expert' to look at it, it was working fine.
The issue is, sometimes the program seems unable to run the main() on my laptop, possibly due to how heavy the algorithm is. Is there a way around this? I would hate to keep having this problem in the future. The same code is working perfectly on another computer which i have limited access to.
(P.S. laptop having the issue is a MacBook Air 2015 and it should have no problem running the program. Also, it stops after printing "hi")
It does not give and error message, it just doesn't print anything from main(). It's supposed to print a series of strings which progressively converge to "methinks it is like a weasel". In eclipse, it shows that the code is still being processed but it does not output anything that it is supposed to
import random
def generateOne(strlen):
alphabet = "abcdefghijklmnopqrstuvwxyz "
res = ""
for i in range(strlen):
res = res + alphabet[random.randrange(27)]
return res
def score(goal, teststring):
numSame = 0
for i in range(len(goal)):
if goal[i] == teststring[i]:
numSame = numSame + 1
return numSame / len(goal)
def main():
goalstring = "methinks it is like a weasel"
chgoal = [0]*len(goalstring)
newstring = generateOne(28)
workingstring = list(newstring)
countvar = 0
finalstring = ""
while score(list(goalstring), workingstring) < 1:
if score(goalstring, newstring) > 0:
for j in range(len(goalstring)):
if goalstring[j] == newstring[j] and chgoal[j] == 0:
workingstring[j] = newstring[j]
chgoal[j] = 1
finalstring = "".join(workingstring)
countvar = countvar + 1
print(finalstring)
newstring = generateOne(28)
finalstring = "".join(workingstring)
print(finalstring)
print(countvar)
print("hi")
if __name__ == '__main__':
main()
print("ho")
You can optimize a bit. Strings are immutable - every time you append one char to a string a new string is created and replaces the old one. Use lists of chars instead - also do not use "".join() all the time for printing purposes if you can print the list of chars by decomposing and a seperator of "":
import random
def generateOne(strlen):
"""Create one in one random-call, return as list, do not iterativly add to string"""
alphabet = "abcdefghijklmnopqrstuvwxyz "
return random.choices(alphabet,k=strlen)
def score(goal, teststring):
"""Use zip and generator expr. for summing/scoring"""
return sum(1 if a==b else 0 for a,b in zip(goal,teststring))/len(goal)
def main():
goalstring = list("methinks it is like a weasel") # use a list
newstring = generateOne(28) # also returns a list
workingstring = newstring [:] # copy
countvar = 0
while score(goalstring, workingstring) < 1:
if score(goalstring, newstring) > 0:
for pos,c in enumerate(goalstring): # enumerate for getting the index
# test if equal, only change if not yet ok
if c == newstring[pos] and workingstring[pos] != c:
workingstring[pos] = newstring[pos] # could use c instead
countvar += 1
print(*workingstring, sep="") # print decomposed with sep of ""
# instead of "".join()
newstring = generateOne(28)
finalstring = "".join(workingstring) # create result once ...
# although its same as goalstring
# so we could just assing that one
print(finalstring)
print(countvar)
print("hi")
if __name__ == '__main__':
s = datetime.datetime.now()
main()
print(datetime.datetime.now()-s)
print("ho")
Timings with printouts are very unrelieable. If I comment the print printing the intermediate steps to the final solution and use a `random.seed(42)' - I get for mine:
0:00:00.012536
0:00:00.012664
0:00:00.008590
0:00:00.012575
0:00:00.012576
and for yours:
0:00:00.017490
0:00:00.017427
0:00:00.013481
0:00:00.017657
0:00:00.013210
I am quite sure this wont solve your laptops issues, but still - it is a bit faster.

Removing from a list without affecting a dummy variable

from random import choice
inputs=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func={}
code=""
z=len(inputs)
x=z-1
temp=inputs
while x>=0:
y=choice(temp)
print(str(x)+" "+inputs[x]+" "+y)
func[inputs[x]]=y
code=code+inputs[x]+y
del temp[x]
x=x-1
print(temp)
print(inputs)
Why does this code not asign every element of inputs to a unique and random element of inputs(as the temp dummy set)? it seems to delete items from both temp and inputs when only told to delete items from the dummy set.
Thanks for any help.
You are not making a copy of 'inputs' when you do 'temp=inputs', but making a new variable to access the same content. If you want a new copy of the list, then use 'temp = inputs[:]'. Otherwise you are just creating a new reference to the same object, but not duplicating the object itself.
You can find more about this in the official Python FAQ.
You are creating an alias of your list instead of a true copy of it:
replace temp=inputs with temp=inputs[:]
import random
inputs = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func = {}
code = ""
z = len(inputs)
x = z-1
temp = inputs[:] #<-- here
while x >= 0:
y = random.choice(temp)
print(str(x) + " " + inputs[x] + " " + y)
func[inputs[x]] = y
code = code+inputs[x] + y
del temp[x]
x = x - 1
print(temp)
print(inputs)

python : Noob IndexError

I am currently trying to create a code that can scan a string, put the position of each letter found in a list associated to the letter (ex : if you find a S as the 35, 48 and 120 letter of the string, it will put 35, 48, and 120 in a list for the letter S). It will then put this list in a dictionary as a value with S for key.
My problem is simple, I have an IndexError: list assignment index out of range when I try to put the value in the list, but I cant find out why.
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
va = 0
valA = []
valA[va] = i
va = va + 1
print(valA)
I apologize for my poor English, and thank by advance for the help.
You don't need to specify an index while pushing an item to a list in python. Try this:
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA = []
valA.append(i)
print(valA)
You are getting this error in these lines
va = 0
valA = []
valA[va] = i
valA is blank list here, with zero elements, so when you try to assign a value to its 0 index, it raises IndexError.
Also to get indexes for each character you can directly loop over string, like
s = "Squalalanoussommespartisetjetedteste"
d = dict()
for i, c in enumerate(s):
d.setdefault(c.lower(), []).append(i)
print d
I found some errors in the code.
The index error is because you tried to call 0th position of an empty list.
valA = []
The list is empty. Then you tried to replace value at the 0th position when there is no 0th position
valA[va] = i
I made some changes to the code. In the ninth line you initialize an empty list. You should do that before for loop. Otherwise for loop initiate it everytime and you lose the value in the previous loop.
here is the modified code.
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a":
valA.append(i)
print(valA)
The output i got is
[3, 5, 7, 19]
Though you may use straightforward approach, Python has some usefull modules that may help. For example
import collections
s = "Squalalanoussommespartisetjetedteste"
result = collections.defaultdict(list)
for i,char in enumerate(s):
result[char].append(i)
result would contain a dictionary with string characters as keys and lists if char's indexes as items.
You are redefining variables below everytime. So move them to out of loop.
va = 0
valA = []
Also use insert method for list. (You can use insert for when you need to use define index in list. otherwise append is enough)
so final code :
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
va = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA.insert(va, i)
va = va + 1
print(valA)
index error, because array valA is empty array, that means there are no indexes...
use function append and declare array valA outside the loop...
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA.append(i)
print(valA)

Another IndexError with python

This is supposed to become a random name generator in the end, all the random part is working. Only problem is that it is REALLY random, getting weird stuff like aaaaaaaa etc.
So I'm trying to add a rule to not allow 2 vowels after each other (same goes with consonants).
So yeah, guys please help me out here. I've been looking throu' this code for 2 hours now and I cant find the problem.
Just pasting my entire code here.
import random
import string
import numpy as np
from sys import argv
import csv
# abcdefghijklmnopqrstuvwxyz
# Example output: floke fl0ke flok3 fl0k3
#
class facts:
kons = list('bcdfghjklmnpqrstvwxz') #20
voks = list('aeiouy') #6
abc = list('abcdefghijklmnopqrstuvwxyz')
def r_trfa(): #True Or False (1/0)
x = random.randrange(0, 2)
return x;
def r_kons(): #Konsonant
y = random.randrange(0, 20)
x = facts.kons[y]
return x;
def r_vok(): #Vokal
y = random.randrange(0, 6)
x = facts.voks[y]
return x;
def r_len(): #Langd
x = random.randrange(4, 8)
return x;
def r_type():
x = random.randrange(1, 4)
return x;
def r_structure(length): #Skapar strukturen
y = r_type()
if y == 0:
no1 = 1
else:
no1 = 2
i = 0
x = [no1]
y = r_type()
if not no1 == y:
x.append(y)
while i < length:
y = r_type()
if not x[i] == y:
x.append(y)
i = i + 1
x2 = list(x)
return x2;
def name(): #Final product
struct = r_structure(r_len())
name = struct
You've got several bugs. For example, you're checking the value y against 0 even though it is always in the range 1-4, probably unintended behavior. Furthermore, you never actually call a function that gets you a character, and you never create a string. Thus it's not clear what you're trying to do.
Here's how I'd rewrite things based on my guess of what you want to do.
import random, itertools
voks = frozenset('aeiouy')
abc = 'abcdefghijklmnopqrstuvwxyz'
def r_gen():
last=None #both classes ok
while 1:
new = random.choice(abc)
if (new in voks) != last:
yield new
last = (new in voks)
def name(): #Final product
length = random.randrange(4, 8)
return ''.join(itertools.islice(r_gen(), length))
The problem you're having is that your loop increments i always, but only adds an additional value to your x list if the random value doesn't match x[i]. This means that if you get several matches in a row, i may become larger than the largest index into x and so you'll get an IndexError exception.
I'm not entirely sure I understand what you're trying to do, but I think this will do something similar to your current r_structure function:
def r_structure(length):
"""Returns a list of random "types", avoiding any immediate repeats"""
x = [r_type()]
while len(x) < length:
y = r_type()
if y != x[-1]: # check against the last item in the list
x.append(y)
return x
If your goal is simply to randomly generate a sequence of alternating vowels and consonants, there's an easier way than what you seem to be doing. First off, you can use random.choice to pick your characters. Further, rather than picking many letters and rejecting ones that are of the wrong type, you can simply pick from one string, then pick from the other, for as long as you need:
import random
def alternating_characters(length):
characters = ["aeiouy", "bcdfghjklmnpqrstvwxz"]
char_type = random.randrange(2) # pick a random letter type to start with
results = []
while len(char_list) < length:
results.append(random.choice(characters[char_type])) # pick random char
char_type = 1-char_type # pick from the other list next time
return "".join(char_list)
Well it's unclear what you want to do.. As the conditions on vowels and consonants is the same, so why do you need to differentiate between them?
So all you need to do is take a random letter and check that it doesn't match with the last letter.
Here's some code:
import random
abc = 'abcdefghijklmnopqrstuvwxyz'
def gen_word(length):
last = ''
while length > 0:
l = random.choice(abc)
if l != last:
length -= 1
yield l
if __name__ == '__main__':
word = ''.join(gen_word(10))
print word

Categories