i am just trying...but the self.value show error ie...i want to loop self.a,self.b,self.c...help require for learning help required......output wanted is x= [AA,EE,II] using classes and loops.i tried looping the self.a,self.b,self.c using for loop.........i am learning python and object oriented programming newly....help me out
import string
A = ["AA","BB","CC","DD"]
B = ["EE","FF","GG","HH"]
C = ["II","JJ","KK","LL"]
class User:
def __init__(self,A,B,C):
self.a= A
self.b= B
self.c= C
def User1(self):
x=[]
for i in range(ord('a'), ord('c')+1):
value= chr(i)
x.append= self.(value)[0] ///for getting first elemen from A,B,C
i+=1
return x
honey= User(A,B,C)
print(honey.User1())
WHat you want is to use getattr - but there are a few other things broken there. (to start with the fact that the comment character is # in Python, and not the // sequence.
So, your User1 method could be something like:
def User1(self):
x=[]
for value in "abc":
x.append(getattr(self, value)[0])
return x
Note as well that the for statement will always iterate over a sequence, and you don't need to go long ways to convert your sequence to numbers, just for converting those numbers back to the desired elements. As a string is also a sequence of characters - just looping over "abc" will yield your desired letters.
As stated above, the getattr built-in will then retrieve the desired attribute from self gven the attribute name as a string, contained in the value variable.
Related
How can I pass an integer by reference in Python?
I want to modify the value of a variable that I am passing to the function. I have read that everything in Python is pass by value, but there has to be an easy trick. For example, in Java you could pass the reference types of Integer, Long, etc.
How can I pass an integer into a function by reference?
What are the best practices?
It doesn't quite work that way in Python. Python passes references to objects. Inside your function you have an object -- You're free to mutate that object (if possible). However, integers are immutable. One workaround is to pass the integer in a container which can be mutated:
def change(x):
x[0] = 3
x = [1]
change(x)
print x
This is ugly/clumsy at best, but you're not going to do any better in Python. The reason is because in Python, assignment (=) takes whatever object is the result of the right hand side and binds it to whatever is on the left hand side *(or passes it to the appropriate function).
Understanding this, we can see why there is no way to change the value of an immutable object inside a function -- you can't change any of its attributes because it's immutable, and you can't just assign the "variable" a new value because then you're actually creating a new object (which is distinct from the old one) and giving it the name that the old object had in the local namespace.
Usually the workaround is to simply return the object that you want:
def multiply_by_2(x):
return 2*x
x = 1
x = multiply_by_2(x)
*In the first example case above, 3 actually gets passed to x.__setitem__.
Most cases where you would need to pass by reference are where you need to return more than one value back to the caller. A "best practice" is to use multiple return values, which is much easier to do in Python than in languages like Java.
Here's a simple example:
def RectToPolar(x, y):
r = (x ** 2 + y ** 2) ** 0.5
theta = math.atan2(y, x)
return r, theta # return 2 things at once
r, theta = RectToPolar(3, 4) # assign 2 things at once
Not exactly passing a value directly, but using it as if it was passed.
x = 7
def my_method():
nonlocal x
x += 1
my_method()
print(x) # 8
Caveats:
nonlocal was introduced in python 3
If the enclosing scope is the global one, use global instead of nonlocal.
Maybe it's not pythonic way, but you can do this
import ctypes
def incr(a):
a += 1
x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref
Really, the best practice is to step back and ask whether you really need to do this. Why do you want to modify the value of a variable that you're passing in to the function?
If you need to do it for a quick hack, the quickest way is to pass a list holding the integer, and stick a [0] around every use of it, as mgilson's answer demonstrates.
If you need to do it for something more significant, write a class that has an int as an attribute, so you can just set it. Of course this forces you to come up with a good name for the class, and for the attribute—if you can't think of anything, go back and read the sentence again a few times, and then use the list.
More generally, if you're trying to port some Java idiom directly to Python, you're doing it wrong. Even when there is something directly corresponding (as with static/#staticmethod), you still don't want to use it in most Python programs just because you'd use it in Java.
Maybe slightly more self-documenting than the list-of-length-1 trick is the old empty type trick:
def inc_i(v):
v.i += 1
x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)
A numpy single-element array is mutable and yet for most purposes, it can be evaluated as if it was a numerical python variable. Therefore, it's a more convenient by-reference number container than a single-element list.
import numpy as np
def triple_var_by_ref(x):
x[0]=x[0]*3
a=np.array([2])
triple_var_by_ref(a)
print(a+1)
output:
7
The correct answer, is to use a class and put the value inside the class, this lets you pass by reference exactly as you desire.
class Thing:
def __init__(self,a):
self.a = a
def dosomething(ref)
ref.a += 1
t = Thing(3)
dosomething(t)
print("T is now",t.a)
In Python, every value is a reference (a pointer to an object), just like non-primitives in Java. Also, like Java, Python only has pass by value. So, semantically, they are pretty much the same.
Since you mention Java in your question, I would like to see how you achieve what you want in Java. If you can show it in Java, I can show you how to do it exactly equivalently in Python.
class PassByReference:
def Change(self, var):
self.a = var
print(self.a)
s=PassByReference()
s.Change(5)
class Obj:
def __init__(self,a):
self.value = a
def sum(self, a):
self.value += a
a = Obj(1)
b = a
a.sum(1)
print(a.value, b.value)// 2 2
In Python, everything is passed by value, but if you want to modify some state, you can change the value of an integer inside a list or object that's passed to a method.
integers are immutable in python and once they are created we cannot change their value by using assignment operator to a variable we are making it to point to some other address not the previous address.
In python a function can return multiple values we can make use of it:
def swap(a,b):
return b,a
a,b=22,55
a,b=swap(a,b)
print(a,b)
To change the reference a variable is pointing to we can wrap immutable data types(int, long, float, complex, str, bytes, truple, frozenset) inside of mutable data types (bytearray, list, set, dict).
#var is an instance of dictionary type
def change(var,key,new_value):
var[key]=new_value
var =dict()
var['a']=33
change(var,'a',2625)
print(var['a'])
For example, in python, when I type in ord("a") it returns 97 because it refers to the ascii list. I want ord("a") to return zero from a string that I created such as
alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 .,?!"
so ord("b") would be 1 and ord("c") would be 2 ect.
How would I go about doing this?
You don't.
You're going about this the wrong way: you're making the mistake
This existing thing doesn't meet my needs. I want to make it meet my needs!
instead, the way to go about the problem is
This existing thing doesn't meet my needs. I need a thing that does meet my needs!
Once you realize that, the problem is now pretty straightforward. e.g.
DEFAULT_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789 .,?!"
def myord(x, alphabet=DEFAULT_ALPHABET):
return alphabet.find(x)
Something like this should do the trick:
def my_ord(c):
alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 .,?!"
return alphabet.index(c)
If i've understood correctly, this is what you want:
alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 .,?!"
def crypt(c, key=97):
return ord(c)-key
def decrypt(c, key=97):
return chr(c+key)
dst = [crypt(c) for c in alphabet]
src = [decrypt(c) for c in dst]
print dst
print ''.join(src)
You can create a dict to map from characters to indices and then do lookups into that. This will avoid repeatedly searching the string as other answers are suggesting (which is O(n)) and instead give O(1) lookup time with respect to the alphabet:
my_ord_dict = {c : i for i, c in enumerate(alphabet)}
my_ord_dict['0'] # 26
At that point you can easily wrap it in a function:
def my_ord(c):
return my_ord_dict['0']
Or use the bound method directly
my_ord = my_ord_dict.__getitem__
But you don't want to change the name that refers to a builtin function, that'll confuse everyone else trying to use it that can see your change. If you are really trying to hurt yourself you can replace my_ord with ord in the above.
I am taking a class and i'm confused. It would really help if you could guide me through the proccess of this and tell me what I am doing wrong. I have an error that has to do with the parentheses since theres nothing in them. I am a newbie so i'm sorry.
def FractionDivider(a,b,c,d):
n = ()
d = ()
n2 = ()
d2 = ()
print int(float(n)/d), int(float(n2)/d2)
return float (n)/d / (n2)/d2
Your function is taking in arguments a, b, c, and d, but you're not using them anywhere. You're instead defining four new variables. Try:
def FractionDivider(n, d, n2, d2):
and get rid of your empty parentheses bits, see if that does what you are trying to do.
you cannot declare a variable as you are doing n = () and then try to assign an integer or string to it.
n=() does not mean:
n equals nothing at the moment but i will assign a variable shortly.
() ---> Tuples https://docs.python.org/3/tutorial/datastructures.html
They are two examples of sequence data types (see Sequence Types —
list, tuple, range). Since Python is an evolving language, other
sequence data types may be added. There is also another standard
sequence data type: the tuple.
so within your function, if you want you varialbes to be assigned what is passed as an argument
for Ex:
def FractionDivider(a,b,c,d):
n = a
d = b
n2 = c
d2 = d
consider reading more on tuples from the above link
n=() is a valid python statement and there is no issue with that. However n=() is evaluating n to an empty tuple(). I believe that what you are trying to do is as follows.
def FractionDivider(a,b,c,d):
'''
Divides a fraction by another fraction...
'''
n = a #setting each individual parameter to a new name.
d = b #creating a pointer is often useful in order to preserve original data
n2 = c #but it is however not necessary in this function
d2 = d
return (float(n)/d) / (float(n2)/d2) #we return our math, Also order of operations exists here '''1/2/3/4 != (1/2)/(3/4)'''
print FractionDivider(1, 2, 3, 4) #here we print the result of our function call.
#indentation is extremely important in Python
here is a simpiler way of writing the same function
def FractionDivider_2(n,d,n2,d2):
return (float(n)/d) / (float(n2)/d2)
print FractionDivider_2(1,2,3,4)
I'm trying to write a function to return the word string of any number less than 1000.
Everytime I run my code at the interactive prompt it appears to work without issue but when I try to import wordify and run it with a test number higher than 20 it fails as "TypeError: 'function' object is unsubscriptable".
Based on the error message, it seems the issue is when it tries to index numString (for example trying to extract the number 4 out of the test case of n = 24) and the compiler thinks numString is a function instead of a string. since the first line of the function is me defining numString as a string of the variable n, I'm not really sure why that is.
Any help in getting around this error, or even just help in explaining why I'm seeing it, would be awesome.
def wordify(n):
# Convert n to a string to parse out ones, tens and hundreds later.
numString = str(n)
# N less than 20 is hard-coded.
if n < 21:
return numToWordMap(n)
# N between 21 and 99 parses ones and tens then concatenates.
elif n < 100:
onesNum = numString[-1]
ones = numToWordMap(int(onesNum))
tensNum = numString[-2]
tens = numToWordMap(int(tensNum)*10)
return tens+ones
else:
# TODO
pass
def numToWordMap(num):
mapping = {
0:"",
1:"one",
2:"two",
3:"three",
4:"four",
5:"five",
6:"six",
7:"seven",
8:"eight",
9:"nine",
10:"ten",
11:"eleven",
12:"twelve",
13:"thirteen",
14:"fourteen",
15:"fifteen",
16:"sixteen",
17:"seventeen",
18:"eighteen",
19:"nineteen",
20:"twenty",
30:"thirty",
40:"fourty",
50:"fifty",
60:"sixty",
70:"seventy",
80:"eighty",
90:"ninety",
100:"onehundred",
200:"twohundred",
300:"threehundred",
400:"fourhundred",
500:"fivehundred",
600:"sixhundred",
700:"sevenhundred",
800:"eighthundred",
900:"ninehundred",
}
return mapping[num]
if __name__ == '__main__':
pass
The error means that a function was used where there should have been a list, like this:
def foo(): pass
foo[3]
You must have changed some code.
By the way, wordify(40) returned "fourty". I spell it "forty"
And you have no entry for zero
In case someone looks here and has the same problem I had, you can also get a pointer to a function object if the wrong variable name is returned. For example, if you have function like this:
def foo():
my_return_val = 0
return return_val
my_val = foo()
then my_val will be a pointer to a function object which is another cause to "TypeError: 'function' object is unsubscriptable" if my_val is treated like a list or array when it really is a function object.
The solution? Simple! Fix the variable name in foo that is returned to my_return_val.
I'm writing a parser, and there is LOTS of text to decode but most of my users will only care about a few fields from all the data. So I only want to do the decoding when a user actually uses some of the data. Is this a good way to do it?
class LazyString(str):
def __init__(self, v) :
self.value = v
def __str__(self) :
r = ""
s = self.value
for i in xrange(0, len(s), 2) :
r += chr(int(s[i:i+2], 16))
return r
def p_buffer(p):
"""buffer : HASH chars"""
p[0] = LazyString(p[2])
Is that the only method I need to override?
I'm not sure how implementing a string subclass is of much benefit here. It seems to me that if you're processing a stream containing petabytes of data, whenever you've created an object that you don't need to you've already lost the game. Your first priority should be to ignore as much input as you possibly can.
You could certainly build a string-like class that did this:
class mystr(str):
def __init__(self, value):
self.value = value
self._decoded = None
#property
def decoded(self):
if self._decoded == None:
self._decoded = self.value.decode("hex")
return self._decoded
def __repr__(self):
return self.decoded
def __len__(self):
return len(self.decoded)
def __getitem__(self, i):
return self.decoded.__getitem__(i)
def __getslice__(self, i, j):
return self.decoded.__getslice__(i, j)
and so on. A weird thing about doing this is that if you subclass str, every method that you don't explicitly implement will be called on the value that's passed to the constructor:
>>> s = mystr('a0a1a2')
>>> s
¡¢
>>> len(s)
3
>>> s.capitalize()
'A0a1a2'
I don't see any kind on lazy evaluation in your code. The fact that you use xrange only means that the list of integers from 0 to len(s) will be generated on demand. The whole string r will be decoded during string conversion anyway.
The best way to implement lazy sequence in Python is using generators. You could try something like this:
def lazy(v):
for i in xrange(0, len(v), 2):
yield int(v[i:i+2], 16)
list(lazy("0a0a0f"))
Out: [10, 10, 15]
What you're doing is built in already:
s = "i am a string!".encode('hex')
# what you do
r = ""
for i in xrange(0, len(s), 2) :
r += chr(int(s[i:i+2], 16))
# but decoding is builtin
print r==s.decode('hex') # => True
As you can see your whole decoding is s.decode('hex').
But "lazy" decoding sounds like premature optimization to me. You'd need gigabytes of data to even notice it. Try profiling, the .decode is 50 times faster that your old code already.
Maybe you want somthing like this:
class DB(object): # dunno what data it is ;)
def __init__(self, data):
self.data = data
self.decoded = {} # maybe cache if the field data is long
def __getitem__(self, name):
try:
return self.decoded[name]
except KeyError:
# this copies the fields data
self.decoded[name] = ret = self.data[ self._get_field_slice( name ) ].decode('hex')
return ret
def _get_field_slice(self, name):
# find out what part to decode, return the index in the data
return slice( ... )
db = DB(encoded_data)
print db["some_field"] # find out where the field is, get its data and decode it
The methods you need to override really depend on how are planning to use you new string type.
However you str based type looks a little suspicious to me, have you looked into the implementation of str to check that it has the value attribute that you are setting in your __init__()? Performing a dir(str) does not indicate that there is any such attribute on str. This being the case the normal str methods will not be operating on your data at all, I doubt that is the effect you want otherwise what would be the advantage of sub-classing.
Sub-classing base data types is a little strange anyway unless you have very specific requirements. For the lazy evaluation you want you are probably better of creating your class that contains a string rather than sub-classing str and write your client code to work with that class. You will then be free to add the just in time evaluation you want in a number of ways an example using the descriptor protocol can be found in this presentation: Python's Object Model (search for "class Jit(object)" to get to the relevant section)
The question is incomplete, in that the answer will depend on details of the encoding you use.
Say, if you encode a list of strings as pascal strings (i.e. prefixed with string length encoded as a fixed-size integer), and say you want to read the 100th string from the list, you may seek() forward for each of the first 99 strings and not read their contents at all. This will give some performance gain if the strings are large.
If, OTOH, you encode a list of strings as concatenated 0-terminated stirngs, you would have to read all bytes until the 100th 0.
Also, you're speaking about some "fields" but your example looks completely different.