Python separate objects using copy method - python-2.7

every one. I was trying to use the method copy(), but I was really frustrated it seems that there was bug within my program. I was supposed to get ct=99 only instead of ct =0, when comparing c1 and c2, but it turns out there are so extra terms behind.
Just run the code , and you can immediately spot What that weird thing is. Thank you every one.
NB: This problem is a generic programming problem and has nothing to do with Fourvector.
import numpy as np
class FourVector:
""" This document is a demonstration of how to create a class of Four vector """
def __init__(self, ct=0, x=1, y=5, z=2, r=None):
self.ct = ct
self.r = np.array(r if r else [x,y,z])
def __repr__(self):
return "%s(ct=%g,r=array%s)"% ("FourVector",self.ct,str(self.r))
def copy(self):
return FourVector(self.ct,self.r)
c1=FourVector(ct=0,r=[1,2,3]) # Note: c1,c2 here are objects, we used __repr__ to make them printable
print c1
c2=c1.copy() #use method copy within object c1
c2.ct=99
print c2

When you are copying, you are passing two unnamed arguments to FourVector.__init__. Python interprets them positionally, so you are effectively calling:
FourVector.__init__(new_self, ct=self.ct, x=self.r, y=5, z=2, r=None)
r is still None, so new_self.r is assigned to be np.array([self.r, y, z]). This is why the array in c2 has extra terms.
Instead, you need to tell Python that the second value should be for the r argument, not just the second argument:
def copy(self):
return FourVector(self.ct, r=self.r)
Alternatively, you could either re-order the arguments:
def __init__(self, ct, r=None, x=1, y=5, z=2):
or even remove the x, y and z arguments and provide them as the default value for r:
def __init__(self, ct, r=[1,5,2]):

Related

Use value to another function in any function

def anshu():
a=1+2
print(a)
anshu()
def sanju():
b=2+3
print(b)
sanju()
def bala():
c=a+b
print(c)
can you explain?
I gave many value in one or more function i want use these value in any function in python
To access a variable from one function in another function, you can either return the variable from the first function and pass it as an argument to the second function, or you can make the variable global so that it can be accessed from any function. Here's an example using the first approach:
def anshu():
a = 1 + 2
return a
def sanju():
b = 2 + 3
return b
def bala(a, b):
c = a + b
print(c)
anshu_result = anshu()
sanju_result = sanju()
bala(anshu_result, sanju_result)
Here's an example using the second approach:
def anshu():
global a
a = 1 + 2
def sanju():
global b
b = 2 + 3
def bala():
c = a + b
print(c)
anshu()
sanju()
bala()
Note that using global variables is generally not considered good practice, because it can make your code difficult to maintain and debug. It's usually better to use the first approach of passing variables as arguments to functions.

How to increment std:set iterator by more than one in Cython?

I have a C++ std:set for which I want to implement "fake" indexing in Cython. Let's say I have an extension type that wraps the set and I want to have a method get_member(int i) which returns the ith element in the set. This is what I got, basically iterating over the set using cython.operator.preincrement until the desired point is reached and then dereferencing the current iterator position:
# distutils: language = c++
from cython.operator cimport dereference, preincrement
from libcpp.set cimport set as cppset
cdef class SetWrapper:
cdef cppset[int] _set
def __cinit__(self, s: set = None):
if s is not None:
self._set = s
cpdef int get_member(self, int i):
cdef cppset[int].iterator it = self._set.begin()
cdef int count
# Would it be possible to increment it directly by i?
for count in range(i):
preincrement(it)
return dereference(it)
test_set = SetWrapper({1, 2, 3})
test_set.get_member(2)
# 3
While this works, it seems a bit wasteful to always iterate through the set when it was possible to increment the iterator directly by i positions. Is this possible in some way?
PS: Let's put aside the fact that this is not quite what one is supposed to use sets for...

Strange behaviour of list.remove()

Consider the following piece of code.
def foo(a):
b = [a+9*i+j for i in xrange(0,3) for j in xrange(0,3)]
return b.remove(a)
The code doesn't work. It returns an null. But if I do the following, it works.
def foo1(a):
return [a+9*i+j for i in xrange(0,3) for j in xrange(0,3)]
b = foo1(a)
b = b.remove(a) # This works
Why does the first snippet fail when the second one works?
.remove(...) does not return any value. According to official documentation
You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. This is a design principle for all mutable data structures in Python.

Objects and Lists

I have a duck Class, such that each Duck object created contains wingspan and weight field variables. Each of these should be initialized randomly for every duck. Wingspans should be initialized to a random float in the range [80.0,100.0]cm. Weight should be initialized randomly in the range [0.7,1.6]kg. I have
import random
class Duck:
def __init__(self):
self.wingspan = round(random.uniform(80.0, 100.0), 1)
self.weight = round(random.uniform(0.7,1.6), 2)
But the second part is asking me to write a function called makeFlock() that takes an integer parameter, n, and returns a list of n Duck objects. I'm not sure how to do this. Any suggestions?
def makeFlock(n):
flock = []
for _ in range(n):
flock.append(Duck())
return(flock)

How to access or change the value of a variable inside a function which is nested inside another fucntion?

def next1():
x=1
def nest2():
x+=1
nest2()
return x
When I try to call the fucntion nest1(), it says "local variable 'x' referenced before assignment
". I want to access x which is declared at line 2 inside nest2(). What is the solution?
in your nested function you havent defined x. you need to pass x to it def nest2(x): plus you have an infinite loop in nest2() - it continually calls itself, and never returns a value.
Why not do it this way? or is there some reason it needs to be nested.
def nest2(value):
value +=1
return value
def next1():
x=1
nest2(x)
return x