I'm relatively new to Python but typically find it fairly easy to work out. I've just encountered something, though, which has thrown me a little.
I know that type-checking is not very Pythonic but I'm dealing with user-input and it seems useful here. I expected the following code (in Python 2.7.6) to change a non-relevant input to an empty string, but while trying it out in an interactive interpreter, it returned an unexpected int. Could anybody tell me if this is a special value in Python, or explain why this happens.
I thought that perhaps "code" may be the name of a reserved variable ie. one used internally, but changing the name seemed to have no result.
>>> code = 0134
>>> if type(code) is not int: code =""
...
>>> code
92
I'm sure I can find an alternative way to do what I'm trying to do here, so that's not so much the focus. I'd simply like to work out what's happening with the unexpected int.
Thanks,
Rob
>>> code = 0134
In python 2.7.6 this defines the octal number 132 because of the leading 0. This is equal to the decimal 92.
>>> if type(code) is not int: code =""
If it's not an int then you clear it.
>>> code = 0134
>>> type(code)
<type 'int'>
As you can see you do have an int. When you print it out you get the base-10 representation which is 92.
This particular cause of confusion led to the following PEP http://legacy.python.org/dev/peps/pep-3127/
When a number begins with a 0 in Python, it is interpreted as an octal number. 0134 in octal is 92 in decimal.
I'm not sure why you think the type of that value will not be int. It is an integer.
Related
I've got to write a single-input module that can convert decimals to Bukiyip (some ancient language with a counting base of 3 or 4). For the purpose of the assignment, we only need to work with base 3.
I've written some code that does this, but it returns my Bukiyip number with quotes, leaving me with an answer such as '110' for 12.
Please help me understand how to work around this? I'm new to Python and keen to learn so explanations will be really appreciated.
def bukiyip_to_decimal(num):
convert_to_string = "012"
if num < 3:
return convert_to_string[num]
else:
return bukiyip_to_decimal(num//3) + convert_to_string[num%3]
I've also tried the following, but get errors.
else:
result = bukiyip_to_decimal(num//3) + convert_to_string[num%3]
print(int(result))
You are either echoing the return value in your interpreter, including the result in a container (such as a list, dictionary, set or tuple), or directly producing the repr() output for your result.
Your function (rightly) returns a string. When echoing in the interpreter or using the repr() function you are given a debugging-friendly representation, which for strings means Python will format the value in a way you can copy and paste right back into Python to reproduce the value. That means that the quotes are included.
Just print the value itself:
>>> result = bukiyip_to_decimal(12)
>>> result
'110'
>>> print(result)
110
or use it in other output:
>>> print('The Bukiyip representation for 12 is {}'.format(result))
The Bukiyip representation for 12 is 110
int() doesn't work? The quotes are not for decoration, you see. They are part of the string literal representation. "hello" is a string. It is not hello with quotes. A bare hello is an identifier, a name. So you don't wanna strip quotes from a string, which doesn't make any sense. What you want is a int.
I need to unpack information in python from a C Structure,
doing it by the following code:
struct.unpack_from('>I', file.read(4))[0]
and afterwards, writing changed values back:
new_value = struct.pack('>I', 008200)
file.write(new_value)
a few examples:
008200 returns an syntaxerror: invalid token.
000010 is written into: 8
000017 is written into: 15
000017 returns a syntaxerror.
I have no idea what kind of conversion that is.
Any kind of help would be great.
This is invalid python code and is not related to the struct module. In python, numbers starting with a zero are octal (base 8). So, python tries to decode 008200 in octal but '8' isn't valid. Assuming you wanted decimal, use 8200. If you wanted hex, use 0x8200.
Just starting out with Python, so this is probably my mistake, but...
I'm trying out Python. I like to use it as a calculator, and I'm slowly working through some tutorials.
I ran into something weird today. I wanted to find out 2013*2013, but I wrote the wrong thing and wrote 2013*013, and got this:
>>> 2013*013
22143
I checked with my calculator, and 22143 is the wrong answer! 2013 * 13 is supposed to be 26169.
Why is Python giving me a wrong answer? My old Casio calculator doesn't do this...
Because of octal arithmetic, 013 is actually the integer 11.
>>> 013
11
With a leading zero, 013 is interpreted as a base-8 number and 1*81 + 3*80 = 11.
Note: this behaviour was changed in python 3. Here is a particularly appropriate quote from PEP 3127
The default octal representation of integers is silently confusing to
people unfamiliar with C-like languages. It is extremely easy to
inadvertently create an integer object with the wrong value, because
'013' means 'decimal 11', not 'decimal 13', to the Python language
itself, which is not the meaning that most humans would assign to this
literal.
013 is an octal integer literal (equivalent to the decimal integer literal 11), due to the leading 0.
>>> 2013*013
22143
>>> 2013*11
22143
>>> 2013*13
26169
It is very common (certainly in most of the languages I'm familiar with) to have octal integer literals start with 0 and hexadecimal integer literals start with 0x. Due to the exact confusion you experienced, Python 3 raises a SyntaxError:
>>> 2013*013
File "<stdin>", line 1
2013*013
^
SyntaxError: invalid token
and requires either 0o or 0O instead:
>>> 2013*0o13
22143
>>> 2013*0O13
22143
Python's 'leading zero' syntax for octal literals is a common gotcha:
Python 2.7.3
>>> 010
8
The syntax was changed in Python 3.x http://docs.python.org/3.0/whatsnew/3.0.html#integers
This is mostly just expanding on #Wim's answer a bit, but Python indicates the base of integer literals using certain prefixes. Without a prefix, integers are interpreted as being in base-10. With an "0x", the integer will be interpreted as a hexadecimal int. The full grammar specification is here, though it's a bit tricky to understand if you're not familiar with formal grammars: http://docs.python.org/2/reference/lexical_analysis.html#integers
The table essentially says that if you want a long value (i.e. one that exceeds the capacity of a normal int), write the number followed by the letter "L" or "l"; if you want your number to be interpreted in decimal, write the number normally (with no leading 0); if you want it interpreted in octal, prefix it with "0", "0o", or "0O"; if you want it in hex, prefix it with "0x"; and if you want it in binary, prefix it with "0b" or "0B".
This question already exists:
Closed 10 years ago.
Possible Duplicate:
accessing a python int literals methods
Everything in Python is an object. Even a number is an object:
>>> a=1
>>> type(a)
<class 'int'>
>>>a.real
1
I tried the following, because we should be able to access class members of an object:
>>> type(1)
<class 'int'>
>>> 1.real
File "<stdin>", line 1
1.real
^
SyntaxError: invalid syntax
Why does this not work?
Yes, an integer literal is an object in Python. To summarize, the parser needs to be able to understand it is dealing with an object of type integer, while the statement 1.real confuses the parser into thinking it has a float 1. followed by the word real, and therefore raises a syntax error.
To test this you can also try
>> (1).real
1
as well as,
>> 1.0.real
1.0
so in the case of 1.real python is interpreting the . as a decimal point.
Edit
BasicWolf puts it nicely too - 1. is being interpreted as the floating point representation of 1, so 1.real is equivalent to writing (1.)real - so with no attribute access operator i.e. period /full stop. Hence the syntax error.
Further edit
As mgilson alludes to in his/her comment: the parser can handle access to int's attributes and methods, but only as long the statement makes it clear that it is being given an int and not a float.
a language is usually built in three layers.
when you provide a program to a language it first has to "read" the program. then it builds what it has read into something it can work with. and finally it runs that thing as "a program" and (hopefully) prints a result.
the problem here is that the first part of python - the part that reads programs - is confused. it's confused because it's not clever enough to know the difference between
1.234
and
1.letters
what seems to be happening is that it thinks you were trying to type a number like 1.234 but made a mistake and typed letters instead(!).
so this has nothing to do with what 1 "really is" and whether or not is it an object. all that kind of logic happens in the second and third stages i described earlier, when python tries to build and then run the program.
what you've uncovered is just a strange (but interesting!) wrinkle in how python reads programs.
[i'd call it a bug, but it's probably like this for a reason. it turns out that some things are hard for computers to read. python is probably designed so that it's easy (fast) for the computer to read programs. fixing this "bug" would probably make the part of python that reads programs slower or more complicated. so it's probably a trade-off.]
Although the behaviour with 1.real seems unlogical, it is expected due to the language specification: Python interprets 1. as a float (see floating point literals). But as #mutzmatron pointed out (1).real works because the expression in brackets is a valid Python object.
Update: Note the following pits:
1 + 2j.real
>>> 1.0 # due to the fact that 2j.real == 0
# but
1 + 2j.imag
>>> 3.0 # due to the fact that 2j.imag == 2
You can still access 1.real:
>>> hasattr(1, 'real')
True
>>> getattr(1, 'real')
1
I'm a bit new to python and can't seem to figure out what I'm doing wrong.
a = 9
b = 13
print ((a-b)/a)
-1
But on my calculator, the correct answer is -0.444444444 (meaning 'a' is about 45% lower than 'b').
How can I get a few decimals to show up?
I tried
print Decimal((a-b)/a)
print float((a-b)/a)
both with the same result. it works if I make a = 9.0 but I wanted to see if there was anything I can do without changing the variables.
I'm sure this is super easy but I'm not sure what to try. Any suggestions?
Thanks
Try converting one (or both) of the arguments to a float, rather than the result:
print ((a-b)/float(a))
Or just upgrade to Python 3 where this behaviour has been fixed:
>>> a = 9
>>> b = 13
>>> print ((a-b)/a)
-0.4444444444444444
By the way, if you want integer division in Python 3.x you can use // instead of /. See the PEP about this change if you are interested.
You need to specify that you want to operate on floating point numbers.
For example:
3.0/4.0 or just 3.0/4 will give you floating point. Right now it's just performing integer operations.
EDIT: you could use float(3)/4 too
You are performing division on two integer operands and in Python 2.x this means integer division. That is, the result is an integer.
You need what is known as floating point division. To force this you just need at least one of the operands to the division to be a float. For example:
print ((a-b)/float(a))
or
print (float(a-b)/a)