When I type the code below, it gives me a blank HTML page. Even though I put a <h1> and a <a href> tag. Only the <title> tag is executed. Does anyone know why and how to fix it?
Code:
my_variable = '''
<html>
<head>
<title>My HTML File</title>
</head>
<body>
<h1>Hello world!</h1>
Click me
</body>
</html>'''
my_html_file = open(r"\Users\hp\Desktop\Code\Python testing\CH\my_html_file.html", "w")
my_html_file.write(my_variable)
Thanks in advance!
As #bill Bell said, it's probably because you haven't closed your file (so it hasn't flushed its buffer).
So, in your case:
my_html_file = open(r"\Users\hp\Desktop\Code\Python testing\CH\my_html_file.html", "w")
my_html_file.write(my_variable)
my_html_file.close()
But, this is not the right way to do it. Indeed, if an errors occurs in the second line for example, the file'll never get closed. So, you can use the with statement to make sure that it always is. (just as #Rawing said)
with open('my-file.txt', 'w') as my_file:
my_file.write('hello world!')
So, in fact, it's like if you did:
my_file = open('my-file.txt', 'w')
try:
my_file.write('hello world!')
finally:
# this part is always executed, whatever happens in the try block
# (a return, an exception)
my_file.close()
Related
Program is still a mess and giving me lots of errors....sadly after many, many tries.
Tried changing file.write to f.write...after reading some other solutions. But know I am wrong.
f = 'file'
def main():
statement
statement
statement
statement
statement
def write_html_file():
statement
statement
statement
statement
statement
def write_html_head():
statement
statement
statement
statement
def write_html_body():
statement
statement
statement
statement
statement
print('Your web page is done')
main()
The following is a sample of what the user should see:
Enter your name: First Last
Describe yourself: I am trying to be a great python student...just not
there yet...
>After user has entered info, program should create n HTML file, with the input, for a web page. Following is a sample HTML content for the above input.
<html>
<head>
</head>
<body>
<center>
<h1> Firs Last </h1>
</center>
<hr />
I am trying to be a great python student...just not
there yet...
<hr />
</body>
</html>
You need to make your variables accessible from the other functions. If we declare f outside the main method, we are able to use the f.write on the other functions as well. Your code will run like this:
f = 'file'
name=input('Enter your name: ')
description=input('Describe yourself: ')
f = open('my_page.html','w')
def main():
write_html_file()
f.close()
def write_html_file():
f.write('<html>\n')
f.write('<head>\n')
f.write('<body>\n')
f.write('</html>\n')
def write_html_head():
f.write('<head>\n')
f.write('<title>My Personal Web Page</title>')
f.write('/<head>\n')
def write_html_body():
f.write('<body>\n')
f.write('\t<center>\n')
f.write('\t\t<h1>'+name+'</h1>\n')
f.write('\t<hr />\n')
f.write(description+'\n')
f.write('\t<hr />\n')
f.write('\t</center>\n')
f.write('</body>\n')
print('Your web page is done')
main()
Your output looks like this when running:
Enter your name: Sykezlol
Describe yourself: I like python
Your web page is done
<html>
<head>
<body>
</html>
<body>
<center>
<h1>Sykezlol</h1>
<hr />
I like python
<hr />
</center>
</body>
<head>
<title>My Personal Web Page</title>/<head>
remove the global file variable it is useless and for other functions you should pass a parameters that indicates the file , name and description like this :
def main():
name = input("Enter your name: ")
description = input("Describe yourself: ")
f = open("my_page.html", "w")
write_html_file(f, name, description)
f.close()
def write_html_file(f, name, description):
f.write(
f"<html>\n<head>\n</head>\n<body>\n<center>\n<h1>{name}</h1>\n</center>\n<hr />{description}<hr />\n</body>\n</html>"
)
main()
this should fix your attribute error
the html code could've been written in a better way but this will work and you don't need a several functions to write to a file just make one only.
you could split each line in a different write statement but make sure to use formatting to provide the name and description and that can be done with f at the beginning of a string or with .foramt() method.
I have written a game in Python using the PyGame library that I am trying to embed into an HTML page to allow me to play in a web browser.
I am attempting to do this using the JavaScript library Skulpt. I have attached a test script below that successfully outputs the print statement below.
skulpt.html
<html>
<head>
<script src="assets/skulpt/skulpt.js" type="text/javascript"></script>
</head>
<body>
<textarea id="pythonCode">
print "I am python."
</textarea><br />
<pre id="output"></pre>
<script type="text/javascript">
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
var code = document.getElementById("pythonCode").value;
Sk.configure({output:outf});
eval(Sk.importMainWithBody("<stdin>",false,code));
</script>
</body>
</html>
Output of skulpt.html:
The issue that I am having is that when I use my game code instead of the simple print statement shown above it produces the error seen below;
I have included all relevant images to my web servers' directory at the correct path. I am unsure of why this error is being produced. Any help would be much appreciated, thanks!
Also, here is the attached Python game code (and a live demo of the error):
http://nicolasward.com/portfolio/skulpt.html
You have a lot of indentation on line 1 -> remember, in python, indentation always matters. Take away all those spaces/tabs on the first line and it should run.
I am trying to create a corpus of data from a set of .html pages I have stored in a directory.
These HTML pages have lots of info I don't need.
This info is all stored before the line
<div class="channel">
How can I programmatically remove all of the text before
<div class="channel">
in every HTML file in a folder?
Bonus question for a 50point bounty :
How do I programmatically remove everything AFTER, for example,
<div class="footer">
?
So if my index.html was previously :
<head>
<title>This is bad HTML</title>
</head>
<body>
<h1> Remove me</h1>
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
<div class="footer">
<h1> Remove me, I am pointless</h1>
</div>
</body>
After my script runs, I want it to be :
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
This is a bit heavy on memory usage, but it works. Basically you open up the directory, get all ".html" files, read them into a variable, find the split point, store the before or after in a variable, and then overwrite the file.
There are probably better ways to do this, nonetheless, but it works.
import os
dir = os.listdir(".")
files = []
for file in dir:
if file[-5:] == '.html':
files.insert(0, file)
for fileName in files:
file = open(fileName)
content = file.read()
file.close()
loc = content.find('<div class="channel">')
newContent = content[loc:]
file = open(fileName, 'w')
file.write(newContent)
file.close()
If you wanted to just keep up to a point:
newContent = content[0:loc - 1] # I think the -1 is needed, not sure
Note that the things you're searching should be kept in a variable, and not hardcoded.
Also, this won't work recursively for file/folder structures, but you can find out how to modify it to do that very easily.
to remove everything above and everything below
that means the only thing left should be this section:
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
rather than thinking to remove the unwanted, it would be easier to just extract the wanted.
you can easily extract channel div using XML parser such as DOM
You've not mentioned a language in the question - the post is tagged with python so this answer might still be out of context, but I'll give a php solution that could likely easily be rewritten in another language.
$html='....'; // your page
$search='<div class="channel">';
$components = explode($search,$html); // [0 => before the string, 1 => after the string]
$result = $search.$components[1];
return $result;
To do the reverse is fairly easy too; simply take the value of $components[0] after altering $search to your <div class="footer"> value.
If you happen to have the $search string cropping up multiple times:
$html='....'; // your page
$search='<div class="channel">';
$components = explode($search,$html); // [0 => before the string, 1 => after the string]
unset($components[0]);
$result = $search.implode($search,$components);
return $result;
Someone who knows python better than I do feel free to rewrite and take the answer!
How do I insert a variable into an HTML email I'm sending with python? The variable I'm trying to send is code. Below is what I have so far.
text = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1><% print code %></h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
"""
Use "formatstring".format:
code = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>{code}</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
""".format(code=code)
If you find yourself substituting a large number of variables, you can use
.format(**locals())
Another way is to use Templates:
>>> from string import Template
>>> html = '''\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>$code</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
'''
>>> s = Template(html).safe_substitute(code="We Says Thanks!")
>>> print(s)
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>We Says Thanks!</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
Note, that I used safe_substitute, not substitute, as if there is a placeholder which is not in the dictionary provided, substitute will raise ValueError: Invalid placeholder in string. The same problem is with string formatting.
use pythons string manipulation:
http://docs.python.org/2/library/stdtypes.html#string-formatting
generally the % operator is used to put a variable into a string, %i for integers, %s for strings and %f for floats,
NB: there is also another formatting type (.format) which is also described in the above link, that allows you to pass in a dict or list slightly more elegant than what I show below, this may be what you should go for in the long run as the % operator gets confusing if you have 100 variables you want to put into a string, though the use of dicts (my last example) kinda negates this.
code_str = "super duper heading"
html = "<h1>%s</h1>" % code_str
# <h1>super duper heading</h1>
code_nr = 42
html = "<h1>%i</h1>" % code_nr
# <h1>42</h1>
html = "<h1>%s %i</h1>" % (code_str, code_nr)
# <h1>super duper heading 42</h1>
html = "%(my_str)s %(my_nr)d" % {"my_str": code_str, "my_nr": code_nr}
# <h1>super duper heading 42</h1>
this is very basic and only work with primitive types, if you want to be able to store dicts, lists and possible objects I suggest you use cobvert them to jsons http://docs.python.org/2/library/json.html and https://stackoverflow.com/questions/4759634/python-json-tutorial are good sources of inspiration
Hope this helps
How is to compress (minimize) HTML from python; I know I can use some regex to strip spaces and other things, but I want a real compiler using pure python(so it can be used on Google App Engine).
I did a test on a online html compressor and it saved 65% of the html size. I want that, but from python.
You can use htmlmin to minify your html:
import htmlmin
html = """
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Case</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>Well</h2>
<div class="well">Basic Well</div>
</div>
</body>
</html>
"""
minified = htmlmin.minify(html.decode("utf-8"), remove_empty_space=True)
print(minified)
htmlmin and html_slimmer are some simple html minifying tools for python. I have millions of html pages stored in my database and running htmlmin, I am able to reduce the page size between 5 and 50%. Neither of them do an optimal job at complete html minification (i.e. the font color #00000 can be reduced to #000), but it's a good start. I have a try/except block that runs htmlmin and then if that fails, html_slimmer because htmlmin seems to provide better compression, but it does not support non ascii characters.
Example Code:
import htmlmin
from slimmer import html_slimmer # or xhtml_slimmer, css_slimmer
try:
html=htmlmin.minify(html, remove_comments=True, remove_empty_space=True)
except:
html=html_slimmer( html.strip().replace('\n',' ').replace('\t',' ').replace('\r',' ') )
Good Luck!
I suppose that in GAE there is no really need for minify your html as GAE already gzip it Caching & GZip on GAE (Community Wiki)
I did not test but minified version of html will probably win only 1% of size as it only remove space once both version are compressed.
If you want to save storage, for example by memcached it, you have more interest to gzip it (even at low level of compression) than removing space as in python it will be probably smaller and faster as processed in C instead of pure python
import htmlmin
code='''<body>
Hello World
<div style='color:red;'>Hi</div>
</body>
'''
htmlmin.minify(code)
Last line output
<body> Hello World <div style=color:red;>Hi</div> </body>
You can use this code to delete spaces
htmlmin.minify(code,remove_empty_space=True)
I wrote a build script that duplicates my templates into another directory and then I use this trick to tell my application to select the correct template in development mode, or in production:
DEV = os.environ['SERVER_SOFTWARE'].startswith('Development') and not PRODUCTION_MODE
TEMPLATE_DIR = 'templates/2012/head/' if DEV else 'templates/2012/output/'
Whether it is gzipped by your webserver is not really the point, you should save every byte that you can for performance reasons.
If you look at some of the biggest sites out there, they often do things like writing invalid html to save bytes, for example, it is common to omit double quotes in id attributes in html tags, for example:
<!-- Invalid HTML -->
<div id=mydiv> ... </div>
<!-- Valid HTML -->
<div id="mydiv"> ... </div>
And there are several examples like this one, but that's beside the scope of the thread I guess.
Back to the question, I put together a little build script that minifies your HTML, CSS and JS. Caveat: It doesn't cover the case of the PRE tag.
import os
import re
import sys
from subprocess import call
HEAD_DIR = 'templates/2012/head/'
OUT_DIR = 'templates/2012/output/'
REMOVE_WS = re.compile(r"\s{2,}").sub
YUI_COMPRESSOR = 'java -jar tools/yuicompressor-2.4.7.jar '
CLOSURE_COMPILER = 'java -jar tools/compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS '
def ensure_dir(f):
d = os.path.dirname(f)
if not os.path.exists(d):
os.makedirs(d)
def getTarget(fn):
return fn.replace(HEAD_DIR, OUT_DIR)
def processHtml(fn, tg):
f = open(fn, 'r')
content = f.read()
content = REMOVE_WS(" ", content)
ensure_dir(tg)
d = open(tg, 'w+')
d.write(content)
content
def processCSS(fn, tg):
cmd = YUI_COMPRESSOR + fn + ' -o ' + tg
call(cmd, shell=True)
return
def processJS(fn, tg):
cmd = CLOSURE_COMPILER + fn + ' --js_output_file ' + tg
call(cmd, shell=True)
return
# Script starts here.
ensure_dir(OUT_DIR)
for root, dirs, files in os.walk(os.getcwd()):
for dir in dirs:
print "Processing", os.path.join(root, dir)
for file in files:
fn = os.path.join(root) + '/' + file
if fn.find(OUT_DIR) > 0:
continue
tg = getTarget(fn)
if file.endswith('.html'):
processHtml(fn, tg)
if file.endswith('.css'):
processCSS(fn, tg)
if file.endswith('.js'):
processJS(fn, tg)