├── Python, 2024 07July 03.ipynb ├── Python, 2024 07July 10.ipynb ├── Python, 2024 07July 24.ipynb ├── Python, 2024 07July 31.ipynb ├── Python, 2024 08August 07.ipynb ├── README.md ├── chooser.py ├── config.txt ├── linux-etc-passwd.txt ├── menu.py ├── mini-access-log.txt ├── mymod.py ├── nums.txt ├── reuven-testfile.txt ├── shoe-data.txt └── wcfile.txt /Python, 2024 07July 03.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Agenda\n", 8 | "\n", 9 | "1. Basic Python fundamentals\n", 10 | " - Values and variables\n", 11 | " - Display values and get input from the user\n", 12 | " - Assignment\n", 13 | " - Comparison\n", 14 | " - Conditional code\n", 15 | " - Numbers (integers and floats)\n", 16 | " - Strings (text)\n", 17 | " - Methods (functionality we can run on an object)\n", 18 | "2. Loops, lists, and tuples\n", 19 | " - Repeat functionality with a loop (`for` and `while`)\n", 20 | " - Using lists -- how are they different from strings, and how are they the same?\n", 21 | " - Tuples -- another data structure that's similar to strings and lists (\"sequence\")\n", 22 | " - Tuple unpacking\n", 23 | "3. Dictionaries and files\n", 24 | " - Creating and working with dicts\n", 25 | " - Different paradigms for using dicts\n", 26 | " - Read from files\n", 27 | " - (A little) writing to files\n", 28 | "4. Functions\n", 29 | " - Write functions\n", 30 | " - Function bodies\n", 31 | " - Arguments and parameters\n", 32 | " - Return values\n", 33 | "5. Modules and packages\n", 34 | " - How can we use modules in Python?\n", 35 | " - How can write our own modules?\n", 36 | " - PyPI (the Python Package Index)\n", 37 | " - `pip`" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "# What is a programming language? What is Python?\n", 45 | "\n", 46 | "A program is a set of instructions, telling the computer what to do. In the end, it's just a bunch of 1s and 0s. In order to write programs and keep track of them and debug them easily, we write in programming languages, which are then translated into 1s and 0s. (This process is sometimes known as interpretation and sometimes compilation.)\n", 47 | "\n", 48 | "Python is a high-level language.\n", 49 | "\n", 50 | "Python has been around for more than 30 years. It's now super super popular. Why? Python is a perfect language for an age in which people are expensive and computers are cheap. If we can increase the person's productivity in writing code, then that's worth having to pay more for computers.\n", 51 | "\n", 52 | "Python is popular in a wide variety of areas:\n", 53 | "- Data science and machine learning (#1)\n", 54 | "- Web development\n", 55 | "- Devops and system administration\n", 56 | "- Automated testing\n", 57 | "- Education\n", 58 | "\n", 59 | "Python is super consistent -- once you learn something in the language, you can use it forever.\n", 60 | "\n", 61 | "I sometimes call Python the Esperanto of programming languages, because it is so consistent.\n", 62 | "\n", 63 | "Jupyter gives us the illusion that we're running Python in the browser. There's a server on the back end that's actually running Python -- but it's a great illusion! I can type into it, and give you text (Markdown) or in code (Python)." 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "Hello, world!\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "# if I type into a cell in Jupyter, then I can type Python code\n", 81 | "# this is a comment; Python ignores it completely. It's for me to leave hints/reminders to myself and other coders.\n", 82 | "# Just type # and go to the end of the line -- Python doesn't care what you write\n", 83 | "\n", 84 | "# print is a function, a verb in our programming language\n", 85 | "# print displays something on the screen\n", 86 | "# we need to use () to run the print function\n", 87 | "# whatever is inside of the () is displayed\n", 88 | "# note that if we want text (aka \"a string\") then it needs to be inside of '' (or \"\" if you prefer)\n", 89 | "\n", 90 | "# if I want to execute the contents of a cell, I press shift+ENTER\n", 91 | "print('Hello, world!')" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 2, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "5\n" 104 | ] 105 | } 106 | ], 107 | "source": [ 108 | "# what else can I print?\n", 109 | "\n", 110 | "print(5)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 4, 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "name": "stdout", 120 | "output_type": "stream", 121 | "text": [ 122 | "8\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "# before print executes, and displays something on the screen,\n", 128 | "# whatever is inside of its parentheses needs to be \"evaluated,\" or run\n", 129 | "\n", 130 | "# in this example, first 5+3 is evaluated, we get back 8, and then print\n", 131 | "# only sees print(8), which it executes\n", 132 | "\n", 133 | "print(5 + 3)" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "helloworld\n" 146 | ] 147 | } 148 | ], 149 | "source": [ 150 | "# I can use + with numbers\n", 151 | "# can I use + with text, also?\n", 152 | "\n", 153 | "print('hello' + 'world') # yes, we can use + ! ... but... there isn't any space between the words" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "# The most important thing to remember\n", 161 | "\n", 162 | "Computers do what you tell them to do, not what you want them to do." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 7, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "name": "stdout", 172 | "output_type": "stream", 173 | "text": [ 174 | "hello world\n" 175 | ] 176 | } 177 | ], 178 | "source": [ 179 | "print('hello' + ' ' + 'world') " 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 11, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "hello world\n" 192 | ] 193 | } 194 | ], 195 | "source": [ 196 | "print('hello ' + 'world')" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "# Storing our values\n", 204 | "\n", 205 | "What we saw above with text and numbers are *values*. Those are the nouns in a programming language. We're going to spend much of the next three weeks talking about different types of values, and how they work.\n", 206 | "\n", 207 | "But what if we want to store a value somewhere? Then we use a *variable*. A variable is a pronoun in a programming language, which refers to an actual value.\n", 208 | "\n", 209 | "If I want to associate a value with a variable, I need to *assign* the value to it. We do this with the `=` sign, known as the \"assignment operator.\"\n", 210 | "\n", 211 | "# VERY VERY IMPORTANT -- `=` is not the same in Python as in math!\n", 212 | "\n", 213 | "In Python, `=` means:\n", 214 | "- Take the value on the right\n", 215 | "- Assign it to the variable on the left\n", 216 | "- If the variable didn't yet exist, now it does!" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 8, 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "name = 'Reuven'" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 9, 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "name\n" 238 | ] 239 | } 240 | ], 241 | "source": [ 242 | "# now I can refer to 'Reuven' via the variable name!\n", 243 | "# note that text has quotes around it, but variables don't.\n", 244 | "\n", 245 | "print('name') # this will display the literal word 'name'" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 10, 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "name": "stdout", 255 | "output_type": "stream", 256 | "text": [ 257 | "Reuven\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "print(name) # this will display the value in the variable name" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "# Variable names\n", 270 | "\n", 271 | "What names can we use for variables?\n", 272 | "\n", 273 | "Any combination of letters, digits, and `_`, but:\n", 274 | "\n", 275 | "- You cannot start with a digit\n", 276 | "- You SHOULD NOT start or end with `_` (because they have special meaning to Python)\n", 277 | "- Capital and lowercase letters are different, so the variable `x` and the variable `X` have nothing to do with one another\n", 278 | "\n", 279 | "Python has some \"reserved words\" that you cannot assign to, such as `for` and `def` and `with`. Trying to assign to those will result in an error.\n", 280 | "\n", 281 | "There are also words that you shouldn't assign to, such as `print`, `len`, `sum`, and `list` and `dict`. If you see your editor (or Jupyter) change the color of the word when you have a variable name, don't use that variable!" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 12, 287 | "metadata": {}, 288 | "outputs": [ 289 | { 290 | "name": "stdout", 291 | "output_type": "stream", 292 | "text": [ 293 | "Reuven\n" 294 | ] 295 | } 296 | ], 297 | "source": [ 298 | "name = 'Reuven' # value on the right, variable on the left\n", 299 | "print(name)" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 13, 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "name": "stdout", 309 | "output_type": "stream", 310 | "text": [ 311 | "12345\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "number = 12345 # value on the right, variable on the left\n", 317 | "print(number)" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 14, 323 | "metadata": {}, 324 | "outputs": [ 325 | { 326 | "name": "stdout", 327 | "output_type": "stream", 328 | "text": [ 329 | "7\n" 330 | ] 331 | } 332 | ], 333 | "source": [ 334 | "number = 2+5 # value on the right is 2+5 -> 7, and that is assigned to number\n", 335 | "print(number)" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 15, 341 | "metadata": {}, 342 | "outputs": [ 343 | { 344 | "data": { 345 | "text/plain": [ 346 | "7" 347 | ] 348 | }, 349 | "execution_count": 15, 350 | "metadata": {}, 351 | "output_type": "execute_result" 352 | } 353 | ], 354 | "source": [ 355 | "# in Jupyter, and *ONLY* in Jupyter, there's a fancy feature that says:\n", 356 | "# if a value is on the final line of the cell, then executing the cell shows that value\n", 357 | "\n", 358 | "number" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 16, 364 | "metadata": {}, 365 | "outputs": [ 366 | { 367 | "data": { 368 | "text/plain": [ 369 | "12" 370 | ] 371 | }, 372 | "execution_count": 16, 373 | "metadata": {}, 374 | "output_type": "execute_result" 375 | } 376 | ], 377 | "source": [ 378 | "number + 5" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": 17, 384 | "metadata": {}, 385 | "outputs": [ 386 | { 387 | "name": "stdout", 388 | "output_type": "stream", 389 | "text": [ 390 | "30\n" 391 | ] 392 | } 393 | ], 394 | "source": [ 395 | "x = 10 # assigning 10 to x\n", 396 | "y = 20 # assigning 20 to y\n", 397 | "\n", 398 | "print(x + y)" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 18, 404 | "metadata": {}, 405 | "outputs": [ 406 | { 407 | "data": { 408 | "text/plain": [ 409 | "20" 410 | ] 411 | }, 412 | "execution_count": 18, 413 | "metadata": {}, 414 | "output_type": "execute_result" 415 | } 416 | ], 417 | "source": [ 418 | "x = 10 # assigning the integer 10 to x\n", 419 | "y = '20' # assigning the text string '20' to y\n", 420 | "\n", 421 | "x + x" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": 19, 427 | "metadata": {}, 428 | "outputs": [ 429 | { 430 | "data": { 431 | "text/plain": [ 432 | "'2020'" 433 | ] 434 | }, 435 | "execution_count": 19, 436 | "metadata": {}, 437 | "output_type": "execute_result" 438 | } 439 | ], 440 | "source": [ 441 | "y + y" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 20, 447 | "metadata": { 448 | "scrolled": true 449 | }, 450 | "outputs": [ 451 | { 452 | "ename": "TypeError", 453 | "evalue": "unsupported operand type(s) for +: 'int' and 'str'", 454 | "output_type": "error", 455 | "traceback": [ 456 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 457 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 458 | "Cell \u001b[0;32mIn[20], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# so what will happen when I try adding x and y?\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\n", 459 | "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "# so what will happen when I try adding x and y?\n", 465 | "x + y" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 21, 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "ename": "TypeError", 475 | "evalue": "can only concatenate str (not \"int\") to str", 476 | "output_type": "error", 477 | "traceback": [ 478 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 479 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 480 | "Cell \u001b[0;32mIn[21], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43my\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mx\u001b[49m\n", 481 | "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" 482 | ] 483 | } 484 | ], 485 | "source": [ 486 | "y + x" 487 | ] 488 | }, 489 | { 490 | "cell_type": "markdown", 491 | "metadata": {}, 492 | "source": [ 493 | "# You have to be careful about types!\n", 494 | "\n", 495 | "Different types of data cannot be mixed together willy nilly. You need to make sure that both values you're adding (or anything else) are the same type. We will talk about how to convert one type to another." 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "# Exercise: Simple calculator\n", 503 | "\n", 504 | "Assign two whole numbers (i.e., just digits 0-9) to two different variables. (You get to choose their names!) Add them together, and assign the result to a third variable. Print that third variable on the screen." 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": 22, 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "data": { 514 | "text/plain": [ 515 | "57" 516 | ] 517 | }, 518 | "execution_count": 22, 519 | "metadata": {}, 520 | "output_type": "execute_result" 521 | } 522 | ], 523 | "source": [ 524 | "first = 25 # assigning the integer 25 to first\n", 525 | "second = 32 # assigning the integer 32 t second\n", 526 | "\n", 527 | "first + second" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 23, 533 | "metadata": {}, 534 | "outputs": [ 535 | { 536 | "data": { 537 | "text/plain": [ 538 | "'2532'" 539 | ] 540 | }, 541 | "execution_count": 23, 542 | "metadata": {}, 543 | "output_type": "execute_result" 544 | } 545 | ], 546 | "source": [ 547 | "# let's try something else\n", 548 | "first = '25' # assigning the text string '25' to first\n", 549 | "second = '32' # assigning the text string '32' to second\n", 550 | "\n", 551 | "first + second" 552 | ] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": 24, 557 | "metadata": {}, 558 | "outputs": [ 559 | { 560 | "name": "stdout", 561 | "output_type": "stream", 562 | "text": [ 563 | "57\n" 564 | ] 565 | } 566 | ], 567 | "source": [ 568 | "first = 25 # assigning the integer 25 to first\n", 569 | "second = 32 # assigning the integer 32 t second\n", 570 | "\n", 571 | "total = first + second\n", 572 | "\n", 573 | "print(total)" 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": 25, 579 | "metadata": {}, 580 | "outputs": [ 581 | { 582 | "ename": "TypeError", 583 | "evalue": "can only concatenate str (not \"int\") to str", 584 | "output_type": "error", 585 | "traceback": [ 586 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 587 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 588 | "Cell \u001b[0;32mIn[25], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# what if I want to print some text along with that number?\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mYour total is \u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mtotal\u001b[49m)\n", 589 | "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" 590 | ] 591 | } 592 | ], 593 | "source": [ 594 | "# what if I want to print some text along with that number?\n", 595 | "\n", 596 | "print('Your total is ' + total)" 597 | ] 598 | }, 599 | { 600 | "cell_type": "code", 601 | "execution_count": 28, 602 | "metadata": {}, 603 | "outputs": [ 604 | { 605 | "name": "stdout", 606 | "output_type": "stream", 607 | "text": [ 608 | "25 + 32 = 57\n" 609 | ] 610 | } 611 | ], 612 | "source": [ 613 | "# however, we can use a special kind of text string called an f-string\n", 614 | "# (that's short for format string or fancy string)\n", 615 | "\n", 616 | "# you put an f before the opening '\n", 617 | "# inside of the f-string, you can put {} with any Python expression inside\n", 618 | "# that will be turned into a text string!\n", 619 | "\n", 620 | "print(f'{first} + {second} = {total}') # value of first, value of second, value of total are *INTERPOLATED* into the string" 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": 31, 626 | "metadata": {}, 627 | "outputs": [ 628 | { 629 | "name": "stdout", 630 | "output_type": "stream", 631 | "text": [ 632 | "Hello, strange!\n" 633 | ] 634 | } 635 | ], 636 | "source": [ 637 | "name = 'strange'\n", 638 | "\n", 639 | "print(f'Hello, {name}!') # this f-string's value depends on the value of the variable name" 640 | ] 641 | }, 642 | { 643 | "cell_type": "markdown", 644 | "metadata": {}, 645 | "source": [ 646 | "# What does an f-string do?\n", 647 | "\n", 648 | "In a standard, traditional string, what we type is (basically) what we get. \n", 649 | "\n", 650 | "What we want, though, is a string in which there's some *dynamic* content. That is, some part of it will change its value based on what a variable contains. \n", 651 | "\n", 652 | "- If your string won't ever change, then don't use an f-string. (You lose nothing!)\n", 653 | "- If your string contains values from variables, then an f-string is a godsend.\n", 654 | "- The types of values you put in an f-string don't matter, because they're all converted into text strings behind the scenes.\n" 655 | ] 656 | }, 657 | { 658 | "cell_type": "code", 659 | "execution_count": 32, 660 | "metadata": {}, 661 | "outputs": [ 662 | { 663 | "name": "stdout", 664 | "output_type": "stream", 665 | "text": [ 666 | "10 + 20 + 30 = 60\n" 667 | ] 668 | } 669 | ], 670 | "source": [ 671 | "# Think of the {} as a tiny Python program\n", 672 | "\n", 673 | "x = 10\n", 674 | "y = 20\n", 675 | "z = 30\n", 676 | "\n", 677 | "print(f'{x} + {y} + {z} = {x+y+z}') # inside of {} we can have any expression, not just a variable" 678 | ] 679 | }, 680 | { 681 | "cell_type": "code", 682 | "execution_count": 34, 683 | "metadata": {}, 684 | "outputs": [ 685 | { 686 | "name": "stdin", 687 | "output_type": "stream", 688 | "text": [ 689 | "Enter your name: someone else\n" 690 | ] 691 | }, 692 | { 693 | "name": "stdout", 694 | "output_type": "stream", 695 | "text": [ 696 | "Hello, someone else!\n" 697 | ] 698 | } 699 | ], 700 | "source": [ 701 | "# what if I want to get input from the user, and not hard-code it in my program?\n", 702 | "\n", 703 | "# I can use the \"input\" function, which pauses the program and asks the user to enter something\n", 704 | "# whatever the user entered is \"returned\" by that function, and can be assigned to a variable\n", 705 | "\n", 706 | "# here's the typical look of input:\n", 707 | "\n", 708 | "# when we assign, the right side runs before the left side\n", 709 | "# the right side asks the user to enter their name\n", 710 | "# whatever the user types is returned as a string (the right side will contain a string)\n", 711 | "# that string is assigned to the variable name\n", 712 | "\n", 713 | "name = input('Enter your name: ')\n", 714 | "print(f'Hello, {name}!')" 715 | ] 716 | }, 717 | { 718 | "cell_type": "markdown", 719 | "metadata": {}, 720 | "source": [ 721 | "# Exercise: User input\n", 722 | "\n", 723 | "1. Ask the user to enter their name, and assign that to a variable `name`.\n", 724 | "2. Ask the user to enter their city, and assign that to a variable `city`.\n", 725 | "3. Print output to the user, greeting them from their city.\n", 726 | "\n", 727 | "Example:\n", 728 | "\n", 729 | " Enter your name: Reuven\n", 730 | " Enter your city: Modi'in\n", 731 | " Hello Reuven from Modi'in!" 732 | ] 733 | }, 734 | { 735 | "cell_type": "code", 736 | "execution_count": 35, 737 | "metadata": { 738 | "scrolled": true 739 | }, 740 | "outputs": [ 741 | { 742 | "name": "stdin", 743 | "output_type": "stream", 744 | "text": [ 745 | "Enter your name: Reuven\n", 746 | "Enter your city: Modi'in\n" 747 | ] 748 | }, 749 | { 750 | "name": "stdout", 751 | "output_type": "stream", 752 | "text": [ 753 | "Hello, Reuven from Modi'in!\n" 754 | ] 755 | } 756 | ], 757 | "source": [ 758 | "name = input('Enter your name: ')\n", 759 | "city = input('Enter your city: ')\n", 760 | "\n", 761 | "print(f'Hello, {name} from {city}!')" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": 36, 767 | "metadata": { 768 | "scrolled": true 769 | }, 770 | "outputs": [ 771 | { 772 | "name": "stdin", 773 | "output_type": "stream", 774 | "text": [ 775 | "Enter your name: Reuven\n", 776 | "Enter your city: Modi'in\n" 777 | ] 778 | }, 779 | { 780 | "name": "stdout", 781 | "output_type": "stream", 782 | "text": [ 783 | "Hello, Reuven, from, Modi'in!\n" 784 | ] 785 | } 786 | ], 787 | "source": [ 788 | "name = input('Enter your name: ')\n", 789 | "city = input('Enter your city: ')\n", 790 | "\n", 791 | "print(f'Hello, {name}, from, {city}!')" 792 | ] 793 | }, 794 | { 795 | "cell_type": "code", 796 | "execution_count": 37, 797 | "metadata": {}, 798 | "outputs": [ 799 | { 800 | "ename": "SyntaxError", 801 | "evalue": "unterminated string literal (detected at line 4) (3214737825.py, line 4)", 802 | "output_type": "error", 803 | "traceback": [ 804 | "\u001b[0;36m Cell \u001b[0;32mIn[37], line 4\u001b[0;36m\u001b[0m\n\u001b[0;31m print(f'{name}'s city is {city}!')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unterminated string literal (detected at line 4)\n" 805 | ] 806 | } 807 | ], 808 | "source": [ 809 | "name = input('Enter your name: ')\n", 810 | "city = input('Enter your city: ')\n", 811 | "\n", 812 | "print(f'{name}\\'s city is {city}!') # inside of a '' string, you can use \\' to mean: give me a literal ', not the end of the string" 813 | ] 814 | }, 815 | { 816 | "cell_type": "markdown", 817 | "metadata": {}, 818 | "source": [ 819 | "# Next up\n", 820 | "\n", 821 | "- Comparing values\n", 822 | "- Conditional execution" 823 | ] 824 | }, 825 | { 826 | "cell_type": "markdown", 827 | "metadata": {}, 828 | "source": [ 829 | "# Conditions\n", 830 | "\n", 831 | "We've seen that we can use `+` on values to add them together (numbers or text strings). But there are many operators, too. One of them is `==`, which is the *equality operator*. It tells us if two things are the same.\n", 832 | "\n", 833 | "## `=` and `==` are *VERY* different!\n", 834 | "\n", 835 | "- `=`, as we saw before, is the assignment operator. It takes the value on the right and assigns to the variable on the left.\n", 836 | "- `==` has a completely different role; it returns either `True` or `False`, depending on if the values on its left and right are the same." 837 | ] 838 | }, 839 | { 840 | "cell_type": "code", 841 | "execution_count": 38, 842 | "metadata": {}, 843 | "outputs": [ 844 | { 845 | "data": { 846 | "text/plain": [ 847 | "False" 848 | ] 849 | }, 850 | "execution_count": 38, 851 | "metadata": {}, 852 | "output_type": "execute_result" 853 | } 854 | ], 855 | "source": [ 856 | "10 == 20 # what will this return" 857 | ] 858 | }, 859 | { 860 | "cell_type": "code", 861 | "execution_count": 39, 862 | "metadata": {}, 863 | "outputs": [ 864 | { 865 | "data": { 866 | "text/plain": [ 867 | "True" 868 | ] 869 | }, 870 | "execution_count": 39, 871 | "metadata": {}, 872 | "output_type": "execute_result" 873 | } 874 | ], 875 | "source": [ 876 | "10 == 10" 877 | ] 878 | }, 879 | { 880 | "cell_type": "code", 881 | "execution_count": 40, 882 | "metadata": {}, 883 | "outputs": [ 884 | { 885 | "data": { 886 | "text/plain": [ 887 | "False" 888 | ] 889 | }, 890 | "execution_count": 40, 891 | "metadata": {}, 892 | "output_type": "execute_result" 893 | } 894 | ], 895 | "source": [ 896 | "10 == '10' " 897 | ] 898 | }, 899 | { 900 | "cell_type": "code", 901 | "execution_count": 41, 902 | "metadata": {}, 903 | "outputs": [ 904 | { 905 | "data": { 906 | "text/plain": [ 907 | "True" 908 | ] 909 | }, 910 | "execution_count": 41, 911 | "metadata": {}, 912 | "output_type": "execute_result" 913 | } 914 | ], 915 | "source": [ 916 | "'abcd' == 'abcd' " 917 | ] 918 | }, 919 | { 920 | "cell_type": "code", 921 | "execution_count": 42, 922 | "metadata": {}, 923 | "outputs": [ 924 | { 925 | "data": { 926 | "text/plain": [ 927 | "False" 928 | ] 929 | }, 930 | "execution_count": 42, 931 | "metadata": {}, 932 | "output_type": "execute_result" 933 | } 934 | ], 935 | "source": [ 936 | "'abcd' == ' abcd'" 937 | ] 938 | }, 939 | { 940 | "cell_type": "code", 941 | "execution_count": 43, 942 | "metadata": {}, 943 | "outputs": [ 944 | { 945 | "data": { 946 | "text/plain": [ 947 | "False" 948 | ] 949 | }, 950 | "execution_count": 43, 951 | "metadata": {}, 952 | "output_type": "execute_result" 953 | } 954 | ], 955 | "source": [ 956 | "'abcd' == 'Abcd'" 957 | ] 958 | }, 959 | { 960 | "cell_type": "markdown", 961 | "metadata": {}, 962 | "source": [ 963 | "# Comparison operators\n", 964 | "\n", 965 | "We can compare two values in a number of ways:\n", 966 | "\n", 967 | "- `==` -- are they the same?\n", 968 | "- `!=` -- are they *not* the same?\n", 969 | "- `<` -- is the value on the left less than the value on the right?\n", 970 | "- `<=` -- is the value on the left less than or equal to the value on the right?\n", 971 | "- `>` -- is the value on the left greater than the value on the right?\n", 972 | "- `>=` -- is the value on the left greater than or equal to the value on the right?\n", 973 | " " 974 | ] 975 | }, 976 | { 977 | "cell_type": "markdown", 978 | "metadata": {}, 979 | "source": [ 980 | "# Conditionals \n", 981 | "\n", 982 | "So far, when we've had code in our program, it always ran. Conditionals allow us to say, \"This code should only run sometimes, under the following conditions.\"\n", 983 | "\n", 984 | "The way we do this is with the `if` statement.\n", 985 | "\n", 986 | "1. `if` looks to its right, and checks if there is a `True` or `False` value. Very often, we're going to have a comparison there, often (but not always) with `==`.\n", 987 | "2. At the end of that line, there must be a `:`.\n", 988 | "3. Starting on the following line, we have a \"block\" of code. How does Python know where the block starts? Right after the colon. How does it know when it ends? When the indentation ends. There is no `end` or `}` or other syntax in Python to indicate the end of a block; it's just indentation.\n", 989 | "4. A block must contain at least one line. Whatever is in the `if` block runs if the condition for `if` was `True`.\n", 990 | "5. If the condition for the `if` was `False`, and if there's an `else` clause, then the `else` block runs.\n", 991 | "6. `else` does *not* have a condition! It runs if the previous clause was `False`.\n", 992 | "7. `else` has a `:` at the end of the line, and its own block, which can be any length.\n", 993 | "8. If you don't have an `else` clause, then `if` might or might run.\n", 994 | "9. If you *do* have an `else` clause, then either `if` or `else` will run -- one of them is guaranteed to run; not zero and not both of them." 995 | ] 996 | }, 997 | { 998 | "cell_type": "code", 999 | "execution_count": 46, 1000 | "metadata": {}, 1001 | "outputs": [ 1002 | { 1003 | "ename": "IndentationError", 1004 | "evalue": "expected an indented block after 'if' statement on line 3 (2268419397.py, line 4)", 1005 | "output_type": "error", 1006 | "traceback": [ 1007 | "\u001b[0;36m Cell \u001b[0;32mIn[46], line 4\u001b[0;36m\u001b[0m\n\u001b[0;31m print('Hello, boss!')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block after 'if' statement on line 3\n" 1008 | ] 1009 | } 1010 | ], 1011 | "source": [ 1012 | "name = input('Enter your name: ')\n", 1013 | "\n", 1014 | "if name == 'Reuven':\n", 1015 | " print('Hello, boss!')\n", 1016 | " print('It is great to see you again!')\n", 1017 | "else:\n", 1018 | " print(f'Who are you, {name}?')" 1019 | ] 1020 | }, 1021 | { 1022 | "cell_type": "markdown", 1023 | "metadata": {}, 1024 | "source": [ 1025 | "# Exercise: Which word comes first?\n", 1026 | "\n", 1027 | "1. Ask the user to enter a word, and assign it to a variable.\n", 1028 | "2. Ask the user to enter a second word, and assign it to another variable.\n", 1029 | "3. If the first word comes before the second one alphabetically, say so.\n", 1030 | "4. If the second word comes before the first one alphabetically, say so.\n", 1031 | "\n", 1032 | "Some things to keep in mind:\n", 1033 | "- Yes, you can use `<` and `>` on text strings! \"Less\" in this case means \"comes earlier alphabetically.\"\n", 1034 | "- Assume the user entered two different words.\n", 1035 | "- Also assume that the words contain only lowercase letters (no digits, symbols, spaces, etc.)" 1036 | ] 1037 | }, 1038 | { 1039 | "cell_type": "markdown", 1040 | "metadata": {}, 1041 | "source": [ 1042 | "# Single vs. double quotes\n", 1043 | "\n", 1044 | "In some programming languages, it's very important to distinguish between `'` and `\"`. Not so in Python! You can define strings with either one, and they are identical. The only difference is whether you have `'` inside of a single-quoted string or `\"` inside of a double-quoted string, which is annoying.\n", 1045 | "\n" 1046 | ] 1047 | }, 1048 | { 1049 | "cell_type": "code", 1050 | "execution_count": 48, 1051 | "metadata": {}, 1052 | "outputs": [ 1053 | { 1054 | "name": "stdin", 1055 | "output_type": "stream", 1056 | "text": [ 1057 | "Enter first word: taxi\n", 1058 | "Enter second word: cab\n" 1059 | ] 1060 | }, 1061 | { 1062 | "name": "stdout", 1063 | "output_type": "stream", 1064 | "text": [ 1065 | "cab comes before taxi\n" 1066 | ] 1067 | } 1068 | ], 1069 | "source": [ 1070 | "first = input('Enter first word: ')\n", 1071 | "second = input('Enter second word: ')\n", 1072 | "\n", 1073 | "if first < second:\n", 1074 | " print(f'{first} comes before {second}')\n", 1075 | "else:\n", 1076 | " print(f'{second} comes before {first}')" 1077 | ] 1078 | }, 1079 | { 1080 | "cell_type": "markdown", 1081 | "metadata": {}, 1082 | "source": [ 1083 | "# Indentation\n", 1084 | "\n", 1085 | "Python knows where a block starts/ends with indentation. The indentation is MANDATORY. It's not just decorative.\n", 1086 | "\n", 1087 | "What counts as indentation? Any combination of spaces and tabs **BUT** you must be consistent, always using precisely the same combination. Most people in the Python world have settled on four spaces for indentation.\n", 1088 | "\n", 1089 | "To end a block, just backspace and end the indentation.\n", 1090 | "\n", 1091 | "To indent a line that wasn't before, use tab to move it in four spaces. You can also normally use shift-tab to reverse-indent." 1092 | ] 1093 | }, 1094 | { 1095 | "cell_type": "markdown", 1096 | "metadata": {}, 1097 | "source": [ 1098 | "# More sophisticated conditions\n", 1099 | "\n", 1100 | "`elif` allows us to deal with more than two options. It works as another `if` statement that only checks things if the original `if` condition returned `False`.\n", 1101 | "\n", 1102 | "You can have as many `elif` clauses as you want. Each has its own condition, and each is checked in turn. The first that is `True` wins." 1103 | ] 1104 | }, 1105 | { 1106 | "cell_type": "code", 1107 | "execution_count": 51, 1108 | "metadata": {}, 1109 | "outputs": [ 1110 | { 1111 | "name": "stdin", 1112 | "output_type": "stream", 1113 | "text": [ 1114 | "Enter your name: sadfasdfasfsasafa\n" 1115 | ] 1116 | }, 1117 | { 1118 | "name": "stdout", 1119 | "output_type": "stream", 1120 | "text": [ 1121 | "I have no idea what to say to you, sadfasdfasfsasafa.\n" 1122 | ] 1123 | } 1124 | ], 1125 | "source": [ 1126 | "name = input('Enter your name: ')\n", 1127 | "\n", 1128 | "if name == 'Reuven':\n", 1129 | " print('Hi, boss!')\n", 1130 | "elif name == 'someone else':\n", 1131 | " print('Is that really a name?!?')\n", 1132 | "elif name == 'whatever':\n", 1133 | " print('Oh, you must be a teenager')\n", 1134 | "else:\n", 1135 | " print(f'I have no idea what to say to you, {name}.')" 1136 | ] 1137 | }, 1138 | { 1139 | "cell_type": "markdown", 1140 | "metadata": {}, 1141 | "source": [ 1142 | "# Exercise: Which word comes first?\n", 1143 | "\n", 1144 | "Repeat the previous exercise, but now deal with the possiblity that the person entered the same word twice. In such a case, tell them that they entered the word twice." 1145 | ] 1146 | }, 1147 | { 1148 | "cell_type": "code", 1149 | "execution_count": 53, 1150 | "metadata": {}, 1151 | "outputs": [ 1152 | { 1153 | "name": "stdin", 1154 | "output_type": "stream", 1155 | "text": [ 1156 | "Enter first word: hello\n", 1157 | "Enter second word: goodbye\n" 1158 | ] 1159 | }, 1160 | { 1161 | "name": "stdout", 1162 | "output_type": "stream", 1163 | "text": [ 1164 | "goodbye comes before hello\n" 1165 | ] 1166 | } 1167 | ], 1168 | "source": [ 1169 | "first = input('Enter first word: ')\n", 1170 | "second = input('Enter second word: ')\n", 1171 | "\n", 1172 | "if first < second:\n", 1173 | " print(f'{first} comes before {second}')\n", 1174 | "elif first > second:\n", 1175 | " print(f'{second} comes before {first}')\n", 1176 | "else:\n", 1177 | " print(f'{first} and {second} are the same')" 1178 | ] 1179 | }, 1180 | { 1181 | "cell_type": "code", 1182 | "execution_count": null, 1183 | "metadata": {}, 1184 | "outputs": [], 1185 | "source": [ 1186 | "# SY\n", 1187 | "\n", 1188 | "# Which word comes first (elif)\n", 1189 | "\n", 1190 | "word1 = input('Enter Word 1 = ')\n", 1191 | "word2 = input('Enter Word 2 = ')\n", 1192 | "if word1 == word2:\n", 1193 | " print('You have entered the same word twice')\n", 1194 | "elif word1 True\n", 1232 | "if x == 10 and y == 20:\n", 1233 | " print('Yes, they are what you want!')" 1234 | ] 1235 | }, 1236 | { 1237 | "cell_type": "code", 1238 | "execution_count": 56, 1239 | "metadata": {}, 1240 | "outputs": [], 1241 | "source": [ 1242 | "x = 10\n", 1243 | "y = 20\n", 1244 | "\n", 1245 | "# True and False -> False\n", 1246 | "if x == 10 and y == 35:\n", 1247 | " print('Yes, they are what you want!') # the condition is False and there's no else clause, so .. silence" 1248 | ] 1249 | }, 1250 | { 1251 | "cell_type": "code", 1252 | "execution_count": 57, 1253 | "metadata": {}, 1254 | "outputs": [ 1255 | { 1256 | "name": "stdout", 1257 | "output_type": "stream", 1258 | "text": [ 1259 | "Yes, at least one is what you want!\n" 1260 | ] 1261 | } 1262 | ], 1263 | "source": [ 1264 | "x = 10\n", 1265 | "y = 20\n", 1266 | "\n", 1267 | "# True or False : True\n", 1268 | "if x == 10 or y == 35:\n", 1269 | " print('Yes, at least one is what you want!')" 1270 | ] 1271 | }, 1272 | { 1273 | "cell_type": "markdown", 1274 | "metadata": {}, 1275 | "source": [ 1276 | "If you get this error:\n", 1277 | "\n", 1278 | "```\n", 1279 | "could you please help: and 'PyodideFuture\n", 1280 | "\n", 1281 | "\n", 1282 | "\n", 1283 | "what is TypeError: '<' not supported between instances of 'PyodideFuture' and 'PyodideFuture' error, I got this when I use in string comparion. if str1 < str2:\n", 1284 | "```\n", 1285 | "\n", 1286 | "You're using something called JupyterLite, which runs *only* in the browser. " 1287 | ] 1288 | }, 1289 | { 1290 | "cell_type": "markdown", 1291 | "metadata": {}, 1292 | "source": [ 1293 | "# Exercise: Name and company\n", 1294 | "\n", 1295 | "1. Ask the user to enter their name\n", 1296 | "2. Ask them to enter their company's name\n", 1297 | "3. Print one of four sentences:\n", 1298 | " - if both are the same as you, print \"You must be me!\"\n", 1299 | " - if the name is the same (but not the company), compliment their name\n", 1300 | " - if the company is the same (but not the name), compliment the company and call them a colleague\n", 1301 | " - if neither is the same, then be snarky toward them" 1302 | ] 1303 | }, 1304 | { 1305 | "cell_type": "code", 1306 | "execution_count": 60, 1307 | "metadata": {}, 1308 | "outputs": [ 1309 | { 1310 | "name": "stdin", 1311 | "output_type": "stream", 1312 | "text": [ 1313 | "Enter your name: Someone\n", 1314 | "Enter your company: Lerner\n" 1315 | ] 1316 | }, 1317 | { 1318 | "name": "stdout", 1319 | "output_type": "stream", 1320 | "text": [ 1321 | "Hey, my amazing colleague!\n" 1322 | ] 1323 | } 1324 | ], 1325 | "source": [ 1326 | "name = input('Enter your name: ')\n", 1327 | "company = input('Enter your company: ')\n", 1328 | "\n", 1329 | "if name == 'Reuven' and company == 'Lerner':\n", 1330 | " print('You must be me!')\n", 1331 | "elif name == 'Reuven':\n", 1332 | " print('Great name, bad company')\n", 1333 | "elif company == 'Lerner':\n", 1334 | " print('Hey, my amazing colleague!')\n", 1335 | "else:\n", 1336 | " print('Who are you and why do I care?')" 1337 | ] 1338 | }, 1339 | { 1340 | "cell_type": "markdown", 1341 | "metadata": {}, 1342 | "source": [ 1343 | "# Next up\n", 1344 | "\n", 1345 | "1. Numbers (Integers and floats)\n", 1346 | "2. Text strings" 1347 | ] 1348 | }, 1349 | { 1350 | "cell_type": "markdown", 1351 | "metadata": {}, 1352 | "source": [ 1353 | "# Numbers\n", 1354 | "\n", 1355 | "In Python (and most modern computers), we have two types of numbers in the system (including in the CPU):\n", 1356 | "- Integers (whole numbers)\n", 1357 | "- Floats (with a decimal point + fractional part)\n", 1358 | "\n" 1359 | ] 1360 | }, 1361 | { 1362 | "cell_type": "code", 1363 | "execution_count": 61, 1364 | "metadata": {}, 1365 | "outputs": [ 1366 | { 1367 | "data": { 1368 | "text/plain": [ 1369 | "int" 1370 | ] 1371 | }, 1372 | "execution_count": 61, 1373 | "metadata": {}, 1374 | "output_type": "execute_result" 1375 | } 1376 | ], 1377 | "source": [ 1378 | "x = 10 # is this an integer? Yes, because it doesn't have any decimal point\n", 1379 | "\n", 1380 | "# I can ask Python: What kind of value is this?\n", 1381 | "type(x) " 1382 | ] 1383 | }, 1384 | { 1385 | "cell_type": "code", 1386 | "execution_count": 62, 1387 | "metadata": {}, 1388 | "outputs": [ 1389 | { 1390 | "data": { 1391 | "text/plain": [ 1392 | "13" 1393 | ] 1394 | }, 1395 | "execution_count": 62, 1396 | "metadata": {}, 1397 | "output_type": "execute_result" 1398 | } 1399 | ], 1400 | "source": [ 1401 | "# what can I do with an integer?\n", 1402 | "\n", 1403 | "x = 10\n", 1404 | "y = 3\n", 1405 | "\n", 1406 | "x + y # addition" 1407 | ] 1408 | }, 1409 | { 1410 | "cell_type": "code", 1411 | "execution_count": 63, 1412 | "metadata": {}, 1413 | "outputs": [ 1414 | { 1415 | "data": { 1416 | "text/plain": [ 1417 | "7" 1418 | ] 1419 | }, 1420 | "execution_count": 63, 1421 | "metadata": {}, 1422 | "output_type": "execute_result" 1423 | } 1424 | ], 1425 | "source": [ 1426 | "x - y # subtraction" 1427 | ] 1428 | }, 1429 | { 1430 | "cell_type": "code", 1431 | "execution_count": 64, 1432 | "metadata": {}, 1433 | "outputs": [ 1434 | { 1435 | "data": { 1436 | "text/plain": [ 1437 | "30" 1438 | ] 1439 | }, 1440 | "execution_count": 64, 1441 | "metadata": {}, 1442 | "output_type": "execute_result" 1443 | } 1444 | ], 1445 | "source": [ 1446 | "x * y # multiplication" 1447 | ] 1448 | }, 1449 | { 1450 | "cell_type": "code", 1451 | "execution_count": 65, 1452 | "metadata": {}, 1453 | "outputs": [ 1454 | { 1455 | "data": { 1456 | "text/plain": [ 1457 | "3.3333333333333335" 1458 | ] 1459 | }, 1460 | "execution_count": 65, 1461 | "metadata": {}, 1462 | "output_type": "execute_result" 1463 | } 1464 | ], 1465 | "source": [ 1466 | "x / y # division -- truediv, meaning that we'll get a floating point value back" 1467 | ] 1468 | }, 1469 | { 1470 | "cell_type": "code", 1471 | "execution_count": 67, 1472 | "metadata": {}, 1473 | "outputs": [ 1474 | { 1475 | "data": { 1476 | "text/plain": [ 1477 | "3" 1478 | ] 1479 | }, 1480 | "execution_count": 67, 1481 | "metadata": {}, 1482 | "output_type": "execute_result" 1483 | } 1484 | ], 1485 | "source": [ 1486 | "x // y # division -- floordiv, meaning that we'll get an integer back, chopping off (not rounding) any fractional part" 1487 | ] 1488 | }, 1489 | { 1490 | "cell_type": "code", 1491 | "execution_count": 68, 1492 | "metadata": {}, 1493 | "outputs": [ 1494 | { 1495 | "data": { 1496 | "text/plain": [ 1497 | "1000" 1498 | ] 1499 | }, 1500 | "execution_count": 68, 1501 | "metadata": {}, 1502 | "output_type": "execute_result" 1503 | } 1504 | ], 1505 | "source": [ 1506 | "x ** y # exponentiation" 1507 | ] 1508 | }, 1509 | { 1510 | "cell_type": "code", 1511 | "execution_count": 69, 1512 | "metadata": {}, 1513 | "outputs": [ 1514 | { 1515 | "data": { 1516 | "text/plain": [ 1517 | "1" 1518 | ] 1519 | }, 1520 | "execution_count": 69, 1521 | "metadata": {}, 1522 | "output_type": "execute_result" 1523 | } 1524 | ], 1525 | "source": [ 1526 | "x % y # modulus -- the remainder after integer division" 1527 | ] 1528 | }, 1529 | { 1530 | "cell_type": "code", 1531 | "execution_count": 70, 1532 | "metadata": {}, 1533 | "outputs": [], 1534 | "source": [ 1535 | "# if you're wondering why we need a % operator\n", 1536 | "# (a) very useful for checking for even/odd numbers\n", 1537 | "# (b) very useful in modern cryptography" 1538 | ] 1539 | }, 1540 | { 1541 | "cell_type": "code", 1542 | "execution_count": 71, 1543 | "metadata": {}, 1544 | "outputs": [ 1545 | { 1546 | "data": { 1547 | "text/plain": [ 1548 | "11" 1549 | ] 1550 | }, 1551 | "execution_count": 71, 1552 | "metadata": {}, 1553 | "output_type": "execute_result" 1554 | } 1555 | ], 1556 | "source": [ 1557 | "# what if I want to add 1 to an integer?\n", 1558 | "\n", 1559 | "x = 10\n", 1560 | "x = x + 1 # this looks crazy -- it really means, add 1 to x and assign back to x\n", 1561 | "\n", 1562 | "x" 1563 | ] 1564 | }, 1565 | { 1566 | "cell_type": "code", 1567 | "execution_count": 73, 1568 | "metadata": {}, 1569 | "outputs": [ 1570 | { 1571 | "data": { 1572 | "text/plain": [ 1573 | "11" 1574 | ] 1575 | }, 1576 | "execution_count": 73, 1577 | "metadata": {}, 1578 | "output_type": "execute_result" 1579 | } 1580 | ], 1581 | "source": [ 1582 | "# I could also say\n", 1583 | "\n", 1584 | "x = 10\n", 1585 | "x += 1 # this is the same as x = x + 1\n", 1586 | "\n", 1587 | "x" 1588 | ] 1589 | }, 1590 | { 1591 | "cell_type": "code", 1592 | "execution_count": 74, 1593 | "metadata": {}, 1594 | "outputs": [ 1595 | { 1596 | "data": { 1597 | "text/plain": [ 1598 | "False" 1599 | ] 1600 | }, 1601 | "execution_count": 74, 1602 | "metadata": {}, 1603 | "output_type": "execute_result" 1604 | } 1605 | ], 1606 | "source": [ 1607 | "x = 10\n", 1608 | "y = '10' \n", 1609 | "\n", 1610 | "x == y" 1611 | ] 1612 | }, 1613 | { 1614 | "cell_type": "code", 1615 | "execution_count": 76, 1616 | "metadata": {}, 1617 | "outputs": [ 1618 | { 1619 | "data": { 1620 | "text/plain": [ 1621 | "True" 1622 | ] 1623 | }, 1624 | "execution_count": 76, 1625 | "metadata": {}, 1626 | "output_type": "execute_result" 1627 | } 1628 | ], 1629 | "source": [ 1630 | "# when I use the \"input\" function, I get back a string\n", 1631 | "# it's always a string, even if the string contains digits\n", 1632 | "\n", 1633 | "# how can I take a string, and based on it get back an integer?\n", 1634 | "# answer: int\n", 1635 | "# if we invoke int() on a string that contains only digits, we get back an integer\n", 1636 | "\n", 1637 | "x == int(y) # now we're comparing an integer (x) with an integer (int(y))" 1638 | ] 1639 | }, 1640 | { 1641 | "cell_type": "markdown", 1642 | "metadata": {}, 1643 | "source": [ 1644 | "# Exercise: Guessing game\n", 1645 | "\n", 1646 | "1. Define a variable `number` to be an integer.\n", 1647 | "2. Ask the user to guess the number, and assign to `guess`.\n", 1648 | "3. Print one of three things:\n", 1649 | " - Too high\n", 1650 | " - Too low\n", 1651 | " - You got it!" 1652 | ] 1653 | }, 1654 | { 1655 | "cell_type": "code", 1656 | "execution_count": 82, 1657 | "metadata": {}, 1658 | "outputs": [ 1659 | { 1660 | "name": "stdin", 1661 | "output_type": "stream", 1662 | "text": [ 1663 | "Guess my secret number! 1234\n" 1664 | ] 1665 | }, 1666 | { 1667 | "name": "stdout", 1668 | "output_type": "stream", 1669 | "text": [ 1670 | "Too high!\n" 1671 | ] 1672 | } 1673 | ], 1674 | "source": [ 1675 | "number = 72\n", 1676 | "\n", 1677 | "guess = input('Guess my secret number!' )\n", 1678 | "guess = int(guess) # get an integer based on the user's input string\n", 1679 | "\n", 1680 | "# you could also use this:\n", 1681 | "# guess = int(input('Enter a number: '))\n", 1682 | "\n", 1683 | "if guess == number:\n", 1684 | " print('You got it!')\n", 1685 | "elif guess < number:\n", 1686 | " print('Too low!')\n", 1687 | "else:\n", 1688 | " print('Too high!')" 1689 | ] 1690 | }, 1691 | { 1692 | "cell_type": "markdown", 1693 | "metadata": {}, 1694 | "source": [ 1695 | "# Floats\n", 1696 | "\n", 1697 | "Floating-point numbers have a decimal point and a fractional part (which can be 0)." 1698 | ] 1699 | }, 1700 | { 1701 | "cell_type": "code", 1702 | "execution_count": 83, 1703 | "metadata": {}, 1704 | "outputs": [ 1705 | { 1706 | "data": { 1707 | "text/plain": [ 1708 | "float" 1709 | ] 1710 | }, 1711 | "execution_count": 83, 1712 | "metadata": {}, 1713 | "output_type": "execute_result" 1714 | } 1715 | ], 1716 | "source": [ 1717 | "n = 12.34\n", 1718 | "type(n)" 1719 | ] 1720 | }, 1721 | { 1722 | "cell_type": "code", 1723 | "execution_count": 85, 1724 | "metadata": {}, 1725 | "outputs": [ 1726 | { 1727 | "data": { 1728 | "text/plain": [ 1729 | "15.5" 1730 | ] 1731 | }, 1732 | "execution_count": 85, 1733 | "metadata": {}, 1734 | "output_type": "execute_result" 1735 | } 1736 | ], 1737 | "source": [ 1738 | "# what happens if I use floats and ints together?\n", 1739 | "# I get a float back\n", 1740 | "\n", 1741 | "10 + 5.5" 1742 | ] 1743 | }, 1744 | { 1745 | "cell_type": "code", 1746 | "execution_count": 86, 1747 | "metadata": {}, 1748 | "outputs": [ 1749 | { 1750 | "data": { 1751 | "text/plain": [ 1752 | "12.34" 1753 | ] 1754 | }, 1755 | "execution_count": 86, 1756 | "metadata": {}, 1757 | "output_type": "execute_result" 1758 | } 1759 | ], 1760 | "source": [ 1761 | "# how can I convert a string into a float?\n", 1762 | "# answer: call float() on the string, just as we called int() on the string earlier\n", 1763 | "\n", 1764 | "float('12.34')" 1765 | ] 1766 | }, 1767 | { 1768 | "cell_type": "code", 1769 | "execution_count": 87, 1770 | "metadata": {}, 1771 | "outputs": [ 1772 | { 1773 | "data": { 1774 | "text/plain": [ 1775 | "12.0" 1776 | ] 1777 | }, 1778 | "execution_count": 87, 1779 | "metadata": {}, 1780 | "output_type": "execute_result" 1781 | } 1782 | ], 1783 | "source": [ 1784 | "float('12')" 1785 | ] 1786 | }, 1787 | { 1788 | "cell_type": "code", 1789 | "execution_count": 89, 1790 | "metadata": {}, 1791 | "outputs": [ 1792 | { 1793 | "data": { 1794 | "text/plain": [ 1795 | "0.30000000000000004" 1796 | ] 1797 | }, 1798 | "execution_count": 89, 1799 | "metadata": {}, 1800 | "output_type": "execute_result" 1801 | } 1802 | ], 1803 | "source": [ 1804 | "# floats are not always accurate!\n", 1805 | "# (they're very close, but ...)\n", 1806 | "\n", 1807 | "0.1 + 0.2" 1808 | ] 1809 | }, 1810 | { 1811 | "cell_type": "code", 1812 | "execution_count": 90, 1813 | "metadata": {}, 1814 | "outputs": [ 1815 | { 1816 | "data": { 1817 | "text/plain": [ 1818 | "12" 1819 | ] 1820 | }, 1821 | "execution_count": 90, 1822 | "metadata": {}, 1823 | "output_type": "execute_result" 1824 | } 1825 | ], 1826 | "source": [ 1827 | "int(12.34) " 1828 | ] 1829 | }, 1830 | { 1831 | "cell_type": "markdown", 1832 | "metadata": {}, 1833 | "source": [ 1834 | "# Exercise: Add the fractional part\n", 1835 | "\n", 1836 | "1. Ask the user to enter two floats, and assign to two variables. (Don't forget that `input` returns a string, so you'll need to convert to `float`. Assume that the user will really enter digits and a decimal point.)\n", 1837 | "2. Add the fraction parts of these two floats together, ignoring the integer part.\n", 1838 | "\n", 1839 | "Example:\n", 1840 | "\n", 1841 | " Enter first number: 12.34\n", 1842 | " Enter second number: 56.34\n", 1843 | " Total is 0.68" 1844 | ] 1845 | }, 1846 | { 1847 | "cell_type": "code", 1848 | "execution_count": 93, 1849 | "metadata": {}, 1850 | "outputs": [ 1851 | { 1852 | "name": "stdin", 1853 | "output_type": "stream", 1854 | "text": [ 1855 | "Enter first number: 12.34\n", 1856 | "Enter second number: 56.34\n" 1857 | ] 1858 | }, 1859 | { 1860 | "name": "stdout", 1861 | "output_type": "stream", 1862 | "text": [ 1863 | "0.33999999999999986 + 0.3400000000000034 = 0.6800000000000033\n" 1864 | ] 1865 | } 1866 | ], 1867 | "source": [ 1868 | "first = input('Enter first number: ')\n", 1869 | "second = input('Enter second number: ')\n", 1870 | "\n", 1871 | "f1 = float(first)\n", 1872 | "f1 = f1 - int(f1)\n", 1873 | "\n", 1874 | "f2 = float(second)\n", 1875 | "f2 = f2 - int(f2)\n", 1876 | "\n", 1877 | "print(f'{f1} + {f2} = {f1+f2}')" 1878 | ] 1879 | }, 1880 | { 1881 | "cell_type": "code", 1882 | "execution_count": 94, 1883 | "metadata": {}, 1884 | "outputs": [ 1885 | { 1886 | "data": { 1887 | "text/plain": [ 1888 | "0" 1889 | ] 1890 | }, 1891 | "execution_count": 94, 1892 | "metadata": {}, 1893 | "output_type": "execute_result" 1894 | } 1895 | ], 1896 | "source": [ 1897 | "# we can use the \"round\" function on a float to round it to a certain number of digits\n", 1898 | "# after the decimal point\n", 1899 | "\n", 1900 | "round(0.33999999999999986)" 1901 | ] 1902 | }, 1903 | { 1904 | "cell_type": "code", 1905 | "execution_count": 97, 1906 | "metadata": {}, 1907 | "outputs": [ 1908 | { 1909 | "data": { 1910 | "text/plain": [ 1911 | "0.34" 1912 | ] 1913 | }, 1914 | "execution_count": 97, 1915 | "metadata": {}, 1916 | "output_type": "execute_result" 1917 | } 1918 | ], 1919 | "source": [ 1920 | "# how many digits do we want after the decimal point?\n", 1921 | "round(0.33999999999999986, 2)" 1922 | ] 1923 | }, 1924 | { 1925 | "cell_type": "code", 1926 | "execution_count": 98, 1927 | "metadata": {}, 1928 | "outputs": [ 1929 | { 1930 | "name": "stdin", 1931 | "output_type": "stream", 1932 | "text": [ 1933 | "Enter first number: 12.34\n", 1934 | "Enter second number: 56.34\n" 1935 | ] 1936 | }, 1937 | { 1938 | "name": "stdout", 1939 | "output_type": "stream", 1940 | "text": [ 1941 | "0.34 + 0.34 = 0.68\n" 1942 | ] 1943 | } 1944 | ], 1945 | "source": [ 1946 | "first = input('Enter first number: ')\n", 1947 | "second = input('Enter second number: ')\n", 1948 | "\n", 1949 | "f1 = float(first)\n", 1950 | "f1 = round(f1 - int(f1), 2)\n", 1951 | "\n", 1952 | "f2 = float(second)\n", 1953 | "f2 = round(f2 - int(f2), 2)\n", 1954 | "\n", 1955 | "print(f'{f1} + {f2} = {f1+f2}')" 1956 | ] 1957 | }, 1958 | { 1959 | "cell_type": "code", 1960 | "execution_count": 99, 1961 | "metadata": {}, 1962 | "outputs": [ 1963 | { 1964 | "name": "stdin", 1965 | "output_type": "stream", 1966 | "text": [ 1967 | "enter first float 12.34\n", 1968 | "enter second float 56.34\n" 1969 | ] 1970 | }, 1971 | { 1972 | "name": "stdout", 1973 | "output_type": "stream", 1974 | "text": [ 1975 | " enter first number 12.34\n", 1976 | " enter second number 56.34\n", 1977 | " total is 0.6800000000000068\n" 1978 | ] 1979 | } 1980 | ], 1981 | "source": [ 1982 | "# EG\n", 1983 | "\n", 1984 | "float1 = float(input ('enter first float'))\n", 1985 | "float2 = float(input ('enter second float'))\n", 1986 | "\n", 1987 | "print (f' enter first number {float1}')\n", 1988 | "print (f' enter second number {float2}')\n", 1989 | "print (f' total is {float1+float2-int(float1+float2)}')" 1990 | ] 1991 | }, 1992 | { 1993 | "cell_type": "code", 1994 | "execution_count": 100, 1995 | "metadata": {}, 1996 | "outputs": [ 1997 | { 1998 | "data": { 1999 | "text/plain": [ 2000 | "'1234'" 2001 | ] 2002 | }, 2003 | "execution_count": 100, 2004 | "metadata": {}, 2005 | "output_type": "execute_result" 2006 | } 2007 | ], 2008 | "source": [ 2009 | "# it's great that we can call int() on a value to get an integer, or float on a value to get a float.\n", 2010 | "# *BUT* what if I want a string?\n", 2011 | "# we can call str() on anything in all of Python, and it'll work, giving me back a string based on the value\n", 2012 | "\n", 2013 | "str(1234)" 2014 | ] 2015 | }, 2016 | { 2017 | "cell_type": "code", 2018 | "execution_count": 101, 2019 | "metadata": {}, 2020 | "outputs": [ 2021 | { 2022 | "data": { 2023 | "text/plain": [ 2024 | "'12.34'" 2025 | ] 2026 | }, 2027 | "execution_count": 101, 2028 | "metadata": {}, 2029 | "output_type": "execute_result" 2030 | } 2031 | ], 2032 | "source": [ 2033 | "str(12.34)\n" 2034 | ] 2035 | }, 2036 | { 2037 | "cell_type": "markdown", 2038 | "metadata": {}, 2039 | "source": [ 2040 | "# Next up\n", 2041 | "\n", 2042 | "1. Strings\n", 2043 | "2. Methods (especially string methods)" 2044 | ] 2045 | }, 2046 | { 2047 | "cell_type": "markdown", 2048 | "metadata": {}, 2049 | "source": [ 2050 | "# Strings\n", 2051 | "\n", 2052 | "Strings are where/how we store text in Python. Whether it's a single character or many gigabytes, strings are for text. Strings can contain any characters from all of Unicode (i.e., any language in the world). \n", 2053 | "\n", 2054 | "We create a string using quotes -- either `''` or `\"\"`, either one is fine, just be consistent in each string. " 2055 | ] 2056 | }, 2057 | { 2058 | "cell_type": "code", 2059 | "execution_count": 102, 2060 | "metadata": {}, 2061 | "outputs": [ 2062 | { 2063 | "data": { 2064 | "text/plain": [ 2065 | "26" 2066 | ] 2067 | }, 2068 | "execution_count": 102, 2069 | "metadata": {}, 2070 | "output_type": "execute_result" 2071 | } 2072 | ], 2073 | "source": [ 2074 | "s = 'abcdefghijklmnopqrstuvwxyz'\n", 2075 | "\n", 2076 | "# I can find the length of the string with the len() function\n", 2077 | "len(s) " 2078 | ] 2079 | }, 2080 | { 2081 | "cell_type": "code", 2082 | "execution_count": 103, 2083 | "metadata": {}, 2084 | "outputs": [ 2085 | { 2086 | "data": { 2087 | "text/plain": [ 2088 | "'a'" 2089 | ] 2090 | }, 2091 | "execution_count": 103, 2092 | "metadata": {}, 2093 | "output_type": "execute_result" 2094 | } 2095 | ], 2096 | "source": [ 2097 | "# how can I retrieve characters from this string?\n", 2098 | "# I can [] with an index, and the index starts with 0\n", 2099 | "\n", 2100 | "s[0] " 2101 | ] 2102 | }, 2103 | { 2104 | "cell_type": "code", 2105 | "execution_count": 104, 2106 | "metadata": {}, 2107 | "outputs": [ 2108 | { 2109 | "data": { 2110 | "text/plain": [ 2111 | "'b'" 2112 | ] 2113 | }, 2114 | "execution_count": 104, 2115 | "metadata": {}, 2116 | "output_type": "execute_result" 2117 | } 2118 | ], 2119 | "source": [ 2120 | "s[1]" 2121 | ] 2122 | }, 2123 | { 2124 | "cell_type": "code", 2125 | "execution_count": 105, 2126 | "metadata": {}, 2127 | "outputs": [ 2128 | { 2129 | "data": { 2130 | "text/plain": [ 2131 | "'f'" 2132 | ] 2133 | }, 2134 | "execution_count": 105, 2135 | "metadata": {}, 2136 | "output_type": "execute_result" 2137 | } 2138 | ], 2139 | "source": [ 2140 | "# I can use a variable, rather than a number\n", 2141 | "i = 5\n", 2142 | "\n", 2143 | "s[i]" 2144 | ] 2145 | }, 2146 | { 2147 | "cell_type": "code", 2148 | "execution_count": 106, 2149 | "metadata": {}, 2150 | "outputs": [ 2151 | { 2152 | "data": { 2153 | "text/plain": [ 2154 | "'z'" 2155 | ] 2156 | }, 2157 | "execution_count": 106, 2158 | "metadata": {}, 2159 | "output_type": "execute_result" 2160 | } 2161 | ], 2162 | "source": [ 2163 | "# since there are 26 letters\n", 2164 | "# and the first letter is at index 0\n", 2165 | "# the final letter (z) is at index 25\n", 2166 | "\n", 2167 | "s[25]" 2168 | ] 2169 | }, 2170 | { 2171 | "cell_type": "code", 2172 | "execution_count": 107, 2173 | "metadata": {}, 2174 | "outputs": [ 2175 | { 2176 | "data": { 2177 | "text/plain": [ 2178 | "'z'" 2179 | ] 2180 | }, 2181 | "execution_count": 107, 2182 | "metadata": {}, 2183 | "output_type": "execute_result" 2184 | } 2185 | ], 2186 | "source": [ 2187 | "i = len(s) - 1 # the final element will always be at 1 before the length\n", 2188 | "s[i]" 2189 | ] 2190 | }, 2191 | { 2192 | "cell_type": "code", 2193 | "execution_count": 108, 2194 | "metadata": {}, 2195 | "outputs": [ 2196 | { 2197 | "data": { 2198 | "text/plain": [ 2199 | "'z'" 2200 | ] 2201 | }, 2202 | "execution_count": 108, 2203 | "metadata": {}, 2204 | "output_type": "execute_result" 2205 | } 2206 | ], 2207 | "source": [ 2208 | "# put it all inside of the square brackets!\n", 2209 | "s[ len(s)-1 ]" 2210 | ] 2211 | }, 2212 | { 2213 | "cell_type": "code", 2214 | "execution_count": 109, 2215 | "metadata": {}, 2216 | "outputs": [ 2217 | { 2218 | "data": { 2219 | "text/plain": [ 2220 | "'z'" 2221 | ] 2222 | }, 2223 | "execution_count": 109, 2224 | "metadata": {}, 2225 | "output_type": "execute_result" 2226 | } 2227 | ], 2228 | "source": [ 2229 | "# we can just use negative indexes\n", 2230 | "s[-1] # this is the same as s[len(s)-1]" 2231 | ] 2232 | }, 2233 | { 2234 | "cell_type": "code", 2235 | "execution_count": 110, 2236 | "metadata": {}, 2237 | "outputs": [ 2238 | { 2239 | "data": { 2240 | "text/plain": [ 2241 | "'y'" 2242 | ] 2243 | }, 2244 | "execution_count": 110, 2245 | "metadata": {}, 2246 | "output_type": "execute_result" 2247 | } 2248 | ], 2249 | "source": [ 2250 | "s[-2]" 2251 | ] 2252 | }, 2253 | { 2254 | "cell_type": "code", 2255 | "execution_count": 111, 2256 | "metadata": {}, 2257 | "outputs": [ 2258 | { 2259 | "data": { 2260 | "text/plain": [ 2261 | "'x'" 2262 | ] 2263 | }, 2264 | "execution_count": 111, 2265 | "metadata": {}, 2266 | "output_type": "execute_result" 2267 | } 2268 | ], 2269 | "source": [ 2270 | "s[-3]" 2271 | ] 2272 | }, 2273 | { 2274 | "cell_type": "code", 2275 | "execution_count": 112, 2276 | "metadata": {}, 2277 | "outputs": [ 2278 | { 2279 | "ename": "IndexError", 2280 | "evalue": "string index out of range", 2281 | "output_type": "error", 2282 | "traceback": [ 2283 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2284 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 2285 | "Cell \u001b[0;32mIn[112], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43ms\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m100\u001b[39;49m\u001b[43m]\u001b[49m \n", 2286 | "\u001b[0;31mIndexError\u001b[0m: string index out of range" 2287 | ] 2288 | } 2289 | ], 2290 | "source": [ 2291 | "s[-100] " 2292 | ] 2293 | }, 2294 | { 2295 | "cell_type": "code", 2296 | "execution_count": 113, 2297 | "metadata": {}, 2298 | "outputs": [ 2299 | { 2300 | "ename": "IndexError", 2301 | "evalue": "string index out of range", 2302 | "output_type": "error", 2303 | "traceback": [ 2304 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2305 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 2306 | "Cell \u001b[0;32mIn[113], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43ms\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m100\u001b[39;49m\u001b[43m]\u001b[49m\n", 2307 | "\u001b[0;31mIndexError\u001b[0m: string index out of range" 2308 | ] 2309 | } 2310 | ], 2311 | "source": [ 2312 | "s[100]" 2313 | ] 2314 | }, 2315 | { 2316 | "cell_type": "markdown", 2317 | "metadata": {}, 2318 | "source": [ 2319 | "# Exercise: Retrieve a character\n", 2320 | "\n", 2321 | "1. Ask the user to enter a string, and assign to a variable.\n", 2322 | "2. Ask the user to enter an integer, which we'll use as an index in the string.\n", 2323 | "3. If the integer is < 0, scold the user for giving something too small\n", 2324 | "4. If the integer is >= len(string), scold them for giving something too big\n", 2325 | "5. Otherwise, print the character and its index\n", 2326 | "\n", 2327 | "Example:\n", 2328 | "\n", 2329 | " Enter text: hello out there\n", 2330 | " Enter an index: 7\n", 2331 | " index 7 in hello out there is u" 2332 | ] 2333 | }, 2334 | { 2335 | "cell_type": "code", 2336 | "execution_count": 118, 2337 | "metadata": {}, 2338 | "outputs": [ 2339 | { 2340 | "name": "stdin", 2341 | "output_type": "stream", 2342 | "text": [ 2343 | "Enter text: hello\n", 2344 | "Enter index: 5\n" 2345 | ] 2346 | }, 2347 | { 2348 | "name": "stdout", 2349 | "output_type": "stream", 2350 | "text": [ 2351 | "Too high\n" 2352 | ] 2353 | } 2354 | ], 2355 | "source": [ 2356 | "s = input('Enter text: ')\n", 2357 | "i = input('Enter index: ')\n", 2358 | "index = int(i)\n", 2359 | "\n", 2360 | "if index < 0:\n", 2361 | " print(f'Too low')\n", 2362 | "elif index >= len(s):\n", 2363 | " print(f'Too high')\n", 2364 | "else:\n", 2365 | " print(f'Index {index} in {s} is {s[index]}')" 2366 | ] 2367 | }, 2368 | { 2369 | "cell_type": "code", 2370 | "execution_count": null, 2371 | "metadata": {}, 2372 | "outputs": [], 2373 | "source": [ 2374 | "# JD \n", 2375 | "string = input(\"Enter a String: \")\n", 2376 | "integer = int(input(\"ENter a number: \"))\n", 2377 | "\n", 2378 | "if integer < 0:\n", 2379 | " print(\"please enter a bigger number\")\n", 2380 | "elif integer >= len(string):\n", 2381 | " print(\"please give a smaller number\")\n", 2382 | "else:\n", 2383 | " print(f'index {integer} in {string} is {string[integer]}')" 2384 | ] 2385 | }, 2386 | { 2387 | "cell_type": "markdown", 2388 | "metadata": {}, 2389 | "source": [ 2390 | "# Other string functionality\n", 2391 | "\n", 2392 | "1. We can retrieve more than one character with a \"slice\": `s[start:finish]` returns a subset of `s`, starting at index `start` and going up to and not including index `finish`. This is known as a \"slice.\" If we don't include either `start` or `finish`, we start from that end.\n", 2393 | "2. We can search in a string to see if a character is there using the `in` operator, which returns `True` if the left side is in the right side." 2394 | ] 2395 | }, 2396 | { 2397 | "cell_type": "code", 2398 | "execution_count": 121, 2399 | "metadata": {}, 2400 | "outputs": [ 2401 | { 2402 | "data": { 2403 | "text/plain": [ 2404 | "26" 2405 | ] 2406 | }, 2407 | "execution_count": 121, 2408 | "metadata": {}, 2409 | "output_type": "execute_result" 2410 | } 2411 | ], 2412 | "source": [ 2413 | "s = 'abcdefghijklmnopqrstuvwxyz'\n", 2414 | "len(s)" 2415 | ] 2416 | }, 2417 | { 2418 | "cell_type": "code", 2419 | "execution_count": 122, 2420 | "metadata": {}, 2421 | "outputs": [ 2422 | { 2423 | "data": { 2424 | "text/plain": [ 2425 | "'klmnopqrst'" 2426 | ] 2427 | }, 2428 | "execution_count": 122, 2429 | "metadata": {}, 2430 | "output_type": "execute_result" 2431 | } 2432 | ], 2433 | "source": [ 2434 | "s[10:20] # from 10, until (not including) 20\n" 2435 | ] 2436 | }, 2437 | { 2438 | "cell_type": "code", 2439 | "execution_count": 123, 2440 | "metadata": {}, 2441 | "outputs": [ 2442 | { 2443 | "data": { 2444 | "text/plain": [ 2445 | "'abcdefghijklmnopqrst'" 2446 | ] 2447 | }, 2448 | "execution_count": 123, 2449 | "metadata": {}, 2450 | "output_type": "execute_result" 2451 | } 2452 | ], 2453 | "source": [ 2454 | "s[:20] # from the start, up to and not including index 20" 2455 | ] 2456 | }, 2457 | { 2458 | "cell_type": "code", 2459 | "execution_count": 124, 2460 | "metadata": {}, 2461 | "outputs": [ 2462 | { 2463 | "data": { 2464 | "text/plain": [ 2465 | "'klmnopqrstuvwxyz'" 2466 | ] 2467 | }, 2468 | "execution_count": 124, 2469 | "metadata": {}, 2470 | "output_type": "execute_result" 2471 | } 2472 | ], 2473 | "source": [ 2474 | "s[10:] # from index 10, through the end" 2475 | ] 2476 | }, 2477 | { 2478 | "cell_type": "code", 2479 | "execution_count": 125, 2480 | "metadata": {}, 2481 | "outputs": [ 2482 | { 2483 | "data": { 2484 | "text/plain": [ 2485 | "True" 2486 | ] 2487 | }, 2488 | "execution_count": 125, 2489 | "metadata": {}, 2490 | "output_type": "execute_result" 2491 | } 2492 | ], 2493 | "source": [ 2494 | "# search in a string with \"in\"\n", 2495 | "\n", 2496 | "'b' in s" 2497 | ] 2498 | }, 2499 | { 2500 | "cell_type": "code", 2501 | "execution_count": 127, 2502 | "metadata": {}, 2503 | "outputs": [ 2504 | { 2505 | "data": { 2506 | "text/plain": [ 2507 | "True" 2508 | ] 2509 | }, 2510 | "execution_count": 127, 2511 | "metadata": {}, 2512 | "output_type": "execute_result" 2513 | } 2514 | ], 2515 | "source": [ 2516 | "'tuv' in s" 2517 | ] 2518 | }, 2519 | { 2520 | "cell_type": "markdown", 2521 | "metadata": {}, 2522 | "source": [ 2523 | "# Strings are IMMUTABLE\n", 2524 | "\n", 2525 | "Once you create a string, its contents cannot be changed.\n", 2526 | "\n" 2527 | ] 2528 | }, 2529 | { 2530 | "cell_type": "code", 2531 | "execution_count": 128, 2532 | "metadata": {}, 2533 | "outputs": [ 2534 | { 2535 | "ename": "TypeError", 2536 | "evalue": "'str' object does not support item assignment", 2537 | "output_type": "error", 2538 | "traceback": [ 2539 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2540 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 2541 | "Cell \u001b[0;32mIn[128], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43ms\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m!\u001b[39m\u001b[38;5;124m'\u001b[39m\n", 2542 | "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" 2543 | ] 2544 | } 2545 | ], 2546 | "source": [ 2547 | "s[0] = '!'" 2548 | ] 2549 | }, 2550 | { 2551 | "cell_type": "markdown", 2552 | "metadata": {}, 2553 | "source": [ 2554 | "# Exercise: Pig Latin\n", 2555 | "\n", 2556 | "To translate a word from English to Pig Latin, look at the first letter of the word:\n", 2557 | "\n", 2558 | "- If the first letter is a vowel (a, e, i, o, u), then add `way` to the end of the word.\n", 2559 | "- Otherwise, move the first letter to the end, and add `ay`.\n", 2560 | "\n", 2561 | "Examples:\n", 2562 | "- `computer` -> `omputercay`\n", 2563 | "- `papaya` -> `apayapay`\n", 2564 | "- `apple` -> `appleway`\n", 2565 | "\n", 2566 | "1. Ask the user to enter a word\n", 2567 | "2. Translate the word into Pig Latin." 2568 | ] 2569 | }, 2570 | { 2571 | "cell_type": "code", 2572 | "execution_count": 130, 2573 | "metadata": {}, 2574 | "outputs": [ 2575 | { 2576 | "name": "stdin", 2577 | "output_type": "stream", 2578 | "text": [ 2579 | "Enter word: computer\n" 2580 | ] 2581 | } 2582 | ], 2583 | "source": [ 2584 | "word = input('Enter word: ')\n", 2585 | "\n", 2586 | "if word[0] == 'a' or word[0] == 'e' or word[0] == 'i' or word[0] == 'o' or word[0] == 'u':\n", 2587 | " print(word + 'way')" 2588 | ] 2589 | }, 2590 | { 2591 | "cell_type": "code", 2592 | "execution_count": 133, 2593 | "metadata": {}, 2594 | "outputs": [ 2595 | { 2596 | "name": "stdin", 2597 | "output_type": "stream", 2598 | "text": [ 2599 | "Enter word: elephant\n" 2600 | ] 2601 | }, 2602 | { 2603 | "name": "stdout", 2604 | "output_type": "stream", 2605 | "text": [ 2606 | "elephantway\n" 2607 | ] 2608 | } 2609 | ], 2610 | "source": [ 2611 | "word = input('Enter word: ')\n", 2612 | "\n", 2613 | "if word[0] in 'aeiou': # this is the standard/Pythonic way to do it\n", 2614 | " print(word + 'way')\n", 2615 | "else:\n", 2616 | " print(word[1:] + word[0] + 'ay') # move the first letter to the end" 2617 | ] 2618 | }, 2619 | { 2620 | "cell_type": "code", 2621 | "execution_count": null, 2622 | "metadata": {}, 2623 | "outputs": [], 2624 | "source": [ 2625 | "# SY\n", 2626 | "\n", 2627 | "str1 = input('Enter the word = ')\n", 2628 | "\n", 2629 | "if('a' in str1[0] or 'e' in str1[0] or 'i' in str1[0] or 'o' in str1[0] or 'u' in str1[0]):\n", 2630 | " print(f'{str1}way')\n", 2631 | "else:\n", 2632 | " print(f'{str1[1:]}{str1[0]}ay')" 2633 | ] 2634 | }, 2635 | { 2636 | "cell_type": "code", 2637 | "execution_count": null, 2638 | "metadata": {}, 2639 | "outputs": [], 2640 | "source": [ 2641 | "# JD\n", 2642 | "\n", 2643 | "word = input(\"Enter a word: \")\n", 2644 | "\n", 2645 | "if word[0] in ['a','e','i','o','u'] or word[0] in ['A','E','I','O','U']:\n", 2646 | " #word = str(word) + \"way\"\n", 2647 | " print(f'{word}way')\n", 2648 | "else:\n", 2649 | " print(word[1:] + word[0] + 'ay')" 2650 | ] 2651 | }, 2652 | { 2653 | "cell_type": "code", 2654 | "execution_count": null, 2655 | "metadata": {}, 2656 | "outputs": [], 2657 | "source": [ 2658 | "# P\n", 2659 | "\n", 2660 | "s= input(\"Entera word: \")\n", 2661 | "a= 'a','e','i','o','u'\n", 2662 | "if s[0] in a: \n", 2663 | " print(f'{s[1:]}way')\n", 2664 | "else:\n", 2665 | " print(f'{s[1:]}{s[0]}ay')" 2666 | ] 2667 | }, 2668 | { 2669 | "cell_type": "markdown", 2670 | "metadata": {}, 2671 | "source": [ 2672 | "# Methods (vs. functions)\n", 2673 | "\n", 2674 | "We've seen that functions are the verbs in a programming language:\n", 2675 | "\n", 2676 | "- `input`\n", 2677 | "- `print`\n", 2678 | "- `len`\n", 2679 | "\n", 2680 | "But there is another kind of verb, called a \"method\", in Python. Methods are different from functions, in that they are attached to objects. We don't say\n", 2681 | "\n", 2682 | " FUNC(DATA)\n", 2683 | "\n", 2684 | "instead, we say\n", 2685 | "\n", 2686 | " DATA.METHOD(ARG1, ARG2)\n", 2687 | "\n", 2688 | "We need data to run it on!\n", 2689 | "\n", 2690 | "Example:\n", 2691 | "\n", 2692 | " The method str.lower, which is invoked on a string, and returns a new string similar to the old but all lowercase" 2693 | ] 2694 | }, 2695 | { 2696 | "cell_type": "code", 2697 | "execution_count": 135, 2698 | "metadata": {}, 2699 | "outputs": [ 2700 | { 2701 | "data": { 2702 | "text/plain": [ 2703 | "'abcdeabcde'" 2704 | ] 2705 | }, 2706 | "execution_count": 135, 2707 | "metadata": {}, 2708 | "output_type": "execute_result" 2709 | } 2710 | ], 2711 | "source": [ 2712 | "'abcdeABCDE'.lower()" 2713 | ] 2714 | }, 2715 | { 2716 | "cell_type": "code", 2717 | "execution_count": 137, 2718 | "metadata": {}, 2719 | "outputs": [ 2720 | { 2721 | "name": "stdin", 2722 | "output_type": "stream", 2723 | "text": [ 2724 | "Enter your name: Reuven \n" 2725 | ] 2726 | }, 2727 | { 2728 | "name": "stdout", 2729 | "output_type": "stream", 2730 | "text": [ 2731 | "Hello, Reuven !\n" 2732 | ] 2733 | } 2734 | ], 2735 | "source": [ 2736 | "# let's get the user's name\n", 2737 | "\n", 2738 | "name = input('Enter your name: ')\n", 2739 | "\n", 2740 | "print(f'Hello, {name}!')" 2741 | ] 2742 | }, 2743 | { 2744 | "cell_type": "code", 2745 | "execution_count": 138, 2746 | "metadata": {}, 2747 | "outputs": [ 2748 | { 2749 | "name": "stdin", 2750 | "output_type": "stream", 2751 | "text": [ 2752 | "Enter your name: Reuven \n" 2753 | ] 2754 | }, 2755 | { 2756 | "name": "stdout", 2757 | "output_type": "stream", 2758 | "text": [ 2759 | "Hello, Reuven!\n" 2760 | ] 2761 | } 2762 | ], 2763 | "source": [ 2764 | "\n", 2765 | "name = input('Enter your name: ').strip() # strip is a method that returns a string without leading/trailing whitespace\n", 2766 | "\n", 2767 | "print(f'Hello, {name}!')" 2768 | ] 2769 | }, 2770 | { 2771 | "cell_type": "code", 2772 | "execution_count": 139, 2773 | "metadata": {}, 2774 | "outputs": [ 2775 | { 2776 | "data": { 2777 | "text/plain": [ 2778 | "'Reuven'" 2779 | ] 2780 | }, 2781 | "execution_count": 139, 2782 | "metadata": {}, 2783 | "output_type": "execute_result" 2784 | } 2785 | ], 2786 | "source": [ 2787 | "name" 2788 | ] 2789 | }, 2790 | { 2791 | "cell_type": "code", 2792 | "execution_count": null, 2793 | "metadata": {}, 2794 | "outputs": [], 2795 | "source": [] 2796 | } 2797 | ], 2798 | "metadata": { 2799 | "kernelspec": { 2800 | "display_name": "Python 3 (ipykernel)", 2801 | "language": "python", 2802 | "name": "python3" 2803 | }, 2804 | "language_info": { 2805 | "codemirror_mode": { 2806 | "name": "ipython", 2807 | "version": 3 2808 | }, 2809 | "file_extension": ".py", 2810 | "mimetype": "text/x-python", 2811 | "name": "python", 2812 | "nbconvert_exporter": "python", 2813 | "pygments_lexer": "ipython3", 2814 | "version": "3.12.1" 2815 | } 2816 | }, 2817 | "nbformat": 4, 2818 | "nbformat_minor": 4 2819 | } 2820 | -------------------------------------------------------------------------------- /Python, 2024 07July 10.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Agenda: Loops, lists, and tuples\n", 8 | "\n", 9 | "1. Q&A\n", 10 | "2. Loops\n", 11 | " - `for` loops\n", 12 | " - `while` loops\n", 13 | " - Looping a number of times with `range`\n", 14 | " - Getting the index in different ways\n", 15 | " - Controlling our loop with `break` and `continue`\n", 16 | "3. Lists\n", 17 | " - Creating lists\n", 18 | " - What can we do with lists (same as strings)?\n", 19 | " - What can we do with lists (different from strings)?\n", 20 | " - Lists are mutable\n", 21 | "4. Strings to lists, and back\n", 22 | " - Converting strings to lists (`str.split`)\n", 23 | " - Converting lists to strings (`str.join`)\n", 24 | "5. Tuples\n", 25 | " - What are tuples?\n", 26 | " - Where do we use them?\n", 27 | " - How are they similar to lists (and strings)?\n", 28 | " - How are they different from lists (and strings)?\n", 29 | "6. Tuple unpacking" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "# DRY -- don't repeat yourself\n", 37 | "\n", 38 | "Let's say that I want to print every character in a string, `s`. How can I do that?" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 1, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "a\n", 51 | "b\n", 52 | "c\n", 53 | "d\n" 54 | ] 55 | } 56 | ], 57 | "source": [ 58 | "s = 'abcd'\n", 59 | "\n", 60 | "print(s[0])\n", 61 | "print(s[1])\n", 62 | "print(s[2])\n", 63 | "print(s[3])" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "The DRY rule tells us that if we look at what we've done, we have four lines that (more or less) repeat themselves. That's something we should try to avoid in our programs.\n", 71 | "\n", 72 | "Why?\n", 73 | "\n", 74 | "- If we write less code, it's easier to write\n", 75 | "- If we write less code, it's easier to read and debug\n", 76 | "- Less code is easier to wrap your head around\n", 77 | "- It'll probably run faster\n", 78 | "- It's more semantically powerful\n", 79 | "\n", 80 | "A loop allows us to repeat certain actions multiple times, with (if we want) variations in each of those iterations.\n", 81 | "\n", 82 | "Python has two different kinds of loops:\n", 83 | "\n", 84 | "- `for` -- these are much more common\n", 85 | "- `while`" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 2, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "name": "stdout", 95 | "output_type": "stream", 96 | "text": [ 97 | "a\n", 98 | "b\n", 99 | "c\n", 100 | "d\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "# if I want to print all of the characters in the string s,\n", 106 | "# here is a for loop that does it:\n", 107 | "\n", 108 | "s = 'abcd'\n", 109 | "\n", 110 | "for one_character in s:\n", 111 | " print(one_character)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "# `for` loop syntax\n", 119 | "\n", 120 | "1. The first line of the loop is `for` .. `in` ..\n", 121 | "2. After the word `for`, we have a \"loop variable.\" That is the variable which will be assigned a new value with each iteration. Its name is *COMPLETELY* up to you; the loop behavior doesn't change based on the variable name.\n", 122 | "3. After the word `in` on the top line, we have an object, one which must be \"iterable.\" What is an iterable object? One that knows how to behave inside of a `for` loop. String, lists, tuples, dicts, and files are all iterable. Integers and floats are not.\n", 123 | "4. At the end of the line, we have a `:`.\n", 124 | "5. The following line is indented (because it's after a colon), and starts the \"loop body\".\n", 125 | "6. The loop body can contain any code we want, and can be as long (or as short) as we want.\n", 126 | "\n", 127 | "# What's really going on here?\n", 128 | "1. `for` turns to the object at the end of the line, and asks it: Are you iterable?\n", 129 | " - If the answer is \"no,\" then the loop exits right there with an exception.\n", 130 | "2. Assuming that the object is iterable, the `for` loop then says to it: Give me your next value.\n", 131 | " - If there are no more values, then the loop exits silently, no error.\n", 132 | "3. If there is another value, then it is assigned to the loop variable\n", 133 | "4. We execute the body of the loop.\n", 134 | "5. Go back to line 2.\n", 135 | "\n", 136 | "# A few things to notice\n", 137 | "1. The loop is not in control; the object on which we're looping is in control.\n", 138 | "2. In other languages, the `for` loop assigns an index, and uses it to retrieve values from the object.\n", 139 | "3. We don't care what kind of object is at the end of the first line; so long as it's iterable, we're fine with it." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 3, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "name": "stdout", 149 | "output_type": "stream", 150 | "text": [ 151 | "a\n", 152 | "b\n", 153 | "c\n", 154 | "d\n", 155 | "e\n" 156 | ] 157 | } 158 | ], 159 | "source": [ 160 | "for one_item in 'abcde':\n", 161 | " print(one_item)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "# Exercise: Vowels, digits, and others\n", 169 | "\n", 170 | "1. Define three variables, `vowels`, `digits`, and `others`, and assign them all the value 0.\n", 171 | "2. Ask the user to enter some text.\n", 172 | "3. Go through that text, one character at a time:\n", 173 | " - If it's a digit, then add 1 to `digits`\n", 174 | " - If it's a vowel (a,e,i,o.u), then add 1 to `vowels`\n", 175 | " - Otherwise, add 1 to `others`\n", 176 | "4. Print the values of `vowels`, `digits`, and `others`.\n", 177 | " \n", 178 | "Example:\n", 179 | "\n", 180 | " Enter text: hello!! 123\n", 181 | " vowels: 2\n", 182 | " digits: 3\n", 183 | " others: 6" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 6, 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "name": "stdin", 193 | "output_type": "stream", 194 | "text": [ 195 | "Enter text: hello!! 123\n" 196 | ] 197 | }, 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "vowels: 2\n", 203 | "digits: 3\n", 204 | "others: 6\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "vowels = 0\n", 210 | "digits = 0\n", 211 | "others = 0\n", 212 | "\n", 213 | "text = input('Enter text: ').strip() # get user input, remove whitespace on the ends, assign to text\n", 214 | "\n", 215 | "for one_character in text:\n", 216 | " if one_character in 'aeiou':\n", 217 | " # print(f'{one_character} is a vowel')\n", 218 | " vowels += 1\n", 219 | " elif one_character.isdigit():\n", 220 | " digits += 1\n", 221 | " # print(f'{one_character} is a digit')\n", 222 | " else:\n", 223 | " others += 1\n", 224 | " # print(f'{one_character} is something else')\n", 225 | "\n", 226 | "print(f'vowels: {vowels}')\n", 227 | "print(f'digits: {digits}')\n", 228 | "print(f'others: {others}')" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 7, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "name": "stdin", 238 | "output_type": "stream", 239 | "text": [ 240 | "Enter some text: hello!! 123\n" 241 | ] 242 | }, 243 | { 244 | "name": "stdout", 245 | "output_type": "stream", 246 | "text": [ 247 | "vowels:2, digits:3, others: 6\n" 248 | ] 249 | } 250 | ], 251 | "source": [ 252 | "# IM\n", 253 | "\n", 254 | "vowels=0\n", 255 | "digits=0\n", 256 | "others=0\n", 257 | "\n", 258 | "phrase=input(\"Enter some text: \")\n", 259 | "\n", 260 | "vowel= 'aeiouAEIOU'\n", 261 | "digit= '0123456789'\n", 262 | "\n", 263 | "for one_char in phrase:\n", 264 | " if one_char in vowel:\n", 265 | " vowels += 1\n", 266 | " elif one_char in digit:\n", 267 | " digits +=1\n", 268 | " else:\n", 269 | " others += 1\n", 270 | "\n", 271 | "print( f'vowels:{vowels}, digits:{digits}, others: {others}')" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 8, 277 | "metadata": {}, 278 | "outputs": [], 279 | "source": [ 280 | "# What is strip?\n", 281 | "# strip is a method, not a function. Still a verb, but it's attached (with .) to the end\n", 282 | "# of a value. It must be a string, because strip is a string method. Its full name is str.strip.\n", 283 | "\n", 284 | "# we can run str.strip on any string we want. We'll get back a new string, identical to the original\n", 285 | "# one, but without any spaces (or other whitespace characters) at the start and end.\n", 286 | "\n", 287 | "# you can run str.strip on any string. Here, we're going on the fact that the input function always\n", 288 | "# returns a string. We run str.strip on that string (which is anonymous), getting back a new string\n", 289 | "# that is identical, but without leading/trailing whitespace. That string is assigned to the variable\n", 290 | "# \"text\" on the left of the assignment operator, =." 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 10, 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "'abcdefgh'" 302 | ] 303 | }, 304 | "execution_count": 10, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "# to remove spaces in the middle is a bit tougher; you can remove them all with \n", 311 | "\n", 312 | "s = 'abcd efgh'\n", 313 | "s.replace(' ', '') # replaces the space character with the empty string" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 11, 319 | "metadata": {}, 320 | "outputs": [ 321 | { 322 | "data": { 323 | "text/plain": [ 324 | "True" 325 | ] 326 | }, 327 | "execution_count": 11, 328 | "metadata": {}, 329 | "output_type": "execute_result" 330 | } 331 | ], 332 | "source": [ 333 | "# str.isdigit is a string method (as you can see from its name), and it returns True\n", 334 | "# if all of the characters in the string are numbers 0-9. This is a simple way to check\n", 335 | "# if you can run \"int\" on a string and not get an error.\n", 336 | "\n", 337 | "s = '1234'\n", 338 | "s.isdigit()" 339 | ] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": 13, 344 | "metadata": {}, 345 | "outputs": [ 346 | { 347 | "ename": "TypeError", 348 | "evalue": "'int' object is not iterable", 349 | "output_type": "error", 350 | "traceback": [ 351 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 352 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 353 | "Cell \u001b[0;32mIn[13], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# It's great to iterate over a string!\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# what about iterating a number of times?\u001b[39;00m\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcounter\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;241;43m5\u001b[39;49m\u001b[43m:\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mprint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mHooray!\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", 354 | "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable" 355 | ] 356 | } 357 | ], 358 | "source": [ 359 | "# It's great to iterate over a string!\n", 360 | "# what about iterating a number of times?\n", 361 | "\n", 362 | "for counter in 5:\n", 363 | " print('Hooray!')" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "# Using `range` \n", 371 | "\n", 372 | "If we want to iterate a certain number of times, we need to use the `range` builtin function, which returns an object that we can use to iterate a number of times.\n", 373 | "\n" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 14, 379 | "metadata": {}, 380 | "outputs": [ 381 | { 382 | "name": "stdout", 383 | "output_type": "stream", 384 | "text": [ 385 | "Hooray!\n", 386 | "Hooray!\n", 387 | "Hooray!\n", 388 | "Hooray!\n", 389 | "Hooray!\n" 390 | ] 391 | } 392 | ], 393 | "source": [ 394 | "for counter in range(5):\n", 395 | " print('Hooray!')" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 15, 401 | "metadata": {}, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "Hooray!\n", 408 | "Hooray!\n", 409 | "Hooray!\n", 410 | "Hooray!\n" 411 | ] 412 | } 413 | ], 414 | "source": [ 415 | "n = 4\n", 416 | "\n", 417 | "for counter in range(n):\n", 418 | " print('Hooray!')" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "execution_count": 16, 424 | "metadata": {}, 425 | "outputs": [], 426 | "source": [ 427 | "# range actually returns an integer with each iteration, starting at 0\n", 428 | "# and going up to the number provided - 1. \n", 429 | "\n", 430 | "# So range(5) will iterate 5 times, from 0 through 4." 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": 17, 436 | "metadata": {}, 437 | "outputs": [ 438 | { 439 | "name": "stdout", 440 | "output_type": "stream", 441 | "text": [ 442 | "0 Hooray!\n", 443 | "1 Hooray!\n", 444 | "2 Hooray!\n", 445 | "3 Hooray!\n" 446 | ] 447 | } 448 | ], 449 | "source": [ 450 | "for counter in range(n):\n", 451 | " print(f'{counter} Hooray!')" 452 | ] 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": 18, 457 | "metadata": {}, 458 | "outputs": [ 459 | { 460 | "name": "stdin", 461 | "output_type": "stream", 462 | "text": [ 463 | "Enter some text : hello!! 123\n" 464 | ] 465 | }, 466 | { 467 | "name": "stdout", 468 | "output_type": "stream", 469 | "text": [ 470 | "h is something else\n", 471 | "e is a Vowel\n", 472 | "l is something else\n", 473 | "l is something else\n", 474 | "o is a Vowel\n", 475 | "! is something else\n", 476 | "! is something else\n", 477 | " is something else\n", 478 | "1 is a Digit\n", 479 | "2 is a Digit\n", 480 | "3 is a Digit\n" 481 | ] 482 | } 483 | ], 484 | "source": [ 485 | "# JD\n", 486 | "\n", 487 | "vowels = 0\n", 488 | "digits = 0\n", 489 | "others = 0\n", 490 | "\n", 491 | "char = input('Enter some text : ').strip()\n", 492 | "\n", 493 | "for c in char:\n", 494 | " if c.isdigit():\n", 495 | " print(f'{c} is a Digit')\n", 496 | " \n", 497 | " elif c in 'a,e,i,o,u':\n", 498 | " print(f'{c} is a Vowel')\n", 499 | " else:\n", 500 | " print(f'{c} is something else')" 501 | ] 502 | }, 503 | { 504 | "cell_type": "markdown", 505 | "metadata": {}, 506 | "source": [ 507 | "# Functions vs methods\n", 508 | "\n", 509 | "Both are \"verbs\" in the Python world. One (functions) are free-floating, and can be invoked on anyone. Methods are attachedk to another object, in name and functionality. Sou you cannot run a string method on an integer.\n", 510 | "\n", 511 | "Example:\n", 512 | "\n", 513 | "```python3\n", 514 | "x = len(s) # this is a function\n", 515 | "```\n", 516 | "\n", 517 | "I can also say:\n", 518 | "\n", 519 | "```python3\n", 520 | "s = s.lower() # str.lower is a method" 521 | ] 522 | }, 523 | { 524 | "cell_type": "code", 525 | "execution_count": null, 526 | "metadata": {}, 527 | "outputs": [], 528 | "source": [] 529 | }, 530 | { 531 | "cell_type": "markdown", 532 | "metadata": {}, 533 | "source": [ 534 | "# Exercise: Name triangles\n", 535 | "\n", 536 | "1. Ask the user to enter their name.\n", 537 | "2. Print a \"name triangle,\" which means that on the first line, we print the first character of the name. On the second line, we print the first 2. Then print the first 3, etc., until printed the full name.\n", 538 | "\n", 539 | "Example:\n", 540 | "\n", 541 | " Enter your name: Reuven\n", 542 | " R\n", 543 | " Re\n", 544 | " Reu\n", 545 | " Reuv\n", 546 | " Reuve\n", 547 | " Reuven\n", 548 | "\n", 549 | "1. You'll probably want to use `range`\n", 550 | "2. Don't forget slices, i.e., `[start:stop]` in the string.\n", 551 | "3. You can use `len` to get the length of the string." 552 | ] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": 20, 557 | "metadata": {}, 558 | "outputs": [ 559 | { 560 | "name": "stdout", 561 | "output_type": "stream", 562 | "text": [ 563 | "R\n", 564 | "Re\n", 565 | "Reu\n", 566 | "Reuv\n", 567 | "Reuve\n", 568 | "Reuven\n" 569 | ] 570 | } 571 | ], 572 | "source": [ 573 | "# if I didn't have a loop, what would I want?\n", 574 | "\n", 575 | "name = 'Reuven'\n", 576 | "\n", 577 | "print(name[:1])\n", 578 | "print(name[:2])\n", 579 | "print(name[:3])\n", 580 | "print(name[:4])\n", 581 | "print(name[:5])\n", 582 | "print(name[:6]) # the max index for our string is 5; its len is 6\n", 583 | "\n", 584 | "# yes, you can actually go beyond the bounds of the string with a slice" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": 22, 590 | "metadata": {}, 591 | "outputs": [ 592 | { 593 | "name": "stdout", 594 | "output_type": "stream", 595 | "text": [ 596 | "R\n", 597 | "Re\n", 598 | "Reu\n", 599 | "Reuv\n", 600 | "Reuve\n", 601 | "Reuven\n" 602 | ] 603 | } 604 | ], 605 | "source": [ 606 | "name = 'Reuven'\n", 607 | "\n", 608 | "for max_index in range(len(name)):\n", 609 | " print(name[:max_index+1])" 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": 24, 615 | "metadata": {}, 616 | "outputs": [ 617 | { 618 | "name": "stdin", 619 | "output_type": "stream", 620 | "text": [ 621 | "Enter your Name: Reuven\n" 622 | ] 623 | }, 624 | { 625 | "name": "stdout", 626 | "output_type": "stream", 627 | "text": [ 628 | "R\n", 629 | "Re\n", 630 | "Reu\n", 631 | "Reuv\n", 632 | "Reuve\n", 633 | "Reuven\n" 634 | ] 635 | } 636 | ], 637 | "source": [ 638 | "# SY\n", 639 | "\n", 640 | "name = input('Enter your Name: ') \n", 641 | "for loop in range(len(name)): \n", 642 | " print(name[:loop+1])" 643 | ] 644 | }, 645 | { 646 | "cell_type": "code", 647 | "execution_count": 25, 648 | "metadata": {}, 649 | "outputs": [ 650 | { 651 | "name": "stdin", 652 | "output_type": "stream", 653 | "text": [ 654 | "What is your name? Reuven\n" 655 | ] 656 | }, 657 | { 658 | "name": "stdout", 659 | "output_type": "stream", 660 | "text": [ 661 | "R\n", 662 | "Re\n", 663 | "Reu\n", 664 | "Reuv\n", 665 | "Reuve\n", 666 | "Reuven\n" 667 | ] 668 | } 669 | ], 670 | "source": [ 671 | "# AM \n", 672 | "\n", 673 | "name = input('What is your name? ')\n", 674 | "for count in range(len(name)):\n", 675 | " print(name[:count+1])" 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "execution_count": 27, 681 | "metadata": {}, 682 | "outputs": [ 683 | { 684 | "name": "stdin", 685 | "output_type": "stream", 686 | "text": [ 687 | "Enter your Name : Reuven\n" 688 | ] 689 | }, 690 | { 691 | "name": "stdout", 692 | "output_type": "stream", 693 | "text": [ 694 | "R\n", 695 | "Re\n", 696 | "Reu\n", 697 | "Reuv\n", 698 | "Reuve\n", 699 | "Reuven\n" 700 | ] 701 | } 702 | ], 703 | "source": [ 704 | "#JD \n", 705 | "\n", 706 | "name = input(\"Enter your Name : \").strip()\n", 707 | "\n", 708 | "for i in range(len(name)):\n", 709 | " print(name[:i+1])" 710 | ] 711 | }, 712 | { 713 | "cell_type": "code", 714 | "execution_count": 28, 715 | "metadata": {}, 716 | "outputs": [ 717 | { 718 | "name": "stdin", 719 | "output_type": "stream", 720 | "text": [ 721 | "Enter your name: Reuven\n" 722 | ] 723 | }, 724 | { 725 | "name": "stdout", 726 | "output_type": "stream", 727 | "text": [ 728 | "R\n", 729 | "Re\n", 730 | "Reu\n", 731 | "Reuv\n", 732 | "Reuve\n", 733 | "Reuven\n" 734 | ] 735 | } 736 | ], 737 | "source": [ 738 | "# SK\n", 739 | "\n", 740 | "name = input(\"Enter your name: \")\n", 741 | "\n", 742 | "l = len(name)\n", 743 | "\n", 744 | "for t in range(l):\n", 745 | " print(f'{name[:t+1]}')" 746 | ] 747 | }, 748 | { 749 | "cell_type": "code", 750 | "execution_count": 33, 751 | "metadata": {}, 752 | "outputs": [ 753 | { 754 | "name": "stdin", 755 | "output_type": "stream", 756 | "text": [ 757 | "Enter your text here : Reuven\n" 758 | ] 759 | }, 760 | { 761 | "name": "stdout", 762 | "output_type": "stream", 763 | "text": [ 764 | "R\n", 765 | "Re\n", 766 | "Reu\n", 767 | "Reuv\n", 768 | "Reuve\n", 769 | "Reuven\n" 770 | ] 771 | } 772 | ], 773 | "source": [ 774 | "# IG\n", 775 | "\n", 776 | "s=input('Enter your text here : ')\n", 777 | "v_g=0\n", 778 | "\n", 779 | "for n in range(len(s)):\n", 780 | " v_g += 1\n", 781 | " print(s[:v_g]) " 782 | ] 783 | }, 784 | { 785 | "cell_type": "code", 786 | "execution_count": 32, 787 | "metadata": {}, 788 | "outputs": [], 789 | "source": [ 790 | "#there is a __len__ (\"dunder len\") method on strings, and it is connected to the len()\n", 791 | "# function. But any \"dunder\" method should *not* be invoked by us directly.\n", 792 | "\n" 793 | ] 794 | }, 795 | { 796 | "cell_type": "markdown", 797 | "metadata": {}, 798 | "source": [ 799 | "# What is `__len__`?\n", 800 | "\n", 801 | "When we invoke `len(x)`, Python looks to see if there is a method `x.__len__`, and invokes it on our behalf. This is typical with many operators in Python; when we invoke `a + b`, Python invokes behind the scenes `a.__add__(b)`. There are lots of \"magic methods\" in Python that do this.\n", 802 | "\n", 803 | "In theory, you could run `__len__` on any object, and get its length. But that's frowned upon. You should really never be invoked magic methods unless you really know what you're doing -- and even then, it's a bad idea." 804 | ] 805 | }, 806 | { 807 | "cell_type": "code", 808 | "execution_count": null, 809 | "metadata": {}, 810 | "outputs": [], 811 | "source": [] 812 | }, 813 | { 814 | "cell_type": "code", 815 | "execution_count": null, 816 | "metadata": {}, 817 | "outputs": [], 818 | "source": [] 819 | }, 820 | { 821 | "cell_type": "code", 822 | "execution_count": null, 823 | "metadata": {}, 824 | "outputs": [], 825 | "source": [] 826 | }, 827 | { 828 | "cell_type": "markdown", 829 | "metadata": {}, 830 | "source": [ 831 | "# Next up:\n", 832 | "\n", 833 | "1. Indexes\n", 834 | "2. `while` loops\n" 835 | ] 836 | }, 837 | { 838 | "cell_type": "markdown", 839 | "metadata": {}, 840 | "source": [ 841 | "In many other programming languages, the `for` loop has to keep track of an index. It starts that index at 0, and stops when it reaches a certain size/value, and does something in the loop body. The point of the index is to retrieve the right value from the string in each iteration.\n", 842 | "\n", 843 | "In Python, things work completely differently -- the object is in charge of its own index, and returns the next value with each time. \n", 844 | "\n", 845 | "Moreover, in other languages, we have an index because we need it to retrieve the value.\n", 846 | "\n", 847 | "In Python, we don't -- we just get the values directly! But there are times when we might want to print the index or use it for a calculation.\n", 848 | "\n" 849 | ] 850 | }, 851 | { 852 | "cell_type": "code", 853 | "execution_count": 38, 854 | "metadata": {}, 855 | "outputs": [ 856 | { 857 | "name": "stdout", 858 | "output_type": "stream", 859 | "text": [ 860 | "0: a\n", 861 | "1: b\n", 862 | "2: c\n", 863 | "3: d\n", 864 | "4: e\n" 865 | ] 866 | } 867 | ], 868 | "source": [ 869 | "# option 1: Do it ourselves\n", 870 | "\n", 871 | "index = 0 \n", 872 | "s = 'abcde'\n", 873 | "\n", 874 | "for one_character in s:\n", 875 | " print(f'{index}: {one_character}')\n", 876 | " index += 1" 877 | ] 878 | }, 879 | { 880 | "cell_type": "code", 881 | "execution_count": 40, 882 | "metadata": {}, 883 | "outputs": [ 884 | { 885 | "name": "stdout", 886 | "output_type": "stream", 887 | "text": [ 888 | "0: a\n", 889 | "1: b\n", 890 | "2: c\n", 891 | "3: d\n" 892 | ] 893 | } 894 | ], 895 | "source": [ 896 | "# option 2: use \"enumerate\"\n", 897 | "# this builtin function is surprisingly unknown: It takes an iterable value\n", 898 | "# as an argument. Enumerate is designed to be used inside of loops.\n", 899 | "\n", 900 | "for index, one_item in enumerate('abcd'):\n", 901 | " print(f\"{index}: {one_item}\")" 902 | ] 903 | }, 904 | { 905 | "cell_type": "markdown", 906 | "metadata": {}, 907 | "source": [ 908 | "# Exercise: Multiples of n indexes\n", 909 | "\n", 910 | "1. Ask the user to enter some text, and assign to `text`\n", 911 | "2. Ask the user to enter an integer, and assign to `n`.\n", 912 | "3. Go through the string, and print each of the characters whose index is a multple `n`. So if `n` is 2, you would print the charactres at even indexes.\n", 913 | "\n", 914 | "Example:\n", 915 | "\n", 916 | " Enter some text: encyclopedia\n", 917 | " Enter a number: 3 # meaning: show characters at indexes that are multiples of 3\n", 918 | " y o d\n" 919 | ] 920 | }, 921 | { 922 | "cell_type": "code", 923 | "execution_count": 43, 924 | "metadata": {}, 925 | "outputs": [ 926 | { 927 | "name": "stdin", 928 | "output_type": "stream", 929 | "text": [ 930 | "Enter text: encyclopedia\n", 931 | "Enter a number: 3\n" 932 | ] 933 | }, 934 | { 935 | "name": "stdout", 936 | "output_type": "stream", 937 | "text": [ 938 | "0: e\n", 939 | "3: y\n", 940 | "6: o\n", 941 | "9: d\n" 942 | ] 943 | } 944 | ], 945 | "source": [ 946 | "text = input('Enter text: ').strip()\n", 947 | "n_string = input('Enter a number: ').strip()\n", 948 | "\n", 949 | "if n_string.isdigit():\n", 950 | " n = int(n_string)\n", 951 | "\n", 952 | " for index, one_character in enumerate(text):\n", 953 | " if (index % n) == 0:\n", 954 | " print(f'{index}: {one_character}')\n", 955 | " " 956 | ] 957 | }, 958 | { 959 | "cell_type": "code", 960 | "execution_count": null, 961 | "metadata": {}, 962 | "outputs": [], 963 | "source": [ 964 | "text = input('Enter text = ')\n", 965 | "n = int(input('Enter Integer = '))\n", 966 | "\n", 967 | "for index, each_character in enumerate(text):\n", 968 | " if(index%n == 0):\n", 969 | " print(f'{text[index]} {index}')" 970 | ] 971 | }, 972 | { 973 | "cell_type": "markdown", 974 | "metadata": {}, 975 | "source": [ 976 | "`while` loops\n", 977 | "\n", 978 | "A `while` loop is just like a `for` statement:\n", 979 | "\n", 980 | "- `while` looks to its right for a `True` value.\n", 981 | " - If it sees `False`, then the loop stops.\n", 982 | " - If it sees `True`, then it executes the loop body again.\n", 983 | " \n", 984 | "If we don't know how many iterations we need, but we do know when we can stop looping." 985 | ] 986 | }, 987 | { 988 | "cell_type": "code", 989 | "execution_count": 45, 990 | "metadata": {}, 991 | "outputs": [ 992 | { 993 | "name": "stdin", 994 | "output_type": "stream", 995 | "text": [ 996 | "Enter text = testing 123\n", 997 | "Enter Integer = 3\n" 998 | ] 999 | }, 1000 | { 1001 | "name": "stdout", 1002 | "output_type": "stream", 1003 | "text": [ 1004 | "t 0\n", 1005 | "t 3\n", 1006 | "g 6\n", 1007 | "2 9\n" 1008 | ] 1009 | } 1010 | ], 1011 | "source": [ 1012 | "# SY\n", 1013 | "\n", 1014 | "text = input('Enter text = ')\n", 1015 | "n = int(input('Enter Integer = '))\n", 1016 | "for index, each_character in enumerate(text):\n", 1017 | " if(index%n == 0):\n", 1018 | " print(f'{text[index]} {index}')" 1019 | ] 1020 | }, 1021 | { 1022 | "cell_type": "code", 1023 | "execution_count": null, 1024 | "metadata": {}, 1025 | "outputs": [], 1026 | "source": [] 1027 | }, 1028 | { 1029 | "cell_type": "code", 1030 | "execution_count": 44, 1031 | "metadata": {}, 1032 | "outputs": [ 1033 | { 1034 | "name": "stdout", 1035 | "output_type": "stream", 1036 | "text": [ 1037 | "5\n", 1038 | "4\n", 1039 | "3\n", 1040 | "2\n", 1041 | "1\n" 1042 | ] 1043 | } 1044 | ], 1045 | "source": [ 1046 | "x = 5\n", 1047 | "\n", 1048 | "while x > 0:\n", 1049 | " print(x)\n", 1050 | " x -= 1 # x = x -1" 1051 | ] 1052 | }, 1053 | { 1054 | "cell_type": "markdown", 1055 | "metadata": {}, 1056 | "source": [ 1057 | "# What's the difference?\n", 1058 | "\n", 1059 | "In a `for` loop, you go over every element once, and it has a chance to do something. But if you want to do something to each element of your sequence, use a `for` loop.\n", 1060 | "\n", 1061 | "In a `while` loop, you run the body until the test is `False`." 1062 | ] 1063 | }, 1064 | { 1065 | "cell_type": "markdown", 1066 | "metadata": {}, 1067 | "source": [ 1068 | "# Exercise: Sum to 100\n", 1069 | "\n", 1070 | "1. Set `total` to be 0.\n", 1071 | "2. Repeatedly ask the user to enter a number.\n", 1072 | "3. If the user's numbers get them over 100, then stop and print the total.\n", 1073 | "\n", 1074 | "Example: Sum to 100\n", 1075 | "\n", 1076 | " Enter a number: 30\n", 1077 | " Enter a number: 10\n", 1078 | " Enter a nubmer: 50\n", 1079 | " Enter a number: 15\n", 1080 | " Total is 105\n", 1081 | " " 1082 | ] 1083 | }, 1084 | { 1085 | "cell_type": "code", 1086 | "execution_count": 48, 1087 | "metadata": {}, 1088 | "outputs": [ 1089 | { 1090 | "name": "stdin", 1091 | "output_type": "stream", 1092 | "text": [ 1093 | "Enter a number: 1\n", 1094 | "Enter a number: 1\n", 1095 | "Enter a number: 1\n", 1096 | "Enter a number: 1\n", 1097 | "Enter a number: 1\n", 1098 | "Enter a number: 1\n", 1099 | "Enter a number: 1\n", 1100 | "Enter a number: 1\n", 1101 | "Enter a number: 1\n", 1102 | "Enter a number: 1\n", 1103 | "Enter a number: 1\n", 1104 | "Enter a number: 1\n", 1105 | "Enter a number: 1\n", 1106 | "Enter a number: 1\n", 1107 | "Enter a number: 2\n", 1108 | "Enter a number: 2\n", 1109 | "Enter a number: 2\n", 1110 | "Enter a number: 2\n", 1111 | "Enter a number: 2\n", 1112 | "Enter a number: 3\n", 1113 | "Enter a number: 3\n", 1114 | "Enter a number: 3\n", 1115 | "Enter a number: 45\n", 1116 | "Enter a number: 90\n" 1117 | ] 1118 | }, 1119 | { 1120 | "name": "stdout", 1121 | "output_type": "stream", 1122 | "text": [ 1123 | "168\n" 1124 | ] 1125 | } 1126 | ], 1127 | "source": [ 1128 | "total = 0\n", 1129 | "\n", 1130 | "while total < 100:\n", 1131 | " s = input('Enter a number: ').strip()\n", 1132 | "\n", 1133 | " if s.isdigit():\n", 1134 | " total += int(s)\n", 1135 | " else:\n", 1136 | " print('Ignoring non-intener {s}')\n", 1137 | "\n", 1138 | "print(total)" 1139 | ] 1140 | }, 1141 | { 1142 | "cell_type": "code", 1143 | "execution_count": 47, 1144 | "metadata": {}, 1145 | "outputs": [ 1146 | { 1147 | "name": "stdin", 1148 | "output_type": "stream", 1149 | "text": [ 1150 | "Enter a number: 10\n", 1151 | "Enter a number: 30\n", 1152 | "Enter a number: 50\n", 1153 | "Enter a number: 70\n" 1154 | ] 1155 | }, 1156 | { 1157 | "name": "stdout", 1158 | "output_type": "stream", 1159 | "text": [ 1160 | "Total: 160\n" 1161 | ] 1162 | } 1163 | ], 1164 | "source": [ 1165 | "# SK \n", 1166 | "total = 0\n", 1167 | "\n", 1168 | "while total < 100:\n", 1169 | " a = input(\"Enter a number: \")\n", 1170 | " a = int(a)\n", 1171 | " total = total + a\n", 1172 | "print(f'Total: {total}')\n" 1173 | ] 1174 | }, 1175 | { 1176 | "cell_type": "code", 1177 | "execution_count": null, 1178 | "metadata": {}, 1179 | "outputs": [], 1180 | "source": [ 1181 | "# MM\n", 1182 | "\n", 1183 | "total = 0\n", 1184 | "is_not_max = True\n", 1185 | "while is_not_max:\n", 1186 | " user = int(input(\"Type a number to add: \"))\n", 1187 | " if user > 0:\n", 1188 | " print(f\"{user} + {total}\")\n", 1189 | " total += user\n", 1190 | " if total >= 100:\n", 1191 | " print(f\"You've reached {total}\")\n", 1192 | " is_not_max = False" 1193 | ] 1194 | }, 1195 | { 1196 | "cell_type": "code", 1197 | "execution_count": 50, 1198 | "metadata": {}, 1199 | "outputs": [ 1200 | { 1201 | "data": { 1202 | "text/plain": [ 1203 | "12345" 1204 | ] 1205 | }, 1206 | "execution_count": 50, 1207 | "metadata": {}, 1208 | "output_type": "execute_result" 1209 | } 1210 | ], 1211 | "source": [ 1212 | "# if you're going to use int(), then you don't need strip...\n", 1213 | "\n", 1214 | "s = ' 12345 '\n", 1215 | "int(s) # int automatically removes whitespace from the front/back of the string" 1216 | ] 1217 | }, 1218 | { 1219 | "cell_type": "code", 1220 | "execution_count": 52, 1221 | "metadata": {}, 1222 | "outputs": [ 1223 | { 1224 | "data": { 1225 | "text/plain": [ 1226 | "False" 1227 | ] 1228 | }, 1229 | "execution_count": 52, 1230 | "metadata": {}, 1231 | "output_type": "execute_result" 1232 | } 1233 | ], 1234 | "source": [ 1235 | "s.isdigit() # because it contains spaces" 1236 | ] 1237 | }, 1238 | { 1239 | "cell_type": "markdown", 1240 | "metadata": {}, 1241 | "source": [ 1242 | "# Next up\n", 1243 | "\n", 1244 | "1. A bit more on looping, with `continue` and `break`\n", 1245 | "2. Mainly, working on lists" 1246 | ] 1247 | }, 1248 | { 1249 | "cell_type": "markdown", 1250 | "metadata": {}, 1251 | "source": [ 1252 | "# How can we control our loop?\n", 1253 | "\n", 1254 | "So far, we've seen that we can run `for` and `while` loops. A `for` loop ends when we get through all of the elements of the iterable. A `while` loop ends when the condition is `False`, when checked at the top of the loop.\n", 1255 | "\n", 1256 | "But what if we want to exit the loop early? What if we've encountered an error, and need to break out of it? What if the current element isn't really appropriate, and we want to go onto the next one?\n", 1257 | "\n", 1258 | "We have two keywords we can use in our loops to do this:\n", 1259 | "\n", 1260 | "- `break`, which stops the loop *right now*, and continues to the code following the loop\n", 1261 | "- `continue`, which stops the current iteration right now, but goes onto the next one. We don't break out of the loop, but we do immediate go to the next value in the loop.\n", 1262 | "\n", 1263 | "Where do I use these? Typically, I'll use them at the *top* of a loop:\n", 1264 | "- I'll use `break` to determine if I should stop the loop right away, if we've achieved our goals\n", 1265 | "- I'll use `continue` to determine if the loop variable's value is inappropriate for our iteration, and we should get a next one." 1266 | ] 1267 | }, 1268 | { 1269 | "cell_type": "code", 1270 | "execution_count": 54, 1271 | "metadata": {}, 1272 | "outputs": [ 1273 | { 1274 | "name": "stdout", 1275 | "output_type": "stream", 1276 | "text": [ 1277 | "this\n", 1278 | "is\n", 1279 | "a\n", 1280 | "bunch\n", 1281 | "of\n", 1282 | "words\n", 1283 | "Sum of word lengths: 19\n" 1284 | ] 1285 | } 1286 | ], 1287 | "source": [ 1288 | "words = 'this is a bunch of words'.split()\n", 1289 | "\n", 1290 | "total = 0\n", 1291 | "for one_word in words:\n", 1292 | " print(one_word)\n", 1293 | " total += len(one_word)\n", 1294 | "\n", 1295 | "print(f'Sum of word lengths: {total}')" 1296 | ] 1297 | }, 1298 | { 1299 | "cell_type": "code", 1300 | "execution_count": 57, 1301 | "metadata": {}, 1302 | "outputs": [ 1303 | { 1304 | "name": "stdout", 1305 | "output_type": "stream", 1306 | "text": [ 1307 | "this\n", 1308 | "bunch\n", 1309 | "words\n", 1310 | "Sum of word lengths: 14\n" 1311 | ] 1312 | } 1313 | ], 1314 | "source": [ 1315 | "# what if I don't want to include words that are shorter than 3 characters?\n", 1316 | "\n", 1317 | "words = ['this', 'is', 'a', 'bunch', 'of', 'words']\n", 1318 | "\n", 1319 | "total = 0\n", 1320 | "for one_word in words:\n", 1321 | " if len(one_word) < 3:\n", 1322 | " continue\n", 1323 | " \n", 1324 | " print(one_word)\n", 1325 | " total += len(one_word)\n", 1326 | "\n", 1327 | "print(f'Sum of word lengths: {total}')" 1328 | ] 1329 | }, 1330 | { 1331 | "cell_type": "code", 1332 | "execution_count": 58, 1333 | "metadata": {}, 1334 | "outputs": [ 1335 | { 1336 | "name": "stdin", 1337 | "output_type": "stream", 1338 | "text": [ 1339 | "Enter text: \n" 1340 | ] 1341 | } 1342 | ], 1343 | "source": [ 1344 | "# here's one of my favorite ways to use \"break\"\n", 1345 | "\n", 1346 | "while True: # yes, this is an infinite loop! \n", 1347 | " s = input('Enter text: ').strip()\n", 1348 | "\n", 1349 | " if s == '': # empty string?\n", 1350 | " break # break!\n", 1351 | "\n", 1352 | " print(f'Hello, {s}!')" 1353 | ] 1354 | }, 1355 | { 1356 | "cell_type": "markdown", 1357 | "metadata": {}, 1358 | "source": [ 1359 | "# Lists\n", 1360 | "\n", 1361 | "So far, we've seen a few data structures:\n", 1362 | "\n", 1363 | "- Numbers (ints and floats)\n", 1364 | "- Strings\n", 1365 | "\n", 1366 | "Lists are container objects; they contain other objects. Indeed, a list can contain *any* number of *any* objects we want. Traditionally, a list contains only elements of one type, but that's a convention, not enforced anywhere.\n", 1367 | "\n", 1368 | "Lists look/feel a lot like arrays in other languages. But we call them \"lists,\" and we're technically correct." 1369 | ] 1370 | }, 1371 | { 1372 | "cell_type": "code", 1373 | "execution_count": 59, 1374 | "metadata": {}, 1375 | "outputs": [], 1376 | "source": [ 1377 | "# define a list with []\n", 1378 | "# elements are separated by ,\n", 1379 | "\n", 1380 | "mylist = [10, 20, 30, 40, 50]\n" 1381 | ] 1382 | }, 1383 | { 1384 | "cell_type": "code", 1385 | "execution_count": 60, 1386 | "metadata": {}, 1387 | "outputs": [ 1388 | { 1389 | "data": { 1390 | "text/plain": [ 1391 | "list" 1392 | ] 1393 | }, 1394 | "execution_count": 60, 1395 | "metadata": {}, 1396 | "output_type": "execute_result" 1397 | } 1398 | ], 1399 | "source": [ 1400 | "type(mylist) # what kind of value is this?" 1401 | ] 1402 | }, 1403 | { 1404 | "cell_type": "code", 1405 | "execution_count": 61, 1406 | "metadata": {}, 1407 | "outputs": [ 1408 | { 1409 | "data": { 1410 | "text/plain": [ 1411 | "5" 1412 | ] 1413 | }, 1414 | "execution_count": 61, 1415 | "metadata": {}, 1416 | "output_type": "execute_result" 1417 | } 1418 | ], 1419 | "source": [ 1420 | "len(mylist) # how many elements?" 1421 | ] 1422 | }, 1423 | { 1424 | "cell_type": "code", 1425 | "execution_count": 62, 1426 | "metadata": {}, 1427 | "outputs": [ 1428 | { 1429 | "data": { 1430 | "text/plain": [ 1431 | "10" 1432 | ] 1433 | }, 1434 | "execution_count": 62, 1435 | "metadata": {}, 1436 | "output_type": "execute_result" 1437 | } 1438 | ], 1439 | "source": [ 1440 | "mylist[0] # first element" 1441 | ] 1442 | }, 1443 | { 1444 | "cell_type": "code", 1445 | "execution_count": 63, 1446 | "metadata": {}, 1447 | "outputs": [ 1448 | { 1449 | "data": { 1450 | "text/plain": [ 1451 | "20" 1452 | ] 1453 | }, 1454 | "execution_count": 63, 1455 | "metadata": {}, 1456 | "output_type": "execute_result" 1457 | } 1458 | ], 1459 | "source": [ 1460 | "mylist[1] # scond element" 1461 | ] 1462 | }, 1463 | { 1464 | "cell_type": "code", 1465 | "execution_count": 64, 1466 | "metadata": {}, 1467 | "outputs": [ 1468 | { 1469 | "data": { 1470 | "text/plain": [ 1471 | "50" 1472 | ] 1473 | }, 1474 | "execution_count": 64, 1475 | "metadata": {}, 1476 | "output_type": "execute_result" 1477 | } 1478 | ], 1479 | "source": [ 1480 | "mylist[-1] # final element\n" 1481 | ] 1482 | }, 1483 | { 1484 | "cell_type": "code", 1485 | "execution_count": 65, 1486 | "metadata": {}, 1487 | "outputs": [ 1488 | { 1489 | "data": { 1490 | "text/plain": [ 1491 | "40" 1492 | ] 1493 | }, 1494 | "execution_count": 65, 1495 | "metadata": {}, 1496 | "output_type": "execute_result" 1497 | } 1498 | ], 1499 | "source": [ 1500 | "i = 3\n", 1501 | "mylist[i]" 1502 | ] 1503 | }, 1504 | { 1505 | "cell_type": "code", 1506 | "execution_count": 66, 1507 | "metadata": {}, 1508 | "outputs": [ 1509 | { 1510 | "data": { 1511 | "text/plain": [ 1512 | "[20, 30, 40]" 1513 | ] 1514 | }, 1515 | "execution_count": 66, 1516 | "metadata": {}, 1517 | "output_type": "execute_result" 1518 | } 1519 | ], 1520 | "source": [ 1521 | "# slice\n", 1522 | "mylist[1:4]" 1523 | ] 1524 | }, 1525 | { 1526 | "cell_type": "code", 1527 | "execution_count": 67, 1528 | "metadata": {}, 1529 | "outputs": [], 1530 | "source": [ 1531 | "# Lists and strings are both *sequences*, with a common set of methods and operations" 1532 | ] 1533 | }, 1534 | { 1535 | "cell_type": "code", 1536 | "execution_count": 68, 1537 | "metadata": {}, 1538 | "outputs": [ 1539 | { 1540 | "name": "stdout", 1541 | "output_type": "stream", 1542 | "text": [ 1543 | "10\n", 1544 | "20\n", 1545 | "30\n", 1546 | "40\n", 1547 | "50\n" 1548 | ] 1549 | } 1550 | ], 1551 | "source": [ 1552 | "# We can iterate over a list\n", 1553 | "\n", 1554 | "for one_item in mylist:\n", 1555 | " print(one_item)" 1556 | ] 1557 | }, 1558 | { 1559 | "cell_type": "code", 1560 | "execution_count": 69, 1561 | "metadata": {}, 1562 | "outputs": [ 1563 | { 1564 | "data": { 1565 | "text/plain": [ 1566 | "True" 1567 | ] 1568 | }, 1569 | "execution_count": 69, 1570 | "metadata": {}, 1571 | "output_type": "execute_result" 1572 | } 1573 | ], 1574 | "source": [ 1575 | "# search in a list with \"in\"\n", 1576 | "\n", 1577 | "40 in mylist" 1578 | ] 1579 | }, 1580 | { 1581 | "cell_type": "code", 1582 | "execution_count": 70, 1583 | "metadata": {}, 1584 | "outputs": [ 1585 | { 1586 | "data": { 1587 | "text/plain": [ 1588 | "False" 1589 | ] 1590 | }, 1591 | "execution_count": 70, 1592 | "metadata": {}, 1593 | "output_type": "execute_result" 1594 | } 1595 | ], 1596 | "source": [ 1597 | "100 in mylist" 1598 | ] 1599 | }, 1600 | { 1601 | "cell_type": "code", 1602 | "execution_count": 73, 1603 | "metadata": {}, 1604 | "outputs": [], 1605 | "source": [ 1606 | "# lists are also *not* the same as strings\n", 1607 | "# first, they can contain other objects (ints, floats, strings, other lists, dicts, etc.)\n", 1608 | "# also: They are *mutable*, meaning that we can modify them\n", 1609 | "\n", 1610 | "mylist[0] = '!' # if the index already exists, you can assign to it" 1611 | ] 1612 | }, 1613 | { 1614 | "cell_type": "code", 1615 | "execution_count": 74, 1616 | "metadata": {}, 1617 | "outputs": [ 1618 | { 1619 | "data": { 1620 | "text/plain": [ 1621 | "['!', 20, 30, 40, 50]" 1622 | ] 1623 | }, 1624 | "execution_count": 74, 1625 | "metadata": {}, 1626 | "output_type": "execute_result" 1627 | } 1628 | ], 1629 | "source": [ 1630 | "mylist" 1631 | ] 1632 | }, 1633 | { 1634 | "cell_type": "markdown", 1635 | "metadata": {}, 1636 | "source": [ 1637 | "# Lists are mutable!\n", 1638 | "\n", 1639 | "We can modify the contents of a list. This is new! We don't have any other data, so far, that we can modify in this way.\n", 1640 | "\n", 1641 | "If two variables are referring to the same list, and one modifies the list, then other will also be modified. In other words, there's no rule in Python against having multiple variables refer to the same object. If the object changes, then all variables will see that change." 1642 | ] 1643 | }, 1644 | { 1645 | "cell_type": "code", 1646 | "execution_count": 75, 1647 | "metadata": {}, 1648 | "outputs": [ 1649 | { 1650 | "data": { 1651 | "text/plain": [ 1652 | "[10, 20, 30, 40, 50, 100, [200, 300]]" 1653 | ] 1654 | }, 1655 | "execution_count": 75, 1656 | "metadata": {}, 1657 | "output_type": "execute_result" 1658 | } 1659 | ], 1660 | "source": [ 1661 | "# How do I add to the end of a list?\n", 1662 | "# we use the \"append\" method, which adds one item to the end\n", 1663 | "\n", 1664 | "mylist = [10, 20, 30, 40, 50]\n", 1665 | "mylist.append(100)\n", 1666 | "mylist.append([200, 300])\n", 1667 | "mylist" 1668 | ] 1669 | }, 1670 | { 1671 | "cell_type": "markdown", 1672 | "metadata": {}, 1673 | "source": [ 1674 | "# Where do we use lists?\n", 1675 | "\n", 1676 | "- Lists of users\n", 1677 | "- Lists of servers\n", 1678 | "- Lists of things in the refrigerator\n", 1679 | "- Lists of books I'm supposed to read" 1680 | ] 1681 | }, 1682 | { 1683 | "cell_type": "code", 1684 | "execution_count": 76, 1685 | "metadata": {}, 1686 | "outputs": [], 1687 | "source": [ 1688 | "# to remove an item, you can use \"list.pop\", a method that removes (by default) from the\n", 1689 | "# end of the list. It removes and returns it\n" 1690 | ] 1691 | }, 1692 | { 1693 | "cell_type": "code", 1694 | "execution_count": 77, 1695 | "metadata": {}, 1696 | "outputs": [ 1697 | { 1698 | "data": { 1699 | "text/plain": [ 1700 | "[200, 300]" 1701 | ] 1702 | }, 1703 | "execution_count": 77, 1704 | "metadata": {}, 1705 | "output_type": "execute_result" 1706 | } 1707 | ], 1708 | "source": [ 1709 | "mylist.pop()" 1710 | ] 1711 | }, 1712 | { 1713 | "cell_type": "code", 1714 | "execution_count": 79, 1715 | "metadata": {}, 1716 | "outputs": [ 1717 | { 1718 | "data": { 1719 | "text/plain": [ 1720 | "100" 1721 | ] 1722 | }, 1723 | "execution_count": 79, 1724 | "metadata": {}, 1725 | "output_type": "execute_result" 1726 | } 1727 | ], 1728 | "source": [ 1729 | "mylist.pop()" 1730 | ] 1731 | }, 1732 | { 1733 | "cell_type": "code", 1734 | "execution_count": 80, 1735 | "metadata": {}, 1736 | "outputs": [ 1737 | { 1738 | "data": { 1739 | "text/plain": [ 1740 | "4" 1741 | ] 1742 | }, 1743 | "execution_count": 80, 1744 | "metadata": {}, 1745 | "output_type": "execute_result" 1746 | } 1747 | ], 1748 | "source": [ 1749 | "mylist = [10, 20, [30, 40, 50], 60]\n", 1750 | "len(mylist)" 1751 | ] 1752 | }, 1753 | { 1754 | "cell_type": "code", 1755 | "execution_count": 81, 1756 | "metadata": {}, 1757 | "outputs": [ 1758 | { 1759 | "data": { 1760 | "text/plain": [ 1761 | "[30, 40, 50]" 1762 | ] 1763 | }, 1764 | "execution_count": 81, 1765 | "metadata": {}, 1766 | "output_type": "execute_result" 1767 | } 1768 | ], 1769 | "source": [ 1770 | "mylist[2] # get the sublist" 1771 | ] 1772 | }, 1773 | { 1774 | "cell_type": "code", 1775 | "execution_count": 82, 1776 | "metadata": { 1777 | "scrolled": true 1778 | }, 1779 | "outputs": [ 1780 | { 1781 | "data": { 1782 | "text/plain": [ 1783 | "30" 1784 | ] 1785 | }, 1786 | "execution_count": 82, 1787 | "metadata": {}, 1788 | "output_type": "execute_result" 1789 | } 1790 | ], 1791 | "source": [ 1792 | "mylist[2][0] # put multple sets of [] next to one another" 1793 | ] 1794 | }, 1795 | { 1796 | "cell_type": "markdown", 1797 | "metadata": {}, 1798 | "source": [ 1799 | "# Exercise: Odds and evens\n", 1800 | "\n", 1801 | "1. Create two lists, `odds` and `evens`.\n", 1802 | "2. Repeatedly ask the user to enter a number.\n", 1803 | " - If they enter an empty string, stop asking and print\n", 1804 | "3. If the value is non-numeric, scold the user and let them try again.\n", 1805 | "4. If the value is numeric, then make it an integer and add it to either `odds` or `evens`, as appropriate\n", 1806 | " - Remember that you can find out if it's odd if you check the remainder of dividing by 2 -- if it's 1, then the number is odd\n", 1807 | "5. Print both `odds` and `evens`.\n", 1808 | "\n", 1809 | "Example:\n", 1810 | "\n", 1811 | " Enter a number: 10\n", 1812 | " Enter a number: 15\n", 1813 | " Enter a number: hello\n", 1814 | " hello is not numeric; try again\n", 1815 | " Enter a number: 12\n", 1816 | " Enter a number: 17\n", 1817 | " Enter a number: [ENTER]\n", 1818 | " \n", 1819 | " odds: [15, 17]\n", 1820 | " evens: 10, 12]" 1821 | ] 1822 | }, 1823 | { 1824 | "cell_type": "code", 1825 | "execution_count": 83, 1826 | "metadata": {}, 1827 | "outputs": [ 1828 | { 1829 | "name": "stdin", 1830 | "output_type": "stream", 1831 | "text": [ 1832 | "Enter a number: 10\n", 1833 | "Enter a number: 11\n", 1834 | "Enter a number: 15\n", 1835 | "Enter a number: 19\n", 1836 | "Enter a number: 22\n", 1837 | "Enter a number: 28\n", 1838 | "Enter a number: 76\n", 1839 | "Enter a number: \n" 1840 | ] 1841 | }, 1842 | { 1843 | "name": "stdout", 1844 | "output_type": "stream", 1845 | "text": [ 1846 | "odds = [11, 15, 19]\n", 1847 | "evens = [10, 22, 28, 76]\n" 1848 | ] 1849 | } 1850 | ], 1851 | "source": [ 1852 | "odds = []\n", 1853 | "evens = []\n", 1854 | "\n", 1855 | "while True: \n", 1856 | " s = input('Enter a number: ').strip()\n", 1857 | "\n", 1858 | " # is this an empty string? \n", 1859 | " if s == '':\n", 1860 | " break # exit the loop if we got the empty string\n", 1861 | "\n", 1862 | " # is the string numeric?\n", 1863 | " if not s.isdigit():\n", 1864 | " print(f'{s} is not numeric; try again')\n", 1865 | "\n", 1866 | " n = int(s)\n", 1867 | "\n", 1868 | " if n%2 == 0: # even, because it divides evenly by 2\n", 1869 | " evens.append(n)\n", 1870 | " else:\n", 1871 | " odds.append(n)\n", 1872 | "\n", 1873 | "print(f'odds = {odds}')\n", 1874 | "print(f'evens = {evens}')" 1875 | ] 1876 | }, 1877 | { 1878 | "cell_type": "code", 1879 | "execution_count": 84, 1880 | "metadata": {}, 1881 | "outputs": [ 1882 | { 1883 | "name": "stdin", 1884 | "output_type": "stream", 1885 | "text": [ 1886 | "Enter a number: 10\n", 1887 | "Enter a number: 11\n", 1888 | "Enter a number: 15\n", 1889 | "Enter a number: 16\n", 1890 | "Enter a number: \n" 1891 | ] 1892 | }, 1893 | { 1894 | "name": "stdout", 1895 | "output_type": "stream", 1896 | "text": [ 1897 | "YOu entered an empty string\n", 1898 | "['10', '16']\n", 1899 | "['11', '15']\n" 1900 | ] 1901 | } 1902 | ], 1903 | "source": [ 1904 | "# AM\n", 1905 | "\n", 1906 | "\n", 1907 | "odds=[]\n", 1908 | "evens=[]\n", 1909 | "\n", 1910 | "while True:\n", 1911 | " number=input('Enter a number: ')\n", 1912 | " if number == \"\":\n", 1913 | " print(f'YOu entered an empty string')\n", 1914 | " break\n", 1915 | " elif not number.isdigit():\n", 1916 | " print(f'{number} is not numeric!')\n", 1917 | " else:\n", 1918 | " int_number = int(number)\n", 1919 | " if int_number%2 == 0:\n", 1920 | " evens.append(number)\n", 1921 | " else:\n", 1922 | " odds.append(number)\n", 1923 | "\n", 1924 | "print(evens)\n", 1925 | "print(odds)" 1926 | ] 1927 | }, 1928 | { 1929 | "cell_type": "code", 1930 | "execution_count": 85, 1931 | "metadata": {}, 1932 | "outputs": [ 1933 | { 1934 | "data": { 1935 | "text/plain": [ 1936 | "[10, 20, 30, 50, 100, 200]" 1937 | ] 1938 | }, 1939 | "execution_count": 85, 1940 | "metadata": {}, 1941 | "output_type": "execute_result" 1942 | } 1943 | ], 1944 | "source": [ 1945 | "# what if we want to add multiple things to our list?\n", 1946 | "# we can use the += operator on a list. It will run a for loop\n", 1947 | "# on whatever is to its right, adding each element it gets to the list\n", 1948 | "\n", 1949 | "mylist = [10, 20, 30]\n", 1950 | "\n", 1951 | "mylist += [50, 100, 200] # +=, so evey element on the right is appended to mylist\n", 1952 | "\n", 1953 | "mylist\n" 1954 | ] 1955 | }, 1956 | { 1957 | "cell_type": "code", 1958 | "execution_count": 86, 1959 | "metadata": {}, 1960 | "outputs": [ 1961 | { 1962 | "name": "stdin", 1963 | "output_type": "stream", 1964 | "text": [ 1965 | "Enter Number : 10\n" 1966 | ] 1967 | }, 1968 | { 1969 | "name": "stdout", 1970 | "output_type": "stream", 1971 | "text": [ 1972 | "Even\n" 1973 | ] 1974 | }, 1975 | { 1976 | "name": "stdin", 1977 | "output_type": "stream", 1978 | "text": [ 1979 | "Enter Number : 20\n" 1980 | ] 1981 | }, 1982 | { 1983 | "name": "stdout", 1984 | "output_type": "stream", 1985 | "text": [ 1986 | "Even\n" 1987 | ] 1988 | }, 1989 | { 1990 | "name": "stdin", 1991 | "output_type": "stream", 1992 | "text": [ 1993 | "Enter Number : hello\n" 1994 | ] 1995 | }, 1996 | { 1997 | "ename": "ValueError", 1998 | "evalue": "invalid literal for int() with base 10: 'hello'", 1999 | "output_type": "error", 2000 | "traceback": [ 2001 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2002 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 2003 | "Cell \u001b[0;32mIn[86], line 11\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m number \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[0;32m---> 11\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnumber\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m2\u001b[39m \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mEven\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 13\u001b[0m evens\u001b[38;5;241m.\u001b[39mappend(number)\n", 2004 | "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'hello'" 2005 | ] 2006 | } 2007 | ], 2008 | "source": [ 2009 | "# JD\n", 2010 | "\n", 2011 | "odds = []\n", 2012 | "evens = []\n", 2013 | "\n", 2014 | "while True:\n", 2015 | " number = input(\"Enter Number :\")\n", 2016 | " if number == \"\":\n", 2017 | " break\n", 2018 | " \n", 2019 | " if int(number) % 2 == 0:\n", 2020 | " print(\"Even\")\n", 2021 | " evens.append(number)\n", 2022 | " #print(evens)\n", 2023 | " elif int(number) % 2 == 1:\n", 2024 | " print(\"Odd\")\n", 2025 | " odds.append(number)\n", 2026 | " #print(odds)\n", 2027 | " else:\n", 2028 | " if number == \"\":\n", 2029 | " break\n", 2030 | "print(odds)\n", 2031 | "print(evens)" 2032 | ] 2033 | }, 2034 | { 2035 | "cell_type": "markdown", 2036 | "metadata": {}, 2037 | "source": [ 2038 | "# Splitting strings\n", 2039 | "\n", 2040 | "We know that to turn a string into an int, we run `int` on it, and get back a new integer we can use.\n", 2041 | "\n", 2042 | "We can do the opposite, too -- pass an integer into a string with `str`, and get back a string related.\n", 2043 | "\n", 2044 | "As a general rule, if you have data `d` and you want to get it out as type `t`, you just run `t(d)`.\n", 2045 | "\n", 2046 | "Can I get a list back from a string by running `list(s)`? Yes, this will work!" 2047 | ] 2048 | }, 2049 | { 2050 | "cell_type": "code", 2051 | "execution_count": 87, 2052 | "metadata": {}, 2053 | "outputs": [ 2054 | { 2055 | "data": { 2056 | "text/plain": [ 2057 | "['h', 'e', 'l', 'l', 'o', ' ', 'o', 'u', 't', ' ', 't', 'h', 'e', 'r', 'e']" 2058 | ] 2059 | }, 2060 | "execution_count": 87, 2061 | "metadata": {}, 2062 | "output_type": "execute_result" 2063 | } 2064 | ], 2065 | "source": [ 2066 | "s = 'hello out there'\n", 2067 | "list(s)" 2068 | ] 2069 | }, 2070 | { 2071 | "cell_type": "code", 2072 | "execution_count": 88, 2073 | "metadata": {}, 2074 | "outputs": [ 2075 | { 2076 | "data": { 2077 | "text/plain": [ 2078 | "'[10, 20, 30, 50, 100, 200]'" 2079 | ] 2080 | }, 2081 | "execution_count": 88, 2082 | "metadata": {}, 2083 | "output_type": "execute_result" 2084 | } 2085 | ], 2086 | "source": [ 2087 | "# what about str() on a list?\n", 2088 | "str(mylist)" 2089 | ] 2090 | }, 2091 | { 2092 | "cell_type": "markdown", 2093 | "metadata": {}, 2094 | "source": [ 2095 | "There are many situations in which we have a string that would clearly benefit from being a list, broken apart into its piece. (`str.split`)\n", 2096 | "\n", 2097 | "And similarly, there are many times when we want to take the elements of a list and weld them together. (`str.join`)" 2098 | ] 2099 | }, 2100 | { 2101 | "cell_type": "code", 2102 | "execution_count": 89, 2103 | "metadata": {}, 2104 | "outputs": [ 2105 | { 2106 | "data": { 2107 | "text/plain": [ 2108 | "['abc', 'de', 'fghi']" 2109 | ] 2110 | }, 2111 | "execution_count": 89, 2112 | "metadata": {}, 2113 | "output_type": "execute_result" 2114 | } 2115 | ], 2116 | "source": [ 2117 | "# if I have a string, and want a list of strings, I can use str.split\n", 2118 | "\n", 2119 | "s = 'abc;de;fghi'\n", 2120 | "\n", 2121 | "s.split(';') # this returns a list of strings, one element from between each `;`." 2122 | ] 2123 | }, 2124 | { 2125 | "cell_type": "code", 2126 | "execution_count": 90, 2127 | "metadata": {}, 2128 | "outputs": [ 2129 | { 2130 | "data": { 2131 | "text/plain": [ 2132 | "['This', 'is', 'a', 'bunch', 'of', 'words', 'for', 'my', 'course']" 2133 | ] 2134 | }, 2135 | "execution_count": 90, 2136 | "metadata": {}, 2137 | "output_type": "execute_result" 2138 | } 2139 | ], 2140 | "source": [ 2141 | "words = 'This is a bunch of words for my course'\n", 2142 | "words.split(' ')" 2143 | ] 2144 | }, 2145 | { 2146 | "cell_type": "code", 2147 | "execution_count": 91, 2148 | "metadata": {}, 2149 | "outputs": [ 2150 | { 2151 | "data": { 2152 | "text/plain": [ 2153 | "['This',\n", 2154 | " '',\n", 2155 | " 'is',\n", 2156 | " 'a',\n", 2157 | " '',\n", 2158 | " '',\n", 2159 | " 'bunch',\n", 2160 | " 'of',\n", 2161 | " '',\n", 2162 | " '',\n", 2163 | " '',\n", 2164 | " 'words',\n", 2165 | " 'for',\n", 2166 | " 'my',\n", 2167 | " 'course']" 2168 | ] 2169 | }, 2170 | "execution_count": 91, 2171 | "metadata": {}, 2172 | "output_type": "execute_result" 2173 | } 2174 | ], 2175 | "source": [ 2176 | "# but what about this:\n", 2177 | "\n", 2178 | "\n", 2179 | "words = 'This is a bunch of words for my course'\n", 2180 | "words.split(' ')" 2181 | ] 2182 | }, 2183 | { 2184 | "cell_type": "code", 2185 | "execution_count": 93, 2186 | "metadata": {}, 2187 | "outputs": [ 2188 | { 2189 | "data": { 2190 | "text/plain": [ 2191 | "['This', 'is', 'a', 'bunch', 'of', 'words', 'for', 'my', 'course']" 2192 | ] 2193 | }, 2194 | "execution_count": 93, 2195 | "metadata": {}, 2196 | "output_type": "execute_result" 2197 | } 2198 | ], 2199 | "source": [ 2200 | "# passing no argument to str.split means that it'll use whitespace of any sort or combination,\n", 2201 | "# including \\n and \\t.\n", 2202 | "words.split()" 2203 | ] 2204 | }, 2205 | { 2206 | "cell_type": "markdown", 2207 | "metadata": {}, 2208 | "source": [ 2209 | "# Next up\n", 2210 | "\n", 2211 | "1. Exercise with `str.split`\n", 2212 | "2. Talk about `str.join`\n", 2213 | "3. Tuples + unpacking" 2214 | ] 2215 | }, 2216 | { 2217 | "cell_type": "markdown", 2218 | "metadata": {}, 2219 | "source": [ 2220 | "# Exercise: Pig Latin sentence\n", 2221 | "\n", 2222 | "You might remember that last week, we wrote a program that takes a single word and translates it into Pig Latin:\n", 2223 | "\n", 2224 | "```python\n", 2225 | "word = input('Enter a word: ').strip()\n", 2226 | "\n", 2227 | "if word[0] in 'aeiou':\n", 2228 | " print(word[0] + 'way')\n", 2229 | "else:\n", 2230 | " print(word[1:] + word[0] + 'ay')\n", 2231 | "```\n", 2232 | "\n", 2233 | "I want you to:\n", 2234 | "1. Get a sentence (all lowercase, no punctuation) from the user\n", 2235 | "2. Print a translation of each word into Pig Latin\n", 2236 | "3. Don't worry about whether the words are all on the same line.\n", 2237 | "\n", 2238 | "Example:\n", 2239 | "\n", 2240 | " Enter text: this is a test\n", 2241 | " histay isway away esttay" 2242 | ] 2243 | }, 2244 | { 2245 | "cell_type": "code", 2246 | "execution_count": 98, 2247 | "metadata": {}, 2248 | "outputs": [ 2249 | { 2250 | "name": "stdin", 2251 | "output_type": "stream", 2252 | "text": [ 2253 | "Enter a sentence: this is a test\n" 2254 | ] 2255 | }, 2256 | { 2257 | "name": "stdout", 2258 | "output_type": "stream", 2259 | "text": [ 2260 | "histay\n", 2261 | "isway\n", 2262 | "away\n", 2263 | "esttay\n" 2264 | ] 2265 | } 2266 | ], 2267 | "source": [ 2268 | "sentence = input('Enter a sentence: ').strip()\n", 2269 | "\n", 2270 | "for word in sentence.split():\n", 2271 | "\n", 2272 | " if word[0] in 'aeiou':\n", 2273 | " print(word + 'way')\n", 2274 | " else:\n", 2275 | " print(word[1:] + word[0] + 'ay')\n" 2276 | ] 2277 | }, 2278 | { 2279 | "cell_type": "code", 2280 | "execution_count": 99, 2281 | "metadata": {}, 2282 | "outputs": [ 2283 | { 2284 | "name": "stdin", 2285 | "output_type": "stream", 2286 | "text": [ 2287 | "Enter the word = this is a very important test\n" 2288 | ] 2289 | }, 2290 | { 2291 | "name": "stdout", 2292 | "output_type": "stream", 2293 | "text": [ 2294 | "histay\n", 2295 | "isway\n", 2296 | "away\n", 2297 | "eryvay\n", 2298 | "importantway\n", 2299 | "esttay\n" 2300 | ] 2301 | } 2302 | ], 2303 | "source": [ 2304 | "# SY\n", 2305 | "str1 = input('Enter the word = ').split()\n", 2306 | "\n", 2307 | "for each_value in str1:\n", 2308 | " if(each_value[0] in 'aeiou'):\n", 2309 | " print(f'{each_value}way')\n", 2310 | " else:\n", 2311 | " print(f'{each_value[1:]}{each_value[0]}ay')" 2312 | ] 2313 | }, 2314 | { 2315 | "cell_type": "markdown", 2316 | "metadata": {}, 2317 | "source": [ 2318 | "# The opposite of `str.split` is `str.join`\n", 2319 | "\n", 2320 | "`str.join` is string method that returns a new string based on (a) a list of strings and (b) a stringm, which I call \"glue,\" which will go between them." 2321 | ] 2322 | }, 2323 | { 2324 | "cell_type": "code", 2325 | "execution_count": 100, 2326 | "metadata": {}, 2327 | "outputs": [ 2328 | { 2329 | "data": { 2330 | "text/plain": [ 2331 | "'abcd*ef*ghij'" 2332 | ] 2333 | }, 2334 | "execution_count": 100, 2335 | "metadata": {}, 2336 | "output_type": "execute_result" 2337 | } 2338 | ], 2339 | "source": [ 2340 | "mylist = ['abcd', 'ef', 'ghij']\n", 2341 | "\n", 2342 | "'*'.join(mylist)" 2343 | ] 2344 | }, 2345 | { 2346 | "cell_type": "code", 2347 | "execution_count": 101, 2348 | "metadata": {}, 2349 | "outputs": [ 2350 | { 2351 | "data": { 2352 | "text/plain": [ 2353 | "'abcdefghij'" 2354 | ] 2355 | }, 2356 | "execution_count": 101, 2357 | "metadata": {}, 2358 | "output_type": "execute_result" 2359 | } 2360 | ], 2361 | "source": [ 2362 | "# don't want any glue? Pass the empty string\n", 2363 | "''.join(mylist)" 2364 | ] 2365 | }, 2366 | { 2367 | "cell_type": "markdown", 2368 | "metadata": {}, 2369 | "source": [ 2370 | "# Exercise: Pig Latin sentence (on one line)\n", 2371 | "\n", 2372 | "Repeat the last exercise, but make sure that the translation is all displayed on one line. You can (should?) use an empty list, and then `append` each of the translates words." 2373 | ] 2374 | }, 2375 | { 2376 | "cell_type": "code", 2377 | "execution_count": 103, 2378 | "metadata": {}, 2379 | "outputs": [ 2380 | { 2381 | "name": "stdin", 2382 | "output_type": "stream", 2383 | "text": [ 2384 | "Enter a sentence: this is a test\n" 2385 | ] 2386 | }, 2387 | { 2388 | "name": "stdout", 2389 | "output_type": "stream", 2390 | "text": [ 2391 | "histay isway away esttay\n" 2392 | ] 2393 | } 2394 | ], 2395 | "source": [ 2396 | "output = []\n", 2397 | "\n", 2398 | "sentence = input('Enter a sentence: ').strip()\n", 2399 | "\n", 2400 | "for word in sentence.split():\n", 2401 | "\n", 2402 | " if word[0] in 'aeiou':\n", 2403 | " output.append(word + 'way')\n", 2404 | " else:\n", 2405 | " output.append(word[1:] + word[0] + 'ay')\n", 2406 | "print(' '.join(output))" 2407 | ] 2408 | }, 2409 | { 2410 | "cell_type": "code", 2411 | "execution_count": 105, 2412 | "metadata": {}, 2413 | "outputs": [ 2414 | { 2415 | "name": "stdin", 2416 | "output_type": "stream", 2417 | "text": [ 2418 | "Enter a word: this is a test\n" 2419 | ] 2420 | }, 2421 | { 2422 | "name": "stdout", 2423 | "output_type": "stream", 2424 | "text": [ 2425 | "histay\n", 2426 | "isway\n", 2427 | "away\n", 2428 | "esttay\n", 2429 | "histay isway away esttay\n" 2430 | ] 2431 | } 2432 | ], 2433 | "source": [ 2434 | "# SK\n", 2435 | " \n", 2436 | "output_list = []\n", 2437 | "sentence = input('Enter a word: ').lower()\n", 2438 | "\n", 2439 | "sentence = sentence.split()\n", 2440 | "\n", 2441 | "for word in sentence:\n", 2442 | " if word[0][0] in 'aeiou':\n", 2443 | " print(word + 'way')\n", 2444 | " output_list.append(word + 'way')\n", 2445 | " else:\n", 2446 | " print(word[1:] + word[0] + 'ay')\n", 2447 | " output_list.append(word[1:] + word[0] + 'ay')\n", 2448 | "print(' '.join(output_list))\n" 2449 | ] 2450 | }, 2451 | { 2452 | "cell_type": "code", 2453 | "execution_count": null, 2454 | "metadata": {}, 2455 | "outputs": [], 2456 | "source": [ 2457 | "# SK\n", 2458 | "\n", 2459 | "list = []\n", 2460 | "sentence = input('Enter a word: ').lower()\n", 2461 | "\n", 2462 | "sentence = sentence.split()\n", 2463 | "\n", 2464 | "for word in sentence:\n", 2465 | " if word[0][0] in 'aeiou':\n", 2466 | " print(word + 'way')\n", 2467 | " list.append(word + 'way')\n", 2468 | " else:\n", 2469 | " print(word[1:] + word[0] + 'ay')\n", 2470 | " list.append(word[1:] + word[0] + 'ay')\n", 2471 | "print(list)\n", 2472 | "''.join(list)" 2473 | ] 2474 | }, 2475 | { 2476 | "cell_type": "markdown", 2477 | "metadata": {}, 2478 | "source": [ 2479 | "# Tuples\n", 2480 | "\n", 2481 | "Tuples are the 3rd member of the \"sequence\" family, with the other two being strings and lists. \n", 2482 | "\n", 2483 | "- Strings:\n", 2484 | " - Can contain characters\n", 2485 | " - Immutable\n", 2486 | "\n", 2487 | "- Lists:\n", 2488 | " - Can contain anything\n", 2489 | " - Mutable\n", 2490 | " \n", 2491 | "- Tuples:\n", 2492 | " - Can contain anything\n", 2493 | " - Immutable\n", 2494 | " \n", 2495 | "The real reason tuples exist is for a kind of struct/record or multi-part storage of different types. Lists, by contrast, are meant to be used with a single type." 2496 | ] 2497 | }, 2498 | { 2499 | "cell_type": "code", 2500 | "execution_count": 106, 2501 | "metadata": {}, 2502 | "outputs": [ 2503 | { 2504 | "data": { 2505 | "text/plain": [ 2506 | "tuple" 2507 | ] 2508 | }, 2509 | "execution_count": 106, 2510 | "metadata": {}, 2511 | "output_type": "execute_result" 2512 | } 2513 | ], 2514 | "source": [ 2515 | "# defining a tuple -- we normally use (), even though (as we'll see) they are optional\n", 2516 | "\n", 2517 | "t = (10, 20, 30, 40, 50)\n", 2518 | "type(t)" 2519 | ] 2520 | }, 2521 | { 2522 | "cell_type": "code", 2523 | "execution_count": 107, 2524 | "metadata": {}, 2525 | "outputs": [ 2526 | { 2527 | "data": { 2528 | "text/plain": [ 2529 | "10" 2530 | ] 2531 | }, 2532 | "execution_count": 107, 2533 | "metadata": {}, 2534 | "output_type": "execute_result" 2535 | } 2536 | ], 2537 | "source": [ 2538 | "t[0]" 2539 | ] 2540 | }, 2541 | { 2542 | "cell_type": "code", 2543 | "execution_count": 108, 2544 | "metadata": {}, 2545 | "outputs": [ 2546 | { 2547 | "data": { 2548 | "text/plain": [ 2549 | "(20, 30, 40)" 2550 | ] 2551 | }, 2552 | "execution_count": 108, 2553 | "metadata": {}, 2554 | "output_type": "execute_result" 2555 | } 2556 | ], 2557 | "source": [ 2558 | "t[1:4] # slice" 2559 | ] 2560 | }, 2561 | { 2562 | "cell_type": "code", 2563 | "execution_count": 109, 2564 | "metadata": {}, 2565 | "outputs": [ 2566 | { 2567 | "data": { 2568 | "text/plain": [ 2569 | "True" 2570 | ] 2571 | }, 2572 | "execution_count": 109, 2573 | "metadata": {}, 2574 | "output_type": "execute_result" 2575 | } 2576 | ], 2577 | "source": [ 2578 | "30 in t" 2579 | ] 2580 | }, 2581 | { 2582 | "cell_type": "code", 2583 | "execution_count": 110, 2584 | "metadata": {}, 2585 | "outputs": [ 2586 | { 2587 | "name": "stdout", 2588 | "output_type": "stream", 2589 | "text": [ 2590 | "10\n", 2591 | "20\n", 2592 | "30\n", 2593 | "40\n", 2594 | "50\n" 2595 | ] 2596 | } 2597 | ], 2598 | "source": [ 2599 | "for one_item in t:\n", 2600 | " print(one_item)" 2601 | ] 2602 | }, 2603 | { 2604 | "cell_type": "code", 2605 | "execution_count": 111, 2606 | "metadata": {}, 2607 | "outputs": [ 2608 | { 2609 | "data": { 2610 | "text/plain": [ 2611 | "(10, 20, 30, 40, 50)" 2612 | ] 2613 | }, 2614 | "execution_count": 111, 2615 | "metadata": {}, 2616 | "output_type": "execute_result" 2617 | } 2618 | ], 2619 | "source": [ 2620 | "# you don't even need () to use tuples\n", 2621 | "\n", 2622 | "t = 10, 20, 30, 40, 50\n", 2623 | "t" 2624 | ] 2625 | }, 2626 | { 2627 | "cell_type": "code", 2628 | "execution_count": 112, 2629 | "metadata": {}, 2630 | "outputs": [ 2631 | { 2632 | "ename": "TypeError", 2633 | "evalue": "'tuple' object does not support item assignment", 2634 | "output_type": "error", 2635 | "traceback": [ 2636 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2637 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 2638 | "Cell \u001b[0;32mIn[112], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# remember that tuples are immutable!\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mt\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m!\u001b[39m\u001b[38;5;124m'\u001b[39m\n", 2639 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 2640 | ] 2641 | } 2642 | ], 2643 | "source": [ 2644 | "# remember that tuples are immutable!\n", 2645 | "\n", 2646 | "t[3] = '!'" 2647 | ] 2648 | }, 2649 | { 2650 | "cell_type": "code", 2651 | "execution_count": 113, 2652 | "metadata": {}, 2653 | "outputs": [ 2654 | { 2655 | "name": "stdout", 2656 | "output_type": "stream", 2657 | "text": [ 2658 | "[10, 20, 30]\n" 2659 | ] 2660 | } 2661 | ], 2662 | "source": [ 2663 | "# check this out:\n", 2664 | "\n", 2665 | "mylist = [10, 20, 30]\n", 2666 | "x = mylist\n", 2667 | "print(x)" 2668 | ] 2669 | }, 2670 | { 2671 | "cell_type": "code", 2672 | "execution_count": 114, 2673 | "metadata": {}, 2674 | "outputs": [], 2675 | "source": [ 2676 | "# tuple unpacking\n", 2677 | "# on the right, we have a data source an iterable)\n", 2678 | "# on the left, we have a tuple of variables\n", 2679 | "\n", 2680 | "x,y,z = mylist" 2681 | ] 2682 | }, 2683 | { 2684 | "cell_type": "code", 2685 | "execution_count": 115, 2686 | "metadata": {}, 2687 | "outputs": [ 2688 | { 2689 | "data": { 2690 | "text/plain": [ 2691 | "10" 2692 | ] 2693 | }, 2694 | "execution_count": 115, 2695 | "metadata": {}, 2696 | "output_type": "execute_result" 2697 | } 2698 | ], 2699 | "source": [ 2700 | "x" 2701 | ] 2702 | }, 2703 | { 2704 | "cell_type": "code", 2705 | "execution_count": 116, 2706 | "metadata": {}, 2707 | "outputs": [ 2708 | { 2709 | "data": { 2710 | "text/plain": [ 2711 | "20" 2712 | ] 2713 | }, 2714 | "execution_count": 116, 2715 | "metadata": {}, 2716 | "output_type": "execute_result" 2717 | } 2718 | ], 2719 | "source": [ 2720 | "y" 2721 | ] 2722 | }, 2723 | { 2724 | "cell_type": "code", 2725 | "execution_count": 117, 2726 | "metadata": {}, 2727 | "outputs": [ 2728 | { 2729 | "data": { 2730 | "text/plain": [ 2731 | "30" 2732 | ] 2733 | }, 2734 | "execution_count": 117, 2735 | "metadata": {}, 2736 | "output_type": "execute_result" 2737 | } 2738 | ], 2739 | "source": [ 2740 | "z" 2741 | ] 2742 | }, 2743 | { 2744 | "cell_type": "code", 2745 | "execution_count": 121, 2746 | "metadata": {}, 2747 | "outputs": [ 2748 | { 2749 | "name": "stdout", 2750 | "output_type": "stream", 2751 | "text": [ 2752 | "0: a\n", 2753 | "1: b\n", 2754 | "2: c\n", 2755 | "3: d\n" 2756 | ] 2757 | } 2758 | ], 2759 | "source": [ 2760 | "s = 'abcd'\n", 2761 | "\n", 2762 | "for one_item in enumerate(s):\n", 2763 | " key, value = one_item # tuple unpacking\n", 2764 | " print(f'{key}: {value}')" 2765 | ] 2766 | }, 2767 | { 2768 | "cell_type": "code", 2769 | "execution_count": null, 2770 | "metadata": {}, 2771 | "outputs": [], 2772 | "source": [ 2773 | "# why work so hard?\n", 2774 | "# there's an even better way.\n", 2775 | "\n", 2776 | "s = 'abcd'\n", 2777 | "\n", 2778 | "for key, value in enumerate(s):\n", 2779 | " print(f'{key}: {value}')" 2780 | ] 2781 | }, 2782 | { 2783 | "cell_type": "markdown", 2784 | "metadata": {}, 2785 | "source": [ 2786 | "# Homework for the 24th\n", 2787 | "\n", 2788 | "1. Implement vowels, digits, and others with three lists.\n", 2789 | "2. The elements of each list will be the characters that you get from the user.\n", 2790 | "3. Have the user enter text until they enter the empty string.\n", 2791 | "4. When the user enters a non-empty string, the program should through it , one character at a time, and classify it as vowel/digit/other.\n", 2792 | "5. The idea is that we'll have the three lists fill up with characters of the same type." 2793 | ] 2794 | }, 2795 | { 2796 | "cell_type": "code", 2797 | "execution_count": null, 2798 | "metadata": {}, 2799 | "outputs": [], 2800 | "source": [] 2801 | } 2802 | ], 2803 | "metadata": { 2804 | "kernelspec": { 2805 | "display_name": "Python 3 (ipykernel)", 2806 | "language": "python", 2807 | "name": "python3" 2808 | }, 2809 | "language_info": { 2810 | "codemirror_mode": { 2811 | "name": "ipython", 2812 | "version": 3 2813 | }, 2814 | "file_extension": ".py", 2815 | "mimetype": "text/x-python", 2816 | "name": "python", 2817 | "nbconvert_exporter": "python", 2818 | "pygments_lexer": "ipython3", 2819 | "version": "3.12.1" 2820 | }, 2821 | "widgets": { 2822 | "application/vnd.jupyter.widget-state+json": { 2823 | "state": {}, 2824 | "version_major": 2, 2825 | "version_minor": 0 2826 | } 2827 | } 2828 | }, 2829 | "nbformat": 4, 2830 | "nbformat_minor": 4 2831 | } 2832 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notebooks, files, and programs from "Python in Five weeks" 2 | 3 | This repo contains the Jupyter notebook + program files from my training for O'Reilly from summer 2024. It'll remain open, so you can review the material later on. 4 | 5 | Enjoy! 6 | 7 | If you liked this training, you might also like: 8 | 9 | - My online courses offerings, at https://LernerPython.com/ 10 | - Better developers, with new articles about Python every week: https://BetterDevelopersWeekly.com/ 11 | - My Twitter feed: https://Twitter.com/reuvenmlerner 12 | - My YouTube channel: https://YouTube.com/reuvenlerner 13 | - My book, "Python Workout": https://PythonWorkout.com/ 14 | - My book, "Pandas Workout": https://PandasWorkout.com/ 15 | - "Bamboo Weekly," where I analyze data related to current events using Pandas: https://www.BambooWeekly.com/ 16 | - LinkedIn, where I also post: https://linkedin.com/in/reuven 17 | 18 | And of course, you can read more about me at https://lerner.co.il/ 19 | -------------------------------------------------------------------------------- /chooser.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def chooser(options): 4 | return random.choice(options) 5 | -------------------------------------------------------------------------------- /config.txt: -------------------------------------------------------------------------------- 1 | a=10 2 | b=20 3 | c=30 4 | -------------------------------------------------------------------------------- /linux-etc-passwd.txt: -------------------------------------------------------------------------------- 1 | # This is a comment 2 | # You should ignore me 3 | root:x:0:0:root:/root:/bin/bash 4 | daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 5 | bin:x:2:2:bin:/bin:/usr/sbin/nologin 6 | sys:x:3:3:sys:/dev:/usr/sbin/nologin 7 | sync:x:4:65534:sync:/bin:/bin/sync 8 | games:x:5:60:games:/usr/games:/usr/sbin/nologin 9 | man:x:6:12:man:/var/cache/man:/usr/sbin/nologin 10 | lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin 11 | mail:x:8:8:mail:/var/mail:/usr/sbin/nologin 12 | 13 | 14 | 15 | news:x:9:9:news:/var/spool/news:/usr/sbin/nologin 16 | uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin 17 | proxy:x:13:13:proxy:/bin:/usr/sbin/nologin 18 | www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin 19 | backup:x:34:34:backup:/var/backups:/usr/sbin/nologin 20 | list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin 21 | irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin 22 | gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin 23 | 24 | nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin 25 | syslog:x:101:104::/home/syslog:/bin/false 26 | messagebus:x:102:106::/var/run/dbus:/bin/false 27 | landscape:x:103:109::/var/lib/landscape:/bin/false 28 | jci:x:955:955::/home/jci:/bin/bash 29 | sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin 30 | user:x:1000:1000:user,,,:/home/user:/bin/bash 31 | reuven:x:1001:1001:Reuven M. Lerner,,,:/home/reuven:/bin/bash 32 | postfix:x:105:113::/var/spool/postfix:/bin/false 33 | colord:x:106:116:colord colour management daemon,,,:/var/lib/colord:/bin/false 34 | postgres:x:107:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash 35 | dovecot:x:108:119:Dovecot mail server,,,:/usr/lib/dovecot:/bin/false 36 | dovenull:x:109:120:Dovecot login user,,,:/nonexistent:/bin/false 37 | postgrey:x:110:121::/var/lib/postgrey:/bin/false 38 | debian-spamd:x:111:122::/var/lib/spamassassin:/bin/sh 39 | memcache:x:113:124:Memcached,,,:/nonexistent:/bin/false 40 | genadi:x:1002:1003:Genadi Reznichenko,,,:/home/genadi:/bin/bash 41 | shira:x:1003:1004:Shira Friedman,,,:/home/shira:/bin/bash 42 | atara:x:1004:1005:Atara Lerner-Friedman,,,:/home/atara:/bin/bash 43 | shikma:x:1005:1006:Shikma Lerner-Friedman,,,:/home/shikma:/bin/bash 44 | amotz:x:1006:1007:Amotz Lerner-Friedman,,,:/home/amotz:/bin/bash 45 | mysql:x:114:125:MySQL Server,,,:/nonexistent:/bin/false 46 | clamav:x:115:126::/var/lib/clamav:/bin/false 47 | amavis:x:116:127:AMaViS system user,,,:/var/lib/amavis:/bin/sh 48 | opendkim:x:117:128::/var/run/opendkim:/bin/false 49 | gitlab-redis:x:999:1009::/var/opt/gitlab/redis:/bin/nologin 50 | gitlab-psql:x:998:1010::/var/opt/gitlab/postgresql:/bin/sh 51 | git:x:1007:1008:GitLab,,,:/home/git:/bin/bash 52 | opendmarc:x:118:129::/var/run/opendmarc:/bin/false 53 | dkim-milter-python:x:119:130::/var/run/dkim-milter-python:/bin/false 54 | deploy:x:1008:1011:Deploy,,,:/home/deploy:/bin/bash 55 | redis:x:112:123:redis server,,,:/var/lib/redis:/bin/false 56 | -------------------------------------------------------------------------------- /menu.py: -------------------------------------------------------------------------------- 1 | def menu(choices): 2 | while True: 3 | s = input(f'Choose from {"/".join(choices)}: ').strip() 4 | 5 | if s in choices: 6 | return s 7 | 8 | print(f'{s} is invalid; try again') 9 | 10 | if __name__ == '__main__': 11 | choices = 'abc' 12 | 13 | user_choice = menu(choices) 14 | print(f'You chose {user_choice}.') 15 | -------------------------------------------------------------------------------- /mini-access-log.txt: -------------------------------------------------------------------------------- 1 | 67.218.116.165 - - [30/Jan/2010:00:03:18 +0200] "GET /robots.txt HTTP/1.0" 200 99 "-" "Mozilla/5.0 (Twiceler-0.9 http://www.cuil.com/twiceler/robot.html)" 2 | 66.249.71.65 - - [30/Jan/2010:00:12:06 +0200] "GET /browse/one_node/1557 HTTP/1.1" 200 39208 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 3 | 65.55.106.183 - - [30/Jan/2010:01:29:23 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 4 | 65.55.106.183 - - [30/Jan/2010:01:30:06 +0200] "GET /browse/one_model/2162 HTTP/1.1" 200 2181 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 5 | 66.249.71.65 - - [30/Jan/2010:02:07:14 +0200] "GET /browse/browse_applet_tab/2593 HTTP/1.1" 200 10305 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 6 | 66.249.71.65 - - [30/Jan/2010:02:10:39 +0200] "GET /browse/browse_files_tab/2499?tab=true HTTP/1.1" 200 446 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 7 | 66.249.65.12 - - [30/Jan/2010:03:13:34 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 8 | 66.249.65.12 - - [30/Jan/2010:03:13:34 +0200] "GET /browse/one_node/2715 HTTP/1.1" 200 26433 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 9 | 66.249.65.12 - - [30/Jan/2010:03:43:39 +0200] "GET /browse/download_model/1969 HTTP/1.1" 200 31713 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 10 | 66.249.65.12 - - [30/Jan/2010:04:05:43 +0200] "GET /browse/one_node/1406 HTTP/1.1" 302 118 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 11 | 66.249.65.12 - - [30/Jan/2010:04:05:51 +0200] "GET /browse/one_model/1406 HTTP/1.1" 200 2179 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 12 | 65.55.106.131 - - [30/Jan/2010:04:24:33 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 13 | 65.55.106.131 - - [30/Jan/2010:04:25:36 +0200] "GET /browse/one_model/1200 HTTP/1.1" 200 2180 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 14 | 66.249.65.12 - - [30/Jan/2010:04:34:36 +0200] "GET /browse/download_model/2170 HTTP/1.1" 200 11772 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 15 | 66.249.65.12 - - [30/Jan/2010:04:39:37 +0200] "GET /browse/browse_preview_tab/2499?tab=true HTTP/1.1" 200 452 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 16 | 66.249.65.12 - - [30/Jan/2010:05:03:34 +0200] "GET /browse/download_model/2244 HTTP/1.1" 200 7215 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 17 | 66.249.65.12 - - [30/Jan/2010:05:32:31 +0200] "GET /browse/download_model/1002 HTTP/1.1" 200 3658 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 18 | 66.249.65.12 - - [30/Jan/2010:06:01:22 +0200] "GET /browse/download_model/1200 HTTP/1.1" 200 31950 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 19 | 66.249.65.12 - - [30/Jan/2010:06:30:19 +0200] "GET /browse/download_model/2463 HTTP/1.1" 200 3357 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 20 | 66.249.65.12 - - [30/Jan/2010:06:59:14 +0200] "GET /browse/download_model/1861 HTTP/1.1" 200 5136 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 21 | 65.55.106.186 - - [30/Jan/2010:07:07:13 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 22 | 65.55.106.186 - - [30/Jan/2010:07:08:06 +0200] "GET /browse/about HTTP/1.1" 200 2315 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 23 | 66.249.65.12 - - [30/Jan/2010:07:28:09 +0200] "GET /browse/download_model/1712 HTTP/1.1" 200 11605 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 24 | 66.249.65.12 - - [30/Jan/2010:07:57:06 +0200] "GET /browse/download_model/1192 HTTP/1.1" 200 31656 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 25 | 66.249.65.12 - - [30/Jan/2010:08:26:00 +0200] "GET /browse/download_model/1140 HTTP/1.1" 200 4370 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 26 | 74.52.245.146 - - [30/Jan/2010:08:40:26 +0200] "GET / HTTP/1.0" 302 110 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0" 27 | 74.52.245.146 - - [30/Jan/2010:08:40:26 +0200] "GET /account/login HTTP/1.0" 200 5801 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0" 28 | 66.249.65.43 - - [30/Jan/2010:08:44:51 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 29 | 66.249.65.43 - - [30/Jan/2010:08:44:52 +0200] "GET / HTTP/1.1" 302 112 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 30 | 66.249.65.43 - - [30/Jan/2010:08:44:52 +0200] "GET /account/login HTTP/1.1" 200 1935 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 31 | 66.249.65.12 - - [30/Jan/2010:08:54:53 +0200] "GET /browse/download_model/2152 HTTP/1.1" 200 7285 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 32 | 66.249.65.12 - - [30/Jan/2010:09:23:46 +0200] "GET /browse/download_model/796 HTTP/1.1" 200 3241 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 33 | 66.249.65.12 - - [30/Jan/2010:09:52:42 +0200] "GET /browse/one_node/2177 HTTP/1.1" 200 1556 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 34 | 66.249.65.12 - - [30/Jan/2010:10:21:43 +0200] "GET /browse/one_node/2163 HTTP/1.1" 200 4124 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 35 | 66.249.65.12 - - [30/Jan/2010:10:50:35 +0200] "GET /browse/one_node/1193 HTTP/1.1" 200 29168 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 36 | 66.249.65.12 - - [30/Jan/2010:11:19:27 +0200] "GET /browse/one_node/1241 HTTP/1.1" 200 7032 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 37 | 65.55.207.25 - - [30/Jan/2010:11:43:56 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 38 | 65.55.207.25 - - [30/Jan/2010:11:44:35 +0200] "GET /help HTTP/1.1" 304 - "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 39 | 66.249.65.12 - - [30/Jan/2010:11:48:31 +0200] "GET /browse/download_model/2508 HTTP/1.1" 200 11374 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 40 | 66.249.65.12 - - [30/Jan/2010:12:17:24 +0200] "GET /browse/one_node/2509 HTTP/1.1" 200 4766 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 41 | 66.249.65.12 - - [30/Jan/2010:12:46:17 +0200] "GET /browse/one_node/1233 HTTP/1.1" 200 79301 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 42 | 66.249.65.12 - - [30/Jan/2010:13:15:09 +0200] "GET /browse/download_model/2508?version=1819 HTTP/1.1" 200 11374 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 43 | 66.249.65.12 - - [30/Jan/2010:13:44:01 +0200] "GET /browse/download_model/2508?version=1821 HTTP/1.1" 200 11374 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 44 | 66.249.65.12 - - [30/Jan/2010:14:12:55 +0200] "GET /browse/download_model/902 HTTP/1.1" 200 5050 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45 | 66.249.65.12 - - [30/Jan/2010:14:42:01 +0200] "GET /browse/download_model/1679 HTTP/1.1" 200 11290 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 46 | 65.55.207.94 - - [30/Jan/2010:15:02:52 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 47 | 65.55.207.94 - - [30/Jan/2010:15:03:36 +0200] "GET /browse/one_model/900 HTTP/1.1" 200 2165 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 48 | 66.249.65.12 - - [30/Jan/2010:15:10:51 +0200] "GET /browse/download_model/1612 HTTP/1.1" 200 30540 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 49 | 65.55.207.71 - - [30/Jan/2010:15:32:04 +0200] "GET /account/new HTTP/1.1" 304 - "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 50 | 66.249.65.12 - - [30/Jan/2010:15:39:45 +0200] "GET /browse/download_model/892 HTTP/1.1" 200 4195 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 51 | 66.249.65.12 - - [30/Jan/2010:15:52:21 +0200] "GET /system/avatars/7/thumb/fractal-tree-on-transparent-sm.png?1237131134 HTTP/1.1" 304 - "-" "Googlebot-Image/1.0" 52 | 66.249.65.12 - - [30/Jan/2010:16:08:36 +0200] "GET /browse/download_model/1865 HTTP/1.1" 200 19432 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 53 | 98.242.170.241 - - [30/Jan/2010:16:10:49 +0200] "GET /dvdrental.com HTTP/1.1" 404 947 "http://www.dvdrental.com/modelingcommons.org" "Opera/9.80 (Windows NT 5.2; U; en) Presto/2.2.15 Version/10.10" 54 | 66.249.65.38 - - [30/Jan/2010:16:37:33 +0200] "GET /browse/download_model/914 HTTP/1.1" 200 6181 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 55 | 66.249.65.38 - - [30/Jan/2010:16:45:12 +0200] "GET /browse/browse_applet_tab/2593?tab=true HTTP/1.1" 200 10237 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 56 | 66.249.65.38 - - [30/Jan/2010:17:02:28 +0200] "GET /javascripts/application.js?1264605648 HTTP/1.1" 200 698 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 57 | 66.249.65.38 - - [30/Jan/2010:17:02:29 +0200] "GET /stylesheets/browse.css?1264605648 HTTP/1.1" 200 422 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 58 | 66.249.65.38 - - [30/Jan/2010:17:02:30 +0200] "GET /javascripts/jquery.livequery.js?1264605648 HTTP/1.1" 200 2135 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 59 | 66.249.65.38 - - [30/Jan/2010:17:02:30 +0200] "GET /javascripts/jrails.js?1264605648 HTTP/1.1" 200 1093 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 60 | 66.249.65.38 - - [30/Jan/2010:17:02:31 +0200] "GET /stylesheets/themes/nlcommons/ui.all.css?1264605648 HTTP/1.1" 200 52 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 61 | 66.249.65.38 - - [30/Jan/2010:17:02:31 +0200] "GET /stylesheets/jquery.autocomplete.css?1264605648 HTTP/1.1" 200 447 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 62 | 66.249.65.38 - - [30/Jan/2010:17:02:32 +0200] "GET /stylesheets/nlcommons.css?1264605648 HTTP/1.1" 200 1179 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 63 | 66.249.65.38 - - [30/Jan/2010:17:02:32 +0200] "GET /javascripts/jquery.dataTables.js?1264605648 HTTP/1.1" 200 15537 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 64 | 66.249.65.38 - - [30/Jan/2010:17:02:33 +0200] "GET /javascripts/jquery.js?1264605648 HTTP/1.1" 200 19740 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 65 | 66.249.65.38 - - [30/Jan/2010:17:02:34 +0200] "GET /javascripts/nlcommons.js?1264605648 HTTP/1.1" 200 20 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 66 | 66.249.65.38 - - [30/Jan/2010:17:02:34 +0200] "GET /javascripts/jquery-ui.js?1264605648 HTTP/1.1" 200 72080 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 67 | 66.249.65.38 - - [30/Jan/2010:17:02:35 +0200] "GET /javascripts/jquery.autocomplete.js?1264605648 HTTP/1.1" 200 6433 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 68 | 66.249.65.38 - - [30/Jan/2010:17:03:16 +0200] "GET /stylesheets/themes/nlcommons/ui.base.css HTTP/1.1" 200 111 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 69 | 66.249.65.38 - - [30/Jan/2010:17:03:16 +0200] "GET /stylesheets/themes/nlcommons/ui.theme.css HTTP/1.1" 200 2862 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 70 | 66.249.65.38 - - [30/Jan/2010:17:03:30 +0200] "GET /stylesheets/themes/nlcommons/ui.core.css HTTP/1.1" 200 624 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 71 | 66.249.65.38 - - [30/Jan/2010:17:03:31 +0200] "GET /stylesheets/themes/nlcommons/ui.accordion.css HTTP/1.1" 200 295 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 72 | 66.249.65.38 - - [30/Jan/2010:17:03:31 +0200] "GET /stylesheets/themes/nlcommons/ui.datepicker.css HTTP/1.1" 200 965 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 73 | 66.249.65.38 - - [30/Jan/2010:17:03:32 +0200] "GET /stylesheets/themes/nlcommons/ui.dialog.css HTTP/1.1" 200 442 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 74 | 66.249.65.38 - - [30/Jan/2010:17:03:32 +0200] "GET /stylesheets/themes/nlcommons/ui.slider.css HTTP/1.1" 200 318 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 75 | 66.249.65.38 - - [30/Jan/2010:17:03:33 +0200] "GET /stylesheets/themes/nlcommons/ui.progressbar.css HTTP/1.1" 200 114 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 76 | 66.249.65.38 - - [30/Jan/2010:17:03:34 +0200] "GET /stylesheets/themes/nlcommons/ui.tabs.css HTTP/1.1" 200 414 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 77 | 66.249.65.38 - - [30/Jan/2010:17:03:34 +0200] "GET /stylesheets/themes/nlcommons/ui.resizable.css HTTP/1.1" 200 307 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 78 | 66.249.65.38 - - [30/Jan/2010:17:06:29 +0200] "GET /browse/download_model/743 HTTP/1.1" 200 10552 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 79 | 66.249.65.38 - - [30/Jan/2010:17:35:24 +0200] "GET /browse/download_model/2547 HTTP/1.1" 200 40914 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 80 | 65.55.207.126 - - [30/Jan/2010:17:46:11 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 81 | 65.55.207.126 - - [30/Jan/2010:17:48:32 +0200] "GET /browse/one_model/1002 HTTP/1.1" 200 2173 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 82 | 66.249.65.38 - - [30/Jan/2010:18:04:31 +0200] "GET /browse/download_model/1210 HTTP/1.1" 200 11948 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 83 | 66.249.65.38 - - [30/Jan/2010:18:33:30 +0200] "GET /browse/download_model/849 HTTP/1.1" 200 6836 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 84 | 66.249.65.38 - - [30/Jan/2010:18:53:53 +0200] "GET /tags/one_tag/27 HTTP/1.1" 200 2033 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 85 | 66.249.65.38 - - [30/Jan/2010:19:02:20 +0200] "GET /browse/download_model/739 HTTP/1.1" 200 11302 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 86 | 82.34.9.20 - - [30/Jan/2010:19:18:24 +0200] "GET /account/models/33 HTTP/1.1" 200 23774 "http://www.google.co.uk/search?hl=en&q=%22netlogo%22+sokoban&btnG=Search&meta=&aq=f&oq=" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)" 87 | 82.34.9.20 - - [30/Jan/2010:19:18:18 +0200] "GET /account/models/33 HTTP/1.1" 200 23774 "http://www.google.co.uk/search?hl=en&q=%22netlogo%22+sokoban&btnG=Search&meta=&aq=f&oq=" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)" 88 | 66.249.65.38 - - [30/Jan/2010:19:31:07 +0200] "GET /browse/download_model/838 HTTP/1.1" 200 7691 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 89 | 66.249.65.38 - - [30/Jan/2010:20:00:20 +0200] "GET /browse/download_model/2316 HTTP/1.1" 200 48709 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 90 | 66.249.65.38 - - [30/Jan/2010:20:28:55 +0200] "GET /browse/download_model/840 HTTP/1.1" 200 6063 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 91 | 66.249.65.38 - - [30/Jan/2010:20:47:05 +0200] "GET /?id=7 HTTP/1.1" 200 3058 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 92 | 66.249.65.38 - - [30/Jan/2010:20:57:43 +0200] "GET /browse/download_model/806 HTTP/1.1" 200 4263 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 93 | 66.249.65.38 - - [30/Jan/2010:21:07:44 +0200] "GET /account/mypage/17 HTTP/1.1" 200 3103 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 94 | 66.249.65.38 - - [30/Jan/2010:21:26:36 +0200] "GET /browse/download_model/1891 HTTP/1.1" 200 8570 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 95 | 66.249.65.38 - - [30/Jan/2010:21:56:01 +0200] "GET /browse/download_model/1881 HTTP/1.1" 200 9618 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 96 | 66.249.65.38 - - [30/Jan/2010:22:25:13 +0200] "GET /browse/download_model/735 HTTP/1.1" 200 16848 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 97 | 65.55.106.155 - - [30/Jan/2010:22:25:26 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 98 | 65.55.106.155 - - [30/Jan/2010:22:26:11 +0200] "GET /account/send_password HTTP/1.1" 304 - "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 99 | 66.249.65.38 - - [30/Jan/2010:22:53:40 +0200] "GET /browse/download_model/1779 HTTP/1.1" 200 8576 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 100 | 66.249.65.38 - - [30/Jan/2010:23:21:25 +0200] "GET /browse/follow/2029.atom HTTP/1.1" 200 653 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 101 | 66.249.65.38 - - [30/Jan/2010:23:22:21 +0200] "GET /browse/download_model/788 HTTP/1.1" 200 3865 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 102 | 66.249.65.38 - - [30/Jan/2010:23:28:41 +0200] "GET /images/default-person.png?1245832850 HTTP/1.1" 200 677 "-" "Googlebot-Image/1.0" 103 | 66.249.65.38 - - [30/Jan/2010:23:53:12 +0200] "GET /browse/download_model/2340 HTTP/1.1" 200 30305 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 104 | 65.55.207.77 - - [31/Jan/2010:00:06:37 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 105 | 65.55.207.77 - - [31/Jan/2010:00:09:36 +0200] "GET /browse/one_model/2152 HTTP/1.1" 200 2195 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 106 | 66.249.65.38 - - [31/Jan/2010:01:15:50 +0200] "GET /account/follow/2029.atom HTTP/1.1" 404 577 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 107 | 67.218.116.165 - - [31/Jan/2010:01:23:08 +0200] "GET /robots.txt HTTP/1.0" 200 99 "-" "Mozilla/5.0 (Twiceler-0.9 http://www.cuil.com/twiceler/robot.html)" 108 | 66.249.65.38 - - [31/Jan/2010:01:35:43 +0200] "GET /browse/one_model/2099 HTTP/1.1" 200 2179 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 109 | 208.80.193.28 - - [31/Jan/2010:01:50:14 +0200] "GET / HTTP/1.0" 302 106 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; Hotbar 10.0.356.0)" 110 | 66.249.65.38 - - [31/Jan/2010:02:17:46 +0200] "GET /browse/download_model/985 HTTP/1.1" 200 3204 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 111 | 66.249.65.38 - - [31/Jan/2010:02:48:17 +0200] "GET /browse/download_model/2162 HTTP/1.1" 200 9362 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 112 | 66.249.65.38 - - [31/Jan/2010:02:51:11 +0200] "GET /browse/display_preview/2099 HTTP/1.1" 200 7563 "-" "Googlebot-Image/1.0" 113 | 66.249.65.38 - - [31/Jan/2010:03:04:16 +0200] "GET /browse/download_model/993 HTTP/1.1" 200 3175 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 114 | 66.249.65.38 - - [31/Jan/2010:03:29:31 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 115 | 66.249.65.38 - - [31/Jan/2010:03:29:31 +0200] "GET /browse/download_model/977 HTTP/1.1" 200 2992 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 116 | 66.249.65.38 - - [31/Jan/2010:03:49:42 +0200] "GET /tags/one_tag/42 HTTP/1.1" 200 2014 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 117 | 66.249.65.38 - - [31/Jan/2010:03:54:44 +0200] "GET /browse/download_model/746 HTTP/1.1" 200 12754 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 118 | 66.249.65.38 - - [31/Jan/2010:04:19:51 +0200] "GET /browse/download_model/815 HTTP/1.1" 200 6284 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 119 | 89.248.172.58 - - [31/Jan/2010:04:32:52 +0200] "GET /account/mypage/7 HTTP/1.1" 200 14292 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 120 | 89.248.172.58 - - [31/Jan/2010:04:33:03 +0200] "GET / HTTP/1.1" 302 106 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 121 | 89.248.172.58 - - [31/Jan/2010:04:33:03 +0200] "GET /account/login HTTP/1.1" 200 5998 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 122 | 89.248.172.58 - - [31/Jan/2010:04:33:04 +0200] "GET /browse/list_models HTTP/1.1" 200 21752 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 123 | 89.248.172.58 - - [31/Jan/2010:04:33:05 +0200] "GET /browse/about HTTP/1.1" 200 6801 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 124 | 89.248.172.58 - - [31/Jan/2010:04:33:06 +0200] "GET /help HTTP/1.1" 200 5683 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 125 | 89.248.172.58 - - [31/Jan/2010:04:33:06 +0200] "GET /account/login HTTP/1.1" 200 5801 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 126 | 89.248.172.58 - - [31/Jan/2010:04:33:07 +0200] "GET /account/follow/7.atom HTTP/1.1" 200 4893 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 127 | 89.248.172.58 - - [31/Jan/2010:04:33:07 +0200] "GET /browse/one_model/1210 HTTP/1.1" 200 6905 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 128 | 89.248.172.58 - - [31/Jan/2010:04:33:08 +0200] "GET /browse/one_model/1390 HTTP/1.1" 200 6957 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 129 | 89.248.172.58 - - [31/Jan/2010:04:33:09 +0200] "GET /browse/one_model/2495 HTTP/1.1" 200 7013 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 130 | 89.248.172.58 - - [31/Jan/2010:04:33:09 +0200] "GET /browse/one_model/2518 HTTP/1.1" 200 6869 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 131 | 89.248.172.58 - - [31/Jan/2010:04:33:10 +0200] "GET /browse/one_model/1408 HTTP/1.1" 200 6893 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 132 | 89.248.172.58 - - [31/Jan/2010:04:33:11 +0200] "GET /tags/one_tag/48 HTTP/1.1" 200 6313 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 133 | 89.248.172.58 - - [31/Jan/2010:04:33:11 +0200] "GET /tags/one_tag/8 HTTP/1.1" 200 6295 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 134 | 89.248.172.58 - - [31/Jan/2010:04:33:12 +0200] "GET /browse/one_model/815 HTTP/1.1" 200 6839 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 135 | 89.248.172.58 - - [31/Jan/2010:04:33:13 +0200] "GET /browse/one_model/2547 HTTP/1.1" 200 6890 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 136 | 89.248.172.58 - - [31/Jan/2010:04:33:13 +0200] "GET /browse/one_model/1578 HTTP/1.1" 200 6913 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 137 | 89.248.172.58 - - [31/Jan/2010:04:33:14 +0200] "GET /browse/one_model/2510 HTTP/1.1" 200 6829 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 138 | 89.248.172.58 - - [31/Jan/2010:04:33:14 +0200] "GET /browse/one_model/999 HTTP/1.1" 200 6860 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 139 | 89.248.172.58 - - [31/Jan/2010:04:33:15 +0200] "GET /account/models/7 HTTP/1.1" 200 8787 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 140 | 89.248.172.58 - - [31/Jan/2010:04:33:16 +0200] "GET /?id=17 HTTP/1.1" 200 14542 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" 141 | 66.249.65.38 - - [31/Jan/2010:04:45:02 +0200] "GET /browse/download_model/2182 HTTP/1.1" 200 16607 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 142 | 66.249.65.38 - - [31/Jan/2010:05:10:16 +0200] "GET /browse/download_model/900 HTTP/1.1" 200 3440 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 143 | 66.249.65.38 - - [31/Jan/2010:05:17:05 +0200] "GET /?id=8 HTTP/1.1" 200 3018 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 144 | 66.249.65.38 - - [31/Jan/2010:05:35:29 +0200] "GET /browse/download_model/797 HTTP/1.1" 200 11950 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 145 | 66.249.65.38 - - [31/Jan/2010:06:00:42 +0200] "GET /browse/download_model/2606 HTTP/1.1" 200 357240 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 146 | 66.249.65.38 - - [31/Jan/2010:06:03:13 +0200] "GET /browse/one_model/993 HTTP/1.1" 200 2170 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 147 | 66.249.65.38 - - [31/Jan/2010:06:25:55 +0200] "GET /browse/download_model/2601 HTTP/1.1" 200 2498832 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 148 | 66.249.65.38 - - [31/Jan/2010:06:51:01 +0200] "GET /browse/download_model/2596 HTTP/1.1" 200 220990 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 149 | 66.249.65.38 - - [31/Jan/2010:07:06:26 +0200] "GET /browse/display_preview/2244 HTTP/1.1" 200 4072 "-" "Googlebot-Image/1.0" 150 | 66.249.65.38 - - [31/Jan/2010:07:16:18 +0200] "GET /browse/download_model/2752 HTTP/1.1" 200 3146 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 151 | 66.249.65.38 - - [31/Jan/2010:07:41:27 +0200] "GET /browse/download_model/2492 HTTP/1.1" 200 1680079 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 152 | 66.249.65.38 - - [31/Jan/2010:08:06:40 +0200] "GET /browse/download_model/1408 HTTP/1.1" 200 25038 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 153 | 66.249.65.38 - - [31/Jan/2010:08:31:50 +0200] "GET /browse/download_model/2511 HTTP/1.1" 200 39499 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 154 | 66.249.65.38 - - [31/Jan/2010:08:56:59 +0200] "GET /browse/download_model/2479 HTTP/1.1" 200 39598 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 155 | 66.249.65.38 - - [31/Jan/2010:09:22:13 +0200] "GET /browse/download_model/2754 HTTP/1.1" 200 3279 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 156 | 66.249.65.38 - - [31/Jan/2010:09:47:25 +0200] "GET /browse/download_model/2751 HTTP/1.1" 200 3146 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 157 | 66.249.65.38 - - [31/Jan/2010:10:12:33 +0200] "GET /browse/download_model/2656 HTTP/1.1" 200 117532 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 158 | 66.249.65.38 - - [31/Jan/2010:10:30:53 +0200] "GET /browse/one_node/2701 HTTP/1.1" 200 39424 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 159 | 66.249.65.38 - - [31/Jan/2010:10:37:46 +0200] "GET /browse/download_model/935 HTTP/1.1" 200 5014 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 160 | 66.249.65.38 - - [31/Jan/2010:11:03:00 +0200] "GET /browse/download_model/717 HTTP/1.1" 200 30442 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 161 | 66.249.65.38 - - [31/Jan/2010:11:28:14 +0200] "GET /browse/download_model/751 HTTP/1.1" 200 7485 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 162 | 66.249.65.38 - - [31/Jan/2010:11:53:26 +0200] "GET /browse/download_model/2549 HTTP/1.1" 200 5052 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 163 | 66.249.65.38 - - [31/Jan/2010:12:18:38 +0200] "GET /browse/download_model/2650 HTTP/1.1" 200 57739 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 164 | 66.249.65.38 - - [31/Jan/2010:12:43:41 +0200] "GET /browse/download_model/729 HTTP/1.1" 200 13146 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 165 | 66.249.65.38 - - [31/Jan/2010:12:45:28 +0200] "GET /browse/browse_applet_tab/2593 HTTP/1.1" 200 10305 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 166 | 66.249.65.38 - - [31/Jan/2010:13:09:00 +0200] "GET /browse/download_model/814 HTTP/1.1" 200 3066 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 167 | 66.249.65.38 - - [31/Jan/2010:13:34:05 +0200] "GET /browse/download_model/2629 HTTP/1.1" 200 62903 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 168 | 66.249.65.38 - - [31/Jan/2010:13:59:27 +0200] "GET /browse/download_model/2644 HTTP/1.1" 200 12122 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 169 | 66.249.65.38 - - [31/Jan/2010:14:24:30 +0200] "GET /browse/download_model/804 HTTP/1.1" 200 4085 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 170 | 67.195.112.35 - - [31/Jan/2010:14:45:44 +0200] "GET /robots.txt HTTP/1.0" 200 99 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" 171 | 67.195.112.35 - - [31/Jan/2010:14:45:44 +0200] "GET /account/new HTTP/1.0" 200 2226 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 172 | 67.195.112.35 - - [31/Jan/2010:14:45:47 +0200] "GET /stylesheets/nlcommons.css?1264605648 HTTP/1.0" 200 1179 "http://modelingcommons.org/account/new" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 173 | 67.195.112.35 - - [31/Jan/2010:14:45:50 +0200] "GET /stylesheets/browse.css?1264605648 HTTP/1.0" 200 422 "http://modelingcommons.org/account/new" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 174 | 67.195.112.35 - - [31/Jan/2010:14:45:52 +0200] "GET /stylesheets/jquery.autocomplete.css?1264605648 HTTP/1.0" 200 447 "http://modelingcommons.org/account/new" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 175 | 67.195.112.35 - - [31/Jan/2010:14:45:55 +0200] "GET /stylesheets/themes/nlcommons/ui.all.css?1264605648 HTTP/1.0" 200 52 "http://modelingcommons.org/account/new" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 176 | 67.195.112.35 - - [31/Jan/2010:14:45:57 +0200] "GET /stylesheets/themes/nlcommons/ui.theme.css HTTP/1.0" 200 2862 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.all.css?1264605648" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 177 | 67.195.112.35 - - [31/Jan/2010:14:45:57 +0200] "GET /stylesheets/themes/nlcommons/ui.base.css HTTP/1.0" 200 111 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.all.css?1264605648" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 178 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.slider.css HTTP/1.0" 200 318 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 179 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.core.css HTTP/1.0" 200 624 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 180 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.tabs.css HTTP/1.0" 200 414 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 181 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.accordion.css HTTP/1.0" 200 295 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 182 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.dialog.css HTTP/1.0" 200 442 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 183 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.resizable.css HTTP/1.0" 200 307 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 184 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.datepicker.css HTTP/1.0" 200 965 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 185 | 67.195.112.35 - - [31/Jan/2010:14:45:59 +0200] "GET /stylesheets/themes/nlcommons/ui.progressbar.css HTTP/1.0" 200 114 "http://modelingcommons.org/stylesheets/themes/nlcommons/ui.base.css" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)" 186 | 66.249.65.38 - - [31/Jan/2010:14:49:40 +0200] "GET /browse/download_model/1420 HTTP/1.1" 200 73293 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 187 | 65.55.207.50 - - [31/Jan/2010:15:07:49 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 188 | 65.55.207.50 - - [31/Jan/2010:15:09:06 +0200] "GET / HTTP/1.1" 302 109 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 189 | 65.55.207.50 - - [31/Jan/2010:15:09:14 +0200] "GET /account/login HTTP/1.1" 200 1935 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 190 | 66.249.65.38 - - [31/Jan/2010:15:14:55 +0200] "GET /browse/download_model/766 HTTP/1.1" 200 10923 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 191 | 66.249.65.38 - - [31/Jan/2010:15:40:01 +0200] "GET /browse/download_model/756 HTTP/1.1" 200 4632 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 192 | 66.249.65.38 - - [31/Jan/2010:16:05:28 +0200] "GET /browse/download_model/757 HTTP/1.1" 200 11079 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 193 | 66.249.65.38 - - [31/Jan/2010:16:30:36 +0200] "GET /browse/download_model/725 HTTP/1.1" 200 16082 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 194 | 66.249.65.38 - - [31/Jan/2010:16:55:37 +0200] "GET /browse/download_model/2473 HTTP/1.1" 200 211110 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 195 | 66.249.65.38 - - [31/Jan/2010:17:20:49 +0200] "GET /browse/download_model/1510 HTTP/1.1" 200 35814 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 196 | 65.55.215.75 - - [31/Jan/2010:17:39:03 +0200] "GET /robots.txt HTTP/1.1" 200 99 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 197 | 65.55.215.75 - - [31/Jan/2010:17:40:02 +0200] "GET /browse/list_models HTTP/1.1" 304 - "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" 198 | 66.249.65.38 - - [31/Jan/2010:17:46:08 +0200] "GET /browse/download_model/802 HTTP/1.1" 200 4800 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 199 | 66.249.65.38 - - [31/Jan/2010:18:11:17 +0200] "GET /browse/download_model/2194 HTTP/1.1" 200 11380 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 200 | 66.249.65.38 - - [31/Jan/2010:18:36:25 +0200] "GET /browse/download_model/1572 HTTP/1.1" 200 10239 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 201 | 66.249.65.38 - - [31/Jan/2010:19:01:55 +0200] "GET /browse/download_model/1806 HTTP/1.1" 200 12739 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 202 | 66.249.65.38 - - [31/Jan/2010:19:26:45 +0200] "GET /browse/download_model/930 HTTP/1.1" 200 8271 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 203 | 66.249.65.38 - - [31/Jan/2010:19:52:00 +0200] "GET /browse/download_model/2041 HTTP/1.1" 200 18891 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 204 | 66.249.65.38 - - [31/Jan/2010:20:17:07 +0200] "GET /browse/download_model/1800 HTTP/1.1" 200 14802 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 205 | 66.249.65.38 - - [31/Jan/2010:20:42:19 +0200] "GET /browse/one_node/1613 HTTP/1.1" 200 27080 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 206 | 66.249.65.38 - - [31/Jan/2010:21:08:00 +0200] "GET /browse/one_node/1892 HTTP/1.1" 200 1296 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 207 | -------------------------------------------------------------------------------- /mymod.py: -------------------------------------------------------------------------------- 1 | if __name__ == '__main__': 2 | print(f'Hello from the top of {__name__}!') 3 | 4 | x = 100 5 | 6 | y = [10, 20, 30] 7 | 8 | def hello(name): 9 | return f'Hello, {name}!' 10 | 11 | if __name__ == '__main__': 12 | print(f'Hello from the bottom of {__name__}!') 13 | 14 | -------------------------------------------------------------------------------- /nums.txt: -------------------------------------------------------------------------------- 1 | 5 2 | 10 3 | 20 4 | 3 5 | 20 6 | 7 | 25 8 | -------------------------------------------------------------------------------- /reuven-testfile.txt: -------------------------------------------------------------------------------- 1 | abcd -------------------------------------------------------------------------------- /shoe-data.txt: -------------------------------------------------------------------------------- 1 | Adidas orange 43 2 | Nike black 41 3 | Adidas black 39 4 | New Balance pink 41 5 | Nike white 44 6 | New Balance orange 38 7 | Nike pink 44 8 | Adidas pink 44 9 | New Balance orange 39 10 | New Balance black 43 11 | New Balance orange 44 12 | Nike black 41 13 | Adidas orange 37 14 | Adidas black 38 15 | Adidas pink 41 16 | Adidas white 36 17 | Adidas orange 36 18 | Nike pink 41 19 | Adidas pink 35 20 | New Balance orange 37 21 | Nike pink 43 22 | Nike black 43 23 | Nike black 42 24 | Nike black 35 25 | Adidas black 41 26 | New Balance pink 40 27 | Adidas white 35 28 | New Balance pink 41 29 | New Balance orange 41 30 | Adidas orange 40 31 | New Balance orange 40 32 | New Balance white 44 33 | New Balance pink 40 34 | Nike black 43 35 | Nike pink 36 36 | New Balance white 39 37 | Nike black 42 38 | Adidas black 41 39 | New Balance orange 40 40 | New Balance black 40 41 | Nike white 37 42 | Adidas black 39 43 | Adidas black 40 44 | Adidas orange 38 45 | New Balance orange 39 46 | Nike black 35 47 | Adidas white 39 48 | Nike white 37 49 | Adidas orange 37 50 | Adidas pink 35 51 | New Balance orange 41 52 | Nike pink 44 53 | Nike pink 38 54 | Adidas black 39 55 | New Balance white 35 56 | Nike pink 40 57 | Nike white 44 58 | Nike orange 38 59 | Adidas orange 42 60 | New Balance orange 43 61 | Adidas pink 39 62 | Adidas pink 41 63 | Adidas pink 39 64 | Nike white 37 65 | Nike orange 38 66 | Adidas orange 39 67 | Nike pink 40 68 | Adidas white 36 69 | Nike orange 40 70 | New Balance pink 40 71 | New Balance black 40 72 | New Balance pink 40 73 | Adidas pink 41 74 | Nike pink 40 75 | Nike black 41 76 | Nike black 39 77 | New Balance white 38 78 | Adidas black 41 79 | Nike orange 36 80 | Nike black 38 81 | New Balance black 40 82 | New Balance pink 40 83 | Adidas black 42 84 | Adidas white 40 85 | New Balance orange 38 86 | Nike pink 41 87 | Adidas orange 37 88 | Nike black 44 89 | Adidas pink 36 90 | Adidas white 35 91 | Nike black 38 92 | Nike pink 42 93 | New Balance black 43 94 | Nike white 38 95 | New Balance pink 39 96 | Nike orange 39 97 | New Balance orange 40 98 | New Balance white 44 99 | Adidas black 42 100 | Nike black 35 101 | -------------------------------------------------------------------------------- /wcfile.txt: -------------------------------------------------------------------------------- 1 | This is a test file. 2 | 3 | It contains 28 words and 20 different words. 4 | 5 | It also contains 165 characters. 6 | 7 | It also contains 11 lines. 8 | 9 | It is also self-referential. 10 | 11 | Wow! 12 | --------------------------------------------------------------------------------