How to find compatible alternative to string.atol in python3 - python-3.x

I am trying to make my python2.x-Code compatible with both 2.7 and 3.x. Currently I am stuck at some Code in Pmw.py (from python megawidgets). Have a a look at the first three entries of this dictionary:
_standardValidators = {
'numeric' : (numericvalidator, string.atol),
'integer' : (integervalidator, string.atol),
'hexadecimal' : (hexadecimalvalidator, lambda s: string.atol(s, 16)),
'real' : (realvalidator, Pmw.stringtoreal),
'alphabetic' : (alphabeticvalidator, len),
'alphanumeric' : (alphanumericvalidator, len),
'time' : (timevalidator, Pmw.timestringtoseconds),
'date' : (datevalidator, Pmw.datestringtojdn),
}
The first two entries contain "string.atol". My questions are:
In the python docs atol is introduced as a function ( string.atol(s[, base]) ) , so there should be parentheses, which are missing here. So how is this syntax to be understood?
In python 3.2 this code raises the error:
'numeric' : (numericvalidator, string.atol),
AttributeError: 'module' object has no attribute 'atol'
I already tried replacing the three occurences of "atol" with long, like suggested in the python docs, but that just raised the error:
'numeric' : (numericvalidator, string.long),
AttributeError: 'module' object has no attribute 'long'
As I don't even understand the syntax, I'm quite helpless about what to try next. How is this code to be fixed, so that it works both in python 2.7 and 3.x?
Hope you can help me on that one.

1: string.atol is the function itself: functions are first-class objects in python. The parentheses are only used for a call.
>>> import string
>>> string.atol
<function atol at 0x00B29AB0>
>>> string.atol("aab2", 16)
43698L
2: I think you must have misread. long doesn't live in string, but there isn't a long in Python 3 anyway. That's a relic of when Python distinguished between small integers and long integers in ways that could be seen from userspace. (That's what the "L" on the end of 43698L above means.)
Simply use int, i.e.
'numeric': (numericvalidator, int),

When the parenthesis are missing, you're assigning the function itself, rather than the results of a function call.
Try replacing string.atol with int.

Related

AttributeError: 'int' object has no attribute 'pop'

When writing list inside tuple, getting error:
AttributeError: 'int' object has no attribute 'pop'
fruits=('apple','banana', ['kiwi','grapes'])
fruits[1].pop()
fruits[1].append('rice')
print(fruits)
I am getting:
str object has no attribute pop
which is what I was expecting since fruits[1] is 'banana' which is a string and strings do not have a pop method.
If you look at the next line you will run into a similar issue since strings also don't have an append method.
If you remove both of those lines you shouldn't have any errors with just the list inside of the tuple.
fruits = ('apple','banana', ['kiwi','grapes'])
print(fruits)
Your issue is coming from you trying to pop a string, in the second line of your code - not from adding a list in the tuple. Now as tuples are immutable in python, you will need to convert it into a list if you wish to start modyfing what is inside of it. A simple example using your code is below.
fruits=('apple','banana', ['kiwi','grapes'])
fruits_list = list(fruits)
fruits_list.pop(1)
fruits_list.insert(1, 'rice')
fruits = tuple(fruits_list)
print(fruits)
You can read more about it here: pop/remove items out of a python tuple

Why can't I sort a list of dicts in 3.x? Why do I get "TypeError: '<' not supported between instances of 'dict' and 'dict'"?

I had a perfectly functioning sort by value in python 2.7 but I'm trying to upgrade to python 3.6 and I get that error:
TypeError: '<' not supported between instances of 'dict' and 'dict'
Here is my code
server_list = []
for server in res["aggregations"]["hostname"]["buckets"]:
temp_obj = []
temp_obj.append({"name":server.key})
temp_obj.append({"stat": server["last_log"]["hits"]["hits"][0]["_source"][system].stat})
server_list.append(temp_obj)
server_list.sort(key=lambda x: x[0], reverse=False)
Why it's considered as a dict when I declare my server_list as a list. How can I make it sort by my name attribute?
Python 2's dictionary sort order was quite involved and poorly understood. It only happened to work because Python 2 tried to make everything orderable.
For your specific case, with {'name': ...} dictionaries with a single key, the ordering was determined by the value for that single key.
In Python 3, where dictionaries are no longer orderable (together with many other types), just use that value as the sorting key:
server_list.sort(key=lambda x: x[0]['name'], reverse=False)

Using {scatter, line}_kws argument in Seaborn

