So everytime I try to use my Point.top() command I keep getting:
'int' object is not subscriptable
And this the code:
def top():
datalist = sorted(Point.dPoint.items(), key=lambda x: x[1][0], reverse=True)
t = 1
top = []
for l in datalist:
top.append(l[0].title()+": "+str(l[1][0])+(" point" if l[1][0] > 1 else " points"))
if t == 15:
break
t+=1
return top
This is inside the file and how it saves:
charles 45
tim 32
bob 67
I'm not sure why that error keeps happening. The code is suppose to get the top 15 people of who has the highest points. It would return this:
["Bob: 67 points", "Charles: 45 points", "Tim: 32 points"]
One of your variables is an int, and you're doing variable[0], which you can't do with an int.
Python 3.3.2 (default, Aug 25 2013, 14:58:58)
[GCC 4.2.1 Compatible FreeBSD Clang 3.1 ((branches/release_31 156863))] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 42
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
>>> type(a)
<class 'int'>
>>>
I suggest to make code more explicit, e.g.:
def top():
player_points_couples = sorted(Point.dPoint.items(), key=lambda player_point_couple: player_point_couple[1][0], reverse=True)
top_players_number = 1
top_players = []
for player, points in player_points_couples :
top_players.append(player.title()+": "+str(points[0])+(" point" if points[0] > 1 else " points"))
if top_players_number == 15:
break
top_players_number += 1
return top_players
In this way you'll find the strange expressions:
player_point_couple[1][0]
...
points[0]
which mean "the first element of 'points'"... but 'points' is a number, no elements inside!
EDIT
Just to go into pythonic style:
def top():
from operator import itemgetter
player_points_couples = sorted(Point.dPoint.items(), key=itemgetter(1), reverse=True)
string_template_singular = "%s: %d point"
string_template_plural = "%s: %d points"
top_players = []
for player, points in player_points_couples[:15]:
string_template = string_template_plural if points > 1 else string_template_singular
top_players.append(string_template % (player.title(), points))
return top_players
Related
I am very new to python.
I am trying to run a simple code with a 2d list. But I'm getting an error:
"TypeError: 'generator' object is not subscriptable". Can anyone please help me with how to solve this? Or what is wrong with the code.
import sys
import numpy as np
from scipy import stats
max_event = 1000000
a_bin = 10 # number each bin from 0-->10 where cumulant calculation will be done
# Define 2D array for [ bin, here 0->10][proton in each bin]
pArray = (() for nn in range(a_bin))
neve = (0 for mm in range(a_bin))
for ii in range(0, max_event):
_a = np.random.randint(10)
_b = np.random.randint(120)
if ii % 1000 == 0:
print(ii, _a, _b)
for j in range(0, 10):
if _a == j:
pArray[j].append(_b)
neve[j] += 1
print("filling done!")
for k in range(0, a_bin):
mu2 = stats.mstats.moment(pArray[k], moment=2)
mu4 = stats.mstats.moment(pArray[k], moment=4)
print('serial = %d, mu_2 = %f , mu_4 = %f, event = %d' %
(k, mu2, mu4, neve[k]))
# print k, neve[k], c1[k], c2[k], c3[k], c4[k], c5[k], c6[k]
print("calculation done!")
Here is the output I am getting:
0 9 18 Traceback (most recent call last): File "calcumuBin.py", line
23, in
pArray[j].append(_b) TypeError: 'generator' object is not subscriptable
You can change the pArray to be a list of lists that will prevent you from getting the TypeError: 'generator' object is not subscriptable
pArray = [[] for nn in range(a_bin)]
neve = [0 for mm in range(a_bin)]
Say i have
1009732533765201
and i want:
0x1009732533765201 which is
1155581383011619329
You can do this in programming languages with strings like this
int('1009732533765201',16)
but i want the pure math way. To convert 1009732533765201 to it's base16 of 1155581383011619329
I tried: int('1009732533765201',16) but this uses a string, and is slow for large numbers, i'm looking for a math angle only.
Here is a math way i know how to do it:
0x1009732533765201 = 1155581383011619329
Here is a python way to do it:
int('1009732533765201',16)
but i can only do the first math version manually. How can this be accomplished, converting 0x1009732533765201 without using a string to concatenating '0x' to '1009732533765201' and not using eval
Is there any way to take 1009732533765201, and convert it to the same ouput as 0x1009732533765201 to get its integer without using int('1009732533765201',16) my goal is to find a faster approach
ANSWERED BY PARTHIAN SHOT, here is the result of his approach which is exactly what i was looking for, a way to do this without int()
orig = 1009732533765201
num = orig
result = 0
i = 0
while num != 0:
result += (num % 10) * (16 ** i)
num //= 10
i += 1
print(orig, num, result, "%x" % (result))
1009732533765201 0 1155581383011619329 1009732533765201
As I said in my comment, Python knows, out of box, how to deal with base 16 numbers. Just go ahead and assign the base 16 value to a variable.
Here is an example:
Python 3.7.4 (default, Aug 12 2019, 14:45:07)
[GCC 9.1.1 20190605 (Red Hat 9.1.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> i=0x16
>>> i
22
>>> i=0xAA
>>> i
170
>>>
And as I said, that works for other bases, like base 2:
>>> i=0b1010
>>> i
10
>>>
And base 8:
>>> i=0o12
>>> i
10
>>>
The idea here is that we're looking at each digit of the original decimal number one at a time, from right to left, and multiplying it by 16 ** i instead of 10 ** i, then adding it to the new number.
The result is the equivalent of interpreting the original decimal representation of the number as if it were hexadecimal.
#!/usr/bin/env python
orig = 34029235
num = orig
result = 0
i = 0
while num != 0:
result += (num % 10) * (16 ** i)
num //= 10
i += 1
print(orig, num, result, "%x" % (result))
And running that code gets us...
bash$ ./main.py
(34029235, 0, 872583733, '34029235')
bash$
This code is a simple implementation of Fermat's Prime Factor. When I enter random 13, 14 15 digit integer to find the factor, depends on the input value, it produces the wrong result.
unit tested with product of two prime numbers of (7919) and prime numbers under 10000. It seems working well. However, when I tried with large integer of 13, 14, 15 digit numbers, depend on the input value, it produces wrong result.
def Prime_Factor(target):
a = int(math.sqrt(target))
b= a
while((a+b) <= target):
a = a + 1
b = math.sqrt(a**2 - target)
if((b % 1) == 0):
b = int(b)
print('a = ', a, ', b = ',b)
print('(a+b) = ,', (a+b), ', (a-b) = ', (a-b))
print('(a+b) * (a-b) = ', (a+b)*(a-b), end='')
if((a+b)*(a-b) == target):
print(' No Error Detected \n\n')
else:
print(' <> !=' , target, ' ERROR ******** \n\n')
exit
return
import math
Prime_Factor(9484756478341)
> Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)]
> Type "copyright", "credits" or "license" for more information.
> IPython 7.4.0 -- An enhanced Interactive Python.
> runfile('C:/Users/Paul/.spyder-py3/temp.py', wdir='C:/Users/Paul/.spyder- py3')
> a = 68579938 , b = 68510752
> (a+b) = , 137090690 , (a-b) = 69186
> (a+b) * (a-b) = 9484756478340 <> != 9484756478341 ERROR ********
Thank you everyone for the valuable comment. I've look into and found a few big integer packages for python such as gmpy2 etc. Death by truncation, indeed. Thank you for your help. cheers!
I want to implement python code that related to Problem 2-4 of third edition of CLRS .The problem is "find the number of Inversion s in a list " in page 41 and I write this code:
mainCounter = 0
def merg(array,counter):
if len(array)==1:
return array
left = array[:len(array)/2]
right = array[len(array)/2:]
return combine(merg(left, counter), merg(right, counter), counter)
def combine(array1, array2, counter):
global mainCounter
result = []
pointer1 = 0
pointer2 = 0
while(pointer1 != len(array1) and pointer2 != len(array2)):
if array1[pointer1] < array2[pointer2]:
result.append(array1[pointer1])
pointer1 += 1
elif array1[pointer1] == array2[pointer2]:
result.append(array1[pointer1])
pointer1 += 1
else:
result.append(array2[pointer2])
counter += (len(array1)-pointer1)
pointer2 += 1
if pointer1 == len(array1):
for i in array2[pointer2:]:
result.append(i)
else:
for i in array1[pointer1:]:
result.append(i)
mainCounter+=counter
return result
The problem is when I import this module in python console mainCounter doesn't change but this must be changed !!:
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from mergSort import *
>>> merg([1,4,2,3],0)
0
0
2
[1, 2, 3, 4]
>>> merg([1,4,2,3],0)
2
2
4
[1, 2, 3, 4]
>>> mainCounter
0
>>> merg([1,4,2,3],0)
4
4
6
[1, 2, 3, 4]
>>> merg([1,4,2,3],0)
6
6
8
[1, 2, 3, 4]
>>> merg([1,4,2,3],0)
8
8
10
[1, 2, 3, 4]
>>> mainCounter
0
every time I call the merg function I get different results but mainCounter doesn't changed ! where I am wrong ?
tldr: Don't use from module import *
import * is less special than you might think - when you import things with from mergSort import *, think of it as
import mergSort
mainCounter = mergSort.mainCounter
merg = mergSort.merg
del mergSort
So you really just have a reference to the int object that mergSort.mainCounter referred to when you did the import. mergSort uses the mergSort.mainCounter one; in the same way that
>>> a = 1
>>> b = a
>>> a += 1 # or a = a + 1 or a = a.__add__(1)
>>> a
2
>>> b
1
we have two separate references to integer objects, and incrementing one (changing the reference to point to a new object produced by a method call on the old object) won't effect the other. To confirm this, try
merg.__globals__['mainCounter']
or
import sys; sys.modules[merg.__module__].mainCounter
These should have the mainCounter value merg is using.
(sys.modules['mergSort'] is merg.__globals__ is true, they're the same thing dictionary)
When a name is declared global in a function, it is looked up in the function's module's namespace.
import * is often maligned because it makes it very difficult to trace where a name came from, but here it's also bad because it breaks our conception of modules - just because you import * from a module doesn't mean you're actually in its namespace, you've just done from module import a, b, c, d, e, .... This is made worse because many names aren't re-bound in Python much, but some are all the time, like names acting as counters by referring to integers.
It's a good practice to don't use import * at all.
Your imported objects don't know anything about each other and using global mainCounter doesn't help.
Try this:
import mergSort
mergSort.merg([1, 4, 2, 3], 0)
print mergSort.mainCounter
Here's my code:
# Note: Return a string of 2 decimal places.
def Cel2Fah(temp):
fah = float((temp*9/5)+32)
fah_two = (%.2f) % fah
fah_string = str(fah_two)
return fah_string
Here's what I should get:
>>> Cel2Fah(28.0)
'82.40'
>>> Cel2Fah(0.00)
'32.00'
But I get an error:
Traceback (most recent call last):
File "Code", line 4
fah_two = (%.2f) % fah
^
SyntaxError: invalid syntax
I'm not sure what is going on...
This doesn't seem to work either for some reason:
# Note: Return a string of 2 decimal places.
def Cel2Fah(temp):
fah = temp*9/5+32
fah_cut = str(fah).split()
while len(fah_cut) > 4:
fah_cut.pop()
fah_shorter = fah_cut
return fah_shorter
It looks like you want:
fah_two = "%.2f" % fah
The result of the % formatting operator is a string, so you don't need fah_string because fah_two is already a string.
sucmac:~ ajung$ cat x.py
def toF(cel):
return '%.2f' % (cel * 1.8 +32)
print toF(0)
print toF(50)
print toF(100)
sucmac:~ ajung$ python x.py
32.00
122.00
212.00
Further, I think temp * 9 / 5 should be temp * 9 / 5.0.