I have a small bit of code in Python 3 -
'{:08b}' .format(i)
that gives an error in Python 2.x. Does anyone know the equivalent?
Your original code actually works in Python 2.7. For Python 2.6, you need to introduce a reference to your format argument - either an index (0):
'{0:08b}'.format(i)
or a name:
'{x:08b}'.format(x=i) # or:
'{i:08b}'.format(i=i) # or even:
'{_:08b}'.format(_=i) # (since you don't care about the name)
Strangely enough, this particular quirk doesn't seem to be mentioned in the documentation about string formatting :(
Try this:
def fun(i):
print ('{0:08b}'.format(i))
fun(i) # Put any decimal number instead of i in fun(i) like fun(5). The result will be the binary code for number five which is 00000101
Related
I am brand new to python. I have been working on the courses on Codecademy. I am also currently using Pydev / LiClipse.
In one of the first lessons on Codecademy it wants you to set the variable parrot to "Norwegian Blue". Then it wants you to print the length of parrot using the len string method. It is very simple, and I got the answer right away with:
parrot = "Norwegian Blue"
print len(parrot)
When I put the exact same code into LiClipse it returned:
SyntaxError: invalid syntax
It work in LiClipse when I changed it to:
print (len(parrot))
Can someone let me know why that worked in codecademy, but not in LiClipse, and why adding the parenthesis fixed it?
It sounds like Pydev/LiClipse is using Python 3 while Codeacademy is using python 2.x or some other older version. One of the changes made when python updated from 2.x to 3 was print is now a function.
Python 2:
print "stuff to be printed"
Python 3:
print("stuff to be printed")
You must take into account the version in which you are working.
In Python 2 your code would look like this:
parrot = "Norwegian Blue"
print len(parrot)
In Python 3 your code would look like this:
parrot = "Norwegian Blue"
print ( len(parrot) )
It worked in CodeAcademy because their interpreter is a Python 2.7, where you didn't need the parenthesis because print was a statement. In Python 3.0+, print requires the parentheses because it's a function.
More information on what's different between Python 2.7 and 3.0+ can be found here:
What's New In Python 3.0
Some of the sample differences with print on the above page:
Old: print "The answer is", 2*2
New: print("The answer is", 2*2)
Old: print x, # Trailing comma suppresses newline
New: print(x, end=" ") # Appends a space instead of a newline
Old: print # Prints a newline
New: print() # You must call the function!
It's good to know the differences between both, in case you're working with legacy systems and the lot vs. in your private environment. In Python 2.7 and below, print() works; however, omitting the ()s does not work in Python 3.0+, so it's better to get into the habit of using them for print.
End of life for Python 2.7 is expected to be in 2020, so you have plenty of time anyway.
In Python 3 print was changed to require parenthesis. CodeAcademy is probably using Python 2 and it looks like you're using Python 3.
https://docs.python.org/3/whatsnew/3.0.html#print-is-a-function
From the docs
Print Is A Function
The print statement has been replaced with a
print() function, with keyword arguments to replace most of the
special syntax of the old print statement (PEP 3105). Examples:
I am trying to encrypt PDF files under Python 3.3.2 using PyPDF2.
The code is very simple:
password = 'password';
# password = password.encode('utf-8')
PDFout.encrypt(user_pwd=password,owner_pwd=password)
however I am getting the following errors, depending if the encoding is on or off:
on: TypeError: slice indices must be integers or None or have an __index__ method
off: TypeError: Can't convert 'bytes' object to str implicitly
Would you know by any chance how to resolve that problem?
Thanks and Regards
Peter
It appears to me that the current version of PyPDF2 (1.19 as of this writing) has some bugs concerning compatibility with Python 3, and that is what is causing both error messages. The change log on GitHub for PyPDF2 indicates that Python 3 support was added in version 1.16, which was released only 3 1/2 months ago, so it is possible this bug hasn't either been reported or fixed yet. GitHub also shows that there is a branch of this project specifically for Python 3.3 support, which is not currently merged back into the main branch.
Both errors occur in the pdf.py file of the PyPDF2 module. Here is what is happening:
The PyPDF2 module creates some extra bytes as padding and concatenates it with your password. If the Python version is less than 3, the padding is created as a string literal. If the version is 3 or higher, the padding is encoded using the 'latin-1' encoding. In Python 3, this means the padding is a bytes object, and concatenating that with a string object (your password) produces the TypeError you saw. Under Python 2, the concatenation would work because both objects would be the same type.
When you encode your password using "utf-8", you resolve that problem since both the password and padding are bytes objects in that case. However, you end up running into a second bug later in the module. The pdf.py file creates and uses a variable "keylen" like this:
keylen = 128 / 8
... # later on in the code...
key = md5_hash[:keylen]
The division operator underwent a change in Python 2.2 which altered its default behavior starting in Python 3. In brief, "/" means floor division in Python 2 and returns an int, but it means true division in Python 3 and returns a float. Therefore, "keylen" would be 16 in Python 2, but instead 16.0 in Python 3. Floats, unlike ints, can't be used to splice arrays, so Python 3 throws the TypeError you saw when md5_hash[:keylen] is evaluated. Python 2 would run this without error, since keylen would be an int.
You could resolve this second problem by altering the module's source code to use the "//" operator (which means floor division and returns an int in both Python 2 and 3):
keylen = 128 // 8
However, you would then run into a third bug later in the code, also related to Python 3 compatibility. I won't belabor the point by describing it. The short answer to your question then, as far as I see it, is to either use Python 2, or patch the various code compatibility problems, or use a different PDF library for Python which has better support for Python 3 (if one exists which meets your particular requirements).
Try installing the most recent version of PyPDF2 - it now fully supports Python 3!
It seems that "some" support was added in 1.16, but it didn't cover all features. Now, Py 3 should be fully compatible with this library.
I am new to python and am having difficulties with an assignment for a class.
Here's my code:
print ('Plants for each semicircle garden: ',round(semiPlants,0))
Here's what gets printed:
('Plants for each semicircle garden:', 50.0)
As you see I am getting the parenthesis and apostrophes, which I do not want shown.
You're clearly using python2.x when you think you're using python3.x. In python 2.x, the stuff in the parenthesis is being interpreted as a tuple.
One fix is to use string formatting to do this:
print ( 'Plants for each semicircle garden: {0}'.format(round(semiPlants,0)))
which will work with python2.6 and onward (parenthesis around a single argument aren't interpreted as a tuple. To get a 1-tuple, you need to do (some_object,))
You've tagged this question Python-3.x, but it looks like you are actually running your code with Python 2.
To see what version you're using, run, "python -V".
Remove the parentheses as print is a statement, not a function in Python 2.x:
print 'Plants for each semicircle garden: ',round(semiPlants,0)
Plants for each simicircle garden: 50.0
I am tryiing to port some python code to ruby, and I am doing pretty well, using equivelent ruby functions, even removing / altering some to use ruby features more.
However at a core point I need to get slices from an array
in python the following works fine:
output=["Apple","Orange","Pear"]
team_slices=[(0,1),(1,2),(2,3)]
for start,end in team_slices:
print output[start:end]
Will output as expected:
['Apple']
['Orange']
['Pear']
Whereas the ruby code:
output=["Apple","Orange","Pear"]
team_slices=[[0,1],[1,2],[2,3]]
team_slices.each do |start,ending|
print output[start..ending]
end
Will output:
["Apple","Orange"]
["Orange","Pear"]
["Pear"]
Is there any way to do the slicing more equivalent to python? I know I am likely missing somethign simple here
Seems like python's ranges exclude the end value, so just use the ... variant in ruby:
output=["Apple","Orange","Pear"]
team_slices=[[0,1],[1,2],[2,3]]
team_slices.each do |start, last|
print output[start...last]
end
PS: In ruby you should use 2 spaces for indentation, if you want to stick to conventions ;)
EDIT| Had to rename end to last due to ruby using it as a syntactical keyword.
Python 2.x (30 bytes):
_='_=%r;print _%%_';print _%_
Python 3.x (32 bytes)
_='_=%r;print(_%%_)';print(_%_)
Is this the shortest possible Python quine, or can it be done better? This one seems to improve on all the entries on The Quine Page.
I'm not counting the trivial 'empty' program.
I'm just going to leave this here (save as exceptionQuine.py):
File "exceptionQuine.py", line 1
File "exceptionQuine.py", line 1
^
IndentationError: unexpected indent
Technically, the shortest Python quine is the empty file. Apart from this trivial case:
Since Python's print automatically appends a newline, the quine is actually _='_=%r;print _%%_';print _%_\n (where \n represents a single newline character in the file).
Both
print open(__file__).read()
and anything involving import are not valid quines, because a quine by definition cannot take any input. Reading an external file is considered taking input, and thus a quine cannot read a file -- including itself.
For the record, technically speaking, the shortest possible quine in python is a blank file, but that is sort of cheating too.
In a slightly non-literal approach, taking 'shortest' to mean short in terms of the number of statements as well as just the character count, I have one here that doesn't include any semicolons.
print(lambda x:x+str((x,)))('print(lambda x:x+str((x,)))',)
In my mind this contends, because it's all one function, whereas others are multiple. Does anyone have a shorter one like this?
Edit: User flornquake made the following improvement (backticks for repr() to replace str() and shave off 6 characters):
print(lambda x:x+`(x,)`)('print(lambda x:x+`(x,)`)',)
Even shorter:
print(__file__[:-3])
And name the file print(__file__[:-3]).py (Source)
Edit: actually,
print(__file__)
named print(__file__) works too.
Python 3.8
exec(s:='print("exec(s:=%r)"%s)')
Here is another similar to postylem's answer.
Python 3.6:
print((lambda s:s%s)('print((lambda s:s%%s)(%r))'))
Python 2.7:
print(lambda s:s%s)('print(lambda s:s%%s)(%r)')
I would say:
print open(__file__).read()
Source
As of Python 3.8 I have a new quine! I'm quite proud of it because until now I have never created my own. I drew inspiration from _='_=%r;print(_%%_)';print(_%_), but made it into a single function (with only 2 more characters). It uses the new walrus operator.
print((_:='print((_:=%r)%%_)')%_)
This one is least cryptic, cor is a.format(a)
a="a={1}{0}{1};print(a.format(a,chr(34)))";print(a.format(a,chr(34)))
I am strictly against your solution.
The formatting prarameter % is definitively a too advanced high level language function. If such constructs are allowed, I would say, that import must be allowed as well. Then I can construct a shorter Quine by introducing some other high level language construct (which, BTW is much less powerful than the % function, so it is less advanced):
Here is a Unix shell script creating such a quine.py file and checking it really works:
echo 'import x' > quine.py
echo "print 'import x'" > x.py
python quine.py | cmp - quine.py; echo $?
outputs 0
Yes, that's cheating, like using %. Sorry.