├── README.md ├── course-info.md ├── deliverables ├── 1 │ ├── deliverable1.md │ └── grading_rubric.txt ├── 2 │ ├── deliverable2.md │ └── grading_rubric.txt ├── 3 │ ├── deliverable3.md │ └── grading_rubric.txt ├── 4 │ ├── deliverable4.md │ └── grading_rubric.txt ├── 5 │ ├── deliverable5.md │ └── grading_rubric.txt └── 6 │ ├── deliverable6.md │ └── grading_rubric.txt ├── exercises ├── TicTacToe.java ├── TicTacToeAnswer.java ├── command_line_exercise.md ├── git911-answers.md ├── git911.md ├── gradle-exercise.md ├── swing_exercise.md └── threads-exercise │ ├── Pi.java │ ├── hints.md │ └── threads-exercise.md ├── how_to_sign_up.md ├── lectures ├── A_Friendly_Introduction_to_Git_And_GitHub.pdf ├── CS1530_Fiat_Voluntas_Tua.pdf ├── CS1530_Lecture10-11_Methodologies.pdf ├── CS1530_Lecture11_QA_Quality_Software.pdf ├── CS1530_Lecture12_SoftwareDesign.pdf ├── CS1530_Lecture13_OO_Design.pdf ├── CS1530_Lecture14_Integration.pdf ├── CS1530_Lecture15_Concurrency.pdf ├── CS1530_Lecture16_Concurrency2.pdf ├── CS1530_Lecture17_Legacy_Code.pdf ├── CS1530_Lecture18_DesignPatterns.pdf ├── CS1530_Lecture18_SoftwareCraftsmanship.pdf ├── CS1530_Lecture2_SDLC.pdf ├── CS1530_Lecture3_AgileScrum.pdf ├── CS1530_Lecture4_StakeholderInteraction.pdf ├── CS1530_Lecture7_GradleBuildTool.pdf ├── CS1530_Lecture8_TDD.pdf ├── CS1530_Lecture9_OOTDDEngineering.pdf └── lecture1-intro.md ├── project_groups.md ├── sample_code ├── DecoratorDemo.java ├── complexity │ ├── Foo2.asm │ ├── Foo2.bytecode │ └── Foo2.java ├── concurrency │ ├── Atomic.java │ ├── BadConcurrency.java │ ├── BetterConcurrency.java │ ├── ConcurrentCalculator.java │ ├── ConcurrentHashMapDemo.java │ ├── DavidConcurrency.java │ ├── Deadlock.java │ ├── FixedDeadlock.java │ ├── HowManyThreads.java │ ├── Increment.java │ ├── JoinDemo.java │ ├── Livelock.java │ ├── LolWut.java │ ├── MethodLevelConcurrency.java │ ├── SimpleThread.java │ ├── SynchronousCalculator.java │ ├── ThreadedHashMap.java │ ├── Timer.java │ └── TimerActual.java ├── hash │ ├── HashMapDemo.java │ ├── Hashing.java │ ├── Hashtable.java │ └── HashtableDemo.java └── unit_tests │ ├── LinkedList.java │ ├── LinkedListTest.java │ └── Node.java ├── study_guides ├── midterm_1_study_guide.md └── midterm_2_study_guide.md └── syllabus.md /README.md: -------------------------------------------------------------------------------- 1 | # CS1530_Spring2017 2 | CS1530 Software Engineering, Spring 2017 3 | -------------------------------------------------------------------------------- /course-info.md: -------------------------------------------------------------------------------- 1 | # CS 1530 - Spring 2017 2 | Software Engineering 3 | 4 | ## Course Information 5 | 6 | **Taught by:** Bill Laboon ([laboon@cs.pitt.edu](mailto:laboon@cs.pitt.edu)) 7 | 8 | **Professor's Office Hours:** 9 | 10 | * SENSQ 6305 11 | * Monday and Wednesday 2:30 - 4:00 PM 12 | * ...or by appointment. 13 | 14 | **Class Time:** MW 9:30 AM - 10:45 PM 15 | 16 | **Room:** SENSQ 6110 17 | 18 | **TA:** Adam Hobaugh 19 | 20 | **Class GitHub repo:** [https://www.github.com/laboon/cs1530_Spring2017](https://www.github.com/laboon/CS1530_Spring2017) 21 | 22 | **Required Texts:** 23 | * Growing Object-Oriented Software, Guided by Tests. Authors: Steve Freeman and Nat Pryce. ISBN 9780321503626 24 | 25 | * Code Complete (Second Edition). Author: Steve McConnell. ISBN 0790145196705 26 | 27 | * Online essays/articles will also be assigned. 28 | 29 | This course provides students with a broad understanding of modern software engineering. Although it will cover theory, the emphasis is on providing practical skills in software engineering currently used in industry. To that end, it will cover project and product management, software architecture and design patterns, team communications, and other material relevant to __engineering__ software instead of just __coding__ it. 30 | 31 | ## Grading 32 | 33 | * Mid-term Exam 1 - 15% 34 | * Mid-term Exam 2 - 15% 35 | * Group Project: 36 | * Sprint 1 Deliverable - 10% 37 | * Sprint 2 Deliverable - 10% 38 | * Sprint 3 Deliverable - 10% 39 | * Sprint 4 Deliverable - 10% 40 | * Sprint 5 Deliverable - 10% 41 | * Final Deliverable and Presentation - 15% 42 | * Class Participation - 5% (Exercises and Guest Lecture attendance) 43 | 44 | It is strongly recommended that you come to class each for each lecture. Material may be presented or covered in class that is not in the reading. I also expect active participation in class (there will be various projects done in class). However, I will only take roll for the class exercise days. On these days, attendance and participation is mandatory. 45 | 46 | The syllabus is subject to modification if circumstances dictate (e.g. a guest lecturer is unable to make the scheduled day). 47 | 48 | The following grading scale will be used. 49 | 50 | Score | Grade 51 | -----: | ------------------------------ 52 | 100.00-94.00 | A (A+ for extraordinary work) 53 | 93.99-91.00 | A- 54 | 90.99-88.00 | B+ 55 | 87.99-84.00 | B 56 | 83.99-81.00 | B- 57 | 80.99-78.00 | C+ 58 | 77.99-74.00 | C 59 | 73.99-71.00 | C- 60 | 70.99-68.00 | D+ 61 | 67.99-64.00 | D 62 | 63.99-61.00 | D- 63 | 60.99-0.00 | F 64 | 65 | All groups are expected to do their own work on the group project, but are more than welcome to collaborate and ask questions with other groups, the Internet, or other colleagues. Projects may be analyzed with the Stanford _moss_ system to detect unauthorized collaboration between groups. 66 | 67 | However, any student caught collaborating or cheating on an exam will automatically receive a 0 (zero) for that exam, and may be penalized more harshly based on University of Pittsburgh academic policy. 68 | 69 | Note that there are two mid-terms, and no final exams. The second mid-term exam will not be cumulative. 70 | 71 | It is recommended you keep all of your graded assignments until final grades are posted and accepted, in order to resolve any discrepancies in grading. 72 | 73 | ## Readings 74 | 75 | Readings are listed in the syllabus.md file for each day. The instructor may not mention the reading for the next class. The onus is on you to review the syllabus and do the appropriate reading before class. 76 | 77 | ## Attendance 78 | 79 | Presence for the mid-term exams and class exercises are REQUIRED. They will be individually re-scheduled only in the event of an emergency. If you are facing an emergency, please contact the instructor IMMEDIATELY (if it is safe to do so, of course). Failure to show up for an exam without clearing it first with the instructor will result in a 0 (zero) for that exam or exercise. 80 | 81 | ## Group Project Details 82 | 83 | Students will be grouped into groups of approximately 4 or 5, and will work on a project for the duration of the course. There will be several sprints, at the end of each of which the students will have a working version of their software available on GitHub or GitLab, as well as documentation and other information (specified for each particular sprint). 84 | 85 | Deliverables must be committed to GitHub or GitLab by the beginning of class on the day that it is due. Late deliverables will NOT be accepted unless authorized __at least 24 hours before the due date__. 86 | 87 | ## Extra Credit 88 | 89 | Bonus points (at the discretion of the instructor) will be given if you give a talk to a programming meetup, the Pitt Computer Science club, or a conference. 90 | 91 | If you are looking to do this, I recommend you start early to prepare a talk and set up a time with the organization. 92 | 93 | I do not give retroactive or other extra credit. If you are interested in extra credit, here is your opportunity! 94 | 95 | ## Programming Language Selection 96 | 97 | All software projects for this course will be written in the Java language (version 1.8). Additionally, we will be using associated tools, libraries and frameworks such as Swing, Gradle and JUnit. These will be discussed in class. 98 | 99 | ## Collaborative Programming 100 | 101 | Note that all works produced by you are your intellectual property and you may do what you want with it. However, this class is collaborative. You may need to show and share your work to other students under the direction of the instructor. 102 | 103 | ## Disability Services Statement 104 | 105 | "The Office of Disability Resources and 106 | Services (DRS) provides a broad range of support services to assist 107 | students with disabilities. Services include, but are not limited to, 108 | tape-recorded textbooks, sign language interpreters, adaptive and 109 | transportation. Contact DRS at 412-648-7890 or 412-383-1355 (TTY) in 110 | 216 William Pitt Union or see www.drs.pitt.edu for more computer 111 | technology, Braille translation, and nonstandard exam arrangements, 112 | DRS can also assist students with accessibility to campus housing 113 | information." 114 | 115 | ## Academic Integrity Statement 116 | 117 | "As members of the University of 118 | Pittsburgh community, A&S students are expected to meet the obligation 119 | to exhibit honesty and to respect the ethical standards of the 120 | University community and of their chosen field of study in carrying 121 | out academic assignments. A&S students are therefore expected to 122 | familiarize themselves with the published rules and regulations go to 123 | http://www.provost.pitt.edu/info/acguidelinespdf.pdf 124 | 125 | -------------------------------------------------------------------------------- /deliverables/1/deliverable1.md: -------------------------------------------------------------------------------- 1 | # CS/COE 1530 - Software Engineering 2 | Spring Semester 2017 3 | 4 | ## DUE DATE: 1 FEB 2017 5 | 6 | ## Deliverable 1 7 | 8 | For the first sprint, each group will need to: 9 | 10 | 1. Determine initial user stories for the project, including prioritization 11 | 2. Write a walking skeleton and prototype UI of the application using gradle, which should include unit tests 12 | 3. Write about the various decisions that the group came to, and how they did so 13 | 14 | The team should determine the Scrum Master for this first sprint. The Scrum Master will change each sprint. 15 | 16 | ## Format 17 | 18 | For the first sprint, you will turn in: 19 | 20 | 1. A cover page, in the format described below 21 | 2. A backlog of user stories, ranked by prioritization (highest priority first) 22 | 3. A description of decisions made in the sprint 23 | 3. A "walking skeleton" application available on GitHub or GitLab (ADD ME AS A COLLABORATOR! Username on either site is "laboon"). This should include a basic UI of the program - note that this does not need to have any functionality asociated with it, and it may change in the future. 24 | 25 | Each of these paper sections shall be CLEARLY MARKED (i.e. they should each have titles and start on their own page). 26 | 27 | Format for cover page: 28 | * The title "*your team name* - SPRINT 1 DELIVERABLE" 29 | * The names of the people in the group, and their GitHub or GitLab username. Mark down who the Scrum Master is this sprint, e.g. "Jane Doe (Scrum Master)" 30 | * The date that it is due (1 FEB 2017) 31 | 32 | ## Grading 33 | * User Stories and Ranking: 25% of grade 34 | * Walking Skeleton: 50% of grade 35 | * Description of Decisions: 25% of grade 36 | 37 | User stories shall be in the Connextra template ("As a.. I want.. so that..") and provide good, user-level descriptions of user needs and wants. User stories should be printed in order of priority. It is NOT expected that you will complete every single user story, or even that these are the final versions of the user story; they may change and be prioritized differently as the sprints go on. 38 | 39 | User stories should flow from the needs of the customer. Your discussions with the customer should guide the user stories themselves as well as their prioritization. 40 | 41 | The number of user stories will vary based on the project, but it should be at least eight at the VERY minimum. If there are fewer than eight stories, the project may be too small or your user stories too big. 42 | 43 | The walking skeleton __must__ compile and show a basic UI for the application. It should follow the general outline of a walking skeleton as discussed in GOOSGBT (specifically, it just needs to display the basic outline of a frame and have at least one test) . You can have more functionality if you like, but it is essential that your program compiles, runs and displays a basic UI without error! 44 | 45 | The walking skeleton __must__ be able to run on __everybody's__ computer! Everybody should have access to the repository on GitHub and able to make commits by the end of this sprint. 46 | 47 | The description of decisions should be, at an absolute minimum, one page of text. It should include any background research you did on the domain, your interactions with the customer, and your team's opinions on prioritization. Be sure to include any __disagreement__ your team had internally! Software engineering is rarely without some sort of disagreement about the direction of the software. 48 | 49 | The description of decisions should also indicate what you think is effective and ineffective during this sprint, and what you plan to do about these going forward. For example, stand-ups took up too much time so we're shortening them, people were stepping over each other's code so the team is going to use a different branching model, etc. This concept of continuous improvement is important to the Scrum methodology. 50 | 51 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. Yes, this is important. 52 | 53 | The needs of the user/customer (i.e., Bill Laboon) will be determined in class by interviewing the user/customer (once again, i.e., Bill Laboon). 54 | 55 | ## The Game 56 | 57 | In this class, we are going to make a Java version of the ancient Norse game, hnefatafl("table of the fist", in Old Norse). We will play by Copenhagen rules - that is, an 11 x 11 square board, and the king must reach a corner to win. Rules for the game can be found here: http://aagenielsen.dk/copenhagen_rules.php. 58 | 59 | We will start by allowing player vs player on the same computer. Future functionality may include playing the computer (AI), playing by email (correspondence), or via a server. 60 | 61 | There should be a way to save and load games locally. 62 | 63 | Further details on what other features, functionality, etc. may be found by interviewing the customer/user during the stakeholder interaction exercise. 64 | 65 | ## Other 66 | 67 | I recommend you use the Java Swing framework for the graphical user interface (this is not technically necessary, but many students have already learned Swing for their CS0401 class, and I can help you with it). You can use the following repository to either brush up on your Swing or learn it on your own: https://github.com/laboon/GameOfLife This contains a graphical version of Conway's Game of Life. 68 | 69 | The following files from my CS0401 class may also be helpful as examples: 70 | 71 | 1. Frames - https://github.com/laboon/cs0401/blob/master/sample_code/FrameDemo.java 72 | 1. Panels - https://github.com/laboon/cs0401/blob/master/sample_code/PanelDemo.java and https://github.com/laboon/cs0401/blob/master/sample_code/PanelDemo2.java 73 | 2. Extending Panels - https://github.com/laboon/cs0401/tree/master/sample_code/extended_jpanel 74 | 3. Creating and Interacting with Buttons - https://github.com/laboon/cs0401/blob/master/sample_code/ButtonDemo.java 75 | 4. Creating a Grid Layout - https://github.com/laboon/cs0401/blob/master/sample_code/GridDemo.java 76 | 5. Dynamically Changing A Button - https://github.com/laboon/cs0401/blob/master/sample_code/NameChangeButtonDemo.java 77 | 78 | Please feel free to email me or come to office hours to discuss any problems you have. 79 | -------------------------------------------------------------------------------- /deliverables/1/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D1 2 | 3 | * User Stories: 25% of grade 4 | 5 | User Stories in correct format: _____ / 5 6 | * As a.. I want.. So that.. 7 | * -2 for each one not in correct format 8 | 9 | User stories mention USER needs/ 10 | from user perspective: _____ / 15 11 | * Not from a developer perspective 12 | * Reference specific functionality 13 | * -3 for each one not from user perspective 14 | 15 | Clearly written: _____ / 5 16 | * No typos / misspellings / etc 17 | * Understandable to reader (incl. clear sentence structure) 18 | 19 | If < 8 user stories, -5 for each one less than 8 20 | 21 | * Walking Skeleton: 50% of grade 22 | 23 | Gradle/git setup correct ______ / 20 24 | * gradle {build,test,clean,run} all work w/o error 25 | * -5 for each that fails/returns an error 26 | 27 | At least one passing unit test: ______ / 15 28 | * -5 if there are test, but contain failures 29 | 30 | GUI displays: ______ / 15 31 | * A GUI should appear when "gradle run" is typed 32 | * If none, -15 33 | 34 | * Description of Decisions: 25% of grade 35 | 36 | Description of background research: ______ / 6 37 | 38 | Description of prioritization of user stories: ______ / 6 39 | 40 | Describe effective/ineffective item(s) in sprint: ______ / 8 41 | 42 | General quality: ______ / 5 43 | * No typos (-1 for each past the first) 44 | * No grammatical errors (-1 for each past the first) 45 | * Generally easy to read 46 | 47 | -5 if this is not ~1 page of text; -15 if less than half a page 48 | 49 | Other: 50 | 51 | Improper format for title page: 52 | * -2 does not list Scrum Master 53 | * -5 does not list GitHub usernames of team members 54 | 55 | Total: ____ / 100 56 | -------------------------------------------------------------------------------- /deliverables/2/deliverable2.md: -------------------------------------------------------------------------------- 1 | ## CS/COE 1530 - Software Engineering 2 | ### Spring Semester 2017 3 | 4 | ### DUE DATE: 15 FEB 2017 5 | 6 | ### Deliverable 2 7 | 8 | For the second sprint, each group will start implementing user stories on top of the walking skeleton developed for the first sprint. You will also turn in several other reports - see the Format section, below. 9 | 10 | NOTE: If I see nothing from you in the git commit history for a sprint in master, and you cannot explain and prove it (e.g., you focused on documentation this sprint with the agreement of your teammates, work was done in another branch but couldn't be merged to master, etc.), then you may get a 0 for the entire sprint. 11 | 12 | ### Format 13 | 14 | For the second sprint, you will turn in: 15 | 16 | 1. A cover page, in the format described below 17 | 2. An approximately one or two page description of what was accomplished this sprint. This can (but is not limited to) cover details such as: 18 | 1. How teams communicated 19 | 1. What disagreements arose 20 | 1. How problems were resolved 21 | 1. Changes in process since first sprint 22 | 1. Interactions with customer 23 | 1. Challenges writing the code or tests 24 | 1. Design patterns or architectural patterns used 25 | 1. Anything else that might be of interest 26 | 3. User stories completed this sprint, along with their indicated number of story points and total velocity 27 | 4. A *link to the code on GitHub/GitLab*. If I or the TA (Adam Hobaugh) cannot access it (that is, usernames laboon and greenmanspirit are not added as a collaborator), there is an automatic -15 point deduction. 28 | 4. Details on why you decided on those user stories 29 | 5. A list of any defects found (by unit testing, manual testing, or by developers), and how they were discovered and fixed (or if not fixed, why you decided not to fix them this sprint). This can include defects found by unit testing or system testing by QA (or other methods, such as issues found by the customer). If no defects were found, then please write a paper on how you have developed a way to develop software without making any mistakes, because I would be happy to read it! 30 | 31 | Each of these sections shall be CLEARLY MARKED (i.e. they should each have titles and start on their own page). 32 | 33 | Remember that user stories are not to be marked as complete until they meet the DEFINITION OF DONE - that is, they have been developed, tested, and reviewed according to the plan laid out in the first deliverable. 34 | 35 | Remember to use the 1-2-4-8-16 story point format, where 16 points is one developer working only on one story for a sprint. 36 | 37 | Remember that your main goal is to deliver a working version of the software (i.e., can be compiled and executed on any individual member's computer). Think about that when planning and prioritizing! During the in-class retrospective and sprint planning session, you can apportion responsibilities, agree on the story ordering, etc. 38 | 39 | If I have any questions on the code, I may ask *any* individual member to show me the code running on their computer. Therefore, if anyone has a problem running the current version of the code, that fact needs to be included as a defect. Failure to have a working version of the project at end of sprint may mean a drastically lower score for the project. 40 | 41 | Code should not be merged to master without the approval of at least ONE other member of the team. Please do this using pull requests and have the reviewer comment on the PR itself. We will go over this in class. 42 | 43 | #### Format for cover page: 44 | 45 | The cover page should include: 46 | 47 | 1. The name of the team 48 | 1. The names of the people in the group, and their GitHub usernames 49 | 1. A link to the GitHub repo 50 | 1. The date that it is due (15 FEB 2017) 51 | 1. The title "CS 1530 - SPRINT 2 DELIVERABLE" 52 | 53 | ### Grading 54 | 55 | Group Grading: 56 | 57 | 1. Listing of Completed User Stories And Story Points: 15% of grade 58 | 1. Details of Why Those User Stories Were Chosen: 10% of grade 59 | 1. Description of Sprint: 10% of grade 60 | 1. Listing of Defects: 15% of grade 61 | 1. Code and Tests: 50% of grade 62 | 1. Functionality: New game, pieces can move (even if not all legal moves/captures/etc. implemented), black/white take turns 63 | 1. Code: All methods should be commented (with JavaDoc or similar) 64 | 1. Tests: There are unit tests for any "computational" methods (i.e. those that do not display data to the screen) 65 | 1. Code quality: Try to separate computation from display, good method/variable names, code is easy to understand, etc. 66 | 67 | 68 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. 69 | 70 | Code should be well-tested; you don't need to do "official" TDD (although I recommend you do so when you can), but there should be good code coverage of common use cases for many, if not most, methods. 71 | 72 | Defects should include at least the following information: 73 | 74 | 1. Reproduction Steps (or reference unit test or other test that caught failure) 75 | 1. Expected Behavior (What did you expect to happen?) 76 | 1. Observed Behavior (What did you actually see happen?) 77 | 78 | ### Other 79 | 80 | Please feel free to email me or come to office hours to discuss any problems you have. 81 | -------------------------------------------------------------------------------- /deliverables/2/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D2 2 | 3 | Listing of Completed User Stories And Story Points: 15% of grade 4 | 5 | Contains actual completed user stories _____ / 10 6 | * Meet Definition of Done (coded, documented, tested, integrated) 7 | 8 | Story points included: _____ / 5 9 | 10 | Details of Why Those User Stories Were Chosen: 10% of grade 11 | 12 | Provide explanation for why they were chosen: _____ / 8 13 | 14 | General quality (no typos, etc.) _____ / 2 15 | 16 | Description of Sprint: 10% of grade 17 | 18 | Provides a good description of sprint: _____ / 8 19 | 20 | General quality (no typos, etc.) _____ / 2 21 | 22 | Listing of Defects: 15% of grade 23 | 24 | At least one defect listed: _____ / 5 25 | 26 | Proper format used: _____ / 5 27 | * Reproduction Steps 28 | * Expected Behavior 29 | * Observed Behavior 30 | 31 | If > 1 defect listed, and at least one is of proper format, maximum 32 | points off is -2 33 | 34 | Defect is readable/understandable/valid: _____ / 5 35 | 36 | If > 1 defect listed, and at least one is understandable/valid, 37 | maximum points off is -2 38 | 39 | Code and Tests: 50% of grade 40 | 41 | New game: _____ / 8 42 | * New button or similar exists (3 points) 43 | * Resets game appropriately (5 points) 44 | 45 | Pieces can move _____ / 10 46 | * Even if not all legal moves/captures/etc. implemented) 47 | 48 | Black/white take turns _____ / 7 49 | * Cannot move white pieces when black's turn & vice-versa 50 | 51 | All methods should be commented (with JavaDoc or similar) _____ / 7 52 | 53 | Tests: _____ / 10 54 | * Unit tests exist for computational methods 55 | * Tests are valid / have assertions 56 | * Tests explain what they are doing 57 | 58 | General code quality: _____ / 8 59 | 60 | 61 | Other: 62 | 63 | Improper format for title page: 64 | * -2 does not list Scrum Master 65 | * -5 does not list GitHub usernames of team members 66 | 67 | Total: ____ / 100 68 | -------------------------------------------------------------------------------- /deliverables/3/deliverable3.md: -------------------------------------------------------------------------------- 1 | ## CS/COE 1530 - Software Engineering 2 | ### Spring Semester 2017 3 | 4 | ### DUE DATE: 1 MAR 2017 5 | 6 | ### Deliverable 3 7 | 8 | For the third sprint, each group will continue implementing user stories. You will also turn in several other reports - see the Format section, below. 9 | 10 | NOTE: If I see nothing from you in the git commit history for a sprint in master, and you cannot explain and prove it (e.g., you focused on documentation this sprint with the agreement of your teammates, work was done in another branch but couldn't be merged to master, etc.), then you may get a 0 for the entire sprint. 11 | 12 | ### Format 13 | 14 | For the third sprint, you will turn in: 15 | 16 | 1. A cover page, in the format described below 17 | 2. An approximately one or two page description of what was accomplished this sprint. This can (but is not limited to) cover details such as: 18 | 1. How teams communicated 19 | 1. What disagreements arose 20 | 1. How problems were resolved 21 | 1. Changes in process since first sprint 22 | 1. Interactions with customer 23 | 1. Challenges writing the code or tests 24 | 1. Design patterns or architectural patterns used 25 | 1. Anything else that might be of interest 26 | 3. User stories completed this sprint, along with their indicated number of story points and total velocity 27 | 4. A *link to the code on GitHub/GitLab*. If I or the TA (Adam Hobaugh) cannot access it (that is, usernames laboon and greenmanspirit are not added as a collaborator), there is an automatic -15 point deduction. 28 | 4. Details on why you decided on those user stories 29 | 5. A list of any defects found (by unit testing, manual testing, or by developers), and how they were discovered and fixed (or if not fixed, why you decided not to fix them this sprint). This can include defects found by unit testing or system testing by QA (or other methods, such as issues found by the customer). If no defects were found, then please write a paper on how you have developed a way to develop software without making any mistakes, because I would be happy to read it! 30 | 31 | Each of these sections shall be CLEARLY MARKED (i.e. they should each have titles and start on their own page). 32 | 33 | Remember that user stories are not to be marked as complete until they meet the DEFINITION OF DONE - that is, they have been developed, tested, and reviewed according to the plan laid out in the first deliverable. 34 | 35 | Remember to use the 1-2-4-8-16 story point format, where 16 points is one developer working only on one story for a sprint. 36 | 37 | Remember that your main goal is to deliver a working version of the software (i.e., can be compiled and executed on any individual member's computer). Think about that when planning and prioritizing! During the in-class retrospective and sprint planning session, you can apportion responsibilities, agree on the story ordering, etc. 38 | 39 | If I have any questions on the code, I may ask *any* individual member to show me the code running on their computer. Therefore, if anyone has a problem running the current version of the code, that fact needs to be included as a defect. Failure to have a working version of the project at end of sprint may mean a drastically lower score for the project. 40 | 41 | Code should not be merged to master without the approval of at least ONE other member of the team. Please do this using pull requests and have the reviewer comment on the PR itself. We will go over this in class. 42 | 43 | #### Format for cover page: 44 | 45 | The cover page should include: 46 | 47 | 1. The name of the group 48 | 1. The names of the people in the group, and their GitHub usernames 49 | 1. A link to the 50 | 1. The date that it is due (1 MAR 2017) 51 | 1. The title "CS 1530 - SPRINT 3 DELIVERABLE" 52 | 53 | ### Grading 54 | 55 | Group Grading: 56 | 57 | 1. Listing of Completed User Stories And Story Points: 15% of grade 58 | 1. Details of Why Those User Stories Were Chosen: 10% of grade 59 | 1. Description of Sprint: 10% of grade 60 | 1. Listing of Defects: 15% of grade 61 | 1. Code and Tests: 50% of grade 62 | 1. Functionality: Moves must be legal, players can win/lose game, "special" squares (corner and throne/center) must be visually distinct 63 | 1. Code: All methods should be commented (with JavaDoc or similar) 64 | 1. Tests: There are unit tests for any "computational" methods (i.e. those that do not display data to the screen) 65 | 1. Code quality: Try to separate computation from display, good method/variable names, code is easy to understand, etc. 66 | 67 | 68 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. 69 | 70 | Code should be well-tested; you don't need to do "official" TDD (although I recommend you do so when you can), but there should be good code coverage of common use cases for many, if not most, methods. 71 | 72 | Defects should include at least the following information: 73 | 74 | 1. Reproduction Steps (or reference unit test or other test that caught failure) 75 | 1. Expected Behavior (What did you expect to happen?) 76 | 1. Observed Behavior (What did you actually see happen?) 77 | 78 | ### Other 79 | 80 | Please feel free to email me or come to office hours to discuss any problems you have. -------------------------------------------------------------------------------- /deliverables/3/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D2 2 | 3 | Listing of Completed User Stories And Story Points: 15% of grade 4 | 5 | Contains actual completed user stories _____ / 10 6 | * Meet Definition of Done (coded, documented, tested, integrated) 7 | 8 | Story points included: _____ / 5 9 | 10 | Details of Why Those User Stories Were Chosen: 10% of grade 11 | 12 | Provide explanation for why they were chosen: _____ / 8 13 | 14 | General quality (no typos, etc.) _____ / 2 15 | 16 | Description of Sprint: 10% of grade 17 | 18 | Provides a good description of sprint: _____ / 8 19 | 20 | General quality (no typos, etc.) _____ / 2 21 | 22 | Listing of Defects: 15% of grade 23 | 24 | At least one defect listed: _____ / 5 25 | 26 | Proper format used: _____ / 5 27 | * Reproduction Steps, Expected, Observed 28 | 29 | If > 1 defect listed, and at least one is of proper format, maximum 30 | points off is -3 31 | 32 | Defect is readable/understandable/valid: _____ / 5 33 | 34 | If > 1 defect listed, and at least one is understandable/valid, 35 | maximum points off is -2 36 | 37 | Code and Tests: 50% of grade 38 | 39 | No regression: 40 | 41 | Legal moves: _____ / 15 42 | 43 | Players can win/lose _____ / 10 44 | 45 | Special squares distinct _____ / 5 46 | 47 | All methods should be commented (with JavaDoc or similar) _____ / 5 48 | 49 | Tests: _____ / 10 50 | 51 | General code quality: _____ / 5 52 | 53 | Miscellaneous: 54 | 55 | 56 | Total: ____ / 100 57 | -------------------------------------------------------------------------------- /deliverables/4/deliverable4.md: -------------------------------------------------------------------------------- 1 | ## CS/COE 1530 - Software Engineering 2 | ### Spring Semester 2017 3 | 4 | ### DUE DATE: 15 MAR 2017 5 | 6 | ### Deliverable 4 7 | 8 | For the fourth sprint, we will perform a _hardening sprint_. That is, you will work to increase code quality and/or fill in any functionality that you may have missed earlier. You will also turn in several other reports - see the Format section, below. 9 | 10 | Unlike other sprints, this sprint is individually graded. I want you to examine the code yourself, determine something which needs to be fixed, and fix it. This could be a lack of comments or tests, an edge case that was not considered, improved usability or functionality, a known defect, or anything else that you see that could be improved. 11 | 12 | Please ensure that you discuss what you will be doing with your group partners before doing it! You should use your normal sprint planning time to determine who will be working on what. 13 | 14 | Since this is a short sprint, I will not expect the same amount of work as in a normal sprint. 15 | 16 | ### Format 17 | 18 | For the fourth sprint, you will turn in: 19 | 20 | 1. A cover page, in the format described below 21 | 2. An approximately 1/2 to 1 page description of what was accomplished this sprint, and why. This can (but is not limited to) cover details such as: 22 | 1. How teams communicated 23 | 1. What disagreements arose 24 | 1. How problems were resolved 25 | 1. Changes in process since first sprint 26 | 1. Interactions with customer 27 | 1. Challenges writing the code or tests 28 | 1. Design patterns or architectural patterns used 29 | 1. Anything else that might be of interest 30 | 4. A *link to the code on GitHub/GitLab*. If I or the TA cannot access it (that is, usernames `laboon` and `mBarrenSQA` are not added as a collaborator), there is an automatic -15 point deduction. 31 | 32 | Remember that your main goal is to deliver a working version of the software (i.e., can be compiled and executed on any individual member's computer). Think about that when planning and prioritizing! During the in-class retrospective and sprint planning session, you can apportion responsibilities, agree on the story ordering, etc. 33 | 34 | If I have any questions on the code, I may ask *any* individual member to show me the code running on their computer. Therefore, if anyone has a problem running the current version of the code, that fact needs to be included as a defect. Failure to have a working version of the project at end of sprint may mean a drastically lower score for the project. 35 | 36 | Code should not be merged to master without the approval of at least ONE other member of the team. Please do this using pull requests and have the reviewer comment on the PR itself. We will go over this in class. 37 | 38 | #### Format for cover page: 39 | 40 | The cover page should include: 41 | 42 | 1. The name of the group 43 | 1. The names of the people in the group, and their GitHub usernames 44 | 1. The name of the INDIVIDUAL turning it in 45 | 1. A link to the GitHub repository 46 | 1. The date that it is due (15 MAR 2017) 47 | 1. The title "CS 1530 - SPRINT 4 DELIVERABLE" 48 | 49 | ### Grading 50 | 51 | Individual Grading: 52 | 53 | 1. Description of Sprint: 30% of grade 54 | 1. Code and Tests: 70% of grade 55 | 1. Functionality 56 | 1. Code: All methods should be commented (with JavaDoc or similar) 57 | 1. Tests: There are unit tests for any "computational" methods (i.e. those that do not display data to the screen) 58 | 1. Code quality: Try to separate computation from display, good method/variable names, code is easy to understand, etc. 59 | 60 | 61 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. 62 | 63 | Code should be well-tested; you don't need to do "official" TDD (although I recommend you do so when you can), but there should be good code coverage of common use cases for any public methods. 64 | 65 | If you cannot test something in an automated way, make sure you explain how you tested it manually. 66 | 67 | ### Other 68 | 69 | Please feel free to email me or come to office hours to discuss any problems you have. -------------------------------------------------------------------------------- /deliverables/4/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D4 2 | 3 | Description of Sprint: 30% of grade 4 | 5 | Provides a good description of work: _____ / 10 6 | 7 | Describes why it was chosen: _____ / 10 8 | 9 | General quality (no typos, etc.) _____ / 10 10 | 11 | Code and Tests: 70% of grade 12 | 13 | Picked relevant work: _____ / 15 14 | * Comments 15 | * Tests added 16 | * Feature added 17 | * Defect fixed 18 | * Other 19 | 20 | Quality: _____ / 55 21 | * If comments, whole system should be well-commented 22 | * If tests, cover all equivalence classes 23 | * If feature added, feature works 24 | * If defect fixed, was fixed appropriately 25 | 26 | Miscellaneous: 27 | 28 | 29 | Total: ____ / 100 30 | -------------------------------------------------------------------------------- /deliverables/5/deliverable5.md: -------------------------------------------------------------------------------- 1 | ## CS/COE 1530 - Software Engineering 2 | ### Spring Semester 2017 3 | 4 | ### DUE DATE: 29 MAR 2017 5 | 6 | ### Deliverable 5 7 | 8 | For the fifth sprint, each group will continue implementing user stories, *AND* a few little twists have been added. You will also turn in several other reports - see the Format section, below. 9 | 10 | NOTE: If I see nothing from you in the git commit history for a sprint in master, and you cannot explain and prove it (e.g., you focused on documentation this sprint with the agreement of your teammates, work was done in another branch but couldn't be merged to master, etc.), then you may get a 0 for the entire sprint. 11 | 12 | ### Format 13 | 14 | For the fifth sprint, you will turn in: 15 | 16 | 1. A cover page, in the format described below 17 | 2. An approximately one page description of what was accomplished this sprint. This can (but is not limited to) cover details such as: 18 | 1. How teams communicated 19 | 1. What disagreements arose 20 | 1. How problems were resolved 21 | 1. Changes in process since first sprint 22 | 1. Interactions with customer 23 | 1. Challenges writing the code or tests 24 | 1. Design patterns or architectural patterns used 25 | 1. Anything else that might be of interest 26 | 3. User stories completed this sprint, along with their indicated number of story points and total velocity 27 | 4. A *link to the code on GitHub/GitLab*. If I or the TA (Adam Hobaugh) cannot access it (that is, usernames laboon and greenmanspirit are not added as a collaborator), there is an automatic -15 point deduction. 28 | 5. A list of any defects found (by unit testing, manual testing, or by developers), and how they were discovered and fixed (or if not fixed, why you decided not to fix them this sprint). This can include defects found by unit testing or system testing by QA (or other methods, such as issues found by the customer). If no defects were found, then please write a paper on how you have developed a way to develop software without making any mistakes, because I would be happy to read it! 29 | 30 | Each of these sections shall be CLEARLY MARKED (i.e. they should each have titles and start on their own page). 31 | 32 | Remember that user stories are not to be marked as complete until they meet the DEFINITION OF DONE - that is, they have been developed, tested, and reviewed according to the plan laid out in the first deliverable. 33 | 34 | Remember to use the 1-2-4-8-16 story point format, where 16 points is one developer working only on one story for a sprint. 35 | 36 | Remember that your main goal is to deliver a working version of the software (i.e., can be compiled and executed on any individual member's computer). Think about that when planning and prioritizing! 37 | 38 | If I have any questions on the code, I may ask *any* individual member to show me the code running on their computer. Therefore, if anyone has a problem running the current version of the code, that fact needs to be included as a defect. Failure to have a working version of the project at end of sprint may mean a drastically lower score for the project. 39 | 40 | Code should not be merged to master without the approval of at least ONE other member of the team. Please do this using pull requests and have the reviewer comment on the PR itself. We will go over this in class. 41 | 42 | #### Format for cover page: 43 | 44 | The cover page should include: 45 | 46 | 1. The name of the group 47 | 1. The names of the people in the group, and their GitHub usernames 48 | 1. A link to the 49 | 1. The date that it is due (29 MAR 2017) 50 | 1. The title "CS 1530 - SPRINT 5 DELIVERABLE" 51 | 52 | ### Timer 53 | 54 | The customer has decided that they have an additional request which MUST be implemented. These user stories should be added to your product backlog and completed this sprint. It is up to you how many points it is allocated. 55 | 56 | As a user, 57 | I want a countdown timer for each side, 58 | So that I can timebox the game 59 | 60 | As a user, 61 | I want five minutes plus three seconds per move for each player, 62 | So that I always have at least three seconds to make a move 63 | 64 | This countdown timer should update once per second, starting at 5:00. This countdown timer acts like a chess clock - the "black" clock should count down only when it is the black player's move, and after the black player has made a move, the white player's clock will start counting down. The same process will occur for the "white" clock. In other words, each player has ten minutes total for making moves (with one additional caveat, below). 65 | 66 | Every time a player makes a move, three seconds should be added to their clock. This is to ensure that there is always time to make _some_ move. 67 | 68 | If a particular player's clock hits 0, that player loses the game automatically. 69 | 70 | For extra points, both of these values can be configurable (e.g., 10 minutes + 1 second per move, or 1 minute plus ten seconds per move, etc.). 71 | 72 | This clock should be implemented on a separate thread. 73 | 74 | ### File Load/Save 75 | 76 | I should be able to save and later load games. The best way to do this is probably with a simple text file. 77 | 78 | It is _not_ necessary to be able to save more than one game (i.e., you may always save to the same file). However, if you allow me to select filenames to save to / load from, you will get additional points. 79 | 80 | ### Grading 81 | 82 | Group Grading: 83 | 84 | 1. Listing of Completed User Stories And Story Points: 10% of grade 85 | 1. Description of Sprint: 15% of grade 86 | 1. Listing of Defects: 15% of grade 87 | 1. Code and Tests: 60% of grade 88 | 1. Functionality: Captures can occur, file load/save implemented, countdown timer implemented 89 | 1. No regressions: Functionality which worked in a previous sprint should still work in this one 90 | 1. Code: All methods should be commented (with JavaDoc or similar) 91 | 1. Tests: There are unit tests for any "computational" methods. 92 | 1. Code quality: Try to separate computation from display, good method/variable names, code is easy to understand, etc. 93 | 94 | Be sure to fix any issues you had in previous sprints, as well! 95 | 96 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. 97 | 98 | Code should be well-tested; you don't need to do "official" TDD (although I recommend you do so when you can), but there should be good code coverage of common use cases for many, if not most, methods. 99 | 100 | Defects should include at least the following information: 101 | 102 | 1. Reproduction Steps (or reference unit test or other test that caught failure) 103 | 1. Expected Behavior (What did you expect to happen?) 104 | 1. Observed Behavior (What did you actually see happen?) 105 | 106 | ### Other 107 | 108 | Please feel free to email me or come to office hours to discuss any problems you have. -------------------------------------------------------------------------------- /deliverables/5/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D5 2 | 3 | Listing of Completed User Stories And Story Points: 10% of grade 4 | 5 | Contains actual completed user stories _____ / 8 6 | * Meet Definition of Done (coded, documented, tested, integrated) 7 | 8 | Story points included: _____ / 2 9 | 10 | Description of Sprint: 15% of grade 11 | 12 | Provides a good description of sprint: _____ / 12 13 | 14 | General quality (no typos, etc.) _____ / 3 15 | 16 | Listing of Defects: 15% of grade 17 | 18 | At least one defect listed: _____ / 5 19 | 20 | Proper format used: _____ / 5 21 | * Reproduction Steps, Expected, Observed 22 | 23 | If > 1 defect listed, and at least one is of proper format, maximum 24 | points off is -3 25 | 26 | Defect is readable/understandable/valid: _____ / 5 27 | 28 | If > 1 defect listed, and at least one is understandable/valid, 29 | maximum points off is -2 30 | 31 | Code and Tests: 60% of grade 32 | 33 | No regression: 34 | * Legal moves can be made (-10 if not) 35 | * Illegal moves cannot be made (-6 if not) 36 | * Both black and white can win (-5 for each if not) 37 | 38 | New Functionality: 39 | 40 | Captures: ____ / 10 41 | * Pieces can be captured in "normal" way (-8 if not) 42 | * Pieces can be captured using special squares (-3 if not) 43 | 44 | File Save: ____ / 7 45 | * Board position can be saved to file (-7 if not) 46 | 47 | File Load: ____ / 8 48 | * Saved board position can be loaded (-8 if not) 49 | * Empty file is handled gracefully (-3 if not) 50 | * Corrupt file is handled gracefully (-3 if not) 51 | 52 | Countdown Timer implemented: ____ / 13 53 | * Running in a separate thread: (-9 if not) 54 | (note: Swing Timer is in separate thread implicitly) 55 | * 5 minute countdown by default (-5 if not) 56 | * Countdown only takes place on player's move (-8 if not) 57 | * 3 seconds added per move (-5 if not) 58 | 59 | 60 | All methods should be commented (with JavaDoc or similar) _____ / 5 61 | 62 | Tests: _____ / 10 63 | 64 | General code quality: _____ / 7 65 | 66 | Bonus: 67 | Configurable total time: +3 68 | Configurable per-move time: +2 69 | 70 | Miscellaneous: 71 | 72 | 73 | Total: ____ / 100 74 | -------------------------------------------------------------------------------- /deliverables/6/deliverable6.md: -------------------------------------------------------------------------------- 1 | ## CS/COE 1530 - Software Engineering 2 | ### Spring Semester 2017 3 | 4 | ### DUE DATE: 17 APR 2017 5 | 6 | ### Deliverable 6 7 | 8 | For the sixth and final sprint, each group will finish up the game and present it to the class, *AND* a few little twists have been added. You will also turn in several other reports - see the Format section, below. 9 | 10 | NOTE: If I see nothing from you in the git commit history for a sprint in master, and you cannot explain and prove it (e.g., you focused on documentation this sprint with the agreement of your teammates, work was done in another branch but couldn't be merged to master, etc.), then you may get a 0 for the entire sprint. 11 | 12 | ### Format 13 | 14 | For the sixth sprint, you will turn in: 15 | 16 | 1. A cover page, in the format described below 17 | 2. An approximately one page description of what was accomplished this sprint. This can (but is not limited to) cover details such as: 18 | 1. How teams communicated 19 | 1. What disagreements arose 20 | 1. How problems were resolved 21 | 1. Changes in process since first sprint 22 | 1. Interactions with customer 23 | 1. Challenges writing the code or tests 24 | 1. Design patterns or architectural patterns used 25 | 1. Anything else that might be of interest 26 | 3. User stories completed this sprint, along with their indicated number of story points and total velocity 27 | 4. A *link to the code on GitHub/GitLab*. If I or the TA (Adam Hobaugh) cannot access it (that is, usernames laboon and greenmanspirit are not added as a collaborator), there is an automatic -15 point deduction. 28 | 5. A list of any defects found (by unit testing, manual testing, or by developers), and how they were discovered and fixed (or if not fixed, why you decided not to fix them this sprint). This can include defects found by unit testing or system testing by QA (or other methods, such as issues found by the customer). If no defects were found, then please write a paper on how you have developed a way to develop software without making any mistakes, because I would be happy to read it! 29 | 30 | Each of these sections shall be CLEARLY MARKED (i.e. they should each have titles and start on their own page). 31 | 32 | Remember that user stories are not to be marked as complete until they meet the DEFINITION OF DONE - that is, they have been developed, tested, and reviewed according to the plan laid out in the first deliverable. 33 | 34 | Remember to use the 1-2-4-8-16 story point format, where 16 points is one developer working only on one story for a sprint. 35 | 36 | Remember that your main goal is to deliver a working version of the software (i.e., can be compiled and executed on any individual member's computer). Think about that when planning and prioritizing! 37 | 38 | If I have any questions on the code, I may ask *any* individual member to show me the code running on their computer. Therefore, if anyone has a problem running the current version of the code, that fact needs to be included as a defect. Failure to have a working version of the project at end of sprint may mean a drastically lower score for the project. 39 | 40 | Code should not be merged to master without the approval of at least ONE other member of the team. Please do this using pull requests and have the reviewer comment on the PR itself. We will go over this in class. 41 | 42 | You will also give a presentation to the class on your project, which must include a live demo. This presentation should be approximately 10-15 minutes and cover the functionality of your program and the code behind it. 43 | 44 | Student groups may go on either Monday or Wednesday of the final week. I will decide who goes (although I may ask for volunteers). Be prepared to go on Monday although you may get a two-day reprieve. 45 | 46 | #### Format for cover page: 47 | 48 | The cover page should include: 49 | 50 | 1. The name of the group 51 | 1. The names of the people in the group, and their GitHub usernames 52 | 1. A link to the 53 | 1. The date that it is due (17 APR 2017) 54 | 1. The title "CS 1530 - SPRINT 6 DELIVERABLE" 55 | 56 | ### Hnefatafl Implementation 57 | 58 | All of the rules for Copenhagen Hnefatafl should be implemented by the end of this sprint. This includes the "shield wall" rule, using squares as "attacking" squares, etc. I should be able to play Hnefatafl according to all of the rules listed on http://aagenielsen.dk/copenhagen_rules.php. 59 | 60 | ### Additional Functionality 61 | 62 | You should add one or more _additional_ pieces of functionality. It is up to you to decide what functionality you would like to add. This part is a bit subjective. 63 | 64 | Possible additional functionality: 65 | 66 | #### "Easy" functionality - Need to implement two of these level for full points 67 | 68 | 1. Change colors of pieces / board 69 | 2. Displaying number of pieces left for each side 70 | 3. Displaying possible moves 71 | 4. Use loadable images for pieces 72 | 73 | #### "Hard" functionality - Full points (if not more!) for one 74 | 75 | 1. Displaying "good" moves (what is a metric for "good"?) 76 | 2. An AI which plays against the user 77 | 3. Training mode which gives you "challenges" to complete 78 | 79 | Don't let these limit you, though. Feel free to do something else! If you have questions, feel free to ask me. 80 | 81 | ### Grading 82 | 83 | Group Grading: 84 | 85 | 1. Listing of Completed User Stories And Story Points: 5% of grade 86 | 1. Description of Sprint: 10% of grade 87 | 1. Listing of Defects: 10% of grade 88 | 1. Code and Tests: 55% of grade 89 | * Functionality: All Hnefatafl rules implemented + at least one additional piece of functionality 90 | * No regressions: Functionality which worked in a previous sprint should still work in this one 91 | * Code: All methods should be commented (with JavaDoc or similar) 92 | * Tests: There are unit tests for any "computational" methods. 93 | * Code quality: Try to separate computation from display, good method/variable names, code is easy to understand, etc. 94 | 1. Presentation: 20% of grade 95 | 96 | Yes, grammar and spelling count. Points will be deducted for more than one grammatical or spelling error per section. 97 | 98 | Code should be well-tested; you don't need to do "official" TDD (although I recommend you do so when you can), but there should be good code coverage of common use cases for many, if not most, methods. 99 | 100 | Defects should include at least the following information: 101 | 102 | 1. Reproduction Steps (or reference unit test or other test that caught failure) 103 | 1. Expected Behavior (What did you expect to happen?) 104 | 1. Observed Behavior (What did you actually see happen?) 105 | 106 | ### Other 107 | 108 | Please feel free to email me or come to office hours to discuss any problems you have. -------------------------------------------------------------------------------- /deliverables/6/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D6 2 | 3 | Listing of Completed User Stories And Story Points: 5% of grade 4 | 5 | Contains actual completed user stories _____ / 4 6 | * Meet Definition of Done (coded, documented, tested, integrated) 7 | 8 | Story points included: _____ / 1 9 | 10 | Description of Sprint: 10% of grade 11 | 12 | Provides a good description of sprint: _____ / 7 13 | 14 | General quality (no typos, etc.) _____ / 3 15 | 16 | Listing of Defects: 10% of grade 17 | 18 | At least one defect listed: _____ / 5 19 | * NOTE: For final sprint, if NO defects found by 20 | grader, and "No defects" are listed, they can 21 | get full credit for this and next marking "None" here 22 | 23 | Proper format used: _____ / 5 24 | * Reproduction Steps, Expected, Observed 25 | * Defect is readable/understandable/valid: 26 | 27 | If > 1 defect listed, and at least one is understandable/valid, 28 | maximum points off is -2 29 | 30 | Code and Tests: 55% of grade 31 | 32 | Final Functionality: _____ / 30 33 | * Legal moves can be made (-10 if not) 34 | * Illegal moves cannot be made (-5 if not) 35 | * Both black and white can win (-5 for each if not) 36 | * Files can be saved/loaded (-5 each, if not) 37 | * Pieces can be captured in normal way (-8 if not) 38 | * Shield Wall works (-3 if not) 39 | * Surround-Loss works (-3 if not) 40 | 41 | Two easy or one hard pieces of functionality implemented: _____ / 10 42 | * Easy 43 | * Change colors 44 | * Display # pieces left 45 | * Display possible moves 46 | * Use loadable images for pieces 47 | * Hard 48 | * Display "good" moves 49 | * Play against AI 50 | * Training mode 51 | * Others possible! 52 | 53 | All methods should be commented (with JavaDoc or similar) _____ / 5 54 | 55 | Tests: _____ / 5 56 | * Additional tests added - do not check all of them, 57 | only that they continued to test 58 | 59 | General code quality: _____ / 5 60 | 61 | Presentation: _____ / 20 62 | 63 | Bonus: 64 | 65 | Miscellaneous: 66 | 67 | 68 | Total: ____ / 100 69 | -------------------------------------------------------------------------------- /exercises/TicTacToe.java: -------------------------------------------------------------------------------- 1 | import java.awt.*; 2 | import java.awt.event.*; 3 | import javax.swing.*; 4 | 5 | public class TicTacToe { 6 | JFrame _frame = new JFrame("Tic-Tac-Toe"); 7 | JPanel _ttt = new JPanel(); 8 | JPanel _newPanel = new JPanel(); 9 | JButton[] _buttons = new JButton[9]; 10 | 11 | public TicTacToe() { 12 | _frame.setSize(400, 400); 13 | _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 14 | 15 | _ttt.setLayout(new GridLayout(3, 3)); 16 | _newPanel.setLayout(new FlowLayout()); 17 | 18 | // This will place the tic-tac-toe panel at the top of 19 | // the frame and the newPanel panel at the bottom 20 | _frame.add(_ttt, BorderLayout.NORTH); 21 | _frame.add(_newPanel, BorderLayout.SOUTH); 22 | 23 | 24 | for (int j=0; j<9; j++) { 25 | // Make a new button in the array location with text "_" 26 | _buttons[j] = new JButton("_"); 27 | // Associate a new ButtonListener to the button (see below) 28 | ActionListener buttonListener = new ButtonListener(); 29 | _buttons[j].addActionListener(buttonListener); 30 | // Set the font on the button 31 | _buttons[j].setFont(new Font("Courier", Font.PLAIN, 48)); 32 | // Add this button to the _ttt panel 33 | _ttt.add(_buttons[j]); 34 | } 35 | 36 | _frame.setVisible(true); 37 | 38 | } 39 | 40 | public static void main(String[] args) { 41 | new TicTacToe(); 42 | } 43 | 44 | class ButtonListener implements ActionListener { 45 | 46 | // Every time we click the button, it will perform 47 | // the following action. 48 | 49 | public void actionPerformed(ActionEvent e) { 50 | JButton source = (JButton) e.getSource(); 51 | String currentText = source.getText(); 52 | if (currentText.equals("_")) { 53 | source.setText("X"); 54 | } else { 55 | source.setText("_"); 56 | } 57 | } 58 | 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /exercises/TicTacToeAnswer.java: -------------------------------------------------------------------------------- 1 | import java.awt.*; 2 | import java.awt.event.*; 3 | import javax.swing.*; 4 | 5 | public class TicTacToeAnswer { 6 | 7 | JFrame _frame = new JFrame("Tic-Tac-Toe"); 8 | JPanel _ttt = new JPanel(); 9 | JPanel _newPanel = new JPanel(); 10 | JButton[] _buttons = new JButton[9]; 11 | JButton _newButton = new JButton("New Game"); 12 | 13 | boolean _xTurn = true; 14 | 15 | public TicTacToeAnswer() { 16 | _frame.setSize(400, 400); 17 | _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 | 19 | _ttt.setLayout(new GridLayout(3, 3)); 20 | _newPanel.setLayout(new FlowLayout()); 21 | 22 | // This will place the tic-tac-toe panel at the top of 23 | // the frame and the newPanel panel at the bottom 24 | _frame.add(_ttt, BorderLayout.NORTH); 25 | _frame.add(_newPanel, BorderLayout.SOUTH); 26 | 27 | // Add nine buttons for the Tic-Tac-Toe game itself 28 | for (int j=0; j<9; j++) { 29 | // Make a new button in the array location with text "_" 30 | _buttons[j] = new JButton("_"); 31 | // Associate a new ButtonListener to the button (see below) 32 | ActionListener buttonListener = new ButtonListener(); 33 | _buttons[j].addActionListener(buttonListener); 34 | // Set the font on the button 35 | _buttons[j].setFont(new Font("Courier", Font.PLAIN, 48)); 36 | // Add this button to the _ttt panel 37 | _ttt.add(_buttons[j]); 38 | } 39 | 40 | // Associate a NewGameListener with the new button and add it 41 | // to the newPanel 42 | 43 | _newButton.addActionListener(new NewGameListener()); 44 | _newPanel.add(_newButton); 45 | 46 | _frame.setVisible(true); 47 | 48 | } 49 | 50 | public static void main(String[] args) { 51 | new TicTacToeAnswer(); 52 | } 53 | 54 | class ButtonListener implements ActionListener { 55 | 56 | // Every time we click the button, it will perform 57 | // the following action. 58 | 59 | public void actionPerformed(ActionEvent e) { 60 | 61 | // Figure out where the click came from. source will 62 | // contain a reference to the clicked button. 63 | // Note e.getSource() will return an object, but we know 64 | // that it will be a JButton so we cast it. 65 | JButton source = (JButton) e.getSource(); 66 | String currentText = source.getText(); 67 | if (currentText.equals("_")) { 68 | // Button has not yet been selected, change it 69 | // to X or O and then it is the other player's turn 70 | if (_xTurn) { 71 | source.setText("X"); 72 | } else { 73 | source.setText("O"); 74 | } 75 | // flip-flop the boolean 76 | _xTurn = !_xTurn; 77 | } else { 78 | // Can't click here, already selected! 79 | // Do nothing 80 | } 81 | 82 | } 83 | 84 | } 85 | 86 | // This listener will be called when the new game button is clicked 87 | class NewGameListener implements ActionListener { 88 | 89 | public void actionPerformed(ActionEvent e) { 90 | // Change all of the buttons to "_", unselected 91 | // Restart user to be "X" player 92 | for (JButton btn : _buttons) { 93 | _xTurn = true; 94 | btn.setText("_"); 95 | } 96 | 97 | } 98 | 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /exercises/command_line_exercise.md: -------------------------------------------------------------------------------- 1 | 1. Clone the repo to your local machine https://github.com/laboon/CommandLineFun 2 | 2. There are several exercises in the README.md file. Please do them with a partner. 3 | 3. If you do not have a Unix system (OS X or Linux), these should work with Cygwin or bash shell on Windows, or ssh into unixs -------------------------------------------------------------------------------- /exercises/git911-answers.md: -------------------------------------------------------------------------------- 1 | # Git 911 Answers 2 | 3 | Note that there are multiple ways to solve most of these! I just wrote down one for each. 4 | 5 | ## BadRepo0 6 | 7 | ``` 8 | git checkout -b new_branch_name 9 | *make changes* 10 | git commit -am "change message" 11 | git checkout master 12 | git merge new_branch_name 13 | git push origin master 14 | ``` 15 | 16 | ## BadRepo1 17 | 18 | ``` 19 | git revert _SHA of last commit_ 20 | ``` 21 | 22 | ## BadRepo2 23 | 24 | A _merge conflict_ is when two branches change the same line of code. When merging, they are indicated as follows: 25 | 26 | ``` 27 | <<<<<<< HEAD 28 | toReturn = '_'; 29 | ======= 30 | toReturn = ' '; 31 | >>>>>>> wjl_display 32 | ``` 33 | 34 | When you see these, it means git could not figure out which one to use. You need to delete all of the garbage (<<<<<< HEAD, ======, >>>>>> wjl_display), and determine yourself which line to use. The lines _above_ the ====== signs are what is in the branch you are merging into; the lines _below_ are the ones from the branch you are merging from. The final product should be equal to the code you want in master (or whatever branch you are merging _into_). This can be either one of the chunks, both of them, or something entirely new (e.g., `toReturn = '?'`). However, you will definitely need to ensure that you remove the <<<<<, =====, and >>>>> lines. 35 | 36 | Merge conflicts were accidentally committed "as actual code". Two solutions: 37 | 38 | 1. Revert back a commit (as in BadRepo1). Then re-merge (`git merge wjl_display`). Fix merge conflicts along the way as per normal. 39 | 2. Resolve the merge conflicts in master, and then commit that as an additional change. 40 | 41 | In general, small issues like this would be solved the second way; larger errors in the first way. 42 | 43 | ## BadRepo3 44 | 45 | ``` 46 | git checkout wjl_commits 47 | git rebase -i master 48 | Squash (s) all of the commits into the first one (change "pick" to "squash" or just "s") 49 | git push --force origin wjl_commits 50 | ``` 51 | 52 | Note that you won't be able to push this back up without forcing, since you "rewrote history" on the branch! This behavior can be overriden with `git push -f _branchname_`, or `git push --force _branchname_` or you can make a new branch from that point `git checkout -b _new_branch_`. 53 | 54 | After rebasing, you can merge to master just like before: 55 | 56 | ``` 57 | git checkout master 58 | git merge wjl_commits 59 | git push origin master 60 | ``` 61 | 62 | You should NOT have to force push the _master_ branch! Rebasing will add it to the end of the list of deltas (i.e., all the code in the branch will become a new commit "on top of" the master branch). This does not modify history. 63 | 64 | ## BadRepo4 65 | 66 | ``` 67 | git checkout master 68 | git merge wjl_derp 69 | ``` 70 | 71 | Fix all of the merge conflicts using your favorite text editor, then commit changes like so: 72 | 73 | ``` 74 | git add com/laboon/Cell.java com/laboon/JavaLife.java 75 | git commit -am "fix merge conflicts" 76 | git push origin master 77 | ``` -------------------------------------------------------------------------------- /exercises/git911.md: -------------------------------------------------------------------------------- 1 | Please fork the BadRepo[0-4] repositories under GitHub username laboon. 2 | 3 | BadRepo0 - Create a branch that corrects the incorrect text in the README.md file, then merge that back in the master branch. Do not do the work directly on the master branch! Corrections to be made: CS1530 should be the "best" class, not the "worst"; the line referencing pudding should be deleted; you should add a line at the end that says "Final version". 4 | 5 | BadRepo1 - Somebody accidentally sent a commit which deleted all of the codes. How can you fix this? 6 | 7 | BadRepo2 - Somebody merged a branch, but was in a real hurry and didn't check if it compiled. Can you recover while still ensuring that their changes get merged in (that is, you don't just revert to the previous version)? 8 | 9 | BadRepo3 - Somebody created a branch with oh-so-many commits. Can you compress them all down into one commit? 10 | 11 | BadRepo4 - Merge the wjl_derp branch into master. Deal with the merge conflicts as best you can. 12 | 13 | If you finish these, can _you_ make a messed-up git repository? Messed up in a different way, that is? If so, and I decide to use it for my next "Git 911", it can mean bonus points for you! 14 | -------------------------------------------------------------------------------- /exercises/gradle-exercise.md: -------------------------------------------------------------------------------- 1 | # Gradle Exercise 2 | 3 | You and a partner are going to create a Java application gradle project which will print integer sequences. You will then push your project to GitHub and show me. I recommend you start by creating a new GitHub repository! 4 | 5 | The first integer sequence is the Triangle number sequence. Think of this as an "additive" version of a factorial function: whereas 5! = 5 * 4 * 3 * 2 * 1, Tri(5) = 5 + 4 + 3 + 2 + 1. You can find the exact equation here: https://en.wikipedia.org/wiki/Triangular_number 6 | 7 | The second sequence is the Lazy Caterer sequence. This is the sequence which indicates how many pieces a cake could be cut into by using n knife cuts. For example, with 0 knife cuts, a cake would have to stay in one piece. With two knife cuts, you could have four pieces. You can find the equation governing the Lazy Caterer sequence here: https://en.wikipedia.org/wiki/Lazy_caterer%27s_sequence 8 | 9 | The project should meet the following specifications: 10 | 11 | 1. A main class which accepts two arguments: 12 | 1. The first argument shall consist of either the string "lazy" or "triangle". If neither, the program shall inform the user and exit with error code 1. 13 | 2. The second argument shall be a positive 32-bit integer. If it is not, the program shall inform the user and exit with error code 2. 14 | 2. The program shall print out the result (the Lazy Caterer number or the Triangle number) in the following format: "Tri(n) = x" if the user selected a triangle number or "Lazy(n) = x" if the user selected a Lazy Caterer number. 15 | 3. At least three unit tests of each non-main method shall be added. The minimum here is two methods (one to calculate triangle numbers and the other to calculate Lazy Caterer numbers). 16 | 4. Aside from the gradle commands "build", "run", and "test", an additional task, "sequencehelp", shall be added. I should be able to run this command with `gradle -q sequencehelp` or `gradle sequencehelp` . This task shall do the following (in Groovy): 17 | 1. Print "Integer Sequence Project" 18 | 2. Print a short help sequence showing how the program works (as described in the specifications above) 19 | 20 | If you need to exit with an error, it is important to exit with a different error than 0, as 0 indicates success to gradle. It will not know that your program has an error unless you indicate it with a non-zero exit code. This is good advice not just for this class but in general - if your program exits abnormally, the way to indicate this is with some non-zero exit code. Other programs which may depend on yours can use that as a "signal" from your program. 21 | 22 | When complete, you should push up to GitHub and show me. I may or may not clone it down to my computer to ensure that it works! -------------------------------------------------------------------------------- /exercises/swing_exercise.md: -------------------------------------------------------------------------------- 1 | ## Swing Exercise 2 | 3 | Your mission, should you choose to accept it, is to create a Tic-Tac-Toe game! 4 | 5 | As you are going along, please compile and check that you are on the right track regularly. Do not just type, type, type. Studies have shown that more senior software engineers tend to make smaller steps, whereas junior engineers like to type in hundreds of lines then see if they compile. Become a senior engineer as soon as you can! 6 | 7 | ### Instructions 8 | 9 | The first thing to do is import all of the libraries that we need. Specifically, we will want the java.awt.*, java.awt.event.*, and javax.swing.* classes. We will see why later. 10 | 11 | ```java 12 | import java.awt.*; 13 | import java.awt.event.*; 14 | import javax.swing.*; 15 | ``` 16 | 17 | After that, it's time to create a new frame. A frame is what most people think of as a window (this is actually an old term - Emacs, for example, calls a window a "frame"). Creating a JFrame will create a new window. You can set its size, default closing behavior, etc. Frames are constructed like so: 18 | 19 | ```java 20 | JFrame _frame = new JFrame("Tic-Tac-Toe"); 21 | ``` 22 | 23 | You should create this as an instance variable, not in a method. Example: 24 | 25 | ```java 26 | public class TicTacToe { 27 | JFrame _frame = new JFrame("Tic-Tac-Toe"); 28 | 29 | public static void main(String[] args) { 30 | 31 | } 32 | 33 | } 34 | ``` 35 | 36 | You will note that our class is a JFrame, and not a Frame. Frames are AWT (Abstract Window Toolkit) classes; JFrames are Swing classes. Swing is a GUI framework built on top of AWT (which is much nicer, trust me). You will find that most classes that start with J have an equivalent J-less class in AWT. 37 | 38 | We will do most of the work in the constructor; our main method should just make a new instance of the TicTacToe class. 39 | 40 | ```java 41 | public static void main(String[] args) { 42 | new TicTacToe(); 43 | } 44 | ``` 45 | 46 | The last line of the constructor should let the frame be visible. We can generate all of the data/elements/etc. "behind the scenes" without displaying them to the user, and then show them the finished version. If you find that a window is not updating, it may be that you need to "force" a refresh by setting the frame to visible again. It won't hurt anything if you do it more times than necessary (except when it comes to performance). 47 | 48 | ```java 49 | // Refresh window - otherwise we will not be able to see it 50 | // THIS IS A COMMON SOURCE OF BUGS! 51 | _frame.setVisible(true); 52 | ``` 53 | 54 | You can set the size of the frame by using the `setSize(width, height)` method on the frame. `width` and `height` are specified in pixels. The size of the frame is up to you. Figure out what works best on your screen. This can be done in the constructor. 55 | 56 | ```java 57 | _frame.setSize(400, 400); 58 | _frame.setVisible(true); 59 | 60 | ``` 61 | 62 | You can set what should happen the user closes the window. In many cases, we will want the program to exit; in others, we would want other events to occur. For example, if you have multiple Firefox windows open, and you close one, you would not want the whole program to exit! In our case, though, since we will have only one window and we will not need it to run in the background. You can also do this in the constructor. 63 | 64 | ```java 65 | _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 66 | ``` 67 | 68 | Feel free to look at the JFrame API (https://docs.oracle.com/javase/8/docs/api/javax/swing/JFrame.html) to see what else you can do! Look under WindowConstants. 69 | 70 | Now, we want to have two sections of the frame. Each of these sections is called a panel, and like good Swing classes, are called JPanels. Create them 71 | 72 | ```java 73 | JPanel _ttt = new JPanel(); 74 | JPanel _newPanel = new JPanel(); 75 | ``` 76 | 77 | The top panel is going to be a grid layout (that is, it will have all of its elements in a two-dimensional grid, just like a Tic-Tac-Toe board). Each spot in the grid will be a button. The bottom panel is only going to have one button in it, so it doesn't really matter what layout we use. 78 | 79 | In the constructor, set their respective layouts: 80 | 81 | ```java 82 | _ttt.setLayout(new GridLayout(3, 3)); 83 | _newPanel.setLayout(new FlowLayout()); 84 | ``` 85 | 86 | The Grid layout will position any elements (e.g. textboxes, buttons, labels, etc.) in a 3x3 layout. The FlowLayout will just position the elements one after another, like letters in a line of text. Also like a line of text, when no more elements fit, it will go "down" to the next line. 87 | 88 | Now in the constructor, position them like so: 89 | 90 | ```java 91 | 92 | // This will place the tic-tac-toe panel at the top of 93 | // the frame and the newPanel panel at the bottom 94 | _frame.add(_ttt, BorderLayout.NORTH); 95 | _frame.add(_newPanel, BorderLayout.SOUTH); 96 | 97 | ``` 98 | 99 | 100 | Create nine buttons to put in the 3x3 layout and add them. You can do this with a simple for loop: 101 | 102 | ```java 103 | public class TicTacToe { 104 | JButton[] _buttons = new JButton[9]; 105 | ... 106 | ``` 107 | 108 | In the constructor: 109 | 110 | ```java 111 | for (int j=0; j<9; j++) { 112 | // Make a new button in the array location with text "_" 113 | _buttons[j] = new JButton("_"); 114 | // Associate a new ButtonListener to the button (see below) 115 | ActionListener buttonListener = new ButtonListener(); 116 | _buttons[j].addActionListener(buttonListener); 117 | // Set the font on the button 118 | _buttons[j].setFont(new Font("Courier", Font.PLAIN, 48)); 119 | // Add this button to the _ttt panel 120 | _ttt.add(_buttons[j]); 121 | } 122 | ``` 123 | 124 | This will create nine buttons along with their _listeners_ - that is, objects that "listen" for an event to take place, and then execute code when it happens. We will fill in the listeners soon. 125 | 126 | Before you can compile, add a ButtonListener. This can be an internal (non-public) class. In our case, we will start with a button which just changes to X when it is pressed. 127 | 128 | ```java 129 | class ButtonListener implements ActionListener { 130 | 131 | // Every time we click the button, it will perform 132 | // the following action. 133 | 134 | public void actionPerformed(ActionEvent e) { 135 | / 136 | JButton source = (JButton) e.getSource(); 137 | String currentText = source.getText(); 138 | if (currentText.equals("_")) { 139 | source.setText("X"); 140 | } else { 141 | source.setText("_"); 142 | } 143 | } 144 | 145 | } 146 | 147 | ``` 148 | 149 | Their default text on the button is `"_"` (the String argument to the JButton constructor). When a user presses a button, the associated ActionListener for the clicked button will have its actionPerformed(ActionEvent e) method called. We associated the listener with our button when we did the `_buttons[j].addActionListener(buttonListener);` statement. Now when a button is pressed, the actionPerformed event actions take place. If the text was a `"_"`, it will be changed to an `"X"`; otherwise, it will be set back to `"_"`. 150 | 151 | Using the above code as a base, create one button and listener for the other panel in the layout (`newPanel`). 152 | 153 | Using the previous steps as a base, create the listener for the "new game" button. It should "erase" all of the buttons, putting them back to their default text when pressed. 154 | 155 | Using the previous steps as a base, create a boolean variable which flip-flops every time somebody presses a button. The first time a button is pressed, the player should be an X, the second time an O, the third time an X, etc. You can determine whether to make the spot an X or O based on this flip-flop variable. 156 | 157 | Finally, add code to ensure that users cannot press a button which is already an X or an O. 158 | 159 | ### Additional Information 160 | 161 | Feel free to take a look at the sample code for these classes to help put the system together: 162 | 163 | 1. Frames - https://github.com/laboon/cs0401/blob/master/sample_code/FrameDemo.java 164 | 1. Panels - https://github.com/laboon/cs0401/blob/master/sample_code/PanelDemo.java and https://github.com/laboon/cs0401/blob/master/sample_code/PanelDemo2.java 165 | 2. Extending Panels - https://github.com/laboon/cs0401/tree/master/sample_code/extended_jpanel 166 | 3. Creating and Interacting with Buttons - https://github.com/laboon/cs0401/blob/master/sample_code/ButtonDemo.java 167 | 4. Creating a Grid Layout - https://github.com/laboon/cs0401/blob/master/sample_code/GridDemo.java 168 | 5. Dynamically Changing A Button - https://github.com/laboon/cs0401/blob/master/sample_code/NameChangeButtonDemo.java 169 | 170 | Remember that part of being a software engineer is knowing how to look things up on your own! If you don't understand how something works, feel free to look at the Java API pages (http://docs.oracle.com/javase/8/docs/api/). 171 | 172 | For fun, you can add code to detect when a player has won or lost. For even more fun, add some artificial intelligence and have the computer play the user! However, neither of these is necessary. 173 | 174 | Working code will be put up on GitHub in this directory sometime after class today. -------------------------------------------------------------------------------- /exercises/threads-exercise/Pi.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.atomic.*; 2 | import java.util.concurrent.*; 3 | import java.util.concurrent.ThreadLocalRandom; 4 | 5 | public class Pi { 6 | 7 | // The shared total count. 8 | 9 | public static AtomicLong _count = new AtomicLong(0); 10 | 11 | // Another (less efficient) way of doing this is constantly 12 | // update the _total and _count. We'll minimize synchronization 13 | // here in order to help performance. 14 | 15 | // public static AtomicLong _total = new AtomicLong(0); 16 | 17 | // Array of threads which we will start. We don't know how 18 | // many are in here at this point. 19 | 20 | public Thread[] _threads; 21 | 22 | // Calculate 23 | 24 | public void calculate(long numThreads, long numIters) { 25 | 26 | // We now know how many threads, so 27 | // Note that we can only create an int-sized array, so 28 | // we had to cast our long to (int) 29 | _threads = new Thread[(int) numThreads]; 30 | 31 | // Note that we have a slight issue due to rounding 32 | // here if numIters is not evenly divisible by numThreads. 33 | // This should probably be fixed if we really cared about 34 | // accuracy. But it won't make much of a difference 35 | // for large values. 36 | 37 | // Convert to final values so that lambda can use them. 38 | 39 | final long numItersFinal = numIters / numThreads; 40 | 41 | // Create threads 42 | 43 | for (int j = 0; j < _threads.length; j++) { 44 | 45 | _threads[j] = new Thread(() -> { 46 | int curIter = 0; 47 | int localCount = 0; 48 | while (curIter++ < numItersFinal) { 49 | // Generate random X and Y values from 0.0 to 1.0 50 | double x = ThreadLocalRandom.current().nextDouble(1); 51 | double y = ThreadLocalRandom.current().nextDouble(1); 52 | 53 | // Debug print statement 54 | // System.out.print("(" + x + "," + y + ")"); 55 | 56 | // If x^2 + y^2 < 1, the point is INSIDE the circle 57 | if ((x * x + y * y) < 1) { 58 | // in circle 59 | 60 | // AtomicLong way of doing it 61 | // Note this REALLY slows down your code! 62 | // This is due to MANY synchronizations 63 | // _count.incrementAndGet(); 64 | localCount++; 65 | 66 | } else { 67 | // out of circle 68 | // Do nothing 69 | 70 | } 71 | } 72 | 73 | // In this case, we'll use an AtomicLong to avoid 74 | // any data races. 75 | 76 | // A different approach to avoid ANY synchronization 77 | // issues is storing different elements in a 78 | // results array (not sharing any state) and then 79 | // adding all of the elements in the array after joining. 80 | 81 | // However, this will only cause n accesses to the 82 | // locked value (where n = number of threads) and so 83 | // there's not much of a performance hit. 84 | 85 | _count.addAndGet(localCount); 86 | 87 | }); 88 | } 89 | 90 | // Remember all of the threads have been created but are not 91 | // yet running. Start all threads in the array running below. 92 | 93 | for (int j = 0; j < _threads.length; j++) { 94 | _threads[j].start(); 95 | } 96 | 97 | // Now wait for all of them to finish before continuing. 98 | 99 | for (int j = 0; j < _threads.length; j++) { 100 | try { 101 | _threads[j].join(); 102 | } catch (Exception ex) { } 103 | } 104 | 105 | // We already know the number of iterations, we sent in the value! 106 | 107 | long t = numIters; // _total.get(); 108 | 109 | // Number of points inside the circle 110 | 111 | long c = _count.get(); 112 | 113 | // Ratio = c / t. Forcing floating-point arithmetic by 114 | // casting c as double (could cast t, as well, it's arbitrary) 115 | 116 | double r = ((double) c / t); 117 | 118 | // Print out results 119 | 120 | System.out.println("Total = " + t); 121 | System.out.println("Inside = " + c); 122 | System.out.println("Ratio = " + r); 123 | System.out.println("Pi = " + (r * 4)); 124 | 125 | 126 | } 127 | 128 | public static void main(String[] args) { 129 | 130 | // I do no error-checking here. Proceed at your own risk. 131 | 132 | long numThreads = Long.parseLong(args[0]); 133 | long numIters = Long.parseLong(args[1]); 134 | 135 | // Avoiding doing anything static by creating a Pi object. 136 | 137 | Pi pi = new Pi(); 138 | 139 | // Start calculating! 140 | 141 | pi.calculate(numThreads, numIters); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /exercises/threads-exercise/hints.md: -------------------------------------------------------------------------------- 1 | 1. Are you synchronizing properly? 2 | 3 | 2. Are you joining at the correct point? 4 | 5 | 3. Are you remembering to split the number of iterations amongst all threads? 6 | 7 | 4. Should you be using AtomicLong or similar Atomic variables? 8 | 9 | 5. Remember that synchronizing is computationally expensive. Are you minimizing the number of synchronizations? 10 | 11 | 6. Can you reduce shared mutable state? 12 | 13 | 7. Is there any information which you are re-calculating but it is not actually necessary to do so? 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /exercises/threads-exercise/threads-exercise.md: -------------------------------------------------------------------------------- 1 | ## Threads Exercise 2 | 3 | You and a partner are going to discover the value of pi through the magic of threads! 4 | 5 | First, let's discuss the _Monte Carlo_ method of calculation. In a Monte Carlo experiment, large numbers of random values are repeatedly tried, instead of using a deterministic algorithm. It is a form of stochastic testing. The benefit of using these methods is that sometimes trying to use a deterministic algorithm is infeasible, would require too much computation, or we do not know the underlying algorithm. 6 | 7 | For example, let's say we wanted to know how large a dartboard's bullseye is compared to the size of the dartboard. We throw twenty darts at it, aiming at different random parts of the board. Two end up in the bullseye. So we determine that 2 / 20, or 10%, of the board is the bullseye. Note that we are not guaranteed to get this value or anything close to it the next time we do this experiment. Perhaps next time, all of our darts miss the bullseye, and so we estimate that the size is 0% of the board. Or by change, every single dart of ours hits the bullseye, and we estimate that the bullseye takes up 100% of the board. 8 | 9 | This is one of the downsides of using a Monte Carlo method of calculation - it's not always replicable. However, with larger numbers, we _should_ get closer and closer to the true value (we will approach the value, if you will). Let's throw a million darts at the board, and we notice that 30,000 darts land in the bullseye. Assuming our throws were sufficiently random, we can say with relative confidence that the bullseye takes up 3% of the board (30000 / 1000000). It is very unlikely - but of course possible! - that it takes up 20% of the board, but only 3% of a million randomly-thrown darts ended up in it. 10 | 11 | For this project, let's assume that we do not know the value of _pi_, but we would like to discover it. Something we can do is think of a unit square (that is, each side is 1 "unit"), and throw a "dart" at some random point on it (with x and y both somewhere between 0.000 and 1.000). If x^2 + y^2 < 1, then that point is "inside" the circle. See this illustration: https://en.wikipedia.org/wiki/Monte_Carlo_method#/media/File:Pi_30K.gif 12 | 13 | After we have run this simulation many times, we can figure out the ratio between how many points were inside the circle and the total number of points. This should be multiplied by four (since we were looking at a "quarter" of the circle). This will allow us to calculate an estimate of pi. 14 | 15 | A more detailed description of the math is here: http://mathfaculty.fullerton.edu/mathews/n2003/montecarlopimod.html 16 | 17 | Since we're running many calculations which are basically independent of each other, this is an excellent opportunity to use threads! 18 | 19 | You will write a program which accepts two long arguments. The first will indicate how many threads the program should use, and the second how many total iterations. Note that the number of iterations should remain constant - for example, if I say 10,000 iterations, and have 4 threads, each thread should calculate 2,500 times. 20 | 21 | This program will tell the user the total number of iterations, the total number of values "inside" the circle, the ratio of points inside to total number of iterations, and finally calculate the value of pi from that. 22 | 23 | Note that you may not see significant differences in time until you work with rather larger numbers. For example, I used one billion (1,000,000,000) in the examples below. 24 | 25 | You should then time how long it takes the program to execute with a differing number of threads. Try to get it down to the minimum amount of time - this will differ based on different people's computers, especially depending on how many cores or virtual cores your computer's CPU has. 26 | 27 | If you are not seeing a reduction in time with more than one thread, even with large values, see the hints.md file in this directory. You can also ignore that file if you want to figure it all out on your own. 28 | 29 | One note: Using Math.random() will result in conflicts between multiple threads as they all try to access the static method. You should use ThreadLocalRandom to get random numbers - it's built into the Java API. Docs here: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadLocalRandom.html 30 | 31 | ### Sample Output 32 | 33 | ``` 34 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 35 | (16894) $ time java Pi 2 100 36 | Total = 100 37 | Inside = 90 38 | Ratio = 0.9 39 | Pi = 3.6 40 | 41 | real 0m0.312s 42 | user 0m0.185s 43 | sys 0m0.066s 44 | 45 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 46 | (16895) $ time java Pi 4 100 47 | Total = 100 48 | Inside = 89 49 | Ratio = 0.89 50 | Pi = 3.56 51 | 52 | real 0m0.166s 53 | user 0m0.182s 54 | sys 0m0.036s 55 | 56 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 57 | (16889) $ time java Pi 1 1000000000 58 | Total = 1000000000 59 | Inside = 785402183 60 | Ratio = 0.785402183 61 | Pi = 3.141608732 62 | 63 | real 0m5.996s 64 | user 0m5.990s 65 | sys 0m0.051s 66 | 67 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 68 | (16893) $ time java Pi 2 1000000000 69 | Total = 1000000000 70 | Inside = 785418050 71 | Ratio = 0.78541805 72 | Pi = 3.1416722 73 | 74 | real 0m3.206s 75 | user 0m6.162s 76 | sys 0m0.053s 77 | 78 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 79 | (16890) $ time java Pi 4 1000000000 80 | Total = 1000000000 81 | Inside = 785401494 82 | Ratio = 0.785401494 83 | Pi = 3.141605976 84 | 85 | real 0m2.780s 86 | user 0m9.980s 87 | sys 0m0.048s 88 | 89 | [laboon@Bills-MacBook-Pro-2 ~/pitt/pitt_private] 90 | (16892) $ time java Pi 20 1000000000 91 | Total = 1000000000 92 | Inside = 785430126 93 | Ratio = 0.785430126 94 | Pi = 3.141720504 95 | 96 | real 0m3.733s 97 | user 0m13.110s 98 | sys 0m0.075s 99 | ``` -------------------------------------------------------------------------------- /how_to_sign_up.md: -------------------------------------------------------------------------------- 1 | ## How To Sign Up For A Group 2 | 3 | 1. If you have not done so, create a GitHub user account. You can do so by going to https://education.github.com/pack to create a new student account. You can also create a regular account for this class (at https://github.com) but you do get lots of benefits by signing up for an educational account. 4 | 1. In your favorite web browser, go to https://github.com/laboon/CS1530_Spring2017 5 | 2. Click on `project_groups.md` 6 | 3. In the upper-right hand part of the page, there are three buttons - Raw, Blame, and History. Next to them is an icon of a pencil (for "Edit File"). Click on the pencil. 7 | 4. Edit the file to add your name to the appropriate group (or make a new group) using the appropriate Markdown format. In our case, this is two spaces, then an asterisk, and then your name. You can look at the "Namey McNamerson" entry as an example. 8 | 5. At the bottom of the screen, there is a box labeled "Commit Changes". Click on the FIRST (upper) textbox and type your name in here. Ignore the second (lower) textbox. 9 | 6. There are two radio buttons below the textboxes. Ensure that the one labeled "Create a new branch for this commit and start a pull request." is selected. This will create a new branch to be merged into the master branch (what everybody sees by default). The default name for the branch is fine. 10 | 7. Click on the green "Propose file change" button. 11 | 8. A new screen will come up. Just click on the "Crete pull request" button. 12 | 9. You are done! Note that you have _proposed_ this group, I have not approved it. Therefore, you will not see your name in the list until I have merged it to the master branch. However, you can verify that it's there by clicking on the "Pull requests" tab at the top of the screen and checking that your PR is listed. These are the list of PRs (pull requests) that I have not yet merged. I try to merge them to master as soon as I see them. 13 | 14 | _If you have any questions or issues, please feel free to email me._ -------------------------------------------------------------------------------- /lectures/A_Friendly_Introduction_to_Git_And_GitHub.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/A_Friendly_Introduction_to_Git_And_GitHub.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Fiat_Voluntas_Tua.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Fiat_Voluntas_Tua.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture10-11_Methodologies.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture10-11_Methodologies.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture11_QA_Quality_Software.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture11_QA_Quality_Software.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture12_SoftwareDesign.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture12_SoftwareDesign.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture13_OO_Design.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture13_OO_Design.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture14_Integration.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture14_Integration.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture15_Concurrency.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture15_Concurrency.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture16_Concurrency2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture16_Concurrency2.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture17_Legacy_Code.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture17_Legacy_Code.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture18_DesignPatterns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture18_DesignPatterns.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture18_SoftwareCraftsmanship.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture18_SoftwareCraftsmanship.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture2_SDLC.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture2_SDLC.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture3_AgileScrum.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture3_AgileScrum.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture4_StakeholderInteraction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture4_StakeholderInteraction.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture7_GradleBuildTool.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture7_GradleBuildTool.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture8_TDD.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture8_TDD.pdf -------------------------------------------------------------------------------- /lectures/CS1530_Lecture9_OOTDDEngineering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1530_Spring2017/5ee5e3e13121b6a329465b38a207782721a44852/lectures/CS1530_Lecture9_OOTDDEngineering.pdf -------------------------------------------------------------------------------- /lectures/lecture1-intro.md: -------------------------------------------------------------------------------- 1 | * What is software engineering? 2 | 3 | * How does it differ from programming? 4 | 5 | * How does it differ from computer science? 6 | 7 | CS: Physics, Programming: Construction, SE: Civil Engineering 8 | 9 | * How did I prepare? Went back and looked at my old class homeworks. 10 | 11 | What did I use in the last fifteen years? 12 | 13 | What did I not use? 14 | 15 | * My Philosophy for this Course 16 | 17 | Hands-on. Project-based. Discussion-based. 18 | 19 | Focus on practical applications of theory. 20 | 21 | REAL ARTISTS SHIP - YOU WILL NEED TO MAKE TRADE-OFFS 22 | 23 | * Why should you NOT take this course? 24 | 25 | Not interested in practical applications 26 | 27 | Never going to write software > 20 lines of code 28 | 29 | You want a professor who only reads off of slides 30 | 31 | Want a professor who wears a tie to class 32 | 33 | * Why should you take this course? 34 | 35 | You want to write better software 36 | 37 | You want to work effectively 38 | 39 | You want to know what I meant by "better" and "effectively" 40 | 41 | What do you think I mean by "better"? What makes software "good"? 42 | 43 | * Go over course info 44 | 45 | * Go over syllabus 46 | 47 | -------------------------------------------------------------------------------- /project_groups.md: -------------------------------------------------------------------------------- 1 | ## Project Groups 2 | 3 | Please add your name to a group using a PR. Be sure you come up with a name for your software company/group and provide a slogan or talk of your group's programming philosophy. You may choose an already-existing group if it has fewer than four members. Or you may create your own group. 4 | 5 | If you don't know how to issue a PR, please see the file how_to_sign_up.md in this directory for detailed instructions. 6 | 7 | Format: 8 | 9 | ## EXAMPLE GROUP NAME 10 | 11 | _We don't engineer software, software engineers us!_ 12 | 13 | * Namey McNamerson 14 | * Name N. Namer 15 | 16 | ---- 17 | 18 | ## The Dining Philosophers 19 | 20 | _//TODO Review witty software motto at first sprint meeting._ 21 | _We code, therefore we are_ 22 | 23 | * Nicholas Denu 24 | * Brandon Torchia 25 | * Aleks Tapinsh 26 | * Audrey Ann Blakely 27 | 28 | ---- 29 | 30 | ## The Software Engineering Cowards 31 | 32 | _Scrum is spooky and evil and we are a'fear of it sir._ 33 | 34 | * Brian Ashworth 35 | * John Johnson 36 | * Edwin Mellet 37 | * Aaron Tamenne 38 | 39 | ---- 40 | 41 | ## Cool People 42 | 43 | _We don't know what we're doing!_ 44 | 45 | * Vivien Chang 46 | * Jennifer Zysk 47 | * Keri Bookleiner 48 | * Max Garber 49 | 50 | --- 51 | 52 | ## Pessimistic Estimator 53 | 54 | _"You know what the problem with rose colored glass is? When you're wearing them you can never see the red flags."_ 55 | _"Java is to JavaScript as Car is to Carpet."_ 56 | 57 | * Stephen Pappas 58 | * Pulkit Mittal 59 | * Steve Roomberg 60 | * Henrique Machado 61 | 62 | --- 63 | 64 | ## Quick and Agile Scrumbags (QAS) 65 | 66 | _"PROGRAMMER? I HARDLY KNOW HER"_ 67 | _"The Field Mouse is fast, but the Owl sees at night."_ 68 | 69 | * Timothy Kang 70 | * Daniel Justice 71 | * George Mattesi 72 | * Zach Gannon 73 | 74 | --- 75 | 76 | ## The No Ideas 77 | 78 | _Not compiling is not an option_ 79 | 80 | * Matthew Turley 81 | * Kyle Plump 82 | * Ken Morse 83 | * Matthew Strayhorn 84 | 85 | --- 86 | 87 | ## The New Ideas 88 | 89 | _We are not a knockoff of "The No Ideas" we swear!_ 90 | 91 | * Daniel Nestor 92 | * Ish Davis 93 | * Nathan Anuskiewicz 94 | * Jason Tucker 95 | * Austin Marcus 96 | 97 | ---- 98 | 99 | ## Nasty Women 100 | 101 | _The future is female_ 102 | 103 | * Therese Dachille 104 | * Nicole Daniels 105 | * Kristen Gardner 106 | * Rachel McQuown 107 | 108 | ---- 109 | 110 | ## $team 111 | 112 | _//TODO whitty slogen_ 113 | 114 | * Peter McCloskey 115 | * Guiseppe Zielinski 116 | * Jason Tucker 117 | * Jennifer Fang 118 | * Michael Oles 119 | -------------------------------------------------------------------------------- /sample_code/DecoratorDemo.java: -------------------------------------------------------------------------------- 1 | public class DecoratorDemo { 2 | 3 | public static void main(String[] args) { 4 | 5 | System.out.println("\nCoyote 1\n"); 6 | 7 | Coyote c1 = new SimpleCoyote(); 8 | c1.chase(); 9 | 10 | System.out.println("\nCoyote 2\n"); 11 | 12 | Coyote c2 = new CoyoteRocketDecorator(new SimpleCoyote()); 13 | c2.chase(); 14 | 15 | System.out.println("\nCoyote 3\n"); 16 | 17 | Coyote c3 = new CoyoteRocketDecorator(new CoyoteRollerSkatesDecorator ( new SimpleCoyote() )); 18 | c3.chase(); 19 | 20 | System.out.println("\nCoyote 4\n"); 21 | 22 | Coyote c4 = new CoyoteRocketDecorator(new CoyoteRocketDecorator ( new CoyoteRocketDecorator(new CoyoteRollerSkatesDecorator ( new SimpleCoyote() )))); 23 | c4.chase(); 24 | 25 | } 26 | } 27 | 28 | interface Coyote { 29 | 30 | public void chase(); 31 | 32 | } 33 | 34 | class SimpleCoyote implements Coyote { 35 | 36 | public void chase() { System.out.println("Chase!"); } 37 | 38 | } 39 | 40 | abstract class CoyoteDecorator implements Coyote { 41 | 42 | protected Coyote _decoratedCoyote; 43 | 44 | public CoyoteDecorator(Coyote c) { 45 | _decoratedCoyote = c; 46 | } 47 | 48 | public void chase() { 49 | _decoratedCoyote.chase(); 50 | } 51 | 52 | } 53 | 54 | class CoyoteRocketDecorator extends CoyoteDecorator { 55 | 56 | 57 | public CoyoteRocketDecorator(Coyote c) { 58 | super(c); 59 | } 60 | 61 | @Override 62 | public void chase() { 63 | super.chase(); 64 | chaseOnRocket(); 65 | } 66 | 67 | private void chaseOnRocket() { System.out.println("Chase on Rocket!"); } 68 | 69 | } 70 | 71 | class CoyoteRollerSkatesDecorator extends CoyoteDecorator { 72 | 73 | public CoyoteRollerSkatesDecorator(Coyote c) { 74 | super(c); 75 | } 76 | 77 | @Override 78 | public void chase() { 79 | super.chase(); 80 | chaseOnRollerSkates(); 81 | } 82 | 83 | private void chaseOnRollerSkates() { System.out.println("Chase on Roller Skates!"); } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /sample_code/complexity/Foo2.bytecode: -------------------------------------------------------------------------------- 1 | Compiled from "Foo2.java" 2 | public class Foo2 { 3 | public Foo2(); 4 | Code: 5 | 0: aload_0 6 | 1: invokespecial #1 // Method java/lang/Object."":()V 7 | 4: return 8 | 9 | public static void main(java.lang.String[]); 10 | Code: 11 | 0: iconst_0 12 | 1: istore_1 13 | 2: iconst_0 14 | 3: istore_2 15 | 4: iload_2 16 | 5: bipush 10 17 | 7: if_icmpge 52 18 | 10: iload_2 19 | 11: iconst_2 20 | 12: imul 21 | 13: istore_1 22 | 14: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 23 | 17: new #3 // class java/lang/StringBuilder 24 | 20: dup 25 | 21: invokespecial #4 // Method java/lang/StringBuilder."":()V 26 | 24: iload_2 27 | 25: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 28 | 28: ldc #6 // String doubled is 29 | 30: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30 | 33: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 31 | 36: invokevirtual #9 // Method java/io/PrintStream.print:(Ljava/lang/String;)V 32 | 39: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 33 | 42: iload_1 34 | 43: invokevirtual #10 // Method java/io/PrintStream.println:(I)V 35 | 46: iinc 2, 1 36 | 49: goto 4 37 | 52: return 38 | } 39 | -------------------------------------------------------------------------------- /sample_code/complexity/Foo2.java: -------------------------------------------------------------------------------- 1 | public class Foo2 { 2 | 3 | public static void main(String[] args) { 4 | int i = 0; 5 | for (int j = 0; j < 10; j++) { 6 | i = j * 2; 7 | System.out.print(j + " doubled is "); 8 | System.out.println(i); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample_code/concurrency/Atomic.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.atomic.*; 2 | 3 | public class Atomic { 4 | 5 | // Atomic version of Long class 6 | // Note that there are lots of Atomic variants - 7 | // AtomicBoolean, AtomicLongArray, AtomicInteger, etc. 8 | // See https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html 9 | 10 | public static AtomicLong _a = new AtomicLong(5); 11 | 12 | // Our unsynchronized long 13 | 14 | public static Long _l = new Long(5); 15 | 16 | // Our synchronized Long 17 | 18 | public static Long _sl = new Long(5); 19 | 20 | public static final long NUM_TIMES = 100000; 21 | 22 | public static void main(String[] args) { 23 | 24 | Object lock2 = new Object(); 25 | 26 | Thread t1 = new Thread(() -> { 27 | for (int j = 0; j < NUM_TIMES; j++) { 28 | // Note that our API is slightly different 29 | // for Atomic* types! 30 | // Allow us to do multiple things atomically 31 | // Also note this method returns the new value 32 | // but we are implicitly throwing it away 33 | // synchronized(lock2) { 34 | _a.incrementAndGet(); 35 | // } 36 | } 37 | }); 38 | 39 | Thread t2 = new Thread(() -> { 40 | for (int j = 0; j < NUM_TIMES; j++) { 41 | // synchronized(lock2) { 42 | _a.decrementAndGet(); 43 | // } 44 | } 45 | }); 46 | try { 47 | t1.start(); 48 | t2.start(); 49 | t1.join(); 50 | t2.join(); 51 | } catch (InterruptedException iex) { } 52 | System.out.println("Atomic long is: " + _a); 53 | // System.exit(0); 54 | // Do the same thing, with a regular Long 55 | 56 | Thread t3 = new Thread(() -> { 57 | for (int j = 0; j < NUM_TIMES; j++) { 58 | // No way to perform an increment atomically 59 | // on long 60 | _l++; 61 | } 62 | }); 63 | 64 | Thread t4 = new Thread(() -> { 65 | for (int j = 0; j < NUM_TIMES; j++) { 66 | _l--; 67 | } 68 | }); 69 | 70 | try { 71 | t3.start(); 72 | t4.start(); 73 | t3.join(); 74 | t4.join(); 75 | } catch (InterruptedException iex) { } 76 | 77 | System.out.println("Regular long is: " + _l); 78 | 79 | // We CAN use a regular Long, but we will need to make sure 80 | // that we synchronize on some shared object 81 | 82 | // Note that there is now the chance for error since we a 83 | // are forced to remember to synchronize EVERY time we use 84 | // that variable! And remember what to sync on! 85 | 86 | Object lock = new Object(); 87 | 88 | Thread t5 = new Thread(() -> { 89 | for (int j = 0; j < NUM_TIMES; j++) { 90 | // Note that we are synchronizing on a 91 | // RELEVANT object (_l) instead of just 92 | // a random one as we did when I 93 | // introduced locking and synchronization 94 | 95 | synchronized(lock) { 96 | _sl += 1; 97 | } 98 | } 99 | }); 100 | 101 | Thread t6 = new Thread(() -> { 102 | for (int j = 0; j < NUM_TIMES; j++) { 103 | synchronized(lock) { 104 | _sl -= 1; 105 | } 106 | } 107 | }); 108 | 109 | try { 110 | t5.start(); 111 | t6.start(); 112 | t5.join(); 113 | t6.join(); 114 | } catch (InterruptedException iex) { } 115 | 116 | 117 | // Print out results 118 | 119 | System.out.println("Synchronized long is: " + _sl); 120 | 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /sample_code/concurrency/BadConcurrency.java: -------------------------------------------------------------------------------- 1 | public class BadConcurrency { 2 | 3 | public static int x = 0; 4 | 5 | public static final int NUM_TIMES = 100000; 6 | 7 | public static void main(String[] args) { 8 | 9 | // Start thread 1, which will add 100,000 to x 10 | 11 | Thread t1 = new Thread(() -> { 12 | for (int j = 0; j < NUM_TIMES; j++) { 13 | x++; 14 | } 15 | }); 16 | 17 | // Start thread 1, which will subtract 100,000 from x 18 | 19 | Thread t2 = new Thread(() -> { 20 | for (int j = 0; j < NUM_TIMES; j++) { 21 | x--; 22 | } 23 | }); 24 | 25 | // Start off both threads 26 | t1.start(); 27 | t2.start(); 28 | 29 | // Wait for both to finish 30 | 31 | try { 32 | t1.join(); 33 | t2.join(); 34 | } catch (InterruptedException iex) { } 35 | 36 | // Print out final result - we have done x++ 37 | // and x-- the same number of times 38 | 39 | System.out.println("x is now " + x); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample_code/concurrency/BetterConcurrency.java: -------------------------------------------------------------------------------- 1 | // In this case, every time we increment or decrement x, 2 | // we ensure that is an ATOMIC operation. 3 | // Either t1 or t2 has the lock on Object ref, 4 | // but never both, so they will never interleave. 5 | 6 | public class BetterConcurrency { 7 | 8 | public static int x = 0; 9 | 10 | public static final int NUM_TIMES = 1000000; 11 | 12 | public static void main(String[] args) { 13 | 14 | final Object ref = new Object(); 15 | 16 | Thread t1 = new Thread(() -> { 17 | for (int j = 0; j < NUM_TIMES; j++) { 18 | synchronized(ref) { 19 | x++; 20 | } 21 | } 22 | }); 23 | Thread t2 = new Thread(() -> { 24 | for (int j = 0; j < NUM_TIMES; j++) { 25 | synchronized(ref) { 26 | x--; 27 | } 28 | } 29 | }); 30 | 31 | // Start off both threads 32 | t1.start(); 33 | t2.start(); 34 | 35 | // Wait for both to finish 36 | 37 | try { 38 | t1.join(); 39 | t2.join(); 40 | } catch (InterruptedException iex) { } 41 | 42 | // Print out final result - we have done x++ 10000 times 43 | // and x-- 10000 times 44 | 45 | System.out.println("x is now " + x); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample_code/concurrency/ConcurrentCalculator.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | // Perform the same calculations as we did in the SynchronousCalculator, 4 | // but this time using threads 5 | 6 | // For explanation of different performance characteristics, see 7 | // Amdahl's Law - https://en.wikipedia.org/wiki/Amdahl%27s_law 8 | // This is an "embarassingly parallel" problem 9 | 10 | public class ConcurrentCalculator { 11 | 12 | /** 13 | * Helper method for printing out arrays. 14 | * @param int[] arr Array of integers to print 15 | */ 16 | public static void printArray(int[] arr) { 17 | System.out.print("[ "); 18 | for (int j=0; j < (arr.length - 1); j++) { 19 | System.out.print(arr[j] + ", "); 20 | } 21 | if (arr.length > 0) { 22 | System.out.print(arr[arr.length - 1]); 23 | } 24 | System.out.println(" ]"); 25 | 26 | } 27 | 28 | /** 29 | * Generate initial array, where location 0 has 30 | * value 0, location 1 value 1, etc. 31 | */ 32 | 33 | private static int[] generateInitialArray(int n) { 34 | int[] toReturn = new int[n]; 35 | for (int j = 0; j < n; j++) { 36 | toReturn[j] = j; 37 | } 38 | return toReturn; 39 | } 40 | 41 | /** 42 | * Placeholder for complex calculation 43 | */ 44 | 45 | private static int calculate(int n) { 46 | int x = n; 47 | for (int j = 0; j < 100000; j++) { 48 | for (int k = 0; k < 20; k++) { 49 | x += k * Math.atan(n); 50 | } 51 | x += Math.acos(n); 52 | x -= j * Math.sin(n); 53 | } 54 | return x; 55 | } 56 | 57 | 58 | public static void main(String[] args) { 59 | 60 | int n = -1; 61 | 62 | try { 63 | n = Integer.parseInt(args[0]); 64 | if (n < 1) { 65 | throw new Exception(); 66 | } 67 | } catch (Exception ex) { 68 | System.out.println("Expected positive int as argument!"); 69 | System.exit(1); 70 | } 71 | 72 | int[] initialArray = generateInitialArray(n); 73 | final int[] newArray = new int[initialArray.length]; 74 | 75 | printArray(initialArray); 76 | 77 | // Create an array which will hold n threads. 78 | 79 | Thread[] ts = new Thread[n]; 80 | 81 | for (int j = 0; j < initialArray.length; j++) { 82 | 83 | // Any external variables we access in a lambda must be final 84 | // Since j will never need to be modified by the lambda, it's 85 | // fine to just make a final version of it. 86 | 87 | final int fj = j; 88 | 89 | // For each element, create a new thread with a Runnable lambda. 90 | // Note that this is very similar to defining an "anonymous method" 91 | 92 | ts[fj] = new Thread(() -> 93 | { 94 | newArray[fj] = calculate(initialArray[fj]); 95 | System.out.println("Finished calculating " + fj); 96 | 97 | }); 98 | 99 | // We have now created a thread and it is ready to work, but not doing 100 | // anything yet! 101 | } 102 | try { 103 | 104 | // Start each individual thread to calculate. 105 | 106 | for (Thread t : ts) t.start(); 107 | 108 | // All threads must be complete before any further progress in our 109 | // main thread. What do you think will happen if we comment this out? 110 | // Note that if you do comment it out, the compiler will yell about 111 | // our try catch block since no InterruptedException is thrown in the block. 112 | // It's OK if we just catch a generic Exception since a generic Exception 113 | // could theoretically be thrown at any point. 114 | 115 | for (Thread t : ts) t.join(); 116 | 117 | // } catch (Exception iex) { } 118 | } catch (InterruptedException iex) { } 119 | 120 | printArray(newArray); 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /sample_code/concurrency/ConcurrentHashMapDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.ConcurrentHashMap; 2 | 3 | public class ConcurrentHashMapDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | // Remember hashes are key-value pairs 8 | // e.g. animal id number to noise it makes 9 | // 1 -> "meow" 10 | // 17 -> "moo" 11 | // 4 -> "cluck" 12 | // Can be in any order, can be gaps 13 | 14 | ConcurrentHashMap h = new ConcurrentHashMap(); 15 | 16 | final int NUM_TIMES = 9999999; 17 | 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | h.put(j, "chirp"); 20 | } 21 | 22 | for (int j = 0; j < NUM_TIMES; j++) { 23 | h.remove(j); 24 | } 25 | 26 | System.out.println("Final size of hash is " + h.size()); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample_code/concurrency/DavidConcurrency.java: -------------------------------------------------------------------------------- 1 | // In this case, every time we increment or decrement x, 2 | // we ensure that is an ATOMIC operation. 3 | // Either t1 or t2 has the lock on Object ref, 4 | // but never both, so they will never interleave. 5 | 6 | public class DavidConcurrency { 7 | 8 | public static int x = 0; 9 | 10 | public static final int NUM_TIMES = Integer.MAX_VALUE; 11 | 12 | public static void main(String[] args) { 13 | 14 | for (int j = 0; j < NUM_TIMES; j++) { 15 | x++; 16 | } 17 | 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | x--; 20 | } 21 | 22 | // Print out final result - we have done x++ 10000 times 23 | // and x-- 10000 times 24 | 25 | System.out.println("x is now " + x); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sample_code/concurrency/Deadlock.java: -------------------------------------------------------------------------------- 1 | // A demonstration of deadlock 2 | 3 | public class Deadlock { 4 | 5 | // We have two resources to lock on, printer and scanner 6 | 7 | public static Printer printer = new Printer(); 8 | 9 | public static Scanner scanner = new Scanner(); 10 | 11 | public static void main(String[] args) { 12 | 13 | // Thread 1 is going to attempt to get the printer first, then scanner 14 | // Thread 2 is going to attempt to get the scanner first, then printer 15 | 16 | // Thread 1 gets printer 17 | // Thread 2 gets scanner 18 | // Thread 1 is now waiting for the scanner to be free 19 | // Thread 2 is now waiting for the printer to be free 20 | // Neither will ever be! Each is waiting for the other 21 | 22 | Thread t1 = new Thread(() -> { 23 | synchronized(printer) { 24 | printer.print("thread 1"); 25 | try { 26 | Thread.sleep(100); 27 | } catch (InterruptedException iex) {} 28 | 29 | synchronized(scanner) { 30 | scanner.scan("thread 1"); 31 | try { 32 | Thread.sleep(100); 33 | } catch (InterruptedException iex) {} 34 | 35 | 36 | } 37 | } 38 | }); 39 | 40 | Thread t2 = new Thread(() -> { 41 | synchronized(scanner) { 42 | scanner.scan("thread 2"); 43 | try { 44 | Thread.sleep(100); 45 | } catch (InterruptedException iex) {} 46 | synchronized(printer) { 47 | printer.print("thread 2"); 48 | try { 49 | Thread.sleep(100); 50 | } catch (InterruptedException iex) {} 51 | 52 | } 53 | } 54 | }); 55 | 56 | // Start threads and wait for them finish 57 | 58 | t1.start(); 59 | t2.start(); 60 | try { 61 | t1.join(); 62 | t2.join(); 63 | } catch (InterruptedException iex) { } 64 | 65 | // We'll never get to this point. How can we fix it? 66 | 67 | System.out.println("Everything went well"); 68 | } 69 | 70 | } 71 | 72 | // Two filler classes, just showing example resources to lock on 73 | 74 | class Printer { 75 | public void print(String x) { 76 | System.out.println("Printing, from " + x); 77 | } 78 | } 79 | 80 | class Scanner { 81 | public void scan(String x) { 82 | System.out.println("Scanning, from " + x); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /sample_code/concurrency/FixedDeadlock.java: -------------------------------------------------------------------------------- 1 | // A demonstration of deadlock 2 | 3 | public class FixedDeadlock { 4 | 5 | // We have two resources to lock on, printer and scanner 6 | 7 | public static Printer printer = new Printer(); 8 | 9 | public static Scanner scanner = new Scanner(); 10 | 11 | public static void main(String[] args) { 12 | 13 | // Thread 1 is going to attempt to get the printer first, then scanner 14 | // Thread 2 is going to attempt to get the scanner first, then printer 15 | 16 | // Thread 1 gets printer 17 | // Thread 2 gets scanner 18 | // Thread 1 is now waiting for the scanner to be free 19 | // Thread 2 is now waiting for the printer to be free 20 | // Neither will ever be! Each is waiting for the other 21 | 22 | Thread t1 = new Thread(() -> { 23 | synchronized(printer) { 24 | printer.print("thread 1"); 25 | try { 26 | Thread.sleep(100); 27 | } catch (InterruptedException iex) {} 28 | 29 | synchronized(scanner) { 30 | scanner.scan("thread 1"); 31 | try { 32 | Thread.sleep(100); 33 | } catch (InterruptedException iex) {} 34 | 35 | 36 | } 37 | } 38 | }); 39 | 40 | Thread t2 = new Thread(() -> { 41 | synchronized(printer) { 42 | printer.print("thread 2"); 43 | 44 | try { 45 | Thread.sleep(100); 46 | } catch (InterruptedException iex) {} 47 | synchronized(scanner) { 48 | scanner.scan("thread 2"); 49 | try { 50 | Thread.sleep(100); 51 | } catch (InterruptedException iex) {} 52 | 53 | } 54 | } 55 | }); 56 | 57 | // Start threads and wait for them finish 58 | 59 | t1.start(); 60 | t2.start(); 61 | try { 62 | t1.join(); 63 | t2.join(); 64 | } catch (InterruptedException iex) { } 65 | 66 | // We'll never get to this point. How can we fix it? 67 | 68 | System.out.println("Everything went well"); 69 | } 70 | 71 | // Two filler classes, just showing example resources to lock on 72 | 73 | // class Printer { 74 | // public void print(String x) { 75 | // System.out.println("Printing, from " + x); 76 | // } 77 | // } 78 | 79 | // class Scanner { 80 | // public void scan(String x) { 81 | // System.out.println("Scanning, from " + x); 82 | // } 83 | // } 84 | 85 | 86 | } 87 | 88 | -------------------------------------------------------------------------------- /sample_code/concurrency/HowManyThreads.java: -------------------------------------------------------------------------------- 1 | public class HowManyThreads { 2 | 3 | public static void main(String[] args) { 4 | while (true) { 5 | System.out.println("Hello, world!"); 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /sample_code/concurrency/Increment.java: -------------------------------------------------------------------------------- 1 | // Remember that a line != a command! 2 | 3 | public class Increment { 4 | 5 | public static void main(String[] args) { 6 | byte a = 12; 7 | a += 1; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sample_code/concurrency/JoinDemo.java: -------------------------------------------------------------------------------- 1 | // Here, we have thread 1 ("xincr") incrementing variable x, 2 | // and thread 2 ("yincr") incrementing variable y. 3 | // Once they are done incrementing, will then print out values 4 | 5 | // What happens when we comment out the joins? 6 | 7 | public class JoinDemo { 8 | 9 | public static int x = 0; 10 | 11 | public static int y = 0; 12 | 13 | public static final int NUM_TIMES = 1000000; 14 | 15 | public static void main(String[] args) { 16 | 17 | Thread t1 = new Thread(() -> { 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | x++; 20 | } 21 | }); 22 | Thread t2 = new Thread(() -> { 23 | for (int j = 0; j < NUM_TIMES; j++) { 24 | y++; 25 | } 26 | }); 27 | 28 | // Start off both threads 29 | t1.start(); 30 | t2.start(); 31 | 32 | // Wait for both to finish 33 | System.out.println("Main thread of execution here..."); 34 | 35 | try { 36 | t1.join(); 37 | t2.join(); 38 | } catch (InterruptedException iex) { } 39 | 40 | System.out.println("x = " + x + " and y = " + y); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sample_code/concurrency/Livelock.java: -------------------------------------------------------------------------------- 1 | // Livelock 2 | 3 | // In this case, we have two friends who are very polite. 4 | // Both of them want to rent a cat from Rent-A-Cat, but they 5 | // don't want to rent it if their friend also wants it. 6 | // So each one is waiting until the other person has rented 7 | // the cat before they rent it themself. Every time they 8 | // try to rent the cat, they check to see if the other person 9 | // has rented it, and if not, they wait. However, since both 10 | // of them are waiting for the other, none will ever actually 11 | // get the cat! 12 | 13 | // This is not deadlock because there is work being done by 14 | // the CPU, it's just not useful. The two threads are "spinning 15 | // their wheels". 16 | 17 | // Another way to think of livelock as two people trying to walk 18 | // past each other in a hallway. As they approach each other, 19 | // Person A goes to the left and Person B goes to the right. 20 | // This means that they are both on the same side of the hallway, 21 | // and neither can get past the other. 22 | // ---------------------------------------------- 23 | // --->A B<---- 24 | // 25 | // ---------------------------------------------- 26 | 27 | // Now the algorithm for deciding how to go past the other person 28 | // is "go to the other side of the hallway". So both A and B 29 | // go to the other side. 30 | // ---------------------------------------------- 31 | // V V 32 | // A B 33 | // ---------------------------------------------- 34 | 35 | // But they're still blocked! So try the algorithm again - go to 36 | // the other side of the hallway. 37 | // ---------------------------------------------- 38 | // A B 39 | // ^ ^ 40 | // ---------------------------------------------- 41 | 42 | // Continue ad infinitum. There is definitely "work" being done as 43 | // the two people move endlessly back and forth, but it is not 44 | // useful work - no progress is being made. They are stuck in an 45 | // "infinite loop". 46 | 47 | public class Livelock { 48 | 49 | public static void main(String[] args) { 50 | final Renter r1 = new Renter("John"); 51 | final Renter r2 = new Renter("Jane"); 52 | 53 | final Cat c = new Cat(r1); 54 | 55 | new Thread(() -> { 56 | r1.rent(c, r2); 57 | }).start(); 58 | 59 | new Thread(() -> { 60 | r2.rent(c, r1); 61 | }).start(); 62 | } 63 | } 64 | 65 | class Cat { 66 | public Renter _renter; 67 | public Cat(Renter r) { _renter = r; } 68 | 69 | // Note that we are synchronizing on this for both setRenter 70 | // and rent. We should not have issues with accessing data 71 | // or data races here. 72 | 73 | public synchronized void setRenter(Renter r) { _renter = r; } 74 | public synchronized void rent() { 75 | System.out.println(_renter._name + " has rented the cat!"); 76 | } 77 | } 78 | 79 | class Renter { 80 | public String _name; 81 | public boolean _wantsCat; 82 | 83 | public Renter(String n) { 84 | _name = n; 85 | _wantsCat = true; 86 | } 87 | 88 | public void rent(Cat cat, Renter friend) { 89 | while (_wantsCat) { 90 | // Don't have the cat, so wait for friend. 91 | if (cat._renter != this) { 92 | try { 93 | Thread.sleep(1); 94 | } 95 | catch(InterruptedException iex) { } 96 | // Go back to the beginning of the loop and try again 97 | continue; 98 | } 99 | 100 | // If friend wants the cat, insist upon passing the cat. 101 | if (friend._wantsCat) { 102 | System.out.println("You can have the cat, " + friend._name + "!"); 103 | cat.setRenter(friend); 104 | // Go back to the beginning of the loop and try again 105 | continue; 106 | } 107 | 108 | // Friend no longer wants the cat, so finally rent it 109 | cat.rent(); 110 | _wantsCat = false; 111 | System.out.println(_name + " rented the cat!"); 112 | cat.setRenter(friend); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /sample_code/concurrency/LolWut.java: -------------------------------------------------------------------------------- 1 | // "volatile" is a Java keyword which means that the variable 2 | // will be read from main memory *every* time it is accessed. 3 | // It will not be hoisted or read from CPU cache. 4 | 5 | // Threading can result in really, really fun and interesting 6 | // bugs, which will react differently based on slight changes 7 | // in code. Sometimes a threading issue may only show up once every 8 | // several million - or more - times that a program is run. 9 | 10 | // Try commenting/uncommenting the System.out.println on line 11 | // 57 and see how often our (known) data race occurs. 12 | // Threading is a minefield! 13 | 14 | public class LolWut { 15 | 16 | public static final int NUM_TIMES = 10000; 17 | 18 | public static volatile boolean allDoneVolatile = false; 19 | 20 | public static boolean allDone = false; 21 | 22 | public static volatile int v = 0; 23 | 24 | public static int nv = 0; 25 | 26 | public static void main(String[] args) { 27 | 28 | final Object ref = new Object(); 29 | 30 | // Thread 1 is going to increment v and nv NUM_TIMES times 31 | 32 | Thread t1 = new Thread(() -> { 33 | for (int j = 0; j < NUM_TIMES; j++) { 34 | v++; 35 | nv++; 36 | try { 37 | Thread.sleep(0, 100); 38 | } catch (InterruptedException iex) { } 39 | } 40 | allDone = true; 41 | }); 42 | 43 | Thread t2 = new Thread(() -> { 44 | int lv = -1; 45 | int lnv = -1; 46 | while (!allDone) { 47 | lv = v; 48 | // System.out.println("lv = " + lv); 49 | lnv = nv; 50 | // System.out.println("lnv = " + lnv); 51 | 52 | if (lv != lnv) { 53 | System.out.println("1 DIFFERENT! lv = " + lv + ", lnv = " + lnv); 54 | } else { 55 | // Try commenting out this line and seeing how many times values 56 | // are different! 57 | // System.out.println("1 SAME! v = " + lv + ", nv = " + lnv); 58 | } 59 | } 60 | 61 | }); 62 | 63 | t1.start(); 64 | t2.start(); 65 | 66 | try { 67 | t1.join(); 68 | t2.join(); 69 | } catch (InterruptedException iex) {} 70 | 71 | System.out.println("Final value of v = " + v); 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sample_code/concurrency/MethodLevelConcurrency.java: -------------------------------------------------------------------------------- 1 | // Just a different way of using synchronized, as a 2 | // method modifier instead of synchronizing on a specific 3 | // object in code. 4 | 5 | // synchronized as a method modifier automatically 6 | // syncs on "this" (i.e. the object the method belongs to) 7 | 8 | // The downside to this is that the entire method is 9 | // synchronized, and not just the part that you absolutely 10 | // need to be run atomically. This can degrade performance. 11 | 12 | public class MethodLevelConcurrency { 13 | 14 | public static int x = 0; 15 | 16 | public static final int NUM_TIMES = 100000; 17 | 18 | public static synchronized void safeIncrement() { 19 | x++; 20 | } 21 | 22 | public static synchronized void safeDecrement() { 23 | x--; 24 | } 25 | 26 | 27 | public static void main(String[] args) { 28 | 29 | Thread t1 = new Thread(() -> { 30 | for (int j = 0; j < NUM_TIMES; j++) { 31 | safeIncrement(); 32 | } 33 | }); 34 | Thread t2 = new Thread(() -> { 35 | for (int j = 0; j < NUM_TIMES; j++) { 36 | safeDecrement(); 37 | } 38 | }); 39 | 40 | // Start off both threads 41 | t1.start(); 42 | t2.start(); 43 | 44 | // Wait for both to finish 45 | 46 | try { 47 | t1.join(); 48 | t2.join(); 49 | } catch (InterruptedException iex) { } 50 | 51 | // Print out final result - we have done x++ 10000 times 52 | // and x-- 100 times 53 | 54 | System.out.println("x is now " + x); 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sample_code/concurrency/SimpleThread.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SimpleThread { 4 | 5 | private static Random rng = new Random(); 6 | 7 | public static void main(String[] args) { 8 | 9 | // Create a new thread which will run the method 10 | // SimpleThread::backgroundTask. 11 | 12 | // Note that it has not started yet! It's just been 13 | // created and sitting around 14 | 15 | // Note that a method is a type of Runnable (something that 16 | // can be run in a Thread). 17 | 18 | Thread t = new Thread(SimpleThread::backgroundTask); 19 | 20 | // Start running the other thread 21 | 22 | t.start(); 23 | 24 | // Now, in main thread, print out Main Task (j) 25 | // with j from 0 to 99 26 | 27 | // Note that any thread may throw an InterruptedException. 28 | // This occurs when a thread is interrupted before it 29 | // does the activity it is supposed to do. 30 | 31 | for (int j=0; j < 100; j++) { 32 | System.out.println("MAIN TASK (" + j + ")"); 33 | try { 34 | Thread.sleep(20); 35 | } catch (InterruptedException iex) { } 36 | } 37 | } 38 | 39 | // Note that there is nothing special about this method! 40 | 41 | private static void backgroundTask() { 42 | 43 | // In other thread, print out Background Task (j) 44 | // with j from 0 to 99 45 | 46 | for (int j = 0; j < 100; j++) { 47 | System.out.println("BACKGROUND TASK(" + j + ")"); 48 | try { 49 | Thread.sleep(20); 50 | } catch (InterruptedException iex) { } 51 | 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample_code/concurrency/SynchronousCalculator.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | // This will run a complex calculation on every element of an array 4 | // of the size passed in as a parameter. 5 | // It will do so synchronously (that is, work on the first element, then 6 | // the second, then the third, etc.) 7 | 8 | public class SynchronousCalculator { 9 | 10 | /** 11 | * Helper method for printing out arrays. 12 | * @param int[] arr Array of integers to print 13 | */ 14 | public static void printArray(int[] arr) { 15 | System.out.print("[ "); 16 | for (int j=0; j < (arr.length - 1); j++) { 17 | System.out.print(arr[j] + ", "); 18 | } 19 | if (arr.length > 0) { 20 | System.out.print(arr[arr.length - 1]); 21 | } 22 | System.out.println(" ]"); 23 | 24 | } 25 | 26 | /** 27 | * Generate initial array, where location 0 has 28 | * value 0, location 1 value 1, etc. 29 | */ 30 | 31 | private static int[] generateInitialArray(int n) { 32 | int[] toReturn = new int[n]; 33 | for (int j = 0; j < n; j++) { 34 | toReturn[j] = j; 35 | } 36 | return toReturn; 37 | } 38 | 39 | /** 40 | * Placeholder for complex calculation 41 | */ 42 | 43 | private static int calculate(int n) { 44 | int x = n; 45 | for (int j = 0; j < 100000; j++) { 46 | for (int k = 0; k < 20; k++) { 47 | x += k * Math.atan(n); 48 | } 49 | x += Math.acos(n); 50 | x -= j * Math.sin(n); 51 | } 52 | return x; 53 | } 54 | 55 | 56 | public static void main(String[] args) { 57 | 58 | int n = -1; 59 | 60 | try { 61 | n = Integer.parseInt(args[0]); 62 | if (n < 1) { 63 | throw new Exception(); 64 | } 65 | } catch (Exception ex) { 66 | System.out.println("Expected positive int as argument!"); 67 | System.exit(1); 68 | } 69 | 70 | int[] initialArray = generateInitialArray(n); 71 | int[] newArray = new int[initialArray.length]; 72 | 73 | printArray(initialArray); 74 | 75 | for (int j = 0; j < initialArray.length; j++) { 76 | newArray[j] = calculate(initialArray[j]); 77 | System.out.println("Finished calculating " + j); 78 | } 79 | 80 | printArray(newArray); 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /sample_code/concurrency/ThreadedHashMap.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | 3 | public class ThreadedHashMap { 4 | 5 | public static HashMap h = new HashMap(); 6 | public static HashMap h2 = new HashMap(); 7 | 8 | public static void main(String[] args) { 9 | 10 | // Remember hashes are key-value pairs 11 | // e.g. animal id number to noise it makes 12 | // 1 -> "meow" 13 | // 17 -> "moo" 14 | // 4 -> "cluck" 15 | // Can be in any order, can be gaps 16 | 17 | 18 | final int NUM_TIMES = 1000; 19 | 20 | Thread t1 = new Thread(() -> { 21 | for (int j = 0; j < NUM_TIMES; j++) { 22 | // System.out.println("Adding " + j); 23 | h.put(j, "chirp"); 24 | try { 25 | Thread.sleep(1); 26 | } catch (InterruptedException iex) { } 27 | 28 | } 29 | }); 30 | 31 | Thread t2 = new Thread(() -> { 32 | for (int j = 0; j < NUM_TIMES; j++) { 33 | //System.out.println("Removing " + j); 34 | h.remove(j); 35 | try { 36 | Thread.sleep(1); 37 | } catch (InterruptedException iex) { } 38 | 39 | } 40 | }); 41 | 42 | try { 43 | t2.start(); 44 | t1.start(); 45 | t1.join(); 46 | t2.join(); 47 | } catch (InterruptedException iex) { } 48 | 49 | System.out.println("Final size of hash is " + h.size()); 50 | 51 | // Thread t3 = new Thread(() -> { 52 | // for (int j = 0; j < NUM_TIMES; j++) { 53 | // h2.put(j, "COFFEE"); 54 | // try { 55 | // Thread.sleep(1); 56 | // } catch (InterruptedException iex) { } 57 | 58 | // } 59 | // }); 60 | 61 | // Thread t4 = new Thread(() -> { 62 | // for (int j = 0; j < NUM_TIMES; j++) { 63 | // h2.put(j, "TEA"); 64 | // try { 65 | // Thread.sleep(1); 66 | // } catch (InterruptedException iex) { } 67 | 68 | // } 69 | // }); 70 | 71 | // try { 72 | // t4.start(); 73 | // t3.start(); 74 | // t3.join(); 75 | // t4.join(); 76 | // } catch (InterruptedException iex) { } 77 | 78 | // int c = 0; 79 | // for (Object value: h2.values()) { 80 | 81 | // System.out.println(c++ + ": "+ value); 82 | // } 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /sample_code/concurrency/Timer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This illustrates how to sleep for a given number of seconds. 3 | * Note that this is _not_ going to be perfect because sleeping is 4 | * _not_ guaranteed to be for a _precise_ amount of time. 5 | * But it is good enough for our project! 6 | * You can use System.nanoTime() if you want better precision. 7 | */ 8 | 9 | public class Timer { 10 | 11 | public static void main(String[] args) { 12 | 13 | System.out.println("Countdown timer..."); 14 | 15 | // Create a new thread which will count down from 10 to 0... 16 | 17 | // Note this uses the lambda syntax! 18 | 19 | Thread t = new Thread(() -> { 20 | for (int j = 10; j >= 0; j--) { 21 | System.out.println(j + "..."); 22 | 23 | // This thread will sleep for >= 1000 milliseconds (1 second) 24 | // In practice it will be very close to 1000 milliseconds 25 | // Do not rely on Java (or the JVM in general) for hard 26 | // real-time guarantees! 27 | try { 28 | Thread.sleep(1000); 29 | } catch (InterruptedException iex) { 30 | // ignore 31 | } 32 | } 33 | }); 34 | 35 | // Start the thread 36 | 37 | t.start(); 38 | 39 | // Wait until the thread is complete before moving on 40 | 41 | try { 42 | t.join(); 43 | } catch (InterruptedException iex) { 44 | // ignore 45 | } 46 | 47 | System.out.println("Liftoff!"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample_code/concurrency/TimerActual.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a variation on Timer.java in this same directory. 3 | * See there for more specifics. 4 | * Here we will use System.nanoTime() to 5 | */ 6 | 7 | public class TimerActual { 8 | 9 | public static long[] _times = new long[12]; 10 | 11 | 12 | public static void printTimeDiffs() { 13 | long timeDiff = -1; 14 | for (int j = 10; j >= 0; j--) { 15 | timeDiff = (_times[j + 1] - _times[j]) * -1; 16 | System.out.println("Time " + j + " = " + timeDiff + " ns"); 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | 22 | System.out.println("Countdown timer..."); 23 | 24 | 25 | // Create a new thread which will count down from 10 to 0... 26 | 27 | // Note this uses the lambda syntax! 28 | 29 | Thread t = new Thread(() -> { 30 | 31 | // Initial time 32 | _times[11] = System.nanoTime(); 33 | 34 | for (int j = 10; j >= 0; j--) { 35 | System.out.println(j + "..."); 36 | 37 | try { 38 | Thread.sleep(1000); 39 | } catch (InterruptedException iex) { 40 | // ignore 41 | } 42 | _times[j] = System.nanoTime(); 43 | 44 | } 45 | }); 46 | 47 | // Start the thread 48 | 49 | t.start(); 50 | 51 | // Wait until the thread is complete before moving on 52 | 53 | try { 54 | t.join(); 55 | } catch (InterruptedException iex) { 56 | // ignore 57 | } 58 | 59 | System.out.println("Liftoff!"); 60 | 61 | printTimeDiffs(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sample_code/hash/HashMapDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | 3 | public class HashMapDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | // Remember hashes are key-value pairs 8 | // e.g. animal id number to noise it makes 9 | // 1 -> "meow" 10 | // 17 -> "moo" 11 | // 4 -> "cluck" 12 | // Can be in any order, can be gaps 13 | 14 | HashMap h = new HashMap(); 15 | 16 | final int NUM_TIMES = 9999999; 17 | 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | h.put(j, "chirp"); 20 | } 21 | 22 | for (int j = 0; j < NUM_TIMES; j++) { 23 | h.remove(j); 24 | } 25 | 26 | System.out.println("Final size of hash is " + h.size()); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample_code/hash/Hashing.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | 4 | 5 | public class Hashing { 6 | 7 | public HashMap _hashmap = new HashMap(); 8 | 9 | public Hashtable _hashtable = new Hashtable(); 10 | 11 | public int counter = 0; 12 | 13 | public static void main() { 14 | Thread t1 = new Thread(() -> { 15 | for (int j = 0; j < 100; j++) { 16 | _hashmap.add(j, "monkey"); 17 | } 18 | }); 19 | 20 | Thread t2 = new Thread(() -> { 21 | for (int j = 0; j < 100; j++) { 22 | _hashmap.add(j, "monkey"); 23 | } 24 | }); 25 | 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sample_code/hash/Hashtable.java: -------------------------------------------------------------------------------- 1 | import java.util.Hashtable; 2 | 3 | public class Hashtable { 4 | 5 | public static void main(String[] args) { 6 | 7 | // Remember hashes are key-value pairs 8 | // e.g. animal id number to noise it makes 9 | // 1 -> "meow" 10 | // 17 -> "moo" 11 | // 4 -> "cluck" 12 | // Can be in any order, can be gaps 13 | 14 | Hashtable h = new Hashtable(); 15 | 16 | final int NUM_TIMES = 999999999; 17 | 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | h.add(j, "chirp"); 20 | } 21 | 22 | for (int j = 0; j < NUM_TIMES; j++) { 23 | h.remove(j); 24 | } 25 | 26 | System.out.println("Final size of hash is " + h.size()); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample_code/hash/HashtableDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.Hashtable; 2 | 3 | public class HashtableDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | // Remember hashes are key-value pairs 8 | // e.g. animal id number to noise it makes 9 | // 1 -> "meow" 10 | // 17 -> "moo" 11 | // 4 -> "cluck" 12 | // Can be in any order, can be gaps 13 | 14 | Hashtable h = new Hashtable(); 15 | 16 | final int NUM_TIMES = 9999999; 17 | 18 | for (int j = 0; j < NUM_TIMES; j++) { 19 | h.put(j, "chirp"); 20 | } 21 | 22 | for (int j = 0; j < NUM_TIMES; j++) { 23 | h.remove(j); 24 | } 25 | 26 | System.out.println("Final size of hash is " + h.size()); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample_code/unit_tests/LinkedList.java: -------------------------------------------------------------------------------- 1 | package com.laboon; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class LinkedList { 6 | 7 | Node _head = null; 8 | 9 | public LinkedList() { 10 | 11 | } 12 | 13 | public void traverse() { 14 | Node ptr = _head; 15 | while (ptr != null) { 16 | ptr = ptr.getNext(); 17 | } 18 | } 19 | 20 | public void prettyPrint() { 21 | Node ptr = _head; 22 | if (_head == null) { 23 | System.out.println(""); 24 | } 25 | while (ptr != null) { 26 | if (ptr.getNext() != null) { 27 | System.out.print(ptr.getData() + " -> "); 28 | } else { 29 | System.out.println(ptr.getData()); 30 | } 31 | ptr = ptr.getNext(); 32 | } 33 | } 34 | 35 | public void addToFront(Node toAdd) { 36 | if (_head == null) { 37 | _head = toAdd; 38 | } else { 39 | Node oldHead = _head; 40 | _head = toAdd; 41 | _head.setNext(oldHead); 42 | } 43 | } 44 | 45 | public void deleteLast() { 46 | if (_head == null) { 47 | // Nothing to do! 48 | return; 49 | } 50 | 51 | if (_head.getNext() == null) { 52 | _head = null; 53 | return; 54 | } 55 | 56 | Node ptr = _head; 57 | Node last = ptr; 58 | 59 | while (ptr != null) { 60 | 61 | ptr = ptr.getNext(); 62 | if (ptr != null && ptr.getNext() != null) { 63 | 64 | last = ptr; 65 | } 66 | } 67 | 68 | last.setNext(null); 69 | } 70 | 71 | public void deleteFront() { 72 | if (_head == null) { 73 | // Nothing to do! 74 | return; 75 | } 76 | 77 | if (_head.getNext() == null) { 78 | _head = null; 79 | return; 80 | } 81 | 82 | _head = _head.getNext(); 83 | 84 | } 85 | 86 | public T getFrontData() { 87 | if (_head == null) { 88 | return null; 89 | } else { 90 | return _head.getData(); 91 | } 92 | } 93 | 94 | public Node getFront() { 95 | return _head; 96 | } 97 | 98 | public void addToEnd(Node toAdd) { 99 | 100 | toAdd.setNext(null); 101 | 102 | if (_head == null) { 103 | _head = toAdd; 104 | } else { 105 | 106 | Node ptr = _head; 107 | Node last = ptr; 108 | while (ptr != null) { 109 | 110 | last = ptr; 111 | ptr = ptr.getNext(); 112 | } 113 | 114 | last.setNext(toAdd); 115 | 116 | } 117 | 118 | } 119 | 120 | /** 121 | * Delete all duplicate data 122 | */ 123 | 124 | public void deleteDupes() { 125 | 126 | // If there are zero or one elements, there can't be dupes 127 | 128 | if (_head == null || _head.getNext() == null) { 129 | return; 130 | } 131 | 132 | ArrayList prevObjs = new ArrayList(); 133 | Node ptr = _head; 134 | Node last = ptr; 135 | 136 | // Traverse list 137 | 138 | while (ptr != null) { 139 | if (prevObjs.contains(ptr.getData())) { 140 | // delete node - note this will never occur on first pass-through 141 | last.setNext(ptr.getNext()); 142 | } else { 143 | // add it to the list of previous data elements 144 | last = ptr; 145 | prevObjs.add(ptr.getData()); 146 | } 147 | 148 | ptr = ptr.getNext(); 149 | } 150 | 151 | } 152 | 153 | /** 154 | * Will delete first element with that value 155 | * @param valToCheck 156 | */ 157 | 158 | public void deleteByVal(T valToCheck) { 159 | 160 | if (_head == null) { 161 | // nothing here, return 162 | return; 163 | } 164 | 165 | if (_head.getNext() == null) { 166 | // Only one item 167 | if (_head.getData() == valToCheck) { 168 | _head = null; 169 | } 170 | return; 171 | } 172 | 173 | if (_head.getData() == valToCheck) { 174 | _head = _head.getNext(); 175 | } 176 | 177 | Node ptr = _head; 178 | Node last = ptr; 179 | boolean foundIt = false; 180 | while (ptr != null && !(foundIt)) { 181 | if (ptr.getData() == valToCheck) { 182 | // Found it! 183 | foundIt = true; 184 | last.setNext(ptr.getNext()); 185 | } else { 186 | last = ptr; 187 | ptr = ptr.getNext(); 188 | } 189 | } 190 | } 191 | 192 | public void clear() { 193 | _head = null; 194 | } 195 | 196 | public T kthToLast(int k) { 197 | 198 | if (_head == null) { 199 | return null; 200 | } 201 | Node ptr = _head; 202 | Node candidate = null; 203 | int ctr = 0; 204 | while (ptr != null) { 205 | 206 | if (ctr == k) { 207 | candidate = _head; 208 | } else if (ctr > k) { 209 | candidate = candidate.getNext(); 210 | } 211 | ctr++; 212 | ptr = ptr.getNext(); 213 | } 214 | if (candidate == null) { 215 | return null; 216 | } else { 217 | return candidate.getData(); 218 | } 219 | } 220 | 221 | @Override 222 | public boolean equals(Object rhs) { 223 | 224 | // Trivial cases - if exact same object, return true, 225 | // if not of correct class or if null, return false 226 | 227 | if (this == rhs) return true; 228 | else if (!(rhs instanceof LinkedList) || rhs == null) return false; 229 | LinkedList other = (LinkedList) rhs; 230 | boolean toReturn = true; 231 | Node ptr1 = this.getFront(); 232 | Node ptr2 = other.getFront(); 233 | boolean cont = true; 234 | while (ptr1 != null && ptr2 != null && cont == true) { 235 | // System.out.println("Ptr1 = " + ptr1.getData() + " / ptr2 = " + ptr2.getData()); 236 | if (ptr1.getData().equals(ptr2.getData())) { 237 | ptr1 = ptr1.getNext(); 238 | ptr2 = ptr2.getNext(); 239 | } else { 240 | // System.out.println("Data not equal, setting to false"); 241 | toReturn = false; 242 | cont = false; 243 | } 244 | } 245 | if (ptr1 == null ^ ptr2 == null) { 246 | // System.out.println("XOR failure - lists are diff sizes"); 247 | toReturn = false; 248 | } 249 | 250 | return toReturn; 251 | } 252 | 253 | @Override 254 | public int hashCode() { 255 | return 1; 256 | } 257 | 258 | /** 259 | * @param args 260 | */ 261 | public static void main(String[] args) { 262 | /* 263 | LinkedList ll = new LinkedList(); 264 | Node node0 = new Node(0); 265 | Node node1 = new Node(1); 266 | Node node2 = new Node(2); 267 | Node node3 = new Node(3); 268 | Node node4 = new Node(4); 269 | Node node5 = new Node(5); 270 | ll.addToEnd(node1); 271 | ll.addToEnd(node2); 272 | ll.addToEnd(node3); 273 | ll.addToEnd(node4); 274 | ll.addToEnd(node5); 275 | ll.addToFront(node0); 276 | 277 | System.out.println("Original.."); 278 | ll.traverse(); 279 | 280 | System.out.println("Pretty..."); 281 | ll.prettyPrint(); 282 | 283 | System.out.println("Delete front.."); 284 | ll.deleteFront(); 285 | ll.traverse(); 286 | 287 | System.out.println("Delete end..."); 288 | ll.deleteLast(); 289 | ll.traverse(); 290 | 291 | System.out.println("Delete non-existent 1000.."); 292 | ll.deleteByVal(1000); 293 | ll.traverse(); 294 | 295 | System.out.println("Delete 2.."); 296 | ll.deleteByVal(2); 297 | ll.traverse(); 298 | 299 | System.out.println("Delete 1.."); 300 | ll.deleteByVal(1); 301 | ll.traverse(); 302 | 303 | System.out.println("Delete 4.."); 304 | ll.deleteByVal(4); 305 | ll.traverse(); 306 | 307 | System.out.println("Delete 3.."); 308 | ll.deleteByVal(3); 309 | ll.traverse(); 310 | 311 | System.out.println("Delete 1 on null.."); 312 | ll.deleteByVal(1); 313 | ll.traverse(); 314 | 315 | 316 | ll.clear(); 317 | System.out.println("Delete dupes NULL: orig"); 318 | ll.prettyPrint(); 319 | ll.deleteDupes(); 320 | System.out.println("Delete dupes NULL: after"); 321 | ll.prettyPrint(); 322 | ll.addToEnd(new Node(new Integer(1))); 323 | ll.addToEnd(new Node(new Integer(1))); 324 | ll.addToEnd(new Node(new Integer(2))); 325 | ll.addToEnd(new Node(new Integer(3))); 326 | ll.addToEnd(new Node(new Integer(3))); 327 | ll.addToEnd(new Node(new Integer(2))); 328 | ll.addToEnd(new Node(new Integer(1))); 329 | ll.addToEnd(new Node(new Integer(3))); 330 | ll.addToEnd(new Node(new Integer(2))); 331 | ll.addToEnd(new Node(new Integer(1))); 332 | System.out.println("Delete dupes: orig"); 333 | ll.prettyPrint(); 334 | System.out.println("Delete dupes: after"); 335 | ll.deleteDupes(); 336 | ll.prettyPrint(); 337 | 338 | System.out.println("Long ordered list"); 339 | ll.clear(); 340 | ll.addToEnd(new Node(new Integer(1))); 341 | ll.addToEnd(new Node(new Integer(2))); 342 | ll.addToEnd(new Node(new Integer(3))); 343 | ll.addToEnd(new Node(new Integer(4))); 344 | ll.addToEnd(new Node(new Integer(5))); 345 | ll.addToEnd(new Node(new Integer(6))); 346 | ll.addToEnd(new Node(new Integer(7))); 347 | ll.addToEnd(new Node(new Integer(8))); 348 | ll.addToEnd(new Node(new Integer(9))); 349 | ll.prettyPrint(); 350 | for (int j=0; j<10; j++) { 351 | Integer n = ll.kthToLast(j); 352 | if (n == null) { 353 | System.out.println("Returned null"); 354 | } else { 355 | System.out.println(j + "[st/nd/th] to last = " + n.intValue()); 356 | } 357 | } 358 | */ 359 | } 360 | 361 | } 362 | -------------------------------------------------------------------------------- /sample_code/unit_tests/LinkedListTest.java: -------------------------------------------------------------------------------- 1 | package com.laboon; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class LinkedListTest { 10 | 11 | // -------------------------------------------------------------- 12 | // ZERO-LENGTH TESTS 13 | // -------------------------------------------------------------- 14 | 15 | // Test that a zero-length list will return null if you try to get 16 | // the first element 17 | @Test 18 | public void testZeroList() { 19 | LinkedList ll = new LinkedList(); 20 | ll.clear(); 21 | assertNull(ll.getFront()); 22 | } 23 | 24 | // Test that the .clear() methods works, by first adding an item, and then 25 | // clearing the list. It should be empty (tested by ensuring that 26 | // the first element is null). 27 | @Test 28 | public void testClearedList() { 29 | LinkedList ll = new LinkedList(); 30 | ll.addToFront(new Node(new Integer(7))); 31 | ll.clear(); 32 | assertNull(ll.getFront()); 33 | } 34 | 35 | // This tests whether a multiple item linked lit will 36 | // clear down to zero items when clear method is called. 37 | 38 | @Test 39 | public void testMultiList() { 40 | LinkedList ll = new LinkedList(); 41 | for (int j=0; j < 10; j++) { 42 | ll.addToFront(new Node(new Integer(j))); 43 | } 44 | ll.clear(); 45 | assertNull(ll.getFront()); 46 | } 47 | 48 | // -------------------------------------------------------------- 49 | // ADD TO FRONT TESTS 50 | // -------------------------------------------------------------- 51 | 52 | // Add ten nodes, then add one more (testNode). Check that setNext() has been 53 | // called to the last of the first ten nodes, and that the added 54 | // node testNode is the same as the one that is at the front of the list. 55 | 56 | @SuppressWarnings("unchecked") 57 | @Test 58 | public void testAddToNoItemLL() { 59 | LinkedList ll = new LinkedList(); 60 | Node[] nodes = new Node[10]; 61 | 62 | for (int j = 0; j < 10; j++) { 63 | nodes[j] = new Node(5);; 64 | ll.addToFront(nodes[j]); 65 | } 66 | 67 | Node testNode = new Node(5); 68 | ll.addToFront(testNode); 69 | assertSame(ll.getFront(), testNode); 70 | 71 | } 72 | 73 | // -------------------------------------------------------------- 74 | // DELETE FROM FRONT TESTS 75 | // -------------------------------------------------------------- 76 | 77 | // Check that attempting to delete a node from a Linked List with 78 | // no elements will not throw an error. 79 | 80 | @Test 81 | public void testDeleteFrontNoItem() { 82 | LinkedList ll = new LinkedList(); 83 | ll.deleteFront(); 84 | assertEquals(ll.getFront(), null); 85 | 86 | } 87 | 88 | // Check that deleting a node from a Linked List with 89 | // one elements will not throw an error, and will result in an 90 | // empty LinkedList (front is null). 91 | 92 | @SuppressWarnings("unchecked") 93 | @Test 94 | public void testDeleteFrontOneItem() { 95 | LinkedList ll = new LinkedList(); 96 | ll.addToFront(new Node(5)); 97 | ll.deleteFront(); 98 | assertEquals(ll.getFront(), null); 99 | } 100 | 101 | // Check that deleting a node from a Linked List with 102 | // multiple elements will properly delete the first node 103 | // and leave the old second node as the new first node.. 104 | 105 | @SuppressWarnings("unchecked") 106 | @Test 107 | public void testDeleteFrontMultipleItems() { 108 | LinkedList ll = new LinkedList(); 109 | Node[] nodes = new Node[10]; 110 | 111 | for (int j = 0; j < 10; j++) { 112 | nodes[j] = new Node(new Integer(1)); 113 | ll.addToFront(nodes[j]); 114 | } 115 | 116 | ll.deleteFront(); 117 | 118 | assertSame(ll.getFront(), nodes[8]); 119 | } 120 | 121 | // -------------------------------------------------------------- 122 | // EQUALITY TESTS 123 | // -------------------------------------------------------------- 124 | 125 | // Check that a new linked list equals itself. 126 | @Test 127 | public void testEqualsSelf() { 128 | LinkedList ll = new LinkedList(); 129 | assertEquals(ll, ll); 130 | } 131 | 132 | // Check that two new linked lists with no elements equal each other. 133 | @Test 134 | public void testEquals0Elems() { 135 | LinkedList ll01 = new LinkedList(); 136 | LinkedList ll02 = new LinkedList(); 137 | assertEquals(ll01, ll02); 138 | } 139 | 140 | // An instantiated linked list should not equal null. 141 | @Test 142 | public void testNotEqualsNull() { 143 | LinkedList ll01 = new LinkedList(); 144 | assertFalse(ll01.equals(null)); 145 | } 146 | 147 | // Check that a LL object does equal a non-LinkedList, e.g. Object 148 | @Test 149 | public void testNotEqualsRegularObject() { 150 | LinkedList ll01 = new LinkedList(); 151 | Object obj = new Object(); 152 | assertFalse(ll01.equals(obj)); 153 | } 154 | 155 | @Test 156 | public void throwException() { 157 | try { 158 | doSomethingThatThrowsException(); 159 | fail(); 160 | } catch (Exceptio e) { 161 | } 162 | 163 | } 164 | 165 | 166 | // Check that two LLs with the same Node value with a single node are equal 167 | @Test 168 | public void testEqualsOneNodeSameVals() { 169 | LinkedList ll11 = new LinkedList(); 170 | LinkedList ll12 = new LinkedList(); 171 | ll11.addToFront(new Node(new Integer(1))); 172 | ll12.addToFront(new Node(new Integer(1))); 173 | assertEquals(ll11, ll12); 174 | } 175 | 176 | // Check that two LL with different Node values with a single node are NOT equal 177 | @Test 178 | public void testEqualsOneNodeDiffVals() { 179 | LinkedList ll11 = new LinkedList(); 180 | LinkedList ll2 = new LinkedList(); 181 | ll11.addToFront(new Node(new Integer(1))); 182 | ll2.addToFront(new Node(new Integer(2))); 183 | assertFalse(ll11.equals(ll2)); 184 | } 185 | 186 | // Check that two LLs with different sizes, but the same front node value, 187 | // are not considered equal. 188 | @Test 189 | public void testNotEqualsDiffSizes() { 190 | LinkedList ll11 = new LinkedList(); 191 | LinkedList ll_3elems = new LinkedList(); 192 | 193 | ll11.addToFront(new Node(new Integer(1))); 194 | ll_3elems.addToFront(new Node(new Integer(3))); 195 | ll_3elems.addToFront(new Node(new Integer(2))); 196 | ll_3elems.addToFront(new Node(new Integer(1))); 197 | 198 | assertFalse(ll_3elems.equals(ll11)); 199 | } 200 | 201 | // Check that a LL which is just a reference to another instance of itself 202 | // equals itself 203 | @Test 204 | public void testEqualsRef() { 205 | LinkedList ll11 = new LinkedList(); 206 | ll11.addToFront(new Node(new Integer(1))); 207 | LinkedList ll11_new = ll11; 208 | assertSame(ll11, ll11_new); 209 | } 210 | 211 | // Check that LLs with the same size, but different data in the nodes, 212 | // do not equal each other. 213 | @Test 214 | public void testNotEqualsDiffData() { 215 | LinkedList ll_3elems = new LinkedList(); 216 | LinkedList ll_321 = new LinkedList(); 217 | ll_3elems.addToFront(new Node(new Integer(3))); 218 | ll_3elems.addToFront(new Node(new Integer(2))); 219 | ll_3elems.addToFront(new Node(new Integer(1))); 220 | 221 | ll_321.addToFront(new Node(new Integer(1))); 222 | ll_321.addToFront(new Node(new Integer(2))); 223 | ll_321.addToFront(new Node(new Integer(3))); 224 | assertFalse(ll_321.equals(ll_3elems)); 225 | } 226 | 227 | // Check that two multiple-node LLs with the same data equal each other 228 | @Test 229 | public void testEqualsSameData() { 230 | LinkedList ll_321 = new LinkedList(); 231 | LinkedList ll_321_2 = new LinkedList(); 232 | 233 | ll_321.addToFront(new Node(new Integer(1))); 234 | ll_321.addToFront(new Node(new Integer(2))); 235 | ll_321.addToFront(new Node(new Integer(3))); 236 | 237 | ll_321_2.addToFront(new Node(new Integer(1))); 238 | ll_321_2.addToFront(new Node(new Integer(2))); 239 | ll_321_2.addToFront(new Node(new Integer(3))); 240 | 241 | assertTrue(ll_321.equals(ll_321_2)); 242 | 243 | } 244 | 245 | } 246 | -------------------------------------------------------------------------------- /sample_code/unit_tests/Node.java: -------------------------------------------------------------------------------- 1 | public class Node { 2 | 3 | private Node _nextNode = null; 4 | private T _data = null; 5 | 6 | public Node(T data) { 7 | _data = data; 8 | } 9 | 10 | public void setData(T data) { 11 | _data = data; 12 | } 13 | 14 | public T getData() { 15 | return _data; 16 | } 17 | 18 | public Node getNext() { 19 | return _nextNode; 20 | } 21 | 22 | public void setNext(Node newNext) { 23 | _nextNode = newNext; 24 | } 25 | 26 | public String toString() { 27 | if (_nextNode != null) { 28 | return "(" + _data + ", " + _nextNode.hashCode() + ")"; 29 | } else { 30 | return "(" + _data + ", " + null + ")"; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /study_guides/midterm_1_study_guide.md: -------------------------------------------------------------------------------- 1 | ## Midterm Study Guide 2 | 3 | __Reminder: Midterm is 20 February 2017!__ 4 | 5 | You are responsible for everything discussed in class or on the slides. However, the topics for the questions will be pulled from this study guide. 6 | 7 | 1. Be able to explain difference between software engineering, computer science, programming 8 | 2. Understand the Software Development Life Cycle (SDLC) 9 | 1. Analysis 10 | 2. Requirements 11 | 3. Design 12 | 4. Development 13 | 5. Integration and Test 14 | 6. Release 15 | 7. Maintenance 16 | 8. Optional steps - External Acceptance, Regulatory Checks, DevOps, EOL, Customer Support... 17 | 3. ^ Traditional waterfall method - what are the problems with this? 18 | 4. The Iron Triangle of Project Management (Cost / Schedule / Scope & Quality) 19 | 5. Brooks's Law (Adding manpower to a late software project makes it later) 20 | 6. Understand different development methodologies (benefits and drawbacks), esp: 21 | 1. Cowboy coding 22 | 2. Waterfall 23 | 3. Iterative and Incremental 24 | 4. Agile 25 | 5. Cleanroom 26 | 7. Be able to explain Agile/Scrum 27 | 1. What is a standup? 28 | 2. Sprint? 29 | 3. User Story? 30 | 4. Product backlog? 31 | 5. Retrospective? 32 | 8. Interacting with Stakeholders 33 | 1. What is a stakeholder? 34 | 2. What are some problems with eliciting requirements? 35 | 2. Customer vs user 36 | 3. Ways to Elicit Requirements 37 | 1. Interviews 38 | 2. Paper prototyping 39 | 3. User observation 40 | 9. Build Systems 41 | 1. Why use a build system? 42 | 2. Basic Gradle usage and tasks 43 | 1. gradle run 44 | 2. gradle build 45 | 3. gradle test 46 | 4. Can we add our own? How? 47 | 10. Test-Driven Development 48 | 1. Understand unit tests 49 | 2. Be able to write simple unit tests 50 | 3. Given a method, understand how to test it 51 | 2. Red-green-refactor loop 52 | 3. What kinds of assertions to use? 53 | 11. Object-Oriented Design 54 | 1. Coupling (which is better, loose or tight?) 55 | 2. Cohesion (which is better, high or low?) 56 | 12. Define Walking Skeleton 57 | 13. Object-Oriented Style: 58 | 1. Encapsulation 59 | 2. Information Hiding 60 | 3. Postel's Principle 61 | 14. What is a leaky abstraction? Is it good or bad? Can you give an example? 62 | -------------------------------------------------------------------------------- /study_guides/midterm_2_study_guide.md: -------------------------------------------------------------------------------- 1 | ## Midterm 2 Study Guide 2 | 3 | __Reminder: Midterm 2 is 12 APR!__ 4 | 5 | ### Software Design 6 | * Why is software design a "wicked" process? 7 | * Essential vs Accidental difficulties 8 | * Minimizing and managing complexity 9 | * What is a subsystem? 10 | * Should these be loosely or tightly coupled? 11 | * Should they have high or low cohesion? 12 | * Be able to describe/recognize a code smell 13 | * Top-Down vs Bottom-Up Design 14 | * Be able to describe 15 | * Be able to decide which to use for a project 16 | * Understand common architectural patterns 17 | * Layered Architecture 18 | * Model-View-Controller 19 | * n-Tier 20 | * Client-Server 21 | * Pipeline 22 | * Event-Driven 23 | * Big Ball o' Mud 24 | 25 | ### Object-Oriented Analysis and Design 26 | * UML (Unified Moeling Language) 27 | * Static vs Dynamic views 28 | * Class Diagram 29 | * Generalization 30 | * Aggregation 31 | * Composition 32 | * Sequence Diagram 33 | * Be able to read 34 | * SOLID Principles 35 | * Understand all of them 36 | * Realize when they are being broken 37 | * Heuristics vs Laws 38 | 39 | ### Quality Assurance 40 | * Internal vs External Quality 41 | * Ways to improve quality 42 | * Testing, pair programming, code reviews, etc 43 | * Multi-modal reviews 44 | * Limitations of testing 45 | 46 | ### Working on Legacy and Other People's Code 47 | * When should you modify legacy code? 48 | * Questions to ask before you do so 49 | * Pinning tests 50 | * What are they? 51 | * When do you use them? 52 | * How do they differ from "regular" unit tests? 53 | * Be able to describe what seams are, and find one in code 54 | * Understand change points 55 | * Understand inflection points 56 | * Understand and be able to implement sprout methods 57 | * Understand and be able to implement wrap methods 58 | * TUFs and TUCs 59 | 60 | ### Integration and the Software Pipeline 61 | * Phased vs incremental vs Continuous integration 62 | * Benefits / downsides of each 63 | * Integration strategies: 64 | * Top-down 65 | * Bottom-up 66 | * Risk-oriented 67 | * Feature-oriented 68 | * Understand feature toggles 69 | 70 | ### Programming With Concurrency 71 | * Why use threads? 72 | * Understand Concurrency vs Parallelism 73 | * Understand the differences between processes and threads 74 | * Be able to create use threading in Java 75 | * Threads vs Runnables 76 | * Running 77 | * Starting 78 | * Joining 79 | * Synchronization 80 | * Method level 81 | * On a lock object 82 | * Data race - be able to diagnose/implement 83 | * Ways to avoid: synchronization, no shared mutable state 84 | * Deadlock - be able to diagnose/implement 85 | * Livelock - be able to diagnose/implement 86 | 87 | ### Concurrency in Java 88 | * Understand Atomic variables 89 | * Be able to use appropriately 90 | * HashMap vs Hashtable 91 | * Which is thread-safe? 92 | * What are benefits/drawbacks of using thread-safe collections? 93 | 94 | ### Design Patterns 95 | * Why do we use patterns? 96 | * For each design pattern, be able to recognize/implement 97 | * For each design pattern, understand why it would be used 98 | * Design patterns: 99 | * Null check 100 | * Utility 101 | * Singleton 102 | * Factory 103 | * Decorator 104 | * Pool 105 | * Iterator 106 | * Strategy 107 | * Null Object 108 | 109 | ### Software Craftsmanship 110 | * Why is it difficult to quantify how good a software engineer is? 111 | * Know the three traits of a Great Programmer 112 | * Laziness, Impatience, Hubris 113 | * Define and explain intellectual humility 114 | * What is UPOD? 115 | * What is "managing up"? 116 | * Ways of reducing complexity: 117 | * Pure functions 118 | * Minimizing deepness 119 | * Minimizing shared mutable state 120 | * Using a code style guide 121 | * Using conventions 122 | * Short methods 123 | 124 | ### Trade-Offs in Software Engineering 125 | * Be able to make trade-offs using the "cost/benefit" method described in class 126 | * Be able to distinguish between NECESSARY and NICE-TO-HAVE features and quality attributes 127 | * Understand difference in trade-offs in internal quality vs external quality. Which are preferable? When? 128 | -------------------------------------------------------------------------------- /syllabus.md: -------------------------------------------------------------------------------- 1 | # Syllabus - Spring 2017 2 | CS1530: Software Engineering 3 | 4 | Note that this syllabus is subject to change, but we will cover all of these topics! I may change the ordering based on class/project needs or interests, but these are the topics we will cover. 5 | 6 | # Required Books 7 | 8 | * Freeman/Pryce - Growing Object-Oriented Software, Guided by Tests 9 | * McConnell - Code Complete, Second Edition 10 | * The Mythical Man-Month is available for free online at the Internet Archive: [https://archive.org/details/mythicalmanmonth00fred](https://archive.org/details/mythicalmanmonth00fred) 11 | * Building and Testing With Gradle is available for free online at: http://www2.gradle.com/l/68052/2015-01-13/6dm 12 | * A Friendly Introduction to Git by Bill Laboon is available for free online at: https://github.com/laboon/friendly_introduction_git/tree/master/presentation 13 | 14 | ## WEEK 1 (4 Jan) 15 | 16 | ### Class 1 - Introduction: What is Software Engineering? 17 | * Software Engineering vs Programming vs Computer Science 18 | 19 | ## WEEK 2 (9 and 11 Jan) 20 | 21 | ### Class 1 - Overview: Designing a Software Product 22 | #### __Reading: Brooks, "The Tar Pit" and Brooks, "The Mythical Man-Month" (just the titular essay, not the entire book)__ 23 | #### __ASSIGNED: Group Selection__ 24 | * Why is this difficult? 25 | * Overview of the Software Development Life Cycle 26 | * What goes into a software product aside from code? 27 | 28 | ### Class 2 - Agile Development: Theory and Practice 29 | #### __Reading: "Manifesto for Agile Software Development", http://agilemanifesto.org/ 30 | * Terminology - Sprints, scrums, kanban, retrospective, etc. 31 | 32 | ## WEEK 3 (16 and 18 Jan) 33 | 34 | ### NO CLASS - MARTIN LUTHER KING, JR DAY 35 | 36 | ### Class 2 - Interacting with Stakeholders and Co-workers 37 | * EXERCISE: Stakeholder interaction 38 | * SPRINT 1 BEGINS 39 | 40 | ## WEEK 4 (23 and 25 Jan) 41 | 42 | ### Class 1 - Git Exercise 43 | * Reading: A Friendly Introduction to Git by Bill Laboon 44 | * Branches and Merging 45 | * EXERCISE: Git 911 46 | 47 | ### Class 2 - Intro to Gradle 48 | * Building 49 | * Testing 50 | * Other tasks 51 | 52 | ## WEEK 5 (30 Jan and 1 Feb) 53 | 54 | ### Class 1 - Gradle Exercise 55 | * EXERCISE: Pair Programming a Gradle application 56 | 57 | ### Class 2 - First Retrospective / Sprint Planning 58 | * EXERCISE: In-class retrospective and sprint planning 59 | * SPRINT 1 ENDS; SPRINT 2 BEGINS 60 | 61 | ## WEEK 6 (6 and 8 Feb) 62 | 63 | ### Class 1 - Introduction to Test-Driven Development (TDD) 64 | #### __Reading: Freeman/Pryce, Chapters 1 - 3__ 65 | * TFD / TDD 66 | * The Red-Green-Refactor cycle 67 | 68 | ### Class 2 - Software Engineering with TDD 69 | #### __Reading: Freeman/Pryce, Chapters 4 - 6__ 70 | 71 | ## WEEK 7 (13 and 15 Feb) 72 | 73 | ### Class 1 - An Overview of Other Software Engineering Methodologies 74 | #### __Reading: McConnell, Chapters 1 - 3__ 75 | * Waterfall (BDUF) 76 | * Prototyping 77 | * Incremental 78 | * RAD 79 | * "Cowboy coding" 80 | 81 | ### Class 2 - An Overview of Software Engineering Methodologies, cont'd 82 | * SPRINT 2 ENDS; SPRINT 3 BEGINS 83 | 84 | ## WEEK 8 (20 and 22 Feb) 85 | 86 | ### Class 1 87 | * __MIDTERM__ 88 | 89 | ### Class 2 - Software Design 90 | #### __Reading: McConnell, Chapters 4 -5 and Freeman/Pryce, Chapter 7__ 91 | * Top-down vs bottom-up 92 | * Architecture Models (simple, layered, client-server, n-tier, Big Ball of Mud, etc.) 93 | 94 | ## WEEK 9 (27 Feb and 1 Mar) 95 | 96 | ### Class 1 - Object-Oriented Analysis and Design 97 | * Overview of UML 98 | * SOLID Principles 99 | * DRY 100 | 101 | ### Class 2 - Quality Assurance and Quality Software 102 | #### __READING: McConnell, Chapters 20 - 23__ 103 | * The QA process and why it is important 104 | * QA implementation as part of the SDLC 105 | * Code Reviews 106 | * SPRINT 3 ENDS; SPRINT 4 BEGINS 107 | 108 | ## WEEK 10 (6 and 8 Mar) 109 | 110 | ### NO CLASS - SPRING BREAK 111 | 112 | ### NO CLASS - SPRING BREAK 113 | 114 | ## WEEK 11 (13 and 15 Mar) 115 | 116 | ### Class 1 - Programming with Concurrency 117 | * Why program with threads? 118 | * Threads vs Processes 119 | * Pitfalls 120 | 121 | ### Class 1 - Concurrency in Java 122 | * java.util.concurrent 123 | * Thread-safe programming in Java 124 | * Common patterns and anti-patterns 125 | * SPRINT 4 ENDS; SPRINT 5 BEGINS 126 | 127 | ## WEEK 12 (20 and 22 Mar) 128 | 129 | ### Class 1 - Concurrency Exercise 130 | * EXERCISE: Concurrency 131 | 132 | ### Class 2 - Legacy Code, Large Systems, and Working On Other People's Code 133 | #### __OPTIONAL READING: Working Effectively With Legacy Code by Michael Feathers (http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf)__ 134 | #### __OPTIONAL READING: Testable Java by Michael Feathers (http://www.objectmentor.com/resources/articles/TestableJava.pdf)__ 135 | 136 | 137 | ## WEEK 13 (27 and 29 Mar) 138 | 139 | ### Class 1 - Integration and the Software Pipeline 140 | * Classical models of integration 141 | * Continuous Integration 142 | 143 | ### Class 2 - Using Design Patterns 144 | #### ___READING: Freeman/Pryce, Chapters 26 - 27__ 145 | * EXERCISE: Design Patterns 146 | * SPRINT 5 ENDS; SPRINT 6 BEGINS 147 | 148 | ## WEEK 14 (3 and 5 Apr) 149 | 150 | ### Class 1 - Software Craftsmanship 151 | #### __READING: McConnell, Chapters 33 - 34__ 152 | * Writing good code - maintainable, testable, etc. 153 | * Intellectual humility and avoiding complexity 154 | * Conventions and Abstractions 155 | * Continuous Improvement 156 | 157 | ### Class 2 - Fiat Voluntas Tua: Understanding The Command Line 158 | * EXERCISE: Unix commands 159 | 160 | ## WEEK 15 (10 and 12 Apr) 161 | 162 | ### Class 1 - Trade-Offs in Software Engineering 163 | * Cost / Benefit analysis 164 | * Making decisions based on the Iron Triangle 165 | * Examples - Apollo Guidance Computer, Adding Metrics to Web Application 166 | * EXERCISE: Trade-off Discussion 167 | 168 | ### Class 2 169 | #### __MIDTERM__ 170 | 171 | ## WEEK 16 (17 and 19 Apr) 172 | 173 | ### Class 1 - Project Presentation 174 | * Each group will present their project to the rest of the class 175 | * You may go today or next class; will be assigned randomly 176 | * END OF SPRINT 6; END OF PROJECT! 177 | 178 | ### Class 2 - Project Presentations, cont'd. 179 | 180 | 181 | --------------------------------------------------------------------------------