I am trying to customize a regplot using the _kws argument but I get an exception. In fact I do not know how to use this argument, how to pass values to it and even what kind of properties I can influence through this argument. I can not find relevant documentation and examples.
Here is a sample of code that returns an exception. I tried other things as well but all return error messages.
toy_data # json format
'{"REGION":{"3041":2,"1335":5,"6261":8,"548":7,"4471":8,"3226":5,"5601":5,"1141":4,"1175":4,"1825":5,"5038":4,"3767":5,"1536":1,"168":5,"6247":6,"31":5,"1107":3,"5067":6,"985":3,"6176":5,"3415":6,"3013":2,"4785":1,"2676":3,"228":8,"5807":7,"530":7,"4678":5,"1062":3,"1698":3,"6648":3,"4686":5,"571":7,"760":5,"5178":9,"6090":8,"4945":2,"5636":7,"490":8,"1734":4,"3012":2,"14":5,"4637":2,"3239":4,"5866":2,"5297":4,"3011":2,"612":1,"1137":4,"1384":5,"3194":5,"632":2,"3820":3,"3923":9,"6580":3,"3870":9,"5952":5,"6423":5,"1101":3,"4622":6,"975":3,"1954":7,"4515":3,"1252":4,"457":8,"4712":1,"4446":6,"788":5,"2392":2,"704":5,"2378":2,"547":7,"115":6,"3703":8,"1949":7,"5852":8,"1468":2,"1680":3,"471":8,"750":5,"2605":3,"3974":6,"3029":2,"1237":4,"1521":1,"2543":5,"5907":6,"5782":4,"5974":5,"4070":9,"1838":5,"3880":9,"1938":4,"2596":4,"6533":2,"2941":2,"6160":2,"3572":7,"2326":2,"1355":5},"Tuition":{"3041":20825.0,"1335":10948.0,"6261":null,"548":14144.0,"4471":8622.0,"3226":14190.0,"5601":12897.0,"1141":23799.0,"1175":13141.0,"1825":2372.0,"5038":null,"3767":3732.0,"1536":null,"168":19143.0,"6247":9804.0,"31":8000.0,"1107":20203.0,"5067":null,"985":12334.0,"6176":8459.0,"3415":6561.0,"3013":13496.0,"4785":20544.0,"2676":32395.0,"228":13328.0,"5807":21132.0,"530":8212.0,"4678":15113.0,"1062":17176.0,"1698":17596.0,"6648":null,"4686":null,"571":14405.0,"760":4987.0,"5178":15505.0,"6090":15685.0,"4945":23896.0,"5636":13710.0,"490":5906.0,"1734":22306.0,"3012":21284.0,"14":4499.0,"4637":25300.0,"3239":19052.0,"5866":null,"5297":10399.0,"3011":11401.0,"612":35653.0,"1137":19869.0,"1384":15669.0,"3194":18833.0,"632":22675.0,"3820":21771.0,"3923":7139.0,"6580":null,"3870":10359.0,"5952":null,"6423":null,"1101":15326.0,"4622":21863.0,"975":4613.0,"1954":12967.0,"4515":9531.0,"1252":18609.0,"457":2140.0,"4712":22745.0,"4446":8585.0,"788":11430.0,"2392":18870.0,"704":28870.0,"2378":null,"547":null,"115":12977.0,"3703":12633.0,"1949":8881.0,"5852":23186.0,"1468":29049.0,"1680":7137.0,"471":null,"750":6894.0,"2605":3283.0,"3974":5282.0,"3029":18048.0,"1237":6355.0,"1521":29464.0,"2543":6558.0,"5907":11972.0,"5782":17544.0,"5974":5769.0,"4070":3452.0,"1838":4592.0,"3880":7932.0,"1938":6861.0,"2596":2265.0,"6533":null,"2941":34857.0,"6160":null,"3572":11571.0,"2326":34945.0,"1355":19308.0}}'
sns.regplot(data= toy_data,
y='Tuition',
x="REGION",
x_estimator=np.mean,
scatter_kws['color'] = 'r',
line_kws['color'] = 'b')
plt.show()
plt.clf()
scatter_kws['color'] = 'r',
^
SyntaxError: keyword can't be an expression
Looking at the documentation:
{scatter,line}_kws : dictionaries
Additional keyword arguments to pass to plt.scatter and plt.plot.
It can be seen that you they are keyword arguments to regplot and that they are dictionaries. In addition, the paramters that can be accepted can be found by looking at the documentation of plt.plot and plt.scatter depending on which argument you are using.
Therefore, your call to regplot would look something like:
sns.regplot(data= toy_data,
y='Tuition',
x="REGION",
x_estimator=np.mean,
scatter_kws={'c': 'r'},
line_kws={'color': 'b'})

Iterate through each integer python separated by a blankspace/endline

I am a Python 2.7 user who recently switched to python3. While reading integers separated by a blackspace/endline I used nex = iter(map(int,stdin.read().split())).next, where nex() acts as a function to input integers (Suppose for inputting an integral value in x -> x=nex(). But in python3 this doesn't seem to work. Someone please propose a workaround for using the same in Python3.
.next() method is called .__next__() in Python 3. You could use next() function to write single-source Python 2/3 compatible code:
from functools import partial
nex = partial(next, iter(iterable))
print(nex())

LEN error for zipping in python

def shufflemode():
import random
combined = zip(question, answer)
random.shuffle(combined)
question[:], answer[:] = zip(*combined)
but then i get the error:
TypeError: object of type 'zip' has no len()
What do I do im so confused
I wonder the same thing. According to:
randomizing two lists and maintaining order in python
You should be able to do it like the OP tried, but i also get the same error. I think the ones from the link are using python 2 and not 3, could this be the problem?
This is an issue between Python 2 and Python 3. In Python 2 using shuffle after zip works, because zip returns a list. In Python 3: "TypeError: object of type 'zip' has no len()" because zip returns an iterator in Python 3.
Solution, use list() to convert to a list:
combined = list(zip(question, answer))
random.shuffle(combined)
The error appeared with shuffle() because shuffle() uses len().
References issue:
The zip() function in python 3
Stumbled upon this and was surprised to learn about the random.shuffle method. So I tried your example, and it worked for me in Python 2.7.5:
def shufflemode():
import random
combined = zip(question, answer)
random.shuffle(combined)
question[:], answer[:] = zip(*combined)
question = ["q1","q2","q3","q4","q5"]
answer = ["a1","a2","a3","a4","a5"]
if __name__ == "__main__":
shufflemode()
print question,answer
The result is two lists with the same randomized sequence of questions and answers*strong text*:
>>>
['q3', 'q2', 'q5', 'q4', 'q1'] ['a3', 'a2', 'a5', 'a4', 'a1']
>>>

Resources