├── .gitignore
├── LICENSE
├── README.md
├── ch01
└── hello.py
├── ch02
├── ch02_arg_mutate.py
├── ch02_encoding.py
├── ch02_for_break.py
├── ch02_for_break_nested.py
├── ch02_for_multiple.py
├── ch02_for_nested.py
├── ch02_for_score.py
├── ch02_if.py
├── ch02_my_len.py
├── ch02_my_sum.py
├── ch02_return_total_avg.py
├── ch02_score_high.py
├── ch02_score_plus.py
├── ch02_while_score.py
├── myhello.py
└── mymath.py
├── ch02ex
├── ch02ex2.10_answer.py
├── ch02ex2.1_answer.py
├── ch02ex2.1_more_answer.py
├── ch02ex2.2_answer.py
├── ch02ex2.3_answer.py
├── ch02ex2.4_answer.py
├── ch02ex2.5_answer.py
├── ch02ex2.6_answer.py
├── ch02ex2.7_answer.py
├── ch02ex2.8_answer.py
└── ch02ex2.9_answer.py
├── ch03
├── ch03_geom.py
├── ch03_getbits.py
└── ch03_my_sqrt.py
├── ch03ex
├── ch03ex3.10_answer.py
├── ch03ex3.11_answer.py
├── ch03ex3.12_answer.py
├── ch03ex3.1_answer.py
├── ch03ex3.2_answer.py
├── ch03ex3.3_answer.py
├── ch03ex3.4_answer.py
├── ch03ex3.5_answer.py
├── ch03ex3.6_answer.py
├── ch03ex3.7_answer.py
├── ch03ex3.8_answer.py
└── ch03ex3.9_answer.py
├── ch04
├── ch04_99m_format.py
├── ch04_9x9m.py
├── ch04_anagram.py
├── ch04_base36encode.py
├── ch04_comb.py
├── ch04_cumulative_sum.py
├── ch04_duplicate.py
├── ch04_flatten.py
├── ch04_ft_to_ct.py
├── ch04_group.py
├── ch04_hamming.py
├── ch04_my_factorial.py
├── ch04_my_sum.py
├── ch04_product.py
├── ch04_unique.py
└── ch04_while_iteration.py
├── ch04ex
├── ch04ex4.18_answer.py
├── ch04ex4.1_answer.py
├── ch04ex4.2_answer.py
├── ch04ex4.3_answer.py
├── ch04ex4.4_answer.py
├── ch04ex4.5_answer.py
├── ch04ex4.6_answer.py
└── ch04ex4.7_answer.py
├── ch05
├── ch05_dict_invert.py
├── ch05_dict_sort.py
├── ch05_powerset.py
├── ch05_prime_sieve.py
├── ch05_symbol_table.py
├── ch05ex5.5.py
├── ch05ex5.6.py
└── ch05ex5.7.py
├── ch05ex
├── ch05ex5.1_answer.py
├── ch05ex5.2_answer.py
├── ch05ex5.3_answer.py
├── ch05ex5.5_answer.py
├── ch05ex5.6_answer.py
└── ch05ex5.8_answer.py
├── ch06
├── ch06_8queen_basic.py
├── ch06_8queen_hettingers.py
├── ch06_8queen_hettingers_gf.py
├── ch06_8queen_howell.py
├── ch06_8queen_test.py
├── ch06_counter.py
├── ch06_env.py
├── ch06_fact.py
├── ch06_fib.py
├── ch06_fib_gf.py
├── ch06_fib_hf.py
├── ch06_frange.py
├── ch06_gcd.py
├── ch06_generator_send.py
├── ch06_hanoi.py
├── ch06_hf_sum.py
├── ch06_int_from.py
├── ch06_lambda_long.py
├── ch06_lambda_sorted.py
├── ch06_multipliers.py
├── ch06_mutable_default.py
├── ch06_perm.py
├── ch06_pi_cesaro.py
├── ch06_powerset.py
├── ch06_range.py
└── ch06_yield_from.py
├── ch06ex
├── ch06ex6.12_answer.py
└── ch06ex6.15_answer.py
├── ch07
├── big5ext.py
├── big5uao.py
├── big5uao_3.py
├── ch07_big5_uao.py
├── ch07_big5_uao_test.py
├── ch07_caesar.py
├── ch07_csv.py
├── ch07_enc_change.py
├── ch07_json.py
├── ch07_line_count.py
├── ch07_line_count_test
│ ├── a no.py
│ ├── aaa big5.py
│ ├── aaa utf16be.py
│ ├── empty.py
│ ├── test ascii.py
│ └── wrong utf8.py
├── ch07_line_number.py
├── ch07_pickle.py
├── ch07_print_self.py
├── ch07_print_self_big5.py
├── ch07_print_self_utf8.py
├── ch07_redirect.py
├── ch07_redirect_stdin.py
├── ch07_struct.c
├── ch07_struct.py
├── ch07_test.c
├── ch07_test.py
├── ch07_test_context.py
├── ch07ex7.1_answer.txt
├── ch07ex7.1_testdata_0.txt
├── ch07ex7.1_testdata_1.txt
├── ch07ex7.1_testdata_2.txt
├── ch07ex7.2_answer.txt
├── ch07ex7.2_testdata_0.txt
├── ch07ex7.2_testdata_1.txt
├── ch07ex7.2_testdata_2.txt
├── ch07ex7.3_testdata.txt
├── ch07ex7.4.py
├── ch07ex7.5_testdata.txt
├── csv.txt
├── csv_out.txt
├── i_have_a_dream.txt
├── json.txt
├── json_out1.txt
├── json_out2.txt
├── pickle.bin
├── stdin_test.txt
├── test.bin
├── test.txt
├── test_big5.txt
└── test_utf8.txt
├── ch08
├── ch08_counter.py
├── ch08_namedtuple_csv.py
├── ch08ex8.5_testdata.bin
├── ch08ex8.6_testdata.ini
├── ch08ex8.6_testdata2.ini
├── ch08ex8.7_testdata.plist
├── ch08ex8.7_testdata2.plist
├── csv.txt
├── csv_out.txt
└── i_have_a_dream.txt
├── ch09
├── ch09_coin_sum.py
├── ch09_ctof_side_effetcs.py
├── ch09_dec_memo.py
├── ch09_dec_memo_limit.py
├── ch09_dec_natural.py
├── ch09_dec_notfunc.py
├── ch09_dec_time.py
├── ch09_dec_wraps.py
├── ch09_fact_i_r.py
├── ch09_fact_tail.py
├── ch09_fact_tco.py
├── ch09_forest.py
├── ch09_i_to_r.py
├── ch09_map.py
├── ch09_odd_even.py
├── ch09_odd_fibs.py
├── ch09_sum_is_prime.py
├── ch09_sum_of_primes.py
├── ch09_sum_sq_even.py
├── ch09_tph.py
├── ch09_tree.py
├── ch09ex9.10_flatten_list.py
├── ch09ex9.7_hamming.py
└── ch09ex9.xzy_accept.py
├── ch10
├── ch10_ns_package.py
├── ch10_package_example.py
├── ch10_reload.py
├── ch10_reload_2.py
├── ch10_reload_module.py
├── myhello.py
├── myhello2.py
├── mymath.py
├── mymath2.py
├── mymath3.py
├── package_example
│ ├── __init__.py
│ ├── formats
│ │ ├── __init__.py
│ │ ├── bar.py
│ │ ├── bmp.py
│ │ ├── foo.py
│ │ ├── jpg.py
│ │ └── png.py
│ ├── gui
│ │ ├── __init__.py
│ │ ├── canvas.py
│ │ └── menu.py
│ ├── info.py
│ └── tools
│ │ ├── __init__.py
│ │ ├── bar.py
│ │ ├── foo.py
│ │ ├── rotate.py
│ │ └── xyz
│ │ └── __init__.py
├── path1
│ └── mymodule
│ │ └── sub1.py
└── path2
│ └── mymodule
│ └── sub2.py
├── ch11
├── ch11_abc.py
├── ch11_bankaccount.py
├── ch11_class_generator.py
├── ch11_foo.py
├── ch11_frange.py
├── ch11_inherit.py
├── ch11_mi.py
├── ch11_mi2.py
├── ch11_myclass.py
├── ch11_myclass_scope.py
├── ch11_orderedset.py
├── ch11_private.py
├── ch11_property.py
├── ch11_static_class_method.py
├── ch11_test.py
├── ch11_test2.py
├── ch11_test3.py
├── ch11_test4.py
├── ch11_test5.py
└── ch11_test6.py
├── ch12
├── ch12_2.x_old_syntax.py
├── ch12_as_e.py
├── ch12_assert.py
├── ch12_fact.py
├── ch12_fact_2.py
├── ch12_fact_exception.py
├── ch12_fact_exception_2.py
├── ch12_flow.py
├── ch12_foo_exception.py
├── ch12_list_bound.py
├── ch12_no_with.py
└── test.txt
├── ch13
├── ch13_argparse.py
├── ch13_argv.py
├── ch13_argv_basic.py
├── ch13_dining_ph.py
├── ch13_ticket.py
└── ch13_tkinter.py
├── cover.jpg
└── misc
├── c_rw.py
├── c_ticket.py
├── ch04_base26_aa_zz.py
├── ch04_base26_aa_zz_no_padding.py
├── ch05_stu_d.py
├── ch05_stu_data.py
├── scope_comprehension.py
└── u_to_enc.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | env/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | lib/
17 | lib64/
18 | parts/
19 | sdist/
20 | var/
21 | *.egg-info/
22 | .installed.cfg
23 | *.egg
24 |
25 | # PyInstaller
26 | # Usually these files are written by a python script from a template
27 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
28 | *.manifest
29 | *.spec
30 |
31 | # Installer logs
32 | pip-log.txt
33 | pip-delete-this-directory.txt
34 |
35 | # Unit test / coverage reports
36 | htmlcov/
37 | .tox/
38 | .coverage
39 | .cache
40 | nosetests.xml
41 | coverage.xml
42 |
43 | # Translations
44 | *.mo
45 | *.pot
46 |
47 | # Django stuff:
48 | *.log
49 |
50 | # Sphinx documentation
51 | docs/_build/
52 |
53 | # PyBuilder
54 | target/
55 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 《Python程式設計入門》一書的相關程式檔案。
2 | 「ch02」資料夾,含有第2章的範例程式原始碼,以及練習題所需檔案。
3 | 「ch02ex」資料夾,含有第2章練習題的參考答案。
4 | 出版社:博碩
5 | 書號:PG21421
6 | 勘誤表與其他資訊:http://yehnan.blogspot.tw/2015/03/python_30.html
7 |
8 | 
9 |
10 |
--------------------------------------------------------------------------------
/ch01/hello.py:
--------------------------------------------------------------------------------
1 | print('Hello Python')
2 |
--------------------------------------------------------------------------------
/ch02/ch02_arg_mutate.py:
--------------------------------------------------------------------------------
1 |
2 | def my_len(seq):
3 | n = 0
4 | for x in seq:
5 | n += 1
6 | return n
7 |
8 | data = [-30.2, -22.5, 15.8, 23.7, 35.2]
9 | print(data)
10 | def ctof(temp):
11 | n = my_len(temp)
12 | i = 0
13 | while i < n:
14 | temp[i] = temp[i] * 9.0 / 5.0 + 32
15 | i += 1
16 |
17 | ctof(data)
18 | print(data)
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch02/ch02_encoding.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch02/ch02_encoding.py
--------------------------------------------------------------------------------
/ch02/ch02_for_break.py:
--------------------------------------------------------------------------------
1 |
2 | scores = (98, 78, 64, 55, 61, 82)
3 | lowerThan60 = False
4 | for x in scores:
5 | if x < 60:
6 | lowerThan60 = True
7 | break
8 |
9 | print(lowerThan60)
10 |
--------------------------------------------------------------------------------
/ch02/ch02_for_break_nested.py:
--------------------------------------------------------------------------------
1 |
2 | data = [[33, 44, 55], [18381, 99781], [60, 70, 42, 91], [32, 51]]
3 | total = 0
4 | for x in data:
5 | for y in x:
6 | if 0 <= y <= 100:
7 | total += y
8 | else:
9 | break
10 |
11 | print(total)
12 |
--------------------------------------------------------------------------------
/ch02/ch02_for_multiple.py:
--------------------------------------------------------------------------------
1 |
2 | names_scores = (('Amy', 82, 90), ('John', 33, 64), ('Zoe', 91, 94))
3 | highs = []
4 | for x, y, z in names_scores:
5 | if y >= 90 and z >= 90:
6 | highs += [x, y, z]
7 |
8 | print(highs)
9 |
--------------------------------------------------------------------------------
/ch02/ch02_for_nested.py:
--------------------------------------------------------------------------------
1 |
2 | colors = ['red', 'green', 'blue']
3 | animals = ['cat', 'dog', 'horse', 'sheep']
4 | results = []
5 | for x in colors:
6 | for y in animals:
7 | results += [x + ' ' + y]
8 |
9 | print(results)
10 |
11 |
--------------------------------------------------------------------------------
/ch02/ch02_for_score.py:
--------------------------------------------------------------------------------
1 |
2 | scores = [60, 73, 81, 95, 34]
3 | n = 0
4 | total = 0
5 | for x in scores:
6 | n += 1
7 | total += x
8 |
9 | avg = total / n
10 |
11 | print('total ' + str(total))
12 | print('average ' + str(avg))
13 |
--------------------------------------------------------------------------------
/ch02/ch02_if.py:
--------------------------------------------------------------------------------
1 |
2 | a, b, c = 3, 5, 7
3 | x = None
4 |
5 | if a < b:
6 | if b < c:
7 | x = c
8 | else:
9 | x = b
10 | else:
11 | if a < c:
12 | x = c
13 | else:
14 | x = a
15 |
16 | x
17 | print(x)
18 |
--------------------------------------------------------------------------------
/ch02/ch02_my_len.py:
--------------------------------------------------------------------------------
1 |
2 | li = [60, 73, 81, 95, 34]
3 | t = (0, 1, 2, 3, 4, 5)
4 | s = 'Learning Python is fun'
5 | empty = []
6 |
7 | def my_len(seq):
8 | n = 0
9 | for x in seq:
10 | n += 1
11 | return n
12 |
13 | print(str(li) + ' length ' + str(my_len(li)))
14 | print(str(t) + ' length ' + str(my_len(t)))
15 | print(str(s) + ' length ' + str(my_len(s)))
16 | print(str(empty) + ' length ' + str(my_len(empty)))
17 |
--------------------------------------------------------------------------------
/ch02/ch02_my_sum.py:
--------------------------------------------------------------------------------
1 |
2 | def my_sum(numbers, initial=0):
3 | total = initial
4 | for x in numbers:
5 | total += x
6 | return total
7 |
8 | scores0 = [60, 73, 81, 95, 34]
9 | scores1 = [10, 20, 30, 40, 50, 60]
10 | scores2 = [0, 0, 0]
11 | scores3 = []
12 | scores4 = [-3, -5, -6, -7, -1, -2]
13 |
14 | print(str(scores0) + ' total is ' + str(my_sum(scores0)))
15 | print(str(scores1) + ' total is ' + str(my_sum(scores1)))
16 | print(str(scores2) + ' total is ' + str(my_sum(scores2)))
17 | print(str(scores3) + ' total is ' + str(my_sum(scores3)))
18 | print(str(scores4) + ' total is ' + str(my_sum(scores4, 100)))
19 |
--------------------------------------------------------------------------------
/ch02/ch02_return_total_avg.py:
--------------------------------------------------------------------------------
1 |
2 | scores = [60, 73, 81, 95, 34]
3 |
4 | def total_avg(scores, initial=0):
5 | n = 0
6 | total = initial
7 | for x in scores:
8 | total += x
9 | n += 1
10 | return (total, total/n)
11 |
12 | print('total,avg ' + str(total_avg(scores)))
13 |
14 |
--------------------------------------------------------------------------------
/ch02/ch02_score_high.py:
--------------------------------------------------------------------------------
1 |
2 | scores = [60, 73, 81, 95, 34]
3 | n = 0
4 | high_total = 0
5 | for x in scores:
6 | if x < 60:
7 | continue
8 | n += 1
9 | high_total += x
10 |
11 | high_avg = high_total / n
12 |
13 | print('high average ' + str(high_avg))
14 |
--------------------------------------------------------------------------------
/ch02/ch02_score_plus.py:
--------------------------------------------------------------------------------
1 |
2 | scores = [30, 99, 41, 55, 84]
3 | scores_new = []
4 | for x in scores:
5 | if x >= 90:
6 | scores_new += [x]
7 | continue
8 | x += 10
9 | if x >= 90:
10 | x = 90
11 | scores_new += [x]
12 |
13 | print(scores)
14 | print(scores_new)
15 |
--------------------------------------------------------------------------------
/ch02/ch02_while_score.py:
--------------------------------------------------------------------------------
1 |
2 | scores = [60, 73, 81, 95, 34]
3 | n = 5
4 | i = 0
5 | total = 0
6 | while i < 5:
7 | total += scores[i]
8 | i += 1
9 |
10 | avg = total / n
11 |
12 | print('total ' + str(total))
13 | print('average ' + str(avg))
14 |
--------------------------------------------------------------------------------
/ch02/myhello.py:
--------------------------------------------------------------------------------
1 | #import mymath
2 | #from mymath import pi, gcd, factorial
3 | import mymath as m
4 |
5 | print('Hello Python')
6 | print('pi is ' + str(m.pi))
7 | print('gcd of 24 and 16 is ' + str(m.gcd(24, 16)))
8 | print('factorial of 6 is ' + str(m.factorial(6)))
9 | print('Bye Python')
10 |
11 | if __name__ == '__main__':
12 | print('myhello as main program')
13 | else:
14 | print('myhello as module')
15 |
16 |
--------------------------------------------------------------------------------
/ch02/mymath.py:
--------------------------------------------------------------------------------
1 |
2 | pi = 3.14
3 |
4 | def gcd(a, b):
5 | while b:
6 | a, b = b, a%b
7 | return a
8 |
9 | def factorial(n):
10 | result = 1
11 | for i in range(1, n+1):
12 | result *= i
13 | return result
14 |
15 | if __name__ == '__main__':
16 | print('mymath as main program')
17 | else:
18 | print('mymath as module')
19 |
20 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.10_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | li_a = [1, 5, 9, 11, 22, 4, 9, 1, 3, 7]
4 | li_b = [9, 4, 55, 66, 1, 11, 77]
5 |
6 | def f(li_a, li_b):
7 | li = []
8 | for n in li_a:
9 | if n in li_b and n not in li:
10 | li += [n]
11 | return li
12 |
13 | print(f(li_a, li_b))
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.1_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # examples:
4 | # leap year: 1600, 1992, 1996, 2000, 2060, 2400
5 | # not leap year: 1800, 1900, 2100
6 | # not leap year: 1997, 2057
7 |
8 | year = 1996
9 |
10 | if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0):
11 | print(year)
12 | print(' is leap year')
13 | else:
14 | print(year)
15 | print(' is not leap year')
16 |
17 | year = 2100
18 |
19 | if year % 400 == 0 or year % 4 == 0 and year % 100 != 0:
20 | print(year)
21 | print(' is leap year')
22 | else:
23 | print(year)
24 | print(' is not leap year')
25 |
26 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.1_more_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from __future__ import print_function
4 |
5 | # examples:
6 | # leap year: 1600, 1992, 1996, 2000, 2060, 2400
7 | # not leap year: 1800, 1900, 2100
8 | # not leap year: 1997, 2057
9 |
10 | def leapyear_a(year):
11 | if year % 400 == 0:
12 | return True
13 | elif year % 100 == 0:
14 | return False
15 | elif year % 4 == 0:
16 | return True
17 | else:
18 | return False
19 |
20 | def leapyear_b(year):
21 | if ((year % 4 == 0) and (year % 100 != 0)) or (year % 400 == 0):
22 | return True
23 | else:
24 | return False
25 |
26 | def leapyear_c(year):
27 | if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0):
28 | return True
29 | else:
30 | return False
31 |
32 | def leapyear_d(year):
33 | if year % 400 == 0 or year % 4 == 0 and year % 100 != 0:
34 | return True
35 | else:
36 | return False
37 |
38 | if __name__ == '__main__':
39 | funcs = [leapyear_a, leapyear_b, leapyear_c, leapyear_d]
40 | leapyears = [1600, 1992, 1996, 2000, 2060, 2400]
41 | not_leapyears = [1800, 1900, 2100, 1997, 2057]
42 | allpass = True
43 | for f in funcs:
44 | print('Testing function: %s' % f.__name__)
45 | for y in leapyears:
46 | if f(y) != True:
47 | print('Failed: %d is leap year' % y)
48 | allpass = False
49 | for y in not_leapyears:
50 | if f(y) != False:
51 | print('Failed: %d is not leap year' % y)
52 | allpass = False
53 | if allpass:
54 | print('All passed')
55 | else:
56 | print('Not all passed')
57 |
58 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.2_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # for loop
4 | for x in range(2, 9+1):
5 | for y in range(1, 9+1):
6 | print(x, ' * ', y, ' = ', x*y)
7 | # print(str(x) + ' * ' + str(y) + ' = ' + str(x*y))
8 | # print('%d * %d = %d' % (x, y, x*y))
9 |
10 | # while loop
11 | x = 2
12 | while x < 9+1:
13 | y = 1
14 | while y < 9+1:
15 | print(x, ' * ', y, ' = ', x*y)
16 | # print(str(x) + ' * ' + str(y) + ' = ' + str(x*y))
17 | # print('%d * %d = %d' % (x, y, x*y))
18 | y += 1
19 | x += 1
20 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.3_answer.py:
--------------------------------------------------------------------------------
1 |
2 | # don't use continue statement
3 |
4 | scores = [30, 99, 41, 55, 84]
5 | scores_new = []
6 | for x in scores:
7 | if x >= 90:
8 | scores_new += [x]
9 | else:
10 | if x+10 >= 90:
11 | scores_new += [90]
12 | else:
13 | scores_new += [x+10]
14 |
15 | print(scores)
16 | print(scores_new)
17 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.4_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Celsius to Fahrenheit
4 | def ctof(temp):
5 | return temp * 9.0 / 5.0 + 32
6 |
7 | # Fahrenheit to Celsius
8 | def ftoc(temp):
9 | return (temp - 32) * 5.0 / 9.0
10 |
11 |
12 | if __name__ == '__main__':
13 | # simple tests
14 | if ctof(0) - 32 >= 0.0001:
15 | print('Failed: 0 C should be 32 F')
16 | if ctof(100) - 212 >= 0.0001:
17 | print('Failed: 100 C should be 212 F')
18 |
19 | if ftoc(32) - 0 >= 0.0001:
20 | print('Failed: 32 F should be 0 C')
21 | if ftoc(212) - 100 >= 0.0001:
22 | print('Failed: 212 F should be 100 C')
23 |
24 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.5_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def f(x, y, z):
4 | if x >= y:
5 | if y >= z: # x y z
6 | return x**2 + y**2
7 | else: # x z y
8 | return x**2 + z**2
9 | else:
10 | if x >= z: # y x z
11 | return y**2 + x**2
12 | else: # y z x
13 | return y**2 + z**2
14 |
15 |
16 | if __name__ == '__main__':
17 | # simple tests
18 | if f(1, 2, 3) != (2**2 + 3**2):
19 | print('Failed')
20 | if f(5, 3, 4) != (5**2 + 4**2):
21 | print('Failed')
22 | if f(9, 11, 10) != (11**2 + 10**2):
23 | print('Failed')
24 |
25 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.6_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # greatest common divisor
4 | def gcd(a, b):
5 | while b:
6 | a, b = b, a%b
7 | return a
8 |
9 | # least common multiple
10 | def lcm(a, b):
11 | x = gcd(a, b)
12 | return (a // x) * b
13 |
14 | if __name__ == '__main__':
15 | # simple tests
16 | if lcm(7, 13) != 91:
17 | print('Failed')
18 | if lcm(100, 25) != 100:
19 | print('Failed')
20 | if lcm(16, 24) != 48:
21 | print('Failed')
22 |
23 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.7_answer.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | # 串列裡含有由小到大排列好的整數,數字可能重複,
4 | # 例如 [0, 1, 1, 2, 3, 4, 5, 5, 9, 9, 9, 23, 25, 25, 25],
5 | # 請撰寫函式找出重複最多次的整數,若重複次數相等則回傳值較小的,
6 | # 以此例而言,9 與 25 都重複 3 次,應回傳 9。
7 |
8 | # 若把「重複的整數」稱為「平台」,
9 | # 那麼此問題可稱為找出「最長平台」的問題,
10 | # 以上例而言,整數0這個平台的長度是1,整數1這個平台的長度為2,
11 | # 依此類推,最長平台是9與25,根據題意應回傳9。
12 |
13 | def plateau(data):
14 | if len(data) == 0:
15 | return None
16 | # 記錄到目前為止找到的最長平台
17 | result_i_max = 0 # 一開始先把索引值0的元素當做最長平台
18 | result_x_max = data[0] # 記錄該平台的整數,最後會成為此函式的回傳
19 | count_max = 1 # 該平台的長度,目前是1
20 |
21 | # 記錄目前正在處理中的平台
22 | result_i = 0 # 從索引值0開始處理
23 | result_x = data[0] # 記錄該平台的整數
24 | count = 1 # 該平台的長度,目前是1
25 |
26 | for i in range(1, len(data)): # 從索引值1開始
27 | if data[i] == result_x: # 若元素(整數)等於前一平台,該平台的長度加一
28 | count += 1 # 換句話說,該平台繼續延伸
29 |
30 | else: # data[i] > result_x: # 若大於,代表進入新的平台
31 | result_i = i # 進入新的平台了,
32 | result_x = data[i] # 所以重新設定目前正在處理的平台
33 | count = 1
34 |
35 | if count > count_max: # 記錄到目前為止,最長平台的資訊
36 | result_i_max, result_x_max, count_max = result_i, result_x, count
37 |
38 | return result_x_max # 此題目要求回傳result_x_max,
39 | # 有時則會需要result_i_max或count_max
40 |
41 | if __name__ == '__main__':
42 | # simple tests
43 | data = [0, 1, 1, 2, 3, 4, 5, 5, 9, 9, 9, 23, 25, 25, 25]
44 | if plateau(data) != 9:
45 | print('Failed')
46 |
47 | data = [1, 1, 1, 2, 3, 4, 5, 5, 9, 9, 9, 23, 25, 25, 25]
48 | if plateau(data) != 1:
49 | print('Failed')
50 |
51 | data = [1, 1, 1, 2, 3, 5, 5, 5, 5, 9, 9, 23, 25, 25, 25]
52 | if plateau(data) != 5:
53 | print('Failed')
54 |
55 | data = [0, 1, 1, 2, 3, 4, 5, 5, 9, 9, 9, 23, 25, 25, 25, 25]
56 | if plateau(data) != 25:
57 | print('Failed')
58 |
59 | data = [0, 1, 2, 2, 3, 4, 5, 5, 9, 9, 9, 23, 25, 25, 25, 25, 26, 27, 27]
60 | if plateau(data) != 25:
61 | print('Failed')
62 |
63 | # 你是否能改進這支函式、使用較少的物件?
64 |
65 | # 若只需知道最長平台的長度,程式碼將非常簡短,如下:
66 | def plateau_longest_length(data):
67 | if len(data) == 0:
68 | return None
69 |
70 | length_max = 1
71 | for i in range(1, len(data)):
72 | if data[i] == data[i - length_max]:
73 | length_max += 1
74 |
75 | return length_max
76 |
77 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.8_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def is_leap_year(year):
4 | if ((year % 4 == 0) and (year % 100 != 0)) or (year % 400 == 0):
5 | return True
6 | else:
7 | return False
8 |
9 | def year_days(year):
10 | return 365 + (1 if is_leap_year(year) else 0)
11 |
12 | # argument month is 1, 2, 3, ..., 11, 12
13 | def month_days(month, year):
14 | md = [31, 28, 31, 30, 31, 30,
15 | 31, 31, 30, 31, 30, 31]
16 | return md[month-1] + (1 if month == 2 and is_leap_year(year) else 0)
17 |
18 | # assume epoch is [1970, 1, 1]
19 | def days_since_epoch(date):
20 | year, month, day = date
21 |
22 | days = day
23 | for y in range(1970, year):
24 | days += year_days(y)
25 | for m in range(1, month):
26 | days += month_days(m, year)
27 |
28 | return days
29 |
30 | def days_diff(date1, date2):
31 | return days_since_epoch(date2) - days_since_epoch(date1)
32 |
33 |
34 | ##
35 |
36 | date1 = [2014, 11, 12]
37 | date2 = [2015, 2, 15]
38 |
39 | print(days_diff(date1, date2), "days")
40 |
41 |
42 | # from datetime import date
43 | # print(date(*date2) - date(*date1))
44 |
45 |
46 | # for y in range(1970, 2020):
47 | # for m in range(5, 11+1):
48 | # for d in range(5, 27):
49 | # date1 = [y, m, d]
50 | # date2 = [y+1, m-2, d-3]
51 | # if days_diff(date1, date2) != (date(*date2) - date(*date1)).days:
52 | # print("Failed")
53 |
54 |
--------------------------------------------------------------------------------
/ch02ex/ch02ex2.9_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def factorial(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 |
9 | def f(n):
10 | fact = factorial(n)
11 | result = 0
12 | while fact > 0:
13 | result += fact % 10
14 | fact //= 10
15 |
16 | return result
17 |
18 | if __name__ == '__main__':
19 | # simple tests
20 | n_fn = ((1, 1), (2, 2), (3, 6), (4, 6), (5, 3),
21 | (6, 9), (7, 9), (8, 9), (9, 27), (10, 27))
22 |
23 | for n, fn in n_fn:
24 | if fn != f(n):
25 | print('Failed:')
26 | print('summation of digits of %d! should be %d, not %d' % (n, fn, f(n)))
27 |
28 |
--------------------------------------------------------------------------------
/ch03/ch03_geom.py:
--------------------------------------------------------------------------------
1 |
2 | def geomean(numbers):
3 | product = 1
4 | for n in numbers:
5 | product *= n
6 | return product ** (1.0 / len(numbers))
7 |
8 | if __name__ == '__main__':
9 | a = list(range(1, 10+1))
10 | gm = geomean(a)
11 | print(gm)
12 |
13 |
--------------------------------------------------------------------------------
/ch03/ch03_getbits.py:
--------------------------------------------------------------------------------
1 |
2 | def getbits(x, p, n):
3 | return (x >> (p+1-n)) & ~(~0b0 << n)
4 |
5 | print(bin(getbits(0b10101010, 4, 3)))
6 | print(bin(getbits(0b11110101, 5, 4)))
7 |
8 |
--------------------------------------------------------------------------------
/ch03/ch03_my_sqrt.py:
--------------------------------------------------------------------------------
1 |
2 | diff = 0.00001
3 | def is_ok(n, ans):
4 | return abs(ans**2 - n) < diff
5 | def get_better(n, ans):
6 | return ((float(n) / ans) + ans) / 2
7 | def my_sqrt(n):
8 | ans = 1
9 | while not is_ok(n, ans):
10 | ans = get_better(n, ans)
11 | return ans
12 |
13 | import math
14 | print(my_sqrt(9))
15 | print(math.sqrt(9))
16 | print(my_sqrt(2))
17 | print(math.sqrt(2))
18 | print(my_sqrt(3))
19 | print(math.sqrt(3))
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.10_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | try:
4 | input = raw_input
5 | except NameError:
6 | pass
7 |
8 | ####
9 |
10 | import random
11 |
12 | def main():
13 | range_min = 1
14 | range_max = 100
15 | answer = random.randint(range_min+1, range_max-1)
16 | guess_count = 0
17 |
18 | while True:
19 | print('Range %d ~ %d' % (range_min, range_max))
20 | guess = input('Input your %dth guess: ' % (guess_count+1))
21 | guess = int(guess)
22 | if guess <= range_min or range_max <= guess:
23 | print('Your guess %d is beyond the valid range.' % guess)
24 | elif guess == answer:
25 | print('Yes, answer is %d!' % answer)
26 | break
27 | else:
28 | if answer < guess:
29 | range_max = guess
30 | else:
31 | range_min = guess
32 | guess_count += 1
33 |
34 | if __name__ == '__main__':
35 | main()
36 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.11_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from math import log2, ceil
4 |
5 | def f(a, b):
6 | bit_n = ceil(log2(max(a, b)))
7 | count = 0
8 | for i in range(bit_n):
9 | if (a ^ b) & (0x1 << i):
10 | count += 1
11 | return count
12 |
13 |
14 | if __name__ == "__main__":
15 | if f(31, 14) != 2:
16 | print('Failed: f(31, 14) should be 2')
17 |
18 | if f(0b11110000, 0b00001111) != 8:
19 | print('Failed: f(0b11110000, 0b00001111) should be 8')
20 |
21 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.12_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | def f(n):
5 | m1 = 0b10101010
6 | mask1 = (m1 << 24) | (m1 << 16) | (m1 << 8) | m1
7 | m2 = 0b01010101
8 | mask2 = (m2 << 24) | (m2 << 16) | (m2 << 8) | m2
9 |
10 | return ((n & mask1) >> 1) | ((n & mask2) << 1)
11 |
12 |
13 | if __name__ == "__main__":
14 | if f(0b10101010) != 0b01010101:
15 | print('Failed: f(0b10101010) should be 0b01010101')
16 |
17 | if f(0b11001001) != 0b11000110:
18 | print('Failed: f(0b11001001) should be 0b11000110')
19 |
20 | if f(0b1100100111001001) != 0b1100011011000110:
21 | print('Failed: f(0b1100100111001001) should be 0b1100011011000110')
22 |
23 | if f(0b101010101100100111001001) != 0b010101011100011011000110:
24 | print('Failed: f(0b101010101100100111001001) should be 0b010101011100011011000110')
25 |
26 | if f(0b11001001101010101100100111001001) != 0b11000110010101011100011011000110:
27 | print('Failed: f(0b11001001101010101100100111001001) should be 0b11000110010101011100011011000110')
28 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.1_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import math
4 |
5 | def area_circle(r):
6 | return r * r * math.pi
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.2_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def f(n):
4 | if n < 0:
5 | n = 0
6 | elif n > 255:
7 | n = 255
8 |
9 | if 0 <= n <= 130:
10 | a0, a1 = 0, 130
11 | b0, b1 = 0, 60
12 | elif 130 < n < 200:
13 | a0, a1 = 130, 200
14 | b0, b1 = 60, 85
15 | else: # 200 <= n <= 255
16 | a0, a1 = 200, 255
17 | b0, b1 = 85, 100
18 |
19 | return int((n - a0) / (a1 - a0) * (b1 - b0) + b0)
20 |
21 |
22 | if __name__ == '__main__':
23 | # simple tests
24 | if f(0) != 0:
25 | print('Failed')
26 | if f(130) != 60:
27 | print('Failed')
28 | if f(200) != 85:
29 | print('Failed')
30 | if f(255) != 100:
31 | print('Failed')
32 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.3_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def f(n):
4 | if n < 10:
5 | if n == 9 or n == 6 or n == 3:
6 | return True
7 | else:
8 | return False
9 | else:
10 | result = 0
11 | while n > 0:
12 | result += n % 10
13 | n //= 10
14 | return f(result)
15 |
16 |
17 | if __name__ == '__main__':
18 | # simple tests
19 | if f(9) != True:
20 | print('Failed')
21 | if f(37524) != True:
22 | print('Failed')
23 | if f(21) != True:
24 | print('Failed')
25 | if f(18) != True:
26 | print('Failed')
27 | if f(4) != False:
28 | print('Failed')
29 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.4_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def collatz(n):
4 | if n == 1:
5 | return 1
6 | elif n % 2 == 0:
7 | return collatz(n // 2)
8 | else:
9 | return collatz(3 * n + 1)
10 |
11 | def collatz_i(n):
12 | while n != 1:
13 | if n % 2 == 0:
14 | n //= 2
15 | else:
16 | n = 3 * n + 1
17 | return n
18 |
19 | if __name__ == '__main__':
20 | for i in range(1, 10000+1):
21 | if collatz_i(i) != 1:
22 | print('collatz_i(' + str(i) + ') failed');
23 | break
24 | else:
25 | print('All passed')
26 |
27 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.5_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # note: this version is very inefficient
4 | def is_prime(n):
5 | for i in range(2, n):
6 | if n % i == 0:
7 | return False
8 | return True
9 |
10 | if __name__ == '__main__':
11 | # simple tests
12 | primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
13 | not_primes = [4, 6, 15, 20, 21, 25, 100, 246]
14 | for i in primes:
15 | if is_prime(i) != True:
16 | print('Failed: %d is prime' % i)
17 | for i in not_primes:
18 | if is_prime(i) != False:
19 | print('Failed: %d is not prime' % i)
20 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.6_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def is_1089(n):
4 | nabc = n
5 | ncba = int(str(nabc)[::-1])
6 | ndef = abs(nabc - ncba)
7 | nfed = int(str(ndef)[::-1])
8 | return (ndef + nfed) == 1089
9 |
10 | if __name__ == '__main__':
11 | # simple test
12 | if is_1089(732) != True:
13 | print('Failed: 732')
14 | if is_1089(654) != True:
15 | print('Failed: 654')
16 | if is_1089(123) != True:
17 | print('Failed: 123')
18 |
19 | # test all 3-digit numbers
20 | for x in range(1, 9+1):
21 | for y in range(0, 9+1):
22 | for z in range(0, 9+1):
23 | n = x*100 + y*10 + z
24 | if is_1089(n) != (abs(x - z) >= 2):
25 | print('Failed: %d' % n);
26 |
27 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.7_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import math
4 |
5 | def factorial(n):
6 | result = 1
7 | for i in range(1, n+1):
8 | result *= i
9 | return result
10 |
11 | def factorial_stirling(n):
12 | return math.sqrt(2 * math.pi * n) * pow(float(n) / math.e, n)
13 |
14 | if __name__ == '__main__':
15 | # simple test
16 | for n in range(2, 30):
17 | nf = factorial(n)
18 | nfs = factorial_stirling(n)
19 | error = (nfs - nf) / nf
20 | tolerance = 0.1
21 | if error >= tolerance:
22 | print('%d! = %d, stirling: %f' % (n, nf, nfs))
23 | print('error: %f' % ((nfs - nf) / nf))
24 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.8_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import math
4 |
5 | def is_cardano(a, b, c):
6 | return (8*a*a*a + 15*a*a + 6*a - 1) == 27*b*b*c
7 |
8 | def main():
9 | count = 0
10 | for a in range(1, 1000-1-1 + 1):
11 | for b in range(1, 1000-a-1 + 1):
12 | for c in range(1, 1000-a-b + 1):
13 | if is_cardano(a, b, c):
14 | count += 1
15 | print("%d: %d, %d, %d" % (count, a, b, c))
16 | print('Total: %d' % count)
17 | return count
18 |
19 | if __name__ == '__main__':
20 | # simple test
21 | if is_cardano(2, 1, 5) == False:
22 | print('Failed: (2, 1, 5) should be a Cardano Triple')
23 | if main() != 149:
24 | print('Failed: should be 149')
25 |
--------------------------------------------------------------------------------
/ch03ex/ch03ex3.9_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def check_ab(answer, guess):
4 | a_count = 0
5 | b_count = 0
6 | for i in range(len(guess)):
7 | if guess[i] == answer[i]:
8 | a_count += 1
9 | elif guess[i] in answer:
10 | b_count += 1
11 |
12 | return (a_count, b_count)
13 |
14 | if __name__ == '__main__':
15 | # simple test
16 | if check_ab('5234', '5346') != (1, 2):
17 | print('Failed: answer 5234, guess 5346')
18 | if check_ab('5234', '5234') != (4, 0):
19 | print('Failed: answer 5234, guess 5234')
20 | if check_ab('1234', '4321') != (0, 4):
21 | print('Failed: answer 1234, guess 4321')
22 | if check_ab('1234', '2134') != (2, 2):
23 | print('Failed: answer 1234, guess 2134')
24 | if check_ab('1234', '3241') != (1, 3):
25 | print('Failed: answer 1234, guess 3241')
26 |
--------------------------------------------------------------------------------
/ch04/ch04_99m_format.py:
--------------------------------------------------------------------------------
1 |
2 | def p99(li):
3 | for y in range(1, 9+1):
4 | result = []
5 | for x in li:
6 | s = '%2d x%2d = %2d' % (x, y, x*y)
7 | result.append(s)
8 | print(' '.join(result))
9 |
10 | p99([2, 3, 4, 5])
11 | print('')
12 | p99([6, 7, 8, 9])
13 |
14 |
--------------------------------------------------------------------------------
/ch04/ch04_9x9m.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | result = []
4 | for x in range(2, 9+1):
5 | for y in range(1, 9+1):
6 | result.append(str(x) + '*' + str(y) + '=' + str(x*y))
7 |
8 | print(result)
9 |
10 | ####
11 |
12 | result = [str(x)+'*'+str(y)+'='+str(x*y) for x in range(2, 9+1)
13 | for y in range(1, 9+1)]
14 |
15 | print(result)
16 |
--------------------------------------------------------------------------------
/ch04/ch04_anagram.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def is_anagram(s1, s2):
4 | s1 = ''.join(s1.lower().split())
5 | s2 = ''.join(s2.lower().split())
6 | return sorted(s1) == sorted(s2)
7 |
8 | # True
9 | print(is_anagram('heart', 'earth'))
10 | print(is_anagram('Torchwood', 'Doctor Who'))
11 | print(is_anagram('spot', 'stop'))
12 | print(is_anagram('silent', 'listen'))
13 | print(is_anagram('William Shakespeare', 'I am a weakish speller'))
14 | print(is_anagram('computer', 'cuter mop'))
15 | print(is_anagram('a b c \t\n 1 2 3 \t\n ', '123abc\t\n'))
16 | print('')
17 | # False
18 | print(is_anagram('abc', 'abd'))
19 | print(is_anagram('play', 'pray'))
20 | print(is_anagram('string', 'sting'))
21 |
22 |
--------------------------------------------------------------------------------
/ch04/ch04_base36encode.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4 | def base36encode(number, alphabet=alphabet):
5 | result = []
6 | base = len(alphabet)
7 | sign = ''
8 | if number < 0:
9 | sign = '-'
10 | number = -number
11 |
12 | while number >= base:
13 | number, i = divmod(number, base)
14 | result.append(alphabet[i])
15 | result.append(alphabet[number])
16 | if sign == '-':
17 | result.append(sign)
18 |
19 | return ''.join(reversed(result))
20 |
21 | print(base36encode(int('0', 36)))
22 | print(base36encode(int('ZZ', 36)))
23 | print(base36encode(int('ZYXW', 36)))
24 | print(base36encode(int('-ABCDEF', 36)))
25 | print(base36encode(int('-GHIJKLMNOPQ', 36)))
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ch04/ch04_comb.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | li0 = ['a', 'b', 'c']
4 | li1 = ['.jpg', '.png', '.bmp']
5 | result = []
6 | for x in li0:
7 | if x != 'a':
8 | for y in li1:
9 | if y != '.jpg':
10 | result.append(x + y)
11 |
12 | print(result)
13 |
14 | ####
15 |
16 | result = [x+y for x in li0 if x != 'a' for y in li1 if y != '.jpg']
17 |
18 | print(result)
19 |
--------------------------------------------------------------------------------
/ch04/ch04_cumulative_sum.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def cumulative_sum(iterable, start=0):
4 | result = []
5 | acc = start
6 | for x in iterable:
7 | acc += x
8 | result.append(acc)
9 | return result
10 |
11 |
12 | print(cumulative_sum(range(10+1)))
13 | print(cumulative_sum(range(0, 1000, 100)))
14 |
15 |
--------------------------------------------------------------------------------
/ch04/ch04_duplicate.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def duplicate(iterable):
4 | fst = []
5 | snd = []
6 | for x in iterable:
7 | if x not in fst:
8 | fst.append(x)
9 | elif x not in snd:
10 | snd.append(x)
11 | else:
12 | pass
13 | return snd
14 |
15 | print(duplicate([1, 2, 6, 1, 3, 2, 5]))
16 | print(duplicate(range(10)))
17 | print(duplicate([1, 1, 3, 1, 3, 3, 1, 2, 1, 5, 2]))
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch04/ch04_flatten.py:
--------------------------------------------------------------------------------
1 |
2 | def flatten(iterable):
3 | result = []
4 | for x in iterable:
5 | result.extend(x)
6 | return result
7 |
8 |
9 | print(flatten([[0, 1, 2], [3, 4, 5], [6], [7, 8], [9]]))
10 | print(flatten([[0, 1], [3, 5], [6], [7, 8], [9]]))
11 |
--------------------------------------------------------------------------------
/ch04/ch04_ft_to_ct.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | ft = [32, 212, 10, 55, 78, 110, 178]
4 | def ftoc(ft):
5 | ct = []
6 | for x in ft:
7 | ct.append((x - 32) * 5 / 9)
8 | return ct
9 |
10 | ct = ftoc(ft)
11 | print(list(zip(ft, ct)))
12 |
13 | ####
14 |
15 | ft = [32, 212, 10, 55, 78, 110, 178]
16 | ct = [(x - 32) * 5 / 9 for x in ft]
17 | print(list(zip(ft, ct)))
18 |
19 |
--------------------------------------------------------------------------------
/ch04/ch04_group.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def group(iterable, size):
4 | result = []
5 | li = list(iterable)
6 | length = len(li)
7 | for i in range(0, length, size):
8 | result.append(li[i:i+size])
9 | return result
10 |
11 | print(group([1, 2, 3, 4, 5, 6, 7, 8, 9], 3))
12 | # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
13 |
14 | print(group([1, 2, 3, 4, 5, 6, 7, 8, 9], 4))
15 | # [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
16 |
17 | print(group(range(20), 5))
18 |
--------------------------------------------------------------------------------
/ch04/ch04_hamming.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def hamming(s1, s2):
4 | lens = (len(s1), len(s2))
5 | minlen = min(lens)
6 | maxlen = max(lens)
7 | h = maxlen - minlen
8 |
9 | for i in range(minlen):
10 | if(s1[i] != s2[i]):
11 | h += 1
12 |
13 | return h
14 |
15 | print(hamming('abcde', 'edcba')) # 4
16 | print(hamming('abc', 'abcde')) # 2
17 | print(hamming('1011101', '1001001')) # 2
18 | print(hamming('karolin', 'kathrin')) # 3
19 |
20 |
--------------------------------------------------------------------------------
/ch04/ch04_my_factorial.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def product(iterable, start=1):
4 | result = start
5 | for x in iterable:
6 | result *= x
7 | return result
8 |
9 | def my_factorial(n):
10 | return product(range(2, n+1))
11 |
12 | from math import factorial
13 | print('6! is ' + str(my_factorial(6)))
14 | print('math.factorial: ' + str(factorial(6)))
15 | print('10! is ' + str(my_factorial(10)))
16 | print('math.factorial: ' + str(factorial(10)))
17 | print('15! is ' + str(my_factorial(15)))
18 | print('math.factorial: ' + str(factorial(15)))
19 |
--------------------------------------------------------------------------------
/ch04/ch04_my_sum.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def my_sum(iterable, start=0):
4 | result = start
5 | for x in iterable:
6 | result += x
7 | return result
8 |
9 | a = ('a', 'b', 'c', 'd')
10 | b = range(1, 10+1)
11 | c = ['abc', 'def', 'gh', 'i']
12 | print(my_sum(a, ''))
13 | print(my_sum(b))
14 | print(my_sum(c, ''))
15 |
--------------------------------------------------------------------------------
/ch04/ch04_product.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def product(iterable, start=1):
4 | result = start
5 | for x in iterable:
6 | result *= x
7 | return result
8 |
9 | a = range(1, 10+1)
10 | b = [2, 3, 4, 5]
11 | c = [1.1, 3.5, 5.6]
12 | print(product(a, 0.1))
13 | print(product(b))
14 | print(product(c))
15 |
--------------------------------------------------------------------------------
/ch04/ch04_unique.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def unique(iterable):
4 | result = []
5 | for x in iterable:
6 | if x not in result:
7 | result.append(x)
8 | return result
9 |
10 |
11 | print(unique([1, 2, 1, 3, 2, 5, 5, 6, 1])) # [1, 2, 3, 5, 6]
12 | print(unique([1, 2, 1, 3, 2, 5])) # [1, 2, 3, 5]
13 | print(unique(range(10)))
14 |
15 |
--------------------------------------------------------------------------------
/ch04/ch04_while_iteration.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | li = [30, 41, 52]
4 | itb = iter(li)
5 | while True:
6 | try:
7 | x = next(itb)
8 | print(x)
9 | except StopIteration:
10 | break
11 |
12 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.18_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def is_palindrome(n):
4 | ns = str(n)
5 | a, b = 0, len(ns)-1
6 | while a < b:
7 | if ns[a] != ns[b]:
8 | return False
9 | else:
10 | a += 1
11 | b -= 1
12 | return True
13 |
14 | def is_palindrome_2(n):
15 | ns = str(n)
16 | ns_r = ''.join(reversed(ns))
17 | return ns == ns_r
18 |
19 | print(sum([1 for i in range(10, 99+1) if is_palindrome(i)]))
20 | print(sum([1 for i in range(100, 999+1) if is_palindrome(i)]))
21 | print(sum([1 for i in range(1000, 9999+1) if is_palindrome(i)]))
22 |
23 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.1_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def find_once(li):
4 | result = []
5 | for i, e in enumerate(li):
6 | if e not in li[:i] and e not in li[i+1:]:
7 | result.append(e)
8 | return result
9 |
10 | if __name__ == '__main__':
11 | # simple tests
12 | li = [9, 5, 5, -4, 7, 6, 4, 1, -2, 0, 10, 9, 7]
13 | if find_once(li) != [-4, 6, 4, 1, -2, 0, 10]:
14 | print('Failed')
15 |
16 | li = [1, 1, -3, -3]
17 | if find_once(li) != []:
18 | print('Failed')
19 |
20 | li = [5, 6, 8, -3]
21 | if find_once(li) != [5, 6, 8, -3]:
22 | print('Failed')
23 |
24 | li = [-3, 8, 5, 6, 8, -3]
25 | if find_once(li) != [5, 6]:
26 | print('Failed')
27 |
28 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.2_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def split_a(li, n):
4 | result = []
5 | for i in range(0, len(li), n):
6 | result.append(li[i:i+n])
7 |
8 | return result
9 |
10 | def split_b(li, n):
11 | return [li[i:i+n] for i in range(0, len(li), n)]
12 |
13 | if __name__ == '__main__':
14 | # simple tests
15 | li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
16 | if split_a(li, 3) != [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]:
17 | print('Failed')
18 | if split_a(li, 4) != [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]:
19 | print('Failed')
20 | if split_a(li, 1) != [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]:
21 | print('Failed')
22 |
23 | if split_b(li, 3) != [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]:
24 | print('Failed')
25 | if split_b(li, 4) != [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]:
26 | print('Failed')
27 | if split_b(li, 1) != [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]:
28 | print('Failed')
29 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.3_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def f(li):
4 | result = []
5 | for i, e in enumerate(li):
6 | result.append(e+i)
7 |
8 | return result
9 |
10 | if __name__ == '__main__':
11 | # simple tests
12 | li = [8, 4, 1, 7]
13 | if f(li) != [8, 5, 3, 10]:
14 | print('Failed')
15 |
16 | li = [10, 11, 12, 13]
17 | if f(li) != [10, 12, 14, 16]:
18 | print('Failed')
19 |
20 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.4_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | s = 'abcde'
4 | print(s)
5 |
6 | sr0 = ''.join(reversed(s))
7 | print(sr0) # edcba, ok
8 |
9 | sr1 = s[::-1]
10 | print(sr1) # edcba, ok
11 |
12 | sr2 = s[-1:0:-1]
13 | print(sr2) # edcb, not ok
14 |
15 | sr3 = s[-1::-1]
16 | print(sr3) # edcba, ok
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.5_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | data = [('John', 40, 174, 65), ('Amy', 28, 165, 44), ('Jessie', 32, 158, 45)]
4 |
5 | data_sorted = sorted(data, key=lambda x: x[1])
6 |
7 | print(data_sorted)
8 |
9 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.6_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def cumulative_product(iterable, start=1):
4 | result = []
5 | acc = start
6 | for x in iterable:
7 | acc *= x
8 | result.append(acc)
9 | return result
10 |
11 | # print(cumulative_product(range(1, 9+1)))
12 |
--------------------------------------------------------------------------------
/ch04ex/ch04ex4.7_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # def group(iterable, size):
4 | # result = []
5 | # li = list(iterable)
6 | # length = len(li)
7 | # for i in range(0, length, size):
8 | # result.append(li[i:i+size])
9 | # return result
10 |
11 | def group(iterable, size):
12 | result = []
13 | it = iter(iterable)
14 | while True:
15 | temp = []
16 | try:
17 | for _ in range(size):
18 | temp.append(next(it))
19 | result.append(temp)
20 | except StopIteration:
21 | if temp != []:
22 | result.append(temp)
23 | break
24 | return result
25 |
26 |
27 | if __name__ == '__main__':
28 | # simple tests
29 | li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
30 | if group(li, 3) != [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]:
31 | print('Failed')
32 | if group(li, 4) != [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]:
33 | print('Failed')
34 | if group(li, 1) != [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]:
35 | print('Failed')
36 |
37 | if group(li, 3) != [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]:
38 | print('Failed')
39 | if group(li, 4) != [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]:
40 | print('Failed')
41 | if group(li, 1) != [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]:
42 | print('Failed')
43 |
44 |
45 |
--------------------------------------------------------------------------------
/ch05/ch05_dict_invert.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | d = {'Amy': 45, 'Bob': 50, 'Cathy': 62, 'David': 45,
4 | 'Eason': 63, 'Fred': 78, 'George': 72, 'Helen': 82,
5 | 'Ivan': 100, 'Jason': 98, 'Kevin': 0, 'Laura': 100}
6 |
7 | d2 = {v:k for k,v in d.items()}
8 |
9 | d3 = {}
10 | for k, v in d.items():
11 | r = v // 10
12 | if r not in d3:
13 | d3[r] = []
14 | d3[r].append(k)
15 | print(d3)
16 |
17 | #### output: ####
18 | # {0: ['Kevin'], 4: ['David', 'Amy'], 5: ['Bob'], 6: ['Cathy', 'Eason'],
19 | # 7: ['Fred', 'George'], 8: ['Helen'], 9: ['Jason'], 10: ['Ivan', 'Laura']}
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ch05/ch05_dict_sort.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | d = {'Amy': (45, 60, 33), 'Bob': (50, 62, 78),
4 | 'Cathy': (62, 98, 87), 'David': (45, 22, 12),
5 | 'Eason': (63, 55, 71), 'Fred': (78, 79, 32)}
6 |
7 | for k in sorted(d.keys()):
8 | print(k, d[k])
9 |
10 | def foo(item):
11 | return item[1][2]
12 | for item in sorted(d.items(), key=foo):
13 | print(item)
14 |
15 | def bar(item):
16 | return sum(item[1])
17 | for item in sorted(d.items(), key=bar):
18 | print(item)
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch05/ch05_powerset.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | #### powerset, all subsets of a set ####
4 | def powerset(s):
5 | li = list(s)
6 | ps = set()
7 | for n in range(0, 2**len(s)):
8 | sub = set()
9 | x = n
10 | for i in range(len(s)):
11 | if x & 0x1:
12 | sub.add(li[i])
13 | x >>= 1
14 | ps.add(frozenset(sub))
15 | return ps
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch05/ch05_prime_sieve.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | #### generate a set containing prime numbers from 2 to n ####
4 | def prime_sieve(n):
5 | primes = set(range(2, n+1))
6 | for i in range(2, (n+1+1) // 2):
7 | if i in primes:
8 | m = 2
9 | while i*m <= n:
10 | primes.discard(i*m)
11 | m += 1
12 | return primes
13 |
14 | #### this is not a good algorithm to check prime numbers ####
15 | def is_prime(n):
16 | for i in range(2, n):
17 | if n % i == 0:
18 | return False
19 | return True
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch05/ch05_symbol_table.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | a = 1
4 | b = 2
5 | c = 3
6 |
7 | def foo(x, y):
8 | a = 'aaa'
9 | b = 'bbb'
10 | print(locals())
11 |
12 | print(globals())
13 | print('*' * 10)
14 | foo(80, 91)
15 |
--------------------------------------------------------------------------------
/ch05/ch05ex5.5.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | friends = [
4 | {'first':'Amy', 'last':'Wallace', 'email':'plunk@service.com.ru'},
5 | {'first':'John', 'last':'Dickson', 'email':'john@edu.com.tw'},
6 | {'first':'Amy', 'last':'Obama', 'email':'amy@whitehouse.gov'},
7 | {'first':'Bob', 'last':'Banks', 'email':'bob@service.com.ru'},
8 | {'first':'Amy', 'last':'Southward', 'email':'amys@service.com.ru'},
9 | {'first':'Bob', 'last':'Wilkson', 'email':'bobwilkson@service.com.ru'}]
10 |
11 |
--------------------------------------------------------------------------------
/ch05/ch05ex5.6.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # I Have a Dream
4 | # Martin Luther King, Jr.
5 | # http://www.americanrhetoric.com/speeches/mlkihaveadream.htm
6 | speech = (
7 | """I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
8 |
9 | Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.
10 |
11 | But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
12 |
13 | In a sense we've come to our nation's capital to cash a check. When the architects of our republic wrote the magnificent words of the Constitution and the Declaration of Independence, they were signing a promissory note to which every American was to fall heir. This note was a promise that all men, yes, black men as well as white men, would be guaranteed the "unalienable Rights" of "Life, Liberty and the pursuit of Happiness." It is obvious today that America has defaulted on this promissory note, insofar as her citizens of color are concerned. Instead of honoring this sacred obligation, America has given the Negro people a bad check, a check which has come back marked "insufficient funds."
14 |
15 | But we refuse to believe that the bank of justice is bankrupt. We refuse to believe that there are insufficient funds in the great vaults of opportunity of this nation. And so, we've come to cash this check, a check that will give us upon demand the riches of freedom and the security of justice.
16 | """)
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch05/ch05ex5.7.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # date, name, fruit, number
4 | data = ("""
5 | 2014/05/06, Amy, apple, 50,
6 | 2014/05/06, Bob, banana, 35,
7 | 2014/05/06, Cathy, grape, 40,
8 | 2014/05/07, Amy, apple, 42,
9 | 2014/05/07, Cathy, banana, 30,
10 | 2014/05/07, David, banana, 33,
11 | 2014/05/07, Bob, grape, 44,
12 | 2014/05/08, Amy, apple, 55,
13 | 2014/05/08, Bob, grape, 56,
14 | 2014/05/08, David, banana, 51,
15 | 2014/05/10, David, grape, 25,
16 | 2014/05/10, Cathy, grape, 26,
17 | 2014/05/10, David, banana, 51,
18 | 2014/05/10, Amy, grape, 23,
19 | 2014/05/10, David, apple, 11,
20 | """)
21 |
22 | # fruit : price
23 | prices = {'apple': 30, 'banana': 22, 'grape': 25}
24 |
25 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.1_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | d = {1: 'January', 2: 'February', 3: 'March',
4 | 4: 'April', 5: 'May', 6: 'June',
5 | 7: 'July', 8: 'August', 9: 'September',
6 | 10: 'October', 11: 'November', 12: 'December'}
7 |
8 | print(d[9])
9 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.2_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | stock = {
4 | 'Apple': 655.95, 'IBM': 202.13, 'HP': 45.51, 'Facebook': 12.11,
5 | 'Intel': 40.51, 'Atmel': 10.23, 'Amazon': 305.35, 'Google': 535.81
6 | }
7 |
8 | stock_new0 = {}
9 | for k, v in stock.items():
10 | if v >= 100:
11 | stock_new0[k] = v
12 |
13 | print(stock_new0)
14 |
15 |
16 | stock_new1 = {k: v for k, v in stock.items() if v >= 100}
17 |
18 | print(stock_new1)
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.3_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def caesar_dict(n):
4 | alphabet_lower = 'abcdefghijklmnopqrstuvwxyz'
5 | alphabet_upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
6 |
7 | result = {}
8 | for i, e in enumerate(alphabet_lower):
9 | i = (i + n) % len(alphabet_lower)
10 | result[e] = alphabet_lower[i]
11 |
12 | for i, e in enumerate(alphabet_upper):
13 | i = (i + n) % len(alphabet_upper)
14 | result[e] = alphabet_upper[i]
15 |
16 | return result
17 |
18 |
19 | if __name__ == '__main__':
20 | print(caesar_dict(13))
21 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.5_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | friends = [
4 | {'first':'Amy', 'last':'Wallace', 'email':'plunk@service.com.ru'},
5 | {'first':'John', 'last':'Dickson', 'email':'john@edu.com.tw'},
6 | {'first':'Amy', 'last':'Obama', 'email':'amy@whitehouse.gov'},
7 | {'first':'Bob', 'last':'Banks', 'email':'bob@service.com.ru'},
8 | {'first':'Amy', 'last':'Southward', 'email':'amys@service.com.ru'},
9 | {'first':'Bob', 'last':'Wilkson', 'email':'bobwilkson@service.com.ru'}]
10 |
11 | def key_func(x):
12 | return x['first'] + ' ' + x['last']
13 | friends_sorted = sorted(friends, key=key_func)
14 |
15 | print(friends_sorted)
16 |
17 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.6_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from __future__ import print_function
4 |
5 | # I Have a Dream
6 | # Martin Luther King, Jr.
7 | # http://www.americanrhetoric.com/speeches/mlkihaveadream.htm
8 | speech = (
9 | """I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
10 |
11 | Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.
12 |
13 | But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
14 |
15 | In a sense we've come to our nation's capital to cash a check. When the architects of our republic wrote the magnificent words of the Constitution and the Declaration of Independence, they were signing a promissory note to which every American was to fall heir. This note was a promise that all men, yes, black men as well as white men, would be guaranteed the "unalienable Rights" of "Life, Liberty and the pursuit of Happiness." It is obvious today that America has defaulted on this promissory note, insofar as her citizens of color are concerned. Instead of honoring this sacred obligation, America has given the Negro people a bad check, a check which has come back marked "insufficient funds."
16 |
17 | But we refuse to believe that the bank of justice is bankrupt. We refuse to believe that there are insufficient funds in the great vaults of opportunity of this nation. And so, we've come to cash this check, a check that will give us upon demand the riches of freedom and the security of justice.
18 | """)
19 |
20 | import string
21 | from collections import defaultdict
22 |
23 | d = defaultdict(int)
24 |
25 | for w in speech.split():
26 | w2 = w.strip(string.punctuation + string.whitespace).lower()
27 | d[w2] += 1
28 |
29 | print('Totally there are %d words.' % len(d))
30 |
31 | data = []
32 | for k, v in d.items():
33 | data.append((k, v))
34 |
35 | data_sorted = sorted(data, key=lambda x: x[1])
36 |
37 | print('Top 5 least frequent words: ')
38 | for i in range(5):
39 | print(data_sorted[i])
40 |
41 | data_sorted2 = list(reversed(data_sorted))
42 |
43 | print('Top 5 most frequent words: ')
44 | for i in range(5):
45 | print(data_sorted2[i])
46 |
--------------------------------------------------------------------------------
/ch05ex/ch05ex5.8_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def main(words):
4 | d = {}
5 | for w in words:
6 | ws = ''.join(sorted(w)) ## not use set or hash
7 | if ws not in d:
8 | d[ws] = [w]
9 | else:
10 | d[ws].append(w)
11 | return list(d.values())
12 |
13 | data = ['eat', 'ate', 'done', 'tea',
14 | 'opus', 'soup', 'node', 'quick']
15 | print(main(data))
16 |
17 | # [['eat', 'ate', 'tea'], ['done', 'node'], ['opus', 'soup'], ['quick']]
18 |
19 |
--------------------------------------------------------------------------------
/ch06/ch06_8queen_basic.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def queen(n):
4 | answers = []
5 |
6 | def is_safe(ans, col):
7 | for i, c in enumerate(ans):
8 | if len(ans)-i == abs(c-col):
9 | return False
10 | return True
11 |
12 | def sub(ans, n):
13 | if len(ans) == n:
14 | answers.append(ans)
15 | else:
16 | for col in range(n):
17 | if col not in ans and is_safe(ans, col):
18 | sub(ans + (col,), n)
19 |
20 | sub((), n)
21 | return answers
22 |
--------------------------------------------------------------------------------
/ch06/ch06_8queen_hettingers.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Raymond Hettingers
4 | # http://code.activestate.com/recipes/576647/
5 | from itertools import permutations
6 |
7 | def queen(n):
8 | answers = []
9 | cols = range(n)
10 | for ans in permutations(cols):
11 | if (n ==
12 | len(set([ans[i]+i for i in cols])) ==
13 | len(set([ans[i]-i for i in cols]))):
14 | answers.append(ans)
15 | return answers
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch06/ch06_8queen_hettingers_gf.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Raymond Hettingers
4 | # http://code.activestate.com/recipes/576647/
5 | from itertools import permutations
6 |
7 | def queen_gf(n):
8 | cols = range(n)
9 | for ans in permutations(cols):
10 | if (n == len(set(ans[i]+i for i in cols)) ==
11 | len(set(ans[i]-i for i in cols))):
12 | yield ans
13 |
--------------------------------------------------------------------------------
/ch06/ch06_8queen_howell.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Steve Howell
4 | # http://wiki.python.org/moin/SimplePrograms
5 |
6 | def queen(n):
7 | answers = [()]
8 |
9 | def under_attack(col, ans):
10 | return (col in ans or
11 | any([abs(col - x) == len(ans)-i
12 | for i,x in enumerate(ans)]))
13 |
14 | for row in range(n):
15 | answers = [ans + (col,)
16 | for ans in answers
17 | for col in range(n)
18 | if not under_attack(col, ans)]
19 | return answers
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ch06/ch06_8queen_test.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import ch06_8queen_hettingers as het
4 | import ch06_8queen_howell as how
5 | import ch06_8queen_basic as ba
6 | import ch06_8queen_hettingers_gf as het_gf
7 |
8 | n = 8
9 |
10 | het_answers = het.queen(n)
11 | print(len(het_answers))
12 | print(het_answers)
13 |
14 | how_answers = how.queen(n)
15 | # for answer in answers:
16 | # print(list(enumerate(answer, start=1)))
17 | #print(answer)
18 |
19 | print(len(how_answers))
20 | print(how_answers)
21 |
22 | ba_answers = ba.queen(n)
23 | print(len(ba_answers))
24 | print(ba_answers)
25 |
26 | queen_het_g = het_gf.queen_gf(n)
27 | het_g_answers = [x for x in queen_het_g]
28 |
29 | #if set(iter(het_answers)) == set(iter(how_answers)):
30 | if set(het_answers) == set(how_answers) == set(ba_answers) == set(het_g_answers):
31 | print('yes')
32 | else:
33 | print('no')
34 |
35 |
--------------------------------------------------------------------------------
/ch06/ch06_counter.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # not work
4 | # def counter(n):
5 | # def bar(x):
6 | # n += x
7 | # return n
8 | # return bar
9 |
10 | def counter(n):
11 | def bar(x):
12 | nonlocal n
13 | n += x
14 | return n
15 | return bar
16 |
17 | c0 = counter(0)
18 | c100 = counter(100)
19 | print(c0(1))
20 | print(c100(10))
21 | print(c0(1))
22 | print(c0(3))
23 | print(c100(20))
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ch06/ch06_env.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | def fact(n):
5 | if n <= 1:
6 | return n
7 | else:
8 | return n * fact(n-1)
9 |
10 | print(fact(3))
11 |
12 | def counter(n):
13 | li = [n]
14 | def bar(x):
15 | li[0] += x
16 | return li[0]
17 | return bar
18 |
19 | c0 = counter(0)
20 | c100 = counter(100)
21 | print(c0(1))
22 | print(c100(10))
23 | print(c0(1))
24 | print(c0(3))
25 | print(c100(20))
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ch06/ch06_fact.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact_i(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 | ####
9 | def fact_r(n):
10 | if n == 1 or n == 0:
11 | return 1
12 | else:
13 | return n * fact_r(n-1)
14 |
15 | if __name__ == '__main__':
16 | for n in range(10):
17 | fi = fact_i(n)
18 | fr = fact_r(n)
19 | if fi != fr:
20 | print('error: %d, %d, %d' % (n, fi, fr))
--------------------------------------------------------------------------------
/ch06/ch06_fib.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fib_r(n):
4 | if n == 0 or n == 1:
5 | return n
6 | else:
7 | return fib_r(n-1) + fib_r(n-2)
8 | ####
9 | def fib_i(n):
10 | a, b = 0, 1
11 | for i in range(n):
12 | a, b = b, a+b
13 | return a
14 | ####
15 | memo = {0: 0, 1: 1}
16 | def fib_m(n):
17 | if n not in memo:
18 | memo[n] = fib_m(n-1) + fib_m(n-2)
19 | return memo[n]
20 |
21 | for x in range(20):
22 | fr = fib_r(x)
23 | fi = fib_i(x)
24 | fm = fib_m(x)
25 | if fr != fi or fi != fm:
26 | print('error: fib(%d) %d %d %d' % (x, fr, fi, fm))
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ch06/ch06_fib_gf.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fib_gf():
4 | a, b = 0, 1
5 | while True:
6 | yield a
7 | a, b = b, a+b
8 | fib_g = fib_gf()
9 |
10 | def fib_memo():
11 | memo = {0: 0, 1: 1}
12 | def sub(n):
13 | if n not in memo:
14 | memo[n] = sub(n-1) + sub(n-2)
15 | return memo[n]
16 | return sub
17 | fib_m = fib_memo()
18 |
19 | for x in range(40):
20 | fg = next(fib_g)
21 | fm = fib_m(x)
22 | if fg != fm:
23 | print('error: fib(%d) %d %d' % (x, fg, fm))
24 |
25 |
--------------------------------------------------------------------------------
/ch06/ch06_fib_hf.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fib_i(n):
4 | a, b = 0, 1
5 | for i in range(n):
6 | a, b = b, a+b
7 | return a
8 | ####
9 | def fib_memo():
10 | memo = {0: 0, 1: 1}
11 | def sub(n):
12 | if n not in memo:
13 | memo[n] = sub(n-1) + sub(n-2)
14 | return memo[n]
15 | return sub
16 | fib_m = fib_memo()
17 |
18 | for x in range(30):
19 | fi = fib_i(x)
20 | fm = fib_m(x)
21 | if fi != fm:
22 | print('error: fib(%d) %d %d' % (x, fi, fm))
23 |
24 |
--------------------------------------------------------------------------------
/ch06/ch06_frange.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def frange_g(start, end=None, inc=None):
4 | if end is None:
5 | end = start
6 | start = 0.0
7 | if inc is None:
8 | inc = 0.1
9 | while True:
10 | if inc > 0 and start >= end:
11 | break
12 | elif inc < 0 and start <= end:
13 | break
14 | yield start
15 | start += inc
16 |
17 | for i in frange_g(0, -1, -0.1):
18 | print(i)
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch06/ch06_gcd.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def gcd_i(a, b):
4 | while b:
5 | a, b = b, a%b
6 | return a
7 | ####
8 | def gcd_r(a, b):
9 | if b == 0:
10 | return a
11 | else:
12 | return gcd_r(b, a%b)
13 |
14 | if __name__ == '__main__':
15 | for a in range(1, 100):
16 | for b in range(1, 100):
17 | x = gcd_i(a, b)
18 | y = gcd_r(a, b)
19 | if x != y:
20 | print('error: gcd(%d,%d), %d, %d' % (a, b, x, y))
--------------------------------------------------------------------------------
/ch06/ch06_generator_send.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def gf():
4 | n = 0
5 | while True:
6 | from_send = yield n
7 | n += 1 if from_send is None else from_send
8 |
9 | g = gf()
10 | print(next(g))
11 | print(g.send(3))
12 | print(g.send(5))
13 | print(next(g))
14 | print(g.send(10))
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch06/ch06_hanoi.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def hanoi(n):
4 | steps = []
5 | def sub(n, pfrom, pto, pbuf):
6 | if n == 1:
7 | steps.append((pfrom, pto))
8 | else:
9 | sub(n-1, pfrom, pbuf, pto)
10 | steps.append((pfrom, pto))
11 | sub(n-1, pbuf, pto, pfrom)
12 | sub(n, 'A', 'C', 'B')
13 | return steps
14 |
15 | steps = hanoi(3)
16 | print(steps)
17 |
18 | def simulate_hanoi(n, pfrom, pto, pbuf, steps):
19 | pillars = {pfrom: list(range(n)), pto: [], pbuf: []}
20 | for s in steps:
21 | disk = pillars[s[0]].pop()
22 | pillars[s[1]].append(disk)
23 | print(pillars[pfrom])
24 | print(pillars[pto])
25 | print(pillars[pbuf])
26 | if (pillars[pfrom] == [] and
27 | pillars[pbuf] == [] and
28 | pillars[pto] == list(range(n))):
29 | return True
30 | else:
31 | return False
32 |
33 | print(simulate_hanoi(3, 'A', 'C', 'B', steps))
34 |
--------------------------------------------------------------------------------
/ch06/ch06_hf_sum.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def sum_number(start, end):
4 | result = 0
5 | while start <= end:
6 | result += start
7 | start += 1
8 | return result
9 |
10 | def sum_square(start, end):
11 | result = 0
12 | while start <= end:
13 | result += start**2
14 | start += 1
15 | return result
16 |
17 | # pi/8
18 | def sum_pi(start, end):
19 | result = 0
20 | while start <= end:
21 | result += 1.0 / (start * (start+2))
22 | start += 4
23 | return result
24 |
25 | def sum_hf(item, start, next, end):
26 | result = 0
27 | while start <= end:
28 | result += item(start)
29 | start = next(start)
30 | return result
31 |
32 |
33 | def sum_number_r(start, end):
34 | if start > end:
35 | return 0
36 | else:
37 | return start + sum_number_r(start+1, end)
38 | def sum_square_r(start, end):
39 | if start > end:
40 | return 0
41 | else:
42 | return start**2 + sum_square_r(start+1, end)
43 | def sum_pi_r(start, end):
44 | if start > end:
45 | return 0
46 | else:
47 | return (1.0 / (start * (start+2))) + sum_pi_r(start+4, end)
48 |
49 | def sum_hf_r(item, start, next, end):
50 | if start > end:
51 | return 0
52 | else:
53 | return item(start) + sum_hf_r(item, next(start), next, end)
54 |
55 | if __name__ == '__main__':
56 | tests = [(0, 10), (100, 200), (2000, 2500)]
57 | for t in tests:
58 | fa = sum(range(t[0], t[1]+1))
59 | fb = sum_number(t[0], t[1])
60 | fc = sum_hf(lambda x: x, t[0], lambda i: i+1, t[1])
61 | fd = sum_number_r(t[0], t[1])
62 | fe = sum_hf_r(lambda x: x, t[0], lambda i: i+1, t[1])
63 | if fa == fb == fc == fd == fe:
64 | print('pass')
65 | for t in tests:
66 | fa = sum([x**2 for x in range(t[0], t[1]+1)])
67 | fb = sum_square(t[0], t[1])
68 | fc = sum_hf(lambda x: x**2, t[0], lambda i: i+1, t[1])
69 | fd = sum_square_r(t[0], t[1])
70 | fe = sum_hf_r(lambda x: x**2, t[0], lambda i: i+1, t[1])
71 | if fa == fb == fc == fd == fe:
72 | print('pass')
73 | for end in range(200, 205):
74 | print(sum_pi(1, end) * 8)
75 | print(sum_pi_r(1, end) * 8)
76 | print(sum_hf(lambda x: 1.0 / (x * (x+2)), 1, lambda i: i+4, end) * 8)
77 | print(sum_hf_r(lambda x: 1.0 / (x * (x+2)), 1, lambda i: i+4, end) * 8)
78 | print('---')
79 |
80 |
81 |
--------------------------------------------------------------------------------
/ch06/ch06_int_from.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def int_from(n, inc=1):
4 | while True:
5 | yield n
6 | n += inc
7 |
8 | ix = int_from(1)
9 | iy = int_from(100, -2)
10 |
11 | for i in range(5):
12 | print(next(ix))
13 | print(next(iy))
14 |
15 |
--------------------------------------------------------------------------------
/ch06/ch06_lambda_long.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | li = [30, 41, 52, 63]
4 |
5 | def sum(li):
6 | result = 0
7 | for x in li:
8 | result += x
9 | return result
10 | print(sum(li))
11 |
12 | def sum(li):
13 | if not li:
14 | return 0
15 | else:
16 | return li[0] + sum(li[1:])
17 | print(sum(li))
18 |
19 | (lambda li: [print(x) for x in li])(li)
20 |
21 | print((lambda li:
22 | (lambda f, r, li: f(f, r, li))
23 | (lambda f, r, li: f(f, r+li[0], li[1:]) if li else r, 0, li))
24 | (li))
25 |
26 | print((lambda li:
27 | (lambda f, r, i: f(f, r, i))
28 | (lambda f, r, i: f(f, r+li[i], i+1) if i < len(li) else r, 0, 0))
29 | (li))
30 |
31 |
--------------------------------------------------------------------------------
/ch06/ch06_lambda_sorted.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | li = [('apple', 25), ('orange', 10), ('fig', 12), ('apricot', 20)]
4 |
5 | def by_name(item):
6 | return item[0]
7 | def by_name_len(item):
8 | return len(item[0])
9 | def by_value(item):
10 | return item[1]
11 |
12 | print(sorted(li, key=by_name))
13 | print(sorted(li, key=by_name_len))
14 | print(sorted(li, key=by_value))
15 |
16 | #### ####
17 | #[('apple', 25), ('apricot', 20), ('fig', 12), ('orange', 10)]
18 | #[('fig', 12), ('apple', 25), ('orange', 10), ('apricot', 20)]
19 | #[('orange', 10), ('fig', 12), ('apricot', 20), ('apple', 25)]
20 |
21 | print(sorted(li, key=lambda item: item[0]))
22 | print(sorted(li, key=lambda item: len(item[0])))
23 | print(sorted(li, key=lambda item: item[1]))
24 |
25 |
--------------------------------------------------------------------------------
/ch06/ch06_multipliers.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def make_multipliers():
4 | result = []
5 | for i in range(3):
6 | def m(x):
7 | return i * x
8 | result.append(m)
9 | return result
10 | for m in make_multipliers():
11 | print(m(5))
12 | print('-' * 20)
13 |
14 | def make_multipliers():
15 | result = []
16 | for i in range(3):
17 | m = lambda x: i * x
18 | result.append(m)
19 | return result
20 | for m in make_multipliers():
21 | print(m(5))
22 | print('-' * 20)
23 |
24 | def make_multipliers():
25 | return [lambda x: i*x for i in range(3)]
26 | for m in make_multipliers():
27 | print(m(5))
28 | print('-' * 20)
29 |
30 | def make_multipliers():
31 | result = []
32 | for i in range(3):
33 | m = lambda x, y=i: y * x
34 | result.append(m)
35 | return result
36 | for m in make_multipliers():
37 | print(m(5))
38 | print('-' * 20)
39 |
40 | for m in [lambda x, n=n: n*x for n in range(3)]:
41 | print(m(5))
42 | print('-' * 20)
43 |
--------------------------------------------------------------------------------
/ch06/ch06_mutable_default.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | ALPHA_DEFAULT = 1.0
4 | def color(red, green, blue, alpha=ALPHA_DEFAULT):
5 | # alpha = ...
6 | # ...
7 | print (red, green, blue, alpha)
8 |
9 | def foo(x, y=[]):
10 | y.append(x)
11 | print(y)
12 |
13 | foo(1)
14 | foo(2)
15 | foo(3)
16 |
17 | def foo(x, y=None):
18 | if y is None:
19 | y = []
20 | y.append(x)
21 | print(y)
22 |
23 | foo(1)
24 | foo(2)
25 | foo(3, [90, 91])
--------------------------------------------------------------------------------
/ch06/ch06_perm.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from itertools import permutations
4 | p = permutations
5 |
6 | def perm(iterable, r=None):
7 | items = tuple(iterable)
8 | r = len(items) if r is None else r
9 | answers = []
10 | def sub(items, k, p):
11 | if k == 0:
12 | answers.append(p)
13 | else:
14 | # for i in range(k): # wrong
15 | for i in range(len(items)):
16 | # sub(list_del(items, i), k-1, p+(items[i],))
17 | sub(items[:i] + items[i+1:], k-1, p+(items[i],))
18 | sub(items, r, ())
19 | return answers
20 |
21 | if __name__ == '__main__':
22 | tests = (list(range(3)), ['a','b','c','d'], list(range(100, 106)))
23 | for t in tests:
24 | pa = list(p(t))
25 | pb = perm(t)
26 | if set(pa) == set(pb):
27 | print('yes')
28 | else:
29 | print('no')
30 | for t in tests:
31 | for r in range(1, len(t)):
32 | pa = list(p(t, r))
33 | pb = perm(t, r)
34 | if set(pa) == set(pb):
35 | print('yes')
36 | else:
37 | print('no')
38 |
--------------------------------------------------------------------------------
/ch06/ch06_pi_cesaro.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from math import sqrt
4 | from random import randint
5 |
6 | def estimate_pi(n):
7 | N = 10**100
8 | def gcd(a, b):
9 | while b:
10 | a, b = b, a%b
11 | return a
12 | def montecarlo(n, experiment):
13 | passed = 0
14 | for i in range(n):
15 | if experiment():
16 | passed += 1
17 | return float(passed) / n
18 | def cesaro():
19 | return gcd(randint(1, N), randint(1, N)) == 1
20 | return sqrt(6.0 / montecarlo(n, cesaro))
21 |
22 | if __name__ == '__main__':
23 | for i in range(10, 101, 10):
24 | print(estimate_pi(i))
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ch06/ch06_powerset.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def powerset(s):
4 | li = list(s)
5 | ps = set()
6 | for n in range(0, 2**len(s)):
7 | sub = set()
8 | x = n
9 | for i in range(len(s)):
10 | if x & 0x1:
11 | sub.add(li[i])
12 | x >>= 1
13 | ps.add(frozenset(sub))
14 | return ps
15 | ####
16 |
17 | def powerset_r(iterable):
18 | def set_add(ps, item):
19 | if len(ps) == 0:
20 | return []
21 | else:
22 | return [ps[0] + [item]] + set_add(ps[1:], item)
23 | def sub(s):
24 | if len(s) == 1:
25 | return [s, []]
26 | else:
27 | ps = sub(s[1:])
28 | return ps + set_add(ps, s[0])
29 | return sub(list(iterable))
30 |
31 | test = [1,2,3,4]
32 | print(powerset(test))
33 | print(sorted(powerset_r(test), key=lambda x: len(x)))
34 |
35 |
--------------------------------------------------------------------------------
/ch06/ch06_range.py:
--------------------------------------------------------------------------------
1 |
2 | def range_g(start, end=None, inc=None):
3 | if end is None:
4 | end = start
5 | start = 0
6 | if inc is None:
7 | inc = 1
8 | while True:
9 | if inc > 0 and start >= end:
10 | break
11 | elif inc < 0 and start <= end:
12 | break
13 | yield start
14 | start += inc
15 |
16 | def range2x(start, end=None, inc=None):
17 | if end is None:
18 | end = start
19 | start = 0
20 | if inc is None:
21 | inc = 1
22 | result = []
23 | while True:
24 | if inc > 0 and start >= end:
25 | break
26 | elif inc < 0 and start <= end:
27 | break
28 | result.append(start)
29 | start += inc
30 | return result
31 |
32 | # not work
33 | def range3x(start, end=None, inc=None):
34 | if end is None:
35 | end = start
36 | start = 0
37 | if inc is None:
38 | inc = 1
39 | s = [start]
40 | def sub():
41 | while s[0] < end:
42 | if inc > 0 and s[0] >= end:
43 | break
44 | elif inc < 0 and s[0] <= end:
45 | break
46 | s[0] += inc
47 | return (s[0] - inc)
48 | return sub
49 |
50 | if __name__ == '__main__':
51 | tests = (0, 10, 30, -100, 1, 2)
52 | for a in tests:
53 | x0 = list(range(a))
54 | x1 = range2x(a)
55 | x2 = list(range_g(a))
56 | if x0 != x1 or x0 != x2:
57 | print('error')
58 | tests = ((0, 10), (10, 30), (-100, 20), (1, 2))
59 | for a,b in tests:
60 | x0 = list(range(a, b))
61 | x1 = range2x(a, b)
62 | x2 = list(range_g(a, b))
63 | if x0 != x1 or x0 != x2:
64 | print('error')
65 | tests = ((0, 10, 1), (10, 30, 2), (-10, -20, -1), (0, -31, -3))
66 | for a,b,c in tests:
67 | x0 = list(range(a, b, c))
68 | x1 = range2x(a, b, c)
69 | x2 = list(range_g(a, b, c))
70 | if x0 != x1 or x0 != x2:
71 | print('error %s %s' % (x0, x1))
72 | # xx = range3x(10, -3, -1)
73 | # for i in range(20):
74 | # print(xx())
75 |
76 |
77 |
--------------------------------------------------------------------------------
/ch06/ch06_yield_from.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fg(n):
4 | for i in range(1, n):
5 | yield i
6 | for i in range(-1, -n, -1):
7 | yield i
8 |
9 | print(list(fg(5)))
10 |
11 | def sub_fg(n):
12 | i = 1 if n > 0 else -1
13 | inc = i
14 | while i != n:
15 | yield i
16 | i += inc
17 | def fg(n):
18 | yield from sub_fg(n)
19 | yield from sub_fg(-n)
20 |
21 | print(list(fg(5)))
22 |
23 | def fg(n):
24 | yield from range(1, n)
25 | yield from range(-1, -n, -1)
26 |
27 | print(list(fg(5)))
28 |
--------------------------------------------------------------------------------
/ch06ex/ch06ex6.12_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def coin_sum_r(total, coins):
4 | if len(coins) == 1:
5 | return 1
6 | elif total < coins[-1]:
7 | return coin_sum_r(total, coins[:-1])
8 | else:
9 | return coin_sum_r(total-coins[-1], coins) + coin_sum_r(total, coins[:-1])
10 |
11 | coins_a = (1, 5, 10, 25)
12 | print(coin_sum_r(100, coins_a)) # 242
13 |
14 | coins_england = (1, 2, 5, 10, 20, 50, 100, 200)
15 | print(coin_sum_r(200, coins_england)) # 73682
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ch06ex/ch06ex6.15_answer.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | #
4 | def prime_gf():
5 | primes = [2]
6 | def is_prime(n):
7 | for i in primes:
8 | if n % i == 0:
9 | return False
10 | return True
11 | while True:
12 | p = primes[-1]
13 | yield p
14 | while True:
15 | p += 1
16 | if is_prime(p):
17 | primes.append(p)
18 | break
19 | prime_f = prime_gf()
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ch07/ch07_big5_uao.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from __future__ import print_function
4 | import codecs
5 | # import big5uao
6 | import big5uao_3
7 |
8 | # a煊b喆c凜凛
9 | test = b'a\x95\x4Fb\x95\xEDc\xBB\xFE\x81\x60'
10 |
11 | dec = codecs.getdecoder('big5uao')
12 | enc = codecs.getencoder('big5uao')
13 |
14 | d0, d1 = dec(test)
15 | print(d0, d1)
16 |
17 | test = b'\x95\x4F\x80\x80'
18 | d0, d1 = dec(test, errors='replace')
19 | print(d0, d1)
20 |
21 | # 應是Big5+UAO的 0xa7 0x41 0xa6 0x6e
22 | s = '你好' # 2.x u'你好' 3.x '你好'
23 |
24 | e = enc(s)
25 | for b in e[0]:
26 | print('%x ' % b, end='')
27 | print(e[1])
28 |
29 | s = '\uEEEE\uDDDD'
30 | e = enc(s, errors='strict')
31 | for b in e[0]:
32 | print('%x ' % b, end='')
33 | print(e[1])
34 |
--------------------------------------------------------------------------------
/ch07/ch07_big5_uao_test.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from __future__ import print_function
4 | import codecs
5 | import big5ext
6 | import big5uao
7 |
8 | def getregentry(codec_name):
9 | if codec_name == 'big5ext':
10 | return codecs.CodecInfo(
11 | name='big5ext',
12 | encode=big5ext.Codec().encode,
13 | decode=big5ext.Codec().decode,
14 | incrementalencoder=big5ext.IncrementalEncoder,
15 | incrementaldecoder=big5ext.IncrementalDecoder,
16 | streamreader=big5ext.StreamReader,
17 | streamwriter=big5ext.StreamWriter,
18 | )
19 | elif codec_name == 'big5uao':
20 | return codecs.CodecInfo(
21 | name='big5uao',
22 | encode=big5uao.Codec().encode,
23 | decode=big5uao.Codec().decode,
24 | incrementalencoder=big5uao.IncrementalEncoder,
25 | incrementaldecoder=big5uao.IncrementalDecoder,
26 | streamreader=big5uao.StreamReader,
27 | streamwriter=big5uao.StreamWriter,
28 | )
29 |
30 | codecs.register(getregentry)
31 |
32 | #################
33 | print(codecs.lookup('big5uao'))
34 | print(codecs.lookup('big5ext'))
35 |
36 |
37 | test = b'a\x95\x4Fb\x95\xEDc\xBB\xFE\x81\x60'
38 | print(len(test))
39 | dec1 = codecs.getdecoder('big5ext')
40 | dec2 = codecs.getdecoder('big5uao')
41 |
42 | d1 = dec1(test)
43 | d2 = dec2(test)
44 | print(d1[0], d1[1])
45 | print(d2[0], d2[1])
46 |
47 | for b1 in range(0x81, 0xFE+1):
48 | for b2 in range(0x40, 0x7E+1):
49 | big5 = chr(b1) + chr(b2)
50 | d1 = dec1(big5)
51 | d2 = dec2(big5)
52 | if d1[0] != d2[0]:
53 | print(d1, d2)
54 | for b2 in range(0xA1, 0xFE+1):
55 | big5 = chr(b1) + chr(b2)
56 | d1 = dec1(big5)
57 | d2 = dec2(big5)
58 | if d1[0] != d2[0]:
59 | print(d1, d2)
60 |
61 | ss = u'你好' # a7 41 a6 6e
62 | enc2 = codecs.getencoder('big5uao')
63 | e2 = enc2(ss)
64 | for b in e2[0]:
65 | print('%x ' % ord(b), end='')
66 | print(e2[1])
67 |
68 |
--------------------------------------------------------------------------------
/ch07/ch07_caesar.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from io import open
4 | import string
5 |
6 | # 回傳轉換表,shift是偏移量,可正可負,encrypt代表要加密還是解密
7 | def caesar_table(shift, encrypt=True):
8 | lowers = string.ascii_lowercase # 小寫英文字母
9 | uppers = string.ascii_uppercase # 大寫英文字母
10 | lowers_new = lowers[shift:] + lowers[:shift]
11 | uppers_new = uppers[shift:] + uppers[:shift]
12 | # 若是2.x版,請把str.maketrans改成string.maketrans
13 | # maketrans的功能是製作轉換表,供str.translate使用
14 | if encrypt:
15 | return str.maketrans(lowers+uppers, lowers_new+uppers_new)
16 | else:
17 | return str.maketrans(lowers_new+uppers_new, lowers+uppers)
18 | # 凱撒密碼,shift是偏移量,encrypt代表要加密還是解密
19 | def caesar(file_in, file_out, shift, encrypt=True):
20 | table = caesar_table(shift, encrypt)
21 | with open(file_in, mode='r', encoding='ascii') as fin:
22 | with open(file_out, mode='w', encoding='ascii') as fout:
23 | for line in fin:
24 | # 呼叫translate,傳入轉換表
25 | fout.write(line.translate(table))
26 |
27 | caesar('test.txt', 'encrypt.txt', 3, True)
28 | caesar('encrypt.txt', 'decrypt.txt', 3, False)
29 |
30 |
--------------------------------------------------------------------------------
/ch07/ch07_csv.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | # Python 3.x
4 | import csv
5 |
6 | with open('csv.txt', 'r', encoding='utf-8') as fin:
7 | with open('csv_out.txt', 'w', encoding='utf-8') as fout:
8 | csvreader = csv.reader(fin, delimiter=',')
9 | csvwriter = csv.writer(fout, delimiter=' ')
10 | header = next(csvreader)
11 | csvwriter.writerow(header)
12 | for row in csvreader:
13 | row[0] = row[0].replace('/', '-')
14 | row[-1] += '%'
15 | print(','.join(row))
16 | csvwriter.writerow(row)
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch07/ch07_enc_change.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from io import open
4 |
5 | def enc_change(file_in, enc_in, file_out, enc_out):
6 | with open(file_in, mode='r', encoding=enc_in) as fin:
7 | with open(file_out, mode='w', encoding=enc_out) as fout:
8 | for line in fin:
9 | fout.write(line)
10 |
11 |
12 |
13 | enc_change('test_big5.txt', 'big5', 'test_utf8.txt', 'utf8')
14 |
--------------------------------------------------------------------------------
/ch07/ch07_json.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from __future__ import print_function
4 | from io import open
5 | import json
6 |
7 | with open('json.txt', 'r', encoding='ascii') as fin:
8 | data = json.loads(fin.read())
9 | print(data['menu']['hello'])
10 | print(data['menu']['flag'])
11 | print(data['menu']['count'])
12 | with open('json_out1.txt', 'w', encoding='ascii') as fout:
13 | fout.write(json.dumps(data, separators=(',', ':')))
14 | with open('json_out2.txt', 'w', encoding='ascii') as fout:
15 | fout.write(json.dumps(data, sort_keys=True,
16 | indent=4, separators=(',', ':')))
17 |
18 |
--------------------------------------------------------------------------------
/ch07/ch07_line_count.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from io import open
4 | import os
5 | import os.path
6 |
7 | # 計算文字檔有幾行
8 | def line_count(filepath, enc='utf8'):
9 | count = 0
10 | with open(filepath, mode='r', encoding=enc) as fin:
11 | for line in fin:
12 | if line.strip(): # 空白行不算
13 | count += 1
14 | return count
15 | # 判斷文字編碼系統,從檔案開頭的前幾個位元組
16 | def what_encoding_by_head(filepath):
17 | enc = None
18 | with open(filepath, 'rb') as fin:
19 | data = fin.read(3)
20 | if len(data) == 3: # Windows會在UTF-8檔案開頭加上BOM
21 | if data[0] == 0xEF and data[1] == 0xBB and data[2] == 0xBF:
22 | enc = 'utf8'
23 | if len(data) >= 2: # UTF-16 BE與LE
24 | if data[0] == 0xFE and data[1] == 0xFF:
25 | enc = 'UTF-16BE'
26 | elif data[0] == 0xFF and data[1] == 0xFE:
27 | enc = 'UTF-16LE'
28 | return enc
29 | # 判斷文字編碼系統,從第一行或第二行,若含有'coding'字樣的話
30 | def what_encoding_by_mark(filepath):
31 | enc = 'ascii' # 預設為ASCII
32 | mark = 'coding' # 編碼標記字樣
33 | def extract_enc(line):
34 | chars = ' :=-*' # 編碼標記字樣周圍無用的字元
35 | return line.strip().lstrip(chars).rstrip(chars)
36 | with open(filepath, mode='r', encoding=enc, errors='ignore') as fin:
37 | for i in range(2): # 只讀兩行
38 | line = fin.readline()
39 | idx = line.find(mark) # 若含有編碼標記字樣
40 | if idx != -1:
41 | enc = extract_enc(line[idx+len(mark):])
42 | break
43 | return enc
44 | # 判斷文字編碼系統
45 | def what_encoding(filepath):
46 | return what_encoding_by_head(filepath) or what_encoding_by_mark(filepath)
47 |
48 | lc_total = 0 # 總行數
49 | file_count = 0 # 被計算行數的檔案個數
50 | for p in os.listdir('.'): # 2.x版應使用u'.'
51 | if os.path.isfile(p) and p[-3:] == '.py':
52 | try:
53 | enc = what_encoding(p)
54 | lc = line_count(p, enc)
55 | lc_total += lc
56 | file_count += 1
57 | print(p, enc, lc)
58 | except:
59 | print(p, "can't count lines")
60 |
61 | print('%d .py files totally have %d lines ' % (file_count, lc_total))
62 |
63 |
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/a no.py:
--------------------------------------------------------------------------------
1 | a
2 | b
3 | c
4 |
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/aaa big5.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_line_count_test/aaa big5.py
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/aaa utf16be.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_line_count_test/aaa utf16be.py
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/empty.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_line_count_test/empty.py
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/test ascii.py:
--------------------------------------------------------------------------------
1 |
2 | fin = open('test.txt')
3 | print(fin.readline())
4 | for line in fin:
5 | print(line)
6 | fin.close()
7 |
8 | ####
9 | fin = open('test.txt')
10 | fout = open('testw.txt', 'w')
11 | for line in fin:
12 | print(line)
13 | fout.write(line)
14 | fin.close()
15 | fout.close()
16 |
17 | ####
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch07/ch07_line_count_test/wrong utf8.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_line_count_test/wrong utf8.py
--------------------------------------------------------------------------------
/ch07/ch07_line_number.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from io import open
4 |
5 | # 計算文字檔有幾行
6 | def line_count(filepath, enc='utf8'):
7 | count = 0
8 | with open(filepath, mode='r', encoding=enc) as fin:
9 | for line in fin:
10 | count += 1
11 | return count
12 |
13 | # 計算文字檔有幾行,另一種作法
14 | def line_count_2(filepath, enc='utf8'):
15 | return sum(1 for line in open(filepath, mode='r', encoding=enc))
16 |
17 | # 為文字檔加上行號,參數:輸入檔路徑、輸出檔路徑、編碼
18 | def line_number(fin_path, fout_path, enc='utf8'):
19 | lc = line_count(fin_path) # 知道行數才能對齊
20 | lcw = len(str(lc)) # 該佔幾格
21 | with open(fin_path, mode='r', encoding=enc) as fin:
22 | with open(fout_path, mode='w', encoding=enc) as fout:
23 | for i, line in enumerate(fin):
24 | fout.write(u'{:0{width}d} {}'.format(i+1, line, width=lcw))
25 |
26 |
--------------------------------------------------------------------------------
/ch07/ch07_pickle.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 |
4 | from __future__ import print_function
5 | from io import open
6 | import pickle
7 |
8 | data = {'a': [1, 2, 3, 4],
9 | 'John': 'abcdef',
10 | 334455: 778899,
11 | 'default': None}
12 |
13 | with open('pickle.bin', 'wb') as fout:
14 | pickle.dump(data, fout, 0)
15 |
16 | with open('pickle.bin', 'rb') as fin:
17 | d = pickle.load(fin)
18 | print(d['John'])
19 | print(d[334455])
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch07/ch07_print_self.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | with open('ch07_print_self.py') as fin:
4 | for line in fin:
5 | print(line)
6 |
--------------------------------------------------------------------------------
/ch07/ch07_print_self_big5.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_print_self_big5.py
--------------------------------------------------------------------------------
/ch07/ch07_print_self_utf8.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | # 你好
4 | from __future__ import print_function
5 | from io import open
6 |
7 | print('你好Python')
8 | with open('ch07_print_self_utf8.py', encoding='utf8') as fin:
9 | for line in fin:
10 | print(line, end='')
11 | print('再見Python')
12 |
--------------------------------------------------------------------------------
/ch07/ch07_redirect.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from __future__ import print_function
4 | from io import open
5 | import sys
6 |
7 | with open('test.txt', 'w', encoding='utf-8') as fout:
8 | stdout_backup = sys.stdout
9 | sys.stdout = fout
10 | print(u'Hello Python')
11 | sys.stdout = stdout_backup
12 |
13 |
--------------------------------------------------------------------------------
/ch07/ch07_redirect_stdin.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07_redirect_stdin.py
--------------------------------------------------------------------------------
/ch07/ch07_struct.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | typedef struct {
4 | char a;
5 | unsigned long b;
6 | int c;
7 | float d;
8 | char e;
9 | double f;
10 | } Data;
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | Data d = {'a', 0x12AB34CD, 100, 3.4, 'b', 5.6};
15 | FILE *fp = fopen("test.bin", "wb");
16 | fwrite(&d, 1, sizeof(Data), fp);
17 | fclose(fp);
18 | return 0;
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/ch07/ch07_struct.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 |
4 | from __future__ import print_function
5 | from io import open
6 | import struct
7 |
8 | with open ('test.bin', 'rb') as fin:
9 | a = struct.unpack('
2 |
3 | typedef struct {
4 | char a;
5 | unsigned long c;
6 | int b;
7 | float d;
8 | char e;
9 | double f;
10 | } Data;
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | printf("sizeof(char) = %d\n", sizeof(char));
15 | printf("sizeof(int) = %d\n", sizeof(int));
16 | printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
17 | printf("sizeof(float) = %d\n", sizeof(float));
18 | printf("sizeof(double) = %d\n", sizeof(double));
19 | printf("sizeof(Data) = %d\n", sizeof(Data));
20 | return 0;
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/ch07/ch07_test.py:
--------------------------------------------------------------------------------
1 |
2 | fin = open('test.txt')
3 | print(fin.readline())
4 | for line in fin:
5 | print(line)
6 | fin.close()
7 |
8 | ####
9 | fin = open('test.txt')
10 | fout = open('testw.txt', 'w')
11 | for line in fin:
12 | print(line)
13 | fout.write(line)
14 | fin.close()
15 | fout.close()
16 |
17 | ####
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch07/ch07_test_context.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from __future__ import print_function
4 | from io import open
5 |
6 | with open('test.txt') as fin:
7 | for line in fin:
8 | print(line, end='')
9 |
10 | ####
11 | with open('test.txt', 'r') as fin:
12 | with open('testw.txt', 'w') as fout:
13 | for line in fin:
14 | print(line, end='')
15 | fout.write(line)
16 |
17 | ####
18 | with open('test.txt', 'r') as fin, open('testw.txt', 'w') as fout:
19 | for line in fin:
20 | print(line, end='')
21 | fout.write(line)
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ch07/ch07ex7.1_answer.txt:
--------------------------------------------------------------------------------
1 | ch07ex7.1_testdata_0.txt,UTF-8
2 | ch07ex7.1_testdata_1.txt,ISO-8859-15
3 | ch07ex7.1_testdata_2.txt,Windows-1252
4 |
5 |
--------------------------------------------------------------------------------
/ch07/ch07ex7.1_testdata_0.txt:
--------------------------------------------------------------------------------
1 | The symbol € is a euro sign.
2 |
--------------------------------------------------------------------------------
/ch07/ch07ex7.1_testdata_1.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.1_testdata_1.txt
--------------------------------------------------------------------------------
/ch07/ch07ex7.1_testdata_2.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.1_testdata_2.txt
--------------------------------------------------------------------------------
/ch07/ch07ex7.2_answer.txt:
--------------------------------------------------------------------------------
1 | ch07ex7.2_testdata_0.txt,UTF-8
2 | ch07ex7.2_testdata_1.txt,Big5+UAO
3 | ch07ex7.2_testdata_2.txt,GBK
4 |
5 |
--------------------------------------------------------------------------------
/ch07/ch07ex7.2_testdata_0.txt:
--------------------------------------------------------------------------------
1 | 你好PYTHON榮荣栄
2 |
--------------------------------------------------------------------------------
/ch07/ch07ex7.2_testdata_1.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.2_testdata_1.txt
--------------------------------------------------------------------------------
/ch07/ch07ex7.2_testdata_2.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.2_testdata_2.txt
--------------------------------------------------------------------------------
/ch07/ch07ex7.3_testdata.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.3_testdata.txt
--------------------------------------------------------------------------------
/ch07/ch07ex7.4.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/ch07ex7.4.py
--------------------------------------------------------------------------------
/ch07/ch07ex7.5_testdata.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | 煊堃喆凜凛遙遥阪坂齊斉齐齋斎榮荣栄富冨樫堅島嶋崎﨑邊边辺絕绝對对対涉澀渋瑠鹽塩盐汙污汚櫻樱桜鐮镰鎌高髙癡痴劍剑剣龍龙竜氣气気單单単
4 |
5 |
--------------------------------------------------------------------------------
/ch07/csv.txt:
--------------------------------------------------------------------------------
1 | date,time,temperature,humidity
2 | 2014/01/01,08:00,15.3,30
3 | 2014/01/02,11:00,23.5,40
4 | 2014/01/03,14:00,25.5,36
5 | 2014/01/04,15:00,22.1,33
6 |
--------------------------------------------------------------------------------
/ch07/csv_out.txt:
--------------------------------------------------------------------------------
1 | date time temperature humidity
2 | 2014-01-01 08:00 15.3 30%
3 | 2014-01-02 11:00 23.5 40%
4 | 2014-01-03 14:00 25.5 36%
5 | 2014-01-04 15:00 22.1 33%
6 |
--------------------------------------------------------------------------------
/ch07/i_have_a_dream.txt:
--------------------------------------------------------------------------------
1 | # I Have a Dream
2 | # Martin Luther King, Jr.
3 | # http://www.americanrhetoric.com/speeches/mlkihaveadream.htm
4 |
5 | I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
6 |
7 | Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.
8 |
9 | But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
10 |
11 | In a sense we've come to our nation's capital to cash a check. When the architects of our republic wrote the magnificent words of the Constitution and the Declaration of Independence, they were signing a promissory note to which every American was to fall heir. This note was a promise that all men, yes, black men as well as white men, would be guaranteed the "unalienable Rights" of "Life, Liberty and the pursuit of Happiness." It is obvious today that America has defaulted on this promissory note, insofar as her citizens of color are concerned. Instead of honoring this sacred obligation, America has given the Negro people a bad check, a check which has come back marked "insufficient funds."
12 |
13 | But we refuse to believe that the bank of justice is bankrupt. We refuse to believe that there are insufficient funds in the great vaults of opportunity of this nation. And so, we've come to cash this check, a check that will give us upon demand the riches of freedom and the security of justice.
14 |
15 | We have also come to this hallowed spot to remind America of the fierce urgency of Now. This is no time to engage in the luxury of cooling off or to take the tranquilizing drug of gradualism. Now is the time to make real the promises of democracy. Now is the time to rise from the dark and desolate valley of segregation to the sunlit path of racial justice. Now is the time to lift our nation from the quicksands of racial injustice to the solid rock of brotherhood. Now is the time to make justice a reality for all of God's children.
16 |
17 | It would be fatal for the nation to overlook the urgency of the moment. This sweltering summer of the Negro's legitimate discontent will not pass until there is an invigorating autumn of freedom and equality. Nineteen sixty-three is not an end, but a beginning. And those who hope that the Negro needed to blow off steam and will now be content will have a rude awakening if the nation returns to business as usual. And there will be neither rest nor tranquility in America until the Negro is granted his citizenship rights. The whirlwinds of revolt will continue to shake the foundations of our nation until the bright day of justice emerges.
18 |
19 | But there is something that I must say to my people, who stand on the warm threshold which leads into the palace of justice: In the process of gaining our rightful place, we must not be guilty of wrongful deeds. Let us not seek to satisfy our thirst for freedom by drinking from the cup of bitterness and hatred. We must forever conduct our struggle on the high plane of dignity and discipline. We must not allow our creative protest to degenerate into physical violence. Again and again, we must rise to the majestic heights of meeting physical force with soul force.
20 |
21 | The marvelous new militancy which has engulfed the Negro community must not lead us to a distrust of all white people, for many of our white brothers, as evidenced by their presence here today, have come to realize that their destiny is tied up with our destiny. And they have come to realize that their freedom is inextricably bound to our freedom.
22 |
23 | We cannot walk alone.
24 |
25 | And as we walk, we must make the pledge that we shall always march ahead.
26 |
27 | We cannot turn back.
28 |
29 | There are those who are asking the devotees of civil rights, "When will you be satisfied?" We can never be satisfied as long as the Negro is the victim of the unspeakable horrors of police brutality. We can never be satisfied as long as our bodies, heavy with the fatigue of travel, cannot gain lodging in the motels of the highways and the hotels of the cities. We cannot be satisfied as long as the negro's basic mobility is from a smaller ghetto to a larger one. We can never be satisfied as long as our children are stripped of their self-hood and robbed of their dignity by signs stating: "For Whites Only." We cannot be satisfied as long as a Negro in Mississippi cannot vote and a Negro in New York believes he has nothing for which to vote. No, no, we are not satisfied, and we will not be satisfied until "justice rolls down like waters, and righteousness like a mighty stream."
30 |
31 | I am not unmindful that some of you have come here out of great trials and tribulations. Some of you have come fresh from narrow jail cells. And some of you have come from areas where your quest -- quest for freedom left you battered by the storms of persecution and staggered by the winds of police brutality. You have been the veterans of creative suffering. Continue to work with the faith that unearned suffering is redemptive. Go back to Mississippi, go back to Alabama, go back to South Carolina, go back to Georgia, go back to Louisiana, go back to the slums and ghettos of our northern cities, knowing that somehow this situation can and will be changed.
32 |
33 | Let us not wallow in the valley of despair, I say to you today, my friends.
34 |
35 | And so even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream.
36 |
37 | I have a dream that one day this nation will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident, that all men are created equal."
38 |
39 | I have a dream that one day on the red hills of Georgia, the sons of former slaves and the sons of former slave owners will be able to sit down together at the table of brotherhood.
40 |
41 | I have a dream that one day even the state of Mississippi, a state sweltering with the heat of injustice, sweltering with the heat of oppression, will be transformed into an oasis of freedom and justice.
42 |
43 | I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.
44 |
45 | I have a dream today!
46 |
47 | I have a dream that one day, down in Alabama, with its vicious racists, with its governor having his lips dripping with the words of "interposition" and "nullification" -- one day right there in Alabama little black boys and black girls will be able to join hands with little white boys and white girls as sisters and brothers.
48 |
49 | I have a dream today!
50 |
51 | I have a dream that one day every valley shall be exalted, and every hill and mountain shall be made low, the rough places will be made plain, and the crooked places will be made straight; "and the glory of the Lord shall be revealed and all flesh shall see it together."
52 |
53 | This is our hope, and this is the faith that I go back to the South with.
54 |
55 | With this faith, we will be able to hew out of the mountain of despair a stone of hope. With this faith, we will be able to transform the jangling discords of our nation into a beautiful symphony of brotherhood. With this faith, we will be able to work together, to pray together, to struggle together, to go to jail together, to stand up for freedom together, knowing that we will be free one day.
56 |
57 | And this will be the day -- this will be the day when all of God's children will be able to sing with new meaning:
58 |
59 | My country 'tis of thee, sweet land of liberty, of thee I sing.
60 |
61 | Land where my fathers died, land of the Pilgrim's pride,
62 |
63 | From every mountainside, let freedom ring!
64 |
65 | And if America is to be a great nation, this must become true.
66 |
67 | And so let freedom ring from the prodigious hilltops of New Hampshire.
68 |
69 | Let freedom ring from the mighty mountains of New York.
70 |
71 | Let freedom ring from the heightening Alleghenies of Pennsylvania.
72 |
73 | Let freedom ring from the snow-capped Rockies of Colorado.
74 |
75 | Let freedom ring from the curvaceous slopes of California.
76 |
77 | But not only that:
78 |
79 | Let freedom ring from Stone Mountain of Georgia.
80 |
81 | Let freedom ring from Lookout Mountain of Tennessee.
82 |
83 | Let freedom ring from every hill and molehill of Mississippi.
84 |
85 | From every mountainside, let freedom ring.
86 |
87 | And when this happens, and when we allow freedom ring, when we let it ring from every village and every hamlet, from every state and every city, we will be able to speed up that day when all of God's children, black men and white men, Jews and Gentiles, Protestants and Catholics, will be able to join hands and sing in the words of the old Negro spiritual:
88 |
89 | Free at last! Free at last!
90 |
91 | Thank God Almighty, we are free at last!
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/ch07/json.txt:
--------------------------------------------------------------------------------
1 | {"menu": {
2 | "hello": "hi",
3 | "flag": true,
4 | "count": 123,
5 | "id": "icjowiieh",
6 | "value": "File",
7 | "popup": {
8 | "menuitem": [
9 | {"value": "New", "onclick": "CreateNewDoc()"},
10 | {"value": "Open", "onclick": "OpenDoc()"},
11 | {"value": "Close", "onclick": "CloseDoc()"}
12 | ]
13 | }
14 | }}
15 |
--------------------------------------------------------------------------------
/ch07/json_out1.txt:
--------------------------------------------------------------------------------
1 | {"menu":{"count":123,"popup":{"menuitem":[{"onclick":"CreateNewDoc()","value":"New"},{"onclick":"OpenDoc()","value":"Open"},{"onclick":"CloseDoc()","value":"Close"}]},"value":"File","id":"icjowiieh","flag":true,"hello":"hi"}}
--------------------------------------------------------------------------------
/ch07/json_out2.txt:
--------------------------------------------------------------------------------
1 | {
2 | "menu":{
3 | "count":123,
4 | "flag":true,
5 | "hello":"hi",
6 | "id":"icjowiieh",
7 | "popup":{
8 | "menuitem":[
9 | {
10 | "onclick":"CreateNewDoc()",
11 | "value":"New"
12 | },
13 | {
14 | "onclick":"OpenDoc()",
15 | "value":"Open"
16 | },
17 | {
18 | "onclick":"CloseDoc()",
19 | "value":"Close"
20 | }
21 | ]
22 | },
23 | "value":"File"
24 | }
25 | }
--------------------------------------------------------------------------------
/ch07/pickle.bin:
--------------------------------------------------------------------------------
1 | (dp0
2 | S'a'
3 | p1
4 | (lp2
5 | I1
6 | aI2
7 | aI3
8 | aI4
9 | asS'default'
10 | p3
11 | NsS'John'
12 | p4
13 | S'abcdef'
14 | p5
15 | sI334455
16 | I778899
17 | s.
--------------------------------------------------------------------------------
/ch07/stdin_test.txt:
--------------------------------------------------------------------------------
1 | Amy
2 | John
3 | David
4 |
--------------------------------------------------------------------------------
/ch07/test.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/test.bin
--------------------------------------------------------------------------------
/ch07/test.txt:
--------------------------------------------------------------------------------
1 | Hello Python!
2 | How are you?
3 | abc 123
4 |
--------------------------------------------------------------------------------
/ch07/test_big5.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch07/test_big5.txt
--------------------------------------------------------------------------------
/ch07/test_utf8.txt:
--------------------------------------------------------------------------------
1 | 你好嗎?
2 | 我很好。
3 | 學習Python
4 | 床前明月光
5 |
--------------------------------------------------------------------------------
/ch08/ch08_counter.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from __future__ import print_function
4 | from collections import Counter
5 | from io import open
6 |
7 | with open('i_have_a_dream.txt', 'r', encoding='ascii') as fin:
8 | c = Counter()
9 | for line in fin:
10 | if line[0] == '#':
11 | continue
12 | c.update(line.split())
13 | print(sorted(c.items(), key=lambda x: x[1]))
14 |
15 |
--------------------------------------------------------------------------------
/ch08/ch08_namedtuple_csv.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from __future__ import print_function
4 | from io import open
5 | from collections import namedtuple
6 | import csv
7 |
8 | with open('csv.txt', 'r', encoding='ascii') as fin:
9 | csvreader = csv.reader(fin, delimiter=',')
10 | header = next(csvreader)
11 | Data = namedtuple('Header', ','.join(header))
12 | for row in csvreader:
13 | d = Data._make(row)
14 | print(d.name, d.eng, d.history, d.math)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ch08/ch08ex8.5_testdata.bin:
--------------------------------------------------------------------------------
1 | hello python. abc 123. bye bye.
--------------------------------------------------------------------------------
/ch08/ch08ex8.6_testdata.ini:
--------------------------------------------------------------------------------
1 |
2 | [user]
3 | name=(none)
4 | organization=Python User Group
5 |
6 | [database]
7 | server=192.168.1.1
8 | port=143
9 | file="no.dat"
10 |
11 |
--------------------------------------------------------------------------------
/ch08/ch08ex8.6_testdata2.ini:
--------------------------------------------------------------------------------
1 |
2 | [user]
3 | name=john
4 | organization=Python User Group
5 |
6 | [database]
7 | server=192.0.2.62
8 | port=143
9 | file="somefile.dat"
10 |
11 |
--------------------------------------------------------------------------------
/ch08/ch08ex8.7_testdata.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | username
6 | john
7 | ip
8 | 192.168.1.1
9 | port
10 | 143
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ch08/ch08ex8.7_testdata2.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | username
6 | sys
7 | ip
8 | 192.0.0.1
9 | port
10 | 255
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ch08/csv.txt:
--------------------------------------------------------------------------------
1 | name,eng,history,math
2 | John,67,85,43
3 | Amy,32,89,91
4 | David,90,76,55
5 |
--------------------------------------------------------------------------------
/ch08/csv_out.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch08/csv_out.txt
--------------------------------------------------------------------------------
/ch08/i_have_a_dream.txt:
--------------------------------------------------------------------------------
1 | # I Have a Dream
2 | # Martin Luther King, Jr.
3 | # http://www.americanrhetoric.com/speeches/mlkihaveadream.htm
4 |
5 | I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
6 |
7 | Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.
8 |
9 | But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
10 |
11 | In a sense we've come to our nation's capital to cash a check. When the architects of our republic wrote the magnificent words of the Constitution and the Declaration of Independence, they were signing a promissory note to which every American was to fall heir. This note was a promise that all men, yes, black men as well as white men, would be guaranteed the "unalienable Rights" of "Life, Liberty and the pursuit of Happiness." It is obvious today that America has defaulted on this promissory note, insofar as her citizens of color are concerned. Instead of honoring this sacred obligation, America has given the Negro people a bad check, a check which has come back marked "insufficient funds."
12 |
13 | But we refuse to believe that the bank of justice is bankrupt. We refuse to believe that there are insufficient funds in the great vaults of opportunity of this nation. And so, we've come to cash this check, a check that will give us upon demand the riches of freedom and the security of justice.
14 |
15 | We have also come to this hallowed spot to remind America of the fierce urgency of Now. This is no time to engage in the luxury of cooling off or to take the tranquilizing drug of gradualism. Now is the time to make real the promises of democracy. Now is the time to rise from the dark and desolate valley of segregation to the sunlit path of racial justice. Now is the time to lift our nation from the quicksands of racial injustice to the solid rock of brotherhood. Now is the time to make justice a reality for all of God's children.
16 |
17 | It would be fatal for the nation to overlook the urgency of the moment. This sweltering summer of the Negro's legitimate discontent will not pass until there is an invigorating autumn of freedom and equality. Nineteen sixty-three is not an end, but a beginning. And those who hope that the Negro needed to blow off steam and will now be content will have a rude awakening if the nation returns to business as usual. And there will be neither rest nor tranquility in America until the Negro is granted his citizenship rights. The whirlwinds of revolt will continue to shake the foundations of our nation until the bright day of justice emerges.
18 |
19 | But there is something that I must say to my people, who stand on the warm threshold which leads into the palace of justice: In the process of gaining our rightful place, we must not be guilty of wrongful deeds. Let us not seek to satisfy our thirst for freedom by drinking from the cup of bitterness and hatred. We must forever conduct our struggle on the high plane of dignity and discipline. We must not allow our creative protest to degenerate into physical violence. Again and again, we must rise to the majestic heights of meeting physical force with soul force.
20 |
21 | The marvelous new militancy which has engulfed the Negro community must not lead us to a distrust of all white people, for many of our white brothers, as evidenced by their presence here today, have come to realize that their destiny is tied up with our destiny. And they have come to realize that their freedom is inextricably bound to our freedom.
22 |
23 | We cannot walk alone.
24 |
25 | And as we walk, we must make the pledge that we shall always march ahead.
26 |
27 | We cannot turn back.
28 |
29 | There are those who are asking the devotees of civil rights, "When will you be satisfied?" We can never be satisfied as long as the Negro is the victim of the unspeakable horrors of police brutality. We can never be satisfied as long as our bodies, heavy with the fatigue of travel, cannot gain lodging in the motels of the highways and the hotels of the cities. We cannot be satisfied as long as the negro's basic mobility is from a smaller ghetto to a larger one. We can never be satisfied as long as our children are stripped of their self-hood and robbed of their dignity by signs stating: "For Whites Only." We cannot be satisfied as long as a Negro in Mississippi cannot vote and a Negro in New York believes he has nothing for which to vote. No, no, we are not satisfied, and we will not be satisfied until "justice rolls down like waters, and righteousness like a mighty stream."
30 |
31 | I am not unmindful that some of you have come here out of great trials and tribulations. Some of you have come fresh from narrow jail cells. And some of you have come from areas where your quest -- quest for freedom left you battered by the storms of persecution and staggered by the winds of police brutality. You have been the veterans of creative suffering. Continue to work with the faith that unearned suffering is redemptive. Go back to Mississippi, go back to Alabama, go back to South Carolina, go back to Georgia, go back to Louisiana, go back to the slums and ghettos of our northern cities, knowing that somehow this situation can and will be changed.
32 |
33 | Let us not wallow in the valley of despair, I say to you today, my friends.
34 |
35 | And so even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream.
36 |
37 | I have a dream that one day this nation will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident, that all men are created equal."
38 |
39 | I have a dream that one day on the red hills of Georgia, the sons of former slaves and the sons of former slave owners will be able to sit down together at the table of brotherhood.
40 |
41 | I have a dream that one day even the state of Mississippi, a state sweltering with the heat of injustice, sweltering with the heat of oppression, will be transformed into an oasis of freedom and justice.
42 |
43 | I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.
44 |
45 | I have a dream today!
46 |
47 | I have a dream that one day, down in Alabama, with its vicious racists, with its governor having his lips dripping with the words of "interposition" and "nullification" -- one day right there in Alabama little black boys and black girls will be able to join hands with little white boys and white girls as sisters and brothers.
48 |
49 | I have a dream today!
50 |
51 | I have a dream that one day every valley shall be exalted, and every hill and mountain shall be made low, the rough places will be made plain, and the crooked places will be made straight; "and the glory of the Lord shall be revealed and all flesh shall see it together."
52 |
53 | This is our hope, and this is the faith that I go back to the South with.
54 |
55 | With this faith, we will be able to hew out of the mountain of despair a stone of hope. With this faith, we will be able to transform the jangling discords of our nation into a beautiful symphony of brotherhood. With this faith, we will be able to work together, to pray together, to struggle together, to go to jail together, to stand up for freedom together, knowing that we will be free one day.
56 |
57 | And this will be the day -- this will be the day when all of God's children will be able to sing with new meaning:
58 |
59 | My country 'tis of thee, sweet land of liberty, of thee I sing.
60 |
61 | Land where my fathers died, land of the Pilgrim's pride,
62 |
63 | From every mountainside, let freedom ring!
64 |
65 | And if America is to be a great nation, this must become true.
66 |
67 | And so let freedom ring from the prodigious hilltops of New Hampshire.
68 |
69 | Let freedom ring from the mighty mountains of New York.
70 |
71 | Let freedom ring from the heightening Alleghenies of Pennsylvania.
72 |
73 | Let freedom ring from the snow-capped Rockies of Colorado.
74 |
75 | Let freedom ring from the curvaceous slopes of California.
76 |
77 | But not only that:
78 |
79 | Let freedom ring from Stone Mountain of Georgia.
80 |
81 | Let freedom ring from Lookout Mountain of Tennessee.
82 |
83 | Let freedom ring from every hill and molehill of Mississippi.
84 |
85 | From every mountainside, let freedom ring.
86 |
87 | And when this happens, and when we allow freedom ring, when we let it ring from every village and every hamlet, from every state and every city, we will be able to speed up that day when all of God's children, black men and white men, Jews and Gentiles, Protestants and Catholics, will be able to join hands and sing in the words of the old Negro spiritual:
88 |
89 | Free at last! Free at last!
90 |
91 | Thank God Almighty, we are free at last!
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/ch09/ch09_coin_sum.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Problem 31: Coin sums
4 | # https://projecteuler.net/problem=31
5 |
6 | # dynamic programming
7 | def coin_sum(total, coins):
8 | ways = [1] + ([0] * total)
9 | for coin in coins:
10 | for i in range(coin, total+1):
11 | ways[i] += ways[i - coin]
12 | return ways[total]
13 |
14 | def coin_sum_r(total, coins):
15 | if len(coins) == 1:
16 | return 1
17 | elif total < coins[-1]:
18 | return coin_sum_r(total, coins[:-1])
19 | else:
20 | return (coin_sum_r(total-coins[-1], coins) +
21 | coin_sum_r(total, coins[:-1]))
22 |
23 | # coins_a = (1, 5, 10, 25)
24 | # print(coin_sum(100, coins_a)) # 242
25 |
26 | # coins_b = (1, 5, 10, 25, 50, 100)
27 | # print(coin_sum(100000, coins_b)) # 13398445413854501
28 |
29 | coins_england = (1, 2, 5, 10, 20, 50, 100, 200)
30 | # print(coin_sum(100, coins_england)) # 73682
31 | # print(coin_sum(600, coins_england)) # 73682
32 | # print(coin_sum_r(600, coins_england)) # 73682
33 |
34 | coins_x = (1, 2)
35 | for i in range(1, 12+1):
36 | print(coin_sum(i, coins_x))
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ch09/ch09_ctof_side_effetcs.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | temps = [0, 100, 30.2, 22.5, -15.8, 23.7, -22.5]
4 |
5 | def ctof():
6 | for i in range(len(temps)):
7 | temps[i] = temps[i] * 9.0 / 5.0 + 32
8 |
9 | print(temps)
10 | ctof()
11 | print(temps)
12 |
13 | ####
14 |
15 | def ctof(temps):
16 | result = []
17 | for i in range(len(temps)):
18 | result.append(temps[i] * 9.0 / 5.0 + 32)
19 | return result
20 |
21 | temps = [0, 100, 30.2, 22.5, -15.8, 23.7, -22.5]
22 | print(ctof(temps))
23 | print(ctof(temps))
24 |
25 | ####
26 |
27 | def ctof(temps):
28 | if temps == []:
29 | return []
30 | else:
31 | return [temps[0] * 9.0 / 5.0 + 32] + ctof(temps[1:])
32 |
33 | temps = [0, 100, 30.2, 22.5, -15.8, 23.7, -22.5]
34 | print(ctof(temps))
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_memo.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def dec_memo(func):
4 | cache = func.cache = {}
5 | def wrapper(*args, **kwargs):
6 | key = str(args) + str(kwargs)
7 | if key not in cache:
8 | cache[key] = func(*args, **kwargs)
9 | return cache[key]
10 | return wrapper
11 |
12 | @dec_memo
13 | def fib_r(n):
14 | if n == 0 or n == 1:
15 | return n
16 | else:
17 | return fib_r(n-1) + fib_r(n-2)
18 |
19 | def fib_r2(n):
20 | if n == 0 or n == 1:
21 | return n
22 | else:
23 | return fib_r2(n-1) + fib_r2(n-2)
24 |
25 | def dec_time(func):
26 | def wrapper(*args, **kwargs):
27 | import time
28 | t_start = time.clock()
29 | res = func(*args, **kwargs)
30 | t_end = time.clock()
31 | print(func.__name__, t_end-t_start)
32 | return res
33 | return wrapper
34 | @dec_time
35 | def foo1():
36 | for i in range(6000):
37 | fib_r(i)
38 | @dec_time
39 | def foo2():
40 | for i in range(33):
41 | fib_r2(i)
42 |
43 | foo1()
44 | foo2()
45 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_memo_limit.py:
--------------------------------------------------------------------------------
1 |
2 | import pickle
3 | def dec_memo_limit(func, limit=None):
4 | if isinstance(func, int):
5 | def wrapper(f):
6 | return dec_memo_limit(f, func)
7 | return wrapper
8 |
9 | d = {}
10 | li = []
11 | def wrapper(*args, **kwargs):
12 | key = pickle.dumps((args, kwargs))
13 | try:
14 | li.append(li.pop(li.index(key)))
15 | except ValueError:
16 | d[key] = func(*args, **kwargs)
17 | li.append(key)
18 | if limit is not None and len(li) > limit:
19 | del d[li.pop(0)]
20 | return d[key]
21 |
22 | wrapper._memoize_dict = d
23 | wrapper._memoize_list = li
24 | wrapper._memoize_limit = limit
25 | wrapper._memoize_origfunc = func
26 | wrapper.__name__ = func.__name__
27 | return wrapper
28 |
29 | @dec_memo_limit(200)
30 | def fib_r(n):
31 | if n == 0 or n == 1:
32 | return n
33 | else:
34 | return fib_r(n-1) + fib_r(n-2)
35 | print(fib_r._memoize_limit)
36 |
37 | @dec_memo_limit(100)
38 | def fib_r2(n):
39 | if n == 0 or n == 1:
40 | return n
41 | else:
42 | return fib_r2(n-1) + fib_r2(n-2)
43 | print(fib_r2._memoize_limit)
44 |
45 | def dec_time(func):
46 | def wrapper(*args, **kwargs):
47 | import time
48 | t_start = time.clock()
49 | res = func(*args, **kwargs)
50 | t_end = time.clock()
51 | print(func.__name__, t_end-t_start)
52 | return res
53 | return wrapper
54 | @dec_time
55 | def foo1():
56 | for i in range(1000):
57 | fib_r(i)
58 | @dec_time
59 | def foo2():
60 | for i in range(1000):
61 | fib_r2(i)
62 |
63 | foo1()
64 | foo2()
65 |
66 | import functools
67 | @functools.lru_cache(maxsize=100)
68 | def fib_r3(n):
69 | if n == 0 or n == 1:
70 | return n
71 | else:
72 | return fib_r3(n-1) + fib_r3(n-2)
73 |
74 | @dec_time
75 | def foo3():
76 | for i in range(1000):
77 | fib_r3(i)
78 | foo3()
79 |
80 | # @functools.lru_cache(maxsize=300)
81 | # def bar(li):
82 | # return sum(li)
83 |
84 | # print(bar([1,2,3]))
85 | # print(bar([22,22,22]))
86 |
87 | @dec_memo_limit
88 | def fib_r4(n):
89 | if n == 0 or n == 1:
90 | return n
91 | else:
92 | return fib_r4(n-1) + fib_r4(n-2)
93 | print(fib_r4)
94 |
95 |
96 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_natural.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def dec_natural(func):
4 | def wrapper(n):
5 | if type(n) == int and n >= 0:
6 | return func(n)
7 | else:
8 | raise TypeError('Argument is not a natural number')
9 | return wrapper
10 |
11 | @dec_natural
12 | def fact_i(n):
13 | result = 1
14 | for i in range(1, n+1):
15 | result *= i
16 | return result
17 |
18 | print(fact_i(3))
19 | # print(fact_i(-1))
20 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_notfunc.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def dec_notfunc(n):
4 | def wrapper(func):
5 | return [func(i) for i in range(n)]
6 | return wrapper
7 |
8 | @dec_notfunc(5)
9 | def foo(n):
10 | return n**2
11 |
12 | print(foo)
13 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_time.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def dec_time(func):
4 | def wrapper(*args, **kwargs):
5 | import time
6 | t_start = time.clock()
7 | res = func(*args, **kwargs)
8 | t_end = time.clock()
9 | print(func.__name__, t_end-t_start)
10 | return res
11 | return wrapper
12 |
13 | def fact_i(n):
14 | result = 1
15 | for i in range(1, n+1):
16 | result *= i
17 | return result
18 |
19 | @dec_time
20 | def foo(n):
21 | for i in range(n):
22 | fact_i(i)
23 | foo(1000)
24 |
--------------------------------------------------------------------------------
/ch09/ch09_dec_wraps.py:
--------------------------------------------------------------------------------
1 |
2 | import functools
3 |
4 | def dec(func):
5 | @functools.wraps(func)
6 | def wrapper():
7 | return func()
8 | return wrapper
9 |
10 | @dec
11 | def foo():
12 | pass
13 |
14 | print(foo.__name__)
15 |
16 |
--------------------------------------------------------------------------------
/ch09/ch09_fact_i_r.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact_i(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 | ####
9 | def fact_r(n):
10 | if n == 1 or n == 0:
11 | return 1
12 | else:
13 | return n * fact_r(n-1)
14 |
15 | print(fact_i(999))
16 | print(fact_r(999))
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch09/ch09_fact_tail.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact_i(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 | ####
9 | def fact_r(n):
10 | if n == 1 or n == 0:
11 | return 1
12 | else:
13 | return n * fact_r(n-1)
14 | ####
15 | def fact_r_tail(n, result=1):
16 | if n == 1 or n == 0:
17 | return result
18 | else:
19 | return fact_r_tail(n-1, n*result)
20 |
21 | for i in range(2, 50):
22 | x = fact_i(i)
23 | y = fact_r(i)
24 | z = fact_r_tail(i)
25 | if x == y == z:
26 | pass
27 | else:
28 | print('error')
29 |
30 |
--------------------------------------------------------------------------------
/ch09/ch09_fact_tco.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact_i(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 | ####
9 | def fact_r(n):
10 | if n == 1 or n == 0:
11 | return 1
12 | else:
13 | return n * fact_r(n-1)
14 | ####
15 | def fact_r_tail(n, result=1):
16 | if n == 1 or n == 0:
17 | return result
18 | else:
19 | return fact_r_tail(n-1, n*result)
20 | ####
21 |
22 | import sys
23 |
24 | class TailRecurseException(BaseException):
25 | def __init__(self, args, kwargs):
26 | self.args = args
27 | self.kwargs = kwargs
28 |
29 | def tail_call_optimized(g):
30 | def func(*args, **kwargs):
31 | f = sys._getframe()
32 | if (f.f_back and f.f_back.f_back and
33 | f.f_back.f_back.f_code == f.f_code):
34 | raise TailRecurseException(args, kwargs)
35 | else:
36 | while 1:
37 | try:
38 | return g(*args, **kwargs)
39 | except TailRecurseException as e:
40 | args = e.args
41 | kwargs = e.kwargs
42 | return func
43 |
44 | # @tail_call_optimized
45 | # def fact_tco(n, result=1):
46 | # if n == 1 or n == 0:
47 | # return result
48 | # else:
49 | # return fact_tco(n-1, n*result)
50 | def fact_tco(n, result=1):
51 | if n == 1 or n == 0:
52 | return result
53 | else:
54 | return fact_tco(n-1, n*result)
55 |
56 | fact_tco = tail_call_optimized(fact_tco)
57 |
58 | for i in range(2, 50):
59 | x = fact_i(i)
60 | y = fact_r(i)
61 | z = fact_r_tail(i)
62 | w = fact_tco(i)
63 | if x == y == z == w:
64 | pass
65 | else:
66 | print('error')
67 |
68 | # print(fact_i(980))
69 | sys.setrecursionlimit(2000)
70 | print(fact_r_tail(1000))
71 | sys.setrecursionlimit(100)
72 | print(fact_tco(1000))
73 | for i in range(1000, 1050, 3):
74 | x = fact_i(i)
75 | w = fact_tco(i)
76 | if x == w:
77 | pass
78 | else:
79 | print('error')
80 |
--------------------------------------------------------------------------------
/ch09/ch09_forest.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | tree_a = ['-', 6, 2]
4 | tree_b = ['/', 10, 2]
5 | tree_c = ['+', 3, tree_a, tree_b]
6 | tree_d = ['-', 5, 2, 1]
7 | tree_e = ['*', tree_d, tree_c]
8 |
9 | import operator
10 |
11 | ops = {'+': operator.add,
12 | '-': operator.sub,
13 | '*': operator.mul,
14 | '/': operator.floordiv}
15 |
16 | def cal_tree(tree):
17 | if type(tree) == int:
18 | return tree
19 | else:
20 | return cal_forest(tree[1:], tree[0])
21 |
22 | def cal_forest(forest, op):
23 | if len(forest) == 2:
24 | return ops[op](cal_tree(forest[0]), cal_tree(forest[1]))
25 | else:
26 | hsr = cal_forest(forest[:-1], op)
27 | return ops[op](hsr, cal_tree(forest[-1]))
28 |
29 | print(cal_tree(tree_e))
30 |
31 |
--------------------------------------------------------------------------------
/ch09/ch09_i_to_r.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def my_sum(li):
4 | if li == []:
5 | return 0
6 | else:
7 | return li[0] + my_sum(li[1:])
8 |
9 | print(my_sum(list(range(100+1))))
10 | print(my_sum([]))
11 | print(my_sum([1, 2, 3]))
12 |
13 | def my_len(li):
14 | if li == []:
15 | return 0
16 | else:
17 | return 1 + my_len(li[1:])
18 | print(my_len(list(range(100+1))))
19 | print(my_len([]))
20 | print(my_len([1, 2, 3]))
21 |
22 | def gcd(a, b):
23 | while b:
24 | a, b = b, a%b
25 | return a
26 | def gcd_r(a, b):
27 | if a%b == 0:
28 | return b
29 | else:
30 | return gcd(b, a%b)
31 | for i in range(2, 100, 3):
32 | for j in range(3, 100, 4):
33 | if gcd(i, j) != gcd_r(i, j):
34 | print('error', i, j)
35 |
36 | def ctof2(temp):
37 | n = my_len(temp)
38 | i = 0
39 | while i < n:
40 | temp[i] = temp[i] * 9.0 / 5.0 + 32
41 | i += 1
42 | data2 = [-30.2, -22.5, 15.8, 23.7, 35.2]
43 | ctof2(data2)
44 | data = [-30.2, -22.5, 15.8, 23.7, 35.2]
45 | def ctof(li):
46 | if li == []:
47 | return []
48 | else:
49 | return [li[0]*9.0/5.0+32] + ctof(li[1:])
50 | if ctof(data) != data2:
51 | print('error')
52 | print(ctof(data))
53 | print(data2)
54 |
--------------------------------------------------------------------------------
/ch09/ch09_map.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def sq(n): return n**2
4 | def even(n): return n % 2 == 0
5 | def sum_sq_even(n):
6 | result = 0
7 | for i in range(1, n):
8 | if even(i):
9 | result += sq(i)
10 | return result
11 |
12 | print(sum_sq_even(10))
13 |
14 | ####
15 |
16 | def sum_sq_even(n):
17 | return sum(map(sq, filter(even, range(1, n))))
18 |
19 | print(sum_sq_even(10))
20 |
21 | ####
22 |
23 | def dec_memo(func):
24 | cache = func.cache = {}
25 | def wrapper(*args, **kwargs):
26 | key = str(args) + str(kwargs)
27 | if key not in cache:
28 | cache[key] = func(*args, **kwargs)
29 | return cache[key]
30 | return wrapper
31 |
32 | @dec_memo
33 | def fib_r(n):
34 | if n == 0 or n == 1:
35 | return n
36 | else:
37 | return fib_r(n-1) + fib_r(n-2)
38 | fib = fib_r
39 |
40 | def odd(n):
41 | return n % 2 != 0
42 |
43 | def odd_fibs(n):
44 | result = []
45 | i = 0
46 | while i < n:
47 | temp = fib(i)
48 | if odd(temp):
49 | result.append(temp)
50 | i += 1
51 | return result
52 |
53 | print(odd_fibs(10))
54 |
55 | ####
56 |
57 | def odd_fibs(n):
58 | return list(filter(odd, map(fib, range(n))))
59 |
60 | print(odd_fibs(10))
61 |
62 | ####
63 |
64 | def my_map(func, iterable):
65 | result = []
66 | for e in iterable:
67 | result.append(func(e))
68 | return result
69 | def my_filter(func, iterable):
70 | result = []
71 | for e in iterable:
72 | if func(e):
73 | result.append(e)
74 | return result
75 |
76 | def sum_sq_even(n):
77 | return sum(my_map(sq, my_filter(even, range(1, n))))
78 |
79 | print(sum_sq_even(10))
80 |
81 | def odd_fibs(n):
82 | return list(my_filter(odd, my_map(fib, range(n))))
83 |
84 | print(odd_fibs(10))
85 |
86 | ####
87 |
88 | def sum_sq_even(n):
89 | return sum(my_map(sq,
90 | my_filter(even,
91 | range(1, n))))
92 |
93 | def odd_fibs(n):
94 | return list(my_filter(odd,
95 | my_map(fib,
96 | range(n))))
97 |
98 | ####
99 | print('-' * 20)
100 | from operator import add
101 | def sum_sq_even(n):
102 | return reduce(add,
103 | map(sq,
104 | filter(even,
105 | range(1, n))))
106 |
107 | def odd_fibs(n):
108 | return reduce(lambda x, y: x+[y],
109 | filter(odd,
110 | map(fib,
111 | range(n))),
112 | [])
113 |
114 |
115 | print(sum_sq_even(10))
116 | print(odd_fibs(10))
117 |
--------------------------------------------------------------------------------
/ch09/ch09_odd_even.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def is_odd(n):
4 | if n == 0:
5 | return False
6 | else:
7 | return is_even(n-1)
8 | def is_even(n):
9 | if n == 0:
10 | return True
11 | else:
12 | return is_odd(n-1)
13 |
14 |
15 |
16 | if __name__ == '__main__':
17 | for i in range(0, 100):
18 | if is_odd(i) != (i%2 == 1):
19 | print('error odd', i)
20 | if is_even(i) != (i%2 == 0):
21 | print('error even', i)
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ch09/ch09_odd_fibs.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def dec_memo(func):
4 | cache = func.cache = {}
5 | def wrapper(*args, **kwargs):
6 | key = str(args) + str(kwargs)
7 | if key not in cache:
8 | cache[key] = func(*args, **kwargs)
9 | return cache[key]
10 | return wrapper
11 |
12 | @dec_memo
13 | def fib_r(n):
14 | if n == 0 or n == 1:
15 | return n
16 | else:
17 | return fib_r(n-1) + fib_r(n-2)
18 | fib = fib_r
19 |
20 | def odd(n):
21 | return n % 2 != 0
22 |
23 | def odd_fibs(n):
24 | result = []
25 | i = 0
26 | while i < n:
27 | temp = fib(i)
28 | if odd(temp):
29 | result.append(temp)
30 | i += 1
31 | return result
32 |
33 | print(odd_fibs(10))
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ch09/ch09_sum_is_prime.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # from itertools import imap as map
4 | from itertools import repeat, chain
5 |
6 | def prime_sieve(n):
7 | primes = set(range(2, n+1))
8 | for i in range(2, (n+1+1) // 2):
9 | if i in primes:
10 | m = 2
11 | while i*m <= n:
12 | primes.discard(i*m)
13 | m += 1
14 | return primes
15 |
16 | def gen_pairs(i):
17 | return map(lambda i,j: (i,j), repeat(i), range(1, i))
18 |
19 | def gen_allpairs(n):
20 | return chain(*map(gen_pairs, range(2, n+1)))
21 |
22 | def pair_sum(p):
23 | return (p[0], p[1], p[0]+p[1])
24 |
25 | def is_prime(ps):
26 | return ps[2] in prime_sieve(ps[2])
27 |
28 | def sum_is_prime(n):
29 | return filter(is_prime, map(pair_sum, gen_allpairs(n)))
30 |
31 | print(list(sum_is_prime(6)))
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ch09/ch09_sum_of_primes.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from itertools import imap as map
4 |
5 | def prime_sieve(n):
6 | primes = set(range(2, n+1))
7 | for i in range(2, (n+1+1) // 2):
8 | if i in primes:
9 | m = 2
10 | while i*m <= n:
11 | primes.discard(i*m)
12 | m += 1
13 | return primes
14 |
15 | def is_prime(n):
16 | return n in prime_sieve(n)
17 | def sum_of_primes(n):
18 | return sum(filter(is_prime, range(2, n+1)))
19 |
20 | print(sum_of_primes(20))
21 | print(sum_of_primes(2 * 1000))
22 |
--------------------------------------------------------------------------------
/ch09/ch09_sum_sq_even.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def sq(n): return n**2
4 | def even(n): return n % 2 == 0
5 | def sum_sq_even(n):
6 | result = 0
7 | for i in range(1, n):
8 | if even(i):
9 | result += sq(i)
10 | return result
11 |
12 | print(sum_sq_even(10))
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ch09/ch09_tph.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Problem 45: Triangular, pentagonal, and hexagonal
4 | # https://projecteuler.net/problem=45
5 |
6 | from itertools import count
7 | from itertools import imap as map
8 |
9 | def filter_equal(ita, itb):
10 | a = next(ita)
11 | b = next(itb)
12 | while True:
13 | if a < b:
14 | a = next(ita)
15 | elif a > b:
16 | b = next(itb)
17 | else:
18 | yield a
19 | a = next(ita)
20 |
21 | def tph_gf():
22 | t = map(lambda n: n * (n+1) // 2, count(1))
23 | p = map(lambda n: n * (3*n - 1) // 2, count(1))
24 | h = map(lambda n: n * (2*n - 1), count(1))
25 | filter_tph = filter_equal(filter_equal(t, p), h)
26 | while True:
27 | yield next(filter_tph)
28 |
29 | tph = tph_gf()
30 | print(next(tph)) # 1
31 | print(next(tph)) # 40755
32 | print(next(tph)) # 1533776805
33 |
--------------------------------------------------------------------------------
/ch09/ch09_tree.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | tree_a = ['-', 4, 1]
4 | tree_b = ['/', 10, 2]
5 | tree_c = ['+', tree_a, tree_b]
6 | tree_d = ['+', 3, tree_c]
7 | tree_e = ['-', 4, 2]
8 | tree_f = ['*', tree_e, tree_d]
9 |
10 | import operator
11 |
12 | ops = {'+': operator.add,
13 | '-': operator.sub,
14 | '*': operator.mul,
15 | '/': operator.floordiv}
16 |
17 | def cal(tree):
18 | if type(tree) == int:
19 | return tree
20 | else:
21 | return ops[tree[0]](cal(tree[1]), cal(tree[2]))
22 |
23 | print(cal(tree_f))
24 |
25 |
--------------------------------------------------------------------------------
/ch09/ch09ex9.10_flatten_list.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def flatten_list(a, result=None):
4 | if result is None:
5 | result = []
6 | for x in a:
7 | if isinstance(x, list):
8 | else:
9 | result.append(x)
10 | return result
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ch09/ch09ex9.7_hamming.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def hamming(a, b):
4 | return sum(x != y for x, y in map(None, a, b))
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ch09/ch09ex9.xzy_accept.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # from PEP 318
4 | # https://www.python.org/dev/peps/pep-0318/#current-syntax
5 |
6 | def accepts(*types):
7 | def check_accepts(f):
8 | assert len(types) == f.func_code.co_argcount
9 | def new_f(*args, **kwds):
10 | for (a, t) in zip(args, types):
11 | assert isinstance(a, t), \
12 | "arg %r does not match %s" % (a,t)
13 | return f(*args, **kwds)
14 | new_f.func_name = f.func_name
15 | return new_f
16 | return check_accepts
17 |
18 | def returns(rtype):
19 | def check_returns(f):
20 | def new_f(*args, **kwds):
21 | result = f(*args, **kwds)
22 | assert isinstance(result, rtype), \
23 | "return value %r does not match %s" % (result,rtype)
24 | return result
25 | new_f.func_name = f.func_name
26 | return new_f
27 | return check_returns
28 |
29 | @accepts(int, (int,float))
30 | @returns((int,float))
31 | def func(arg1, arg2):
32 | return arg1 * arg2
33 |
--------------------------------------------------------------------------------
/ch10/ch10_ns_package.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import sys
4 | # sys.path.append('/cygdrive/d/yehnan/wr_python_drmaster/python_book_yehnan/ch10/path1')
5 | # sys.path.append('/cygdrive/d/yehnan/wr_python_drmaster/python_book_yehnan/ch10/path2')
6 | sys.path.append(r'D:\yehnan\wr_python_drmaster\python_book_yehnan\ch10\path1')
7 | sys.path.append(r'D:\yehnan\wr_python_drmaster\python_book_yehnan\ch10\path2')
8 |
9 | # import mymodule
10 | # print(mymodule.__name__)
11 | # print(mymodule.__file__)
12 | # print(mymodule.__path__)
13 |
14 | import mymodule.sub1
15 | import mymodule.sub2
16 |
17 | print(mymodule.sub1.foo())
18 | print(mymodule.sub2.bar())
19 |
--------------------------------------------------------------------------------
/ch10/ch10_package_example.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # import package_example.gui.menu
5 | # import package_example.gui.canvas
6 | # from package_example.gui import *
7 |
8 | # print(display())
9 | # print(draw())
10 | # print(menu.__name__)
11 | # print(canvas.__name__)
12 |
13 |
14 | # print(canvas.__name__)
15 | # print(menu.__name__)
16 |
17 | # import package_example.formats.foo
18 | # print(type(package_example.formats.foo))
19 |
20 | # from package_example.formats import foo
21 | # print(type(foo))
22 |
23 | # import package_example.tools
24 | # print(package_example.tools.foo())
25 | # print(package_example.tools.bar())
26 |
27 | # from package_example.tools import rotate
28 | # print(rotate.rotate())
29 |
30 | # import package_example.formats.jpg
31 | # import package_example.formats.bar
32 | # print(package_example.formats.bar.__name__)
33 |
34 | # import package_example
35 |
36 | # import package_example.tools.xyz
37 |
38 | # from . import info
39 | # print(info.__name__)
40 |
41 | import package_example.formats.foo
42 | print(package_example.formats.foo.sos(3, 4))
43 | print(package_example.__path__)
44 |
--------------------------------------------------------------------------------
/ch10/ch10_reload.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | # from importlib import reload # 3.4版
4 | from imp import reload # 3.4版之前
5 | # # 2.x版直接使用內建函式reload
6 | from time import sleep
7 |
8 | import ch10_reload_module
9 |
10 | while True:
11 | print('-' * 20)
12 | print(ch10_reload_module.pi)
13 | print(ch10_reload_module.data)
14 | print(ch10_reload_module.foo(3, 4))
15 | sleep(5)
16 | reload(ch10_reload_module)
17 |
18 |
--------------------------------------------------------------------------------
/ch10/ch10_reload_2.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | # from importlib import reload # 3.4版
4 | from imp import reload # 3.4版之前
5 | # # 2.x版直接使用內建函式reload
6 | from time import sleep
7 |
8 | import ch10_reload_module
9 | from ch10_reload_module import pi
10 | from ch10_reload_module import data
11 | from ch10_reload_module import foo
12 |
13 | while True:
14 | print('-' * 20)
15 | print(pi)
16 | print(data)
17 | print(foo(3, 4))
18 | sleep(5)
19 | reload(ch10_reload_module)
20 |
21 |
--------------------------------------------------------------------------------
/ch10/ch10_reload_module.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 |
4 | pi = 3.14
5 | data = [30, 41, 52, 63, 74]
6 | z = 100
7 |
8 | def foo(x, y):
9 | return x + y + z
10 |
11 |
--------------------------------------------------------------------------------
/ch10/myhello.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | a = 26
4 | b = 16
5 |
6 | import mymath
7 |
8 | def main():
9 | print('Hello Python')
10 | print('pi is ' + str(mymath.pi))
11 | print('gcd(%d, %d) is %d' % (a, b, mymath.gcd(a, b)))
12 | print('factorial(%d) is %d' % (6, mymath.factorial(6)))
13 | print('Bye Python')
14 |
15 | if __name__ == '__main__':
16 | print('%s as main program' % __name__)
17 | print('mymath.__name__ is %s ' % mymath.__name__)
18 | main()
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ch10/myhello2.py:
--------------------------------------------------------------------------------
1 |
2 | # import mymath2
3 | # print(mymath2._x)
4 |
5 | # from mymath2 import _x
6 | # print(_x)
7 |
8 | # from mymath3 import *
9 | # print(pi)
10 | # print(x)
11 |
12 | # from mymath3 import *
13 | # print(pi)
14 | # print(x)
15 | # print(y)
16 |
17 | from mymath3 import x
18 | print(x)
19 |
--------------------------------------------------------------------------------
/ch10/mymath.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | pi = 3.14
4 |
5 | def gcd(a, b):
6 | while b:
7 | a, b = b, a%b
8 | return a
9 |
10 | def factorial(n):
11 | result = 1
12 | for i in range(1, n+1):
13 | result *= i
14 | return result
15 |
16 | if __name__ == '__main__':
17 | print('%s as main program' % __name__)
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ch10/mymath2.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | _x = 'xxx'
5 | _y = 3
6 | pi = 3.14
7 | def gcd(a, b): pass
8 | def factorial(n): pass
9 | def _z(): pass
10 |
--------------------------------------------------------------------------------
/ch10/mymath3.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | __all__ = ['pi', 'gcd', 'factorial']
4 | x = 'xxx'
5 | y = 3
6 | pi = 3.14
7 | def gcd(a, b): pass
8 | def factorial(n): pass
9 | def z(): pass
10 |
--------------------------------------------------------------------------------
/ch10/package_example/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # from .. import * # error
5 |
6 |
--------------------------------------------------------------------------------
/ch10/package_example/formats/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | def foo():
3 | return 'foo'
4 |
--------------------------------------------------------------------------------
/ch10/package_example/formats/bar.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def square(x):
4 | return x * x
5 |
--------------------------------------------------------------------------------
/ch10/package_example/formats/bmp.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch10/package_example/formats/bmp.py
--------------------------------------------------------------------------------
/ch10/package_example/formats/foo.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import sys
4 | sys.path.append('/cygdrive/d/yehnan/wr_python_drmaster/python_book_yehnan/ch10')
5 |
6 | # import package_example.formats.bar
7 | # square = package_example.formats.bar.square
8 |
9 | # from bar import square
10 |
11 | from . import bar
12 | square = bar.square
13 |
14 | # from .bar import square
15 |
16 |
17 | def sos(a, b):
18 | return square(a) + square(b)
19 |
20 |
21 | if __name__ == '__main__':
22 | if sos(3, 4) != 25:
23 | print('error')
24 | else:
25 | print('ok')
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ch10/package_example/formats/jpg.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from . import bar
4 | from .. import info
5 | from ..gui import display
6 | from ..gui import menu
7 | from ..gui.canvas import *
8 |
9 | print(bar.__name__)
10 | print(info.__name__)
11 | print(display())
12 | print(menu.__name__)
13 | print(clear())
14 |
15 |
--------------------------------------------------------------------------------
/ch10/package_example/formats/png.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch10/package_example/formats/png.py
--------------------------------------------------------------------------------
/ch10/package_example/gui/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | __all__= ['menu', 'canvas', 'display', 'draw']
4 |
5 | def display():
6 | return 'display'
7 | def draw():
8 | return 'draw'
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ch10/package_example/gui/canvas.py:
--------------------------------------------------------------------------------
1 |
2 | def clear():
3 | return 'clear'
4 |
--------------------------------------------------------------------------------
/ch10/package_example/gui/menu.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch10/package_example/gui/menu.py
--------------------------------------------------------------------------------
/ch10/package_example/info.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/ch10/package_example/info.py
--------------------------------------------------------------------------------
/ch10/package_example/tools/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # from foo import * # 2.x
4 | # from bar import * # 2.x
5 |
6 | # from package_example.tools.foo import *
7 | # from package_example.tools.bar import *
8 |
9 | from .foo import *
10 | from .bar import *
11 |
12 |
--------------------------------------------------------------------------------
/ch10/package_example/tools/bar.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def bar():
4 | return 'bar'
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ch10/package_example/tools/foo.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def foo():
4 | return 'foo'
5 |
6 |
--------------------------------------------------------------------------------
/ch10/package_example/tools/rotate.py:
--------------------------------------------------------------------------------
1 |
2 | def rotate():
3 | return 'rotate'
4 |
5 |
--------------------------------------------------------------------------------
/ch10/package_example/tools/xyz/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | from ... import info
5 |
6 | print(info.__name__)
7 |
--------------------------------------------------------------------------------
/ch10/path1/mymodule/sub1.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def foo():
4 | return 'foo'
5 |
--------------------------------------------------------------------------------
/ch10/path2/mymodule/sub2.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def bar():
4 | return 'bar'
5 |
--------------------------------------------------------------------------------
/ch11/ch11_abc.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from abc import ABCMeta, abstractmethod
4 |
5 | class S(metaclass=ABCMeta):
6 | # __metaclass__ = ABCMeta
7 | @abstractmethod
8 | def method_1(self, arg1): pass
9 | def method_2(self, arg1, arg2): pass
10 |
11 | # s = S()
12 |
13 | class Sub(S):
14 | def method_1(self, arg1):
15 | print(arg1)
16 | def method_2(self, arg1, arg2):
17 | print(arg1, arg2)
18 |
19 | s = Sub()
20 | s.method_1(3)
21 | s.method_2(3, 4)
22 |
23 |
--------------------------------------------------------------------------------
/ch11/ch11_bankaccount.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class BankAccount():
4 | def __init__(self):
5 | self.balance = 0
6 | def deposit(self, amount):
7 | self.balance += amount
8 | def withdraw(self, amount):
9 | self.balance -= amount
10 | def get_balance(self):
11 | return self.balance
12 |
13 | ac0 = BankAccount()
14 | print(ac0.balance)
15 | ac0.deposit(100)
16 | ac0.withdraw(30)
17 | print(ac0.get_balance())
18 | ac1 = BankAccount()
19 | ac1.deposit(1000)
20 | print(ac1.get_balance())
21 |
22 | print(type(BankAccount.deposit))
23 | print(BankAccount.__init__)
24 |
25 | print(type(ac0.deposit))
26 | print(type(ac0.__init__))
27 | print(BankAccount)
28 | print(callable(BankAccount))
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ch11/ch11_class_generator.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class FromNtoM():
4 | def __init__(self, n, m):
5 | self.n = n
6 | self.m = m
7 | def __iter__(self):
8 | return self
9 | def __next__(self):
10 | if self.n < self.m:
11 | tmp, self.n = self.n, self.n+1
12 | return tmp
13 | else:
14 | raise StopIteration
15 |
16 | print(sum(FromNtoM(1, 100+1)))
17 | print(sum(range(1, 100+1)))
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ch11/ch11_foo.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Foo(object):
4 | pass
5 |
6 | Foo.pi = 3.14
7 | print(Foo.pi)
8 |
9 | def gcd(a, b): # Greatest Common Divisor
10 | while b:
11 | a, b = b, a%b
12 | return a
13 |
14 | Foo.gcd = gcd
15 | print(Foo.gcd)
16 |
17 |
18 | class Bar():
19 | def __init__(self):
20 | self.x = 3
21 | def xxx():
22 | print('hello')
23 | def yyy(aa):
24 | print('hello', aa.x)
25 | Bar.xxx()
26 | b = Bar()
27 | # b.xxx()
28 | b.yyy()
29 |
--------------------------------------------------------------------------------
/ch11/ch11_frange.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Frange():
4 | def __init__(self, start, stop=None, step=None):
5 | self.start = start + 0.0
6 | self.stop = stop
7 | self.step = step
8 | if self.stop is None:
9 | self.stop = self.start + 0.0
10 | self.start = 0.0
11 | if self.step is None:
12 | self.step = 1.0
13 | def __iter__(self):
14 | return self
15 | def __next__(self):
16 | next = self.start
17 | self.start += self.step
18 | if abs(next) < abs(self.stop):
19 | return next
20 | else:
21 | raise StopIteration
22 |
23 | for x in Frange(3):
24 | print(x)
25 | print([i for i in Frange(2.55, 3.7, 0.1)])
26 | print([i for i in Frange(0, 1, 0.1)])
27 |
--------------------------------------------------------------------------------
/ch11/ch11_inherit.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class A():
4 | x, y = 3, 4
5 | def __init__(self, a, b):
6 | self.a = a
7 | self.b = b
8 | def foo(self):
9 | print(self.a + self.b + self.x + self.y)
10 | class B(A):
11 | ww = 1000
12 | x = 1003
13 | def bar(self):
14 | self.foo()
15 | print(self.x + self.ww)
16 |
17 | a0 = A(13, 14)
18 | a0.foo()
19 | b0 = B(103, 104)
20 | b0.foo()
21 | b0.bar()
22 |
23 |
--------------------------------------------------------------------------------
/ch11/ch11_mi.py:
--------------------------------------------------------------------------------
1 |
2 | class S():
3 | def foo(self): pass
4 | class A(S):
5 | def foo(self): print('A foo')
6 | class B(S):
7 | def foo(self): print('B foo')
8 | class C(A, B):
9 | pass
10 | C().foo()
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ch11/ch11_mi2.py:
--------------------------------------------------------------------------------
1 |
2 | class A(object): pass
3 | class B(object): pass
4 | class X(A, B): pass
5 | class Y(B, A): pass
6 | class Z(X, Y): pass
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ch11/ch11_myclass.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Person():
4 | def __init__(self, name, age, height, weight):
5 | self.name = name
6 | self.age = age
7 | self.height = height
8 | self.weight = weight
9 |
10 | # p1 = Person()
11 | p2 = Person('John', 22, 170, 60)
12 | p3 = Person('Amy', 17, 160, 42)
13 |
14 |
15 | class Book():
16 | def __init__(self, title, cover_price, discount=1.0):
17 | self.title = title
18 | self.cover_price = cover_price
19 | self.discount = discount
20 | def get_title(self): return self.title
21 | def get_cover_price(self): return self.cover_price
22 | def get_discount(self): return self.discount
23 | def set_discount(self, discount): self.discount = discount
24 | def get_price(self): return int(self.cover_price * self.discount)
25 |
26 | b1 = Book('Make Wishes', 300)
27 | b2 = Book('Fun of cooking', 500, 0.79)
28 | print(b2.get_price())
29 | print('-' * 20)
30 |
31 | class MyClass():
32 | x, y, z = 3, 4, 5
33 | def sfoo():
34 | # print(z)
35 | print(MyClass.z)
36 | def __init__(self, x, y):
37 | self.x = x
38 | self.y = y
39 | def foo(self): print(self.x + self.z)
40 | def bar(self):
41 | # print(self.y - z)
42 | print(self.y - MyClass.z)
43 |
44 | c0 = MyClass(33, 44)
45 | MyClass.sfoo() # 5
46 | # c0.sfoo()
47 | c0.foo() # 38
48 | c0.bar() # 39
49 |
50 |
51 |
--------------------------------------------------------------------------------
/ch11/ch11_myclass_scope.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def foo():
4 | x = 3
5 | def bar():
6 | print(x)
7 | bar()
8 | foo()
9 |
10 | class MyClass():
11 | x = 3
12 | def foo():
13 | print(x)
14 | def bar(self):
15 | # print(x)
16 | print(self.x)
17 | # MyClass.foo()
18 | MyClass().bar()
19 |
--------------------------------------------------------------------------------
/ch11/ch11_orderedset.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # http://code.activestate.com/recipes/576694-orderedset/
4 | import collections
5 |
6 | class OrderedSet(collections.MutableSet):
7 | def __init__(self, iterable=None):
8 | self.end = end = []
9 | end += [None, end, end] # sentinel node for doubly linked list
10 | self.map = {} # key --> [key, prev, next]
11 | if iterable is not None:
12 | self |= iterable
13 |
14 | def __len__(self): return len(self.map)
15 |
16 | def __contains__(self, key): return key in self.map
17 |
18 | def add(self, key):
19 | if key not in self.map:
20 | end = self.end
21 | curr = end[1]
22 | curr[2] = end[1] = self.map[key] = [key, curr, end]
23 |
24 | def discard(self, key):
25 | if key in self.map:
26 | key, prev, next = self.map.pop(key)
27 | prev[2] = next
28 | next[1] = prev
29 |
30 | def __iter__(self):
31 | end = self.end
32 | curr = end[2]
33 | while curr is not end:
34 | yield curr[0]
35 | curr = curr[2]
36 |
37 | def __reversed__(self):
38 | end = self.end
39 | curr = end[1]
40 | while curr is not end:
41 | yield curr[0]
42 | curr = curr[1]
43 |
44 | def pop(self, last=True):
45 | if not self:
46 | raise KeyError('set is empty')
47 | key = self.end[1][0] if last else self.end[2][0]
48 | self.discard(key)
49 | return key
50 |
51 | def __repr__(self):
52 | if not self:
53 | return '%s()' % (self.__class__.__name__,)
54 | return '%s(%r)' % (self.__class__.__name__, list(self))
55 |
56 | def __eq__(self, other):
57 | if isinstance(other, OrderedSet):
58 | return len(self) == len(other) and list(self) == list(other)
59 | return set(self) == set(other)
60 |
61 |
62 | if __name__ == '__main__':
63 | s = OrderedSet('abracadaba')
64 | t = OrderedSet('simsalabim')
65 | print(s)
66 | print(t)
67 | print(s | t)
68 | print(s & t)
69 | print(s - t)
70 |
--------------------------------------------------------------------------------
/ch11/ch11_private.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class A():
4 | def bar(self): return 4
5 | def foo(self): return 3 + self.bar()
6 | class B(A):
7 | def bar(self): return 104
8 |
9 | b = B()
10 | print(b.foo())
11 |
12 | class A():
13 | def __bar(self): return 4
14 | def foo(self): return 3 + self.__bar()
15 | class B(A):
16 | def bar(self): return 104
17 | def bm(self): return self.bar() + 1000
18 |
19 | b = B()
20 | print(b.foo())
21 | print(b.bm())
22 | print(b._A__bar())
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ch11/ch11_property.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Person():
4 | def __init__(self, name):
5 | self._name = name
6 | @property
7 | def name(self):
8 | #
9 | return self._name
10 | @name.setter
11 | def name(self, value):
12 | #
13 | self._name = value
14 | @name.deleter
15 | def name(self):
16 | #
17 | del self._name
18 | p = Person('John')
19 | print(p.name)
20 | p.name = 'Amy'
21 | print(p.name)
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/ch11/ch11_static_class_method.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class MyClass():
4 | @staticmethod
5 | def foo(arg1, arg2): print(arg1, arg2)
6 | @classmethod
7 | def bar(cls, arg1): print(cls, arg1)
8 | MyClass.foo(3, 4)
9 | MyClass.bar(5)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ch11/ch11_test.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class A(object):
4 | x, y = 3, 4
5 | def __init__(self, a, b):
6 | self.a = a
7 | self.b = b
8 | def foo(self):
9 | print(self.a + self.b + self.x + self.y)
10 | class B(A):
11 | ww = 1000
12 | x = 1003
13 | def __init__(self):
14 | # self.__init__(13, 14)
15 | # A.__init__(self, 13, 14)
16 | # super(B, self).__init__(13, 14)
17 | super().__init__(13, 14)
18 | self.c = 15
19 | def bar(self):
20 | self.foo()
21 | print(self.x + self.ww)
22 |
23 | a0 = A(13, 14)
24 | a0.foo()
25 | b0 = B()
26 | b0.foo()
27 | b0.bar()
28 |
--------------------------------------------------------------------------------
/ch11/ch11_test2.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class A():
4 | x = 3
5 | def __init__(self):
6 | self.x = 33
7 |
8 |
9 | class B(A):
10 | x = 4
11 | def __init__(self):
12 | super().__init__()
13 | self.z = 1000
14 | b = B()
15 | print(b.x)
16 |
--------------------------------------------------------------------------------
/ch11/ch11_test3.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Animal():
4 | def shout(self): print('Animal shout')
5 | class Dog(Animal):
6 | def shout(self): print('Dog shout')
7 | class Cat(Animal):
8 | def shout(self): print('Cat shout')
9 | def __str__(self): return 'I am a cat'
10 |
11 | d = Dog(); d.shout()
12 | c = Cat(); c.shout()
13 | print(c)
14 |
15 | class MyClass():
16 | def __str__(self): return 'a MyClass instance'
17 | mc = MyClass()
18 | print(str(mc))
19 | print(mc)
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch11/ch11_test4.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class MyC():
4 | def __init__(self):
5 | self.x = 3
6 | self.y = 4
7 | def __hash__(self):
8 | return 100
9 | a = MyC()
10 | b = MyC()
11 | print(hash(a))
12 | print(hash(b))
13 |
14 | from collections import Hashable
15 |
16 | print(issubclass(MyC, Hashable))
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch11/ch11_test5.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class MyClass():
4 | x, y = 3, 4
5 | def foo(self):
6 | print(x + y)
7 | def bar(self):
8 | print(self.x + self.y)
9 | MyClass().foo()
10 | MyClass().bar()
11 |
--------------------------------------------------------------------------------
/ch11/ch11_test6.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class A(object):
4 | def __init__(self):
5 | super(A, self).__init__()
6 | print('A')
7 |
8 | class B(object):
9 | def __init__(self):
10 | super(B, self).__init__()
11 | print('B')
12 |
13 | class C(A, B):
14 | def __init__(self):
15 | super(C, self).__init__()
16 | # super().__init__()
17 | print('C')
18 | C()
19 |
--------------------------------------------------------------------------------
/ch12/ch12_2.x_old_syntax.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # different in 2.x and 3.x
4 | try:
5 | [0, 1, 2][999]
6 | except IndexError, ValueError:
7 | print('hi')
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ch12/ch12_as_e.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | def f():
5 | try:
6 | [0, 1, 2][999]
7 | except IndexError as e:
8 | print(e)
9 | finally:
10 | print(e)
11 | print(e)
12 | f()
13 |
14 | def f():
15 | exc = None
16 | try:
17 | [0, 1, 2][999]
18 | except IndexError as e:
19 | exc = e
20 | print(exc)
21 | finally:
22 | print(exc)
23 | print(exc)
24 | f()
25 |
26 |
--------------------------------------------------------------------------------
/ch12/ch12_assert.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | def fact(n):
5 | assert type(n) is int
6 | assert n < 0
7 | result = 1
8 | for i in range(1, n+1):
9 | result *= i
10 | return result
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ch12/ch12_fact.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact(n):
4 | result = 1
5 | for i in range(1, n+1):
6 | result *= i
7 | return result
8 |
9 | while True:
10 | s = input('input n: ')
11 | f = fact(int(s))
12 | print('%s! = %d' % (s, f))
13 |
14 |
--------------------------------------------------------------------------------
/ch12/ch12_fact_2.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def fact(n):
4 | if type(n) is not int or n < 0:
5 | return None
6 | result = 1
7 | for i in range(1, n+1):
8 | result *= i
9 | return result
10 |
11 | while True:
12 | s = input('input n: ')
13 | f = fact(int(s))
14 | if f is not None:
15 | print('%s! = %d' % (s, f))
16 | else:
17 | print('n must be a non-negative integer')
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ch12/ch12_fact_exception.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | def fact(n):
4 | if type(n) is not int:
5 | raise TypeError
6 | if n < 0:
7 | raise ValueError('Argument must be non-negative')
8 | result = 1
9 | for i in range(1, n+1):
10 | result *= i
11 | return result
12 |
13 | while True:
14 | try:
15 | s = input('input n: ') # 2.x版改用raw_input
16 | f = fact(int(s))
17 | except TypeError:
18 | print('%s is not an integer' % s)
19 | break
20 | except ValueError as e:
21 | print('%s can not be less than 0' % s)
22 | break
23 | print('%s! = %d' % (s, f))
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ch12/ch12_fact_exception_2.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | def fact(n):
4 | if type(n) is not int:
5 | raise TypeError('Argument must be type int')
6 | if n < 0:
7 | raise ValueError('Argument must be non-negative')
8 | result = 1
9 | for i in range(1, n+1):
10 | result *= i
11 | return result
12 |
13 | while True:
14 | try:
15 | s = input('input n: ') # 2.x版改用raw_input
16 | f = fact(int(s))
17 | except (EOFError, KeyboardInterrupt) as e:
18 | print('Bye')
19 | break
20 | except TypeError as e:
21 | print('Error: ' + str(e))
22 | except ValueError as e:
23 | print('Error: ' + str(e))
24 | except Exception:
25 | print('Error: unknown error')
26 | else:
27 | print('%s! = %d' % (s, f))
28 |
29 |
--------------------------------------------------------------------------------
/ch12/ch12_flow.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def foo():
4 | try :
5 | raise ValueError
6 | except IndexError:
7 | print('IndexError')
8 | finally:
9 | print('foo finally')
10 | print('foo end')
11 | def bar():
12 | try:
13 | foo()
14 | except ValueError:
15 | print('ValueError')
16 | finally:
17 | print('bar finally')
18 | print('bar end')
19 | bar()
20 | print('program end')
21 |
22 |
--------------------------------------------------------------------------------
/ch12/ch12_foo_exception.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | class FooException(Exception):
5 | def __init__(self, msg, status):
6 | Exception.__init__(self, msg, status)
7 | self.msg = msg
8 | self.status = status
9 |
10 | try:
11 | raise FooException('hello', 'sta')
12 | except FooException as e:
13 | print(e)
--------------------------------------------------------------------------------
/ch12/ch12_list_bound.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # def get(li, n):
4 | # try:
5 | # li[n]
6 | # except IndexError as e:
7 | # print('get IndexError')
8 | # raise
9 |
10 | def get(li, n):
11 | try:
12 | li[n]
13 | except IndexError as e:
14 | s = 'index %d, len of list is %d' % (n, len(li))
15 | raise IndexError(s) from e
16 |
17 | li = [0, 1, 2]
18 | get(li, 99)
19 |
20 |
--------------------------------------------------------------------------------
/ch12/ch12_no_with.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | from io import open
4 |
5 | try:
6 | fin = open('test.txt', 'r', encoding='utf-8')
7 | try:
8 | for line in fin:
9 | print(line)
10 | except UnicodeError as e:
11 | print('Error while reading file: ' + str(e))
12 | except Exception as e:
13 | print('Error while reading file: ' + str(e))
14 | finally:
15 | fin.close()
16 | except Exception as e:
17 | print('Error while opening file: ' + str(e))
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch12/test.txt:
--------------------------------------------------------------------------------
1 | abc
2 | 123
3 | 你我他
4 | xyz
5 |
--------------------------------------------------------------------------------
/ch13/ch13_argparse.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import argparse
4 |
5 | parser = argparse.ArgumentParser(description='Count lines in text files')
6 |
7 | parser.add_argument(dest='path', metavar='path')
8 |
9 | parser.add_argument('-e', dest='extensions', action='append',
10 | metavar='extension', required=True,
11 | help='filename extensions to process')
12 |
13 | parser.add_argument('-b', dest='blankline', action='store_true',
14 | help='blank line')
15 |
16 | parser.add_argument('-r', dest='recur', action='store_true',
17 | help='recursively into subdirectories')
18 |
19 | parser.add_argument('-o', dest='outfile', action='store',
20 | help='output file')
21 |
22 | parser.add_argument('--speed', dest='speed', action='store',
23 | choices={'slow','fast'}, default='fast',
24 | help='processing speed')
25 |
26 | args = parser.parse_args()
27 |
28 | print('path', args.path)
29 | print('extensions', args.extensions)
30 | print('blankline', args.blankline)
31 | print('recur', args.recur)
32 | print('outfile', args.outfile)
33 | print('speed', args.speed)
34 |
35 |
--------------------------------------------------------------------------------
/ch13/ch13_argv.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import sys
4 |
5 | print(sys.argv)
6 |
7 |
--------------------------------------------------------------------------------
/ch13/ch13_argv_basic.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import sys
4 |
5 | def main(infile, outfile):
6 | print(infile, outfile)
7 |
8 | def proc_argv(argv):
9 | infile, outfile = None, None
10 | infile = argv[0]
11 | try:
12 | outfile = argv[1]
13 | except Exception:
14 | outfile = infile + '.out'
15 | print("Warning: output filename defaults to " + outfile)
16 | return infile, outfile
17 |
18 | if __name__ == '__main__':
19 | try:
20 | inf, outf = proc_argv(sys.argv[1:])
21 | except Exception:
22 | print("At least specify input filename")
23 | sys.exit()
24 | main(inf, outf)
25 |
--------------------------------------------------------------------------------
/ch13/ch13_dining_ph.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import random
4 | import time
5 | import threading
6 | from contextlib import contextmanager
7 |
8 | # Thread-local state to stored information on locks already acquired
9 | _local = threading.local()
10 |
11 | @contextmanager
12 | def acquire(*locks):
13 | # Sort locks by object identifier
14 | locks = sorted(locks, key=lambda x: id(x))
15 | # Make sure lock order of previously acquired locks is not violated
16 | acquired = getattr(_local, 'acquired', [])
17 | if acquired and max(id(lock) for lock in acquired) >= id(locks[0]):
18 | raise RuntimeError('Lock Order Violation')
19 | # Acquire all of the locks
20 | acquired.extend(locks)
21 | _local.acquired = acquired
22 |
23 | try:
24 | for lock in locks:
25 | lock.acquire()
26 | yield
27 | finally:
28 | # Release locks in reverse order of acquisition
29 | for lock in reversed(locks):
30 | lock.release()
31 | del acquired[-len(locks):]
32 |
33 | # The philosopher thread
34 | def philosopher(id, left, right):
35 | while True:
36 | with acquire(left, right):
37 | print(id, 'eating')
38 | time.sleep(random.random())
39 | print(id, 'thinking')
40 | time.sleep(random.random())
41 |
42 | # The sticks (represented by locks)
43 | num_sticks = 5
44 | sticks_lock = [threading.Lock() for n in range(num_sticks)]
45 |
46 | # Create all of the philosophers
47 | for n in range(num_sticks):
48 | t = threading.Thread(target=philosopher,
49 | args=(n, sticks_lock[n],
50 | sticks_lock[(n+1) % num_sticks]))
51 | t.start()
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ch13/ch13_ticket.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import random
4 | import time
5 | from threading import Thread, Lock
6 |
7 | num_agents = 10
8 | num_tickets = [100]
9 |
10 | def sell_tickets(agent_id, nt, lock):
11 | total = 0
12 | while True:
13 | with lock:
14 | if nt[0] > 0:
15 | print('Agent %d sells a ticket No. %d' % (agent_id, nt[0]))
16 | nt[0] -= 1
17 | total += 1
18 | elif nt[0] == 0:
19 | break;
20 | #time.sleep(random.randrange(1, 3))
21 | time.sleep(random.random() * (1 + agent_id/2))
22 | print('Agent %d done. Totally sells %d tickets' % (agent_id, total))
23 |
24 | lock = Lock()
25 | for i in range(num_agents):
26 | t = Thread(target=sell_tickets, args=(i, num_tickets, lock))
27 | t.start()
28 |
29 |
--------------------------------------------------------------------------------
/ch13/ch13_tkinter.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from tkinter import *
4 |
5 | def fib(n):
6 | a, b = 0, 1
7 | for i in range(n):
8 | a, b = b, a+b
9 | return a
10 |
11 | class App(Frame):
12 | def __init__(self, master=None):
13 | Frame.__init__(self, master)
14 | self.pack()
15 |
16 | self.entry_n = Entry(self, width=10)
17 | self.entry_n.pack()
18 |
19 | self.fn = StringVar()
20 | self.label_fn = Label(self, textvariable=self.fn,
21 | width=50)
22 | self.fn.set('result')
23 | self.label_fn.pack()
24 |
25 | self.btn_cal = Button(self, text="Calculate",
26 | command=self.cal_fib)
27 | self.btn_cal.pack()
28 |
29 | self.btn_quit = Button(self, text="Quit", fg="red",
30 | command=root.destroy)
31 | self.btn_quit.pack(side=BOTTOM)
32 |
33 | def cal_fib(self):
34 | try:
35 | n = int(self.entry_n.get())
36 | self.fn.set(str(fib(n)))
37 | except Exception:
38 | self.fn.set('Invalid input')
39 |
40 | root = Tk()
41 | app = App(root)
42 | app.mainloop()
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/cover.jpg
--------------------------------------------------------------------------------
/misc/c_rw.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yehnan/python_book_yehnan/b1e1e0be5731160c36d53eaf7a1cee3ac03f30d9/misc/c_rw.py
--------------------------------------------------------------------------------
/misc/c_ticket.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # 電影院賣票 10個售票員(窗口) 共150張票
3 | # 每人負責15張
4 | # future: 有些售票員動作較慢,也有可能他的客人動作較慢,讓動作快的人負責賣較多張的票
5 | # future: 有些售票員可能突然肚子痛,關閉窗口;之後再回來賣票
6 |
7 | import random
8 | import time
9 | from threading import Thread
10 |
11 | print('main start')
12 |
13 | numAgents = 10
14 | numTickets = 150
15 |
16 | random.seed()
17 |
18 | def sellTickets(agentID, numTicketsToSell):
19 | while numTicketsToSell > 0:
20 | print('Agent ', agentID, ' sells a ticket ', numTicketsToSell)
21 | numTicketsToSell -= 1
22 | time.sleep(random.randrange(1, 3)) # simulating the time needed for selling a ticket
23 | print('Agent ', agentID, ' all down')
24 |
25 | ts = []
26 | for i in range(numAgents):
27 | t = Thread(target=sellTickets, args=(i, numTickets//numAgents))
28 | ts.append(t)
29 |
30 | for i in range(numAgents):
31 | ts[i].start()
32 |
33 | print('main end')
34 |
35 |
--------------------------------------------------------------------------------
/misc/ch04_base26_aa_zz.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # A B C D... Z AA AB AZ BA
4 | # 1 26 27 28 52 53
5 | # note: there is no zero
6 |
7 | alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
8 | base = len(alphabet)
9 |
10 | # from int to str, number must >= 1
11 | def base26encode(number, width=0):
12 | result = []
13 | while number-1 >= base:
14 | number, i = divmod(number-1, base)
15 | result.append(alphabet[i])
16 | result.append(alphabet[number-1])
17 |
18 | # padding
19 | result.extend([alphabet[0]] * (width - len(result)))
20 |
21 | return ''.join(reversed(result))
22 |
23 | # from str to int, 'A', 'B', ...'Z', 'AA', ...'AZ', ...
24 | def base26decode(s):
25 | s = s.upper()
26 | number = 0
27 | for n in s:
28 | number *= base
29 | number += alphabet.index(n) + 1
30 | return number
31 |
32 | print('a ', base26decode('a'))
33 | print(base26encode(base26decode('a') + 1))
34 | print('b ', base26decode('b'))
35 | print(base26encode(base26decode('b') + 1))
36 | print('aa ', base26decode('aa'))
37 | print(base26encode(base26decode('aa') + 1))
38 | print('ab ', base26decode('ab'))
39 | print(base26encode(base26decode('ab') + 1))
40 | print('z ', base26decode('z'))
41 | print(base26encode(base26decode('z') + 1))
42 | print('az ', base26decode('az'))
43 | print(base26encode(base26decode('az') + 1))
44 | print('ba ', base26decode('ba'))
45 | print(base26encode(base26decode('ba') + 1))
46 | print('bz ', base26decode('bz'))
47 | print(base26encode(base26decode('bz') + 1))
48 | print('zz ', base26decode('zz'))
49 | print(base26encode(base26decode('zz') + 1))
50 | print('------')
51 | print('at ', base26decode('at'))
52 | print(base26encode(base26decode('at') + 1, 2))
53 | print('bzz ', base26decode('bzz'))
54 | print(base26encode(base26decode('bzz') + 1, 4))
55 | print('zz ', base26decode('zz'))
56 | print(base26encode(base26decode('zz') + 1, 4))
57 | print('-' * 40)
58 |
59 |
60 |
--------------------------------------------------------------------------------
/misc/ch04_base26_aa_zz_no_padding.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # A B C D... Z AA AB AZ BA
4 | # 1 26 27 28 52 53
5 | # note: there is no zero
6 |
7 | alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
8 | base = len(alphabet)
9 |
10 | # from int to str, number must >= 1
11 | def base26encode(number):
12 | result = []
13 | while number-1 >= base:
14 | number, i = divmod(number-1, base)
15 | result.append(alphabet[i])
16 | result.append(alphabet[number-1])
17 |
18 | return ''.join(reversed(result))
19 |
20 | # from str to int, 'A', 'B', ...'Z', 'AA', ...'AZ', ...
21 | def base26decode(s):
22 | s = s.upper()
23 | number = 0
24 | for n in s:
25 | number *= base
26 | number += alphabet.index(n) + 1
27 | return number
28 |
29 | print('a ', base26decode('a'))
30 | print(base26encode(base26decode('a') + 1))
31 | print('b ', base26decode('b'))
32 | print(base26encode(base26decode('b') + 1))
33 | print('aa ', base26decode('aa'))
34 | print(base26encode(base26decode('aa') + 1))
35 | print('ab ', base26decode('ab'))
36 | print(base26encode(base26decode('ab') + 1))
37 | print('z ', base26decode('z'))
38 | print(base26encode(base26decode('z') + 1))
39 | print('az ', base26decode('az'))
40 | print(base26encode(base26decode('az') + 1))
41 | print('ba ', base26decode('ba'))
42 | print(base26encode(base26decode('ba') + 1))
43 | print('bz ', base26decode('bz'))
44 | print(base26encode(base26decode('bz') + 1))
45 | print('zz ', base26decode('zz'))
46 | print(base26encode(base26decode('zz') + 1))
47 | print('bzz ', base26decode('bzz'))
48 | print(base26encode(base26decode('bzz') + 1))
49 | print('------')
50 | print('-' * 40)
51 |
52 |
53 |
--------------------------------------------------------------------------------
/misc/ch05_stu_d.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | name, id, age, score_math, score_eng = range(0, 4+1)
4 | amy = ['Amy Chen', 14001, 17, 92, 75]
5 | john = ['John Smith', 14009, 18, 81, 84]
6 |
7 | print(amy[name])
8 | print(amy[age])
9 | print(john[score_math])
10 | print(john[score_eng])
11 |
12 | amy = {
13 | 'name': 'Amy Chen',
14 | 'id': 14001,
15 | 'age': 17,
16 | 'score_math': 92,
17 | 'score_eng': 75,
18 | }
19 | john = {
20 | 'name': 'John Smith',
21 | 'id': 14009,
22 | 'age': 18,
23 | 'score_math': 81,
24 | 'score_eng': 84,
25 | }
26 |
27 | print(amy['name'])
28 | print(amy['age'])
29 | print(john['score_math'])
30 | print(john['score_eng'])
31 |
32 |
33 |
--------------------------------------------------------------------------------
/misc/ch05_stu_data.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # dept is department
4 | name, id, age, dept, scores = range(0, 4+1)
5 | dept_phy = 'physics'
6 | dept_math = 'mathematics'
7 | dept_cs = 'computer science'
8 | # calculus, python, electromagnetism, history
9 | s_cal, s_ph, s_em, s_his = range(0, 3+1)
10 | students = [
11 | ['Amy Chen', '14001', '21', dept_phy, [90, 82, 95, None]],
12 | ['John Smith', '14003', '20', dept_math, [92, 82, None, 71]],
13 | ['Elsa Iceman', '14007', '24', dept_math, [93, 92, None, 73]],
14 | ['Penny Kuan', '14012', '22', dept_cs, [81, 99, 82, None]]
15 | ]
16 | print(students)
17 | print(students[0][name])
18 | print(students[1][id])
19 | print(students[2][age])
20 | print(students[3][dept])
21 | print(students[3][scores])
22 | print(students[3][scores][s_cal])
23 |
24 |
--------------------------------------------------------------------------------
/misc/scope_comprehension.py:
--------------------------------------------------------------------------------
1 |
2 | # i = 'abc'
3 | # print(i)
4 | # x = [i**2 for i in range(10)]
5 | # print(i) # 2.x 3.x different
6 |
7 | # i = 'abc'
8 | # print(i)
9 | # x = {i**2 for i in range(10)}
10 | # print(i)
11 |
12 | # i = 'abc'
13 | # print(i)
14 | # x = {i:i**2 for i in range(10)}
15 | # print(i)
16 |
17 | # i = 'abc'
18 | # print(i)
19 | # x = (i**2 for i in range(10))
20 | # print(i)
21 |
22 | # i = 'abc'
23 | # print(i)
24 | # for i in range(10):
25 | # pass
26 | # print(i)
27 |
28 | # print(globals())
29 |
--------------------------------------------------------------------------------
/misc/u_to_enc.py:
--------------------------------------------------------------------------------
1 |
2 | # -*- coding: utf-8 -*-
3 | import big5uao
4 | import codecs
5 |
6 | enc_utf_16_be = codecs.getencoder('utf_16_be')
7 | enc_big5uao = codecs.getencoder('big5uao')
8 | enc_gbk = codecs.getencoder('gbk')
9 |
10 | encs = (enc_utf_16_be, enc_big5uao, enc_gbk)
11 |
12 | s = '煊喆凜凛遙遥阪坂齊斉齐齋斎榮荣栄富冨樫堅島嶋崎﨑邊边辺絕绝對对対涉澀渋瑠鹽塩盐汙污汚櫻桜鐮镰鎌高髙癡痴'
13 |
14 | for c in s:
15 | fs = [c, ' ']
16 | for enc in encs:
17 | d, e = enc(c)
18 | x = '%02X%02X' % (d[0], d[1])
19 | fs.append(x)
20 | fs.append(' ')
21 | print(''.join(fs))
22 |
23 |
24 | print(len(s))
25 |
--------------------------------------------------------------------------------