├── .gitignore ├── Part 1 - Python Basics for Agent Based Modelling.ipynb ├── Part 2 - A Simple Agent Based Model in Python.ipynb ├── Part 3 - A slightly More Complex Agent Based Model.ipynb └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | MANIFEST 2 | build 3 | dist 4 | _build 5 | docs/man/*.gz 6 | docs/source/api/generated 7 | docs/source/config.rst 8 | docs/gh-pages 9 | notebook/i18n/*/LC_MESSAGES/*.mo 10 | notebook/i18n/*/LC_MESSAGES/nbjs.json 11 | notebook/static/components 12 | notebook/static/style/*.min.css* 13 | notebook/static/*/js/built/ 14 | notebook/static/*/built/ 15 | notebook/static/built/ 16 | notebook/static/*/js/main.min.js* 17 | notebook/static/lab/*bundle.js 18 | node_modules 19 | *.py[co] 20 | __pycache__ 21 | *.egg-info 22 | *~ 23 | *.bak 24 | .ipynb_checkpoints 25 | .tox 26 | .DS_Store 27 | \#*# 28 | .#* 29 | .coverage 30 | src 31 | 32 | *.swp 33 | *.map 34 | .idea/ 35 | Read the Docs 36 | config.rst 37 | 38 | /.project 39 | /.pydevproject -------------------------------------------------------------------------------- /Part 1 - Python Basics for Agent Based Modelling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Part 1: Python Basics for Agent-Based Modelling\n", 8 | "\n", 9 | "##### Authors: Bill Thompson (biltho@mpi.nl) and Limor Raviv (limor.raviv@mpi.nl) \n", 10 | "Please let us know if you have any comments, suggestions or questions regarding this notebook.\n", 11 | "\n", 12 | "---------------\n", 13 | "\n", 14 | "## Summary\n", 15 | "In this first tutorial, we will introduce the Python commands needed for basic agent-based modelling: lists, loops, conditions and functions.\n", 16 | "Hopefully, you have managed to install Anaconda and open this file as an interactive jupyter notebook, and you can use Shift+Enter to run each code line. You can change the code yourself by editing each cell. A good exercise would be to run each cell first, and then add your own modifications to check that you've understood. \n", 17 | "\n", 18 | "-------------- \n", 19 | "\n", 20 | "\n", 21 | "### 1. Lists\n", 22 | "The first thing you need to know is how to make lists.\n", 23 | "\n", 24 | "Lists are created using square brackets. You can use lists to store many types of value: from numbers, to strings, to other lists. In fact, we will often use lists of lists to create our populations of agents." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "First, let's make an empty list and print it:" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 1, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "[]\n" 44 | ] 45 | } 46 | ], 47 | "source": [ 48 | "emptylist = []\n", 49 | "\n", 50 | "print(emptylist)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "Now, let's make some lists with numbers!" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "[1, 2, 3]\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "# Make a list of integers\n", 75 | "\n", 76 | "ints = [1,2,3]\n", 77 | "\n", 78 | "print(ints)\n" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 3, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "[1.0, 2.0, 3]\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "# Make a list of floats by adding dots after the numbers\n", 96 | "# To see the crucial difference between floats and intgers, try dividing 5 / 2 and 5. / 2.\n", 97 | "\n", 98 | "nums = [1.,2.,3]\n", 99 | "\n", 100 | "print(nums)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "You can also make a list of numbers using \"range\"." 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "NOTE: Python starts counting from zero, not one!" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "See what this means for yourself by trying to generate a list with a range of 10." 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "name": "stdout", 131 | "output_type": "stream", 132 | "text": [ 133 | "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n" 134 | ] 135 | } 136 | ], 137 | "source": [ 138 | "# Make a with a range of 10 items - but pay attention!\n", 139 | "\n", 140 | "nums2 = range(10)\n", 141 | "\n", 142 | "print(list(nums2))" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "You can also make lists of random numbers within a given range using a package called \"random\":" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 5, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "[15, -48, -32, -36, -50, 7, 1, -42, -6, 39]\n" 162 | ] 163 | } 164 | ], 165 | "source": [ 166 | "import random \n", 167 | "\n", 168 | "length = 10\n", 169 | "\n", 170 | "randomlist = random.sample(range(-50, 50), length)\n", 171 | "\n", 172 | "print(randomlist)" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "Of course, lists don't have to contain numbers. You can also create lists of strings:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 6, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "['my', 'cat', 'is', 'fluffy']\n" 192 | ] 193 | } 194 | ], 195 | "source": [ 196 | "# Make a list of words\n", 197 | "\n", 198 | "mywordlist = ['my', 'cat', 'is', 'fluffy']\n", 199 | "\n", 200 | "print(mywordlist)" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "Or lists of lists:" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 7, 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "name": "stdout", 217 | "output_type": "stream", 218 | "text": [ 219 | "[['my', 'cat', 'is', 'fluffy'], [1, 2, 3], ['dog', 'fish'], range(0, 2)]\n" 220 | ] 221 | } 222 | ], 223 | "source": [ 224 | "# Create a list of lists\n", 225 | "\n", 226 | "superlist = [mywordlist, ints, ['dog', 'fish'], range(2)]\n", 227 | "\n", 228 | "print(superlist)" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "You can also combine lists and add more values to them. Note that without assigning the output to a variable, it doesn't save the changes to the original list." 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 8, 241 | "metadata": {}, 242 | "outputs": [ 243 | { 244 | "name": "stdout", 245 | "output_type": "stream", 246 | "text": [ 247 | "['my', 'cat', 'is', 'fluffy', 1, 2, 3]\n" 248 | ] 249 | } 250 | ], 251 | "source": [ 252 | "# Combine lists and save to a new list\n", 253 | "\n", 254 | "mynewlist = mywordlist + ints\n", 255 | "\n", 256 | "print(mynewlist)" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 9, 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "data": { 266 | "text/plain": [ 267 | "['Jane', 'said', 'my', 'cat', 'is', 'fluffy']" 268 | ] 269 | }, 270 | "execution_count": 9, 271 | "metadata": {}, 272 | "output_type": "execute_result" 273 | } 274 | ], 275 | "source": [ 276 | "# Add values to the start of a list without changing the list or saving the output\n", 277 | "\n", 278 | "['Jane', 'said'] + mywordlist" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 10, 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "data": { 288 | "text/plain": [ 289 | "['my', 'cat', 'is', 'fluffy', 'too']" 290 | ] 291 | }, 292 | "execution_count": 10, 293 | "metadata": {}, 294 | "output_type": "execute_result" 295 | } 296 | ], 297 | "source": [ 298 | "# Add values to the end of a list (again, without saving the changes)\n", 299 | "\n", 300 | "mywordlist + ['too']" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 11, 306 | "metadata": {}, 307 | "outputs": [ 308 | { 309 | "name": "stdout", 310 | "output_type": "stream", 311 | "text": [ 312 | "['Jane', 'said', 'my', 'cat', 'is', 'fluffy']\n" 313 | ] 314 | } 315 | ], 316 | "source": [ 317 | "# Add values to the start of a list and save changes\n", 318 | "#\n", 319 | "mysecondwordlist= ['Jane', 'said'] + mywordlist\n", 320 | "\n", 321 | "print(mysecondwordlist)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 12, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "name": "stdout", 331 | "output_type": "stream", 332 | "text": [ 333 | "['my', 'cat', 'is', 'fluffy', 1, 2, 3, 4, 'This works!']\n" 334 | ] 335 | } 336 | ], 337 | "source": [ 338 | "# Use \".append\" to add items to the end of a list and save changes\n", 339 | "\n", 340 | "mynewlist.append(4)\n", 341 | "mynewlist.append('This works!')\n", 342 | "\n", 343 | "print(mynewlist)" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "If you want to retrieve a specific item from a list, you can use its index. " 351 | ] 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "metadata": {}, 356 | "source": [ 357 | "But remember, Python starts counting from zero, not one!" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "metadata": {}, 363 | "source": [ 364 | "This means that for a list of length *l*, the first value in the list is stored in position *0*, and the last values is stored in position *l-1*." 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 13, 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "name": "stdout", 374 | "output_type": "stream", 375 | "text": [ 376 | "['my', 'cat', 'is', 'fluffy']\n", 377 | "This list is of length 4\n", 378 | "Cell 0 contains the word: my\n", 379 | "Cell 1 contains the word: cat\n", 380 | "Cell 2 contains the word: is\n", 381 | "Cell 3 contains the word: fluffy\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "# Check the indexing of a list\n", 387 | "print(mywordlist)\n", 388 | "print('This list is of length', len(mywordlist))\n", 389 | "print('Cell 0 contains the word:', mywordlist[0])\n", 390 | "print('Cell 1 contains the word:', mywordlist[1])\n", 391 | "print('Cell 2 contains the word:', mywordlist[2])\n", 392 | "print('Cell 3 contains the word:', mywordlist[3])" 393 | ] 394 | }, 395 | { 396 | "cell_type": "code", 397 | "execution_count": 14, 398 | "metadata": {}, 399 | "outputs": [ 400 | { 401 | "name": "stdout", 402 | "output_type": "stream", 403 | "text": [ 404 | "['your', 'cat', 'is', 'fluffy']\n" 405 | ] 406 | } 407 | ], 408 | "source": [ 409 | "# Change a specific value in a list using its index\n", 410 | "\n", 411 | "mywordlist[0] = 'your'\n", 412 | "\n", 413 | "print(mywordlist)" 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "metadata": {}, 419 | "source": [ 420 | "## 2. Loops\n", 421 | "The second thing you need to know is how to create For loops, with the same action repeated multiple time on different values. " 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "Importantly, you need to use a colon at the end of every \"for\" statement, and use indentation to indicate which statments belong in the loop." 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "metadata": {}, 434 | "source": [ 435 | "Here are some basic exmaples:" 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 15, 441 | "metadata": {}, 442 | "outputs": [ 443 | { 444 | "name": "stdout", 445 | "output_type": "stream", 446 | "text": [ 447 | "0\n", 448 | "1\n", 449 | "2\n", 450 | "3\n", 451 | "4\n" 452 | ] 453 | } 454 | ], 455 | "source": [ 456 | "# Make a loop that goes through all values in a given list and prints them\n", 457 | "\n", 458 | "for i in range(5):\n", 459 | " print(i)" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 16, 465 | "metadata": {}, 466 | "outputs": [ 467 | { 468 | "name": "stdout", 469 | "output_type": "stream", 470 | "text": [ 471 | "10\n", 472 | "11\n", 473 | "12\n", 474 | "13\n", 475 | "14\n" 476 | ] 477 | } 478 | ], 479 | "source": [ 480 | "# Make a loop that adds 10 to every number in a given range and prints it\n", 481 | "\n", 482 | "for i in range(5):\n", 483 | " print(i+10)" 484 | ] 485 | }, 486 | { 487 | "cell_type": "markdown", 488 | "metadata": {}, 489 | "source": [ 490 | "You can loop over many things, as long as they have some values in them. For example:" 491 | ] 492 | }, 493 | { 494 | "cell_type": "code", 495 | "execution_count": 17, 496 | "metadata": {}, 497 | "outputs": [ 498 | { 499 | "name": "stdout", 500 | "output_type": "stream", 501 | "text": [ 502 | "1.5\n", 503 | "4.0\n", 504 | "5.5\n", 505 | "11.0\n" 506 | ] 507 | } 508 | ], 509 | "source": [ 510 | "# Looping over a list of numbers\n", 511 | "\n", 512 | "for i in [3.,8.,11.,22.]:\n", 513 | " print(i/2)" 514 | ] 515 | }, 516 | { 517 | "cell_type": "code", 518 | "execution_count": 18, 519 | "metadata": {}, 520 | "outputs": [ 521 | { 522 | "name": "stdout", 523 | "output_type": "stream", 524 | "text": [ 525 | "Jane\n", 526 | "said\n", 527 | "my\n", 528 | "cat\n", 529 | "is\n", 530 | "fluffy\n" 531 | ] 532 | } 533 | ], 534 | "source": [ 535 | "# Looping over a list of numbers in a given size\n", 536 | "\n", 537 | "for i in range(len(mysecondwordlist)):\n", 538 | " print(mysecondwordlist[i])" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 19, 544 | "metadata": {}, 545 | "outputs": [ 546 | { 547 | "name": "stdout", 548 | "output_type": "stream", 549 | "text": [ 550 | "Jane\n", 551 | "said\n", 552 | "my\n", 553 | "cat\n", 554 | "is\n", 555 | "fluffy\n" 556 | ] 557 | } 558 | ], 559 | "source": [ 560 | "# Looping over a list of strings\n", 561 | "\n", 562 | "for word in mysecondwordlist:\n", 563 | " print(word)" 564 | ] 565 | }, 566 | { 567 | "cell_type": "markdown", 568 | "metadata": {}, 569 | "source": [ 570 | "And we can use loops to create and update lists:" 571 | ] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": 20, 576 | "metadata": {}, 577 | "outputs": [ 578 | { 579 | "name": "stdout", 580 | "output_type": "stream", 581 | "text": [ 582 | "[0, 5, 10, 15]\n" 583 | ] 584 | } 585 | ], 586 | "source": [ 587 | "# Make a loop that adds values to a list\n", 588 | "\n", 589 | "looplist = [] # if you don't have an existing list already, you'll need to define an empty list first \n", 590 | "\n", 591 | "for i in range(4):\n", 592 | " looplist.append(i*5)\n", 593 | "\n", 594 | "print(looplist)" 595 | ] 596 | }, 597 | { 598 | "cell_type": "code", 599 | "execution_count": 21, 600 | "metadata": {}, 601 | "outputs": [ 602 | { 603 | "name": "stdout", 604 | "output_type": "stream", 605 | "text": [ 606 | "[0, 500, 1000, 1500, 'your', 'cat', 'is', 'fluffy']\n" 607 | ] 608 | } 609 | ], 610 | "source": [ 611 | "# Make another loop that multiples the numbers by 100 and adds the corresponding string from a different list\n", 612 | "\n", 613 | "for i in range(len(looplist)):\n", 614 | " looplist[i] = looplist[i] * 100\n", 615 | " looplist.append(mywordlist[i])\n", 616 | "\n", 617 | "print(looplist)" 618 | ] 619 | }, 620 | { 621 | "cell_type": "markdown", 622 | "metadata": {}, 623 | "source": [ 624 | "## 3. Conditions\n", 625 | "The third thing you need to know is how to create If statments, so that different actions can be taken in different conditions." 626 | ] 627 | }, 628 | { 629 | "cell_type": "markdown", 630 | "metadata": {}, 631 | "source": [ 632 | "Here you'll also need to use a colon at the end of every if/else statement, and use indentation to indicate which statments belong in the condition." 633 | ] 634 | }, 635 | { 636 | "cell_type": "markdown", 637 | "metadata": {}, 638 | "source": [ 639 | "First, you can make a basic statment with one condition:" 640 | ] 641 | }, 642 | { 643 | "cell_type": "code", 644 | "execution_count": 22, 645 | "metadata": {}, 646 | "outputs": [ 647 | { 648 | "name": "stdout", 649 | "output_type": "stream", 650 | "text": [ 651 | "x is bigger than 3\n" 652 | ] 653 | } 654 | ], 655 | "source": [ 656 | "x = 4\n", 657 | "\n", 658 | "if x > 3:\n", 659 | " print(\"x is bigger than 3\")" 660 | ] 661 | }, 662 | { 663 | "cell_type": "markdown", 664 | "metadata": {}, 665 | "source": [ 666 | "If you want to have a different action taken when this condition is false, you can use \"else\":" 667 | ] 668 | }, 669 | { 670 | "cell_type": "code", 671 | "execution_count": 23, 672 | "metadata": {}, 673 | "outputs": [ 674 | { 675 | "name": "stdout", 676 | "output_type": "stream", 677 | "text": [ 678 | "y is smaller than 3\n" 679 | ] 680 | } 681 | ], 682 | "source": [ 683 | "y = 2\n", 684 | "\n", 685 | "if y > 3:\n", 686 | " print(\"y is bigger than 3\")\n", 687 | "else:\n", 688 | " print(\"y is smaller than 3\")" 689 | ] 690 | }, 691 | { 692 | "cell_type": "markdown", 693 | "metadata": {}, 694 | "source": [ 695 | "For more conditions, use \"elif\" (short for 'else if'):" 696 | ] 697 | }, 698 | { 699 | "cell_type": "code", 700 | "execution_count": 24, 701 | "metadata": {}, 702 | "outputs": [ 703 | { 704 | "name": "stdout", 705 | "output_type": "stream", 706 | "text": [ 707 | "x equals 4\n" 708 | ] 709 | } 710 | ], 711 | "source": [ 712 | "# Now, let's put more conditions in there\n", 713 | "\n", 714 | "x = 4\n", 715 | "\n", 716 | "if x > 7:\n", 717 | " print(\"x is bigger than 7\")\n", 718 | "elif x > 6:\n", 719 | " print(\"x is bigger than 6\")\n", 720 | "elif x > 5:\n", 721 | " print(\"x is bigger than 5\")\n", 722 | "elif x == 4:\n", 723 | " print(\"x equals 4\")\n", 724 | "else:\n", 725 | " print(\"x is smaller than 4\")" 726 | ] 727 | }, 728 | { 729 | "cell_type": "markdown", 730 | "metadata": {}, 731 | "source": [ 732 | "Of course, you can combine loops and if statments to do some more intersting things:" 733 | ] 734 | }, 735 | { 736 | "cell_type": "code", 737 | "execution_count": 25, 738 | "metadata": {}, 739 | "outputs": [ 740 | { 741 | "name": "stdout", 742 | "output_type": "stream", 743 | "text": [ 744 | "the number 0 is smaller than 5\n", 745 | "the number 1 is smaller than 5\n", 746 | "the number 2 is smaller than 5\n", 747 | "the number 3 is smaller than 5\n", 748 | "the number 4 is smaller than 5\n", 749 | "the number 5 equals 5 (sanity check!)\n", 750 | "the number 6 is bigger than 5\n", 751 | "the number 7 is bigger than 5\n", 752 | "the number 8 is bigger than 5\n", 753 | "the number 9 is bigger than 5\n" 754 | ] 755 | } 756 | ], 757 | "source": [ 758 | "for number in range(10):\n", 759 | " if number < 5:\n", 760 | " print('the number', number, 'is smaller than 5')\n", 761 | " elif number==5:\n", 762 | " print('the number', number, 'equals 5 (sanity check!)')\n", 763 | " else:\n", 764 | " print('the number', number, 'is bigger than 5')" 765 | ] 766 | }, 767 | { 768 | "cell_type": "markdown", 769 | "metadata": {}, 770 | "source": [ 771 | "Like only apply operations on certain types of values in the list:" 772 | ] 773 | }, 774 | { 775 | "cell_type": "code", 776 | "execution_count": 26, 777 | "metadata": {}, 778 | "outputs": [ 779 | { 780 | "name": "stdout", 781 | "output_type": "stream", 782 | "text": [ 783 | "my\n", 784 | "cat\n", 785 | "is\n", 786 | "fluffy\n", 787 | "... this is not a word\n", 788 | "... this is not a word\n", 789 | "... this is not a word\n", 790 | "... this is not a word\n", 791 | "This works!\n" 792 | ] 793 | } 794 | ], 795 | "source": [ 796 | "for word in mynewlist:\n", 797 | " if type(word)== int:\n", 798 | " print('... this is not a word')\n", 799 | " else:\n", 800 | " print(word)" 801 | ] 802 | }, 803 | { 804 | "cell_type": "markdown", 805 | "metadata": {}, 806 | "source": [ 807 | "## 4. Functions\n", 808 | "The last thing you need to know is how to write and call functions." 809 | ] 810 | }, 811 | { 812 | "cell_type": "markdown", 813 | "metadata": {}, 814 | "source": [ 815 | "Functions are created using \"def\", and typically return some value. " 816 | ] 817 | }, 818 | { 819 | "cell_type": "markdown", 820 | "metadata": {}, 821 | "source": [ 822 | "Here are some basic examples to help you get started!" 823 | ] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "execution_count": 27, 828 | "metadata": {}, 829 | "outputs": [ 830 | { 831 | "data": { 832 | "text/plain": [ 833 | "100" 834 | ] 835 | }, 836 | "execution_count": 27, 837 | "metadata": {}, 838 | "output_type": "execute_result" 839 | } 840 | ], 841 | "source": [ 842 | "# Create a function called \"func\" that adds 1 to a given number i\n", 843 | "\n", 844 | "def func(i):\n", 845 | " return i + 1\n", 846 | "\n", 847 | "# Call the function on a specific number\n", 848 | "\n", 849 | "func(99)" 850 | ] 851 | }, 852 | { 853 | "cell_type": "code", 854 | "execution_count": 28, 855 | "metadata": {}, 856 | "outputs": [ 857 | { 858 | "data": { 859 | "text/plain": [ 860 | "[2, 4, 6, 8]" 861 | ] 862 | }, 863 | "execution_count": 28, 864 | "metadata": {}, 865 | "output_type": "execute_result" 866 | } 867 | ], 868 | "source": [ 869 | "# Create a function called \"myfunc\" that multiplies a list of numbers by 2\n", 870 | "\n", 871 | "def myfunc(numlist):\n", 872 | " newvalues = []\n", 873 | " for i in numlist:\n", 874 | " newvalues.append(i*2) \n", 875 | " return newvalues\n", 876 | "\n", 877 | "# Call the function on a myfuspecific list\n", 878 | "\n", 879 | "myfunc([1,2,3,4])" 880 | ] 881 | }, 882 | { 883 | "cell_type": "code", 884 | "execution_count": 29, 885 | "metadata": {}, 886 | "outputs": [ 887 | { 888 | "data": { 889 | "text/plain": [ 890 | "'cat'" 891 | ] 892 | }, 893 | "execution_count": 29, 894 | "metadata": {}, 895 | "output_type": "execute_result" 896 | } 897 | ], 898 | "source": [ 899 | "# Define a function called \"listfunc\" that returns the value in the third cell of any list\n", 900 | "\n", 901 | "def listfunc(mylist):\n", 902 | " if len(mylist) >= 4:\n", 903 | " return mylist[3]\n", 904 | " else:\n", 905 | " return 'your list is not long enough'\n", 906 | " \n", 907 | "\n", 908 | "# Call the function on one of our lists\n", 909 | "\n", 910 | "listfunc(mysecondwordlist)" 911 | ] 912 | }, 913 | { 914 | "cell_type": "markdown", 915 | "metadata": {}, 916 | "source": [ 917 | "You can also save the function's output to a variable:" 918 | ] 919 | }, 920 | { 921 | "cell_type": "code", 922 | "execution_count": 30, 923 | "metadata": {}, 924 | "outputs": [ 925 | { 926 | "name": "stdout", 927 | "output_type": "stream", 928 | "text": [ 929 | "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n" 930 | ] 931 | } 932 | ], 933 | "source": [ 934 | "results = myfunc(range(10))\n", 935 | "\n", 936 | "print(results)" 937 | ] 938 | }, 939 | { 940 | "cell_type": "markdown", 941 | "metadata": {}, 942 | "source": [ 943 | "If your function has more than one returned output, you can save both using a comma:" 944 | ] 945 | }, 946 | { 947 | "cell_type": "code", 948 | "execution_count": 31, 949 | "metadata": {}, 950 | "outputs": [ 951 | { 952 | "name": "stdout", 953 | "output_type": "stream", 954 | "text": [ 955 | "[5, 10, 15, 20]\n", 956 | "12.5\n" 957 | ] 958 | } 959 | ], 960 | "source": [ 961 | "# Create a function called \"twofunc\" that gives back two things\n", 962 | "\n", 963 | "def twofunc(anotherlist):\n", 964 | " values1 = []\n", 965 | " for i in anotherlist:\n", 966 | " values1.append(i*5) \n", 967 | " mean = sum(values1)/len(values1)\n", 968 | " return values1, mean\n", 969 | "\n", 970 | "# Call the function on a myfuspecific list\n", 971 | "\n", 972 | "output1, output2 = twofunc([1,2,3,4])\n", 973 | "\n", 974 | "print(output1)\n", 975 | "print(output2)" 976 | ] 977 | }, 978 | { 979 | "cell_type": "markdown", 980 | "metadata": {}, 981 | "source": [ 982 | "Excellent! Now you're really ready to start modelling!" 983 | ] 984 | } 985 | ], 986 | "metadata": { 987 | "kernelspec": { 988 | "display_name": "Python 3", 989 | "language": "python", 990 | "name": "python3" 991 | }, 992 | "language_info": { 993 | "codemirror_mode": { 994 | "name": "ipython", 995 | "version": 3 996 | }, 997 | "file_extension": ".py", 998 | "mimetype": "text/x-python", 999 | "name": "python", 1000 | "nbconvert_exporter": "python", 1001 | "pygments_lexer": "ipython3", 1002 | "version": "3.4.3" 1003 | } 1004 | }, 1005 | "nbformat": 4, 1006 | "nbformat_minor": 2 1007 | } 1008 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tutorial_Agent_Based_Models 2 | A Short Tutorial on Agent Based Modeling in Python 3 | 4 | Authors: Limor Raviv and Bill Thompson 5 | 6 | *Updated: 07.03.2018* 7 | 8 | ## Summary 9 | 10 | This repository contains three Jupyter notebooks offering a short tutorial on agent-based modeling using Python. 11 | They are intended to offer anyone with little or no prior experience with Python the ability to incrementally construct a simple simulation of sound change in a population of agents with different personalities (stubborn or flexible learners). We will try to answer questions like: Has one of the variants spread to the entire community? Does this depend on the community's size and initial structure? How many stubborn people must be present to prevent (or facilitate?) convergence? etc. 12 | 13 | This choice of model and questions reflect our personal theoretical interests: the cultural evolution of language through interaction in populations. However, we hope that the tutorials can also be of use to those who wish to build simulations of completely different topics, by modifying the basic parameters of the model. 14 | 15 | We aim for simplicity in design: agents are represented as simple Python lists whose elements represent their properties; populations are represented as lists of agents; evolution is implemented by looping over members of the population and modifying their properties. It is our hope that these implementational principles can be applied to a broad range of phenomena. In addition, any part of the code can be changed to introduce new features and constraints. 16 | 17 | Please let us know if you have any comments, suggestions or questions regarding this notebook! 18 | 19 | 20 | ## Technical Requirements 21 | 22 | To view the tutorial in the browser, just click on each notebook. For a more interactive experience in which you can fiddle with the code and run the simulations yourself, you can download the tutorial by clicking the green "Clone or Download" button at the top right of this page, and open it as a Jupyter Notebook. 23 | 24 | You'll need [Python](https://www.python.org/downloads/) and [Jupyter](http://jupyter.org) installed to run the notebooks yourself. We recommend using the [Anaconda](https://anaconda.org/anaconda/python) distribution of Python, which already includes everything you need including Jupyter. If you need any help with the installation process, you can check out these two tutorials: for installing Anaconda on [Windows](https://medium.com/@GalarnykMichael/install-python-on-windows-anaconda-c63c7c3d1444) or on a [Mac](https://medium.com/@GalarnykMichael/install-python-on-mac-anaconda-ccd9f2014072). We wrote the tutorial using Python 2.7, so it's probably better to use Python 2.7 to run the notebooks unless you understand the differences between Python versions 2.7 and 3.x. 25 | 26 | For instructions on how to open and use jupyter notebooks, see [this page](http://jupyter.readthedocs.io/en/latest/running.html). 27 | 28 | 29 | ## Notebooks 30 | If you already know Python, jump straight to Part Two. 31 | 32 | ### Part One: 33 | 34 | [notebook here](https://github.com/Limor-Raviv/Tutorial_Agent_Based_Models/blob/master/Part%201%20-%20Python%20Basics%20for%20Agent%20Based%20Modelling.ipynb) 35 | 36 | Part one lays out the Python basics. We hope that this notebook can be a good starting point even with no prior experience of programming, but it is designed to be readable in an afternoon by someone who understands how programming works in general (e.g. can code in another language, like R or Matlab), but doesn't have much experience with Python. 37 | 38 | You'll need to be reasonably comfortable with the material in this notebook to begin building the models in the following sections. 39 | 40 | To open the jupyter notebook, 41 | 42 | ### Part Two: 43 | 44 | [notebook here](https://github.com/Limor-Raviv/Tutorial_Agent_Based_Models/blob/master/Part%202%20-%20A%20Simple%20Agent%20Based%20Model%20in%20Python.ipynb) 45 | 46 | Part two uses the knowledge from part one to build a model of communicating agents with different biases (vowel preferences, personality) step by step. 47 | 48 | By the end of the notebook you'll be running multiple simulations on different conditions, and plot your results to see trends in interactions patterns. 49 | 50 | ### Part Three: 51 | 52 | [notebook here](https://github.com/Limor-Raviv/Tutorial_Agent_Based_Models/blob/master/Part%203%20-%20A%20slightly%20More%20Complex%20Agent%20Based%20Model.ipynb) 53 | 54 | Part three expands on the functions introduced in part two and introduces new features for building a slightly more complex and ecologically valid model of communicating agents. 55 | 56 | 57 | We hope you'll find this tutorial useful, and we'd love to hear from you! 58 | 59 | Contact Us: biltho@mpi.nl // limor.raviv@mpi.nl 60 | 61 | 62 | --------------------------------------------------------------------------------