lists and for loop syntax - python

so I'm a beginner programmer and I'm trying to build a python program to print the Fibonacci sequence.
my code is as follows:
fib_sequence = [0,1,1]
def fib_add(x):
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2])
for n in range(2,10):
fib_add(n)
print(fib_seq)
the program says there is a syntax error at the colon on
for n in range(2,10):
I don't know how to correct it

Interestingly, that is not where the syntax error is. It is the preceding line that is the problem:
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2]))
This line was missing closing parentheses. What happens in such cases is that, since the parentheses were not closed, the Python interpreter continues looking for more stuff to put in the expression. It hits the for in the next line and continues all the way to right before the colon. At this point, there is a way to continue the code which is still valid.
Then, it hits the colon. There is no valid Python syntax which allows a colon there, so it stops and raises an error at the first token which is objectively in the wrong place. In terms of your intention, however, we can see that the mistake was actually made earlier.
Also, as noted in a comment, your original list was named fib_sequence, while in the rest of your code you reference fib_list. This will raise a NameError.

You have to place your for loop code inside main. Also as the other answer suggests, you must add another parenthesis after
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2]))
if __name__ == '__main__':
for n in range(2,10):
fib_add(n)
print(fib_seq)

While you have some useful answers, you might look into generators, they make Python a powerful language:
def fibonacci():
x, y = 0, 1
while True:
yield x
x, y = y, x + y
for x in fibonacci():
if x >= 10:
break
print(x)
This prints
0
1
1
2
3
5
8

Here is the corrected code:
fib_seq = [0,1,1]
def fib_add(x):
fib_seq.insert(x, int(fib_seq[x-1]+fib_seq[x-2]))
for n in range(3,10):
fib_add(n)
print(fib_seq)
Resulting Output:
[0, 1, 1, 2]
[0, 1, 1, 2, 3]
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 13]
[0, 1, 1, 2, 3, 5, 8, 13, 21]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Related

What to put in blanks to complete python program (recursion)

I've been at it for hours now yet I still don't know what to put in these blanks. I have an idea on how it will work but I don't know how to apply it. Help!
Basically, I need to find out what are the blanks in order for the program to run. It's a recursion problem where the program would just basically get the sum of all the elements in the list.
enter image description here
Without having to fill in the blanks:
def listsum(numlist):
size=len(numlist)
if(size==1): return numlist[0]
else:
mid=size//2
return listsum(numlist[:mid])+listsum(numlist[mid:])
numbers=[3, 5, 4, 1, 7, 2, 9, 8, 0, 6]
Having to fill in the blanks:
def listsum(numlist, size):
if size==0:
return 0
elif size==1:
return numlist[0]
mid=size//2
return listsum(numlist[:mid], mid)+listsum(numlist[mid:], size-mid)
numbers=[3, 5, 4, 1, 7, 2, 9, 8, 0, 6]
print(listsum(numbers, len(numbers)))
I highly question why such a piece of homework would be meted out to students

Random series whre non are 75% alike

