├── .gitignore
├── LICENSE
├── README.md
├── U1-Fundamentals
├── README.md
├── U1.1-Scratch
│ ├── FortuneTellerStateMachineSample.png
│ └── README.md
└── U1.2-Python
│ ├── AllTheFilters
│ ├── README.md
│ ├── part1
│ │ ├── filtergram.py
│ │ └── filters.py
│ ├── part2
│ │ ├── filtergram.py
│ │ └── filters.py
│ ├── part3
│ │ ├── filtergram.py
│ │ └── filters.py
│ └── part4
│ │ ├── brooklyn.jpg
│ │ ├── filtergram.py
│ │ └── filters.py
│ ├── GuessTheNumber
│ ├── README.md
│ └── guess_number.py
│ ├── GuessTheSecretWord
│ ├── README.md
│ └── guess_the_secret_word.py
│ ├── ListChallenge
│ ├── README.md
│ └── list_challenge.py
│ ├── README.md
│ ├── TextAdventure
│ ├── README.md
│ └── text_adventure.py
│ └── chatbot
│ ├── README.md
│ ├── chatbot-pt1.py
│ ├── chatbot-pt2.py
│ ├── chatbot-pt4.py
│ └── chatbot-pt5.py
└── U2-Applications
├── README.md
├── U2.1-Data
├── DataScientist
│ ├── README.md
│ ├── data_science.py
│ ├── school_scores.db
│ └── school_scores.py
├── DataVisualizationProject
│ ├── Readme.md
│ ├── cloud_generator.py
│ ├── data_vis_project_part1.py
│ ├── data_vis_project_part2.py
│ ├── data_vis_project_part3.py
│ └── data_vis_project_part4.py
├── DictionaryAttack
│ ├── README.md
│ ├── dictionary.txt
│ └── dictionary_attack.py
├── README.md
├── SurveyProject
│ ├── README.md
│ ├── allanswers.json
│ ├── surveyproject_pt1.py
│ ├── surveyproject_pt2.py
│ ├── surveyproject_pt3.py
│ └── surveyproject_pt4.py
├── TweetProcessing
│ ├── README.md
│ ├── tweet-scraper.py
│ ├── tweets.json
│ └── tweets_small.json
├── TwitterData
│ ├── README.md
│ └── tweets_small.json
└── TwitterDataCodeAlong
│ ├── Readme.md
│ └── twitter_data_code_along.py
├── U2.2-Web-Development
├── BuildAWebPage
│ ├── README.md
│ ├── contact.html
│ ├── hello.html
│ ├── side-scrolling-screenshot.png
│ └── styles.css
├── JavaScriptAndAccessibility
│ ├── README.md
│ ├── aboutme.html
│ ├── aboutme.js
│ ├── side-scrolling-screenshot.png
│ └── styles.css
├── README.md
└── UseAnAPI
│ ├── README.md
│ ├── index.html
│ ├── map_part0_startercode.html
│ ├── map_part1_setup_API.html
│ ├── map_part2_setup_script.html
│ ├── map_part2_setup_script.js
│ ├── map_part3_animate_view.html
│ ├── map_part3_animate_view.js
│ ├── map_part4_input_a_country.html
│ ├── map_part4_input_a_country.js
│ ├── map_part5_get_country_information.html
│ ├── map_part5_get_country_information.js
│ ├── map_part6_get_the_lon_and_lat.html
│ ├── map_part6_get_the_lon_and_lat.js
│ ├── map_part7_make_call_asynchronous.html
│ └── map_part7_make_call_asynchronous.js
└── U2.3-Robotics
├── BuildACircuit
├── BuildACircuit.ino
└── README.md
├── Circuits
├── README.md
├── input-irreceiver.png
├── input-phototransistor.png
├── input-piezo.png
├── input-pushbutton.png
└── input-whisker.png
├── CodeExamples
├── BooleanOperators
│ └── BooleanOperators.ino
├── Conditionals
│ └── Conditionals.ino
├── README.md
├── analogRead
│ └── analogRead.ino
└── digitalRead
│ └── digitalRead.ino
├── EscapeBot
├── EscapeBot.ino
└── README.md
├── HereKittyKitty
├── HereKittyKitty.ino
└── README.md
├── LetThereBeLight-Pt2
├── LetThereBeLight-Pt2.ino
└── README.md
├── LetThereBeLight-Pt3
├── LetThereBeLight-Pt3.ino
└── README.md
├── README.md
├── RobotDanceParty
├── README.md
└── RobotDanceParty.ino
└── WhiskerCodeAlong
├── README.md
└── WhiskerCodeAlong.ino
/.gitignore:
--------------------------------------------------------------------------------
1 | U1-Fundamentals/U1.2-Python/AllTheFilters/part4/recolored1.jpg
2 | U1-Fundamentals/U1.2-Python/AllTheFilters/part4/recolored2.jpg
3 | U1-Fundamentals/U1.2-Python/AllTheFilters/part4/recolored3.jpg
4 | U1-Fundamentals/U1.2-Python/AllTheFilters/part4/recolored4.jpg
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SIP-2018
2 | Sample solutions for the projects in Girls Who Code's 2018 Summer Immersion Program.
3 |
--------------------------------------------------------------------------------
/U1-Fundamentals/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U1-Fundamentals/README.md
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.1-Scratch/FortuneTellerStateMachineSample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U1-Fundamentals/U1.1-Scratch/FortuneTellerStateMachineSample.png
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.1-Scratch/README.md:
--------------------------------------------------------------------------------
1 | # Unit 1.1: Scratch
2 |
3 | ## Table of Contents
4 |
5 | ### Projects:
6 |
7 | All of the following projects are hosted on Scratch.
8 |
9 | 1. [All About Me](https://scratch.mit.edu/projects/199757118/)
10 | * This project is used in U1L1.
11 | * Students experiment with Scratch and learn how to create sprites and use the broadcast block.
12 | 1. [So You Think You've Got Moves](https://scratch.mit.edu/projects/200128110/)
13 | * This project is used in U1L2.
14 | * Students learn to use loops and variables in Scratch.
15 | 1. [State Machine Example](FortuneTellerStateMachineSample.png)
16 | * This project is used in U1L3.
17 | * Students learn how to make a state machine for a fortune teller.
18 | 1. [State Machine Challenge](https://scratch.mit.edu/projects/202394000/)
19 | * This project is used in U1L3.
20 | * Students learn how to make a state machine in Scratch.
21 | 1. [Choose Your Own Adventure Game](https://scratch.mit.edu/projects/200106180/)
22 | * This project is used in U1L3.
23 | * Students practice making state machines and using conditionals in Scratch.
24 | 1. [Maze Game](https://scratch.mit.edu/projects/201471886/)
25 | * This project is used in U1L4.
26 | * Students practice loops, variables, and conditionals while learning how to use iterative Design-Build-Test.
27 |
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/README.md:
--------------------------------------------------------------------------------
1 | # #AllTheFilters
2 |
3 | To run on Mac:
4 | `$ python3 filtergram.py`
5 |
6 | To run on Windows:
7 | `$ python filtergram.py`
8 |
9 | A sample image ([brooklyn.jpg](brooklyn.jpg)) has been included for testing purposes.
10 |
11 |
12 | ## Contents
13 |
14 | This project is split into the following parts:
15 |
16 | * [Part 1](part1): Setting Up The Basics
17 | * In `filters.py`, students write the `load_img()` and `save_img()` functions.
18 | * In `filtergram.py`, students test out their filters library by loading and saving an image. (The saved image will look identical to the source image, since no filters have been applied yet!)
19 | * [Part 2](part2): Building Your First Filter
20 | * In `filters.py`, students write the `obamicon()` filter.
21 | * In `filtergram.py`, students apply their Obamicon filter to an image.
22 | * [Part 3](part3): Creating Your Own Custom Filter
23 | * In `filters.py`, students write their own custom filter. Actual student filters may vary, based on student interest.
24 | * In `filtergram.py`, students apply their new filter to an image. You can apply multiple filters to the same image!
25 | * [Part 4](part4): Putting It All Together
26 | * Students use the `filters.py` created by the teacher, which consolidates all the custom filters built by the entire class. Actual student filters may vary, based on student interest.
27 | * In `filtergram.py`, students apply a variety of filters to an image.
28 |
29 | Each folder contains the two following files:
30 |
31 | * `filtergram.py`
32 | * This program will create a new image called "recolored.jpg" in the current directory.
33 | * `filters.py`
34 | * This program contains functions defined by students, including wrappers for Pillow functions and custom image filter functions.
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part1/filtergram.py:
--------------------------------------------------------------------------------
1 | import filters
2 |
3 | def main():
4 | # Ask what image the user wants to edit
5 | filename = input("Enter the name of the image file to edit: ")
6 |
7 | # Load the image from the specified file
8 | img = filters.load_img(filename)
9 |
10 | # Save the final image
11 | filters.save_img(img, "recolored.jpg")
12 |
13 | if __name__ == '__main__':
14 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part1/filters.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 |
3 | def load_img(filename):
4 | im = Image.open(filename)
5 | return im
6 |
7 | def show_img(im):
8 | im.show()
9 |
10 | def save_img(im, filename):
11 | im.save(filename, "jpeg")
12 | show_img(im)
13 |
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part2/filtergram.py:
--------------------------------------------------------------------------------
1 | import filters
2 |
3 | def main():
4 | # Ask what image the user wants to edit
5 | filename = input("Enter the name of the image file to edit: ")
6 |
7 | # Load the image from the specified file
8 | img = filters.load_img(filename)
9 |
10 | # Apply filters!
11 | newimg = filters.obamicon(img)
12 |
13 | # Save the final image
14 | filters.save_img(newimg, "recolored.jpg")
15 |
16 | if __name__ == '__main__':
17 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part2/filters.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 |
3 | def load_img(filename):
4 | im = Image.open(filename)
5 | return im
6 |
7 | def show_img(im):
8 | im.show()
9 |
10 | def save_img(im, filename):
11 | im.save(filename, "jpeg")
12 | show_img(im)
13 |
14 | def obamicon(im):
15 | # Load the pixel data from im.
16 | pixels = im.getdata()
17 | # Create a list to hold the new image pixel data.
18 | new_pixels = []
19 |
20 | # Define color constants to use for recoloring.
21 | darkBlue = (0, 51, 76)
22 | red = (217, 26, 33)
23 | lightBlue = (112, 150, 158)
24 | yellow = (252, 227, 166)
25 |
26 | # Process the pixels in the image.
27 | for p in pixels:
28 | # Pixel intensity = R value + G value + B value
29 | intensity = p[0] + p[1] + p[2]
30 |
31 | if intensity < 182:
32 | new_pixels.append(darkBlue)
33 |
34 | elif intensity >= 182 and intensity < 364:
35 | new_pixels.append(red)
36 |
37 | elif intensity >= 364 and intensity < 546:
38 | new_pixels.append(lightBlue)
39 |
40 | elif intensity >=546:
41 | new_pixels.append(yellow)
42 |
43 | # Save the filtered pixels as a new image
44 | newim = Image.new("RGB", im.size)
45 | newim.putdata(new_pixels)
46 | return newim
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part3/filtergram.py:
--------------------------------------------------------------------------------
1 | import filters
2 |
3 | def main():
4 | # Ask what image the user wants to edit
5 | filename = input("Enter the name of the image file to edit: ")
6 |
7 | # Load the image from the specified file
8 | img = filters.load_img(filename)
9 |
10 | # Apply filters!
11 | newimg = filters.obamicon(img)
12 | newimg = filters.grayscale(newimg)
13 |
14 | # Save the final image
15 | filters.save_img(newimg, "recolored.jpg")
16 |
17 | if __name__ == '__main__':
18 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part3/filters.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 |
3 | # Return an Image loaded from the specified file.
4 | def load_img(filename):
5 | im = Image.open(filename)
6 | return im
7 |
8 | # Display Image to the user (for debugging purposes).
9 | def show_img(im):
10 | im.show()
11 |
12 | # Save the Image to a file with the specified filename,
13 | # then show the Image to the user.
14 | def save_img(im, filename):
15 | im.save(filename, "jpeg")
16 | show_img(im)
17 |
18 | # Return a new Image, with Obamicon filter applied.
19 | def obamicon(im):
20 | # Load the pixel data from im.
21 | pixels = im.getdata()
22 | # Create a list to hold the new image pixel data.
23 | new_pixels = []
24 |
25 | # Define color constants to use for recoloring.
26 | darkBlue = (0, 51, 76)
27 | red = (217, 26, 33)
28 | lightBlue = (112, 150, 158)
29 | yellow = (252, 227, 166)
30 |
31 | # Process the pixels in the image.
32 | for p in pixels:
33 | # Pixel intensity = R value + G value + B value
34 | intensity = p[0] + p[1] + p[2]
35 |
36 | if intensity < 182:
37 | new_pixels.append(darkBlue)
38 |
39 | elif intensity >= 182 and intensity < 364:
40 | new_pixels.append(red)
41 |
42 | elif intensity >= 364 and intensity < 546:
43 | new_pixels.append(lightBlue)
44 |
45 | elif intensity >=546:
46 | new_pixels.append(yellow)
47 |
48 | # Save the filtered pixels as a new image
49 | newim = Image.new("RGB", im.size)
50 | newim.putdata(new_pixels)
51 | return newim
52 |
53 | # Return a new Image, with grayscale filter applied.
54 | def grayscale(im):
55 | # Load the pixel data from im.
56 | pixels = im.getdata()
57 | # Create a list to hold the new image pixel data.
58 | new_pixels = []
59 |
60 | # Process the pixels in the image.
61 | for p in pixels:
62 | new_p = avg_pixel(p)
63 | new_pixels.append(new_p)
64 |
65 | # Save the filtered pixels as a new image
66 | newim = Image.new("RGB", im.size)
67 | newim.putdata(new_pixels)
68 | return newim
69 |
70 | # Helper function.
71 | # Return a grayscale tuple for a single pixel value.
72 | def avg_pixel(pixel):
73 | # Use the average of p's RGB values to set a new pixel value.
74 | avg = (pixel[0] + pixel[1] + pixel[2]) // 3 # Use // for int division.
75 | return (avg, avg, avg) # R = G = B will be a gray pixel!
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part4/brooklyn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U1-Fundamentals/U1.2-Python/AllTheFilters/part4/brooklyn.jpg
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part4/filtergram.py:
--------------------------------------------------------------------------------
1 | import filters
2 |
3 | def main():
4 | # Ask what image the user wants to edit
5 | filename = input("Enter the name of the image file to edit: ")
6 |
7 | # Load the image from the specified file
8 | img = filters.load_img(filename)
9 |
10 | # Apply filters!
11 | newimg = filters.obamicon(img)
12 | newimg = filters.grayscale(newimg)
13 |
14 | blue = (30,85,115)
15 | anotherimg = filters.emphasize(img, blue, 50)
16 |
17 | blueimg = filters.add_color(img, blue)
18 |
19 | lastimg = filters.invert(blueimg)
20 |
21 | # Save the final images
22 | filters.save_img(newimg, "recolored1.jpg")
23 | filters.save_img(anotherimg, "recolored2.jpg")
24 | filters.save_img(blueimg, "recolored3.jpg")
25 | filters.save_img(lastimg, "recolored4.jpg")
26 |
27 | if __name__ == '__main__':
28 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/AllTheFilters/part4/filters.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 | import math
3 |
4 | # Return an Image loaded from the specified file.
5 | # * filename: string, name of file to load
6 | def load_img(filename):
7 | im = Image.open(filename)
8 | return im
9 |
10 | # Display Image to the user (for debugging purposes).
11 | # * im: Image to display
12 | def show_img(im):
13 | im.show()
14 |
15 | # Save the Image to a file with the specified filename,
16 | # then show the Image to the user.
17 | # * im: Image to be saved
18 | # * filename: string, name to save file as
19 | def save_img(im, filename):
20 | im.save(filename, "jpeg")
21 | show_img(im)
22 |
23 | # Return a new Image, with Obamicon filter applied.
24 | # * im: Image to be filtered
25 | def obamicon(im):
26 | # Load the pixel data from im.
27 | pixels = im.getdata()
28 | # Create a list to hold the new image pixel data.
29 | new_pixels = []
30 |
31 | # Define color constants to use for recoloring.
32 | darkBlue = (0, 51, 76)
33 | red = (217, 26, 33)
34 | lightBlue = (112, 150, 158)
35 | yellow = (252, 227, 166)
36 |
37 | # Process the pixels in the image.
38 | for p in pixels:
39 | # Pixel intensity = R value + G value + B value
40 | intensity = p[0] + p[1] + p[2]
41 |
42 | if intensity < 182:
43 | new_pixels.append(darkBlue)
44 |
45 | elif intensity >= 182 and intensity < 364:
46 | new_pixels.append(red)
47 |
48 | elif intensity >= 364 and intensity < 546:
49 | new_pixels.append(lightBlue)
50 |
51 | elif intensity >=546:
52 | new_pixels.append(yellow)
53 |
54 | # Save the filtered pixels as a new image
55 | newim = Image.new("RGB", im.size)
56 | newim.putdata(new_pixels)
57 | return newim
58 |
59 | # Return a new Image, with grayscale filter applied.
60 | # * im: Image to be filtered
61 | def grayscale(im):
62 | # Load the pixel data from im.
63 | pixels = im.getdata()
64 | # Create a list to hold the new image pixel data.
65 | new_pixels = []
66 |
67 | # Process the pixels in the image.
68 | for p in pixels:
69 | new_p = avg_pixel(p)
70 | new_pixels.append(new_p)
71 |
72 | # Save the filtered pixels as a new image
73 | newim = Image.new("RGB", im.size)
74 | newim.putdata(new_pixels)
75 | return newim
76 |
77 | # Return a sequence of pixels, with emphasize filter applied.
78 | # * im: Image to be filtered
79 | # * rgb_color: (r,g,b) tuple, color to be isolated in image
80 | # * threshold: int, tolerance for which colors should be filtered
81 | def emphasize(im, rgb_color, threshold):
82 | # Load the pixel data from im.
83 | pixels = im.getdata()
84 | # Create a list to hold the new image pixel data.
85 | new_pixels = []
86 |
87 | # Set RGB values for color to isolate in the image
88 | rtarget = rgb_color[0]
89 | gtarget = rgb_color[1]
90 | btarget = rgb_color[2]
91 |
92 | # Process the pixels in the image.
93 | for p in pixels:
94 | r = p[0]
95 | g = p[1]
96 | b = p[2]
97 |
98 | # Calculate how far away p's color is from the target color.
99 | # Use the distance formula:
100 | # d = sqrt((rtarget-r)^2 + (gtarget-g)^2 + (btarget-b)^2)
101 | color_dist = math.sqrt((rtarget-r)**2 + (gtarget-g)**2 + (btarget-b)**2)
102 |
103 | # If p's color is too far away from target color,
104 | # make it grayscale. Otherwise, use p's color.
105 | if color_dist > threshold:
106 | new_p = avg_pixel(p)
107 | new_pixels.append(new_p)
108 | else:
109 | new_pixels.append(p)
110 |
111 | # Save the filtered pixels as a new image
112 | newim = Image.new("RGB", im.size)
113 | newim.putdata(new_pixels)
114 | return newim
115 |
116 | # Return a new Image, with add_color filter applied.
117 | # * im: Image to be filtered
118 | # * color: (r,g,b) tuple
119 | def add_color(im, color):
120 | # Load the pixel data from im.
121 | pixels = im.getdata()
122 | # Create a list to hold the new image pixel data.
123 | new_pixels = []
124 |
125 | # Process the pixels in the image.
126 | for p in pixels:
127 | new_r = p[0]+color[0]
128 | new_g = p[1]+color[1]
129 | new_b = p[2]+color[2]
130 | new_pixels.append((new_r, new_g, new_b))
131 |
132 | # Save the filtered pixels as a new image
133 | newim = Image.new("RGB", im.size)
134 | newim.putdata(new_pixels)
135 | return newim
136 |
137 | # Return a new Image, with invert filter applied.
138 | # * im: Image to be filtered
139 | def invert(im):
140 | # Load the pixel data from im.
141 | pixels = im.getdata()
142 | # Create a list to hold the new image pixel data.
143 | new_pixels = []
144 |
145 | # Process the pixels in the image.
146 | for p in pixels:
147 | new_r = 255-p[0]
148 | new_g = 255-p[1]
149 | new_b = 255-p[2]
150 | new_pixels.append((new_r, new_g, new_b))
151 |
152 | # Save the filtered pixels as a new image
153 | newim = Image.new("RGB", im.size)
154 | newim.putdata(new_pixels)
155 | return newim
156 |
157 | # Helper function.
158 | # Return a grayscale tuple for a single pixel value.
159 | # * pixel: (r,g,b) tuple
160 | def avg_pixel(pixel):
161 | # Use the average of p's RGB values to set a new pixel value.
162 | avg = (pixel[0] + pixel[1] + pixel[2]) // 3 # Use // for int division.
163 | return (avg, avg, avg) # R = G = B will be a gray pixel!
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/GuessTheNumber/README.md:
--------------------------------------------------------------------------------
1 | # Guess The Number
2 |
3 | To run on Mac:
4 | `$ python3 guess_number.py`
5 |
6 | To run on Windows:
7 | `$ python guess_number.py`
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/GuessTheNumber/guess_number.py:
--------------------------------------------------------------------------------
1 | #imports the ability to get a random number (we will learn more about this later!)
2 | from random import *
3 |
4 | #Generates a random integer.
5 | aRandomNumber = randint(1, 20)
6 | # For Testing: print(aRandomNumber)
7 |
8 | numTries = 0 # don't need this variable in for loops
9 | while True: # for numTries in range(3):
10 | guess = input("Guess a number between 1 and 20 (inclusive): ")
11 | numTries += 1
12 | if not guess.isnumeric(): # checks if a string is only digits 0 to 9
13 | print("That's not a positive whole number, try again!")
14 | continue
15 | else:
16 | guess = int(guess) # converts a string to an integer
17 |
18 | # check if correct
19 | if guess == aRandomNumber:
20 | print("You go it!")
21 | break
22 |
23 | # check if out of tries
24 | if numTries >= 3: #numTries >= 2
25 | print("Sorry! You failed.")
26 | break
27 |
28 | # give hints
29 | if(guess > aRandomNumber):
30 | print("Try a smaller number next time.")
31 | elif(guess < aRandomNumber):
32 | print("Try a bigger number next time.")
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/GuessTheSecretWord/README.md:
--------------------------------------------------------------------------------
1 | # Guess The Secret Word
2 |
3 | To run on Mac:
4 | `$ python3 guess_the_secret_word.py`
5 |
6 | To run on Windows:
7 | `$ python guess_the_secret_word.py`
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/GuessTheSecretWord/guess_the_secret_word.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | # A list of words that
4 | potential_words = ["example", "words", "someone", "can", "guess"]
5 |
6 | word = random.choice(potential_words)
7 |
8 | # Use to test your code:
9 | # print(word)
10 |
11 | # Converts the word to lowercase
12 | word = word.lower()
13 |
14 |
15 | guesses = []
16 | numfails = 0
17 | maxfails = 7
18 | wordToGuess = []
19 |
20 | for letter in word:
21 | wordToGuess.append("_")
22 |
23 | done = False
24 |
25 | while not done:
26 | print("-----------------------------------")
27 | print("Lives Left: ", maxfails - numfails)
28 | print("Guesses So Far: ", guesses)
29 | print("Current Word: ", wordToGuess)
30 |
31 | guess = input("Guess a letter: ")
32 | guess = guess.lower()
33 |
34 | if(len(guess) > 1):
35 | print("That's too long!")
36 | elif(guess.isalpha() == False):
37 | print("That's not a letter!")
38 | elif(guess in guesses):
39 | print("You already guessed that!")
40 | else:
41 | guesses.append(guess)
42 |
43 | if(guess in word):
44 | print("You got a letter!")
45 | for idx in range(0, len(word)):
46 | if word[idx] == guess:
47 | wordToGuess[idx] = guess
48 |
49 | done = True
50 | for idx in range(0, len(wordToGuess)):
51 | if wordToGuess[idx] == "_":
52 | done = False
53 | break
54 | if done:
55 | print("You won! It was: " + word)
56 | else:
57 | print("Wrong guess!")
58 | numfails += 1
59 |
60 | if numfails >= maxfails:
61 | print("You lost!")
62 | done = True
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/ListChallenge/README.md:
--------------------------------------------------------------------------------
1 | # List Challenge
2 |
3 | To run on Mac:
4 | `$ python3 list_challenge.py`
5 |
6 | To run on Windows:
7 | `$ python list_challenge.py`
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/ListChallenge/list_challenge.py:
--------------------------------------------------------------------------------
1 | ### LEVEL 1 ###
2 |
3 | from random import *
4 |
5 | #Code below is the skeleton for a simple name generator.
6 |
7 | #Create the list of words you want to choose from.
8 | word_list = ["frank", "bean", "jean", "louis", "lisa", "pisa", "italy", "spaghetti"]
9 |
10 | name = ""
11 |
12 | for x in range(2):
13 |
14 | #Generates a random integer.
15 | x = randint(0, len(word_list)-1)
16 | name += word_list[x] + " "
17 |
18 | print(name)
19 | print("")
20 |
21 | ### LEVEL 2 ###
22 |
23 | from random import *
24 |
25 | #Code below is the skeleton for a menu generator.
26 |
27 | #Create the list of words you want to choose from.
28 | side = ["beans", "rice", "salsa", "guac", "chips"]
29 | main = ["tamale", "burrito", "enchilada", "tostada"]
30 | dessert = ["flan", "rice pudding", "sopapillas"]
31 |
32 | sides_selected = []
33 |
34 | for x in range(2):
35 |
36 | #Generates a random integer.
37 | x = randint(0, len(side)-1)
38 | sides_selected.append(side[x])
39 |
40 | print("sides: ", sides_selected)
41 |
42 | #Generates a random integer.
43 | x = randint(0, len(main)-1)
44 | print("main: ", main[x])
45 |
46 | x = randint(0, len(dessert)-1)
47 | print("dessert: ", dessert[x])
48 |
49 |
50 | print("")
51 |
52 | ### LEVEL 3 ###
53 |
54 | from random import *
55 |
56 | #Code below is the skeleton for a simple haiku generator.
57 |
58 | #Create the list of words you want to choose from.
59 | five_syllable = ["Hey, I just met you", "First I was afraid", "Love the one you’re with"]
60 | seven_syllable = ["Now, winter chills on my feet", "A time of joy, peace and love", "Your shadow, one can not find"]
61 |
62 | first_sentence = ""
63 | second_sentence = ""
64 | third_sentence = ""
65 |
66 | #Generates a random integer.
67 | x = randint(0, len(five_syllable)-1)
68 | print(five_syllable[x])
69 |
70 | x = randint(0, len(seven_syllable)-1)
71 | print(seven_syllable[x])
72 |
73 | x = randint(0, len(five_syllable)-1)
74 | print(five_syllable[x])
75 |
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/README.md:
--------------------------------------------------------------------------------
1 | # Unit 1.2: Python
2 |
3 | ## Table of Contents
4 |
5 | ### Projects:
6 |
7 | 1. [Guess The Number](GuessTheNumber)
8 | * This project is used in U1L5.
9 | * Students practice using loops and conditionals.
10 | 1. [Text Adventure](TextAdventure)
11 | * This project is used in U1L5.
12 | * Students practice loops, variables, and conditionals in Python while translating their Choose Your Own Adventure project from Scratch.
13 | 1. [List Challenge](ListChallenge)
14 | * This project is used in U1L6.
15 | * Students practice using lists in Python.
16 | 1. [Guess The Secret Word](GuessTheSecretWord)
17 | * This project is used in U1L6.
18 | * Students learn how to use lists while creating a Guess The Secret Word game.
19 | 1. [Chatbot](Chatbot)
20 | * This project is used in U1L7.
21 | * Students learn to use functions in Python.
22 | 1. [#AllTheFilters](AllTheFilters)
23 | * This project is used in U1L8.
24 | * Students learn about libraries and use the PIL library to create filters for an image.
25 |
26 |
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/TextAdventure/README.md:
--------------------------------------------------------------------------------
1 | # Text Adventure
2 |
3 | To run on Mac:
4 | `$ python3 text_adventure.py`
5 |
6 | To run on Windows:
7 | `$ python text_adventure.py`
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/TextAdventure/text_adventure.py:
--------------------------------------------------------------------------------
1 | start = '''
2 | You wake up one morning and find that you aren’t in your bed; you aren’t even in
3 | your room. You’re in the middle of a giant maze. A sign is hanging from the ivy:
4 | “You have one hour. Don’t touch the walls.” There is a hallway to your right and
5 | to your left.
6 | '''
7 |
8 | left_hallway = '''
9 | You go left and as you go farther down the path the ivy starts to change color
10 | going from green to white. You are drenched in sweat by the time you reach the
11 | next room where you find a glass of water on the stump of a tree. There is a
12 | passageway to your right. The glass has condensation on the outside like it is
13 | cold. You are so thirsty that you reach for it. As soon as the glass is off the
14 | stump the room goes up in flames. Even the stump is on fire. You drink the
15 | water. It is cold. You run as fast you can to the passageway to your right
16 | catching a few minor burns along the way.
17 | '''
18 | right_hallway = '''
19 | You go right and as you go the ground feels softer. It's like walking on a balloon.
20 | It's so hard to keep your balance that you're on your hands and knees as you reach
21 | a room with nothing but swords sticking out of the wall and a passageway to your left.
22 | In the center of the room is a big fluffy red bathrobe laying on top of a table.
23 | You go to examine the bathrobe but as you pick it up the swords on the wall
24 | start hitting each other. It's as if there are people on the other side holding
25 | on to the swords and dueling. Then the walls start closing in, you put the robe
26 | on to protect yourself as you run for the passageway to your left. By the time
27 | you make it to the passageway the robe has been cut to shreds, catching a few
28 | cuts on your skin along the way.
29 | '''
30 |
31 | right_corridor = '''
32 | You go along the passageway trying to assess the damage to yourself when you
33 | come upon a third room. This room has an office desk in the middle with a big
34 | rotary telephone. The phone is ringing. You pick it up and notice that it smells
35 | like fresh squeezed orange juice and the receiver has the texture of hair. On it
36 | you hear your mothers voice repeating, "Why?" over and over. You try to talk to it but
37 | there is no response, just "Why?". The voice suddenly stops and you hear the slow
38 | creaking of two doors opening. You turn around and see two doorways into complete
39 | darkness. One is framed in red and one is framed in white.
40 | '''
41 |
42 | left_corridor = '''
43 | You go along the passageway trying to assess the damage to yourself when you
44 | come upon a third room. This room has an office desk in the middle with a big
45 | rotary telephone. The phone is ringing. You pick it up and notice that it smells
46 | like fresh squeezed orange juice and the receiver has the texture of hair. On it
47 | you hear your mothers voice repeating, "Why?" over and over. You try to talk to it but
48 | there is no response, just "Why?". The voice suddenly stops and you hear the slow
49 | creaking of two doors opening. You turn around and see two doorways into complete
50 | darkness. One is framed in yellow and one is framed in blue.
51 | '''
52 | print(start)
53 | done = False
54 | color = ""
55 |
56 | while not done:
57 | user_input = input("Type 'left' to go left or 'right' to go right: ")
58 | if user_input == "left":
59 | print(left_hallway)
60 | print(left_corridor)
61 | color = "blue_yellow"
62 | done = True
63 | elif user_input == "right":
64 | print(right_hallway)
65 | print(right_corridor)
66 | color = "red_white"
67 | done = True
68 | else:
69 | print("Please type 'left' or 'right'");
70 |
71 |
72 | blue_doorway = '''
73 | You walk into the darkness through the blue doorway and immediately get the sensation
74 | that you are falling. You try to scream but can't even hear your own voice. Then
75 | you start to see your things fly past you. Your phone, you favorite pair of shoes,
76 | your favorite toy, pictures from your childhood. You see memories, but you can't
77 | feel them. They are all happening to this other person that looks like you but is
78 | a stranger. You hear your mother's voice, "Why?". Then you hit something.
79 | '''
80 |
81 | yellow_doorway = '''
82 | You walk into the darkness through the yellow doorway and feel yourself pulled up
83 | like you're in a vacuum, but gently. A soft breeze that smells of vanilla seems
84 | to envelope you and you sense two large hands underneath pushing you up. You weren't
85 | being sucked up but carried up. You hear your mothers voice again, "Why?". Then
86 | you stop.
87 | '''
88 |
89 | red_doorway = '''
90 | You walk into the darkness through the red doorway and immediately get the sensation
91 | that you are falling. You try to scream but can't even hear your own voice. Then
92 | you start to see your things fly past you. Your phone, you favorite pair of shoes,
93 | your favorite toy, pictures from your childhood. You see memories, but you can't
94 | feel them. They are all happening to this other person that looks like you but is
95 | a stranger. You hear your mother's voice, "Why?". Then you hit something.
96 | '''
97 |
98 | white_doorway = '''
99 | You walk into the darkness through the white doorway and feel yourself pulled up
100 | like you're in a vacuum, but gently. A soft breeze that smells of vanilla seems
101 | to envelope you and you sense two large hands underneath pushing you up. You weren't
102 | being sucked up but carried up. You hear your mothers voice again, "Why?". Then
103 | you stop.
104 | '''
105 |
106 | end_of_story_red_white = '''
107 | You're in bed. You stand up in bed and turn off your alarm. It's time to
108 | to start your day. You put on your pair of mismatched slippers, red and white, and
109 | go to the bathroom.
110 | '''
111 |
112 | end_of_story_blue_yellow = '''
113 | You're in bed. You stand up in bed and turn off your alarm. It's time to
114 | to start your day. You put on your pair of mismatched slippers, blue and yellow, and
115 | go to the bathroom.
116 | '''
117 |
118 | done = False
119 | while not done:
120 | if(color == "red_white"):
121 | user_input = input("Type 'red' to go into the red doorway or 'white' to into the white doorway: ")
122 | if user_input == "red":
123 | print(red_doorway)
124 | print(end_of_story_red_white)
125 | done = True
126 | elif user_input == "white":
127 | print(white_doorway)
128 | print(end_of_story_red_white)
129 | done = True
130 | else:
131 | print("Please type 'red' or 'white'");
132 | elif(color == "blue_yellow"):
133 | user_input = input("Type 'blue' to go into the blue doorway or 'yellow' to into the yellow doorway: ")
134 | if user_input == "blue":
135 | print(blue_doorway)
136 | print(end_of_story_blue_yellow)
137 | done = True
138 | elif user_input == "yellow":
139 | print(yellow_doorway)
140 | print(end_of_story_blue_yellow)
141 | done = True
142 | else:
143 | print("Please type 'blue' or 'yellow'");
144 | else:
145 | print("You wake up suddenly and confused. How did you end up here?")
146 | done = True
147 |
148 |
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/chatbot/README.md:
--------------------------------------------------------------------------------
1 | # Chatbot
2 |
3 | To run on Mac:
4 | `$ python3 chatbot-pt1.py`
5 |
6 | To run on Windows:
7 | `$ python chatbot-pt1.py`
8 |
9 | ## Contents
10 |
11 | * `chatbot-pt1.py`
12 | * Defines `intro()` function.
13 | * `chatbot-pt2.py`
14 | * Defines `process_input()`, `say_greeting()`, and `say_default()` functions.
15 | * Updates main program loop to incorporate `process_input()`.
16 | * `chatbot-pt4.py`
17 | * Defines `is_valid_input()` function.
18 | * Updates `process_input()` to use `is_valid_input()` to allow a variety of greeting inputs.
19 | * `chatbot-pt5.py`
20 | * **Note:** These changes are just examples of customizations students might choose. Actual student solutions will vary.
21 | * Defines `say_joke()` function, which tells the user a knock-knock joke.
22 | * Defines `say_goodbye()` function, and updates main while loop to exit cleanly when the user enters a farewell phrase.
23 |
24 | **Note:** There is no `chatbot-pt3.py`, since this part of the activity is all student customizations.
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/chatbot/chatbot-pt1.py:
--------------------------------------------------------------------------------
1 | # --- Define your functions below! ---
2 |
3 | # The chatbot introduces itself and gives the user instructions.
4 | def intro():
5 | print("Hi, my name is Phyllis. Let's talk!")
6 | print("Type something and hit enter.")
7 |
8 |
9 | # --- Put your main program below! ---
10 | def main():
11 | intro()
12 | while True:
13 | answer = input("(What will you say?) ")
14 | print("That's cool!")
15 |
16 |
17 | # DON'T TOUCH! Setup code that runs your main() function.
18 | if __name__ == "__main__":
19 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/chatbot/chatbot-pt2.py:
--------------------------------------------------------------------------------
1 | # --- Define your functions below! ---
2 |
3 | # The chatbot introduces itself and gives the user instructions.
4 | def intro():
5 | print("Hi, my name is Phyllis. Let's talk!")
6 | print("Type something and hit enter.")
7 |
8 | # Choose a response based on the user's input.
9 | def process_input(answer):
10 | if answer == "hi":
11 | say_greeting()
12 | else:
13 | say_default()
14 |
15 | # Display a greeting message to the user.
16 | def say_greeting():
17 | print("Hey there!")
18 |
19 | # Display a default message to the user.
20 | def say_default():
21 | print("That's cool!")
22 |
23 |
24 | # --- Put your main program below! ---
25 | def main():
26 | intro()
27 | while True:
28 | answer = input("(What will you say?) ")
29 | process_input(answer)
30 |
31 |
32 | # DON'T TOUCH! Setup code that runs your main() function.
33 | if __name__ == "__main__":
34 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/chatbot/chatbot-pt4.py:
--------------------------------------------------------------------------------
1 | # --- Define your functions below! ---
2 |
3 | # The chatbot introduces itself and gives the user instructions.
4 | def intro():
5 | print("Hi, my name is Phyllis. Let's talk!")
6 | print("Type something and hit enter.")
7 |
8 | # Choose a response based on the user's input.
9 | def process_input(answer):
10 | # Define a list of possible ways the user might say hello.
11 | greetings = ["hi", "hello", "hey", "hey there", "sup"]
12 |
13 | if is_valid_input(answer, greetings):
14 | say_greeting()
15 | else:
16 | say_default()
17 |
18 | # Display a greeting message to the user.
19 | def say_greeting():
20 | print("Hey there!")
21 |
22 | # Display a default message to the user.
23 | def say_default():
24 | print("That's cool!")
25 |
26 | # Check if user_input matches one of the elements
27 | # in valid_responses.
28 | def is_valid_input(user_input, valid_responses):
29 | for item in valid_responses:
30 | if user_input == item:
31 | # If you find a matching response, the input is
32 | # valid for this kind of response.
33 | return True
34 | # If you didn't find a matching response, after
35 | # going through the entire list, the input
36 | # isn't valid for this kind of response.
37 | return False
38 |
39 | # --- Put your main program below! ---
40 | def main():
41 | intro()
42 | while True:
43 | answer = input("(What will you say?) ")
44 | process_input(answer)
45 |
46 |
47 | # DON'T TOUCH! Setup code that runs your main() function.
48 | if __name__ == "__main__":
49 | main()
--------------------------------------------------------------------------------
/U1-Fundamentals/U1.2-Python/chatbot/chatbot-pt5.py:
--------------------------------------------------------------------------------
1 | # --- Define your functions below! ---
2 |
3 | # The chatbot introduces itself and gives the user instructions.
4 | def intro():
5 | print("Hi, my name is Phyllis. Let's talk!")
6 | print("Type something and hit enter.")
7 |
8 | # Choose a response based on the user's input.
9 | def process_input(answer):
10 | # Define a list of possible ways the user might say hello.
11 | greetings = ["hi", "hello", "hey", "hey there", "sup"]
12 |
13 | # Define a list of possible ways the user might say bye.
14 | farewells = ["bye", "see ya", "goodbye", "quit", "exit"]
15 |
16 | if is_valid_input(answer, farewells):
17 | say_goodbye()
18 | return True # The user wants to exit!
19 | elif is_valid_input(answer, greetings):
20 | say_greeting()
21 | elif 'joke' in answer:
22 | say_joke()
23 | else:
24 | say_default()
25 | return False # The chatbot will continue asking for user input.
26 |
27 | # Display a greeting message to the user.
28 | def say_greeting():
29 | print("Hey there!")
30 |
31 | # Display a farewell message to the user.
32 | def say_goodbye():
33 | print("See you next time!")
34 |
35 | # Tell the user an interactive knock-knock joke.
36 | def say_joke():
37 | print("Let me tell you a joke!")
38 |
39 | # "Knock knock!" "Who's there"?
40 | valid_responses = ["who's there", "whos there", "who's there?", "whos there?"]
41 | done = False
42 | while not done:
43 | answer = input("Knock knock! ")
44 | if not is_valid_input(answer.lower(), valid_responses):
45 | print("No, you're supposed to say, 'Who's there?'")
46 | else:
47 | done = True
48 |
49 | # "Little old lady." "Little old lady who?"
50 | valid_responses = ["little old lady who", "little old lady who?"]
51 | done = False
52 | while not done:
53 | answer = input("Little old lady. ")
54 | if not is_valid_input(answer.lower(), valid_responses):
55 | print("No, you're supposed to say, 'Little old lady who?'")
56 | else:
57 | done = True
58 |
59 | # Say the punchline!
60 | print("I didn't know you could yodel!")
61 |
62 | # Display a default message to the user.
63 | def say_default():
64 | print("That's cool!")
65 |
66 | # Check if user_input matches one of the elements
67 | # in valid_responses.
68 | def is_valid_input(user_input, valid_responses):
69 | for item in valid_responses:
70 | if user_input == item:
71 | # If you find a matching response, the input is
72 | # valid for this kind of response.
73 | return True
74 | # If you didn't find a matching response, after
75 | # going through the entire list, the input
76 | # isn't valid for this kind of response.
77 | return False
78 |
79 | # --- Put your main program below! ---
80 | def main():
81 | intro()
82 | done = False # Use this to keep track of when the user wants to exit.
83 | while not done:
84 | answer = input("(What will you say?) ")
85 | done = process_input(answer)
86 |
87 |
88 | # DON'T TOUCH! Setup code that runs your main() function.
89 | if __name__ == "__main__":
90 | main()
--------------------------------------------------------------------------------
/U2-Applications/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/README.md
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataScientist/README.md:
--------------------------------------------------------------------------------
1 | # Data Scientist for a Day
2 |
3 | To run on Mac:
4 | `$ python3 data_science.py`
5 |
6 | To run on Windows:
7 | `$ python data_science.py`
8 |
9 | This program uses the matplotlib library to create a line graph of average math SAT scores in AL and MA.
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataScientist/data_science.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import school_scores
3 |
4 | years = []
5 | AL_scores = []
6 | MA_scores = []
7 |
8 | scores = school_scores.get_all()
9 |
10 | for score in scores:
11 | if score["State"]["Code"] == 'AL':
12 | AL_scores.append(score["Total"]["Math"])
13 | years.append(score["Year"])
14 | elif score["State"]["Code"] == 'MA':
15 | MA_scores.append(score["Total"]["Math"])
16 |
17 | plt.plot(years, AL_scores)
18 | plt.plot(years, MA_scores)
19 | plt.legend(['AL', 'MA'], loc='upper left')
20 |
21 | plt.xlabel('Years')
22 | plt.ylabel('Scores')
23 | plt.title('Average Math SAT scores in AL and MA')
24 |
25 |
26 | plt.show()
27 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataScientist/school_scores.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.1-Data/DataScientist/school_scores.db
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataScientist/school_scores.py:
--------------------------------------------------------------------------------
1 | '''
2 | Hello student. Thank you for downloading a CORGIS library. However, you do not need to open this library. Instead you should use the following:
3 |
4 | import school_scores
5 |
6 | If you opened the file because you are curious how this library works, then well done! We hope that you find it a useful learning experience. However, you should know that this code is meant to solve somewhat esoteric pedagogical problems, so it is often not best practices.
7 | '''
8 |
9 | import sys as _sys
10 | import os as _os
11 | import json as _json
12 | import sqlite3 as _sql
13 | import difflib as _difflib
14 |
15 | class _Constants(object):
16 | '''
17 | Global singleton object to hide some of the constants; some IDEs reveal internal module details very aggressively, and there's no other way to hide stuff.
18 | '''
19 | _HEADER = {'User-Agent':
20 | 'CORGIS School Scores library for educational purposes'}
21 | _PYTHON_3 = _sys.version_info >= (3, 0)
22 | _TEST = False
23 | _HARDWARE = 1000
24 |
25 | if _Constants._PYTHON_3:
26 | import urllib.request as _request
27 | from urllib.parse import quote_plus as _quote_plus
28 | from urllib.error import HTTPError as _HTTPError
29 | else:
30 | import urllib2 as _urllib2
31 | from urllib import quote_plus as _quote_plus
32 | from urllib2 import HTTPError as _HTTPError
33 |
34 | class DatasetException(Exception):
35 | ''' Thrown when there is an error loading the dataset for some reason.'''
36 | pass
37 |
38 | _Constants._DATABASE_NAME = "school_scores.db"
39 | if not _os.access(_Constants._DATABASE_NAME, _os.F_OK):
40 | raise DatasetException("Error! Could not find a \"{0}\" file. Make sure that there is a \"{0}\" in the same directory as \"{1}.py\"! Spelling is very important here.".format(_Constants._DATABASE_NAME, __name__))
41 | elif not _os.access(_Constants._DATABASE_NAME, _os.R_OK):
42 | raise DatasetException("Error! Could not read the \"{0}\" file. Make sure that it readable by changing its permissions. You may need to get help from your instructor.".format(_Constants._DATABASE_NAME, __name__))
43 | elif not _os.access(_Constants._DATABASE_NAME, _os.W_OK):
44 | _sys.stderr.write('The local cache (\" \") will not be updated. Make sure that it is writable by changing its permissions. You may need to get help from your instructor.\n'.format(_Constants._DATABASE_NAME))
45 | _sys.stderr.flush()
46 |
47 | _Constants._DATABASE = _sql.connect(_Constants._DATABASE_NAME)
48 |
49 | class _Auxiliary(object):
50 | @staticmethod
51 | def _parse_type(value, type_func):
52 | """
53 | Attempt to cast *value* into *type_func*, returning *default* if it fails.
54 | """
55 | default = type_func(0)
56 | if value is None:
57 | return default
58 | try:
59 | return type_func(value)
60 | except ValueError:
61 | return default
62 |
63 | @staticmethod
64 | def _byteify(input):
65 | """
66 | Force the given input to only use `str` instead of `bytes` or `unicode`.
67 | This works even if the input is a dict, list,
68 | """
69 | if isinstance(input, dict):
70 | return {_Auxiliary._byteify(key): _Auxiliary._byteify(value) for key, value in input.items()}
71 | elif isinstance(input, list):
72 | return [_Auxiliary._byteify(element) for element in input]
73 | elif _Constants._PYTHON_3 and isinstance(input, str):
74 | return str(input.encode('ascii', 'replace').decode('ascii'))
75 | elif not _Constants._PYTHON_3 and isinstance(input, unicode):
76 | return str(input.encode('ascii', 'replace').decode('ascii'))
77 | else:
78 | return input
79 |
80 | @staticmethod
81 | def _guess_schema(input):
82 | if isinstance(input, dict):
83 | return {str(key.encode('ascii', 'replace').decode('ascii')):
84 | _Auxiliary._guess_schema(value) for key, value in input.items()}
85 | elif isinstance(input, list):
86 | return [_Auxiliary._guess_schema(input[0])] if input else []
87 | else:
88 | return type(input)
89 |
90 |
91 |
92 | ################################################################################
93 | # Domain Objects
94 | ################################################################################
95 |
96 |
97 |
98 |
99 |
100 | ################################################################################
101 | # Interfaces
102 | ################################################################################
103 |
104 |
105 |
106 | def get_all():
107 | """
108 | Returns all of the data for every state into a list.
109 |
110 | """
111 | if False:
112 | # If there was a Test version of this method, it would go here. But alas.
113 | pass
114 | else:
115 | rows = _Constants._DATABASE.execute("SELECT data FROM school_scores".format(
116 | hardware=_Constants._HARDWARE))
117 | data = [r[0] for r in rows]
118 | data = [_Auxiliary._byteify(_json.loads(r)) for r in data]
119 |
120 | return _Auxiliary._byteify(data)
121 |
122 |
123 | ################################################################################
124 | # Internalized testing code
125 | ################################################################################
126 |
127 | def _test_interfaces():
128 | from pprint import pprint as _pprint
129 | from timeit import default_timer as _default_timer
130 | # Production test
131 | print("Production get_all")
132 | start_time = _default_timer()
133 | result = get_all()
134 |
135 | print("{} entries found.".format(len(result)))
136 | _pprint(_Auxiliary._guess_schema(result))
137 |
138 | print("Time taken: {}".format(_default_timer() - start_time))
139 |
140 |
141 | if __name__ == '__main__':
142 | from optparse import OptionParser as _OptionParser
143 | _parser = _OptionParser()
144 | _parser.add_option("-t", "--test", action="store_true",
145 | default=False,
146 | help="Execute the interfaces to test them.")
147 | (_options, _args) = _parser.parse_args()
148 |
149 | if _options.test:
150 | _test_interfaces()
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/Readme.md:
--------------------------------------------------------------------------------
1 | # Data Visualization Project
2 |
3 | To run on Mac: `python3 data_vis_project_pt1.py`
4 |
5 | To run on Windows: `python data_vis_project_pt1.py`
6 |
7 | Get Twitter Data at [TwitterData/tweets_small.json](../TwitterData/tweets_small.json). Copy this to your project folder.
8 |
9 | ### Part 1: Analyze the Feelings in the Tweets
10 | This program uses the TextBlob library to analyze the sentiment in a set of tweets.
11 |
12 | ### Part 2: Visualize the Feelings
13 | This program creates a histogram of polarity of tweets. This program also creates a scatter plot of polarity vs. subjectivity.
14 |
15 | ### Part 3: Visualize the Language
16 | This program generates a word cloud from tweets.
17 |
18 | ### Part 4: Compare the Language and Feelings
19 | This program creates three word clouds: positive tweets, negative tweets, and neutral tweets.
20 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/cloud_generator.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we will generate a three word clouds from tweet data.
3 | One for positive tweets, one for negative, and one for neutral tweets.
4 |
5 | For students who finish this part of the program quickly,
6 | they might try it on the larger JSON file to see how much longer that takes.
7 | They might also want to try subjective vs objective tweets.
8 | '''
9 |
10 | import json
11 | from textblob import TextBlob
12 | import matplotlib.pyplot as plt
13 | from wordcloud import WordCloud
14 |
15 | title = "CS Topics"
16 | mainDict = dict()
17 | mainDict["variables"] = 1
18 | mainDict["loops"] = 1
19 | mainDict["conditionals"] = 1
20 | mainDict["functions"] = 1
21 | mainDict["algorithms"] = 2
22 | mainDict["decomposition"] = 2
23 | mainDict["sorting"] = 4
24 | mainDict["linked lists"] = 3
25 | mainDict["hash maps"] = 3
26 | mainDict["recursion"] = 3
27 | mainDict["binary search trees"] = 4
28 | mainDict["regular expressions"] = 4
29 | mainDict["A* search"] = 4
30 | mainDict["machine learning"] = 4
31 | mainDict["wireframing"] = 1
32 | mainDict["pseudocoding"] = 2
33 | mainDict["state machines"] = 2
34 |
35 |
36 |
37 | #Wrap this in a function so we can use it three times
38 | def AddFigure(dictionary, plotnum, title):
39 | wordcloud = WordCloud().generate_from_frequencies(dictionary)
40 | plt.subplot(plotnum)
41 | plt.imshow(wordcloud, interpolation='bilinear')
42 | plt.title(title)
43 | plt.axis("off")
44 |
45 |
46 | #Create a matplotlib figure
47 | plt.figure(1)
48 |
49 | #Create the three word clouds
50 | AddFigure(mainDict, 111, title)
51 |
52 | #Show all at once
53 | plt.show()
54 |
55 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/data_vis_project_part1.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we store the polarities and subjectivities of all the tweets.
3 | '''
4 |
5 | import json
6 | from textblob import TextBlob
7 | import matplotlib.pyplot as plt
8 |
9 | #Get the JSON data
10 | tweetFile = open("../TwitterData/tweets_small.json", "r")
11 | tweetData = json.load(tweetFile)
12 | tweetFile.close()
13 |
14 | #Create a Sentiment List
15 | polarityList = []
16 |
17 | #[OPTIONAL] Subjectivity
18 | subjectivityList = []
19 |
20 | #Get Sentiment Data
21 | for tweet in tweetData:
22 | tweetblob = TextBlob(tweet["text"])
23 | polarityList.append(tweetblob.polarity)
24 |
25 | #[OPTIONAL] Subjectivity
26 | subjectivityList.append(tweetblob.subjectivity)
27 |
28 | print(polarityList)
29 | print(subjectivityList)
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/data_vis_project_part2.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we display a histogram of the polarities of all the tweets.
3 |
4 | [OPTIONAL]
5 | In this program, we will also display a scatter plot of polarity vs subjectivity.
6 |
7 | For students who finish this part of the program quickly,
8 | they might try out the optional graph. They might also try
9 | using the larger tweet file to generate the graph (this might take a while).
10 |
11 | They might also try to combine both graphs into one display.
12 | They can also play around with different bins for the histogram
13 | or try to draw centeredaxes on the scatter plot using matplotlib "spines".
14 | '''
15 |
16 | import json
17 | from textblob import TextBlob
18 | import matplotlib.pyplot as plt
19 |
20 | #Get the JSON data
21 | tweetFile = open("../TwitterData/tweets_small.json", "r")
22 | tweetData = json.load(tweetFile)
23 | tweetFile.close()
24 |
25 | #Create a Sentiment List
26 | polarityList = []
27 |
28 | #[OPTIONAL] Subjectivity
29 | subjectivityList = []
30 |
31 | #Get Sentiment Data
32 | for tweet in tweetData:
33 | tweetblob = TextBlob(tweet["text"])
34 | polarityList.append(tweetblob.polarity)
35 |
36 | #[OPTIONAL] Subjectivity
37 | subjectivityList.append(tweetblob.subjectivity)
38 |
39 |
40 | #Create the Graph
41 | plt.hist(polarityList, bins=[-1.1, -.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1.1])
42 | plt.xlabel('Polarities')
43 | plt.ylabel('Number of Tweets')
44 | plt.title('Histogram of Tweet Polarity')
45 | plt.axis([-1.1, 1.1, 0, 100])
46 | plt.grid(True)
47 | plt.show()
48 |
49 | #[OPTIONAL] Subjectivity
50 | plt.plot(polarityList, subjectivityList, 'ro')
51 | plt.xlabel('Polarity')
52 | plt.ylabel('Subjectivity')
53 | plt.title('Tweet Polarity vs Subjectivity')
54 | plt.axis([-1.1, 1.1, -0.1, 1.1])
55 | plt.grid(True)
56 | plt.show()
57 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/data_vis_project_part3.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we will generate a word cloud from tweet data.
3 |
4 | For students who finish this part of the program quickly,
5 | they might try it on the larger JSON file to see what clouds they can get.
6 | '''
7 |
8 | import json
9 | from textblob import TextBlob
10 | import matplotlib.pyplot as plt
11 | from wordcloud import WordCloud
12 |
13 | #Search term used for this tweet
14 | #We want to filter this out!
15 | tweetSearch = "automation"
16 |
17 | #Get the JSON data
18 | tweetFile = open("../TwitterData/tweets_small.json", "r")
19 | tweetData = json.load(tweetFile)
20 | tweetFile.close()
21 |
22 | #Combine All the Tweet Texts
23 | combinedTweets = ""
24 | for tweet in tweetData:
25 | combinedTweets += tweet['text']
26 |
27 | #Create a Combined Tweet Blob
28 | tweetblob = TextBlob(combinedTweets)
29 |
30 | #This can be useful to see what's possible
31 | #to do with a Textlob object
32 | #print(dir(tweetblob))
33 |
34 | #Filter Words
35 | wordsToFilter = ["about", "https", "in", "the", "thing", "will", "could", tweetSearch]
36 | filteredDictionary = dict()
37 |
38 | for word in tweetblob.words:
39 | #skip tiny words
40 | if len(word) < 2:
41 | continue
42 | #skip words with random characters or numbers
43 | if not word.isalpha():
44 | continue
45 | #skip words in our filter
46 | if word.lower() in wordsToFilter:
47 | continue
48 | #don't want lower case words smaller than 5 letters
49 | if len(word) < 5 and word.upper() != word:
50 | continue;
51 |
52 | #Try lower case only, try with upper case!
53 | filteredDictionary[word.lower()] = tweetblob.word_counts[word.lower()]
54 |
55 | #Create the word cloud
56 | wordcloud = WordCloud().generate_from_frequencies(filteredDictionary)
57 | plt.imshow(wordcloud, interpolation='bilinear')
58 | plt.axis("off")
59 | plt.show()
60 |
61 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DataVisualizationProject/data_vis_project_part4.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we will generate a three word clouds from tweet data.
3 | One for positive tweets, one for negative, and one for neutral tweets.
4 |
5 | For students who finish this part of the program quickly,
6 | they might try it on the larger JSON file to see how much longer that takes.
7 | They might also want to try subjective vs objective tweets.
8 | '''
9 |
10 | import json
11 | from textblob import TextBlob
12 | import matplotlib.pyplot as plt
13 | from wordcloud import WordCloud
14 |
15 | #Wrap this in a function because we'll use it several times
16 | def GetFilteredDictionary(tweetblob, tweetSearch):
17 | #Filter Words
18 | wordsToFilter = ["about", "https", "in", "the", "thing", "will", "could", tweetSearch]
19 | filteredDictionary = dict()
20 |
21 | for word in tweetblob.words:
22 | #skip tiny words
23 | if len(word) < 2:
24 | continue
25 | #skip words with random characters or numbers
26 | if not word.isalpha():
27 | continue
28 | #skip words in our filter
29 | if word.lower() in wordsToFilter:
30 | continue
31 | #don't want lower case words smaller than 5 letters
32 | if len(word) < 5 and word.upper() != word:
33 | continue;
34 |
35 | #Try lower case only, try with upper case!
36 | filteredDictionary[word.lower()] = tweetblob.word_counts[word.lower()]
37 |
38 | return filteredDictionary
39 |
40 | #Wrap this in a function so we can use it three times
41 | def AddFigure(filteredDictionary, plotnum, title):
42 | wordcloud = WordCloud().generate_from_frequencies(filteredDictionary)
43 | plt.subplot(plotnum)
44 | plt.imshow(wordcloud, interpolation='bilinear')
45 | plt.title(title)
46 | plt.axis("off")
47 |
48 | #Search term used for this tweet
49 | #We want to filter this out!
50 | tweetSearch = "automation"
51 |
52 | #Get the JSON data
53 | tweetFile = open("../TwitterData/tweets_small.json", "r")
54 | tweetData = json.load(tweetFile)
55 | tweetFile.close()
56 |
57 | #Combine All the Tweet Texts
58 | positiveTweets = ""
59 | negativeTweets = ""
60 | neutralTweets = ""
61 | for tweet in tweetData:
62 | tweetblob = TextBlob(tweet['text'])
63 | #Play with the numbers here
64 | if tweetblob.polarity > 0.2:
65 | positiveTweets += tweet['text']
66 | elif tweetblob.polarity < -0.2:
67 | negativeTweets += tweet['text']
68 | else:
69 | neutralTweets += tweet['text']
70 |
71 | #Create a Combined Tweet Blob
72 | positiveblob = TextBlob(positiveTweets)
73 | negativeblob = TextBlob(negativeTweets)
74 | neutralblob = TextBlob(neutralTweets)
75 |
76 | #Create a matplotlib figure
77 | plt.figure(1)
78 |
79 | #Create the three word clouds
80 | AddFigure(GetFilteredDictionary(negativeblob, tweetSearch), 131, "Negative Tweets")
81 | AddFigure(GetFilteredDictionary(neutralblob, tweetSearch), 132, "Neutral Tweets")
82 | AddFigure(GetFilteredDictionary(positiveblob, tweetSearch), 133, "Positive Tweets")
83 |
84 | #Show all at once
85 | plt.show()
86 |
87 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DictionaryAttack/README.md:
--------------------------------------------------------------------------------
1 | # Dictionary Attack
2 |
3 | To run on Mac:
4 | `$ python3 dictionary_attack.py`
5 |
6 | To run on Windows:
7 | `$ python dictionary_attack.py`
8 |
9 | This program runs a simple check to see if a password matches a word in a dictionary. Students doing only the basic solution do not need to include a check for letter-to-number substitutions.
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/DictionaryAttack/dictionary_attack.py:
--------------------------------------------------------------------------------
1 | def main():
2 |
3 | f = open("dictionary.txt","r")
4 | in_dictionary = False
5 |
6 | print("Can your password survive a dictionary attack?")
7 | test_password = input("Type in a trial password: ")
8 |
9 | for line in f:
10 | test_password = find_variations(test_password)
11 | if line.strip() == test_password.strip():
12 | in_dictionary = True
13 | print("Password match found: ", line.strip())
14 | break
15 |
16 | if not in_dictionary:
17 | print("Password not found... in this dictionary attack")
18 |
19 | # For extension project only:
20 | # Check and convert common letter-to-number substitutions
21 | def find_variations(password):
22 | password = password.replace("1", "l")
23 | password = password.replace("!", "i")
24 | password = password.replace("2", "z")
25 | password = password.replace("3", "e")
26 | password = password.replace("@", "a")
27 | password = password.replace("4", "a")
28 | password = password.replace("$", "s")
29 | password = password.replace("5", "s")
30 | password = password.replace("6", "g")
31 | password = password.replace("7", "t")
32 | password = password.replace("8", "b")
33 | password = password.replace("9", "g")
34 | password = password.replace("0", "o")
35 | return password
36 |
37 | if __name__ == '__main__':
38 | main()
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/README.md:
--------------------------------------------------------------------------------
1 | # Unit 2.3: Data
2 |
3 | ## Table of Contents
4 |
5 | ### Projects:
6 |
7 | 1. [Survey Project](SurveyProject)
8 | * This project is used in U2L9.
9 | * Students learn how to get and process data from a survey they create.
10 | 1. [Twitter Data Code-Along](TwitterDataCodeAlong)
11 | * This project is used in U2L9.
12 | * Students learn how to process data from twitter.
13 | 1. [Data Visualization Project](DataVisualizationProject)
14 | * This project is used in U2L10.
15 | * Students learn how to make visualizations with data.
16 | 1. [Data Scientist for a Day](DataScientist)
17 | * This project is used in U2L11.
18 | * Students learn how to draw conclusions from data by asking a question.
19 | 1. [Dictionary Attack](DictionaryAttack)
20 | * This project is used in U2L12.
21 | * Students learn how to check whether a password could withstand a dictionary attack.
22 |
23 |
24 | ### Tools:
25 |
26 | 1. [Tweet Processing](TweetProcessing)
27 | * This is sample code of how to download data from Twitter.
28 | * This can be used to customize what data students use for U2L10.
29 | 1. [Twitter Data](TwitterData)
30 | * This is sample data for the [Twitter Code Along](TwitterDataCodeAlong) and [Data Visualization Project](DataVisualizationProject).
31 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/README.md:
--------------------------------------------------------------------------------
1 | # Survey Project
2 |
3 | To run on Mac: python3 surveyproject_pt1.py
4 |
5 | To run on Windows: python surveyproject_pt1.py
6 |
7 | ### Part 1: Gather One response
8 | This program gets one response to a survey and stores the answer as a dictionary.
9 |
10 | ### Part 2: Gather Multiple Responses
11 | This program gets multiple responses and stores them as a list of dictionaries.
12 |
13 | ### Part 3: Save the responses
14 | This program adds responses that are captured to an existing json file.
15 |
16 | ### Part 4: Analyze the data
17 | This program loads the json file and completes a simple analysis of the data.
18 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/allanswers.json:
--------------------------------------------------------------------------------
1 | [
2 | {"DOB": "1999", "hometown": "bridgeport", "age": "30", "name": "Diana"},
3 | {"DOB": "", "hometown": "", "age": "26", "name": "Alisa"},
4 | {"DOB": "", "hometown": "60", "age": "40", "name": "Megan"},
5 | {"DOB": "", "hometown": "", "age": "", "name": "megan"},
6 | {"DOB": "", "hometown": "", "age": "", "name": "claire"},
7 | {"DOB": "", "hometown": "", "age": "", "name": "diana"}
8 | ]
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/surveyproject_pt1.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we iterate over a list of survey questions and save
3 | the responses in a dictionary with a related, easier to read key that
4 | corresponds with each question.
5 |
6 | For students who finish this part of the program quickly, a student might
7 | extend the program to catch invalid or blank responses.
8 | '''
9 |
10 |
11 |
12 | # Create the dictionary to store the responses.
13 | answers = {}
14 |
15 | # Create a list of survey questions and a list of related keys that will be used when storing survey results.
16 | survey = [
17 | "What is your name?",
18 | "How old are you?",
19 | "What is your hometown?",
20 | "What is your date of birth? (DD/MM/YYYY)"]
21 | keys = ["name", "age", "hometown", "DOB"]
22 |
23 | # Iterate over the list of survey questions and take in user responses.
24 | for x in range(len(survey)):
25 | response = raw_input(survey[x] +": ")
26 | answers[keys[x]] = response
27 |
28 | # Print the entire dictionary.
29 | print(answers)
30 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/surveyproject_pt2.py:
--------------------------------------------------------------------------------
1 | '''
2 | This program expands the previous program by looping continuously over the
3 | questions in the survey until the user says they are done collecting responses.
4 | Each individual response is a dictionary, and the set of all responses is saved
5 | as a list of dictionaries.
6 |
7 | For students who finish this part of the program quickly, encourage students to
8 | practice iterating over the list of dictionaries and gathering different pieces of the data.
9 | They might also choose to create a way for the user to quit providing input, or revise
10 | past answers.
11 | '''
12 |
13 |
14 | # Create a list of survey questions and a list of related keys that will be used when storing survey results.
15 | survey = [
16 | "What is your name?",
17 | "How old are you?",
18 | "What is your hometown?",
19 | "What is your date of birth? (DD/MM/YYYY)"]
20 | keys = ["name", "age", "hometown", "DOB"]
21 |
22 | # Create a list that will store each person's individual survey responses.
23 | list_of_answers = []
24 |
25 | done = "NO"
26 | while done == "NO":
27 |
28 | # Create the dictionary to store the responses.
29 | answers = {}
30 | print("New entry! Please answer the questions below.")
31 |
32 | # Iterate over the list of survey questions and take in user responses.
33 | for x in range(len(survey)):
34 | response = raw_input(survey[x] +": ")
35 | answers[keys[x]] = response
36 |
37 | list_of_answers.append(answers)
38 |
39 | done = raw_input("Are you done collecting information? Type YES or NO. ").upper()
40 |
41 | # Print the list of dictionaries.
42 | print(list_of_answers)
43 |
44 | # Example of how to iterate over the list of dictionaries and pull out particular pieces of information.
45 | names = []
46 | for s in range(len(list_of_answers)):
47 | names.append(list_of_answers[s]["name"])
48 | print(names)
49 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/surveyproject_pt3.py:
--------------------------------------------------------------------------------
1 | '''
2 | This program expands the previous program by saving any new data to an existing
3 | JSON file. This requires file i/o commands, as well as parsing the data to save
4 | the responses as a correctly formatted file.
5 |
6 | If students finish this section quickly, encourage them to define functions to make
7 | their program more modular and might allow them to reuse pieces of the code later.
8 | '''
9 | import json
10 |
11 | # Create a list of survey questions and a list of related keys that will be used when storing survey results.
12 | survey = [
13 | "What is your name?",
14 | "How old are you?",
15 | "What is your hometown?",
16 | "What is your date of birth? (DD/MM/YYYY)"]
17 |
18 | keys = ["name", "age", "hometown", "DOB"]
19 |
20 | # Create a list that will store each person's survey responses as a separate dictionary.
21 | list_of_answers = []
22 |
23 | # Continue to create new entries until the user exits.
24 | done = "NO"
25 | while done == "NO":
26 |
27 | # Create the dictionary to store the responses.
28 | answers = {}
29 | print("New entry! Please answer the questions below.")
30 |
31 | # Iterate over the list of survey questions and take in user responses.
32 | for x in range(len(survey)):
33 | response = raw_input(survey[x] +": ")
34 | answers[keys[x]] = response
35 |
36 | list_of_answers.append(answers)
37 | done = raw_input("\nAre you done collecting information? Type YES or NO. ")
38 |
39 | # Open the file containing all past results and append them to our current list.
40 | f = open("allanswers.json", "r")
41 | olddata = json.load(f)
42 | list_of_answers.extend(olddata)
43 | f.close()
44 |
45 | # Reopen the file in write mode and write each entry in json format.
46 | f = open("allanswers.json", "w")
47 | f.write('[\n')
48 | index = 0
49 | for t in list_of_answers:
50 | if (index < len(list_of_answers)-1):
51 | json.dump(t, f)
52 | f.write(',\n')
53 | else:
54 | json.dump(t, f)
55 | f.write('\n')
56 | index += 1
57 |
58 | f.write(']')
59 | f.close()
60 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/SurveyProject/surveyproject_pt4.py:
--------------------------------------------------------------------------------
1 | '''
2 | This program loads survey data that is saved in a JSON file and does some simple analysis
3 | of the data.
4 | '''
5 |
6 | import json
7 | from pprint import pprint
8 |
9 |
10 | # Open a json file and append entries to the file.
11 | f = open("allanswers.json", "r")
12 | data = json.load(f)
13 | print(type(data))
14 | print(data)
15 | f.close()
16 |
17 | '''
18 | Do some analysis with your data.
19 | You can do whatever you choose, but this code calculates
20 | the average age of people in your data set.
21 | '''
22 |
23 | # Example of how to iterate over the list of dictionaries and pull out particular pieces of information.
24 | ages = []
25 | for s in range(len(data)):
26 | if data[s]['age'] is not '': # Catches and skips over blank entries.
27 | ages.append(int(data[s]['age']))
28 |
29 | print(ages)
30 | total = sum(ages)
31 | average = total/len(ages)
32 |
33 | print(average)
34 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/TweetProcessing/README.md:
--------------------------------------------------------------------------------
1 | # Tweet Processing
2 |
3 | * `tweet-scraper.py` - This file pulls tweets about automation from Twitter using the python-twitter library.
4 | * You will need to create a file called "credentials" to run this script.
5 |
6 | * `tweets.json` - This file contains a list of JSON-formatted tweets about automation.
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/TweetProcessing/tweet-scraper.py:
--------------------------------------------------------------------------------
1 | import twitter
2 | import json
3 | import sys
4 |
5 | # Read keys and secrets from separate credentials file
6 | credentials_file = open("credentials", "r")
7 |
8 | consumer_key = credentials_file.readline().rstrip()
9 | consumer_secret = credentials_file.readline().rstrip()
10 | access_token_key = credentials_file.readline().rstrip()
11 | access_token_secret = credentials_file.readline().rstrip()
12 |
13 | # Create an API instance using the credentials
14 | api = twitter.Api(consumer_key=consumer_key,
15 | consumer_secret=consumer_secret,
16 | access_token_key=access_token_key,
17 | access_token_secret=access_token_secret)
18 |
19 | # Get a batch of tweets
20 | try:
21 | tweets = api.GetSearch(term="automation", count=100)
22 | except twitter.error.TwitterError as e:
23 | print("Could not make initial query.")
24 | print(e)
25 | sys.exit()
26 |
27 | # Get as many tweets as you can before hitting your rate limit
28 | oldest = tweets[-1].id
29 | rounds = 0
30 | hitRateLimit = False
31 | while hitRateLimit == False:
32 | try:
33 | data = api.GetSearch(term="automation", count=100, max_id=oldest)
34 | tweets.extend(data)
35 | oldest = data[-1].id
36 | rounds += 1
37 | except twitter.error.TwitterError as e:
38 | print("Requests made: " + str(rounds))
39 | print(e)
40 | hitRateLimit = True
41 | pass
42 |
43 | # Open a file to write results to
44 | f = open('tweets.json', 'w')
45 |
46 | f.write('[\n')
47 | index = 0
48 | for t in tweets:
49 | if (index < len(tweets)-1):
50 | f.write(t.AsJsonString() + ',\n')
51 | else:
52 | f.write(t.AsJsonString() + '\n')
53 | index += 1
54 |
55 | f.write(']')
56 | f.close()
57 |
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/TwitterData/README.md:
--------------------------------------------------------------------------------
1 | # Twitter Data
2 |
3 | This file contains sample Twitter data, to be used for the Twitter Code Along and Data Visualization Project.
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/TwitterDataCodeAlong/Readme.md:
--------------------------------------------------------------------------------
1 | # Twitter Data Code Along
2 |
3 | To run on Mac: `python3 twitter_data_code_along.py`
4 |
5 | To run on Windows: `python twitter_data_code_along.py`
6 |
7 | 1. Get Twitter Data at [../TwitterData/tweets_small.json](../TwitterData/tweets_small.json).
8 | * Copy this file to your project folder.
9 | 1. Read all the comments
10 | * The comments are the guides to explain each step to the students.
11 | 1. Do the code along with students
12 | * Remember to read the comments or explain what's in the comments as you code along. We want students to come away knowing that information!
--------------------------------------------------------------------------------
/U2-Applications/U2.1-Data/TwitterDataCodeAlong/twitter_data_code_along.py:
--------------------------------------------------------------------------------
1 | '''
2 | In this program, we print out all the text data from our twitter JSON file.
3 |
4 | Please explain the comments to students as you code.
5 | '''
6 |
7 | # We start by importing the JSON library to use for this project.
8 | # Twitter data is stored in this format - this is the same format
9 | # students learned for their Survey Project!
10 | import json
11 |
12 | # Next we want to open the JSON file. We tag this file as
13 | # "r" read only because we are only going to look at the data.
14 | tweetFile = open("../TwitterData/tweets_small.json", "r")
15 |
16 | # We use the JSON library to get data from the file as JSON data.
17 | tweetData = json.load(tweetFile)
18 |
19 | # We can close the file now that we have locally stored the data.
20 | tweetFile.close()
21 |
22 | # We then print the data of ONE tweet:
23 | # the [0] denotes the *first* tweet object.
24 | # We access parts of the tweet using ["NameOfPart"].
25 | print("Tweet id: ", tweetData[0]["id"])
26 |
27 | # First ask students how they might print the text object:
28 | # Then show them the following code
29 | print("Tweet text: ", tweetData[0]["text"])
30 |
31 |
32 | # First ask students how might they use loops
33 | # to print the ["text"] of all the tweets:
34 |
35 | # Show them the following two options:
36 |
37 | # Explain how here, we're using index and
38 | # counting the number of tweets in the tweetData
39 | # using the python len() function.
40 | for idx in range(len(tweetData)):
41 | print("Tweet text: " + tweetData[idx]["text"])
42 |
43 | # Explain here how Python lets you get objects
44 | # directly without having to use an index.
45 | for tweet in tweetData:
46 | print("Tweet text: " + tweet["text"])
47 |
48 | # Encourage students to think about how there are
49 | # often multiple solutions for each problem, and
50 | # how each solution might have strenghts and drawbacks.
51 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/BuildAWebPage/README.md:
--------------------------------------------------------------------------------
1 | # HTML/CSS Portfolio Page
2 |
3 | To run: Open `hello.html` in your favorite browser.
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/BuildAWebPage/contact.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | About Me
7 |
8 |
9 |
I am a girl who codes from Sumware, CA. I will be in the 12th grade in the fall, and I am looking forward to applying to colleges. I live at home with my mom, my brother, and my cat named Seymore. When I'm not coding, you can find me listening to music with my friends or reading.
20 |
21 |
22 |
23 | Likes: I love a great science fiction novel. Right now I am reading The Three Body Problem, by Cixin Liu.
24 | Dislikes: I really don't like fish. They have dead eyes that freak me out!
25 |
26 |
27 |
28 | Fun Fact: So far, I've been to 4 different continents! I can't wait to see the others.
29 |
30 |
31 |
32 |
Favorite Websites:
33 |
34 |
New York Times: I like to stay up to date, and to do the crosswords!
Tumblr: I love the pictures that people I follow post.
37 |
38 |
39 |
40 |
41 |
Recent Projects:
42 |
Side Scroller Project:
43 |
44 | Last week, I build a cool side scroller project in Scratch. To build it, I learned about storyboarding, graphic design and using the concepts of functions, loops, conditionals, and variables. Check out the screenshot below!
45 |
I am a girl who codes from Sumware, CA. I will be in the 12th grade in the fall, and I am looking forward to applying to colleges. I live at home with my mom, my brother, and my cat named Seymore. When I'm not coding, you can find me listening to music with my friends or reading.
24 |
25 |
26 |
27 | Likes: I love a great science fiction novel. Right now I am reading The Three Body Problem, by Cixin Liu.
28 | Dislikes: I really don't like fish. They have dead eyes that freak me out!
29 |
30 |
31 |
32 | Fun Fact: So far, I've been to 4 different continents! I can't wait to see the others.
33 |
34 |
35 |
36 |
Favorite Websites:
37 |
38 |
New York Times: I like to stay up to date, and to do the crosswords!
Tumblr: I love the pictures that people I follow post.
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
Recent Projects:
49 |
Side Scroller Project:
50 |
51 | Last week, I build a cool side scroller project in Scratch. To build it, I learned about storyboarding, graphic design and using the concepts of functions, loops, conditionals, and variables. Check out the screenshot below!
52 |
Last week, I build a cool side scroller project in Scratch. To build it, I learned about storyboarding, graphic design and using the concepts of functions, loops, conditionals, and variables. Check out the screenshot below!
';
33 | imgID = 1;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/JavaScriptAndAccessibility/side-scrolling-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.2-Web-Development/JavaScriptAndAccessibility/side-scrolling-screenshot.png
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/JavaScriptAndAccessibility/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: mintcream;
3 | color: teal;
4 | font-family: 'Open Sans Condensed', sans-serif;
5 | margin: 10px 20px 10px 20px;
6 | }
7 |
8 | h1 {
9 | color: lightseagreen;
10 | font-size: 36px;
11 | }
12 |
13 | p, li {
14 | font-size: 20px;
15 | }
16 |
17 | a {
18 | color: lightseagreen;
19 | }
20 |
21 | #header {
22 | border: 2px solid teal;
23 | padding: 20px;
24 | font-size: 50px;
25 | font-weight: bold;
26 | }
27 |
28 | #navigation a {
29 | float: right;
30 | text-align: center;
31 | padding: 15px;
32 | font-size: 30px;
33 | text-decoration: none;
34 | }
35 |
36 | #profile-pic {
37 | height: 70px;
38 | vertical-align: middle;
39 | }
40 |
41 | .content {
42 | padding: 15px 50px 15px 50px;
43 | }
44 |
45 | #bio {
46 | border-bottom: 1px solid teal;
47 | }
48 |
49 | #scratch-project {
50 | width: 700px;
51 | }
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/README.md:
--------------------------------------------------------------------------------
1 | # Unit 2.2: Web Development
2 |
3 | ## Table of Contents
4 |
5 | ### Projects:
6 |
7 | 1. [Build A Web Page](BuildAWebPage)
8 | * This project is used in U2L5.
9 | * Students learn how to build a basic web page using HTML and CSS.
10 | 1. [Introduction to JavaScript and Accessibility](JavaScriptAndAccessibility)
11 | * This project is used in U2L6.
12 | * Students learn how to build accessibility features for a website.
13 | 1. [Use An API](UseAnAPI)
14 | * This project is used in U2L7.
15 | * Students learn how to use an API to create a feature. One API is a JavaScript extension; the other API is a REST API that uses HTTP requests to get data.
16 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/README.md:
--------------------------------------------------------------------------------
1 | # Map and Weather API Page
2 |
3 | This is a multi-part code along. Each part starts with the map_part_*.html file.
4 |
5 | Start by opening the map_part0_startercode.html file. Each file will have ordered steps and explanations.
6 |
7 | 1. [map_part1_setup_API.html](map_part1_setup_API.html)
8 | * We are going to start by setting up our API.
9 | 1. [map_part2_setup_script.html](map_part2_setup_script.html)
10 | * We are going to set up our JavaScript.
11 | 1. [map_part3_animate_view.html](map_part3_animate_view.html)
12 | * Now we are going to try to create a button that animates the map!
13 | 1. [map_part4_input_a_country.html](map_part4_input_a_country.html)
14 | * Now we are going to create in input so people can select the country to pan to!
15 | 1. [map_part5_get_country_information.html](map_part5_get_country_information.html)
16 | * Now we are going to use an HTTP GET request to find information about the input country.
17 | 1. [map_part6_get_the_lon_and_lat.html](map_part6_get_the_lon_and_lat.html)
18 | * Now we are going to parse our data to get the longitude and lattitude.
19 | 1. [map_part7_make_call_asynchronous.html](map_part7_make_call_asynchronous.html)
20 | * Now we are going to make the call asynchronous.
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Weather Map
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part0_startercode.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Weather Map
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part1_setup_API.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 |
11 |
12 | Weather Map
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part2_setup_script.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Weather Map
14 |
15 |
16 |
17 |
21 |
22 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part2_setup_script.js:
--------------------------------------------------------------------------------
1 | // Step 2: Ask students what kinds of information they need to start with:
2 | // -- Since this is a "Map API" - we probably need a map.
3 | // -- We also need to specify where to center the map!
4 | // Have the students go to Google and find out the
5 | // longitude and latitude of the SIP location.
6 | // -- In order to "see" the map and interact with it, we need
7 | // a view. A view is like a computer screen. The computer
8 | // can do processes without it, but we won't be able to see.
9 | var ourLoc;
10 | var view;
11 | var map;
12 |
13 | // Step 3: We should initalize our variables!
14 | function init() {
15 | // Initalize things here
16 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
17 |
18 | view = new ol.View({
19 | center: ourLoc,
20 | zoom: 6 // Students can play around with the starting zoom.
21 | });
22 |
23 | map = new ol.Map({
24 | target: 'map', // The "Target" is our
name.
25 | layers: [
26 | new ol.layer.Tile({
27 | source: new ol.source.OSM() // Explain: this is a required variable.
28 | })
29 | // Explain: Open Layer offers different types of layers. Layers are like
30 | // different brushes used to make the same image. They look different.
31 | // Some might take more time than others.
32 | ],
33 | // Note from the View Animation website:
34 | // Improve user experience by loading tiles while animating. Will make
35 | // animations stutter on mobile or slow devices.
36 | loadTilesWhileAnimating: true,
37 | view: view
38 | });
39 | }
40 |
41 | // Step 4: We can run the init function when the window loads.
42 | window.onload = init;
43 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part3_animate_view.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Weather Map
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part3_animate_view.js:
--------------------------------------------------------------------------------
1 | var ourLoc;
2 | var view;
3 | var map;
4 |
5 | function init() {
6 | // Initalize things here
7 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
8 |
9 | view = new ol.View({
10 | center: ourLoc,
11 | zoom: 6
12 | });
13 |
14 | map = new ol.Map({
15 | target: 'map',
16 | layers: [
17 | new ol.layer.Tile({
18 | source: new ol.source.OSM()
19 | })
20 | ],
21 | // Note from the View Animation website:
22 | // Improve user experience by loading tiles while animating. Will make
23 | // animations stutter on mobile or slow devices.
24 | loadTilesWhileAnimating: true,
25 | view: view
26 | });
27 | }
28 |
29 | // Step 2: Let's make our button do something!
30 | // We use "animate" on the view to animate it.
31 | // To pan the view, we simply need to tell the view
32 | // where to go and how long to take to get there.
33 | function panHome() {
34 | view.animate({
35 | center: ourLoc, // "Home" Location
36 | duration: 2000 // Two seconds
37 | });
38 | }
39 |
40 | // Final Step: Now ask the students how they might
41 | // let someone move the map to a particular
42 | // city or location. Would they have the
43 | // user input longitude/latitude, or is it
44 | // easier for them to use a name of a city?
45 | // To use the name of a city, we need
46 | // another API!
47 |
48 | window.onload = init;
49 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part4_input_a_country.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Weather Map
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part4_input_a_country.js:
--------------------------------------------------------------------------------
1 | var ourLoc;
2 | var view;
3 | var map;
4 |
5 | function init() {
6 | // Initalize things here
7 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
8 |
9 | view = new ol.View({
10 | center: ourLoc,
11 | zoom: 6
12 | });
13 |
14 | map = new ol.Map({
15 | target: 'map',
16 | layers: [
17 | new ol.layer.Tile({
18 | source: new ol.source.OSM()
19 | })
20 | ],
21 | // Note from the View Animation website:
22 | // Improve user experience by loading tiles while animating. Will make
23 | // animations stutter on mobile or slow devices.
24 | loadTilesWhileAnimating: true,
25 | view: view
26 | });
27 | }
28 |
29 | function panHome() {
30 | view.animate({
31 | center: ourLoc, // "Home" Location
32 | duration: 2000 // Two seconds
33 | });
34 | }
35 |
36 |
37 | // Step 2: Create the panToLocation function.
38 | function panToLocation() {
39 | // Step 2: add the basic values we know we'll need
40 | var countryName = document.getElementById("country-name").value;
41 |
42 | // Step 4: Let's add an error check to make sure
43 | // the person has typed something in.
44 | if(countryName === "") {
45 | alert("You didn't enter a country name!");
46 | return;
47 | }
48 |
49 | // Step 3: Let's find our country's longitude and latitude!
50 | // Ask the students to find the documentation where they can
51 | // search / query for a location's information!
52 | // Once you write this, pause and ask students what next?
53 | // How do we get information from this URL. Right now it's
54 | // just a url...
55 | var query = "https://restcountries.eu/rest/v2/name/"+countryName;
56 |
57 | // Step 2: Add the conversion from longitude and latitude
58 | // that we used for our home location!
59 | var lon = 0.0;
60 | var lat = 0.0;
61 | var location = ol.proj.fromLonLat([lon, lat]);
62 |
63 | // Step 2: Add the animation that we used in panHome
64 | // and swap out what we pan to! Stop here and run the code.
65 | // When it errors, ask the students what they think happened.
66 | // Direct them to think about the 0, 0 of longitude and latitude
67 | view.animate({
68 | center: location, // Location
69 | duration: 2000 // Two seconds
70 | });
71 | }
72 |
73 | window.onload = init;
74 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part5_get_country_information.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Weather Map
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part5_get_country_information.js:
--------------------------------------------------------------------------------
1 | var ourLoc;
2 | var view;
3 | var map;
4 |
5 | function init() {
6 | // Initalize things here
7 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
8 |
9 | view = new ol.View({
10 | center: ourLoc,
11 | zoom: 6
12 | });
13 |
14 | map = new ol.Map({
15 | target: 'map',
16 | layers: [
17 | new ol.layer.Tile({
18 | source: new ol.source.OSM()
19 | })
20 | ],
21 | // Note from the View Animation website:
22 | // Improve user experience by loading tiles while animating. Will make
23 | // animations stutter on mobile or slow devices.
24 | loadTilesWhileAnimating: true,
25 | view: view
26 | });
27 | }
28 |
29 | function panHome() {
30 | view.animate({
31 | center: ourLoc, // "Home" Location
32 | duration: 2000 // Two seconds
33 | });
34 | }
35 |
36 | function panToCountry() {
37 | var countryName = document.getElementById("country-name").value;
38 | var lon = 0.0;
39 | var lat = 0.0;
40 |
41 | var query = "https://restcountries.eu/rest/v2/name/"+countryName
42 | // Step 3: Let's do some error checks and input modification
43 | // Explain: When we make requests in a browser, we want to
44 | // replace spaces with %20.
45 | query = query.replace(/ /g, "%20")
46 | alert(query);
47 |
48 | // Step 1: Let's start by making an HTTP GET request:
49 | var countryRequest = new XMLHttpRequest();
50 | countryRequest.open('GET', query, false);
51 |
52 | // Step 2: Send the request and see the output:
53 | countryRequest.send();
54 |
55 | alert("Ready State " + countryRequest.readyState);
56 | alert("Status " + countryRequest.status);
57 | alert("Response" + countryRequest.responseText);
58 |
59 | var location = ol.proj.fromLonLat([lon, lat]);
60 |
61 | // Note: If you run into an error like window
62 | // not loading, check that you declared VAR
63 | // before the location variable.
64 |
65 | view.animate({
66 | center: location, // Location
67 | duration: 2000 // Two seconds
68 | });
69 | }
70 |
71 | window.onload = init;
72 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part6_get_the_lon_and_lat.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Weather Map
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part6_get_the_lon_and_lat.js:
--------------------------------------------------------------------------------
1 | var ourLoc;
2 | var view;
3 | var map;
4 |
5 | function init() {
6 | // Initalize things here
7 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
8 |
9 | view = new ol.View({
10 | center: ourLoc,
11 | zoom: 6
12 | });
13 |
14 | map = new ol.Map({
15 | target: 'map',
16 | layers: [
17 | new ol.layer.Tile({
18 | source: new ol.source.OSM()
19 | })
20 | ],
21 | // Note from the View Animation website:
22 | // Improve user experience by loading tiles while animating. Will make
23 | // animations stutter on mobile or slow devices.
24 | loadTilesWhileAnimating: true,
25 | view: view
26 | });
27 | }
28 |
29 | function panHome() {
30 | view.animate({
31 | center: ourLoc, // "Home" Location
32 | duration: 2000 // Two seconds
33 | });
34 | }
35 |
36 | function panToCountry() {
37 | var countryName = document.getElementById("country-name").value;
38 |
39 | if(countryName === "") {
40 | alert("You didn't enter a country name!");
41 | return;
42 | }
43 |
44 | var query = "https://restcountries.eu/rest/v2/name/"+countryName+"?fullText=true"
45 |
46 | query = query.replace(/ /g, "%20")
47 |
48 | var countryRequest = new XMLHttpRequest();
49 | countryRequest.open('GET', query, false);
50 |
51 | countryRequest.send();
52 |
53 | //window.console.log("Ready State " + countryRequest.readyState);
54 | //window.console.log("Status " + countryRequest.status);
55 | //window.console.log("Response" + countryRequest.responseText);
56 |
57 | // Step 1: First we should only pan if the information was correct:
58 | if(countryRequest.readyState != 4 || countryRequest.status != 200 || countryRequest.responseText === "") {
59 | window.console.error("Request had an error!");
60 | return;
61 | }
62 |
63 | // Step 2: Let's copy this output into a text file and
64 | // see where the latitude and longitude live
65 | // We need to convert this to JSON using the JSON.parse
66 | // function in order to use the data.
67 | //window.console.log(countryRequest.responseText);
68 | var countryInformation = JSON.parse(countryRequest.responseText);
69 |
70 | // Step 3: We have to figure out where the information is based
71 | // on the JSON we got back. This can be very tricky sometimes.
72 | // For instance, this JSON returns an ARRAY of information.
73 | // Inside the FIRST array element, we have our latlng variable.
74 | // This variable has the information we need!
75 | var lat = countryInformation[0].latlng[0];
76 | var lon = countryInformation[0].latlng[1];
77 |
78 | // Note: If you run into an error like the map
79 | // disappearing, check that you have your
80 | // longtidue and latitude variables mapped
81 | // to the right indexes. Lon is index 1,
82 | // lat is index 0.
83 | window.console.log(countryName + ": lon " + lon + " & lat " + lat);
84 |
85 | var location = ol.proj.fromLonLat([lon, lat]);
86 |
87 | // Note: If you run into an error like window
88 | // not loading, check that you declared VAR
89 | // before the location variable.
90 |
91 | view.animate({
92 | center: location, // Location
93 | duration: 2000 // Two seconds
94 | });
95 | }
96 |
97 | window.onload = init;
98 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part7_make_call_asynchronous.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Weather Map
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/U2-Applications/U2.2-Web-Development/UseAnAPI/map_part7_make_call_asynchronous.js:
--------------------------------------------------------------------------------
1 | var ourLoc;
2 | var view;
3 | var map;
4 |
5 | function init() {
6 | // Initalize things here
7 | ourLoc = ol.proj.fromLonLat([41.043316, 28.862457]);
8 |
9 | view = new ol.View({
10 | center: ourLoc,
11 | zoom: 6
12 | });
13 |
14 | map = new ol.Map({
15 | target: 'map',
16 | layers: [
17 | new ol.layer.Tile({
18 | source: new ol.source.OSM()
19 | })
20 | ],
21 | // Note from the View Animation website:
22 | // Improve user experience by loading tiles while animating. Will make
23 | // animations stutter on mobile or slow devices.
24 | loadTilesWhileAnimating: true,
25 | view: view
26 | });
27 | }
28 |
29 | function panHome() {
30 | view.animate({
31 | center: ourLoc, // "Home" Location
32 | duration: 2000 // Two seconds
33 | });
34 | }
35 |
36 | // Step 1: Make a new function with this name.
37 | // Copy from the Pan To Location function:
38 | // countryName, query, countryRequest
39 | // countryRequest.open()
40 | // countryRequest.send()
41 | function makeCountryRequest() {
42 | var countryName = document.getElementById("country-name").value;
43 |
44 | if(countryName === "") {
45 | alert("You didn't enter a country name!");
46 | return;
47 | }
48 |
49 | var query = "https://restcountries.eu/rest/v2/name/"+countryName+"?fullText=true"
50 |
51 | query = query.replace(/ /g, "%20")
52 |
53 | countryRequest = new XMLHttpRequest();
54 |
55 | // Step 1: Switch this last condition to TRUE
56 | // This changes the call from synchronous to
57 | // an asynchronous call.
58 | countryRequest.open('GET', query, true);
59 |
60 | // Step 2: Add an onload function to process
61 | // what happens when we send the HTTP Request.
62 | countryRequest.onload = processCountryRequest
63 |
64 | countryRequest.send();
65 | }
66 |
67 | function processCountryRequest() {
68 | // Step 3: In the onload function, we wait
69 | // until the request is complete.
70 | if(countryRequest.readyState != 4) {
71 | return;
72 | }
73 |
74 | // Step 4: Once the request is completed,
75 | // We look for errors.
76 | if (countryRequest.status != 200 || countryRequest.responseText === "") {
77 | alert("We were unable to find your requested country!");
78 | return;
79 | }
80 |
81 |
82 | // Step 5: Now that the errors are gone, we add
83 | // in what happens when the request succeeds.
84 | var countryInformation = JSON.parse(countryRequest.responseText);
85 | var lon = countryInformation[0].latlng[1];
86 | var lat = countryInformation[0].latlng[0];
87 |
88 | // Note: If you run into an error like the map
89 | // disappearing, check that you have your
90 | // longtidue and latitude variables mapped
91 | // to the right indexes. Lon is index 1,
92 | // lat is index 0.
93 | //window.console.log("lon " + lon + " & lat " + lat);
94 |
95 | var location = ol.proj.fromLonLat([lon, lat]);
96 |
97 | // Note: If you run into an error like window
98 | // not loading, check that you declared VAR
99 | // before the location variable.
100 | //window.console.log("location " + location);
101 |
102 | view.animate({
103 | center: location, // Location
104 | duration: 2000 // Two seconds
105 | });
106 | }
107 |
108 | window.onload = init;
109 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/BuildACircuit/BuildACircuit.ino:
--------------------------------------------------------------------------------
1 |
2 | int piezo = A0;
3 |
4 | int sensorReading = 0;
5 | int threshold = 10;
6 |
7 | void setup() {
8 | // put your setup code here, to run once:
9 | Serial.begin(9600);
10 | }
11 |
12 | void loop() {
13 | // put your main code here, to run repeatedly:
14 | sensorReading = analogRead(piezo);
15 |
16 | Serial.println(sensorReading);
17 |
18 | if (sensorReading <= threshold) {
19 | Serial.println("Knock!");
20 | delay(1000);
21 | }
22 |
23 | delay(100);
24 | }
25 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/BuildACircuit/README.md:
--------------------------------------------------------------------------------
1 | # Build a Circuit
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program uses a piezo speaker as an analog input. When the user taps the piezo, a message gets printed to the console.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/README.md:
--------------------------------------------------------------------------------
1 | # Circuits
2 |
3 | These are circuit diagrams for the different inputs used in U2L3.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/input-irreceiver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.3-Robotics/Circuits/input-irreceiver.png
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/input-phototransistor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.3-Robotics/Circuits/input-phototransistor.png
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/input-piezo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.3-Robotics/Circuits/input-piezo.png
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/input-pushbutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.3-Robotics/Circuits/input-pushbutton.png
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/Circuits/input-whisker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GirlsFirst/SIP-2018/0f851f6c251bf7ed1b6f47310fbf4bb25bbd4727/U2-Applications/U2.3-Robotics/Circuits/input-whisker.png
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/CodeExamples/BooleanOperators/BooleanOperators.ino:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | int sensor1 = 3;
6 | int sensor2 = 4;
7 |
8 | void setup() {
9 | // put your setup code here, to run once:
10 | Serial.begin(9600); // use the serial port
11 |
12 | pinMode(sensor1, INPUT);
13 | pinMode(sensor2, INPUT);
14 | }
15 |
16 | void loop() {
17 | if(digitalRead(sensor1) == HIGH && digitalRead(sensor2) == HIGH) {
18 | Serial.println("Both sensors are being sensed!");
19 | }
20 | if(digitalRead(sensor1) == HIGH || digitalRead(sensor2) == HIGH) {
21 | Serial.println("At least one sensors is being sensed!");
22 | }
23 | if(!(digitalRead(sensor1) == HIGH)) {
24 | Serial.println("Sensor1 is not being sensed!");
25 | }
26 |
27 | delay(100);
28 | }
29 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/CodeExamples/Conditionals/Conditionals.ino:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | int aNumber;
6 |
7 | void setup() {
8 | // put your setup code here, to run once:
9 | Serial.begin(9600); // use the serial port
10 | aNumber = 0;
11 | }
12 |
13 | void loop() {
14 | if(aNumber < 5) {
15 | Serial.println("a number is less than five");
16 | } else if(aNumber == 5) {
17 | Serial.println("a number is five");
18 | } else {
19 | Serial.println("a number more than five");
20 | }
21 | aNumber = aNumber + 1;
22 | }
23 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/CodeExamples/README.md:
--------------------------------------------------------------------------------
1 | # Code Examples
2 |
3 | These files include the code snippets that are shown on the slides in U2L3.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/CodeExamples/analogRead/analogRead.ino:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | int aAnalogPin = A0;
6 |
7 | void setup() {
8 | // put your setup code here, to run once:
9 | }
10 |
11 | void loop() {
12 | int aValue = analogRead(aAnalogPin);
13 | }
14 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/CodeExamples/digitalRead/digitalRead.ino:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | int aDigitalPin = 13;
6 |
7 | void setup() {
8 | // put your setup code here, to run once:
9 | pinMode(aDigitalPin, INPUT);
10 | }
11 |
12 | void loop() {
13 | int aValue = digitalRead(aDigitalPin);
14 | }
15 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/EscapeBot/EscapeBot.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int rightWhiskerPin = 7;
4 | int leftWhiskerPin = 5;
5 | int rightWhiskerState = 0;
6 | int leftWhiskerState = 0;
7 | Servo servoRight;
8 | Servo servoLeft;
9 |
10 | void setup() {
11 | // put your setup code here, to run once:
12 | //tone(4, 3000, 1000);
13 | delay(1000);
14 | pinMode(rightWhiskerPin, INPUT);
15 | pinMode(leftWhiskerPin, INPUT);
16 | Serial.begin(9600);
17 | servoLeft.attach(12);
18 | servoRight.attach(13);
19 | servoLeft.writeMicroseconds(1500);
20 | servoRight.writeMicroseconds(1300);
21 |
22 | }
23 |
24 | void loop() {
25 | // put your main code here, to run repeatedly:
26 | rightWhiskerState = digitalRead(rightWhiskerPin);
27 | leftWhiskerState = digitalRead(leftWhiskerPin);
28 | // whisker state is 1 if unpressed and 0 if pressed.
29 | if(rightWhiskerState == 0 && leftWhiskerState == 0){
30 | backward(1000);
31 | turnRight(800);
32 | }
33 | else if(leftWhiskerState == 0){
34 | backward(1000);
35 | turnRight(800);
36 | }
37 | else if(rightWhiskerState == 0){
38 | backward(1000);
39 | turnLeft(800);
40 | }
41 | else{
42 | forward(20);
43 | }
44 | }
45 |
46 | void stopnow(){
47 | servoLeft.writeMicroseconds(1500);
48 | servoRight.writeMicroseconds(1500);
49 | }
50 |
51 | void forward(int time) // Forward function
52 | {
53 | servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
54 | servoRight.writeMicroseconds(1300); // Right wheel clockwise
55 | delay(time); // Maneuver for time ms
56 | }
57 |
58 | void turnLeft(int time) // Left turn function
59 | {
60 | servoLeft.writeMicroseconds(1300); // Left wheel clockwise
61 | servoRight.writeMicroseconds(1300); // Right wheel clockwise
62 | delay(time); // Maneuver for time ms
63 | }
64 |
65 | void turnRight(int time) // Right turn function
66 | {
67 | servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
68 | servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
69 | delay(time); // Maneuver for time ms
70 | }
71 |
72 | void backward(int time) // Backward function
73 | {
74 | servoLeft.writeMicroseconds(1300); // Left wheel clockwise
75 | servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
76 | delay(time); // Maneuver for time ms
77 | }
78 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/EscapeBot/README.md:
--------------------------------------------------------------------------------
1 | # Escape Bot
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program uses whisker sensors to help a robot navigate its way out of a 3-walled box.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/HereKittyKitty/HereKittyKitty.ino:
--------------------------------------------------------------------------------
1 | // This version of the catbot uses the piezo as an input.
2 |
3 | #include // Include servo library
4 |
5 | Servo servoRight;
6 | Servo servoLeft;
7 | int piezo = A0;
8 |
9 | int sensorReading = 0;
10 | int threshold = 10;
11 |
12 | void moveKitty() {
13 | servoLeft.writeMicroseconds(1300);
14 | servoRight.writeMicroseconds(1700);
15 | }
16 |
17 | void stopKitty() {
18 | servoLeft.writeMicroseconds(1500);
19 | servoRight.writeMicroseconds(1500);
20 | }
21 |
22 | void setup() {
23 | // put your setup code here, to run once:
24 | servoLeft.attach(13); // Attach left signal to pin 13
25 | servoRight.attach(12); // Attach right signal to pin 12
26 | stopKitty();
27 |
28 | Serial.begin(9600); // use the serial port
29 | }
30 |
31 | void loop() {
32 | // put your main code here, to run repeatedly:
33 | sensorReading = analogRead(piezo);
34 |
35 | //Serial.println(sensorReading);
36 |
37 | if (sensorReading <= threshold) {
38 | moveKitty();
39 | Serial.println("You pet me! <3");
40 | delay(1000);
41 | }
42 | stopKitty();
43 | delay(100);
44 | }
45 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/HereKittyKitty/README.md:
--------------------------------------------------------------------------------
1 | # Here Kitty Kitty
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program uses a piezo as input to make a "catbot" move when the piezospeaker is tapped (knock sensor).
11 |
12 | **Notes:**
13 |
14 | * Student solutions may choose to use other sensors besides the piezo as an input.
15 | * You may need to calibrate your piezo, based on your resistor, by changing the threshold value.
16 | * Piezos require being plugged in positive/negative in a specific direction (like LEDs). Check out this resource for more information: [Piezo Guide](https://pubweb.eng.utah.edu/~cs5789/handouts/piezo.pdf).
17 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/LetThereBeLight-Pt2/LetThereBeLight-Pt2.ino:
--------------------------------------------------------------------------------
1 | // Let There Be Light: Part 2
2 |
3 | int pin = 10; // Make sure your circuit is using digital pin 10!
4 |
5 | void setup() {
6 | // put your setup code here, to run once:
7 | pinMode(pin, OUTPUT);
8 |
9 | }
10 |
11 | void loop() {
12 | // put your main code here, to run repeatedly:
13 |
14 | digitalWrite(pin, HIGH);
15 | delay(500);
16 | digitalWrite(pin, LOW);
17 | delay(500);
18 | }
19 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/LetThereBeLight-Pt2/README.md:
--------------------------------------------------------------------------------
1 | # Let There Be Light (Part 2)
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program makes an LED blink on and off forever.
11 |
12 | **Note:** The circuit on the breadboard needs to use digital pin 10 instead of 5V!
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/LetThereBeLight-Pt3/LetThereBeLight-Pt3.ino:
--------------------------------------------------------------------------------
1 | // Let There Be Light: Part 3
2 |
3 | int unit = 300;
4 | int pin = 10; // Make sure your circuit is using digital pin 10!
5 |
6 | void setup() {
7 | // put your setup code here, to run once:
8 | pinMode(pin, OUTPUT);
9 | }
10 |
11 | void loop() {
12 | // put your main code here, to run repeatedly:
13 |
14 | /*
15 | * Secret message: "GWC ROCKS."
16 | * Letters needed: C G K O R S W
17 | */
18 |
19 | // Spell out message:
20 | // "GWC "
21 | flashG();
22 | delay(unit * 3); // 3 units between each letter
23 | flashW();
24 | delay(unit * 3);
25 | flashC();
26 | flashSpace(); // 7 units between each word
27 |
28 | // "ROCKS. "
29 | flashR();
30 | delay(unit * 3);
31 | flashO();
32 | delay(unit * 3);
33 | flashC();
34 | delay(unit * 3);
35 | flashK();
36 | delay(unit * 3);
37 | flashS();
38 | delay(unit * 3);
39 | flashPeriod();
40 | flashSpace();
41 |
42 | }
43 |
44 | void dot() {
45 | digitalWrite(pin, HIGH);
46 | delay(unit);
47 | digitalWrite(pin, LOW);
48 | }
49 |
50 | void dash() {
51 | digitalWrite(pin, HIGH);
52 | delay(unit * 3);
53 | digitalWrite(pin, LOW);
54 | }
55 |
56 | // Functions to flash a specific letter
57 | void flashC() {
58 | // -.-.
59 | dash();
60 | delay(unit);
61 | dot();
62 | delay(unit);
63 | dash();
64 | delay(unit);
65 | dot();
66 | }
67 |
68 | void flashG() {
69 | // --.
70 | dash();
71 | delay(unit);
72 | dash();
73 | delay(unit);
74 | dot();
75 | }
76 |
77 | void flashK() {
78 | // -.-
79 | dash();
80 | delay(unit);
81 | dot();
82 | delay(unit);
83 | dash();
84 | }
85 |
86 | void flashO() {
87 | // ---
88 | dash();
89 | delay(unit);
90 | dash();
91 | delay(unit);
92 | dash();
93 | }
94 |
95 | void flashR() {
96 | // .-.
97 | dot();
98 | delay(unit);
99 | dash();
100 | delay(unit);
101 | dot();
102 | }
103 |
104 | void flashS() {
105 | // ...
106 | dot();
107 | delay(unit);
108 | dot();
109 | delay(unit);
110 | dot();
111 | }
112 |
113 | void flashW() {
114 | // .--
115 | dot();
116 | delay(unit);
117 | dash();
118 | delay(unit);
119 | dash();
120 | }
121 |
122 | void flashSpace() {
123 | // 7 units
124 | delay(unit * 7);
125 | }
126 |
127 | void flashPeriod() {
128 | // .-.-.-
129 | dot();
130 | delay(unit);
131 | dash();
132 | delay(unit);
133 | dot();
134 | delay(unit);
135 | dash();
136 | delay(unit);
137 | dot();
138 | delay(unit);
139 | dash();
140 | }
141 |
142 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/LetThereBeLight-Pt3/README.md:
--------------------------------------------------------------------------------
1 | # Let There Be Light (Part 3)
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program makes an LED blink "GWC ROCKS" in Morse code.
11 |
12 | **Note:** The circuit on the breadboard needs to use digital pin 10 instead of 5V!
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/README.md:
--------------------------------------------------------------------------------
1 | # Unit 2.1: Robotics
2 |
3 | ## Table of Contents
4 |
5 | ### Projects:
6 |
7 | 1. [Let There Be Light: Part 2](LetThereBeLight-Pt2)
8 | * This project is used in U2L1.
9 | * Students learn how to write an Arduino C program and how to use the commands `pinMode()`, `delay()`, and `digitalWrite()`.
10 | 1. [Let There Be Light: Part 3](LetThereBeLight-Pt3)
11 | * This project is used in U2L1.
12 | * Students learn how to use functions and variables in Arduino C.
13 | 1. [Robot Dance Party](RobotDanceParty)
14 | * This project is used in U2L2.
15 | * Students learn how to read circuit diagrams, declare and call functions in Arduino C, and use loops.
16 | 1. [Whisker Input Code ALong](WhiskerCodeAlong)
17 | * This project is used in U2L3.
18 | * Students learn how to use an input with the teacher by coding the whisker sensor.
19 | 1. [Build a Circuit](BuildACircuit)
20 | * This project is used in U2L3.
21 | * Students learn how to plug in and code an input using just the circuit diagram.
22 | 1. [Here Kitty Kitty](HereKittyKitty)
23 | * This project is used in U2L3.
24 | * Students get creative with inputs. They use a sensor to move a cat robot forward.
25 | 1. [Escape Bot](EscapeBot)
26 | * This project is used in U2L4.
27 | * Students learn AI development by creating a robot that can escape from a three-sided box.
28 |
29 | ### Reference:
30 |
31 | 1. [Circuits](Circuits)
32 | * These are circuit diagrams for the different inputs used in U2L3.
33 | 1. [CodeExamples](CodeExamples)
34 | * These files include the code snippets that are shown on the slides in U2L3.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/RobotDanceParty/README.md:
--------------------------------------------------------------------------------
1 | # Robot Dance Party
2 |
3 | 1. The program begins by setting up the pins to control the various devices, and a declaration of frequencies for different notes to use with the piezo.
4 | 1. Next there are 3 functions that are defined: one for a dance move (twirlStopShake()), for an LED pattern (ledSwirl()), and for a short song (piezoGreeting()).
5 | 1. Finally the program will loop through these 3 functions.
6 |
7 | If students want the LED and dance to happen simultaneously and not sequentially, they will have to combine the commands for the dance moves and LED pattern into a single function.
8 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/RobotDanceParty/RobotDanceParty.ino:
--------------------------------------------------------------------------------
1 |
2 | #include // Include servo library.
3 |
4 | Servo servoLeft; // Declare left servo signal.
5 | Servo servoRight; // Declare right servo signal.
6 |
7 |
8 | // Declare pin that the piezo is connected to.
9 | int PIEZOPIN = 5;
10 |
11 | // DECLARE LED PINS HERE
12 | int LED1 = 2;
13 | int LED2 = 3;
14 | int LED3 = 4;
15 |
16 | // One octave of notes between A4 and A5, for Piezo Greeting
17 | int note_A4 = 440;
18 | int note_As4 = 466; int note_Bb4 = note_As4;
19 | int note_B4 = 494;
20 | int note_C5 = 523;
21 | int note_Cs5 = 554; int note_Db5 = note_Cs5;
22 | int note_D5 = 587;
23 | int note_Ds5 = 622; int note_Eb5 = note_Ds5;
24 | int note_E5 = 659;
25 | int note_F5 = 698;
26 | int note_Fs5 = 740; int note_Gb5 = note_Fs5;
27 | int note_G5 = 784;
28 | int note_Gs5 = 830; int note_Ab5 = note_Gs5;
29 |
30 | void setup()
31 | {
32 | pinMode(PIEZOPIN, OUTPUT); // Attach piezo to pin 5.
33 |
34 | servoLeft.attach(13); // Attach left signal to pin 13.
35 | servoRight.attach(12); // Attach right signal to pin 12.
36 | servoLeft.writeMicroseconds(1500); // Stop left servo.
37 | servoRight.writeMicroseconds(1500); // Stop right servo.
38 |
39 | pinMode(LED1, OUTPUT); // Set all LED pins to output.
40 | pinMode(LED2, OUTPUT);
41 | pinMode(LED3, OUTPUT);
42 |
43 | }
44 |
45 | // Example function that defines a dance move.
46 | void twirlStopShake(){
47 |
48 | // Twirl
49 | servoLeft.writeMicroseconds(1700);
50 | delay(4000);
51 |
52 | // Stop
53 | servoLeft.writeMicroseconds(1500);
54 | delay(1000);
55 |
56 | // Shake
57 | for(int x = 1; x < 20; x += 1){
58 | servoLeft.writeMicroseconds(1700);
59 | servoRight.writeMicroseconds(1300);
60 | delay(50);
61 |
62 | servoLeft.writeMicroseconds(1300);
63 | servoRight.writeMicroseconds(1700);
64 | delay(50);
65 | }
66 |
67 | // Stop motion
68 | servoLeft.writeMicroseconds(1500);
69 | servoRight.writeMicroseconds(1500);
70 |
71 | }
72 |
73 | // Example function that results in 3 LEDs lighting up in sequence.
74 | void ledSwirl(){
75 |
76 | for( int x = 0; x < 3; x++){
77 | digitalWrite(LED1, HIGH);
78 | delay(100);
79 | digitalWrite(LED2, HIGH);
80 | delay(100);
81 | digitalWrite(LED3, HIGH);
82 | digitalWrite(LED1, LOW);
83 | delay(100);
84 | digitalWrite(LED2, LOW);
85 | delay(100);
86 | digitalWrite(LED3, LOW);
87 | }
88 | }
89 |
90 | // Sample piezo greeting, using the note declarations from above.
91 | void piezoGreeting(){
92 |
93 | for( int x = 0; x < 5; x++){
94 | tone(PIEZOPIN, note_C5, 200);
95 | delay(500);
96 | tone(PIEZOPIN, note_E5, 200);
97 | delay(500);
98 | tone(PIEZOPIN, note_G5, 200);
99 | delay(500);
100 | }
101 | }
102 |
103 | // Sample main program.
104 | // The robot will play its greeting, then flash its lights, then dance.
105 | // If you want the lights and the dance to happen simultaneously,
106 | // those two functions must be combined because they currently execute
107 | // sequentially.
108 | void loop()
109 | {
110 | piezoGreeting();
111 |
112 | for( int x = 0; x < 5; x++){
113 | ledSwirl();
114 | twirlStopShake();
115 | }
116 |
117 | delay(1000);
118 | }
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/WhiskerCodeAlong/README.md:
--------------------------------------------------------------------------------
1 | # Whisker Input Code Along
2 |
3 | To run:
4 |
5 | 1. Open in Arduino.
6 | 1. Plug in robot using USB.
7 | 1. Verify code.
8 | 1. Upload program to robot.
9 |
10 | This program prints out different messages to the console, based on whether the left whisker is pressed, the right whisker is pressed, or both whiskers are pressed.
11 |
12 | **Note:** For this particular program, make sure the left whisker is connected to digital pin 5 and the right whisker is connected to digital pin 7.
--------------------------------------------------------------------------------
/U2-Applications/U2.3-Robotics/WhiskerCodeAlong/WhiskerCodeAlong.ino:
--------------------------------------------------------------------------------
1 | /* Whisker Code Along
2 | * Part 1:
3 | * We will show students how to set up the whisker inputs.
4 | * We will show them how to print values from the input.
5 | *
6 | * Part 2:
7 | * We will show students how to use conditionals with inputs.
8 | */
9 |
10 | // PART 1
11 | // We start by declaring where we've plugged in the whiskers.
12 | // This can be different for different students, however,
13 | // They should all be in digital pins!
14 | int leftWhisker = 5;
15 | int rightWhisker = 7;
16 |
17 | void setup() {
18 | // PART 1
19 | // We always start opening up the serial port for writing.
20 | // If we don't do this, we can't see any values!
21 | Serial.begin(9600);
22 |
23 | // PART 1
24 | // We also need to declare these digital pins as INPUT
25 | // in order to read what values they are.
26 | pinMode(leftWhisker, INPUT);
27 | pinMode(rightWhisker, INPUT);
28 | }
29 |
30 | void loop() {
31 | // PART 1
32 | // We start by using our new information: digitalRead().
33 | // This less us see get information from the whisker sensor.
34 | int leftWhiskerValue = digitalRead(leftWhisker);
35 | int rightWhiskerValue = digitalRead(rightWhisker);
36 |
37 | // PART 1
38 | // Then we print out the information.
39 | // Note the use of print() vs println() in order
40 | // to make the output very easy to read.
41 | Serial.print("Left :");
42 | Serial.print(leftWhiskerValue);
43 | Serial.print(" Right :");
44 | Serial.print(rightWhiskerValue);
45 | Serial.println("");
46 |
47 | // PART 2
48 | // Explain that just printing the values
49 | // isn't enough information. Let's try using
50 | // conditionals to print what information we
51 | // learn from the values.
52 | // Replace the prints above with:
53 | if(leftWhiskerValue == 0 && rightWhiskerValue == 0) {
54 | Serial.println("Left and Right pressed!");
55 | } else if(leftWhiskerValue == 0) {
56 | Serial.print("Left pressed!");
57 | } else if(rightWhiskerValue == 0) {
58 | Serial.print("Right pressed!");
59 | } else {
60 | Serial.print("No whiskers pressed!");
61 | }
62 |
63 | // PART 1
64 | // Avoid overwhelming the serial buffer.
65 | // Explain to students that this is like
66 | // lights on a highway entrance ramp --
67 | // preventing too many cars from going
68 | // on the highway at the same time to avoid
69 | // traffic jams.
70 | delay(100);
71 | }
72 |
--------------------------------------------------------------------------------