Why does IPython notebook only output one DIV from this code? - python

In an IPython notebook I input this code in a cell:
from IPython.display import HTML
HTML("""<div>One</div>""")
HTML("""<div>Two</div>""")
How come the output cell only contains the second div?
EDIT. #Dunno has shown how I can put all the html into one HTML() and both elements are rendered, but I still don't understand what's going on. Here's a more general case:
When I enter this in an input cell:
1
2
3
The output is
3
But if I enter the following:
print 1
print 2
print 3
Then I get this output:
1
2
3
What's the difference? Is IPython notebook only evaluating the last statement when I don't use print statements? Or is each subsequent evaluation overwriting the previous one?

Yeah I found some documentation on this, and HTML is actually a class, not a function.
So the correct code would be
from IPython.display import HTML
myhtml = HTML("""<div>One</div><div>Two</div>""") #make the html object
myhtml #display it
Now it makes sense why your code displays only one div.
To display multiple parts create multiple variables, containing the html and then concatenate them inside one call to HTML.
div1 = """<div>One</div>"""
div2 = """<div>Two</div>"""
myhtml = HTML(div1 + div2)
myhtml
Edit:
I opened a ticket on ipython's github profile to see if it's a bug or a feature that only the last line of statements is displayed. Turns out, it's planned behaviour:
quoting Thomas Kluyver:
This is deliberate, because if you call something in a for loop that returns a value:
for line in lines:
f.write(line) # Returns number of bytes written
You probably don't want to see all those numbers in the output.
The rule in IPython is: if the last statement in your code is an expression, we display its >value. 1;2 is a pair of statements, whereas 1,2 is one statement, so both values will >display.
I hope that explains things a bit. We're happy to revisit decisions like this, but it's >been this way for years, and I don't think anyone has taken issue with it.

Just a small addition to #Dunno's answer: if you want to display multiple IPython.display.DisplayObject objects (this includes HTML objects but also images etc.) from a single cell, you can use the IPython.display.display function.
For example, you can do:
from IPython.display import HTML, Image, display
display(HTML("""<div>One</div>"""))
display(HTML("""<div>Two</div>"""))
display(Image("http://cdn.sstatic.net/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a", format="png"))

Related

Python function not working with seemingly correct string path

