├── .gitattributes ├── .gitignore ├── LICENSE.md ├── data ├── gitnames.csv ├── students.csv └── submissions.csv ├── doc ├── Makefile └── source │ ├── 0_preface.rst │ ├── 10_further_object-oriented_features.rst │ ├── 1_introduction.rst │ ├── 2_programs_in_files.rst │ ├── 3_objects.rst │ ├── 4_style.rst │ ├── 5_abstract_data_types.rst │ ├── 6_exceptions.rst │ ├── 7_inheritance.rst │ ├── 8_debugging.rst │ ├── 9_trees_and_directed_acyclic_graphs.rst │ ├── _scripts │ ├── animate_entity_nodes.py │ ├── animate_reference_element.py │ ├── animation_tools.py │ └── process_video_list.py │ ├── _static │ ├── Academic_Integrity.pdf │ ├── If_you_have_a_problem.pdf │ ├── imperialmathnotes.sty │ ├── poptitle.sty │ └── video_cover_page.svg │ ├── _themes │ └── finite_element │ │ ├── README │ │ ├── layout.html │ │ ├── static │ │ ├── banner.png │ │ ├── banner.svg │ │ ├── dialog-note.png │ │ ├── dialog-right.png │ │ ├── dialog-seealso.png │ │ ├── dialog-topic.png │ │ ├── dialog-warning.png │ │ ├── dialog-wrong.png │ │ ├── epub.css │ │ ├── feature-item-1.png │ │ ├── featured.css │ │ ├── feed-icon-14x14.gif │ │ ├── fenics-book-icon.png │ │ ├── fenics-web.png │ │ ├── fenics.css_t │ │ ├── fenics.css_t~ │ │ ├── footerbg.png │ │ ├── headerbg.png │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── ie6.css │ │ ├── jquery.latest-commit.js │ │ ├── middlebg.png │ │ ├── neuton-fontfacekit │ │ │ ├── Apache License Version 2.txt │ │ │ ├── Neuton-webfont.eot │ │ │ ├── Neuton-webfont.svg │ │ │ ├── Neuton-webfont.ttf │ │ │ ├── Neuton-webfont.woff │ │ │ ├── demo.html │ │ │ └── stylesheet.css │ │ ├── nobile-fontfacekit │ │ │ ├── SIL Open Font License 1.1.txt │ │ │ ├── demo.html │ │ │ ├── nobile-webfont.eot │ │ │ ├── nobile-webfont.svg │ │ │ ├── nobile-webfont.ttf │ │ │ ├── nobile-webfont.woff │ │ │ ├── nobile_bold-webfont.eot │ │ │ ├── nobile_bold-webfont.svg │ │ │ ├── nobile_bold-webfont.ttf │ │ │ ├── nobile_bold-webfont.woff │ │ │ ├── nobile_bold_italic-webfont.eot │ │ │ ├── nobile_bold_italic-webfont.svg │ │ │ ├── nobile_bold_italic-webfont.ttf │ │ │ ├── nobile_bold_italic-webfont.woff │ │ │ ├── nobile_italic-webfont.eot │ │ │ ├── nobile_italic-webfont.svg │ │ │ ├── nobile_italic-webfont.ttf │ │ │ ├── nobile_italic-webfont.woff │ │ │ └── stylesheet.css │ │ ├── sample-news-image.png │ │ ├── social-buttons.html │ │ ├── transparent.gif │ │ └── unknown.png │ │ └── theme.conf │ ├── a1_help.rst │ ├── a2_git.rst │ ├── conf.py │ ├── cover_text │ ├── example_code.rst │ ├── exercises.rst │ ├── fibonacci.rst │ ├── images │ ├── Imperial.pdf │ ├── blackboard.css │ ├── cover.pdf │ ├── cover.png │ ├── cover.svg │ ├── debug_controls.png │ ├── debug_controls_annotated.pdf │ ├── debug_controls_annotated.svg │ ├── debug_icon.png │ ├── debug_screen.png │ ├── debug_screen_annotated.pdf │ ├── debug_screen_annotated.svg │ ├── dynamic_array.pdf │ ├── dynamic_array.svg │ ├── edstem_issue.png │ ├── git_clone.png │ ├── git_exercise.png │ ├── github_autograding_fail.png │ ├── github_autograding_fail_detail.png │ ├── github_autograding_pass.png │ ├── github_change_branch.png │ ├── github_commit_list.png │ ├── github_diff.png │ ├── github_post_commit.png │ ├── github_template.png │ ├── glider.png │ ├── glider.svg │ ├── glider_1.png │ ├── glider_2.png │ ├── glider_3.png │ ├── glider_flip.png │ ├── glider_gun.png │ ├── glider_h.png │ ├── glider_inserted.png │ ├── glider_r.png │ ├── glider_t.png │ ├── glider_v.png │ ├── linked_list.pdf │ ├── linked_list.svg │ ├── nano-write-out.png │ ├── nano.png │ ├── piazza_editor_choice.png │ ├── piazza_issue.png │ ├── ring_buffer.pdf │ ├── ring_buffer.svg │ ├── stack.pdf │ ├── stack.svg │ ├── vscode_extensions.pdf │ ├── vscode_extensions.svg │ ├── vscode_indent.png │ └── vscode_workspace.png │ ├── index.rst │ ├── installation.rst │ ├── python3_intersphinx │ ├── quiz_material.rst │ ├── refs.bib │ ├── tests_and_exams.rst │ ├── texput.log │ ├── videos.csv │ └── videos.rst ├── example_code ├── __init__.py ├── addable.py ├── euclid.py ├── expression_tools.py ├── graphs.py ├── groups.py ├── groups_abc.py ├── groups_basic.py ├── hello.py ├── linked_list.py ├── polynomial.py ├── shapes.py ├── simple_classes.py ├── square.py └── try_except.py ├── fibonacci ├── __init__.py ├── fibonacci.py └── typesafe_fibonacci.py ├── pyproject.toml ├── scripts ├── oo_convert_classroom ├── oo_doc_dependencies ├── oo_exercise_marks ├── oo_generate_wk9_data ├── oo_install_venv ├── oo_install_venv_win ├── oo_repo_tool ├── oo_test_report └── run_fibonacci.py ├── setup.cfg └── tests ├── test_fibonacci.py ├── test_fibonacci_parametrised.py ├── test_linked_list.py ├── test_numpoly.py └── test_pandas_fail.py /.gitattributes: -------------------------------------------------------------------------------- 1 | Attempt to prevent Windows mucking up line endings. 2 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | .cache 4 | *~ 5 | doc/build/* 6 | .DS_Store 7 | *.egg-info/ 8 | doc/webgit -------------------------------------------------------------------------------- /data/gitnames.csv: -------------------------------------------------------------------------------- 1 | ImperialID,GitHubID 2 | an118,unfermented 3 | kp718,acrobatical 4 | kb518,Kevin-89 5 | cb1618,Carolyn-50 6 | kh518,tossed 7 | lp618,Lucien-4 8 | sp918,Seymour-82 9 | jd1418,Brianza 10 | tc2018,Terry-93 11 | tm1718,fancied 12 | cs918,Carol-93 13 | pz1818,solidarities 14 | hw1618,Heidi-90 15 | et1218,Edward-39 16 | tg1818,Thelma-85 17 | la218,Larry-33 18 | dw1318,dw1318 19 | hm618,portière 20 | jn1318,Jana-42 21 | sk1118,Sheila-30 22 | ae218,ae218 23 | hg1718,Helena-12 24 | jf618,brittanic 25 | mm118,Mary-51 26 | df218,remeant 27 | mj118,Mary-11 28 | ma918,ma918 29 | ak1218,air-cock 30 | da418,da418 31 | cl1718,sewing-press 32 | af1318,af1318 33 | ry1718,glottology 34 | pt518,Petra-74 35 | jd1618,jd1618 36 | se1618,Sarah-62 37 | jk1618,Jacqueline-33 38 | ew1718,ew1718 39 | be1218,bearing 40 | bj1318,Brenda-54 41 | dh1818,enchain 42 | sh618,sh618 43 | dm618,dm618 44 | mg518,Mary-24 45 | kl1318,wrestler 46 | jr1318,jr1318 47 | cl1318,co-lessor 48 | rb918,Robert-6 49 | rm518,rm518 50 | dm1918,Danielle-81 51 | am1118,am1118 52 | if1318,upbrought 53 | jf218,nondiabetic 54 | gu918,Gwendolyn-75 55 | pf1118,hungover 56 | hh918,hh918 57 | jb918,miffy 58 | jp918,raptors 59 | jm1218,rascally 60 | kk418,kk418 61 | dg2018,solar 62 | wb1918,wb1918 63 | ap218,Adam-8 64 | bd1918,Britni-25 65 | lw618,top-lantern 66 | jh118,beavers 67 | ls818,boardwalk 68 | js318,consisting 69 | dw118,monton 70 | fg218,abbreviated 71 | ea418,ea418 72 | rs2018,rs2018 73 | jh318,jh318 74 | dp1118,Diana-50 75 | tl2018,tl2018 76 | kr618,kr618 77 | jb1918,John-83 78 | mt1018,filming 79 | mb118,hanty 80 | rk1118,rk1118 81 | dc218,Debra-34 82 | dp818,dp818 83 | rm218,Robert-33 84 | bk118,azurites 85 | pr2018,dadlike 86 | rf1218,motes 87 | mo418,Morgan-24 88 | rm1518,svengali 89 | wq1118,wq1118 90 | mc618,mc618 91 | jm1718,jm1718 92 | mw918,mw918 93 | es218,Buchner 94 | lb318,lb318 95 | iw818,iw818 96 | jl818,swifter 97 | cl1618,teemingness 98 | nc918,nc918 99 | lv1918,sarcophage 100 | ln1618,medial 101 | ds618,struthiones 102 | dk718,dk718 103 | cg418,Christopher-24 104 | gl818, 105 | ps1518,ps1518 106 | hw618,autohidden 107 | wm1318,squire 108 | ju518,Janice-62 109 | ma2018,Marjorie-16 110 | eb1218,frenemies 111 | rs618,rewild 112 | ja218,Jay-9 113 | mj1418,mj1418 114 | rt618,Rudolph-35 115 | wg418,wg418 116 | sm118,Steven-94 117 | mr818,mr818 118 | cs1618,damosella 119 | sa118,tollbar 120 | jr1418,jr1418 121 | jm1318,palmipeds 122 | lv218,lv218 123 | th1618,Traci-26 124 | bl1818,Bessie-25 125 | fh1018,fh1018 126 | rh1518,delayer 127 | cg918,Christina-92 128 | db1018,adroitness 129 | jg1218,Jose-4 130 | gp1918,Gwenda-15 131 | rc218,rc218 132 | ds1518,Daniel-30 133 | hb1018,untowardly 134 | at318,at318 135 | kj1518,sweater 136 | sy1418,loxitane 137 | lb818,inveiglement 138 | vn1418,Vernon-96 139 | cr1018,Catherine-19 140 | ta118,known 141 | tc918,hostessing 142 | -------------------------------------------------------------------------------- /data/students.csv: -------------------------------------------------------------------------------- 1 | FirstName,Surname,Username 2 | Patrick,Forth,PF1118 3 | Lorene,Vaux,LV1918 4 | Gwendolyn,Ulbrich,GU918 5 | Richard,Mccoy,RM518 6 | Marjorie,Jackson,MJ1418 7 | Morgan,Otter,MO418 8 | Jay,Adams,JA218 9 | Lee,Beltz,LB318 10 | Deanna,Becknell,DB1018 11 | Christina,Gross,CG918 12 | Mary,Merritt,MM118 13 | James,Holmes,JH318 14 | Bobby,Patton,BP1918 15 | Hortense,Worley,HW618 16 | Magaret,Brown,MB118 17 | Gwendolyn,Lichty,GL818 18 | Michelle,Anderson,MA918 19 | Marc,Coleman,MC618 20 | Harold,Birch,HB1018 21 | Carol,Stapleton,CS918 22 | John,Bourbeau,JB918 23 | Adam,Macias,AM1118 24 | Bridget,Edmondson,BE1218 25 | Adam,Parker,AP218 26 | Petra,Turner,PT518 27 | Kari,Palermo,KP718 28 | Christopher,Goodsell,CG418 29 | Kelli,Jones,KJ1518 30 | Jeffrey,Foreman,JF218 31 | Andre,Fields,AF1318 32 | Lindsey,Bourne,LB818 33 | Thomas,Mortensen,TM1718 34 | Rachel,Conroy,RC218 35 | Scott,Alford,SA118 36 | Sarah,Endo,SE1618 37 | Nancy,Corey,NC918 38 | Andrew,Kent,AK1218 39 | Jose,Lawson,JL818 40 | Sheila,Key,SK1118 41 | Robert,Maruschak,RM218 42 | Ida,Faulk,IF1318 43 | Jacob,Rice,JR1318 44 | Edward,Thompson,ET1218 45 | Erick,Rupert,ER1518 46 | Ronald,Smith,RS618 47 | Chris,Losee,CL1618 48 | David,Hensley,DH1818 49 | James,Horner,JH118 50 | Darcie,Flythe,DF218 51 | Elise,Smith,ES218 52 | Debra,Chapin,DC218 53 | Larry,Avalos,LA218 54 | Justin,Micklos,JM1718 55 | Kathleen,Kirkwood,KK1818 56 | Harry,Mendoza,HM618 57 | Robert,Schwartz,RS2018 58 | Don,Graham,DG2018 59 | Traci,Ham,TH1618 60 | John,Smith,JS318 61 | Janet,Ritzman,JR1418 62 | Delores,Posada,DP818 63 | Terry,Alderman,TA118 64 | Raymond,Yates,RY1718 65 | Rudolph,Thompson,RT618 66 | Myong,Rodriguez,MR818 67 | Christine,Lopez,CL1318 68 | Brenda,Johnson,BJ1318 69 | Jessica,Monroe,JM1218 70 | Karl,Layton,KL1318 71 | Jacqueline,Kaauamo,JK1618 72 | Carolyn,Bozeman,CB1618 73 | Helena,Goldfeder,HG1718 74 | Catherine,Ryerson,CR1018 75 | Doris,Micheals,DM618 76 | Seymour,Perez,SP918 77 | Jana,Norton,JN1318 78 | Erica,Williams,EW1718 79 | Heidi,Whitman,HW1618 80 | Terry,Clements,TC2018 81 | Robert,Kelley,RK1118 82 | Freddie,Gandy,FG218 83 | Britni,Drewett,BD1918 84 | Lucien,Powell,LP618 85 | Ida,Wilson,IW818 86 | Linda,Willingham,LW618 87 | Mildred,Weaver,MW918 88 | William,Bolin,WB1918 89 | Karen,Kipp,KK418 90 | Darren,Bell,DB1118 91 | Kelly,Ratzlaff,KR618 92 | Darryl,Atkins,DA418 93 | Philip,Renick,PR2018 94 | Harry,Hebert,HH918 95 | Ronald,Martinez,RM1518 96 | Gwenda,Passmore,GP1918 97 | Mildred,Tartaglia,MT1018 98 | Jerry,Merrick,JM1318 99 | Steven,Merk,SM118 100 | Mary,Garcia,MG518 101 | Danielle,Mcauliffe,DM1918 102 | Josef,Dennis,JD1418 103 | Juan,Davis,JD1618 104 | Benjamin,Klepchick,BK118 105 | Callie,Landry,CL1718 106 | Donna,Winfield,DW1318 107 | John,Baro,JB1918 108 | Donald,Wallace,DW118 109 | Dave,Kroon,DK718 110 | Daniel,Serrano,DS1518 111 | Ted,Willsey,TW518 112 | Amy,Epp,AE218 113 | Randolph,Hardy,RH1518 114 | Thelma,Gifford,TG1818 115 | Walter,Molina,WM1318 116 | Kevin,Bush,KB518 117 | Amanda,Nagy,AN118 118 | Karri,Hughes,KH518 119 | Elizabeth,Bloom,EB1218 120 | Edna,Adams,EA418 121 | William,Gonzalez,WG418 122 | Bessie,Lyster,BL1818 123 | Robert,Burnside,RB918 124 | Kathyrn,Wells,KW2018 125 | Vernon,Niles,VN1418 126 | Marjorie,Schwartz,MS1518 127 | Steven,Howell,SH618 128 | Terry,Camarillo,TC918 129 | Laticia,Vega,LV218 130 | Brian,Jenkins,BJ1418 131 | Donald,Sparks,DS618 132 | Diana,Paquette,DP1118 133 | William,Quinn,WQ1118 134 | Polly,Smith,PS1518 135 | Thelma,Goodin,TG1718 136 | Candace,Sherrell,CS1618 137 | Alejandro,Tarpley,AT318 138 | John,Palacio,JP918 139 | Jose,Freiseis,JF618 140 | Larry,Nelson,LN1618 141 | Shirley,York,SY1418 142 | Rhonda,Fox,RF1218 143 | Larry,Sells,LS818 144 | Timothy,Lombardo,TL2018 145 | Janice,Urda,JU518 146 | Sandra,Wallace,SW1818 147 | Frank,Herndon,FH1018 148 | Pamela,Zody,PZ1818 149 | Jose,Gibson,JG1218 150 | Marjorie,Albright,MA2018 151 | Mary,Jackson,MJ118 152 | -------------------------------------------------------------------------------- /data/submissions.csv: -------------------------------------------------------------------------------- 1 | ,User,SubmissionTime 2 | 0,Daniel-30,14:28:33+01:00 3 | 1,Jose-4,14:49:28+00:00 4 | 2,Jana-42,14:47:42+08:00 5 | 3,wg418,14:18:31+08:00 6 | 4,dadlike,14:19:02+01:00 7 | 5,af1318,14:31:04+01:00 8 | 6,beavers,14:36:46+01:00 9 | 7,Seymour-82,14:41:31+08:00 10 | 8,jh318,14:45:12+01:00 11 | 9,tl2018,14:48:33+00:00 12 | 10,sh618,14:27:00+08:00 13 | 11,upbrought,14:48:24+08:00 14 | 12,medial,14:34:36+08:00 15 | 13,glottology,14:29:14+00:00 16 | 14,squire,14:47:51+00:00 17 | 15,wq1118,14:49:27+08:00 18 | 16,Catherine-19,14:16:50+01:00 19 | 17,mc618,14:28:59+00:00 20 | 18,dk718,14:34:13+08:00 21 | 19,Heidi-90,14:22:14+01:00 22 | 20,ew1718,14:23:51+01:00 23 | 21,fancied,14:35:23+00:00 24 | 22,hostessing,14:31:08+08:00 25 | 23,am1118,14:18:37+08:00 26 | 24,lb318, 27 | 25,Edward-39,14:46:29+00:00 28 | 26,Danielle-81,14:39:07+01:00 29 | 27,mj1418,14:47:31+08:00 30 | 28,azurites,14:33:24+01:00 31 | 29,fh1018, 32 | 30,Jay-9,14:48:43+00:00 33 | 31,miffy,14:25:19+01:00 34 | 32,Larry-33,14:31:28+08:00 35 | 33,hh918,14:48:17+08:00 36 | 34,Jacqueline-33,14:22:51+08:00 37 | 35,Debra-34,14:26:48+08:00 38 | 36,Petra-74,14:32:10+00:00 39 | 37,sewing-press,14:28:04+00:00 40 | 38,Mary-51,14:21:21+08:00 41 | 39,kk418,14:30:42+01:00 42 | 40,Carolyn-50,14:25:59+00:00 43 | 41,ma918,14:34:45+00:00 44 | 42,filming,14:36:01+01:00 45 | 43,dw1318,14:45:30+00:00 46 | 44,da418,14:42:32+08:00 47 | 45,ps1518,14:49:01+00:00 48 | 46,tollbar,14:33:06+01:00 49 | 47,raptors,14:20:23+00:00 50 | 48,tossed,14:19:50+01:00 51 | 49,delayer,14:30:09+00:00 52 | 50,Thelma-85, 53 | 51,motes,14:46:07+01:00 54 | 52,abbreviated,14:25:59+00:00 55 | 53,jm1718,14:29:02+01:00 56 | 54,Helena-12,14:45:02+08:00 57 | 55,hanty,14:22:12+01:00 58 | 56,wb1918,14:20:03+01:00 59 | 57,rewild,14:41:45+01:00 60 | 58,jd1618,14:22:31+01:00 61 | 59,lv218,14:22:50+08:00 62 | 60,loxitane,14:35:57+01:00 63 | 61,swifter,14:18:59+01:00 64 | 62,, 65 | 63,Christopher-24,14:25:06+00:00 66 | 64,jr1418,14:48:05+08:00 67 | 65,Rudolph-35,14:34:18+08:00 68 | 66,rk1118,14:15:04+00:00 69 | 67,co-lessor,14:24:18+00:00 70 | 68,solidarities,14:27:29+08:00 71 | 69,Gwendolyn-75, 72 | 70,damosella, 73 | 71,at318,14:23:28+00:00 74 | 72,known,14:33:06+08:00 75 | 73,consisting,14:42:05+01:00 76 | 74,dp818,14:15:15+00:00 77 | 75,Adam-8,14:41:47+00:00 78 | 76,portière,14:42:25+08:00 79 | 77,sarcophage,14:44:43+08:00 80 | 78,Britni-25,14:24:13+08:00 81 | 79,rascally,14:42:45+00:00 82 | 80,adroitness,14:40:08+01:00 83 | 81,Terry-93,14:29:03+00:00 84 | 82,Steven-94,14:47:09+00:00 85 | 83,inveiglement,14:27:42+01:00 86 | 84,rm518, 87 | 85,Sarah-62,14:17:12+00:00 88 | 86,nondiabetic,14:49:34+08:00 89 | 87,kr618,14:19:48+00:00 90 | 88,enchain, 91 | 89,Gwenda-15,14:39:54+01:00 92 | 90,bearing,14:25:10+08:00 93 | 91,Mary-11,14:19:58+00:00 94 | 92,jr1318,14:22:43+01:00 95 | 93,mr818,14:22:57+00:00 96 | 94,hungover,14:41:32+08:00 97 | 95,monton,14:25:01+01:00 98 | 96,svengali,14:36:21+08:00 99 | 97,solar,14:22:31+01:00 100 | 98,Mary-24,14:18:56+08:00 101 | 99,boardwalk,14:28:04+00:00 102 | 100,Diana-50,14:47:41+08:00 103 | 101,Brianza,14:33:30+08:00 104 | 102,nc918,14:22:23+08:00 105 | 103,Traci-26,14:37:37+08:00 106 | 104,Morgan-24,14:34:28+00:00 107 | 105,dm618,14:25:01+01:00 108 | 106,Carol-93,14:49:58+08:00 109 | 107,Robert-33,14:32:07+01:00 110 | 108,acrobatical,14:46:39+08:00 111 | 109,Sheila-30,14:26:59+01:00 112 | 110,untowardly,14:30:24+08:00 113 | 111,wrestler,14:28:12+01:00 114 | 112,frenemies, 115 | 113,remeant, 116 | 114,air-cock,14:23:01+01:00 117 | 115,autohidden,14:17:32+00:00 118 | 116,Kevin-89,14:49:53+08:00 119 | 117,palmipeds,14:32:58+00:00 120 | 118,Christina-92,14:19:23+00:00 121 | 119,Buchner,14:24:45+08:00 122 | 120,unfermented,14:20:12+08:00 123 | 121,Janice-62,14:43:31+00:00 124 | 122,Brenda-54,14:26:48+00:00 125 | 123,ea418,14:19:46+00:00 126 | 124,Bessie-25,14:44:46+01:00 127 | 125,brittanic,14:43:56+08:00 128 | 126,iw818,14:40:17+08:00 129 | 127,rc218,14:39:35+01:00 130 | 128,John-83,14:50:51+00:00 131 | 129,top-lantern,14:44:11+00:00 132 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | PYTHONPATH := $(PWD)/..:$(PWD)/../test:$(PWD)/sphinx_latex:$(PYTHONPATH) 11 | 12 | # User-friendly check for sphinx-build 13 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 14 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 15 | endif 16 | 17 | # Internal variables. 18 | PAPEROPT_a4 = -D latex_paper_size=a4 19 | PAPEROPT_letter = -D latex_paper_size=letter 20 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | # the i18n builder cannot share the environment and doctrees with the others 22 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 23 | 24 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 25 | 26 | help: 27 | @echo "Please use \`make ' where is one of" 28 | @echo " html to make standalone HTML files" 29 | @echo " dirhtml to make HTML files named index.html in directories" 30 | @echo " singlehtml to make a single large HTML file" 31 | @echo " pickle to make pickle files" 32 | @echo " json to make JSON files" 33 | @echo " htmlhelp to make HTML files and a HTML help project" 34 | @echo " qthelp to make HTML files and a qthelp project" 35 | @echo " devhelp to make HTML files and a Devhelp project" 36 | @echo " epub to make an epub" 37 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 38 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 39 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 40 | @echo " text to make text files" 41 | @echo " man to make manual pages" 42 | @echo " texinfo to make Texinfo files" 43 | @echo " info to make Texinfo files and run them through makeinfo" 44 | @echo " gettext to make PO message catalogs" 45 | @echo " changes to make an overview of all changed/added/deprecated items" 46 | @echo " xml to make Docutils-native XML files" 47 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 48 | @echo " linkcheck to check all external links for integrity" 49 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 50 | 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | apidoc: $(GENERATED_FILES) 55 | PYTHONPATH=$(PWD)/..:$(PYTHONPATH) sphinx-apidoc ../example_code -o source/ -f -T 56 | PYTHONPATH=$(PWD)/..:$(PYTHONPATH) sphinx-apidoc ../fibonacci -o source/ -f -T 57 | 58 | webgit: 59 | git clone git@github.com:object-oriented-python/object-oriented-python.github.io.git webgit 60 | 61 | html: apidoc webgit # latexpdf 62 | rm webgit/* || true 63 | rm -rf $(BUILDDIR)/doctrees || true 64 | rm $(BUILDDIR)/html || rm -rf $(BUILDDIR)/html 65 | install -d $(BUILDDIR) 66 | ln -s $(PWD)/webgit $(BUILDDIR)/html 67 | PYTHONPATH=$(PWD)/..:$(PYTHONPATH) $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 68 | #cp $(BUILDDIR)/latex/Finiteelementcourse.pdf $(BUILDDIR)/html 69 | @echo 70 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 71 | 72 | make publish: 73 | cd webgit; git add -A; git commit -am "Website build"; git push --force 74 | 75 | livehtml: 76 | sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 77 | 78 | dirhtml: apidoc 79 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 80 | @echo 81 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 82 | 83 | singlehtml: apidoc 84 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 85 | @echo 86 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 87 | 88 | pickle: apidoc 89 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 90 | @echo 91 | @echo "Build finished; now you can process the pickle files." 92 | 93 | json: apidoc 94 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 95 | @echo 96 | @echo "Build finished; now you can process the JSON files." 97 | 98 | htmlhelp: apidoc 99 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 100 | @echo 101 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 102 | ".hhp project file in $(BUILDDIR)/htmlhelp." 103 | 104 | qthelp: apidoc 105 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 106 | @echo 107 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 108 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 109 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Finiteelementcourse.qhcp" 110 | @echo "To view the help file:" 111 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Finiteelementcourse.qhc" 112 | 113 | devhelp: apidoc 114 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 115 | @echo 116 | @echo "Build finished." 117 | @echo "To view the help file:" 118 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Finiteelementcourse" 119 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Finiteelementcourse" 120 | @echo "# devhelp" 121 | 122 | epub: apidoc 123 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 124 | @echo 125 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 126 | 127 | latex: apidoc 128 | $(SPHINXBUILD) $(ALLSPHINXOPTS) -b latex $(BUILDDIR)/latex 129 | @echo 130 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 131 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 132 | "(use \`make latexpdf' here to do that automatically)." 133 | 134 | latexpdf: apidoc 135 | PYTHONPATH=$(PWD)/..:$(PYTHONPATH) $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 136 | @echo "Running LaTeX files through pdflatex..." 137 | # $(MAKE) -C $(BUILDDIR)/latex all-pdf 138 | cd $(BUILDDIR)/latex; latexmk -pdf 139 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 140 | 141 | book: 142 | $(SPHINXBUILD) $(ALLSPHINXOPTS) -b latex -t book $(BUILDDIR)/book 143 | @echo 144 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/book." 145 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 146 | "(use \`make bookpdf' here to do that automatically)." 147 | 148 | bookpdf: 149 | PYTHONPATH=$(PWD)/..:$(PYTHONPATH) $(SPHINXBUILD) -b latex -t book $(ALLSPHINXOPTS) $(BUILDDIR)/book 150 | @echo "Running LaTeX files through pdflatex..." 151 | # $(MAKE) -C $(BUILDDIR)/latex all-pdf 152 | cd $(BUILDDIR)/book; latexmk -pdf 153 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/book." 154 | 155 | latexpdfja: apidoc 156 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 157 | @echo "Running LaTeX files through platex and dvipdfmx..." 158 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 159 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 160 | 161 | text: apidoc 162 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 163 | @echo 164 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 165 | 166 | man: apidoc 167 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 168 | @echo 169 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 170 | 171 | texinfo: apidoc 172 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 173 | @echo 174 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 175 | @echo "Run \`make' in that directory to run these through makeinfo" \ 176 | "(use \`make info' here to do that automatically)." 177 | 178 | info: apidoc 179 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 180 | @echo "Running Texinfo files through makeinfo..." 181 | make -C $(BUILDDIR)/texinfo info 182 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 183 | 184 | gettext: apidoc 185 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 186 | @echo 187 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 188 | 189 | changes: apidoc 190 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 191 | @echo 192 | @echo "The overview file is in $(BUILDDIR)/changes." 193 | 194 | linkcheck: apidoc 195 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 196 | @echo 197 | @echo "Link check complete; look for any errors in the above output " \ 198 | "or in $(BUILDDIR)/linkcheck/output.txt." 199 | 200 | doctest: apidoc 201 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 202 | @echo "Testing of doctests in the sources finished, look at the " \ 203 | "results in $(BUILDDIR)/doctest/output.txt." 204 | 205 | xml: apidoc 206 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 207 | @echo 208 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 209 | 210 | pseudoxml: apidoc 211 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 212 | @echo 213 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 214 | -------------------------------------------------------------------------------- /doc/source/0_preface.rst: -------------------------------------------------------------------------------- 1 | Preface 2 | ======= 3 | 4 | Computers have revolutionised mathematics and the many scientific, engineering, 5 | and economic fields in which mathematics is applied. In the applications of 6 | mathematics the role of computation has long been obvious and prominent. Now, 7 | the development of theorem proving software is increasing the prominence of 8 | computing in pure mathematics. What this means is that the ability to write 9 | computer programs well is an indispensable part of the toolkit of a 21st 10 | century mathematician and, indeed, scientist or engineer. 11 | 12 | Regrettably, university courses in mathematics and its sibling disciplines have 13 | often failed to reflect this revolution in the way that mathematics is 14 | practised. Far too often the sum total of programming education in an 15 | undergraduate degree is a computational methods module in which students are 16 | shown elementary programming constructs such as functions, loops, and perhaps 17 | plotting. These are introduced in the context of solving particular 18 | computational mathematics or statistics problems, and the programming 19 | constructs introduced are driven by what is needed to solve those problems. 20 | 21 | The assumptions underpinning this approach seem to be some combination of a 22 | belief that maths degrees should only teach maths, as well a feeling that the 23 | mathematical algorithms are some how the difficult part and that programming is 24 | a mere technical skill that students will somehow pick up along the way. The 25 | consequence of this approach is that many maths students and graduates end up 26 | without the programming, software development, and debugging skills that they 27 | need to make effective use of computers in their further studies or working 28 | careers. 29 | 30 | What is this book for? 31 | ---------------------- 32 | 33 | This book is the result of a significant change in the mathematics curriculum 34 | at Imperial College London. Rather than assume that students will somehow 35 | acquire programming skills along the way, we have introduced first and second 36 | year courses with the sole objective of teaching students to programme well. 37 | This book is the text for the second of these courses. Named "Principles of 38 | Programming", the course aims to take students with a knowledge of basic Python 39 | programming (functions, loops, plotting and so forth) and introduce them to 40 | higher level programming concepts. 41 | 42 | The objective of this course is to graduate better programmers. Material on 43 | new programming constructs and concepts is accompanied by chapters on good 44 | programming style, so that students learn how to write code that they and 45 | others can understand, and on errors, exceptions and debugging, so that 46 | students learn how to get themselves out of trouble. 47 | 48 | An underlying theme throughout this book is that programming has strong 49 | connections with mathematics. In particular, both mathematics and programming 50 | depend on building higher level, more abstract objects which encapsulate and 51 | hide the underlying complexity of operations. It is in taking this mathematical 52 | approach to programming that this book is "for mathematicians". 53 | 54 | The examples are chosen from across mathematics. For example, it appears to be 55 | traditional in object oriented programming books to use a telephone directory 56 | as the initial example of classes. We eschew this in favour of a class 57 | implementing polynomials. This provides the opportunity to introduce 58 | encapsulation and operator overloading for a familiar mathematical object. In 59 | contrast to the traditional computational methods courses, the examples are 60 | chosen to illustrate and explain the programming concepts we study rather than 61 | the converse. 62 | 63 | Who is this book for? 64 | --------------------- 65 | 66 | This book is for anyone with mathematical, scientific, or engineering interests 67 | who would like to learn to be a more capable programmer. The mathematical 68 | examples assume that you know how to differentiate functions of one variable, 69 | but very little beyond that. Where examples or exercises employ other 70 | mathematics, such as cellular automata in :numref:`Chapter %s 21 | 22 | 23 | 24 |
25 |

Font-face Demo for the Neuton Font

26 | 27 | 28 | 29 |

Neuton Regular - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/neuton-fontfacekit/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on June 12, 2011 05:33:46 AM America/New_York */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'NeutonRegular'; 7 | src: url('Neuton-webfont.eot'); 8 | src: url('Neuton-webfont.eot?#iefix') format('embedded-opentype'), 9 | url('Neuton-webfont.woff') format('woff'), 10 | url('Neuton-webfont.ttf') format('truetype'), 11 | url('Neuton-webfont.svg#NeutonRegular') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/SIL Open Font License 1.1.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: 3 | http://scripts.sil.org/OFL 4 | 5 | 6 | ----------------------------------------------------------- 7 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 8 | ----------------------------------------------------------- 9 | 10 | PREAMBLE 11 | The goals of the Open Font License (OFL) are to stimulate worldwide 12 | development of collaborative font projects, to support the font creation 13 | efforts of academic and linguistic communities, and to provide a free and 14 | open framework in which fonts may be shared and improved in partnership 15 | with others. 16 | 17 | The OFL allows the licensed fonts to be used, studied, modified and 18 | redistributed freely as long as they are not sold by themselves. The 19 | fonts, including any derivative works, can be bundled, embedded, 20 | redistributed and/or sold with any software provided that any reserved 21 | names are not used by derivative works. The fonts and derivatives, 22 | however, cannot be released under any other type of license. The 23 | requirement for fonts to remain under this license does not apply 24 | to any document created using the fonts or their derivatives. 25 | 26 | DEFINITIONS 27 | "Font Software" refers to the set of files released by the Copyright 28 | Holder(s) under this license and clearly marked as such. This may 29 | include source files, build scripts and documentation. 30 | 31 | "Reserved Font Name" refers to any names specified as such after the 32 | copyright statement(s). 33 | 34 | "Original Version" refers to the collection of Font Software components as 35 | distributed by the Copyright Holder(s). 36 | 37 | "Modified Version" refers to any derivative made by adding to, deleting, 38 | or substituting -- in part or in whole -- any of the components of the 39 | Original Version, by changing formats or by porting the Font Software to a 40 | new environment. 41 | 42 | "Author" refers to any designer, engineer, programmer, technical 43 | writer or other person who contributed to the Font Software. 44 | 45 | PERMISSION & CONDITIONS 46 | Permission is hereby granted, free of charge, to any person obtaining 47 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 48 | redistribute, and sell modified and unmodified copies of the Font 49 | Software, subject to the following conditions: 50 | 51 | 1) Neither the Font Software nor any of its individual components, 52 | in Original or Modified Versions, may be sold by itself. 53 | 54 | 2) Original or Modified Versions of the Font Software may be bundled, 55 | redistributed and/or sold with any software, provided that each copy 56 | contains the above copyright notice and this license. These can be 57 | included either as stand-alone text files, human-readable headers or 58 | in the appropriate machine-readable metadata fields within text or 59 | binary files as long as those fields can be easily viewed by the user. 60 | 61 | 3) No Modified Version of the Font Software may use the Reserved Font 62 | Name(s) unless explicit written permission is granted by the corresponding 63 | Copyright Holder. This restriction only applies to the primary font name as 64 | presented to the users. 65 | 66 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 67 | Software shall not be used to promote, endorse or advertise any 68 | Modified Version, except to acknowledge the contribution(s) of the 69 | Copyright Holder(s) and the Author(s) or with their explicit written 70 | permission. 71 | 72 | 5) The Font Software, modified or unmodified, in part or in whole, 73 | must be distributed entirely under this license, and must not be 74 | distributed under any other license. The requirement for fonts to 75 | remain under this license does not apply to any document created 76 | using the Font Software. 77 | 78 | TERMINATION 79 | This license becomes null and void if any of the above conditions are 80 | not met. 81 | 82 | DISCLAIMER 83 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 85 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 86 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 87 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 89 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 91 | OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Font Face Demo 9 | 10 | 24 | 25 | 26 | 27 |
28 |