So, I've been trying to make a random series generator with the given numbers using an array:
so the possibilities are: [0-9, 0-9, 0-9, 0 - 59, 0-9, 0-9, 0-9].
The only problem is that I want that all the series aren't even 75% the same (no more than 2 numbers the same).
So here are some examples:
Good:
[1, 1, 1, 1, 1, 1, 1]
[2, 2, 1, 2, 1, 2, 2]
Not good:
[1, 1, 1, 1, 1, 1, 1]
[2, 2, 1, 2, 1, 2, 1]
So, if there are fewer than 2 numbers the same it deletes the second one.
And the second problem is that I want 10,000 of these series.
Sorry if I didn't explain it well, the code would probably explain what I tried to explain.
TRIGGER WARNING!! CODE ISN'T EFFICIENT AT ALL!!
TOTAL_SERIES = 10000
placement_amount = [9, 9, 9, 59, 9, 9, 9]
all_series = []
def create_series():
global fail, success
series = []
for i in range(len(placement_amount)):
series.append(random.randint(0, placement_amount[i]))
for i in all_series:
count = 0
for j in range(len(i)):
if series[j] == i[j]:
count += 1
if count > 2:
return;
all_series.append(series)
while len(all_series) < TOTAL_SERIES:
create_series()
The code technically works but it takes around 1 hour to generate 400 of these since the longer it runs the harder it takes to find a series that follows the rules.
So, my question is how do I make it more efficient and so it will make 10,000 series the fastest a code can.
What I've tried so far:
Tried adding cuda so I'll be able to run the code on a gpu making it faster (have python 32-bit so can't)
Tried creating a few threads where each generates 10,000/threads amount and then run a code that deletes all the ones who don't follow the rules (the code just got stuck).
I'm open to hear how I can try these again but with a correct code or anything that will make it efficient.
The answer for me isn't code efficiency but just that it's impossible make 10,000 series since the first 3 numbers can't be identical, so I changed the lines:
if counter > 2:
to
if counter > 3
Thanks everyone for the help, but if you got a way to make it more efficient it would be nice :D
Your original solution is in O( P(N)*N), you can reduce it to O(P(N)) with dicts and computing the differrent index combinations:
-P(N) is the expected number of iterations to get N such series
- the constants are larger!
import itertools
import random
indexes=list(itertools.combinations(range(7),3))
big_dict={ k : {} for k in indexes }
TOTAL_SERIES = 1000
placement_amount = [9, 9, 9, 59, 9, 9, 9]
all_series = []
loops=0
while len(all_series) < TOTAL_SERIES:
loops+=1
candidate = tuple(random.randint(0, amount) for amount in placement_amount)
if any( (candidate[index[0]],candidate[index[1]],candidate[index[2]]) in \
big_dict[index] for index in indexes ):
continue
else:
for index in indexes:
big_dict[index[(candidate[index[0]],candidate[index[1]],candidate[index[2]])]=True
all_series.append(candidate)
This must be the solution:
import random
def gen_series(pattern):
return [random.randint(0, max_val) for max_val in pattern]
pattern = [9, 9, 9, 59, 9, 9, 9]
for i in range(100):
print(gen_series(pattern))

Python: Dictionary to Spare Vector

I am new to Python and programming in general. I was working on Pyschool exercises Topic 8, Q 11 on converting Dictionary to Spare Vectore.
I was asked to Write a function that converts a dictionary back to its sparese vector representation.
Examples
>>> convertDictionary({0: 1, 3: 2, 7: 3, 12: 4})
[1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4]
>>> convertDictionary({0: 1, 2: 1, 4: 2, 6: 1, 9: 1})
[1, 0, 1, 0, 2, 0, 1, 0, 0, 1]
>>> convertDictionary({})
[]
I have attempted many times. Below is the latest code I have:
def convertDictionary(dictionary):
k=dictionary.keys()
v=dictionary.values()
result=[]
for i in range(0,max(k)):
result.append(0)
for j in k:
result[j]=v[k.index(j)]
return result
The returned error is:
Traceback (most recent call last):
File "Code", line 8, in convertDictionary
IndexError: list assignment index out of range
Could anyone help me? Thank you so much!
Something like this should suffice:
M = max(dictionary, default=0)
vector = [dictionary.get(i, 0) for i in range(M)]
Translated into a plain old for-loop
M = max(dictionary, default=0)
vector = []
for i in range(M):
vector.append(dictionary.get(i, 0))
The get method lets you provide a default as a second argument in case the key is missing. Once you get more advance you could use a defaultdict
Edit: the default parameter for max requires Python >3.4 . You can either use exception handling (generally prefered) or explicit checks for empty dictionary to deal with that case if you have earlier versions.
Your code works logically fine, but you have a problem of indentation. Your function should be:
def convertDictionary(dictionary):
k=dictionary.keys()
v=dictionary.values()
result=[]
for i in range(0,max(k)):
result.append(0)
for j in k:
result[j]=v[k.index(j)]
return result
The problem is that your second for was inside of the first. What you want is to build a list with max(k) elements and then put the right values into it. Then, the two for loops should be one after the other, rather than one inside of the other.

In Python how can I change the values in a list to meet certain criteria

In Python, I have several lists that look like variations of:
[X,1,2,3,4,5,6,7,8,9,X,11,12,13,14,15,16,17,18,19,20]
[X,1,2,3,4,5,6,7,8,9,10,X,12,13,14,15,16,17,18,19,20]
[0,X,2,3,4,5,6,7,8,9,10,11,X,13,14,15,16,17,18,19,20]
The X can fall anywhere. There are criteria where I put an X, but it's not important for this example. The numbers are always contiguous around/through the X.
I need to renumber these lists to meet a certain criteria - once there is an X, the numbers need to reset to zero. Each X == a reset. Each X needs to become a zero, and counting resumes from there to the next X. Results I'd want:
[0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10]
[0,1,2,3,4,5,6,7,8,9,10,0,1,2,3,4,5,6,7,8,9]
Seems like a list comprehension of some type or a generator could help me here, but I can't get it right.
I'm new and learning - your patience and kindness are appreciated. :-)
EDIT: I'm getting pummeled with downvotes, like I've reposted on reddit or something. I want to be a good citizen - what is getting me down arrows? I didn't show code? Unclear question? Help me be better. Thanks!
Assuming the existing values don't matter this would work
def fixList(inputList, splitChar='X'):
outputList = inputList[:]
x = None
for i in xrange(len(outputList)):
if outputList[i] == splitChar:
outputList[i] = x = 0
elif x is None:
continue
else:
outputList[i] = x
x += 1
return outputList
eg
>>> a = ['X',1,2,3,4,5,6,7,8,9,'X',11,12,13,14,15,16,17,18,19,20]
>>> fixList(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b = ['y',1,2,3,4,5,6,7,8,9,10,'y',12,13,14,15,16,17,18,19,20]
>>> fixList(b, splitChar='y')
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
EDIT: fixed to account for the instances where list does not start with either X or 0,1,2,...
Using the string 'X' as X and the_list as list:
[0 if i == 'X' else i for i in the_list]
This will return the filtered list.

quicksort divide-and-conquer returns incorrect partial answer

My program does not return the correct question in the end but it shows correct ones in the intermediate results. I needs help, thanks.
Output sample:
sort begin: A,start,end [3, 5, 2, 1, 7, 6, 8, 4] 0 7
sort begin: A,start,end [2, 1, 3, 5, 7, 6, 8, 4] 0 1
sort begin: A,start,end [1, 2, 3, 5, 7, 6, 8, 4] 3 7
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 3 3
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 7
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 4
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 6 7
####################################################
final result [1, 2, 3, 5, 4, 6, 8, 7]
My code:
def qSort(A,start,end):
print "sort begin: A,start,end",A,start,end
if start >= end:
return A
elif end == start + 1:
if A[start] > A[end]:
A[start],A[end] = A[end],A[start]
return A
else:
i = start + 1
j = i
p = A[start]
while j < end:
j = j + 1
if p > A[j]:
A[i],A[j] = A[j],A[i]
i = i + 1
A = A[0:start] + A[start+1:i]+ [p] + A[i:end+1]
qSort(A,start,i-2)
qSort(A,i,end)
return A
print "###################"
myarray = [3,5,2,1,7,6,8,4]
result = qSort(myarray,0,7)
print "final result",result
Sorry for my lack luster comments. I reviewed your code and realized it was correct! You have one minor coding mistake which I will point out and then explain. In your else block you currently have:
else:
# Bunch of correct stuff
# ...
# Stuff that is ALMOST correct
qSort(A,start,i-2)
qSort(A,i,end)
return A
you need to change this to:
else:
# Bunch of correct stuff
# ...
# Stuff that is definitely correct
A = qSort(A,start,i-2)
A = qSort(A,i,end)
return A
Without going too deeply into this, your function does not discriminate between list references and newly created lists. If you put print A in you elif block right before return A you will notice that on the final iteration, your sort, as is, does everything correctly, and produces the correct list!
Unfortunately, the call that produced this change was one of the lines I've mentioned above which calls the sort but doesn't store the resulting list returned by the recursive function call!
My simple change just takes the modified list returned from secondary function calls to qSort and reassigns the variable A.
Weirdly, this behavior actually worked ok for you sometimes for reasons I cannot fully explain (like the first time you enter your `elif' block which does the right thing and modifies the list correctly). I am sure someone smarter than I surely can explain the odd behavior.
Alternatively, you could come up with a simple way to count recursion depth (number of times your function calls itself) and print that out while debugging with some breakpoints in your favorite IDE.
Heres how you could do that with global variables:
recursion_depth = -1
def qSort(A,start,end):
global recursion_depth
recursion_depth += 1
print "sort begin: A,start,end,level",A,start,end,recursion_depth
# bunch of code edited out for brevity
# ...
result = qSort(myarray,0,7)
print "final result",result

Categories