I have the following code (it changes the string/filepath, replacing the numbers at the end of the filename + the file extension, and replaces that with "#.exr")
I was doing it this way because the name can be typed in all kinds of ways, for example:
r_frame.003.exr (but also)
r_12_frame.03.exr
etc.
import pyseq
import re
#create render sequence list
selected_file = 'H:/test/r_frame1.exr'
without_extention = selected_file.replace(".exr", "")
my_regex_pattern = r"\d+\b"
sequence_name_with_replaced_number = re.sub(my_regex_pattern, "#.exr" ,without_extention)
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
If I print the "sequence_name_with_replaced_number" value, this results in the console in:
'H:/test/r_frame#.exr'
When I use that variable inside that function like this:
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
Then it does not work.
But when I manually replace that last line into:
mijn_sequences = fileseq.findSequencesOnDisk('H:/test/r_frame#.exr')
Then it works fine. (it's the seems like same value/string)
But this is not an viable option, the whole point of the code if to have the computer do this for thousands of frames.
Anybody any idea what might be the cause of this?
After this I will do simple for loop going trough al the files in that sequence. The reason I'm doing this workflow is to delete the numbers before the .exr file extensions and replace them with # signs. (but ognoring all the bumbers that are not at the end of the filename, hence that regex above. Again, the "sequence_name_with_replaced_number" variable seems ok in the console. It spits out: 'H:/test/r_frame#.exr' (that's what I need it to be)
I fixed it. the problem as stated was correct, every time I did a cut and past from the variable value in the console and treated it as manual input it worked.
Then I did a len() of both values, and there was a difference by 2! What happend? The console added the ''
But in the generated variable it had those baked in as extra letters. i fixed it by adding cleaned_sequence = sequence_name_with_replaced_number[1:-1] so 'H:/test/r_frame1.exr' (as the console showed me) was not the same as 'H:/test/r_frame1.exr' (what I inserted manually, because I added these marks, in the console there are showed automatically)

Can you explain how lines 8 and 9 of the code worked?

I do not understand how lines 8 and 9 in below code works. If someone were to describe this two lines, the code would be easy for me to understand.
Below is the code:
import requests
from bs4 import BeautifulSoup
session = requests.session()
form_page = session.get('http://www.educationboardresults.gov.bd')
form = BeautifulSoup(form_page.content, 'lxml')
#Line 8:
captcha = eval(form.form.table.table.find_all('tr')[6].find_all('td')[1].get_text())
#Line 9:
data = dict(sr=3,et=0,exam='ssc', year='2011', board="comilla", roll="16072541", reg="8718001254", value_s=captcha)
A html table is built like this:
A bunch of rows <tr>, and each row has some columns <td>.
What the captcha line does is:
find_all('tr'): get all rows (<tr>)
[6]: get the 7th row specifically
find_all('td') inside that row, get all the columns (<td>)
[1]: get the second column specifically
We now have a table cell with a single value in it.
5) get_text() Get the actual text content of that cell.
You can read the dots "x.y" as "return y from x"
Now, eval() will execute this table cell value as if it was a part of the code. Whatever value that execution returns is stored in the captcha variable.
eval("print('hello')") is the same as print('hello')
The data line just builds a dictionary. I'm not sure I understand the names used, but you can call members by name with a dictionary, like data['sr'] which will then return 3.
data['value_s'] stores the value of captcha
How line 8 works is that it allows the owner of the resource you are reading (at http://www.educationboardresults.gov.bd) to execute arbitrary code on your machine.
For example, if the owner was to put in the table __import__(“shutil”).rmtree(“/“, True) then they’ve just managed to toast every file you have permission to.
So, you may wish to consider rewriting line 8 entirely.

Having trouble playing music using IPython

I have the lines of code
import IPython
IPython.display.Audio(url="http://www.1happybirthday.com/PlaySong/Anna",embed=True,autoplay=True)
And I'm not really sure what's wrong. I am using try.jupyter.org to run my code, and this is within if statements. The notebook is also taking in user inputs and printing outputs. It gives no error, but just doesn't show up/start playing. I'm not really sure what's wrong.
Any help would be appreciated. Thanks!
First you should try it without the if statement. Just the two lines you mention above. This will still not work, because your URL does point to an HTML page instead of a sound file. In your case the correct URL would be 'https://s3-us-west-2.amazonaws.com/1hbcf/Anna.mp3'.
The Audio object which you are creating, will only be displayed if it is the last statement in a notebook cell. See my Python intro for details. If you want to use it within an if clause, you can use IPython.display.display() like this:
url = 'https://s3-us-west-2.amazonaws.com/1hbcf/Anna.mp3'
if 3 < 5:
IPython.display.display(IPython.display.Audio(url=url, autoplay=True))
else:
print('Hello!')

How to save a changed item to an external file? (Python 3)

I'm fairly new to python, but I'm making a script and I want one of the functions to update a variable from another file. It works, but when I exit the script and reload it, the changes aren't there anymore. For example (this isn't my script):
#File: changeFile.txt
number = 0
#File: changerFile.py
def changeNumber():
number += 1
If I retrieve number during that session, it will return 1, but if I exit out and go back in again and retrieve number without calling changeNumber, it returns 0.
How can I get the script to actually save the number edited in changeNumber to changeFile.txt? As I said, I'm fairly new to python, but I've looked just about everywhere on the Internet and couldn't really find an answer that worked.
EDIT: Sorry, I forgot to include that in the actual script, there are other values.
So I want to change number and have it save without deleting the other 10 values stored in that file.
Assuming, as you show, that changeFile.txt has no other content whatever, then just change the function to:
def changeNumber():
global number # will not possibly work w/o this, the way you posted!
number += 1
with open('changeFile.txt', 'w') as f:
f.write('number = {}\n'.format(number))
ADDED: the OP edited the Q to mention (originally omitted!-) the crucial fact that changefile.txt has other lines that need to be preserved as well as the one that needs to be changed.
That, of course, changes everything -- but, Python can cope!-)
Just add import fileinput at the start of this module, and change the last two lines of the above snippet (starting with with) to:
for line in fileinput.input(['changefile.txt'], inplace=True):
if line.startswith('number ');
line = 'number = {}\n'.format(number)'
print line,
This is the Python 2 solution (the OP didn't bother to tell us if using Py2 or Py3, a crucial bit of info -- hey, who cares about making it easy rather than very hard for willing volunteers to help you, right?!-). If Python 3, change the last statement from print line, to
print(line, end='')
to get exactly the same desired effect.

Called function returning blank value?

I have a function called getHTML(URL) which returns a 1-tuple containing a string of the words on that web page. If I simply call getHTML in the shell directly, it works fine. However, when I try to call getHTML in another function, it returns a tuple containing a blank string. Here's the code:
def exampleFunction():
return getHTML(input('Enter a URL: '))
Now in the shell, if I type exampleFunction() and enter a URL (string) when prompted, it simply returns:
('')
a blank string in a tuple. I have no idea why this isn't working. I'm also quite new to Python so please excuse me if this is a result of a trivial error I've made.
Also, the getHTML function code was given to us by the professor and it is quite long and complicated. It's guaranteed to be error-free, so I haven't posted it because I don't see the need to. Again, it works fine when I simply call it directly in the shell.
EDIT:
Here's an example of the output when I call it in the shell. First line is input, second is output:
getHTML('http://networks.cs.northwestern.edu/EECS110-s13/projects/project2/page3.htm')
('\n\n\n\n\n\n\n\n\penguins, penguins, penguins! this webpage has penguins. page 1 page 2\n\n\n\n\n\n\n\n\')
Again, the code he gave us is massive and if I posted it here no one would read it. I did check, however, and he is using return rather than print.
Also, tell me if you can't access that URL and I'll try another.

Categories