mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
validation
This commit is contained in:
@@ -51,7 +51,7 @@ import itertools
|
||||
def solve(puzzle):
|
||||
words = re.findall('[A-Z]+', puzzle.upper())
|
||||
unique_characters = set(''.join(words))
|
||||
assert len(unique_characters) <= 10, 'Too many letters'
|
||||
assert len(unique_characters) <= 10, 'Too many letters'
|
||||
first_letters = {word[0] for word in words}
|
||||
n = len(first_letters)
|
||||
sorted_characters = ''.join(first_letters) + \
|
||||
@@ -164,11 +164,11 @@ if __name__ == '__main__':
|
||||
<a><samp class=p>>>> </samp><kbd class=pp>assert 1 + 1 == 2</kbd> <span class=u>①</span></a>
|
||||
<a><samp class=p>>>> </samp><kbd class=pp>assert 1 + 1 == 3</kbd> <span class=u>②</span></a>
|
||||
<samp class=traceback>Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "<stdin>", line 1, in <module>
|
||||
AssertionError</samp>
|
||||
<a><samp class=p>>>> </samp><kbd class=pp>assert 2 + 2 == 5, "Only for very large values of 2"</kbd> <span class=u>③</span></a>
|
||||
<samp class=traceback>Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "<stdin>", line 1, in <module>
|
||||
AssertionError: Only for very large values of 2</samp></pre>
|
||||
<ol>
|
||||
<li>The <code>assert</code> statement is followed by any valid Python expression. In this case, the expression <code>1 + 1 == 2</code> evaluates to <code>True</code>, so the <code>assert</code> statement does nothing.
|
||||
@@ -335,7 +335,7 @@ StopIteration</samp>
|
||||
<p>What does this have to do with the <code>itertools</code> module? I’m glad you asked.
|
||||
|
||||
<pre class=screen>
|
||||
<p>…continuing from the previous interactive shell…
|
||||
…continuing from the previous interactive shell…
|
||||
<samp class=p>>>> </samp><kbd class=pp>import itertools</kbd>
|
||||
<a><samp class=p>>>> </samp><kbd class=pp>groups = itertools.groupby(names, len)</kbd> <span class=u>①</span></a>
|
||||
<samp class=p>>>> </samp><kbd class=pp>groups</kbd>
|
||||
@@ -582,8 +582,8 @@ NameError: name '__import__' is not defined</samp>
|
||||
<samp class=p>>>> </samp><kbd class=pp>eval("__import__('subprocess').getoutput('rm -rf /')",</kbd>
|
||||
<a><samp class=p>... </samp><kbd class=pp> {"__builtins__":None}, {})</kbd> <span class=u>②</span></a>
|
||||
<samp class=traceback>Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "<string>", line 1, in <module>
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "<string>", line 1, in <module>
|
||||
NameError: name '__import__' is not defined</samp></pre>
|
||||
<ol>
|
||||
<li>To evaluate untrusted expressions safely, you need to define a global namespace dictionary that maps <code>"__builtins__"</code> to <code>None</code>, the Python null value. Internally, the “built-in” functions are contained within a pseudo-module called <code>"__builtins__"</code>. This pseudo-module (<i>i.e.</i> the set of built-in functions) is made available to evaluated expressions unless you explicitly override it.
|
||||
|
||||
Reference in New Issue
Block a user