Font-face Demo for the Nobile Font

29 | 30 | 31 | 32 |

Nobile Regular - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

33 | 34 | 35 | 36 |

Nobile Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

37 | 38 | 39 | 40 |

Nobile Bold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

41 | 42 | 43 | 44 |

Nobile Bold Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

45 | 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.eot -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.ttf -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile-webfont.woff -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.eot -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.ttf -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold-webfont.woff -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.eot -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.ttf -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_bold_italic-webfont.woff -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.eot -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.ttf -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/nobile-fontfacekit/nobile_italic-webfont.woff -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/nobile-fontfacekit/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on June 12, 2011 05:30:25 AM America/New_York */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'NobileRegular'; 7 | src: url('nobile-webfont.eot'); 8 | src: url('nobile-webfont.eot?#iefix') format('embedded-opentype'), 9 | url('nobile-webfont.woff') format('woff'), 10 | url('nobile-webfont.ttf') format('truetype'), 11 | url('nobile-webfont.svg#NobileRegular') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | } 16 | 17 | @font-face { 18 | font-family: 'NobileItalic'; 19 | src: url('nobile_italic-webfont.eot'); 20 | src: url('nobile_italic-webfont.eot?#iefix') format('embedded-opentype'), 21 | url('nobile_italic-webfont.woff') format('woff'), 22 | url('nobile_italic-webfont.ttf') format('truetype'), 23 | url('nobile_italic-webfont.svg#NobileItalic') format('svg'); 24 | font-weight: normal; 25 | font-style: normal; 26 | 27 | } 28 | 29 | @font-face { 30 | font-family: 'NobileBold'; 31 | src: url('nobile_bold-webfont.eot'); 32 | src: url('nobile_bold-webfont.eot?#iefix') format('embedded-opentype'), 33 | url('nobile_bold-webfont.woff') format('woff'), 34 | url('nobile_bold-webfont.ttf') format('truetype'), 35 | url('nobile_bold-webfont.svg#NobileBold') format('svg'); 36 | font-weight: normal; 37 | font-style: normal; 38 | 39 | } 40 | 41 | @font-face { 42 | font-family: 'NobileBoldItalic'; 43 | src: url('nobile_bold_italic-webfont.eot'); 44 | src: url('nobile_bold_italic-webfont.eot?#iefix') format('embedded-opentype'), 45 | url('nobile_bold_italic-webfont.woff') format('woff'), 46 | url('nobile_bold_italic-webfont.ttf') format('truetype'), 47 | url('nobile_bold_italic-webfont.svg#NobileBoldItalic') format('svg'); 48 | font-weight: normal; 49 | font-style: normal; 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/sample-news-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/sample-news-image.png -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/social-buttons.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | A test of social buttons 7 | 8 | 9 | 10 |
11 | 20 | 21 | 28 | 29 |
30 |
31 |

Let’s be social!

32 |
33 |
34 |
35 |
36 |
37 |

Please test these buttons by logging into your social profiles.

38 |
39 |
40 |

© 2011

41 |
42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/transparent.gif -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/static/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/_themes/finite_element/static/unknown.png -------------------------------------------------------------------------------- /doc/source/_themes/finite_element/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = fenics.css 4 | pygments_style = fenics_theme_support.FenicsStyle 5 | 6 | [options] 7 | highlight_language = guess 8 | short_title = Home 9 | logo = icon.png 10 | favicon = icon.ico 11 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Object oriented programming course documentation build configuration file, 4 | # created by sphinx-quickstart on Sat Sep 6 21:48:49 2014. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | # sys.path.insert(0, os.path.abspath('.')) 20 | 21 | # -- General configuration ------------------------------------------------ 22 | 23 | # If your documentation needs a minimal Sphinx version, state it here. 24 | # needs_sphinx = '1.0' 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be 27 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 28 | # ones. 29 | extensions = [ 30 | 'sphinx.ext.autodoc', 31 | 'sphinx.ext.intersphinx', 32 | 'sphinx.ext.mathjax', 33 | 'sphinxcontrib.youtube', 34 | 'sphinx.ext.viewcode', 35 | 'sphinxcontrib.proof', 36 | 'IPython.sphinxext.ipython_console_highlighting', 37 | 'IPython.sphinxext.ipython_directive', 38 | 'sphinx.ext.graphviz', 39 | 'sphinxcontrib.blockdiag', 40 | 'sphinx.ext.napoleon', 41 | 'sphinxcontrib.details.directive', 42 | 'sphinx_reredirects' 43 | ] 44 | # Both the class’ and the __init__ method’s docstring are concatenated and 45 | # inserted into the class definition 46 | autoclass_content = 'both' 47 | 48 | # Add any paths that contain templates here, relative to this directory. 49 | templates_path = ['_templates'] 50 | 51 | # The suffix of source filenames. 52 | source_suffix = '.rst' 53 | 54 | # The encoding of source files. 55 | # source_encoding = 'utf-8-sig' 56 | 57 | # The master toctree document. 58 | master_doc = 'index' 59 | 60 | # General information about the project. 61 | project = u'Object-oriented Programming' 62 | author = u'David A. Ham' 63 | copyright = u'2019-2023, David A. Ham' 64 | 65 | mathjax_path = \ 66 | "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" # noqa 501 67 | 68 | # The version info for the project you're documenting, acts as replacement for 69 | # |version| and |release|, also used in various other places throughout the 70 | # built documents. 71 | # 72 | # The short X.Y version. 73 | version = '2023.0' 74 | # The full version, including alpha/beta/rc tags. 75 | release = '' 76 | 77 | # The language for content autogenerated by Sphinx. Refer to documentation 78 | # for a list of supported languages. 79 | # language = None 80 | 81 | redirects = { 82 | "edition1/exercises": "../exercises.html", 83 | "edition1/videos": "../videos.html", 84 | "edition2/exercises": "../exercises.html", 85 | "edition2/videos": "../videos.html", 86 | "edition3/exercises": "../exercises.html", 87 | "edition3/videos": "../videos.html" 88 | } 89 | 90 | # There are two options for replacing |today|: either, you set today to some 91 | # non-false value, then it is used: 92 | # today = '' 93 | # Else, today_fmt is used as the format for a strftime call. 94 | # today_fmt = '%B %d, %Y' 95 | 96 | # List of patterns, relative to source directory, that match files and 97 | # directories to ignore when looking for source files. 98 | exclude_patterns = [] 99 | 100 | # The reST default role (used for this markup: `text`) to use for all 101 | # documents. 102 | default_role = "py:obj" 103 | 104 | # If true, '()' will be appended to :func: etc. cross-reference text. 105 | # add_function_parentheses = True 106 | 107 | # If true, the current module name will be prepended to all description 108 | # unit titles (such as .. function::). 109 | # add_module_names = True 110 | 111 | # If true, sectionauthor and moduleauthor directives will be shown in the 112 | # output. They are ignored by default. 113 | # show_authors = False 114 | 115 | # The name of the Pygments (syntax highlighting) style to use. 116 | pygments_style = 'sphinx' 117 | 118 | # A list of ignored prefixes for module index sorting. 119 | # modindex_common_prefix = [] 120 | 121 | # If true, keep warnings as "system message" paragraphs in the built documents. 122 | # keep_warnings = False 123 | 124 | 125 | proof_theorem_types = { 126 | "algorithm": "Algorithm", 127 | "conjecture": "Conjecture", 128 | "corollary": "Corollary", 129 | "definition": "Definition", 130 | "example": "Example", 131 | "lemma": "Lemma", 132 | "observation": "Observation", 133 | "proof": "Proof", 134 | "property": "Property", 135 | "theorem": "Theorem", 136 | "exercise": "Exercise", 137 | } 138 | 139 | proof_latex_parent = "chapter" 140 | 141 | # -- Options for HTML output ---------------------------------------------- 142 | 143 | # The theme to use for HTML and HTML Help pages. See the documentation for 144 | # a list of builtin themes. 145 | html_theme = 'finite_element' 146 | 147 | # Theme options are theme-specific and customize the look and feel of a theme 148 | # further. For a list of options available for each theme, see the 149 | # documentation. 150 | # html_theme_options = {} 151 | 152 | # Add any paths that contain custom themes here, relative to this directory. 153 | html_theme_path = ['_themes'] 154 | 155 | # The name for this set of Sphinx documents. If None, it defaults to 156 | # " v documentation". 157 | # html_title = None 158 | 159 | # A shorter title for the navigation bar. Default is the same as html_title. 160 | # html_short_title = None 161 | 162 | # The name of an image file (relative to this directory) to place at the top 163 | # of the sidebar. 164 | # html_logo = None 165 | 166 | # The name of an image file (within the static path) to use as favicon of the 167 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 168 | # pixels large. 169 | # html_favicon = None 170 | 171 | # Add any paths that contain custom static files (such as style sheets) here, 172 | # relative to this directory. They are copied after the builtin static files, 173 | # so a file named "default.css" will overwrite the builtin "default.css". 174 | html_static_path = ['_static'] 175 | 176 | # Add any extra paths that contain custom files (such as robots.txt or 177 | # .htaccess) here, relative to this directory. These files are copied 178 | # directly to the root of the documentation. 179 | # html_extra_path = [] 180 | 181 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 182 | # using the given strftime format. 183 | # html_last_updated_fmt = '%b %d, %Y' 184 | 185 | # If true, SmartyPants will be used to convert quotes and dashes to 186 | # typographically correct entities. 187 | html_use_smartypants = True 188 | 189 | # Custom sidebar templates, maps document names to template names. 190 | # html_sidebars = {} 191 | 192 | # Additional templates that should be rendered to pages, maps page names to 193 | # template names. 194 | # html_additional_pages = {} 195 | 196 | # If false, no module index is generated. 197 | # html_domain_indices = True 198 | 199 | # If false, no index is generated. 200 | # html_use_index = True 201 | 202 | # If true, the index is split into individual pages for each letter. 203 | # html_split_index = False 204 | 205 | # If true, links to the reST sources are added to the pages. 206 | # html_show_sourcelink = True 207 | 208 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 209 | # html_show_sphinx = True 210 | 211 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 212 | # html_show_copyright = True 213 | 214 | # If true, an OpenSearch description file will be output, and all pages will 215 | # contain a tag referring to it. The value of this option must be the 216 | # base URL from which the finished HTML is served. 217 | # html_use_opensearch = '' 218 | 219 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 220 | # html_file_suffix = None 221 | 222 | # Output file base name for HTML help builder. 223 | htmlhelp_basename = 'Finiteelementcoursedoc' 224 | 225 | # -- GraphViz configuration ----------------------------------------------- 226 | graphviz_output_format = 'svg' 227 | 228 | # Fontpath for blockdiag (truetype font) 229 | blockdiag_fontpath = '/Users/dham/Library/Fonts/Carlito-Regular.ttf' 230 | blockdiag_html_image_format = 'svg' 231 | blockdiag_latex_image_format = 'pdf' 232 | 233 | # -- Options for LaTeX output --------------------------------------------- 234 | 235 | latex_engine = 'lualatex' 236 | 237 | latex_use_xindy = False 238 | 239 | latex_additional_files = [ 240 | '_themes/finite_element/static/dialog-right.png', 241 | '_themes/finite_element/static/dialog-wrong.png', 242 | '_static/imperialmathnotes.sty', 243 | '_static/poptitle.sty', 244 | 'images/Imperial.pdf' 245 | ] 246 | 247 | if tags.has("book"): 248 | preamble = r""" 249 | % The default sphinx colouring colours a lot of links that are actually dead in 250 | % the book version. 251 | \definecolor{internallinkcolor}{HTML}{c52b03} 252 | \definecolor{externallinkcolor}{HTML}{e55d05} 253 | %\hypersetup{linkcolor=internallinkcolor} 254 | \hypersetup{linkcolor=black} 255 | %\hypersetup{urlcolor=externallinkcolor} 256 | \hypersetup{urlcolor=black} 257 | \usepackage{poptitle} 258 | \title{Object-oriented Programming} 259 | \subtitle{in Python for Mathematicians} 260 | \edition{2021} 261 | \edition{2023} 262 | \edition{2023} 263 | \makeatletter 264 | \fancypagestyle{normal}{ 265 | \fancyhf{} 266 | \fancyfoot[RO]{{\py@HeaderFamily\thepage}} 267 | \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}} 268 | \fancyhead[RO]{{}} 269 | \if@twoside 270 | \fancyfoot[LE]{{\py@HeaderFamily\thepage}} 271 | \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} 272 | \fancyhead[LE]{{}} 273 | \fi 274 | \renewcommand{\headrulewidth}{0.4pt} 275 | \renewcommand{\footrulewidth}{0.4pt} 276 | } 277 | \makeatother 278 | """ 279 | else: 280 | # Imperial lecture notes version. 281 | preamble = r""" 282 | \usepackage{imperialmathnotes} 283 | \subtitle{in Python for Mathematicians} 284 | \imperialmathnotesvolume{2} 285 | \edition{2021} 286 | """ 287 | 288 | latex_elements = { 289 | # The paper size ('letterpaper' or 'a4paper'). 290 | 'papersize': 'a4paper', 291 | 292 | # The font size ('10pt', '11pt' or '12pt'). 293 | 'pointsize': '11pt', 294 | 295 | 'babel': r'\usepackage[british]{babel}', 296 | 297 | # Additional stuff for the LaTeX preamble. 298 | 'preamble': preamble + r''' 299 | \addto\captionsbritish{\renewcommand{\figurename}{Figure\@{} }} 300 | \def\fnum@figure{\figurename\thefigure{}} 301 | 302 | \addto\captionsbritish{\renewcommand{\tablename}{Table }} 303 | \def\fnum@table{\tablename\thetable{}} 304 | 305 | \usepackage[margin=10pt,font=small,labelfont=bf]{caption} 306 | \setcounter{MaxMatrixCols}{20} 307 | \usepackage{tcolorbox} 308 | \usepackage{tikz} 309 | \newcommand{\currentsummary}{} 310 | \newcommand{\sphinxdetailssummary}[1]{ 311 | \renewcommand{\currentsummary}{#1}} 312 | \newcounter{video}[chapter] 313 | \newwrite\videolist 314 | \immediate\openout\videolist=videos.csv 315 | \newcommand{\sphinxcontribvimeo}[2]{% 316 | \stepcounter{video} 317 | \immediate\write\videolist{\thechapter.\thevideo, `\currentsummary\space <#1#2>`_} 318 | \hfill\smash{ 319 | \begin{minipage}[b][5em][c]{5.5em} 320 | \tcbox[tikznode,colframe=TitleColor,colback=TitleColor,coltext=white]{ 321 | \bfseries\sffamily 322 | \protect\href{#1#2}{\color{white}Video}\\\bfseries\sffamily 323 | \protect\href{#1#2}{\color{white}\thechapter.\thevideo} 324 | %\currentsummary 325 | } 326 | \end{minipage} 327 | } 328 | } 329 | \usepackage{etoolbox} 330 | \usepackage{pifont} 331 | \newcommand{\cmark}{\ding{51}}% 332 | \newcommand{\xmark}{\ding{55}}% 333 | \newcommand{\currentsphinxclass}{} 334 | \usepackage{calc} 335 | \newlength{\badcodesize} 336 | \renewenvironment{sphinxnote}[1] 337 | {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} 338 | \definecolor{sphinxnoteBgColor}{HTML}{e1ecfe} 339 | \renewenvironment{sphinxhint}[1] 340 | {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} 341 | \definecolor{sphinxhintBgColor}{HTML}{e1ecfe} 342 | \renewenvironment{sphinxuseclass}[1]{ 343 | \setlength{\badcodesize}{\linewidth-2.5em} 344 | \renewcommand{\currentsphinxclass}{#1} % Note not safe for nested containers. 345 | \ifstrequal{#1}{badcode}{\noindent\begin{minipage}{\badcodesize}}{} 346 | \ifstrequal{#1}{goodcode}{\noindent\begin{minipage}{\badcodesize}}{} 347 | }{ 348 | \ifdefstring{\currentsphinxclass}{badcode}{\end{minipage} 349 | \begin{minipage}{.045\textwidth}{\Huge\color{red}\ \xmark}\end{minipage} 350 | 351 | }{} 352 | \ifdefstring{\currentsphinxclass}{goodcode}{\end{minipage}\ 353 | \begin{minipage}{.045\textwidth}{\Huge\color{green}\ \cmark}\end{minipage} 354 | 355 | }{} 356 | \renewcommand{\currentsphinxclass}{} 357 | } 358 | ''', 359 | 'releasename': '', 360 | 'sphinxsetup': 'VerbatimColor={HTML}{FAFAFA}, \ 361 | VerbatimBorderColor={HTML}{c6c9cb}, \ 362 | noteBorderColor={HTML}{7a9eec}, \ 363 | hintBorderColor={HTML}{7a9eec}, \ 364 | warningBorderColor={HTML}{fbc2c4}, \ 365 | warningBgColor={HTML}{fbe3e4}, \ 366 | TitleColor={cmyk}{1,.61,0,.45}' 367 | } 368 | 369 | if tags.has("book"): 370 | latex_elements['geometry'] = r'\usepackage[papersize={189mm,246.1mm}]{geometry}' 371 | latex_elements['sphinxsetup'] += ',hmargin={1.9cm,1.3cm},vmargin={2cm,2cm}' 372 | latex_elements['maketitle'] = r'\poptitlepages' 373 | else: 374 | latex_elements['maketitle'] = r'\imperialmathnotestitlepages' 375 | latex_elements['sphinxsetup'] += ', \ 376 | InnerLinkColor={HTML}{c52b03}, \ 377 | OuterLinkColor={HTML}{e55d05},' 378 | 379 | 380 | # Grouping the document tree into LaTeX files. List of tuples 381 | # (source start file, target name, title, 382 | # author, documentclass [howto, manual, or own class]). 383 | # latex_documents = [ 384 | # ('index', 'Finiteelementcourse.tex', 385 | # u'M345A47 Finite Elements: Analysis and Implementation', 386 | # u'David A. Ham and Colin J. Cotter', 'manual'), 387 | # ] 388 | # if tags.has("book"): 389 | # latex_documents = [ 390 | # ('index', 'objectorientedprogramming.tex', 391 | # 'Object oriented programming\\\\\\LARGE in Python for mathematicians', 392 | # 'David A. Ham', 'book'), 393 | # ] 394 | 395 | # The name of an image file (relative to this directory) to place at the top of 396 | # the title page. 397 | # latex_logo = None 398 | 399 | # For "manual" documents, if this is true, then toplevel headings are parts, 400 | # not chapters. 401 | # latex_use_parts = False 402 | latex_toplevel_sectioning = "chapter" 403 | 404 | # If true, show page references after internal links. 405 | # latex_show_pagerefs = False 406 | 407 | # If true, show URL addresses after external links. 408 | # latex_show_urls = False 409 | 410 | # Documents to append as an appendix to all manuals. 411 | # latex_appendices = [] 412 | 413 | # If false, no module index is generated. 414 | # latex_domain_indices = True 415 | latex_docclass = {"manual": "book"} 416 | 417 | 418 | # -- Options for manual page output --------------------------------------- 419 | 420 | # One entry per manual page. List of tuples 421 | # (source start file, name, description, authors, manual section). 422 | # man_pages = [ 423 | # ('index', 'finiteelementcourse', u'Finite element course Documentation', 424 | # [u'David A. Ham and Colin J. Cotter'], 1) 425 | # ] 426 | 427 | # If true, show URL addresses after external links. 428 | # man_show_urls = False 429 | 430 | 431 | numfig = True 432 | 433 | # Example configuration for intersphinx: refer to the Python standard library. 434 | intersphinx_mapping = { 435 | 'python': ('https://docs.python.org/3/', None), 436 | 'scipy': ('https://scipy.github.io/devdocs/', None), 437 | 'numpy': ('https://numpy.org/doc/stable/', None), 438 | 'matplotlib': ('https://matplotlib.org/', None), 439 | 'setuptools': ('https://setuptools.readthedocs.io/en/latest/', None), 440 | 'pip': ('https://pip.pypa.io/en/stable/', None), 441 | 'sympy': ('https://docs.sympy.org/latest', None), 442 | 'pytest': ('https://docs.pytest.org/en/latest/', None), 443 | 'fons': ('https://imperial-fons-computing.github.io', None), 444 | 'pandas': ('https://pandas.pydata.org/docs/', None) 445 | } 446 | -------------------------------------------------------------------------------- /doc/source/cover_text: -------------------------------------------------------------------------------- 1 | This book is for mathematicians, scientists, and engineers who have learned the 2 | very basics of programming in Python, and who would like to become more capable 3 | programmers. In addition to covering higher level programming concepts such as 4 | objects, inheritance, and abstract data types, emphasis is placed on 5 | programming skills such as interpreting and debugging errors. If you find 6 | yourself baffled by the pages of error messages that Python emits, and would 7 | like to make sense of them, then this book is for you. 8 | 9 | The book takes a mathematician's view of programming, introducing higher level 10 | programming abstractions by analogy with the abstract objects that make up 11 | higher mathematics. Examples and exercises are chosen from across mathematics, 12 | though the actual mathematical knowledge required to understand this book is 13 | limited to differentiating functions of one variable. 14 | 15 | Dr David Ham is Reader in Computational Mathematics at Imperial College London. 16 | He teaches the object-oriented programming course for undergraduate 17 | mathematicians on which this book is based, as well as an advanced course on 18 | the finite element method. His research focusses on high level abstractions and 19 | code generation for forward and inverse finite element simulation. -------------------------------------------------------------------------------- /doc/source/example_code.rst: -------------------------------------------------------------------------------- 1 | example\_code package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | example\_code.addable module 8 | ---------------------------- 9 | 10 | .. automodule:: example_code.addable 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | example\_code.euclid module 16 | --------------------------- 17 | 18 | .. automodule:: example_code.euclid 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | example\_code.expression\_tools module 24 | -------------------------------------- 25 | 26 | .. automodule:: example_code.expression_tools 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | example\_code.graphs module 32 | --------------------------- 33 | 34 | .. automodule:: example_code.graphs 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | example\_code.groups module 40 | --------------------------- 41 | 42 | .. automodule:: example_code.groups 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | example\_code.groups\_abc module 48 | -------------------------------- 49 | 50 | .. automodule:: example_code.groups_abc 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | example\_code.groups\_basic module 56 | ---------------------------------- 57 | 58 | .. automodule:: example_code.groups_basic 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | 63 | example\_code.hello module 64 | -------------------------- 65 | 66 | .. automodule:: example_code.hello 67 | :members: 68 | :undoc-members: 69 | :show-inheritance: 70 | 71 | example\_code.linked\_list module 72 | --------------------------------- 73 | 74 | .. automodule:: example_code.linked_list 75 | :members: 76 | :undoc-members: 77 | :show-inheritance: 78 | 79 | example\_code.polynomial module 80 | ------------------------------- 81 | 82 | .. automodule:: example_code.polynomial 83 | :members: 84 | :undoc-members: 85 | :show-inheritance: 86 | 87 | example\_code.shapes module 88 | --------------------------- 89 | 90 | .. automodule:: example_code.shapes 91 | :members: 92 | :undoc-members: 93 | :show-inheritance: 94 | 95 | example\_code.simple\_classes module 96 | ------------------------------------ 97 | 98 | .. automodule:: example_code.simple_classes 99 | :members: 100 | :undoc-members: 101 | :show-inheritance: 102 | 103 | example\_code.square module 104 | --------------------------- 105 | 106 | .. automodule:: example_code.square 107 | :members: 108 | :undoc-members: 109 | :show-inheritance: 110 | 111 | example\_code.try\_except module 112 | -------------------------------- 113 | 114 | .. automodule:: example_code.try_except 115 | :members: 116 | :undoc-members: 117 | :show-inheritance: 118 | 119 | Module contents 120 | --------------- 121 | 122 | .. automodule:: example_code 123 | :members: 124 | :undoc-members: 125 | :show-inheritance: 126 | -------------------------------------------------------------------------------- /doc/source/exercises.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _exercises: 4 | 5 | Exercise code 6 | ============= 7 | 8 | These are the GitHub template repositories to use for the exercises in each 9 | Chapter. For further information on using GitHub template repositories, see 10 | :numref:`Appendix %s `. 11 | 12 | If you are using this book as a part of a course where the instructor provides 13 | GitHub Classroom assignments for the exercises, you should not use the links 14 | here but rather use the Classroom links provided by your instructor. Students 15 | taking Principles of Programming at Imperial College London will find their 16 | list of GitHub Classroom links `on Blackboard 17 | `__. 18 | 19 | 20 | * `Chapter 2 exercises `__ 21 | * `Chapter 3 exercises `__ 22 | * `Chapter 4 exercises `__ 23 | * `Chapter 5 exercises `__ 24 | * `Chapter 6 exercises `__ 25 | * `Chapter 7 exercises `__ 26 | * `Chapter 8 exercises `__ and 27 | `quiz `__ 28 | * `Chapter 9 exercises `__ 29 | * `Chapter 10 exercises `__ 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/source/fibonacci.rst: -------------------------------------------------------------------------------- 1 | fibonacci package 2 | ================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | fibonacci.fibonacci module 8 | -------------------------- 9 | 10 | .. automodule:: fibonacci.fibonacci 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | fibonacci.typesafe\_fibonacci module 16 | ------------------------------------ 17 | 18 | .. automodule:: fibonacci.typesafe_fibonacci 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | Module contents 24 | --------------- 25 | 26 | .. automodule:: fibonacci 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /doc/source/images/Imperial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/Imperial.pdf -------------------------------------------------------------------------------- /doc/source/images/blackboard.css: -------------------------------------------------------------------------------- 1 | style="background-color: #fafafa; padding: 10px; margin-bottom: 10px; border-top: 2px solid #c6c9cb; border-bottom: 2px solid #c6c9cb; font-family: Consolas, "andale mono", "lucida console", monospace;" -------------------------------------------------------------------------------- /doc/source/images/cover.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/cover.pdf -------------------------------------------------------------------------------- /doc/source/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/cover.png -------------------------------------------------------------------------------- /doc/source/images/debug_controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/debug_controls.png -------------------------------------------------------------------------------- /doc/source/images/debug_controls_annotated.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/debug_controls_annotated.pdf -------------------------------------------------------------------------------- /doc/source/images/debug_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/debug_icon.png -------------------------------------------------------------------------------- /doc/source/images/debug_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/debug_screen.png -------------------------------------------------------------------------------- /doc/source/images/debug_screen_annotated.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/debug_screen_annotated.pdf -------------------------------------------------------------------------------- /doc/source/images/dynamic_array.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/dynamic_array.pdf -------------------------------------------------------------------------------- /doc/source/images/edstem_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/edstem_issue.png -------------------------------------------------------------------------------- /doc/source/images/git_clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/git_clone.png -------------------------------------------------------------------------------- /doc/source/images/git_exercise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/git_exercise.png -------------------------------------------------------------------------------- /doc/source/images/github_autograding_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_autograding_fail.png -------------------------------------------------------------------------------- /doc/source/images/github_autograding_fail_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_autograding_fail_detail.png -------------------------------------------------------------------------------- /doc/source/images/github_autograding_pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_autograding_pass.png -------------------------------------------------------------------------------- /doc/source/images/github_change_branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_change_branch.png -------------------------------------------------------------------------------- /doc/source/images/github_commit_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_commit_list.png -------------------------------------------------------------------------------- /doc/source/images/github_diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_diff.png -------------------------------------------------------------------------------- /doc/source/images/github_post_commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_post_commit.png -------------------------------------------------------------------------------- /doc/source/images/github_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/github_template.png -------------------------------------------------------------------------------- /doc/source/images/glider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider.png -------------------------------------------------------------------------------- /doc/source/images/glider_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_1.png -------------------------------------------------------------------------------- /doc/source/images/glider_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_2.png -------------------------------------------------------------------------------- /doc/source/images/glider_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_3.png -------------------------------------------------------------------------------- /doc/source/images/glider_flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_flip.png -------------------------------------------------------------------------------- /doc/source/images/glider_gun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_gun.png -------------------------------------------------------------------------------- /doc/source/images/glider_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_h.png -------------------------------------------------------------------------------- /doc/source/images/glider_inserted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_inserted.png -------------------------------------------------------------------------------- /doc/source/images/glider_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_r.png -------------------------------------------------------------------------------- /doc/source/images/glider_t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_t.png -------------------------------------------------------------------------------- /doc/source/images/glider_v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/glider_v.png -------------------------------------------------------------------------------- /doc/source/images/linked_list.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/linked_list.pdf -------------------------------------------------------------------------------- /doc/source/images/nano-write-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/nano-write-out.png -------------------------------------------------------------------------------- /doc/source/images/nano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/nano.png -------------------------------------------------------------------------------- /doc/source/images/piazza_editor_choice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/piazza_editor_choice.png -------------------------------------------------------------------------------- /doc/source/images/piazza_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/piazza_issue.png -------------------------------------------------------------------------------- /doc/source/images/ring_buffer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/ring_buffer.pdf -------------------------------------------------------------------------------- /doc/source/images/stack.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/stack.pdf -------------------------------------------------------------------------------- /doc/source/images/vscode_extensions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/vscode_extensions.pdf -------------------------------------------------------------------------------- /doc/source/images/vscode_extensions.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/source/images/vscode_indent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/vscode_indent.png -------------------------------------------------------------------------------- /doc/source/images/vscode_workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/doc/source/images/vscode_workspace.png -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. only:: latex 2 | 3 | ======================================================== 4 | Object oriented programming in Python for mathematicians 5 | ======================================================== 6 | 7 | .. raw:: latex 8 | 9 | \frontmatter 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | 0_preface 15 | 16 | 17 | .. raw:: latex 18 | 19 | \mainmatter 20 | 21 | .. only:: html 22 | 23 | Welcome to the website for the book Object-oriented Programming in Python 24 | for Mathematicians. Here you'll find the full hyperlinked book text, as well 25 | as consolidated lists of the accompanying :doc:`videos ` and 26 | :doc:`exercise repositories `. 27 | 28 | .. image:: images/cover.png 29 | :width: 10em 30 | :align: right 31 | :target: https://www.amazon.co.uk/dp/B0CJXLFDFD 32 | 33 | The complete book text is available on this website. However, if you'd 34 | like to have a physical copy, then please `buy the book 35 | `__. 36 | 37 | .. container:: preface 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | 42 | 0_preface.rst 43 | 44 | .. toctree:: 45 | :numbered: 46 | :maxdepth: 2 47 | 48 | 1_introduction.rst 49 | 2_programs_in_files.rst 50 | 3_objects.rst 51 | 4_style.rst 52 | 5_abstract_data_types.rst 53 | 6_exceptions.rst 54 | 7_inheritance.rst 55 | 8_debugging.rst 56 | 9_trees_and_directed_acyclic_graphs.rst 57 | 10_further_object-oriented_features.rst 58 | 59 | .. raw:: latex 60 | 61 | \appendix 62 | 63 | .. container:: appendix 64 | 65 | .. toctree:: 66 | :numbered: 67 | :maxdepth: 2 68 | 69 | a1_help 70 | a2_git 71 | 72 | 73 | .. :numbered: 74 | .. :maxdepth: 1 75 | 76 | .. example_code 77 | .. fibonacci 78 | -------------------------------------------------------------------------------- /doc/source/installation.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | Installing the necessary software 4 | ================================= 5 | 6 | In order to do the exercises in this book, you will need Python, Git, and a 7 | suitable text editor or :term:`Integrated Development Environment`. Visual 8 | Studio Code is recommended as the :term:`IDE`. 9 | 10 | Instructions are provided here for Windows, MacOS, and Linux. Chromebook users 11 | can follow the Linux instructions if they first `activate Linux on their 12 | Chromebook `__. 13 | 14 | Homebrew for Mac 15 | ---------------- 16 | 17 | The easiest way to install additional programming software on a Mac is to first 18 | install the Homebrew package manager. Open a terminal (press :kbd:`⌘` + 19 | :kbd:`space` to open Spotlight Search and then type `terminal` in the search 20 | window) and run the following command: 21 | 22 | .. code-block:: console 23 | 24 | $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 25 | 26 | Don't type the :kbd:`$`. That's the terminal prompt (it might appear as another 27 | symbol such as :kbd:`%` for you). 28 | 29 | This will start the install process, and ask you for confirmation before 30 | installing Homebrew. 31 | 32 | Further documentation about Homebrew and its dependencies is available on the 33 | `Homebrew website `_. 34 | 35 | 36 | Python 37 | ------ 38 | 39 | There are a number of different ways of obtaining Python, depending a little on 40 | which operating system your computer runs. The routes suggested here are ones 41 | that have been easiest for students taking the course at Imperial, however any 42 | sufficiently recent Python should be sufficient. 43 | 44 | Windows 45 | ....... 46 | 47 | Install `Python from the Microsoft Store 48 | `__. 49 | 50 | MacOS 51 | ..... 52 | 53 | MacOS comes with Python 3, but it's a cut down version not suitable for our 54 | purposes. Instead, install Python from Homebrew: 55 | 56 | .. code-block:: console 57 | 58 | $ brew install python3.12 59 | 60 | 61 | Linux 62 | ..... 63 | 64 | Every Linux distribution ships with Python 3 by default. However, they don't 65 | always have the Python package manager Pip installed by default. We will need 66 | that so you'll need to use your distribution's package manager to install it. 67 | For example on Ubuntu or Debian you would run: 68 | 69 | .. code-block:: console 70 | 71 | $ sudo apt install python3-pip 72 | 73 | You can also install newer versions of Python on Ubuntu or Debian using the 74 | `dead snakes package archive `__. 75 | 76 | On Fedora and related distributions you would run: 77 | 78 | .. code-block:: console 79 | 80 | $ sudo dnf install python-pip 81 | 82 | Git 83 | --- 84 | 85 | Git is a revision control system. Revision control systems enable you to keep 86 | track of the different versions of a piece of code as you work on them, and to 87 | have these versions on different computers as well as backed up in the cloud. We 88 | will use Git and GitHub classroom as a mechanism for distributing, working with 89 | and submitting code exercises. 90 | 91 | Windows 92 | ....... 93 | 94 | Download and install the `Git package `__. 95 | 96 | MacOS 97 | ..... 98 | 99 | MacOS comes with a perfectly acceptable Git installation. However you can also 100 | install a more recent version from Homebrew: 101 | 102 | .. code-block:: console 103 | 104 | $ brew install git 105 | 106 | Linux 107 | ..... 108 | 109 | Use your distribution package manager to install Git. For example on Ubuntu or 110 | Debian: 111 | 112 | .. code-block:: 113 | 114 | $ sudo apt install git-all 115 | 116 | On Fedora: 117 | 118 | .. code-block:: 119 | 120 | $ sudo apt install git-all 121 | 122 | 123 | Visual Studio Code 124 | ------------------ 125 | 126 | Visual Studio Code is a Python-aware Integrated Development Environment (IDE). 127 | This means that it incorporates editing files with other programming features 128 | such as :ref:`debugging`, Git support, and built-in terminal. 129 | 130 | Windows 131 | ....... 132 | 133 | `Download and install the package `__. 134 | 135 | MacOS 136 | ..... 137 | 138 | Use Homebrew to install Visual Studio Code: 139 | 140 | .. code-block:: console 141 | 142 | $ brew install visual-studio-code 143 | 144 | 145 | Linux 146 | ..... 147 | 148 | `Download the package `__ and then use 149 | your package manager to install it `following these instructions 150 | `__. 151 | -------------------------------------------------------------------------------- /doc/source/quiz_material.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. code-block:: python3 4 | 5 | class a: 6 | def __init__(self, b): 7 | self.b = b 8 | 9 | def c(self): 10 | return float(self.b) 11 | 12 | 13 | d = a 14 | e = a(2) 15 | f = e.c() 16 | g = e.c 17 | 18 | 19 | .. code-block:: python3 20 | 21 | False if a and b else True 22 | 23 | .. code-block:: python3 24 | 25 | not (a and b) 26 | 27 | .. code-block:: python3 28 | 29 | not a and b 30 | 31 | .. code-block:: python3 32 | 33 | not a or not b 34 | 35 | .. code-block:: python3 36 | 37 | a and b 38 | 39 | .. code-block:: python3 40 | 41 | (not a) and b 42 | 43 | `not` has `and` 44 | 45 | `integrate` 46 | 47 | `IntegrationMeasure` 48 | 49 | `__hash__` 50 | 51 | `_prepare_integration` 52 | 53 | `problemDomain` 54 | 55 | `Lebesgue_Measure` 56 | 57 | .. code-block:: ipython3 58 | 59 | --------------------------------------------------------------------------- 60 | ZeroDivisionError Traceback (most recent call last) 61 | ~/traceback.py in 62 | 15 63 | 16 64 | ---> 17 print(b(5, 2, 0)) 65 | 66 | ~/traceback.py in b(x, y, z) 67 | 5 def b(x, y, z): 68 | 6 s = a(x, y) 69 | ----> 7 t = c(s, z) 70 | 8 return t 71 | 9 72 | 73 | ~/traceback.py in c(x, y) 74 | 11 def c(x, y): 75 | 12 if x > y: 76 | ---> 13 return c(x-1, y) 77 | 14 return a(x, y) 78 | 15 79 | 80 | ~/traceback.py in c(x, y) 81 | 11 def c(x, y): 82 | 12 if x > y: 83 | ---> 13 return c(x-1, y) 84 | 14 return a(x, y) 85 | 15 86 | 87 | ~/traceback.py in c(x, y) 88 | 11 def c(x, y): 89 | 12 if x > y: 90 | ---> 13 return c(x-1, y) 91 | 14 return a(x, y) 92 | 15 93 | 94 | ~/traceback.py in c(x, y) 95 | 12 if x > y: 96 | 13 return c(x-1, y) 97 | ---> 14 return a(x, y) 98 | 15 99 | 16 100 | 101 | ~/traceback.py in a(x, y) 102 | 1 def a(x, y): 103 | ----> 2 return x/y 104 | 3 105 | 4 106 | 5 def b(x, y, z): 107 | 108 | ZeroDivisionError: float division by zero 109 | 110 | 111 | .. code-block:: python3 112 | 113 | assert math.isclose(calc.peek(), answer, rel_tol=1.e-5), \ -------------------------------------------------------------------------------- /doc/source/refs.bib: -------------------------------------------------------------------------------- 1 | @article{Kirby2004, 2 | title = {Algorithm 839: FIAT, a new paradigm for computing 3 | finite element basis functions}, 4 | author = {Kirby, R.C.}, 5 | journal = {ACM Transactions on Mathematical Software (TOMS)}, 6 | volume = {30}, 7 | number = {4}, 8 | pages = {502--516}, 9 | year = {2004}, 10 | publisher = {ACM}, 11 | doi = {10.1145/1039813.1039820} 12 | } 13 | 14 | @Article{Logg2009, 15 | author = {A. Logg}, 16 | title = {Efficient representation of computational meshes}, 17 | journal = {International Journal of Computational Science and 18 | Engineering}, 19 | year = 2009, 20 | volume = 4, 21 | number = 4, 22 | pages = {283 -- 295}, 23 | doi = {10.1504/IJCSE.2009.029164} 24 | } 25 | 26 | @book{Ciarlet2002, 27 | title = {The finite element method for elliptic problems}, 28 | author = {Ciarlet, Philippe G}, 29 | year = {2002}, 30 | publisher = {Elsevier}, 31 | doi = {10.1137/1.9780898719208} 32 | } 33 | 34 | @Book{Deuflhard2011, 35 | author = {Deuflhard, Peter}, 36 | title = {Newton Methods for Nonlinear Problems}, 37 | publisher = {Springer}, 38 | doi = {10.1007/978-3-642-23899-4}, 39 | year = 2011} 40 | 41 | -------------------------------------------------------------------------------- /doc/source/texput.log: -------------------------------------------------------------------------------- 1 | This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex 2020.10.2) 18 NOV 2020 22:35 2 | entering extended mode 3 | restricted \write18 enabled. 4 | %&-line parsing enabled. 5 | **objectorientedprogramminginpythonformathematicians.tex 6 | 7 | ! Emergency stop. 8 | <*> ...tedprogramminginpythonformathematicians.tex 9 | 10 | End of file on the terminal! 11 | 12 | 13 | Here is how much of TeX's memory you used: 14 | 3 strings out of 479418 15 | 61 string characters out of 5884585 16 | 245340 words of memory out of 5000000 17 | 17624 multiletter control sequences out of 15000+600000 18 | 532338 words of font info for 24 fonts, out of 8000000 for 9000 19 | 1348 hyphenation exceptions out of 8191 20 | 0i,0n,0p,58b,6s stack positions out of 5000i,500n,10000p,200000b,80000s 21 | No pages of output. 22 | -------------------------------------------------------------------------------- /doc/source/videos.csv: -------------------------------------------------------------------------------- 1 | 1.1, `Setting up your virtual environment. `_ 2 | 2.1, `A first Python script. `_ 3 | 2.2, `A first Python module. `_ 4 | 2.3, `A first Python package. `_ 5 | 2.4, `Introducing Pytest. `_ 6 | 3.1, `A first class `_ 7 | 3.2, `Defining methods `_ 8 | 3.3, `Printing classes `_ 9 | 3.4, `Object equality and test driven development `_ 10 | 3.5, `Polynomial addition. `_ 11 | 4.1, `Why style? `_ 12 | 4.2, `Installing and using a linter. `_ 13 | 5.1, `Stacks as an abstract data type. `_ 14 | 5.2, `Dynamic arrays and algorithmic complexity. `_ 15 | 5.3, `Deques and ring buffers. `_ 16 | 5.4, `Linked lists. `_ 17 | 5.5, `The iterator protocol. `_ 18 | 6.1, `Errors and exceptions. `_ 19 | 6.2, `Tracebacks. `_ 20 | 6.3, `The call stack. `_ 21 | 6.4, `Raising an exception. `_ 22 | 6.5, `Handling exceptions. `_ 23 | 6.6, `Further exception handling. `_ 24 | 7.1, `Inheritance and composition. `_ 25 | 7.2, `An example from group theory. `_ 26 | 7.3, `Inheritance. `_ 27 | 8.1, `Using a graphical debugger. `_ 28 | 8.2, `Command line debuggers. `_ 29 | 8.3, `Minimal failing examples and bisection. `_ 30 | 9.1, `Splat and double splat. `_ 31 | 9.2, `Tree data structures. `_ 32 | 9.3, `Tree traversal. `_ 33 | 9.4, `Evaluating expressions. `_ 34 | 10.1, `Decorators. `_ 35 | 10.2, `Abstract base classes. `_ 36 | 10.3, `Virtual subclasses. `_ 37 | -------------------------------------------------------------------------------- /doc/source/videos.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _videos: 4 | 5 | Videos 6 | ====== 7 | 8 | This is the full list of videos accompanying Object-oriented Programming in 9 | Python for Mathematicians. The videos are also embedded in the web version of 10 | the book. 11 | 12 | .. csv-table:: 13 | :file: videos.csv 14 | :widths: auto -------------------------------------------------------------------------------- /example_code/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/object-oriented-python/object-oriented-programming/c7576c2be246f6272ea61e22143eacc7efc49a3d/example_code/__init__.py -------------------------------------------------------------------------------- /example_code/addable.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Addable(ABC): 5 | 6 | @abstractmethod 7 | def __add__(self, other): 8 | return NotImplemented 9 | 10 | @classmethod 11 | def __subclasshook__(cls, C): 12 | if cls is not Addable: 13 | return NotImplemented 14 | for B in C.__mro__: 15 | if "__add__" in B.__dict__: 16 | if B.__dict__["__add__"] is None: 17 | return NotImplemented 18 | return True 19 | return NotImplemented 20 | -------------------------------------------------------------------------------- /example_code/euclid.py: -------------------------------------------------------------------------------- 1 | def gcd(a, b): 2 | """Return the greatest common divisor of a and b using a recursive 3 | implementation of Euclid's algorithm.""" 4 | try: 5 | return gcd(b, a % b) 6 | except ZeroDivisionError: 7 | return a 8 | -------------------------------------------------------------------------------- /example_code/expression_tools.py: -------------------------------------------------------------------------------- 1 | from functools import singledispatch 2 | import expressions 3 | 4 | 5 | @singledispatch 6 | def evaluate(expr, *o, **kwargs): 7 | """Evaluate an expression node. 8 | 9 | Parameters 10 | ---------- 11 | expr: Expression 12 | The expression node to be evaluated. 13 | *o: numbers.Number 14 | The results of evaluating the operands of expr. 15 | **kwargs: 16 | Any keyword arguments required to evaluate specific types of 17 | expression. 18 | symbol_map: dict 19 | A dictionary mapping Symbol names to numerical values, for 20 | example: 21 | 22 | {'x': 1} 23 | """ 24 | raise NotImplementedError( 25 | f"Cannot evaluate a {type(expr).__name__}") 26 | 27 | 28 | @evaluate.register(expressions.Number) 29 | def _(expr, *o, **kwargs): 30 | return expr.value 31 | 32 | 33 | @evaluate.register(expressions.Symbol) 34 | def _(expr, *o, symbol_map, **kwargs): 35 | return symbol_map[expr.value] 36 | 37 | 38 | @evaluate.register(expressions.Add) 39 | def _(expr, *o, **kwargs): 40 | return o[0] + o[1] 41 | 42 | 43 | @evaluate.register(expressions.Sub) 44 | def _(expr, *o, **kwargs): 45 | return o[0] - o[1] 46 | 47 | 48 | @evaluate.register(expressions.Mul) 49 | def _(expr, *o, **kwargs): 50 | return o[0] * o[1] 51 | 52 | 53 | @evaluate.register(expressions.Div) 54 | def _(expr, *o, **kwargs): 55 | return o[0] / o[1] 56 | 57 | 58 | @evaluate.register(expressions.Pow) 59 | def _(expr, *o, **kwargs): 60 | return o[0] ** o[1] 61 | 62 | 63 | def postvisitor(expr, fn, **kwargs): 64 | '''Visit an Expression in postorder applying a function to every node. 65 | 66 | Parameters 67 | ---------- 68 | expr: Expression 69 | The expression to be visited. 70 | fn: `function(node, *o, **kwargs)` 71 | A function to be applied at each node. The function should take 72 | the node to be visited as its first argument, and the results of 73 | visiting its operands as any further positional arguments. Any 74 | additional information that the visitor requires can be passed in 75 | as keyword arguments. 76 | **kwargs: 77 | Any additional keyword arguments to be passed to fn. 78 | ''' 79 | return fn(expr, 80 | *(postvisitor(c, fn, **kwargs) for c in expr.operands), 81 | **kwargs) 82 | -------------------------------------------------------------------------------- /example_code/graphs.py: -------------------------------------------------------------------------------- 1 | """A simple tree implementation with basic pre- and post-visitors.""" 2 | 3 | 4 | class TreeNode: 5 | """A basic tree implementation. 6 | 7 | A tree is simply a collection of connected TreeNodes. 8 | 9 | Parameters 10 | ---------- 11 | value: 12 | An arbitrary value associated with this node. 13 | children: 14 | The TreeNodes which are the children of this node. 15 | """ 16 | 17 | def __init__(self, value, *children): 18 | self.value = value 19 | self.children = children 20 | 21 | def __repr__(self): 22 | """Return the canonical string representation.""" 23 | return f"{type(self).__name__}{(self.value,) + self.children}" 24 | 25 | def __str__(self): 26 | """Serialise the tree recursively as parent -> (children).""" 27 | childstring = ", ".join(map(str, self.children)) 28 | return f"{self.value!s} -> ({childstring})" 29 | 30 | 31 | def previsitor(tree, fn, fn_parent=None): 32 | """Traverse tree in preorder applying a function to every node. 33 | 34 | Parameters 35 | ---------- 36 | tree: TreeNode 37 | The tree to be visited. 38 | fn: function(node, fn_parent) 39 | A function to be applied at each node. The function should take 40 | the node to be visited as its first argument, and the result of 41 | visiting its parent as the second. 42 | """ 43 | fn_out = fn(tree, fn_parent) 44 | 45 | for child in tree.children: 46 | previsitor(child, fn, fn_out) 47 | 48 | 49 | def postvisitor(tree, fn): 50 | """Traverse tree in postorder applying a function to every node. 51 | 52 | Parameters 53 | ---------- 54 | tree: TreeNode 55 | The tree to be visited. 56 | fn: function(node, *fn_children) 57 | A function to be applied at each node. The function should take the 58 | node to be visited as its first argument, and the results of 59 | visiting its children as any further arguments. 60 | """ 61 | return fn(tree, *(postvisitor(c, fn) for c in tree.children)) 62 | -------------------------------------------------------------------------------- /example_code/groups.py: -------------------------------------------------------------------------------- 1 | """A module implementing the basic functionality of mathematical groups. 2 | 3 | This version of the module uses inheritance. 4 | """ 5 | 6 | from numbers import Integral 7 | import numpy as np 8 | 9 | 10 | class Element: 11 | """An element of the specified group. 12 | 13 | Parameters 14 | ---------- 15 | group: Group 16 | The group of which this is an element. 17 | value: 18 | The value of this entity. Valid values depend on the group. 19 | """ 20 | 21 | def __init__(self, group, value): 22 | group._validate(value) 23 | self.group = group 24 | self.value = value 25 | 26 | def __mul__(self, other): 27 | """Use * to represent the group operation.""" 28 | return Element(self.group, 29 | self.group.operation(self.value, 30 | other.value)) 31 | 32 | def __str__(self): 33 | """Return a string of the form value_group.""" 34 | return f"{self.value}_{self.group}" 35 | 36 | def __repr__(self): 37 | """Return the canonical string representation of the element.""" 38 | return f"{type(self).__name__}{self.group, self.value!r}" 39 | 40 | 41 | class Group: 42 | """A base class containing methods common to many groups. 43 | 44 | Each subclass represents a family of parametrised groups. 45 | 46 | Parameters 47 | ---------- 48 | n: int 49 | The primary group parameter, such as order or degree. The 50 | precise meaning of n changes from subclass to subclass. 51 | """ 52 | 53 | def __init__(self, n): 54 | self.n = n 55 | 56 | def __call__(self, value): 57 | """Create an element of this group.""" 58 | return Element(self, value) 59 | 60 | def __str__(self): 61 | """Return a string in the form symbol then group parameter.""" 62 | return f"{self.symbol}{self.n}" 63 | 64 | def __repr__(self): 65 | """Return the canonical string representation of the element.""" 66 | return f"{type(self).__name__}({self.n!r})" 67 | 68 | 69 | class CyclicGroup(Group): 70 | """A cyclic group represented by integer addition modulo n.""" 71 | 72 | symbol = "C" 73 | 74 | def _validate(self, value): 75 | """Ensure that value is an allowed element value in this group.""" 76 | if not (isinstance(value, Integral) and 0 <= value < self.n): 77 | raise ValueError("Element value must be an integer" 78 | f" in the range [0, {self.n})") 79 | 80 | def operation(self, a, b): 81 | """Perform the group operation on two values. 82 | 83 | The group operation is addition modulo n. 84 | """ 85 | return (a + b) % self.n 86 | 87 | 88 | class GeneralLinearGroup(Group): 89 | """The general linear group represented by n x n matrices.""" 90 | symbol = "G" 91 | 92 | def _validate(self, value): 93 | """Ensure that value is an allowed element value in this group.""" 94 | value = np.asarray(value) 95 | if not (value.shape == (self.n, self.n)): 96 | raise ValueError("Element value must be a " 97 | f"{self.n} x {self.n}" 98 | "square array.") 99 | 100 | def operation(self, a, b): 101 | """Perform the group operation on two values. 102 | 103 | The group operation is matrix multiplication. 104 | """ 105 | return a @ b 106 | -------------------------------------------------------------------------------- /example_code/groups_abc.py: -------------------------------------------------------------------------------- 1 | """A module implementing the basic functionality of mathematical groups. 2 | 3 | This version of the module uses inheritance and defines the base class as an 4 | :class:`abc.ABC`. 5 | """ 6 | 7 | from abc import ABC, abstractmethod 8 | from numbers import Integral 9 | import numpy as np 10 | 11 | 12 | class Element: 13 | """An element of the specified group. 14 | 15 | Parameters 16 | ---------- 17 | group: Group 18 | The group of which this is an element. 19 | value: 20 | The value of this entity. Valid values depend on the group. 21 | """ 22 | 23 | def __init__(self, group, value): 24 | group._validate(value) 25 | self.group = group 26 | self.value = value 27 | 28 | def __mul__(self, other): 29 | """Use * to represent the group operation.""" 30 | return Element(self.group, 31 | self.group.operation(self.value, 32 | other.value)) 33 | 34 | def __str__(self): 35 | """Return a string of the form value_group.""" 36 | return f"{self.value}_{self.group}" 37 | 38 | def __repr__(self): 39 | """Return the canonical string representation of the element.""" 40 | return f"{type(self).__name__}{self.group, self.value!r}" 41 | 42 | 43 | class Group(ABC): 44 | """A base class containing methods common to many groups. 45 | 46 | Each subclass represents a family of parametrised groups. 47 | 48 | Parameters 49 | ---------- 50 | n: int 51 | The primary group parameter, such as order or degree. The 52 | precise meaning of n changes from subclass to subclass. 53 | """ 54 | 55 | def __init__(self, n): 56 | self.n = n 57 | 58 | @property 59 | @abstractmethod 60 | def symbol(self): 61 | """Represent the group name as a character.""" 62 | pass 63 | 64 | @abstractmethod 65 | def _validate(self, value): 66 | """Ensure that value is an allowed element value in this Group.""" 67 | pass 68 | 69 | @abstractmethod 70 | def operation(self, a, b): 71 | """Return a ∘ b using the group operation ∘.""" 72 | pass 73 | 74 | def __call__(self, value): 75 | """Create an element of this group.""" 76 | return Element(self, value) 77 | 78 | def __str__(self): 79 | """Return a string in the form symbol then group parameter.""" 80 | return f"{self.symbol}{self.n}" 81 | 82 | def __repr__(self): 83 | """Return the canonical string representation of the element.""" 84 | return f"{type(self).__name__}({self.n!r})" 85 | 86 | 87 | class CyclicGroup(Group): 88 | """A cyclic group represented by integer addition modulo n.""" 89 | 90 | symbol = "C" 91 | 92 | def _validate(self, value): 93 | """Ensure that value is a legitimate element value in this group.""" 94 | if not (isinstance(value, Integral) and 0 <= value < self.n): 95 | raise ValueError("Element value must be an integer" 96 | f" in the range [0, {self.n})") 97 | 98 | def operation(self, a, b): 99 | """Perform the group operation on two values. 100 | 101 | The group operation is addition modulo n. 102 | """ 103 | return (a + b) % self.n 104 | 105 | 106 | class GeneralLinearGroup(Group): 107 | """The general linear group represented by n x n matrices.""" 108 | 109 | symbol = "G" 110 | 111 | def _validate(self, value): 112 | """Ensure that value is a legitimate element value in this group.""" 113 | value = np.asarray(value) 114 | if not (value.shape == (self.n, self.n)): 115 | raise ValueError("Element value must be a " 116 | f"{self.n} x {self.n}" 117 | "square array.") 118 | 119 | def operation(self, a, b): 120 | """Perform the group operation on two values. 121 | 122 | The group operation is matrix multiplication. 123 | """ 124 | return a @ b 125 | -------------------------------------------------------------------------------- /example_code/groups_basic.py: -------------------------------------------------------------------------------- 1 | """A module implementing the basic functionality of mathematical groups.""" 2 | 3 | from numbers import Integral 4 | import numpy as np 5 | 6 | 7 | class Element: 8 | """An element of the specified group. 9 | 10 | Parameters 11 | ---------- 12 | group: 13 | The group of which this is an element. 14 | value: 15 | The individual element value. 16 | """ 17 | def __init__(self, group, value): 18 | group._validate(value) 19 | self.group = group 20 | self.value = value 21 | 22 | def __mul__(self, other): 23 | """Use * to represent the group operation.""" 24 | return Element(self.group, 25 | self.group.operation(self.value, other.value)) 26 | 27 | def __str__(self): 28 | """Return a string of the form value_group.""" 29 | return f"{self.value}_{self.group}" 30 | 31 | def __repr__(self): 32 | """Return the canonical string representation of the element.""" 33 | return f"{type(self).__name__}{self.group, self.value!r}" 34 | 35 | 36 | class CyclicGroup: 37 | """A cyclic group represented by addition modulo group order.""" 38 | def __init__(self, order): 39 | self.order = order 40 | 41 | def _validate(self, value): 42 | """Ensure that value is an allowed element value in this group.""" 43 | if not (isinstance(value, Integral) and 0 <= value < self.order): 44 | raise ValueError("Element value must be an integer" 45 | f" in the range [0, {self.order})") 46 | 47 | def operation(self, a, b): 48 | """Perform the group operation on two values. 49 | 50 | The group operation is addition modulo n. 51 | """ 52 | return (a + b) % self.order 53 | 54 | def __call__(self, value): 55 | """Create an element of this group.""" 56 | return Element(self, value) 57 | 58 | def __str__(self): 59 | """Represent the group as Gd.""" 60 | return f"C{self.order}" 61 | 62 | def __repr__(self): 63 | """Return the canonical string representation of the group.""" 64 | return f"{type(self).__name__}({self.order!r})" 65 | 66 | 67 | class GeneralLinearGroup: 68 | """The general linear group represented by degree square matrices.""" 69 | 70 | def __init__(self, degree): 71 | self.degree = degree 72 | 73 | def _validate(self, value): 74 | """Ensure that value is an allowed element value in this group.""" 75 | if not (isinstance(value, np.ndarray), 76 | value.shape == (self.degree, self.degree)): 77 | raise ValueError("Element value must be a " 78 | f"{self.degree} x {self.degree}" 79 | "square array.") 80 | 81 | def operation(self, a, b): 82 | """Perform the group operation on two values. 83 | 84 | The group operation is matrix multiplication. 85 | """ 86 | return a @ b 87 | 88 | def __call__(self, value): 89 | """Create an element of this group.""" 90 | return Element(self, value) 91 | 92 | def __str__(self): 93 | """Represent the group as Gd.""" 94 | return f"G{self.degree}" 95 | 96 | def __repr__(self): 97 | """Return the canonical string representation of the group.""" 98 | return f"{type(self).__name__}({self.degree!r})" 99 | -------------------------------------------------------------------------------- /example_code/hello.py: -------------------------------------------------------------------------------- 1 | print("Hello World") 2 | -------------------------------------------------------------------------------- /example_code/linked_list.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class Link: 5 | def __init__(self, value, next=None): 6 | self.value = value 7 | self.next = next 8 | 9 | def insert(self, link): 10 | '''Insert a new link after the current one.''' 11 | 12 | link.next = self.next 13 | self.next = link 14 | 15 | def __iter__(self): 16 | return LinkIterator(self) 17 | 18 | 19 | class LinkIterator: 20 | def __init__(self, link): 21 | self.here = link 22 | 23 | def __iter__(self): 24 | return self 25 | 26 | def __next__(self): 27 | if self.here: 28 | next = self.here 29 | self.here = self.here.next 30 | return next.value 31 | else: 32 | raise StopIteration 33 | 34 | 35 | def byte_size(n): 36 | """Print the size in bytes of lists up to length n.""" 37 | data = [] 38 | for i in range(n): 39 | a = len(data) 40 | b = sys.getsizeof(data) 41 | print(f"Length:{a}; Size in bytes:{b}") 42 | data.append(i) 43 | -------------------------------------------------------------------------------- /example_code/polynomial.py: -------------------------------------------------------------------------------- 1 | from numbers import Number 2 | 3 | 4 | class Polynomial: 5 | 6 | def __init__(self, coefs): 7 | self.coefficients = coefs 8 | 9 | def degree(self): 10 | return len(self.coefficients) - 1 11 | 12 | def __str__(self): 13 | coefs = self.coefficients 14 | terms = [] 15 | 16 | # Degree 0 and 1 terms conventionally have different representation. 17 | if coefs[0]: 18 | terms.append(str(coefs[0])) 19 | if self.degree() > 0 and coefs[1]: 20 | terms.append(f"{coefs[1]}x") 21 | 22 | # Remaining terms look like cx^d, though factors of 1 are dropped. 23 | terms += [f"{'' if c == 1 else c}x^{d}" 24 | for d, c in enumerate(coefs[2:], start=2) if c] 25 | 26 | # Sum polynomial terms from high to low exponent. 27 | return " + ".join(reversed(terms)) or "0" 28 | 29 | def __repr__(self): 30 | return type(self).__name__ + "(" + repr(self.coefficients) + ")" 31 | 32 | def __eq__(self, other): 33 | return isinstance(other, Polynomial) and \ 34 | self.coefficients == other.coefficients 35 | 36 | def __add__(self, other): 37 | if isinstance(other, Number): 38 | return Polynomial((self.coefficients[0] + other,) 39 | + self.coefficients[1:]) 40 | 41 | elif isinstance(other, Polynomial): 42 | # Work out how many coefficient places the two polynomials have in 43 | # common. 44 | common = min(self.degree(), other.degree()) + 1 45 | # Sum the common coefficient positions. 46 | coefs = tuple(a + b for a, b in zip(self.coefficients[:common], 47 | other.coefficients[:common])) 48 | 49 | # Append the high degree coefficients from the higher degree 50 | # summand. 51 | coefs += self.coefficients[common:] + other.coefficients[common:] 52 | 53 | return Polynomial(coefs) 54 | 55 | else: 56 | return NotImplemented 57 | 58 | def __radd__(self, other): 59 | return self + other 60 | -------------------------------------------------------------------------------- /example_code/shapes.py: -------------------------------------------------------------------------------- 1 | '''A module containing some very simple shape classes to illustrate the use of 2 | :func:`super`.''' 3 | 4 | 5 | class Rectangle: 6 | def __init__(self, length, width): 7 | self.length = length 8 | self.width = width 9 | 10 | def area(self): 11 | return self.length * self.width 12 | 13 | def __repr__(self): 14 | return f"{self.__class__.__name__}{self.length, self.width!r}" 15 | 16 | 17 | class Square(Rectangle): 18 | def __init__(self, length): 19 | super().__init__(length, length) 20 | 21 | def __repr__(self): 22 | return f"{self.__class__.__name__}({self.length!r})" 23 | -------------------------------------------------------------------------------- /example_code/simple_classes.py: -------------------------------------------------------------------------------- 1 | '''A very elementary set of classes and objects for one of the week 3 quiz 2 | questions.''' 3 | 4 | 5 | class a: 6 | def __init__(self, b): 7 | self.b = b 8 | 9 | def c(self): 10 | return float(self.b) 11 | 12 | 13 | d = a 14 | e = a(2) 15 | f = e.c() 16 | g = e.c 17 | -------------------------------------------------------------------------------- /example_code/square.py: -------------------------------------------------------------------------------- 1 | def square(x): 2 | return x^2 3 | -------------------------------------------------------------------------------- /example_code/try_except.py: -------------------------------------------------------------------------------- 1 | def except_demo(n): 2 | """Demonstrate all the clauses of a `try` block.""" 3 | 4 | print(f"Attempting division by {n}") 5 | try: 6 | print(0./n) 7 | except ZeroDivisionError: 8 | print("Zero division") 9 | else: 10 | print("Division successful.") 11 | finally: 12 | print("Finishing up.") 13 | -------------------------------------------------------------------------------- /fibonacci/__init__.py: -------------------------------------------------------------------------------- 1 | from .fibonacci import fib 2 | -------------------------------------------------------------------------------- /fibonacci/fibonacci.py: -------------------------------------------------------------------------------- 1 | def fib(n): 2 | """Return the n-th Fibonacci number.""" 3 | if n == 0: 4 | return 0 5 | elif n == 1: 6 | return 1 7 | else: 8 | return fib(n-2) + fib(n-1) 9 | -------------------------------------------------------------------------------- /fibonacci/typesafe_fibonacci.py: -------------------------------------------------------------------------------- 1 | from numbers import Integral 2 | 3 | 4 | def typesafe_fib(n): 5 | """Return the n-th Fibonacci number, raising an exception if a 6 | non-integer is passed as n.""" 7 | if not isinstance(n, Integral): 8 | raise TypeError( 9 | f"fib expects an integer, not a {type(n).__name__}" 10 | ) 11 | if n == 0: 12 | return 0 13 | elif n == 1: 14 | return 1 15 | else: 16 | return typesafe_fib(n-2) + typesafe_fib(n-1) 17 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "oo-programming-exercises" 7 | version = "2022.0" 8 | authors = [ 9 | { name="David A. Ham", email="David.Ham@imperial.ac.uk" }, 10 | ] 11 | description= """ 12 | Code for Object oriented programming in Python for mathematicians.""" 13 | dependencies = ["numpy", "ipython"] 14 | license-file = "LICENSE.md" 15 | license = "CC-BY-4.0" 16 | 17 | [project.urls] 18 | "Homepage" = "https://object-oriented-python.github.io/" 19 | 20 | [project.optional-dependencies] 21 | all = [ 22 | "flake8", 23 | "pep8-naming", 24 | "flake8-docstrings", 25 | "pytest", 26 | "pandas", 27 | "ipdb", 28 | "debugpy", 29 | ] 30 | 31 | [tool.hatch.build.targets.wheel] 32 | packages = ["fibonacci", "example_code"] -------------------------------------------------------------------------------- /scripts/oo_convert_classroom: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | import json 3 | import yaml 4 | import os 5 | import copy 6 | from argparse import ArgumentParser 7 | 8 | 9 | yaml_template = { 10 | 'name': 'Autograding Tests', 11 | 'on': ['push', 'repository_dispatch'], 12 | 'permissions': {'checks': 'write', 'actions': 'read', 'contents': 'read'}, 13 | 'jobs': {'run-autograding-tests': {'runs-on': 'ubuntu-latest'}} 14 | } 15 | 16 | 17 | def report(runners): 18 | return { 19 | 'name': 'Autograding Reporter', 20 | 'uses': 'classroom-resources/autograding-grading-reporter@v1', 21 | 'env': {r.upper() + "_RESULTS": '${{steps.' + r + '.outputs.result}}' 22 | for r in runners}, 23 | 'with': {'runners': ", ".join(runners)} 24 | } 25 | 26 | 27 | step_header = [ 28 | {'name': 'Checkout code', 'uses': 'actions/checkout@v4'}, 29 | {'name': 'Install Python', 30 | 'uses': 'actions/setup-python@v5', 31 | 'with': {'python-version': '3.12'}} 32 | ] 33 | 34 | step_template = { 35 | 'uses': 'classroom-resources/autograding-command-grader@v1', 36 | 'with': { 37 | 'setup-command': '', 38 | 'command': '', 39 | 'timeout': 1, 40 | 'max-score': 0 41 | } 42 | } 43 | 44 | 45 | def convert_tests(tests): 46 | """Convert tests from old json to new yaml.""" 47 | steps = step_header.copy() 48 | for test in tests: 49 | step = copy.deepcopy(step_template) 50 | step["name"] = test["name"] 51 | step["id"] = test["name"] 52 | step["with"]["test-name"] = test["name"] 53 | step["with"]["setup-command"] = test["setup"] 54 | step["with"]["command"] = test["run"] 55 | step["with"]["timeout"] = test["timeout"] 56 | step["with"]["max-score"] = test["points"] 57 | steps.append(step) 58 | steps.append(report([test["name"] for test in tests])) 59 | 60 | tests_yaml = yaml_template.copy() 61 | tests_yaml['jobs']['run-autograding-tests']['steps'] = steps 62 | return tests_yaml 63 | 64 | 65 | if __name__ == "__main__": 66 | parser = ArgumentParser( 67 | description="""Convert old GitHub classroom autograding.json into""" 68 | """ new classroom.yml.""" 69 | ) 70 | parser.add_argument( 71 | "repository", type=str, action="store", 72 | help="The folder name of the repository to convert." 73 | ) 74 | args = parser.parse_args() 75 | 76 | with open(os.path.join( 77 | args.repository, ".github", "classroom", "autograding.json" 78 | ), "r") as infile: 79 | tests = json.load(infile) 80 | 81 | out_yaml = convert_tests(tests["tests"]) 82 | 83 | with open(os.path.join( 84 | args.repository, ".github", "workflows", "classroom.yml" 85 | ), "w") as outfile: 86 | for key in ['name', 'on', 'permissions', 'jobs']: 87 | outfile.write(yaml.dump({key: out_yaml[key]})) 88 | -------------------------------------------------------------------------------- /scripts/oo_doc_dependencies: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | if [[ $VIRTUAL_ENV ]]; 3 | then 4 | pip install sphinx sphinxcontrib-bibtex sphinxcontrib-proof \ 5 | sphinx-autobuild sphinxcontrib-youtube \ 6 | sphinxcontrib-blockdiag sphinx-reredirects 7 | pip install git+https://github.com/dham/sphinxcontrib-details-directive.git 8 | else 9 | echo ERROR: please activate the finite element course venv 10 | exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /scripts/oo_exercise_marks: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | import pandas 3 | from argparse import ArgumentParser 4 | import sys 5 | 6 | parser = ArgumentParser( 7 | description="""Import GitHub Classroom autotest""" 8 | """ results into Blackboard.""") 9 | parser.add_argument( 10 | "github", type=str, action="store", 11 | help="The CSV Grade file downloaded from GitHub Classroom." 12 | ) 13 | parser.add_argument( 14 | "blackboard", type=str, action="store", 15 | help="The CSV Grade file downloaded from Blackboard." 16 | ) 17 | parser.add_argument("--week", type=int, action="store", 18 | help="The week whose exercises we are marking.") 19 | parser.add_argument("--max-mark", type=int, action="store", 20 | help="The maximum mark achievable.") 21 | 22 | args = parser.parse_args() 23 | 24 | blackboard = pandas.read_csv(args.blackboard) 25 | 26 | try: 27 | mark_column = [k for k in blackboard.keys() 28 | if k.startswith(f"Week {args.week}")][0] 29 | except IndexError: 30 | sys.stderr.write(f'{args.blackboard} has no Week {args.week} column') 31 | 32 | github = pandas.read_csv(args.github) 33 | 34 | grade_map = {username: grade//args.max_mark or float("NaN") for username, grade 35 | in zip(github["roster_identifier"], github["points_awarded"])} 36 | 37 | grades = [grade_map.get(username, float("NaN")) 38 | for username in blackboard["Username"]] 39 | 40 | blackboard[mark_column].update(grades) 41 | 42 | blackboard.to_csv(f"marks_week_{args.week}.csv", index=False) 43 | -------------------------------------------------------------------------------- /scripts/oo_generate_wk9_data: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import pandas as pd 3 | import names 4 | import random 5 | from random import randint 6 | from random_word import RandomWords 7 | import datetime 8 | 9 | firstnames, surnames = zip(*[names.get_full_name().split() 10 | for i in range(150)]) 11 | 12 | uset = set() 13 | usernames = [] 14 | gitnames = [] 15 | uname = None 16 | for f, s in zip(firstnames, surnames): 17 | while not uname or uname in uset: 18 | uname = f[0] + s[0] + str(randint(1, 20)) + "18" 19 | usernames.append(uname) 20 | uset.add(uname) 21 | 22 | students = pd.DataFrame({ 23 | "FirstName": firstnames, 24 | "Surname": surnames, 25 | "Username": usernames 26 | }) 27 | students.to_csv("students.csv", index=False) 28 | 29 | r = RandomWords() 30 | 31 | for f, s, u in zip(firstnames, surnames, usernames): 32 | i = randint(1, 3) 33 | if i == 1: 34 | gitnames.append(u.lower()) 35 | elif i == 2: 36 | gitnames.append(f"{f}-{randint(1, 100)}") 37 | else: 38 | gitnames.append(r.get_random_word(includePartOfSpeech="noun")) 39 | 40 | ug = list(zip(usernames, gitnames)) 41 | random.shuffle(ug) 42 | usernames, gitnames = zip(*ug) 43 | usernames = map(str.lower, usernames[:-10]) 44 | gitnames = list(gitnames[:-10]) 45 | 46 | gitmap = pd.DataFrame({ 47 | "ImperialID": usernames, 48 | "GitHubID": gitnames 49 | } 50 | ) 51 | 52 | gitmap.to_csv("gitnames.csv", index=False) 53 | 54 | random.shuffle(gitnames) 55 | gitnames = gitnames[:-10] 56 | 57 | time = [] 58 | timezones = [datetime.timezone(datetime.timedelta(hours=h)) 59 | for h in (0, 1, 8)] 60 | 61 | submissiontimes = [] 62 | 63 | for g in gitnames: 64 | if randint(1, 10) == 1: 65 | submissiontimes.append(None) 66 | else: 67 | submissiontimes.append(str(datetime.time( 68 | 14, randint(15, 50), randint(0, 59), 00, 69 | tzinfo=timezones[randint(0, 2)]))) 70 | 71 | pd.DataFrame({ 72 | "User": gitnames, 73 | "SubmissionTime": submissiontimes 74 | }).to_csv("submissions.csv") 75 | -------------------------------------------------------------------------------- /scripts/oo_install_venv: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | if [ $# -eq 0 ] 4 | then 5 | echo "Please pass a name for your venv as the first argument." 6 | fi 7 | 8 | python3 -m venv $1 --without-pip 9 | . $1/bin/activate 10 | curl https://bootstrap.pypa.io/get-pip.py | python3 11 | $1/bin/pip install -U pip 12 | $1/bin/pip install ipython matplotlib numpy scipy pytest 13 | $1/bin/pip install -e $(dirname $0)/.. 14 | -------------------------------------------------------------------------------- /scripts/oo_install_venv_win: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | if [ $# -eq 0 ] 4 | then 5 | echo "Please pass a name for your venv as the first argument." 6 | fi 7 | 8 | python -m venv $1 --without-pip 9 | . $1/Scripts/activate 10 | curl https://bootstrap.pypa.io/get-pip.py | python 11 | $1/Scripts/pip install -U pip 12 | $1/Scripts/pip install ipython matplotlib numpy scipy pytest 13 | $1/Scripts/pip install -e $(dirname $0)/.. 14 | -------------------------------------------------------------------------------- /scripts/oo_repo_tool: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import github # Install pygithub 4 | import git # Install gitpython 5 | from argparse import ArgumentParser 6 | import subprocess 7 | import sys 8 | 9 | parser = ArgumentParser( 10 | description="""Helper script to mark finite element assignments.""") 11 | parser.add_argument( 12 | "--update", action="store_true", help="Update all student repositories.") 13 | parser.add_argument( 14 | "--push-masters", action="store_true", 15 | help="Push the master branch of all student repos to the instructor repo.") 16 | parser.add_argument("--checkout", type=str, action="store", metavar=("REPO"), 17 | help="checkout finite-element/fe-%d-REPO." % 0) 18 | parser.add_argument("--test", action="store_true", help="Execute tests") 19 | parser.add_argument("-x", action="store_true", help="Stop on first test fail") 20 | parser.add_argument("--week", type=str, action="store", required=True, 21 | help="Week whose repositories should be cloned.") 22 | args = parser.parse_args() 23 | 24 | repo = git.Repo(".") 25 | 26 | if args.update: 27 | g = github.Github(os.environ["GITHUB_OAUTH"]) 28 | org = g.get_organization("Imperial-MATH50009") 29 | count = 0 30 | 31 | for r in org.get_repos(): 32 | if r.name.startswith("exercises-week-%s" % args.week): 33 | count += 1 34 | uname = r.name[10:] 35 | print("Looking for remote %s" % uname) 36 | try: 37 | remote = repo.remote(uname) 38 | print("Found") 39 | except ValueError: 40 | print("Not found. Creating") 41 | remote = repo.create_remote(uname, r.ssh_url) 42 | print("Fetching") 43 | remote.fetch() 44 | print(f"{count} repos found.") 45 | 46 | if args.push_masters: 47 | g = github.Github(os.environ["GITHUB_OAUTH"]) 48 | org = g.get_organization("finite-element") 49 | 50 | remote = repo.remote(instructor) 51 | 52 | for r in org.get_repos(): 53 | if r.name.startswith("fe-%d" % year): 54 | uname = r.name[8:] 55 | print("Pushing master for remote %s" % uname) 56 | remote.push("remotes/{0}/master:refs/heads/{0}-master".format(uname)) 57 | 58 | 59 | if args.checkout: 60 | user = args.checkout 61 | print("Checking out head for %s" % user) 62 | head = repo.create_head(user, commit="/%s/implementation" % user) 63 | repo.head.reference = head 64 | repo.head.reset(working_tree=True) 65 | print("success") 66 | 67 | if args.test: 68 | os.environ["PYTHONPATH"] = repo.working_tree_dir 69 | test_args = ["-x"] if args.x else [] 70 | try: 71 | subprocess.check_output(["py.test"] + test_args) 72 | except subprocess.CalledProcessError as e: 73 | sys.stdout.write(e.output.decode("utf8")) 74 | -------------------------------------------------------------------------------- /scripts/oo_test_report: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Create a report of when students submitted a test.""" 3 | import pandas as pd 4 | import os 5 | 6 | 7 | def read_data(filename): 8 | """Read in CSV files from the data folder.""" 9 | pd.read_csv(os.path.join( 10 | os.path.dirname(__file__), "..", "data", filename)) 11 | 12 | 13 | class_list = read_data("students.csv") 14 | submissions = read_data("submissions.csv") 15 | git_names = read_data("submissions.csv") 16 | 17 | # Create a mapping from Imperial usernames to GitHub names. 18 | name_map = {imperial: git 19 | for imperial, git in zip(git_names["ImperialID", "GitHubID"])} 20 | 21 | # Map GitHub names to submission times. 22 | submissions_map = { 23 | git: time for git, time in zip(git_names["User", "SubmissionTime"]) 24 | } 25 | 26 | # For each student in the class, find their submission time. 27 | submission_times = [submissions_map[name_map[id]] 28 | for id in class_list["Username"]] 29 | submission_times = pd.Series(submission_times, name="SubmissionTimes") 30 | 31 | report = pd.DataFrame([class_list["Firstname"], 32 | class_list["Surname"], 33 | class_list["Username"], 34 | submission_times]) 35 | 36 | print("Report complete.") 37 | -------------------------------------------------------------------------------- /scripts/run_fibonacci.py: -------------------------------------------------------------------------------- 1 | from fibonacci import fib 2 | 3 | print(fib(4)) 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | addopts = "--pdbcls=IPython.terminal.debugger:Pdb" 3 | filterwarnings = 4 | ignore:the matrix subclass:PendingDeprecationWarning 5 | 6 | [flake8] 7 | exclude = doc 8 | extend-ignore = D100,D101,D102,D103,D104,D105,D106,D107 9 | -------------------------------------------------------------------------------- /tests/test_fibonacci.py: -------------------------------------------------------------------------------- 1 | from fibonacci import fib 2 | 3 | 4 | def test_fibonacci_values(): 5 | 6 | for i, f in enumerate([1, 1, 2, 3, 5, 8]): 7 | assert fib(i+1) == f 8 | -------------------------------------------------------------------------------- /tests/test_fibonacci_parametrised.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from fibonacci import fib 3 | 4 | 5 | @pytest.mark.parametrize("n, ans", enumerate((0, 1, 1, 2, 3, 5, 8))) 6 | def test_fibonacci(n, ans): 7 | assert fib(n) == ans 8 | -------------------------------------------------------------------------------- /tests/test_linked_list.py: -------------------------------------------------------------------------------- 1 | from example_code.linked_list import Link 2 | 3 | def test_linked_list(): 4 | 5 | linked_list = Link(1, Link(2, Link(3))) 6 | 7 | assert list(linked_list) == [1, 2, 3] 8 | -------------------------------------------------------------------------------- /tests/test_numpoly.py: -------------------------------------------------------------------------------- 1 | """Basic proof of life check for numpoly.""" 2 | 3 | 4 | def test_numpoly(): 5 | import numpoly 6 | x = numpoly.symbols("x") 7 | p = x**2 + 3*x + 1 8 | 9 | assert numpoly.diff(p, x) == 2*x + 3 10 | -------------------------------------------------------------------------------- /tests/test_pandas_fail.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import os 3 | 4 | 5 | def test_pandas_fail(): 6 | data = pd.read_csv(os.path.join(os.path.dirname(__file__), 7 | "..", "data", "students.csv")) 8 | 9 | usernames = data["UIDs"] 10 | 11 | assert "LB818" in usernames --------------------------------------------------------------------------------