├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── EDUCATORS.md ├── LICENSE.txt ├── TRANSLATIONS.md ├── book ├── chapter_01.md ├── chapter_02.md ├── chapter_03.md ├── chapter_04.md ├── chapter_05.md └── resources.md ├── media ├── demos │ ├── cli │ │ ├── a_game_of_dice.gif │ │ ├── a_game_of_dice.mp4 │ │ ├── autoloan_calculator.gif │ │ ├── autoloan_calculator.mp4 │ │ ├── california_lottery.gif │ │ ├── california_lottery.mp4 │ │ ├── random_person_generator.gif │ │ ├── random_person_generator.mp4 │ │ ├── spanish_translator_demo.gif │ │ └── spanish_translator_demo.mp4 │ ├── gui │ │ ├── bmi_calculator.gif │ │ ├── bmi_calculator.mp4 │ │ ├── secret_number_game_demo.gif │ │ ├── secret_number_game_demo.mp4 │ │ ├── temperature_converter.gif │ │ └── temperature_converter.mp4 │ ├── simple_images_with_turtle_collage.jpg │ └── turtle │ │ ├── 4_little_turtles_demo.gif │ │ ├── circle_art_demo.gif │ │ ├── circle_turtle_demo.gif │ │ ├── mike_and_ike_candies.gif │ │ ├── night_sky.gif │ │ ├── party-lights-demo.gif │ │ └── spirograph.gif ├── images │ ├── book │ │ ├── ccswp_ebook_cover.jpg │ │ ├── ccswp_paperback_cover.pdf │ │ ├── code_cool_stuff_with_python_robot.png │ │ └── code_cool_stuff_with_python_source.ai │ ├── ch_01 │ │ ├── Create_SampleProjects.jpg │ │ ├── adding_interpreter.jpg │ │ ├── create_a_fresh_python_file.jpg │ │ ├── helloworld.jpg │ │ ├── new_python_file.jpg │ │ ├── pycharm_project_setup.jpg │ │ └── run_helloworld.jpg │ ├── ch_04 │ │ ├── 4_little_turtles_racing.png │ │ ├── 4_little_turtles_racing_1.png │ │ ├── 4_little_turtles_racing_2.png │ │ ├── 4_little_turtles_racing_3.png │ │ ├── 4_little_turtles_racing_4.png │ │ ├── arc.png │ │ ├── big_green_turtle.png │ │ ├── blue_square.png │ │ ├── brick_wall.png │ │ ├── candies.png │ │ ├── circle.png │ │ ├── circle_art.png │ │ ├── enhanced_square.jpg │ │ ├── moving_turtle.png │ │ ├── nested_squares.png │ │ ├── night.png │ │ ├── party_lights.png │ │ ├── py_turtle_racing.png │ │ ├── random_color_circles.png │ │ ├── random_color_square_1.png │ │ ├── random_color_square_2.png │ │ ├── simple_turtle.png │ │ ├── snow_flake.png │ │ ├── spirograph1.png │ │ ├── square_cube.png │ │ ├── square_portrait.png │ │ ├── triangle_cube.png │ │ ├── turtle_angles.png │ │ ├── turtle_image_default.png │ │ ├── turtle_right_triangle_art.png │ │ └── two_turtles.png │ └── ch_05 │ │ ├── Greetings_app_1.jpg │ │ ├── Greetings_app_2.jpg │ │ ├── Simple_Tkinter_GUI.jpg │ │ ├── bmi_weight_status_labels.jpg │ │ ├── body_mass_index_calculator.jpg │ │ ├── grid_layout_manager_example.jpg │ │ ├── guessing_game_1.jpg │ │ ├── guessing_game_2.jpg │ │ ├── guessing_game_3.jpg │ │ ├── pack_geometry_manager.jpg │ │ ├── place_geometry_example.jpg │ │ └── temperature_converter_gui.jpg ├── pdfs │ ├── 01_A_Merry_Overview_Of_Python_PDF.pdf │ ├── 02_Crafting_Small_Scripts,_Converters_Practical_Tools_PDF.pdf │ ├── 03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python_PDF.pdf │ ├── 04_Crafting_Catchy_Computer_Art_with_Python_Turtle_PDF.pdf │ └── 05_Building_Practical_Desktop_apps_in_Python_Using_the_Core_Tkinter_Library_PDF.pdf └── slidedecks │ ├── 01_A_Merry_Overview_Of_Python.pptx │ ├── 02_Crafting_Small_Scripts_Converters_Practical_Tools.pptx │ ├── 03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python.pptx │ ├── 04_Crafting_Catchy_Computer_Art_With_Python.pptx │ └── 05_Building_Practical_Desktop_Apps_Tkinter.pptx ├── readme.md └── sourcecode ├── ch_01 ├── boolean_algebra.py ├── builtin_math_operators.py ├── comments.py ├── dictionaries_demo.py ├── elif_statement.py ├── exception_handling.py ├── for_loop.py ├── functions_in_python.py ├── helloworld.py ├── if_else_statement.py ├── list_demo.py ├── point_class.py ├── python_math_operators.py ├── sets_demo.py ├── strings_in_python.py ├── swapping_variables.py ├── ternary_statement.py ├── tuples_demo.py ├── variables.py └── while_loop.py ├── ch_02 ├── autoloan_calculator.py ├── mortgage_calculator.py ├── spanish_translator.py ├── temperature_converter.py └── your_bio.py ├── ch_03 ├── a_game_of_dice.py ├── california_lottery.py ├── draw_unique_nums.py └── random_person_generator.py ├── ch_04 ├── __pycache__ │ └── random_colors.cpython-37.pyc ├── big_green_turtle.py ├── mike_and_ike_candies.py ├── multi_color_cube.py ├── night.py ├── party_lights.py ├── random_circles.py ├── random_colors.py ├── simple_turtle_animation.py ├── snow_flake.py ├── spirograph_1.py ├── spirograph_2.py ├── square_artwork.py ├── square_random_color.py └── turtle_racing_game.py └── ch_05 ├── bmi_calculator.py ├── calculator.py ├── fahrenheit_to_celsius_app.py ├── secret_number_game.py ├── tkinter_basic_app.py ├── tkinter_checkbutton_demo.py ├── tkinter_greeting_app.py ├── tkinter_grid_example.py ├── tkinter_list_box.py ├── tkinter_pack_example.py └── tkinter_place_example.py /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | 3 | *Code Cool Stuff with Python* is dedicated to providing a harassment-free community for all, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of any form. All communication should be appropriate for a professional audience including people of many different backgrounds. 4 | 5 | Sexual language and imagery is not appropriate for any communication. Be kind and do not insult or put down others. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for the *Code Cool Stuff With Python* community. 6 | 7 | These are the values to which contributors in the community should aspire: 8 | 9 | - Be friendly and welcoming 10 | - Be patient 11 | - Remember that people have varying communication styles and that not everyone is using their native language. (Meaning and tone can be lost in translation.) 12 | - Be thoughtful 13 | - Productive communication requires effort. Think about how your words will be interpreted. 14 | - Remember that sometimes it is best to refrain entirely from commenting. 15 | 16 | - Be respectful 17 | - In particular, respect differences of opinion. 18 | - Be charitable 19 | - Interpret the arguments of others in good faith, do not seek to disagree. 20 | - When we do disagree, try to understand why. 21 | - Avoid destructive behavior: 22 | - Derailing: stay on topic; if you want to talk about something else, start a new conversation. 23 | - Unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved. 24 | - Snarking (pithy, unproductive, sniping comments) 25 | - Discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict. 26 | - Microaggressions: brief and commonplace verbal, behavioral and environmental indignities that communicate hostile, derogatory or negative slights and insults to a person or group. 27 | 28 | 29 | 30 | People are complicated. You should expect to be misunderstood and to misunderstand others; when this inevitably occurs, resist the urge to be defensive or assign blame. Try not to take offense where no offense was intended. Give people the benefit of the doubt. Even if the intent was to provoke, do not rise to it. It is the responsibility of all parties to de-escalate conflict when it arises. 31 | 32 | ## Reporting an incident 33 | 34 | Incidents that violate the Code of Conduct will not be tolerated. The silver lining is that, in many cases, these incidents present a chance for the offenders to grow, learn, and become better. To report a violation of the Code of Conduct send an email with the subject CoC violation to: purcellconsult@gmail.com 35 | This Code of Conduct was adapted from both [Golang](https://golang.org/conduct) and the [Golang UK Conference](https://www.gophercon.co.uk/conduct). 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | ## CONTRIBUTING 3 | 4 | We would love to have you contribute to the *Code Cool Stuff with Python* project! All levels are welcome because the more eyes on a project typically mean better quality. 5 | 6 | However, I want to be 100% transparent and upfront. If you do contribute then bear in mind that you give me a non-exclusive license to integrate your contributions into the book. 7 | 8 | You probably already knew this but I want to put it in writing to not hide anything. 9 | 10 | ## Why You Should Contribute? 11 | 12 | Here are some benefits of contributing to the Code Cool Stuff with Python project: 13 | 14 | - Experience mental growth and learn something new 15 | - Add more skills to your resume 16 | - Build your digital portfolio 17 | - Grow your professional network 18 | - Give back to the tech community 19 | 20 | ## How You Can Contribute? 21 | 22 | Here are some ideas to get you started with contributing to the Code Cool Stuff with Python project: 23 | 24 | - **Coding errors**: If you spot a bug then open up an issue discussing it before submitting a pull request. 25 | - **Write better explanations**: If you feel that something can be explained better or that more details are needed. 26 | - **Start a STEM meetup**: Share the wonders of technology by teaching a programming language like python. Read [EDUCATORS.MD](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/EDUCATORS.md) for ideas on how to get started along with the resources. 27 | - **Translations**: If you can speak more than one language and are interested in translating Code Cool Stuff with Python read [TRANSLATIONS.MD](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/TRANSLATIONS.md). 28 | - **Typographical/grammatical errors**: Self explanatory. 29 | 30 | Never contributed to an open source project before? Here’s a [succinct guide](https://gist.github.com/MarcDiethelm/7303312) on how to get started. 31 | 32 | Make sure to read the [code of conduct](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/CODE_OF_CONDUCT.md) before contributing to the Code Cool Stuff with Python project. 33 | -------------------------------------------------------------------------------- /EDUCATORS.md: -------------------------------------------------------------------------------- 1 | ## For Educators and Meet up Organizers: Slide decks and PDFs 2 | 3 | *Give a Man a Fish, and You Feed Him for a Day. Teach a Man to Fish, and You Feed Him for a Lifetime.* 4 | 5 | Python is an excellent language for *coding-virgins*. It has an English-like syntax, a wide spectrum of applicability, and a large community which makes accessing online support trivial. By helping others learn how to code you can equip them with a skill set that could help them unlock the potential of computers. 6 | 7 | You also help deepen your mastery of coding and will be on the path to further enlightenment. I want to encourage others to get involved with spreading the knowledge of coding so you have my permission to use my course as a template for your teachings. The only caveat is that the teachings must be free. Here’s a prospective 5-week FAST TRACK course that you can offer. 8 | 9 | | Week | Title | Slide Deck | PDF 10 | |--|--|--|--| 11 | |One | A Merry Overview of The Python programming Language | [Slide Deck](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/slidedecks/01_A_Merry_Overview_Of_Python.pptx) | [PDF](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/pdfs/01_A_Merry_Overview_Of_Python_PDF.pdf) | 12 | |Two | Crafting Small Scripts, Converters, and Practical Tools in Python| [Slide Deck](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/slidedecks/02_Crafting_Small_Scripts_Converters_Practical_Tools.pptx) | [PDF](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/pdfs/02_Crafting_Small_Scripts,_Converters_Practical_Tools_PDF.pdf) | 13 | |Three | How to Unlock the Power of Randomization to Create Intriguing Scripts in Python | [Slide Deck](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/slidedecks/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python.pptx) | [PDF](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/pdfs/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python_PDF.pdf)| 14 | |Four | Crafting Catchy Computer Art with Python Turtle | [Slide Deck](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/slidedecks/04_Crafting_Catchy_Computer_Art_With_Python.pptx) | [PDF](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/pdfs/04_Crafting_Catchy_Computer_Art_with_Python_Turtle_PDF.pdf) | 15 | |Five | Building Practical Desktop apps in Python Using the Core Tkinter Library |[Slide Deck](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/slidedecks/05_Building_Practical_Desktop_Apps_Tkinter.pptx) | [PDF](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/media/pdfs/05_Building_Practical_Desktop_apps_in_Python_Using_the_Core_Tkinter_Library_PDF.pdf) | 16 | 17 | ## The best way to support this project is to [purchase a digital copy](https://www.amazon.com/Code-Cool-Stuff-Python-Purcell-ebook/dp/B081XJMNRB) on Amazon and leave a review. 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | License: 2 | 3 | Creative Commons Legal Code 4 | 5 | Attribution-NonCommercial 3.0 Unported 6 | 7 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 8 | LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN 9 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 10 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 11 | REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR 12 | DAMAGES RESULTING FROM ITS USE. 13 | 14 | License 15 | 16 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE 17 | COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY 18 | COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS 19 | AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 20 | 21 | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE 22 | TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY 23 | BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS 24 | CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND 25 | CONDITIONS. 26 | 27 | 1. Definitions 28 | 29 | a. "Adaptation" means a work based upon the Work, or upon the Work and 30 | other pre-existing works, such as a translation, adaptation, 31 | derivative work, arrangement of music or other alterations of a 32 | literary or artistic work, or phonogram or performance and includes 33 | cinematographic adaptations or any other form in which the Work may be 34 | recast, transformed, or adapted including in any form recognizably 35 | derived from the original, except that a work that constitutes a 36 | Collection will not be considered an Adaptation for the purpose of 37 | this License. For the avoidance of doubt, where the Work is a musical 38 | work, performance or phonogram, the synchronization of the Work in 39 | timed-relation with a moving image ("synching") will be considered an 40 | Adaptation for the purpose of this License. 41 | b. "Collection" means a collection of literary or artistic works, such as 42 | encyclopedias and anthologies, or performances, phonograms or 43 | broadcasts, or other works or subject matter other than works listed 44 | in Section 1(f) below, which, by reason of the selection and 45 | arrangement of their contents, constitute intellectual creations, in 46 | which the Work is included in its entirety in unmodified form along 47 | with one or more other contributions, each constituting separate and 48 | independent works in themselves, which together are assembled into a 49 | collective whole. A work that constitutes a Collection will not be 50 | considered an Adaptation (as defined above) for the purposes of this 51 | License. 52 | c. "Distribute" means to make available to the public the original and 53 | copies of the Work or Adaptation, as appropriate, through sale or 54 | other transfer of ownership. 55 | d. "Licensor" means the individual, individuals, entity or entities that 56 | offer(s) the Work under the terms of this License. 57 | e. "Original Author" means, in the case of a literary or artistic work, 58 | the individual, individuals, entity or entities who created the Work 59 | or if no individual or entity can be identified, the publisher; and in 60 | addition (i) in the case of a performance the actors, singers, 61 | musicians, dancers, and other persons who act, sing, deliver, declaim, 62 | play in, interpret or otherwise perform literary or artistic works or 63 | expressions of folklore; (ii) in the case of a phonogram the producer 64 | being the person or legal entity who first fixes the sounds of a 65 | performance or other sounds; and, (iii) in the case of broadcasts, the 66 | organization that transmits the broadcast. 67 | f. "Work" means the literary and/or artistic work offered under the terms 68 | of this License including without limitation any production in the 69 | literary, scientific and artistic domain, whatever may be the mode or 70 | form of its expression including digital form, such as a book, 71 | pamphlet and other writing; a lecture, address, sermon or other work 72 | of the same nature; a dramatic or dramatico-musical work; a 73 | choreographic work or entertainment in dumb show; a musical 74 | composition with or without words; a cinematographic work to which are 75 | assimilated works expressed by a process analogous to cinematography; 76 | a work of drawing, painting, architecture, sculpture, engraving or 77 | lithography; a photographic work to which are assimilated works 78 | expressed by a process analogous to photography; a work of applied 79 | art; an illustration, map, plan, sketch or three-dimensional work 80 | relative to geography, topography, architecture or science; a 81 | performance; a broadcast; a phonogram; a compilation of data to the 82 | extent it is protected as a copyrightable work; or a work performed by 83 | a variety or circus performer to the extent it is not otherwise 84 | considered a literary or artistic work. 85 | g. "You" means an individual or entity exercising rights under this 86 | License who has not previously violated the terms of this License with 87 | respect to the Work, or who has received express permission from the 88 | Licensor to exercise rights under this License despite a previous 89 | violation. 90 | h. "Publicly Perform" means to perform public recitations of the Work and 91 | to communicate to the public those public recitations, by any means or 92 | process, including by wire or wireless means or public digital 93 | performances; to make available to the public Works in such a way that 94 | members of the public may access these Works from a place and at a 95 | place individually chosen by them; to perform the Work to the public 96 | by any means or process and the communication to the public of the 97 | performances of the Work, including by public digital performance; to 98 | broadcast and rebroadcast the Work by any means including signs, 99 | sounds or images. 100 | i. "Reproduce" means to make copies of the Work by any means including 101 | without limitation by sound or visual recordings and the right of 102 | fixation and reproducing fixations of the Work, including storage of a 103 | protected performance or phonogram in digital form or other electronic 104 | medium. 105 | 106 | 2. Fair Dealing Rights. Nothing in this License is intended to reduce, 107 | limit, or restrict any uses free from copyright or rights arising from 108 | limitations or exceptions that are provided for in connection with the 109 | copyright protection under copyright law or other applicable laws. 110 | 111 | 3. License Grant. Subject to the terms and conditions of this License, 112 | Licensor hereby grants You a worldwide, royalty-free, non-exclusive, 113 | perpetual (for the duration of the applicable copyright) license to 114 | exercise the rights in the Work as stated below: 115 | 116 | a. to Reproduce the Work, to incorporate the Work into one or more 117 | Collections, and to Reproduce the Work as incorporated in the 118 | Collections; 119 | b. to create and Reproduce Adaptations provided that any such Adaptation, 120 | including any translation in any medium, takes reasonable steps to 121 | clearly label, demarcate or otherwise identify that changes were made 122 | to the original Work. For example, a translation could be marked "The 123 | original work was translated from English to Spanish," or a 124 | modification could indicate "The original work has been modified."; 125 | c. to Distribute and Publicly Perform the Work including as incorporated 126 | in Collections; and, 127 | d. to Distribute and Publicly Perform Adaptations. 128 | 129 | The above rights may be exercised in all media and formats whether now 130 | known or hereafter devised. The above rights include the right to make 131 | such modifications as are technically necessary to exercise the rights in 132 | other media and formats. Subject to Section 8(f), all rights not expressly 133 | granted by Licensor are hereby reserved, including but not limited to the 134 | rights set forth in Section 4(d). 135 | 136 | 4. Restrictions. The license granted in Section 3 above is expressly made 137 | subject to and limited by the following restrictions: 138 | 139 | a. You may Distribute or Publicly Perform the Work only under the terms 140 | of this License. You must include a copy of, or the Uniform Resource 141 | Identifier (URI) for, this License with every copy of the Work You 142 | Distribute or Publicly Perform. You may not offer or impose any terms 143 | on the Work that restrict the terms of this License or the ability of 144 | the recipient of the Work to exercise the rights granted to that 145 | recipient under the terms of the License. You may not sublicense the 146 | Work. You must keep intact all notices that refer to this License and 147 | to the disclaimer of warranties with every copy of the Work You 148 | Distribute or Publicly Perform. When You Distribute or Publicly 149 | Perform the Work, You may not impose any effective technological 150 | measures on the Work that restrict the ability of a recipient of the 151 | Work from You to exercise the rights granted to that recipient under 152 | the terms of the License. This Section 4(a) applies to the Work as 153 | incorporated in a Collection, but this does not require the Collection 154 | apart from the Work itself to be made subject to the terms of this 155 | License. If You create a Collection, upon notice from any Licensor You 156 | must, to the extent practicable, remove from the Collection any credit 157 | as required by Section 4(c), as requested. If You create an 158 | Adaptation, upon notice from any Licensor You must, to the extent 159 | practicable, remove from the Adaptation any credit as required by 160 | Section 4(c), as requested. 161 | b. You may not exercise any of the rights granted to You in Section 3 162 | above in any manner that is primarily intended for or directed toward 163 | commercial advantage or private monetary compensation. The exchange of 164 | the Work for other copyrighted works by means of digital file-sharing 165 | or otherwise shall not be considered to be intended for or directed 166 | toward commercial advantage or private monetary compensation, provided 167 | there is no payment of any monetary compensation in connection with 168 | the exchange of copyrighted works. 169 | c. If You Distribute, or Publicly Perform the Work or any Adaptations or 170 | Collections, You must, unless a request has been made pursuant to 171 | Section 4(a), keep intact all copyright notices for the Work and 172 | provide, reasonable to the medium or means You are utilizing: (i) the 173 | name of the Original Author (or pseudonym, if applicable) if supplied, 174 | and/or if the Original Author and/or Licensor designate another party 175 | or parties (e.g., a sponsor institute, publishing entity, journal) for 176 | attribution ("Attribution Parties") in Licensor's copyright notice, 177 | terms of service or by other reasonable means, the name of such party 178 | or parties; (ii) the title of the Work if supplied; (iii) to the 179 | extent reasonably practicable, the URI, if any, that Licensor 180 | specifies to be associated with the Work, unless such URI does not 181 | refer to the copyright notice or licensing information for the Work; 182 | and, (iv) consistent with Section 3(b), in the case of an Adaptation, 183 | a credit identifying the use of the Work in the Adaptation (e.g., 184 | "French translation of the Work by Original Author," or "Screenplay 185 | based on original Work by Original Author"). The credit required by 186 | this Section 4(c) may be implemented in any reasonable manner; 187 | provided, however, that in the case of a Adaptation or Collection, at 188 | a minimum such credit will appear, if a credit for all contributing 189 | authors of the Adaptation or Collection appears, then as part of these 190 | credits and in a manner at least as prominent as the credits for the 191 | other contributing authors. For the avoidance of doubt, You may only 192 | use the credit required by this Section for the purpose of attribution 193 | in the manner set out above and, by exercising Your rights under this 194 | License, You may not implicitly or explicitly assert or imply any 195 | connection with, sponsorship or endorsement by the Original Author, 196 | Licensor and/or Attribution Parties, as appropriate, of You or Your 197 | use of the Work, without the separate, express prior written 198 | permission of the Original Author, Licensor and/or Attribution 199 | Parties. 200 | d. For the avoidance of doubt: 201 | 202 | i. Non-waivable Compulsory License Schemes. In those jurisdictions in 203 | which the right to collect royalties through any statutory or 204 | compulsory licensing scheme cannot be waived, the Licensor 205 | reserves the exclusive right to collect such royalties for any 206 | exercise by You of the rights granted under this License; 207 | ii. Waivable Compulsory License Schemes. In those jurisdictions in 208 | which the right to collect royalties through any statutory or 209 | compulsory licensing scheme can be waived, the Licensor reserves 210 | the exclusive right to collect such royalties for any exercise by 211 | You of the rights granted under this License if Your exercise of 212 | such rights is for a purpose or use which is otherwise than 213 | noncommercial as permitted under Section 4(b) and otherwise waives 214 | the right to collect royalties through any statutory or compulsory 215 | licensing scheme; and, 216 | iii. Voluntary License Schemes. The Licensor reserves the right to 217 | collect royalties, whether individually or, in the event that the 218 | Licensor is a member of a collecting society that administers 219 | voluntary licensing schemes, via that society, from any exercise 220 | by You of the rights granted under this License that is for a 221 | purpose or use which is otherwise than noncommercial as permitted 222 | under Section 4(c). 223 | e. Except as otherwise agreed in writing by the Licensor or as may be 224 | otherwise permitted by applicable law, if You Reproduce, Distribute or 225 | Publicly Perform the Work either by itself or as part of any 226 | Adaptations or Collections, You must not distort, mutilate, modify or 227 | take other derogatory action in relation to the Work which would be 228 | prejudicial to the Original Author's honor or reputation. Licensor 229 | agrees that in those jurisdictions (e.g. Japan), in which any exercise 230 | of the right granted in Section 3(b) of this License (the right to 231 | make Adaptations) would be deemed to be a distortion, mutilation, 232 | modification or other derogatory action prejudicial to the Original 233 | Author's honor and reputation, the Licensor will waive or not assert, 234 | as appropriate, this Section, to the fullest extent permitted by the 235 | applicable national law, to enable You to reasonably exercise Your 236 | right under Section 3(b) of this License (right to make Adaptations) 237 | but not otherwise. 238 | 239 | 5. Representations, Warranties and Disclaimer 240 | 241 | UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR 242 | OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY 243 | KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, 244 | INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, 245 | FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF 246 | LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, 247 | WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION 248 | OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 249 | 250 | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE 251 | LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR 252 | ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES 253 | ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS 254 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 255 | 256 | 7. Termination 257 | 258 | a. This License and the rights granted hereunder will terminate 259 | automatically upon any breach by You of the terms of this License. 260 | Individuals or entities who have received Adaptations or Collections 261 | from You under this License, however, will not have their licenses 262 | terminated provided such individuals or entities remain in full 263 | compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will 264 | survive any termination of this License. 265 | b. Subject to the above terms and conditions, the license granted here is 266 | perpetual (for the duration of the applicable copyright in the Work). 267 | Notwithstanding the above, Licensor reserves the right to release the 268 | Work under different license terms or to stop distributing the Work at 269 | any time; provided, however that any such election will not serve to 270 | withdraw this License (or any other license that has been, or is 271 | required to be, granted under the terms of this License), and this 272 | License will continue in full force and effect unless terminated as 273 | stated above. 274 | 275 | 8. Miscellaneous 276 | 277 | a. Each time You Distribute or Publicly Perform the Work or a Collection, 278 | the Licensor offers to the recipient a license to the Work on the same 279 | terms and conditions as the license granted to You under this License. 280 | b. Each time You Distribute or Publicly Perform an Adaptation, Licensor 281 | offers to the recipient a license to the original Work on the same 282 | terms and conditions as the license granted to You under this License. 283 | c. If any provision of this License is invalid or unenforceable under 284 | applicable law, it shall not affect the validity or enforceability of 285 | the remainder of the terms of this License, and without further action 286 | by the parties to this agreement, such provision shall be reformed to 287 | the minimum extent necessary to make such provision valid and 288 | enforceable. 289 | d. No term or provision of this License shall be deemed waived and no 290 | breach consented to unless such waiver or consent shall be in writing 291 | and signed by the party to be charged with such waiver or consent. 292 | e. This License constitutes the entire agreement between the parties with 293 | respect to the Work licensed here. There are no understandings, 294 | agreements or representations with respect to the Work not specified 295 | here. Licensor shall not be bound by any additional provisions that 296 | may appear in any communication from You. This License may not be 297 | modified without the mutual written agreement of the Licensor and You. 298 | f. The rights granted under, and the subject matter referenced, in this 299 | License were drafted utilizing the terminology of the Berne Convention 300 | for the Protection of Literary and Artistic Works (as amended on 301 | September 28, 1979), the Rome Convention of 1961, the WIPO Copyright 302 | Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 303 | and the Universal Copyright Convention (as revised on July 24, 1971). 304 | These rights and subject matter take effect in the relevant 305 | jurisdiction in which the License terms are sought to be enforced 306 | according to the corresponding provisions of the implementation of 307 | those treaty provisions in the applicable national law. If the 308 | standard suite of rights granted under applicable copyright law 309 | includes additional rights not granted under this License, such 310 | additional rights are deemed to be included in the License; this 311 | License is not intended to restrict the license of any rights under 312 | applicable law. 313 | 314 | 315 | Creative Commons Notice 316 | 317 | Creative Commons is not a party to this License, and makes no warranty 318 | whatsoever in connection with the Work. Creative Commons will not be 319 | liable to You or any party on any legal theory for any damages 320 | whatsoever, including without limitation any general, special, 321 | incidental or consequential damages arising in connection to this 322 | license. Notwithstanding the foregoing two (2) sentences, if Creative 323 | Commons has expressly identified itself as the Licensor hereunder, it 324 | shall have all rights and obligations of Licensor. 325 | 326 | Except for the limited purpose of indicating to the public that the 327 | Work is licensed under the CCPL, Creative Commons does not authorize 328 | the use by either party of the trademark "Creative Commons" or any 329 | related trademark or logo of Creative Commons without the prior 330 | written consent of Creative Commons. Any permitted use will be in 331 | compliance with Creative Commons' then-current trademark usage 332 | guidelines, as may be published on its website or otherwise made 333 | available upon request from time to time. For the avoidance of doubt, 334 | this trademark restriction does not form part of the License. 335 | 336 | -------------------------------------------------------------------------------- /TRANSLATIONS.md: -------------------------------------------------------------------------------- 1 | ## TRANSLATIONS 2 | 3 | Thanks for the interest in translating *Code Cool Stuff with Python*. 4 | 5 | Before you start translating a document you can first open a [pull request](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/pulls) to see if anyone has already started working on a translation in your language. 6 | 7 | If not then today is the day for you to spearhead the translation project! Here are the steps to translating *Code Cool Stuff with Python*: 8 | 9 | 1) Fork the repository. 10 | 2) Create a new branch for your translation. For example, if you’re translating the guide into German use `de`. 11 | 3) Translate the files in `/book`. 12 | 4) When you have at least the first chapter translated, go ahead and push it. For example, the path of the German translation repo should look like the following: `Code-Cool-Stuff-With-Python/de/book` 13 | 14 | Translating a book is a large project, so you’re more than welcome to break the process into parts. I’ll recommend working on a chapter at a time and then push what you got into the master branch. 15 | 16 | If someone has already started a translation project and you would like to contribute then go to the project page, open up an issue, and ask how you can contribute. Ideally, multiple translators can work on a single translation project in an organized state. 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /book/chapter_02.md: -------------------------------------------------------------------------------- 1 | 2 | ## Chapter II: Crafting Small Scripts, Converters, and Practical Tools in Python 3 | 4 | In this chapter we’ll learn how to build some simple yet cool python scripts that can be ran through the command line. We will learn how to make scripts that asks the user a series of questions and then process the input to do various tasks such as converting the temperature to different units, computing auto loans, and handy translators. 5 | 6 | # **Project: Your Biography** 7 | 8 | Let’s write a program that creates a biography for us. One way to do this is to ask a series of probing questions. Some questions that you may want to answer are things like: 9 | 10 | - first name 11 | 12 | - last name 13 | 14 | - nationally 15 | 16 | - birth place 17 | 18 | - age 19 | 20 | - height: 21 | 22 | - feet 23 | 24 | - inches 25 | 26 | - weight (in pounds) 27 | 28 | - favorite food 29 | 30 | - favorite city 31 | 32 | We won’t use this for a dating app, we just want to use this exercise as a means to explore some of the possibilities of python ;). You can add on any additional questions you want. 33 | 34 | ## Script Hints 35 | 36 | In order to create this script follow the steps: 37 | 38 | 1) In PyCharm go to the directory where you’ll place all of your programs. Right-click on the directory and select: New → Python File. Enter the name of the python file as _bio.py._ 39 | 40 | 2) In the PyCharm editor add a function named questions. Inside the function is where all of the statements for your logic to go inside. You can use the input function to read in text form the terminal. If you need to read in an int or a float then you can pass the input function into the int or float functions. For example, the following will read in a float from the terminal: 41 | 42 | weight = float(input('Enter weight in lbs: ')) 43 | 44 | To view a list of the builtin functions in python check out this url: [https://docs.python.org/3/library/functions.html](https://docs.python.org/3/library/functions.html) 45 | 46 | 3) Include the following code snippet after the questions function: 47 | 48 | if __name__ == '__main__': 49 | # this is where your program starts 50 | questions() 51 | 52 | This lets the python interpreter know where to start at. In every python file there’s a __name__ variable that’s set equal to __main__. Therefore, if your file explicitly includes this then it will tell the python interpreter to start here. Below is a template to how your python file will look: 53 | 54 | 55 | def questions(): 56 | """This is the part of the program that prompts the user""" 57 | 58 | if __name__ == '__main__': 59 | # this is the entry point to the program 60 | questions() 61 | 62 | One of the tricky things that you may want to look out for is how to read in multiple user input in a single statement. For example, reading in a single int or string is easy because you can do something like this: 63 | 64 |
65 | 66 | >>> temperature = int(input('Temp today:')) 67 | 68 | ... 69 | 70 | Temp today:75 71 | 72 | >>> color = input('The color:') 73 | ... 74 | 75 | The color:blue 76 |77 | 78 | However, what if you want the user to enter in two inputs so that you can store the data in feet and inches? One way to do that is to use the builtin string method called split. This will split the text around a certain character like a comma. 79 | 80 | ## Solution 81 | 82 | Below is a sample solution. Your script may have more or less questions, it really depends on how you want to create it. 83 | 84 | 85 | def questions(): 86 | """This is the part of the program that prompts the user 87 | for a bunch of questions.""" 88 | first_name = input('Enter your first name: ').capitalize() 89 | last_name = input('Enter your last name: ').capitalize() 90 | nationality = input('Enter your nationality: ').capitalize() 91 | age = int(input('Enter your age: ')) 92 | height = input('Enter feet and inches separated by commas: ') 93 | user_input = height.split(',') 94 | heights = user_input[0], user_input[1] 95 | weight = float(input('Enter weight in lbs: ')) 96 | favorite_food = input('Enter your favorite food: ').capitalize() 97 | favorite_city = input('Enter in your favorite city: ').capitalize() 98 | print() 99 | 100 | print('First name: {}'.format(first_name)) 101 | print('Last name: {}'.format(last_name)) 102 | print('Nationality: {}'.format(nationality)) 103 | print('Age: {}'.format(age)) 104 | print('Height: {} ft {} in'.format(user_input[0], user_input[1])) 105 | print('Weight: {}'.format(weight)) 106 | print('Favorite food: {}'.format(favorite_food)) 107 | print('Favorite city: {}'.format(favorite_city)) 108 | 109 | if __name__ == '__main__': 110 | # this is where your program starts 111 | questions() 112 | 113 |
114 | 115 | print('First name: {}'.format(first_name)) 116 | 117 | print('Last name: {}'.format(last_name)) 118 | 119 | print('Nationality: {}'.format(nationality)) 120 | 121 | print('Age: {}'.format(age)) 122 | 123 | print('Height: {} ft {} in'.format(user_input[0], user_input[1])) 124 | 125 | print('Weight: {}'.format(weight)) 126 | 127 | print('Favorite food: {}'.format(favorite_food)) 128 | 129 | print('Favorite city: {}'.format(favorite_city)) 130 |131 | 132 | 133 | if __name__ == '__main__': 134 | 135 | # this is where your program starts 136 | 137 | questions() 138 | 139 |
140 | 141 | Sample input: 142 | 143 | Enter your first name: danny 144 | 145 | Enter your last name: hill 146 | 147 | Enter your nationality: american 148 | 149 | Enter your age: 47 150 | 151 | Enter feet and inches separated by commas: 5, 5 152 | 153 | Enter weight in lbs: 200 154 | 155 | Enter your favorite food: pizza 156 | 157 | Enter in your favorite city: philadelphia 158 | 159 | Sample output: 160 | 161 | First name: Danny 162 | 163 | Last name: Hill 164 | 165 | Nationality: American 166 | 167 | Age: 47 168 | 169 | Height: 5 ft 5 in 170 | 171 | Weight: 200.0 172 | 173 | Favorite food: Pizza 174 | 175 | Favorite city: Philadelphia 176 |177 | 178 | You can run the file by opening up the terminal or command prompt and typing in the following: 179 | 180 | $ python bio.py 181 | 182 | # **Project: Temperature Converter** 183 | 184 | 185 | The world is not singular. There’s many different types to something and this can vary from country to even region. Let’s focus our attention on converters; there’s many of these online and Google has a massive amount that you can trigger by just entering specific queries into the search box: [https://support.google.com/websearch/answer/3284611?hl=en](https://support.google.com/websearch/answer/3284611?hl=en) 186 | 187 | The advantage that you have as a python programmer is that you can also add new features, create updates, and write a new script for something you can’t find online. That’s the beauty about knowing how to code, _you now have a new world of possibilities_. 188 | 189 | There’s three commonly used scales for measuring temperature: Celsius (°C), Fahrenheit (°F), and Kelvin (K). Celsius is used by all the countries except United States, Bahamas, Belize, Cayman Islands, and Liberia. Americans that travel abroad will probably have to go through a phase in which they have to adjust to reading temperature in Celsius… I know I did! 190 | 191 | Kelvin is the unit of measurement used in the International System of Units (SI). The Kelvin scale is also heavily used in science and technology. Let’s create a script that can convert all of the temperature units to each other and back. In order to do this we must need to know the mathematical formulas. Luckily, they’re simple: 192 | 193 | - F -> C = (F - 32) x 5/9 194 | 195 | - F -> K = (F - 32)/1.8 + 273.15 196 | 197 | - C -> F = (C x 9/5) + 32 198 | 199 | - C -> K = C + 273.15 200 | 201 | - K -> F = (K - 273.15) x 9/5 + 32 202 | 203 | - K -> C = K - 273.15 204 | 205 | 206 | With the above knowledge you can proceed to write your temperature conversion script. Sometimes the first step is the most difficult one to take. Here’s some tips to get started. 207 | 208 | ## Script Hints 209 | 210 | 211 | We can create the function names and just include the pass statement so that the code doesn’t do nothing yet. Here’s the name of the functions: 212 | 213 | `fahrenheit_to_celsius`: Converts the user input from Fahrenheit to Celsius. 214 | 215 | `fahrenheit_to_kelvin`: Converts the user input from Fahrenheit to Kelvin. 216 | 217 | `celsius_to_fahrenheit`: Converts the user input from Celsius to Fahrenheit. 218 | 219 | `celsius_to_kelvin`: Converts the user input from Celsius to Kelvin. 220 | 221 | `kelvin_to_fahrenheit`: Converts the user input from Kelvin to Fahrenheit. 222 | 223 | `kelvin_to_celsius`: Converts the user input from Kelvin to Celsius. 224 | 225 | `fahrenheit_to_celsius`: Converts the user input from Fahrenheit to Celsius. 226 | 227 | Here’s a template of how the script looks: 228 | 229 | def fahrenheit_to_celsius(): 230 | pass 231 | def fahrenheit_to_kelvin(): 232 | pass 233 | def celsius_to_fahrenheit(): 234 | pass 235 | def celsius_to_kelvin(): 236 | pass 237 | def kelvin_to_fahrenheit(): 238 | pass 239 | def kelvin_to_celsius(): 240 | pass 241 | 242 | if __name__ == '__main__': 243 | pass 244 | 245 | 246 | ## Solution 247 | 248 | 249 | Below is one solution: 250 | 251 | def fahrenheit_to_celsius(): 252 | temp_in_fahren = float(input('Enter the temperature in Fahrenheit ')) 253 | celsius = (temp_in_fahren - 32) * 5/9 254 | celsius = round(celsius, 4) 255 | print(celsius, '°C') 256 | def fahrenheit_to_kelvin(): 257 | temp_in_fahren = float(input('Enter the temperature in Kelvin ')) 258 | kelvin = (temp_in_fahren - 32) / 1.8 + 273.15 259 | print(kelvin, 'K') 260 | def celsius_to_fahrenheit(): 261 | temp_in_celsius = float(input('Enter the temperature in Celsius ')) 262 | celsius_to_fahren = (temp_in_celsius * 9/5) + 32 263 | print(celsius_to_fahren, '°F') 264 | def celsius_to_kelvin(): 265 | temp_in_cel = float(input('Enter the temperature in Celsius ')) 266 | celsius_to_kel = (temp_in_cel + 273.15) 267 | print(celsius_to_kel, 'K') 268 | def kelvin_to_fahrenheit(): 269 | temp_in_kelvin = float(input('Enter the temperature in Kelvin ')) 270 | kelvin_to_fahren = (temp_in_kelvin - 273.15) * 9/5 + 32 271 | kelvin_to_fahren = round(kelvin_to_fahren, 3) 272 | print(kelvin_to_fahren, '°F') 273 | def kelvin_to_celsius(): 274 | temp_in_kelvin = float(input('Enter the temperature in Kelvin ')) 275 | kelvin_to_cel = temp_in_kelvin - 273.15 276 | kelvin_to_cel = round(kelvin_to_cel, 3) 277 | print(kelvin_to_cel, '°C') 278 | 279 | if __name__ == '__main__': 280 | message = input("""Select one of the following options: 281 | 282 | Type 'fc' to convert from Fahrenheit to Celsius. 283 | Type 'fk' to convert from Fahrenheit to Kelvin. 284 | Type 'cf' to convert from Celsius to Fahrenheit. 285 | Type 'ck' to convert from Celsius to Kelvin. 286 | Type 'kf' to convert from Kelvin to Fahrenheit. 287 | Type 'kc' to convert from Kelvin to Celsius. 288 | 289 | Enter input here: 290 | """) 291 | 292 | # casefold is for case-insensitive comparisons 293 | 294 | message = message.casefold() 295 | if message == 'fc': 296 | fahrenheit_to_celsius() 297 | elif message == 'fk': 298 | fahrenheit_to_kelvin() 299 | elif message == 'cf': 300 | celsius_to_fahrenheit() 301 | elif message == 'ck': 302 | celsius_to_kelvin() 303 | elif message == 'kf': 304 | kelvin_to_fahrenheit() 305 | elif message == 'kc': 306 | kelvin_to_celsius() 307 | else: 308 | print('Not a valid option pal!') 309 | 310 | You can download the script from GitHub: [https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/temp_converter.py](https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/temp_converter.py) 311 | 312 | When the program runs it should display a message to show the user how to use the script. We’ve created a command line script so therefore some instructions on how to use it is a good start. To do this simply create a message in the form of a string and display it. 313 | 314 | We could of used single print statements, but I’ve opted to use a string that’s wrapped in triple quotes for this as this style of strings will make it so that we don’t have to worry about escaping characters like apostrophes. I’m referring to this segment of the code: 315 | 316 | if __name__ == '__main__': 317 | message = input("""Select one of the following options: 318 | 319 | Type 'fc' to convert from Fahrenheit to Celsius. 320 | Type 'fk' to convert from Fahrenheit to Kelvin. 321 | Type 'cf' to convert from Celsius to Fahrenheit. 322 | Type 'ck' to convert from Celsius to Kelvin. 323 | Type 'kf' to convert from Kelvin to Fahrenheit. 324 | Type 'kc' to convert from Kelvin to Celsius. 325 | 326 | Enter input here: 327 | """) 328 | 329 | When writing command line scripts we always want to make it easy for the user to enter in text. For i.e, if the user entered FC then this will not match the condition if message == ‘fc’ and therefore the program will evaluate to False. However, with the assistance of the casefold method all of these cases are evaluated so it doesn’t matter what case the user enters. 330 | 331 | # **Project: Auto loan Calculator** 332 | 333 | Cars are incredible mechanical inventions. Something they can be driven for countless of miles and still function properly is quite amazing. Like many quality things in life it costs money so in this project we’re going to code a useful script that will help us make better purchasing decisions when deciding on a new car. The script will have two parts: one, how many months it will take to pay off the loan and two, what’s the total interest paid accumulated over that period of time. Here’s some formulas to get started: 334 | 335 | A = P x (1 + r) ^N / (1 + r)^N – 1 336 | 337 | Formula for calculating the accrued interest: 338 | 339 | A = P(1 + rt) 340 | 341 | The first formula looks tricky but it’s simple once you know what all of the variables represent. Here’s a quick overview: 342 | 343 | - P = Principal or the amount owned on a loan. 344 | 345 | - A = Total accrued amount (principal + interest). 346 | 347 | - r = Rate of interest per year as a decimal, or interest rate / 100. 348 | 349 | - N = Number of months in the loan period. 350 | 351 | 352 | If you were to go into an auto company’s finance department then this is the same formula that they’ll use to determine your monthly car payments. In the second formula, p(1 + rt), _t_ represents the number of months on the loan like _n_, it’s just that by using _r_ and _n_ together (rn) that it would be more difficult to read. 353 | 354 | ## Script Hints 355 | 356 | Create a function that calculates the monthly cost. You can break down the formula in order to minimize the chances of making a mistake. This reduces syntax errors and makes debugging potential arithmetic errors more straightforward. 357 | 358 | ## Solution 359 | 360 | 361 | Below is one solution to the problem: 362 | 363 | def monthly_cost(): 364 | print('Gotta couple of questions for you...') 365 | p = float(input('Enter loan amount ')) 366 | r = float(input('Enter interest rate (%)')) 367 | n = int(input('Enter loan period (in months)')) 368 | # convert r to a decimal and divide by interest per year 369 | r = (r / 100) / 12 370 | # breaks formula down into 3 parts to reduce error 371 | # numerator 372 | top = r * (1 + r)**n 373 | # denominator 374 | bottom = ((1 + r)**n) - 1 375 | # putting it all together 376 | a = round(p * (top / bottom)) 377 | # use simple interest formula 378 | # I = Prt 379 | # In this case, I = Prn 380 | total_interest = round(p * r * n, 3) 381 | print(f'Monthly costs = ${a}. Total interest = ${total_interest} ') 382 | if __name__ == '__main__': 383 | monthly_cost() 384 | 385 | Here’s a quick breakdown of what’s happening: 386 | 387 | 1) The user input is requested and stored in the variables of p, n, and r. 388 | 389 | 2) Once the user input is collected, the mathematics is done on separate statements to minimize errors. For example, the value of r is calculated on one line, and instead of trying to translate the mathematical formula to python code on a single line, the numerator and denominator is calculated in separate statements and then combined in this statement: 390 | 391 | a = round(p * (top / bottom)) 392 | 393 | If you have lot’s of experience in python then doing everything in a single statement may be trivial. However, if you’re new to the language then the important thing is to get the script to work as you can refactor (restructure) the code later. 394 | 395 | The auto loan calculator script on GitHub: [https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/auto_loan_calculator.py](https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/auto_loan_calculator.py) 396 | 397 | # **Project: Mortgage Calculator** 398 | 399 | 400 | Getting a house is the American dream, but to obtain a dream does cost. In this exercise we’re going to create a script that calculates the monthly payment that someone owes on a house. When one takes out a loan for a house this is known as a mortgage. 401 | 402 | Mortgage calculators can get pretty complex, so in this exercise we’re going to _stupify_ the process so that we just calculate the monthly payments and total mortgage that one would owe contingent on some variables. These variables are: 403 | 404 | - **Mortgage period**: How long the mortgage will last in years. 405 | 406 | - **Principal**: The amount of money owed on the loan. 407 | 408 | - **Interest rate**: The percentage of principal charged by the lender for the use of their money. 409 | 410 | 411 | ## Script Hints 412 | 413 | After digging around here’s the formula that you can use to calculate the monthly payments on a house: 414 | 415 | - p x r (1 + r) ^ N / (1 + r) ^ N - 1 416 | 417 | 418 | Put together a python script that prompts the user for their name, principal, interest rate, and then outputs the monthly payment and the total interest a homeowner would pay. 419 | 420 | ## Solution: 421 | 422 | def mortgage(): 423 | name = input('Enter your name ').capitalize() 424 | print(f"Time to calculate your mortgage payments {name}... ") 425 | principal = float(input('Enter in your principal ')) 426 | interest_rate = float(input('Enter interest rate ')) 427 | r = (interest_rate / 100) / 12 428 | n = int(input('Enter mortgage period (years) ')) 429 | # get total number of months 430 | n = n * 12 431 | numerator = r * (1 + r) ** n 432 | deno = (1 + r) ** n - 1 433 | monthly_payment = principal * (numerator / deno) 434 | monthly_payment = round(monthly_payment) 435 | total_mortgage = monthly_payment * 30 * 12 436 | print(f'Monthly payment: ${monthly_payment}, total mortgage = ${total_mortgage}') 437 | 438 | if __name__ == '__main__': 439 | mortgage() 440 | 441 | This script is very similar to the auto loan script except that the formula varies: 442 | 443 | - The variables of principal, interest rate, r, and n are prompted from the user. 444 | 445 | - The numerator and denominator of the function is calculated separately and then combined together at the end to emulate the formula: p x r (1 + r) ^ N / (1 + r) ^ N – 1 446 | 447 | - Once the total monthly payment is calculated, the total mortgage is computed by taking the monthly payment and multiplying it by 30 and 12. The reason for this is because there’s roughly 30 days in a month, and 12 months in a year. 448 | 449 | Language translation is a complicated art. Even online translation tools created by teams of talented engineers at behemoth tech companies miss structural and linguistic elements in their translations. Therefore, to serve as a learning project we’re going to simplify the process and focus on a narrow domain of words and phases to transliterate. 450 | 451 | Not only is this a good exercise to gain more familiarity with data structures, strings, and conditional statements, it’s also a good exercise for gaining more comfort with loops in python. So, to simplify the process create a python script that focuses on translating foods and general phrases. 452 | 453 | ## Script Hints 454 | 455 | Here’s an outline of the script: 456 | 457 | 458 | def food(): 459 | pass 460 | 461 | def general_phrases(): 462 | pass 463 | 464 | if __name__ == '__main__': 465 | 466 | print('Bienvenidos! What phases would you like to translate?') 467 | print('1: Common foods ') 468 | print('2: General phases') 469 | your_choice = int(input("Enter your choice: '1' or '2'")) 470 | if your_choice == 1: 471 | food() 472 | elif your_choice == 2: 473 | general_phrases() 474 | else: 475 | print('Not a possible choice!') 476 | 477 | 478 | The list of food items and general phrases that you want to translate is up to you. I would suggest using a dictionary to store the Spanish-to-English and vice-versa mappings, as this data structure is perfectly suited for this type of task. 479 | 480 | Another thing that you may be pondering is how to create the script so that a user could easily use it? The strategy I took was that once the program runs it asks the user a question and then executes the appropriate function contingent on their feedback. Also, you may want to think about a way to normalize the text. 481 | 482 | For example, assume that the user wants to translate Barbacoa into English. What happens if they entered a variant spelling such as _BarBacoa_ or _barbacoa_? We need a way to modify the input so that any variant of the spelling is processed. We can accomplish this by using a builtin string method such as `capitalize` so that the user input is in the same case as the text stored in the dictionaries. 483 | 484 | ## Solution 485 | 486 | 487 | The script contains two functions which are food and `general_phrases`. The food function contains popular Mexican food items written in Spanish, and if the user types that item into the shell then it’s respective English term will be printed. The `general_phrases` function contains a list of common conversation phrases which are translated into English when it’s typed into the shell. Let’s first breakdown the food function as shown below: 488 | 489 | 490 | def food(): 491 | """Names for some popular mexican food items. 492 | Translate spanish food names to english. 493 | """ 494 | print('\n') 495 | spanish_to_english = { 496 | 'Birria': 'Spicy stew made with goat or mutton. ', 497 | 'Quesadilla con carne': 'season steak strips. ', 498 | 'Barbacoa': 'Slow cooked meat in soup. Beef, goat, or sheep.', 499 | 'Burrito Banado': 'Wet Burrito.', 500 | 'Huevos rancheros': '"Rancher\'s eggs." Corn tortillas, fried eggs, topped with warm salsa.', 501 | 'Coctel de camarones': 'Shrimp cocktail served cold with tomato, onion, cucumber, and cilantro. ', 502 | 'Huevos a la mexicana': 'Eggs, tomato, onion, and serrano chile. A classic.', 503 | 'Huevo con Chorizo': 'Eggs and chorizo sausage.', 504 | 'Burritos de Desayuno ': 'Breakfast burrito.', 505 | 'Chilli con carne': 'Chili with meat.', 506 | 'Lengua': 'Beef tongue, typically in tacos.', 507 | 'Tripas': 'Small intestines of farm animals that\'s cleaned, boiled, and grilled. ', 508 | 'Al pastor': 'Pork based taco based on shawarma', 509 | 'Suadero': 'Tender slow cooked beef brisket. Typically served in tacos.', 510 | 'Cabeza': 'Beef head/cheek meat. Served in soups or tacos.', 511 | 'Sesos': 'Brains from either a goat or cow. Popular taco filling.' 512 | } 513 | 514 | print('Spanish phases available for translation:') 515 | for spanish, english in spanish_to_english.items(): 516 | print(spanish) 517 | 518 | print() 519 | translate = input('Type in spanish phase you\'ll like to translate: ').capitalize() 520 | for english, spanish in spanish_to_english.items(): 521 | if translate == english: 522 | print(spanish_to_english.get(translate)) 523 | break 524 | else: 525 | print('Word is not available for translation') 526 | 527 | 528 | This code can be broken down into a couple of parts. The `spanish_to_english` dictionary contains a mapping of Mexican dishes and their explanation in English. The for loop iterates over the dictionary and then prints the Spanish words. 529 | 530 | The user input is requested for the Mexican dish that they would like a to translate into English. A for loop is used that iterates over the dictionary and then a conditional check is utilized to see if the user input matches any of the items in the dictionary. If it is then the English explanation is printed, and if not then a default message is printed letting the user know that the word is not available for translation. 531 | 532 | Identical logic is used for general_phrases with the exception that the dictionary contains mappings of English to Spanish. 533 | 534 | See the complete source code of the Spanish translator script: [https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/spanish_translator.py](https://github.com/purcellconsult/Build-Cool-Stuff-With-Python/blob/master/spanish_translator.py) 535 | 536 | ## Chapter II Recap 537 | 538 | In this chapter we learned how to start building some real-world practical programs. Converters and calculators are some basic programs that you can start writing that allows you to start solving real world problems. If you’ve built a couple of these scripts then this is something that you can show your friends and family to showcase your evolving python programming prowess! 539 | 540 | 541 | ## The best way to support this project is to [purchase a digital copy](https://www.amazon.com/Code-Cool-Stuff-Python-Purcell-ebook/dp/B081XJMNRB) on Amazon and leave a review. 542 | -------------------------------------------------------------------------------- /book/chapter_03.md: -------------------------------------------------------------------------------- 1 | # Chapter III: How to Unlock The Power of Randomization to Create Intriguing Scripts in Python 2 | 3 | _Coin flipping_ is the practice of throwing a coin in the air and checking which side it lands on; just think of the Batman antihero _Two-Face_. Coin flipping is an unbiased way to solve a dispute, and is a solid example of randomization. In this chapter we’ll build three scripts that relies heavily on randomization: A simple dice game, a random person generator, and a lottery simulator. 4 | 5 | Randomization is a phenomena that effects all humans regardless of what walk of life they’re from. Many things are randomly assigned to us such as such as our date of birth, nationally, family, height, and eye color. 6 | 7 | With it’s inherit nonpartisan attributes, randomization is heavily used in statistics, clinical trials, and shuffling cards. 8 | 9 | Randomization is a fascinating somewhat overlooked portion of life, so let’s get more familiar with it by writing some cool python programs. 10 | 11 | # Project: A Game of Dice. Humans vs Randomization 12 | 13 | An object that involves heavy randomization is a dice. This cubic device has a wide array of application such as tabletop games, board games, and of course gambling. A dice can easily be modeled computationally through the use of a _random_ module. Python has a built in one for this which is conveniently named _random_. We’ll create a simple yet elegant game that involved randomization called _A Game of Dice._ 14 | 15 | The user will start with a bank account of $1000 and can keep making wagers on which number the dice will roll on. If the dice falls on the number that the user guesses, then the user gets the money that they wagered, and vice-versa. The game play will continue until the user runs out of money or exits from the game. This is a truly simple game that displays the beauty and the volatile nature of randomness. 16 | 17 | ## Script Hint 18 | 19 | Let’s breakdown the logic: 20 | 21 | - Who goes first? The first question is how to determine which player goes first, the human or the computer? One way is to simulate a coin flip of heads or tails. Both players are allowed to pick which side of the coin they want. If both players both pick the correct side then this process should be repeated until there’s a single winner. 22 | 23 | - How much money will each player start with? What happens when some edge cases arise like a player betting more money than they have, or enters an invalid input like a string? 24 | 25 | - What’s the minimum and maximum amount of rounds allowed? 26 | 27 | - What happens when the player has no more money to bet? 28 | 29 | 30 | ## Solution 31 | 32 | There’s a couple of things to think about when you’re coding the script. For one, we need to generate a seed of numbers within the range of 1-6 that emulates the dice. We then need to figure out how many rounds we want the player to play. Here’s some code to get us started: 33 | 34 | from random import randint 35 | def game(): 36 | print('Welcome! You\'re Playing:') 37 | human_bank = 1000 38 | while True: 39 | you = float(input("How much money do you want to wager? " 40 | "Your bank has ${} ".format(human_bank))) 41 | 42 | The first line simply imports the randint function from the random module. This allows us to generate the seed of numbers to mimic the effect of a dice. Next, a game function is created which holds the bulk of the logic. I’ve decided that I want to indiscriminately decide when to terminate the game-play. 43 | 44 | Therefore, a simple way to do this is to wrap our logic within an indefinite while loop and then include several conditional statements to control the progression of the program. 45 | 46 | Don’t worry about the while loop not having an exiting condition as there’s several ways in which we can address this later. The following code snippet shows the logic that’s needed to check if the player has enough money in the bank, simulates the rolling of the dice, and then asks the user for their guess: 47 | 48 | if you > 0 <= human_bank: 49 | print("You're betting ${}".format(you)) 50 | dice_roll = randint(1, 6) 51 | human_guess = float(input('What number you think the dice will roll on? ' 52 | 'Select numbers: 1-6 ')) 53 | 54 | Let’s analyze this portion: 55 | 56 | if you > 0 <= human_bank: 57 | 58 | This condition ensures that the user didn’t enter in a negative number (that makes no sense) and also that the maximum amount of money that they’re wagering is all the money they got in their account; anything above that shouldn't be permissible as you can’t deduct more money than what’s in your bank account! 59 | 60 | Next, a random number within the range of 1-6 is generated, and then the user is asked for the amount that they’re wagering. The input is _cast_ or converted to a float which are just decimal point numbers. Most people don't bet $100.50, but I’ve included it just for those quirky individuals that do. The next step is to update the cash in the bank account contingent on the outcome as shown in the following code snippet: 61 | 62 | if human_guess == dice_roll: 63 | human_bank += you 64 | print('Dice landed on {}'.format(dice_roll)) 65 | print("Congrats! You now have ${}".format(human_bank)) 66 | else: 67 | human_bank -= you 68 | print("Bummers! Dice landed on {}! Money gone...".format(dice_roll)) 69 | print("You have ${}".format(human_bank)) 70 | if human_bank == 0: 71 | print("Game over! You're out of cash") 72 | break 73 | 74 | The above code snippet includes an if/else statement to check to see if the user guess right or hit a big fat 0. The last if statement checks to see if the player’s account is 0, and if it is then game over and breaks of the script. 75 | 76 | We also need to put in some logic to determine if the player wants to continue the game or exit. The following code snippet does this: 77 | 78 | play_again = input("Enter 'y' to play again or 'n' to stop" ).lower() 79 | if play_again == 'y': 80 | continue 81 | elif play_again == 'n': 82 | print("Game Over...") 83 | if human_bank > 1000: 84 | print("You're lucky! You won ${} ".format(human_bank - 1000)) 85 | break 86 | elif human_bank < 1000: 87 | print("Better luck next time! You loss ${} ".format(1000 - human_bank)) 88 | break 89 | else: 90 | print("You didn't win nor you didn't lose!") 91 | break 92 | else: 93 | print('Enter a valid amount. You have ${} to bet'.format(human_bank)) 94 | game() 95 | 96 | Note, if the user enters _n_ for no then the game terminates and tells them if they won or lost money along with the exact amount. If the user enters _y_ then the program will go on which is done through the continue statement which forces to the next cycle of the iteration. 97 | 98 | The _Game of Dice_ script is available on GitHub here: [insert link] 99 | 100 | Get creative, you can extend this script if you’re motivated. You can make modifications such as emulating this game through a computer. In other words you can write a program in which the computer automatically wagers an amount, guess where the dice will roll on, and then simulate the dice rolling. The sequences will be quite odd but it will still be fun to watch the computer go through all of that madness. 101 | 102 | 103 | # Project: Random Person Generator 104 | 105 | Have you ever seen those online name generators? I have, I’ve used them a couple of times for novels I was writing. Yes, I wrote novels under a pseudonym and occasionally had a difficult time creating names for fictitious characters! It may seem random (no pun) for a software engineer to do that, but there's actually quite a bit of parallels between writing code and writing stories. 106 | 107 | Anyhoo, to prevent from deviating let’s take the functionality of a simple random name generator a step or two further. Let’s write a script that allows us to randomly generate first names, last names, full names, emails, ages, telephone numbers, and email passwords. It will be a fun project to code and showcase! 108 | 109 | ## Script Hints 110 | 111 | Let’s breakdown the script into individual functions so that it’s more modular. Here’s the functions that you can fill-in: 112 | 113 | `first_name`: A function that allows us to generate male or female first names. By default we’ll let the program decide on the gendered pronoun. 114 | 115 | `last_name`: A function that allows us to generate surnames. 116 | 117 | `full_name`: A function that allows us to generate first and last names. Like the first_name function it can be gendered or we can let the program decide this. 118 | 119 | `age`: Generate a random age for the person. We can specify something like 1-100. 120 | 121 | `phone_number`: Generate a random 10 digit phone number. For the sake of simplicity we can decide on the region which in this example are North American phone numbers. The key here is that the first digit can’t be 0 or 1. 122 | 123 | `email_password`: We can generate a random email address which uses the random person’s first and last names. 124 | 125 | There’s some subtle decisions that we need to make. For one, the randomly generated full name is tied to the email that’s created. Since we’re creating separate functions for the first_name, last_name, and full_name functions, how can we create the email so that it’s tied to the random name that’s generated? There’s a couple of ways to do this, for one we can call the first_name and last_name functions within the a function that creates the email. 126 | 127 | Or, we can do the second approach which is the choice I decided to do which is to include a nested function within the outer function of full_name. Therefore, we can create the full name and within the function give the user the option of creating an email address that uses that randomly generated full name. 128 | 129 | If they opt for no then the full name will just be generated, and if they opt for yes then a dictionary with randomly generated name and email will be created. By the way, there’s something else to think about. Where will we get the names from? You don’t have to download a massive file of names, instead I just did a couple of searches online looking for popular male and female names in the USA. 130 | 131 | You’re more than welcome to research popular names in any country you want. You can simply store the names in a list, and then you can use the choice function from the random module to randomly select a name as shown in the code snippet below: 132 | 133 |
134 | >>> from random import choice 135 | 136 | >>> female_names = ['Molly', 'Sue', 'Angela'] 137 | 138 | >>> choice(female_names) 139 | 140 | ... 141 | 142 | 'Angela' 143 |144 | 145 | To generate a random age is easy, you just need to generate a random number within a realistic interval: 146 | 147 |
148 | >>> from random import randint 149 | 150 | >>> [randint(1, 100) for x in range(10)] 151 | 152 | ... 153 | 154 | [2, 23, 99, 19, 96, 27, 61, 88, 53, 38] 155 |156 | 157 | The above is simply a list comprehension that generates a list of 10 random numbers within the range of 1-100. To generate a random password here’s a hint, you should investigate the functions in the string module. You have some useful things available to you in this module which are shown in the following code snippets: 158 |
159 | >>> from random import choice 160 | 161 | >>> from string import ascii_letters 162 | 163 | >>> from string import digits 164 | 165 | >>> from string import punctuation 166 | 167 | >>> ascii_letters 168 | 169 | ... 170 | 171 | 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 172 |173 | 174 |
175 | >>> digits 176 | ... 177 | '0123456789' 178 |179 | 180 |
181 | >>> punctuation 182 | ... 183 | 184 | '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' 185 |186 | 187 |
188 | >>> [ascii for ascii in ascii_letters] 189 | 190 | ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] 191 | 192 | >>> for x in range(5): 193 | print(choice(letters)) 194 | 195 | ... 196 | 197 | H 198 | 199 | u 200 | 201 | K 202 | 203 | u 204 | 205 | A 206 |207 | 208 | ## Solution 209 | 210 | Below is what I cooked up: 211 | 212 | from random import randint 213 | from random import choice 214 | from string import ascii_letters 215 | 216 | def first_name(male=None, female=None): 217 | 218 | genders = ['m', 'f'] 219 | male_first_names = ['Liam', 'Noah', 'William', 'Logan', 'Benjamin', 'Mason', 'Elijah', 'Oliver', 'Jacob', 'James'] 220 | female_first_names = ['Emma', 'Olivia', 'Ava', 'Isabella', 'Sophia', 'Charlotte', 'Mia', 'Amelia', 'Harper', 'Evelyn'] 221 | if male: 222 | name = choice(male_first_names) 223 | return name 224 | elif female: 225 | name = choice(female_first_names) 226 | return name 227 | elif male is None and female is None: 228 | pick_gender = choice(genders) 229 | if pick_gender == 'm': 230 | alias = choice(male_first_names) 231 | return alias 232 | elif pick_gender == 'f': 233 | alias = choice(female_first_names) 234 | return alias 235 | 236 | The three functions from the import statement was previously discussed, and the first_name function contains the logic for randomly generating a first name. 237 | 238 | I decided to include a list named genders which holds the characters _m_ for male and _f_ for female. Contingent on if the user entered a keyword argument, the function would randomly select a male or female first name. If no keyword argument was entered then the program would randomly select a gendered first name by passing the genders list into the choice function. Let’s observe the function declaration: 239 | 240 | male=None, female=None 241 | 242 | The keyword arguments are both set to None. Therefore, we can check if the user passed in a value for the keyword argument if it’s not equal to None. For example, let’s just look at the following snippet: 243 | 244 | if male: 245 | name = choice(male_first_names) 246 | return 247 | 248 | The variable male will be True if it’s not empty or None. If that’s the case then a random male name will be generated and vice versa. Moving along, let’s implement the code for generating the last name: 249 | 250 | def last_name(): 251 | 252 | last_names = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Martinez', 'Sanchez', 'Nguyen', 'Barnes'] 253 | surname = choice(last_names) 254 | return surname 255 | 256 | This is quite simple. I’ve just researched some popular surnames in the US on Wikipedia, added it to a list, and then implemented a random selection by using the `choice` function. Next, let’s cook up the logic for creating a full name. 257 | 258 | Now, bear in mind that the route I took was to include an inner function called `create_name`. I did this because I saw where more or less the same logic was being used in two separate parts of the function. Therefore, one idea is to wrap it inside of a function and then call it when needed. The inner function I created for this purpose is called `create_name`; below is the logic for the `full_name` function: 259 | 260 | def full_name(male=None, female=None): 261 | 262 | email_services = ['gmail', 'aol', 'yahoo', 'aol', 'yandex', 'mail'] 263 | create_email = input("Do you want to create an email address? Enter 'y' for yes" 264 | "or 'n' for no. ").lower() 265 | def create_name(): 266 | if male: 267 | male_name = first_name(male='m') 268 | last = last_name() 269 | full = male_name + ' ' + last 270 | return full 271 | elif female: 272 | female_name = first_name(female='f') 273 | last = last_name() 274 | full = female_name + ' ' + last 275 | return full 276 | else: 277 | first = first_name() 278 | last = last_name() 279 | full = first + ' ' + last 280 | return full 281 | if create_email == 'y': 282 | email_id = { 283 | 'name': None, 284 | 'email': None 285 | } 286 | moniker = create_name() 287 | first, last = moniker.split(' ') 288 | e_address = (first + '.' + last + '@' + choice(email_services) + '.com').lower() 289 | email_id['name'] = moniker 290 | email_id['email'] = e_address 291 | return email_id 292 | elif create_email == 'n': 293 | name = create_name() 294 | return name 295 | 296 | Inside of the `create_name` function is similar logic that you saw in the `first_name` function. The reason for this is that it too gives the user the option of specifying a gender first-name which will be combined with the last-name. In this function the user is asked if they want to create an email or not. If they entered _y_ then a dictionary will be created and returned that contains the name and email mapping pair; if not, then just the full name will be returned. 297 | 298 | The email service like gmail, yahoo, yandex, etc, is also generated by adding it to a list, randomly selecting an item from it with choice, and then affixing it to the end of the email string. The following code snippet shows how to randomly generate the age of a person which can be done in one line as shown below: 299 | 300 | def age(): 301 | 302 | person_age = randint(1, 100) 303 | return person_age 304 | 305 | 306 | That’s simple stuff, just randomly generate a sequence of numbers within the range of 1-100 and then return it. Let’s analyze the logic that’s needed to randomly create a North American phone number: 307 | 308 | def phone_number(): 309 | 310 | number = '' 311 | for x in range(1, 11): 312 | if x == 1: 313 | num = randint(2, 9) 314 | number += str(num) 315 | elif x == 4: 316 | num = randint(2, 9) 317 | number += str(num) 318 | else: 319 | num = randint(0, 9) 320 | number += str(num) 321 | if x % 3 == 0 and x <= 6 322 | number += '-' 323 | return number 324 | 325 | The first thing that we need to think of is what exactly is a valid North American phone number? It’s a number that can be placed in the following format: 326 | 327 | XNN-XNN-NNNN 328 | 329 | In the above syntax _X_ represents a number within the range of 2-9, while _N_ represents a number within the range of 0-9. 330 | 331 | Once we understand that we can create a loop that iterates over a range of 10 (the total digits in a phone number) and then randomly generate a number within the range of 0-9 EXCEPT when it’s the first or fourth digit. 332 | 333 | The reason for this is because the first and fourth digits can’t be within the range of 0-9, but instead within the range of 2-9; this can be accomplished with conditional checks. Also, there’s two more things to keep note of. One, we need to convert the integers to strings because we want to do concatenation not sum integers. Here’s an example on summing integers vs concatenation: 334 | 335 |
336 | >>> x = 5 337 | >>> y = 10 338 | >>> x + y 339 | ... 340 | 15 341 | 342 | >>> str(x) + str(y) 343 | ... 344 | '510' 345 |346 | 347 | Two, we want to format the string using hyphens to separate them. This appears simple at first glance because the string has a pattern in which the dash appears every 3 digits. If we implement a potential solution using just modulus arithmetic then the problem with this is that we could end up with a phone number that looks like this: 348 | 349 | 948-456-857-7 350 | 351 | The reason for this is that the dash is added after every group of 3s. However, we can bypass this by adding a conditional check that says: _only add a hyphen if we are not past the sixth digit_ 352 | 353 | This ensures that the 3rd hyphen is NOT added. 354 | 355 | Last but not least, we must create a simple password of an arbitrary length. We can accomplish this in a single line using a list comprehension: 356 | 357 | def email_password(length=7): 358 | 359 | return ''.join([choice(ascii_letters) for x in range(length)]) 360 | 361 | We now have several functions coded so the next step is to test them. I’ve created a simple function for this: 362 | 363 | def run(): 364 | for x in range(3): 365 | print(first_name()) 366 | print() 367 | for x in range(3): 368 | print(last_name()) 369 | print() 370 | for x in range(3): 371 | print(full_name()) 372 | print() 373 | for x in range(3): 374 | print(age()) 375 | print() 376 | for x in range(3): 377 | print(phone_number()) 378 | print() 379 | for x in range(3): 380 | print(email_password()) 381 | 382 | Here’s some test output when the run function is ran through the shell assuming that the file is named `random_person.py`: 383 | 384 | $ python random_person.py 385 |
386 | Logan 387 | Ava 388 | Mia 389 | 390 | Jones 391 | Smith 392 | Nguyen 393 | 394 | Do you want to create an email address? Enter 'y' for yes or 'n' for no. y 395 | {'name': 'Charlotte Jones', 'email': 'charlotte.jones@gmail.com'} 396 | Do you want to create an email address? Enter 'y' for yes or 'n' for no. y 397 | {'name': 'Mia Smith', 'email': 'mia.smith@yahoo.com'} 398 | Do you want to create an email address? Enter 'y' for yes or 'n' for no. y 399 | {'name': 'Ava Miller', 'email': 'ava.miller@yahoo.com'} 400 | 401 | 87 402 | 58 403 | 62 404 | 405 | 774-201-6881 406 | 908-307-6702 407 | 772-268-8114 408 | 409 | MgxpMRp 410 | kCtcLUp 411 | VrWMVgq 412 |413 | 414 | View the full source code for [Random Person Generator](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py). 415 | 416 | ## Project: The California State Lottery 417 | 418 | Most states in the US allows denizens the ability to play the lottery. While I’m not advocating for folks to become chronic gamblers, I am advocating simulating the winning numbers through a python program. In this project we’re going to simulate the various lotteries that California makes available which are: 419 | 420 | - Daily 3: Pick any 3 numbers within the range of 0-9. 421 | 422 | - Daily 4: Pick any 4 numbers within the range of 0-9. 423 | 424 | - Fantasy 5: Pick any 5 numbers within the range of 1-39. 425 | 426 | - Super Lotto PLUS: Pick any five numbers within the range of 1-47, and then one mega number from 1-27. 427 | 428 | - Mega Millions: Select six numbers from two separate pool of numbers, five different numbers from 1-70, and one number from 1-25. 429 | 430 | - Powerball: Select 5 numbers between 1-69, and one Powerball number between 1-26. 431 | 432 | 433 | There’s many ways to play the lottery. For simplicity’s sake we’ll give the user just one option to bet which is a straight bet, or a bet in which the player must select all of the winning numbers in the exact order in which they occur. 434 | 435 | 436 | ## Script Hints 437 | 438 | An easy way to solve this is to create a function that represents each type of lottery, and then fill in the respective logic. Once you know how to code The Daily 3, then you’ll also know how to code the rest of them. The reason for this is because the logic is in essence the same, the only thing that changes are the amount of numbers to predict along with their ranges. Below are the functions to be coded: 439 | 440 | 441 | - daily_3 442 | 443 | - daily_4 444 | 445 | - fantasy_5 446 | 447 | - super_lotto_plus 448 | 449 | - mega_millions 450 | 451 | - powerball 452 | 453 | 454 | ## Solution 455 | 456 | 457 | Let’s put the above hint into motion and code the `daily_3`. Here’s the start: 458 | 459 | from random import randint 460 | from time import sleep 461 | def daily_3(): 462 | """ 463 | emulates the daily 3 464 | lottery 465 | """ 466 | print("Welcome! You're playing Daily 3.") 467 | lucky_one = randint(0, 9) 468 | lucky_two = randint(0, 9) 469 | lucky_three = randint(0, 9) 470 | guess_one = int(input('Guess your lucky number: 0 – 9 ')) 471 | guess_two = int(input('Guess your lucky number: 0 – 9 ')) 472 | guess_three = int(input('Guess your lucky number: 0 – 9 ')) 473 | 474 | We need to import the randint function to generate a range of random numbers, and then we could use the sleep function from the time module to pause the program for more theatricality. 475 | 476 | The program starts off with a cordial welcome message and then three separate random variables are generated. 477 | 478 | Next, three consecutive prompts are generated which asks the user for their guess. Once done the program can then display the results of the randomly generated numbers: 479 | 480 | print("Here's the Daily 3 results...") 481 | sleep(3) 482 | print(lucky_one) 483 | sleep(2) 484 | print(lucky_two) 485 | sleep(2) 486 | print(lucky_three) 487 | print([lucky_one,lucky_two, lucky_three]) 488 | 489 | The first random variable is printed followed by a two-second pause, and then the other two variables follow the same steps; all of the random variables are then printed as a list. 490 | 491 | Last, the user input needs to be checked to see if it matches the randomly generated numbers. This can be easily accomplished with an if statement that checks each guess against the variable that holds the respective random number. If any of these evaluates to False then we know that the user did not win the lottery. Below is the logic for this: 492 | 493 | if guess_one == lucky_one and guess_two == lucky_two and guess_three == lucky_three: 494 | print("Congrats! You won $500") 495 | else: 496 | print("Today wasn't your day! Try again.") 497 | 498 | 499 | That's all there is to it! Now, fill out the remaining functions and once done you can check them against the [solution here](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py). 500 | 501 | ## The best way to support this project is to [purchase a digital copy](https://www.amazon.com/Code-Cool-Stuff-Python-Purcell-ebook/dp/B081XJMNRB) on Amazon and leave a review. -------------------------------------------------------------------------------- /book/resources.md: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | #### This is the accompanying resources for the *Code Cool Stuff in Python* book If there are any links that are dead or changed, create an issue or a pull request. #### 3 | ---------------------------------------------------------- 4 | 5 | ## Prequel: ## 6 | 7 | Creative Commons 3.0 Noncommercial License: [https://creativecommons.org/licenses/by-nc-sa/3.0 ](https://creativecommons.org/licenses/by-nc-sa/3.0 ) 8 | 9 | ---- 10 | 11 | ## Chapter I: A Merry Overview of The Python Programming Language ## 12 | 13 | 14 | **Online Python Interpreters:** 15 | 16 | - Online GDB: [https://www.onlinegdb.com/online_python_interpreter](https://www.onlinegdb.com/online_python_interpreter) 17 | - Repl.it: [https://repl.it/languages/python3](https://repl.it/languages/python3) 18 | - Another online python interpreter: [http://mathcs.holycross.edu/~kwalsh/python](http://mathcs.holycross.edu/~kwalsh/python) 19 | 20 | A list of Python IDEs: [https://wiki.python.org/moin/IntegratedDevelopmentEnvironments](https://wiki.python.org/moin/IntegratedDevelopmentEnvironments) 21 | 22 | #### The Python IDE I Recommend: PyCharm 23 | 24 | PyCharm Installation on Windows: [https://www.jetbrains.com/help/pycharm/installation-guide.html?section=Windows](https://www.jetbrains.com/help/pycharm/installation-guide.html?section=Windows) 25 | 26 | PyCharm Installation on MacOs: [https://www.jetbrains.com/help/pycharm/installation-guide.html?section=macOS](https://www.jetbrains.com/help/pycharm/installation-guide.html?section=macOS) 27 | 28 | PyCharm installation on Ubuntu: 29 | `$ sudo snap apt-get install pycharm-community` 30 | 31 | PyCharm Quick Start Guide: [https://www.jetbrains.com/help/pycharm/quick-start-guide.html](https://www.jetbrains.com/help/pycharm/quick-start-guide.html) 32 | 33 | PyCharm blog: [https://blog.jetbrains.com/pycharm](https://blog.jetbrains.com/pycharm) 34 | 35 | PyCharm keyboard shortcuts for editing, navigating, refactoring, and debugging: [https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html](https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html) 36 | 37 | 38 | #### A Theoretical Book for Mastering The Fundamentals of Python 39 | 40 | Become a Python Developer: [https://www.amazon.com/Become-Python-Developer-Wrestle-Defeat-ebook/dp/B07KX8RT4V](https://www.amazon.com/Become-Python-Developer-Wrestle-Defeat-ebook/dp/B07KX8RT4V) 41 | 42 | -------------- 43 | 44 | Variable Naming Tips in Python, PEP 8: [https://www.python.org/dev/peps/pep-0008](https://www.python.org/dev/peps/pep-0008) 45 | 46 | Math module: [https://docs.python.org/3/library/math.html](https://docs.python.org/3/library/math.html) 47 | 48 | 49 | ---------------------------------------------------------- 50 | 51 | ## Chapter II: Crafting Small Scripts, Converters, and Practical Tools in Python ## 52 | 53 | 54 | A list of the builtin functions in python: [https://docs.python.org/3/library/functions.html](https://docs.python.org/3/library/functions.html) 55 | 56 | Math equations or conversions in the Google Search Box: [https://support.google.com/websearch/answer/3284611?hl=en](https://support.google.com/websearch/answer/3284611?hl=en) 57 | 58 | Temperature Converter Script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/temperature_converter.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/temperature_converter.py ) 59 | 60 | Auto loan calculator script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/autoloan_calculator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/autoloan_calculator.py) 61 | 62 | Spanish Translator Script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/spanish_translator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/spanish_translator.py) 63 | 64 | --------- 65 | 66 | 67 | ## Chapter III: How to Unlock the Power of Randomization to Create Intriguing Scripts in Python ## 68 | 69 | 70 | The Game of Dice: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/a_game_of_dice.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/a_game_of_dice.py) 71 | 72 | Random Person Generator: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py) 73 | 74 | California State Lottery: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py) 75 | 76 | 77 | 78 | ## Chapter IV: Crafting Catchy Computer Art with Python Turtle ## 79 | 80 | The Turtle Module: [https://docs.python.org/3.3/library/turtle.html?highlight=turtle](https://docs.python.org/3.3/library/turtle.html?highlight=turtle) 81 | 82 | The Turtle color module: [https://docs.python.org/3.3/library/turtle.html?highlight=turtle#turtle.color](https://docs.python.org/3.3/library/turtle.html?highlight=turtle#turtle.color) 83 | 84 | PyRandomColor Module: [https://github.com/purcellconsult/PyRandomColor](https://github.com/purcellconsult/PyRandomColor) 85 | 86 | 4 Little Turtles Game: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_04/turtle_racing_game.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_04/turtle_racing_game.py ) 87 | 88 | 89 | 90 | ----------- 91 | 92 | 93 | ## Chapter V: Building Practical Desktop apps in Python Using the Core Tkinter Library # 94 | 95 | Online resource for Tkinter: [http://effbot.org/tkinterbook/label.htm](http://effbot.org/tkinterbook/label.htm) 96 | 97 | BMI Calculator: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py "https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py ") 98 | 99 | Secret Number Game GUI: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/secret_number_game.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/secret_number_game.py) 100 | ======= 101 | #### This is the accompanying resources for the *Code Cool Stuff in Python* book If there are any links that are dead or changed, create an issue or a pull request. #### 102 | ---------------------------------------------------------- 103 | 104 | ## Prequel: ## 105 | 106 | Creative Commons 3.0 Noncommercial License: [https://creativecommons.org/licenses/by-nc-sa/3.0 ](https://creativecommons.org/licenses/by-nc-sa/3.0 ) 107 | 108 | ---- 109 | 110 | ## Chapter I: A Merry Overview of The Python Programming Language ## 111 | 112 | 113 | **Online Python Interpreters:** 114 | 115 | - Online GDB: [https://www.onlinegdb.com/online_python_interpreter](https://www.onlinegdb.com/online_python_interpreter) 116 | - Repl.it: [https://repl.it/languages/python3](https://repl.it/languages/python3) 117 | - Another online python interpreter: [http://mathcs.holycross.edu/~kwalsh/python](http://mathcs.holycross.edu/~kwalsh/python) 118 | 119 | A list of Python IDEs: [https://wiki.python.org/moin/IntegratedDevelopmentEnvironments](https://wiki.python.org/moin/IntegratedDevelopmentEnvironments) 120 | 121 | #### The Python IDE I Recommend: PyCharm 122 | 123 | PyCharm Installation on Windows: [https://www.jetbrains.com/help/pycharm/installation-guide.html?section=Windows](https://www.jetbrains.com/help/pycharm/installation-guide.html?section=Windows) 124 | 125 | PyCharm Installation on MacOs: [https://www.jetbrains.com/help/pycharm/installation-guide.html?section=macOS](https://www.jetbrains.com/help/pycharm/installation-guide.html?section=macOS) 126 | 127 | PyCharm installation on Ubuntu: 128 | `$ sudo snap apt-get install pycharm-community` 129 | 130 | PyCharm Quick Start Guide: [https://www.jetbrains.com/help/pycharm/quick-start-guide.html](https://www.jetbrains.com/help/pycharm/quick-start-guide.html) 131 | 132 | PyCharm blog: [https://blog.jetbrains.com/pycharm](https://blog.jetbrains.com/pycharm) 133 | 134 | PyCharm keyboard shortcuts for editing, navigating, refactoring, and debugging: [https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html](https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html) 135 | 136 | 137 | #### A Theoretical Book for Mastering The Fundamentals of Python 138 | 139 | Become a Python Developer: [https://www.amazon.com/Become-Python-Developer-Wrestle-Defeat-ebook/dp/B07KX8RT4V](https://www.amazon.com/Become-Python-Developer-Wrestle-Defeat-ebook/dp/B07KX8RT4V) 140 | 141 | -------------- 142 | 143 | Variable Naming Tips in Python, PEP 8: [https://www.python.org/dev/peps/pep-0008](https://www.python.org/dev/peps/pep-0008) 144 | 145 | Math module: [https://docs.python.org/3/library/math.html](https://docs.python.org/3/library/math.html) 146 | 147 | 148 | ---------------------------------------------------------- 149 | 150 | ## Chapter II: Crafting Small Scripts, Converters, and Practical Tools in Python ## 151 | 152 | 153 | A list of the builtin functions in python: [https://docs.python.org/3/library/functions.html](https://docs.python.org/3/library/functions.html) 154 | 155 | Math equations or conversions in the Google Search Box: [https://support.google.com/websearch/answer/3284611?hl=en](https://support.google.com/websearch/answer/3284611?hl=en) 156 | 157 | Temperature Converter Script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/temperature_converter.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/temperature_converter.py ) 158 | 159 | Auto loan calculator script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/autoloan_calculator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/autoloan_calculator.py) 160 | 161 | Spanish Translator Script: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/spanish_translator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/spanish_translator.py) 162 | 163 | --------- 164 | 165 | 166 | ## Chapter III: How to Unlock the Power of Randomization to Create Intriguing Scripts in Python ## 167 | 168 | 169 | The Game of Dice: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/a_game_of_dice.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/a_game_of_dice.py) 170 | 171 | Random Person Generator: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py) 172 | 173 | California State Lottery: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py) 174 | 175 | 176 | 177 | ## Chapter IV: Crafting Catchy Computer Art with Python Turtle ## 178 | 179 | The Turtle Module: [https://docs.python.org/3.3/library/turtle.html?highlight=turtle](https://docs.python.org/3.3/library/turtle.html?highlight=turtle) 180 | 181 | The Turtle color module: [https://docs.python.org/3.3/library/turtle.html?highlight=turtle#turtle.color](https://docs.python.org/3.3/library/turtle.html?highlight=turtle#turtle.color) 182 | 183 | PyRandomColor Module: [https://github.com/purcellconsult/PyRandomColor](https://github.com/purcellconsult/PyRandomColor) 184 | 185 | 4 Little Turtles Game: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_04/turtle_racing_game.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_04/turtle_racing_game.py ) 186 | 187 | 188 | 189 | ----------- 190 | 191 | 192 | ## Chapter V: Building Practical Desktop apps in Python Using the Core Tkinter Library # 193 | 194 | Online resource for Tkinter: [http://effbot.org/tkinterbook/label.htm](http://effbot.org/tkinterbook/label.htm) 195 | 196 | BMI Calculator: [https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py ](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py "https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py ") 197 | 198 | >>>>>>> 27f0623c15640315fa2c7cd98302055ec6a636ad 199 | -------------------------------------------------------------------------------- /media/demos/cli/a_game_of_dice.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/a_game_of_dice.gif -------------------------------------------------------------------------------- /media/demos/cli/a_game_of_dice.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/a_game_of_dice.mp4 -------------------------------------------------------------------------------- /media/demos/cli/autoloan_calculator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/autoloan_calculator.gif -------------------------------------------------------------------------------- /media/demos/cli/autoloan_calculator.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/autoloan_calculator.mp4 -------------------------------------------------------------------------------- /media/demos/cli/california_lottery.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/california_lottery.gif -------------------------------------------------------------------------------- /media/demos/cli/california_lottery.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/california_lottery.mp4 -------------------------------------------------------------------------------- /media/demos/cli/random_person_generator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/random_person_generator.gif -------------------------------------------------------------------------------- /media/demos/cli/random_person_generator.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/random_person_generator.mp4 -------------------------------------------------------------------------------- /media/demos/cli/spanish_translator_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/spanish_translator_demo.gif -------------------------------------------------------------------------------- /media/demos/cli/spanish_translator_demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/cli/spanish_translator_demo.mp4 -------------------------------------------------------------------------------- /media/demos/gui/bmi_calculator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/bmi_calculator.gif -------------------------------------------------------------------------------- /media/demos/gui/bmi_calculator.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/bmi_calculator.mp4 -------------------------------------------------------------------------------- /media/demos/gui/secret_number_game_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/secret_number_game_demo.gif -------------------------------------------------------------------------------- /media/demos/gui/secret_number_game_demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/secret_number_game_demo.mp4 -------------------------------------------------------------------------------- /media/demos/gui/temperature_converter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/temperature_converter.gif -------------------------------------------------------------------------------- /media/demos/gui/temperature_converter.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/gui/temperature_converter.mp4 -------------------------------------------------------------------------------- /media/demos/simple_images_with_turtle_collage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/simple_images_with_turtle_collage.jpg -------------------------------------------------------------------------------- /media/demos/turtle/4_little_turtles_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/4_little_turtles_demo.gif -------------------------------------------------------------------------------- /media/demos/turtle/circle_art_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/circle_art_demo.gif -------------------------------------------------------------------------------- /media/demos/turtle/circle_turtle_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/circle_turtle_demo.gif -------------------------------------------------------------------------------- /media/demos/turtle/mike_and_ike_candies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/mike_and_ike_candies.gif -------------------------------------------------------------------------------- /media/demos/turtle/night_sky.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/night_sky.gif -------------------------------------------------------------------------------- /media/demos/turtle/party-lights-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/party-lights-demo.gif -------------------------------------------------------------------------------- /media/demos/turtle/spirograph.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/demos/turtle/spirograph.gif -------------------------------------------------------------------------------- /media/images/book/ccswp_ebook_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/book/ccswp_ebook_cover.jpg -------------------------------------------------------------------------------- /media/images/book/ccswp_paperback_cover.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/book/ccswp_paperback_cover.pdf -------------------------------------------------------------------------------- /media/images/book/code_cool_stuff_with_python_robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/book/code_cool_stuff_with_python_robot.png -------------------------------------------------------------------------------- /media/images/book/code_cool_stuff_with_python_source.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/book/code_cool_stuff_with_python_source.ai -------------------------------------------------------------------------------- /media/images/ch_01/Create_SampleProjects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/Create_SampleProjects.jpg -------------------------------------------------------------------------------- /media/images/ch_01/adding_interpreter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/adding_interpreter.jpg -------------------------------------------------------------------------------- /media/images/ch_01/create_a_fresh_python_file.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/create_a_fresh_python_file.jpg -------------------------------------------------------------------------------- /media/images/ch_01/helloworld.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/helloworld.jpg -------------------------------------------------------------------------------- /media/images/ch_01/new_python_file.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/new_python_file.jpg -------------------------------------------------------------------------------- /media/images/ch_01/pycharm_project_setup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/pycharm_project_setup.jpg -------------------------------------------------------------------------------- /media/images/ch_01/run_helloworld.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_01/run_helloworld.jpg -------------------------------------------------------------------------------- /media/images/ch_04/4_little_turtles_racing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/4_little_turtles_racing.png -------------------------------------------------------------------------------- /media/images/ch_04/4_little_turtles_racing_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/4_little_turtles_racing_1.png -------------------------------------------------------------------------------- /media/images/ch_04/4_little_turtles_racing_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/4_little_turtles_racing_2.png -------------------------------------------------------------------------------- /media/images/ch_04/4_little_turtles_racing_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/4_little_turtles_racing_3.png -------------------------------------------------------------------------------- /media/images/ch_04/4_little_turtles_racing_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/4_little_turtles_racing_4.png -------------------------------------------------------------------------------- /media/images/ch_04/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/arc.png -------------------------------------------------------------------------------- /media/images/ch_04/big_green_turtle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/big_green_turtle.png -------------------------------------------------------------------------------- /media/images/ch_04/blue_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/blue_square.png -------------------------------------------------------------------------------- /media/images/ch_04/brick_wall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/brick_wall.png -------------------------------------------------------------------------------- /media/images/ch_04/candies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/candies.png -------------------------------------------------------------------------------- /media/images/ch_04/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/circle.png -------------------------------------------------------------------------------- /media/images/ch_04/circle_art.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/circle_art.png -------------------------------------------------------------------------------- /media/images/ch_04/enhanced_square.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/enhanced_square.jpg -------------------------------------------------------------------------------- /media/images/ch_04/moving_turtle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/moving_turtle.png -------------------------------------------------------------------------------- /media/images/ch_04/nested_squares.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/nested_squares.png -------------------------------------------------------------------------------- /media/images/ch_04/night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/night.png -------------------------------------------------------------------------------- /media/images/ch_04/party_lights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/party_lights.png -------------------------------------------------------------------------------- /media/images/ch_04/py_turtle_racing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/py_turtle_racing.png -------------------------------------------------------------------------------- /media/images/ch_04/random_color_circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/random_color_circles.png -------------------------------------------------------------------------------- /media/images/ch_04/random_color_square_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/random_color_square_1.png -------------------------------------------------------------------------------- /media/images/ch_04/random_color_square_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/random_color_square_2.png -------------------------------------------------------------------------------- /media/images/ch_04/simple_turtle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/simple_turtle.png -------------------------------------------------------------------------------- /media/images/ch_04/snow_flake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/snow_flake.png -------------------------------------------------------------------------------- /media/images/ch_04/spirograph1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/spirograph1.png -------------------------------------------------------------------------------- /media/images/ch_04/square_cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/square_cube.png -------------------------------------------------------------------------------- /media/images/ch_04/square_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/square_portrait.png -------------------------------------------------------------------------------- /media/images/ch_04/triangle_cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/triangle_cube.png -------------------------------------------------------------------------------- /media/images/ch_04/turtle_angles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/turtle_angles.png -------------------------------------------------------------------------------- /media/images/ch_04/turtle_image_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/turtle_image_default.png -------------------------------------------------------------------------------- /media/images/ch_04/turtle_right_triangle_art.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/turtle_right_triangle_art.png -------------------------------------------------------------------------------- /media/images/ch_04/two_turtles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_04/two_turtles.png -------------------------------------------------------------------------------- /media/images/ch_05/Greetings_app_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/Greetings_app_1.jpg -------------------------------------------------------------------------------- /media/images/ch_05/Greetings_app_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/Greetings_app_2.jpg -------------------------------------------------------------------------------- /media/images/ch_05/Simple_Tkinter_GUI.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/Simple_Tkinter_GUI.jpg -------------------------------------------------------------------------------- /media/images/ch_05/bmi_weight_status_labels.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/bmi_weight_status_labels.jpg -------------------------------------------------------------------------------- /media/images/ch_05/body_mass_index_calculator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/body_mass_index_calculator.jpg -------------------------------------------------------------------------------- /media/images/ch_05/grid_layout_manager_example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/grid_layout_manager_example.jpg -------------------------------------------------------------------------------- /media/images/ch_05/guessing_game_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/guessing_game_1.jpg -------------------------------------------------------------------------------- /media/images/ch_05/guessing_game_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/guessing_game_2.jpg -------------------------------------------------------------------------------- /media/images/ch_05/guessing_game_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/guessing_game_3.jpg -------------------------------------------------------------------------------- /media/images/ch_05/pack_geometry_manager.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/pack_geometry_manager.jpg -------------------------------------------------------------------------------- /media/images/ch_05/place_geometry_example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/place_geometry_example.jpg -------------------------------------------------------------------------------- /media/images/ch_05/temperature_converter_gui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/images/ch_05/temperature_converter_gui.jpg -------------------------------------------------------------------------------- /media/pdfs/01_A_Merry_Overview_Of_Python_PDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/pdfs/01_A_Merry_Overview_Of_Python_PDF.pdf -------------------------------------------------------------------------------- /media/pdfs/02_Crafting_Small_Scripts,_Converters_Practical_Tools_PDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/pdfs/02_Crafting_Small_Scripts,_Converters_Practical_Tools_PDF.pdf -------------------------------------------------------------------------------- /media/pdfs/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python_PDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/pdfs/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python_PDF.pdf -------------------------------------------------------------------------------- /media/pdfs/04_Crafting_Catchy_Computer_Art_with_Python_Turtle_PDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/pdfs/04_Crafting_Catchy_Computer_Art_with_Python_Turtle_PDF.pdf -------------------------------------------------------------------------------- /media/pdfs/05_Building_Practical_Desktop_apps_in_Python_Using_the_Core_Tkinter_Library_PDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/pdfs/05_Building_Practical_Desktop_apps_in_Python_Using_the_Core_Tkinter_Library_PDF.pdf -------------------------------------------------------------------------------- /media/slidedecks/01_A_Merry_Overview_Of_Python.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/slidedecks/01_A_Merry_Overview_Of_Python.pptx -------------------------------------------------------------------------------- /media/slidedecks/02_Crafting_Small_Scripts_Converters_Practical_Tools.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/slidedecks/02_Crafting_Small_Scripts_Converters_Practical_Tools.pptx -------------------------------------------------------------------------------- /media/slidedecks/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/slidedecks/03_How_to_Unlock_the_Power_of_Randomization_to_Create_Intriguing_Scripts_in_Python.pptx -------------------------------------------------------------------------------- /media/slidedecks/04_Crafting_Catchy_Computer_Art_With_Python.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/slidedecks/04_Crafting_Catchy_Computer_Art_With_Python.pptx -------------------------------------------------------------------------------- /media/slidedecks/05_Building_Practical_Desktop_Apps_Tkinter.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/media/slidedecks/05_Building_Practical_Desktop_Apps_Tkinter.pptx -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Code Cool Stuff With Python 2 | 3 | ## A Cool Book to Learning Python! 4 | 5 |  6 | 7 | Let's learn how to build cool stuff with python that impress your friends and get you hired. By the time you’re done you’ll build 12 REAL PROJECTS that force you to master the fundamentals of python while having fun to boot. 8 | - Acquire a new skill that lasts a lifetime 9 | 10 | Here's a taste of some of the fun programs you'll build… 11 | 12 |  13 | 14 |  15 | 16 |  17 | 18 |  19 | 20 | 21 | The code examples in this book are written for Python 3.X. 22 | 23 | **Want to Contribute to an Open Source Project**? We would love to have you contribute to the project. There’s a plethora of ways to get involved from all skill sets, read [CONTRIBUTING.md](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/CONTRIBUTING.md) to get started today. 24 | 25 | If you're an educator that wants to promote STEM then I got ya covered. I've created slide decks and pdfs based off the content in the book that you can use as source material. Check out [EDUCATORS.md](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/EDUCATORS.md) 26 | 27 | 28 | Here's a list of all the chapters in *Code Cool Stuff with Python*: 29 | 30 | - [Chapter I: A Merry Overview of the Python Programming Language](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_01.md) 31 | - [Chapter II: Crafting Small Scripts, Converters, and Practical Tools in Python](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_02.md) 32 | - [Chapter III: How to Unlock the Power of Randomization](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_03.md) 33 | - [Chapter IV: Crafting Catchy Computer Art With Python Turtle](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_04.md) 34 | - [Chapter V: Building Practical Desktop apps in Python Using the Core Tkinter Library](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_05.md) 35 | 36 | If you're new to python then start with the first chapter which is a [Merry Overview of the Python Programming Language](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/book/chapter_01.md). That will assist you with getting your environment setup and also learning the basics of python. Keep on rolling from there to complete more interesting projects. 37 | 38 | ## Projects 39 | 40 | Below is an explanation of the projects along with a link to the respective source code. 41 | 42 | | Name | Description | Source 43 | |--|--| --| 44 | |Temperature Converter CLI | Convert temperatures into Celsius, Fahrenheit, and Kelvin. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/temperature_converter.py) | 45 | Auto loan calculator | Calculates the total cost of an autoloan. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/autoloan_calculator.py) 46 | Mortgage calculator | Calculate the monthly payment that one owes on a house. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/mortgage_calculator.py) 47 | Spanish translator | A simple command line script that translates common Spanish phrases into English. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/spanish_translator.py) 48 | Your Bio | Prompts the user for a series of questions about themselves and then displays the answers. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_02/your_bio.py) 49 | A Game of Dice | A simple text based game that simulates a virtual bank account, a dice, and wagering. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/a_game_of_dice.py) 50 | Random Person Generator | Randomly generates a person's name, email, phone number, and age. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/random_person_generator.py) 51 | The California State Lottery | Simulates the various Californian lotteries such as Daily 3, Daily 4, Fantasy 5, Super Lotto Plus, Mega Millions, and Power Ball | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_03/california_lottery.py) 52 | Four Little Turtles | Simulates a racing game with python turtle |[Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_04/turtle_racing_game.py) 53 | BMI Calculator | Computes the BMI index of an indivdual. Accepts input in pounds and kilograms. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/bmi_calculator.py) 54 | Temperature Converter GUI | Allows for the conversion of Fahrenheit to Celsius and vice versa with Tkinter. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/fahrenheit_to_celsius_app.py) 55 | Secret Number Game | A fun guessing game in which the user guesses a number within the range of 1-100 until they're out of tries. The tries are randomly generated. | [Source](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/sourcecode/ch_05/secret_number_game.py) 56 | 57 | ## How to Support 58 | 59 | This version of *Code Cool Stuff with Python* is released under the Creative Commons 3.0 Noncommercial License. It’s free here for a simple reason, to make the book widely accessible to as many people as possible. However, I do wish to profit off my work and there are several ways you can support this project. 60 | 1) Purchase the [digital](https://www.amazon.com/Code-Cool-Stuff-Python-Purcell-ebook/dp/B081XJMNRB) or paperback edition of this book on Amazon AND leave a review. Reviews help consumers make inform purchasing decisions. Learn [how to leave reviews on Amazon](https://www.amazon.com/gp/help/customer/display.html?nodeId=201889700). 61 | 2) Make a donation, my PayPal email is: purcellconsult@gmail.com 62 | 3) Sponsor me on GitHub, I offer several tiers: https://github.com/sponsors/purcellconsult 63 | 64 | ## Have a Tech Related Slack Channel Or a Tech Focused Online Community? I Would Love to Support 65 | 66 | I like collaborating with organizations that are passionate in tech. I endorse STEM education, lifelong learning, diversity, and equality. I would love to get a channel dedicated on your slack for Code Cool Stuff with Python. Of course I’ll pop up every now and then to answer questions, and will even be willing to schedule a live Q & A session on the channel. If interested, send me an email with details of your Slack Channel here: purcellconsult@gmail.com 67 | 68 | ## Business Related Inquiries 69 | 70 | 71 | - If you’re affiliated with a software company, school, or library, and would like to order 100+ copies of Code Cool Stuff With Python. 72 | - If you would like to license Code Cool Stuff with Python. 73 | - If you need a python workshop organized. 74 | - If you need a keynote or technical talk for a conference. 75 | 76 | Send me a concise email with a self explanatory subject: purcellconsult@gmail.com 77 | 78 | 79 | ## License and Copyright 80 | 81 | The materials herein are all © 2019-2020 Doug Purcell. 82 | 83 |  84 | 85 | The content in this repo is released under the [Creative Commons 3.0](https://github.com/purcellconsult/Code-Cool-Stuff-With-Python/blob/master/CODE_OF_CONDUCT.md) Noncommercial License so feel free to organize a meetup or teach a class based off this material. 86 | -------------------------------------------------------------------------------- /sourcecode/ch_01/boolean_algebra.py: -------------------------------------------------------------------------------- 1 | is_the_sky_blue = True 2 | do_cats_bark = False 3 | 4 | print(is_the_sky_blue) # True 5 | print(do_cats_bark) # False 6 | 7 | print(True and True) # True 8 | print(True and False) # False 9 | print(False and False) # False 10 | print(False and True) # False 11 | 12 | print(True or True) # True 13 | print(True or False) # True 14 | print(False or False) # False 15 | print(False or True) # True 16 | 17 | print(True ^ True) # False 18 | print(True ^ False) # True 19 | print(False ^ True) # True 20 | print(False ^ False) # False -------------------------------------------------------------------------------- /sourcecode/ch_01/builtin_math_operators.py: -------------------------------------------------------------------------------- 1 | import math 2 | print(math.log(1000000, 2)) 3 | print(math.sqrt(9)) 4 | print(math.cos(100) + math.sin(90) + math.tan(90)) 5 | print(math.pi**2 * math.e) 6 | 7 | -------------------------------------------------------------------------------- /sourcecode/ch_01/comments.py: -------------------------------------------------------------------------------- 1 | # This is a comment 2 | # This is a comment and will be ignored by the interpreter 3 | # I think you get the memo! -------------------------------------------------------------------------------- /sourcecode/ch_01/dictionaries_demo.py: -------------------------------------------------------------------------------- 1 | vowels = {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0} 2 | for key, value in vowels.items(): 3 | print(key, value) -------------------------------------------------------------------------------- /sourcecode/ch_01/elif_statement.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | # picks a random number in range 1...100 3 | grade = randint(1, 100) 4 | if grade >= 90 <= 100: 5 | print('A') 6 | elif grade >= 80 <= 89: 7 | print('B') 8 | elif grade >= 70 <= 79: 9 | print('C') 10 | elif grade >= 60 <= 69: 11 | print('D') 12 | else: 13 | print('F!') -------------------------------------------------------------------------------- /sourcecode/ch_01/exception_handling.py: -------------------------------------------------------------------------------- 1 | def divide(num, den): 2 | try: 3 | x = num / den 4 | print('{} / {} = {}'.format(num, den, num / den)) 5 | except ZeroDivisionError: 6 | print("can't divide by zero.") 7 | 8 | 9 | divide(10, 5) 10 | divide(0, 10) 11 | divide(10, 0) 12 | print() 13 | 14 | 15 | def import_test(): 16 | try: 17 | import math 18 | import operating 19 | import sys 20 | print(math.pi) 21 | print(sys.version_info) 22 | except ImportError: 23 | print("Couldn't import something") 24 | import_test() 25 | 26 | 27 | def divide(a, b): 28 | try: 29 | result = a / b 30 | except ZeroDivisionError: 31 | print("Can't divide by 0") 32 | else: 33 | print(result) 34 | finally: 35 | print('This is in the finally statement') 36 | divide(10, 2) 37 | 38 | try: 39 | a = input('Enter an integer ') 40 | raise Exception("Something strange happened") 41 | except ValueError: 42 | print("An exception happened.") -------------------------------------------------------------------------------- /sourcecode/ch_01/for_loop.py: -------------------------------------------------------------------------------- 1 | for x in range(10): 2 | print(x, end=' ') 3 | 4 | print() 5 | 6 | x, y = 0, 1 7 | for z in range(10): 8 | next = x + y 9 | x, y = y, next 10 | print('12th fib number = {}'.format(next)) 11 | -------------------------------------------------------------------------------- /sourcecode/ch_01/functions_in_python.py: -------------------------------------------------------------------------------- 1 | def scale_number(num, amount): 2 | return num * amount 3 | print(scale_number(10, 5)) 4 | print() 5 | 6 | def area_triangle(height=11, width=7.5): 7 | return 1/2 * (height * width) 8 | print(area_triangle()) 9 | print(area_triangle(height=20, width=100)) 10 | print() 11 | 12 | def multiply(*args, y=1): 13 | for x in range(len(args)): 14 | y *= args[x] 15 | return y 16 | print('multiply =', multiply(1, 2, 3, 4)) 17 | print() 18 | 19 | def key_value(**kwargs): 20 | for key, value in kwargs.items(): 21 | print('{} {}'.format(key, value)) 22 | key_value(a=5, b=10, c=15) 23 | -------------------------------------------------------------------------------- /sourcecode/ch_01/helloworld.py: -------------------------------------------------------------------------------- 1 | print('Hello World!!!') -------------------------------------------------------------------------------- /sourcecode/ch_01/if_else_statement.py: -------------------------------------------------------------------------------- 1 | x, y, z = 5, 10, 15 2 | if x < y and z > y: 3 | print(x) 4 | else: 5 | print(y) -------------------------------------------------------------------------------- /sourcecode/ch_01/list_demo.py: -------------------------------------------------------------------------------- 1 | evens = [0, 2, 4, 6, 8, 10] 2 | 3 | # reverses the list 4 | print(evens.reverse()) 5 | 6 | # adds an object to the list 7 | evens.append(100) 8 | print(evens) 9 | 10 | # merges another list with the list 11 | evens.extend([1, 3, 5, 7, 9]) 12 | print(evens) 13 | 14 | # pops an item from the list 15 | print(evens.pop()) 16 | 17 | # iterating over a list 18 | for x in evens: 19 | print(x) 20 | -------------------------------------------------------------------------------- /sourcecode/ch_01/point_class.py: -------------------------------------------------------------------------------- 1 | class Point: 2 | """Simple class in python. This is an example 3 | of a docstring, or a string that's used like a 4 | comment to document a segment of code.""" 5 | 6 | def __init__(self, x, y): 7 | self.x = x 8 | self.y = y 9 | 10 | def get_x(self): 11 | return self.x 12 | 13 | def get_y(self): 14 | return self.y 15 | 16 | def set_x(self, new_x): 17 | self.x = new_x 18 | 19 | def set_y(self, new_y): 20 | self.y = new_y 21 | 22 | def get_point(self): 23 | return self.x, self.y 24 | 25 | 26 | p = Point(5, 10) 27 | print() 28 | print(p.get_point()) 29 | 30 | p.set_x(100) 31 | p.set_y(200) 32 | print(p.get_point()) -------------------------------------------------------------------------------- /sourcecode/ch_01/python_math_operators.py: -------------------------------------------------------------------------------- 1 | print(10 + 10) 2 | print(50 - 10) 3 | print(10 * 10) 4 | print(20 ** 2) 5 | print(9 / 5) 6 | print(8 // 3) 7 | print(11 % 5) 8 | print(1e10) -------------------------------------------------------------------------------- /sourcecode/ch_01/sets_demo.py: -------------------------------------------------------------------------------- 1 | letters = {'a', 'a', 'a', 'b', 'b', 'b'} 2 | print(letters) -------------------------------------------------------------------------------- /sourcecode/ch_01/strings_in_python.py: -------------------------------------------------------------------------------- 1 | city = 'Los Angeles' 2 | # indexing: python is a zero based indexed language 3 | print(city[0]) # L 4 | print(city[3]) # empty space is a string! 5 | print(city[4]) # capital A 6 | print(city[-1]) # negative indices are permitted 7 | # len() function: gets the length of the string 8 | print(len(city)) # 11 9 | print(city[len(city)-1]) # s 10 | # concatenation: the combining of multiple strings 11 | print('john ' + 'doe ' + 'public') # john doe public 12 | # slicing: retrieves ranges of a string 13 | print(city[0:3]) # Los 14 | print(city[4:11]) # Angeles 15 | print(city[::]) # Los Angeles 16 | print(city[::2]) # LsAgls 17 | print(city[::-1]) # selegnA soL -------------------------------------------------------------------------------- /sourcecode/ch_01/swapping_variables.py: -------------------------------------------------------------------------------- 1 | x = 5 2 | y = 10 3 | z = 30 4 | x, y, z = z, x, y 5 | print(x) 6 | print(y) 7 | print(z) -------------------------------------------------------------------------------- /sourcecode/ch_01/ternary_statement.py: -------------------------------------------------------------------------------- 1 | mood = True 2 | state = 'nice' if mood else 'not so nice' 3 | print('state = {}'.format(state)) -------------------------------------------------------------------------------- /sourcecode/ch_01/tuples_demo.py: -------------------------------------------------------------------------------- 1 | nums = (1, 3, 5, 7) 2 | print(nums) -------------------------------------------------------------------------------- /sourcecode/ch_01/variables.py: -------------------------------------------------------------------------------- 1 | a = 10 2 | b = 1.598 3 | c = .1987 4 | d = 100.579 5 | 6 | print(a) 7 | print(b) 8 | print(c) 9 | print(d) -------------------------------------------------------------------------------- /sourcecode/ch_01/while_loop.py: -------------------------------------------------------------------------------- 1 | i = 0 2 | # condition 3 | while i < 10: 4 | print('i = {}'.format(i, end=' ')) # print value of i, end='' means print on same line 5 | i += 1 # increment i 6 | 7 | print() 8 | 9 | i, sum = 0, 0 10 | while i < 1000: 11 | i += 1 12 | sum += i 13 | 14 | print('The summation of 1...1000 = {}'.format(sum)) -------------------------------------------------------------------------------- /sourcecode/ch_02/autoloan_calculator.py: -------------------------------------------------------------------------------- 1 | 2 | def monthly_cost(): 3 | print('Gotta couple of questions for you...') 4 | p = float(input('Enter loan amount ')) 5 | r = float(input('Enter interest rate (%)')) 6 | n = int(input('Enter loan period (in months)')) 7 | # convert r to a decimal and divide by interest per year 8 | r = (r / 100) / 12 9 | # breaks formula down into 3 parts to reduce error 10 | # numerator 11 | top = r * (1 + r)**n 12 | # denominator 13 | bottom = ((1 + r)**n) - 1 14 | # putting it all together 15 | a = round(p * (top / bottom)) 16 | # use simple interest formula 17 | # I = Prt 18 | # In this case, I = Prn 19 | total_interest = round(p * r * n, 3) 20 | print(f'Monthly costs = ${a}. Total interest = ${total_interest} ') 21 | 22 | 23 | if __name__ == '__main__': 24 | monthly_cost() -------------------------------------------------------------------------------- /sourcecode/ch_02/mortgage_calculator.py: -------------------------------------------------------------------------------- 1 | def mortgage(): 2 | name = input('Enter your name ').capitalize() 3 | print(f"Time to calculate your mortgage payments {name}... ") 4 | principal = float(input('Enter in your principal ')) 5 | interest_rate = float(input('Enter interest rate ')) 6 | r = (interest_rate / 100) / 12 7 | n = int(input('Enter mortgage period (years) ')) 8 | # get total number of months 9 | n = n * 12 10 | numerator = r * (1 + r) ** n 11 | deno = (1 + r) ** n - 1 12 | monthly_payment = principal * (numerator / deno) 13 | monthly_payment = round(monthly_payment) 14 | total_mortgage = monthly_payment * 30 * 12 15 | print(f'Monthly payment: ${monthly_payment}, total mortgage = ${total_mortgage}') 16 | 17 | 18 | if __name__ == '__main__': 19 | mortgage() -------------------------------------------------------------------------------- /sourcecode/ch_02/spanish_translator.py: -------------------------------------------------------------------------------- 1 | ########################################################## 2 | # Spanish translator in python 3 | # A simple script that translates 4 | # popular Mexican foods from Spanish 5 | # to English, and common phrases from English 6 | # to Spanish: 7 | # 8 | # To use script simply type: python spanish_translator.py 9 | # 10 | # 11 | # By Doug Purcell 12 | # http://www.purcellconsult.com 13 | # 14 | # 15 | ########################################################### 16 | 17 | 18 | def food(): 19 | """Names for some popular mexican food items. 20 | Translate spanish food names to english. 21 | """ 22 | print('\n') 23 | spanish_to_english = { 24 | 'Birria': 'Spicy stew made with goat or mutton. ', 25 | 'Quesadilla con carne': 'season steak strips. ', 26 | 'Barbacoa': 'Slow cooked meat in soup. Beef, goat, or sheep.', 27 | 'Burrito Banado': 'Wet Burrito.', 28 | 'Huevos rancheros': '"Rancher\'s eggs." Corn tortillas, fried eggs, topped with warm salsa.', 29 | 'Coctel de camarones': 'Shrimp cocktail served cold with tomato, onion, cucumber, and cilantro. ', 30 | 'Huevos a la mexicana': 'Eggs, tomato, onion, and serrano chile. A classic.', 31 | 'Huevo con Chorizo': 'Eggs and chorizo sausage.', 32 | 'Burritos de Desayuno ': 'Breakfast burrito.', 33 | 'Chilli con carne': 'Chili with meat.', 34 | 'Lengua': 'Beef tongue, typically in tacos.', 35 | 'Tripas': 'Small intestines of farm animals that\'s cleaned, boiled, and grilled. ', 36 | 'Al pastor': 'Pork based taco based on shawarma', 37 | 'Suadero': 'Tender slow cooked beef brisket. Typically served in tacos.', 38 | 'Cabeza': 'Beef head/cheek meat. Served in soups or tacos.', 39 | 'Sesos': 'Brains from either a goat or cow. Popular taco filling.' 40 | } 41 | 42 | print('Spanish phases available for translation:') 43 | for spanish, english in spanish_to_english.items(): 44 | print(spanish) 45 | 46 | print() 47 | translate = input('Type in spanish phase you\'ll like to translate: ').capitalize() 48 | for english, spanish in spanish_to_english.items(): 49 | if translate == english: 50 | print(spanish_to_english.get(translate)) 51 | break 52 | else: 53 | print('Word is not available for translation') 54 | 55 | 56 | def general_phases(): 57 | """Shows available english phases, and then translates 58 | appropriately. 59 | """ 60 | print('\n') 61 | english_to_spanish = { 62 | 'Hello': '¡Hola! ', 63 | 'Please': 'Por favor', 64 | 'Thank you': 'Gracias', 65 | 'Where is the bathroom?': '¿Dónde está el baño?', 66 | 'I\'m sorry': 'Lo siento', 67 | 'Do you speak English?': '¿Habla usted Inglés?', 68 | 'I don\'t speak much Spanish': 'No hablo mucho español?', 69 | 'I don\'t know': 'No sé', 70 | 'Clear': 'Claro', 71 | 'Good-bye': 'Adiós', 72 | } 73 | 74 | print('English phases available for translation:') 75 | for english, spanish in english_to_spanish.items(): 76 | print(english) 77 | 78 | print() 79 | translate = input('Type English phase to translate to Espanol: ') 80 | translate = translate.capitalize() 81 | for english, spanish in english_to_spanish.items(): 82 | if translate == english: 83 | print(english_to_spanish.get(translate)) 84 | break 85 | else: 86 | print('Word is not available for translation') 87 | 88 | 89 | if __name__ == '__main__': 90 | 91 | print('Bienvenidos! What phases would you like to translate?') 92 | print('1: Common foods ') 93 | print('2: General phases') 94 | your_choice = int(input("Enter your choice: '1' or '2'")) 95 | if your_choice == 1: 96 | food() 97 | elif your_choice == 2: 98 | general_phases() 99 | else: 100 | print('Not a possible choice!') -------------------------------------------------------------------------------- /sourcecode/ch_02/temperature_converter.py: -------------------------------------------------------------------------------- 1 | def fahrenheit_to_celsius(): 2 | temp_in_fahren = float(input('Enter the temperature in Fahrenheit ')) 3 | celsius = (temp_in_fahren - 32) * 5 / 9 4 | celsius = round(celsius, 4) 5 | print(celsius, '°C') 6 | 7 | 8 | def fahrenheit_to_kelvin(): 9 | temp_in_fahren = float(input('Enter the temperature in Kelvin ')) 10 | kelvin = (temp_in_fahren - 32) / 1.8 + 273.15 11 | print(kelvin, 'K') 12 | 13 | 14 | def celsius_to_fahrenheit(): 15 | temp_in_celsius = float(input('Enter the temperature in Celsius ')) 16 | celsius_to_fahren = (temp_in_celsius * 9 / 5) + 32 17 | print(celsius_to_fahren, '°F') 18 | 19 | 20 | def celsius_to_kelvin(): 21 | temp_in_cel = float(input('Enter the temperature in Celsius ')) 22 | celsius_to_kel = (temp_in_cel + 273.15) 23 | print(celsius_to_kel, 'K') 24 | 25 | 26 | def kelvin_to_fahrenheit(): 27 | temp_in_kelvin = float(input('Enter the temperature in Kelvin ')) 28 | kelvin_to_fahren = (temp_in_kelvin - 273.15) * 9 / 5 + 32 29 | kelvin_to_fahren = round(kelvin_to_fahren, 3) 30 | print(kelvin_to_fahren, '°F') 31 | 32 | 33 | def kelvin_to_celsius(): 34 | temp_in_kelvin = float(input('Enter the temperature in Kelvin ')) 35 | kelvin_to_cel = temp_in_kelvin - 273.15 36 | kelvin_to_cel = round(kelvin_to_cel, 3) 37 | print(kelvin_to_cel, '°C') 38 | 39 | 40 | if __name__ == '__main__': 41 | message = input("""Select one of the following options: 42 | 43 | Type 'fc' to convert from Fahrenheit to Celsius. 44 | Type 'fk' to convert from Fahrenheit to Kelvin. 45 | Type 'cf' to convert from Celsius to 46 | Fahrenheit. 47 | Type 'ck' to convert from Celsius to Kelvin. 48 | Type 'kf' to convert from Kelvin to Fahrenheit. 49 | Type 'kc' to convert from Kelvin to Celsius. 50 | 51 | Enter input here: 52 | """) 53 | 54 | # casefold is for case-insensitive comparisons 55 | 56 | message = message.casefold() 57 | if message == 'fc': 58 | fahrenheit_to_celsius() 59 | elif message == 'fk': 60 | fahrenheit_to_kelvin() 61 | elif message == 'cf': 62 | celsius_to_fahrenheit() 63 | elif message == 'ck': 64 | celsius_to_kelvin() 65 | elif message == 'kf': 66 | kelvin_to_fahrenheit() 67 | elif message == 'kc': 68 | kelvin_to_celsius() 69 | else: 70 | print('Not a valid option pal!') -------------------------------------------------------------------------------- /sourcecode/ch_02/your_bio.py: -------------------------------------------------------------------------------- 1 | def questions(): 2 | """This is the part of the program that prompts the user 3 | for a bunch of questions.""" 4 | first_name = input('Enter your first name: ').capitalize() 5 | last_name = input('Enter your last name: ').capitalize() 6 | nationality = input('Enter your nationality: ').capitalize() 7 | age = int(input('Enter your age: ')) 8 | height = input('Enter feet and inches separated by commas: ') 9 | user_input = height.split(',') 10 | heights = user_input[0], user_input[1] 11 | weight = float(input('Enter weight in lbs: ')) 12 | favorite_food = input('Enter your favorite food: ').capitalize() 13 | favorite_city = input('Enter in your favorite city: ').capitalize() 14 | print() 15 | 16 | print('First name: {}'.format(first_name)) 17 | print('Last name: {}'.format(last_name)) 18 | print('Nationality: {}'.format(nationality)) 19 | print('Age: {}'.format(age)) 20 | print('Height: {} ft {} in'.format(user_input[0], user_input[1])) 21 | print('Weight: {}'.format(weight)) 22 | print('Favorite food: {}'.format(favorite_food)) 23 | print('Favorite city: {}'.format(favorite_city)) 24 | 25 | if __name__ == '__main__': 26 | # this is where your program starts 27 | questions() -------------------------------------------------------------------------------- /sourcecode/ch_03/a_game_of_dice.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | 4 | def game(): 5 | print('Welcome! You\'re Playing:') 6 | print( 7 | """ 8 | _____ ________ _____ ________ .__ 9 | / _ \ / _____/_____ _____ ____ _____/ ____\ \______ \ |__| ____ ____ 10 | / /_\ \ / \ ___\__ \ / \_/ __ \ / _ \ __\ | | \| |/ ___\/ __ \ 11 | / | \ \ \_\ \/ __ \| \ ___/ ( <_> ) | | ` \ \ \__\ ___/ 12 | \____|__ / \______ (____ /__|_| /\___ > \____/|__| /_______ /__|\___ >___ > 13 | \/ \/ \/ \/ \/ \/ \/ \/ 14 | """ 15 | ) 16 | 17 | human_bank = 1000 18 | while True: 19 | you = float(input("How much money do you want to wager? " 20 | "Your bank has ${} ".format(human_bank))) 21 | if you > 0 <= human_bank: 22 | print("You're betting ${}".format(you)) 23 | dice_roll = randint(1, 6) 24 | human_guess = float(input('What number you think the dice will roll on? ' 25 | 'Select numbers: 1-6 ')) 26 | if human_guess == dice_roll: 27 | human_bank += you 28 | print('Dice landed on {}'.format(dice_roll)) 29 | print("Congrats! You now have ${}".format(human_bank)) 30 | else: 31 | human_bank -= you 32 | print("Bummers! Dice landed on {}! Money gone...".format(dice_roll)) 33 | print("You have ${}".format(human_bank)) 34 | if human_bank == 0.0: 35 | print("Game over! You're out of cash") 36 | break 37 | play_again = input("Enter 'y' to play again or 'n' to stop ").lower() 38 | if play_again == 'y': 39 | continue 40 | elif play_again == 'n': 41 | print("Game Over...") 42 | if human_bank > 1000: 43 | print("You're lucky! You won ${} ".format(human_bank - 1000)) 44 | break 45 | elif human_bank < 1000: 46 | print("Better luck next time! You loss ${} ".format(1000 - human_bank)) 47 | break 48 | else: 49 | print("You didn't win nor you didn't lose!") 50 | break 51 | else: 52 | print('Enter a valid amount. You have ${} to bet'.format(human_bank)) 53 | game() 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /sourcecode/ch_03/california_lottery.py: -------------------------------------------------------------------------------- 1 | 2 | from random import randint 3 | from time import sleep 4 | 5 | 6 | def daily_3(): 7 | """ 8 | emulates the daily 3 9 | lottery 10 | """ 11 | print("Welcome! You're playing Daily 3.") 12 | lucky_one = randint(0, 9) 13 | lucky_two = randint(0, 9) 14 | lucky_three = randint(0, 9) 15 | 16 | guess_one = int(input('Guess your lucky number: 0 - 9 ')) 17 | guess_two = int(input('Guess your lucky number: 0 - 9 ')) 18 | guess_three = int(input('Guess your lucky number: 0 - 9 ')) 19 | 20 | print("Here's the Daily 3 results...") 21 | sleep(3) 22 | print(lucky_one) 23 | sleep(2) 24 | print(lucky_two) 25 | sleep(2) 26 | print(lucky_three) 27 | print([lucky_one,lucky_two, lucky_three]) 28 | 29 | if guess_one == lucky_one and guess_two == lucky_two and guess_three == lucky_three: 30 | print("Congrats! You won $500") 31 | else: 32 | print("Today wasn't your day! Try again.") 33 | 34 | 35 | def daily_4(): 36 | """ 37 | emulates the daily 4 38 | lottery 39 | """ 40 | print("Welcome! You're playing Daily 4.") 41 | lucky_one = randint(0, 9) 42 | lucky_two = randint(0, 9) 43 | lucky_three = randint(0, 9) 44 | lucky_four = randint(0, 9) 45 | 46 | guess_one = int(input('Guess your lucky number: 0 - 9 ')) 47 | guess_two = int(input('Guess your lucky number: 0 - 9 ')) 48 | guess_three = int(input('Guess your lucky number: 0 - 9 ')) 49 | guess_four = int(input('Guess your lucky number: 0 - 9 ')) 50 | 51 | print("Here's the Daily 4 results...") 52 | sleep(3) 53 | print(lucky_one) 54 | sleep(2) 55 | print(lucky_two) 56 | sleep(2) 57 | print(lucky_three) 58 | sleep(2) 59 | print(lucky_four) 60 | 61 | print([lucky_one, lucky_two, lucky_three, lucky_four]) 62 | 63 | if guess_one == lucky_one and guess_two == lucky_two and guess_three == lucky_three and guess_four == lucky_four: 64 | print("Congrats! You won the jackpot") 65 | else: 66 | print("Today wasn't your day! Try again.") 67 | 68 | 69 | def fantasy_5(): 70 | """ 71 | fantasy 5 are 5 numbers within the range 72 | of 1-39. 73 | """ 74 | print("Welcome! You're playing Fantasy 5.") 75 | lucky_one = randint(1, 39) 76 | lucky_two = randint(1, 39) 77 | lucky_three = randint(1, 39) 78 | lucky_four = randint(1, 39) 79 | lucky_five = randint(1, 39) 80 | 81 | guess_one = int(input('Guess your lucky number: 1 - 39 ')) 82 | guess_two = int(input('Guess your lucky number: 1 - 39 ')) 83 | guess_three = int(input('Guess your lucky number: 1 - 39 ')) 84 | guess_four = int(input('Guess your lucky number: 1 - 39 ')) 85 | guess_five = int(input('Guess your lucky number: 1 - 39 ')) 86 | 87 | print("Here's the Fantasy 5 results...") 88 | sleep(3) 89 | print(lucky_one) 90 | sleep(2) 91 | print(lucky_two) 92 | sleep(2) 93 | print(lucky_three) 94 | sleep(2) 95 | print(lucky_four) 96 | sleep(2) 97 | print(lucky_five) 98 | 99 | print([lucky_one, lucky_two, lucky_three, lucky_four, lucky_five]) 100 | 101 | if guess_one == lucky_one and guess_two == lucky_two and \ 102 | guess_three == lucky_three and guess_four == lucky_four\ 103 | and guess_five == lucky_five: 104 | print("Congrats! You won the jackpot") 105 | else: 106 | print("Today wasn't your day! Try again.") 107 | 108 | 109 | def super_lotto_plus(): 110 | """ 111 | Pick any five numbers within the range of 112 | 1-47, and then one omega number within the 113 | range of 1-27. 114 | """ 115 | print("Welcome! You're playing Super Lotto Plus.") 116 | lucky_one = randint(1, 47) 117 | lucky_two = randint(1, 47) 118 | lucky_three = randint(1, 47) 119 | lucky_four = randint(1, 47) 120 | lucky_five = randint(1, 47) 121 | lucky_six = randint(1, 27) 122 | 123 | guess_one = int(input('Guess your lucky number: 1 - 47 ')) 124 | guess_two = int(input('Guess your lucky number: 1 - 47 ')) 125 | guess_three = int(input('Guess your lucky number: 1 - 47 ')) 126 | guess_four = int(input('Guess your lucky number: 1 - 47 ')) 127 | guess_five = int(input('Guess your lucky number: 1 - 47 ')) 128 | guess_six = int(input('Guess your mega number: 1 - 27 ')) 129 | 130 | print("Here's the Super Lotto Plus results...") 131 | sleep(3) 132 | print(lucky_one) 133 | sleep(2) 134 | print(lucky_two) 135 | sleep(2) 136 | print(lucky_three) 137 | sleep(2) 138 | print(lucky_four) 139 | sleep(2) 140 | print(lucky_five) 141 | sleep(2) 142 | print(lucky_six) 143 | 144 | print([lucky_one, lucky_two, lucky_three, lucky_four, lucky_five, lucky_six]) 145 | 146 | if guess_one == lucky_one and guess_two == lucky_two and \ 147 | guess_three == lucky_three and guess_four == lucky_four \ 148 | and guess_five == lucky_five and guess_six == lucky_six: 149 | print("Congrats! You won the jackpot") 150 | else: 151 | print("Today wasn't your day! Try again.") 152 | 153 | 154 | def mega_millions(): 155 | """ 156 | 5 numbers from 1-70, and 1 number from 1-25. 157 | """ 158 | print("Welcome! You're playing Mega Millions.") 159 | lucky_one = randint(1, 70) 160 | lucky_two = randint(1, 70) 161 | lucky_three = randint(1, 70) 162 | lucky_four = randint(1, 70) 163 | lucky_five = randint(1, 70) 164 | lucky_six = randint(1, 26) 165 | 166 | guess_one = int(input('Guess your lucky number: 1 - 70 ')) 167 | guess_two = int(input('Guess your lucky number: 1 - 70 ')) 168 | guess_three = int(input('Guess your lucky number: 1 - 70 ')) 169 | guess_four = int(input('Guess your lucky number: 1 - 70 ')) 170 | guess_five = int(input('Guess your lucky number: 1 - 70 ')) 171 | guess_six = int(input('Guess your mega number: 1 - 26 ')) 172 | 173 | print("Here's the Mega Million results...") 174 | sleep(3) 175 | print(lucky_one) 176 | sleep(2) 177 | print(lucky_two) 178 | sleep(2) 179 | print(lucky_three) 180 | sleep(2) 181 | print(lucky_four) 182 | sleep(2) 183 | print(lucky_five) 184 | sleep(2) 185 | print(lucky_six) 186 | 187 | print([lucky_one, lucky_two, lucky_three, lucky_four, lucky_five, lucky_six]) 188 | 189 | if guess_one == lucky_one and guess_two == lucky_two and \ 190 | guess_three == lucky_three and guess_four == lucky_four \ 191 | and guess_five == lucky_five and guess_six == lucky_six: 192 | print("Congrats! You won the jackpot") 193 | else: 194 | print("Today wasn't your day! Try again.") 195 | 196 | 197 | def powerball(): 198 | print("Welcome! You're playing Powerball.") 199 | lucky_one = randint(1, 69) 200 | lucky_two = randint(1, 69) 201 | lucky_three = randint(1, 69) 202 | lucky_four = randint(1, 69) 203 | lucky_five = randint(1, 69) 204 | lucky_six = randint(1, 26) 205 | 206 | guess_one = int(input('Guess your lucky number: 1 - 69 ')) 207 | guess_two = int(input('Guess your lucky number: 1 - 69 ')) 208 | guess_three = int(input('Guess your lucky number: 1 - 69 ')) 209 | guess_four = int(input('Guess your lucky number: 1 - 69 ')) 210 | guess_five = int(input('Guess your lucky number: 1 - 69 ')) 211 | guess_six = int(input('Guess the powerball: 1 - 26 ')) 212 | 213 | print("Here's the Powerball results...") 214 | sleep(3) 215 | print(lucky_one) 216 | sleep(2) 217 | print(lucky_two) 218 | sleep(2) 219 | print(lucky_three) 220 | sleep(2) 221 | print(lucky_four) 222 | sleep(2) 223 | print(lucky_five) 224 | print('And thee powerball...') 225 | sleep(5) 226 | print(lucky_six) 227 | 228 | print([lucky_one, lucky_two, lucky_three, lucky_four, lucky_five, lucky_six]) 229 | 230 | if guess_one == lucky_one and guess_two == lucky_two and \ 231 | guess_three == lucky_three and guess_four == lucky_four \ 232 | and guess_five == lucky_five and guess_six == lucky_six: 233 | print("Congrats! You won the jackpot") 234 | else: 235 | print("Today wasn't your day! Try again.") 236 | 237 | 238 | if __name__ == '__main__': 239 | daily_3() -------------------------------------------------------------------------------- /sourcecode/ch_03/draw_unique_nums.py: -------------------------------------------------------------------------------- 1 | """ 2 | A very non-efficient way to randomly draw numbers 3 | and print unique output each time. 4 | """ 5 | 6 | from random import choice 7 | 8 | 9 | def straight_bet(games=3, nums=9): 10 | cycles = games 11 | pass_nums = [] 12 | roll = [x for x in range(nums + 1)] 13 | while cycles > 0: 14 | rand_one = choice(roll) 15 | rand_two = choice(roll) 16 | rand_three = choice(roll) 17 | if rand_one in pass_nums or rand_one == rand_two or rand_one == rand_three: 18 | continue 19 | elif rand_two in pass_nums or rand_two == rand_three: 20 | continue 21 | elif rand_three in pass_nums: 22 | continue 23 | else: 24 | cycles -= 1 25 | print('{} {} {}'.format(rand_one, rand_two, rand_three)) 26 | pass_nums.append(rand_one) 27 | pass_nums.append(rand_two) 28 | pass_nums.append(rand_three) 29 | roll.remove(rand_one) 30 | roll.remove(rand_two) 31 | roll.remove(rand_three) 32 | 33 | 34 | straight_bet() -------------------------------------------------------------------------------- /sourcecode/ch_03/random_person_generator.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | from random import choice 3 | from string import ascii_letters 4 | 5 | 6 | def first_name(male=None, female=None): 7 | """ 8 | creates a random person name. 9 | popular male names taken from: 10 | https://www.babble.com/pregnancy/1000-most-popular-boy-names 11 | popular female names taken from: https://www.verywellfamily.com/top-1000-baby-girl-names-2757832 12 | popular last names: https://en.wikipedia.org/wiki/List_of_most_common_surnames_in_North_America#United_States_(American) 13 | """ 14 | genders = ['m', 'f'] 15 | male_first_names = ['Liam', 'Noah', 'William', 'Logan', 'Benjamin', 'Mason', 'Elijah', 'Oliver', 'Jacob', 'James'] 16 | female_first_names = ['Emma', 'Olivia', 'Ava', 'Isabella', 'Sophia', 'Charlotte', 'Mia', 'Amelia', 'Harper', 'Evelyn'] 17 | 18 | if male: 19 | name = choice(male_first_names) 20 | return name 21 | elif female: 22 | name = choice(female_first_names) 23 | return name 24 | elif male is None and female is None: 25 | pick_gender = choice(genders) 26 | if pick_gender == 'm': 27 | alias = choice(male_first_names) 28 | return alias 29 | elif pick_gender == 'f': 30 | alias = choice(female_first_names) 31 | return alias 32 | 33 | 34 | def last_name(): 35 | """ 36 | generates last name 37 | """ 38 | last_names = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Martinez', 'Sanchez', 'Nguyen', 'Barnes'] 39 | surname = choice(last_names) 40 | return surname 41 | 42 | 43 | def full_name(male=None, female=None): 44 | """ 45 | generates the full name. 46 | returns as string or dictionary. 47 | """ 48 | email_services = ['gmail', 'aol', 'yahoo', 'aol', 'yandex', 'mail'] 49 | create_email = input("Do you want to create an email address? Enter 'y' for yes" 50 | " or 'n' for no. ").lower() 51 | 52 | def create_name(): 53 | if male: 54 | male_name = first_name(male='m') 55 | last = last_name() 56 | full = male_name + ' ' + last 57 | return full 58 | elif female: 59 | female_name = first_name(female='f') 60 | last = last_name() 61 | full = female_name + ' ' + last 62 | return full 63 | else: 64 | first = first_name() 65 | last = last_name() 66 | full = first + ' ' + last 67 | return full 68 | if create_email == 'y': 69 | email_id = { 70 | 'name': None, 71 | 'email': None 72 | } 73 | moniker = create_name() 74 | first, last = moniker.split(' ') 75 | e_address = (first + '.' + last + '@' + choice(email_services) + '.com').lower() 76 | email_id['name'] = moniker 77 | email_id['email'] = e_address 78 | return email_id 79 | elif create_email == 'n': 80 | name = create_name() 81 | return name 82 | 83 | 84 | def age(): 85 | """ 86 | creates the random person age. 87 | gives them a range from 1 to 100 88 | making the oldest possible choice a centenarian. 89 | """ 90 | return randint(1, 100) 91 | 92 | 93 | def phone_number(): 94 | """ 95 | creates the random person 96 | phone number. 97 | Lists valid North American 98 | area codes: https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes 99 | """ 100 | number = '' 101 | for x in range(1, 11): 102 | if x == 1: 103 | num = randint(2, 9) 104 | number += str(num) 105 | elif x == 4: 106 | num = randint(2, 9) 107 | number += str(num) 108 | else: 109 | num = randint(0, 9) 110 | number += str(num) 111 | if x % 3 == 0 and x <= 6: 112 | number += '-' 113 | return number 114 | 115 | 116 | def email_password(length=7): 117 | """ 118 | returns a randomly generated password 119 | using ascii characters 120 | """ 121 | return ''.join([choice(ascii_letters) for x in range(length)]) 122 | 123 | 124 | def run(): 125 | for x in range(3): 126 | print(first_name()) 127 | print() 128 | 129 | for x in range(3): 130 | print(last_name()) 131 | print() 132 | 133 | for x in range(3): 134 | print(full_name()) 135 | print() 136 | 137 | for x in range(3): 138 | print(age()) 139 | print() 140 | 141 | for x in range(3): 142 | print(phone_number()) 143 | print() 144 | 145 | for x in range(3): 146 | print(email_password()) 147 | 148 | 149 | run() 150 | -------------------------------------------------------------------------------- /sourcecode/ch_04/__pycache__/random_colors.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purcellconsult/Code-Cool-Stuff-With-Python/c553b09872a7d4e9c357cc055974b7859953a262/sourcecode/ch_04/__pycache__/random_colors.cpython-37.pyc -------------------------------------------------------------------------------- /sourcecode/ch_04/big_green_turtle.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | leonardo = turtle.Turtle() 3 | leonardo.shape('turtle') 4 | leonardo.shapesize(7.5, 7.5) 5 | leonardo.color('green') 6 | turtle.done() -------------------------------------------------------------------------------- /sourcecode/ch_04/mike_and_ike_candies.py: -------------------------------------------------------------------------------- 1 | ################################### 2 | # Mike and Ike candies 3 | # -------------------- 4 | # 5 | # 6 | # 7 | # By Doug Purcell 8 | # http://www.purcellconsult.com 9 | # 10 | ################################### 11 | 12 | import turtle 13 | from random_colors import get_random_color 14 | from random import randint 15 | 16 | 17 | def create_candies(number=70, angle=20): 18 | width = turtle.Screen().window_width() 19 | height = turtle.Screen().window_height() 20 | 21 | screen = turtle.Screen() 22 | screen.bgcolor('black') 23 | screen.screensize(width, height) 24 | turn = angle 25 | lights = turtle.Turtle() 26 | lights.speed(0) 27 | lights.hideturtle() 28 | 29 | for x in range(number): 30 | x, y = randint(-height, height), randint(-width, width) 31 | lights.pensize(50) 32 | lights.pencolor(get_random_color()) 33 | lights.right(turn) 34 | lights.forward(200) 35 | lights.penup() 36 | lights.goto(x, y) 37 | lights.pendown() 38 | turtle.done() 39 | 40 | 41 | if __name__ == '__main__': 42 | create_candies() 43 | 44 | -------------------------------------------------------------------------------- /sourcecode/ch_04/multi_color_cube.py: -------------------------------------------------------------------------------- 1 | ######################################### 2 | # Multicolor cube image in turtle 3 | # ------------------------------- 4 | # 5 | # Learn how to make a multi colored cube 6 | # in python using turtle. Color changes 7 | # every time the program runs! 8 | # 9 | # +--+--+ 10 | # | | | 11 | # +--+--+ 12 | # | | | 13 | # +--+--+ 14 | # 15 | # By Doug Purcell 16 | # http://www.purcellconsult.com 17 | # 18 | ########################################### 19 | 20 | import turtle 21 | from random_colors import get_random_color 22 | 23 | square = turtle.Turtle() 24 | square.hideturtle() 25 | 26 | for x in range(4): 27 | square.color(get_random_color(), get_random_color()) 28 | square.begin_fill() 29 | square.right(90) 30 | for y in range(4): 31 | square.forward(100) 32 | square.right(90) 33 | square.end_fill() 34 | turtle.done() -------------------------------------------------------------------------------- /sourcecode/ch_04/night.py: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Creates a night sky using the turtle 3 | # module in python. 4 | # 5 | # 6 | # 7 | # By Doug Purcell 8 | # http://www.purcellconsult.com 9 | # 10 | ####################################### 11 | 12 | import turtle 13 | from random import randint 14 | from random_colors import whites_and_pastels 15 | 16 | 17 | def create_night_sky(stars=1000): 18 | sky = turtle.Turtle() 19 | 20 | back_ground = turtle.Screen() 21 | back_ground.bgcolor('black') 22 | num = stars 23 | sky.speed(0) 24 | for x in range(num): 25 | sky.color(whites_and_pastels()) 26 | sky.begin_fill() 27 | sky.penup() 28 | sky.goto(randint(-300, 300), randint(-300, 300)) 29 | sky.circle(randint(1, 5)) 30 | sky.pendown() 31 | sky.end_fill() 32 | turtle.done() 33 | 34 | 35 | if __name__ == '__main__': 36 | create_night_sky() -------------------------------------------------------------------------------- /sourcecode/ch_04/party_lights.py: -------------------------------------------------------------------------------- 1 | ################################## 2 | # Party lights in turtle 3 | # 4 | # 5 | # By Doug Purcell 6 | # http://www.purcellconsult.com 7 | # 8 | ################################### 9 | 10 | import turtle 11 | from random_colors import get_random_color 12 | from random import randint 13 | 14 | 15 | def create_lights(number=100, angle=20, forward=100): 16 | screen = turtle.Screen() 17 | screen.bgcolor('black') 18 | screen.screensize(-300, 300) 19 | turn = angle 20 | lights = turtle.Turtle() 21 | lights.speed(0) 22 | lights.hideturtle() 23 | 24 | for x in range(200): 25 | x, y = randint(-300, 300), randint(-300, 300) 26 | lights.pensize(4) 27 | lights.pencolor(get_random_color()) 28 | lights.right(turn) 29 | lights.forward(200) 30 | lights.penup() 31 | lights.goto(x, y) 32 | lights.pendown() 33 | turtle.done() 34 | 35 | 36 | if __name__ == '__main__': 37 | create_lights() 38 | 39 | 40 | -------------------------------------------------------------------------------- /sourcecode/ch_04/random_circles.py: -------------------------------------------------------------------------------- 1 | ##################################### 2 | # Random circles in turtle 3 | # ------------------------ 4 | # Creates randomed colored circles 5 | # in python. 6 | # 7 | # 8 | # By Doug Purcell 9 | # http://www.purcellconsult.com 10 | # 11 | ##################################### 12 | 13 | import turtle 14 | from random_colors import get_random_color 15 | from random import randint 16 | 17 | 18 | def create_circles(amount=500): 19 | """ 20 | Learn how to create random circles 21 | in python. 22 | """ 23 | cir = turtle.Turtle() 24 | cir.speed(0) 25 | quantity_circles = amount 26 | length = cir.getscreen().window_width() 27 | height = cir.getscreen().window_height() 28 | for cycles in range(quantity_circles): 29 | cir.color(get_random_color()) 30 | cir.penup() 31 | x, y = randint(-length, length), randint(-height, height) 32 | cir.goto(x, y) 33 | cir.pendown() 34 | rad = randint(5, 50) 35 | cir.begin_fill() 36 | cir.color(get_random_color()) 37 | cir.pendown() 38 | cir.circle(rad) 39 | cir.end_fill() 40 | turtle.done() 41 | 42 | 43 | if __name__ == '__main__': 44 | create_circles() 45 | 46 | -------------------------------------------------------------------------------- /sourcecode/ch_04/random_colors.py: -------------------------------------------------------------------------------- 1 | #################################################################### 2 | # Random color generator with turtle 3 | # Enjoy 150 colors that you can use in 4 | # your python computer graphics! 5 | # 6 | # Taken from: https://ecsdtech.com/8-pages/121-python-turtle-colors 7 | # 8 | # 9 | # 10 | # By Doug Purcell 11 | # http://www.purcellconsult.com 12 | # 13 | ##################################################################### 14 | 15 | from random import randint 16 | 17 | turtle_colors = [ 18 | 'snow', 'snow2', 'snow3', 'snow4', 'ghostwhite', 'whitesmoke', 19 | 'gainsboro', 'floralwhite', 'oldlace', 'linen', 'antiquewhite', 20 | 'antiquewhite2', 'antiquewhite2', 'antiquewhite3', 'antiquewhite4', 21 | 'papayawhip', 'blanchedalmond','bisque', 'bisque2', 'bisque3', 'bisque4', 22 | 'peachpuff', 'peachpuff2', 'peachpuff3', 'peachpuff4', 23 | 'navajowhite', 'moccasin', 'cornsilk','cornsilk2','cornsilk3', 24 | 'cornsilk4', 'ivory','ivory2', 'ivory3', 'ivory4', 'lemonchiffon', 25 | 'seashell', 'seashell2', 'seashell3', 'seashell4', 'honeydew', 26 | 'honeydew2', 'honeydew3', 'honeydew4', 'mintcream','azure', 27 | 'aliceblue', 'lavender', 'lavenderblush', 'mistyrose', 'white', 28 | 'black', 'darkslategray', 'dimgray', 'slategray', 'lightslategray', 29 | 'gray', 'lightgray', 'midnightblue', 'navy', 'cornflowerblue', 30 | 'darkslateblue', 'slateblue', 'mediumslateblue', 'lightslateblue', 31 | 'mediumslateblue', 'lightslateblue', 'mediumblue', 'royalblue', 32 | 'blue', 'dodgerblue', 'deepskyblue', 'skyblue', 'lightskyblue', 33 | 'lightblue', 'powderblue', 'paleturquoise', 'darkturquoise', 34 | 'mediumturquoise', 'turquoise', 'cyan', 'lightcyan','cadetblue', 35 | 'mediumaquamarine', 'aquamarine', 'darkgreen', 'darkolivegreen', 36 | 'darkseagreen', 'seagreen', 'mediumseagreen', 'lightseagreen', 37 | 'palegreen', 'springgreen', 'lawngreen', 'chartreuse', 38 | 'mediumspringgreen', 'greenyellow', 'limegreen', 'yellowgreen', 39 | 'forestgreen', 'olivedrab', 'darkkhaki', 'khaki', 'palegoldenrod', 40 | 'lightgoldenrodyellow', 'lightyellow', 'yellow', 'gold', 'lightgoldenrod', 41 | 'goldenrod', 'darkgoldenrod', 'rosybrown', 'indianred', 'saddlebrown', 42 | 'sienna', 'peru', 'burlywood', 'beige', 'wheat', 'sandybrown', 'tan', 43 | 'chocolate', 'firebrick', 'brown', 'darksalmon', 'orange', 'darkorange', 44 | 'coral', 'lightcoral', 'tomato', 'orangered', 'red', 'hotpink', 'deeppink', 45 | 'pink', 'lightpink', 'palevioletred', 'maroon', 'mediumvioletred', 'violetred', 46 | 'violet', 'plum', 'orchid', 'mediumorchid', 'darkorchid', 'darkviolet', 47 | 'blueviolet', 'purple', 'mediumpurple', 'thistle' 48 | 49 | ] 50 | 51 | 52 | def number_of_colors(): 53 | """ 54 | gets the total number of 55 | colors available. 56 | """ 57 | return len(turtle_colors) 58 | 59 | 60 | def get_random_color(): 61 | """ 62 | returns a random color from 63 | all of the 150 options. 64 | """ 65 | x = randint(0, number_of_colors()-1) 66 | return turtle_colors[x] 67 | 68 | """ 69 | Use the following functions if 70 | you want to only return colors from 71 | a similar shade 72 | """ 73 | 74 | 75 | def whites_and_pastels(): 76 | """ 77 | gets a light color such as 78 | snow or cornsilk 79 | """ 80 | x = randint(0, 50) 81 | return turtle_colors[x] 82 | 83 | 84 | def grays(): 85 | """ 86 | returns colors from black 87 | to light gray 88 | """ 89 | x = randint(51, 56) 90 | return turtle_colors[x] 91 | 92 | 93 | def blues(): 94 | """ 95 | returns shades of blue. 96 | """ 97 | x = randint(58, 83) 98 | return turtle_colors[x] 99 | 100 | 101 | def greens(): 102 | """ 103 | returns shades of green. 104 | """ 105 | x = randint(83, 103) 106 | return turtle_colors[x] 107 | 108 | 109 | def yellows(): 110 | """ 111 | returns shades of yellow 112 | """ 113 | x = randint(103, 110) 114 | return turtle_colors[x] 115 | 116 | 117 | def browns(): 118 | """ 119 | returns shades of brown 120 | """ 121 | x = randint(110, 123) 122 | return turtle_colors[x] 123 | 124 | 125 | def oranges(): 126 | """ 127 | returns shades of orange. 128 | """ 129 | x = randint(123, 131) 130 | return turtle_colors[x] 131 | 132 | 133 | def pinks_violets(): 134 | """ 135 | returns shades of pink and violets. 136 | """ 137 | x = randint(131, 151) 138 | return turtle_colors[x] 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /sourcecode/ch_04/simple_turtle_animation.py: -------------------------------------------------------------------------------- 1 | ###################################### 2 | # Simple turtle animation in python 3 | # that shows a turtle rotating. 4 | # 5 | # 6 | # By Doug Purcell 7 | # http://www.purcellconsult.com 8 | # 9 | ####################################### 10 | 11 | import turtle 12 | 13 | 14 | def turtle_dance(rotate=90, cycles=500): 15 | """ 16 | a simple program to model animation with 17 | the python turtle module. To change the 18 | animation try playing with the rotation. 19 | Try changing it to .5, 1, 5, and 10 to see 20 | how it effects the program. 21 | """ 22 | tur = turtle.Turtle() 23 | tur.write('This shows a turtle spinning!', align='center', font=("Cambria", 11, "normal")) 24 | tur.shape('turtle') 25 | tur.color('green') 26 | x, y = rotate, cycles 27 | for spin in range(cycles): 28 | tur.left(x) 29 | turtle.done() 30 | 31 | 32 | if __name__ == '__main__': 33 | turtle_dance() 34 | -------------------------------------------------------------------------------- /sourcecode/ch_04/snow_flake.py: -------------------------------------------------------------------------------- 1 | ################################# 2 | # Snow flake 3 | # ---------------------------- 4 | # Draw a simple snow flake using 5 | # lines in python. 6 | # 7 | # 8 | # 9 | # 10 | # By Doug Purcell 11 | # http://www.purcellconsult.com 12 | # 13 | ################################### 14 | 15 | 16 | import turtle 17 | 18 | line = turtle.Turtle() 19 | line.hideturtle() 20 | line.pensize(3) 21 | 22 | for x in range(8): 23 | line.forward(200) 24 | line.goto(0, 0) 25 | line.left(45) 26 | turtle.done() -------------------------------------------------------------------------------- /sourcecode/ch_04/spirograph_1.py: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Spirograph creator 3 | # ------------------ 4 | # Creates spirograph using the 5 | # turtle module in python. 6 | # 7 | # Learn more about spirographs here: 8 | # http://www.mathematische-basteleien.de/spirographs.htm 9 | # 10 | # By Doug Purcell 11 | # http://www.purcellconsult.com 12 | # 13 | # 14 | ######################################## 15 | 16 | import turtle 17 | from random_colors import get_random_color 18 | 19 | 20 | def create_circles(cycles=100): 21 | """ 22 | Function for creating a spriograph 23 | Cycles is the number of iterations. 24 | """ 25 | turtle.bgcolor('black') 26 | turtle.pensize(3) # sets thickness of pencil stroke 27 | turtle.speed(0) # sets drawing to the fastest speed possible 28 | 29 | for i in range(cycles): 30 | turtle.color(get_random_color()) 31 | turtle.circle(125) # sets circle radius 32 | turtle.right(25) # turn right 25 degrees 33 | turtle.done() 34 | 35 | 36 | if __name__ == '__main__': 37 | create_circles() 38 | 39 | -------------------------------------------------------------------------------- /sourcecode/ch_04/spirograph_2.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | from random_colors import get_random_color 3 | 4 | 5 | def create_circles(cycles=30): 6 | """ 7 | Function for creating a spriograph 8 | Cycles is the number of iterations. 9 | """ 10 | turtle.bgcolor('black') 11 | turtle.pensize(3) # sets thickness of pencil stroke 12 | turtle.speed(0) # sets drawing to the fastest speed possible 13 | x = -(turtle.Screen().window_width()) 14 | 15 | for i in range(cycles): 16 | turtle.penup() 17 | turtle.goto(x,0) 18 | turtle.pendown() 19 | turtle.color(get_random_color()) 20 | turtle.circle(100) # sets circle radius 21 | x += 50 22 | turtle.done() 23 | 24 | 25 | if __name__ == '__main__': 26 | create_circles() 27 | -------------------------------------------------------------------------------- /sourcecode/ch_04/square_artwork.py: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | import turtle 3 | from random_colors import get_random_color 4 | square = turtle.Turtle() 5 | square.hideturtle() 6 | square.speed(75) 7 | for x in range(50): 8 | square.color(get_random_color(), get_random_color()) 9 | square.begin_fill() 10 | square.right(35) 11 | for y in range(4): 12 | square.forward(100) 13 | square.right(90) 14 | square.end_fill() 15 | turtle.done() 16 | ======= 17 | import turtle 18 | from random_colors import get_random_color 19 | square = turtle.Turtle() 20 | square.hideturtle() 21 | square.speed(0) 22 | for x in range(50): 23 | square.color(get_random_color(), get_random_color()) 24 | square.begin_fill() 25 | square.right(35) 26 | for y in range(4): 27 | square.forward(100) 28 | square.right(90) 29 | square.end_fill() 30 | turtle.done() 31 | >>>>>>> 27f0623c15640315fa2c7cd98302055ec6a636ad 32 | -------------------------------------------------------------------------------- /sourcecode/ch_04/square_random_color.py: -------------------------------------------------------------------------------- 1 | from random_colors import get_random_color 2 | import turtle 3 | 4 | 5 | def random_color_square(): 6 | square = turtle.Turtle() 7 | square.hideturtle() 8 | square.pensize(3) # set the border to 3 pixels 9 | square.pencolor(get_random_color()) # set border color 10 | square.color(get_random_color(), get_random_color()) # set fill and outer color 11 | square.begin_fill() 12 | for x in range(4): 13 | square.forward(100) 14 | square.right(90) 15 | square.end_fill() 16 | turtle.done() 17 | 18 | 19 | random_color_square() -------------------------------------------------------------------------------- /sourcecode/ch_04/turtle_racing_game.py: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # PyTurtle Race Game 3 | # ---------------------------- 4 | # Creates a simple yet fun little 5 | # turtle racing simulator in python using 6 | # the turtle module. Includes countdown timer 7 | # and randomly determines the speed of the turtles. 8 | # 9 | # By Doug Purcell 10 | # http://www.purcellconsult.com 11 | # 12 | ############################################ 13 | 14 | import turtle 15 | from random import choice 16 | from time import sleep 17 | 18 | 19 | class TurtleRace: 20 | 21 | def __init__(self): 22 | """ 23 | creates the various turtles as instance 24 | variables. 25 | """ 26 | self.red = turtle.Turtle(shape='turtle') 27 | self.blue = turtle.Turtle(shape='turtle') 28 | self.green = turtle.Turtle(shape='turtle') 29 | self.black = turtle.Turtle(shape='turtle') 30 | self.height = turtle.Screen().window_height() 31 | self.width = -turtle.Screen().window_width() # make it negative to start turtle farthest left possible 32 | self.finish = turtle.Turtle() 33 | self.finish.hideturtle() 34 | 35 | self.finish.speed(0) # draws graphics fastest possible 36 | self.games = 1 37 | 38 | # create starting x positions of turtles 39 | 40 | self.red_x = self.width + 100 41 | self.blue_x = self.width + 100 42 | self.green_x = self.width + 100 43 | self.black_x = self.width + 100 44 | 45 | # create speeds of turtles 46 | 47 | self.red_speed = None 48 | self.blue_speed = None 49 | self.green_speed = None 50 | self.black_speed = None 51 | 52 | def start_turtles(self): 53 | """ 54 | Draws the turtles on the 55 | screen. 56 | """ 57 | self.red.penup() 58 | self.red.color('red') 59 | self.red.goto(self.width + 100, 100) 60 | self.red.pendown() 61 | 62 | self.blue.penup() 63 | self.blue.color('blue') 64 | self.blue.goto(self.width + 100, 50) 65 | self.blue.pendown() 66 | 67 | self.green.penup() 68 | self.green.color('green') 69 | self.green.goto(self.width + 100, 0) 70 | self.green.pendown() 71 | 72 | self.black.penup() 73 | self.black.color('black') 74 | self.black.goto(self.width + 100, -50) 75 | self.black.pendown() 76 | 77 | def set_turtle_speeds(self): 78 | """ 79 | Randomly sets the speeds of 80 | the turtles. 81 | """ 82 | speeds = [x for x in range(1, 25) if x % 2 == 0] 83 | self.red_speed = choice(speeds) 84 | self.blue_speed = choice(speeds) 85 | self.green_speed = choice(speeds) 86 | self.black_speed = choice(speeds) 87 | 88 | def turtle_race(self): 89 | """ 90 | Makes the turtles actually move, 91 | and determines the winner. 92 | """ 93 | race_on = True 94 | while race_on: 95 | self.red.forward(self.red_speed) 96 | self.blue.forward(self.blue_speed) 97 | self.green.forward(self.green_speed) 98 | self.black.forward(self.black_speed) 99 | red_x, red_y = self.red.pos() 100 | 101 | if self.red.pos()[0] >= self.finish.pos()[0]: 102 | self.red.forward(self.red_speed * 2.75) 103 | self.finish.penup() 104 | self.finish.goto(-self.width, self.height / 2.9) 105 | self.finish.pendown() 106 | self.finish.write('Red Wins!', font=('Verdana', 13)) 107 | race_on = False 108 | return self.red 109 | elif self.blue.pos()[0] >= self.finish.pos()[0]: 110 | self.blue.forward(self.blue_speed * 2.75) 111 | self.finish.penup() 112 | self.finish.goto(-self.width, self.height / 2.9) 113 | self.finish.pendown() 114 | self.finish.write('Blue Wins!', font=('Verdana', 13)) 115 | race_on = False 116 | return self.blue 117 | elif self.green.pos()[0] >= self.finish.pos()[0]: 118 | self.green.forward(self.green_speed * 2.75) 119 | self.finish.penup() 120 | self.finish.goto(-self.width, self.height / 2.9) 121 | self.finish.pendown() 122 | self.finish.write('Green Wins!', font=('Verdana', 13)) 123 | race_on = False 124 | return self.green 125 | elif self.black.pos()[0] >= self.finish.pos()[0]: 126 | self.black.forward(self.black_speed * 1.75) 127 | self.finish.penup() 128 | self.finish.goto(-self.width, self.height / 2.9) 129 | self.finish.pendown() 130 | self.finish.write('Black Wins!', font=('Verdana', 13)) 131 | race_on = False 132 | return self.black 133 | 134 | def victor_dance(self): 135 | """ 136 | silly little dance the winner 137 | turtle does after winning. 138 | """ 139 | if self.turtle_race() == self.red: 140 | for x in range(50): 141 | self.red.right(90) 142 | self.red.shapesize(10, 10) 143 | elif self.turtle_race() == self.blue: 144 | for x in range(50): 145 | self.blue.right(29) 146 | self.blue.shapesize(10, 10) 147 | elif self.turtle_race() == self.green: 148 | for x in range(50): 149 | self.green.right(30) 150 | self.green.shapesize(10, 10) 151 | elif self.turtle_race() == self.black: 152 | for x in range(15): 153 | self.black.right(90) 154 | self.black.shapesize(10, 10) 155 | 156 | def finish_line(self): 157 | """ 158 | Draws the finish line 159 | and positions it on right 160 | hand portion of the screen. 161 | """ 162 | 163 | self.finish.pensize(7) 164 | self.finish.hideturtle() 165 | self.finish.penup() 166 | self.finish.goto(-self.width / 2, self.height / 3) 167 | self.finish.pendown() 168 | self.finish.right(90) 169 | 170 | for cycles in range(30): 171 | self.finish.forward(cycles) 172 | self.finish.penup() 173 | self.width = int(self.width / 2.4) 174 | self.finish.goto(-self.width, self.height / 2) 175 | self.finish.pendown() 176 | self.finish.write('Finish Line!', font=('Verdana', 13)) 177 | 178 | 179 | if __name__ == '__main__': 180 | message = turtle.Turtle() 181 | message.hideturtle() 182 | 183 | race = TurtleRace() 184 | race.start_turtles() 185 | race.finish_line() 186 | 187 | message.penup() 188 | message.goto(race.width, race.height / 2) 189 | message.pendown() 190 | 191 | """ 192 | adds countdown timer to game. 193 | """ 194 | secs = 5 195 | while secs > 0: 196 | message.write(secs, font=('Verdana', 50)) 197 | secs -= 1 198 | sleep(1) 199 | message.clear() 200 | race.set_turtle_speeds() 201 | race.turtle_race() 202 | race.victor_dance() 203 | turtle.done() 204 | -------------------------------------------------------------------------------- /sourcecode/ch_05/bmi_calculator.py: -------------------------------------------------------------------------------- 1 | ##################################### 2 | # BMI calculator app in python: 3 | # ----------------------------- 4 | # BMI aka body mass index is a tool 5 | # that's used to access and monitor 6 | # changes in body weight. 7 | # 8 | # Calculate BMI using feet/inches: 9 | # ------------------------------- 10 | # 11 | # 12 | # By Doug Purcell 13 | # http://www.purcellconsult.com 14 | # 15 | ###################################### 16 | 17 | import tkinter as tk 18 | 19 | 20 | class BMICalculator: 21 | 22 | def __init__(self, master): 23 | 24 | # BMI converter for inches and feet 25 | 26 | self.bmi_feet_inches_label = tk.Label(text='Enter height in feet') 27 | self.bmi_feet_inches_label.place(x=0, y=0, height=25, width=250) 28 | 29 | self.height_in_feet = tk.StringVar() 30 | self.weight_in_pounds = tk.StringVar() 31 | self.pounds_bmi = tk.StringVar() 32 | 33 | self.bmi_feet_inches_entry = tk.Entry(textvariable=self.height_in_feet) 34 | self.bmi_feet_inches_entry.place(x=275, y=0, height=25, width=250) 35 | self.bmi_feet_inches_entry.config(highlightbackground='white smoke') 36 | 37 | self.height_inches_label = tk.Label(text='Enter weight in pounds') 38 | self.height_inches_label.place(x=0, y=40, height=25, width=250) 39 | 40 | self.weight_pounds_entry = tk.Entry(textvariable=self.weight_in_pounds) 41 | self.weight_pounds_entry.place(x=275, y=40, height=25, width=250) 42 | self.weight_pounds_entry.config(highlightbackground='white smoke') 43 | 44 | self.bmi_button = tk.Button(text='Find BMI', command=self.bmi_in_pounds) 45 | self.bmi_button.place(x=50, y=80, width=100) 46 | 47 | self.display_bmi_inches = tk.Entry(textvariable=self.pounds_bmi) 48 | self.display_bmi_inches.place(x=200, y=80, height=25, width=100) 49 | self.display_bmi_inches.config(highlightbackground='black', bg='lavender') 50 | 51 | # BMI weight status labels 52 | 53 | tk.Label(bg='black', fg='white', text='BMI Weight Status').place(x=325, y=80) 54 | tk.Label(bg='floral white', text='Below 18.5 Under weight').place(x=325, y=95) 55 | tk.Label(bg='azure', text='Below 18.5-24.9 Normal weight').place(x=325, y=110) 56 | tk.Label(bg='yellow', fg='black', text='Below 25.0-29.9 Over weight').place(x=325, y=125) 57 | tk.Label(bg='red', fg='white', text='30.0 and above Obese').place(x=325, y=140) 58 | 59 | # BMI converter for meters and kilograms 60 | 61 | self.height_in_meters = tk.StringVar() 62 | self.weight_in_kilos = tk.StringVar() 63 | self.kilos_bmi = tk.StringVar() 64 | 65 | self.meters_and_kilo_label = tk.Label(text='Enter height in meters') 66 | self.meters_and_kilo_label.place(x=100, y=200, width=400) 67 | 68 | self.height_meters_label = tk.Label(text='Enter height in meters') 69 | self.height_meters_label.place(x=0, y=250, height=25, width=250) 70 | self.height_meters_entry = tk.Entry(textvariable=self.height_in_meters) 71 | self.height_meters_entry.place(x=275, y=250, height=25, width=250) 72 | self.height_meters_entry.config(highlightbackground='white smoke') 73 | 74 | self.bmi_meters_kilo_label = tk.Label(text='Enter weight in kilograms') 75 | self.bmi_meters_kilo_label.place(x=0, y=300, height=25, width=260) 76 | self.bmi_meters_kilo_entry = tk.Entry(textvariable=self.weight_in_kilos) 77 | self.bmi_meters_kilo_entry.place(x=275, y=300, height=25, width=260) 78 | self.bmi_meters_kilo_entry.config(highlightbackground='white smoke') 79 | 80 | self.bmi_button_meters = tk.Button(text='Find BMI', command=self.weight_in_kilograms) 81 | self.bmi_button_meters.place(x=50, y=350, width=100) 82 | 83 | self.display_bmi_meters = tk.Entry(textvariable=self.kilos_bmi) 84 | self.display_bmi_meters.place(x=200, y=350, height=25, width=100) 85 | self.display_bmi_meters.config(highlightbackground='black', bg='lavender') 86 | 87 | def bmi_in_pounds(self): 88 | """ 89 | height will be in feet, and 90 | weight will be in pounds. 91 | BMI = (weight in pounds / 92 | (height in inches) x (height in inches)) x 703 93 | """ 94 | inches = float(self.height_in_feet.get()) * 12 95 | pounds = float(self.weight_in_pounds.get()) 96 | bmi = round(float(pounds / (inches ** 2)) * 703, 2) 97 | self.pounds_bmi.set(bmi) 98 | 99 | def weight_in_kilograms(self): 100 | """ 101 | Calculate BMI using meters and kilograms: 102 | BMI = Weight in Kilograms / (Height in Meters) 103 | x (Height in Meters) 104 | """ 105 | 106 | meters = float(self.height_in_meters.get()) 107 | kilograms = float(self.bmi_meters_kilo_entry.get()) 108 | bmi = round(float(kilograms / (meters ** 2)), 2) 109 | self.kilos_bmi.set(bmi) 110 | 111 | 112 | def run(): 113 | root = tk.Tk() 114 | root.title('Body Mass Index Calculator') 115 | root.geometry('600x600') 116 | root.configure(bg='AntiqueWhite2') 117 | BMICalculator(root) 118 | tk.mainloop() 119 | 120 | 121 | if __name__ == '__main__': 122 | run() 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /sourcecode/ch_05/calculator.py: -------------------------------------------------------------------------------- 1 | #################################### 2 | # Calculator app using Tkinter 3 | # ------------------------------ 4 | # 5 | # App Features: 6 | # Add numbers 7 | # Subtract numbers 8 | # Divide numbers 9 | # Multiply numbers 10 | # Square root 11 | # Modulus 12 | # Square numbers 13 | # Backspace 14 | # 15 | # By Doug Purcell 16 | # http://www.purcellconsult.com 17 | # 18 | #################################### 19 | 20 | import tkinter as tk 21 | from math import sqrt 22 | from math import pow 23 | 24 | 25 | class CalculatorApp(object): 26 | def __init__(self): 27 | pass 28 | 29 | 30 | user_input = '' # the contents the user types into the lcd screen 31 | 32 | 33 | def press(num): 34 | """ 35 | Method updates the text to be displayed 36 | to the lcd screen when pressed. 37 | """ 38 | global user_input 39 | 40 | user_input = user_input + str(num) 41 | result.set(user_input) 42 | 43 | 44 | def back(): 45 | lcd_screen.delete(-1, last=1) 46 | 47 | 48 | def equal(): 49 | """ 50 | Method that evaluates the final expression. 51 | """ 52 | try: 53 | global user_input 54 | answer = str(eval(user_input)) 55 | result.set(answer) 56 | except: 57 | result.set('ERROR') 58 | 59 | 60 | def square_root(): 61 | """ 62 | Computes the square root. You must enter numbers 63 | first and then press the √ button. 64 | """ 65 | 66 | x = lcd_screen.get() 67 | x = sqrt(eval(x)) 68 | result.set(x) 69 | 70 | 71 | def squared(): 72 | """ 73 | Squares any number or expression. 74 | """ 75 | x = lcd_screen.get() 76 | x = pow(eval(x), 2) 77 | result.set(x) 78 | 79 | 80 | def clear(): 81 | """ 82 | clears the contents of the lcd screen. 83 | """ 84 | global user_input 85 | user_input = '' 86 | result.set(user_input) 87 | 88 | 89 | if __name__ == '__main__': 90 | root = tk.Tk() 91 | result = tk.StringVar(root) # the result of the user's actions 92 | 93 | root.configure(background='BurlyWood') 94 | 95 | root.title('Calculator App') 96 | root.geometry('300x225') 97 | 98 | lcd_screen = tk.Entry(root, textvariable=result, font="Courier 12 bold", fg='red', bg='black', border=2) 99 | lcd_screen.grid(row=0, columnspan=5, ipadx=10) 100 | lcd_screen.insert(0, '0.00000') 101 | 102 | # 7,8, 9, *, ←, and C buttons 103 | 104 | seven_button = tk.Button(root, text='7', command=lambda: press(7)) 105 | seven_button.grid(row=10, column=0) 106 | 107 | eight_button = tk.Button(root, text='8', command=lambda: press(8)) 108 | eight_button.grid(row=10, column=1) 109 | 110 | nine_button = tk.Button(root, text='9', command=lambda: press(9)) 111 | nine_button.grid(row=10, column=2) 112 | 113 | divide_button = tk.Button(root, text='÷', command=lambda: press('/')) 114 | divide_button.grid(row=10, column=3) 115 | 116 | back_button = tk.Button(root, text='←', command=lambda : back()) 117 | back_button.grid(row=10, column=4) 118 | 119 | clear_button = tk.Button(root, text='C', command=lambda: clear()) 120 | clear_button.grid(row=10, column=5) 121 | 122 | # 4, 5, 6, x, (, and ) buttons 123 | 124 | four_button = tk.Button(root, text='4', command=lambda: press(4)) 125 | four_button.grid(row=11, column=0) 126 | 127 | five_button = tk.Button(root, text='5', command=lambda: press(5)) 128 | five_button.grid(row=11, column=1) 129 | 130 | six_button = tk.Button(root, text='6', command=lambda: press(6)) 131 | six_button.grid(row=11, column=2) 132 | 133 | star_button = tk.Button(root, text='x', command=lambda: press('*')) 134 | star_button.grid(row=11, column=3) 135 | 136 | left_parentheses = tk.Button(root, text='(', command=lambda: press('(')) 137 | left_parentheses.grid(row=11, column=4) 138 | 139 | right_parentheses = tk.Button(root, text=')', command=lambda: press(')')) 140 | right_parentheses.grid(row=11, column=5) 141 | 142 | # 1, 2, 3, -, x², and √ buttons 143 | 144 | one_button = tk.Button(root, text='1', command=lambda: press(1)) 145 | one_button.grid(row=12, column=0) 146 | 147 | two_button = tk.Button(root, text='2', command=lambda: press(2)) 148 | two_button.grid(row=12, column=1) 149 | 150 | three_button = tk.Button(root, text='3', command=lambda: press(3)) 151 | three_button.grid(row=12, column=2) 152 | 153 | subtract_button = tk.Button(root, text='-', command=lambda: press('-')) 154 | subtract_button.grid(row=12, column=3) 155 | 156 | squared_button = tk.Button(root, text='x²', command=lambda: squared()) 157 | squared_button.grid(row=12, column=4) 158 | 159 | square_root_button = tk.Button(root, text='√', command=lambda: square_root()) 160 | square_root_button.grid(row=12, column=5) 161 | 162 | # 0, ., %, +, and '=' buttons 163 | 164 | zero_button = tk.Button(root, text='0', command=lambda: press(0)) 165 | zero_button.grid(row=13, column=0) 166 | 167 | decimal_button = tk.Button(root, text='.', command=lambda: press('.')) 168 | decimal_button.grid(row=13, column=1) 169 | 170 | percent_button = tk.Button(root, text='%', command=lambda: press('%')) 171 | percent_button.grid(row=13, column=2) 172 | 173 | addition_button = tk.Button(root, text='+', command=lambda: press('+')) 174 | addition_button.grid(row=13, column=3) 175 | 176 | equal_button = tk.Button(root, text='=', width=4, command=equal) 177 | equal_button.grid(row=13, column=4) 178 | 179 | root.mainloop() 180 | -------------------------------------------------------------------------------- /sourcecode/ch_05/fahrenheit_to_celsius_app.py: -------------------------------------------------------------------------------- 1 | ########################################## 2 | # A simple app that converts fahrenheit 3 | # to celsius and vice versa. 4 | # 5 | # Features: 6 | # -------- 7 | # Converts celsius to fahrenheit 8 | # Converts fahrenheit to celsius 9 | # 10 | # By Doug Purcell 11 | # http://www.purcellconsult.com 12 | # 13 | ########################################## 14 | 15 | import tkinter as tk 16 | 17 | 18 | def fahrenheit_to_celsius(): 19 | """ 20 | Fahrenheit to Celsius formula is: 21 | (x - 32) * 5/ 9 22 | """ 23 | try: 24 | celsius = float(get_fahren.get()) 25 | 26 | result = (celsius - 32) * 5 / 9 27 | 28 | # rounds float to 3 places, then converts to string 29 | result = str(round(result, 3)) + '° C' 30 | 31 | get_fahren.set(result) 32 | 33 | except ValueError as e: 34 | get_fahren.set('ERROR!!!') 35 | 36 | 37 | def celsius_to_fahrenheit(): 38 | """ 39 | Celsius to Fahrenheit formula is: 40 | F = (x x 9/5) + 32 41 | """ 42 | try: 43 | fahrenheit = float(get_celsius.get()) 44 | 45 | result = (fahrenheit * 9/5) + 32 46 | 47 | # rounds float to 3 places, then converts to string 48 | result = str(round(result, 3)) + '° F' 49 | 50 | get_celsius.set(result) 51 | 52 | except ValueError as e: 53 | get_celsius.set('ERROR!!!') 54 | 55 | 56 | root = tk.Tk() 57 | root.title('Temperature Converter') 58 | root.geometry('500x150') 59 | root.configure(bg='tan') 60 | 61 | 62 | # fahrenheit to celsius label, widget, and button 63 | 64 | fahrenheit_to_celsius_label = tk.Label(root, text='Temperature in Fahrenheit').place(x=0, y=0) 65 | 66 | get_fahren = tk.StringVar(root) 67 | 68 | fahrenheit_to_celsius_widget = tk.Entry(root, text='enter temperature', textvariable=get_fahren, bg='white smoke').place(x=200, y=0, width=225) 69 | 70 | get_fahren.set('° F') 71 | fahrenheit_to_celsius_button = tk.Button(root, text='convert', width=15, border=2, command=fahrenheit_to_celsius) 72 | 73 | fahrenheit_to_celsius_button.place(x=200, y=25, width=150) 74 | 75 | 76 | # celsius to fahrenheit label, widget, and button 77 | 78 | celsius_to_fahrenheit_label = tk.Label(text='Temperature in Celsius').place(x=0, y=85) 79 | 80 | get_celsius = tk.StringVar() 81 | 82 | get_celsius.set('° C') 83 | 84 | read_celsius_widget = tk.Entry(root, text='enter temperature', textvariable=get_celsius, bg='white smoke').place(x=200, y=85, width=225) 85 | 86 | 87 | celsius_to_fahren_button = tk.Button(root, text='convert', width=15, border=2, command=celsius_to_fahrenheit) 88 | 89 | celsius_to_fahren_button.place(x=200, y=115, width=150) 90 | 91 | 92 | root.mainloop() 93 | -------------------------------------------------------------------------------- /sourcecode/ch_05/secret_number_game.py: -------------------------------------------------------------------------------- 1 | ##################################### 2 | # Secret number game written in 3 | # python and Tkinter 4 | # ----------------------------- 5 | # 6 | # When ran gives the user a random 7 | # amount of tries within the range 8 | # of 1-15 to guess the secret number 9 | # which will be in the range of 1-100. 10 | # 11 | # By Doug Purcell 12 | # http://www.purcellconsult.com 13 | # 14 | ####################################### 15 | 16 | 17 | import tkinter as tk 18 | from random import randint 19 | 20 | 21 | class SecretNumberGame: 22 | def __init__(self): 23 | self.root = tk.Tk() 24 | self.secret_number = randint(1, 100) 25 | self.tries = randint(1, 15) 26 | 27 | # a list of StringVars 28 | 29 | self.secret_num_str_var = tk.StringVar() 30 | self.secret_num_str_var.set('Secret Number is ?????') 31 | self.your_guess = tk.StringVar() 32 | self.hint = tk.StringVar() 33 | 34 | # Labels 35 | 36 | self.game_banner = tk.Label(text='Guess Any Number From 1-100').place(x=0, y=0, width=500, height=50) 37 | self.guess_number_label = tk.Label(text='Guess Number').place(x=50, y=85, width=100) 38 | self.your_tries = tk.Label(text=f'You have {self.tries} tries').place(x=225, y=160, width=200) 39 | 40 | # Entry Widgets 41 | 42 | self.guess_number_widget = tk.Entry(textvariable=self.your_guess).place(x=225, y=75, height=40, width=150) 43 | self.the_secret_number = tk.Entry(textvariable=self.secret_num_str_var).place(x=225, y=250, width=175, 44 | height=25) 45 | # Button 46 | 47 | self.guess_budget = tk.Button(text='Guess', command=self.guess).place(x=225, y=125, width=125) 48 | 49 | def guess(self): 50 | """ 51 | method updates the GUI 52 | after each user guess. 53 | """ 54 | your_guess = self.your_guess.get() 55 | your_guess = int(your_guess) 56 | 57 | if self.tries == 1: 58 | self.your_tries = tk.Label(text=f'Game Over!!!').place(x=225, y=160, width=200) 59 | self.secret_num_str_var.set(self.secret_number) 60 | tk.Label(text=f'{self.secret_number} is the secret number!').place(x=225, y=230, width=250) 61 | self.guess_number_widget = None 62 | elif your_guess == self.secret_number: 63 | self.your_tries = tk.Label(text='You Win!!!').place(x=225, y=160, width=200) 64 | self.secret_num_str_var.set(self.secret_number) 65 | elif your_guess > self.secret_number: 66 | self.tries -= 1 67 | tk.Label(text=f'{your_guess} is too big').place(x=225, y=160, width=200) 68 | self.your_tries = tk.Label(text=f'You have {self.tries} tries').place(x=225, y=180, width=200) 69 | elif your_guess < self.secret_number: 70 | self.tries -= 1 71 | tk.Label(text=f'{your_guess} is too small').place(x=225, y=160, width=200) 72 | self.your_tries = tk.Label(text=f'You have {self.tries} tries').place(x=225, y=180, width=200) 73 | 74 | def setup(self): 75 | """ 76 | Setups the basics of the app. 77 | """ 78 | 79 | self.root.title('Secret Number Game') 80 | self.root.config(bg='tan') 81 | self.root.geometry('500x500') 82 | self.root.mainloop() 83 | 84 | def run(self): 85 | """ 86 | Fires the app. 87 | """ 88 | self.setup() 89 | 90 | 91 | if __name__ == '__main__': 92 | SecretNumberGame().run() 93 | -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_basic_app.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | root = tk.Tk() # starts a tcl/tk interpreter under the cover 4 | root.title('Simple Tkinter App') 5 | root.geometry('500x500') 6 | tk.mainloop() -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_checkbutton_demo.py: -------------------------------------------------------------------------------- 1 | ################################## 2 | # Tkinter CheckButton Demo 3 | # ------------------------ 4 | # A simple demo that shows how 5 | # to use the checkbox in python. 6 | # 7 | # 8 | # By Doug Purcell 9 | # http://www.purcellconsult.com 10 | # 11 | ################################### 12 | 13 | import tkinter as tk 14 | 15 | root = tk.Tk() 16 | root.geometry('350x300') 17 | root.title('Tkinter CheckButton Widget') 18 | 19 | var_1 = tk.IntVar() 20 | var_2 = tk.IntVar() 21 | var_3 = tk.IntVar() 22 | var_4 = tk.IntVar() 23 | var_5 = tk.IntVar() 24 | 25 | 26 | def fire(): 27 | print(var_1.get()) 28 | 29 | 30 | check_button_a = tk.Checkbutton(text=' Choice a', variable=var_1, command=fire).pack() 31 | check_button_b = tk.Checkbutton(text=' Choice b', variable=var_2, command=fire).pack() 32 | check_button_c = tk.Checkbutton(text=' Choice c', variable=var_3, command=fire).pack() 33 | check_button_d = tk.Checkbutton(text=' Choice d', variable=var_4, command=fire).pack() 34 | check_button_e = tk.Checkbutton(text=' Choice e', variable=var_5, command=fire).pack() 35 | 36 | tk.mainloop() -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_greeting_app.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | root = tk.Tk() # starts a tcl/tk interpreter under the cover 4 | root.title('Greetings App') 5 | root.geometry('350x250') 6 | 7 | 8 | def greeting(): 9 | greetings = tk.Label(root, bg='tan', borderwidth=3.5, relief='groove', text="Hello {} :-)! Welcome to the wonderful\n" 10 | "world of programming. Enjoy your stay!".format(default_value.get())) 11 | greetings.pack() 12 | 13 | 14 | default_value = tk.StringVar() 15 | default_value.set('????') 16 | 17 | first_name_label = tk.Label(root, text='What\'s your name?').pack() 18 | 19 | first_name = tk.Entry(root, textvariable=default_value).pack() 20 | 21 | button = tk.Button(text='Click Me!', command=greeting).pack() 22 | 23 | tk.mainloop() -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_grid_example.py: -------------------------------------------------------------------------------- 1 | ######################################### 2 | # Tkinter Grid Example 3 | # -------------------- 4 | # Lays out the various colors and their 5 | # labels in a declining step like 6 | # format. 7 | # 8 | # By Doug Purcell 9 | # http://www.purcellconsult.com 10 | # 11 | ########################################## 12 | 13 | import tkinter as tk 14 | 15 | root = tk.Tk() 16 | root.title('Tkinter Grid Geometry Manager') 17 | root.geometry('875x200') 18 | 19 | colors = ['black', 'red', 'orange', 'blue', 'green', 20 | 'yellow', 'brown', 'gold'] 21 | 22 | i = 0 23 | for x in colors: 24 | tk.Label(text=x, width=15).grid(row=i+1, column=i) 25 | tk.Label(bg=x, width=15).grid(row=i, column=i) 26 | i += 1 27 | tk.mainloop() -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_list_box.py: -------------------------------------------------------------------------------- 1 | ################################# 2 | # Listbox Demo Tkinter 3 | # -------------------- 4 | # 5 | # Add a widget that allows the user 6 | # to select multiple options. 7 | # 8 | # 9 | # By Doug Purcell 10 | # http://www.purcellconsult.com 11 | # 12 | ################################# 13 | 14 | import tkinter as tk 15 | 16 | root = tk.Tk() 17 | root.geometry('400x400') 18 | 19 | list_box_1_var = tk.StringVar() 20 | 21 | list_box_1 = tk.Listbox() 22 | list_box_1.pack() 23 | list_box_1.insert(tk.END, 'English') 24 | list_box_1.insert(tk.END, 'Spanish') 25 | list_box_1.insert(tk.END, 'French') 26 | list_box_1.insert(tk.END, 'German') 27 | list_box_1.insert(tk.END, 'Italian') 28 | 29 | tk.mainloop() -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_pack_example.py: -------------------------------------------------------------------------------- 1 | ################################### 2 | # Tkinter pack example 3 | # -------------------- 4 | # 5 | # Example of the pack geometry manager 6 | # 7 | # 8 | # By Doug Purcell 9 | # http://www.purcellconsult.com 10 | # 11 | ################################### 12 | 13 | 14 | import tkinter as tk 15 | 16 | root = tk.Tk() 17 | root.title('Tinker Geometry Managers') 18 | 19 | colors = ['black', 'red', 'orange', 'blue', 'green', 20 | 'yellow', 'brown', 'gold'] 21 | 22 | # The label geometry layout manager in Tkinter 23 | 24 | label_one = tk.Label(text='The Black Label').pack() 25 | label_one_black = tk.Label(root, bg=colors[0]).pack(fill=tk.X) 26 | 27 | label_two = tk.Label(text='The Red Label').pack() 28 | label_two_red = tk.Label(root, bg=colors[1]).pack(fill=tk.X) 29 | 30 | label_three = tk.Label(text='The Orange Label').pack() 31 | label_three_orange = tk.Label(root, bg=colors[2]).pack(fill=tk.X) 32 | 33 | label_four = tk.Label(text='The Blue Label').pack() 34 | label_four_blue = tk.Label(root, bg=colors[3]).pack(fill=tk.X) 35 | 36 | label_five = tk.Label(text='The Green Label').pack() 37 | label_five_blue = tk.Label(root, bg=colors[4]).pack(fill=tk.X) 38 | 39 | label_six = tk.Label(text='The Yellow Label').pack() 40 | label_six_yellow = tk.Label(root, bg=colors[5]).pack(fill=tk.X) 41 | 42 | label_seven = tk.Label(text='The Brown Label').pack() 43 | label_six_brown = tk.Label(root, bg=colors[6]).pack(fill=tk.X) 44 | 45 | label_eight = tk.Label(text='The Gold Label').pack() 46 | label_six_gold = tk.Label(root, bg=colors[7]).pack(fill=tk.X) 47 | 48 | 49 | root.mainloop() 50 | 51 | -------------------------------------------------------------------------------- /sourcecode/ch_05/tkinter_place_example.py: -------------------------------------------------------------------------------- 1 | ######################################## 2 | # Tkinter place example 3 | # -------------------- 4 | # 5 | # Example of the pack geometry manager 6 | # 7 | # 8 | # By Doug Purcell 9 | # http://www.purcellconsult.com 10 | # 11 | ######################################### 12 | 13 | 14 | import tkinter as tk 15 | 16 | root = tk.Tk() 17 | root.title('Tinker Place Geometry Manager') 18 | root.geometry('375x350') 19 | 20 | colors = ['black', 'red', 'orange', 'blue', 'green', 21 | 'yellow', 'brown', 'gold'] 22 | 23 | width, height = 0, 0 24 | for x in range(len(colors)): 25 | tk.Label(text=colors[x], width=10).place(x=0, y=height) 26 | tk.Label(bg=colors[x], width=15).place(x=100, y=height) 27 | height += 15 28 | 29 | tk.mainloop() --------------------------------------------------------------------------------