Python programming beginner difficulties - python

I am trying to write a program in Python, but I am stuck in this piece of code:
def function():
a=[3,4,5,2,4]
b=1
c=0
for x in range(5):
if a[x-1]>b:
c=c+1
return c
print(function())
It gives me value 1 instead of 5. Actually the function I am trying to write is a little bit more complicated, but the problem is actually the same, it doesn't give me the right result.
def result():
r=[0]*len(y)
a=2
b=an_integer
while b>0:
for x in range(len(y)) :
if y[x-1] > 1/a and b>0:
r[x-1]=r[x-1]+1
b=b-1
a=a+1
return r
print(result())
v is a list of values smaller than 1 and b has an integer as value. If some values x in v are bigger than 1/a then the values x in r should get 1 bigger, then it should repeat a=a+1 until b becomes 0. I want this function to give a result of the type for ex. [7,6,5,4,3] where the sum of the elements in this list is equal to b.
Sometimes it gives me the right value, sometimes not and when the elements in v are equal for example v=[0.33333,0.33333,0.33333] it gets stuck and doesn't give me a result.
I don't know what I am doing wrong !

Your return statements are incorrectly indented. You want to return after the loop ends, not inside the loop.
def function():
a = [3, 4, 5, 2, 4]
b = 1
c = 0
for x in range(5):
if a[x-1] > b:
c = c + 1
return c
Also, a couple of optimizations to the code:
def function(a, b):
c = 0
for x in a:
if x > b:
c += 1
return c
or further:
def function(a, b):
return sum(x > b for x in a)

return; only inside the fun in the end it.
and name the Variable v

Related

Changing a list (passed as a function parameter) changes the list with the same name in the previous function call

Recently a friend of mine asked me to explain a strange behavior in a piece of code originally intended to count permutations using recursion. There were many improvements that could be made to the code, which I noted, but these seemed to not have any real impact.
I simplified the code down to the following, which reproduces only the problem, and not the permutations.
def foo(bar, lst):
if(bar == 1):
lst.append(0)
return
print(lst)
foo(1, lst)
print(lst)
foo(2, [])
The output is
[]
[0]
I tried lst += [0] or deleting lst after appending 0, but these did not help. Doing lst2 = lst.copy() followed by lst2.append(0) gave the expected result of two []s, however. I am confused as to why appending 0 (or any value) to lst where bar == 1 would have an effect on the lst where bar == 2. I do not consider myself a total beginner to Python, and I usually can determine the behavior of local variables. This has baffled me though. An explanation would be really appreciated.
In case you want the original code, though I don't think it'll give much more info, here it is:
A = 0
A2 = 0
NN = 3
def P(N, C):
global A
Temp = [X for X in range(1, NN + 1) if X not in C]
if(N == 1):
C.append(None)
A += 1
return
for e in Temp:
C.append(e)
P(N - 1, C)
del C[-1]
def P2(N, C):
global A2
Temp = [X for X in range(1, NN + 1) if X not in C]
if(N == 1):
A2 += 1
return
for e in Temp:
C.append(e)
P2(N - 1, C)
del C[-1]
P(NN, [])
P2(NN, [])
print(A, A2, sep = " ")
print(A == A2)

Is there a compact way to write the below function using ListComprehension/Lambda in Python

The rating for Alice's challenge is the triplet a = (a[0], a[1], a[2]), and the rating for Bob's challenge is the triplet b = (b[0], b[1], b[2]).
The task is to find their comparison points by comparing a[0] with b[0], a[1] with b[1], and a[2] with b[2].
If a[i] > b[i], then Alice is awarded 1 point.
If a[i] < b[i], then Bob is awarded 1 point.
If a[i] = b[i], then neither person receives a point.
Below is the function body:
# The function is expected to return an INTEGER_ARRAY.
# The function accepts following parameters:
# 1. INTEGER_ARRAY a
# 2. INTEGER_ARRAY b
#
def compareTriplets(a, b):
# Write your code here
c=0
d=0
for i in range(0,len(a)-1):
if(a[i]>b[i]):
c+=1
elif(a[i]<b[i]):
d+=1
return array.array("i",[c,d])
First of all, not sure why you're iterating with range(0,len(a)-1) - you are skipping the last element. It should be range(len(a)).
Second, it is more "pythonic" in these cases to use the zip function instead of using indexes. So you could do:
def compareTriplets(alice, bob):
alice_score = 0
bob_score = 0
for a, b in zip(alice, bob):
if a > b:
alice_score += 1
elif a < b:
bob_score += 1
return array.array("i", [alice_score, bob_score])
If you're looking for shorter code (note that it doesn't mean better or faster code!), you could use the sum function:
def compareTriplets(alice, bob):
alice_score = sum(a > b for a, b in zip(alice, bob))
bob_score = sum(a < b for a, b in zip(alice, bob))
return array.array("i", [alice_score, bob_score])
As you can see this loops over the zip twice. For two tuples of three elements this is insignificant, but it is important to take in count that once you're dealing with big data, this approach is not ideal.
Here is the comprehension for ya:
def compareTriplets(a, b):
return [sum(tot) for tot in zip(*((aa > bb, aa < bb) for aa, bb in zip(a, b)))]

Access 2D array slots by a number and vice versa

