├── .DS_Store ├── Dockerfile ├── Dockerfile copy ├── README.md ├── StartHere.ipynb ├── WrapUp.ipynb ├── ch11 ├── .DS_Store ├── 1513-0_RomeoAndJulietOriginalDownload.txt ├── Ch11-executed.ipynb ├── Ch11.ipynb ├── RomeoAndJulietHeart.png ├── keys.py ├── mask_circle.png ├── mask_heart.png ├── mask_oval.png ├── mask_star.png └── pg20288_OriginalEdwardTheSecondDownload.txt ├── ch12_Mastodon ├── ch12_Mastodon.ipynb ├── keys_mastodon.py ├── locationlistener.py ├── sentimentlistener.py ├── toot_map.html ├── tootlistener.py ├── tootutilities.py └── tweetutilities.py ├── ch12_TwitterV2 ├── .DS_Store ├── ch12New-EXECUTED.ipynb ├── ch12New.ipynb ├── keys.py ├── locationlistener.py ├── sentimentlistener.py ├── tweetlistener.py └── tweetutilities.py ├── ch14 ├── Ch14-executed.ipynb ├── Ch14.ipynb ├── ave_hi_nyc_jan_1895-2018.csv ├── ave_yearly_temp_nyc_1895-2017.csv ├── ch14images │ ├── 2018-11-03_08-21-23.png │ ├── 22.png │ ├── 24digits.png │ ├── 3d1.png │ ├── 3d2.png │ ├── 3d3.png │ ├── 5.png │ ├── Blue_FlagOttawa.jpg │ ├── Blue_FlagOttawa.png │ ├── IMG_7911-Iris_virginica.jpg │ ├── IrisVersicolor-FoxRoost-Newfoundland.jpg │ ├── NYC_AVE_ANNUAL.png │ ├── NYC_seaborn_regplot.png │ ├── NYC_seaborn_regplot_with_ci.png │ ├── NYC_seaborn_regplota (1).png │ ├── NYC_seaborn_regplota.png │ ├── NYC_seaborn_regplota_with_ci.png │ ├── TypesOfMachineLearning.png │ ├── Wild_iris_KEFJ_(9025144383).jpg │ ├── avebedrooms.png │ ├── aveoccupancy.png │ ├── averooms.png │ ├── axes.png │ ├── celsius.png │ ├── confusion_nipy_spectral_r.png │ ├── digits_black.png │ ├── digits_tsne.png │ ├── distance.png │ ├── expectedVSpredicted.png │ ├── expectedVSpredictedmultiple.png │ ├── feature_selection.png │ ├── grays.png │ ├── houseage.png │ ├── housing_expect_predict.png │ ├── iris_box_plots.png │ ├── iris_decision_boundary_1neighbor.png │ ├── iris_decision_boundary_3neighbors.png │ ├── iris_histograms.png │ ├── iris_model_comparison.png │ ├── iris_pairplot.png │ ├── iris_pairplot2.png │ ├── iris_pca.png │ ├── iris_pca_centroids.png │ ├── iris_scatter_matrix (1).png │ ├── iris_scatter_matrix (2).png │ ├── iris_scatter_matrix.png │ ├── lattitude.png │ ├── longitude.png │ ├── mechanicalLinearRegression.png │ ├── medincome-predicted.png │ ├── medincome.png │ ├── nearest.png │ ├── nyc_data.png │ ├── nyc_data_with_reg_line_scaled.png │ ├── nyc_test_data_with_reg_line.png │ ├── nyc_test_data_with_reg_line_scaled.png │ ├── nyc_train_data_with_reg_line_scaled.png │ ├── population.png │ ├── sampledigit.png │ ├── sampledigit2.png │ ├── sampledigit3.png │ └── seaborn_iris.png └── digits3d.py ├── ch15 ├── .DS_Store ├── Ch15-executed.ipynb ├── Ch15.ipynb ├── Ch15_executed.ipynb ├── ch15images │ ├── convolution.png │ ├── convolution2.png │ ├── incorrect24.png │ ├── neuralnet.png │ ├── neuron.png │ ├── pooling.png │ ├── pooling2.png │ └── tensorboard.png ├── convnet.png └── mnist_cnn.keras ├── ch16 ├── Ch16_Part1.ipynb ├── Ch16_Part2_Mastodon.ipynb ├── Ch16_Part2_MastodonStructuredStreaming.ipynb ├── Ch16_Part3.ipynb ├── OLD_Ch16_Part2NewTwitter-Executed.ipynb ├── OLD_Ch16_Part2NewTwitter.ipynb ├── OLD_starttweetstream-updated.py ├── OLD_starttweetstream.py ├── OLD_tweetlistener.py ├── RomeoAndJuliet.txt ├── books.db ├── books.sql ├── ch16images │ ├── .DS_Store │ ├── SenatorTweetsByState.png │ ├── TwitterHashtags.png │ ├── pubnubSensors.png │ ├── stockprices.png │ ├── thermostat1.png │ ├── thermostat2.png │ ├── thermostat3.png │ └── top10senators.png ├── keys.py ├── keys_mastodon.py ├── senators.csv ├── simulator.py ├── simulator_dashboard.py ├── simulator_pubnub.py ├── starttootstream.py ├── state_codes.py ├── stocklistener.py └── us-states.json ├── images ├── .ipynb_checkpoints │ ├── IntroToPythonCover-checkpoint.png │ ├── PyFPCover-checkpoint.png │ ├── PythonFundamentalsLiveLessons-checkpoint.jpg │ └── course_image-checkpoint.jpg ├── IntroToPythonCover.png ├── IntroToPythonTOC.png ├── PyFPCover.png ├── PythonFundamentalsLiveLessons.jpg ├── course_image.jpg └── jhtp12Cover.jpg └── openai ├── .DS_Store ├── Chinese.mp3 ├── HavaneseDog.png ├── OpenAI_Updated-Executed.ipynb ├── OpenAI_Updated.ipynb ├── RomeoAndJuliet.txt ├── Spanish.mp3 ├── SpokenResponse.wav ├── deep_learning_intro.m4a ├── english_summary.mp3 ├── mask_heart.png ├── presentation_summary.docx └── resources ├── .DS_Store ├── 1513-0_RomeoAndJulietOriginalDownload.txt ├── ForLoop.png ├── RomeoAndJuliet.txt ├── WhatsNewInJavaOverview.m4a ├── beach.jpg ├── deep_learning_intro.m4a ├── lessonBYB_00.mp4 ├── mask_heart.png ├── outputs ├── .DS_Store ├── ActivityDiagramApp.java ├── CannonGame copy.java ├── CannonGame.java ├── ForLoopAnimation.java ├── HavaneseAnime.webp ├── HavaneseDaVinci.webp ├── HavaneseVanGogh.webp ├── RollDie.java ├── SpotOnGame.java ├── Thumbs.db ├── UMLActivityDiagramForLoop.java ├── english_speech.mp3 ├── japanese_speech.mp3 └── spanish_speech.mp3 ├── sora ├── DogsWithMistakes.mp4 ├── HavanesePuppy.mp4 └── YawningDog.mp4 ├── transcript.txt └── web.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/.DS_Store -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Based on the Dockerfiles from the Jupyter Development Team which 2 | # are Copyright (c) Jupyter Development Team and distributed under 3 | # the terms of the Modified BSD License. 4 | ARG OWNER=jupyter 5 | ARG BASE_CONTAINER=$OWNER/pyspark-notebook 6 | FROM $BASE_CONTAINER 7 | 8 | LABEL maintainer="Paul Deitel " 9 | 10 | # Fix: https://github.com/hadolint/hadolint/wiki/DL4006 11 | # Fix: https://github.com/koalaman/shellcheck/wiki/SC3014 12 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 13 | 14 | RUN mamba install --yes \ 15 | 'dnspython' \ 16 | 'folium' \ 17 | 'geopy' \ 18 | 'imageio' \ 19 | 'nltk' \ 20 | 'pymongo' \ 21 | 'scikit-learn' \ 22 | 'spacy' \ 23 | 'tweepy' 24 | 25 | RUN pip install --upgrade \ 26 | 'tensorflow' \ 27 | 'openai' \ 28 | 'beautifulsoup4' \ 29 | 'deepl' \ 30 | 'mastodon.py' \ 31 | 'better_profanity' \ 32 | 'tweet-preprocessor' \ 33 | 'ibm-watson' \ 34 | 'pubnub' \ 35 | 'textblob' \ 36 | 'wordcloud' \ 37 | 'dweepy' \ 38 | 'sounddevice' 39 | 40 | 41 | # download data required by textblob and spacy 42 | RUN python -m textblob.download_corpora && \ 43 | python -m spacy download en_core_web_sm && \ 44 | python -m spacy download en_core_web_md && \ 45 | python -m spacy download en_core_web_lg 46 | 47 | # clean up 48 | RUN mamba clean --all -f -y && \ 49 | fix-permissions "${CONDA_DIR}" && \ 50 | fix-permissions "/home/${NB_USER}" 51 | -------------------------------------------------------------------------------- /Dockerfile copy: -------------------------------------------------------------------------------- 1 | # Based on the Dockerfiles from the Jupyter Development Team which 2 | # are Copyright (c) Jupyter Development Team and distributed under 3 | # the terms of the Modified BSD License. 4 | ARG OWNER=jupyter 5 | ARG BASE_CONTAINER=$OWNER/pyspark-notebook 6 | FROM $BASE_CONTAINER 7 | 8 | LABEL maintainer="Paul Deitel " 9 | 10 | # Fix: https://github.com/hadolint/hadolint/wiki/DL4006 11 | # Fix: https://github.com/koalaman/shellcheck/wiki/SC3014 12 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 13 | 14 | RUN mamba install --yes \ 15 | 'dnspython' \ 16 | 'folium' \ 17 | 'geopy' \ 18 | 'imageio' \ 19 | 'nltk' \ 20 | 'pymongo' \ 21 | 'scikit-learn' \ 22 | 'spacy' \ 23 | 'tweepy' 24 | 25 | RUN pip install --upgrade \ 26 | 'tensorflow' \ 27 | 'openai' \ 28 | 'beautifulsoup4' \ 29 | 'deepl' \ 30 | 'mastodon.py' \ 31 | 'better_profanity' \ 32 | 'tweet-preprocessor' \ 33 | 'ibm-watson' \ 34 | 'pubnub' \ 35 | 'textblob' \ 36 | 'wordcloud' \ 37 | 'dweepy' 38 | 39 | # download data required by textblob and spacy 40 | RUN python -m textblob.download_corpora && \ 41 | python -m spacy download en_core_web_sm && \ 42 | python -m spacy download en_core_web_md && \ 43 | python -m spacy download en_core_web_lg 44 | 45 | # clean up 46 | RUN mamba clean --all -f -y && \ 47 | fix-permissions "${CONDA_DIR}" && \ 48 | fix-permissions "/home/${NB_USER}" 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonDataScienceFullThrottle 2 | 3 | Repository for my [O'Reilly Online Learning](https://learning.oreilly.com) live training course **Python Data Science Full Throttle: Introductory Artificial Intelligence (AI), Big Data and Cloud Case Studies** 4 | 5 | All the Twitter examples are updated to the Twitter V2 APIs. **However**, in March 2023, Twitter changed the API access levels. Now, you cannot use most of the examples without having **pro** (US$5000/month) or **enterprise** (US$42000/month) API access. **Twitter has hired a new CEO and we are hoping to see changes to the API levels in the future.** 6 | 7 | In the meantime, for this course, I will use the Mastodon open-source federated social media network for the data mining social media examples. 8 | 9 | 10 | # Running the Code Examples 11 | The easiest way to run most of the code examples is to use the Dockerfile to create a Docker container. 12 | 13 | From the folder containing the Dockerfile, run the command: 14 | > `docker build -t deitelpydsft .` 15 | 16 | From the root folder of this course's examples, run the `deitelpydsft` Docker container with the following command: 17 | > docker run --rm -p 8888:8888 -p 4040:4040 -it --user root \ 18 | > -v .:/home/jovyan/work deitelpydsft start.sh jupyter lab 19 | 20 | Your command-line window will show you the URL to use to access the notebooks in your web browser. 21 | 22 | # Custom Conda Environment 23 | Rather than using Docker, you can set up a custom Anaconda environment on your local computer. These are the commands I used. They create a custom environment named `pydsft` — you can choose any name you like: 24 | 25 | * Create the custom environment 26 | 27 | > conda create --name pydsft 28 | 29 | * Activate the environment you just created 30 | 31 | > conda activate pydsft 32 | 33 | * The following two commands install most of what you need for the content from ch11, ch12, ch13, ch14, ch15 and a good chunk of ch16—if you’re working from our books or videos, you might need to subsequently install a few other packages. **NOTE: You might want to install one package at a time from the following command as it can take a significant amount of time to resolve all the interdependencies if you do it all at once.** 34 | 35 | > conda install nodejs jupyterlab ipympl wordcloud spacy tweepy geopy folium scikit-learn tensorflow matplotlib seaborn pymongo dnspython imageio pyaudio pydub 36 | 37 | > pip install -U dweepy pubnub ibm-watson tweet-preprocessor textblob deep_translator deepL 38 | 39 | The `pip` command is needed because a few packages are not available through the `conda` repository. 40 | 41 | If any package install fails with `conda` on Windows, use `pip` to install it. 42 | 43 | I'll keep this repository up-to-date with any changes I make for future presentations. 44 | 45 | **These files are for your personal use and may not be redistributed or reposted.** 46 | 47 | If you have any questions, open an issue in the Issues tab or email us: deitel at deitel dot com. 48 | 49 | Copyright 2019 by Deitel & Associates, Inc. and Pearson Education, Inc. All Rights Reserved. 50 | 51 | # Setup for Executing the Examples 52 | The notebooks contain links to my videos and book on O'Reilly Online Learning where I discuss setup issues. 53 | 54 | # Our Books on Which These Examples Are Based 55 | The content of this course is based on our book Python for Programmers, which is a subset of our book Intro to Python for Computer Science and Data Science: Learning to Program with AI, Big Data and the Cloud. 56 | 57 | ![Cover image for Python for Programmers](https://deitel.com/wp-content/uploads/2020/01/python-for-programmers.jpg) 58 | 59 | The authors and publisher of this book have used their best efforts in preparing this book. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. The authors and publisher make no warranty of any kind, expressed or implied, with regard to these programs or to the documentation contained in this book. The authors and publisher shall not be liable in any event for incidental or consequential damages in connection with, or arising out of, the furnishing, performance, or use of these programs. 60 | -------------------------------------------------------------------------------- /WrapUp.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "© 2023 by Pearson Education, Inc. All Rights Reserved. The content in this notebook is based on the textbook [**Intro Python for Computer Science and Data Science**](https://amzn.to/2YU0QTJ) and our professional book [**Python for Programmers**](https://amzn.to/2VvdnxE) — Please do not purchase both. The professional book is a subset of the textbook." 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "
" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "slideshow": { 21 | "slide_type": "slide" 22 | } 23 | }, 24 | "source": [ 25 | "# Wrap-Up\n", 26 | "### Thank You for Coming!\n", 27 | "* Please fill out the **course survey**. \n", 28 | " * All comments, criticisms and suggestions are welcome.\n", 29 | "* Like what you saw? **Please send testimonial comments to paul@deitel.com**. We'd love to feature your comments in our marketing for future courses." 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "
" 37 | ] 38 | }, 39 | { 40 | "attachments": {}, 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "slideshow": { 44 | "slide_type": "slide" 45 | }, 46 | "tags": [] 47 | }, 48 | "source": [ 49 | "# My Upcoming O'Reilly Live Training Courses\n", 50 | "https://deitel.com/LearnWithDeitel\n", 51 | "\n", 52 | "* **May 6**—Python Full Throttle (with updates through 3.13)\n", 53 | "* **May 13** —Modern C++ Full Throttle: Intro to C++20 & the Standard Library — A Presentation-Only Intro\n", 54 | "* **June 4**—Java Full Throttle (with updates through Java 24)\n", 55 | "* **June 10**—Python Full Throttle (with updates through 3.13)\n", 56 | "* **July 8**—Python Full Throttle (with updates through 3.13)\n", 57 | "* **July 15**—Python® Data Science Full Throttle: Introductory Artificial Intelligence (AI), Big Data and Cloud Case Studies\n", 58 | "* **Auguts 5**—Modern C++ Full Throttle: Intro to C++20 & the Standard Library (with C++23 updates)\n", 59 | "* **Auguts 26**—Python Full Throttle (with updates through 3.13)\n" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "
" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "slideshow": { 73 | "slide_type": "slide" 74 | }, 75 | "tags": [] 76 | }, 77 | "source": [ 78 | "## New C++20-Based Full Throttle Courses\n", 79 | "Updated titles will appear on learning.oreilly.com soon\n", 80 | "\n", 81 | "1. **Modern C++ Full Throttle with Paul Deitel: Intro to C++20 & the Standard Library**\n", 82 | "> Presentation-Only Intro to Fundamentals, Arrays, Vectors, Pointers, OOP, Ranges, Views, Functional Programming; Brief Intro to Concepts, Modules & Coroutines\n", 83 | "\n", 84 | "2. **C++20 “Big Four” Full Throttle with Paul Deitel: Ranges, Concepts, Modules, Coroutines & More** \n", 85 | "Under development. **Watch the videos now** at https://learning.oreilly.com/videos/c-20-fundamentals/9780136875185\n", 86 | "> In-Depth, Presentation-Only Treatment of the Big Four, Containers, Iterators, Algorithms, Views, Functional Programming, Templates, Metaprogramming, Concurrency\n" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "
" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": { 99 | "slideshow": { 100 | "slide_type": "slide" 101 | } 102 | }, 103 | "source": [ 104 | "# Deitel Python on O'Reilly:
https://deitel.com/LearnWithPaul\n", 105 | "
\"Python   \n", 106 | "
\"Intro
Buy on Amazon
\n", 107 | "
\"Python
Buy on Amazon
" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "
" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "# Java How to Program, 12/e and Java for Programmers, 5/e\n", 122 | "\"Java\n", 123 | "\n", 124 | "\"Java\n", 125 | "\n", 126 | "* **Java How to Program, 12/e** in production\n", 127 | " * TOC/Preface posted at https://deitel.com/jhtp12\n", 128 | "* **Java for Programmers, 5/e** and **Java Fundamentals LiveLessons. 3/e** in production—will be posted here on O'Reilly\n", 129 | "* **20+ hours of new Java Fundamentals, 3/e videos already posted at https://learning.oreilly.com/videos/java-fundamentals-with/9780135353134**" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "
" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": { 142 | "slideshow": { 143 | "slide_type": "slide" 144 | }, 145 | "tags": [] 146 | }, 147 | "source": [ 148 | "# On O'Reilly:
**C++20 for Programmers** and
**C++20 LiveLessons** Sneak Peek \n", 149 | "https://deitel.com/LearnWithDeitel\n", 150 | "\n", 151 | "\"C++   \"C++20\n" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": { 157 | "tags": [] 158 | }, 159 | "source": [ 160 | "
" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": { 166 | "slideshow": { 167 | "slide_type": "slide" 168 | }, 169 | "tags": [] 170 | }, 171 | "source": [ 172 | "# C++ How to Program: An Objects-Natural Approach, 11/e\n", 173 | "\n", 174 | "\"C++\n", 175 | "\n", 176 | "* https://deitel.com/cpphtp11\n", 177 | "* One year more up-to-date than **C++20 for Programmers**\n", 178 | "* No more print textbooks\n", 179 | "* e-book formats: **Amazon Kindle** (and other e-readers), **https://VitalSource.com**, **https://RedShelf.com**\n", 180 | "* **Pearson+ eText** (includes VideoNotes for Chapters 1-10) — https://pearson.com\n", 181 | "* **Pearson Revel** (Pearson eText + VideoNotes for Chapters 1-10 + graded assessments) — https://revel.pearson.com" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "
" 189 | ] 190 | }, 191 | { 192 | "attachments": {}, 193 | "cell_type": "markdown", 194 | "metadata": { 195 | "slideshow": { 196 | "slide_type": "slide" 197 | } 198 | }, 199 | "source": [ 200 | "# Contact Info\n", 201 | "* **Questions? **\n", 202 | "* https://deitel.com\n", 203 | "* Deitel on O'Reilly: https://deitel.com/LearnWithDeitel\n", 204 | "* Facebook: https://facebook.com/DeitelFan\n", 205 | "* Meta Threads: @DeitelFan\n", 206 | "* X: https://X.com/deitel (@deitel)\n", 207 | "* LinkedIn: https://linkedin.com/company/deitel-&-associates\n", 208 | "* YouTube: https://youtube.com/DeitelTV" 209 | ] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "metadata": {}, 214 | "source": [ 215 | "
" 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": {}, 221 | "source": [ 222 | "© 2023 by Pearson Education, Inc. All Rights Reserved. The content in this notebook is based on the textbook [**Intro Python for Computer Science and Data Science**](https://amzn.to/2YU0QTJ) and our professional book [**Python for Programmers**](https://amzn.to/2VvdnxE) — Please do not purchase both. The professional book is a subset of the textbook." 223 | ] 224 | } 225 | ], 226 | "metadata": { 227 | "kernelspec": { 228 | "display_name": "Python 3 (ipykernel)", 229 | "language": "python", 230 | "name": "python3" 231 | }, 232 | "language_info": { 233 | "codemirror_mode": { 234 | "name": "ipython", 235 | "version": 3 236 | }, 237 | "file_extension": ".py", 238 | "mimetype": "text/x-python", 239 | "name": "python", 240 | "nbconvert_exporter": "python", 241 | "pygments_lexer": "ipython3", 242 | "version": "3.11.0" 243 | }, 244 | "nbTranslate": { 245 | "displayLangs": [ 246 | "*" 247 | ], 248 | "hotkey": "alt-t", 249 | "langInMainMenu": true, 250 | "sourceLang": "en", 251 | "targetLang": "fr", 252 | "useGoogleTranslate": true 253 | } 254 | }, 255 | "nbformat": 4, 256 | "nbformat_minor": 4 257 | } 258 | -------------------------------------------------------------------------------- /ch11/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/.DS_Store -------------------------------------------------------------------------------- /ch11/RomeoAndJulietHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/RomeoAndJulietHeart.png -------------------------------------------------------------------------------- /ch11/keys.py: -------------------------------------------------------------------------------- 1 | # Sign up for free account and get free key at https://detectlanguage.com/documentation 2 | deepL_key = 'YOUR KEY HERE' 3 | -------------------------------------------------------------------------------- /ch11/mask_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/mask_circle.png -------------------------------------------------------------------------------- /ch11/mask_heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/mask_heart.png -------------------------------------------------------------------------------- /ch11/mask_oval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/mask_oval.png -------------------------------------------------------------------------------- /ch11/mask_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch11/mask_star.png -------------------------------------------------------------------------------- /ch12_Mastodon/keys_mastodon.py: -------------------------------------------------------------------------------- 1 | # insert your Mastodon username and password in the strings below 2 | usr = '' 3 | pwd = '' 4 | 5 | # get DeepL key 6 | # 1. Go to https://www.deepl.com/pro#developer 7 | # 2. Click Sign up for free 8 | # 3. Under DeepL API Free click Sign up for free 9 | # 4. Specify an email/password and click Continue 10 | # 5. Fill in the form and provide a credit card, then click Continue 11 | # CC required to prevent “fraudulent multiple registrations” 12 | # 6. Read the terms and, if you agree, click Sign up for free 13 | # 7. Click the Account Management link on the thank you page 14 | # 8. Click the Account tab and scroll to Authentication Key for DeepL API 15 | # 9. Paste key into string below (make sure you have no spaces before or 16 | # after your key in the string) 17 | deepL_key = '' 18 | 19 | 20 | # get ipgeolocation.io API key 21 | # 1. Go to https://ipgeolocation.io/signup.html 22 | # 2. Sign up for a free account 23 | # 3. In your Dashboard, copy the API key 24 | # 4. Paste the API key into string below (make sure you have no spaces 25 | # before or after your key in the string) 26 | ipgeolocation_key = '' -------------------------------------------------------------------------------- /ch12_Mastodon/locationlistener.py: -------------------------------------------------------------------------------- 1 | # locationlistener.py 2 | """Receives toots and stores a list of dictionaries containing 3 | each toot's username/content, server domain and server location.""" 4 | import keys_mastodon 5 | import tootutilities 6 | from mastodon import StreamListener 7 | from bs4 import BeautifulSoup 8 | import deepl 9 | import preprocessor as p 10 | from textblob import TextBlob 11 | 12 | # stream will be set to the stream handle so we can close 13 | # the stream after a specified number of toots are received 14 | location_listener_stream = None 15 | 16 | class LocationListener(StreamListener): 17 | """Handles incoming Toot stream to get location data.""" 18 | 19 | def __init__(self, counts_dict, toots_list, limit=10): 20 | """Configure the LocationListener.""" 21 | self.toots_list = toots_list 22 | self.counts_dict = counts_dict 23 | self.TOOT_LIMIT = limit 24 | 25 | def on_update(self, status): 26 | """Called when Mastodon pushes a new toot to you.""" 27 | 28 | # get toot's username, text and location 29 | toot_data = tootutilities.get_toot_content(status) 30 | self.counts_dict['total_toots'] += 1 # it's an original toot 31 | 32 | # ignore toots with no server location--can't plot on a map 33 | if not toot_data.get('location'): 34 | return 35 | 36 | self.counts_dict['locations'] += 1 37 | self.toots_list.append(toot_data) # store the toot 38 | 39 | print(f"{self.counts_dict['locations']:2}: {toot_data['username']}") 40 | 41 | # if TOOT_LIMIT is reached, terminate streaming 42 | if self.counts_dict['locations'] == self.TOOT_LIMIT: 43 | location_listener_stream.close() 44 | 45 | 46 | 47 | ########################################################################## 48 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 49 | # Pearson Education, Inc. All Rights Reserved. # 50 | # # 51 | # DISCLAIMER: The authors and publisher of this book have used their # 52 | # best efforts in preparing the book. These efforts include the # 53 | # development, research, and testing of the theories and programs # 54 | # to determine their effectiveness. The authors and publisher make # 55 | # no warranty of any kind, expressed or implied, with regard to these # 56 | # programs or to the documentation contained in these books. The authors # 57 | # and publisher shall not be liable in any event for incidental or # 58 | # consequential damages in connection with, or arising out of, the # 59 | # furnishing, performance, or use of these programs. # 60 | ########################################################################## 61 | -------------------------------------------------------------------------------- /ch12_Mastodon/sentimentlistener.py: -------------------------------------------------------------------------------- 1 | # sentimentlisener.py 2 | """Tallies the number of positive, neutral and negative toots.""" 3 | import keys_mastodon 4 | from better_profanity import profanity 5 | from mastodon import StreamListener 6 | from bs4 import BeautifulSoup 7 | import deepl 8 | import preprocessor as p 9 | from textblob import TextBlob 10 | 11 | # load censored words list 12 | profanity.load_censor_words() 13 | 14 | # stream will be set to the stream handle so we can close 15 | # the stream after a specified number of toots are received 16 | sentiment_listener_stream = None 17 | 18 | # translator to autodetect source language and return English 19 | translator = deepl.Translator(keys_mastodon.deepL_key) 20 | 21 | class SentimentListener(StreamListener): 22 | """Handles incoming Tweet stream.""" 23 | 24 | def __init__(self, sentiment_dict, limit=10): 25 | """Configure the SentimentListener.""" 26 | self.sentiment_dict = sentiment_dict 27 | self.toot_count = 0 28 | self.TOOT_LIMIT = limit 29 | 30 | # tweet-preprocessor remove @ mentions, emojis, hashtags, URLs 31 | p.set_options(p.OPT.MENTION, p.OPT.EMOJI, p.OPT.HASHTAG, p.OPT.URL) 32 | 33 | def on_update(self, status): 34 | """Called when Mastodon pushes a new toot to you.""" 35 | 36 | # if the toot is not a retoot 37 | if status.reblogs_count == 0: 38 | # remove all HTML/CSS tags and commands 39 | plain_text = BeautifulSoup( 40 | status.content, 'html.parser').get_text() 41 | 42 | # clean the toot 43 | text = p.clean(plain_text) 44 | 45 | # possibly translate plain_text 46 | if status.language and not status.language.startswith('en'): 47 | try: 48 | result = translator.translate_text( 49 | plain_text, target_lang='en-us') 50 | text = profanity.censor(result.text) # save translated text 51 | except: 52 | text = 'toot was empty' 53 | 54 | # update self.sentiment_dict with the polarity 55 | blob = TextBlob(text) 56 | if blob.sentiment.polarity > 0.1: 57 | sentiment = '+' 58 | self.sentiment_dict['positive'] += 1 59 | elif blob.sentiment.polarity < -0.1: 60 | sentiment = '-' 61 | self.sentiment_dict['negative'] += 1 62 | else: 63 | sentiment = ' ' 64 | self.sentiment_dict['neutral'] += 1 65 | 66 | # display the toot 67 | print(f'{sentiment} {status.account.username}: {text}\n') 68 | 69 | self.toot_count += 1 # track number of toots processed 70 | 71 | # if TOOT_LIMIT reached, terminate streaming 72 | if self.toot_count == self.TOOT_LIMIT: 73 | sentiment_listener_stream.close() 74 | 75 | 76 | ########################################################################## 77 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 78 | # Pearson Education, Inc. All Rights Reserved. # 79 | # # 80 | # DISCLAIMER: The authors and publisher of this book have used their # 81 | # best efforts in preparing the book. These efforts include the # 82 | # development, research, and testing of the theories and programs # 83 | # to determine their effectiveness. The authors and publisher make # 84 | # no warranty of any kind, expressed or implied, with regard to these # 85 | # programs or to the documentation contained in these books. The authors # 86 | # and publisher shall not be liable in any event for incidental or # 87 | # consequential damages in connection with, or arising out of, the # 88 | # furnishing, performance, or use of these programs. # 89 | ########################################################################## 90 | -------------------------------------------------------------------------------- /ch12_Mastodon/tootlistener.py: -------------------------------------------------------------------------------- 1 | # tootlistener.py 2 | """StreamListener subclass that processes toots as they arrive.""" 3 | from mastodon import StreamListener 4 | import tootutilities 5 | 6 | # Global variable toot_listener_stream will be set to the stream handle so 7 | # we can close the stream after a specified number of toots are received 8 | toot_listener_stream = None 9 | 10 | class TootListener(StreamListener): 11 | """Handles incoming toot stream.""" 12 | 13 | def __init__(self, limit=10): 14 | """Create instance variables for tracking number of tweets.""" 15 | self.toot_count = 0 16 | self.TOOT_LIMIT = limit 17 | 18 | def on_update(self, status): 19 | """Called when your listener receives a toot (status).""" 20 | tootutilities.print_toot(status) 21 | print() 22 | self.toot_count += 1 # track number of toots received 23 | 24 | # if TOOT_LIMIT is reached, close the stream 25 | if self.toot_count == self.TOOT_LIMIT: 26 | toot_listener_stream.close() 27 | 28 | ########################################################################## 29 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 30 | # Pearson Education, Inc. All Rights Reserved. # 31 | # # 32 | # DISCLAIMER: The authors and publisher of this book have used their # 33 | # best efforts in preparing the book. These efforts include the # 34 | # development, research, and testing of the theories and programs # 35 | # to determine their effectiveness. The authors and publisher make # 36 | # no warranty of any kind, expressed or implied, with regard to these # 37 | # programs or to the documentation contained in these books. The authors # 38 | # and publisher shall not be liable in any event for incidental or # 39 | # consequential damages in connection with, or arising out of, the # 40 | # furnishing, performance, or use of these programs. # 41 | ########################################################################## 42 | -------------------------------------------------------------------------------- /ch12_Mastodon/tootutilities.py: -------------------------------------------------------------------------------- 1 | # tweetutilities.py 2 | """Utility functions for interacting with Tweepy objects.""" 3 | from better_profanity import profanity 4 | from bs4 import BeautifulSoup 5 | import deepl 6 | from geopy import ArcGIS 7 | import keys_mastodon 8 | import preprocessor as p 9 | import requests 10 | import socket 11 | import time 12 | from urllib.parse import urlparse 13 | from IPython.display import display, HTML 14 | 15 | # load censored words list 16 | profanity.load_censor_words() 17 | 18 | # translator to autodetect source language and return English 19 | translator = deepl.Translator(keys_mastodon.deepL_key) 20 | 21 | # tweet-preprocessor remove @ mentions, emojis, hashtags, URLs 22 | p.set_options(p.OPT.MENTION, p.OPT.EMOJI, p.OPT.HASHTAG, p.OPT.URL) 23 | 24 | def print_toot(toot): 25 | """Prints one toot's username and content (translated, if not English).""" 26 | 27 | # display the username of the sender 28 | print(f'{toot.account.username}:') 29 | 30 | # display toot text 31 | if toot.language and toot.language.startswith('en'): 32 | # render HTML version of toot in an HTML div indented 0.5 inches 33 | text = profanity.censor(toot.content) 34 | display(HTML(f'
{text}
')) 35 | 36 | # if the language is not English, display original & translated text 37 | else: 38 | # render HTML version of toot in an HTML div indented 0.5 inches 39 | print(f'ORIGINAL: ') 40 | display(HTML(f'
{toot.content}
')) 41 | 42 | # remove HTML 43 | soup = BeautifulSoup(toot.content, 'html.parser') 44 | content = soup.get_text() # remove all HTML/CSS tags and commands 45 | 46 | # translate content 47 | try: 48 | result = translator.translate_text(content, target_lang='en-us') 49 | text = profanity.censor(result.text) 50 | except: 51 | text = 'toot was empty' 52 | 53 | # render HTML version of toot in an HTML div indented 0.5 inches 54 | print(f'TRANSLATED: ') 55 | display(HTML(f'
{text}
')) 56 | 57 | def print_toots(toots): 58 | """For each toot in toots, call print_toot to display 59 | the username of the sender and toot text.""" 60 | for toot in toots: 61 | print_toot(toot) 62 | 63 | def get_domain_location_from_url(url): 64 | """Parse the domain from url, then look up the IP address 65 | and get its city. 66 | 67 | Get a key at for ipgeolocation.io web service at: 68 | https://ipgeolocation.io/signup.html 69 | """ 70 | 71 | # get domain from url argument using Python 72 | # urllib.parse module's urlparse function 73 | domain = urlparse(url).netloc 74 | 75 | # get IP address for hostname using Python 76 | # socket module's gethostbyname function 77 | ip_address = socket.gethostbyname(domain) 78 | 79 | # URL to access ipgeolocation.io web services 80 | ipgeolocation_url = ('https://api.ipgeolocation.io/ipgeo?apiKey=' + 81 | keys_mastodon.ipgeolocation_key + f'&ip={ip_address}') 82 | 83 | # use Python requests module to invoke web service 84 | response = requests.get(ipgeolocation_url) 85 | 86 | # if successful get the location 87 | if response.status_code == 200: 88 | data = response.json() # convert JSON to dictionary 89 | location = (f"{data['city']}, {data['state_prov']}, " + 90 | f"{data['country_code2']}") 91 | return location 92 | else: 93 | print('Error getting location\n', 94 | f'{response.status_code}: {response.text}') 95 | return None 96 | 97 | def get_toot_content(toot): 98 | """Return dictionary with username of toot sender, toot content 99 | translated to English (if necessary) and the sender account's 100 | Mastodon server domain.""" 101 | 102 | fields = {} 103 | fields['username'] = toot.account.username 104 | 105 | # possibly translate plain_text 106 | if toot.language and not toot.language.startswith('en'): 107 | try: 108 | result = translator.translate_text( 109 | toot.content, target_lang='en-us') 110 | 111 | # save translated text 112 | fields['text'] = profanity.censor(result.text) 113 | except: 114 | fields['text'] = None 115 | else: 116 | fields['text'] = profanity.censor(toot.content) 117 | 118 | # look up server location 119 | fields['location'] = get_domain_location_from_url(toot.url) 120 | 121 | return fields 122 | 123 | def get_geocodes(toot_list): 124 | """Get the latitude and longitude for each tweet's location. 125 | Returns the number of tweets with invalid location data.""" 126 | 127 | print('Getting coordinates for mastodon server locations...') 128 | geo = ArcGIS() # geocoder 129 | bad_locations = 0 130 | 131 | for toot in toot_list: 132 | processed = False 133 | delay = .1 # used if OpenMapQuest times out to delay next call 134 | while not processed: 135 | try: # get coordinates for tweet['location'] 136 | geo_location = geo.geocode(toot['location']) 137 | processed = True 138 | except: # timed out, so wait before trying again 139 | print('Service timed out. Waiting.') 140 | time.sleep(delay) 141 | delay += .1 142 | print(f'{geo_location=}') 143 | if geo_location: 144 | toot['latitude'] = geo_location.latitude 145 | toot['longitude'] = geo_location.longitude 146 | else: 147 | bad_locations += 1 # toot['location'] was invalid 148 | 149 | print('Done geocoding') 150 | return bad_locations 151 | 152 | 153 | ########################################################################## 154 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 155 | # Pearson Education, Inc. All Rights Reserved. # 156 | # # 157 | # DISCLAIMER: The authors and publisher of this book have used their # 158 | # best efforts in preparing the book. These efforts include the # 159 | # development, research, and testing of the theories and programs # 160 | # to determine their effectiveness. The authors and publisher make # 161 | # no warranty of any kind, expressed or implied, with regard to these # 162 | # programs or to the documentation contained in these books. The authors # 163 | # and publisher shall not be liable in any event for incidental or # 164 | # consequential damages in connection with, or arising out of, the # 165 | # furnishing, performance, or use of these programs. # 166 | ########################################################################## 167 | -------------------------------------------------------------------------------- /ch12_Mastodon/tweetutilities.py: -------------------------------------------------------------------------------- 1 | # tweetutilities.py 2 | """Utility functions for interacting with Tweepy objects.""" 3 | import deepl 4 | #from deep_translator import GoogleTranslator 5 | from geopy import ArcGIS 6 | from geopy import OpenMapQuest 7 | import keys 8 | import time 9 | import tweepy 10 | 11 | def print_tweets(tweets): 12 | # translator to autodetect source language and return English 13 | # translator = GoogleTranslator(source='auto', target='en') 14 | translator = deepl.Translator(keys.deepL_key) 15 | 16 | """For each tweet in tweets, display the username of the sender 17 | and tweet text. If the language is not English, translate the text 18 | with Deep Translator.""" 19 | for tweet, user in zip(tweets.data, tweets.includes['users']): 20 | print(f'{user.username}:', end=' ') 21 | #print(f'{tweet.text}\n') 22 | if 'en' in tweet.lang: 23 | print(f'{tweet.text}\n') 24 | elif 'und' not in tweet.lang: # translate to English first 25 | print(f'\n ORIGINAL: {tweet.text}') 26 | result = translator.translate_text(tweet.text, target_lang='en-us') 27 | print(f'TRANSLATED: {result.text}\n') 28 | 29 | def get_tweet_content(response): 30 | """Return dictionary with data from tweet.""" 31 | fields = {} 32 | fields['username'] = response.includes['users'][0].username 33 | fields['text'] = response.data.text 34 | fields['location'] = response.includes['users'][0].location 35 | 36 | return fields 37 | 38 | def get_geocodes(tweet_list): 39 | """Get the latitude and longitude for each tweet's location. 40 | Returns the number of tweets with invalid location data.""" 41 | print('Getting coordinates for tweet locations...') 42 | # geo = OpenMapQuest(api_key=keys.mapquest_key) # geocoder 43 | geo = ArcGIS() # geocoder 44 | bad_locations = 0 45 | 46 | for tweet in tweet_list: 47 | processed = False 48 | delay = .1 # used if OpenMapQuest times out to delay next call 49 | while not processed: 50 | try: # get coordinates for tweet['location'] 51 | geo_location = geo.geocode(tweet['location']) 52 | processed = True 53 | except: # timed out, so wait before trying again 54 | print('Service timed out. Waiting.') 55 | time.sleep(delay) 56 | delay += .1 57 | 58 | if geo_location: 59 | tweet['latitude'] = geo_location.latitude 60 | tweet['longitude'] = geo_location.longitude 61 | else: 62 | bad_locations += 1 # tweet['location'] was invalid 63 | 64 | print('Done geocoding') 65 | return bad_locations 66 | 67 | 68 | ########################################################################## 69 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 70 | # Pearson Education, Inc. All Rights Reserved. # 71 | # # 72 | # DISCLAIMER: The authors and publisher of this book have used their # 73 | # best efforts in preparing the book. These efforts include the # 74 | # development, research, and testing of the theories and programs # 75 | # to determine their effectiveness. The authors and publisher make # 76 | # no warranty of any kind, expressed or implied, with regard to these # 77 | # programs or to the documentation contained in these books. The authors # 78 | # and publisher shall not be liable in any event for incidental or # 79 | # consequential damages in connection with, or arising out of, the # 80 | # furnishing, performance, or use of these programs. # 81 | ########################################################################## 82 | -------------------------------------------------------------------------------- /ch12_TwitterV2/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch12_TwitterV2/.DS_Store -------------------------------------------------------------------------------- /ch12_TwitterV2/keys.py: -------------------------------------------------------------------------------- 1 | 2 | mapquest_key = '' 3 | bearer_token = '' -------------------------------------------------------------------------------- /ch12_TwitterV2/locationlistener.py: -------------------------------------------------------------------------------- 1 | # locationlistener.py 2 | """Receives tweets matching a search string and stores a list of 3 | dictionaries containing each tweet's username/text/location.""" 4 | import tweepy 5 | from tweetutilities import get_tweet_content 6 | from IPython.display import clear_output 7 | 8 | class LocationListener(tweepy.StreamingClient): 9 | """Handles incoming Tweet stream to get location data.""" 10 | 11 | def __init__(self, bearer_token, counts_dict, 12 | tweets_list, topic, limit=10): 13 | """Configure the LocationListener.""" 14 | self.tweets_list = tweets_list 15 | self.counts_dict = counts_dict 16 | self.topic = topic 17 | self.TWEET_LIMIT = limit 18 | super().__init__(bearer_token, wait_on_rate_limit=True) 19 | 20 | def on_response(self, response): 21 | """Called when Twitter pushes a new tweet to you.""" 22 | 23 | # get tweet's username, text and location 24 | tweet_data = get_tweet_content(response) 25 | 26 | # ignore retweets and tweets that do not contain the topic 27 | if (tweet_data['text'].startswith('RT') or 28 | self.topic.lower() not in tweet_data['text'].lower()): 29 | return 30 | 31 | self.counts_dict['total_tweets'] += 1 # it's an original tweet 32 | 33 | # ignore tweets with no location 34 | if not tweet_data.get('location'): 35 | return 36 | 37 | self.counts_dict['locations'] += 1 # user account has location 38 | self.tweets_list.append(tweet_data) # store the tweet 39 | clear_output() 40 | print(f"{self.counts_dict['locations']}: {tweet_data['username']}: {tweet_data['text']}\n") 41 | 42 | # if TWEET_LIMIT is reached, terminate streaming 43 | if self.counts_dict['locations'] == self.TWEET_LIMIT: 44 | self.disconnect() 45 | 46 | 47 | 48 | ########################################################################## 49 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 50 | # Pearson Education, Inc. All Rights Reserved. # 51 | # # 52 | # DISCLAIMER: The authors and publisher of this book have used their # 53 | # best efforts in preparing the book. These efforts include the # 54 | # development, research, and testing of the theories and programs # 55 | # to determine their effectiveness. The authors and publisher make # 56 | # no warranty of any kind, expressed or implied, with regard to these # 57 | # programs or to the documentation contained in these books. The authors # 58 | # and publisher shall not be liable in any event for incidental or # 59 | # consequential damages in connection with, or arising out of, the # 60 | # furnishing, performance, or use of these programs. # 61 | ########################################################################## 62 | -------------------------------------------------------------------------------- /ch12_TwitterV2/sentimentlistener.py: -------------------------------------------------------------------------------- 1 | # sentimentlisener.py 2 | """Searches for tweets that match a search string and tallies 3 | the number of positive, neutral and negative tweets.""" 4 | import keys 5 | import preprocessor as p 6 | import sys 7 | from textblob import TextBlob 8 | import tweepy 9 | 10 | class SentimentListener(tweepy.StreamingClient): 11 | """Handles incoming Tweet stream.""" 12 | 13 | def __init__(self, bearer_token, sentiment_dict, topic, limit=10): 14 | """Configure the SentimentListener.""" 15 | self.sentiment_dict = sentiment_dict 16 | self.tweet_count = 0 17 | self.topic = topic 18 | self.TWEET_LIMIT = limit 19 | 20 | # set tweet-preprocessor to remove URLs/reserved words 21 | p.set_options(p.OPT.URL, p.OPT.RESERVED) 22 | super().__init__(bearer_token, wait_on_rate_limit=True) 23 | 24 | def on_response(self, response): 25 | """Called when Twitter pushes a new tweet to you.""" 26 | 27 | # if the tweet is not a retweet 28 | if not response.data.text.startswith('RT'): 29 | text = p.clean(response.data.text) # clean the tweet 30 | 31 | # ignore tweet if the topic is not in the tweet text 32 | if self.topic.lower() not in text.lower(): 33 | return 34 | 35 | # update self.sentiment_dict with the polarity 36 | blob = TextBlob(text) 37 | if blob.sentiment.polarity > 0: 38 | sentiment = '+' 39 | self.sentiment_dict['positive'] += 1 40 | elif blob.sentiment.polarity == 0: 41 | sentiment = ' ' 42 | self.sentiment_dict['neutral'] += 1 43 | else: 44 | sentiment = '-' 45 | self.sentiment_dict['negative'] += 1 46 | 47 | # display the tweet 48 | username = response.includes['users'][0].username 49 | print(f'{sentiment} {username}: {text}\n') 50 | 51 | self.tweet_count += 1 # track number of tweets processed 52 | 53 | # if TWEET_LIMIT is reached, terminate streaming 54 | if self.tweet_count == self.TWEET_LIMIT: 55 | self.disconnect() 56 | 57 | def main(): 58 | # get search term and number of tweets 59 | search_key = sys.argv[1] 60 | limit = int(sys.argv[2]) # number of tweets to tally 61 | 62 | # set up the sentiment dictionary 63 | sentiment_dict = {'positive': 0, 'neutral': 0, 'negative': 0} 64 | 65 | # create the StreamingClient subclass object 66 | sentiment_listener = SentimentListener(keys.bearer_token, 67 | sentiment_dict, search_key, limit) 68 | 69 | # redirect sys.stderr to sys.stdout 70 | sys.stderr = sys.stdout 71 | 72 | # delete existing stream rules 73 | rules = sentiment_listener.get_rules().data 74 | rule_ids = [rule.id for rule in rules] 75 | sentiment_listener.delete_rules(rule_ids) 76 | 77 | # create stream rule 78 | sentiment_listener.add_rules( 79 | tweepy.StreamRule(f'{search_key} lang:en')) 80 | 81 | # start filtering English tweets containing search_key 82 | sentiment_listener.filter(expansions=['author_id']) 83 | 84 | print(f'Tweet sentiment for "{search_key}"') 85 | print('Positive:', sentiment_dict['positive']) 86 | print(' Neutral:', sentiment_dict['neutral']) 87 | print('Negative:', sentiment_dict['negative']) 88 | 89 | # call main if this file is executed as a script 90 | if __name__ == '__main__': 91 | main() 92 | 93 | ########################################################################## 94 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 95 | # Pearson Education, Inc. All Rights Reserved. # 96 | # # 97 | # DISCLAIMER: The authors and publisher of this book have used their # 98 | # best efforts in preparing the book. These efforts include the # 99 | # development, research, and testing of the theories and programs # 100 | # to determine their effectiveness. The authors and publisher make # 101 | # no warranty of any kind, expressed or implied, with regard to these # 102 | # programs or to the documentation contained in these books. The authors # 103 | # and publisher shall not be liable in any event for incidental or # 104 | # consequential damages in connection with, or arising out of, the # 105 | # furnishing, performance, or use of these programs. # 106 | ########################################################################## 107 | -------------------------------------------------------------------------------- /ch12_TwitterV2/tweetlistener.py: -------------------------------------------------------------------------------- 1 | # tweetlistener.py 2 | """StreamListener subclass that processes tweets as they arrive.""" 3 | from deep_translator import GoogleTranslator 4 | import tweepy 5 | 6 | class TweetListener(tweepy.StreamingClient): 7 | """Handles incoming Tweet stream.""" 8 | 9 | def __init__(self, bearer_token, limit=10): 10 | """Create instance variables for tracking number of tweets.""" 11 | self.tweet_count = 0 12 | self.TWEET_LIMIT = limit 13 | 14 | # GoogleTranslator object for translating tweets to English 15 | self.translator = GoogleTranslator(source='auto', target='en') 16 | 17 | super().__init__(bearer_token, wait_on_rate_limit=True) 18 | 19 | def on_connect(self): 20 | """Called when your connection attempt is successful, enabling 21 | you to perform appropriate application tasks at that point.""" 22 | print('Connection successful\n') 23 | 24 | def on_response(self, response): 25 | """Called when Twitter pushes a new tweet to you.""" 26 | 27 | try: 28 | # get username of user who sent the tweet 29 | username = response.includes['users'][0].username 30 | print(f'Screen name: {username}') 31 | print(f' Language: {response.data.lang}') 32 | print(f' Tweet text: {response.data.text}') 33 | 34 | if response.data.lang != 'en' and response.data.lang != 'und': 35 | english = self.translator.translate(response.data.text) 36 | print(f' Translated: {english}') 37 | 38 | print() 39 | self.tweet_count += 1 40 | except Exception as e: 41 | print(f'Exception occured: {e}') 42 | self.disconnect() 43 | 44 | # if TWEET_LIMIT is reached, terminate streaming 45 | if self.tweet_count == self.TWEET_LIMIT: 46 | self.disconnect() 47 | 48 | ########################################################################## 49 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 50 | # Pearson Education, Inc. All Rights Reserved. # 51 | # # 52 | # DISCLAIMER: The authors and publisher of this book have used their # 53 | # best efforts in preparing the book. These efforts include the # 54 | # development, research, and testing of the theories and programs # 55 | # to determine their effectiveness. The authors and publisher make # 56 | # no warranty of any kind, expressed or implied, with regard to these # 57 | # programs or to the documentation contained in these books. The authors # 58 | # and publisher shall not be liable in any event for incidental or # 59 | # consequential damages in connection with, or arising out of, the # 60 | # furnishing, performance, or use of these programs. # 61 | ########################################################################## 62 | -------------------------------------------------------------------------------- /ch12_TwitterV2/tweetutilities.py: -------------------------------------------------------------------------------- 1 | # tweetutilities.py 2 | """Utility functions for interacting with Tweepy objects.""" 3 | import deepl 4 | #from deep_translator import GoogleTranslator 5 | from geopy import ArcGIS 6 | from geopy import OpenMapQuest 7 | import keys 8 | import time 9 | import tweepy 10 | 11 | def print_tweets(tweets): 12 | # translator to autodetect source language and return English 13 | # translator = GoogleTranslator(source='auto', target='en') 14 | translator = deepl.Translator(keys.deepL_key) 15 | 16 | """For each tweet in tweets, display the username of the sender 17 | and tweet text. If the language is not English, translate the text 18 | with Deep Translator.""" 19 | for tweet, user in zip(tweets.data, tweets.includes['users']): 20 | print(f'{user.username}:', end=' ') 21 | #print(f'{tweet.text}\n') 22 | if 'en' in tweet.lang: 23 | print(f'{tweet.text}\n') 24 | elif 'und' not in tweet.lang: # translate to English first 25 | print(f'\n ORIGINAL: {tweet.text}') 26 | result = translator.translate_text(tweet.text, target_lang='en-us') 27 | print(f'TRANSLATED: {result.text}\n') 28 | 29 | def get_tweet_content(response): 30 | """Return dictionary with data from tweet.""" 31 | fields = {} 32 | fields['username'] = response.includes['users'][0].username 33 | fields['text'] = response.data.text 34 | fields['location'] = response.includes['users'][0].location 35 | 36 | return fields 37 | 38 | def get_geocodes(tweet_list): 39 | """Get the latitude and longitude for each tweet's location. 40 | Returns the number of tweets with invalid location data.""" 41 | print('Getting coordinates for tweet locations...') 42 | # geo = OpenMapQuest(api_key=keys.mapquest_key) # geocoder 43 | geo = ArcGIS() # geocoder 44 | bad_locations = 0 45 | 46 | for tweet in tweet_list: 47 | processed = False 48 | delay = .1 # used if OpenMapQuest times out to delay next call 49 | while not processed: 50 | try: # get coordinates for tweet['location'] 51 | geo_location = geo.geocode(tweet['location']) 52 | processed = True 53 | except: # timed out, so wait before trying again 54 | print('Service timed out. Waiting.') 55 | time.sleep(delay) 56 | delay += .1 57 | 58 | if geo_location: 59 | tweet['latitude'] = geo_location.latitude 60 | tweet['longitude'] = geo_location.longitude 61 | else: 62 | bad_locations += 1 # tweet['location'] was invalid 63 | 64 | print('Done geocoding') 65 | return bad_locations 66 | 67 | 68 | ########################################################################## 69 | # (C) Copyright 2022 by Deitel & Associates, Inc. and # 70 | # Pearson Education, Inc. All Rights Reserved. # 71 | # # 72 | # DISCLAIMER: The authors and publisher of this book have used their # 73 | # best efforts in preparing the book. These efforts include the # 74 | # development, research, and testing of the theories and programs # 75 | # to determine their effectiveness. The authors and publisher make # 76 | # no warranty of any kind, expressed or implied, with regard to these # 77 | # programs or to the documentation contained in these books. The authors # 78 | # and publisher shall not be liable in any event for incidental or # 79 | # consequential damages in connection with, or arising out of, the # 80 | # furnishing, performance, or use of these programs. # 81 | ########################################################################## 82 | -------------------------------------------------------------------------------- /ch14/ave_hi_nyc_jan_1895-2018.csv: -------------------------------------------------------------------------------- 1 | Date,Value,Anomaly 2 | 189501,34.2,-3.2 3 | 189601,34.7,-2.7 4 | 189701,35.5,-1.9 5 | 189801,39.6,2.2 6 | 189901,36.4,-1.0 7 | 190001,37.4,0.0 8 | 190101,37.0,-0.4 9 | 190201,35.0,-2.4 10 | 190301,35.5,-1.9 11 | 190401,29.8,-7.6 12 | 190501,33.7,-3.7 13 | 190601,42.3,4.9 14 | 190701,40.5,3.1 15 | 190801,38.3,0.9 16 | 190901,39.6,2.2 17 | 191001,36.1,-1.3 18 | 191101,40.7,3.3 19 | 191201,29.3,-8.1 20 | 191301,46.9,9.5 21 | 191401,36.9,-0.5 22 | 191501,38.9,1.5 23 | 191601,42.3,4.9 24 | 191701,38.4,1.0 25 | 191801,26.5,-10.9 26 | 191901,40.6,3.2 27 | 192001,29.7,-7.7 28 | 192101,39.7,2.3 29 | 192201,33.4,-4.0 30 | 192301,35.2,-2.2 31 | 192401,39.4,2.0 32 | 192501,33.8,-3.6 33 | 192601,37.2,-0.2 34 | 192701,36.8,-0.6 35 | 192801,40.0,2.6 36 | 192901,37.8,0.4 37 | 193001,38.5,1.1 38 | 193101,38.2,0.8 39 | 193201,47.6,10.2 40 | 193301,45.6,8.2 41 | 193401,39.8,2.4 42 | 193501,35.0,-2.4 43 | 193601,34.3,-3.1 44 | 193701,45.7,8.3 45 | 193801,37.3,-0.1 46 | 193901,36.8,-0.6 47 | 194001,30.0,-7.4 48 | 194101,34.5,-2.9 49 | 194201,36.5,-0.9 50 | 194301,36.1,-1.3 51 | 194401,39.0,1.6 52 | 194501,31.5,-5.9 53 | 194601,40.2,2.8 54 | 194701,43.0,5.6 55 | 194801,30.1,-7.3 56 | 194901,43.5,6.1 57 | 195001,47.6,10.2 58 | 195101,42.5,5.1 59 | 195201,42.4,5.0 60 | 195301,42.4,5.0 61 | 195401,37.0,-0.4 62 | 195501,35.6,-1.8 63 | 195601,36.2,-1.2 64 | 195701,33.8,-3.6 65 | 195801,36.4,-1.0 66 | 195901,37.1,-0.3 67 | 196001,37.8,0.4 68 | 196101,31.9,-5.5 69 | 196201,38.0,0.6 70 | 196301,34.6,-2.8 71 | 196401,40.2,2.8 72 | 196501,34.0,-3.4 73 | 196601,37.1,-0.3 74 | 196701,41.6,4.2 75 | 196801,31.7,-5.7 76 | 196901,35.7,-1.7 77 | 197001,29.9,-7.5 78 | 197101,31.5,-5.9 79 | 197201,40.5,3.1 80 | 197301,40.6,3.2 81 | 197401,39.7,2.3 82 | 197501,41.7,4.3 83 | 197601,32.6,-4.8 84 | 197701,26.1,-11.3 85 | 197801,32.3,-5.1 86 | 197901,38.6,1.2 87 | 198001,38.0,0.6 88 | 198101,30.6,-6.8 89 | 198201,30.9,-6.5 90 | 198301,38.0,0.6 91 | 198401,33.5,-3.9 92 | 198501,33.0,-4.4 93 | 198601,39.3,1.9 94 | 198701,35.9,-1.5 95 | 198801,34.2,-3.2 96 | 198901,42.4,5.0 97 | 199001,46.0,8.6 98 | 199101,39.6,2.2 99 | 199201,40.9,3.5 100 | 199301,41.0,3.6 101 | 199401,31.6,-5.8 102 | 199501,42.6,5.2 103 | 199601,37.0,-0.4 104 | 199701,39.2,1.8 105 | 199801,45.8,8.4 106 | 199901,40.8,3.4 107 | 200001,37.8,0.4 108 | 200101,38.8,1.4 109 | 200201,45.4,8.0 110 | 200301,32.9,-4.5 111 | 200401,31.0,-6.4 112 | 200501,37.4,0.0 113 | 200601,47.6,10.2 114 | 200701,43.6,6.2 115 | 200801,42.4,5.0 116 | 200901,33.4,-4.0 117 | 201001,38.1,0.7 118 | 201101,34.8,-2.6 119 | 201201,44.2,6.8 120 | 201301,40.8,3.4 121 | 201401,35.5,-1.9 122 | 201501,36.1,-1.3 123 | 201601,40.8,3.4 124 | 201701,42.8,5.4 125 | 201801,38.7,1.3 -------------------------------------------------------------------------------- /ch14/ave_yearly_temp_nyc_1895-2017.csv: -------------------------------------------------------------------------------- 1 | Date,Value,Anomaly 2 | 189512,52.1,-1.8 3 | 189612,52.3,-1.6 4 | 189712,52.3,-1.6 5 | 189812,53.8,-0.1 6 | 189912,52.7,-1.2 7 | 190012,52.9,-1.0 8 | 190112,51.2,-2.7 9 | 190212,51.7,-2.2 10 | 190312,51.7,-2.2 11 | 190412,49.2,-4.7 12 | 190512,51.5,-2.4 13 | 190612,53.1,-0.8 14 | 190712,51.0,-2.9 15 | 190812,53.1,-0.8 16 | 190912,51.8,-2.1 17 | 191012,51.6,-2.3 18 | 191112,52.8,-1.1 19 | 191212,52.1,-1.8 20 | 191312,54.3,0.4 21 | 191412,51.4,-2.5 22 | 191512,52.8,-1.1 23 | 191612,51.6,-2.3 24 | 191712,50.1,-3.8 25 | 191812,52.6,-1.3 26 | 191912,53.2,-0.7 27 | 192012,52.0,-1.9 28 | 192112,54.6,0.7 29 | 192212,53.2,-0.7 30 | 192312,52.4,-1.5 31 | 192412,51.4,-2.5 32 | 192512,53.0,-0.9 33 | 192612,50.7,-3.2 34 | 192712,52.9,-1.0 35 | 192812,53.0,-0.9 36 | 192912,53.3,-0.6 37 | 193012,53.7,-0.2 38 | 193112,55.0,1.1 39 | 193212,54.3,0.4 40 | 193312,53.6,-0.3 41 | 193412,52.4,-1.5 42 | 193512,52.5,-1.4 43 | 193612,52.8,-1.1 44 | 193712,53.9,0.0 45 | 193812,54.6,0.7 46 | 193912,54.1,0.2 47 | 194012,51.3,-2.6 48 | 194112,54.3,0.4 49 | 194212,53.5,-0.4 50 | 194312,53.2,-0.7 51 | 194412,54.1,0.2 52 | 194512,53.5,-0.4 53 | 194612,54.8,0.9 54 | 194712,53.2,-0.7 55 | 194812,53.5,-0.4 56 | 194912,56.3,2.4 57 | 195012,53.0,-0.9 58 | 195112,54.4,0.5 59 | 195212,55.2,1.3 60 | 195312,56.5,2.6 61 | 195412,54.3,0.4 62 | 195512,54.1,0.2 63 | 195612,52.9,-1.0 64 | 195712,54.9,1.0 65 | 195812,52.0,-1.9 66 | 195912,54.8,0.9 67 | 196012,53.4,-0.5 68 | 196112,54.5,0.6 69 | 196212,52.8,-1.1 70 | 196312,53.0,-0.9 71 | 196412,54.0,0.1 72 | 196512,53.6,-0.3 73 | 196612,54.5,0.6 74 | 196712,52.4,-1.5 75 | 196812,53.5,-0.4 76 | 196912,54.2,0.3 77 | 197012,53.7,-0.2 78 | 197112,54.6,0.7 79 | 197212,53.3,-0.6 80 | 197312,55.5,1.6 81 | 197412,54.1,0.2 82 | 197512,54.4,0.5 83 | 197612,52.9,-1.0 84 | 197712,53.5,-0.4 85 | 197812,52.2,-1.7 86 | 197912,54.3,0.4 87 | 198012,53.8,-0.1 88 | 198112,54.0,0.1 89 | 198212,53.6,-0.3 90 | 198312,54.8,0.9 91 | 198412,54.2,0.3 92 | 198512,54.6,0.7 93 | 198612,54.5,0.6 94 | 198712,54.7,0.8 95 | 198812,54.3,0.4 96 | 198912,53.5,-0.4 97 | 199012,56.7,2.8 98 | 199112,56.7,2.8 99 | 199212,53.5,-0.4 100 | 199312,55.0,1.1 101 | 199412,54.8,0.9 102 | 199512,55.0,1.1 103 | 199612,54.1,0.2 104 | 199712,54.7,0.8 105 | 199812,57.5,3.6 106 | 199912,56.9,3.0 107 | 200012,54.2,0.3 108 | 200112,56.6,2.7 109 | 200212,56.8,2.9 110 | 200312,53.8,-0.1 111 | 200412,54.9,1.0 112 | 200512,56.1,2.2 113 | 200612,57.2,3.3 114 | 200712,55.4,1.5 115 | 200812,55.7,1.8 116 | 200912,54.4,0.5 117 | 201012,57.1,3.2 118 | 201112,56.8,2.9 119 | 201212,57.7,3.8 120 | 201312,55.6,1.7 121 | 201412,54.4,0.5 122 | 201512,56.7,2.8 123 | 201612,57.2,3.3 124 | 201712,56.4,2.5 125 | -------------------------------------------------------------------------------- /ch14/ch14images/2018-11-03_08-21-23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/2018-11-03_08-21-23.png -------------------------------------------------------------------------------- /ch14/ch14images/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/22.png -------------------------------------------------------------------------------- /ch14/ch14images/24digits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/24digits.png -------------------------------------------------------------------------------- /ch14/ch14images/3d1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/3d1.png -------------------------------------------------------------------------------- /ch14/ch14images/3d2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/3d2.png -------------------------------------------------------------------------------- /ch14/ch14images/3d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/3d3.png -------------------------------------------------------------------------------- /ch14/ch14images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/5.png -------------------------------------------------------------------------------- /ch14/ch14images/Blue_FlagOttawa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/Blue_FlagOttawa.jpg -------------------------------------------------------------------------------- /ch14/ch14images/Blue_FlagOttawa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/Blue_FlagOttawa.png -------------------------------------------------------------------------------- /ch14/ch14images/IMG_7911-Iris_virginica.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/IMG_7911-Iris_virginica.jpg -------------------------------------------------------------------------------- /ch14/ch14images/IrisVersicolor-FoxRoost-Newfoundland.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/IrisVersicolor-FoxRoost-Newfoundland.jpg -------------------------------------------------------------------------------- /ch14/ch14images/NYC_AVE_ANNUAL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_AVE_ANNUAL.png -------------------------------------------------------------------------------- /ch14/ch14images/NYC_seaborn_regplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_seaborn_regplot.png -------------------------------------------------------------------------------- /ch14/ch14images/NYC_seaborn_regplot_with_ci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_seaborn_regplot_with_ci.png -------------------------------------------------------------------------------- /ch14/ch14images/NYC_seaborn_regplota (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_seaborn_regplota (1).png -------------------------------------------------------------------------------- /ch14/ch14images/NYC_seaborn_regplota.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_seaborn_regplota.png -------------------------------------------------------------------------------- /ch14/ch14images/NYC_seaborn_regplota_with_ci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/NYC_seaborn_regplota_with_ci.png -------------------------------------------------------------------------------- /ch14/ch14images/TypesOfMachineLearning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/TypesOfMachineLearning.png -------------------------------------------------------------------------------- /ch14/ch14images/Wild_iris_KEFJ_(9025144383).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/Wild_iris_KEFJ_(9025144383).jpg -------------------------------------------------------------------------------- /ch14/ch14images/avebedrooms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/avebedrooms.png -------------------------------------------------------------------------------- /ch14/ch14images/aveoccupancy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/aveoccupancy.png -------------------------------------------------------------------------------- /ch14/ch14images/averooms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/averooms.png -------------------------------------------------------------------------------- /ch14/ch14images/axes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/axes.png -------------------------------------------------------------------------------- /ch14/ch14images/celsius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/celsius.png -------------------------------------------------------------------------------- /ch14/ch14images/confusion_nipy_spectral_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/confusion_nipy_spectral_r.png -------------------------------------------------------------------------------- /ch14/ch14images/digits_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/digits_black.png -------------------------------------------------------------------------------- /ch14/ch14images/digits_tsne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/digits_tsne.png -------------------------------------------------------------------------------- /ch14/ch14images/distance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/distance.png -------------------------------------------------------------------------------- /ch14/ch14images/expectedVSpredicted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/expectedVSpredicted.png -------------------------------------------------------------------------------- /ch14/ch14images/expectedVSpredictedmultiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/expectedVSpredictedmultiple.png -------------------------------------------------------------------------------- /ch14/ch14images/feature_selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/feature_selection.png -------------------------------------------------------------------------------- /ch14/ch14images/grays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/grays.png -------------------------------------------------------------------------------- /ch14/ch14images/houseage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/houseage.png -------------------------------------------------------------------------------- /ch14/ch14images/housing_expect_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/housing_expect_predict.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_box_plots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_box_plots.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_decision_boundary_1neighbor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_decision_boundary_1neighbor.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_decision_boundary_3neighbors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_decision_boundary_3neighbors.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_histograms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_histograms.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_model_comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_model_comparison.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_pairplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_pairplot.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_pairplot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_pairplot2.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_pca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_pca.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_pca_centroids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_pca_centroids.png -------------------------------------------------------------------------------- /ch14/ch14images/iris_scatter_matrix (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_scatter_matrix (1).png -------------------------------------------------------------------------------- /ch14/ch14images/iris_scatter_matrix (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_scatter_matrix (2).png -------------------------------------------------------------------------------- /ch14/ch14images/iris_scatter_matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/iris_scatter_matrix.png -------------------------------------------------------------------------------- /ch14/ch14images/lattitude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/lattitude.png -------------------------------------------------------------------------------- /ch14/ch14images/longitude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/longitude.png -------------------------------------------------------------------------------- /ch14/ch14images/mechanicalLinearRegression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/mechanicalLinearRegression.png -------------------------------------------------------------------------------- /ch14/ch14images/medincome-predicted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/medincome-predicted.png -------------------------------------------------------------------------------- /ch14/ch14images/medincome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/medincome.png -------------------------------------------------------------------------------- /ch14/ch14images/nearest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nearest.png -------------------------------------------------------------------------------- /ch14/ch14images/nyc_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nyc_data.png -------------------------------------------------------------------------------- /ch14/ch14images/nyc_data_with_reg_line_scaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nyc_data_with_reg_line_scaled.png -------------------------------------------------------------------------------- /ch14/ch14images/nyc_test_data_with_reg_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nyc_test_data_with_reg_line.png -------------------------------------------------------------------------------- /ch14/ch14images/nyc_test_data_with_reg_line_scaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nyc_test_data_with_reg_line_scaled.png -------------------------------------------------------------------------------- /ch14/ch14images/nyc_train_data_with_reg_line_scaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/nyc_train_data_with_reg_line_scaled.png -------------------------------------------------------------------------------- /ch14/ch14images/population.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/population.png -------------------------------------------------------------------------------- /ch14/ch14images/sampledigit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/sampledigit.png -------------------------------------------------------------------------------- /ch14/ch14images/sampledigit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/sampledigit2.png -------------------------------------------------------------------------------- /ch14/ch14images/sampledigit3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/sampledigit3.png -------------------------------------------------------------------------------- /ch14/ch14images/seaborn_iris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch14/ch14images/seaborn_iris.png -------------------------------------------------------------------------------- /ch14/digits3d.py: -------------------------------------------------------------------------------- 1 | # Code for visualizing Digits dataset in 3D 2 | from sklearn.datasets import load_digits 3 | from sklearn.manifold import TSNE 4 | import matplotlib 5 | import matplotlib.pyplot as plt 6 | import mpl_toolkits.mplot3d.axes3d as axes3d 7 | digits = load_digits() 8 | tsne3 = TSNE(n_components=3, random_state=11) 9 | reduced_data3 = tsne3.fit_transform(digits.data) 10 | figure = plt.figure(figsize=(7, 5)) 11 | axes = figure.add_subplot(projection='3d') 12 | dots = axes.scatter(reduced_data3[:, 0], reduced_data3[:, 1], reduced_data3[:, 2], 13 | c=digits.target, cmap=matplotlib.colormaps['nipy_spectral_r']) 14 | colorbar = plt.colorbar(dots) 15 | plt.show() 16 | -------------------------------------------------------------------------------- /ch15/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/.DS_Store -------------------------------------------------------------------------------- /ch15/ch15images/convolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/convolution.png -------------------------------------------------------------------------------- /ch15/ch15images/convolution2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/convolution2.png -------------------------------------------------------------------------------- /ch15/ch15images/incorrect24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/incorrect24.png -------------------------------------------------------------------------------- /ch15/ch15images/neuralnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/neuralnet.png -------------------------------------------------------------------------------- /ch15/ch15images/neuron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/neuron.png -------------------------------------------------------------------------------- /ch15/ch15images/pooling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/pooling.png -------------------------------------------------------------------------------- /ch15/ch15images/pooling2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/pooling2.png -------------------------------------------------------------------------------- /ch15/ch15images/tensorboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/ch15images/tensorboard.png -------------------------------------------------------------------------------- /ch15/convnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/convnet.png -------------------------------------------------------------------------------- /ch15/mnist_cnn.keras: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch15/mnist_cnn.keras -------------------------------------------------------------------------------- /ch16/OLD_starttweetstream-updated.py: -------------------------------------------------------------------------------- 1 | # starttweetstream.py 2 | """Script to get tweets on topic(s) specified as script argument(s) 3 | and send tweet text to a socket for processing by Spark.""" 4 | import keys 5 | import socket 6 | import sys 7 | import tweepy 8 | import re 9 | 10 | class TweetListener(tweepy.StreamingClient): 11 | """Handles incoming Tweet stream.""" 12 | 13 | def __init__(self, bearer_token, connection, limit=10): 14 | #def __init__(self, bearer_token, limit=10): 15 | """Create instance variables for tracking number of tweets.""" 16 | self.connection = connection 17 | self.tweet_count = 0 18 | self.TWEET_LIMIT = limit # 10 by default 19 | super().__init__(bearer_token, wait_on_rate_limit=True) 20 | 21 | def on_connect(self): 22 | """Called when your connection attempt is successful, enabling 23 | you to perform appropriate application tasks at that point.""" 24 | print('Successfully connected to Twitter\n') 25 | 26 | def on_response(self, response): 27 | """Called when Twitter pushes a new tweet to you.""" 28 | # get the hashtags 29 | hashtags = [] 30 | 31 | if 'hashtags' in response.data.entities: 32 | for hashtag in response.data.entities['hashtags']: 33 | hashtags.append(hashtag['tag'].lower()) 34 | 35 | hashtags_string = ' '.join(hashtags) + '\n' 36 | print(f'Screen name: {response.includes["users"][0].username}:') 37 | print(f' Hashtags: {hashtags_string}') 38 | self.tweet_count += 1 # track number of tweets processed 39 | 40 | try: 41 | # send requires bytes, so encode the string in utf-8 format 42 | self.connection.send(hashtags_string.encode('utf-8')) 43 | except Exception as e: 44 | print(f'Error: {e}') 45 | 46 | # if TWEET_LIMIT is reached, return False to terminate streaming 47 | if self.tweet_count == self.TWEET_LIMIT: 48 | self.disconnect() 49 | 50 | def on_errors(self, errors): 51 | print(errors) 52 | return True 53 | 54 | if __name__ == '__main__': 55 | tweet_limit = int(sys.argv[1]) # get maximum number of tweets 56 | client_socket = socket.socket() # create a socket 57 | 58 | # app will use localhost (this computer) port 9876 59 | client_socket.bind(('localhost', 9876)) 60 | 61 | print('Waiting for connection') 62 | client_socket.listen() # wait for client to connect 63 | 64 | # when connection received, get connection/client address 65 | connection, address = client_socket.accept() 66 | print(f'Connection received from {address}') 67 | 68 | # create the StreamingClient 69 | twitter_stream = TweetListener( 70 | keys.bearer_token, connection, tweet_limit) 71 | #twitter_stream = TweetListener(keys.bearer_token, tweet_limit) 72 | 73 | # delete old rules 74 | rules = twitter_stream.get_rules().data 75 | rule_ids = [rule.id for rule in rules] 76 | twitter_stream.delete_rules(rule_ids) 77 | 78 | # create filtering rules 79 | for term in sys.argv[2:]: 80 | filter_rule = tweepy.StreamRule(f'{term} has:hashtags') 81 | print(twitter_stream.add_rules(filter_rule)) 82 | 83 | # sys.argv[2] is the first search term 84 | twitter_stream.filter(expansions=['author_id'], tweet_fields=['entities']) 85 | connection.close() 86 | client_socket.close() 87 | 88 | ########################################################################## 89 | # (C) Copyright 2019 by Deitel & Associates, Inc. and # 90 | # Pearson Education, Inc. All Rights Reserved. # 91 | # # 92 | # DISCLAIMER: The authors and publisher of this book have used their # 93 | # best efforts in preparing the book. These efforts include the # 94 | # development, research, and testing of the theories and programs # 95 | # to determine their effectiveness. The authors and publisher make # 96 | # no warranty of any kind, expressed or implied, with regard to these # 97 | # programs or to the documentation contained in these books. The authors # 98 | # and publisher shall not be liable in any event for incidental or # 99 | # consequential damages in connection with, or arising out of, the # 100 | # furnishing, performance, or use of these programs. # 101 | ########################################################################## 102 | -------------------------------------------------------------------------------- /ch16/OLD_starttweetstream.py: -------------------------------------------------------------------------------- 1 | # starttweetstream.py 2 | """Script to get tweets on topic(s) specified as script argument(s) 3 | and send tweet text to a socket for processing by Spark.""" 4 | import keys 5 | import socket 6 | import sys 7 | import tweepy 8 | 9 | class TweetListener(tweepy.StreamListener): 10 | """Handles incoming Tweet stream.""" 11 | 12 | def __init__(self, api, connection, limit=10000): 13 | """Create instance variables for tracking number of tweets.""" 14 | self.connection = connection 15 | self.tweet_count = 0 16 | self.TWEET_LIMIT = limit # 10,000 by default 17 | super().__init__(api) # call superclass's init 18 | 19 | def on_connect(self): 20 | """Called when your connection attempt is successful, enabling 21 | you to perform appropriate application tasks at that point.""" 22 | print('Successfully connected to Twitter\n') 23 | 24 | def on_status(self, status): 25 | """Called when Twitter pushes a new tweet to you.""" 26 | # get the hashtags 27 | hashtags = [] 28 | 29 | for hashtag_dict in status.entities['hashtags']: 30 | hashtags.append(hashtag_dict['text'].lower()) 31 | 32 | hashtags_string = ' '.join(hashtags) + '\n' 33 | print(f'Screen name: {status.user.screen_name}:') 34 | print(f' Hashtags: {hashtags_string}') 35 | self.tweet_count += 1 # track number of tweets processed 36 | 37 | try: 38 | # send requires bytes, so encode the string in utf-8 format 39 | self.connection.send(hashtags_string.encode('utf-8')) 40 | except Exception as e: 41 | print(f'Error: {e}') 42 | 43 | # if TWEET_LIMIT is reached, return False to terminate streaming 44 | return self.tweet_count < self.TWEET_LIMIT 45 | 46 | def on_error(self, status): 47 | print(status) 48 | return True 49 | 50 | if __name__ == '__main__': 51 | tweet_limit = int(sys.argv[1]) # get maximum number of tweets 52 | client_socket = socket.socket() # create a socket 53 | 54 | # app will use localhost (this computer) port 9876 55 | client_socket.bind(('localhost', 9876)) 56 | 57 | print('Waiting for connection') 58 | client_socket.listen() # wait for client to connect 59 | 60 | # when connection received, get connection/client address 61 | connection, address = client_socket.accept() 62 | print(f'Connection received from {address}') 63 | 64 | # configure Twitter access 65 | auth = tweepy.OAuthHandler(keys.consumer_key, keys.consumer_secret) 66 | auth.set_access_token(keys.access_token, keys.access_token_secret) 67 | 68 | # configure Tweepy to wait if Twitter rate limits are reached 69 | api = tweepy.API(auth, wait_on_rate_limit=True, 70 | wait_on_rate_limit_notify=True) 71 | 72 | # create the Stream 73 | twitter_stream = tweepy.Stream(api.auth, 74 | TweetListener(api, connection, tweet_limit)) 75 | 76 | # sys.argv[2] is the first search term 77 | twitter_stream.filter(track=sys.argv[2:]) 78 | 79 | connection.close() 80 | client_socket.close() 81 | 82 | ########################################################################## 83 | # (C) Copyright 2019 by Deitel & Associates, Inc. and # 84 | # Pearson Education, Inc. All Rights Reserved. # 85 | # # 86 | # DISCLAIMER: The authors and publisher of this book have used their # 87 | # best efforts in preparing the book. These efforts include the # 88 | # development, research, and testing of the theories and programs # 89 | # to determine their effectiveness. The authors and publisher make # 90 | # no warranty of any kind, expressed or implied, with regard to these # 91 | # programs or to the documentation contained in these books. The authors # 92 | # and publisher shall not be liable in any event for incidental or # 93 | # consequential damages in connection with, or arising out of, the # 94 | # furnishing, performance, or use of these programs. # 95 | ########################################################################## 96 | -------------------------------------------------------------------------------- /ch16/OLD_tweetlistener.py: -------------------------------------------------------------------------------- 1 | # tweetlistener.py 2 | """TweetListener downloads tweets and stores them in MongoDB.""" 3 | import json 4 | import tweepy 5 | from IPython.display import clear_output 6 | 7 | class TweetListener(tweepy.StreamingClient): 8 | """Handles incoming Tweet stream.""" 9 | 10 | def __init__(self, bearer_token, database, limit=10000): 11 | """Create instance variables for tracking number of tweets.""" 12 | self.db = database 13 | self.tweet_count = 0 14 | self.TWEET_LIMIT = limit # 10,000 by default 15 | super().__init__(bearer_token, wait_on_rate_limit=True) 16 | 17 | def on_connect(self): 18 | """Called when your connection attempt is successful, enabling 19 | you to perform appropriate application tasks at that point.""" 20 | print('Successfully connected to Twitter\n') 21 | 22 | def on_data(self, data): 23 | """Called when Twitter pushes a new tweet to you.""" 24 | self.tweet_count += 1 # track number of tweets processed 25 | json_data = json.loads(data) # convert string to JSON 26 | self.db.tweets.insert_one(json_data) # store in tweets collection 27 | clear_output() # ADDED: show one tweet at a time in Jupyter Notebook 28 | 29 | try: 30 | print(f' Screen name: {json_data["includes"]["users"][0]["username"]}') 31 | print(f' Created at: {json_data["data"]["created_at"][:10]}') 32 | print(f'Tweets received: {self.tweet_count}') 33 | except: 34 | print("Twitter response missing a requested field") 35 | 36 | # if TWEET_LIMIT is reached, return False to terminate streaming 37 | if self.tweet_count == self.TWEET_LIMIT: 38 | self.disconnect() 39 | 40 | def on_exception(self, status): 41 | print(f'Error: {status}') 42 | return True 43 | 44 | ########################################################################## 45 | # (C) Copyright 2019 by Deitel & Associates, Inc. and # 46 | # Pearson Education, Inc. All Rights Reserved. # 47 | # # 48 | # DISCLAIMER: The authors and publisher of this book have used their # 49 | # best efforts in preparing the book. These efforts include the # 50 | # development, research, and testing of the theories and programs # 51 | # to determine their effectiveness. The authors and publisher make # 52 | # no warranty of any kind, expressed or implied, with regard to these # 53 | # programs or to the documentation contained in these books. The authors # 54 | # and publisher shall not be liable in any event for incidental or # 55 | # consequential damages in connection with, or arising out of, the # 56 | # furnishing, performance, or use of these programs. # 57 | ########################################################################## 58 | -------------------------------------------------------------------------------- /ch16/books.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/books.db -------------------------------------------------------------------------------- /ch16/books.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS author_ISBN; 2 | DROP TABLE IF EXISTS titles; 3 | DROP TABLE IF EXISTS authors; 4 | 5 | CREATE TABLE authors ( 6 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 7 | first TEXT NOT NULL, 8 | last TEXT NOT NULL 9 | ); 10 | 11 | CREATE TABLE titles ( 12 | isbn TEXT NOT NULL, 13 | title TEXT NOT NULL, 14 | edition INTEGER NOT NULL, 15 | copyright TEXT NOT NULL, 16 | PRIMARY KEY (isbn) 17 | ); 18 | 19 | CREATE TABLE author_ISBN ( 20 | id INTEGER NOT NULL, 21 | isbn TEXT NOT NULL, 22 | PRIMARY KEY (id, isbn), 23 | FOREIGN KEY (id) REFERENCES authors(id) ON DELETE CASCADE, 24 | FOREIGN KEY (isbn) REFERENCES titles (isbn) ON DELETE CASCADE 25 | ); 26 | 27 | PRAGMA foreign_keys = ON; 28 | 29 | INSERT INTO authors (first, last) 30 | VALUES 31 | ('Paul','Deitel'), 32 | ('Harvey','Deitel'), 33 | ('Abbey','Deitel'), 34 | ('Dan','Quirk'), 35 | ('Alexander', 'Wald'); 36 | 37 | INSERT INTO titles (isbn,title,edition,copyright) 38 | VALUES 39 | ('0135404673','Intro to Python for CS and DS',1,'2020'), 40 | ('0132151006','Internet & WWW How to Program',5,'2012'), 41 | ('0134743350','Java How to Program',11,'2018'), 42 | ('0133976890','C How to Program',8,'2016'), 43 | ('0133406954','Visual Basic 2012 How to Program',6,'2014'), 44 | ('0134601548','Visual C# How to Program',6,'2017'), 45 | ('0136151574','Visual C++ How to Program',2,'2008'), 46 | ('0134448235','C++ How to Program',10,'2017'), 47 | ('0134444302','Android How to Program',3,'2017'), 48 | ('0134289366','Android 6 for Programmers',3,'2016'); 49 | 50 | INSERT INTO author_ISBN (id,isbn) 51 | VALUES 52 | (1,'0134289366'), 53 | (2,'0134289366'), 54 | (5,'0134289366'), 55 | (1,'0135404673'), 56 | (2,'0135404673'), 57 | (1,'0132151006'), 58 | (2,'0132151006'), 59 | (3,'0132151006'), 60 | (1,'0134743350'), 61 | (2,'0134743350'), 62 | (1,'0133976890'), 63 | (2,'0133976890'), 64 | (1,'0133406954'), 65 | (2,'0133406954'), 66 | (3,'0133406954'), 67 | (1,'0134601548'), 68 | (2,'0134601548'), 69 | (1,'0136151574'), 70 | (2,'0136151574'), 71 | (4,'0136151574'), 72 | (1,'0134448235'), 73 | (2,'0134448235'), 74 | (1,'0134444302'), 75 | (2,'0134444302'); 76 | -------------------------------------------------------------------------------- /ch16/ch16images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/.DS_Store -------------------------------------------------------------------------------- /ch16/ch16images/SenatorTweetsByState.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/SenatorTweetsByState.png -------------------------------------------------------------------------------- /ch16/ch16images/TwitterHashtags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/TwitterHashtags.png -------------------------------------------------------------------------------- /ch16/ch16images/pubnubSensors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/pubnubSensors.png -------------------------------------------------------------------------------- /ch16/ch16images/stockprices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/stockprices.png -------------------------------------------------------------------------------- /ch16/ch16images/thermostat1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/thermostat1.png -------------------------------------------------------------------------------- /ch16/ch16images/thermostat2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/thermostat2.png -------------------------------------------------------------------------------- /ch16/ch16images/thermostat3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/thermostat3.png -------------------------------------------------------------------------------- /ch16/ch16images/top10senators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/ch16/ch16images/top10senators.png -------------------------------------------------------------------------------- /ch16/keys.py: -------------------------------------------------------------------------------- 1 | consumer_key = '' 2 | consumer_secret = '' 3 | access_token = '' 4 | access_token_secret = '' 5 | 6 | mapquest_key = '' 7 | 8 | mongo_connection_string = '' -------------------------------------------------------------------------------- /ch16/keys_mastodon.py: -------------------------------------------------------------------------------- 1 | # insert your Mastodon username and password in the strings below 2 | usr = '' 3 | pwd = '' 4 | 5 | # get DeepL key 6 | # 1. Go to https://www.deepl.com/pro#developer 7 | # 2. Click Sign up for free 8 | # 3. Under DeepL API Free click Sign up for free 9 | # 4. Specify an email/password and click Continue 10 | # 5. Fill in the form and provide a credit card, then click Continue 11 | # CC required to prevent “fraudulent multiple registrations” 12 | # 6. Read the terms and, if you agree, click Sign up for free 13 | # 7. Click the Account Management link on the thank you page 14 | # 8. Click the Account tab and scroll to Authentication Key for DeepL API 15 | # 9. Paste key into string below (make sure you have no spaces before or 16 | # after your key in the string) 17 | deepL_key = '' 18 | 19 | 20 | # get ipgeolocation.io API key 21 | # 1. Go to https://ipgeolocation.io/signup.html 22 | # 2. Sign up for a free account 23 | # 3. In your Dashboard, copy the API key 24 | # 4. Paste the API key into string below (make sure you have no spaces 25 | # before or after your key in the string) 26 | ipgeolocation_key = '' -------------------------------------------------------------------------------- /ch16/senators.csv: -------------------------------------------------------------------------------- 1 | State,Name,Party,TwitterHandle,TwitterID 2 | AL,Richard Shelby,R,SenShelby,21111098 3 | AL,Tommy Tuberville,R,TTuberville,110798061 4 | AK,Lisa Murkowski,R,lisamurkowski,18061669 5 | AK,Dan Sullivan,R,SenDanSullivan,2891210047 6 | AZ,Mark Kelly,D,SenMarkKelly,1324926274888888320 7 | AZ,Kyrsten Sinema,D,SenatorSinema,1080844782 8 | AR,Tom Cotton,R,SenTomCotton,968650362 9 | AR,John Boozman,R,JohnBoozman,5558312 10 | CA,Dianne Feinstein,D,SenFeinstein,476256944 11 | CA,Kamala Harris,D,SenKamalaHarris,803694179079458816 12 | CO,Michael Bennet,D,SenBennetCO,224285242 13 | CO,John Hickenlooper,D,Hickenlooper,117839957 14 | CT,Christopher Murphy,D,ChrisMurphyCT,150078976 15 | CT,Richard Blumenthal,D,SenBlumenthal,278124059 16 | DE,Tom Carper,D,SenatorCarper,249787913 17 | DE,Chris Coons,D,ChrisCoons,15324851 18 | FL,Rick Scott ,R,SenRickScott,131546062 19 | FL,Marco Rubio,R,marcorubio,15745368 20 | GA,Jon Ossoff,D,ossoff,2863210809 21 | GA,Raphael Warnock,D,ReverendWarnock,1221242033530195970 22 | HI,Brian Schatz,D,brianschatz,47747074 23 | HI,Mazie Hirono,D,maziehirono,92186819 24 | ID,Mike Crapo,R,MikeCrapo,600463589 25 | ID,Jim Risch,R,SenatorRisch,1096059529 26 | IL,Tammy Duckworth,D,SenDuckworth,1058520120 27 | IL,Dick Durbin,D,SenatorDurbin,247334603 28 | IN,Mike Braun ,R,SenatorBraun,1080870981877534720 29 | IN,Todd Young,R,SenToddYoung,234128524 30 | IA,Chuck Grassley,R,ChuckGrassley,10615232 31 | IA,Joni Ernst,R,joniernst,1383059977 32 | KS,Roger Marshall,R,RogerMarshallMD,1240107944 33 | KS,Jerry Moran,R,JerryMoran,18632666 34 | KY,Mitch McConnell,R,SenateMajLdr,1249982359 35 | KY,Rand Paul,R,RandPaul,216881337 36 | LA,Bill Cassidy,R,BillCassidy,55677432 37 | LA,John Kennedy,R,SenJohnKennedy,816683274076614656 38 | ME,Angus King,I,SenAngusKing,1068481578 39 | ME,Susan Collins,R,SenatorCollins,19726613 40 | MD,Chris Van Hollen,D,ChrisVanHollen,18137749 41 | MD,Ben Cardin,D,SenatorCardin,109071031 42 | MA,Ed Markey,D,senmarkey,21406834 43 | MA,Elizabeth Warren,D,SenWarren,970207298 44 | MI,Gary Peters,D,SenGaryPeters,236511574 45 | MI,Debbie Stabenow,D,SenStabenow,76456274 46 | MN,Amy Klobuchar,D,amyklobuchar,33537967 47 | MN,Tina Smith,D,SenTinaSmith,941000686275387392 48 | MS,Cindy Hyde-Smith,R,SenHydeSmith,983348251972816896 49 | MS,Roger Wicker,R,SenatorWicker,264219447 50 | MO,Josh Hawley,R,SenHawleyPress,1080960924687704064 51 | MO,Roy Blunt,R,RoyBlunt,21269970 52 | MT,Steve Daines,R,SteveDaines,11651202 53 | MT,Jon Tester,D,SenatorTester,515822213 54 | NE,Deb Fischer,R,SenatorFischer,1071402577 55 | NE,Ben Sasse,R,BenSasse,1480852568 56 | NV,Catherine Cortez Masto,D,SenCortezMasto,811313565760163844 57 | NV,Jacky Rosen,D,SenJackyRosen,818554054309715969 58 | NH,Jeanne Shaheen,D,SenatorShaheen,109287731 59 | NH,Maggie Hassan,D,SenatorHassan,946549322 60 | NJ,Cory Booker,D,CoryBooker,15808765 61 | NJ,Bob Menendez,D,SenatorMenendez,18695134 62 | NM,Martin Heinrich,D,MartinHeinrich,1099199839 63 | NM,Ben Ray Luján,D,benraylujan,91125308 64 | NY,Chuck Schumer,D,SenSchumer,17494010 65 | NY,Kirsten Gillibrand,D,SenGillibrand,72198806 66 | NC,Richard Burr,R,SenatorBurr,21157904 67 | NC,Thom Tillis,R,SenThomTillis,2964174789 68 | ND,Kevin Cramer ,R,SenKevinCramer,1048784496 69 | ND,John Hoeven,R,SenJohnHoeven,382791093 70 | OH,Sherrod Brown,D,SenSherrodBrown,43910797 71 | OH,Rob Portman,R,SenRobPortman,18915145 72 | OK,Jim Inhofe,R,jiminhofe,7270292 73 | OK,James Lankford,R,SenatorLankford,225921757 74 | OR,Ron Wyden,D,RonWyden,250188760 75 | OR,Jeff Merkley,D,SenJeffMerkley,29201047 76 | PA,Bob Casey,D,SenBobCasey,171598736 77 | PA,Pat Toomey,R,SenToomey,221162525 78 | RI,Jack Reed,D,SenJackReed,486694111 79 | RI,Sheldon Whitehouse,D,SenWhitehouse,242555999 80 | SC,Lindsey Graham,R,LindseyGrahamSC,432895323 81 | SC,Tim Scott,R,SenatorTimScott,217543151 82 | SD,Mike Rounds,R,SenatorRounds,2955485182 83 | SD,John Thune,R,SenJohnThune,296361085 84 | TN,Bill Hagerty,R,BillHagertyTN,1152598802873880576 85 | TN,Marsha Blackburn ,R,MarshaBlackburn,278145569 86 | TX,John Cornyn,R,JohnCornyn,13218102 87 | TX,Ted Cruz,R,SenTedCruz,1074480192 88 | UT,Mitt Romney ,R,SenatorRomney,1078693601356509184 89 | UT,Mike Lee,R,SenMikeLee,88784440 90 | VT,Patrick Leahy,D,SenatorLeahy,242836537 91 | VT,Bernie Sanders,I,SenatorSanders,946946130 92 | VA,Tim Kaine,D,timkaine,172858784 93 | VA,Mark Warner,D,MarkWarner,7429102 94 | WA,Patty Murray,D,PattyMurray,293131808 95 | WA,Maria Cantwell,D,SenatorCantwell,117501995 96 | WV,Shelley Moore Capito,R,SenCapito,193794406 97 | WV,Joe Manchin,D,Sen_JoeManchin,234374703 98 | WI,Tammy Baldwin,D,SenatorBaldwin,1074518754 99 | WI,Ron Johnson,R,SenRonJohnson,233737858 100 | WY,Cynthia Lummis,R,CynthiaMLummis,1136711154435207168 101 | WY,John Barrasso,R,SenJohnBarrasso,202206694 -------------------------------------------------------------------------------- /ch16/simulator.py: -------------------------------------------------------------------------------- 1 | # simulator.py 2 | """A connected thermostat simulator that publishes JSON 3 | messages to dweet.io""" 4 | import dweepy 5 | import sys 6 | import time 7 | import random 8 | 9 | MIN_CELSIUS_TEMP = -25 10 | MAX_CELSIUS_TEMP = 45 11 | MAX_TEMP_CHANGE = 2 12 | 13 | # get the number of messages to simulate and delay between them 14 | NUMBER_OF_MESSAGES = int(sys.argv[1]) 15 | MESSAGE_DELAY = int(sys.argv[2]) 16 | 17 | dweeter = 'temperature-simulator-deitel-python-paul' # provide a unique name 18 | thermostat = {'Location': 'Boston, MA, USA', 19 | 'Temperature': 20, 20 | 'LowTempWarning': False, 21 | 'HighTempWarning': False} 22 | 23 | print('Temperature simulator starting') 24 | 25 | for message in range(NUMBER_OF_MESSAGES): 26 | # generate a random number in the range -MAX_TEMP_CHANGE 27 | # through MAX_TEMP_CHANGE and add it to the current temperature 28 | thermostat['Temperature'] += random.randrange( 29 | -MAX_TEMP_CHANGE, MAX_TEMP_CHANGE + 1) 30 | 31 | # ensure that the temperature stays within range 32 | if thermostat['Temperature'] < MIN_CELSIUS_TEMP: 33 | thermostat['Temperature'] = MIN_CELSIUS_TEMP 34 | 35 | if thermostat['Temperature'] > MAX_CELSIUS_TEMP: 36 | thermostat['Temperature'] = MAX_CELSIUS_TEMP 37 | 38 | # check for low temperature warning 39 | if thermostat['Temperature'] < 3: 40 | thermostat['LowTempWarning'] = True 41 | else: 42 | thermostat['LowTempWarning'] = False 43 | 44 | # check for high temperature warning 45 | if thermostat['Temperature'] > 35: 46 | thermostat['HighTempWarning'] = True 47 | else: 48 | thermostat['HighTempWarning'] = False 49 | 50 | # send the dweet to dweet.io via dweepy 51 | print(f'Messages sent: {message + 1}\r', end='') 52 | dweepy.dweet_for(dweeter, thermostat) 53 | time.sleep(MESSAGE_DELAY) 54 | 55 | print('Temperature simulator finished') 56 | -------------------------------------------------------------------------------- /ch16/simulator_dashboard.py: -------------------------------------------------------------------------------- 1 | # simulator_dashboard.py 2 | """Script That Subscribes to the Thermostat Messages 3 | and Visualizes them Using Plotly's Dash""" 4 | import dash 5 | from dash import dcc, html, Output, Input 6 | import plotly.graph_objs as go 7 | from pubnub.enums import PNStatusCategory 8 | from pubnub.pubnub import PubNub 9 | from pubnub.pnconfiguration import PNConfiguration 10 | from pubnub.callbacks import SubscribeCallback 11 | import keys 12 | 13 | # create Dash app named with the global variable __name__ 14 | app = dash.Dash(__name__) 15 | 16 | # create app's layout 17 | app.layout = html.Div([ 18 | dcc.Graph(id='temperature-gauge', style={'marginBottom': '0px'}), 19 | html.Div(id='fahrenheit-text', 20 | style={'textAlign': 'center', 21 | 'fontSize': 30, 'fontFamily': 'Arial'}), 22 | html.Div([ 23 | html.Div([ 24 | html.Div(id='low-warning-light', 25 | style={'display': 'inline-block', 'width': '20px', 26 | 'height': '20px', 'borderRadius': '50%'}), 27 | html.Div("Too Low", 28 | style={'display': 'inline-block', 29 | 'fontSize': 16, 'fontFamily': 'Arial'}) 30 | ], style={'textAlign': 'center', 'marginTop': '10px'}), 31 | html.Div([ 32 | html.Div(id='high-warning-light', 33 | style={'display': 'inline-block', 'width': '20px', 34 | 'height': '20px', 'borderRadius': '50%'}), 35 | html.Div("Too High", 36 | style={'display': 'inline-block', 37 | 'fontSize': 16, 'fontFamily': 'Arial'}) 38 | ], style={'textAlign': 'center', 39 | 'marginTop': '10px'}) 40 | ]), 41 | dcc.Interval(id='interval-component', 42 | interval=1000) # refresh once per second 43 | ], style={'fontFamily': 'Arial', 'width': '500px', 'margin': '0 auto'}) 44 | 45 | # global variable to store latest message received from thermostat 46 | latest_message = None 47 | 48 | class ThermostatSubscribeCallback(SubscribeCallback): 49 | """ThermostatSubscribeCallback receives messages from PubNub.""" 50 | 51 | def __init__(self, max_messages=1000): 52 | """Creates instance variables for tracking number of messages.""" 53 | self.message_count = 0 54 | self.MAX_MESSAGES = max_messages # 1000 by default 55 | super().__init__() # call superclass's init 56 | 57 | def status(self, pubnub, status): 58 | """Processes status notifications from PubNub.""" 59 | if status.category == PNStatusCategory.PNConnectedCategory: 60 | print('Subscribed') 61 | elif status.category == PNStatusCategory.PNAcknowledgmentCategory: 62 | print('Unsubscribed') 63 | else: 64 | print(status.category) 65 | 66 | def message(self, pubnub, message): 67 | """Receives each message PubNub pushes.""" 68 | global latest_message 69 | self.message_count += 1 70 | latest_message = message.message 71 | 72 | # if MAX_MESSAGES reached, unsubscribe from PubNub channel 73 | if self.message_count == self.MAX_MESSAGES: 74 | pubnub.unsubscribe_all() 75 | 76 | # set up the Dash app's callback that updates the UI 77 | @app.callback( 78 | [Output('temperature-gauge', 'figure'), 79 | Output('fahrenheit-text', 'children'), 80 | Output('low-warning-light', 'style'), 81 | Output('high-warning-light', 'style')], 82 | [Input('interval-component', 'n_intervals')] 83 | ) 84 | def update_dashboard(n): 85 | # do not update unless latest_message contains a message 86 | if latest_message is None: 87 | raise dash.exceptions.PreventUpdate 88 | 89 | # get the temperature from the message and convert it to Fahrenheit 90 | temperature_c = latest_message.get('Temperature', 0) 91 | temperature_f = temperature_c * 9 / 5 + 32 92 | fahrenheit_text = f"{temperature_f:.1f}°F" 93 | 94 | # create the gauge graph object (go) for the next update 95 | gauge = go.Figure(go.Indicator( 96 | mode="gauge+number", 97 | value=temperature_c, 98 | domain={'x': [0, 1], 'y': [0, 1]}, 99 | title={'text': "Temperature (°C)"}, 100 | number={'font': {'family': "Arial"}}, 101 | gauge={ 102 | 'axis': {'range': [-25, 45], 103 | 'tickfont': {'size': 12, 'family': 'Arial'}}, 104 | 'bar': {'color': "darkblue"}, 105 | 'steps': [ 106 | {'range': [-25, 0], 'color': 'cyan'}, 107 | {'range': [0, 45], 'color': 'orange'} 108 | ], 109 | 'threshold': { 110 | 'line': {'color': "red", 'width': 4}, 111 | 'thickness': 0.75, 112 | 'value': temperature_c 113 | } 114 | } 115 | )) 116 | 117 | # update warning lights based on values in latest message 118 | low_light = latest_message.get('Too_Low', False) 119 | high_light = latest_message.get('Too_High', False) 120 | 121 | low_light_style = { 122 | 'display': 'inline-block', 123 | 'width': '20px', 124 | 'height': '20px', 125 | 'borderRadius': '50%', 126 | 'backgroundColor': 'red' if low_light else 'grey', 127 | 'marginRight': '10px' 128 | } 129 | high_light_style = { 130 | 'display': 'inline-block', 131 | 'width': '20px', 132 | 'height': '20px', 133 | 'borderRadius': '50%', 134 | 'backgroundColor': 'red' if high_light else 'grey', 135 | 'marginRight': '10px' 136 | } 137 | 138 | return gauge, fahrenheit_text, low_light_style, high_light_style 139 | 140 | # launch Dash server when this file is run as a script 141 | if __name__ == '__main__': 142 | # PubNub client subscription info 143 | config = PNConfiguration() 144 | config.subscribe_key = keys.pubnub_subscribe_key 145 | config.user_id = keys.pubnub_user_id # your login ID 146 | 147 | # create the pubnub client 148 | pubnub = PubNub(config) 149 | 150 | # channel we'll subscribe to 151 | CHANNEL_NAME = 'deitel-thermostat-simulator' 152 | 153 | # set up the listener and subscribe to the channel 154 | pubnub.add_listener(ThermostatSubscribeCallback()) 155 | pubnub.subscribe().channels(CHANNEL_NAME).execute() 156 | 157 | app.run_server(debug=True) 158 | 159 | -------------------------------------------------------------------------------- /ch16/simulator_pubnub.py: -------------------------------------------------------------------------------- 1 | # simulator_pubnub.py 2 | """A connected thermostat simulator that publishes JSON 3 | messages using PubNub""" 4 | import keys 5 | from pubnub.pnconfiguration import PNConfiguration 6 | from pubnub.pubnub import PubNub 7 | from pubnub.exceptions import PubNubException 8 | import random 9 | import sys 10 | import time 11 | 12 | MIN_CELSIUS_TEMP = -25 13 | MAX_CELSIUS_TEMP = 45 14 | MAX_TEMP_CHANGE = 2 15 | 16 | # get the number of messages to simulate and delay between them 17 | NUMBER_OF_MESSAGES = int(sys.argv[1]) 18 | MESSAGE_DELAY = int(sys.argv[2]) 19 | 20 | # PubNub configuration 21 | config = PNConfiguration() 22 | config.user_id = keys.pubnub_user_id 23 | config.publish_key = keys.pubnub_publish_key 24 | config.subscribe_key = keys.pubnub_subscribe_key 25 | pubnub = PubNub(config) 26 | 27 | channel = 'deitel-thermostat-simulator' # provide a unique name 28 | 29 | thermostat = {'Location': 'Home', 30 | 'Temperature': 20, 31 | 'Too_Low': False, 32 | 'Too_High': False} 33 | 34 | print('Temperature simulator starting') 35 | 36 | def publish_callback(envelope, status): 37 | # Handle PUBLISH response and status 38 | if status.is_error(): 39 | print(f'Failed to publish message: {status}') 40 | 41 | for message in range(1, NUMBER_OF_MESSAGES + 1): 42 | # generate a random number in the range -MAX_TEMP_CHANGE 43 | # through MAX_TEMP_CHANGE and add it to the current temperature 44 | thermostat['Temperature'] += random.randrange( 45 | -MAX_TEMP_CHANGE, MAX_TEMP_CHANGE + 1) 46 | 47 | # ensure that the temperature stays within range 48 | if thermostat['Temperature'] < MIN_CELSIUS_TEMP: 49 | thermostat['Temperature'] = MIN_CELSIUS_TEMP 50 | 51 | if thermostat['Temperature'] > MAX_CELSIUS_TEMP: 52 | thermostat['Temperature'] = MAX_CELSIUS_TEMP 53 | 54 | # check for low temperature warning 55 | if thermostat['Temperature'] < 3: 56 | thermostat['Too_Low'] = True 57 | else: 58 | thermostat['Too_Low'] = False 59 | 60 | # check for high temperature warning 61 | if thermostat['Temperature'] > 35: 62 | thermostat['Too_High'] = True 63 | else: 64 | thermostat['Too_High'] = False 65 | 66 | # Publish the message to PubNub 67 | try: 68 | pubnub.publish().channel(channel).message(thermostat).pn_async(publish_callback) 69 | except PubNubException as e: 70 | print(f"An error occurred: {e}") 71 | sys.exit(1) 72 | else: 73 | print(f'Message {message}: {thermostat}\r', end='') 74 | 75 | time.sleep(MESSAGE_DELAY) 76 | 77 | print('\nTemperature simulator finished') 78 | -------------------------------------------------------------------------------- /ch16/starttootstream.py: -------------------------------------------------------------------------------- 1 | # starttweetstream.py 2 | """Script to get tweets on topic(s) specified as script argument(s) 3 | and send tweet text to a socket for processing by Spark.""" 4 | import keys_mastodon 5 | from mastodon import Mastodon 6 | from mastodon import StreamListener 7 | import socket 8 | import sys 9 | import re 10 | 11 | class TootListener(StreamListener): 12 | """Handles incoming toot stream.""" 13 | 14 | def __init__(self, connection, limit=10): 15 | """Create instance variables for tracking number of tweets.""" 16 | self.connection = connection 17 | self.toot_count = 0 18 | self.TOOT_LIMIT = limit 19 | 20 | def on_update(self, status): 21 | """Called when your listener receives a toot (status).""" 22 | 23 | # ignore if no hashtags 24 | if not status.tags: 25 | return 26 | 27 | hashtags = [] # stores the hashtags to send to spark app 28 | for hashtag in status.tags: 29 | hashtags.append(hashtag['name'].lower()) 30 | 31 | # create a string of hashtags 32 | hashtags_string = ' '.join(hashtags) + '\n' 33 | print(f'{status.account.username}: {hashtags_string}') 34 | 35 | self.toot_count += 1 # track number of tweets processed 36 | 37 | # send hashtags to listening spark app 38 | try: 39 | # send requires bytes, so encode the string in utf-8 format 40 | self.connection.send(hashtags_string.encode('utf-8')) 41 | except Exception as e: 42 | print(f'Error: {e}') 43 | 44 | # if TOOT_LIMIT is reached, close the stream 45 | if self.toot_count == self.TOOT_LIMIT: 46 | print('TOOT_LIMIT reached. Application terminating.') 47 | sys.exit(0) 48 | 49 | if __name__ == '__main__': 50 | # create deiteltest app and save its credentials 51 | credentials = Mastodon.create_app( 52 | 'DeitelSteamHashtags', 53 | api_base_url='https://mastodon.social', 54 | to_file='deitel_stream_hashtags_credentials.secret' 55 | ) 56 | 57 | # create Mastodon client objects for making API calls then log in 58 | #mastodon = Mastodon(client_id='deitel_stream_hashtags_credentials.secret') 59 | mastodon = Mastodon( 60 | client_id='deitel_stream_hashtags_credentials.secret', 61 | api_base_url='https://mastodon.social' 62 | ) 63 | 64 | # have user log in 65 | auth_url = mastodon.auth_request_url(scopes=['read', 'write']) 66 | print(f"Please visit this URL and authorize the app: {auth_url}") 67 | code = input("Enter the authorization code: ") 68 | 69 | # log into mastodon API 70 | access_token_str = mastodon.log_in( 71 | code=code, 72 | scopes=['read'], # can include read, write, follow, push 73 | to_file='usercred.secret' 74 | ) 75 | # access_token = mastodon.log_in(keys_mastodon.usr, keys_mastodon.pwd, 76 | # to_file='deitel_stream_hashtags_credentials.secret') 77 | 78 | toot_limit = int(sys.argv[1]) # get maximum number of toots 79 | client_socket = socket.socket() # create a socket 80 | 81 | # app will use localhost (this computer) port 9876 82 | client_socket.bind(('localhost', 9876)) 83 | 84 | print('Waiting for connection') 85 | client_socket.listen() # wait for client to connect 86 | 87 | # when connection received, get connection/client address 88 | connection, address = client_socket.accept() 89 | print(f'Connection received from {address}') 90 | 91 | # create the StreamListener 92 | toot_listener = TootListener(connection, limit=toot_limit) 93 | 94 | # start the public federated stream and store the stream handle 95 | mastodon.stream_public(toot_listener, run_async=False) 96 | 97 | 98 | ########################################################################## 99 | # (C) Copyright 2023 by Deitel & Associates, Inc. and # 100 | # Pearson Education, Inc. All Rights Reserved. # 101 | # # 102 | # DISCLAIMER: The authors and publisher of this book have used their # 103 | # best efforts in preparing the book. These efforts include the # 104 | # development, research, and testing of the theories and programs # 105 | # to determine their effectiveness. The authors and publisher make # 106 | # no warranty of any kind, expressed or implied, with regard to these # 107 | # programs or to the documentation contained in these books. The authors # 108 | # and publisher shall not be liable in any event for incidental or # 109 | # consequential damages in connection with, or arising out of, the # 110 | # furnishing, performance, or use of these programs. # 111 | ########################################################################## 112 | -------------------------------------------------------------------------------- /ch16/state_codes.py: -------------------------------------------------------------------------------- 1 | state_codes = { 2 | 'AL': 'Alabama', 3 | 'AK': 'Alaska', 4 | 'AZ': 'Arizona', 5 | 'AR': 'Arkansas', 6 | 'CA': 'California', 7 | 'CO': 'Colorado', 8 | 'CT': 'Connecticut', 9 | 'DE': 'Delaware', 10 | 'FL': 'Florida', 11 | 'GA': 'Georgia', 12 | 'HI': 'Hawaii', 13 | 'ID': 'Idaho', 14 | 'IL': 'Illinois', 15 | 'IN': 'Indiana', 16 | 'IA': 'Iowa', 17 | 'KS': 'Kansas', 18 | 'KY': 'Kentucky', 19 | 'LA': 'Louisiana', 20 | 'ME': 'Maine', 21 | 'MD': 'Maryland', 22 | 'MA': 'Massachusetts', 23 | 'MI': 'Michigan', 24 | 'MN': 'Minnesota', 25 | 'MS': 'Mississippi', 26 | 'MO': 'Missouri', 27 | 'MT': 'Montana', 28 | 'NE': 'Nebraska', 29 | 'NV': 'Nevada', 30 | 'NH': 'New Hampshire', 31 | 'NJ': 'New Jersey', 32 | 'NM': 'New Mexico', 33 | 'NY': 'New York', 34 | 'NC': 'North Carolina', 35 | 'ND': 'North Dakota', 36 | 'OH': 'Ohio', 37 | 'OK': 'Oklahoma', 38 | 'OR': 'Oregon', 39 | 'PA': 'Pennsylvania', 40 | 'RI': 'Rhode Island', 41 | 'SC': 'South Carolina', 42 | 'SD': 'South Dakota', 43 | 'TN': 'Tennessee', 44 | 'TX': 'Texas', 45 | 'UT': 'Utah', 46 | 'VT': 'Vermont', 47 | 'VA': 'Virginia', 48 | 'WA': 'Washington State', 49 | 'WV': 'West Virginia', 50 | 'WI': 'Wisconsin', 51 | 'WY': 'Wyoming' 52 | } -------------------------------------------------------------------------------- /ch16/stocklistener.py: -------------------------------------------------------------------------------- 1 | # stocklistener.py 2 | """Visualizing a PubNub live stream.""" 3 | from matplotlib import animation 4 | import matplotlib.pyplot as plt 5 | import pandas as pd 6 | import random 7 | import seaborn as sns 8 | import sys 9 | import keys 10 | 11 | from pubnub.callbacks import SubscribeCallback 12 | from pubnub.enums import PNStatusCategory 13 | from pubnub.pnconfiguration import PNConfiguration 14 | from pubnub.pubnub import PubNub 15 | 16 | import warnings 17 | warnings.simplefilter(action='ignore', category=FutureWarning) 18 | 19 | companies = ['Apple', 'Bespin Gas', 'Elerium', 'Google', 'Linen Cloth'] 20 | 21 | # DataFrame to store last stock prices 22 | companies_df = pd.DataFrame( 23 | {'company': companies, 'price' : [0, 0, 0, 0, 0]}) 24 | 25 | class StockSubscriberCallback(SubscribeCallback): 26 | """StockSubscriberCallback receives messages from PubNub.""" 27 | def __init__(self, df, limit=1000): 28 | """Create instance variables for tracking number of tweets.""" 29 | self.df = df # DataFrame to store last stock prices 30 | self.order_count = 0 31 | self.MAX_ORDERS = limit # 1000 by default 32 | super().__init__() # call superclass's init 33 | 34 | def status(self, pubnub, status): 35 | if status.category == PNStatusCategory.PNConnectedCategory: 36 | print('Subscribed') 37 | elif status.category == PNStatusCategory.PNAcknowledgmentCategory: 38 | print('Unsubscribed') 39 | 40 | def message(self, pubnub, message): 41 | symbol = message.message['symbol'] 42 | bid_price = message.message['bid_price'] 43 | print(symbol, bid_price) 44 | self.df.at[companies.index(symbol), 'price'] = bid_price 45 | self.order_count += 1 46 | 47 | # if MAX_ORDERS is reached, unsubscribe from PubNub channel 48 | if self.order_count == self.MAX_ORDERS: 49 | pubnub.unsubscribe_all() 50 | 51 | def update(frame_number): 52 | """Configures bar plot contents for each animation frame.""" 53 | plt.cla() # clear old barplot 54 | axes = sns.barplot( 55 | data=companies_df, x='company', y='price', palette='cool') 56 | axes.set(xlabel='Company', ylabel='Price') 57 | 58 | if __name__ == '__main__': 59 | sns.set_style('whitegrid') # white background with gray grid lines 60 | figure = plt.figure('Stock Prices') # Figure for animation 61 | 62 | # set up pubnub-market-orders sensor stream key 63 | config = PNConfiguration() 64 | config.subscribe_key = 'sub-c-99084bc5-1844-4e1c-82ca-a01b18166ca8' 65 | config.user_id = keys.pubnub_user_id # new requirement in SDK 6.x 66 | 67 | # create PubNub client and register a SubscribeCallback 68 | pubnub = PubNub(config) 69 | pubnub.add_listener( 70 | StockSubscriberCallback(df=companies_df, 71 | limit=int(sys.argv[1] if len(sys.argv) > 1 else 1000))) 72 | 73 | # subscribe to pubnub-sensor-network channel and begin streaming 74 | pubnub.subscribe().channels('pubnub-market-orders').execute() 75 | 76 | # configure and start animation that calls function update 77 | stock_animation = animation.FuncAnimation( 78 | figure, update, frames=1000, repeat=False, interval=33) 79 | plt.tight_layout() 80 | plt.show() # keeps graph on screen until you dismiss its window 81 | 82 | #************************************************************************** 83 | #* (C) Copyright 1992-2018 by Deitel & Associates, Inc. and * 84 | #* Pearson Education, Inc. All Rights Reserved. * 85 | #* * 86 | #* DISCLAIMER: The authors and publisher of this book have used their * 87 | #* best efforts in preparing the book. These efforts include the * 88 | #* development, research, and testing of the theories and programs * 89 | #* to determine their effectiveness. The authors and publisher make * 90 | #* no warranty of any kind, expressed or implied, with regard to these * 91 | #* programs or to the documentation contained in these books. The authors * 92 | #* and publisher shall not be liable in any event for incidental or * 93 | #* consequential damages in connection with, or arising out of, the * 94 | #* furnishing, performance, or use of these programs. * 95 | #************************************************************************** 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /images/.ipynb_checkpoints/IntroToPythonCover-checkpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/.ipynb_checkpoints/IntroToPythonCover-checkpoint.png -------------------------------------------------------------------------------- /images/.ipynb_checkpoints/PyFPCover-checkpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/.ipynb_checkpoints/PyFPCover-checkpoint.png -------------------------------------------------------------------------------- /images/.ipynb_checkpoints/PythonFundamentalsLiveLessons-checkpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/.ipynb_checkpoints/PythonFundamentalsLiveLessons-checkpoint.jpg -------------------------------------------------------------------------------- /images/.ipynb_checkpoints/course_image-checkpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/.ipynb_checkpoints/course_image-checkpoint.jpg -------------------------------------------------------------------------------- /images/IntroToPythonCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/IntroToPythonCover.png -------------------------------------------------------------------------------- /images/IntroToPythonTOC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/IntroToPythonTOC.png -------------------------------------------------------------------------------- /images/PyFPCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/PyFPCover.png -------------------------------------------------------------------------------- /images/PythonFundamentalsLiveLessons.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/PythonFundamentalsLiveLessons.jpg -------------------------------------------------------------------------------- /images/course_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/course_image.jpg -------------------------------------------------------------------------------- /images/jhtp12Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/images/jhtp12Cover.jpg -------------------------------------------------------------------------------- /openai/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/.DS_Store -------------------------------------------------------------------------------- /openai/Chinese.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/Chinese.mp3 -------------------------------------------------------------------------------- /openai/HavaneseDog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/HavaneseDog.png -------------------------------------------------------------------------------- /openai/Spanish.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/Spanish.mp3 -------------------------------------------------------------------------------- /openai/SpokenResponse.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/SpokenResponse.wav -------------------------------------------------------------------------------- /openai/deep_learning_intro.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/deep_learning_intro.m4a -------------------------------------------------------------------------------- /openai/english_summary.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/english_summary.mp3 -------------------------------------------------------------------------------- /openai/mask_heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/mask_heart.png -------------------------------------------------------------------------------- /openai/presentation_summary.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/presentation_summary.docx -------------------------------------------------------------------------------- /openai/resources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/.DS_Store -------------------------------------------------------------------------------- /openai/resources/ForLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/ForLoop.png -------------------------------------------------------------------------------- /openai/resources/WhatsNewInJavaOverview.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/WhatsNewInJavaOverview.m4a -------------------------------------------------------------------------------- /openai/resources/beach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/beach.jpg -------------------------------------------------------------------------------- /openai/resources/deep_learning_intro.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/deep_learning_intro.m4a -------------------------------------------------------------------------------- /openai/resources/lessonBYB_00.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/lessonBYB_00.mp4 -------------------------------------------------------------------------------- /openai/resources/mask_heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/mask_heart.png -------------------------------------------------------------------------------- /openai/resources/outputs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/.DS_Store -------------------------------------------------------------------------------- /openai/resources/outputs/ActivityDiagramApp.java: -------------------------------------------------------------------------------- 1 | import javafx.application.Application; 2 | import javafx.scene.Scene; 3 | import javafx.scene.layout.Pane; 4 | import javafx.scene.paint.Color; 5 | import javafx.scene.shape.Line; 6 | import javafx.scene.shape.SVGPath; 7 | import javafx.scene.shape.Rectangle; 8 | import javafx.scene.shape.Circle; 9 | import javafx.scene.text.Font; 10 | import javafx.scene.text.FontWeight; 11 | import javafx.scene.text.Text; 12 | import javafx.stage.Stage; 13 | import org.w3c.dom.Document; 14 | import org.w3c.dom.NodeList; 15 | import javax.xml.parsers.DocumentBuilder; 16 | import javax.xml.parsers.DocumentBuilderFactory; 17 | import java.nio.file.Files; 18 | import java.nio.file.Path; 19 | import java.nio.file.Paths; 20 | 21 | public class ActivityDiagramApp extends Application { 22 | @Override 23 | public void start(Stage stage) { 24 | Pane pane = new Pane(); 25 | pane.setPrefSize(1000, 800); // Set larger bounds for Pane 26 | 27 | // Load SVG content from the file 28 | java.nio.file.Path svgFilePath = Paths.get("/mnt/data/ForLoopUMLActivityDiagram.svg"); 29 | try { 30 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 31 | DocumentBuilder builder = factory.newDocumentBuilder(); 32 | Document document = builder.parse(Files.newInputStream(svgFilePath)); 33 | document.getDocumentElement().normalize(); 34 | 35 | // Extract and render lines 36 | NodeList lineList = document.getElementsByTagName("line"); 37 | for (int i = 0; i < lineList.getLength(); i++) { 38 | try { 39 | double x1 = Double.parseDouble(lineList.item(i).getAttributes().getNamedItem("x1").getNodeValue()); 40 | double y1 = Double.parseDouble(lineList.item(i).getAttributes().getNamedItem("y1").getNodeValue()); 41 | double x2 = Double.parseDouble(lineList.item(i).getAttributes().getNamedItem("x2").getNodeValue()); 42 | double y2 = Double.parseDouble(lineList.item(i).getAttributes().getNamedItem("y2").getNodeValue()); 43 | 44 | Line line = new Line(x1, y1, x2, y2); 45 | line.setStrokeWidth(2); 46 | line.setStroke(Color.BLACK); 47 | pane.getChildren().add(line); 48 | } catch (Exception e) { 49 | System.out.println("Error parsing line element: " + e.getMessage()); 50 | } 51 | } 52 | 53 | // Extract and render rectangles 54 | NodeList rectList = document.getElementsByTagName("rect"); 55 | for (int i = 0; i < rectList.getLength(); i++) { 56 | try { 57 | double x = Double.parseDouble(rectList.item(i).getAttributes().getNamedItem("x").getNodeValue()); 58 | double y = Double.parseDouble(rectList.item(i).getAttributes().getNamedItem("y").getNodeValue()); 59 | double width = Double.parseDouble(rectList.item(i).getAttributes().getNamedItem("width").getNodeValue()); 60 | double height = Double.parseDouble(rectList.item(i).getAttributes().getNamedItem("height").getNodeValue()); 61 | 62 | Rectangle rectangle = new Rectangle(x, y, width, height); 63 | rectangle.setArcWidth(10); 64 | rectangle.setArcHeight(10); 65 | rectangle.setFill(Color.LIGHTBLUE); 66 | rectangle.setStroke(Color.BLACK); 67 | pane.getChildren().add(rectangle); 68 | } catch (Exception e) { 69 | System.out.println("Error parsing rectangle element: " + e.getMessage()); 70 | } 71 | } 72 | 73 | // Extract and render circles 74 | NodeList circleList = document.getElementsByTagName("circle"); 75 | for (int i = 0; i < circleList.getLength(); i++) { 76 | try { 77 | double cx = Double.parseDouble(circleList.item(i).getAttributes().getNamedItem("cx").getNodeValue()); 78 | double cy = Double.parseDouble(circleList.item(i).getAttributes().getNamedItem("cy").getNodeValue()); 79 | double radius = Double.parseDouble(circleList.item(i).getAttributes().getNamedItem("r").getNodeValue()); 80 | 81 | Circle circle = new Circle(cx, cy, radius); 82 | circle.setFill(Color.LIGHTGREEN); 83 | circle.setStroke(Color.BLACK); 84 | pane.getChildren().add(circle); 85 | } catch (Exception e) { 86 | System.out.println("Error parsing circle element: " + e.getMessage()); 87 | } 88 | } 89 | 90 | // Extract and render paths 91 | NodeList pathList = document.getElementsByTagName("path"); 92 | for (int i = 0; i < pathList.getLength(); i++) { 93 | try { 94 | String pathData = pathList.item(i).getAttributes().getNamedItem("d").getNodeValue(); 95 | 96 | SVGPath svgPath = new SVGPath(); 97 | svgPath.setContent(pathData); 98 | svgPath.setFill(Color.TRANSPARENT); 99 | svgPath.setStroke(Color.BLACK); 100 | pane.getChildren().add(svgPath); 101 | } catch (Exception e) { 102 | System.out.println("Error parsing path element: " + e.getMessage()); 103 | } 104 | } 105 | 106 | } catch (Exception e) { 107 | System.out.println("Error loading SVG: " + e.getMessage()); 108 | } 109 | 110 | // Set up the scene 111 | Scene scene = new Scene(pane, 1000, 800); 112 | stage.setTitle("Activity Diagram Exact Recreation with JavaFX 23"); 113 | stage.setScene(scene); 114 | stage.show(); 115 | } 116 | 117 | public static void main(String[] args) { 118 | launch(args); 119 | } 120 | } 121 | 122 | /************************************************************************** 123 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 124 | * Pearson Education, Inc. All Rights Reserved. * 125 | * * 126 | * DISCLAIMER: The authors and publisher of this book have used their * 127 | * best efforts in preparing the book. These efforts include the * 128 | * development, research, and testing of the theories and programs * 129 | * to determine their effectiveness. The authors and publisher make * 130 | * no warranty of any kind, expressed or implied, with regard to these * 131 | * programs or to the documentation contained in these books. The authors * 132 | * and publisher shall not be liable in any event for incidental or * 133 | * consequential damages in connection with, or arising out of, the * 134 | * furnishing, performance, or use of these programs. * 135 | *************************************************************************/ 136 | -------------------------------------------------------------------------------- /openai/resources/outputs/CannonGame copy.java: -------------------------------------------------------------------------------- 1 | import javafx.animation.*; 2 | import javafx.application.Application; 3 | import javafx.application.Platform; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Alert; 6 | import javafx.scene.control.Label; 7 | import javafx.scene.layout.Pane; 8 | import javafx.scene.media.AudioClip; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Circle; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.scene.shape.Shape; 13 | import javafx.stage.Stage; 14 | import javafx.util.Duration; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.Random; 19 | 20 | public class CannonGame extends Application { 21 | private final String path = java.nio.file.Path.of(System.getProperty("user.home"), "Documents", "examples", "ch19", "resources", "Cannon").toString(); 22 | 23 | private Pane root; 24 | private int shotsFired = 0; 25 | private double timeRemaining = 10.0; 26 | private List targets = new ArrayList<>(); 27 | private Blocker blocker; 28 | private Timeline timer; 29 | private final AudioClip cannonFireSound = new AudioClip(java.nio.file.Path.of(path, "cannon_fire.wav").toUri().toString()); 30 | private final AudioClip targetHitSound = new AudioClip(java.nio.file.Path.of(path, "target_hit.wav").toUri().toString()); 31 | private final AudioClip blockerHitSound = new AudioClip(java.nio.file.Path.of(path, "blocker_hit.wav").toUri().toString()); 32 | private boolean cannonBallInFlight = false; 33 | private Label timerLabel; 34 | 35 | @Override 36 | public void start(Stage primaryStage) { 37 | root = new Pane(); 38 | Scene scene = new Scene(root, 1024, 768); 39 | 40 | // Timer label setup 41 | timerLabel = new Label("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 42 | timerLabel.setStyle("-fx-font-size: 24px;"); // Increase timer label font size 43 | timerLabel.setLayoutX(20); 44 | timerLabel.setLayoutY(20); 45 | root.getChildren().add(timerLabel); 46 | 47 | Cannon cannon = new Cannon(50, 384); 48 | root.getChildren().add(cannon.getShape()); 49 | 50 | // Targets setup 51 | Random random = new Random(); 52 | for (int i = 0; i < 9; i++) { 53 | Target target = new Target(600 + (i * 40), 100); 54 | targets.add(target); 55 | root.getChildren().add(target.getShape()); 56 | target.startMovement(random.nextBoolean(), random.nextDouble() * 1.5 + 1.0); // Randomize direction and speed 57 | } 58 | 59 | // Blocker setup 60 | blocker = new Blocker(450, 200); // Move blocker farther to the right 61 | root.getChildren().add(blocker.getShape()); 62 | blocker.startMovement(random.nextBoolean(), random.nextDouble() * 1.5 + 1.0); 63 | 64 | // Timer setup 65 | timer = new Timeline(new KeyFrame(Duration.seconds(0.1), event -> { 66 | timeRemaining = Math.max(0.0, timeRemaining - 0.1); // Ensure time does not go below 0 67 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 68 | if (timeRemaining <= 0) { 69 | Platform.runLater(() -> endGame(false)); 70 | } 71 | })); 72 | timer.setCycleCount(Animation.INDEFINITE); 73 | timer.play(); 74 | 75 | // Mouse click listener for firing cannon 76 | scene.setOnMouseClicked(e -> { 77 | if (!cannonBallInFlight) { 78 | shotsFired++; 79 | CannonBall cannonBall = cannon.fire(e.getX(), e.getY()); 80 | cannonFireSound.play(); 81 | root.getChildren().add(cannonBall.getShape()); 82 | cannonBall.startMovement(targets, blocker); 83 | cannonBallInFlight = true; 84 | } 85 | }); 86 | 87 | primaryStage.setScene(scene); 88 | primaryStage.setTitle("Cannon Game"); 89 | primaryStage.show(); 90 | } 91 | 92 | private void endGame(boolean won) { 93 | timer.stop(); 94 | stopAllAnimations(); 95 | Platform.runLater(() -> { 96 | Alert alert = new Alert(Alert.AlertType.INFORMATION); 97 | alert.setTitle("Game Over"); 98 | alert.setHeaderText(null); 99 | alert.setContentText(won ? "You won! Shots fired: " + shotsFired : "You lost! Shots fired: " + shotsFired); 100 | alert.showAndWait(); 101 | }); 102 | } 103 | 104 | private void stopAllAnimations() { 105 | // Stop all targets and blocker animations 106 | for (Target target : targets) { 107 | target.stopMovement(); 108 | } 109 | if (blocker != null) { 110 | blocker.stopMovement(); 111 | } 112 | } 113 | 114 | public static void main(String[] args) { 115 | launch(args); 116 | } 117 | 118 | // Cannon Class 119 | class Cannon { 120 | private Rectangle barrel; 121 | 122 | public Cannon(double x, double y) { 123 | barrel = new Rectangle(x, y - 15, 80, 30); // Adjusted size to match the image 124 | barrel.setFill(Color.BLACK); 125 | } 126 | 127 | public Rectangle getShape() { 128 | return barrel; 129 | } 130 | 131 | public CannonBall fire(double targetX, double targetY) { 132 | double angle = Math.atan2(targetY - (barrel.getY() + barrel.getHeight() / 2), targetX - (barrel.getX() + barrel.getWidth() / 2)); 133 | barrel.setRotate(Math.toDegrees(angle)); // Rotate the barrel to point in the direction of fire 134 | return new CannonBall(barrel.getX() + barrel.getWidth(), barrel.getY() + barrel.getHeight() / 2, angle); 135 | } 136 | } 137 | 138 | // CannonBall Class 139 | class CannonBall { 140 | private Circle shape; 141 | private double angle; 142 | private double speed = 10; // Increased speed for better gameplay 143 | 144 | public CannonBall(double x, double y, double angle) { 145 | shape = new Circle(x, y, 10, Color.BLACK); // Increased size for better visibility 146 | this.angle = angle; 147 | } 148 | 149 | public Circle getShape() { 150 | return shape; 151 | } 152 | 153 | public void startMovement(List targets, Blocker blocker) { 154 | AnimationTimer movement = new AnimationTimer() { 155 | @Override 156 | public void handle(long now) { 157 | shape.setCenterX(shape.getCenterX() + Math.cos(angle) * speed); 158 | shape.setCenterY(shape.getCenterY() + Math.sin(angle) * speed); 159 | 160 | // Check collisions with targets 161 | for (Target target : new ArrayList<>(targets)) { 162 | if (Shape.intersect(shape, target.getShape()).getBoundsInLocal().getWidth() != -1) { 163 | root.getChildren().remove(target.getShape()); 164 | root.getChildren().remove(shape); 165 | targets.remove(target); 166 | timeRemaining += 3; 167 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 168 | targetHitSound.play(); 169 | stop(); 170 | cannonBallInFlight = false; 171 | if (targets.isEmpty()) { 172 | Platform.runLater(() -> endGame(true)); 173 | } 174 | return; 175 | } 176 | } 177 | 178 | // Check collision with blocker 179 | if (Shape.intersect(shape, blocker.getShape()).getBoundsInLocal().getWidth() != -1) { 180 | timeRemaining = Math.max(0.0, timeRemaining - 3); 181 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 182 | blockerHitSound.play(); 183 | angle = Math.PI - angle; // Ricochet the cannonball in the opposite direction 184 | } 185 | 186 | // Check if cannonball is out of bounds 187 | if (shape.getCenterX() < 0 || shape.getCenterX() > 1024 || shape.getCenterY() < 0 || shape.getCenterY() > 768) { 188 | root.getChildren().remove(shape); 189 | stop(); 190 | cannonBallInFlight = false; 191 | } 192 | } 193 | }; 194 | movement.start(); 195 | } 196 | } 197 | 198 | // Target Class 199 | class Target { 200 | private Rectangle shape; 201 | private TranslateTransition transition; 202 | 203 | public Target(double x, double y) { 204 | shape = new Rectangle(x, y, 30, 80); // Adjusted size to match image 205 | shape.setFill(Color.BLUE); 206 | } 207 | 208 | public Rectangle getShape() { 209 | return shape; 210 | } 211 | 212 | public void startMovement(boolean moveUpInitially, double speed) { 213 | transition = new TranslateTransition(Duration.seconds(3 / speed), shape); 214 | transition.setByY(500); 215 | transition.setAutoReverse(true); 216 | transition.setCycleCount(TranslateTransition.INDEFINITE); 217 | transition.setRate(moveUpInitially ? -1 : 1); 218 | transition.play(); 219 | } 220 | 221 | public void stopMovement() { 222 | if (transition != null) { 223 | transition.stop(); 224 | } 225 | } 226 | } 227 | 228 | // Blocker Class 229 | class Blocker { 230 | private Rectangle shape; 231 | private TranslateTransition transition; 232 | 233 | public Blocker(double x, double y) { 234 | shape = new Rectangle(x, y, 50, 150); // Adjusted size to match image 235 | shape.setFill(Color.BLACK); 236 | } 237 | 238 | public Rectangle getShape() { 239 | return shape; 240 | } 241 | 242 | public void startMovement(boolean moveUpInitially, double speed) { 243 | transition = new TranslateTransition(Duration.seconds(3 / speed), shape); 244 | transition.setByY(400); 245 | transition.setAutoReverse(true); 246 | transition.setCycleCount(TranslateTransition.INDEFINITE); 247 | transition.setRate(moveUpInitially ? -1 : 1); 248 | transition.play(); 249 | } 250 | 251 | public void stopMovement() { 252 | if (transition != null) { 253 | transition.stop(); 254 | } 255 | } 256 | } 257 | } 258 | 259 | /************************************************************************** 260 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 261 | * Pearson Education, Inc. All Rights Reserved. * 262 | * * 263 | * DISCLAIMER: The authors and publisher of this book have used their * 264 | * best efforts in preparing the book. These efforts include the * 265 | * development, research, and testing of the theories and programs * 266 | * to determine their effectiveness. The authors and publisher make * 267 | * no warranty of any kind, expressed or implied, with regard to these * 268 | * programs or to the documentation contained in these books. The authors * 269 | * and publisher shall not be liable in any event for incidental or * 270 | * consequential damages in connection with, or arising out of, the * 271 | * furnishing, performance, or use of these programs. * 272 | *************************************************************************/ 273 | -------------------------------------------------------------------------------- /openai/resources/outputs/CannonGame.java: -------------------------------------------------------------------------------- 1 | import javafx.animation.*; 2 | import javafx.application.Application; 3 | import javafx.application.Platform; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Alert; 6 | import javafx.scene.control.Label; 7 | import javafx.scene.layout.Pane; 8 | import javafx.scene.media.AudioClip; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Arc; 11 | import javafx.scene.shape.ArcType; 12 | import javafx.scene.shape.Circle; 13 | import javafx.scene.shape.Rectangle; 14 | import javafx.scene.shape.Shape; 15 | import javafx.stage.Stage; 16 | import javafx.util.Duration; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.Random; 21 | 22 | public class CannonGame extends Application { 23 | private final String path = java.nio.file.Path.of(System.getProperty("user.home"), "Documents", "examples", "ch19", "resources", "Cannon").toString(); 24 | 25 | private Pane root; 26 | private int shotsFired = 0; 27 | private double timeRemaining = 10.0; 28 | private List targets = new ArrayList<>(); 29 | private Blocker blocker; 30 | private Timeline timer; 31 | private final AudioClip cannonFireSound = new AudioClip(java.nio.file.Path.of(path, "cannon_fire.wav").toUri().toString()); 32 | private final AudioClip targetHitSound = new AudioClip(java.nio.file.Path.of(path, "target_hit.wav").toUri().toString()); 33 | private final AudioClip blockerHitSound = new AudioClip(java.nio.file.Path.of(path, "blocker_hit.wav").toUri().toString()); 34 | private boolean cannonBallInFlight = false; 35 | private Label timerLabel; 36 | 37 | @Override 38 | public void start(Stage primaryStage) { 39 | root = new Pane(); 40 | Scene scene = new Scene(root, 1024, 768); 41 | 42 | // Timer label setup 43 | timerLabel = new Label("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 44 | timerLabel.setStyle("-fx-font-size: 24px;"); // Increase timer label font size 45 | timerLabel.setLayoutX(20); 46 | timerLabel.setLayoutY(20); 47 | root.getChildren().add(timerLabel); 48 | 49 | Cannon cannon = new Cannon(0, 384); // Adjusted position to place the cannon at the far left edge 50 | root.getChildren().addAll(cannon.getShapes()); 51 | 52 | // Targets setup 53 | Random random = new Random(); 54 | for (int i = 0; i < 9; i++) { 55 | Target target = new Target(600 + (i * 40), 100); 56 | targets.add(target); 57 | root.getChildren().add(target.getShape()); 58 | target.startMovement(random.nextBoolean(), random.nextDouble() * 1.5 + 1.0); // Randomize direction and speed 59 | } 60 | 61 | // Blocker setup 62 | blocker = new Blocker(450, 200); // Move blocker farther to the right 63 | root.getChildren().add(blocker.getShape()); 64 | blocker.startMovement(random.nextBoolean(), random.nextDouble() * 1.5 + 1.0); 65 | 66 | // Timer setup 67 | timer = new Timeline(new KeyFrame(Duration.seconds(0.1), event -> { 68 | timeRemaining = Math.max(0.0, timeRemaining - 0.1); // Ensure time does not go below 0 69 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 70 | if (timeRemaining <= 0) { 71 | Platform.runLater(() -> endGame(false)); 72 | } 73 | })); 74 | timer.setCycleCount(Animation.INDEFINITE); 75 | timer.play(); 76 | 77 | // Mouse click listener for firing cannon 78 | scene.setOnMouseClicked(e -> { 79 | if (!cannonBallInFlight) { 80 | shotsFired++; 81 | CannonBall cannonBall = cannon.fire(e.getX(), e.getY()); 82 | cannonFireSound.play(); 83 | root.getChildren().add(cannonBall.getShape()); 84 | cannonBall.startMovement(targets, blocker); 85 | cannonBallInFlight = true; 86 | } 87 | }); 88 | 89 | primaryStage.setScene(scene); 90 | primaryStage.setTitle("Cannon Game"); 91 | primaryStage.show(); 92 | } 93 | 94 | private void endGame(boolean won) { 95 | timer.stop(); 96 | stopAllAnimations(); 97 | Platform.runLater(() -> { 98 | Alert alert = new Alert(Alert.AlertType.INFORMATION); 99 | alert.setTitle("Game Over"); 100 | alert.setHeaderText(null); 101 | alert.setContentText(won ? "You won! Shots fired: " + shotsFired : "You lost! Shots fired: " + shotsFired); 102 | alert.showAndWait(); 103 | }); 104 | } 105 | 106 | private void stopAllAnimations() { 107 | // Stop all targets and blocker animations 108 | for (Target target : targets) { 109 | target.stopMovement(); 110 | } 111 | if (blocker != null) { 112 | blocker.stopMovement(); 113 | } 114 | } 115 | 116 | public static void main(String[] args) { 117 | launch(args); 118 | } 119 | 120 | // Cannon Class 121 | class Cannon { 122 | private Rectangle barrel; 123 | private Arc base; 124 | 125 | public Cannon(double x, double y) { 126 | // Create the base (semicircle) 127 | base = new Arc(x, y, 60, 60, -90, 180); // Flipped semicircle so the straight edge is on the left side 128 | base.setType(ArcType.ROUND); 129 | base.setFill(Color.BLACK); 130 | 131 | // Create the barrel 132 | barrel = new Rectangle(x, y - 15, 120, 30); // Adjusted position to align with the semicircle base, ensuring it starts from the center left of the semicircle 133 | barrel.setFill(Color.BLACK); 134 | } 135 | 136 | public List getShapes() { 137 | List shapes = new ArrayList<>(); 138 | shapes.add(base); 139 | shapes.add(barrel); 140 | return shapes; 141 | } 142 | 143 | public CannonBall fire(double targetX, double targetY) { 144 | double angle = Math.atan2(targetY - (barrel.getY() + barrel.getHeight() / 2), targetX - (barrel.getX() + barrel.getWidth() / 2)); 145 | double pivotX = barrel.getX(); // The left edge of the barrel remains fixed 146 | double pivotY = barrel.getY() + barrel.getHeight() / 2; 147 | 148 | barrel.getTransforms().clear(); // Clear any previous transforms 149 | barrel.getTransforms().add(new javafx.scene.transform.Rotate(Math.toDegrees(angle), pivotX, pivotY)); // Rotate around the left edge 150 | 151 | return new CannonBall(barrel.getX() + barrel.getWidth(), barrel.getY() + barrel.getHeight() / 2, angle); // Fire from the end of the barrel 152 | } 153 | } 154 | 155 | // CannonBall Class 156 | class CannonBall { 157 | private Circle shape; 158 | private double angle; 159 | private double speed = 10; // Increased speed for better gameplay 160 | 161 | public CannonBall(double x, double y, double angle) { 162 | shape = new Circle(x, y, 10, Color.BLACK); // Increased size for better visibility 163 | this.angle = angle; 164 | } 165 | 166 | public Circle getShape() { 167 | return shape; 168 | } 169 | 170 | public void startMovement(List targets, Blocker blocker) { 171 | AnimationTimer movement = new AnimationTimer() { 172 | @Override 173 | public void handle(long now) { 174 | shape.setCenterX(shape.getCenterX() + Math.cos(angle) * speed); 175 | shape.setCenterY(shape.getCenterY() + Math.sin(angle) * speed); 176 | 177 | // Check collisions with targets 178 | for (Target target : new ArrayList<>(targets)) { 179 | if (Shape.intersect(shape, target.getShape()).getBoundsInLocal().getWidth() != -1) { 180 | root.getChildren().remove(target.getShape()); 181 | root.getChildren().remove(shape); 182 | targets.remove(target); 183 | timeRemaining += 3; 184 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 185 | targetHitSound.play(); 186 | stop(); 187 | cannonBallInFlight = false; 188 | if (targets.isEmpty()) { 189 | Platform.runLater(() -> endGame(true)); 190 | } 191 | return; 192 | } 193 | } 194 | 195 | // Check collision with blocker 196 | if (Shape.intersect(shape, blocker.getShape()).getBoundsInLocal().getWidth() != -1) { 197 | timeRemaining = Math.max(0.0, timeRemaining - 3); 198 | timerLabel.setText("Time remaining: " + String.format("%.1f", timeRemaining) + " seconds"); 199 | blockerHitSound.play(); 200 | angle = Math.PI - angle; // Ricochet the cannonball in the opposite direction 201 | } 202 | 203 | // Check if cannonball is out of bounds 204 | if (shape.getCenterX() < 0 || shape.getCenterX() > 1024 || shape.getCenterY() < 0 || shape.getCenterY() > 768) { 205 | root.getChildren().remove(shape); 206 | stop(); 207 | cannonBallInFlight = false; 208 | } 209 | } 210 | }; 211 | movement.start(); 212 | } 213 | } 214 | 215 | // Target Class 216 | class Target { 217 | private Rectangle shape; 218 | private TranslateTransition transition; 219 | 220 | public Target(double x, double y) { 221 | shape = new Rectangle(x, y, 30, 80); // Adjusted size to match image 222 | shape.setFill(Color.BLUE); 223 | } 224 | 225 | public Rectangle getShape() { 226 | return shape; 227 | } 228 | 229 | public void startMovement(boolean moveUpInitially, double speed) { 230 | transition = new TranslateTransition(Duration.seconds(3 / speed), shape); 231 | transition.setByY(500); 232 | transition.setAutoReverse(true); 233 | transition.setCycleCount(TranslateTransition.INDEFINITE); 234 | transition.setRate(moveUpInitially ? -1 : 1); 235 | transition.play(); 236 | } 237 | 238 | public void stopMovement() { 239 | if (transition != null) { 240 | transition.stop(); 241 | } 242 | } 243 | } 244 | 245 | // Blocker Class 246 | class Blocker { 247 | private Rectangle shape; 248 | private TranslateTransition transition; 249 | 250 | public Blocker(double x, double y) { 251 | shape = new Rectangle(x, y, 50, 150); // Adjusted size to match image 252 | shape.setFill(Color.BLACK); 253 | } 254 | 255 | public Rectangle getShape() { 256 | return shape; 257 | } 258 | 259 | public void startMovement(boolean moveUpInitially, double speed) { 260 | transition = new TranslateTransition(Duration.seconds(3 / speed), shape); 261 | transition.setByY(400); 262 | transition.setAutoReverse(true); 263 | transition.setCycleCount(TranslateTransition.INDEFINITE); 264 | transition.setRate(moveUpInitially ? -1 : 1); 265 | transition.play(); 266 | } 267 | 268 | public void stopMovement() { 269 | if (transition != null) { 270 | transition.stop(); 271 | } 272 | } 273 | } 274 | } 275 | 276 | /************************************************************************** 277 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 278 | * Pearson Education, Inc. All Rights Reserved. * 279 | * * 280 | * DISCLAIMER: The authors and publisher of this book have used their * 281 | * best efforts in preparing the book. These efforts include the * 282 | * development, research, and testing of the theories and programs * 283 | * to determine their effectiveness. The authors and publisher make * 284 | * no warranty of any kind, expressed or implied, with regard to these * 285 | * programs or to the documentation contained in these books. The authors * 286 | * and publisher shall not be liable in any event for incidental or * 287 | * consequential damages in connection with, or arising out of, the * 288 | * furnishing, performance, or use of these programs. * 289 | *************************************************************************/ 290 | -------------------------------------------------------------------------------- /openai/resources/outputs/ForLoopAnimation.java: -------------------------------------------------------------------------------- 1 | import javafx.animation.KeyFrame; 2 | import javafx.animation.PauseTransition; 3 | import javafx.animation.SequentialTransition; 4 | import javafx.animation.Timeline; 5 | import javafx.application.Application; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Button; 8 | import javafx.scene.control.Label; 9 | import javafx.scene.layout.Pane; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.shape.Rectangle; 12 | import javafx.stage.Stage; 13 | import javafx.util.Duration; 14 | 15 | public class ForLoopAnimation extends Application { 16 | private int counter; 17 | private Label counterValueLabel; 18 | private Label explanationLabel; 19 | private Label outputLabel; 20 | private SequentialTransition animationSequence; 21 | private Rectangle highlightRect; 22 | 23 | @Override 24 | public void start(Stage primaryStage) { 25 | Pane root = new Pane(); 26 | 27 | // Set up labels and buttons 28 | Label loopTextLabel = new Label("for (int counter = 1; counter <= 3; ++counter) {\n System.out.printf(\"%d \" , counter);\n}"); 29 | loopTextLabel.setFont(javafx.scene.text.Font.font("Courier New", 36)); 30 | loopTextLabel.setLayoutX(50); 31 | loopTextLabel.setLayoutY(50); 32 | loopTextLabel.setPrefWidth(1200); 33 | loopTextLabel.setPrefHeight(200); 34 | 35 | counterValueLabel = new Label("counter = 1"); 36 | counterValueLabel.setLayoutX(50); 37 | counterValueLabel.setLayoutY(400); 38 | 39 | explanationLabel = new Label("Initializing control variable counter to 1"); 40 | explanationLabel.setLayoutX(50); 41 | explanationLabel.setLayoutY(500); 42 | 43 | outputLabel = new Label("Output: "); 44 | outputLabel.setLayoutX(50); 45 | outputLabel.setLayoutY(600); 46 | 47 | Button playPauseButton = new Button("Play/Pause"); 48 | playPauseButton.setLayoutX(300); 49 | playPauseButton.setLayoutY(1000); 50 | 51 | // Create transparent highlight rectangle 52 | highlightRect = new Rectangle(); 53 | highlightRect.setFill(Color.TRANSPARENT); 54 | highlightRect.setStroke(Color.RED); 55 | highlightRect.setStrokeWidth(2); 56 | highlightRect.setOpacity(0.6); 57 | 58 | root.getChildren().addAll(loopTextLabel, counterValueLabel, explanationLabel, outputLabel, highlightRect, playPauseButton); 59 | 60 | Scene scene = new Scene(root, 1600, 1200); 61 | primaryStage.setScene(scene); 62 | primaryStage.setTitle("JavaFX Animation - For Loop Explanation"); 63 | primaryStage.show(); 64 | 65 | setupAnimation(loopTextLabel); 66 | playPauseButton.setOnAction(e -> { 67 | if (animationSequence.getStatus() == javafx.animation.Animation.Status.RUNNING) { 68 | animationSequence.pause(); 69 | } else { 70 | animationSequence.play(); 71 | } 72 | }); 73 | } 74 | 75 | private void setupAnimation(Label loopTextLabel) { 76 | animationSequence = new SequentialTransition(); 77 | double baseX = loopTextLabel.getLayoutX(); 78 | double baseY = loopTextLabel.getLayoutY(); 79 | double lineHeight = 40; // Adjust based on font size and spacing 80 | double charWidth = 20; // Adjust based on font size and fixed-width font 81 | 82 | // Step 1: Highlight "int counter = 1" 83 | PauseTransition highlightInit = new PauseTransition(Duration.seconds(2)); 84 | highlightInit.setOnFinished(e -> { 85 | highlightRect.setLayoutX(baseX); 86 | highlightRect.setLayoutY(baseY); 87 | highlightRect.setWidth(11 * charWidth); // "int counter = 1" 88 | highlightRect.setHeight(lineHeight); 89 | explanationLabel.setText("Initializing control variable counter to 1"); 90 | counterValueLabel.setText("counter = 1"); 91 | counter = 1; 92 | }); 93 | animationSequence.getChildren().add(highlightInit); 94 | 95 | // Step 2: Highlight "counter <= 3" 96 | PauseTransition highlightCondition = new PauseTransition(Duration.seconds(2)); 97 | highlightCondition.setOnFinished(e -> { 98 | highlightRect.setLayoutX(baseX + 14 * charWidth); 99 | highlightRect.setLayoutY(baseY); 100 | highlightRect.setWidth(11 * charWidth); // "counter <= 3" 101 | highlightRect.setHeight(lineHeight); 102 | explanationLabel.setText("Checking if counter (" + counter + ") <= 3: " + (counter <= 3 ? "true" : "false")); 103 | }); 104 | animationSequence.getChildren().add(highlightCondition); 105 | 106 | // Step 3: Highlight body "System.out.println("%d", counter);" 107 | PauseTransition highlightBody = new PauseTransition(Duration.seconds(2)); 108 | highlightBody.setOnFinished(e -> { 109 | highlightRect.setLayoutX(baseX); 110 | highlightRect.setLayoutY(baseY + lineHeight); 111 | highlightRect.setWidth(38 * charWidth); // "System.out.println("%d", counter);" 112 | highlightRect.setHeight(lineHeight); 113 | explanationLabel.setText("Executing body: printing counter = " + counter); 114 | outputLabel.setText(outputLabel.getText() + counter + " "); 115 | }); 116 | animationSequence.getChildren().add(highlightBody); 117 | 118 | // Step 4: Highlight "++counter" 119 | PauseTransition highlightIncrement = new PauseTransition(Duration.seconds(2)); 120 | highlightIncrement.setOnFinished(e -> { 121 | highlightRect.setLayoutX(baseX + 28 * charWidth); 122 | highlightRect.setLayoutY(baseY); 123 | highlightRect.setWidth(8 * charWidth); // "++counter" 124 | highlightRect.setHeight(lineHeight); 125 | counter++; 126 | explanationLabel.setText("Incrementing counter to " + counter); 127 | counterValueLabel.setText("counter = " + counter); 128 | }); 129 | animationSequence.getChildren().add(highlightIncrement); 130 | 131 | // Repeat Steps 2-4 until the condition becomes false 132 | Timeline loopTimeline = new Timeline( 133 | new KeyFrame(Duration.seconds(2), e -> { 134 | // Highlight condition 135 | highlightRect.setLayoutX(baseX + 14 * charWidth); 136 | highlightRect.setLayoutY(baseY); 137 | highlightRect.setWidth(11 * charWidth); // "counter <= 3" 138 | highlightRect.setHeight(lineHeight); 139 | if (counter <= 3) { 140 | explanationLabel.setText("Checking if counter (" + counter + ") <= 3: true"); 141 | } else { 142 | explanationLabel.setText("Checking if counter (" + counter + ") <= 3: false. Loop terminates."); 143 | } 144 | }), 145 | new KeyFrame(Duration.seconds(4), e -> { 146 | if (counter <= 3) { 147 | // Highlight body 148 | highlightRect.setLayoutX(baseX); 149 | highlightRect.setLayoutY(baseY + lineHeight); 150 | highlightRect.setWidth(38 * charWidth); // "System.out.println("%d", counter);" 151 | highlightRect.setHeight(lineHeight); 152 | explanationLabel.setText("Executing body: printing counter = " + counter); 153 | outputLabel.setText(outputLabel.getText() + counter + " "); 154 | } 155 | }), 156 | new KeyFrame(Duration.seconds(6), e -> { 157 | if (counter <= 3) { 158 | // Highlight increment 159 | highlightRect.setLayoutX(baseX + 28 * charWidth); 160 | highlightRect.setLayoutY(baseY); 161 | highlightRect.setWidth(8 * charWidth); // "++counter" 162 | highlightRect.setHeight(lineHeight); 163 | counter++; 164 | explanationLabel.setText("Incrementing counter to " + counter); 165 | counterValueLabel.setText("counter = " + counter); 166 | } 167 | }) 168 | ); 169 | loopTimeline.setCycleCount(3); 170 | animationSequence.getChildren().add(loopTimeline); 171 | } 172 | 173 | public static void main(String[] args) { 174 | launch(args); 175 | } 176 | } 177 | 178 | /************************************************************************** 179 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 180 | * Pearson Education, Inc. All Rights Reserved. * 181 | * * 182 | * DISCLAIMER: The authors and publisher of this book have used their * 183 | * best efforts in preparing the book. These efforts include the * 184 | * development, research, and testing of the theories and programs * 185 | * to determine their effectiveness. The authors and publisher make * 186 | * no warranty of any kind, expressed or implied, with regard to these * 187 | * programs or to the documentation contained in these books. The authors * 188 | * and publisher shall not be liable in any event for incidental or * 189 | * consequential damages in connection with, or arising out of, the * 190 | * furnishing, performance, or use of these programs. * 191 | *************************************************************************/ 192 | -------------------------------------------------------------------------------- /openai/resources/outputs/HavaneseAnime.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/HavaneseAnime.webp -------------------------------------------------------------------------------- /openai/resources/outputs/HavaneseDaVinci.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/HavaneseDaVinci.webp -------------------------------------------------------------------------------- /openai/resources/outputs/HavaneseVanGogh.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/HavaneseVanGogh.webp -------------------------------------------------------------------------------- /openai/resources/outputs/RollDie.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.ThreadLocalRandom; 2 | import java.util.concurrent.atomic.LongAdder; 3 | import java.util.stream.IntStream; 4 | 5 | public class RollDie { 6 | 7 | private static final int NUM_ROLLS = 600_000_000; 8 | private static final int NUM_SIDES = 6; 9 | 10 | public static void main(String[] args) { 11 | 12 | // Use LongAdder for efficient counting in a concurrent environment 13 | LongAdder[] frequencies = new LongAdder[NUM_SIDES]; 14 | for (int i = 0; i < NUM_SIDES; i++) { 15 | frequencies[i] = new LongAdder(); 16 | } 17 | 18 | // Parallelizing the workload 19 | IntStream.range(0, NUM_ROLLS).parallel().forEach(i -> { 20 | int face = ThreadLocalRandom.current().nextInt(1, NUM_SIDES + 1); 21 | frequencies[face - 1].increment(); 22 | }); 23 | 24 | // Display the result 25 | System.out.printf("%-5s %-10s%n", "Face", "Frequency"); 26 | for (int i = 0; i < NUM_SIDES; i++) { 27 | System.out.printf("%-5d %-10d%n", i + 1, frequencies[i].longValue()); 28 | } 29 | } 30 | } 31 | 32 | /************************************************************************** 33 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 34 | * Pearson Education, Inc. All Rights Reserved. * 35 | * * 36 | * DISCLAIMER: The authors and publisher of this book have used their * 37 | * best efforts in preparing the book. These efforts include the * 38 | * development, research, and testing of the theories and programs * 39 | * to determine their effectiveness. The authors and publisher make * 40 | * no warranty of any kind, expressed or implied, with regard to these * 41 | * programs or to the documentation contained in these books. The authors * 42 | * and publisher shall not be liable in any event for incidental or * 43 | * consequential damages in connection with, or arising out of, the * 44 | * furnishing, performance, or use of these programs. * 45 | *************************************************************************/ 46 | -------------------------------------------------------------------------------- /openai/resources/outputs/SpotOnGame.java: -------------------------------------------------------------------------------- 1 | import javafx.animation.*; 2 | import javafx.application.Application; 3 | import javafx.scene.Scene; 4 | import javafx.scene.control.Alert; 5 | import javafx.scene.image.Image; 6 | import javafx.scene.layout.Pane; 7 | import javafx.scene.paint.Color; 8 | import javafx.scene.paint.ImagePattern; 9 | import javafx.scene.shape.Circle; 10 | import javafx.stage.Stage; 11 | import javafx.util.Duration; 12 | 13 | import java.util.Random; 14 | 15 | public class SpotOnGame extends Application { 16 | 17 | private static final int INITIAL_LIVES = 3; 18 | private static final int MAX_LIVES = 7; 19 | private static final int SPOT_RADIUS = 50; 20 | private static final double MIN_SPOT_SCALE = 0.25; 21 | 22 | private Pane gamePane; 23 | private int lives = INITIAL_LIVES; 24 | private int level = 1; 25 | private int score = 0; 26 | private int spotsClicked = 0; 27 | 28 | private javafx.scene.media.AudioClip hitSound; 29 | private javafx.scene.media.AudioClip missSound; 30 | private javafx.scene.media.AudioClip disappearSound; 31 | 32 | private Random random = new Random(); 33 | 34 | public static void main(String[] args) { 35 | launch(args); 36 | } 37 | 38 | @Override 39 | public void start(Stage primaryStage) { 40 | preloadSounds(); 41 | gamePane = new Pane(); 42 | gamePane.setPrefSize(800, 600); 43 | gamePane.setStyle("-fx-background-color: white;"); 44 | gamePane.setOnMouseClicked(event -> handleMiss()); 45 | 46 | Scene scene = new Scene(gamePane); 47 | primaryStage.setTitle("SpotOn Game"); 48 | primaryStage.setScene(scene); 49 | primaryStage.show(); 50 | 51 | createInitialSpots(); 52 | } 53 | 54 | private void preloadSounds() { 55 | hitSound = new javafx.scene.media.AudioClip(java.nio.file.Path.of(System.getProperty("user.home"), "Documents/examples/ch19/resources/SpotOn/sounds/hit.mp3").toUri().toString()); 56 | missSound = new javafx.scene.media.AudioClip(java.nio.file.Path.of(System.getProperty("user.home"), "Documents/examples/ch19/resources/SpotOn/sounds/miss.mp3").toUri().toString()); 57 | disappearSound = new javafx.scene.media.AudioClip(java.nio.file.Path.of(System.getProperty("user.home"), "Documents/examples/ch19/resources/SpotOn/sounds/disappear.mp3").toUri().toString()); 58 | } 59 | 60 | private void createInitialSpots() { 61 | Timeline timeline = new Timeline(new KeyFrame(Duration.millis(500), event -> createSpot())); 62 | timeline.setCycleCount(5); 63 | timeline.play(); 64 | } 65 | 66 | private void createSpot() { 67 | Spot spot = new Spot(); 68 | spot.setOnMouseClicked(event -> handleSpotClick(spot)); 69 | gamePane.getChildren().add(spot); 70 | spot.animate(); 71 | } 72 | 73 | private void handleSpotClick(Spot spot) { 74 | gamePane.getChildren().remove(spot); 75 | score += 10 * level; 76 | spotsClicked++; 77 | 78 | hitSound.play(); 79 | 80 | if (spotsClicked == 10) { 81 | level++; 82 | spotsClicked = 0; 83 | if (lives < MAX_LIVES) { 84 | lives++; 85 | } 86 | } 87 | 88 | createSpot(); 89 | } 90 | 91 | private void handleMiss() { 92 | score -= 15 * level; 93 | missSound.play(); 94 | } 95 | 96 | private void loseLife() { 97 | lives--; 98 | disappearSound.play(); 99 | if (lives <= 0) { 100 | endGame(); 101 | } 102 | } 103 | 104 | private void endGame() { 105 | javafx.scene.text.Text gameOverText = new javafx.scene.text.Text("GAME OVER"); 106 | gameOverText.setFill(javafx.scene.paint.Color.RED); 107 | gameOverText.setStyle("-fx-font-size: 48px; -fx-font-weight: bold;"); 108 | gameOverText.setX(gamePane.getWidth() / 2 - 150); 109 | gameOverText.setY(gamePane.getHeight() / 2); 110 | gamePane.getChildren().add(gameOverText); 111 | 112 | gamePane.setOnMouseClicked(event -> System.exit(0)); 113 | } 114 | 115 | private class Spot extends Circle { 116 | private ParallelTransition animation; 117 | 118 | public Spot() { 119 | super(SPOT_RADIUS); 120 | setRandomPosition(); 121 | setFill(new ImagePattern(new Image(random.nextBoolean() ? java.nio.file.Path.of(System.getProperty("user.home"), "Documents/examples/ch19/resources/SpotOn/images/orange_spot.png").toUri().toString() : java.nio.file.Path.of(System.getProperty("user.home"), "Documents/examples/ch19/resources/SpotOn/images/blue_spot.png").toUri().toString()))); 122 | 123 | PathTransition pathTransition = createPathTransition(); 124 | ScaleTransition scaleTransition = createScaleTransition(); 125 | animation = new ParallelTransition(this, pathTransition, scaleTransition); 126 | animation.setOnFinished(event -> handleSpotMiss()); 127 | } 128 | 129 | public void animate() { 130 | animation.play(); 131 | } 132 | 133 | private void setRandomPosition() { 134 | double x = random.nextDouble() * (gamePane.getWidth() - SPOT_RADIUS * 2) + SPOT_RADIUS; 135 | double y = random.nextDouble() * (gamePane.getHeight() - SPOT_RADIUS * 2) + SPOT_RADIUS; 136 | setCenterX(x); 137 | setCenterY(y); 138 | } 139 | 140 | private PathTransition createPathTransition() { 141 | double endX = random.nextDouble() * (gamePane.getWidth() - SPOT_RADIUS * 2) + SPOT_RADIUS; 142 | double endY = random.nextDouble() * (gamePane.getHeight() - SPOT_RADIUS * 2) + SPOT_RADIUS; 143 | 144 | PathTransition pathTransition = new PathTransition(Duration.seconds(3 - level * 0.2), this); 145 | pathTransition.setInterpolator(Interpolator.LINEAR); 146 | var path = new javafx.scene.shape.Path(); 147 | path.getElements().add(new javafx.scene.shape.MoveTo(getCenterX(), getCenterY())); 148 | path.getElements().add(new javafx.scene.shape.LineTo(endX, endY)); 149 | pathTransition.setPath(path); 150 | return pathTransition; 151 | } 152 | 153 | private ScaleTransition createScaleTransition() { 154 | ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(3 - level * 0.2), this); 155 | scaleTransition.setToX(MIN_SPOT_SCALE); 156 | scaleTransition.setToY(MIN_SPOT_SCALE); 157 | 158 | return scaleTransition; 159 | } 160 | 161 | private void handleSpotMiss() { 162 | gamePane.getChildren().remove(this); 163 | loseLife(); 164 | createSpot(); 165 | } 166 | } 167 | } 168 | 169 | 170 | /************************************************************************** 171 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 172 | * Pearson Education, Inc. All Rights Reserved. * 173 | * * 174 | * DISCLAIMER: The authors and publisher of this book have used their * 175 | * best efforts in preparing the book. These efforts include the * 176 | * development, research, and testing of the theories and programs * 177 | * to determine their effectiveness. The authors and publisher make * 178 | * no warranty of any kind, expressed or implied, with regard to these * 179 | * programs or to the documentation contained in these books. The authors * 180 | * and publisher shall not be liable in any event for incidental or * 181 | * consequential damages in connection with, or arising out of, the * 182 | * furnishing, performance, or use of these programs. * 183 | *************************************************************************/ 184 | -------------------------------------------------------------------------------- /openai/resources/outputs/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/Thumbs.db -------------------------------------------------------------------------------- /openai/resources/outputs/UMLActivityDiagramForLoop.java: -------------------------------------------------------------------------------- 1 | import javafx.application.Application; 2 | import javafx.scene.Scene; 3 | import javafx.scene.layout.Pane; 4 | import javafx.scene.paint.Color; 5 | import javafx.scene.shape.*; 6 | import javafx.scene.text.Text; 7 | import javafx.stage.Stage; 8 | 9 | public class UMLActivityDiagramForLoop extends Application { 10 | @Override 11 | public void start(Stage primaryStage) { 12 | Pane pane = new Pane(); 13 | 14 | // Initial Node - Start 15 | Circle startCircle = new Circle(50, 50, 10); 16 | startCircle.setFill(Color.BLACK); 17 | pane.getChildren().add(startCircle); 18 | 19 | // Initialize control variable node 20 | Rectangle initializeRect = new Rectangle(100, 30); 21 | initializeRect.setX(80); 22 | initializeRect.setY(30); 23 | initializeRect.setArcWidth(20); 24 | initializeRect.setArcHeight(20); 25 | initializeRect.setFill(Color.LIGHTBLUE); 26 | Text initializeText = new Text(90, 50, "Initialize\ncontrol variable\nint count = 1"); 27 | pane.getChildren().addAll(initializeRect, initializeText); 28 | 29 | // Decision diamond - Loop condition 30 | Polygon decisionDiamond = new Polygon(); 31 | decisionDiamond.getPoints().addAll(200.0, 60.0, 220.0, 90.0, 200.0, 120.0, 180.0, 90.0); 32 | decisionDiamond.setFill(Color.WHITE); 33 | decisionDiamond.setStroke(Color.BLACK); 34 | Text decisionText = new Text(170, 95, "count <= 3"); 35 | pane.getChildren().addAll(decisionDiamond, decisionText); 36 | 37 | // Display control value node 38 | Rectangle displayRect = new Rectangle(100, 30); 39 | displayRect.setX(260); 40 | displayRect.setY(70); 41 | displayRect.setArcWidth(20); 42 | displayRect.setArcHeight(20); 43 | displayRect.setFill(Color.LIGHTBLUE); 44 | Text displayText = new Text(270, 90, "Display\ncounter value\nSystem.out.printf"); 45 | pane.getChildren().addAll(displayRect, displayText); 46 | 47 | // Increment control variable node 48 | Rectangle incrementRect = new Rectangle(100, 30); 49 | incrementRect.setX(260); 50 | incrementRect.setY(150); 51 | incrementRect.setArcWidth(20); 52 | incrementRect.setArcHeight(20); 53 | incrementRect.setFill(Color.LIGHTBLUE); 54 | Text incrementText = new Text(270, 170, "Increment\ncontrol variable\n++count"); 55 | pane.getChildren().addAll(incrementRect, incrementText); 56 | 57 | // Final Node - End 58 | Circle endCircle = new Circle(220, 300, 10); 59 | endCircle.setFill(Color.BLACK); 60 | pane.getChildren().add(endCircle); 61 | 62 | // Arrows 63 | Line line1 = new Line(60, 50, 80, 50); // From start to initialize 64 | Line line2 = new Line(180, 90, 200, 90); // From initialize to decision 65 | Line line3 = new Line(220, 90, 260, 90); // From decision to display 66 | Line line4 = new Line(310, 90, 310, 150); // From display to increment 67 | Line line5 = new Line(310, 165, 310, 90); // Loop back from increment to decision 68 | Line line6 = new Line(220, 120, 220, 300); // From decision to end (loop termination) 69 | pane.getChildren().addAll(line1, line2, line3, line4, line5, line6); 70 | 71 | // Set the scene 72 | Scene scene = new Scene(pane, 400, 400); 73 | primaryStage.setTitle("UML Activity Diagram for Loop"); 74 | primaryStage.setScene(scene); 75 | primaryStage.show(); 76 | } 77 | 78 | public static void main(String[] args) { 79 | launch(args); 80 | } 81 | } 82 | 83 | /************************************************************************** 84 | * (C) Copyright 1992-2025 by Deitel & Associates, Inc. and * 85 | * Pearson Education, Inc. All Rights Reserved. * 86 | * * 87 | * DISCLAIMER: The authors and publisher of this book have used their * 88 | * best efforts in preparing the book. These efforts include the * 89 | * development, research, and testing of the theories and programs * 90 | * to determine their effectiveness. The authors and publisher make * 91 | * no warranty of any kind, expressed or implied, with regard to these * 92 | * programs or to the documentation contained in these books. The authors * 93 | * and publisher shall not be liable in any event for incidental or * 94 | * consequential damages in connection with, or arising out of, the * 95 | * furnishing, performance, or use of these programs. * 96 | *************************************************************************/ 97 | -------------------------------------------------------------------------------- /openai/resources/outputs/english_speech.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/english_speech.mp3 -------------------------------------------------------------------------------- /openai/resources/outputs/japanese_speech.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/japanese_speech.mp3 -------------------------------------------------------------------------------- /openai/resources/outputs/spanish_speech.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/outputs/spanish_speech.mp3 -------------------------------------------------------------------------------- /openai/resources/sora/DogsWithMistakes.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/sora/DogsWithMistakes.mp4 -------------------------------------------------------------------------------- /openai/resources/sora/HavanesePuppy.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/sora/HavanesePuppy.mp4 -------------------------------------------------------------------------------- /openai/resources/sora/YawningDog.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdeitel/PythonDataScienceFullThrottle/3f4874c78d9f8ccba3a999eee7c34a3998eb3ed9/openai/resources/sora/YawningDog.mp4 -------------------------------------------------------------------------------- /openai/resources/transcript.txt: -------------------------------------------------------------------------------- 1 | Welcome to the What's New in Java lesson. In this lesson I have about two and a half hours of new video with new examples that will be appearing in our forthcoming new editions of our Java suite of products, and that includes the new edition of this video course, Java Fundamentals third edition. Java had a program 12th Edition, our Java textbook, and Java for programmers 5th Edition, our corresponding professional book as well. Throughout these videos, I'll be presenting various key Java programming features from Java 10 through Java 22, and I'll have a slide on one Java 23 feature as well that's related to some of the other examples that I'll be presenting to you here. These videos in the What's New Lesson are targeted to existing lessons in the current product where the features in question could potentially be used. That does not necessarily reflect where they'll appear in the new suite of products, but it's a relatively good guess as to where they'll appear. And as we produce the new versions of these videos, we will post the new lessons online and eventually this lesson will go away as we meld the new features into the new presentation as well. So the various features are labeled with which Java versions they were introduced in. That may be important to you as a developer because you may be required to use a specific version of the Java platform. For example, the current long-term support release is Java 21. Therefore, if you're using Java 21, you won't be able to take advantage of Java 22 features. And some people are still on previous versions of Java as well, such as the long-term support release Java 17, the long-term support release Java 11, or even going all the way back to Java eight as well. So obviously if you are in one of those earlier versions for a project that you're working on, you will not be able to take advantage of some of the later features. As you work your way through this lesson, if you have any questions on these new features, feel free to reach out to me at paul@deitel.com and I'll try to respond to you promptly. You can also check out our deitel.com website for updates on what's going on, and we'll post messages into our various social media channels as well as new content becomes available. Here's the proposed outline for the third edition of this video course. We will be starting with the fundamentals in lessons one through eight. We'll begin by demonstrating how to test drive a Java application. Actually, we'll do that several different ways. Then we'll get into the actual Java programming in lesson two. And in lessons three and four, we'll focus on most but not all of Java's control statements. There are a couple that make sense to cover in later lessons. Next up, we'll take a look at method definitions in Java. Then we'll start getting into data structures with the built-in array data structure and the array list collection class, which is one of many different collections that come built into the Java APIs. And as part of this new version of lesson six, we'll be introducing some functional programming concepts in Java as well, with the Lambda and streams capabilities that were introduced in Java eight. We'll move on to some string character and regular expression processing and we'll finish off the fundamentals section with some files and IO streams capabilities. And as part of that lesson, we'll also get into comma separated value files, which is a popular format for representing data sets nowadays. And also JavaScript object notation, which is the most popular format used to transmit data back and forth over the internet when you have applications that are talking to what are known as web services, which are basically functions that you call on servers around the internet to perform tasks for you and possibly give you back results as well. Next up, we'll move into the object oriented programming portion of the course with custom classes and objects, and we'll then talk about how to create new classes from existing ones via inheritance and the capability of polymorphism, which allows us to process a bunch of objects of related classes as if they're all objects of the superclass in a hierarchy. We will talk more in the next lesson about interfaces, specifically showing you how to create your own custom interfaces and also working with some of the Java APIs interface capabilities as well. And those interface capabilities are critical in hierarchy design nowadays, but they're also critical in all sorts of different areas of Java application development. So it's critical that everyone be familiar with the concepts of interfaces and how to use them as well. We'll finish up the object oriented programming portion with a deeper look at exception handling, which we'll actually introduce initially back in lesson six and we'll use a little bit as well in some of the earlier object oriented programming chapters. Next up, we'll move on to generic programming. We'll take a look at several different generic collections of which array lists are one. The generic collections allow you to specify when you create objects of those collections, the type of elements that they'll store. And we'll also take a look at how to create your own custom generic classes and methods as well. Next up we have a segment on Java FX, graphical user Interfaces, graphics and multimedia, three lesson run on that. Java FX is the modern Java graphical user interface set of capabilities that also includes graphics and multimedia capabilities. It's highly customizable, which is one of the benefits of using it. And so we'll take a look at a number of examples using those capabilities. Unfortunately, Java FX is not built into the Java development kit. So as part of our new and updated before you begin lesson, we'll talk about how to get the Java FX capabilities installed so that you can take advantage of them as part of your Java development. And then finally, we have a number of high-end topics, including a deeper look at functional programming in Java with Lambdas and streams. You'll notice that there's the word streams here, but we also have the word streams back in lesson eight. Those are two different concepts. In the case of lesson eight, it's the concepts of bites or characters being written out of a program or read into a program. In the case of functional programming, the concept of a stream is simply the idea of elements moving their way through a pipeline of operations. And that's just a an entirely different concept. We will have a brand new lesson on generative AI, which of course is super hot right now. We'll show you how to actually programmatically interact with generative Ais in the Java programming language, and we'll actually incorporate a number of concepts from generative AI throughout many of the lessons in the new edition as well. We have an extensive lesson on concurrency and multi-core performance, and this is one of the areas in which there are a bunch of new capabilities. We'll actually have a whole separate new lesson that we will publish before the full new version of the Java Fundamentals course of the concurrency lesson, excuse me, in which we'll introduce those new features so people can start using them right away. We'll have a databases lesson for interacting with databases via JDBC and then back in Java 9 they introduced the Java platform module system, which has had a few changes along the way since then. So we'll be updating that as well. And finally we'll finish off with a lesson on using Java's JShell tool for interactive Java development at the command line. And that's kind of handy not only for learning but also for testing purposes. You can, for example, load up a library into JShell and work with it in a snippet oriented way without having to create full blown applications to test out various features. So it can be quite handy for developers to play around, if you will. As for the new features that you'll see in this lesson, we've broken that down here in a series of slides by the lesson number that the features will be associated with initially based on the current product outline, not the one I just showed you on the previous slide. So for lesson one where we show you how to test drive a Java application, in this lesson, we will show you a new feature that was introduced in Java 11 for executing source files directly via the Java command. And they recently enhanced that feature to support not just single source file programs, but also multiple source file programs. So what's interesting is that the Java command is actually able to read a Java source code file and compile it in memory now and then execute the code directly from memory without ever storing a dot class file on disc. In lesson two's new features, we're going to be taking a look at a new simplified version of the main method that is used to launch a Java application. It's called an instance main method, and there are actually two different ways we can take advantage of this simple new version both inside of an actual named class definition like we've traditionally done in Java since inception, but also we can just define the main method in a file now with no class wrapped around it. And so we'll show you both versions of that. And interestingly, in the version that has no class wrapped around it, it creates an implicitly declared class to wrap around that main method for you. And you can also define other methods in that file as well. So this is about as close as we can get to creating a C programming language style program in the Java programming language. We also have a new feature for multi-line strings called text blocks that we'll take a look at. Those are particularly useful for folks who need to embed large blocks of text into Java source code, things like JavaScript object notation documents for communicating with web services or HTML documents if you're building a web application or maybe SQL queries if you're interacting with databases, for example. As for the features related to lesson four on the first control statements lesson, we have a new feature called string templates. And the reason I associated this with lesson four is this is the lesson where we first do not only formatted output, but specifically a little bit of floating point number formatting as well. With string templates, we have a new feature that allows you to plug values directly into placeholders within a string, literal or a text block as well. So we'll introduce what are known as template processors that can either simply plug something in or apply formatting as well. There's two different template processors that we'll demonstrate there. For lesson five, we'll take a look at a feature that was introduced in Java 14 called Switch Expressions. It's a new, more compact way to represent the concept of a switch statement, but it's also more powerful. As you'll see over a a series of examples in this what's New lesson, there's actually some pattern matching capabilities that have been added to the Java programming language and those pattern matching capabilities make the switch concept much more powerful now than it used to be in Java. From the inception of Java, we were able to create switches that supported integer constants and enumerated constants and strings as well, which was added a little bit later. But now with the various pattern matching capabilities that they've been adding in versions of Java after version 14, we actually have the capability now to test any kind of object in a switch controlling expression with these new switch expressions and test that against the various cases. Also, cases are no longer restricted to just a single constant value. You can actually have comma delimited lists of values in cases as well. So we'll build up the set of switch capabilities over several examples throughout this What's New lesson. With regard to lesson six on methods, we have a couple of new features that we'll introduce here. The methods lesson is where we introduce random number generation in our book and videos. And what we've done for this part of the demonstration is we've actually reimplemented one of the examples from lesson six. It simulates a die rolling game from casinos around the world. And as part of that, we're actually going to demonstrate two different new features. From Java 16, we have a concept called records. Some languages refer to these as data classes. They are classes, special classes that enable you to house data and access that data. And objects of these classes are immutable, so they're meant specifically for the purpose of grouping together a bunch of data items into an object and making those data items conveniently accessible. And one of the new features associated with records that came later is the ability to use records in the context of those switch expressions that I was talking about in the previous slide. So we'll talk more about records in later examples as well, but we'll use a record class to represent a pair of randomly rolled dice. And for the random number generation, we'll use a feature from Java 17, which is from their enhanced Pseudo-Random number generators. There's a new class called random generator that can give you a default Pseudo-Random number generator, but it also supports a total of 13 random number generation algorithms that you can choose from as well. So we'll give you a reference to the doc page where you can learn more about those algorithms. When we do talk about records, we're gonna see that records auto generate certain kind of boilerplate code that you need to be able to initialize an object to be able to get the values out of an object. They'll create an automated string representation for an object and some other methods as well that we'll talk about in later examples. For lesson seven on arrays and array lists, we have a Java 10 feature that we'll talk about called local variable type inference, which is basically where when you declare a local variable and immediately initialize it inside the body of a method, you can let the compiler figure out the variables data type from its initializer. So whatever's on the right side of the equal sign, the compiler knows what that is and can use that to help declare the variable for you. And that's a new keyword called var V-A-R, which is short for variable that will let the compiler do that work for you. With respect to lesson eight, we'll go back and talk more about the concepts of records. One of the interesting features of records is the ability to create a short form of constructor where all you specify is your validation code. And if the data items that you pass into the constructor for a record are all valid, it will automatically handle the assignment of the arguments to the constructor into the instance variables for the record object, which is kind of a cool little feature. So we'll demonstrate that and we'll talk more about all the different capabilities that are auto generated for you as part of record classes. We'll also take a look at features from Java 21, the pattern matching capabilities for switch were introduced here. And along with those are something called record patterns. So we're going to talk a lot about records in this lesson. And when we look at these features, we're going to see that this pattern matching switch expression is able to look at the type of objects and if they are record objects, we can also automatically decompose them into individual variables from the record data types. So for convenient access to the data members or the instance variables I should say, we have these things called record patterns. They work well with switch expressions, but they can also be used with what is known as the pattern matching instance of operator also. Java 22 introduced something called unnamed variables and patterns. And this is for scenarios where, for example, a variable name may be required, but you don't need to use the variable in your code. They give a new feature, which is the underscore character that can be used to specify a placeholder for a variable name that is not used in the code. So for example, if you're doing a try-catch statement and your catch handler for an exception doesn't need to interact with the exception object, you can specify instead of a variable name, the underscore character, and that's an unnamed variable to allow the syntax to work correctly for that statement. You can also use those in records if, for example, you were decomposing a record object that had lots of fields in it, but you only needed to use certain fields in a switch expression, you can use unnamed variables to indicate the other fields that you don't intend to take advantage of. With respect to chapter nine, we have an interesting new preview feature called Statements Before Super. With respect to constructors, since the inception of Java, it has always been the case that when a constructor for a subclass type gets called, the very first thing it must do in its body is either call another constructor in the same class, which in turn usually would have to call the superclass constructor, or the subclass constructor must immediately invoke the super classes constructor. And that means that you may wind up doing some additional work that is unnecessary because when you get back to the subclass constructor, which is where you would do validation of additional arguments that are specific to the subclass, if there's an invalid argument, generally you would throw an exception at that point. And that means that all the work you've done previously in Superclass constructors was unnecessary in the first place. So they're previewing a feature that allows us to put validation code in a subclass constructor before we write the call to super or in the case where you're calling another constructor of the same class to do some shared code before the call to this. And by doing that, we can help improve a little bit the performance of our initialization in cases where exceptions are going to get thrown because of invalid data. For features related to lesson 10 on object-oriented programming polymorphism and interfaces, we have something called the pattern matching version of the instance of operator. So as part of this example, we'll actually do a re-architecting of the employee hierarchy that's currently presented in that polymorphism lesson in these live lessons videos. And we'll talk a little bit, as part of that example about programming to an interface rather than doing implementation inheritance. So first we'll take a look at a new hierarchy, and then we'll use that new hierarchy with this new version of the instance of operator. And we'll also edit that hierarchy, or I should say modify that hierarchy with a new feature called sealed classes, which is really sealed classes and interfaces. And what these sealed classes and interfaces enable you to do as a hierarchy designer is gain complete control over your hierarchy. Because when you define a sealed super class, part of defining it is to actually name the explicit subclasses that are allowed. And when you define a sealed interface, part of defining it is to define a list of explicit classes that are allowed to implement that interface. So you basically have a closed set of types that you're creating with a sealed superclass or a sealed interface, and that gives you complete control over those types. And there are no surprises in applications that use sealed hierarchies where another programmer could come along and extend your hierarchy with an unknown type that could cause problems in your application because that simply is not allowed when you're using sealed hierarchies. And then finally, to finish off this what's New lesson, we're going to jump to the generic collections feature called Sequenced Collections. Interestingly, it turns out that there's a bunch of types of collections in Java that can be indexed by position number. Those are sequenced collections. And also, interestingly, although they all support things like being able to add an element at the beginning or end of the collection and remove an element from the beginning or end of a collection or get the element from the beginning or end of a collection, they use different method names across the different collection classes. So they've added some new interfaces to Java 21 that unify the method naming across those different collection classes, thus making those collections easier to use and learn for people new to the language because they're now going to be more consistent with one another. And also, as part of the sequenced collection capabilities, they've added a new method to these interfaces called Reversed, which allows you to iterate backwards through those collections as well. Just as a reminder, if you have any questions as you work your way through these videos, you can once again reach out to me at paul@deitel.com and on all of these sites, we'll be announcing the new content as it becomes available. And you may notice if you've been following along with the Java releases, that there are other concepts that we are not covering in this What's New in Java lesson. For example, there's a bunch of new stuff going on in the areas of concurrency and parallelism. I'm going to have a whole separate new lesson on that set of concepts that I'm already working on right now, and we will post that here as well as soon as it becomes available. -------------------------------------------------------------------------------- /openai/resources/web.txt: -------------------------------------------------------------------------------- 1 | The World Wide Web (simply called "the web") is a collection of hardware and software associated with the Internet that allows computer users to locate and view documents (with various combinations of text, graphics, animations, audios and videos) on almost any subject. In 1989, Tim Berners-Lee of CERN (the European Organization for Nuclear Research) began developing HyperText Markup Language (HTML)—the technology for sharing information via "hyperlinked" text documents. He also wrote communication protocols such as HyperText Transfer Protocol (HTTP) to form the backbone of his new hypertext information system, which he referred to as the World Wide Web. In 1994, Berners-Lee founded the World Wide Web Consortium (W3C, https://www.w3.org), which was devoted to developing web technologies. A key W3C goal is to make the web universally accessible to everyone regardless of disabilities, language or culture. --------------------------------------------------------------------------------