I want to map an array indices to a number, if this is an array:
grid2=[ ['a','b','c'],
['x','y','z']]
the number of 'a' is 1 and the number of 'b' is 2 and the number of 'c' is 3 and the number of 'x' is 4 and the number of 'y' is 5 and the number of 'z' is 6.
Here is my attempt, but it works only for squared arrays:
def i2d(r,c):
return r*height + c+1
here is the result which is not correct:
slot number of a=1 slot number of b=2 slot number of c=3
slot number of x=6 slot number of y=7 slot number of z=8
the correct result should be:
slot number of a=1 slot number of b=2 slot number of c=3
slot number of x=4 slot number of y=5 slot number of z=6
Also I want to write a convert method for mapping an integer to array index, here is my attempt:
def d2i(d):
r= int(d/height)-1
c= width - r
return (r,c)
but unfortunately, the final output is not correct. please help me in writing these two functions, I don't why my algorithm development aspect is turned off, maybe it is a side effect of using frameworks and libraries that they do the logic behind the scene, and I have used to call them.
Please tell me about the pythonish code if python has solved this by one of its operators or library functions, I want to learn it if such a thing exists.
Example : (input/output)
grid= [['a','b','c'],['x','y','z']]
#desired slot numbers=[1 ,2 ,3 ,4 ,5 ,6]
x = i2d(0,2)
#so x would be 3 if the we suppose number of a is 1
slot = d2i(3)
row=slot[0]
col=slot[1]
print(grid[row][col])
#the output is 'c'
Thanks in advance
UPDATE
I think calculation the slot number for an array index has different formula for when W=H and W>H and W<H:
def i2d(r,c,w,h):
if(h>w):
return r*h + c-r+1
if(h==w):
return r*h+c+1
if(h < w):
return r * w + c + 1
I cannot find any examples where this doesn't work.
def i2d(r, c, w):
return r * w + c + 1
def d2i(d, w):
div = int((d - 1) / w)
return (div, (d - 1) % w)
Is this what you're looking for? Outputs are commented throughout.
grid2 = [['a','b','c'], ['x','y','z']]
height = 2
width = 3
def i2d(r = None, c = None):
a = 1
if r is not None and c is not None:
for i in range(height):
for j in range(width):
if i == r and j == c:
return a
a += 1
print(i2d(0, 2)) # 3
def d2i(l, d):
for i in range(height):
for j in range(width):
if d == i2d(i, j):
return l[i][j]
print(d2i(grid2, 3)) # 'c'
Try this, it works for me :
width=3
height=3
def i2d(r,c):
return r*width + c+1
def d2i(d):
r= int(d/width)
#cover the h=w case
if (d%width==0 and width==height):
r=r-1
c= d%width-1
return (r,c)

Least Common Multiple of 2 numbers by prime factors of number

In this code, I am trying to get prime factors for the prime method to find LCM. then I am trying to save it by counter but I am not able to divide both key and values for the proper method.
I'm stuck at counter, please can anyone help me?
from collections import Counter
def q2_factor_lcm(a, b): #function for lcm
fa = factor_list(a) #factor list for a
fb = factor_list(b) #factorlist for b
c = Counter(fa) #variables to save counter for a
d = Counter(fb) #variables to save counter for b
r = c | d
r.keys()
for key, value in sorted(r.items()): # for loop for getting counter subtraction
l = pow(key, value)
result = [] # I am getting confused what to do now
for item in l:
result.append(l)
return result #will return result
def factor_list(n): # it is to generate prime numbers
factors = [] # to save list
iprimes = iter( primes_list(n) ) # loop
while n > 1:
p = next(iprimes)
while n % p == 0: # python calculation
n = n // p
factors.append(p)
return factors # it will return factors
First this method is not really efficient to find a lcm. As there are some nice and clean algo to find a gcd, it is easier to get the lcm of a and b by lcm = a * b / gcd(a,b) (*).
Second, never use pow with integer values. Floating point arithmetics is know to be broken not accurate.
Now for your question. The update operation on the 2 counters in not what you want: you lose one of the values when a key is present in both dicts. You should instead use the union of the key sets, and then use the max of both values (a non existent key is seen as a 0 value for the exponent):
...
# use a true dict to be able to later use the get method with a default
c = dict(Counter(fa)) #variables to save counter for a
d = dict(Counter(fb)) #variables to save counter for b
result = []
for key in sorted(set(c.keys()).union(set(d.keys()))):
exp = max(c.get(key, 0), d.get(key, 0))
for i in range(exp):
result.append(key)
return result
(*) The trick is that when a > b, GCD(a,b) is GCD(b, mod(a,b)). In Python it gives immediately:
def gcd(a, b):
if b > a:
return gcd(b, a)
if b == 1:
return b
m = a % b
return b if m == 0 else gcd(b, m)
def lcm(a,b):
return a * b / gcd(a,b)

Python gives strange values of factorial

x = 5
def SsolGom():
k = 1
for i in range( 1 , x+1 ):
k = k * i
print(SsolGom)
=function SsolGom at 0x00F1B660
120 must come out but strange value came out...
SsolGom is a function, SsolGom() is the value returned by this function. It's similar in math: sin is a function, sin(0) is a number.
x = 5
def SsolGom():
k = 1
for i in range( 1 , x+1 ):
k = k * i
return k
print(SsolGom())
# 120
You need to have a correct indentation inside your function, and you need to return a value. SsolGom() would be None otherwise.
Note that x probably shouldn't be a global variable. Otherwise, your function could be replaced by return 120:
def factorial(x):
k = 1
for i in range(x):
k = k * (i + 1)
return k
print(factorial(5))
Finally, here's the easiest way to get factorial in Python:
>>> from math import factorial
>>> factorial(5)
120
You're missing the brackets. It should be:
print(SsolGom())
You are printing the function without the parenthesis. Calling a function with and without parenthesis gives different results in Python. If you do not provide a parenthesis, Python considers it as properties and not a method/function. Hence you got that result
provide a return statement in the function.
Updated Code:
x=5
def SsolGom():
k=1
for i in range( 1 , x+1 ):
k=k*i
return k
print(SsolGom())

Categories

Resources